Cylinder Vs Triangle Selector Collision, and a bunch of ?'s

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
BoingBoing
Posts: 18
Joined: Fri Sep 11, 2009 4:31 am

Cylinder Vs Triangle Selector Collision, and a bunch of ?'s

Post by BoingBoing »

Is this possible yet?

And is there a Cylinder vs Cylinder Collision detect also?

What is the best way to make the character move and climb up stairs?
In my 2D games I would move my character one pixel and then see if it collides with anything, then when it does it would move one pixel back.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Irrlicht does not support cylinder/cylinder collision. If you want to do simple cylinder collision, where all bounding cylinders are oriented similarly (the primary axis is facing the perpendicular to the ground), you can write it pretty easily. If you need to handle cylinders that are in various orientations, or if you're not up to it, you might consider using a physics engine. They handle object/object collision for you, and they should do it fairly efficiently since that is one of their primary functions.

BTW, I don't understand why you'd want to move one pixel at a time though. It seems to me that you'd want to move your characters based on the velocity that they are supposed to maintain. If two objects start to collide, then you have to resolve the collision by moving one, or both of the objects as necessary.
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

I just whipped this up, so I'm not certain it will work, but you could try it if it suits your needs.

Code: Select all


#include <vector3d.h>

struct SCylinder
{
  core::vector3df Pos; // center of the base
  f32 Height; // height of the cylinder
  f32 RadiusSQ; // radius of the cylinder squared
};

bool collide (const SCylinder* a, const SCylinder* b)
{
  // bottom of B is above the top of A
  if (a->Pos.Y + a->Height < b->Pos.Y)
    return false;

  // bottom of A is above the top of B
  if (b->Pos.Y + b->Height < a->Pos.Y)
    return false;

  // some part of A and B overlap vertically

  // use pythagorean theorem to find squared distance from
  // A to B.
  const f32 Xoff = b->Pos.X - a->Pos.X;
  const f32 Zoff = b->Pos.Z - a->Pos.Z;

  //  C^2 = A^2 + B^2
  const f32 XZoffSQ = Xoff * Xoff + Zoff * Zoff;

  // if the square of the distance from A to B is more then
  // the sum of the squares of the radiuses, then there is
  // no collision
  if (a->RadiusSQ + b->RadiusSQ < XZoffSQ)
    return false;

  // there is a collision
  return true;
}
Travis
BoingBoing
Posts: 18
Joined: Fri Sep 11, 2009 4:31 am

Post by BoingBoing »

If I wanted the other one to move then I'd use a physics engine.

I just want the object to stop dead in it's track.

So how would I do a selector vs cylinder collision?

Edit: And yes, 90 degrees Cylinders are what I'm going for.

I'm actually not looking for collision, but really more of intersection.

Edit:
I came up with a function that detects intersection between a cylinder and a triangle. I haven't tested it, but I'm going to guess there is an easier way.

Code: Select all

/* Equation for Circle-Line intersection detection.
dx = x2 - x1
dy = y2 - y1
r^2*(dx^2+dy^2)-(x1*y2-x2*y1)^2

(http://mathworld.wolfram.com/Circle-LineIntersection.html)
*/

bool YPointInLine (float y1, float y2, float yc)
{
	if (y1 >= yc >= y2)
		return true;

	if (y2 >= yc >= y1)
		return true;

	return false;
}

bool trianglecollision (const SCylinder* a, core::vector3df vec1, core::vector3df vec2, core::vector3df vec3)
{
	float dx = vec2.X - vec1.X;
	float dy = vec2.Z - vec1.Z;

	float dis = a->RadiusSQ*(dx^2+dy^2)-(vec1.X*vec2.Z-vec2.X*vec1.Z)^2

	if (dis < 0 && !YPointInLine(vec2.Y, vec1.Y, a->Pos.Y))
		return false;

	dx = vec3.X - vec1.X;
	dy = vec3.Z - vec1.Z;

	dis = a->RadiusSQ*(dx^2+dy^2)-(vec1.X*vec3.Z-vec3.X*vec1.Z)^2

	if (dis < 0 && !YPointInLine(vec3.Y, vec1.Y, a->Pos.Y))
		return false;

	dx = vec3.X - vec2.X;
	dy = vec3.Z - vec2.Z;

	dis = a->RadiusSQ*(dx^2+dy^2)-(vec2.X*vec3.Z-vec3.X*vec2.Z)^2

	if (dis < 0 && !YPointInLine(vec3.Y, vec2.Y, a->Pos.Y))
		return false;

	return true;
}
BoingBoing
Posts: 18
Joined: Fri Sep 11, 2009 4:31 am

Post by BoingBoing »

BUMP

Can anyone confirm that this works?
vitek
Bug Slayer
Posts: 3919
Joined: Mon Jan 16, 2006 10:52 am
Location: Corvallis, OR

Post by vitek »

Is there some reason that you can't write a test to confirm it? Seems that it would be trivial.

Travis
Post Reply