示例#1
0
        public override void CreatePhysics(IPhysicsBody physicsBody)
        {
            const double radius             = 0.5, // mech legs collider
                         meleeHitboxHeight  = 0.7,
                         meleeHitboxOffset  = 0.25,
                         rangedHitboxHeight = 1.4,
                         rangedHitboxOffset = 0;

            physicsBody.AddShapeCircle(
                radius / 2,
                center: (-radius / 2, 0));

            physicsBody.AddShapeCircle(
                radius / 2,
                center: (radius / 2, 0));

            physicsBody.AddShapeRectangle(
                size: (radius, radius),
                offset: (-radius / 2, -radius / 2));

            // melee hitbox
            physicsBody.AddShapeRectangle(
                size: (0.8, meleeHitboxHeight),
                offset: (-0.4, meleeHitboxOffset),
                group: CollisionGroups.HitboxMelee);

            // ranged hitbox
            physicsBody.AddShapeRectangle(
                size: (0.8, rangedHitboxHeight),
                offset: (-0.4, rangedHitboxOffset),
                group: CollisionGroups.HitboxRanged);
        }
示例#2
0
文件: RigidBody.cs 项目: idafi/heng
        Vector2 GetMomentumChange(IPhysicsBody body, CollisionData collision)
        {
            // only deal with velocity along the collision normal
            Vector2 aV = collision.Normal.Project(body.Velocity);
            Vector2 bV = collision.Normal.Project(collision.Other.Velocity);

            float aM = body.Mass;
            float bM = collision.Other.Mass;

            // get net restitution coefficient (higher values means more "bouncy")
            float c = GetRestitutionCoefficient(body, collision.Other);

            Vector2 change;

            // handle infinite mass
            if (body.Mass == float.PositiveInfinity)
            {
                change = Vector2.Zero;
            }                                           // this body has inifinte mass - no energy is sent back
            else if (collision.Other.Mass == float.PositiveInfinity)
            {
                change = -(aV * c);
            }                                           // the other body has infinite mass - all energy not lost is sent back
            else
            {
                change = ((aV * aM) + (bV * bM) + ((bV - aV) * bM * c)) * (1 / (aM + bM));
            }

            // replace old velocity component with the calculated momentum-shifted velocity
            return((body.Velocity - aV) + change);
        }
示例#3
0
        public override void CreatePhysics(IPhysicsBody physicsBody)
        {
            // human legs collider
            var radius = 0.2;

            physicsBody.AddShapeCircle(
                radius / 2,
                center: (-radius / 2, 0));

            physicsBody.AddShapeCircle(
                radius / 2,
                center: (radius / 2, 0));

            physicsBody.AddShapeRectangle(
                size: (radius, radius),
                offset: (-radius / 2, -radius / 2));

            // melee hitbox
            physicsBody.AddShapeRectangle(
                size: (0.6, MeleeHitboxHeight),
                offset: (-0.3, MeleeHitboxOffset),
                group: CollisionGroups.HitboxMelee);

            // ranged hitbox
            physicsBody.AddShapeRectangle(
                size: (0.5, RangedHitboxHeight),
                offset: (-0.25, RangedHitboxOffset),
                group: CollisionGroups.HitboxRanged);
        }
示例#4
0
            public int AddPhysicsObject(IPhysicsBody obj)
            {
                Assert.Ref(obj);

                physicsBodies.Add(obj);
                return(physicsBodies.Count - 1);
            }
        private static Vector2D ServerGetClosestPointToExplosionEpicenter(
            IPhysicsBody physicsBody,
            Vector2D positionEpicenter)
        {
            if (!(physicsBody.AssociatedWorldObject?.ProtoWorldObject
                  is IProtoStaticWorldObject protoStaticWorldObject))
            {
                return(physicsBody.ClampPointInside(
                           positionEpicenter,
                           CollisionGroups.Default,
                           out _));
            }

            // find closest tile in layout and return its center
            var closestDistanceSqr = double.MaxValue;
            var tilePosition       = physicsBody.AssociatedWorldObject.TilePosition;
            var closestPosition    = tilePosition.ToVector2D();

            foreach (var tileOffset in protoStaticWorldObject.Layout.TileOffsets)
            {
                Vector2D pos = (tilePosition.X + tileOffset.X,
                                tilePosition.Y + tileOffset.Y);
                var distanceSqr = pos.DistanceSquaredTo(positionEpicenter);
                if (distanceSqr < closestDistanceSqr)
                {
                    closestDistanceSqr = distanceSqr;
                    closestPosition    = pos;
                }
            }

            return(closestPosition.X + 0.5,
                   closestPosition.Y + 0.5);
        }
示例#6
0
 public override void CreatePhysics(IPhysicsBody physicsBody)
 {
     physicsBody.IsNotPushable = true;
     physicsBody.AddShapeRectangle(size: (0.9, 0.6), offset: (0.05 - 0.5, 0))
     .AddShapeRectangle(size: (0.8, 0.7), offset: (0.1 - 0.5, 0.4), group: HitboxMelee)
     .AddShapeRectangle(size: (0.7, 0.5), offset: (0.15 - 0.5, 0.65), group: HitboxRanged);
 }
示例#7
0
        IEnumerable <(IPhysicsBody, CollisionData)> TestGroup(IReadOnlyList <IPhysicsBody> objects)
        {
            // we're just checking each collider against those at larger indices
            // (i.e., those which it hasn't yet been checked against)
            for (int a = 0; a < objects.Count - 1; a++)
            {
                IPhysicsBody oa = objects[a];

                if (oa.Collider != null)
                {
                    for (int b = a + 1; b < objects.Count; b++)
                    {
                        IPhysicsBody ob = objects[b];
                        if (ob.Collider != null)
                        {
                            // don't bother checking collisions between non-moving objects
                            // (this will implicitly factor out StaticBodies)
                            if (oa.Velocity != Vector2.Zero || ob.Velocity != Vector2.Zero)
                            {
                                if (TestPair(oa, ob, out Vector2 mtv))
                                {
                                    // return
                                    yield return(oa, new CollisionData(ob, mtv));

                                    yield return(ob, new CollisionData(oa, -mtv));
                                }
                            }
                        }
                    }
                }
            }
        }
示例#8
0
        public override void CreatePhysics(IPhysicsBody physicsBody)
        {
            const double radius = LegsColliderRadius;

            physicsBody.AddShapeCircle(
                radius / 2,
                center: (-radius / 2, 0),
                CollisionGroups.CharacterOrVehicle);

            physicsBody.AddShapeCircle(
                radius / 2,
                center: (radius / 2, 0),
                CollisionGroups.CharacterOrVehicle);

            physicsBody.AddShapeRectangle(
                size: (radius, radius),
                offset: (-radius / 2, -radius / 2),
                CollisionGroups.CharacterOrVehicle);

            // melee hitbox
            physicsBody.AddShapeRectangle(
                size: (0.6, MeleeHitboxHeight),
                offset: (-0.3, MeleeHitboxOffset),
                group: CollisionGroups.HitboxMelee);

            // ranged hitbox
            physicsBody.AddShapeRectangle(
                size: (0.5, RangedHitboxHeight),
                offset: (-0.25, RangedHitboxOffset),
                group: CollisionGroups.HitboxRanged);
        }
示例#9
0
 public GravityManagement(IPhysicsBody physicsBody)
 {
     this.physicsBody = physicsBody;
     YVelocity        = PhysicsUtil.zero;
     Gravity          = PhysicsUtil.gravity;
     Island           = physicsBody.Island;
 }
示例#10
0
        public override void CreatePhysics(IPhysicsBody physicsBody)
        {
            physicsBody.IsNotPushable = true;

            physicsBody
            .AddShapeCircle(radius: 1.2,
                            center: (0 - 0.3375, 0.15))
            .AddShapeCircle(radius: 1.2,
                            center: (0 + 0.3375, 0.15))
            .AddShapeCircle(radius: 1.05,
                            center: (0, 0),
                            group: CollisionGroups.HitboxMelee)
            .AddShapeCircle(radius: 1.05,
                            center: (0, 0.6),
                            group: CollisionGroups.HitboxMelee)
            .AddShapeCircle(radius: 1.05,
                            center: (0, 0),
                            group: CollisionGroups.HitboxRanged)
            .AddShapeCircle(radius: 1.05,
                            center: (0, 0.75),
                            group: CollisionGroups.HitboxRanged)
            .AddShapeCircle(radius: 1.05,
                            center: (0, 1.5),
                            group: CollisionGroups.HitboxRanged);
        }
示例#11
0
        public void RenderGdiFallback(Graphics graphics, RectangleD cameraBounds, IPhysicsBody sun)
        {
            RectangleD bounds = ComputeBoundingBox();

            // Not in range easy return
            if (!cameraBounds.IntersectsWith(bounds))
            {
                return;
            }

            if (AtmosphereHeight > 0)
            {
                RectangleF atmosphereBounds = RenderUtils.ComputeEllipseSize(Position, cameraBounds, BoundingRadius);

                // Saftey
                if (atmosphereBounds.Width > RenderUtils.ScreenWidth * 5000)
                {
                    return;
                }

                graphics.FillEllipse(new SolidBrush(IconAtmopshereColor), atmosphereBounds);
            }

            RectangleF surfaceBounds = RenderUtils.ComputeEllipseSize(Position, cameraBounds, SurfaceRadius);

            // Saftey
            if (surfaceBounds.Width > RenderUtils.ScreenWidth * 5000)
            {
                return;
            }

            graphics.FillEllipse(new SolidBrush(IconColor), surfaceBounds);
        }
示例#12
0
        public override void SharedCreatePhysicsConstructionBlueprint(IPhysicsBody physicsBody)
        {
            var worldObject      = (IStaticWorldObject)physicsBody.AssociatedWorldObject;
            var isHorizontalDoor = DoorHelper.IsHorizontalDoorNeeded(worldObject.OccupiedTile, checkExistingDoor: true);

            SharedCreateDoorPhysics(physicsBody, isHorizontalDoor, isOpened: true);
        }
示例#13
0
        public void UpdateTarget(IPhysicsBody target)
        {
            _lastTarget = _target;
            _target     = target;

            _isInterpolating   = true;
            _interpolationTime = 0;
        }
示例#14
0
        internal CollisionData(IPhysicsBody other, Vector2 mtv)
        {
            Assert.Ref(other);

            Other  = other;
            MTV    = mtv;
            Normal = mtv.Normalize();
        }
示例#15
0
        public override bool CanCollide(IPhysicsBody thisBody, IPhysicsBody otherBody, Ignorer other)
        {
            AdvGroupIgnorer value = other as AdvGroupIgnorer;

            return
                (value == null ||
                 CanCollideInternal(value));
        }
示例#16
0
        public void UpdateTarget(IPhysicsBody target)
        {
            _lastTarget = _target;
            _target = target;

            _isInterpolating = true;
            _interpolationTime = 0;
        }
示例#17
0
 protected override void Awake()
 {
     base.Awake();
     healthBody      = GetComponent <HealthBody>();
     physicsBody     = GetComponent <CirclePhysicsBody>();
     itemHandlerBody = GetComponent <ItemHandlerBody>();
     activator       = GetComponent <Activator>();
 }
示例#18
0
 public virtual void SharedCreatePhysicsConstructionBlueprint(IPhysicsBody physicsBody)
 {
     foreach (Vector2D tileOffset in this.Layout.TileOffsets)
     {
         physicsBody.AddShapeRectangle(Vector2D.One, tileOffset, CollisionGroups.Default)
         .AddShapeRectangle(Vector2D.One, tileOffset, CollisionGroups.ClickArea);
     }
 }
示例#19
0
        public void AddBody(IPhysicsBody b)
        {
            if (b.PhysicsManager == null)
            {
                b.PhysicsManager = this;
            }

            Bodies.Add(b);
        }
示例#20
0
        public Camera(IPhysicsBody target, double zoom = 1)
        {
            _target = target;
            _lastTarget = target;

            _position = _target.Position.Clone();

            Zoom = zoom;
        }
示例#21
0
        public override void ResolveGravitation(IPhysicsBody other)
        {
            if (Parent != null)
            {
                return;
            }

            base.ResolveGravitation(other);
        }
示例#22
0
        public void RemoveBody(IPhysicsBody b)
        {
            if (b.PhysicsManager == null)
            {
                b.PhysicsManager = this;
            }

            Bodies.Remove(b);
        }
示例#23
0
        /// <summary>
        /// Lisää kappaleen moottoriin.
        /// </summary>
        /// <param name="body">Kappale</param>
        public void RemoveBody(IPhysicsBody body)
        {
            if (!(body is PhysicsBody))
            {
                throw new ArgumentException("Physics object has unrecognizable body type.");
            }

            bodies.Remove((PhysicsBody)body);
        }
示例#24
0
        public Camera(IPhysicsBody target, double zoom = 1)
        {
            _target     = target;
            _lastTarget = target;

            _position = _target.Position.Clone();

            Zoom = zoom;
        }
示例#25
0
        public override bool CanCollide(IPhysicsBody thisBody, IPhysicsBody otherBody, Ignorer other)
        {
            if (otherBody.IgnoresPhysicsLogics)
            // || otherBody.IsBroadPhaseOnly)
            {
                return(true);
            }

            return(thisBody.Position.Y - depthAllowed > otherBody.Position.Y);
        }
示例#26
0
        public static Vector2D GetCenterPosition(IPhysicsBody target)
        {
            var shape = target.Shapes.FirstOrDefault(s => s.CollisionGroup == CollisionGroups.HitboxMelee);

            if (shape == null)
            {
                Api.Logger.Error("Automaton: target object has no HitBoxMelee shape " + target);
                return(target.Position);
            }
            return(ShapeCenter(shape) + target.Position);
        }
示例#27
0
        public override bool CanCollide(IPhysicsBody thisBody, IPhysicsBody otherBody, Ignorer other)
        {
            JypeliGroupIgnorer jOther = other as JypeliGroupIgnorer;

            if (jOther == null)
            {
                return(true);
            }

            return((this.LegacyGroup == 0 || jOther.LegacyGroup == 0 || this.LegacyGroup != jOther.LegacyGroup) && (this.IgnoreMask & jOther.IgnoreMask) == 0);
        }
示例#28
0
 public override void CreatePhysics(IPhysicsBody physicsBody)
 {
     physicsBody
     .AddShapeRectangle(size: (0.6, 0.25),
                        offset: (-0.3, -0.05))
     .AddShapeCircle(radius: 0.42,
                     center: (0, 0.35),
                     group: CollisionGroups.HitboxMelee)
     .AddShapeCircle(radius: 0.42,
                     center: (0, 0.35),
                     group: CollisionGroups.HitboxRanged);
 }
示例#29
0
 public override void CreatePhysics(IPhysicsBody physicsBody)
 {
     physicsBody
     .AddShapeCircle(radius: 0.25,
                     center: (0, 0.0))
     .AddShapeCircle(radius: 0.4,
                     center: (0, 0.25),
                     group: CollisionGroups.HitboxMelee)
     .AddShapeCircle(radius: 0.4,
                     center: (0, 0.25),
                     group: CollisionGroups.HitboxRanged);
 }
示例#30
0
 public void AddBody(IPhysicsBody body)
 {
     if (body != null)
     {
         _bodies.Add(body);
         body._SetPhysicsDomain(this);
     }
     else
     {
         throw new ArgumentNullException(nameof(body));
     }
 }
示例#31
0
        public void RenderCl(OpenCLProxy clProxy, Camera camera, IPhysicsBody sun)
        {
            RectangleD bounds = ComputeBoundingBox();

            // Not in range easy return
            if (!camera.Intersects(bounds))
            {
                return;
            }

            DVector2 sunNormal = DVector2.Zero;

            if (sun != null)
            {
                sunNormal = sun.Position - Position;

                sunNormal.Normalize();
            }

            if (clProxy.HardwareAccelerationEnabled)
            {
                clProxy.UpdateDoubleArgument("cX", camera.Bounds.X);
                clProxy.UpdateDoubleArgument("cY", camera.Bounds.Y);

                clProxy.UpdateDoubleArgument("cWidth", camera.Bounds.Width);
                clProxy.UpdateDoubleArgument("cHeight", camera.Bounds.Height);

                clProxy.UpdateDoubleArgument("cRot", -camera.Rotation);

                clProxy.UpdateDoubleArgument("sunNormalX", sunNormal.X);
                clProxy.UpdateDoubleArgument("sunNormalY", sunNormal.Y);

                clProxy.UpdateDoubleArgument("bodyX", Position.X);
                clProxy.UpdateDoubleArgument("bodyY", Position.Y);
                clProxy.UpdateDoubleArgument("bodyRot", Pitch);

                clProxy.RunKernel(_computeKernel, RenderUtils.ScreenArea);
            }
            else
            {
                int totalSize = RenderUtils.ScreenArea;

                for (int i = 0; i < totalSize; i++)
                {
                    Kernel.Run(clProxy.ReadIntBuffer("image", totalSize), RenderUtils.ScreenWidth, RenderUtils.ScreenHeight,
                               camera.Bounds.X, camera.Bounds.Y, camera.Bounds.Width, camera.Bounds.Height, camera.Rotation,
                               sunNormal.X, sunNormal.Y, Position.X, Position.Y, Pitch);
                }

                Kernel.Finish();
            }
        }
示例#32
0
        public static Body CreateCircle(IPhysicsBody owner, PhysicsWorld world, float radius, BodyType type = BodyType.Static)
        {
            var body = BodyFactory.CreateCircle(world.World, ConvertUnits.ToSimUnits(radius), 1f);

            body.BodyType = type;
            body.UserData = owner;
            if (owner != null)
            {
                owner.Body = body;
            }

            return(body);
        }
示例#33
0
        public virtual void ResolveGravitation(IPhysicsBody other)
        {
            DVector2 difference = other.Position - Position;

            double r2 = difference.LengthSquared();

            double massDistanceRatio = other.Mass / r2;

            // Ignore the force, the planet is too far away to matter
            if (massDistanceRatio < 2500)
            {
                return;
            }

            difference.Normalize();

            // Gravitation ( aG = G m1 / r^2 )
            AccelerationG += difference * FlightGlobals.GRAVITATION_CONSTANT * massDistanceRatio;
        }
示例#34
0
        public void RenderCl(OpenCLProxy clProxy, RectangleD cameraBounds, IPhysicsBody sun)
        {
            RectangleD bounds = ComputeBoundingBox();

            // Not in range easy return
            if (!cameraBounds.IntersectsWith(bounds))
            {
                return;
            }

            DVector2 sunNormal = DVector2.Zero;

            if (sun != null)
            {
                sunNormal = sun.Position - Position;

                sunNormal.Normalize();
            }

            var normalizedPosition = new DVector2(cameraBounds.X - Position.X, cameraBounds.Y - Position.Y);

            if (clProxy.HardwareAccelerationEnabled)
            {
                clProxy.UpdateDoubleArgument("cameraLeft", normalizedPosition.X);
                clProxy.UpdateDoubleArgument("cameraTop", normalizedPosition.Y);

                clProxy.UpdateDoubleArgument("cameraWidth", cameraBounds.Width);
                clProxy.UpdateDoubleArgument("cameraHeight", cameraBounds.Height);

                clProxy.UpdateDoubleArgument("sunNormalX", sunNormal.X);
                clProxy.UpdateDoubleArgument("sunNormalY", sunNormal.Y);

                clProxy.UpdateDoubleArgument("rotation", Rotation);

                clProxy.RunKernel(_computeKernel, RenderUtils.ScreenArea);
            }
            else
            {
                int totalSize = RenderUtils.ScreenArea;

                for (int i = 0; i < totalSize; i++)
                {
                    Kernel.Run(clProxy.ReadIntBuffer("image", totalSize), RenderUtils.ScreenWidth, RenderUtils.ScreenHeight,
                                                    normalizedPosition.X, normalizedPosition.Y, cameraBounds.Width, cameraBounds.Height,
                                                    sunNormal.X, sunNormal.Y, Rotation);
                }

                Kernel.Finish();
            }
        }
示例#35
0
        public override void ResolveGravitation(IPhysicsBody other)
        {
            if (Parent != null) return;

            base.ResolveGravitation(other);
        }
示例#36
0
        public void RenderGdiFallback(Graphics graphics, RectangleD cameraBounds, IPhysicsBody sun)
        {
            RectangleD bounds = ComputeBoundingBox();

            // Not in range easy return
            if (!cameraBounds.IntersectsWith(bounds))
            {
                return;
            }

            if (AtmosphereHeight > 0)
            {
                RectangleF atmosphereBounds = RenderUtils.ComputeEllipseSize(Position, cameraBounds, BoundingRadius);

                // Saftey
                if (atmosphereBounds.Width > RenderUtils.ScreenWidth * 5000) return;

                graphics.FillEllipse(new SolidBrush(IconAtmopshereColor), atmosphereBounds);
            }

            RectangleF surfaceBounds = RenderUtils.ComputeEllipseSize(Position, cameraBounds, SurfaceRadius);

            // Saftey
            if (surfaceBounds.Width > RenderUtils.ScreenWidth * 5000) return;

            graphics.FillEllipse(new SolidBrush(IconColor), surfaceBounds);
        }