Example #1
0
        private void MoveAngular(float timestep)
        {
            /*
             * private Vector3 m_angularMotorDirection = Vector3.Zero;            // angular velocity requested by LSL motor
             * private int m_angularMotorApply = 0;                            // application frame counter
             * private float m_angularMotorVelocity = 0;                        // current angular motor velocity (ramps up and down)
             * private float m_angularMotorTimescale = 0;                        // motor angular velocity ramp up rate
             * private float m_angularMotorDecayTimescale = 0;                    // motor angular velocity decay rate
             * private Vector3 m_angularFrictionTimescale = Vector3.Zero;        // body angular velocity  decay rate
             * private Vector3 m_lastAngularVelocity = Vector3.Zero;            // what was last applied to body
             */

            // Get what the body is doing, this includes 'external' influences
            btVector3 angularVelocity = m_body.getInterpolationAngularVelocity();

            //         Vector3 angularVelocity = Vector3.Zero;

            if (m_angularMotorApply > 0)
            {
                // ramp up to new value
                //   current velocity  +=                         error                       /    (time to get there / step interval)
                //                               requested speed            -  last motor speed
                m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / timestep);
                m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / timestep);
                m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / timestep);

                m_angularMotorApply--;        // This is done so that if script request rate is less than phys frame rate the expected
                // velocity may still be acheived.
            }
            else
            {
                // no motor recently applied, keep the body velocity

                /*        m_angularMotorVelocity.X = angularVelocity.X;
                 *      m_angularMotorVelocity.Y = angularVelocity.Y;
                 *      m_angularMotorVelocity.Z = angularVelocity.Z; */

                // and decay the velocity
                m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / timestep);
            } // end motor section

            // Vertical attractor section
            Vector3 vertattr = Vector3.Zero;

            if (m_verticalAttractionTimescale < 300)
            {
                float VAservo = 0.2f / (m_verticalAttractionTimescale * timestep);
                // get present body rotation
                btQuaternion rot  = m_body.getWorldTransform().getRotation();
                Quaternion   rotq = new Quaternion(rot.getX(), rot.getY(), rot.getZ(), rot.getW());
                // make a vector pointing up
                Vector3 verterr = Vector3.Zero;
                verterr.Z = 1.0f;
                // rotate it to Body Angle
                verterr = verterr * rotq;
                // verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1.
                // As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go
                // negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body.
                if (verterr.Z < 0.0f)
                {
                    verterr.X = 2.0f - verterr.X;
                    verterr.Y = 2.0f - verterr.Y;
                }
                // Error is 0 (no error) to +/- 2 (max error)
                // scale it by VAservo
                verterr = verterr * VAservo;
                //if (frcount == 0) Console.WriteLine("VAerr=" + verterr);

                // As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so
                // Change  Body angular velocity  X based on Y, and Y based on X. Z is not changed.
                vertattr.X = verterr.Y;
                vertattr.Y = -verterr.X;
                vertattr.Z = 0f;

                // scaling appears better usingsquare-law
                float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
                vertattr.X += bounce * angularVelocity.getX();
                vertattr.Y += bounce * angularVelocity.getY();
            } // else vertical attractor is off

            //        m_lastVertAttractor = vertattr;

            // Bank section tba
            // Deflection section tba

            // Sum velocities
            m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection

            if ((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) != 0)
            {
                m_lastAngularVelocity.X = 0;
                m_lastAngularVelocity.Y = 0;
            }

            // apply friction
            Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / timestep);

            m_lastAngularVelocity -= m_lastAngularVelocity * decayamount;

            // Apply to the body
            m_body.setAngularVelocity(new btVector3(m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z));
        }