|
|
@ -60,7 +60,6 @@ import com.jme3.scene.Geometry; |
|
|
|
import com.jme3.scene.Mesh; |
|
|
|
import com.jme3.scene.Mesh; |
|
|
|
import com.jme3.scene.Node; |
|
|
|
import com.jme3.scene.Node; |
|
|
|
import com.jme3.scene.Spatial; |
|
|
|
import com.jme3.scene.Spatial; |
|
|
|
import com.jme3.scene.VertexBuffer; |
|
|
|
|
|
|
|
import com.jme3.scene.VertexBuffer.Type; |
|
|
|
import com.jme3.scene.VertexBuffer.Type; |
|
|
|
import com.jme3.scene.plugins.blender.data.FileBlockHeader; |
|
|
|
import com.jme3.scene.plugins.blender.data.FileBlockHeader; |
|
|
|
import com.jme3.scene.plugins.blender.data.Structure; |
|
|
|
import com.jme3.scene.plugins.blender.data.Structure; |
|
|
@ -110,7 +109,7 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
return this.applyArrayModifierData(node, modifier, dataRepository); |
|
|
|
return this.applyArrayModifierData(node, modifier, dataRepository); |
|
|
|
} else if (Modifier.PARTICLE_MODIFIER_DATA.equals(modifier.getType())) { |
|
|
|
} else if (Modifier.PARTICLE_MODIFIER_DATA.equals(modifier.getType())) { |
|
|
|
return this.applyParticleSystemModifierData(node, modifier, dataRepository); |
|
|
|
return this.applyParticleSystemModifierData(node, modifier, dataRepository); |
|
|
|
} else if(Modifier.MIRROR_MODIFIER_DATA.equals(modifier.getType())) { |
|
|
|
} else if (Modifier.MIRROR_MODIFIER_DATA.equals(modifier.getType())) { |
|
|
|
return this.applyMirrorModifierData(node, modifier, dataRepository); |
|
|
|
return this.applyMirrorModifierData(node, modifier, dataRepository); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
LOGGER.warning("Modifier: " + modifier.getType() + " not yet implemented!!!"); |
|
|
|
LOGGER.warning("Modifier: " + modifier.getType() + " not yet implemented!!!"); |
|
|
@ -136,45 +135,45 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
for (Structure modifier : modifiers) { |
|
|
|
for (Structure modifier : modifiers) { |
|
|
|
Object loadedModifier = null; |
|
|
|
Object loadedModifier = null; |
|
|
|
Object modifierAdditionalData = null; |
|
|
|
Object modifierAdditionalData = null; |
|
|
|
if (Modifier.ARRAY_MODIFIER_DATA.equals(modifier.getType())) {//****************ARRAY MODIFIER
|
|
|
|
if (Modifier.ARRAY_MODIFIER_DATA.equals(modifier.getType())) {// ****************ARRAY MODIFIER
|
|
|
|
Map<String, Object> params = new HashMap<String, Object>(); |
|
|
|
Map<String, Object> params = new HashMap<String, Object>(); |
|
|
|
|
|
|
|
|
|
|
|
Number fittype = (Number) modifier.getFieldValue("fit_type"); |
|
|
|
Number fittype = (Number) modifier.getFieldValue("fit_type"); |
|
|
|
params.put("fittype", fittype); |
|
|
|
params.put("fittype", fittype); |
|
|
|
switch (fittype.intValue()) { |
|
|
|
switch (fittype.intValue()) { |
|
|
|
case 0://FIXED COUNT
|
|
|
|
case 0:// FIXED COUNT
|
|
|
|
params.put("count", modifier.getFieldValue("count")); |
|
|
|
params.put("count", modifier.getFieldValue("count")); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 1://FIXED LENGTH
|
|
|
|
case 1:// FIXED LENGTH
|
|
|
|
params.put("length", modifier.getFieldValue("length")); |
|
|
|
params.put("length", modifier.getFieldValue("length")); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 2://FITCURVE
|
|
|
|
case 2:// FITCURVE
|
|
|
|
//TODO: implement after loading curves is added; warning will be generated during modifier applying
|
|
|
|
// TODO: implement after loading curves is added; warning will be generated during modifier applying
|
|
|
|
break; |
|
|
|
break; |
|
|
|
default: |
|
|
|
default: |
|
|
|
assert false : "Unknown array modifier fit type: " + fittype; |
|
|
|
assert false : "Unknown array modifier fit type: " + fittype; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//offset parameters
|
|
|
|
// offset parameters
|
|
|
|
int offsettype = ((Number) modifier.getFieldValue("offset_type")).intValue(); |
|
|
|
int offsettype = ((Number) modifier.getFieldValue("offset_type")).intValue(); |
|
|
|
if ((offsettype & 0x01) != 0) {//Constant offset
|
|
|
|
if ((offsettype & 0x01) != 0) {// Constant offset
|
|
|
|
DynamicArray<Number> offsetArray = (DynamicArray<Number>) modifier.getFieldValue("offset"); |
|
|
|
DynamicArray<Number> offsetArray = (DynamicArray<Number>) modifier.getFieldValue("offset"); |
|
|
|
float[] offset = new float[]{offsetArray.get(0).floatValue(), offsetArray.get(1).floatValue(), offsetArray.get(2).floatValue()}; |
|
|
|
float[] offset = new float[] { offsetArray.get(0).floatValue(), offsetArray.get(1).floatValue(), offsetArray.get(2).floatValue() }; |
|
|
|
params.put("offset", offset); |
|
|
|
params.put("offset", offset); |
|
|
|
} |
|
|
|
} |
|
|
|
if ((offsettype & 0x02) != 0) {//Relative offset
|
|
|
|
if ((offsettype & 0x02) != 0) {// Relative offset
|
|
|
|
DynamicArray<Number> scaleArray = (DynamicArray<Number>) modifier.getFieldValue("scale"); |
|
|
|
DynamicArray<Number> scaleArray = (DynamicArray<Number>) modifier.getFieldValue("scale"); |
|
|
|
float[] scale = new float[]{scaleArray.get(0).floatValue(), scaleArray.get(1).floatValue(), scaleArray.get(2).floatValue()}; |
|
|
|
float[] scale = new float[] { scaleArray.get(0).floatValue(), scaleArray.get(1).floatValue(), scaleArray.get(2).floatValue() }; |
|
|
|
params.put("scale", scale); |
|
|
|
params.put("scale", scale); |
|
|
|
} |
|
|
|
} |
|
|
|
if ((offsettype & 0x04) != 0) {//Object offset
|
|
|
|
if ((offsettype & 0x04) != 0) {// Object offset
|
|
|
|
Pointer pOffsetObject = (Pointer) modifier.getFieldValue("offset_ob"); |
|
|
|
Pointer pOffsetObject = (Pointer) modifier.getFieldValue("offset_ob"); |
|
|
|
if (!pOffsetObject.isNull()) { |
|
|
|
if (!pOffsetObject.isNull()) { |
|
|
|
params.put("offsetob", pOffsetObject); |
|
|
|
params.put("offsetob", pOffsetObject); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//start cap and end cap
|
|
|
|
// start cap and end cap
|
|
|
|
Pointer pStartCap = (Pointer) modifier.getFieldValue("start_cap"); |
|
|
|
Pointer pStartCap = (Pointer) modifier.getFieldValue("start_cap"); |
|
|
|
if (!pStartCap.isNull()) { |
|
|
|
if (!pStartCap.isNull()) { |
|
|
|
params.put("startcap", pStartCap); |
|
|
|
params.put("startcap", pStartCap); |
|
|
@ -184,7 +183,8 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
params.put("endcap", pEndCap); |
|
|
|
params.put("endcap", pEndCap); |
|
|
|
} |
|
|
|
} |
|
|
|
loadedModifier = params; |
|
|
|
loadedModifier = params; |
|
|
|
} if (Modifier.MIRROR_MODIFIER_DATA.equals(modifier.getType())) {//****************MIRROR MODIFIER
|
|
|
|
} |
|
|
|
|
|
|
|
if (Modifier.MIRROR_MODIFIER_DATA.equals(modifier.getType())) {// ****************MIRROR MODIFIER
|
|
|
|
Map<String, Object> params = new HashMap<String, Object>(); |
|
|
|
Map<String, Object> params = new HashMap<String, Object>(); |
|
|
|
|
|
|
|
|
|
|
|
params.put("flag", modifier.getFieldValue("flag")); |
|
|
|
params.put("flag", modifier.getFieldValue("flag")); |
|
|
@ -194,19 +194,19 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
params.put("mirrorob", pMirrorOb); |
|
|
|
params.put("mirrorob", pMirrorOb); |
|
|
|
} |
|
|
|
} |
|
|
|
loadedModifier = params; |
|
|
|
loadedModifier = params; |
|
|
|
} else if (Modifier.ARMATURE_MODIFIER_DATA.equals(modifier.getType())) {//****************ARMATURE MODIFIER
|
|
|
|
} else if (Modifier.ARMATURE_MODIFIER_DATA.equals(modifier.getType())) {// ****************ARMATURE MODIFIER
|
|
|
|
Pointer pArmatureObject = (Pointer) modifier.getFieldValue("object"); |
|
|
|
Pointer pArmatureObject = (Pointer) modifier.getFieldValue("object"); |
|
|
|
if (!pArmatureObject.isNull()) { |
|
|
|
if (!pArmatureObject.isNull()) { |
|
|
|
ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class); |
|
|
|
ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class); |
|
|
|
Structure armatureObject = (Structure) dataRepository.getLoadedFeature(pArmatureObject.getOldMemoryAddress(), LoadedFeatureDataType.LOADED_STRUCTURE); |
|
|
|
Structure armatureObject = (Structure) dataRepository.getLoadedFeature(pArmatureObject.getOldMemoryAddress(), LoadedFeatureDataType.LOADED_STRUCTURE); |
|
|
|
if (armatureObject == null) {//we check this first not to fetch the structure unnecessary
|
|
|
|
if (armatureObject == null) {// we check this first not to fetch the structure unnecessary
|
|
|
|
armatureObject = pArmatureObject.fetchData(dataRepository.getInputStream()).get(0); |
|
|
|
armatureObject = pArmatureObject.fetchData(dataRepository.getInputStream()).get(0); |
|
|
|
objectHelper.toObject(armatureObject, dataRepository); |
|
|
|
objectHelper.toObject(armatureObject, dataRepository); |
|
|
|
} |
|
|
|
} |
|
|
|
modifierAdditionalData = armatureObject.getOldMemoryAddress(); |
|
|
|
modifierAdditionalData = armatureObject.getOldMemoryAddress(); |
|
|
|
ArmatureHelper armatureHelper = dataRepository.getHelper(ArmatureHelper.class); |
|
|
|
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)
|
|
|
|
// 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); |
|
|
|
Matrix4f armatureObjectMatrix = objectHelper.getTransformationMatrix(armatureObject); |
|
|
|
Matrix4f inverseMeshObjectMatrix = objectHelper.getTransformationMatrix(objectStructure).invert(); |
|
|
|
Matrix4f inverseMeshObjectMatrix = objectHelper.getTransformationMatrix(objectStructure).invert(); |
|
|
|
Matrix4f additionalRootBoneTransformation = inverseMeshObjectMatrix.multLocal(armatureObjectMatrix); |
|
|
|
Matrix4f additionalRootBoneTransformation = inverseMeshObjectMatrix.multLocal(armatureObjectMatrix); |
|
|
@ -235,7 +235,7 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
LOGGER.warning("Unsupported modifier type: " + modifier.getType()); |
|
|
|
LOGGER.warning("Unsupported modifier type: " + modifier.getType()); |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (Modifier.PARTICLE_MODIFIER_DATA.equals(modifier.getType())) {//****************PARTICLES MODIFIER
|
|
|
|
} else if (Modifier.PARTICLE_MODIFIER_DATA.equals(modifier.getType())) {// ****************PARTICLES MODIFIER
|
|
|
|
Pointer pParticleSystem = (Pointer) modifier.getFieldValue("psys"); |
|
|
|
Pointer pParticleSystem = (Pointer) modifier.getFieldValue("psys"); |
|
|
|
if (!pParticleSystem.isNull()) { |
|
|
|
if (!pParticleSystem.isNull()) { |
|
|
|
ParticlesHelper particlesHelper = dataRepository.getHelper(ParticlesHelper.class); |
|
|
|
ParticlesHelper particlesHelper = dataRepository.getHelper(ParticlesHelper.class); |
|
|
@ -243,7 +243,7 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
loadedModifier = particlesHelper.toParticleEmitter(particleSystem, dataRepository); |
|
|
|
loadedModifier = particlesHelper.toParticleEmitter(particleSystem, dataRepository); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
//adding modifier to the modifier's lists
|
|
|
|
// adding modifier to the modifier's lists
|
|
|
|
if (loadedModifier != null) { |
|
|
|
if (loadedModifier != null) { |
|
|
|
dataRepository.addModifier(objectStructure.getOldMemoryAddress(), modifier.getType(), loadedModifier, modifierAdditionalData); |
|
|
|
dataRepository.addModifier(objectStructure.getOldMemoryAddress(), modifier.getType(), loadedModifier, modifierAdditionalData); |
|
|
|
modifierAdditionalData = null; |
|
|
|
modifierAdditionalData = null; |
|
|
@ -253,9 +253,12 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* This method applies particles emitter to the given node. |
|
|
|
* This method applies particles emitter to the given node. |
|
|
|
* @param node the particles emitter node |
|
|
|
* @param node |
|
|
|
* @param modifier the modifier containing the emitter data |
|
|
|
* the particles emitter node |
|
|
|
* @param dataRepository the data repository |
|
|
|
* @param modifier |
|
|
|
|
|
|
|
* the modifier containing the emitter data |
|
|
|
|
|
|
|
* @param dataRepository |
|
|
|
|
|
|
|
* the data repository |
|
|
|
* @return node with particles' emitter applied |
|
|
|
* @return node with particles' emitter applied |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected Node applyParticleSystemModifierData(Node node, Modifier modifier, DataRepository dataRepository) { |
|
|
|
protected Node applyParticleSystemModifierData(Node node, Modifier modifier, DataRepository dataRepository) { |
|
|
@ -263,16 +266,16 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
ParticleEmitter emitter = (ParticleEmitter) modifier.getJmeModifierRepresentation(); |
|
|
|
ParticleEmitter emitter = (ParticleEmitter) modifier.getJmeModifierRepresentation(); |
|
|
|
emitter = emitter.clone(); |
|
|
|
emitter = emitter.clone(); |
|
|
|
|
|
|
|
|
|
|
|
//veryfying the alpha function for particles' texture
|
|
|
|
// veryfying the alpha function for particles' texture
|
|
|
|
Integer alphaFunction = MaterialHelper.ALPHA_MASK_HYPERBOLE; |
|
|
|
Integer alphaFunction = MaterialHelper.ALPHA_MASK_HYPERBOLE; |
|
|
|
char nameSuffix = emitter.getName().charAt(emitter.getName().length() - 1); |
|
|
|
char nameSuffix = emitter.getName().charAt(emitter.getName().length() - 1); |
|
|
|
if (nameSuffix == 'B' || nameSuffix == 'N') { |
|
|
|
if (nameSuffix == 'B' || nameSuffix == 'N') { |
|
|
|
alphaFunction = MaterialHelper.ALPHA_MASK_NONE; |
|
|
|
alphaFunction = MaterialHelper.ALPHA_MASK_NONE; |
|
|
|
} |
|
|
|
} |
|
|
|
//removing the type suffix from the name
|
|
|
|
// removing the type suffix from the name
|
|
|
|
emitter.setName(emitter.getName().substring(0, emitter.getName().length() - 1)); |
|
|
|
emitter.setName(emitter.getName().substring(0, emitter.getName().length() - 1)); |
|
|
|
|
|
|
|
|
|
|
|
//applying emitter shape
|
|
|
|
// applying emitter shape
|
|
|
|
EmitterShape emitterShape = emitter.getShape(); |
|
|
|
EmitterShape emitterShape = emitter.getShape(); |
|
|
|
List<Mesh> meshes = new ArrayList<Mesh>(); |
|
|
|
List<Mesh> meshes = new ArrayList<Mesh>(); |
|
|
|
for (Spatial spatial : node.getChildren()) { |
|
|
|
for (Spatial spatial : node.getChildren()) { |
|
|
@ -281,7 +284,7 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
if (mesh != null) { |
|
|
|
if (mesh != null) { |
|
|
|
meshes.add(mesh); |
|
|
|
meshes.add(mesh); |
|
|
|
Material material = materialHelper.getParticlesMaterial(((Geometry) spatial).getMaterial(), alphaFunction, dataRepository); |
|
|
|
Material material = materialHelper.getParticlesMaterial(((Geometry) spatial).getMaterial(), alphaFunction, dataRepository); |
|
|
|
emitter.setMaterial(material);//TODO: divide into several pieces
|
|
|
|
emitter.setMaterial(material);// TODO: divide into several pieces
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -314,7 +317,7 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
for (int i = 0; i < animList.size(); ++i) { |
|
|
|
for (int i = 0; i < animList.size(); ++i) { |
|
|
|
BoneAnimation boneAnimation = this.cloneBoneAnimation(animList.get(i)); |
|
|
|
BoneAnimation boneAnimation = this.cloneBoneAnimation(animList.get(i)); |
|
|
|
|
|
|
|
|
|
|
|
//baking constraints into animations
|
|
|
|
// baking constraints into animations
|
|
|
|
if (constraints != null && constraints.length > 0) { |
|
|
|
if (constraints != null && constraints.length > 0) { |
|
|
|
for (Constraint constraint : constraints) { |
|
|
|
for (Constraint constraint : constraints) { |
|
|
|
constraint.affectAnimation(ad.skeleton, boneAnimation); |
|
|
|
constraint.affectAnimation(ad.skeleton, boneAnimation); |
|
|
@ -324,7 +327,7 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
anims.put(boneAnimation.getName(), boneAnimation); |
|
|
|
anims.put(boneAnimation.getName(), boneAnimation); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//getting meshes
|
|
|
|
// getting meshes
|
|
|
|
Mesh[] meshes = null; |
|
|
|
Mesh[] meshes = null; |
|
|
|
List<Mesh> meshesList = new ArrayList<Mesh>(); |
|
|
|
List<Mesh> meshesList = new ArrayList<Mesh>(); |
|
|
|
List<Spatial> children = node.getChildren(); |
|
|
|
List<Spatial> children = node.getChildren(); |
|
|
@ -337,19 +340,19 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
meshes = meshesList.toArray(new Mesh[meshesList.size()]); |
|
|
|
meshes = meshesList.toArray(new Mesh[meshesList.size()]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//applying the control to the node
|
|
|
|
// applying the control to the node
|
|
|
|
SkeletonControl skeletonControl = new SkeletonControl(meshes, ad.skeleton); |
|
|
|
SkeletonControl skeletonControl = new SkeletonControl(meshes, ad.skeleton); |
|
|
|
AnimControl control = node.getControl(AnimControl.class); |
|
|
|
AnimControl control = node.getControl(AnimControl.class); |
|
|
|
|
|
|
|
|
|
|
|
if (control == null) { |
|
|
|
if (control == null) { |
|
|
|
control = new AnimControl(ad.skeleton); |
|
|
|
control = new AnimControl(ad.skeleton); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
//merging skeletons
|
|
|
|
// merging skeletons
|
|
|
|
Skeleton controlSkeleton = control.getSkeleton(); |
|
|
|
Skeleton controlSkeleton = control.getSkeleton(); |
|
|
|
int boneIndexIncrease = controlSkeleton.getBoneCount(); |
|
|
|
int boneIndexIncrease = controlSkeleton.getBoneCount(); |
|
|
|
Skeleton skeleton = this.merge(controlSkeleton, ad.skeleton); |
|
|
|
Skeleton skeleton = this.merge(controlSkeleton, ad.skeleton); |
|
|
|
|
|
|
|
|
|
|
|
//merging animations
|
|
|
|
// merging animations
|
|
|
|
HashMap<String, BoneAnimation> animations = new HashMap<String, BoneAnimation>(); |
|
|
|
HashMap<String, BoneAnimation> animations = new HashMap<String, BoneAnimation>(); |
|
|
|
for (String animationName : control.getAnimationNames()) { |
|
|
|
for (String animationName : control.getAnimationNames()) { |
|
|
|
animations.put(animationName, control.getAnim(animationName)); |
|
|
|
animations.put(animationName, control.getAnim(animationName)); |
|
|
@ -364,7 +367,7 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
animations.put(animEntry.getKey(), animEntry.getValue()); |
|
|
|
animations.put(animEntry.getKey(), animEntry.getValue()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//replacing the control
|
|
|
|
// replacing the control
|
|
|
|
node.removeControl(control); |
|
|
|
node.removeControl(control); |
|
|
|
control = new AnimControl(skeleton); |
|
|
|
control = new AnimControl(skeleton); |
|
|
|
} |
|
|
|
} |
|
|
@ -390,14 +393,14 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
Map<String, Object> modifierData = (Map<String, Object>) modifier.getJmeModifierRepresentation(); |
|
|
|
Map<String, Object> modifierData = (Map<String, Object>) modifier.getJmeModifierRepresentation(); |
|
|
|
int fittype = ((Number) modifierData.get("fittype")).intValue(); |
|
|
|
int fittype = ((Number) modifierData.get("fittype")).intValue(); |
|
|
|
float[] offset = (float[]) modifierData.get("offset"); |
|
|
|
float[] offset = (float[]) modifierData.get("offset"); |
|
|
|
if (offset == null) {//the node will be repeated several times in the same place
|
|
|
|
if (offset == null) {// the node will be repeated several times in the same place
|
|
|
|
offset = new float[]{0.0f, 0.0f, 0.0f}; |
|
|
|
offset = new float[] { 0.0f, 0.0f, 0.0f }; |
|
|
|
} |
|
|
|
} |
|
|
|
float[] scale = (float[]) modifierData.get("scale"); |
|
|
|
float[] scale = (float[]) modifierData.get("scale"); |
|
|
|
if (scale == null) {//the node will be repeated several times in the same place
|
|
|
|
if (scale == null) {// the node will be repeated several times in the same place
|
|
|
|
scale = new float[]{0.0f, 0.0f, 0.0f}; |
|
|
|
scale = new float[] { 0.0f, 0.0f, 0.0f }; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
//getting bounding box
|
|
|
|
// getting bounding box
|
|
|
|
node.updateModelBound(); |
|
|
|
node.updateModelBound(); |
|
|
|
BoundingVolume boundingVolume = node.getWorldBound(); |
|
|
|
BoundingVolume boundingVolume = node.getWorldBound(); |
|
|
|
if (boundingVolume instanceof BoundingBox) { |
|
|
|
if (boundingVolume instanceof BoundingBox) { |
|
|
@ -414,13 +417,13 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//adding object's offset
|
|
|
|
// adding object's offset
|
|
|
|
float[] objectOffset = new float[]{0.0f, 0.0f, 0.0f}; |
|
|
|
float[] objectOffset = new float[] { 0.0f, 0.0f, 0.0f }; |
|
|
|
Pointer pOffsetObject = (Pointer) modifierData.get("offsetob"); |
|
|
|
Pointer pOffsetObject = (Pointer) modifierData.get("offsetob"); |
|
|
|
if (pOffsetObject != null) { |
|
|
|
if (pOffsetObject != null) { |
|
|
|
FileBlockHeader offsetObjectBlock = dataRepository.getFileBlock(pOffsetObject.getOldMemoryAddress()); |
|
|
|
FileBlockHeader offsetObjectBlock = dataRepository.getFileBlock(pOffsetObject.getOldMemoryAddress()); |
|
|
|
ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class); |
|
|
|
ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class); |
|
|
|
try {//we take the structure in case the object was not yet loaded
|
|
|
|
try {// we take the structure in case the object was not yet loaded
|
|
|
|
Structure offsetStructure = offsetObjectBlock.getStructure(dataRepository); |
|
|
|
Structure offsetStructure = offsetObjectBlock.getStructure(dataRepository); |
|
|
|
Vector3f translation = objectHelper.getTransformation(offsetStructure).getTranslation(); |
|
|
|
Vector3f translation = objectHelper.getTransformation(offsetStructure).getTranslation(); |
|
|
|
objectOffset[0] = translation.x; |
|
|
|
objectOffset[0] = translation.x; |
|
|
@ -431,9 +434,9 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//getting start and end caps
|
|
|
|
// getting start and end caps
|
|
|
|
Node[] caps = new Node[]{null, null}; |
|
|
|
Node[] caps = new Node[] { null, null }; |
|
|
|
Pointer[] pCaps = new Pointer[]{(Pointer) modifierData.get("startcap"), (Pointer) modifierData.get("endcap")}; |
|
|
|
Pointer[] pCaps = new Pointer[] { (Pointer) modifierData.get("startcap"), (Pointer) modifierData.get("endcap") }; |
|
|
|
for (int i = 0; i < pCaps.length; ++i) { |
|
|
|
for (int i = 0; i < pCaps.length; ++i) { |
|
|
|
if (pCaps[i] != null) { |
|
|
|
if (pCaps[i] != null) { |
|
|
|
caps[i] = (Node) dataRepository.getLoadedFeature(pCaps[i].getOldMemoryAddress(), LoadedFeatureDataType.LOADED_FEATURE); |
|
|
|
caps[i] = (Node) dataRepository.getLoadedFeature(pCaps[i].getOldMemoryAddress(), LoadedFeatureDataType.LOADED_FEATURE); |
|
|
@ -441,7 +444,7 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
caps[i] = (Node) caps[i].clone(); |
|
|
|
caps[i] = (Node) caps[i].clone(); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
FileBlockHeader capBlock = dataRepository.getFileBlock(pOffsetObject.getOldMemoryAddress()); |
|
|
|
FileBlockHeader capBlock = dataRepository.getFileBlock(pOffsetObject.getOldMemoryAddress()); |
|
|
|
try {//we take the structure in case the object was not yet loaded
|
|
|
|
try {// we take the structure in case the object was not yet loaded
|
|
|
|
Structure capStructure = capBlock.getStructure(dataRepository); |
|
|
|
Structure capStructure = capBlock.getStructure(dataRepository); |
|
|
|
ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class); |
|
|
|
ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class); |
|
|
|
caps[i] = (Node) objectHelper.toObject(capStructure, dataRepository); |
|
|
|
caps[i] = (Node) objectHelper.toObject(capStructure, dataRepository); |
|
|
@ -455,26 +458,24 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Vector3f translationVector = new Vector3f(offset[0] + scale[0] + objectOffset[0], |
|
|
|
Vector3f translationVector = new Vector3f(offset[0] + scale[0] + objectOffset[0], offset[1] + scale[1] + objectOffset[1], offset[2] + scale[2] + objectOffset[2]); |
|
|
|
offset[1] + scale[1] + objectOffset[1], |
|
|
|
|
|
|
|
offset[2] + scale[2] + objectOffset[2]); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//getting/calculating repeats amount
|
|
|
|
// getting/calculating repeats amount
|
|
|
|
int count = 0; |
|
|
|
int count = 0; |
|
|
|
if (fittype == 0) {//Fixed count
|
|
|
|
if (fittype == 0) {// Fixed count
|
|
|
|
count = ((Number) modifierData.get("count")).intValue() - 1; |
|
|
|
count = ((Number) modifierData.get("count")).intValue() - 1; |
|
|
|
} else if (fittype == 1) {//Fixed length
|
|
|
|
} else if (fittype == 1) {// Fixed length
|
|
|
|
float length = ((Number) modifierData.get("length")).floatValue(); |
|
|
|
float length = ((Number) modifierData.get("length")).floatValue(); |
|
|
|
if (translationVector.length() > 0.0f) { |
|
|
|
if (translationVector.length() > 0.0f) { |
|
|
|
count = (int) (length / translationVector.length()) - 1; |
|
|
|
count = (int) (length / translationVector.length()) - 1; |
|
|
|
} |
|
|
|
} |
|
|
|
} else if (fittype == 2) {//Fit curve
|
|
|
|
} else if (fittype == 2) {// Fit curve
|
|
|
|
LOGGER.warning("Fit curve mode in array modifier not yet implemented!");//TODO: implement fit curve
|
|
|
|
LOGGER.warning("Fit curve mode in array modifier not yet implemented!");// TODO: implement fit curve
|
|
|
|
} else { |
|
|
|
} else { |
|
|
|
throw new IllegalStateException("Unknown fit type: " + fittype); |
|
|
|
throw new IllegalStateException("Unknown fit type: " + fittype); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//adding translated nodes and caps
|
|
|
|
// adding translated nodes and caps
|
|
|
|
if (count > 0) { |
|
|
|
if (count > 0) { |
|
|
|
Node[] arrayNodes = new Node[count]; |
|
|
|
Node[] arrayNodes = new Node[count]; |
|
|
|
Vector3f newTranslation = node.getLocalTranslation().clone(); |
|
|
|
Vector3f newTranslation = node.getLocalTranslation().clone(); |
|
|
@ -512,35 +513,81 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
@SuppressWarnings("unchecked") |
|
|
|
protected Node applyMirrorModifierData(Node node, Modifier modifier, DataRepository dataRepository) { |
|
|
|
protected Node applyMirrorModifierData(Node node, Modifier modifier, DataRepository dataRepository) { |
|
|
|
Map<String, Object> modifierData = (Map<String, Object>) modifier.getJmeModifierRepresentation(); |
|
|
|
Map<String, Object> modifierData = (Map<String, Object>) modifier.getJmeModifierRepresentation(); |
|
|
|
int flag = ((Number)modifierData.get("flag")).intValue(); |
|
|
|
int flag = ((Number) modifierData.get("flag")).intValue(); |
|
|
|
float[] mirrorFactor = new float[] { |
|
|
|
float[] mirrorFactor = new float[] { |
|
|
|
(flag & 0x08) != 0 ? -1.0f : 1.0f, |
|
|
|
(flag & 0x08) != 0 ? -1.0f : 1.0f, |
|
|
|
(flag & 0x10) != 0 ? -1.0f : 1.0f, |
|
|
|
(flag & 0x10) != 0 ? -1.0f : 1.0f, |
|
|
|
(flag & 0x20) != 0 ? -1.0f : 1.0f |
|
|
|
(flag & 0x20) != 0 ? -1.0f : 1.0f |
|
|
|
}; |
|
|
|
}; |
|
|
|
float[] center = new float[] {0.0f, 0.0f, 0.0f}; |
|
|
|
float[] center = new float[] { 0.0f, 0.0f, 0.0f }; |
|
|
|
float tolerance = ((Number)modifierData.get("tolerance")).floatValue(); |
|
|
|
Pointer pObject = (Pointer) modifierData.get("mirrorob"); |
|
|
|
|
|
|
|
if (pObject != null) { |
|
|
|
|
|
|
|
Structure objectStructure; |
|
|
|
|
|
|
|
try { |
|
|
|
|
|
|
|
objectStructure = pObject.fetchData(dataRepository.getInputStream()).get(0); |
|
|
|
|
|
|
|
ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class); |
|
|
|
|
|
|
|
Node object = (Node) objectHelper.toObject(objectStructure, dataRepository); |
|
|
|
|
|
|
|
if (object != null) { |
|
|
|
|
|
|
|
Vector3f translation = object.getWorldTranslation(); |
|
|
|
|
|
|
|
center[0] = translation.x; |
|
|
|
|
|
|
|
center[1] = translation.y; |
|
|
|
|
|
|
|
center[2] = translation.z; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} catch (BlenderFileException e) { |
|
|
|
|
|
|
|
LOGGER.severe("Cannot load mirror's reference object. Cause: " + e.getLocalizedMessage()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
float tolerance = ((Number) modifierData.get("tolerance")).floatValue(); |
|
|
|
|
|
|
|
boolean mirrorU = (flag & 0x01) != 0; |
|
|
|
|
|
|
|
boolean mirrorV = (flag & 0x02) != 0; |
|
|
|
|
|
|
|
// boolean mirrorVGroup = (flag & 0x20) != 0;
|
|
|
|
|
|
|
|
|
|
|
|
List<Geometry> geometriesToAdd = new ArrayList<Geometry>(); |
|
|
|
List<Geometry> geometriesToAdd = new ArrayList<Geometry>(); |
|
|
|
for(int mirrorIndex = 0;mirrorIndex<3;++mirrorIndex) { |
|
|
|
for (int mirrorIndex = 0; mirrorIndex < 3; ++mirrorIndex) { |
|
|
|
if(mirrorFactor[mirrorIndex] == -1.0f) { |
|
|
|
if (mirrorFactor[mirrorIndex] == -1.0f) { |
|
|
|
for (Spatial spatial : node.getChildren()) { |
|
|
|
for (Spatial spatial : node.getChildren()) { |
|
|
|
if (spatial instanceof Geometry) { |
|
|
|
if (spatial instanceof Geometry) { |
|
|
|
Mesh mesh = ((Geometry) spatial).getMesh(); |
|
|
|
Mesh mesh = ((Geometry) spatial).getMesh(); |
|
|
|
Mesh clone = mesh.deepClone(); |
|
|
|
Mesh clone = mesh.deepClone(); |
|
|
|
|
|
|
|
|
|
|
|
VertexBuffer position = clone.getBuffer(Type.Position); |
|
|
|
// getting buffers
|
|
|
|
VertexBuffer bindPosePosition = clone.getBuffer(Type.BindPosePosition); |
|
|
|
FloatBuffer position = (FloatBuffer) mesh.getBuffer(Type.Position).getData(); |
|
|
|
FloatBuffer positionBuffer = (FloatBuffer) position.getData(); |
|
|
|
FloatBuffer bindPosePosition = (FloatBuffer) mesh.getBuffer(Type.BindPosePosition).getData(); |
|
|
|
FloatBuffer bindPosePositionBuffer = (FloatBuffer) bindPosePosition.getData(); |
|
|
|
|
|
|
|
positionBuffer.rewind(); |
|
|
|
FloatBuffer clonePosition = (FloatBuffer) clone.getBuffer(Type.Position).getData(); |
|
|
|
bindPosePositionBuffer.rewind(); |
|
|
|
FloatBuffer cloneBindPosePosition = (FloatBuffer) clone.getBuffer(Type.BindPosePosition).getData(); |
|
|
|
for(int i=mirrorIndex;i<positionBuffer.limit();i+=3) { |
|
|
|
FloatBuffer cloneNormals = (FloatBuffer) clone.getBuffer(Type.Normal).getData(); |
|
|
|
float value = positionBuffer.get(i); |
|
|
|
FloatBuffer cloneBindPoseNormals = (FloatBuffer) clone.getBuffer(Type.BindPoseNormal).getData(); |
|
|
|
positionBuffer.put(i, Math.abs(value) <= tolerance ? 0.0f : -value); |
|
|
|
|
|
|
|
|
|
|
|
// modyfying data
|
|
|
|
|
|
|
|
for (int i = mirrorIndex; i < clonePosition.limit(); i += 3) { |
|
|
|
|
|
|
|
float value = clonePosition.get(i); |
|
|
|
|
|
|
|
float d = center[mirrorIndex] - value; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (Math.abs(d) <= tolerance) { |
|
|
|
|
|
|
|
clonePosition.put(i, center[mirrorIndex]); |
|
|
|
|
|
|
|
cloneBindPosePosition.put(i, center[mirrorIndex]); |
|
|
|
|
|
|
|
position.put(i, center[mirrorIndex]); |
|
|
|
|
|
|
|
bindPosePosition.put(i, center[mirrorIndex]); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
clonePosition.put(i, value + 2.0f * d); |
|
|
|
|
|
|
|
cloneBindPosePosition.put(i, value + 2.0f * d); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
cloneNormals.put(i, -cloneNormals.get(i)); |
|
|
|
|
|
|
|
cloneBindPoseNormals.put(i, -cloneNormals.get(i)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
value = bindPosePositionBuffer.get(i); |
|
|
|
if(mirrorU) { |
|
|
|
bindPosePositionBuffer.put(i, Math.abs(value) <= tolerance ? 0.0f : -value); |
|
|
|
FloatBuffer cloneUVs = (FloatBuffer) clone.getBuffer(Type.TexCoord).getData(); |
|
|
|
|
|
|
|
for(int i=0;i<cloneUVs.limit();i+=2) { |
|
|
|
|
|
|
|
cloneUVs.put(i, 1.0f - cloneUVs.get(i)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(mirrorV) { |
|
|
|
|
|
|
|
FloatBuffer cloneUVs = (FloatBuffer) clone.getBuffer(Type.TexCoord).getData(); |
|
|
|
|
|
|
|
for(int i=1;i<cloneUVs.limit();i+=2) { |
|
|
|
|
|
|
|
cloneUVs.put(i, 1.0f - cloneUVs.get(i)); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Geometry geometry = new Geometry(null, clone); |
|
|
|
Geometry geometry = new Geometry(null, clone); |
|
|
@ -549,8 +596,8 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//adding meshes to node
|
|
|
|
// adding meshes to node
|
|
|
|
for(Geometry geometry : geometriesToAdd) { |
|
|
|
for (Geometry geometry : geometriesToAdd) { |
|
|
|
node.attachChild(geometry); |
|
|
|
node.attachChild(geometry); |
|
|
|
} |
|
|
|
} |
|
|
|
geometriesToAdd.clear(); |
|
|
|
geometriesToAdd.clear(); |
|
|
@ -568,7 +615,7 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
protected BoneAnimation cloneBoneAnimation(BoneAnimation source) { |
|
|
|
protected BoneAnimation cloneBoneAnimation(BoneAnimation source) { |
|
|
|
BoneAnimation result = new BoneAnimation(source.getName(), source.getLength()); |
|
|
|
BoneAnimation result = new BoneAnimation(source.getName(), source.getLength()); |
|
|
|
|
|
|
|
|
|
|
|
//copying tracks and applying constraints
|
|
|
|
// copying tracks and applying constraints
|
|
|
|
BoneTrack[] sourceTracks = source.getTracks(); |
|
|
|
BoneTrack[] sourceTracks = source.getTracks(); |
|
|
|
BoneTrack[] boneTracks = new BoneTrack[sourceTracks.length]; |
|
|
|
BoneTrack[] boneTracks = new BoneTrack[sourceTracks.length]; |
|
|
|
for (int i = 0; i < sourceTracks.length; ++i) { |
|
|
|
for (int i = 0; i < sourceTracks.length; ++i) { |
|
|
@ -584,11 +631,12 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
for (int j = 0; j < tablesLength; ++j) { |
|
|
|
for (int j = 0; j < tablesLength; ++j) { |
|
|
|
translations[j] = sourceTranslations[j].clone(); |
|
|
|
translations[j] = sourceTranslations[j].clone(); |
|
|
|
rotations[j] = sourceRotations[j].clone(); |
|
|
|
rotations[j] = sourceRotations[j].clone(); |
|
|
|
if (sourceScales != null) {//only scales may not be applied
|
|
|
|
if (sourceScales != null) {// only scales may not be applied
|
|
|
|
scales[j] = sourceScales[j].clone(); |
|
|
|
scales[j] = sourceScales[j].clone(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
boneTracks[i] = new BoneTrack(sourceTracks[i].getTargetBoneIndex(), sourceTracks[i].getTimes(),//times do not change, no need to clone them,
|
|
|
|
boneTracks[i] = new BoneTrack(sourceTracks[i].getTargetBoneIndex(), sourceTracks[i].getTimes(),// times do not change, no need
|
|
|
|
|
|
|
|
// to clone them,
|
|
|
|
translations, rotations, scales); |
|
|
|
translations, rotations, scales); |
|
|
|
} |
|
|
|
} |
|
|
|
result.setTracks(boneTracks); |
|
|
|
result.setTracks(boneTracks); |
|
|
@ -609,7 +657,7 @@ public class ModifierHelper extends AbstractBlenderHelper { |
|
|
|
for (int i = 0; i < s1.getBoneCount(); ++i) { |
|
|
|
for (int i = 0; i < s1.getBoneCount(); ++i) { |
|
|
|
bones.add(s1.getBone(i)); |
|
|
|
bones.add(s1.getBone(i)); |
|
|
|
} |
|
|
|
} |
|
|
|
for (int i = 1; i < s2.getBoneCount(); ++i) {//ommit objectAnimationBone
|
|
|
|
for (int i = 1; i < s2.getBoneCount(); ++i) {// ommit objectAnimationBone
|
|
|
|
bones.add(s2.getBone(i)); |
|
|
|
bones.add(s2.getBone(i)); |
|
|
|
} |
|
|
|
} |
|
|
|
return new Skeleton(bones.toArray(new Bone[bones.size()])); |
|
|
|
return new Skeleton(bones.toArray(new Bone[bones.size()])); |
|
|
|