Пример #1
0
        /// <summary>
        /// Allows to update the transformation of the entity. Accounts for the
        /// hierachy and uses flags to only update properties which really 
        /// need a refresh.
        /// </summary>
        /// <param name="gameTime">A snapshot of timing values.</param>
        public override void Update(GameTime gameTime)
        {
            // Iterate all available child nodes
            for (int i = 0, n = _children.Count; i != n; ++i)
            {
                // Cache the currently iterated child node
                TransformComponent child = _children[i];

                // Enforce an transformation update on the child node if any
                // of the properties have been modified
                if (_propertyChangedFlag != PropertyChangedFlag.None)
                    child._dirtyFlag |= DirtyFlags.Transform;

                // Allow the child component to do the same
                if (child.Enabled)
                    child.Update(gameTime);
            }

            // Notify subscribers that some properties changed
            if ((_propertyChangedFlag & PropertyChangedFlag.Scale) != 0
                || (_propertyChangedFlag & PropertyChangedFlag.Orientation) != 0
                || (_propertyChangedFlag & PropertyChangedFlag.Translation) != 0)
                OnChanged();

            // Notify subscribers that the position changed
            if ((_propertyChangedFlag & PropertyChangedFlag.Translation) != 0)
                OnPositionChanged();

            // Notify subscribers that the orientation changed
            if ((_propertyChangedFlag & PropertyChangedFlag.Orientation) != 0)
                OnRotationChanged();

            // Reset the property changed flag
            _propertyChangedFlag = PropertyChangedFlag.None;
        }
Пример #2
0
        /// <summary>
        /// Rotates the entity around a certain axis.
        /// </summary>
        /// <param name="axis">The axis to rotate around.</param>
        /// <param name="radians">The angle in radians.</param>
        public void RotateAround(Vector3 axis, float radians)
        {
            // Perform rotation
            Quaternion rotate;
            Quaternion.CreateFromAxisAngle(ref axis, radians, out rotate);
            Quaternion.Multiply(ref _rotation, ref rotate, out _rotation);

            // Accumulate for numerical errors
            _rotation.Normalize();

            // Force an update of dependent properties
            _dirtyFlag |= (DirtyFlags.LocalAxis | DirtyFlags.Transform);
            _propertyChangedFlag |= PropertyChangedFlag.Orientation;
        }
Пример #3
0
        /// <summary>
        /// Rotates the entity using roll, yaw and pitch values.
        /// </summary>
        /// <param name="x">The angle used to roll the entity in radians (rotate around x-Axis).</param>
        /// <param name="y">The angle used to yaw the entity in radians (rotate around y-Axis).</param>
        /// <param name="z">The angle used to pitch the entity in radians (rotate around z-Axis).</param>
        /// <param name="space">The coordinate system that should be used to rotate the entity: local or world space.</param>
        public void Rotate(float x, float y, float z, TransformationSpace space)
        {
            // Perform rotation
            Quaternion rotate = Quaternion.CreateFromYawPitchRoll(y, x, z);

            switch (space)
            {
                case TransformationSpace.Local:
                    Quaternion.Multiply(ref _rotation, ref rotate, out _rotation);
                    break;
                case TransformationSpace.World:
                    Quaternion.Multiply(ref rotate, ref _rotation, out _rotation);
                    break;
            }

            // Accumulate for numerical errors
            _rotation.Normalize();

            // Force an update of dependent properties
            _dirtyFlag |= (DirtyFlags.LocalAxis | DirtyFlags.Transform);
            _propertyChangedFlag |= PropertyChangedFlag.Orientation;
        }
Пример #4
0
 /// <summary>
 /// Resets the current component to its original state.
 /// </summary>
 public void Reset()
 {
     _scale = Vector3.One;
     _rotation = Quaternion.Identity;
     _translation = Vector3.Zero;
     _dirtyFlag = DirtyFlags.All;
     _propertyChangedFlag = PropertyChangedFlag.All;
 }
Пример #5
0
        /// <summary>
        /// Moves the entity the specified amount into the specified
        /// direction.
        /// </summary>
        /// <param name="direction">The direction to move.</param>
        /// <param name="amount">The amount to move the entity into that direction.</param>
        /// <param name="space">The coordinate system that should be used to move the entity: local or world space.</param>
        public void Move(Vector3 direction, float amount, TransformationSpace space)
        {
            if (space == TransformationSpace.Local)
            {
                Vector3.Transform(ref direction, ref _rotation, out direction);
                direction.Normalize();
            }

            _translation += direction * amount;
            _dirtyFlag |= DirtyFlags.Transform;
            _propertyChangedFlag |= PropertyChangedFlag.Translation;
        }
Пример #6
0
        /// <summary>
        /// Forces the entity to look at the specified target position.
        /// </summary>
        /// <param name="target">The position to look at.</param>
        /// <param name="up">A vector which specifies the up direction of the entity.</param>
        public void LookAt(Vector3 target, Vector3 up)
        {
            // Calculate the new facing vector
            Vector3 forward = Vector3.Normalize(target - _translation);

            // Calculate the rotation axis
            Vector3 rotationAxis = Vector3.Normalize(Vector3.Cross(Forward, forward));

            // Calculate the dot product which will be used to calculate the
            // rotation angle
            float dotProduct = Vector3.Dot(Forward, forward);

            // Ensure that the two forward vectors do not point in opposite
            // directions
            if (Math.Abs(dotProduct + 1f) < float.Epsilon)
                _rotation = new Quaternion(up, MathHelper.Pi);

            // Ensure that both forward vectors do not point in the same
            // direction
            else if (Math.Abs(dotProduct - 1f) < float.Epsilon)
                _rotation = Quaternion.Identity;

            // Calculate the absolute rotation to look at the target point
            else
                Quaternion.CreateFromAxisAngle(ref rotationAxis, (float)Math.Acos(dotProduct), out _rotation);

            // Force an update of dependent properties
            _dirtyFlag |= (DirtyFlags.LocalAxis | DirtyFlags.Transform);
            _propertyChangedFlag |= PropertyChangedFlag.Orientation;
        }