[primitive mesh] ConvexPrism (ex. triangular prism)

Hi everybody,



I have made a primitive mesh class for convex prisms wich are very useful in procedural generation of cities like mine :slight_smile:







Uploaded with
ImageShack.us’/>



The class can easily be optimized because I use ArrayList and then tables, but the 15 000 buildings of the picture are generated in no time so I leave it like this for now.



The constructor needs only an ArrayList of Vector2f wich store a linear counter-clockwise ring of 2D coordinates, with the last isEqual to the first. It also needs a positive height (if someone need to set negative mesh then tell me, I can integarte it). The pivot and center of the mesh is set at the first linear ring point and 0-y height.



The top and bottom faces are triangulated with a triangle fan shape. I don’t know if the texture coordinate are oriented the good way. If it’s not, I could modify it (I don’t know very well the UV standards). I also don’t know how to make the texture unique on the multiple triangles of the face. I could set textCoord of each corner to a complicated value but it seems hard to do. Is there any simple solution?



Does anyone can send me a source code for a triangulation of concave polygons (Monotone or by ears)? I can integrate it to make the same class accepting concave rings (and holes, if the triangulator supports it).



I hope that it will help.



[java]import java.util.ArrayList;



import com.jme3.math.Vector2f;

import com.jme3.math.Vector3f;

import com.jme3.scene.Mesh;

import com.jme3.scene.VertexBuffer.Type;



/**

  • Convex Prism.

    *
  • Wiki : "In geometry, a prism is a polyhedron with an n-sided polygonal base, a translated copy
  • (not in the same plane as the first), and n other faces (necessarily all parallelograms) joining
  • corresponding sides of the two bases."

    *
  • @author Benoît Dumas
  • @version $Id$

    */

    public class ConvexPrism extends Mesh {

    private ArrayList<Vector2f> polygonalBase;

    private float height;



    /**
  • Constructs a new convex prism.

    *
  • @param polygonalBase
  • This is a linear rings of points, with the first is equal to the last.
  • The first point of the list is the pivot.
  • @param height
  • This is the height of the prism. Bottom base is set at 0-y coordinate.

    /

    public ConvexPrism(ArrayList<Vector2f> polygonalBase, float height) {

    this.polygonalBase = polygonalBase;

    this.height = height;

    updateGeometry();

    }





    private void updateGeometry() {

    ArrayList<Vector3f> verticesArray = new ArrayList<Vector3f>();

    ArrayList<Vector2f> textCoordArray = new ArrayList<Vector2f>();

    ArrayList<Vector3f> normalsArray = new ArrayList<Vector3f>();

    ArrayList<Short> indicesArray = new ArrayList<Short>();



    // faces

    int numberOfFaces = polygonalBase.size()-1; // the last vertex is the same than the first

    for (int i = 0; i < numberOfFaces; i++) {

    // For each face

    // add 4 vertices

    int topLeftCorner = verticesArray.size();

    verticesArray.add(new Vector3f(polygonalBase.get(i).x, height, polygonalBase.get(i).y)); // Top left corner



    int topRightCorner = verticesArray.size();

    verticesArray.add(new Vector3f(polygonalBase.get(i+1).x, height, polygonalBase.get(i+1).y)); // Top right corner



    int bottomRightCorner = verticesArray.size();

    verticesArray.add(new Vector3f(polygonalBase.get(i+1).x, 0, polygonalBase.get(i+1).y)); // Bottom right corner



    int bottomLeftCorner = verticesArray.size();

    verticesArray.add(new Vector3f(polygonalBase.get(i).x, 0, polygonalBase.get(i).y)); // bottom left corner



    // add 6 indices

    indicesArray.add((short) topLeftCorner);

    indicesArray.add((short) topRightCorner);

    indicesArray.add((short) bottomLeftCorner);



    indicesArray.add((short) bottomLeftCorner);

    indicesArray.add((short) topRightCorner);

    indicesArray.add((short) bottomRightCorner);



    // add 4 normals

    float faceNormal = (float) (polygonalBase.get(i+1).subtract(polygonalBase.get(i)).getAngle()
    -1 - Math.PI/2);

    float cosNormal = (float)Math.cos(faceNormal);

    float sinNormal = (float)Math.sin(faceNormal);

    normalsArray.add(new Vector3f(cosNormal, 0, sinNormal));

    normalsArray.add(new Vector3f(cosNormal, 0, sinNormal));

    normalsArray.add(new Vector3f(cosNormal, 0, sinNormal));

    normalsArray.add(new Vector3f(cosNormal, 0, sinNormal));



    // add 4 textCoord

    textCoordArray.add(new Vector2f(1, 1));

    textCoordArray.add(new Vector2f(0, 1));

    textCoordArray.add(new Vector2f(0, 0));

    textCoordArray.add(new Vector2f(1, 0));



    }



    // top face

    int numberOfTriangles = polygonalBase.size()-2;

    for (int i = 0; i < numberOfTriangles; i++) {

    // for each triangle

    // add 3 vertices

    int firstCorner = verticesArray.size();

    verticesArray.add(new Vector3f(polygonalBase.get(0).x, height, polygonalBase.get(0).y)); // first Corner is always the center of fan



    int secondCorner = verticesArray.size();

    verticesArray.add(new Vector3f(polygonalBase.get(i+1).x, height, polygonalBase.get(i+1).y)); // second corner



    int thirdCorner = verticesArray.size();

    verticesArray.add(new Vector3f(polygonalBase.get(i+2).x, height, polygonalBase.get(i+2).y)); // Bottom right corner



    // add 3 indices

    indicesArray.add((short) firstCorner);

    indicesArray.add((short) thirdCorner);

    indicesArray.add((short) secondCorner);



    // add 3 texture coordinates

    textCoordArray.add(new Vector2f(1, 1));

    textCoordArray.add(new Vector2f(0, 1));

    textCoordArray.add(new Vector2f(0, 0));



    // add 3 normals

    normalsArray.add(new Vector3f(0, 1, 0));

    normalsArray.add(new Vector3f(0, 1, 0));

    normalsArray.add(new Vector3f(0, 1, 0));

    }



    // bottom face

    for (int i = 0; i < numberOfTriangles; i++) {

    // for each triangle

    // add 3 vertices

    int firstCorner = verticesArray.size();

    verticesArray.add(new Vector3f(polygonalBase.get(0).x, 0, polygonalBase.get(0).y)); // first Corner is always the center of fan



    int secondCorner = verticesArray.size();

    verticesArray.add(new Vector3f(polygonalBase.get(i+1).x, 0, polygonalBase.get(i+1).y)); // second corner



    int thirdCorner = verticesArray.size();

    verticesArray.add(new Vector3f(polygonalBase.get(i+2).x, 0, polygonalBase.get(i+2).y)); // Bottom right corner



    // add 3 indices

    indicesArray.add((short) firstCorner);

    indicesArray.add((short) secondCorner);

    indicesArray.add((short) thirdCorner);



    // add 3 texture coordinates

    textCoordArray.add(new Vector2f(1, 1));

    textCoordArray.add(new Vector2f(0, 1));

    textCoordArray.add(new Vector2f(0, 0));



    // add 3 normals

    normalsArray.add(new Vector3f(0, -1, 0));

    normalsArray.add(new Vector3f(0, -1, 0));

    normalsArray.add(new Vector3f(0, -1, 0));

    }



    float vertices[] = new float[verticesArray.size()*3];

    float textCoord[] = new float[textCoordArray.size()*2];

    float normals[] = new float[normalsArray.size()*3];

    short indices[] = new short[indicesArray.size()];

    int j = 0;

    for (int i = 0; i < verticesArray.size()*3; i+:3) {

    vertices = verticesArray.get(j).x;

    vertices[i+1] = verticesArray.get(j).y;

    vertices[i+2] = verticesArray.get(j).z;

    j++;

    }



    j = 0;

    for (int i = 0; i < textCoordArray.size()*2; i+=2) {

    textCoord = textCoordArray.get(j).x;

    textCoord[i+1] = textCoordArray.get(j).y;

    j++;

    }



    j = 0;

    for (int i = 0; i < normalsArray.size()*3; i+:3) {

    normals = normalsArray.get(j).x;

    normals[i+1] = normalsArray.get(j).y;

    normals[i+2] = normalsArray.get(j).z;

    j++;

    }



    for (int i = 0; i < indicesArray.size(); i++) {

    indices = indicesArray.get(i);

    }



    setBuffer(Type.Position, 3, vertices);

    setBuffer(Type.TexCoord, 2, textCoord);

    setBuffer(Type.Normal, 3, normals);

    setBuffer(Type.Index, 3, indices);



    updateBound();

    }

    }[/java]
3 Likes