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

de.javagl.jgltf.model.v2.AccessorSparseUtils Maven / Gradle / Ivy

There is a newer version: 2.0.4
Show newest version
/*
 * www.javagl.de - JglTF
 *
 * Copyright 2015-2017 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.model.v2;

import java.util.logging.Logger;

import de.javagl.jgltf.model.AccessorByteData;
import de.javagl.jgltf.model.AccessorData;
import de.javagl.jgltf.model.AccessorFloatData;
import de.javagl.jgltf.model.AccessorIntData;
import de.javagl.jgltf.model.AccessorShortData;

/**
 * Utility methods related to sparse accessors.
*
* These methods mainly do the substitution of the data that is defined in * a sparse accessor, and put this data into an {@link AccessorData} that * represents the dense data.
*
* Yes, Java does not play out so well with different primitive types... */ class AccessorSparseUtils { /** * The logger used in this class */ private static final Logger logger = Logger.getLogger(AccessorSparseUtils.class.getName()); /** * Extract indices from the given {@link AccessorData}. The given * {@link AccessorData} must contain an integral type. That is, * its {@link AccessorData#getComponentType() component type} must * be byte.class, short.class or * int.class. * * @param accessorData The {@link AccessorData} * @return The indices * @throws IllegalArgumentException If the given data does not contain * an integral type */ private static int[] extractIndices(AccessorData accessorData) { if (accessorData.getComponentType() == byte.class) { AccessorByteData accessorByteData = (AccessorByteData)accessorData; int numElements = accessorByteData.getNumElements(); int indices[] = new int[numElements]; for (int i=0; i *
* The baseAccessorData is the data that the dense data * will be initialized with, before applying the substitution * that is defined by the given sparse indices and values.
*
* The sparseIndicesAccessorData is an {@link AccessorData} * that was created from the accessor.sparse.indices * structure.
*
* The sparseValuesAccessorData is an {@link AccessorData} * that was created from the accessor.sparse.values * structure.
*
* This method does very few sanity checks. The caller is responsible * for calling it only with arguments that are valid (in terms of * indices and data types). * * @param denseAccessorData The dense {@link AccessorData} to be filled * @param baseAccessorData The optional "base" {@link AccessorData} * @param sparseIndicesAccessorData The sparse indices {@link AccessorData} * @param sparseValuesAccessorData The sparse values {@link AccessorData} * @throws IllegalArgumentException If the sparseIndicesAccessorData does * not contain data with an integral type (byte, short, int). */ static void substituteAccessorData( AccessorData denseAccessorData, AccessorData baseAccessorData, AccessorData sparseIndicesAccessorData, AccessorData sparseValuesAccessorData) { Class componentType = denseAccessorData.getComponentType(); if (componentType == byte.class) { AccessorByteData sparseValuesAccessorByteData = (AccessorByteData)sparseValuesAccessorData; AccessorByteData baseAccessorByteData = (AccessorByteData)baseAccessorData; AccessorByteData denseAccessorByteData = (AccessorByteData)denseAccessorData; substituteByteAccessorData( denseAccessorByteData, baseAccessorByteData, sparseIndicesAccessorData, sparseValuesAccessorByteData); } else if (componentType == short.class) { AccessorShortData sparseValuesAccessorShortData = (AccessorShortData)sparseValuesAccessorData; AccessorShortData baseAccessorShortData = (AccessorShortData)baseAccessorData; AccessorShortData denseAccessorShortData = (AccessorShortData)denseAccessorData; substituteShortAccessorData( denseAccessorShortData, baseAccessorShortData, sparseIndicesAccessorData, sparseValuesAccessorShortData); } else if (componentType == int.class) { AccessorIntData sparseValuesAccessorIntData = (AccessorIntData)sparseValuesAccessorData; AccessorIntData baseAccessorIntData = (AccessorIntData)baseAccessorData; AccessorIntData denseAccessorIntData = (AccessorIntData)denseAccessorData; substituteIntAccessorData( denseAccessorIntData, baseAccessorIntData, sparseIndicesAccessorData, sparseValuesAccessorIntData); } else if (componentType == float.class) { AccessorFloatData sparseValuesAccessorFloatData = (AccessorFloatData)sparseValuesAccessorData; AccessorFloatData baseAccessorFloatData = (AccessorFloatData)baseAccessorData; AccessorFloatData denseAccessorFloatData = (AccessorFloatData)denseAccessorData; substituteFloatAccessorData( denseAccessorFloatData, baseAccessorFloatData, sparseIndicesAccessorData, sparseValuesAccessorFloatData); } else { logger.warning("Invalid component type for accessor: " + componentType); } } /** * See {@link #substituteAccessorData} * * @param denseAccessorData The dense {@link AccessorData} to be filled * @param baseAccessorData The optional "base" {@link AccessorData} * @param sparseIndicesAccessorData The sparse indices {@link AccessorData} * @param sparseValuesAccessorData The sparse values {@link AccessorData} * @throws IllegalArgumentException If the sparseIndicesAccessorData does * not contain data with an integral type (byte, short, int). */ private static void substituteByteAccessorData( AccessorByteData denseAccessorData, AccessorByteData baseAccessorData, AccessorData sparseIndicesAccessorData, AccessorByteData sparseValuesAccessorData) { int numElements = denseAccessorData.getNumElements(); int numComponentsPerElement = denseAccessorData.getNumComponentsPerElement(); if (baseAccessorData != null) { // Fill the dense AccessorData with the base data for (int e = 0; e < numElements; e++) { for (int c = 0; c < numComponentsPerElement; c++) { byte value = baseAccessorData.get(e, c); denseAccessorData.set(e, c, value); } } } // Apply the substitution based on the sparse indices and values int indices[] = extractIndices(sparseIndicesAccessorData); for (int i = 0; i < indices.length; i++) { int targetElementIndex = indices[i]; for (int c = 0; c < numComponentsPerElement; c++) { byte substitution = sparseValuesAccessorData.get(i, c); denseAccessorData.set(targetElementIndex, c, substitution); } } } /** * See {@link #substituteAccessorData} * * @param denseAccessorData The dense {@link AccessorData} to be filled * @param baseAccessorData The optional "base" {@link AccessorData} * @param sparseIndicesAccessorData The sparse indices {@link AccessorData} * @param sparseValuesAccessorData The sparse values {@link AccessorData} * @throws IllegalArgumentException If the sparseIndicesAccessorData does * not contain data with an integral type (byte, short, int). */ private static void substituteShortAccessorData( AccessorShortData denseAccessorData, AccessorShortData baseAccessorData, AccessorData sparseIndicesAccessorData, AccessorShortData sparseValuesAccessorData) { int numElements = denseAccessorData.getNumElements(); int numComponentsPerElement = denseAccessorData.getNumComponentsPerElement(); if (baseAccessorData != null) { // Fill the dense AccessorData with the base data for (int e = 0; e < numElements; e++) { for (int c = 0; c < numComponentsPerElement; c++) { short value = baseAccessorData.get(e, c); denseAccessorData.set(e, c, value); } } } // Apply the substitution based on the sparse indices and values int indices[] = extractIndices(sparseIndicesAccessorData); for (int i = 0; i < indices.length; i++) { int targetElementIndex = indices[i]; for (int c = 0; c < numComponentsPerElement; c++) { short substitution = sparseValuesAccessorData.get(i, c); denseAccessorData.set(targetElementIndex, c, substitution); } } } /** * See {@link #substituteAccessorData} * * @param denseAccessorData The dense {@link AccessorData} to be filled * @param baseAccessorData The optional "base" {@link AccessorData} * @param sparseIndicesAccessorData The sparse indices {@link AccessorData} * @param sparseValuesAccessorData The sparse values {@link AccessorData} * @throws IllegalArgumentException If the sparseIndicesAccessorData does * not contain data with an integral type (byte, short, int). */ private static void substituteIntAccessorData( AccessorIntData denseAccessorData, AccessorIntData baseAccessorData, AccessorData sparseIndicesAccessorData, AccessorIntData sparseValuesAccessorData) { int numElements = denseAccessorData.getNumElements(); int numComponentsPerElement = denseAccessorData.getNumComponentsPerElement(); if (baseAccessorData != null) { // Fill the dense AccessorData with the base data for (int e = 0; e < numElements; e++) { for (int c = 0; c < numComponentsPerElement; c++) { int value = baseAccessorData.get(e, c); denseAccessorData.set(e, c, value); } } } // Apply the substitution based on the sparse indices and values int indices[] = extractIndices(sparseIndicesAccessorData); for (int i = 0; i < indices.length; i++) { int targetElementIndex = indices[i]; for (int c = 0; c < numComponentsPerElement; c++) { int substitution = sparseValuesAccessorData.get(i, c); denseAccessorData.set(targetElementIndex, c, substitution); } } } /** * See {@link #substituteAccessorData} * * @param denseAccessorData The dense {@link AccessorData} to be filled * @param baseAccessorData The optional "base" {@link AccessorData} * @param sparseIndicesAccessorData The sparse indices {@link AccessorData} * @param sparseValuesAccessorData The sparse values {@link AccessorData} * @throws IllegalArgumentException If the sparseIndicesAccessorData does * not contain data with an integral type (byte, short, int). */ private static void substituteFloatAccessorData( AccessorFloatData denseAccessorData, AccessorFloatData baseAccessorData, AccessorData sparseIndicesAccessorData, AccessorFloatData sparseValuesAccessorData) { int numElements = denseAccessorData.getNumElements(); int numComponentsPerElement = denseAccessorData.getNumComponentsPerElement(); if (baseAccessorData != null) { // Fill the dense AccessorData with the base data for (int e = 0; e < numElements; e++) { for (int c = 0; c < numComponentsPerElement; c++) { float value = baseAccessorData.get(e, c); denseAccessorData.set(e, c, value); } } } // Apply the substitution based on the sparse indices and values int indices[] = extractIndices(sparseIndicesAccessorData); for (int i = 0; i < indices.length; i++) { int targetElementIndex = indices[i]; for (int c = 0; c < numComponentsPerElement; c++) { float substitution = sparseValuesAccessorData.get(i, c); denseAccessorData.set(targetElementIndex, c, substitution); } } } /** * Private constructor to prevent instantiation */ private AccessorSparseUtils() { // Private constructor to prevent instantiation } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy