Search in sources :

Example 1 with IndexShortBuffer

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;
}
Also used : HashMap(java.util.HashMap) VertexBuffer(com.jme3.scene.VertexBuffer) ArrayList(java.util.ArrayList) Mesh(com.jme3.scene.Mesh) FloatBuffer(java.nio.FloatBuffer) ByteBuffer(java.nio.ByteBuffer) IndexBuffer(com.jme3.scene.mesh.IndexBuffer) IndexShortBuffer(com.jme3.scene.mesh.IndexShortBuffer) IndexIntBuffer(com.jme3.scene.mesh.IndexIntBuffer) IndexIntBuffer(com.jme3.scene.mesh.IndexIntBuffer) IntBuffer(java.nio.IntBuffer) IndexShortBuffer(com.jme3.scene.mesh.IndexShortBuffer) ShortBuffer(java.nio.ShortBuffer)

Example 2 with IndexShortBuffer

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;
}
Also used : FloatBuffer(java.nio.FloatBuffer) IndexBuffer(com.jme3.scene.mesh.IndexBuffer) IndexShortBuffer(com.jme3.scene.mesh.IndexShortBuffer) IndexIntBuffer(com.jme3.scene.mesh.IndexIntBuffer) IndexIntBuffer(com.jme3.scene.mesh.IndexIntBuffer) IntBuffer(java.nio.IntBuffer) IndexShortBuffer(com.jme3.scene.mesh.IndexShortBuffer) ShortBuffer(java.nio.ShortBuffer)

Aggregations

IndexBuffer (com.jme3.scene.mesh.IndexBuffer)2 IndexIntBuffer (com.jme3.scene.mesh.IndexIntBuffer)2 IndexShortBuffer (com.jme3.scene.mesh.IndexShortBuffer)2 FloatBuffer (java.nio.FloatBuffer)2 IntBuffer (java.nio.IntBuffer)2 ShortBuffer (java.nio.ShortBuffer)2 Mesh (com.jme3.scene.Mesh)1 VertexBuffer (com.jme3.scene.VertexBuffer)1 ByteBuffer (java.nio.ByteBuffer)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1