Questions about the ellipsoid collision...

Discuss about anything related to the Irrlicht Engine, or read announcements about any significant features or usage changes.
Post Reply
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Questions about the ellipsoid collision...

Post by christianclavet »

Hi, I've checked the IRRlicht source code and found the document mentionned in the source.

Line 506-506 from CSceneCollisionManager.cpp:
// This code is based on the paper "Improved Collision detection and Response"
// by Kasper Fauerby, but some parts are modified.
Link to the document is here (Written by Kasper Fauerby in 2003):
http://www.peroxide.dk/papers/collision/collision.pdf

I can understand only a tiny amount of the principles talked there as my math skills are not that good.

Found also this document about the same concepts with extra details and tricks by Paul Nettle (Generic Collision Detection using Ellipsoid).
http://www.paulnettle.com/pub/FluidStud ... psoids.pdf

The part of the source I'm talking about is the collision response animator that use an ellipsoid for collision detection, use gravity and find a slide plane to move. The source code is located mostly on that file: CSceneCollisionManager.cpp and CSceneCollisionManager.h

From the comments of the authors thoses methods should work in almost any situation and the ellipsoid should not get "stuck". Also in theses documents they are talking about velocity that could be reused to have a sliding and bouncing effect.

IF I'm using a really simple geometry to work on, there is no problem. But everytime I've tried with more complex geometry. I'm getting stuck, and sometimes there nothing really visible that block the way.

I'm wondering if the source could have problems :roll: :?: . Could be the way the sampling is done inside the triangle selector or if the collision is done properly :?: (the ellipsoid could enter the plane and that could explain why it's getting stuck) I understood a lot more from Paul Nettle document.

If someone could have time and enough math knowledge to see the source and check the documents to see where could be the problem, the collision response animator could be more useful.

Thanks to anyone that would take the time to to look into this.

Also note that the problem could be me! 8) Perhaps there is really some limitations of using a ellipsoid over arbitrary geometry (convave could cause problems)
CuteAlien
Admin
Posts: 9634
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

In short - that was also my experience. Also there was another thread recently with similar complains. When I used it I got stuck in all sort of situations where I didn't expect it. But I haven't found time yet to create a good test-situation to reproduce it (the code I used was complex and collision run on some server, etc).

So if you have a good test-case to reproduce this it would be welcome.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Post by christianclavet »

I could post my test level. It the got stuck at the weirdest places.

Here is my test level with a small application to run thru it written with IRRlicht.
http://www.clavet.org/forum/download/file.php?id=8816Mb

The original level was created very quickly (1 hour) in the Hammer editor.

The zip contain 2, version of the same level.
One version (OBJ) came from "Crafty", a HL2 tool to export levels in OBJ format.
The other version (B3D), is the same OBJ level that as been loaded in Gile[s] 2 and saved in B3D format.

If you navigate thrus the 2 levels (its exactly the same application). You will notice that both have the same problems, but that the B3D level problems are much more pronounced (Got stock about everywhere)
CuteAlien
Admin
Posts: 9634
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Thanks, it behaves similar as it did in my case. But I still need to find time to write a test to have a reproducible situation. I will try to do that in some weekend whenever I have a free one again (could be a while atm).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Post by christianclavet »

If you need to test other meshes. You can take IRRedit and save the scene as Level1.irr

My application is checking for that filename load it. The player is set at the position of the camera, and the collision is created from the OCTREE (need to put the mesh as octree in IRRedit.)

One you have that, you start the application and it should work.
CuteAlien
Admin
Posts: 9634
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

I found out it works if you set a larger slidingValue in createCollisionResponseAnimator. From 0.01on it started to work in your level. Figuring out what exactly happens would probably take some more work - I hope someone else might just know...


In case anyone wants to continue looking for this, this is the code I used to get rather close to the problem (needs current svn trunk and the testlevel):

Code: Select all

#include <irrlicht.h>
#include <iostream>
#include <vector>

using namespace irr;

#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif

struct Collision
{
	core::triangle3df triangle;
	core::vector3df targetWish;	// here we wanna be
	core::vector3df targetGot;	// here we are now
};
std::vector<Collision> Collisions;

class CCollisionCb : public scene::ICollisionCallback 
{
	public:
	virtual bool onCollision(const scene::ISceneNodeAnimatorCollisionResponse& animator)
	{
		Collision coll;
		
		coll.triangle = animator.getCollisionTriangle();
		coll.targetWish = animator.getTargetNode()->getPosition();
		coll.targetGot = animator.getCollisionResultPosition();
		
		Collisions.push_back(coll);	
		
		return false;
	}
};


int main()
{
	video::E_DRIVER_TYPE driverType = video::EDT_OPENGL;
	IrrlichtDevice *device =
		createDevice(driverType, core::dimension2d<u32>(640, 480), 16, false);
	if (device == 0)
		return 1; // could not create selected driver.

	video::IVideoDriver* driver = device->getVideoDriver();
	scene::ISceneManager* smgr = device->getSceneManager();
	scene::IAnimatedMesh* levelmesh = smgr->getMesh("Display_level/B3d Model/scenes/Level_IRR.b3d");
	scene::IMeshSceneNode* levelnode = 0;

	scene::ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(0, 100.0f, .3f, -1, 0, 0, true, 3.f);
	camera->setPosition(core::vector3df(2276,-200,-1312));
	camera->setTarget(core::vector3df(-70,30,-60));

	if (levelmesh)
	{
		levelnode = smgr->addOctTreeSceneNode(levelmesh->getMesh(0), 0, -1);
		if (levelnode)
		{
			levelnode->setMaterialFlag(video::EMF_LIGHTING, false);
			
			scene::ITriangleSelector* selector = smgr->createOctTreeTriangleSelector(
					levelnode->getMesh(), levelnode, 128);
			levelnode->setTriangleSelector(selector);
			
			if (selector && camera)
			{
				scene::ISceneNodeAnimatorCollisionResponse * anim = smgr->createCollisionResponseAnimator(
					selector, camera, core::vector3df(10,30,10),	// a little smmaller than in example 07 to fit through door
					core::vector3df(0,-10,0), core::vector3df(0,0,0));	// will work with larger sliding value
				anim->setCollisionCallback( new CCollisionCb() );
				camera->addAnimator(anim);
				anim->drop();
			}
			selector->drop();
		}
	}

	video::SMaterial material;
	material.NormalizeNormals = true;
	material.setTexture(0, 0);
	material.Lighting = false;

	while(device->run())
	if (device->isWindowActive())
	{
		driver->beginScene(true, true, 0);

		smgr->drawAll();
		
		driver->setMaterial(material);		
		driver->setTransform(video::ETS_WORLD, core::matrix4());

		for ( size_t i=0; i < Collisions.size(); ++i )
		{
			driver->draw3DTriangle(Collisions[i].triangle, video::SColor(0,0,255,0));
			//			driver->draw3DLine (Collisions[i].targetWish, Collisions[i].targetGot, video::SColor(255, 0, 255, 0));
			std::cout << "wish: " << Collisions[i].targetWish.X << "," << Collisions[i].targetWish.Y << "," << Collisions[i].targetWish.Z << std::endl;
			std::cout << "got: " << Collisions[i].targetGot.X << "," << Collisions[i].targetGot.Y << "," << Collisions[i].targetGot.Z << std::endl;
		}
		Collisions.clear();

		driver->endScene();
		
		// print always current position
		core::stringw str = L"Pos:";
		str += camera->getPosition().X;
		str += ",";
		str += camera->getPosition().Y;
		str += ",";
		str += camera->getPosition().Z;

		device->setWindowCaption(str.c_str());
		
	}

	device->drop();

	return 0;
}
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Post by christianclavet »

Hi, CuteAlien!

Thanks for testing this!
class CCollisionCb : public scene::ICollisionCallback
{
public:
virtual bool onCollision(const scene::ISceneNodeAnimatorCollisionResponse& animator)
{
Collision coll;

coll.triangle = animator.getCollisionTriangle();
coll.targetWish = animator.getTargetNode()->getPosition();
coll.targetGot = animator.getCollisionResultPosition();

Collisions.push_back(coll);

return false;
}
};
This is really super nice! I could use it to determine if there is a collision and even calculate the velocity. (I needed to check for the velocity of the camera, for the walk simulator. With that code, I think I could determine when there is a collision and stop the walk movement.

With a bigger sliding value, you where able to walk inside the B3D version of the level and not getting stuck?
CuteAlien
Admin
Posts: 9634
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Yeah, the ICollisionCallbacks are new - I also liked them :-)
And yes it worked for me with a bigger sliding value. You can test with the code from above. Didn't that work for you in your project? Maybe there is another problem...
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Virion
Competition winner
Posts: 2148
Joined: Mon Dec 18, 2006 5:04 am

Post by Virion »

slidingSpeed,: DOCUMENTATION NEEDED.
what's slidingSpeed for?
CuteAlien
Admin
Posts: 9634
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Post by CuteAlien »

Virion wrote:
slidingSpeed,: DOCUMENTATION NEEDED.
what's slidingSpeed for?
Mhm, that's the question - I don't know yet. That is what I mainly meant when I said that it would take more work figuring out what exactly happens.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
christianclavet
Posts: 1638
Joined: Mon Apr 30, 2007 3:24 am
Location: Montreal, CANADA
Contact:

Post by christianclavet »

Not sure, but looking at the documents, could be the velocity vector when determined with the sliding plane (taken from Paul Nettle document, page 12)
If our velocity vector is long enough, we can slide along multiple surfaces. This is possible if our sliding vector so long, that it causes a collision with another angular surface, which in turn, causes us to slide along it. If the initial velocity vector was long enough, we could end up sliding right around the inside of a rounded corner.

This is similar to a hockey puck traveling at a high velocity, sliding around the back corner in a hockey rink.
instinct
Posts: 87
Joined: Sat May 10, 2008 3:42 pm

Post by instinct »

In the thread i posted about being stuck on a scenenode (http://irrlicht.sourceforge.net/phpBB2/ ... highlight=) i thought i fixed the problem but i hadn't. Changing the sliding value to 0.1 also worked for me, while a value of 0.01 did not work. I suggest setting the default value of the slidingvalue to 0.1 since that seems to be the most bug-free value. Also, some documentation about it might help other people understanding it ;) (but then again i understand you also have other important things on your mind)
koscianski
Posts: 5
Joined: Thu Aug 13, 2009 12:35 am
Location: Brazil
Contact:

Post by koscianski »

From what I've read, the first step of math is to distort the world, so that ellipses get the shape of spheres; this makes it easier to calculate distances. BTW yes, the triangles are also distorted, but since math properties are maintained, the calculations work fine. That's the magic. The rest is 'simple' vector math between vectors, planes and the like.

Following the code I arrived at this:

core::vector3df CSceneCollisionManager::collideWithWorld {

f32 veryCloseDistance = colData.slidingSpeed;
...
if (colData.nearestDistance >= veryCloseDistance)
...}


And in function "CSceneNodeAnimatorCollisionResponse::animateNode":

// TODO: divide SlidingSpeed by frame time


First: shouldn't it be multiply speed by time, leading distance? This calculation leads to acceleration (m/s^2).

Anyway, since there is information of distance contained into "slidingspeed" (speed = distance per time), maybe that it poses no problem for the algorithm to assign it to "veryCloseDistance" (things get approximated, I guess).

By the way, it seems that there is an inconsistency in the seventh tutorial, about collision. Gravity was set as (0, -10, 0) and should be 10 meters per second. But the position of the ellipsoid was set as (0, 50, 0) and this should be 50 meters, not the position of the eyes.
Post Reply