Feature: added support for line and point type of meshes.
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10914 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
69e4392ba9
commit
dd8b8fbd5f
@ -1,5 +1,6 @@
|
|||||||
package com.jme3.scene.plugins.blender.meshes;
|
package com.jme3.scene.plugins.blender.meshes;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -14,7 +15,7 @@ import com.jme3.scene.Geometry;
|
|||||||
*/
|
*/
|
||||||
public class MeshContext {
|
public class MeshContext {
|
||||||
/** A map between material index and the geometry. */
|
/** A map between material index and the geometry. */
|
||||||
private Map<Integer, Geometry> geometries = new HashMap<Integer, Geometry>();
|
private Map<Integer, List<Geometry>> geometries = new HashMap<Integer, List<Geometry>>();
|
||||||
/** The vertex reference map. */
|
/** The vertex reference map. */
|
||||||
private Map<Integer, Map<Integer, List<Integer>>> vertexReferenceMap;
|
private Map<Integer, Map<Integer, List<Integer>>> vertexReferenceMap;
|
||||||
|
|
||||||
@ -26,7 +27,12 @@ public class MeshContext {
|
|||||||
* the geometry
|
* the geometry
|
||||||
*/
|
*/
|
||||||
public void putGeometry(Integer materialIndex, Geometry geometry) {
|
public void putGeometry(Integer materialIndex, Geometry geometry) {
|
||||||
geometries.put(materialIndex, geometry);
|
List<Geometry> geomList = geometries.get(materialIndex);
|
||||||
|
if (geomList == null) {
|
||||||
|
geomList = new ArrayList<Geometry>();
|
||||||
|
geometries.put(materialIndex, geomList);
|
||||||
|
}
|
||||||
|
geomList.add(geometry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -35,7 +41,11 @@ public class MeshContext {
|
|||||||
* @return vertices amount that is used by mesh with the specified material
|
* @return vertices amount that is used by mesh with the specified material
|
||||||
*/
|
*/
|
||||||
public int getVertexCount(int materialIndex) {
|
public int getVertexCount(int materialIndex) {
|
||||||
return geometries.get(materialIndex).getVertexCount();
|
int result = 0;
|
||||||
|
for (Geometry geometry : geometries.get(materialIndex)) {
|
||||||
|
result += geometry.getVertexCount();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -47,9 +57,11 @@ public class MeshContext {
|
|||||||
* this exception is thrown when no material is found for the specified geometry
|
* this exception is thrown when no material is found for the specified geometry
|
||||||
*/
|
*/
|
||||||
public int getMaterialIndex(Geometry geometry) {
|
public int getMaterialIndex(Geometry geometry) {
|
||||||
for (Entry<Integer, Geometry> entry : geometries.entrySet()) {
|
for (Entry<Integer, List<Geometry>> entry : geometries.entrySet()) {
|
||||||
if (entry.getValue().equals(geometry)) {
|
for (Geometry g : entry.getValue()) {
|
||||||
return entry.getKey();
|
if (g.equals(geometry)) {
|
||||||
|
return entry.getKey();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("Cannot find material index for the given geometry: " + geometry);
|
throw new IllegalStateException("Cannot find material index for the given geometry: " + geometry);
|
||||||
|
@ -40,9 +40,12 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import com.jme3.asset.BlenderKey.FeaturesToLoad;
|
import com.jme3.asset.BlenderKey.FeaturesToLoad;
|
||||||
|
import com.jme3.material.Material;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.math.Vector2f;
|
import com.jme3.math.Vector2f;
|
||||||
import com.jme3.scene.Geometry;
|
import com.jme3.scene.Geometry;
|
||||||
import com.jme3.scene.Mesh;
|
import com.jme3.scene.Mesh;
|
||||||
|
import com.jme3.scene.Mesh.Mode;
|
||||||
import com.jme3.scene.VertexBuffer;
|
import com.jme3.scene.VertexBuffer;
|
||||||
import com.jme3.scene.VertexBuffer.Format;
|
import com.jme3.scene.VertexBuffer.Format;
|
||||||
import com.jme3.scene.VertexBuffer.Usage;
|
import com.jme3.scene.VertexBuffer.Usage;
|
||||||
@ -68,10 +71,12 @@ public class MeshHelper extends AbstractBlenderHelper {
|
|||||||
private static final Logger LOGGER = Logger.getLogger(MeshHelper.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(MeshHelper.class.getName());
|
||||||
|
|
||||||
/** A type of UV data layer in traditional faced mesh (triangles or quads). */
|
/** A type of UV data layer in traditional faced mesh (triangles or quads). */
|
||||||
public static final int UV_DATA_LAYER_TYPE_FMESH = 5;
|
public static final int UV_DATA_LAYER_TYPE_FMESH = 5;
|
||||||
/** A type of UV data layer in bmesh type. */
|
/** A type of UV data layer in bmesh type. */
|
||||||
public static final int UV_DATA_LAYER_TYPE_BMESH = 16;
|
public static final int UV_DATA_LAYER_TYPE_BMESH = 16;
|
||||||
|
/** A material used for single lines and points. */
|
||||||
|
private Material blackUnshadedMaterial;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constructor parses the given blender version and stores the result. Some functionalities may differ in different blender
|
* This constructor parses the given blender version and stores the result. Some functionalities may differ in different blender
|
||||||
* versions.
|
* versions.
|
||||||
@ -143,9 +148,9 @@ public class MeshHelper extends AbstractBlenderHelper {
|
|||||||
LOGGER.fine("Generating meshes.");
|
LOGGER.fine("Generating meshes.");
|
||||||
Map<Integer, List<Mesh>> meshes = meshBuilder.buildMeshes();
|
Map<Integer, List<Mesh>> meshes = meshBuilder.buildMeshes();
|
||||||
geometries = new ArrayList<Geometry>(meshes.size());
|
geometries = new ArrayList<Geometry>(meshes.size());
|
||||||
for(Entry<Integer, List<Mesh>> meshEntry : meshes.entrySet()) {
|
for (Entry<Integer, List<Mesh>> meshEntry : meshes.entrySet()) {
|
||||||
int materialIndex = meshEntry.getKey();
|
int materialIndex = meshEntry.getKey();
|
||||||
for(Mesh mesh : meshEntry.getValue()) {
|
for (Mesh mesh : meshEntry.getValue()) {
|
||||||
LOGGER.fine("Preparing the result part.");
|
LOGGER.fine("Preparing the result part.");
|
||||||
Geometry geometry = new Geometry(name + (geometries.size() + 1), mesh);
|
Geometry geometry = new Geometry(name + (geometries.size() + 1), mesh);
|
||||||
if (properties != null && properties.getValue() != null) {
|
if (properties != null && properties.getValue() != null) {
|
||||||
@ -164,7 +169,9 @@ public class MeshHelper extends AbstractBlenderHelper {
|
|||||||
if (materials != null) {
|
if (materials != null) {
|
||||||
for (Geometry geometry : geometries) {
|
for (Geometry geometry : geometries) {
|
||||||
int materialNumber = meshContext.getMaterialIndex(geometry);
|
int materialNumber = meshContext.getMaterialIndex(geometry);
|
||||||
if (materials[materialNumber] != null) {
|
if (materialNumber < 0) {
|
||||||
|
geometry.setMaterial(this.getBlackUnshadedMaterial(blenderContext));
|
||||||
|
} else if (materials[materialNumber] != null) {
|
||||||
LinkedHashMap<String, List<Vector2f>> uvCoordinates = meshBuilder.getUVCoordinates(materialNumber);
|
LinkedHashMap<String, List<Vector2f>> uvCoordinates = meshBuilder.getUVCoordinates(materialNumber);
|
||||||
MaterialContext materialContext = materials[materialNumber];
|
MaterialContext materialContext = materials[materialNumber];
|
||||||
materialContext.applyMaterial(geometry, structure.getOldMemoryAddress(), uvCoordinates, blenderContext);
|
materialContext.applyMaterial(geometry, structure.getOldMemoryAddress(), uvCoordinates, blenderContext);
|
||||||
@ -190,7 +197,12 @@ public class MeshHelper extends AbstractBlenderHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Geometry geometry : geometries) {
|
for (Geometry geometry : geometries) {
|
||||||
geometry.setMaterial(blenderContext.getDefaultMaterial());
|
Mode mode = geometry.getMesh().getMode();
|
||||||
|
if (mode != Mode.Triangles && mode != Mode.TriangleFan && mode != Mode.TriangleStrip) {
|
||||||
|
geometry.setMaterial(this.getBlackUnshadedMaterial(blenderContext));
|
||||||
|
} else {
|
||||||
|
geometry.setMaterial(blenderContext.getDefaultMaterial());
|
||||||
|
}
|
||||||
if (uvCoordsBuffer != null) {
|
if (uvCoordsBuffer != null) {
|
||||||
for (VertexBuffer buffer : uvCoordsBuffer) {
|
for (VertexBuffer buffer : uvCoordsBuffer) {
|
||||||
geometry.getMesh().setBuffer(buffer);
|
geometry.getMesh().setBuffer(buffer);
|
||||||
@ -201,7 +213,7 @@ public class MeshHelper extends AbstractBlenderHelper {
|
|||||||
|
|
||||||
return geometries;
|
return geometries;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tells if the given mesh structure supports BMesh.
|
* Tells if the given mesh structure supports BMesh.
|
||||||
*
|
*
|
||||||
@ -214,4 +226,12 @@ public class MeshHelper extends AbstractBlenderHelper {
|
|||||||
Pointer pMPoly = (Pointer) meshStructure.getFieldValue("mpoly");
|
Pointer pMPoly = (Pointer) meshStructure.getFieldValue("mpoly");
|
||||||
return pMLoop != null && pMPoly != null && pMLoop.isNotNull() && pMPoly.isNotNull();
|
return pMLoop != null && pMPoly != null && pMLoop.isNotNull() && pMPoly.isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private synchronized Material getBlackUnshadedMaterial(BlenderContext blenderContext) {
|
||||||
|
if (blackUnshadedMaterial == null) {
|
||||||
|
blackUnshadedMaterial = new Material(blenderContext.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
|
||||||
|
blackUnshadedMaterial.setColor("Color", ColorRGBA.Black);
|
||||||
|
}
|
||||||
|
return blackUnshadedMaterial;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ import com.jme3.util.BufferUtils;
|
|||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/* package */class FaceMeshBuilder {
|
/* package */class FaceMeshBuilder {
|
||||||
private static final Logger LOGGER = Logger.getLogger(FaceMeshBuilder.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(FaceMeshBuilder.class.getName());
|
||||||
|
|
||||||
/** An array of reference vertices. */
|
/** An array of reference vertices. */
|
||||||
private Vector3f[][] verticesAndNormals;
|
private Vector3f[][] verticesAndNormals;
|
||||||
@ -46,15 +46,15 @@ import com.jme3.util.BufferUtils;
|
|||||||
*/
|
*/
|
||||||
private Map<Integer, Map<Integer, List<Integer>>> globalVertexReferenceMap;
|
private Map<Integer, Map<Integer, List<Integer>>> globalVertexReferenceMap;
|
||||||
/** The following map sorts vertices by material number (because in jme Mesh can have only one material). */
|
/** The following map sorts vertices by material number (because in jme Mesh can have only one material). */
|
||||||
private Map<Integer, List<Vector3f>> normalMap = new HashMap<Integer, List<Vector3f>>();
|
private Map<Integer, List<Vector3f>> normalMap = new HashMap<Integer, List<Vector3f>>();
|
||||||
/** The following map sorts vertices by material number (because in jme Mesh can have only one material). */
|
/** The following map sorts vertices by material number (because in jme Mesh can have only one material). */
|
||||||
private Map<Integer, List<Vector3f>> vertexMap = new HashMap<Integer, List<Vector3f>>();
|
private Map<Integer, List<Vector3f>> vertexMap = new HashMap<Integer, List<Vector3f>>();
|
||||||
/** The following map sorts vertices colors by material number (because in jme Mesh can have only one material). */
|
/** The following map sorts vertices colors by material number (because in jme Mesh can have only one material). */
|
||||||
private Map<Integer, List<byte[]>> vertexColorsMap = new HashMap<Integer, List<byte[]>>();
|
private Map<Integer, List<byte[]>> vertexColorsMap = new HashMap<Integer, List<byte[]>>();
|
||||||
/** The following map sorts indexes by material number (because in jme Mesh can have only one material). */
|
/** The following map sorts indexes by material number (because in jme Mesh can have only one material). */
|
||||||
private Map<Integer, List<Integer>> indexMap = new HashMap<Integer, List<Integer>>();
|
private Map<Integer, List<Integer>> indexMap = new HashMap<Integer, List<Integer>>();
|
||||||
/** A collection of user defined UV coordinates (one mesh can have more than one such mappings). */
|
/** A collection of user defined UV coordinates (one mesh can have more than one such mappings). */
|
||||||
private UserUVCollection userUVCollection = new UserUVCollection();
|
private UserUVCollection userUVCollection = new UserUVCollection();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor. Stores the given array (not copying it).
|
* Constructor. Stores the given array (not copying it).
|
||||||
@ -74,7 +74,7 @@ import com.jme3.util.BufferUtils;
|
|||||||
public void readMesh(Structure structure, BlenderContext blenderContext) throws BlenderFileException {
|
public void readMesh(Structure structure, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
verticesColors = this.getVerticesColors(structure, blenderContext);
|
verticesColors = this.getVerticesColors(structure, blenderContext);
|
||||||
MeshHelper meshHelper = blenderContext.getHelper(MeshHelper.class);
|
MeshHelper meshHelper = blenderContext.getHelper(MeshHelper.class);
|
||||||
|
|
||||||
if (meshHelper.isBMeshCompatible(structure)) {
|
if (meshHelper.isBMeshCompatible(structure)) {
|
||||||
this.readBMesh(structure, blenderContext);
|
this.readBMesh(structure, blenderContext);
|
||||||
} else {
|
} else {
|
||||||
@ -91,7 +91,7 @@ import com.jme3.util.BufferUtils;
|
|||||||
|
|
||||||
for (Entry<Integer, List<Integer>> meshEntry : indexMap.entrySet()) {
|
for (Entry<Integer, List<Integer>> meshEntry : indexMap.entrySet()) {
|
||||||
int materialIndex = meshEntry.getKey();
|
int materialIndex = meshEntry.getKey();
|
||||||
// key is the material index (or -1 if the material has no texture)
|
// key is the material index
|
||||||
// value is a list of vertex indices
|
// value is a list of vertex indices
|
||||||
Mesh mesh = new Mesh();
|
Mesh mesh = new Mesh();
|
||||||
|
|
||||||
@ -148,10 +148,9 @@ import com.jme3.util.BufferUtils;
|
|||||||
LOGGER.fine("Reading BMesh.");
|
LOGGER.fine("Reading BMesh.");
|
||||||
Pointer pMLoop = (Pointer) meshStructure.getFieldValue("mloop");
|
Pointer pMLoop = (Pointer) meshStructure.getFieldValue("mloop");
|
||||||
Pointer pMPoly = (Pointer) meshStructure.getFieldValue("mpoly");
|
Pointer pMPoly = (Pointer) meshStructure.getFieldValue("mpoly");
|
||||||
Pointer pMEdge = (Pointer) meshStructure.getFieldValue("medge");
|
|
||||||
Map<String, Vector2f[]> uvCoordinatesForFace = new HashMap<String, Vector2f[]>();
|
Map<String, Vector2f[]> uvCoordinatesForFace = new HashMap<String, Vector2f[]>();
|
||||||
|
|
||||||
if (pMPoly.isNotNull() && pMLoop.isNotNull() && pMEdge.isNotNull()) {
|
if (pMPoly.isNotNull() && pMLoop.isNotNull()) {
|
||||||
Map<String, List<Vector2f>> uvs = this.loadUVCoordinates(meshStructure, true, blenderContext);
|
Map<String, List<Vector2f>> uvs = this.loadUVCoordinates(meshStructure, true, blenderContext);
|
||||||
List<Structure> polys = pMPoly.fetchData(blenderContext.getInputStream());
|
List<Structure> polys = pMPoly.fetchData(blenderContext.getInputStream());
|
||||||
List<Structure> loops = pMLoop.fetchData(blenderContext.getInputStream());
|
List<Structure> loops = pMLoop.fetchData(blenderContext.getInputStream());
|
||||||
@ -172,7 +171,7 @@ import com.jme3.util.BufferUtils;
|
|||||||
int v1 = vertexIndexes[0];
|
int v1 = vertexIndexes[0];
|
||||||
int v2 = vertexIndexes[i + 1];
|
int v2 = vertexIndexes[i + 1];
|
||||||
int v3 = vertexIndexes[i + 2];
|
int v3 = vertexIndexes[i + 2];
|
||||||
if(vertexColorIndex != null) {
|
if (vertexColorIndex != null) {
|
||||||
vertexColorIndex[0] = loopStart;
|
vertexColorIndex[0] = loopStart;
|
||||||
vertexColorIndex[1] = loopStart + i + 1;
|
vertexColorIndex[1] = loopStart + i + 1;
|
||||||
vertexColorIndex[2] = loopStart + i + 2;
|
vertexColorIndex[2] = loopStart + i + 2;
|
||||||
@ -237,7 +236,7 @@ import com.jme3.util.BufferUtils;
|
|||||||
int v2 = ((Number) mFace.getFieldValue("v2")).intValue();
|
int v2 = ((Number) mFace.getFieldValue("v2")).intValue();
|
||||||
int v3 = ((Number) mFace.getFieldValue("v3")).intValue();
|
int v3 = ((Number) mFace.getFieldValue("v3")).intValue();
|
||||||
int v4 = ((Number) mFace.getFieldValue("v4")).intValue();
|
int v4 = ((Number) mFace.getFieldValue("v4")).intValue();
|
||||||
if(vertexColorIndex != null) {
|
if (vertexColorIndex != null) {
|
||||||
vertexColorIndex[0] = i * 4;
|
vertexColorIndex[0] = i * 4;
|
||||||
vertexColorIndex[1] = i * 4 + 1;
|
vertexColorIndex[1] = i * 4 + 1;
|
||||||
vertexColorIndex[2] = i * 4 + 2;
|
vertexColorIndex[2] = i * 4 + 2;
|
||||||
@ -256,7 +255,7 @@ import com.jme3.util.BufferUtils;
|
|||||||
uvCoordinatesForFace.put(entry.getKey(), uvCoordsForASingleFace);
|
uvCoordinatesForFace.put(entry.getKey(), uvCoordsForASingleFace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(vertexColorIndex != null) {
|
if (vertexColorIndex != null) {
|
||||||
vertexColorIndex[0] = i * 4;
|
vertexColorIndex[0] = i * 4;
|
||||||
vertexColorIndex[1] = i * 4 + 2;
|
vertexColorIndex[1] = i * 4 + 2;
|
||||||
vertexColorIndex[2] = i * 4 + 3;
|
vertexColorIndex[2] = i * 4 + 3;
|
||||||
@ -282,6 +281,8 @@ import com.jme3.util.BufferUtils;
|
|||||||
* the material number for this face
|
* the material number for this face
|
||||||
* @param uvsForFace
|
* @param uvsForFace
|
||||||
* a 3-element array of vertices UV coordinates mapped to the UV's set name
|
* a 3-element array of vertices UV coordinates mapped to the UV's set name
|
||||||
|
* @param vertexColorIndex
|
||||||
|
* a table of 3 elements that indicates the verts' colors indexes
|
||||||
*/
|
*/
|
||||||
private void appendFace(int v1, int v2, int v3, boolean smooth, int materialNumber, Map<String, Vector2f[]> uvsForFace, int[] vertexColorIndex) {
|
private void appendFace(int v1, int v2, int v3, boolean smooth, int materialNumber, Map<String, Vector2f[]> uvsForFace, int[] vertexColorIndex) {
|
||||||
if (uvsForFace != null && uvsForFace.size() > 0) {
|
if (uvsForFace != null && uvsForFace.size() > 0) {
|
||||||
|
@ -1,5 +1,163 @@
|
|||||||
package com.jme3.scene.plugins.blender.meshes.builders;
|
package com.jme3.scene.plugins.blender.meshes.builders;
|
||||||
|
|
||||||
/*package*/ class LineMeshBuilder {
|
import java.util.ArrayList;
|
||||||
//TODO: this will be implemented soon
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.scene.Mesh;
|
||||||
|
import com.jme3.scene.Mesh.Mode;
|
||||||
|
import com.jme3.scene.VertexBuffer;
|
||||||
|
import com.jme3.scene.VertexBuffer.Format;
|
||||||
|
import com.jme3.scene.VertexBuffer.Type;
|
||||||
|
import com.jme3.scene.VertexBuffer.Usage;
|
||||||
|
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.util.BufferUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A builder that creates a lines mesh. The result is made of lines that do not belong to any face.
|
||||||
|
*
|
||||||
|
* @author Marcin Roguski (Kaelthas)
|
||||||
|
*/
|
||||||
|
/* package */class LineMeshBuilder {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(LineMeshBuilder.class.getName());
|
||||||
|
|
||||||
|
private static final int EDGE_NOT_IN_FACE_FLAG = 0x80;
|
||||||
|
|
||||||
|
/** An array of reference vertices. */
|
||||||
|
private Vector3f[][] verticesAndNormals;
|
||||||
|
/** The vertices of the mesh. */
|
||||||
|
private List<Vector3f> vertices = new ArrayList<Vector3f>();
|
||||||
|
/** The normals of the mesh. */
|
||||||
|
private List<Vector3f> normals = new ArrayList<Vector3f>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This map's key is the vertex index from 'vertices 'table and the value are indices from 'vertexList'
|
||||||
|
* positions (it simply tells which vertex is referenced where in the result list).
|
||||||
|
*/
|
||||||
|
private Map<Integer, List<Integer>> globalVertexReferenceMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor. Stores the given array (not copying it).
|
||||||
|
* The second argument describes if the model uses generated textures. If yes then no vertex amount optimisation is applied.
|
||||||
|
* The amount of vertices is always faceCount * 3.
|
||||||
|
* @param verticesAndNormals
|
||||||
|
* the reference vertices and normals array
|
||||||
|
*/
|
||||||
|
public LineMeshBuilder(Vector3f[][] verticesAndNormals) {
|
||||||
|
this.verticesAndNormals = verticesAndNormals;
|
||||||
|
globalVertexReferenceMap = new HashMap<Integer, List<Integer>>(verticesAndNormals.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The method reads the mesh. It loads only edges that are marked as not belonging to any face in their flag field.
|
||||||
|
* @param meshStructure
|
||||||
|
* the mesh structure
|
||||||
|
* @param blenderContext
|
||||||
|
* the blender context
|
||||||
|
* @throws BlenderFileException
|
||||||
|
* an exception thrown when reading from the blend file fails
|
||||||
|
*/
|
||||||
|
public void readMesh(Structure meshStructure, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
|
LOGGER.fine("Reading line mesh.");
|
||||||
|
Pointer pMEdge = (Pointer) meshStructure.getFieldValue("medge");
|
||||||
|
|
||||||
|
if (pMEdge.isNotNull()) {
|
||||||
|
List<Structure> edges = pMEdge.fetchData(blenderContext.getInputStream());
|
||||||
|
int vertexIndex = 0;//vertex index in the result mesh
|
||||||
|
for (Structure edge : edges) {
|
||||||
|
int flag = ((Number) edge.getFieldValue("flag")).intValue();
|
||||||
|
if ((flag & EDGE_NOT_IN_FACE_FLAG) != 0) {
|
||||||
|
int v1 = ((Number) edge.getFieldValue("v1")).intValue();
|
||||||
|
int v2 = ((Number) edge.getFieldValue("v2")).intValue();
|
||||||
|
|
||||||
|
vertices.add(verticesAndNormals[v1][0]);
|
||||||
|
normals.add(verticesAndNormals[v1][1]);
|
||||||
|
this.appendVertexReference(v1, vertexIndex++, globalVertexReferenceMap);
|
||||||
|
|
||||||
|
vertices.add(verticesAndNormals[v2][0]);
|
||||||
|
normals.add(verticesAndNormals[v2][1]);
|
||||||
|
this.appendVertexReference(v2, vertexIndex++, globalVertexReferenceMap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the meshes.
|
||||||
|
* @return a map between material index and the mesh
|
||||||
|
*/
|
||||||
|
public Map<Integer, Mesh> buildMeshes() {
|
||||||
|
LOGGER.fine("Building line mesh.");
|
||||||
|
Map<Integer, Mesh> result = new HashMap<Integer, Mesh>(1);
|
||||||
|
if (vertices.size() > 0) {
|
||||||
|
Mesh mesh = new Mesh();
|
||||||
|
mesh.setMode(Mode.Lines);
|
||||||
|
|
||||||
|
LOGGER.fine("Creating indices buffer.");
|
||||||
|
if (vertices.size() <= Short.MAX_VALUE) {
|
||||||
|
short[] indices = new short[vertices.size()];
|
||||||
|
for (int i = 0; i < vertices.size(); ++i) {
|
||||||
|
indices[i] = (short) i;
|
||||||
|
}
|
||||||
|
mesh.setBuffer(Type.Index, 1, indices);
|
||||||
|
} else {
|
||||||
|
int[] indices = new int[vertices.size()];
|
||||||
|
for (int i = 0; i < vertices.size(); ++i) {
|
||||||
|
indices[i] = i;
|
||||||
|
}
|
||||||
|
mesh.setBuffer(Type.Index, 1, indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.fine("Creating vertices buffer.");
|
||||||
|
VertexBuffer verticesBuffer = new VertexBuffer(Type.Position);
|
||||||
|
verticesBuffer.setupData(Usage.Static, 3, Format.Float, BufferUtils.createFloatBuffer(vertices.toArray(new Vector3f[vertices.size()])));
|
||||||
|
mesh.setBuffer(verticesBuffer);
|
||||||
|
|
||||||
|
LOGGER.fine("Creating normals buffer (in case of lines it is required if skeleton is applied).");
|
||||||
|
VertexBuffer normalsBuffer = new VertexBuffer(Type.Normal);
|
||||||
|
normalsBuffer.setupData(Usage.Static, 3, Format.Float, BufferUtils.createFloatBuffer(normals.toArray(new Vector3f[normals.size()])));
|
||||||
|
mesh.setBuffer(normalsBuffer);
|
||||||
|
|
||||||
|
result.put(-1, mesh);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return <b>true</b> if the mesh has no vertices and <b>false</b> otherwise
|
||||||
|
*/
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return vertices == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Integer, List<Integer>> getGlobalVertexReferenceMap() {
|
||||||
|
return globalVertexReferenceMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method fills the vertex reference map. The vertices are loaded once and referenced many times in the model. This map is created
|
||||||
|
* to tell where the basic vertices are referenced in the result vertex lists. The key of the map is the basic vertex index, and its key
|
||||||
|
* - the reference indices list.
|
||||||
|
*
|
||||||
|
* @param basicVertexIndex
|
||||||
|
* the index of the vertex from its basic table
|
||||||
|
* @param resultIndex
|
||||||
|
* the index of the vertex in its result vertex list
|
||||||
|
* @param vertexReferenceMap
|
||||||
|
* the reference map
|
||||||
|
*/
|
||||||
|
private void appendVertexReference(int basicVertexIndex, int resultIndex, Map<Integer, List<Integer>> vertexReferenceMap) {
|
||||||
|
List<Integer> referenceList = vertexReferenceMap.get(Integer.valueOf(basicVertexIndex));
|
||||||
|
if (referenceList == null) {
|
||||||
|
referenceList = new ArrayList<Integer>();
|
||||||
|
vertexReferenceMap.put(Integer.valueOf(basicVertexIndex), referenceList);
|
||||||
|
}
|
||||||
|
referenceList.add(Integer.valueOf(resultIndex));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,44 +18,78 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
import com.jme3.scene.plugins.blender.materials.MaterialContext;
|
import com.jme3.scene.plugins.blender.materials.MaterialContext;
|
||||||
|
|
||||||
public class MeshBuilder {
|
public class MeshBuilder {
|
||||||
private boolean fixUpAxis;
|
private boolean fixUpAxis;
|
||||||
//TODO: these will be added soon
|
private PointMeshBuilder pointMeshBuilder;
|
||||||
// private PointMeshBuilder pointMeshBuilder;
|
private LineMeshBuilder lineMeshBuilder;
|
||||||
// private LineMeshBuilder lineMeshBuilder;
|
private FaceMeshBuilder faceMeshBuilder;
|
||||||
private FaceMeshBuilder faceMeshBuilder;
|
/**
|
||||||
|
* This map's key is the vertex index from 'vertices 'table and the value are indices from 'vertexList'
|
||||||
|
* positions (it simply tells which vertex is referenced where in the result list).
|
||||||
|
*/
|
||||||
|
private Map<Integer, Map<Integer, List<Integer>>> globalVertexReferenceMap = new HashMap<Integer, Map<Integer,List<Integer>>>();
|
||||||
|
|
||||||
public MeshBuilder(Structure meshStructure, MaterialContext[] materials, BlenderContext blenderContext) throws BlenderFileException {
|
public MeshBuilder(Structure meshStructure, MaterialContext[] materials, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
fixUpAxis = blenderContext.getBlenderKey().isFixUpAxis();
|
fixUpAxis = blenderContext.getBlenderKey().isFixUpAxis();
|
||||||
Vector3f[][] verticesAndNormals = this.getVerticesAndNormals(meshStructure, blenderContext);
|
Vector3f[][] verticesAndNormals = this.getVerticesAndNormals(meshStructure, blenderContext);
|
||||||
boolean generatedTexturesPresent = this.areGeneratedTexturesPresent(materials);
|
|
||||||
|
faceMeshBuilder = new FaceMeshBuilder(verticesAndNormals, this.areGeneratedTexturesPresent(materials));
|
||||||
faceMeshBuilder = new FaceMeshBuilder(verticesAndNormals, generatedTexturesPresent);
|
|
||||||
faceMeshBuilder.readMesh(meshStructure, blenderContext);
|
faceMeshBuilder.readMesh(meshStructure, blenderContext);
|
||||||
|
lineMeshBuilder = new LineMeshBuilder(verticesAndNormals);
|
||||||
|
lineMeshBuilder.readMesh(meshStructure, blenderContext);
|
||||||
|
pointMeshBuilder = new PointMeshBuilder(verticesAndNormals);
|
||||||
|
pointMeshBuilder.readMesh(meshStructure, blenderContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Integer, List<Mesh>> buildMeshes() {
|
public Map<Integer, List<Mesh>> buildMeshes() {
|
||||||
Map<Integer, List<Mesh>> result = new HashMap<Integer, List<Mesh>>();
|
Map<Integer, List<Mesh>> result = new HashMap<Integer, List<Mesh>>();
|
||||||
|
|
||||||
Map<Integer, Mesh> meshes = faceMeshBuilder.buildMeshes();
|
Map<Integer, Mesh> meshes = faceMeshBuilder.buildMeshes();
|
||||||
for(Entry<Integer, Mesh> entry : meshes.entrySet()) {
|
for (Entry<Integer, Mesh> entry : meshes.entrySet()) {
|
||||||
List<Mesh> meshList = new ArrayList<Mesh>();
|
List<Mesh> meshList = new ArrayList<Mesh>();
|
||||||
meshList.add(entry.getValue());
|
meshList.add(entry.getValue());
|
||||||
result.put(entry.getKey(), meshList);
|
result.put(entry.getKey(), meshList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
meshes = lineMeshBuilder.buildMeshes();
|
||||||
|
for (Entry<Integer, Mesh> entry : meshes.entrySet()) {
|
||||||
|
List<Mesh> meshList = result.get(entry.getKey());
|
||||||
|
if (meshList == null) {
|
||||||
|
meshList = new ArrayList<Mesh>();
|
||||||
|
result.put(entry.getKey(), meshList);
|
||||||
|
}
|
||||||
|
meshList.add(entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
meshes = pointMeshBuilder.buildMeshes();
|
||||||
|
for (Entry<Integer, Mesh> entry : meshes.entrySet()) {
|
||||||
|
List<Mesh> meshList = result.get(entry.getKey());
|
||||||
|
if (meshList == null) {
|
||||||
|
meshList = new ArrayList<Mesh>();
|
||||||
|
result.put(entry.getKey(), meshList);
|
||||||
|
}
|
||||||
|
meshList.add(entry.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
globalVertexReferenceMap.putAll(faceMeshBuilder.getVertexReferenceMap());
|
||||||
|
globalVertexReferenceMap.put(-1, lineMeshBuilder.getGlobalVertexReferenceMap());
|
||||||
|
globalVertexReferenceMap.get(-1).putAll(pointMeshBuilder.getGlobalVertexReferenceMap());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return <b>true</b> if the mesh has no vertices and <b>false</b> otherwise
|
||||||
|
*/
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return faceMeshBuilder.isEmpty();
|
return faceMeshBuilder.isEmpty() && lineMeshBuilder.isEmpty() && pointMeshBuilder.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return a map that maps vertex index from reference array to its indices in the result list
|
* @return a map that maps vertex index from reference array to its indices in the result list
|
||||||
*/
|
*/
|
||||||
public Map<Integer, Map<Integer, List<Integer>>> getVertexReferenceMap() {
|
public Map<Integer, Map<Integer, List<Integer>>> getVertexReferenceMap() {
|
||||||
return faceMeshBuilder.getVertexReferenceMap();
|
return globalVertexReferenceMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param materialNumber
|
* @param materialNumber
|
||||||
* the material number that is appied to the mesh
|
* the material number that is appied to the mesh
|
||||||
@ -64,14 +98,14 @@ public class MeshBuilder {
|
|||||||
public LinkedHashMap<String, List<Vector2f>> getUVCoordinates(int materialNumber) {
|
public LinkedHashMap<String, List<Vector2f>> getUVCoordinates(int materialNumber) {
|
||||||
return faceMeshBuilder.getUVCoordinates(materialNumber);
|
return faceMeshBuilder.getUVCoordinates(materialNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return indicates if the mesh has UV coordinates
|
* @return indicates if the mesh has UV coordinates
|
||||||
*/
|
*/
|
||||||
public boolean hasUVCoordinates() {
|
public boolean hasUVCoordinates() {
|
||||||
return faceMeshBuilder.hasUVCoordinates();
|
return faceMeshBuilder.hasUVCoordinates();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the vertices.
|
* This method returns the vertices.
|
||||||
*
|
*
|
||||||
@ -112,7 +146,7 @@ public class MeshBuilder {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return <b>true</b> if the material has at least one generated component and <b>false</b> otherwise
|
* @return <b>true</b> if the material has at least one generated component and <b>false</b> otherwise
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,174 @@
|
|||||||
package com.jme3.scene.plugins.blender.meshes.builders;
|
package com.jme3.scene.plugins.blender.meshes.builders;
|
||||||
|
|
||||||
/*package*/ class PointMeshBuilder {
|
import java.util.ArrayList;
|
||||||
//TODO: this will be implemented soon
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.scene.Mesh;
|
||||||
|
import com.jme3.scene.Mesh.Mode;
|
||||||
|
import com.jme3.scene.VertexBuffer;
|
||||||
|
import com.jme3.scene.VertexBuffer.Format;
|
||||||
|
import com.jme3.scene.VertexBuffer.Type;
|
||||||
|
import com.jme3.scene.VertexBuffer.Usage;
|
||||||
|
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.util.BufferUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A builder that creates a points mesh. The result is made of points that do not belong to any edge and face.
|
||||||
|
*
|
||||||
|
* @author Marcin Roguski (Kaelthas)
|
||||||
|
*/
|
||||||
|
/* package */class PointMeshBuilder {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(PointMeshBuilder.class.getName());
|
||||||
|
|
||||||
|
/** An array of reference vertices. */
|
||||||
|
private Vector3f[][] verticesAndNormals;
|
||||||
|
/** The vertices of the mesh. */
|
||||||
|
private List<Vector3f> vertices = new ArrayList<Vector3f>();
|
||||||
|
/** The normals of the mesh. */
|
||||||
|
private List<Vector3f> normals = new ArrayList<Vector3f>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This map's key is the vertex index from 'vertices 'table and the value are indices from 'vertexList'
|
||||||
|
* positions (it simply tells which vertex is referenced where in the result list).
|
||||||
|
*/
|
||||||
|
private Map<Integer, List<Integer>> globalVertexReferenceMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor. Stores the given array (not copying it).
|
||||||
|
* The second argument describes if the model uses generated textures. If yes then no vertex amount optimisation is applied.
|
||||||
|
* The amount of vertices is always faceCount * 3.
|
||||||
|
* @param verticesAndNormals
|
||||||
|
* the reference vertices and normals array
|
||||||
|
*/
|
||||||
|
public PointMeshBuilder(Vector3f[][] verticesAndNormals) {
|
||||||
|
this.verticesAndNormals = verticesAndNormals;
|
||||||
|
globalVertexReferenceMap = new HashMap<Integer, List<Integer>>(verticesAndNormals.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The method reads the mesh. Since blender does not store the information in the vertex itself whether it belongs
|
||||||
|
* anywhere or not, we need to check all vertices and use here only those that are not used.
|
||||||
|
* @param meshStructure
|
||||||
|
* the mesh structure
|
||||||
|
* @param blenderContext
|
||||||
|
* the blender context
|
||||||
|
* @throws BlenderFileException
|
||||||
|
* an exception thrown when reading from the blend file fails
|
||||||
|
*/
|
||||||
|
public void readMesh(Structure meshStructure, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
|
LOGGER.fine("Reading points mesh.");
|
||||||
|
Pointer pMEdge = (Pointer) meshStructure.getFieldValue("medge");
|
||||||
|
|
||||||
|
if (pMEdge.isNotNull()) {
|
||||||
|
int count = ((Number) meshStructure.getFieldValue("totvert")).intValue();
|
||||||
|
Set<Vector3f> usedVertices = new HashSet<Vector3f>(count);
|
||||||
|
List<Structure> edges = pMEdge.fetchData(blenderContext.getInputStream());
|
||||||
|
|
||||||
|
for (Structure edge : edges) {
|
||||||
|
int v1 = ((Number) edge.getFieldValue("v1")).intValue();
|
||||||
|
int v2 = ((Number) edge.getFieldValue("v2")).intValue();
|
||||||
|
usedVertices.add(verticesAndNormals[v1][0]);
|
||||||
|
usedVertices.add(verticesAndNormals[v2][0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (usedVertices.size() < count) {
|
||||||
|
vertices = new ArrayList<Vector3f>(count - usedVertices.size());
|
||||||
|
int vertexIndex = 0, blenderVertexIndex = 0;
|
||||||
|
for (Vector3f[] vertAndNormal : verticesAndNormals) {
|
||||||
|
if (!usedVertices.contains(vertAndNormal[0])) {
|
||||||
|
vertices.add(vertAndNormal[0]);
|
||||||
|
normals.add(vertAndNormal[1]);
|
||||||
|
this.appendVertexReference(blenderVertexIndex, vertexIndex++, globalVertexReferenceMap);
|
||||||
|
}
|
||||||
|
++blenderVertexIndex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds the meshes.
|
||||||
|
* @return a map between material index and the mesh
|
||||||
|
*/
|
||||||
|
public Map<Integer, Mesh> buildMeshes() {
|
||||||
|
LOGGER.fine("Building point mesh.");
|
||||||
|
Map<Integer, Mesh> result = new HashMap<Integer, Mesh>(1);
|
||||||
|
|
||||||
|
if (vertices.size() > 0) {
|
||||||
|
Mesh mesh = new Mesh();
|
||||||
|
mesh.setMode(Mode.Points);
|
||||||
|
mesh.setPointSize(3);
|
||||||
|
|
||||||
|
// the point mesh does not need index buffer, but some modifiers applied by importer need it
|
||||||
|
// the 'alone point' situation should be quite rare so not too many resources are wasted here
|
||||||
|
LOGGER.fine("Creating indices buffer.");
|
||||||
|
if (vertices.size() <= Short.MAX_VALUE) {
|
||||||
|
short[] indices = new short[vertices.size()];
|
||||||
|
for (int i = 0; i < vertices.size(); ++i) {
|
||||||
|
indices[i] = (short) i;
|
||||||
|
}
|
||||||
|
mesh.setBuffer(Type.Index, 1, indices);
|
||||||
|
} else {
|
||||||
|
int[] indices = new int[vertices.size()];
|
||||||
|
for (int i = 0; i < vertices.size(); ++i) {
|
||||||
|
indices[i] = i;
|
||||||
|
}
|
||||||
|
mesh.setBuffer(Type.Index, 1, indices);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGGER.fine("Creating vertices buffer.");
|
||||||
|
VertexBuffer verticesBuffer = new VertexBuffer(Type.Position);
|
||||||
|
verticesBuffer.setupData(Usage.Static, 3, Format.Float, BufferUtils.createFloatBuffer(vertices.toArray(new Vector3f[vertices.size()])));
|
||||||
|
mesh.setBuffer(verticesBuffer);
|
||||||
|
|
||||||
|
LOGGER.fine("Creating normals buffer (in case of points it is required if skeleton is applied).");
|
||||||
|
VertexBuffer normalsBuffer = new VertexBuffer(Type.Normal);
|
||||||
|
normalsBuffer.setupData(Usage.Static, 3, Format.Float, BufferUtils.createFloatBuffer(normals.toArray(new Vector3f[normals.size()])));
|
||||||
|
mesh.setBuffer(normalsBuffer);
|
||||||
|
|
||||||
|
result.put(-1, mesh);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return <b>true</b> if the mesh has no vertices and <b>false</b> otherwise
|
||||||
|
*/
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return vertices == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<Integer, List<Integer>> getGlobalVertexReferenceMap() {
|
||||||
|
return globalVertexReferenceMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method fills the vertex reference map. The vertices are loaded once and referenced many times in the model. This map is created
|
||||||
|
* to tell where the basic vertices are referenced in the result vertex lists. The key of the map is the basic vertex index, and its key
|
||||||
|
* - the reference indices list.
|
||||||
|
*
|
||||||
|
* @param basicVertexIndex
|
||||||
|
* the index of the vertex from its basic table
|
||||||
|
* @param resultIndex
|
||||||
|
* the index of the vertex in its result vertex list
|
||||||
|
* @param vertexReferenceMap
|
||||||
|
* the reference map
|
||||||
|
*/
|
||||||
|
private void appendVertexReference(int basicVertexIndex, int resultIndex, Map<Integer, List<Integer>> vertexReferenceMap) {
|
||||||
|
List<Integer> referenceList = vertexReferenceMap.get(Integer.valueOf(basicVertexIndex));
|
||||||
|
if (referenceList == null) {
|
||||||
|
referenceList = new ArrayList<Integer>();
|
||||||
|
vertexReferenceMap.put(Integer.valueOf(basicVertexIndex), referenceList);
|
||||||
|
}
|
||||||
|
referenceList.add(Integer.valueOf(resultIndex));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,8 +119,8 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper;
|
|||||||
|
|
||||||
for (int i = 0; i < cloneIndexes.limit(); ++i) {
|
for (int i = 0; i < cloneIndexes.limit(); ++i) {
|
||||||
int index = cloneIndexes instanceof ShortBuffer ? ((ShortBuffer) cloneIndexes).get(i) : ((IntBuffer) cloneIndexes).get(i);
|
int index = cloneIndexes instanceof ShortBuffer ? ((ShortBuffer) cloneIndexes).get(i) : ((IntBuffer) cloneIndexes).get(i);
|
||||||
if (!modifiedIndexes.contains((int) index)) {
|
if (!modifiedIndexes.contains(index)) {
|
||||||
modifiedIndexes.add((int) index);
|
modifiedIndexes.add(index);
|
||||||
int valueIndex = index * 3 + mirrorIndex;
|
int valueIndex = index * 3 + mirrorIndex;
|
||||||
|
|
||||||
float value = clonePosition.get(valueIndex);
|
float value = clonePosition.get(valueIndex);
|
||||||
@ -155,17 +155,39 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper;
|
|||||||
}
|
}
|
||||||
modifiedIndexes.clear();
|
modifiedIndexes.clear();
|
||||||
|
|
||||||
// flipping index order
|
LOGGER.finer("Flipping index order.");
|
||||||
for (int i = 0; i < cloneIndexes.limit(); i += 3) {
|
switch(mesh.getMode()) {
|
||||||
if (cloneIndexes instanceof ShortBuffer) {
|
case Points:
|
||||||
short index = ((ShortBuffer) cloneIndexes).get(i + 2);
|
cloneIndexes.flip();
|
||||||
((ShortBuffer) cloneIndexes).put(i + 2, ((ShortBuffer) cloneIndexes).get(i + 1));
|
break;
|
||||||
((ShortBuffer) cloneIndexes).put(i + 1, index);
|
case Lines:
|
||||||
} else {
|
for (int i = 0; i < cloneIndexes.limit(); i += 2) {
|
||||||
int index = ((IntBuffer) cloneIndexes).get(i + 2);
|
if (cloneIndexes instanceof ShortBuffer) {
|
||||||
((IntBuffer) cloneIndexes).put(i + 2, ((IntBuffer) cloneIndexes).get(i + 1));
|
short index = ((ShortBuffer) cloneIndexes).get(i + 1);
|
||||||
((IntBuffer) cloneIndexes).put(i + 1, index);
|
((ShortBuffer) cloneIndexes).put(i + 1, ((ShortBuffer) cloneIndexes).get(i));
|
||||||
}
|
((ShortBuffer) cloneIndexes).put(i, index);
|
||||||
|
} else {
|
||||||
|
int index = ((IntBuffer) cloneIndexes).get(i + 1);
|
||||||
|
((IntBuffer) cloneIndexes).put(i + 1, ((IntBuffer) cloneIndexes).get(i));
|
||||||
|
((IntBuffer) cloneIndexes).put(i, index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Triangles:
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Invalid mesh mode: " + mesh.getMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mirrorU && clone.getBuffer(Type.TexCoord) != null) {
|
if (mirrorU && clone.getBuffer(Type.TexCoord) != null) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user