Beispiel #1
0
            public override void ExclusiveUpdate()
            {
                if (Plane.DriverSeat.Sitter == null)
                {
                    return; // Don't fly when there's nobody driving this!
                }
                // TODO: Special case for motion on land: only push forward if W key is pressed? Or maybe apply that rule in general?
                // Collect the plane's relative vectors
                Vector3 forward = Quaternion.Transform(Vector3.UnitY, Entity.Orientation);
                Vector3 side    = Quaternion.Transform(Vector3.UnitX, Entity.Orientation);
                Vector3 up      = Quaternion.Transform(Vector3.UnitZ, Entity.Orientation);

                // Engines!
                if (Plane.FastOrSlow >= 0.0)
                {
                    Vector3 force = forward * (Plane.RegularStrength + Plane.FastStrength) * Delta;
                    entity.ApplyLinearImpulse(ref force);
                }
                double dotforw = Vector3.Dot(entity.LinearVelocity, forward);

                entity.ApplyImpulse(side * 5 + entity.Position, up * -Plane.RightLeft * entity.Mass * dotforw * 0.5 * Delta);
                entity.ApplyImpulse(forward * 5 + entity.Position, side * ((Plane.IRight ? 1 : 0) + (Plane.ILeft ? -1 : 0)) * entity.Mass * dotforw * 0.5 * Delta);
                entity.ApplyImpulse(forward * 5 + entity.Position, up * Plane.ForwBack * entity.Mass * 0.5 * Delta * dotforw);
                // Rotate the entity pre-emptively, and re-apply the movement velocity in this new direction!
                double     vellen          = entity.LinearVelocity.Length();
                Vector3    normvel         = entity.LinearVelocity / vellen;
                Vector3    norm_vel_transf = Quaternion.Transform(normvel, Quaternion.Inverse(entity.Orientation)); // Probably just 1,0,0 on whichever axis... can be simplified!
                Vector3    inc             = entity.AngularVelocity * Delta * 0.5;
                Quaternion quat            = new Quaternion(inc.X, inc.Y, inc.Z, 0);

                quat = quat * entity.Orientation;
                Quaternion orient = entity.Orientation;

                Quaternion.Add(ref orient, ref quat, out orient);
                orient.Normalize();
                entity.Orientation      = orient;
                entity.LinearVelocity   = Quaternion.Transform(norm_vel_transf, orient) * vellen;
                entity.AngularVelocity *= 0.1;
                // Apply air drag
                Entity.ModifyLinearDamping(Plane.FastOrSlow < 0.0 ? 0.6 : 0.1); // TODO: arbitrary constant
                Entity.ModifyAngularDamping(0.5);                               // TODO: arbitrary constant
                // Ensure we're active if flying!
                Entity.ActivityInformation.Activate();
            }
Beispiel #2
0
            public override void ExclusiveUpdate()
            {
                if (Plane.Driver == null) // TODO: Engine on/off rather than driver check
                {
                    return;               // Don't fly when there's nobody driving this!
                }
                // TODO: Special case for motion on land: only push forward if FORWARD key is pressed? Or maybe apply that rule in general?
                // Collect the plane's relative vectors
                Vector3 forward = BEPUutilities.Quaternion.Transform(Vector3.UnitY, Entity.Orientation);
                Vector3 side    = BEPUutilities.Quaternion.Transform(Vector3.UnitX, Entity.Orientation);
                Vector3 up      = BEPUutilities.Quaternion.Transform(Vector3.UnitZ, Entity.Orientation);

                // Engines!
                if (Plane.FastOrSlow >= 0.0)
                {
                    // TODO: Controls raise/lower engine thrust rather than continual direct control
                    Vector3 force = forward * (Plane.RegularStrength + Plane.FastStrength * Plane.FastOrSlow) * Delta;
                    entity.ApplyLinearImpulse(ref force);
                }
                // TODO: For very low forward velocities, turn weaker
                double dotforw = Vector3.Dot(entity.LinearVelocity, forward);
                double mval    = 2.0 * (1.0 / Math.Max(1.0, entity.LinearVelocity.Length()));
                double rot_x   = -Plane.ForwBack * Plane.StrPitch * Delta * dotforw * mval;
                double rot_y   = Plane.RightLeft * dotforw * Plane.StrRoll * Delta * mval;
                double rot_z   = -((Plane.IRight ? 1 : 0) + (Plane.ILeft ? -1 : 0)) * dotforw * Plane.StrYaw * Delta * mval;

                entity.AngularVelocity += BEPUutilities.Quaternion.Transform(new Vector3(rot_x, rot_y, rot_z), entity.Orientation);
                double  vellen  = entity.LinearVelocity.Length();
                Vector3 newVel  = forward * vellen;
                double  forwVel = Vector3.Dot(entity.LinearVelocity, forward);
                double  root    = Math.Sqrt(Math.Sign(forwVel) * forwVel);

                entity.LinearVelocity += (newVel - entity.LinearVelocity) * MathHelper.Clamp(Delta, 0.01, 0.3) * Math.Min(2.0, root * Plane.ForwardHelper);
                // Apply air drag
                Entity.ModifyLinearDamping(Plane.FastOrSlow < 0.0 ? 0.5 : 0.1); // TODO: arbitrary constants
                Entity.ModifyAngularDamping(0.995);                             // TODO: arbitrary constant
                // Ensure we're active if flying!
                Entity.ActivityInformation.Activate();
            }
            public override void ExclusiveUpdate()
            {
                if (Helicopter.DriverSeat.Sitter == null)
                {
                    return; // Don't fly when there's nobody driving this!
                }
                // Collect the helicopter's relative "up" vector
                Vector3 up = Quaternion.Transform(Vector3.UnitZ, Entity.Orientation);
                // Apply the amount of force necessary to counteract downward force, within a limit.
                // POTENTIAL: Adjust according to orientation?
                double uspeed = Math.Min(Helicopter.LiftStrength, -(Entity.LinearVelocity.Z + Entity.Space.ForceUpdater.Gravity.Z) * Entity.Mass);

                if (uspeed < 0f)
                {
                    uspeed += (uspeed - Helicopter.FallStrength) * Helicopter.SprintOrWalk;
                }
                else
                {
                    uspeed += (Helicopter.LiftStrength - uspeed) * Helicopter.SprintOrWalk;
                }
                Vector3 upvel = up * uspeed * Delta;

                Entity.ApplyLinearImpulse(ref upvel);
                // Rotate slightly to move in a direction.
                // At the same time, fight against existing rotation.
                Vector3 VecUp = new Vector3(Helicopter.RightLeft * 0.2f * Helicopter.TiltMod, Helicopter.ForwBack * -0.2f * Helicopter.TiltMod, 1);
                // TODO: Simplify yawrel calculation.
                double     tyaw   = (double)(Utilities.MatrixToAngles(Matrix.CreateFromQuaternion(Entity.Orientation)).Z *Utilities.PI180);
                Quaternion yawrel = Quaternion.CreateFromAxisAngle(Vector3.UnitZ, tyaw);

                VecUp   = Quaternion.Transform(VecUp, yawrel);
                VecUp.Y = -VecUp.Y;
                VecUp.Normalize();
                Vector3 axis = Vector3.Cross(VecUp, up);
                double  len  = axis.Length();

                if (len > 0)
                {
                    axis /= len;
                    double angle = (double)Math.Asin(len);
                    if (!double.IsNaN(angle))
                    {
                        double  avel   = Vector3.Dot(Entity.AngularVelocity, axis);
                        Vector3 torque = axis * ((-angle) - 0.3f * avel);
                        torque *= Entity.Mass * Delta * 30;
                        Entity.ApplyAngularImpulse(ref torque);
                    }
                }
                // Spin in place
                double rotation = (Helicopter.IRight ? -1f : 0f) + (Helicopter.ILeft ? 1f : 0f);

                if (rotation * rotation > 0f)
                {
                    Vector3 rot = new Vector3(0, 0, rotation * 15f * Delta * Entity.Mass);
                    Entity.ApplyAngularImpulse(ref rot);
                }
                // Apply air drag
                Entity.ModifyLinearDamping(0.3f);  // TODO: arbitrary constant
                Entity.ModifyAngularDamping(0.6f); // TODO: arbitrary constant
                // Ensure we're active if flying!
                Entity.ActivityInformation.Activate();
            }