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
engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249
@ -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…
x
Reference in New Issue
Block a user