package com.gebauz.bauzoid2.graphics.model;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.utils.JsonReader;
import com.badlogic.gdx.utils.JsonValue;
import com.gebauz.bauzoid2.file.FileUtil;
import com.gebauz.bauzoid2.game.Consts;
import com.gebauz.bauzoid2.game.Engine;
import com.gebauz.bauzoid2.graphics.animation.Animation;
import com.gebauz.bauzoid2.graphics.animation.BoneKeyframes;
import com.gebauz.bauzoid2.graphics.geometry.IndexStream;
import com.gebauz.bauzoid2.graphics.geometry.VertexAttribute;
import com.gebauz.bauzoid2.graphics.geometry.VertexStream;
import com.gebauz.bauzoid2.graphics.util.Transform;
import com.gebauz.bauzoid2.math.Matrix4;
import com.gebauz.bauzoid2.math.Quaternion;
import com.gebauz.bauzoid2.math.Vector3;
import java.lang.reflect.Field;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import sun.security.provider.certpath.Vertex;
public class GdxModelUtil
{
public final static int NUM_POSITION_COORDS =
3;
public final static int NUM_NORMAL_COORDS =
3;
public final static int NUM_TEXCOORD_COORDS =
2;
public final static int NUM_COLOR_COORDS =
4;
public final static int NUM_COLOR_PACKED_COORDS =
1;
public final static int NUM_TANGENT_COORDS =
3;
public final static int NUM_BINORMAL_COORDS =
3;
public final static int NUM_BLENDWEIGHT_COORDS =
2;
public final static int NUM_COMBINED_BLENDINDICES_COORDS =
4;
public final static int NUM_COMBINED_BLENDWEIGHTS_COORDS =
4;
public static class MeshData
{
public String[] attributes =
null;
public float[] vertices =
null;
public int numIndices =
0;
public ArrayList<PartData
> parts =
new ArrayList<PartData
>();
}
public static class PartData
{
public String id =
null;
public String type =
null;
public short[] indices =
null;
}
public static class MaterialData
{
public String id =
null;
public ArrayList<TextureData
> textures =
new ArrayList<TextureData
>();
float[] ambient =
null;
float[] diffuse =
null;
float[] emissive =
null;
float opacity = 1.0f
;
float[] specular =
null;
float shininess = 1.0f
;
}
public static class TextureData
{
public String id =
null;
public String type =
null;
public String filename =
null;
public boolean isAsync =
false;
}
public static class NodePartData
{
public String subMeshId =
null;
public String materialId =
null;
public ArrayList<BoneData
> bones =
new ArrayList<BoneData
>();
// TODO: uvmapping
}
public static class NodeData
{
public String id =
null;
public float[] translation =
null;
public float[] rotation =
null;
public float[] scale =
null;
public ArrayList<NodePartData
> parts =
new ArrayList<NodePartData
>();
public ArrayList<NodeData
> children =
new ArrayList<NodeData
>();
public NodeData parent =
null;
}
public static class BoneData
{
String nodeId =
null;
public float[] translation =
null;
public float[] rotation =
null;
public float[] scale =
null;
}
public static class KeyframeData
{
float time = 0.0f
;
public float[] translation =
null;
public float[] rotation =
null;
public float[] scale =
null;
}
public static class BoneKeyframeData
{
public String boneId =
null;
public ArrayList<KeyframeData
> keyframes =
new ArrayList<KeyframeData
>();
}
public static class AnimationData
{
public String id =
null;
public ArrayList<BoneKeyframeData
> boneKeys =
new ArrayList<BoneKeyframeData
>();
}
public static class GdxModelDescriptor
{
public int[] version =
null;
public String id =
null;
public ArrayList<MeshData
> meshes =
new ArrayList<MeshData
>();
public ArrayList<MaterialData
> materials =
new ArrayList<MaterialData
>();
public ArrayList<NodeData
> nodes =
new ArrayList<NodeData
>();
public ArrayList<AnimationData
> animations =
new ArrayList<AnimationData
>();
public GdxModelDescriptor
()
{
}
}
private GdxModelUtil
() {}
public static GdxModelDescriptor readModel
(String filename
)
{
String modelFile = FileUtil.
loadString(filename
);
JsonValue root =
new JsonReader
().
parse(modelFile
);
GdxModelDescriptor descriptor =
new GdxModelDescriptor
();
for (JsonValue entry : root
)
{
if (entry.
name.
equalsIgnoreCase("version"))
{
try
{
Field f = GdxModelDescriptor.
class.
getField(entry.
name);
if (f.
getType().
isArray())
{
if (f.
getType().
getComponentType() ==
int.
class)
{
f.
set(descriptor, entry.
asIntArray());
}
}
Engine.
log("bla");
}
catch (Exception ex
)
{
Engine.
log(ex.
getMessage());
}
//int[] version = entry.asIntArray();
Engine.
log("G3DJ Version: " + descriptor.
version[0] +
"." + descriptor.
version[1]);
}
else if (entry.
name.
equalsIgnoreCase("id"))
{
descriptor.
id = entry.
asString();
}
else if (entry.
name.
equalsIgnoreCase("meshes"))
{
for (JsonValue meshEntry : entry
)
{
descriptor.
meshes.
add(processMesh
(meshEntry
));
}
}
else if (entry.
name.
equalsIgnoreCase("materials"))
{
for (JsonValue materialEntry : entry
)
{
descriptor.
materials.
add(processMaterial
(materialEntry
));
}
}
else if (entry.
name.
equalsIgnoreCase("nodes"))
{
for (JsonValue nodeEntry : entry
)
{
descriptor.
nodes.
add(processNode
(nodeEntry
));
}
}
else if (entry.
name.
equalsIgnoreCase("animations"))
{
for (JsonValue animationEntry : entry
)
{
descriptor.
animations.
add(processAnimation
(animationEntry
));
}
}
}
return descriptor
;
}
public static Model buildModel
(GdxModelDescriptor descriptor
)
{
return buildModel
(descriptor.
id, descriptor.
meshes, descriptor.
materials, descriptor.
nodes, descriptor.
animations);
}
public static Model buildModel
(String id,
ArrayList<MeshData
> meshDatas,
ArrayList<MaterialData
> materialDatas,
ArrayList<NodeData
> nodeDatas,
ArrayList<AnimationData
> anims
)
{
Model model =
new Model
(id
);
Mesh
[] meshes =
new Mesh
[meshDatas.
size()];
for (int meshIndex =
0; meshIndex
< meshDatas.
size(); meshIndex++
)
{
MeshData meshData = meshDatas.
get(meshIndex
);
meshes
[meshIndex
] =
new Mesh
();
ArrayList<VertexAttribute
> attribs =
new ArrayList<VertexAttribute
>();
int byteOffset =
0;
int coords =
0;
ArrayList<VertexStream
> vertexStreams = buildVertexStream
(attribs, meshData.
attributes, meshData.
vertices);
meshes
[meshIndex
].
getGeometry().
setVertexStreams(vertexStreams.
toArray(new VertexStream
[vertexStreams.
size()]));
short[] indices =
new short[meshData.
numIndices];
int indexOffset =
0;
MeshGroup
[] subMeshes =
new MeshGroup
[meshData.
parts.
size()];
for (int partIndex =
0; partIndex
< meshData.
parts.
size(); partIndex++
)
{
PartData part = meshData.
parts.
get(partIndex
);
System.
arraycopy(part.
indices,
0, indices, indexOffset, part.
indices.
length);
subMeshes
[partIndex
] =
new MeshGroup
(meshes
[meshIndex
], part.
id, indexOffset, indexOffset + part.
indices.
length);
indexOffset += part.
indices.
length;
}
meshes
[meshIndex
].
setMeshGroups(subMeshes
);
IndexStream is =
new IndexStream
();
is.
setData(indices
);
is.
upload();
meshes
[meshIndex
].
getGeometry().
setIndexStream(is
);
}
Material
[] materials =
new Material
[materialDatas.
size()];
for (int materialIndex =
0; materialIndex
< materialDatas.
size(); materialIndex++
)
{
// TODO: for now, only take first texture, always diffuse
MaterialData matData = materialDatas.
get(materialIndex
);
String textureFile =
null;
Texture texture =
null;
if (matData.
textures.
size() > 0)
{
TextureData texData = matData.
textures.
get(0);
textureFile = texData.
filename;
if (texData.
isAsync)
{
texture = Engine.
assets.
get(textureFile
);
}
else
{
texture =
new Texture
(Gdx.
files.
internal(textureFile
));
}
}
materials
[materialIndex
] =
new Material
(matData.
id, texture
);
//matData.textures
}
model.
setMeshes(meshes
);
model.
setMaterials(materials
);
int nodeCount = getTotalNodeCount
(nodeDatas
);
ArrayList<ModelPart
> partList =
new ArrayList<ModelPart
>();
ArrayList<NodePartData
> partDataList =
new ArrayList<NodePartData
>();
ModelNode
[] nodes =
new ModelNode
[nodeCount
];
int newNodeIndex =
0;
for (int nodeIndex =
0; nodeIndex
< nodeDatas.
size(); nodeIndex++
)
{
Deque
<NodeData
> stack =
new ArrayDeque
<NodeData
>();
Deque
<Integer> parentStack =
new ArrayDeque
<Integer>();
stack.
push(nodeDatas.
get(nodeIndex
));
parentStack.
push(-
1);
while (!stack.
isEmpty())
{
NodeData nodeData = stack.
pop();
int parentIndex = parentStack.
pop();
nodes
[newNodeIndex
] =
new ModelNode
(nodeData.
id, parentIndex
);
if (nodeData.
parts.
size() > 0)
{
ModelPart
[] parts =
new ModelPart
[nodeData.
parts.
size()];
for (int partIndex =
0; partIndex
< nodeData.
parts.
size(); partIndex++
)
{
NodePartData pair = nodeData.
parts.
get(partIndex
);
MeshGroup group = findSubMesh
(meshes, pair.
subMeshId);
Material material = findMaterial
(materials, pair.
materialId);
parts
[partIndex
] =
new ModelPart
(pair.
subMeshId, group, material
);
// for later wiring
partList.
add(parts
[partIndex
]);
partDataList.
add(pair
);
}
nodes
[newNodeIndex
].
parts = parts
;
}
if (nodeData.
scale !=
null)
nodes
[newNodeIndex
].
bindPose.
scale.
set(nodeData.
scale);
if (nodeData.
rotation !=
null)
nodes
[newNodeIndex
].
bindPose.
rotation.
set(nodeData.
rotation);
if (nodeData.
translation !=
null)
nodes
[newNodeIndex
].
bindPose.
translation.
set(nodeData.
translation);
nodes
[newNodeIndex
].
transform.
setFrom(nodes
[newNodeIndex
].
bindPose);
for (NodeData child : nodeData.
children)
{
stack.
push(child
);
parentStack.
push(newNodeIndex
);
}
newNodeIndex++
;
}
}
model.
setNodes(nodes
);
// wire together bone influences
for (int i =
0; i
< partList.
size(); i++
)
{
ModelPart part = partList.
get(i
);
NodePartData partData = partDataList.
get(i
);
if (partData.
bones.
size() ==
0)
continue;
ModelNode
[] influences =
new ModelNode
[partData.
bones.
size()];
Transform
[] transforms =
new Transform
[partData.
bones.
size()];
for (int j =
0; j
< partData.
bones.
size(); j++
)
{
influences
[j
] = model.
findNode(partData.
bones.
get(j
).
nodeId);
transforms
[j
] =
new Transform
();
transforms
[j
].
translation.
set(partData.
bones.
get(j
).
translation);
transforms
[j
].
rotation.
set(partData.
bones.
get(j
).
rotation);
transforms
[j
].
scale.
set(partData.
bones.
get(j
).
scale);
}
part.
setBones(influences, transforms
);
}
Animation
[] animations =
new Animation
[anims.
size()];
for (int i =
0; i
< anims.
size(); i++
)
{
AnimationData animData = anims.
get(i
);
animations
[i
] =
new Animation
(animData.
id);
float totalTime = 0.0f
;
BoneKeyframes
[] boneKeys =
new BoneKeyframes
[animData.
boneKeys.
size()];
for (int j =
0; j
< animData.
boneKeys.
size(); j++
)
{
BoneKeyframeData boneKeyData = animData.
boneKeys.
get(j
);
ModelNode bone = model.
findNode(boneKeyData.
boneId);
boneKeys
[j
] =
new BoneKeyframes
(bone
);
ArrayList<BoneKeyframes.
RotationKey> rotations =
new ArrayList<BoneKeyframes.
RotationKey>();
for (KeyframeData keyframe : boneKeyData.
keyframes)
{
if (keyframe.
translation !=
null)
{
}
if (keyframe.
rotation !=
null)
{
rotations.
add(new BoneKeyframes.
RotationKey(keyframe.
time,
new Quaternion
(keyframe.
rotation)));
}
if (keyframe.
scale !=
null)
{
}
if (keyframe.
time > totalTime
)
totalTime = keyframe.
time;
}
boneKeys
[j
].
setRotationKeys(rotations.
toArray(new BoneKeyframes.
RotationKey[rotations.
size()]));
}
animations
[i
].
setBoneKeys(boneKeys
);
animations
[i
].
setTotalTime(totalTime
);
}
model.
setAnimations(animations
);
return model
;
}
private static float[] toFloatArray
(ArrayList<Float> array
)
{
float[] rt =
new float[array.
size()];
for (int k =
0; k
< array.
size(); k++
)
rt
[k
] = array.
get(k
);
return rt
;
}
private static ArrayList<VertexStream
> buildVertexStream
(ArrayList<VertexAttribute
> attribs,
String[] attributes,
float[] vertices
)
{
int coordsPerVertex = calcVertexSize
(attributes
);
int numVertices = vertices.
length / coordsPerVertex
;
ArrayList<VertexStream
> result =
new ArrayList<VertexStream
>();
float[] coords =
null;
float[] normals =
null;
float[] texcoords =
null;
float[] blendIndices =
null;
float[] blendWeights =
null;
int offset =
0;
int blendOffset =
0;
for (String attr : attributes
)
{
if (attr.
equalsIgnoreCase("POSITION"))
{
coords =
new float[numVertices
*NUM_POSITION_COORDS
];
extractInterleaved
(coords,
0, NUM_POSITION_COORDS, vertices, offset, coordsPerVertex, NUM_POSITION_COORDS
);
offset += NUM_POSITION_COORDS
;
result.
add(createIndividualVertexStream
(coords, VertexAttribute.
POSITION, NUM_POSITION_COORDS,
"POSITION"));
}
else if (attr.
equalsIgnoreCase("NORMAL"))
{
normals =
new float[numVertices
*NUM_NORMAL_COORDS
];
extractInterleaved
(normals,
0, NUM_NORMAL_COORDS, vertices, offset, coordsPerVertex, NUM_NORMAL_COORDS
);
offset += NUM_NORMAL_COORDS
;
result.
add(createIndividualVertexStream
(normals, VertexAttribute.
NORMAL, NUM_NORMAL_COORDS,
"NORMAL"));
}
else if (attr.
equalsIgnoreCase("TEXCOORD0"))
{
texcoords =
new float[numVertices
*NUM_TEXCOORD_COORDS
];
extractInterleaved
(texcoords,
0, NUM_TEXCOORD_COORDS, vertices, offset, coordsPerVertex, NUM_TEXCOORD_COORDS
);
offset += NUM_TEXCOORD_COORDS
;
result.
add(createIndividualVertexStream
(texcoords, VertexAttribute.
TEXCOORD0, NUM_TEXCOORD_COORDS,
"TEXCOORD0"));
}
else if (attr.
startsWith("BLENDWEIGHT"))
{
if (blendIndices ==
null)
blendIndices =
new float[numVertices
*NUM_COMBINED_BLENDINDICES_COORDS
];
if (blendWeights ==
null)
blendWeights =
new float[numVertices
*NUM_COMBINED_BLENDWEIGHTS_COORDS
];
extractInterleaved
(blendIndices, blendOffset, NUM_COMBINED_BLENDINDICES_COORDS, vertices, offset, coordsPerVertex,
1);
extractInterleaved
(blendWeights, blendOffset, NUM_COMBINED_BLENDWEIGHTS_COORDS, vertices, offset+
1, coordsPerVertex,
1);
blendOffset++
;
offset += NUM_BLENDWEIGHT_COORDS
;
}
}
if ((blendIndices
!=
null) && (blendWeights
!=
null))
{
result.
add(createIndividualVertexStream
(blendIndices, VertexAttribute.
BLENDINDICES, NUM_COMBINED_BLENDINDICES_COORDS,
"BLENDINDICES"));
result.
add(createIndividualVertexStream
(blendWeights, VertexAttribute.
BLENDWEIGHTS, NUM_COMBINED_BLENDWEIGHTS_COORDS,
"BLENDWEIGHTS"));
}
return result
;
}
private static VertexStream createIndividualVertexStream
(float[] data,
int attribute,
int numCoords,
String name
)
{
VertexAttribute
[] vertexAttribs =
new VertexAttribute
[]
{
new VertexAttribute
(attribute, numCoords,
0)
};
VertexStream vs =
new VertexStream
(VertexStream.
StreamType.
INDIVIDUAL, name, vertexAttribs,
false);
vs.
setData(data, numCoords, numCoords
* Consts.
SIZEOF_FLOAT);
vs.
upload();
return vs
;
}
private static void extractInterleaved
(float[] dest,
int destOffset,
int destStride,
float[] src,
int srcOffset,
int srcStride,
int count
)
{
int targetIndex =
0;
int sourceIndex =
0;
while (sourceIndex
< src.
length)
{
for (int j =
0; j
< count
; j++
)
{
dest
[targetIndex + destOffset + j
] = src
[sourceIndex + srcOffset + j
];
}
targetIndex += destStride
;
sourceIndex += srcStride
;
}
}
public static int calcVertexSize
(String[] attribs
)
{
int result =
0;
for (String attr : attribs
)
{
if (attr.
equalsIgnoreCase("POSITION"))
result += NUM_POSITION_COORDS
;
else if (attr.
equalsIgnoreCase("NORMAL"))
result += NUM_NORMAL_COORDS
;
else if (attr.
equalsIgnoreCase("COLOR"))
result += NUM_COLOR_COORDS
;
else if (attr.
equalsIgnoreCase("COLORPACKED"))
result += NUM_COLOR_PACKED_COORDS
;
else if (attr.
equalsIgnoreCase("TANGENT"))
result += NUM_TANGENT_COORDS
;
else if (attr.
equalsIgnoreCase("BINORMAL"))
result += NUM_BINORMAL_COORDS
;
else if (attr.
startsWith("TEXCOORD"))
result += NUM_TEXCOORD_COORDS
;
else if (attr.
startsWith("BLENDWEIGHT"))
result += NUM_BLENDWEIGHT_COORDS
;
}
return result
;
}
public static int getTotalNodeCount
(ArrayList<NodeData
> nodeDatas
)
{
int nodeCount =
0;
for (int nodeIndex =
0; nodeIndex
< nodeDatas.
size(); nodeIndex++
)
{
NodeData rootNode = nodeDatas.
get(nodeIndex
);
Deque
<NodeData
> stack =
new ArrayDeque
<NodeData
>();
stack.
push(rootNode
);
while (!stack.
isEmpty())
{
NodeData node = stack.
pop();
nodeCount++
;
for (int j =
0; j
< node.
children.
size(); j++
)
{
stack.
push(node.
children.
get(j
));
}
}
}
return nodeCount
;
}
public static MeshGroup findSubMesh
(Mesh
[] meshes,
String id
)
{
for (Mesh mesh : meshes
)
{
for (MeshGroup group : mesh.
getMeshGroups())
{
if (id.
equalsIgnoreCase(group.
getName()))
return group
;
}
}
return null;
}
public static Material findMaterial
(Material
[] materials,
String id
)
{
for (Material mat : materials
)
{
if (id.
equalsIgnoreCase(mat.
getName()))
return mat
;
}
return null;
}
public static MeshData processMesh
(JsonValue meshesEntry
)
{
MeshData result =
new MeshData
();
for (JsonValue entry : meshesEntry
)
{
if (entry.
name.
equalsIgnoreCase("attributes"))
{
result.
attributes = entry.
asStringArray();
}
else if (entry.
name.
equalsIgnoreCase("vertices"))
{
result.
vertices = entry.
asFloatArray();
}
else if (entry.
name.
equalsIgnoreCase("parts"))
{
result.
numIndices =
0;
for (JsonValue partEntry : entry
)
{
result.
parts.
add(processParts
(partEntry
));
result.
numIndices += result.
parts.
get(result.
parts.
size()-
1).
indices.
length;
}
}
}
return result
;
}
public static PartData processParts
(JsonValue partsEntry
)
{
PartData result =
new PartData
();
for (JsonValue entry : partsEntry
)
{
if (entry.
name.
equalsIgnoreCase("id"))
{
result.
id = entry.
asString();
}
else if (entry.
name.
equalsIgnoreCase("type"))
{
result.
type = entry.
asString();
}
else if (entry.
name.
equalsIgnoreCase("indices"))
{
result.
indices = entry.
asShortArray();
}
}
return result
;
}
public static MaterialData processMaterial
(JsonValue materialsEntry
)
{
MaterialData result =
new MaterialData
();
for (JsonValue entry : materialsEntry
)
{
if (entry.
name.
equalsIgnoreCase("id"))
{
result.
id = entry.
asString();
}
else if (entry.
name.
equalsIgnoreCase("textures"))
{
for (JsonValue textureEntry : entry
)
{
result.
textures.
add(processTexture
(textureEntry
));
}
}
else if (entry.
name.
equalsIgnoreCase("ambient"))
{
result.
ambient = entry.
asFloatArray();
}
else if (entry.
name.
equalsIgnoreCase("diffuse"))
{
result.
diffuse = entry.
asFloatArray();
}
else if (entry.
name.
equalsIgnoreCase("emissive"))
{
result.
emissive = entry.
asFloatArray();
}
else if (entry.
name.
equalsIgnoreCase("opacity"))
{
result.
opacity = entry.
asFloat();
}
else if (entry.
name.
equalsIgnoreCase("specular"))
{
result.
specular = entry.
asFloatArray();
}
else if (entry.
name.
equalsIgnoreCase("shininess"))
{
result.
shininess = entry.
asFloat();
}
}
return result
;
}
public static TextureData processTexture
(JsonValue textureEntry
)
{
TextureData result =
new TextureData
();
for (JsonValue entry : textureEntry
)
{
if (entry.
name.
equalsIgnoreCase("id"))
{
result.
id = entry.
asString();
}
else if (entry.
name.
equalsIgnoreCase("filename"))
{
result.
filename = entry.
asString();
}
else if (entry.
name.
equalsIgnoreCase("type"))
{
result.
type = entry.
asString();
}
}
return result
;
}
public static NodeData processNode
(JsonValue nodeEntry
)
{
NodeData result =
new NodeData
();
for (JsonValue entry : nodeEntry
)
{
if (entry.
name.
equalsIgnoreCase("id"))
{
result.
id = entry.
asString();
}
else if (entry.
name.
equalsIgnoreCase("translation"))
{
result.
translation = entry.
asFloatArray();
}
else if (entry.
name.
equalsIgnoreCase("rotation"))
{
result.
rotation = entry.
asFloatArray();
}
else if (entry.
name.
equalsIgnoreCase("scale"))
{
result.
scale = entry.
asFloatArray();
}
else if (entry.
name.
equalsIgnoreCase("parts"))
{
for (JsonValue partEntry : entry
)
{
result.
parts.
add(processNodePart
(partEntry
));
}
}
else if (entry.
name.
equalsIgnoreCase("children"))
{
for (JsonValue childEntry : entry
)
{
NodeData node = processNode
(childEntry
);
node.
parent = result
;
result.
children.
add(node
);
}
}
}
return result
;
}
public static NodePartData processNodePart
(JsonValue partEntry
)
{
NodePartData result =
new NodePartData
();
for (JsonValue entry : partEntry
)
{
if (entry.
name.
equalsIgnoreCase("meshpartid"))
{
result.
subMeshId = entry.
asString();
}
else if (entry.
name.
equalsIgnoreCase("materialid"))
{
result.
materialId = entry.
asString();
}
else if (entry.
name.
equalsIgnoreCase("bones"))
{
for (JsonValue boneEntry : entry
)
{
result.
bones.
add(processBone
(boneEntry
));
}
}
}
return result
;
}
public static BoneData processBone
(JsonValue boneEntry
)
{
BoneData result =
new BoneData
();
for (JsonValue entry : boneEntry
)
{
if (entry.
name.
equalsIgnoreCase("node"))
{
result.
nodeId = entry.
asString();
}
else if (entry.
name.
equalsIgnoreCase("translation"))
{
result.
translation = entry.
asFloatArray();
}
else if (entry.
name.
equalsIgnoreCase("rotation"))
{
result.
rotation = entry.
asFloatArray();
}
else if (entry.
name.
equalsIgnoreCase("scale"))
{
result.
scale = entry.
asFloatArray();
}
}
return result
;
}
public static AnimationData processAnimation
(JsonValue animEntry
)
{
AnimationData result =
new AnimationData
();
for (JsonValue entry : animEntry
)
{
if (entry.
name.
equalsIgnoreCase("id"))
{
result.
id = entry.
asString();
}
else if (entry.
name.
equalsIgnoreCase("bones"))
{
for (JsonValue boneKeyEntry : entry
)
{
result.
boneKeys.
add(processBoneKeyframe
(boneKeyEntry
));
}
}
}
return result
;
}
public static BoneKeyframeData processBoneKeyframe
(JsonValue boneKeyEntry
)
{
BoneKeyframeData result =
new BoneKeyframeData
();
for (JsonValue entry : boneKeyEntry
)
{
if (entry.
name.
equalsIgnoreCase("boneId"))
{
result.
boneId = entry.
asString();
}
else if (entry.
name.
equalsIgnoreCase("keyframes"))
{
for (JsonValue keyframeEntry : entry
)
{
result.
keyframes.
add(processKeyframe
(keyframeEntry
));
}
}
}
return result
;
}
public static KeyframeData processKeyframe
(JsonValue keyframeEntry
)
{
KeyframeData result =
new KeyframeData
();
for (JsonValue entry : keyframeEntry
)
{
if (entry.
name.
equalsIgnoreCase("keytime"))
{
result.
time = entry.
asFloat();
}
else if (entry.
name.
equalsIgnoreCase("translation"))
{
result.
translation = entry.
asFloatArray();
}
else if (entry.
name.
equalsIgnoreCase("rotation"))
{
result.
rotation = entry.
asFloatArray();
}
else if (entry.
name.
equalsIgnoreCase("scale"))
{
result.
scale = entry.
asFloatArray();
}
}
return result
;
}
}