de.javagl.jgltf.model.AccessorDatas Maven / Gradle / Ivy
/*
*
* 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.model;
import java.nio.ByteBuffer;
import java.util.Locale;
import java.util.logging.Logger;
/**
* Methods to create instances of the accessor data utility classes
* that allow a typed access to the data that is contained in the
* buffer view that the accessor refers to.
*
* Unless otherwise noted, none of the arguments to these methods may
* be null
.
*/
public class AccessorDatas
{
/**
* The logger used in this class
*/
private static final Logger logger =
Logger.getLogger(AccessorDatas.class.getName());
/**
* Create the {@link AccessorData} for the given {@link AccessorModel}
*
* @param accessorModel The {@link AccessorModel}
* @return The {@link AccessorData}
*/
public static AccessorData create(AccessorModel accessorModel)
{
BufferViewModel bufferViewModel = accessorModel.getBufferViewModel();
ByteBuffer bufferViewData = bufferViewModel.getBufferViewData();
return create(accessorModel, bufferViewData);
}
/**
* Create the {@link AccessorData} for the given {@link AccessorModel}
* that refers to the data from the given buffer.
*
* @param accessorModel The {@link AccessorModel}
* @param byteBuffer The byte buffer containing the data
* @return The {@link AccessorData}
*/
public static AccessorData create(
AccessorModel accessorModel, ByteBuffer byteBuffer)
{
if (accessorModel.getComponentDataType() == byte.class)
{
return createByte(accessorModel, byteBuffer);
}
if (accessorModel.getComponentDataType() == short.class)
{
return createShort(accessorModel, byteBuffer);
}
if (accessorModel.getComponentDataType() == int.class)
{
return createInt(accessorModel, byteBuffer);
}
if (accessorModel.getComponentDataType() == float.class)
{
return createFloat(accessorModel, byteBuffer);
}
// Should never happen
logger.severe("Invalid component data type: "
+ accessorModel.getComponentDataType());
return null;
}
/**
* Create an {@link AccessorData} depending on the given component type.
* This will return an {@link AccessorByteData}, {@link AccessorShortData},
* {@link AccessorIntData} or {@link AccessorFloatData}
*
* @param componentType The component type, as a GL constant (for example,
* GL_UNSIGNED_SHORT
or GL_FLOAT
)
* @param bufferViewData The buffer view data that the accessor refers to
* @param byteOffset The byte offset for the accessor
* @param count The count (number of elements) for the accessor
* @param numComponentsPerElement The number of components per element.
* For example, if the accessor type is "VEC3"
, then this
* will be 3
* @param byteStride The optional byte stride for the accessor data
* @return The {@link AccessorData}
* @throws IllegalArgumentException If the given component type is
* not a valid GL constant
*/
public static AccessorData create(
int componentType, ByteBuffer bufferViewData, int byteOffset,
int count, int numComponentsPerElement, Integer byteStride)
{
if (isByteType(componentType))
{
return new AccessorByteData(
componentType, bufferViewData, byteOffset, count,
numComponentsPerElement, byteStride);
}
if (isShortType(componentType))
{
return new AccessorShortData(
componentType, bufferViewData, byteOffset, count,
numComponentsPerElement, byteStride);
}
if (isIntType(componentType))
{
return new AccessorIntData(
componentType, bufferViewData, byteOffset, count,
numComponentsPerElement, byteStride);
}
if (isFloatType(componentType))
{
return new AccessorFloatData(
componentType, bufferViewData, byteOffset, count,
numComponentsPerElement, byteStride);
}
throw new IllegalArgumentException(
"Not a valid component type: " + componentType);
}
/**
* Returns whether the given constant is GL_BYTE
or
* GL_UNSIGNED_BYTE
.
*
* @param type The type constant
* @return Whether the type is a byte
type
*/
public static boolean isByteType(int type)
{
return
type == GltfConstants.GL_BYTE ||
type == GltfConstants.GL_UNSIGNED_BYTE;
}
/**
* Returns whether the given constant is GL_SHORT
or
* GL_UNSIGNED_SHORT
.
*
* @param type The type constant
* @return Whether the type is a short
type
*/
public static boolean isShortType(int type)
{
return
type == GltfConstants.GL_SHORT ||
type == GltfConstants.GL_UNSIGNED_SHORT;
}
/**
* Returns whether the given constant is GL_INT
or
* GL_UNSIGNED_INT
.
*
* @param type The type constant
* @return Whether the type is an int
type
*/
public static boolean isIntType(int type)
{
return
type == GltfConstants.GL_INT ||
type == GltfConstants.GL_UNSIGNED_INT;
}
/**
* Returns whether the given constant is GL_FLOAT
.
*
* @param type The type constant
* @return Whether the type is a float
type
*/
public static boolean isFloatType(int type)
{
return type == GltfConstants.GL_FLOAT;
}
/**
* Returns whether the given constant is GL_UNSIGNED_BYTE
,
* GL_UNSIGNED_SHORT
or GL_UNSIGNED_INT
.
*
* @param type The type constant
* @return Whether the type is an unsigned type
*/
static boolean isUnsignedType(int type)
{
return
type == GltfConstants.GL_UNSIGNED_BYTE ||
type == GltfConstants.GL_UNSIGNED_SHORT ||
type == GltfConstants.GL_UNSIGNED_INT;
}
/**
* Make sure that the given type is GL_BYTE
or
* GL_UNSIGNED_BYTE
, and throw an
* IllegalArgumentException
if this is not the case.
*
* @param type The type constant
* @throws IllegalArgumentException If the given type is not
* GL_BYTE
or GL_UNSIGNED_BYTE
*/
static void validateByteType(int type)
{
if (!isByteType(type))
{
throw new IllegalArgumentException(
"The type is not GL_BYTE or GL_UNSIGNED_BYTE, but " +
GltfConstants.stringFor(type));
}
}
/**
* Make sure that the given type is GL_SHORT
or
* GL_UNSIGNED_SHORT
, and throw an
* IllegalArgumentException
if this is not the case.
*
* @param type The type constant
* @throws IllegalArgumentException If the given type is not
* GL_SHORT
or GL_UNSIGNED_BYTE
*/
static void validateShortType(int type)
{
if (!isShortType(type))
{
throw new IllegalArgumentException(
"The type is not GL_SHORT or GL_UNSIGNED_SHORT, but " +
GltfConstants.stringFor(type));
}
}
/**
* Make sure that the given type is GL_INT
or
* GL_UNSIGNED_INT
, and throw an
* IllegalArgumentException
if this is not the case.
*
* @param type The type constant
* @throws IllegalArgumentException If the given type is not
* GL_INT
or GL_UNSIGNED_INT
*/
static void validateIntType(int type)
{
if (!isIntType(type))
{
throw new IllegalArgumentException(
"The type is not GL_INT or GL_UNSIGNED_INT, but " +
GltfConstants.stringFor(type));
}
}
/**
* Make sure that the given type is GL_FLOAT
, and throw an
* IllegalArgumentException
if this is not the case.
*
* @param type The type constant
* @throws IllegalArgumentException If the given type is not
* GL_FLOAT
*/
static void validateFloatType(int type)
{
if (!isFloatType(type))
{
throw new IllegalArgumentException(
"The type is not GL_FLOAT, but " +
GltfConstants.stringFor(type));
}
}
/**
* Creates an {@link AccessorByteData} for the given {@link AccessorModel}
*
* @param accessorModel The {@link AccessorModel}
* @return The {@link AccessorByteData}
* @throws IllegalArgumentException If the
* {@link AccessorModel#getComponentType() component type} of the given
* accessor is not GL_BYTE
or GL_UNSIGNED_BYTE
*/
static AccessorByteData createByte(AccessorModel accessorModel)
{
BufferViewModel bufferViewModel = accessorModel.getBufferViewModel();
return createByte(accessorModel, bufferViewModel.getBufferViewData());
}
/**
* Creates an {@link AccessorByteData} for the given {@link AccessorModel}
*
* @param accessorModel The {@link AccessorModel}
* @param bufferViewByteBuffer The byte buffer of the
* {@link BufferViewModel} referenced by the {@link AccessorModel}
* @return The {@link AccessorByteData}
* @throws NullPointerException If any argument is null
* @throws IllegalArgumentException If the
* {@link AccessorModel#getComponentType() component type} of the given
* accessorModel is not GL_BYTE
or
* GL_UNSIGNED_BYTE
*/
private static AccessorByteData createByte(
AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer)
{
return new AccessorByteData(accessorModel.getComponentType(),
bufferViewByteBuffer,
accessorModel.getByteOffset(),
accessorModel.getCount(),
accessorModel.getElementType().getNumComponents(),
accessorModel.getByteStride());
}
/**
* Creates an {@link AccessorShortData} for the given {@link AccessorModel}
*
* @param accessorModel The {@link AccessorModel}
* @return The {@link AccessorShortData}
* @throws IllegalArgumentException If the
* {@link AccessorModel#getComponentType() component type} of the given
* accessorModel is not GL_SHORT
or
* GL_UNSIGNED_SHORT
*/
static AccessorShortData createShort(AccessorModel accessorModel)
{
BufferViewModel bufferViewModel = accessorModel.getBufferViewModel();
return createShort(accessorModel, bufferViewModel.getBufferViewData());
}
/**
* Creates an {@link AccessorShortData} for the given {@link AccessorModel}
*
* @param accessorModel The {@link AccessorModel}
* @param bufferViewByteBuffer The byte buffer of the
* {@link BufferViewModel} referenced by the {@link AccessorModel}
* @return The {@link AccessorShortData}
* @throws NullPointerException If any argument is null
* @throws IllegalArgumentException If the
* {@link AccessorModel#getComponentType() component type} of the given
* accessorModel is not GL_SHORT
or
* GL_UNSIGNED_SHORT
*/
private static AccessorShortData createShort(
AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer)
{
return new AccessorShortData(accessorModel.getComponentType(),
bufferViewByteBuffer,
accessorModel.getByteOffset(),
accessorModel.getCount(),
accessorModel.getElementType().getNumComponents(),
accessorModel.getByteStride());
}
/**
* Creates an {@link AccessorIntData} for the given {@link AccessorModel}
*
* @param accessorModel The {@link AccessorModel}
* @return The {@link AccessorIntData}
* @throws IllegalArgumentException If the
* {@link AccessorModel#getComponentType() component type} of the given
* accessorModel is not GL_INT
or GL_UNSIGNED_INT
*/
static AccessorIntData createInt(AccessorModel accessorModel)
{
BufferViewModel bufferViewModel = accessorModel.getBufferViewModel();
return createInt(accessorModel, bufferViewModel.getBufferViewData());
}
/**
* Creates an {@link AccessorIntData} for the given {@link AccessorModel}
*
* @param accessorModel The {@link AccessorModel}
* @param bufferViewByteBuffer The byte buffer of the
* {@link BufferViewModel} referenced by the {@link AccessorModel}
* @return The {@link AccessorIntData}
* @throws NullPointerException If any argument is null
* @throws IllegalArgumentException If the
* {@link AccessorModel#getComponentType() component type} of the given
* accessorModel is not GL_INT
or GL_UNSIGNED_INT
*/
private static AccessorIntData createInt(
AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer)
{
return new AccessorIntData(accessorModel.getComponentType(),
bufferViewByteBuffer,
accessorModel.getByteOffset(),
accessorModel.getCount(),
accessorModel.getElementType().getNumComponents(),
accessorModel.getByteStride());
}
/**
* Creates an {@link AccessorFloatData} for the given {@link AccessorModel}
*
* @param accessorModel The {@link AccessorModel}
* @return The {@link AccessorFloatData}
* @throws IllegalArgumentException If the
* {@link AccessorModel#getComponentType() component type} of the given
* accessorModel is not GL_FLOAT
*/
public static AccessorFloatData createFloat(AccessorModel accessorModel)
{
BufferViewModel bufferViewModel = accessorModel.getBufferViewModel();
return createFloat(accessorModel, bufferViewModel.getBufferViewData());
}
/**
* Creates an {@link AccessorFloatData} for the given {@link AccessorModel}
*
* @param accessorModel The {@link AccessorModel}
* @param bufferViewByteBuffer The byte buffer of the
* {@link BufferViewModel} referenced by the {@link AccessorModel}
* @return The {@link AccessorFloatData}
* @throws NullPointerException If any argument is null
* @throws IllegalArgumentException If the
*/
private static AccessorFloatData createFloat(
AccessorModel accessorModel, ByteBuffer bufferViewByteBuffer)
{
return new AccessorFloatData(accessorModel.getComponentType(),
bufferViewByteBuffer,
accessorModel.getByteOffset(),
accessorModel.getCount(),
accessorModel.getElementType().getNumComponents(),
accessorModel.getByteStride());
}
/**
* Validate that the given {@link AccessorModel} parameters are valid for
* accessing a buffer with the given capacity
*
* @param byteOffset The byte offset
* @param numElements The number of elements
* @param byteStridePerElement The byte stride
* @param bufferCapacity The buffer capacity
* @throws IllegalArgumentException If the given byte buffer does not
* have a sufficient capacity
*/
static void validateCapacity(int byteOffset, int numElements,
int byteStridePerElement, int bufferCapacity)
{
int expectedCapacity = numElements * byteStridePerElement;
if (expectedCapacity > bufferCapacity)
{
throw new IllegalArgumentException(
"The accessorModel has an offset of " + byteOffset + " and " +
numElements + " elements with a byte stride of " +
byteStridePerElement + ", requiring " + expectedCapacity +
" bytes, but the buffer view has only " +
bufferCapacity + " bytes");
}
}
/**
* Compute the the minimum component values of the given
* {@link AccessorData}
*
* @param accessorData The {@link AccessorData}
* @return The minimum values
* @throws IllegalArgumentException If the given model has an unknown type
*/
public static Number[] computeMin(AccessorData accessorData)
{
if (accessorData instanceof AccessorByteData)
{
AccessorByteData accessorByteData =
(AccessorByteData) accessorData;
return NumberArrays.asNumbers(
accessorByteData.computeMinInt());
}
if (accessorData instanceof AccessorShortData)
{
AccessorShortData accessorShortData =
(AccessorShortData) accessorData;
return NumberArrays.asNumbers(
accessorShortData.computeMinInt());
}
if (accessorData instanceof AccessorIntData)
{
AccessorIntData accessorIntData =
(AccessorIntData) accessorData;
return NumberArrays.asNumbers(
accessorIntData.computeMinLong());
}
if (accessorData instanceof AccessorFloatData)
{
AccessorFloatData accessorFloatData =
(AccessorFloatData) accessorData;
return NumberArrays.asNumbers(
accessorFloatData.computeMin());
}
throw new IllegalArgumentException(
"Invalid data type: " + accessorData);
}
/**
* Compute the the maximum component values of the given
* {@link AccessorData}
*
* @param accessorData The {@link AccessorData}
* @return The maximum values
* @throws IllegalArgumentException If the given model has an unknown type
*/
public static Number[] computeMax(AccessorData accessorData)
{
if (accessorData instanceof AccessorByteData)
{
AccessorByteData accessorByteData =
(AccessorByteData) accessorData;
return NumberArrays.asNumbers(
accessorByteData.computeMaxInt());
}
if (accessorData instanceof AccessorShortData)
{
AccessorShortData accessorShortData =
(AccessorShortData) accessorData;
return NumberArrays.asNumbers(
accessorShortData.computeMaxInt());
}
if (accessorData instanceof AccessorIntData)
{
AccessorIntData accessorIntData =
(AccessorIntData) accessorData;
return NumberArrays.asNumbers(
accessorIntData.computeMaxLong());
}
if (accessorData instanceof AccessorFloatData)
{
AccessorFloatData accessorFloatData =
(AccessorFloatData) accessorData;
return NumberArrays.asNumbers(
accessorFloatData.computeMax());
}
throw new IllegalArgumentException(
"Invalid data type: " + accessorData);
}
/**
* Creates a (possibly large!) string representation of the given
* {@link AccessorData}, by calling
* {@link AccessorByteData#createString(Locale, String, int)},
* {@link AccessorShortData#createString(Locale, String, int)},
* {@link AccessorIntData#createString(Locale, String, int)} or
* {@link AccessorFloatData#createString(Locale, String, int)},
* depending on the type of the given data, with an unspecified
* format string.
*
* @param accessorData The {@link AccessorData}
* @param elementsPerRow The number of elements per row
* @return The string
*/
public static String createString(
AccessorData accessorData, int elementsPerRow)
{
if (accessorData instanceof AccessorByteData)
{
AccessorByteData accessorByteData =
(AccessorByteData) accessorData;
String accessorDataString =
accessorByteData.createString(
Locale.ENGLISH, "%4d", elementsPerRow);
return accessorDataString;
}
if (accessorData instanceof AccessorShortData)
{
AccessorShortData accessorShortData =
(AccessorShortData) accessorData;
String accessorDataString =
accessorShortData.createString(
Locale.ENGLISH, "%6d", elementsPerRow);
return accessorDataString;
}
if (accessorData instanceof AccessorIntData)
{
AccessorIntData accessorIntData =
(AccessorIntData) accessorData;
String accessorDataString =
accessorIntData.createString(
Locale.ENGLISH, "%11d", elementsPerRow);
return accessorDataString;
}
if (accessorData instanceof AccessorFloatData)
{
AccessorFloatData accessorFloatData =
(AccessorFloatData) accessorData;
String accessorDataString =
accessorFloatData.createString(
Locale.ENGLISH, "%10.5f", elementsPerRow);
return accessorDataString;
}
return "Unknown accessor data type: " + accessorData;
}
/**
* Private constructor to prevent instantiation
*/
private AccessorDatas()
{
// Private constructor to prevent instantiation
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy