Kolizje w GLScene

0

Witam. Proszę o pomoc w wykrywaniu kolizji między GlLinies a Cubikiem próbowałem już chyba wszstkiego i nic :( jeśli macie pomysł to bardzo proszę o wskazówki

0

z tego co rozumiem to masz cube czyli szescian i gl_lines czyli linie [kod z sulaco.co.za]

musizs tylko zdefimniowac do tego ilosc dla kazdej sciany tablice z wierzcholkami i miec dwa punkty wyznaczajce linie) t3dpoint to record x : single;y:single;z:single;end;

function IntersectedPolygon(vPoly : array of t3dpoint; vLine : array of t3dpoint; verticeCount : integer):boolean;
const
MATCH_FACTOR : Extended = 0.9999999999;
var
vNormal : t3dpoint;
vIntersection : t3dpoint;
originDistance : Extended;
distance1 : Extended;
distance2 : Extended;
vVector1 : t3dpoint;
vVector2 : t3dpoint;
m_magnitude : Double;
vPoint : t3dpoint;
vLineDir : t3dpoint;
Numerator : Extended;
Denominator : Extended;
dist : Extended;
Angle,tempangle : Extended;
vA, vB : t3dpoint;
I : integer;
dotProduct : Extended;
vectorsMagnitude : Extended;
begin
vNormal.X := 0;
vNormal.Y := 0;
vNormal.Z := 0;

originDistance := 0;

distance1 := 0;
distance2 := 0;
vPoint.X := 0;
vPoint.Y := 0;
vPoint.Z := 0;

vLineDir.X := 0;
vLineDir.Y := 0;
vLineDir.Z := 0;

Numerator := 0.0;

Denominator := 0.0;
dist := 0.0;
Angle := 0.0;

vVector1.x := vPoly[2].x - vPoly[0].x;
vVector1.y := vPoly[2].y - vPoly[0].y;
vVector1.z := vPoly[2].z - vPoly[0].z;

vVector2.x := vPoly[1].x - vPoly[0].x;
vVector2.y := vPoly[1].y - vPoly[0].y;
vVector2.z := vPoly[1].z - vPoly[0].z;

vNormal.x := ((vVector1.y * vVector2.z) - (vVector1.z * vVector2.y));

vNormal.y := ((vVector1.z * vVector2.x) - (vVector1.x * vVector2.z));

vNormal.z := ((vVector1.x * vVector2.y) - (vVector1.y * vVector2.x));

m_magnitude := sqrt((vNormal.x * vNormal.x) +
(vNormal.y * vNormal.y) +
(vNormal.z * vNormal.z) );

vNormal.x := vNormal.x/m_magnitude;
vNormal.y := vNormal.y/m_magnitude;
vNormal.z := vNormal.z/m_magnitude;

originDistance := -1 * ((vNormal.x * vPoly[0].x) +
(vNormal.y * vPoly[0].y) +
(vNormal.z * vPoly[0].z));

distance1 := ((vNormal.x * vLine[0].x)  +
	         (vNormal.y * vLine[0].y)  +
			 (vNormal.z * vLine[0].z)) + originDistance;

distance2 := ((vNormal.x * vLine[1].x)  +
	         (vNormal.y * vLine[1].y)  +
			 (vNormal.z * vLine[1].z)) + originDistance;

if(distance1 * distance2 >= 0) then

begin

  result := false;
exit;

end;

vLineDir.x := vLine[1].x - vLine[0].x;
vLineDir.y := vLine[1].y - vLine[0].y;
vLineDir.z := vLine[1].z - vLine[0].z;

m_magnitude := sqrt((vLineDir.x * vLineDir.x) +
(vLineDir.y * vLineDir.y) +
(vLineDir.z * vLineDir.z) );

vLineDir.x := vLineDir.x/m_magnitude;
vLineDir.y := vLineDir.y/m_magnitude;
vLineDir.z := vLineDir.z/m_magnitude;



Numerator := -1 * (vNormal.x * vLine[0].x +
      				   vNormal.y * vLine[0].y +
			             vNormal.z * vLine[0].z + originDistance);




Denominator := ( (vNormal.x * vLineDir.x) + (vNormal.y * vLineDir.y) + (vNormal.z * vLineDir.z) );

if( Denominator = 0.0) then

begin
vIntersection := vLine[0];
end
else
begin

dist := Numerator / Denominator;



vPoint.x := (vLine[0].x + (vLineDir.x * dist));
vPoint.y := (vLine[0].y + (vLineDir.y * dist));
vPoint.z := (vLine[0].z + (vLineDir.z * dist));

vIntersection := vPoint;								// Return the intersection point

end;
temp_intersect_v.x := vIntersection.x;
temp_intersect_v.y := vIntersection.y;
temp_intersect_v.z := vIntersection.z;
temp_intersect_v2 := vPoint;

for i := 0 to verticeCount-1 do
begin

vA.x := vPoly[i].x - vIntersection.x;

  vA.y := vPoly[i].y - vIntersection.y;

  vA.z := vPoly[i].z - vIntersection.z;


vB.x := vPoly[(i + 1) mod verticeCount].x - vIntersection.x;

  vB.y := vPoly[(i + 1) mod verticeCount].y - vIntersection.y;

  vB.z := vPoly[(i + 1) mod verticeCount].z - vIntersection.z;


dotProduct := ( (vA.x * vB.x) +
                (vA.y * vB.y) +
                (vA.z * vB.z) );


  vectorsMagnitude := sqrt(
                 extended(vA.x * vA.x) +
                 extended(vA.y * vA.y) +
                 extended(vA.z * vA.z)
                      )
                      *
                 sqrt(
                 extended(vB.x * vB.x) +
                 extended(vB.y * vB.y) +
                 extended(vB.z * vB.z)
                      );

 tempangle := arccos( dotProduct / vectorsMagnitude );


  if(isnan(tempangle)) then
begin
	tempangle := 0;
end;


  Angle := Angle + tempangle;

end;

if(Angle >= (MATCH_FACTOR * (2.0 * PI)) ) then

begin
result := TRUE;
exit;
end;

result := false;

end;

0

:) dzięki za podpowiedz :) liczyłem na coś kródszego ale sprawdze to jak tylko będę miał więcej czasu
Jeszcze raz WIELKIE DZIĘKI za wskazówki [browar]

0

lajt lajt

temp_intersect_v.x := vIntersection.x;
temp_intersect_v.y := vIntersection.y;
temp_intersect_v.z := vIntersection.z;
temp_intersect_v2 := vPoint;

ten kod to dwie zmienne ktore sa globalnie ustawione jako t3dpoint
var temp_intersect_v,temp_intersect_v2 : t3dpoint; //one pozwalaja na zwrot punktu przeciecia

mozna jeszcze to zrobic inaczej tworzysz w tablicy dla kazdej sciany wektor normalny (i dla szybszego wykonywania) obliczasz ze wzoru na plaszczyzne Ax+By+Cz+D=0 D podstawiajac za ABC wspolrzedne wektora normalnego pewnie wiesz o co mi chodzi a za xyz wspolrzedne jakiegos punktu z tej sciany, ktora obliczasz. nastepnie wyliczasz srodek bryly arytmetycznie cvzyli dodajesz wspolrzedne wszystkich wierzcholkow bryly i dzielisz przez ich ilosc teraz magiczna funkcja classifyapointagainstaplane, ktora bedziesz testowal swoj punkt srodka bryly z kazdym jego face'm poniewaz musisz stworzyc dla kazdej sciany taki wektor normalny, ktory bedzie wychodzil na zewnatrz (lub do srodka bryly ja dla swoich potrzeb ustawialem na zewnatrz) jak z fukncji classifyapointagainstaplane wyjdzie ci -1 bedziesz musial odwrocic wektor normalny dla aktualnie sprawdzanego face'a pozniej juz tylko gllines w tym definiujesz dwa punkty ktore tworza linie testuj czy punkty z tej lini (te dwa) nie znajduja sie w srodku bryly czyli dla kazdego face'a (sciany) bryly wartosc bedzie -1 jak tak to masz kolizje tylko to nie zzwraca punktu przeciecia za bardzo :U

const
SPECIAL_FEAUTRE = 0.0001; //wtf ;u
isOnPlane = 0;
isFront = 1;
isBack = -1;

function betweenorequal(x1,x2,x0                                               : single)       : boolean;
begin
result := false;
if smaller(x1,x2) <= x0 then
if greater(x1,x2) >= x0 then result := true else result := false;
end;

function greater(a,b:single):single;
begin
if a =b then exit;
  if a>b then result:=a else result:=b;
end;

function smaller(a,b:single):single;
begin
if a =b then exit;
  if a>b then result:=b else result:=a;
end;



function classifyapointagainstaplane(point, normal : t3dpoint; distance : single)
: integer;
//using vn o vx+d=0
var
costam : single;
begin
costam := dotproduct(point,normal)+distance;
if costam > 0 then result := isFront;
if costam < 0 then result := isBack; 
if betweenorequal(-SPECIAL_FEAUTRE,SPECIAL_FEAUTRE,costam) = true then result := isOnPlane;
end;
0

function dotproduct(n : single; v1 : t3dpoint) : t3dpoint;
begin
Result.x := nv1.x;
Result.y := n
v1.y;
Result.z := nv1.z;
//+(v1.y
v2.y)+(v1.z*v2.z);
end;

jeszzcze ta funkcja

0

BARDZO SIE CIESZĘ, że pojawiły się nowe posty. Za temat biorę się w przyszłym tygodniu więc chętnie poznam inne propozycje :) . Jeśli możecie zaproponować jakieś CIEKAWE źródło wiedzy, ŁATWO PRZYSWAJALNEJ ;) to proszę o info.
POZDROWIENIA dla WSZYSTKICH GURU GRAFIKI :d

0

Jeśli ktoś chce wykrywać kolizje to polecam TcollisionManager z GLScene naprawde porosty i przyjazny sposób :) i nie trzeba tyle pisać nie wątpie ze jest to LAMERSKIE ;) podejście ale dla prostych zastosowań w zupełności wystarcza
[browar]

1 użytkowników online, w tym zalogowanych: 0, gości: 1