Automatic generation of UV-coordinates (not the best solution yet, but working on it ;) )

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7941 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
Kae..pl 14 years ago
parent c6aafbd0ef
commit 821dc08553
  1. 33
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MaterialHelper.java
  2. 84
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MeshHelper.java

@ -410,6 +410,37 @@ public class MaterialHelper extends AbstractBlenderHelper {
} }
return result; return result;
} }
/**
* This method indicates if the material has any kind of texture.
*
* @param material
* the material
* @return <b>true</b> if the texture exists in the material and <B>false</b> otherwise
*/
public boolean hasTexture(Material material) {
if (material != null) {
if(material.getTextureParam(TEXTURE_TYPE_ALPHA) != null) {
return true;
}
if(material.getTextureParam(TEXTURE_TYPE_COLOR) != null) {
return true;
}
if(material.getTextureParam(TEXTURE_TYPE_DIFFUSE) != null) {
return true;
}
if(material.getTextureParam(TEXTURE_TYPE_GLOW) != null) {
return true;
}
if(material.getTextureParam(TEXTURE_TYPE_NORMAL) != null) {
return true;
}
if(material.getTextureParam(TEXTURE_TYPE_SPECULAR) != null) {
return true;
}
}
return false;
}
/** /**
* This method indicates if the material has a texture of a specified type. * This method indicates if the material has a texture of a specified type.
@ -426,7 +457,7 @@ public class MaterialHelper extends AbstractBlenderHelper {
} }
return false; return false;
} }
/** /**
* This method returns the diffuse color * This method returns the diffuse color
* *

@ -41,8 +41,13 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import com.jme3.asset.BlenderKey.FeaturesToLoad; import com.jme3.asset.BlenderKey.FeaturesToLoad;
import com.jme3.bounding.BoundingBox;
import com.jme3.bounding.BoundingSphere;
import com.jme3.bounding.BoundingVolume;
import com.jme3.collision.CollisionResults;
import com.jme3.material.Material; import com.jme3.material.Material;
import com.jme3.math.FastMath; import com.jme3.math.FastMath;
import com.jme3.math.Ray;
import com.jme3.math.Vector2f; import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f; import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.Bucket; import com.jme3.renderer.queue.RenderQueue.Bucket;
@ -301,7 +306,7 @@ public class MeshHelper extends AbstractBlenderHelper {
FloatBuffer verticesColorsBuffer = this.createFloatBuffer(verticesColors); FloatBuffer verticesColorsBuffer = this.createFloatBuffer(verticesColors);
for (Entry<Integer, List<Integer>> meshEntry : meshesMap.entrySet()) { for (Entry<Integer, List<Integer>> meshEntry : meshesMap.entrySet()) {
Mesh mesh = new Mesh(); Mesh mesh = new Mesh();
// creating vertices indices for this mesh // creating vertices indices for this mesh
List<Integer> indexList = meshEntry.getValue(); List<Integer> indexList = meshEntry.getValue();
int[] indices = new int[indexList.size()]; int[] indices = new int[indexList.size()];
@ -330,11 +335,6 @@ public class MeshHelper extends AbstractBlenderHelper {
mesh.setBuffer(normalsBuffer); mesh.setBuffer(normalsBuffer);
mesh.setBuffer(normalsBind); mesh.setBuffer(normalsBind);
// setting uvCoords
if (uvCoordsBuffer != null) {
mesh.setBuffer(uvCoordsBuffer);
}
// creating the result // creating the result
Geometry geometry = new Geometry(name + (geometries.size() + 1), mesh); Geometry geometry = new Geometry(name + (geometries.size() + 1), mesh);
if (materials != null) { if (materials != null) {
@ -377,9 +377,81 @@ public class MeshHelper extends AbstractBlenderHelper {
} }
geometries.add(geometry); geometries.add(geometry);
} }
//applying uvCoordinates for all the meshes
if (uvCoordsBuffer != null) {
for(Geometry geom : geometries) {
geom.getMesh().setBuffer(uvCoordsBuffer);
}
} else {
Vector2f[] uvTable = new Vector2f[vertexList.size()];
Ray ray = new Ray();
CollisionResults cr = new CollisionResults();
Vector3f yVec = new Vector3f();
Vector3f zVec = new Vector3f();
for(Geometry geom : geometries) {
if(materialHelper.hasTexture(geom.getMaterial())) {//generate only when material has a texture
geom.getMesh().updateBound();
BoundingSphere bs = this.getBoundingSphere(geom.getMesh());
float r2 = bs.getRadius() * bs.getRadius();
yVec.set(0, -bs.getRadius(), 0);
zVec.set(0, 0, -bs.getRadius());
Vector3f center = bs.getCenter();
ray.setOrigin(center);
//we cast each vertex of the current mesh on the bounding box to determine the UV-coordinates
for(int i=0;i<geom.getMesh().getIndexBuffer().size();++i) {
int index = geom.getMesh().getIndexBuffer().get(i);
ray.setOrigin(vertexList.get(index));
ray.setDirection(normalList.get(index));
//finding collision point
cr.clear();
bs.collideWith(ray, cr);//there is ALWAYS one collision
Vector3f p = cr.getCollision(0).getContactPoint();
p.subtractLocal(center);
//arcLength = FastMath.acos(p.dot(yVec)/(p.length * yVec.length)) * r <- an arc length on the sphere (from top to the point on the sphere)
//but yVec.length == r and p.length == r so: arcLength = FastMath.acos(p.dot(yVec)/r^2)/r
//U coordinate is as follows: u = arcLength / PI*r
//so to compute it faster we just write: u = FastMath.acos(p.dot(yVec)/r^2) / PI;
float u = FastMath.acos(p.dot(yVec)/r2) / FastMath.PI;
//we use similiar method to compute v
//the only difference is that we need to cast the p vector on ZX plane
//and use its length instead of r
p.y = 0;
float v = FastMath.acos(p.dot(zVec)/(bs.getRadius()*p.length())) / FastMath.PI;
uvTable[index] = new Vector2f(u, v);
}
}
}
//creating and applying the buffer
uvCoordsBuffer = new VertexBuffer(Type.TexCoord);
uvCoordsBuffer.setupData(Usage.Static, 2, Format.Float, BufferUtils.createFloatBuffer(uvTable));
for(Geometry geom : geometries) {
geom.getMesh().setBuffer(uvCoordsBuffer);
}
}
dataRepository.addLoadedFeatures(structure.getOldMemoryAddress(), structure.getName(), structure, geometries); dataRepository.addLoadedFeatures(structure.getOldMemoryAddress(), structure.getName(), structure, geometries);
return geometries; return geometries;
} }
/**
* This method returns bounding shpere of a given mesh.
* @param mesh the mesh to read the bounding sphere from
* @return the bounding sphere of the given mesh
*/
protected BoundingSphere getBoundingSphere(Mesh mesh) {
BoundingVolume bv = mesh.getBound();
if(bv instanceof BoundingSphere) {
return (BoundingSphere)bv;
} else if(bv instanceof BoundingBox) {
BoundingBox bb = (BoundingBox)bv;
return new BoundingSphere(bb.getCenter().subtract(bb.getMin(null)).length(), bb.getCenter());
}
throw new IllegalStateException("Unknown bounding volume type: " + bv.getClass().getName());
}
/** /**
* 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.

Loading…
Cancel
Save