//converts the chunk data into a physical chunk private void DrawChunk(BlockChunk c, int chunkNum) { int mat; for (int y = 0; y < chunkSize.y; y++) { for (int x = 0; x < chunkSize.x; x++) { mat = c.blocks[chunkSize.x - 1 - x, chunkSize.x - 1 - y]; switch (materials[mat].type) { case Material.transparent: //checks if the block is visible before drawing it if (VisibleCheck(c.x, c.y, x, y)) { baseMap.SetTile(CordsToPos(c.x, c.y, x, y), materials[mat].tile); } break; case Material.visible: lightData[VMSize.x - x - chunkID[chunkNum].x - 1, VMSize.y - y - chunkID[chunkNum].y - 1] = 10; //checks if the block is visible before drawing it if (VisibleCheck(c.x, c.y, x, y)) { baseMap.SetTile(CordsToPos(c.x, c.y, x, y), materials[mat].tile); } break; default: break; } } } }
// TODO: This can be optimized public bool WriteSectors(byte[] data, ulong sectorAddress, uint length) { if (!IsWriting) { ErrorMessage = "Tried to write on a non-writable image"; return(false); } if (data.Length % imageInfo.SectorSize != 0) { ErrorMessage = "Incorrect data size"; return(false); } if (sectorAddress + length > imageInfo.Sectors) { ErrorMessage = "Tried to write past image size"; return(false); } // Ignore empty sectors if (ArrayHelpers.ArrayIsNullOrEmpty(data)) { if (currentChunk.type == CHUNK_TYPE_COPY) { chunks.Add(currentChunk.sector, currentChunk); currentChunk = new BlockChunk { type = CHUNK_TYPE_NOCOPY, sector = currentSector }; } currentChunk.sectors += (ulong)(data.Length / imageInfo.SectorSize); currentSector += (ulong)(data.Length / imageInfo.SectorSize); masterChecksum.Update(data); ErrorMessage = ""; return(true); } for (uint i = 0; i < length; i++) { byte[] tmp = new byte[imageInfo.SectorSize]; Array.Copy(data, i * imageInfo.SectorSize, tmp, 0, imageInfo.SectorSize); if (!WriteSector(tmp, sectorAddress + i)) { return(false); } } ErrorMessage = ""; return(true); }
public BlockData(BlockChunk chunk = null, Vector3Int position = new Vector3Int()) { SetId(); SetMesh(); SetupBlock(chunk, position); SetUpdate(); }
public void Update(GameTime time) { List <int> towersDone = new List <int>(); for (int i = 0; i < chunks.Count; i++) { chunks[i].Update(time); if (chunks[i].TowerDone) { towersDone.Add(i); } } for (int j = towersDone.Count - 1; j >= 0; j--) { chunks.RemoveAt(towersDone[j]); } for (int k = 0; k < towersDone.Count; k++) { int newHeight = lastHeight + (Rand.Next(-1, 2)); if (newHeight > maxHeight) { newHeight = maxHeight; } if (newHeight <= minHeight) { newHeight = minHeight; } int x = (int)CurrentTerrain.Last().CurrentX + groundWidth; BlockChunk next = CurrentTerrain.Construct(x); next.Generate(); chunks.Add(next); lastHeight = newHeight; TowersCreated++; } }
public void UpdateWindow(Rectangle newWindow) { if (CurrentTerrain != null) { CurrentTerrain.ChangeWindow(newWindow); } if (chunks.Count > 0) { for (int i = 0; i < chunks.Count; i++) { chunks[i].UpdateWindow(newWindow); } int oldamountOfTowers = (window.Width / groundWidth) + extraLength + 1; int newamountOfTowers = (newWindow.Width / groundWidth) + extraLength + 1; int towersToCreate = Math.Abs(newamountOfTowers - oldamountOfTowers) + 1; float x = CurrentTerrain.Last().CurrentX + groundWidth; for (int i = 0; i < towersToCreate; i++) { BlockChunk current = CurrentTerrain.Construct((int)x); current.Generate(); chunks.Add(current); x += groundWidth; TowersCreated++; } } window = newWindow; }
public void Initialize(float width, float height) { chunk = new BlockChunk(); chunk.position = this.transform.position; chunk.rect = new Rect(chunk.position, new Vector2(width, height)); unityBlocks = new List <UnityBlock>(); }
public Block_Liquid(BlockChunk chunk, Vector3Int position = new Vector3Int(), int flow = 3) { lastUpdate = Time.time; currentFlow = flow; SetId(); SetMesh(); SetupBlock(chunk, position); SetUpdate(); }
public static int ImprovedPerlinHeight(int atX, int atY, BlockChunk chunk, int maxHeight) { return((int)Mathf.Min( ( Mathf.PerlinNoise((chunk.chunkX * BlockChunk.width + atX) / 10.0f, (chunk.chunkY * BlockChunk.depth + atY) / 10f) + Mathf.PerlinNoise((chunk.chunkX * BlockChunk.width + atX) / 20.0f, (chunk.chunkY * BlockChunk.depth + atY) / 20f) ) * maxHeight, BlockChunk.height - 1 )); }
public void GetMesh( Vector3 position, BlockChunk chunk, ref Mesh refMesh, ref List <Vector3> verts, ref List <Vector3> normals, ref List <int> tris, ref List <Vector2> uvs, ref int meshIndex /* Index of last vertex placed. Used in determining which vertices determine a tris*/) { GenerateCustomMesh(position, chunk, ref refMesh, ref verts, ref normals, ref tris, ref uvs, ref meshIndex); }
protected override void SetupBlock(BlockChunk chunk, Vector3Int position = new Vector3Int()) { if (chunk != null) { this.chunk = chunk; this.position = position; chunk.updateBlocks.Add(this); } else { //Debug.Log("NULL chunk passed to liquid block at " + position); } }
private static void GenerateBlocks(BlockChunk c) { for (int y = 0; y < chunkSize.y; y++) { for (int x = 0; x < chunkSize.x; x++) { if (y == 0) { c.blocks[x, y] = 1; } } } }
private bool adjCheck(BlockChunk a, BlockChunk b) { if (a != b) { if (a.chunkX >= b.chunkX - 1 && a.chunkX <= b.chunkX + 1) { if (a.chunkY >= b.chunkY - 1 && a.chunkY <= b.chunkY + 1) { return(true); } } } return(false); }
private void UpdateNeighbours(BlockChunk targetChunk) { //Update neighbours for single chunk foreach (GameObject chunkObj in chunks) { BlockChunk chunk = chunkObj.GetComponent <BlockChunk>(); if (chunk != targetChunk) { if (adjCheck(chunk, targetChunk)) { setAdjChunk(targetChunk, chunk); } } } }
public bool Create(string path, MediaType mediaType, Dictionary <string, string> options, ulong sectors, uint sectorSize) { if (sectorSize != 512) { ErrorMessage = "Unsupported sector size"; return(false); } if (!SupportedMediaTypes.Contains(mediaType)) { ErrorMessage = $"Unsupported media format {mediaType}"; return(false); } _imageInfo = new ImageInfo { MediaType = mediaType, SectorSize = sectorSize, Sectors = sectors }; try { _writingStream = new FileStream(path, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.None); } catch (IOException e) { ErrorMessage = $"Could not create new image file, exception {e.Message}"; return(false); } _chunks = new Dictionary <ulong, BlockChunk>(); _currentChunk = new BlockChunk(); _currentSector = 0; _dataForkChecksum = new Crc32Context(); _masterChecksum = new Crc32Context(); IsWriting = true; ErrorMessage = null; return(true); }
private static void CreateChunks() { tempChunks = new BlockChunk[worldSize.x, worldSize.y]; for (int y = 0; y < worldSize.y; y++) { for (int x = 0; x < worldSize.x; x++) { BlockChunk c = new BlockChunk(); c.x = x; c.y = y; c.blocks = new int[chunkSize.x, chunkSize.y]; GenerateBlocks(c); tempChunks[x, y] = c; } } }
public void Initialize() { #if DEBUG Debugger.Log(1, "Main", "Initializing level block manager."); #endif Initialized = true; chunks.Clear(); int x = 0; int amountOfTowers = (window.Width / groundWidth) + extraLength + 1; TowersCreated = amountOfTowers; CurrentTerrain.Generate(Rand.Next(30, 50), lastHeight); for (int i = 0; i < amountOfTowers; i++) { BlockChunk tower = CurrentTerrain.Construct(x); tower.Generate(); chunks.Add(tower); x += groundWidth; } }
IEnumerator GenerateMesh() { float startTime = Time.realtimeSinceStartup; for (int i = 0; i < numX * Const.ChunkSize; i++) { for (int k = 0; k < numZ * Const.ChunkSize; k++) { for (int j = 0; j < numY * Const.ChunkSize; j++) { Block.BlockChunk chunk = new BlockChunk(bm, i * Const.ChunkSize, j * Const.ChunkSize, k * Const.ChunkSize); //TerrainTool.calcChunkLight(chunk, i, j, k, rtm, rays, sunDir); //Mesh mesh = MeshTool.createMesh(chunk, blockTypeFun, 0, 0, 0); for (int f = 0; f < 6; f++) { List <Block.MeshTool.BlockSurface> surface = Block.MeshTool.getChunkSurface(chunk, bm.blockTypeFun, f); Texture2D texSurface = Block.MeshTool.SurfacePointsToTexture(surface, f); RenderTexture targetAoResult = rma.RenderByCalcShader(texSurface, new Vector3(i, j, k) * Block.Const.ChunkSize, f); //回读亮度数据 RenderTexture.active = targetAoResult; Texture2D readback = new Texture2D(targetAoResult.width, targetAoResult.height); readback.ReadPixels(new Rect(0, 0, targetAoResult.width, targetAoResult.width), 0, 0); Block.MeshTool.SetRaytraceAo(surface, readback); Mesh mesh = Block.MeshTool.createMesh2(surface, f, bm.blockTypeFun); if (mesh != null) { GameObject obj = new GameObject("Chunk", typeof(MeshRenderer), typeof(MeshFilter)); obj.isStatic = true; obj.GetComponent <Renderer>().material = diffuseMat; obj.GetComponent <MeshFilter>().mesh = mesh; obj.transform.SetParent(transform); obj.transform.position = new Vector3(i * Block.Const.ChunkSize * Block.Const.BlockSize, j * Block.Const.ChunkSize * Block.Const.BlockSize, k * Block.Const.ChunkSize * Block.Const.BlockSize); } } yield return(null); } } } StaticBatchingUtility.Combine(this.gameObject); Debug.Log("计算完," + (Time.realtimeSinceStartup - startTime)); }
private void LoadChunk(ChunkKey key) { var chunk = new BlockChunk(_engine, _depth); chunk.Key = key; //var random = new Random(GetChunkRandomKey(key)); for (ushort x = 0; x < 16; x++) { for (ushort y = 0; y < 16; y++) { for (ushort z = 0; z < _depth; z++) { chunk.SetBlockType(x, y, z, (ushort)(z + 1)); } } } OnChunksGenerated(new List <IChunk> { chunk }); }
public bool WriteSector(byte[] data, ulong sectorAddress) { if (!IsWriting) { ErrorMessage = "Tried to write on a non-writable image"; return(false); } if (data.Length != _imageInfo.SectorSize) { ErrorMessage = "Incorrect data size"; return(false); } if (sectorAddress >= _imageInfo.Sectors) { ErrorMessage = "Tried to write past image size"; return(false); } if (sectorAddress < _currentSector) { ErrorMessage = "Tried to rewind, this format rewinded on writing"; return(false); } _masterChecksum.Update(data); bool isEmpty = ArrayHelpers.ArrayIsNullOrEmpty(data); switch (_currentChunk.type) { case CHUNK_TYPE_ZERO: _currentChunk.type = isEmpty ? CHUNK_TYPE_NOCOPY : CHUNK_TYPE_COPY; break; case CHUNK_TYPE_NOCOPY when !isEmpty: case CHUNK_TYPE_COPY when isEmpty: _chunks.Add(_currentChunk.sector, _currentChunk); _currentChunk = new BlockChunk { type = isEmpty ? CHUNK_TYPE_NOCOPY : CHUNK_TYPE_COPY, sector = _currentSector, offset = (ulong)(isEmpty ? 0 : _writingStream.Position) }; break; } _currentChunk.sectors++; _currentChunk.length += (ulong)(isEmpty ? 0 : 512); _currentSector++; if (!isEmpty) { _dataForkChecksum.Update(data); _writingStream.Write(data, 0, data.Length); } ErrorMessage = ""; return(true); }
// Update is called once per frame public void EditorUpdate(Camera cam) { //Event e = Event.current; //if (e.type == EventType.MouseDown) { // mouseDownPos = e.mousePosition; // if (e.button == 0) { // if (curOperator == Operator.AddBlock) { // if (bShowPreview) { // int gx = (int)previewBlockPos.x; // int gy = (int)previewBlockPos.y; // int gz = (int)previewBlockPos.z; // blockManager.setBlock(gx, gy, gz, (short)BlockTypeEnum.BT_Sand); // bDirty = true; // } // } // if (curOperator == Operator.DeleteBlock) { // if (bShowPreview) { // int gx = (int)selectedBlockPos.x; // int gy = (int)selectedBlockPos.y; // int gz = (int)selectedBlockPos.z; // blockManager.setBlock(gx, gy, gz, (short)BlockTypeEnum.BT_Air); // bDirty = true; // } // } // } //} //else if (e.type == EventType.mouseMove) { // if (curOperator == Operator.AddBlock || curOperator == Operator.DeleteBlock) { // Ray ray = cam.ScreenPointToRay(new Vector3(e.mousePosition.x, cam.pixelHeight - e.mousePosition.y, 0)); // Vector3 startPos = transform.InverseTransformPoint(ray.origin); // Vector3 dir = transform.InverseTransformDirection(ray.direction); // RayCastRestult rlt = rtm.rayCast(startPos, dir, 50); // bShowPreview = rlt.bHit; // if (rlt.bHit) { // //Debug.Log(rlt.hitFaceIndex.ToString()); // if (curOperator == Operator.AddBlock) { // Vector3 hitPos = startPos + dir * (rlt.hitLength + 0.001f); // float gx = (int)(hitPos.x / Const.BlockSize) + 0.5f; // float gy = (int)(hitPos.y / Const.BlockSize) + 0.5f; // float gz = (int)(hitPos.z / Const.BlockSize) + 0.5f; // selectedBlockPos = new Vector3(gx, gy, gz); // previewBlockPos = new Vector3(gx, gy, gz) + Const.getFaceNormal(rlt.hitFaceIndex) * Const.BlockSize; // } // else if (curOperator == Operator.DeleteBlock) { // Vector3 hitPos = startPos + dir * (rlt.hitLength + 0.001f); // float gx = (int)(hitPos.x / Const.BlockSize) + 0.5f; // float gy = (int)(hitPos.y / Const.BlockSize) + 0.5f; // float gz = (int)(hitPos.z / Const.BlockSize) + 0.5f; // selectedBlockPos = new Vector3(gx, gy, gz); // } // } // } //} if (bDirty) { bDirty = false; DebugTool.Log("开始更新光线追踪"); rtm.clearAll(); blockManager.forEachBlock((short block, int gx, int gy, int gz) => { if (block != (short)BlockTypeEnum.Air) { rtm.setBlock(gx, gy, gz, RayCastBlockType.All); } }); //初始化AO计算 RayMarchingAo rma = new RayMarchingAo(); rma.Init(rtm); m_meshes.Clear(); DebugTool.Log("开始计算光照"); TerrainTool.calcLight2(blockManager, 32); DebugTool.Log("开始更新网格"); BlockTypeFun blockTypeFun = new BlockTypeFun(); for (int i = 0; i < SpaceX; i++) { for (int k = 0; k < SpaceZ; k++) { for (int j = 0; j < SpaceY; j++) { BlockChunk chunk = new BlockChunk(blockManager, i * Const.ChunkSize, j * Const.ChunkSize, k * Const.ChunkSize); for (int f = 0; f < 6; f++) { List <MeshTool.BlockSurface> surface = MeshTool.getChunkSurface(chunk, blockTypeFun, f); Texture2D texSurface = MeshTool.SurfacePointsToTexture(surface, f); RenderTexture targetAoResult = rma.RenderByCalcShader(texSurface, new Vector3(i, j, k) * Const.ChunkSize, f); //回读亮度数据 RenderTexture.active = targetAoResult; Texture2D readback = new Texture2D(targetAoResult.width, targetAoResult.height); readback.ReadPixels(new Rect(0, 0, targetAoResult.width, targetAoResult.width), 0, 0); MeshTool.SetRaytraceAo(surface, readback); Mesh mesh = MeshTool.createMesh2(surface, f, blockTypeFun); if (mesh) { Vector3 pos = ((new Vector3(i, j, k))) * Const.ChunkSize; m_meshes.Add(new MeshInfo(mesh, pos)); } } } } } DebugTool.Log("结束"); } }
public bool Open(IFilter imageFilter) { if (!imageFilter.HasResourceFork() || imageFilter.GetResourceForkLength() == 0) { return(false); } ResourceFork rsrcFork; Resource rsrc; short[] bcems; try { rsrcFork = new ResourceFork(imageFilter.GetResourceForkStream()); if (!rsrcFork.ContainsKey(NDIF_RESOURCE)) { return(false); } rsrc = rsrcFork.GetResource(NDIF_RESOURCE); bcems = rsrc.GetIds(); if (bcems == null || bcems.Length == 0) { return(false); } } catch (InvalidCastException) { return(false); } imageInfo.Sectors = 0; foreach (byte[] bcem in bcems.Select(id => rsrc.GetResource(NDIF_RESOURCEID))) { if (bcem.Length < 128) { return(false); } header = Marshal.ByteArrayToStructureBigEndian <ChunkHeader>(bcem); DicConsole.DebugWriteLine("NDIF plugin", "footer.type = {0}", header.version); DicConsole.DebugWriteLine("NDIF plugin", "footer.driver = {0}", header.driver); DicConsole.DebugWriteLine("NDIF plugin", "footer.name = {0}", StringHandlers.PascalToString(header.name, Encoding.GetEncoding("macintosh"))); DicConsole.DebugWriteLine("NDIF plugin", "footer.sectors = {0}", header.sectors); DicConsole.DebugWriteLine("NDIF plugin", "footer.maxSectorsPerChunk = {0}", header.maxSectorsPerChunk); DicConsole.DebugWriteLine("NDIF plugin", "footer.dataOffset = {0}", header.dataOffset); DicConsole.DebugWriteLine("NDIF plugin", "footer.crc = 0x{0:X7}", header.crc); DicConsole.DebugWriteLine("NDIF plugin", "footer.segmented = {0}", header.segmented); DicConsole.DebugWriteLine("NDIF plugin", "footer.p1 = 0x{0:X8}", header.p1); DicConsole.DebugWriteLine("NDIF plugin", "footer.p2 = 0x{0:X8}", header.p2); DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[0] = 0x{0:X8}", header.unknown[0]); DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[1] = 0x{0:X8}", header.unknown[1]); DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[2] = 0x{0:X8}", header.unknown[2]); DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[3] = 0x{0:X8}", header.unknown[3]); DicConsole.DebugWriteLine("NDIF plugin", "footer.unknown[4] = 0x{0:X8}", header.unknown[4]); DicConsole.DebugWriteLine("NDIF plugin", "footer.encrypted = {0}", header.encrypted); DicConsole.DebugWriteLine("NDIF plugin", "footer.hash = 0x{0:X8}", header.hash); DicConsole.DebugWriteLine("NDIF plugin", "footer.chunks = {0}", header.chunks); // Block chunks and headers chunks = new Dictionary <ulong, BlockChunk>(); BigEndianBitConverter.IsLittleEndian = BitConverter.IsLittleEndian; for (int i = 0; i < header.chunks; i++) { // Obsolete read-only NDIF only prepended the header and then put the image without any kind of block references. // So let's falsify a block chunk BlockChunk bChnk = new BlockChunk(); byte[] sector = new byte[4]; Array.Copy(bcem, 128 + 0 + i * 12, sector, 1, 3); bChnk.sector = BigEndianBitConverter.ToUInt32(sector, 0); bChnk.type = bcem[128 + 3 + i * 12]; bChnk.offset = BigEndianBitConverter.ToUInt32(bcem, 128 + 4 + i * 12); bChnk.length = BigEndianBitConverter.ToUInt32(bcem, 128 + 8 + i * 12); DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].type = 0x{1:X2}", i, bChnk.type); DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].sector = {1}", i, bChnk.sector); DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].offset = {1}", i, bChnk.offset); DicConsole.DebugWriteLine("NDIF plugin", "bHdr.chunk[{0}].length = {1}", i, bChnk.length); if (bChnk.type == CHUNK_TYPE_END) { break; } bChnk.offset += header.dataOffset; bChnk.sector += (uint)imageInfo.Sectors; // TODO: Handle compressed chunks switch (bChnk.type) { case CHUNK_TYPE_KENCODE: throw new ImageNotSupportedException("Chunks compressed with KenCode are not yet supported."); case CHUNK_TYPE_LZH: throw new ImageNotSupportedException("Chunks compressed with LZH are not yet supported."); case CHUNK_TYPE_STUFFIT: throw new ImageNotSupportedException("Chunks compressed with StuffIt! are not yet supported."); } // TODO: Handle compressed chunks if (bChnk.type > CHUNK_TYPE_COPY && bChnk.type < CHUNK_TYPE_KENCODE || bChnk.type > CHUNK_TYPE_ADC && bChnk.type < CHUNK_TYPE_STUFFIT || bChnk.type > CHUNK_TYPE_STUFFIT && bChnk.type < CHUNK_TYPE_END || bChnk.type == 1) { throw new ImageNotSupportedException($"Unsupported chunk type 0x{bChnk.type:X8} found"); } chunks.Add(bChnk.sector, bChnk); } imageInfo.Sectors += header.sectors; } if (header.segmented > 0) { throw new ImageNotSupportedException("Segmented images are not yet supported."); } if (header.encrypted > 0) { throw new ImageNotSupportedException("Encrypted images are not yet supported."); } switch (imageInfo.Sectors) { case 1440: imageInfo.MediaType = MediaType.DOS_35_DS_DD_9; break; case 1600: imageInfo.MediaType = MediaType.AppleSonyDS; break; case 2880: imageInfo.MediaType = MediaType.DOS_35_HD; break; case 3360: imageInfo.MediaType = MediaType.DMF; break; default: imageInfo.MediaType = MediaType.GENERIC_HDD; break; } if (rsrcFork.ContainsKey(0x76657273)) { Resource versRsrc = rsrcFork.GetResource(0x76657273); if (versRsrc != null) { byte[] vers = versRsrc.GetResource(versRsrc.GetIds()[0]); Version version = new Version(vers); string release = null; string dev = null; string pre = null; string major = $"{version.MajorVersion}"; string minor = $".{version.MinorVersion / 10}"; if (version.MinorVersion % 10 > 0) { release = $".{version.MinorVersion % 10}"; } switch (version.DevStage) { case Version.DevelopmentStage.Alpha: dev = "a"; break; case Version.DevelopmentStage.Beta: dev = "b"; break; case Version.DevelopmentStage.PreAlpha: dev = "d"; break; } if (dev == null && version.PreReleaseVersion > 0) { dev = "f"; } if (dev != null) { pre = $"{version.PreReleaseVersion}"; } imageInfo.ApplicationVersion = $"{major}{minor}{release}{dev}{pre}"; imageInfo.Application = version.VersionString; imageInfo.Comments = version.VersionMessage; if (version.MajorVersion == 3) { imageInfo.Application = "ShrinkWrap™"; } else if (version.MajorVersion == 6) { imageInfo.Application = "DiskCopy"; } } } DicConsole.DebugWriteLine("NDIF plugin", "Image application = {0} version {1}", imageInfo.Application, imageInfo.ApplicationVersion); sectorCache = new Dictionary <ulong, byte[]>(); chunkCache = new Dictionary <ulong, byte[]>(); currentChunkCacheSize = 0; imageStream = imageFilter.GetDataForkStream(); buffersize = header.maxSectorsPerChunk * SECTOR_SIZE; imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); imageInfo.MediaTitle = StringHandlers.PascalToString(header.name, Encoding.GetEncoding("macintosh")); imageInfo.SectorSize = SECTOR_SIZE; imageInfo.XmlMediaType = XmlMediaType.BlockMedia; imageInfo.ImageSize = imageInfo.Sectors * SECTOR_SIZE; imageInfo.ApplicationVersion = "6"; imageInfo.Application = "Apple DiskCopy"; switch (imageInfo.MediaType) { case MediaType.AppleSonyDS: imageInfo.Cylinders = 80; imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 10; break; case MediaType.DOS_35_DS_DD_9: imageInfo.Cylinders = 80; imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 9; break; case MediaType.DOS_35_HD: imageInfo.Cylinders = 80; imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 18; break; case MediaType.DMF: imageInfo.Cylinders = 80; imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 21; break; default: imageInfo.MediaType = MediaType.GENERIC_HDD; imageInfo.Cylinders = (uint)(imageInfo.Sectors / 16 / 63); imageInfo.Heads = 16; imageInfo.SectorsPerTrack = 63; break; } return(true); }
public void UpdateBlock() { if (Time.time - flowSpeed > lastUpdate) { BlockChunk auxChunk = chunk; Vector3Int at = position; // Only check LEFT, RIGHT, FORWARD and BACK positions if the block below this one can support flow if (chunk.chunkData[position.x, position.y - 1, position.z] as Block_Liquid == null) { // BOTTOM at = new Vector3Int(at.x, at.y - 1, at.z); if (auxChunk.chunkData[at.x, at.y, at.z] == null) { auxChunk.chunkData[position.x, position.y - 1, position.z] = new Block_Liquid(auxChunk, at, maxFlow); auxChunk.pendingUpdate = true; lastUpdate = Time.time; pendingUpdate = false; return; } // Only flow vertically if flow is > 0 if (currentFlow > 0) { auxChunk = chunk; at = position; // FORWARD if (position.z + 1 >= BlockChunk.depth) { auxChunk = chunk.adjChunks[3]; at = new Vector3Int(at.x, at.y, 0); } else { at = new Vector3Int(at.x, at.y, at.z + 1); } if (auxChunk.chunkData[at.x, at.y, at.z] == null && chunk.chunkData[position.x, position.y - 1, position.z] != null) { auxChunk.chunkData[at.x, at.y, at.z] = new Block_Liquid(auxChunk, at, currentFlow - 1); auxChunk.pendingUpdate = true; } auxChunk = chunk; at = position; // RIGHT if (position.x + 1 >= BlockChunk.width) { auxChunk = chunk.adjChunks[5]; at = new Vector3Int(0, at.y, at.z); } else { at = new Vector3Int(at.x + 1, at.y, at.z); } if (auxChunk.chunkData[at.x, at.y, at.z] == null && chunk.chunkData[position.x, position.y - 1, position.z] != null) { auxChunk.chunkData[at.x, at.y, at.z] = new Block_Liquid(auxChunk, at, currentFlow - 1); auxChunk.pendingUpdate = true; } auxChunk = chunk; at = position; // LEFT if (position.x - 1 < 0) { auxChunk = chunk.adjChunks[1]; at = new Vector3Int(BlockChunk.width - 1, at.y, at.z); } else { at = new Vector3Int(at.x - 1, at.y, at.z); } if (auxChunk.chunkData[at.x, at.y, at.z] == null && chunk.chunkData[position.x, position.y - 1, position.z] != null) { auxChunk.chunkData[at.x, at.y, at.z] = new Block_Liquid(auxChunk, at, currentFlow - 1); auxChunk.pendingUpdate = true; } auxChunk = chunk; at = position; // BACK if (position.z - 1 < 0) { auxChunk = chunk.adjChunks[7]; at = new Vector3Int(at.x, at.y, BlockChunk.depth - 1); } else { at = new Vector3Int(at.x, at.y, at.z - 1); } if (auxChunk.chunkData[at.x, at.y, at.z] == null && chunk.chunkData[position.x, position.y - 1, position.z] != null) { auxChunk.chunkData[at.x, at.y, at.z] = new Block_Liquid(auxChunk, at, currentFlow - 1); auxChunk.pendingUpdate = true; } lastUpdate = Time.time; pendingUpdate = false; return; } } } }
public void Update() { if (bDirty) { bDirty = false; bNeedReselectPreview = true; DebugTool.Log("开始更新射线模块"); rtm.clearAll(); blockManager.forEachBlock((short block, int gx, int gy, int gz) => { if (block != (short)BlockTypeEnum.Air) { rtm.setBlock(gx, gy, gz, RayCastBlockType.All); } }); //初始化AO计算 RayMarchingAo rma = new RayMarchingAo(); rma.Init(rtm); foreach (var obj in objects) { GameObject.Destroy(obj); } objects.Clear(); //m_meshes.Clear(); DebugTool.Log("开始计算光照"); { //计算光照 Vector3 sunDir = new Vector3(1, -3, 1); sunDir.Normalize(); TerrainTool.calcLight(blockManager, rtm, rays, sunDir); } BlockTypeFun blockTypeFun = new BlockTypeFun(); //TerrainTool.calcLight2(blockManager, 16); DebugTool.Log("开始更新网格"); for (int i = 0; i < SpaceX; i++) { for (int k = 0; k < SpaceZ; k++) { for (int j = 0; j < SpaceY; j++) { BlockChunk chunk = new BlockChunk(blockManager, i * Const.ChunkSize, j * Const.ChunkSize, k * Const.ChunkSize); for (int f = 0; f < 6; f++) { List <MeshTool.BlockSurface> surface = MeshTool.getChunkSurface(chunk, blockTypeFun, f); Texture2D texSurface = MeshTool.SurfacePointsToTexture(surface, f); Texture2D readback = null; if (surface.Count > 0) { RenderTexture targetAoResult = rma.RenderByCalcShader(texSurface, new Vector3(i, j, k) * Const.ChunkSize, f); //回读亮度数据 RenderTexture.active = targetAoResult; readback = new Texture2D(targetAoResult.width, targetAoResult.height); readback.ReadPixels(new Rect(0, 0, targetAoResult.width, targetAoResult.width), 0, 0); MeshTool.SetRaytraceAo(surface, readback); } Mesh mesh = MeshTool.createMesh2(surface, f, blockTypeFun); if (mesh) { Vector3 pos = ((new Vector3(i, j, k))) * Const.ChunkSize - halfSpaceSize; if (mesh != null) { GameObject obj = new GameObject("Chunk", typeof(MeshRenderer), typeof(MeshFilter)); obj.isStatic = true; obj.GetComponent <Renderer>().material = GlobalResources.getBlockMaterial(); obj.GetComponent <MeshFilter>().mesh = mesh; obj.transform.position = pos; objects.Add(obj); } } } } } } DebugTool.Log("结束"); } }
// Set any block data protected virtual void SetupBlock(BlockChunk chunk = null, Vector3Int position = new Vector3Int()) { }
public virtual void GenerateCustomMesh(Vector3 at, BlockChunk chunk, ref Mesh refMesh, ref List <Vector3> verts, ref List <Vector3> normals, ref List <int> tris, ref List <Vector2> uvs, ref int meshIndex) { }
public void AddBlock(Vector3Int at) { Debug.Log(at); // Place in separate chunk if neccessary BlockChunk auxChunk = null; if (at.x == -1) { if (at.z == -1) { auxChunk = adjChunks[0]; at = new Vector3Int(width - 1, at.y, depth - 1); } else if (at.z == depth) { auxChunk = adjChunks[2]; at = new Vector3Int(width - 1, at.y, 0); } else { auxChunk = adjChunks[1]; at = new Vector3Int(width - 1, at.y, at.z); } } else if (at.x == width) { if (at.z == -1) { auxChunk = adjChunks[6]; at = new Vector3Int(0, at.y, depth - 1); } else if (at.z == depth) { auxChunk = adjChunks[4]; at = new Vector3Int(0, at.y, 0); } else { auxChunk = adjChunks[5]; at = new Vector3Int(0, at.y, at.z); } } else { if (at.z == -1) { auxChunk = adjChunks[7]; at = new Vector3Int(at.x, at.y, depth - 1); } else if (at.z == depth) { auxChunk = adjChunks[3]; at = new Vector3Int(at.x, at.y, 0); } } Debug.Log("New position is " + at); if (auxChunk == null) { auxChunk = this; } if (auxChunk.chunkData[at.x, at.y, at.z] == null || auxChunk.chunkData[at.x, at.y, at.z].Id == 0) { Debug.Log("Adding voxel at " + at); auxChunk.pendingUpdate = true; auxChunk.chunkData[at.x, at.y, at.z] = new Block_Liquid(this, at); if (at.x == 0) { if (auxChunk.adjChunks[1]) { auxChunk.adjChunks[1].pendingUpdate = true; } } else if (at.x == width - 1 && auxChunk.adjChunks[5]) { if (auxChunk.adjChunks[5]) { auxChunk.adjChunks[5].pendingUpdate = true; } } if (at.z == 0) { if (auxChunk.adjChunks[7]) { auxChunk.adjChunks[7].pendingUpdate = true; } } else if (at.z == depth - 1 && auxChunk.adjChunks[3]) { if (auxChunk.adjChunks[3]) { auxChunk.adjChunks[3].pendingUpdate = true; } } } else { Debug.Log("Block already at " + at); } }
private void setAdjChunk(BlockChunk source, BlockChunk target) { int x = target.chunkX - source.chunkX; int y = target.chunkY - source.chunkY; if (x == -1) { if (y == -1) { source.adjChunks[0] = target; target.adjChunks[4] = source; source.pendingUpdate = true; target.pendingUpdate = true; return; } else if (y == 0) { source.adjChunks[1] = target; target.adjChunks[5] = source; source.pendingUpdate = true; target.pendingUpdate = true; return; } else if (y == 1) { source.adjChunks[2] = target; target.adjChunks[6] = source; source.pendingUpdate = true; target.pendingUpdate = true; return; } } else if (x == 0) { if (y == -1) { source.adjChunks[7] = target; target.adjChunks[3] = source; source.pendingUpdate = true; target.pendingUpdate = true; return; } else if (y == 1) { source.adjChunks[3] = target; target.adjChunks[7] = source; source.pendingUpdate = true; target.pendingUpdate = true; return; } } else if (x == 1) { if (y == -1) { source.adjChunks[6] = target; target.adjChunks[2] = source; source.pendingUpdate = true; target.pendingUpdate = true; return; } else if (y == 0) { source.adjChunks[5] = target; target.adjChunks[1] = source; source.pendingUpdate = true; target.pendingUpdate = true; return; } else if (y == 1) { source.adjChunks[4] = target; target.adjChunks[0] = source; source.pendingUpdate = true; target.pendingUpdate = true; return; } } }
public bool Open(IFilter imageFilter) { Stream stream = imageFilter.GetDataForkStream(); if (stream.Length < 512) { return(false); } stream.Seek(-Marshal.SizeOf <UdifFooter>(), SeekOrigin.End); byte[] footerB = new byte[Marshal.SizeOf <UdifFooter>()]; stream.Read(footerB, 0, Marshal.SizeOf <UdifFooter>()); footer = Marshal.ByteArrayToStructureBigEndian <UdifFooter>(footerB); if (footer.signature != UDIF_SIGNATURE) { stream.Seek(0, SeekOrigin.Begin); footerB = new byte[Marshal.SizeOf <UdifFooter>()]; stream.Read(footerB, 0, Marshal.SizeOf <UdifFooter>()); footer = Marshal.ByteArrayToStructureBigEndian <UdifFooter>(footerB); if (footer.signature != UDIF_SIGNATURE) { throw new Exception("Unable to find UDIF signature."); } AaruConsole.VerboseWriteLine("Found obsolete UDIF format."); } AaruConsole.DebugWriteLine("UDIF plugin", "footer.signature = 0x{0:X8}", footer.signature); AaruConsole.DebugWriteLine("UDIF plugin", "footer.version = {0}", footer.version); AaruConsole.DebugWriteLine("UDIF plugin", "footer.headerSize = {0}", footer.headerSize); AaruConsole.DebugWriteLine("UDIF plugin", "footer.flags = {0}", footer.flags); AaruConsole.DebugWriteLine("UDIF plugin", "footer.runningDataForkOff = {0}", footer.runningDataForkOff); AaruConsole.DebugWriteLine("UDIF plugin", "footer.dataForkOff = {0}", footer.dataForkOff); AaruConsole.DebugWriteLine("UDIF plugin", "footer.dataForkLen = {0}", footer.dataForkLen); AaruConsole.DebugWriteLine("UDIF plugin", "footer.rsrcForkOff = {0}", footer.rsrcForkOff); AaruConsole.DebugWriteLine("UDIF plugin", "footer.rsrcForkLen = {0}", footer.rsrcForkLen); AaruConsole.DebugWriteLine("UDIF plugin", "footer.segmentNumber = {0}", footer.segmentNumber); AaruConsole.DebugWriteLine("UDIF plugin", "footer.segmentCount = {0}", footer.segmentCount); AaruConsole.DebugWriteLine("UDIF plugin", "footer.segmentId = {0}", footer.segmentId); AaruConsole.DebugWriteLine("UDIF plugin", "footer.dataForkChkType = {0}", footer.dataForkChkType); AaruConsole.DebugWriteLine("UDIF plugin", "footer.dataForkLen = {0}", footer.dataForkLen); AaruConsole.DebugWriteLine("UDIF plugin", "footer.dataForkChk = 0x{0:X8}", footer.dataForkChk); AaruConsole.DebugWriteLine("UDIF plugin", "footer.plistOff = {0}", footer.plistOff); AaruConsole.DebugWriteLine("UDIF plugin", "footer.plistLen = {0}", footer.plistLen); AaruConsole.DebugWriteLine("UDIF plugin", "footer.masterChkType = {0}", footer.masterChkType); AaruConsole.DebugWriteLine("UDIF plugin", "footer.masterChkLen = {0}", footer.masterChkLen); AaruConsole.DebugWriteLine("UDIF plugin", "footer.masterChk = 0x{0:X8}", footer.masterChk); AaruConsole.DebugWriteLine("UDIF plugin", "footer.imageVariant = {0}", footer.imageVariant); AaruConsole.DebugWriteLine("UDIF plugin", "footer.sectorCount = {0}", footer.sectorCount); AaruConsole.DebugWriteLine("UDIF plugin", "footer.reserved1 is empty? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(footer.reserved1)); AaruConsole.DebugWriteLine("UDIF plugin", "footer.reserved2 is empty? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(footer.reserved2)); AaruConsole.DebugWriteLine("UDIF plugin", "footer.reserved3 is empty? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(footer.reserved3)); AaruConsole.DebugWriteLine("UDIF plugin", "footer.reserved4 is empty? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(footer.reserved4)); // Block chunks and headers List <byte[]> blkxList = new List <byte[]>(); chunks = new Dictionary <ulong, BlockChunk>(); bool fakeBlockChunks = false; byte[] vers = null; if (footer.plistLen == 0 && footer.rsrcForkLen != 0) { AaruConsole.DebugWriteLine("UDIF plugin", "Reading resource fork."); byte[] rsrcB = new byte[footer.rsrcForkLen]; stream.Seek((long)footer.rsrcForkOff, SeekOrigin.Begin); stream.Read(rsrcB, 0, rsrcB.Length); var rsrc = new ResourceFork(rsrcB); if (!rsrc.ContainsKey(BLOCK_OS_TYPE)) { throw new ImageNotSupportedException("Image resource fork doesn't contain UDIF block chunks. Please fill an issue and send it to us."); } Resource blkxRez = rsrc.GetResource(BLOCK_OS_TYPE); if (blkxRez == null) { throw new ImageNotSupportedException("Image resource fork doesn't contain UDIF block chunks. Please fill an issue and send it to us."); } if (blkxRez.GetIds().Length == 0) { throw new ImageNotSupportedException("Image resource fork doesn't contain UDIF block chunks. Please fill an issue and send it to us."); } blkxList.AddRange(blkxRez.GetIds().Select(blkxId => blkxRez.GetResource(blkxId))); Resource versRez = rsrc.GetResource(0x76657273); if (versRez != null) { vers = versRez.GetResource(versRez.GetIds()[0]); } } else if (footer.plistLen != 0) { AaruConsole.DebugWriteLine("UDIF plugin", "Reading property list."); byte[] plistB = new byte[footer.plistLen]; stream.Seek((long)footer.plistOff, SeekOrigin.Begin); stream.Read(plistB, 0, plistB.Length); AaruConsole.DebugWriteLine("UDIF plugin", "Parsing property list."); var plist = (NSDictionary)XmlPropertyListParser.Parse(plistB); if (plist == null) { throw new Exception("Could not parse property list."); } if (!plist.TryGetValue(RESOURCE_FORK_KEY, out NSObject rsrcObj)) { throw new Exception("Could not retrieve resource fork."); } var rsrc = (NSDictionary)rsrcObj; if (!rsrc.TryGetValue(BLOCK_KEY, out NSObject blkxObj)) { throw new Exception("Could not retrieve block chunks array."); } NSObject[] blkx = ((NSArray)blkxObj).GetArray(); foreach (NSDictionary part in blkx.Cast <NSDictionary>()) { if (!part.TryGetValue("Name", out _)) { throw new Exception("Could not retrieve Name"); } if (!part.TryGetValue("Data", out NSObject dataObj)) { throw new Exception("Could not retrieve Data"); } blkxList.Add(((NSData)dataObj).Bytes); } if (rsrc.TryGetValue("vers", out NSObject versObj)) { NSObject[] versArray = ((NSArray)versObj).GetArray(); if (versArray.Length >= 1) { vers = ((NSData)versArray[0]).Bytes; } } } else { // Obsolete read-only UDIF only prepended the header and then put the image without any kind of block references. // So let's falsify a block chunk var bChnk = new BlockChunk { length = footer.dataForkLen, offset = footer.dataForkOff, sector = 0, sectors = footer.sectorCount, type = CHUNK_TYPE_COPY }; imageInfo.Sectors = footer.sectorCount; chunks.Add(bChnk.sector, bChnk); buffersize = 2048 * SECTOR_SIZE; fakeBlockChunks = true; } if (vers != null) { var version = new Version(vers); string release = null; string dev = null; string pre = null; string major = $"{version.MajorVersion}"; string minor = $".{version.MinorVersion / 10}"; if (version.MinorVersion % 10 > 0) { release = $".{version.MinorVersion % 10}"; } switch (version.DevStage) { case Version.DevelopmentStage.Alpha: dev = "a"; break; case Version.DevelopmentStage.Beta: dev = "b"; break; case Version.DevelopmentStage.PreAlpha: dev = "d"; break; } if (dev == null && version.PreReleaseVersion > 0) { dev = "f"; } if (dev != null) { pre = $"{version.PreReleaseVersion}"; } imageInfo.ApplicationVersion = $"{major}{minor}{release}{dev}{pre}"; imageInfo.Application = version.VersionString; imageInfo.Comments = version.VersionMessage; if (version.MajorVersion == 3) { imageInfo.Application = "ShrinkWrap™"; } else if (version.MajorVersion == 6) { imageInfo.Application = "DiskCopy"; } } else { imageInfo.Application = "DiskCopy"; } AaruConsole.DebugWriteLine("UDIF plugin", "Image application = {0} version {1}", imageInfo.Application, imageInfo.ApplicationVersion); imageInfo.Sectors = 0; if (!fakeBlockChunks) { if (blkxList.Count == 0) { throw new ImageNotSupportedException("Could not retrieve block chunks. Please fill an issue and send it to us."); } buffersize = 0; foreach (byte[] blkxBytes in blkxList) { var bHdr = new BlockHeader(); byte[] bHdrB = new byte[Marshal.SizeOf <BlockHeader>()]; Array.Copy(blkxBytes, 0, bHdrB, 0, Marshal.SizeOf <BlockHeader>()); bHdr = Marshal.ByteArrayToStructureBigEndian <BlockHeader>(bHdrB); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.signature = 0x{0:X8}", bHdr.signature); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.version = {0}", bHdr.version); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.sectorStart = {0}", bHdr.sectorStart); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.sectorCount = {0}", bHdr.sectorCount); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.dataOffset = {0}", bHdr.dataOffset); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.buffers = {0}", bHdr.buffers); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.descriptor = 0x{0:X8}", bHdr.descriptor); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.reserved1 = {0}", bHdr.reserved1); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.reserved2 = {0}", bHdr.reserved2); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.reserved3 = {0}", bHdr.reserved3); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.reserved4 = {0}", bHdr.reserved4); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.reserved5 = {0}", bHdr.reserved5); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.reserved6 = {0}", bHdr.reserved6); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.checksumType = {0}", bHdr.checksumType); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.checksumLen = {0}", bHdr.checksumLen); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.checksum = 0x{0:X8}", bHdr.checksum); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.chunks = {0}", bHdr.chunks); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.reservedChk is empty? = {0}", ArrayHelpers.ArrayIsNullOrEmpty(bHdr.reservedChk)); if (bHdr.buffers > buffersize) { buffersize = bHdr.buffers * SECTOR_SIZE; } for (int i = 0; i < bHdr.chunks; i++) { var bChnk = new BlockChunk(); byte[] bChnkB = new byte[Marshal.SizeOf <BlockChunk>()]; Array.Copy(blkxBytes, Marshal.SizeOf <BlockHeader>() + (Marshal.SizeOf <BlockChunk>() * i), bChnkB, 0, Marshal.SizeOf <BlockChunk>()); bChnk = Marshal.ByteArrayToStructureBigEndian <BlockChunk>(bChnkB); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.chunk[{0}].type = 0x{1:X8}", i, bChnk.type); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.chunk[{0}].comment = {1}", i, bChnk.comment); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.chunk[{0}].sector = {1}", i, bChnk.sector); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.chunk[{0}].sectors = {1}", i, bChnk.sectors); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.chunk[{0}].offset = {1}", i, bChnk.offset); AaruConsole.DebugWriteLine("UDIF plugin", "bHdr.chunk[{0}].length = {1}", i, bChnk.length); if (bChnk.type == CHUNK_TYPE_END) { break; } imageInfo.Sectors += bChnk.sectors; // Chunk offset is relative bChnk.sector += bHdr.sectorStart; bChnk.offset += bHdr.dataOffset; switch (bChnk.type) { // TODO: Handle comments case CHUNK_TYPE_COMMNT: continue; // TODO: Handle compressed chunks case CHUNK_TYPE_KENCODE: throw new ImageNotSupportedException("Chunks compressed with KenCode are not yet supported."); case CHUNK_TYPE_LZH: throw new ImageNotSupportedException("Chunks compressed with LZH are not yet supported."); case CHUNK_TYPE_LZFSE: throw new ImageNotSupportedException("Chunks compressed with lzfse are not yet supported."); } if ((bChnk.type > CHUNK_TYPE_NOCOPY && bChnk.type < CHUNK_TYPE_COMMNT) || (bChnk.type > CHUNK_TYPE_LZFSE && bChnk.type < CHUNK_TYPE_END)) { throw new ImageNotSupportedException($"Unsupported chunk type 0x{bChnk.type:X8} found"); } if (bChnk.sectors > 0) { chunks.Add(bChnk.sector, bChnk); } } } } sectorCache = new Dictionary <ulong, byte[]>(); chunkCache = new Dictionary <ulong, byte[]>(); currentChunkCacheSize = 0; imageStream = stream; imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); imageInfo.SectorSize = SECTOR_SIZE; imageInfo.XmlMediaType = XmlMediaType.BlockMedia; imageInfo.MediaType = MediaType.GENERIC_HDD; imageInfo.ImageSize = imageInfo.Sectors * SECTOR_SIZE; imageInfo.Version = $"{footer.version}"; imageInfo.Cylinders = (uint)(imageInfo.Sectors / 16 / 63); imageInfo.Heads = 16; imageInfo.SectorsPerTrack = 63; return(true); }
public override void GenerateCustomMesh(Vector3 at, BlockChunk chunk, ref Mesh refMesh, ref List <Vector3> vertices, ref List <Vector3> normals, ref List <int> tri, ref List <Vector2> uv, ref int vertexId) { int x = (int)at.x, y = (int)at.y, z = (int)at.z; int width = BlockChunk.width, height = BlockChunk.height, depth = BlockChunk.depth; // TOP if (y < height - 1) { if (chunk.chunkData[x, y + 1, z] == null || chunk.chunkData[x, y + 1, z].Id != 1) { vertices.Add(new Vector3(x, 1 + y, z)); vertices.Add(new Vector3(x + 1, 1 + y, z)); vertices.Add(new Vector3(x, 1 + y, z + 1)); vertices.Add(new Vector3(x + 1, 1 + y, z + 1)); tri.Add(vertexId); tri.Add(vertexId + 2); tri.Add(vertexId + 1); tri.Add(vertexId + 2); tri.Add(vertexId + 3); tri.Add(vertexId + 1); normals.Add(Vector3.up); normals.Add(Vector3.up); normals.Add(Vector3.up); normals.Add(Vector3.up); uv.Add(new Vector2(0, 0)); uv.Add(new Vector2(.5f, 0)); uv.Add(new Vector2(0, 1)); uv.Add(new Vector2(.5f, 1)); vertexId += 4; } } // BOTTOM if (y > 0) { if (chunk.chunkData[x, y - 1, z] == null || chunk.chunkData[x, y - 1, z].Id != 1) { vertices.Add(new Vector3(x, y, z)); vertices.Add(new Vector3(x, y, z + 1)); vertices.Add(new Vector3(x + 1, y, z)); vertices.Add(new Vector3(x + 1, y, z + 1)); tri.Add(vertexId); tri.Add(vertexId + 2); tri.Add(vertexId + 1); tri.Add(vertexId + 2); tri.Add(vertexId + 3); tri.Add(vertexId + 1); normals.Add(-Vector3.up); normals.Add(-Vector3.up); normals.Add(-Vector3.up); normals.Add(-Vector3.up); uv.Add(new Vector2(0, 0)); uv.Add(new Vector2(.5f, 0)); uv.Add(new Vector2(0, 1)); uv.Add(new Vector2(.5f, 1)); vertexId += 4; } } // RIGHT if (x < width - 1) { if (chunk.chunkData[x + 1, y, z] == null || chunk.chunkData[x + 1, y, z].Id != 1) { vertices.Add(new Vector3(1 + x, y, z)); vertices.Add(new Vector3(1 + x, y, z + 1)); vertices.Add(new Vector3(1 + x, y + 1, z)); vertices.Add(new Vector3(1 + x, y + 1, z + 1)); tri.Add(vertexId); tri.Add(vertexId + 2); tri.Add(vertexId + 1); tri.Add(vertexId + 2); tri.Add(vertexId + 3); tri.Add(vertexId + 1); normals.Add(Vector3.right); normals.Add(Vector3.right); normals.Add(Vector3.right); normals.Add(Vector3.right); uv.Add(new Vector2(0, 0)); uv.Add(new Vector2(.5f, 0)); uv.Add(new Vector2(0, 1)); uv.Add(new Vector2(.5f, 1)); vertexId += 4; } } else if (chunk.adjChunks[5] != null) { if (chunk.adjChunks[5].chunkData[0, y, z] == null || chunk.adjChunks[5].chunkData[0, y, z].Id != 1) { vertices.Add(new Vector3(1 + x, y, z)); vertices.Add(new Vector3(1 + x, y, z + 1)); vertices.Add(new Vector3(1 + x, y + 1, z)); vertices.Add(new Vector3(1 + x, y + 1, z + 1)); tri.Add(vertexId); tri.Add(vertexId + 2); tri.Add(vertexId + 1); tri.Add(vertexId + 2); tri.Add(vertexId + 3); tri.Add(vertexId + 1); normals.Add(Vector3.right); normals.Add(Vector3.right); normals.Add(Vector3.right); normals.Add(Vector3.right); uv.Add(new Vector2(0, 0)); uv.Add(new Vector2(.5f, 0)); uv.Add(new Vector2(0, 1)); uv.Add(new Vector2(.5f, 1)); vertexId += 4; } } // FRONT if (z < depth - 1) { if (chunk.chunkData[x, y, z + 1] == null || chunk.chunkData[x, y, z + 1].Id != 1) { vertices.Add(new Vector3(x, y, z + 1)); vertices.Add(new Vector3(x + 1, y, z + 1)); vertices.Add(new Vector3(x, y + 1, z + 1)); vertices.Add(new Vector3(x + 1, y + 1, z + 1)); tri.Add(vertexId + 1); tri.Add(vertexId + 2); tri.Add(vertexId); tri.Add(vertexId + 1); tri.Add(vertexId + 3); tri.Add(vertexId + 2); normals.Add(Vector3.forward); normals.Add(Vector3.forward); normals.Add(Vector3.forward); normals.Add(Vector3.forward); uv.Add(new Vector2(0, 0)); uv.Add(new Vector2(.5f, 0)); uv.Add(new Vector2(0, 1)); uv.Add(new Vector2(.5f, 1)); vertexId += 4; } } else if (chunk.adjChunks[3] != null) { if (chunk.adjChunks[3].chunkData[x, y, 0] == null || chunk.adjChunks[3].chunkData[x, y, 0].Id != 1) { vertices.Add(new Vector3(x, y, z + 1)); vertices.Add(new Vector3(x + 1, y, z + 1)); vertices.Add(new Vector3(x, y + 1, z + 1)); vertices.Add(new Vector3(x + 1, y + 1, z + 1)); tri.Add(vertexId + 1); tri.Add(vertexId + 2); tri.Add(vertexId); tri.Add(vertexId + 1); tri.Add(vertexId + 3); tri.Add(vertexId + 2); normals.Add(Vector3.forward); normals.Add(Vector3.forward); normals.Add(Vector3.forward); normals.Add(Vector3.forward); uv.Add(new Vector2(0, 0)); uv.Add(new Vector2(.5f, 0)); uv.Add(new Vector2(0, 1)); uv.Add(new Vector2(.5f, 1)); vertexId += 4; } } // LEFT if (x > 0) { if (chunk.chunkData[x - 1, y, z] == null || chunk.chunkData[x - 1, y, z].Id != 1) { vertices.Add(new Vector3(x, y, z)); vertices.Add(new Vector3(x, y + 1, z)); vertices.Add(new Vector3(x, y, z + 1)); vertices.Add(new Vector3(x, y + 1, z + 1)); tri.Add(vertexId); tri.Add(vertexId + 2); tri.Add(vertexId + 1); tri.Add(vertexId + 2); tri.Add(vertexId + 3); tri.Add(vertexId + 1); normals.Add(-Vector3.right); normals.Add(-Vector3.right); normals.Add(-Vector3.right); normals.Add(-Vector3.right); uv.Add(new Vector2(0, 0)); uv.Add(new Vector2(.5f, 0)); uv.Add(new Vector2(0, 1)); uv.Add(new Vector2(.5f, 1)); vertexId += 4; } } else if (chunk.adjChunks[1] != null) { if (chunk.adjChunks[1].chunkData[width - 1, y, z] == null || chunk.adjChunks[1].chunkData[width - 1, y, z].Id != 1) { vertices.Add(new Vector3(x, y, z)); vertices.Add(new Vector3(x, y + 1, z)); vertices.Add(new Vector3(x, y, z + 1)); vertices.Add(new Vector3(x, y + 1, z + 1)); tri.Add(vertexId); tri.Add(vertexId + 2); tri.Add(vertexId + 1); tri.Add(vertexId + 2); tri.Add(vertexId + 3); tri.Add(vertexId + 1); normals.Add(-Vector3.right); normals.Add(-Vector3.right); normals.Add(-Vector3.right); normals.Add(-Vector3.right); uv.Add(new Vector2(0, 0)); uv.Add(new Vector2(.5f, 0)); uv.Add(new Vector2(0, 1)); uv.Add(new Vector2(.5f, 1)); vertexId += 4; } } // BACK if (z > 0) { if (chunk.chunkData[x, y, z - 1] == null || chunk.chunkData[x, y, z - 1].Id != 1) { vertices.Add(new Vector3(x, y, z)); vertices.Add(new Vector3(x, y + 1, z)); vertices.Add(new Vector3(x + 1, y, z)); vertices.Add(new Vector3(x + 1, y + 1, z)); tri.Add(vertexId + 1); tri.Add(vertexId + 2); tri.Add(vertexId); tri.Add(vertexId + 1); tri.Add(vertexId + 3); tri.Add(vertexId + 2); normals.Add(-Vector3.forward); normals.Add(-Vector3.forward); normals.Add(-Vector3.forward); normals.Add(-Vector3.forward); uv.Add(new Vector2(0, 0)); uv.Add(new Vector2(.5f, 0)); uv.Add(new Vector2(0, 1)); uv.Add(new Vector2(.5f, 1)); vertexId += 4; } } else if (chunk.adjChunks[7] != null) { if (chunk.adjChunks[7].chunkData[x, y, depth - 1] == null || chunk.adjChunks[7].chunkData[x, y, depth - 1].Id != 1) { vertices.Add(new Vector3(x, y, z)); vertices.Add(new Vector3(x, y + 1, z)); vertices.Add(new Vector3(x + 1, y, z)); vertices.Add(new Vector3(x + 1, y + 1, z)); tri.Add(vertexId + 1); tri.Add(vertexId + 2); tri.Add(vertexId); tri.Add(vertexId + 1); tri.Add(vertexId + 3); tri.Add(vertexId + 2); normals.Add(-Vector3.forward); normals.Add(-Vector3.forward); normals.Add(-Vector3.forward); normals.Add(-Vector3.forward); uv.Add(new Vector2(0, 0)); uv.Add(new Vector2(.5f, 0)); uv.Add(new Vector2(0, 1)); uv.Add(new Vector2(.5f, 1)); vertexId += 4; } } }
IEnumerator InitWorld() { Block.BlockManager bm = new Block.BlockManager(); for (int i = 0; i < (int)Game.BlockType.Num; i++) { for (int f = 0; f < 6; f++) { Game.BlockType block = (Game.BlockType)i; texturePacker.AddTexture(block, f, TextureNameConfig.GetTextureName(block, f)); } } texturePacker.Pack(); packedTexture = texturePacker.GetPackedTexture(); BlockTypeFun blockTypeFun = new BlockTypeFun(); blockTypeFun.texturePacker = texturePacker; //float startTime = Time.realtimeSinceStartup; int WorldSizeX = 8; int WorldSizeY = 2; int WorldSizeZ = 8; //申请内存 bm.create(WorldSizeX * Const.ChunkSize, WorldSizeY * Const.ChunkSize, WorldSizeZ * Const.ChunkSize, blockTypeFun); DebugTool.Log("申请内存"); yield return(null); // TerrainTool.createTerrain(bm, WorldSizeX, WorldSizeY, WorldSizeZ); DebugTool.Log("创建地形"); yield return(null); TerrainTool.createTree(bm, WorldSizeX, WorldSizeY, WorldSizeZ); DebugTool.Log("创建树"); yield return(null); List <HouseItem> houseItems = new List <HouseItem>(); TerrainTool.createBuildings(bm, ref houseItems); DebugTool.Log("创建建筑完成"); yield return(null); //光线追踪初始化 RayCastManager rtm = new RayCastManager(); rtm.create(bm.SizeX, bm.SizeY, bm.SizeZ); for (int x = 0; x < rtm.getSizeX(); x++) { for (int z = 0; z < rtm.getSizeZ(); z++) { for (int y = 0; y < rtm.getSizeY(); y++) { short block = bm.getBlock(x, y, z); RayCastBlockType rlt = 0; rlt |= blockTypeFun.isCollider(block) ? RayCastBlockType.Collider : RayCastBlockType.Nothing; rlt |= blockTypeFun.isOpacity(block) ? RayCastBlockType.Opacity : RayCastBlockType.Nothing; rtm.setBlock(x, y, z, rlt); } rtm.updateInSun(x, z); } } //预处理光线 Vector3[][] rays = new Vector3[6][]; { for (int i = 0; i < 6; i++) { rays[i] = TerrainTool.getRandomRays(9, i); } } DebugTool.Log("预处理光线追踪完成"); yield return(null); rtm.updateAllLight(); DebugTool.Log("扩散光照计算完毕"); yield return(null); //int[] lightCount = new int[Const.MaxLightIteration + 1]; //for (int i = 0; i < WorldSizeX * Const.ChunkSize; i++) { // for (int k = 0; k < WorldSizeZ * Const.ChunkSize; k++) { // for (int j = 0; j < WorldSizeY * Const.ChunkSize; j++) { // lightCount[rtm.getLight(i, j, k)]++; // } // } //} //for (int i = 0; i < lightCount.Length; i++) { // Debug.Log("light (" + i + ") = " + lightCount[i]); //} Texture2D lightMap = new Texture2D(256, 256, TextureFormat.RGBAHalf, false); Color[] colors = new Color[256 * 256]; for (int i = 0; i < 256; i++) { for (int j = 0; j < 256; j++) { colors[j * 256 + i] = new Color(i / 256.0f, i / 256.0f, i / 256.0f, 1) * 2; } } lightMap.SetPixels(colors); lightMap.Apply(); LightmapData[] lightmaps = new LightmapData[1]; lightmaps[0] = new LightmapData(); lightmaps[0].lightmapFar = lightMap; lightmaps[0].lightmapNear = lightMap; LightmapSettings.lightmaps = lightmaps; GameObject itemsRoot = new GameObject("items"); for (int i = 0; i < houseItems.Count; i++) { HouseItem item = houseItems[i]; string path = HouseItemGenerator.GetItemPrefabPath(item.item); GameObject prefab = GlobalResources.loadPrefab(path); if (prefab != null) { GameObject inst = GameObject.Instantiate <GameObject>(prefab); inst.name = houseItems[i].item.ToString(); inst.transform.parent = itemsRoot.transform; inst.transform.position = houseItems[i].pos + new Vector3(0.5f, 0f, 0.5f); MeshRenderer renderer = inst.GetComponentInChildren <MeshRenderer>(); renderer.lightmapIndex = 0; inst.isStatic = true; float light = rtm.getLight(item.pos.x, item.pos.y, item.pos.z) / (float)Const.MaxLightIteration; light = Mathf.Lerp(0.0f, 0.6f, light); renderer.lightmapScaleOffset = new Vector4(0, 0, light, 0f); //MeshFilter meshFilter = inst.GetComponentInChildren<MeshFilter>(); //Mesh mesh = meshFilter.mesh; //Color32[] colors = new Color32[mesh.colors.Length]; //byte c = (byte)(rtm.getLight(item.pos.x, item.pos.y, item.pos.z) * 255); //ArrayTool.SetAll(colors, new Color32(c,c,c,1)); //mesh.colors32 = colors; } else { int a = 0; } } //初始化AO计算 rma = new RayMarchingAo(); rma.Init(rtm); //ViewVoxel viewVoxel = GameObject.FindObjectOfType<ViewVoxel>(); //if (viewVoxel) { // Texture3D voxelTex3D = rma.GetVoxelTexture(); // //OpenGLLibrary.glEnable(OpenGL.GL_TEXTURE_3D); // //OpenGLLibrary.glBindTexture(OpenGL.GL_TEXTURE_3D, voxelTex3D.GetNativeTexturePtr()); // //byte[] data = new byte[voxelTex3D.width * voxelTex3D.height * voxelTex3D.depth * 4]; // //for (int i = 0; i < data.Length; i++ ){ // // data[i] = 0x56; // //} // //OpenGL.TexSubImage3D(OpenGL.GL_TEXTURE_3D, 0, 0, 0, 0, 32, 32, 32, OpenGL.GL_RGBA, OpenGL.GL_UNSIGNED_BYTE, ref data); // //OpenGL.TextureSubImage3D(voxelTex3D, 0, 0, 0, 0, 1, 1, 1, OpenGL.GL_RED, OpenGL.GL_UNSIGNED_BYTE, ref data); // viewVoxel.SetVexelTex(voxelTex3D); //} //计算光照 Vector3 sunDir = new Vector3(1, -3, 1); sunDir.Normalize(); { //TerrainTool.calcLight(bm, rtm, rays, sunDir); //TerrainTool.calcLight2(bm,32); } DebugTool.Log("计算光照完成"); yield return(null); Material mat = GlobalResources.getBlockMaterial(); mat.mainTexture = texturePacker.GetPackedTexture(); GameObject root = GameObject.Find("Root"); if (root == null) { root = new GameObject("Root"); } Level level = GameObject.FindObjectOfType <Level>(); if (level) { level.scene = rtm; } //创建网格 for (int i = 0; i < WorldSizeX; i++) { for (int k = 0; k < WorldSizeZ; k++) { for (int j = 0; j < WorldSizeY; j++) { int baseX = i * Const.ChunkSize; int baseY = j * Const.ChunkSize; int baseZ = k * Const.ChunkSize; BlockChunk chunk = new BlockChunk(bm, baseX, baseY, baseZ); Vector3 chunkPos = new Vector3(i * Const.ChunkSize * Const.BlockSize, j * Const.ChunkSize * Const.BlockSize, k * Const.ChunkSize * Const.BlockSize); //bool[,,] visibleBlocks = new bool[Const.ChunkSize,Const.ChunkSize,Const.ChunkSize];// = MeshTool.GetVisibleBlocks(chunk, blockTypeFun); //TerrainTool.calcChunkLight(chunk, i, j, k, rtm, rays, sunDir); //Mesh mesh = MeshTool.createMesh(chunk, blockTypeFun, 0, 0, 0); for (int f = 0; f < 6; f++) { List <MeshTool.BlockSurface> surface = MeshTool.getChunkSurface(chunk, blockTypeFun, f); //for (int s = 0; s < surface.Count; s++) { // visibleBlocks[surface[s].pos.x, surface[s].pos.y, surface[s].pos.z] = true; //} Texture2D texSurface = MeshTool.SurfacePointsToTexture(surface, f); RenderTexture targetAoResult = rma.RenderByCalcShader(texSurface, new Vector3(i, j, k) * Const.ChunkSize, f); //回读亮度数据 RenderTexture.active = targetAoResult; Texture2D readback = new Texture2D(targetAoResult.width, targetAoResult.height); readback.ReadPixels(new Rect(0, 0, targetAoResult.width, targetAoResult.width), 0, 0); MeshTool.SetRaytraceAo(surface, readback); MeshTool.SetExtendAo(surface, rtm, f, new VecInt3(i * Const.ChunkSize, j * Const.ChunkSize, k * Const.ChunkSize)); //将可行走区域标记黑色 //if (f == (int)BlockFaceIndex.BFI_y1) { // for (int s = 0; s < surface.Count; s++) { // int gx = baseX + surface[s].pos.x; // int gy = baseY + surface[s].pos.y; // int gz = baseZ + surface[s].pos.z; // if (rtm.testBlock(gx, gy, gz, (byte)RayTraceBlockType.Walkable)) { // for (int v = 0; v < 4; v++) { // surface[s].raytraceAo[v] *= 0.1f; // } // } // } //} Mesh mesh = MeshTool.createMesh2(surface, f, blockTypeFun); if (mesh != null) { GameObject obj = new GameObject("Chunk", typeof(MeshRenderer), typeof(MeshFilter)); obj.isStatic = true; obj.GetComponent <Renderer>().material = mat; obj.GetComponent <MeshFilter>().mesh = mesh; obj.transform.SetParent(root.transform); obj.transform.position = chunkPos; } } //physics.AddChunk(visibleBlocks, chunkPos); yield return(null); } } } StaticBatchingUtility.Combine(root); StaticBatchingUtility.Combine(itemsRoot); DebugTool.Log("生成网格"); yield return(null); }