Another collision implimentation

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
juliusctw
Posts: 392
Joined: Fri Apr 21, 2006 6:56 am
Contact:

Another collision implimentation

Post by juliusctw »

I implemented my own collision, it is not as good as the current one, but it is much more light weight and probably good enough for 90% of the stuff. I think the version i cut and pasted here is what I have inside my project.

it is pretty easy to use, just add the animator to a sceneNode and give it the selectors.


C++ and header

Code: Select all

#include "collisionAnimator.h"


namespace irr
{
namespace scene
{


//! constructor
collisionAnimator::collisionAnimator(ISceneCollisionManager* cmgr, ITriangleSelector* selector,
float &g,	bool &lg, float height, float radius)
:Cmgr(cmgr), Selector(selector), Height(height), Radius(radius) 
{
	begin = true;
	leaveGround = ≶
	gravity = &g;
	falling = false;
}


collisionAnimator::~collisionAnimator()
{
}

void collisionAnimator::setSelector(ITriangleSelector* selector)
{
	Selector = selector;
}
//! animates a scene node
void collisionAnimator::animateNode(ISceneNode* node, u32 timeMs)
{
	if (!node) return;

	End = node->getPosition();

	if(begin)
	{
		Start = node->getPosition();
		begin = false;
		return;
	}


	if(End == Start)
		return;

	finalPosition = End;
	core::vector3df origV = End - Start;
	Vector = End - Start;
	Vector = Radius*Vector.normalize();
	irr::core::line3df fowardline = irr::core::line3df(Start, (Start + Vector));
	
	if(Cmgr->getCollisionPoint(fowardline, Selector, outCollisionPoint, outTriangle))
	{

		if ( (outCollisionPoint - End).getLength() < Radius )
		{

			core::vector3df nor = outTriangle.getNormal();
			finalPosition = Start + origV - 3*(origV.dotProduct(nor)/nor.dotProduct(nor))*nor;
			finalPosition.Y = End.Y;

			node->setPosition(finalPosition);
		}

	}

	float alpha;
//	if(leaveGround)
//		leaveGround = false;
//	else
	
		fowardline.setLine(End, End + core::vector3df(0,-10000,0));
		if(Cmgr->getCollisionPoint(fowardline, Selector, outCollisionPoint, outTriangle))
		{

			if ( (outCollisionPoint - End).getLength() > Height + 0.1)
			{
	
				if(!falling)
				{
					StartTime = timeMs;
					falling = true;
					return;
				}
				u32 t = (timeMs-StartTime);
				finalPosition.Y -= *gravity*t*t*0.0001 - 0.0002*t;
			}
			else
			{
	
					falling = false;
					alpha = .88;
					finalPosition.Y = outCollisionPoint.Y + Height;
					finalPosition.Y = End.Y*alpha + finalPosition.Y*(1-alpha);
			}
			node->setPosition(finalPosition);		
		}
	

	*leaveGround = falling;

	Start = End;
	
}




} // end namespace scene
} // end namespace irr

Code: Select all

#ifndef __COLLISIONANIMATOR_H_INCLUDE
#define __COLLISIONANIMATOR_H_INCLUDE

#include "ISceneNode.h"
#include "ISceneCollisionManager.h"

namespace irr
{
namespace scene
{
	class collisionAnimator: public ISceneNodeAnimator
	{
	public:

		//! constructor
		collisionAnimator(ISceneCollisionManager* cmgr, ITriangleSelector* selector, 
						float &g, bool &leaveGround, float height = 2, float radius = 2);

		//! destructor
		virtual ~collisionAnimator();

		virtual void animateNode(ISceneNode* node, u32 timeMs);

		void setSelector(ITriangleSelector* selector);

		//! Returns type of the scene node animator
		virtual ESCENE_NODE_ANIMATOR_TYPE getType()	{ return ESNAT_FLY_STRAIGHT; }

		bool falling;
	private:
		ISceneCollisionManager* Cmgr;
		ITriangleSelector* Selector;
		float Height, Radius;
		core::vector3df Start;
		core::vector3df End;
		core::vector3df Vector;

		core::vector3df finalPosition;

		core::vector3df outCollisionPoint;
		core::triangle3df outTriangle;

		f32 TimeFactor;
		u32 StartTime;
		bool Loop;
		bool begin;
		bool *leaveGround;
		float *gravity;
	};


} // end namespace scene
} // end namespace irr

#endif
raven_coda
Posts: 89
Joined: Thu Aug 17, 2006 8:11 pm
Location: Salt Lake City, UT, USA
Contact:

Post by raven_coda »

Looks pretty good but there are a few things I'm questioning jus looking at it. First, shoudn't

Code: Select all

Vector = End - Start; 
Vector = Radius*Vector.normalize(); 
be

Code: Select all

Vector = End - Start; 
Vector += Radius*Vector.normalize(); 
also, I'm not sure I understand why you have a 3 in the following

Code: Select all

finalPosition = Start + origV - 3*(origV.dotProduct(nor)/nor.dotProduct(nor))*nor; 
if you did added

Code: Select all

nor=nor.normalize();
then you could replace the above with

Code: Select all

finalPosition = Start + origV - orgV.dotProduct(nor)*nor;
Finally, there is one type of collison that your not checking for that makes this hard. Say you have the following (forgive me for my limited ascii art skills) Ignore the `s they are there for spacing


`````` ___
``````/```\
````` |````|----->``____________
_____ \___/_______|

You collision detection will not detect bumps or steps that are smaller than the radius of you sphere. As long as you don't have any then you are fine but it's just something to keep in mind.
Definition of an Upgrade: Take old bugs out, put new ones in.
Post Reply