Exemple #1
0
 public override void DebugDrawInvalidTriangles()
 {
     if (this.Entity != null)
     {
         using (List <MyHierarchyComponentBase> .Enumerator enumerator = this.Entity.Hierarchy.Children.GetEnumerator())
         {
             while (enumerator.MoveNext())
             {
                 enumerator.Current.Container.Entity.DebugDrawInvalidTriangles();
             }
         }
         if (this.Entity.Render.GetModel() != null)
         {
             int trianglesCount = this.Entity.Render.GetModel().GetTrianglesCount();
             for (int i = 0; i < trianglesCount; i++)
             {
                 MyTriangleVertexIndices triangle = this.Entity.Render.GetModel().GetTriangle(i);
                 if (MyUtils.IsWrongTriangle(this.Entity.Render.GetModel().GetVertex(triangle.I0), this.Entity.Render.GetModel().GetVertex(triangle.I1), this.Entity.Render.GetModel().GetVertex(triangle.I2)))
                 {
                     Vector3 pointFrom = (Vector3)Vector3.Transform(this.Entity.Render.GetModel().GetVertex(triangle.I0), this.Entity.PositionComp.WorldMatrix);
                     Vector3 pointTo   = (Vector3)Vector3.Transform(this.Entity.Render.GetModel().GetVertex(triangle.I1), this.Entity.PositionComp.WorldMatrix);
                     Vector3 vector3   = (Vector3)Vector3.Transform(this.Entity.Render.GetModel().GetVertex(triangle.I2), this.Entity.PositionComp.WorldMatrix);
                     MyRenderProxy.DebugDrawLine3D(pointFrom, pointTo, Color.Purple, Color.Purple, false, false);
                     MyRenderProxy.DebugDrawLine3D(pointTo, vector3, Color.Purple, Color.Purple, false, false);
                     MyRenderProxy.DebugDrawLine3D(vector3, pointFrom, Color.Purple, Color.Purple, false, false);
                     Vector3 vector4 = ((pointFrom + pointTo) + vector3) / 3f;
                     MyRenderProxy.DebugDrawLine3D(vector4, vector4 + Vector3.UnitX, Color.Yellow, Color.Yellow, false, false);
                     MyRenderProxy.DebugDrawLine3D(vector4, vector4 + Vector3.UnitY, Color.Yellow, Color.Yellow, false, false);
                     MyRenderProxy.DebugDrawLine3D(vector4, vector4 + Vector3.UnitZ, Color.Yellow, Color.Yellow, false, false);
                 }
             }
         }
     }
 }
        private float?ProcessTriangle(int triangleIndex)
        {
            System.Diagnostics.Debug.Assert((int)m_flags != 0);

            MyTriangle_Vertexes     triangle;
            MyTriangleVertexIndices triangleIndices = m_model.Triangles[triangleIndex];

            m_model.GetVertex(triangleIndices.I0, triangleIndices.I2, triangleIndices.I1, out triangle.Vertex0, out triangle.Vertex1, out triangle.Vertex2);

            Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

            //We dont want backside intersections
            if (((int)(m_flags & IntersectionFlags.FLIPPED_TRIANGLES) == 0) &&
                Vector3.Dot(m_line.Direction, calculatedTriangleNormal) > 0)
            {
                return(null);
            }

            float?distance = MyUtils.GetLineTriangleIntersection(ref m_line, ref triangle);

            //  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)))
            {
                //  We need to remember original triangleVertexes coordinates (not transformed by world matrix)
                result = new MyIntersectionResultLineTriangle(ref triangle, ref calculatedTriangleNormal, distance.Value);
                return(distance.Value);
            }
            return(null);
        }
        //  Return true if object intersects specified sphere.
        //  This method doesn't return exact point of intersection or any additional data.
        //  We don't look for closest intersection - so we stop on first intersection found.
        //  IMPORTANT: Sphere must be in model space, so don't transform it!
        public bool GetIntersectionWithSphere(MyModel model, ref BoundingSphere sphere)
        {
            //  Check if sphere intersects bounding box of this node
            if (MyUtils.IsBoxIntersectingSphere(ref m_boundingBox, ref sphere) == false)
            {
                return(false);
            }

            // temporary variable for storing tirngle boundingbox info
            BoundingBox triangleBoundingBox = new BoundingBox();

            //  Triangles that are directly in this node
            for (int i = 0; i < m_triangleIndices.Count; i++)
            {
                int triangleIndex = m_triangleIndices[i];

                model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);

                //  First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests.
                if (MyUtils.IsBoxIntersectingSphere(triangleBoundingBox, ref sphere) == true)
                {
                    //  See that we swaped vertex indices!!
                    MyTriangle_Vertexes     triangle;
                    MyTriangleVertexIndices triangleIndices = model.Triangles[triangleIndex];
                    triangle.Vertex0 = model.GetVertex(triangleIndices.I0);
                    triangle.Vertex1 = model.GetVertex(triangleIndices.I2);
                    triangle.Vertex2 = model.GetVertex(triangleIndices.I1);

                    MyPlane trianglePlane = new MyPlane(ref triangle);

                    if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null)
                    {
                        //  If we found intersection we can stop and dont need to look further
                        return(true);
                    }
                }
            }

            //  Get intersection with childs of this node
            if (m_childs != null)
            {
                for (int i = 0; i < m_childs.Count; i++)
                {
                    if (m_childs[i].GetIntersectionWithSphere(model, ref sphere))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
        public void GetTrianglesIntersectingAABB(ref BoundingBox aabb, List <MyTriangle_Vertex_Normal> retTriangles, int maxNeighbourTriangles)
        {
            IndexedVector3 min     = new IndexedVector3(ref aabb.Min);
            IndexedVector3 max     = new IndexedVector3(ref aabb.Max);
            AABB           gi_aabb = new AABB(ref min, ref max);

            m_overlappedTriangles.Clear();

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("m_bvh.BoxQuery");
            bool res = m_bvh.BoxQuery(ref gi_aabb, m_overlappedTriangles);

            MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

            if (res)
            {
                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("m_overlappedTriangles");

                //foreach (var triangleIndex in m_overlappedTriangles)
                for (int i = 0; i < m_overlappedTriangles.Count; i++)
                {
                    var triangleIndex = m_overlappedTriangles[i];

                    //  If we reached end of the buffer of neighbour triangles, we stop adding new ones. This is better behavior than throwing exception because of array overflow.
                    if (retTriangles.Count == maxNeighbourTriangles)
                    {
                        MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
                        return;
                    }


                    MyTriangleVertexIndices triangle         = m_model.Triangles[triangleIndex];
                    MyTriangle_Vertexes     triangleVertices = new MyTriangle_Vertexes();
                    m_model.GetVertex(triangle.I0, triangle.I1, triangle.I2, out triangleVertices.Vertex0, out triangleVertices.Vertex1, out triangleVertices.Vertex2);

                    IndexedVector3 iv0 = new IndexedVector3(ref triangleVertices.Vertex0);
                    IndexedVector3 iv1 = new IndexedVector3(ref triangleVertices.Vertex1);
                    IndexedVector3 iv2 = new IndexedVector3(ref triangleVertices.Vertex2);

                    MyTriangle_Vertex_Normal retTriangle;
                    retTriangle.Vertexes = triangleVertices;
                    retTriangle.Normal   = Vector3.Forward;

                    retTriangles.Add(retTriangle);
                }

                MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
            }
        }
        public bool GetIntersectionWithSphere(MyEntity physObject, ref BoundingSphere sphere)
        {
            //  Transform sphere from world space to object space
            Matrix         worldInv = physObject.GetWorldMatrixInverted();
            Vector3        positionInObjectSpace = MyUtils.GetTransform(sphere.Center, ref worldInv);
            BoundingSphere sphereInObjectSpace   = new BoundingSphere(positionInObjectSpace, sphere.Radius);

            var aabb = BoundingBoxHelper.InitialBox;

            BoundingBoxHelper.AddSphere(ref sphereInObjectSpace, ref aabb);
            AABB gi_aabb = new AABB(ref aabb.Min, ref aabb.Max);

            m_overlappedTriangles.Clear();
            if (m_bvh.BoxQuery(ref gi_aabb, m_overlappedTriangles))
            {
                // temporary variable for storing tirngle boundingbox info
                BoundingBox triangleBoundingBox = new BoundingBox();

                //  Triangles that are directly in this node
                for (int i = 0; i < m_overlappedTriangles.Count; i++)
                {
                    var triangleIndex = m_overlappedTriangles[i];

                    m_model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);

                    //  First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests.
                    if (MyUtils.IsBoxIntersectingSphere(triangleBoundingBox, ref sphereInObjectSpace) == true)
                    {
                        //  See that we swaped vertex indices!!
                        MyTriangle_Vertexes     triangle;
                        MyTriangleVertexIndices triangleIndices = m_model.Triangles[triangleIndex];
                        triangle.Vertex0 = m_model.GetVertex(triangleIndices.I0);
                        triangle.Vertex1 = m_model.GetVertex(triangleIndices.I2);
                        triangle.Vertex2 = m_model.GetVertex(triangleIndices.I1);

                        MyPlane trianglePlane = new MyPlane(ref triangle);

                        if (MyUtils.GetSphereTriangleIntersection(ref sphereInObjectSpace, ref trianglePlane, ref triangle) != null)
                        {
                            //  If we found intersection we can stop and dont need to look further
                            return(true);
                        }
                    }
                }
            }

            return(false);
        }
Exemple #6
0
 public override void DebugDrawInvalidTriangles()
 {
     base.DebugDrawInvalidTriangles();
     foreach (KeyValuePair <Vector3I, MyCubeGridRenderCell> pair in this.m_cubeGrid.Render.RenderData.Cells)
     {
         IEnumerator <KeyValuePair <MyCubePart, ConcurrentDictionary <uint, bool> > > enumerator = pair.Value.CubeParts.GetEnumerator();
         try
         {
             while (enumerator.MoveNext())
             {
                 KeyValuePair <MyCubePart, ConcurrentDictionary <uint, bool> > current = enumerator.Current;
                 MyModel model = current.Key.Model;
                 if (model != null)
                 {
                     int trianglesCount = model.GetTrianglesCount();
                     for (int i = 0; i < trianglesCount; i++)
                     {
                         MyTriangleVertexIndices triangle = model.GetTriangle(i);
                         if (MyUtils.IsWrongTriangle(model.GetVertex(triangle.I0), model.GetVertex(triangle.I1), model.GetVertex(triangle.I2)))
                         {
                             Vector3 pointFrom = Vector3.Transform(model.GetVertex(triangle.I0), (Matrix)this.m_cubeGrid.PositionComp.WorldMatrix);
                             Vector3 pointTo   = Vector3.Transform(model.GetVertex(triangle.I1), (Matrix)this.m_cubeGrid.PositionComp.WorldMatrix);
                             Vector3 vector3   = Vector3.Transform(model.GetVertex(triangle.I2), (Matrix)this.m_cubeGrid.PositionComp.WorldMatrix);
                             MyRenderProxy.DebugDrawLine3D(pointFrom, pointTo, Color.Purple, Color.Purple, false, false);
                             MyRenderProxy.DebugDrawLine3D(pointTo, vector3, Color.Purple, Color.Purple, false, false);
                             MyRenderProxy.DebugDrawLine3D(vector3, pointFrom, Color.Purple, Color.Purple, false, false);
                             Vector3 vector4 = ((pointFrom + pointTo) + vector3) / 3f;
                             MyRenderProxy.DebugDrawLine3D(vector4, vector4 + Vector3.UnitX, Color.Yellow, Color.Yellow, false, false);
                             MyRenderProxy.DebugDrawLine3D(vector4, vector4 + Vector3.UnitY, Color.Yellow, Color.Yellow, false, false);
                             MyRenderProxy.DebugDrawLine3D(vector4, vector4 + Vector3.UnitZ, Color.Yellow, Color.Yellow, false, false);
                         }
                     }
                 }
             }
         }
         finally
         {
             if (enumerator == null)
             {
                 continue;
             }
             enumerator.Dispose();
         }
     }
 }
Exemple #7
0
 public bool GetIntersectionWithSphere(MyModel model, ref BoundingSphere sphere)
 {
     if (this.m_boundingBox.Intersects(ref sphere))
     {
         BoundingBox boundingBox = new BoundingBox();
         for (int i = 0; i < this.m_triangleIndices.Count; i++)
         {
             int triangleIndex = this.m_triangleIndices[i];
             model.GetTriangleBoundingBox(triangleIndex, ref boundingBox);
             if (boundingBox.Intersects(ref sphere))
             {
                 MyTriangle_Vertices     vertices;
                 MyTriangleVertexIndices indices = model.Triangles[triangleIndex];
                 vertices.Vertex0 = model.GetVertex(indices.I0);
                 vertices.Vertex1 = model.GetVertex(indices.I2);
                 vertices.Vertex2 = model.GetVertex(indices.I1);
                 Plane trianglePlane = new Plane(vertices.Vertex0, vertices.Vertex1, vertices.Vertex2);
                 if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref vertices) != null)
                 {
                     return(true);
                 }
             }
         }
         if (this.m_childs != null)
         {
             for (int j = 0; j < this.m_childs.Count; j++)
             {
                 if (this.m_childs[j].GetIntersectionWithSphere(model, ref sphere))
                 {
                     return(true);
                 }
             }
         }
     }
     return(false);
 }
        public void GetTrianglesIntersectingSphere(MyModel model, ref BoundingSphere sphere, Vector3?referenceNormalVector, float?maxAngle, List <MyTriangle_Vertex_Normals> retTriangles, int maxNeighbourTriangles)
        {
            //  Check if sphere intersects bounding box of this node
            //if (m_boundingBox.Contains(sphere) == ContainmentType.Disjoint) return;
            if (MyUtils.IsBoxIntersectingSphere(ref m_boundingBox, ref sphere) == false)
            {
                return;
            }

            // temporary variable for storing tirngle boundingbox info
            BoundingBox triangleBoundingBox = new BoundingBox();

            //  Triangles that are directly in this node
            for (int i = 0; i < m_triangleIndices.Count; i++)
            {
                //  If we reached end of the buffer of neighbour triangles, we stop adding new ones. This is better behavior than throwing exception because of array overflow.
                if (retTriangles.Count == maxNeighbourTriangles)
                {
                    return;
                }

                int triangleIndex = m_triangleIndices[i];

                model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);

                //  First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests.
                if (MyUtils.IsBoxIntersectingSphere(triangleBoundingBox, ref sphere) == true)
                {
                    //if (m_triangleIndices[value] != ignoreTriangleWithIndex)
                    {
                        //  See that we swaped vertex indices!!
                        MyTriangle_Vertexes triangle;
                        MyTriangle_Normals  triangleNormals;
                        MyTriangle_Normals  triangleBinormals;
                        MyTriangle_Normals  triangleTangents;

                        MyTriangleVertexIndices triangleIndices = model.Triangles[triangleIndex];
                        triangle.Vertex0        = model.GetVertex(triangleIndices.I0);
                        triangle.Vertex1        = model.GetVertex(triangleIndices.I2);
                        triangle.Vertex2        = model.GetVertex(triangleIndices.I1);
                        triangleNormals.Normal0 = model.GetVertexNormal(triangleIndices.I0);
                        triangleNormals.Normal1 = model.GetVertexNormal(triangleIndices.I2);
                        triangleNormals.Normal2 = model.GetVertexNormal(triangleIndices.I1);

                        triangleBinormals.Normal0 = model.GetVertexBinormal(triangleIndices.I0);
                        triangleBinormals.Normal1 = model.GetVertexBinormal(triangleIndices.I2);
                        triangleBinormals.Normal2 = model.GetVertexBinormal(triangleIndices.I1);

                        triangleTangents.Normal0 = model.GetVertexTangent(triangleIndices.I0);
                        triangleTangents.Normal1 = model.GetVertexTangent(triangleIndices.I2);
                        triangleTangents.Normal2 = model.GetVertexTangent(triangleIndices.I1);

                        MyPlane trianglePlane = new MyPlane(ref triangle);

                        if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null)
                        {
                            Vector3 triangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

                            if ((referenceNormalVector.HasValue == false) || (maxAngle.HasValue == false) ||
                                ((MyUtils.GetAngleBetweenVectors(referenceNormalVector.Value, triangleNormal) <= maxAngle)))
                            {
                                MyTriangle_Vertex_Normals retTriangle;
                                retTriangle.Vertexes  = triangle;
                                retTriangle.Normals   = triangleNormals;
                                retTriangle.Binormals = triangleBinormals;
                                retTriangle.Tangents  = triangleTangents;

                                retTriangles.Add(retTriangle);
                            }
                        }
                    }
                }
            }

            //  Get intersection with childs of this node
            if (m_childs != null)
            {
                for (int i = 0; i < m_childs.Count; i++)
                {
                    //m_childs[value].GetTrianglesIntersectingSphere(physObject, ref sphere, referenceNormalVector, maxAngle, ignoreTriangleWithIndex, retTriangles, maxNeighbourTriangles);
                    m_childs[i].GetTrianglesIntersectingSphere(model, ref sphere, referenceNormalVector, maxAngle, retTriangles, maxNeighbourTriangles);
                }
            }
        }
        //  Finds intersection between line and model, using octree for speedup the lookup.
        //  Another speedup is, that first we check triangles that are directly in the node and then start
        //  checking node's childs. But only if child node instersection is less than last know min distance.
        MyIntersectionResultLineTriangle?GetIntersectionWithLineRecursive(MyModel model, ref MyLine line, float?minDistanceUntilNow)
        {
            //  Check if line intersects bounding box of this node and if distance to bounding box is less then last know min distance
            float?distanceToBoundingBox = MyUtils.GetLineBoundingBoxIntersection(ref line, ref m_boundingBox);

            if ((distanceToBoundingBox.HasValue == false) || ((minDistanceUntilNow != null) && (minDistanceUntilNow < distanceToBoundingBox.Value)))
            {
                return(null);
            }

            //  Triangles that are directly in this node
            MyIntersectionResultLineTriangle?foundIntersection = null;

            // temporary variable for storing tirngle boundingbox info
            BoundingBox triangleBoundingBox = new BoundingBox();

            MinerWars.AppCode.Game.Managers.MyPerformanceCounter.PerCameraDraw.RayCastTrianglesProcessed += m_triangleIndices.Count;

            for (int i = 0; i < m_triangleIndices.Count; i++)
            {
                int triangleIndex = m_triangleIndices[i];

                model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);

                //  First test intersection of triangleVertexes's bounding box with line's bounding box. And only if they overlap or intersect, do further intersection tests.
                if (MyUtils.IsBoxIntersectingBox(triangleBoundingBox, ref line.BoundingBox) == true)
                {
                    //  See that we swaped vertex indices!!
                    MyTriangle_Vertexes     triangle;
                    MyTriangleVertexIndices triangleIndices = model.Triangles[triangleIndex];
                    triangle.Vertex0 = model.GetVertex(triangleIndices.I0);
                    triangle.Vertex1 = model.GetVertex(triangleIndices.I2);
                    triangle.Vertex2 = model.GetVertex(triangleIndices.I1);

                    float?distance = MyUtils.GetLineTriangleIntersection(ref line, ref triangle);

                    //  If intersection occured and if distance to intersection is closer to origin than any previous intersection
                    if ((distance != null) && ((foundIntersection == null) || (distance.Value < foundIntersection.Value.Distance)))
                    {
                        Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

                        //  We need to remember original triangleVertexes coordinates (not transformed by world matrix)
                        foundIntersection = new MyIntersectionResultLineTriangle(ref triangle, ref calculatedTriangleNormal, distance.Value);
                    }
                }
            }

            //  Get intersection with childs of this node
            if (m_childs != null)
            {
                for (int i = 0; i < m_childs.Count; i++)
                {
                    MyIntersectionResultLineTriangle?childIntersection = m_childs[i].GetIntersectionWithLineRecursive(model, ref line,
                                                                                                                      (foundIntersection == null) ? (float?)null : foundIntersection.Value.Distance);

                    //  If intersection occured and if distance to intersection is closer to origin than any previous intersection
                    foundIntersection = MyIntersectionResultLineTriangle.GetCloserIntersection(ref foundIntersection, ref childIntersection);
                }
            }

            return(foundIntersection);
        }
        public void GetTrianglesIntersectingSphere(ref BoundingSphere sphere, List <MyTriangle_Vertex_Normal> retTriangles, int maxNeighbourTriangles)
        {
            Vector3?referenceNormalVector = null;
            float?  maxAngle = null;

            var aabb = BoundingBoxHelper.InitialBox;

            BoundingBoxHelper.AddSphere(ref sphere, ref aabb);
            AABB gi_aabb = new AABB(ref aabb.Min, ref aabb.Max);

            m_overlappedTriangles.Clear();

            // MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("m_bvh.BoxQuery"); // This code is called recursively and cause profiler to lag
            bool res = m_bvh.BoxQuery(ref gi_aabb, m_overlappedTriangles);

            // MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();

            if (res)
            {
                //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().StartProfilingBlock("m_overlappedTriangles");  // This code is called recursively and cause profiler to lag

                // temporary variable for storing tirngle boundingbox info
                BoundingBox triangleBoundingBox = new BoundingBox();

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

                    //  If we reached end of the buffer of neighbour triangles, we stop adding new ones. This is better behavior than throwing exception because of array overflow.
                    if (retTriangles.Count == maxNeighbourTriangles)
                    {
                        return;
                    }

                    m_model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);

                    //gi_aabb.CollideTriangleExact

                    //  First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests.
                    if (MyUtils.IsBoxIntersectingSphere(triangleBoundingBox, ref sphere) == true)
                    {
                        //if (m_triangleIndices[value] != ignoreTriangleWithIndex)
                        {
                            //  See that we swaped vertex indices!!
                            MyTriangle_Vertexes triangle;

                            MyTriangleVertexIndices triangleIndices = m_model.Triangles[triangleIndex];
                            triangle.Vertex0 = m_model.GetVertex(triangleIndices.I0);
                            triangle.Vertex1 = m_model.GetVertex(triangleIndices.I2);
                            triangle.Vertex2 = m_model.GetVertex(triangleIndices.I1);
                            Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

                            MyPlane trianglePlane = new MyPlane(ref triangle);

                            if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null)
                            {
                                Vector3 triangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

                                if ((referenceNormalVector.HasValue == false) || (maxAngle.HasValue == false) ||
                                    ((MyUtils.GetAngleBetweenVectors(referenceNormalVector.Value, triangleNormal) <= maxAngle)))
                                {
                                    MyTriangle_Vertex_Normal retTriangle;
                                    retTriangle.Vertexes = triangle;
                                    retTriangle.Normal   = calculatedTriangleNormal;

                                    retTriangles.Add(retTriangle);
                                }
                            }
                        }
                    }
                }

                //MinerWars.AppCode.Game.Render.MyRender.GetRenderProfiler().EndProfilingBlock();
            }
        }
        public void GetTrianglesIntersectingSphere(ref BoundingSphere sphere, Vector3?referenceNormalVector, float?maxAngle, List <MyTriangle_Vertex_Normals> retTriangles, int maxNeighbourTriangles)
        {
            var aabb = BoundingBoxHelper.InitialBox;

            BoundingBoxHelper.AddSphere(ref sphere, ref aabb);
            AABB gi_aabb = new AABB(ref aabb.Min, ref aabb.Max);

            m_overlappedTriangles.Clear();
            if (m_bvh.BoxQuery(ref gi_aabb, m_overlappedTriangles))
            {
                // temporary variable for storing tirngle boundingbox info
                BoundingBox triangleBoundingBox = new BoundingBox();

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

                    //  If we reached end of the buffer of neighbour triangles, we stop adding new ones. This is better behavior than throwing exception because of array overflow.
                    if (retTriangles.Count == maxNeighbourTriangles)
                    {
                        return;
                    }

                    m_model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);

                    //  First test intersection of triangleVertexes's bounding box with bounding sphere. And only if they overlap or intersect, do further intersection tests.
                    if (MyUtils.IsBoxIntersectingSphere(triangleBoundingBox, ref sphere) == true)
                    {
                        //if (m_triangleIndices[value] != ignoreTriangleWithIndex)
                        {
                            //  See that we swaped vertex indices!!
                            MyTriangle_Vertexes triangle;
                            MyTriangle_Normals  triangleNormals;
                            MyTriangle_Normals  triangleBinormals;
                            MyTriangle_Normals  triangleTangents;

                            MyTriangleVertexIndices triangleIndices = m_model.Triangles[triangleIndex];
                            m_model.GetVertex(triangleIndices.I0, triangleIndices.I2, triangleIndices.I1, out triangle.Vertex0, out triangle.Vertex1, out triangle.Vertex2);

                            /*
                             * triangle.Vertex0 = m_model.GetVertex(triangleIndices.I0);
                             * triangle.Vertex1 = m_model.GetVertex(triangleIndices.I2);
                             * triangle.Vertex2 = m_model.GetVertex(triangleIndices.I1);
                             */

                            triangleNormals.Normal0 = m_model.GetVertexNormal(triangleIndices.I0);
                            triangleNormals.Normal1 = m_model.GetVertexNormal(triangleIndices.I2);
                            triangleNormals.Normal2 = m_model.GetVertexNormal(triangleIndices.I1);

                            if (MinerWars.AppCode.Game.Render.MyRenderConstants.RenderQualityProfile.ForwardRender)
                            {
                                triangleBinormals.Normal0 = triangleNormals.Normal0;
                                triangleBinormals.Normal1 = triangleNormals.Normal1;
                                triangleBinormals.Normal2 = triangleNormals.Normal2;

                                triangleTangents.Normal0 = triangleNormals.Normal0;
                                triangleTangents.Normal1 = triangleNormals.Normal1;
                                triangleTangents.Normal2 = triangleNormals.Normal2;
                            }
                            else
                            {
                                triangleBinormals.Normal0 = m_model.GetVertexBinormal(triangleIndices.I0);
                                triangleBinormals.Normal1 = m_model.GetVertexBinormal(triangleIndices.I2);
                                triangleBinormals.Normal2 = m_model.GetVertexBinormal(triangleIndices.I1);

                                triangleTangents.Normal0 = m_model.GetVertexTangent(triangleIndices.I0);
                                triangleTangents.Normal1 = m_model.GetVertexTangent(triangleIndices.I2);
                                triangleTangents.Normal2 = m_model.GetVertexTangent(triangleIndices.I1);
                            }

                            MyPlane trianglePlane = new MyPlane(ref triangle);

                            if (MyUtils.GetSphereTriangleIntersection(ref sphere, ref trianglePlane, ref triangle) != null)
                            {
                                Vector3 triangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

                                if ((referenceNormalVector.HasValue == false) || (maxAngle.HasValue == false) ||
                                    ((MyUtils.GetAngleBetweenVectors(referenceNormalVector.Value, triangleNormal) <= maxAngle)))
                                {
                                    MyTriangle_Vertex_Normals retTriangle;
                                    retTriangle.Vertexes  = triangle;
                                    retTriangle.Normals   = triangleNormals;
                                    retTriangle.Binormals = triangleBinormals;
                                    retTriangle.Tangents  = triangleTangents;

                                    retTriangles.Add(retTriangle);
                                }
                            }
                        }
                    }
                }
            }
        }
        //  Finds intersection between line and model, using octree for speedup the lookup.
        //  Another speedup is, that first we check triangles that are directly in the node and then start
        //  checking node's childs. But only if child node instersection is less than last know min distance.
        VRage.Game.Models.MyIntersectionResultLineTriangle?GetIntersectionWithLineRecursive(MyModel model, ref LineD line, double?minDistanceUntilNow)
        {
            //  Check if line intersects bounding box of this node and if distance to bounding box is less then last know min distance
            Line   lineF = (Line)line;
            double?distanceToBoundingBox = MyUtils.GetLineBoundingBoxIntersection(ref lineF, ref m_boundingBox);

            if ((distanceToBoundingBox.HasValue == false) || ((minDistanceUntilNow != null) && (minDistanceUntilNow < distanceToBoundingBox.Value)))
            {
                return(null);
            }

            //  Triangles that are directly in this node
            VRage.Game.Models.MyIntersectionResultLineTriangle?foundIntersection = null;

            // temporary variable for storing tirngle boundingbox info
            BoundingBox triangleBoundingBox = new BoundingBox();
            BoundingBox lineBB = BoundingBox.CreateInvalid();

            lineBB = lineBB.Include(line.From);
            lineBB = lineBB.Include(line.To);

            for (int i = 0; i < m_triangleIndices.Count; i++)
            {
                int triangleIndex = m_triangleIndices[i];

                model.GetTriangleBoundingBox(triangleIndex, ref triangleBoundingBox);

                //  First test intersection of triangleVertexes's bounding box with line's bounding box. And only if they overlap or intersect, do further intersection tests.
                if (triangleBoundingBox.Intersects(ref lineBB))
                {
                    //  See that we swaped vertex indices!!
                    MyTriangle_Vertices     triangle;
                    MyTriangleVertexIndices triangleIndices = model.Triangles[triangleIndex];
                    triangle.Vertex0 = model.GetVertex(triangleIndices.I0);
                    triangle.Vertex1 = model.GetVertex(triangleIndices.I2);
                    triangle.Vertex2 = model.GetVertex(triangleIndices.I1);

                    double?distance = MyUtils.GetLineTriangleIntersection(ref lineF, ref triangle);

                    //  If intersection occured and if distance to intersection is closer to origin than any previous intersection
                    if ((distance != null) && ((foundIntersection == null) || (distance.Value < foundIntersection.Value.Distance)))
                    {
                        Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref triangle);

                        //  We need to remember original triangleVertexes coordinates (not transformed by world matrix)
                        foundIntersection = new VRage.Game.Models.MyIntersectionResultLineTriangle(ref triangle, ref calculatedTriangleNormal, distance.Value);
                    }
                }
            }

            //  Get intersection with childs of this node
            if (m_childs != null)
            {
                for (int i = 0; i < m_childs.Count; i++)
                {
                    VRage.Game.Models.MyIntersectionResultLineTriangle?childIntersection = m_childs[i].GetIntersectionWithLineRecursive(model, ref line,
                                                                                                                                        (foundIntersection == null) ? (double?)null : foundIntersection.Value.Distance);

                    //  If intersection occured and if distance to intersection is closer to origin than any previous intersection
                    foundIntersection = VRage.Game.Models.MyIntersectionResultLineTriangle.GetCloserIntersection(ref foundIntersection, ref childIntersection);
                }
            }

            return(foundIntersection);
        }
Exemple #13
0
        /// <summary>
        /// Debug draw of this physics object.
        /// </summary>
        public void DebugDraw()
        {
            const float alpha = 0.3f;

            if (!Enabled)
            {
                return;
            }

            foreach (var primitive in this.rigidBody.GetRBElementList())
            {
                MyRBElementType type = primitive.GetElementType();

                switch (type)
                {
                case MyRBElementType.ET_BOX:
                {
                    var box = (MyRBBoxElement)primitive;

                    MyDebugDraw.DrawHiresBoxWireframe(
                        Matrix.CreateScale(box.Size) * box.GetGlobalTransformation(),
                        Color.Green.ToVector3(), alpha);
                }
                break;

                case MyRBElementType.ET_SPHERE:
                {
                    var sphere = (MyRBSphereElement)primitive;

                    MyDebugDraw.DrawSphereWireframe(
                        Matrix.CreateScale(sphere.Radius) * sphere.GetGlobalTransformation(),
                        Color.Green.ToVector3(), alpha);
                }
                break;

                case MyRBElementType.ET_TRIANGLEMESH:
                {
                    var triMesh = (MyRBTriangleMeshElement)primitive;
                    var model   = triMesh.Model;

                    Matrix transformMatrix = this.rigidBody.Matrix;

                    MyDebugDrawCachedLines.Clear();

                    //  This is just a reserve
                    const int numberOfAddTrianglesInLoop = 3;

                    int triangleIndex = 0;
                    while (true)
                    {
                        //bool finished = triangleIndex >= mesh.GetNumTriangles();
                        bool finished = triangleIndex >= model.GetTrianglesCount();

                        if ((MyDebugDrawCachedLines.IsFull(-numberOfAddTrianglesInLoop)) || (finished))
                        {
                            MyDebugDrawCachedLines.DrawLines();
                            MyDebugDrawCachedLines.Clear();
                        }

                        if (finished)
                        {
                            break;
                        }

                        MyTriangleVertexIndices triangle = model.Triangles[triangleIndex];

                        //  We now transform the triangleVertexes into world space (we could keep leave the mesh alone
                        //  but at this point 3 vector transforms is probably not a major slow down)
                        Vector3 triVec0 = model.GetVertex(triangle.I0);
                        Vector3 triVec1 = model.GetVertex(triangle.I2);
                        Vector3 triVec2 = model.GetVertex(triangle.I1);

                        // Move triangle into world space
                        Vector3.Transform(ref triVec0, ref transformMatrix, out triVec0);
                        Vector3.Transform(ref triVec1, ref transformMatrix, out triVec1);
                        Vector3.Transform(ref triVec2, ref transformMatrix, out triVec2);

                        MyDebugDrawCachedLines.AddLine(triVec0, triVec1, Color.Green, Color.Green);
                        MyDebugDrawCachedLines.AddLine(triVec1, triVec2, Color.Green, Color.Green);
                        MyDebugDrawCachedLines.AddLine(triVec2, triVec0, Color.Green, Color.Green);

                        /*
                         * MyTriangle_Vertexes tv = new MyTriangle_Vertexes();
                         * tv.Vertex0 = triVec0;
                         * tv.Vertex1 = triVec1;
                         * tv.Vertex2 = triVec2;
                         * Vector3 calculatedTriangleNormal = MyUtils.GetNormalVectorFromTriangle(ref tv);
                         * Vector3 center = (triVec0 + triVec1 + triVec2)/3.0f;
                         * MyDebugDrawCachedLines.AddLine(center, center + calculatedTriangleNormal * 5, Color.Red, Color.Red);
                         */

                        //MyDebugDraw.AddDrawTriangle(triVec0, triVec1, triVec2, new Color(0,0.8f, 0, 0.1f));

                        triangleIndex++;
                    }
                }
                break;
                }
            }
        }
Exemple #14
0
        public void GetTrianglesIntersectingSphere(MyModel model, ref BoundingSphereD sphere, Vector3?referenceNormalVector, float?maxAngle, List <MyTriangle_Vertex_Normal> retTriangles, int maxNeighbourTriangles)
        {
            BoundingSphere sphere2 = (BoundingSphere)sphere;

            if (this.m_boundingBox.Intersects(ref sphere))
            {
                BoundingBox boundingBox = new BoundingBox();
                int         num         = 0;
                while (true)
                {
                    while (true)
                    {
                        if (num >= this.m_triangleIndices.Count)
                        {
                            if (this.m_childs != null)
                            {
                                for (int i = 0; i < this.m_childs.Count; i++)
                                {
                                    this.m_childs[i].GetTrianglesIntersectingSphere(model, ref sphere, referenceNormalVector, maxAngle, retTriangles, maxNeighbourTriangles);
                                }
                            }
                            return;
                        }
                        if (retTriangles.Count == maxNeighbourTriangles)
                        {
                            return;
                        }
                        int triangleIndex = this.m_triangleIndices[num];
                        model.GetTriangleBoundingBox(triangleIndex, ref boundingBox);
                        if (boundingBox.Intersects(ref sphere))
                        {
                            MyTriangle_Vertices     vertices;
                            MyTriangleVertexIndices indices = model.Triangles[triangleIndex];
                            vertices.Vertex0 = model.GetVertex(indices.I0);
                            vertices.Vertex1 = model.GetVertex(indices.I2);
                            vertices.Vertex2 = model.GetVertex(indices.I1);
                            Vector3 normalVectorFromTriangle = MyUtils.GetNormalVectorFromTriangle(ref vertices);
                            Plane   trianglePlane            = new Plane(vertices.Vertex0, vertices.Vertex1, vertices.Vertex2);
                            if (MyUtils.GetSphereTriangleIntersection(ref sphere2, ref trianglePlane, ref vertices) != null)
                            {
                                MyTriangle_Vertex_Normal normal;
                                Vector3 vectorB = MyUtils.GetNormalVectorFromTriangle(ref vertices);
                                if ((referenceNormalVector != null) && (maxAngle != null))
                                {
                                    float?nullable2 = maxAngle;
                                    if (!((MyUtils.GetAngleBetweenVectors(referenceNormalVector.Value, vectorB) <= nullable2.GetValueOrDefault()) & (nullable2 != null)))
                                    {
                                        break;
                                    }
                                }
                                normal.Vertexes = vertices;
                                normal.Normal   = normalVectorFromTriangle;
                                retTriangles.Add(normal);
                            }
                        }
                        break;
                    }
                    num++;
                }
            }
        }
Exemple #15
0
        private MyIntersectionResultLineTriangle?GetIntersectionWithLineRecursive(MyModel model, ref Line line, double?minDistanceUntilNow)
        {
            double?nullable4;
            double?nullable1;
            float? lineBoundingBoxIntersection = MyUtils.GetLineBoundingBoxIntersection(ref line, ref this.m_boundingBox);

            if (lineBoundingBoxIntersection != null)
            {
                nullable1 = new double?((double)lineBoundingBoxIntersection.GetValueOrDefault());
            }
            else
            {
                nullable4 = null;
                nullable1 = nullable4;
            }
            double?nullable = nullable1;

            if (nullable != null)
            {
                if (minDistanceUntilNow != null)
                {
                    nullable4 = minDistanceUntilNow;
                    double num = nullable.Value;
                    if ((nullable4.GetValueOrDefault() < num) & (nullable4 != null))
                    {
                        goto TR_0000;
                    }
                }
                MyIntersectionResultLineTriangle?a = null;
                BoundingBox boundingBox            = new BoundingBox();
                BoundingBox box = BoundingBox.CreateInvalid().Include(line.From).Include(line.To);
                for (int i = 0; i < this.m_triangleIndices.Count; i++)
                {
                    int triangleIndex = this.m_triangleIndices[i];
                    model.GetTriangleBoundingBox(triangleIndex, ref boundingBox);
                    if (boundingBox.Intersects(ref box))
                    {
                        MyTriangle_Vertices     vertices;
                        MyTriangleVertexIndices indices = model.Triangles[triangleIndex];
                        vertices.Vertex0 = model.GetVertex(indices.I0);
                        vertices.Vertex1 = model.GetVertex(indices.I2);
                        vertices.Vertex2 = model.GetVertex(indices.I1);
                        float?lineTriangleIntersection = MyUtils.GetLineTriangleIntersection(ref line, ref vertices);
                        if ((lineTriangleIntersection != null) && ((a == null) || (lineTriangleIntersection.Value < a.Value.Distance)))
                        {
                            Vector3 normalVectorFromTriangle = MyUtils.GetNormalVectorFromTriangle(ref vertices);
                            a = new MyIntersectionResultLineTriangle(triangleIndex, ref vertices, ref normalVectorFromTriangle, lineTriangleIntersection.Value);
                        }
                    }
                }
                if (this.m_childs != null)
                {
                    for (int j = 0; j < this.m_childs.Count; j++)
                    {
                        double?nullable8;
                        if (a != null)
                        {
                            nullable8 = new double?((double)a.Value.Distance);
                        }
                        else
                        {
                            nullable4 = null;
                            nullable8 = nullable4;
                        }
                        MyIntersectionResultLineTriangle?b = this.m_childs[j].GetIntersectionWithLineRecursive(model, ref line, nullable8);
                        a = MyIntersectionResultLineTriangle.GetCloserIntersection(ref a, ref b);
                    }
                }
                return(a);
            }
TR_0000:
            return(null);
        }