Moving loading object animation modifier to ModifierHelper class.
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7852 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
d90f6e7e18
commit
a67dbf9977
@ -56,6 +56,7 @@ import com.jme3.effect.shapes.EmitterMeshVertexShape;
|
|||||||
import com.jme3.effect.shapes.EmitterShape;
|
import com.jme3.effect.shapes.EmitterShape;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
import com.jme3.math.Matrix4f;
|
import com.jme3.math.Matrix4f;
|
||||||
|
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.Mesh;
|
import com.jme3.scene.Mesh;
|
||||||
@ -67,6 +68,7 @@ import com.jme3.scene.plugins.blender.data.Structure;
|
|||||||
import com.jme3.scene.plugins.blender.exception.BlenderFileException;
|
import com.jme3.scene.plugins.blender.exception.BlenderFileException;
|
||||||
import com.jme3.scene.plugins.blender.helpers.ParticlesHelper;
|
import com.jme3.scene.plugins.blender.helpers.ParticlesHelper;
|
||||||
import com.jme3.scene.plugins.blender.structures.Constraint;
|
import com.jme3.scene.plugins.blender.structures.Constraint;
|
||||||
|
import com.jme3.scene.plugins.blender.structures.Ipo;
|
||||||
import com.jme3.scene.plugins.blender.structures.Modifier;
|
import com.jme3.scene.plugins.blender.structures.Modifier;
|
||||||
import com.jme3.scene.plugins.blender.utils.AbstractBlenderHelper;
|
import com.jme3.scene.plugins.blender.utils.AbstractBlenderHelper;
|
||||||
import com.jme3.scene.plugins.blender.utils.DataRepository;
|
import com.jme3.scene.plugins.blender.utils.DataRepository;
|
||||||
@ -107,6 +109,8 @@ public class ModifierHelper extends AbstractBlenderHelper {
|
|||||||
public Node applyModifier(Node node, Modifier modifier, DataRepository dataRepository) {
|
public Node applyModifier(Node node, Modifier modifier, DataRepository dataRepository) {
|
||||||
if (Modifier.ARMATURE_MODIFIER_DATA.equals(modifier.getType())) {
|
if (Modifier.ARMATURE_MODIFIER_DATA.equals(modifier.getType())) {
|
||||||
return this.applyArmatureModifierData(node, modifier, dataRepository);
|
return this.applyArmatureModifierData(node, modifier, dataRepository);
|
||||||
|
} else if (Modifier.OBJECT_ANIMATION_MODIFIER_DATA.equals(modifier.getType())) {
|
||||||
|
return this.applyObjectAnimationModifier(node, modifier, dataRepository);
|
||||||
} else if (Modifier.ARRAY_MODIFIER_DATA.equals(modifier.getType())) {
|
} else if (Modifier.ARRAY_MODIFIER_DATA.equals(modifier.getType())) {
|
||||||
return this.applyArrayModifierData(node, modifier, dataRepository);
|
return this.applyArrayModifierData(node, modifier, dataRepository);
|
||||||
} else if (Modifier.PARTICLE_MODIFIER_DATA.equals(modifier.getType())) {
|
} else if (Modifier.PARTICLE_MODIFIER_DATA.equals(modifier.getType())) {
|
||||||
@ -227,17 +231,20 @@ public class ModifierHelper extends AbstractBlenderHelper {
|
|||||||
Structure armatureObject = (Structure) dataRepository.getLoadedFeature(pArmatureObject.getOldMemoryAddress(), LoadedFeatureDataType.LOADED_STRUCTURE);
|
Structure armatureObject = (Structure) dataRepository.getLoadedFeature(pArmatureObject.getOldMemoryAddress(), LoadedFeatureDataType.LOADED_STRUCTURE);
|
||||||
if (armatureObject == null) {// we check this first not to fetch the structure unnecessary
|
if (armatureObject == null) {// we check this first not to fetch the structure unnecessary
|
||||||
armatureObject = pArmatureObject.fetchData(dataRepository.getInputStream()).get(0);
|
armatureObject = pArmatureObject.fetchData(dataRepository.getInputStream()).get(0);
|
||||||
objectHelper.toObject(armatureObject, dataRepository);
|
|
||||||
}
|
}
|
||||||
modifierAdditionalData = armatureObject.getOldMemoryAddress();
|
modifierAdditionalData = armatureObject.getOldMemoryAddress();
|
||||||
ArmatureHelper armatureHelper = dataRepository.getHelper(ArmatureHelper.class);
|
ArmatureHelper armatureHelper = dataRepository.getHelper(ArmatureHelper.class);
|
||||||
|
|
||||||
// changing bones matrices so that they fit the current object (taht is why we need a copy of a skeleton)
|
// changing bones matrices so that they fit the current object (that is why we need a copy of a skeleton)
|
||||||
Matrix4f armatureObjectMatrix = objectHelper.getTransformationMatrix(armatureObject);
|
Matrix4f armatureObjectMatrix = objectHelper.getTransformationMatrix(armatureObject);
|
||||||
Matrix4f inverseMeshObjectMatrix = objectHelper.getTransformationMatrix(objectStructure).invert();
|
Matrix4f inverseMeshObjectMatrix = objectHelper.getTransformationMatrix(objectStructure).invert();
|
||||||
Matrix4f additionalRootBoneTransformation = inverseMeshObjectMatrix.multLocal(armatureObjectMatrix);
|
Matrix4f additionalRootBoneTransformation = inverseMeshObjectMatrix.multLocal(armatureObjectMatrix);
|
||||||
Bone[] bones = armatureHelper.buildBonesStructure(Long.valueOf(0L), additionalRootBoneTransformation);
|
Bone[] bones = armatureHelper.buildBonesStructure(Long.valueOf(0L), additionalRootBoneTransformation);
|
||||||
|
|
||||||
|
//setting the bones structure inside the skeleton (thus completing its loading)
|
||||||
|
Skeleton skeleton = new Skeleton(bones);
|
||||||
|
dataRepository.addLoadedFeatures(armatureObject.getOldMemoryAddress(), armatureObject.getName(), armatureObject, skeleton);
|
||||||
|
|
||||||
String objectName = objectStructure.getName();
|
String objectName = objectStructure.getName();
|
||||||
Set<String> animationNames = dataRepository.getBlenderKey().getAnimationNames(objectName);
|
Set<String> animationNames = dataRepository.getBlenderKey().getAnimationNames(objectName);
|
||||||
if (animationNames != null && animationNames.size() > 0) {
|
if (animationNames != null && animationNames.size() > 0) {
|
||||||
@ -275,6 +282,81 @@ public class ModifierHelper extends AbstractBlenderHelper {
|
|||||||
modifierAdditionalData = null;
|
modifierAdditionalData = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//at the end read object's animation modifier
|
||||||
|
Modifier objectAnimationModifier = this.readObjectAnimation(objectStructure, dataRepository);
|
||||||
|
if(objectAnimationModifier != null) {
|
||||||
|
dataRepository.addModifier(objectStructure.getOldMemoryAddress(),
|
||||||
|
objectAnimationModifier.getType(),
|
||||||
|
objectAnimationModifier.getJmeModifierRepresentation(),
|
||||||
|
objectAnimationModifier.getAdditionalData());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method reads animation of the object itself (without bones) and stores it as an ArmatureModifierData
|
||||||
|
* modifier. The animation is returned as a modifier. It should be later applied regardless other modifiers. The
|
||||||
|
* reason for this is that object may not have modifiers added but it's animation should be working.
|
||||||
|
* @param objectStructure
|
||||||
|
* the structure of the object
|
||||||
|
* @param dataRepository
|
||||||
|
* the data repository
|
||||||
|
* @return animation modifier is returned, it should be separately applied when the object is loaded
|
||||||
|
* @throws BlenderFileException
|
||||||
|
* this exception is thrown when the blender file is somehow corrupted
|
||||||
|
*/
|
||||||
|
protected Modifier readObjectAnimation(Structure objectStructure, DataRepository dataRepository) throws BlenderFileException {
|
||||||
|
Pointer pIpo = (Pointer)objectStructure.getFieldValue("ipo");
|
||||||
|
if(pIpo.isNotNull()) {
|
||||||
|
//check if there is an action name connected with this ipo
|
||||||
|
String objectAnimationName = null;
|
||||||
|
List<FileBlockHeader> actionBlocks = dataRepository.getFileBlocks(Integer.valueOf(FileBlockHeader.BLOCK_AC00));
|
||||||
|
for(FileBlockHeader actionBlock : actionBlocks) {
|
||||||
|
Structure action = actionBlock.getStructure(dataRepository);
|
||||||
|
List<Structure> actionChannels = ((Structure)action.getFieldValue("chanbase")).evaluateListBase(dataRepository);
|
||||||
|
if(actionChannels.size() == 1) {//object's animtion action has only one channel
|
||||||
|
Pointer pChannelIpo = (Pointer)actionChannels.get(0).getFieldValue("ipo");
|
||||||
|
if(pChannelIpo.equals(pIpo)) {
|
||||||
|
objectAnimationName = action.getName();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String objectName = objectStructure.getName();
|
||||||
|
if(objectAnimationName == null) {//set the object's animation name to object's name
|
||||||
|
objectAnimationName = objectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
IpoHelper ipoHelper = dataRepository.getHelper(IpoHelper.class);
|
||||||
|
Structure ipoStructure = pIpo.fetchData(dataRepository.getInputStream()).get(0);
|
||||||
|
Ipo ipo = ipoHelper.createIpo(ipoStructure, dataRepository);
|
||||||
|
int[] animationFrames = dataRepository.getBlenderKey().getAnimationFrames(objectName, objectAnimationName);
|
||||||
|
if(animationFrames == null) {//if the name was created here there are no frames set for the animation
|
||||||
|
animationFrames = new int[] {1, ipo.getLastFrame()};
|
||||||
|
}
|
||||||
|
int fps = dataRepository.getBlenderKey().getFps();
|
||||||
|
float start = (float)animationFrames[0] / (float)fps;
|
||||||
|
float stop = (float)animationFrames[1] / (float)fps;
|
||||||
|
|
||||||
|
//calculating track for the only bone in this skeleton
|
||||||
|
BoneTrack[] tracks = new BoneTrack[1];
|
||||||
|
tracks[0] = ipo.calculateTrack(0, animationFrames[0], animationFrames[1], fps);
|
||||||
|
|
||||||
|
BoneAnimation boneAnimation = new BoneAnimation(objectAnimationName, stop - start);
|
||||||
|
boneAnimation.setTracks(tracks);
|
||||||
|
ArrayList<BoneAnimation> animations = new ArrayList<BoneAnimation>(1);
|
||||||
|
animations.add(boneAnimation);
|
||||||
|
|
||||||
|
//preparing the object's bone
|
||||||
|
ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class);
|
||||||
|
Transform t = objectHelper.getTransformation(objectStructure);
|
||||||
|
Bone bone = new Bone(null);
|
||||||
|
bone.setBindTransforms(t.getTranslation(), t.getRotation(), t.getScale());
|
||||||
|
|
||||||
|
return new Modifier(Modifier.OBJECT_ANIMATION_MODIFIER_DATA, new AnimData(new Skeleton(new Bone[] {bone}), animations), objectStructure.getOldMemoryAddress());
|
||||||
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -404,6 +486,12 @@ public class ModifierHelper extends AbstractBlenderHelper {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected Node applyObjectAnimationModifier(Node node, Modifier modifier, DataRepository dataRepository) {
|
||||||
|
AnimData ad = (AnimData) modifier.getJmeModifierRepresentation();
|
||||||
|
ad.skeleton.getBone(0).setAttachNode(node);
|
||||||
|
return this.applyArmatureModifierData(node, modifier, dataRepository);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method applies the array modifier to the node.
|
* This method applies the array modifier to the node.
|
||||||
* @param node
|
* @param node
|
||||||
|
@ -31,15 +31,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.jme3.scene.plugins.blender.helpers.v249;
|
package com.jme3.scene.plugins.blender.helpers.v249;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
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.BoneAnimation;
|
|
||||||
import com.jme3.animation.BoneTrack;
|
|
||||||
import com.jme3.animation.Skeleton;
|
|
||||||
import com.jme3.light.DirectionalLight;
|
import com.jme3.light.DirectionalLight;
|
||||||
import com.jme3.light.Light;
|
import com.jme3.light.Light;
|
||||||
import com.jme3.light.PointLight;
|
import com.jme3.light.PointLight;
|
||||||
@ -53,10 +48,8 @@ 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;
|
||||||
import com.jme3.scene.Spatial.CullHint;
|
import com.jme3.scene.Spatial.CullHint;
|
||||||
import com.jme3.scene.plugins.blender.data.FileBlockHeader;
|
|
||||||
import com.jme3.scene.plugins.blender.data.Structure;
|
import com.jme3.scene.plugins.blender.data.Structure;
|
||||||
import com.jme3.scene.plugins.blender.exception.BlenderFileException;
|
import com.jme3.scene.plugins.blender.exception.BlenderFileException;
|
||||||
import com.jme3.scene.plugins.blender.structures.Ipo;
|
|
||||||
import com.jme3.scene.plugins.blender.structures.Modifier;
|
import com.jme3.scene.plugins.blender.structures.Modifier;
|
||||||
import com.jme3.scene.plugins.blender.structures.Properties;
|
import com.jme3.scene.plugins.blender.structures.Properties;
|
||||||
import com.jme3.scene.plugins.blender.utils.AbstractBlenderHelper;
|
import com.jme3.scene.plugins.blender.utils.AbstractBlenderHelper;
|
||||||
@ -64,7 +57,6 @@ import com.jme3.scene.plugins.blender.utils.DataRepository;
|
|||||||
import com.jme3.scene.plugins.blender.utils.DataRepository.LoadedFeatureDataType;
|
import com.jme3.scene.plugins.blender.utils.DataRepository.LoadedFeatureDataType;
|
||||||
import com.jme3.scene.plugins.blender.utils.DynamicArray;
|
import com.jme3.scene.plugins.blender.utils.DynamicArray;
|
||||||
import com.jme3.scene.plugins.blender.utils.Pointer;
|
import com.jme3.scene.plugins.blender.utils.Pointer;
|
||||||
import com.jme3.scene.plugins.ogre.AnimData;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that is used in object calculations.
|
* A class that is used in object calculations.
|
||||||
@ -142,7 +134,6 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|||||||
|
|
||||||
//reading modifiers
|
//reading modifiers
|
||||||
modifierHelper.readModifiers(objectStructure, dataRepository);
|
modifierHelper.readModifiers(objectStructure, dataRepository);
|
||||||
Modifier objectAnimationModifier = objectHelper.readObjectAnimation(objectStructure, dataRepository);
|
|
||||||
|
|
||||||
//loading constraints connected with this object
|
//loading constraints connected with this object
|
||||||
constraintHelper.loadConstraints(objectStructure, dataRepository);
|
constraintHelper.loadConstraints(objectStructure, dataRepository);
|
||||||
@ -188,10 +179,6 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|||||||
for(Modifier modifier : modifiers) {
|
for(Modifier modifier : modifiers) {
|
||||||
modifierHelper.applyModifier(node, modifier, dataRepository);
|
modifierHelper.applyModifier(node, modifier, dataRepository);
|
||||||
}
|
}
|
||||||
//adding object animation modifier
|
|
||||||
if(objectAnimationModifier != null) {
|
|
||||||
node = modifierHelper.applyModifier(node, objectAnimationModifier, dataRepository);
|
|
||||||
}
|
|
||||||
|
|
||||||
//setting the parent
|
//setting the parent
|
||||||
if(parent instanceof Node) {
|
if(parent instanceof Node) {
|
||||||
@ -352,71 +339,6 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method reads animation of the object itself (without bones) and stores it as an ArmatureModifierData
|
|
||||||
* modifier. The animation is returned as a modifier. It should be later applied regardless other modifiers. The
|
|
||||||
* reason for this is that object may not have modifiers added but it's animation should be working.
|
|
||||||
* @param objectStructure
|
|
||||||
* the structure of the object
|
|
||||||
* @param dataRepository
|
|
||||||
* the data repository
|
|
||||||
* @return animation modifier is returned, it should be separately applied when the object is loaded
|
|
||||||
* @throws BlenderFileException
|
|
||||||
* this exception is thrown when the blender file is somehow corrupted
|
|
||||||
*/
|
|
||||||
public Modifier readObjectAnimation(Structure objectStructure, DataRepository dataRepository) throws BlenderFileException {
|
|
||||||
Pointer pIpo = (Pointer)objectStructure.getFieldValue("ipo");
|
|
||||||
if(pIpo.isNotNull()) {
|
|
||||||
//check if there is an action name connected with this ipo
|
|
||||||
String objectAnimationName = null;
|
|
||||||
List<FileBlockHeader> actionBlocks = dataRepository.getFileBlocks(Integer.valueOf(FileBlockHeader.BLOCK_AC00));
|
|
||||||
for(FileBlockHeader actionBlock : actionBlocks) {
|
|
||||||
Structure action = actionBlock.getStructure(dataRepository);
|
|
||||||
List<Structure> actionChannels = ((Structure)action.getFieldValue("chanbase")).evaluateListBase(dataRepository);
|
|
||||||
if(actionChannels.size() == 1) {//object's animtion action has only one channel
|
|
||||||
Pointer pChannelIpo = (Pointer)actionChannels.get(0).getFieldValue("ipo");
|
|
||||||
if(pChannelIpo.equals(pIpo)) {
|
|
||||||
objectAnimationName = action.getName();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String objectName = objectStructure.getName();
|
|
||||||
if(objectAnimationName == null) {//set the object's animation name to object's name
|
|
||||||
objectAnimationName = objectName;
|
|
||||||
}
|
|
||||||
|
|
||||||
IpoHelper ipoHelper = dataRepository.getHelper(IpoHelper.class);
|
|
||||||
Structure ipoStructure = pIpo.fetchData(dataRepository.getInputStream()).get(0);
|
|
||||||
Ipo ipo = ipoHelper.createIpo(ipoStructure, dataRepository);
|
|
||||||
int[] animationFrames = dataRepository.getBlenderKey().getAnimationFrames(objectName, objectAnimationName);
|
|
||||||
if(animationFrames == null) {//if the name was created here there are no frames set for the animation
|
|
||||||
animationFrames = new int[] {1, ipo.getLastFrame()};
|
|
||||||
}
|
|
||||||
int fps = dataRepository.getBlenderKey().getFps();
|
|
||||||
float start = (float)animationFrames[0] / (float)fps;
|
|
||||||
float stop = (float)animationFrames[1] / (float)fps;
|
|
||||||
|
|
||||||
//calculating track for the only bone in this skeleton
|
|
||||||
BoneTrack[] tracks = new BoneTrack[1];
|
|
||||||
tracks[0] = ipo.calculateTrack(0, animationFrames[0], animationFrames[1], fps);
|
|
||||||
|
|
||||||
BoneAnimation boneAnimation = new BoneAnimation(objectAnimationName, stop - start);
|
|
||||||
boneAnimation.setTracks(tracks);
|
|
||||||
ArrayList<BoneAnimation> animations = new ArrayList<BoneAnimation>(1);
|
|
||||||
animations.add(boneAnimation);
|
|
||||||
|
|
||||||
//preparing the object's bone
|
|
||||||
Transform t = this.getTransformation(objectStructure);
|
|
||||||
Bone bone = new Bone(null);
|
|
||||||
bone.setBindTransforms(t.getTranslation(), t.getRotation(), t.getScale());
|
|
||||||
|
|
||||||
return new Modifier(Modifier.ARMATURE_MODIFIER_DATA, new AnimData(new Skeleton(new Bone[] {bone}), animations), objectStructure.getOldMemoryAddress());
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clearState() {
|
public void clearState() {
|
||||||
fixUpAxis = false;
|
fixUpAxis = false;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user