Search in sources :

Example 1 with FbxMaterial

use of com.jme3.scene.plugins.fbx.objects.FbxMaterial in project jmonkeyengine by jMonkeyEngine.

the class SceneLoader method loadObjects.

private void loadObjects(FbxElement element) throws IOException {
    FbxObject obj = null;
    for (FbxElement e : element.children) {
        switch(e.id) {
            case "Geometry":
                FbxMesh mesh = new FbxMesh(this, e);
                obj = mesh;
                if (mesh.geometries != null)
                    geomMap.put(mesh.id, mesh);
                break;
            case "Material":
                obj = new FbxMaterial(this, e);
                break;
            case "Model":
                FbxNode node = new FbxNode(this, e);
                obj = node;
                modelMap.put(node.id, node);
                if (node.isLimb())
                    limbMap.put(node.id, node);
                break;
            case "Pose":
                FbxBindPose pose = new FbxBindPose(this, e);
                obj = pose;
                bindMap.put(pose.id, pose);
                break;
            case "Texture":
                obj = new FbxTexture(this, e);
                break;
            case "Video":
                obj = new FbxImage(this, e);
                break;
            case "Deformer":
                obj = loadDeformer(e);
                break;
            case "AnimationLayer":
                FbxObject layer = new FbxObject(this, e);
                obj = layer;
                alayerMap.put(layer.id, layer);
                break;
            case "AnimationCurve":
                obj = new FbxAnimCurve(this, e);
                break;
            case "AnimationCurveNode":
                obj = new FbxAnimNode(this, e);
                break;
            default:
                obj = null;
        }
        if (obj != null)
            allObjects.put(obj.id, obj);
    }
}
Also used : FbxElement(com.jme3.scene.plugins.fbx.file.FbxElement) FbxObject(com.jme3.scene.plugins.fbx.objects.FbxObject) FbxNode(com.jme3.scene.plugins.fbx.objects.FbxNode) FbxAnimCurve(com.jme3.scene.plugins.fbx.objects.FbxAnimCurve) FbxTexture(com.jme3.scene.plugins.fbx.objects.FbxTexture) FbxMesh(com.jme3.scene.plugins.fbx.objects.FbxMesh) FbxBindPose(com.jme3.scene.plugins.fbx.objects.FbxBindPose) FbxAnimNode(com.jme3.scene.plugins.fbx.objects.FbxAnimNode) FbxMaterial(com.jme3.scene.plugins.fbx.objects.FbxMaterial) FbxImage(com.jme3.scene.plugins.fbx.objects.FbxImage)

Example 2 with FbxMaterial

use of com.jme3.scene.plugins.fbx.objects.FbxMaterial in project jmonkeyengine by jMonkeyEngine.

the class FbxMesh method createGeometries.

private List<Geometry> createGeometries() throws IOException {
    Mesh mesh = new Mesh();
    mesh.setMode(Mode.Triangles);
    // Moreover quads should be triangulated (this increases number of vertices)
    if (indices != null) {
        iCount = indices.length;
        srcVertexCount = vertices.length / 3;
        // Indices contains negative numbers to define polygon last index
        // Check indices strides to be sure we have triangles or quads
        vCount = 0;
        // Count number of vertices to be produced
        int polyVertCount = 0;
        for (int i = 0; i < iCount; ++i) {
            int index = indices[i];
            polyVertCount++;
            if (index < 0) {
                if (polyVertCount == 3) {
                    // A triangle
                    vCount += 3;
                } else if (polyVertCount == 4) {
                    // A quad produce two triangles
                    vCount += 6;
                } else {
                    throw new AssetLoadException("Unsupported PolygonVertexIndex stride");
                }
                polyVertCount = 0;
            }
        }
        // Unroll index array into vertex mapping
        vertexMap = new ArrayList<>(vCount);
        indexMap = new ArrayList<>(vCount);
        polyVertCount = 0;
        for (int i = 0; i < iCount; ++i) {
            int index = indices[i];
            polyVertCount++;
            if (index < 0) {
                int lastIndex = -(index + 1);
                if (polyVertCount == 3) {
                    vertexMap.add(indices[i - 2]);
                    vertexMap.add(indices[i - 1]);
                    vertexMap.add(lastIndex);
                    indexMap.add(i - 2);
                    indexMap.add(i - 1);
                    indexMap.add(i - 0);
                } else if (polyVertCount == 4) {
                    vertexMap.add(indices[i - 3]);
                    vertexMap.add(indices[i - 2]);
                    vertexMap.add(indices[i - 1]);
                    vertexMap.add(indices[i - 3]);
                    vertexMap.add(indices[i - 1]);
                    vertexMap.add(lastIndex);
                    indexMap.add(i - 3);
                    indexMap.add(i - 2);
                    indexMap.add(i - 1);
                    indexMap.add(i - 3);
                    indexMap.add(i - 1);
                    indexMap.add(i - 0);
                }
                polyVertCount = 0;
            }
        }
        // Build reverse vertex mapping
        reverseVertexMap = new ArrayList<>(srcVertexCount);
        for (int i = 0; i < srcVertexCount; ++i) reverseVertexMap.add(new ArrayList<Integer>());
        for (int i = 0; i < vCount; ++i) {
            int index = vertexMap.get(i);
            reverseVertexMap.get(index).add(i);
        }
    } else {
        // Stub for no vertex indexing (direct mapping)
        iCount = vCount = srcVertexCount;
        vertexMap = new ArrayList<>(vCount);
        indexMap = new ArrayList<>(vCount);
        reverseVertexMap = new ArrayList<>(vCount);
        for (int i = 0; i < vCount; ++i) {
            vertexMap.set(i, i);
            indexMap.set(i, i);
            List<Integer> l = new ArrayList<Integer>(1);
            l.add(i);
            reverseVertexMap.add(l);
        }
    }
    if (vertices != null) {
        // Unroll vertices data array
        FloatBuffer posBuf = BufferUtils.createFloatBuffer(vCount * 3);
        mesh.setBuffer(VertexBuffer.Type.Position, 3, posBuf);
        int srcCount = vertices.length / 3;
        for (int i = 0; i < vCount; ++i) {
            int index = vertexMap.get(i);
            if (index > srcCount)
                throw new AssetLoadException("Invalid vertex mapping. Unexpected lookup vertex " + index + " from " + srcCount);
            // XXX Why we should scale by unit size?
            float x = (float) vertices[3 * index + 0] / scene.unitSize * scene.xAxis;
            float y = (float) vertices[3 * index + 1] / scene.unitSize * scene.yAxis;
            float z = (float) vertices[3 * index + 2] / scene.unitSize * scene.zAxis;
            posBuf.put(x).put(y).put(z);
        }
    }
    if (normals != null) {
        // Unroll normals data array
        FloatBuffer normBuf = BufferUtils.createFloatBuffer(vCount * 3);
        mesh.setBuffer(VertexBuffer.Type.Normal, 3, normBuf);
        List<Integer> mapping = null;
        if (normalsMapping.equals("ByVertice"))
            mapping = vertexMap;
        else if (normalsMapping.equals("ByPolygonVertex"))
            mapping = indexMap;
        else
            throw new IOException("Unknown normals mapping type: " + normalsMapping);
        int srcCount = normals.length / 3;
        for (int i = 0; i < vCount; ++i) {
            int index = mapping.get(i);
            if (index > srcCount)
                throw new AssetLoadException("Invalid normal mapping. Unexpected lookup normal " + index + " from " + srcCount);
            float x = (float) normals[3 * index + 0] * scene.xAxis;
            float y = (float) normals[3 * index + 1] * scene.yAxis;
            float z = (float) normals[3 * index + 2] * scene.zAxis;
            normBuf.put(x).put(y).put(z);
        }
    }
    if (tangents != null) {
        // Unroll normals data array
        FloatBuffer tanBuf = BufferUtils.createFloatBuffer(vCount * 4);
        mesh.setBuffer(VertexBuffer.Type.Tangent, 4, tanBuf);
        List<Integer> mapping = null;
        if (tangentsMapping.equals("ByVertice"))
            mapping = vertexMap;
        else if (tangentsMapping.equals("ByPolygonVertex"))
            mapping = indexMap;
        else
            throw new IOException("Unknown tangents mapping type: " + tangentsMapping);
        int srcCount = tangents.length / 3;
        for (int i = 0; i < vCount; ++i) {
            int index = mapping.get(i);
            if (index > srcCount)
                throw new AssetLoadException("Invalid tangent mapping. Unexpected lookup tangent " + index + " from " + srcCount);
            float x = (float) tangents[3 * index + 0] * scene.xAxis;
            float y = (float) tangents[3 * index + 1] * scene.yAxis;
            float z = (float) tangents[3 * index + 2] * scene.zAxis;
            tanBuf.put(x).put(y).put(z).put(-1.0f);
        }
    }
    if (binormals != null) {
        // Unroll normals data array
        FloatBuffer binormBuf = BufferUtils.createFloatBuffer(vCount * 3);
        mesh.setBuffer(VertexBuffer.Type.Binormal, 3, binormBuf);
        List<Integer> mapping = null;
        if (binormalsMapping.equals("ByVertice"))
            mapping = vertexMap;
        else if (binormalsMapping.equals("ByPolygonVertex"))
            mapping = indexMap;
        else
            throw new IOException("Unknown binormals mapping type: " + binormalsMapping);
        int srcCount = binormals.length / 3;
        for (int i = 0; i < vCount; ++i) {
            int index = mapping.get(i);
            if (index > srcCount)
                throw new AssetLoadException("Invalid binormal mapping. Unexpected lookup binormal " + index + " from " + srcCount);
            float x = (float) binormals[3 * index + 0] * scene.xAxis;
            float y = (float) binormals[3 * index + 1] * scene.yAxis;
            float z = (float) binormals[3 * index + 2] * scene.zAxis;
            binormBuf.put(x).put(y).put(z);
        }
    }
    for (int uvLayer = 0; uvLayer < uvs.size(); ++uvLayer) {
        double[] uv = uvs.get(uvLayer);
        int[] uvIndex = uvIndexes.size() > uvLayer ? uvIndexes.get(uvLayer) : null;
        List<Integer> unIndexMap = vertexMap;
        if (uvIndex != null) {
            int uvIndexSrcCount = uvIndex.length;
            if (uvIndexSrcCount != iCount)
                throw new AssetLoadException("Invalid number of texcoord index data " + uvIndexSrcCount + " expected " + iCount);
            // Unroll UV index array
            unIndexMap = new ArrayList<>(vCount);
            int polyVertCount = 0;
            for (int i = 0; i < iCount; ++i) {
                int index = indices[i];
                polyVertCount++;
                if (index < 0) {
                    if (polyVertCount == 3) {
                        unIndexMap.add(uvIndex[i - 2]);
                        unIndexMap.add(uvIndex[i - 1]);
                        unIndexMap.add(uvIndex[i - 0]);
                    } else if (polyVertCount == 4) {
                        unIndexMap.add(uvIndex[i - 3]);
                        unIndexMap.add(uvIndex[i - 2]);
                        unIndexMap.add(uvIndex[i - 1]);
                        unIndexMap.add(uvIndex[i - 3]);
                        unIndexMap.add(uvIndex[i - 1]);
                        unIndexMap.add(uvIndex[i - 0]);
                    }
                    polyVertCount = 0;
                }
            }
        }
        // Unroll UV data array
        FloatBuffer tcBuf = BufferUtils.createFloatBuffer(vCount * 2);
        VertexBuffer.Type type = VertexBuffer.Type.TexCoord;
        switch(uvLayer) {
            case 1:
                type = VertexBuffer.Type.TexCoord2;
                break;
            case 2:
                type = VertexBuffer.Type.TexCoord3;
                break;
            case 3:
                type = VertexBuffer.Type.TexCoord4;
                break;
            case 4:
                type = VertexBuffer.Type.TexCoord5;
                break;
            case 5:
                type = VertexBuffer.Type.TexCoord6;
                break;
            case 6:
                type = VertexBuffer.Type.TexCoord7;
                break;
            case 7:
                type = VertexBuffer.Type.TexCoord8;
                break;
        }
        mesh.setBuffer(type, 2, tcBuf);
        int srcCount = uv.length / 2;
        for (int i = 0; i < vCount; ++i) {
            int index = unIndexMap.get(i);
            if (index > srcCount)
                throw new AssetLoadException("Invalid texcoord mapping. Unexpected lookup texcoord " + index + " from " + srcCount);
            float u = (index >= 0) ? (float) uv[2 * index + 0] : 0;
            float v = (index >= 0) ? (float) uv[2 * index + 1] : 0;
            tcBuf.put(u).put(v);
        }
    }
    List<Geometry> geometries = new ArrayList<Geometry>();
    if (materialsReference.equals("IndexToDirect") && materialsMapping.equals("ByPolygon")) {
        IntMap<List<Integer>> indexBuffers = new IntMap<>();
        for (int polygon = 0; polygon < materials.length; ++polygon) {
            int material = materials[polygon];
            List<Integer> list = indexBuffers.get(material);
            if (list == null) {
                list = new ArrayList<>();
                indexBuffers.put(material, list);
            }
            list.add(polygon * 3 + 0);
            list.add(polygon * 3 + 1);
            list.add(polygon * 3 + 2);
        }
        Iterator<Entry<List<Integer>>> iterator = indexBuffers.iterator();
        while (iterator.hasNext()) {
            Entry<List<Integer>> e = iterator.next();
            int materialId = e.getKey();
            List<Integer> indexes = e.getValue();
            Mesh newMesh = mesh.clone();
            newMesh.setBuffer(VertexBuffer.Type.Index, 3, toArray(indexes.toArray(new Integer[indexes.size()])));
            newMesh.setStatic();
            newMesh.updateBound();
            newMesh.updateCounts();
            Geometry geom = new Geometry();
            geom.setMesh(newMesh);
            geometries.add(geom);
            geom.setUserData("FBXMaterial", materialId);
        }
    } else {
        mesh.setStatic();
        mesh.updateBound();
        mesh.updateCounts();
        Geometry geom = new Geometry();
        geom.setMesh(mesh);
        geometries.add(geom);
    }
    return geometries;
}
Also used : VertexBuffer(com.jme3.scene.VertexBuffer) ArrayList(java.util.ArrayList) Mesh(com.jme3.scene.Mesh) FloatBuffer(java.nio.FloatBuffer) IOException(java.io.IOException) AssetLoadException(com.jme3.asset.AssetLoadException) Geometry(com.jme3.scene.Geometry) Entry(com.jme3.util.IntMap.Entry) IntMap(com.jme3.util.IntMap) ArrayList(java.util.ArrayList) List(java.util.List)

Example 3 with FbxMaterial

use of com.jme3.scene.plugins.fbx.objects.FbxMaterial in project jmonkeyengine by jMonkeyEngine.

the class FbxNode method link.

@Override
public void link(FbxObject otherObject) {
    if (otherObject instanceof FbxMaterial) {
        FbxMaterial m = (FbxMaterial) otherObject;
        Material mat = m.material;
        if (cullMode != FaceCullMode.Back)
            mat.getAdditionalRenderState().setFaceCullMode(cullMode);
        for (Geometry g : mesh.geometries) {
            if (g.getUserData("FBXMaterial") != null) {
                if ((Integer) g.getUserData("FBXMaterial") == mesh.lastMaterialId)
                    g.setMaterial(mat);
            } else {
                g.setMaterial(mat);
            }
        }
        mesh.lastMaterialId++;
    } else if (otherObject instanceof FbxNode) {
        FbxNode n = (FbxNode) otherObject;
        node.attachChild(n.node);
        n.parentFbxNode = this;
        if (isLimb() && n.isLimb()) {
            if (bone == null)
                bone = new Bone(name);
            if (n.bone == null)
                n.bone = new Bone(n.name);
            bone.addChild(n.bone);
        }
    } else if (otherObject instanceof FbxMesh) {
        FbxMesh m = (FbxMesh) otherObject;
        m.setParent(node);
        m.parent = this;
        mesh = m;
    }
}
Also used : Geometry(com.jme3.scene.Geometry) Material(com.jme3.material.Material) Bone(com.jme3.animation.Bone)

Example 4 with FbxMaterial

use of com.jme3.scene.plugins.fbx.objects.FbxMaterial in project jmonkeyengine by jMonkeyEngine.

the class FbxNode method tryCreateGeometry.

private Spatial tryCreateGeometry(int materialIndex, Mesh jmeMesh, boolean single) {
    // Map meshes without material indices to material 0.
    if (materialIndex == -1) {
        materialIndex = 0;
    }
    Material jmeMat;
    if (materialIndex >= materials.size()) {
        // Material index does not exist. Create default material.
        jmeMat = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");
        jmeMat.setReceivesShadows(true);
    } else {
        FbxMaterial fbxMat = materials.get(materialIndex);
        jmeMat = fbxMat.getJmeObject();
    }
    String geomName = getName();
    if (single) {
        geomName += "-submesh";
    } else {
        geomName += "-mat-" + materialIndex + "-submesh";
    }
    Spatial spatial = new Geometry(geomName, jmeMesh);
    spatial.setMaterial(jmeMat);
    if (jmeMat.isTransparent()) {
        spatial.setQueueBucket(Bucket.Transparent);
    }
    if (jmeMat.isReceivesShadows()) {
        spatial.setShadowMode(ShadowMode.Receive);
    }
    spatial.updateModelBound();
    return spatial;
}
Also used : Geometry(com.jme3.scene.Geometry) Spatial(com.jme3.scene.Spatial) Material(com.jme3.material.Material) FbxMaterial(com.jme3.scene.plugins.fbx.material.FbxMaterial) FbxMaterial(com.jme3.scene.plugins.fbx.material.FbxMaterial)

Aggregations

Geometry (com.jme3.scene.Geometry)3 Material (com.jme3.material.Material)2 Bone (com.jme3.animation.Bone)1 AssetLoadException (com.jme3.asset.AssetLoadException)1 Mesh (com.jme3.scene.Mesh)1 Spatial (com.jme3.scene.Spatial)1 VertexBuffer (com.jme3.scene.VertexBuffer)1 FbxElement (com.jme3.scene.plugins.fbx.file.FbxElement)1 FbxMaterial (com.jme3.scene.plugins.fbx.material.FbxMaterial)1 FbxAnimCurve (com.jme3.scene.plugins.fbx.objects.FbxAnimCurve)1 FbxAnimNode (com.jme3.scene.plugins.fbx.objects.FbxAnimNode)1 FbxBindPose (com.jme3.scene.plugins.fbx.objects.FbxBindPose)1 FbxImage (com.jme3.scene.plugins.fbx.objects.FbxImage)1 FbxMaterial (com.jme3.scene.plugins.fbx.objects.FbxMaterial)1 FbxMesh (com.jme3.scene.plugins.fbx.objects.FbxMesh)1 FbxNode (com.jme3.scene.plugins.fbx.objects.FbxNode)1 FbxObject (com.jme3.scene.plugins.fbx.objects.FbxObject)1 FbxTexture (com.jme3.scene.plugins.fbx.objects.FbxTexture)1 IntMap (com.jme3.util.IntMap)1 Entry (com.jme3.util.IntMap.Entry)1