public TransitionCache() { const int cacheSize = 0; // 2 * TransvoxelExtractor.BlockWidth * TransvoxelExtractor.BlockWidth; _cache = new ReuseCell[cacheSize]; for (int i = 0; i < cacheSize; i++) { _cache[i] = new ReuseCell(12); } }
public RegularCellCache(int chunksize) { this.chunkSize = chunksize; _cache = new ReuseCell[2][]; _cache[0] = new ReuseCell[chunkSize * chunkSize]; _cache[1] = new ReuseCell[chunkSize * chunkSize]; for (int i = 0; i < chunkSize * chunkSize; i++) { _cache[0][i] = new ReuseCell(4); _cache[1][i] = new ReuseCell(4); } }
private void PolygonizeCell(Vector3int16 offsetPos, Vector3int16 pos, ref List <TerrainVertex> vertices, ref List <ushort> indices, int lod) { Debug.Assert(lod >= 1, "Level of Detail must be greater than 1"); offsetPos *= Terrain.ChunkSize; offsetPos += pos * lod; byte directionMask = (byte)((pos.x > 0 ? 1 : 0) | ((pos.z > 0 ? 1 : 0) << 1) | ((pos.y > 0 ? 1 : 0) << 2)); sbyte[] density = new sbyte[8]; for (int i = 0; i < density.Length; i++) { density[i] = _volume[offsetPos + CornerIndex[i] * lod].Density; } byte caseCode = GetCaseCode(density); if ((caseCode ^ ((density[7] >> 7) & 0xFF)) == 0) //for this cases there is no triangulation { return; } var cornerNormals = new Vector3[8]; for (int i = 0; i < 8; i++) { var p = offsetPos + CornerIndex[i] * lod; float nx = (_volume.GetCell(p.x + 1, p.y, p.z).Density - _volume[p - Vector3int16.Right].Density) * 0.5f; float ny = (_volume[p + Vector3int16.Up].Density - _volume[p - Vector3int16.Up].Density) * 0.5f; float nz = (_volume[p + Vector3int16.Backward].Density - _volume[p - Vector3int16.Backward].Density) * 0.5f; cornerNormals[i].Set(nx, ny, nz); cornerNormals[i].Normalize(); } byte regularCellClass = RegularCellClass[caseCode]; ushort[] vertexLocations = RegularVertexData[caseCode]; var c = RegularCellData[regularCellClass]; long vertexCount = c.GetVertexCount(); long triangleCount = c.GetTriangleCount(); byte[] indexOffset = c.Indices(); //index offsets for current cell ushort[] mappedIndizes = new ushort[indexOffset.Length]; //array with real indizes for current cell for (int i = 0; i < vertexCount; i++) { byte edge = (byte)(vertexLocations[i] >> 8); byte reuseIndex = (byte)(edge & 0xF); //Vertex id which should be created or reused 1,2 or 3 byte rDir = (byte)(edge >> 4); //the direction to go to reach a previous cell for reusing byte v1 = (byte)((vertexLocations[i]) & 0x0F); //Second Corner Index byte v0 = (byte)((vertexLocations[i] >> 4) & 0x0F); //First Corner Index sbyte d0 = density[v0]; sbyte d1 = density[v1]; //Vector3f n0 = cornerNormals[v0]; //Vector3f n1 = cornerNormals[v1]; Debug.Assert(v1 > v0); int t = (d1 << 8) / (d1 - d0); int u = 0x0100 - t; float t0 = t / 256f; float t1 = u / 256f; int index = -1; if (UseCache && v1 != 7 && (rDir & directionMask) == rDir) { Debug.Assert(reuseIndex != 0); ReuseCell cell = _cache.GetReusedIndex(pos, rDir); index = cell.Verts[reuseIndex]; } if (index == -1) { var normal = cornerNormals[v0] * t0 + cornerNormals[v1] * t1; GenerateVertex(ref offsetPos, ref pos, ref vertices, lod, t, ref v0, ref v1, ref d0, ref d1, ref normal); index = vertices.Count - 1; } if ((rDir & 8) != 0) { _cache.SetReusableIndex(pos, reuseIndex, (ushort)(vertices.Count - 1)); } mappedIndizes[i] = (ushort)index; } for (int t = 0; t < triangleCount; t++) { for (int i = 0; i < 3; i++) { indices.Add(mappedIndizes[c.Indices()[t * 3 + i]]); } } }