Sign in to follow this  
JamesCobras

Lag time in Third Person Camera.

Recommended Posts

Hi guys, i have a problem, i was going to post this in the physics forums but decided it was more directx based. Here's the problem: 1. When my object accelerates the camera gets further and further away, now this can be a nice effect but obviously this could be a major bug and is not done on purpose. 2. (and this one is a more Physics question ) I'm using directx and PhysX and i need to make sure that the PhysX object is in the same orentation as the rendered one. This i do by getting a matrix from PhysX manipultion it in directx and placing it back into the object. This works fine untill i use the left and right arrow key only then does the object turn, but while it turns it freezes in place. I might try add local force next and i'l give you an update on how it goes. Here is the code: (sorry about the messy commented out code, i have been experimenting)
// this is the function used to render a single frame
void render_frame(void)
{
    d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
    d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

	
		
					if (KEY_DOWN(VK_UP))
					{
					gCharacterSpeed += 1;
					move = 1;
					
					}

					if (KEY_DOWN(VK_DOWN))
					{
					gCharacterSpeed += -2;
					move = 1;
					}
					
					if (KEY_DOWN(VK_LEFT))
					{
					YRotate = YRotate - 5; 
					stepYRotate = -5;
					}
					if (KEY_DOWN(VK_RIGHT))
					{
					YRotate = YRotate + 5;
					stepYRotate = 5;
					}
					if (!KEY_DOWN(VK_UP) && !KEY_DOWN(VK_DOWN))
					{
					move = 1;
					}

					if (!KEY_DOWN(VK_LEFT) && !KEY_DOWN(VK_RIGHT))
					{
					stepYRotate = 0;
					move = 1;
					}

					if (gCharacterSpeed < 0.5)
					{
						gCharacterSpeed = 0;
						transport.Animationloop(0.0,0.145,0);
					}
					else
					{
						transport.Animationloop(0.5,0.75,0);
					}


	D3DXMATRIX matrixtransport;
	gCharacterVec = NxVec3(gCharacterSpeed*(sin (D3DXToRadian(YRotate))),0,gCharacterSpeed*(cos (D3DXToRadian(YRotate))));
	PhysXtransport->getGlobalPose().getColumnMajor44(matrixtransport);
	matrixtransport = Rotate(0,stepYRotate,0)*matrixtransport;
	transmatrix.setColumnMajor44(matrixtransport);
	PhysXtransport->setGlobalPose(transmatrix);
	PhysXtransport->addForce(gCharacterVec);
	
	if (gScene)
	{

		GetPhysicsResults();
		StartPhysics();
	}

    d3ddev->BeginScene();

    // SET UP THE TRANSFORMS

	static float index = 0.0f; 
	index+= 3.0;    // an ever-increasing float value
	
	//D3DXMATRIX matCube;
	//cube->getGlobalPose().getColumnMajor44(matCube);
	//box.Transform(matCube);
	//box.Draw();

	D3DXMATRIX matModel;
	
	
	//chara = gSelectedController->GetCharacterActor();
	
	PhysXtransport->getGlobalPose().getColumnMajor44(matModel);
	transport.Transform(matModel);
	
	
	transport.Draw();
	
	
	D3DXMATRIX matModell;
	gTerrain->getGlobalPose().getColumnMajor44(matModell);
	room.Transform(matModell);
   	room.Draw();
	
	D3DXMATRIX matView;
	
	
	D3DXMATRIX tempmatView;
	D3DXMATRIX tempView;
	    // the view transform matrix
	
	tempView = *Rotate(0,0,0)*Translate(0,50,-500)*matModel;
	D3DXMatrixInverse(&matView,NULL,&tempView);
	
    /* next plan PhysXtransportpos = PhysXtransport->getGlobalPosition();
	
    D3DXMatrixLookAtLH(&matView,
    &D3DXVECTOR3 (50.0f, 600.0f, -600.0f),    // the camera position
    &D3DXVECTOR3 (PhysXtransportpos.x, PhysXtransportpos.y, PhysXtransportpos.z),    // the look-at position
    &D3DXVECTOR3 (0.0f, 1.0f, 0.0f));    // the up direction
	*/
    d3ddev->SetTransform(D3DTS_VIEW, &matView);    // set the view transform to matView 

    D3DXMATRIX matProjection;    // the projection transform matrix
    D3DXMatrixPerspectiveFovLH(&matProjection,
                               D3DXToRadian(45),    // the horizontal field of view
                               (FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT,    // aspect ratio
                               1.0f,    // the near view-plane
                                              20000.0f);    // the far view-plane
    d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection);    // set the projection
//float MRotation;
//float MMove;
    
    d3ddev->EndScene(); 

    d3ddev->Present(NULL, NULL, NULL, NULL);

    return;
}





All comments and solutions welcome. JamesCobras [Edited by - JamesCobras on June 5, 2009 11:12:55 AM]

Share this post


Link to post
Share on other sites
Hi,

About your 1st question, I'm using a technique for that. It's a nice effect can be seen when rotating and moving. Here's the code snippet (from the UpdateCamera() function in my GKamera class):

if (g_KameraLookAtModel == NULL) return;

D3DXMATRIX mtxRot;
D3DXVECTOR3 vPos, vDir, vOffset;

float fTimeScale = 1.0f, Len = 0.0f;
if (Lag > 0) fTimeScale = TimeScale / Lag;

D3DXMatrixIdentity (&mtxRot);
D3DXVECTOR3 vR = g_KameraLookAtModel ->g_ModelRightVek;
D3DXVECTOR3 vU = g_KameraLookAtModel ->g_ModelUpVek;
D3DXVECTOR3 vL = g_KameraLookAtModel ->g_ModelLookVek;

mtxRot._11 = vR.x; mtxRot._12 = vR.y; mtxRot._13 = vR.z;
mtxRot._21 = vU.x; mtxRot._22 = vU.y; mtxRot._23 = vU.z;
mtxRot._31 = vL.x; mtxRot._32 = vL.y; mtxRot._33 = vL.z;

D3DXVec3TransformCoord (&vOffset, &g_KameraModelOffsetVek, &mtxRot);
vPos = g_KameraLookAtModel ->g_ModelPosVek + vOffset;
vDir = vPos - g_KameraPosVek;
Len = D3DXVec3Length (&vDir);
D3DXVec3Normalize (&vDir, &vDir);

float distance = Len * fTimeScale;
if (distance > Len || Len < 0.01f) distance = Len;

if (distance > 0)
{
g_KameraPosVek += vDir * distance;
LookAt (g_KameraModel->g_ModelKonumVek);
}



Some explanations about the code:
* g_KameraLookAtModel describes a model that camera is looking at. I mean, that shows a "model" that the camera is attached to.
* g_KameraModelOffsetVek describes an offset vector between model and attached camera. This function tells how far the camera will be away from the model.
* TimeScale and Lag are the function parameters. You can use the time elapsed in your game for TimeScale. For Lag, I'm using floats in range (0, 1]. Bigger values cause the camera take longer time to update.
* I didn't write LookAt() function's definition here. But that's how it works: Function calls D3DXMatrixLookAtLH() then calculates the right, up and look vectors from the returning value. Then builds a "real" view matrix /w that vectors and camera pos. vector (I assume that you know how to build a view matrix from right, up, look and pos. vectors).
* Important Note: In Rotate() function of my model class, I wrote a rotation code for the attached camera as well. But it's not absolutely necessary.


Now about your 2nd one: Moving and rotating processes must be done by using some combinations of local forces/torques and/or linear/angular velocities. There must be an example about that: Chapter 1-Rigid Bodies\Lesson 107-Rigid Body Properties.

Hope this helps.

Share this post


Link to post
Share on other sites
Yes, but what i don't understand is that i'm getting a matrix from a PhysX model and this same matrix is controlling where a the object should be rendered and the exact matrix is also used in calculating the view perspective, i just can't work out where this "lag" is coming from.

Also i like using clear target and zbuffer separate as it makes it clearer to me.

JamesCobras

Share this post


Link to post
Share on other sites
Hi guys one problem down one to go. Using addLocalTorque worked perfectly.

Now just the lag time.

BTW the camera when rotating around the object makes the object move in a small circle, i.e. it looks like it is not centred. This only occurs when a large amount of force/speed is present.



JamesCobras

Share this post


Link to post
Share on other sites
Quote:
Original post by XVincentX
It's slower, anyway.


changed to:

d3ddev->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER , D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);



Well i'm quite new to this so i'll take you're advice.

JamesCobras

Share this post


Link to post
Share on other sites
Just so you know the following produced the same problem:


PhysXtransportpos = PhysXtransport->getGlobalPosition();

D3DXMatrixLookAtLH(&matView,
&D3DXVECTOR3 (PhysXtransportpos.x-500, PhysXtransportpos.y, PhysXtransportpos.z), // the camera position
&D3DXVECTOR3 (PhysXtransportpos.x, PhysXtransportpos.y, PhysXtransportpos.z), // the look-at position
&D3DXVECTOR3 (0.0f, 1.0f, 0.0f)); // the up direction

d3ddev->SetTransform(D3DTS_VIEW, &matView); // set the view transform to matView

D3DXMATRIX matProjection; // the projection transform matrix
D3DXMatrixPerspectiveFovLH(&matProjection,
D3DXToRadian(45), // the horizontal field of view
(FLOAT)SCREEN_WIDTH / (FLOAT)SCREEN_HEIGHT, // aspect ratio
1.0f, // the near view-plane
20000.0f); // the far view-plane
d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection); // set the projection

Share this post


Link to post
Share on other sites
Grrrrr, i really can't work out what's happening and why the object starts to slide off the screen!

Help!

Is there any chance some one can post their whole render frame function using PhysX it would also help to solve the problem.

Jamescobras

[Edited by - JamesCobras on June 5, 2009 7:53:30 AM]

Share this post


Link to post
Share on other sites
Update:

Hi guys, i have managed to isolate the problem to the camera. This is due to the fact that every thing behaves properly until the camera part is reached. This may be due to the way i'm trying to do third person cameras.

I thought i knew better and that all i had to do was invert a matrix to make it the same as a view matrix.

This I believe is not true.

Can anyone post or point me to some simple code that creates a third person camera that's local position is based on a matrix.

I have had a google for some and had a look at the game dev one but they are not what i'm looking for.

Thanks in advance

JamesCobras

Share this post


Link to post
Share on other sites
I think your problem its the time differential, for the character
speed you depend on the frame rate, and i don't know if you are
passing a time differential to physX, or you are using the fixed
time step of 1.0/60.0, check out that part, because maybe your
physX matrix are updating slower than your framerate, so you get
that "lag".

Sorry my english

Share this post


Link to post
Share on other sites
I increment it ever y frame at the start using this:


void GetPhysicsResults()
{
deltatime = UpdateTime();
//UpdateCharacter(deltatime*0.05);
// Get results from gScene->simulate(gDeltaTime)
while (!gScene->fetchResults(NX_RIGID_BODY_FINISHED, false));
}

void StartPhysics()
{
// Update the time step done in Get phys results
//gDeltaTime = UpdateTime();

// Start collision and dynamics for delta time since the last frame
gScene->simulate(deltatime);
gScene->flushStream();
}

Share this post


Link to post
Share on other sites
Has no one else come across this problem while using third person camera with PhysX, if not why do i have it!!!

Come on anyone done anything like that?

Please, i'm tearing my hair out wondering where i have gone soooo wrong!!!
It is key to my engine that i understand why. I have spent all day and i haven't even found an example of anyone using PhysX and a third person camera.

It's so weird.

Update: I have got the camera following properly, but only due to getting the direct position. I cannot use a third person camera as i have no idea how to get the information of angles out of the matrix and
->getGlobalOrientation().rotX(tranx);
will not return anything.

JamesCobras

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this