com.jme3.scene.shape.RectangleMesh Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jme3-core Show documentation
Show all versions of jme3-core Show documentation
jMonkeyEngine is a 3-D game engine for adventurous Java developers
/*
* Copyright (c) 2021 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.scene.shape;
import java.io.IOException;
import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.math.Rectangle;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.scene.Mesh;
import com.jme3.scene.VertexBuffer.Type;
import com.jme3.util.BufferUtils;
import com.jme3.util.clone.Cloner;
/**
* A static, indexed, Triangle-mode mesh that renders a rectangle or
* parallelogram, with customizable normals and texture coordinates.
*
* It uses a {@link com.jme3.math.Rectangle} to locate its vertices, which
* are named as follows:
*
*
* C +----+ D
* |\ |
* | \ |
* | \ |
* | \|
* A +----+ B
*
*
* In the vertex buffers, the order of the vertices is A, B, D, then C.
*
*
The default texture coordinates have:
* - U=0 at vertices A and C
* - U=1 at vertices B and D
* - V=0 at vertices A and B
* - V=1 at vertices C and D
*
* @author Francivan Bezerra
*/
public class RectangleMesh extends Mesh {
/**
* Used to locate the vertices and calculate a default normal.
*/
private Rectangle rectangle;
/**
* Texture coordinates in A-B-D-C order.
*/
private Vector2f[] texCoords;
/**
* Normal direction for all 4 vertices.
*/
private Vector3f normal;
/**
* Used to indicate whether this mesh is flipped.
*/
private boolean flipped;
/**
* Instantiates a unit-square mesh in the X-Y plane, centered at (0.5, 0.5),
* with normals in the +Z direction.
*
*/
public RectangleMesh() {
this(new Rectangle(new Vector3f(), new Vector3f(1, 0, 0), new Vector3f(0, 1, 0)));
}
/**
* Instantiates a rectangle or parallelogram mesh based on the specified
* {@link com.jme3.math.Rectangle}.
*
* @param rectangle to locate the vertices and set the normals (not null,
* alias created)
*/
public RectangleMesh(Rectangle rectangle) {
this.rectangle = rectangle;
this.texCoords = new Vector2f[] {
new Vector2f(0, 0),
new Vector2f(1, 0),
new Vector2f(1, 1),
new Vector2f(0, 1)
};
flipped = false;
updateMesh();
}
/**
* Instantiates a rectangle or parallelogram mesh based on 3 specified
* vertex positions.
*
* @param a the mesh position of vertex A (not null, alias created)
* @param b the mesh position of vertex B (not null, alias created)
* @param c the mesh position of vertex C (not null, alias created)
*/
public RectangleMesh(Vector3f a, Vector3f b, Vector3f c) {
this(new Rectangle(a, b, c));
}
/**
* Provides access to the internal {@link com.jme3.math.Rectangle} on which
* the mesh is based.
*
* @return the pre-existing instance (do not modify!)
*/
public Rectangle getRectangle() {
return rectangle;
}
/**
* Sets the {@link com.jme3.math.Rectangle} and updates the mesh
* accordingly.
*
* @param rectangle the desired Rectangle (not null, alias created)
*/
public void setRectangle(Rectangle rectangle) {
this.rectangle = rectangle;
updateMesh();
}
/**
* Provides access to the internal texture-coordinate array.
*
* @return the pre-existing array of length 4 (do not modify!)
*/
public Vector2f[] getTexCoords() {
return texCoords;
}
/**
* Sets the texture coordinates and updates the mesh accordingly.
*
* @param texCoords the desired texture coordinates for each vertex (not
* null, alias created)
* @throws IllegalArgumentException if the array length isn't exactly 4
*/
public void setTexCoords(Vector2f[] texCoords) throws IllegalArgumentException {
if (texCoords.length != 4) {
throw new IllegalArgumentException(
"Texture coordinates are 4 vertices, therefore a Vector2f array of length 4 must be provided.");
}
this.texCoords = texCoords;
updateMesh();
}
/**
* Provides access to the internal normal-direction vector.
*
* @return the pre-existing vector (do not modify!)
*/
public Vector3f getNormal() {
return normal;
}
/**
* Flips this mesh by reversing its normal vector direction and
* setting the {@code flipped} variable accordingly. This variable
* will be used by the {@code updateMesh()} method to rearrange
* the index buffer.
*/
public void flip() {
normal.negateLocal();
flipped = !flipped;
updateMesh();
}
protected void updateMesh() {
Vector3f a = rectangle.getA();
Vector3f b = rectangle.getB();
Vector3f c = rectangle.getC();
Vector3f d = rectangle.calculateD();
setBuffer(Type.Position, 3, new float[] {
a.x, a.y, a.z,
b.x, b.y, b.z,
d.x, d.y, d.z,
c.x, c.y, c.z
});
setBuffer(Type.TexCoord, 2, BufferUtils.createFloatBuffer(texCoords));
if (normal == null) {
normal = rectangle.calculateNormal(null);
}
setBuffer(Type.Normal, 3, BufferUtils.createFloatBuffer(normal, normal, normal, normal));
if (flipped) {
setBuffer(Type.Index, 3, new short[]{1, 0, 3, 3, 2, 1});
} else {
setBuffer(Type.Index, 3, new short[]{3, 0, 1, 1, 2, 3});
}
updateBound();
setStatic();
}
/**
* Called internally by com.jme3.util.clone.Cloner. Do not call directly.
*/
@Override
public void cloneFields(Cloner cloner, Object original) {
super.cloneFields(cloner, original);
this.rectangle = cloner.clone(rectangle);
this.texCoords = cloner.clone(texCoords);
this.normal = cloner.clone(normal);
}
@Override
public void read(JmeImporter importer) throws IOException {
super.read(importer);
final InputCapsule capsule = importer.getCapsule(this);
rectangle = (Rectangle) capsule.readSavable("rectangle", new Rectangle(
new Vector3f(),
new Vector3f(1, 0, 0),
new Vector3f(0, 1, 0)));
texCoords = (Vector2f[]) capsule.readSavableArray("texCoords", new Vector2f[] {
new Vector2f(0, 0),
new Vector2f(1, 0),
new Vector2f(1, 1),
new Vector2f(0, 1) });
normal = (Vector3f) capsule.readSavable("normal", null);
flipped = capsule.readBoolean("flipped", false);
}
@Override
public void write(JmeExporter e) throws IOException {
super.write(e);
final OutputCapsule capsule = e.getCapsule(this);
capsule.write(rectangle, "rectangle", new Rectangle(
new Vector3f(),
new Vector3f(1, 0, 0),
new Vector3f(0, 1, 0)));
capsule.write(texCoords, "texCoords", new Vector2f[] {
new Vector2f(0, 0),
new Vector2f(1, 0),
new Vector2f(1, 1),
new Vector2f(0, 1)
});
capsule.write(normal, "normal", null);
capsule.write(flipped, "flipped", false);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy