Gładkie przesuwanie sie po krawedziach scianach [kolizja]

0

Problem wyglada nastepujaco, ze jak dojde do sciany i mi zablokuje pozycje gracza i przesune to o jakis wektor to mi postac skacze jak pomirdor z maslem, chodzi mi o to zeby dobijal do face'a i po nim sie sunal a nie skakal [cezet.host.sk/de.avi-tak to wyglada]. Pytanie jak to sie wykonuje i najlepiej zeby odpowiedz nie brzmiala ze trzeba dodac warunek if jest kolizja to wtedy przesuwaj o prostopadla do normalnej face'a w strone w zaleznosci na ktora sie patrzy bo na bank sa inne metody latwiejsze.

Od razu chce zaznaczyc ze jestem nubem w tych sprawach, a takie kolizje i w ogole silnik 3d to pisze pierwszy raz wiec za bardzo nie wiem co i jak..
//funkcja nie jest cala ale jak na testy wystarczy, oto co robi
w petli sprawdza kazda sciane po kolei
//sprawdz nowpos i gopos gdzie sie znajduja wzgledem plaszczyzny, ktora wyznacza ta sciana, potrzebne do operacji na wektorach
//pozniej zostaje sprawdzona odleglosc od sciany (plaszczyzny) jak jest 5 lub mniejsze to tworzymy wektor ktory mnozymy razy 5 [czyli nasza szerokosc dla lepszej precyzji lepiej pomnożyc przez liczbe wieksza szerkosci np 15 ] i razy te zero..jednyki z normalnej sciany, jak przebija sciane to wtedy pobieramy punkt przeciecia odwracamy wektor normalny i mnożymy razy szerkosc gracza znak3 jest to wartosc logiczna czy punkt do ktorego zmierzamy jest z porzu czy z tyłu sciany tak btw, wiem ze to nie jest jeszcze wszystko co trzeba napisac chodzi mi o wieksze sily na ktore te warunki nie beda dzialac, ale ja chce na razie pozbyc sie skakania :U i tej upierdliwej rzeczy ktorej nie opisze bo chyba znam odpowiedz :F
//no i jak jest kolzija to zwraca wektor o ktory trzeba? przesunac gracza

function collisionfunc(nowpos: t3dpoint; gopos : t3dpoint; model : tglarrayselectionmodel) : t3dpoint;
var
znak1,znak2,znak3 : integer;
i,j,n:integer;
punkt : t3dpoint;
wektor : t3dpoint;
wypadkowa : t3dpoint;
punktprosty : t3dpoint;
kolizja : boolean;
temp : t3dpoint;
begin
kolizja := false;
wypadkowa.x := 0;wypadkowa.y:= 0;wypadkowa.z := 0;
result := vectors_substract_v1minusv2(gopos,nowpos);
for i:=0 to high(model.face) do
begin
znak1 := classifyapointagainstaplane(nowpos,model.arrays[i][0].normal3f,model.face_distance[i]);
znak2 := classifyapointagainstaplane(gopos,model.arrays[i][0].normal3f,model.face_distance[i]);
//Jest kilka przypadkow:
//Przebilismy face i sprawdzamy punkt przeciecia i przesuwamy pod katem prostym do face'a punkt - r kola
//jak przebilismy face
if znak2 >= 0 then znak3 := -1 else znak3 := 1;
//schemat kolizja // jak jestesmy w odleglosci 5 od face'a to
if n3dDISTANCE_FACE_POINT(model.arrays[i][0].normal3f,model.arrays[i][0].vertex3f,gopos) < 5 then begin
wektor.x := znak3*model.arrays[i][0].normal3f.x*5;
wektor.y := znak3*model.arrays[i][0].normal3f.y*5;
wektor.z := znak3*model.arrays[i][0].normal3f.z*5;
temp := vectors_add(gopos,wektor);
if  IntersectedPolygon(model.colarrays[i],
[gopos,vectors_add(gopos,wektor)],model.facelength[i]) = true then //mamy przeciecie jest kolizja, a wyszlismy za face trzeba sie wrocic
begin
kolizja := true;
wypadkowa.x := wypadkowa.x              -znak3*model.arrays[i][0].normal3f.x     *       5;
wypadkowa.y := wypadkowa.y              -znak3*model.arrays[i][0].normal3f.y     *       5;
wypadkowa.z := wypadkowa.z             -znak3*model.arrays[i][0].normal3f.z     *       5;
end;
end;


end;


if kolizja then begin
result.x := wypadkowa.x;
result.y := wypadkowa.y;
result.z := wypadkowa.z;
end;

end;
// tak mniej wiecej wyglada funkcja na poruszanie sie gracza po swiecie
result.x := move_vector.x*movespeed;
result.y := move_vector.y*movespeed;
result.z := move_vector.z*movespeed;
result := collisionfunc(old,vectors_add(result,old),qube_model);
//
0
  1. Nigdzie nie używasz zmiennej temp a z tego co widzę ona odpowiada za odległość od płaszczyzny.
  2. Za bardzo ufasz liczbą zmienno przecinkowym. Może się dziać tak że odległość wychodzi ci mniejsza od 5, przesuniesz postać po wektorze normalnym * 5 a w następnym wykonaniu i tak komputer będzie myślał że postać jest bliżej niż 5 jednostek i znowu ją odepchnie i to może być powodem tego skakania.
0

Aha, rozumiem że w tych linijkach :

if n3dDISTANCE_FACE_POINT(model.arrays[i][0].normal3f,model.arrays[i][0].vertex3f,gopos) < 5 then begin
wektor.x := znak3*model.arrays[i][0].normal3f.x*5;
wektor.y := znak3*model.arrays[i][0].normal3f.y*5;
wektor.z := znak3*model.arrays[i][0].normal3f.z*5;

wektor ma być przesunięciem postaci od ściany tak aby była w odległości 5 od poligona? jeżeli tak to powinieneś chyba mnożyć nie przez 5, bo jeżeli on był np w odległości 3 to przesunięcie jeszcze o 5 wysunie go na dystans 8 jednostek! tylko mnóż przez :

pom:=5.0f-n3dDISTANCE_FACE_POINT(model.arrays[i][0].normal3f,model.arrays[i][0].vertex3f,gopos);
wektor.x := znak3*model.arrays[i][0].normal3f.x*pom;
wektor.y := znak3*model.arrays[i][0].normal3f.y*pom;
wektor.z := znak3*model.arrays[i][0].normal3f.z*pom;
0
if n3dDISTANCE_FACE_POINT(model.arrays[i][0].normal3f,model.arrays[i][0].vertex3f,gopos) < 5 then begin
wektor.x := znak3*model.arrays[i][0].normal3f.x*105;
wektor.y := znak3*model.arrays[i][0].normal3f.y*105;
wektor.z := znak3*model.arrays[i][0].normal3f.z*105;

dodalem 105 nie 5 i tak skacze, ale ten kod to tylko wektor z punktu nowpos (czyli tego co jestesmy aktualnie) w strone sciany ktora testujemy (wiem ze nie ma jeszcze testowania w tym kodzie jak 'gopos' (czyli pozycja gdzie idziemy) jest dalej niz 5 od sciany i jest po drugiej stronie sciany niz nowpos.
zmienna 'wektor' po wyliczeniu jest dodawana do zmiennej 'nowpos' co tworzy nam linie, ktora jest testowana funkcją intersectedpolygon czy przebija sciane, a nie tylko plaszczyzne, na ktorej sciana sie znajduje.

if  IntersectedPolygon(model.colarrays[i],
[gopos,vectors_add(nowpos,gopos)],model.facelength[i]) = true then //mamy przeciecie jest kolizja 

Jak linia przebija sciane to pobieramy punkt przeciecia ze sciana i tworzyny nastepny wektor, ktory bedzie nam mowil o ile mamy przesunac nasz obiekt od face'a

wypadkowa.x := wypadkowa.x              -znak3*model.arrays[i][0].normal3f.x     *       5;
wypadkowa.y := wypadkowa.y              -znak3*model.arrays[i][0].normal3f.y     *       5;
wypadkowa.z := wypadkowa.z             -znak3*model.arrays[i][0].normal3f.z     *       5;

5 to w tym przypadku szerokosc obiektu, model.arrays[i][0].normal3f to wektor prostopadly do plaszczyzny, a z kolei znak3 to zmienna, ktora zwraca kierunek naszego wektora (w ktora strone mamy przesunac obiekt). Inaczej to piszac przesuwamy o 5*normalna nasz obiekt od scainy.

Dodatkowo mam problem bo jak uwzglednie ze nowpos i gopos sa po roznych stronach sciany i przeprowadze linie przenbijajaca sciane to i tak przebije mi scaine :U

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