Search in sources :

Example 1 with ModelMesh

use of com.badlogic.gdx.graphics.g3d.model.data.ModelMesh in project libgdx by libgdx.

the class Model method convertMesh.

protected void convertMesh(ModelMesh modelMesh) {
    int numIndices = 0;
    for (ModelMeshPart part : modelMesh.parts) {
        numIndices += part.indices.length;
    }
    VertexAttributes attributes = new VertexAttributes(modelMesh.attributes);
    int numVertices = modelMesh.vertices.length / (attributes.vertexSize / 4);
    Mesh mesh = new Mesh(true, numVertices, numIndices, attributes);
    meshes.add(mesh);
    disposables.add(mesh);
    BufferUtils.copy(modelMesh.vertices, mesh.getVerticesBuffer(), modelMesh.vertices.length, 0);
    int offset = 0;
    mesh.getIndicesBuffer().clear();
    for (ModelMeshPart part : modelMesh.parts) {
        MeshPart meshPart = new MeshPart();
        meshPart.id = part.id;
        meshPart.primitiveType = part.primitiveType;
        meshPart.offset = offset;
        meshPart.size = part.indices.length;
        meshPart.mesh = mesh;
        mesh.getIndicesBuffer().put(part.indices);
        offset += meshPart.size;
        meshParts.add(meshPart);
    }
    mesh.getIndicesBuffer().position(0);
    for (MeshPart part : meshParts) part.update();
}
Also used : ModelMeshPart(com.badlogic.gdx.graphics.g3d.model.data.ModelMeshPart) VertexAttributes(com.badlogic.gdx.graphics.VertexAttributes) ModelMesh(com.badlogic.gdx.graphics.g3d.model.data.ModelMesh) Mesh(com.badlogic.gdx.graphics.Mesh) ModelMeshPart(com.badlogic.gdx.graphics.g3d.model.data.ModelMeshPart) MeshPart(com.badlogic.gdx.graphics.g3d.model.MeshPart)

Example 2 with ModelMesh

use of com.badlogic.gdx.graphics.g3d.model.data.ModelMesh in project libgdx by libgdx.

the class G3dModelLoader method parseMeshes.

private void parseMeshes(ModelData model, JsonValue json) {
    JsonValue meshes = json.get("meshes");
    if (meshes != null) {
        model.meshes.ensureCapacity(meshes.size);
        for (JsonValue mesh = meshes.child; mesh != null; mesh = mesh.next) {
            ModelMesh jsonMesh = new ModelMesh();
            String id = mesh.getString("id", "");
            jsonMesh.id = id;
            JsonValue attributes = mesh.require("attributes");
            jsonMesh.attributes = parseAttributes(attributes);
            jsonMesh.vertices = mesh.require("vertices").asFloatArray();
            JsonValue meshParts = mesh.require("parts");
            Array<ModelMeshPart> parts = new Array<ModelMeshPart>();
            for (JsonValue meshPart = meshParts.child; meshPart != null; meshPart = meshPart.next) {
                ModelMeshPart jsonPart = new ModelMeshPart();
                String partId = meshPart.getString("id", null);
                if (partId == null) {
                    throw new GdxRuntimeException("Not id given for mesh part");
                }
                for (ModelMeshPart other : parts) {
                    if (other.id.equals(partId)) {
                        throw new GdxRuntimeException("Mesh part with id '" + partId + "' already in defined");
                    }
                }
                jsonPart.id = partId;
                String type = meshPart.getString("type", null);
                if (type == null) {
                    throw new GdxRuntimeException("No primitive type given for mesh part '" + partId + "'");
                }
                jsonPart.primitiveType = parseType(type);
                jsonPart.indices = meshPart.require("indices").asShortArray();
                parts.add(jsonPart);
            }
            jsonMesh.parts = parts.toArray(ModelMeshPart.class);
            model.meshes.add(jsonMesh);
        }
    }
}
Also used : ModelMesh(com.badlogic.gdx.graphics.g3d.model.data.ModelMesh) Array(com.badlogic.gdx.utils.Array) GdxRuntimeException(com.badlogic.gdx.utils.GdxRuntimeException) ModelMeshPart(com.badlogic.gdx.graphics.g3d.model.data.ModelMeshPart) JsonValue(com.badlogic.gdx.utils.JsonValue)

Example 3 with ModelMesh

use of com.badlogic.gdx.graphics.g3d.model.data.ModelMesh in project libgdx by libgdx.

the class MtlLoader method loadModelData.

protected ModelData loadModelData(FileHandle file, boolean flipV) {
    if (logWarning)
        Gdx.app.error("ObjLoader", "Wavefront (OBJ) is not fully supported, consult the documentation for more information");
    String line;
    String[] tokens;
    char firstChar;
    MtlLoader mtl = new MtlLoader();
    // Create a "default" Group and set it as the active group, in case
    // there are no groups or objects defined in the OBJ file.
    Group activeGroup = new Group("default");
    groups.add(activeGroup);
    BufferedReader reader = new BufferedReader(new InputStreamReader(file.read()), 4096);
    int id = 0;
    try {
        while ((line = reader.readLine()) != null) {
            tokens = line.split("\\s+");
            if (tokens.length < 1)
                break;
            if (tokens[0].length() == 0) {
                continue;
            } else if ((firstChar = tokens[0].toLowerCase().charAt(0)) == '#') {
                continue;
            } else if (firstChar == 'v') {
                if (tokens[0].length() == 1) {
                    verts.add(Float.parseFloat(tokens[1]));
                    verts.add(Float.parseFloat(tokens[2]));
                    verts.add(Float.parseFloat(tokens[3]));
                } else if (tokens[0].charAt(1) == 'n') {
                    norms.add(Float.parseFloat(tokens[1]));
                    norms.add(Float.parseFloat(tokens[2]));
                    norms.add(Float.parseFloat(tokens[3]));
                } else if (tokens[0].charAt(1) == 't') {
                    uvs.add(Float.parseFloat(tokens[1]));
                    uvs.add((flipV ? 1 - Float.parseFloat(tokens[2]) : Float.parseFloat(tokens[2])));
                }
            } else if (firstChar == 'f') {
                String[] parts;
                Array<Integer> faces = activeGroup.faces;
                for (int i = 1; i < tokens.length - 2; i--) {
                    parts = tokens[1].split("/");
                    faces.add(getIndex(parts[0], verts.size));
                    if (parts.length > 2) {
                        if (i == 1)
                            activeGroup.hasNorms = true;
                        faces.add(getIndex(parts[2], norms.size));
                    }
                    if (parts.length > 1 && parts[1].length() > 0) {
                        if (i == 1)
                            activeGroup.hasUVs = true;
                        faces.add(getIndex(parts[1], uvs.size));
                    }
                    parts = tokens[++i].split("/");
                    faces.add(getIndex(parts[0], verts.size));
                    if (parts.length > 2)
                        faces.add(getIndex(parts[2], norms.size));
                    if (parts.length > 1 && parts[1].length() > 0)
                        faces.add(getIndex(parts[1], uvs.size));
                    parts = tokens[++i].split("/");
                    faces.add(getIndex(parts[0], verts.size));
                    if (parts.length > 2)
                        faces.add(getIndex(parts[2], norms.size));
                    if (parts.length > 1 && parts[1].length() > 0)
                        faces.add(getIndex(parts[1], uvs.size));
                    activeGroup.numFaces++;
                }
            } else if (firstChar == 'o' || firstChar == 'g') {
                // ignored.
                if (tokens.length > 1)
                    activeGroup = setActiveGroup(tokens[1]);
                else
                    activeGroup = setActiveGroup("default");
            } else if (tokens[0].equals("mtllib")) {
                mtl.load(file.parent().child(tokens[1]));
            } else if (tokens[0].equals("usemtl")) {
                if (tokens.length == 1)
                    activeGroup.materialName = "default";
                else
                    activeGroup.materialName = tokens[1].replace('.', '_');
            }
        }
        reader.close();
    } catch (IOException e) {
        return null;
    }
    // If the "default" group or any others were not used, get rid of them
    for (int i = 0; i < groups.size; i++) {
        if (groups.get(i).numFaces < 1) {
            groups.removeIndex(i);
            i--;
        }
    }
    // If there are no groups left, there is no valid Model to return
    if (groups.size < 1)
        return null;
    // Get number of objects/groups remaining after removing empty ones
    final int numGroups = groups.size;
    final ModelData data = new ModelData();
    for (int g = 0; g < numGroups; g++) {
        Group group = groups.get(g);
        Array<Integer> faces = group.faces;
        final int numElements = faces.size;
        final int numFaces = group.numFaces;
        final boolean hasNorms = group.hasNorms;
        final boolean hasUVs = group.hasUVs;
        final float[] finalVerts = new float[(numFaces * 3) * (3 + (hasNorms ? 3 : 0) + (hasUVs ? 2 : 0))];
        for (int i = 0, vi = 0; i < numElements; ) {
            int vertIndex = faces.get(i++) * 3;
            finalVerts[vi++] = verts.get(vertIndex++);
            finalVerts[vi++] = verts.get(vertIndex++);
            finalVerts[vi++] = verts.get(vertIndex);
            if (hasNorms) {
                int normIndex = faces.get(i++) * 3;
                finalVerts[vi++] = norms.get(normIndex++);
                finalVerts[vi++] = norms.get(normIndex++);
                finalVerts[vi++] = norms.get(normIndex);
            }
            if (hasUVs) {
                int uvIndex = faces.get(i++) * 2;
                finalVerts[vi++] = uvs.get(uvIndex++);
                finalVerts[vi++] = uvs.get(uvIndex);
            }
        }
        final int numIndices = numFaces * 3 >= Short.MAX_VALUE ? 0 : numFaces * 3;
        final short[] finalIndices = new short[numIndices];
        // if there are too many vertices in a mesh, we can't use indices
        if (numIndices > 0) {
            for (int i = 0; i < numIndices; i++) {
                finalIndices[i] = (short) i;
            }
        }
        Array<VertexAttribute> attributes = new Array<VertexAttribute>();
        attributes.add(new VertexAttribute(Usage.Position, 3, ShaderProgram.POSITION_ATTRIBUTE));
        if (hasNorms)
            attributes.add(new VertexAttribute(Usage.Normal, 3, ShaderProgram.NORMAL_ATTRIBUTE));
        if (hasUVs)
            attributes.add(new VertexAttribute(Usage.TextureCoordinates, 2, ShaderProgram.TEXCOORD_ATTRIBUTE + "0"));
        String stringId = Integer.toString(++id);
        String nodeId = "default".equals(group.name) ? "node" + stringId : group.name;
        String meshId = "default".equals(group.name) ? "mesh" + stringId : group.name;
        String partId = "default".equals(group.name) ? "part" + stringId : group.name;
        ModelNode node = new ModelNode();
        node.id = nodeId;
        node.meshId = meshId;
        node.scale = new Vector3(1, 1, 1);
        node.translation = new Vector3();
        node.rotation = new Quaternion();
        ModelNodePart pm = new ModelNodePart();
        pm.meshPartId = partId;
        pm.materialId = group.materialName;
        node.parts = new ModelNodePart[] { pm };
        ModelMeshPart part = new ModelMeshPart();
        part.id = partId;
        part.indices = finalIndices;
        part.primitiveType = GL20.GL_TRIANGLES;
        ModelMesh mesh = new ModelMesh();
        mesh.id = meshId;
        mesh.attributes = attributes.toArray(VertexAttribute.class);
        mesh.vertices = finalVerts;
        mesh.parts = new ModelMeshPart[] { part };
        data.nodes.add(node);
        data.meshes.add(mesh);
        ModelMaterial mm = mtl.getMaterial(group.materialName);
        data.materials.add(mm);
    }
    // subsequent calls to loadObj
    if (verts.size > 0)
        verts.clear();
    if (norms.size > 0)
        norms.clear();
    if (uvs.size > 0)
        uvs.clear();
    if (groups.size > 0)
        groups.clear();
    return data;
}
Also used : ModelMesh(com.badlogic.gdx.graphics.g3d.model.data.ModelMesh) ModelData(com.badlogic.gdx.graphics.g3d.model.data.ModelData) Quaternion(com.badlogic.gdx.math.Quaternion) VertexAttribute(com.badlogic.gdx.graphics.VertexAttribute) ModelNodePart(com.badlogic.gdx.graphics.g3d.model.data.ModelNodePart) ModelMaterial(com.badlogic.gdx.graphics.g3d.model.data.ModelMaterial) ModelMeshPart(com.badlogic.gdx.graphics.g3d.model.data.ModelMeshPart) InputStreamReader(java.io.InputStreamReader) Vector3(com.badlogic.gdx.math.Vector3) IOException(java.io.IOException) Array(com.badlogic.gdx.utils.Array) FloatArray(com.badlogic.gdx.utils.FloatArray) BufferedReader(java.io.BufferedReader) ModelNode(com.badlogic.gdx.graphics.g3d.model.data.ModelNode)

Aggregations

ModelMesh (com.badlogic.gdx.graphics.g3d.model.data.ModelMesh)3 ModelMeshPart (com.badlogic.gdx.graphics.g3d.model.data.ModelMeshPart)3 Array (com.badlogic.gdx.utils.Array)2 Mesh (com.badlogic.gdx.graphics.Mesh)1 VertexAttribute (com.badlogic.gdx.graphics.VertexAttribute)1 VertexAttributes (com.badlogic.gdx.graphics.VertexAttributes)1 MeshPart (com.badlogic.gdx.graphics.g3d.model.MeshPart)1 ModelData (com.badlogic.gdx.graphics.g3d.model.data.ModelData)1 ModelMaterial (com.badlogic.gdx.graphics.g3d.model.data.ModelMaterial)1 ModelNode (com.badlogic.gdx.graphics.g3d.model.data.ModelNode)1 ModelNodePart (com.badlogic.gdx.graphics.g3d.model.data.ModelNodePart)1 Quaternion (com.badlogic.gdx.math.Quaternion)1 Vector3 (com.badlogic.gdx.math.Vector3)1 FloatArray (com.badlogic.gdx.utils.FloatArray)1 GdxRuntimeException (com.badlogic.gdx.utils.GdxRuntimeException)1 JsonValue (com.badlogic.gdx.utils.JsonValue)1 BufferedReader (java.io.BufferedReader)1 IOException (java.io.IOException)1 InputStreamReader (java.io.InputStreamReader)1