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

llennard

Frischling

  • »llennard« ist der Autor dieses Themas

Beiträge: 74

Wohnort: Kiel

  • Private Nachricht senden

1

10.02.2008, 10:30

Fehler in Box-Box-Kollisionsfunktion

Hallo,
ich habe eine Box-Box-Kollisionsfunktion geschrieben und teils auch übernommen, allerdings funktioniert die Kollisionserkennung damit nicht richtig. Manchmal wird eine Kollision erkannt, wenn sich die Boxen sich nicht schneiden und manchmal wird keine erkannt, wenn sie es tun. Ich habe die Funktion schon mehrere Male verglichen mit anderen Implementierungen aus Büchern, aber ich kann keinen Fehler entdecken. Habt ihr eine Ahnung wo er sein könnte? Hier ist der Code:

C-/C++-Quelltext

1
2
3
4
5
6
7
struct GSBOX
{
    GSVECTOR3 vCenter;
    GSVECTOR3 vHalfSize;
    GSMATRIX  mRotation;
    GSMATRIX  mInvRotation;
};


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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
GSBOOL gsBoxHitsBox(const GSBOX& Box, const GSBOX& Box2)
{
    const GSVECTOR3 vBox1Position = Box.vCenter;
    const GSVECTOR3 vBox2Position = Box2.vCenter;
    const GSVECTOR3 v = vBox2Position - vBox1Position;
    const GSVECTOR3 T(gsVec3Dot(v, GSVECTOR3(&Box.mRotation.m11)),
                      gsVec3Dot(v, GSVECTOR3(&Box.mRotation.m21)),
                      gsVec3Dot(v, GSVECTOR3(&Box.mRotation.m31)));

    GSFLOAT R[3][3];
    GSFLOAT ra, rb, t;
    int i, k;

    for(i = 0; i < 3; i++)
    {
        for(k = 0; k < 3; k++)
        {
            R[k][i] = gsVec3Dot(GSVECTOR3(Box.mRotation.n + i * 4),
                                GSVECTOR3(Box2.mRotation.n + k * 4));
        }
    }

    for(i = 0; i < 3; i++)
    {
        ra = Box.vHalfSize.c[i];
        rb = Box2.vHalfSize.c[0] * fabsf(R[i][0]) +
             Box2.vHalfSize.c[1] * fabsf(R[i][1]) +
             Box2.vHalfSize.c[2] * fabsf(R[i][2]);
        t = fabsf(T.c[i]);
        if(t > ra + rb) return false;
    }

    for(k = 0; k < 3; k++)
    {
        ra = Box.vHalfSize.c[0] * fabsf(R[0][k]) +
             Box.vHalfSize.c[1] * fabsf(R[1][k]) +
             Box.vHalfSize.c[2] * fabsf(R[2][k]);
        rb = Box2.vHalfSize.c[k];
        t = fabsf(T.c[0] * R[0][k] + T.c[1] * R[1][k] + T.c[2] * R[2][k]);
        if(t > ra + rb) return false;
    }

    ra = Box.vHalfSize.c[1] * fabsf(R[2][0]) + Box.vHalfSize.c[2] * fabsf(R[1][0]);
    rb = Box2.vHalfSize.c[1] * fabsf(R[0][2]) + Box2.vHalfSize.c[2] * fabsf(R[0][1]);
    t = fabsf(T.c[2] * R[1][0] - T.c[1] * R[2][0]);
    if(t > ra + rb) return false;

    ra = Box.vHalfSize.c[1] * fabsf(R[2][1]) + Box.vHalfSize.c[2] * fabsf(R[1][1]);
    rb = Box2.vHalfSize.c[0] * fabsf(R[0][2]) + Box2.vHalfSize.c[2] * fabsf(R[0][0]);
    t = fabsf(T.c[2] * R[1][1] - T.c[1] * R[2][1]);
    if(t > ra + rb) return false;

    ra = Box.vHalfSize.c[1] * fabsf(R[2][2]) + Box.vHalfSize.c[2] * fabsf(R[1][2]);
    rb = Box2.vHalfSize.c[0] * fabsf(R[0][1]) + Box2.vHalfSize.c[1] * fabsf(R[0][0]);
    t = fabsf(T.c[2] * R[1][2] - T.c[1] * R[2][2]);
    if(t > ra + rb) return false;

    ra = Box.vHalfSize.c[0] * fabsf(R[2][0]) + Box.vHalfSize.c[2] * fabsf(R[0][0]);
    rb = Box2.vHalfSize.c[1] * fabsf(R[1][2]) + Box2.vHalfSize.c[2] * fabsf(R[1][1]);
    t = fabsf(T.c[0] * R[2][0] - T.c[2] * R[0][0]);
    if(t > ra + rb) return false;

    ra = Box.vHalfSize.c[0] * fabsf(R[2][1]) + Box.vHalfSize.c[2] * fabsf(R[0][1]);
    rb = Box2.vHalfSize.c[0] * fabsf(R[1][2]) + Box2.vHalfSize.c[2] * fabsf(R[1][0]);
    t = fabsf(T.c[0] * R[2][1] - T.c[2] * R[0][1]);
    if(t > ra + rb) return false;

    ra = Box.vHalfSize.c[0] * fabsf(R[2][2]) + Box.vHalfSize.c[2] * fabsf(R[0][2]);
    rb = Box2.vHalfSize.c[0] * fabsf(R[1][1]) + Box2.vHalfSize.c[1] * fabsf(R[1][0]);
    t = fabsf(T.c[0] * R[2][2] - T.c[2] * R[0][2]);
    if(t > ra + rb) return false;

    ra = Box.vHalfSize.c[0] * fabsf(R[1][0]) + Box.vHalfSize.c[1] * fabsf(R[0][0]);
    rb = Box2.vHalfSize.c[1] * fabsf(R[2][2]) + Box2.vHalfSize.c[2] * fabsf(R[2][1]);
    t = fabsf(T.c[1] * R[0][0] - T.c[0] * R[1][0]);
    if(t > ra + rb) return false;

    ra = Box.vHalfSize.c[0] * fabsf(R[1][1]) + Box.vHalfSize.c[1] * fabsf(R[0][1]);
    rb = Box2.vHalfSize.c[0] * fabsf(R[2][2]) + Box2.vHalfSize.c[2] * fabsf(R[2][0]);
    t = fabsf(T.c[1] * R[0][1] - T.c[0] * R[1][1]);
    if(t > ra + rb) return false;

    ra = Box.vHalfSize.c[0] * fabsf(R[1][2]) + Box.vHalfSize.c[1] * fabsf(R[0][2]);
    rb = Box2.vHalfSize.c[0] * fabsf(R[2][1]) + Box2.vHalfSize.c[1] * fabsf(R[2][0]);
    t = fabsf(T.c[1] * R[0][2] - T.c[0] * R[1][2]);
    if(t > ra + rb) return false;

    return true;
}

2

10.02.2008, 11:07

Viel interessante wäre es zu wissen, wie die Boxen angeordnet sein müssen, damit die Kollision falsch ist. Ist die Funktion nur ungenau? Oder kann auch ein zich Einheiten entfernter Würfel, der bloß falsch gedreht ist eine Kollision hervorrufen?
Konntest du herausfinden, wie sich 2 Würfel überschneiden müssen, damit es keine Kollision gibt?
Wenn du das genau analysieren würdest, wärst du wahrscheinlich schon ein ganze Stückchen weiter. Den ich guck mir deinen Code jetzt bestimmt nicht an. Zich Zeilen wo einfach nur gerechnet wird, ohne ein einziges Kommentar, was genau du machst.
Lieber dumm fragen, als dumm bleiben!