Huge constraints refactoring (the computations might yet not be perfect, but models loading should get much less crashes).
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9720 75d07b2b-3a1a-0410-a2c5-0572b91ccdca3.0
parent
58bbd2d076
commit
711b8ab9ca
@ -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()); |
||||
} |
||||
} |
@ -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;i<bonesOMAs.length;++i) { |
||||
Long oma = bonesOMAs[i]; |
||||
if(this.hasAnimation(oma)) { |
||||
Bone currentBone = blenderContext.getBoneContext(oma).getBone(); |
||||
Bone parent = currentBone.getParent(); |
||||
boolean foundAnimation = false; |
||||
AnimData animData = null; |
||||
while(parent != null && !foundAnimation) { |
||||
BoneContext boneContext = blenderContext.getBoneByName(parent.getName()); |
||||
foundAnimation = this.hasAnimation(boneContext.getBoneOma()); |
||||
animData = blenderContext.getAnimData(boneContext.getBoneOma()); |
||||
parent = parent.getParent(); |
||||
} |
||||
|
||||
if(foundAnimation) { |
||||
this.applyAnimData(blenderContext.getBoneContext(oma), spaces[i], animData); |
||||
} |
||||
} |
||||
} |
||||
|
||||
//creating animation for owner if it doesn't have one already and if the target has it
|
||||
if(!this.hasAnimation(ownerOMA) && this.hasAnimation(targetOMA)) { |
||||
AnimData targetAnimData = blenderContext.getAnimData(targetOMA); |
||||
this.applyAnimData(blenderContext.getBoneContext(ownerOMA), ownerSpace, targetAnimData); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* The method determines if the bone has animations. |
||||
* |
||||
* @param boneOMA |
||||
* OMA of the bone |
||||
* @return <b>true</b> if the bone has animations and <b>false</b> 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); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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() {} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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
|
||||
} |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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<Number> locArray = ((DynamicArray<Number>) targetStructure.getFieldValue("loc")); |
||||
Vector3f loc = new Vector3f(locArray.get(0).floatValue(), locArray.get(1).floatValue(), locArray.get(2).floatValue()); |
||||
DynamicArray<Number> rotArray = ((DynamicArray<Number>) targetStructure.getFieldValue("rot")); |
||||
Quaternion rot = new Quaternion(new float[] { rotArray.get(0).floatValue(), rotArray.get(1).floatValue(), rotArray.get(2).floatValue() }); |
||||
DynamicArray<Number> sizeArray = ((DynamicArray<Number>) 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; |
||||
} |
||||
} |
@ -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() { } |
||||
} |
@ -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<String, Animation> anims = new HashMap<String, Animation>(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<Animation>(anims.values()))); |
||||
} |
||||
} |
@ -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 <ownerTimes.length; ++i) { |
||||
float t = ownerTimes[i]; |
||||
ownerTemp.setTranslation(translations[i]); |
||||
ownerTemp.setRotation(rotations[i]); |
||||
ownerTemp.setScale(scales[i]); |
||||
if(targetWrapperTrack == null) { |
||||
this.bake(ownerTemp, targetTransform, influenceIpo.calculateValue(i)); |
||||
} else { |
||||
//getting the values that are the interpolation of the target track for the time 't'
|
||||
this.interpolate(targetTranslations, targetTimes, t, translation); |
||||
this.interpolate(targetRotations, targetTimes, t, rotation); |
||||
this.interpolate(targetScales, targetTimes, t, scale); |
||||
|
||||
targetTemp.setTranslation(translation); |
||||
targetTemp.setRotation(rotation); |
||||
targetTemp.setScale(scale); |
||||
|
||||
this.bake(ownerTemp, targetTemp, influenceIpo.calculateValue(i)); |
||||
} |
||||
//need to clone here because each of the arrays will reference the same instance if they hold the same value in the compact array
|
||||
translations[i] = ownerTemp.getTranslation().clone(); |
||||
rotations[i] = ownerTemp.getRotation().clone(); |
||||
scales[i] = ownerTemp.getScale().clone(); |
||||
} |
||||
ownerWrapperTrack.setKeyframes(ownerTimes, translations, rotations, scales); |
||||
} |
||||
} |
||||
|
||||
protected abstract void bake(Transform ownerTransform, Transform targetTransform, float influence); |
||||
|
||||
private void interpolate(Vector3f[] targetVectors, float[] targetTimes, float currentTime, Vector3f 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(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: |
||||
* <li> BoneTrack |
||||
* <li> 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()); |
||||
} |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
||||
} |
@ -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<String, Class<? extends ConstraintDefinition>> CONSTRAINT_CLASSES = new HashMap<String, Class<? extends ConstraintDefinition>>(); |
||||
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<? extends ConstraintDefinition> 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); |
||||
} |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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);
|
@ -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); |
||||
} |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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) { } |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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
|
||||
} |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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); |
||||
} |
||||
} |
@ -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; |
||||
} |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
@ -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!"); |
||||
} |
||||
} |
Loading…
Reference in new issue