Bladeren bron

Refactoring: removed unnecessary return type from the modifiers (it was never used).

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10803 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
Kae..pl 12 jaren geleden
bovenliggende
commit
2a00f1ccb0

+ 59 - 62
engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArmatureModifier.java

@@ -177,76 +177,73 @@ import com.jme3.util.BufferUtils;
 
     @Override
     @SuppressWarnings("unchecked")
-    public Node apply(Node node, BlenderContext blenderContext) {
+    public void apply(Node node, BlenderContext blenderContext) {
         if (invalid) {
             LOGGER.log(Level.WARNING, "Armature modifier is invalid! Cannot be applied to: {0}", node.getName());
         }// if invalid, animData will be null
-        if (animationData == null || skeleton == null) {
-            return node;
-        }
-
-        // setting weights for bones
-        List<Geometry> geomList = (List<Geometry>) blenderContext.getLoadedFeature(meshOMA, LoadedFeatureDataType.LOADED_FEATURE);
-        MeshContext meshContext = blenderContext.getMeshContext(meshOMA);
-        int[] bonesGroups = new int[] { 0 };
-        for (Geometry geom : geomList) {
-            int materialIndex = meshContext.getMaterialIndex(geom);
-            Mesh mesh = geom.getMesh();
-
-            try {
-                VertexBuffer[] buffers = this.readVerticesWeightsData(objectStructure, meshStructure, skeleton, materialIndex, bonesGroups, blenderContext);
-                if (buffers != null) {
-                    mesh.setMaxNumWeights(bonesGroups[0]);
-                    mesh.setBuffer(buffers[0]);
-                    mesh.setBuffer(buffers[1]);
-
-                    //FIXME @Kaelthas this should be replaced by a call to 
-                    //mesh.generateBindPos(true)
-                    VertexBuffer bindNormalBuffer = meshContext.getBindNormalBuffer(materialIndex);
-                    if (bindNormalBuffer != null) {
-                        mesh.setBuffer(bindNormalBuffer);
-                    }
-                    VertexBuffer bindPoseBuffer = meshContext.getBindPoseBuffer(materialIndex);
-                    if (bindPoseBuffer != null) {
-                        mesh.setBuffer(bindPoseBuffer);
+        if(animationData != null && skeleton != null) {
+            // setting weights for bones
+            List<Geometry> geomList = (List<Geometry>) blenderContext.getLoadedFeature(meshOMA, LoadedFeatureDataType.LOADED_FEATURE);
+            MeshContext meshContext = blenderContext.getMeshContext(meshOMA);
+            int[] bonesGroups = new int[] { 0 };
+            for (Geometry geom : geomList) {
+                int materialIndex = meshContext.getMaterialIndex(geom);
+                Mesh mesh = geom.getMesh();
+    
+                try {
+                    VertexBuffer[] buffers = this.readVerticesWeightsData(objectStructure, meshStructure, skeleton, materialIndex, bonesGroups, blenderContext);
+                    if (buffers != null) {
+                        mesh.setMaxNumWeights(bonesGroups[0]);
+                        mesh.setBuffer(buffers[0]);
+                        mesh.setBuffer(buffers[1]);
+    
+                        //FIXME @Kaelthas this should be replaced by a call to 
+                        //mesh.generateBindPos(true)
+                        VertexBuffer bindNormalBuffer = meshContext.getBindNormalBuffer(materialIndex);
+                        if (bindNormalBuffer != null) {
+                            mesh.setBuffer(bindNormalBuffer);
+                        }
+                        VertexBuffer bindPoseBuffer = meshContext.getBindPoseBuffer(materialIndex);
+                        if (bindPoseBuffer != null) {
+                            mesh.setBuffer(bindPoseBuffer);
+                        }
+                        // change the usage type of vertex and normal buffers from
+                        // Static to Stream
+                        mesh.getBuffer(Type.Position).setUsage(Usage.Stream);
+                        mesh.getBuffer(Type.Normal).setUsage(Usage.Stream);
+                        
+                        
+                        //creating empty buffers for HW skinning 
+                        //the buffers will be setup if ever used.
+                        VertexBuffer verticesWeightsHW = new VertexBuffer(Type.HWBoneWeight);
+                        VertexBuffer verticesWeightsIndicesHW = new VertexBuffer(Type.HWBoneIndex);
+                        mesh.setBuffer(verticesWeightsHW);
+                        mesh.setBuffer(verticesWeightsIndicesHW);
                     }
-                    // change the usage type of vertex and normal buffers from
-                    // Static to Stream
-                    mesh.getBuffer(Type.Position).setUsage(Usage.Stream);
-                    mesh.getBuffer(Type.Normal).setUsage(Usage.Stream);
-                    
-                    
-                    //creating empty buffers for HW skinning 
-                    //the buffers will be setup if ever used.
-                    VertexBuffer verticesWeightsHW = new VertexBuffer(Type.HWBoneWeight);
-                    VertexBuffer verticesWeightsIndicesHW = new VertexBuffer(Type.HWBoneIndex);
-                    mesh.setBuffer(verticesWeightsHW);
-                    mesh.setBuffer(verticesWeightsIndicesHW);
+                } catch (BlenderFileException e) {
+                    LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
+                    invalid = true;
                 }
-            } catch (BlenderFileException e) {
-                LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
-                this.invalid = true;
-                return node;
             }
-        }
-
-        // applying animations
-        AnimControl control = new AnimControl(animationData.skeleton);
-        List<Animation> animList = animationData.anims;
-        if (animList != null && animList.size() > 0) {
-            HashMap<String, Animation> anims = new HashMap<String, Animation>(animList.size());
-            for (int i = 0; i < animList.size(); ++i) {
-                Animation animation = animList.get(i);
-                anims.put(animation.getName(), animation);
+    
+            if(!invalid) {
+                // applying animations
+                AnimControl control = new AnimControl(animationData.skeleton);
+                List<Animation> animList = animationData.anims;
+                if (animList != null && animList.size() > 0) {
+                    HashMap<String, Animation> anims = new HashMap<String, Animation>(animList.size());
+                    for (int i = 0; i < animList.size(); ++i) {
+                        Animation animation = animList.get(i);
+                        anims.put(animation.getName(), animation);
+                    }
+                    control.setAnimations(anims);
+                }
+                node.addControl(control);
+                node.addControl(new SkeletonControl(animationData.skeleton));
+        
+                blenderContext.setNodeForSkeleton(skeleton, node);
             }
-            control.setAnimations(anims);
         }
-        node.addControl(control);
-        node.addControl(new SkeletonControl(animationData.skeleton));
-
-        blenderContext.setNodeForSkeleton(skeleton, node);
-
-        return node;
     }
 
     /**

+ 102 - 103
engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArrayModifier.java

@@ -127,122 +127,121 @@ import java.util.logging.Logger;
     }
 
     @Override
-    public Node apply(Node node, BlenderContext blenderContext) {
+    public void apply(Node node, BlenderContext blenderContext) {
         if (invalid) {
             LOGGER.log(Level.WARNING, "Array modifier is invalid! Cannot be applied to: {0}", node.getName());
-            return node;
-        }
-        int fittype = ((Number) modifierData.get("fittype")).intValue();
-        float[] offset = (float[]) modifierData.get("offset");
-        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
-            scale = new float[] { 0.0f, 0.0f, 0.0f };
         } else {
-            // getting bounding box
-            node.updateModelBound();
-            BoundingVolume boundingVolume = node.getWorldBound();
-            if (boundingVolume instanceof BoundingBox) {
-                scale[0] *= ((BoundingBox) boundingVolume).getXExtent() * 2.0f;
-                scale[1] *= ((BoundingBox) boundingVolume).getYExtent() * 2.0f;
-                scale[2] *= ((BoundingBox) boundingVolume).getZExtent() * 2.0f;
-            } else if (boundingVolume instanceof BoundingSphere) {
-                float radius = ((BoundingSphere) boundingVolume).getRadius();
-                scale[0] *= radius * 2.0f;
-                scale[1] *= radius * 2.0f;
-                scale[2] *= radius * 2.0f;
+            int fittype = ((Number) modifierData.get("fittype")).intValue();
+            float[] offset = (float[]) modifierData.get("offset");
+            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
+                scale = new float[] { 0.0f, 0.0f, 0.0f };
             } else {
-                throw new IllegalStateException("Unknown bounding volume type: " + boundingVolume.getClass().getName());
+                // getting bounding box
+                node.updateModelBound();
+                BoundingVolume boundingVolume = node.getWorldBound();
+                if (boundingVolume instanceof BoundingBox) {
+                    scale[0] *= ((BoundingBox) boundingVolume).getXExtent() * 2.0f;
+                    scale[1] *= ((BoundingBox) boundingVolume).getYExtent() * 2.0f;
+                    scale[2] *= ((BoundingBox) boundingVolume).getZExtent() * 2.0f;
+                } else if (boundingVolume instanceof BoundingSphere) {
+                    float radius = ((BoundingSphere) boundingVolume).getRadius();
+                    scale[0] *= radius * 2.0f;
+                    scale[1] *= radius * 2.0f;
+                    scale[2] *= radius * 2.0f;
+                } 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 };
-        Pointer pOffsetObject = (Pointer) modifierData.get("offsetob");
-        if (pOffsetObject != null) {
-            FileBlockHeader offsetObjectBlock = blenderContext.getFileBlock(pOffsetObject.getOldMemoryAddress());
-            ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
-            try {// we take the structure in case the object was not yet loaded
-                Structure offsetStructure = offsetObjectBlock.getStructure(blenderContext);
-                Vector3f translation = objectHelper.getTransformation(offsetStructure, blenderContext).getTranslation();
-                objectOffset[0] = translation.x;
-                objectOffset[1] = translation.y;
-                objectOffset[2] = translation.z;
-            } catch (BlenderFileException e) {
-                LOGGER.log(Level.WARNING, "Problems in blender file structure! Object offset cannot be applied! The problem: {0}", e.getMessage());
+    
+            // adding object's offset
+            float[] objectOffset = new float[] { 0.0f, 0.0f, 0.0f };
+            Pointer pOffsetObject = (Pointer) modifierData.get("offsetob");
+            if (pOffsetObject != null) {
+                FileBlockHeader offsetObjectBlock = blenderContext.getFileBlock(pOffsetObject.getOldMemoryAddress());
+                ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
+                try {// we take the structure in case the object was not yet loaded
+                    Structure offsetStructure = offsetObjectBlock.getStructure(blenderContext);
+                    Vector3f translation = objectHelper.getTransformation(offsetStructure, blenderContext).getTranslation();
+                    objectOffset[0] = translation.x;
+                    objectOffset[1] = translation.y;
+                    objectOffset[2] = translation.z;
+                } catch (BlenderFileException e) {
+                    LOGGER.log(Level.WARNING, "Problems in blender file structure! Object offset cannot be applied! The problem: {0}", e.getMessage());
+                }
             }
-        }
-
-        // getting start and end caps
-        Node[] caps = new Node[] { null, null };
-        Pointer[] pCaps = new Pointer[] { (Pointer) modifierData.get("startcap"), (Pointer) modifierData.get("endcap") };
-        for (int i = 0; i < pCaps.length; ++i) {
-            if (pCaps[i] != null) {
-                caps[i] = (Node) blenderContext.getLoadedFeature(pCaps[i].getOldMemoryAddress(), LoadedFeatureDataType.LOADED_FEATURE);
-                if (caps[i] != null) {
-                    caps[i] = (Node) caps[i].clone();
-                } else {
-                    FileBlockHeader capBlock = blenderContext.getFileBlock(pOffsetObject.getOldMemoryAddress());
-                    try {// we take the structure in case the object was not yet loaded
-                        Structure capStructure = capBlock.getStructure(blenderContext);
-                        ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
-                        caps[i] = (Node) objectHelper.toObject(capStructure, blenderContext);
-                        if (caps[i] == null) {
-                            LOGGER.log(Level.WARNING, "Cap object ''{0}'' couldn''t be loaded!", capStructure.getName());
+    
+            // getting start and end caps
+            Node[] caps = new Node[] { null, null };
+            Pointer[] pCaps = new Pointer[] { (Pointer) modifierData.get("startcap"), (Pointer) modifierData.get("endcap") };
+            for (int i = 0; i < pCaps.length; ++i) {
+                if (pCaps[i] != null) {
+                    caps[i] = (Node) blenderContext.getLoadedFeature(pCaps[i].getOldMemoryAddress(), LoadedFeatureDataType.LOADED_FEATURE);
+                    if (caps[i] != null) {
+                        caps[i] = (Node) caps[i].clone();
+                    } else {
+                        FileBlockHeader capBlock = blenderContext.getFileBlock(pOffsetObject.getOldMemoryAddress());
+                        try {// we take the structure in case the object was not yet loaded
+                            Structure capStructure = capBlock.getStructure(blenderContext);
+                            ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
+                            caps[i] = (Node) objectHelper.toObject(capStructure, blenderContext);
+                            if (caps[i] == null) {
+                                LOGGER.log(Level.WARNING, "Cap object ''{0}'' couldn''t be loaded!", capStructure.getName());
+                            }
+                        } catch (BlenderFileException e) {
+                            LOGGER.log(Level.WARNING, "Problems in blender file structure! Cap object cannot be applied! The problem: {0}", e.getMessage());
                         }
-                    } catch (BlenderFileException e) {
-                        LOGGER.log(Level.WARNING, "Problems in blender file structure! Cap object cannot be applied! The problem: {0}", e.getMessage());
                     }
                 }
             }
-        }
-
-        Vector3f translationVector = new Vector3f(offset[0] + scale[0] + objectOffset[0], offset[1] + scale[1] + objectOffset[1], offset[2] + scale[2] + objectOffset[2]);
-        if(blenderContext.getBlenderKey().isFixUpAxis()) {
-            float y = translationVector.y;
-            translationVector.y = translationVector.z;
-            translationVector.z = y == 0 ? 0 : -y;
-        }
-        
-        // getting/calculating repeats amount
-        int count = 0;
-        if (fittype == 0) {// Fixed count
-            count = ((Number) modifierData.get("count")).intValue() - 1;
-        } else if (fittype == 1) {// Fixed length
-            float length = ((Number) modifierData.get("length")).floatValue();
-            if (translationVector.length() > 0.0f) {
-                count = (int) (length / translationVector.length()) - 1;
-            }
-        } else if (fittype == 2) {// Fit curve
-            throw new IllegalStateException("Fit curve should be transformed to Fixed Length array type!");
-        } else {
-            throw new IllegalStateException("Unknown fit type: " + fittype);
-        }
-
-        // adding translated nodes and caps
-        if (count > 0) {
-            Node[] arrayNodes = new Node[count];
-            Vector3f newTranslation = new Vector3f();
-            for (int i = 0; i < count; ++i) {
-                newTranslation.addLocal(translationVector);
-                Node nodeClone = (Node) node.clone();
-                nodeClone.setLocalTranslation(newTranslation);
-                arrayNodes[i] = nodeClone;
-            }
-            for (Node nodeClone : arrayNodes) {
-                node.attachChild(nodeClone);
+    
+            Vector3f translationVector = new Vector3f(offset[0] + scale[0] + objectOffset[0], offset[1] + scale[1] + objectOffset[1], offset[2] + scale[2] + objectOffset[2]);
+            if(blenderContext.getBlenderKey().isFixUpAxis()) {
+                float y = translationVector.y;
+                translationVector.y = translationVector.z;
+                translationVector.z = y == 0 ? 0 : -y;
             }
-            if (caps[0] != null) {
-                caps[0].getLocalTranslation().set(node.getLocalTranslation()).subtractLocal(translationVector);
-                node.attachChild(caps[0]);
+            
+            // getting/calculating repeats amount
+            int count = 0;
+            if (fittype == 0) {// Fixed count
+                count = ((Number) modifierData.get("count")).intValue() - 1;
+            } else if (fittype == 1) {// Fixed length
+                float length = ((Number) modifierData.get("length")).floatValue();
+                if (translationVector.length() > 0.0f) {
+                    count = (int) (length / translationVector.length()) - 1;
+                }
+            } else if (fittype == 2) {// Fit curve
+                throw new IllegalStateException("Fit curve should be transformed to Fixed Length array type!");
+            } else {
+                throw new IllegalStateException("Unknown fit type: " + fittype);
             }
-            if (caps[1] != null) {
-                caps[1].getLocalTranslation().set(newTranslation).addLocal(translationVector);
-                node.attachChild(caps[1]);
+    
+            // adding translated nodes and caps
+            if (count > 0) {
+                Node[] arrayNodes = new Node[count];
+                Vector3f newTranslation = new Vector3f();
+                for (int i = 0; i < count; ++i) {
+                    newTranslation.addLocal(translationVector);
+                    Node nodeClone = (Node) node.clone();
+                    nodeClone.setLocalTranslation(newTranslation);
+                    arrayNodes[i] = nodeClone;
+                }
+                for (Node nodeClone : arrayNodes) {
+                    node.attachChild(nodeClone);
+                }
+                if (caps[0] != null) {
+                    caps[0].getLocalTranslation().set(node.getLocalTranslation()).subtractLocal(translationVector);
+                    node.attachChild(caps[0]);
+                }
+                if (caps[1] != null) {
+                    caps[1].getLocalTranslation().set(newTranslation).addLocal(translationVector);
+                    node.attachChild(caps[1]);
+                }
             }
         }
-        return node;
     }
 }

+ 107 - 109
engine/src/blender/com/jme3/scene/plugins/blender/modifiers/MirrorModifier.java

@@ -64,132 +64,130 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper;
     }
 
     @Override
-    public Node apply(Node node, BlenderContext blenderContext) {
+    public void apply(Node node, BlenderContext blenderContext) {
         if (invalid) {
             LOGGER.log(Level.WARNING, "Mirror modifier is invalid! Cannot be applied to: {0}", node.getName());
-            return node;
-        }
-
-        int flag = ((Number) modifierData.get("flag")).intValue();
-        float[] mirrorFactor = new float[] { (flag & 0x08) != 0 ? -1.0f : 1.0f, (flag & 0x10) != 0 ? -1.0f : 1.0f, (flag & 0x20) != 0 ? -1.0f : 1.0f };
-        if (blenderContext.getBlenderKey().isFixUpAxis()) {
-            float temp = mirrorFactor[1];
-            mirrorFactor[1] = mirrorFactor[2];
-            mirrorFactor[2] = temp;
-        }
-        float[] center = new float[] { 0.0f, 0.0f, 0.0f };
-        Pointer pObject = (Pointer) modifierData.get("mirrorob");
-        if (pObject != null) {
-            Structure objectStructure;
-            try {
-                objectStructure = pObject.fetchData(blenderContext.getInputStream()).get(0);
-                ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
-                Node object = (Node) objectHelper.toObject(objectStructure, blenderContext);
-                if (object != null) {
-                    Vector3f translation = object.getWorldTranslation();
-                    center[0] = translation.x;
-                    center[1] = translation.y;
-                    center[2] = translation.z;
+        } else {
+            int flag = ((Number) modifierData.get("flag")).intValue();
+            float[] mirrorFactor = new float[] { (flag & 0x08) != 0 ? -1.0f : 1.0f, (flag & 0x10) != 0 ? -1.0f : 1.0f, (flag & 0x20) != 0 ? -1.0f : 1.0f };
+            if (blenderContext.getBlenderKey().isFixUpAxis()) {
+                float temp = mirrorFactor[1];
+                mirrorFactor[1] = mirrorFactor[2];
+                mirrorFactor[2] = temp;
+            }
+            float[] center = new float[] { 0.0f, 0.0f, 0.0f };
+            Pointer pObject = (Pointer) modifierData.get("mirrorob");
+            if (pObject != null) {
+                Structure objectStructure;
+                try {
+                    objectStructure = pObject.fetchData(blenderContext.getInputStream()).get(0);
+                    ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
+                    Node object = (Node) objectHelper.toObject(objectStructure, blenderContext);
+                    if (object != null) {
+                        Vector3f translation = object.getWorldTranslation();
+                        center[0] = translation.x;
+                        center[1] = translation.y;
+                        center[2] = translation.z;
+                    }
+                } catch (BlenderFileException e) {
+                    LOGGER.log(Level.SEVERE, "Cannot load mirror''s reference object. Cause: {0}", e.getLocalizedMessage());
                 }
-            } catch (BlenderFileException e) {
-                LOGGER.log(Level.SEVERE, "Cannot load mirror''s reference object. Cause: {0}", e.getLocalizedMessage());
             }
-        }
-        float tolerance = ((Number) modifierData.get("tolerance")).floatValue();
-        boolean mirrorU = (flag & 0x01) != 0;
-        boolean mirrorV = (flag & 0x02) != 0;
-        // boolean mirrorVGroup = (flag & 0x20) != 0;
-
-        Set<Integer> modifiedIndexes = new HashSet<Integer>();
-        List<Geometry> geometriesToAdd = new ArrayList<Geometry>();
-        for (int mirrorIndex = 0; mirrorIndex < 3; ++mirrorIndex) {
-            if (mirrorFactor[mirrorIndex] == -1.0f) {
-                for (Spatial spatial : node.getChildren()) {
-                    if (spatial instanceof Geometry) {
-                        Mesh mesh = ((Geometry) spatial).getMesh();
-                        Mesh clone = mesh.deepClone();
-
-                        // getting buffers
-                        FloatBuffer position = mesh.getFloatBuffer(Type.Position);
-                        FloatBuffer bindPosePosition = mesh.getFloatBuffer(Type.BindPosePosition);
-
-                        FloatBuffer clonePosition = clone.getFloatBuffer(Type.Position);
-                        FloatBuffer cloneBindPosePosition = clone.getFloatBuffer(Type.BindPosePosition);
-                        FloatBuffer cloneNormals = clone.getFloatBuffer(Type.Normal);
-                        FloatBuffer cloneBindPoseNormals = clone.getFloatBuffer(Type.BindPoseNormal);
-                        Buffer cloneIndexes = clone.getBuffer(Type.Index).getData();
-
-                        for (int i = 0; i < cloneIndexes.limit(); ++i) {
-                            int index = cloneIndexes instanceof ShortBuffer ? ((ShortBuffer) cloneIndexes).get(i) : ((IntBuffer) cloneIndexes).get(i);
-                            if (!modifiedIndexes.contains((int) index)) {
-                                modifiedIndexes.add((int) index);
-                                int valueIndex = index * 3 + mirrorIndex;
-
-                                float value = clonePosition.get(valueIndex);
-                                float d = center[mirrorIndex] - value;
-
-                                if (Math.abs(d) <= tolerance) {
-                                    clonePosition.put(valueIndex, center[mirrorIndex]);
-                                    if (cloneBindPosePosition != null) {
-                                        cloneBindPosePosition.put(valueIndex, center[mirrorIndex]);
-                                    }
-                                    position.put(valueIndex, center[mirrorIndex]);
-                                    if (bindPosePosition != null) {
-                                        bindPosePosition.put(valueIndex, center[mirrorIndex]);
+            float tolerance = ((Number) modifierData.get("tolerance")).floatValue();
+            boolean mirrorU = (flag & 0x01) != 0;
+            boolean mirrorV = (flag & 0x02) != 0;
+            // boolean mirrorVGroup = (flag & 0x20) != 0;
+
+            Set<Integer> modifiedIndexes = new HashSet<Integer>();
+            List<Geometry> geometriesToAdd = new ArrayList<Geometry>();
+            for (int mirrorIndex = 0; mirrorIndex < 3; ++mirrorIndex) {
+                if (mirrorFactor[mirrorIndex] == -1.0f) {
+                    for (Spatial spatial : node.getChildren()) {
+                        if (spatial instanceof Geometry) {
+                            Mesh mesh = ((Geometry) spatial).getMesh();
+                            Mesh clone = mesh.deepClone();
+
+                            // getting buffers
+                            FloatBuffer position = mesh.getFloatBuffer(Type.Position);
+                            FloatBuffer bindPosePosition = mesh.getFloatBuffer(Type.BindPosePosition);
+
+                            FloatBuffer clonePosition = clone.getFloatBuffer(Type.Position);
+                            FloatBuffer cloneBindPosePosition = clone.getFloatBuffer(Type.BindPosePosition);
+                            FloatBuffer cloneNormals = clone.getFloatBuffer(Type.Normal);
+                            FloatBuffer cloneBindPoseNormals = clone.getFloatBuffer(Type.BindPoseNormal);
+                            Buffer cloneIndexes = clone.getBuffer(Type.Index).getData();
+
+                            for (int i = 0; i < cloneIndexes.limit(); ++i) {
+                                int index = cloneIndexes instanceof ShortBuffer ? ((ShortBuffer) cloneIndexes).get(i) : ((IntBuffer) cloneIndexes).get(i);
+                                if (!modifiedIndexes.contains((int) index)) {
+                                    modifiedIndexes.add((int) index);
+                                    int valueIndex = index * 3 + mirrorIndex;
+
+                                    float value = clonePosition.get(valueIndex);
+                                    float d = center[mirrorIndex] - value;
+
+                                    if (Math.abs(d) <= tolerance) {
+                                        clonePosition.put(valueIndex, center[mirrorIndex]);
+                                        if (cloneBindPosePosition != null) {
+                                            cloneBindPosePosition.put(valueIndex, center[mirrorIndex]);
+                                        }
+                                        position.put(valueIndex, center[mirrorIndex]);
+                                        if (bindPosePosition != null) {
+                                            bindPosePosition.put(valueIndex, center[mirrorIndex]);
+                                        }
+                                    } else {
+                                        clonePosition.put(valueIndex, value + 2.0f * d);
+                                        if (cloneBindPosePosition != null) {
+                                            cloneBindPosePosition.put(valueIndex, value + 2.0f * d);
+                                        }
                                     }
-                                } else {
-                                    clonePosition.put(valueIndex, value + 2.0f * d);
-                                    if (cloneBindPosePosition != null) {
-                                        cloneBindPosePosition.put(valueIndex, value + 2.0f * d);
+                                    cloneNormals.put(valueIndex, -cloneNormals.get(valueIndex));
+                                    if (cloneBindPoseNormals != null) {
+                                        cloneBindPoseNormals.put(valueIndex, -cloneNormals.get(valueIndex));
                                     }
                                 }
-                                cloneNormals.put(valueIndex, -cloneNormals.get(valueIndex));
-                                if (cloneBindPoseNormals != null) {
-                                    cloneBindPoseNormals.put(valueIndex, -cloneNormals.get(valueIndex));
-                                }
                             }
-                        }
-                        modifiedIndexes.clear();
-
-                        // flipping index order
-                        for (int i = 0; i < cloneIndexes.limit(); i += 3) {
-                            if (cloneIndexes instanceof ShortBuffer) {
-                                short index = ((ShortBuffer) cloneIndexes).get(i + 2);
-                                ((ShortBuffer) cloneIndexes).put(i + 2, ((ShortBuffer) cloneIndexes).get(i + 1));
-                                ((ShortBuffer) cloneIndexes).put(i + 1, index);
-                            } else {
-                                int index = ((IntBuffer) cloneIndexes).get(i + 2);
-                                ((IntBuffer) cloneIndexes).put(i + 2, ((IntBuffer) cloneIndexes).get(i + 1));
-                                ((IntBuffer) cloneIndexes).put(i + 1, index);
+                            modifiedIndexes.clear();
+
+                            // flipping index order
+                            for (int i = 0; i < cloneIndexes.limit(); i += 3) {
+                                if (cloneIndexes instanceof ShortBuffer) {
+                                    short index = ((ShortBuffer) cloneIndexes).get(i + 2);
+                                    ((ShortBuffer) cloneIndexes).put(i + 2, ((ShortBuffer) cloneIndexes).get(i + 1));
+                                    ((ShortBuffer) cloneIndexes).put(i + 1, index);
+                                } else {
+                                    int index = ((IntBuffer) cloneIndexes).get(i + 2);
+                                    ((IntBuffer) cloneIndexes).put(i + 2, ((IntBuffer) cloneIndexes).get(i + 1));
+                                    ((IntBuffer) cloneIndexes).put(i + 1, index);
+                                }
                             }
-                        }
 
-                        if (mirrorU && clone.getBuffer(Type.TexCoord) != null) {
-                            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 (mirrorU && clone.getBuffer(Type.TexCoord) != null) {
+                                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 && clone.getBuffer(Type.TexCoord) != null) {
-                            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));
+                            if (mirrorV && clone.getBuffer(Type.TexCoord) != null) {
+                                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.setMaterial(((Geometry) spatial).getMaterial());
-                        geometriesToAdd.add(geometry);
+                            Geometry geometry = new Geometry(null, clone);
+                            geometry.setMaterial(((Geometry) spatial).getMaterial());
+                            geometriesToAdd.add(geometry);
+                        }
                     }
-                }
 
-                // adding meshes to node
-                for (Geometry geometry : geometriesToAdd) {
-                    node.attachChild(geometry);
+                    // adding meshes to node
+                    for (Geometry geometry : geometriesToAdd) {
+                        node.attachChild(geometry);
+                    }
+                    geometriesToAdd.clear();
                 }
-                geometriesToAdd.clear();
             }
         }
-        return node;
     }
 }

+ 1 - 2
engine/src/blender/com/jme3/scene/plugins/blender/modifiers/Modifier.java

@@ -37,9 +37,8 @@ public abstract class Modifier {
      *            the node that will have modifier applied
      * @param blenderContext
      *            the blender context
-     * @return the node with applied modifier
      */
-    public abstract Node apply(Node node, BlenderContext blenderContext);
+    public abstract void apply(Node node, BlenderContext blenderContext);
 
     /**
      * Determines if the modifier can be applied multiple times over one mesh.

+ 1 - 2
engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ObjectAnimationModifier.java

@@ -65,7 +65,7 @@ import com.jme3.scene.plugins.blender.file.BlenderFileException;
     }
 
     @Override
-    public Node apply(Node node, BlenderContext blenderContext) {
+    public void apply(Node node, BlenderContext blenderContext) {
         if (invalid) {
             LOGGER.log(Level.WARNING, "Armature modifier is invalid! Cannot be applied to: {0}", node.getName());
         }// if invalid, animData will be null
@@ -85,6 +85,5 @@ import com.jme3.scene.plugins.blender.file.BlenderFileException;
                 node.addControl(control);
             }
         }
-        return node;
     }
 }

+ 28 - 30
engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ParticlesModifier.java

@@ -55,42 +55,40 @@ import java.util.logging.Logger;
     }
 
     @Override
-    public Node apply(Node node, BlenderContext blenderContext) {
+    public void apply(Node node, BlenderContext blenderContext) {
         if (invalid) {
             LOGGER.log(Level.WARNING, "Particles modifier is invalid! Cannot be applied to: {0}", node.getName());
-            return node;
-        }
-
-        MaterialHelper materialHelper = blenderContext.getHelper(MaterialHelper.class);
-        ParticleEmitter emitter = particleEmitter.clone();
+        } else {
+            MaterialHelper materialHelper = blenderContext.getHelper(MaterialHelper.class);
+            ParticleEmitter emitter = particleEmitter.clone();
 
-        // veryfying the alpha function for particles' texture
-        Integer alphaFunction = MaterialHelper.ALPHA_MASK_HYPERBOLE;
-        char nameSuffix = emitter.getName().charAt(emitter.getName().length() - 1);
-        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));
+            // veryfying the alpha function for particles' texture
+            Integer alphaFunction = MaterialHelper.ALPHA_MASK_HYPERBOLE;
+            char nameSuffix = emitter.getName().charAt(emitter.getName().length() - 1);
+            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));
 
-        // applying emitter shape
-        EmitterShape emitterShape = emitter.getShape();
-        List<Mesh> meshes = new ArrayList<Mesh>();
-        for (Spatial spatial : node.getChildren()) {
-            if (spatial instanceof Geometry) {
-                Mesh mesh = ((Geometry) spatial).getMesh();
-                if (mesh != null) {
-                    meshes.add(mesh);
-                    Material material = materialHelper.getParticlesMaterial(((Geometry) spatial).getMaterial(), alphaFunction, blenderContext);
-                    emitter.setMaterial(material);// TODO: divide into several pieces
+            // applying emitter shape
+            EmitterShape emitterShape = emitter.getShape();
+            List<Mesh> meshes = new ArrayList<Mesh>();
+            for (Spatial spatial : node.getChildren()) {
+                if (spatial instanceof Geometry) {
+                    Mesh mesh = ((Geometry) spatial).getMesh();
+                    if (mesh != null) {
+                        meshes.add(mesh);
+                        Material material = materialHelper.getParticlesMaterial(((Geometry) spatial).getMaterial(), alphaFunction, blenderContext);
+                        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);
+        }
     }
 }