Example #1
0
        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);
            }
        }
Example #2
0
        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]]);
                }
            }
        }