use of com.jme3.scene.mesh.IndexShortBuffer in project jmonkeyengine by jMonkeyEngine.
the class IrUtils method convertIrMeshToJmeMesh.
/**
* Convert IrMesh to jME3 mesh.
*/
public static Mesh convertIrMeshToJmeMesh(IrMesh mesh) {
Map<IrVertex, Integer> vertexToVertexIndex = new HashMap<IrVertex, Integer>();
List<IrVertex> vertices = new ArrayList<IrVertex>();
List<Integer> indexes = new ArrayList<Integer>();
int vertexIndex = 0;
for (IrPolygon polygon : mesh.polygons) {
if (polygon.vertices.length != 3) {
throw new UnsupportedOperationException("IrMesh must be triangulated first");
}
for (IrVertex vertex : polygon.vertices) {
// Is this vertex already indexed?
Integer existingIndex = vertexToVertexIndex.get(vertex);
if (existingIndex == null) {
// Not indexed yet, allocate index.
indexes.add(vertexIndex);
vertexToVertexIndex.put(vertex, vertexIndex);
vertices.add(vertex);
vertexIndex++;
} else {
// Index already allocated for this vertex, reuse it.
indexes.add(existingIndex);
}
}
}
Mesh jmeMesh = new Mesh();
jmeMesh.setMode(Mesh.Mode.Triangles);
FloatBuffer posBuf = null;
FloatBuffer normBuf = null;
FloatBuffer tangBuf = null;
FloatBuffer uv0Buf = null;
FloatBuffer uv1Buf = null;
ByteBuffer colorBuf = null;
ByteBuffer boneIndices = null;
FloatBuffer boneWeights = null;
IndexBuffer indexBuf = null;
IrVertex inspectionVertex = vertices.get(0);
if (inspectionVertex.pos != null) {
posBuf = BufferUtils.createVector3Buffer(vertices.size());
jmeMesh.setBuffer(VertexBuffer.Type.Position, 3, posBuf);
}
if (inspectionVertex.norm != null) {
normBuf = BufferUtils.createVector3Buffer(vertices.size());
jmeMesh.setBuffer(VertexBuffer.Type.Normal, 3, normBuf);
}
if (inspectionVertex.tang4d != null) {
tangBuf = BufferUtils.createFloatBuffer(vertices.size() * 4);
jmeMesh.setBuffer(VertexBuffer.Type.Tangent, 4, tangBuf);
}
if (inspectionVertex.tang != null || inspectionVertex.bitang != null) {
throw new IllegalStateException("Mesh is using 3D tangents, must be converted to 4D tangents first.");
}
if (inspectionVertex.uv0 != null) {
uv0Buf = BufferUtils.createVector2Buffer(vertices.size());
jmeMesh.setBuffer(VertexBuffer.Type.TexCoord, 2, uv0Buf);
}
if (inspectionVertex.uv1 != null) {
uv1Buf = BufferUtils.createVector2Buffer(vertices.size());
jmeMesh.setBuffer(VertexBuffer.Type.TexCoord2, 2, uv1Buf);
}
if (inspectionVertex.color != null) {
colorBuf = BufferUtils.createByteBuffer(vertices.size() * 4);
jmeMesh.setBuffer(VertexBuffer.Type.Color, 4, colorBuf);
jmeMesh.getBuffer(VertexBuffer.Type.Color).setNormalized(true);
}
if (inspectionVertex.boneWeightsIndices != null) {
boneIndices = BufferUtils.createByteBuffer(vertices.size() * 4);
boneWeights = BufferUtils.createFloatBuffer(vertices.size() * 4);
jmeMesh.setBuffer(VertexBuffer.Type.BoneIndex, 4, boneIndices);
jmeMesh.setBuffer(VertexBuffer.Type.BoneWeight, 4, boneWeights);
//creating empty buffers for HW skinning
//the buffers will be setup if ever used.
VertexBuffer weightsHW = new VertexBuffer(VertexBuffer.Type.HWBoneWeight);
VertexBuffer indicesHW = new VertexBuffer(VertexBuffer.Type.HWBoneIndex);
//setting usage to cpuOnly so that the buffer is not send empty to the GPU
indicesHW.setUsage(VertexBuffer.Usage.CpuOnly);
weightsHW.setUsage(VertexBuffer.Usage.CpuOnly);
jmeMesh.setBuffer(weightsHW);
jmeMesh.setBuffer(indicesHW);
}
if (vertices.size() >= 65536) {
// too many verticies: use intbuffer instead of shortbuffer
IntBuffer ib = BufferUtils.createIntBuffer(indexes.size());
jmeMesh.setBuffer(VertexBuffer.Type.Index, 3, ib);
indexBuf = new IndexIntBuffer(ib);
} else {
ShortBuffer sb = BufferUtils.createShortBuffer(indexes.size());
jmeMesh.setBuffer(VertexBuffer.Type.Index, 3, sb);
indexBuf = new IndexShortBuffer(sb);
}
jmeMesh.setStatic();
int maxBonesPerVertex = -1;
for (IrVertex vertex : vertices) {
if (posBuf != null) {
posBuf.put(vertex.pos.x).put(vertex.pos.y).put(vertex.pos.z);
}
if (normBuf != null) {
normBuf.put(vertex.norm.x).put(vertex.norm.y).put(vertex.norm.z);
}
if (tangBuf != null) {
tangBuf.put(vertex.tang4d.x).put(vertex.tang4d.y).put(vertex.tang4d.z).put(vertex.tang4d.w);
}
if (uv0Buf != null) {
uv0Buf.put(vertex.uv0.x).put(vertex.uv0.y);
}
if (uv1Buf != null) {
uv1Buf.put(vertex.uv1.x).put(vertex.uv1.y);
}
if (colorBuf != null) {
colorBuf.putInt(vertex.color.asIntABGR());
}
if (boneIndices != null) {
if (vertex.boneWeightsIndices != null) {
if (vertex.boneWeightsIndices.length > 4) {
throw new UnsupportedOperationException("Mesh uses more than 4 weights per bone. " + "Call trimBoneWeights() to allieviate this");
}
for (int i = 0; i < vertex.boneWeightsIndices.length; i++) {
boneIndices.put((byte) (vertex.boneWeightsIndices[i].boneIndex & 0xFF));
boneWeights.put(vertex.boneWeightsIndices[i].boneWeight);
}
for (int i = 0; i < 4 - vertex.boneWeightsIndices.length; i++) {
boneIndices.put((byte) 0);
boneWeights.put(0f);
}
} else {
boneIndices.putInt(0);
boneWeights.put(0f).put(0f).put(0f).put(0f);
}
maxBonesPerVertex = Math.max(maxBonesPerVertex, vertex.boneWeightsIndices.length);
}
}
for (int i = 0; i < indexes.size(); i++) {
indexBuf.put(i, indexes.get(i));
}
jmeMesh.updateCounts();
jmeMesh.updateBound();
if (boneIndices != null) {
jmeMesh.setMaxNumWeights(maxBonesPerVertex);
jmeMesh.prepareForAnim(true);
jmeMesh.generateBindPose(true);
}
return jmeMesh;
}
use of com.jme3.scene.mesh.IndexShortBuffer in project jmonkeyengine by jMonkeyEngine.
the class OBJLoader method constructMesh.
protected Mesh constructMesh(ArrayList<Face> faceList) {
Mesh m = new Mesh();
m.setMode(Mode.Triangles);
boolean hasTexCoord = false;
boolean hasNormals = false;
ArrayList<Face> newFaces = new ArrayList<Face>(faceList.size());
for (int i = 0; i < faceList.size(); i++) {
Face f = faceList.get(i);
for (Vertex v : f.verticies) {
findVertexIndex(v);
if (!hasTexCoord && v.vt != null)
hasTexCoord = true;
if (!hasNormals && v.vn != null)
hasNormals = true;
}
if (f.verticies.length == 4) {
Face[] t = quadToTriangle(f);
newFaces.add(t[0]);
newFaces.add(t[1]);
} else {
newFaces.add(f);
}
}
FloatBuffer posBuf = BufferUtils.createFloatBuffer(vertIndexMap.size() * 3);
FloatBuffer normBuf = null;
FloatBuffer tcBuf = null;
if (hasNormals) {
normBuf = BufferUtils.createFloatBuffer(vertIndexMap.size() * 3);
m.setBuffer(VertexBuffer.Type.Normal, 3, normBuf);
}
if (hasTexCoord) {
tcBuf = BufferUtils.createFloatBuffer(vertIndexMap.size() * 2);
m.setBuffer(VertexBuffer.Type.TexCoord, 2, tcBuf);
}
IndexBuffer indexBuf = null;
if (vertIndexMap.size() >= 65536) {
// too many verticies: use intbuffer instead of shortbuffer
IntBuffer ib = BufferUtils.createIntBuffer(newFaces.size() * 3);
m.setBuffer(VertexBuffer.Type.Index, 3, ib);
indexBuf = new IndexIntBuffer(ib);
} else {
ShortBuffer sb = BufferUtils.createShortBuffer(newFaces.size() * 3);
m.setBuffer(VertexBuffer.Type.Index, 3, sb);
indexBuf = new IndexShortBuffer(sb);
}
int numFaces = newFaces.size();
for (int i = 0; i < numFaces; i++) {
Face f = newFaces.get(i);
if (f.verticies.length != 3)
continue;
Vertex v0 = f.verticies[0];
Vertex v1 = f.verticies[1];
Vertex v2 = f.verticies[2];
posBuf.position(v0.index * 3);
posBuf.put(v0.v.x).put(v0.v.y).put(v0.v.z);
posBuf.position(v1.index * 3);
posBuf.put(v1.v.x).put(v1.v.y).put(v1.v.z);
posBuf.position(v2.index * 3);
posBuf.put(v2.v.x).put(v2.v.y).put(v2.v.z);
if (normBuf != null) {
if (v0.vn != null) {
normBuf.position(v0.index * 3);
normBuf.put(v0.vn.x).put(v0.vn.y).put(v0.vn.z);
normBuf.position(v1.index * 3);
normBuf.put(v1.vn.x).put(v1.vn.y).put(v1.vn.z);
normBuf.position(v2.index * 3);
normBuf.put(v2.vn.x).put(v2.vn.y).put(v2.vn.z);
}
}
if (tcBuf != null) {
if (v0.vt != null) {
tcBuf.position(v0.index * 2);
tcBuf.put(v0.vt.x).put(v0.vt.y);
tcBuf.position(v1.index * 2);
tcBuf.put(v1.vt.x).put(v1.vt.y);
tcBuf.position(v2.index * 2);
tcBuf.put(v2.vt.x).put(v2.vt.y);
}
}
// current face * 3 = current index
int index = i * 3;
indexBuf.put(index, v0.index);
indexBuf.put(index + 1, v1.index);
indexBuf.put(index + 2, v2.index);
}
m.setBuffer(VertexBuffer.Type.Position, 3, posBuf);
// index buffer and others were set on creation
m.setStatic();
m.updateBound();
m.updateCounts();
//m.setInterleaved();
// clear data generated face statements
// to prepare for next mesh
vertIndexMap.clear();
indexVertMap.clear();
curIndex = 0;
return m;
}
Aggregations