@ -48,12 +48,15 @@ public class GltfLoader implements AssetLoader {
private Material defaultMat ;
private Material defaultMat ;
private AssetInfo info ;
private AssetInfo info ;
private JsonObject docRoot ;
private Node rootNode ;
private FloatArrayPopulator floatArrayPopulator = new FloatArrayPopulator ( ) ;
private FloatArrayPopulator floatArrayPopulator = new FloatArrayPopulator ( ) ;
private Vector3fArrayPopulator vector3fArrayPopulator = new Vector3fArrayPopulator ( ) ;
private Vector3fArrayPopulator vector3fArrayPopulator = new Vector3fArrayPopulator ( ) ;
private QuaternionArrayPopulator quaternionArrayPopulator = new QuaternionArrayPopulator ( ) ;
private QuaternionArrayPopulator quaternionArrayPopulator = new QuaternionArrayPopulator ( ) ;
private Matrix4fArrayPopulator matrix4fArrayPopulator = new Matrix4fArrayPopulator ( ) ;
private Matrix4fArrayPopulator matrix4fArrayPopulator = new Matrix4fArrayPopulator ( ) ;
private static Map < String , MaterialAdapter > defaultMaterialAdapters = new HashMap < > ( ) ;
private static Map < String , MaterialAdapter > defaultMaterialAdapters = new HashMap < > ( ) ;
private CustomContentManager customContentManager = new CustomContentManager ( ) ;
private boolean useNormalsFlag = false ;
private boolean useNormalsFlag = false ;
private Quaternion tmpQuat = new Quaternion ( ) ;
private Quaternion tmpQuat = new Quaternion ( ) ;
private Transform tmpTransforms = new Transform ( ) ;
private Transform tmpTransforms = new Transform ( ) ;
@ -64,7 +67,7 @@ public class GltfLoader implements AssetLoader {
IntMap < SkinBuffers > skinBuffers = new IntMap < > ( ) ;
IntMap < SkinBuffers > skinBuffers = new IntMap < > ( ) ;
static {
static {
defaultMaterialAdapters . put ( "pbrMetallicRoughness" , new PBRMaterialAdapter ( ) ) ;
defaultMaterialAdapters . put ( "pbrMetallicRoughness" , new PBRMetalRoughM aterialAdapter ( ) ) ;
}
}
@Override
@Override
@ -72,6 +75,7 @@ public class GltfLoader implements AssetLoader {
try {
try {
dataCache . clear ( ) ;
dataCache . clear ( ) ;
info = assetInfo ;
info = assetInfo ;
rootNode = new Node ( ) ;
if ( defaultMat = = null ) {
if ( defaultMat = = null ) {
defaultMat = new Material ( assetInfo . getManager ( ) , "Common/MatDefs/Light/PBRLighting.j3md" ) ;
defaultMat = new Material ( assetInfo . getManager ( ) , "Common/MatDefs/Light/PBRLighting.j3md" ) ;
@ -80,9 +84,9 @@ public class GltfLoader implements AssetLoader {
defaultMat . setFloat ( "Roughness" , 1f ) ;
defaultMat . setFloat ( "Roughness" , 1f ) ;
}
}
JsonObject r oot = new JsonParser ( ) . parse ( new JsonReader ( new InputStreamReader ( assetInfo . openStream ( ) ) ) ) . getAsJsonObject ( ) ;
docR oot = new JsonParser ( ) . parse ( new JsonReader ( new InputStreamReader ( assetInfo . openStream ( ) ) ) ) . getAsJsonObject ( ) ;
JsonObject asset = r oot. getAsJsonObject ( ) . get ( "asset" ) . getAsJsonObject ( ) ;
JsonObject asset = docR oot. getAsJsonObject ( ) . get ( "asset" ) . getAsJsonObject ( ) ;
String generator = getAsString ( asset , "generator" ) ;
String generator = getAsString ( asset , "generator" ) ;
String version = getAsString ( asset , "version" ) ;
String version = getAsString ( asset , "version" ) ;
String minVersion = getAsString ( asset , "minVersion" ) ;
String minVersion = getAsString ( asset , "minVersion" ) ;
@ -91,51 +95,62 @@ public class GltfLoader implements AssetLoader {
throw new AssetLoadException ( "Gltf Loader doesn't support this gltf version: " + version + ( minVersion ! = null ? ( "/" + minVersion ) : "" ) ) ;
throw new AssetLoadException ( "Gltf Loader doesn't support this gltf version: " + version + ( minVersion ! = null ? ( "/" + minVersion ) : "" ) ) ;
}
}
scenes = root . getAsJsonArray ( "scenes" ) ;
scenes = docRoot . getAsJsonArray ( "scenes" ) ;
nodes = root . getAsJsonArray ( "nodes" ) ;
nodes = docRoot . getAsJsonArray ( "nodes" ) ;
meshes = root . getAsJsonArray ( "meshes" ) ;
meshes = docRoot . getAsJsonArray ( "meshes" ) ;
accessors = root . getAsJsonArray ( "accessors" ) ;
accessors = docRoot . getAsJsonArray ( "accessors" ) ;
bufferViews = root . getAsJsonArray ( "bufferViews" ) ;
bufferViews = docRoot . getAsJsonArray ( "bufferViews" ) ;
buffers = root . getAsJsonArray ( "buffers" ) ;
buffers = docRoot . getAsJsonArray ( "buffers" ) ;
materials = root . getAsJsonArray ( "materials" ) ;
materials = docRoot . getAsJsonArray ( "materials" ) ;
textures = root . getAsJsonArray ( "textures" ) ;
textures = docRoot . getAsJsonArray ( "textures" ) ;
images = root . getAsJsonArray ( "images" ) ;
images = docRoot . getAsJsonArray ( "images" ) ;
samplers = root . getAsJsonArray ( "samplers" ) ;
samplers = docRoot . getAsJsonArray ( "samplers" ) ;
animations = root . getAsJsonArray ( "animations" ) ;
animations = docRoot . getAsJsonArray ( "animations" ) ;
skins = root . getAsJsonArray ( "skins" ) ;
skins = docRoot . getAsJsonArray ( "skins" ) ;
customContentManager . init ( this ) ;
readSkins ( ) ;
readSkins ( ) ;
JsonPrimitive defaultScene = root . getAsJsonPrimitive ( "scene" ) ;
JsonPrimitive defaultScene = docRoot . getAsJsonPrimitive ( "scene" ) ;
readScenes ( defaultScene , rootNode ) ;
Node n = readScenes ( defaultScene ) ;
rootNode = customContentManager . readExtension ( docRoot , rootNod e) ;
setupControls ( ) ;
setupControls ( ) ;
//only one scene let's not return the root.
//only one scene let's not return the root.
if ( n . getChildren ( ) . size ( ) = = 1 ) {
if ( rootNode . getChildren ( ) . size ( ) = = 1 ) {
n = ( Node ) n . getChild ( 0 ) ;
rootNode = ( Node ) rootNode . getChild ( 0 ) ;
}
}
//no name for the scene... let's set the file name.
//no name for the scene... let's set the file name.
if ( n . getName ( ) = = null ) {
if ( rootNode . getName ( ) = = null ) {
n . setName ( assetInfo . getKey ( ) . getName ( ) ) ;
rootNode . setName ( assetInfo . getKey ( ) . getName ( ) ) ;
}
}
return n ;
return rootNode ;
} catch ( Exception e ) {
} catch ( Exception e ) {
throw new AssetLoadException ( "An error occurred loading " + assetInfo . getKey ( ) . getName ( ) , e ) ;
throw new AssetLoadException ( "An error occurred loading " + assetInfo . getKey ( ) . getName ( ) , e ) ;
}
}
}
}
private void setDefaultParams ( Material mat ) {
mat . setColor ( "BaseColor" , ColorRGBA . White ) ;
mat . setFloat ( "Metallic" , 0f ) ;
mat . setFloat ( "Roughness" , 1f ) ;
}
private boolean isSupported ( String version , String minVersion ) {
private boolean isSupported ( String version , String minVersion ) {
return "2.0" . equals ( version ) ;
return "2.0" . equals ( version ) ;
}
}
private Node readScenes ( JsonPrimitive defaultScene ) throws IOException {
public void readScenes ( JsonPrimitive defaultScene , Node rootNod e ) throws IOException {
if ( scenes = = null ) {
if ( scenes = = null ) {
//no scene... lets handle this later...
//no scene... lets handle this later...
throw new AssetLoadException ( "Gltf files with no scene is not yet supported" ) ;
throw new AssetLoadException ( "Gltf files with no scene is not yet supported" ) ;
}
}
Node root = new Node ( ) ;
for ( JsonElement scene : scenes ) {
for ( JsonElement scene : scenes ) {
Node sceneNode = new Node ( ) ;
Node sceneNode = new Node ( ) ;
//specs says that only the default scene should be rendered,
//specs says that only the default scene should be rendered,
@ -144,10 +159,12 @@ public class GltfLoader implements AssetLoader {
sceneNode . setName ( getAsString ( scene . getAsJsonObject ( ) , "name" ) ) ;
sceneNode . setName ( getAsString ( scene . getAsJsonObject ( ) , "name" ) ) ;
JsonArray sceneNodes = scene . getAsJsonObject ( ) . getAsJsonArray ( "nodes" ) ;
JsonArray sceneNodes = scene . getAsJsonObject ( ) . getAsJsonArray ( "nodes" ) ;
root . attachChild ( sceneNode ) ;
sceneNode = customContentManager . readExtension ( scene , sceneNode ) ;
rootNode . attachChild ( sceneNode ) ;
for ( JsonElement node : sceneNodes ) {
for ( JsonElement node : sceneNodes ) {
readChild ( sceneNode , node ) ;
readChild ( sceneNode , node ) ;
}
}
}
}
//Loading animations
//Loading animations
@ -162,11 +179,10 @@ public class GltfLoader implements AssetLoader {
if ( defaultScene ! = null ) {
if ( defaultScene ! = null ) {
activeChild = defaultScene . getAsInt ( ) ;
activeChild = defaultScene . getAsInt ( ) ;
}
}
root . getChild ( activeChild ) . setCullHint ( Spatial . CullHint . Inherit ) ;
rootNode . getChild ( activeChild ) . setCullHint ( Spatial . CullHint . Inherit ) ;
return root ;
}
}
private Object readNode ( int nodeIndex ) throws IOException {
public Object readNode ( int nodeIndex ) throws IOException {
Object obj = fetchFromCache ( "nodes" , nodeIndex , Object . class ) ;
Object obj = fetchFromCache ( "nodes" , nodeIndex , Object . class ) ;
if ( obj ! = null ) {
if ( obj ! = null ) {
if ( obj instanceof BoneWrapper ) {
if ( obj instanceof BoneWrapper ) {
@ -222,6 +238,8 @@ public class GltfLoader implements AssetLoader {
spatial . setName ( getAsString ( nodeData . getAsJsonObject ( ) , "name" ) ) ;
spatial . setName ( getAsString ( nodeData . getAsJsonObject ( ) , "name" ) ) ;
}
}
spatial = customContentManager . readExtension ( nodeData , spatial ) ;
addToCache ( "nodes" , nodeIndex , spatial , nodes . size ( ) ) ;
addToCache ( "nodes" , nodeIndex , spatial , nodes . size ( ) ) ;
return spatial ;
return spatial ;
}
}
@ -248,7 +266,7 @@ public class GltfLoader implements AssetLoader {
}
}
private Transform readTransforms ( JsonObject nodeData ) {
public Transform readTransforms ( JsonObject nodeData ) {
Transform transform = new Transform ( ) ;
Transform transform = new Transform ( ) ;
JsonArray matrix = nodeData . getAsJsonArray ( "matrix" ) ;
JsonArray matrix = nodeData . getAsJsonArray ( "matrix" ) ;
if ( matrix ! = null ) {
if ( matrix ! = null ) {
@ -288,7 +306,7 @@ public class GltfLoader implements AssetLoader {
return transform ;
return transform ;
}
}
private Geometry [ ] readMeshPrimitives ( int meshIndex ) throws IOException {
public Geometry [ ] readMeshPrimitives ( int meshIndex ) throws IOException {
Geometry [ ] geomArray = ( Geometry [ ] ) fetchFromCache ( "meshes" , meshIndex , Object . class ) ;
Geometry [ ] geomArray = ( Geometry [ ] ) fetchFromCache ( "meshes" , meshIndex , Object . class ) ;
if ( geomArray ! = null ) {
if ( geomArray ! = null ) {
//cloning the geoms.
//cloning the geoms.
@ -355,6 +373,8 @@ public class GltfLoader implements AssetLoader {
mesh . generateBindPose ( ) ;
mesh . generateBindPose ( ) ;
}
}
mesh = customContentManager . readExtension ( meshObject , mesh ) ;
Geometry geom = new Geometry ( null , mesh ) ;
Geometry geom = new Geometry ( null , mesh ) ;
Integer materialIndex = getAsInteger ( meshObject , "material" ) ;
Integer materialIndex = getAsInteger ( meshObject , "material" ) ;
@ -384,21 +404,12 @@ public class GltfLoader implements AssetLoader {
//TODO targets(morph anim...)
//TODO targets(morph anim...)
}
}
geomArray = customContentManager . readExtension ( meshData , geomArray ) ;
addToCache ( "meshes" , meshIndex , geomArray , meshes . size ( ) ) ;
addToCache ( "meshes" , meshIndex , geomArray , meshes . size ( ) ) ;
return geomArray ;
return geomArray ;
}
}
public static class WeightData {
float value ;
short index ;
int componentSize ;
public WeightData ( float value , short index , int componentSize ) {
this . value = value ;
this . index = index ;
this . componentSize = componentSize ;
}
}
private SkinBuffers getSkinBuffers ( String bufferType ) {
private SkinBuffers getSkinBuffers ( String bufferType ) {
int bufIndex = getIndex ( bufferType ) ;
int bufIndex = getIndex ( bufferType ) ;
@ -410,7 +421,7 @@ public class GltfLoader implements AssetLoader {
return buffs ;
return buffs ;
}
}
private < R > R readAccessorData ( int accessorIndex , Populator < R > populator ) throws IOException {
public < R > R readAccessorData ( int accessorIndex , Populator < R > populator ) throws IOException {
assertNotNull ( accessors , "No accessor attribute in the gltf file" ) ;
assertNotNull ( accessors , "No accessor attribute in the gltf file" ) ;
@ -432,10 +443,12 @@ public class GltfLoader implements AssetLoader {
//TODO extensions?
//TODO extensions?
//TODO extras?
//TODO extras?
return populator . populate ( bufferViewIndex , componentType , type , count , byteOffset ) ;
R data = populator . populate ( bufferViewIndex , componentType , type , count , byteOffset ) ;
data = customContentManager . readExtension ( accessor , data ) ;
return data ;
}
}
private void readBuffer ( Integer bufferViewIndex , int byteOffset , int bufferSize , Object store , int numComponents , int componentSize ) throws IOException {
public void readBuffer ( Integer bufferViewIndex , int byteOffset , int bufferSize , Object store , int numComponents , int componentSize ) throws IOException {
JsonObject bufferView = bufferViews . get ( bufferViewIndex ) . getAsJsonObject ( ) ;
JsonObject bufferView = bufferViews . get ( bufferViewIndex ) . getAsJsonObject ( ) ;
Integer bufferIndex = getAsInteger ( bufferView , "buffer" ) ;
Integer bufferIndex = getAsInteger ( bufferView , "buffer" ) ;
@ -450,14 +463,17 @@ public class GltfLoader implements AssetLoader {
//int target = getAsInteger(bufferView, "target", 0);
//int target = getAsInteger(bufferView, "target", 0);
byte [ ] data = readData ( bufferIndex ) ;
byte [ ] data = readData ( bufferIndex ) ;
data = customContentManager . readExtension ( bufferView , data ) ;
populateBuffer ( store , data , bufferSize , byteOffset + bvByteOffset , byteStride , numComponents , componentSize ) ;
populateBuffer ( store , data , bufferSize , byteOffset + bvByteOffset , byteStride , numComponents , componentSize ) ;
//TODO extensions?
//TODO extras?
//TODO extras?
}
}
private byte [ ] readData ( int bufferIndex ) throws IOException {
public byte [ ] readData ( int bufferIndex ) throws IOException {
assertNotNull ( buffers , "No buffer defined" ) ;
assertNotNull ( buffers , "No buffer defined" ) ;
@ -465,25 +481,23 @@ public class GltfLoader implements AssetLoader {
String uri = getAsString ( buffer , "uri" ) ;
String uri = getAsString ( buffer , "uri" ) ;
Integer bufferLength = getAsInteger ( buffer , "byteLength" ) ;
Integer bufferLength = getAsInteger ( buffer , "byteLength" ) ;
assertNotNull ( bufferLength , "No byteLength defined for buffer " + bufferIndex ) ;
assertNotNull ( bufferLength , "No byteLength defined for buffer " + bufferIndex ) ;
byte [ ] data = ( byte [ ] ) fetchFromCache ( "buffers" , bufferIndex , Object . class ) ;
if ( data ! = null ) {
return data ;
}
if ( uri ! = null ) {
if ( uri ! = null ) {
if ( uri . startsWith ( "data:" ) ) {
if ( uri . startsWith ( "data:" ) ) {
//base 64 embed data
//base 64 embed data
return DatatypeConverter . parseBase64Binary ( uri . substring ( uri . indexOf ( "," ) + 1 ) ) ;
data = DatatypeConverter . parseBase64Binary ( uri . substring ( uri . indexOf ( "," ) + 1 ) ) ;
} else {
} else {
//external file let's load it
//external file let's load it
if ( ! uri . endsWith ( ".bin" ) ) {
if ( ! uri . endsWith ( ".bin" ) ) {
throw new AssetLoadException ( "Cannot load " + uri + ", a .bin extension is required." ) ;
throw new AssetLoadException ( "Cannot load " + uri + ", a .bin extension is required." ) ;
}
}
byte [ ] data = ( byte [ ] ) fetchFromCache ( "buffers" , bufferIndex , Object . class ) ;
if ( data ! = null ) {
return data ;
}
InputStream input = ( InputStream ) info . getManager ( ) . loadAsset ( info . getKey ( ) . getFolder ( ) + uri ) ;
InputStream input = ( InputStream ) info . getManager ( ) . loadAsset ( info . getKey ( ) . getFolder ( ) + uri ) ;
data = new byte [ bufferLength ] ;
data = new byte [ bufferLength ] ;
input . read ( data ) ;
input . read ( data ) ;
addToCache ( "buffers" , bufferIndex , data , buffers . size ( ) ) ;
return data ;
}
}
} else {
} else {
//no URI we are in a binary file so the data is in the 2nd chunk
//no URI we are in a binary file so the data is in the 2nd chunk
@ -491,52 +505,73 @@ public class GltfLoader implements AssetLoader {
throw new AssetLoadException ( "Binary gltf is not supported yet" ) ;
throw new AssetLoadException ( "Binary gltf is not supported yet" ) ;
}
}
data = customContentManager . readExtension ( buffer , data ) ;
addToCache ( "buffers" , bufferIndex , data , buffers . size ( ) ) ;
return data ;
}
}
private Material readMaterial ( int materialIndex ) {
public Material readMaterial ( int materialIndex ) {
assertNotNull ( materials , "There is no material defined yet a mesh references one" ) ;
assertNotNull ( materials , "There is no material defined yet a mesh references one" ) ;
JsonObject matData = materials . get ( materialIndex ) . getAsJsonObject ( ) ;
JsonObject matData = materials . get ( materialIndex ) . getAsJsonObject ( ) ;
JsonObject pbrMat = matData . getAsJsonObject ( "pbrMetallicRoughness" ) ;
JsonObject pbrMat = matData . getAsJsonObject ( "pbrMetallicRoughness" ) ;
if ( pbrMat = = null ) {
logger . log ( Level . WARNING , "Unable to find any pbrMetallicRoughness material entry in material " + materialIndex + ". Only PBR material is supported for now" ) ;
MaterialAdapter adapter = null ;
return defaultMat ;
if ( pbrMat ! = null ) {
adapter = getAdapterForMaterial ( info , "pbrMetallicRoughness" ) ;
if ( adapter = = null ) {
adapter = defaultMaterialAdapters . get ( "pbrMetallicRoughness" ) ;
}
adapter . init ( info . getManager ( ) ) ;
}
}
MaterialAdapter adapter = getAdapterForMaterial ( info , "pbrMetallicRoughness" ) ;
adapter = customContentManager . readExtension ( matData , adapter ) ;
if ( adapter = = null ) {
if ( adapter = = null ) {
logger . log ( Level . WARNING , "Couldn't find any matching material definition for material " + materialIndex ) ;
adapter = defaultMaterialAdapters . get ( "pbrMetallicRoughness" ) ;
adapter = defaultMaterialAdapters . get ( "pbrMetallicRoughness" ) ;
adapter . init ( info . getManager ( ) ) ;
setDefaultParams ( adapter . getMaterial ( ) ) ;
}
}
Material mat = adapter . getMaterial ( info . getManager ( ) ) ;
if ( pbrMat ! = null ) {
mat . setName ( getAsString ( matData , "name" ) ) ;
adapter . setParam ( "baseColorFactor" , getAsColor ( pbrMat , "baseColorFactor" , ColorRGBA . White ) ) ;
adapter . setParam ( "metallicFactor" , getAsFloat ( pbrMat , "metallicFactor" , 1f ) ) ;
adapter . setParam ( "roughnessFactor" , getAsFloat ( pbrMat , "roughnessFactor" , 1f ) ) ;
adapter . setParam ( "baseColorTexture" , readTexture ( pbrMat . getAsJsonObject ( "baseColorTexture" ) ) ) ;
adapter . setParam ( "metallicRoughnessTexture" , readTexture ( pbrMat . getAsJsonObject ( "metallicRoughnessTexture" ) ) ) ;
}
adapter . setParam ( mat , "baseColorFactor" , getAsColor ( pbrMat , "baseColorFactor" , ColorRGBA . White ) ) ;
adapter . getMaterial ( ) . setName ( getAsString ( matData , "name" ) ) ;
adapter . setParam ( mat , "metallicFactor" , getAsFloat ( pbrMat , "metallicFactor" , 1f ) ) ;
adapter . setParam ( "emissiveFactor" , getAsColor ( matData , "emissiveFactor" , ColorRGBA . Black ) ) ;
adapter . setParam ( mat , "roughnessFactor" , getAsFloat ( pbrMat , "roughnessFactor" , 1f ) ) ;
adapter . setParam ( mat , "emissiveFactor" , getAsColor ( matData , "emissiveFactor" , ColorRGBA . Black ) ) ;
String alphaMode = getAsString ( matData , "alphaMode" ) ;
String alphaMode = getAsString ( matData , "alphaMode" ) ;
adapter . setParam ( mat , "alphaMode" , alphaMode ) ;
adapter . setParam ( "alphaMode" , alphaMode ) ;
if ( alphaMode ! = null & & alphaMode . equals ( "MASK" ) ) {
if ( alphaMode ! = null & & alphaMode . equals ( "MASK" ) ) {
adapter . setParam ( mat , "alphaCutoff" , getAsFloat ( matData , "alphaCutoff" ) ) ;
adapter . setParam ( "alphaCutoff" , getAsFloat ( matData , "alphaCutoff" ) ) ;
}
}
adapter . setParam ( mat , "doubleSided" , getAsBoolean ( matData , "doubleSided" ) ) ;
adapter . setParam ( "doubleSided" , getAsBoolean ( matData , "doubleSided" ) ) ;
adapter . setParam ( mat , "baseColorTexture" , readTexture ( pbrMat . getAsJsonObject ( "baseColorTexture" ) ) ) ;
adapter . setParam ( mat , "metallicRoughnessTexture" , readTexture ( pbrMat . getAsJsonObject ( "metallicRoughnessTexture" ) ) ) ;
Texture2D normal = readTexture ( matData . getAsJsonObject ( "normalTexture" ) ) ;
Texture2D normal = readTexture ( matData . getAsJsonObject ( "normalTexture" ) ) ;
adapter . setParam ( mat , "normalTexture" , normal ) ;
adapter . setParam ( "normalTexture" , normal ) ;
if ( normal ! = null ) {
if ( normal ! = null ) {
useNormalsFlag = true ;
useNormalsFlag = true ;
}
}
adapter . setParam ( mat , "occlusionTexture" , readTexture ( matData . getAsJsonObject ( "occlusionTexture" ) ) ) ;
adapter . setParam ( "occlusionTexture" , readTexture ( matData . getAsJsonObject ( "occlusionTexture" ) ) ) ;
adapter . setParam ( mat , "emissiveTexture" , readTexture ( matData . getAsJsonObject ( "emissiveTexture" ) ) ) ;
adapter . setParam ( "emissiveTexture" , readTexture ( matData . getAsJsonObject ( "emissiveTexture" ) ) ) ;
return adapter . getMaterial ( ) ;
}
public Texture2D readTexture ( JsonObject texture ) {
return readTexture ( texture , false ) ;
return mat ;
}
}
private Texture2D readTexture ( JsonObject texture ) {
public Texture2D readTexture ( JsonObject texture , boolean flip ) {
if ( texture = = null ) {
if ( texture = = null ) {
return null ;
return null ;
}
}
@ -548,19 +583,22 @@ public class GltfLoader implements AssetLoader {
Integer sourceIndex = getAsInteger ( textureData , "source" ) ;
Integer sourceIndex = getAsInteger ( textureData , "source" ) ;
Integer samplerIndex = getAsInteger ( textureData , "sampler" ) ;
Integer samplerIndex = getAsInteger ( textureData , "sampler" ) ;
Texture2D texture2d = readImage ( sourceIndex ) ;
Texture2D texture2d = readImage ( sourceIndex , flip ) ;
readSampler ( samplerIndex , texture2d ) ;
readSampler ( samplerIndex , texture2d ) ;
texture2d = customContentManager . readExtension ( texture , texture2d ) ;
return texture2d ;
return texture2d ;
}
}
private Texture2D readImage ( int sourceIndex ) {
public Texture2D readImage ( int sourceIndex , boolean flip ) {
if ( images = = null ) {
if ( images = = null ) {
throw new AssetLoadException ( "No image defined" ) ;
throw new AssetLoadException ( "No image defined" ) ;
}
}
JsonObject image = images . get ( sourceIndex ) . getAsJsonObject ( ) ;
JsonObject image = images . get ( sourceIndex ) . getAsJsonObject ( ) ;
String uri = getAsString ( image , "uri" ) ;
String uri = getAsString ( image , "uri" ) ;
Texture2D result ;
if ( uri = = null ) {
if ( uri = = null ) {
//Image is embed in a buffer not supported yet
//Image is embed in a buffer not supported yet
//TODO support images embed in a buffer
//TODO support images embed in a buffer
@ -571,18 +609,22 @@ public class GltfLoader implements AssetLoader {
byte [ ] data = DatatypeConverter . parseBase64Binary ( uriInfo [ 1 ] ) ;
byte [ ] data = DatatypeConverter . parseBase64Binary ( uriInfo [ 1 ] ) ;
String headerInfo = uriInfo [ 0 ] . split ( ";" ) [ 0 ] ;
String headerInfo = uriInfo [ 0 ] . split ( ";" ) [ 0 ] ;
String extension = headerInfo . split ( "/" ) [ 1 ] ;
String extension = headerInfo . split ( "/" ) [ 1 ] ;
TextureKey key = new TextureKey ( "image" + sourceIndex + "." + extension , false ) ;
TextureKey key = new TextureKey ( "image" + sourceIndex + "." + extension , flip ) ;
return ( Texture2D ) info . getManager ( ) . loadAssetFromStream ( key , new ByteArrayInputStream ( data ) ) ;
result = ( Texture2D ) info . getManager ( ) . loadAssetFromStream ( key , new ByteArrayInputStream ( data ) ) ;
} else {
} else {
//external file image
//external file image
TextureKey key = new TextureKey ( info . getKey ( ) . getFolder ( ) + uri , false ) ;
TextureKey key = new TextureKey ( info . getKey ( ) . getFolder ( ) + uri , flip ) ;
Texture tex = info . getManager ( ) . loadTexture ( key ) ;
Texture tex = info . getManager ( ) . loadTexture ( key ) ;
return ( Texture2D ) tex ;
result = ( Texture2D ) tex ;
}
}
result = customContentManager . readExtension ( image , result ) ;
return result ;
}
}
private void readAnimation ( int animationIndex ) throws IOException {
public void readAnimation ( int animationIndex ) throws IOException {
JsonObject animation = animations . get ( animationIndex ) . getAsJsonObject ( ) ;
JsonObject animation = animations . get ( animationIndex ) . getAsJsonObject ( ) ;
JsonArray channels = animation . getAsJsonArray ( "channels" ) ;
JsonArray channels = animation . getAsJsonArray ( "channels" ) ;
JsonArray samplers = animation . getAsJsonArray ( "samplers" ) ;
JsonArray samplers = animation . getAsJsonArray ( "samplers" ) ;
@ -705,6 +747,8 @@ public class GltfLoader implements AssetLoader {
}
}
}
}
anim = customContentManager . readExtension ( animation , anim ) ;
if ( skinIndex ! = - 1 ) {
if ( skinIndex ! = - 1 ) {
//we have a bone animation.
//we have a bone animation.
SkinData skin = fetchFromCache ( "skins" , skinIndex , SkinData . class ) ;
SkinData skin = fetchFromCache ( "skins" , skinIndex , SkinData . class ) ;
@ -742,7 +786,7 @@ public class GltfLoader implements AssetLoader {
}
}
}
}
private void readSampler ( int samplerIndex , Texture2D texture ) {
public void readSampler ( int samplerIndex , Texture2D texture ) {
if ( samplers = = null ) {
if ( samplers = = null ) {
throw new AssetLoadException ( "No samplers defined" ) ;
throw new AssetLoadException ( "No samplers defined" ) ;
}
}
@ -762,7 +806,7 @@ public class GltfLoader implements AssetLoader {
texture . setWrap ( Texture . WrapAxis . T , wrapT ) ;
texture . setWrap ( Texture . WrapAxis . T , wrapT ) ;
}
}
private void readSkins ( ) throws IOException {
public void readSkins ( ) throws IOException {
if ( skins = = null ) {
if ( skins = = null ) {
//no skins, no bone animation.
//no skins, no bone animation.
return ;
return ;
@ -870,7 +914,7 @@ public class GltfLoader implements AssetLoader {
return null ;
return null ;
}
}
private Bone readNodeAsBone ( int nodeIndex , int boneIndex , int skinIndex , Matrix4f modelBindMatrix ) throws IOException {
public Bone readNodeAsBone ( int nodeIndex , int boneIndex , int skinIndex , Matrix4f modelBindMatrix ) throws IOException {
BoneWrapper boneWrapper = fetchFromCache ( "nodes" , nodeIndex , BoneWrapper . class ) ;
BoneWrapper boneWrapper = fetchFromCache ( "nodes" , nodeIndex , BoneWrapper . class ) ;
if ( boneWrapper ! = null ) {
if ( boneWrapper ! = null ) {
@ -927,8 +971,11 @@ public class GltfLoader implements AssetLoader {
spatial . removeControl ( animControl ) ;
spatial . removeControl ( animControl ) ;
}
}
spatial . addControl ( skinData . animControl ) ;
if ( skinData . animControl ! = null ) {
spatial . addControl ( skinData . skeletonControl ) ;
spatial . addControl ( skinData . animControl ) ;
spatial . addControl ( skinData . skeletonControl ) ;
}
}
}
}
}
@ -937,7 +984,7 @@ public class GltfLoader implements AssetLoader {
return getAsString ( meshData , "name" ) ;
return getAsString ( meshData , "name" ) ;
}
}
private < T > T fetchFromCache ( String name , int index , Class < T > type ) {
public < T > T fetchFromCache ( String name , int index , Class < T > type ) {
Object [ ] data = dataCache . get ( name ) ;
Object [ ] data = dataCache . get ( name ) ;
if ( data = = null ) {
if ( data = = null ) {
return null ;
return null ;
@ -945,7 +992,7 @@ public class GltfLoader implements AssetLoader {
return type . cast ( data [ index ] ) ;
return type . cast ( data [ index ] ) ;
}
}
private void addToCache ( String name , int index , Object object , int maxLength ) {
public void addToCache ( String name , int index , Object object , int maxLength ) {
Object [ ] data = dataCache . get ( name ) ;
Object [ ] data = dataCache . get ( name ) ;
if ( data = = null ) {
if ( data = = null ) {
data = new Object [ maxLength ] ;
data = new Object [ maxLength ] ;
@ -954,6 +1001,30 @@ public class GltfLoader implements AssetLoader {
data [ index ] = object ;
data [ index ] = object ;
}
}
public AssetInfo getInfo ( ) {
return info ;
}
public JsonObject getDocRoot ( ) {
return docRoot ;
}
public Node getRootNode ( ) {
return rootNode ;
}
public static class WeightData {
float value ;
short index ;
int componentSize ;
public WeightData ( float value , short index , int componentSize ) {
this . value = value ;
this . index = index ;
this . componentSize = componentSize ;
}
}
private class AnimData {
private class AnimData {
Float length ;
Float length ;
float [ ] times ;
float [ ] times ;