/*
* Copyright 2012 Benjamin Glatzel <benjamin.glatzel@me.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.terasology.rendering.primitives;
import gnu.trove.list.array.TFloatArrayList;
import gnu.trove.list.array.TIntArrayList;
import org.terasology.model.shapes.BlockMeshPart;
import javax.vecmath.Vector2f;
import javax.vecmath.Vector3f;
import javax.vecmath.Vector4f;
public class Tessellator {
private TFloatArrayList _color = new TFloatArrayList();
private TFloatArrayList _vertices = new TFloatArrayList();
private TFloatArrayList _texCoord0 = new TFloatArrayList();
private TFloatArrayList _texCoord1 = new TFloatArrayList();
private TFloatArrayList _normals = new TFloatArrayList();
private TIntArrayList _indices = new TIntArrayList();
private int _indexOffset = 0;
private Vector4f _activeColor = new Vector4f();
private Vector3f _activeNormal = new Vector3f();
private Vector2f _activeTex = new Vector2f();
private Vector3f _lighting = new Vector3f();
private boolean useLighting = true;
private boolean useNormals = true;
public Tessellator() {
resetParams();
}
public void resetAll() {
_color.reset();
_vertices.reset();
_texCoord0.reset();
_texCoord1.reset();
_normals.reset();
_indices.reset();
_indexOffset = 0;
resetParams();
}
public void setUseLighting(boolean enable) {
this.useLighting = enable;
}
public void setUseNormals(boolean enable) {
this.useNormals = enable;
}
public void resetParams() {
_activeColor.set(1, 1, 1, 1);
_activeTex.set(0, 0);
_lighting.set(1, 1, 1);
_activeNormal.set(0, 1, 0);
}
public void addPoly(Vector3f[] vertices, Vector2f[] texCoords) {
if (vertices.length != texCoords.length || vertices.length < 3) {
throw new IllegalArgumentException("addPoly expected vertices.length == texCoords.length > 2");
}
for (int i = 0; i < vertices.length; ++i) {
_vertices.add(vertices[i].x);
_vertices.add(vertices[i].y);
_vertices.add(vertices[i].z);
_color.add(_activeColor.x);
_color.add(_activeColor.y);
_color.add(_activeColor.z);
_color.add(_activeColor.w);
if (useNormals) {
_normals.add(_activeNormal.x);
_normals.add(_activeNormal.y);
_normals.add(_activeNormal.z);
}
_texCoord0.add(texCoords[i].x);
_texCoord0.add(texCoords[i].y);
if (useLighting) {
_texCoord1.add(_lighting.x);
_texCoord1.add(_lighting.y);
_texCoord1.add(_lighting.z);
}
}
// Standard fan
for (int i = 0; i < vertices.length - 2; i++) {
_indices.add(_indexOffset);
_indices.add(_indexOffset + i + 1);
_indices.add(_indexOffset + i + 2);
}
_indexOffset += vertices.length;
}
public void addMeshPart(BlockMeshPart part) {
for (int i = 0; i < part.size(); ++i) {
Vector3f vertex = part.getVertex(i);
_vertices.add(vertex.x);
_vertices.add(vertex.y);
_vertices.add(vertex.z);
_color.add(_activeColor.x);
_color.add(_activeColor.y);
_color.add(_activeColor.z);
_color.add(_activeColor.w);
Vector3f normal = part.getNormal(i);
_normals.add(normal.x);
_normals.add(normal.y);
_normals.add(normal.z);
Vector2f uv = part.getTexCoord(i);
_texCoord0.add(uv.x);
_texCoord0.add(uv.y);
_texCoord1.add(_lighting.x);
_texCoord1.add(_lighting.y);
_texCoord1.add(_lighting.z);
}
for (int i = 0; i < part.indicesSize(); ++i) {
_indices.add(_indexOffset + part.getIndex(i));
}
_indexOffset += part.size();
}
public void setColor(Vector4f v) {
_activeColor.set(v);
}
public void setNormal(Vector3f v) {
_activeNormal.set(v);
}
public void setTex(Vector2f v) {
_activeTex.set(v);
}
public void setLighting(Vector3f v) {
_lighting.set(v);
}
public Mesh generateMesh() {
return Mesh.buildMesh(_vertices, _texCoord0, _texCoord1, _normals, _color, _indices);
}
}