Пример #1
0
        /// <summary>
        /// This function returns a vector that is rotated by the opposite of me
        /// </summary>
        public MyVector GetRotatedVectorReverse(MyVector vector, bool isQuatNormalized)
        {
            if (!isQuatNormalized)
            {
                // I'm not normalized, clone myself and normalize it
                MyQuaternion myUnitClone = new MyQuaternion(this.X, this.Y, this.Z, this.W);
                myUnitClone.BecomeUnitQuaternion();

                return(myUnitClone.GetRotatedVectorReverse(vector, true));
            }

            MyVector qvec = new MyVector(this.X, this.Y, this.Z);

            //Vector uv = qvec.Cross(vector);
            MyVector uv = MyVector.Cross(qvec, vector);

            //Vector uuv = qvec.Cross(uv);
            MyVector uuv = MyVector.Cross(qvec, uv);

            //uv *= (2.0f * quat.w);
            uv.Multiply(this.W * -2d);

            //uuv *= 2.0f;
            uuv.Multiply(2d);

            //return vector + uv + uuv;
            MyVector retVal = vector.Clone();

            retVal.Add(uv);
            retVal.Add(uuv);
            return(retVal);
        }
Пример #2
0
        /// <summary>
        /// This function will calculate the new velocity based on the current acceleration and elapsed time.  I will store the result back into
        /// my velocity property.
        /// </summary>
        private void TimerSprtVel(double elapsedTime)
        {
            // Clone the current accel
            MyVector changeInVel = _acceleration.Clone();

            // Now make the ChangeInVel a velocity instead of an acceleration by multiplying it by time
            changeInVel.Multiply(elapsedTime);

            // I have the change in velocity, so I will add it to the current velocity in order to make a new velocity
            _velocity.Add(changeInVel);
        }
Пример #3
0
        /// <summary>
        /// This function needs to be called before the timer is called.  Between this function and the timer function is when all the outside
        /// forces have a chance to influence the object (gravity, explosion blasts, conveyor belts, etc)
        /// </summary>
        /// <remarks>
        /// I've given this function a bit of thought.  It's really not needed, because when TimerFinish is done, that should be the equivalent
        /// of a new cycle.  But I like having more defined phases (even though there is an extra round of function calls to make)
        /// </remarks>
        public virtual void PrepareForNewTimerCycle()
        {
            // I can't decide whether to put this here, or the timerfinish
            _savedPosition = null;
            _elapsedTime   = 0;

            // Reset stuff
            _internalForce.Multiply(0);
            _externalForce.Multiply(0);
            _acceleration.Multiply(0);
        }
Пример #4
0
        public override void TimerTestPosition(double elapsedTime)
        {
            base.TimerTestPosition(elapsedTime);

            // Either remember the orig rotation, or restore to that orig rotation (as of PrepareForNew)
            if (_savedRotation == null)
            {
                _savedRotation = this.Rotation.Clone();
            }
            else
            {
                this.Rotation.StoreNewValues(_savedRotation);
            }

            // Remember the elapsed time that was passed in
            _elapsedTime = elapsedTime;

            // Figure out the new rotation (the body has been rotating at some velocity during the previous tick)
            if (!_angularVelocity.IsZero)
            {
                // Figure out what the angle will be
                double timedAngle = _angularVelocity.GetMagnitude();
                timedAngle *= elapsedTime;

                if (!_centerOfMass.IsZero)
                {
                    #region Rotate around center of mass

                    // Remember where the center of mass is in world coords
                    MyVector cmRotated = this.Rotation.GetRotatedVector(_centerOfMass, true);
                    MyVector cmWorld   = this.Position + cmRotated;

                    // Get the opposite of the cm
                    MyVector posRelativeToCM = cmRotated.Clone();
                    posRelativeToCM.Multiply(-1d);

                    // Rotate the center of position around the center of mass
                    posRelativeToCM.RotateAroundAxis(_angularVelocity, timedAngle);

                    // Now figure out the new center of position
                    this.Position.X = cmWorld.X + posRelativeToCM.X;
                    this.Position.Y = cmWorld.Y + posRelativeToCM.Y;
                    this.Position.Z = cmWorld.Z + posRelativeToCM.Z;

                    #endregion
                }

                // Rotate myself
                this.RotateAroundAxis(_angularVelocity, timedAngle);
            }
        }
Пример #5
0
        private void ApplyTorque(double elapsedTime)
        {
            // Calculate the new angular momentum (current + (torque * time))
            MyVector newMomentum = _internalTorque.Clone();

            newMomentum.Multiply(elapsedTime);
            _angularMomentum.Add(newMomentum);

            // Figure out the inverse of the world frame's inertia tensor
            // (Rotation * bodyInertialTensorInverse * Transposed Rotation)
            MyMatrix3 curRotation = base.RotationMatrix.Clone();
            MyMatrix3 inverseWorldInertiaTensor = MyMatrix3.Multiply(MyMatrix3.Multiply(curRotation, _inertialTensorBodyInverse), MyMatrix3.Transpose(curRotation));

            // Now all that's left is to figure out the new angular velocity
            _angularVelocity.StoreNewValues(MyMatrix3.Multiply(inverseWorldInertiaTensor, _angularMomentum));
        }
Пример #6
0
        protected void GetCollisionNormalAndPointsOfContact_SphereSphere(out MyVector normal, out double normalMagnitude, out MyVector pointOfContact1, out MyVector pointOfContact2, BallBlip ball1, BallBlip ball2)
        {
            // Vector that is perpendicular to the tangent of the collision, and it points in the direction of object 1.  Real
            // easy when dealing with spheres     :)
            normal = ball2.Ball.Position - ball1.Ball.Position;

            // Remember this length
            normalMagnitude = normal.GetMagnitude();

            // This needs to be returned as a unit vector
            normal.Divide(normalMagnitude);

            // Start them off as unit vectors
            pointOfContact1 = normal.Clone();
            pointOfContact2 = normal.Clone();

            // Finish (use the ratio of their radii)
            pointOfContact1.Multiply((ball1.Ball.Radius / (ball1.Ball.Radius + ball2.Ball.Radius)) * normalMagnitude);
            pointOfContact2.Multiply((ball2.Ball.Radius / (ball1.Ball.Radius + ball2.Ball.Radius)) * normalMagnitude * -1);		// I want this one pointing the other direction

            // Now that I have the points of contact relative to the centers of position, I need to make them
            // relative to the centers of mass
            if (ball1.TorqueBall != null)
            {
                pointOfContact1.Subtract(ball1.TorqueBall.CenterOfMass);
            }

            if (ball2.TorqueBall != null)
            {
                pointOfContact2.Subtract(ball2.TorqueBall.CenterOfMass);
            }
        }
Пример #7
0
        private void StoreMouseMove(int x, int y)
        {
            MyVector safe = new MyVector();
            safe.X = UtilityCore.GetScaledValue(_multiplier * -1d, _multiplier, 0, this.Width, x);
            safe.Y = UtilityCore.GetScaledValue(_multiplier * -1d, _multiplier, 0, this.Height, y);

            double safeMultiplier = _multiplier * SAFEPERCENT;		// I don't want to butt up against the multiplier, or store value will increase it on me
            if (safe.GetMagnitudeSquared() > safeMultiplier * safeMultiplier)
            {
                safe.BecomeUnitVector();
                safe.Multiply(safeMultiplier);
            }

            StoreNewValue(safe.X, safe.Y, 0d);
        }