private static void AddVertexToBuffer(MySingleMaterialHelper materialHelper, ref MyVoxelVertex vertex0,
                                              int matIndex, short vertexIndex0)
        {
            if (MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matIndex][vertexIndex0].CalcCounter !=
                MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookupCount[matIndex])
            {
                int nextVertexIndex = materialHelper.VertexCount;

                //  Short overflow check
                System.Diagnostics.Debug.Assert(nextVertexIndex <= short.MaxValue);

                // copy position and ambient
                materialHelper.Vertices[nextVertexIndex].m_positionAndAmbient = vertex0.m_positionAndAmbient;
                materialHelper.Vertices[nextVertexIndex].Ambient = vertex0.Ambient;

                // Copy normal
#if PACKED_VERTEX_FORMAT
                materialHelper.Vertices[nextVertexIndex].m_normal = vertex0.m_normal;
#else
                materialHelper.Vertices[nextVertexIndex].Normal = vertex0.Normal;
#endif

                MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matIndex][vertexIndex0].CalcCounter =
                    MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookupCount[matIndex];
                MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matIndex][vertexIndex0].VertexIndex =
                    (short)nextVertexIndex;

                materialHelper.VertexCount++;
            }
        }
        public void AddVertex(ref MyVoxelVertex vertex)//Vector3 pos, Vector3 normal, MyMwcVoxelMaterialsEnum material, float ambient)
        {
            var  material = vertex.Material;
            byte alphaIndex;

            if (Material0 == material)
            {
                alphaIndex = 0;
            }
            else if (Material1 == material)
            {
                alphaIndex = 1;
            }
            else if (Material2 == material)
            {
                alphaIndex = 2;
            }
            else
            {
                throw new System.InvalidOperationException("Should not be there, invalid material");
            }

            Vertices[VertexCount].m_positionAndAmbient = vertex.m_positionAndAmbient;
            Vertices[VertexCount].Ambient = vertex.Ambient;

#if PACKED_VERTEX_FORMAT
            Vertices[VertexCount].m_normal = vertex.m_normal;
#else
            Vertices[VertexCount].Normal = vertex.Normal;
#endif

            Vertices[VertexCount].MaterialAlphaIndex = alphaIndex;
            VertexCount++;
        }
예제 #3
0
        public void PrepareCache(MyVoxelVertex[] vertices, int vertexCount, MyVoxelTriangle[] triangles, int triangleCount)
        {
            lock (m_syncRoot)
            {
                if (vertexCount == 0)
                {
                    VoxelVerticesCount = 0;
                    VoxelTrianglesCount = 0;
                    m_octree = null;
                    VoxelVertices = null;
                    return;
                }
                MyCommonDebugUtils.AssertDebug(vertexCount <= Int16.MaxValue);

                MyRender.GetRenderProfiler().StartProfilingBlock("build octree");
                if (m_octree == null)
                    m_octree = new MyOctree();
                m_octree.Init(ref vertices, ref vertexCount, ref triangles, ref triangleCount, out VoxelTriangles);
                MyRender.GetRenderProfiler().EndProfilingBlock();

                // copy voxel vertices
                VoxelVertices = new MyVoxelVertex[vertexCount];
                for (int i = 0; i < vertexCount; i++)
                    VoxelVertices[i] = vertices[i];

                // set size only after the arrays are fully allocated
                VoxelVerticesCount = vertexCount;
                VoxelTrianglesCount = triangleCount;
            }
        }
        public void AddVertex(ref MyVoxelVertex vertex)//Vector3 pos, Vector3 normal, MyVoxelMaterialsEnum material, float ambient)
        {
            var  material = vertex.Material;
            byte alphaIndex;

            if (Material0.Index == material)
            {
                alphaIndex = 0;
            }
            else if (Material1.Index == material)
            {
                alphaIndex = 1;
            }
            else if (Material2.Index == material)
            {
                alphaIndex = 2;
            }
            else
            {
                throw new System.InvalidOperationException("Should not be there, invalid material");
            }

            Vertices[VertexCount].Position           = vertex.Position;
            Vertices[VertexCount].Ambient            = vertex.Ambient;
            Vertices[VertexCount].Normal             = vertex.Normal;
            Vertices[VertexCount].MaterialAlphaIndex = alphaIndex;
            VertexCount++;
        }
        private static void AddVertexToBuffer(MySingleMaterialHelper materialHelper, ref MyVoxelVertex vertex0,
                                              int matIndex, short vertexIndex0)
        {
            MyVoxelCacheCellRenderHelper.CreateArrayIfNotExist(matIndex);

            if (MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matIndex][vertexIndex0].CalcCounter !=
                MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookupCount[matIndex])
            {
                int nextVertexIndex = materialHelper.VertexCount;

                //  Short overflow check
                System.Diagnostics.Debug.Assert(nextVertexIndex <= short.MaxValue);

                // copy position and ambient
                materialHelper.Vertices[nextVertexIndex].Position = vertex0.Position;
                materialHelper.Vertices[nextVertexIndex].Ambient  = vertex0.Ambient;

                // Copy normal
                materialHelper.Vertices[nextVertexIndex].Normal = vertex0.Normal;

                MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matIndex][vertexIndex0].CalcCounter =
                    MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookupCount[matIndex];
                MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matIndex][vertexIndex0].VertexIndex =
                    (short)nextVertexIndex;

                materialHelper.VertexCount++;
            }
        }
        public void AddVertex(ref MyVoxelVertex vertex)//Vector3 pos, Vector3 normal, MyMwcVoxelMaterialsEnum material, float ambient)
        {
            var material = vertex.Material;
            byte alphaIndex;
            if (Material0 == material)
                alphaIndex = 0;
            else if (Material1 == material)
                alphaIndex = 1;
            else if (Material2 == material)
                alphaIndex = 2;
            else
                throw new System.InvalidOperationException("Should not be there, invalid material");

            Vertices[VertexCount].m_positionAndAmbient = vertex.m_positionAndAmbient;
            Vertices[VertexCount].Ambient = vertex.Ambient;

#if PACKED_VERTEX_FORMAT
            Vertices[VertexCount].m_normal = vertex.m_normal;
#else
            Vertices[VertexCount].Normal = vertex.Normal;
#endif

            Vertices[VertexCount].MaterialAlphaIndex = alphaIndex;
            VertexCount++;
        }
예제 #7
0
        public static MyVoxelVertex?ReadVoxelVertexEx(BinaryReader binaryReader, EndPoint senderEndPoint)
        {
            MyMwcVoxelMaterialsEnum?voxelMaterial = MyMwcMessageIn.ReadVoxelMaterialsEnumEx(binaryReader, senderEndPoint);
            Byte4? normal             = MyMwcMessageIn.ReadByte4Ex(binaryReader, senderEndPoint);
            UInt64?positionAndAmbient = MyMwcMessageIn.ReadUInt64Ex(binaryReader, senderEndPoint);

            if (voxelMaterial.HasValue && normal.HasValue && positionAndAmbient.HasValue)
            {
                MyVoxelVertex result = new MyVoxelVertex
                {
                    Material             = voxelMaterial.Value,
                    m_normal             = normal.Value,
                    m_positionAndAmbient = { packed_value = positionAndAmbient.Value }
                };
                return(result);
            }

            return(null);
        }
예제 #8
0
 public void GetUnpackedVertex(int index, out MyVoxelVertex vertex)
 {
     vertex          = (MyVoxelVertex)m_voxelVertices[index];
     vertex.Position = vertex.Position * PositionScale + PositionOffset;
 }
        //  This method adds triangles from one data cell into this render cell. Single-texture triangles are added using indices (so we use m_notCompressedIndex buffer).
        //  For this we need to find indices. We use lookup array for it.
        //  Now we support only 16-bit indices, so vertex buffer can't have more then short.MaxValue vertices.
        public void AddTriangles(List <MyVoxelCacheCellData> cacheDataArray)
        {
            //     MyPerformanceTimer.VoxelGpuBuffersBuild.Start();


            //MyMwcVoxelMaterialsEnum? CurrentSingleMaterial = null;
            //            bool triangleAdded = true;

            // while (triangleAdded)
            //  {
            //   triangleAdded = false;
            //CurrentSingleMaterial = null;


            foreach (var cacheData in cacheDataArray)
            {
                //  Increase lookup count, so we will think that all vertexes in helper arrays are new
                for (int i = 0; i < MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookupCount.Length; i++)
                {
                    MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookupCount[i]++;
                }

                for (int i = 0; i < cacheData.VoxelTrianglesCount; i++)
                {
                    MyVoxelTriangle triangle = cacheData.VoxelTriangles[i];
                    MyVoxelVertex   vertex0  = cacheData.VoxelVertices[triangle.VertexIndex0];
                    MyVoxelVertex   vertex1  = cacheData.VoxelVertices[triangle.VertexIndex1];
                    MyVoxelVertex   vertex2  = cacheData.VoxelVertices[triangle.VertexIndex2];

                    if ((vertex0.Material == vertex1.Material) && (vertex0.Material == vertex2.Material))
                    {
                        int matIndex = (int)vertex0.Material;

                        //  This is single-texture triangleVertexes, so we can choose material from any edge
                        MySingleMaterialHelper materialHelper = MyVoxelCacheCellRenderHelper.GetForMaterial(vertex0.Material);

                        //  Add vertex0 to vertex buffer
                        AddVertexToBuffer(materialHelper, ref vertex0, matIndex, triangle.VertexIndex0);

                        //  Add vertex1 to vertex buffer
                        AddVertexToBuffer(materialHelper, ref vertex1, matIndex, triangle.VertexIndex1);

                        //  Add vertex2 to vertex buffer
                        AddVertexToBuffer(materialHelper, ref vertex2, matIndex, triangle.VertexIndex2);

                        //triangleAdded = true;

                        //  Add indices
                        int nextTriangleIndex = materialHelper.IndexCount;
                        materialHelper.Indices[nextTriangleIndex + 0] = MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matIndex][triangle.VertexIndex0].VertexIndex;
                        materialHelper.Indices[nextTriangleIndex + 1] = MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matIndex][triangle.VertexIndex1].VertexIndex;
                        materialHelper.Indices[nextTriangleIndex + 2] = MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matIndex][triangle.VertexIndex2].VertexIndex;
                        materialHelper.IndexCount += 3;

                        if ((materialHelper.VertexCount >= MyVoxelCacheCellRenderHelper.MAX_VERTICES_COUNT_STOP) ||
                            (materialHelper.IndexCount >= MyVoxelCacheCellRenderHelper.MAX_INDICES_COUNT_STOP))
                        {
                            //  If this batch is almost full (or is full), we end it and start with new one
                            EndSingleMaterial(materialHelper);
                        }
                    }
                    else
                    {
                        int id = GetMultimaterialId(vertex0.Material, vertex1.Material, vertex2.Material);
                        // Assign current material
                        MyMultiMaterialHelper multiMaterialHelper = MyVoxelCacheCellRenderHelper.GetForMultimaterial(vertex0.Material, vertex1.Material, vertex2.Material);

                        //triangleAdded = true;

#if PACKED_VERTEX_FORMAT
                        // Copy packed normals
                        multiMaterialHelper.Vertices[multiMaterialHelper.VertexCount + 0].PackedNormal = vertex0.PackedNormal;
                        multiMaterialHelper.Vertices[multiMaterialHelper.VertexCount + 1].PackedNormal = vertex0.PackedNormal;
                        multiMaterialHelper.Vertices[multiMaterialHelper.VertexCount + 2].PackedNormal = vertex0.PackedNormal;
#endif

                        multiMaterialHelper.AddVertex(ref vertex0);
                        multiMaterialHelper.AddVertex(ref vertex1);
                        multiMaterialHelper.AddVertex(ref vertex2);

                        if (multiMaterialHelper.VertexCount >= MyVoxelCacheCellRenderHelper.MAX_VERTICES_COUNT_STOP)
                        {
                            EndMultiMaterial(multiMaterialHelper);
                        }
                    }
                }

                /*
                 * if (multiMaterialHelper != null)
                 * {
                 * int id = GetMultimaterialId(multiMaterialHelper.Material0, multiMaterialHelper.Material1, multiMaterialHelper.Material2);
                 * MyVoxelCacheCellRenderHelper.FinishedMultiMaterials[id] = true;
                 * EndMultimaterial(multiMaterialHelper);
                 * }
                 *
                 * if (singleMaterialHelper != null)
                 * {
                 * MyVoxelCacheCellRenderHelper.FinishedSingleMaterials[(int)singleMaterialHelper.Material] = true;
                 * EndSingleMaterial(singleMaterialHelper);
                 * }      */
            }


            //    }
            //MyPerformanceTimer.VoxelGpuBuffersBuild.End();
        }
예제 #10
0
        public static MyVoxelVertex? ReadVoxelVertexEx(BinaryReader binaryReader, EndPoint senderEndPoint)
        {
            MyMwcVoxelMaterialsEnum? voxelMaterial = MyMwcMessageIn.ReadVoxelMaterialsEnumEx(binaryReader, senderEndPoint);
            Byte4? normal = MyMwcMessageIn.ReadByte4Ex(binaryReader, senderEndPoint);
            UInt64? positionAndAmbient = MyMwcMessageIn.ReadUInt64Ex(binaryReader, senderEndPoint);

            if (voxelMaterial.HasValue && normal.HasValue && positionAndAmbient.HasValue)
            {
                MyVoxelVertex result = new MyVoxelVertex
                    {
                        Material = voxelMaterial.Value,
                        m_normal = normal.Value,
                        m_positionAndAmbient = { packed_value = positionAndAmbient.Value }
                    };
                return result;
            }

            return null;
        }
예제 #11
0
 public static void WriteVoxelVertex(MyVoxelVertex voxelVertex, BinaryWriter binaryWriter)
 {
     MyMwcMessageOut.WriteVoxelMaterialsEnum(voxelVertex.Material, binaryWriter);
     MyMwcMessageOut.WriteByte4(voxelVertex.m_normal, binaryWriter);
     binaryWriter.Write(voxelVertex.m_positionAndAmbient.packed_value);
 }
예제 #12
0
        public void Init(ref MyVoxelVertex[] vertices, ref int vertexCount, ref MyVoxelTriangle[] triangles, ref int triangleCount, out MyVoxelTriangle[] sortedTriangles)
        {
            for (int i = 0; i < NODE_COUNT; i++)
            {
                m_firstTriangleIndex[i] = 0;
                m_triangleCount[i] = 0;
            }
            for (int i = 0; i < 9; i++)
            {
                m_childEmpty[i] = 0;
            }

            // compute bounding box
            {
                BoundingBox bbox = BoundingBoxHelper.InitialBox;
                for (int i = 0; i < vertexCount; i++)
                    BoundingBoxHelper.AddPoint(vertices[i].Position, ref bbox);
                m_bbMin = bbox.Min;
                var scale = bbox.Max - bbox.Min;

                m_bbInvScale = Vector3.One;  // minimum bounding box size = 1 (in each dimension)
                if (scale.X > 1) m_bbInvScale.X = 1 / scale.X;
                if (scale.Y > 1) m_bbInvScale.Y = 1 / scale.Y;
                if (scale.Z > 1) m_bbInvScale.Z = 1 / scale.Z;
            }

            // compute triangle counts
            for (int i = 0; i < triangleCount; i++)
            {
                var t = triangles[i];
                BoundingBox bbox = BoundingBoxHelper.InitialBox;
                BoundingBoxHelper.AddTriangle(ref bbox, vertices[t.VertexIndex0].Position, vertices[t.VertexIndex1].Position, vertices[t.VertexIndex2].Position);
                short count = m_triangleCount[GetNode(ref bbox)]++;
            }

            // accumulate triangle counts
            m_firstTriangleIndex[0] = m_triangleCount[0];
            for (int i = 1; i < NODE_COUNT; i++)
            {
                m_firstTriangleIndex[i] = (short)(m_firstTriangleIndex[i - 1] + m_triangleCount[i]);
            }
            // m_firstTriangleIndex[i] now contains the first index AFTER where the node's triangles will be, e.g.:
            //   m_triangleCount:      2 0 4 3
            //   m_firstTriangleIndex: 2 2 6 9

            // bucketsort triangles into the output array according to the nodes they're in
            var newSortedTriangles = new MyVoxelTriangle[triangleCount];
            for (int i = 0; i < triangleCount; i++)
            {
                var t = triangles[i];
                BoundingBox bbox = BoundingBoxHelper.InitialBox;
                BoundingBoxHelper.AddTriangle(ref bbox, vertices[t.VertexIndex0].Position, vertices[t.VertexIndex1].Position, vertices[t.VertexIndex2].Position);
                newSortedTriangles[--m_firstTriangleIndex[GetNode(ref bbox)]] = t;
            }
            sortedTriangles = newSortedTriangles;  // "out sortedTriangles" may be the same as "triangles"

            // find empty children
            for (int i = NODE_COUNT - 1; i > 0; i--)
                if (m_triangleCount[i] == 0 && (i > 8 || m_childEmpty[i] == 0xFF)) // no triangles AND (no children OR all children empty)
                    m_childEmpty[i - 1 >> 3] |= (byte)(1 << (i - 1 & 7));
        }
예제 #13
0
 public static void WriteVoxelVertex(MyVoxelVertex voxelVertex, BinaryWriter binaryWriter)
 {
     MyMwcMessageOut.WriteVoxelMaterialsEnum(voxelVertex.Material, binaryWriter);
     MyMwcMessageOut.WriteByte4(voxelVertex.m_normal, binaryWriter);
     binaryWriter.Write(voxelVertex.m_positionAndAmbient.packed_value);
 }
 //  We want to skip all wrong triangles, those that have two vertex at almost the same location, etc.
 bool IsWrongTriangle(ref MyVoxelVertex edge0, ref MyVoxelVertex edge1, ref MyVoxelVertex edge2)
 {
     return(MyMeshPartSolver.IsWrongTriangle(edge0.Position, edge1.Position, edge2.Position));
 }
        private void CreateTriangles(ref Vector3I coord0, int cubeIndex, ref Vector3I tempVoxelCoord0)
        {
            MyVoxelVertex tmpVertex = new MyVoxelVertex();
            Vector3I      edge      = new Vector3I(coord0.X - 1, coord0.Y - 1, coord0.Z - 1);

            for (int i = 0; MyMarchingCubesConstants.TriangleTable[cubeIndex, i] != -1; i += 3)
            {
                //  Edge indexes inside the cube
                int edgeIndex0 = MyMarchingCubesConstants.TriangleTable[cubeIndex, i + 0];
                int edgeIndex1 = MyMarchingCubesConstants.TriangleTable[cubeIndex, i + 1];
                int edgeIndex2 = MyMarchingCubesConstants.TriangleTable[cubeIndex, i + 2];

                MyEdge edge0 = m_edges[edgeIndex0];
                MyEdge edge1 = m_edges[edgeIndex1];
                MyEdge edge2 = m_edges[edgeIndex2];


                //  Edge indexes inside the cell
                Vector4I edgeConversion0 = MyMarchingCubesConstants.EdgeConversion[edgeIndex0];
                Vector4I edgeConversion1 = MyMarchingCubesConstants.EdgeConversion[edgeIndex1];
                Vector4I edgeConversion2 = MyMarchingCubesConstants.EdgeConversion[edgeIndex2];

                MyEdgeVertex edgeVertex0 = m_edgeVertex[edge.X + edgeConversion0.X][edge.Y + edgeConversion0.Y][edge.Z + edgeConversion0.Z][edgeConversion0.W];
                MyEdgeVertex edgeVertex1 = m_edgeVertex[edge.X + edgeConversion1.X][edge.Y + edgeConversion1.Y][edge.Z + edgeConversion1.Z][edgeConversion1.W];
                MyEdgeVertex edgeVertex2 = m_edgeVertex[edge.X + edgeConversion2.X][edge.Y + edgeConversion2.Y][edge.Z + edgeConversion2.Z][edgeConversion2.W];


                MyVoxelVertex compressedVertex0 = new MyVoxelVertex();
                compressedVertex0.Position = edge0.Position;
                MyVoxelVertex compressedVertex1 = new MyVoxelVertex();
                compressedVertex1.Position = edge1.Position;
                MyVoxelVertex compressedVertex2 = new MyVoxelVertex();
                compressedVertex2.Position = edge2.Position;

                //  We want to skip all wrong triangles, those that have two vertex at almost the same location, etc.
                //  We do it simply, by calculating triangle normal and then checking if this normal has length large enough
                if (IsWrongTriangle(ref compressedVertex0, ref compressedVertex1, ref compressedVertex2) == true)
                {
                    continue;
                }

                //  Vertex at edge 0
                if (edgeVertex0.CalcCounter != m_edgeVertexCalcCounter)
                {
                    //  If vertex at edge0 wasn't calculated for this cell during this precalc, we need to add it

                    //  Short overflow check
                    System.Diagnostics.Debug.Assert(m_resultVerticesCounter <= short.MaxValue);

                    edgeVertex0.CalcCounter = m_edgeVertexCalcCounter;
                    edgeVertex0.VertexIndex = m_resultVerticesCounter;

                    tmpVertex.Position = (edge0.Position - m_originPosition) / m_positionScale;
                    tmpVertex.Normal   = edge0.Normal;
                    tmpVertex.Ambient  = edge0.Ambient;
                    tmpVertex.Material = edge0.Material;
                    m_resultVertices[m_resultVerticesCounter] = tmpVertex;

                    m_resultVerticesCounter++;
                }

                //  Vertex at edge 1
                if (edgeVertex1.CalcCounter != m_edgeVertexCalcCounter)
                {
                    //  If vertex at edge1 wasn't calculated for this cell during this precalc, we need to add it

                    //  Short overflow check
                    System.Diagnostics.Debug.Assert(m_resultVerticesCounter <= short.MaxValue);

                    edgeVertex1.CalcCounter = m_edgeVertexCalcCounter;
                    edgeVertex1.VertexIndex = m_resultVerticesCounter;

                    tmpVertex.Position = (edge1.Position - m_originPosition) / m_positionScale;
                    tmpVertex.Normal   = edge1.Normal;
                    tmpVertex.Ambient  = edge1.Ambient;
                    tmpVertex.Material = edge1.Material;
                    m_resultVertices[m_resultVerticesCounter] = tmpVertex;

                    m_resultVerticesCounter++;
                }

                //  Vertex at edge 2
                if (edgeVertex2.CalcCounter != m_edgeVertexCalcCounter)
                {
                    //  If vertex at edge2 wasn't calculated for this cell during this precalc, we need to add it

                    //  Short overflow check
                    System.Diagnostics.Debug.Assert(m_resultVerticesCounter <= short.MaxValue);

                    edgeVertex2.CalcCounter = m_edgeVertexCalcCounter;
                    edgeVertex2.VertexIndex = m_resultVerticesCounter;

                    tmpVertex.Position = (edge2.Position - m_originPosition) / m_positionScale;
                    tmpVertex.Normal   = edge2.Normal;
                    tmpVertex.Ambient  = edge2.Ambient;
                    tmpVertex.Material = edge2.Material;
                    m_resultVertices[m_resultVerticesCounter] = tmpVertex;

                    m_resultVerticesCounter++;
                }

                //  Triangle
                m_resultTriangles[m_resultTrianglesCounter].VertexIndex0 = edgeVertex0.VertexIndex;
                m_resultTriangles[m_resultTrianglesCounter].VertexIndex1 = edgeVertex1.VertexIndex;
                m_resultTriangles[m_resultTrianglesCounter].VertexIndex2 = edgeVertex2.VertexIndex;
                Debug.Assert(edgeVertex0.VertexIndex < m_resultVerticesCounter);
                Debug.Assert(edgeVertex1.VertexIndex < m_resultVerticesCounter);
                Debug.Assert(edgeVertex2.VertexIndex < m_resultVerticesCounter);

                m_resultTrianglesCounter++;
            }
        }
예제 #16
0
        //  We want to skip all wrong triangles, those that have two vertex at almost the same location, etc.
        //  We do it simply, by calculating triangle normal and then checking if this normal has length large enough
        bool IsWrongTriangle(ref MyVoxelVertex edge0, ref MyVoxelVertex edge1, ref MyVoxelVertex edge2)
        {
            //  Distance between two vertices is the fastest test
            Vector3 triangleEdgeVector1 = edge2.Position - edge0.Position;
            if (triangleEdgeVector1.LengthSquared() <= MyMwcMathConstants.EPSILON_SQUARED) return true;

            //  Distance between two vertexes is the fastest test
            Vector3 triangleEdgeVector2 = edge1.Position - edge0.Position;
            if (triangleEdgeVector2.LengthSquared() <= MyMwcMathConstants.EPSILON_SQUARED) return true;

            //  Distance between two vertexes is the fastest test
            Vector3 triangleEdgeVector3 = edge1.Position - edge2.Position;
            if (triangleEdgeVector3.LengthSquared() <= MyMwcMathConstants.EPSILON_SQUARED) return true;

            //  We don't need to do this advanced test, because it has zero improvement on voxel triangles (and testing takes time too)
            /*Vector3 norm;
            Vector3.Cross(ref triangleEdgeVector1, ref triangleEdgeVector2, out norm);
            if (norm.Length() < MyMwcMathConstants.EPSILON) return true;*/

            return false;
        }
예제 #17
0
        ////  Copy shadow values of surrounding cells
        //void CopyShadowValues()
        //{
        //    if (m_precalcType == MyLodTypeEnum.LOD0)
        //    {
        //        //  This is cell we are trying to precalculate            
        //        MyMwcVector3Int precalculatedCellCoord = m_voxelMap.GetDataCellCoordinate(ref m_voxelStart);

        //        for (int x = 0; x < SHADOW_CELLS; x++)
        //        {
        //            for (int y = 0; y < SHADOW_CELLS; y++)
        //            {
        //                for (int z = 0; z < SHADOW_CELLS; z++)
        //                {
        //                    MyMwcVector3Int tempCellCoord = new MyMwcVector3Int(precalculatedCellCoord.X + x - 1, precalculatedCellCoord.Y + y - 1, precalculatedCellCoord.Z + z - 1);

        //                    //  This is coordinate of cell's middle and it may contain values that are outside voxel map. It is OK, because we use it for bilinear/average calculations.
        //                    m_shadows[x][y][z].CoordOfDataCellCenter = m_voxelMap.GetVoxelCoordinatesOfCenterOfDataCell(ref tempCellCoord);

        //                    if (m_voxelMap.IsDataCellInVoxelMap(ref tempCellCoord) == false)
        //                    {
        //                        //  Data cell isn't in this voxel map, so it can't cast shadow map
        //                        m_shadows[x][y][z].ShadowValue = 1.0f;
        //                    }
        //                    else
        //                    {
        //                        m_shadows[x][y][z].ShadowValue = (float)m_voxelMap.GetDataCellShadow(ref tempCellCoord) / 255.0f;
        //                    }
        //                }
        //            }
        //        }
        //    }
        //}

        //  Precalculate voxel cell into cache (makes triangles and vertex buffer from voxels)
        public void Precalc(MyVoxelPrecalcTaskItem task)
        {
            m_precalcType = task.Type;

            m_resultVerticesCounter = 0;
            m_resultTrianglesCounter = 0;
            m_edgeVertexCalcCounter++;
            m_voxelMap = task.VoxelMap;
            m_voxelStart = task.VoxelStart;

            try
            {
                //m_voxelMap.LockAcquireWriterLock(Timeout.Infinite);

                CalcPolygCubeSize();

                //CopyShadowValues();

                //  Copy voxels into temp array
                bool totallyEmptyOrTotallyFull = CopyVoxelContents();

                if (totallyEmptyOrTotallyFull == false)
                {
                    //  Size of voxel or cell (in meters) and size of voxel map / voxel cells
                    float size;
                    if (m_precalcType == MyLodTypeEnum.LOD0)
                    {
                        size = MyVoxelConstants.VOXEL_SIZE_IN_METRES;
                        m_sizeMinusOne = m_voxelMap.SizeMinusOne;
                    }
                    else if (m_precalcType == MyLodTypeEnum.LOD1)
                    {
                        size = MyVoxelConstants.VOXEL_DATA_CELL_SIZE_IN_METRES;
                        m_sizeMinusOne = m_voxelMap.DataCellsCountMinusOne;
                    }
                    else
                    {
                        throw new MyMwcExceptionApplicationShouldNotGetHere();
                    }

                    //  Origin position for voxels (in meters)
                    Vector3 originPosition;
                    if (m_precalcType == MyLodTypeEnum.LOD0)
                    {
                        originPosition = m_voxelMap.GetVoxelCenterPositionRelative(ref m_voxelStart);
                    }
                    else if (m_precalcType == MyLodTypeEnum.LOD1)
                    {
                        originPosition = m_voxelMap.GetDataCellCenterPositionRelative(ref m_voxelStart);
                    }
                    else
                    {
                        throw new MyMwcExceptionApplicationShouldNotGetHere();
                    }

                    MyMwcVector3Int coord0;
                    for (coord0.X = 1; coord0.X <= (m_polygCubesX - 1); coord0.X++)
                    {
                        for (coord0.Y = 1; coord0.Y <= (m_polygCubesY - 1); coord0.Y++)
                        {
                            for (coord0.Z = 1; coord0.Z <= (m_polygCubesZ - 1); coord0.Z++)
                            {
                                //  We can get this voxel content right from cache (not using GetVoxelContent method), because after CopyVoxelContents these array must be filled. But only content, not material, normal, etc.
                                MyTemporaryVoxel tempVoxel0 = m_temporaryVoxels[coord0.X][coord0.Y][coord0.Z];
                                MyTemporaryVoxel tempVoxel1 = m_temporaryVoxels[coord0.X + 1][coord0.Y][coord0.Z];
                                MyTemporaryVoxel tempVoxel2 = m_temporaryVoxels[coord0.X + 1][coord0.Y][coord0.Z + 1];
                                MyTemporaryVoxel tempVoxel3 = m_temporaryVoxels[coord0.X][coord0.Y][coord0.Z + 1];
                                MyTemporaryVoxel tempVoxel4 = m_temporaryVoxels[coord0.X][coord0.Y + 1][coord0.Z];
                                MyTemporaryVoxel tempVoxel5 = m_temporaryVoxels[coord0.X + 1][coord0.Y + 1][coord0.Z];
                                MyTemporaryVoxel tempVoxel6 = m_temporaryVoxels[coord0.X + 1][coord0.Y + 1][coord0.Z + 1];
                                MyTemporaryVoxel tempVoxel7 = m_temporaryVoxels[coord0.X][coord0.Y + 1][coord0.Z + 1];

                                System.Diagnostics.Debug.Assert(tempVoxel0.Content_CalcCounter == m_temporaryVoxelsCounter);
                                System.Diagnostics.Debug.Assert(tempVoxel1.Content_CalcCounter == m_temporaryVoxelsCounter);
                                System.Diagnostics.Debug.Assert(tempVoxel2.Content_CalcCounter == m_temporaryVoxelsCounter);
                                System.Diagnostics.Debug.Assert(tempVoxel3.Content_CalcCounter == m_temporaryVoxelsCounter);
                                System.Diagnostics.Debug.Assert(tempVoxel4.Content_CalcCounter == m_temporaryVoxelsCounter);
                                System.Diagnostics.Debug.Assert(tempVoxel5.Content_CalcCounter == m_temporaryVoxelsCounter);
                                System.Diagnostics.Debug.Assert(tempVoxel6.Content_CalcCounter == m_temporaryVoxelsCounter);
                                System.Diagnostics.Debug.Assert(tempVoxel7.Content_CalcCounter == m_temporaryVoxelsCounter);

                                //  We can get this voxel content right from cache (not using GetVoxelContent method), because after CopyVoxelContents these array must be filled. But only content, not material, normal, etc.
                                int cubeIndex = 0;
                                if (tempVoxel0.Content < MyVoxelConstants.VOXEL_ISO_LEVEL) cubeIndex |= 1;
                                if (tempVoxel1.Content < MyVoxelConstants.VOXEL_ISO_LEVEL) cubeIndex |= 2;
                                if (tempVoxel2.Content < MyVoxelConstants.VOXEL_ISO_LEVEL) cubeIndex |= 4;
                                if (tempVoxel3.Content < MyVoxelConstants.VOXEL_ISO_LEVEL) cubeIndex |= 8;
                                if (tempVoxel4.Content < MyVoxelConstants.VOXEL_ISO_LEVEL) cubeIndex |= 16;
                                if (tempVoxel5.Content < MyVoxelConstants.VOXEL_ISO_LEVEL) cubeIndex |= 32;
                                if (tempVoxel6.Content < MyVoxelConstants.VOXEL_ISO_LEVEL) cubeIndex |= 64;
                                if (tempVoxel7.Content < MyVoxelConstants.VOXEL_ISO_LEVEL) cubeIndex |= 128;

                                //  Cube is entirely in/out of the surface
                                if (MyVoxelPrecalcConstants.EdgeTable[cubeIndex] == 0)
                                {
                                    continue;
                                }

                                MyMwcVector3Int coord1 = new MyMwcVector3Int(coord0.X + 1, coord0.Y, coord0.Z);
                                MyMwcVector3Int coord2 = new MyMwcVector3Int(coord0.X + 1, coord0.Y, coord0.Z + 1);
                                MyMwcVector3Int coord3 = new MyMwcVector3Int(coord0.X, coord0.Y, coord0.Z + 1);
                                MyMwcVector3Int coord4 = new MyMwcVector3Int(coord0.X, coord0.Y + 1, coord0.Z);
                                MyMwcVector3Int coord5 = new MyMwcVector3Int(coord0.X + 1, coord0.Y + 1, coord0.Z);
                                MyMwcVector3Int coord6 = new MyMwcVector3Int(coord0.X + 1, coord0.Y + 1, coord0.Z + 1);
                                MyMwcVector3Int coord7 = new MyMwcVector3Int(coord0.X, coord0.Y + 1, coord0.Z + 1);

                                MyMwcVector3Int tempVoxelCoord0 = new MyMwcVector3Int(m_voxelStart.X + coord0.X - 1, m_voxelStart.Y + coord0.Y - 1, m_voxelStart.Z + coord0.Z - 1);
                                MyMwcVector3Int tempVoxelCoord1 = new MyMwcVector3Int(m_voxelStart.X + coord1.X - 1, m_voxelStart.Y + coord1.Y - 1, m_voxelStart.Z + coord1.Z - 1);
                                MyMwcVector3Int tempVoxelCoord2 = new MyMwcVector3Int(m_voxelStart.X + coord2.X - 1, m_voxelStart.Y + coord2.Y - 1, m_voxelStart.Z + coord2.Z - 1);
                                MyMwcVector3Int tempVoxelCoord3 = new MyMwcVector3Int(m_voxelStart.X + coord3.X - 1, m_voxelStart.Y + coord3.Y - 1, m_voxelStart.Z + coord3.Z - 1);
                                MyMwcVector3Int tempVoxelCoord4 = new MyMwcVector3Int(m_voxelStart.X + coord4.X - 1, m_voxelStart.Y + coord4.Y - 1, m_voxelStart.Z + coord4.Z - 1);
                                MyMwcVector3Int tempVoxelCoord5 = new MyMwcVector3Int(m_voxelStart.X + coord5.X - 1, m_voxelStart.Y + coord5.Y - 1, m_voxelStart.Z + coord5.Z - 1);
                                MyMwcVector3Int tempVoxelCoord6 = new MyMwcVector3Int(m_voxelStart.X + coord6.X - 1, m_voxelStart.Y + coord6.Y - 1, m_voxelStart.Z + coord6.Z - 1);
                                MyMwcVector3Int tempVoxelCoord7 = new MyMwcVector3Int(m_voxelStart.X + coord7.X - 1, m_voxelStart.Y + coord7.Y - 1, m_voxelStart.Z + coord7.Z - 1);

                                tempVoxel0.Position.X = originPosition.X + (coord0.X - 1) * size;
                                tempVoxel0.Position.Y = originPosition.Y + (coord0.Y - 1) * size;
                                tempVoxel0.Position.Z = originPosition.Z + (coord0.Z - 1) * size;

                                tempVoxel1.Position.X = tempVoxel0.Position.X + size;
                                tempVoxel1.Position.Y = tempVoxel0.Position.Y;
                                tempVoxel1.Position.Z = tempVoxel0.Position.Z;

                                tempVoxel2.Position.X = tempVoxel0.Position.X + size;
                                tempVoxel2.Position.Y = tempVoxel0.Position.Y;
                                tempVoxel2.Position.Z = tempVoxel0.Position.Z + size;

                                tempVoxel3.Position.X = tempVoxel0.Position.X;
                                tempVoxel3.Position.Y = tempVoxel0.Position.Y;
                                tempVoxel3.Position.Z = tempVoxel0.Position.Z + size;

                                tempVoxel4.Position.X = tempVoxel0.Position.X;
                                tempVoxel4.Position.Y = tempVoxel0.Position.Y + size;
                                tempVoxel4.Position.Z = tempVoxel0.Position.Z;

                                tempVoxel5.Position.X = tempVoxel0.Position.X + size;
                                tempVoxel5.Position.Y = tempVoxel0.Position.Y + size;
                                tempVoxel5.Position.Z = tempVoxel0.Position.Z;

                                tempVoxel6.Position.X = tempVoxel0.Position.X + size;
                                tempVoxel6.Position.Y = tempVoxel0.Position.Y + size;
                                tempVoxel6.Position.Z = tempVoxel0.Position.Z + size;

                                tempVoxel7.Position.X = tempVoxel0.Position.X;
                                tempVoxel7.Position.Y = tempVoxel0.Position.Y + size;
                                tempVoxel7.Position.Z = tempVoxel0.Position.Z + size;

                                //  Normals at grid corners (calculated from gradient)
                                GetVoxelNormal(tempVoxel0, ref coord0, ref tempVoxelCoord0, tempVoxel0);
                                GetVoxelNormal(tempVoxel1, ref coord1, ref tempVoxelCoord1, tempVoxel0);
                                GetVoxelNormal(tempVoxel2, ref coord2, ref tempVoxelCoord2, tempVoxel0);
                                GetVoxelNormal(tempVoxel3, ref coord3, ref tempVoxelCoord3, tempVoxel0);
                                GetVoxelNormal(tempVoxel4, ref coord4, ref tempVoxelCoord4, tempVoxel0);
                                GetVoxelNormal(tempVoxel5, ref coord5, ref tempVoxelCoord5, tempVoxel0);
                                GetVoxelNormal(tempVoxel6, ref coord6, ref tempVoxelCoord6, tempVoxel0);
                                GetVoxelNormal(tempVoxel7, ref coord7, ref tempVoxelCoord7, tempVoxel0);

                                //  Ambient occlusion colors at grid corners
                                //  IMPORTANT: At this point normals must be calculated because GetVoxelAmbientAndSun() will be retrieving them from temp table and not checking if there is actual value
                                GetVoxelAmbient(tempVoxel0, ref coord0, ref tempVoxelCoord0);
                                GetVoxelAmbient(tempVoxel1, ref coord1, ref tempVoxelCoord1);
                                GetVoxelAmbient(tempVoxel2, ref coord2, ref tempVoxelCoord2);
                                GetVoxelAmbient(tempVoxel3, ref coord3, ref tempVoxelCoord3);
                                GetVoxelAmbient(tempVoxel4, ref coord4, ref tempVoxelCoord4);
                                GetVoxelAmbient(tempVoxel5, ref coord5, ref tempVoxelCoord5);
                                GetVoxelAmbient(tempVoxel6, ref coord6, ref tempVoxelCoord6);
                                GetVoxelAmbient(tempVoxel7, ref coord7, ref tempVoxelCoord7);

                                //  Materials at grid corners
                                GetVoxelMaterial(tempVoxel0, ref tempVoxelCoord0);
                                GetVoxelMaterial(tempVoxel1, ref tempVoxelCoord1);
                                GetVoxelMaterial(tempVoxel2, ref tempVoxelCoord2);
                                GetVoxelMaterial(tempVoxel3, ref tempVoxelCoord3);
                                GetVoxelMaterial(tempVoxel4, ref tempVoxelCoord4);
                                GetVoxelMaterial(tempVoxel5, ref tempVoxelCoord5);
                                GetVoxelMaterial(tempVoxel6, ref tempVoxelCoord6);
                                GetVoxelMaterial(tempVoxel7, ref tempVoxelCoord7);

                                //  Find the vertices where the surface intersects the cube
                                if ((MyVoxelPrecalcConstants.EdgeTable[cubeIndex] & 1) == 1)
                                {
                                    GetVertexInterpolation(tempVoxel0, tempVoxel1, 0);
                                }
                                if ((MyVoxelPrecalcConstants.EdgeTable[cubeIndex] & 2) == 2)
                                {
                                    GetVertexInterpolation(tempVoxel1, tempVoxel2, 1);
                                }
                                if ((MyVoxelPrecalcConstants.EdgeTable[cubeIndex] & 4) == 4)
                                {
                                    GetVertexInterpolation(tempVoxel2, tempVoxel3, 2);
                                }
                                if ((MyVoxelPrecalcConstants.EdgeTable[cubeIndex] & 8) == 8)
                                {
                                    GetVertexInterpolation(tempVoxel3, tempVoxel0, 3);
                                }
                                if ((MyVoxelPrecalcConstants.EdgeTable[cubeIndex] & 16) == 16)
                                {
                                    GetVertexInterpolation(tempVoxel4, tempVoxel5, 4);
                                }
                                if ((MyVoxelPrecalcConstants.EdgeTable[cubeIndex] & 32) == 32)
                                {
                                    GetVertexInterpolation(tempVoxel5, tempVoxel6, 5);
                                }
                                if ((MyVoxelPrecalcConstants.EdgeTable[cubeIndex] & 64) == 64)
                                {
                                    GetVertexInterpolation(tempVoxel6, tempVoxel7, 6);
                                }
                                if ((MyVoxelPrecalcConstants.EdgeTable[cubeIndex] & 128) == 128)
                                {
                                    GetVertexInterpolation(tempVoxel7, tempVoxel4, 7);
                                }
                                if ((MyVoxelPrecalcConstants.EdgeTable[cubeIndex] & 256) == 256)
                                {
                                    GetVertexInterpolation(tempVoxel0, tempVoxel4, 8);
                                }
                                if ((MyVoxelPrecalcConstants.EdgeTable[cubeIndex] & 512) == 512)
                                {
                                    GetVertexInterpolation(tempVoxel1, tempVoxel5, 9);
                                }
                                if ((MyVoxelPrecalcConstants.EdgeTable[cubeIndex] & 1024) == 1024)
                                {
                                    GetVertexInterpolation(tempVoxel2, tempVoxel6, 10);
                                }
                                if ((MyVoxelPrecalcConstants.EdgeTable[cubeIndex] & 2048) == 2048)
                                {
                                    GetVertexInterpolation(tempVoxel3, tempVoxel7, 11);
                                }

                                //  Create the triangles
                                MyMwcVector3Int edge = new MyMwcVector3Int(coord0.X - 1, coord0.Y - 1, coord0.Z - 1);
                                for (int i = 0; MyVoxelPrecalcConstants.TriangleTable[cubeIndex, i] != -1; i += 3)
                                {
                                    //  Edge indexes inside the cube
                                    int edgeIndex0 = MyVoxelPrecalcConstants.TriangleTable[cubeIndex, i + 0];
                                    int edgeIndex1 = MyVoxelPrecalcConstants.TriangleTable[cubeIndex, i + 1];
                                    int edgeIndex2 = MyVoxelPrecalcConstants.TriangleTable[cubeIndex, i + 2];

                                    MyEdge edge0 = m_edges[edgeIndex0];
                                    MyEdge edge1 = m_edges[edgeIndex1];
                                    MyEdge edge2 = m_edges[edgeIndex2];


                                    //  Edge indexes inside the cell
                                    MyMwcVector4Int edgeConversion0 = MyVoxelPrecalcConstants.EdgeConversion[edgeIndex0];
                                    MyMwcVector4Int edgeConversion1 = MyVoxelPrecalcConstants.EdgeConversion[edgeIndex1];
                                    MyMwcVector4Int edgeConversion2 = MyVoxelPrecalcConstants.EdgeConversion[edgeIndex2];

                                    MyEdgeVertex edgeVertex0 = m_edgeVertex[edge.X + edgeConversion0.X][edge.Y + edgeConversion0.Y][edge.Z + edgeConversion0.Z][edgeConversion0.W];
                                    MyEdgeVertex edgeVertex1 = m_edgeVertex[edge.X + edgeConversion1.X][edge.Y + edgeConversion1.Y][edge.Z + edgeConversion1.Z][edgeConversion1.W];
                                    MyEdgeVertex edgeVertex2 = m_edgeVertex[edge.X + edgeConversion2.X][edge.Y + edgeConversion2.Y][edge.Z + edgeConversion2.Z][edgeConversion2.W];


                                    MyVoxelVertex compressedVertex0 = new MyVoxelVertex();
                                    compressedVertex0.Position = edge0.Position;
                                    MyVoxelVertex compressedVertex1 = new MyVoxelVertex();
                                    compressedVertex1.Position = edge1.Position;
                                    MyVoxelVertex compressedVertex2 = new MyVoxelVertex();
                                    compressedVertex2.Position = edge2.Position;

                                    //  We want to skip all wrong triangles, those that have two vertex at almost the same location, etc.
                                    //  We do it simply, by calculating triangle normal and then checking if this normal has length large enough
                                    if (IsWrongTriangle(ref compressedVertex0, ref compressedVertex1, ref compressedVertex2) == true)
                                    {
                                        continue;
                                    }

                                    //  Vertex at edge 0     
                                    if (edgeVertex0.CalcCounter != m_edgeVertexCalcCounter)
                                    {
                                        //  If vertex at edge0 wasn't calculated for this cell during this precalc, we need to add it

                                        //  Short overflow check
                                        System.Diagnostics.Debug.Assert(m_resultVerticesCounter <= short.MaxValue);

                                        edgeVertex0.CalcCounter = m_edgeVertexCalcCounter;
                                        edgeVertex0.VertexIndex = m_resultVerticesCounter;

                                        m_resultVertices[m_resultVerticesCounter].Position = edge0.Position;
                                        m_resultVertices[m_resultVerticesCounter].Normal = edge0.Normal;
                                        m_resultVertices[m_resultVerticesCounter].Ambient = edge0.Ambient;
                                        m_resultVertices[m_resultVerticesCounter].Material = edge0.Material;
                                        //m_resultVertices[m_resultVerticesCounter].OnRenderCellEdge = false;

                                        if (IsCoordOnRenderCellEdge(tempVoxelCoord0))
                                        {
                                            //m_resultVertices[m_resultVerticesCounter].OnRenderCellEdge = true;
                                        }

                                        m_resultVerticesCounter++;
                                    }

                                    //  Vertex at edge 1
                                    if (edgeVertex1.CalcCounter != m_edgeVertexCalcCounter)
                                    {
                                        //  If vertex at edge1 wasn't calculated for this cell during this precalc, we need to add it

                                        //  Short overflow check
                                        System.Diagnostics.Debug.Assert(m_resultVerticesCounter <= short.MaxValue);

                                        edgeVertex1.CalcCounter = m_edgeVertexCalcCounter;
                                        edgeVertex1.VertexIndex = m_resultVerticesCounter;

                                        m_resultVertices[m_resultVerticesCounter].Position = edge1.Position;
                                        m_resultVertices[m_resultVerticesCounter].Normal = edge1.Normal;
                                        m_resultVertices[m_resultVerticesCounter].Ambient = edge1.Ambient;
                                        m_resultVertices[m_resultVerticesCounter].Material = edge1.Material;
                                        //m_resultVertices[m_resultVerticesCounter].OnRenderCellEdge = false;

                                        if (IsCoordOnRenderCellEdge(tempVoxelCoord0))
                                        {
                                            //m_resultVertices[m_resultVerticesCounter].OnRenderCellEdge = true;
                                        }

                                        m_resultVerticesCounter++;
                                    }

                                    //  Vertex at edge 2
                                    if (edgeVertex2.CalcCounter != m_edgeVertexCalcCounter)
                                    {
                                        //  If vertex at edge2 wasn't calculated for this cell during this precalc, we need to add it

                                        //  Short overflow check
                                        System.Diagnostics.Debug.Assert(m_resultVerticesCounter <= short.MaxValue);

                                        edgeVertex2.CalcCounter = m_edgeVertexCalcCounter;
                                        edgeVertex2.VertexIndex = m_resultVerticesCounter;

                                        m_resultVertices[m_resultVerticesCounter].Position = edge2.Position;
                                        m_resultVertices[m_resultVerticesCounter].Normal = edge2.Normal;
                                        m_resultVertices[m_resultVerticesCounter].Ambient = edge2.Ambient;
                                        m_resultVertices[m_resultVerticesCounter].Material = edge2.Material;
                                        //m_resultVertices[m_resultVerticesCounter].OnRenderCellEdge = false;

                                        if (IsCoordOnRenderCellEdge(tempVoxelCoord0))
                                        {
                                          //  m_resultVertices[m_resultVerticesCounter].OnRenderCellEdge = true;
                                        }

                                        m_resultVerticesCounter++;
                                    }

                                    //  Triangle
                                    m_resultTriangles[m_resultTrianglesCounter].VertexIndex0 = edgeVertex0.VertexIndex;
                                    m_resultTriangles[m_resultTrianglesCounter].VertexIndex1 = edgeVertex1.VertexIndex;
                                    m_resultTriangles[m_resultTrianglesCounter].VertexIndex2 = edgeVertex2.VertexIndex;
                                    Debug.Assert(edgeVertex0.VertexIndex < m_resultVerticesCounter);
                                    Debug.Assert(edgeVertex1.VertexIndex < m_resultVerticesCounter);
                                    Debug.Assert(edgeVertex2.VertexIndex < m_resultVerticesCounter);

                                    //  Each voxel triangleVertexes has unique ID in whole game (but only on client side)
                                    //m_resultTriangles[m_resultTrianglesCounter].TriangleId = m_triangleIdCounter++;

                                    m_resultTrianglesCounter++;
                                }
                            }
                        }
                    }
                }

                // Cache the vertices and triangles and precalculate the octree
                task.Cache.PrepareCache(m_resultVertices, m_resultVerticesCounter, m_resultTriangles, m_resultTrianglesCounter);
            }
            finally
            {
                //m_voxelMap.Lock.ReleaseWriterLock();
            }
        }