Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
4 | daniel-mar | 1 | unit colli3DX; |
2 | |||
3 | {$include DelphiXcfg.inc} |
||
4 | |||
5 | |||
6 | //************************************************************************* |
||
7 | //* * |
||
8 | //* TCollisionTester3DX vs 1.3 * |
||
9 | //* * |
||
10 | //************************************************************************* |
||
11 | // |
||
12 | // This Delphi 4, 5, 6 component is CopyRight: |
||
13 | // |
||
14 | // Henrik Fabricius, August 1999, March 2000, June 2002 |
||
15 | // http://users.cybercity.dk/~bbl6194/delphi3dx.htm |
||
16 | // E-mail: henrik_og_bodil@vip.cybercity.dk |
||
17 | // |
||
18 | // You may use this component for free on the following conditions: |
||
19 | // 1) this text must remain part of the unit. |
||
20 | // 2) Any proposals for changes or improvements should be addressed directly to |
||
21 | // the copyright owner Henrik Fabricius |
||
22 | // 3) The use of this component is on your own risk. The software is provided |
||
23 | // as is without any garanties and warranty. The CopyRight Owner is not |
||
24 | // responsible for any damage or losses of any kind caused by the use of this |
||
25 | // software or the software it is intended to be used with. |
||
26 | // |
||
27 | // To place a link for down-loads of this component on your homepage |
||
28 | // please place a link to the Delphi3DX page where the latest version |
||
29 | // is available. |
||
30 | // |
||
31 | // To use this component you must have |
||
32 | // 1) Delphi 4, 5 or 6 |
||
33 | // 2) MS-DirectX 6.0 or higher |
||
34 | // 3) the DelphiX components from Hori in Japan |
||
35 | // |
||
36 | // MS-DirectX is a trademark of the Microsoft Corporation |
||
37 | // Delphi 4, 5 and 6 is a trademark of the Inprise Corporation |
||
38 | // |
||
39 | // Use this component to check for collisions between 3D objects in |
||
40 | // Direct3D games. |
||
41 | // Place your 3D-objects in a world described by : |
||
42 | // - DXDrawUsed - |
||
43 | // |
||
44 | // Group the 3D-objects in series with different material |
||
45 | // or functional properties |
||
46 | // The 3D-object series are named by the property: |
||
47 | // - Indexof3DSeries - |
||
48 | // 3D-objects are named by the property : |
||
49 | // - Indexof3Dobject - |
||
50 | // A 3D-object consist of one or more 3D-elements named by the property : |
||
51 | // - Indexof3DElement - |
||
52 | // |
||
53 | // Surround each of your 3D elements by at least one collision object |
||
54 | // which must be a member of the following primitives : |
||
55 | // - box3D - sphere3D - ellipsoid3D - cylinder3D - conus3D - |
||
56 | // available CollOrientations are : |
||
57 | // - Symmetric_X - Symmetric_Y - Symmetric_Z - |
||
58 | // available material properties are : |
||
59 | // - solid3D - water3D - air3D |
||
60 | // the size of the small end of the conus is described by the property |
||
61 | // - PercentLeftatTop - |
||
62 | // a negative value means that the top is downwards |
||
63 | // available functional properties are : |
||
64 | // - Pickable - Shootable - Fixed3DObject |
||
65 | // Add each object by specifying : |
||
66 | // - FrameSeries - NextAddMesh - CoverWholeMesh - |
||
67 | // - IndexOf3DSeries - IndexOf3DObject - IndexOf3DElement - |
||
68 | // if coverWholeMesh is false then specify a box containing the part of the |
||
69 | // 3D object which should be covered by the coll object by the commands |
||
70 | // - BoxPartMin(x,y,z) - BoxPartMax(x,y,z) - |
||
71 | // Finally add the collision object by executing the command |
||
72 | // - AddCollisionObject - |
||
73 | // |
||
74 | // Bullets are described by the following properties : |
||
75 | // - BulletRadius - BulletRange - BulletFrame - LongShots - |
||
76 | // LongShots moves with a unlimited speed reaching the objects immediately |
||
77 | // |
||
78 | // The actor is described by : |
||
79 | // - FrontDistance - HeadRadius - |
||
80 | // |
||
81 | // The camera-frame and the bullet-frames move each time the move command |
||
82 | // is used in the main program. |
||
83 | // Execute the following commands prior to each move command : |
||
84 | // - GetOldEyePos - GetOldBulletPos - |
||
85 | // The collisionTester needs this information to test for a possible collision |
||
86 | // in between the starting and the ending points of the Eye/bullet |
||
87 | // |
||
88 | // Test for collision with the following function calls : |
||
89 | // - if CollisionTester3DX1.Collision then .. |
||
90 | // - if CollisionTester3DX1.BulletCollision then .. |
||
91 | // On collision read the HitLinkNr and the properties of the collision object |
||
92 | // |
||
93 | // Destroy 3D collisionObjects by specifying : |
||
94 | // - NextDestroyNr - IndexOf3DSeries - |
||
95 | // and the executing command DestroyCollisionObject |
||
96 | // |
||
97 | // Initialize the collisionTester with the command : |
||
98 | // - CollisionTester3DX1.ZeroSetIt - |
||
99 | // This must always be done when DXDraw is initialized |
||
100 | // |
||
101 | // To install the component: |
||
102 | // 1) place this unit and the dcr file in the same directory as DelphiX |
||
103 | // 2) In Delphi you must click on Component - Install Component |
||
104 | // 3) Select the colli3DX.pas file and choose the Samples package to install it |
||
105 | // 4) Rebuild the library |
||
106 | // 5) Look for a new icon with a bomb on the page named DelphiX |
||
107 | // |
||
108 | // Tutorial programs are available for down-load at |
||
109 | // http://users.cybercity.dk/~bbl6194/delphi3dx.htm |
||
110 | // |
||
111 | // Good Luck |
||
112 | // Henrik Fabricius |
||
113 | // |
||
114 | // |
||
115 | //**************************************************************************** |
||
116 | |||
117 | |||
118 | |||
119 | interface |
||
120 | |||
121 | uses |
||
122 | Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, |
||
123 | StdCtrls, DXClass, DXDraws, |
||
124 | {$IfDef StandardDX} |
||
125 | DirectDraw, Direct3D, Direct3DRM; |
||
126 | {$Else} |
||
127 | DirectX; |
||
128 | {$EndIf} |
||
129 | |||
130 | Type |
||
131 | Tshapes3D = (box3D, sphere3D, ellipsoid3D, cylinder3D, conus3D); |
||
132 | Tmaterials3D = (solid3D, water3D, air3D); |
||
133 | TOrientation3D = (symmetric_x, symmetric_y, symmetric_z); |
||
134 | TFrames3D = Array of Array of IDirect3DRMFrame; |
||
135 | |||
136 | TCollisionTester3DX = class(TComponent) |
||
137 | private |
||
138 | {private declarations} |
||
139 | FDXDrawUsed : TDXDraw; |
||
140 | FFrameSeries : TFrames3D; |
||
141 | FNextAddMesh : IDirect3DRMMesh; |
||
142 | FBulletFrame : IDirect3DRMFrame; |
||
143 | FBoxPartMin : TD3DVector; |
||
144 | FBoxPartMax : TD3DVector; |
||
145 | FOldBulletPosition: TD3DVector; |
||
146 | FOldEyePosition : TD3DVector; |
||
147 | |||
148 | FNrOfSeries : integer; |
||
149 | FSeriesIndex : integer; |
||
150 | FSeriesNr : integer; |
||
151 | FOrientation3D : TOrientation3D; |
||
152 | Fshape3D : Tshapes3D; |
||
153 | Fmaterial3D : Tmaterials3D; |
||
154 | FPercentLeftAtTop : integer; |
||
155 | Fbullet_hitLinknr : integer; |
||
156 | FIndexOf3DObject : integer; |
||
157 | FIndexOf3DElement : integer; |
||
158 | FNextDestroyNr : integer; |
||
159 | FNextAllOfMesh : Boolean; |
||
160 | FFrontDistance : integer; |
||
161 | FBulletRange : integer; |
||
162 | FBulletRadius : integer; |
||
163 | FHeadRadius : integer; |
||
164 | FFixed3DObject : Boolean; |
||
165 | FShootable : Boolean; |
||
166 | FLongShots : Boolean; |
||
167 | FPickable : Boolean; |
||
168 | FCheckAllCollObj : Boolean; |
||
169 | |||
170 | Fcoll_Nr_Objects : Array of integer; |
||
171 | FSeriesIndex_for_SeriesNr : Array of integer; |
||
172 | |||
173 | FNrinFrameSeries : Array of Array of integer; |
||
174 | Fcoll_orientation : Array of Array of TOrientation3D; |
||
175 | Fcoll_shape : Array of Array of Tshapes3D; |
||
176 | Fcoll_material : Array of Array of Tmaterials3D; |
||
177 | Fcoll_box_min : Array of Array of TD3DVector; |
||
178 | Fcoll_box_max : Array of Array of TD3DVector; |
||
179 | Fcoll_radius : Array of Array of TD3DValue; |
||
180 | Fcoll_frac_at_top : Array of Array of TD3DValue; |
||
181 | Fcoll_shootable : Array of Array of boolean; |
||
182 | Fcoll_Pickable : Array of Array of boolean; |
||
183 | Fcoll_Fixed3D : Array of Array of boolean; |
||
184 | Fcoll_objectNr : Array of Array of integer; |
||
185 | |||
186 | procedure SetOrientation3D(Value : TOrientation3D); |
||
187 | procedure SetShape3D(Value: TShapes3D); |
||
188 | procedure SetMaterial3D(Value: Tmaterials3D); |
||
189 | procedure SetPercentLeftatTop(Value: integer); |
||
190 | procedure SetIndexOf3DObject(Value : integer); |
||
191 | procedure SetIndexOf3DElement(Value : integer); |
||
192 | procedure SetIndexOf3DSeries(Value : integer); |
||
193 | procedure SetNextDestroyNr(Value : Integer); |
||
194 | procedure SetBulletRadius(Value : Integer); |
||
195 | procedure SetHeadRadius(Value : Integer); |
||
196 | procedure SetFrontDistance(Value : Integer); |
||
197 | procedure SetBulletRange(Value : Integer); |
||
198 | function add_space_for_one_more : boolean; |
||
199 | procedure GetTheBox; |
||
200 | procedure AddBox; |
||
201 | procedure AddSphere; |
||
202 | procedure AddCylinder; |
||
203 | procedure AddConus; |
||
204 | procedure AddEllipsoid; |
||
205 | |||
206 | procedure MakeNewSeries; |
||
207 | procedure Destroy_empty_series(SeriesNr : integer); |
||
208 | function GetSeriesNr(Nr : integer): integer; |
||
209 | procedure remove_collision_object(seriesNr, Value : integer); |
||
210 | function CheckForSeriesIndex(indexnow : integer): boolean; |
||
211 | procedure ListDataForCollObject; |
||
212 | function coll_test_box(coll_nr : byte; |
||
213 | old_attacker_position, attacker_position : TD3DVector; |
||
214 | bullet_radius : TD3DValue; longshot : boolean): boolean; |
||
215 | function coll_test_cylinder(coll_nr : byte; |
||
216 | old_attacker_position, attacker_position : TD3DVector; |
||
217 | bullet_radius : TD3DValue; longshot : boolean): boolean; |
||
218 | function coll_test_sphere(coll_nr : byte; |
||
219 | old_attacker_position, |
||
220 | attacker_position : TD3DVector; |
||
221 | bullet_radius : TD3Dvalue; longshot : boolean): boolean; |
||
222 | function coll_test_ellipsoid(coll_nr : byte; |
||
223 | old_attacker_position, attacker_position : TD3DVector; |
||
224 | bullet_radius : TD3DValue; longshot : boolean): boolean; |
||
225 | function coll_test_conus(coll_nr : byte; |
||
226 | old_attacker_position, attacker_position : TD3DVector; |
||
227 | bullet_radius : TD3DValue; longshot : boolean): boolean; |
||
228 | |||
229 | protected |
||
230 | |||
231 | public |
||
232 | Constructor Create(AOwner : TComponent); override; |
||
233 | destructor Destroy; override; |
||
234 | |||
235 | property DXDrawUsed : TDXDraw write FDXDrawUsed stored false; |
||
236 | property FrameSeries : TFrames3D write FFrameSeries stored false; |
||
237 | property NextAddMesh : IDirect3DRMMesh write FNextAddMesh stored false; |
||
238 | property BulletFrame : IDirect3DRMFrame write FBulletFrame stored false; |
||
239 | |||
240 | procedure ZeroSetIt; |
||
241 | procedure BoxPartMin(xval, yval, zval: TD3DValue); |
||
242 | procedure BoxPartMax(xval, yval, zval: TD3DValue); |
||
243 | procedure GetOldBulletPos; |
||
244 | procedure GetOldEyePos; |
||
245 | |||
246 | function HitLinkNr: integer; |
||
247 | function DestroyCollisionObject: boolean; |
||
248 | procedure AddCollisionObject; |
||
249 | function Collision: boolean; |
||
250 | function Bulletcollision: boolean; |
||
251 | function BulletDead : boolean; |
||
252 | |||
253 | |||
254 | published |
||
255 | |||
256 | property BulletRadius : Integer read FBulletRadius write SetBulletRadius |
||
257 | default 0; |
||
258 | property BulletRange : Integer read FbulletRange write SetBulletRange |
||
259 | Default 100; |
||
260 | property CollisionCheckAll: Boolean read FCheckAllCollObj |
||
261 | write FCheckAllCollObj Default true; |
||
262 | property CollOrientation : TOrientation3D read FOrientation3D |
||
263 | write SetOrientation3D default symmetric_y; |
||
264 | property CollObjectType : Tshapes3D read Fshape3D write SetShape3D |
||
265 | default box3D; |
||
266 | property CollObjMaterial : Tmaterials3D read Fmaterial3D write SetMaterial3D |
||
267 | default solid3D; |
||
268 | property CoverWholeMesh : boolean read FNextAllOfMesh |
||
269 | write FNextAllOfMesh default true; |
||
270 | Property Fixed3DObject : boolean read FFixed3DObject |
||
271 | write FFixed3DObject default true; |
||
272 | property FrontDistance : Integer read FFrontDistance |
||
273 | write SetFrontDistance default 0; |
||
274 | property HeadRadius : integer read FHeadRadius write SetHeadRadius |
||
275 | default 0; |
||
276 | property IndexOf3DSeries : integer read FSeriesIndex |
||
277 | write SetIndexOf3DSeries default 0; |
||
278 | property IndexOf3DObject : integer read FIndexOf3DObject |
||
279 | write SetIndexOf3DObject default 0; |
||
280 | property IndexOf3DElement : integer read FIndexOf3DElement |
||
281 | write SetIndexOf3DElement default 0; |
||
282 | property NextDestroyNr : Integer read FNextDestroyNr |
||
283 | write SetNextDestroyNr default 0; |
||
284 | Property PercentLeftAtTop : integer read FPercentLeftAtTop |
||
285 | write SetPercentLeftAtTop default 0; |
||
286 | Property Pickable : Boolean read FPickable write FPickable |
||
287 | default false; |
||
288 | Property Shootable : boolean read FShootable write FShootable |
||
289 | Default false; |
||
290 | Property LongShots : boolean read FLongShots write FLongShots |
||
291 | Default false; |
||
292 | |||
293 | |||
294 | end; //end of Class |
||
295 | |||
296 | |||
297 | |||
298 | //Registering of the Component |
||
299 | Procedure Register; |
||
300 | |||
301 | |||
302 | implementation |
||
303 | |||
304 | |||
305 | |||
306 | procedure Register; |
||
307 | begin |
||
308 | //Register the component together with the DelphiX components from Hori |
||
309 | RegisterComponents('DelphiX', [TCollisionTester3DX]); |
||
310 | end; //end of Register |
||
311 | |||
312 | |||
313 | constructor TCollisionTester3DX.Create(AOwner : TComponent); |
||
314 | begin |
||
315 | inherited Create(AOwner); |
||
316 | //The constructor always clears the storage it allocates for a new object |
||
317 | //Hence there is no need to initialize fields except to nonzero or nonempty |
||
318 | //values |
||
319 | FDXDrawUsed := nil; |
||
320 | FFrameSeries := nil; |
||
321 | FNextAddMesh := nil; |
||
322 | FBulletFrame := nil; |
||
323 | |||
324 | FOrientation3D := symmetric_y; |
||
325 | FShape3D := box3D; |
||
326 | FMaterial3D := solid3D; |
||
327 | FBulletRange := 100; |
||
328 | FNrOfSeries := 0; |
||
329 | setlength(FSeriesIndex_for_SeriesNr, 0); |
||
330 | setlength(FColl_nr_objects, 0); |
||
331 | setlength(FNrinFrameSeries, 0); |
||
332 | setlength(Fcoll_shape, 0); |
||
333 | setlength(Fcoll_box_min, 0); |
||
334 | setlength(Fcoll_box_max, 0); |
||
335 | setlength(Fcoll_radius, 0); |
||
336 | setlength(Fcoll_frac_at_top, 0); |
||
337 | setlength(Fcoll_objectnr, 0); |
||
338 | setlength(Fcoll_shootable, 0); |
||
339 | setlength(Fcoll_pickable, 0); |
||
340 | setlength(Fcoll_orientation, 0); |
||
341 | setlength(Fcoll_material, 0); |
||
342 | setlength(Fcoll_Fixed3D, 0); |
||
343 | |||
344 | end; //end of creation |
||
345 | |||
346 | |||
347 | |||
348 | |||
349 | |||
350 | |||
351 | |||
352 | destructor TCollisionTester3DX.Destroy; |
||
353 | begin |
||
354 | //destroy any embedded objects and free resources allocated by the objects |
||
355 | FnrinFrameSeries := nil; |
||
356 | Fcoll_shape := nil; |
||
357 | Fcoll_box_min := nil; |
||
358 | Fcoll_box_max := nil; |
||
359 | Fcoll_radius := nil; |
||
360 | Fcoll_frac_at_top := nil; |
||
361 | Fcoll_objectnr := nil; |
||
362 | Fcoll_shootable := nil; |
||
363 | Fcoll_pickable := nil; |
||
364 | Fcoll_orientation := nil; |
||
365 | Fcoll_material := nil; |
||
366 | Fcoll_Fixed3D := nil; |
||
367 | FSeriesIndex_for_SeriesNr := nil; |
||
368 | Fcoll_nr_objects := nil; |
||
369 | |||
370 | inherited Destroy; |
||
371 | end; //end of Destroy |
||
372 | |||
373 | |||
374 | |||
375 | |||
376 | procedure TCollisionTester3DX.ZeroSetIt; |
||
377 | begin |
||
378 | //initialises the dynamic arrays |
||
379 | FnrinFrameSeries := nil; |
||
380 | Fcoll_shape := nil; |
||
381 | Fcoll_box_min := nil; |
||
382 | Fcoll_box_max := nil; |
||
383 | Fcoll_radius := nil; |
||
384 | Fcoll_frac_at_top := nil; |
||
385 | Fcoll_objectnr := nil; |
||
386 | Fcoll_shootable := nil; |
||
387 | Fcoll_pickable := nil; |
||
388 | Fcoll_orientation := nil; |
||
389 | Fcoll_material := nil; |
||
390 | Fcoll_Fixed3D := nil; |
||
391 | FSeriesIndex_for_SeriesNr := nil; |
||
392 | Fcoll_nr_objects := nil; |
||
393 | |||
394 | FDXDrawUsed := nil; |
||
395 | FFrameSeries := nil; |
||
396 | FNextAddMesh := nil; |
||
397 | FBulletFrame := nil; |
||
398 | |||
399 | FOrientation3D := symmetric_y; |
||
400 | FShape3D := box3D; |
||
401 | FMaterial3D := solid3D; |
||
402 | FBulletRange := 100; |
||
403 | FNrOfSeries := 0; |
||
404 | setlength(FSeriesIndex_for_SeriesNr, 0); |
||
405 | setlength(FColl_nr_objects, 0); |
||
406 | setlength(FNrinFrameSeries, 0); |
||
407 | setlength(Fcoll_shape, 0); |
||
408 | setlength(Fcoll_box_min, 0); |
||
409 | setlength(Fcoll_box_max, 0); |
||
410 | setlength(Fcoll_radius, 0); |
||
411 | setlength(Fcoll_frac_at_top, 0); |
||
412 | setlength(Fcoll_objectnr, 0); |
||
413 | setlength(Fcoll_shootable, 0); |
||
414 | setlength(Fcoll_pickable, 0); |
||
415 | setlength(Fcoll_orientation, 0); |
||
416 | setlength(Fcoll_material, 0); |
||
417 | setlength(Fcoll_Fixed3D, 0); |
||
418 | |||
419 | end; //end of ZeroSetIt |
||
420 | |||
421 | |||
422 | |||
423 | |||
424 | function TcollisionTester3DX.HitLinkNr: integer; |
||
425 | begin |
||
426 | result := Fbullet_hitlinknr; |
||
427 | end; //end of HitLinkNr |
||
428 | |||
429 | |||
430 | |||
431 | procedure TCollisionTester3DX.ListDataForCollObject; |
||
432 | var |
||
433 | Nr : integer; |
||
434 | begin |
||
435 | Nr := FBullet_HitLinkNr; |
||
436 | |||
437 | CollObjectType := Fcoll_shape[FSeriesNr, Nr]; |
||
438 | CollObjMaterial := Fcoll_material[FSeriesNr, Nr]; |
||
439 | Fixed3DObject := Fcoll_Fixed3D[FSeriesNr, Nr]; |
||
440 | CollOrientation := Fcoll_orientation[FSeriesNr, Nr]; |
||
441 | IndexOf3DObject := Fcoll_objectNr[FSeriesNr, Nr]; |
||
442 | IndexOf3DSeries := FSeriesIndex; |
||
443 | IndexOf3DElement := FNrinFrameSeries[FSeriesNr, Nr]; |
||
444 | Pickable := Fcoll_pickable[FSeriesNr, Nr]; |
||
445 | Shootable := Fcoll_shootable[FseriesNr, Nr]; |
||
446 | |||
447 | end; //end of ListDataForCollObject |
||
448 | |||
449 | |||
450 | |||
451 | |||
452 | procedure TcollisionTester3DX.SetPercentLeftAtTop(Value : Integer); |
||
453 | begin |
||
454 | //value can not be negative |
||
455 | if (FPercentLeftAtTop <> Value) and (Value >= 0) |
||
456 | then |
||
457 | FPercentLeftAtTop := value; |
||
458 | end; //end of SetPercentLeftAtTop |
||
459 | |||
460 | |||
461 | |||
462 | |||
463 | procedure TcollisionTester3DX.SetOrientation3D(Value : TOrientation3D); |
||
464 | begin |
||
465 | if FOrientation3D <> Value |
||
466 | then |
||
467 | FOrientation3D := Value; |
||
468 | end; //end setorientation3D |
||
469 | |||
470 | |||
471 | procedure TcollisionTester3DX.SetShape3D(Value : Tshapes3D); |
||
472 | begin |
||
473 | if Fshape3D <> Value |
||
474 | then |
||
475 | Fshape3D := Value; |
||
476 | end; //end setshapes3D |
||
477 | |||
478 | |||
479 | |||
480 | procedure TcollisionTester3DX.SetMaterial3D(Value : Tmaterials3D); |
||
481 | begin |
||
482 | if Fmaterial3D <> Value |
||
483 | then |
||
484 | Fmaterial3D := Value; |
||
485 | end; //end setshapes3D |
||
486 | |||
487 | |||
488 | |||
489 | procedure TCollisionTester3DX.SetIndexOf3DObject(Value : integer); |
||
490 | begin |
||
491 | //Index can not be negative |
||
492 | if (FIndexOf3DObject <> Value) and (Value >= 0) |
||
493 | then |
||
494 | FIndexOf3DObject := value; |
||
495 | end; //end setIndexOf3DObject |
||
496 | |||
497 | |||
498 | procedure TCollisionTester3DX.SetIndexOf3DElement(Value : integer); |
||
499 | begin |
||
500 | //Index can not be negative |
||
501 | if (FIndexOf3DElement <> Value) and (Value >= 0) |
||
502 | then |
||
503 | FIndexOf3DElement := value; |
||
504 | end; //end setIndexOf3DElement |
||
505 | |||
506 | |||
507 | |||
508 | procedure TCollisionTester3DX.SetIndexOf3DSeries(Value : integer); |
||
509 | begin |
||
510 | //Index can not be negative |
||
511 | if (FSeriesIndex <> Value) and (Value >= 0) |
||
512 | then |
||
513 | FSeriesIndex := value; |
||
514 | end; //end of SetIndexOf3DSeries |
||
515 | |||
516 | |||
517 | |||
518 | |||
519 | procedure TCollisionTester3DX.SetNextDestroyNr(Value : integer); |
||
520 | begin |
||
521 | //Index can not be negative |
||
522 | if (FNextDestroyNr <> Value) and (Value >= 0) |
||
523 | then |
||
524 | FNextDestroyNr := value; |
||
525 | end; //end of SetNextDestroyNr |
||
526 | |||
527 | |||
528 | |||
529 | |||
530 | procedure TCollisionTester3DX.SetBulletRadius(Value : Integer); |
||
531 | begin |
||
532 | //Radius can not be negative |
||
533 | if (FBulletRadius <> Value) and (Value >= 0) |
||
534 | then |
||
535 | FBulletRadius := value; |
||
536 | end; //end of SetBulletRadius |
||
537 | |||
538 | |||
539 | |||
540 | procedure TCollisionTester3DX.SetHeadRadius(Value : Integer); |
||
541 | begin |
||
542 | //Radius can not be negative |
||
543 | if (FHeadRadius <> Value) and (Value >= 0) |
||
544 | then |
||
545 | FHeadRadius := value; |
||
546 | end; //end of SetHeadRadius |
||
547 | |||
548 | |||
549 | |||
550 | |||
551 | procedure TCollisionTester3DX.SetFrontDistance(Value : Integer); |
||
552 | begin |
||
553 | //FrontDistance can not be negative |
||
554 | if (FFrontDistance <> Value) and (Value >= 0) |
||
555 | then |
||
556 | FFrontDistance := value; |
||
557 | end; //end of SetFrontDistance |
||
558 | |||
559 | |||
560 | |||
561 | |||
562 | procedure TCollisionTester3DX.SetBulletRange(Value : Integer); |
||
563 | begin |
||
564 | //BulletRange can not be negative |
||
565 | if (FBulletRange <> Value) and (Value >= 0) |
||
566 | then |
||
567 | FBulletRange := value; |
||
568 | end; //end of SetBulletRange |
||
569 | |||
570 | |||
571 | |||
572 | |||
573 | function TcollisionTester3DX.Add_Space_For_One_More: boolean; |
||
574 | var |
||
575 | NewNr : integer; |
||
576 | begin |
||
577 | //add space for one more element in the present series |
||
578 | |||
579 | //length of Fcoll_nr_objects and FSeries_nIndex_for_SeriesNr are unchanged |
||
580 | NewNr := Fcoll_nr_objects[FseriesNr] + 1; |
||
581 | |||
582 | result := true; |
||
583 | |||
584 | try |
||
585 | SetLength(FNrinFrameSeries[FSeriesNr], NewNr); |
||
586 | SetLength(Fcoll_shape[FSeriesNr], NewNr); |
||
587 | SetLength(Fcoll_box_min[FSeriesNr], NewNr); |
||
588 | SetLength(Fcoll_box_max[FSeriesNr], NewNr); |
||
589 | SetLength(Fcoll_radius[FSeriesNr], NewNr); |
||
590 | SetLength(Fcoll_frac_at_top[FSeriesNr], NewNr); |
||
591 | SetLength(Fcoll_objectnr[FSeriesNr], NewNr); |
||
592 | SetLength(Fcoll_shootable[FSeriesNr], NewNr); |
||
593 | SetLength(Fcoll_pickable[FSeriesNr], NewNr); |
||
594 | SetLength(Fcoll_orientation[FSeriesNr], NewNr); |
||
595 | SetLength(Fcoll_material[FSeriesNr], NewNr); |
||
596 | SetLength(Fcoll_Fixed3D[FSeriesNr], NewNr); |
||
597 | |||
598 | except |
||
599 | on EOutOfMemory do |
||
600 | begin |
||
601 | //There is not enough memory available. Free some memory |
||
602 | dec(NewNr); |
||
603 | |||
604 | copy(FNrinFrameSeries[FseriesNr], 0, NewNr); |
||
605 | copy(Fcoll_shape[FseriesNr], 0, NewNr); |
||
606 | copy(Fcoll_box_min[FSeriesNr], 0, NewNr); |
||
607 | copy(Fcoll_box_max[FSeriesNr], 0, NewNr); |
||
608 | copy(Fcoll_radius[FSeriesNr], 0, NewNr); |
||
609 | copy(Fcoll_frac_at_top[FSeriesNr], 0, NewNr); |
||
610 | copy(Fcoll_objectnr[FSeriesNr], 0, NewNr); |
||
611 | copy(Fcoll_shootable[FSeriesNr], 0, NewNr); |
||
612 | copy(Fcoll_pickable[FSeriesNr], 0, NewNr); |
||
613 | copy(Fcoll_orientation[FSeriesNr], 0, NewNr); |
||
614 | copy(Fcoll_material[FSeriesNr], 0, NewNr); |
||
615 | copy(Fcoll_Fixed3D[FSeriesNr], 0, NewNr); |
||
616 | |||
617 | result := false; |
||
618 | end; |
||
619 | end; |
||
620 | |||
621 | //update count of objects in series |
||
622 | Fcoll_nr_objects[FseriesNr] := NewNr; |
||
623 | |||
624 | end; //end of Add_Space_For_One_More |
||
625 | |||
626 | |||
627 | |||
628 | |||
629 | procedure TcollisionTester3DX.MakeNewSeries; |
||
630 | begin |
||
631 | inc(FNrOfSeries); |
||
632 | |||
633 | SetLength(FSeriesIndex_for_SeriesNr, FNrOfSeries); |
||
634 | FSeriesIndex_for_SeriesNr[FNrOfSeries-1] := FSeriesIndex; |
||
635 | |||
636 | SetLength(Fcoll_nr_objects, FNrOfSeries); |
||
637 | Fcoll_nr_objects[FNrOfSeries-1] := 0; |
||
638 | |||
639 | SetLength(FNrinFrameSeries, FNrOfSeries); |
||
640 | SetLength(Fcoll_shape, FNrOfSeries); |
||
641 | SetLength(Fcoll_box_min, FNrOfSeries); |
||
642 | SetLength(Fcoll_box_max, FNrOfSeries); |
||
643 | SetLength(Fcoll_radius, FNrOfSeries); |
||
644 | SetLength(Fcoll_frac_at_top, FNrOfSeries); |
||
645 | SetLength(Fcoll_objectnr, FNrOfSeries); |
||
646 | SetLength(Fcoll_shootable, FNrOfSeries); |
||
647 | SetLength(Fcoll_pickable, FNrOfSeries); |
||
648 | SetLength(Fcoll_orientation, FNrOfSeries); |
||
649 | SetLength(Fcoll_material, FNrOfSeries); |
||
650 | SetLength(Fcoll_Fixed3D, FNrOfSeries); |
||
651 | end; //end of MakeNewSeries |
||
652 | |||
653 | |||
654 | |||
655 | |||
656 | procedure TcollisionTester3DX.Destroy_Empty_Series(SeriesNr : integer); |
||
657 | var |
||
658 | i, j : integer; |
||
659 | begin |
||
660 | if seriesNr < (FNrOfSeries - 1) |
||
661 | then |
||
662 | begin |
||
663 | for i := SeriesNr to (FNrOfSeries - 2) do |
||
664 | begin |
||
665 | FSeriesIndex_for_SeriesNr[i] := FSeriesIndex_for_SeriesNr[i+1]; |
||
666 | |||
667 | SetLength(FNrinFrameSeries[i], Fcoll_Nr_objects[i+1]); |
||
668 | for j := 0 to (Fcoll_Nr_objects[i+1] - 1) do |
||
669 | FNrinFrameSeries[i, j] := FNrinFrameSeries[(i+1), j]; |
||
670 | |||
671 | SetLength(Fcoll_shape[i], Fcoll_Nr_objects[i+1]); |
||
672 | for j := 0 to (Fcoll_Nr_objects[i+1] - 1) do |
||
673 | Fcoll_shape[i, j] := Fcoll_shape[(i+1), j]; |
||
674 | |||
675 | SetLength(Fcoll_box_min[i], Fcoll_Nr_objects[i+1]); |
||
676 | for j := 0 to (Fcoll_Nr_objects[i+1] - 1) do |
||
677 | Fcoll_box_min[i, j] := Fcoll_box_min[(i+1), j]; |
||
678 | |||
679 | SetLength(Fcoll_box_max[i], Fcoll_Nr_objects[i+1]); |
||
680 | for j := 0 to (Fcoll_Nr_objects[i+1] - 1) do |
||
681 | Fcoll_box_max[i, j] := Fcoll_box_max[(i+1), j]; |
||
682 | |||
683 | SetLength(Fcoll_radius[i], Fcoll_Nr_objects[i+1]); |
||
684 | for j := 0 to (Fcoll_Nr_objects[i+1] - 1) do |
||
685 | Fcoll_radius[i, j] := Fcoll_radius[(i+1), j]; |
||
686 | |||
687 | SetLength(Fcoll_frac_at_top[i], Fcoll_Nr_objects[i+1]); |
||
688 | for j := 0 to (Fcoll_Nr_objects[i+1] - 1) do |
||
689 | Fcoll_frac_at_top[i, j] := Fcoll_frac_at_top[(i+1), j]; |
||
690 | |||
691 | SetLength(Fcoll_objectnr[i], Fcoll_Nr_objects[i+1]); |
||
692 | for j := 0 to (Fcoll_Nr_objects[i+1] - 1) do |
||
693 | Fcoll_objectNr[i, j] := Fcoll_objectNr[(i+1), j]; |
||
694 | |||
695 | SetLength(Fcoll_shootable[i], Fcoll_Nr_objects[i+1]); |
||
696 | for j := 0 to (Fcoll_Nr_objects[i+1] - 1) do |
||
697 | Fcoll_shootable[i, j] := Fcoll_shootable[(i+1), j]; |
||
698 | |||
699 | SetLength(Fcoll_pickable[i], Fcoll_Nr_objects[i+1]); |
||
700 | for j := 0 to (Fcoll_Nr_objects[i+1] - 1) do |
||
701 | Fcoll_pickable[i, j] := Fcoll_pickable[(i+1), j]; |
||
702 | |||
703 | SetLength(Fcoll_orientation[i], Fcoll_Nr_objects[i+1]); |
||
704 | for j := 0 to (Fcoll_Nr_objects[i+1] - 1) do |
||
705 | Fcoll_orientation[i, j] := Fcoll_orientation[(i+1), j]; |
||
706 | |||
707 | SetLength(Fcoll_material[i], Fcoll_Nr_objects[i+1]); |
||
708 | for j := 0 to (Fcoll_Nr_objects[i+1] - 1) do |
||
709 | Fcoll_material[i, j] := Fcoll_material[(i+1), j]; |
||
710 | |||
711 | SetLength(Fcoll_Fixed3D[i], Fcoll_Nr_objects[i+1]); |
||
712 | for j := 0 to (Fcoll_Nr_objects[i+1] - 1) do |
||
713 | Fcoll_Fixed3D[i, j] := Fcoll_Fixed3D[(i+1), j]; |
||
714 | |||
715 | Fcoll_nr_objects[i] := Fcoll_nr_objects[i+1]; |
||
716 | |||
717 | end; |
||
718 | end; |
||
719 | |||
720 | dec(FNrOfSeries); |
||
721 | |||
722 | FSeriesIndex_For_SeriesNr := copy(FSeriesIndex_for_SeriesNr, 0, FNrOfSeries); |
||
723 | Fcoll_Nr_Objects := copy(Fcoll_Nr_Objects, 0, FNrOfSeries); |
||
724 | FNrinFrameSeries := copy(FNrinFrameSeries, 0, FNrOfSeries); |
||
725 | Fcoll_Shape := copy(Fcoll_Shape, 0, FNrOfSeries); |
||
726 | Fcoll_Box_Min := copy(Fcoll_Box_Min, 0, FNrOfSeries); |
||
727 | Fcoll_Box_Max := copy(Fcoll_Box_Max, 0, FNrOfSeries); |
||
728 | Fcoll_Radius := copy(Fcoll_Radius, 0, FNrOfSeries); |
||
729 | Fcoll_Frac_At_Top := copy(Fcoll_Frac_At_Top, 0, FNrOfSeries); |
||
730 | Fcoll_ObjectNr := copy(Fcoll_ObjectNr, 0, FNrOfSeries); |
||
731 | Fcoll_Shootable := copy(Fcoll_Shootable, 0, FNrOfSeries); |
||
732 | Fcoll_Pickable := copy(Fcoll_Pickable, 0, FNrOfSeries); |
||
733 | Fcoll_orientation := copy(Fcoll_orientation, 0, FNrOfSeries); |
||
734 | Fcoll_Material := copy(Fcoll_Material, 0, FNrOfSeries); |
||
735 | Fcoll_Fixed3D := copy(Fcoll_Fixed3D, 0, FNrOfSeries); |
||
736 | end; //end of Destroy_Empty_Series |
||
737 | |||
738 | |||
739 | |||
740 | |||
741 | |||
742 | |||
743 | |||
744 | procedure TcollisionTester3DX.Remove_Collision_Object(SeriesNr, Value : integer); |
||
745 | var |
||
746 | i : integer; |
||
747 | begin |
||
748 | //Elements in the series which have a higher index than the one removed |
||
749 | //gets a smaller index which is correct when the main program removes the object |
||
750 | for i := 0 to (FColl_nr_objects[SeriesNr] - 1) do |
||
751 | begin |
||
752 | if FNrinFrameSeries[SeriesNr, i] >= value |
||
753 | then |
||
754 | dec(FNrinFrameSeries[SeriesNr, i]); |
||
755 | end; |
||
756 | |||
757 | for i := Value to (Fcoll_nr_objects[SeriesNr] - 2) do |
||
758 | begin |
||
759 | FNrinFrameSeries[SeriesNr, i] := FNrinFrameSeries[SeriesNr, (i+1)]; |
||
760 | Fcoll_shape[SeriesNr, i] := Fcoll_shape[SeriesNr, (i+1)]; |
||
761 | Fcoll_box_min[SeriesNr, i] := Fcoll_box_min[SeriesNr, (i+1)]; |
||
762 | Fcoll_box_max[SeriesNr, i] := Fcoll_box_max[SeriesNr, (i+1)]; |
||
763 | Fcoll_radius[seriesNr, i] := Fcoll_radius[SeriesNr, (i+1)]; |
||
764 | Fcoll_frac_at_top[SeriesNr, i] := Fcoll_frac_at_top[SeriesNr, (i+1)]; |
||
765 | Fcoll_objectnr[SeriesNr, i] := Fcoll_objectnr[SeriesNr, (i+1)]; |
||
766 | Fcoll_shootable[SeriesNr, i] := Fcoll_shootable[SeriesNr, (i+1)]; |
||
767 | Fcoll_Pickable[SeriesNr, i] := Fcoll_Pickable[SeriesNr, (i+1)]; |
||
768 | Fcoll_orientation[SeriesNr, i] := Fcoll_orientation[SeriesNr, (i+1)]; |
||
769 | Fcoll_material[SeriesNr, i] := Fcoll_material[SeriesNr, (i+1)]; |
||
770 | Fcoll_Fixed3D[SeriesNr, i] := Fcoll_Fixed3D[SeriesNr, (i+1)]; |
||
771 | end; |
||
772 | |||
773 | dec(Fcoll_nr_objects[SeriesNr]); |
||
774 | |||
775 | //remember to reduce the length of Fcoll_frame |
||
776 | FNrinFrameSeries[SeriesNr] := copy(FNrinFrameSeries[SeriesNr], 0, |
||
777 | Fcoll_nr_objects[SeriesNr]); |
||
778 | Fcoll_shape[SeriesNr] := copy(Fcoll_shape[SeriesNr], 0, |
||
779 | Fcoll_nr_objects[SeriesNr]); |
||
780 | Fcoll_box_min[SeriesNr] := copy(Fcoll_box_min[SeriesNr], 0, |
||
781 | Fcoll_nr_objects[SeriesNr]); |
||
782 | Fcoll_box_max[SeriesNr] := copy(Fcoll_box_max[SeriesNr], 0, |
||
783 | Fcoll_nr_objects[SeriesNr]); |
||
784 | Fcoll_radius[SeriesNr] := copy(Fcoll_radius[SeriesNr], 0, |
||
785 | Fcoll_nr_objects[SeriesNr]); |
||
786 | Fcoll_frac_at_top[SeriesNr] := copy(Fcoll_frac_at_top[SeriesNr], 0, |
||
787 | Fcoll_nr_objects[SeriesNr]); |
||
788 | Fcoll_objectnr[SeriesNr] := copy(Fcoll_objectnr[SeriesNr], 0, |
||
789 | Fcoll_nr_objects[SeriesNr]); |
||
790 | Fcoll_shootable[SeriesNr] := copy(Fcoll_shootable[SeriesNr], 0, |
||
791 | Fcoll_nr_objects[SeriesNr]); |
||
792 | Fcoll_pickable[SeriesNr] := copy(Fcoll_pickable[SeriesNr], 0, |
||
793 | Fcoll_nr_objects[SeriesNr]); |
||
794 | Fcoll_material[SeriesNr] := copy(Fcoll_material[SeriesNr], 0, |
||
795 | Fcoll_nr_objects[FSeriesNr]); |
||
796 | Fcoll_orientation[SeriesNr] := copy(Fcoll_orientation[SeriesNr], 0, |
||
797 | Fcoll_nr_objects[FSeriesNr]); |
||
798 | Fcoll_fixed3D[SeriesNr] := copy(Fcoll_fixed3D[SeriesNr], 0, |
||
799 | Fcoll_nr_objects[SeriesNr]); |
||
800 | |||
801 | end; //end of Remove_Collision_Object |
||
802 | |||
803 | |||
804 | |||
805 | |||
806 | |||
807 | |||
808 | |||
809 | procedure TCollisionTester3DX.GetTheBox; |
||
810 | var |
||
811 | box: TD3DRMBOX; |
||
812 | begin |
||
813 | if FNextAllOfMesh |
||
814 | then |
||
815 | begin |
||
816 | FNextAddMesh.GetBox(box); |
||
817 | FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := box.min; |
||
818 | FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := box.max; |
||
819 | end |
||
820 | else |
||
821 | begin |
||
822 | FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FBoxPartMin; |
||
823 | FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FBoxPartMax; |
||
824 | end; |
||
825 | |||
826 | end; //end of GetTheBox |
||
827 | |||
828 | |||
829 | |||
830 | procedure TCollisionTester3DX.BoxPartMin(xval, yval, zval : TD3DValue); |
||
831 | begin |
||
832 | FBoxPartMin.x := xval; |
||
833 | FBoxPartMin.y := yval; |
||
834 | FBoxPartMin.z := zval; |
||
835 | end; //end of BoxPartMin |
||
836 | |||
837 | |||
838 | |||
839 | |||
840 | procedure TCollisionTester3DX.BoxPartMax(xval, yval, zval : TD3DValue); |
||
841 | begin |
||
842 | FBoxPartMax.x := xval; |
||
843 | FBoxPartMax.y := yval; |
||
844 | FBoxPartMax.z := zval; |
||
845 | end; //end of BoxPartMax |
||
846 | |||
847 | |||
848 | |||
849 | |||
850 | |||
851 | procedure TCollisionTester3DX.AddBox; |
||
852 | begin |
||
853 | if add_space_for_one_more |
||
854 | then |
||
855 | begin |
||
856 | GetTheBox; |
||
857 | |||
858 | Fcoll_objectnr[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexOf3DObject; |
||
859 | Fcoll_shape[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := box3D; |
||
860 | FNrinFrameSeries[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexof3Delement; |
||
861 | Fcoll_radius[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := 0; //not used |
||
862 | Fcoll_frac_at_top[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := 0; //not used |
||
863 | Fcoll_material[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fmaterial3D; |
||
864 | Fcoll_orientation[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Forientation3D; |
||
865 | Fcoll_shootable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] -1)] := Fshootable; |
||
866 | Fcoll_Pickable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fpickable; |
||
867 | Fcoll_fixed3D[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FFixed3DObject; |
||
868 | end; |
||
869 | end; //end of AddBox |
||
870 | |||
871 | |||
872 | |||
873 | |||
874 | procedure TCollisionTester3DX.AddSphere; |
||
875 | begin |
||
876 | if add_space_for_one_more |
||
877 | then |
||
878 | begin |
||
879 | GetTheBox; |
||
880 | Fcoll_objectnr[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexOf3DObject; |
||
881 | Fcoll_shape[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := sphere3D; |
||
882 | FNrinFrameSeries[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexof3Delement; |
||
883 | Fcoll_radius[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := |
||
884 | (FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].x |
||
885 | - FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].x |
||
886 | + FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].y |
||
887 | - FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].y |
||
888 | + FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].z |
||
889 | - FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FseriesNr] - 1)].z)/2/3; |
||
890 | Fcoll_frac_at_top[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := 0; //not used |
||
891 | Fcoll_orientation[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Forientation3D; |
||
892 | Fcoll_material[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fmaterial3D; |
||
893 | Fcoll_shootable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fshootable; |
||
894 | Fcoll_Pickable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fpickable; |
||
895 | Fcoll_fixed3D[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FFixed3DObject; |
||
896 | end; |
||
897 | |||
898 | end; //end of AddSphere |
||
899 | |||
900 | |||
901 | |||
902 | |||
903 | |||
904 | procedure TCollisionTester3DX.Addcylinder; |
||
905 | begin |
||
906 | //the sphere cowers whole of the 3D-object |
||
907 | if add_space_for_one_more |
||
908 | then |
||
909 | begin |
||
910 | GetTheBox; |
||
911 | |||
912 | Fcoll_objectnr[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexOf3DObject; |
||
913 | Fcoll_shape[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := cylinder3D; |
||
914 | FNrinFrameSeries[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexof3Delement; |
||
915 | case Forientation3D of |
||
916 | symmetric_x : Fcoll_radius[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := |
||
917 | (FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].y |
||
918 | - FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FseriesNr] - 1)].y |
||
919 | + FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].z |
||
920 | - FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].z)/2/2; |
||
921 | symmetric_y : Fcoll_radius[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := |
||
922 | (FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].x |
||
923 | - FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FseriesNr] - 1)].x |
||
924 | + FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].z |
||
925 | - FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].z)/2/2; |
||
926 | symmetric_z : Fcoll_radius[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := |
||
927 | (FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].x |
||
928 | - FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FseriesNr] - 1)].x |
||
929 | + FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].y |
||
930 | - FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].y)/2/2; |
||
931 | end; |
||
932 | |||
933 | Fcoll_frac_at_top[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := 0; //not used |
||
934 | Fcoll_orientation[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Forientation3D; |
||
935 | Fcoll_material[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fmaterial3D; |
||
936 | Fcoll_shootable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fshootable; |
||
937 | Fcoll_Pickable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fpickable; |
||
938 | Fcoll_fixed3D[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FFixed3DObject; |
||
939 | end; |
||
940 | end; //end of Addcylinder |
||
941 | |||
942 | |||
943 | |||
944 | |||
945 | procedure TCollisionTester3DX.Addconus; |
||
946 | begin |
||
947 | //the conus cowers whole of or part of the 3D-object |
||
948 | //fraction_left_at_top = 0 if sharp tip |
||
949 | if add_space_for_one_more |
||
950 | then |
||
951 | begin |
||
952 | GettheBox; |
||
953 | |||
954 | Fcoll_objectnr[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexOf3DObject; |
||
955 | Fcoll_shape[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := conus3D; |
||
956 | FNrinFrameSeries[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexof3Delement; |
||
957 | Fcoll_radius[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := |
||
958 | (FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].x |
||
959 | - FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].x |
||
960 | + FColl_box_max[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].z |
||
961 | - FColl_box_min[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)].z)/2/2; |
||
962 | Fcoll_frac_at_top[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FPercentLeftAtTop/100; |
||
963 | Fcoll_orientation[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Forientation3D; |
||
964 | Fcoll_material[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fmaterial3D; |
||
965 | Fcoll_shootable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] -1)] := Fshootable; |
||
966 | Fcoll_Pickable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fpickable; |
||
967 | Fcoll_fixed3D[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FFixed3DObject; |
||
968 | end; |
||
969 | end; //end of Addconus |
||
970 | |||
971 | |||
972 | |||
973 | |||
974 | procedure TCollisionTester3DX.AddEllipsoid; |
||
975 | begin |
||
976 | if add_space_for_one_more |
||
977 | then |
||
978 | begin |
||
979 | GetTheBox; |
||
980 | Fcoll_objectnr[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexOf3DObject; |
||
981 | Fcoll_shape[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Ellipsoid3D; |
||
982 | FNrinFrameSeries[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FIndexof3Delement; |
||
983 | Fcoll_radius[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := 0; //not used |
||
984 | Fcoll_frac_at_top[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := 0; //not used |
||
985 | Fcoll_orientation[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Forientation3D; |
||
986 | Fcoll_material[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fmaterial3D; |
||
987 | Fcoll_shootable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fshootable; |
||
988 | Fcoll_Pickable[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := Fpickable; |
||
989 | Fcoll_fixed3D[FSeriesNr, (Fcoll_Nr_objects[FSeriesNr] - 1)] := FFixed3DObject; |
||
990 | end; |
||
991 | end; //end of AddEllipsoid |
||
992 | |||
993 | |||
994 | |||
995 | |||
996 | |||
997 | |||
998 | |||
999 | function TcollisionTester3DX.GetSeriesNr(Nr : integer): integer; |
||
1000 | var |
||
1001 | NrNow, i : integer; |
||
1002 | begin |
||
1003 | |||
1004 | if FNrOfSeries = 0 |
||
1005 | then |
||
1006 | NrNow := 0 |
||
1007 | else |
||
1008 | begin |
||
1009 | NrNow := -1; |
||
1010 | for i := 0 to (FNrOfSeries - 1) do |
||
1011 | begin |
||
1012 | if Nr = FSeriesIndex_for_SeriesNr[i] |
||
1013 | then |
||
1014 | NrNow := i; |
||
1015 | end; |
||
1016 | |||
1017 | if NrNow = -1 |
||
1018 | then |
||
1019 | NrNow := FNrOfSeries; //make new series |
||
1020 | end; |
||
1021 | |||
1022 | if NrNow = FNrOfSeries |
||
1023 | then |
||
1024 | MakeNewSeries; |
||
1025 | |||
1026 | |||
1027 | result := NrNow; |
||
1028 | |||
1029 | |||
1030 | end; //end of GetSeriesNr |
||
1031 | |||
1032 | |||
1033 | |||
1034 | |||
1035 | |||
1036 | function TcollisionTester3DX.CheckForSeriesIndex(indexnow : integer): boolean; |
||
1037 | var |
||
1038 | i : integer; |
||
1039 | begin |
||
1040 | |||
1041 | if FNrOfSeries = 0 |
||
1042 | then |
||
1043 | result := false |
||
1044 | else |
||
1045 | begin |
||
1046 | FSeriesNr := -1; |
||
1047 | for i := 0 to (FNrOfSeries - 1) do |
||
1048 | begin |
||
1049 | if indexnow = FSeriesIndex_for_SeriesNr[i] |
||
1050 | then |
||
1051 | FSeriesNr := i; |
||
1052 | end; |
||
1053 | |||
1054 | result := (FSeriesNr <> -1); |
||
1055 | end; |
||
1056 | |||
1057 | end; //end of CheckForSeriesIndex |
||
1058 | |||
1059 | |||
1060 | |||
1061 | |||
1062 | |||
1063 | procedure TcollisionTester3DX.AddCollisionObject; |
||
1064 | begin |
||
1065 | FSeriesNr := GetSeriesNr(FSeriesIndex); |
||
1066 | |||
1067 | case Fshape3D of |
||
1068 | box3D : AddBox; |
||
1069 | sphere3D : AddSphere; |
||
1070 | cylinder3D : AddCylinder; |
||
1071 | ellipsoid3D: AddEllipsoid; |
||
1072 | Conus3D : AddConus; |
||
1073 | end; |
||
1074 | |||
1075 | end; //end of AddCollisionObject |
||
1076 | |||
1077 | |||
1078 | |||
1079 | |||
1080 | |||
1081 | function TCollisionTester3DX.DestroyCollisionObject: boolean; |
||
1082 | var |
||
1083 | test_nr : integer; |
||
1084 | begin |
||
1085 | //remove all collision objects connected with the 3D-object |
||
1086 | //with the index FnextDestroyNr |
||
1087 | |||
1088 | //Check whether series index exists |
||
1089 | if CheckForSeriesIndex(FSeriesIndex) |
||
1090 | then |
||
1091 | begin |
||
1092 | //FSeriesNr was found |
||
1093 | test_nr := 0; |
||
1094 | |||
1095 | while (test_nr <= (Fcoll_nr_objects[FSeriesNr] - 1)) do |
||
1096 | begin |
||
1097 | if Fcoll_objectnr[FSeriesNr, test_nr] = FnextDestroyNr |
||
1098 | then |
||
1099 | remove_collision_object(FSeriesNr, FnextDestroyNr) |
||
1100 | else |
||
1101 | inc(test_nr); |
||
1102 | end; //end of while loop |
||
1103 | |||
1104 | //now we have to decrement all Fcoll_objectnr values larger than object_nr |
||
1105 | //because the main program does a similar decrementation when the 3D-object |
||
1106 | //is removed |
||
1107 | |||
1108 | if Fcoll_nr_objects[FSeriesNr] > 0 |
||
1109 | then |
||
1110 | begin |
||
1111 | //the series is not empty |
||
1112 | for test_nr := 0 to (Fcoll_nr_objects[FSeriesNr] - 1) do |
||
1113 | begin |
||
1114 | if Fcoll_objectnr[FSeriesNr, test_nr] > FNextDestroyNr |
||
1115 | then |
||
1116 | dec(Fcoll_objectnr[FSeriesNr, test_nr]); |
||
1117 | end; |
||
1118 | end |
||
1119 | else |
||
1120 | destroy_empty_Series(FSeriesNr); |
||
1121 | |||
1122 | |||
1123 | result := true; //collision object was destroyed |
||
1124 | |||
1125 | end //end of CheckForSeriesIndex... |
||
1126 | else |
||
1127 | result := false; //unable to destroy |
||
1128 | |||
1129 | end; //end of DestroyCollisionObject |
||
1130 | |||
1131 | |||
1132 | |||
1133 | |||
1134 | |||
1135 | |||
1136 | function TcollisionTester3DX.coll_test_sphere(coll_nr : byte; |
||
1137 | old_attacker_position, attacker_position : TD3DVector; |
||
1138 | bullet_radius : TD3DValue; longshot : boolean): boolean; |
||
1139 | var |
||
1140 | new_eye, old_eye : TD3DVector; |
||
1141 | dstep, step, center : TD3DVector; |
||
1142 | radius, d0, d1, d2, rod, rod2, t1, t2 : TD3DValue; |
||
1143 | begin |
||
1144 | result := false; |
||
1145 | |||
1146 | //Get the coordinates of the old eye_position in the actual coll frame |
||
1147 | FFrameSeries[FSeriesIndex, FNrinFrameSeries[FSeriesNr, coll_nr]].InverseTransform |
||
1148 | (old_eye, old_attacker_position); |
||
1149 | |||
1150 | //Get the coordinates of the eye_position in the actual coll frame |
||
1151 | FFrameSeries[FSeriesIndex, FNrinFrameSeries[FSeriesNr, coll_nr]].InverseTransform |
||
1152 | (new_eye, attacker_position); |
||
1153 | |||
1154 | center.x := (Fcoll_box_max[FSeriesNr, coll_nr].x |
||
1155 | + Fcoll_box_min[FSeriesNr, coll_nr].x)/2; |
||
1156 | center.y := (Fcoll_box_max[FSeriesNr, coll_nr].y |
||
1157 | + Fcoll_box_min[FSeriesNr, coll_nr].y)/2; |
||
1158 | center.z := (Fcoll_box_max[FSeriesNr, coll_nr].z |
||
1159 | + Fcoll_box_min[FSeriesNr, coll_nr].z)/2; |
||
1160 | |||
1161 | //radius of sphere enlarged with the radius of the bullet |
||
1162 | //to cover the space where a collision may occure |
||
1163 | radius := Fcoll_radius[FSeriesNr, coll_nr] + bullet_radius; |
||
1164 | |||
1165 | //eye to center distance |
||
1166 | dstep.x := old_eye.x - center.x; |
||
1167 | dstep.y := old_eye.y - center.y; |
||
1168 | dstep.z := old_eye.z - center.z; |
||
1169 | |||
1170 | //step in eye position |
||
1171 | step.x := new_eye.x - old_eye.x; |
||
1172 | step.y := new_eye.y - old_eye.y; |
||
1173 | step.z := new_eye.z - old_eye.z; |
||
1174 | |||
1175 | //collision is only possible when something moves |
||
1176 | if (abs(step.x) < 1e-3) and (abs(step.y) < 1e-3) and (abs(step.z) < 1e-3) |
||
1177 | then |
||
1178 | begin |
||
1179 | result := false; |
||
1180 | exit; |
||
1181 | end; |
||
1182 | |||
1183 | |||
1184 | //factors |
||
1185 | d0 := sqr(dstep.x) + sqr(dstep.y) + sqr(dstep.z) - sqr(radius); |
||
1186 | d1 := 2 * (step.x * dstep.x + step.y * dstep.y + step.z * dstep.z); |
||
1187 | d2 := sqr(step.x) + sqr(step.y) + sqr(step.z); |
||
1188 | |||
1189 | //solving an equation of the second degree |
||
1190 | rod := sqr(d1) - 4 * d2 * d0; |
||
1191 | |||
1192 | //d2 is never zero |
||
1193 | if rod > 0 |
||
1194 | then |
||
1195 | begin |
||
1196 | rod2 := sqrt(rod); |
||
1197 | t1 := (-d1 - rod2)/2/d2; |
||
1198 | t2 := (-d1 + rod2)/2/d2; |
||
1199 | |||
1200 | // if longshot then look into all future |
||
1201 | if longshot |
||
1202 | then |
||
1203 | result := (t1 >= 0) or (t2 >= 0) |
||
1204 | else |
||
1205 | begin |
||
1206 | //collision in between the starting and the ending point if |
||
1207 | result := ((t1 >= 0) and (t1 <= 1)) |
||
1208 | or ((t2 >= 0) and (t2 <= 1)); |
||
1209 | end; |
||
1210 | end; |
||
1211 | |||
1212 | end; //end of coll_test_sphere |
||
1213 | |||
1214 | |||
1215 | |||
1216 | |||
1217 | function TcollisionTester3DX.coll_test_ellipsoid(coll_nr : byte; |
||
1218 | old_attacker_position, attacker_position : TD3DVector; |
||
1219 | bullet_radius : TD3DValue; longshot : boolean): boolean; |
||
1220 | var |
||
1221 | new_eye, old_eye : TD3DVector; |
||
1222 | dstep, step, center : TD3DVector; |
||
1223 | d0, d1, d2, rod, rod2, t1, t2, a, b, c : TD3DValue; |
||
1224 | begin |
||
1225 | result := false; |
||
1226 | |||
1227 | //Get the coordinates of the old eye_position in the actual coll frame |
||
1228 | FFrameSeries[FSeriesIndex, FNrinFrameSeries[FSeriesNr, coll_nr]].InverseTransform |
||
1229 | (old_eye, old_attacker_position); |
||
1230 | |||
1231 | //Get the coordinates of the eye_position in the actual coll frame |
||
1232 | FFrameSeries[FSeriesIndex, FNrinFrameSeries[FSeriesNr, coll_nr]].InverseTransform |
||
1233 | (new_eye, attacker_position); |
||
1234 | |||
1235 | center.x := (Fcoll_box_max[FSeriesNr, coll_nr].x |
||
1236 | + Fcoll_box_min[FSeriesNr, coll_nr].x)/2; |
||
1237 | center.y := (Fcoll_box_max[FSeriesNr, coll_nr].y |
||
1238 | + Fcoll_box_min[FSeriesNr, coll_nr].y)/2; |
||
1239 | center.z := (Fcoll_box_max[FSeriesNr, coll_nr].z |
||
1240 | + Fcoll_box_min[FSeriesNr, coll_nr].z)/2; |
||
1241 | |||
1242 | //x, y and z radius of ellipsoid enlarged with the radius of the bullet |
||
1243 | //to cover the space where a collision may occure |
||
1244 | a := (Fcoll_box_max[FSeriesNr, coll_nr].x |
||
1245 | - Fcoll_box_min[FSeriesNr, coll_nr].x)/2 + bullet_radius; |
||
1246 | b := (Fcoll_box_max[FSeriesNr, coll_nr].y |
||
1247 | - Fcoll_box_min[FSeriesNr, coll_nr].y)/2 + bullet_radius; |
||
1248 | c := (Fcoll_box_max[FSeriesNr, coll_nr].z |
||
1249 | - Fcoll_box_min[FSeriesNr, coll_nr].z)/2 + bullet_radius; |
||
1250 | |||
1251 | //eye to center distance |
||
1252 | dstep.x := old_eye.x - center.x; |
||
1253 | dstep.y := old_eye.y - center.y; |
||
1254 | dstep.z := old_eye.z - center.z; |
||
1255 | |||
1256 | //step in eye position |
||
1257 | step.x := new_eye.x - old_eye.x; |
||
1258 | step.y := new_eye.y - old_eye.y; |
||
1259 | step.z := new_eye.z - old_eye.z; |
||
1260 | |||
1261 | //collision is only possible when something moves |
||
1262 | if (abs(step.x) < 1e-3) and (abs(step.y) < 1e-3) and (abs(step.z) < 1e-3) |
||
1263 | then |
||
1264 | begin |
||
1265 | result := false; |
||
1266 | exit; |
||
1267 | end; |
||
1268 | |||
1269 | |||
1270 | //factors |
||
1271 | d0 := sqr(b * c * dstep.x) + sqr(a * c * dstep.y) + sqr(a * b * dstep.z) |
||
1272 | - sqr(a * b * c); |
||
1273 | d1 := 2 * (sqr(b * c) * step.x * dstep.x + sqr(a * c) * step.y * dstep.y |
||
1274 | + sqr(a * b) * step.z * dstep.z); |
||
1275 | d2 := sqr(b * c * step.x) + sqr(a * c * step.y) + sqr(a * b * step.z); |
||
1276 | |||
1277 | //solving an equation of the second degree |
||
1278 | rod := sqr(d1) - 4 * d2 * d0; |
||
1279 | |||
1280 | //d2 is never zero |
||
1281 | if rod > 0 |
||
1282 | then |
||
1283 | begin |
||
1284 | rod2 := sqrt(rod); |
||
1285 | t1 := (-d1 - rod2)/2/d2; |
||
1286 | t2 := (-d1 + rod2)/2/d2; |
||
1287 | |||
1288 | // if longshot then look into all future |
||
1289 | if longshot |
||
1290 | then |
||
1291 | result := (t1 >= 0) or (t2 >= 0) |
||
1292 | else |
||
1293 | begin |
||
1294 | //collision in between the starting and the ending point if |
||
1295 | result := ((t1 >= 0) and (t1 <= 1)) |
||
1296 | or ((t2 >= 0) and (t2 <= 1)); |
||
1297 | end; |
||
1298 | end; |
||
1299 | |||
1300 | end; //end of coll_test_ellipsoid |
||
1301 | |||
1302 | |||
1303 | |||
1304 | |||
1305 | |||
1306 | function TcollisionTester3DX.coll_test_cylinder(coll_nr : byte; |
||
1307 | old_attacker_position, attacker_position : TD3DVector; |
||
1308 | bullet_radius : TD3DValue; longshot : boolean): boolean; |
||
1309 | var |
||
1310 | distance : TD3DValue; |
||
1311 | new_eye, old_eye : TD3DVector; |
||
1312 | dstep, step, center : TD3DVector; |
||
1313 | radius, d0, d1, d2, rod, rod2, t1, t2, xc1, yc1, zc1, xc2, yc2, zc2 : TD3DValue; |
||
1314 | begin |
||
1315 | result := false; |
||
1316 | |||
1317 | |||
1318 | //Get the coordinates of the old eye_position in the actual coll frame |
||
1319 | FFrameSeries[FSeriesIndex, FNrinFrameSeries[FSeriesNr, coll_nr]].InverseTransform |
||
1320 | (old_eye, old_attacker_position); |
||
1321 | |||
1322 | //Get the coordinates of the eye_position in the actual coll frame |
||
1323 | FFrameSeries[FSeriesIndex, FNrinFrameSeries[FSeriesNr, coll_nr]].InverseTransform |
||
1324 | (new_eye, attacker_position); |
||
1325 | |||
1326 | center.x := (Fcoll_box_max[FSeriesNr, coll_nr].x |
||
1327 | + Fcoll_box_min[FSeriesNr, coll_nr].x)/2; |
||
1328 | center.y := (Fcoll_box_max[FSeriesNr, coll_nr].y |
||
1329 | + Fcoll_box_min[FSeriesNr, coll_nr].y)/2; |
||
1330 | center.z := (Fcoll_box_max[FSeriesNr, coll_nr].z |
||
1331 | + Fcoll_box_min[FSeriesNr, coll_nr].z)/2; |
||
1332 | |||
1333 | //radius of sphere enlarged with the radius of the bullet |
||
1334 | //to cover the space where a collision may occure |
||
1335 | radius := Fcoll_radius[FSeriesNr, coll_nr] + bullet_radius; |
||
1336 | |||
1337 | //eye to center distance |
||
1338 | dstep.x := old_eye.x - center.x; |
||
1339 | dstep.y := old_eye.y - center.y; |
||
1340 | dstep.z := old_eye.z - center.z; |
||
1341 | |||
1342 | //step in eye position |
||
1343 | step.x := new_eye.x - old_eye.x; |
||
1344 | step.y := new_eye.y - old_eye.y; |
||
1345 | step.z := new_eye.z - old_eye.z; |
||
1346 | |||
1347 | //collision is only possible when something moves |
||
1348 | if (abs(step.x) < 1e-3) and (abs(step.y) < 1e-3) and (abs(step.z) < 1e-3) |
||
1349 | then |
||
1350 | begin |
||
1351 | result := false; |
||
1352 | exit; |
||
1353 | end; |
||
1354 | |||
1355 | d0 := 1; //just to avoid warnings |
||
1356 | d1 := 1; |
||
1357 | d2 := 1; |
||
1358 | |||
1359 | |||
1360 | //The cylinder is alined parallel to the x, y or z axis |
||
1361 | case FOrientation3D of |
||
1362 | symmetric_x : |
||
1363 | begin |
||
1364 | //factors |
||
1365 | d0 := sqr(dstep.y) + sqr(dstep.z) - sqr(radius); |
||
1366 | d1 := 2 * (step.y * dstep.y + step.z * dstep.z); |
||
1367 | d2 := sqr(step.y) + sqr(step.z); |
||
1368 | end; |
||
1369 | symmetric_y : |
||
1370 | begin |
||
1371 | //factors |
||
1372 | d0 := sqr(dstep.x) + sqr(dstep.z) - sqr(radius); |
||
1373 | d1 := 2 * (step.x * dstep.x + step.z * dstep.z); |
||
1374 | d2 := sqr(step.x) + sqr(step.z); |
||
1375 | end; |
||
1376 | symmetric_z : |
||
1377 | begin |
||
1378 | //factors |
||
1379 | d0 := sqr(dstep.x) + sqr(dstep.y) - sqr(radius); |
||
1380 | d1 := 2 * (step.x * dstep.x + step.y * dstep.y); |
||
1381 | d2 := sqr(step.x) + sqr(step.y); |
||
1382 | end; |
||
1383 | end; //end of case FOrientation3D of |
||
1384 | |||
1385 | |||
1386 | //solving an equation of the second degree |
||
1387 | rod := sqr(d1) - 4 * d2 * d0; |
||
1388 | |||
1389 | //d2 is never zero |
||
1390 | if rod >= 0 |
||
1391 | then |
||
1392 | begin |
||
1393 | //only then is the collision possible |
||
1394 | rod2 := sqrt(rod); |
||
1395 | t1 := (-d1 - rod2)/2/d2; |
||
1396 | t2 := (-d1 + rod2)/2/d2; |
||
1397 | |||
1398 | // if longshot then look into all future |
||
1399 | if longshot |
||
1400 | then |
||
1401 | result := (t1 >= 0) or (t2 >= 0) |
||
1402 | else |
||
1403 | begin |
||
1404 | //collision in between the starting and the ending point if |
||
1405 | result := ((t1 >= 0) and (t1 <= 1)) |
||
1406 | or ((t2 >= 0) and (t2 <= 1)); |
||
1407 | end; |
||
1408 | |||
1409 | // however the collision also affords that we are within the length of the cylinder |
||
1410 | if result then |
||
1411 | begin |
||
1412 | case FOrientation3D of |
||
1413 | symmetric_x : |
||
1414 | begin |
||
1415 | xc1 := old_eye.x + t1 * step.x; |
||
1416 | xc2 := old_eye.x + t2 * step.x; |
||
1417 | |||
1418 | |||
1419 | if longshot |
||
1420 | then |
||
1421 | result := |
||
1422 | (result and (t1 >= 0) and |
||
1423 | (xc1 >= (Fcoll_box_min[FseriesNr, coll_nr].x - bullet_radius)) and |
||
1424 | (xc1 <= (Fcoll_box_max[FseriesNr, coll_nr].x + bullet_radius)) ) |
||
1425 | or |
||
1426 | (result and (t2 >= 0) and |
||
1427 | (xc2 >= (Fcoll_box_min[FseriesNr, coll_nr].x - bullet_radius)) and |
||
1428 | (xc2 <= (Fcoll_box_max[FseriesNr, coll_nr].x + bullet_radius)) ) |
||
1429 | else |
||
1430 | result := |
||
1431 | (result and (t1 >= 0) and (t1 <= 1) and |
||
1432 | (xc1 >= (Fcoll_box_min[FseriesNr, coll_nr].x - bullet_radius)) and |
||
1433 | (xc1 <= (Fcoll_box_max[FseriesNr, coll_nr].x + bullet_radius)) ) |
||
1434 | or |
||
1435 | (result and (t2 >= 0) and (t2 <= 1) and |
||
1436 | (xc2 >= (Fcoll_box_min[FseriesNr, coll_nr].x - bullet_radius)) and |
||
1437 | (xc2 <= (Fcoll_box_max[FseriesNr, coll_nr].x + bullet_radius)) ); |
||
1438 | |||
1439 | //if collision detected then exit now |
||
1440 | if result then exit; |
||
1441 | |||
1442 | end; |
||
1443 | symmetric_y : |
||
1444 | begin |
||
1445 | yc1 := old_eye.y + t1 * step.y; |
||
1446 | yc2 := old_eye.y + t2 * step.y; |
||
1447 | |||
1448 | |||
1449 | if longshot |
||
1450 | then |
||
1451 | result := |
||
1452 | (result and (t1 >= 0) and |
||
1453 | (yc1 >= (Fcoll_box_min[FseriesNr, coll_nr].y - bullet_radius)) and |
||
1454 | (yc1 <= (Fcoll_box_max[FseriesNr, coll_nr].y + bullet_radius)) ) |
||
1455 | or |
||
1456 | (result and (t2 >= 0) and |
||
1457 | (yc2 >= (Fcoll_box_min[FseriesNr, coll_nr].y - bullet_radius)) and |
||
1458 | (yc2 <= (Fcoll_box_max[FseriesNr, coll_nr].y + bullet_radius)) ) |
||
1459 | else |
||
1460 | result := |
||
1461 | (result and (t1 >= 0) and (t1 <= 1) and |
||
1462 | (yc1 >= (Fcoll_box_min[FseriesNr, coll_nr].y - bullet_radius)) and |
||
1463 | (yc1 <= (Fcoll_box_max[FseriesNr, coll_nr].y + bullet_radius)) ) |
||
1464 | or |
||
1465 | (result and (t2 >= 0) and (t2 <= 1) and |
||
1466 | (yc2 >= (Fcoll_box_min[FseriesNr, coll_nr].y - bullet_radius)) and |
||
1467 | (yc2 <= (Fcoll_box_max[FseriesNr, coll_nr].y + bullet_radius)) ); |
||
1468 | |||
1469 | //if collision detected then exit now |
||
1470 | if result then exit; |
||
1471 | |||
1472 | |||
1473 | end; |
||
1474 | symmetric_z : |
||
1475 | begin |
||
1476 | zc1 := old_eye.z + t1 * step.z; |
||
1477 | zc2 := old_eye.z + t2 * step.z; |
||
1478 | |||
1479 | |||
1480 | if longshot |
||
1481 | then |
||
1482 | result := |
||
1483 | (result and (t1 >= 0) and |
||
1484 | (zc1 >= (Fcoll_box_min[FseriesNr, coll_nr].z - bullet_radius)) and |
||
1485 | (zc1 <= (Fcoll_box_max[FseriesNr, coll_nr].z + bullet_radius)) ) |
||
1486 | or |
||
1487 | (result and (t2 >= 0) and |
||
1488 | (zc2 >= (Fcoll_box_min[FseriesNr, coll_nr].z - bullet_radius)) and |
||
1489 | (zc2 <= (Fcoll_box_max[FseriesNr, coll_nr].z + bullet_radius)) ) |
||
1490 | else |
||
1491 | result := |
||
1492 | (result and (t1 >= 0) and (t1 <= 1) and |
||
1493 | (zc1 >= (Fcoll_box_min[FseriesNr, coll_nr].z - bullet_radius)) and |
||
1494 | (zc1 <= (Fcoll_box_max[FseriesNr, coll_nr].z + bullet_radius)) ) |
||
1495 | or |
||
1496 | (result and (t2 >= 0) and (t2 <= 1) and |
||
1497 | (zc2 >= (Fcoll_box_min[FseriesNr, coll_nr].z - bullet_radius)) and |
||
1498 | (zc2 <= (Fcoll_box_max[FseriesNr, coll_nr].z + bullet_radius)) ); |
||
1499 | |||
1500 | //if collision detected then exit now |
||
1501 | if result then exit; |
||
1502 | end; |
||
1503 | |||
1504 | end; //end of case |
||
1505 | end; |
||
1506 | |||
1507 | //exit if a collision occured |
||
1508 | if result then exit; |
||
1509 | end; |
||
1510 | |||
1511 | |||
1512 | //the collision may also occur with the end surfaces of the cylinder |
||
1513 | case FOrientation3D of |
||
1514 | symmetric_x : |
||
1515 | begin |
||
1516 | if step.x > 1e-6 |
||
1517 | then |
||
1518 | begin |
||
1519 | //1st end surface |
||
1520 | t1 := (Fcoll_box_min[FseriesNr, coll_Nr].x - old_eye.x)/step.x; |
||
1521 | yc1 := old_eye.y + t1 * step.y; |
||
1522 | zc1 := old_eye.z + t1 * step.z; |
||
1523 | |||
1524 | distance := sqrt( sqr(yc1 - center.y) + sqr(zc1 - center.z) ); |
||
1525 | |||
1526 | result := (distance < radius) and (t1 >= 0); |
||
1527 | if not longshot then result := result and (t1 <= 1); |
||
1528 | if result then exit; |
||
1529 | |||
1530 | //2nd end surface |
||
1531 | t1 := (Fcoll_box_max[FseriesNr, coll_Nr].x - old_eye.x)/step.x; |
||
1532 | yc1 := old_eye.y + t1 * step.y; |
||
1533 | zc1 := old_eye.z + t1 * step.z; |
||
1534 | |||
1535 | distance := sqrt( sqr(yc1 - center.y) + sqr(zc1 - center.z) ); |
||
1536 | |||
1537 | result := (distance < radius) and (t1 >= 0); |
||
1538 | if not longshot then result := result and (t1 <= 1); |
||
1539 | if result then exit; |
||
1540 | end; |
||
1541 | end; |
||
1542 | symmetric_y : |
||
1543 | begin |
||
1544 | if step.y > 1e-6 |
||
1545 | then |
||
1546 | begin |
||
1547 | //1st end surface |
||
1548 | t1 := (Fcoll_box_min[FseriesNr, coll_Nr].y - old_eye.y)/step.y; |
||
1549 | xc1 := old_eye.x + t1 * step.x; |
||
1550 | zc1 := old_eye.z + t1 * step.z; |
||
1551 | |||
1552 | distance := sqrt( sqr(xc1 - center.x) + sqr(zc1 - center.z) ); |
||
1553 | |||
1554 | result := (distance < radius) and (t1 >= 0); |
||
1555 | if not longshot then result := result and (t1 <= 1); |
||
1556 | if result then exit; |
||
1557 | |||
1558 | //2nd end surface |
||
1559 | t1 := (Fcoll_box_max[FseriesNr, coll_Nr].y - old_eye.y)/step.y; |
||
1560 | xc1 := old_eye.x + t1 * step.x; |
||
1561 | zc1 := old_eye.z + t1 * step.z; |
||
1562 | |||
1563 | distance := sqrt( sqr(xc1 - center.x) + sqr(zc1 - center.z) ); |
||
1564 | |||
1565 | result := (distance < radius) and (t1 >= 0); |
||
1566 | if not longshot then result := result and (t1 <= 1); |
||
1567 | if result then exit; |
||
1568 | end; |
||
1569 | |||
1570 | end; |
||
1571 | symmetric_z : |
||
1572 | begin |
||
1573 | if step.z > 1e-6 |
||
1574 | then |
||
1575 | begin |
||
1576 | //1st end surface |
||
1577 | t1 := (Fcoll_box_min[FseriesNr, coll_Nr].z - old_eye.z)/step.z; |
||
1578 | xc1 := old_eye.x + t1 * step.x; |
||
1579 | yc1 := old_eye.y + t1 * step.y; |
||
1580 | |||
1581 | distance := sqrt( sqr(xc1 - center.x) + sqr(yc1 - center.y) ); |
||
1582 | |||
1583 | result := (distance < radius) and (t1 >= 0); |
||
1584 | if not longshot then result := result and (t1 <= 1); |
||
1585 | if result then exit; |
||
1586 | |||
1587 | //2nd end surface |
||
1588 | t1 := (Fcoll_box_max[FseriesNr, coll_Nr].z - old_eye.z)/step.z; |
||
1589 | xc1 := old_eye.x + t1 * step.x; |
||
1590 | yc1 := old_eye.y + t1 * step.y; |
||
1591 | |||
1592 | distance := sqrt( sqr(xc1 - center.x) + sqr(yc1 - center.y) ); |
||
1593 | |||
1594 | result := (distance < radius) and (t1 >= 0); |
||
1595 | if not longshot then result := result and (t1 <= 1); |
||
1596 | if result then exit; |
||
1597 | end; |
||
1598 | |||
1599 | end; |
||
1600 | |||
1601 | |||
1602 | end; //end of case |
||
1603 | |||
1604 | end; //end of coll_test_cylinder |
||
1605 | |||
1606 | |||
1607 | |||
1608 | |||
1609 | |||
1610 | function TcollisionTester3DX.coll_test_conus(coll_nr : byte; |
||
1611 | old_attacker_position, attacker_position : TD3DVector; |
||
1612 | bullet_radius : TD3DValue; longshot : boolean): boolean; |
||
1613 | var |
||
1614 | height3D, width3D : TD3DValue; |
||
1615 | distance : TD3DValue; |
||
1616 | new_eye, old_eye : TD3DVector; |
||
1617 | dstep, step, center : TD3DVector; |
||
1618 | radius, d0, d1, d2, rod, rod2, t1, t2, xc1, yc1, zc1, xc2, yc2, zc2 : TD3DValue; |
||
1619 | xc, yc, zc, conusfact : TD3DValue; |
||
1620 | begin |
||
1621 | result := false; |
||
1622 | |||
1623 | //Get the coordinates of the old eye_position in the actual coll frame |
||
1624 | FFrameSeries[FSeriesIndex, FNrinFrameSeries[FSeriesNr, coll_nr]].InverseTransform |
||
1625 | (old_eye, old_attacker_position); |
||
1626 | |||
1627 | //Get the coordinates of the eye_position in the actual coll frame |
||
1628 | FFrameSeries[FSeriesIndex, FNrinFrameSeries[FSeriesNr, coll_nr]].InverseTransform |
||
1629 | (new_eye, attacker_position); |
||
1630 | |||
1631 | center.x := (Fcoll_box_max[FSeriesNr, coll_nr].x |
||
1632 | + Fcoll_box_min[FSeriesNr, coll_nr].x)/2; |
||
1633 | center.y := (Fcoll_box_max[FSeriesNr, coll_nr].y |
||
1634 | + Fcoll_box_min[FSeriesNr, coll_nr].y)/2; |
||
1635 | center.z := (Fcoll_box_max[FSeriesNr, coll_nr].z |
||
1636 | + Fcoll_box_min[FSeriesNr, coll_nr].z)/2; |
||
1637 | |||
1638 | |||
1639 | //step in eye position |
||
1640 | step.x := new_eye.x - old_eye.x; |
||
1641 | step.y := new_eye.y - old_eye.y; |
||
1642 | step.z := new_eye.z - old_eye.z; |
||
1643 | |||
1644 | //collision is only possible when something moves |
||
1645 | if (abs(step.x) < 1e-3) and (abs(step.y) < 1e-3) and (abs(step.z) < 1e-3) |
||
1646 | then |
||
1647 | begin |
||
1648 | result := false; |
||
1649 | exit; |
||
1650 | end; |
||
1651 | |||
1652 | //if FPercentLeftatTop is positiv then the conus is largest at the bottom |
||
1653 | xc := center.x; |
||
1654 | yc := center.y; |
||
1655 | zc := center.z; |
||
1656 | |||
1657 | width3D := 10; //just to avoid warnings |
||
1658 | height3D := 10; |
||
1659 | |||
1660 | case FOrientation3D of |
||
1661 | symmetric_x : |
||
1662 | begin |
||
1663 | height3D := Fcoll_box_max[FSeriesNr, coll_nr].x |
||
1664 | - Fcoll_box_min[FSeriesNr, coll_nr].x; |
||
1665 | width3D := (Fcoll_box_max[FSeriesNr, coll_Nr].y |
||
1666 | - Fcoll_box_min[FSeriesNr, coll_nr].y |
||
1667 | + Fcoll_box_max[FSeriesNr, coll_nr].z |
||
1668 | - Fcoll_box_min[FSeriesNr, coll_nr].z)/2; |
||
1669 | |||
1670 | //the top of the conus is maller than the bottom of it |
||
1671 | if FPercentLeftatTop >= 0 |
||
1672 | then |
||
1673 | xc := center.x - height3D/2 + 100 * height3D/(100 - FpercentLeftatTop) |
||
1674 | else |
||
1675 | xc := center.x + height3D/2 - 100 * height3D/(100 + FpercentLeftatTop); |
||
1676 | end; //end of symmetric_x |
||
1677 | symmetric_y : |
||
1678 | begin |
||
1679 | height3D := Fcoll_box_max[FSeriesNr, coll_nr].y |
||
1680 | - Fcoll_box_min[FSeriesNr, coll_nr].y; |
||
1681 | width3D := (Fcoll_box_max[FSeriesNr, coll_Nr].x |
||
1682 | - Fcoll_box_min[FSeriesNr, coll_nr].x |
||
1683 | + Fcoll_box_max[FSeriesNr, coll_nr].z |
||
1684 | - Fcoll_box_min[FSeriesNr, coll_nr].z)/2; |
||
1685 | |||
1686 | //the top of the conus is maller than the bottom of it |
||
1687 | if FPercentLeftatTop >= 0 |
||
1688 | then |
||
1689 | yc := center.y - height3D/2 + 100 * height3D/(100 - FpercentLeftatTop) |
||
1690 | else |
||
1691 | yc := center.y + height3D/2 - 100 * height3D/(100 + FpercentLeftatTop); |
||
1692 | end; //end of symmetric_y |
||
1693 | symmetric_z : |
||
1694 | begin |
||
1695 | height3D := Fcoll_box_max[FSeriesNr, coll_nr].z |
||
1696 | - Fcoll_box_min[FSeriesNr, coll_nr].z; |
||
1697 | width3D := (Fcoll_box_max[FSeriesNr, coll_Nr].x |
||
1698 | - Fcoll_box_min[FSeriesNr, coll_nr].x |
||
1699 | + Fcoll_box_max[FSeriesNr, coll_nr].y |
||
1700 | - Fcoll_box_min[FSeriesNr, coll_nr].y)/2; |
||
1701 | |||
1702 | //the top of the conus is maller than the bottom of it |
||
1703 | if FPercentLeftatTop >= 0 |
||
1704 | then |
||
1705 | zc := center.z - height3D/2 + 100 * height3D/(100 - FpercentLeftatTop) |
||
1706 | else |
||
1707 | zc := center.z + height3D/2 - 100 * height3D/(100 + FpercentLeftatTop); |
||
1708 | end; //end of symmetric_z |
||
1709 | end; //end of case |
||
1710 | |||
1711 | //mathematically we need the conusfact describing the ratio between the radius of |
||
1712 | //the large end of the conus and the height of the conus |
||
1713 | if width3D > 0 |
||
1714 | then |
||
1715 | conusfact := height3D/2/width3D |
||
1716 | else |
||
1717 | conusfact := 1e9; |
||
1718 | |||
1719 | //eye to the fictive tip of the conus distance |
||
1720 | dstep.x := old_eye.x - xc; |
||
1721 | dstep.y := old_eye.y - yc; |
||
1722 | dstep.z := old_eye.z - zc; |
||
1723 | |||
1724 | d0 := 1; //just to avoid warnings |
||
1725 | d1 := 1; |
||
1726 | d2 := 1; |
||
1727 | |||
1728 | //The conus is aligned parallel to the x, y or z axis |
||
1729 | case FOrientation3D of |
||
1730 | symmetric_x : |
||
1731 | begin |
||
1732 | //factors |
||
1733 | d0 := sqr(dstep.y) + sqr(dstep.z) - sqr(dstep.x * conusfact); |
||
1734 | d1 := 2 * (step.y * dstep.y + step.z * dstep.z |
||
1735 | - sqr(conusfact) * step.x * dstep.x); |
||
1736 | d2 := sqr(step.y) + sqr(step.z) - sqr(conusfact * step.x); |
||
1737 | end; |
||
1738 | symmetric_y : |
||
1739 | begin |
||
1740 | //factors |
||
1741 | d0 := sqr(dstep.x) + sqr(dstep.z) - sqr(dstep.y * conusfact); |
||
1742 | d1 := 2 * (step.x * dstep.x + step.z * dstep.z |
||
1743 | - sqr(conusfact) * step.y * dstep.y); |
||
1744 | d2 := sqr(step.x) + sqr(step.z) - sqr(conusfact * step.y); |
||
1745 | end; |
||
1746 | symmetric_z : |
||
1747 | begin |
||
1748 | //factors |
||
1749 | d0 := sqr(dstep.x) + sqr(dstep.y) - sqr(dstep.z * conusfact); |
||
1750 | d1 := 2 * (step.x * dstep.x + step.y * dstep.y |
||
1751 | - sqr(conusfact) * step.z * dstep.z); |
||
1752 | d2 := sqr(step.x) + sqr(step.y) - sqr(conusfact * step.z); |
||
1753 | end; |
||
1754 | end; //end of case FOrientation3D of |
||
1755 | |||
1756 | |||
1757 | //solving an equation of the second degree |
||
1758 | rod := sqr(d1) - 4 * d2 * d0; |
||
1759 | |||
1760 | //d2 is never zero |
||
1761 | if rod >= 0 |
||
1762 | then |
||
1763 | begin |
||
1764 | //only then is the collision possible |
||
1765 | rod2 := sqrt(rod); |
||
1766 | t1 := (-d1 - rod2)/2/d2; |
||
1767 | t2 := (-d1 + rod2)/2/d2; |
||
1768 | |||
1769 | // if longshot then look into all future |
||
1770 | if longshot |
||
1771 | then |
||
1772 | result := (t1 >= 0) or (t2 >= 0) |
||
1773 | else |
||
1774 | begin |
||
1775 | //collision in between the starting and the ending point if |
||
1776 | result := ((t1 >= 0) and (t1 <= 1)) |
||
1777 | or ((t2 >= 0) and (t2 <= 1)); |
||
1778 | end; |
||
1779 | |||
1780 | // however the collision also affords that we are within the length of the conus |
||
1781 | if result then |
||
1782 | begin |
||
1783 | case FOrientation3D of |
||
1784 | symmetric_x : |
||
1785 | begin |
||
1786 | xc1 := old_eye.x + t1 * step.x; |
||
1787 | xc2 := old_eye.x + t2 * step.x; |
||
1788 | |||
1789 | |||
1790 | if longshot |
||
1791 | then |
||
1792 | result := |
||
1793 | (result and (t1 >= 0) and |
||
1794 | (xc1 >= (Fcoll_box_min[FseriesNr, coll_nr].x - bullet_radius)) and |
||
1795 | (xc1 <= (Fcoll_box_max[FseriesNr, coll_nr].x + bullet_radius)) ) |
||
1796 | or |
||
1797 | (result and (t2 >= 0) and |
||
1798 | (xc2 >= (Fcoll_box_min[FseriesNr, coll_nr].x - bullet_radius)) and |
||
1799 | (xc2 <= (Fcoll_box_max[FseriesNr, coll_nr].x + bullet_radius)) ) |
||
1800 | else |
||
1801 | result := |
||
1802 | (result and (t1 >= 0) and (t1 <= 1) and |
||
1803 | (xc1 >= (Fcoll_box_min[FseriesNr, coll_nr].x - bullet_radius)) and |
||
1804 | (xc1 <= (Fcoll_box_max[FseriesNr, coll_nr].x + bullet_radius)) ) |
||
1805 | or |
||
1806 | (result and (t2 >= 0) and (t2 <= 1) and |
||
1807 | (xc2 >= (Fcoll_box_min[FseriesNr, coll_nr].x - bullet_radius)) and |
||
1808 | (xc2 <= (Fcoll_box_max[FseriesNr, coll_nr].x + bullet_radius)) ); |
||
1809 | |||
1810 | //if collision detected then exit now |
||
1811 | if result then exit; |
||
1812 | |||
1813 | end; |
||
1814 | symmetric_y : |
||
1815 | begin |
||
1816 | yc1 := old_eye.y + t1 * step.y; |
||
1817 | yc2 := old_eye.y + t2 * step.y; |
||
1818 | |||
1819 | |||
1820 | if longshot |
||
1821 | then |
||
1822 | result := |
||
1823 | (result and (t1 >= 0) and |
||
1824 | (yc1 >= (Fcoll_box_min[FseriesNr, coll_nr].y - bullet_radius)) and |
||
1825 | (yc1 <= (Fcoll_box_max[FseriesNr, coll_nr].y + bullet_radius)) ) |
||
1826 | or |
||
1827 | (result and (t2 >= 0) and |
||
1828 | (yc2 >= (Fcoll_box_min[FseriesNr, coll_nr].y - bullet_radius)) and |
||
1829 | (yc2 <= (Fcoll_box_max[FseriesNr, coll_nr].y + bullet_radius)) ) |
||
1830 | else |
||
1831 | result := |
||
1832 | (result and (t1 >= 0) and (t1 <= 1) and |
||
1833 | (yc1 >= (Fcoll_box_min[FseriesNr, coll_nr].y - bullet_radius)) and |
||
1834 | (yc1 <= (Fcoll_box_max[FseriesNr, coll_nr].y + bullet_radius)) ) |
||
1835 | or |
||
1836 | (result and (t2 >= 0) and (t2 <= 1) and |
||
1837 | (yc2 >= (Fcoll_box_min[FseriesNr, coll_nr].y - bullet_radius)) and |
||
1838 | (yc2 <= (Fcoll_box_max[FseriesNr, coll_nr].y + bullet_radius)) ); |
||
1839 | |||
1840 | //if collision detected then exit now |
||
1841 | if result then exit; |
||
1842 | |||
1843 | |||
1844 | end; |
||
1845 | symmetric_z : |
||
1846 | begin |
||
1847 | zc1 := old_eye.z + t1 * step.z; |
||
1848 | zc2 := old_eye.z + t2 * step.z; |
||
1849 | |||
1850 | |||
1851 | if longshot |
||
1852 | then |
||
1853 | result := |
||
1854 | (result and (t1 >= 0) and |
||
1855 | (zc1 >= (Fcoll_box_min[FseriesNr, coll_nr].z - bullet_radius)) and |
||
1856 | (zc1 <= (Fcoll_box_max[FseriesNr, coll_nr].z + bullet_radius)) ) |
||
1857 | or |
||
1858 | (result and (t2 >= 0) and |
||
1859 | (zc2 >= (Fcoll_box_min[FseriesNr, coll_nr].z - bullet_radius)) and |
||
1860 | (zc2 <= (Fcoll_box_max[FseriesNr, coll_nr].z + bullet_radius)) ) |
||
1861 | else |
||
1862 | result := |
||
1863 | (result and (t1 >= 0) and (t1 <= 1) and |
||
1864 | (zc1 >= (Fcoll_box_min[FseriesNr, coll_nr].z - bullet_radius)) and |
||
1865 | (zc1 <= (Fcoll_box_max[FseriesNr, coll_nr].z + bullet_radius)) ) |
||
1866 | or |
||
1867 | (result and (t2 >= 0) and (t2 <= 1) and |
||
1868 | (zc2 >= (Fcoll_box_min[FseriesNr, coll_nr].z - bullet_radius)) and |
||
1869 | (zc2 <= (Fcoll_box_max[FseriesNr, coll_nr].z + bullet_radius)) ); |
||
1870 | |||
1871 | //if collision detected then exit now |
||
1872 | if result then exit; |
||
1873 | end; |
||
1874 | |||
1875 | end; //end of case |
||
1876 | end; |
||
1877 | |||
1878 | //exit if a collision occured |
||
1879 | if result then exit; |
||
1880 | end; |
||
1881 | |||
1882 | |||
1883 | //the collision may also occur with the end surfaces of the cylinder |
||
1884 | case FOrientation3D of |
||
1885 | symmetric_x : |
||
1886 | begin |
||
1887 | if step.x > 1e-6 |
||
1888 | then |
||
1889 | begin |
||
1890 | //1st end surface |
||
1891 | t1 := (Fcoll_box_min[FseriesNr, coll_Nr].x - old_eye.x)/step.x; |
||
1892 | yc1 := old_eye.y + t1 * step.y; |
||
1893 | zc1 := old_eye.z + t1 * step.z; |
||
1894 | |||
1895 | distance := sqrt( sqr(yc1 - center.y) + sqr(zc1 - center.z) ); |
||
1896 | |||
1897 | if FPercentLeftatTop >= 0 |
||
1898 | then |
||
1899 | radius := width3D/2 //the large end of the conus is down |
||
1900 | else |
||
1901 | radius := -width3D/2 * FPercentLeftatTop; |
||
1902 | |||
1903 | radius := radius + bullet_radius; |
||
1904 | |||
1905 | result := (distance < radius) and (t1 >= 0); |
||
1906 | if not longshot then result := result and (t1 <= 1); |
||
1907 | if result then exit; |
||
1908 | |||
1909 | //2nd end surface |
||
1910 | t1 := (Fcoll_box_max[FseriesNr, coll_Nr].x - old_eye.x)/step.x; |
||
1911 | yc1 := old_eye.y + t1 * step.y; |
||
1912 | zc1 := old_eye.z + t1 * step.z; |
||
1913 | |||
1914 | distance := sqrt( sqr(yc1 - center.y) + sqr(zc1 - center.z) ); |
||
1915 | |||
1916 | if FPercentLeftatTop >= 0 |
||
1917 | then |
||
1918 | radius := width3D/2 * FPercentLeftatTop //the small end of the conus is upwards |
||
1919 | else |
||
1920 | radius := width3D/2; |
||
1921 | |||
1922 | radius := radius + bullet_radius; |
||
1923 | |||
1924 | result := (distance < radius) and (t1 >= 0); |
||
1925 | if not longshot then result := result and (t1 <= 1); |
||
1926 | if result then exit; |
||
1927 | end; |
||
1928 | end; |
||
1929 | symmetric_y : |
||
1930 | begin |
||
1931 | if step.y > 1e-6 |
||
1932 | then |
||
1933 | begin |
||
1934 | //1st end surface |
||
1935 | t1 := (Fcoll_box_min[FseriesNr, coll_Nr].y - old_eye.y)/step.y; |
||
1936 | xc1 := old_eye.x + t1 * step.x; |
||
1937 | zc1 := old_eye.z + t1 * step.z; |
||
1938 | |||
1939 | distance := sqrt( sqr(xc1 - center.x) + sqr(zc1 - center.z) ); |
||
1940 | |||
1941 | if FPercentLeftatTop >= 0 |
||
1942 | then |
||
1943 | radius := width3D/2 //the large end of the conus is down |
||
1944 | else |
||
1945 | radius := -width3D/2 * FPercentLeftatTop; |
||
1946 | |||
1947 | radius := radius + bullet_radius; |
||
1948 | |||
1949 | result := (distance < radius) and (t1 >= 0); |
||
1950 | if not longshot then result := result and (t1 <= 1); |
||
1951 | if result then exit; |
||
1952 | |||
1953 | //2nd end surface |
||
1954 | t1 := (Fcoll_box_max[FseriesNr, coll_Nr].y - old_eye.y)/step.y; |
||
1955 | xc1 := old_eye.x + t1 * step.x; |
||
1956 | zc1 := old_eye.z + t1 * step.z; |
||
1957 | |||
1958 | distance := sqrt( sqr(xc1 - center.x) + sqr(zc1 - center.z) ); |
||
1959 | |||
1960 | if FPercentLeftatTop >= 0 |
||
1961 | then |
||
1962 | radius := width3D/2 * FPercentLeftatTop //the small end of the conus is upwards |
||
1963 | else |
||
1964 | radius := width3D/2; |
||
1965 | |||
1966 | radius := radius + bullet_radius; |
||
1967 | |||
1968 | result := (distance < radius) and (t1 >= 0); |
||
1969 | if not longshot then result := result and (t1 <= 1); |
||
1970 | if result then exit; |
||
1971 | end; |
||
1972 | |||
1973 | end; |
||
1974 | symmetric_z : |
||
1975 | begin |
||
1976 | if step.z > 1e-6 |
||
1977 | then |
||
1978 | begin |
||
1979 | //1st end surface |
||
1980 | t1 := (Fcoll_box_min[FseriesNr, coll_Nr].z - old_eye.z)/step.z; |
||
1981 | xc1 := old_eye.x + t1 * step.x; |
||
1982 | yc1 := old_eye.y + t1 * step.y; |
||
1983 | |||
1984 | distance := sqrt( sqr(xc1 - center.x) + sqr(yc1 - center.y) ); |
||
1985 | |||
1986 | if FPercentLeftatTop >= 0 |
||
1987 | then |
||
1988 | radius := width3D/2 //the large end of the conus is down |
||
1989 | else |
||
1990 | radius := width3D/2 * FPercentLeftatTop; |
||
1991 | |||
1992 | radius := radius + bullet_radius; |
||
1993 | |||
1994 | result := (distance < radius) and (t1 >= 0); |
||
1995 | if not longshot then result := result and (t1 <= 1); |
||
1996 | if result then exit; |
||
1997 | |||
1998 | //2nd end surface |
||
1999 | t1 := (Fcoll_box_max[FseriesNr, coll_Nr].z - old_eye.z)/step.z; |
||
2000 | xc1 := old_eye.x + t1 * step.x; |
||
2001 | yc1 := old_eye.y + t1 * step.y; |
||
2002 | |||
2003 | distance := sqrt( sqr(xc1 - center.x) + sqr(yc1 - center.y) ); |
||
2004 | |||
2005 | if FPercentLeftatTop >= 0 |
||
2006 | then |
||
2007 | radius := -width3D/2 * FPercentLeftatTop //the small end of the conus is upwards |
||
2008 | else |
||
2009 | radius := width3D/2; |
||
2010 | |||
2011 | radius := radius + bullet_radius; |
||
2012 | |||
2013 | result := (distance < radius) and (t1 >= 0); |
||
2014 | if not longshot then result := result and (t1 <= 1); |
||
2015 | if result then exit; |
||
2016 | end; |
||
2017 | |||
2018 | end; |
||
2019 | |||
2020 | |||
2021 | end; //end of case |
||
2022 | |||
2023 | |||
2024 | end; //end of coll_test_conus |
||
2025 | |||
2026 | |||
2027 | |||
2028 | |||
2029 | function TcollisionTester3DX.coll_test_box(coll_nr : byte; |
||
2030 | old_attacker_position, attacker_position : TD3DVector; |
||
2031 | bullet_radius : TD3DValue; longshot : boolean): boolean; |
||
2032 | var |
||
2033 | new_eye, old_eye : TD3DVector; |
||
2034 | step : TD3DVector; |
||
2035 | t1, xc, yc, zc : TD3DValue; |
||
2036 | begin |
||
2037 | result := false; |
||
2038 | |||
2039 | //Get the coordinates of the old eye_position in the actual coll frame |
||
2040 | FFrameSeries[FSeriesIndex, FNrinFrameSeries[FSeriesNr, coll_nr]].InverseTransform |
||
2041 | (old_eye, old_attacker_position); |
||
2042 | |||
2043 | //Get the coordinates of the eye_position in the actual coll frame |
||
2044 | FFrameSeries[FSeriesIndex, FNrinFrameSeries[FSeriesNr, coll_nr]].InverseTransform |
||
2045 | (new_eye, attacker_position); |
||
2046 | |||
2047 | //step in eye position |
||
2048 | step.x := new_eye.x - old_eye.x; |
||
2049 | step.y := new_eye.y - old_eye.y; |
||
2050 | step.z := new_eye.z - old_eye.z; |
||
2051 | |||
2052 | //collision is only possible when something moves |
||
2053 | if (abs(step.x) < 1e-3) and (abs(step.y) < 1e-3) and (abs(step.z) < 1e-3) |
||
2054 | then |
||
2055 | begin |
||
2056 | result := false; |
||
2057 | exit; |
||
2058 | end; |
||
2059 | |||
2060 | //check the surfaces which are normal to the x-axis |
||
2061 | if abs(step.x) >= 1E-6 |
||
2062 | then |
||
2063 | begin |
||
2064 | //test 1st surface |
||
2065 | t1 := (Fcoll_box_min[FseriesNr, coll_nr].x - old_eye.x)/step.x; |
||
2066 | //collision point |
||
2067 | zc := old_eye.z + t1 * step.z; |
||
2068 | yc := old_eye.y + t1 * step.y; |
||
2069 | |||
2070 | //collision if the collision point is close enough to the surface |
||
2071 | result := |
||
2072 | (zc >= (Fcoll_box_min[FseriesNr, coll_nr].z - bullet_radius)) and |
||
2073 | (zc <= (Fcoll_box_max[FseriesNr, coll_nr].z + bullet_radius)) and |
||
2074 | (yc >= (Fcoll_box_min[FseriesNr, coll_nr].y - bullet_radius)) and |
||
2075 | (yc <= (Fcoll_box_max[FseriesNr, coll_nr].y + bullet_radius)); |
||
2076 | |||
2077 | if longshot |
||
2078 | then result := result and (t1 >= 0) |
||
2079 | else result := result and (t1 >= 0) and (t1 <= 1); |
||
2080 | |||
2081 | //if collision detected then exit now |
||
2082 | if result then exit; |
||
2083 | |||
2084 | //test 2nd surface |
||
2085 | t1 := (Fcoll_box_max[FseriesNr, coll_nr].x - old_eye.x)/step.x; |
||
2086 | //collision point |
||
2087 | zc := old_eye.z + t1 * step.z; |
||
2088 | yc := old_eye.y + t1 * step.y; |
||
2089 | |||
2090 | //collision if the collision point is close enough to the surface |
||
2091 | result := |
||
2092 | (zc >= (Fcoll_box_min[FseriesNr, coll_nr].z - bullet_radius)) and |
||
2093 | (zc <= (Fcoll_box_max[FseriesNr, coll_nr].z + bullet_radius)) and |
||
2094 | (yc >= (Fcoll_box_min[FseriesNr, coll_nr].y - bullet_radius)) and |
||
2095 | (yc <= (Fcoll_box_max[FseriesNr, coll_nr].y + bullet_radius)); |
||
2096 | |||
2097 | if longshot |
||
2098 | then result := result and (t1 >= 0) |
||
2099 | else result := result and (t1 >= 0) and (t1 <= 1); |
||
2100 | |||
2101 | //if collision detected then exit now |
||
2102 | if result then exit; |
||
2103 | |||
2104 | end; //end of step.x <> 0 |
||
2105 | |||
2106 | |||
2107 | //check the surfaces which are normal to the y-axis |
||
2108 | if abs(step.y) >= 1E-6 |
||
2109 | then |
||
2110 | begin |
||
2111 | //test 1st surface |
||
2112 | t1 := (Fcoll_box_min[FseriesNr, coll_nr].y - old_eye.y)/step.y; |
||
2113 | //collision point |
||
2114 | xc := old_eye.x + t1 * step.x; |
||
2115 | zc := old_eye.z + t1 * step.z; |
||
2116 | |||
2117 | //collision if the collision point is close enough to the surface |
||
2118 | result := |
||
2119 | (xc >= (Fcoll_box_min[FseriesNr, coll_nr].x - bullet_radius)) and |
||
2120 | (xc <= (Fcoll_box_max[FseriesNr, coll_nr].x + bullet_radius)) and |
||
2121 | (zc >= (Fcoll_box_min[FseriesNr, coll_nr].z - bullet_radius)) and |
||
2122 | (zc <= (Fcoll_box_max[FseriesNr, coll_nr].z + bullet_radius)); |
||
2123 | |||
2124 | if longshot |
||
2125 | then result := result and (t1 >= 0) |
||
2126 | else result := result and (t1 >= 0) and (t1 <= 1); |
||
2127 | |||
2128 | //if collision detected then exit now |
||
2129 | if result then exit; |
||
2130 | |||
2131 | //test 2nd surface |
||
2132 | t1 := (Fcoll_box_max[FseriesNr, coll_nr].y - old_eye.y)/step.y; |
||
2133 | //collision point |
||
2134 | xc := old_eye.x + t1 * step.x; |
||
2135 | zc := old_eye.z + t1 * step.z; |
||
2136 | |||
2137 | //collision if the collision point is close enough to the surface |
||
2138 | result := |
||
2139 | (xc >= (Fcoll_box_min[FseriesNr, coll_nr].x - bullet_radius)) and |
||
2140 | (xc <= (Fcoll_box_max[FseriesNr, coll_nr].x + bullet_radius)) and |
||
2141 | (zc >= (Fcoll_box_min[FseriesNr, coll_nr].z - bullet_radius)) and |
||
2142 | (zc <= (Fcoll_box_max[FseriesNr, coll_nr].z + bullet_radius)); |
||
2143 | |||
2144 | if longshot |
||
2145 | then result := result and (t1 >= 0) |
||
2146 | else result := result and (t1 >= 0) and (t1 <= 1); |
||
2147 | |||
2148 | //if collision detected then exit now |
||
2149 | if result then exit; |
||
2150 | |||
2151 | end; //end of step.y <> 0 |
||
2152 | |||
2153 | |||
2154 | |||
2155 | //check the surfaces which are normal to the z-axis |
||
2156 | if abs(step.z) >= 1E-6 |
||
2157 | then |
||
2158 | begin |
||
2159 | //test 1st surface |
||
2160 | t1 := (Fcoll_box_min[FseriesNr, coll_nr].z - old_eye.z)/step.z; |
||
2161 | //collision point |
||
2162 | xc := old_eye.x + t1 * step.x; |
||
2163 | yc := old_eye.y + t1 * step.y; |
||
2164 | |||
2165 | //collision if the collision point is close enough to the surface |
||
2166 | result := |
||
2167 | (xc >= (Fcoll_box_min[FseriesNr, coll_nr].x - bullet_radius)) and |
||
2168 | (xc <= (Fcoll_box_max[FseriesNr, coll_nr].x + bullet_radius)) and |
||
2169 | (yc >= (Fcoll_box_min[FseriesNr, coll_nr].y - bullet_radius)) and |
||
2170 | (yc <= (Fcoll_box_max[FseriesNr, coll_nr].y + bullet_radius)); |
||
2171 | |||
2172 | if longshot |
||
2173 | then result := result and (t1 >= 0) |
||
2174 | else result := result and (t1 >= 0) and (t1 <= 1); |
||
2175 | |||
2176 | //if collision detected then exit now |
||
2177 | if result then exit; |
||
2178 | |||
2179 | //test 2nd surface |
||
2180 | t1 := (Fcoll_box_max[FseriesNr, coll_nr].z - old_eye.z)/step.z; |
||
2181 | //collision point |
||
2182 | xc := old_eye.x + t1 * step.x; |
||
2183 | yc := old_eye.y + t1 * step.y; |
||
2184 | |||
2185 | //collision if the collision point is close enough to the surface |
||
2186 | result := |
||
2187 | (xc >= (Fcoll_box_min[FseriesNr, coll_nr].x - bullet_radius)) and |
||
2188 | (xc <= (Fcoll_box_max[FseriesNr, coll_nr].x + bullet_radius)) and |
||
2189 | (yc >= (Fcoll_box_min[FseriesNr, coll_nr].y - bullet_radius)) and |
||
2190 | (yc <= (Fcoll_box_max[FseriesNr, coll_nr].y + bullet_radius)); |
||
2191 | |||
2192 | if longshot |
||
2193 | then result := result and (t1 >= 0) |
||
2194 | else result := result and (t1 >= 0) and (t1 <= 1); |
||
2195 | |||
2196 | //if collision detected then exit now |
||
2197 | if result then exit; |
||
2198 | |||
2199 | end; //end of step.z <> 0 |
||
2200 | |||
2201 | |||
2202 | end; //end of coll_test_box |
||
2203 | |||
2204 | |||
2205 | |||
2206 | |||
2207 | |||
2208 | |||
2209 | function TCollisionTester3DX.BulletDead:boolean; |
||
2210 | var |
||
2211 | camera_position, bullet_position : TD3DVector; |
||
2212 | Distance : TD3DValue; |
||
2213 | begin |
||
2214 | FBulletFrame.GetPosition(FDXDrawUsed.Scene, bullet_position); |
||
2215 | FDXDrawUsed.Camera.GetPosition(FDXDrawUsed.Scene, camera_position); |
||
2216 | |||
2217 | Distance := sqr(Bullet_position.x - camera_position.x) |
||
2218 | + sqr(Bullet_position.y - camera_position.y) |
||
2219 | + sqr(Bullet_position.z - camera_position.z); |
||
2220 | |||
2221 | //remove the bullet if it is beyond the bulletrange or if it is a longshot |
||
2222 | result := (sqrt(Distance) > FBulletRange) or FLongShots; |
||
2223 | |||
2224 | end; //end of BulletDead |
||
2225 | |||
2226 | |||
2227 | |||
2228 | |||
2229 | //use this function to check whether the camera or an object in a distance of |
||
2230 | // -from camera- from the camera collides with any collision object |
||
2231 | function TCollisionTester3DX.collision: boolean; |
||
2232 | var |
||
2233 | i : integer; |
||
2234 | camera_position, camera_direction, camera_up : TD3DVECTOR; |
||
2235 | eye_position : TD3DVector; |
||
2236 | begin |
||
2237 | Result := false; |
||
2238 | FBullet_HitlinkNr := -1; |
||
2239 | |||
2240 | if CheckForSeriesIndex(FSeriesIndex) |
||
2241 | then |
||
2242 | begin |
||
2243 | //The series exists |
||
2244 | if Fcoll_Nr_objects[FSeriesNr] > 0 |
||
2245 | then |
||
2246 | begin |
||
2247 | //The series is not empty |
||
2248 | |||
2249 | //Get the position of the camera |
||
2250 | FDXDrawUsed.Camera.GetPosition(FDXDrawUsed.Scene, camera_position); |
||
2251 | FDXDrawUsed.camera.GetOrientation(FDXDrawUsed.scene, camera_direction, camera_up); |
||
2252 | //calculate the eye position |
||
2253 | eye_position.x := camera_position.x + FFrontDistance * camera_direction.x; |
||
2254 | eye_position.y := camera_position.y + FFrontDistance * camera_direction.y; |
||
2255 | eye_position.z := camera_position.z + FFrontDistance * camera_direction.z; |
||
2256 | |||
2257 | //test whether the eye collides with any of the collision objects |
||
2258 | i := 0; |
||
2259 | while (not result) and (i < Fcoll_nr_objects[FSeriesNr]) do //0.. |
||
2260 | begin |
||
2261 | case Fcoll_shape[FSeriesNr, i] of |
||
2262 | box3D : Result := coll_test_box(i, FOldEyePosition, |
||
2263 | eye_position, FHeadRadius, false); |
||
2264 | sphere3D : Result := coll_test_sphere(i, FOldEyePosition, |
||
2265 | eye_position, FHeadRadius, false); |
||
2266 | cylinder3D : Result := coll_test_cylinder(i, FOldEyePosition, |
||
2267 | eye_position, FHeadRadius, false); |
||
2268 | ellipsoid3D: Result := coll_test_ellipsoid(i, FOldEyePosition, |
||
2269 | eye_position, FHeadRadius, false); |
||
2270 | conus3D : Result := coll_test_conus(i, FOldEyePosition, |
||
2271 | eye_position, FHeadRadius, false); |
||
2272 | end; |
||
2273 | |||
2274 | if result then Fbullet_hitLinkNr := Fcoll_objectnr[FseriesNr, i]; |
||
2275 | inc(i); |
||
2276 | end; |
||
2277 | end; |
||
2278 | end; //end of if checkforseriesIndex |
||
2279 | |||
2280 | if result |
||
2281 | then |
||
2282 | ListDataForCollObject; |
||
2283 | |||
2284 | end; //end of collision |
||
2285 | |||
2286 | |||
2287 | |||
2288 | |||
2289 | |||
2290 | |||
2291 | |||
2292 | //use this function to check whether an object sent from the camera collides |
||
2293 | //with any collision object |
||
2294 | function TCollisionTester3DX.BulletCollision: boolean; |
||
2295 | var |
||
2296 | i: integer; |
||
2297 | bullet_position : TD3DVector; |
||
2298 | begin |
||
2299 | Result := false; |
||
2300 | FBullet_HitLinkNr := -1; |
||
2301 | |||
2302 | if checkForSeriesIndex(FSeriesIndex) |
||
2303 | then |
||
2304 | begin |
||
2305 | //Series exists |
||
2306 | |||
2307 | //test whether eye collides with any of the collision objects |
||
2308 | if Fcoll_Nr_objects[FSeriesNr] > 0 |
||
2309 | then |
||
2310 | begin |
||
2311 | //Get position of the bullet |
||
2312 | FBulletFrame.GetPosition(FDXDrawUsed.Scene, bullet_position); |
||
2313 | i := 0; |
||
2314 | |||
2315 | while (not result) and (i < Fcoll_Nr_objects[FSeriesNr]) do //0.. |
||
2316 | begin |
||
2317 | if FColl_Shootable[FseriesNr, i] or |
||
2318 | (FColl_material[FSeriesNr, i] = solid3D) |
||
2319 | then |
||
2320 | begin |
||
2321 | case Fcoll_shape[FSeriesNr, i] of |
||
2322 | box3D : result := coll_test_box(i, FOldBulletPosition, |
||
2323 | bullet_position, |
||
2324 | FBulletRadius, FLongShots); |
||
2325 | sphere3D : result := coll_test_sphere(i, FOldBulletPosition, |
||
2326 | bullet_position, |
||
2327 | FBulletRadius, FLongShots); |
||
2328 | cylinder3D : result := coll_test_cylinder(i, FOldBulletPosition, |
||
2329 | bullet_position, |
||
2330 | FBulletRadius, FLongShots); |
||
2331 | ellipsoid3D: result := coll_test_ellipsoid(i, FOldBulletPosition, |
||
2332 | bullet_position, |
||
2333 | FBulletRadius, FLongShots); |
||
2334 | conus3D : result := coll_test_conus(i, FOldBulletPosition, |
||
2335 | bullet_position, |
||
2336 | FBulletRadius, FLongShots); |
||
2337 | end; //end case |
||
2338 | end; //end of if.. |
||
2339 | |||
2340 | if result |
||
2341 | then |
||
2342 | FBullet_HitLinkNr := Fcoll_ObjectNr[FSeriesNr, i]; |
||
2343 | |||
2344 | inc(i); |
||
2345 | end; //end of while |
||
2346 | |||
2347 | if result |
||
2348 | then |
||
2349 | ListDataForCollObject; |
||
2350 | |||
2351 | end; //end if Fcoll_Nr_ob.... |
||
2352 | end; //end if checkForSeriesIndex... |
||
2353 | |||
2354 | end; //end of bullet_collision |
||
2355 | |||
2356 | |||
2357 | |||
2358 | |||
2359 | procedure TCollisionTester3DX.GetOldBulletPos; |
||
2360 | begin |
||
2361 | FbulletFrame.GetPosition(FDXDrawUsed.Scene, FOldBulletPosition); |
||
2362 | end; //end of GetOldBulletPos |
||
2363 | |||
2364 | |||
2365 | procedure TCollisionTester3DX.GetOldEyePos; |
||
2366 | var |
||
2367 | OldPos, camera_direction, camera_up : TD3DVector; |
||
2368 | begin |
||
2369 | FDXDrawUsed.Camera.GetPosition(FDXDrawUsed.Scene, OldPos); |
||
2370 | FDXDrawUsed.Camera.GetOrientation(FDXDrawUsed.Scene, camera_direction, camera_up); |
||
2371 | |||
2372 | FOldEyePosition.x := OldPos.x + FFrontDistance * camera_direction.x; |
||
2373 | FOldEyePosition.y := OldPos.y + FFrontDistance * camera_direction.y; |
||
2374 | FOldEyePosition.z := OldPos.z + FFrontDistance * camera_direction.z; |
||
2375 | |||
2376 | end; //end of GetOldEyePos |
||
2377 | |||
2378 | |||
2379 | |||
2380 | |||
2381 | |||
2382 | |||
2383 | end. |