rayTest collision result coordinates differing by ±0.000015

Roflcopter
Posts: 3
Joined: Wed May 06, 2015 12:29 am

rayTest collision result coordinates differing by ±0.000015

Post by Roflcopter »

Hello. I'm mucking around trying to make a Minecraft style voxel game engine for fun and I've been using Irrlicht for collision until now but I want to try to migrate all collision to Bullet to allow for more physics options at the same time. When I still used Irrlicht's collision I would fire raycasts from the camera position in the direction of the center of the screen to pin point positions to add and remove blocks, the same way it's done in Minecraft. Basically, since all the meshes are block shaped when a raycast hits it it should intersect cleanly exactly on point zero zero zero(and so on) on the side of the block it hits.

Most of the time it works, but for some reason every once in a while it intersects on the hit side between on a value -0.000015 to +0.000015 different of the point it should be hitting instead(x.000000 that is).

For instance let's say we hit the face of block 100,100,100 on the z-side from some arbitrary position around 100,100,110 that should yield an intersection at something like 100.934312, 100.232241, 100.000000 but sometimes instead I get values like 100.934312, 100.232241, 99.999985 or 100.934312, 100.232241, 100.000002.

I have absolutely no idea why this is happening, can someone shed some light on this issue for me? I'm using a triangle mesh shape for rigid body collision and this is the code to make it:

Code: Select all

	if (Mesh->getMeshBuffer(0)->getIndexCount())
	{

		BulletMesh = new btTriangleMesh;

		S3DVertex *Vertices = (S3DVertex*)Mesh->getMeshBuffer(0)->getVertices();
		u16* Indices = Mesh->getMeshBuffer(0)->getIndices();

		for (u32 i = 0; i < Mesh->getMeshBuffer(0)->getIndexCount(); i += 3)
		{

			vector3df Tri1Pos = Vertices[Indices[i]].Pos;
			vector3df Tri2Pos = Vertices[Indices[i + 1]].Pos;
			vector3df Tri3Pos = Vertices[Indices[i + 2]].Pos;

			BulletMesh->addTriangle(btVector3(Tri1Pos.X, Tri1Pos.Y, Tri1Pos.Z), btVector3(Tri2Pos.X, Tri2Pos.Y, Tri2Pos.Z), btVector3(Tri3Pos.X, Tri3Pos.Y, Tri3Pos.Z));

		}

		btBvhTriangleMeshShape *Shape = new btBvhTriangleMeshShape(BulletMesh, true);
		btScalar Mass = 0;
		btVector3 FallInertia(0, 0, 0);
		btDefaultMotionState *MotionState = new btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 0, 0)));
		btRigidBody::btRigidBodyConstructionInfo CI(Mass, MotionState, Shape, FallInertia);
		RigidBody = new btRigidBody(CI);
		DynamicsWorld->addRigidBody(RigidBody);

	}
And this is the code that I use for the rayTest:

Code: Select all

	line3d<f32> Ray;
	Ray.start = IrrCam->getPosition();
	Ray.end = Ray.start + (IrrCam->getTarget() - Ray.start).normalize() * 256.0f;

	btVector3 RayStart(Ray.start.X, Ray.start.Y, Ray.start.Z);
	btVector3 RayEnd(Ray.end.X, Ray.end.Y, Ray.end.Z);

	btCollisionWorld::ClosestRayResultCallback RayCallback(RayStart, RayEnd);

	DynamicsWorld->rayTest(RayStart, RayEnd, RayCallback);
This is the code I use to verify which point the intersection happens:

Code: Select all

printf("Test: %f %f %f\n\n", RayCallback.m_hitPointWorld.x(), RayCallback.m_hitPointWorld.y(), RayCallback.m_hitPointWorld.z());
Any help is appreciated, thanks! :)

Also! An additional question... Is it possible to get the coordinates of each vertex of the triangle that you hit with a raycast? Irrlicht has that feature and it's very nifty.
teh_ballerer
Posts: 9
Joined: Fri Sep 26, 2014 3:31 am

Re: rayTest collision result coordinates differing by ±0.000

Post by teh_ballerer »

Read this:

http://blog.reverberate.org/2014/09/wha ... hould.html

In summary, floats (and doubles) only represent certain values exactly, so if a float can represent 0.0000001 and 0.0000004, if you hard coded a value of 0.0000002 in your code, it will really end up being 0.0000001 because floats can't represent 0.0000002.
Roflcopter
Posts: 3
Joined: Wed May 06, 2015 12:29 am

Re: rayTest collision result coordinates differing by ±0.000

Post by Roflcopter »

teh_ballerer wrote:Read this:

http://blog.reverberate.org/2014/09/wha ... hould.html

In summary, floats (and doubles) only represent certain values exactly, so if a float can represent 0.0000001 and 0.0000004, if you hard coded a value of 0.0000002 in your code, it will really end up being 0.0000001 because floats can't represent 0.0000002.
Does that really explain why a raycast is hitting a point behind or in front the triangle it's supposed to hit? I never had this problem in Irrlicht. I think I'm just doing something wrong.

Edit: You were absolutely right! I compiled the static libraries for Bullet again with BT_USE_DOUBLE_PRECISION and defined it in my project and now it's fixed, thanks :D