static ThreeDSFileData ParseFromData(DataReader3DS data) { DataReader3DS dataSubSegment = null; if ((ChunkCodes)data.Tag == ChunkCodes.PRIMARY) { dataSubSegment = data.GetNextSubSegment(); } else return null; ThreeDSFileData file = new ThreeDSFileData(); while (dataSubSegment != null) { // Check the tag to see what sort of data is in this subsegment (or "chunk") switch ((ChunkCodes)dataSubSegment.Tag) { case ChunkCodes.VERSION: file.version = dataSubSegment.GetUShort(); break; case ChunkCodes.EDIT3DS: Parse3DSData(dataSubSegment, file); break; default: break; } dataSubSegment = data.GetNextSubSegment(); } return file; }
/// <summary> /// Moves to the next subsegment of data in the data stream. /// </summary> /// <returns>Returns the next subsegment of data in the data stream.</returns> public DataReader3DS GetNextSubSegment() { if (currentSegment.BaseStream.Position > 3700000) { System.Diagnostics.Debug.WriteLine("Breaking..."); } if ((ulong)currentSegment.BaseStream.Position < (size - HeaderSize)) { if (currentSubSegment != null) { currentSegment.BaseStream.Position += (long)currentSubSegment.Size; currentSubSegment = null; } //currentSubSegment = new DataReader3DS(sourceData, // (int)currentSegment.BaseStream.Position, // (int)(currentSegment.BaseStream.Length - currentSegment.BaseStream.Position)); if ((currentSegment.BaseStream.Length - currentSegment.BaseStream.Position) > 0) { currentSubSegment = new DataReader3DS(sourceData, (int)(myStreamOffset + (ulong)currentSegment.BaseStream.Position), (int)(currentSegment.BaseStream.Length - currentSegment.BaseStream.Position)); } } else { currentSubSegment = null; } return(currentSubSegment); }
private static ThreeDSObject ParseMeshData(DataReader3DS dataSegment) { string name = dataSegment.GetString(); DataReader3DS subSegment = dataSegment.GetNextSubSegment(); ThreeDSObject obj = new ThreeDSObject(); obj.name = name; while (subSegment != null) { switch ((ChunkCodes)subSegment.Tag) { case ChunkCodes.OBJ_MESH: // Current subsegment contains the polygonal information obj.meshes.Add(ParsePolygonalData(subSegment)); break; default: // Ignore all other subsegment types break; } subSegment = dataSegment.GetNextSubSegment(); } return(obj); }
private static ThreeDSMesh.FaceGroup ParseFaceData(DataReader3DS dataSegment) { DataReader3DS subSegment; // will be used to read other subsegments (do not initialize yet) ThreeDSMesh.FaceGroup group = new ThreeDSMesh.FaceGroup(); group.faces = new ThreeDSMesh.Face[dataSegment.GetUShort()]; // Read face data for (int face = 0; face < group.faces.Length; face++) { group.faces[face].p1 = dataSegment.GetUShort(); group.faces[face].p2 = dataSegment.GetUShort(); group.faces[face].p3 = dataSegment.GetUShort(); // Ignore flag dataSegment.GetUShort(); } // Read other subsegments subSegment = dataSegment.GetNextSubSegment(); while (subSegment != null) { switch ((ChunkCodes)subSegment.Tag) { case ChunkCodes.MESH_MATER: // Name of material used group.mappings.Add(ParseMeshMaterial(subSegment)); break; case ChunkCodes.TRI_SMOOTH: break; } subSegment = dataSegment.GetNextSubSegment(); } return(group); }
/// <summary> /// Creates a DataReader3DS object. /// </summary> /// <param name="inputData">Contains array of data bytes.</param> public DataReader3DS(byte[] inputData) { sourceData = inputData; myStreamOffset = 0; sourceStream = new MemoryStream(sourceData); dataReader = new BinaryReader(sourceStream); tag = dataReader.ReadUInt16(); size = (ulong)dataReader.ReadInt32(); currentSubSegment = null; currentSegment = dataReader; }
/// <summary> /// Internal constructor that creates a DataReader3DS object. /// </summary> /// <param name="inputData">Contains array of data bytes.</param> /// <param name="startingPoint">Specified starting location.</param> /// <param name="length">Specified length.</param> protected DataReader3DS(byte[] inputData, int startingPoint, int length) { sourceData = inputData; myStreamOffset = (ulong)startingPoint; sourceStream = new MemoryStream(sourceData, startingPoint, length); dataReader = new BinaryReader(sourceStream); tag = dataReader.ReadUInt16(); size = (ulong)dataReader.ReadInt32(); currentSubSegment = null; currentSegment = dataReader; }
private static ThreeDSMesh.Material ParseMaterialData(DataReader3DS dataSegment) { DataReader3DS subSegment = dataSegment.GetNextSubSegment(); ThreeDSMesh.Material mat = new ThreeDSMesh.Material(); while (subSegment != null) { switch ((ChunkCodes)subSegment.Tag) { case ChunkCodes.MAT_NAME: // Subsegment holds material name mat.name = subSegment.GetString(); break; case ChunkCodes.MAT_AMBIENT: // Subsegment holds ambient color mat.ambient = ParseColorData(subSegment.GetNextSubSegment()); break; case ChunkCodes.MAT_DIFFUSE: // Subsegment holds diffuse color (this is iffy...) mat.diffuse = ParseColorData(subSegment.GetNextSubSegment()); break; case ChunkCodes.MAT_TEXMAP: // Subsegment holds texture map info /*ParseTextureWeight(*/ subSegment.GetNextSubSegment(); mat.texture = subSegment.GetNextSubSegment().GetString(); break; default: // Ignore all other subsegment types break; } subSegment = dataSegment.GetNextSubSegment(); } // Check if this is a duplicate material entry (by name) // NOTE: Duplicate material name update should be in form materialname_submeshname /*if (materialDataStore.ContainsKey(currentMaterialData.name)) * { * // Select an "owning" submesh for the material * referencingSubmeshes = (ArrayList)(submeshesUsingMaterials[currentMaterialData.name]); * owningSubmesh = (SubmeshData3DS)(referencingSubmeshes[referencingSubmeshes.Count - 1]); * // Qualify the material name with the submesh's name as well (see above note) * currentMaterialData.name = currentMaterialData.name + "_" + owningSubmesh.name; * owningSubmesh.materialUsed = currentMaterialData.name; * // Clean up and update submesh reference lists * referencingSubmeshes.RemoveAt(referencingSubmeshes.Count - 1); * referencingSubmeshes = new ArrayList(); * referencingSubmeshes.Add(owningSubmesh); * submeshesUsingMaterials.Add(currentMaterialData.name, referencingSubmeshes); * }*/ return(mat); }
private static ThreeDSMesh.UV[] ParseTexVerts(DataReader3DS subSegment) { ThreeDSMesh.UV[] uv = new ThreeDSMesh.UV[subSegment.GetUShort()]; for (int coord = 0; coord < uv.Length; coord++) { uv[coord].u = subSegment.GetFloat(); uv[coord].v = subSegment.GetFloat(); } return(uv); }
private static ThreeDSMesh.MaterialMapping ParseMeshMaterial(DataReader3DS subSegment) { ThreeDSMesh.MaterialMapping mapping = new ThreeDSMesh.MaterialMapping(); mapping.name = subSegment.GetString(); // Read mapped faces mapping.mappedFaces = new ushort[subSegment.GetUShort()]; for (int face = 0; face < mapping.mappedFaces.Length; face++) { mapping.mappedFaces[face] = subSegment.GetUShort(); } return(mapping); }
protected const ushort HeaderSize = 6; // = (size of 'tag') + (size of 'size') #endregion #region Constructor(s) public DataReader3DS(string filename) { FileStream file = new FileStream(filename, FileMode.Open); byte[] data = new byte[file.Length]; file.Read(data, 0, (int)file.Length); file.Close(); sourceData = data; myStreamOffset = 0; sourceStream = new MemoryStream(sourceData); dataReader = new BinaryReader(sourceStream); tag = dataReader.ReadUInt16(); size = (ulong)dataReader.ReadInt32(); currentSubSegment = null; currentSegment = dataReader; }
private static void Parse3DSData(DataReader3DS dataSegment, ThreeDSFileData file) { DataReader3DS subSegment = dataSegment.GetNextSubSegment(); while (subSegment != null) { switch ((ChunkCodes)subSegment.Tag) { case ChunkCodes.MATERIAL: file.materials.Add(ParseMaterialData(subSegment)); break; case ChunkCodes.NAMED_OBJECT: file.objects.Add(ParseMeshData(subSegment)); break; default: break; } subSegment = dataSegment.GetNextSubSegment(); } }
private static ThreeDSMesh ParsePolygonalData(DataReader3DS dataSegment) { DataReader3DS subSegment = dataSegment.GetNextSubSegment(); // working data subsegment ThreeDSMesh mesh = new ThreeDSMesh(); while (subSegment != null) { switch ((ChunkCodes)subSegment.Tag) { case ChunkCodes.MESH_VERTICES: // Subsegment contains vertex information mesh.verticies = new ThreeDSMesh.Vertex[subSegment.GetUShort()]; for (int vertex = 0; vertex < mesh.verticies.Length; vertex++) { mesh.verticies[vertex].x = subSegment.GetFloat(); mesh.verticies[vertex].y = subSegment.GetFloat(); mesh.verticies[vertex].z = subSegment.GetFloat(); } break; case ChunkCodes.MESH_XFMATRIX: // Subsegment contains translation matrix info (ignore for now) break; case ChunkCodes.MESH_FACES: // Subsegment contains face information mesh.groups.Add(ParseFaceData(subSegment)); break; case ChunkCodes.MESH_TEX_VERT: // Subsegment contains texture mapping information mesh.uvMap = ParseTexVerts(subSegment); break; } subSegment = dataSegment.GetNextSubSegment(); } // Also use face data to calculate vertex normals CalculateVertexNormals(mesh); return(mesh); }
private static ThreeDSMesh.Colour ParseColorData(DataReader3DS dataSegment) { ThreeDSMesh.Colour clr = new ThreeDSMesh.Colour(); switch ((ChunkCodes)dataSegment.Tag) { case ChunkCodes.COLOR_F: // Color is in float format clr.r = (byte)(1.0f / dataSegment.GetFloat()); clr.g = (byte)(1.0f / dataSegment.GetFloat()); clr.b = (byte)(1.0f / dataSegment.GetFloat()); break; case ChunkCodes.COLOR_24: // Color is in byte format clr.r = dataSegment.GetByte(); clr.g = dataSegment.GetByte(); clr.b = dataSegment.GetByte(); break; default: // If there are any other formats, then we ignore them break; } return(clr); }
static ThreeDSFileData ParseFromData(DataReader3DS data) { DataReader3DS dataSubSegment = null; if ((ChunkCodes)data.Tag == ChunkCodes.PRIMARY) { dataSubSegment = data.GetNextSubSegment(); } else { return(null); } ThreeDSFileData file = new ThreeDSFileData(); while (dataSubSegment != null) { // Check the tag to see what sort of data is in this subsegment (or "chunk") switch ((ChunkCodes)dataSubSegment.Tag) { case ChunkCodes.VERSION: file.version = dataSubSegment.GetUShort(); break; case ChunkCodes.EDIT3DS: Parse3DSData(dataSubSegment, file); break; default: break; } dataSubSegment = data.GetNextSubSegment(); } return(file); }
/// <summary> /// Moves to the next subsegment of data in the data stream. /// </summary> /// <returns>Returns the next subsegment of data in the data stream.</returns> public DataReader3DS GetNextSubSegment() { if (currentSegment.BaseStream.Position > 3700000) System.Diagnostics.Debug.WriteLine("Breaking..."); if ((ulong)currentSegment.BaseStream.Position < (size - HeaderSize)) { if (currentSubSegment != null) { currentSegment.BaseStream.Position += (long)currentSubSegment.Size; currentSubSegment = null; } //currentSubSegment = new DataReader3DS(sourceData, // (int)currentSegment.BaseStream.Position, // (int)(currentSegment.BaseStream.Length - currentSegment.BaseStream.Position)); if ((currentSegment.BaseStream.Length - currentSegment.BaseStream.Position) > 0) { currentSubSegment = new DataReader3DS(sourceData, (int)(myStreamOffset + (ulong)currentSegment.BaseStream.Position), (int)(currentSegment.BaseStream.Length - currentSegment.BaseStream.Position)); } } else { currentSubSegment = null; } return currentSubSegment; }
public static ThreeDSFileData ParseFromFile(string file) { DataReader3DS data = new DataReader3DS(file); return ParseFromData(data); }
private static ThreeDSMesh.Colour ParseColorData(DataReader3DS dataSegment) { ThreeDSMesh.Colour clr = new ThreeDSMesh.Colour(); switch ((ChunkCodes)dataSegment.Tag) { case ChunkCodes.COLOR_F: // Color is in float format clr.r = (byte)(1.0f / dataSegment.GetFloat()); clr.g = (byte)(1.0f / dataSegment.GetFloat()); clr.b = (byte)(1.0f / dataSegment.GetFloat()); break; case ChunkCodes.COLOR_24: // Color is in byte format clr.r = dataSegment.GetByte(); clr.g = dataSegment.GetByte(); clr.b = dataSegment.GetByte(); break; default: // If there are any other formats, then we ignore them break; } return clr; }
private static ThreeDSMesh.Material ParseMaterialData(DataReader3DS dataSegment) { DataReader3DS subSegment = dataSegment.GetNextSubSegment(); ThreeDSMesh.Material mat = new ThreeDSMesh.Material(); while (subSegment != null) { switch ((ChunkCodes)subSegment.Tag) { case ChunkCodes.MAT_NAME: // Subsegment holds material name mat.name = subSegment.GetString(); break; case ChunkCodes.MAT_AMBIENT: // Subsegment holds ambient color mat.ambient = ParseColorData(subSegment.GetNextSubSegment()); break; case ChunkCodes.MAT_DIFFUSE: // Subsegment holds diffuse color (this is iffy...) mat.diffuse = ParseColorData(subSegment.GetNextSubSegment()); break; case ChunkCodes.MAT_TEXMAP: // Subsegment holds texture map info /*ParseTextureWeight(*/subSegment.GetNextSubSegment(); mat.texture = subSegment.GetNextSubSegment().GetString(); break; default: // Ignore all other subsegment types break; } subSegment = dataSegment.GetNextSubSegment(); } // Check if this is a duplicate material entry (by name) // NOTE: Duplicate material name update should be in form materialname_submeshname /*if (materialDataStore.ContainsKey(currentMaterialData.name)) { // Select an "owning" submesh for the material referencingSubmeshes = (ArrayList)(submeshesUsingMaterials[currentMaterialData.name]); owningSubmesh = (SubmeshData3DS)(referencingSubmeshes[referencingSubmeshes.Count - 1]); // Qualify the material name with the submesh's name as well (see above note) currentMaterialData.name = currentMaterialData.name + "_" + owningSubmesh.name; owningSubmesh.materialUsed = currentMaterialData.name; // Clean up and update submesh reference lists referencingSubmeshes.RemoveAt(referencingSubmeshes.Count - 1); referencingSubmeshes = new ArrayList(); referencingSubmeshes.Add(owningSubmesh); submeshesUsingMaterials.Add(currentMaterialData.name, referencingSubmeshes); }*/ return mat; }
private static ThreeDSMesh.MaterialMapping ParseMeshMaterial(DataReader3DS subSegment) { ThreeDSMesh.MaterialMapping mapping = new ThreeDSMesh.MaterialMapping(); mapping.name = subSegment.GetString(); // Read mapped faces mapping.mappedFaces = new ushort[subSegment.GetUShort()]; for (int face = 0; face < mapping.mappedFaces.Length; face++) { mapping.mappedFaces[face] = subSegment.GetUShort(); } return mapping; }
private static ThreeDSMesh.FaceGroup ParseFaceData(DataReader3DS dataSegment) { DataReader3DS subSegment; // will be used to read other subsegments (do not initialize yet) ThreeDSMesh.FaceGroup group = new ThreeDSMesh.FaceGroup(); group.faces = new ThreeDSMesh.Face[dataSegment.GetUShort()]; // Read face data for (int face = 0; face < group.faces.Length; face++) { group.faces[face].p1 = dataSegment.GetUShort(); group.faces[face].p2 = dataSegment.GetUShort(); group.faces[face].p3 = dataSegment.GetUShort(); // Ignore flag dataSegment.GetUShort(); } // Read other subsegments subSegment = dataSegment.GetNextSubSegment(); while (subSegment != null) { switch ((ChunkCodes)subSegment.Tag) { case ChunkCodes.MESH_MATER: // Name of material used group.mappings.Add(ParseMeshMaterial(subSegment)); break; case ChunkCodes.TRI_SMOOTH: break; } subSegment = dataSegment.GetNextSubSegment(); } return group; }
private static ThreeDSMesh.UV[] ParseTexVerts(DataReader3DS subSegment) { ThreeDSMesh.UV[] uv = new ThreeDSMesh.UV[subSegment.GetUShort()]; for (int coord = 0; coord < uv.Length; coord++) { uv[coord].u = subSegment.GetFloat(); uv[coord].v = subSegment.GetFloat(); } return uv; }
private static ThreeDSMesh ParsePolygonalData(DataReader3DS dataSegment) { DataReader3DS subSegment = dataSegment.GetNextSubSegment(); // working data subsegment ThreeDSMesh mesh = new ThreeDSMesh(); while (subSegment != null) { switch ((ChunkCodes)subSegment.Tag) { case ChunkCodes.MESH_VERTICES: // Subsegment contains vertex information mesh.verticies = new ThreeDSMesh.Vertex[subSegment.GetUShort()]; for (int vertex = 0; vertex < mesh.verticies.Length; vertex++) { mesh.verticies[vertex].x = subSegment.GetFloat(); mesh.verticies[vertex].y = subSegment.GetFloat(); mesh.verticies[vertex].z = subSegment.GetFloat(); } break; case ChunkCodes.MESH_XFMATRIX: // Subsegment contains translation matrix info (ignore for now) break; case ChunkCodes.MESH_FACES: // Subsegment contains face information mesh.groups.Add(ParseFaceData(subSegment)); break; case ChunkCodes.MESH_TEX_VERT: // Subsegment contains texture mapping information mesh.uvMap = ParseTexVerts(subSegment); break; } subSegment = dataSegment.GetNextSubSegment(); } // Also use face data to calculate vertex normals CalculateVertexNormals(mesh); return mesh; }
private static ThreeDSObject ParseMeshData(DataReader3DS dataSegment) { string name = dataSegment.GetString(); DataReader3DS subSegment = dataSegment.GetNextSubSegment(); ThreeDSObject obj = new ThreeDSObject(); obj.name = name; while (subSegment != null) { switch ((ChunkCodes)subSegment.Tag) { case ChunkCodes.OBJ_MESH: // Current subsegment contains the polygonal information obj.meshes.Add(ParsePolygonalData(subSegment)); break; default: // Ignore all other subsegment types break; } subSegment = dataSegment.GetNextSubSegment(); } return obj; }
public static ThreeDSFileData ParseFromFile(string file) { DataReader3DS data = new DataReader3DS(file); return(ParseFromData(data)); }