Model can now be loaded keeping the specific pose of the skeleton in the file.

fix-456
Nehon 7 years ago committed by Rémy Bouquet
parent de78c8deb6
commit 94277ac286
  1. 47
      jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java
  2. 9
      jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfModelKey.java
  3. 24
      jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfUtils.java

@ -156,17 +156,6 @@ public class GltfLoader implements AssetLoader {
} }
} }
//update skeletons
if (skins != null) {
for (int i = 0; i < skins.size(); i++) {
SkinData sd = fetchFromCache("skins", i, SkinData.class);
//reset to bind pose and update model transforms of each bones.
sd.skeletonControl.getSkeleton().resetAndUpdate();
//Compute sthe inverse bind transforms needed for skinning.
sd.skeletonControl.getSkeleton().setBindingPose();
}
}
//Setting the default scene cul hint to inherit. //Setting the default scene cul hint to inherit.
int activeChild = 0; int activeChild = 0;
if (defaultScene != null) { if (defaultScene != null) {
@ -515,10 +504,8 @@ public class GltfLoader implements AssetLoader {
logger.log(Level.WARNING, "Unable to find any pbrMetallicRoughness material entry in material " + materialIndex + ". Only PBR material is supported for now"); logger.log(Level.WARNING, "Unable to find any pbrMetallicRoughness material entry in material " + materialIndex + ". Only PBR material is supported for now");
return defaultMat; return defaultMat;
} }
MaterialAdapter adapter = null;
if (info.getKey() instanceof GltfModelKey) { MaterialAdapter adapter = getAdapterForMaterial(info, "pbrMetallicRoughness");
adapter = ((GltfModelKey) info.getKey()).getAdapterForMaterial("pbrMetallicRoughness");
}
if (adapter == null) { if (adapter == null) {
adapter = defaultMaterialAdapters.get("pbrMetallicRoughness"); adapter = defaultMaterialAdapters.get("pbrMetallicRoughness");
} }
@ -820,11 +807,20 @@ public class GltfLoader implements AssetLoader {
Skeleton skeleton = new Skeleton(bones); Skeleton skeleton = new Skeleton(bones);
//Compute bind transforms. We need to do it from root bone to leaves bone.
for (Bone bone : skeleton.getRoots()) { for (Bone bone : skeleton.getRoots()) {
BoneWrapper bw = findBoneWrapper(bone); BoneWrapper bw = findBoneWrapper(bone);
computeBindTransforms(bw, skeleton); computeBindTransforms(bw, skeleton);
} }
if (isKeepSkeletonPose(info)) {
//Set local transforms. The skeleton may come in a given pose, that is not the rest pose, so let's apply it.
for (int i = 0; i < joints.size(); i++) {
applyPose(joints.get(i).getAsInt());
}
skeleton.updateWorldVectors();
}
SkinData skinData = new SkinData(); SkinData skinData = new SkinData();
skinData.skeletonControl = new SkeletonControl(skeleton); skinData.skeletonControl = new SkeletonControl(skeleton);
addToCache("skins", index, skinData, nodes.size()); addToCache("skins", index, skinData, nodes.size());
@ -832,6 +828,14 @@ public class GltfLoader implements AssetLoader {
} }
} }
private void applyPose(int index) {
BoneWrapper bw = fetchFromCache("nodes", index, BoneWrapper.class);
bw.bone.setUserControl(true);
bw.bone.setLocalTranslation(bw.localTransform.getTranslation());
bw.bone.setLocalRotation(bw.localTransform.getRotation());
bw.bone.setLocalScale(bw.localTransform.getScale());
}
private void computeBindTransforms(BoneWrapper boneWrapper, Skeleton skeleton) { private void computeBindTransforms(BoneWrapper boneWrapper, Skeleton skeleton) {
Bone bone = boneWrapper.bone; Bone bone = boneWrapper.bone;
tmpTransforms.fromTransformMatrix(boneWrapper.modelBindMatrix); tmpTransforms.fromTransformMatrix(boneWrapper.modelBindMatrix);
@ -880,10 +884,11 @@ public class GltfLoader implements AssetLoader {
name = "Bone_" + nodeIndex; name = "Bone_" + nodeIndex;
} }
Bone bone = new Bone(name); Bone bone = new Bone(name);
Transform boneTransforms = readTransforms(nodeData); Transform boneTransforms = null;
bone.setBindTransforms(boneTransforms.getTranslation(), boneTransforms.getRotation(), boneTransforms.getScale()); if (isKeepSkeletonPose(info)) {
boneTransforms = readTransforms(nodeData);
addToCache("nodes", nodeIndex, new BoneWrapper(bone, boneIndex, skinIndex, modelBindMatrix), nodes.size()); }
addToCache("nodes", nodeIndex, new BoneWrapper(bone, boneIndex, skinIndex, modelBindMatrix, boneTransforms), nodes.size());
return bone; return bone;
} }
@ -965,15 +970,17 @@ public class GltfLoader implements AssetLoader {
Bone bone; Bone bone;
int boneIndex; int boneIndex;
int skinIndex; int skinIndex;
Transform localTransform;
Matrix4f modelBindMatrix; Matrix4f modelBindMatrix;
boolean isRoot = false; boolean isRoot = false;
List<Integer> children = new ArrayList<>(); List<Integer> children = new ArrayList<>();
public BoneWrapper(Bone bone, int boneIndex, int skinIndex, Matrix4f modelBindMatrix) { public BoneWrapper(Bone bone, int boneIndex, int skinIndex, Matrix4f modelBindMatrix, Transform localTransform) {
this.bone = bone; this.bone = bone;
this.boneIndex = boneIndex; this.boneIndex = boneIndex;
this.skinIndex = skinIndex; this.skinIndex = skinIndex;
this.modelBindMatrix = modelBindMatrix; this.modelBindMatrix = modelBindMatrix;
this.localTransform = localTransform;
} }
/** /**

@ -11,6 +11,7 @@ import java.util.Map;
public class GltfModelKey extends ModelKey { public class GltfModelKey extends ModelKey {
private Map<String, MaterialAdapter> materialAdapters = new HashMap<>(); private Map<String, MaterialAdapter> materialAdapters = new HashMap<>();
private boolean keepSkeletonPose = false;
public GltfModelKey(String name) { public GltfModelKey(String name) {
super(name); super(name);
@ -26,4 +27,12 @@ public class GltfModelKey extends ModelKey {
public MaterialAdapter getAdapterForMaterial(String gltfMaterialName) { public MaterialAdapter getAdapterForMaterial(String gltfMaterialName) {
return materialAdapters.get(gltfMaterialName); return materialAdapters.get(gltfMaterialName);
} }
public boolean isKeepSkeletonPose() {
return keepSkeletonPose;
}
public void setKeepSkeletonPose(boolean keepSkeletonPose) {
this.keepSkeletonPose = keepSkeletonPose;
}
} }

@ -1,6 +1,7 @@
package com.jme3.scene.plugins.gltf; package com.jme3.scene.plugins.gltf;
import com.google.gson.*; import com.google.gson.*;
import com.jme3.asset.AssetInfo;
import com.jme3.asset.AssetLoadException; import com.jme3.asset.AssetLoadException;
import com.jme3.math.ColorRGBA; import com.jme3.math.ColorRGBA;
import com.jme3.math.Matrix4f; import com.jme3.math.Matrix4f;
@ -495,6 +496,29 @@ public class GltfUtils {
return new Matrix4f(m00, m10, m20, m30, m01, m11, m21, m31, m02, m12, m22, m32, m03, m13, m23, m33); return new Matrix4f(m00, m10, m20, m30, m01, m11, m21, m31, m02, m12, m22, m32, m03, m13, m23, m33);
} }
public static GltfModelKey getKey(AssetInfo info) {
if (info.getKey() instanceof GltfModelKey) {
return (GltfModelKey) info.getKey();
}
return null;
}
public static MaterialAdapter getAdapterForMaterial(AssetInfo info, String defName) {
GltfModelKey key = getKey(info);
if (key == null) {
return null;
}
return key.getAdapterForMaterial(defName);
}
public static boolean isKeepSkeletonPose(AssetInfo info) {
GltfModelKey key = getKey(info);
if (key == null) {
return false;
}
return key.isKeepSkeletonPose();
}
private static LittleEndien getStream(byte[] buffer) { private static LittleEndien getStream(byte[] buffer) {
return new LittleEndien(new DataInputStream(new ByteArrayInputStream(buffer))); return new LittleEndien(new DataInputStream(new ByteArrayInputStream(buffer)));
} }

Loading…
Cancel
Save