Camera and Collision Issues

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
ceisnaugle

Camera and Collision Issues

Post by ceisnaugle »

I'm still working on my Camera and Collision code and still am having a number of problems. I have included the basic camera update routine source below to look at, but odd things are happening. I am having the following problems:

- When backing up if I use the shift key to increase my movement rate (2X), strange things will happen with the I assume target getting screwed up when the movement rate goes above 1.0. It basically flips my view 180, goes in the right direction but seems to turn me around, then when I let go of the key it restores my view to the corret direction. Not sure if going above 1.0 is overflowing or what. I cannot call "updateAbsolutePosition" since it is protected, and not sure that is it.

- When using the routine "getCollisionResultPosition" other odd things happen. I set the ellipsoid radius in the routine but as soon as I move it drops my eyelevel to 34 (which is 1/2 the height of the ellipsoid and what is passed into the routine). Also When I approach any doorwayds, steps or anything else I cannot go through them or up them (basically ANY polygon will block even though its mayb 1" tall). Also when this happens the if I hold the move key down the screen will flash like it is alternating between 2 views. Another thing that is happening is during sliding a long a wall (this works for the most part). My target seems to become parelell with the wall during the movement and the camera reflects this, but when I let go of the key it reverts back to my normal target, thus a flip/flop between two views.

Overall Im happy with the power of the engine but there are just a numer of little things like this that cause some real issues, so if anyone has any ideas looking at the source etc for the update routine ti would be aprpecaited. BTW this update routine is called each time before the BeginScene method is called so im at my new position etc before rendering is done.

------------ Source ---------------

void CCameraNode::CheckCameraKeys()
{
// First time through?
if (FirstUpdate == true)
{
LastTime = Timer->getTime();
FirstUpdate = false;
return;
}

// Store Time Difference and Current time
s32 CurrTime = (s32)Timer->getTime();
s32 DiffTime = (CurrTime - LastTime);
LastTime = CurrTime;

// Get Key States
long AltKey = GetAsyncKeyState(VK_MENU);
long ShiftKey = GetAsyncKeyState(VK_SHIFT);

// Setup Movement Multiplier
f32 Multiplier = 1.0f;

// Check for a Multiplier
if (ShiftKey == 1 || ShiftKey < 0) Multiplier = 2.0f;

// Check for Left/Right Turns
long KeyState = GetAsyncKeyState(VK_LEFT);
if (KeyState == 1 || KeyState < 0)
{
Yaw -= (0.1f * Multiplier) * (f32)DiffTime;
if (Yaw < 0) Yaw += 360;

Update = true;
}
else
{
KeyState = GetAsyncKeyState(VK_RIGHT);
if (KeyState == 1 || KeyState < 0)
{
Yaw += (0.1f * Multiplier) * (f32)DiffTime;
if (Yaw >= 360) Yaw -= 360;

Update = true;
}
}

// Check for Up and Down keys
KeyState = GetAsyncKeyState(VK_NEXT);
if (KeyState == 1 || KeyState < 0)
{
Pitch += (0.25f * (f32)DiffTime);
if (Pitch > 85.0f) Pitch = 85.0f;

Update = true;
}
else
{
KeyState = GetAsyncKeyState(VK_PRIOR);
if (KeyState == 1 || KeyState < 0)
{
Pitch -= (0.25f * (f32)DiffTime);
if (Pitch < -85.0f) Pitch = -85.0f;

Update = true;
}
}


// Prepare for new Target etc
core::vector3df NewTarget(0,0,1);

core::matrix4 Mat;
Mat.setRotationDegrees(core::vector3df(Pitch,Yaw,Roll));
Mat.transformVect(NewTarget);

core::vector3df MoveDir = NewTarget;
MoveDir.normalize();


// Setup NewPos vector so we can compare to old position after move
core::vector3df NewPos = Position;

// Check for Forward/back Movement
KeyState = GetAsyncKeyState(VK_UP);
if (KeyState == 1 || KeyState < 0)
{
NewPos += MoveDir * (f32)DiffTime * (0.1f * Multiplier);
Update = true;
}
else {
KeyState = GetAsyncKeyState(VK_DOWN);
if (KeyState == 1 || KeyState < 0)
{
NewPos -= MoveDir * (f32)DiffTime * (0.1f * Multiplier);
Update = true;
}
}


// Do we need to update?
if (Update == true)
{
// do we have a selector
if (Selector != NULL)
{
bool OutFalling;
core::triangle3df Tri;
core::vector3df Mover = (NewPos - Position);
NewPos = CollMgr->getCollisionResultPosition(Selector,
Position,
core::vector3df(12,34,12),
Mover,
Tri,
OutFalling,
0.0005f,
core::vector3df(0.0f,-100.0f,0.0f));
}

// Here check how far moved if Position != NewPos
Position = NewPos;
Camera->setPosition(Position);

// Unable to call Protected Member
// Camera->updateAbsolutePosition();

Target = NewTarget;
Target += Position;
Camera->setTarget(Target);

Update = false;
}
}
rt
Posts: 150
Joined: Sun Nov 30, 2003 6:54 am
Location: canada
Contact:

Re: Camera and Collision Issues

Post by rt »

ceisnaugle wrote:I cannot call "updateAbsolutePosition" since it is protected, and not sure that is it.
If you derive your camera class from CCameraSceneNode then you should be able to call it from within your camera class. Create a public function which then calls updateAbsolutePosition().

Or you could hack the irrlicht source to make it a non-protected function.
ceisnaugle

Issues

Post by ceisnaugle »

At the moment the camera* is just a pointer to an ICameraSceneNode in the CameraNode class, and addCamera is used to popualte that pointer.

Everytime I have tried to create a new camera class and derive it from CCameraSceneNode I get a ton of unresolved external issues with the methods in the CCameraSceneNode Class, wasnt sure why it was happening so just used a pointer instead, but as we see it has its own issues.

Anyone have any examples of deriving a new class using CCameraSceneNode that does not hack the source up, make changes to the engine itself but is just specific to your own app?

Chris
rt
Posts: 150
Joined: Sun Nov 30, 2003 6:54 am
Location: canada
Contact:

Re: Issues

Post by rt »

ceisnaugle wrote:Anyone have any examples of deriving a new class using CCameraSceneNode that does not hack the source up, make changes to the engine itself but is just specific to your own app?
I remember posting this answer before ... ah yes on this thread http://irrlicht.sourceforge.net/phpBB2/ ... php?t=1307. in fact it was you who asked it the first time too! :shock: .. try it out and report back

remeber that your camera class constructor should look like

Code: Select all

MyCam::MyCam() : CCameraSceneNode(smgr->getRootSceneNode(),smgr,-1){ 
} 
Phunk
Posts: 78
Joined: Sun Dec 14, 2003 8:18 pm
Location: The Netherlands

Post by Phunk »

I experienced the same problems when I created my own camera class(ah, well, more like function)from a standard camera(trough addCamera ), and it has something to do with the order of SetTarged and setposition. It sounds strange, but you could encounter the same problems if you create a custom FPS cam with sligtly diffirent code than in the source. It even matters(at least in my experience) where you call the function that animates your camera(before, after or in between device->beginscene()). Your collision problems are also coming from this.
Mercior

Post by Mercior »

I too have come across the same problems when making a custom FPS cam - It is as if the setTarget function() sets an invalid target 50% of the time :(

Has anyone got a solution to this.. Or is it a bug?
Phunk
Posts: 78
Joined: Sun Dec 14, 2003 8:18 pm
Location: The Netherlands

Post by Phunk »

well I don't know about version 0.5, but I could not find any workaround or fix in ver. 4.2, I just made my cam based on a normal cam instead of on an FPS-one. when you do this, jou should be able to get it right, but experiment where you put the call( in the while(device->run) loop) to the animation code of the cam, because this makes all the diffirence. I do know, that in version 0.5, the absoluteupdate func is made public, so you should be able to use this, to make your cam work the way you want it
Guest

Post by Guest »

Oh yeah, to fix this first problem:
- When backing up if I use the shift key to increase my movement rate (2X), strange things will happen with the I assume target getting screwed up when the movement rate goes above 1.0. It basically flips my view 180, goes in the right direction but seems to turn me around, then when I let go of the key it restores my view to the corret direction. Not sure if going above 1.0 is overflowing or what. I cannot call "updateAbsolutePosition" since it is protected, and not sure that is it.
Your view is flipping because you're moving faster than your target vector. You can fix this problem my multiplying the target vector, but you'll still be left with a different type of flickering :(
Phunk
Posts: 78
Joined: Sun Dec 14, 2003 8:18 pm
Location: The Netherlands

Post by Phunk »

I do my animations like this, and then there are no problems whatsoever(but it is a 2 player screen game, so it could be that the code I deleted for this post was crucial for the cam to work, but I do not think this is true!) if your cam also has collision problems, it should also be solved with this code(at least it did for me)


void AnimateFPSCam(scene::ICameraSceneNode* cam,unsigned int player)
{
//animation stuff here
// write right target
cam->setTarget(cam->getPosition() + target);
cam->setUpVector(upvec);
cam->setPosition(pos);

}


int main()
{
while(IsRunning && device->run())
{
driver->beginScene(true, true, video::SColor(255,90,90,156));

AnimateFPSCam(camera,sw1);
smgr->setActiveCamera(camera);
smgr->drawAll();

driver->endScene();
}

return 0;

}

ow, yeah, the target vector is a NORMALIZED one, I didn't had to increase the vector to make it work, you can see a working example at http://www.freewebs.com/therealsoundofm ... acecam.zip, with sourcecode(just the cpp file, and I did NOT modify the dll, and it only compiles in VC++, as far as I know)
Mercior
Posts: 100
Joined: Tue Feb 24, 2004 1:53 am
Location: UK
Contact:

Post by Mercior »

Thanks punk, I've finally got my custom camera working :)

I actually had to use:

Code: Select all

	camera->setTarget(camVec + lAngle);
	camera->setUpVector(uAngle);
	camera->setPosition(camVec);
	camera->updateAbsolutePosition();
Post Reply