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

1

01.07.2014, 20:03

Kollisionserkennung bei Rotation

Hallo,

ich bin im Moment dabei ein Android-3D-Spiel mit opengles und Java zu entwickeln. Bin gerade bei den Funktionen für die Kollisionstests angekommen, jedoch funktioniert es nur für nicht gedrehte Objekte. Ich finde keinen brauchbaren Ansatz, womit ich die Endkoordinaten nach der Rotation ermitteln kann. Ich habe auch schon mehrere Dinge probiert, die ich über Google gefunden habe, jedoch gabs oft die benötigten Funktionen in opengles nicht, wie z.B. das Auslesen der Modelmatrix, der Vertexinfos oder das Erstellen einer eigenen Matrix.

Wie muss ich hier also vorgehen?

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

2

01.07.2014, 21:43

Leider sagst du uns gar nicht, um welche Art von Objekten es sich hier handelt.
Meshes aus Polygonen? Sind sie konvex? Quader/Boxen?

3

01.07.2014, 21:54

Quader, Cubes, Spheres, etc. Eigentlich alle Geometrischen Grundformen. Das was ich benötige, ist ein Denkanstoß oder einen kleinen Codeschnipsel, mit dem ich die Endkoordinaten der Vertices bekomme.

Das eigentliche Problem:

- Objekt hat Information x,y,z rotx, roty, rotz ...
- Objekt wird mit dem Mittelpunkt auf x,y,z verschoben
- Objekt wird auf den Achsen gedreht
- Durch die Rotatation stimmen x,y,z nicht mehr
- Die Kollisionserkennung, die diese Werte benötigt funktioniert nicht mehr richtig
- Für die Kollisionserkennung benötige ich die "neuen" Koordinaten

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

4

01.07.2014, 22:03

Also, um Kugeln brauchst du dich nicht zu sorgen, da man die drehen und wenden kann, wie man lustig ist, ohne dass sie sich dabei verändern. Quader sind konvex, das bringt dir schonmal viel, denn konvexe Körper kann man sehr effizient auf Schnitt testen. Um Translation und Rotation zu berücksichtigen, musst du natürlich die Eckpunkte der Objekte mit der Transformationsmatrix transformieren. Wenn du das hast, liegen beide Objekte im selben Koordinatensystem, und du kannst losrechnen. Schau dir mal das hier an: http://geometrictools.com/Documentation/…aratingAxes.pdf

5

02.07.2014, 00:24

Wait.. Wieso ändern sich xyz wenn du rotierst? Über welchen Koordinaten Raum reden wir denn hier? Object space? World space?

Rotations Matrizen findest du im Internet und in Tafelwerken mehr als ausführlich beschrieben.

Auch stellt sich mir noch die Frage, was genau du da vorliegen hast. Grundsätzlich werden kollisionsabfragen mit abstrakten collisionshapes (sphere, box, capsule, cylinder) realisiert, damit die Berechnungen auf einfache geometrische Berechnungen beschränkt wird und man mit einem ausgewogenen repoirtoir an Trigonometrie und Algebra auskommen sollte. Dann gibt es auch keine vertices, essei denn natürlich du verwendest simplified meshes (low lod) ...?
EnvisionGame(); EnableGame(); AchieveGame(); - Visionen kann man viele haben. Sie umzusetzen und auf das Ergebnis stolz zu sein ist die eigentliche Kunst.

6

09.07.2014, 18:59

Nach langem Suchen und Forschen habe ich jetzt eine Antwort gefunden. Das Stichwort war Objektkoordinaten->Weltkoordinaten.
Es mag sein, dass der Code nicht gerade gut für die Performance ist, aber das ist erstmal mein Prototyp für weiteren Berechnungen.


Wie gehe ich vor?

Zunächst erstmal muss man wissen, dass ich für jedes Objekt (z.B. Quader) und für jede Transformation (z.B. Rotation) ein Objekt in Java angelegt habe. Beim Zeichnen werden alle Objekte nacheinander durchlaufen und an openGL übergeben. Beim Kollisionstest werden die Objekte nochmals durchlaufen, bei jeder Transformation wird meine u.g. Funktion "transformMatrix" aufgerufen und verändert. Sobald ich dann die Weltkoordinaten von einem Objekt benötige, so werden über "getWorldCoordinates" die Vertices mit meiner Matrix multipliziert und erhalte die Koordinaten, wie sie nach der Transformation sind.

Ich mache allso das, was openGL beim Rendern automatisch macht, nochmal manuell, weil ich keinen Weg gefunden habe, wie ich die Weltkoordinaten auslesen kann.



Quellcode

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import javax.microedition.khronos.opengles.GL11;


public class Matrix
{
    
    private static float matrix[] = new float[16];
    private static float identityMatrix[] = {1, 0, 0, 0,    0, 1, 0, 0,     0, 0, 1, 0,     0, 0, 0, 1};
    
    static void resetMatrix()
    {
        matrix = identityMatrix.clone();
    }
    
    static void transformMatrix(GL11 gl, float translation[], float rotation[])
    {
        gl.glPushMatrix();
        gl.glLoadMatrixf(matrix, 0);
        
        
        gl.glRotatef(rotation[0], 1, 0, 0);
        gl.glRotatef(rotation[1], 0, 1, 0);
        gl.glRotatef(rotation[2], 0, 0, 1);
        gl.glTranslatef(translation[0], translation[1], translation[2]);
        
        gl.glGetFloatv(GL11.GL_MODELVIEW_MATRIX, matrix, 0);
        gl.glPopMatrix();
    }
    
    public static float[] getWorldCoordinates(float vertices[])
    {
        for(int i = 0; i < vertices.length / 3; i++)
        {
            int idx1 = i*3 + 0;
            int idx2 = i*3 + 1;
            int idx3 = i*3 + 2;
            
            float vec[] = {vertices[idx1], vertices[idx2], vertices[idx3]};
            
            
            float mtx[] = matrix;
            
            vertices[idx1] = (vec[0] * mtx[0]) + (vec[1] * mtx[4]) + (vec[2] * mtx[8])  + mtx[12];
            vertices[idx2] = (vec[0] * mtx[1]) + (vec[1] * mtx[5]) + (vec[2] * mtx[9])  + mtx[13];
            vertices[idx3] = (vec[0] * mtx[2]) + (vec[1] * mtx[6]) + (vec[2] * mtx[10]) + mtx[14];
        }
        
        
        
        return vertices;
    }
    
}



Verbesserungsvorschläge sind erwünscht.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »lennard« (29.07.2014, 19:18)


Werbeanzeige