Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Black-Panther

Alter Hase

  • »Black-Panther« ist der Autor dieses Themas

Beiträge: 1 443

Wohnort: Innsbruck

  • Private Nachricht senden

1

13.02.2006, 13:50

An der Mauer entlanggleiten...

Wie der Titel schon sagt, hab ich mir einige Gedanken bezüglich dem Entlanggleiten an einer Mauer bei Kollision gemacht... Meine derzeitige Lösung: (oder besser Ansatz?)

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//.....

//Blickrichtung

        og3DVector vCameraDirection;
        vCameraDirection = og3DVector(sinf(g_fCameraAngle), 0.0f, cosf(g_fCameraAngle));        //2D-Blickrichtung


        //Strafevektor

        og3DVector vStrafe = og3DVectorCross(og3DVector(0.0f, 1.0f, 0.0f), vCameraDirection);

        //Linksrechts

        g_fCameraAngle += OG_DEG_TO_RAD(g_fMouseSpeed * 40.0f) * DI[OG_MOUSE_X_POS].fAnalog;

        //Strafe

        vOldCameraPosition = g_vCameraPosition;
        if(DI[OG_KEY_A].bDigital) vCameraVelocity -= vStrafe;
        if(DI[OG_KEY_D].bDigital) vCameraVelocity += vStrafe;

        //Vor und zurück

        vCameraDirection = og3DVector(sinf(g_fCameraAngle), g_fCameraUpDown, cosf(g_fCameraAngle)); //3D-Blickrichtung

        if(DI[OG_KEY_W].bDigital) vCameraVelocity += vCameraDirection;
        if(DI[OG_KEY_S].bDigital) vCameraVelocity -= vCameraDirection;

    //Kollisionstest

    if(g_bCollisionTest)
    {
        vCameraVelocity     = og3DVectorNormalizeEx(vCameraVelocity);
        if(ogCollisionLineModel(vOldCameraPosition,
                                vOldCameraPosition + og3DVectorNormalizeEx(vCameraVelocity) * g_fSpeed * fTime,
                                g_Model, g_mWorld, ogMatrixInvert(g_mWorld), 0.0f, NULL, &g_vNormal))
        {
            vCameraVelocity         += g_vNormal * -og3DVectorDot(vCameraVelocity, g_vNormal);
            //g_vCameraPosition = vOldCameraPosition;

        }
        else g_vNormal = og3DVector(0.0f);
    }

    //Kameraposition aktualisieren

    g_vCameraPosition       += og3DVectorNormalizeEx(vCameraVelocity) * g_fSpeed * fTime;


Nun zum Problem... Also das Entlanggleiten an und für sich funktioniert einwandfrei, nur sobald ich auf eine Ecke stoße(also keine gerade Fläche) komm ich durch die Mauer/Wand durch... Habt ihr einen Lösungsvorschlag oder einen anderen besseren Ansatz?
stillalive studios
Drone Swarm (32.000 Dronen gleichzeitig steuern!)
facebook, twitter

2

13.02.2006, 14:38

Hast du Davids Buch?
Da ist doch ein Ansatz gegeben (beim Beispiel mit Octrees). Manchmal gleitet man zwar durch Wände, das liegt jedoch afaik an einer kleinen boundingbox.

Ich hoffe, das war richtig...

F0GX

Black-Panther

Alter Hase

  • »Black-Panther« ist der Autor dieses Themas

Beiträge: 1 443

Wohnort: Innsbruck

  • Private Nachricht senden

3

13.02.2006, 16:19

Also ja ich habe diesen Ansatz aus Davids Buch.... Sagen wir so, ich habe ich ihn nicht 1:1 übernommen, aber so in der Richtung... Hab ihn schon mit dem eigentlichen verglichen, dabei aber keinen Hinweis auf den "Fehler" gefunden...
@FOGX
Was soll das mit den BB zu tun haben? Ich mach ja einen Kollisionstest zwischen Linie und Modell und bin, wenn i an der Mauer entlanggleite 100%ig IN der BBox!
stillalive studios
Drone Swarm (32.000 Dronen gleichzeitig steuern!)
facebook, twitter

rewb0rn

Supermoderator

Beiträge: 2 773

Wohnort: Berlin

Beruf: Indie Game Dev

  • Private Nachricht senden

4

15.02.2006, 09:01

Die Zeile geht kürzer

C-/C++-Quelltext

1
        if(ogCollisionLineModel(vOldCameraPosition, vOldCameraPosition + vCameraVelocity * g_fSpeed * fTime, g_Model, g_mWorld,


Ich denke der Fehler liegt darin, dass wenn du an der Ecke ankommst, gibt es irgendwann den Punkt wo er nicht mehr mit dem Dreieck das zu dir zeigt kollidiert sondern mit dem um die ecke liegenden. Dh Kamerablickrichtung und Normalenvektor sind nahezu parallel, dh die Cameraposition wird so gut wie nicht korrigiert, dh du kommst durch die Wand. Du könntest zB eine Mindestkorrektur einbauen um das zu verhindern, oder eine Schleife in der die Korrektur solange durchgeführt wird, bis nicht mehr kollidiert wird (aber vorsicht, das könnte n geschwindigkeitsfresser werden)

Black-Panther

Alter Hase

  • »Black-Panther« ist der Autor dieses Themas

Beiträge: 1 443

Wohnort: Innsbruck

  • Private Nachricht senden

5

15.02.2006, 13:31

Danke erstmal... werd ich mal versuchen... Ich glaub ich weiß wo das Prob liegt... Und zwar wenn ich auf die Senkrechte Mauer treffe, dann wird durch die Vektoraddition ein resultierender Vektor gebildet, der IN die Ecke zeigt... D.h. ich könnte das ganze vermeiden, wenn ich ab einen gewissen Einfallswinkel die Position nicht mehr verändern lasse...

Zitat von »"Spik)evil("«

Die Zeile geht kürzer

C-/C++-Quelltext

1
        if(ogCollisionLineModel(vOldCameraPosition, vOldCameraPosition + vCameraVelocity * g_fSpeed * fTime, g_Model, g_mWorld,


Wieso???
1. Wenn ich vCameraVelocity nicht Normalisiere, dann ist die Geschwindigkeit nicht immer konstant
2. Wieso hörst du nach g_mWorld auf?

EDIT: Ups... ^^ Hab übersehen, dass ich vCameraVelocity eine Zeile darüber Normalisiere ;) Sry Blackout :D
stillalive studios
Drone Swarm (32.000 Dronen gleichzeitig steuern!)
facebook, twitter

Anonymous

unregistriert

6

15.02.2006, 14:28

Hi!

Besser wäre es, wenn du für den Gleitvorgang auch auf Kollisionen testest:

Die Ursprungsbewegung sei A nach B. Wenn dabei eine Kollision auftritt,
dann sei das im Punkt C. Nun gleitet der Spieler von C aus zu dem Punkt D,
der das Ziel des Gleitens darstellt. Falls auf dem Weg von C nach D auch
eine Kollision auftritt, stoppst du einfach die Bewegung in dieser
zweiten Kollision. So bist du auf der sicheren Seite.

Grüße
Stefan

rewb0rn

Supermoderator

Beiträge: 2 773

Wohnort: Berlin

Beruf: Indie Game Dev

  • Private Nachricht senden

7

15.02.2006, 16:11

Zitat von »"Black-Panther"«


2. Wieso hörst du nach g_mWorld auf?

Mein Fehler ^^

@scarsen: Die große Frage ist aber: Wie berechnet man D? Den genau diese Berechnung gibt ja an, wie das Gleiten aussieht, bzw wo seine Schwächen liegen. Und die Bewegung zu stoppen während man kollidiert würde doch darin resultieren, dass man sich immer noch in der Mauer befindet, und im nächsten Frame möglicherweise noch weiter reinrutscht (was wieder von der Berechnung von D abhängt) oder hab ich dich falsch verstanden?

Wie auch immer, willkommen im Forum :kipp:

Black-Panther

Alter Hase

  • »Black-Panther« ist der Autor dieses Themas

Beiträge: 1 443

Wohnort: Innsbruck

  • Private Nachricht senden

8

15.02.2006, 17:18

Wenn ich das aber so mache, dann fällt immer wenn eine Kollision ansteht zu mindestens 80% ein weiterer Kollisionstest an... Aber ich werds mal probiern...

Auch von mir willkommen im Forum! und danke ^^
stillalive studios
Drone Swarm (32.000 Dronen gleichzeitig steuern!)
facebook, twitter

Anonymous

unregistriert

9

16.02.2006, 08:54

Hallo ihr zwei!

Erst mal danke für die freundliche Begrüßung :)

Zitat

Die große Frage ist aber: Wie berechnet man D? Den genau diese Berechnung gibt ja an, wie das Gleiten aussieht, bzw wo seine Schwächen liegen. Und die Bewegung zu stoppen während man kollidiert würde doch darin resultieren, dass man sich immer noch in der Mauer befindet, und im nächsten Frame möglicherweise noch weiter reinrutscht (was wieder von der Berechnung von D abhängt) oder hab ich dich falsch verstanden?


D wird berechnet, indem der Vektor B-C senkrecht auf die Normale der
Wand projiziert wird und der so entstehende Vektor auf B addiert wird
(falls die Normale der Wand in die Richtung zeigt von der aus sie sichtbar
sein soll und von wo aus die Kollision erfolgt). Klingt kompliziert, ist aber
relativ einfach zu realisieren. Wenn ihr wollt kann ich dazu gerne mal
näheres schreiben.

Generell ist bei Kollisionen wichtig, dass man stets Abstand hält - d.h.
dass man immer ein wenig von der Wand weggeht. Wenn C z.B. der
exakte Kollisionspunkt ist, dann sollte man auf C z.B. den Wert von
1.0e-5 mal die Wandnormale aufaddieren - dadurch stellt man sicher, dass
der Normalzustand des Spieler kollisionsfrei ist und bei jedem
Durchlaufen der Spielschleife nur zwei Möglichkeiten existieren:
* Der Spieler bewegt sich von der Kollisionsfreiheit in eine Wand (Kollision!)
* Der Spieler bewegt sich und kollidiert mit keinen Wänden (keine Kollision!)
Es wäre sehr viel aufwändiger wenn man auch die Fälle berücksichtigen
möchte bei denen der Ausgangspunkt der Bewegung pro Frame bereits
eine Kollision beinhaltet.

Grüße
Stefan

Werbeanzeige