diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Edge.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Edge.java index 2d47df89c..48f9b8990 100644 --- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Edge.java +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Edge.java @@ -18,7 +18,7 @@ import com.jme3.scene.plugins.blender.meshes.IndexesLoop.IndexPredicate; * * @author Marcin Roguski (Kaelthas) */ -/* package */class Edge extends Line { +public class Edge extends Line { private static final long serialVersionUID = 7172714692126675311L; private static final Logger LOGGER = Logger.getLogger(Edge.class.getName()); diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Face.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Face.java index 7a8ac7173..6d94a4707 100644 --- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Face.java +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Face.java @@ -25,13 +25,13 @@ import com.jme3.scene.plugins.blender.file.Structure; * * @author Marcin Roguski (Kaelthas) */ -/* package */class Face implements Comparator { +public class Face implements Comparator { private static final Logger LOGGER = Logger.getLogger(Face.class.getName()); /** The indexes loop of the face. */ private IndexesLoop indexes; - - private List triangulatedFaces; + + private List triangulatedFaces; /** Indicates if the face is smooth or solid. */ private boolean smooth; /** The material index of the face. */ @@ -116,7 +116,14 @@ import com.jme3.scene.plugins.blender.file.Structure; } return indexes.get(indexPosition); } - + + /** + * @return the mesh this face belongs to + */ + public TemporalMesh getTemporalMesh() { + return temporalMesh; + } + /** * @return the original indexes of the face */ @@ -129,11 +136,11 @@ import com.jme3.scene.plugins.blender.file.Structure; */ @SuppressWarnings("unchecked") public List> getCurrentIndexes() { - if(triangulatedFaces == null) { + if (triangulatedFaces == null) { return Arrays.asList(indexes.getAll()); } List> result = new ArrayList>(triangulatedFaces.size()); - for(IndexesLoop loop : triangulatedFaces) { + for (IndexesLoop loop : triangulatedFaces) { result.add(loop.getAll()); } return result; @@ -155,9 +162,10 @@ import com.jme3.scene.plugins.blender.file.Structure; if (triangleIndexes.length != 3) { throw new IllegalArgumentException("Cannot detach triangle with that does not have 3 indexes!"); } + MeshHelper meshHelper = temporalMesh.getBlenderContext().getHelper(MeshHelper.class); List detachedFaces = new ArrayList(); List path = new ArrayList(indexes.size()); - + boolean[] edgeRemoved = new boolean[] { indexes.removeEdge(triangleIndexes[0], triangleIndexes[1]), indexes.removeEdge(triangleIndexes[0], triangleIndexes[2]), indexes.removeEdge(triangleIndexes[1], triangleIndexes[2]) }; Integer[][] indexesPairs = new Integer[][] { new Integer[] { triangleIndexes[0], triangleIndexes[1] }, new Integer[] { triangleIndexes[0], triangleIndexes[2] }, new Integer[] { triangleIndexes[1], triangleIndexes[2] } }; @@ -171,7 +179,8 @@ import com.jme3.scene.plugins.blender.file.Structure; throw new IllegalStateException("Triangulation failed. Cannot find path between two indexes. Please apply triangulation in Blender as a workaround."); } if (detachedFaces.size() == 0 && path.size() < indexes.size()) { - detachedFaces.add(new Face(path.toArray(new Integer[path.size()]), smooth, materialNumber, faceUVCoords, vertexColors, temporalMesh)); + Integer[] indexesSublist = path.toArray(new Integer[path.size()]); + detachedFaces.add(new Face(indexesSublist, smooth, materialNumber, meshHelper.selectUVSubset(this, indexesSublist), vertexColors, temporalMesh)); for (int j = 0; j < path.size() - 1; ++j) { indexes.removeEdge(path.get(j), path.get(j + 1)); } @@ -244,17 +253,13 @@ import com.jme3.scene.plugins.blender.file.Structure; /** * The method triangulates the face. - * @param vertices - * the vertices of the mesh (all verts and not only those belonging to the face) - * @param normals - * the normals of the mesh (all normals and not only those belonging to the face) */ - public void triangulate(List vertices, List normals) { + public void triangulate() { LOGGER.fine("Triangulating face."); assert indexes.size() >= 3 : "Invalid indexes amount for face. 3 is the required minimum!"; triangulatedFaces = new ArrayList(indexes.size() - 2); Integer[] indexes = new Integer[3]; - + try { List facesToTriangulate = new ArrayList(Arrays.asList(this.clone())); while (facesToTriangulate.size() > 0) { @@ -264,30 +269,27 @@ import com.jme3.scene.plugins.blender.file.Structure; indexes[0] = face.getIndex(0); indexes[1] = face.findClosestVertex(indexes[0], -1); indexes[2] = face.findClosestVertex(indexes[0], indexes[1]); - + LOGGER.finer("Veryfying improper triangulation of the temporal mesh."); - if(indexes[0] < 0 || indexes[1] < 0 || indexes[2] < 0) { - throw new BlenderFileException("Unable to find two closest vertices while triangulating face in mesh: " + temporalMesh + - "Please apply triangulation modifier in blender as a workaround and load again!"); + if (indexes[0] < 0 || indexes[1] < 0 || indexes[2] < 0) { + throw new BlenderFileException("Unable to find two closest vertices while triangulating face in mesh: " + temporalMesh + "Please apply triangulation modifier in blender as a workaround and load again!"); } - if(previousIndex1 == indexes[0] && previousIndex2 == indexes[1] && previousIndex3 == indexes[2]) { - throw new BlenderFileException("Infinite loop detected during triangulation of mesh: " + temporalMesh + - "Please apply triangulation modifier in blender as a workaround and load again!"); + if (previousIndex1 == indexes[0] && previousIndex2 == indexes[1] && previousIndex3 == indexes[2]) { + throw new BlenderFileException("Infinite loop detected during triangulation of mesh: " + temporalMesh + "Please apply triangulation modifier in blender as a workaround and load again!"); } previousIndex1 = indexes[0]; previousIndex2 = indexes[1]; previousIndex3 = indexes[2]; - + Arrays.sort(indexes, this); facesToTriangulate.addAll(face.detachTriangle(indexes)); triangulatedFaces.add(new IndexesLoop(indexes)); } } - } catch(BlenderFileException e) { - LOGGER.log(Level.WARNING, "Errors occured during face triangulation: {0}. The face will be triangulated with the most direct algorithm, " + - "but the results might not be identical to blender.", e.getLocalizedMessage()); + } catch (BlenderFileException e) { + LOGGER.log(Level.WARNING, "Errors occured during face triangulation: {0}. The face will be triangulated with the most direct algorithm, " + "but the results might not be identical to blender.", e.getLocalizedMessage()); indexes[0] = this.getIndex(0); - for(int i=1;i> selectUVSubset(Face face, Integer... indexesSublist) { + Map> result = null; + if (face.getUvSets() != null) { + result = new HashMap>(); + for (Entry> entry : face.getUvSets().entrySet()) { + List uvs = new ArrayList(indexesSublist.length); + for (Integer index : indexesSublist) { + uvs.add(entry.getValue().get(face.getIndexes().indexOf(index))); + } + result.put(entry.getKey(), uvs); + } + } + return result; + } + /** * Returns the black unshaded material. It is used for lines and points because that is how blender * renders it. diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Point.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Point.java index ef4c98430..04f705e5b 100644 --- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Point.java +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Point.java @@ -17,7 +17,7 @@ import com.jme3.scene.plugins.blender.meshes.IndexesLoop.IndexPredicate; * * @author Marcin Roguski (Kaelthas) */ -/* package */class Point { +public class Point { private static final Logger LOGGER = Logger.getLogger(Point.class.getName()); /** The point's index. */ diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/TemporalMesh.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/TemporalMesh.java index fc71fe4d1..da10c676d 100644 --- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/TemporalMesh.java +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/TemporalMesh.java @@ -4,15 +4,11 @@ import java.nio.IntBuffer; import java.nio.ShortBuffer; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; -import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -32,7 +28,6 @@ import com.jme3.scene.plugins.blender.BlenderContext.LoadedDataType; import com.jme3.scene.plugins.blender.file.BlenderFileException; import com.jme3.scene.plugins.blender.file.Structure; import com.jme3.scene.plugins.blender.materials.MaterialContext; -import com.jme3.scene.plugins.blender.meshes.IndexesLoop.IndexPredicate; import com.jme3.scene.plugins.blender.meshes.MeshBuffers.BoneBuffersData; import com.jme3.scene.plugins.blender.modifiers.Modifier; import com.jme3.scene.plugins.blender.objects.Properties; @@ -123,6 +118,62 @@ public class TemporalMesh extends Geometry { } } + /** + * @return the blender context + */ + public BlenderContext getBlenderContext() { + return blenderContext; + } + + /** + * @return the vertices of the mesh + */ + public List getVertices() { + return vertices; + } + + /** + * @return the normals of the mesh + */ + public List getNormals() { + return normals; + } + + /** + * @return all faces + */ + public List getFaces() { + return faces; + } + + /** + * @return all edges + */ + public List getEdges() { + return edges; + } + + /** + * @return all points (do not mistake it with vertices) + */ + public List getPoints() { + return points; + } + + /** + * @return all vertices colors + */ + public List getVerticesColors() { + return verticesColors; + } + + /** + * @return all vertex groups for the vertices (each map has groups for the proper vertex) + */ + public List> getVertexGroups() { + return vertexGroups; + } + @Override public TemporalMesh clone() { try { @@ -159,20 +210,6 @@ public class TemporalMesh extends Geometry { return null; } - /** - * @return the vertices of the mesh - */ - protected List getVertices() { - return vertices; - } - - /** - * @return the normals of the mesh - */ - protected List getNormals() { - return normals; - } - @Override public void updateModelBound() { if (boundingBox == null) { @@ -212,7 +249,7 @@ public class TemporalMesh extends Geometry { public void triangulate() { LOGGER.fine("Triangulating temporal mesh."); for (Face face : faces) { - face.triangulate(vertices, normals); + face.triangulate(); } } @@ -248,19 +285,6 @@ public class TemporalMesh extends Geometry { boneIndexes.putAll(mesh.boneIndexes); } - /** - * Translate all vertices by the given vector. - * @param translation - * the translation vector - * @return this mesh after translation (NO new instance is created) - */ - public TemporalMesh translate(Vector3f translation) { - for (Vector3f v : vertices) { - v.addLocal(translation); - } - return this; - } - /** * Sets the properties of the mesh. * @param properties @@ -304,47 +328,6 @@ public class TemporalMesh extends Geometry { return vertices.size(); } - /** - * Returns the vertex at the given position. - * @param i - * the vertex position - * @return the vertex at the given position - */ - public Vector3f getVertex(int i) { - return vertices.get(i); - } - - /** - * Returns the normal at the given position. - * @param i - * the normal position - * @return the normal at the given position - */ - public Vector3f getNormal(int i) { - return normals.get(i); - } - - /** - * Returns the vertex groups at the given vertex index. - * @param i - * the vertex groups for vertex with a given index - * @return the vertex groups at the given vertex index - */ - public Map getVertexGroups(int i) { - return vertexGroups.size() > i ? vertexGroups.get(i) : null; - } - - /** - * @return a collection of vertex group names for this mesh - */ - public Collection getVertexGroupNames() { - Set result = new HashSet(); - for (Map groups : vertexGroups) { - result.addAll(groups.keySet()); - } - return result; - } - /** * Removes all vertices from the mesh. */ @@ -358,86 +341,6 @@ public class TemporalMesh extends Geometry { points.clear(); } - /** - * Every face, edge and point that contains - * the vertex will be removed. - * @param index - * the index of a vertex to be removed - * @throws IndexOutOfBoundsException - * thrown when given index is negative or beyond the count of vertices - */ - public void removeVertexAt(final int index) { - if (index < 0 || index >= vertices.size()) { - throw new IndexOutOfBoundsException("The given index is out of bounds: " + index); - } - - vertices.remove(index); - normals.remove(index); - if(vertexGroups.size() > 0) { - vertexGroups.remove(index); - } - if(verticesColors.size() > 0) { - verticesColors.remove(index); - } - - IndexPredicate shiftPredicate = new IndexPredicate() { - @Override - public boolean execute(Integer i) { - return i > index; - } - }; - for (int i = faces.size() - 1; i >= 0; --i) { - Face face = faces.get(i); - if (face.getIndexes().indexOf(index) >= 0) { - faces.remove(i); - } else { - face.getIndexes().shiftIndexes(-1, shiftPredicate); - } - } - for (int i = edges.size() - 1; i >= 0; --i) { - Edge edge = edges.get(i); - if (edge.getFirstIndex() == index || edge.getSecondIndex() == index) { - edges.remove(i); - } else { - edge.shiftIndexes(-1, shiftPredicate); - } - } - for (int i = points.size() - 1; i >= 0; --i) { - Point point = points.get(i); - if (point.getIndex() == index) { - points.remove(i); - } else { - point.shiftIndexes(-1, shiftPredicate); - } - } - } - - /** - * Flips the order of the mesh's indexes. - */ - public void flipIndexes() { - for (Face face : faces) { - face.flipIndexes(); - } - for (Edge edge : edges) { - edge.flipIndexes(); - } - Collections.reverse(points); - } - - /** - * Flips UV coordinates. - * @param u - * indicates if U coords should be flipped - * @param v - * indicates if V coords should be flipped - */ - public void flipUV(boolean u, boolean v) { - for (Face face : faces) { - face.flipUV(u, v); - } - } - /** * The mesh builds geometries from the mesh. The result is stored in the blender context * under the mesh's OMA. @@ -513,7 +416,8 @@ public class TemporalMesh extends Geometry { } } - meshBuffers.append(face.isSmooth(), tempVerts, tempNormals, face.getUvSets(), tempVertColors, boneBuffers); + Map> uvs = meshHelper.selectUVSubset(face, indexes.toArray(new Integer[indexes.size()])); + meshBuffers.append(face.isSmooth(), tempVerts, tempNormals, uvs, tempVertColors, boneBuffers); } } diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/modifiers/ArrayModifier.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/modifiers/ArrayModifier.java index 4a34a84d5..e00c22640 100644 --- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/modifiers/ArrayModifier.java +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/modifiers/ArrayModifier.java @@ -210,15 +210,28 @@ import com.jme3.scene.shape.Curve; if (count > 0) { TemporalMesh originalMesh = temporalMesh.clone(); for (int i = 0; i < count; ++i) { - temporalMesh.append(originalMesh.clone().translate(totalTranslation)); + TemporalMesh clone = originalMesh.clone(); + for (Vector3f v : clone.getVertices()) { + v.addLocal(totalTranslation); + } + temporalMesh.append(clone); totalTranslation.addLocal(translationVector); } } if (caps[0] != null) { - temporalMesh.append(caps[0].clone().translate(translationVector.multLocal(-1))); + translationVector.multLocal(-1); + TemporalMesh capsClone = caps[0].clone(); + for (Vector3f v : capsClone.getVertices()) { + v.addLocal(translationVector); + } + temporalMesh.append(capsClone); } if (caps[1] != null) { - temporalMesh.append(caps[1].clone().translate(totalTranslation)); + TemporalMesh capsClone = caps[1].clone(); + for (Vector3f v : capsClone.getVertices()) { + v.addLocal(totalTranslation); + } + temporalMesh.append(capsClone); } } else { LOGGER.log(Level.WARNING, "Cannot find temporal mesh for node: {0}. The modifier will NOT be applied!", node); diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/modifiers/MaskModifier.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/modifiers/MaskModifier.java index b8c05c91f..9201800e6 100644 --- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/modifiers/MaskModifier.java +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/modifiers/MaskModifier.java @@ -1,10 +1,11 @@ package com.jme3.scene.plugins.blender.modifiers; import java.util.ArrayList; -import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -14,6 +15,10 @@ import com.jme3.scene.plugins.blender.animations.BoneContext; import com.jme3.scene.plugins.blender.file.BlenderFileException; import com.jme3.scene.plugins.blender.file.Pointer; import com.jme3.scene.plugins.blender.file.Structure; +import com.jme3.scene.plugins.blender.meshes.Edge; +import com.jme3.scene.plugins.blender.meshes.Face; +import com.jme3.scene.plugins.blender.meshes.IndexesLoop.IndexPredicate; +import com.jme3.scene.plugins.blender.meshes.Point; import com.jme3.scene.plugins.blender.meshes.TemporalMesh; /** @@ -22,12 +27,12 @@ import com.jme3.scene.plugins.blender.meshes.TemporalMesh; * @author Marcin Roguski (Kaelthas) */ /* package */class MaskModifier extends Modifier { - private static final Logger LOGGER = Logger.getLogger(MaskModifier.class.getName()); + private static final Logger LOGGER = Logger.getLogger(MaskModifier.class.getName()); - private static final int FLAG_INVERT_MASK = 0x01; + private static final int FLAG_INVERT_MASK = 0x01; - private static final int MODE_VERTEX_GROUP = 0; - private static final int MODE_ARMATURE = 1; + private static final int MODE_VERTEX_GROUP = 0; + private static final int MODE_ARMATURE = 1; private Pointer pArmatureObject; private String vertexGroupName; @@ -37,7 +42,7 @@ import com.jme3.scene.plugins.blender.meshes.TemporalMesh; if (this.validate(modifierStructure, blenderContext)) { int flag = ((Number) modifierStructure.getFieldValue("flag")).intValue(); invertMask = (flag & FLAG_INVERT_MASK) != 0; - + int mode = ((Number) modifierStructure.getFieldValue("mode")).intValue(); if (mode == MODE_VERTEX_GROUP) { vertexGroupName = modifierStructure.getFieldValue("vgroup").toString(); @@ -78,7 +83,10 @@ import com.jme3.scene.plugins.blender.meshes.TemporalMesh; // if the mesh has no vertex groups then remove all verts // if the mesh has at least one vertex group - then do nothing // I have no idea why we should do that, but blender works this way - Collection vertexGroupNames = temporalMesh.getVertexGroupNames(); + Set vertexGroupNames = new HashSet(); + for (Map groups : temporalMesh.getVertexGroups()) { + vertexGroupNames.addAll(groups.keySet()); + } if (vertexGroupNames.size() == 0 && !invertMask || vertexGroupNames.size() > 0 && invertMask) { temporalMesh.clear(); } @@ -87,9 +95,9 @@ import com.jme3.scene.plugins.blender.meshes.TemporalMesh; if (vertexGroupsToRemove.size() > 0) { List vertsToBeRemoved = new ArrayList(); for (int i = 0; i < temporalMesh.getVertexCount(); ++i) { - Map vertexGroups = temporalMesh.getVertexGroups(i); + Map vertexGroups = temporalMesh.getVertexGroups().get(i); boolean hasVertexGroup = false; - if(vertexGroups != null) { + if (vertexGroups != null) { for (String groupName : vertexGroupsToRemove) { Float weight = vertexGroups.get(groupName); if (weight != null && weight > 0) { @@ -106,7 +114,7 @@ import com.jme3.scene.plugins.blender.meshes.TemporalMesh; Collections.reverse(vertsToBeRemoved); for (Integer vertexIndex : vertsToBeRemoved) { - temporalMesh.removeVertexAt(vertexIndex); + this.removeVertexAt(vertexIndex, temporalMesh); } } } else { @@ -115,6 +123,60 @@ import com.jme3.scene.plugins.blender.meshes.TemporalMesh; } } + /** + * Every face, edge and point that contains + * the vertex will be removed. + * @param index + * the index of a vertex to be removed + * @throws IndexOutOfBoundsException + * thrown when given index is negative or beyond the count of vertices + */ + private void removeVertexAt(final int index, TemporalMesh temporalMesh) { + if (index < 0 || index >= temporalMesh.getVertexCount()) { + throw new IndexOutOfBoundsException("The given index is out of bounds: " + index); + } + + temporalMesh.getVertices().remove(index); + temporalMesh.getNormals().remove(index); + if (temporalMesh.getVertexGroups().size() > 0) { + temporalMesh.getVertexGroups().remove(index); + } + if (temporalMesh.getVerticesColors().size() > 0) { + temporalMesh.getVerticesColors().remove(index); + } + + IndexPredicate shiftPredicate = new IndexPredicate() { + @Override + public boolean execute(Integer i) { + return i > index; + } + }; + for (int i = temporalMesh.getFaces().size() - 1; i >= 0; --i) { + Face face = temporalMesh.getFaces().get(i); + if (face.getIndexes().indexOf(index) >= 0) { + temporalMesh.getFaces().remove(i); + } else { + face.getIndexes().shiftIndexes(-1, shiftPredicate); + } + } + for (int i = temporalMesh.getEdges().size() - 1; i >= 0; --i) { + Edge edge = temporalMesh.getEdges().get(i); + if (edge.getFirstIndex() == index || edge.getSecondIndex() == index) { + temporalMesh.getEdges().remove(i); + } else { + edge.shiftIndexes(-1, shiftPredicate); + } + } + for (int i = temporalMesh.getPoints().size() - 1; i >= 0; --i) { + Point point = temporalMesh.getPoints().get(i); + if (point.getIndex() == index) { + temporalMesh.getPoints().remove(i); + } else { + point.shiftIndexes(-1, shiftPredicate); + } + } + } + /** * Reads the names of the bones from the given bone base. * @param boneBase diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/modifiers/MirrorModifier.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/modifiers/MirrorModifier.java index 67fc453fe..36538afc3 100644 --- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/modifiers/MirrorModifier.java +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/modifiers/MirrorModifier.java @@ -1,5 +1,6 @@ package com.jme3.scene.plugins.blender.modifiers; +import java.util.Collections; import java.util.logging.Level; import java.util.logging.Logger; @@ -10,6 +11,8 @@ import com.jme3.scene.plugins.blender.BlenderContext; import com.jme3.scene.plugins.blender.file.BlenderFileException; import com.jme3.scene.plugins.blender.file.Pointer; import com.jme3.scene.plugins.blender.file.Structure; +import com.jme3.scene.plugins.blender.meshes.Edge; +import com.jme3.scene.plugins.blender.meshes.Face; import com.jme3.scene.plugins.blender.meshes.TemporalMesh; import com.jme3.scene.plugins.blender.objects.ObjectHelper; @@ -69,8 +72,8 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper; tolerance = ((Number) modifierStructure.getFieldValue("tolerance")).floatValue(); pMirrorObject = (Pointer) modifierStructure.getFieldValue("mirror_ob"); - - if(mirrorVGroup) { + + if (mirrorVGroup) { LOGGER.warning("Mirroring vertex groups is currently not supported."); } } @@ -117,8 +120,8 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper; TemporalMesh mirror = temporalMesh.clone(); for (int i = 0; i < mirror.getVertexCount(); ++i) { - Vector3f vertex = mirror.getVertex(i); - Vector3f normal = mirror.getNormal(i); + Vector3f vertex = mirror.getVertices().get(i); + Vector3f normal = mirror.getNormals().get(i); if (mirrorAtPoint0) { d = Math.abs(vertex.get(mirrorIndex)); @@ -131,18 +134,27 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper; if (merge && d <= tolerance) { vertex.addLocal(shiftVector); normal.set(mirrorIndex, 0); - temporalMesh.getVertex(i).addLocal(shiftVector); - temporalMesh.getNormal(i).set(mirrorIndex, 0); + temporalMesh.getVertices().get(i).addLocal(shiftVector); + temporalMesh.getNormals().get(i).set(mirrorIndex, 0); } else { vertex.addLocal(shiftVector.multLocal(2)); normal.set(mirrorIndex, -normal.get(mirrorIndex)); } } - mirror.flipIndexes(); + // flipping the indexes + for (Face face : mirror.getFaces()) { + face.flipIndexes(); + } + for (Edge edge : mirror.getEdges()) { + edge.flipIndexes(); + } + Collections.reverse(mirror.getPoints()); if (mirrorU || mirrorV) { - mirror.flipUV(mirrorU, mirrorV); + for (Face face : mirror.getFaces()) { + face.flipUV(mirrorU, mirrorV); + } } temporalMesh.append(mirror);