Moving loading object animation modifier to ModifierHelper class.

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7852 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
Kae..pl 14 years ago
parent d90f6e7e18
commit a67dbf9977
  1. 92
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ModifierHelper.java
  2. 78
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ObjectHelper.java

@ -56,6 +56,7 @@ import com.jme3.effect.shapes.EmitterMeshVertexShape;
import com.jme3.effect.shapes.EmitterShape;
import com.jme3.material.Material;
import com.jme3.math.Matrix4f;
import com.jme3.math.Transform;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
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.helpers.ParticlesHelper;
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.utils.AbstractBlenderHelper;
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) {
if (Modifier.ARMATURE_MODIFIER_DATA.equals(modifier.getType())) {
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())) {
return this.applyArrayModifierData(node, modifier, dataRepository);
} 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);
if (armatureObject == null) {// we check this first not to fetch the structure unnecessary
armatureObject = pArmatureObject.fetchData(dataRepository.getInputStream()).get(0);
objectHelper.toObject(armatureObject, dataRepository);
}
modifierAdditionalData = armatureObject.getOldMemoryAddress();
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 inverseMeshObjectMatrix = objectHelper.getTransformationMatrix(objectStructure).invert();
Matrix4f additionalRootBoneTransformation = inverseMeshObjectMatrix.multLocal(armatureObjectMatrix);
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();
Set<String> animationNames = dataRepository.getBlenderKey().getAnimationNames(objectName);
if (animationNames != null && animationNames.size() > 0) {
@ -275,6 +282,81 @@ public class ModifierHelper extends AbstractBlenderHelper {
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;
}
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.
* @param node

@ -31,15 +31,10 @@
*/
package com.jme3.scene.plugins.blender.helpers.v249;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
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.Light;
import com.jme3.light.PointLight;
@ -53,10 +48,8 @@ import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
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.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.Properties;
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.DynamicArray;
import com.jme3.scene.plugins.blender.utils.Pointer;
import com.jme3.scene.plugins.ogre.AnimData;
/**
* A class that is used in object calculations.
@ -142,7 +134,6 @@ public class ObjectHelper extends AbstractBlenderHelper {
//reading modifiers
modifierHelper.readModifiers(objectStructure, dataRepository);
Modifier objectAnimationModifier = objectHelper.readObjectAnimation(objectStructure, dataRepository);
//loading constraints connected with this object
constraintHelper.loadConstraints(objectStructure, dataRepository);
@ -188,10 +179,6 @@ public class ObjectHelper extends AbstractBlenderHelper {
for(Modifier modifier : modifiers) {
modifierHelper.applyModifier(node, modifier, dataRepository);
}
//adding object animation modifier
if(objectAnimationModifier != null) {
node = modifierHelper.applyModifier(node, objectAnimationModifier, dataRepository);
}
//setting the parent
if(parent instanceof Node) {
@ -352,71 +339,6 @@ public class ObjectHelper extends AbstractBlenderHelper {
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
public void clearState() {
fixUpAxis = false;

Loading…
Cancel
Save