/// <summary> /// Raycasts and stops at the first hit. /// </summary> /// <param name="simulation">Physics simulation.</param> /// <param name="raySegment">Ray.</param> /// <returns>The hit results.</returns> /// <exception cref="ArgumentNullException">If the simulation argument is null.</exception> public static HitResult Raycast(this Simulation simulation, RaySegment raySegment) { if (simulation == null) { throw new ArgumentNullException(nameof(simulation)); } return(simulation.Raycast(raySegment.Start, raySegment.End)); }
/// <summary> /// Raycasts penetrating any shape the ray encounters. /// </summary> /// <param name="simulation">Physics simulation.</param> /// <param name="raySegment">Ray.</param> /// <param name="resultsOutput">The list to fill with results.</param> /// <exception cref="ArgumentNullException">If the simulation argument is null.</exception> public static void RaycastPenetrating(this Simulation simulation, RaySegment raySegment, IList <HitResult> resultsOutput) { if (simulation == null) { throw new ArgumentNullException(nameof(simulation)); } simulation.RaycastPenetrating(raySegment.Start, raySegment.End, resultsOutput); }
/// <summary> /// Raycasts and stops at the first hit. /// </summary> /// <param name="simulation">Physics simulation.</param> /// <param name="raySegment">Ray.</param> /// <param name="collisionFilterGroups">The collision group of this shape sweep</param> /// <param name="collisionFilterGroupFlags">The collision group that this shape sweep can collide with</param> /// <returns>The hit results.</returns> /// <exception cref="ArgumentNullException">If the simulation argument is null.</exception> public static HitResult Raycast(this Simulation simulation, RaySegment raySegment, CollisionFilterGroups collisionFilterGroups, CollisionFilterGroupFlags collisionFilterGroupFlags) { if (simulation == null) { throw new ArgumentNullException(nameof(simulation)); } return(simulation.Raycast(raySegment.Start, raySegment.End, collisionFilterGroups, collisionFilterGroupFlags)); }
/// <summary> /// Raycasts penetrating any shape the ray encounters. /// Filtering by CollisionGroup /// </summary> /// <param name="simulation">Physics simulation.</param> /// <param name="raySegment">Ray.</param> /// <param name="resultsOutput">The list to fill with results.</param> /// <param name="collisionFilterGroups">The collision group of this shape sweep</param> /// <param name="collisionFilterGroupFlags">The collision group that this shape sweep can collide with</param> /// <exception cref="ArgumentNullException">If the simulation argument is null.</exception> public static void RaycastPenetrating(this Simulation simulation, RaySegment raySegment, IList <HitResult> resultsOutput, CollisionFilterGroups collisionFilterGroups, CollisionFilterGroupFlags collisionFilterGroupFlags) { if (simulation == null) { throw new ArgumentNullException(nameof(simulation)); } simulation.RaycastPenetrating(raySegment.Start, raySegment.End, resultsOutput, collisionFilterGroups, collisionFilterGroupFlags); }
public static DefaultBulletSegment Allocate(int serverTime, RaySegment raySegment, IBulletEntityAgent bulletEntityAgent) { var ret = ObjectAllocatorHolder <DefaultBulletSegment> .Allocate(); ret.ServerTime = serverTime; ret.RaySegment = raySegment; ret.BulletEntityAgent = bulletEntityAgent; return(ret); }
public RaysSegmentsDrawable(RaySegmentsShape shape) { this.shape = shape; this.array = new Vector2D[shape.Segments.Length * 2]; for (int index = 0; index < shape.Segments.Length; ++index) { RaySegment segment = shape.Segments[index]; Ray ray = segment.RayInstance; array[index * 2] = ray.Origin; array[index * 2 + 1] = ray.Origin + ray.Direction * segment.Length; } }
public void LineAim(Vector2 realPos, object whoShoots, Vector2 origin, float barrelLenght, float reach) { RaySegment.Start = origin; RaySegment.End = realPos; RayEnlonged = new LineSegmentF(RaySegment.Start, RaySegment.Start + RaySegment.NormalizedWithZeroSolution() * reach); RayBarrel.Start = origin; RayBarrel.End = RaySegment.Start + RaySegment.NormalizedWithZeroSolution() * barrelLenght; RayDestination = CompareF.RaySegmentCalc(origin, RayEnlonged, whoShoots); }
public static DisposeCallback BasicDemoSetup(DemoOpenInfo info) { DisposeCallback dispose = null; IShape bombShape = ShapeFactory.CreateSprite(Cache <SurfacePolygons> .GetItem("rocket.png"), 2, 16, 3); dispose += DemoHelper.RegisterBombLaunching(info, bombShape, 120); dispose += DemoHelper.RegisterMousePicking(info); dispose += DemoHelper.RegisterBodyStreamSpawning(info, new Body(new PhysicsState(), ParticleShape.Default, 1, Coefficients.Duplicate(), new Lifespan(.5f)), 2, 120, 1000, Key.B); dispose += DemoHelper.RegisterMaintainSpawning(info, SdlDotNet.Input.Key.N, delegate(Vector2D position) { ExplosionLogic result = new ExplosionLogic(position, Vector2D.Zero, 9000, .1f, 600, new Lifespan(.25f)); info.Scene.Engine.AddLogic(result); return(result); }); List <RaySegment> segments = new List <RaySegment>(); for (Scalar angle = 0; angle < MathHelper.PiOver2; angle += .05f) { RaySegment seg = new RaySegment(); seg.Length = 500; seg.RayInstance = new Ray(Vector2D.Zero, Vector2D.FromLengthAndAngle(1, angle)); segments.Add(seg); } IShape rayShape = ShapeFactory.CreateRays(segments.ToArray()); dispose += DemoHelper.RegisterMaintainSpawning(info, SdlDotNet.Input.Key.M, delegate(Vector2D position) { Body lazer = new Body(new PhysicsState(), rayShape, 1, new Coefficients(1, 1), new Lifespan()); lazer.State.Position.Linear = position; lazer.State.Velocity.Angular = .91f; lazer.IgnoresGravity = true; lazer.ApplyPosition(); info.Scene.AddGraphic(CreateGraphic(lazer)); return(lazer); }); return(dispose); }
/// <summary> /// Converts the screen position to a <see cref="RaySegment"/> in world coordinates. /// </summary> /// <param name="cameraComponent"></param> /// <param name="position"></param> /// <param name="result"><see cref="RaySegment"/>, starting at near plain and ending at the far plain.</param> /// <exception cref="ArgumentNullException">If the cameraComponent argument is <see langword="null"/>.</exception> /// <remarks> /// This method does not update the <see cref="CameraComponent.ViewMatrix"/> or <see cref="CameraComponent.ProjectionMatrix"/> before performing the transformation. /// If the <see cref="CameraComponent"/> or it's containing <see cref="Entity"/> <see cref="TransformComponent"/>has been modified since the last frame you may need to call the <see cref="CameraComponent.Update()"/> method first. /// </remarks> public static void ScreenToWorldRaySegment(this CameraComponent cameraComponent, ref Vector2 position, out RaySegment result) { if (cameraComponent == null) { throw new ArgumentNullException(nameof(cameraComponent)); } Matrix.Invert(ref cameraComponent.ViewProjectionMatrix, out var inverseViewProjection); ScreenToClipSpace(ref position, out var clipSpace); Vector3.TransformCoordinate(ref clipSpace, ref inverseViewProjection, out var near); clipSpace.Z = 1f; Vector3.TransformCoordinate(ref clipSpace, ref inverseViewProjection, out var far); result = new RaySegment(near, far); }
public List <IThrowingSegment> MoveThrowing(ThrowingEntity throwingEntity, int frameTime) { _entityAdapter.SetEntity(throwingEntity); List <IThrowingSegment> rc = new List <IThrowingSegment>(); _entityAdapter.RemainFrameTime += frameTime; while (_entityAdapter.RemainFrameTime >= _stepInterval) { int oldServerTime = _entityAdapter.ServerTime; int t = oldServerTime / _stepInterval; _entityAdapter.ServerTime = _stepInterval * (t + 1); float interval = (_entityAdapter.ServerTime - oldServerTime) / 1000.0f; Vector3 oldOrigin = _entityAdapter.Origin; // O(1) = O(0) + V(0) * t; _entityAdapter.Origin = _entityAdapter.Origin + _entityAdapter.Velocity * interval; if (DebugConfig.DrawThrowingLine) { RuntimeDebugDraw.Draw.DrawLine(oldOrigin, _entityAdapter.Origin, Color.blue, 60f); } // V(1) = V(0) + a * t Vector3 v = _entityAdapter.Velocity; v.y = v.y - _entityAdapter.Gravity * interval; v = v * Mathf.Pow(_entityAdapter.VelocityDecay, interval); _entityAdapter.Velocity = v; RaySegment raySegment = new RaySegment(); raySegment.Ray.origin = oldOrigin; var direction = _entityAdapter.Origin - oldOrigin; raySegment.Ray.direction = direction; raySegment.Length = direction.magnitude; DefaultThrowingSegment segment = new DefaultThrowingSegment(oldServerTime, raySegment, throwingEntity, _playerContext); rc.Add(segment); _entityAdapter.RemainFrameTime -= _stepInterval; } return(rc); }
public void Draw(DrawInfo drawInfo, IDrawableState state) { RaysSegmentsState st = state as RaysSegmentsState; for (int index = 0; index < st.lenghts.Length; ++index) { RaySegment segment = shape.Segments[index]; Ray ray = segment.RayInstance; Scalar length = (st.lenghts[index] == -1) ? (segment.Length) : (st.lenghts[index]); int destIndex = index * 2 + 1; array[destIndex].X = ray.Origin.X + ray.Direction.X * length; array[destIndex].Y = ray.Origin.Y + ray.Direction.Y * length; } Gl.glLineWidth(2); Gl.glColor3f(1, 1, 1); Gl.glBegin(Gl.GL_LINES); for (int index = 0; index < array.Length; ++index) { GlHelper.GlVertex(array[index]); } Gl.glEnd(); }
/// <summary> /// Raycasts penetrating any shape the ray encounters. /// </summary> /// <param name="simulation">Physics simulation.</param> /// <param name="raySegment">Ray.</param> /// <returns>The list with hit results.</returns> /// <exception cref="ArgumentNullException">If the simulation argument is null.</exception> public static FastList <HitResult> RaycastPenetrating(this Simulation simulation, RaySegment raySegment) { if (simulation == null) { throw new ArgumentNullException(nameof(simulation)); } return(simulation.RaycastPenetrating(raySegment.Start, raySegment.End)); }
/// <summary> /// Raycasts penetrating any shape the ray encounters. /// </summary> /// <param name="simulation">Physics simulation.</param> /// <param name="raySegment">Ray.</param> /// <param name="collisionFilterGroups">The collision group of this shape sweep</param> /// <param name="collisionFilterGroupFlags">The collision group that this shape sweep can collide with</param> /// <returns>The list with hit results.</returns> /// <exception cref="ArgumentNullException">If the simulation argument is null.</exception> public static FastList <HitResult> RaycastPenetrating(this Simulation simulation, RaySegment raySegment, CollisionFilterGroups collisionFilterGroups, CollisionFilterGroupFlags collisionFilterGroupFlags) { if (simulation == null) { throw new ArgumentNullException(nameof(simulation)); } var result = new FastList <HitResult>(); simulation.RaycastPenetrating(raySegment.Start, raySegment.End, result, collisionFilterGroups, collisionFilterGroupFlags); return(result); }
/// <summary> /// Raycasts penetrating any shape the ray encounters. /// </summary> /// <param name="simulation">Physics simulation.</param> /// <param name="raySegment">Ray.</param> /// <param name="collisionFilterGroups">The collision group of this shape sweep</param> /// <param name="collisionFilterGroupFlags">The collision group that this shape sweep can collide with</param> /// <returns>The list with hit results.</returns> /// <exception cref="ArgumentNullException">If the simulation argument is null.</exception> public static FastList <HitResult> RaycastPenetrating(this Simulation simulation, RaySegment raySegment, CollisionFilterGroups collisionFilterGroups, CollisionFilterGroupFlags collisionFilterGroupFlags) { if (simulation == null) { throw new ArgumentNullException(nameof(simulation)); } return(simulation.RaycastPenetrating(raySegment, collisionFilterGroups, collisionFilterGroupFlags)); }
/// <summary> /// Raycasts penetrating any shape the ray encounters. /// </summary> /// <param name="simulation">Physics simulation.</param> /// <param name="raySegment">Ray.</param> /// <returns>The list with hit results.</returns> /// <exception cref="ArgumentNullException">If the simulation argument is null.</exception> public static FastList <HitResult> RaycastPenetrating(this Simulation simulation, RaySegment raySegment) { if (simulation == null) { throw new ArgumentNullException(nameof(simulation)); } var resultsOutput = new FastList <HitResult>(); simulation.RaycastPenetrating(raySegment.Start, raySegment.End, resultsOutput); return(resultsOutput); }
public void MoveBullet(IBulletEntity bulletEntity, int renderTime, List <DefaultBulletSegment> allBulletSegments) { if (renderTime < bulletEntity.NextFrameTime) { return; } var origin = bulletEntity.Origin; var velocity = bulletEntity.Velocity; var gravity = bulletEntity.Gravity; var velocityDecay = bulletEntity.VelocityDecay; var distance = bulletEntity.Distance; float interval = (renderTime - bulletEntity.ServerTime) / 1000.0f; Vector3 oldOrigin = origin; // O(1) = O(0) + V(0) * t; origin.x = origin.x + velocity.x * interval; origin.y = origin.y + velocity.y * interval; origin.z = origin.z + velocity.z * interval; if (DebugConfig.DrawBulletLine) { RuntimeDebugDraw.Draw.DrawLine(oldOrigin, origin, Color.blue, 60f); Debug.DrawLine(oldOrigin, origin, Color.red, 60f); } // V(1) = V(0) + a * t Vector3 v = velocity; v.y = v.y - gravity * interval; v = v * Mathf.Pow(velocityDecay, interval); velocity = v; RaySegment raySegment = new RaySegment(); raySegment.Ray.origin = oldOrigin; var direction = origin - oldOrigin; raySegment.Ray.direction = direction; raySegment.Length = direction.magnitude; distance += raySegment.Length; _logger.DebugFormat("move bullet velocity {0}, direction {1}, distance {2}, total distance {3}, interval {4}, move {5} -> {6}, stepinterval {7}", velocity, direction, raySegment.Length, distance, interval, oldOrigin, origin, _stepInterval); DefaultBulletSegment segment = DefaultBulletSegment.Allocate(renderTime, raySegment, bulletEntity); allBulletSegments.Add(segment); if (Mathf.Approximately(v.magnitude, 0)) { bulletEntity.IsValid = false; _logger.ErrorFormat("bullet velocity is zero, set to invalid"); } bulletEntity.Origin = origin; bulletEntity.ServerTime = renderTime; bulletEntity.Velocity = velocity; bulletEntity.Distance = distance; bulletEntity.NextFrameTime = renderTime + _stepInterval; }
public void MoveBullet(IBulletEntityAgent bulletEntityAgent, int renderTime, List <DefaultBulletSegment> allBulletSegments, int cmdSeq) { if (renderTime < bulletEntityAgent.NextFrameTime) { return; } var origin = bulletEntityAgent.Position; var velocity = bulletEntityAgent.Velocity; var gravity = bulletEntityAgent.Gravity; var velocityDecay = bulletEntityAgent.VelocityDecay; var distance = bulletEntityAgent.Distance; float interval = (renderTime - bulletEntityAgent.ServerTime) / 1000.0f; Vector3 oldOrigin = origin; // O(1) = O(0) + V(0) * t; origin.x = origin.x + velocity.x * interval; origin.y = origin.y + velocity.y * interval; origin.z = origin.z + velocity.z * interval; if (DebugConfig.DrawBulletLine) { RuntimeDebugDraw.Draw.DrawLine(oldOrigin, origin, Color.blue, 60f); Debug.DrawLine(oldOrigin, origin, Color.red, 60f); } // V(1) = V(0) + a * t Vector3 v = velocity; v.y = v.y - gravity * interval; v = v * Mathf.Pow(velocityDecay, interval); velocity = v; RaySegment raySegment = new RaySegment(); raySegment.Ray.origin = oldOrigin; var direction = origin - oldOrigin; raySegment.Ray.direction = direction; raySegment.Length = direction.magnitude; distance += raySegment.Length; // string rayInfo = string.Format("direction {0}, length {1},readInterval {2}, move {3} -> {4}, stepinterval {5}",direction,raySegment.Length, interval, oldOrigin, origin, _stepInterval); DefaultBulletSegment segment = DefaultBulletSegment.Allocate(renderTime, raySegment, bulletEntityAgent); allBulletSegments.Add(segment); if (Mathf.Approximately(v.magnitude, 0)) { bulletEntityAgent.IsValid = false; _logger.ErrorFormat("bullet velocity is zero, set to invalid"); DebugUtil.AppendShootText(cmdSeq, "[Bullet Move] bullet {0}invalid", bulletEntityAgent.OwnerEntityKey); } bulletEntityAgent.Position = origin; bulletEntityAgent.ServerTime = renderTime; bulletEntityAgent.Velocity = velocity; bulletEntityAgent.Distance = distance; bulletEntityAgent.NextFrameTime = renderTime + _stepInterval; // DebugUtil.AppendShootText(cmdSeq,"[Bullet Move]rayInfo :{0} //// bulletInfo :{1} ",rayInfo,bulletEntityAgent.ToMoveString()); }
private void NewBulletHit(int cmdSeq, DefaultBulletSegment segment, ICompensationWorld world) { RaycastHit camDirHit; segment.BulletEntity.IsNew = false; RaycastHit gunDirHit; var camRaySegment = segment.RaySegment; bool checkGunDirObstacle = false; while (segment.BulletEntity.IsValid && world.Raycast(camRaySegment, out camDirHit, _hitboxLayerMask)) { if (!checkGunDirObstacle) { checkGunDirObstacle = true; //如果击中物体,从枪口向击中位置做检测,如果有物体,则使用枪口方向的结果 var startPosition = segment.BulletEntity.GunEmitPosition; var target = camDirHit.point; var dir = target - startPosition; var blockCheckSegment = new RaySegment() { Length = Vector3.Distance(target, startPosition) - RaycastStepOffset, Ray = new Ray(startPosition, dir.normalized), }; while (segment.BulletEntity.IsValid && world.Raycast(blockCheckSegment, out gunDirHit, _hitboxLayerMask)) { _bulletHitHandler.OnHit(cmdSeq, segment.BulletEntity, gunDirHit, world); blockCheckSegment.Ray.origin = gunDirHit.point + blockCheckSegment.Ray.direction * RaycastStepOffset; } } if (segment.BulletEntity.IsValid) { _bulletHitHandler.OnHit(cmdSeq, segment.BulletEntity, camDirHit, world); camRaySegment.Ray.origin = camDirHit.point + camRaySegment.Ray.direction * RaycastStepOffset; } } if (segment.BulletEntity.IsValid) { if (!checkGunDirObstacle) { //如果没有击中物体,从枪口向第一帧末子弹到达的位置做检测,如果有物体,使用枪口方向的结果 var startPosition = segment.BulletEntity.GunEmitPosition; var target = segment.RaySegment.Ray.direction * segment.RaySegment.Length + segment.RaySegment.Ray.origin; var dir = target - startPosition; var blockCheckSegment = new RaySegment() { Length = Vector3.Distance(target, startPosition) - RaycastStepOffset, Ray = new Ray(startPosition, dir.normalized), }; while (segment.BulletEntity.IsValid && world.Raycast(blockCheckSegment, out gunDirHit, _hitboxLayerMask)) { checkGunDirObstacle = true; _bulletHitHandler.OnHit(cmdSeq, segment.BulletEntity, gunDirHit, world); blockCheckSegment.Ray.origin = gunDirHit.point + blockCheckSegment.Ray.direction * RaycastStepOffset; } } } }
void DrawInternal() { if (entity.Shape.Tag is Sprite) { Sprite s = (Sprite)entity.Shape.Tag; s.Draw(); if (DrawLinesAndNormalsForSprites) { foreach (Vector2D[] vertexes in s.Polygons) { Gl.glLineWidth(1); Gl.glBegin(Gl.GL_LINES); Vector2D v1 = vertexes[vertexes.Length - 1]; Vector2D v2; for (int index = 0; index < vertexes.Length; ++index, v1 = v2) { v2 = vertexes[index]; Gl.glColor3f(1, 1, 1); Gl.glVertex2f(v1.X, v1.Y); Gl.glColor3f(1, 0, 0); Gl.glVertex2f(v2.X, v2.Y); DrawNormal(ref v1, ref v2); } Gl.glEnd(); } } } else if (entity.Shape is ParticleShape) { Gl.glBegin(Gl.GL_POINTS); Gl.glColor3f(1, 0, 0); //Gl.glColor3d(rand.NextDouble(), rand.NextDouble(), rand.NextDouble()); foreach (Vector2D vector in entity.Shape.Vertexes) { Gl.glVertex2f((Scalar)vector.X, (Scalar)vector.Y); } Gl.glEnd(); } else if (entity.Shape is RaySegmentsShape) { Gl.glLineWidth(1); RaySegmentsShape collection = (RaySegmentsShape)entity.Shape; Gl.glBegin(Gl.GL_LINES); for (int index = 0; index < collection.Segments.Length; ++index) { Gl.glColor3f(1, 0, 1); RaySegment ray = collection.Segments[index]; Gl.glVertex2f(ray.RayInstance.Origin.X, ray.RayInstance.Origin.Y); Scalar length; if (logic.Collisions[index].Distance == -1) { length = ray.Length; } else { length = logic.Collisions[index].Distance; } Vector2D temp = ray.RayInstance.Origin + ray.RayInstance.Direction * length; Gl.glColor3f(1, 1, 1); Gl.glVertex2f(temp.X, temp.Y); } Gl.glEnd(); } else { Gl.glBegin(Gl.GL_POLYGON); bool first = true; bool second = true; foreach (Vector2D vector in entity.Shape.Vertexes) { if (first) { Gl.glColor3f(1, .5f, 0); first = false; } else if (second) { Gl.glColor3f(1, 1, 1); second = false; } Gl.glVertex2f((Scalar)vector.X, (Scalar)vector.Y); } Gl.glEnd(); } }