From 94277ac286477e5e23e32181c90f53440bc6a264 Mon Sep 17 00:00:00 2001 From: Nehon Date: Sat, 19 Aug 2017 21:21:55 +0200 Subject: [PATCH] Model can now be loaded keeping the specific pose of the skeleton in the file. --- .../jme3/scene/plugins/gltf/GltfLoader.java | 47 +++++++++++-------- .../jme3/scene/plugins/gltf/GltfModelKey.java | 9 ++++ .../jme3/scene/plugins/gltf/GltfUtils.java | 24 ++++++++++ 3 files changed, 60 insertions(+), 20 deletions(-) diff --git a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java index eaebc6089..33cc0b36c 100644 --- a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.java +++ b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfLoader.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. int activeChild = 0; 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"); return defaultMat; } - MaterialAdapter adapter = null; - if (info.getKey() instanceof GltfModelKey) { - adapter = ((GltfModelKey) info.getKey()).getAdapterForMaterial("pbrMetallicRoughness"); - } + + MaterialAdapter adapter = getAdapterForMaterial(info, "pbrMetallicRoughness"); if (adapter == null) { adapter = defaultMaterialAdapters.get("pbrMetallicRoughness"); } @@ -820,11 +807,20 @@ public class GltfLoader implements AssetLoader { Skeleton skeleton = new Skeleton(bones); + //Compute bind transforms. We need to do it from root bone to leaves bone. for (Bone bone : skeleton.getRoots()) { BoneWrapper bw = findBoneWrapper(bone); 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.skeletonControl = new SkeletonControl(skeleton); 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) { Bone bone = boneWrapper.bone; tmpTransforms.fromTransformMatrix(boneWrapper.modelBindMatrix); @@ -880,10 +884,11 @@ public class GltfLoader implements AssetLoader { name = "Bone_" + nodeIndex; } Bone bone = new Bone(name); - Transform boneTransforms = readTransforms(nodeData); - bone.setBindTransforms(boneTransforms.getTranslation(), boneTransforms.getRotation(), boneTransforms.getScale()); - - addToCache("nodes", nodeIndex, new BoneWrapper(bone, boneIndex, skinIndex, modelBindMatrix), nodes.size()); + Transform boneTransforms = null; + if (isKeepSkeletonPose(info)) { + boneTransforms = readTransforms(nodeData); + } + addToCache("nodes", nodeIndex, new BoneWrapper(bone, boneIndex, skinIndex, modelBindMatrix, boneTransforms), nodes.size()); return bone; } @@ -965,15 +970,17 @@ public class GltfLoader implements AssetLoader { Bone bone; int boneIndex; int skinIndex; + Transform localTransform; Matrix4f modelBindMatrix; boolean isRoot = false; List 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.boneIndex = boneIndex; this.skinIndex = skinIndex; this.modelBindMatrix = modelBindMatrix; + this.localTransform = localTransform; } /** diff --git a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfModelKey.java b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfModelKey.java index 67c076e30..a75ca38b3 100644 --- a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfModelKey.java +++ b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfModelKey.java @@ -11,6 +11,7 @@ import java.util.Map; public class GltfModelKey extends ModelKey { private Map materialAdapters = new HashMap<>(); + private boolean keepSkeletonPose = false; public GltfModelKey(String name) { super(name); @@ -26,4 +27,12 @@ public class GltfModelKey extends ModelKey { public MaterialAdapter getAdapterForMaterial(String gltfMaterialName) { return materialAdapters.get(gltfMaterialName); } + + public boolean isKeepSkeletonPose() { + return keepSkeletonPose; + } + + public void setKeepSkeletonPose(boolean keepSkeletonPose) { + this.keepSkeletonPose = keepSkeletonPose; + } } diff --git a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfUtils.java b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfUtils.java index 8e8120998..86de6d072 100644 --- a/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfUtils.java +++ b/jme3-plugins/src/gltf/java/com/jme3/scene/plugins/gltf/GltfUtils.java @@ -1,6 +1,7 @@ package com.jme3.scene.plugins.gltf; import com.google.gson.*; +import com.jme3.asset.AssetInfo; import com.jme3.asset.AssetLoadException; import com.jme3.math.ColorRGBA; 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); } + 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) { return new LittleEndien(new DataInputStream(new ByteArrayInputStream(buffer))); }