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
This commit is contained in:
		
							parent
							
								
									c6aafbd0ef
								
							
						
					
					
						commit
						821dc08553
					
				| @ -410,6 +410,37 @@ public class MaterialHelper extends AbstractBlenderHelper { | ||||
| 		} | ||||
| 		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. | ||||
| @ -426,7 +457,7 @@ public class MaterialHelper extends AbstractBlenderHelper { | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	 | ||||
| 	/** | ||||
| 	 * This method returns the diffuse color | ||||
| 	 *  | ||||
|  | ||||
| @ -41,8 +41,13 @@ import java.util.Map; | ||||
| import java.util.Map.Entry; | ||||
| 
 | ||||
| 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.math.FastMath; | ||||
| import com.jme3.math.Ray; | ||||
| import com.jme3.math.Vector2f; | ||||
| import com.jme3.math.Vector3f; | ||||
| import com.jme3.renderer.queue.RenderQueue.Bucket; | ||||
| @ -301,7 +306,7 @@ public class MeshHelper extends AbstractBlenderHelper { | ||||
| 		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()]; | ||||
| @ -330,11 +335,6 @@ public class MeshHelper extends AbstractBlenderHelper { | ||||
| 			mesh.setBuffer(normalsBuffer); | ||||
| 			mesh.setBuffer(normalsBind); | ||||
| 
 | ||||
| 			// setting uvCoords | ||||
| 			if (uvCoordsBuffer != null) { | ||||
| 				mesh.setBuffer(uvCoordsBuffer); | ||||
| 			} | ||||
| 
 | ||||
| 			// creating the result | ||||
| 			Geometry geometry = new Geometry(name + (geometries.size() + 1), mesh); | ||||
| 			if (materials != null) { | ||||
| @ -377,9 +377,81 @@ public class MeshHelper extends AbstractBlenderHelper { | ||||
| 			} | ||||
| 			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); | ||||
| 		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. | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user