Armature bugfix: bones had constraints applied before they were loaded (skeleton loading moved to ObjectHelper).
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8946 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
f232b11318
commit
8297877114
@ -41,6 +41,7 @@ import java.util.Stack;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import com.jme3.animation.Skeleton;
|
||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
import com.jme3.asset.BlenderKey;
|
import com.jme3.asset.BlenderKey;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
@ -107,6 +108,8 @@ public class BlenderContext {
|
|||||||
protected Map<Long, List<Constraint>> constraints = new HashMap<Long, List<Constraint>>();
|
protected Map<Long, List<Constraint>> constraints = new HashMap<Long, List<Constraint>>();
|
||||||
/** Anim data loaded for features. */
|
/** Anim data loaded for features. */
|
||||||
private Map<Long, AnimData> animData = new HashMap<Long, AnimData>();
|
private Map<Long, AnimData> animData = new HashMap<Long, AnimData>();
|
||||||
|
/** Loaded skeletons. */
|
||||||
|
private Map<Long, Skeleton> skeletons = new HashMap<Long, Skeleton>();
|
||||||
/** A map of mesh contexts. */
|
/** A map of mesh contexts. */
|
||||||
protected Map<Long, MeshContext> meshContexts = new HashMap<Long, MeshContext>();
|
protected Map<Long, MeshContext> meshContexts = new HashMap<Long, MeshContext>();
|
||||||
/** A map of material contexts. */
|
/** A map of material contexts. */
|
||||||
@ -494,6 +497,29 @@ public class BlenderContext {
|
|||||||
public AnimData getAnimData(Long ownerOMA) {
|
public AnimData getAnimData(Long ownerOMA) {
|
||||||
return this.animData.get(ownerOMA);
|
return this.animData.get(ownerOMA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method sets the skeleton for the specified OMA of its owner.
|
||||||
|
*
|
||||||
|
* @param skeletonOMA
|
||||||
|
* the skeleton's old memory address
|
||||||
|
* @param animData
|
||||||
|
* the skeleton specified by the given OMA
|
||||||
|
*/
|
||||||
|
public void setSkeleton(Long skeletonOMA, Skeleton skeleton) {
|
||||||
|
this.skeletons.put(skeletonOMA, skeleton);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the skeleton for the specified OMA of its owner.
|
||||||
|
*
|
||||||
|
* @param skeletonOMA
|
||||||
|
* the skeleton's old memory address
|
||||||
|
* @return the skeleton specified by the given OMA
|
||||||
|
*/
|
||||||
|
public Skeleton getSkeleton(Long skeletonOMA) {
|
||||||
|
return this.skeletons.get(skeletonOMA);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method sets the mesh context for the given mesh old memory address.
|
* This method sets the mesh context for the given mesh old memory address.
|
||||||
|
|||||||
@ -11,11 +11,9 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import com.jme3.animation.AnimControl;
|
import com.jme3.animation.AnimControl;
|
||||||
import com.jme3.animation.Animation;
|
import com.jme3.animation.Animation;
|
||||||
import com.jme3.animation.Bone;
|
|
||||||
import com.jme3.animation.BoneTrack;
|
import com.jme3.animation.BoneTrack;
|
||||||
import com.jme3.animation.Skeleton;
|
import com.jme3.animation.Skeleton;
|
||||||
import com.jme3.animation.SkeletonControl;
|
import com.jme3.animation.SkeletonControl;
|
||||||
import com.jme3.math.Matrix4f;
|
|
||||||
import com.jme3.scene.Geometry;
|
import com.jme3.scene.Geometry;
|
||||||
import com.jme3.scene.Mesh;
|
import com.jme3.scene.Mesh;
|
||||||
import com.jme3.scene.Node;
|
import com.jme3.scene.Node;
|
||||||
@ -27,7 +25,6 @@ import com.jme3.scene.plugins.blender.BlenderContext;
|
|||||||
import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType;
|
import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType;
|
||||||
import com.jme3.scene.plugins.blender.animations.ArmatureHelper;
|
import com.jme3.scene.plugins.blender.animations.ArmatureHelper;
|
||||||
import com.jme3.scene.plugins.blender.constraints.Constraint;
|
import com.jme3.scene.plugins.blender.constraints.Constraint;
|
||||||
import com.jme3.scene.plugins.blender.constraints.ConstraintHelper;
|
|
||||||
import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
|
import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
|
||||||
import com.jme3.scene.plugins.blender.file.FileBlockHeader;
|
import com.jme3.scene.plugins.blender.file.FileBlockHeader;
|
||||||
import com.jme3.scene.plugins.blender.file.Pointer;
|
import com.jme3.scene.plugins.blender.file.Pointer;
|
||||||
@ -91,34 +88,17 @@ import com.jme3.util.BufferUtils;
|
|||||||
Pointer pArmatureObject = (Pointer) modifierStructure.getFieldValue("object");
|
Pointer pArmatureObject = (Pointer) modifierStructure.getFieldValue("object");
|
||||||
if (pArmatureObject.isNotNull()) {
|
if (pArmatureObject.isNotNull()) {
|
||||||
ArmatureHelper armatureHelper = blenderContext.getHelper(ArmatureHelper.class);
|
ArmatureHelper armatureHelper = blenderContext.getHelper(ArmatureHelper.class);
|
||||||
|
ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
|
||||||
|
|
||||||
Structure armatureObject = pArmatureObject.fetchData(blenderContext.getInputStream()).get(0);
|
Structure armatureObject = pArmatureObject.fetchData(blenderContext.getInputStream()).get(0);
|
||||||
|
|
||||||
// load skeleton
|
// load skeleton
|
||||||
Structure armatureStructure = ((Pointer) armatureObject.getFieldValue("data")).fetchData(blenderContext.getInputStream()).get(0);
|
Structure armatureStructure = ((Pointer) armatureObject.getFieldValue("data")).fetchData(blenderContext.getInputStream()).get(0);
|
||||||
|
|
||||||
Structure pose = ((Pointer) armatureObject.getFieldValue("pose")).fetchData(blenderContext.getInputStream()).get(0);
|
|
||||||
List<Structure> chanbase = ((Structure) pose.getFieldValue("chanbase")).evaluateListBase(blenderContext);
|
|
||||||
|
|
||||||
Map<Long, Structure> bonesPoseChannels = new HashMap<Long, Structure>(chanbase.size());
|
|
||||||
for (Structure poseChannel : chanbase) {
|
|
||||||
Pointer pBone = (Pointer) poseChannel.getFieldValue("bone");
|
|
||||||
bonesPoseChannels.put(pBone.getOldMemoryAddress(), poseChannel);
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
|
|
||||||
Matrix4f armatureObjectMatrix = objectHelper.getMatrix(armatureObject, "obmat", true);
|
|
||||||
Matrix4f inverseMeshObjectMatrix = objectHelper.getMatrix(objectStructure, "obmat", true).invertLocal();
|
|
||||||
Matrix4f objectToArmatureTransformation = armatureObjectMatrix.multLocal(inverseMeshObjectMatrix);
|
|
||||||
|
|
||||||
List<Structure> bonebase = ((Structure) armatureStructure.getFieldValue("bonebase")).evaluateListBase(blenderContext);
|
List<Structure> bonebase = ((Structure) armatureStructure.getFieldValue("bonebase")).evaluateListBase(blenderContext);
|
||||||
List<Bone> bonesList = new ArrayList<Bone>();
|
//load the skeleton and its bones first
|
||||||
for (int i = 0; i < bonebase.size(); ++i) {
|
objectHelper.toObject(armatureObject, blenderContext);
|
||||||
armatureHelper.buildBones(bonebase.get(i), null, bonesList, objectToArmatureTransformation, bonesPoseChannels, blenderContext);
|
Skeleton skeleton = blenderContext.getSkeleton(armatureObject.getOldMemoryAddress());
|
||||||
}
|
|
||||||
bonesList.add(0, new Bone(""));
|
|
||||||
Skeleton skeleton = new Skeleton(bonesList.toArray(new Bone[bonesList.size()]));
|
|
||||||
|
|
||||||
// read mesh indexes
|
// read mesh indexes
|
||||||
this.meshOMA = meshStructure.getOldMemoryAddress();
|
this.meshOMA = meshStructure.getOldMemoryAddress();
|
||||||
this.readVerticesWeightsData(objectStructure, meshStructure, skeleton, blenderContext);
|
this.readVerticesWeightsData(objectStructure, meshStructure, skeleton, blenderContext);
|
||||||
@ -153,10 +133,6 @@ import com.jme3.util.BufferUtils;
|
|||||||
for (Structure boneStructure : bonebase) {
|
for (Structure boneStructure : bonebase) {
|
||||||
blenderContext.setAnimData(boneStructure.getOldMemoryAddress(), animData);
|
blenderContext.setAnimData(boneStructure.getOldMemoryAddress(), animData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// loading constraints connected with this object
|
|
||||||
ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class);
|
|
||||||
constraintHelper.loadConstraints(armatureObject, blenderContext);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,11 +31,16 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.scene.plugins.blender.objects;
|
package com.jme3.scene.plugins.blender.objects;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import com.jme3.animation.Bone;
|
||||||
|
import com.jme3.animation.Skeleton;
|
||||||
import com.jme3.asset.BlenderKey.FeaturesToLoad;
|
import com.jme3.asset.BlenderKey.FeaturesToLoad;
|
||||||
import com.jme3.light.DirectionalLight;
|
import com.jme3.light.DirectionalLight;
|
||||||
import com.jme3.light.Light;
|
import com.jme3.light.Light;
|
||||||
@ -53,6 +58,7 @@ import com.jme3.scene.Spatial.CullHint;
|
|||||||
import com.jme3.scene.plugins.blender.AbstractBlenderHelper;
|
import com.jme3.scene.plugins.blender.AbstractBlenderHelper;
|
||||||
import com.jme3.scene.plugins.blender.BlenderContext;
|
import com.jme3.scene.plugins.blender.BlenderContext;
|
||||||
import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType;
|
import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType;
|
||||||
|
import com.jme3.scene.plugins.blender.animations.ArmatureHelper;
|
||||||
import com.jme3.scene.plugins.blender.cameras.CameraHelper;
|
import com.jme3.scene.plugins.blender.cameras.CameraHelper;
|
||||||
import com.jme3.scene.plugins.blender.constraints.Constraint;
|
import com.jme3.scene.plugins.blender.constraints.Constraint;
|
||||||
import com.jme3.scene.plugins.blender.constraints.ConstraintHelper;
|
import com.jme3.scene.plugins.blender.constraints.ConstraintHelper;
|
||||||
@ -233,6 +239,31 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OBJECT_TYPE_ARMATURE:
|
case OBJECT_TYPE_ARMATURE:
|
||||||
|
//load the skeleton first and store it in the blender context
|
||||||
|
Structure armatureStructure = ((Pointer) objectStructure.getFieldValue("data")).fetchData(blenderContext.getInputStream()).get(0);
|
||||||
|
Structure pose = ((Pointer) objectStructure.getFieldValue("pose")).fetchData(blenderContext.getInputStream()).get(0);
|
||||||
|
List<Structure> chanbase = ((Structure) pose.getFieldValue("chanbase")).evaluateListBase(blenderContext);
|
||||||
|
|
||||||
|
Map<Long, Structure> bonesPoseChannels = new HashMap<Long, Structure>(chanbase.size());
|
||||||
|
for (Structure poseChannel : chanbase) {
|
||||||
|
Pointer pBone = (Pointer) poseChannel.getFieldValue("bone");
|
||||||
|
bonesPoseChannels.put(pBone.getOldMemoryAddress(), poseChannel);
|
||||||
|
}
|
||||||
|
|
||||||
|
Matrix4f armatureObjectMatrix = this.getMatrix(objectStructure, "obmat", true);
|
||||||
|
Matrix4f inverseMeshObjectMatrix = this.getMatrix(objectStructure, "obmat", true).invertLocal();
|
||||||
|
Matrix4f objectToArmatureTransformation = armatureObjectMatrix.multLocal(inverseMeshObjectMatrix);
|
||||||
|
|
||||||
|
List<Structure> bonebase = ((Structure) armatureStructure.getFieldValue("bonebase")).evaluateListBase(blenderContext);
|
||||||
|
ArmatureHelper armatureHelper = blenderContext.getHelper(ArmatureHelper.class);
|
||||||
|
List<Bone> bonesList = new ArrayList<Bone>();
|
||||||
|
for (int i = 0; i < bonebase.size(); ++i) {
|
||||||
|
armatureHelper.buildBones(bonebase.get(i), null, bonesList, objectToArmatureTransformation, bonesPoseChannels, blenderContext);
|
||||||
|
}
|
||||||
|
bonesList.add(0, new Bone(""));
|
||||||
|
Skeleton skeleton = new Skeleton(bonesList.toArray(new Bone[bonesList.size()]));
|
||||||
|
blenderContext.setSkeleton(objectStructure.getOldMemoryAddress(), skeleton);
|
||||||
|
|
||||||
//need to create an empty node to properly create parent-children relationships between nodes
|
//need to create an empty node to properly create parent-children relationships between nodes
|
||||||
Node armature = new Node(name);
|
Node armature = new Node(name);
|
||||||
armature.setLocalTransform(t);
|
armature.setLocalTransform(t);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user