Blender Loader : implemented fixUpAxis for meshes

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8265 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
rem..om 14 years ago
parent c011a29529
commit bf70599185
  1. 859
      engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java

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

Loading…
Cancel
Save