@ -24,18 +24,19 @@ import com.jme3.scene.plugins.blender.structures.Ipo;
import com.jme3.scene.plugins.blender.utils.AbstractBlenderHelper ;
import com.jme3.scene.plugins.blender.utils.DataRepository ;
import com.jme3.scene.plugins.blender.utils.Pointer ;
import java.util.logging.Level ;
/ * *
* This class should be used for constraint calculations .
* @author Marcin Roguski
* /
public class ConstraintHelper extends AbstractBlenderHelper {
/ * *
* A table containing implementations of influence functions for constraints . It should contain functions for
* blender at least 249 and higher .
* /
protected static AbstractInfluenceFunction [ ] influenceFunctions ;
/ * *
* Constraints stored for object with the given old memory address .
* /
@ -51,47 +52,51 @@ public class ConstraintHelper extends AbstractBlenderHelper {
* /
public ConstraintHelper ( String blenderVersion , DataRepository dataRepository ) {
super ( blenderVersion ) ;
if ( influenceFunctions = = null ) {
if ( influenceFunctions = = null ) {
//TODO: synchronization
influenceFunctions = new AbstractInfluenceFunction [ ConstraintType . getLastDefinedTypeValue ( ) + 1 ] ;
//ACTION constraint (TODO: to implement)
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_ACTION . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_ACTION , dataRepository ) { } ;
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_ACTION . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_ACTION , dataRepository ) {
} ;
//CHILDOF constraint (TODO: to implement)
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_CHILDOF . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_CHILDOF , dataRepository ) { } ;
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_CHILDOF . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_CHILDOF , dataRepository ) {
} ;
//CLAMPTO constraint
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_CLAMPTO . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_CLAMPTO , dataRepository ) {
@Override
public void affectAnimation ( Skeleton skeleton , BoneAnimation boneAnimation , Constraint constraint ) {
this . validateConstraintType ( constraint . getData ( ) ) ;
LOGGER . info ( constraint . getName ( ) + " not active! Curves not yet implemented!" ) ; //TODO: implement when curves are implemented
LOGGER . log ( Level . INFO , "{0} not active! Curves not yet implemented!" , constraint . getName ( ) ) ; //TODO: implement when curves are implemented
}
} ;
//DISTLIMIT constraint
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_DISTLIMIT . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_DISTLIMIT , dataRepository ) {
@Override
public void affectAnimation ( Skeleton skeleton , BoneAnimation boneAnimation , Constraint constraint ) {
Structure constraintStructure = constraint . getData ( ) ;
this . validateConstraintType ( constraintStructure ) ;
Vector3f targetLocation = this . getTargetLocation ( constraint ) ;
BoneTrack boneTrack = this . getBoneTrack ( skeleton , boneAnimation , constraint ) ;
if ( boneTrack ! = null ) {
if ( boneTrack ! = null ) {
//TODO: target vertex group !!!
float dist = ( ( Number ) constraintStructure . getFieldValue ( "dist" ) ) . floatValue ( ) ;
int mode = ( ( Number ) constraintStructure . getFieldValue ( "mode" ) ) . intValue ( ) ;
float dist = ( ( Number ) constraintStructure . getFieldValue ( "dist" ) ) . floatValue ( ) ;
int mode = ( ( Number ) constraintStructure . getFieldValue ( "mode" ) ) . intValue ( ) ;
int maxFrames = boneTrack . getTimes ( ) . length ;
Vector3f [ ] translations = boneTrack . getTranslations ( ) ;
for ( int frame = 0 ; frame < maxFrames ; + + frame ) {
for ( int frame = 0 ; frame < maxFrames ; + + frame ) {
Vector3f v = translations [ frame ] . subtract ( targetLocation ) ;
float currentDistance = v . length ( ) ;
float influence = constraint . getIpo ( ) . calculateValue ( frame ) ;
float modifier = 0 . 0f ;
switch ( mode ) {
switch ( mode ) {
case LIMITDIST_INSIDE :
if ( currentDistance > = dist ) {
if ( currentDistance > = dist ) {
modifier = ( dist - currentDistance ) / currentDistance ;
}
break ;
@ -99,7 +104,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
modifier = ( dist - currentDistance ) / currentDistance ;
break ;
case LIMITDIST_OUTSIDE :
if ( currentDistance < = dist ) {
if ( currentDistance < = dist ) {
modifier = ( dist - currentDistance ) / currentDistance ;
}
break ;
@ -115,15 +120,17 @@ public class ConstraintHelper extends AbstractBlenderHelper {
//FOLLOWPATH constraint
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_FOLLOWPATH . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_FOLLOWPATH , dataRepository ) {
@Override
public void affectAnimation ( Skeleton skeleton , BoneAnimation boneAnimation , Constraint constraint ) {
this . validateConstraintType ( constraint . getData ( ) ) ;
LOGGER . info ( constraint . getName ( ) + " not active! Curves not yet implemented!" ) ; //TODO: implement when curves are implemented
LOGGER . log ( Level . INFO , "{0} not active! Curves not yet implemented!" , constraint . getName ( ) ) ; //TODO: implement when curves are implemented
}
} ;
//KINEMATIC constraint (TODO: to implement)
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_KINEMATIC . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_KINEMATIC , dataRepository ) {
@Override
public void affectAnimation ( Skeleton skeleton , BoneAnimation boneAnimation , Constraint constraint ) {
Structure constraintStructure = constraint . getData ( ) ;
@ -207,17 +214,17 @@ public class ConstraintHelper extends AbstractBlenderHelper {
Bone currentBone = bone ;
do {
int boneIndex = skeleton . getBoneIndex ( currentBone ) ;
for ( int i = 0 ; i < boneAnimation . getTracks ( ) . length ; + + i ) {
if ( boneAnimation . getTracks ( ) [ i ] . getTargetBoneIndex ( ) = = boneIndex ) {
for ( int i = 0 ; i < boneAnimation . getTracks ( ) . length ; + + i ) {
if ( boneAnimation . getTracks ( ) [ i ] . getTargetBoneIndex ( ) = = boneIndex ) {
bonesList . add ( new CalculationBone ( currentBone , boneAnimation . getTracks ( ) [ i ] ) ) ;
break ;
}
}
currentBone = currentBone . getParent ( ) ;
} while ( currentBone ! = null ) ;
} while ( currentBone ! = null ) ;
//attaching children
CalculationBone [ ] result = bonesList . toArray ( new CalculationBone [ bonesList . size ( ) ] ) ;
for ( int i = result . length - 1 ; i > 0 ; - - i ) {
for ( int i = result . length - 1 ; i > 0 ; - - i ) {
result [ i ] . attachChild ( result [ i - 1 ] ) ;
}
return result ;
@ -225,39 +232,41 @@ public class ConstraintHelper extends AbstractBlenderHelper {
} ;
//LOCKTRACK constraint (TODO: to implement)
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_LOCKTRACK . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_LOCKTRACK , dataRepository ) { } ;
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_LOCKTRACK . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_LOCKTRACK , dataRepository ) {
} ;
//LOCLIKE constraint
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_LOCLIKE . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_LOCLIKE , dataRepository ) {
@Override
public void affectAnimation ( Skeleton skeleton , BoneAnimation boneAnimation , Constraint constraint ) {
Structure constraintData = constraint . getData ( ) ;
this . validateConstraintType ( constraintData ) ;
BoneTrack boneTrack = this . getBoneTrack ( skeleton , boneAnimation , constraint ) ;
if ( boneTrack ! = null ) {
if ( boneTrack ! = null ) {
Vector3f targetLocation = this . getTargetLocation ( constraint ) ;
int flag = ( ( Number ) constraintData . getFieldValue ( "flag" ) ) . intValue ( ) ;
int flag = ( ( Number ) constraintData . getFieldValue ( "flag" ) ) . intValue ( ) ;
Vector3f [ ] translations = boneTrack . getTranslations ( ) ;
int maxFrames = translations . length ;
for ( int frame = 0 ; frame < maxFrames ; + + frame ) {
for ( int frame = 0 ; frame < maxFrames ; + + frame ) {
Vector3f offset = Vector3f . ZERO ;
if ( ( flag & LOCLIKE_OFFSET ) ! = 0 ) { //we add the original location to the copied location
if ( ( flag & LOCLIKE_OFFSET ) ! = 0 ) { //we add the original location to the copied location
offset = translations [ frame ] . clone ( ) ;
}
if ( ( flag & LOCLIKE_X ) ! = 0 ) {
if ( ( flag & LOCLIKE_X ) ! = 0 ) {
translations [ frame ] . x = targetLocation . x ;
if ( ( flag & LOCLIKE_X_INVERT ) ! = 0 ) {
if ( ( flag & LOCLIKE_X_INVERT ) ! = 0 ) {
translations [ frame ] . x = - translations [ frame ] . x ;
}
} else if ( ( flag & LOCLIKE_Y ) ! = 0 ) {
} else if ( ( flag & LOCLIKE_Y ) ! = 0 ) {
translations [ frame ] . y = targetLocation . y ;
if ( ( flag & LOCLIKE_Y_INVERT ) ! = 0 ) {
if ( ( flag & LOCLIKE_Y_INVERT ) ! = 0 ) {
translations [ frame ] . y = - translations [ frame ] . y ;
}
} else if ( ( flag & LOCLIKE_Z ) ! = 0 ) {
} else if ( ( flag & LOCLIKE_Z ) ! = 0 ) {
translations [ frame ] . z = targetLocation . z ;
if ( ( flag & LOCLIKE_Z_INVERT ) ! = 0 ) {
if ( ( flag & LOCLIKE_Z_INVERT ) ! = 0 ) {
translations [ frame ] . z = - translations [ frame ] . z ;
}
}
@ -270,50 +279,51 @@ public class ConstraintHelper extends AbstractBlenderHelper {
//LOCLIMIT constraint
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_LOCLIMIT . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_LOCLIMIT , dataRepository ) {
@Override
public void affectAnimation ( Skeleton skeleton , BoneAnimation boneAnimation , Constraint constraint ) {
Structure constraintStructure = constraint . getData ( ) ;
this . validateConstraintType ( constraintStructure ) ;
BoneTrack boneTrack = this . getBoneTrack ( skeleton , boneAnimation , constraint ) ;
if ( boneTrack ! = null ) {
int flag = ( ( Number ) constraintStructure . getFieldValue ( "flag" ) ) . intValue ( ) ;
if ( boneTrack ! = null ) {
int flag = ( ( Number ) constraintStructure . getFieldValue ( "flag" ) ) . intValue ( ) ;
Vector3f [ ] translations = boneTrack . getTranslations ( ) ;
int maxFrames = translations . length ;
for ( int frame = 0 ; frame < maxFrames ; + + frame ) {
for ( int frame = 0 ; frame < maxFrames ; + + frame ) {
float influence = constraint . getIpo ( ) . calculateValue ( frame ) ;
if ( ( flag & LIMIT_XMIN ) ! = 0 ) {
float xmin = ( ( Number ) constraintStructure . getFieldValue ( "xmin" ) ) . floatValue ( ) ;
if ( translations [ frame ] . x < xmin ) {
if ( ( flag & LIMIT_XMIN ) ! = 0 ) {
float xmin = ( ( Number ) constraintStructure . getFieldValue ( "xmin" ) ) . floatValue ( ) ;
if ( translations [ frame ] . x < xmin ) {
translations [ frame ] . x - = ( translations [ frame ] . x - xmin ) * influence ;
}
}
if ( ( flag & LIMIT_XMAX ) ! = 0 ) {
float xmax = ( ( Number ) constraintStructure . getFieldValue ( "xmax" ) ) . floatValue ( ) ;
if ( translations [ frame ] . x > xmax ) {
if ( ( flag & LIMIT_XMAX ) ! = 0 ) {
float xmax = ( ( Number ) constraintStructure . getFieldValue ( "xmax" ) ) . floatValue ( ) ;
if ( translations [ frame ] . x > xmax ) {
translations [ frame ] . x - = ( translations [ frame ] . x - xmax ) * influence ;
}
}
if ( ( flag & LIMIT_YMIN ) ! = 0 ) {
float ymin = ( ( Number ) constraintStructure . getFieldValue ( "ymin" ) ) . floatValue ( ) ;
if ( translations [ frame ] . y < ymin ) {
if ( ( flag & LIMIT_YMIN ) ! = 0 ) {
float ymin = ( ( Number ) constraintStructure . getFieldValue ( "ymin" ) ) . floatValue ( ) ;
if ( translations [ frame ] . y < ymin ) {
translations [ frame ] . y - = ( translations [ frame ] . y - ymin ) * influence ;
}
}
if ( ( flag & LIMIT_YMAX ) ! = 0 ) {
float ymax = ( ( Number ) constraintStructure . getFieldValue ( "ymax" ) ) . floatValue ( ) ;
if ( translations [ frame ] . y > ymax ) {
if ( ( flag & LIMIT_YMAX ) ! = 0 ) {
float ymax = ( ( Number ) constraintStructure . getFieldValue ( "ymax" ) ) . floatValue ( ) ;
if ( translations [ frame ] . y > ymax ) {
translations [ frame ] . y - = ( translations [ frame ] . y - ymax ) * influence ;
}
}
if ( ( flag & LIMIT_ZMIN ) ! = 0 ) {
float zmin = ( ( Number ) constraintStructure . getFieldValue ( "zmin" ) ) . floatValue ( ) ;
if ( translations [ frame ] . z < zmin ) {
if ( ( flag & LIMIT_ZMIN ) ! = 0 ) {
float zmin = ( ( Number ) constraintStructure . getFieldValue ( "zmin" ) ) . floatValue ( ) ;
if ( translations [ frame ] . z < zmin ) {
translations [ frame ] . z - = ( translations [ frame ] . z - zmin ) * influence ;
}
}
if ( ( flag & LIMIT_ZMAX ) ! = 0 ) {
float zmax = ( ( Number ) constraintStructure . getFieldValue ( "zmax" ) ) . floatValue ( ) ;
if ( translations [ frame ] . z > zmax ) {
if ( ( flag & LIMIT_ZMAX ) ! = 0 ) {
float zmax = ( ( Number ) constraintStructure . getFieldValue ( "zmax" ) ) . floatValue ( ) ;
if ( translations [ frame ] . z > zmax ) {
translations [ frame ] . z - = ( translations [ frame ] . z - zmax ) * influence ;
}
} //TODO: consider constraint space !!!
@ -324,51 +334,56 @@ public class ConstraintHelper extends AbstractBlenderHelper {
} ;
//MINMAX constraint (TODO: to implement)
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_MINMAX . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_MINMAX , dataRepository ) { } ;
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_MINMAX . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_MINMAX , dataRepository ) {
} ;
//NULL constraint - does nothing
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_NULL . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_NULL , dataRepository ) { } ;
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_NULL . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_NULL , dataRepository ) {
} ;
//PYTHON constraint (TODO: to implement)
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_PYTHON . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_PYTHON , dataRepository ) { } ;
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_PYTHON . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_PYTHON , dataRepository ) {
} ;
//RIGIDBODYJOINT constraint (TODO: to implement)
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_RIGIDBODYJOINT . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_RIGIDBODYJOINT , dataRepository ) { } ;
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_RIGIDBODYJOINT . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_RIGIDBODYJOINT , dataRepository ) {
} ;
//ROTLIKE constraint
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_ROTLIKE . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_ROTLIKE , dataRepository ) {
@Override
public void affectAnimation ( Skeleton skeleton , BoneAnimation boneAnimation , Constraint constraint ) {
Structure constraintData = constraint . getData ( ) ;
this . validateConstraintType ( constraintData ) ;
BoneTrack boneTrack = this . getBoneTrack ( skeleton , boneAnimation , constraint ) ;
if ( boneTrack ! = null ) {
if ( boneTrack ! = null ) {
Quaternion targetRotation = this . getTargetRotation ( constraint ) ;
int flag = ( ( Number ) constraintData . getFieldValue ( "flag" ) ) . intValue ( ) ;
int flag = ( ( Number ) constraintData . getFieldValue ( "flag" ) ) . intValue ( ) ;
float [ ] targetAngles = targetRotation . toAngles ( null ) ;
Quaternion [ ] rotations = boneTrack . getRotations ( ) ;
int maxFrames = rotations . length ;
for ( int frame = 0 ; frame < maxFrames ; + + frame ) {
for ( int frame = 0 ; frame < maxFrames ; + + frame ) {
float [ ] angles = rotations [ frame ] . toAngles ( null ) ;
Quaternion offset = Quaternion . IDENTITY ;
if ( ( flag & ROTLIKE_OFFSET ) ! = 0 ) { //we add the original rotation to the copied rotation
if ( ( flag & ROTLIKE_OFFSET ) ! = 0 ) { //we add the original rotation to the copied rotation
offset = rotations [ frame ] . clone ( ) ;
}
if ( ( flag & ROTLIKE_X ) ! = 0 ) {
if ( ( flag & ROTLIKE_X ) ! = 0 ) {
angles [ 0 ] = targetAngles [ 0 ] ;
if ( ( flag & ROTLIKE_X_INVERT ) ! = 0 ) {
if ( ( flag & ROTLIKE_X_INVERT ) ! = 0 ) {
angles [ 0 ] = - angles [ 0 ] ;
}
} else if ( ( flag & ROTLIKE_Y ) ! = 0 ) {
} else if ( ( flag & ROTLIKE_Y ) ! = 0 ) {
angles [ 1 ] = targetAngles [ 1 ] ;
if ( ( flag & ROTLIKE_Y_INVERT ) ! = 0 ) {
if ( ( flag & ROTLIKE_Y_INVERT ) ! = 0 ) {
angles [ 1 ] = - angles [ 1 ] ;
}
} else if ( ( flag & ROTLIKE_Z ) ! = 0 ) {
} else if ( ( flag & ROTLIKE_Z ) ! = 0 ) {
angles [ 2 ] = targetAngles [ 2 ] ;
if ( ( flag & ROTLIKE_Z_INVERT ) ! = 0 ) {
if ( ( flag & ROTLIKE_Z_INVERT ) ! = 0 ) {
angles [ 2 ] = - angles [ 2 ] ;
}
}
@ -381,47 +396,48 @@ public class ConstraintHelper extends AbstractBlenderHelper {
//ROTLIMIT constraint
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_ROTLIMIT . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_ROTLIMIT , dataRepository ) {
@Override
public void affectAnimation ( Skeleton skeleton , BoneAnimation boneAnimation , Constraint constraint ) {
Structure constraintStructure = constraint . getData ( ) ;
this . validateConstraintType ( constraintStructure ) ;
BoneTrack boneTrack = this . getBoneTrack ( skeleton , boneAnimation , constraint ) ;
if ( boneTrack ! = null ) {
int flag = ( ( Number ) constraintStructure . getFieldValue ( "flag" ) ) . intValue ( ) ;
if ( boneTrack ! = null ) {
int flag = ( ( Number ) constraintStructure . getFieldValue ( "flag" ) ) . intValue ( ) ;
Quaternion [ ] rotations = boneTrack . getRotations ( ) ;
int maxFrames = rotations . length ;
for ( int frame = 0 ; frame < maxFrames ; + + frame ) {
for ( int frame = 0 ; frame < maxFrames ; + + frame ) {
float [ ] angles = rotations [ frame ] . toAngles ( null ) ;
float influence = constraint . getIpo ( ) . calculateValue ( frame ) ;
if ( ( flag & LIMIT_XROT ) ! = 0 ) {
float xmin = ( ( Number ) constraintStructure . getFieldValue ( "xmin" ) ) . floatValue ( ) * FastMath . DEG_TO_RAD ;
float xmax = ( ( Number ) constraintStructure . getFieldValue ( "xmax" ) ) . floatValue ( ) * FastMath . DEG_TO_RAD ;
if ( ( flag & LIMIT_XROT ) ! = 0 ) {
float xmin = ( ( Number ) constraintStructure . getFieldValue ( "xmin" ) ) . floatValue ( ) * FastMath . DEG_TO_RAD ;
float xmax = ( ( Number ) constraintStructure . getFieldValue ( "xmax" ) ) . floatValue ( ) * FastMath . DEG_TO_RAD ;
float difference = 0 . 0f ;
if ( angles [ 0 ] < xmin ) {
if ( angles [ 0 ] < xmin ) {
difference = ( angles [ 0 ] - xmin ) * influence ;
} else if ( angles [ 0 ] > xmax ) {
} else if ( angles [ 0 ] > xmax ) {
difference = ( angles [ 0 ] - xmax ) * influence ;
}
angles [ 0 ] - = difference ;
}
if ( ( flag & LIMIT_YROT ) ! = 0 ) {
float ymin = ( ( Number ) constraintStructure . getFieldValue ( "ymin" ) ) . floatValue ( ) * FastMath . DEG_TO_RAD ;
float ymax = ( ( Number ) constraintStructure . getFieldValue ( "ymax" ) ) . floatValue ( ) * FastMath . DEG_TO_RAD ;
if ( ( flag & LIMIT_YROT ) ! = 0 ) {
float ymin = ( ( Number ) constraintStructure . getFieldValue ( "ymin" ) ) . floatValue ( ) * FastMath . DEG_TO_RAD ;
float ymax = ( ( Number ) constraintStructure . getFieldValue ( "ymax" ) ) . floatValue ( ) * FastMath . DEG_TO_RAD ;
float difference = 0 . 0f ;
if ( angles [ 1 ] < ymin ) {
if ( angles [ 1 ] < ymin ) {
difference = ( angles [ 1 ] - ymin ) * influence ;
} else if ( angles [ 1 ] > ymax ) {
} else if ( angles [ 1 ] > ymax ) {
difference = ( angles [ 1 ] - ymax ) * influence ;
}
angles [ 1 ] - = difference ;
}
if ( ( flag & LIMIT_ZROT ) ! = 0 ) {
float zmin = ( ( Number ) constraintStructure . getFieldValue ( "zmin" ) ) . floatValue ( ) * FastMath . DEG_TO_RAD ;
float zmax = ( ( Number ) constraintStructure . getFieldValue ( "zmax" ) ) . floatValue ( ) * FastMath . DEG_TO_RAD ;
if ( ( flag & LIMIT_ZROT ) ! = 0 ) {
float zmin = ( ( Number ) constraintStructure . getFieldValue ( "zmin" ) ) . floatValue ( ) * FastMath . DEG_TO_RAD ;
float zmax = ( ( Number ) constraintStructure . getFieldValue ( "zmax" ) ) . floatValue ( ) * FastMath . DEG_TO_RAD ;
float difference = 0 . 0f ;
if ( angles [ 2 ] < zmin ) {
if ( angles [ 2 ] < zmin ) {
difference = ( angles [ 2 ] - zmin ) * influence ;
} else if ( angles [ 2 ] > zmax ) {
} else if ( angles [ 2 ] > zmax ) {
difference = ( angles [ 2 ] - zmax ) * influence ;
}
angles [ 2 ] - = difference ;
@ -434,31 +450,33 @@ public class ConstraintHelper extends AbstractBlenderHelper {
} ;
//SHRINKWRAP constraint (TODO: to implement)
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_SHRINKWRAP . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_SHRINKWRAP , dataRepository ) { } ;
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_SHRINKWRAP . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_SHRINKWRAP , dataRepository ) {
} ;
//SIZELIKE constraint
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_SIZELIKE . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_SIZELIKE , dataRepository ) {
@Override
public void affectAnimation ( Skeleton skeleton , BoneAnimation boneAnimation , Constraint constraint ) {
Structure constraintData = constraint . getData ( ) ;
this . validateConstraintType ( constraintData ) ;
Vector3f targetScale = this . getTargetLocation ( constraint ) ;
BoneTrack boneTrack = this . getBoneTrack ( skeleton , boneAnimation , constraint ) ;
if ( boneTrack ! = null ) {
int flag = ( ( Number ) constraintData . getFieldValue ( "flag" ) ) . intValue ( ) ;
if ( boneTrack ! = null ) {
int flag = ( ( Number ) constraintData . getFieldValue ( "flag" ) ) . intValue ( ) ;
Vector3f [ ] scales = boneTrack . getScales ( ) ;
int maxFrames = scales . length ;
for ( int frame = 0 ; frame < maxFrames ; + + frame ) {
for ( int frame = 0 ; frame < maxFrames ; + + frame ) {
Vector3f offset = Vector3f . ZERO ;
if ( ( flag & LOCLIKE_OFFSET ) ! = 0 ) { //we add the original scale to the copied scale
if ( ( flag & LOCLIKE_OFFSET ) ! = 0 ) { //we add the original scale to the copied scale
offset = scales [ frame ] . clone ( ) ;
}
if ( ( flag & SIZELIKE_X ) ! = 0 ) {
if ( ( flag & SIZELIKE_X ) ! = 0 ) {
scales [ frame ] . x = targetScale . x ;
} else if ( ( flag & SIZELIKE_Y ) ! = 0 ) {
} else if ( ( flag & SIZELIKE_Y ) ! = 0 ) {
scales [ frame ] . y = targetScale . y ;
} else if ( ( flag & SIZELIKE_Z ) ! = 0 ) {
} else if ( ( flag & SIZELIKE_Z ) ! = 0 ) {
scales [ frame ] . z = targetScale . z ;
}
scales [ frame ] . addLocal ( offset ) ; //TODO: ipo influence
@ -471,50 +489,51 @@ public class ConstraintHelper extends AbstractBlenderHelper {
//SIZELIMIT constraint
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_SIZELIMIT . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_SIZELIMIT , dataRepository ) {
@Override
public void affectAnimation ( Skeleton skeleton , BoneAnimation boneAnimation , Constraint constraint ) {
Structure constraintStructure = constraint . getData ( ) ;
this . validateConstraintType ( constraintStructure ) ;
BoneTrack boneTrack = this . getBoneTrack ( skeleton , boneAnimation , constraint ) ;
if ( boneTrack ! = null ) {
int flag = ( ( Number ) constraintStructure . getFieldValue ( "flag" ) ) . intValue ( ) ;
if ( boneTrack ! = null ) {
int flag = ( ( Number ) constraintStructure . getFieldValue ( "flag" ) ) . intValue ( ) ;
Vector3f [ ] scales = boneTrack . getScales ( ) ;
int maxFrames = scales . length ;
for ( int frame = 0 ; frame < maxFrames ; + + frame ) {
for ( int frame = 0 ; frame < maxFrames ; + + frame ) {
float influence = constraint . getIpo ( ) . calculateValue ( frame ) ;
if ( ( flag & LIMIT_XMIN ) ! = 0 ) {
float xmin = ( ( Number ) constraintStructure . getFieldValue ( "xmin" ) ) . floatValue ( ) ;
if ( scales [ frame ] . x < xmin ) {
if ( ( flag & LIMIT_XMIN ) ! = 0 ) {
float xmin = ( ( Number ) constraintStructure . getFieldValue ( "xmin" ) ) . floatValue ( ) ;
if ( scales [ frame ] . x < xmin ) {
scales [ frame ] . x - = ( scales [ frame ] . x - xmin ) * influence ;
}
}
if ( ( flag & LIMIT_XMAX ) ! = 0 ) {
float xmax = ( ( Number ) constraintStructure . getFieldValue ( "xmax" ) ) . floatValue ( ) ;
if ( scales [ frame ] . x > xmax ) {
if ( ( flag & LIMIT_XMAX ) ! = 0 ) {
float xmax = ( ( Number ) constraintStructure . getFieldValue ( "xmax" ) ) . floatValue ( ) ;
if ( scales [ frame ] . x > xmax ) {
scales [ frame ] . x - = ( scales [ frame ] . x - xmax ) * influence ;
}
}
if ( ( flag & LIMIT_YMIN ) ! = 0 ) {
float ymin = ( ( Number ) constraintStructure . getFieldValue ( "ymin" ) ) . floatValue ( ) ;
if ( scales [ frame ] . y < ymin ) {
if ( ( flag & LIMIT_YMIN ) ! = 0 ) {
float ymin = ( ( Number ) constraintStructure . getFieldValue ( "ymin" ) ) . floatValue ( ) ;
if ( scales [ frame ] . y < ymin ) {
scales [ frame ] . y - = ( scales [ frame ] . y - ymin ) * influence ;
}
}
if ( ( flag & LIMIT_YMAX ) ! = 0 ) {
float ymax = ( ( Number ) constraintStructure . getFieldValue ( "ymax" ) ) . floatValue ( ) ;
if ( scales [ frame ] . y > ymax ) {
if ( ( flag & LIMIT_YMAX ) ! = 0 ) {
float ymax = ( ( Number ) constraintStructure . getFieldValue ( "ymax" ) ) . floatValue ( ) ;
if ( scales [ frame ] . y > ymax ) {
scales [ frame ] . y - = ( scales [ frame ] . y - ymax ) * influence ;
}
}
if ( ( flag & LIMIT_ZMIN ) ! = 0 ) {
float zmin = ( ( Number ) constraintStructure . getFieldValue ( "zmin" ) ) . floatValue ( ) ;
if ( scales [ frame ] . z < zmin ) {
if ( ( flag & LIMIT_ZMIN ) ! = 0 ) {
float zmin = ( ( Number ) constraintStructure . getFieldValue ( "zmin" ) ) . floatValue ( ) ;
if ( scales [ frame ] . z < zmin ) {
scales [ frame ] . z - = ( scales [ frame ] . z - zmin ) * influence ;
}
}
if ( ( flag & LIMIT_ZMAX ) ! = 0 ) {
float zmax = ( ( Number ) constraintStructure . getFieldValue ( "zmax" ) ) . floatValue ( ) ;
if ( scales [ frame ] . z > zmax ) {
if ( ( flag & LIMIT_ZMAX ) ! = 0 ) {
float zmax = ( ( Number ) constraintStructure . getFieldValue ( "zmax" ) ) . floatValue ( ) ;
if ( scales [ frame ] . z > zmax ) {
scales [ frame ] . z - = ( scales [ frame ] . z - zmax ) * influence ;
}
} //TODO: consider constraint space !!!
@ -525,10 +544,12 @@ public class ConstraintHelper extends AbstractBlenderHelper {
} ;
//STRETCHTO constraint (TODO: to implement)
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_STRETCHTO . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_STRETCHTO , dataRepository ) { } ;
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_STRETCHTO . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_STRETCHTO , dataRepository ) {
} ;
//TRANSFORM constraint (TODO: to implement)
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_TRANSFORM . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_TRANSFORM , dataRepository ) { } ;
influenceFunctions [ ConstraintType . CONSTRAINT_TYPE_TRANSFORM . getConstraintId ( ) ] = new AbstractInfluenceFunction ( ConstraintType . CONSTRAINT_TYPE_TRANSFORM , dataRepository ) {
} ;
}
}
@ -546,19 +567,19 @@ public class ConstraintHelper extends AbstractBlenderHelper {
// reading influence ipos for the constraints
IpoHelper ipoHelper = dataRepository . getHelper ( IpoHelper . class ) ;
Map < String , Map < String , Ipo > > constraintsIpos = new HashMap < String , Map < String , Ipo > > ( ) ;
Pointer pActions = ( Pointer ) objectStructure . getFieldValue ( "action" ) ;
if ( ! pActions . isNull ( ) ) {
Pointer pActions = ( Pointer ) objectStructure . getFieldValue ( "action" ) ;
if ( ! pActions . isNull ( ) ) {
List < Structure > actions = pActions . fetchData ( dataRepository . getInputStream ( ) ) ;
for ( Structure action : actions ) {
Structure chanbase = ( Structure ) action . getFieldValue ( "chanbase" ) ;
for ( Structure action : actions ) {
Structure chanbase = ( Structure ) action . getFieldValue ( "chanbase" ) ;
List < Structure > actionChannels = chanbase . evaluateListBase ( dataRepository ) ;
for ( Structure actionChannel : actionChannels ) {
for ( Structure actionChannel : actionChannels ) {
Map < String , Ipo > ipos = new HashMap < String , Ipo > ( ) ;
Structure constChannels = ( Structure ) actionChannel . getFieldValue ( "constraintChannels" ) ;
Structure constChannels = ( Structure ) actionChannel . getFieldValue ( "constraintChannels" ) ;
List < Structure > constraintChannels = constChannels . evaluateListBase ( dataRepository ) ;
for ( Structure constraintChannel : constraintChannels ) {
Pointer pIpo = ( Pointer ) constraintChannel . getFieldValue ( "ipo" ) ;
if ( ! pIpo . isNull ( ) ) {
for ( Structure constraintChannel : constraintChannels ) {
Pointer pIpo = ( Pointer ) constraintChannel . getFieldValue ( "ipo" ) ;
if ( ! pIpo . isNull ( ) ) {
String constraintName = constraintChannel . getFieldValue ( "name" ) . toString ( ) ;
Ipo ipo = ipoHelper . createIpo ( pIpo . fetchData ( dataRepository . getInputStream ( ) ) . get ( 0 ) , dataRepository ) ;
ipos . put ( constraintName , ipo ) ;
@ -572,25 +593,25 @@ public class ConstraintHelper extends AbstractBlenderHelper {
//loading constraints connected with the object's bones
List < Constraint > constraintsList = new ArrayList < Constraint > ( ) ;
Pointer pPose = ( Pointer ) objectStructure . getFieldValue ( "pose" ) ; //TODO: what if the object has two armatures ????
if ( ! pPose . isNull ( ) ) {
Pointer pPose = ( Pointer ) objectStructure . getFieldValue ( "pose" ) ; //TODO: what if the object has two armatures ????
if ( ! pPose . isNull ( ) ) {
//getting pose channels
List < Structure > poseChannels = ( ( Structure ) pPose . fetchData ( dataRepository . getInputStream ( ) ) . get ( 0 ) . getFieldValue ( "chanbase" ) ) . evaluateListBase ( dataRepository ) ;
for ( Structure poseChannel : poseChannels ) {
Long boneOMA = Long . valueOf ( ( ( Pointer ) poseChannel . getFieldValue ( "bone" ) ) . getOldMemoryAddress ( ) ) ;
List < Structure > poseChannels = ( ( Structure ) pPose . fetchData ( dataRepository . getInputStream ( ) ) . get ( 0 ) . getFieldValue ( "chanbase" ) ) . evaluateListBase ( dataRepository ) ;
for ( Structure poseChannel : poseChannels ) {
Long boneOMA = Long . valueOf ( ( ( Pointer ) poseChannel . getFieldValue ( "bone" ) ) . getOldMemoryAddress ( ) ) ;
//the name is read directly from structure because bone might not yet be loaded
String name = dataRepository . getFileBlock ( boneOMA ) . getStructure ( dataRepository ) . getFieldValue ( "name" ) . toString ( ) ;
List < Structure > constraints = ( ( Structure ) poseChannel . getFieldValue ( "constraints" ) ) . evaluateListBase ( dataRepository ) ;
for ( Structure constraint : constraints ) {
int type = ( ( Number ) constraint . getFieldValue ( "type" ) ) . intValue ( ) ;
List < Structure > constraints = ( ( Structure ) poseChannel . getFieldValue ( "constraints" ) ) . evaluateListBase ( dataRepository ) ;
for ( Structure constraint : constraints ) {
int type = ( ( Number ) constraint . getFieldValue ( "type" ) ) . intValue ( ) ;
String constraintName = constraint . getFieldValue ( "name" ) . toString ( ) ;
Ipo ipo = constraintsIpos . get ( name ) . get ( constraintName ) ;
if ( ipo = = null ) {
float enforce = ( ( Number ) constraint . getFieldValue ( "enforce" ) ) . floatValue ( ) ;
if ( ipo = = null ) {
float enforce = ( ( Number ) constraint . getFieldValue ( "enforce" ) ) . floatValue ( ) ;
ipo = ipoHelper . createIpo ( enforce ) ;
}
Space ownerSpace = Space . valueOf ( ( ( Number ) constraint . getFieldValue ( "ownspace" ) ) . byteValue ( ) ) ;
Space targetSpace = Space . valueOf ( ( ( Number ) constraint . getFieldValue ( "tarspace" ) ) . byteValue ( ) ) ;
Space ownerSpace = Space . valueOf ( ( ( Number ) constraint . getFieldValue ( "ownspace" ) ) . byteValue ( ) ) ;
Space targetSpace = Space . valueOf ( ( ( Number ) constraint . getFieldValue ( "tarspace" ) ) . byteValue ( ) ) ;
Constraint c = new Constraint ( constraint , influenceFunctions [ type ] , boneOMA , ownerSpace , targetSpace , ipo , dataRepository ) ;
constraintsList . add ( c ) ;
}
@ -615,7 +636,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
this . constraints . put ( objectStructure . getOldMemoryAddress ( ) , result ) ;
}
* /
if ( constraintsList . size ( ) > 0 ) {
if ( constraintsList . size ( ) > 0 ) {
this . constraints . put ( objectStructure . getOldMemoryAddress ( ) , constraintsList . toArray ( new Constraint [ constraintsList . size ( ) ] ) ) ;
}
}
@ -640,6 +661,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
* @author Marcin Roguski
* /
private static class CalculationBone extends Node {
/** The name of the bone. Only to be used in toString method. */
private String boneName ;
/** The bone's tracks. Will be altered at the end of calculation process. */
@ -650,7 +672,6 @@ public class ConstraintHelper extends AbstractBlenderHelper {
private Quaternion startRotation ;
/** The starting scale of the bone. */
private Vector3f startScale ;
private Vector3f [ ] translations ;
private Quaternion [ ] rotations ;
private Vector3f [ ] scales ;
@ -682,7 +703,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
* /
//TODO: set to Z axis if user defined it this way
public Vector3f getEndPoint ( ) {
if ( this . getParent ( ) = = null ) {
if ( this . getParent ( ) = = null ) {
return new Vector3f ( 0 , this . getLocalScale ( ) . y , 0 ) ;
} else {
Node parent = this . getParent ( ) ;
@ -701,7 +722,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
@Override
public int attachChild ( Spatial child ) {
if ( this . getChildren ( ) ! = null & & this . getChildren ( ) . size ( ) > 1 ) {
if ( this . getChildren ( ) ! = null & & this . getChildren ( ) . size ( ) > 1 ) {
throw new IllegalStateException ( this . getClass ( ) . getName ( ) + " class instance can only have one child!" ) ;
}
return super . attachChild ( child ) ;
@ -710,13 +731,13 @@ public class ConstraintHelper extends AbstractBlenderHelper {
public Spatial rotate ( Quaternion rot , int frame ) {
Spatial spatial = super . rotate ( rot ) ;
this . updateWorldTransforms ( ) ;
if ( this . getChildren ( ) ! = null & & this . getChildren ( ) . size ( ) > 0 ) {
CalculationBone child = ( CalculationBone ) this . getChild ( 0 ) ;
if ( this . getChildren ( ) ! = null & & this . getChildren ( ) . size ( ) > 0 ) {
CalculationBone child = ( CalculationBone ) this . getChild ( 0 ) ;
child . updateWorldTransforms ( ) ;
}
rotations [ frame ] . set ( this . getLocalRotation ( ) ) ;
translations [ frame ] . set ( this . getLocalTranslation ( ) ) ;
if ( scales ! = null ) {
if ( scales ! = null ) {
scales [ frame ] . set ( this . getLocalScale ( ) ) ;
}
return spatial ;
@ -728,7 +749,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
@Override
public String toString ( ) {
return boneName + ": " + this . getLocalRotation ( ) + " " + this . getLocalTranslation ( ) ;
return boneName + ": " + this . getLocalRotation ( ) + " " + this . getLocalTranslation ( ) ;
}
}
}