This is the code where I form the Spatial. Take in account that I’m a n00b in 3D programming.
/**
* Creates a Spatial that corresponds to the surface object.
* @param surface
* @param material
* @param doubleFaced if the object must be drawn in its two faces. Set to
* false if only one face is drawn (maybe useful for walls).
* @return a Spatial that corresponds to the surface object.
*/
public Spatial createSurface(Surface surface, Material material, boolean doubleFaced) {
Spatial result;
Node node = new Node(surface.getId());
List<SpatialLocation> corners = surface.getCorners();
Set<Mesh> triangles = operator.getTriangles(corners, doubleFaced);
for(Mesh triangle: triangles) {
Geometry geom = new Geometry(triangle.toString(), triangle);
node.attachChild(geom);
}
result = GeometryBatchFactory.optimize(node);
result.setMaterial(material);
return result;
}
operator is a member of an inner class that makes the triangulation. I wrote it several months ago, so I don’t remember it quite well
/**
* Helper class to calculate triangulation.
*
* Uses java3d technology.
*/
private class J3dOperator {
private Set<Mesh> getTriangles(List<SpatialLocation> corners, boolean doubleFaced) {
Set<Mesh> result = new HashSet<Mesh>();
double[] vertexArray = new double[corners.size()*3];
int i=0;
/*
* Insert corners in vertex array.
*
* Coordinates components (x,y,z) are simply append one after
* another.
*/
for(SpatialLocation corner: corners) {
vertexArray[(i*3)] = corner.getX();
vertexArray[(i*3)+1] = corner.getY();
vertexArray[(i*3)+2] = corner.getZ();
i++;
}
// Create polygon structure.
GeometryInfo gi = new GeometryInfo(GeometryInfo.POLYGON_ARRAY);
gi.setCoordinates( vertexArray );
int[] stripCountArray = {corners.size()};
int[] countourCountArray = {stripCountArray.length};
gi.setContourCounts( countourCountArray );
gi.setStripCounts( stripCountArray );
//Forces triangulation
gi.getGeometryArray();
// Take the vertices of the polygon's triangles and build the vertex
Point3f[] trianglesVertices = gi.getCoordinates();
for( i=0; i<trianglesVertices.length; i+=3) {
Mesh mesh = triangle2Mesh(trianglesVertices[i],
trianglesVertices[i+1], trianglesVertices[i+2]);
result.add(mesh);
/* If the surface must be drawn in both faces, the inverse
* triangle must be added.
*/
if(doubleFaced) {
mesh = triangle2Mesh(trianglesVertices[i+2],
trianglesVertices[i+1], trianglesVertices[i]);
result.add(mesh);
}
}
return result;
}
private Mesh triangle2Mesh(Point3f v1, Point3f v2, Point3f v3) {
Mesh mesh = new Mesh();
Vector3f[] vertices = new Vector3f[3];
int i=0;
if(v1!=null)
vertices[i++] = new Vector3f(
(float) v1.x,
(float) v1.y,
(float) v1.z
);
if(v2!=null)
vertices[i++] = new Vector3f(
(float) v2.x,
(float) v2.y,
(float) v2.z
);
if(v3!=null)
vertices[i++] = new Vector3f(
(float) v3.x,
(float) v3.y,
(float) v3.z
);
int[] indexes = {0, 1, 2 };
mesh.setBuffer(Type.Position, 3, BufferUtils.createFloatBuffer(vertices));
mesh.setBuffer(Type.Index, 1, BufferUtils.createIntBuffer(indexes));
// TODO texture coordinates?
// TODO indexes?
mesh.updateBound();
return mesh;
}
}
Copypasteing the code, I see I had a pair of TODO, one of them “TODO texture coordinates”. I don’t remember which tutorial may I be following and I don’t know exactly what “texture coordinates” are.
Here is the material. It is not written by me, but by a coworker who I cannot contact at the moment. I don’t know much about materials.
Material MyMaterial : Common/MatDefs/Light/Lighting.j3md {
MaterialParameters {
ParallaxHeight : 0.05
Shininess : 64.0
Minnaert : true
DiffuseMap : Flip Repeat Textures/habitacion/suelo_1_dif.jpg
NormalMap : Flip Repeat Textures/habitacion/suelo_1_bump.jpg
VertexLighting : false
UseVertexColor : false
SteepParallax : false
LightMap : Flip Repeat Textures/habitacion/suelo_1_spcu.jpg
}
AdditionalRenderState {
FaceCull Back
Wireframe Off
DepthWrite On
PolyOffset 0.0 0.0
AlphaTestFalloff 0.0
Blend Off
PointSprite Off
ColorWrite On
DepthTest On
}
}