PDA

View Full Version : Collision Slide Effect for 3DS Objects



Daikrys
03-05-2005, 03:08 PM
Hi there,

note: i use Delphi and OpenGL for programming

how to make a slide collision between 2 or more 3DS Objects?
for example:
-i have a player(3DS or something)
-i have a world(1 3DS or more created to 1 world)

i dont need a 3DS to 3DS collision detection, it will also
work with a Sphere or Cylinder collision detection.
but i need a SLIDE effect!

ive thinking a lot, but dont get an answer, at time my head will explode :roll:

Thanks a lot for help
Daikrys

Daikrys
03-05-2005, 06:42 PM
uh? :cry:

nobody can help me?
ok i find this link http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=30
but i dont understand it :?
i think my english is to bad or iam to silly :(

if someone understand this tutorial(and i think many would understand it)
can u write a simple short help for cylinder or sphere collision?
if its easier it would work with cylinder-cylinder collision

can anyone help me plz?

{MSX}
04-05-2005, 07:06 AM
Hi Daikrys, and welcome! :D

Well if i understand well, you just have to implement a sphere to sphere (or cylinder) collision.

To see if two spheres are colliding, you just need to calculate the distance D between them, and then check if D is smaller then the sum of the two radius:

if r1+r2 >= D then collision!

This apply for both 3d and 2d (circles).
Now, if you want a sphere to slide along another (if i understood correctly), you need some little complex calculation.

I'm not too good with this.. I'll try to read the tutorial and see if i get it :P

But is your world truly 3d? Becouse if the character can just move in four direction on a plane, then you can just use 2d circle collision.

Bye!

Daikrys
04-05-2005, 10:35 AM
much thanks :D

i think i understand what u mean :wink:
first i try to use 2d collision, it will work for now
but i think i need 3d collision later :roll:

thank u again for trying to read the tutorial, i hope u can help me
with the slide effect

what mean the first parameter by glusphere?

GLusphere(gluNewQuadric, radius,singlevar1,singlevar2);
can anyone give me an example plz?

or how i can create a sphere?

{MSX}
04-05-2005, 11:33 AM
what mean the first parameter by glusphere?

GLusphere(gluNewQuadric, radius,singlevar1,singlevar2);
can anyone give me an example plz?

or how i can create a sphere?

The first parameter is the quadric that you have to create before use.


sphereObj := gluNewQuadric();
gluSphere(sphereObj, r, a, b);
// ....
// after use, delete it:
gluDeleteQuadric(sphereObj)

Daikrys
04-05-2005, 01:30 PM
ok here it is the collisionscode for circle collision
i use gludisk to create a circle


function check(x,y,size : single): boolean;
var d:single;
begin
d:=sqr(x)+sqr(y);
if d<=sqr(size+0.3) then result:=true else result:=false;
end;

procedure Render;
var i: integer;
rotation,xpos,ypos: double;
sphereobj: gluquadricobj;
begin
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glLoadidentity;

glpushmatrix();
gltranslatef(0,0,-6);

glcolor3f(1,1,1);
sphereobj:=glunewquadric();
gludisk(sphereobj,0,0.3,12,1);
gluDeleteQuadric(sphereObj);

glpopmatrix();

glpushmatrix();
gltranslatef(posx,posy,-6);

glcolor3f(1,1,1);
sphereobj:=glunewquadric();
gludisk(sphereobj,0,0.3,12,1);
gluDeleteQuadric(sphereObj);

glpopmatrix();

if check(posx,posy,0.3) then Form1.Caption:='Collision!' else Form1.Caption:=nope!';

SwapBuffers(myDC);
end;


so how to make a slide collision?

{MSX}
04-05-2005, 07:50 PM
ok, i'd do this way for collision with slide:
When 2 sphere collide, you find how much they compenetrate, that is

compenetration := distance - (size1+size2);

now, you must pull them "apart" by that value.
You can choose how to distribute it between the two object. If one of them is fixed, just add all compenetration value to the other, elseway you can distribute it half way (so it will be possible to push something).

The problem is that compenetration value is a scalar, so you need to obtain a vector of that dimension.
Now the vector happends to be the subtraction between the positions (that must be normalized and scaled):


var
comp,d:TFloat;
v:TVector;
// find compenetration value
comp := distance(a.position, b.position)-(size1+size2);
if d<0 then // if collide
begin
// find vector distance (it will have length=distance, no good, must be normalized)
v:=sub(a.position,b.position);
// normalize the vector, now direction is ok, and length is 1
normalize(v);
// make length equal to compenetration value
scale(v,d);
// ok, now vector points from a to b, length d. We subtract from position
// so it will be pulled away
a.position:=sub(a.position,v);
end;


That's it. If you want to distribute "sliding" between the two object, you can change it to:


// make length equal to half compenetration value
scale(v,d/2);
// pull them apart
a.position:=sub(a.position,v);
b.position:=add(b.position,v); // this is added becous v already points away from it


Ok, this should work. IHTH :P

Daikrys
08-05-2005, 08:23 PM
hi again,

iam back from my girlfriend and ready for programming :wink:

ok i understand some of them but what are scale and normalize? :|
if that a function or procedure i dont find it :oops:
or what are u mean by that?

i hope it isnt that stupid question i think it is :toothy:

{MSX}
08-05-2005, 08:37 PM
hi again,

iam back from my girlfriend and ready for programming :wink:


Ehehe good for you :P


ok i understand some of them but what are scale and normalize? :|
if that a function or procedure i dont find it :oops:
or what are u mean by that?

i hope it isnt that stupid question i think it is :toothy:

As we say: there's no stupid questions, only stupid answares :P

Scale and normalize are two operation you can do with vectors.
As you know each vector (2d, 3d, and all others) have a length, (that can be calculated as: sqrt( x^2 + y^2 ), that is the suare root of the sum of all members squared).
Now if a vector have length 1 it is said to be normalized. Normalized vectors have special properties that comes handy.
Normalizing a vector means making it's length 1. So if a vector has length 15 then you divide each element by 15 and get a vector that's normalized (it points in the very same direction but it's length's 1)
Here's the code:


procedure Normalize(var Vec:TVector);
var Mag : TFloat;
begin
Mag := Magnitude(Vec); // the length
vec.x := Vec.x / Mag;
vec.y := Vec.y / Mag;
end;


The scale is similar, it means that you multiply the length of a vector by a given number. If you scale a vector with length 5 by 2 you obtain a vector (that points in the same direction) with length 10.
Here's the code for scale:


procedure Scale(var vec:TVector; ascale:TFloat);
begin
vec.x := Vec.x * ascale;
vec.y := Vec.y * ascale;
end;


IHTH
Bye!

Daikrys
08-05-2005, 10:54 PM
ok i do something....(wrong)....


As we say: there's no stupid questions, only stupid answares

Thanks :wink:

can u watch my sample and correct them?

download it here:
http://daikrys.funpic.de/collide.zip

Thanks

i gonna sleep
good night

Daikrys
10-05-2005, 07:27 AM
another question:

can i use my sample to make a plane to sphere(or circle) slide collision?
is that easier? how to?

THX

{MSX}
10-05-2005, 08:31 AM
Sorry but i don't have time to check code (nor i have glscene). I took i quick look on the vector unit and it seems ok at fist sight.

The system i explained above should work with 3d also (just use 3d vector math instead of 2d).
Plane/sphere collision should be easy too. You need a function that calculates the distance between a sphere and a plane. If the plane is perpendicular to the axis (is horizontal or vertical) than it's trivial, if it's arbitrary oriented then you need some more math.

Once you have the distance D, you check if D is smaller than the radius of the sphere. If it is, they collide.

Daikrys
10-05-2005, 05:02 PM
ok iam back again :P

i found the failure i have :D
i used the wrong function for the compenetration d

so a little problem/failure i have is when i collide to slide
i used for the new Vector coordinates

a,v: TVector;
...
a:=add(a,v);

and not

a:=sub(a,v);

when i use sub the Vector a and b will be the same and i see only one
circle and cant move :cry:
but when i use add i can "slide" but on slide my circle step back?
example:
i slide in direction right the circle step right AND back
but the step back is the failure :cry:

here the short code:

var
d: Double;
v: TVector;
...
d:=distv(a,b)-0.6; //0.6 are the value of size+size

if d<0 then // if collide
begin
Form1.Caption:='yeah';
// find vector distance (it will have length=distance, no good, must be normalized)
v:=sub(a,b);
// normalize the vector, now direction is ok, and length is 1
normalize(v);
// make length equal to compenetration value
multiply(v,d);
// ok, now vector points from a to b, length d. We subtract from position
// so it will be pulled away
a:=add(a,v);

end else Form1.Caption:='no';


Thanks u helped me so much, i wouldnt figure it in a year :roll:

{MSX}
10-05-2005, 05:25 PM
Umm i don't understand very well the problem. could you post an executable so that tomorrow i can try it at work? Maybe with the latest sources.
I wont be able to compile but maybe i can find the problem the same.

Well maybe you could check that 0.6 if it's really size+size.. It could be that it's wrong and when you scale v by d you get a value too large that makes your circle bump on the other. (shooting in the dark here :P )

Bye!

Daikrys
10-05-2005, 06:20 PM
first a picture for help

when a collision is the Vectors position are:

http://daikrys.da.funpic.de/Problem.gif

at the red cross was the collision

later i post the exe and source

Bye[/img]

Daikrys
10-05-2005, 07:22 PM
first a picture to help

http://daikrys.da.funpic.de/Problem.gif
or
http://daikrys.funpic.de/Problem.gif

this are the vectors a collide by the red cross
i draw v for better understanding
note: this is an original screenshot from the programm

at tomorrow i post my exe and source

Bye

Daikrys
11-05-2005, 08:00 AM
i did it :mrgreen:

i change the function add to the following:

function add(v1,v2: TVector): TVector;
begin
result.x:=v1.x/5 + v2.x;
result.y:=v1.y/5 + v2.y;
result.z:=v1.z/5 + v2.z;
end;


then how to do a slide collision with a moving shpere and a static plane?
a plane have 5 vectors(include the center point), or?

Daikrys
11-05-2005, 08:35 PM
ok i uploaded it here:
http://daikrys.funpic.de/collide.rar

i hope u have a look :roll:

the slide isnt very smoothed :?
but i dont know how to get it smoother

Thanks, bye

Daikrys
16-05-2005, 04:55 PM
huh? :scratch:

no new posts?

{MSX}
19-05-2005, 09:45 AM
sorry, i've been quite busy..
At first sight the problem seems to be one of:
- a rounding problem: probably you round some float value to integer, but you're working with values in the range of 0.5 so rounding will loose precision. I'm quite sure this is the problem but i couldn't find where it is in the code.
- a scale problem: maybe you're using too big values for radius, distances, etc. Try and control them.

Bye!

Daikrys
19-05-2005, 05:16 PM
oh boy,

i cant solve it iam to stupid :evil:
can u post an code example were u solve it?
i think the game Omino 3d from ur site is very cool :P
what are u using for this?
can u post the source or mail at Novastern@gmx.net

thank u
good bye

{MSX}
23-05-2005, 09:40 AM
I don't have a version working.
If i find the time i'll try to compile it this evening (it requires me to reboot to windows, something i seldom do :P)
For Omino3D i used JEDI-SDL. It uses a system for circle collision like the one you're making. If i find the sources i'll send them.

Daikrys
25-05-2005, 09:24 AM
hi :mrgreen:

IT WORKED *yieh*

i only change my vector with ur vector2d unit (i think my will work too)
and use ur floatunit unit

now i will study the code of both units to understand

thank u very much
greats Dai

Daikrys
27-05-2005, 08:38 PM
hi again :wink:

umm...when i will used a plane to plane or sphere to plane
u said thats the same but what is with the edges? how too calculate?
i know how, but i need too get the direction of the collide object
then how i can use the scale and multiply functions from v? there i get the
direction and what about the planes thats arbitrary oriented?

sorry for the headage :roll:

thanks and bye

{MSX}
07-06-2005, 08:45 PM
well, if you have an (infinite) plane, then you just have to test if the center of the sphere and the plane are less distant then the radius.
The plane will be perpendicular to an axe, so it will be in the form x = 3 or y = 5 etc.
If it's x=3 for example, the distance will be abs(Cx - 3) where Cx is the x coordinate of the center.

If you have lines or rectangles instead of planes, then it's far more difficoult, becouse you must discriminate the cases in which the sphere collides on an edge and the cases in whitch the sphere collides on an angle.
Possibly an easy solution is to consider each edge a plane and test all of them, but obviously this is not precise in the angles it will not raise a collision in some cases (anyway you can tell it's a feature: rounded rect collision algorithm :mrgreen:)

IHTH