/// <summary> /// Parses the face-specific polygonal data from the current data segment. /// </summary> /// <param name="dataSegment"> /// Contains the data to be parsed. /// </param> protected void ParseFaceData(DataReader3DS dataSegment) { int i; // counter DataReader3DS subSegment; // will be used to read other subsegments (do not initialize yet) this.currentMeshData.Faces = new MeshData3DS.FaceData3DS[dataSegment.GetUShort()]; // Read face data for (i = 0; i < this.currentMeshData.Faces.Length; i++) { this.currentMeshData.Faces[i].Vertex1 = dataSegment.GetUShort(); this.currentMeshData.Faces[i].Vertex2 = dataSegment.GetUShort(); this.currentMeshData.Faces[i].Vertex3 = dataSegment.GetUShort(); this.currentMeshData.Faces[i].Flags = dataSegment.GetUShort(); } // Read other subsegments subSegment = dataSegment.GetNextSubSegment(); while (subSegment != null) { switch (subSegment.Tag) { case 0x4130: // Name of material used this.currentMeshData.MaterialUsed = subSegment.GetString(); break; } subSegment = dataSegment.GetNextSubSegment(); } }
/// <summary> /// Parses the mesh data from the current data segment. /// </summary> /// <param name="dataSegment"> /// Contains the data to be parsed. /// </param> protected void ParseMeshData(DataReader3DS dataSegment) { string name = dataSegment.GetString(); // mesh object name DataReader3DS subSegment = dataSegment.GetNextSubSegment(); // working subsegment this.currentMeshData = new MeshData3DS(); this.currentMeshData.Name = name; while (subSegment != null) { switch (subSegment.Tag) { case 0x4100: // Current subsegment contains the polygonal information this.ParsePolygonalData(subSegment); break; default: // Ignore all other subsegment types break; } subSegment = dataSegment.GetNextSubSegment(); } while (this.meshDataStore.ContainsKey(this.currentMeshData.Name)) { this.currentMeshData.Name += "X"; } this.meshDataStore.Add(this.currentMeshData.Name, this.currentMeshData); }
/// <summary> /// Parses the polygonal data from the current data segment. /// </summary> /// <param name="dataSegment"> /// Contains the data to be parsed. /// </param> protected void ParsePolygonalData(DataReader3DS dataSegment) { int i; // counter DataReader3DS subSegment = dataSegment.GetNextSubSegment(); // working data subsegment while (subSegment != null) { switch (subSegment.Tag) { case 0x4110: // Subsegment contains vertex information this.currentMeshData.Vertices = new Point3D[subSegment.GetUShort()]; for (i = 0; i < this.currentMeshData.Vertices.Length; i++) { this.currentMeshData.Vertices[i].X = subSegment.GetFloat(); this.currentMeshData.Vertices[i].Y = subSegment.GetFloat(); this.currentMeshData.Vertices[i].Z = subSegment.GetFloat(); } break; case 0x4160: // Subsegment contains translation matrix info (ignore for now) break; case 0x4120: // Subsegment contains face information this.ParseFaceData(subSegment); break; case 0x4140: // Subsegment contains texture mapping information this.currentMeshData.TextureCoordinates = new Point2D[subSegment.GetUShort()]; //HACK: This is because the above array allocation doesn't automatically //HACK: create each element. for (i = 0; i < this.currentMeshData.TextureCoordinates.Length; i++) { this.currentMeshData.TextureCoordinates[i] = new Point2D(); } //HACK: End hack. if (this.currentMeshData.TextureCoordinates.Length != this.currentMeshData.Vertices.Length) { Console.WriteLine("WARNING: Possible errors in texture coordinate mapping!"); } for (i = 0; i < this.currentMeshData.TextureCoordinates.Length; i++) { this.currentMeshData.TextureCoordinates[i].X = subSegment.GetFloat(); this.currentMeshData.TextureCoordinates[i].Y = subSegment.GetFloat(); } break; } subSegment = dataSegment.GetNextSubSegment(); } // Also use face data to calculate vertex normals this.CalculateVertexNormals(); }
/// <summary> /// Parses the 3DS data stream into mesh and material information. /// </summary> /// <param name="dataSegment"> /// Contains the data to be parsed. /// </param> protected void ParseData(DataReader3DS dataSegment) { DataReader3DS subSegment = dataSegment.GetNextSubSegment(); while (subSegment != null) { switch (subSegment.Tag) { case 0xafff: // Current subsegment holds material data this.ParseMaterialData(subSegment); break; case 0x4000: // Current subsegment holds mesh data this.ParseMeshData(subSegment); break; } subSegment = dataSegment.GetNextSubSegment(); } }
/// <summary> /// Parses the material data from the current data segment. /// </summary> /// <param name="dataSegment"> /// Contains the data to be parsed. /// </param> protected void ParseMaterialData(DataReader3DS dataSegment) { DataReader3DS subSegment = dataSegment.GetNextSubSegment(); this.currentMaterialData = new MaterialData3DS(); while (subSegment != null) { switch (subSegment.Tag) { case 0xa000: // Subsegment holds material name this.currentMaterialData.name = subSegment.GetString(); Console.WriteLine("Material is named: " + this.currentMaterialData.name); break; case 0xa010: // Subsegment holds ambient color this.currentMaterialData.ambient = this.ParseColorData(subSegment.GetNextSubSegment()); break; case 0xa020: // Subsegment holds diffuse color (this is iffy...) this.currentMaterialData.diffuse = this.ParseColorData(subSegment.GetNextSubSegment()); break; case 0xa200: // Subsegment holds texture map info this.ParseTextureWeight(subSegment.GetNextSubSegment()); this.currentMaterialData.textureName = subSegment.GetNextSubSegment().GetString(); break; default: // Ignore all other subsegment types break; } subSegment = dataSegment.GetNextSubSegment(); } // Store newly created material in data store and change name if another exists with its name while (this.materialDataStore.ContainsKey(this.currentMaterialData.name)) { this.currentMaterialData.name += "X"; } this.materialDataStore.Add(this.currentMaterialData.name, this.currentMaterialData); }