(solved) first person camera falllow btKinematicCharacter

plan
Posts: 7
Joined: Sun Oct 10, 2010 8:49 am

(solved) first person camera falllow btKinematicCharacter

Post by plan »

hi, there!

i want to create a first person camera to follow the btKinematicCharacterController, how can i do?

the camera in the characterdome do not meet my need, and i use the ogre3d.

tks very much!
Last edited by plan on Wed Oct 20, 2010 1:32 am, edited 1 time in total.
User avatar
gennoevus
Posts: 39
Joined: Sun Oct 10, 2010 4:39 am

Re: first person camera falllow btKinematicCharacterControll

Post by gennoevus »

plan wrote:hi, there!

i want to create a first person camera to follow the btKinematicCharacterController, how can i do?

the camera in the characterdome do not meet my need, and i use the ogre3d.

tks very much!
Sorry that no-one replied earlier.

I'm not familiar with ogre, but it is easy to access the location and orientation data of a btKinematicCharacterController by using the getWorldTransform () member function of the connected ghost object:

Code: Select all

btTransform xform;
xform = g_ghostObject->getWorldTransform (); // xform now holds the transform data!
You can also turn the btTransform into an OpenGL type matrix:

Code: Select all

float l_matrix[16];
xform.getOpenGLMatrix(l_matrix);
plan
Posts: 7
Joined: Sun Oct 10, 2010 8:49 am

Re: first person camera falllow btKinematicCharacterControll

Post by plan »

tks for the reply!

i use below code, but i'm a little confused about it

Code: Select all

btTransform tr = ghost->getWorldTransform();               
btQuaternion rot = tr.getRotation();
btVector3 pos = tr.getOrigin(); 
does btQuaternion rot = tr.getRotation() get a quaternion in the world coordinate (represent a rotation from UNIT_X )?
how can i use this btQuaternion rot?

i use it like below, but it seems the camera and the ghost does not face the same direction.

Code: Select all

mCamera->setOrientation(BtOgre::Convert::toOgre(rot));
User avatar
gennoevus
Posts: 39
Joined: Sun Oct 10, 2010 4:39 am

Re: first person camera falllow btKinematicCharacterControll

Post by gennoevus »

plan wrote:does btQuaternion rot = tr.getRotation() get a quaternion in the world coordinate (represent a rotation from UNIT_X )?
how can i use this btQuaternion rot?
Are you familiar with matrix math? Instead of getting involved in complicated quaternions, maybe you should just use a matrix instead as I explained in my other post. example:

our example 4x4 matrix:

01 02 03 04
05 06 07 08
09 10 11 12
13 14 15 16

components 13, 14, and 15 are your x y z coordinates. If you set these to 0, the matrix basically becomes a rotation matrix.

If you multiply your model view matrix by this matrix, you will get your rotation. Sorry, I don't know how to do this with ogre because I've never used it before.
i use it like below, but it seems the camera and the ghost does not face the same direction.
Really? You could be right - to be honest I wouldn't know because I only use bullet to get the woord coordinates of the btKinematicCharacterController because I store the 'camera' orientation in my own code. You can manage the player orientation yourself and simply tell the btKinematicCharacterController to walk in that direction when you are pressing down your forward key. (the character is a capsule shape that is stuck on the y axis so changing the yaw of it in the physics engine doesn't really achieve anything)

pseudocode example:
characterController->setWalkDirection(btVector3(sin(player.direction)*WALK_SPEED,0,-cos(player.direction)*WALK_SPEED));
player.direction is the 'yaw' of the player. in a FPS, this would be the left/right looking direction

I hope this helps!
plan
Posts: 7
Joined: Sun Oct 10, 2010 8:49 am

Re: first person camera falllow btKinematicCharacterControll

Post by plan »

tks so much! but i'm a little idiot. :P

so let's make the problem a little simple(only in bullet without ogre),
how can we get the correct direction of the character?
I only use bullet to get the woord coordinates of the btKinematicCharacterController because I store the 'camera' orientation in my own code
i think this mean that, get the right direction of character and pass it to your camera in your own code, am i right?

i do this with below code,
1. create btKinematicCharacterController and make it face positive x,

Code: Select all

btTransform startTransform;
startTransform.setIdentity ();
startTransform.setOrigin (btVector3(0.0,10.0,0.0));
mPlayerGhost = new btPairCachingGhostObject();
mPlayerGhost->setWorldTransform(startTransform);
.....
2. control the character, (from the bullet demo, may be a little different with your control code)

Code: Select all

btTransform xform;
xform = mPlayerGhost->getWorldTransform ();

btVector3 forwardDir = xform.getBasis()[2];
forwardDir.normalize ();
												
btVector3 walkDirection = btVector3(0.0, 0.0, 0.0);
btScalar walkVelocity = btScalar(1.1) * 10.0; 
btScalar walkSpeed = walkVelocity * evt.timeSinceLastFrame;

//rotate view
if (gLeft)
{
	btMatrix3x3 orn = mPlayerGhost->getWorldTransform().getBasis();
	orn *= btMatrix3x3(btQuaternion(btVector3(0,1,0),0.02));
	mPlayerGhost->getWorldTransform ().setBasis(orn);
}
if (gRight)
{
	btMatrix3x3 orn = mPlayerGhost->getWorldTransform().getBasis();
	orn *= btMatrix3x3(btQuaternion(btVector3(0,1,0),-0.02));
	mPlayerGhost->getWorldTransform ().setBasis(orn);
}

if (gForward)
	walkDirection += forwardDir;

if (gBackward)
	walkDirection -= forwardDir;	


mPlayerController->setWalkDirection(walkDirection*walkSpeed);

3. get the direction and pass to the camera

Code: Select all

btTransform tr = mPlayerGhost->getWorldTransform();               
btQuaternion rot = tr.getRotation();
btVector3 pos = tr.getOrigin();

//btVector3 forwardDir1 = tr.getBasis()[2];
//forwardDir1.normalize ();

//float l_matrix[16];
//xform.getOpenGLMatrix(l_matrix);

direction of character= ????????????(btQuaternion, btVector3, or matrix )   <-----this is important to this topic
...................<----pass to the camera.

so the 3nd step is important to us, how can we get it (the direction/orientation of the character).

tks very much!
User avatar
gennoevus
Posts: 39
Joined: Sun Oct 10, 2010 4:39 am

Re: first person camera falllow btKinematicCharacterControll

Post by gennoevus »

how can we get the correct direction of the character?
Answer: Don't know! but that doesn't matter. What I am trying to say is that the direction that the capsule is facing inside the physics engine is irrelevant. the 'front' of a capsule is exactly the same shape as the 'back' or 'side,' etc.

example of modified code:

Code: Select all

float cameraYaw; // this is a global variable or something
...
if (gLeft)
{
   cameraYaw+=0.03f;
}
if (gRight)
{
   cameraYaw-=0.03f;
}

if (gForward)
   walkDirection = btVector3(sin(player.direction),0,-cos(player.direction)); 

mPlayerController->setWalkDirection(walkDirection*walkSpeed);
See? the character never changes its facing direction inside the physics engine. (in my code, anyway) all you have to do is "push" it in the direction that your camera is facing. changing the orientation of the player model can be purely visual (i.e. rotate the model to sync with cameraYaw). - but what is rendered on screen and what happens inside the physics engine are two different things.

This is only one approach, and I'm sure if you pick apart the source code of the original demo you will find how to do it your own way. I just did it this way because it was much simpler for how my brain works. but everyone thinks in different ways so doing it another way is not wrong! unfortunately i dont know off the top of my head how to get the character orientation from inside the physics engine.
plan
Posts: 7
Joined: Sun Oct 10, 2010 8:49 am

Re: first person camera falllow btKinematicCharacterControll

Post by plan »

tks for your patience!

i got your idea, and i'm trying it.
the rotation is ok now, when i turn left or right, the camera and the character face the same direction.

but another problem occured that, the character can't move forward in the current direction, but move a random directon.

i think this may be relative to player.direction, you said it
player.direction is the 'yaw' of the player. in a FPS, this would be the left/right looking direction
how exactly get the player.direction, and move the character forward.
is it an angle from the initial direction or any other thing?

sorry for bothering you so much, :P
plan
Posts: 7
Joined: Sun Oct 10, 2010 8:49 am

Re: first person camera falllow btKinematicCharacterControll

Post by plan »

solved, tks verymuch!

i'll share the code below, anyone who use the bullet+ogre may feel useful.

Code: Select all

cameraYaw = 0.0f;
btVector3 walkDirection = btVector3(0.0, 0.0, 0.0);
if (gLeft)
{
			
	cameraYaw+=0.03f;
}
if (gRight)
{
			
	cameraYaw-=0.03f;
}
if (cameraYaw != 0.0f)
{
	mCamera->yaw( Ogre::Degree(cameraYaw * 500 *evt.timeSinceLastFrame) );
	Quaternion q = mCamera->getOrientation();
	q.normalise();
	mCamera->setOrientation(q);
	mPlayerNode->setOrientation(q);

	mPlayerGhost->getWorldTransform ().setRotation(btQuaternion(q.x, q.y, q.z, q.w)
}

if (gForward)
	walkDirection +=  btVector3(mCamera->getDirection().x, mCamera->getDirection().y, mCamera->getDirection().z);
if (gBackward)
	walkDirection -=  btVector3(mCamera->getDirection().x, mCamera->getDirection().y, mCamera->getDirection().z);

mPlayerController->setWalkDirection(walkDirection*walkSpeed);
User avatar
gennoevus
Posts: 39
Joined: Sun Oct 10, 2010 4:39 am

Re: first person camera falllow btKinematicCharacterControll

Post by gennoevus »

plan wrote:solved, tks verymuch!

i'll share the code below, anyone who use the bullet+ogre may feel useful.

Code: Select all

cameraYaw = 0.0f;
btVector3 walkDirection = btVector3(0.0, 0.0, 0.0);
if (gLeft)
{
			
	cameraYaw+=0.03f;
}
if (gRight)
{
			
	cameraYaw-=0.03f;
}
if (cameraYaw != 0.0f)
{
	mCamera->yaw( Ogre::Degree(cameraYaw * 500 *evt.timeSinceLastFrame) );
	Quaternion q = mCamera->getOrientation();
	q.normalise();
	mCamera->setOrientation(q);
	mPlayerNode->setOrientation(q);

	mPlayerGhost->getWorldTransform ().setRotation(btQuaternion(q.x, q.y, q.z, q.w)
}

if (gForward)
	walkDirection +=  btVector3(mCamera->getDirection().x, mCamera->getDirection().y, mCamera->getDirection().z);
if (gBackward)
	walkDirection -=  btVector3(mCamera->getDirection().x, mCamera->getDirection().y, mCamera->getDirection().z);

mPlayerController->setWalkDirection(walkDirection*walkSpeed);
Not quite what I meant but as those crazy American people say: "Don't fix what ain't broke." :D :D