Bugfix: fixed an issue with proper bone orientation in 3D space (as in blender bones have different local coordinates system than other features); this fix caused more models to be loaded properly and made the code more simple
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10840 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
c0f0f0ca9e
commit
32b79324a9
@ -41,7 +41,6 @@ import java.util.logging.Logger;
|
|||||||
import com.jme3.animation.Bone;
|
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.math.Matrix4f;
|
|
||||||
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.curves.BezierCurve;
|
import com.jme3.scene.plugins.blender.curves.BezierCurve;
|
||||||
@ -76,21 +75,25 @@ public class ArmatureHelper extends AbstractBlenderHelper {
|
|||||||
/**
|
/**
|
||||||
* This method builds the object's bones structure.
|
* This method builds the object's bones structure.
|
||||||
*
|
*
|
||||||
|
* @param armatureObjectOMA
|
||||||
|
* the OMa of the armature node
|
||||||
* @param boneStructure
|
* @param boneStructure
|
||||||
* the structure containing the bones' data
|
* the structure containing the bones' data
|
||||||
* @param parent
|
* @param parent
|
||||||
* the parent bone
|
* the parent bone
|
||||||
* @param result
|
* @param result
|
||||||
* the list where the newly created bone will be added
|
* the list where the newly created bone will be added
|
||||||
|
* @param spatialOMA
|
||||||
|
* the OMA of the spatial that will own the skeleton
|
||||||
* @param blenderContext
|
* @param blenderContext
|
||||||
* the blender context
|
* the blender context
|
||||||
* @throws BlenderFileException
|
* @throws BlenderFileException
|
||||||
* an exception is thrown when there is problem with the blender
|
* an exception is thrown when there is problem with the blender
|
||||||
* file
|
* file
|
||||||
*/
|
*/
|
||||||
public void buildBones(Long armatureObjectOMA, Structure boneStructure, Bone parent, List<Bone> result, Matrix4f objectToArmatureTransformation, BlenderContext blenderContext) throws BlenderFileException {
|
public void buildBones(Long armatureObjectOMA, Structure boneStructure, Bone parent, List<Bone> result, Long spatialOMA, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
BoneContext bc = new BoneContext(armatureObjectOMA, boneStructure, blenderContext);
|
BoneContext bc = new BoneContext(armatureObjectOMA, boneStructure, blenderContext);
|
||||||
bc.buildBone(result, objectToArmatureTransformation, blenderContext);
|
bc.buildBone(result, spatialOMA, blenderContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -8,7 +8,10 @@ import com.jme3.animation.Skeleton;
|
|||||||
import com.jme3.math.Matrix4f;
|
import com.jme3.math.Matrix4f;
|
||||||
import com.jme3.math.Quaternion;
|
import com.jme3.math.Quaternion;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.scene.Spatial;
|
||||||
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.constraints.ConstraintHelper;
|
||||||
import com.jme3.scene.plugins.blender.file.BlenderFileException;
|
import com.jme3.scene.plugins.blender.file.BlenderFileException;
|
||||||
import com.jme3.scene.plugins.blender.file.Structure;
|
import com.jme3.scene.plugins.blender.file.Structure;
|
||||||
import com.jme3.scene.plugins.blender.objects.ObjectHelper;
|
import com.jme3.scene.plugins.blender.objects.ObjectHelper;
|
||||||
@ -19,6 +22,15 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper;
|
|||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
public class BoneContext {
|
public class BoneContext {
|
||||||
|
// the flags of the bone
|
||||||
|
private static final int CONNECTED_TO_PARENT = 0x10;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bones' matrices have, unlike objects', the coordinate system identical to JME's (Y axis is UP, X to the right and Z toward us).
|
||||||
|
* So in order to have them loaded properly we need to transform their armature matrix (which blender sees as rotated) to make sure we get identical results.
|
||||||
|
*/
|
||||||
|
private static final Matrix4f BONE_ARMATURE_TRANSFORMATION_MATRIX = new Matrix4f(1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1);
|
||||||
|
|
||||||
private BlenderContext blenderContext;
|
private BlenderContext blenderContext;
|
||||||
/** The OMA of the bone's armature object. */
|
/** The OMA of the bone's armature object. */
|
||||||
private Long armatureObjectOMA;
|
private Long armatureObjectOMA;
|
||||||
@ -26,18 +38,18 @@ public class BoneContext {
|
|||||||
private Structure boneStructure;
|
private Structure boneStructure;
|
||||||
/** Bone's name. */
|
/** Bone's name. */
|
||||||
private String boneName;
|
private String boneName;
|
||||||
/** The bone's armature matrix. */
|
/** The bone's flag. */
|
||||||
private Matrix4f armatureMatrix;
|
private int flag;
|
||||||
|
/** The bone's matrix in world space. */
|
||||||
|
private Matrix4f globalBoneMatrix;
|
||||||
|
/** The bone's matrix in the model space. */
|
||||||
|
private Matrix4f boneMatrixInModelSpace;
|
||||||
/** The parent context. */
|
/** The parent context. */
|
||||||
private BoneContext parent;
|
private BoneContext parent;
|
||||||
/** The children of this context. */
|
/** The children of this context. */
|
||||||
private List<BoneContext> children = new ArrayList<BoneContext>();
|
private List<BoneContext> children = new ArrayList<BoneContext>();
|
||||||
/** Created bone (available after calling 'buildBone' method). */
|
/** Created bone (available after calling 'buildBone' method). */
|
||||||
private Bone bone;
|
private Bone bone;
|
||||||
/** The bone's rest matrix. */
|
|
||||||
private Matrix4f restMatrix;
|
|
||||||
/** Bone's total inverse transformation. */
|
|
||||||
private Matrix4f inverseTotalTransformation;
|
|
||||||
/** The length of the bone. */
|
/** The length of the bone. */
|
||||||
private float length;
|
private float length;
|
||||||
|
|
||||||
@ -79,21 +91,26 @@ public class BoneContext {
|
|||||||
this.boneStructure = boneStructure;
|
this.boneStructure = boneStructure;
|
||||||
this.armatureObjectOMA = armatureObjectOMA;
|
this.armatureObjectOMA = armatureObjectOMA;
|
||||||
boneName = boneStructure.getFieldValue("name").toString();
|
boneName = boneStructure.getFieldValue("name").toString();
|
||||||
|
flag = ((Number) boneStructure.getFieldValue("flag")).intValue();
|
||||||
length = ((Number) boneStructure.getFieldValue("length")).floatValue();
|
length = ((Number) boneStructure.getFieldValue("length")).floatValue();
|
||||||
ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
|
ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
|
||||||
armatureMatrix = objectHelper.getMatrix(boneStructure, "arm_mat", blenderContext.getBlenderKey().isFixUpAxis());
|
|
||||||
|
|
||||||
// compute the bone's rest matrix
|
// first get the bone matrix in its armature space
|
||||||
restMatrix = armatureMatrix.clone();
|
globalBoneMatrix = objectHelper.getMatrix(boneStructure, "arm_mat", blenderContext.getBlenderKey().isFixUpAxis());
|
||||||
inverseTotalTransformation = restMatrix.invert();
|
// then make sure it is rotated in a proper way to fit the jme bone transformation conventions
|
||||||
if (parent != null) {
|
globalBoneMatrix.multLocal(BONE_ARMATURE_TRANSFORMATION_MATRIX);
|
||||||
restMatrix = parent.inverseTotalTransformation.mult(restMatrix);
|
|
||||||
}
|
Spatial armature = (Spatial) blenderContext.getLoadedFeature(armatureObjectOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
||||||
|
ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class);
|
||||||
|
Matrix4f armatureWorldMatrix = constraintHelper.toMatrix(armature.getWorldTransform());
|
||||||
|
|
||||||
|
// and now compute the final bone matrix in world space
|
||||||
|
globalBoneMatrix = armatureWorldMatrix.mult(globalBoneMatrix);
|
||||||
|
|
||||||
// create the children
|
// create the children
|
||||||
List<Structure> childbase = ((Structure) boneStructure.getFieldValue("childbase")).evaluateListBase(blenderContext);
|
List<Structure> childbase = ((Structure) boneStructure.getFieldValue("childbase")).evaluateListBase(blenderContext);
|
||||||
for (Structure child : childbase) {
|
for (Structure child : childbase) {
|
||||||
this.children.add(new BoneContext(child, armatureObjectOMA, this, blenderContext));
|
children.add(new BoneContext(child, armatureObjectOMA, this, blenderContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
blenderContext.setBoneContext(boneStructure.getOldMemoryAddress(), this);
|
blenderContext.setBoneContext(boneStructure.getOldMemoryAddress(), this);
|
||||||
@ -104,31 +121,36 @@ public class BoneContext {
|
|||||||
*
|
*
|
||||||
* @param bones
|
* @param bones
|
||||||
* a list of bones where the newly created bone will be added
|
* a list of bones where the newly created bone will be added
|
||||||
* @param objectToArmatureMatrix
|
* @param skeletonOwnerOma
|
||||||
* object to armature transformation matrix
|
* the spatial of the object that will own the skeleton
|
||||||
* @param blenderContext
|
* @param blenderContext
|
||||||
* the blender context
|
* the blender context
|
||||||
* @return newly created bone
|
* @return newly created bone
|
||||||
*/
|
*/
|
||||||
public Bone buildBone(List<Bone> bones, Matrix4f objectToArmatureMatrix, BlenderContext blenderContext) {
|
public Bone buildBone(List<Bone> bones, Long skeletonOwnerOma, BlenderContext blenderContext) {
|
||||||
Long boneOMA = boneStructure.getOldMemoryAddress();
|
Long boneOMA = boneStructure.getOldMemoryAddress();
|
||||||
bone = new Bone(boneName);
|
bone = new Bone(boneName);
|
||||||
bones.add(bone);
|
bones.add(bone);
|
||||||
blenderContext.addLoadedFeatures(boneOMA, boneName, boneStructure, bone);
|
blenderContext.addLoadedFeatures(boneOMA, boneName, boneStructure, bone);
|
||||||
|
ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
|
||||||
|
|
||||||
Vector3f poseLocation = restMatrix.toTranslationVector();
|
Structure skeletonOwnerObjectStructure = (Structure) blenderContext.getLoadedFeature(skeletonOwnerOma, LoadedFeatureDataType.LOADED_STRUCTURE);
|
||||||
Quaternion rotation = restMatrix.toRotationQuat().normalizeLocal();
|
Matrix4f invertedObjectOwnerGlobalMatrix = objectHelper.getMatrix(skeletonOwnerObjectStructure, "imat", blenderContext.getBlenderKey().isFixUpAxis());
|
||||||
Vector3f scale = restMatrix.toScaleVector();
|
if (objectHelper.isParent(skeletonOwnerOma, armatureObjectOMA)) {
|
||||||
if (parent == null) {
|
boneMatrixInModelSpace = globalBoneMatrix.mult(invertedObjectOwnerGlobalMatrix);
|
||||||
Quaternion rotationQuaternion = objectToArmatureMatrix.toRotationQuat().normalizeLocal();
|
} else {
|
||||||
scale.multLocal(objectToArmatureMatrix.toScaleVector());
|
boneMatrixInModelSpace = invertedObjectOwnerGlobalMatrix.mult(globalBoneMatrix);
|
||||||
rotationQuaternion.multLocal(poseLocation.addLocal(objectToArmatureMatrix.toTranslationVector()));
|
|
||||||
rotation.multLocal(rotationQuaternion);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Matrix4f boneLocalMatrix = parent == null ? boneMatrixInModelSpace : parent.boneMatrixInModelSpace.invert().multLocal(boneMatrixInModelSpace);
|
||||||
|
|
||||||
|
Vector3f poseLocation = parent == null || !this.is(CONNECTED_TO_PARENT) ? boneLocalMatrix.toTranslationVector() : new Vector3f(0, parent.length, 0);
|
||||||
|
Quaternion rotation = boneLocalMatrix.toRotationQuat().normalizeLocal();
|
||||||
|
Vector3f scale = boneLocalMatrix.toScaleVector();
|
||||||
|
|
||||||
bone.setBindTransforms(poseLocation, rotation, scale);
|
bone.setBindTransforms(poseLocation, rotation, scale);
|
||||||
for (BoneContext child : children) {
|
for (BoneContext child : children) {
|
||||||
bone.addChild(child.buildBone(bones, objectToArmatureMatrix, blenderContext));
|
bone.addChild(child.buildBone(bones, skeletonOwnerOma, blenderContext));
|
||||||
}
|
}
|
||||||
|
|
||||||
return bone;
|
return bone;
|
||||||
@ -168,4 +190,14 @@ public class BoneContext {
|
|||||||
public Skeleton getSkeleton() {
|
public Skeleton getSkeleton() {
|
||||||
return blenderContext.getSkeleton(armatureObjectOMA);
|
return blenderContext.getSkeleton(armatureObjectOMA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells if the bone is of specified property defined by its flag.
|
||||||
|
* @param flagMask
|
||||||
|
* the mask of the flag (constants defined in this class)
|
||||||
|
* @return <b>true</b> if the bone IS of specified proeprty and <b>false</b> otherwise
|
||||||
|
*/
|
||||||
|
private boolean is(int flagMask) {
|
||||||
|
return (flag & flagMask) != 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.jme3.scene.plugins.blender.animations;
|
package com.jme3.scene.plugins.blender.animations;
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import com.jme3.animation.BoneTrack;
|
import com.jme3.animation.BoneTrack;
|
||||||
@ -148,6 +149,11 @@ public class Ipo {
|
|||||||
if (blenderVersion < 250) {// in blender earlier than 2.50 the values are stored in degrees
|
if (blenderVersion < 250) {// in blender earlier than 2.50 the values are stored in degrees
|
||||||
degreeToRadiansFactor *= FastMath.DEG_TO_RAD * 10;// the values in blender are divided by 10, so we need to mult it here
|
degreeToRadiansFactor *= FastMath.DEG_TO_RAD * 10;// the values in blender are divided by 10, so we need to mult it here
|
||||||
}
|
}
|
||||||
|
int yIndex = 1, zIndex = 2;
|
||||||
|
if(spatialTrack && fixUpAxis) {
|
||||||
|
yIndex = 2;
|
||||||
|
zIndex = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// calculating track data
|
// calculating track data
|
||||||
for (int frame = startFrame; frame <= stopFrame; ++frame) {
|
for (int frame = startFrame; frame <= stopFrame; ++frame) {
|
||||||
@ -162,31 +168,25 @@ public class Ipo {
|
|||||||
translation[0] = (float) value;
|
translation[0] = (float) value;
|
||||||
break;
|
break;
|
||||||
case AC_LOC_Y:
|
case AC_LOC_Y:
|
||||||
if (fixUpAxis) {
|
translation[yIndex] = (float) value;
|
||||||
translation[2] = value == 0.0f ? 0 : (float) -value;
|
|
||||||
} else {
|
|
||||||
translation[1] = (float) value;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case AC_LOC_Z:
|
case AC_LOC_Z:
|
||||||
translation[fixUpAxis ? 1 : 2] = (float) value;
|
translation[zIndex] = (float) value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// ROTATION (used with object animation)
|
// ROTATION (used with object animation)
|
||||||
// the value here is in degrees divided by 10 (so in
|
|
||||||
// example: 9 = PI/2)
|
|
||||||
case OB_ROT_X:
|
case OB_ROT_X:
|
||||||
objectRotation[0] = (float) value * degreeToRadiansFactor;
|
objectRotation[0] = (float) value * degreeToRadiansFactor;
|
||||||
break;
|
break;
|
||||||
case OB_ROT_Y:
|
case OB_ROT_Y:
|
||||||
if (fixUpAxis) {
|
if (fixUpAxis) {
|
||||||
objectRotation[2] = value == 0.0f ? 0 : (float) -value * degreeToRadiansFactor;
|
objectRotation[yIndex] = value == 0.0f ? 0 : (float) -value * degreeToRadiansFactor;
|
||||||
} else {
|
} else {
|
||||||
objectRotation[1] = (float) value * degreeToRadiansFactor;
|
objectRotation[yIndex] = (float) value * degreeToRadiansFactor;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OB_ROT_Z:
|
case OB_ROT_Z:
|
||||||
objectRotation[fixUpAxis ? 1 : 2] = (float) value * degreeToRadiansFactor;
|
objectRotation[zIndex] = (float) value * degreeToRadiansFactor;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// SIZE
|
// SIZE
|
||||||
@ -200,9 +200,7 @@ public class Ipo {
|
|||||||
scale[fixUpAxis ? 1 : 2] = (float) value;
|
scale[fixUpAxis ? 1 : 2] = (float) value;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// QUATERNION ROTATION (used with bone animation), dunno
|
// QUATERNION ROTATION (used with bone animation)
|
||||||
// why but here we shouldn't check the
|
|
||||||
// spatialTrack flag value
|
|
||||||
case AC_QUAT_W:
|
case AC_QUAT_W:
|
||||||
quaternionRotation[3] = (float) value;
|
quaternionRotation[3] = (float) value;
|
||||||
break;
|
break;
|
||||||
@ -210,17 +208,13 @@ public class Ipo {
|
|||||||
quaternionRotation[0] = (float) value;
|
quaternionRotation[0] = (float) value;
|
||||||
break;
|
break;
|
||||||
case AC_QUAT_Y:
|
case AC_QUAT_Y:
|
||||||
if (fixUpAxis) {
|
|
||||||
quaternionRotation[2] = value == 0.0f ? 0 : -(float) value;
|
|
||||||
} else {
|
|
||||||
quaternionRotation[1] = (float) value;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case AC_QUAT_Z:
|
|
||||||
quaternionRotation[fixUpAxis ? 1 : 2] = (float) value;
|
quaternionRotation[fixUpAxis ? 1 : 2] = (float) value;
|
||||||
break;
|
break;
|
||||||
|
case AC_QUAT_Z:
|
||||||
|
quaternionRotation[fixUpAxis ? 2 : 1] = (float) value;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
LOGGER.warning("Unknown ipo curve type: " + bezierCurves[j].getType());
|
LOGGER.log(Level.WARNING, "Unknown ipo curve type: {0}.", bezierCurves[j].getType());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
translations[index] = localQuaternionRotation.multLocal(new Vector3f(translation[0], translation[1], translation[2]));
|
translations[index] = localQuaternionRotation.multLocal(new Vector3f(translation[0], translation[1], translation[2]));
|
||||||
|
@ -17,7 +17,6 @@ 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;
|
||||||
@ -35,7 +34,6 @@ import com.jme3.scene.plugins.blender.file.FileBlockHeader;
|
|||||||
import com.jme3.scene.plugins.blender.file.Pointer;
|
import com.jme3.scene.plugins.blender.file.Pointer;
|
||||||
import com.jme3.scene.plugins.blender.file.Structure;
|
import com.jme3.scene.plugins.blender.file.Structure;
|
||||||
import com.jme3.scene.plugins.blender.meshes.MeshContext;
|
import com.jme3.scene.plugins.blender.meshes.MeshContext;
|
||||||
import com.jme3.scene.plugins.blender.objects.ObjectHelper;
|
|
||||||
import com.jme3.util.BufferUtils;
|
import com.jme3.util.BufferUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -85,17 +83,10 @@ import com.jme3.util.BufferUtils;
|
|||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
|
|
||||||
boolean fixUpAxis = blenderContext.getBlenderKey().isFixUpAxis();
|
|
||||||
Matrix4f armatureObjectMatrix = objectHelper.getMatrix(armatureObject, "obmat", fixUpAxis);
|
|
||||||
Matrix4f inverseMeshObjectMatrix = objectHelper.getMatrix(objectStructure, "imat", fixUpAxis);
|
|
||||||
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>();
|
List<Bone> bonesList = new ArrayList<Bone>();
|
||||||
for (int i = 0; i < bonebase.size(); ++i) {
|
for (int i = 0; i < bonebase.size(); ++i) {
|
||||||
armatureHelper.buildBones(armatureObject.getOldMemoryAddress(), bonebase.get(i), null, bonesList, objectToArmatureTransformation, blenderContext);
|
armatureHelper.buildBones(armatureObject.getOldMemoryAddress(), bonebase.get(i), null, bonesList, objectStructure.getOldMemoryAddress(), blenderContext);
|
||||||
}
|
}
|
||||||
bonesList.add(0, new Bone(""));
|
bonesList.add(0, new Bone(""));
|
||||||
Bone[] bones = bonesList.toArray(new Bone[bonesList.size()]);
|
Bone[] bones = bonesList.toArray(new Bone[bonesList.size()]);
|
||||||
@ -105,7 +96,7 @@ import com.jme3.util.BufferUtils;
|
|||||||
this.meshStructure = meshStructure;
|
this.meshStructure = meshStructure;
|
||||||
|
|
||||||
// read mesh indexes
|
// read mesh indexes
|
||||||
this.meshOMA = meshStructure.getOldMemoryAddress();
|
meshOMA = meshStructure.getOldMemoryAddress();
|
||||||
|
|
||||||
// read animations
|
// read animations
|
||||||
ArrayList<Animation> animations = new ArrayList<Animation>();
|
ArrayList<Animation> animations = new ArrayList<Animation>();
|
||||||
|
@ -44,6 +44,7 @@ import com.jme3.math.Transform;
|
|||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
import com.jme3.scene.Geometry;
|
import com.jme3.scene.Geometry;
|
||||||
import com.jme3.scene.Node;
|
import com.jme3.scene.Node;
|
||||||
|
import com.jme3.scene.Spatial;
|
||||||
import com.jme3.scene.Spatial.CullHint;
|
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;
|
||||||
@ -241,6 +242,31 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the first given OMA points to a parent of the second one.
|
||||||
|
* The parent need not to be the direct one. This method should be called when we are sure
|
||||||
|
* that both of the features are alred loaded because it does not check it.
|
||||||
|
* The OMA's should point to a spatials, otherwise the function will throw ClassCastException.
|
||||||
|
* @param supposedParentOMA
|
||||||
|
* the OMA of the node that we suppose might be a parent of the second one
|
||||||
|
* @param spatialOMA
|
||||||
|
* the OMA of the scene's node
|
||||||
|
* @return <b>true</b> if the first given OMA points to a parent of the second one and <b>false</b> otherwise
|
||||||
|
*/
|
||||||
|
public boolean isParent(Long supposedParentOMA, Long spatialOMA) {
|
||||||
|
Spatial supposedParent = (Spatial) blenderContext.getLoadedFeature(supposedParentOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
||||||
|
Spatial spatial = (Spatial) blenderContext.getLoadedFeature(spatialOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
||||||
|
|
||||||
|
Spatial parent = spatial.getParent();
|
||||||
|
while (parent != null) {
|
||||||
|
if (parent.equals(supposedParent)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
parent = parent.getParent();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method calculates local transformation for the object. Parentage is
|
* This method calculates local transformation for the object. Parentage is
|
||||||
* taken under consideration.
|
* taken under consideration.
|
||||||
@ -363,17 +389,7 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static enum ObjectType {
|
private static enum ObjectType {
|
||||||
EMPTY(0),
|
EMPTY(0), MESH(1), CURVE(2), SURF(3), TEXT(4), METABALL(5), LAMP(10), CAMERA(11), WAVE(21), LATTICE(22), ARMATURE(25);
|
||||||
MESH(1),
|
|
||||||
CURVE(2),
|
|
||||||
SURF(3),
|
|
||||||
TEXT(4),
|
|
||||||
METABALL(5),
|
|
||||||
LAMP(10),
|
|
||||||
CAMERA(11),
|
|
||||||
WAVE(21),
|
|
||||||
LATTICE(22),
|
|
||||||
ARMATURE(25);
|
|
||||||
|
|
||||||
private int blenderTypeValue;
|
private int blenderTypeValue;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user