public void Update(GameTime gameTime)
 {
     if (LinearVelocity.LengthSquared() >= 1e-7)
     {
         var  step    = LinearVelocity * World.TimeScale * (float)gameTime.ElapsedGameTime.TotalSeconds;
         bool stopped = false;
         var  rf      = this;
         World.Physics.RayCast((Fixture arg1, Vector2 arg2, Vector2 arg3, float arg4) =>
         {
             if (arg1.Body.Tag is TerrainComponent)
             {
                 Position       = arg2 * 64f;
                 LinearVelocity = Vector2.Zero;
                 stopped        = true;
             }
             else if (arg1.Body.Tag is Entity)
             {
                 var ent = arg1.Body.Tag as Entity;
                 if (ent.Tags.Any(t => TargetedTags.Contains(t)))
                 {
                     var ch = ent.GetComponent <CharacterComponent>();
                     if (ch != null)
                     {
                         ch.Damage(World.GetEntity(OwnerID), Damage);
                         Position       = arg2 * 64f;
                         LinearVelocity = Vector2.Zero;
                         stopped        = true;
                         Parent.AddComponent(new BindedBodyComponent().BindTo(ent, Position, Rotation));
                         rf.Remove = true;
                         return(0);
                     }
                 }
             }
             return(arg4);
         }, Position / 64f, (Position + step) / 64f);
         if (!stopped)
         {
             Position += step;
         }
         else
         {
             Gravity = false;
         }
     }
     if (Gravity)
     {
         LinearVelocity += new Vector2(0, World.Physics.Gravity.Y * 64f *
                                       (float)gameTime.ElapsedGameTime.TotalSeconds * World.TimeScale);
     }
     if (Friction > 0)
     {
         LinearVelocity /= Friction;
     }
 }
示例#2
0
文件: Dude.cs 项目: payload/godot-mo
    public override void _Process(float delta)
    {
        Delta = delta;
        ProcessTask();

        if (LinearVelocity.LengthSquared() > 0.01)
        {
            var visual = GetNode <Spatial>("Visual");
            var angle  = Mathf.Atan2(LinearVelocity.x, LinearVelocity.z);
            visual.Rotation = new Vector3(0, angle, 0);
        }
    }
示例#3
0
        /// <summary>
        /// Updates the sleeping state. Is called in <see cref="UpdateVelocity"/>.
        /// </summary>
        /// <param name="deltaTime">The time step.</param>
        private void UpdateSleeping(float deltaTime)
        {
            if (IsSleeping || !CanSleep)
            {
                return;
            }

            if (MotionType == MotionType.Dynamic)
            {
                if (LinearVelocity.LengthSquared() < Simulation.Settings.Sleeping.LinearVelocityThresholdSquared &&
                    AngularVelocity.LengthSquared() < Simulation.Settings.Sleeping.AngularVelocityThresholdSquared)
                {
                    // Movement is below threshold. Increase counter.
                    _noMovementTime += deltaTime;

                    // Static bodies sleep immediately. Kinematic and dynamic bodies are handled here.
                    // Dynamic bodies can only sleep if their whole island is sleeping. (Note: When the island
                    // is processed the sleeping of the dynamic body is deferred if the island is awake.)
                    if (_noMovementTime > Simulation.Settings.Sleeping.TimeThreshold)
                    {
                        IsSleeping = true;
                    }
                }
                else
                {
                    // Movement detected.
                    _noMovementTime = 0;
                }
            }
            else
            {
                if (LinearVelocity.LengthSquared() < Numeric.EpsilonFSquared &&
                    AngularVelocity.LengthSquared() < Numeric.EpsilonFSquared)
                {
                    // Kinematic bodies are set to sleep immediately!
                    IsSleeping       = true;
                    _linearVelocity  = Vector3.Zero;
                    _angularVelocity = Vector3.Zero;
                    _noMovementTime  = float.PositiveInfinity;
                }
                else
                {
                    // Movement detected.
                    _noMovementTime = 0;
                }
            }
        }
示例#4
0
        public void UpdateDeactivation(float timeStep)
        {
            if ((ActivationState == ActivationState.IslandSleeping) || (ActivationState == ActivationState.DisableDeactivation))
            {
                return;
            }

            if ((LinearVelocity.LengthSquared() < LinearSleepingThreshold * LinearSleepingThreshold) &&
                (AngularVelocity.LengthSquared() < AngularSleepingThreshold * AngularSleepingThreshold))
            {
                DeactivationTime += timeStep;
            }
            else
            {
                DeactivationTime = 0;
                ActivationState  = ActivationState.Nothing;
            }
        }
示例#5
0
        /// <summary>
        /// Applies buoyancy, drag and angular drag caused by water
        /// </summary>
        public void ApplyWaterForces()
        {
            //buoyancy
            Vector2 buoyancy = new Vector2(0, Mass * 9.6f);

            Vector2 dragForce = Vector2.Zero;

            if (LinearVelocity.LengthSquared() > 0.00001f)
            {
                //drag
                Vector2 velDir = Vector2.Normalize(LinearVelocity);

                float vel  = LinearVelocity.Length() * 2.0f;
                float drag = vel * vel * Math.Max(height + radius * 2, height);
                dragForce = Math.Min(drag, Mass * 500.0f) * -velDir;
            }

            ApplyForce(dragForce + buoyancy);
            ApplyTorque(body.AngularVelocity * body.Mass * -0.08f);
        }
示例#6
0
        /// <summary>
        /// Applies buoyancy, drag and angular drag caused by water
        /// </summary>
        public void ApplyWaterForces()
        {
            //buoyancy
            Vector2 buoyancy = new Vector2(0, Mass * 9.6f);

            Vector2 dragForce = Vector2.Zero;

            float speedSqr = LinearVelocity.LengthSquared();
            if (speedSqr > 0.00001f)
            {
                //drag
                float speed = (float)Math.Sqrt(speedSqr);
                Vector2 velDir = LinearVelocity / speed;

                float vel = speed * 2.0f;
                float drag = vel * vel * Math.Max(height + radius * 2, height);
                dragForce = Math.Min(drag, Mass * 500.0f) * -velDir;
            }

            ApplyForce(dragForce + buoyancy, maxVelocity: NetConfig.MaxPhysicsBodyVelocity);
            ApplyTorque(body.AngularVelocity * body.Mass * -0.08f);
        }
示例#7
0
        /// <summary>
        /// Updates the pose using numerical integration.
        /// </summary>
        /// <param name="deltaTime">The time step.</param>
        internal void UpdatePose(float deltaTime)
        {
            // Static bodies do not move.
            if (MotionType == MotionType.Static)
            {
                return;
            }

            if (IsSleeping)
            {
                // Previously in this time step the sleeping could still be deferred. Therefore the
                // velocities have not been reset. At this point the rigid body is definitely sleeping.

                // Reset the velocities...
                _linearVelocity  = Vector3.Zero;
                _angularVelocity = Vector3.Zero;

                // ...and exit.
                return;
            }

            // Clamp velocities before we apply them.
            if (_linearVelocity.IsNaN)
            {
                _linearVelocity = Vector3.Zero;
            }
            else if (_linearVelocity.LengthSquared() > Simulation.Settings.Motion.MaxLinearVelocitySquared)
            {
                _linearVelocity.Length = Simulation.Settings.Motion.MaxLinearVelocity;
            }

            if (_angularVelocity.IsNaN)
            {
                _angularVelocity = Vector3.Zero;
            }
            else if (_angularVelocity.LengthSquared() > Simulation.Settings.Motion.MaxAngularVelocitySquared)
            {
                _angularVelocity.Length = Simulation.Settings.Motion.MaxAngularVelocity;
            }

            // Important: Use the center-of-mass pose!
            var x = PoseCenterOfMass.Position;
            var q = Quaternion.CreateFromRotationMatrix(PoseCenterOfMass.Orientation);

            // Derivative of position: velocity
            // Derivative of orientation: q' = 1/2 * (0, ω) * q
            var  xDerivative   = LinearVelocity + LinearCorrectionVelocity;
            var  qDerivative   = 0.5f * new Quaternion(0, AngularVelocity + AngularCorrectionVelocity) * q;
            Pose targetPoseCOM = new Pose(x + deltaTime * xDerivative, (q + deltaTime * qDerivative).Normalized);

            if (CcdEnabled &&
                Simulation.Settings.Motion.CcdEnabled &&
                LinearVelocity.LengthSquared() > Simulation.Settings.Motion.CcdVelocityThresholdSquared)
            {
                // Continuous collision detection.
                IsCcdActive             = true;
                TimeOfImpact            = 1;
                Simulation.CcdRequested = true;
                TargetPose = targetPoseCOM * MassFrame.Pose.Inverse;

                // Trigger PoseChanged event. The pose has not changed but the AABB will be set to the
                // temporal AABB during motion clamping.
                _aabbIsValid = false;
                OnPoseChanged(EventArgs.Empty);
            }
            else
            {
                IsCcdActive      = false;
                PoseCenterOfMass = targetPoseCOM;
            }

            LinearCorrectionVelocity  = Vector3.Zero;
            AngularCorrectionVelocity = Vector3.Zero;
        }