/// <summary> /// Calculates move in invisible mode /// </summary> /// <param name="delay">The delay between last two frames</param> public override void NonActiveRotate(float delay) { Update(delay); if (!mFlying) { if (NextLocation()) { mFlying = true; nextPostion = circularPositions.First.Value; // Get the next destination. PrepareNextPosition(); // Update the direction and the distance mDirection = nextPostion - position.Value; mDistance = mDirection.Normalise(); } else { } // Nothing to do so stay in position } else { double move = GetProperty <float>(PropertyEnum.Speed).Value *delay; mDistance -= move; if (mDistance <= .0f) // Reached destination { position.Value = nextPostion; mDirection = Mogre.Vector3.ZERO; mFlying = false; } else { position.Value += (mDirection * (float)move); } } }
/// <summary>Calculate a face normal, no w-information. </summary> public static Vector3 CalculateBasicFaceNormal(Vector3 v1, Vector3 v2, Vector3 v3) { Vector3 rkVector = v3 - v1; Vector3 result = (v2 - v1).CrossProduct(rkVector); result.Normalise(); return(result); }
private void updateBody(float deltaTime) { Position = mBodyNode.Position; mGoalDirection = Mogre.Vector3.ZERO; // we will calculate this if (mKeyDirection != Mogre.Vector3.ZERO && mBaseAnimID != AnimID.ANIM_DANCE) { // calculate actually goal direction in world based on player's key directions mGoalDirection += mKeyDirection.z * mCameraNode.Orientation.ZAxis; mGoalDirection += mKeyDirection.x * mCameraNode.Orientation.XAxis; mGoalDirection.y = 0; mGoalDirection.Normalise(); Quaternion toGoal = mBodyNode.Orientation.ZAxis.GetRotationTo(mGoalDirection); // calculate how much the character has to turn to face goal direction float yawToGoal = toGoal.Yaw.ValueDegrees; // this is how much the character CAN turn this frame float yawAtSpeed = yawToGoal / Mogre.Math.Abs(yawToGoal) * deltaTime * TURN_SPEED; // reduce "turnability" if we're in midair if (mBaseAnimID == AnimID.ANIM_JUMP_LOOP) { yawAtSpeed *= 0.2f; } // turn as much as we can, but not more than we need to if (yawToGoal < 0) { yawToGoal = System.Math.Min(0, System.Math.Max(yawToGoal, yawAtSpeed)); //yawToGoal = Math::Clamp<Real>(yawToGoal, yawAtSpeed, 0); } else if (yawToGoal > 0) { yawToGoal = System.Math.Max(0, System.Math.Min(yawToGoal, yawAtSpeed)); //yawToGoal = Math::Clamp<Real>(yawToGoal, 0, yawAtSpeed); } mBodyNode.Yaw(new Degree(yawToGoal)); // move in current body direction (not the goal direction) mBodyNode.Translate(0, 0, deltaTime * RUN_SPEED * mAnims[(int)mBaseAnimID].Weight, Node.TransformSpace.TS_LOCAL); } if (mBaseAnimID == AnimID.ANIM_JUMP_LOOP) { // if we're jumping, add a vertical offset too, and apply gravity mBodyNode.Translate(0, mVerticalVelocity * deltaTime, 0, Node.TransformSpace.TS_LOCAL); mVerticalVelocity -= GRAVITY * deltaTime; Mogre.Vector3 pos = mBodyNode.Position; if (pos.y <= CHAR_HEIGHT) { // if we've hit the ground, change to landing state pos.y = CHAR_HEIGHT; mBodyNode.Position = pos; setBaseAnimation(AnimID.ANIM_JUMP_END, true); mTimer = 0; } } }
public static Vector3 CalculateTangentSpaceVector( Vector3 position1, Vector3 position2, Vector3 position3, float u1, float v1, float u2, float v2, float u3, float v3) { //side0 is the vector along one side of the triangle of vertices passed in, //and side1 is the vector along another side. Taking the cross product of these returns the normal. Vector3 side0 = position1 - position2; Vector3 side1 = position3 - position1; //Calculate face normal Vector3 normal = side1.CrossProduct(side0); normal.Normalise(); //Now we use a formula to calculate the tangent. float deltaV0 = v1 - v2; float deltaV1 = v3 - v1; Vector3 tangent = deltaV1 * side0 - deltaV0 * side1; tangent.Normalise(); //Calculate binormal float deltaU0 = u1 - u2; float deltaU1 = u3 - u1; Vector3 binormal = deltaU1 * side0 - deltaU0 * side1; binormal.Normalise(); //Now, we take the cross product of the tangents to get a vector which //should point in the same direction as our normal calculated above. //If it points in the opposite direction (the dot product between the normals is less than zero), //then we need to reverse the s and t tangents. //This is because the triangle has been mirrored when going from tangent space to object space. //reverse tangents if necessary Vector3 tangentCross = tangent.CrossProduct(binormal); if (tangentCross.DotProduct(normal) < 0.0f) { tangent = -tangent; binormal = -binormal; } return(tangent); }
private void updateBody(float deltaTime) { goalDirection = Mogre.Vector3.ZERO; // we will calculate this if (keyDirection != Mogre.Vector3.ZERO && baseAnim.Type != ChaAnimType.CAT_CUSTOME_BLOCK) { // calculate actually goal direction in world based on player's key directions goalDirection += keyDirection.z * cameraNode.Orientation.ZAxis; goalDirection += keyDirection.x * cameraNode.Orientation.XAxis; goalDirection.y = 0; goalDirection.Normalise(); Quaternion toGoal = entityNode.Orientation.ZAxis.GetRotationTo(goalDirection); // calculate how much the character has to turn to face goal direction float yawToGoal = toGoal.Yaw.ValueDegrees; // this is how much the character CAN turn this frame float yawAtSpeed = yawToGoal / Mogre.Math.Abs(yawToGoal) * deltaTime * TURN_SPEED; // reduce "turnability" if we're in midair if (baseAnim.Type == ChaAnimType.CAT_JUMP_LOOP) { yawAtSpeed *= 0.2f; } // turn as much as we can, but not more than we need to if (yawToGoal < 0) { yawToGoal = System.Math.Min(0, System.Math.Max(yawToGoal, yawAtSpeed)); //yawToGoal = Math::Clamp<Real>(yawToGoal, yawAtSpeed, 0); } else if (yawToGoal > 0) { yawToGoal = System.Math.Max(0, System.Math.Min(yawToGoal, yawAtSpeed)); //yawToGoal = Math::Clamp<Real>(yawToGoal, 0, yawAtSpeed); } entityNode.Yaw(new Degree(yawToGoal)); // move in current body direction (not the goal direction) var dist = deltaTime * RUN_SPEED /* * baseAnim.AnimationState.Weight*/; Mogre.Vector3 displacement = new Mogre.Vector3(0, 0, dist); entityNode.Translate(displacement.x, displacement.y, displacement.z, Node.TransformSpace.TS_LOCAL); /*Get world movement*/ displacement = entityNode.Orientation * displacement; ControllerFlags flag; physicsController.Move(displacement, 0, 0.01f, out flag); entityNode.Position = new Mogre.Vector3( physicsController.Actor.GlobalPosition.x, entityNode.Position.y, physicsController.Actor.GlobalPosition.z); } if (baseAnim.Type == ChaAnimType.CAT_JUMP_LOOP) { // if we're jumping, add a vertical offset too, and apply gravity entityNode.Translate(0, verticalVelocity * deltaTime, 0, Node.TransformSpace.TS_LOCAL); verticalVelocity -= GRAVITY * deltaTime; Mogre.Vector3 pos = entityNode.Position; if (pos.y <= CHAR_HEIGHT * lastPosition.y) { // if we've hit the ground, change to landing state pos.y = CHAR_HEIGHT * lastPosition.y; entityNode.Position = pos; ControllerFlags flag; physicsController.Move(pos, 1 << 3, 0.01f, out flag); entityNode.Position = physicsController.Actor.GlobalPosition; SetBaseAnimation(anims.Where(o => o.Type == ChaAnimType.CAT_JUMP_END).First(), true); timer = 0; } } }
/// <summary> /// Moves in visible mood, it means when planet is in active solar system. /// </summary> /// <param name="delay">The delay between last two frames</param> public override void Rotate(float delay) { Update(delay); sceneNode.Roll(new Mogre.Degree((float)(GetProperty<float>(PropertyEnum.Speed).Value * GetProperty<float>(PropertyEnum.Rotate).Value * delay))); if (!mFlying) { if (NextLocation()) { mFlying = true; nextPostion = circularPositions.First.Value; // Get the next destination. PrepareNextPosition(); // Update the direction and the distance mDirection = nextPostion - position.Value; mDistance = mDirection.Normalise(); } else { }// Nothing to do so stay in position } else { double move = GetProperty<float>(PropertyEnum.Speed).Value * delay; mDistance -= move; if (mDistance <= .0f) { // Reached destination sceneNode.Position = nextPostion; position.Value = nextPostion; mDirection = Mogre.Vector3.ZERO; mFlying = false; } else { sceneNode.Translate(mDirection * (float)move); position.Value = sceneNode.Position; } } }