示例#1
0
 public Iteration(Car carBefore, IReadOnlyList<Point> steps, int index, Point lastSumAcc)
 {
     _lastSumAcc = lastSumAcc;
     CarBefore = carBefore;
     Steps = steps;
     Index = index;
     Line = new LineD(carBefore.Position, carBefore.Iterate(Direction).Position);
 }
示例#2
0
        public static void IntersectionOnBothLines(LineD a, LineD b, PointD result)
        {
            var intersection = a.IntersectionAndOnBothLines(b, true);

            intersection.HasValue.Should().BeTrue();

            intersection.Value.X.Should().BeApproximately(result.X, 1e-7);
            intersection.Value.Y.Should().BeApproximately(result.Y, 1e-7);
        }
示例#3
0
        /// <summary>
        /// 判断折线PL与线段L的交点个数
        /// </summary>
        /// <param name="L">线段L</param>
        /// <param name="PL">折线PL</param>
        /// <returns>相交返回交点数目,否则返回0</returns>
        public static Int32?HasIntersection(LineD L, PolylineD PL)
        {
            Int32 count = 0;

            foreach (LineD S in PL)
            {
                Int32?result = HasIntersection(L, S);
                if (result == null)
                {
                    return(null);
                }
                count += (Int32)result;
            }
            for (Int32 i = 1; i < PL.Points.Count - 1; ++i)//排除折线的开始和结束顶点
            {
                if (OnLine(L, PL.Points[i]) == true)
                {
                    count--;
                }
            }
            return(count);
        }
示例#4
0
        private void DamageGrid(FlameInfo flameInfo, LineD l, MyCubeGrid grid)
        {
            HkSphereShape sph       = new HkSphereShape(flameInfo.Radius * m_thrustDefinition.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 * m_thrustDefinition.FlameDamage, MyDamageType.Environment, attackerId: EntityId);
                        }
                    }
                    var areaPlanar   = 0.5f * flameInfo.Radius * CubeGrid.GridSize;
                    var areaVertical = 0.5f * CubeGrid.GridSize;

                    grid.Physics.ApplyDeformation(m_thrustDefinition.FlameDamage, areaPlanar, areaVertical, gridPos, gridDir, MyDamageType.Environment, CubeGrid.GridSizeEnum == MyCubeSize.Small ? 0.1f : 0, attackerId: EntityId);
                }
            }
        }
示例#5
0
        /// <summary>
        /// 获取线段L与多边形PG的交点集合
        /// </summary>
        /// <param name="L">线段L</param>
        /// <param name="PG">多边形PG</param>
        /// <returns>返回交点集合,如果有无数个交点则返回null.</returns>
        public static PointD[] Intersection(LineD L, PolygonD PG)
        {
            List <PointD> result = new List <PointD>();

            foreach (LineD S in PG)
            {
                PointD[] P = Intersection(L, S);
                if (P == null)
                {
                    return(null);
                }
                if (P.Length == 0)
                {
                    continue;
                }
                if (result.Contains(P[0]) == false)
                {
                    result.Add((PointD)P[0]);
                }
            }
            return(result.ToArray());
        }
示例#6
0
        /// <summary>
        /// 判断多边形PG与线段L的交点个数
        /// </summary>
        /// <param name="L">线段L</param>
        /// <param name="PG">多边形PG</param>
        /// <returns>相交返回交点数目,否则返回0</returns>
        public static Int32?HasIntersection(LineD L, PolygonD PG)
        {
            Int32 count = 0;

            foreach (LineD S in PG)
            {
                Int32?result = HasIntersection(L, S);
                if (result == null)
                {
                    return(null);
                }
                count += (Int32)result;
            }
            foreach (PointD P in PG.Vertex)
            {
                if (OnLine(L, P) == true)
                {
                    count--;
                }
            }
            return(count);
        }
        public static void GetAllEntitiesInRay(ref LineD ray, List <MyLineSegmentOverlapResult <MyEntity> > result, MyEntityQueryType qtype = MyEntityQueryType.Both)
        {
            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyGamePruningStructure::GetAllEntitiesInRay");
            if (qtype.HasDynamic())
            {
                m_dynamicObjectsTree.OverlapAllLineSegment <MyEntity>(ref ray, result);
            }
            if (qtype.HasStatic())
            {
                m_staticObjectsTree.OverlapAllLineSegment <MyEntity>(ref ray, result, false);
            }
            int topmostCount = result.Count;

            for (int i = 0; i < topmostCount; i++)
            {
                if (result[i].Element.Hierarchy != null)
                {
                    result[i].Element.Hierarchy.QueryLine(ref ray, result);
                }
            }
            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();
        }
示例#8
0
        /// <summary>
        /// 判断线段与矩形的交点个数
        /// </summary>
        /// <param name="L">线段L</param>
        /// <param name="R">线段R</param>
        /// <returns>相交返回交点数目,否则返回0,如果有无数个交点则返回null</returns>
        public static Int32?HasIntersection(LineD L, RectangleD R)
        {
            Int32 count = 0;

            foreach (LineD S in R)
            {
                Int32?result = HasIntersection(L, S);
                if (result == null)
                {
                    return(null);
                }
                count += (Int32)result;
            }
            foreach (PointD P in R.GetVertexs())
            {
                if (OnLine(L, P) == true)
                {
                    count--;
                }
            }
            return(count);
        }
示例#9
0
        public void UpdatePlacement()
        {
            this.m_lastUpdate      = MySession.Static.GameplayFrameCounter;
            this.m_hitInfo         = null;
            this.m_closestGrid     = null;
            this.m_closestVoxelMap = null;
            LineD ed = new LineD(this.RayStart, this.RayStart + (this.RayDirection * this.IntersectionDistance));

            MyPhysics.CastRay(ed.From, ed.To, this.m_tmpHitList, 0x18);
            if (MySession.Static.ControlledEntity != null)
            {
                this.m_tmpHitList.RemoveAll(hitInfo => ReferenceEquals(hitInfo.HkHitInfo.GetHitEntity(), MySession.Static.ControlledEntity.Entity));
            }
            if (this.m_tmpHitList.Count != 0)
            {
                Sandbox.Engine.Physics.MyPhysics.HitInfo info = this.m_tmpHitList[0];
                if (info.HkHitInfo.GetHitEntity() != null)
                {
                    this.m_closestGrid = info.HkHitInfo.GetHitEntity().GetTopMostParent(null) as MyCubeGrid;
                }
                if (this.m_closestGrid != null)
                {
                    this.m_hitInfo = new Sandbox.Engine.Physics.MyPhysics.HitInfo?(info);
                    if (!this.ClosestGrid.Editable)
                    {
                        this.m_closestGrid = null;
                    }
                }
                else
                {
                    this.m_closestVoxelMap = info.HkHitInfo.GetHitEntity() as MyVoxelBase;
                    if (this.m_closestVoxelMap != null)
                    {
                        this.m_hitInfo = new Sandbox.Engine.Physics.MyPhysics.HitInfo?(info);
                    }
                }
            }
        }
示例#10
0
        /// <summary>
        /// 判断线段L与圆C的交点个数
        /// </summary>
        /// <param name="L">线段L</param>
        /// <param name="C">圆形C</param>
        /// <returns>相交返回交点数目,否则返回0</returns>
        public static Int32?HasIntersection(LineD L, CircleD C)
        {
            Int32 count = 0;

            //如果和圆C有交点首先是L到圆心的距离小于或等于C的半径
            if (DoubleAlgorithm.Equals(PointAlgorithm.ClosestDistance(C.Center, L), C.Radius))
            {
                return(1);
            }
            else if (PointAlgorithm.ClosestDistance(C.Center, L) > C.Radius)
            {
                return(0);
            }
            if (PointAlgorithm.Distance(C.Center, L.Starting) >= C.Radius)
            {
                ++count;
            }
            if (PointAlgorithm.Distance(C.Center, L.End) >= C.Radius)
            {
                ++count;
            }
            return(count);
        }
示例#11
0
        public void CalculateCollisions(Vector3D direction, double distance, bool calculateTime = false, bool useAsteroidAABB = false)
        {
            var timeSpan = MyAPIGateway.Session.GameDateTime - _lastCollisionCheckTime;

            if (timeSpan.TotalMilliseconds < 240)
            {
                return;
            }

            _lastCollisionCheckTime = MyAPIGateway.Session.GameDateTime;

            ResetResults();
            CalculateTime   = calculateTime;
            DirectionVector = direction;
            Distance        = GetDistanceFromWeapons(distance, CollisionDirection);
            StartPosition   = _collisionSystem.Matrix.Translation;
            EndPosition     = direction * distance + StartPosition;
            Line            = new LineD(StartPosition, EndPosition);
            Ray             = new RayD(StartPosition, direction);
            TargetIntersectionCheck();
            ShieldIntersectionCheck();
            VoxelCheckRequest(useAsteroidAABB);
        }
示例#12
0
        internal void SmartLosDebug()
        {
            if (PosChangedTick != System.Session.Tick)
            {
                UpdatePivotPos();
            }
            var info = GetScope.Info;

            var checkLevel = Comp.Ai.IsStatic ? 1 : 5;
            var angle      = Comp.Session.Tick20 ? GetAngle() : _losAngle;

            for (int i = 0; i < checkLevel; i++)
            {
                var      source = GetSmartLosPosition(i, ref info, angle);
                IHitInfo hitInfo;
                Comp.Ai.Session.Physics.CastRay(source, info.Position, out hitInfo, 15, false);
                var grid = hitInfo?.HitEntity?.GetTopMostParent() as MyCubeGrid;
                var hit  = grid != null && grid.IsInSameLogicalGroupAs(Comp.Ai.MyGrid) && grid.GetTargetedBlock(hitInfo.Position + (-info.Direction * 0.1f)) != Comp.MyCube.SlimBlock;

                var line = new LineD(source, info.Position);
                DsDebugDraw.DrawLine(line, hit ? Color.Red : Color.Blue, 0.05f);
            }
        }
示例#13
0
        public unsafe bool Intersect(ref LineD line, out double startOffset, out double endOffset)
        {
            LineD     ll          = line;
            Vector3   vector      = this.Shape.Center();
            Vector3D *vectordPtr1 = (Vector3D *)ref ll.To;

            vectordPtr1[0] -= vector;
            Vector3D *vectordPtr2 = (Vector3D *)ref ll.From;

            vectordPtr2[0] -= vector;
            if (!this.Shape.IntersectLine(ref ll, out startOffset, out endOffset))
            {
                return(false);
            }
            Vector3D *vectordPtr3 = (Vector3D *)ref ll.From;

            vectordPtr3[0] += vector;
            Vector3D *vectordPtr4 = (Vector3D *)ref ll.To;

            vectordPtr4[0] += vector;
            line            = ll;
            return(true);
        }
示例#14
0
        public override void DebugDraw()
        {
            Vector3D positionLeftBottomCorner = this.m_planet.PositionLeftBottomCorner;

            if (MyDebugDrawSettings.DEBUG_DRAW_VOXEL_MAP_AABB)
            {
                this.m_planet.Components.Get <MyPlanetEnvironmentComponent>().DebugDraw();
                this.m_planet.DebugDrawPhysics();
                MyRenderProxy.DebugDrawAABB(this.m_planet.PositionComp.WorldAABB, Color.White, 1f, 1f, true, false, false);
                MyRenderProxy.DebugDrawLine3D(positionLeftBottomCorner, positionLeftBottomCorner + new Vector3(1f, 0f, 0f), Color.Red, Color.Red, true, false);
                MyRenderProxy.DebugDrawLine3D(positionLeftBottomCorner, positionLeftBottomCorner + new Vector3(0f, 1f, 0f), Color.Green, Color.Green, true, false);
                MyRenderProxy.DebugDrawLine3D(positionLeftBottomCorner, positionLeftBottomCorner + new Vector3(0f, 0f, 1f), Color.Blue, Color.Blue, true, false);
                MyRenderProxy.DebugDrawAxis(this.m_planet.PositionComp.WorldMatrix, 2f, false, false, false);
                MyRenderProxy.DebugDrawSphere(this.m_planet.PositionComp.GetPosition(), 1f, Color.OrangeRed, 1f, false, false, true, false);
            }
            if (MyDebugDrawSettings.DEBUG_DRAW_VOXEL_GEOMETRY_CELL)
            {
                MyIntersectionResultLineTriangleEx?nullable;
                MyCamera mainCamera = MySector.MainCamera;
                LineD    line       = new LineD(mainCamera.Position, mainCamera.Position + (25f * mainCamera.ForwardVector));
                if (this.m_planet.GetIntersectionWithLine(ref line, out nullable, IntersectionFlags.ALL_TRIANGLES))
                {
                    Vector3I            vectori;
                    Vector3I            vectori2;
                    BoundingBoxD        xd2;
                    MyTriangle_Vertices inputTriangle = nullable.Value.Triangle.InputTriangle;
                    MyRenderProxy.DebugDrawTriangle(inputTriangle.Vertex0 + positionLeftBottomCorner, inputTriangle.Vertex1 + positionLeftBottomCorner, inputTriangle.Vertex2 + positionLeftBottomCorner, Color.Red, true, false, false);
                    Vector3D intersectionPointInWorldSpace = nullable.Value.IntersectionPointInWorldSpace;
                    MyVoxelCoordSystems.WorldPositionToVoxelCoord(positionLeftBottomCorner, ref intersectionPointInWorldSpace, out vectori2);
                    MyVoxelCoordSystems.VoxelCoordToWorldAABB(positionLeftBottomCorner, ref vectori2, out xd2);
                    MyRenderProxy.DebugDrawAABB(xd2, Vector3.UnitY, 1f, 1f, true, false, false);
                    MyVoxelCoordSystems.WorldPositionToGeometryCellCoord(positionLeftBottomCorner, ref intersectionPointInWorldSpace, out vectori);
                    MyVoxelCoordSystems.GeometryCellCoordToWorldAABB(positionLeftBottomCorner, ref vectori, out xd2);
                    MyRenderProxy.DebugDrawAABB(xd2, Vector3.UnitZ, 1f, 1f, true, false, false);
                }
            }
        }
示例#15
0
 public void PrefetchShapeOnRay(ref LineD ray)
 {
     if (this.m_mesher != null)
     {
         Vector3            vector;
         Vector3            vector2;
         HkUniformGridShape shape;
         int lod = UseLod1VoxelPhysics ? 1 : 0;
         MyVoxelCoordSystems.WorldPositionToLocalPosition(this.m_voxelMap.PositionLeftBottomCorner, ref ray.From, out vector);
         MyVoxelCoordSystems.WorldPositionToLocalPosition(this.m_voxelMap.PositionLeftBottomCorner, ref ray.To, out vector2);
         if (this.GetShape(lod, out shape))
         {
             if (m_cellsToGenerateBuffer.Length < 0x40)
             {
                 m_cellsToGenerateBuffer = new Vector3I[0x40];
             }
             int num2 = shape.GetHitCellsInRange(vector, vector2, m_cellsToGenerateBuffer);
             if (num2 != 0)
             {
                 for (int i = 0; i < num2; i++)
                 {
                     MyCellCoord id = new MyCellCoord(lod, m_cellsToGenerateBuffer[i]);
                     if (!this.m_workTracker.Exists(id))
                     {
                         MyPrecalcJobPhysicsPrefetch.Args args = new MyPrecalcJobPhysicsPrefetch.Args {
                             TargetPhysics = this,
                             Tracker       = this.m_workTracker,
                             GeometryCell  = id,
                             Storage       = this.m_voxelMap.Storage
                         };
                         MyPrecalcJobPhysicsPrefetch.Start(args);
                     }
                 }
             }
         }
     }
 }
        public void DoubleEdgeX()
        {
            LineD line = new LineD(-5, 0, +5, 0);

            // parallel horizontal edges
            CheckSearch(line, new LineD(-4, +2, +4, +2));
            CheckSearch(line, new LineD(-5, +2, +4, +2));
            CheckSearch(line, new LineD(-5, +2, +5, +2)); // multi-cell intersection
            CheckSearch(line, new LineD(-4, -2, +4, -2));
            CheckSearch(line, new LineD(-4, -2, +5, -2));
            CheckSearch(line, new LineD(-5, -2, +5, -2)); // multi-cell intersection

            // horizontal and vertical edge
            CheckSearch(line, new LineD(0, +1, 0, +4));
            CheckSearch(line, new LineD(0, -1, 0, -4));

            // horizontal and diagonal edge
            CheckSearch(line, new LineD(-5, 0, +4, +2));
            CheckSearch(line, new LineD(-5, 0, +5, +2));  // multi-cell intersection
            CheckSearch(line, new LineD(-5, 0, +5, -2));
            CheckSearch(line, new LineD(-5, +2, +5, 0));
            CheckSearch(line, new LineD(-4, -2, +5, 0));
            CheckSearch(line, new LineD(-5, -2, +5, 0));  // multi-cell intersection
        }
示例#17
0
        private static bool FilterCheckIfTrackForCrossedOldTrack(LineD currentTrack, LineD track, Point currentPosition)
        {
            if (currentPosition == track.A)
            {
                return(true);
            }

            if (currentTrack.IntersectionAndOnBothLines(track, true) != null)
            {
                return(true);
            }

            if (track.IsOnLine(currentPosition, true))
            {
                return(true);
            }

            if (currentTrack.IsOnLine(track.A, true))
            {
                return(true);
            }

            return(false);
        }
示例#18
0
        private Vector3D ComputeHandlerImpact()
        {
            WebDamage            = false;
            HandlerImpact.Active = false;
            if (HandlerImpact.HitBlock == null)
            {
                return(MyGrid.PositionComp.WorldAABB.Center);
            }

            Vector3D originHit;

            HandlerImpact.HitBlock.ComputeWorldCenter(out originHit);

            var line = new LineD(HandlerImpact.Attacker.PositionComp.WorldAABB.Center, originHit);

            var testDir       = Vector3D.Normalize(line.From - line.To);
            var ray           = new RayD(line.From, -testDir);
            var matrix        = ShieldShapeMatrix * MyGrid.WorldMatrix;
            var intersectDist = CustomCollision.IntersectEllipsoid(MatrixD.Invert(matrix), matrix, ray);
            var ellipsoid     = intersectDist ?? line.Length;
            var shieldHitPos  = line.From + (testDir * -ellipsoid);

            return(shieldHitPos);
        }
示例#19
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);
            }
        }
示例#20
0
        public bool Contains(PointD p)
        {
            if (!BoundingBox.Contains(p))
            {
                return(false);
            }

            //avg of height and width divided by 100
            var e   = (BoundingBox.Width + BoundingBox.Height) / 200;
            var ray = new LineD(BoundingBox.X - e, BoundingBox.Y + e, p.X, p.Y);

            var   intersections = 0;
            LineD line;

            for (var i = 0; i < Shape.OuterRing.Positions.Count - 1; i++)
            {
                line = new LineD(Shape.OuterRing.Positions[i].Longitude, Shape.OuterRing.Positions[i].Latitude, Shape.OuterRing.Positions[i + 1].Longitude, Shape.OuterRing.Positions[i + 1].Latitude);
                if (line.Intersects(ray))
                {
                    intersections++;
                }
            }
            foreach (var lineString in Shape.InnerRings)
            {
                for (var i = 0; i < Shape.OuterRing.Positions.Count - 1; i++)
                {
                    line = new LineD(Shape.OuterRing.Positions[i].Longitude, Shape.OuterRing.Positions[i].Latitude, Shape.OuterRing.Positions[i + 1].Longitude, Shape.OuterRing.Positions[i + 1].Latitude);
                    if (line.Intersects(ray))
                    {
                        intersections++;
                    }
                }
            }

            return(intersections % 2 == 1);
        }
示例#21
0
        //  Method finds intersection with line and any voxel triangleVertexes in this voxel map. Closes intersection is returned.
        public override bool GetIntersectionWithLine(ref LineD worldLine, out VRage.Game.Models.MyIntersectionResultLineTriangleEx?t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES)
        {
            t = null;

            double intersectionDistance;
            LineD  line = (LineD)worldLine;

            if (!PositionComp.WorldAABB.Intersects(ref line, out intersectionDistance))
            {
                return(false);
            }

            ProfilerShort.Begin("VoxelMap.LineIntersection");
            try
            {
                Line localLine = new Line(worldLine.From - PositionLeftBottomCorner,
                                          worldLine.To - PositionLeftBottomCorner, true);
                VRage.Game.Models.MyIntersectionResultLineTriangle tmpResult;
                if (Storage.Geometry.Intersect(ref localLine, out tmpResult, flags))
                {
                    t = new VRage.Game.Models.MyIntersectionResultLineTriangleEx(tmpResult, this, ref worldLine);
                    var tmp = t.Value.IntersectionPointInWorldSpace;
                    tmp.AssertIsValid();
                    return(true);
                }
                else
                {
                    t = null;
                    return(false);
                }
            }
            finally
            {
                ProfilerShort.End();
            }
        }
示例#22
0
        public MyIntersectionResultLineTriangleEx?GetIntersectionWithLine(IMyEntity entity, ref LineD line, ref MatrixD customInvMatrix, IntersectionFlags flags)
        {
            LineD lineInModelSpace = new LineD(Vector3D.Transform(line.From, ref customInvMatrix), Vector3D.Transform(line.To, ref customInvMatrix));

            //MyIntersectionResultLineTriangle? result = null;

            m_result.Start(m_model, lineInModelSpace, flags);

            var dir  = lineInModelSpace.Direction.ToBullet();
            var from = lineInModelSpace.From.ToBullet();

            VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("m_bvh.RayQueryClosest()");
            m_bvh.RayQueryClosest(ref dir, ref from, m_result.ProcessTriangleHandler);
            VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock();

            if (m_result.Result.HasValue)
            {
                return(new MyIntersectionResultLineTriangleEx(m_result.Result.Value, entity, ref lineInModelSpace));
            }
            else
            {
                return(null);
            }
        }
示例#23
0
        internal void InitialHitCheck()
        {
            var vhCount  = ValidateHits.Count;
            var minCount = Session.Settings.Enforcement.ServerOptimizations ? 96 : 99999;
            var stride   = vhCount < minCount ? 100000 : 48;

            MyAPIGateway.Parallel.For(0, ValidateHits.Count, x => {
                var p = ValidateHits[x];

                var shieldByPass       = p.Info.ConsumableDef.DamageScales.Shields.Type == ShieldDef.ShieldType.Bypass;
                var shieldFullBypass   = shieldByPass && p.Info.ConsumableDef.Const.ShieldBypassMod >= 1;
                var genericFields      = p.Info.EwarActive && (p.Info.ConsumableDef.Const.AreaEffect == DotField || p.Info.ConsumableDef.Const.AreaEffect == PushField || p.Info.ConsumableDef.Const.AreaEffect == PullField);
                p.FinalizeIntersection = false;
                var lineCheck          = p.Info.ConsumableDef.Const.CollisionIsLine && !p.Info.EwarAreaPulse;
                var ewarProjectile     = (p.Info.EwarActive || p.Info.ConsumableDef.Const.EwarEffect);

                bool projetileInShield = false;
                var tick = p.Info.System.Session.Tick;

                var useEntityCollection = p.CheckType != Projectile.CheckTypes.Ray;
                var entityCollection    = p.UseEntityCache ? p.Info.Ai.NearByEntityCache : p.MyEntityList;
                var collectionCount     = !useEntityCollection ? p.MySegmentList.Count : entityCollection.Count;
                var ray    = new RayD(ref p.Beam.From, ref p.Beam.Direction);
                var myGrid = p.Info.Target.FiringCube.CubeGrid;

                Water water = null;
                if (Session.WaterApiLoaded && p.Info.MyPlanet != null)
                {
                    Session.WaterMap.TryGetValue(p.Info.MyPlanet, out water);
                }

                for (int i = 0; i < collectionCount; i++)
                {
                    var ent = !useEntityCollection ? p.MySegmentList[i].Element : entityCollection[i];

                    var grid      = ent as MyCubeGrid;
                    var entIsSelf = grid != null && (grid == myGrid || myGrid.IsSameConstructAs(grid));

                    if (entIsSelf && p.SmartsOn || ent.MarkedForClose || !ent.InScene || ent == p.Info.MyShield)
                    {
                        continue;
                    }

                    var character = ent as IMyCharacter;
                    if (p.Info.EwarActive && character != null && !genericFields)
                    {
                        continue;
                    }

                    var entSphere = ent.PositionComp.WorldVolume;
                    if (useEntityCollection)
                    {
                        if (p.CheckType == Projectile.CheckTypes.CachedRay)
                        {
                            var dist = ray.Intersects(entSphere);
                            if (!dist.HasValue || dist > p.Beam.Length)
                            {
                                continue;
                            }
                        }
                        else if (p.CheckType == Projectile.CheckTypes.CachedSphere && p.PruneSphere.Contains(entSphere) == ContainmentType.Disjoint)
                        {
                            continue;
                        }
                    }

                    if (grid != null || character != null)
                    {
                        var extBeam   = new LineD(p.Beam.From - p.Beam.Direction * (entSphere.Radius * 2), p.Beam.To);
                        var transform = ent.PositionComp.WorldMatrixRef;
                        var box       = ent.PositionComp.LocalAABB;
                        var obb       = new MyOrientedBoundingBoxD(box, transform);
                        if (lineCheck && obb.Intersects(ref extBeam) == null || !lineCheck && !obb.Intersects(ref p.PruneSphere))
                        {
                            continue;
                        }
                    }
                    var safeZone = ent as MySafeZone;
                    if (safeZone != null && safeZone.Enabled)
                    {
                        var action = (Session.SafeZoneAction)safeZone.AllowedActions;
                        if ((action & Session.SafeZoneAction.Damage) == 0)
                        {
                            bool intersects;
                            if (safeZone.Shape == MySafeZoneShape.Sphere)
                            {
                                var sphere = new BoundingSphereD(safeZone.PositionComp.WorldVolume.Center, safeZone.Radius);
                                var dist   = ray.Intersects(sphere);
                                intersects = dist != null && dist <= p.Beam.Length;
                            }
                            else
                            {
                                intersects = new MyOrientedBoundingBoxD(safeZone.PositionComp.LocalAABB, safeZone.PositionComp.WorldMatrixRef).Intersects(ref p.Beam) != null;
                            }

                            if (intersects)
                            {
                                p.State    = Projectile.ProjectileState.Depleted;
                                p.EarlyEnd = true;

                                if (p.EnableAv)
                                {
                                    p.Info.AvShot.ForceHitParticle = true;
                                }
                                break;
                            }
                        }
                    }

                    HitEntity hitEntity = null;
                    var checkShield     = Session.ShieldApiLoaded && Session.ShieldHash == ent.DefinitionId?.SubtypeId && ent.Render.Visible;
                    MyTuple <IMyTerminalBlock, MyTuple <bool, bool, float, float, float, int>, MyTuple <MatrixD, MatrixD> >?shieldInfo = null;
                    if (checkShield && (!shieldFullBypass && !p.ShieldBypassed || p.Info.EwarActive && (p.Info.ConsumableDef.Const.AreaEffect == DotField || p.Info.ConsumableDef.Const.AreaEffect == EmpField)))
                    {
                        shieldInfo = p.Info.System.Session.SApi.MatchEntToShieldFastExt(ent, true);
                        if (shieldInfo != null && !myGrid.IsSameConstructAs(shieldInfo.Value.Item1.CubeGrid))
                        {
                            if (p.Info.IsShrapnel || Vector3D.Transform(p.Info.Origin, shieldInfo.Value.Item3.Item1).LengthSquared() > 1)
                            {
                                p.EntitiesNear = true;
                                var dist       = MathFuncs.IntersectEllipsoid(shieldInfo.Value.Item3.Item1, shieldInfo.Value.Item3.Item2, new RayD(p.Beam.From, p.Beam.Direction));
                                if (p.Info.Target.IsProjectile && Vector3D.Transform(p.Info.Target.Projectile.Position, shieldInfo.Value.Item3.Item1).LengthSquared() <= 1)
                                {
                                    projetileInShield = true;
                                }

                                if (dist != null && (dist.Value < p.Beam.Length || p.Info.EwarActive))
                                {
                                    if (shieldByPass)
                                    {
                                        p.ShieldBypassed = true;
                                    }
                                    hitEntity           = HitEntityPool.Get();
                                    hitEntity.EventType = Shield;
                                    hitEntity.HitPos    = p.Beam.From + (p.Beam.Direction * dist.Value);
                                    hitEntity.HitDist   = dist;
                                }
                                else
                                {
                                    continue;
                                }
                            }
                        }
                    }

                    var destroyable = ent as IMyDestroyableObject;
                    var voxel       = ent as MyVoxelBase;
                    if (voxel != null && voxel == voxel?.RootVoxel)
                    {
                        if (ent == p.Info.MyPlanet && !(p.LinePlanetCheck || p.DynamicGuidance || p.CachedPlanetHit))
                        {
                            continue;
                        }
                        VoxelIntersectBranch voxelState = VoxelIntersectBranch.None;
                        Vector3D?voxelHit = null;
                        if (tick - p.Info.VoxelCache.HitRefreshed < 60)
                        {
                            var cacheDist = ray.Intersects(p.Info.VoxelCache.HitSphere);
                            if (cacheDist.HasValue && cacheDist.Value <= p.Beam.Length)
                            {
                                voxelHit   = p.Beam.From + (p.Beam.Direction * cacheDist.Value);
                                voxelState = VoxelIntersectBranch.PseudoHit1;
                            }
                            else if (cacheDist.HasValue)
                            {
                                p.Info.VoxelCache.MissSphere.Center = p.Beam.To;
                            }
                        }

                        if (voxelState != VoxelIntersectBranch.PseudoHit1)
                        {
                            if (voxel == p.Info.MyPlanet && p.Info.VoxelCache.MissSphere.Contains(p.Beam.To) == ContainmentType.Disjoint)
                            {
                                if (p.LinePlanetCheck)
                                {
                                    if (water != null && !p.Info.ConsumableDef.IgnoreWater)
                                    {
                                        var waterSphere = new BoundingSphereD(p.Info.MyPlanet.PositionComp.WorldAABB.Center, water.radius);
                                        var estiamtedSurfaceDistance = ray.Intersects(waterSphere);

                                        if (estiamtedSurfaceDistance.HasValue && estiamtedSurfaceDistance.Value <= p.Beam.Length)
                                        {
                                            var estimatedHit = ray.Position + (ray.Direction * estiamtedSurfaceDistance.Value);
                                            voxelHit         = estimatedHit;
                                            voxelState       = VoxelIntersectBranch.PseudoHit2;
                                        }
                                    }

                                    if (voxelState != VoxelIntersectBranch.PseudoHit2)
                                    {
                                        var surfacePos   = p.Info.MyPlanet.GetClosestSurfacePointGlobal(ref p.Position);
                                        var planetCenter = p.Info.MyPlanet.PositionComp.WorldAABB.Center;
                                        double surfaceToCenter;
                                        Vector3D.DistanceSquared(ref surfacePos, ref planetCenter, out surfaceToCenter);
                                        double endPointToCenter;
                                        Vector3D.DistanceSquared(ref p.Position, ref planetCenter, out endPointToCenter);
                                        double startPointToCenter;
                                        Vector3D.DistanceSquared(ref p.Info.Origin, ref planetCenter, out startPointToCenter);

                                        var prevEndPointToCenter = p.PrevEndPointToCenterSqr;
                                        Vector3D.DistanceSquared(ref surfacePos, ref p.Position, out p.PrevEndPointToCenterSqr);
                                        if (surfaceToCenter > endPointToCenter || p.PrevEndPointToCenterSqr <= (p.Beam.Length * p.Beam.Length) || endPointToCenter > startPointToCenter && prevEndPointToCenter > p.DistanceToTravelSqr || surfaceToCenter > Vector3D.DistanceSquared(planetCenter, p.LastPosition))
                                        {
                                            var estiamtedSurfaceDistance = ray.Intersects(p.Info.VoxelCache.PlanetSphere);
                                            var fullCheck = p.Info.VoxelCache.PlanetSphere.Contains(p.Info.Origin) != ContainmentType.Disjoint || !estiamtedSurfaceDistance.HasValue;

                                            if (!fullCheck && estiamtedSurfaceDistance.HasValue && (estiamtedSurfaceDistance.Value <= p.Beam.Length || p.Info.VoxelCache.PlanetSphere.Radius < 1))
                                            {
                                                double distSqr;
                                                var estimatedHit = ray.Position + (ray.Direction * estiamtedSurfaceDistance.Value);
                                                Vector3D.DistanceSquared(ref p.Info.VoxelCache.FirstPlanetHit, ref estimatedHit, out distSqr);

                                                if (distSqr > 625)
                                                {
                                                    fullCheck = true;
                                                }
                                                else
                                                {
                                                    voxelHit   = estimatedHit;
                                                    voxelState = VoxelIntersectBranch.PseudoHit2;
                                                }
                                            }

                                            if (fullCheck)
                                            {
                                                voxelState = VoxelIntersectBranch.DeferFullCheck;
                                            }

                                            if (voxelHit.HasValue && Vector3D.DistanceSquared(voxelHit.Value, p.Info.VoxelCache.PlanetSphere.Center) > p.Info.VoxelCache.PlanetSphere.Radius * p.Info.VoxelCache.PlanetSphere.Radius)
                                            {
                                                p.Info.VoxelCache.GrowPlanetCache(voxelHit.Value);
                                            }
                                        }
                                    }
                                }
                            }
                            else if (voxelHit == null && p.Info.VoxelCache.MissSphere.Contains(p.Beam.To) == ContainmentType.Disjoint)
                            {
                                voxelState = VoxelIntersectBranch.DeferedMissUpdate;
                            }
                        }

                        if (voxelState == VoxelIntersectBranch.PseudoHit1 || voxelState == VoxelIntersectBranch.PseudoHit2)
                        {
                            if (!voxelHit.HasValue)
                            {
                                if (p.Info.VoxelCache.MissSphere.Contains(p.Beam.To) == ContainmentType.Disjoint)
                                {
                                    p.Info.VoxelCache.MissSphere.Center = p.Beam.To;
                                }
                                continue;
                            }

                            hitEntity = HitEntityPool.Get();

                            var hitPos       = voxelHit.Value;
                            hitEntity.HitPos = hitPos;

                            double dist;
                            Vector3D.Distance(ref p.Beam.From, ref hitPos, out dist);
                            hitEntity.HitDist = dist;

                            hitEntity.EventType = Voxel;
                        }
                        else if (voxelState == VoxelIntersectBranch.DeferedMissUpdate || voxelState == VoxelIntersectBranch.DeferFullCheck)
                        {
                            DeferedVoxels.Add(new DeferedVoxels {
                                Projectile = p, Branch = voxelState, Voxel = voxel
                            });
                        }
                    }
                    else if (ent.Physics != null && !ent.Physics.IsPhantom && !ent.IsPreview && grid != null)
                    {
                        if (grid != null)
                        {
                            hitEntity = HitEntityPool.Get();
                            if (entIsSelf)
                            {
                                if (!p.Info.ConsumableDef.Const.IsBeamWeapon && p.Beam.Length <= grid.GridSize * 2)
                                {
                                    MyCube cube;
                                    if (!(grid.TryGetCube(grid.WorldToGridInteger(p.Position), out cube) && cube.CubeBlock != p.Info.Target.FiringCube.SlimBlock || grid.TryGetCube(grid.WorldToGridInteger(p.LastPosition), out cube) && cube.CubeBlock != p.Info.Target.FiringCube.SlimBlock))
                                    {
                                        HitEntityPool.Return(hitEntity);
                                        continue;
                                    }
                                }

                                if (!p.Info.EwarAreaPulse)
                                {
                                    var forwardPos = p.Info.Age != 1 ? p.Beam.From : p.Beam.From + (p.Beam.Direction * Math.Min(grid.GridSizeHalf, p.Info.DistanceTraveled - p.Info.PrevDistanceTraveled));
                                    grid.RayCastCells(forwardPos, p.Beam.To, hitEntity.Vector3ICache, null, true, true);

                                    if (hitEntity.Vector3ICache.Count > 0)
                                    {
                                        IHitInfo hitInfo;
                                        p.Info.System.Session.Physics.CastRay(forwardPos, p.Beam.To, out hitInfo, CollisionLayers.DefaultCollisionLayer);
                                        var hitGrid = hitInfo?.HitEntity?.GetTopMostParent() as MyCubeGrid;
                                        if (hitGrid == null || !myGrid.IsSameConstructAs(hitGrid))
                                        {
                                            HitEntityPool.Return(hitEntity);
                                            continue;
                                        }

                                        hitEntity.HitPos = hitInfo.Position;
                                        hitEntity.Blocks.Add(grid.GetCubeBlock(hitEntity.Vector3ICache[0]));
                                    }
                                }
                            }
                            else
                            {
                                grid.RayCastCells(p.Beam.From, p.Beam.To, hitEntity.Vector3ICache, null, true, true);
                            }

                            if (!ewarProjectile)
                            {
                                hitEntity.EventType = Grid;
                            }
                            else if (!p.Info.EwarAreaPulse)
                            {
                                hitEntity.EventType = Effect;
                            }
                            else
                            {
                                hitEntity.EventType = Field;
                            }

                            p.EntitiesNear = true;
                        }
                    }
                    else if (destroyable != null)
                    {
                        hitEntity           = HitEntityPool.Get();
                        hitEntity.EventType = Destroyable;
                    }

                    if (hitEntity != null)
                    {
                        p.FinalizeIntersection   = true;
                        hitEntity.Info           = p.Info;
                        hitEntity.Entity         = hitEntity.EventType != Shield ? ent : (MyEntity)shieldInfo.Value.Item1;
                        hitEntity.Intersection   = p.Beam;
                        hitEntity.SphereCheck    = !lineCheck;
                        hitEntity.PruneSphere    = p.PruneSphere;
                        hitEntity.SelfHit        = entIsSelf;
                        hitEntity.DamageOverTime = p.Info.ConsumableDef.Const.AreaEffect == DotField;

                        p.Info.HitList.Add(hitEntity);
                    }
                }

                if (p.Info.Target.IsProjectile && !p.Info.ConsumableDef.Const.EwarEffect && !projetileInShield)
                {
                    var detonate     = p.State == Projectile.ProjectileState.Detonate;
                    var hitTolerance = detonate ? p.Info.ConsumableDef.Const.DetonationRadius : p.Info.ConsumableDef.Const.AreaEffectSize > p.Info.ConsumableDef.Const.CollisionSize ? p.Info.ConsumableDef.Const.AreaEffectSize : p.Info.ConsumableDef.Const.CollisionSize;
                    var useLine      = p.Info.ConsumableDef.Const.CollisionIsLine && !detonate && p.Info.ConsumableDef.Const.AreaEffectSize <= 0;

                    var sphere = new BoundingSphereD(p.Info.Target.Projectile.Position, p.Info.Target.Projectile.Info.ConsumableDef.Const.CollisionSize);
                    sphere.Include(new BoundingSphereD(p.Info.Target.Projectile.LastPosition, 1));

                    bool rayCheck = false;
                    if (useLine)
                    {
                        var dist = sphere.Intersects(new RayD(p.LastPosition, p.Info.Direction));
                        if (dist <= hitTolerance || p.Info.ConsumableDef.Const.IsBeamWeapon && dist <= p.Beam.Length)
                        {
                            rayCheck = true;
                        }
                    }

                    var testSphere    = p.PruneSphere;
                    testSphere.Radius = hitTolerance;

                    if (rayCheck || sphere.Intersects(testSphere))
                    {
                        ProjectileHit(p, p.Info.Target.Projectile, lineCheck, ref p.Beam);
                    }
                }

                if (!useEntityCollection)
                {
                    p.MySegmentList.Clear();
                }
                else if (p.CheckType == Projectile.CheckTypes.Sphere)
                {
                    entityCollection.Clear();
                }

                if (p.FinalizeIntersection)
                {
                    FinalHitCheck.Add(p);
                }
            }, stride);
            ValidateHits.ClearImmediate();
        }
示例#24
0
 public void GetTrianglesIntersectingLine(IMyEntity entity, ref LineD line, ref MatrixD customInvMatrix, IntersectionFlags flags, List <MyIntersectionResultLineTriangleEx> result)
 {
     System.Diagnostics.Debug.Assert(false, "Not implemented");
 }
示例#25
0
        public void GetTrianglesIntersectingLine(IMyEntity entity, ref LineD line, IntersectionFlags flags, List <VRage.Game.Models.MyIntersectionResultLineTriangleEx> result)
        {
            MatrixD worldInv = entity.GetWorldMatrixNormalizedInv();

            GetTrianglesIntersectingLine(entity, ref line, ref worldInv, flags, result);
        }
示例#26
0
        public VRage.Game.Models.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));

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

            return(ret);
        }
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            List<Line> lineList = new List<Line>();
            List<Line> lineListInput = new List<Line>();
            List<LineD> lineDList = new List<LineD>();
            LineD[] currLinesArr;
            Subdivision InverseGraph;

            Dictionary<PointD, LineD> InverseEdgesMapping = new Dictionary<PointD,LineD>();
            Dictionary<LineD, double> RealDist = new Dictionary<LineD,double>();
            Dictionary<LineD, double> RealAngle = new Dictionary<LineD,double>();

            if (DA.GetDataList(0, lineListInput)) //If it works...
            {
                // sort out duplicate Lines
                //========================================================
                List<Point3d> mPointList = new List<Point3d>();
                foreach (Line mLine in lineListInput)
                {
                    //compute middle points
                    Point3d middle = (mLine.From + mLine.To) * 0.5;
                    mPointList.Add(middle);
                }
                // add lines and middle points to dictionary
                Dictionary<Point3d, Line> inputMap = new Dictionary<Point3d, Line>();
                for (int i = 0; i < mPointList.Count; i++)
                {
                    if (inputMap.ContainsKey(mPointList[i]))
                        continue;
                    inputMap.Add(mPointList[i], lineListInput[i]);
                }
                lineList = inputMap.Values.ToList();

                /*
                // filter duplicate points
                mPointList = mPointList.Distinct().ToList();
                for (int i = 0; i < lineListInput.Count; i++)
                {
                    Point3d point = mPointList[i];
                    lineList[i] = inputMap[point];
                }*/

                //======================================================================
                foreach (Line a in lineList)

                {
                    if (a.IsValid)
                    {

                        PointD start = new PointD(a.FromX, a.FromY);
                        PointD end = new PointD(a.ToX, a.ToY);
                        LineD b = new LineD(start, end);
                        lineDList.Add(b);
                    }
                }

                    Subdivision Graph;
                    Graph = new Subdivision();
                    currLinesArr = lineDList.ToArray();
                    Graph = Subdivision.FromLines(currLinesArr);
                    InverseGraph = Tools.ConstructInverseGraph(Graph, ref RealDist, ref RealAngle, ref InverseEdgesMapping);
                    SubdShortestPath ShortPahtesMetric = new SubdShortestPath(InverseGraph, RealDist);

                    ShortPahtesMetric.EvaluateMetric(null);

                    List<PointD> curVertices = new List<PointD>();
                    foreach (PointD pt in InverseGraph.Vertices.Keys)
                    {
                        curVertices.Add(pt);
                    }

                    LineD curEdge;

                    float[] finRes = new float[lineDList.Count];
                    float[] tempRes = ShortPahtesMetric.GetNormChoiceArray();
                    for (int i = 0; i < curVertices.Count; i++)
                    {
                        PointD point = curVertices[i];
                        curEdge = InverseEdgesMapping[point];
                        int idx = lineDList.IndexOf(curEdge);

                        finRes[idx] = tempRes[i];

                    }

                DA.SetDataList(0, new List<float>(finRes));
                DA.SetDataList(1, lineList);
            }
        }
示例#28
0
        private static bool HasSichtLine(List<LineD> obstacles, Point position, Point end)
        {
            var line = new LineD(position, end);

            foreach (var obstacle in obstacles)
            {
                if (obstacle.IntersectionAndOnBothLines(line, false) != null)
                {
                    return false;
                }
            }
            return true;
        }
示例#29
0
 bool IMyCubeGrid.GetLineIntersectionExactGrid(ref LineD line, ref Vector3I position, ref double distanceSquared)
 {
     return(GetLineIntersectionExactGrid(ref line, ref position, ref distanceSquared));
 }
示例#30
0
        private static void Test(DateTime startTime)
        {
            var start = new Point(120, 0);
            var end = new Point(0, 0);
            var steps = 35;
            var height = -2;

            var lines = new LineD[]
            {
                new LineD(new PointD(160, -5), new PointD(-5, -5)),
                new LineD(new PointD(160, 1), new PointD(-5, 1)),
                //new LineD(new PointD(10, 2), new PointD(10, -2)),
                //new LineD(new PointD(30, -10), new PointD(30, -1)),
                //new LineD(new PointD(60, 2), new PointD(60, -2)),
                //new LineD(new PointD(50, 3), new PointD(50, -3)),
                // new LineD(new PointD(100, 3), new PointD(100, -3)),
                // new LineD(new PointD(100, -3), new PointD(50, -3)),

                new LineD(new PointD(20, 2), new PointD(10, height)),
                new LineD(new PointD(60, 2), new PointD(60, height)),
                new LineD(new PointD(20, height), new PointD(60, height)),
                //   new LineD(new PointD(60, -height), new PointD(80, 0)),
            };

            var bb = new BoundingBox(start, end).Inflate(0, 0, Math.Abs(height) + 2, 1);

            var desc = new Description(new Car(start), end, lines.ToList(), bb, steps);

            Solver.Solver.DoIt(desc, LogResult(startTime, start), LogInfo(startTime, start),
                false);
        }
示例#31
0
        public static void Shift(LineD start, double shift, LineD result)
        {
            var shifted = start.ShiftOrthoToDirection(shift);

            shifted.Should().Be(result);
        }
示例#32
0
        public static void IntersectionOnBothLinesFail(LineD a, LineD b, PointD result)
        {
            var intersection = a.IntersectionAndOnBothLines(b, true);

            intersection.HasValue.Should().BeFalse();
        }
示例#33
0
        private static bool FilterCheckIfTrackForCrossedOldTrack(LineD currentTrack, LineD track, Point currentPosition)
        {
            if (currentPosition == track.A)
            {
                return true;
            }

            if (currentTrack.IntersectionAndOnBothLines(track, true) != null)
            {
                return true;
            }

            if (track.IsOnLine(currentPosition, true))
            {
                return true;
            }

            if (currentTrack.IsOnLine(track.A, true))
            {
                return true;
            }

            return false;
        }
示例#34
0
        internal void ProjectileHit(Projectile attacker, Projectile target, bool lineCheck, ref LineD beam)
        {
            var hitEntity = HitEntityPool.Get();

            hitEntity.Info        = attacker.Info;
            hitEntity.EventType   = HitEntity.Type.Projectile;
            hitEntity.Hit         = true;
            hitEntity.Projectile  = target;
            hitEntity.SphereCheck = !lineCheck;
            hitEntity.PruneSphere = attacker.PruneSphere;
            double dist;

            Vector3D.Distance(ref beam.From, ref target.Position, out dist);
            hitEntity.HitDist = dist;

            hitEntity.Intersection = new LineD(attacker.LastPosition, attacker.LastPosition + (attacker.Info.Direction * dist));
            hitEntity.HitPos       = hitEntity.Intersection.To;

            attacker.Info.HitList.Add(hitEntity);
            attacker.FinalizeIntersection = true;
        }
示例#35
0
        /// <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;

            Debug.Assert(CurrentGrid != null);
            if (CurrentGrid == null)
            {
                return(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;
                VRage.Game.Models.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);
        }
示例#36
0
        /// <summary>
        /// Handles camera collisions with environment
        /// </summary>
        /// <param name="controlledEntity"></param>
        /// <param name="shakeActive"></param>
        /// <param name="headPosition"></param>
        /// <param name="headDirection"></param>
        /// <returns>False if no correct position was found</returns>
        private bool HandleIntersection(MyEntity controlledEntity, MyOrientedBoundingBoxD safeOBB, bool requireRaycast, bool shakeActive, Vector3D headPosition, Vector3 headDirection)
        {
            var line = new LineD(m_target, m_position);

            var      safeOBBLine = new LineD(line.From, line.From + line.Direction * 2 * safeOBB.HalfExtent.Length());
            Vector3D castStartSafe;

            {
                MyOrientedBoundingBoxD safeObbWithCollisionExtents = new MyOrientedBoundingBoxD(safeOBB.Center, safeOBB.HalfExtent + 2 * CAMERA_RADIUS, safeOBB.Orientation);
                double?safeIntersection = safeObbWithCollisionExtents.Intersects(ref safeOBBLine);
                if (!safeIntersection.HasValue)
                {
                    safeIntersection = safeOBB.HalfExtent.Length();
                }
                double safeDistance = safeIntersection.Value;
                castStartSafe = line.From + line.Direction * safeDistance;
            }

            {
                double?unsafeIntersection = safeOBB.Intersects(ref safeOBBLine);
                if (!requireRaycast && unsafeIntersection.HasValue)
                {
                    var castStartUnsafe = line.From + line.Direction * unsafeIntersection.Value;
                    var castEndUnsafe   = castStartSafe + line.Direction;
                    // short raycast, not causing problems with asteroids generating geometry
                    Physics.MyPhysics.CastRay(castStartUnsafe, castEndUnsafe, m_raycastList, MyPhysics.CollisionLayers.CharacterCollisionLayer);
                    if (!IsRaycastOK(m_raycastList))
                    {
                        return(false);
                    }
                }
            }

            if (requireRaycast)
            {
                // short raycast, not causing problems with asteroids generating geometry
                Physics.MyPhysics.CastRay(line.From, castStartSafe + line.Direction, m_raycastList, MyPhysics.CollisionLayers.CharacterCollisionLayer);
                if (!IsRaycastOK(m_raycastList))
                {
                    return(false);
                }
            }

            HkShape shape = new HkSphereShape(CAMERA_RADIUS);

            try
            {
                // small shape, not causing problems with asteroids generating geometry
                Physics.MyPhysics.GetPenetrationsShape(shape, ref castStartSafe, ref Quaternion.Identity, m_rigidList, MyPhysics.CollisionLayers.CharacterCollisionLayer);
                if (m_rigidList.Count > 0)
                {
                    bool sameGrid = false;
                    if (MySession.Static.ControlledEntity != null && m_rigidList[0].Body != null)
                    {
                        sameGrid = m_rigidList[0].GetCollisionEntity() == MySession.Static.ControlledEntity;
                    }

                    if (sameGrid)
                    {
                        castStartSafe += line.Direction;
                    }
                }

                var  shapeCastLine = new LineD(castStartSafe, m_position);
                uint steps         = 1;
                uint stepIdx       = 0;
                if (shapeCastLine.Length > SHAPE_CAST_STEP)
                {
                    steps = (uint)Math.Ceiling(shapeCastLine.Length / SHAPE_CAST_STEP);
                    if (steps >= SHAPE_CAST_MAX_STEP_COUNT)
                    {
                        steps = SHAPE_CAST_MAX_STEP_COUNT - 1;
                    }
                    stepIdx = m_updateCount % steps;
                    m_lastShapeCastDistance[stepIdx] = float.PositiveInfinity;

                    Vector3D step = shapeCastLine.Direction * (shapeCastLine.Length / steps);
                    shapeCastLine = new LineD(castStartSafe + stepIdx * step, castStartSafe + (stepIdx + 1) * step);
                }

                if (false)
                {
                    BoundingBoxD bbox = BoundingBoxD.CreateInvalid();
                    bbox.Include(new BoundingSphereD(shapeCastLine.From, CAMERA_RADIUS));
                    bbox.Include(new BoundingSphereD(shapeCastLine.To, CAMERA_RADIUS));
                    VRageRender.MyRenderProxy.DebugDrawAABB(bbox, Color.Crimson, 1f, 1f, true);
                }

                var matrix = MatrixD.CreateTranslation(shapeCastLine.From);
                HkContactPointData?cpd;
                if (controlledEntity.Physics != null && controlledEntity.GetPhysicsBody().CharacterProxy != null)
                {
                    cpd = MyPhysics.CastShapeReturnContactData(shapeCastLine.To, shape, ref matrix, MyPhysics.CollisionLayers.CharacterCollisionLayer, 0.0f);
                }
                else
                {
                    cpd = MyPhysics.CastShapeReturnContactData(shapeCastLine.To, shape, ref matrix, MyPhysics.CollisionLayers.DefaultCollisionLayer, 0.0f);
                }
                if (cpd.HasValue)
                {
                    var point = shapeCastLine.From + shapeCastLine.Direction * shapeCastLine.Length * cpd.Value.DistanceFraction;
                    m_lastShapeCastDistance[stepIdx] = (float)(castStartSafe - point).Length();
                }
                else
                {
                    m_lastShapeCastDistance[stepIdx] = float.PositiveInfinity;
                }


                float?dist = null;
                for (int i = 0; i < steps; ++i)
                {
                    if (m_lastShapeCastDistance[i] != float.PositiveInfinity)
                    {
                        dist = Math.Min(m_lastShapeCastDistance[i], dist ?? float.PositiveInfinity);
                    }
                }

                if (dist.HasValue)
                {
                    if (dist == 0.0f)
                    {
                        return(false);
                    }
                    else
                    {
                        m_positionSafe = castStartSafe + shapeCastLine.Direction * dist.Value;
                    }
                }
                else
                {
                    m_positionSafe = m_position;
                }
                return(true);
            }
            finally
            {
                shape.RemoveReference();
            }
        }
        private void DebugDrawVertexNames()
        {
            //VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(10, 0), "Voxel names searching", Color.Yellow, 0.5f);
            LineD line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * 500);
            MyIntersectionResultLineTriangleEx?intersection =
                MyEntities.GetIntersectionWithLine(ref line, MySession.Static.LocalCharacter, null, false, true, true,
                                                   VRage.Game.Components.IntersectionFlags.ALL_TRIANGLES, 0, false);


            if (intersection.HasValue)
            {
                if (intersection.Value.Entity is MyVoxelBase)
                {
                    MyVoxelBase voxels = (MyVoxelBase)intersection.Value.Entity;
                    Vector3D    point  = intersection.Value.IntersectionPointInWorldSpace;
                    if (intersection.Value.Entity is MyPlanet)
                    {
                        MyRenderProxy.DebugDrawText2D(new Vector2(20, 20), "Type: planet/moon", Color.Yellow,
                                                      DEBUG_SCALE);
                        MyRenderProxy.DebugDrawText2D(new Vector2(20, 30),
                                                      "Terrain: " + voxels.GetMaterialAt(ref point), Color.Yellow, DEBUG_SCALE);
                    }
                    else
                    {
                        MyRenderProxy.DebugDrawText2D(new Vector2(20, 20), "Type: asteroid", Color.Yellow,
                                                      DEBUG_SCALE);
                        MyRenderProxy.DebugDrawText2D(new Vector2(20, 30),
                                                      "Terrain: " + voxels.GetMaterialAt(ref point), Color.Yellow, DEBUG_SCALE);
                    }
                    MyRenderProxy.DebugDrawText2D(new Vector2(20, 40),
                                                  "Object size: " + voxels.SizeInMetres, Color.Yellow, DEBUG_SCALE);

                    //location

                    /*
                     * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(20, 50), "Location:", Color.Yellow, 0.5f);
                     * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(30, 60), "x " + Math.Round(point.X, 3).ToString(), Color.Yellow, 0.5f);
                     * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(30, 70), "y " + Math.Round(point.Y, 3).ToString(), Color.Yellow, 0.5f);
                     * VRageRender.MyRenderProxy.DebugDrawText2D(new Vector2(30, 80), "z " + Math.Round(point.Z, 3).ToString(), Color.Yellow, 0.5f);*/
                }
                else if (intersection.Value.Entity is MyCubeGrid)
                {
                    MyCubeGrid grid = (MyCubeGrid)intersection.Value.Entity;
                    MyRenderProxy.DebugDrawText2D(new Vector2(20, 20), "Detected grid object", Color.Yellow, DEBUG_SCALE);
                    MyRenderProxy.DebugDrawText2D(new Vector2(20, 30), String.Format("Grid name: {0}", grid.DisplayName), Color.Yellow,
                                                  DEBUG_SCALE);
                    int row = 4;

                    MyIntersectionResultLineTriangleEx?t;
                    MySlimBlock block;
                    if (grid.GetIntersectionWithLine(ref line, out t, out block) && t.HasValue && block != null)
                    {
                        if (block.FatBlock != null)
                        {
                            DebugDrawModelTextures(block.FatBlock, ref row);
                        }
                        else
                        {
                            DebugDrawBareBlockInfo(block, ref row);
                        }
                    }
                }
                else
                {
                    MyRenderProxy.DebugDrawText2D(new Vector2(20, 20), "Unknown object detected", Color.Yellow,
                                                  DEBUG_SCALE);
                }
            }
            else
            {
                MyRenderProxy.DebugDrawText2D(new Vector2(20, 20), "Nothing detected nearby", Color.Yellow, DEBUG_SCALE);
            }
        }
示例#38
0
        private static bool IsCrashWithObstacles(IEnumerable<LineD> obstacles, LineD? currentTrack)
        {
            if (!currentTrack.HasValue)
            {
                return false;
            }

            return obstacles.Any(obstacle => obstacle.IntersectionAndOnBothLines(currentTrack.Value, false) != null);
        }
示例#39
0
        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)
                {
                    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;
                }
            }
        }
示例#40
0
 public static void Intersection(LineD a, LineD b, PointD result)
 {
     var intersection = a.Intersection(b);
     intersection.X.Should().BeApproximately(result.X, 1e-7);
     intersection.Y.Should().BeApproximately(result.Y, 1e-7);
 }