Пример #1
0
        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);
            }

            Line  lineF    = (Line)m_line;
            float?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) && ((m_result == null) || (distance.Value < m_result.Value.Distance)))
            {
                //  We need to remember original triangleVertexes coordinates (not transformed by world matrix)
                m_result = new MyIntersectionResultLineTriangle(ref triangle, ref calculatedTriangleNormal, distance.Value);
                return(distance.Value);
            }
            return(null);
        }
Пример #2
0
        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);
            }

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

            if (distance.HasValue)
            {
                var result = new MyIntersectionResultLineTriangle(ref triangle, ref calculatedTriangleNormal, distance.Value);
                m_result.Add(result);
            }

            return(distance);
        }
Пример #3
0
        public void GetTrianglesIntersectingAABB(ref BoundingBoxD aabb, List <MyTriangle_Vertex_Normal> retTriangles, int maxNeighbourTriangles)
        {
            BoundingBox    boxF    = (BoundingBox)aabb;
            IndexedVector3 min     = boxF.Min.ToBullet();
            IndexedVector3 max     = boxF.Max.ToBullet();
            AABB           gi_aabb = new AABB(ref min, ref max);

            m_overlappedTriangles.Clear();

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("m_bvh.BoxQuery");
            bool res = m_bvh.BoxQuery(ref gi_aabb, m_overlappedTriangles);

            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            if (res)
            {
                VRageRender.MyRenderProxy.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)
                    {
                        VRageRender.MyRenderProxy.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 = triangleVertices.Vertex0.ToBullet();
                    IndexedVector3 iv1 = triangleVertices.Vertex1.ToBullet();
                    IndexedVector3 iv2 = triangleVertices.Vertex2.ToBullet();

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

                    retTriangles.Add(retTriangle);
                }

                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
            }
        }
Пример #4
0
        public bool GetIntersectionWithSphere(IMyEntity entity, ref BoundingSphereD sphere)
        {
            //  Transform sphere from world space to object space
            MatrixD         worldInv = entity.PositionComp.GetWorldMatrixNormalizedInv();
            Vector3         positionInObjectSpace = (Vector3)Vector3D.Transform(sphere.Center, ref worldInv);
            BoundingSphereD sphereInObjectSpace   = new BoundingSphereD(positionInObjectSpace, (float)sphere.Radius);

            var            aabb    = BoundingBox.CreateInvalid();
            BoundingSphere sphereF = (BoundingSphere)sphereInObjectSpace;

            aabb.Include(ref sphereF);
            AABB gi_aabb = new AABB(aabb.Min.ToBullet(), aabb.Max.ToBullet());

            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 (triangleBoundingBox.Intersects(ref sphereInObjectSpace))
                    {
                        //  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);

                        PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2);

                        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);
        }
Пример #5
0
        void CopyTriangleIndices()
        {
            Triangles = new MyTriangleVertexIndices[GetNumberOfTrianglesForColDet()];
            int triangleIndex = 0;

            foreach (MyMesh mesh in m_meshContainer)
            {
                mesh.TriStart = triangleIndex;

                if (m_Indices != null)
                {
                    for (int i = 0; i < mesh.TriCount; i++)
                    {
                        //  Notice we swap indices. It's because XNA's clock-wise rule probably differs from FBX's, and JigLib needs it in this order.
                        //  But because of this, I did similar swaping in my col/det functions
                        Triangles[triangleIndex] = new MyTriangleVertexIndices(m_Indices[mesh.IndexStart + i * 3 + 0], m_Indices[mesh.IndexStart + i * 3 + 2], m_Indices[mesh.IndexStart + i * 3 + 1]);
                        triangleIndex++;
                    }
                }
                else if (m_Indices_16bit != null)
                {
                    for (int i = 0; i < mesh.TriCount; i++)
                    {
                        //  Notice we swap indices. It's because XNA's clock-wise rule probably differs from FBX's, and JigLib needs it in this order.
                        //  But because of this, I did similar swaping in my col/det functions
                        Triangles[triangleIndex] = new MyTriangleVertexIndices(m_Indices_16bit[mesh.IndexStart + i * 3 + 0], m_Indices_16bit[mesh.IndexStart + i * 3 + 2], m_Indices_16bit[mesh.IndexStart + i * 3 + 1]);
                        triangleIndex++;
                    }
                }
                else
                {
                    throw new InvalidBranchException();  // Neither 32bit or 16bit indices are set, probably already called mesh.DisposeIndices()
                }
            }

            CheckTriangles(triangleIndex);
        }
Пример #6
0
        void CopyTriangleIndices()
        {
            Triangles = new MyTriangleVertexIndices[GetNumberOfTrianglesForColDet()];
            int triangleIndex = 0;

            foreach (MyMesh mesh in m_meshContainer)
            {
                mesh.TriStart = triangleIndex;

                if (m_Indices != null)
                {
                    for (int i = 0; i < mesh.TriCount; i++)
                    {
                        //  Notice we swap indices. It's because XNA's clock-wise rule probably differs from FBX's, and JigLib needs it in this order.
                        //  But because of this, I did similar swaping in my col/det functions
                        Triangles[triangleIndex] = new MyTriangleVertexIndices(m_Indices[mesh.IndexStart + i * 3 + 0], m_Indices[mesh.IndexStart + i * 3 + 2], m_Indices[mesh.IndexStart + i * 3 + 1]);
                        triangleIndex++;
                    }
                }
                else if (m_Indices_16bit != null)
                {
                    for (int i = 0; i < mesh.TriCount; i++)
                    {
                        //  Notice we swap indices. It's because XNA's clock-wise rule probably differs from FBX's, and JigLib needs it in this order.
                        //  But because of this, I did similar swaping in my col/det functions
                        Triangles[triangleIndex] = new MyTriangleVertexIndices(m_Indices_16bit[mesh.IndexStart + i * 3 + 0], m_Indices_16bit[mesh.IndexStart + i * 3 + 2], m_Indices_16bit[mesh.IndexStart + i * 3 + 1]);
                        triangleIndex++;
                    }
                }
                else throw new InvalidBranchException(); // Neither 32bit or 16bit indices are set, probably already called mesh.DisposeIndices()
            }

            CheckTriangles(triangleIndex);
        }
Пример #7
0
        public void GetTrianglesIntersectingSphere(ref BoundingSphereD sphere, List <MyTriangle_Vertex_Normal> retTriangles, int maxNeighbourTriangles)
        {
            Vector3?referenceNormalVector = null;
            float?  maxAngle = null;

            var            aabb    = BoundingBox.CreateInvalid();
            BoundingSphere sphereF = (BoundingSphere)sphere;

            aabb.Include(ref sphereF);
            AABB gi_aabb = new AABB(aabb.Min.ToBullet(), aabb.Max.ToBullet());

            m_overlappedTriangles.Clear();

            // VRageRender.MyRenderProxy.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);

            // VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            if (res)
            {
                //VRageRender.MyRenderProxy.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 (triangleBoundingBox.Intersects(ref sphere))
                    {
                        //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);

                            PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2);

                            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);
                                }
                            }
                        }
                    }
                }

                //VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
            }
        }
Пример #8
0
        public void GetTrianglesIntersectingSphere(ref BoundingSphereD sphere, Vector3?referenceNormalVector, float?maxAngle, List <MyTriangle_Vertex_Normals> retTriangles, int maxNeighbourTriangles)
        {
            var            aabb    = BoundingBox.CreateInvalid();
            BoundingSphere sphereF = (BoundingSphere)sphere;

            aabb.Include(ref sphereF);
            AABB gi_aabb = new AABB(aabb.Min.ToBullet(), aabb.Max.ToBullet());

            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 (triangleBoundingBox.Intersects(ref sphere))
                    {
                        //if (m_triangleIndices[value] != ignoreTriangleWithIndex)
                        {
                            //  See that we swaped vertex indices!!
                            MyTriangle_Vertexes triangle;
                            MyTriangle_Normals  triangleNormals;
                            //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);

                            PlaneD trianglePlane = new PlaneD(triangle.Vertex0, triangle.Vertex1, triangle.Vertex2);

                            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.Vertices = triangle;
                                    retTriangle.Normals  = triangleNormals;

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