/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package automenta.spacenet.space.geom;
import com.ardor3d.bounding.OrientedBoundingBox;
import com.ardor3d.math.Vector3;
import com.ardor3d.math.type.ReadOnlyVector3;
import com.ardor3d.scenegraph.Mesh;
import com.ardor3d.util.geom.BufferUtils;
import java.nio.FloatBuffer;
/**
* trapezoidal box
*/
public class TrapBox extends Box {
//TODO compute correct side (left, right, top, bottom) normals when flare<>1.0
public static class TrapBoxGeom extends Mesh {
private double _xExtent, _yExtent, _zExtent;
private final Vector3 _center = new Vector3(0, 0, 0);
private final double flare;
/**
* Constructs a new 1x1x1 <code>Box</code>.
*/
public TrapBoxGeom(double flare) {
super("");
this.flare = flare;
setData(Vector3.ZERO, 0.5, 0.5, 0.5);
}
/**
* @return the current center of this box.
*/
public ReadOnlyVector3 getCenter() {
return _center;
}
/**
* @return the current X extent of this box.
*/
public double getXExtent() {
return _xExtent;
}
/**
* @return the current Y extent of this box.
*/
public double getYExtent() {
return _yExtent;
}
/**
* @return the current Z extent of this box.
*/
public double getZExtent() {
return _zExtent;
}
/**
* Updates the center point and extents of this box to match an axis-aligned box defined by the two given opposite
* corners.
*
* @param pntA
* the first point
* @param pntB
* the second point.
*/
public void setData(final ReadOnlyVector3 pntA, final ReadOnlyVector3 pntB) {
_center.set(pntB).addLocal(pntA).multiplyLocal(0.5);
final double x = Math.abs(pntB.getX() - _center.getX());
final double y = Math.abs(pntB.getY() - _center.getY());
final double z = Math.abs(pntB.getZ() - _center.getZ());
setData(_center, x, y, z);
}
/**
* Updates the center point and extents of this box using the defined values.
*
* @param center
* The center of the box.
* @param xExtent
* x extent of the box
* @param yExtent
* y extent of the box
* @param zExtent
* z extent of the box
*/
public void setData(final ReadOnlyVector3 center, final double xExtent, final double yExtent, final double zExtent) {
if (center != null) {
_center.set(center);
}
_xExtent = xExtent;
_yExtent = yExtent;
_zExtent = zExtent;
setVertexData();
setNormalData();
setTextureData();
setIndexData();
}
/**
* <code>setVertexData</code> sets the vertex positions that define the box using the center point and defined
* extents.
*/
protected void setVertexData() {
if (_meshData.getVertexBuffer() == null) {
_meshData.setVertexBuffer(BufferUtils.createVector3Buffer(24));
}
final Vector3[] vert = computeVertices(); // returns 8
// Back
BufferUtils.setInBuffer(vert[0], _meshData.getVertexBuffer(), 0);
BufferUtils.setInBuffer(vert[1], _meshData.getVertexBuffer(), 1);
BufferUtils.setInBuffer(vert[2], _meshData.getVertexBuffer(), 2);
BufferUtils.setInBuffer(vert[3], _meshData.getVertexBuffer(), 3);
// Right
BufferUtils.setInBuffer(vert[1], _meshData.getVertexBuffer(), 4);
BufferUtils.setInBuffer(vert[4], _meshData.getVertexBuffer(), 5);
BufferUtils.setInBuffer(vert[6], _meshData.getVertexBuffer(), 6);
BufferUtils.setInBuffer(vert[2], _meshData.getVertexBuffer(), 7);
// Front
BufferUtils.setInBuffer(vert[4], _meshData.getVertexBuffer(), 8);
BufferUtils.setInBuffer(vert[5], _meshData.getVertexBuffer(), 9);
BufferUtils.setInBuffer(vert[7], _meshData.getVertexBuffer(), 10);
BufferUtils.setInBuffer(vert[6], _meshData.getVertexBuffer(), 11);
// Left
BufferUtils.setInBuffer(vert[5], _meshData.getVertexBuffer(), 12);
BufferUtils.setInBuffer(vert[0], _meshData.getVertexBuffer(), 13);
BufferUtils.setInBuffer(vert[3], _meshData.getVertexBuffer(), 14);
BufferUtils.setInBuffer(vert[7], _meshData.getVertexBuffer(), 15);
// Top
BufferUtils.setInBuffer(vert[2], _meshData.getVertexBuffer(), 16);
BufferUtils.setInBuffer(vert[6], _meshData.getVertexBuffer(), 17);
BufferUtils.setInBuffer(vert[7], _meshData.getVertexBuffer(), 18);
BufferUtils.setInBuffer(vert[3], _meshData.getVertexBuffer(), 19);
// Bottom
BufferUtils.setInBuffer(vert[0], _meshData.getVertexBuffer(), 20);
BufferUtils.setInBuffer(vert[5], _meshData.getVertexBuffer(), 21);
BufferUtils.setInBuffer(vert[4], _meshData.getVertexBuffer(), 22);
BufferUtils.setInBuffer(vert[1], _meshData.getVertexBuffer(), 23);
}
/**
* <code>setNormalData</code> sets the normals of each of the box's planes.
*/
private void setNormalData() {
if (_meshData.getNormalBuffer() == null) {
_meshData.setNormalBuffer(BufferUtils.createVector3Buffer(24));
// back
for (int i = 0; i < 4; i++) {
_meshData.getNormalBuffer().put(0).put(0).put(-1);
}
// right
for (int i = 0; i < 4; i++) {
_meshData.getNormalBuffer().put(1).put(0).put(0);
}
// front
for (int i = 0; i < 4; i++) {
_meshData.getNormalBuffer().put(0).put(0).put(1);
}
// left
for (int i = 0; i < 4; i++) {
_meshData.getNormalBuffer().put(-1).put(0).put(0);
}
// top
for (int i = 0; i < 4; i++) {
_meshData.getNormalBuffer().put(0).put(1).put(0);
}
// bottom
for (int i = 0; i < 4; i++) {
_meshData.getNormalBuffer().put(0).put(-1).put(0);
}
}
}
/**
* <code>setTextureData</code> sets the points that define the texture of the box. It's a one-to-one ratio, where
* each plane of the box has it's own copy of the texture. That is, the texture is repeated one time for each six
* faces.
*/
private void setTextureData() {
if (_meshData.getTextureCoords(0) == null) {
_meshData.setTextureBuffer(BufferUtils.createVector2Buffer(24), 0);
final FloatBuffer tex = _meshData.getTextureBuffer(0);
for (int i = 0; i < 6; i++) {
tex.put(1).put(0);
tex.put(0).put(0);
tex.put(0).put(1);
tex.put(1).put(1);
}
}
}
/**
* <code>setIndexData</code> sets the indices into the list of vertices, defining all triangles that constitute the
* box.
*/
private void setIndexData() {
if (_meshData.getIndexBuffer() == null) {
final int[] indices = {2, 1, 0, 3, 2, 0, 6, 5, 4, 7, 6, 4, 10, 9, 8, 11, 10, 8, 14, 13, 12, 15, 14, 12,
18, 17, 16, 19, 18, 16, 22, 21, 20, 23, 22, 20};
_meshData.setIndexBuffer(BufferUtils.createIntBuffer(indices));
}
}
/**
* @return a size 8 array of Vectors representing the 8 points of the box.
*/
public Vector3[] computeVertices() {
final Vector3 rVal[] = new Vector3[8];
rVal[0] = _center.add(-_xExtent, -_yExtent, -_zExtent, null);
rVal[1] = _center.add(_xExtent, -_yExtent, -_zExtent, null);
rVal[2] = _center.add(_xExtent, _yExtent, -_zExtent, null);
rVal[3] = _center.add(-_xExtent, _yExtent, -_zExtent, null);
rVal[4] = _center.add(_xExtent*flare, -_yExtent*flare, _zExtent, null);
rVal[5] = _center.add(-_xExtent*flare, -_yExtent*flare, _zExtent, null);
rVal[6] = _center.add(_xExtent*flare, _yExtent*flare, _zExtent, null);
rVal[7] = _center.add(-_xExtent*flare, _yExtent*flare, _zExtent, null);
return rVal;
}
}
public TrapBox(double flare) {
super(BoxShape.Empty);
TrapBoxGeom trapBox = add(new TrapBoxGeom(flare));
trapBox.setModelBound(new OrientedBoundingBox());
}
}