|
@@ -72,438 +72,443 @@ import com.jme3.util.BufferUtils;
|
|
|
* @author Marcin Roguski (Kaelthas)
|
|
|
*/
|
|
|
public class MeshHelper extends AbstractBlenderHelper {
|
|
|
- /**
|
|
|
- * This constructor parses the given blender version and stores the result. Some functionalities may differ in different blender
|
|
|
- * versions.
|
|
|
- *
|
|
|
- * @param blenderVersion
|
|
|
- * the version read from the blend file
|
|
|
- */
|
|
|
- public MeshHelper(String blenderVersion) {
|
|
|
- super(blenderVersion);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * This method reads converts the given structure into mesh. The given structure needs to be filled with the appropriate data.
|
|
|
- *
|
|
|
- * @param structure
|
|
|
- * the structure we read the mesh from
|
|
|
- * @return the mesh feature
|
|
|
- * @throws BlenderFileException
|
|
|
- */
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
- public List<Geometry> toMesh(Structure structure, BlenderContext blenderContext) throws BlenderFileException {
|
|
|
- List<Geometry> geometries = (List<Geometry>) blenderContext.getLoadedFeature(structure.getOldMemoryAddress(),
|
|
|
- LoadedFeatureDataType.LOADED_FEATURE);
|
|
|
- if (geometries != null) {
|
|
|
- List<Geometry> copiedGeometries = new ArrayList<Geometry>(geometries.size());
|
|
|
- for (Geometry geometry : geometries) {
|
|
|
- copiedGeometries.add(geometry.clone());
|
|
|
- }
|
|
|
- return copiedGeometries;
|
|
|
- }
|
|
|
-
|
|
|
- // helpers
|
|
|
- TextureHelper textureHelper = blenderContext.getHelper(TextureHelper.class);
|
|
|
-
|
|
|
- // reading mesh data
|
|
|
- String name = structure.getName();
|
|
|
- MeshContext meshContext = new MeshContext();
|
|
|
-
|
|
|
- // reading vertices
|
|
|
- Vector3f[] vertices = this.getVertices(structure, blenderContext);
|
|
|
- int verticesAmount = vertices.length;
|
|
|
-
|
|
|
- // vertices Colors
|
|
|
- List<float[]> verticesColors = this.getVerticesColors(structure, blenderContext);
|
|
|
-
|
|
|
- // reading faces
|
|
|
- // the following map sorts faces by material number (because in jme Mesh can have only one material)
|
|
|
- Map<Integer, List<Integer>> meshesMap = new HashMap<Integer, List<Integer>>();
|
|
|
- Pointer pMFace = (Pointer) structure.getFieldValue("mface");
|
|
|
+
|
|
|
+ /**
|
|
|
+ * This constructor parses the given blender version and stores the result. Some functionalities may differ in different blender
|
|
|
+ * versions.
|
|
|
+ *
|
|
|
+ * @param blenderVersion
|
|
|
+ * the version read from the blend file
|
|
|
+ */
|
|
|
+ public MeshHelper(String blenderVersion) {
|
|
|
+ super(blenderVersion);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * This method reads converts the given structure into mesh. The given structure needs to be filled with the appropriate data.
|
|
|
+ *
|
|
|
+ * @param structure
|
|
|
+ * the structure we read the mesh from
|
|
|
+ * @return the mesh feature
|
|
|
+ * @throws BlenderFileException
|
|
|
+ */
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public List<Geometry> toMesh(Structure structure, BlenderContext blenderContext) throws BlenderFileException {
|
|
|
+ List<Geometry> geometries = (List<Geometry>) blenderContext.getLoadedFeature(structure.getOldMemoryAddress(),
|
|
|
+ LoadedFeatureDataType.LOADED_FEATURE);
|
|
|
+ if (geometries != null) {
|
|
|
+ List<Geometry> copiedGeometries = new ArrayList<Geometry>(geometries.size());
|
|
|
+ for (Geometry geometry : geometries) {
|
|
|
+ copiedGeometries.add(geometry.clone());
|
|
|
+ }
|
|
|
+ return copiedGeometries;
|
|
|
+ }
|
|
|
+
|
|
|
+ // helpers
|
|
|
+ TextureHelper textureHelper = blenderContext.getHelper(TextureHelper.class);
|
|
|
+
|
|
|
+ // reading mesh data
|
|
|
+ String name = structure.getName();
|
|
|
+ MeshContext meshContext = new MeshContext();
|
|
|
+
|
|
|
+ // reading vertices
|
|
|
+ Vector3f[] vertices = this.getVertices(structure, blenderContext);
|
|
|
+ int verticesAmount = vertices.length;
|
|
|
+
|
|
|
+ // vertices Colors
|
|
|
+ List<float[]> verticesColors = this.getVerticesColors(structure, blenderContext);
|
|
|
+
|
|
|
+ // reading faces
|
|
|
+ // the following map sorts faces by material number (because in jme Mesh can have only one material)
|
|
|
+ Map<Integer, List<Integer>> meshesMap = new HashMap<Integer, List<Integer>>();
|
|
|
+ Pointer pMFace = (Pointer) structure.getFieldValue("mface");
|
|
|
List<Structure> mFaces = null;
|
|
|
- if (pMFace.isNotNull()){
|
|
|
+ if (pMFace.isNotNull()) {
|
|
|
mFaces = pMFace.fetchData(blenderContext.getInputStream());
|
|
|
- if(mFaces==null || mFaces.size()==0) {
|
|
|
- return new ArrayList<Geometry>(0);
|
|
|
+ if (mFaces == null || mFaces.size() == 0) {
|
|
|
+ return new ArrayList<Geometry>(0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ Pointer pMTFace = (Pointer) structure.getFieldValue("mtface");
|
|
|
+ List<Vector2f> uvCoordinates = null;
|
|
|
+ List<Structure> mtFaces = null;
|
|
|
+
|
|
|
+ if (pMTFace.isNotNull()) {
|
|
|
+ mtFaces = pMTFace.fetchData(blenderContext.getInputStream());
|
|
|
+ int facesAmount = ((Number) structure.getFieldValue("totface")).intValue();
|
|
|
+ if (mtFaces.size() != facesAmount) {
|
|
|
+ throw new BlenderFileException("The amount of faces uv coordinates is not equal to faces amount!");
|
|
|
+ }
|
|
|
+ uvCoordinates = new ArrayList<Vector2f>();
|
|
|
+ }
|
|
|
+
|
|
|
+ // normalMap merges normals of faces that will be rendered smooth
|
|
|
+ Map<Vector3f, Vector3f> normalMap = new HashMap<Vector3f, Vector3f>(verticesAmount);
|
|
|
+
|
|
|
+ List<Vector3f> normalList = new ArrayList<Vector3f>();
|
|
|
+ List<Vector3f> vertexList = new ArrayList<Vector3f>();
|
|
|
+ // indicates if the material with the specified number should have a texture attached
|
|
|
+ Map<Integer, Texture> materialNumberToTexture = new HashMap<Integer, Texture>();
|
|
|
+ // 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)
|
|
|
+ Map<Integer, List<Integer>> vertexReferenceMap = new HashMap<Integer, List<Integer>>(verticesAmount);
|
|
|
+ int vertexColorIndex = 0;
|
|
|
+ for (int i = 0; i < mFaces.size(); ++i) {
|
|
|
+ Structure mFace = mFaces.get(i);
|
|
|
+ boolean smooth = (((Number) mFace.getFieldValue("flag")).byteValue() & 0x01) != 0x00;
|
|
|
+ DynamicArray<Number> uvs = null;
|
|
|
+ boolean materialWithoutTextures = false;
|
|
|
+ Pointer pImage = null;
|
|
|
+ if (mtFaces != null) {
|
|
|
+ Structure mtFace = mtFaces.get(i);
|
|
|
+ pImage = (Pointer) mtFace.getFieldValue("tpage");
|
|
|
+ materialWithoutTextures = pImage.isNull();
|
|
|
+ // uvs always must be added wheater we have texture or not
|
|
|
+ uvs = (DynamicArray<Number>) mtFace.getFieldValue("uv");
|
|
|
+ uvCoordinates.add(new Vector2f(uvs.get(0, 0).floatValue(), uvs.get(0, 1).floatValue()));
|
|
|
+ uvCoordinates.add(new Vector2f(uvs.get(1, 0).floatValue(), uvs.get(1, 1).floatValue()));
|
|
|
+ uvCoordinates.add(new Vector2f(uvs.get(2, 0).floatValue(), uvs.get(2, 1).floatValue()));
|
|
|
+ }
|
|
|
+ int matNr = ((Number) mFace.getFieldValue("mat_nr")).intValue();
|
|
|
+ Integer materialNumber = Integer.valueOf(materialWithoutTextures ? -1 * matNr - 1 : matNr);
|
|
|
+ List<Integer> indexList = meshesMap.get(materialNumber);
|
|
|
+ if (indexList == null) {
|
|
|
+ indexList = new ArrayList<Integer>();
|
|
|
+ meshesMap.put(materialNumber, indexList);
|
|
|
}
|
|
|
+
|
|
|
+ // attaching image to texture (face can have UV's and image whlie its material may have no texture attached)
|
|
|
+ if (pImage != null && pImage.isNotNull() && !materialNumberToTexture.containsKey(materialNumber)) {
|
|
|
+ Texture texture = textureHelper.getTextureFromImage(pImage.fetchData(blenderContext.getInputStream()).get(0),
|
|
|
+ blenderContext);
|
|
|
+ if (texture != null) {
|
|
|
+ materialNumberToTexture.put(materialNumber, texture);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ int v1 = ((Number) mFace.getFieldValue("v1")).intValue();
|
|
|
+ int v2 = ((Number) mFace.getFieldValue("v2")).intValue();
|
|
|
+ int v3 = ((Number) mFace.getFieldValue("v3")).intValue();
|
|
|
+ int v4 = ((Number) mFace.getFieldValue("v4")).intValue();
|
|
|
+
|
|
|
+ Vector3f n = FastMath.computeNormal(vertices[v1], vertices[v2], vertices[v3]);
|
|
|
+ this.addNormal(n, normalMap, smooth, vertices[v1], vertices[v2], vertices[v3]);
|
|
|
+ normalList.add(normalMap.get(vertices[v1]));
|
|
|
+ normalList.add(normalMap.get(vertices[v2]));
|
|
|
+ normalList.add(normalMap.get(vertices[v3]));
|
|
|
+
|
|
|
+ this.appendVertexReference(v1, vertexList.size(), vertexReferenceMap);
|
|
|
+ indexList.add(vertexList.size());
|
|
|
+ vertexList.add(vertices[v1]);
|
|
|
+
|
|
|
+ this.appendVertexReference(v2, vertexList.size(), vertexReferenceMap);
|
|
|
+ indexList.add(vertexList.size());
|
|
|
+ vertexList.add(vertices[v2]);
|
|
|
+
|
|
|
+ this.appendVertexReference(v3, vertexList.size(), vertexReferenceMap);
|
|
|
+ indexList.add(vertexList.size());
|
|
|
+ vertexList.add(vertices[v3]);
|
|
|
+
|
|
|
+ if (v4 > 0) {
|
|
|
+ if (uvs != null) {
|
|
|
+ uvCoordinates.add(new Vector2f(uvs.get(0, 0).floatValue(), uvs.get(0, 1).floatValue()));
|
|
|
+ uvCoordinates.add(new Vector2f(uvs.get(2, 0).floatValue(), uvs.get(2, 1).floatValue()));
|
|
|
+ uvCoordinates.add(new Vector2f(uvs.get(3, 0).floatValue(), uvs.get(3, 1).floatValue()));
|
|
|
+ }
|
|
|
+ this.appendVertexReference(v1, vertexList.size(), vertexReferenceMap);
|
|
|
+ indexList.add(vertexList.size());
|
|
|
+ vertexList.add(vertices[v1]);
|
|
|
+
|
|
|
+ this.appendVertexReference(v3, vertexList.size(), vertexReferenceMap);
|
|
|
+ indexList.add(vertexList.size());
|
|
|
+ vertexList.add(vertices[v3]);
|
|
|
+
|
|
|
+ this.appendVertexReference(v4, vertexList.size(), vertexReferenceMap);
|
|
|
+ indexList.add(vertexList.size());
|
|
|
+ vertexList.add(vertices[v4]);
|
|
|
+
|
|
|
+ this.addNormal(n, normalMap, smooth, vertices[v4]);
|
|
|
+ normalList.add(normalMap.get(vertices[v1]));
|
|
|
+ normalList.add(normalMap.get(vertices[v3]));
|
|
|
+ normalList.add(normalMap.get(vertices[v4]));
|
|
|
+
|
|
|
+ if (verticesColors != null) {
|
|
|
+ verticesColors.add(vertexColorIndex + 3, verticesColors.get(vertexColorIndex));
|
|
|
+ verticesColors.add(vertexColorIndex + 4, verticesColors.get(vertexColorIndex + 2));
|
|
|
+ }
|
|
|
+ vertexColorIndex += 6;
|
|
|
+ } else {
|
|
|
+ if (verticesColors != null) {
|
|
|
+ verticesColors.remove(vertexColorIndex + 3);
|
|
|
+ vertexColorIndex += 3;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ meshContext.setVertexList(vertexList);
|
|
|
+ meshContext.setVertexReferenceMap(vertexReferenceMap);
|
|
|
+
|
|
|
+ Vector3f[] normals = normalList.toArray(new Vector3f[normalList.size()]);
|
|
|
+
|
|
|
+ // reading vertices groups (from the parent)
|
|
|
+ Structure parent = blenderContext.peekParent();
|
|
|
+ Structure defbase = (Structure) parent.getFieldValue("defbase");
|
|
|
+ List<Structure> defs = defbase.evaluateListBase(blenderContext);
|
|
|
+ String[] verticesGroups = new String[defs.size()];
|
|
|
+ int defIndex = 0;
|
|
|
+ for (Structure def : defs) {
|
|
|
+ verticesGroups[defIndex++] = def.getFieldValue("name").toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ // reading materials
|
|
|
+ MaterialHelper materialHelper = blenderContext.getHelper(MaterialHelper.class);
|
|
|
+ Material[] materials = null;
|
|
|
+ Material[] nonTexturedMaterials = null;
|
|
|
+ if ((blenderContext.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.MATERIALS) != 0) {
|
|
|
+ materials = materialHelper.getMaterials(structure, blenderContext);
|
|
|
+ nonTexturedMaterials = materials == null ? null : new Material[materials.length];// fill it when needed
|
|
|
+ }
|
|
|
+
|
|
|
+ // creating the result meshes
|
|
|
+ geometries = new ArrayList<Geometry>(meshesMap.size());
|
|
|
+
|
|
|
+ VertexBuffer verticesBuffer = new VertexBuffer(Type.Position);
|
|
|
+ verticesBuffer.setupData(Usage.Stream, 3, Format.Float,
|
|
|
+ BufferUtils.createFloatBuffer(vertexList.toArray(new Vector3f[vertexList.size()])));
|
|
|
+
|
|
|
+ // initial vertex position (used with animation)
|
|
|
+ VertexBuffer verticesBind = new VertexBuffer(Type.BindPosePosition);
|
|
|
+ verticesBind.setupData(Usage.CpuOnly, 3, Format.Float, BufferUtils.clone(verticesBuffer.getData()));
|
|
|
+
|
|
|
+ VertexBuffer normalsBuffer = new VertexBuffer(Type.Normal);
|
|
|
+ normalsBuffer.setupData(Usage.Stream, 3, Format.Float, BufferUtils.createFloatBuffer(normals));
|
|
|
+
|
|
|
+ // initial normals position (used with animation)
|
|
|
+ VertexBuffer normalsBind = new VertexBuffer(Type.BindPoseNormal);
|
|
|
+ normalsBind.setupData(Usage.CpuOnly, 3, Format.Float, BufferUtils.clone(normalsBuffer.getData()));
|
|
|
+
|
|
|
+ VertexBuffer uvCoordsBuffer = null;
|
|
|
+ if (uvCoordinates != null) {
|
|
|
+ uvCoordsBuffer = new VertexBuffer(Type.TexCoord);
|
|
|
+ uvCoordsBuffer.setupData(Usage.Static, 2, Format.Float,
|
|
|
+ BufferUtils.createFloatBuffer(uvCoordinates.toArray(new Vector2f[uvCoordinates.size()])));
|
|
|
}
|
|
|
|
|
|
- Pointer pMTFace = (Pointer) structure.getFieldValue("mtface");
|
|
|
- List<Vector2f> uvCoordinates = null;
|
|
|
- List<Structure> mtFaces = null;
|
|
|
-
|
|
|
- if (pMTFace.isNotNull()) {
|
|
|
- mtFaces = pMTFace.fetchData(blenderContext.getInputStream());
|
|
|
- int facesAmount = ((Number) structure.getFieldValue("totface")).intValue();
|
|
|
- if (mtFaces.size() != facesAmount) {
|
|
|
- throw new BlenderFileException("The amount of faces uv coordinates is not equal to faces amount!");
|
|
|
- }
|
|
|
- uvCoordinates = new ArrayList<Vector2f>();
|
|
|
- }
|
|
|
-
|
|
|
- // normalMap merges normals of faces that will be rendered smooth
|
|
|
- Map<Vector3f, Vector3f> normalMap = new HashMap<Vector3f, Vector3f>(verticesAmount);
|
|
|
-
|
|
|
- List<Vector3f> normalList = new ArrayList<Vector3f>();
|
|
|
- List<Vector3f> vertexList = new ArrayList<Vector3f>();
|
|
|
- // indicates if the material with the specified number should have a texture attached
|
|
|
- Map<Integer, Texture> materialNumberToTexture = new HashMap<Integer, Texture>();
|
|
|
- // 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)
|
|
|
- Map<Integer, List<Integer>> vertexReferenceMap = new HashMap<Integer, List<Integer>>(verticesAmount);
|
|
|
- int vertexColorIndex = 0;
|
|
|
- for (int i = 0; i < mFaces.size(); ++i) {
|
|
|
- Structure mFace = mFaces.get(i);
|
|
|
- boolean smooth = (((Number) mFace.getFieldValue("flag")).byteValue() & 0x01) != 0x00;
|
|
|
- DynamicArray<Number> uvs = null;
|
|
|
- boolean materialWithoutTextures = false;
|
|
|
- Pointer pImage = null;
|
|
|
- if (mtFaces != null) {
|
|
|
- Structure mtFace = mtFaces.get(i);
|
|
|
- pImage = (Pointer) mtFace.getFieldValue("tpage");
|
|
|
- materialWithoutTextures = pImage.isNull();
|
|
|
- // uvs always must be added wheater we have texture or not
|
|
|
- uvs = (DynamicArray<Number>) mtFace.getFieldValue("uv");
|
|
|
- uvCoordinates.add(new Vector2f(uvs.get(0, 0).floatValue(), uvs.get(0, 1).floatValue()));
|
|
|
- uvCoordinates.add(new Vector2f(uvs.get(1, 0).floatValue(), uvs.get(1, 1).floatValue()));
|
|
|
- uvCoordinates.add(new Vector2f(uvs.get(2, 0).floatValue(), uvs.get(2, 1).floatValue()));
|
|
|
- }
|
|
|
- int matNr = ((Number) mFace.getFieldValue("mat_nr")).intValue();
|
|
|
- Integer materialNumber = Integer.valueOf(materialWithoutTextures ? -1 * matNr - 1 : matNr);
|
|
|
- List<Integer> indexList = meshesMap.get(materialNumber);
|
|
|
- if (indexList == null) {
|
|
|
- indexList = new ArrayList<Integer>();
|
|
|
- meshesMap.put(materialNumber, indexList);
|
|
|
- }
|
|
|
-
|
|
|
- // attaching image to texture (face can have UV's and image whlie its material may have no texture attached)
|
|
|
- if (pImage != null && pImage.isNotNull() && !materialNumberToTexture.containsKey(materialNumber)) {
|
|
|
- Texture texture = textureHelper.getTextureFromImage(pImage.fetchData(blenderContext.getInputStream()).get(0),
|
|
|
- blenderContext);
|
|
|
- if (texture != null) {
|
|
|
- materialNumberToTexture.put(materialNumber, texture);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- int v1 = ((Number) mFace.getFieldValue("v1")).intValue();
|
|
|
- int v2 = ((Number) mFace.getFieldValue("v2")).intValue();
|
|
|
- int v3 = ((Number) mFace.getFieldValue("v3")).intValue();
|
|
|
- int v4 = ((Number) mFace.getFieldValue("v4")).intValue();
|
|
|
-
|
|
|
- Vector3f n = FastMath.computeNormal(vertices[v1], vertices[v2], vertices[v3]);
|
|
|
- this.addNormal(n, normalMap, smooth, vertices[v1], vertices[v2], vertices[v3]);
|
|
|
- normalList.add(normalMap.get(vertices[v1]));
|
|
|
- normalList.add(normalMap.get(vertices[v2]));
|
|
|
- normalList.add(normalMap.get(vertices[v3]));
|
|
|
-
|
|
|
- this.appendVertexReference(v1, vertexList.size(), vertexReferenceMap);
|
|
|
- indexList.add(vertexList.size());
|
|
|
- vertexList.add(vertices[v1]);
|
|
|
-
|
|
|
- this.appendVertexReference(v2, vertexList.size(), vertexReferenceMap);
|
|
|
- indexList.add(vertexList.size());
|
|
|
- vertexList.add(vertices[v2]);
|
|
|
-
|
|
|
- this.appendVertexReference(v3, vertexList.size(), vertexReferenceMap);
|
|
|
- indexList.add(vertexList.size());
|
|
|
- vertexList.add(vertices[v3]);
|
|
|
-
|
|
|
- if (v4 > 0) {
|
|
|
- if (uvs != null) {
|
|
|
- uvCoordinates.add(new Vector2f(uvs.get(0, 0).floatValue(), uvs.get(0, 1).floatValue()));
|
|
|
- uvCoordinates.add(new Vector2f(uvs.get(2, 0).floatValue(), uvs.get(2, 1).floatValue()));
|
|
|
- uvCoordinates.add(new Vector2f(uvs.get(3, 0).floatValue(), uvs.get(3, 1).floatValue()));
|
|
|
- }
|
|
|
- this.appendVertexReference(v1, vertexList.size(), vertexReferenceMap);
|
|
|
- indexList.add(vertexList.size());
|
|
|
- vertexList.add(vertices[v1]);
|
|
|
-
|
|
|
- this.appendVertexReference(v3, vertexList.size(), vertexReferenceMap);
|
|
|
- indexList.add(vertexList.size());
|
|
|
- vertexList.add(vertices[v3]);
|
|
|
-
|
|
|
- this.appendVertexReference(v4, vertexList.size(), vertexReferenceMap);
|
|
|
- indexList.add(vertexList.size());
|
|
|
- vertexList.add(vertices[v4]);
|
|
|
-
|
|
|
- this.addNormal(n, normalMap, smooth, vertices[v4]);
|
|
|
- normalList.add(normalMap.get(vertices[v1]));
|
|
|
- normalList.add(normalMap.get(vertices[v3]));
|
|
|
- normalList.add(normalMap.get(vertices[v4]));
|
|
|
-
|
|
|
- if (verticesColors != null) {
|
|
|
- verticesColors.add(vertexColorIndex + 3, verticesColors.get(vertexColorIndex));
|
|
|
- verticesColors.add(vertexColorIndex + 4, verticesColors.get(vertexColorIndex + 2));
|
|
|
- }
|
|
|
- vertexColorIndex += 6;
|
|
|
- } else {
|
|
|
- if (verticesColors != null) {
|
|
|
- verticesColors.remove(vertexColorIndex + 3);
|
|
|
- vertexColorIndex += 3;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- meshContext.setVertexList(vertexList);
|
|
|
- meshContext.setVertexReferenceMap(vertexReferenceMap);
|
|
|
-
|
|
|
- Vector3f[] normals = normalList.toArray(new Vector3f[normalList.size()]);
|
|
|
-
|
|
|
- // reading vertices groups (from the parent)
|
|
|
- Structure parent = blenderContext.peekParent();
|
|
|
- Structure defbase = (Structure) parent.getFieldValue("defbase");
|
|
|
- List<Structure> defs = defbase.evaluateListBase(blenderContext);
|
|
|
- String[] verticesGroups = new String[defs.size()];
|
|
|
- int defIndex = 0;
|
|
|
- for (Structure def : defs) {
|
|
|
- verticesGroups[defIndex++] = def.getFieldValue("name").toString();
|
|
|
- }
|
|
|
-
|
|
|
- // reading materials
|
|
|
- MaterialHelper materialHelper = blenderContext.getHelper(MaterialHelper.class);
|
|
|
- Material[] materials = null;
|
|
|
- Material[] nonTexturedMaterials = null;
|
|
|
- if ((blenderContext.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.MATERIALS) != 0) {
|
|
|
- materials = materialHelper.getMaterials(structure, blenderContext);
|
|
|
- nonTexturedMaterials = materials == null ? null : new Material[materials.length];// fill it when needed
|
|
|
- }
|
|
|
-
|
|
|
- // creating the result meshes
|
|
|
- geometries = new ArrayList<Geometry>(meshesMap.size());
|
|
|
-
|
|
|
- VertexBuffer verticesBuffer = new VertexBuffer(Type.Position);
|
|
|
- verticesBuffer.setupData(Usage.Stream, 3, Format.Float,
|
|
|
- BufferUtils.createFloatBuffer(vertexList.toArray(new Vector3f[vertexList.size()])));
|
|
|
-
|
|
|
- // initial vertex position (used with animation)
|
|
|
- VertexBuffer verticesBind = new VertexBuffer(Type.BindPosePosition);
|
|
|
- verticesBind.setupData(Usage.CpuOnly, 3, Format.Float, BufferUtils.clone(verticesBuffer.getData()));
|
|
|
-
|
|
|
- VertexBuffer normalsBuffer = new VertexBuffer(Type.Normal);
|
|
|
- normalsBuffer.setupData(Usage.Stream, 3, Format.Float, BufferUtils.createFloatBuffer(normals));
|
|
|
-
|
|
|
- // initial normals position (used with animation)
|
|
|
- VertexBuffer normalsBind = new VertexBuffer(Type.BindPoseNormal);
|
|
|
- normalsBind.setupData(Usage.CpuOnly, 3, Format.Float, BufferUtils.clone(normalsBuffer.getData()));
|
|
|
-
|
|
|
- VertexBuffer uvCoordsBuffer = null;
|
|
|
- if (uvCoordinates != null) {
|
|
|
- uvCoordsBuffer = new VertexBuffer(Type.TexCoord);
|
|
|
- uvCoordsBuffer.setupData(Usage.Static, 2, Format.Float,
|
|
|
- BufferUtils.createFloatBuffer(uvCoordinates.toArray(new Vector2f[uvCoordinates.size()])));
|
|
|
- }
|
|
|
-
|
|
|
- //reading custom properties
|
|
|
- Properties properties = this.loadProperties(structure, blenderContext);
|
|
|
-
|
|
|
- // generating meshes
|
|
|
- FloatBuffer verticesColorsBuffer = this.createFloatBuffer(verticesColors);
|
|
|
- for (Entry<Integer, List<Integer>> meshEntry : meshesMap.entrySet()) {
|
|
|
- Mesh mesh = new Mesh();
|
|
|
-
|
|
|
- // creating vertices indices for this mesh
|
|
|
- List<Integer> indexList = meshEntry.getValue();
|
|
|
- int[] indices = new int[indexList.size()];
|
|
|
- for (int i = 0; i < indexList.size(); ++i) {
|
|
|
- indices[i] = indexList.get(i).intValue();
|
|
|
- }
|
|
|
-
|
|
|
- // setting vertices
|
|
|
- mesh.setBuffer(Type.Index, 1, indices);
|
|
|
- mesh.setBuffer(verticesBuffer);
|
|
|
- mesh.setBuffer(verticesBind);
|
|
|
-
|
|
|
- // setting vertices colors
|
|
|
- if (verticesColorsBuffer != null) {
|
|
|
- mesh.setBuffer(Type.Color, 4, verticesColorsBuffer);
|
|
|
- }
|
|
|
-
|
|
|
- // setting faces' normals
|
|
|
- mesh.setBuffer(normalsBuffer);
|
|
|
- mesh.setBuffer(normalsBind);
|
|
|
-
|
|
|
- // creating the result
|
|
|
- Geometry geometry = new Geometry(name + (geometries.size() + 1), mesh);
|
|
|
- if (materials != null) {
|
|
|
- int materialNumber = meshEntry.getKey().intValue();
|
|
|
- Material material;
|
|
|
- if (materialNumber >= 0) {
|
|
|
- material = materials[materialNumber];
|
|
|
- if (materialNumberToTexture.containsKey(Integer.valueOf(materialNumber))) {
|
|
|
- if (material.getMaterialDef().getAssetName().contains("Lighting")) {
|
|
|
- if (!materialHelper.hasTexture(material, MaterialHelper.TEXTURE_TYPE_DIFFUSE)) {
|
|
|
- material = material.clone();
|
|
|
- material.setTexture(MaterialHelper.TEXTURE_TYPE_DIFFUSE,
|
|
|
- materialNumberToTexture.get(Integer.valueOf(materialNumber)));
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (!materialHelper.hasTexture(material, MaterialHelper.TEXTURE_TYPE_COLOR)) {
|
|
|
- material = material.clone();
|
|
|
- material.setTexture(MaterialHelper.TEXTURE_TYPE_COLOR,
|
|
|
- materialNumberToTexture.get(Integer.valueOf(materialNumber)));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- materialNumber = -1 * (materialNumber + 1);
|
|
|
- if (nonTexturedMaterials[materialNumber] == null) {
|
|
|
- nonTexturedMaterials[materialNumber] = materialHelper.getNonTexturedMaterial(materials[materialNumber],
|
|
|
- TextureHelper.TEX_IMAGE);
|
|
|
- }
|
|
|
- material = nonTexturedMaterials[materialNumber];
|
|
|
- }
|
|
|
- geometry.setMaterial(material);
|
|
|
- if (material.isTransparent()){
|
|
|
+ //reading custom properties
|
|
|
+ Properties properties = this.loadProperties(structure, blenderContext);
|
|
|
+
|
|
|
+ // generating meshes
|
|
|
+ FloatBuffer verticesColorsBuffer = this.createFloatBuffer(verticesColors);
|
|
|
+ for (Entry<Integer, List<Integer>> meshEntry : meshesMap.entrySet()) {
|
|
|
+ Mesh mesh = new Mesh();
|
|
|
+
|
|
|
+ // creating vertices indices for this mesh
|
|
|
+ List<Integer> indexList = meshEntry.getValue();
|
|
|
+ int[] indices = new int[indexList.size()];
|
|
|
+ for (int i = 0; i < indexList.size(); ++i) {
|
|
|
+ indices[i] = indexList.get(i).intValue();
|
|
|
+ }
|
|
|
+
|
|
|
+ // setting vertices
|
|
|
+ mesh.setBuffer(Type.Index, 1, indices);
|
|
|
+ mesh.setBuffer(verticesBuffer);
|
|
|
+ mesh.setBuffer(verticesBind);
|
|
|
+
|
|
|
+ // setting vertices colors
|
|
|
+ if (verticesColorsBuffer != null) {
|
|
|
+ mesh.setBuffer(Type.Color, 4, verticesColorsBuffer);
|
|
|
+ }
|
|
|
+
|
|
|
+ // setting faces' normals
|
|
|
+ mesh.setBuffer(normalsBuffer);
|
|
|
+ mesh.setBuffer(normalsBind);
|
|
|
+
|
|
|
+ // creating the result
|
|
|
+ Geometry geometry = new Geometry(name + (geometries.size() + 1), mesh);
|
|
|
+ if (materials != null) {
|
|
|
+ int materialNumber = meshEntry.getKey().intValue();
|
|
|
+ Material material;
|
|
|
+ if (materialNumber >= 0) {
|
|
|
+ material = materials[materialNumber];
|
|
|
+ if (materialNumberToTexture.containsKey(Integer.valueOf(materialNumber))) {
|
|
|
+ if (material.getMaterialDef().getAssetName().contains("Lighting")) {
|
|
|
+ if (!materialHelper.hasTexture(material, MaterialHelper.TEXTURE_TYPE_DIFFUSE)) {
|
|
|
+ material = material.clone();
|
|
|
+ material.setTexture(MaterialHelper.TEXTURE_TYPE_DIFFUSE,
|
|
|
+ materialNumberToTexture.get(Integer.valueOf(materialNumber)));
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (!materialHelper.hasTexture(material, MaterialHelper.TEXTURE_TYPE_COLOR)) {
|
|
|
+ material = material.clone();
|
|
|
+ material.setTexture(MaterialHelper.TEXTURE_TYPE_COLOR,
|
|
|
+ materialNumberToTexture.get(Integer.valueOf(materialNumber)));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ materialNumber = -1 * (materialNumber + 1);
|
|
|
+ if (nonTexturedMaterials[materialNumber] == null) {
|
|
|
+ nonTexturedMaterials[materialNumber] = materialHelper.getNonTexturedMaterial(materials[materialNumber],
|
|
|
+ TextureHelper.TEX_IMAGE);
|
|
|
+ }
|
|
|
+ material = nonTexturedMaterials[materialNumber];
|
|
|
+ }
|
|
|
+ geometry.setMaterial(material);
|
|
|
+ if (material.isTransparent()) {
|
|
|
geometry.setQueueBucket(Bucket.Transparent);
|
|
|
}
|
|
|
- } else {
|
|
|
- geometry.setMaterial(blenderContext.getDefaultMaterial());
|
|
|
- }
|
|
|
- if(properties != null && properties.getValue() != null) {
|
|
|
- geometry.setUserData("properties", properties);
|
|
|
- }
|
|
|
- geometries.add(geometry);
|
|
|
- }
|
|
|
-
|
|
|
- //applying uvCoordinates for all the meshes
|
|
|
- if (uvCoordsBuffer != null) {
|
|
|
- for(Geometry geom : geometries) {
|
|
|
- geom.getMesh().setBuffer(uvCoordsBuffer);
|
|
|
- }
|
|
|
- } else {
|
|
|
- Map<Material, List<Geometry>> materialMap = new HashMap<Material, List<Geometry>>();
|
|
|
- for(Geometry geom : geometries) {
|
|
|
- Material material = geom.getMaterial();
|
|
|
- List<Geometry> geomsWithCommonMaterial = materialMap.get(material);
|
|
|
- if(geomsWithCommonMaterial==null) {
|
|
|
- geomsWithCommonMaterial = new ArrayList<Geometry>();
|
|
|
- materialMap.put(material, geomsWithCommonMaterial);
|
|
|
- }
|
|
|
- geomsWithCommonMaterial.add(geom);
|
|
|
-
|
|
|
- }
|
|
|
- for(Entry<Material, List<Geometry>> entry : materialMap.entrySet()) {
|
|
|
- MaterialContext materialContext = blenderContext.getMaterialContext(entry.getKey());
|
|
|
- if(materialContext != null && materialContext.getTexturesCount()>0) {
|
|
|
- VertexBuffer coords = UVCoordinatesGenerator.generateUVCoordinates(materialContext.getUvCoordinatesType(),
|
|
|
- materialContext.getProjectionType(), materialContext.getTextureDimension(),
|
|
|
- materialContext.getProjection(0), entry.getValue());
|
|
|
- //setting the coordinates inside the mesh context
|
|
|
- for(Geometry geometry : entry.getValue()) {
|
|
|
- meshContext.addUVCoordinates(geometry, coords);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- blenderContext.addLoadedFeatures(structure.getOldMemoryAddress(), structure.getName(), structure, geometries);
|
|
|
- blenderContext.setMeshContext(structure.getOldMemoryAddress(), meshContext);
|
|
|
- return geometries;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * This method adds a normal to a normals' map. This map is used to merge normals of a vertor that should be rendered smooth.
|
|
|
- *
|
|
|
- * @param normalToAdd
|
|
|
- * a normal to be added
|
|
|
- * @param normalMap
|
|
|
- * merges normals of faces that will be rendered smooth; the key is the vertex and the value - its normal vector
|
|
|
- * @param smooth
|
|
|
- * the variable that indicates wheather to merge normals (creating the smooth mesh) or not
|
|
|
- * @param vertices
|
|
|
- * a list of vertices read from the blender file
|
|
|
- */
|
|
|
- public void addNormal(Vector3f normalToAdd, Map<Vector3f, Vector3f> normalMap, boolean smooth, Vector3f... vertices) {
|
|
|
- for (Vector3f v : vertices) {
|
|
|
- Vector3f n = normalMap.get(v);
|
|
|
- if (!smooth || n == null) {
|
|
|
- normalMap.put(v, normalToAdd.clone());
|
|
|
- } else {
|
|
|
- n.addLocal(normalToAdd).normalizeLocal();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 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
|
|
|
- */
|
|
|
- protected 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));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * This method returns the vertices colors. Each vertex is stored in float[4] array.
|
|
|
- *
|
|
|
- * @param meshStructure
|
|
|
- * the structure containing the mesh data
|
|
|
- * @param blenderContext
|
|
|
- * the blender context
|
|
|
- * @return a list of vertices colors, each color belongs to a single vertex
|
|
|
- * @throws BlenderFileException
|
|
|
- * this exception is thrown when the blend file structure is somehow invalid or corrupted
|
|
|
- */
|
|
|
- public List<float[]> getVerticesColors(Structure meshStructure, BlenderContext blenderContext) throws BlenderFileException {
|
|
|
- Pointer pMCol = (Pointer) meshStructure.getFieldValue("mcol");
|
|
|
- List<float[]> verticesColors = null;
|
|
|
- List<Structure> mCol = null;
|
|
|
- if (pMCol.isNotNull()) {
|
|
|
- verticesColors = new LinkedList<float[]>();
|
|
|
- mCol = pMCol.fetchData(blenderContext.getInputStream());
|
|
|
- for (Structure color : mCol) {
|
|
|
- float r = ((Number) color.getFieldValue("r")).byteValue() / 256.0f;
|
|
|
- float g = ((Number) color.getFieldValue("g")).byteValue() / 256.0f;
|
|
|
- float b = ((Number) color.getFieldValue("b")).byteValue() / 256.0f;
|
|
|
- float a = ((Number) color.getFieldValue("a")).byteValue() / 256.0f;
|
|
|
- verticesColors.add(new float[] { b, g, r, a });
|
|
|
- }
|
|
|
- }
|
|
|
- return verticesColors;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * This method returns the vertices.
|
|
|
- *
|
|
|
- * @param meshStructure
|
|
|
- * the structure containing the mesh data
|
|
|
- * @param blenderContext
|
|
|
- * the blender context
|
|
|
- * @return a list of vertices colors, each color belongs to a single vertex
|
|
|
- * @throws BlenderFileException
|
|
|
- * this exception is thrown when the blend file structure is somehow invalid or corrupted
|
|
|
- */
|
|
|
- @SuppressWarnings("unchecked")
|
|
|
- public Vector3f[] getVertices(Structure meshStructure, BlenderContext blenderContext) throws BlenderFileException {
|
|
|
- int verticesAmount = ((Number) meshStructure.getFieldValue("totvert")).intValue();
|
|
|
- Vector3f[] vertices = new Vector3f[verticesAmount];
|
|
|
- if (verticesAmount == 0) {
|
|
|
- return vertices;
|
|
|
- }
|
|
|
-
|
|
|
- Pointer pMVert = (Pointer) meshStructure.getFieldValue("mvert");
|
|
|
- List<Structure> mVerts = pMVert.fetchData(blenderContext.getInputStream());
|
|
|
- for (int i = 0; i < verticesAmount; ++i) {
|
|
|
- DynamicArray<Number> coordinates = (DynamicArray<Number>) mVerts.get(i).getFieldValue("co");
|
|
|
- vertices[i] = new Vector3f(coordinates.get(0).floatValue(), coordinates.get(1).floatValue(), coordinates.get(2).floatValue());
|
|
|
- }
|
|
|
- return vertices;
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean shouldBeLoaded(Structure structure, BlenderContext blenderContext) {
|
|
|
- return true;
|
|
|
- }
|
|
|
+ } else {
|
|
|
+ geometry.setMaterial(blenderContext.getDefaultMaterial());
|
|
|
+ }
|
|
|
+ if (properties != null && properties.getValue() != null) {
|
|
|
+ geometry.setUserData("properties", properties);
|
|
|
+ }
|
|
|
+ geometries.add(geometry);
|
|
|
+ }
|
|
|
+
|
|
|
+ //applying uvCoordinates for all the meshes
|
|
|
+ if (uvCoordsBuffer != null) {
|
|
|
+ for (Geometry geom : geometries) {
|
|
|
+ geom.getMesh().setBuffer(uvCoordsBuffer);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ Map<Material, List<Geometry>> materialMap = new HashMap<Material, List<Geometry>>();
|
|
|
+ for (Geometry geom : geometries) {
|
|
|
+ Material material = geom.getMaterial();
|
|
|
+ List<Geometry> geomsWithCommonMaterial = materialMap.get(material);
|
|
|
+ if (geomsWithCommonMaterial == null) {
|
|
|
+ geomsWithCommonMaterial = new ArrayList<Geometry>();
|
|
|
+ materialMap.put(material, geomsWithCommonMaterial);
|
|
|
+ }
|
|
|
+ geomsWithCommonMaterial.add(geom);
|
|
|
+
|
|
|
+ }
|
|
|
+ for (Entry<Material, List<Geometry>> entry : materialMap.entrySet()) {
|
|
|
+ MaterialContext materialContext = blenderContext.getMaterialContext(entry.getKey());
|
|
|
+ if (materialContext != null && materialContext.getTexturesCount() > 0) {
|
|
|
+ VertexBuffer coords = UVCoordinatesGenerator.generateUVCoordinates(materialContext.getUvCoordinatesType(),
|
|
|
+ materialContext.getProjectionType(), materialContext.getTextureDimension(),
|
|
|
+ materialContext.getProjection(0), entry.getValue());
|
|
|
+ //setting the coordinates inside the mesh context
|
|
|
+ for (Geometry geometry : entry.getValue()) {
|
|
|
+ meshContext.addUVCoordinates(geometry, coords);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ blenderContext.addLoadedFeatures(structure.getOldMemoryAddress(), structure.getName(), structure, geometries);
|
|
|
+ blenderContext.setMeshContext(structure.getOldMemoryAddress(), meshContext);
|
|
|
+ return geometries;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * This method adds a normal to a normals' map. This map is used to merge normals of a vertor that should be rendered smooth.
|
|
|
+ *
|
|
|
+ * @param normalToAdd
|
|
|
+ * a normal to be added
|
|
|
+ * @param normalMap
|
|
|
+ * merges normals of faces that will be rendered smooth; the key is the vertex and the value - its normal vector
|
|
|
+ * @param smooth
|
|
|
+ * the variable that indicates wheather to merge normals (creating the smooth mesh) or not
|
|
|
+ * @param vertices
|
|
|
+ * a list of vertices read from the blender file
|
|
|
+ */
|
|
|
+ public void addNormal(Vector3f normalToAdd, Map<Vector3f, Vector3f> normalMap, boolean smooth, Vector3f... vertices) {
|
|
|
+ for (Vector3f v : vertices) {
|
|
|
+ Vector3f n = normalMap.get(v);
|
|
|
+ if (!smooth || n == null) {
|
|
|
+ normalMap.put(v, normalToAdd.clone());
|
|
|
+ } else {
|
|
|
+ n.addLocal(normalToAdd).normalizeLocal();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 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
|
|
|
+ */
|
|
|
+ protected 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));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * This method returns the vertices colors. Each vertex is stored in float[4] array.
|
|
|
+ *
|
|
|
+ * @param meshStructure
|
|
|
+ * the structure containing the mesh data
|
|
|
+ * @param blenderContext
|
|
|
+ * the blender context
|
|
|
+ * @return a list of vertices colors, each color belongs to a single vertex
|
|
|
+ * @throws BlenderFileException
|
|
|
+ * this exception is thrown when the blend file structure is somehow invalid or corrupted
|
|
|
+ */
|
|
|
+ public List<float[]> getVerticesColors(Structure meshStructure, BlenderContext blenderContext) throws BlenderFileException {
|
|
|
+ Pointer pMCol = (Pointer) meshStructure.getFieldValue("mcol");
|
|
|
+ List<float[]> verticesColors = null;
|
|
|
+ List<Structure> mCol = null;
|
|
|
+ if (pMCol.isNotNull()) {
|
|
|
+ verticesColors = new LinkedList<float[]>();
|
|
|
+ mCol = pMCol.fetchData(blenderContext.getInputStream());
|
|
|
+ for (Structure color : mCol) {
|
|
|
+ float r = ((Number) color.getFieldValue("r")).byteValue() / 256.0f;
|
|
|
+ float g = ((Number) color.getFieldValue("g")).byteValue() / 256.0f;
|
|
|
+ float b = ((Number) color.getFieldValue("b")).byteValue() / 256.0f;
|
|
|
+ float a = ((Number) color.getFieldValue("a")).byteValue() / 256.0f;
|
|
|
+ verticesColors.add(new float[]{b, g, r, a});
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return verticesColors;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * This method returns the vertices.
|
|
|
+ *
|
|
|
+ * @param meshStructure
|
|
|
+ * the structure containing the mesh data
|
|
|
+ * @param blenderContext
|
|
|
+ * the blender context
|
|
|
+ * @return a list of vertices colors, each color belongs to a single vertex
|
|
|
+ * @throws BlenderFileException
|
|
|
+ * this exception is thrown when the blend file structure is somehow invalid or corrupted
|
|
|
+ */
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
+ public Vector3f[] getVertices(Structure meshStructure, BlenderContext blenderContext) throws BlenderFileException {
|
|
|
+ int verticesAmount = ((Number) meshStructure.getFieldValue("totvert")).intValue();
|
|
|
+ Vector3f[] vertices = new Vector3f[verticesAmount];
|
|
|
+ if (verticesAmount == 0) {
|
|
|
+ return vertices;
|
|
|
+ }
|
|
|
+
|
|
|
+ Pointer pMVert = (Pointer) meshStructure.getFieldValue("mvert");
|
|
|
+ List<Structure> mVerts = pMVert.fetchData(blenderContext.getInputStream());
|
|
|
+ for (int i = 0; i < verticesAmount; ++i) {
|
|
|
+ DynamicArray<Number> coordinates = (DynamicArray<Number>) mVerts.get(i).getFieldValue("co");
|
|
|
+ if (blenderContext.getBlenderKey().isFixUpAxis()) {
|
|
|
+ vertices[i] = new Vector3f(coordinates.get(0).floatValue(), coordinates.get(2).floatValue(), -coordinates.get(1).floatValue());
|
|
|
+ } else {
|
|
|
+ vertices[i] = new Vector3f(coordinates.get(0).floatValue(), coordinates.get(1).floatValue(), coordinates.get(2).floatValue());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return vertices;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean shouldBeLoaded(Structure structure, BlenderContext blenderContext) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
}
|