DeltaYaw/entity rotation problem

Blitz3D Forums/Blitz3D Programming/DeltaYaw/entity rotation problem

JustLuke(Posted 2007) [#1]
Ok, before I ask my question, I'll explain what I've got so far:

1) I've modelled a character riding a cloud. He is split into three seperate .b3d models, which I refer to in code as PLAYER_LEGS, PLAYER_BODY, and PLAYER_HEAD.

2) The mouse can be used to pan around the character.

3) Movement is relative to the direction of the camera and controlled by the arrow keys. To do this I place an invisible target to the left, right, front or back of the character, and I use deltayaw with turnentity to make the model turn smoothly in the correct direction.

I want the three parts of the body to turn to face the correct direction at a different rate (the head turns most quickly, followed by the body and then the legs) to add a nice, fluid, "twisty" feel. The code I'm using for this is:

;move relative to camera.
	
TFormVector tmpMx, 0, tmpMz, CAMERApivot , 0
TranslateEntity PLAYER_LEGS, TFormedX(), TFormedY(), TFormedZ()	
	
If Mx <> 0 Or Mz <> 0
	
        ;turn relative to movement.
		
        PositionEntity TARGET, EntityX( PLAYER_LEGS ) + TFormedX() , EntityY( PLAYER_LEGS), EntityZ( PLAYER_LEGS ) + TFormedZ()
		
        TurnEntity PLAYER_LEGS, 0 , DeltaYaw( PLAYER_LEGS, TARGET ) * .15, 0
	TurnEntity PLAYER_BODY, 0 , DeltaYaw( PLAYER_BODY, TARGET ) * .10, 0
	TurnEntity PLAYER_HEAD, 0 , DeltaYaw( PLAYER_HEAD, TARGET ) * .20, 0

EndIf

The problem is that, because of the different rates of turn, sometimes the three seperate body parts turn in different directions to each other (for example, the head might rotate clockwise whilst the body rotates anti-clockwise). This is because each body part elects to turn in the shortest direction to the target. This looks a bit freaky. What I need to do is discover which direction the head is turning (clockwise or anticlockwise) and pass this to the body and legs so that they can all rotate in the same direction (albeit at different speeds), but I'm not sure how to do this.

Can someone help?


GfK(Posted 2007) [#2]
Try creating a pivot - call it head_pivot. Move the pivot to the same location as the player's head, and rotate it to the same orientation, then move it forward a few units.

Then, use DeltaYaw with the body and head_pivot, to find out which direction to turn the body.

Then have a body_pivot, and use that with DeltaYaw to find out which way to turn the legs.

If you're using this method a lot you'd be better off getting the head_pivot and body_pivot into the right place, and parenting them to their respective body parts. That way you won't need to create/position them every frame.

Doing it this way means that each body part is turning to catch up with the body part directly above it, rather than getting them all to turn at different rates to face a single point.


Stevie G(Posted 2007) [#3]
Is it not as simple as?

;move relative to camera.
	
TFormVector tmpMx, 0, tmpMz, CAMERApivot , 0
TranslateEntity PLAYER_LEGS, TFormedX(), TFormedY(), TFormedZ()	
	
If Mx <> 0 Or Mz <> 0
	
	  ;turn relative to movement.
	PositionEntity TARGET, EntityX( PLAYER_LEGS ) + TFormedX() , EntityY( PLAYER_LEGS), EntityZ( PLAYER_LEGS ) + TFormedZ()
	
	Dy# = DeltaYaw( PLAYER_HEAD, TARGET )
			
	TurnEntity PLAYER_LEGS, 0 , Dy * .15, 0, 1
	TurnEntity PLAYER_BODY, 0 , Dy * .10, 0, 1
	TurnEntity PLAYER_HEAD, 0 , Dy * .20, 0, 1
	
EndIf