Collision Camera Demo (source code)

Show what you made with Bullet Physics SDK: Games, Demos, Integrations with a graphics engine, modeler or any other application
Flix
Posts: 456
Joined: Tue Dec 25, 2007 1:06 pm

Collision Camera Demo (source code)

Post by Flix »

Hi everybody,

I've finally ported my semi-physic camera implementation (the angular part is not physically simulated) from my Bullet-Ogre environment to plain Bullet-OpenGL and I've added an attachment with the source code here. Hope you like it.

The physic camera topic has already been discussed here: http://www.bulletphysics.com/Bullet/php ... f=9&t=3619.

I haven't included an .exe file yet, because I don't know if there are limits in the attachment's size or type (maybe I'll try in a follow-up).

INSTALLATION:
The code does not include any project file, so the fastest way to compile it is probably to temporary replace the BasicDemo files with the ones in the attachment (or to clone the project settings and replace the files). I compiled the code with the VC++ 2008 Express compiler and with current (at the time of writing) Bullet SVN version.

FEATURES:
-> ghost object frustum culling (explained here: http://www.bulletphysics.com/Bullet/php ... f=9&t=3896)
-> alternative navigation system (now camera is no more bound to a target point)
-> semi-physic camera moved by setLinearVelocity(...) methods (but by defining USE_THE_FORCE in "btCamera.cpp" we can use applyCentralForce(...) methods). I know, it's the simplest possible collision camera and not a full physic solution, but the code can be easily extended to improve it.
-> alternative colors as proposed by orange here: http://www.bulletphysics.com/Bullet/php ... f=9&t=3941

CONTROLS:
arrow keys + pgUp/pgDown -> camera movement
LMB + mouse move -> camera rotation
MMB -> picking
RMB -> shooting boxes
F1/F2 -> adjust camera velocity

LICENSE:
Free of course, you can use the code as you like it (maybe we can put it in a Bullet Demo, but I don't think that the quality is good enough...).

CODE SNIPPET:
In case somebody is too lazy to look through the code, here is the important stuff:

Code: Select all

void btDefaultCamera::bindBtCameraToInput(btScalar mousePositionRelativeToLastFrameX,btScalar mousePositionRelativeToLastFrameY,const btVector3& cameraRelativeTranslationVector,btMatrix3x3* semiPhysicCameraOrientation,btScalar* m_azi,btScalar* m_ele)	{		
		bool cameraAngleModified = (mousePositionRelativeToLastFrameX!=0 || mousePositionRelativeToLastFrameY!=0);
		if (cameraAngleModified)	{
			btMatrix3x3& q=*semiPhysicCameraOrientation;	// From now on q is the Matrix that represents the camera orientation
			btMatrix3x3 oldQ=q;								// We clone q
			btScalar& yaw = *m_azi;							// From now on yaw is *m_azi ( global yaw, not a relative delta )
			btScalar& pitch = *m_ele;						// From now on pitch is *m_ele ( global pitch, not a relative delta )
			
			pitch+= (-mousePositionRelativeToLastFrameY);	// User input modifies pitch
			yaw+= (-mousePositionRelativeToLastFrameX);		// User input modifies yaw
			if (pitch<-90.0) pitch=-90.0;					// Clamp pitch
			else if (pitch>90.0) pitch=90.0;
			
			btQuaternion qQ = btQuaternion(btRadians(yaw),btRadians(pitch),0);	// Instead we use an additional temporary quaternion, whose ctr with setEuler(...) is very reliable
			q.setRotation(qQ);													// and use it to modify the camera matrix (q) directly (because it's SEMI-physic)			
			
			// This code is a W.I.P. snippet that should "lead" the camera linear velocity in the
			// new direction of the camera (if the camera is moved by inertia and you rotate it, you
			// expect that some of its global velocity turns, as it's you that drive the camera...) 
			// Turn existing camera linear velocity (it's stored in world space):	
			oldQ = oldQ.inverse() * q;	// This matrix should give the differential orientation of the camera... well, let's hope so!
				
			btVector3 linearVelocity=this->getLinearVelocity();
			linearVelocity = oldQ.getColumn(0)*linearVelocity.x() + oldQ.getColumn(2)*linearVelocity.z();	// We take off the y component and "turn" the x and z components
			linearVelocity.setY(this->getLinearVelocity().y());	//We only turn XZ components to avoid unwanted up/down movements

			this->setLinearVelocity(0.2f*this->getLinearVelocity()+0.8*linearVelocity);	// We do a wise mix				
				
		}
	
		bool cameraPositionModified = (cameraRelativeTranslationVector!=btVector3(0.,0.,0.));
		if (cameraPositionModified)	{
			this->setDamping(0.15,0.0);		// Ideally it should be left to zero (better input range), but it's better to leave some damping on the camera always, since it can be moved by collisions that we do not handle.
					
			btQuaternion q;
			semiPhysicCameraOrientation->getRotation(q);
			this->setLinearVelocity(0.4f*this->getLinearVelocity()+0.6*65*m_speed*quatRotate(q,cameraRelativeTranslationVector));	
		}
	
}

void btDefaultCamera::onTranslationalKeyReleased()	{
	this->setDamping(0.65f,.0);	// Modify the first argument to increase damping strength.
	this->applyDamping(1.2);	// Decrease the argument to increase the camera "stopping time".
}
P.S. btDefaultCamera inherits from btCameraBase that extends btRigidBody and provides the two pure virtual methods above.

Hope you enjoy it :) !
You do not have the required permissions to view the files attached to this post.
Flix
Posts: 456
Joined: Tue Dec 25, 2007 1:06 pm

Re: Collision Camera Demo (source code)

Post by Flix »

Here I'm trying to attach a compiled version (requires VC++ 2008 redist. package, because I compiled it with the /MD option).

Unluckily I needed the .7z extension to include glut.dll and have a file size < 256 kiB.
You do not have the required permissions to view the files attached to this post.