diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/BlenderContext.java b/engine/src/blender/com/jme3/scene/plugins/blender/BlenderContext.java index ecc777e19..5b5c57e69 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/BlenderContext.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/BlenderContext.java @@ -31,6 +31,7 @@ */ package com.jme3.scene.plugins.blender; +import com.jme3.animation.Bone; import com.jme3.animation.Skeleton; import com.jme3.asset.AssetManager; import com.jme3.asset.BlenderKey; @@ -52,6 +53,7 @@ import java.util.EmptyStackException; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Stack; import java.util.logging.Level; import java.util.logging.Logger; @@ -488,6 +490,17 @@ public class BlenderContext { public List getConstraints(Long objectOMA) { return objectOMA == null ? null : constraints.get(objectOMA); } + + /** + * @return all available constraints + */ + public List getAllConstraints() { + List result = new ArrayList(); + for(Entry> entry : constraints.entrySet()) { + result.addAll(entry.getValue()); + } + return result; + } /** * This method sets the anim data for the specified OMA of its owner. @@ -584,7 +597,24 @@ public class BlenderContext { public BoneContext getBoneContext(Long boneOMA) { return boneContexts.get(boneOMA); } - + + /** + * Returns bone by given name. + * + * @param name + * the name of the bone + * @return found bone or null if none bone of a given name exists + */ + public BoneContext getBoneByName(String name) { + for(Entry entry : boneContexts.entrySet()) { + Bone bone = entry.getValue().getBone(); + if(bone != null && name.equals(bone.getName())) { + return entry.getValue(); + } + } + return null; + } + /** * This metod returns the default material. * diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/BlenderLoader.java b/engine/src/blender/com/jme3/scene/plugins/blender/BlenderLoader.java index 46bb44b44..afad7ff09 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/BlenderLoader.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/BlenderLoader.java @@ -79,6 +79,7 @@ public class BlenderLoader extends AbstractBlenderLoader { try { this.setup(assetInfo); + List sceneBlocks = new ArrayList(); BlenderKey blenderKey = blenderContext.getBlenderKey(); LoadingResults loadingResults = blenderKey.prepareLoadingResults(); WorldData worldData = null;// a set of data used in different scene aspects @@ -104,7 +105,7 @@ public class BlenderLoader extends AbstractBlenderLoader { // break; case FileBlockHeader.BLOCK_SC00:// Scene if ((blenderKey.getFeaturesToLoad() & FeaturesToLoad.SCENES) != 0) { - loadingResults.addScene(this.toScene(block.getStructure(blenderContext))); + sceneBlocks.add(block); } break; case FileBlockHeader.BLOCK_WO00:// World @@ -121,6 +122,16 @@ public class BlenderLoader extends AbstractBlenderLoader { break; } } + + //bake constraints after everything is loaded + ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class); + constraintHelper.bakeConstraints(blenderContext); + + //load the scene at the very end so that the root nodes have no parent during loading or constraints applying + for(FileBlockHeader sceneBlock : sceneBlocks) { + loadingResults.addScene(this.toScene(sceneBlock.getStructure(blenderContext))); + } + blenderContext.dispose(); return loadingResults; } catch (BlenderFileException e) { diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/BlenderModelLoader.java b/engine/src/blender/com/jme3/scene/plugins/blender/BlenderModelLoader.java index adff4457a..996715015 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/BlenderModelLoader.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/BlenderModelLoader.java @@ -41,6 +41,7 @@ import com.jme3.asset.BlenderKey.FeaturesToLoad; import com.jme3.scene.LightNode; import com.jme3.scene.Node; import com.jme3.scene.Spatial; +import com.jme3.scene.plugins.blender.constraints.ConstraintHelper; import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; import com.jme3.scene.plugins.blender.file.FileBlockHeader; @@ -75,6 +76,11 @@ public class BlenderModelLoader extends BlenderLoader { } } } + + //bake constraints after everything is loaded + ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class); + constraintHelper.bakeConstraints(blenderContext); + blenderContext.dispose(); return modelRoot; } catch (BlenderFileException e) { diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/animations/BoneContext.java b/engine/src/blender/com/jme3/scene/plugins/blender/animations/BoneContext.java index eeba7a88c..9670f605c 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/animations/BoneContext.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/animations/BoneContext.java @@ -200,4 +200,11 @@ public class BoneContext { public Bone getBone() { return bone; } + + /** + * @return the old memory address of the bone + */ + public Long getBoneOma() { + return boneStructure.getOldMemoryAddress(); + } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/BlenderTrack.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/BlenderTrack.java deleted file mode 100644 index d375f87d3..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/BlenderTrack.java +++ /dev/null @@ -1,142 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.animation.AnimChannel; -import com.jme3.animation.AnimControl; -import com.jme3.animation.BoneTrack; -import com.jme3.animation.SpatialTrack; -import com.jme3.animation.Track; -import com.jme3.export.JmeExporter; -import com.jme3.export.JmeImporter; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.util.TempVars; -import java.io.IOException; - -/** - * This class holds either the bone track or spatial track. Is made to improve - * code readability. - * - * @author Marcin Roguski (Kaelthas) - */ -/* package */final class BlenderTrack implements Track { - /** The spatial track. */ - private SpatialTrack spatialTrack; - /** The bone track. */ - private BoneTrack boneTrack; - - /** - * Constructs the object using spatial track (bone track is null). - * - * @param spatialTrack - * the spatial track - */ - public BlenderTrack(SpatialTrack spatialTrack) { - this.spatialTrack = spatialTrack; - } - - /** - * Constructs the object using bone track (spatial track is null). - * - * @param spatialTrack - * the spatial track - */ - public BlenderTrack(BoneTrack boneTrack) { - this.boneTrack = boneTrack; - } - - /** - * @return the stored track (either bone or spatial) - */ - public Track getTrack() { - return boneTrack != null ? boneTrack : spatialTrack; - } - - /** - * @return the array of rotations of this track - */ - public Quaternion[] getRotations() { - if (boneTrack != null) { - return boneTrack.getRotations(); - } - return spatialTrack.getRotations(); - } - - /** - * @return the array of scales for this track - */ - public Vector3f[] getScales() { - if (boneTrack != null) { - return boneTrack.getScales(); - } - return spatialTrack.getScales(); - } - - /** - * @return the arrays of time for this track - */ - public float[] getTimes() { - if (boneTrack != null) { - return boneTrack.getTimes(); - } - return spatialTrack.getTimes(); - } - - /** - * @return the array of translations of this track - */ - public Vector3f[] getTranslations() { - if (boneTrack != null) { - return boneTrack.getTranslations(); - } - return spatialTrack.getTranslations(); - } - - /** - * Set the translations, rotations and scales for this bone track - * - * @param times - * a float array with the time of each frame - * @param translations - * the translation of the bone for each frame - * @param rotations - * the rotation of the bone for each frame - * @param scales - * the scale of the bone for each frame - */ - public void setKeyframes(float[] times, Vector3f[] translations, - Quaternion[] rotations, Vector3f[] scales) { - if (boneTrack != null) { - boneTrack.setKeyframes(times, translations, rotations, scales); - } else { - spatialTrack.setKeyframes(times, translations, rotations, scales); - } - } - - public void write(JmeExporter ex) throws IOException { - } - - public void read(JmeImporter im) throws IOException { - } - - public void setTime(float time, float weight, AnimControl control, - AnimChannel channel, TempVars vars) { - if (boneTrack != null) { - boneTrack.setTime(time, weight, control, channel, vars); - } else { - spatialTrack.setTime(time, weight, control, channel, vars); - } - } - - public float getLength() { - return spatialTrack == null ? boneTrack.getLength() : spatialTrack - .getLength(); - } - - @Override - public BlenderTrack clone() { - if (boneTrack != null) { - return new BlenderTrack(boneTrack.clone()); - } - return new BlenderTrack(spatialTrack.clone()); - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/BoneConstraint.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/BoneConstraint.java new file mode 100644 index 000000000..30f330d48 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/BoneConstraint.java @@ -0,0 +1,168 @@ +package com.jme3.scene.plugins.blender.constraints; + +import java.util.Arrays; +import java.util.logging.Logger; + +import com.jme3.animation.Animation; +import com.jme3.animation.Bone; +import com.jme3.animation.BoneTrack; +import com.jme3.animation.Track; +import com.jme3.math.Quaternion; +import com.jme3.math.Transform; +import com.jme3.math.Vector3f; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType; +import com.jme3.scene.plugins.blender.animations.BoneContext; +import com.jme3.scene.plugins.blender.animations.Ipo; +import com.jme3.scene.plugins.blender.constraints.ConstraintHelper.Space; +import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; +import com.jme3.scene.plugins.blender.file.Structure; +import com.jme3.scene.plugins.blender.objects.ObjectHelper; +import com.jme3.scene.plugins.ogre.AnimData; + +/** + * Constraint applied on the bone. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class BoneConstraint extends Constraint { + private static final Logger LOGGER = Logger.getLogger(BoneConstraint.class.getName()); + /** The OMA of the target armature. */ + private Long targetArmatureOMA; + + public BoneConstraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) + throws BlenderFileException { + super(constraintStructure, ownerOMA, influenceIpo, blenderContext); + targetArmatureOMA = targetOMA; + if(targetArmatureOMA != null && targetArmatureOMA <= 0L) { + targetArmatureOMA = null; + } + targetOMA = null; + if(targetArmatureOMA != null && targetArmatureOMA > 0L && (subtargetName == null || subtargetName.length() == 0)) { + invalid = true; + } + } + + @Override + public void performBakingOperation() { + Bone owner = blenderContext.getBoneContext(ownerOMA).getBone(); + Bone target = null; + + if(targetArmatureOMA != null) {//first make sure the target is loaded + ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class); + try { + objectHelper.toObject((Structure) blenderContext.getLoadedFeature(targetArmatureOMA, LoadedFeatureDataType.LOADED_STRUCTURE), blenderContext); + } catch (BlenderFileException e) { + LOGGER.warning("Problems occured during target object loading. The constraint " + name + " will not be applied."); + return ; + } + + BoneContext boneContext = blenderContext.getBoneByName(subtargetName); + target = boneContext.getBone(); + this.targetOMA = boneContext.getBoneOma(); + } + + this.prepareTracksForApplyingConstraints(); + AnimData animData = blenderContext.getAnimData(ownerOMA); + if(animData != null) { + for(Animation animation : animData.anims) { + Transform ownerTransform = constraintHelper.getBoneTransform(ownerSpace, owner); + Transform targetTransform = target != null ? constraintHelper.getBoneTransform(targetSpace, target) : null; + + BoneTrack boneTrack = constraintHelper.getTrack(owner, animData.skeleton, animation); + BoneTrack targetTrack = target != null ? constraintHelper.getTrack(target, animData.skeleton, animation) : null; + + constraintDefinition.bake(ownerTransform, targetTransform, boneTrack, targetTrack, this.ipo); + } + } + } + + @Override + protected void prepareTracksForApplyingConstraints() { + Long[] bonesOMAs = new Long[] { ownerOMA, targetOMA }; + Space[] spaces = new Space[] { ownerSpace, targetSpace }; + + //creating animations for current objects if at least on of their parents have an animation + for(int i=0;itrue if the bone has animations and false otherwise + */ + private boolean hasAnimation(Long boneOMA) { + AnimData animData = blenderContext.getAnimData(boneOMA); + if(animData != null) { + Bone bone = blenderContext.getBoneContext(boneOMA).getBone(); + int boneIndex = animData.skeleton.getBoneIndex(bone); + for(Animation animation : animData.anims) { + for(Track track : animation.getTracks()) { + if(track instanceof BoneTrack && ((BoneTrack) track).getTargetBoneIndex() == boneIndex) { + return true; + } + } + } + } + return false; + } + + /** + * The method applies bone's current position to all of the traces of the + * given animations. + * + * @param boneContext + * the bone context + * @param space + * the bone's evaluation space + * @param referenceAnimData + * the object containing the animations + */ + private void applyAnimData(BoneContext boneContext, Space space, AnimData referenceAnimData) { + ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class); + Transform transform = constraintHelper.getBoneTransform(space, boneContext.getBone()); + + AnimData animData = blenderContext.getAnimData(boneContext.getBoneOma()); + + for(Animation animation : referenceAnimData.anims) { + BoneTrack parentTrack = (BoneTrack) animation.getTracks()[0]; + + float[] times = parentTrack.getTimes(); + Vector3f[] translations = new Vector3f[times.length]; + Quaternion[] rotations = new Quaternion[times.length]; + Vector3f[] scales = new Vector3f[times.length]; + Arrays.fill(translations, transform.getTranslation()); + Arrays.fill(rotations, transform.getRotation()); + Arrays.fill(scales, transform.getScale()); + for(Animation anim : animData.anims) { + anim.addTrack(new BoneTrack(animData.skeleton.getBoneIndex(boneContext.getBone()), times, translations, rotations, scales)); + } + } + blenderContext.setAnimData(boneContext.getBoneOma(), animData); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/Constraint.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/Constraint.java index 6846d14bb..af3748473 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/Constraint.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/Constraint.java @@ -1,18 +1,17 @@ package com.jme3.scene.plugins.blender.constraints; -import com.jme3.animation.Animation; -import com.jme3.animation.Bone; -import com.jme3.animation.BoneTrack; -import com.jme3.animation.Skeleton; -import com.jme3.animation.SpatialTrack; -import com.jme3.animation.Track; -import com.jme3.scene.Spatial; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + import com.jme3.scene.plugins.blender.BlenderContext; import com.jme3.scene.plugins.blender.animations.Ipo; +import com.jme3.scene.plugins.blender.constraints.ConstraintHelper.Space; +import com.jme3.scene.plugins.blender.constraints.definitions.ConstraintDefinition; +import com.jme3.scene.plugins.blender.constraints.definitions.ConstraintDefinitionFactory; import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; import com.jme3.scene.plugins.blender.file.Pointer; import com.jme3.scene.plugins.blender.file.Structure; -import com.jme3.scene.plugins.blender.objects.ObjectHelper; /** * The implementation of a constraint. @@ -20,18 +19,28 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper; * @author Marcin Roguski (Kaelthas) */ public abstract class Constraint { + private static final Logger LOGGER = Logger.getLogger(Constraint.class.getName()); + + /** Indicates if the constraint is invalid. */ + protected boolean invalid; /** The name of this constraint. */ protected final String name; - /** The constraint's owner. */ - protected final Feature owner; - /** The constraint's target. */ - protected final Feature target; - /** The structure with constraint's data. */ - protected final Structure data; + /** Indicates if the constraint is already baked or not. */ + protected boolean baked; + + protected Space ownerSpace; + protected final ConstraintDefinition constraintDefinition; + protected Long ownerOMA; + + protected Long targetOMA; + protected Space targetSpace; + protected String subtargetName; + /** The ipo object defining influence. */ protected final Ipo ipo; /** The blender context. */ protected final BlenderContext blenderContext; + protected final ConstraintHelper constraintHelper; /** * This constructor creates the constraint instance. @@ -48,100 +57,64 @@ public abstract class Constraint { * this exception is thrown when the blender file is somehow * corrupted */ - public Constraint(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { + public Constraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { this.blenderContext = blenderContext; this.name = constraintStructure.getFieldValue("name").toString(); Pointer pData = (Pointer) constraintStructure.getFieldValue("data"); if (pData.isNotNull()) { - data = pData.fetchData(blenderContext.getInputStream()).get(0); + Structure data = pData.fetchData(blenderContext.getInputStream()).get(0); + constraintDefinition = ConstraintDefinitionFactory.createConstraintDefinition(data, blenderContext); Pointer pTar = (Pointer)data.getFieldValue("tar"); if(pTar!= null && pTar.isNotNull()) { - Structure targetStructure = pTar.fetchData(blenderContext.getInputStream()).get(0); - Long targetOMA = pTar.getOldMemoryAddress(); - Space targetSpace = Space.valueOf(((Number) constraintStructure.getFieldValue("tarspace")).byteValue()); - ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class); - Spatial target = (Spatial) objectHelper.toObject(targetStructure, blenderContext); - this.target = new Feature(target, targetSpace, targetOMA, blenderContext); - } else { - this.target = null; + this.targetOMA = pTar.getOldMemoryAddress(); + this.targetSpace = Space.valueOf(((Number) constraintStructure.getFieldValue("tarspace")).byteValue()); + subtargetName = data.getFieldValue("subtarget").toString(); } } else { - throw new BlenderFileException("The constraint has no data specified!"); + //Null constraint has no data, so create it here + constraintDefinition = ConstraintDefinitionFactory.createConstraintDefinition(null, blenderContext); } - Space ownerSpace = Space.valueOf(((Number) constraintStructure.getFieldValue("ownspace")).byteValue()); - this.owner = new Feature(ownerSpace, ownerOMA, blenderContext); + this.ownerSpace = Space.valueOf(((Number) constraintStructure.getFieldValue("ownspace")).byteValue()); this.ipo = influenceIpo; + this.ownerOMA = ownerOMA; + this.constraintHelper = blenderContext.getHelper(ConstraintHelper.class); } - + /** - * This method bakes the required sontraints into its owner. + * This method bakes the required sontraints into its owner. It checks if the constraint is invalid + * or if it isn't yet baked. It also performs baking of its target constraints so that the proper baking + * order is kept. */ public void bake() { - this.owner.update(); - if(this.target != null) { - this.target.update(); + if(invalid) { + LOGGER.warning("The constraint " + name + " is invalid and will not be applied."); + } else if(!baked) { + if(targetOMA != null) { + List targetConstraints = blenderContext.getConstraints(targetOMA); + if(targetConstraints != null && targetConstraints.size() > 0) { + LOGGER.log(Level.FINE, "Baking target constraints of constraint: {0}", name); + for(Constraint targetConstraint : targetConstraints) { + targetConstraint.bake(); + } + } + } + + LOGGER.log(Level.FINE, "Performing baking of constraint: {0}", name); + this.performBakingOperation(); + baked = true; } - this.bakeConstraint(); } /** - * Bake the animation's constraints into its owner. + * This method should be overwridden and perform the baking opertion. */ - protected abstract void bakeConstraint(); + protected abstract void performBakingOperation(); - /** - * This method returns the bone traces for the bone that is affected by the given constraint. - * @param skeleton - * the skeleton containing bones - * @param boneAnimation - * the bone animation that affects the skeleton - * @return the bone track for the bone that is being affected by the constraint - */ - protected BlenderTrack getTrack(Object owner, Skeleton skeleton, Animation animation) { - if(owner instanceof Bone) { - int boneIndex = skeleton.getBoneIndex((Bone) owner); - for (Track track : animation.getTracks()) { - if (((BoneTrack) track).getTargetBoneIndex() == boneIndex) { - return new BlenderTrack(((BoneTrack) track)); - } - } - throw new IllegalStateException("Cannot find track for: " + owner); - } else { - return new BlenderTrack((SpatialTrack)animation.getTracks()[0]); - } - } - /** - * The space of target or owner transformation. - * - * @author Marcin Roguski (Kaelthas) + * This method prepares the tracks for both owner and parent. If either owner or parent have no track while its parent has - + * the tracks are created. The tracks will not modify the owner/target movement but will be there ready for applying constraints. + * For example if the owner is a spatial and has no animation but its parent is moving then the track is created for the owner + * that will have non modifying values for translation, rotation and scale and will have the same amount of frames as its parent has. */ - public static enum Space { - - CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL, CONSTRAINT_SPACE_INVALID; - - /** - * This method returns the enum instance when given the appropriate - * value from the blend file. - * - * @param c - * the blender's value of the space modifier - * @return the scape enum instance - */ - public static Space valueOf(byte c) { - switch (c) { - case 0: - return CONSTRAINT_SPACE_WORLD; - case 1: - return CONSTRAINT_SPACE_LOCAL; - case 2: - return CONSTRAINT_SPACE_POSE; - case 3: - return CONSTRAINT_SPACE_PARLOCAL; - default: - return CONSTRAINT_SPACE_INVALID; - } - } - } + protected abstract void prepareTracksForApplyingConstraints(); } \ No newline at end of file diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintAction.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintAction.java deleted file mode 100644 index 6c58ac030..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintAction.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * This class represents 'Action' constraint type in blender. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintAction extends Constraint { - private static final Logger LOGGER = Logger.getLogger(ConstraintAction.class.getName()); - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintAction(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - } - - @Override - protected void bakeConstraint() { - // TODO: implement 'Action' constraint - LOGGER.log(Level.WARNING, "'Action' constraint NOT implemented!"); - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintChildOf.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintChildOf.java deleted file mode 100644 index 592d74014..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintChildOf.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * This class represents 'ChildOf' constraint type in blender. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintChildOf extends Constraint { - private static final Logger LOGGER = Logger.getLogger(ConstraintChildOf.class.getName()); - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintChildOf(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - } - - @Override - protected void bakeConstraint() { - // TODO: implement ChildOf constraint - LOGGER.log(Level.WARNING, "ChildOf constraint NOT implemented!"); - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintClampTo.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintClampTo.java deleted file mode 100644 index 5c265c79d..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintClampTo.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * This class represents 'Clamp to' constraint type in blender. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintClampTo extends Constraint { - private static final Logger LOGGER = Logger.getLogger(ConstraintClampTo.class.getName()); - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintClampTo(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) - throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - } - - @Override - protected void bakeConstraint() { - //TODO: implement when curves are implemented - LOGGER.log(Level.INFO, "'Clamp to' not yet implemented! Curves not yet implemented!", name); - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintDampTrack.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintDampTrack.java deleted file mode 100644 index 60a24034e..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintDampTrack.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * The damp track constraint. Available for blender 2.50+. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintDampTrack extends Constraint { - private static final Logger LOGGER = Logger.getLogger(ConstraintDampTrack.class.getName()); - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintDampTrack(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - // TODO Auto-generated constructor stub - } - - @Override - protected void bakeConstraint() { - // TODO Auto-generated method stub - LOGGER.log(Level.WARNING, "'Damp Track' constraint NOT implemented!"); - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintDistLimit.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintDistLimit.java deleted file mode 100644 index ff3b99a51..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintDistLimit.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.animation.Animation; -import com.jme3.math.Matrix4f; -import com.jme3.math.Vector3f; -import com.jme3.scene.Spatial; -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import com.jme3.scene.plugins.ogre.AnimData; - -/** - * This class represents 'Dist limit' constraint type in blender. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintDistLimit extends Constraint { - private static final int LIMITDIST_INSIDE = 0; - private static final int LIMITDIST_OUTSIDE = 1; - private static final int LIMITDIST_ONSURFACE = 2; - - protected int mode; - protected float dist; - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintDistLimit(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - - mode = ((Number) data.getFieldValue("mode")).intValue(); - dist = ((Number) data.getFieldValue("dist")).floatValue(); - } - - @Override - protected void bakeConstraint() { - Object owner = this.owner.getObject(); - AnimData animData = blenderContext.getAnimData(this.owner.getOma()); - if(animData != null) { - if(owner instanceof Spatial) { - Vector3f targetLocation = ((Spatial) owner).getWorldTranslation(); - for(Animation animation : animData.anims) { - BlenderTrack blenderTrack = this.getTrack(owner, animData.skeleton, animation); - int maxFrames = blenderTrack.getTimes().length; - Vector3f[] translations = blenderTrack.getTranslations(); - for (int frame = 0; frame < maxFrames; ++frame) { - Vector3f v = translations[frame].subtract(targetLocation); - this.distLimit(v, targetLocation, ipo.calculateValue(frame)); - translations[frame].addLocal(v); - } - blenderTrack.setKeyframes(blenderTrack.getTimes(), translations, blenderTrack.getRotations(), blenderTrack.getScales()); - } - } - } - - // apply static constraint only to spatials - if(owner instanceof Spatial) { - Matrix4f targetWorldMatrix = target.getWorldTransformMatrix(); - Vector3f targetLocation = targetWorldMatrix.toTranslationVector(); - Matrix4f m = this.owner.getParentWorldTransformMatrix(); - m.invertLocal(); - Matrix4f ownerWorldMatrix = this.owner.getWorldTransformMatrix(); - Vector3f ownerLocation = ownerWorldMatrix.toTranslationVector(); - this.distLimit(ownerLocation, targetLocation, ipo.calculateValue(0)); - ((Spatial) owner).setLocalTranslation(m.mult(ownerLocation)); - } - } - - /** - * - * @param currentLocation - * @param targetLocation - * @param influence - */ - private void distLimit(Vector3f currentLocation, Vector3f targetLocation, float influence) { - Vector3f v = currentLocation.subtract(targetLocation); - float currentDistance = v.length(); - - switch (mode) { - case LIMITDIST_INSIDE: - if (currentDistance >= dist) { - v.normalizeLocal(); - v.multLocal(dist + (currentDistance - dist) * (1.0f - influence)); - currentLocation.set(v.addLocal(targetLocation)); - } - break; - case LIMITDIST_ONSURFACE: - if (currentDistance > dist) { - v.normalizeLocal(); - v.multLocal(dist + (currentDistance - dist) * (1.0f - influence)); - currentLocation.set(v.addLocal(targetLocation)); - } else if(currentDistance < dist) { - v.normalizeLocal().multLocal(dist * influence); - currentLocation.set(targetLocation.add(v)); - } - break; - case LIMITDIST_OUTSIDE: - if (currentDistance <= dist) { - v = targetLocation.subtract(currentLocation).normalizeLocal().multLocal(dist * influence); - currentLocation.set(targetLocation.add(v)); - } - break; - default: - throw new IllegalStateException("Unknown distance limit constraint mode: " + mode); - } - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintFollowPath.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintFollowPath.java deleted file mode 100644 index 5f8be2c22..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintFollowPath.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * This class represents 'Follow path' constraint type in blender. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintFollowPath extends Constraint { - private static final Logger LOGGER = Logger.getLogger(ConstraintFollowPath.class.getName()); - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintFollowPath(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - } - - @Override - protected void bakeConstraint() { - //TODO: implement when curves are implemented - LOGGER.log(Level.INFO, "'Follow path' not implemented! Curves not yet implemented!"); - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintHelper.java index 031a20e95..af06ae44a 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintHelper.java @@ -1,18 +1,31 @@ package com.jme3.scene.plugins.blender.constraints; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.logging.Logger; + +import com.jme3.animation.Animation; +import com.jme3.animation.Bone; +import com.jme3.animation.BoneTrack; +import com.jme3.animation.Skeleton; +import com.jme3.animation.SpatialTrack; +import com.jme3.animation.Track; +import com.jme3.math.Matrix4f; +import com.jme3.math.Quaternion; +import com.jme3.math.Transform; +import com.jme3.math.Vector3f; +import com.jme3.scene.Spatial; import com.jme3.scene.plugins.blender.AbstractBlenderHelper; import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType; import com.jme3.scene.plugins.blender.animations.Ipo; import com.jme3.scene.plugins.blender.animations.IpoHelper; import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; +import com.jme3.scene.plugins.blender.file.DynamicArray; import com.jme3.scene.plugins.blender.file.Pointer; import com.jme3.scene.plugins.blender.file.Structure; -import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.logging.Logger; /** * This class should be used for constraint calculations. @@ -21,38 +34,6 @@ import java.util.logging.Logger; public class ConstraintHelper extends AbstractBlenderHelper { private static final Logger LOGGER = Logger.getLogger(ConstraintHelper.class.getName()); - private static final Map> constraintClasses = new HashMap>(22); - static { - constraintClasses.put("bActionConstraint", ConstraintAction.class); - constraintClasses.put("bChildOfConstraint", ConstraintChildOf.class); - constraintClasses.put("bClampToConstraint", ConstraintClampTo.class); - constraintClasses.put("bDistLimitConstraint", ConstraintDistLimit.class); - constraintClasses.put("bFollowPathConstraint", ConstraintFollowPath.class); - constraintClasses.put("bKinematicConstraint", ConstraintInverseKinematics.class); - constraintClasses.put("bLockTrackConstraint", ConstraintLockTrack.class); - constraintClasses.put("bLocateLikeConstraint", ConstraintLocLike.class); - constraintClasses.put("bLocLimitConstraint", ConstraintLocLimit.class); - constraintClasses.put("bMinMaxConstraint", ConstraintMinMax.class); - constraintClasses.put("bNullConstraint", ConstraintNull.class); - constraintClasses.put("bPythonConstraint", ConstraintPython.class); - constraintClasses.put("bRigidBodyJointConstraint", ConstraintRigidBodyJoint.class); - constraintClasses.put("bRotateLikeConstraint", ConstraintRotLike.class); - constraintClasses.put("bShrinkWrapConstraint", ConstraintShrinkWrap.class); - constraintClasses.put("bSizeLikeConstraint", ConstraintSizeLike.class); - constraintClasses.put("bSizeLimitConstraint", ConstraintSizeLimit.class); - constraintClasses.put("bStretchToConstraint", ConstraintStretchTo.class); - constraintClasses.put("bTransformConstraint", ConstraintTransform.class); - constraintClasses.put("bRotLimitConstraint", ConstraintRotLimit.class); - //Blender 2.50+ - constraintClasses.put("bSplineIKConstraint", ConstraintSplineInverseKinematic.class); - constraintClasses.put("bDampTrackConstraint", ConstraintDampTrack.class); - constraintClasses.put("bPivotConstraint", ConstraintDampTrack.class); - //Blender 2.56+ - constraintClasses.put("bTrackToConstraint", ConstraintTrackTo.class); - constraintClasses.put("bSameVolumeConstraint", ConstraintSameVolume.class); - constraintClasses.put("bTransLikeConstraint", ConstraintTransLike.class); - } - /** * Helper constructor. It's main task is to generate the affection functions. These functions are common to all * ConstraintHelper instances. Unfortunately this constructor might grow large. If it becomes too large - I shall @@ -125,7 +106,7 @@ public class ConstraintHelper extends AbstractBlenderHelper { float enforce = ((Number) constraint.getFieldValue("enforce")).floatValue(); ipo = ipoHelper.fromValue(enforce); } - constraintsList.add(this.createConstraint(constraint, boneOMA, ipo, blenderContext)); + constraintsList.add(new BoneConstraint(constraint, boneOMA, ipo, blenderContext)); } blenderContext.addConstraints(boneOMA, constraintsList); } @@ -133,74 +114,362 @@ public class ConstraintHelper extends AbstractBlenderHelper { //loading constraints connected with the object itself List constraints = ((Structure)objectStructure.getFieldValue("constraints")).evaluateListBase(blenderContext); - List constraintsList = new ArrayList(constraints.size()); - - for(Structure constraint : constraints) { - String constraintName = constraint.getFieldValue("name").toString(); - String objectName = objectStructure.getName(); + if(constraints != null && constraints.size() > 0) { + Pointer pData = (Pointer) objectStructure.getFieldValue("data"); + String dataType = pData.isNotNull() ? pData.fetchData(blenderContext.getInputStream()).get(0).getType() : null; + List constraintsList = new ArrayList(constraints.size()); - Map objectConstraintsIpos = constraintsIpos.get(objectName); - Ipo ipo = objectConstraintsIpos!=null ? objectConstraintsIpos.get(constraintName) : null; - if (ipo == null) { - float enforce = ((Number) constraint.getFieldValue("enforce")).floatValue(); - ipo = ipoHelper.fromValue(enforce); + for(Structure constraint : constraints) { + String constraintName = constraint.getFieldValue("name").toString(); + String objectName = objectStructure.getName(); + + Map objectConstraintsIpos = constraintsIpos.get(objectName); + Ipo ipo = objectConstraintsIpos!=null ? objectConstraintsIpos.get(constraintName) : null; + if (ipo == null) { + float enforce = ((Number) constraint.getFieldValue("enforce")).floatValue(); + ipo = ipoHelper.fromValue(enforce); + } + + constraintsList.add(this.getConstraint(dataType, constraint, objectStructure.getOldMemoryAddress(), ipo, blenderContext)); } - constraintsList.add(this.createConstraint(constraint, objectStructure.getOldMemoryAddress(), ipo, blenderContext)); + blenderContext.addConstraints(objectStructure.getOldMemoryAddress(), constraintsList); } - blenderContext.addConstraints(objectStructure.getOldMemoryAddress(), constraintsList); } /** - * This method creates the constraint instance. + * This method creates a proper constraint object depending on the object's + * data type. Supported data types:
  • Mesh
  • Armature
  • Camera
  • + * Lamp Bone constraints are created in a different place. * + * @param dataType + * the type of the object's data * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). + * the constraint structure * @param ownerOMA - * the old memory address of the constraint's owner + * the owner OMA * @param influenceIpo - * the ipo curve of the influence factor + * the influence interpolation curve * @param blenderContext * the blender context + * @return constraint object for the required type * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted + * thrown when problems with blender file occured */ - protected Constraint createConstraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, - BlenderContext blenderContext) throws BlenderFileException { - String constraintClassName = this.getConstraintClassName(constraintStructure, blenderContext); - Class constraintClass = constraintClasses.get(constraintClassName); - if(constraintClass != null) { - try { - return (Constraint) constraintClass.getDeclaredConstructors()[0].newInstance(constraintStructure, ownerOMA, influenceIpo, - blenderContext); - } catch (IllegalArgumentException e) { - throw new BlenderFileException(e.getLocalizedMessage(), e); - } catch (SecurityException e) { - throw new BlenderFileException(e.getLocalizedMessage(), e); - } catch (InstantiationException e) { - throw new BlenderFileException(e.getLocalizedMessage(), e); - } catch (IllegalAccessException e) { - throw new BlenderFileException(e.getLocalizedMessage(), e); - } catch (InvocationTargetException e) { - throw new BlenderFileException(e.getLocalizedMessage(), e); - } + private Constraint getConstraint(String dataType, Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { + if(dataType == null || "Mesh".equalsIgnoreCase(dataType) || "Camera".equalsIgnoreCase(dataType) || "Lamp".equalsIgnoreCase(dataType)) { + return new SpatialConstraint(constraintStructure, ownerOMA, influenceIpo, blenderContext); + } else if("Armature".equalsIgnoreCase(dataType)) { + return new SkeletonConstraint(constraintStructure, ownerOMA, influenceIpo, blenderContext); } else { - throw new BlenderFileException("Unknown constraint type: " + constraintClassName); + throw new IllegalArgumentException("Unsupported data type for applying constraints: " + dataType); } } - protected String getConstraintClassName(Structure constraintStructure, BlenderContext blenderContext) throws BlenderFileException { - Pointer pData = (Pointer)constraintStructure.getFieldValue("data"); - if(pData.isNotNull()) { - Structure data = pData.fetchData(blenderContext.getInputStream()).get(0); - return data.getType(); - + /** + * The method bakes all available and valid constraints. + * + * @param blenderContext + * the blender context + */ + public void bakeConstraints(BlenderContext blenderContext) { + for(Constraint constraint : blenderContext.getAllConstraints()) { + constraint.bake(); } - return constraintStructure.getType(); + } + + /** + * The method returns track for bone. + * + * @param bone + * the bone + * @param skeleton + * the bone's skeleton + * @param animation + * the bone's animation + * @return track for the given bone that was found among the given + * animations or null if none is found + */ + /*package*/ BoneTrack getTrack(Bone bone, Skeleton skeleton, Animation animation) { + int boneIndex = skeleton.getBoneIndex(bone); + for (Track track : animation.getTracks()) { + if (((BoneTrack) track).getTargetBoneIndex() == boneIndex) { + return (BoneTrack) track; + } + } + return null; + } + + /** + * The method returns track for spatial. + * + * @param bone + * the spatial + * @param animation + * the spatial's animation + * @return track for the given spatial that was found among the given + * animations or null if none is found + */ + /*package*/ SpatialTrack getTrack(Spatial spatial, Animation animation) { + Track[] tracks = animation.getTracks(); + if(tracks != null && tracks.length == 1) { + return (SpatialTrack)tracks[0]; + } + return null; + } + + /** + * This method returns the transform read directly from the blender + * structure. This can be used to read transforms from one of the object + * types:
  • Spatial
  • Camera
  • Light + * + * @param space + * the space where transform is evaluated + * @param spatialOMA + * the OMA of the object + * @param blenderContext + * the blender context + * @return the object's transform in a given space + */ + @SuppressWarnings("unchecked") + /*package*/ Transform getNodeObjectTransform(Space space, Long spatialOMA, BlenderContext blenderContext) { + switch (space) { + case CONSTRAINT_SPACE_LOCAL: + Structure targetStructure = (Structure) blenderContext.getLoadedFeature(spatialOMA, LoadedFeatureDataType.LOADED_STRUCTURE); + + DynamicArray locArray = ((DynamicArray) targetStructure.getFieldValue("loc")); + Vector3f loc = new Vector3f(locArray.get(0).floatValue(), locArray.get(1).floatValue(), locArray.get(2).floatValue()); + DynamicArray rotArray = ((DynamicArray) targetStructure.getFieldValue("rot")); + Quaternion rot = new Quaternion(new float[] { rotArray.get(0).floatValue(), rotArray.get(1).floatValue(), rotArray.get(2).floatValue() }); + DynamicArray sizeArray = ((DynamicArray) targetStructure.getFieldValue("size")); + Vector3f size = new Vector3f(sizeArray.get(0).floatValue(), sizeArray.get(1).floatValue(), sizeArray.get(2).floatValue()); + + if (blenderContext.getBlenderKey().isFixUpAxis()) { + float y = loc.y; + loc.y = loc.z; + loc.z = -y; + + y = rot.getY(); + float z = rot.getZ(); + rot.set(rot.getX(), z, -y, rot.getW()); + + y = size.y; + size.y = size.z; + size.z = y; + } + + Transform result = new Transform(loc, rot); + result.setScale(size); + return result; + case CONSTRAINT_SPACE_WORLD://TODO: get it from the object structure ??? + Object feature = blenderContext.getLoadedFeature(spatialOMA, LoadedFeatureDataType.LOADED_FEATURE); + if(feature instanceof Spatial) { + return ((Spatial) feature).getWorldTransform(); + } else if(feature instanceof Skeleton) { + LOGGER.warning("Trying to get transformation for skeleton. This is not supported. Returning null."); + return null; + } else { + throw new IllegalArgumentException("Given old memory address does not point to a valid object type (spatial, camera or light)."); + } + default: + throw new IllegalStateException("Invalid space type for target object: " + space.toString()); + } + } + + /** + * The method returns the transform for the given bone computed in the given + * space. + * + * @param space + * the computation space + * @param bone + * the bone we get the transform from + * @return the transform of the given bone + */ + /*package*/ Transform getBoneTransform(Space space, Bone bone) { + switch (space) { + case CONSTRAINT_SPACE_LOCAL: + Transform localTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation()); + localTransform.setScale(bone.getLocalScale()); + return localTransform; + case CONSTRAINT_SPACE_WORLD: + Transform worldTransform = new Transform(bone.getWorldBindPosition(), bone.getWorldBindRotation()); + worldTransform.setScale(bone.getWorldBindScale()); + return worldTransform; + case CONSTRAINT_SPACE_POSE: + Transform poseTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation()); + poseTransform.setScale(bone.getLocalScale()); + return poseTransform; + case CONSTRAINT_SPACE_PARLOCAL: + Transform parentLocalTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation()); + parentLocalTransform.setScale(bone.getLocalScale()); + return parentLocalTransform; + default: + throw new IllegalStateException("Invalid space type for target object: " + space.toString()); + } + } + + /** + * The method applies the transform for the given spatial, computed in the + * given space. + * + * @param spatial + * the spatial we apply the transform for + * @param space + * the computation space + * @param transform + * the transform being applied + */ + /*package*/ void applyTransform(Spatial spatial, Space space, Transform transform) { + switch (space) { + case CONSTRAINT_SPACE_LOCAL: + Transform ownerLocalTransform = spatial.getLocalTransform(); + ownerLocalTransform.getTranslation().addLocal(transform.getTranslation()); + ownerLocalTransform.getRotation().multLocal(transform.getRotation()); + ownerLocalTransform.getScale().multLocal(transform.getScale()); + break; + case CONSTRAINT_SPACE_WORLD: + Matrix4f m = this.getParentWorldTransformMatrix(spatial); + m.invertLocal(); + Matrix4f matrix = this.toMatrix(transform); + m.multLocal(matrix); + + float scaleX = (float) Math.sqrt(m.m00 * m.m00 + m.m10 * m.m10 + m.m20 * m.m20); + float scaleY = (float) Math.sqrt(m.m01 * m.m01 + m.m11 * m.m11 + m.m21 * m.m21); + float scaleZ = (float) Math.sqrt(m.m02 * m.m02 + m.m12 * m.m12 + m.m22 * m.m22); + + transform.setTranslation(m.toTranslationVector()); + transform.setRotation(m.toRotationQuat()); + transform.setScale(scaleX, scaleY, scaleZ); + spatial.setLocalTransform(transform); + break; + case CONSTRAINT_SPACE_PARLOCAL: + case CONSTRAINT_SPACE_POSE: + throw new IllegalStateException("Invalid space type (" + space.toString() + ") for owner object."); + default: + throw new IllegalStateException("Invalid space type for target object: " + space.toString()); + } + } + + /** + * The method applies the transform for the given bone, computed in the + * given space. + * + * @param bone + * the bone we apply the transform for + * @param space + * the computation space + * @param transform + * the transform being applied + */ + /*package*/ void applyTransform(Bone bone, Space space, Transform transform) { + switch (space) { + case CONSTRAINT_SPACE_LOCAL: + bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale()); + break; + case CONSTRAINT_SPACE_WORLD: + Matrix4f m = this.getParentWorldTransformMatrix(bone); + // m.invertLocal(); + transform.setTranslation(m.mult(transform.getTranslation())); + transform.setRotation(m.mult(transform.getRotation(), null)); + transform.setScale(transform.getScale()); + bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale()); + // float x = FastMath.HALF_PI/2; + // float y = -FastMath.HALF_PI; + // float z = -FastMath.HALF_PI/2; + // bone.setBindTransforms(new Vector3f(0,0,0), new Quaternion().fromAngles(x, y, z), new Vector3f(1,1,1)); + break; + case CONSTRAINT_SPACE_PARLOCAL: + Vector3f parentLocalTranslation = bone.getLocalPosition().add(transform.getTranslation()); + Quaternion parentLocalRotation = bone.getLocalRotation().mult(transform.getRotation()); + bone.setBindTransforms(parentLocalTranslation, parentLocalRotation, transform.getScale()); + break; + case CONSTRAINT_SPACE_POSE: + bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale()); + break; + default: + throw new IllegalStateException("Invalid space type for target object: " + space.toString()); + } + } + + /** + * @return world transform matrix of the feature's parent or identity matrix + * if the feature has no parent + */ + private Matrix4f getParentWorldTransformMatrix(Spatial spatial) { + Matrix4f result = new Matrix4f(); + if (spatial.getParent() != null) { + Transform t = spatial.getParent().getWorldTransform(); + result.setTransform(t.getTranslation(), t.getScale(), t.getRotation().toRotationMatrix()); + } + return result; + } + + /** + * @return world transform matrix of the feature's parent or identity matrix + * if the feature has no parent + */ + private Matrix4f getParentWorldTransformMatrix(Bone bone) { + Matrix4f result = new Matrix4f(); + Bone parent = bone.getParent(); + if (parent != null) { + result.setTransform(parent.getWorldBindPosition(), parent.getWorldBindScale(), parent.getWorldBindRotation().toRotationMatrix()); + } + return result; + } + + /** + * Converts given transform to the matrix. + * + * @param transform + * the transform to be converted + * @return 4x4 matri that represents the given transform + */ + private Matrix4f toMatrix(Transform transform) { + Matrix4f result = Matrix4f.IDENTITY; + if (transform != null) { + result = new Matrix4f(); + result.setTranslation(transform.getTranslation()); + result.setRotationQuaternion(transform.getRotation()); + result.setScale(transform.getScale()); + } + return result; } @Override public boolean shouldBeLoaded(Structure structure, BlenderContext blenderContext) { return true; } + + /** + * The space of target or owner transformation. + * + * @author Marcin Roguski (Kaelthas) + */ + public static enum Space { + + CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL, CONSTRAINT_SPACE_INVALID; + + /** + * This method returns the enum instance when given the appropriate + * value from the blend file. + * + * @param c + * the blender's value of the space modifier + * @return the scape enum instance + */ + public static Space valueOf(byte c) { + switch (c) { + case 0: + return CONSTRAINT_SPACE_WORLD; + case 1: + return CONSTRAINT_SPACE_LOCAL; + case 2: + return CONSTRAINT_SPACE_POSE; + case 3: + return CONSTRAINT_SPACE_PARLOCAL; + default: + return CONSTRAINT_SPACE_INVALID; + } + } + } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLike.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLike.java deleted file mode 100644 index 834dfb43a..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLike.java +++ /dev/null @@ -1,122 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.animation.Animation; -import com.jme3.math.Transform; -import com.jme3.math.Vector3f; -import com.jme3.scene.Spatial; -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import com.jme3.scene.plugins.ogre.AnimData; - -/** - * This class represents 'Loc like' constraint type in blender. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintLocLike extends Constraint { - private static final int LOCLIKE_X = 0x01; - private static final int LOCLIKE_Y = 0x02; - private static final int LOCLIKE_Z = 0x04; - //protected static final int LOCLIKE_TIP = 0x08;//this is deprecated in blender - private static final int LOCLIKE_X_INVERT = 0x10; - private static final int LOCLIKE_Y_INVERT = 0x20; - private static final int LOCLIKE_Z_INVERT = 0x40; - private static final int LOCLIKE_OFFSET = 0x80; - - protected int flag; - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintLocLike(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - - flag = ((Number) data.getFieldValue("flag")).intValue(); - - if(blenderContext.getBlenderKey().isFixUpAxis()) { - //swapping Y and X limits flag in the bitwise flag - int y = flag & LOCLIKE_Y; - int invY = flag & LOCLIKE_Y_INVERT; - int z = flag & LOCLIKE_Z; - int invZ = flag & LOCLIKE_Z_INVERT; - flag &= LOCLIKE_X | LOCLIKE_X_INVERT | LOCLIKE_OFFSET;//clear the other flags to swap them - flag |= y << 2; - flag |= invY << 2; - flag |= z >> 2; - flag |= invZ >> 2; - } - } - - @Override - protected void bakeConstraint() { - Object owner = this.owner.getObject(); - AnimData animData = blenderContext.getAnimData(this.owner.getOma()); - if(animData != null) { - Transform targetTransform = this.target.getTransform(); - for(Animation animation : animData.anims) { - BlenderTrack blenderTrack = this.getTrack(owner, animData.skeleton, animation); - Vector3f[] translations = blenderTrack.getTranslations(); - int maxFrames = translations.length; - for (int frame = 0; frame < maxFrames; ++frame) { - this.locLike(translations[frame], targetTransform.getTranslation(), ipo.calculateValue(frame)); - } - blenderTrack.setKeyframes(blenderTrack.getTimes(), translations, blenderTrack.getRotations(), blenderTrack.getScales()); - } - } - - if(owner instanceof Spatial) { - Transform targetTransform = this.target.getTransform(); - Transform ownerTransform = this.owner.getTransform(); - Vector3f ownerLocation = ownerTransform.getTranslation(); - this.locLike(ownerLocation, targetTransform.getTranslation(), ipo.calculateValue(0)); - this.owner.applyTransform(ownerTransform); - } - } - - private void locLike(Vector3f ownerLocation, Vector3f targetLocation, float influence) { - Vector3f startLocation = ownerLocation.clone(); - Vector3f offset = Vector3f.ZERO; - if ((flag & LOCLIKE_OFFSET) != 0) {//we add the original location to the copied location - offset = startLocation; - } - - if ((flag & LOCLIKE_X) != 0) { - ownerLocation.x = targetLocation.x; - if ((flag & LOCLIKE_X_INVERT) != 0) { - ownerLocation.x = -ownerLocation.x; - } - } - if ((flag & LOCLIKE_Y) != 0) { - ownerLocation.y = targetLocation.y; - if ((flag & LOCLIKE_Y_INVERT) != 0) { - ownerLocation.y = -ownerLocation.y; - } - } - if ((flag & LOCLIKE_Z) != 0) { - ownerLocation.z = targetLocation.z; - if ((flag & LOCLIKE_Z_INVERT) != 0) { - ownerLocation.z = -ownerLocation.z; - } - } - ownerLocation.addLocal(offset); - - if(influence < 1.0f) { - startLocation.subtractLocal(ownerLocation).normalizeLocal().mult(influence); - ownerLocation.addLocal(startLocation); - } - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLimit.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLimit.java deleted file mode 100644 index 74e2ec1f8..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLimit.java +++ /dev/null @@ -1,137 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.animation.Animation; -import com.jme3.math.Transform; -import com.jme3.math.Vector3f; -import com.jme3.scene.Spatial; -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import com.jme3.scene.plugins.ogre.AnimData; - -/** - * This class represents 'Loc limit' constraint type in blender. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintLocLimit extends Constraint { - private static final int LIMIT_XMIN = 0x01; - private static final int LIMIT_XMAX = 0x02; - private static final int LIMIT_YMIN = 0x04; - private static final int LIMIT_YMAX = 0x08; - private static final int LIMIT_ZMIN = 0x10; - private static final int LIMIT_ZMAX = 0x20; - - protected float[][] limits = new float[3][2]; - protected int flag; - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintLocLimit(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - - flag = ((Number) data.getFieldValue("flag")).intValue(); - if(blenderContext.getBlenderKey().isFixUpAxis()) { - limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue(); - limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue(); - limits[2][0] = -((Number) data.getFieldValue("ymin")).floatValue(); - limits[2][1] = -((Number) data.getFieldValue("ymax")).floatValue(); - limits[1][0] = ((Number) data.getFieldValue("zmin")).floatValue(); - limits[1][1] = ((Number) data.getFieldValue("zmax")).floatValue(); - - //swapping Y and X limits flag in the bitwise flag - int ymin = flag & LIMIT_YMIN; - int ymax = flag & LIMIT_YMAX; - int zmin = flag & LIMIT_ZMIN; - int zmax = flag & LIMIT_ZMAX; - flag &= LIMIT_XMIN | LIMIT_XMAX;//clear the other flags to swap them - flag |= ymin << 2; - flag |= ymax << 2; - flag |= zmin >> 2; - flag |= zmax >> 2; - } else { - limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue(); - limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue(); - limits[1][0] = ((Number) data.getFieldValue("ymin")).floatValue(); - limits[1][1] = ((Number) data.getFieldValue("ymax")).floatValue(); - limits[2][0] = ((Number) data.getFieldValue("zmin")).floatValue(); - limits[2][1] = ((Number) data.getFieldValue("zmax")).floatValue(); - } - } - - @Override - protected void bakeConstraint() { - Object owner = this.owner.getObject(); - AnimData animData = blenderContext.getAnimData(this.owner.getOma()); - if(animData != null) { - for(Animation animation : animData.anims) { - BlenderTrack track = this.getTrack(owner, animData.skeleton, animation); - Vector3f[] translations = track.getTranslations(); - int maxFrames = translations.length; - for (int frame = 0; frame < maxFrames; ++frame) { - this.locLimit(translations[frame], ipo.calculateValue(frame)); - } - track.setKeyframes(track.getTimes(), translations, track.getRotations(), track.getScales()); - } - } - - if(owner instanceof Spatial) { - Transform ownerTransform = this.owner.getTransform(); - Vector3f ownerLocation = ownerTransform.getTranslation(); - this.locLimit(ownerLocation, ipo.calculateValue(0)); - this.owner.applyTransform(ownerTransform); - } - } - - /** - * This method modifies the given translation. - * @param translation the translation to be modified. - * @param influence the influence value - */ - private void locLimit(Vector3f translation, float influence) { - if ((flag & LIMIT_XMIN) != 0) { - if (translation.x < limits[0][0]) { - translation.x -= (translation.x - limits[0][0]) * influence; - } - } - if ((flag & LIMIT_XMAX) != 0) { - if (translation.x > limits[0][1]) { - translation.x -= (translation.x - limits[0][1]) * influence; - } - } - if ((flag & LIMIT_YMIN) != 0) { - if (translation.y < limits[1][0]) { - translation.y -= (translation.y - limits[1][0]) * influence; - } - } - if ((flag & LIMIT_YMAX) != 0) { - if (translation.y > limits[1][1]) { - translation.y -= (translation.y - limits[1][1]) * influence; - } - } - if ((flag & LIMIT_ZMIN) != 0) { - if (translation.z < limits[2][0]) { - translation.z -= (translation.z - limits[2][0]) * influence; - } - } - if ((flag & LIMIT_ZMAX) != 0) { - if (translation.z > limits[2][1]) { - translation.z -= (translation.z - limits[2][1]) * influence; - } - } - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLockTrack.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLockTrack.java deleted file mode 100644 index e54d70a45..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLockTrack.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * This class represents 'Action' constraint type in blender. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintLockTrack extends Constraint { - private static final Logger LOGGER = Logger.getLogger(ConstraintLockTrack.class.getName()); - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintLockTrack(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) - throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - } - - @Override - protected void bakeConstraint() { - // TODO: implement 'Lock track' constraint - LOGGER.log(Level.WARNING, "'Lock track' constraint NOT implemented!"); - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintMinMax.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintMinMax.java deleted file mode 100644 index f4a5456e8..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintMinMax.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * This class represents 'Min max' constraint type in blender. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintMinMax extends Constraint { - private static final Logger LOGGER = Logger.getLogger(ConstraintMinMax.class.getName()); - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintMinMax(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - } - - @Override - protected void bakeConstraint() { - // TODO: implement 'Min max' constraint - LOGGER.log(Level.WARNING, "'Min max' constraint NOT implemented!"); - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintNull.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintNull.java deleted file mode 100644 index 4409969ee..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintNull.java +++ /dev/null @@ -1,37 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; - -/** - * This class represents 'Null' constraint type in blender. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintNull extends Constraint { - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintNull(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) - throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - } - - @Override - protected void bakeConstraint() {} -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintPivot.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintPivot.java deleted file mode 100644 index e7cb65a60..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintPivot.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * The pivot constraint. Available for blender 2.50+. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintPivot extends Constraint { - private static final Logger LOGGER = Logger.getLogger(ConstraintPivot.class.getName()); - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintPivot(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, - BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - // TODO Auto-generated constructor stub - } - - @Override - protected void bakeConstraint() { - // TODO Auto-generated method stub - LOGGER.log(Level.WARNING, "'Pivot' constraint NOT implemented!"); - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintPython.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintPython.java deleted file mode 100644 index a0beb7864..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintPython.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * This class represents 'Python' constraint type in blender. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintPython extends Constraint { - private static final Logger LOGGER = Logger.getLogger(ConstraintPython.class.getName()); - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintPython(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - } - - @Override - protected void bakeConstraint() { - // TODO: implement 'Python' constraint - LOGGER.log(Level.WARNING, "'Python' constraint NOT implemented!"); - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRigidBodyJoint.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRigidBodyJoint.java deleted file mode 100644 index b398ae612..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRigidBodyJoint.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * This class represents 'Rigid body joint' constraint type in blender. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintRigidBodyJoint extends Constraint { - private static final Logger LOGGER = Logger.getLogger(ConstraintRigidBodyJoint.class.getName()); - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintRigidBodyJoint(Structure constraintStructure, - Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - } - - @Override - protected void bakeConstraint() { - // TODO: implement 'Rigid body joint' constraint - LOGGER.log(Level.WARNING, "'Rigid body joint' constraint NOT implemented!"); - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLike.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLike.java deleted file mode 100644 index db0c93a6c..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLike.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.animation.Animation; -import com.jme3.math.Quaternion; -import com.jme3.math.Transform; -import com.jme3.scene.Spatial; -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import com.jme3.scene.plugins.ogre.AnimData; - -/** - * This class represents 'Rot like' constraint type in blender. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintRotLike extends Constraint { - private static final int ROTLIKE_X = 0x01; - private static final int ROTLIKE_Y = 0x02; - private static final int ROTLIKE_Z = 0x04; - private static final int ROTLIKE_X_INVERT = 0x10; - private static final int ROTLIKE_Y_INVERT = 0x20; - private static final int ROTLIKE_Z_INVERT = 0x40; - private static final int ROTLIKE_OFFSET = 0x80; - - protected int flag; - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintRotLike(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - - flag = ((Number) data.getFieldValue("flag")).intValue(); - } - - @Override - protected void bakeConstraint() { - Object owner = this.owner.getObject(); - AnimData animData = blenderContext.getAnimData(this.owner.getOma()); - if(animData != null) { - Transform targetTransform = this.target.getTransform(); - Quaternion targetRotation = targetTransform.getRotation(); - for(Animation animation : animData.anims) { - BlenderTrack track = this.getTrack(owner, animData.skeleton, animation); - float[] targetAngles = targetRotation.toAngles(null); - Quaternion[] rotations = track.getRotations(); - int maxFrames = rotations.length; - float[] angles = new float[3]; - for (int frame = 0; frame < maxFrames; ++frame) { - rotations[frame].toAngles(angles); - this.rotLike(rotations[frame], angles, targetAngles, ipo.calculateValue(frame)); - } - track.setKeyframes(track.getTimes(), track.getTranslations(), rotations, track.getScales()); - } - } - - if(owner instanceof Spatial) { - Transform targetTransform = this.target.getTransform(); - Transform ownerTransform = this.owner.getTransform(); - Quaternion ownerRotation = ownerTransform.getRotation(); - this.rotLike(ownerRotation, ownerRotation.toAngles(null), targetTransform.getRotation().toAngles(null), ipo.calculateValue(0)); - this.owner.applyTransform(ownerTransform); - } - } - - private void rotLike(Quaternion ownerRotation, float[] ownerAngles, float[] targetAngles, float influence) { - Quaternion startRotation = ownerRotation.clone(); - Quaternion offset = Quaternion.IDENTITY; - if ((flag & ROTLIKE_OFFSET) != 0) {//we add the original rotation to the copied rotation - offset = startRotation; - } - - if ((flag & ROTLIKE_X) != 0) { - ownerAngles[0] = targetAngles[0]; - if ((flag & ROTLIKE_X_INVERT) != 0) { - ownerAngles[0] = -ownerAngles[0]; - } - } - if ((flag & ROTLIKE_Y) != 0) { - ownerAngles[1] = targetAngles[1]; - if ((flag & ROTLIKE_Y_INVERT) != 0) { - ownerAngles[1] = -ownerAngles[1]; - } - } - if ((flag & ROTLIKE_Z) != 0) { - ownerAngles[2] = targetAngles[2]; - if ((flag & ROTLIKE_Z_INVERT) != 0) { - ownerAngles[2] = -ownerAngles[2]; - } - } - ownerRotation.fromAngles(ownerAngles).multLocal(offset); - - if(influence < 1.0f) { - -// startLocation.subtractLocal(ownerLocation).normalizeLocal().mult(influence); -// ownerLocation.addLocal(startLocation); - //TODO - } - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLimit.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLimit.java deleted file mode 100644 index d63f342de..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintRotLimit.java +++ /dev/null @@ -1,180 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.animation.Animation; -import com.jme3.animation.Bone; -import com.jme3.math.FastMath; -import com.jme3.math.Quaternion; -import com.jme3.math.Transform; -import com.jme3.scene.Spatial; -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import com.jme3.scene.plugins.ogre.AnimData; - -/** - * This class represents 'Rot limit' constraint type in blender. - * - * @author Marcin Roguski (Kaelthas) - */ -/* package */class ConstraintRotLimit extends Constraint { - private static final int LIMIT_XROT = 0x01; - private static final int LIMIT_YROT = 0x02; - private static final int LIMIT_ZROT = 0x04; - - protected float[][] limits = new float[3][2]; - protected int flag; - protected boolean updated; - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintRotLimit(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - - flag = ((Number) data.getFieldValue("flag")).intValue(); - if (blenderContext.getBlenderKey().isFixUpAxis() && owner.spatial != null) { - limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue(); - limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue(); - limits[2][0] = -((Number) data.getFieldValue("ymin")).floatValue(); - limits[2][1] = -((Number) data.getFieldValue("ymax")).floatValue(); - limits[1][0] = ((Number) data.getFieldValue("zmin")).floatValue(); - limits[1][1] = ((Number) data.getFieldValue("zmax")).floatValue(); - - // swapping Y and X limits flag in the bitwise flag - int limitY = flag & LIMIT_YROT; - int limitZ = flag & LIMIT_ZROT; - flag &= LIMIT_XROT;// clear the other flags to swap them - flag |= limitY << 1; - flag |= limitZ >> 1; - } else { - limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue(); - limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue(); - limits[1][0] = ((Number) data.getFieldValue("ymin")).floatValue(); - limits[1][1] = ((Number) data.getFieldValue("ymax")).floatValue(); - limits[2][0] = ((Number) data.getFieldValue("zmin")).floatValue(); - limits[2][1] = ((Number) data.getFieldValue("zmax")).floatValue(); - } - - // until blender 2.49 the rotations values were stored in degrees - if (blenderContext.getBlenderVersion() <= 249) { - for (int i = 0; i < limits.length; ++i) { - limits[i][0] *= FastMath.DEG_TO_RAD; - limits[i][1] *= FastMath.DEG_TO_RAD; - } - } - } - - @Override - protected void bakeConstraint() { - this.update(); - Object owner = this.owner.getObject(); - AnimData animData = blenderContext.getAnimData(this.owner.getOma()); - if (animData != null) { - for (Animation animation : animData.anims) { - BlenderTrack track = this.getTrack(owner, animData.skeleton, animation); - Quaternion[] rotations = track.getRotations(); - float[] angles = new float[3]; - int maxFrames = rotations.length; - for (int frame = 0; frame < maxFrames; ++frame) { - rotations[frame].toAngles(angles); - this.rotLimit(angles, ipo.calculateValue(frame)); - rotations[frame].fromAngles(angles); - } - track.setKeyframes(track.getTimes(), track.getTranslations(), rotations, track.getScales()); - } - } - - if (owner instanceof Spatial) { - Transform ownerTransform = this.owner.getTransform(); - float[] angles = ownerTransform.getRotation().toAngles(null); - this.rotLimit(angles, ipo.calculateValue(0)); - ownerTransform.getRotation().fromAngles(angles); - this.owner.applyTransform(ownerTransform); - } - } - - /** - * This method computes new constrained angles. - * - * @param angles - * angles to be altered - * @param influence - * the alteration influence - */ - private void rotLimit(float[] angles, float influence) { - if ((flag & LIMIT_XROT) != 0) { - float difference = 0.0f; - if (angles[0] < limits[0][0]) { - difference = (angles[0] - limits[0][0]) * influence; - } else if (angles[0] > limits[0][1]) { - difference = (angles[0] - limits[0][1]) * influence; - } - angles[0] -= difference; - } - if ((flag & LIMIT_YROT) != 0) { - float difference = 0.0f; - if (angles[1] < limits[1][0]) { - difference = (angles[1] - limits[1][0]) * influence; - } else if (angles[1] > limits[1][1]) { - difference = (angles[1] - limits[1][1]) * influence; - } - angles[1] -= difference; - } - if ((flag & LIMIT_ZROT) != 0) { - float difference = 0.0f; - if (angles[2] < limits[2][0]) { - difference = (angles[2] - limits[2][0]) * influence; - } else if (angles[2] > limits[2][1]) { - difference = (angles[2] - limits[2][1]) * influence; - } - angles[2] -= difference; - } - } - - /** - * This method is called before baking (performes its operations only once). - * It is important to update the state of the limits and owner/target before - * baking the constraint. - */ - private void update() { - if (!updated) { - updated = true; - if (owner != null) { - owner.update(); - } - if (target != null) { - target.update(); - } - if (this.owner.getObject() instanceof Bone) {// for bones we need to - // change the sign - // of the limits - for (int i = 0; i < limits.length; ++i) { - limits[i][0] *= -1; - limits[i][1] *= -1; - } - } - - // sorting the limits (lower is always first) - for (int i = 0; i < limits.length; ++i) { - if (limits[i][0] > limits[i][1]) { - float temp = limits[i][0]; - limits[i][0] = limits[i][1]; - limits[i][1] = temp; - } - } - } - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSameVolume.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSameVolume.java deleted file mode 100644 index 5311057f8..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSameVolume.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; - -/** - * This class represents 'Same volume' constraint type in blender. - * - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintSameVolume extends Constraint { - private static final Logger LOGGER = Logger.getLogger(ConstraintSameVolume.class.getName()); - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintSameVolume(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) - throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - } - - @Override - protected void bakeConstraint() { - // TODO: implement 'Same volume' constraint - LOGGER.log(Level.WARNING, "'Same volume' constraint NOT implemented!"); - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLike.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLike.java deleted file mode 100644 index 8b697aa82..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLike.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.animation.Animation; -import com.jme3.math.Transform; -import com.jme3.math.Vector3f; -import com.jme3.scene.Spatial; -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import com.jme3.scene.plugins.ogre.AnimData; - -/** - * This class represents 'Size like' constraint type in blender. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintSizeLike extends Constraint { - private static final int SIZELIKE_X = 0x01; - private static final int SIZELIKE_Y = 0x02; - private static final int SIZELIKE_Z = 0x04; - private static final int LOCLIKE_OFFSET = 0x80; - - protected int flag; - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintSizeLike(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - - flag = ((Number) data.getFieldValue("flag")).intValue(); - if(blenderContext.getBlenderKey().isFixUpAxis()) { - //swapping Y and X limits flag in the bitwise flag - int y = flag & SIZELIKE_Y; - int z = flag & SIZELIKE_Z; - flag &= SIZELIKE_X | LOCLIKE_OFFSET;//clear the other flags to swap them - flag |= y << 1; - flag |= z >> 1; - } - } - - @Override - protected void bakeConstraint() { - Object owner = this.owner.getObject(); - AnimData animData = blenderContext.getAnimData(this.owner.getOma()); - if(animData != null) { - Transform targetTransform = this.target.getTransform(); - Vector3f targetScale = targetTransform.getScale(); - for(Animation animation : animData.anims) { - BlenderTrack track = this.getTrack(owner, animData.skeleton, animation); - Vector3f[] scales = track.getScales(); - int maxFrames = scales.length; - for (int frame = 0; frame < maxFrames; ++frame) { - this.sizeLike(scales[frame], targetScale, ipo.calculateValue(frame)); - } - track.setKeyframes(track.getTimes(), track.getTranslations(), track.getRotations(), scales); - } - } - - if(owner instanceof Spatial) { - Transform targetTransform = this.target.getTransform(); - Transform ownerTransform = this.owner.getTransform(); - this.sizeLike(ownerTransform.getScale(), targetTransform.getScale(), ipo.calculateValue(0)); - this.owner.applyTransform(ownerTransform); - } - } - - private void sizeLike(Vector3f ownerScale, Vector3f targetScale, float influence) { - Vector3f offset = Vector3f.ZERO; - if ((flag & LOCLIKE_OFFSET) != 0) {//we add the original scale to the copied scale - offset = ownerScale.clone(); - } - - if ((flag & SIZELIKE_X) != 0) { - ownerScale.x = targetScale.x * influence + (1.0f - influence) * ownerScale.x; - } - if ((flag & SIZELIKE_Y) != 0) { - ownerScale.y = targetScale.y * influence + (1.0f - influence) * ownerScale.y; - } - if ((flag & SIZELIKE_Z) != 0) { - ownerScale.z = targetScale.z * influence + (1.0f - influence) * ownerScale.z; - } - ownerScale.addLocal(offset); - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLimit.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLimit.java deleted file mode 100644 index 5d5829958..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSizeLimit.java +++ /dev/null @@ -1,131 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.animation.Animation; -import com.jme3.math.Transform; -import com.jme3.math.Vector3f; -import com.jme3.scene.Spatial; -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import com.jme3.scene.plugins.ogre.AnimData; - -/** - * This class represents 'Size limit' constraint type in blender. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintSizeLimit extends Constraint { - private static final int LIMIT_XMIN = 0x01; - private static final int LIMIT_XMAX = 0x02; - private static final int LIMIT_YMIN = 0x04; - private static final int LIMIT_YMAX = 0x08; - private static final int LIMIT_ZMIN = 0x10; - private static final int LIMIT_ZMAX = 0x20; - - protected float[][] limits = new float[3][2]; - protected int flag; - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintSizeLimit(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - - flag = ((Number) data.getFieldValue("flag")).intValue(); - if(blenderContext.getBlenderKey().isFixUpAxis()) { - limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue(); - limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue(); - limits[2][0] = -((Number) data.getFieldValue("ymin")).floatValue(); - limits[2][1] = -((Number) data.getFieldValue("ymax")).floatValue(); - limits[1][0] = ((Number) data.getFieldValue("zmin")).floatValue(); - limits[1][1] = ((Number) data.getFieldValue("zmax")).floatValue(); - - //swapping Y and X limits flag in the bitwise flag - int ymin = flag & LIMIT_YMIN; - int ymax = flag & LIMIT_YMAX; - int zmin = flag & LIMIT_ZMIN; - int zmax = flag & LIMIT_ZMAX; - flag &= LIMIT_XMIN | LIMIT_XMAX;//clear the other flags to swap them - flag |= ymin << 2; - flag |= ymax << 2; - flag |= zmin >> 2; - flag |= zmax >> 2; - } else { - limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue(); - limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue(); - limits[1][0] = ((Number) data.getFieldValue("ymin")).floatValue(); - limits[1][1] = ((Number) data.getFieldValue("ymax")).floatValue(); - limits[2][0] = ((Number) data.getFieldValue("zmin")).floatValue(); - limits[2][1] = ((Number) data.getFieldValue("zmax")).floatValue(); - } - } - - @Override - protected void bakeConstraint() { - Object owner = this.owner.getObject(); - AnimData animData = blenderContext.getAnimData(this.owner.getOma()); - if(animData != null) { - for(Animation animation : animData.anims) { - BlenderTrack track = this.getTrack(owner, animData.skeleton, animation); - Vector3f[] scales = track.getScales(); - int maxFrames = scales.length; - for (int frame = 0; frame < maxFrames; ++frame) { - this.sizeLimit(scales[frame], ipo.calculateValue(frame)); - } - track.setKeyframes(track.getTimes(), track.getTranslations(), track.getRotations(), scales); - } - } - - if(owner instanceof Spatial) { - Transform ownerTransform = this.owner.getTransform(); - this.sizeLimit(ownerTransform.getScale(), ipo.calculateValue(0)); - this.owner.applyTransform(ownerTransform); - } - } - - private void sizeLimit(Vector3f scale, float influence) { - if ((flag & LIMIT_XMIN) != 0) { - if (scale.x < limits[0][0]) { - scale.x -= (scale.x - limits[0][0]) * influence; - } - } - if ((flag & LIMIT_XMAX) != 0) { - if (scale.x > limits[0][1]) { - scale.x -= (scale.x - limits[0][1]) * influence; - } - } - if ((flag & LIMIT_YMIN) != 0) { - if (scale.y < limits[1][0]) { - scale.y -= (scale.y - limits[1][0]) * influence; - } - } - if ((flag & LIMIT_YMAX) != 0) { - if (scale.y > limits[1][1]) { - scale.y -= (scale.y - limits[1][1]) * influence; - } - } - if ((flag & LIMIT_ZMIN) != 0) { - if (scale.z < limits[2][0]) { - scale.z -= (scale.z - limits[2][0]) * influence; - } - } - if ((flag & LIMIT_ZMAX) != 0) { - if (scale.z > limits[2][1]) { - scale.z -= (scale.z - limits[2][1]) * influence; - } - } - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSplineInverseKinematic.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSplineInverseKinematic.java deleted file mode 100644 index e38b78637..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintSplineInverseKinematic.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * The spline inverse kinematic constraint. Available for blender 2.50+. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintSplineInverseKinematic extends Constraint { - private static final Logger LOGGER = Logger.getLogger(ConstraintSplineInverseKinematic.class.getName()); - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintSplineInverseKinematic(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, - BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - // TODO Auto-generated constructor stub - } - - @Override - protected void bakeConstraint() { - // TODO Auto-generated method stub - LOGGER.log(Level.WARNING, "'Splie IK' constraint NOT implemented!"); - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintStretchTo.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintStretchTo.java deleted file mode 100644 index a5a9f55aa..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintStretchTo.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * This class represents 'Stretch to' constraint type in blender. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintStretchTo extends Constraint { - private static final Logger LOGGER = Logger.getLogger(ConstraintStretchTo.class.getName()); - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintStretchTo(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - } - - @Override - protected void bakeConstraint() { - // TODO: implement 'Stretch to' constraint - LOGGER.log(Level.WARNING, "'Stretch to' constraint NOT implemented!"); - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintTrackTo.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintTrackTo.java deleted file mode 100644 index fdcf55462..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintTrackTo.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; - -/** - * This class represents 'Track to' constraint type in blender. - * - * @author Marcin Roguski (Kaelthas) - */ -/* package */class ConstraintTrackTo extends Constraint { - private static final Logger LOGGER = Logger.getLogger(ConstraintTrackTo.class.getName()); - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintTrackTo(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) - throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - } - - @Override - protected void bakeConstraint() { - // TODO: implement 'Track to' constraint - LOGGER.log(Level.WARNING, "'Track to' constraint NOT implemented!"); - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintTransLike.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintTransLike.java deleted file mode 100644 index 6be52d3a9..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintTransLike.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; - -/** - * This class represents 'Trans like' constraint type in blender. - * - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintTransLike extends Constraint { - private static final Logger LOGGER = Logger.getLogger(ConstraintTransLike.class.getName()); - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintTransLike(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) - throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - } - - @Override - protected void bakeConstraint() { - // TODO: implement 'Trans like' constraint - LOGGER.log(Level.WARNING, "'Trans like' constraint NOT implemented!"); - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintTransform.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintTransform.java deleted file mode 100644 index 5d111a318..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintTransform.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Structure; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * This class represents 'Transform' constraint type in blender. - * @author Marcin Roguski (Kaelthas) - */ -/*package*/ class ConstraintTransform extends Constraint { - private static final Logger LOGGER = Logger.getLogger(ConstraintAction.class.getName()); - - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintTransform(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); - } - - @Override - protected void bakeConstraint() { - // TODO: implement 'Transform' constraint - LOGGER.log(Level.WARNING, "'Transform' constraint NOT implemented!"); - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/Feature.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/Feature.java deleted file mode 100644 index b08a20c0c..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/Feature.java +++ /dev/null @@ -1,302 +0,0 @@ -package com.jme3.scene.plugins.blender.constraints; - -import com.jme3.animation.Bone; -import com.jme3.math.Matrix4f; -import com.jme3.math.Quaternion; -import com.jme3.math.Transform; -import com.jme3.math.Vector3f; -import com.jme3.scene.Spatial; -import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType; -import com.jme3.scene.plugins.blender.constraints.Constraint.Space; -import com.jme3.scene.plugins.blender.file.DynamicArray; -import com.jme3.scene.plugins.blender.file.Structure; - -/** - * This class represents either owner or target of the constraint. It has the - * common methods that take the evalueation space of the feature. - * - * @author Marcin Roguski (Kaelthas) - */ -/* package */class Feature { - /** The evalueation space. */ - protected Space space; - /** Old memory address of the feature. */ - protected Long oma; - /** The spatial that is hold by the Feature. */ - protected Spatial spatial; - /** The bone that is hold by the Feature. */ - protected Bone bone; - /** The blender context. */ - protected BlenderContext blenderContext; - - /** - * Constructs the feature. This object should be loaded later - * when it is read from the blender file. - * The update method should be called before the feature is used. - * - * @param space - * the spatial's evaluation space - * @param oma - * the spatial's old memory address - * @param blenderContext - * the blender context - */ - public Feature(Space space, Long oma, BlenderContext blenderContext) { - this.space = space; - this.oma = oma; - this.blenderContext = blenderContext; - } - - /** - * Constructs the feature based on spatial. - * - * @param spatial - * the spatial - * @param space - * the spatial's evaluation space - * @param oma - * the spatial's old memory address - * @param blenderContext - * the blender context - */ - public Feature(Spatial spatial, Space space, Long oma, BlenderContext blenderContext) { - this(space, oma, blenderContext); - this.blenderContext = blenderContext; - } - - /** - * Constructs the feature based on bone. - * - * @param bone - * the bone - * @param space - * the bone evaluation space - * @param oma - * the bone old memory address - * @param blenderContext - * the blender context - */ - public Feature(Bone bone, Space space, Long oma, BlenderContext blenderContext) { - this(space, oma, blenderContext); - this.bone = bone; - } - - /** - * This method should be called before the feature is used. - * It may happen that the object this feature refers to was not yet loaded from blend file - * when the instance of this class was created. - */ - public void update() { - Object owner = blenderContext.getLoadedFeature(oma, LoadedFeatureDataType.LOADED_FEATURE); - if(owner instanceof Spatial) { - this.spatial = (Spatial) owner; - } else if(owner instanceof Bone) { - this.bone = (Bone) owner; - } else { - throw new IllegalStateException("Unknown type of owner: " + owner.getClass()); - } - } - - /** - * @return the feature's old memory address - */ - public Long getOma() { - return oma; - } - - /** - * @return the object held by the feature (either bone or spatial) - */ - public Object getObject() { - if (spatial != null) { - return spatial; - } - return bone; - } - - /** - * @return the feature's transform depending on the evaluation space - */ - @SuppressWarnings("unchecked") - public Transform getTransform() { - if (spatial != null) { - switch (space) { - case CONSTRAINT_SPACE_LOCAL: - Structure targetStructure = (Structure) blenderContext.getLoadedFeature(oma, LoadedFeatureDataType.LOADED_STRUCTURE); - - DynamicArray locArray = ((DynamicArray) targetStructure.getFieldValue("loc")); - Vector3f loc = new Vector3f(locArray.get(0).floatValue(), locArray.get(1).floatValue(), locArray.get(2).floatValue()); - DynamicArray rotArray = ((DynamicArray) targetStructure.getFieldValue("rot")); - Quaternion rot = new Quaternion(new float[] { rotArray.get(0).floatValue(), rotArray.get(1).floatValue(), rotArray.get(2).floatValue() }); - DynamicArray sizeArray = ((DynamicArray) targetStructure.getFieldValue("size")); - Vector3f size = new Vector3f(sizeArray.get(0).floatValue(), sizeArray.get(1).floatValue(), sizeArray.get(2).floatValue()); - - if (blenderContext.getBlenderKey().isFixUpAxis()) { - float y = loc.y; - loc.y = loc.z; - loc.z = -y; - - y = rot.getY(); - float z = rot.getZ(); - rot.set(rot.getX(), z, -y, rot.getW()); - - y = size.y; - size.y = size.z; - size.z = y; - } - - Transform result = new Transform(loc, rot); - result.setScale(size); - return result; - case CONSTRAINT_SPACE_WORLD: - return spatial.getWorldTransform(); - default: - throw new IllegalStateException("Invalid space type for target object: " + space.toString()); - } - } - // Bone - switch (space) { - case CONSTRAINT_SPACE_LOCAL: - Transform localTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation()); - localTransform.setScale(bone.getLocalScale()); - return localTransform; - case CONSTRAINT_SPACE_WORLD: - Transform worldTransform = new Transform(bone.getWorldBindPosition(), bone.getWorldBindRotation()); - worldTransform.setScale(bone.getWorldBindScale()); - return worldTransform; - case CONSTRAINT_SPACE_POSE: - Transform poseTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation()); - poseTransform.setScale(bone.getLocalScale()); - return poseTransform; - case CONSTRAINT_SPACE_PARLOCAL: - Transform parentLocalTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation()); - parentLocalTransform.setScale(bone.getLocalScale()); - return parentLocalTransform; - default: - throw new IllegalStateException("Invalid space type for target object: " + space.toString()); - } - } - - /** - * This method applies the given transform to the feature in the proper - * evaluation space. - * - * @param transform - * the transform to be applied - */ - public void applyTransform(Transform transform) { - if (spatial != null) { - switch (space) { - case CONSTRAINT_SPACE_LOCAL: - Transform ownerLocalTransform = spatial.getLocalTransform(); - ownerLocalTransform.getTranslation().addLocal(transform.getTranslation()); - ownerLocalTransform.getRotation().multLocal(transform.getRotation()); - ownerLocalTransform.getScale().multLocal(transform.getScale()); - break; - case CONSTRAINT_SPACE_WORLD: - Matrix4f m = this.getParentWorldTransformMatrix(); - m.invertLocal(); - Matrix4f matrix = this.toMatrix(transform); - m.multLocal(matrix); - - float scaleX = (float) Math.sqrt(m.m00 * m.m00 + m.m10 * m.m10 + m.m20 * m.m20); - float scaleY = (float) Math.sqrt(m.m01 * m.m01 + m.m11 * m.m11 + m.m21 * m.m21); - float scaleZ = (float) Math.sqrt(m.m02 * m.m02 + m.m12 * m.m12 + m.m22 * m.m22); - - transform.setTranslation(m.toTranslationVector()); - transform.setRotation(m.toRotationQuat()); - transform.setScale(scaleX, scaleY, scaleZ); - spatial.setLocalTransform(transform); - break; - case CONSTRAINT_SPACE_PARLOCAL: - case CONSTRAINT_SPACE_POSE: - throw new IllegalStateException("Invalid space type (" + space.toString() + ") for owner object."); - default: - throw new IllegalStateException("Invalid space type for target object: " + space.toString()); - } - } else {// Bone - switch (space) { - case CONSTRAINT_SPACE_LOCAL: - bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale()); - break; - case CONSTRAINT_SPACE_WORLD: - Matrix4f m = this.getParentWorldTransformMatrix(); -// m.invertLocal(); - transform.setTranslation(m.mult(transform.getTranslation())); - transform.setRotation(m.mult(transform.getRotation(), null)); - transform.setScale(transform.getScale()); - bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale()); -// float x = FastMath.HALF_PI/2; -// float y = -FastMath.HALF_PI; -// float z = -FastMath.HALF_PI/2; -// bone.setBindTransforms(new Vector3f(0,0,0), new Quaternion().fromAngles(x, y, z), new Vector3f(1,1,1)); - break; - case CONSTRAINT_SPACE_PARLOCAL: - Vector3f parentLocalTranslation = bone.getLocalPosition().add(transform.getTranslation()); - Quaternion parentLocalRotation = bone.getLocalRotation().mult(transform.getRotation()); - bone.setBindTransforms(parentLocalTranslation, parentLocalRotation, transform.getScale()); - break; - case CONSTRAINT_SPACE_POSE: - bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale()); - break; - default: - throw new IllegalStateException("Invalid space type for target object: " + space.toString()); - } - } - } - - /** - * @return world transform matrix of the feature - */ - public Matrix4f getWorldTransformMatrix() { - if (spatial != null) { - Matrix4f result = new Matrix4f(); - Transform t = spatial.getWorldTransform(); - result.setTransform(t.getTranslation(), t.getScale(), t.getRotation().toRotationMatrix()); - return result; - } - // Bone - Matrix4f result = new Matrix4f(); - result.setTransform(bone.getWorldBindPosition(), bone.getWorldBindScale(), bone.getWorldBindRotation().toRotationMatrix()); - return result; - } - - /** - * @return world transform matrix of the feature's parent or identity matrix - * if the feature has no parent - */ - public Matrix4f getParentWorldTransformMatrix() { - Matrix4f result = new Matrix4f(); - if (spatial != null) { - if (spatial.getParent() != null) { - Transform t = spatial.getParent().getWorldTransform(); - result.setTransform(t.getTranslation(), t.getScale(), t.getRotation().toRotationMatrix()); - } - } else {// Bone - Bone parent = bone.getParent(); - if (parent != null) { - result.setTransform(parent.getWorldBindPosition(), parent.getWorldBindScale(), parent.getWorldBindRotation().toRotationMatrix()); - } - } - return result; - } - - /** - * Converts given transform to the matrix. - * - * @param transform - * the transform to be converted - * @return 4x4 matri that represents the given transform - */ - protected Matrix4f toMatrix(Transform transform) { - Matrix4f result = Matrix4f.IDENTITY; - if (transform != null) { - result = new Matrix4f(); - result.setTranslation(transform.getTranslation()); - result.setRotationQuaternion(transform.getRotation()); - result.setScale(transform.getScale()); - } - return result; - } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/SkeletonConstraint.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/SkeletonConstraint.java new file mode 100644 index 000000000..887018320 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/SkeletonConstraint.java @@ -0,0 +1,32 @@ +package com.jme3.scene.plugins.blender.constraints; + +import java.util.logging.Logger; + +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.animations.Ipo; +import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * Constraint applied on the skeleton. This constraint is here only to make the + * application not crash when loads constraints applied to armature. But + * skeleton movement is not supported by jme so the constraint will never be + * applied. + * + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class SkeletonConstraint extends Constraint { + private static final Logger LOGGER = Logger.getLogger(SkeletonConstraint.class.getName()); + + public SkeletonConstraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { + super(constraintStructure, ownerOMA, influenceIpo, blenderContext); + } + + @Override + public void performBakingOperation() { + LOGGER.warning("Applying constraints to skeleton is not supported."); + } + + @Override + protected void prepareTracksForApplyingConstraints() { } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/SpatialConstraint.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/SpatialConstraint.java new file mode 100644 index 000000000..aa2a59193 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/SpatialConstraint.java @@ -0,0 +1,146 @@ +package com.jme3.scene.plugins.blender.constraints; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; + +import com.jme3.animation.AnimControl; +import com.jme3.animation.Animation; +import com.jme3.animation.SpatialTrack; +import com.jme3.math.Quaternion; +import com.jme3.math.Transform; +import com.jme3.math.Vector3f; +import com.jme3.scene.Spatial; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType; +import com.jme3.scene.plugins.blender.animations.Ipo; +import com.jme3.scene.plugins.blender.constraints.ConstraintHelper.Space; +import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; +import com.jme3.scene.plugins.blender.file.Structure; +import com.jme3.scene.plugins.ogre.AnimData; + +/** + * Constraint applied on the spatial objects. + * This includes: nodes, cameras nodes and light nodes. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class SpatialConstraint extends Constraint { + /** The owner of the constraint. */ + private Spatial owner; + /** The target of the constraint. */ + private Object target; + + public SpatialConstraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) + throws BlenderFileException { + super(constraintStructure, ownerOMA, influenceIpo, blenderContext); + } + + @Override + public void performBakingOperation() { + this.owner = (Spatial) blenderContext.getLoadedFeature(ownerOMA, LoadedFeatureDataType.LOADED_FEATURE); + this.target = targetOMA != null ? blenderContext.getLoadedFeature(targetOMA, LoadedFeatureDataType.LOADED_FEATURE) : null; + this.prepareTracksForApplyingConstraints(); + + //apply static constraint + Transform ownerTransform = constraintHelper.getNodeObjectTransform(ownerSpace, ownerOMA, blenderContext); + Transform targetTransform = targetOMA != null ? constraintHelper.getNodeObjectTransform(targetSpace, targetOMA, blenderContext) : null; + constraintDefinition.bake(ownerTransform, targetTransform, null, null, this.ipo); + constraintHelper.applyTransform(owner, ownerSpace, ownerTransform); + + //apply dynamic constraint + AnimData animData = blenderContext.getAnimData(ownerOMA); + if(animData != null) { + for(Animation animation : animData.anims) { + SpatialTrack ownerTrack = constraintHelper.getTrack(owner, animation); + + AnimData targetAnimData = blenderContext.getAnimData(targetOMA); + SpatialTrack targetTrack = null; + if(targetAnimData != null) { + targetTrack = constraintHelper.getTrack((Spatial)target, targetAnimData.anims.get(0)); + } + + constraintDefinition.bake(ownerTransform, targetTransform, ownerTrack, targetTrack, this.ipo); + } + } + } + + @Override + protected void prepareTracksForApplyingConstraints() { + Long[] spatialsOMAs = new Long[] { ownerOMA, targetOMA }; + Space[] spaces = new Space[] { ownerSpace, targetSpace }; + + //creating animations for current objects if at least on of their parents have an animation + for (int i = 0; i < spatialsOMAs.length; ++i) { + Long oma = spatialsOMAs[i]; + if(oma != null && oma > 0L) { + AnimData animData = blenderContext.getAnimData(oma); + if(animData == null) { + Spatial currentSpatial = (Spatial)blenderContext.getLoadedFeature(oma, LoadedFeatureDataType.LOADED_FEATURE); + Spatial parent = currentSpatial.getParent(); + while(parent != null && animData == null) { + Structure parentStructure = (Structure)blenderContext.getLoadedFeature(parent.getName(), LoadedFeatureDataType.LOADED_STRUCTURE); + if(parentStructure == null) { + parent = null; + } else { + Long parentOma = parentStructure.getOldMemoryAddress(); + animData = blenderContext.getAnimData(parentOma); + parent = parent.getParent(); + } + } + + if(animData != null) {//create anim data for the current object + this.applyAnimData(currentSpatial, oma, spaces[i], animData.anims.get(0)); + } + } + } + } + + //creating animation for owner if it doesn't have one already and if the target has it + AnimData animData = blenderContext.getAnimData(ownerOMA); + if(animData == null) { + AnimData targetAnimData = blenderContext.getAnimData(targetOMA); + if(targetAnimData != null) { + this.applyAnimData(owner, ownerOMA, ownerSpace, targetAnimData.anims.get(0)); + } + } + } + + /** + * This method applies spatial transform on each frame of the given + * animations. + * + * @param spatial + * the spatial + * @param spatialOma + * the OMA of the given spatial + * @param space + * the space we compute the transform in + * @param referenceAnimation + * the object containing the animations + */ + private void applyAnimData(Spatial spatial, Long spatialOma, Space space, Animation referenceAnimation) { + ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class); + Transform transform = constraintHelper.getNodeObjectTransform(space, spatialOma, blenderContext); + + SpatialTrack parentTrack = (SpatialTrack) referenceAnimation.getTracks()[0]; + + HashMap anims = new HashMap(1); + Animation animation = new Animation(spatial.getName(), referenceAnimation.getLength()); + anims.put(spatial.getName(), animation); + + float[] times = parentTrack.getTimes(); + Vector3f[] translations = new Vector3f[times.length]; + Quaternion[] rotations = new Quaternion[times.length]; + Vector3f[] scales = new Vector3f[times.length]; + Arrays.fill(translations, transform.getTranslation()); + Arrays.fill(rotations, transform.getRotation()); + Arrays.fill(scales, transform.getScale()); + animation.addTrack(new SpatialTrack(times, translations, rotations, scales)); + + AnimControl control = new AnimControl(null); + control.setAnimations(anims); + spatial.addControl(control); + + blenderContext.setAnimData(spatialOma, new AnimData(null, new ArrayList(anims.values()))); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinition.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinition.java new file mode 100644 index 000000000..c03a1eb74 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinition.java @@ -0,0 +1,244 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import java.io.IOException; + +import com.jme3.animation.AnimChannel; +import com.jme3.animation.AnimControl; +import com.jme3.animation.BoneTrack; +import com.jme3.animation.SpatialTrack; +import com.jme3.animation.Track; +import com.jme3.export.JmeExporter; +import com.jme3.export.JmeImporter; +import com.jme3.math.FastMath; +import com.jme3.math.Quaternion; +import com.jme3.math.Transform; +import com.jme3.math.Vector3f; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.animations.Ipo; +import com.jme3.scene.plugins.blender.file.Structure; +import com.jme3.util.TempVars; + +public abstract class ConstraintDefinition { + protected int flag; + + public ConstraintDefinition(Structure constraintData, BlenderContext blenderContext) { + if(constraintData != null) {//Null constraint has no data + Number flag = (Number)constraintData.getFieldValue("flag"); + if(flag != null) { + this.flag = flag.intValue(); + } + } + } + + public void bake(Transform ownerTransform, Transform targetTransform, Track ownerTrack, Track targetTrack, Ipo influenceIpo) { + TrackWrapper ownerWrapperTrack = ownerTrack != null ? new TrackWrapper(ownerTrack) : null; + TrackWrapper targetWrapperTrack = targetTrack != null ? new TrackWrapper(targetTrack) : null; + + //uruchamiamy bake dla transformat zale¿nie od tego, które argumenty s¹ nullami, a które - nie + this.bake(ownerTransform, targetTransform, influenceIpo.calculateValue(0)); + if(ownerWrapperTrack != null) { + float[] ownerTimes = ownerWrapperTrack.getTimes(); + Vector3f[] translations = ownerWrapperTrack.getTranslations(); + Quaternion[] rotations = ownerWrapperTrack.getRotations(); + Vector3f[] scales = ownerWrapperTrack.getScales(); + + float[] targetTimes = targetWrapperTrack == null ? null : targetWrapperTrack.getTimes(); + Vector3f[] targetTranslations = targetWrapperTrack == null ? null : targetWrapperTrack.getTranslations(); + Quaternion[] targetRotations = targetWrapperTrack == null ? null : targetWrapperTrack.getRotations(); + Vector3f[] targetScales = targetWrapperTrack == null ? null : targetWrapperTrack.getScales(); + Vector3f translation = new Vector3f(), scale = new Vector3f(); + Quaternion rotation = new Quaternion(); + + Transform ownerTemp = new Transform(), targetTemp = new Transform(); + for (int i = 0; i = targetTimes.length - 1) { + result.set(targetVectors[targetTimes.length - 1]); + } else { + float delta = targetTimes[index + 1] - targetTimes[index]; + if(delta == 0.0f) { + result.set(targetVectors[index + 1]); + } else { + float scale = (currentTime - targetTimes[index])/(targetTimes[index + 1] - targetTimes[index]); + FastMath.interpolateLinear(scale, targetVectors[index], targetVectors[index + 1], result); + } + } + } + + private void interpolate(Quaternion[] targetQuaternions, float[] targetTimes, float currentTime, Quaternion result) { + int index = 0; + for (int i = 1; i < targetTimes.length; ++i) { + if(targetTimes[i] < currentTime) { + ++index; + } else { + break; + } + } + if(index >= targetTimes.length - 1) { + result.set(targetQuaternions[targetTimes.length - 1]); + } else { + float delta = targetTimes[index + 1] - targetTimes[index]; + if(delta == 0.0f) { + result.set(targetQuaternions[index + 1]); + } else { + float scale = (currentTime - targetTimes[index])/(targetTimes[index + 1] - targetTimes[index]); + result.slerp(targetQuaternions[index], targetQuaternions[index + 1], scale); + } + } + } + + /** + * This class holds either the bone track or spatial track. Is made to improve + * code readability. + * + * @author Marcin Roguski (Kaelthas) + */ + private static class TrackWrapper implements Track { + /** The spatial track. */ + private SpatialTrack spatialTrack; + /** The bone track. */ + private BoneTrack boneTrack; + + /** + * Constructs the object using the given track. The track must be of one of the types: + *
  • BoneTrack + *
  • SpatialTrack + * + * @param track + * the animation track + */ + public TrackWrapper(Track track) { + if(track instanceof SpatialTrack) { + this.spatialTrack = (SpatialTrack)track; + } else if(track instanceof BoneTrack) { + this.boneTrack = (BoneTrack)track; + } else { + throw new IllegalStateException("Unknown track type!"); + } + } + + /** + * @return the array of rotations of this track + */ + public Quaternion[] getRotations() { + if (boneTrack != null) { + return boneTrack.getRotations(); + } + return spatialTrack.getRotations(); + } + + /** + * @return the array of scales for this track + */ + public Vector3f[] getScales() { + if (boneTrack != null) { + return boneTrack.getScales(); + } + return spatialTrack.getScales(); + } + + /** + * @return the arrays of time for this track + */ + public float[] getTimes() { + if (boneTrack != null) { + return boneTrack.getTimes(); + } + return spatialTrack.getTimes(); + } + + /** + * @return the array of translations of this track + */ + public Vector3f[] getTranslations() { + if (boneTrack != null) { + return boneTrack.getTranslations(); + } + return spatialTrack.getTranslations(); + } + + /** + * Set the translations, rotations and scales for this bone track + * + * @param times + * a float array with the time of each frame + * @param translations + * the translation of the bone for each frame + * @param rotations + * the rotation of the bone for each frame + * @param scales + * the scale of the bone for each frame + */ + public void setKeyframes(float[] times, Vector3f[] translations, + Quaternion[] rotations, Vector3f[] scales) { + if (boneTrack != null) { + boneTrack.setKeyframes(times, translations, rotations, scales); + } else { + spatialTrack.setKeyframes(times, translations, rotations, scales); + } + } + + public void write(JmeExporter ex) throws IOException { } + + public void read(JmeImporter im) throws IOException { } + + public void setTime(float time, float weight, AnimControl control, + AnimChannel channel, TempVars vars) { + if (boneTrack != null) { + boneTrack.setTime(time, weight, control, channel, vars); + } else { + spatialTrack.setTime(time, weight, control, channel, vars); + } + } + + public float getLength() { + return spatialTrack == null ? boneTrack.getLength() : spatialTrack + .getLength(); + } + + @Override + public TrackWrapper clone() { + if (boneTrack != null) { + return new TrackWrapper(boneTrack.clone()); + } + return new TrackWrapper(spatialTrack.clone()); + } + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionAction.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionAction.java new file mode 100644 index 000000000..77935ee2f --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionAction.java @@ -0,0 +1,26 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Action' constraint type in blender. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionAction extends ConstraintDefinition { + private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionAction.class.getName()); + + public ConstraintDefinitionAction(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + // TODO: implement 'Action' constraint + LOGGER.log(Level.WARNING, "'Action' constraint NOT implemented!"); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionChildOf.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionChildOf.java new file mode 100644 index 000000000..8c1c2c300 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionChildOf.java @@ -0,0 +1,26 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'ChildOf' constraint type in blender. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionChildOf extends ConstraintDefinition { + private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionChildOf.class.getName()); + + public ConstraintDefinitionChildOf(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + // TODO: implement ChildOf constraint + LOGGER.log(Level.WARNING, "ChildOf constraint NOT implemented!"); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionClampTo.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionClampTo.java new file mode 100644 index 000000000..a0032036a --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionClampTo.java @@ -0,0 +1,26 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Clamp to' constraint type in blender. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionClampTo extends ConstraintDefinition { + private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionClampTo.class.getName()); + + public ConstraintDefinitionClampTo(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + //TODO: implement when curves are implemented + LOGGER.log(Level.INFO, "'Clamp to' not yet implemented!"); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionDampTrack.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionDampTrack.java new file mode 100644 index 000000000..dd9ee8c2c --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionDampTrack.java @@ -0,0 +1,26 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * The damp track constraint. Available for blender 2.50+. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionDampTrack extends ConstraintDefinition { + private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionDampTrack.class.getName()); + + public ConstraintDefinitionDampTrack(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + // TODO Auto-generated method stub + LOGGER.log(Level.WARNING, "'Damp Track' constraint NOT implemented!"); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionDistLimit.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionDistLimit.java new file mode 100644 index 000000000..fdaa7eeeb --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionDistLimit.java @@ -0,0 +1,59 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import com.jme3.math.Transform; +import com.jme3.math.Vector3f; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Dist limit' constraint type in blender. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionDistLimit extends ConstraintDefinition { + private static final int LIMITDIST_INSIDE = 0; + private static final int LIMITDIST_OUTSIDE = 1; + private static final int LIMITDIST_ONSURFACE = 2; + + protected int mode; + protected float dist; + + public ConstraintDefinitionDistLimit(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + mode = ((Number) constraintData.getFieldValue("mode")).intValue(); + dist = ((Number) constraintData.getFieldValue("dist")).floatValue(); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + Vector3f v = ownerTransform.getTranslation().subtract(targetTransform.getTranslation()); + float currentDistance = v.length(); + + switch (mode) { + case LIMITDIST_INSIDE: + if (currentDistance >= dist) { + v.normalizeLocal(); + v.multLocal(dist + (currentDistance - dist) * (1.0f - influence)); + ownerTransform.getTranslation().set(v.addLocal(targetTransform.getTranslation())); + } + break; + case LIMITDIST_ONSURFACE: + if (currentDistance > dist) { + v.normalizeLocal(); + v.multLocal(dist + (currentDistance - dist) * (1.0f - influence)); + ownerTransform.getTranslation().set(v.addLocal(targetTransform.getTranslation())); + } else if(currentDistance < dist) { + v.normalizeLocal().multLocal(dist * influence); + ownerTransform.getTranslation().set(targetTransform.getTranslation().add(v)); + } + break; + case LIMITDIST_OUTSIDE: + if (currentDistance <= dist) { + v = targetTransform.getTranslation().subtract(ownerTransform.getTranslation()).normalizeLocal().multLocal(dist * influence); + ownerTransform.getTranslation().set(targetTransform.getTranslation().add(v)); + } + break; + default: + throw new IllegalStateException("Unknown distance limit constraint mode: " + mode); + } + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionFactory.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionFactory.java new file mode 100644 index 000000000..c0c42a008 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionFactory.java @@ -0,0 +1,83 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; + +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; +import com.jme3.scene.plugins.blender.file.Structure; + +public class ConstraintDefinitionFactory { + private static final Map> CONSTRAINT_CLASSES = new HashMap>(); + static { + CONSTRAINT_CLASSES.put("bActionConstraint", ConstraintDefinitionAction.class); + CONSTRAINT_CLASSES.put("bChildOfConstraint", ConstraintDefinitionChildOf.class); + CONSTRAINT_CLASSES.put("bClampToConstraint", ConstraintDefinitionClampTo.class); + CONSTRAINT_CLASSES.put("bDistLimitConstraint", ConstraintDefinitionDistLimit.class); + CONSTRAINT_CLASSES.put("bFollowPathConstraint", ConstraintDefinitionFollowPath.class); + CONSTRAINT_CLASSES.put("bKinematicConstraint", ConstraintDefinitionInverseKinematics.class); + CONSTRAINT_CLASSES.put("bLockTrackConstraint", ConstraintDefinitionLockTrack.class); + CONSTRAINT_CLASSES.put("bLocateLikeConstraint", ConstraintDefinitionLocLike.class); + CONSTRAINT_CLASSES.put("bLocLimitConstraint", ConstraintDefinitionLocLimit.class); + CONSTRAINT_CLASSES.put("bMinMaxConstraint", ConstraintDefinitionMinMax.class); + CONSTRAINT_CLASSES.put("bNullConstraint", ConstraintDefinitionNull.class); + CONSTRAINT_CLASSES.put("bPythonConstraint", ConstraintDefinitionPython.class); + CONSTRAINT_CLASSES.put("bRigidBodyJointConstraint", ConstraintDefinitionRigidBodyJoint.class); + CONSTRAINT_CLASSES.put("bRotateLikeConstraint", ConstraintDefinitionRotLike.class); + CONSTRAINT_CLASSES.put("bShrinkWrapConstraint", ConstraintDefinitionShrinkWrap.class); + CONSTRAINT_CLASSES.put("bSizeLikeConstraint", ConstraintDefinitionSizeLike.class); + CONSTRAINT_CLASSES.put("bSizeLimitConstraint", ConstraintDefinitionSizeLimit.class); + CONSTRAINT_CLASSES.put("bStretchToConstraint", ConstraintDefinitionStretchTo.class); + CONSTRAINT_CLASSES.put("bTransformConstraint", ConstraintDefinitionTransform.class); + CONSTRAINT_CLASSES.put("bRotLimitConstraint", ConstraintDefinitionRotLimit.class); + //Blender 2.50+ + CONSTRAINT_CLASSES.put("bSplineIKConstraint", ConstraintDefinitionSplineInverseKinematic.class); + CONSTRAINT_CLASSES.put("bDampTrackConstraint", ConstraintDefinitionDampTrack.class); + CONSTRAINT_CLASSES.put("bPivotConstraint", ConstraintDefinitionDampTrack.class); + //Blender 2.56+ + CONSTRAINT_CLASSES.put("bTrackToConstraint", ConstraintDefinitionTrackTo.class); + CONSTRAINT_CLASSES.put("bSameVolumeConstraint", ConstraintDefinitionSameVolume.class); + CONSTRAINT_CLASSES.put("bTransLikeConstraint", ConstraintDefinitionTransLike.class); + } + + /** + * This method creates the constraint instance. + * + * @param constraintStructure + * the constraint's structure (bConstraint clss in blender 2.49). If the value is null the NullConstraint is created. + * @param ownerOMA + * the old memory address of the constraint's owner + * @param influenceIpo + * the ipo curve of the influence factor + * @param blenderContext + * the blender context + * @throws BlenderFileException + * this exception is thrown when the blender file is somehow + * corrupted + */ + public static ConstraintDefinition createConstraintDefinition(Structure constraintStructure, BlenderContext blenderContext) throws BlenderFileException { + if(constraintStructure == null) { + return new ConstraintDefinitionNull(null, blenderContext); + } + String constraintClassName = constraintStructure.getType(); + Class constraintDefinitionClass = CONSTRAINT_CLASSES.get(constraintClassName); + if(constraintDefinitionClass != null) { + try { + return (ConstraintDefinition) constraintDefinitionClass.getDeclaredConstructors()[0].newInstance(constraintStructure, blenderContext); + } catch (IllegalArgumentException e) { + throw new BlenderFileException(e.getLocalizedMessage(), e); + } catch (SecurityException e) { + throw new BlenderFileException(e.getLocalizedMessage(), e); + } catch (InstantiationException e) { + throw new BlenderFileException(e.getLocalizedMessage(), e); + } catch (IllegalAccessException e) { + throw new BlenderFileException(e.getLocalizedMessage(), e); + } catch (InvocationTargetException e) { + throw new BlenderFileException(e.getLocalizedMessage(), e); + } + } else { + throw new BlenderFileException("Unknown constraint type: " + constraintClassName); + } + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionFollowPath.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionFollowPath.java new file mode 100644 index 000000000..51cdb4ee4 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionFollowPath.java @@ -0,0 +1,26 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Follow path' constraint type in blender. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionFollowPath extends ConstraintDefinition { + private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionFollowPath.class.getName()); + + public ConstraintDefinitionFollowPath(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + //TODO: implement when curves are implemented + LOGGER.log(Level.INFO, "'Follow path' not implemented! Curves not yet implemented!"); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintInverseKinematics.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionInverseKinematics.java similarity index 80% rename from engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintInverseKinematics.java rename to engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionInverseKinematics.java index ef8544690..e8d035290 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintInverseKinematics.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionInverseKinematics.java @@ -1,44 +1,26 @@ -package com.jme3.scene.plugins.blender.constraints; +package com.jme3.scene.plugins.blender.constraints.definitions; import com.jme3.animation.Animation; import com.jme3.animation.Skeleton; +import com.jme3.math.Transform; import com.jme3.scene.plugins.blender.BlenderContext; import com.jme3.scene.plugins.blender.animations.CalculationBone; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; import com.jme3.scene.plugins.blender.file.Structure; -import java.util.logging.Logger; /** * This class represents 'Inverse kinematics' constraint type in blender. * @author Marcin Roguski (Kaelthas) */ -/*package*/ class ConstraintInverseKinematics extends Constraint { - private static final Logger LOGGER = Logger.getLogger(ConstraintInverseKinematics.class.getName()); - private static final float IK_SOLVER_ERROR = 0.5f; +/*package*/ class ConstraintDefinitionInverseKinematics extends ConstraintDefinition { + //private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionInverseKinematics.class.getName()); + //private static final float IK_SOLVER_ERROR = 0.5f; - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintInverseKinematics(Structure constraintStructure, - Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); + public ConstraintDefinitionInverseKinematics(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); } @Override - protected void bakeConstraint() { + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { // try { // IK solver is only attached to bones // Bone ownerBone = (Bone) blenderContext.getLoadedFeature(ownerOMA, LoadedFeatureDataType.LOADED_FEATURE); diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionLocLike.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionLocLike.java new file mode 100644 index 000000000..129da2a65 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionLocLike.java @@ -0,0 +1,74 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import com.jme3.math.Transform; +import com.jme3.math.Vector3f; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Loc like' constraint type in blender. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionLocLike extends ConstraintDefinition { + private static final int LOCLIKE_X = 0x01; + private static final int LOCLIKE_Y = 0x02; + private static final int LOCLIKE_Z = 0x04; + //protected static final int LOCLIKE_TIP = 0x08;//this is deprecated in blender + private static final int LOCLIKE_X_INVERT = 0x10; + private static final int LOCLIKE_Y_INVERT = 0x20; + private static final int LOCLIKE_Z_INVERT = 0x40; + private static final int LOCLIKE_OFFSET = 0x80; + + public ConstraintDefinitionLocLike(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + if(blenderContext.getBlenderKey().isFixUpAxis()) { + //swapping Y and X limits flag in the bitwise flag + int y = flag & LOCLIKE_Y; + int invY = flag & LOCLIKE_Y_INVERT; + int z = flag & LOCLIKE_Z; + int invZ = flag & LOCLIKE_Z_INVERT; + flag &= LOCLIKE_X | LOCLIKE_X_INVERT | LOCLIKE_OFFSET;//clear the other flags to swap them + flag |= y << 1; + flag |= invY << 1; + flag |= z >> 1; + flag |= invZ >> 1; + } + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + Vector3f ownerLocation = ownerTransform.getTranslation(); + Vector3f targetLocation = targetTransform.getTranslation(); + + Vector3f startLocation = ownerTransform.getTranslation().clone(); + Vector3f offset = Vector3f.ZERO; + if ((flag & LOCLIKE_OFFSET) != 0) {//we add the original location to the copied location + offset = startLocation; + } + + if ((flag & LOCLIKE_X) != 0) { + ownerLocation.x = targetLocation.x; + if ((flag & LOCLIKE_X_INVERT) != 0) { + ownerLocation.x = -ownerLocation.x; + } + } + if ((flag & LOCLIKE_Y) != 0) { + ownerLocation.y = targetLocation.y; + if ((flag & LOCLIKE_Y_INVERT) != 0) { + ownerLocation.y = -ownerLocation.y; + } + } + if ((flag & LOCLIKE_Z) != 0) { + ownerLocation.z = targetLocation.z; + if ((flag & LOCLIKE_Z_INVERT) != 0) { + ownerLocation.z = -ownerLocation.z; + } + } + ownerLocation.addLocal(offset); + + if(influence < 1.0f) { + startLocation.subtractLocal(ownerLocation).normalizeLocal().mult(influence); + ownerLocation.addLocal(startLocation); + } + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionLocLimit.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionLocLimit.java new file mode 100644 index 000000000..1fce62de2 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionLocLimit.java @@ -0,0 +1,87 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import com.jme3.math.Transform; +import com.jme3.math.Vector3f; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Loc limit' constraint type in blender. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionLocLimit extends ConstraintDefinition { + private static final int LIMIT_XMIN = 0x01; + private static final int LIMIT_XMAX = 0x02; + private static final int LIMIT_YMIN = 0x04; + private static final int LIMIT_YMAX = 0x08; + private static final int LIMIT_ZMIN = 0x10; + private static final int LIMIT_ZMAX = 0x20; + + protected float[][] limits = new float[3][2]; + + public ConstraintDefinitionLocLimit(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + if(blenderContext.getBlenderKey().isFixUpAxis()) { + limits[0][0] = ((Number) constraintData.getFieldValue("xmin")).floatValue(); + limits[0][1] = ((Number) constraintData.getFieldValue("xmax")).floatValue(); + limits[2][0] = -((Number) constraintData.getFieldValue("ymin")).floatValue(); + limits[2][1] = -((Number) constraintData.getFieldValue("ymax")).floatValue(); + limits[1][0] = ((Number) constraintData.getFieldValue("zmin")).floatValue(); + limits[1][1] = ((Number) constraintData.getFieldValue("zmax")).floatValue(); + + //swapping Y and X limits flag in the bitwise flag + int ymin = flag & LIMIT_YMIN; + int ymax = flag & LIMIT_YMAX; + int zmin = flag & LIMIT_ZMIN; + int zmax = flag & LIMIT_ZMAX; + flag &= LIMIT_XMIN | LIMIT_XMAX;//clear the other flags to swap them + flag |= ymin << 2; + flag |= ymax << 2; + flag |= zmin >> 2; + flag |= zmax >> 2; + } else { + limits[0][0] = ((Number) constraintData.getFieldValue("xmin")).floatValue(); + limits[0][1] = ((Number) constraintData.getFieldValue("xmax")).floatValue(); + limits[1][0] = ((Number) constraintData.getFieldValue("ymin")).floatValue(); + limits[1][1] = ((Number) constraintData.getFieldValue("ymax")).floatValue(); + limits[2][0] = ((Number) constraintData.getFieldValue("zmin")).floatValue(); + limits[2][1] = ((Number) constraintData.getFieldValue("zmax")).floatValue(); + } + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + Vector3f translation = ownerTransform.getTranslation(); + + if ((flag & LIMIT_XMIN) != 0) { + if (translation.x < limits[0][0]) { + translation.x -= (translation.x - limits[0][0]) * influence; + } + } + if ((flag & LIMIT_XMAX) != 0) { + if (translation.x > limits[0][1]) { + translation.x -= (translation.x - limits[0][1]) * influence; + } + } + if ((flag & LIMIT_YMIN) != 0) { + if (translation.y < limits[1][0]) { + translation.y -= (translation.y - limits[1][0]) * influence; + } + } + if ((flag & LIMIT_YMAX) != 0) { + if (translation.y > limits[1][1]) { + translation.y -= (translation.y - limits[1][1]) * influence; + } + } + if ((flag & LIMIT_ZMIN) != 0) { + if (translation.z < limits[2][0]) { + translation.z -= (translation.z - limits[2][0]) * influence; + } + } + if ((flag & LIMIT_ZMAX) != 0) { + if (translation.z > limits[2][1]) { + translation.z -= (translation.z - limits[2][1]) * influence; + } + } + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionLockTrack.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionLockTrack.java new file mode 100644 index 000000000..9e6746c46 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionLockTrack.java @@ -0,0 +1,26 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Action' constraint type in blender. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionLockTrack extends ConstraintDefinition { + private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionLockTrack.class.getName()); + + public ConstraintDefinitionLockTrack(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + // TODO: implement 'Lock track' constraint + LOGGER.log(Level.WARNING, "'Lock track' constraint NOT implemented!"); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionMinMax.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionMinMax.java new file mode 100644 index 000000000..b47b2d509 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionMinMax.java @@ -0,0 +1,26 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Min max' constraint type in blender. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionMinMax extends ConstraintDefinition { + private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionMinMax.class.getName()); + + public ConstraintDefinitionMinMax(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + // TODO: implement 'Min max' constraint + LOGGER.log(Level.WARNING, "'Min max' constraint NOT implemented!"); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionNull.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionNull.java new file mode 100644 index 000000000..a1a5d507e --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionNull.java @@ -0,0 +1,19 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Null' constraint type in blender. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionNull extends ConstraintDefinition { + + public ConstraintDefinitionNull(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionPivot.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionPivot.java new file mode 100644 index 000000000..462d6681b --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionPivot.java @@ -0,0 +1,26 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * The pivot constraint. Available for blender 2.50+. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionPivot extends ConstraintDefinition { + private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionPivot.class.getName()); + + public ConstraintDefinitionPivot(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + // TODO: implement 'Pivot' constraint + LOGGER.log(Level.WARNING, "'Pivot' constraint NOT implemented!"); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionPython.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionPython.java new file mode 100644 index 000000000..8ec9d652c --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionPython.java @@ -0,0 +1,26 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Python' constraint type in blender. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionPython extends ConstraintDefinition { + private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionPython.class.getName()); + + public ConstraintDefinitionPython(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + // TODO: implement 'Python' constraint + LOGGER.log(Level.WARNING, "'Python' constraint NOT implemented!"); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionRigidBodyJoint.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionRigidBodyJoint.java new file mode 100644 index 000000000..47dfa81a6 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionRigidBodyJoint.java @@ -0,0 +1,26 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Rigid body joint' constraint type in blender. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionRigidBodyJoint extends ConstraintDefinition { + private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionRigidBodyJoint.class.getName()); + + public ConstraintDefinitionRigidBodyJoint(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + // TODO: implement 'Rigid body joint' constraint + LOGGER.log(Level.WARNING, "'Rigid body joint' constraint NOT implemented!"); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionRotLike.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionRotLike.java new file mode 100644 index 000000000..d3aa0f6b7 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionRotLike.java @@ -0,0 +1,67 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import com.jme3.math.Quaternion; +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Rot like' constraint type in blender. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionRotLike extends ConstraintDefinition { + private static final int ROTLIKE_X = 0x01; + private static final int ROTLIKE_Y = 0x02; + private static final int ROTLIKE_Z = 0x04; + private static final int ROTLIKE_X_INVERT = 0x10; + private static final int ROTLIKE_Y_INVERT = 0x20; + private static final int ROTLIKE_Z_INVERT = 0x40; + private static final int ROTLIKE_OFFSET = 0x80; + + private transient float[] ownerAngles = new float[3]; + private transient float[] targetAngles = new float[3]; + + public ConstraintDefinitionRotLike(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + Quaternion ownerRotation = ownerTransform.getRotation(); + ownerAngles = ownerRotation.toAngles(ownerAngles); + targetAngles = targetTransform.getRotation().toAngles(targetAngles); + + Quaternion startRotation = ownerRotation.clone(); + Quaternion offset = Quaternion.IDENTITY; + if ((flag & ROTLIKE_OFFSET) != 0) {//we add the original rotation to the copied rotation + offset = startRotation; + } + + if ((flag & ROTLIKE_X) != 0) { + ownerAngles[0] = targetAngles[0]; + if ((flag & ROTLIKE_X_INVERT) != 0) { + ownerAngles[0] = -ownerAngles[0]; + } + } + if ((flag & ROTLIKE_Y) != 0) { + ownerAngles[1] = targetAngles[1]; + if ((flag & ROTLIKE_Y_INVERT) != 0) { + ownerAngles[1] = -ownerAngles[1]; + } + } + if ((flag & ROTLIKE_Z) != 0) { + ownerAngles[2] = targetAngles[2]; + if ((flag & ROTLIKE_Z_INVERT) != 0) { + ownerAngles[2] = -ownerAngles[2]; + } + } + ownerRotation.fromAngles(ownerAngles).multLocal(offset); + + if(influence < 1.0f) { + +// startLocation.subtractLocal(ownerLocation).normalizeLocal().mult(influence); +// ownerLocation.addLocal(startLocation); + //TODO + } + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionRotLimit.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionRotLimit.java new file mode 100644 index 000000000..1d5af33bb --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionRotLimit.java @@ -0,0 +1,85 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import com.jme3.math.FastMath; +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Rot limit' constraint type in blender. + * + * @author Marcin Roguski (Kaelthas) + */ +/* package */class ConstraintDefinitionRotLimit extends ConstraintDefinition { + private static final int LIMIT_XROT = 0x01; + private static final int LIMIT_YROT = 0x02; + private static final int LIMIT_ZROT = 0x04; + + private float[][] limits = new float[3][2]; + private transient float[] angles = new float[3]; + + public ConstraintDefinitionRotLimit(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + if (blenderContext.getBlenderKey().isFixUpAxis()/* && owner.spatial != null*/) {//FIXME: !!!!!!!! + limits[0][0] = ((Number) constraintData.getFieldValue("xmin")).floatValue(); + limits[0][1] = ((Number) constraintData.getFieldValue("xmax")).floatValue(); + limits[2][0] = -((Number) constraintData.getFieldValue("ymin")).floatValue(); + limits[2][1] = -((Number) constraintData.getFieldValue("ymax")).floatValue(); + limits[1][0] = ((Number) constraintData.getFieldValue("zmin")).floatValue(); + limits[1][1] = ((Number) constraintData.getFieldValue("zmax")).floatValue(); + + // swapping Y and X limits flag in the bitwise flag + int limitY = flag & LIMIT_YROT; + int limitZ = flag & LIMIT_ZROT; + flag &= LIMIT_XROT;// clear the other flags to swap them + flag |= limitY << 1; + flag |= limitZ >> 1; + } else { + limits[0][0] = ((Number) constraintData.getFieldValue("xmin")).floatValue(); + limits[0][1] = ((Number) constraintData.getFieldValue("xmax")).floatValue(); + limits[1][0] = ((Number) constraintData.getFieldValue("ymin")).floatValue(); + limits[1][1] = ((Number) constraintData.getFieldValue("ymax")).floatValue(); + limits[2][0] = ((Number) constraintData.getFieldValue("zmin")).floatValue(); + limits[2][1] = ((Number) constraintData.getFieldValue("zmax")).floatValue(); + } + + // until blender 2.49 the rotations values were stored in degrees + if (blenderContext.getBlenderVersion() <= 249) { + for (int i = 0; i < limits.length; ++i) { + limits[i][0] *= FastMath.DEG_TO_RAD; + limits[i][1] *= FastMath.DEG_TO_RAD; + } + } + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + if ((flag & LIMIT_XROT) != 0) { + float difference = 0.0f; + if (angles[0] < limits[0][0]) { + difference = (angles[0] - limits[0][0]) * influence; + } else if (angles[0] > limits[0][1]) { + difference = (angles[0] - limits[0][1]) * influence; + } + angles[0] -= difference; + } + if ((flag & LIMIT_YROT) != 0) { + float difference = 0.0f; + if (angles[1] < limits[1][0]) { + difference = (angles[1] - limits[1][0]) * influence; + } else if (angles[1] > limits[1][1]) { + difference = (angles[1] - limits[1][1]) * influence; + } + angles[1] -= difference; + } + if ((flag & LIMIT_ZROT) != 0) { + float difference = 0.0f; + if (angles[2] < limits[2][0]) { + difference = (angles[2] - limits[2][0]) * influence; + } else if (angles[2] > limits[2][1]) { + difference = (angles[2] - limits[2][1]) * influence; + } + angles[2] -= difference; + } + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSameVolume.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSameVolume.java new file mode 100644 index 000000000..7812e3e2f --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSameVolume.java @@ -0,0 +1,27 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Same volume' constraint type in blender. + * + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionSameVolume extends ConstraintDefinition { + private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionSameVolume.class.getName()); + + public ConstraintDefinitionSameVolume(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + // TODO: implement 'Same volume' constraint + LOGGER.log(Level.WARNING, "'Same volume' constraint NOT implemented!"); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintShrinkWrap.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionShrinkWrap.java similarity index 52% rename from engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintShrinkWrap.java rename to engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionShrinkWrap.java index e911dbaa8..d1e4c5f52 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintShrinkWrap.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionShrinkWrap.java @@ -1,52 +1,23 @@ -package com.jme3.scene.plugins.blender.constraints; +package com.jme3.scene.plugins.blender.constraints.definitions; -import com.jme3.animation.Animation; -import com.jme3.math.Quaternion; -import com.jme3.math.Vector3f; -import com.jme3.scene.Geometry; -import com.jme3.scene.Mesh; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.VertexBuffer.Type; +import com.jme3.math.Transform; import com.jme3.scene.plugins.blender.BlenderContext; -import com.jme3.scene.plugins.blender.animations.Ipo; -import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; import com.jme3.scene.plugins.blender.file.Structure; -import com.jme3.scene.plugins.ogre.AnimData; -import java.nio.FloatBuffer; -import java.util.ArrayList; -import java.util.List; /** * This class represents 'Shrink wrap' constraint type in blender. * @author Marcin Roguski (Kaelthas) */ -/*package*/ class ConstraintShrinkWrap extends Constraint { +/*package*/ class ConstraintDefinitionShrinkWrap extends ConstraintDefinition { - /** - * This constructor creates the constraint instance. - * - * @param constraintStructure - * the constraint's structure (bConstraint clss in blender 2.49). - * @param ownerOMA - * the old memory address of the constraint owner - * @param influenceIpo - * the ipo curve of the influence factor - * @param blenderContext - * the blender context - * @throws BlenderFileException - * this exception is thrown when the blender file is somehow - * corrupted - */ - public ConstraintShrinkWrap(Structure constraintStructure, Long ownerOMA, - Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { - super(constraintStructure, ownerOMA, influenceIpo, blenderContext); + public ConstraintDefinitionShrinkWrap(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); } @Override - protected void bakeConstraint() { + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { //loading mesh points (blender ensures that the target is a mesh-object) - List pts = new ArrayList(); + /*List pts = new ArrayList(); Node target = (Node) this.target.getObject(); for(Spatial spatial : target.getChildren()) { if(spatial instanceof Geometry) { @@ -84,7 +55,7 @@ import java.util.List; track.setKeyframes(track.getTimes(), translations, rotations, track.getScales()); } - } + }*/ //TODO: static constraint for spatials } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSizeLike.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSizeLike.java new file mode 100644 index 000000000..e798887d2 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSizeLike.java @@ -0,0 +1,51 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import com.jme3.math.Transform; +import com.jme3.math.Vector3f; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Size like' constraint type in blender. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionSizeLike extends ConstraintDefinition { + private static final int SIZELIKE_X = 0x01; + private static final int SIZELIKE_Y = 0x02; + private static final int SIZELIKE_Z = 0x04; + private static final int LOCLIKE_OFFSET = 0x80; + + public ConstraintDefinitionSizeLike(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + if(blenderContext.getBlenderKey().isFixUpAxis()) { + //swapping Y and X limits flag in the bitwise flag + int y = flag & SIZELIKE_Y; + int z = flag & SIZELIKE_Z; + flag &= SIZELIKE_X | LOCLIKE_OFFSET;//clear the other flags to swap them + flag |= y << 1; + flag |= z >> 1; + } + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + Vector3f ownerScale = ownerTransform.getScale(); + Vector3f targetScale = targetTransform.getScale(); + + Vector3f offset = Vector3f.ZERO; + if ((flag & LOCLIKE_OFFSET) != 0) {//we add the original scale to the copied scale + offset = ownerScale.clone(); + } + + if ((flag & SIZELIKE_X) != 0) { + ownerScale.x = targetScale.x * influence + (1.0f - influence) * ownerScale.x; + } + if ((flag & SIZELIKE_Y) != 0) { + ownerScale.y = targetScale.y * influence + (1.0f - influence) * ownerScale.y; + } + if ((flag & SIZELIKE_Z) != 0) { + ownerScale.z = targetScale.z * influence + (1.0f - influence) * ownerScale.z; + } + ownerScale.addLocal(offset); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSizeLimit.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSizeLimit.java new file mode 100644 index 000000000..32803fe5d --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSizeLimit.java @@ -0,0 +1,75 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import com.jme3.math.Transform; +import com.jme3.math.Vector3f; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Size limit' constraint type in blender. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionSizeLimit extends ConstraintDefinition { + private static final int LIMIT_XMIN = 0x01; + private static final int LIMIT_XMAX = 0x02; + private static final int LIMIT_YMIN = 0x04; + private static final int LIMIT_YMAX = 0x08; + private static final int LIMIT_ZMIN = 0x10; + private static final int LIMIT_ZMAX = 0x20; + + protected float[][] limits = new float[3][2]; + + public ConstraintDefinitionSizeLimit(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + if(blenderContext.getBlenderKey().isFixUpAxis()) { + limits[0][0] = ((Number) constraintData.getFieldValue("xmin")).floatValue(); + limits[0][1] = ((Number) constraintData.getFieldValue("xmax")).floatValue(); + limits[2][0] = -((Number) constraintData.getFieldValue("ymin")).floatValue(); + limits[2][1] = -((Number) constraintData.getFieldValue("ymax")).floatValue(); + limits[1][0] = ((Number) constraintData.getFieldValue("zmin")).floatValue(); + limits[1][1] = ((Number) constraintData.getFieldValue("zmax")).floatValue(); + + //swapping Y and X limits flag in the bitwise flag + int ymin = flag & LIMIT_YMIN; + int ymax = flag & LIMIT_YMAX; + int zmin = flag & LIMIT_ZMIN; + int zmax = flag & LIMIT_ZMAX; + flag &= LIMIT_XMIN | LIMIT_XMAX;//clear the other flags to swap them + flag |= ymin << 2; + flag |= ymax << 2; + flag |= zmin >> 2; + flag |= zmax >> 2; + } else { + limits[0][0] = ((Number) constraintData.getFieldValue("xmin")).floatValue(); + limits[0][1] = ((Number) constraintData.getFieldValue("xmax")).floatValue(); + limits[1][0] = ((Number) constraintData.getFieldValue("ymin")).floatValue(); + limits[1][1] = ((Number) constraintData.getFieldValue("ymax")).floatValue(); + limits[2][0] = ((Number) constraintData.getFieldValue("zmin")).floatValue(); + limits[2][1] = ((Number) constraintData.getFieldValue("zmax")).floatValue(); + } + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + Vector3f scale = ownerTransform.getScale(); + + if ((flag & LIMIT_XMIN) != 0 && scale.x < limits[0][0]) { + scale.x -= (scale.x - limits[0][0]) * influence; + } + if ((flag & LIMIT_XMAX) != 0 && scale.x > limits[0][1]) { + scale.x -= (scale.x - limits[0][1]) * influence; + } + if ((flag & LIMIT_YMIN) != 0 && scale.y < limits[1][0]) { + scale.y -= (scale.y - limits[1][0]) * influence; + } + if ((flag & LIMIT_YMAX) != 0 && scale.y > limits[1][1]) { + scale.y -= (scale.y - limits[1][1]) * influence; + } + if ((flag & LIMIT_ZMIN) != 0 && scale.z < limits[2][0]) { + scale.z -= (scale.z - limits[2][0]) * influence; + } + if ((flag & LIMIT_ZMAX) != 0 && scale.z > limits[2][1]) { + scale.z -= (scale.z - limits[2][1]) * influence; + } + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSplineInverseKinematic.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSplineInverseKinematic.java new file mode 100644 index 000000000..424fd0f52 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionSplineInverseKinematic.java @@ -0,0 +1,26 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * The spline inverse kinematic constraint. Available for blender 2.50+. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionSplineInverseKinematic extends ConstraintDefinition { + private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionSplineInverseKinematic.class.getName()); + + public ConstraintDefinitionSplineInverseKinematic(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + // TODO Auto-generated method stub + LOGGER.log(Level.WARNING, "'Splie IK' constraint NOT implemented!"); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionStretchTo.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionStretchTo.java new file mode 100644 index 000000000..47fac26fb --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionStretchTo.java @@ -0,0 +1,26 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Stretch to' constraint type in blender. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionStretchTo extends ConstraintDefinition { + private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionStretchTo.class.getName()); + + public ConstraintDefinitionStretchTo(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + // TODO: implement 'Stretch to' constraint + LOGGER.log(Level.WARNING, "'Stretch to' constraint NOT implemented!"); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionTrackTo.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionTrackTo.java new file mode 100644 index 000000000..4a5dc2620 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionTrackTo.java @@ -0,0 +1,27 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Track to' constraint type in blender. + * + * @author Marcin Roguski (Kaelthas) + */ +/* package */class ConstraintDefinitionTrackTo extends ConstraintDefinition { + private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionTrackTo.class.getName()); + + public ConstraintDefinitionTrackTo(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + // TODO: implement 'Track to' constraint + LOGGER.log(Level.WARNING, "'Track to' constraint NOT implemented!"); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionTransLike.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionTransLike.java new file mode 100644 index 000000000..01d9a5c01 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionTransLike.java @@ -0,0 +1,27 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Trans like' constraint type in blender. + * + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionTransLike extends ConstraintDefinition { + private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionTransLike.class.getName()); + + public ConstraintDefinitionTransLike(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + // TODO: implement 'Trans like' constraint + LOGGER.log(Level.WARNING, "'Trans like' constraint NOT implemented!"); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionTransform.java b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionTransform.java new file mode 100644 index 000000000..bc27fc5b9 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/constraints/definitions/ConstraintDefinitionTransform.java @@ -0,0 +1,26 @@ +package com.jme3.scene.plugins.blender.constraints.definitions; + +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.math.Transform; +import com.jme3.scene.plugins.blender.BlenderContext; +import com.jme3.scene.plugins.blender.file.Structure; + +/** + * This class represents 'Transform' constraint type in blender. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ class ConstraintDefinitionTransform extends ConstraintDefinition { + private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionAction.class.getName()); + + public ConstraintDefinitionTransform(Structure constraintData, BlenderContext blenderContext) { + super(constraintData, blenderContext); + } + + @Override + public void bake(Transform ownerTransform, Transform targetTransform, float influence) { + // TODO: implement 'Transform' constraint + LOGGER.log(Level.WARNING, "'Transform' constraint NOT implemented!"); + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArmatureModifier.java b/engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArmatureModifier.java index d361e9055..722da115f 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArmatureModifier.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArmatureModifier.java @@ -26,7 +26,6 @@ import com.jme3.scene.VertexBuffer.Usage; import com.jme3.scene.plugins.blender.BlenderContext; import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType; import com.jme3.scene.plugins.blender.animations.ArmatureHelper; -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; @@ -224,18 +223,6 @@ import com.jme3.util.BufferUtils; } } - // applying constraints to Bones - ArmatureHelper armatureHelper = blenderContext.getHelper(ArmatureHelper.class); - for (int i = 0; i < animData.skeleton.getBoneCount(); ++i) { - Long boneOMA = armatureHelper.getBoneOMA(animData.skeleton.getBone(i)); - List constraints = blenderContext.getConstraints(boneOMA); - if (constraints != null && constraints.size() > 0) { - for (Constraint constraint : constraints) { - constraint.bake(); - } - } - } - // applying animations AnimControl control = new AnimControl(animData.skeleton); ArrayList animList = animData.anims; diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java index db3c30ce2..c0058ebf0 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java @@ -51,7 +51,6 @@ import com.jme3.scene.plugins.blender.AbstractBlenderHelper; import com.jme3.scene.plugins.blender.BlenderContext; import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType; import com.jme3.scene.plugins.blender.cameras.CameraHelper; -import com.jme3.scene.plugins.blender.constraints.Constraint; import com.jme3.scene.plugins.blender.constraints.ConstraintHelper; import com.jme3.scene.plugins.blender.curves.CurvesHelper; import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; @@ -238,14 +237,6 @@ public class ObjectHelper extends AbstractBlenderHelper { ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class); constraintHelper.loadConstraints(objectStructure, blenderContext); - //baking constraints - List objectConstraints = blenderContext.getConstraints(objectStructure.getOldMemoryAddress()); - if(objectConstraints!=null) { - for(Constraint objectConstraint : objectConstraints) { - objectConstraint.bake(); - } - } - //reading custom properties if(blenderContext.getBlenderKey().isLoadObjectProperties()) { Properties properties = this.loadProperties(objectStructure, blenderContext);