Beispiel #1
0
        //  Calculates intersection of line with any triangleVertexes in this model instance. Closest intersection and intersected triangleVertexes will be returned.
        internal override bool GetIntersectionWithLine(ref LineD line, out MyIntersectionResultLineTriangleEx? t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES)
        {
            t = null;
            return false;

            //Matrix invWorld = Matrix.Invert(WorldMatrix);
            //Vector3 from = Vector3.Transform(line.From, invWorld);
            //Vector3 to = Vector3.Transform(line.To, invWorld);

            //Line lineLocal = new Line(from, to);

            //bool res = base.GetIntersectionWithLine(ref line, out t, flags);

            //if (res)
            //{
            //    var definition = MyDefinitionManager.Static.GetCubeBlockDefinition(new MyDefinitionId(MyObjectBuilderTypeEnum.Ladder));
            //    if (definition.ExcludedAreaForCamera != null)
            //    {
            //        foreach (var b in definition.ExcludedAreaForCamera)
            //        {
            //            if (b.Contains(t.Value.IntersectionPointInObjectSpace) == ContainmentType.Contains)
            //            {
            //                t = null;
            //                return false;
            //            }
            //        }
            //    }
            //}

            //return res;
        }
        public Sandbox.Common.MyIntersectionResultLineTriangleEx? GetIntersectionWithLine(IMyEntity physObject, ref LineD line, ref MatrixD customInvMatrix, IntersectionFlags flags)
        {
            LineD lineInModelSpace = new LineD(Vector3D.Transform(line.From, ref customInvMatrix), Vector3D.Transform(line.To, ref customInvMatrix));

            MyIntersectionResultLineTriangleEx? ret = m_rootNode.GetIntersectionWithLine(physObject, m_model, ref lineInModelSpace, null, flags);

            return ret;
        }
Beispiel #3
0
        public static double GetShortestDistanceSquared(LineD line1, LineD line2)
        {
            Vector3D res1, res2;
            Vector3D dP = GetShortestVector(ref line1, ref line2, out res1, out res2);

            //return Math.Sqrt(dot(dP, dP));
            return Vector3D.Dot(dP, dP);
        }
        VRageMath.Vector3D?IMyCubeGrid.GetLineIntersectionExactAll(ref VRageMath.LineD line, out double distance, out IMySlimBlock intersectedBlock)
        {
            MySlimBlock block;
            var         retVal = GetLineIntersectionExactAll(ref line, out distance, out block);

            intersectedBlock = block;
            return(retVal);
        }
        //  Calculates intersection of line with any triangleVertexes in this model. Closest intersection and intersected triangleVertexes will be returned.
        //  This method is fast, it uses octree.
        public Sandbox.Common.MyIntersectionResultLineTriangleEx? GetIntersectionWithLine(IMyEntity physObject, ref LineD line, IntersectionFlags flags)
        {
            BoundingSphereD vol = physObject.WorldVolume;
            //  Check if line intersects phys object's current bounding sphere, and if not, return 'no intersection'
            if (MyUtils.IsLineIntersectingBoundingSphere(ref line, ref vol) == false) return null;

            //  Transform line into 'model instance' local/object space. Bounding box of a line is needed!!
            MatrixD worldInv = physObject.GetWorldMatrixNormalizedInv();

            return GetIntersectionWithLine(physObject, ref line, ref worldInv, flags);
        }
Beispiel #6
0
        //  Calculates intersection of line with object.
        public override bool GetIntersectionWithLine(ref VRageMath.LineD line)
        {
            double?t = m_aabb.Intersects(new RayD(line.From, line.Direction));

            if (t.HasValue && t.Value < line.Length && t.Value > 0)
            {
                return(true);
            }

            return(false);
        }
        public unsafe void DoWork(WorkData workData = null)
        {
            try
            {
                //MyEntities.EntityCloseLock.AcquireShared();

                if (m_renderObject == null)
                    return;

                if (m_renderObject is MyRenderVoxelCell)
                {
                }
                              
                Vector3 directionToSunNormalized = -MyRender.Sun.Direction;

                VisibleFromSun = false;

                var line2 = new LineD(m_renderObject.WorldVolume.Center, m_renderObject.WorldVolume.Center + directionToSunNormalized * MyShadowRenderer.SHADOW_MAX_OFFSET * 0.5f);
                var result2 = MyRender.GetAnyIntersectionWithLine(MyRender.ShadowPrunning, ref line2, m_renderObject, null, m_overlapList);
                VisibleFromSun |= (result2 == null); //if nothing hit, its visible from sun

                if (m_renderObject.FastCastShadowResolve)
                    return;

                Vector3D* corners = stackalloc Vector3D[8];
                m_renderObject.GetCorners(corners);

                for (int i = 0; i < 8; i++)
                {
                    LineD line = new LineD(corners[i], corners[i] + directionToSunNormalized * MyShadowRenderer.SHADOW_MAX_OFFSET * 0.5f);
                    var result = MyRender.GetAnyIntersectionWithLine(MyRender.ShadowPrunning, ref line, m_renderObject, null, m_overlapList);

                    VisibleFromSun |= (result == null);

                    if (VisibleFromSun)
                        break;
                }

                if (!VisibleFromSun)
                {
                }
            }
            finally
            {      /*
                if (m_renderObject != null)
                {
                    m_renderObject.OnClose -= m_entity_OnMarkForClose;
                }
                 */
               // MyEntities.EntityCloseLock.ReleaseShared();
            }
        }
        public double?Intersects(ref LineD line)
        {
            if (this.Contains(ref line.From))
            {
                RayD   yd       = new RayD(line.To, -line.Direction);
                double?nullable = this.Intersects(ref yd);
                if (!nullable.HasValue)
                {
                    return(null);
                }
                double num = line.Length - nullable.Value;
                if (num < 0.0)
                {
                    return(null);
                }
                if (num > line.Length)
                {
                    return(null);
                }
                return(new double?(num));
            }
            RayD   ray       = new RayD(line.From, line.Direction);
            double?nullable2 = this.Intersects(ref ray);

            if (!nullable2.HasValue)
            {
                return(null);
            }
            if (nullable2.Value < 0.0)
            {
                return(null);
            }
            if (nullable2.Value > line.Length)
            {
                return(null);
            }
            return(new double?(nullable2.Value));
        }
        public bool Intersects(LineD line, out double distance)
        {
            distance = 0f;
            double?f = Intersects(new RayD(line.From, line.Direction));

            if (!f.HasValue)
            {
                return(false);
            }

            if (f.Value < 0)
            {
                return(false);
            }

            if (f.Value > line.Length)
            {
                return(false);
            }

            distance = f.Value;
            return(true);
        }
        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);
            }
        }
        private void Hammer()
        {
            var IntersectionStart = MySector.MainCamera.Position;
            var IntersectionDirection = MySector.MainCamera.ForwardVector;
            LineD line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * 200);

            var m_tmpHitList = new List<MyPhysics.HitInfo>();
            MyPhysics.CastRay(line.From, line.To, m_tmpHitList, MyPhysics.ObjectDetectionCollisionLayer);
            // Remove character hits.
            m_tmpHitList.RemoveAll(delegate(MyPhysics.HitInfo hit)
            {
                return (hit.HkHitInfo.Body.GetEntity() == MySession.ControlledEntity.Entity);
            });

            if (m_tmpHitList.Count == 0)
                return;

            MyEntity closestEntity = null;
            MyPhysics.HitInfo closestHit = default(MyPhysics.HitInfo);

            foreach (var hit in m_tmpHitList)
            {
                if (hit.HkHitInfo.Body != null)
                {
                    closestEntity = hit.HkHitInfo.Body.GetEntity() as MyEntity;
                    closestHit = hit;
                    break;
                }
            }
            if (closestEntity == null)
                return;
            HkdFractureImpactDetails details = HkdFractureImpactDetails.Create();
            details.SetBreakingBody(closestEntity.Physics.RigidBody);
            details.SetContactPoint(closestEntity.Physics.WorldToCluster(closestHit.Position));
            details.SetDestructionRadius(RADIUS);
            details.SetBreakingImpulse(Sandbox.MyDestructionConstants.STRENGTH * 10);
            if(HammerForce)
                details.SetParticleVelocity(-line.Direction * 20);
            details.SetParticlePosition(closestEntity.Physics.WorldToCluster(closestHit.Position));
            details.SetParticleMass(1000000);
            //details.ZeroColidingParticleVelocity();
            details.Flag = details.Flag | HkdFractureImpactDetails.Flags.FLAG_DONT_RECURSE;
            if (closestEntity.Physics.HavokWorld.DestructionWorld != null)
            {
                MyPhysics.FractureImpactDetails destruction = new MyPhysics.FractureImpactDetails();
                destruction.Details = details;
                destruction.World = closestEntity.Physics.HavokWorld;
                destruction.Entity = closestEntity;
                MyPhysics.EnqueueDestruction(destruction);
                //closestGrid.Physics.HavokWorld.DestructionWorld.TriggerDestruction(ref details);
            }
            //details.RemoveReference();
        }
 public override bool GetIntersectionWithLine(ref LineD worldLine, out Vector3D? v, bool useCollisionModel = true, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES)
 {
     MyIntersectionResultLineTriangleEx? result;
     GetIntersectionWithLine(ref worldLine, out result);
     v = null;
     if (result != null)
     {
         v = result.Value.IntersectionPointInWorldSpace;
         return true;
     }
     return false;
 }
 public void Include(ref LineD line)
 {
     Include(ref line.From);
     Include(ref line.To);
 }
        public void PrefetchShapeOnRay(ref LineD ray)
        {
            int lod = 1;
            Vector3D localStart;
            MyVoxelCoordSystems.WorldPositionToLocalPosition(m_voxelMap.PositionLeftBottomCorner, ref ray.From, out localStart);
            
            Vector3D localEnd;
            MyVoxelCoordSystems.WorldPositionToLocalPosition(m_voxelMap.PositionLeftBottomCorner, ref ray.To, out localEnd);

            var shape = GetShape(lod);
            Debug.Assert(shape.Base.IsValid);

            if (m_cellsToGenerateBuffer.Length < 64)
            {
                m_cellsToGenerateBuffer = new Vector3I[64];
            }

            int requiredCellsCount = shape.GetHitCellsInRange(localStart, localEnd, m_cellsToGenerateBuffer);
      
            if (requiredCellsCount == 0)
            {
                return;
            }

            ProfilerShort.Begin("Start Jobs");
            for (int i = 0; i < requiredCellsCount; ++i)
            {
                if (m_workTracker.Exists(new MyCellCoord(lod, m_cellsToGenerateBuffer[i])))
                    continue;

                MyPrecalcJobPhysicsPrefetch.Start(new MyPrecalcJobPhysicsPrefetch.Args
                {
                    TargetPhysics = this,
                    Tracker = m_workTracker,
                    GeometryCell = new MyCellCoord(lod, m_cellsToGenerateBuffer[i]),
                    Storage = m_voxelMap.Storage
                });
            }
            ProfilerShort.End();

        }
 public void OverlapAllLineSegment <T>(ref LineD line, List <MyLineSegmentOverlapResult <T> > elementsList)
 {
     OverlapAllLineSegment <T>(ref line, elementsList, 0);
 }
        /// <summary>
        /// Obtain entity that player is aiming/looking at.
        /// </summary>
        public static MyEntity GetTargetEntity()
        {
            var line = new LineD(MySector.MainCamera.Position, MySector.MainCamera.Position + MySector.MainCamera.ForwardVector * 10000);

            m_tmpHitList.Clear();
            MyPhysics.CastRay(line.From, line.To, m_tmpHitList, MyPhysics.CollisionLayers.DefaultCollisionLayer);
            // Remove character hits.
            m_tmpHitList.RemoveAll(delegate(MyPhysics.HitInfo hit)
            {
                return (hit.HkHitInfo.GetHitEntity() == MySession.Static.ControlledEntity.Entity);
            });

            if (m_tmpHitList.Count == 0)
                return null;

            return m_tmpHitList[0].HkHitInfo.GetHitEntity() as MyEntity;
        }
Beispiel #17
0
        //  Calculates intersection of line with any triangleVertexes in this model instance. All intersections and intersected triangleVertexes will be returned.
        internal virtual bool GetIntersectionsWithLine(ref LineD line, List<MyIntersectionResultLineTriangleEx> result, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES)
        {
            MyModel collisionModel = Model;

            if (collisionModel != null)
            {
                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyEntity.GetIntersectionWithLine on model");
                collisionModel.GetTrianglePruningStructure().GetTrianglesIntersectingLine(this, ref line, flags, result);
                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
            }

            return result.Count > 0;
        }
        /// <summary>
        /// Finds closest object (grid or voxel map) for placement of blocks .
        /// </summary>
        public bool FindClosestPlacementObject(out MyCubeGrid closestGrid, out MyVoxelMap closestVoxelMap)
        {
            closestGrid = null;
            closestVoxelMap = null;

            if (MySession.ControlledEntity == null) return false;

            m_hitInfo = null;

            LineD line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * IntersectionDistance);

            MyPhysics.CastRay(line.From, line.To, m_tmpHitList, MyPhysics.ObjectDetectionCollisionLayer);
            // Remove character hits.

            m_tmpHitList.RemoveAll(delegate(MyPhysics.HitInfo hitInfo)
            {
                return (hitInfo.HkHitInfo.GetHitEntity() == MySession.ControlledEntity.Entity);
            });

            if (m_tmpHitList.Count == 0)
                return false;

            var hit = m_tmpHitList[0];
            closestGrid = hit.HkHitInfo.GetHitEntity() as MyCubeGrid;
            if (closestGrid != null)
            {
                m_hitInfo = hit;
            }

            if (MyFakes.ENABLE_BLOCK_PLACEMENT_ON_VOXEL)
            {
                closestVoxelMap = hit.HkHitInfo.GetHitEntity() as MyVoxelMap;
                if (closestVoxelMap != null)
                    m_hitInfo = hit;
            }

            return closestGrid != null || closestVoxelMap != null;
        }
        public void UpdatePlacement()
        {
            m_lastUpdate = MySession.Static.GameplayFrameCounter;
            m_hitInfo = null;
            m_closestGrid = null;
            m_closestVoxelMap = null;
            LineD line = new LineD(RayStart, RayStart + RayDirection * IntersectionDistance);

            MyPhysics.CastRay(line.From, line.To, m_tmpHitList,
                MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer);
            // Remove character hits.

            m_tmpHitList.RemoveAll(delegate(MyPhysics.HitInfo hitInfo)
            {
                return (hitInfo.HkHitInfo.GetHitEntity() == MySession.Static.ControlledEntity.Entity);
            });

            if (m_tmpHitList.Count == 0)
                return;

            var hit = m_tmpHitList[0];
            m_closestGrid = hit.HkHitInfo.GetHitEntity() as MyCubeGrid;
            if (m_closestGrid != null)
            {
                //always assign otherwise the block will be completely inside/behind the grid
                m_hitInfo = hit; 
                if (!ClosestGrid.Editable)
                    m_closestGrid = null;
                return;

            }

            //if (MyFakes.ENABLE_BLOCK_PLACEMENT_ON_VOXEL) // TODO: check this MyFake to remove or what?
            //{
            m_closestVoxelMap = hit.HkHitInfo.GetHitEntity() as MyVoxelBase;
            if (m_closestVoxelMap != null)
                m_hitInfo = hit;
            //}
        }
Beispiel #20
0
        public static Vector3D GetShortestVector(ref LineD line1, ref LineD line2, out Vector3D res1, out Vector3D res2)
        {
            double EPS = 0.000001f;

            Vector3D delta21 = new Vector3D();

            delta21.X = line1.To.X - line1.From.X;
            delta21.Y = line1.To.Y - line1.From.Y;
            delta21.Z = line1.To.Z - line1.From.Z;

            Vector3D delta41 = new Vector3D();

            delta41.X = line2.To.X - line2.From.X;
            delta41.Y = line2.To.Y - line2.From.Y;
            delta41.Z = line2.To.Z - line2.From.Z;

            Vector3D delta13 = new Vector3D();

            delta13.X = line1.From.X - line2.From.X;
            delta13.Y = line1.From.Y - line2.From.Y;
            delta13.Z = line1.From.Z - line2.From.Z;

            double a = Vector3D.Dot(delta21, delta21);
            double b = Vector3D.Dot(delta21, delta41);
            double c = Vector3D.Dot(delta41, delta41);
            double d = Vector3D.Dot(delta21, delta13);
            double e = Vector3D.Dot(delta41, delta13);
            double D = a * c - b * b;

            double sc, sN, sD = D;
            double tc, tN, tD = D;

            if (D < EPS)
            {
                sN = 0.0f;
                sD = 1.0f;
                tN = e;
                tD = c;
            }
            else
            {
                sN = (b * e - c * d);
                tN = (a * e - b * d);
                if (sN < 0.0)
                {
                    sN = 0.0f;
                    tN = e;
                    tD = c;
                }
                else if (sN > sD)
                {
                    sN = sD;
                    tN = e + b;
                    tD = c;
                }
            }

            if (tN < 0.0)
            {
                tN = 0.0f;

                if (-d < 0.0f)
                {
                    sN = 0.0f;
                }
                else if (-d > a)
                {
                    sN = sD;
                }
                else
                {
                    sN = -d;
                    sD = a;
                }
            }
            else if (tN > tD)
            {
                tN = tD;
                if ((-d + b) < 0.0)
                {
                    sN = 0;
                }
                else if ((-d + b) > a)
                {
                    sN = sD;
                }
                else
                {
                    sN = (-d + b);
                    sD = a;
                }
            }

            if (Math.Abs(sN) < EPS)
            {
                sc = 0.0f;
            }
            else
            {
                sc = sN / sD;
            }
            if (Math.Abs(tN) < EPS)
            {
                tc = 0.0f;
            }
            else
            {
                tc = tN / tD;
            }

            res1.X = (sc * delta21.X);
            res1.Y = (sc * delta21.Y);
            res1.Z = (sc * delta21.Z);

            Vector3D dP = new Vector3D();

            dP.X = delta13.X - (tc * delta41.X) + res1.X;
            dP.Y = delta13.Y - (tc * delta41.Y) + res1.Y;
            dP.Z = delta13.Z - (tc * delta41.Z) + res1.Z;

            res2 = res1 - dP;

            return(dP);
        }
Beispiel #21
0
        public static Vector3D GetShortestVector(ref LineD line1, ref LineD line2, out Vector3D res1, out Vector3D res2)
        {
            double   num8;
            double   num9;
            double   num11;
            double   num12;
            double   num     = 9.9999999747524271E-07;
            Vector3D vectord = new Vector3D {
                X = line1.To.X - line1.From.X,
                Y = line1.To.Y - line1.From.Y,
                Z = line1.To.Z - line1.From.Z
            };
            Vector3D vectord2 = new Vector3D {
                X = line2.To.X - line2.From.X,
                Y = line2.To.Y - line2.From.Y,
                Z = line2.To.Z - line2.From.Z
            };
            Vector3D vectord3 = new Vector3D {
                X = line1.From.X - line2.From.X,
                Y = line1.From.Y - line2.From.Y,
                Z = line1.From.Z - line2.From.Z
            };
            double num2  = Vector3D.Dot(vectord, vectord);
            double num3  = Vector3D.Dot(vectord, vectord2);
            double num4  = Vector3D.Dot(vectord2, vectord2);
            double num5  = Vector3D.Dot(vectord, vectord3);
            double num6  = Vector3D.Dot(vectord2, vectord3);
            double num7  = (num2 * num4) - (num3 * num3);
            double num10 = num7;
            double num13 = num7;

            if (num7 < num)
            {
                num9  = 0.0;
                num10 = 1.0;
                num12 = num6;
                num13 = num4;
            }
            else
            {
                num9  = (num3 * num6) - (num4 * num5);
                num12 = (num2 * num6) - (num3 * num5);
                if (num9 < 0.0)
                {
                    num9  = 0.0;
                    num12 = num6;
                    num13 = num4;
                }
                else if (num9 > num10)
                {
                    num9  = num10;
                    num12 = num6 + num3;
                    num13 = num4;
                }
            }
            if (num12 < 0.0)
            {
                num12 = 0.0;
                if (-num5 < 0.0)
                {
                    num9 = 0.0;
                }
                else if (-num5 > num2)
                {
                    num9 = num10;
                }
                else
                {
                    num9  = -num5;
                    num10 = num2;
                }
            }
            else if (num12 > num13)
            {
                num12 = num13;
                if ((-num5 + num3) < 0.0)
                {
                    num9 = 0.0;
                }
                else if ((-num5 + num3) > num2)
                {
                    num9 = num10;
                }
                else
                {
                    num9  = -num5 + num3;
                    num10 = num2;
                }
            }
            if (Math.Abs(num9) < num)
            {
                num8 = 0.0;
            }
            else
            {
                num8 = num9 / num10;
            }
            if (Math.Abs(num12) < num)
            {
                num11 = 0.0;
            }
            else
            {
                num11 = num12 / num13;
            }
            res1.X = num8 * vectord.X;
            res1.Y = num8 * vectord.Y;
            res1.Z = num8 * vectord.Z;
            Vector3D vectord4 = new Vector3D {
                X = (vectord3.X - (num11 * vectord2.X)) + res1.X,
                Y = (vectord3.Y - (num11 * vectord2.Y)) + res1.Y,
                Z = (vectord3.Z - (num11 * vectord2.Z)) + res1.Z
            };

            res2 = res1 - vectord4;
            return(vectord4);
        }
        public bool Intersect(ref LineD line, out double t1, out double t2)
        {
            RayD ray = new RayD(line.From, line.Direction);

            return(this.Intersect(ref ray, out t1, out t2));
        }
Beispiel #23
0
        //  Calculates intersection of line with object.
        public virtual bool GetIntersectionWithLine(ref LineD line, out Vector3D? v, bool useCollisionModel = true, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES)
        {
            v = null;
            MyModel collisionModel = Model;
            if (useCollisionModel)
                collisionModel = ModelCollision;

            if (collisionModel != null)
            {
                VRage.Game.Models.MyIntersectionResultLineTriangleEx? result = collisionModel.GetTrianglePruningStructure().GetIntersectionWithLine(this, ref line, flags);
                if (result != null)
                {
                    v = result.Value.IntersectionPointInWorldSpace;
                    return true;
                }
            }
            else
                Debug.Assert(false);//this should be overriden by child class if object has no model by default
            return false;
        }
Beispiel #24
0
        //  Calculates intersection of line with any triangleVertexes in this model instance. Closest intersection and intersected triangleVertexes will be returned.
        public virtual bool GetIntersectionWithLine(ref LineD line, out VRage.Game.Models.MyIntersectionResultLineTriangleEx? t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES)
        {
            bool ret = false;

            t = null;
            MyModel collisionModel = Model;

            if (collisionModel != null)
            {
                VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyEntity.GetIntersectionWithLine on model");
                VRage.Game.Models.MyIntersectionResultLineTriangleEx? result = collisionModel.GetTrianglePruningStructure().GetIntersectionWithLine(this, ref line, flags);
                VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
                if (result != null)
                {
                    t = result.Value;
                    ret = true;
                }
            }

            return ret;

        }
        /// <summary>
        /// Calculates exact intersection point (in uniform grid coordinates) of eye ray with the given grid of all cubes.
        /// Returns position of intersected object in uniform grid coordinates
        /// </summary>
        protected Vector3D? IntersectExact(MyCubeGrid grid, ref MatrixD inverseGridWorldMatrix, out Vector3D intersection, out MySlimBlock intersectedBlock)
        {
            intersection = Vector3D.Zero;

            var line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * IntersectionDistance);
            double distance;
            Vector3D? intersectedObjectPos = grid.GetLineIntersectionExactAll(ref line, out distance, out intersectedBlock);
            if (intersectedObjectPos != null)
            {
                Vector3D rayStart = Vector3D.Transform(IntersectionStart, inverseGridWorldMatrix);
                Vector3D rayDir = Vector3D.Normalize(Vector3D.TransformNormal(IntersectionDirection, inverseGridWorldMatrix));
                intersection = rayStart + distance * rayDir;
                intersection *= 1.0f / grid.GridSize;
            }

            return intersectedObjectPos;
        }
Beispiel #26
0
        //  Calculates intersection of line with any bounding sphere in this model instance. Center of the bounding sphere will be returned.
        //  It takes boundingSphereRadiusMultiplier argument which serves for extending the influence (radius) for interaction with line.
        public virtual Vector3D? GetIntersectionWithLineAndBoundingSphere(ref LineD line, float boundingSphereRadiusMultiplier)
        {
            if (Render.GetModel() == null)
                return null;

            BoundingSphereD vol = PositionComp.WorldVolume;
            vol.Radius *= boundingSphereRadiusMultiplier;

            //  Check if line intersects phys object's current bounding sphere, and if not, return 'no intersection'
            if (!MyUtils.IsLineIntersectingBoundingSphere(ref line, ref vol))
                return null;

            return vol.Center;
        }
Beispiel #27
0
        public LineD GetDamageCapsuleLine(FlameInfo info)
        {
            var world = Matrix.CreateFromDir(Vector3.TransformNormal(info.Direction, WorldMatrix));

            var halfLenght = ThrustLengthRand * info.Radius / 2;
            halfLenght *= BlockDefinition.FlameDamageLengthScale;
            var position = Vector3D.Transform(info.Position, WorldMatrix);

            if (halfLenght > info.Radius)
                return new LineD(position - world.Forward * (info.Radius), position + world.Forward * (2 * halfLenght - info.Radius));
            else
            {
                var l = new LineD(position + world.Forward * halfLenght, position + world.Forward * halfLenght);
                l.Direction = world.Forward;
                return l;
            }
        }
        public static bool TryRayCastGrid(ref LineD worldRay, out MyCubeGrid hitGrid, out Vector3D worldHitPos)
        {
            try
            {
                MyPhysics.CastRay(worldRay.From, worldRay.To, m_tmpHitList);
                foreach (var hit in m_tmpHitList)
                {
                    var cubeGrid = hit.HkHitInfo.GetHitEntity() as MyCubeGrid;
                    if (cubeGrid == null)
                        continue;

                    worldHitPos = hit.Position;
                    VRageRender.MyRenderProxy.DebugDrawAABB(new BoundingBoxD(worldHitPos - 0.01, worldHitPos + 0.01), Color.Wheat.ToVector3(), 1f, 1f, true);
                    hitGrid = cubeGrid;
                    return true;
                }

                hitGrid = default(MyCubeGrid);
                worldHitPos = default(Vector3D);
                return false;
            }
            finally
            {
                m_tmpHitList.Clear();
            }
        }
 public void Include(ref LineD line)
 {
     this.Include(ref line.From);
     this.Include(ref line.To);
 }
        public MyCubeGrid FindClosestGrid()
        {
            LineD line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * IntersectionDistance);

            m_tmpHitList.Clear();
            MyPhysics.CastRay(line.From, line.To, m_tmpHitList, MyPhysics.ObjectDetectionCollisionLayer);
            // Remove character hits.
            m_tmpHitList.RemoveAll(delegate(MyPhysics.HitInfo hit)
            {
                return (hit.HkHitInfo.GetHitEntity() == MySession.ControlledEntity.Entity);
            });

            if (m_tmpHitList.Count == 0)
                return null;

            MyCubeGrid closestGrid = m_tmpHitList[0].HkHitInfo.GetHitEntity() as MyCubeGrid;
            return closestGrid;
        }
        Vector3D GetAimedPointFromHead()
        {
            MatrixD headMatrix = GetHeadMatrix(false);
            var endPoint = headMatrix.Translation + headMatrix.Forward * 25000;
            // Same optimization as the one in GetAimedPointFromCamera.
            return endPoint;

            if (MySession.Static.ControlledEntity == this)
            {
                LineD line = new LineD(headMatrix.Translation, endPoint);
                //Line line = new Line(MySector.MainCamera.Position, MySector.MainCamera.Position + MySector.MainCamera.ForwardVector * 1000);
                var intersection = MyEntities.GetIntersectionWithLine(ref line, this, (MyEntity)m_currentWeapon);

                if (intersection.HasValue)
                {
                    return intersection.Value.IntersectionPointInWorldSpace;
                }
                else
                {
                    return (Vector3D)line.To;
                }
            }
            else
            {
                return endPoint;
            }
        }
        protected Vector3I? IntersectCubes(MyCubeGrid grid, out double distance)
        {
            distance = float.MaxValue;

            var line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * IntersectionDistance);
            Vector3I position = Vector3I.Zero;
            double dstSqr = double.MaxValue;

            if (grid.GetLineIntersectionExactGrid(ref line, ref position, ref dstSqr))
            {
                distance = Math.Sqrt(dstSqr);
                return position;
            }
            return null;
        }
 public override bool GetIntersectionWithLine(ref LineD line, out VRage.Game.Models.MyIntersectionResultLineTriangleEx? tri, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES)
 {
     bool ret = GetIntersectionWithLine(ref line, ref m_hitInfoTmp, flags);
     tri = m_hitInfoTmp.Triangle;
     return ret;
 }
        /// <summary>
        /// Calculates exact intersection point (in uniform grid coordinates) from stored havok's hit info object obtained during FindClosest grid.
        /// Returns position of intersected object in uniform grid coordinates.
        /// </summary>
        protected Vector3D? GetIntersectedBlockData(ref MatrixD inverseGridWorldMatrix, out Vector3D intersection, out MySlimBlock intersectedBlock, out ushort? compoundBlockId)
        {
            Debug.Assert(m_hitInfo != null);
            //Debug.Assert(m_hitInfo.Value.HkHitInfo.GetEntity() == CurrentGrid);

            intersection = Vector3D.Zero;
            intersectedBlock = null;
            compoundBlockId = null;

            double distance = double.MaxValue;
            Vector3D? intersectedObjectPos = null;

            var line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * IntersectionDistance);
            Vector3I position = Vector3I.Zero;
            if (!CurrentGrid.GetLineIntersectionExactGrid(ref line, ref position, ref distance, m_hitInfo.Value))
                return null;

            distance = Math.Sqrt(distance);
            intersectedObjectPos = position;

            intersectedBlock = CurrentGrid.GetCubeBlock(position);
            if (intersectedBlock == null)
                return null;

            // Compound block - get index of internal block for removing
            if (intersectedBlock.FatBlock is MyCompoundCubeBlock)
            {
                MyCompoundCubeBlock compoundBlock = intersectedBlock.FatBlock as MyCompoundCubeBlock;
                ushort? idInCompound = null;

                ushort blockId;
                MyIntersectionResultLineTriangleEx? triIntersection;

                if (compoundBlock.GetIntersectionWithLine(ref line, out triIntersection, out blockId))
                    idInCompound = blockId;
                else if (compoundBlock.GetBlocksCount() == 1) // If not intersecting with any internal block and there is only one then set the index to it
                    idInCompound = compoundBlock.GetBlockId(compoundBlock.GetBlocks()[0]);

                compoundBlockId = idInCompound;
            }

            Debug.Assert(intersectedObjectPos != null);
            Vector3D rayStart = Vector3D.Transform(IntersectionStart, inverseGridWorldMatrix);
            Vector3D rayDir = Vector3D.Normalize(Vector3D.TransformNormal(IntersectionDirection, inverseGridWorldMatrix));
            intersection = rayStart + distance * rayDir;
            intersection *= 1.0f / CurrentGrid.GridSize;

            return intersectedObjectPos;
        }
        /// <summary>
        /// Returns closest hit from line start position.
        /// </summary>
        public bool GetIntersectionWithLine(ref LineD line, ref MyCharacterHitInfo info, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES)
        {
            // TODO: This now uses caspule of physics rigid body on the character, it needs to be changed to ragdoll
            //       Currently this approach will be used to support Characters with different skeleton than humanoid
            if (info == null)
                info = new MyCharacterHitInfo();

            info.Reset();

            bool capsulesReady = UpdateCapsuleBones();
            if (!capsulesReady)
                return false;

            double closestDistanceToHit = double.MaxValue;

            Vector3D hitPosition = Vector3D.Zero;
            Vector3D hitPosition2 = Vector3D.Zero;
            Vector3 hitNormal = Vector3.Zero;
            Vector3 hitNormal2 = Vector3.Zero;

            int capsuleIndex = -1;
            for (int i = 0; i < m_bodyCapsules.Length; i++)
            {
                CapsuleD capsule = m_bodyCapsules[i];
                if (capsule.Intersect(line, ref hitPosition, ref hitPosition2, ref hitNormal, ref hitNormal2))
                {
                    double distanceToHit = Vector3.Distance(hitPosition, line.From);
                    if (distanceToHit >= closestDistanceToHit)
                        continue;

                    closestDistanceToHit = distanceToHit;
                    capsuleIndex = i;
                }
            }

            if (capsuleIndex != -1)
            {
                Matrix worldMatrix = PositionComp.WorldMatrix;
                int boneIndex = FindBestBone(capsuleIndex, ref hitPosition, ref worldMatrix);

                // Transform line to model static position and compute accurate collision there
                // 1. Transform line in local coordinates (used later)
                Matrix worldMatrixInv = PositionComp.WorldMatrixNormalizedInv;
                Vector3 fromTrans = Vector3.Transform(line.From, ref worldMatrixInv);
                Vector3 toTrans = Vector3.Transform(line.To, ref worldMatrixInv);
                LineD lineLocal = new LineD(fromTrans, toTrans);

                // 2. Transform line to to bone pose in binding position
                var bone = AnimationController.CharacterBones[boneIndex];
                bone.ComputeAbsoluteTransform();
                Matrix boneAbsTrans = bone.AbsoluteTransform;
                Matrix skinTransform = bone.SkinTransform;
                Matrix boneTrans = skinTransform * boneAbsTrans;
                Matrix invBoneTrans = Matrix.Invert(boneTrans);
                fromTrans = Vector3.Transform(fromTrans, ref invBoneTrans);
                toTrans = Vector3.Transform(toTrans, ref invBoneTrans);

                // 3. Move back line to world coordinates
                LineD lineTransWorld = new LineD(Vector3.Transform(fromTrans, ref worldMatrix), Vector3.Transform(toTrans, ref worldMatrix));
                MyIntersectionResultLineTriangleEx? triangle_;
                bool success = base.GetIntersectionWithLine(ref lineTransWorld, out triangle_, flags);
                if (success)
                {
                    MyIntersectionResultLineTriangleEx triangle = triangle_.Value;

                    info.CapsuleIndex = capsuleIndex;
                    info.BoneIndex = boneIndex;
                    info.Capsule = m_bodyCapsules[info.CapsuleIndex];
                    info.HitHead = info.CapsuleIndex == 0 && m_bodyCapsules.Length > 1;
                    info.HitPositionBindingPose = triangle.IntersectionPointInObjectSpace;
                    info.HitNormalBindingPose = triangle.NormalInObjectSpace;

                    // 4. Move intersection from binding to dynamic pose
                    MyTriangle_Vertexes vertices = new MyTriangle_Vertexes();
                    vertices.Vertex0 = Vector3.Transform(triangle.Triangle.InputTriangle.Vertex0, ref boneTrans);
                    vertices.Vertex1 = Vector3.Transform(triangle.Triangle.InputTriangle.Vertex1, ref boneTrans);
                    vertices.Vertex2 = Vector3.Transform(triangle.Triangle.InputTriangle.Vertex2, ref boneTrans);
                    Vector3 triangleNormal = Vector3.TransformNormal(triangle.Triangle.InputTriangleNormal, boneTrans);
                    MyIntersectionResultLineTriangle triraw = new MyIntersectionResultLineTriangle(ref vertices, ref triangleNormal, triangle.Triangle.Distance);

                    Vector3 intersectionLocal = Vector3.Transform(triangle.IntersectionPointInObjectSpace, ref boneTrans);
                    Vector3 normalLocal = Vector3.TransformNormal(triangle.NormalInObjectSpace, boneTrans);

                    // 5. Store results
                    triangle = new MyIntersectionResultLineTriangleEx();
                    triangle.Triangle = triraw;
                    triangle.IntersectionPointInObjectSpace = intersectionLocal;
                    triangle.NormalInObjectSpace = normalLocal;
                    triangle.IntersectionPointInWorldSpace = Vector3.Transform(intersectionLocal, ref worldMatrix);
                    triangle.NormalInWorldSpace = Vector3.TransformNormal(normalLocal, worldMatrix);
                    triangle.InputLineInObjectSpace = lineLocal;

                    info.Triangle = triangle;

                    if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW)
                    {
                        MyRenderProxy.DebugClearPersistentMessages();
                        MyRenderProxy.DebugDrawCapsule(info.Capsule.P0, info.Capsule.P1, info.Capsule.Radius, Color.Aqua, false, persistent: true);

                        Vector3 p0Local = Vector3.Transform(info.Capsule.P0, ref worldMatrixInv);
                        Vector3 p1Local = Vector3.Transform(info.Capsule.P1, ref worldMatrixInv);
                        Vector3 p0LocalTrans = Vector3.Transform(p0Local, ref invBoneTrans);
                        Vector3 p1LocalTrans = Vector3.Transform(p1Local, ref invBoneTrans);
                        MyRenderProxy.DebugDrawCapsule(Vector3.Transform(p0LocalTrans, ref worldMatrix), Vector3.Transform(p1LocalTrans, ref worldMatrix), info.Capsule.Radius, Color.Brown, false, persistent: true);

                        MyRenderProxy.DebugDrawLine3D(line.From, line.To, Color.Blue, Color.Red, false, true);
                        MyRenderProxy.DebugDrawLine3D(lineTransWorld.From, lineTransWorld.To, Color.Green, Color.Yellow, false, true);
                        MyRenderProxy.DebugDrawSphere(triangle.IntersectionPointInWorldSpace, 0.02f, Color.Red, 1, false, persistent: true);
                        MyRenderProxy.DebugDrawAxis((MatrixD)boneTrans * WorldMatrix, 0.1f, false, true, true);
                    }

                    return true;
                }
            }

            return false;
        }
Beispiel #36
0
        private void DamageGrid(FlameInfo flameInfo, LineD l, MyCubeGrid grid)
        {
            HkSphereShape sph = new HkSphereShape(flameInfo.Radius * BlockDefinition.FlameDamageLengthScale);
            var transform = MatrixD.CreateWorld(l.From, Vector3.Forward, Vector3.Up);
            var hit = MyPhysics.CastShapeReturnPoint(l.To, sph, ref transform, (int)MyPhysics.DefaultCollisionLayer, 0.05f);

            sph.Base.RemoveReference();

            if (hit.HasValue)
            {
                //MyRenderProxy.DebugDrawSphere(hit.Value, 0.1f, Color.Green.ToVector3(), 1, true);
                MyPhysics.CastRay(hit.Value - l.Direction * 0.1f, hit.Value + l.Direction * 0.1f, m_gridRayCastLst, MyPhysics.ObjectDetectionCollisionLayer);
                if ((m_gridRayCastLst.Count == 0 || m_gridRayCastLst[0].HkHitInfo.GetHitEntity() != grid) && grid == CubeGrid)
                {
                    m_gridRayCastLst.Clear();
                    return;
                }
                m_gridRayCastLst.Clear();
                var block = grid.GetCubeBlock(grid.WorldToGridInteger(hit.Value));
                //if (block != this.SlimBlock)
                {
                    //MyRenderProxy.DebugDrawSphere(hit.Value, 0.1f, Color.Green.ToVector3(), 1, true);
                    var invWorld = grid.PositionComp.GetWorldMatrixNormalizedInv();
                    var gridPos = Vector3D.Transform(hit.Value, invWorld);
                    var gridDir = Vector3D.TransformNormal(l.Direction, invWorld);
                    if (block != null)
                        if (block.FatBlock != this && (CubeGrid.GridSizeEnum == MyCubeSize.Large || block.BlockDefinition.DeformationRatio > 0.25))
                        {
                            block.DoDamage(30 * BlockDefinition.FlameDamage, MyDamageType.Environment, attackerId: EntityId);
                        }
                    var areaPlanar = 0.5f * flameInfo.Radius * CubeGrid.GridSize;
                    var areaVertical = 0.5f * CubeGrid.GridSize;

                    grid.Physics.ApplyDeformation(BlockDefinition.FlameDamage, areaPlanar, areaVertical, gridPos, gridDir, MyDamageType.Environment, CubeGrid.GridSizeEnum == MyCubeSize.Small ? 0.1f : 0, attackerId: EntityId);
                }
            }
        }
Beispiel #37
0
        private void TestPath()
        {
            using (m_lock.AcquireExclusiveUsing())
            {
                if (m_grid.MarkedForClose)
                {
                    CurrentState = State.BlockedPath;
                    m_cells.Clear();
                    return;
                }

                if (CurrentState == State.None)
                {
                    m_cells.Clear();
                    return;
                }

                //MyGameTimer timer = new MyGameTimer();
                if (m_cells.Count != 0)
                {
                    Vector3D worldPos = m_grid.GridIntegerToWorld(m_cells.Dequeue());
                    LineD worldLine = new LineD(worldPos, worldPos + m_displacement);
                    //var createLine = timer.Elapsed;
                    //timer = new MyGameTimer();

                    Vector3D? contact;
                    if (RayCast.RayCastVoxel(ClosestPlanet, worldLine, out contact))
                    {
                        //var intersect = timer.Elapsed;
                        m_logger.debugLog("Intersected line: " + worldLine.From + " to " + worldLine.To + ", at " + contact, Logger.severity.DEBUG);
                        //m_logger.debugLog("Intersected line: " + worldLine.From + " to " + worldLine.To + ", at " + contact + ", createLine: " + createLine.ToPrettySeconds() + ", intersect: " + intersect.ToPrettySeconds(), "TestPath()", Logger.severity.DEBUG);
                        ObstructionPoint = contact.Value;
                        CurrentState = State.BlockedPath;
                        m_cells.Clear();
                        return;
                    }
                    //else
                    //{
                    //	var intersect = timer.Elapsed;
                    //	m_logger.debugLog("no intersection with line: " + worldLine.From + " to " + worldLine.To + ", createLine: " + createLine.ToPrettySeconds() + ", intersect: " + intersect.ToPrettySeconds(), "TestPath()", Logger.severity.TRACE);
                    //}

                    DoTests.Enqueue(TestPath);
                }
                else
                {
                    m_logger.debugLog("finished, clear", Logger.severity.DEBUG);
                    CurrentState = State.Clear;
                }
            }
        }
        public override void UpdateBeforeSimulation10()
        {
            base.UpdateBeforeSimulation10();

            if (!CheckUnobstructed())
            {
                if (SafeConstraint != null)
                {
                    RemoveConstraintInBoth();
                }
                return;
            }

            if (SafeConstraint != null)
            {
                bool staticOk = this.CubeGrid.IsStatic || !m_other.CubeGrid.IsStatic;
                if (!staticOk || !IsWorking || !m_other.IsWorking || !IsWithinWorldLimits)
                    return;

                Debug.Assert(!m_other.CubeGrid.MarkedForClose && !CubeGrid.MarkedForClose);

                var mergeBlockDefinition = this.BlockDefinition as MyMergeBlockDefinition;
                float maxStrength = mergeBlockDefinition != null ? mergeBlockDefinition.Strength : 0.1f;
                float dist = (float)(WorldMatrix.Translation - m_other.WorldMatrix.Translation).Length() - CubeGrid.GridSize;

                if (dist > CubeGrid.GridSize * 3)
                {
                    RemoveConstraintInBoth();
                    return;
                }

                MergeData data = new MergeData();
                CalculateMergeData(ref data);

                (m_constraint.ConstraintData as HkMalleableConstraintData).Strength = data.ConstraintStrength;

                if (data.PositionOk && data.AxisOk && data.RotationOk)
                {
                    if (m_frameCounter++ >= 3)
                    {
                        Vector3I gridOffset = CalculateOtherGridOffset();
                        Vector3I otherGridOffset = m_other.CalculateOtherGridOffset();

                        bool canMerge = this.CubeGrid.CanMergeCubes(m_other.CubeGrid, gridOffset);
                        if (!canMerge)
                        {
                            if (this.CubeGrid.GridSystems.ControlSystem.IsLocallyControlled || m_other.CubeGrid.GridSystems.ControlSystem.IsLocallyControlled)
                                MyHud.Notifications.Add(MyNotificationSingletons.ObstructingBlockDuringMerge);
                            return;
                        }
                        var handle = BeforeMerge;
                        if (handle != null) BeforeMerge();
                        if (Sync.IsServer)
                        {
                            foreach (var block in CubeGrid.GetBlocks())
                            {
                                var mergeBlock = block.FatBlock as MyShipMergeBlock;
                                if (mergeBlock != null && mergeBlock != this && mergeBlock.InConstraint)
                                    (block.FatBlock as MyShipMergeBlock).RemoveConstraintInBoth();
                            }

                            MyCubeGrid mergedGrid = this.CubeGrid.MergeGrid_MergeBlock(m_other.CubeGrid, gridOffset);
                            if (mergedGrid == null)
                            {
                                mergedGrid = m_other.CubeGrid.MergeGrid_MergeBlock(this.CubeGrid, otherGridOffset);
                            }
                            Debug.Assert(mergedGrid != null);

                            RemoveConstraintInBoth();
                        }
                    }
                }
                else
                {
                    m_frameCounter = 0;
                }
                return;
            }
            foreach (var other in m_gridList)
            {
                if (other.MarkedForClose)
                    continue;
                Vector3I pos = Vector3I.Zero;
                double dist = double.MaxValue;
                LineD l = new LineD(Physics.ClusterToWorld(Physics.RigidBody.Position), Physics.ClusterToWorld(Physics.RigidBody.Position) + GetMergeNormalWorld());
                if (other.GetLineIntersectionExactGrid(ref l, ref pos, ref dist))
                {
                    var block = other.GetCubeBlock(pos).FatBlock as MyShipMergeBlock;

                    if(block == null)
                    {
                        continue;
                    }
                    if (block.InConstraint || !block.IsWorking || !block.CheckUnobstructed() || block.GetMergeNormalWorld().Dot(GetMergeNormalWorld()) > 0.0f)
                        return;

                    if (!block.FriendlyWithBlock(this)) return;

                    CreateConstraint(other, block);

                    NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME;
                    m_updateBeforeFlags |= UpdateBeforeFlags.EnableConstraint;
                    break;
                }
            }
        }
        //  Method finds intersection with line and any voxel triangleVertexes in this voxel map. Closes intersection is returned.
        internal override bool GetIntersectionWithLine(ref LineD worldLine, out MyIntersectionResultLineTriangleEx? t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES)
        {
            t = null;

            double intersectionDistance;
            LineD line = (LineD)worldLine;
            if (!PositionComp.WorldAABB.Intersects(line, out intersectionDistance))
                return false;

            ProfilerShort.Begin("VoxelMap.LineIntersection");
            try
            {
                Line localLine = new Line(worldLine.From - PositionLeftBottomCorner,
                                          worldLine.To - PositionLeftBottomCorner, true);
                MyIntersectionResultLineTriangle tmpResult;
                if (Storage.Geometry.Intersect(ref localLine, out tmpResult, flags))
                {
                    t = new MyIntersectionResultLineTriangleEx(tmpResult, this, ref worldLine);
                    var tmp = t.Value.IntersectionPointInWorldSpace;
                    tmp.AssertIsValid();
                    return true;
                }
                else
                {
                    t = null;
                    return false;
                }
            }
            finally
            {
                ProfilerShort.End();
            }
        }
        private void ComputeSunAngle()
        {
            m_angleToSun = Vector3.Dot(Vector3.Transform(m_panelOrientation, m_solarBlock.WorldMatrix.GetOrientation()), MySector.DirectionToSunNormalized);

            // If the sun is on the backside of the panel, and we're not two-sided, OR the block not functional, just stop processing here
            if ((m_angleToSun < 0 && !m_isTwoSided) || !m_solarBlock.IsFunctional)
            {
                return;
            }

            m_currentPivot %= 8;

            MatrixD rot = m_solarBlock.WorldMatrix.GetOrientation();
            float scale = (float)m_solarBlock.WorldMatrix.Forward.Dot(Vector3.Transform(m_panelOrientation, rot));
            float unit = m_solarBlock.BlockDefinition.CubeSize == MyCubeSize.Large ? 2.5f : 0.5f;

            Vector3D pivot = m_solarBlock.WorldMatrix.Translation;
            pivot += ((m_currentPivot % 4 - 1.5f) * unit * scale * (m_solarBlock.BlockDefinition.Size.X / 4f)) * m_solarBlock.WorldMatrix.Left;
            pivot += ((m_currentPivot / 4 - 0.5f) * unit * scale * (m_solarBlock.BlockDefinition.Size.Y / 2f)) * m_solarBlock.WorldMatrix.Up;
            pivot += unit * scale * (m_solarBlock.BlockDefinition.Size.Z / 2f) * Vector3.Transform(m_panelOrientation, rot) * m_panelOffset;

            LineD l = new LineD(pivot + MySector.DirectionToSunNormalized * 100, pivot + MySector.DirectionToSunNormalized * m_solarBlock.CubeGrid.GridSize / 4); //shadows are drawn only 1000m

            MyPhysics.CastRay(l.From, l.To, m_hitList, MyPhysics.CollisionLayers.DefaultCollisionLayer);
            m_isPivotInSun[m_currentPivot] = true;
            foreach (var hit in m_hitList)
            {
                var ent = hit.HkHitInfo.GetHitEntity();
                if (ent != m_solarBlock.CubeGrid)
                {
                    m_isPivotInSun[m_currentPivot] = false;
                    break;
                }
                else
                {
                    var grid = ent as MyCubeGrid;
                    var pos = grid.RayCastBlocks(l.From, l.To);
                    if (pos.HasValue && grid.GetCubeBlock(pos.Value) != m_solarBlock.SlimBlock)
                    {
                        m_isPivotInSun[m_currentPivot] = false;
                        break;
                    }
                }
            }

            m_pivotsInSun = 0;
            foreach (bool p in m_isPivotInSun)
            {
                if (p)
                    m_pivotsInSun++;
            }
        }
 VRageMath.Vector3?IMyEntity.GetIntersectionWithLineAndBoundingSphere(ref VRageMath.LineD line, float boundingSphereRadiusMultiplier)
 {
     return(GetIntersectionWithLineAndBoundingSphere(ref line, boundingSphereRadiusMultiplier));
 }