Improvements to mirror modifier (90% complete).

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7637 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
Kae..pl 14 years ago
parent 4c18882032
commit 7d7e6062ee
  1. 200
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ModifierHelper.java

@ -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()]));

Loading…
Cancel
Save