List of usage examples for com.badlogic.gdx.graphics.g3d.model.data ModelNodePart ModelNodePart
ModelNodePart
From source file:com.kevlanche.threedeetest.ScalableObjLoader.java
License:Apache License
protected ModelData loadModelData(FileHandle file, boolean flipV) { String line;/*ww w . j a va2 s. c o m*/ 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]) * this.objScale); verts.add(Float.parseFloat(tokens[2]) * this.objScale); verts.add(Float.parseFloat(tokens[3]) * this.objScale); } 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') { // This implementation only supports single object or group // definitions. i.e. "o group_a group_b" will set group_a // as the active group, while group_b will simply be // 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]; } } 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 nodeId = "node" + (++id); String meshId = "mesh" + id; String partId = "part" + id; 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 = GL10.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); } //for (ModelMaterial m : mtl.materials) //data.materials.add(m); // An instance of ObjLoader can be used to load more than one OBJ. // Clearing the Array cache instead of instantiating new // Arrays should result in slightly faster load times for // 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; }
From source file:com.mbrlabs.mundus.commons.g3d.MG3dModelLoader.java
License:Apache License
private ModelNode parseNodesRecursively(JsonValue json) { ModelNode jsonNode = new ModelNode(); String id = json.getString("id", null); if (id == null) throw new GdxRuntimeException("Node id missing."); jsonNode.id = id;/* ww w.j av a 2s .c o m*/ JsonValue translation = json.get("translation"); if (translation != null && translation.size != 3) throw new GdxRuntimeException("Node translation incomplete"); jsonNode.translation = translation == null ? null : new Vector3(translation.getFloat(0), translation.getFloat(1), translation.getFloat(2)); JsonValue rotation = json.get("rotation"); if (rotation != null && rotation.size != 4) throw new GdxRuntimeException("Node rotation incomplete"); jsonNode.rotation = rotation == null ? null : new Quaternion(rotation.getFloat(0), rotation.getFloat(1), rotation.getFloat(2), rotation.getFloat(3)); JsonValue scale = json.get("scale"); if (scale != null && scale.size != 3) throw new GdxRuntimeException("Node scale incomplete"); jsonNode.scale = scale == null ? null : new Vector3(scale.getFloat(0), scale.getFloat(1), scale.getFloat(2)); String meshId = json.getString("mesh", null); if (meshId != null) jsonNode.meshId = meshId; JsonValue materials = json.get("parts"); if (materials != null) { jsonNode.parts = new ModelNodePart[materials.size]; int i = 0; for (JsonValue material = materials.child; material != null; material = material.next, i++) { ModelNodePart nodePart = new ModelNodePart(); String meshPartId = material.getString("meshpartid", null); String materialId = material.getString("materialid", null); if (meshPartId == null || materialId == null) { throw new GdxRuntimeException("Node " + id + " part is missing meshPartId or materialId"); } nodePart.materialId = materialId; nodePart.meshPartId = meshPartId; JsonValue bones = material.get("bones"); if (bones != null) { nodePart.bones = new ArrayMap<String, Matrix4>(true, bones.size, String.class, Matrix4.class); int j = 0; for (JsonValue bone = bones.child; bone != null; bone = bone.next, j++) { String nodeId = bone.getString("node", null); if (nodeId == null) throw new GdxRuntimeException("Bone node ID missing"); Matrix4 transform = new Matrix4(); JsonValue val = bone.get("translation"); if (val != null && val.size >= 3) transform.translate(val.getFloat(0), val.getFloat(1), val.getFloat(2)); val = bone.get("rotation"); if (val != null && val.size >= 4) transform.rotate( tempQ.set(val.getFloat(0), val.getFloat(1), val.getFloat(2), val.getFloat(3))); val = bone.get("scale"); if (val != null && val.size >= 3) transform.scale(val.getFloat(0), val.getFloat(1), val.getFloat(2)); nodePart.bones.put(nodeId, transform); } } jsonNode.parts[i] = nodePart; } } JsonValue children = json.get("children"); if (children != null) { jsonNode.children = new ModelNode[children.size]; int i = 0; for (JsonValue child = children.child; child != null; child = child.next, i++) { jsonNode.children[i] = parseNodesRecursively(child); } } return jsonNode; }