@ -77,465 +77,466 @@ import com.jme3.scene.plugins.ogre.AnimData;
* @author Marcin Roguski
* @author Marcin Roguski
* /
* /
public class ModifierHelper extends AbstractBlenderHelper {
public class ModifierHelper extends AbstractBlenderHelper {
private static final Logger LOGGER = Logger . getLogger ( ModifierHelper . class . getName ( ) ) ;
private static final Logger LOGGER = Logger . getLogger ( ModifierHelper . class . getName ( ) ) ;
/ * *
* This constructor parses the given blender version and stores the result . Some functionalities may differ in
/ * *
* different blender versions .
* This constructor parses the given blender version and stores the result . Some functionalities may differ in
* @param blenderVersion
* different blender versions .
* the version read from the blend file
* @param blenderVersion
* /
* the version read from the blend file
public ModifierHelper ( String blenderVersion ) {
* /
super ( blenderVersion ) ;
public ModifierHelper ( String blenderVersion ) {
}
super ( blenderVersion ) ;
}
/ * *
* This method applies modifier to the object .
/ * *
* @param node
* This method applies modifier to the object .
* the loaded object
* @param node
* @param modifier
* the loaded object
* the modifier to apply
* @param modifier
* @param dataRepository
* the modifier to apply
* the data repository
* @param dataRepository
* @return the node to whom the modifier was applied
* the data repository
* /
* @return the node to whom the modifier was applied
public Node applyModifier ( Node node , Modifier modifier , DataRepository dataRepository ) {
* /
if ( Modifier . ARMATURE_MODIFIER_DATA . equals ( modifier . getType ( ) ) ) {
public Node applyModifier ( Node node , Modifier modifier , DataRepository dataRepository ) {
return this . applyArmatureModifierData ( node , modifier , dataRepository ) ;
if ( Modifier . ARMATURE_MODIFIER_DATA . equals ( modifier . getType ( ) ) ) {
} else if ( Modifier . ARRAY_MODIFIER_DATA . equals ( modifier . getType ( ) ) ) {
return this . applyArmatureModifierData ( node , modifier , dataRepository ) ;
return this . applyArrayModifierData ( node , modifier , dataRepository ) ;
} else if ( Modifier . ARRAY_MODIFIER_DATA . equals ( modifier . getType ( ) ) ) {
} else if ( Modifier . PARTICLE_MODIFIER_DATA . equals ( modifier . getType ( ) ) ) {
return this . applyArrayModifierData ( node , modifier , dataRepository ) ;
return this . applyParticleSystemModifierData ( node , modifier , dataRepository ) ;
} else if ( Modifier . PARTICLE_MODIFIER_DATA . equals ( modifier . getType ( ) ) ) {
} else {
return this . applyParticleSystemModifierData ( node , modifier , dataRepository ) ;
LOGGER . warning ( "Modifier: " + modifier . getType ( ) + " not yet implemented!!!" ) ;
} else {
return node ;
LOGGER . warning ( "Modifier: " + modifier . getType ( ) + " not yet implemented!!!" ) ;
}
return node ;
}
}
}
/ * *
* This method reads the given object ' s modifiers .
/ * *
* @param objectStructure
* This method reads the given object ' s modifiers .
* the object structure
* @param objectStructure
* @param dataRepository
* the object structure
* the data repository
* @param dataRepository
* @param converter
* the data repository
* the converter object ( in some cases we need to read an object first before loading the modifier )
* @param converter
* @throws BlenderFileException
* the converter object ( in some cases we need to read an object first before loading the modifier )
* this exception is thrown when the blender file is somehow corrupted
* @throws BlenderFileException
* /
* this exception is thrown when the blender file is somehow corrupted
@SuppressWarnings ( "unchecked" )
* /
public void readModifiers ( Structure objectStructure , DataRepository dataRepository ) throws BlenderFileException {
@SuppressWarnings ( "unchecked" )
Structure modifiersListBase = ( Structure ) objectStructure . getFieldValue ( "modifiers" ) ;
public void readModifiers ( Structure objectStructure , DataRepository dataRepository ) throws BlenderFileException {
List < Structure > modifiers = modifiersListBase . evaluateListBase ( dataRepository ) ;
Structure modifiersListBase = ( Structure ) objectStructure . getFieldValue ( "modifiers" ) ;
for ( Structure modifier : modifiers ) {
List < Structure > modifiers = modifiersListBase . evaluateListBase ( dataRepository ) ;
Object loadedModifier = null ;
for ( Structure modifier : modifiers ) {
Object modifierAdditionalData = null ;
Object loadedModifier = null ;
if ( Modifier . ARRAY_MODIFIER_DATA . equals ( modifier . getType ( ) ) ) { //****************ARRAY MODIFIER
Object modifierAdditionalData = null ;
Map < String , Object > params = new HashMap < String , Object > ( ) ;
if ( Modifier . ARRAY_MODIFIER_DATA . equals ( modifier . getType ( ) ) ) { //****************ARRAY MODIFIER
Map < String , Object > params = new HashMap < String , Object > ( ) ;
Number fittype = ( Number ) modifier . getFieldValue ( "fit_type" ) ;
params . put ( "fittype" , fittype ) ;
Number fittype = ( Number ) modifier . getFieldValue ( "fit_type" ) ;
switch ( fittype . intValue ( ) ) {
params . put ( "fittype" , fittype ) ;
case 0 : //FIXED COUNT
switch ( fittype . intValue ( ) ) {
params . put ( "count" , modifier . getFieldValue ( "count" ) ) ;
case 0 : //FIXED COUNT
break ;
params . put ( "count" , modifier . getFieldValue ( "count" ) ) ;
case 1 : //FIXED LENGTH
break ;
params . put ( "length" , modifier . getFieldValue ( "length" ) ) ;
case 1 : //FIXED LENGTH
break ;
params . put ( "length" , modifier . getFieldValue ( "length" ) ) ;
case 2 : //FITCURVE
break ;
//TODO: implement after loading curves is added; warning will be generated during modifier applying
case 2 : //FITCURVE
break ;
//TODO: implement after loading curves is added; warning will be generated during modifier applying
default :
break ;
assert false : "Unknown array modifier fit type: " + fittype ;
default :
}
assert false : "Unknown array modifier fit type: " + fittype ;
}
//offset parameters
int offsettype = ( ( Number ) modifier . getFieldValue ( "offset_type" ) ) . intValue ( ) ;
//offset parameters
if ( ( offsettype & 0x01 ) ! = 0 ) { //Constant offset
int offsettype = ( ( Number ) modifier . getFieldValue ( "offset_type" ) ) . intValue ( ) ;
DynamicArray < Number > offsetArray = ( DynamicArray < Number > ) modifier . getFieldValue ( "offset" ) ;
if ( ( offsettype & 0x01 ) ! = 0 ) { //Constant offset
float [ ] offset = new float [ ] { offsetArray . get ( 0 ) . floatValue ( ) , offsetArray . get ( 1 ) . floatValue ( ) , offsetArray . get ( 2 ) . floatValue ( ) } ;
DynamicArray < Number > offsetArray = ( DynamicArray < Number > ) modifier . getFieldValue ( "offset" ) ;
params . put ( "offset" , offset ) ;
float [ ] offset = new float [ ] { offsetArray . get ( 0 ) . floatValue ( ) , offsetArray . get ( 1 ) . floatValue ( ) , offsetArray . get ( 2 ) . floatValue ( ) } ;
}
params . put ( "offset" , offset ) ;
if ( ( offsettype & 0x02 ) ! = 0 ) { //Relative offset
}
DynamicArray < Number > scaleArray = ( DynamicArray < Number > ) modifier . getFieldValue ( "scale" ) ;
if ( ( offsettype & 0x02 ) ! = 0 ) { //Relative offset
float [ ] scale = new float [ ] { scaleArray . get ( 0 ) . floatValue ( ) , scaleArray . get ( 1 ) . floatValue ( ) , scaleArray . get ( 2 ) . floatValue ( ) } ;
DynamicArray < Number > scaleArray = ( DynamicArray < Number > ) modifier . getFieldValue ( "scale" ) ;
params . put ( "scale" , scale ) ;
float [ ] scale = new float [ ] { scaleArray . get ( 0 ) . floatValue ( ) , scaleArray . get ( 1 ) . floatValue ( ) , scaleArray . get ( 2 ) . floatValue ( ) } ;
}
params . put ( "scale" , scale ) ;
if ( ( offsettype & 0x04 ) ! = 0 ) { //Object offset
}
Pointer pOffsetObject = ( Pointer ) modifier . getFieldValue ( "offset_ob" ) ;
if ( ( offsettype & 0x04 ) ! = 0 ) { //Object offset
if ( ! pOffsetObject . isNull ( ) ) {
Pointer pOffsetObject = ( Pointer ) modifier . getFieldValue ( "offset_ob" ) ;
params . put ( "offsetob" , pOffsetObject ) ;
if ( ! pOffsetObject . isNull ( ) ) {
}
params . put ( "offsetob" , pOffsetObject ) ;
}
}
}
//start cap and end cap
Pointer pStartCap = ( Pointer ) modifier . getFieldValue ( "start_cap" ) ;
//start cap and end cap
if ( ! pStartCap . isNull ( ) ) {
Pointer pStartCap = ( Pointer ) modifier . getFieldValue ( "start_cap" ) ;
params . put ( "startcap" , pStartCap ) ;
if ( ! pStartCap . isNull ( ) ) {
}
params . put ( "startcap" , pStartCap ) ;
Pointer pEndCap = ( Pointer ) modifier . getFieldValue ( "end_cap" ) ;
}
if ( ! pEndCap . isNull ( ) ) {
Pointer pEndCap = ( Pointer ) modifier . getFieldValue ( "end_cap" ) ;
params . put ( "endcap" , pEndCap ) ;
if ( ! pEndCap . isNull ( ) ) {
}
params . put ( "endcap" , pEndCap ) ;
loadedModifier = params ;
}
} else if ( Modifier . ARMATURE_MODIFIER_DATA . equals ( modifier . getType ( ) ) ) { //****************ARMATURE MODIFIER
loadedModifier = params ;
Pointer pArmatureObject = ( Pointer ) modifier . getFieldValue ( "object" ) ;
} else if ( Modifier . ARMATURE_MODIFIER_DATA . equals ( modifier . getType ( ) ) ) { //****************ARMATURE MODIFIER
if ( ! pArmatureObject . isNull ( ) ) {
Pointer pArmatureObject = ( Pointer ) modifier . getFieldValue ( "object" ) ;
ObjectHelper objectHelper = dataRepository . getHelper ( ObjectHelper . class ) ;
if ( ! pArmatureObject . isNull ( ) ) {
Structure armatureObject = ( Structure ) dataRepository . getLoadedFeature ( pArmatureObject . getOldMemoryAddress ( ) , LoadedFeatureDataType . LOADED_STRUCTURE ) ;
ObjectHelper objectHelper = dataRepository . getHelper ( ObjectHelper . class ) ;
if ( armatureObject = = null ) { //we check this first not to fetch the structure unnecessary
Structure armatureObject = ( Structure ) dataRepository . getLoadedFeature ( pArmatureObject . getOldMemoryAddress ( ) , LoadedFeatureDataType . LOADED_STRUCTURE ) ;
armatureObject = pArmatureObject . fetchData ( dataRepository . getInputStream ( ) ) . get ( 0 ) ;
if ( armatureObject = = null ) { //we check this first not to fetch the structure unnecessary
objectHelper . toObject ( armatureObject , dataRepository ) ;
armatureObject = pArmatureObject . fetchData ( dataRepository . getInputStream ( ) ) . get ( 0 ) ;
}
objectHelper . toObject ( armatureObject , dataRepository ) ;
modifierAdditionalData = armatureObject . getOldMemoryAddress ( ) ;
}
ArmatureHelper armatureHelper = dataRepository . getHelper ( ArmatureHelper . class ) ;
modifierAdditionalData = armatureObject . getOldMemoryAddress ( ) ;
ArmatureHelper armatureHelper = dataRepository . getHelper ( ArmatureHelper . class ) ;
//changing bones matrices so that they fit the current object (taht is why we need a copy of a skeleton)
Matrix4f armatureObjectMatrix = objectHelper . getTransformationMatrix ( armatureObject ) ;
//changing bones matrices so that they fit the current object (taht is why we need a copy of a skeleton)
Matrix4f inverseMeshObjectMatrix = objectHelper . getTransformationMatrix ( objectStructure ) . invert ( ) ;
Matrix4f armatureObjectMatrix = objectHelper . getTransformationMatrix ( armatureObject ) ;
Matrix4f additionalRootBoneTransformation = inverseMeshObjectMatrix . multLocal ( armatureObjectMatrix ) ;
Matrix4f inverseMeshObjectMatrix = objectHelper . getTransformationMatrix ( objectStructure ) . invert ( ) ;
Bone [ ] bones = armatureHelper . buildBonesStructure ( Long . valueOf ( 0L ) , additionalRootBoneTransformation ) ;
Matrix4f additionalRootBoneTransformation = inverseMeshObjectMatrix . multLocal ( armatureObjectMatrix ) ;
Bone [ ] bones = armatureHelper . buildBonesStructure ( Long . valueOf ( 0L ) , additionalRootBoneTransformation ) ;
String objectName = objectStructure . getName ( ) ;
Set < String > animationNames = dataRepository . getBlenderKey ( ) . getAnimationNames ( objectName ) ;
String objectName = objectStructure . getName ( ) ;
if ( animationNames ! = null & & animationNames . size ( ) > 0 ) {
Set < String > animationNames = dataRepository . getBlenderKey ( ) . getAnimationNames ( objectName ) ;
ArrayList < BoneAnimation > animations = new ArrayList < BoneAnimation > ( ) ;
if ( animationNames ! = null & & animationNames . size ( ) > 0 ) {
List < FileBlockHeader > actionHeaders = dataRepository . getFileBlocks ( Integer . valueOf ( FileBlockHeader . BLOCK_AC00 ) ) ;
ArrayList < BoneAnimation > animations = new ArrayList < BoneAnimation > ( ) ;
for ( FileBlockHeader header : actionHeaders ) {
List < FileBlockHeader > actionHeaders = dataRepository . getFileBlocks ( Integer . valueOf ( FileBlockHeader . BLOCK_AC00 ) ) ;
Structure actionStructure = header . getStructure ( dataRepository ) ;
for ( FileBlockHeader header : actionHeaders ) {
String actionName = actionStructure . getName ( ) ;
Structure actionStructure = header . getStructure ( dataRepository ) ;
if ( animationNames . contains ( actionName ) ) {
String actionName = actionStructure . getName ( ) ;
int [ ] animationFrames = dataRepository . getBlenderKey ( ) . getAnimationFrames ( objectName , actionName ) ;
if ( animationNames . contains ( actionName ) ) {
int fps = dataRepository . getBlenderKey ( ) . getFps ( ) ;
int [ ] animationFrames = dataRepository . getBlenderKey ( ) . getAnimationFrames ( objectName , actionName ) ;
float start = ( float ) animationFrames [ 0 ] / ( float ) fps ;
int fps = dataRepository . getBlenderKey ( ) . getFps ( ) ;
float stop = ( float ) animationFrames [ 1 ] / ( float ) fps ;
float start = ( float ) animationFrames [ 0 ] / ( float ) fps ;
BoneAnimation boneAnimation = new BoneAnimation ( actionName , stop - start ) ;
float stop = ( float ) animationFrames [ 1 ] / ( float ) fps ;
boneAnimation . setTracks ( armatureHelper . getTracks ( actionStructure , dataRepository , objectName , actionName ) ) ;
BoneAnimation boneAnimation = new BoneAnimation ( actionName , stop - start ) ;
animations . add ( boneAnimation ) ;
boneAnimation . setTracks ( armatureHelper . getTracks ( actionStructure , dataRepository , objectName , actionName ) ) ;
}
animations . add ( boneAnimation ) ;
}
}
loadedModifier = new AnimData ( new Skeleton ( bones ) , animations ) ;
}
}
loadedModifier = new AnimData ( new Skeleton ( bones ) , animations ) ;
} else {
}
LOGGER . warning ( "Unsupported modifier type: " + modifier . getType ( ) ) ;
} else {
}
LOGGER . warning ( "Unsupported modifier type: " + modifier . getType ( ) ) ;
} else if ( Modifier . PARTICLE_MODIFIER_DATA . equals ( modifier . getType ( ) ) ) { //****************PARTICLES MODIFIER
}
Pointer pParticleSystem = ( Pointer ) modifier . getFieldValue ( "psys" ) ;
} else if ( Modifier . PARTICLE_MODIFIER_DATA . equals ( modifier . getType ( ) ) ) { //****************PARTICLES MODIFIER
if ( ! pParticleSystem . isNull ( ) ) {
Pointer pParticleSystem = ( Pointer ) modifier . getFieldValue ( "psys" ) ;
ParticlesHelper particlesHelper = dataRepository . getHelper ( ParticlesHelper . class ) ;
if ( ! pParticleSystem . isNull ( ) ) {
Structure particleSystem = pParticleSystem . fetchData ( dataRepository . getInputStream ( ) ) . get ( 0 ) ;
ParticlesHelper particlesHelper = dataRepository . getHelper ( ParticlesHelper . class ) ;
loadedModifier = particlesHelper . toParticleEmitter ( particleSystem , dataRepository ) ;
Structure particleSystem = pParticleSystem . fetchData ( dataRepository . getInputStream ( ) ) . get ( 0 ) ;
}
loadedModifier = particlesHelper . toParticleEmitter ( particleSystem , dataRepository ) ;
}
}
//adding modifier to the modifier's lists
}
if ( loadedModifier ! = null ) {
//adding modifier to the modifier's lists
dataRepository . addModifier ( objectStructure . getOldMemoryAddress ( ) , modifier . getType ( ) , loadedModifier , modifierAdditionalData ) ;
if ( loadedModifier ! = null ) {
modifierAdditionalData = null ;
dataRepository . addModifier ( objectStructure . getOldMemoryAddress ( ) , modifier . getType ( ) , loadedModifier , modifierAdditionalData ) ;
}
modifierAdditionalData = null ;
}
}
}
}
}
/ * *
* This method applies particles emitter to the given node .
/ * *
* @param node the particles emitter node
* This method applies particles emitter to the given node .
* @param modifier the modifier containing the emitter data
* @param node the particles emitter node
* @param dataRepository the data repository
* @param modifier the modifier containing the emitter data
* @return node with particles ' emitter applied
* @param dataRepository the data repository
* /
* @return node with particles ' emitter applied
protected Node applyParticleSystemModifierData ( Node node , Modifier modifier , DataRepository dataRepository ) {
* /
MaterialHelper materialHelper = dataRepository . getHelper ( MaterialHelper . class ) ;
protected Node applyParticleSystemModifierData ( Node node , Modifier modifier , DataRepository dataRepository ) {
ParticleEmitter emitter = ( ParticleEmitter ) modifier . getJmeModifierRepresentation ( ) ;
MaterialHelper materialHelper = dataRepository . getHelper ( MaterialHelper . class ) ;
emitter = emitter . clone ( ) ;
ParticleEmitter emitter = ( ParticleEmitter ) modifier . getJmeModifierRepresentation ( ) ;
emitter = emitter . clone ( ) ;
//veryfying the alpha function for particles' texture
Integer alphaFunction = MaterialHelper . ALPHA_MASK_HYPERBOLE ;
//veryfying the alpha function for particles' texture
char nameSuffix = emitter . getName ( ) . charAt ( emitter . getName ( ) . length ( ) - 1 ) ;
Integer alphaFunction = MaterialHelper . ALPHA_MASK_HYPERBOLE ;
if ( nameSuffix = = 'B' | | nameSuffix = = 'N' ) {
char nameSuffix = emitter . getName ( ) . charAt ( emitter . getName ( ) . length ( ) - 1 ) ;
alphaFunction = MaterialHelper . ALPHA_MASK_NONE ;
if ( nameSuffix = = 'B' | | nameSuffix = = 'N' ) {
}
alphaFunction = MaterialHelper . ALPHA_MASK_NONE ;
//removing the type suffix from the name
}
emitter . setName ( emitter . getName ( ) . substring ( 0 , emitter . getName ( ) . length ( ) - 1 ) ) ;
//removing the type suffix from the name
emitter . setName ( emitter . getName ( ) . substring ( 0 , emitter . getName ( ) . length ( ) - 1 ) ) ;
//applying emitter shape
EmitterShape emitterShape = emitter . getShape ( ) ;
//applying emitter shape
List < Mesh > meshes = new ArrayList < Mesh > ( ) ;
EmitterShape emitterShape = emitter . getShape ( ) ;
for ( Spatial spatial : node . getChildren ( ) ) {
List < Mesh > meshes = new ArrayList < Mesh > ( ) ;
if ( spatial instanceof Geometry ) {
for ( Spatial spatial : node . getChildren ( ) ) {
Mesh mesh = ( ( Geometry ) spatial ) . getMesh ( ) ;
if ( spatial instanceof Geometry ) {
if ( mesh ! = null ) {
Mesh mesh = ( ( Geometry ) spatial ) . getMesh ( ) ;
meshes . add ( mesh ) ;
if ( mesh ! = null ) {
Material material = materialHelper . getParticlesMaterial ( ( ( Geometry ) spatial ) . getMaterial ( ) , alphaFunction , dataRepository ) ;
meshes . add ( mesh ) ;
emitter . setMaterial ( material ) ; //TODO: divide into several pieces
Material material = materialHelper . getParticlesMaterial ( ( ( Geometry ) spatial ) . getMaterial ( ) , alphaFunction , dataRepository ) ;
}
emitter . setMaterial ( material ) ; //TODO: divide into several pieces
}
}
}
}
if ( meshes . size ( ) > 0 & & emitterShape instanceof EmitterMeshVertexShape ) {
}
( ( EmitterMeshVertexShape ) emitterShape ) . setMeshes ( meshes ) ;
if ( meshes . size ( ) > 0 & & emitterShape instanceof EmitterMeshVertexShape ) {
}
( ( EmitterMeshVertexShape ) emitterShape ) . setMeshes ( meshes ) ;
}
node . attachChild ( emitter ) ;
return node ;
node . attachChild ( emitter ) ;
}
return node ;
}
/ * *
* This method applies ArmatureModifierData to the loaded object .
/ * *
* @param node
* This method applies ArmatureModifierData to the loaded object .
* the loaded object
* @param node
* @param modifier
* the loaded object
* the modifier to apply
* @param modifier
* @param dataRepository
* the modifier to apply
* the data repository
* @param dataRepository
* @return the node to whom the modifier was applied
* the data repository
* /
* @return the node to whom the modifier was applied
protected Node applyArmatureModifierData ( Node node , Modifier modifier , DataRepository dataRepository ) {
* /
AnimData ad = ( AnimData ) modifier . getJmeModifierRepresentation ( ) ;
protected Node applyArmatureModifierData ( Node node , Modifier modifier , DataRepository dataRepository ) {
ArrayList < BoneAnimation > animList = ad . anims ;
AnimData ad = ( AnimData ) modifier . getJmeModifierRepresentation ( ) ;
Long modifierArmatureObject = ( Long ) modifier . getAdditionalData ( ) ;
ArrayList < BoneAnimation > animList = ad . anims ;
if ( animList ! = null & & animList . size ( ) > 0 ) {
Long modifierArmatureObject = ( Long ) modifier . getAdditionalData ( ) ;
ConstraintHelper constraintHelper = dataRepository . getHelper ( ConstraintHelper . class ) ;
if ( animList ! = null & & animList . size ( ) > 0 ) {
Constraint [ ] constraints = constraintHelper . getConstraints ( modifierArmatureObject ) ;
ConstraintHelper constraintHelper = dataRepository . getHelper ( ConstraintHelper . class ) ;
HashMap < String , BoneAnimation > anims = new HashMap < String , BoneAnimation > ( ) ;
Constraint [ ] constraints = constraintHelper . getConstraints ( modifierArmatureObject ) ;
for ( int i = 0 ; i < animList . size ( ) ; + + i ) {
HashMap < String , BoneAnimation > anims = new HashMap < String , BoneAnimation > ( ) ;
BoneAnimation boneAnimation = this . cloneBoneAnimation ( animList . get ( i ) ) ;
for ( int i = 0 ; i < animList . size ( ) ; + + i ) {
BoneAnimation boneAnimation = this . cloneBoneAnimation ( animList . get ( i ) ) ;
//baking constraints into animations
if ( constraints ! = null & & constraints . length > 0 ) {
//baking constraints into animations
for ( Constraint constraint : constraints ) {
if ( constraints ! = null & & constraints . length > 0 ) {
constraint . affectAnimation ( ad . skeleton , boneAnimation ) ;
for ( Constraint constraint : constraints ) {
}
constraint . affectAnimation ( ad . skeleton , boneAnimation ) ;
}
}
}
anims . put ( boneAnimation . getName ( ) , boneAnimation ) ;
}
anims . put ( boneAnimation . getName ( ) , boneAnimation ) ;
}
//getting meshes
Mesh [ ] meshes = null ;
//getting meshes
List < Mesh > meshesList = new ArrayList < Mesh > ( ) ;
Mesh [ ] meshes = null ;
List < Spatial > children = node . getChildren ( ) ;
List < Mesh > meshesList = new ArrayList < Mesh > ( ) ;
for ( Spatial child : children ) {
List < Spatial > children = node . getChildren ( ) ;
if ( child instanceof Geometry ) {
for ( Spatial child : children ) {
meshesList . add ( ( ( Geometry ) child ) . getMesh ( ) ) ;
if ( child instanceof Geometry ) {
}
meshesList . add ( ( ( Geometry ) child ) . getMesh ( ) ) ;
}
}
if ( meshesList . size ( ) > 0 ) {
}
meshes = meshesList . toArray ( new Mesh [ meshesList . size ( ) ] ) ;
if ( meshesList . size ( ) > 0 ) {
}
meshes = meshesList . toArray ( new Mesh [ meshesList . size ( ) ] ) ;
}
//applying the control to the node
SkeletonControl skeletonControl = new SkeletonControl ( meshes , ad . skeleton ) ;
//applying the control to the node
AnimControl control = node . getControl ( AnimControl . class ) ;
SkeletonControl skeletonControl = new SkeletonControl ( meshes , ad . skeleton ) ;
AnimControl control = node . getControl ( AnimControl . class ) ;
if ( control = = null ) {
control = new AnimControl ( ad . skeleton ) ;
if ( control = = null ) {
} else {
control = new AnimControl ( ad . skeleton ) ;
//merging skeletons
} else {
Skeleton controlSkeleton = control . getSkeleton ( ) ;
//merging skeletons
int boneIndexIncrease = controlSkeleton . getBoneCount ( ) ;
Skeleton controlSkeleton = control . getSkeleton ( ) ;
Skeleton skeleton = this . merge ( controlSkeleton , ad . skeleton ) ;
int boneIndexIncrease = controlSkeleton . getBoneCount ( ) ;
Skeleton skeleton = this . merge ( controlSkeleton , ad . skeleton ) ;
//merging animations
HashMap < String , BoneAnimation > animations = new HashMap < String , BoneAnimation > ( ) ;
//merging animations
for ( String animationName : control . getAnimationNames ( ) ) {
HashMap < String , BoneAnimation > animations = new HashMap < String , BoneAnimation > ( ) ;
animations . put ( animationName , control . getAnim ( animationName ) ) ;
for ( String animationName : control . getAnimationNames ( ) ) {
}
animations . put ( animationName , control . getAnim ( animationName ) ) ;
for ( Entry < String , BoneAnimation > animEntry : anims . entrySet ( ) ) {
}
BoneAnimation ba = animEntry . getValue ( ) ;
for ( Entry < String , BoneAnimation > animEntry : anims . entrySet ( ) ) {
for ( int i = 0 ; i < ba . getTracks ( ) . length ; + + i ) {
BoneAnimation ba = animEntry . getValue ( ) ;
BoneTrack bt = ba . getTracks ( ) [ i ] ;
for ( int i = 0 ; i < ba . getTracks ( ) . length ; + + i ) {
int newBoneIndex = bt . getTargetBoneIndex ( ) + boneIndexIncrease ;
BoneTrack bt = ba . getTracks ( ) [ i ] ;
ba . getTracks ( ) [ i ] = new BoneTrack ( newBoneIndex , bt . getTimes ( ) , bt . getTranslations ( ) , bt . getRotations ( ) , bt . getScales ( ) ) ;
int newBoneIndex = bt . getTargetBoneIndex ( ) + boneIndexIncrease ;
}
ba . getTracks ( ) [ i ] = new BoneTrack ( newBoneIndex , bt . getTimes ( ) , bt . getTranslations ( ) , bt . getRotations ( ) , bt . getScales ( ) ) ;
animations . put ( animEntry . getKey ( ) , animEntry . getValue ( ) ) ;
}
}
animations . put ( animEntry . getKey ( ) , animEntry . getValue ( ) ) ;
}
//replacing the control
node . removeControl ( control ) ;
//replacing the control
control = new AnimControl ( skeleton ) ;
node . removeControl ( control ) ;
}
control = new AnimControl ( skeleton ) ;
control . setAnimations ( anims ) ;
}
node . addControl ( control ) ;
control . setAnimations ( anims ) ;
node . addControl ( skeletonControl ) ;
node . addControl ( control ) ;
}
node . addControl ( skeletonControl ) ;
return node ;
}
}
return node ;
}
/ * *
* This method applies the array modifier to the node .
/ * *
* @param node
* This method applies the array modifier to the node .
* the object the modifier will be applied to
* @param node
* @param modifier
* the object the modifier will be applied to
* the modifier to be applied
* @param modifier
* @param dataRepository
* the modifier to be applied
* the data repository
* @param dataRepository
* @return object node with arry modifier applied
* the data repository
* /
* @return object node with arry modifier applied
@SuppressWarnings ( "unchecked" )
* /
protected Node applyArrayModifierData ( Node node , Modifier modifier , DataRepository dataRepository ) {
@SuppressWarnings ( "unchecked" )
Map < String , Object > modifierData = ( Map < String , Object > ) modifier . getJmeModifierRepresentation ( ) ;
protected Node applyArrayModifierData ( Node node , Modifier modifier , DataRepository dataRepository ) {
int fittype = ( ( Number ) modifierData . get ( "fittype" ) ) . intValue ( ) ;
Map < String , Object > modifierData = ( Map < String , Object > ) modifier . getJmeModifierRepresentation ( ) ;
float [ ] offset = ( float [ ] ) modifierData . get ( "offset" ) ;
int fittype = ( ( Number ) modifierData . get ( "fittype" ) ) . intValue ( ) ;
if ( offset = = null ) { //the node will be repeated several times in the same place
float [ ] offset = ( float [ ] ) modifierData . get ( "offset" ) ;
offset = new float [ ] { 0 . 0f , 0 . 0f , 0 . 0f } ;
if ( offset = = null ) { //the node will be repeated several times in the same place
}
offset = new float [ ] { 0 . 0f , 0 . 0f , 0 . 0f } ;
float [ ] scale = ( float [ ] ) modifierData . get ( "scale" ) ;
}
if ( scale = = null ) { //the node will be repeated several times in the same place
float [ ] scale = ( float [ ] ) modifierData . get ( "scale" ) ;
scale = new float [ ] { 0 . 0f , 0 . 0f , 0 . 0f } ;
if ( scale = = null ) { //the node will be repeated several times in the same place
} else {
scale = new float [ ] { 0 . 0f , 0 . 0f , 0 . 0f } ;
//getting bounding box
} else {
node . updateModelBound ( ) ;
//getting bounding box
BoundingVolume boundingVolume = node . getWorldBound ( ) ;
node . updateModelBound ( ) ;
if ( boundingVolume instanceof BoundingBox ) {
BoundingVolume boundingVolume = node . getWorldBound ( ) ;
scale [ 0 ] * = ( ( BoundingBox ) boundingVolume ) . getXExtent ( ) * 2 . 0f ;
if ( boundingVolume instanceof BoundingBox ) {
scale [ 1 ] * = ( ( BoundingBox ) boundingVolume ) . getYExtent ( ) * 2 . 0f ;
scale [ 0 ] * = ( ( BoundingBox ) boundingVolume ) . getXExtent ( ) * 2 . 0f ;
scale [ 2 ] * = ( ( BoundingBox ) boundingVolume ) . getZExtent ( ) * 2 . 0f ;
scale [ 1 ] * = ( ( BoundingBox ) boundingVolume ) . getYExtent ( ) * 2 . 0f ;
} else if ( boundingVolume instanceof BoundingSphere ) {
scale [ 2 ] * = ( ( BoundingBox ) boundingVolume ) . getZExtent ( ) * 2 . 0f ;
float radius = ( ( BoundingSphere ) boundingVolume ) . getRadius ( ) ;
} else if ( boundingVolume instanceof BoundingSphere ) {
scale [ 0 ] * = radius * 2 . 0f ;
float radius = ( ( BoundingSphere ) boundingVolume ) . getRadius ( ) ;
scale [ 1 ] * = radius * 2 . 0f ;
scale [ 0 ] * = radius * 2 . 0f ;
scale [ 2 ] * = radius * 2 . 0f ;
scale [ 1 ] * = radius * 2 . 0f ;
} else {
scale [ 2 ] * = radius * 2 . 0f ;
throw new IllegalStateException ( "Unknown bounding volume type: " + boundingVolume . getClass ( ) . getName ( ) ) ;
} else {
}
throw new IllegalStateException ( "Unknown bounding volume type: " + boundingVolume . getClass ( ) . getName ( ) ) ;
}
}
}
//adding object's offset
float [ ] objectOffset = new float [ ] { 0 . 0f , 0 . 0f , 0 . 0f } ;
//adding object's offset
Pointer pOffsetObject = ( Pointer ) modifierData . get ( "offsetob" ) ;
float [ ] objectOffset = new float [ ] { 0 . 0f , 0 . 0f , 0 . 0f } ;
if ( pOffsetObject ! = null ) {
Pointer pOffsetObject = ( Pointer ) modifierData . get ( "offsetob" ) ;
FileBlockHeader offsetObjectBlock = dataRepository . getFileBlock ( pOffsetObject . getOldMemoryAddress ( ) ) ;
if ( pOffsetObject ! = null ) {
ObjectHelper objectHelper = dataRepository . getHelper ( ObjectHelper . class ) ;
FileBlockHeader offsetObjectBlock = dataRepository . getFileBlock ( pOffsetObject . getOldMemoryAddress ( ) ) ;
try { //we take the structure in case the object was not yet loaded
ObjectHelper objectHelper = dataRepository . getHelper ( ObjectHelper . class ) ;
Structure offsetStructure = offsetObjectBlock . getStructure ( dataRepository ) ;
try { //we take the structure in case the object was not yet loaded
Vector3f translation = objectHelper . getTransformation ( offsetStructure ) . getTranslation ( ) ;
Structure offsetStructure = offsetObjectBlock . getStructure ( dataRepository ) ;
objectOffset [ 0 ] = translation . x ;
Vector3f translation = objectHelper . getTransformation ( offsetStructure ) . getTranslation ( ) ;
objectOffset [ 1 ] = translation . y ;
objectOffset [ 0 ] = translation . x ;
objectOffset [ 2 ] = translation . z ;
objectOffset [ 1 ] = translation . y ;
} catch ( BlenderFileException e ) {
objectOffset [ 2 ] = translation . z ;
LOGGER . warning ( "Problems in blender file structure! Object offset cannot be applied! The problem: " + e . getMessage ( ) ) ;
} catch ( BlenderFileException e ) {
}
LOGGER . warning ( "Problems in blender file structure! Object offset cannot be applied! The problem: " + e . getMessage ( ) ) ;
}
}
}
//getting start and end caps
Node [ ] caps = new Node [ ] { null , null } ;
//getting start and end caps
Pointer [ ] pCaps = new Pointer [ ] { ( Pointer ) modifierData . get ( "startcap" ) , ( Pointer ) modifierData . get ( "endcap" ) } ;
Node [ ] caps = new Node [ ] { null , null } ;
for ( int i = 0 ; i < pCaps . length ; + + i ) {
Pointer [ ] pCaps = new Pointer [ ] { ( Pointer ) modifierData . get ( "startcap" ) , ( Pointer ) modifierData . get ( "endcap" ) } ;
if ( pCaps [ i ] ! = null ) {
for ( int i = 0 ; i < pCaps . length ; + + i ) {
caps [ i ] = ( Node ) dataRepository . getLoadedFeature ( pCaps [ i ] . getOldMemoryAddress ( ) , LoadedFeatureDataType . LOADED_FEATURE ) ;
if ( pCaps [ i ] ! = null ) {
if ( caps [ i ] ! = null ) {
caps [ i ] = ( Node ) dataRepository . getLoadedFeature ( pCaps [ i ] . getOldMemoryAddress ( ) , LoadedFeatureDataType . LOADED_FEATURE ) ;
caps [ i ] = ( Node ) caps [ i ] . clone ( ) ;
if ( caps [ i ] ! = null ) {
} else {
caps [ i ] = ( Node ) caps [ i ] . clone ( ) ;
FileBlockHeader capBlock = dataRepository . getFileBlock ( pOffsetObject . getOldMemoryAddress ( ) ) ;
} else {
try { //we take the structure in case the object was not yet loaded
FileBlockHeader capBlock = dataRepository . getFileBlock ( pOffsetObject . getOldMemoryAddress ( ) ) ;
Structure capStructure = capBlock . getStructure ( dataRepository ) ;
try { //we take the structure in case the object was not yet loaded
ObjectHelper objectHelper = dataRepository . getHelper ( ObjectHelper . class ) ;
Structure capStructure = capBlock . getStructure ( dataRepository ) ;
caps [ i ] = ( Node ) objectHelper . toObject ( capStructure , dataRepository ) ;
ObjectHelper objectHelper = dataRepository . getHelper ( ObjectHelper . class ) ;
if ( caps [ i ] = = null ) {
caps [ i ] = ( Node ) objectHelper . toObject ( capStructure , dataRepository ) ;
LOGGER . warning ( "Cap object '" + capStructure . getName ( ) + "' couldn't be loaded!" ) ;
if ( caps [ i ] = = null ) {
}
LOGGER . warning ( "Cap object '" + capStructure . getName ( ) + "' couldn't be loaded!" ) ;
} catch ( BlenderFileException e ) {
}
LOGGER . warning ( "Problems in blender file structure! Cap object cannot be applied! The problem: " + e . getMessage ( ) ) ;
} catch ( BlenderFileException e ) {
}
LOGGER . warning ( "Problems in blender file structure! Cap object cannot be applied! The problem: " + e . getMessage ( ) ) ;
}
}
}
}
}
}
}
Vector3f translationVector = new Vector3f ( offset [ 0 ] + scale [ 0 ] + objectOffset [ 0 ] ,
offset [ 1 ] + scale [ 1 ] + objectOffset [ 1 ] ,
Vector3f translationVector = new Vector3f ( offset [ 0 ] + scale [ 0 ] + objectOffset [ 0 ] ,
offset [ 2 ] + scale [ 2 ] + objectOffset [ 2 ] ) ;
offset [ 1 ] + scale [ 1 ] + objectOffset [ 1 ] ,
offset [ 2 ] + scale [ 2 ] + objectOffset [ 2 ] ) ;
//getting/calculating repeats amount
int count = 0 ;
//getting/calculating repeats amount
if ( fittype = = 0 ) { //Fixed count
int count = 0 ;
count = ( ( Number ) modifierData . get ( "count" ) ) . intValue ( ) - 1 ;
if ( fittype = = 0 ) { //Fixed count
} else if ( fittype = = 1 ) { //Fixed length
count = ( ( Number ) modifierData . get ( "count" ) ) . intValue ( ) - 1 ;
float length = ( ( Number ) modifierData . get ( "length" ) ) . floatValue ( ) ;
} else if ( fittype = = 1 ) { //Fixed length
if ( translationVector . length ( ) > 0 . 0f ) {
float length = ( ( Number ) modifierData . get ( "length" ) ) . floatValue ( ) ;
count = ( int ) ( length / translationVector . length ( ) ) - 1 ;
if ( translationVector . length ( ) > 0 . 0f ) {
}
count = ( int ) ( length / translationVector . length ( ) ) - 1 ;
} else if ( fittype = = 2 ) { //Fit curve
}
LOGGER . warning ( "Fit curve mode in array modifier not yet implemented!" ) ; //TODO: implement fit curve
} else if ( fittype = = 2 ) { //Fit curve
} else {
LOGGER . warning ( "Fit curve mode in array modifier not yet implemented!" ) ; //TODO: implement fit curve
throw new IllegalStateException ( "Unknown fit type: " + fittype ) ;
} else {
}
throw new IllegalStateException ( "Unknown fit type: " + fittype ) ;
}
//adding translated nodes and caps
if ( count > 0 ) {
//adding translated nodes and caps
Node [ ] arrayNodes = new Node [ count ] ;
if ( count > 0 ) {
Vector3f newTranslation = node . getLocalTranslation ( ) . clone ( ) ;
Node [ ] arrayNodes = new Node [ count ] ;
for ( int i = 0 ; i < count ; + + i ) {
Vector3f newTranslation = node . getLocalTranslation ( ) . clone ( ) ;
newTranslation . addLocal ( translationVector ) ;
for ( int i = 0 ; i < count ; + + i ) {
Node nodeClone = ( Node ) node . clone ( ) ;
newTranslation . addLocal ( translationVector ) ;
nodeClone . setLocalTranslation ( newTranslation ) ;
Node nodeClone = ( Node ) node . clone ( ) ;
arrayNodes [ i ] = nodeClone ;
nodeClone . setLocalTranslation ( newTranslation ) ;
}
arrayNodes [ i ] = nodeClone ;
for ( Node nodeClone : arrayNodes ) {
}
node . attachChild ( nodeClone ) ;
for ( Node nodeClone : arrayNodes ) {
}
node . attachChild ( nodeClone ) ;
if ( caps [ 0 ] ! = null ) {
}
caps [ 0 ] . getLocalTranslation ( ) . set ( node . getLocalTranslation ( ) ) . subtractLocal ( translationVector ) ;
if ( caps [ 0 ] ! = null ) {
node . attachChild ( caps [ 0 ] ) ;
caps [ 0 ] . getLocalTranslation ( ) . set ( node . getLocalTranslation ( ) ) . subtractLocal ( translationVector ) ;
}
node . attachChild ( caps [ 0 ] ) ;
if ( caps [ 1 ] ! = null ) {
}
caps [ 1 ] . getLocalTranslation ( ) . set ( newTranslation ) . addLocal ( translationVector ) ;
if ( caps [ 1 ] ! = null ) {
node . attachChild ( caps [ 1 ] ) ;
caps [ 1 ] . getLocalTranslation ( ) . set ( newTranslation ) . addLocal ( translationVector ) ;
}
node . attachChild ( caps [ 1 ] ) ;
}
}
return node ;
}
}
return node ;
}
/ * *
* This class clones the bone animation data .
/ * *
* @param source
* This class clones the bone animation data .
* the source that is to be cloned
* @param source
* @return the copy of the given bone animation
* the source that is to be cloned
* /
* @return the copy of the given bone animation
protected BoneAnimation cloneBoneAnimation ( BoneAnimation source ) {
* /
BoneAnimation result = new BoneAnimation ( source . getName ( ) , source . getLength ( ) ) ;
protected BoneAnimation cloneBoneAnimation ( BoneAnimation source ) {
BoneAnimation result = new BoneAnimation ( source . getName ( ) , source . getLength ( ) ) ;
//copying tracks and applying constraints
BoneTrack [ ] sourceTracks = source . getTracks ( ) ;
//copying tracks and applying constraints
BoneTrack [ ] boneTracks = new BoneTrack [ sourceTracks . length ] ;
BoneTrack [ ] sourceTracks = source . getTracks ( ) ;
for ( int i = 0 ; i < sourceTracks . length ; + + i ) {
BoneTrack [ ] boneTracks = new BoneTrack [ sourceTracks . length ] ;
int tablesLength = sourceTracks [ i ] . getTimes ( ) . length ;
for ( int i = 0 ; i < sourceTracks . length ; + + i ) {
int tablesLength = sourceTracks [ i ] . getTimes ( ) . length ;
Vector3f [ ] sourceTranslations = sourceTracks [ i ] . getTranslations ( ) ;
Quaternion [ ] sourceRotations = sourceTracks [ i ] . getRotations ( ) ;
Vector3f [ ] sourceTranslations = sourceTracks [ i ] . getTranslations ( ) ;
Vector3f [ ] sourceScales = sourceTracks [ i ] . getScales ( ) ;
Quaternion [ ] sourceRotations = sourceTracks [ i ] . getRotations ( ) ;
Vector3f [ ] sourceScales = sourceTracks [ i ] . getScales ( ) ;
Vector3f [ ] translations = new Vector3f [ tablesLength ] ;
Quaternion [ ] rotations = new Quaternion [ tablesLength ] ;
Vector3f [ ] translations = new Vector3f [ tablesLength ] ;
Vector3f [ ] scales = sourceScales = = null ? null : new Vector3f [ tablesLength ] ;
Quaternion [ ] rotations = new Quaternion [ tablesLength ] ;
for ( int j = 0 ; j < tablesLength ; + + j ) {
Vector3f [ ] scales = sourceScales = = null ? null : new Vector3f [ tablesLength ] ;
translations [ j ] = sourceTranslations [ j ] . clone ( ) ;
for ( int j = 0 ; j < tablesLength ; + + j ) {
rotations [ j ] = sourceRotations [ j ] . clone ( ) ;
translations [ j ] = sourceTranslations [ j ] . clone ( ) ;
if ( sourceScales ! = null ) { //only scales may not be applied
rotations [ j ] = sourceRotations [ j ] . clone ( ) ;
scales [ j ] = sourceScales [ j ] . clone ( ) ;
if ( sourceScales ! = null ) { //only scales may not be applied
}
scales [ j ] = sourceScales [ j ] . clone ( ) ;
}
}
boneTracks [ i ] = new BoneTrack ( sourceTracks [ i ] . getTargetBoneIndex ( ) , sourceTracks [ i ] . getTimes ( ) , //times do not change, no need to clone them,
}
translations , rotations , scales ) ;
boneTracks [ i ] = new BoneTrack ( sourceTracks [ i ] . getTargetBoneIndex ( ) , sourceTracks [ i ] . getTimes ( ) , //times do not change, no need to clone them,
}
translations , rotations , scales ) ;
result . setTracks ( boneTracks ) ;
}
return result ;
result . setTracks ( boneTracks ) ;
}
return result ;
}
/ * *
* This method merges two skeletons into one . I assume that each skeleton ' s 0 - indexed bone is objectAnimationBone so
/ * *
* only one such bone should be placed in the result
* This method merges two skeletons into one . I assume that each skeleton ' s 0 - indexed bone is objectAnimationBone so
* @param s1
* only one such bone should be placed in the result
* first skeleton
* @param s1
* @param s2
* first skeleton
* second skeleton
* @param s2
* @return merged skeleton
* second skeleton
* /
* @return merged skeleton
protected Skeleton merge ( Skeleton s1 , Skeleton s2 ) {
* /
List < Bone > bones = new ArrayList < Bone > ( s1 . getBoneCount ( ) + s2 . getBoneCount ( ) ) ;
protected Skeleton merge ( Skeleton s1 , Skeleton s2 ) {
for ( int i = 0 ; i < s1 . getBoneCount ( ) ; + + i ) {
List < Bone > bones = new ArrayList < Bone > ( s1 . getBoneCount ( ) + s2 . getBoneCount ( ) ) ;
bones . add ( s1 . getBone ( i ) ) ;
for ( int i = 0 ; i < s1 . getBoneCount ( ) ; + + i ) {
}
bones . add ( s1 . getBone ( i ) ) ;
for ( int i = 1 ; i < s2 . getBoneCount ( ) ; + + i ) { //ommit objectAnimationBone
}
bones . add ( s2 . getBone ( i ) ) ;
for ( int i = 1 ; i < s2 . getBoneCount ( ) ; + + i ) { //ommit objectAnimationBone
}
bones . add ( s2 . getBone ( i ) ) ;
return new Skeleton ( bones . toArray ( new Bone [ bones . size ( ) ] ) ) ;
}
}
return new Skeleton ( bones . toArray ( new Bone [ bones . size ( ) ] ) ) ;
}
}
}