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); }
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); }
/// <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); }
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); } } }
/// <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()); }
/// <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(); }
/// <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); }
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); } } } }
/// <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); }
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); }
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); } }
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); }
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); } } }
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 }
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); }
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); }
public MyIntersectionResultLineTriangleEx(MyIntersectionResultLineTriangle triangle, IMyEntity entity, ref LineD line) { Triangle = triangle; Entity = entity; InputLineInObjectSpace = line; NormalInObjectSpace = MyUtils.GetNormalVectorFromTriangle(ref Triangle.InputTriangle); IntersectionPointInObjectSpace = line.From + line.Direction * Triangle.Distance; if (Entity is IMyVoxelBase) { IntersectionPointInWorldSpace = (Vector3D)IntersectionPointInObjectSpace; NormalInWorldSpace = NormalInObjectSpace; // This will move intersection point from world space into voxel map's object space IntersectionPointInObjectSpace = IntersectionPointInObjectSpace - ((IMyVoxelBase)Entity).PositionLeftBottomCorner; } else { var worldMatrix = Entity.WorldMatrix; NormalInWorldSpace = (Vector3)MyUtils.GetTransformNormalNormalized((Vector3D)NormalInObjectSpace, ref worldMatrix); IntersectionPointInWorldSpace = Vector3D.Transform((Vector3D)IntersectionPointInObjectSpace, ref worldMatrix); } }
public 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); }
// 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(); } }
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); } }
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(); }
public void GetTrianglesIntersectingLine(IMyEntity entity, ref LineD line, ref MatrixD customInvMatrix, IntersectionFlags flags, List <MyIntersectionResultLineTriangleEx> result) { System.Diagnostics.Debug.Assert(false, "Not implemented"); }
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); }
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); } }
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; }
bool IMyCubeGrid.GetLineIntersectionExactGrid(ref LineD line, ref Vector3I position, ref double distanceSquared) { return(GetLineIntersectionExactGrid(ref line, ref position, ref distanceSquared)); }
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); }
public static void Shift(LineD start, double shift, LineD result) { var shifted = start.ShiftOrthoToDirection(shift); shifted.Should().Be(result); }
public static void IntersectionOnBothLinesFail(LineD a, LineD b, PointD result) { var intersection = a.IntersectionAndOnBothLines(b, true); intersection.HasValue.Should().BeFalse(); }
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; }
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; }
/// <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); }
/// <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); } }
private static bool IsCrashWithObstacles(IEnumerable<LineD> obstacles, LineD? currentTrack) { if (!currentTrack.HasValue) { return false; } return obstacles.Any(obstacle => obstacle.IntersectionAndOnBothLines(currentTrack.Value, false) != null); }
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; } } }
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); }