Spatial tracks now can keep a reference to the spatial they apply to. This allows to group multiples spatial tracks in a single animation.
This commit is contained in:
parent
6b3093aa3e
commit
d7b2e08d95
@ -93,6 +93,24 @@ public class Animation implements Savable, Cloneable, JmeCloneable {
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the length of the animation
|
||||||
|
*
|
||||||
|
* @param length
|
||||||
|
*/
|
||||||
|
public void setLength(float length) {
|
||||||
|
this.length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the name of the animation
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method sets the current time of the animation.
|
* This method sets the current time of the animation.
|
||||||
* This method behaves differently for every known track type.
|
* This method behaves differently for every known track type.
|
||||||
@ -209,7 +227,7 @@ public class Animation implements Savable, Cloneable, JmeCloneable {
|
|||||||
// isn't cloned at all... even though they all implement clone() methods. -pspeed
|
// isn't cloned at all... even though they all implement clone() methods. -pspeed
|
||||||
SafeArrayList<Track> newTracks = new SafeArrayList<>(Track.class);
|
SafeArrayList<Track> newTracks = new SafeArrayList<>(Track.class);
|
||||||
for( Track track : tracks ) {
|
for( Track track : tracks ) {
|
||||||
if( track instanceof ClonableTrack ) {
|
if (track instanceof JmeCloneable) {
|
||||||
newTracks.add(cloner.clone(track));
|
newTracks.add(cloner.clone(track));
|
||||||
} else {
|
} else {
|
||||||
// this is the part that seems fishy
|
// this is the part that seems fishy
|
||||||
|
@ -39,6 +39,9 @@ import com.jme3.math.Quaternion;
|
|||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
import com.jme3.scene.Spatial;
|
import com.jme3.scene.Spatial;
|
||||||
import com.jme3.util.TempVars;
|
import com.jme3.util.TempVars;
|
||||||
|
import com.jme3.util.clone.Cloner;
|
||||||
|
import com.jme3.util.clone.JmeCloneable;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
@ -47,7 +50,7 @@ import java.util.Arrays;
|
|||||||
*
|
*
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
public class SpatialTrack implements Track {
|
public class SpatialTrack implements Track, JmeCloneable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translations of the track.
|
* Translations of the track.
|
||||||
@ -64,6 +67,12 @@ public class SpatialTrack implements Track {
|
|||||||
*/
|
*/
|
||||||
private CompactVector3Array scales;
|
private CompactVector3Array scales;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The spatial to which this track applies.
|
||||||
|
* Note that this is optional, if no spatial is defined, the AnimControl's Spatial will be used.
|
||||||
|
*/
|
||||||
|
private Spatial trackSpatial;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The times of the animations frames.
|
* The times of the animations frames.
|
||||||
*/
|
*/
|
||||||
@ -97,7 +106,10 @@ public class SpatialTrack implements Track {
|
|||||||
* the current time of the animation
|
* the current time of the animation
|
||||||
*/
|
*/
|
||||||
public void setTime(float time, float weight, AnimControl control, AnimChannel channel, TempVars vars) {
|
public void setTime(float time, float weight, AnimControl control, AnimChannel channel, TempVars vars) {
|
||||||
Spatial spatial = control.getSpatial();
|
Spatial spatial = trackSpatial;
|
||||||
|
if (spatial == null) {
|
||||||
|
spatial = control.getSpatial();
|
||||||
|
}
|
||||||
|
|
||||||
Vector3f tempV = vars.vect1;
|
Vector3f tempV = vars.vect1;
|
||||||
Vector3f tempS = vars.vect2;
|
Vector3f tempS = vars.vect2;
|
||||||
@ -153,10 +165,12 @@ public class SpatialTrack implements Track {
|
|||||||
tempS.interpolateLocal(tempS2, blend);
|
tempS.interpolateLocal(tempS2, blend);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (translations != null)
|
if (translations != null) {
|
||||||
spatial.setLocalTranslation(tempV);
|
spatial.setLocalTranslation(tempV);
|
||||||
if (rotations != null)
|
}
|
||||||
|
if (rotations != null) {
|
||||||
spatial.setLocalRotation(tempQ);
|
spatial.setLocalRotation(tempQ);
|
||||||
|
}
|
||||||
if (scales != null) {
|
if (scales != null) {
|
||||||
spatial.setLocalScale(tempS);
|
spatial.setLocalScale(tempS);
|
||||||
}
|
}
|
||||||
@ -236,17 +250,26 @@ public class SpatialTrack implements Track {
|
|||||||
return times == null ? 0 : times[times.length - 1] - times[0];
|
return times == null ? 0 : times[times.length - 1] - times[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Track clone() {
|
||||||
|
return (Track) jmeClone();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float[] getKeyFrameTimes() {
|
public float[] getKeyFrameTimes() {
|
||||||
return times;
|
return times;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void setTrackSpatial(Spatial trackSpatial) {
|
||||||
* This method creates a clone of the current object.
|
this.trackSpatial = trackSpatial;
|
||||||
* @return a clone of the current object
|
}
|
||||||
*/
|
|
||||||
|
public Spatial getTrackSpatial() {
|
||||||
|
return trackSpatial;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SpatialTrack clone() {
|
public Object jmeClone() {
|
||||||
int tablesLength = times.length;
|
int tablesLength = times.length;
|
||||||
|
|
||||||
float[] timesCopy = this.times.clone();
|
float[] timesCopy = this.times.clone();
|
||||||
@ -258,6 +281,11 @@ public class SpatialTrack implements Track {
|
|||||||
return new SpatialTrack(timesCopy, translationsCopy, rotationsCopy, scalesCopy);
|
return new SpatialTrack(timesCopy, translationsCopy, rotationsCopy, scalesCopy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cloneFields(Cloner cloner, Object original) {
|
||||||
|
this.trackSpatial = cloner.clone(((SpatialTrack) original).trackSpatial);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(JmeExporter ex) throws IOException {
|
public void write(JmeExporter ex) throws IOException {
|
||||||
OutputCapsule oc = ex.getCapsule(this);
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
@ -265,6 +293,7 @@ public class SpatialTrack implements Track {
|
|||||||
oc.write(rotations, "rotations", null);
|
oc.write(rotations, "rotations", null);
|
||||||
oc.write(times, "times", null);
|
oc.write(times, "times", null);
|
||||||
oc.write(scales, "scales", null);
|
oc.write(scales, "scales", null);
|
||||||
|
oc.write(trackSpatial, "trackSpatial", null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -274,5 +303,6 @@ public class SpatialTrack implements Track {
|
|||||||
rotations = (CompactQuaternionArray) ic.readSavable("rotations", null);
|
rotations = (CompactQuaternionArray) ic.readSavable("rotations", null);
|
||||||
times = ic.readFloatArray("times", null);
|
times = ic.readFloatArray("times", null);
|
||||||
scales = (CompactVector3Array) ic.readSavable("scales", null);
|
scales = (CompactVector3Array) ic.readSavable("scales", null);
|
||||||
|
trackSpatial = (Spatial) ic.readSavable("trackSpatial", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
|
|
||||||
JsonPrimitive defaultScene = root.getAsJsonPrimitive("scene");
|
JsonPrimitive defaultScene = root.getAsJsonPrimitive("scene");
|
||||||
|
|
||||||
Node n = loadScenes(defaultScene);
|
Node n = readScenes(defaultScene);
|
||||||
|
|
||||||
setupControls();
|
setupControls();
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
return "2.0".equals(version);
|
return "2.0".equals(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node loadScenes(JsonPrimitive defaultScene) throws IOException {
|
private Node readScenes(JsonPrimitive defaultScene) 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");
|
||||||
@ -141,15 +141,15 @@ 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");
|
||||||
for (JsonElement node : sceneNodes) {
|
for (JsonElement node : sceneNodes) {
|
||||||
loadChild(sceneNode, node);
|
readChild(sceneNode, node);
|
||||||
}
|
}
|
||||||
root.attachChild(sceneNode);
|
root.attachChild(sceneNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Loading animations
|
//Loading animations
|
||||||
if (animations != null) {
|
if (animations != null) {
|
||||||
for (JsonElement animation : animations) {
|
for (int i = 0; i < animations.size(); i++) {
|
||||||
loadAnimation(animation.getAsJsonObject());
|
readAnimation(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +162,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object loadNode(int nodeIndex) throws IOException {
|
private 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 Bone) {
|
if (obj instanceof Bone) {
|
||||||
@ -183,7 +183,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
|
|
||||||
//there is a mesh in this node, however gltf can split meshes in primitives (some kind of sub meshes),
|
//there is a mesh in this node, however gltf can split meshes in primitives (some kind of sub meshes),
|
||||||
//We don't have this in JME so we have to make one mesh and one Geometry for each primitive.
|
//We don't have this in JME so we have to make one mesh and one Geometry for each primitive.
|
||||||
Geometry[] primitives = loadMeshPrimitives(meshIndex);
|
Geometry[] primitives = readMeshPrimitives(meshIndex);
|
||||||
if (primitives.length == 1 && children == null) {
|
if (primitives.length == 1 && children == null) {
|
||||||
//only one geometry, let's not wrap it in another node unless the node has children.
|
//only one geometry, let's not wrap it in another node unless the node has children.
|
||||||
spatial = primitives[0];
|
spatial = primitives[0];
|
||||||
@ -195,7 +195,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
}
|
}
|
||||||
spatial = node;
|
spatial = node;
|
||||||
}
|
}
|
||||||
spatial.setName(loadMeshName(meshIndex));
|
spatial.setName(readMeshName(meshIndex));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//no mesh, we have a node. Can be a camera node or a regular node.
|
//no mesh, we have a node. Can be a camera node or a regular node.
|
||||||
@ -214,22 +214,22 @@ public class GltfLoader implements AssetLoader {
|
|||||||
|
|
||||||
if (children != null) {
|
if (children != null) {
|
||||||
for (JsonElement child : children) {
|
for (JsonElement child : children) {
|
||||||
loadChild(spatial, child);
|
readChild(spatial, child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (spatial.getName() == null) {
|
if (spatial.getName() == null) {
|
||||||
spatial.setName(getAsString(nodeData.getAsJsonObject(), "name"));
|
spatial.setName(getAsString(nodeData.getAsJsonObject(), "name"));
|
||||||
}
|
}
|
||||||
spatial.setLocalTransform(loadTransforms(nodeData));
|
spatial.setLocalTransform(readTransforms(nodeData));
|
||||||
|
|
||||||
addToCache("nodes", nodeIndex, spatial, nodes.size());
|
addToCache("nodes", nodeIndex, spatial, nodes.size());
|
||||||
return spatial;
|
return spatial;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadChild(Spatial parent, JsonElement child) throws IOException {
|
private void readChild(Spatial parent, JsonElement child) throws IOException {
|
||||||
int index = child.getAsInt();
|
int index = child.getAsInt();
|
||||||
Object loaded = loadNode(child.getAsInt());
|
Object loaded = readNode(child.getAsInt());
|
||||||
if (loaded instanceof Spatial) {
|
if (loaded instanceof Spatial) {
|
||||||
((Node) parent).attachChild((Spatial) loaded);
|
((Node) parent).attachChild((Spatial) loaded);
|
||||||
} else if (loaded instanceof Bone) {
|
} else if (loaded instanceof Bone) {
|
||||||
@ -240,7 +240,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Transform loadTransforms(JsonObject nodeData) {
|
private 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) {
|
||||||
@ -280,7 +280,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Geometry[] loadMeshPrimitives(int meshIndex) throws IOException {
|
private 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.
|
||||||
@ -305,12 +305,12 @@ public class GltfLoader implements AssetLoader {
|
|||||||
mesh.setMode(getMeshMode(mode));
|
mesh.setMode(getMeshMode(mode));
|
||||||
Integer indices = getAsInteger(meshObject, "indices");
|
Integer indices = getAsInteger(meshObject, "indices");
|
||||||
if (indices != null) {
|
if (indices != null) {
|
||||||
mesh.setBuffer(loadAccessorData(indices, new VertexBufferPopulator(VertexBuffer.Type.Index)));
|
mesh.setBuffer(readAccessorData(indices, new VertexBufferPopulator(VertexBuffer.Type.Index)));
|
||||||
}
|
}
|
||||||
JsonObject attributes = meshObject.getAsJsonObject("attributes");
|
JsonObject attributes = meshObject.getAsJsonObject("attributes");
|
||||||
assertNotNull(attributes, "No attributes defined for mesh " + mesh);
|
assertNotNull(attributes, "No attributes defined for mesh " + mesh);
|
||||||
for (Map.Entry<String, JsonElement> entry : attributes.entrySet()) {
|
for (Map.Entry<String, JsonElement> entry : attributes.entrySet()) {
|
||||||
mesh.setBuffer(loadAccessorData(entry.getValue().getAsInt(), new VertexBufferPopulator(getVertexBufferType(entry.getKey()))));
|
mesh.setBuffer(readAccessorData(entry.getValue().getAsInt(), new VertexBufferPopulator(getVertexBufferType(entry.getKey()))));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mesh.getBuffer(VertexBuffer.Type.BoneIndex) != null) {
|
if (mesh.getBuffer(VertexBuffer.Type.BoneIndex) != null) {
|
||||||
@ -334,7 +334,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
geom.setMaterial(defaultMat);
|
geom.setMaterial(defaultMat);
|
||||||
} else {
|
} else {
|
||||||
useNormalsFlag = false;
|
useNormalsFlag = false;
|
||||||
geom.setMaterial(loadMaterial(materialIndex));
|
geom.setMaterial(readMaterial(materialIndex));
|
||||||
if (geom.getMaterial().getAdditionalRenderState().getBlendMode() == RenderState.BlendMode.Alpha) {
|
if (geom.getMaterial().getAdditionalRenderState().getBlendMode() == RenderState.BlendMode.Alpha) {
|
||||||
//Alpha blending is on on this material let's place the geom in the transparent bucket
|
//Alpha blending is on on this material let's place the geom in the transparent bucket
|
||||||
geom.setQueueBucket(RenderQueue.Bucket.Transparent);
|
geom.setQueueBucket(RenderQueue.Bucket.Transparent);
|
||||||
@ -361,7 +361,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
return geomArray;
|
return geomArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <R> R loadAccessorData(int accessorIndex, Populator<R> populator) throws IOException {
|
private <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");
|
||||||
|
|
||||||
@ -447,7 +447,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Material loadMaterial(int materialIndex) {
|
private 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();
|
||||||
@ -504,13 +504,13 @@ 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 = loadImage(sourceIndex);
|
Texture2D texture2d = readImage(sourceIndex);
|
||||||
readSampler(samplerIndex, texture2d);
|
readSampler(samplerIndex, texture2d);
|
||||||
|
|
||||||
return texture2d;
|
return texture2d;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Texture2D loadImage(int sourceIndex) {
|
private Texture2D readImage(int sourceIndex) {
|
||||||
if (images == null) {
|
if (images == null) {
|
||||||
throw new AssetLoadException("No image defined");
|
throw new AssetLoadException("No image defined");
|
||||||
}
|
}
|
||||||
@ -533,7 +533,8 @@ public class GltfLoader implements AssetLoader {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loadAnimation(JsonObject animation) throws IOException {
|
private void readAnimation(int animationIndex) throws IOException {
|
||||||
|
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");
|
||||||
String name = getAsString(animation, "name");
|
String name = getAsString(animation, "name");
|
||||||
@ -583,7 +584,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
|
|
||||||
float[] times = fetchFromCache("accessors", timeIndex, float[].class);
|
float[] times = fetchFromCache("accessors", timeIndex, float[].class);
|
||||||
if (times == null) {
|
if (times == null) {
|
||||||
times = loadAccessorData(timeIndex, floatArrayPopulator);
|
times = readAccessorData(timeIndex, floatArrayPopulator);
|
||||||
addToCache("accessors", timeIndex, times, accessors.size());
|
addToCache("accessors", timeIndex, times, accessors.size());
|
||||||
}
|
}
|
||||||
if (animData.times == null) {
|
if (animData.times == null) {
|
||||||
@ -599,38 +600,41 @@ public class GltfLoader implements AssetLoader {
|
|||||||
animData.length = times[times.length - 1];
|
animData.length = times[times.length - 1];
|
||||||
}
|
}
|
||||||
if (targetPath.equals("translation")) {
|
if (targetPath.equals("translation")) {
|
||||||
Vector3f[] translations = loadAccessorData(dataIndex, vector3fArrayPopulator);
|
Vector3f[] translations = readAccessorData(dataIndex, vector3fArrayPopulator);
|
||||||
animData.translations = translations;
|
animData.translations = translations;
|
||||||
} else if (targetPath.equals("scale")) {
|
} else if (targetPath.equals("scale")) {
|
||||||
Vector3f[] scales = loadAccessorData(dataIndex, vector3fArrayPopulator);
|
Vector3f[] scales = readAccessorData(dataIndex, vector3fArrayPopulator);
|
||||||
animData.scales = scales;
|
animData.scales = scales;
|
||||||
} else if (targetPath.equals("rotation")) {
|
} else if (targetPath.equals("rotation")) {
|
||||||
Quaternion[] rotations = loadAccessorData(dataIndex, quaternionArrayPopulator);
|
Quaternion[] rotations = readAccessorData(dataIndex, quaternionArrayPopulator);
|
||||||
animData.rotations = rotations;
|
animData.rotations = rotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name == null) {
|
||||||
|
name = "anim_" + animationIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Spatial> spatials = new ArrayList<>();
|
||||||
|
Animation anim = new Animation();
|
||||||
|
anim.setName(name);
|
||||||
|
|
||||||
for (int i = 0; i < animatedNodes.length; i++) {
|
for (int i = 0; i < animatedNodes.length; i++) {
|
||||||
AnimData animData = animatedNodes[i];
|
AnimData animData = animatedNodes[i];
|
||||||
if (animData == null) {
|
if (animData == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (animData.length > anim.getLength()) {
|
||||||
|
anim.setLength(animData.length);
|
||||||
|
}
|
||||||
Object node = fetchFromCache("nodes", i, Object.class);
|
Object node = fetchFromCache("nodes", i, Object.class);
|
||||||
if (node instanceof Spatial) {
|
if (node instanceof Spatial) {
|
||||||
Spatial s = (Spatial) node;
|
Spatial s = (Spatial) node;
|
||||||
AnimControl control = s.getControl(AnimControl.class);
|
spatials.add(s);
|
||||||
if (control == null) {
|
SpatialTrack track = new SpatialTrack(animData.times, animData.translations, animData.rotations, animData.scales);
|
||||||
control = new AnimControl();
|
track.setTrackSpatial(s);
|
||||||
s.addControl(control);
|
anim.addTrack(track);
|
||||||
}
|
|
||||||
if (name == null) {
|
|
||||||
name = s.getName() + "_anim_" + control.getAnimationNames().size();
|
|
||||||
}
|
|
||||||
Animation anim = new Animation(name, animData.length);
|
|
||||||
anim.addTrack(new SpatialTrack(animData.times, animData.translations, animData.rotations, animData.scales));
|
|
||||||
control.addAnim(anim);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//At some point we'll have bone animation
|
//At some point we'll have bone animation
|
||||||
//TODO support for bone animation.
|
//TODO support for bone animation.
|
||||||
@ -639,11 +643,23 @@ public class GltfLoader implements AssetLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!spatials.isEmpty()) {
|
||||||
|
Spatial spatial = null;
|
||||||
|
if (spatials.size() == 1) {
|
||||||
|
spatial = spatials.get(0);
|
||||||
|
} else {
|
||||||
|
spatial = findCommonAncestor(spatials);
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimControl control = spatial.getControl(AnimControl.class);
|
||||||
|
if (control == null) {
|
||||||
|
control = new AnimControl();
|
||||||
|
spatial.addControl(control);
|
||||||
|
}
|
||||||
|
control.addAnim(anim);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//private void readAnimationSampler()
|
|
||||||
|
|
||||||
private void readSampler(int samplerIndex, Texture2D texture) {
|
private void readSampler(int samplerIndex, Texture2D texture) {
|
||||||
if (samplers == null) {
|
if (samplers == null) {
|
||||||
throw new AssetLoadException("No samplers defined");
|
throw new AssetLoadException("No samplers defined");
|
||||||
@ -679,7 +695,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
Integer matricesIndex = getAsInteger(skin, "inverseBindMatrices");
|
Integer matricesIndex = getAsInteger(skin, "inverseBindMatrices");
|
||||||
Matrix4f[] inverseBindMatrices = null;
|
Matrix4f[] inverseBindMatrices = null;
|
||||||
if (matricesIndex != null) {
|
if (matricesIndex != null) {
|
||||||
inverseBindMatrices = loadAccessorData(matricesIndex, matrix4fArrayPopulator);
|
inverseBindMatrices = readAccessorData(matricesIndex, matrix4fArrayPopulator);
|
||||||
} else {
|
} else {
|
||||||
inverseBindMatrices = new Matrix4f[joints.size()];
|
inverseBindMatrices = new Matrix4f[joints.size()];
|
||||||
for (int i = 0; i < inverseBindMatrices.length; i++) {
|
for (int i = 0; i < inverseBindMatrices.length; i++) {
|
||||||
@ -693,7 +709,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
|
|
||||||
Bone[] bones = new Bone[joints.size()];
|
Bone[] bones = new Bone[joints.size()];
|
||||||
for (int i = 0; i < joints.size(); i++) {
|
for (int i = 0; i < joints.size(); i++) {
|
||||||
bones[i] = loadNodeAsBone(joints.get(i).getAsInt(), inverseBindMatrices[i]);
|
bones[i] = readNodeAsBone(joints.get(i).getAsInt(), inverseBindMatrices[i]);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < joints.size(); i++) {
|
for (int i = 0; i < joints.size(); i++) {
|
||||||
findChildren(joints.get(i).getAsInt());
|
findChildren(joints.get(i).getAsInt());
|
||||||
@ -709,7 +725,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Bone loadNodeAsBone(int nodeIndex, Matrix4f inverseBindMatrix) throws IOException {
|
private Bone readNodeAsBone(int nodeIndex, Matrix4f inverseBindMatrix) throws IOException {
|
||||||
|
|
||||||
Bone bone = fetchFromCache("nodes", nodeIndex, Bone.class);
|
Bone bone = fetchFromCache("nodes", nodeIndex, Bone.class);
|
||||||
if (bone != null) {
|
if (bone != null) {
|
||||||
@ -722,7 +738,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
name = "Bone_" + nodeIndex;
|
name = "Bone_" + nodeIndex;
|
||||||
}
|
}
|
||||||
bone = new Bone(name);
|
bone = new Bone(name);
|
||||||
Transform boneTransforms = loadTransforms(nodeData);
|
Transform boneTransforms = readTransforms(nodeData);
|
||||||
Transform inverseBind = new Transform();
|
Transform inverseBind = new Transform();
|
||||||
inverseBind.fromTransformMatrix(inverseBindMatrix);
|
inverseBind.fromTransformMatrix(inverseBindMatrix);
|
||||||
// boneTransforms.combineWithParent(inverseBind);
|
// boneTransforms.combineWithParent(inverseBind);
|
||||||
@ -758,7 +774,7 @@ public class GltfLoader implements AssetLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String loadMeshName(int meshIndex) {
|
private String readMeshName(int meshIndex) {
|
||||||
JsonObject meshData = meshes.get(meshIndex).getAsJsonObject();
|
JsonObject meshData = meshes.get(meshIndex).getAsJsonObject();
|
||||||
return getAsString(meshData, "name");
|
return getAsString(meshData, "name");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user