internal static MeshDef ExtractMeshDefinition(Model model) { MeshDef def = new MeshDef(); int id = 0; foreach (Material mat in model.materials) { MeshDef.MaterialDef smat = def.addMaterial("m" + id.ToString()); smat.texture = SmartTexture(mat.diffuseTexture); ++id; } foreach (Bone b in model.bones) { MeshDef.Bone bn = def.newBone(); bn.pos = new vec3(b.x, b.y, b.z); bn.rot = makeQuat(new vec3(b.rx, b.ry, b.rz)); bn.parent = b.parentId; bn.name = b.name; } int vadded = 0; int vbase = 0; int nadded = 0; int nbase = 0; foreach (Mesh me in model.meshes) { vbase += vadded; vadded = 0; nbase += nadded; nadded = 0; def.selectMaterial("m" + me.materialId); foreach (Vertex v in me.vertices) { def.addPoint(v.pos, v.bone); def.AddUv(new vec2(v.u, 1 - v.v)); ++vadded; } foreach (Normal n in me.normals) { def.addNomal(n.norm); ++nadded; } foreach (Tri tr in me.tris) { MeshDef.VertexData[] data = new MeshDef.VertexData[3]; data[0].uv = data[0].vertex = vbase + tr.v1; data[1].uv = data[1].vertex = vbase + tr.v2; data[2].uv = data[2].vertex = vbase + tr.v3; data[0].normal = nbase + tr.n1; data[1].normal = nbase + tr.n2; data[2].normal = nbase + tr.n3; def.addTri(new MeshDef.Tri(data)); } } return(def); }
/// <summary> /// Generates a shape /// </summary> /// <param name="name">Name of the geometry</param> /// <returns>Returns an handle to the shape or null</returns> public Mesh GenerateShape(string name) { if (string.IsNullOrEmpty(name) || !Geometries.ContainsKey(name)) { return(null); } Mesh shape = new Mesh(); // Get the geometry Geometry geometry = Geometries[name]; MeshDef mesh = geometry.Mesh; // Get the size of one element (sum of all strides) int stridesum = 0; foreach (Source src in mesh.Sources.Values) { stridesum += src.Technique.Accessor.Stride; } // Create the index buffer int indexCount = mesh.Triangles.Count * 3; int[] indexbuffer = new int[indexCount]; //for (int i = 0; i < indexbuffer.Length; i++) // indexbuffer[i] = -1; // Create the array buffer float[] buffer = new float[stridesum * mesh.VertexCount]; for (int i = 0; i < buffer.Length; i++) { buffer[i] = 99.0f; } // Offset in the <p> buffer according to <inputs> strides int offset = mesh.Triangles.GetInput(InputSemantic.Vertex).Offset; // For each index in the <p> tag for (int i = 0; i < indexCount; i++) { // Position in the <p> tag int pos = i * mesh.Triangles.Inputs.Count + offset; // Fill the index buffer indexbuffer[i] = mesh.Triangles.Data[pos]; } // Copy all vertices to the array buffer Source source = mesh.GetVerticesSource(); for (int i = 0; i < source.Technique.Accessor.Count; i++) { buffer[i * stridesum] = source.Array.Data[i * 3]; buffer[i * stridesum + 1] = source.Array.Data[i * 3 + 1]; buffer[i * stridesum + 2] = source.Array.Data[i * 3 + 2]; } // For each <input> tag in the triangle offset = 0; foreach (Input input in mesh.Triangles.Inputs) { // Get the <source> tag source = mesh.GetSource(input.Source); if (source == null) { offset += 3; continue; } // For each index in the <p> tag for (int i = 0; i < indexCount; i++) { // Position in the <p> tag int pos = i * mesh.Triangles.Inputs.Count + input.Offset; // For each param in the source for (int sub = 0; sub < source.Technique.Accessor.Stride; sub++) { int index = mesh.Triangles.Data[pos]; float value = source.Array.Data[(index * source.Technique.Accessor.Stride) + sub]; try { //buffer[mesh.Triangles.Data[pos] * stridesum + offset + sub] = value; buffer[index * stridesum + offset + sub] = value; } catch { } } } // offset += source.Technique.Accessor.Stride; } shape.SetIndices(indexbuffer); shape.SetVertices(buffer); return(shape); }
// TODO: Clean up this method, split in smaller parts, update it as more info is available private bool Read(BinaryReader br) { try { Header header = new Header(); header.Read(br); NodesTree nodesTree = new NodesTree(); nodesTree.Read(br); Name = nodesTree.name; br.BaseStream.Seek(header.ContentsTableOffset, SeekOrigin.Begin); ContentsTable contentsTable = new ContentsTable(); contentsTable.Read(br); MaterialsHeader materialsHeader = new MaterialsHeader(); materialsHeader.Read(br); ObjectsTable objectsTable = new ObjectsTable(); objectsTable.SetCount(contentsTable.objectsCount); objectsTable.Read(br); SubObjectsTable subObjectsTable = new SubObjectsTable(); subObjectsTable.SetCount(contentsTable.subObjectsCount); subObjectsTable.Read(br); // In theory, it could be read all the data from current stream position // but it would be safer to read by using the already read offsets // Read the materials table MaterialsTable materialsTable = new MaterialsTable(); materialsTable.SetCount(materialsHeader.materialsCount); br.BaseStream.Seek(materialsHeader.materialsTableOffset, SeekOrigin.Begin); materialsTable.Read(br); // Build the materials list for (int i = 0; i < materialsTable.GetCount(); i++) { Material mat = materialsTable[i].GetMaterial(br); Materials.Add(mat); } // TODO: Read data for all the subobjects // Read data for all the objects for (int i = 0; i < objectsTable.GetCount(); i++) { Model model = new Model(); br.BaseStream.Seek(objectsTable[i].nameAddress, SeekOrigin.Begin); model.name = Text.ReadText(br); if (objectsTable[i].materialDefsAddress != null && objectsTable[i].materialDefsCount > 0) { br.BaseStream.Seek(objectsTable[i].materialDefsAddress.Value, SeekOrigin.Begin); MaterialDef matDef = new MaterialDef(); matDef.Read(br); model.materialIndices = matDef.materialIndices; } if (objectsTable[i].childDefsAddress != null && objectsTable[i].childsDefsCount > 0) { br.BaseStream.Seek(objectsTable[i].childDefsAddress.Value, SeekOrigin.Begin); ChildsDef childsDef = new ChildsDef(); childsDef.SetCount(objectsTable[i].childsDefsCount); childsDef.Read(br); // TODO: Decide how to add it to the model } if (objectsTable[i].data1Address != null && objectsTable[i].data1Count > 0) { List <int> meshesAddress = new List <int>(); br.BaseStream.Seek(objectsTable[i].data1Address.Value, SeekOrigin.Begin); for (int j = 0; j < objectsTable[i].data1Count; j++) { int address = (int)ReadRelativeOffset(br); meshesAddress.Add(address); } for (int j = 0; j < objectsTable[i].data1Count; j++) { br.BaseStream.Seek(meshesAddress[j], SeekOrigin.Begin); Def def = new Def(); if (!def.Read(br)) { return(false); } if (def.nextChunk != null && def.nextChunk is MeshDef) { MeshDef md = (MeshDef)def.nextChunk; for (int k = 0; k < md.meshesData.Count; k++) { MeshData data = md.meshesData[k]; Mesh mesh = new Mesh(data.boundingBox, data.vertices, data.triangles, data.textureVertices); model.meshes.Add(mesh); } } } } Models.Add(model); } } catch { // TODO: Handle here any error reading return(false); } return(true); }