// Calculates intersection of line with any triangleVertexes in this model instance. Closest intersection and intersected triangleVertexes will be returned. internal override bool GetIntersectionWithLine(ref LineD line, out MyIntersectionResultLineTriangleEx? t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { t = null; return false; //Matrix invWorld = Matrix.Invert(WorldMatrix); //Vector3 from = Vector3.Transform(line.From, invWorld); //Vector3 to = Vector3.Transform(line.To, invWorld); //Line lineLocal = new Line(from, to); //bool res = base.GetIntersectionWithLine(ref line, out t, flags); //if (res) //{ // var definition = MyDefinitionManager.Static.GetCubeBlockDefinition(new MyDefinitionId(MyObjectBuilderTypeEnum.Ladder)); // if (definition.ExcludedAreaForCamera != null) // { // foreach (var b in definition.ExcludedAreaForCamera) // { // if (b.Contains(t.Value.IntersectionPointInObjectSpace) == ContainmentType.Contains) // { // t = null; // return false; // } // } // } //} //return res; }
public Sandbox.Common.MyIntersectionResultLineTriangleEx? GetIntersectionWithLine(IMyEntity physObject, ref LineD line, ref MatrixD customInvMatrix, IntersectionFlags flags) { LineD lineInModelSpace = new LineD(Vector3D.Transform(line.From, ref customInvMatrix), Vector3D.Transform(line.To, ref customInvMatrix)); MyIntersectionResultLineTriangleEx? ret = m_rootNode.GetIntersectionWithLine(physObject, m_model, ref lineInModelSpace, null, flags); return ret; }
public static double GetShortestDistanceSquared(LineD line1, LineD line2) { Vector3D res1, res2; Vector3D dP = GetShortestVector(ref line1, ref line2, out res1, out res2); //return Math.Sqrt(dot(dP, dP)); return Vector3D.Dot(dP, dP); }
VRageMath.Vector3D?IMyCubeGrid.GetLineIntersectionExactAll(ref VRageMath.LineD line, out double distance, out IMySlimBlock intersectedBlock) { MySlimBlock block; var retVal = GetLineIntersectionExactAll(ref line, out distance, out block); intersectedBlock = block; return(retVal); }
// Calculates intersection of line with any triangleVertexes in this model. Closest intersection and intersected triangleVertexes will be returned. // This method is fast, it uses octree. public Sandbox.Common.MyIntersectionResultLineTriangleEx? GetIntersectionWithLine(IMyEntity physObject, ref LineD line, IntersectionFlags flags) { BoundingSphereD vol = physObject.WorldVolume; // Check if line intersects phys object's current bounding sphere, and if not, return 'no intersection' if (MyUtils.IsLineIntersectingBoundingSphere(ref line, ref vol) == false) return null; // Transform line into 'model instance' local/object space. Bounding box of a line is needed!! MatrixD worldInv = physObject.GetWorldMatrixNormalizedInv(); return GetIntersectionWithLine(physObject, ref line, ref worldInv, flags); }
// Calculates intersection of line with object. public override bool GetIntersectionWithLine(ref VRageMath.LineD line) { double?t = m_aabb.Intersects(new RayD(line.From, line.Direction)); if (t.HasValue && t.Value < line.Length && t.Value > 0) { return(true); } return(false); }
public unsafe void DoWork(WorkData workData = null) { try { //MyEntities.EntityCloseLock.AcquireShared(); if (m_renderObject == null) return; if (m_renderObject is MyRenderVoxelCell) { } Vector3 directionToSunNormalized = -MyRender.Sun.Direction; VisibleFromSun = false; var line2 = new LineD(m_renderObject.WorldVolume.Center, m_renderObject.WorldVolume.Center + directionToSunNormalized * MyShadowRenderer.SHADOW_MAX_OFFSET * 0.5f); var result2 = MyRender.GetAnyIntersectionWithLine(MyRender.ShadowPrunning, ref line2, m_renderObject, null, m_overlapList); VisibleFromSun |= (result2 == null); //if nothing hit, its visible from sun if (m_renderObject.FastCastShadowResolve) return; Vector3D* corners = stackalloc Vector3D[8]; m_renderObject.GetCorners(corners); for (int i = 0; i < 8; i++) { LineD line = new LineD(corners[i], corners[i] + directionToSunNormalized * MyShadowRenderer.SHADOW_MAX_OFFSET * 0.5f); var result = MyRender.GetAnyIntersectionWithLine(MyRender.ShadowPrunning, ref line, m_renderObject, null, m_overlapList); VisibleFromSun |= (result == null); if (VisibleFromSun) break; } if (!VisibleFromSun) { } } finally { /* if (m_renderObject != null) { m_renderObject.OnClose -= m_entity_OnMarkForClose; } */ // MyEntities.EntityCloseLock.ReleaseShared(); } }
public double?Intersects(ref LineD line) { if (this.Contains(ref line.From)) { RayD yd = new RayD(line.To, -line.Direction); double?nullable = this.Intersects(ref yd); if (!nullable.HasValue) { return(null); } double num = line.Length - nullable.Value; if (num < 0.0) { return(null); } if (num > line.Length) { return(null); } return(new double?(num)); } RayD ray = new RayD(line.From, line.Direction); double?nullable2 = this.Intersects(ref ray); if (!nullable2.HasValue) { return(null); } if (nullable2.Value < 0.0) { return(null); } if (nullable2.Value > line.Length) { return(null); } return(new double?(nullable2.Value)); }
public bool Intersects(LineD line, out double distance) { distance = 0f; double?f = Intersects(new RayD(line.From, line.Direction)); if (!f.HasValue) { return(false); } if (f.Value < 0) { return(false); } if (f.Value > line.Length) { return(false); } distance = f.Value; return(true); }
public MyIntersectionResultLineTriangleEx(MyIntersectionResultLineTriangle triangle, IMyEntity entity, ref LineD line) { Triangle = triangle; Entity = entity; InputLineInObjectSpace = line; NormalInObjectSpace = MyUtils.GetNormalVectorFromTriangle(ref Triangle.InputTriangle); IntersectionPointInObjectSpace = line.From + line.Direction * Triangle.Distance; if (Entity is IMyVoxelBase) { IntersectionPointInWorldSpace = (Vector3D)IntersectionPointInObjectSpace; NormalInWorldSpace = NormalInObjectSpace; // This will move intersection point from world space into voxel map's object space IntersectionPointInObjectSpace = IntersectionPointInObjectSpace - ((IMyVoxelBase)Entity).PositionLeftBottomCorner; } else { var worldMatrix = Entity.WorldMatrix; NormalInWorldSpace = (Vector3)MyUtils.GetTransformNormalNormalized((Vector3D)NormalInObjectSpace, ref worldMatrix); IntersectionPointInWorldSpace = Vector3D.Transform((Vector3D)IntersectionPointInObjectSpace, ref worldMatrix); } }
private void Hammer() { var IntersectionStart = MySector.MainCamera.Position; var IntersectionDirection = MySector.MainCamera.ForwardVector; LineD line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * 200); var m_tmpHitList = new List<MyPhysics.HitInfo>(); MyPhysics.CastRay(line.From, line.To, m_tmpHitList, MyPhysics.ObjectDetectionCollisionLayer); // Remove character hits. m_tmpHitList.RemoveAll(delegate(MyPhysics.HitInfo hit) { return (hit.HkHitInfo.Body.GetEntity() == MySession.ControlledEntity.Entity); }); if (m_tmpHitList.Count == 0) return; MyEntity closestEntity = null; MyPhysics.HitInfo closestHit = default(MyPhysics.HitInfo); foreach (var hit in m_tmpHitList) { if (hit.HkHitInfo.Body != null) { closestEntity = hit.HkHitInfo.Body.GetEntity() as MyEntity; closestHit = hit; break; } } if (closestEntity == null) return; HkdFractureImpactDetails details = HkdFractureImpactDetails.Create(); details.SetBreakingBody(closestEntity.Physics.RigidBody); details.SetContactPoint(closestEntity.Physics.WorldToCluster(closestHit.Position)); details.SetDestructionRadius(RADIUS); details.SetBreakingImpulse(Sandbox.MyDestructionConstants.STRENGTH * 10); if(HammerForce) details.SetParticleVelocity(-line.Direction * 20); details.SetParticlePosition(closestEntity.Physics.WorldToCluster(closestHit.Position)); details.SetParticleMass(1000000); //details.ZeroColidingParticleVelocity(); details.Flag = details.Flag | HkdFractureImpactDetails.Flags.FLAG_DONT_RECURSE; if (closestEntity.Physics.HavokWorld.DestructionWorld != null) { MyPhysics.FractureImpactDetails destruction = new MyPhysics.FractureImpactDetails(); destruction.Details = details; destruction.World = closestEntity.Physics.HavokWorld; destruction.Entity = closestEntity; MyPhysics.EnqueueDestruction(destruction); //closestGrid.Physics.HavokWorld.DestructionWorld.TriggerDestruction(ref details); } //details.RemoveReference(); }
public override bool GetIntersectionWithLine(ref LineD worldLine, out Vector3D? v, bool useCollisionModel = true, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { MyIntersectionResultLineTriangleEx? result; GetIntersectionWithLine(ref worldLine, out result); v = null; if (result != null) { v = result.Value.IntersectionPointInWorldSpace; return true; } return false; }
public void Include(ref LineD line) { Include(ref line.From); Include(ref line.To); }
public void PrefetchShapeOnRay(ref LineD ray) { int lod = 1; Vector3D localStart; MyVoxelCoordSystems.WorldPositionToLocalPosition(m_voxelMap.PositionLeftBottomCorner, ref ray.From, out localStart); Vector3D localEnd; MyVoxelCoordSystems.WorldPositionToLocalPosition(m_voxelMap.PositionLeftBottomCorner, ref ray.To, out localEnd); var shape = GetShape(lod); Debug.Assert(shape.Base.IsValid); if (m_cellsToGenerateBuffer.Length < 64) { m_cellsToGenerateBuffer = new Vector3I[64]; } int requiredCellsCount = shape.GetHitCellsInRange(localStart, localEnd, m_cellsToGenerateBuffer); if (requiredCellsCount == 0) { return; } ProfilerShort.Begin("Start Jobs"); for (int i = 0; i < requiredCellsCount; ++i) { if (m_workTracker.Exists(new MyCellCoord(lod, m_cellsToGenerateBuffer[i]))) continue; MyPrecalcJobPhysicsPrefetch.Start(new MyPrecalcJobPhysicsPrefetch.Args { TargetPhysics = this, Tracker = m_workTracker, GeometryCell = new MyCellCoord(lod, m_cellsToGenerateBuffer[i]), Storage = m_voxelMap.Storage }); } ProfilerShort.End(); }
public void OverlapAllLineSegment <T>(ref LineD line, List <MyLineSegmentOverlapResult <T> > elementsList) { OverlapAllLineSegment <T>(ref line, elementsList, 0); }
/// <summary> /// Obtain entity that player is aiming/looking at. /// </summary> public static MyEntity GetTargetEntity() { var line = new LineD(MySector.MainCamera.Position, MySector.MainCamera.Position + MySector.MainCamera.ForwardVector * 10000); m_tmpHitList.Clear(); MyPhysics.CastRay(line.From, line.To, m_tmpHitList, MyPhysics.CollisionLayers.DefaultCollisionLayer); // Remove character hits. m_tmpHitList.RemoveAll(delegate(MyPhysics.HitInfo hit) { return (hit.HkHitInfo.GetHitEntity() == MySession.Static.ControlledEntity.Entity); }); if (m_tmpHitList.Count == 0) return null; return m_tmpHitList[0].HkHitInfo.GetHitEntity() as MyEntity; }
// Calculates intersection of line with any triangleVertexes in this model instance. All intersections and intersected triangleVertexes will be returned. internal virtual bool GetIntersectionsWithLine(ref LineD line, List<MyIntersectionResultLineTriangleEx> result, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { MyModel collisionModel = Model; if (collisionModel != null) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyEntity.GetIntersectionWithLine on model"); collisionModel.GetTrianglePruningStructure().GetTrianglesIntersectingLine(this, ref line, flags, result); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); } return result.Count > 0; }
/// <summary> /// Finds closest object (grid or voxel map) for placement of blocks . /// </summary> public bool FindClosestPlacementObject(out MyCubeGrid closestGrid, out MyVoxelMap closestVoxelMap) { closestGrid = null; closestVoxelMap = null; if (MySession.ControlledEntity == null) return false; m_hitInfo = null; LineD line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * IntersectionDistance); MyPhysics.CastRay(line.From, line.To, m_tmpHitList, MyPhysics.ObjectDetectionCollisionLayer); // Remove character hits. m_tmpHitList.RemoveAll(delegate(MyPhysics.HitInfo hitInfo) { return (hitInfo.HkHitInfo.GetHitEntity() == MySession.ControlledEntity.Entity); }); if (m_tmpHitList.Count == 0) return false; var hit = m_tmpHitList[0]; closestGrid = hit.HkHitInfo.GetHitEntity() as MyCubeGrid; if (closestGrid != null) { m_hitInfo = hit; } if (MyFakes.ENABLE_BLOCK_PLACEMENT_ON_VOXEL) { closestVoxelMap = hit.HkHitInfo.GetHitEntity() as MyVoxelMap; if (closestVoxelMap != null) m_hitInfo = hit; } return closestGrid != null || closestVoxelMap != null; }
public void UpdatePlacement() { m_lastUpdate = MySession.Static.GameplayFrameCounter; m_hitInfo = null; m_closestGrid = null; m_closestVoxelMap = null; LineD line = new LineD(RayStart, RayStart + RayDirection * IntersectionDistance); MyPhysics.CastRay(line.From, line.To, m_tmpHitList, MyPhysics.CollisionLayers.ObjectDetectionCollisionLayer); // Remove character hits. m_tmpHitList.RemoveAll(delegate(MyPhysics.HitInfo hitInfo) { return (hitInfo.HkHitInfo.GetHitEntity() == MySession.Static.ControlledEntity.Entity); }); if (m_tmpHitList.Count == 0) return; var hit = m_tmpHitList[0]; m_closestGrid = hit.HkHitInfo.GetHitEntity() as MyCubeGrid; if (m_closestGrid != null) { //always assign otherwise the block will be completely inside/behind the grid m_hitInfo = hit; if (!ClosestGrid.Editable) m_closestGrid = null; return; } //if (MyFakes.ENABLE_BLOCK_PLACEMENT_ON_VOXEL) // TODO: check this MyFake to remove or what? //{ m_closestVoxelMap = hit.HkHitInfo.GetHitEntity() as MyVoxelBase; if (m_closestVoxelMap != null) m_hitInfo = hit; //} }
public static Vector3D GetShortestVector(ref LineD line1, ref LineD line2, out Vector3D res1, out Vector3D res2) { double EPS = 0.000001f; Vector3D delta21 = new Vector3D(); delta21.X = line1.To.X - line1.From.X; delta21.Y = line1.To.Y - line1.From.Y; delta21.Z = line1.To.Z - line1.From.Z; Vector3D delta41 = new Vector3D(); delta41.X = line2.To.X - line2.From.X; delta41.Y = line2.To.Y - line2.From.Y; delta41.Z = line2.To.Z - line2.From.Z; Vector3D delta13 = new Vector3D(); delta13.X = line1.From.X - line2.From.X; delta13.Y = line1.From.Y - line2.From.Y; delta13.Z = line1.From.Z - line2.From.Z; double a = Vector3D.Dot(delta21, delta21); double b = Vector3D.Dot(delta21, delta41); double c = Vector3D.Dot(delta41, delta41); double d = Vector3D.Dot(delta21, delta13); double e = Vector3D.Dot(delta41, delta13); double D = a * c - b * b; double sc, sN, sD = D; double tc, tN, tD = D; if (D < EPS) { sN = 0.0f; sD = 1.0f; tN = e; tD = c; } else { sN = (b * e - c * d); tN = (a * e - b * d); if (sN < 0.0) { sN = 0.0f; tN = e; tD = c; } else if (sN > sD) { sN = sD; tN = e + b; tD = c; } } if (tN < 0.0) { tN = 0.0f; if (-d < 0.0f) { sN = 0.0f; } else if (-d > a) { sN = sD; } else { sN = -d; sD = a; } } else if (tN > tD) { tN = tD; if ((-d + b) < 0.0) { sN = 0; } else if ((-d + b) > a) { sN = sD; } else { sN = (-d + b); sD = a; } } if (Math.Abs(sN) < EPS) { sc = 0.0f; } else { sc = sN / sD; } if (Math.Abs(tN) < EPS) { tc = 0.0f; } else { tc = tN / tD; } res1.X = (sc * delta21.X); res1.Y = (sc * delta21.Y); res1.Z = (sc * delta21.Z); Vector3D dP = new Vector3D(); dP.X = delta13.X - (tc * delta41.X) + res1.X; dP.Y = delta13.Y - (tc * delta41.Y) + res1.Y; dP.Z = delta13.Z - (tc * delta41.Z) + res1.Z; res2 = res1 - dP; return(dP); }
public static Vector3D GetShortestVector(ref LineD line1, ref LineD line2, out Vector3D res1, out Vector3D res2) { double num8; double num9; double num11; double num12; double num = 9.9999999747524271E-07; Vector3D vectord = new Vector3D { X = line1.To.X - line1.From.X, Y = line1.To.Y - line1.From.Y, Z = line1.To.Z - line1.From.Z }; Vector3D vectord2 = new Vector3D { X = line2.To.X - line2.From.X, Y = line2.To.Y - line2.From.Y, Z = line2.To.Z - line2.From.Z }; Vector3D vectord3 = new Vector3D { X = line1.From.X - line2.From.X, Y = line1.From.Y - line2.From.Y, Z = line1.From.Z - line2.From.Z }; double num2 = Vector3D.Dot(vectord, vectord); double num3 = Vector3D.Dot(vectord, vectord2); double num4 = Vector3D.Dot(vectord2, vectord2); double num5 = Vector3D.Dot(vectord, vectord3); double num6 = Vector3D.Dot(vectord2, vectord3); double num7 = (num2 * num4) - (num3 * num3); double num10 = num7; double num13 = num7; if (num7 < num) { num9 = 0.0; num10 = 1.0; num12 = num6; num13 = num4; } else { num9 = (num3 * num6) - (num4 * num5); num12 = (num2 * num6) - (num3 * num5); if (num9 < 0.0) { num9 = 0.0; num12 = num6; num13 = num4; } else if (num9 > num10) { num9 = num10; num12 = num6 + num3; num13 = num4; } } if (num12 < 0.0) { num12 = 0.0; if (-num5 < 0.0) { num9 = 0.0; } else if (-num5 > num2) { num9 = num10; } else { num9 = -num5; num10 = num2; } } else if (num12 > num13) { num12 = num13; if ((-num5 + num3) < 0.0) { num9 = 0.0; } else if ((-num5 + num3) > num2) { num9 = num10; } else { num9 = -num5 + num3; num10 = num2; } } if (Math.Abs(num9) < num) { num8 = 0.0; } else { num8 = num9 / num10; } if (Math.Abs(num12) < num) { num11 = 0.0; } else { num11 = num12 / num13; } res1.X = num8 * vectord.X; res1.Y = num8 * vectord.Y; res1.Z = num8 * vectord.Z; Vector3D vectord4 = new Vector3D { X = (vectord3.X - (num11 * vectord2.X)) + res1.X, Y = (vectord3.Y - (num11 * vectord2.Y)) + res1.Y, Z = (vectord3.Z - (num11 * vectord2.Z)) + res1.Z }; res2 = res1 - vectord4; return(vectord4); }
public bool Intersect(ref LineD line, out double t1, out double t2) { RayD ray = new RayD(line.From, line.Direction); return(this.Intersect(ref ray, out t1, out t2)); }
// Calculates intersection of line with object. public virtual bool GetIntersectionWithLine(ref LineD line, out Vector3D? v, bool useCollisionModel = true, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { v = null; MyModel collisionModel = Model; if (useCollisionModel) collisionModel = ModelCollision; if (collisionModel != null) { VRage.Game.Models.MyIntersectionResultLineTriangleEx? result = collisionModel.GetTrianglePruningStructure().GetIntersectionWithLine(this, ref line, flags); if (result != null) { v = result.Value.IntersectionPointInWorldSpace; return true; } } else Debug.Assert(false);//this should be overriden by child class if object has no model by default return false; }
// Calculates intersection of line with any triangleVertexes in this model instance. Closest intersection and intersected triangleVertexes will be returned. public virtual bool GetIntersectionWithLine(ref LineD line, out VRage.Game.Models.MyIntersectionResultLineTriangleEx? t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { bool ret = false; t = null; MyModel collisionModel = Model; if (collisionModel != null) { VRageRender.MyRenderProxy.GetRenderProfiler().StartProfilingBlock("MyEntity.GetIntersectionWithLine on model"); VRage.Game.Models.MyIntersectionResultLineTriangleEx? result = collisionModel.GetTrianglePruningStructure().GetIntersectionWithLine(this, ref line, flags); VRageRender.MyRenderProxy.GetRenderProfiler().EndProfilingBlock(); if (result != null) { t = result.Value; ret = true; } } return ret; }
/// <summary> /// Calculates exact intersection point (in uniform grid coordinates) of eye ray with the given grid of all cubes. /// Returns position of intersected object in uniform grid coordinates /// </summary> protected Vector3D? IntersectExact(MyCubeGrid grid, ref MatrixD inverseGridWorldMatrix, out Vector3D intersection, out MySlimBlock intersectedBlock) { intersection = Vector3D.Zero; var line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * IntersectionDistance); double distance; Vector3D? intersectedObjectPos = grid.GetLineIntersectionExactAll(ref line, out distance, out intersectedBlock); if (intersectedObjectPos != null) { Vector3D rayStart = Vector3D.Transform(IntersectionStart, inverseGridWorldMatrix); Vector3D rayDir = Vector3D.Normalize(Vector3D.TransformNormal(IntersectionDirection, inverseGridWorldMatrix)); intersection = rayStart + distance * rayDir; intersection *= 1.0f / grid.GridSize; } return intersectedObjectPos; }
// Calculates intersection of line with any bounding sphere in this model instance. Center of the bounding sphere will be returned. // It takes boundingSphereRadiusMultiplier argument which serves for extending the influence (radius) for interaction with line. public virtual Vector3D? GetIntersectionWithLineAndBoundingSphere(ref LineD line, float boundingSphereRadiusMultiplier) { if (Render.GetModel() == null) return null; BoundingSphereD vol = PositionComp.WorldVolume; vol.Radius *= boundingSphereRadiusMultiplier; // Check if line intersects phys object's current bounding sphere, and if not, return 'no intersection' if (!MyUtils.IsLineIntersectingBoundingSphere(ref line, ref vol)) return null; return vol.Center; }
public LineD GetDamageCapsuleLine(FlameInfo info) { var world = Matrix.CreateFromDir(Vector3.TransformNormal(info.Direction, WorldMatrix)); var halfLenght = ThrustLengthRand * info.Radius / 2; halfLenght *= BlockDefinition.FlameDamageLengthScale; var position = Vector3D.Transform(info.Position, WorldMatrix); if (halfLenght > info.Radius) return new LineD(position - world.Forward * (info.Radius), position + world.Forward * (2 * halfLenght - info.Radius)); else { var l = new LineD(position + world.Forward * halfLenght, position + world.Forward * halfLenght); l.Direction = world.Forward; return l; } }
public static bool TryRayCastGrid(ref LineD worldRay, out MyCubeGrid hitGrid, out Vector3D worldHitPos) { try { MyPhysics.CastRay(worldRay.From, worldRay.To, m_tmpHitList); foreach (var hit in m_tmpHitList) { var cubeGrid = hit.HkHitInfo.GetHitEntity() as MyCubeGrid; if (cubeGrid == null) continue; worldHitPos = hit.Position; VRageRender.MyRenderProxy.DebugDrawAABB(new BoundingBoxD(worldHitPos - 0.01, worldHitPos + 0.01), Color.Wheat.ToVector3(), 1f, 1f, true); hitGrid = cubeGrid; return true; } hitGrid = default(MyCubeGrid); worldHitPos = default(Vector3D); return false; } finally { m_tmpHitList.Clear(); } }
public void Include(ref LineD line) { this.Include(ref line.From); this.Include(ref line.To); }
public MyCubeGrid FindClosestGrid() { LineD line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * IntersectionDistance); m_tmpHitList.Clear(); MyPhysics.CastRay(line.From, line.To, m_tmpHitList, MyPhysics.ObjectDetectionCollisionLayer); // Remove character hits. m_tmpHitList.RemoveAll(delegate(MyPhysics.HitInfo hit) { return (hit.HkHitInfo.GetHitEntity() == MySession.ControlledEntity.Entity); }); if (m_tmpHitList.Count == 0) return null; MyCubeGrid closestGrid = m_tmpHitList[0].HkHitInfo.GetHitEntity() as MyCubeGrid; return closestGrid; }
Vector3D GetAimedPointFromHead() { MatrixD headMatrix = GetHeadMatrix(false); var endPoint = headMatrix.Translation + headMatrix.Forward * 25000; // Same optimization as the one in GetAimedPointFromCamera. return endPoint; if (MySession.Static.ControlledEntity == this) { LineD line = new LineD(headMatrix.Translation, endPoint); //Line line = new Line(MySector.MainCamera.Position, MySector.MainCamera.Position + MySector.MainCamera.ForwardVector * 1000); var intersection = MyEntities.GetIntersectionWithLine(ref line, this, (MyEntity)m_currentWeapon); if (intersection.HasValue) { return intersection.Value.IntersectionPointInWorldSpace; } else { return (Vector3D)line.To; } } else { return endPoint; } }
protected Vector3I? IntersectCubes(MyCubeGrid grid, out double distance) { distance = float.MaxValue; var line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * IntersectionDistance); Vector3I position = Vector3I.Zero; double dstSqr = double.MaxValue; if (grid.GetLineIntersectionExactGrid(ref line, ref position, ref dstSqr)) { distance = Math.Sqrt(dstSqr); return position; } return null; }
public override bool GetIntersectionWithLine(ref LineD line, out VRage.Game.Models.MyIntersectionResultLineTriangleEx? tri, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { bool ret = GetIntersectionWithLine(ref line, ref m_hitInfoTmp, flags); tri = m_hitInfoTmp.Triangle; return ret; }
/// <summary> /// Calculates exact intersection point (in uniform grid coordinates) from stored havok's hit info object obtained during FindClosest grid. /// Returns position of intersected object in uniform grid coordinates. /// </summary> protected Vector3D? GetIntersectedBlockData(ref MatrixD inverseGridWorldMatrix, out Vector3D intersection, out MySlimBlock intersectedBlock, out ushort? compoundBlockId) { Debug.Assert(m_hitInfo != null); //Debug.Assert(m_hitInfo.Value.HkHitInfo.GetEntity() == CurrentGrid); intersection = Vector3D.Zero; intersectedBlock = null; compoundBlockId = null; double distance = double.MaxValue; Vector3D? intersectedObjectPos = null; var line = new LineD(IntersectionStart, IntersectionStart + IntersectionDirection * IntersectionDistance); Vector3I position = Vector3I.Zero; if (!CurrentGrid.GetLineIntersectionExactGrid(ref line, ref position, ref distance, m_hitInfo.Value)) return null; distance = Math.Sqrt(distance); intersectedObjectPos = position; intersectedBlock = CurrentGrid.GetCubeBlock(position); if (intersectedBlock == null) return null; // Compound block - get index of internal block for removing if (intersectedBlock.FatBlock is MyCompoundCubeBlock) { MyCompoundCubeBlock compoundBlock = intersectedBlock.FatBlock as MyCompoundCubeBlock; ushort? idInCompound = null; ushort blockId; MyIntersectionResultLineTriangleEx? triIntersection; if (compoundBlock.GetIntersectionWithLine(ref line, out triIntersection, out blockId)) idInCompound = blockId; else if (compoundBlock.GetBlocksCount() == 1) // If not intersecting with any internal block and there is only one then set the index to it idInCompound = compoundBlock.GetBlockId(compoundBlock.GetBlocks()[0]); compoundBlockId = idInCompound; } Debug.Assert(intersectedObjectPos != null); Vector3D rayStart = Vector3D.Transform(IntersectionStart, inverseGridWorldMatrix); Vector3D rayDir = Vector3D.Normalize(Vector3D.TransformNormal(IntersectionDirection, inverseGridWorldMatrix)); intersection = rayStart + distance * rayDir; intersection *= 1.0f / CurrentGrid.GridSize; return intersectedObjectPos; }
/// <summary> /// Returns closest hit from line start position. /// </summary> public bool GetIntersectionWithLine(ref LineD line, ref MyCharacterHitInfo info, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { // TODO: This now uses caspule of physics rigid body on the character, it needs to be changed to ragdoll // Currently this approach will be used to support Characters with different skeleton than humanoid if (info == null) info = new MyCharacterHitInfo(); info.Reset(); bool capsulesReady = UpdateCapsuleBones(); if (!capsulesReady) return false; double closestDistanceToHit = double.MaxValue; Vector3D hitPosition = Vector3D.Zero; Vector3D hitPosition2 = Vector3D.Zero; Vector3 hitNormal = Vector3.Zero; Vector3 hitNormal2 = Vector3.Zero; int capsuleIndex = -1; for (int i = 0; i < m_bodyCapsules.Length; i++) { CapsuleD capsule = m_bodyCapsules[i]; if (capsule.Intersect(line, ref hitPosition, ref hitPosition2, ref hitNormal, ref hitNormal2)) { double distanceToHit = Vector3.Distance(hitPosition, line.From); if (distanceToHit >= closestDistanceToHit) continue; closestDistanceToHit = distanceToHit; capsuleIndex = i; } } if (capsuleIndex != -1) { Matrix worldMatrix = PositionComp.WorldMatrix; int boneIndex = FindBestBone(capsuleIndex, ref hitPosition, ref worldMatrix); // Transform line to model static position and compute accurate collision there // 1. Transform line in local coordinates (used later) Matrix worldMatrixInv = PositionComp.WorldMatrixNormalizedInv; Vector3 fromTrans = Vector3.Transform(line.From, ref worldMatrixInv); Vector3 toTrans = Vector3.Transform(line.To, ref worldMatrixInv); LineD lineLocal = new LineD(fromTrans, toTrans); // 2. Transform line to to bone pose in binding position var bone = AnimationController.CharacterBones[boneIndex]; bone.ComputeAbsoluteTransform(); Matrix boneAbsTrans = bone.AbsoluteTransform; Matrix skinTransform = bone.SkinTransform; Matrix boneTrans = skinTransform * boneAbsTrans; Matrix invBoneTrans = Matrix.Invert(boneTrans); fromTrans = Vector3.Transform(fromTrans, ref invBoneTrans); toTrans = Vector3.Transform(toTrans, ref invBoneTrans); // 3. Move back line to world coordinates LineD lineTransWorld = new LineD(Vector3.Transform(fromTrans, ref worldMatrix), Vector3.Transform(toTrans, ref worldMatrix)); MyIntersectionResultLineTriangleEx? triangle_; bool success = base.GetIntersectionWithLine(ref lineTransWorld, out triangle_, flags); if (success) { MyIntersectionResultLineTriangleEx triangle = triangle_.Value; info.CapsuleIndex = capsuleIndex; info.BoneIndex = boneIndex; info.Capsule = m_bodyCapsules[info.CapsuleIndex]; info.HitHead = info.CapsuleIndex == 0 && m_bodyCapsules.Length > 1; info.HitPositionBindingPose = triangle.IntersectionPointInObjectSpace; info.HitNormalBindingPose = triangle.NormalInObjectSpace; // 4. Move intersection from binding to dynamic pose MyTriangle_Vertexes vertices = new MyTriangle_Vertexes(); vertices.Vertex0 = Vector3.Transform(triangle.Triangle.InputTriangle.Vertex0, ref boneTrans); vertices.Vertex1 = Vector3.Transform(triangle.Triangle.InputTriangle.Vertex1, ref boneTrans); vertices.Vertex2 = Vector3.Transform(triangle.Triangle.InputTriangle.Vertex2, ref boneTrans); Vector3 triangleNormal = Vector3.TransformNormal(triangle.Triangle.InputTriangleNormal, boneTrans); MyIntersectionResultLineTriangle triraw = new MyIntersectionResultLineTriangle(ref vertices, ref triangleNormal, triangle.Triangle.Distance); Vector3 intersectionLocal = Vector3.Transform(triangle.IntersectionPointInObjectSpace, ref boneTrans); Vector3 normalLocal = Vector3.TransformNormal(triangle.NormalInObjectSpace, boneTrans); // 5. Store results triangle = new MyIntersectionResultLineTriangleEx(); triangle.Triangle = triraw; triangle.IntersectionPointInObjectSpace = intersectionLocal; triangle.NormalInObjectSpace = normalLocal; triangle.IntersectionPointInWorldSpace = Vector3.Transform(intersectionLocal, ref worldMatrix); triangle.NormalInWorldSpace = Vector3.TransformNormal(normalLocal, worldMatrix); triangle.InputLineInObjectSpace = lineLocal; info.Triangle = triangle; if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW) { MyRenderProxy.DebugClearPersistentMessages(); MyRenderProxy.DebugDrawCapsule(info.Capsule.P0, info.Capsule.P1, info.Capsule.Radius, Color.Aqua, false, persistent: true); Vector3 p0Local = Vector3.Transform(info.Capsule.P0, ref worldMatrixInv); Vector3 p1Local = Vector3.Transform(info.Capsule.P1, ref worldMatrixInv); Vector3 p0LocalTrans = Vector3.Transform(p0Local, ref invBoneTrans); Vector3 p1LocalTrans = Vector3.Transform(p1Local, ref invBoneTrans); MyRenderProxy.DebugDrawCapsule(Vector3.Transform(p0LocalTrans, ref worldMatrix), Vector3.Transform(p1LocalTrans, ref worldMatrix), info.Capsule.Radius, Color.Brown, false, persistent: true); MyRenderProxy.DebugDrawLine3D(line.From, line.To, Color.Blue, Color.Red, false, true); MyRenderProxy.DebugDrawLine3D(lineTransWorld.From, lineTransWorld.To, Color.Green, Color.Yellow, false, true); MyRenderProxy.DebugDrawSphere(triangle.IntersectionPointInWorldSpace, 0.02f, Color.Red, 1, false, persistent: true); MyRenderProxy.DebugDrawAxis((MatrixD)boneTrans * WorldMatrix, 0.1f, false, true, true); } return true; } } return false; }
private void DamageGrid(FlameInfo flameInfo, LineD l, MyCubeGrid grid) { HkSphereShape sph = new HkSphereShape(flameInfo.Radius * BlockDefinition.FlameDamageLengthScale); var transform = MatrixD.CreateWorld(l.From, Vector3.Forward, Vector3.Up); var hit = MyPhysics.CastShapeReturnPoint(l.To, sph, ref transform, (int)MyPhysics.DefaultCollisionLayer, 0.05f); sph.Base.RemoveReference(); if (hit.HasValue) { //MyRenderProxy.DebugDrawSphere(hit.Value, 0.1f, Color.Green.ToVector3(), 1, true); MyPhysics.CastRay(hit.Value - l.Direction * 0.1f, hit.Value + l.Direction * 0.1f, m_gridRayCastLst, MyPhysics.ObjectDetectionCollisionLayer); if ((m_gridRayCastLst.Count == 0 || m_gridRayCastLst[0].HkHitInfo.GetHitEntity() != grid) && grid == CubeGrid) { m_gridRayCastLst.Clear(); return; } m_gridRayCastLst.Clear(); var block = grid.GetCubeBlock(grid.WorldToGridInteger(hit.Value)); //if (block != this.SlimBlock) { //MyRenderProxy.DebugDrawSphere(hit.Value, 0.1f, Color.Green.ToVector3(), 1, true); var invWorld = grid.PositionComp.GetWorldMatrixNormalizedInv(); var gridPos = Vector3D.Transform(hit.Value, invWorld); var gridDir = Vector3D.TransformNormal(l.Direction, invWorld); if (block != null) if (block.FatBlock != this && (CubeGrid.GridSizeEnum == MyCubeSize.Large || block.BlockDefinition.DeformationRatio > 0.25)) { block.DoDamage(30 * BlockDefinition.FlameDamage, MyDamageType.Environment, attackerId: EntityId); } var areaPlanar = 0.5f * flameInfo.Radius * CubeGrid.GridSize; var areaVertical = 0.5f * CubeGrid.GridSize; grid.Physics.ApplyDeformation(BlockDefinition.FlameDamage, areaPlanar, areaVertical, gridPos, gridDir, MyDamageType.Environment, CubeGrid.GridSizeEnum == MyCubeSize.Small ? 0.1f : 0, attackerId: EntityId); } } }
private void TestPath() { using (m_lock.AcquireExclusiveUsing()) { if (m_grid.MarkedForClose) { CurrentState = State.BlockedPath; m_cells.Clear(); return; } if (CurrentState == State.None) { m_cells.Clear(); return; } //MyGameTimer timer = new MyGameTimer(); if (m_cells.Count != 0) { Vector3D worldPos = m_grid.GridIntegerToWorld(m_cells.Dequeue()); LineD worldLine = new LineD(worldPos, worldPos + m_displacement); //var createLine = timer.Elapsed; //timer = new MyGameTimer(); Vector3D? contact; if (RayCast.RayCastVoxel(ClosestPlanet, worldLine, out contact)) { //var intersect = timer.Elapsed; m_logger.debugLog("Intersected line: " + worldLine.From + " to " + worldLine.To + ", at " + contact, Logger.severity.DEBUG); //m_logger.debugLog("Intersected line: " + worldLine.From + " to " + worldLine.To + ", at " + contact + ", createLine: " + createLine.ToPrettySeconds() + ", intersect: " + intersect.ToPrettySeconds(), "TestPath()", Logger.severity.DEBUG); ObstructionPoint = contact.Value; CurrentState = State.BlockedPath; m_cells.Clear(); return; } //else //{ // var intersect = timer.Elapsed; // m_logger.debugLog("no intersection with line: " + worldLine.From + " to " + worldLine.To + ", createLine: " + createLine.ToPrettySeconds() + ", intersect: " + intersect.ToPrettySeconds(), "TestPath()", Logger.severity.TRACE); //} DoTests.Enqueue(TestPath); } else { m_logger.debugLog("finished, clear", Logger.severity.DEBUG); CurrentState = State.Clear; } } }
public override void UpdateBeforeSimulation10() { base.UpdateBeforeSimulation10(); if (!CheckUnobstructed()) { if (SafeConstraint != null) { RemoveConstraintInBoth(); } return; } if (SafeConstraint != null) { bool staticOk = this.CubeGrid.IsStatic || !m_other.CubeGrid.IsStatic; if (!staticOk || !IsWorking || !m_other.IsWorking || !IsWithinWorldLimits) return; Debug.Assert(!m_other.CubeGrid.MarkedForClose && !CubeGrid.MarkedForClose); var mergeBlockDefinition = this.BlockDefinition as MyMergeBlockDefinition; float maxStrength = mergeBlockDefinition != null ? mergeBlockDefinition.Strength : 0.1f; float dist = (float)(WorldMatrix.Translation - m_other.WorldMatrix.Translation).Length() - CubeGrid.GridSize; if (dist > CubeGrid.GridSize * 3) { RemoveConstraintInBoth(); return; } MergeData data = new MergeData(); CalculateMergeData(ref data); (m_constraint.ConstraintData as HkMalleableConstraintData).Strength = data.ConstraintStrength; if (data.PositionOk && data.AxisOk && data.RotationOk) { if (m_frameCounter++ >= 3) { Vector3I gridOffset = CalculateOtherGridOffset(); Vector3I otherGridOffset = m_other.CalculateOtherGridOffset(); bool canMerge = this.CubeGrid.CanMergeCubes(m_other.CubeGrid, gridOffset); if (!canMerge) { if (this.CubeGrid.GridSystems.ControlSystem.IsLocallyControlled || m_other.CubeGrid.GridSystems.ControlSystem.IsLocallyControlled) MyHud.Notifications.Add(MyNotificationSingletons.ObstructingBlockDuringMerge); return; } var handle = BeforeMerge; if (handle != null) BeforeMerge(); if (Sync.IsServer) { foreach (var block in CubeGrid.GetBlocks()) { var mergeBlock = block.FatBlock as MyShipMergeBlock; if (mergeBlock != null && mergeBlock != this && mergeBlock.InConstraint) (block.FatBlock as MyShipMergeBlock).RemoveConstraintInBoth(); } MyCubeGrid mergedGrid = this.CubeGrid.MergeGrid_MergeBlock(m_other.CubeGrid, gridOffset); if (mergedGrid == null) { mergedGrid = m_other.CubeGrid.MergeGrid_MergeBlock(this.CubeGrid, otherGridOffset); } Debug.Assert(mergedGrid != null); RemoveConstraintInBoth(); } } } else { m_frameCounter = 0; } return; } foreach (var other in m_gridList) { if (other.MarkedForClose) continue; Vector3I pos = Vector3I.Zero; double dist = double.MaxValue; LineD l = new LineD(Physics.ClusterToWorld(Physics.RigidBody.Position), Physics.ClusterToWorld(Physics.RigidBody.Position) + GetMergeNormalWorld()); if (other.GetLineIntersectionExactGrid(ref l, ref pos, ref dist)) { var block = other.GetCubeBlock(pos).FatBlock as MyShipMergeBlock; if(block == null) { continue; } if (block.InConstraint || !block.IsWorking || !block.CheckUnobstructed() || block.GetMergeNormalWorld().Dot(GetMergeNormalWorld()) > 0.0f) return; if (!block.FriendlyWithBlock(this)) return; CreateConstraint(other, block); NeedsUpdate |= MyEntityUpdateEnum.BEFORE_NEXT_FRAME; m_updateBeforeFlags |= UpdateBeforeFlags.EnableConstraint; break; } } }
// Method finds intersection with line and any voxel triangleVertexes in this voxel map. Closes intersection is returned. internal override bool GetIntersectionWithLine(ref LineD worldLine, out MyIntersectionResultLineTriangleEx? t, IntersectionFlags flags = IntersectionFlags.ALL_TRIANGLES) { t = null; double intersectionDistance; LineD line = (LineD)worldLine; if (!PositionComp.WorldAABB.Intersects(line, out intersectionDistance)) return false; ProfilerShort.Begin("VoxelMap.LineIntersection"); try { Line localLine = new Line(worldLine.From - PositionLeftBottomCorner, worldLine.To - PositionLeftBottomCorner, true); MyIntersectionResultLineTriangle tmpResult; if (Storage.Geometry.Intersect(ref localLine, out tmpResult, flags)) { t = new MyIntersectionResultLineTriangleEx(tmpResult, this, ref worldLine); var tmp = t.Value.IntersectionPointInWorldSpace; tmp.AssertIsValid(); return true; } else { t = null; return false; } } finally { ProfilerShort.End(); } }
private void ComputeSunAngle() { m_angleToSun = Vector3.Dot(Vector3.Transform(m_panelOrientation, m_solarBlock.WorldMatrix.GetOrientation()), MySector.DirectionToSunNormalized); // If the sun is on the backside of the panel, and we're not two-sided, OR the block not functional, just stop processing here if ((m_angleToSun < 0 && !m_isTwoSided) || !m_solarBlock.IsFunctional) { return; } m_currentPivot %= 8; MatrixD rot = m_solarBlock.WorldMatrix.GetOrientation(); float scale = (float)m_solarBlock.WorldMatrix.Forward.Dot(Vector3.Transform(m_panelOrientation, rot)); float unit = m_solarBlock.BlockDefinition.CubeSize == MyCubeSize.Large ? 2.5f : 0.5f; Vector3D pivot = m_solarBlock.WorldMatrix.Translation; pivot += ((m_currentPivot % 4 - 1.5f) * unit * scale * (m_solarBlock.BlockDefinition.Size.X / 4f)) * m_solarBlock.WorldMatrix.Left; pivot += ((m_currentPivot / 4 - 0.5f) * unit * scale * (m_solarBlock.BlockDefinition.Size.Y / 2f)) * m_solarBlock.WorldMatrix.Up; pivot += unit * scale * (m_solarBlock.BlockDefinition.Size.Z / 2f) * Vector3.Transform(m_panelOrientation, rot) * m_panelOffset; LineD l = new LineD(pivot + MySector.DirectionToSunNormalized * 100, pivot + MySector.DirectionToSunNormalized * m_solarBlock.CubeGrid.GridSize / 4); //shadows are drawn only 1000m MyPhysics.CastRay(l.From, l.To, m_hitList, MyPhysics.CollisionLayers.DefaultCollisionLayer); m_isPivotInSun[m_currentPivot] = true; foreach (var hit in m_hitList) { var ent = hit.HkHitInfo.GetHitEntity(); if (ent != m_solarBlock.CubeGrid) { m_isPivotInSun[m_currentPivot] = false; break; } else { var grid = ent as MyCubeGrid; var pos = grid.RayCastBlocks(l.From, l.To); if (pos.HasValue && grid.GetCubeBlock(pos.Value) != m_solarBlock.SlimBlock) { m_isPivotInSun[m_currentPivot] = false; break; } } } m_pivotsInSun = 0; foreach (bool p in m_isPivotInSun) { if (p) m_pivotsInSun++; } }
VRageMath.Vector3?IMyEntity.GetIntersectionWithLineAndBoundingSphere(ref VRageMath.LineD line, float boundingSphereRadiusMultiplier) { return(GetIntersectionWithLineAndBoundingSphere(ref line, boundingSphereRadiusMultiplier)); }