Browse Source

Blender Loader : implemented fixUpAxis for meshes

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8265 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
rem..om 14 years ago
parent
commit
bf70599185
1 changed files with 432 additions and 427 deletions
  1. 432 427
      engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java

+ 432 - 427
engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java

@@ -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;
+    }
 }