RFC: a simple plane

[java]package com.jme3.scene.shape;



import java.nio.Buffer;



import com.jme3.math.Vector2f;

import com.jme3.math.Vector3f;

import com.jme3.scene.Mesh;

import com.jme3.scene.VertexBuffer.Type;

import com.jme3.scene.shape.Quad;

import com.jme3.util.BufferUtils;



/****************************************************************************

  • JM3 Plane – a rectangular 3d-mesh
  • @author .rhavin grobert
  • @version 0.4.0 /

    public class Plane extends Mesh

    {

    /
    * Planes vertices, specified counter-clockwise /

    protected Vector3f[] vertices = new Vector3f[4];

    /
    * Planes texture coordinates /

    protected Vector2f[] texCoord = new Vector2f[4];

    /
    * Indices of vertices, specified counter-clockwise /

    protected int[] indices = {2,0,1, 3,0,2};



    /
    ********************************************************************
  • Constructor: create a plane at given coordinates. You may specify
  • 3 coordinates for a plane or 4 to get two adjacent triangles.
  • @param p The counter-clockwise corner-points. /

    public Plane(Vector3f[] p) throws IllegalArgumentException

    {

    super();

    if (p.length == 4)

    fromPoints(p[0], p[1], p[2], p[3]);

    else if (p.length == 3)

    fromPoints(p[0], p[1], p[2]);

    else

    throw new IllegalArgumentException

    ("Plane constructor must have 3 or 4 corners as argument.");

    _commonInit();

    }



    /
    ********************************************************************
  • Constructor: create a plane at given coordinates.
  • @param p0 The 1st corner point.
  • @param p1 The counter-clockwise 2nd corner-point.
  • @param p2 The counter-clockwise 3rd corner-point. /

    public Plane(Vector3f p0, Vector3f p1, Vector3f p2)

    {

    super();

    fromPoints(p0, p1, p2);

    _commonInit();

    }



    /
    ********************************************************************
  • Constructor: create two adjacent triangles at given coordinates.
  • @param p0 The 1st corner point.
  • @param p1 The counter-clockwise 2nd corner-point.
  • @param p2 The counter-clockwise 3rd corner-point.
  • @param p3 The counter-clockwise 4th corner-point. /

    public Plane(Vector3f p0, Vector3f p1, Vector3f p2, Vector3f p3)

    {

    super();

    fromPoints(p0, p1, p2, p3);

    _commonInit();

    }



    /
    ********************************************************************
  • Constructor: create a plane from given Quad.
  • @param quad The Quad to create from. /

    public Plane(Quad quad)

    {

    super();

    if (quad == null)

    {

    _commonCopy();

    return;

    }

    Buffer b = quad.getBuffer(Type.Position).getData();

    if (b.hasArray())

    {

    Vector3f[] TempV = (Vector3f[]) b.array();

    vertices = TempV.clone();

    }

    b = quad.getBuffer(Type.Index).getData();

    if (b.hasArray())

    {

    int[] TempI = (int[]) b.array();

    indices = TempI.clone();

    }

    b = quad.getBuffer(Type.TexCoord).getData();

    if (b.hasArray())

    {

    Vector2f[] TempT = (Vector2f[]) b.array();

    texCoord = TempT.clone();

    }

    _commonCopy();

    }



    /
    ********************************************************************
  • Copy-constructor: create a plane from another one.
  • @param quad The Plane to create from. /

    public Plane(Plane p)

    {

    super();

    if (p != null)

    {

    vertices = p.vertices.clone();

    indices = p.indices.clone();

    texCoord = p.texCoord.clone();

    }

    _commonCopy();

    }



    /
    ********************************************************************
  • Common constructor implementation. /

    private void _commonInit()

    {

    setTextureCoordinatesToDefault();

    setBuffer(Type.Index, 1, BufferUtils.createIntBuffer(indices));

    }



    /
    ********************************************************************
  • Common copy set-up implementation. /

    private void _commonCopy()

    {

    setBuffer(Type.Index, 1, BufferUtils.createIntBuffer(indices));

    setBuffer(Type.Position, 3,

    BufferUtils.createFloatBuffer(vertices));

    setBuffer(Type.TexCoord, 2,

    BufferUtils.createFloatBuffer(texCoord));

    }



    /
    ********************************************************************
  • Set vertices to form a plane at given coordinates.
  • @param p0 The 1st corner point.
  • @param p1 The counter-clockwise 2nd corner-point.
  • @param p2 The counter-clockwise 3rd corner-point. /

    public void fromPoints(Vector3f p0, Vector3f p1, Vector3f p2)

    {

    fromPoints(p0, p1, p2, new Vector3f

    (

    p0.x + p2.x - p1.x,

    p0.y + p2.y - p1.y,

    p0.z + p2.z - p1.z

    )

    );

    }



    /
    ********************************************************************
  • Set vertices to form two adjacent triangles at given coordinates.
  • @param p0 The 1st corner point.
  • @param p1 The counter-clockwise 2nd corner-point.
  • @param p2 The counter-clockwise 3rd corner-point.
  • @param p3 The counter-clockwise 4th corner-point. /

    public void fromPoints(Vector3f p0, Vector3f p1, Vector3f p2,

    Vector3f p3)

    {

    vertices[0] = p0.clone();

    vertices[1] = p1.clone();

    vertices[2] = p2.clone();

    vertices[3] = p3.clone();

    setBuffer(Type.Position, 3,

    BufferUtils.createFloatBuffer(vertices));

    }



    /
    ********************************************************************
  • Set the texture-coordinates to specified values /

    public void setTextureCoordinates(Vector2f[] texcoord)

    {

    texCoord[0] = texcoord[0].clone();

    texCoord[1] = texcoord[1].clone();

    texCoord[2] = texcoord[2].clone();

    texCoord[3] = texcoord[3].clone();

    }



    /
    ********************************************************************
  • Set the texture-coordinates to default values */

    public void setTextureCoordinatesToDefault()

    {

    texCoord[0] = new Vector2f(0,0);

    texCoord[1] = new Vector2f(1,0);

    texCoord[2] = new Vector2f(1,1);

    texCoord[3] = new Vector2f(0,1);

    setBuffer(Type.TexCoord, 2,

    BufferUtils.createFloatBuffer(texCoord));

    }

    }



    [/java]

Mhhh thanks but… what’s the point? it’s a Quad right?

[poke]Not quite, its something useful;-)[/poke]



When you want a plane, you want to specify where it is. You want to specify coordinates, not lenght and height. And when you want it as part of a blender-mesh, for example, you may want it bended. You cant do that with a Quad. I simply wrote it because the Quad was not what i need. Of course, one could have the same functionality by extending quad, but that would introduce unnecessary operations, and i want it fast to the limit.

Well seems useful to you indeed, but what would be its use from the engine point of view.


rhavin said:
[poke]Not quite, its something useful;-)[/poke]
When you want a plane, you want to specify where it is. You want to specify coordinates, not lenght and height.

That's not only length and height that's, length, height, orientation and position.
But, ok why not, those are 2 different ways to define a quad, but in any case you can sort out things with little math.
Compute height and width from coordinates for example, etc..
I reckon it's a bit more tedious, but your quad seems to only be useful in very particular cases.

rhavin said:
[poke]Not quite, its something useful;-)[/poke]
And when you want it as part of a blender-mesh, for example, you may want it bended.

Ok, but you'll never build a complete mesh out of single skewed quads. Meshes are built from a single VertexBuffer

For what purpose exactly do you use it in your project? maybe this could light my bulb :p

i dynamically create 4-dimensional mazes with a 3-dimensional on-screen projection, but you may apply this to any 3d-maze. i needed a fast way to create walls from given corner-points. Doing that with a Quad was just to much operational overhead, especially annoying rotational brainfuck, so i extended my own class from Mesh.



And as I saw that it was good, i shared it.

Might make for a good snippet then :slight_smile:

Actually it would be kinda good to have a additional constructor for a quad that works like this.

EmpirePhoenix said:
Actually it would be kinda good to have a additional constructor for a quad that works like this.


You mean, like this (see above) …?