Attaching camera to a joint

Blitz3D Forums/Blitz3D Beginners Area/Attaching camera to a joint

Sph!nx(Posted 2008) [#1]
Hi, I'm trying to attach the camera to a bone of a model made in milkhape. The bone is called pl_cam_point and is located at the eyes of the human figure model.

here is my code :
; Create Player
player=LoadAnimMesh("content\models\player\player.b3d")	

; Player Camera Setup
playercam=CreateCamera()


cam_point=FindChild(player,"pl_cam_point")


If Not cam_point=0
	
	EntityParent playercam,cam_point 	
	PositionEntity playercam,EntityX(cam_point),EntityY(cam_point),EntityZ(cam_point)
	
Else
	
	DebugLog "Cam_point joint not found!"
	
EndIf



Here is my model:
http://www.goannasvencoop.com/sphinx/FTP/projects/Origin/wip/player.rar


Now, it does not show me the debuglog error, and it does seem that the camera is connected to the model, but it seems to be connected to a bone on his hand or something.


Any help is appreciated!


Zethrax(Posted 2008) [#2]
The problem is that your PositionEntity code is flagged to operate in local space rather than global space, and the co-ordinates you are giving it are presumably for global space.

Try changing

PositionEntity playercam,EntityX(cam_point),EntityY(cam_point),EntityZ(cam_point)

to

PositionEntity playercam, 0.0, 0.0, 0.0

This will position the camera at the centerpoint of the cam_point entity, in its local space (so at its exact position).

Also, you could rewrite 'If Not cam_point=0' as 'If cam_point'. Any non-zero value is considered to be a 'True' value.

Something else I'll mention while I think of it, is that operators such as Not, And, Or are actually bit level operators, rather than logical operators, so you need to be careful of the values you are evaluating when using them. They don't do a True to False comparison, but rather do a comparison for each individual bit in the values being compared.


Sph!nx(Posted 2008) [#3]
I tried it, but still the same result. Thanks anyway.


Zethrax(Posted 2008) [#4]
This code shows a cube parented to 'pl_cam_point' and positioned at point zero in its local space. The cube ends up positioned between the characters eyes, where it should be.

Global G_timer = CreateTimer( 30 )

Graphics3D 800, 600, 0, 2
SetBuffer BackBuffer()

Global G_light = CreateLight()

; Create Player
player = LoadAnimMesh( "content\models\player\player.b3d" )	

; Player Camera Setup
playercam = CreateCamera()
PositionEntity playercam, 0.0, 40.0, -60.0

cam_point = FindChild( player, "pl_cam_point" )

If cam_point
	
	cube = CreateCube()
	EntityParent cube, cam_point 
	PositionEntity cube, 0.0, 0.0, 0.0
	
Else
	
	DebugLog "Cam_point joint not found!"
	
EndIf


While Not KeyHit( 1 )
	
	UpdateWorld
	RenderWorld
	Flip
	WaitTimer G_timer
	
Wend

End



Ross C(Posted 2008) [#5]
I'm nearly 100% sure Milkshape doesn't save Bone names properly. Well, last time i used it. The way to go, is countchildren() and debuglog the names of each child, just to make sure the bones actually has the proper name


Sph!nx(Posted 2008) [#6]
Thanks Bill! I will try to implement it in right away! :)

Hi Ross, well, I checked the names in Giles and there they seem fine!


t3K|Mac(Posted 2008) [#7]
i know when you export some bones from lightwave to b3d, all bonenames will start with a blank. in lightwave: "headbone" - in exported b3d:
" headbone". maybe its some sort of this bug here too...


Zethrax(Posted 2008) [#8]
The bone is obviously being exported correctly, and with the correct name. If it wasn't, then the demo code I posted above wouldn't work correctly.


Sph!nx(Posted 2008) [#9]
I've successfully attached the camera to the joint. Here's another question.

I want to use my mouse to move the player model on his x axis and a joint in the skeleton to move the bones (where the camera is attached) on the y axis (up/down)

Here is my code
rot_point = FindChild( playermesh, "joint38" )


RotateEntity rot_point,EntityPitch(rot_point)+MouseYSpeed()/2.5,0,0 
RotateEntity player,0,EntityYaw(player)-MouseXSpeed()/2.5,0 
MoveMouse GraphicsWidth()/2,GraphicsHeight()/2 


I've managed to rotate the player perfectly but it does not move the joint the way I want to ...

Any help is appreciated!


Ross C(Posted 2008) [#10]
Note that you'll have to rotate the joint after UpdateWorld i'm sure. Maybe only if your animating though.

In what way does the joint not move correctly?


Sph!nx(Posted 2008) [#11]
Hey Ross. It doesn't move at all. I've also tried placing that code after the UpdateWorld, like you suggested, but same result.

Can it have something to do with that fact that the mesh is also doing an animation? If so, how to fix that?

If I use the camera to rotate it the roll angle gets messed up, and I really want to do this with the joint, for extra body movement realism. I have some good ideas to make a full 3D body for the FPS player, just hope I can realise them ...


edit :

Yes, its the animation. How can I still have control, while playing an animation with the rest of the joints? If its even possible...

Thanks!


Ross C(Posted 2008) [#12]
All rotations get reset to the animation stance. If you use your animate command, then rotate the joint to say:

RotateEntity rot_point,EntityPitch(rot_point)+2.5,0,0

It will be a constant rotation. Using the movexspeed() will cause the following:

joint rotation after animation = 30.5

mousexspeed = 2
joint rotation + mousexspeed = 32.5

LOOP BACK TO BEGINNING


joint rotation after animation = 30.5

mousexspeed = 1.5
joint rotation + mousexspeed = 32.0


As you see, your joint will never rotate this way properly.

You need to keep a variable, say rot_point_x, and do:

animate entity

rot_point_x# = rot_point_x# + (MouseXSpeed()/10)

RotateEntity rot_point,EntityPitch(rot_point)+rot_point_x,0,0


That should work the way you want it. Just remember, the animate command sets the rotation values for all joints/bones. So, whatever your last rotation value is you set, will mean nothing next time around.


Sph!nx(Posted 2008) [#13]
Hmm, okay, thanks Ross. Trying to figure out a workaround then. Thanks


Edit: I could make the headpart and the body separated from each other ...


Sph!nx(Posted 2008) [#14]
I separated the meshes and rotation work. I can also combine bottom animation and still move the upper part.

Yeah, like Ross told, it does not move in the right way, no matter how I set
the RotateEntity.

I'm a bit embarrassed but I do not understand Ross sollution. Can you elaborate a bit more?


Edit :

Okay, another thing, attaching the camera to a joint is no problem, but when I try to control the camera rotation (no joint this time) its gets all screwy (Wrong location, and rotation wont work).

So, I'd still like to know how to control a joint, cause I need that too, but I would also like to know how I can place and move a camere with a joint, without being affected by the joints angles...


Edit 2:

I kinda figured how to make a the camera independently, still need to know how to make joints rotate on key input and overriding the current animation on that particular joint.


Thanks!


Thanks!


Zethrax(Posted 2008) [#15]
Be careful when using the EntityPitch command. It will return duplicate values at different points of rotation. It's better to use a variable to store the pitch value.

EntityYaw and EntityRoll return useful values, but they may not be the values you expect. I'd recommend experimentation.

EntityPitch, EntityYaw, and EntityRoll can be used as a set to take a snapshot of the total rotational state of an entity, however.

Here's some code that can be used to view the rotational values returned by these commands:-



Sph!nx(Posted 2008) [#16]
Thank you very much.

I have this idea now that might work: I create the player pivot, add a mesh of a torso and legs.

Then I add a pivot as a child to a bone (somewhere in the upper torso). Next is add the mesh of the arms to that pivot. ( the arms are like a perfect axis directly at the pivot, so it will perfectly rotate around the pivot on input.

Next, I add the camera, slightly above that pivot, at eye level and also make it rotate with the same pivot, so when you look down, you don't see the faces of where the nek should be, but make a little curve and really look at your feet.

Next I add some 'hitboxes' for its head and feet, for different kind of collision detections.

If this works, I can animate both body meshes and move the camera and arms around while performing an animation!

I know, its a bit of experimentation, but fun stuff none the less!


I will post my results here!

Thanks