Automatic loading of both bone and object animations (no need to specify animations in blender key any more).
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8305 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
ce259299e2
commit
0b274b3c1b
@ -33,12 +33,8 @@ package com.jme3.asset;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Queue;
|
||||
import java.util.Set;
|
||||
|
||||
import com.jme3.bounding.BoundingVolume;
|
||||
import com.jme3.collision.Collidable;
|
||||
@ -66,13 +62,6 @@ import com.jme3.texture.Texture;
|
||||
public class BlenderKey extends ModelKey {
|
||||
|
||||
protected static final int DEFAULT_FPS = 25;
|
||||
/**
|
||||
* Animation definitions. The key is the object name that owns the animation. The value is a map between animation
|
||||
* name and its start and stop frames. Blender stores a pointer for animation within object. Therefore one object
|
||||
* can only have one animation at the time. We want to be able to switch between animations for one object so we
|
||||
* need to map the object name to animation names the object will use.
|
||||
*/
|
||||
protected Map<String, Map<String, int[]>> animations;
|
||||
/**
|
||||
* FramesPerSecond parameter describe how many frames there are in each second. It allows to calculate the time
|
||||
* between the frames.
|
||||
@ -126,76 +115,6 @@ public class BlenderKey extends ModelKey {
|
||||
super(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method adds an animation definition. If a definition already eixists in the key then it is replaced.
|
||||
* @param objectName
|
||||
* the name of animation's owner
|
||||
* @param name
|
||||
* the name of the animation
|
||||
* @param start
|
||||
* the start frame of the animation
|
||||
* @param stop
|
||||
* the stop frame of the animation
|
||||
*/
|
||||
public synchronized void addAnimation(String objectName, String name, int start, int stop) {
|
||||
if (objectName == null) {
|
||||
throw new IllegalArgumentException("Object name cannot be null!");
|
||||
}
|
||||
if (name == null) {
|
||||
throw new IllegalArgumentException("Animation name cannot be null!");
|
||||
}
|
||||
if (start > stop) {
|
||||
throw new IllegalArgumentException("Start frame cannot be greater than stop frame!");
|
||||
}
|
||||
if (animations == null) {
|
||||
animations = new HashMap<String, Map<String, int[]>>();
|
||||
animations.put(objectName, new HashMap<String, int[]>());
|
||||
}
|
||||
Map<String, int[]> objectAnimations = animations.get(objectName);
|
||||
if (objectAnimations == null) {
|
||||
objectAnimations = new HashMap<String, int[]>();
|
||||
animations.put(objectName, objectAnimations);
|
||||
}
|
||||
objectAnimations.put(name, new int[] { start, stop });
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the animation frames boundaries.
|
||||
* @param objectName
|
||||
* the name of animation's owner
|
||||
* @param name
|
||||
* animation name
|
||||
* @return animation frame boundaries in a table [start, stop] or null if animation of the given name does not
|
||||
* exists
|
||||
*/
|
||||
public int[] getAnimationFrames(String objectName, String name) {
|
||||
Map<String, int[]> objectAnimations = animations == null ? null : animations.get(objectName);
|
||||
int[] frames = objectAnimations == null ? null : objectAnimations.get(name);
|
||||
return frames == null ? null : frames.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the animation names for the given object name.
|
||||
* @param objectName
|
||||
* the name of the object
|
||||
* @return an array of animations for this object
|
||||
*/
|
||||
public Set<String> getAnimationNames(String objectName) {
|
||||
Map<String, int[]> objectAnimations = animations == null ? null : animations.get(objectName);
|
||||
return objectAnimations == null ? null : objectAnimations.keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the animations map.
|
||||
* The key is the animated spatial name. The value is a map where the key
|
||||
* is the animation name and the value is 2-element array of int that has
|
||||
* start and stop frame of the animation.
|
||||
* @return the animations map
|
||||
*/
|
||||
public Map<String, Map<String, int[]>> getAnimations() {
|
||||
return animations;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns frames per second amount. The default value is BlenderKey.DEFAULT_FPS = 25.
|
||||
* @return the frames per second amount
|
||||
@ -424,22 +343,6 @@ public class BlenderKey extends ModelKey {
|
||||
public void write(JmeExporter e) throws IOException {
|
||||
super.write(e);
|
||||
OutputCapsule oc = e.getCapsule(this);
|
||||
// saving animations
|
||||
oc.write(animations == null ? 0 : animations.size(), "anim-size", 0);
|
||||
if (animations != null) {
|
||||
int objectCounter = 0;
|
||||
for (Entry<String, Map<String, int[]>> animEntry : animations.entrySet()) {
|
||||
oc.write(animEntry.getKey(), "animated-object-" + objectCounter, null);
|
||||
int animsAmount = animEntry.getValue().size();
|
||||
oc.write(animsAmount, "anims-amount-" + objectCounter, 0);
|
||||
for (Entry<String, int[]> animsEntry : animEntry.getValue().entrySet()) {
|
||||
oc.write(animsEntry.getKey(), "anim-name-" + objectCounter, null);
|
||||
oc.write(animsEntry.getValue(), "anim-frames-" + objectCounter, null);
|
||||
}
|
||||
++objectCounter;
|
||||
}
|
||||
}
|
||||
// saving the rest of the data
|
||||
oc.write(fps, "fps", DEFAULT_FPS);
|
||||
oc.write(generatedTextureWidth, "generated-texture-width", 20);
|
||||
oc.write(generatedTextureHeight, "generated-texture-height", 20);
|
||||
@ -458,28 +361,6 @@ public class BlenderKey extends ModelKey {
|
||||
public void read(JmeImporter e) throws IOException {
|
||||
super.read(e);
|
||||
InputCapsule ic = e.getCapsule(this);
|
||||
// reading animations
|
||||
int animSize = ic.readInt("anim-size", 0);
|
||||
if (animSize > 0) {
|
||||
if (animations == null) {
|
||||
animations = new HashMap<String, Map<String, int[]>>(animSize);
|
||||
} else {
|
||||
animations.clear();
|
||||
}
|
||||
for (int i = 0; i < animSize; ++i) {
|
||||
String objectName = ic.readString("animated-object-" + i, null);
|
||||
int animationsAmount = ic.readInt("anims-amount-" + i, 0);
|
||||
Map<String, int[]> objectAnimations = new HashMap<String, int[]>(animationsAmount);
|
||||
for (int j = 0; j < animationsAmount; ++j) {
|
||||
String animName = ic.readString("anim-name-" + i, null);
|
||||
int[] animFrames = ic.readIntArray("anim-frames-" + i, null);
|
||||
objectAnimations.put(animName, animFrames);
|
||||
}
|
||||
animations.put(objectName, objectAnimations);
|
||||
}
|
||||
}
|
||||
|
||||
// reading the rest of the data
|
||||
fps = ic.readInt("fps", DEFAULT_FPS);
|
||||
generatedTextureWidth = ic.readInt("generated-texture-width", 20);
|
||||
generatedTextureHeight = ic.readInt("generated-texture-height", 20);
|
||||
@ -498,7 +379,6 @@ public class BlenderKey extends ModelKey {
|
||||
public int hashCode() {
|
||||
final int prime = 31;
|
||||
int result = super.hashCode();
|
||||
result = prime * result + (animations == null ? 0 : animations.hashCode());
|
||||
result = prime * result + (assetRootPath == null ? 0 : assetRootPath.hashCode());
|
||||
result = prime * result + (defaultMaterial == null ? 0 : defaultMaterial.hashCode());
|
||||
result = prime * result + (faceCullMode == null ? 0 : faceCullMode.hashCode());
|
||||
@ -526,13 +406,6 @@ public class BlenderKey extends ModelKey {
|
||||
return false;
|
||||
}
|
||||
BlenderKey other = (BlenderKey) obj;
|
||||
if (animations == null) {
|
||||
if (other.animations != null) {
|
||||
return false;
|
||||
}
|
||||
} else if (!animations.equals(other.animations)) {
|
||||
return false;
|
||||
}
|
||||
if (assetRootPath == null) {
|
||||
if (other.assetRootPath != null) {
|
||||
return false;
|
||||
|
@ -39,7 +39,7 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.jme3.animation.Bone;
|
||||
import com.jme3.animation.BoneTrack;
|
||||
import com.jme3.animation.Track;
|
||||
import com.jme3.math.Matrix4f;
|
||||
import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Vector3f;
|
||||
@ -320,20 +320,16 @@ public class ArmatureHelper extends AbstractBlenderHelper {
|
||||
* the structure containing the tracks
|
||||
* @param blenderContext
|
||||
* the blender context
|
||||
* @param objectName
|
||||
* the name of the object that will use these tracks
|
||||
* @param animationName
|
||||
* the animation name
|
||||
* @return a list of tracks for the specified animation
|
||||
* @throws BlenderFileException
|
||||
* an exception is thrown when there are problems with the blend
|
||||
* file
|
||||
*/
|
||||
public BoneTrack[] getTracks(Structure actionStructure, BlenderContext blenderContext, String objectName, String animationName) throws BlenderFileException {
|
||||
public Track<?>[] getTracks(Structure actionStructure, BlenderContext blenderContext) throws BlenderFileException {
|
||||
if (blenderVersion < 250) {
|
||||
return this.getTracks249(actionStructure, blenderContext, objectName, animationName);
|
||||
return this.getTracks249(actionStructure, blenderContext);
|
||||
} else {
|
||||
return this.getTracks250(actionStructure, blenderContext, objectName, animationName);
|
||||
return this.getTracks250(actionStructure, blenderContext);
|
||||
}
|
||||
}
|
||||
|
||||
@ -344,26 +340,21 @@ public class ArmatureHelper extends AbstractBlenderHelper {
|
||||
* the structure containing the tracks
|
||||
* @param blenderContext
|
||||
* the blender context
|
||||
* @param objectName
|
||||
* the name of the object that will use these tracks
|
||||
* @param animationName
|
||||
* the animation name
|
||||
* @return a list of tracks for the specified animation
|
||||
* @throws BlenderFileException
|
||||
* an exception is thrown when there are problems with the blend
|
||||
* file
|
||||
*/
|
||||
private BoneTrack[] getTracks250(Structure actionStructure, BlenderContext blenderContext, String objectName, String animationName) throws BlenderFileException {
|
||||
private Track<?>[] getTracks250(Structure actionStructure, BlenderContext blenderContext) throws BlenderFileException {
|
||||
LOGGER.log(Level.INFO, "Getting tracks!");
|
||||
int fps = blenderContext.getBlenderKey().getFps();
|
||||
int[] animationFrames = blenderContext.getBlenderKey().getAnimationFrames(objectName, animationName);
|
||||
Structure groups = (Structure) actionStructure.getFieldValue("groups");
|
||||
List<Structure> actionGroups = groups.evaluateListBase(blenderContext);//bActionGroup
|
||||
if (actionGroups != null && actionGroups.size() > 0 && (bonesMap == null || bonesMap.size() == 0)) {
|
||||
throw new IllegalStateException("No bones found! Cannot proceed to calculating tracks!");
|
||||
}
|
||||
|
||||
List<BoneTrack> tracks = new ArrayList<BoneTrack>();
|
||||
List<Track<?>> tracks = new ArrayList<Track<?>>();
|
||||
for (Structure actionGroup : actionGroups) {
|
||||
String name = actionGroup.getFieldValue("name").toString();
|
||||
Integer boneIndex = bonesMap.get(name);
|
||||
@ -389,10 +380,10 @@ public class ArmatureHelper extends AbstractBlenderHelper {
|
||||
}
|
||||
|
||||
Ipo ipo = new Ipo(bezierCurves);
|
||||
tracks.add(ipo.calculateTrack(boneIndex.intValue(), animationFrames[0], animationFrames[1], fps));
|
||||
tracks.add(ipo.calculateTrack(boneIndex.intValue(), 0, ipo.getLastFrame(), fps));
|
||||
}
|
||||
}
|
||||
return tracks.toArray(new BoneTrack[tracks.size()]);
|
||||
return tracks.toArray(new Track<?>[tracks.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -402,26 +393,21 @@ public class ArmatureHelper extends AbstractBlenderHelper {
|
||||
* the structure containing the tracks
|
||||
* @param blenderContext
|
||||
* the blender context
|
||||
* @param objectName
|
||||
* the name of the object that will use these tracks
|
||||
* @param animationName
|
||||
* the animation name
|
||||
* @return a list of tracks for the specified animation
|
||||
* @throws BlenderFileException
|
||||
* an exception is thrown when there are problems with the blend
|
||||
* file
|
||||
*/
|
||||
private BoneTrack[] getTracks249(Structure actionStructure, BlenderContext blenderContext, String objectName, String animationName) throws BlenderFileException {
|
||||
private Track<?>[] getTracks249(Structure actionStructure, BlenderContext blenderContext) throws BlenderFileException {
|
||||
LOGGER.log(Level.INFO, "Getting tracks!");
|
||||
IpoHelper ipoHelper = blenderContext.getHelper(IpoHelper.class);
|
||||
int fps = blenderContext.getBlenderKey().getFps();
|
||||
int[] animationFrames = blenderContext.getBlenderKey().getAnimationFrames(objectName, animationName);
|
||||
Structure chanbase = (Structure) actionStructure.getFieldValue("chanbase");
|
||||
List<Structure> actionChannels = chanbase.evaluateListBase(blenderContext);//bActionChannel
|
||||
if (actionChannels != null && actionChannels.size() > 0 && (bonesMap == null || bonesMap.size() == 0)) {
|
||||
throw new IllegalStateException("No bones found! Cannot proceed to calculating tracks!");
|
||||
}
|
||||
List<BoneTrack> tracks = new ArrayList<BoneTrack>();
|
||||
List<Track<?>> tracks = new ArrayList<Track<?>>();
|
||||
for (Structure bActionChannel : actionChannels) {
|
||||
String name = bActionChannel.getFieldValue("name").toString();
|
||||
Integer boneIndex = bonesMap.get(name);
|
||||
@ -430,11 +416,11 @@ public class ArmatureHelper extends AbstractBlenderHelper {
|
||||
if (!p.isNull()) {
|
||||
Structure ipoStructure = p.fetchData(blenderContext.getInputStream()).get(0);
|
||||
Ipo ipo = ipoHelper.createIpo(ipoStructure, blenderContext);
|
||||
tracks.add(ipo.calculateTrack(boneIndex.intValue(), animationFrames[0], animationFrames[1], fps));
|
||||
tracks.add(ipo.calculateTrack(boneIndex.intValue(), 0, ipo.getLastFrame(), fps));
|
||||
}
|
||||
}
|
||||
}
|
||||
return tracks.toArray(new BoneTrack[tracks.size()]);
|
||||
return tracks.toArray(new Track<?>[tracks.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,8 @@
|
||||
package com.jme3.scene.plugins.blender.animations;
|
||||
|
||||
import com.jme3.animation.BoneTrack;
|
||||
import com.jme3.animation.SpatialTrack;
|
||||
import com.jme3.animation.Track;
|
||||
import com.jme3.math.Quaternion;
|
||||
import com.jme3.math.Vector3f;
|
||||
import com.jme3.scene.plugins.blender.curves.BezierCurve;
|
||||
@ -28,7 +30,7 @@ public class Ipo {
|
||||
/** A list of bezier curves for this interpolation object. */
|
||||
private BezierCurve[] bezierCurves;
|
||||
/** Each ipo contains one bone track. */
|
||||
private BoneTrack calculatedTrack;
|
||||
private Track<?> calculatedTrack;
|
||||
|
||||
/**
|
||||
* Constructor. Stores the bezier curves.
|
||||
@ -105,8 +107,9 @@ public class Ipo {
|
||||
|
||||
/**
|
||||
* This method calculates the value of the curves as a bone track between the specified frames.
|
||||
* @param boneIndex
|
||||
* the index of the bone for which the method calculates the tracks
|
||||
* @param targetIndex
|
||||
* the index of the target for which the method calculates the tracks
|
||||
* IMPORTANT! Aet to -1 (or any negative number) if you want to load spatial animation.
|
||||
* @param startFrame
|
||||
* the firs frame of tracks (inclusive)
|
||||
* @param stopFrame
|
||||
@ -115,7 +118,8 @@ public class Ipo {
|
||||
* frame rate (frames per second)
|
||||
* @return bone track for the specified bone
|
||||
*/
|
||||
public BoneTrack calculateTrack(int boneIndex, int startFrame, int stopFrame, int fps) {
|
||||
public Track<?> calculateTrack(int targetIndex, int startFrame, int stopFrame, int fps) {
|
||||
if(calculatedTrack == null) {
|
||||
//preparing data for track
|
||||
int framesAmount = stopFrame - startFrame;
|
||||
float start = (startFrame - 1.0f) / fps;
|
||||
@ -127,7 +131,7 @@ public class Ipo {
|
||||
Quaternion[] rotations = new Quaternion[framesAmount + 1];
|
||||
float[] quaternionRotation = new float[4];
|
||||
float[] objectRotation = new float[3];
|
||||
boolean bObjectRotation = false;
|
||||
boolean bSpatialTrack = targetIndex < 0;
|
||||
Vector3f[] scales = new Vector3f[framesAmount + 1];
|
||||
float[] scale = new float[3];
|
||||
|
||||
@ -147,7 +151,6 @@ public class Ipo {
|
||||
case OB_ROT_Y:
|
||||
case OB_ROT_Z:
|
||||
objectRotation[bezierCurves[j].getType() - 7] = (float) value;
|
||||
bObjectRotation = true;
|
||||
break;
|
||||
case AC_SIZE_X:
|
||||
case AC_SIZE_Y:
|
||||
@ -167,11 +170,16 @@ public class Ipo {
|
||||
}
|
||||
}
|
||||
translations[index] = new Vector3f(translation[0], translation[1], translation[2]);
|
||||
rotations[index] = bObjectRotation ? new Quaternion().fromAngles(objectRotation)
|
||||
rotations[index] = bSpatialTrack ? new Quaternion().fromAngles(objectRotation)
|
||||
: new Quaternion(quaternionRotation[0], quaternionRotation[1], quaternionRotation[2], quaternionRotation[3]);
|
||||
scales[index] = new Vector3f(scale[0], scale[1], scale[2]);
|
||||
}
|
||||
calculatedTrack = new BoneTrack(boneIndex, times, translations, rotations, scales);
|
||||
if(bSpatialTrack) {
|
||||
calculatedTrack = new SpatialTrack(times, translations, rotations, scales);
|
||||
} else {
|
||||
calculatedTrack = new BoneTrack(targetIndex, times, translations, rotations, scales);
|
||||
}
|
||||
}
|
||||
return calculatedTrack;
|
||||
}
|
||||
}
|
@ -6,7 +6,6 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@ -15,6 +14,7 @@ import com.jme3.animation.Animation;
|
||||
import com.jme3.animation.Bone;
|
||||
import com.jme3.animation.Skeleton;
|
||||
import com.jme3.animation.SkeletonControl;
|
||||
import com.jme3.animation.Track;
|
||||
import com.jme3.math.Matrix4f;
|
||||
import com.jme3.scene.Geometry;
|
||||
import com.jme3.scene.Mesh;
|
||||
@ -116,31 +116,30 @@ import com.jme3.util.BufferUtils;
|
||||
this.readVerticesWeightsData(objectStructure, meshStructure, blenderContext);
|
||||
|
||||
//read animations
|
||||
String objectName = objectStructure.getName();
|
||||
Set<String> animationNames = blenderContext.getBlenderKey().getAnimationNames(objectName);
|
||||
System.out.println("Loaded animation " + objectName);
|
||||
if (animationNames != null && animationNames.size() > 0) {
|
||||
ArrayList<Animation> animations = new ArrayList<Animation>();
|
||||
List<FileBlockHeader> actionHeaders = blenderContext.getFileBlocks(Integer.valueOf(FileBlockHeader.BLOCK_AC00));
|
||||
for (FileBlockHeader header : actionHeaders) {
|
||||
Structure actionStructure = header.getStructure(blenderContext);
|
||||
String actionName = actionStructure.getName();
|
||||
if (animationNames.contains(actionName)) {
|
||||
int[] animationFrames = blenderContext.getBlenderKey().getAnimationFrames(objectName, actionName);
|
||||
int fps = blenderContext.getBlenderKey().getFps();
|
||||
float start = (float) animationFrames[0] / (float) fps;
|
||||
float stop = (float) animationFrames[1] / (float) fps;
|
||||
Animation boneAnimation = new Animation(actionName, stop - start);
|
||||
boneAnimation.setTracks(armatureHelper.getTracks(actionStructure, blenderContext, objectName, actionName));
|
||||
animations.add(boneAnimation);
|
||||
|
||||
Track<?>[] tracks = armatureHelper.getTracks(actionStructure, blenderContext);
|
||||
//determining the animation time
|
||||
float maximumTrackLength = 0;
|
||||
for(Track<?> track : tracks) {
|
||||
float length = track.getLength();
|
||||
if(length > maximumTrackLength) {
|
||||
maximumTrackLength = length;
|
||||
}
|
||||
}
|
||||
|
||||
Animation boneAnimation = new Animation(actionName, maximumTrackLength);
|
||||
boneAnimation.setTracks(tracks);
|
||||
animations.add(boneAnimation);
|
||||
}
|
||||
animData = new AnimData(new Skeleton(bones), animations);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
|
@ -1,10 +1,22 @@
|
||||
package com.jme3.scene.plugins.blender.modifiers;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.jme3.animation.AnimControl;
|
||||
import com.jme3.animation.Animation;
|
||||
import com.jme3.animation.Track;
|
||||
import com.jme3.scene.Node;
|
||||
import com.jme3.scene.plugins.blender.BlenderContext;
|
||||
import com.jme3.scene.plugins.blender.animations.Ipo;
|
||||
import com.jme3.scene.plugins.blender.animations.IpoHelper;
|
||||
import com.jme3.scene.plugins.blender.constraints.Constraint;
|
||||
import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
|
||||
import com.jme3.scene.plugins.blender.file.FileBlockHeader;
|
||||
import com.jme3.scene.plugins.blender.file.Pointer;
|
||||
import com.jme3.scene.plugins.blender.file.Structure;
|
||||
import com.jme3.scene.plugins.ogre.AnimData;
|
||||
|
||||
@ -41,13 +53,12 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
||||
*/
|
||||
public ObjectAnimationModifier(Structure objectStructure, BlenderContext blenderContext) throws BlenderFileException {
|
||||
LOGGER.warning("Object animation modifier not yet implemented!");
|
||||
/*
|
||||
|
||||
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 = blenderContext
|
||||
.getFileBlocks(Integer.valueOf(FileBlockHeader.BLOCK_AC00));
|
||||
List<FileBlockHeader> actionBlocks = blenderContext.getFileBlocks(Integer.valueOf(FileBlockHeader.BLOCK_AC00));
|
||||
for (FileBlockHeader actionBlock : actionBlocks) {
|
||||
Structure action = actionBlock.getStructure(blenderContext);
|
||||
List<Structure> actionChannels = ((Structure) action.getFieldValue("chanbase")).evaluateListBase(blenderContext);
|
||||
@ -68,38 +79,51 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
||||
IpoHelper ipoHelper = blenderContext.getHelper(IpoHelper.class);
|
||||
Structure ipoStructure = pIpo.fetchData(blenderContext.getInputStream()).get(0);
|
||||
Ipo ipo = ipoHelper.createIpo(ipoStructure, blenderContext);
|
||||
int[] animationFrames = blenderContext.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 = blenderContext.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);
|
||||
Track<?> track = ipo.calculateTrack(-1, 0, ipo.getLastFrame(), fps);
|
||||
|
||||
BoneAnimation boneAnimation = new BoneAnimation(objectAnimationName, stop - start);
|
||||
boneAnimation.setTracks(tracks);
|
||||
Animation animation = new Animation(objectAnimationName, ipo.getLastFrame() / fps);
|
||||
animation.setTracks(new Track<?>[] { track });
|
||||
ArrayList<Animation> animations = new ArrayList<Animation>(1);
|
||||
animations.add(boneAnimation);
|
||||
animations.add(animation);
|
||||
|
||||
// preparing the object's bone
|
||||
ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
|
||||
Transform t = objectHelper.getTransformation(objectStructure, blenderContext);
|
||||
Bone bone = new Bone(null);
|
||||
bone.setBindTransforms(t.getTranslation(), t.getRotation(), t.getScale());
|
||||
|
||||
animData = new AnimData(new Skeleton(new Bone[] { bone }), animations);
|
||||
animData = new AnimData(null, animations);
|
||||
objectOMA = objectStructure.getOldMemoryAddress();
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node apply(Node node, BlenderContext blenderContext) {
|
||||
LOGGER.warning("Object animation modifier not yet implemented!");
|
||||
if(invalid) {
|
||||
LOGGER.log(Level.WARNING, "Armature modifier is invalid! Cannot be applied to: {0}", node.getName());
|
||||
}//if invalid, animData will be null
|
||||
if(animData == null) {
|
||||
return node;
|
||||
}
|
||||
|
||||
ArrayList<Animation> animList = animData.anims;
|
||||
if (animList != null && animList.size() > 0) {
|
||||
List<Constraint> constraints = blenderContext.getConstraints(this.objectOMA);
|
||||
HashMap<String, Animation> anims = new HashMap<String, Animation>();
|
||||
for (int i = 0; i < animList.size(); ++i) {
|
||||
Animation animation = (Animation) animList.get(i).clone();
|
||||
|
||||
// baking constraints into animations
|
||||
if (constraints != null && constraints.size() > 0) {
|
||||
for (Constraint constraint : constraints) {
|
||||
constraint.affectAnimation(animation, 0);
|
||||
}
|
||||
}
|
||||
|
||||
anims.put(animation.getName(), animation);
|
||||
}
|
||||
|
||||
AnimControl control = new AnimControl(null);
|
||||
control.setAnimations(anims);
|
||||
node.addControl(control);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user