Search in sources :

Example 1 with IrMesh

use of com.jme3.scene.plugins.IrMesh in project jmonkeyengine by jMonkeyEngine.

the class FbxMesh method toIRMesh.

/**
     * Convert FBXMesh to IRMesh.
     */
public IrMesh toIRMesh() {
    IrMesh newMesh = new IrMesh();
    newMesh.polygons = new IrPolygon[polygons.length];
    int polygonVertexIndex = 0;
    int positionIndex = 0;
    FbxLayer layer0 = layers[0];
    FbxLayer layer1 = layers.length > 1 ? layers[1] : null;
    for (int i = 0; i < polygons.length; i++) {
        FbxPolygon polygon = polygons[i];
        IrPolygon irPolygon = new IrPolygon();
        irPolygon.vertices = new IrVertex[polygon.indices.length];
        for (int j = 0; j < polygon.indices.length; j++) {
            positionIndex = polygon.indices[j];
            IrVertex irVertex = new IrVertex();
            irVertex.pos = positions[positionIndex];
            if (layer0 != null) {
                irVertex.norm = (Vector3f) layer0.getVertexData(FbxLayerElement.Type.Normal, i, polygonVertexIndex, positionIndex, 0);
                irVertex.tang = (Vector3f) layer0.getVertexData(FbxLayerElement.Type.Tangent, i, polygonVertexIndex, positionIndex, 0);
                irVertex.bitang = (Vector3f) layer0.getVertexData(FbxLayerElement.Type.Binormal, i, polygonVertexIndex, positionIndex, 0);
                irVertex.uv0 = (Vector2f) layer0.getVertexData(FbxLayerElement.Type.UV, i, polygonVertexIndex, positionIndex, 0);
                irVertex.color = (ColorRGBA) layer0.getVertexData(FbxLayerElement.Type.Color, i, polygonVertexIndex, positionIndex, 0);
                irVertex.material = (Integer) layer0.getVertexData(FbxLayerElement.Type.Material, i, polygonVertexIndex, positionIndex, 0);
                irVertex.smoothing = (Integer) layer0.getVertexData(FbxLayerElement.Type.Smoothing, i, polygonVertexIndex, positionIndex, 0);
            }
            if (layer1 != null) {
                irVertex.uv1 = (Vector2f) layer1.getVertexData(FbxLayerElement.Type.UV, i, polygonVertexIndex, positionIndex, 0);
            }
            if (boneIndices != null) {
                ArrayList<Integer> boneIndicesForVertex = boneIndices[positionIndex];
                ArrayList<Float> boneWeightsForVertex = boneWeights[positionIndex];
                if (boneIndicesForVertex != null) {
                    irVertex.boneWeightsIndices = toBoneWeightIndices(boneIndicesForVertex, boneWeightsForVertex);
                }
            }
            irPolygon.vertices[j] = irVertex;
            polygonVertexIndex++;
        }
        newMesh.polygons[i] = irPolygon;
    }
    // Ensure "inspection vertex" specifies that mesh has bone indices / weights
    if (boneIndices != null && newMesh.polygons[0].vertices[0] == null) {
        newMesh.polygons[0].vertices[0].boneWeightsIndices = new IrBoneWeightIndex[0];
    }
    return newMesh;
}
Also used : IrPolygon(com.jme3.scene.plugins.IrPolygon) IrMesh(com.jme3.scene.plugins.IrMesh) IrVertex(com.jme3.scene.plugins.IrVertex)

Example 2 with IrMesh

use of com.jme3.scene.plugins.IrMesh 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 3 with IrMesh

use of com.jme3.scene.plugins.IrMesh in project jmonkeyengine by jMonkeyEngine.

the class FbxMesh method toJmeObject.

@Override
protected IntMap<Mesh> toJmeObject() {
    // Load clusters from SkinDeformer
    if (skinDeformer != null) {
        for (FbxCluster cluster : skinDeformer.getJmeObject()) {
            applyCluster(cluster);
        }
    }
    IrMesh irMesh = toIRMesh();
    // Trim bone weights to 4 weights per vertex.
    IrUtils.trimBoneWeights(irMesh);
    // Convert tangents / binormals to tangents with parity.
    IrUtils.toTangentsWithParity(irMesh);
    // Triangulate quads.
    IrUtils.triangulate(irMesh);
    // Split meshes by material indices.
    IntMap<IrMesh> irMeshes = IrUtils.splitByMaterial(irMesh);
    // Create a jME3 Mesh for each material index.
    IntMap<Mesh> jmeMeshes = new IntMap<Mesh>();
    for (IntMap.Entry<IrMesh> irMeshEntry : irMeshes) {
        Mesh jmeMesh = IrUtils.convertIrMeshToJmeMesh(irMeshEntry.getValue());
        jmeMeshes.put(irMeshEntry.getKey(), jmeMesh);
    }
    if (jmeMeshes.size() == 0) {
        // When will this actually happen? Not sure.
        logger.log(Level.WARNING, "Empty FBX mesh found (unusual).");
    }
    // It makes sense only if the mesh uses a single material!
    if (jmeMeshes.containsKey(-1) && jmeMeshes.size() > 1) {
        logger.log(Level.WARNING, "Mesh has polygons with no material " + "indices (unusual) - they will use material index 0.");
    }
    return jmeMeshes;
}
Also used : FbxCluster(com.jme3.scene.plugins.fbx.anim.FbxCluster) IntMap(com.jme3.util.IntMap) IrMesh(com.jme3.scene.plugins.IrMesh) Mesh(com.jme3.scene.Mesh) IrMesh(com.jme3.scene.plugins.IrMesh)

Aggregations

Mesh (com.jme3.scene.Mesh)2 IrMesh (com.jme3.scene.plugins.IrMesh)2 VertexBuffer (com.jme3.scene.VertexBuffer)1 IndexBuffer (com.jme3.scene.mesh.IndexBuffer)1 IndexIntBuffer (com.jme3.scene.mesh.IndexIntBuffer)1 IndexShortBuffer (com.jme3.scene.mesh.IndexShortBuffer)1 IrPolygon (com.jme3.scene.plugins.IrPolygon)1 IrVertex (com.jme3.scene.plugins.IrVertex)1 FbxCluster (com.jme3.scene.plugins.fbx.anim.FbxCluster)1 IntMap (com.jme3.util.IntMap)1 ByteBuffer (java.nio.ByteBuffer)1 FloatBuffer (java.nio.FloatBuffer)1 IntBuffer (java.nio.IntBuffer)1 ShortBuffer (java.nio.ShortBuffer)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1