Exemplo n.º 1
0
        public void Merge(ActorBehavior behaviour)
        {
            Vector3        rootRotation    = new Vector3(rotation);
            Vector3        rootTranslation = new Vector3(translation);
            DualQuaternion rootTransform   = DualQuaternion.FromRotationTranslation(
                behaviour.model.MainDefinition.BoneSystem.RootBone.RotationOrder.FromEulerAngles(MathExtensions.DegreesToRadians(rootRotation)),
                rootTranslation);

            behaviour.dragHandle.Transform = rootTransform.ToMatrix();

            var poseDeltas = behaviour.ikAnimator.PoseDeltas;

            poseDeltas.ClearToZero();
            foreach (var bone in behaviour.model.MainDefinition.BoneSystem.Bones)
            {
                Vector3 angles;
                if (boneRotations.TryGetValue(bone.Name, out var values))
                {
                    angles = new Vector3(values);
                }
                else
                {
                    angles = Vector3.Zero;
                }
                var twistSwing = bone.RotationOrder.FromTwistSwingAngles(MathExtensions.DegreesToRadians(angles));
                poseDeltas.Rotations[bone.Index] = twistSwing;
            }
        }
Exemplo n.º 2
0
    void drawGizmos(Color color)
    {
        var oldColor = Gizmos.color;

        Gizmos.color = color;

        var pos = transform.position;
        var rot = transform.rotation;

        var q = DualQuaternion.fromUnityTransform(rot, pos);        //new DualQuaternion(rot.conjugate(), pos);//o_O Well, whatever.

        drawDualQuaternion(q);

        foreach (Transform cur in transform)
        {
            var childQ = DualQuaternion.fromUnityTransform(cur.transform.localRotation, cur.transform.localPosition);
            //new DualQuaternion(cur.transform.localRotation.conjugate(), cur.transform.localPosition);

            var childQ2 = q * childQ;

            drawDualQuaternion(childQ2);

            const int numSteps = 10;
            for (int i = 1; i < numSteps; i++)
            {
                float t    = (float)i / (float)numSteps;
                var   tmpQ = q.sclerp(childQ2, t);
                drawDualQuaternion(tmpQ);
            }
        }

        Gizmos.color = oldColor;
    }
Exemplo n.º 3
0
    public PoseRecipe RecipizePose()
    {
        var     rootTransform   = DualQuaternion.FromMatrix(dragHandle.Transform);
        Vector3 rootRotation    = MathExtensions.RadiansToDegrees(model.MainDefinition.BoneSystem.RootBone.RotationOrder.ToEulerAngles(rootTransform.Rotation));
        Vector3 rootTranslation = rootTransform.Translation;

        Dictionary <string, float[]> boneRotations = new Dictionary <string, float[]>();
        var poseDeltas = ikAnimator.PoseDeltas;

        rootTranslation += Vector3.Transform(poseDeltas.RootTranslation / 100, rootTransform.Rotation);
        foreach (var bone in model.MainDefinition.BoneSystem.Bones)
        {
            var twistSwing = poseDeltas.Rotations[bone.Index];
            var angles     = MathExtensions.RadiansToDegrees(bone.RotationOrder.ToTwistSwingAngles(twistSwing));
            if (!angles.IsZero)
            {
                boneRotations.Add(bone.Name, angles.ToArray());
            }
        }

        return(new PoseRecipe {
            rotation = rootRotation.ToArray(),
            translation = rootTranslation.ToArray(),
            boneRotations = boneRotations
        });
    }
Exemplo n.º 4
0
        private void MaybeStartTracking(FrameUpdateParameters updateParameters, RigidBoneSystemInputs inputs, ControlVertexInfo[] previousFrameControlVertexInfos)
        {
            if (tracking == true)
            {
                //already tracking
                return;
            }

            if (!stateTracker.NonMenuActive)
            {
                return;
            }

            bool triggerPressed = stateTracker.IsPressed(EVRButtonId.k_EButton_SteamVR_Trigger);

            if (!triggerPressed)
            {
                return;
            }

            tracking = true;

            TrackedDevicePose_t gamePose          = updateParameters.GamePoses[stateTracker.DeviceIdx];
            Matrix         controllerTransform    = gamePose.mDeviceToAbsoluteTracking.Convert();
            DualQuaternion controllerTransformDq  = DualQuaternion.FromMatrix(controllerTransform);
            var            worldSourcePosition    = controllerTransformDq.Translation * 100;
            var            worldSourceOrientation = controllerTransformDq.Rotation;

            sourceBone = parentInstance.MapPositionToBone(worldSourcePosition, previousFrameControlVertexInfos);
            var inverseSourceBoneTotalTransform = sourceBone.GetChainedTransform(inputs).Invert();

            boneRelativeSourcePosition    = inverseSourceBoneTotalTransform.Transform(worldSourcePosition) - sourceBone.CenterPoint;
            boneRelativeSourceOrientation = worldSourceOrientation.Chain(inverseSourceBoneTotalTransform.Rotation);
        }
Exemplo n.º 5
0
        private InverseKinematicsGoal MaybeContinueTracking(FrameUpdateParameters updateParameters)
        {
            if (!tracking)
            {
                return(null);
            }

            if (!stateTracker.NonMenuActive)
            {
                tracking = false;
                return(null);
            }

            bool triggerPressed = stateTracker.IsPressed(EVRButtonId.k_EButton_SteamVR_Trigger);

            if (!triggerPressed)
            {
                tracking = false;
                return(null);
            }

            TrackedDevicePose_t gamePose = updateParameters.GamePoses[stateTracker.DeviceIdx];
            Matrix controllerTransform   = gamePose.mDeviceToAbsoluteTracking.Convert();
            var    controllerTransformDq = DualQuaternion.FromMatrix(controllerTransform);
            var    targetPosition        = controllerTransformDq.Translation * 100;
            var    targetOrientation     = controllerTransformDq.Rotation;

            return(new InverseKinematicsGoal(sourceBone,
                                             boneRelativeSourcePosition, boneRelativeSourceOrientation,
                                             targetPosition, targetOrientation));
        }
Exemplo n.º 6
0
    public Vector3 transformPoint(Vector3 arg)
    {
        var val    = new DualQuaternion(new Quaternion(0.0f, 0.0f, 0.0f, 1.0f), new Quaternion(arg.x, arg.y, arg.z, 0.0f));
        var result = this * val *this.translationConjugate();

        return(new Vector3(result.dual.x, result.dual.y, result.dual.z));
    }
Exemplo n.º 7
0
        /// <summary>
        /// Compute the coordinates of the end activator for a EPSON SCARA robot.
        /// </summary>
        /// <param name="pose">
        /// The robot pose.
        /// </param>
        /// <returns>
        /// The coordinates of the end effector.
        /// </returns>
        private static Vector3 ScaraForwardKinematics(ScaraRobotPose pose)
        {
            // Here we create the three rotation quaternions
            // Note that we are directly using the Plücker coordinates of the joint axes.
            // However, rotation would work for axes defined by an orientation and a point belonging to the line.
            var r1 = DualQuaternion.CreateRotation(pose.Theta1, Vector3.UnitZ, new Vector3(0, 0, 0));
            var r2 = DualQuaternion.CreateRotation(pose.Theta2, Vector3.UnitZ, new Vector3(300, 0, 0));
            var r3 = DualQuaternion.CreateRotation(pose.Theta3, Vector3.UnitZ, new Vector3(650, 0, 0));

            // Fourth joint is translation
            var t = DualQuaternion.CreateTranslation(pose.Z, -Vector3.UnitZ);

            // The end effector position for the reference configuration
            var endEffector = DualQuaternion.CreateTranslation(new Vector3(650, 0, 318));

            // Here we combine the four displacements into a single one and return it.
            // Notice we also append the end-effector at the reference configuration.
            // The order of application of the transformations is right-most is applied first.
            var displacements = DualQuaternion.Multiply(r1, r2, r3, t, endEffector);

            // Here we basically use the action f4g (specified in libdq’s manual) to transform the origin point.
            // This will give us the forward kinematics of the robot.
            var result = displacements.TransformPoint();

            return(result);
        }
    public DualQuaternion Invert()
    {
        var inverseRotation    = Quaternion.Invert(Rotation);
        var inverseTranslation = Vector3.Transform(-Translation, inverseRotation);

        return(DualQuaternion.FromRotationTranslation(inverseRotation, inverseTranslation));
    }
Exemplo n.º 9
0
    public Matrix4x4 ToMatrix()
    {
        DualQuaternion q = Normalized();
        Matrix4x4      M = Matrix4x4.identity;
        float          w = q.real.w;
        float          x = q.real.x;
        float          y = q.real.y;
        float          z = q.real.z;

        // Extract rotational information
        M.m00 = w * w + x * x - y * y - z * z;
        M.m10 = 2 * x * y + 2 * w * z;
        M.m20 = 2 * x * z - 2 * w * y;
        M.m01 = 2 * x * y - 2 * w * z;
        M.m11 = w * w + y * y - x * x - z * z;
        M.m21 = 2 * y * z + 2 * w * x;
        M.m02 = 2 * x * z + 2 * w * y;
        M.m12 = 2 * y * z - 2 * w * x;
        M.m22 = w * w + z * z - x * x - y * y;
        // Extract translation information
        Quaternion t = q.dual.Scale(2.0f) * q.real.Conjugate();

        M.m03 = t.x;
        M.m13 = t.y;
        M.m23 = t.z;
        return(M);
    }
Exemplo n.º 10
0
    private DualQuaternion GetObjectCenteredRotationTransform(ChannelOutputs outputs, ScalingTransform parentScale)
    {
        DualQuaternion localSpaceTransform = GetJointCenteredRotationTransform(outputs, parentScale.Scale);
        Vector3        centerPoint         = CenterPoint.GetValue(outputs);

        centerPoint = parentScale.Transform(centerPoint);
        return(DualQuaternion.FromTranslation(-centerPoint).Chain(localSpaceTransform).Chain(DualQuaternion.FromTranslation(+centerPoint)));
    }
Exemplo n.º 11
0
    public static DualQuaternion Normalize(DualQuaternion dq)
    {
        float len = Mathf.Sqrt(dq.real.x * dq.real.x + dq.real.y * dq.real.y + dq.real.z * dq.real.z + dq.real.w * dq.real.w);

        dq.real = dq.real.Multiply(1 / len);
        dq.dual = dq.dual.Multiply(1 / len);
        return(dq);
    }
Exemplo n.º 12
0
    public static DualQuaternion fromUnityTransform(Quaternion rot, Vector3 pos)
    {
        var r      = new DualQuaternion(rot.conjugate(), Vector3.zero);
        var t      = new DualQuaternion(Quaternion.identity, pos);
        var result = t * r;

        return(result);
    }
Exemplo n.º 13
0
    private DualQuaternion GetJointCenteredRotationTransform(ChannelOutputs outputs, Matrix3x3 parentScale)
    {
        Quaternion worldSpaceRotation = GetRotation(outputs);

        Vector3 translation = Vector3.Transform(Translation.GetValue(outputs), parentScale);

        return(DualQuaternion.FromRotationTranslation(worldSpaceRotation, translation));
    }
Exemplo n.º 14
0
    public StagedSkinningTransform GetChainedTransform(ChannelOutputs outputs, StagedSkinningTransform parentTransform)
    {
        ScalingTransform scalingTransform        = GetObjectCenteredScalingTransform(outputs);
        ScalingTransform chainedScalingTransform = scalingTransform.Chain(parentTransform.ScalingStage);

        DualQuaternion rotationTransform        = GetObjectCenteredRotationTransform(outputs, parentTransform.ScalingStage);
        DualQuaternion chainedRotationTransform = rotationTransform.Chain(parentTransform.RotationStage);

        return(new StagedSkinningTransform(chainedScalingTransform, chainedRotationTransform));
    }
Exemplo n.º 15
0
    public void Add(float weight, DualQuaternion dq)
    {
        if (Quaternion.Dot(realAccumulator, dq.Real) < 0)
        {
            weight *= -1;
        }

        realAccumulator += weight * dq.Real;
        dualAccumulator += weight * dq.Dual;
    }
    public void TestFromAndToRotationTranslation()
    {
        Quaternion rotation    = Quaternion.RotationYawPitchRoll(1, 2, 3);
        Vector3    translation = new Vector3(2, 3, 4);

        DualQuaternion dq = DualQuaternion.FromRotationTranslation(rotation, translation);

        Assert.AreEqual(0, Vector3.Distance(translation, dq.Translation), 1e-6);
        Assert.IsTrue(dq.Rotation == rotation || dq.Rotation == -rotation);
    }
Exemplo n.º 17
0
 void Start()
 {
     transform.position = Targets.position;
     transform.rotation = Targets.rotation;
     dualQuaternions.Add(new DualQuaternion(transform.position, transform.rotation));
     foreach (Transform tf in Targets)
     {
         var dq = new DualQuaternion(tf.position, tf.rotation);
         dualQuaternions.Add(dq);
     }
 }
Exemplo n.º 18
0
 public override bool Equals(object obj)
 {
     if (obj is DualQuaternion)
     {
         DualQuaternion dq = (DualQuaternion)obj;
         return(dq == this);
     }
     else
     {
         return(false);
     }
 }
    public void TestFromMatrixRobustness()
    {
        Quaternion rotation    = Quaternion.RotationYawPitchRoll(1, 2, 3);
        Vector3    translation = new Vector3(2, 3, 4);
        Vector3    scale       = new Vector3(3, 4, 5);
        Matrix     matrix      = Matrix.Scaling(scale) * Matrix.RotationQuaternion(rotation) * Matrix.Translation(translation);

        DualQuaternion dq = DualQuaternion.FromMatrix(matrix);

        Assert.AreEqual(0, Vector3.Distance(translation, dq.Translation), 1e-6);
        Assert.IsTrue(dq.Rotation == rotation || dq.Rotation == -rotation);
    }
Exemplo n.º 20
0
    public static DualQuaternion Inverse(DualQuaternion dq)
    {
        float real = (dq.real.w * dq.real.w + dq.real.x * dq.real.x + dq.real.y * dq.real.y + dq.real.z * dq.real.z),
              dual = (dq.real.w * dq.dual.w + dq.real.x * dq.dual.x + dq.real.y * dq.dual.y + dq.real.z * dq.dual.z) * 2.0f;

        DualQuaternion other;

        other.real = Quaternion.Inverse(dq.real);
        other.dual = new Quaternion(dq.dual.x * (dual - real), dq.dual.y * (dual - real), dq.dual.z * (dual - real), dq.dual.w * (real - dual));

        return(other.normalize);
    }
Exemplo n.º 21
0
    // Recursively update all bone transforms
    static void FetchBoneMatrices(Transform bone, DualQuaternion parentTransform)
    {
        if (allBones.TryGetValue(bone.name, out int idx))
        {
            boneTransforms[idx] = parentTransform * (new DualQuaternion(bone));

            foreach (Transform childBone in bone)
            {
                FetchBoneMatrices(childBone, boneTransforms[idx]);
            }
        }
    }
    public void TestTransform()
    {
        Vector3    translation = new Vector3(2, 3, 4);
        Quaternion rotation    = Quaternion.RotationYawPitchRoll(1, 2, 3);
        Matrix     matrix      = Matrix.RotationQuaternion(rotation) * Matrix.Translation(translation);

        DualQuaternion dq = DualQuaternion.FromRotationTranslation(rotation, translation);

        Vector3 v = new Vector3(3, 4, 5);

        Assert.IsTrue(dq.Transform(v) == Vector3.TransformCoordinate(v, matrix));
    }
Exemplo n.º 23
0
    public void Apply(ChannelInputs inputs, Pose pose, DualQuaternion rootTransform)
    {
        foreach (Bone bone in boneSystem.Bones)
        {
            bone.AddRotation(orientationOutputs, inputs, pose.BoneRotations[bone.Index]);
        }

        var rescaledRootTransform = DualQuaternion.FromRotationTranslation(rootTransform.Rotation, rootTransform.Translation * 100);

        boneSystem.RootBone.SetRotation(orientationOutputs, inputs, rescaledRootTransform.Rotation);
        boneSystem.RootBone.SetTranslation(inputs, rescaledRootTransform.Translation);

        boneSystem.Bones[1].SetTranslation(inputs, pose.RootTranslation);
    }
    public void TestInvert()
    {
        Vector3        translation = new Vector3(2, 3, 4);
        Quaternion     rotation    = Quaternion.RotationYawPitchRoll(1, 2, 3);
        DualQuaternion dq          = DualQuaternion.FromRotationTranslation(rotation, translation);

        Vector3 v = new Vector3(3, 4, 5);

        Vector3 transformed        = dq.Transform(v);
        Vector3 inverseTransformed = dq.Invert().Transform(transformed);

        Assert.AreEqual(
            v,
            inverseTransformed);
    }
Exemplo n.º 25
0
    void drawDualQuaternion(DualQuaternion q)
    {
        Vector3 x = Vector3.right * 5.0f;
        Vector3 y = Vector3.up * 5.0f;
        Vector3 z = Vector3.forward * 5.0f;
        Vector3 p = Vector3.zero;

        var x1 = q.transformPoint(x);
        var y1 = q.transformPoint(y);
        var z1 = q.transformPoint(z);
        var p1 = q.transformPoint(p);

        Gizmos.DrawLine(p1, x1);
        Gizmos.DrawLine(p1, y1);
        Gizmos.DrawLine(p1, z1);
    }
Exemplo n.º 26
0
        public void SimpleDualQuaternionTest2()
        {
            // Translation 5 units in X direction
            var translation = DualQuaternion.CreateTranslation(5, Vector3.UnitX);

            // Rotation of PI/2 around Z axis centered on origin - We are using Plücker coordinates to describe the axis of rotation
            var rotation = DualQuaternion.CreateRotationPlucker(Math.PI / 2f, Vector3.UnitZ, Vector3.Zero);

            // We compose displacements, translation is applied first
            var displacement = rotation * translation;

            // We apply the point transform (Clifford conjugation for points) on the origin point using the displacement
            var point = displacement.TransformPoint();

            // Assert
            Assert.That(point, Is.EqualTo(new Vector3(0, 5, 0)));
        }
Exemplo n.º 27
0
    static void BakeFrame(uint globalFrameIndex, bool morton, int size, int weaponSize, Color[][] pixels, Color[][] weaponPixels)
    {
        // Store the bone animation to an array of textures
        for (uint bone = 0; bone < allBones.Count; bone++)
        {
            DualQuaternion dq = boneTransforms[bone];
            if (dq == null)
            {
                continue;
            }
            var row0 = dq.real.ToVector4();
            var row1 = dq.dual.ToVector4();

            uint z;

            if (morton)
            {
                uint y = globalFrameIndex;
                uint x = bone;
                z = MathHelper.EncodeMorton(x, y);
            }
            else
            {
                uint y = globalFrameIndex % (uint)size;
                uint x = bone + globalFrameIndex / (uint)size * (uint)allBones.Count;
                z = y * (uint)size + x;
            }
            pixels[0][z] = row0;
            pixels[1][z] = row1;

            if (bone == weaponBoneID)
            {
                uint y = globalFrameIndex % (uint)weaponSize;
                uint x = 0 + globalFrameIndex / (uint)weaponSize * 1;
                z = y * (uint)weaponSize + x;
                weaponPixels[0][z] = row0;
                weaponPixels[1][z] = row1;
            }
        }
    }
Exemplo n.º 28
0
    public ChannelInputs Update(ChannelInputs shapeInputs, FrameUpdateParameters updateParameters, ControlVertexInfo[] previousFrameControlVertexInfos)
    {
        ChannelInputs inputs = new ChannelInputs(shapeInputs);

        for (int idx = 0; idx < inputs.RawValues.Length; ++idx)
        {
            inputs.RawValues[idx] += model.Inputs.RawValues[idx];
        }

        dragHandle.Update(updateParameters);
        DualQuaternion rootTransform = DualQuaternion.FromMatrix(dragHandle.Transform);

        var blendedPose = GetBlendedPose(updateParameters.Time);

        poser.Apply(inputs, blendedPose, rootTransform);

        ikAnimator.Update(updateParameters, inputs, previousFrameControlVertexInfos);

        proceduralAnimator.Update(updateParameters, inputs);

        return(inputs);
    }
Exemplo n.º 29
0
        void animate()
        {
            //			if (updateMatrices) {
            //				heolienne.UpdateModelsMat ();
            //				updateMatrices = false;
            //				gridCacheIsUpToDate = false;
            //			}
            DualQuaternion dq = new DualQuaternion(Quaternion.FromEulerAngles(0f, heolAngle, 0f), new Vector3(0f, 0f, 0f));

//			for (int i = 0; i < heoliennes.InstancedDatas.Length; i++) {
//				heoliennes.InstancedDatas [i].quat0 = new DualQuaternion(Quaternion.FromEulerAngles(heolAngle*0.2f,0f,0f),new Vector3(0f,0f,0f)).m_real;
//				heoliennes.InstancedDatas [i].bpos1 = dq.m_dual;
//				heoliennes.InstancedDatas [i].quat1 = heoliennes.InstancedDatas [i].quat0*dq.m_real;
//			}
//			heoliennes.UpdateInstancesData ();

            for (int i = 0; i < heollow.InstancedDatas.Length; i++)
            {
                //heollow.InstancedDatas [i].bpos1 = dq.m_dual;
                heollow.InstancedDatas [i].quat1 = dq.m_real;
            }
            heollow.UpdateInstancesData();

//			for (int i = 0; i < pawn.InstancedDatas.Length; i++) {
//				pawn.InstancedDatas [i].quat1 = Quaternion.FromEulerAngles(pawnAngle,pawnAngle,pawnAngle);
//			}
//			pawn.UpdateInstancesData ();
//
//			pawnAngle += pawnAngleIncrement;
//
//			if (pawnAngleIncrement > 0f){
//				if (pawnAngle > pawnAngleLimit)
//					pawnAngleIncrement = -pawnAngleIncrement;
//			}else if (pawnAngle < -pawnAngleLimit)
//				pawnAngleIncrement = -pawnAngleIncrement;

            heolAngle += MathHelper.Pi * 0.007f;
        }
Exemplo n.º 30
0
    public static DualQuaternion sclerp(DualQuaternion from, DualQuaternion to, float t)
    {
        float dot = from.dot(to);

        if (dot < 0)
        {
            to = to * -1.0f;
        }
        var diff = from.conjugate() * to;

        var vr = diff.real.getVectorPart();
        var vd = diff.dual.getVectorPart();

        float invr = 1.0f / Mathf.Sqrt(Vector3.Dot(vr, vr));

        float angle = 2.0f * Mathf.Acos(diff.real.w);
        float pitch = -2.0f * diff.dual.w * invr;

        Vector3 dir    = vr * invr;
        Vector3 moment = (vd - dir * pitch * diff.real.w * 0.5f) * invr;

        angle *= t;
        pitch *= t;

        float sinAngle = Mathf.Sin(0.5f * angle);
        float cosAngle = Mathf.Cos(0.5f * angle);

        var result = new DualQuaternion();

        result.real = new Quaternion(dir.x * sinAngle, dir.y * sinAngle, dir.z * sinAngle, cosAngle);
        var rdv = (sinAngle * moment + pitch * 0.5f * cosAngle * dir);

        result.dual = new Quaternion(rdv.x, rdv.y, rdv.z, -pitch * 0.5f * sinAngle);

        return(result);
    }
Exemplo n.º 31
0
		void animate()
		{

			//			if (updateMatrices) {
			//				heolienne.UpdateModelsMat ();
			//				updateMatrices = false;
			//				gridCacheIsUpToDate = false;
			//			}
			DualQuaternion dq = new DualQuaternion(Quaternion.FromEulerAngles(0f,heolAngle,0f),new Vector3(0f,0f,0f));
//			for (int i = 0; i < heoliennes.InstancedDatas.Length; i++) {
//				heoliennes.InstancedDatas [i].quat0 = new DualQuaternion(Quaternion.FromEulerAngles(heolAngle*0.2f,0f,0f),new Vector3(0f,0f,0f)).m_real;
//				heoliennes.InstancedDatas [i].bpos1 = dq.m_dual;
//				heoliennes.InstancedDatas [i].quat1 = heoliennes.InstancedDatas [i].quat0*dq.m_real;
//			}
//			heoliennes.UpdateInstancesData ();

			for (int i = 0; i < heollow.InstancedDatas.Length; i++) {
				//heollow.InstancedDatas [i].bpos1 = dq.m_dual;
				heollow.InstancedDatas [i].quat1 = dq.m_real;
			}
			heollow.UpdateInstancesData ();

//			for (int i = 0; i < pawn.InstancedDatas.Length; i++) {
//				pawn.InstancedDatas [i].quat1 = Quaternion.FromEulerAngles(pawnAngle,pawnAngle,pawnAngle);
//			}
//			pawn.UpdateInstancesData ();
//
//			pawnAngle += pawnAngleIncrement;
//
//			if (pawnAngleIncrement > 0f){
//				if (pawnAngle > pawnAngleLimit)
//					pawnAngleIncrement = -pawnAngleIncrement;
//			}else if (pawnAngle < -pawnAngleLimit)
//				pawnAngleIncrement = -pawnAngleIncrement;

			heolAngle += MathHelper.Pi * 0.007f;			
		}