~ubuntu-branches/debian/sid/astromenace/sid

« back to all changes in this revision

Viewing changes to AstroMenaceSource/Object3D/Object3DCollisionMath.cpp

  • Committer: Package Import Robot
  • Author(s): Boris Pek
  • Date: 2013-04-09 02:04:25 UTC
  • Revision ID: package-import@ubuntu.com-20130409020425-a7fl9xk4diamw6di
Tags: upstream-1.3.1+repack
Import upstream version 1.3.1+repack

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/************************************************************************************
 
2
 
 
3
        AstroMenace (Hardcore 3D space shooter with spaceship upgrade possibilities)
 
4
        Copyright © 2006-2012 Michael Kurinnoy, Viewizard
 
5
 
 
6
 
 
7
        AstroMenace is free software: you can redistribute it and/or modify
 
8
        it under the terms of the GNU General Public License as published by
 
9
        the Free Software Foundation, either version 3 of the License, or
 
10
        (at your option) any later version.
 
11
 
 
12
        AstroMenace is distributed in the hope that it will be useful,
 
13
        but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
15
        GNU General Public License for more details.
 
16
 
 
17
        You should have received a copy of the GNU General Public License
 
18
        along with AstroMenace. If not, see <http://www.gnu.org/licenses/>.
 
19
 
 
20
 
 
21
        Web Site: http://www.viewizard.com/
 
22
        Project: http://sourceforge.net/projects/openastromenace/
 
23
        E-mail: viewizard@viewizard.com
 
24
 
 
25
*************************************************************************************/
 
26
 
 
27
 
 
28
/// подключаем нужные файлы
 
29
#include "Object3D.h"
 
30
 
 
31
 
 
32
 
 
33
 
 
34
 
 
35
 
 
36
//-----------------------------------------------------------------------------
 
37
// Проверка столкновений Sphere-Mesh
 
38
//-----------------------------------------------------------------------------
 
39
bool CheckMeshSphereCollisionDetection(CObject3D *Object1, CObject3D *Object2, VECTOR3D *NewLoc, int *Object1PieceNum)
 
40
{
 
41
        if (Object1->DrawObjectList == 0) return false;
 
42
 
 
43
 
 
44
        for (int j=0; j<Object1->DrawObjectQuantity; j++)
 
45
        if (Object1->DrawObjectList[j].VertexCount != 0)
 
46
        {
 
47
 
 
48
                if (Object1->HitBB != 0)
 
49
                {
 
50
                        float Distance2 = (Object1->Location.x + Object1->HitBBLocation[j].x - Object2->Location.x)*(Object1->Location.x + Object1->HitBBLocation[j].x - Object2->Location.x) +
 
51
                                                          (Object1->Location.y + Object1->HitBBLocation[j].y - Object2->Location.y)*(Object1->Location.y + Object1->HitBBLocation[j].y - Object2->Location.y) +
 
52
                                                          (Object1->Location.z + Object1->HitBBLocation[j].z - Object2->Location.z)*(Object1->Location.z + Object1->HitBBLocation[j].z - Object2->Location.z);
 
53
 
 
54
                        // если очень далеко - берем следующий HitBB
 
55
                        // но сначала делаем еще одну проверку
 
56
                        if (Distance2 > Object1->HitBBRadius2[j] + Object2->Radius*Object2->Radius)
 
57
                        {
 
58
                                // средняя точка линии
 
59
                                VECTOR3D mid = (Object2->Location + Object2->PrevLocation) / 2.0f;
 
60
                                // направление линии
 
61
                                VECTOR3D dir = Object2->Location - Object2->PrevLocation;
 
62
                                // полудлина линии
 
63
                                float hl = dir.Length()/2.0f;
 
64
                                dir.Normalize();
 
65
 
 
66
                                VECTOR3D T = Object1->Location + Object1->HitBBLocation[j] - mid;
 
67
                                float r;
 
68
 
 
69
                                // проверяем, является ли одна из осей X,Y,Z разделяющей
 
70
                                if ( (fabs(T.x) > Object1->HitBB[j][0].x + hl*fabs(dir.x)) ||
 
71
                                        (fabs(T.y) > Object1->HitBB[j][0].y + hl*fabs(dir.y)) ||
 
72
                                        (fabs(T.z) > Object1->HitBB[j][0].z + hl*fabs(dir.z)) )
 
73
                                        continue;
 
74
 
 
75
 
 
76
                                // проверяем X ^ dir
 
77
                                r = Object1->HitBB[j][0].y*fabs(dir.z) + Object1->HitBB[j][0].z*fabs(dir.y);
 
78
                                if ( fabs(T.y*dir.z - T.z*dir.y) > r )
 
79
                                        continue;
 
80
 
 
81
                                // проверяем Y ^ dir
 
82
                                r = Object1->HitBB[j][0].x*fabs(dir.z) + Object1->HitBB[j][0].z*fabs(dir.x);
 
83
                                if ( fabs(T.z*dir.x - T.x*dir.z) > r )
 
84
                                        continue;
 
85
 
 
86
                                // проверяем Z ^ dir
 
87
                                r = Object1->HitBB[j][0].x*fabs(dir.y) + Object1->HitBB[j][0].y*fabs(dir.x);
 
88
                                if ( fabs(T.x*dir.y - T.y*dir.x) > r )
 
89
                                        continue;
 
90
                        }
 
91
                }
 
92
 
 
93
 
 
94
 
 
95
                // дальше работаем с геометрией
 
96
 
 
97
                if(vw_SphereMeshCollision(Object1->Location, &(Object1->DrawObjectList[j]), Object1->CurrentRotationMat,
 
98
                                                        Object2->Radius, Object2->Location, Object2->PrevLocation,
 
99
                                                        NewLoc))
 
100
                {
 
101
                        *Object1PieceNum = j;
 
102
                        return true;
 
103
                }
 
104
        }
 
105
 
 
106
        return false;
 
107
}
 
108
 
 
109
 
 
110
 
 
111
 
 
112
 
 
113
 
 
114
 
 
115
 
 
116
 
 
117
//-----------------------------------------------------------------------------
 
118
// Проверка столкновений HitBB-HitBB
 
119
//-----------------------------------------------------------------------------
 
120
bool CheckHitBBHitBBCollisionDetection(CObject3D *Object1, CObject3D *Object2, int *Object1PieceNum, int *Object2PieceNum)
 
121
{
 
122
        // проверяем HitBB, находим номера пересекающихся
 
123
        for (int i=0; i<Object1->DrawObjectQuantity; i++)
 
124
        if (Object1->DrawObjectList[i].VertexCount != 0)
 
125
        {
 
126
 
 
127
                for (int j=0; j<Object2->DrawObjectQuantity; j++)
 
128
                if (Object2->DrawObjectList[j].VertexCount != 0)
 
129
                {
 
130
 
 
131
                        // находим расстояние между HitBB-ми
 
132
                        float Distance2 = (Object1->Location.x + Object1->HitBBLocation[i].x - Object2->Location.x - Object2->HitBBLocation[j].x)*
 
133
                                                          (Object1->Location.x + Object1->HitBBLocation[i].x - Object2->Location.x - Object2->HitBBLocation[j].x) +
 
134
                                                          (Object1->Location.y + Object1->HitBBLocation[i].y - Object2->Location.y - Object2->HitBBLocation[j].y)*
 
135
                                                          (Object1->Location.y + Object1->HitBBLocation[i].y - Object2->Location.y - Object2->HitBBLocation[j].y) +
 
136
                                                          (Object1->Location.z + Object1->HitBBLocation[i].z - Object2->Location.z - Object2->HitBBLocation[j].z)*
 
137
                                                          (Object1->Location.z + Object1->HitBBLocation[i].z - Object2->Location.z - Object2->HitBBLocation[j].z);
 
138
 
 
139
 
 
140
                        // если очень далеко - берем следующий HitBB
 
141
                        if (Distance2 > Object2->HitBBRadius2[j] + Object1->HitBBRadius2[i]) continue;
 
142
 
 
143
                        // если достаточно близко - проверяем как OBB
 
144
 
 
145
 
 
146
                        // строим матрицу, чтобы развернуть точки
 
147
                        float TMPOldInvRotationMat[9];
 
148
                        memcpy(TMPOldInvRotationMat, Object1->CurrentRotationMat, 9*sizeof(float));
 
149
                        Matrix33InverseRotate(TMPOldInvRotationMat);
 
150
 
 
151
                        float matB[9];
 
152
                        memcpy(matB, Object2->CurrentRotationMat, 9*sizeof(float));
 
153
                        Matrix33Mult(matB, TMPOldInvRotationMat);
 
154
 
 
155
 
 
156
 
 
157
                        VECTOR3D vPosB = (Object2->Location + Object2->HitBBLocation[j])
 
158
                                                         - (Object1->Location + Object1->HitBBLocation[i]);
 
159
                        Matrix33CalcPoint(&vPosB, TMPOldInvRotationMat);
 
160
 
 
161
 
 
162
                        VECTOR3D XAxis(matB[0],matB[3],matB[6]);
 
163
                        VECTOR3D YAxis(matB[1],matB[4],matB[7]);
 
164
                        VECTOR3D ZAxis(matB[2],matB[5],matB[8]);
 
165
 
 
166
 
 
167
                        VECTOR3D Obj1_data(Object1->HitBBSize[i].x/2.0f, Object1->HitBBSize[i].y/2.0f, Object1->HitBBSize[i].z/2.0f);
 
168
                        VECTOR3D Obj2_data(Object2->HitBBSize[j].x/2.0f, Object2->HitBBSize[j].y/2.0f, Object2->HitBBSize[j].z/2.0f);
 
169
 
 
170
 
 
171
 
 
172
                        //делаем 15 проверок, т.к. у нас 15 разделяющих осей
 
173
 
 
174
                        //1 (Ra)x
 
175
                        if(fabsf(vPosB.x) > Obj1_data.x + Obj2_data.x * fabsf(XAxis.x) + Obj2_data.y * fabsf(XAxis.y) + Obj2_data.z * fabsf(XAxis.z))
 
176
                                continue;
 
177
 
 
178
                        //2 (Ra)y
 
179
                        if(fabsf(vPosB.y) > Obj1_data.y + Obj2_data.x * fabsf(YAxis.x) + Obj2_data.y * fabsf(YAxis.y) + Obj2_data.z * fabsf(YAxis.z))
 
180
                                continue;
 
181
 
 
182
                        //3 (Ra)z
 
183
                        if(fabsf(vPosB.z) > Obj1_data.z + Obj2_data.x * fabsf(ZAxis.x) + Obj2_data.y * fabsf(ZAxis.y) + Obj2_data.z * fabsf(ZAxis.z))
 
184
                                continue;
 
185
 
 
186
 
 
187
                        //4 (Rb)x
 
188
                        if(fabsf(vPosB.x*XAxis.x+vPosB.y*YAxis.x+vPosB.z*ZAxis.x) >
 
189
                                (Obj2_data.x+Obj1_data.x*fabsf(XAxis.x) + Obj1_data.y * fabsf(YAxis.x) + Obj1_data.z*fabsf(ZAxis.x)))
 
190
                                continue;
 
191
 
 
192
                        //5 (Rb)y
 
193
                        if(fabsf(vPosB.x*XAxis.y+vPosB.y*YAxis.y+vPosB.z*ZAxis.y) >
 
194
                                (Obj2_data.y+Obj1_data.x*fabsf(XAxis.y) + Obj1_data.y * fabsf(YAxis.y) + Obj1_data.z*fabsf(ZAxis.y)))
 
195
                                continue;
 
196
 
 
197
                        //6 (Rb)z
 
198
                        if(fabsf(vPosB.x*XAxis.z+vPosB.y*YAxis.z+vPosB.z*ZAxis.z) >
 
199
                                (Obj2_data.z+Obj1_data.x*fabsf(XAxis.z) + Obj1_data.y * fabsf(YAxis.z) + Obj1_data.z*fabsf(ZAxis.z)))
 
200
                                continue;
 
201
 
 
202
                        //7 (Ra)x X (Rb)x
 
203
                        if(fabsf(vPosB.z*YAxis.x-vPosB.y*ZAxis.x) > Obj1_data.y*fabsf(ZAxis.x) +
 
204
                                Obj1_data.z*fabsf(YAxis.x) + Obj2_data.y*fabsf(XAxis.z) + Obj2_data.z*fabsf(XAxis.y))
 
205
                                continue;
 
206
 
 
207
                        //8 (Ra)x X (Rb)y
 
208
                        if(fabsf(vPosB.z*YAxis.y-vPosB.y*ZAxis.y) > Obj1_data.y*fabsf(ZAxis.y) +
 
209
                                Obj1_data.z*fabsf(YAxis.y) + Obj2_data.x*fabsf(XAxis.z) + Obj2_data.z*fabsf(XAxis.x))
 
210
                                continue;
 
211
 
 
212
                        //9 (Ra)x X (Rb)z
 
213
                        if(fabsf(vPosB.z*YAxis.z-vPosB.y*ZAxis.z) > Obj1_data.y*fabsf(ZAxis.z) +
 
214
                                Obj1_data.z*fabsf(YAxis.z) + Obj2_data.x*fabsf(XAxis.y) + Obj2_data.y*fabsf(XAxis.x))
 
215
                                continue;
 
216
 
 
217
                        //10 (Ra)y X (Rb)x
 
218
                        if(fabsf(vPosB.x*ZAxis.x-vPosB.z*XAxis.x) > Obj1_data.x*fabsf(ZAxis.x) +
 
219
                                Obj1_data.z*fabsf(XAxis.x) + Obj2_data.y*fabsf(YAxis.z) + Obj2_data.z*fabsf(YAxis.y))
 
220
                                continue;
 
221
 
 
222
                        //11 (Ra)y X (Rb)y
 
223
                        if(fabsf(vPosB.x*ZAxis.y-vPosB.z*XAxis.y) > Obj1_data.x*fabsf(ZAxis.y) +
 
224
                                Obj1_data.z*fabsf(XAxis.y) + Obj2_data.x*fabsf(YAxis.z) + Obj2_data.z*fabsf(YAxis.x))
 
225
                                continue;
 
226
 
 
227
                        //12 (Ra)y X (Rb)z
 
228
                        if(fabsf(vPosB.x*ZAxis.z-vPosB.z*XAxis.z) > Obj1_data.x*fabsf(ZAxis.z) +
 
229
                                Obj1_data.z*fabsf(XAxis.z) + Obj2_data.x*fabsf(YAxis.y) + Obj2_data.y*fabsf(YAxis.x))
 
230
                                continue;
 
231
 
 
232
                        //13 (Ra)z X (Rb)x
 
233
                        if(fabsf(vPosB.y*XAxis.x-vPosB.x*YAxis.x) > Obj1_data.x*fabsf(YAxis.x) +
 
234
                                Obj1_data.y*fabsf(XAxis.x) + Obj2_data.y*fabsf(ZAxis.z) + Obj2_data.z*fabsf(ZAxis.y))
 
235
                                continue;
 
236
 
 
237
                        //14 (Ra)z X (Rb)y
 
238
                        if(fabsf(vPosB.y*XAxis.y-vPosB.x*YAxis.y) > Obj1_data.x*fabsf(YAxis.y) +
 
239
                                Obj1_data.y*fabsf(XAxis.y) + Obj2_data.x*fabsf(ZAxis.z) + Obj2_data.z*fabsf(ZAxis.x))
 
240
                                continue;
 
241
 
 
242
                        //15 (Ra)z X (Rb)z
 
243
                        if(fabsf(vPosB.y*XAxis.z-vPosB.x*YAxis.z) > Obj1_data.x*fabsf(YAxis.z) +
 
244
                                Obj1_data.y*fabsf(XAxis.z) + Obj2_data.x*fabsf(ZAxis.y) + Obj2_data.y*fabsf(ZAxis.x))
 
245
                                continue;
 
246
 
 
247
 
 
248
                        // если тут, нашли пересекающиеся!
 
249
 
 
250
                        *Object1PieceNum = i;
 
251
                        *Object2PieceNum = j;
 
252
 
 
253
                        return true;
 
254
                }
 
255
 
 
256
 
 
257
        }
 
258
 
 
259
 
 
260
        return false;
 
261
}
 
262
 
 
263
 
 
264
 
 
265
 
 
266
 
 
267
 
 
268
//-----------------------------------------------------------------------------
 
269
// Проверка столкновений HitBB-OBB
 
270
//-----------------------------------------------------------------------------
 
271
bool CheckHitBBOBBCollisionDetection(CObject3D *Object1, CObject3D *Object2, int *Object1PieceNum)
 
272
{
 
273
        // проверяем HitBB, находим номера пересекающихся
 
274
        for (int i=0; i<Object1->DrawObjectQuantity; i++)
 
275
        if (Object1->DrawObjectList[i].VertexCount != 0)
 
276
        {
 
277
 
 
278
                // строим матрицу, чтобы развернуть точки
 
279
                float TMPOldInvRotationMat[9];
 
280
                memcpy(TMPOldInvRotationMat, Object2->CurrentRotationMat, 9*sizeof(float));
 
281
                Matrix33InverseRotate(TMPOldInvRotationMat);
 
282
 
 
283
                float matB[9];
 
284
                memcpy(matB, Object1->CurrentRotationMat, 9*sizeof(float));
 
285
                Matrix33Mult(matB, TMPOldInvRotationMat);
 
286
 
 
287
 
 
288
                VECTOR3D vPosB = (Object1->Location + Object1->HitBBLocation[i])-(Object2->Location + Object2->OBBLocation);
 
289
                Matrix33CalcPoint(&vPosB, TMPOldInvRotationMat);
 
290
 
 
291
 
 
292
                VECTOR3D XAxis(matB[0],matB[3],matB[6]);
 
293
                VECTOR3D YAxis(matB[1],matB[4],matB[7]);
 
294
                VECTOR3D ZAxis(matB[2],matB[5],matB[8]);
 
295
 
 
296
 
 
297
                VECTOR3D Obj2_data(Object1->HitBBSize[i].x/2.0f, Object1->HitBBSize[i].y/2.0f, Object1->HitBBSize[i].z/2.0f);
 
298
                VECTOR3D Obj1_data(Object2->Width/2.0f, Object2->Height/2.0f, Object2->Length/2.0f);
 
299
 
 
300
 
 
301
 
 
302
                //делаем 15 проверок, т.к. у нас 15 разделяющих осей
 
303
 
 
304
                //1 (Ra)x
 
305
                if(fabsf(vPosB.x) > Obj1_data.x + Obj2_data.x * fabsf(XAxis.x) + Obj2_data.y * fabsf(XAxis.y) + Obj2_data.z * fabsf(XAxis.z))
 
306
                        continue;
 
307
 
 
308
                //2 (Ra)y
 
309
                if(fabsf(vPosB.y) > Obj1_data.y + Obj2_data.x * fabsf(YAxis.x) + Obj2_data.y * fabsf(YAxis.y) + Obj2_data.z * fabsf(YAxis.z))
 
310
                        continue;
 
311
 
 
312
                //3 (Ra)z
 
313
                if(fabsf(vPosB.z) > Obj1_data.z + Obj2_data.x * fabsf(ZAxis.x) + Obj2_data.y * fabsf(ZAxis.y) + Obj2_data.z * fabsf(ZAxis.z))
 
314
                        continue;
 
315
 
 
316
                //4 (Rb)x
 
317
                if(fabsf(vPosB.x*XAxis.x+vPosB.y*YAxis.x+vPosB.z*ZAxis.x) >
 
318
                        (Obj2_data.x+Obj1_data.x*fabsf(XAxis.x) + Obj1_data.y * fabsf(YAxis.x) + Obj1_data.z*fabsf(ZAxis.x)))
 
319
                        continue;
 
320
 
 
321
                //5 (Rb)y
 
322
                if(fabsf(vPosB.x*XAxis.y+vPosB.y*YAxis.y+vPosB.z*ZAxis.y) >
 
323
                        (Obj2_data.y+Obj1_data.x*fabsf(XAxis.y) + Obj1_data.y * fabsf(YAxis.y) + Obj1_data.z*fabsf(ZAxis.y)))
 
324
                        continue;
 
325
 
 
326
                //6 (Rb)z
 
327
                if(fabsf(vPosB.x*XAxis.z+vPosB.y*YAxis.z+vPosB.z*ZAxis.z) >
 
328
                        (Obj2_data.z+Obj1_data.x*fabsf(XAxis.z) + Obj1_data.y * fabsf(YAxis.z) + Obj1_data.z*fabsf(ZAxis.z)))
 
329
                        continue;
 
330
 
 
331
                //7 (Ra)x X (Rb)x
 
332
                if(fabsf(vPosB.z*YAxis.x-vPosB.y*ZAxis.x) > Obj1_data.y*fabsf(ZAxis.x) +
 
333
                        Obj1_data.z*fabsf(YAxis.x) + Obj2_data.y*fabsf(XAxis.z) + Obj2_data.z*fabsf(XAxis.y))
 
334
                        continue;
 
335
 
 
336
                //8 (Ra)x X (Rb)y
 
337
                if(fabsf(vPosB.z*YAxis.y-vPosB.y*ZAxis.y) > Obj1_data.y*fabsf(ZAxis.y) +
 
338
                        Obj1_data.z*fabsf(YAxis.y) + Obj2_data.x*fabsf(XAxis.z) + Obj2_data.z*fabsf(XAxis.x))
 
339
                        continue;
 
340
 
 
341
                //9 (Ra)x X (Rb)z
 
342
                if(fabsf(vPosB.z*YAxis.z-vPosB.y*ZAxis.z) > Obj1_data.y*fabsf(ZAxis.z) +
 
343
                        Obj1_data.z*fabsf(YAxis.z) + Obj2_data.x*fabsf(XAxis.y) + Obj2_data.y*fabsf(XAxis.x))
 
344
                        continue;
 
345
 
 
346
                //10 (Ra)y X (Rb)x
 
347
                if(fabsf(vPosB.x*ZAxis.x-vPosB.z*XAxis.x) > Obj1_data.x*fabsf(ZAxis.x) +
 
348
                        Obj1_data.z*fabsf(XAxis.x) + Obj2_data.y*fabsf(YAxis.z) + Obj2_data.z*fabsf(YAxis.y))
 
349
                        continue;
 
350
 
 
351
                //11 (Ra)y X (Rb)y
 
352
                if(fabsf(vPosB.x*ZAxis.y-vPosB.z*XAxis.y) > Obj1_data.x*fabsf(ZAxis.y) +
 
353
                        Obj1_data.z*fabsf(XAxis.y) + Obj2_data.x*fabsf(YAxis.z) + Obj2_data.z*fabsf(YAxis.x))
 
354
                        continue;
 
355
 
 
356
                //12 (Ra)y X (Rb)z
 
357
                if(fabsf(vPosB.x*ZAxis.z-vPosB.z*XAxis.z) > Obj1_data.x*fabsf(ZAxis.z) +
 
358
                        Obj1_data.z*fabsf(XAxis.z) + Obj2_data.x*fabsf(YAxis.y) + Obj2_data.y*fabsf(YAxis.x))
 
359
                        continue;
 
360
 
 
361
                //13 (Ra)z X (Rb)x
 
362
                if(fabsf(vPosB.y*XAxis.x-vPosB.x*YAxis.x) > Obj1_data.x*fabsf(YAxis.x) +
 
363
                        Obj1_data.y*fabsf(XAxis.x) + Obj2_data.y*fabsf(ZAxis.z) + Obj2_data.z*fabsf(ZAxis.y))
 
364
                        continue;
 
365
 
 
366
                //14 (Ra)z X (Rb)y
 
367
                if(fabsf(vPosB.y*XAxis.y-vPosB.x*YAxis.y) > Obj1_data.x*fabsf(YAxis.y) +
 
368
                        Obj1_data.y*fabsf(XAxis.y) + Obj2_data.x*fabsf(ZAxis.z) + Obj2_data.z*fabsf(ZAxis.x))
 
369
                        continue;
 
370
 
 
371
                //15 (Ra)z X (Rb)z
 
372
                if(fabsf(vPosB.y*XAxis.z-vPosB.x*YAxis.z) > Obj1_data.x*fabsf(YAxis.z) +
 
373
                        Obj1_data.y*fabsf(XAxis.z) + Obj2_data.x*fabsf(ZAxis.y) + Obj2_data.y*fabsf(ZAxis.x))
 
374
                        continue;
 
375
 
 
376
                // если тут, нашли пересекающиеся!
 
377
                *Object1PieceNum = i;
 
378
                return true;
 
379
        }
 
380
 
 
381
        return false;
 
382
}
 
383
 
 
384
 
 
385
 
 
386
 
 
387
 
 
388
 
 
389
 
 
390
 
 
391
 
 
392
 
 
393
 
 
394
 
 
395
 
 
396
 
 
397
 
 
398
 
 
399
 
 
400
//-----------------------------------------------------------------------------
 
401
// Проверка столкновений геометрия больших астероидов -HitBB
 
402
//-----------------------------------------------------------------------------
 
403
bool CheckHitBBMeshCollisionDetection(CObject3D *Object1, CObject3D *Object2, int *Object1PieceNum)
 
404
{
 
405
        // делаем матрицу перемещения точки, для геометрии
 
406
        float TransMat[16];
 
407
        TransMat[0] = Object2->CurrentRotationMat[0];
 
408
        TransMat[1] = Object2->CurrentRotationMat[1];
 
409
        TransMat[2] = Object2->CurrentRotationMat[2];
 
410
        TransMat[3] = 0.0f;
 
411
        TransMat[4] = Object2->CurrentRotationMat[3];
 
412
        TransMat[5] = Object2->CurrentRotationMat[4];
 
413
        TransMat[6] = Object2->CurrentRotationMat[5];
 
414
        TransMat[7] = 0.0f;
 
415
        TransMat[8] = Object2->CurrentRotationMat[6];
 
416
        TransMat[9] = Object2->CurrentRotationMat[7];
 
417
        TransMat[10] = Object2->CurrentRotationMat[8];
 
418
        TransMat[11] = 0.0f;
 
419
        TransMat[12] = Object2->Location.x;
 
420
        TransMat[13] = Object2->Location.y;
 
421
        TransMat[14] = Object2->Location.z;
 
422
        TransMat[15] = 1.0f;
 
423
 
 
424
 
 
425
 
 
426
        // проверяем HitBB, находим номера пересекающихся
 
427
        for (int i=0; i<Object1->DrawObjectQuantity; i++)
 
428
        if (Object1->DrawObjectList[i].VertexCount != 0)
 
429
        {
 
430
 
 
431
                // параметры HitBB
 
432
                VECTOR3D TMPMax = Object1->HitBB[i][0];
 
433
                VECTOR3D TMPMin = Object1->HitBB[i][6];
 
434
 
 
435
                // строим матрицу, чтобы развернуть точки
 
436
                float TMPOldInvRotationMat[9];
 
437
                memcpy(TMPOldInvRotationMat, Object1->CurrentRotationMat, 9*sizeof(float));
 
438
                Matrix33InverseRotate(TMPOldInvRotationMat);
 
439
 
 
440
                // перемещаем в общие координаты, теперь это как-бы крайние точки аабб
 
441
                Matrix33CalcPoint(&TMPMax, TMPOldInvRotationMat);
 
442
                Matrix33CalcPoint(&TMPMin, TMPOldInvRotationMat);
 
443
 
 
444
 
 
445
                VECTOR3D Center = Object1->HitBBLocation[i] + Object1->Location;
 
446
                Matrix33CalcPoint(&Center, TMPOldInvRotationMat);
 
447
 
 
448
 
 
449
                VECTOR3D TMPMax2;
 
450
                VECTOR3D TMPMin2;
 
451
                VECTOR3D Point1;
 
452
                VECTOR3D Point2;
 
453
                VECTOR3D Point3;
 
454
 
 
455
 
 
456
                // проверяем все треугольники объекта
 
457
                for (int j=0; j<Object2->DrawObjectQuantity; j++)
 
458
                if (Object2->DrawObjectList[j].VertexCount != 0)
 
459
                {
 
460
 
 
461
                        // дальше работаем с геометрией
 
462
 
 
463
 
 
464
                        // находим точку локального положения объекта в моделе
 
465
                        VECTOR3D LocalLocation(Object2->DrawObjectList[j].Location);
 
466
                        Matrix33CalcPoint(&LocalLocation, Object2->CurrentRotationMat);
 
467
 
 
468
                        // делаем временную матрицу для объекта, т.к. портить основную нельзя
 
469
                        float ObjTransMat[16];
 
470
                        memcpy(ObjTransMat, TransMat, 16*sizeof(float));
 
471
 
 
472
                        // если нужно - создаем матрицу, иначе - копируем ее
 
473
                        if (Object2->DrawObjectList[j].Rotation.x != 0.0f ||
 
474
                                Object2->DrawObjectList[j].Rotation.y != 0.0f ||
 
475
                                Object2->DrawObjectList[j].Rotation.z != 0.0f)
 
476
                        {
 
477
                                float TransMatTMP[16];
 
478
                                Matrix44Identity(TransMatTMP);
 
479
 
 
480
                                Matrix44CreateRotate(TransMatTMP, Object2->DrawObjectList[j].Rotation);
 
481
 
 
482
                                Matrix44Translate(TransMatTMP, LocalLocation);
 
483
                                // и умножаем на основную матрицу, со сведениями по всему объекту
 
484
                                Matrix44Mult(ObjTransMat, TransMatTMP);
 
485
                        }
 
486
                        else
 
487
                        {
 
488
                                Matrix44Translate(ObjTransMat, LocalLocation);
 
489
                        }
 
490
 
 
491
 
 
492
 
 
493
 
 
494
 
 
495
 
 
496
                        for (int k=0; k<Object2->DrawObjectList[j].VertexCount; k+=3)
 
497
                        {
 
498
 
 
499
                                int j2;
 
500
                                if (Object2->DrawObjectList[j].IndexBuffer != 0)
 
501
                                        j2 = Object2->DrawObjectList[j].IndexBuffer[Object2->DrawObjectList[j].RangeStart+k]*Object2->DrawObjectList[j].VertexStride;
 
502
                                else
 
503
                                        j2 = (Object2->DrawObjectList[j].RangeStart+k)*Object2->DrawObjectList[j].VertexStride;
 
504
 
 
505
                                // находим точки триугольника
 
506
                                VECTOR3D Point1;
 
507
                                Point1.x = Object2->DrawObjectList[j].VertexBuffer[j2];
 
508
                                Point1.y = Object2->DrawObjectList[j].VertexBuffer[j2+1];
 
509
                                Point1.z = Object2->DrawObjectList[j].VertexBuffer[j2+2];
 
510
                                Matrix44CalcPoint(&Point1, ObjTransMat);
 
511
 
 
512
                                if (Object2->DrawObjectList[j].IndexBuffer != 0)
 
513
                                        j2 = Object2->DrawObjectList[j].IndexBuffer[Object2->DrawObjectList[j].RangeStart+k+1]*Object2->DrawObjectList[j].VertexStride;
 
514
                                else
 
515
                                        j2 = (Object2->DrawObjectList[j].RangeStart+k+1)*Object2->DrawObjectList[j].VertexStride;
 
516
 
 
517
                                VECTOR3D Point2;
 
518
                                Point2.x = Object2->DrawObjectList[j].VertexBuffer[j2];
 
519
                                Point2.y = Object2->DrawObjectList[j].VertexBuffer[j2+1];
 
520
                                Point2.z = Object2->DrawObjectList[j].VertexBuffer[j2+2];
 
521
                                Matrix44CalcPoint(&Point2, ObjTransMat);
 
522
 
 
523
                                if (Object2->DrawObjectList[j].IndexBuffer != 0)
 
524
                                        j2 = Object2->DrawObjectList[j].IndexBuffer[Object2->DrawObjectList[j].RangeStart+k+2]*Object2->DrawObjectList[j].VertexStride;
 
525
                                else
 
526
                                        j2 = (Object2->DrawObjectList[j].RangeStart+k+2)*Object2->DrawObjectList[j].VertexStride;
 
527
 
 
528
                                VECTOR3D Point3;
 
529
                                Point3.x = Object2->DrawObjectList[j].VertexBuffer[j2];
 
530
                                Point3.y = Object2->DrawObjectList[j].VertexBuffer[j2+1];
 
531
                                Point3.z = Object2->DrawObjectList[j].VertexBuffer[j2+2];
 
532
                                Matrix44CalcPoint(&Point3, ObjTransMat);
 
533
 
 
534
 
 
535
 
 
536
                                // преобразуем все точки в систему первого объекта
 
537
 
 
538
                                Matrix33CalcPoint(&Point1, TMPOldInvRotationMat);
 
539
                                Matrix33CalcPoint(&Point2, TMPOldInvRotationMat);
 
540
                                Matrix33CalcPoint(&Point3, TMPOldInvRotationMat);
 
541
 
 
542
 
 
543
                                // сразу ставим номер
 
544
                                *Object1PieceNum = i;
 
545
 
 
546
 
 
547
                                // сначала проверка по точкам...
 
548
                                if (fabsf(Center.x - Point1.x) <= TMPMax.x)
 
549
                                if (fabsf(Center.y - Point1.y) <= TMPMax.y)
 
550
                                if (fabsf(Center.z - Point1.z) <= TMPMax.z)
 
551
                                                return true;
 
552
                                if (fabsf(Center.x - Point2.x) <= TMPMax.x)
 
553
                                if (fabsf(Center.y - Point2.y) <= TMPMax.y)
 
554
                                if (fabsf(Center.z - Point2.z) <= TMPMax.z)
 
555
                                                return true;
 
556
                                if (fabsf(Center.x - Point3.x) <= TMPMax.x)
 
557
                                if (fabsf(Center.y - Point3.y) <= TMPMax.y)
 
558
                                if (fabsf(Center.z - Point3.z) <= TMPMax.z)
 
559
                                                return true;
 
560
 
 
561
 
 
562
 
 
563
 
 
564
                                // делаем боксы, и проверяем по ним
 
565
 
 
566
 
 
567
                                // делаем аабб
 
568
                                TMPMax2.x = Max3(Point1.x,Point2.x,Point3.x);
 
569
                                TMPMin2.x = Min3(Point1.x,Point2.x,Point3.x);
 
570
 
 
571
                                TMPMax2.y = Max3(Point1.y,Point2.y,Point3.y);
 
572
                                TMPMin2.y = Min3(Point1.y,Point2.y,Point3.y);
 
573
 
 
574
                                TMPMax2.z = Max3(Point1.z,Point2.z,Point3.z);
 
575
                                TMPMin2.z = Min3(Point1.z,Point2.z,Point3.z);
 
576
 
 
577
 
 
578
                                VECTOR3D Center2((TMPMax2.x+TMPMin2.x)/2.0f,(TMPMax2.y+TMPMin2.y)/2.0f,(TMPMax2.z+TMPMin2.z)/2.0f);
 
579
 
 
580
                                TMPMax2.x = TMPMax2.x - Center2.x;
 
581
                                TMPMax2.y = TMPMax2.y - Center2.y;
 
582
                                TMPMax2.z = TMPMax2.z - Center2.z;
 
583
 
 
584
 
 
585
 
 
586
                                if (fabsf(Center.x - Center2.x) > TMPMax.x + TMPMax2.x)
 
587
                                        continue;
 
588
                                if (fabsf(Center.y - Center2.y) > TMPMax.y + TMPMax2.y)
 
589
                                        continue;
 
590
                                if (fabsf(Center.z - Center2.z) > TMPMax.z + TMPMax2.z)
 
591
                                        continue;
 
592
 
 
593
 
 
594
                                return true;
 
595
 
 
596
                        }
 
597
                }
 
598
 
 
599
        }
 
600
 
 
601
        return false;
 
602
}