/// <summary> /// Loads model data. /// </summary> /// <param name="id">Key of source mesh.</param> /// <param name="modelData">ModelData out.</param> /// <param name="scale">Scale of model.</param> /// <returns>True if successful.</returns> public bool GetModelData(uint id, out ModelData modelData) { // New model object modelData = new ModelData(); // Ready check if (!IsReady) { return(false); } // Return from cache if present if (modelDict.ContainsKey((int)id)) { modelData = modelDict[(int)id]; return(true); } // Find mesh index int index = arch3dFile.GetRecordIndex(id); if (index == -1) { return(false); } // Get DFMesh DFMesh dfMesh = arch3dFile.GetMesh(index); if (dfMesh.TotalVertices == 0) { return(false); } // Load mesh data modelData.DFMesh = dfMesh; LoadVertices(ref modelData, GlobalScale); LoadIndices(ref modelData); // Add to cache modelDict.Add((int)id, modelData); return(true); }
private void LoadVertices(ref ModelData model, float scale) { const int BuildingDoors = 74; const int DungeonEnterDoors = 56; const int DungeonRuinEnterDoors = 331; const int DungeonExitDoors = 95; //const int dungeonFloorRecord = 2; // Allocate arrays model.Vertices = new Vector3[model.DFMesh.TotalVertices]; model.Normals = new Vector3[model.DFMesh.TotalVertices]; model.UVs = new Vector2[model.DFMesh.TotalVertices]; // Static door and dungeon floor lists List <ModelDoor> modelDoors = new List <ModelDoor>(); //List<DFMesh.DFPlane> dungeonFloors = new List<DFMesh.DFPlane>(); // Loop through all submeshes int vertexCount = 0; foreach (DFMesh.DFSubMesh dfSubMesh in model.DFMesh.SubMeshes) { // Get cached material data CachedMaterial cm; dfUnity.MaterialReader.GetCachedMaterial(dfSubMesh.TextureArchive, dfSubMesh.TextureRecord, 0, out cm); Vector2 sz = cm.recordSizes[0]; // Get texture archive for this submesh as base climate int submeshTextureArchive = dfSubMesh.TextureArchive; int baseTextureArchive = (submeshTextureArchive - (submeshTextureArchive / 100) * 100); // Get base climate archive for door check // All base door textures are > 100, except dungeon ruins doors int doorArchive = submeshTextureArchive; if (doorArchive > 100 && doorArchive != DungeonRuinEnterDoors) { doorArchive = baseTextureArchive; } // Check if this is a door archive bool doorFound = false; DoorTypes doorType = DoorTypes.None; switch (doorArchive) { case BuildingDoors: doorFound = true; doorType = DoorTypes.Building; break; case DungeonEnterDoors: doorFound = true; doorType = DoorTypes.DungeonEntrance; break; case DungeonRuinEnterDoors: if (dfSubMesh.TextureRecord > 0) // Dungeon ruins index 0 is just a stone texture { doorFound = true; doorType = DoorTypes.DungeonEntrance; } break; case DungeonExitDoors: doorFound = true; doorType = DoorTypes.DungeonExit; break; } //// Check if this is a dungeon floor //bool dungeonFloorFound = false; //if (baseTextureArchive >= 19 && baseTextureArchive <= 24 && dfSubMesh.TextureRecord == dungeonFloorRecord) // dungeonFloorFound = true; // Loop through all planes in this submesh int doorCount = 0; foreach (DFMesh.DFPlane dfPlane in dfSubMesh.Planes) { // If this is a door then each plane is a single door if (doorFound) { // Set door verts DFMesh.DFPoint p0 = dfPlane.Points[0]; DFMesh.DFPoint p1 = dfPlane.Points[1]; DFMesh.DFPoint p2 = dfPlane.Points[2]; ModelDoor modelDoor = new ModelDoor() { Index = doorCount++, Type = doorType, Vert0 = new Vector3(p0.X, -p0.Y, p0.Z) * scale, Vert1 = new Vector3(p1.X, -p1.Y, p1.Z) * scale, Vert2 = new Vector3(p2.X, -p2.Y, p2.Z) * scale, }; // Set door normal Vector3 u = modelDoor.Vert0 - modelDoor.Vert2; Vector3 v = modelDoor.Vert0 - modelDoor.Vert1; modelDoor.Normal = Vector3.Normalize(Vector3.Cross(u, v)); // Add door to list modelDoors.Add(modelDoor); } //// If this a floor then store the polygon //if (dungeonFloorFound) // dungeonFloors.Add(dfPlane); // Copy each point in this plane to vertex buffer foreach (DFMesh.DFPoint dfPoint in dfPlane.Points) { // Position and normal Vector3 position = new Vector3(dfPoint.X, -dfPoint.Y, dfPoint.Z) * scale; Vector3 normal = new Vector3(dfPoint.NX, -dfPoint.NY, dfPoint.NZ); // Store vertex data model.Vertices[vertexCount] = position; model.Normals[vertexCount] = Vector3.Normalize(normal); model.UVs[vertexCount] = new Vector2((dfPoint.U / sz.x), -(dfPoint.V / sz.y)); // Inrement count vertexCount++; } } } // Assign found doors model.Doors = modelDoors.ToArray(); //model.DungeonFloors = dungeonFloors.ToArray(); }
private void LoadIndices(ref ModelData model) { // Allocate model data submesh buffer model.SubMeshes = new ModelData.SubMeshData[model.DFMesh.SubMeshes.Length]; // Allocate index buffer model.Indices = new int[model.DFMesh.TotalTriangles * 3]; // Iterate through all submeshes short indexCount = 0; short subMeshCount = 0, vertexCount = 0; foreach (DFMesh.DFSubMesh dfSubMesh in model.DFMesh.SubMeshes) { // Set start index and primitive count for this submesh model.SubMeshes[subMeshCount].StartIndex = indexCount; model.SubMeshes[subMeshCount].PrimitiveCount = dfSubMesh.TotalTriangles; model.SubMeshes[subMeshCount].TextureArchive = dfSubMesh.TextureArchive; model.SubMeshes[subMeshCount].TextureRecord = dfSubMesh.TextureRecord; // Iterate through all planes in this submesh foreach (DFMesh.DFPlane dfPlane in dfSubMesh.Planes) { // Every DFPlane is a triangle fan radiating from point 0 int sharedPoint = vertexCount++; // Index remaining points. There are (plane.Points.Length - 2) triangles in every plane for (int tri = 0; tri < dfPlane.Points.Length - 2; tri++) { // Store 3 points of current triangle model.Indices[indexCount++] = sharedPoint; model.Indices[indexCount++] = vertexCount + 1; model.Indices[indexCount++] = vertexCount; // Increment vertexCount to next point in fan vertexCount++; } // Increment vertexCount to start of next fan in vertex buffer vertexCount++; } // Increment submesh count subMeshCount++; } }
private void LoadVertices(ref ModelData model, float scale) { const int BuildingDoors = 74; const int DungeonEnterDoors = 56; const int DungeonRuinEnterDoors = 331; const int DungeonExitDoors = 95; // Allocate arrays model.Vertices = new Vector3[model.DFMesh.TotalVertices]; model.Normals = new Vector3[model.DFMesh.TotalVertices]; model.UVs = new Vector2[model.DFMesh.TotalVertices]; // Door list List<ModelDoor> modelDoors = new List<ModelDoor>(); // Loop through all submeshes int vertexCount = 0; foreach (DFMesh.DFSubMesh dfSubMesh in model.DFMesh.SubMeshes) { // Get cached material data CachedMaterial cm; dfUnity.MaterialReader.GetCachedMaterial(dfSubMesh.TextureArchive, dfSubMesh.TextureRecord, 0, out cm); Vector2 sz = cm.recordSizes[0]; // Get base climate archive for door check // All base door textures are < 100, except dungeon ruins doors int doorArchive = dfSubMesh.TextureArchive; if (doorArchive > 100 && doorArchive != DungeonRuinEnterDoors) { // Reduce to base texture set // This shifts all building climate doors to the same index ClimateTextureInfo ci = ClimateSwaps.GetClimateTextureInfo(dfSubMesh.TextureArchive); doorArchive = (int)ci.textureSet; } // Check if this is a door archive bool doorFound = false; DoorTypes doorType = DoorTypes.None; switch (doorArchive) { case BuildingDoors: doorFound = true; doorType = DoorTypes.Building; break; case DungeonEnterDoors: doorFound = true; doorType = DoorTypes.DungeonEntrance; break; case DungeonRuinEnterDoors: if (dfSubMesh.TextureRecord > 0) // Dungeon ruins index 0 is just a stone texture { doorFound = true; doorType = DoorTypes.DungeonEntrance; } break; case DungeonExitDoors: doorFound = true; doorType = DoorTypes.DungeonExit; break; } // Loop through all planes in this submesh int doorCount = 0; foreach (DFMesh.DFPlane dfPlane in dfSubMesh.Planes) { // If this is a door then each plane is a single door if (doorFound) { // Set door verts DFMesh.DFPoint p0 = dfPlane.Points[0]; DFMesh.DFPoint p1 = dfPlane.Points[1]; DFMesh.DFPoint p2 = dfPlane.Points[2]; ModelDoor modelDoor = new ModelDoor() { Index = doorCount++, Type = doorType, Vert0 = new Vector3(p0.X, -p0.Y, p0.Z) * scale, Vert1 = new Vector3(p1.X, -p1.Y, p1.Z) * scale, Vert2 = new Vector3(p2.X, -p2.Y, p2.Z) * scale, }; // Set door normal Vector3 u = modelDoor.Vert0 - modelDoor.Vert2; Vector3 v = modelDoor.Vert0 - modelDoor.Vert1; modelDoor.Normal = Vector3.Normalize(Vector3.Cross(u, v)); // Add door to list modelDoors.Add(modelDoor); } // Copy each point in this plane to vertex buffer foreach (DFMesh.DFPoint dfPoint in dfPlane.Points) { // Position and normal Vector3 position = new Vector3(dfPoint.X, -dfPoint.Y, dfPoint.Z) * scale; Vector3 normal = new Vector3(dfPoint.NX, -dfPoint.NY, dfPoint.NZ); // Store vertex data model.Vertices[vertexCount] = position; model.Normals[vertexCount] = Vector3.Normalize(normal); model.UVs[vertexCount] = new Vector2((dfPoint.U / sz.x), -(dfPoint.V / sz.y)); // Inrement count vertexCount++; } } } // Assign found doors model.Doors = modelDoors.ToArray(); }
/// <summary> /// Loads model data. /// </summary> /// <param name="id">Key of source mesh.</param> /// <param name="modelData">ModelData out.</param> /// <param name="scale">Scale of model.</param> /// <returns>True if successful.</returns> public bool GetModelData(uint id, out ModelData modelData) { // New model object modelData = new ModelData(); // Ready check if (!IsReady) return false; // Return from cache if present if (modelDict.ContainsKey((int)id)) { modelData = modelDict[(int)id]; return true; } // Find mesh index int index = arch3dFile.GetRecordIndex(id); if (index == -1) return false; // Get DFMesh DFMesh dfMesh = arch3dFile.GetMesh(index); if (dfMesh.TotalVertices == 0) return false; // Load mesh data modelData.DFMesh = dfMesh; LoadVertices(ref modelData, GlobalScale); LoadIndices(ref modelData); // Add to cache modelDict.Add((int)id, modelData); return true; }