btQuaternion::slerp often fails assert

Post Reply
sipickles
Posts: 44
Joined: Thu Aug 07, 2008 6:57 am

btQuaternion::slerp often fails assert

Post by sipickles »

Hi,

I am blending my client and server positions of btRigidBodys like this:

Code: Select all

void CModel::UpdateVelocity(	const float& lx, const float& ly, const float& lz,
								const float& ax, const float& ay, const float& az )
{
		const btVector3		clientPos	= m_body->getWorldTransform().getOrigin();
		const btQuaternion	clientRot	= m_body->getWorldTransform().getRotation().normalized();

		const btVector3		serverPos( px, py, pz );
		const btQuaternion	serverRot = btQuaternion( rx, ry, rz, rw ).normalized();

		const btVector3		lerpPos		= clientPos.lerp( serverPos, SERVER_UPDATE_BIAS );
		const btQuaternion	lerpRot		= clientRot.slerp( serverRot, SERVER_UPDATE_BIAS );

		btTransform t;
		t.setIdentity();
		t.setOrigin( lerpPos );
		t.setRotation(lerpRot);
		
		m_body->setWorldTransform(t);
		m_body->setCenterOfMassTransform(t);
}
Unfortuntely, I often get an assertion failure with this callStack:

Code: Select all

 	msvcr80d.dll!_wassert(const wchar_t * expr=0x01c1e3c4, const wchar_t * filename=0x01c1e3f0, unsigned int lineno=197)  Line 384	C
 	Objects.dll!btAcos(float x=1.0000001)  Line 197 + 0x29 bytes	C++
 	Objects.dll!btQuaternion::angle(const btQuaternion & q={...})  Line 148 + 0x1e bytes	C++
 	Objects.dll!btQuaternion::slerp(const btQuaternion & q={...}, const float & t=1.0000000)  Line 196 + 0xc bytes	C++
>	Objects.dll!CModel::UpdateTransform(const float & px=698.87201, const float & py=3.2585874, const float & pz=704.51593, const float & rx=0.00022888184, const float & ry=0.024795890, const float & rz=1.5258789e-005, const float & rw=0.99966431)  Line 456	C++ 	
As you can see the assertion fails since the angle fed to btAcos > 1.0.

Why is this? My quaternions are normalised. They are generated by bullet code on the server.

My theory is that when passed thru the network engine, the serialisation process for the 4 floats used to describe the quaternion is lossy, so the client receives slightly wrong values, triggering this problem. Is there any other way than normalisation that I can correct the quaternion?

Many thanks

Simon
jorjee
Posts: 7
Joined: Fri Mar 27, 2009 12:14 am

Re: btQuaternion::slerp often fails assert

Post by jorjee »

How about if you simulate the same situation on a single side of the client/server cutting out the network?
For example, having a dummy btRigidBody which is not added to the dynamic world (and not drawn) but which you are moving around (simulating the server side), and another btRigidBody which is added to the dynamic world (and drawn) which feeds off the transformations of the dummy object maybe with a small offset (simulating the client side) just like how your client/server objects do.

This way you would know if its the network that's corrupting the values or slerp itself.
Post Reply