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++;
        }
            public void PrepareCache(
                MyVoxelVertex[] vertices, int vertexCount,
                MyVoxelTriangle[] triangles, int triangleCount,
                float positionScale, Vector3 positionOffset,
                bool createPhysicsShape)
            {
                using (m_syncRoot.AcquireExclusiveUsing())
                {
                    if (vertexCount == 0)
                    {
                        VoxelVerticesCount = 0;
                        VoxelTrianglesCount = 0;
                        m_octree = null;
                        m_voxelVertices = null;
                        PositionOffset = new Vector3(0f);
                        PositionScale = 0f;
                        return;
                    }
                    Debug.Assert(vertexCount <= Int16.MaxValue);

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

                    Profiler.Begin("build octree");
                    if (m_octree == null)
                        m_octree = new MyOctree();
                    m_octree.Init(ref m_voxelVertices, ref vertexCount, ref triangles, ref triangleCount, out VoxelTriangles);
                    Profiler.End();

                    // set size only after the arrays are fully allocated
                    VoxelVerticesCount = vertexCount;
                    VoxelTrianglesCount = triangleCount;
                    PositionOffset = positionOffset;
                    PositionScale = positionScale;

                    if (createPhysicsShape)
                        CreateMeshShape();
                }
            }
        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 GetUnpackedVertex(int index, out MyVoxelVertex vertex)
 {
     vertex = (MyVoxelVertex)m_voxelVertices[index];
     vertex.Position = vertex.Position * PositionScale + PositionOffset;
 }
 //  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++;
            }
        }