public static ColladaGeometry LoadDAE(string DAE_NAME) { if (!File.Exists(Constants.CacheDir + DAE_NAME + ".engine_cached_model")) { //DEBUG LOGGING DebugTools.Log("[Model Loader]: No cached geometry found, parsing now."); //No Cache, load it the old way var Collada = ColladaDotNet.Collada.Load_File(DAE_NAME); var geometry = ColladaGeometry.LoadGeometries(Collada); //and save the cache geometry.Save(Constants.CacheDir + DAE_NAME + ".engine_cached_model"); return(geometry); } else { return(ColladaGeometry.Load(Constants.CacheDir + DAE_NAME + ".engine_cached_model")); } }
protected override void OnLoad(EventArgs e) { base.OnLoad(e); world = WorldRenderer.Create(ColladaGeometry.LoadDAE("Assets/room.dae")); Box = PhysicsObjectRenderer.Create(ColladaGeometry.LoadDAE("Assets/box.dae")); Box.BuildDisplayList(); InitializeOpenGL(); Mouse.ButtonDown += MouseClick; //build the world world.BuildDisplayList(); world.AddToPhysics(physics_world); icons[0] = ImageLoader.LoadTexture("Assets/InterfaceTextures/AI Spawn.png"); icons[1] = ImageLoader.LoadTexture("Assets/InterfaceTextures/Camera.png"); icons[2] = ImageLoader.LoadTexture("Assets/InterfaceTextures/Physics Spawn.png"); icons[3] = ImageLoader.LoadTexture("Assets/InterfaceTextures/Waypoint Logo.png"); }
public static ColladaGeometry LoadGeometries(ColladaDotNet.Collada Collada) { Matrix4 transform = new Matrix4( 1, 0, 0, 0, //x_x, x_y, x_z, t 0, 1, 0, 0, //y_x, y_y, y_z, t 0, 0, 1, 0, //z_x, z_y, z_z, t 0, 0, 0, 1 ); List <ColladaGeometry> geometries = new List <ColladaGeometry>(); //Build the geometry index Dictionary <String, Collada_Geometry> geometryNodes = new Dictionary <string, Collada_Geometry>(); //DEBUG LOGGING DebugTools.Log("[Model Loader]: Creating Geometry Dictionary"); foreach (Collada_Geometry geometry in Collada.Library_Geometries.Geometry) { geometryNodes.Add("#" + geometry.ID, geometry); //Number sign for easier look ups } //Build the material ID index Dictionary <String, Color> effectIdNodes = new Dictionary <string, Color>(); //DEBUG LOGGING DebugTools.Log("[Model Loader]: Creating Effect Dictionary"); foreach (Collada_Effect effect in Collada.Library_Effects.Effect) { //Check that it's a valid effect if (!(effect.Profile_COMMON[0].Technique.Lambert == null)) { if (effect.Profile_COMMON[0].Technique.Lambert.Diffuse.Color != null) { float[] RGBA = effect.Profile_COMMON[0].Technique.Lambert.Diffuse.Color.Value(); Color color = Color.FromArgb( (int)(RGBA[3] * 255), (int)(RGBA[0] * 255), (int)(RGBA[1] * 255), (int)(RGBA[2] * 255)); if (RGBA.Average() == 0) { color = Color.Black; } effectIdNodes.Add("#" + effect.ID, color); } else { effectIdNodes.Add("#" + effect.ID, Color.Black); } } else { //it might be a constant if (!(effect.Profile_COMMON[0].Technique.Constant == null)) { float[] RGBA = effect.Profile_COMMON[0].Technique.Constant.Transparent.Color.Value(); Color color = Color.FromArgb( (int)(RGBA[3] * 255), (int)(RGBA[0] * 255), (int)(RGBA[1] * 255), (int)(RGBA[2] * 255)); if (RGBA.Average() == 0) { color = Color.Black; } effectIdNodes.Add("#" + effect.ID, color); } else { effectIdNodes.Add("#" + effect.ID, Color.Black); //DEBUG LOGGING DebugTools.Log("[Model Loader]: Effect with ID " + effect.ID + " has an invalid material, assuming black."); } } } //Build the color ID index Dictionary <String, Color> colorNodes = new Dictionary <string, Color>(); //DEBUG LOGGING DebugTools.Log("[Model Loader]: Creating Color Dictionary"); foreach (Collada_Material material in Collada.Library_Materials.Material) { colorNodes.Add("#" + material.ID, effectIdNodes[material.Instance_Effect.URL]); //Resolve the material effect Id } //and build individual geometry nodes //DEBUG LOGGING DebugTools.Log("[Model Loader]: Building Node Dictionary"); Dictionary <String, Collada_Node> nodeNodes = new Dictionary <string, Collada_Node>(); foreach (Collada_Node node in Collada.Library_Visual_Scene.Visual_Scene[0].Node) { recursiveAddNodes(node, ref nodeNodes); } if (Collada.Library_Nodes != null) { foreach (Collada_Node node in Collada.Library_Nodes.Node) { recursiveAddNodes(node, ref nodeNodes); } } DebugTools.Log("[Model Loader]: Parsing Geometry, " + nodeNodes.Count + " nodes."); foreach (Collada_Node node in nodeNodes.Values) { ParseGeometryFromNode(node, transform, ref colorNodes, ref geometries, ref geometryNodes, ref nodeNodes); } //DEBUG LOGGING DebugTools.Log("[Model Loader]: Removing duplicate triangles."); //and output ColladaGeometry outputGeometry = new ColladaGeometry(); //and finally, merge all of the geometries into one single one foreach (ColladaGeometry geometry in geometries) { outputGeometry.geometryLines.AddRange(geometry.geometryLines); outputGeometry.triangles.AddRange(geometry.triangles); } int preOptimization = outputGeometry.triangles.Count; int i = 0; if (outputGeometry.triangles.Count < 100000) { do { //DEBUG LOGGING DebugTools.Log("[Model Loader]: Parsed " + i + "/" + outputGeometry.triangles.Count); List <Triangle> removeList = new List <Triangle>(); foreach (Triangle t in outputGeometry.triangles) { var x1 = outputGeometry.triangles[i].vertices[0].X + outputGeometry.triangles[i].vertices[1].X + outputGeometry.triangles[i].vertices[2].X; var y1 = outputGeometry.triangles[i].vertices[0].Y + outputGeometry.triangles[i].vertices[1].Y + outputGeometry.triangles[i].vertices[2].Y; var z1 = outputGeometry.triangles[i].vertices[0].Z + outputGeometry.triangles[i].vertices[1].Z + outputGeometry.triangles[i].vertices[2].Z; var x2 = t.vertices[0].X + t.vertices[1].X + t.vertices[2].X; var y2 = t.vertices[0].Y + t.vertices[1].Y + t.vertices[2].Y; var z2 = t.vertices[0].Z + t.vertices[1].Z + t.vertices[2].Z; if (x1 == x2 & y1 == y2 & z1 == z2 & !outputGeometry.triangles[i].Equals(t)) { //DEBUG LOGGING DebugTools.Log("[Model Loader]: Clipping triangles - {" + t.vertices[0].X.ToString("N1") + "," + t.vertices[0].Y.ToString("N1") + "," + t.vertices[0].Z.ToString("N1") + "}{" + t.vertices[0].X.ToString("N1") + "," + t.vertices[1].Y.ToString("N1") + "," + t.vertices[2].Z.ToString("N1") + "}{" + t.vertices[0].X.ToString("N1") + "," + t.vertices[1].Y.ToString("N1") + "," + t.vertices[2].Z.ToString("N1") + "}"); removeList.Add(t); break; //Usually only one duplicate } } foreach (Triangle t in removeList) { outputGeometry.triangles.Remove(t); } i++; } while (i < outputGeometry.triangles.Count); } else { //DEBUG LOGGING DebugTools.Log("[Model Loader]: Skipping polygon optimization, too many triangles to do so."); } //DEBUG LOGGING DebugTools.Log("[Model Loader]: Pre-optimization: " + preOptimization + " tri's, Post-optimization: " + outputGeometry.triangles.Count + " tri's"); DebugTools.Log("[Model Loader]: Lines: " + outputGeometry.geometryLines.Count); //DEBUG LOGGING DebugTools.Log("[Model Loader]: Shifting geometry to center."); var min = new Vector3(99999999999, 999999999999, 99999999999); var max = new Vector3(0, 0, 0); foreach (Triangle tri in outputGeometry.triangles) { foreach (Vector3 vertex in tri.vertices) { if (vertex.X < min.X) { min.X = vertex.X; } if (vertex.Y < min.Y) { min.Y = vertex.Y; } if (vertex.Z < min.Z) { min.Z = vertex.Z; } if (vertex.X > max.X) { max.X = vertex.X; } if (vertex.Y > max.Y) { max.Y = vertex.Y; } if (vertex.Z > max.Z) { max.Z = vertex.Z; } } } Vector3 shiftVector = new Vector3((max + min) / 2); //DEBUG LOGGING DebugTools.Log("[Model Loader]: Shifting Model by " + shiftVector.ToString()); foreach (Triangle tri in outputGeometry.triangles) { tri.vertices[0] = tri.vertices[0] - shiftVector; tri.vertices[1] = tri.vertices[1] - shiftVector; tri.vertices[2] = tri.vertices[2] - shiftVector; } foreach (GeometryLine line in outputGeometry.geometryLines) { line.vertices[0] = line.vertices[0] - shiftVector; line.vertices[1] = line.vertices[1] - shiftVector; } //and return return(outputGeometry); }
public static ColladaGeometry parseGeometry(Matrix4 transform, Collada_Geometry geometry, Dictionary <string, Color> colors) { //Parse all of the geometry ColladaGeometry geom = new ColladaGeometry(); //get the raw geometry float[] Vertices = geometry.Mesh.Source[0].Float_Array.Value(); float[] Normals = { }; if (geometry.Mesh.Source.Length > 1) { Normals = geometry.Mesh.Source[1].Float_Array.Value(); //the normals } //build the vertex and normal lookup table List <Vector3> vertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); //and parse for (int i = 0; i < Vertices.Length; i += 3) { Vector3 vertex = new Vector3(Vertices[i], Vertices[i + 1], Vertices[i + 2]).MultiplyByMatrix4(transform); if (geometry.Mesh.Source.Length > 1) { Vector3 normal = new Vector3(Normals[i], Normals[i + 1], Normals[i + 2]); //.MultiplyByMatrix3x4(transform); normals.Add(normal); } //add to list vertices.Add(vertex); } //and now construct triangle geometry from that if (!(geometry.Mesh.Triangles == null)) { foreach (Collada_Triangles t in geometry.Mesh.Triangles) { int[] geometryIds = t.P.Value(); //and parse the list through the lookup table for (int i = 0; i < geometryIds.Length; i += 3) { Triangle tri = new Triangle(); tri.vertices[0] = vertices[geometryIds[i]]; tri.normals[0] = normals[geometryIds[i]]; tri.vertices[1] = vertices[geometryIds[i + 1]]; tri.normals[1] = normals[geometryIds[i + 1]]; tri.vertices[2] = vertices[geometryIds[i + 2]]; tri.normals[2] = normals[geometryIds[i + 2]]; //color tri.color = colors[t.Material]; //and add it to the triangles list geom.triangles.Add(tri); } } } else { //DEBUG LOGGING //PRINT THE GEOMETRY ID IF NO TRIANGLES DebugTools.Log("[Model Loader]: No triangles in geometry with ID " + geometry.ID); } if (!(geometry.Mesh.Lines == null)) { //and now the lines... int[] lineIds = geometry.Mesh.Lines[0].P.Value(); //and parse the list through the lookup table for (int i = 0; i < lineIds.Length; i += 2) { GeometryLine line = new GeometryLine(); //build the vertex list line.vertices[0] = vertices[lineIds[i]]; line.vertices[1] = vertices[lineIds[i + 1]]; //and add it to the lines list geom.geometryLines.Add(line); } } else { //DEBUG LOGGING //PRINT THE GEOMETRY ID IF NO LINES DebugTools.Log("[Model Loader]: No lines in geometry with ID " + geometry.ID); } return(geom); }