use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.
the class TangentBinormalGenerator method genTangentLines.
private static Mesh genTangentLines(Mesh mesh, float scale) {
FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
FloatBuffer normalBuffer = (FloatBuffer) mesh.getBuffer(Type.Normal).getData();
FloatBuffer tangentBuffer = (FloatBuffer) mesh.getBuffer(Type.Tangent).getData();
FloatBuffer binormalBuffer = null;
if (mesh.getBuffer(Type.Binormal) != null) {
binormalBuffer = (FloatBuffer) mesh.getBuffer(Type.Binormal).getData();
}
ColorRGBA originColor = ColorRGBA.White;
ColorRGBA tangentColor = ColorRGBA.Red;
ColorRGBA binormalColor = ColorRGBA.Green;
ColorRGBA normalColor = ColorRGBA.Blue;
Mesh lineMesh = new Mesh();
lineMesh.setMode(Mesh.Mode.Lines);
Vector3f origin = new Vector3f();
Vector3f point = new Vector3f();
Vector3f tangent = new Vector3f();
Vector3f normal = new Vector3f();
IntBuffer lineIndex = BufferUtils.createIntBuffer(vertexBuffer.limit() / 3 * 6);
FloatBuffer lineVertex = BufferUtils.createFloatBuffer(vertexBuffer.limit() * 4);
FloatBuffer lineColor = BufferUtils.createFloatBuffer(vertexBuffer.limit() / 3 * 4 * 4);
boolean hasParity = mesh.getBuffer(Type.Tangent).getNumComponents() == 4;
float tangentW = 1;
for (int i = 0; i < vertexBuffer.limit() / 3; i++) {
populateFromBuffer(origin, vertexBuffer, i);
populateFromBuffer(normal, normalBuffer, i);
if (hasParity) {
tangent.x = tangentBuffer.get(i * 4);
tangent.y = tangentBuffer.get(i * 4 + 1);
tangent.z = tangentBuffer.get(i * 4 + 2);
tangentW = tangentBuffer.get(i * 4 + 3);
} else {
populateFromBuffer(tangent, tangentBuffer, i);
}
int index = i * 4;
int id = i * 6;
lineIndex.put(id, index);
lineIndex.put(id + 1, index + 1);
lineIndex.put(id + 2, index);
lineIndex.put(id + 3, index + 2);
lineIndex.put(id + 4, index);
lineIndex.put(id + 5, index + 3);
setInBuffer(origin, lineVertex, index);
setInBuffer(originColor, lineColor, index);
point.set(tangent);
point.multLocal(scale);
point.addLocal(origin);
setInBuffer(point, lineVertex, index + 1);
setInBuffer(tangentColor, lineColor, index + 1);
if (binormalBuffer == null) {
normal.cross(tangent, point);
point.multLocal(-tangentW);
point.normalizeLocal();
} else {
populateFromBuffer(point, binormalBuffer, i);
}
point.multLocal(scale);
point.addLocal(origin);
setInBuffer(point, lineVertex, index + 2);
setInBuffer(binormalColor, lineColor, index + 2);
point.set(normal);
point.multLocal(scale);
point.addLocal(origin);
setInBuffer(point, lineVertex, index + 3);
setInBuffer(normalColor, lineColor, index + 3);
}
lineMesh.setBuffer(Type.Index, 1, lineIndex);
lineMesh.setBuffer(Type.Position, 3, lineVertex);
lineMesh.setBuffer(Type.Color, 4, lineColor);
lineMesh.setStatic();
//lineMesh.setInterleaved();
return lineMesh;
}
use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.
the class TangentBinormalGenerator method splitVertices.
//Don't remove splitmirorred boolean,It's not used right now, but i intend to
//make this method also split vertice with rotated tangent space and I'll
//add another splitRotated boolean
private static List<VertexData> splitVertices(Mesh mesh, List<VertexData> vertexData, boolean splitMirorred) {
int nbVertices = mesh.getBuffer(Type.Position).getNumElements();
List<VertexData> newVertices = new ArrayList<VertexData>();
Map<Integer, Integer> indiceMap = new HashMap<Integer, Integer>();
FloatBuffer normalBuffer = mesh.getFloatBuffer(Type.Normal);
for (int i = 0; i < vertexData.size(); i++) {
ArrayList<TriangleData> triangles = vertexData.get(i).triangles;
Vector3f givenNormal = new Vector3f();
populateFromBuffer(givenNormal, normalBuffer, i);
ArrayList<TriangleData> trianglesUp = new ArrayList<TriangleData>();
ArrayList<TriangleData> trianglesDown = new ArrayList<TriangleData>();
for (int j = 0; j < triangles.size(); j++) {
TriangleData triangleData = triangles.get(j);
if (parity(givenNormal, triangleData.normal) > 0) {
trianglesUp.add(triangleData);
} else {
trianglesDown.add(triangleData);
}
}
//if the vertex has triangles with opposite parity it has to be split
if (!trianglesUp.isEmpty() && !trianglesDown.isEmpty()) {
log.log(Level.FINE, "Splitting vertex {0}", i);
//assigning triangle with the same parity to the original vertex
vertexData.get(i).triangles.clear();
vertexData.get(i).triangles.addAll(trianglesUp);
//creating a new vertex
VertexData newVert = new VertexData();
//assigning triangles with opposite parity to it
newVert.triangles.addAll(trianglesDown);
newVertices.add(newVert);
//keep vertex index to fix the index buffers later
indiceMap.put(nbVertices, i);
for (TriangleData tri : newVert.triangles) {
for (int j = 0; j < tri.index.length; j++) {
if (tri.index[j] == i) {
tri.index[j] = nbVertices;
}
}
}
nbVertices++;
}
}
if (!newVertices.isEmpty()) {
//we have new vertices, we need to update the mesh's buffers.
for (Type type : VertexBuffer.Type.values()) {
//skip tangent buffer as we're gonna overwrite it later
if (type == Type.Tangent || type == Type.BindPoseTangent)
continue;
VertexBuffer vb = mesh.getBuffer(type);
//They'll be initialized when Hardware Skinning is engaged
if (vb == null || vb.getNumComponents() == 0)
continue;
Buffer buffer = vb.getData();
//IndexBuffer has special treatement, only swapping the vertex indices is needed
if (type == Type.Index) {
boolean isShortBuffer = vb.getFormat() == VertexBuffer.Format.UnsignedShort;
for (VertexData vertex : newVertices) {
for (TriangleData tri : vertex.triangles) {
for (int i = 0; i < tri.index.length; i++) {
if (isShortBuffer) {
((ShortBuffer) buffer).put(tri.triangleOffset + i, (short) tri.index[i]);
} else {
((IntBuffer) buffer).put(tri.triangleOffset + i, tri.index[i]);
}
}
}
}
vb.setUpdateNeeded();
} else {
//copy the buffer in a bigger one and append nex vertices to the end
Buffer newVerts = VertexBuffer.createBuffer(vb.getFormat(), vb.getNumComponents(), nbVertices);
if (buffer != null) {
buffer.rewind();
bulkPut(vb.getFormat(), newVerts, buffer);
int index = vertexData.size();
newVerts.position(vertexData.size() * vb.getNumComponents());
for (int j = 0; j < newVertices.size(); j++) {
int oldInd = indiceMap.get(index);
for (int i = 0; i < vb.getNumComponents(); i++) {
putValue(vb.getFormat(), newVerts, buffer, oldInd * vb.getNumComponents() + i);
}
index++;
}
vb.updateData(newVerts);
//destroy previous buffer as it's no longer needed
destroyDirectBuffer(buffer);
}
}
}
vertexData.addAll(newVertices);
mesh.updateCounts();
}
return vertexData;
}
use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.
the class TangentBinormalGenerator method linkVertices.
private static ArrayList<VertexInfo> linkVertices(Mesh mesh, boolean splitMirrored) {
ArrayList<VertexInfo> vertexMap = new ArrayList<VertexInfo>();
FloatBuffer vertexBuffer = mesh.getFloatBuffer(Type.Position);
FloatBuffer normalBuffer = mesh.getFloatBuffer(Type.Normal);
FloatBuffer texcoordBuffer = mesh.getFloatBuffer(Type.TexCoord);
Vector3f position = new Vector3f();
Vector3f normal = new Vector3f();
Vector2f texCoord = new Vector2f();
final int size = vertexBuffer.limit() / 3;
for (int i = 0; i < size; i++) {
populateFromBuffer(position, vertexBuffer, i);
populateFromBuffer(normal, normalBuffer, i);
populateFromBuffer(texCoord, texcoordBuffer, i);
boolean found = false;
//separate vertice should have separate tangent space
if (!splitMirrored) {
for (int j = 0; j < vertexMap.size(); j++) {
VertexInfo vertexInfo = vertexMap.get(j);
if (approxEqual(vertexInfo.position, position) && approxEqual(vertexInfo.normal, normal) && approxEqual(vertexInfo.texCoord, texCoord)) {
vertexInfo.indices.add(i);
found = true;
break;
}
}
}
if (!found) {
VertexInfo vertexInfo = new VertexInfo(position.clone(), normal.clone(), texCoord.clone());
vertexInfo.indices.add(i);
vertexMap.add(vertexInfo);
}
}
return vertexMap;
}
use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.
the class TangentBinormalGenerator method processTriangleFan.
private static List<VertexData> processTriangleFan(Mesh mesh, int[] index, Vector3f[] v, Vector2f[] t) {
IndexBuffer indexBuffer = mesh.getIndexBuffer();
FloatBuffer vertexBuffer = (FloatBuffer) mesh.getBuffer(Type.Position).getData();
FloatBuffer textureBuffer = (FloatBuffer) mesh.getBuffer(Type.TexCoord).getData();
List<VertexData> vertices = initVertexData(vertexBuffer.limit() / 3);
index[0] = indexBuffer.get(0);
index[1] = indexBuffer.get(1);
populateFromBuffer(v[0], vertexBuffer, index[0]);
populateFromBuffer(v[1], vertexBuffer, index[1]);
populateFromBuffer(t[0], textureBuffer, index[0]);
populateFromBuffer(t[1], textureBuffer, index[1]);
for (int i = 2; i < vertexBuffer.limit() / 3; i++) {
index[2] = indexBuffer.get(i);
populateFromBuffer(v[2], vertexBuffer, index[2]);
populateFromBuffer(t[2], textureBuffer, index[2]);
TriangleData triData = processTriangle(index, v, t);
vertices.get(index[0]).triangles.add(triData);
vertices.get(index[1]).triangles.add(triData);
vertices.get(index[2]).triangles.add(triData);
Vector3f vTemp = v[1];
v[1] = v[2];
v[2] = vTemp;
Vector2f tTemp = t[1];
t[1] = t[2];
t[2] = tTemp;
index[1] = index[2];
}
return vertices;
}
use of com.jme3.scene.VertexBuffer in project jmonkeyengine by jMonkeyEngine.
the class MikkTSpaceImpl method getNormal.
@Override
public void getNormal(float[] normOut, int face, int vert) {
int vertIndex = getIndex(face, vert);
VertexBuffer normal = mesh.getBuffer(VertexBuffer.Type.Normal);
FloatBuffer norm = (FloatBuffer) normal.getData();
norm.position(vertIndex * 3);
normOut[0] = norm.get();
normOut[1] = norm.get();
normOut[2] = norm.get();
}
Aggregations