All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.javagl.jgltf.viewer.UniformGetters Maven / Gradle / Ivy

/*
 * www.javagl.de - JglTF
 *
 * Copyright 2015-2016 Marco Hutter - http://www.javagl.de
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */
package de.javagl.jgltf.viewer;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;

import de.javagl.jgltf.model.GltfConstants;
import de.javagl.jgltf.model.gl.TechniqueModel;
import de.javagl.jgltf.model.gl.TechniqueParametersModel;

/**
 * Utility methods related to obtaining the values of uniform variables from
 * a {@link RenderedMaterial}. Its only non-private method is 
 * {@link #createGenericSupplier(String, RenderedMaterial)}, which is
 * used by the {@link UniformGetterFactory}.
 */
class UniformGetters
{
    /**
     * Creates a supplier that obtains the specified value for a uniform, and
     * supplies this value with a type that matches the 
     * {@link TechniqueParametersModel#getType()}:
     * 

     * GL_INT
     * GL_UNSIGNED_INT     
     * GL_INT_VEC2
     * GL_INT_VEC3
     * GL_INT_VEC4       : An int[] array with the appropriate size. If
     *                     technique.parameters.count is null, then this
     *                     will be a single-element array.
     *                     
     * GL_FLOAT           
     * GL_FLOAT_MAT3
     * GL_FLOAT_MAT4
     * GL_FLOAT_VEC2
     * GL_FLOAT_VEC3
     * GL_FLOAT_VEC4     : A float[] array with the appropriate size. If
     *                     technique.parameters.count is null, then this
     *                     will be a single-element array. 
     * 
     * GL_SAMPLER_2D     : A Object[1] containing the texture reference. The
     *                     type of this may be a string (namely, the texture
     *                     ID for glTF 1.0) or an integer (namely, the texture
     *                     index for glTF 2.0)
     * 
     * 
*
* The returned suppliers MAY always return the same array instances. * So callers MUST NOT store or modify these arrays.
*
* If the {@link TechniqueParametersModel} for the specified uniform can * not be looked up in the {@link TechniqueModel} of the given * {@link RenderedMaterial} then null is returned. * * @param uniformName The uniform name * @param renderedMaterial The {@link RenderedMaterial} * @return The supplier * @throws IllegalArgumentException If the * {@link TechniqueParametersModel#getType()} is not one of the supported * types for OpenGL uniforms */ static Supplier createGenericSupplier( String uniformName, RenderedMaterial renderedMaterial) { TechniqueModel techniqueModel = renderedMaterial.getTechniqueModel(); TechniqueParametersModel techniqueParametersModel = techniqueModel.getUniformParameters(uniformName); if (techniqueParametersModel == null) { return null; } switch (techniqueParametersModel.getType()) { case GltfConstants.GL_INT: case GltfConstants.GL_UNSIGNED_INT: case GltfConstants.GL_INT_VEC2: case GltfConstants.GL_INT_VEC3: case GltfConstants.GL_INT_VEC4: { return createIntArraySupplier( uniformName, renderedMaterial); } case GltfConstants.GL_FLOAT: case GltfConstants.GL_FLOAT_MAT2: case GltfConstants.GL_FLOAT_MAT3: case GltfConstants.GL_FLOAT_MAT4: case GltfConstants.GL_FLOAT_VEC2: case GltfConstants.GL_FLOAT_VEC3: case GltfConstants.GL_FLOAT_VEC4: { return createFloatArraySupplier( uniformName, renderedMaterial); } case GltfConstants.GL_SAMPLER_2D: { return createObjectArraySupplier( uniformName, renderedMaterial); } // These types are not supported as uniform types in OpenGL case GltfConstants.GL_BOOL: case GltfConstants.GL_BYTE: case GltfConstants.GL_UNSIGNED_BYTE: case GltfConstants.GL_SHORT: case GltfConstants.GL_UNSIGNED_SHORT: case GltfConstants.GL_BOOL_VEC2: case GltfConstants.GL_BOOL_VEC3: case GltfConstants.GL_BOOL_VEC4: throw new IllegalArgumentException( "Uniform parameter type not supported: "+ techniqueParametersModel.getType()); default: break; } throw new IllegalArgumentException( "Invalid parameter type: " + techniqueParametersModel.getType()); } /** * Obtain the value for the uniform with the given name from the given * {@link RenderedMaterial}. If the value for the parameter is not * contained in the given {@link RenderedMaterial}, then return the * default value that is specified by the {@link TechniqueModel} of * the {@link RenderedMaterial}. * (Note that this value may still be null). * * @param uniformName The uniform name * @param renderedMaterial The {@link RenderedMaterial} * @return The uniform value */ private static Object getUniformValueObject( String uniformName, RenderedMaterial renderedMaterial) { TechniqueModel techniqueModel = renderedMaterial.getTechniqueModel(); Map uniforms = techniqueModel.getUniforms(); String parameterName = uniforms.get(uniformName); Map materialValues = renderedMaterial.getValues(); Object materialValue = materialValues.get(parameterName); if (materialValue != null) { return materialValue; } TechniqueParametersModel techniqueParametersModel = techniqueModel.getUniformParameters(uniformName); if (techniqueParametersModel == null) { return null; } return techniqueParametersModel.getValue(); } /** * Returns a supplier for the specified uniform value. This supplier * will return a Object[1] array, with the only element being the * value of the uniform. This value may be null, or * the actual value object. * * @param uniformName The uniform name * @param renderedMaterial The {@link RenderedMaterial} * @return The supplier */ private static Supplier createObjectArraySupplier( String uniformName, RenderedMaterial renderedMaterial) { Object value[] = new Object[1]; return () -> { Object object = getUniformValueObject( uniformName, renderedMaterial); if (object == null) { value[0] = null; } else if (object instanceof Collection) { Collection collection = (Collection)object; if (collection.size() == 0) { value[0] = null; } else { Object element = collection.iterator().next(); value[0] = element; } } else { value[0] = object; } return value; }; } /** * Returns a supplier for the specified uniform value, which is assumed * to be a single number, an integer array, or a list of numbers * * @param uniformName The uniform name * @param renderedMaterial The {@link RenderedMaterial} * @return The supplier */ private static Supplier createIntArraySupplier( String uniformName, RenderedMaterial renderedMaterial) { Supplier supplier = new Supplier() { private int value[] = null; @Override public int[] get() { Object object = getUniformValueObject( uniformName, renderedMaterial); if (object == null) { return null; } if (object instanceof Number) { if (value == null) { value = new int[1]; } Number number = (Number)object; value[0] = number.intValue(); } else if (object instanceof int[]) { return (int[])object; } else { List list = asNumberList(object); value = toIntArray(list, value); } return value; } }; return supplier; } /** * Returns a supplier for the specified uniform value, which is assumed * to be a single number, an float array, or a list of numbers * * @param uniformName The uniform name * @param renderedMaterial The {@link RenderedMaterial} * @return The supplier */ private static Supplier createFloatArraySupplier( String uniformName, RenderedMaterial renderedMaterial) { Supplier supplier = new Supplier() { private float value[] = null; @Override public float[] get() { Object object = getUniformValueObject( uniformName, renderedMaterial); if (object == null) { return null; } if (object instanceof Number) { if (value == null) { value = new float[1]; } Number number = (Number)object; value[0] = number.floatValue(); } else if (object instanceof float[]) { return (float[])object; } else { List list = asNumberList(object); value = toFloatArray(list, value); } return value; } }; return supplier; } /** * Write the elements of the given list into the given array. The given * list may not be null and may not contain null * elements. If the given array is null, then a new array * will be created and returned. If it is not null, it must * be large enough to store the elements of the list. * * @param list The list * @param result The array that will store the result * @return The result array */ private static float[] toFloatArray( List list, float result[]) { float localResult[] = result; if (localResult == null) { localResult = new float[list.size()]; } for (int i = 0; i < list.size(); i++) { localResult[i] = list.get(i).floatValue(); } return localResult; } /** * Write the elements of the given list into the given array. The given * list may not be null and may not contain null * elements. If the given array is null, then a new array * will be created and returned. If it is not null, it must * be large enough to store the elements of the list. * * @param list The list * @param result The array that will store the result * @return The result array */ private static int[] toIntArray( List list, int result[]) { int localResult[] = result; if (localResult == null) { localResult = new int[list.size()]; } for (int i = 0; i < list.size(); i++) { localResult[i] = list.get(i).intValue(); } return localResult; } /** * Brutally casts the given object to a list of subtype of numbers. * * @param object The object * @return The casted object */ private static List asNumberList(Object object) { @SuppressWarnings("unchecked") List list = (List)object; return list; } /** * Private constructor to prevent instantiation */ private UniformGetters() { // Private constructor to prevent instantiation } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy