Пример #1
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;
            }
        }
Пример #2
0
        private void GetCellLineIntersectionOctree(ref MyIntersectionResultLineTriangle?result, ref Line modelSpaceLine, ref float?minDistanceUntilNow, CellData cachedDataCell, IntersectionFlags flags)
        {
            m_overlapElementCache.Clear();
            if (cachedDataCell.Octree != null)
            {
                Vector3 packedStart;
                cachedDataCell.GetPackedPosition(ref modelSpaceLine.From, out packedStart);
                var ray = new Ray(packedStart, modelSpaceLine.Direction);
                cachedDataCell.Octree.GetIntersectionWithLine(ref ray, m_overlapElementCache);
            }

            for (int j = 0; j < m_overlapElementCache.Count; j++)
            {
                var i = m_overlapElementCache[j];

                if (cachedDataCell.VoxelTriangles == null) //probably not calculated yet
                {
                    continue;
                }

                // this should never happen
                if (i >= cachedDataCell.VoxelTriangles.Length)
                {
                    Debug.Assert(i < cachedDataCell.VoxelTriangles.Length);
                    continue;
                }

                MyVoxelTriangle voxelTriangle = cachedDataCell.VoxelTriangles[i];

                MyTriangle_Vertexes triangleVertices;
                cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex0, out triangleVertices.Vertex0);
                cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex1, out triangleVertices.Vertex1);
                cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex2, out triangleVertices.Vertex2);

                Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangleVertices);

                //We dont want backside intersections
                if (((int)(flags & IntersectionFlags.FLIPPED_TRIANGLES) == 0) &&
                    Vector3.Dot(modelSpaceLine.Direction, calculatedTriangleNormal) > 0)
                {
                    continue;
                }

                // AABB intersection test removed, AABB is tested inside BVH
                float?distance = MyUtils.GetLineTriangleIntersection(ref modelSpaceLine, ref triangleVertices);

                //  If intersection occured and if distance to intersection is closer to origin than any previous intersection
                if ((distance != null) && ((result == null) || (distance.Value < result.Value.Distance)))
                {
                    minDistanceUntilNow = distance.Value;
                    result = new MyIntersectionResultLineTriangle(ref triangleVertices, ref calculatedTriangleNormal, distance.Value);
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Returns true if triangle has very close to zero surface area.
        /// </summary>
        private bool HasZeroSurface(MyVoxelTriangle triangle)
        {
            var vertex0 = m_vertices[triangle.VertexIndex0];
            var vertex1 = m_vertices[triangle.VertexIndex1];
            var vertex2 = m_vertices[triangle.VertexIndex2];

            var vector1 = vertex1.Position - vertex0.Position;

            vector1.Normalize();
            var vector2 = vertex2.Position - vertex0.Position;

            vector2.Normalize();
            var dot = Vector3.Dot(vector1, vector2);

            if (Math.Abs(dot) > 0.9999)
            {
                return(true);
            }

            return(false);
        }
        //  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();
        }
Пример #5
0
        public static void StitchDataCells(List<MyVoxelCacheCellData> dataCells)
        {
            Vertices.Clear();
            Triangles.Clear();
            m_verticesMap.Clear();

            //int vertexCount = 0;
            //foreach (MyVoxelCacheCellData dataCell in dataCells)
            //{
            //    m_remapHelper.Clear();

            //    for (int vertexIndex = 0; vertexIndex < dataCell.VoxelVerticesCount; vertexIndex++)
            //    {
            //        var vertex = dataCell.VoxelVertexes[vertexIndex];
            //        Vertices.Add(vertex);
            //    }

            //    for (int triangleIndex = 0; triangleIndex < dataCell.VoxelTrianglesCount; triangleIndex++)
            //    {
            //        var triangle = dataCell.VoxelTriangles[triangleIndex];
            //        MyVoxelTriangle32 newTriangle = new MyVoxelTriangle32();
            //        for (int i = 0; i < 3; i++)
            //        {
            //            var index = triangle[i];
            //            newTriangle[i] = index + vertexCount;
            //        }
            //        Triangles.Add(newTriangle);
            //    }

            //    vertexCount = Vertices.Count;
            //}

            for (int dataCellIndex = 0; dataCellIndex < dataCells.Count; dataCellIndex++)
            {
                m_remapHelper.Clear();
                var dataCell = dataCells[dataCellIndex];

                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Stitch Data Cells - first cycle");

                for (int vertexIndex = 0; vertexIndex < dataCell.VoxelVerticesCount; vertexIndex++)
                {
                    var vertex = dataCell.VoxelVertices[vertexIndex];
                    short index;
                    if (m_verticesMap.TryGetValue(vertex, out index))
                    {
                        m_remapHelper.Add(index);
                    }
                    else
                    {
                        Debug.Assert(Vertices.Count < short.MaxValue);
                        m_verticesMap.Add(vertex, (short) Vertices.Count);
                        m_remapHelper.Add((short) Vertices.Count);
                        Vertices.Add(vertex);
                    }
                }

                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartNextBlock("Stitch Data Cells - second cycle");
                for (int triangleIndex = 0; triangleIndex < dataCell.VoxelTrianglesCount; triangleIndex++)
                {
                    var triangle = dataCell.VoxelTriangles[triangleIndex];
                    MyVoxelTriangle newTriangle = new MyVoxelTriangle();
                    for (int i = 0; i < 3; i++)
                    {
                        var index = triangle[i];
                        newTriangle[i] = m_remapHelper[index];
                    }
                    Triangles.Add(newTriangle);
                }

                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
            }
        }
Пример #6
0
        /// <summary>
        /// Returns true if triangle has very close to zero surface area.
        /// </summary>
        private bool HasZeroSurface(MyVoxelTriangle triangle)
        {
            var vertex0 = m_vertices[triangle.VertexIndex0];
            var vertex1 = m_vertices[triangle.VertexIndex1];
            var vertex2 = m_vertices[triangle.VertexIndex2];

            var vector1 = vertex1.Position - vertex0.Position;
            vector1.Normalize();
            var vector2 = vertex2.Position - vertex0.Position;
            vector2.Normalize();
            var dot = Vector3.Dot(vector1, vector2);
            if (Math.Abs(dot) > 0.9999)
                return true;

            return false;
        }
Пример #7
0
 /// <summary>
 /// Returns true if the given triangle is defined by less than three distincs vertex indices.
 /// </summary>
 private bool IsDegenerated(MyVoxelTriangle triangle)
 {
     return triangle.VertexIndex0 == triangle.VertexIndex1 ||
            triangle.VertexIndex0 == triangle.VertexIndex2 ||
            triangle.VertexIndex1 == triangle.VertexIndex2;
 }
Пример #8
0
        public static void StitchDataCells(List <MyVoxelCacheCellData> dataCells)
        {
            Vertices.Clear();
            Triangles.Clear();
            m_verticesMap.Clear();

            //int vertexCount = 0;
            //foreach (MyVoxelCacheCellData dataCell in dataCells)
            //{
            //    m_remapHelper.Clear();

            //    for (int vertexIndex = 0; vertexIndex < dataCell.VoxelVerticesCount; vertexIndex++)
            //    {
            //        var vertex = dataCell.VoxelVertexes[vertexIndex];
            //        Vertices.Add(vertex);
            //    }

            //    for (int triangleIndex = 0; triangleIndex < dataCell.VoxelTrianglesCount; triangleIndex++)
            //    {
            //        var triangle = dataCell.VoxelTriangles[triangleIndex];
            //        MyVoxelTriangle32 newTriangle = new MyVoxelTriangle32();
            //        for (int i = 0; i < 3; i++)
            //        {
            //            var index = triangle[i];
            //            newTriangle[i] = index + vertexCount;
            //        }
            //        Triangles.Add(newTriangle);
            //    }

            //    vertexCount = Vertices.Count;
            //}

            for (int dataCellIndex = 0; dataCellIndex < dataCells.Count; dataCellIndex++)
            {
                m_remapHelper.Clear();
                var dataCell = dataCells[dataCellIndex];

                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("Stitch Data Cells - first cycle");

                for (int vertexIndex = 0; vertexIndex < dataCell.VoxelVerticesCount; vertexIndex++)
                {
                    var   vertex = dataCell.VoxelVertices[vertexIndex];
                    short index;
                    if (m_verticesMap.TryGetValue(vertex, out index))
                    {
                        m_remapHelper.Add(index);
                    }
                    else
                    {
                        Debug.Assert(Vertices.Count < short.MaxValue);
                        m_verticesMap.Add(vertex, (short)Vertices.Count);
                        m_remapHelper.Add((short)Vertices.Count);
                        Vertices.Add(vertex);
                    }
                }

                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartNextBlock("Stitch Data Cells - second cycle");
                for (int triangleIndex = 0; triangleIndex < dataCell.VoxelTrianglesCount; triangleIndex++)
                {
                    var             triangle    = dataCell.VoxelTriangles[triangleIndex];
                    MyVoxelTriangle newTriangle = new MyVoxelTriangle();
                    for (int i = 0; i < 3; i++)
                    {
                        var index = triangle[i];
                        newTriangle[i] = m_remapHelper[index];
                    }
                    Triangles.Add(newTriangle);
                }

                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
            }
        }
Пример #9
0
 public static void WriteVoxelTriangle(MyVoxelTriangle voxelTriangle, BinaryWriter binaryWriter)
 {
     binaryWriter.Write(voxelTriangle.VertexIndex0);
     binaryWriter.Write(voxelTriangle.VertexIndex1);
     binaryWriter.Write(voxelTriangle.VertexIndex2);
 }
Пример #10
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));
        }
        //  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 <MyVoxelGeometry.CellData> cacheDataArray)
        {
            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, vertex1, vertex2;
                    cacheData.GetUnpackedVertex(triangle.VertexIndex0, out vertex0);
                    cacheData.GetUnpackedVertex(triangle.VertexIndex1, out vertex1);
                    cacheData.GetUnpackedVertex(triangle.VertexIndex2, out vertex2);

                    vertex0.Position = (vertex0.Position - m_positionOffset) / m_positionScale;
                    vertex1.Position = (vertex1.Position - m_positionOffset) / m_positionScale;
                    vertex2.Position = (vertex2.Position - m_positionOffset) / m_positionScale;
                    Debug.Assert(vertex0.Position.IsInsideInclusive(ref Vector3.Zero, ref Vector3.One));
                    Debug.Assert(vertex1.Position.IsInsideInclusive(ref Vector3.Zero, ref Vector3.One));
                    Debug.Assert(vertex2.Position.IsInsideInclusive(ref Vector3.Zero, ref Vector3.One));

                    if ((vertex0.Material == vertex1.Material) && (vertex0.Material == vertex2.Material))
                    {
                        var matDef = MyDefinitionManager.Static.GetVoxelMaterialDefinition((byte)vertex0.Material);

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

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

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

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

                        MyVoxelCacheCellRenderHelper.CreateArrayIfNotExist(matDef.Index);

                        //  Add indices
                        int nextTriangleIndex = materialHelper.IndexCount;
                        materialHelper.Indices[nextTriangleIndex + 0] = MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matDef.Index][triangle.VertexIndex0].VertexIndex;
                        materialHelper.Indices[nextTriangleIndex + 1] = MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matDef.Index][triangle.VertexIndex1].VertexIndex;
                        materialHelper.Indices[nextTriangleIndex + 2] = MyVoxelCacheCellRenderHelper.SingleMaterialIndicesLookup[matDef.Index][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);

                        // Copy packed normals
                        multiMaterialHelper.Vertices[multiMaterialHelper.VertexCount + 0].Normal = vertex0.Normal;
                        multiMaterialHelper.Vertices[multiMaterialHelper.VertexCount + 1].Normal = vertex0.Normal;
                        multiMaterialHelper.Vertices[multiMaterialHelper.VertexCount + 2].Normal = vertex0.Normal;

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

                        if (multiMaterialHelper.VertexCount >= MyVoxelCacheCellRenderHelper.MAX_VERTICES_COUNT_STOP)
                        {
                            EndMultiMaterial(multiMaterialHelper);
                        }
                    }
                }
            }
        }
Пример #12
0
        internal bool Intersects(ref BoundingSphere sphere)
        {
            //  Get min and max cell coordinate where boundingBox can fit
            BoundingBox sphereBoundingBox = BoundingBox.CreateInvalid();

            sphereBoundingBox.Include(ref sphere);
            Vector3I cellCoordMin = GetCellCoordinateFromMeters(ref sphereBoundingBox.Min);
            Vector3I cellCoordMax = GetCellCoordinateFromMeters(ref sphereBoundingBox.Max);

            //  Fix min and max cell coordinates so they don't overlap the voxelmap
            FixDataCellCoord(ref cellCoordMin);
            FixDataCellCoord(ref cellCoordMax);

            Vector3I cellCoord;

            for (cellCoord.X = cellCoordMin.X; cellCoord.X <= cellCoordMax.X; cellCoord.X++)
            {
                for (cellCoord.Y = cellCoordMin.Y; cellCoord.Y <= cellCoordMax.Y; cellCoord.Y++)
                {
                    for (cellCoord.Z = cellCoordMin.Z; cellCoord.Z <= cellCoordMax.Z; cellCoord.Z++)
                    {
                        //  If no overlap between bounding box of data cell and the sphere
                        BoundingBox cellBoundingBox;
                        GetDataCellBoundingBox(ref cellCoord, out cellBoundingBox);
                        if (cellBoundingBox.Intersects(ref sphere) == false)
                        {
                            continue;
                        }

                        //  Get cell from cache. If not there, precalc it and store in the cache.
                        //  If null is returned, we know that cell doesn't contain any triangleVertexes so we don't need to do intersections.
                        CellData cachedDataCell = GetCell(MyLodTypeEnum.LOD0, ref cellCoord);

                        if (cachedDataCell == null)
                        {
                            continue;
                        }

                        for (int i = 0; i < cachedDataCell.VoxelTrianglesCount; i++)
                        {
                            MyVoxelTriangle voxelTriangle = cachedDataCell.VoxelTriangles[i];

                            MyTriangle_Vertexes triangle;
                            cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex0, out triangle.Vertex0);
                            cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex1, out triangle.Vertex1);
                            cachedDataCell.GetUnpackedPosition(voxelTriangle.VertexIndex2, out triangle.Vertex2);
                            triangle.Vertex0 += m_voxelMap.PositionLeftBottomCorner;
                            triangle.Vertex1 += m_voxelMap.PositionLeftBottomCorner;
                            triangle.Vertex2 += m_voxelMap.PositionLeftBottomCorner;

                            BoundingBox voxelTriangleBoundingBox = BoundingBox.CreateInvalid();
                            voxelTriangleBoundingBox.Include(ref triangle.Vertex0);
                            voxelTriangleBoundingBox.Include(ref triangle.Vertex1);
                            voxelTriangleBoundingBox.Include(ref triangle.Vertex2);

                            //  First test intersection of triangle's bounding box with line's bounding box. And only if they overlap or intersect, do further intersection tests.
                            if (voxelTriangleBoundingBox.Intersects(ref sphere))
                            {
                                MyPlane trianglePlane = new MyPlane(ref triangle);

                                if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null)
                                {
                                    //  If intersection found - we are finished. We don't need to look for more.
                                    Profiler.End();
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }

            return(false);
        }
Пример #13
0
 /// <summary>
 /// Returns true if the given triangle is defined by less than three distincs vertex indices.
 /// </summary>
 private bool IsDegenerated(MyVoxelTriangle triangle)
 {
     return(triangle.VertexIndex0 == triangle.VertexIndex1 ||
            triangle.VertexIndex0 == triangle.VertexIndex2 ||
            triangle.VertexIndex1 == triangle.VertexIndex2);
 }
Пример #14
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));
                }
            }
        }
Пример #15
0
 public static void WriteVoxelTriangle(MyVoxelTriangle voxelTriangle, BinaryWriter binaryWriter)
 {
     binaryWriter.Write(voxelTriangle.VertexIndex0);
     binaryWriter.Write(voxelTriangle.VertexIndex1);
     binaryWriter.Write(voxelTriangle.VertexIndex2);
 }