public MyIntersectionResultLineTriangleEx(MyIntersectionResultLineTriangle triangle, IMyEntity entity, ref LineD line)
        {
            Triangle = triangle;
            Entity   = entity;
            InputLineInObjectSpace = line;

            NormalInObjectSpace = MyUtils.GetNormalVectorFromTriangle(ref Triangle.InputTriangle);
            // fixme: calculated normal for degenerated triangles was NaN; here should be some better calculation of normal from degenerated triangle
            if (!NormalInObjectSpace.IsValid())
            {
                NormalInObjectSpace = new Vector3(0, 0, 1);
            }
            IntersectionPointInObjectSpace = line.From + line.Direction * Triangle.Distance;

            if (Entity is IMyVoxelBase)
            {
                IntersectionPointInWorldSpace = (Vector3D)IntersectionPointInObjectSpace;
                NormalInWorldSpace            = NormalInObjectSpace;

                //  This will move intersection point from world space into voxel map's object space
                IntersectionPointInObjectSpace = IntersectionPointInObjectSpace - ((IMyVoxelBase)Entity).PositionLeftBottomCorner;
            }
            else
            {
                var worldMatrix = Entity.WorldMatrix;
                NormalInWorldSpace            = (Vector3)MyUtils.GetTransformNormalNormalized((Vector3D)NormalInObjectSpace, ref worldMatrix);
                IntersectionPointInWorldSpace = Vector3D.Transform((Vector3D)IntersectionPointInObjectSpace, ref worldMatrix);
            }
        }
Esempio n. 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)
            {
                MyTriangle_BoneWeigths?boneWeights = m_model.GetBoneWeights(triangleIndex);
                var result = new MyIntersectionResultLineTriangle(ref triangle, ref boneWeights, ref calculatedTriangleNormal, distance.Value);
                m_result.Add(result);
            }

            return(distance);
        }
Esempio n. 3
0
        public MyIntersectionResultLineTriangleEx(MyIntersectionResultLineTriangle triangle, IMyEntity entity, ref LineD line, Vector3D intersectionPointInWorldSpace, Vector3 normalInWorldSpace)
        {
            Triangle = triangle;
            Entity   = entity;
            InputLineInObjectSpace = line;

            NormalInObjectSpace            = NormalInWorldSpace = normalInWorldSpace;
            IntersectionPointInWorldSpace  = intersectionPointInWorldSpace;
            IntersectionPointInObjectSpace = (Vector3)IntersectionPointInWorldSpace;
        }
 //  Find and return closer intersection of these two. If intersection is null then it's not really an intersection.
 public static MyIntersectionResultLineTriangle? GetCloserIntersection(ref MyIntersectionResultLineTriangle? a, ref MyIntersectionResultLineTriangle? b)
 {
     if (((a == null) && (b != null)) ||
         ((a != null) && (b != null) && (b.Value.Distance < a.Value.Distance)))
     {
         //  If only "b" contains valid intersection, or when it's closer than "a"
         return b;
     }
     else
     {
         //  This will be returned also when ((a == null) && (b == null))
         return a;
     }
 }
Esempio n. 5
0
        public MyIntersectionResultLineTriangleEx(MyIntersectionResultLineTriangle triangle, IMyEntity entity, ref LineD line)
        {
            Triangle = triangle;
            Entity   = entity;
            InputLineInObjectSpace = line;

            NormalInObjectSpace            = MyUtils.GetNormalVectorFromTriangle(ref Triangle.InputTriangle);
            IntersectionPointInObjectSpace = line.From + line.Direction * Triangle.Distance;

            if (Entity is IMyVoxelBase)
            {
                IntersectionPointInWorldSpace = (Vector3D)IntersectionPointInObjectSpace;
                NormalInWorldSpace            = NormalInObjectSpace;

                //  This will move intersection point from world space into voxel map's object space
                IntersectionPointInObjectSpace = IntersectionPointInObjectSpace - ((IMyVoxelBase)Entity).PositionLeftBottomCorner;
            }
            else
            {
                var worldMatrix = Entity.WorldMatrix;
                NormalInWorldSpace            = (Vector3)MyUtils.GetTransformNormalNormalized((Vector3D)NormalInObjectSpace, ref worldMatrix);
                IntersectionPointInWorldSpace = Vector3D.Transform((Vector3D)IntersectionPointInObjectSpace, ref worldMatrix);
            }
        }
        public MyIntersectionResultLineTriangleEx(MyIntersectionResultLineTriangle triangle, IMyEntity entity, ref LineD line)
        {
            Triangle = triangle;
            Entity = entity;
            InputLineInObjectSpace = line;

            NormalInObjectSpace = MyUtils.GetNormalVectorFromTriangle(ref Triangle.InputTriangle);
            IntersectionPointInObjectSpace = line.From + line.Direction * Triangle.Distance;

            if (Entity is IMyVoxelBase)
            {
                IntersectionPointInWorldSpace = (Vector3D)IntersectionPointInObjectSpace;
                NormalInWorldSpace = NormalInObjectSpace;

                //  This will move intersection point from world space into voxel map's object space
                IntersectionPointInObjectSpace = IntersectionPointInObjectSpace - ((IMyVoxelBase)Entity).PositionLeftBottomCorner;
            }
            else
            {
                var worldMatrix = Entity.WorldMatrix;
                NormalInWorldSpace = (Vector3)MyUtils.GetTransformNormalNormalized((Vector3D)NormalInObjectSpace, ref worldMatrix);
                IntersectionPointInWorldSpace = Vector3D.Transform((Vector3D)IntersectionPointInObjectSpace, ref worldMatrix);
            }
        }
Esempio n. 7
0
        //  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;
        }
        public MyIntersectionResultLineTriangleEx(MyIntersectionResultLineTriangle triangle, IMyEntity entity, ref LineD line, Vector3D intersectionPointInWorldSpace, Vector3 normalInWorldSpace)
        {
            Triangle = triangle;
            Entity = entity;
            InputLineInObjectSpace = line;

            NormalInObjectSpace = NormalInWorldSpace = normalInWorldSpace;
            IntersectionPointInWorldSpace = intersectionPointInWorldSpace;
            IntersectionPointInObjectSpace = (Vector3)IntersectionPointInWorldSpace;
        }
        //  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);
        }
        public MyIntersectionResultLineTriangleEx(MyIntersectionResultLineTriangle triangle, IMyEntity entity, ref LineD line)
        {
            Triangle = triangle;
            Entity = entity;
            InputLineInObjectSpace = line;

            NormalInObjectSpace = MyUtils.GetNormalVectorFromTriangle(ref Triangle.InputTriangle);
            // fixme: calculated normal for degenerated triangles was NaN; here should be some better calculation of normal from degenerated triangle
            if (!NormalInObjectSpace.IsValid())
                NormalInObjectSpace = new Vector3(0, 0, 1);
            IntersectionPointInObjectSpace = line.From + line.Direction * Triangle.Distance;

            if (Entity is IMyVoxelBase)
            {
                IntersectionPointInWorldSpace = (Vector3D)IntersectionPointInObjectSpace;
                NormalInWorldSpace = NormalInObjectSpace;

                //  This will move intersection point from world space into voxel map's object space
                IntersectionPointInObjectSpace = IntersectionPointInObjectSpace - ((IMyVoxelBase)Entity).PositionLeftBottomCorner;
            }
            else
            {
                var worldMatrix = Entity.WorldMatrix;
                NormalInWorldSpace = (Vector3)MyUtils.GetTransformNormalNormalized((Vector3D)NormalInObjectSpace, ref worldMatrix);
                IntersectionPointInWorldSpace = Vector3D.Transform((Vector3D)IntersectionPointInObjectSpace, ref worldMatrix);
            }
        }