/// <summary> /// Notify the world and any chunks that this voxel has changed /// </summary> public void NotifyVoxelChange(int x, int y, int z, ushort FromID, ushort ToID) { ChunkID chunkID; if (!GetChunkCoords(x, y, z, out chunkID)) { return; // Chunk doesn't even exist } // Broadcast notify to owning chunk and all chunks where x,y,z is adjacent to its bounds int localX = x % VoxelChunk.ChunkWidth; int localZ = z % VoxelChunk.ChunkWidth; if (localX < 0) { localX += VoxelChunk.ChunkWidth; } if (localZ < 0) { localZ += VoxelChunk.ChunkWidth; } { if (mActiveChunks.ContainsKey(chunkID)) { mActiveChunks[chunkID].OnNotifyVoxelChange(localX, y, localZ, FromID, ToID); } } if (localX == 0) { ChunkID check = new ChunkID(chunkID.X - 1, chunkID.Z); if (mActiveChunks.ContainsKey(check)) { mActiveChunks[check].OnNotifyVoxelChange(localX, y, localZ, FromID, ToID); } } if (localX == VoxelChunk.ChunkWidth - 1) { ChunkID check = new ChunkID(chunkID.X + 1, chunkID.Z); if (mActiveChunks.ContainsKey(check)) { mActiveChunks[check].OnNotifyVoxelChange(localX, y, localZ, FromID, ToID); } } if (localZ == 0) { ChunkID check = new ChunkID(chunkID.X, chunkID.Z - 1); if (mActiveChunks.ContainsKey(check)) { mActiveChunks[check].OnNotifyVoxelChange(localX, y, localZ, FromID, ToID); } } if (localZ == VoxelChunk.ChunkWidth - 1) { ChunkID check = new ChunkID(chunkID.X, chunkID.Z + 1); if (mActiveChunks.ContainsKey(check)) { mActiveChunks[check].OnNotifyVoxelChange(localX, y, localZ, FromID, ToID); } } }
private void ReadObject(int msize) { int total = 6; string objectName = ReadString(); total += objectName.Length + 1; while (total < msize) { ChunkID id = ReadChunkId(); int size = ReadChunkSize(); Debug.WriteLine(id); total += size; switch (id) { case ChunkID.OBJ_TRIMESH: ReadTriangularMesh(size); break; // case ChunkID.OBJ_CAMERA: default: { byte[] bytes = ReadData(size - 6); break; } } } }
private Color ReadColor(int size) { // var bb = ReadData(reader, size - 6); // return Colors.White; ChunkID type = ReadChunkId(); int csize = ReadChunkSize(); size -= 6; switch (type) { case ChunkID.COL_RGB: { // not checked... Debug.Assert(false); float r = reader.ReadSingle(); float g = reader.ReadSingle(); float b = reader.ReadSingle(); return(Color.FromScRgb(1, r, g, b)); } case ChunkID.COL_TRU: { byte r = reader.ReadByte(); byte g = reader.ReadByte(); byte b = reader.ReadByte(); return(Color.FromArgb(0xFF, r, g, b)); } default: ReadData(csize); break; } return(Colors.White); }
public Model3DGroup Read(Stream s) { reader = new BinaryReader(s); long length = reader.BaseStream.Length; // http://gpwiki.org/index.php/Loading_3ds_files // http://www.flipcode.com/archives/3DS_File_Loader.shtml // http://sandy.googlecode.com/svn/trunk/sandy/as3/branches/3.0.2/src/sandy/parser/Parser3DS.as ChunkID headerID = ReadChunkId(); if (headerID != ChunkID.MAIN3DS) { throw new FileFormatException("Unknown file"); } int headerSize = ReadChunkSize(); if (headerSize != length) { throw new FileFormatException("Incomplete file (file length does not match header)"); } Model = new Model3DGroup(); while (reader.BaseStream.Position < reader.BaseStream.Length) { ChunkID id = ReadChunkId(); int size = ReadChunkSize(); Debug.WriteLine(id); switch (id) { case ChunkID.EDIT_MATERIAL: ReadMaterial(size); break; case ChunkID.EDIT_OBJECT: ReadObject(size); break; case ChunkID.EDIT3DS: case ChunkID.OBJ_CAMERA: case ChunkID.OBJ_LIGHT: case ChunkID.OBJ_TRIMESH: // don't read the whole chunk, read the sub-defines... break; default: // download the whole chunk byte[] bytes = ReadData(size - 6); break; } } reader.Close(); return(Model); }
// Terrain Mesh Parser // private static void ParseADT_Main(string Path, string MapName, Vector2 coords) // MS version { StreamTools s = new StreamTools(); ADTRoot r = new ADTRoot(); ChunkID c = new ChunkID(); string ADTmainPath = Path + MapName + "_" + coords.x + "_" + coords.y + ".adt"; string path = Casc.GetFile(ADTmainPath); byte[] ADTmainData = File.ReadAllBytes(path); int MCNKchunkNumber = 0; long streamPosition = 0; using (MemoryStream ms = new MemoryStream(ADTmainData)) { while (streamPosition < ms.Length) { ms.Position = streamPosition; int chunkID = s.ReadLong(ms); int chunkSize = s.ReadLong(ms); streamPosition = ms.Position + chunkSize; switch (chunkID) { case (int)ChunkID.ADT.MVER: r.ReadMVER(ms); // ADT file version break; case (int)ChunkID.ADT.MHDR: r.ReadMHDR(ms); // Offsets for specific chunks 0000 if chunks don't exist. break; case (int)ChunkID.ADT.MH2O: r.ReadMH2O(ms, chunkSize); // Water Data break; case (int)ChunkID.ADT.MCNK: { r.ReadMCNK(ms, MCNKchunkNumber, chunkSize); // Terrain Data - 256chunks MCNKchunkNumber++; } break; case (int)ChunkID.ADT.MFBO: r.ReadMFBO(ms); // FlightBounds plane & Death plane break; default: r.SkipUnknownChunk(ms, chunkID, chunkSize); break; } } } ADTmainData = null; }
/// <summary> /// Called when this chunk comes into usage /// </summary> /// <param name="X"></param> /// <param name="Z"></param> public void Construct(int X, int Z) { bInUse = true; mChunkID = new ChunkID(X, Z); gameObject.name = "Chunk (" + X + ", " + Z + ")"; gameObject.transform.position = new Vector3(X * ChunkWidth, 0, Z * ChunkWidth) * WorldManager.VoxelToUnitScale; gameObject.SetActive(true); Generate(); }
/// <summary> /// Get the chunk coordinates from world coordinates /// </summary> /// <returns>True if the chunk exists</returns> public bool GetChunkCoords(int x, int y, int z, out ChunkID ID) { // If y is out of bounds, instant failure if (y < 0 || y >= VoxelChunk.ChunkHeight) { ID = new ChunkID(0, 0); return(false); } ID = GetChunkIDFromCoords(x, y, z); return(mActiveChunks.ContainsKey(ID)); }
/// <summary> /// Remove a chunk at selected chunk coordinates (If it exists) /// </summary> private void RemoveChunk(int X, int Z) { ChunkID id = new ChunkID(X, Z); VoxelChunk chunk = mActiveChunks[id]; if (chunk != null) { mActiveChunks.Remove(id); chunk.Deconstruct(); mChunkPool.Enqueue(chunk); } }
/// <summary> /// World update tick called from world update thread /// </summary> /// <param name="Tick">The current tick number for this update</param> public void WorldUpdate(uint Tick) { // Attempt to load chunks around player HashSet <ChunkID> loadArea = new HashSet <ChunkID>(); // Populate load are near player Entity_Player player = Entity_Player.Main; if (player == null) { return; } const int radius = 3; ChunkID c = player.mChunkID; for (int x = -radius; x <= radius; ++x) { for (int z = -radius; z <= radius; ++z) { loadArea.Add(new ChunkID(c.X + x, c.Z + z)); } } // Update or unload chunks near player VoxelChunk[] activeChunks = mCurrentTerrain.GetActiveChunks(); foreach (VoxelChunk chunk in activeChunks) { // In view, so update and remove from load area check if (loadArea.Contains(chunk.mChunkID)) { chunk.UpdateChunk(Tick); loadArea.Remove(chunk.mChunkID); } // Request that this chunk is unload else { mCurrentTerrain.RequestChunkUnload(chunk.mChunkID.X, chunk.mChunkID.Z); } } // Load all remaining areas in load area foreach (ChunkID id in loadArea) { mCurrentTerrain.RequestChunkLoad(id.X, id.Z); } }
public DataChunk(BinaryReader reader) : base(reader) { if (reader == null) { throw new ArgumentNullException("reader"); } if (ChunkID != chunkID) { throw new FormatException("Chunk is no datachunk: " + ChunkID.ToString("x") + " != \"0x61746164\""); } }
/// <summary> /// Retreive a chunk for chunk coordinates /// </summary> public VoxelChunk GetChunk(int X, int Z) { ChunkID id = new ChunkID(X, Z); if (mActiveChunks.ContainsKey(id)) { return(mActiveChunks[id]); } else { return(null); } }
/// <summary> /// On GUI /// </summary> private void OnGUI() { WorldManagerScript world_manager = WorldManagerScript.Instance; if (world_manager) { chunkID = (ChunkID)(EditorGUILayout.Vector3IntField("Chunk ID", (Vector3Int)chunkID)); if (GUILayout.Button("Find discrepencies")) { fileBlocksTask = world_manager.IO.CreateReadChunkBlocksTask(chunkID); generatedBlocksTask = world_manager.GetGeneratedBlocksTask(chunkID); } GUILayout.Label($"File blocks task status: { ((fileBlocksTask == null) ? "Not running" : fileBlocksTask.Status.ToString()) }"); GUILayout.Label($"Generated blocks task status: { ((generatedBlocksTask == null) ? "Not running" : generatedBlocksTask.Status.ToString()) }"); if ((fileBlocksTask != null) && (generatedBlocksTask != null)) { if (fileBlocksTask.IsCompleted && generatedBlocksTask.IsCompleted) { StringBuilder output_string_builder = new StringBuilder(); BlockData[] file_blocks = fileBlocksTask.Result; BlockData[] generated_blocks = generatedBlocksTask.Result; fileBlocksTask = null; generatedBlocksTask = null; output_string_builder.AppendLine($"File block count: { file_blocks.Length }"); output_string_builder.AppendLine($"Generated block count: { generated_blocks.Length }"); if (file_blocks.Length == generated_blocks.Length) { for (int index = 0; index < file_blocks.Length; index++) { BlockData file_block = file_blocks[index]; BlockData generated_block = generated_blocks[index]; if (file_block != generated_block) { output_string_builder.AppendLine($"File block is { (file_block.IsABlock ? file_block.Block.Key : "nothing") } with { file_block.Health } health but generated block is { (generated_block.IsABlock ? generated_block.Block.Key : "nothing") } with { generated_block.Health } health."); } } output_string_builder.Append("Finished comparing all blocks."); } else { output_string_builder.Append("File blocks count does not match generated block count."); } output = output_string_builder.ToString(); output_string_builder.Clear(); } } GUILayout.TextArea(output); } }
private string ReadMatMap(int size) { ChunkID id = ReadChunkId(); int siz = ReadChunkSize(); ushort f1 = reader.ReadUInt16(); ushort f2 = reader.ReadUInt16(); ushort f3 = reader.ReadUInt16(); ushort f4 = reader.ReadUInt16(); size -= 14; string cname = ReadString(); size -= cname.Length + 1; byte[] morebytes = ReadData(size); return(cname); }
private List <FaceMaterial> ReadFaceMaterials(int msize) { int total = 6; var list = new List <FaceMaterial>(); while (total < msize) { ChunkID id = ReadChunkId(); int size = ReadChunkSize(); Debug.WriteLine(id); total += size; switch (id) { case ChunkID.TRI_FACEMAT: { string name = ReadString(); int n = reader.ReadUInt16(); var c = new Int32Collection(); for (int i = 0; i < n; i++) { c.Add(reader.ReadUInt16()); } var fm = new FaceMaterial { Name = name, Faces = c }; list.Add(fm); break; } case ChunkID.TRI_SMOOTH: { byte[] bytes = ReadData(size - 6); break; } default: { byte[] bytes = ReadData(size - 6); break; } } } return(list); }
/// <summary> /// Notify the world and any chunks that this chunk has changed /// </summary> public void NotifyChunkChange(int X, int Z) { // Broadcast notify to chunk and all adjacent { ChunkID check = new ChunkID(X, Z); if (mActiveChunks.ContainsKey(check)) { mActiveChunks[check].OnNotifyChunkChange(X, Z); } } { ChunkID check = new ChunkID(X - 1, Z); if (mActiveChunks.ContainsKey(check)) { mActiveChunks[check].OnNotifyChunkChange(X, Z); } } { ChunkID check = new ChunkID(X + 1, Z); if (mActiveChunks.ContainsKey(check)) { mActiveChunks[check].OnNotifyChunkChange(X, Z); } } { ChunkID check = new ChunkID(X, Z - 1); if (mActiveChunks.ContainsKey(check)) { mActiveChunks[check].OnNotifyChunkChange(X, Z); } } { ChunkID check = new ChunkID(X, Z + 1); if (mActiveChunks.ContainsKey(check)) { mActiveChunks[check].OnNotifyChunkChange(X, Z); } } }
void Update() { // Update active chunks lock (mActiveChunks) { while (mPendingUnloads.Count != 0) { ChunkID id = mPendingUnloads.Dequeue(); if (IsChunkLoaded(id.X, id.Z)) { RemoveChunk(id.X, id.Z); } } while (mPendingLoads.Count != 0) { ChunkID id = mPendingLoads.Dequeue(); if (!IsChunkLoaded(id.X, id.Z)) { AddChunk(id.X, id.Z); } } } }
/// <summary> /// reads the Material of a chunck /// </summary> /// <param name="reader"></param> /// <param name="chunkSize"></param> private void ReadMaterial(BinaryReader reader, int chunkSize) { int total = 6; string name = null; var luminance = Color.Transparent; //SharpDX.Color not System.Windows.Media.Color var diffuse = Color.Transparent; var specular = Color.Transparent; var shininess = Color.Transparent; double opacity = 0; string texture = null; float specularPower = 100;//check if we can find this somewhere instead of just setting it to 100 while (total < chunkSize) { ChunkID id = this.ReadChunkId(reader); int size = this.ReadChunkSize(reader); total += size; switch (id) { case ChunkID.MAT_NAME01: name = this.ReadString(reader); break; case ChunkID.MAT_TRANSPARENCY: // skip the first 6 bytes this.ReadData(reader, 6); // read the percent value as 16Bit Uint byte[] data = this.ReadData(reader, 2); opacity = (100 - BitConverter.ToUInt16(data, 0)) / 100.0; break; case ChunkID.MAT_LUMINANCE: luminance = this.ReadColor(reader); break; case ChunkID.MAT_DIFFUSE: diffuse = this.ReadColor(reader); break; case ChunkID.MAT_SPECULAR: specular = this.ReadColor(reader); break; case ChunkID.MAT_SHININESS: //byte[] bytes = this.ReadData(reader, size - 6); specularPower = this.ReadPercent(reader, size - 6); break; case ChunkID.MAT_MAP: texture = this.ReadMatMap(reader, size - 6); break; case ChunkID.MAT_MAPFILE: this.ReadData(reader, size - 6); break; default: this.ReadData(reader, size - 6); break; } } var image = ReadBitmapSoure(texture, diffuse); if (Math.Abs(opacity) > 0.001) { diffuse.A = (byte)(opacity * 255); luminance.A = (byte)(opacity * 255); } var material = new PhongMaterialCore() { DiffuseColor = diffuse, AmbientColor = luminance, //not really sure about this, lib3ds uses 0xA010 as AmbientColor SpecularColor = specular, SpecularShininess = specularPower, }; if (image != null) { material.NormalMap = image; } if (name != null) { materials[name] = material; } }
public TexturePack(ChunkID id, long size, long position) : base(id, size, position) { DebugUtil.EnsureCondition( id == ChunkID.BCHUNK_SPEED_TEXTURE_PACK_LIST_CHUNKS, () => $"Expected BCHUNK_SPEED_TEXTURE_PACK_LIST_CHUNKS, got {id.ToString()}"); }
/// <summary> /// Reads a triangular mesh. /// </summary> /// <param name="reader"> /// The reader. /// </param> /// <param name="chunkSize"> /// The chunk size. /// </param> private void ReadTriangularMesh(BinaryReader reader, int chunkSize) { int bytesRead = 6; List <Point3D> positions = null; List <int> faces = null; List <Point> textureCoordinates = null; List <FaceSet> faceSets = null; while (bytesRead < chunkSize) { ChunkID id = this.ReadChunkId(reader); int size = this.ReadChunkSize(reader); bytesRead += size; switch (id) { case ChunkID.TRI_VERTEXL: positions = this.ReadVertexList(reader); break; case ChunkID.TRI_FACEL1: faces = this.ReadFaceList(reader); size -= (faces.Count / 3 * 8) + 2; faceSets = this.ReadFaceSets(reader, size - 6); break; case ChunkID.TRI_TEXCOORD: textureCoordinates = this.ReadTexCoords(reader); break; case ChunkID.TRI_LOCAL: this.ReadTransformation(reader); break; default: this.ReadData(reader, size - 6); break; } } // TODO: apply transforms // if (!matrix.IsIdentity) /* for (int i = 0; i < vertices.Count; i++) * { * positions[i] = Transform(matrix, positions[i]); * }*/ if (faces == null) { // face list not specified? return; } if (faceSets == null || faceSets.Count == 0) { // add mesh without material defined (e.g. the example Suzanne 3ds model) this.meshes.Add(new Mesh { Positions = positions, TriangleIndices = faces, TextureCoordinates = textureCoordinates, Material = this.DefaultMaterial, BackMaterial = this.DefaultMaterial }); return; } foreach (var fm in faceSets) { var triangleIndices = ConvertFaceIndices(fm.Faces, faces); Material mat = null; if (this.materials.ContainsKey(fm.Name)) { mat = this.materials[fm.Name]; } this.meshes.Add(new Mesh { Positions = positions, TriangleIndices = triangleIndices, TextureCoordinates = textureCoordinates, Material = mat, BackMaterial = mat }); } }
/// <summary> /// Read a material. /// </summary> /// <param name="reader">The reader.</param> /// <param name="chunkSize">The chunk size.</param> private void ReadMaterial(BinaryReader reader, int chunkSize) { int total = 6; string name = null; var luminance = Colors.Transparent; var diffuse = Colors.Transparent; var specular = Colors.Transparent; var shininess = Colors.Transparent; string texture = null; while (total < chunkSize) { ChunkID id = this.ReadChunkId(reader); int size = this.ReadChunkSize(reader); // Debug.WriteLine(id); total += size; switch (id) { case ChunkID.MAT_NAME01: name = this.ReadString(reader); // name = ReadString(size - 6); break; case ChunkID.MAT_LUMINANCE: luminance = this.ReadColor(reader); break; case ChunkID.MAT_DIFFUSE: diffuse = this.ReadColor(reader); break; case ChunkID.MAT_SPECULAR: specular = this.ReadColor(reader); break; case ChunkID.MAT_SHININESS: byte[] bytes = this.ReadData(reader, size - 6); // shininess = ReadColor(r, size); break; case ChunkID.MAT_MAP: texture = this.ReadMatMap(reader, size - 6); break; case ChunkID.MAT_MAPFILE: this.ReadData(reader, size - 6); break; default: this.ReadData(reader, size - 6); break; } } int specularPower = 100; this.Dispatch(() => { var mg = new MaterialGroup(); // mg.Children.Add(new DiffuseMaterial(new SolidColorBrush(luminance))); if (texture != null) { string ext = Path.GetExtension(texture); if (ext != null) { ext = ext.ToLower(); } // TGA not supported - convert textures to .png! if (ext == ".tga") { texture = Path.ChangeExtension(texture, ".png"); } var actualTexturePath = this.TexturePath ?? string.Empty; string path = Path.Combine(actualTexturePath, texture); if (File.Exists(path)) { var img = new BitmapImage(new Uri(path, UriKind.Relative)); var textureBrush = new ImageBrush(img) { ViewportUnits = BrushMappingMode.Absolute, TileMode = TileMode.Tile }; mg.Children.Add(new DiffuseMaterial(textureBrush)); } else { // Debug.WriteLine(string.Format("Texture not found: {0}", Path.GetFullPath(path))); mg.Children.Add(new DiffuseMaterial(new SolidColorBrush(diffuse))); } } else { mg.Children.Add(new DiffuseMaterial(new SolidColorBrush(diffuse))); } mg.Children.Add(new SpecularMaterial(new SolidColorBrush(specular), specularPower)); if (name != null) { this.materials[name] = mg; } }); }
protected virtual void Update() { mWorldLocation = GenerateWorldLocation(); mChunkID = mTerrain.GetChunkIDFromCoords(mWorldLocation.x, mWorldLocation.y, mWorldLocation.z); }
public FNGFile(ChunkID id, long size, long position) : base(id, size, position) { DebugUtil.EnsureCondition( id == ChunkID.BCHUNK_FENG_PACKAGE, () => $"Expected BCHUNK_FENG_PACKAGE, got {id.ToString()}"); }
public NullModel(ChunkID id, long size, long position) : base(id, size, position) { }
public Language(ChunkID id, long size, long position) : base(id, size, position) { DebugUtil.EnsureCondition( id == ChunkID.BCHUNK_LANGUAGE, () => $"Expected BCHUNK_LANGUAGE, got {id.ToString()}"); }
public SolidList(ChunkID id, long size, long position) : base(id, size, position) { DebugUtil.EnsureCondition( id == ChunkID.BCHUNK_SPEED_ESOLID_LIST_CHUNKS, () => $"Expected BCHUNK_SPEED_ESOLID_LIST_CHUNKS, got {id.ToString()}"); }
public CarList(ChunkID id, long size, long position) : base(id, size, position) { DebugUtil.EnsureCondition( id == ChunkID.BCHUNK_CARINFO_ARRAY, () => $"Expected BCHUNK_CARINFO_ARRAY, got {id.ToString()}"); }
/// <summary> /// Reads a triangular mesh. /// </summary> /// <param name="reader"> /// The reader. /// </param> /// <param name="chunkSize"> /// The chunk size. /// </param> private void ReadTriangularMesh(BinaryReader reader, int chunkSize) { MeshBuilder builder = new MeshBuilder(); int bytesRead = 6; Vector3Collection positions = null; IntCollection faces = null; Vector2Collection textureCoordinates = null; List <FaceSet> facesets = null; IntCollection triangleIndices = null; Vector3Collection normals = null; MediaMatrix3D matrix = MediaMatrix3D.Identity; Vector3Collection tangents = null; Vector3Collection bitangents = null; while (bytesRead < chunkSize) { ChunkID id = this.ReadChunkId(reader); int size = this.ReadChunkSize(reader); bytesRead += size; switch (id) { case ChunkID.TRI_VERTEXL: positions = this.ReadVertexList(reader); break; case ChunkID.TRI_FACEL1: faces = ReadFaceList(reader); size -= (faces.Count / 3 * 8) + 2; facesets = this.ReadFaceSets(reader, size - 6); break; case ChunkID.TRI_TEXCOORD: textureCoordinates = ReadTexCoords(reader); break; case ChunkID.TRI_LOCAL: matrix = this.ReadTransformation(reader); break; default: this.ReadData(reader, size - 6); break; } } if (!matrix.IsIdentity) { for (int i = 0; i < positions.Count; i++) { positions[i] = Transform(matrix, positions[i]); } } if (faces == null) { //no faces defined?? return... return; } if (facesets == null || facesets.Count == 0) { triangleIndices = ConvertFaceIndices(faces, faces); CreateMesh(positions, textureCoordinates, triangleIndices, out normals, out tangents, out bitangents, PhongMaterials.Gray); //Add default get and setter } else { foreach (var fm in facesets) { triangleIndices = ConvertFaceIndices(fm.Faces, faces); Material mat = null; if (this.materials.ContainsKey(fm.Name)) { mat = this.materials[fm.Name]; } CreateMesh(positions, textureCoordinates, triangleIndices, out normals, out tangents, out bitangents, mat); } } }
/// <summary> /// Reads a triangular mesh. /// </summary> /// <param name="reader"> /// The reader. /// </param> /// <param name="chunkSize"> /// The chunk size. /// </param> private void ReadTriangularMesh(BinaryReader reader, int chunkSize) { MeshBuilder builder = new MeshBuilder(); int bytesRead = 6; Vector3Collection positions = null; IntCollection faces = null; Vector2Collection textureCoordinates = null; List <FaceSet> facesets = null; IntCollection triangleIndices = null; Vector3Collection normals = null; //Matrix matrix = Matrix.Identity; Vector3Collection tangents = null; Vector3Collection bitangents = null; List <Matrix> transforms = new List <Matrix>(); while (bytesRead < chunkSize) { ChunkID id = this.ReadChunkId(reader); int size = this.ReadChunkSize(reader); bytesRead += size; switch (id) { case ChunkID.TRI_VERTEXL: positions = this.ReadVertexList(reader); break; case ChunkID.TRI_FACEL1: faces = ReadFaceList(reader); size -= (faces.Count / 3 * 8) + 2; facesets = this.ReadFaceSets(reader, size - 6); break; case ChunkID.TRI_TEXCOORD: textureCoordinates = ReadTexCoords(reader); break; case ChunkID.TRI_LOCAL: transforms.Add(this.ReadTransformation(reader)); break; default: this.ReadData(reader, size - 6); break; } } if (faces == null) { //no faces defined?? return... return; } if (facesets == null || facesets.Count == 0) { triangleIndices = faces; CreateMesh(positions, textureCoordinates, triangleIndices, transforms, out normals, out tangents, out bitangents, new PhongMaterial() { Name = "Gray", AmbientColor = new Color4(0.1f, 0.1f, 0.1f, 1.0f), DiffuseColor = new Color4(0.254902f, 0.254902f, 0.254902f, 1.0f), SpecularColor = new Color4(0.0225f, 0.0225f, 0.0225f, 1.0f), EmissiveColor = new Color4(0.0f, 0.0f, 0.0f, 1.0f), SpecularShininess = 12.8f, }); //Add default get and setter } else { foreach (var fm in facesets) { triangleIndices = ConvertFaceIndices(fm.Faces, faces); MaterialCore mat = null; if (this.materials.ContainsKey(fm.Name)) { mat = this.materials[fm.Name]; } CreateMesh(positions, textureCoordinates, triangleIndices, transforms, out normals, out tangents, out bitangents, mat); } } }
/// <summary> /// reads the Material of a chunck /// </summary> /// <param name="reader"></param> /// <param name="chunkSize"></param> private void ReadMaterial(BinaryReader reader, int chunkSize) { int total = 6; string name = null; var luminance = Color.Transparent; //SharpDX.Color not System.Windows.Media.Color var diffuse = Color.Transparent; var specular = Color.Transparent; var shininess = Color.Transparent; string texture = null; while (total < chunkSize) { ChunkID id = this.ReadChunkId(reader); int size = this.ReadChunkSize(reader); total += size; switch (id) { case ChunkID.MAT_NAME01: name = this.ReadString(reader); break; case ChunkID.MAT_LUMINANCE: luminance = this.ReadColor(reader); break; case ChunkID.MAT_DIFFUSE: diffuse = this.ReadColor(reader); break; case ChunkID.MAT_SPECULAR: specular = this.ReadColor(reader); break; case ChunkID.MAT_SHININESS: byte[] bytes = this.ReadData(reader, size - 6); break; case ChunkID.MAT_MAP: texture = this.ReadMatMap(reader, size - 6); break; case ChunkID.MAT_MAPFILE: this.ReadData(reader, size - 6); break; default: this.ReadData(reader, size - 6); break; } } int specularPower = 100;//check if we can find this somewhere instead of just setting it to 100 BitmapSource image = ReadBitmapSoure(texture, diffuse); var material = new PhongMaterial() { DiffuseColor = diffuse, AmbientColor = luminance, //not really sure about this, lib3ds uses 0xA010 as AmbientColor SpecularColor = specular, SpecularShininess = specularPower, }; if (image != null) { material.NormalMap = image; } if (name != null) { materials[name] = material; } }
protected Model(ChunkID id, long size, long position) { ID = id; Size = size; Position = position; }