package com.srbenoit.render;
import com.srbenoit.geom.Point3;
import com.srbenoit.geom.Vector3;
/**
* A vertex in world coordinates that a scene is composed of.
*/
public class WorldVertex extends Point3 {
/** the index of this vertex in the scene where it is contained */
private int indexInScene;
/** the number of faces this vertex is part of */
private int numFaces;
/** the list of faces that contain the vertex */
private WorldFace[] faces;
/** the index of this vertex in each face in the faces array */
private int[] indexInFaces;
/**
* Constructs a new WorldVertex
.
*/
public WorldVertex() {
super();
this.numFaces = 0;
this.faces = new WorldFace[5];
this.indexInFaces = new int[5];
this.indexInScene = -1;
}
/**
* Constructs a new WorldVertex
.
*
* @param xCoord the X coordinate
* @param yCoord the Y coordinate
* @param zCoord the Z coordinate
*/
public WorldVertex(final double xCoord, final double yCoord, final double zCoord) {
super(xCoord, yCoord, zCoord);
this.numFaces = 0;
this.faces = new WorldFace[5];
this.indexInFaces = new int[5];
this.indexInScene = -1;
}
/**
* Sets the index of this vertex in the scene.
*
* @param index the index
*/
public void setIndexInScene(final int index) {
this.indexInScene = index;
}
/**
* Gets the index of this vertex in the scene.
*
* @return the index
*/
public int getIndexInScene() {
return this.indexInScene;
}
/**
* Adds a face to the list of faces this vertex is part of.
*
* @param face the face
* @param index the index of this vertex in the face
*/
public void addFace(final WorldFace face, final int index) {
WorldFace[] newArray;
int[] newIndices;
if (this.numFaces == this.faces.length) {
newArray = new WorldFace[this.numFaces + 5];
System.arraycopy(this.faces, 0, newArray, 0, this.numFaces);
this.faces = newArray;
newIndices = new int[this.numFaces + 5];
System.arraycopy(this.indexInFaces, 0, newIndices, 0, this.numFaces);
this.indexInFaces = newIndices;
}
this.faces[this.numFaces] = face;
this.indexInFaces[this.numFaces] = index;
this.numFaces++;
}
/**
* Gets the number of faces this vertex takes part in.
*
* @return the number of faces
*/
public int getNumFaces() {
return this.numFaces;
}
/**
* Gets a face this vertex takes part in.
*
* @param index the index of the face
* @return the face
*/
public WorldFace getFace(final int index) {
return this.faces[index];
}
/**
* Gets the index of this vertex in one of the faces that it is part of.
*
* @param index the index of the face
* @return the index of this vertex in the specified face
*/
public int getIndexInFace(final int index) {
return this.indexInFaces[index];
}
/**
* Computes the average of the normal vectors of all attached faces and normalizes the result
* to obtain the normal vector at the vertex.
*
* @param normal the vector in which to place the computed normal
*/
public void buildNormal(final Vector3 normal) {
double x;
double y;
double z;
if (this.numFaces == 0) {
normal.setVec(0, 0, 1);
} else {
x = 0;
y = 0;
z = 0;
for (int i = 0; i < this.numFaces; i++) {
x += this.faces[i].getVecX();
y += this.faces[i].getVecY();
z += this.faces[i].getVecZ();
}
normal.setVec(x, y, z);
normal.normalize(); // This method already deals with the 0-length case
}
}
}