Quad alignment?

For Quad being a common element to do sprites and billboards, I am interested, is there any recommended way of specifying Quad’s alignment? For example, I want it to rotate aroung its centre, not the top-left corner. I know that I could create my own mesh with my own vertex buffer, but is there a way to acheive that for the buil-in Quad?

nope, the only solution to using built-in quad (aside from modifying the buffers after creating one) would be to attach to it a node and move the geometry with the quad so that it is centered. Otherwise you can use my “NewQuad” class, which allows you to center a quad at the origin (or anywhere you want). (Some of the comments are still related to the original Quad class which I derived this from)

[java]package com.mmm.entity.shape;

import com.jme3.math.Vector2f;
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer.Type;

/**

  • Quad represents a rectangular plane in space defined by 4

  • vertices. The quad’s lower-left side is contained either at (0, 0, 0), or

  • contained at an origin while the upper-right side is located at the

  • width/height coordinates (width, height, 0).

  • @author Kirill Vainer
    */
    public class NewQuad extends Mesh {

    private float width;
    private float height;
    private Vector2f origin;

    /**

    • Serialization only. Do not use.
      */
      public NewQuad() {
      }

    /**

    • Create a quad with the given width and height. The quad is always created
    • in the XY plane.
    • @param width The X extent or width
    • @param height The Y extent or width
      */
      public NewQuad(float width, float height) {
      updateGeometry(Vector2f.ZERO, width, height);
      }

    /**

    • Create a quad with the given width and height. The quad is always created
    • in the XY plane.
    • @param width The X extent or width
    • @param height The Y extent or width
    • @param flipCoords If true, the texture coordinates will be flipped along
    • the Y axis.
      */
      public NewQuad(float width, float height, boolean flipCoords) {
      updateGeometry(Vector2f.ZERO, width, height, flipCoords);
      }

    /**

    • Create a quad with the given width and height. The quad is always created
    • in the XY plane.
    • @param origin The origin of the quad
    • @param width The X extent or width
    • @param height The Y extent or width
      */
      public NewQuad(Vector2f origin, float width, float height) {
      updateGeometry(origin, width, height);
      }

    /**

    • Create a quad with the given width and height. The quad is always created
    • in the XY plane.
    • @param origin The origin of the quad
    • @param width The X extent or width
    • @param height The Y extent or width
    • @param flipCoords If true, the texture coordinates will be flipped along
    • the Y axis.
      */
      public NewQuad(Vector2f origin, float width, float height, boolean flipCoords) {
      updateGeometry(origin, width, height, flipCoords);
      }

    public float getHeight() {
    return height;
    }

    public float getWidth() {
    return width;
    }

    public Vector2f getOrigin() {
    return origin;
    }

    private void updateGeometry(Vector2f origin, float width, float height) {
    updateGeometry(origin, width, height, false);
    }

    private void updateGeometry(Vector2f origin, float width, float height, boolean flipCoords) {
    this.origin = origin;
    this.width = width;
    this.height = height;

     setBuffer(Type.Position, 3, new float[]{origin.x, origin.y, 0,
                 origin.x + width, origin.y, 0,
                 origin.x + width, origin.y + height, 0,
                 origin.x, origin.y + height, 0});
    
    
     if (flipCoords) {
         setBuffer(Type.TexCoord, 2, new float[]{0, 1,
                     1, 1,
                     1, 0,
                     0, 0});
     } else {
         setBuffer(Type.TexCoord, 2, new float[]{0, 0,
                     1, 0,
                     1, 1,
                     0, 1});
     }
     setBuffer(Type.Normal, 3, new float[]{0, 0, 1,
                 0, 0, 1,
                 0, 0, 1,
                 0, 0, 1});
     
     if (height < 0) {
         setBuffer(Type.Index, 3, new short[]{0, 2, 1,
                     0, 3, 2});
     } else {
         setBuffer(Type.Index, 3, new short[]{0, 1, 2,
                     0, 2, 3});
     }
    
     updateBound();
    

    }
    }[/java]

[java]
// So now if you want to center a quad mesh
Vector3f center = new Vector3f (0, 0, 0);
float xHalfExtent = 2.5f;
float yHalfExtent = 2.5f;
NewQuad quad = new NewQuad (center.subtract (xHalfExtent, yHalfExtent, 0), xHalfExtent * 2, yHalfExtent * 2);[/java]

Nope isn’t exactly accurate.

Geometry.center(); will re-position the quad verts to be center focused.

@t0neg0d said: Nope isn't exactly accurate.

Geometry.center(); will re-position the quad verts to be center focused.

Just to be clear Geometry.center() does not change the mesh at all. It’s Spatial.center() and it simply sets the local translation of the spatial so that the bounding shape is centered with respect to the parent’s local space origin.

ie: if your Quad was 200x200 then it will setLocalTranslation(-100, -100, 0)

1 Like

Thanks everyone for posting! I had implemented a solution similar to what @wezrule proposes, although not so neat. I think I will use the NewQuad class then! :smiley: