1 /*KJL*************************
2 * los.c - Line of sight code *
3 *************************KJL*/
4 #include "3dc.h"
5 #include "module.h"
6 #include "inline.h"
7 #include "stratdef.h"
8 #include "gamedef.h"
9 #include "dynblock.h"
10 #include "dynamics.h"
11
12 #include "bh_types.h"
13 #include "comp_shp.h"
14 #include "avpview.h"
15 #define UseLocalAssert Yes
16 #include "ourasert.h"
17 #include "dxlog.h"
18 #include "showcmds.h"
19 #include "targeting.h"
20 #include "los.h"
21
22 /*KJL****************************************************************************************
23 * P R O T O T Y P E S *
24 ****************************************************************************************KJL*/
25 int IsThisObjectVisibleFromThisPosition(DISPLAYBLOCK *dPtr,VECTORCH *positionPtr,int maxRange);
26 void CheckForVectorIntersectionWithHierarchicalObject(DISPLAYBLOCK *dPtr, VECTORCH *viewVectorAlphaPtr, VECTORCH *viewVectorBetaPtr);
27 void CheckForRayIntersectionWithHierarchy(DISPLAYBLOCK *objectPtr, SECTION_DATA *sectionDataPtr);
28 void CheckForRayIntersectionWithObject(DISPLAYBLOCK *dPtr);
29 /*KJL****************************************************************************************
30 * D E F I N E S *
31 ****************************************************************************************KJL*/
32 #define POLY_REJECT_RANGE 500
33
34 extern MORPHDISPLAY MorphDisplay;
35 extern VECTORCH MorphedPts[];
36 extern VECTORCH *ShapePointsPtr;
37 extern int *ShapeNormalsPtr;
38 extern int *Shape2NormalsPtr;
39 extern char ShapeIsMorphed;
40 extern int **ItemArrayPtr;
41 extern POLYHEADER *PolyheaderPtr;
42
43 #define AccessNextPolygon()\
44 {\
45 int *itemPtr = *(ItemArrayPtr++);\
46 PolyheaderPtr = (POLYHEADER *) itemPtr;\
47 }
48
49 #define GetPolygonVertices(polyPtr)\
50 {\
51 int *vertexNumberPtr = &PolyheaderPtr->Poly1stPt;\
52 \
53 (polyPtr)->PolyPoint[0] = *(ShapePointsPtr + *vertexNumberPtr++);\
54 (polyPtr)->PolyPoint[1] = *(ShapePointsPtr + *vertexNumberPtr++);\
55 (polyPtr)->PolyPoint[2] = *(ShapePointsPtr + *vertexNumberPtr++);\
56 \
57 if (*vertexNumberPtr != Term)\
58 {\
59 (polyPtr)->PolyPoint[3] = *(ShapePointsPtr + *vertexNumberPtr);\
60 (polyPtr)->NumberOfVertices=4; \
61 }\
62 else\
63 {\
64 (polyPtr)->NumberOfVertices=3; \
65 }\
66 }
67 #define GetPolygonNormal(polyPtr)\
68 { \
69 if (ShapeIsMorphed)\
70 {\
71 VECTORCH n1Ptr = *(VECTORCH*)(ShapeNormalsPtr + PolyheaderPtr->PolyNormalIndex);\
72 VECTORCH n2Ptr = *(VECTORCH*)(Shape2NormalsPtr + PolyheaderPtr->PolyNormalIndex);\
73 \
74 if( ((n1Ptr.vx == n2Ptr.vx)\
75 && (n1Ptr.vy == n2Ptr.vy)\
76 && (n1Ptr.vz == n2Ptr.vz))\
77 || (MorphDisplay.md_lerp == 0) )\
78 {\
79 (polyPtr)->PolyNormal = n1Ptr;\
80 }\
81 else if(MorphDisplay.md_lerp == 0xffff)\
82 {\
83 (polyPtr)->PolyNormal = n2Ptr;\
84 }\
85 else\
86 {\
87 VECTORCH *pointPtr[3];\
88 int *vertexNumPtr = &PolyheaderPtr->Poly1stPt;\
89 \
90 pointPtr[0] = (ShapePointsPtr + *vertexNumPtr++);\
91 pointPtr[1] = (ShapePointsPtr + *vertexNumPtr++);\
92 pointPtr[2] = (ShapePointsPtr + *vertexNumPtr);\
93 \
94 MakeNormal\
95 (\
96 pointPtr[0],\
97 pointPtr[1],\
98 pointPtr[2],\
99 &(polyPtr)->PolyNormal\
100 );\
101 }\
102 }\
103 else /* not morphed */\
104 {\
105 (polyPtr)->PolyNormal = *(VECTORCH*)(ShapeNormalsPtr + PolyheaderPtr->PolyNormalIndex);\
106 }\
107 }
108
109 /*KJL****************************************************************************************
110 * G L O B A L S *
111 ****************************************************************************************KJL*/
112 extern DISPLAYBLOCK *Player;
113
114 /* unnormalised vector in the direction which the gun's muzzle is pointing, IN VIEW SPACE */
115 /* very useful when considering sprites, which lie in a Z-plane in view space */
116 extern VECTORCH GunMuzzleDirectionInVS;
117 /* dir gun is pointing, normalised and IN WORLD SPACE */
118 extern VECTORCH GunMuzzleDirectionInWS;
119
120 extern DISPLAYBLOCK PlayersWeapon;
121
122
123 extern int NumOnScreenBlocks;
124 extern DISPLAYBLOCK *OnScreenBlockList[];
125 extern int NumActiveBlocks;
126 extern DISPLAYBLOCK *ActiveBlockList[];
127
128
129 static VECTORCH *ViewpointDirectionPtr;
130 static VECTORCH *ViewpointPositionPtr;
131
132
133 /*KJL****************************************************************************************
134 * CODE STARTS HERE! *
135 ****************************************************************************************KJL*/
CameraCanSeeThisPosition_WithIgnore(DISPLAYBLOCK * ignoredObjectPtr,VECTORCH * positionPtr)136 int CameraCanSeeThisPosition_WithIgnore(DISPLAYBLOCK *ignoredObjectPtr,VECTORCH *positionPtr)
137 {
138 VECTORCH viewVector; /* direction of view-line */
139
140 GLOBALASSERT(ignoredObjectPtr);
141
142 /* try to look at the centre of the camera */
143 viewVector = Global_VDB_Ptr->VDB_World;
144
145 viewVector.vx -= positionPtr->vx;
146 viewVector.vy -= positionPtr->vy;
147 viewVector.vz -= positionPtr->vz;
148 Normalise(&viewVector);
149
150 FindPolygonInLineOfSight(&viewVector, positionPtr, 0,ignoredObjectPtr);
151
152
153 if (LOS_ObjectHitPtr == Player) return 1;
154 else return 0;
155 }
156
IsThisObjectVisibleFromThisPosition_WithIgnore(DISPLAYBLOCK * objectPtr,DISPLAYBLOCK * ignoredObjectPtr,VECTORCH * positionPtr,int maxRange)157 int IsThisObjectVisibleFromThisPosition_WithIgnore(DISPLAYBLOCK *objectPtr,DISPLAYBLOCK *ignoredObjectPtr,VECTORCH *positionPtr,int maxRange)
158 {
159 VECTORCH viewVector; /* direction of view-line */
160
161 GLOBALASSERT(objectPtr);
162
163 /* try to look at the centre of the object */
164 GetTargetingPointOfObject(objectPtr, &viewVector);
165
166 viewVector.vx -= positionPtr->vx;
167 viewVector.vy -= positionPtr->vy;
168 viewVector.vz -= positionPtr->vz;
169 Normalise(&viewVector);
170
171 FindPolygonInLineOfSight(&viewVector, positionPtr, 0,ignoredObjectPtr);
172
173
174 if (LOS_ObjectHitPtr == objectPtr) return 1;
175 else return 0;
176 }
177
IsThisObjectVisibleFromThisPosition(DISPLAYBLOCK * objectPtr,VECTORCH * positionPtr,int maxRange)178 int IsThisObjectVisibleFromThisPosition(DISPLAYBLOCK *objectPtr,VECTORCH *positionPtr,int maxRange)
179 {
180 VECTORCH viewVector; /* direction of view-line */
181
182 GLOBALASSERT(objectPtr);
183
184 /* try to look at the centre of the object */
185 GetTargetingPointOfObject(objectPtr, &viewVector);
186
187 viewVector.vx -= positionPtr->vx;
188 viewVector.vy -= positionPtr->vy;
189 viewVector.vz -= positionPtr->vz;
190 Normalise(&viewVector);
191
192 FindPolygonInLineOfSight(&viewVector, positionPtr, 0,0);
193
194
195 if (LOS_ObjectHitPtr == objectPtr) return 1;
196 else return 0;
197 }
198
199
CheckForVectorIntersectionWith3dObject(DISPLAYBLOCK * objectPtr,VECTORCH * viewVectorAlphaPtr,VECTORCH * viewVectorBetaPtr,int rigorous)200 void CheckForVectorIntersectionWith3dObject(DISPLAYBLOCK *objectPtr, VECTORCH *viewVectorAlphaPtr, VECTORCH *viewVectorBetaPtr, int rigorous)
201 {
202 ViewpointPositionPtr = viewVectorAlphaPtr;
203 ViewpointDirectionPtr = viewVectorBetaPtr;
204
205 if (objectPtr->HModelControlBlock)
206 {
207 SECTION_DATA *firstSectionPtr;
208 firstSectionPtr=objectPtr->HModelControlBlock->section_data;
209 LOCALASSERT(firstSectionPtr);
210 if ( !(
211 (objectPtr->ObWorld.vx<1000000 && objectPtr->ObWorld.vx>-1000000)
212 && (objectPtr->ObWorld.vy<1000000 && objectPtr->ObWorld.vy>-1000000)
213 && (objectPtr->ObWorld.vz<1000000 && objectPtr->ObWorld.vz>-1000000)
214 ) )
215 {
216 return;
217 }
218 LOCALASSERT(objectPtr->ObWorld.vx<1000000 && objectPtr->ObWorld.vx>-1000000);
219 LOCALASSERT(objectPtr->ObWorld.vy<1000000 && objectPtr->ObWorld.vy>-1000000);
220 LOCALASSERT(objectPtr->ObWorld.vz<1000000 && objectPtr->ObWorld.vz>-1000000);
221 CheckForRayIntersectionWithHierarchy(objectPtr,firstSectionPtr);
222 }
223 else
224 {
225 CheckForRayIntersectionWithObject(objectPtr);
226 }
227 }
228
229
230
231
232
233
234
235
236
237 /* KJL 15:26:08 14/05/98 - FindPolygonInLineOfSight
238
239 Using either the Active or OnScreen Block list, find which polygon you would hit first
240 if a ray of light was cast out from a given point in world space (viewpointPositionPtr)
241 in a given direction (viewpointDirectionPtr).
242
243 The following are set:
244
245 LOS_ObjectHitPtr - dispPtr of hit object (NULL if none found)
246
247 LOS_Lambda - distance to hit polygon (or max if no hit)
248 LOS_Point - world space coords of intersection of ray & hit poly
249 LOS_ObjectNormal - normal of the hit polygon
250 LOS_HModel_Section - hierarchical section that was hit (or NULL if not hmodel)
251
252 */
FindPolygonInLineOfSight(VECTORCH * viewpointDirectionPtr,VECTORCH * viewpointPositionPtr,int useOnScreenBlockList,DISPLAYBLOCK * objectToIgnorePtr)253 void FindPolygonInLineOfSight(VECTORCH *viewpointDirectionPtr, VECTORCH *viewpointPositionPtr, int useOnScreenBlockList, DISPLAYBLOCK *objectToIgnorePtr) {
254
255 /* Shell function. */
256 FindPolygonInLineOfSight_TwoIgnores(viewpointDirectionPtr,viewpointPositionPtr,useOnScreenBlockList,objectToIgnorePtr,NULL);
257 /* No, it's not recursive! */
258 }
259
260
FindPolygonInLineOfSight_TwoIgnores(VECTORCH * viewpointDirectionPtr,VECTORCH * viewpointPositionPtr,int useOnScreenBlockList,DISPLAYBLOCK * objectToIgnorePtr,DISPLAYBLOCK * next_objectToIgnorePtr)261 void FindPolygonInLineOfSight_TwoIgnores(VECTORCH *viewpointDirectionPtr, VECTORCH *viewpointPositionPtr, int useOnScreenBlockList, DISPLAYBLOCK *objectToIgnorePtr,DISPLAYBLOCK *next_objectToIgnorePtr)
262 {
263 DISPLAYBLOCK **displayBlockList;
264 int numberOfObjects;
265
266 if (useOnScreenBlockList)
267 {
268 numberOfObjects = NumOnScreenBlocks;
269 displayBlockList = OnScreenBlockList;
270 }
271 else
272 {
273 numberOfObjects = NumActiveBlocks;
274 displayBlockList = ActiveBlockList;
275 }
276
277 /* initialise the LoS data */
278
279 LOS_Lambda=10000000;
280 LOS_ObjectHitPtr = 0;
281 LOS_HModel_Section= 0;
282 ViewpointPositionPtr = viewpointPositionPtr;
283 ViewpointDirectionPtr = viewpointDirectionPtr;
284
285
286 /* scan throught each object */
287 while (numberOfObjects--)
288 {
289 DISPLAYBLOCK* objectPtr = displayBlockList[numberOfObjects];
290
291 if ((objectPtr == objectToIgnorePtr)||(objectPtr == next_objectToIgnorePtr)) continue;
292
293 /* if hierarchical model, consider each object in the model separately */
294 if (objectPtr->HModelControlBlock)
295 {
296 SECTION_DATA *firstSectionPtr;
297 firstSectionPtr=objectPtr->HModelControlBlock->section_data;
298
299 LOCALASSERT(firstSectionPtr);
300 if ( !(
301 (objectPtr->ObWorld.vx<1000000 && objectPtr->ObWorld.vx>-1000000)
302 && (objectPtr->ObWorld.vy<1000000 && objectPtr->ObWorld.vy>-1000000)
303 && (objectPtr->ObWorld.vz<1000000 && objectPtr->ObWorld.vz>-1000000)
304 ) )
305 {
306 continue;
307
308 LOGDXFMT(("Pre assertions check for having processed the section...\n"));
309 LOGDXFMT(("State of initialised flag: %d\n",(firstSectionPtr->flags§ion_data_initialised)));
310 LOGDXFMT(("Name of section: %s\n",firstSectionPtr->sempai->Section_Name));
311 LOGDXFMT(("It was playing sequence: %d,%d\n",firstSectionPtr->my_controller->Sequence_Type,
312 firstSectionPtr->my_controller->Sub_Sequence));
313 LOGDXFMT(("ObWorld %d,%d,%d\n",objectPtr->ObWorld.vx,objectPtr->ObWorld.vy,objectPtr->ObWorld.vz));
314
315 {
316 DYNAMICSBLOCK *dynPtr=objectPtr->ObStrategyBlock->DynPtr;
317 LOCALASSERT(dynPtr);
318 LOGDXFMT(("DynPtr->Position %d,%d,%d\n",dynPtr->Position.vx,dynPtr->Position.vy,dynPtr->Position.vz));
319 }
320
321 LOCALASSERT(firstSectionPtr->flags§ion_data_initialised);
322 LOCALASSERT(objectPtr->ObWorld.vx<1000000 && objectPtr->ObWorld.vx>-1000000);
323 LOCALASSERT(objectPtr->ObWorld.vy<1000000 && objectPtr->ObWorld.vy>-1000000);
324 LOCALASSERT(objectPtr->ObWorld.vz<1000000 && objectPtr->ObWorld.vz>-1000000);
325
326 }
327 CheckForRayIntersectionWithHierarchy(objectPtr,firstSectionPtr);
328 }
329 else
330 {
331 CheckForRayIntersectionWithObject(objectPtr);
332 }
333 }
334 }
335
CheckForRayIntersectionWithHierarchy(DISPLAYBLOCK * objectPtr,SECTION_DATA * sectionDataPtr)336 void CheckForRayIntersectionWithHierarchy(DISPLAYBLOCK *objectPtr, SECTION_DATA *sectionDataPtr)
337 {
338 SECTION *sectionPtr;
339
340 /* LOS check. */
341
342 sectionPtr=sectionDataPtr->sempai;
343
344 /* Unreal things can't be hit... */
345
346 if (!(sectionDataPtr->flags§ion_data_notreal) && (sectionPtr->Shape!=NULL))
347 {
348 DISPLAYBLOCK dummy_displayblock;
349
350 dummy_displayblock.ObShape=sectionPtr->ShapeNum;
351 dummy_displayblock.ObShapeData=sectionPtr->Shape;
352 dummy_displayblock.ObWorld=sectionDataPtr->World_Offset;
353 dummy_displayblock.ObMat=sectionDataPtr->SecMat;
354
355 dummy_displayblock.ObRadius=0;
356 dummy_displayblock.ObMaxX=0;
357 dummy_displayblock.ObMinX=0;
358 dummy_displayblock.ObMaxY=0;
359 dummy_displayblock.ObMinY=0;
360 dummy_displayblock.ObMaxZ=0;
361 dummy_displayblock.ObMinZ=0;
362
363 dummy_displayblock.ObTxAnimCtrlBlks=NULL;
364 dummy_displayblock.ObEIDPtr=NULL;
365 dummy_displayblock.ObMorphCtrl=NULL;
366 dummy_displayblock.ObStrategyBlock=objectPtr->ObStrategyBlock;
367 dummy_displayblock.ShapeAnimControlBlock=sectionDataPtr->sac_ptr;
368 dummy_displayblock.HModelControlBlock=NULL; /* Don't even want to think about that. */
369 dummy_displayblock.ObMyModule=NULL;
370
371 /* KJL 21:12:11 12/11/98 - arg! ObFlags wasn't set */
372 dummy_displayblock.ObFlags = 0;
373
374 if ( !(
375 (dummy_displayblock.ObWorld.vx<1000000 && dummy_displayblock.ObWorld.vx>-1000000)
376 && (dummy_displayblock.ObWorld.vy<1000000 && dummy_displayblock.ObWorld.vy>-1000000)
377 && (dummy_displayblock.ObWorld.vz<1000000 && dummy_displayblock.ObWorld.vz>-1000000)
378 ) ) {
379
380 LOGDXFMT(("Pre assertions check for having processed the section...\n"));
381 LOGDXFMT(("State of initialised flag: %x\n",(sectionDataPtr->flags§ion_data_initialised)));
382 LOGDXFMT(("Name of section: %s\n",sectionDataPtr->sempai->Section_Name));
383 LOGDXFMT(("It was playing sequence: %d,%d\n",sectionDataPtr->my_controller->Sequence_Type,
384 sectionDataPtr->my_controller->Sub_Sequence));
385 LOGDXFMT(("ObWorld %d,%d,%d\n",dummy_displayblock.ObWorld.vx,dummy_displayblock.ObWorld.vy,dummy_displayblock.ObWorld.vz));
386
387 {
388 DYNAMICSBLOCK *dynPtr=objectPtr->ObStrategyBlock->DynPtr;
389 LOCALASSERT(dynPtr);
390 LOGDXFMT(("DynPtr->Position %d,%d,%d\n",dynPtr->Position.vx,dynPtr->Position.vy,dynPtr->Position.vz));
391 }
392
393 LOCALASSERT(sectionDataPtr->flags§ion_data_initialised);
394 LOCALASSERT(dummy_displayblock.ObWorld.vx<1000000 && dummy_displayblock.ObWorld.vx>-1000000);
395 LOCALASSERT(dummy_displayblock.ObWorld.vy<1000000 && dummy_displayblock.ObWorld.vy>-1000000);
396 LOCALASSERT(dummy_displayblock.ObWorld.vz<1000000 && dummy_displayblock.ObWorld.vz>-1000000);
397
398 }
399
400 CheckForRayIntersectionWithObject(&dummy_displayblock);
401
402 if (LOS_ObjectHitPtr == &dummy_displayblock)
403 {
404 /* ah, we've hit this object */
405 LOS_ObjectHitPtr = objectPtr;
406 LOS_HModel_Section = sectionDataPtr;
407 }
408 }
409
410 /* Now call recursion... */
411 if (sectionDataPtr->First_Child!=NULL)
412 {
413 SECTION_DATA *childrenListPtr = sectionDataPtr->First_Child;
414
415 while (childrenListPtr!=NULL)
416 {
417 CheckForRayIntersectionWithHierarchy(objectPtr,childrenListPtr);
418 childrenListPtr=childrenListPtr->Next_Sibling;
419 }
420 }
421
422 }
423
424
425
426
CheckForRayIntersectionWithObject(DISPLAYBLOCK * dPtr)427 void CheckForRayIntersectionWithObject(DISPLAYBLOCK *dPtr)
428 {
429 int numberOfItems;
430 VECTORCH viewVectorAlpha = *ViewpointPositionPtr;
431 VECTORCH viewVectorBeta = *ViewpointDirectionPtr;
432 VECTORCH position;
433 int needToRotate;
434
435 /* check for a valid object */
436 {
437 STRATEGYBLOCK* sbPtr;
438 GLOBALASSERT(dPtr);
439
440 /* can it be seen? */
441 if((dPtr->ObFlags&ObFlag_NotVis)&&(dPtr!=Player)) return;
442 /* KJL 21:18:44 23/05/98 - ugh. Currently the player's bounding box is notvis; I need a rethink */
443
444 /* any hierarchical models should have been split up by now */
445 LOCALASSERT(dPtr->HModelControlBlock==NULL);
446
447 /* no shape? */
448 if (!dPtr->ObShape && dPtr->SfxPtr) return;
449
450 sbPtr = dPtr->ObStrategyBlock;
451
452 /* test for objects we're not interested in */
453 if (sbPtr)
454 {
455 if (sbPtr->DynPtr)
456 {
457 /* ignore it if it's a non-collideable object, eg. debris */
458 if(sbPtr->DynPtr->DynamicsType == DYN_TYPE_NO_COLLISIONS)
459 return;
460 }
461 }
462 }
463
464 /* check objects position is sensible */
465 #if 0
466 LOCALASSERT(dPtr->ObWorld.vx<1000000 && dPtr->ObWorld.vx>-1000000);
467 LOCALASSERT(dPtr->ObWorld.vy<1000000 && dPtr->ObWorld.vy>-1000000);
468 LOCALASSERT(dPtr->ObWorld.vz<1000000 && dPtr->ObWorld.vz>-1000000);
469 #else
470 if(dPtr->ObWorld.vx>1000000 || dPtr->ObWorld.vx<-1000000) return;
471 if(dPtr->ObWorld.vy>1000000 || dPtr->ObWorld.vy<-1000000) return;
472 if(dPtr->ObWorld.vz>1000000 || dPtr->ObWorld.vz<-1000000) return;
473 #endif
474 if (dPtr==Player)
475 {
476 position = dPtr->ObStrategyBlock->DynPtr->Position;
477 }
478 else
479 {
480 position = dPtr->ObWorld;
481 }
482 /* transform view line into shape space */
483 viewVectorAlpha.vx -= position.vx;
484 viewVectorAlpha.vy -= position.vy;
485 viewVectorAlpha.vz -= position.vz;
486
487 #if 1
488 if (dPtr!=Player)
489 {
490 if (MagnitudeOfCrossProduct(&viewVectorAlpha,&viewVectorBeta)>dPtr->ObShapeData->shaperadius)
491 return;
492 }
493 #endif
494
495 /* if we're not dealing with a module, it's probably rotated */
496 if(!dPtr->ObMyModule&&dPtr!=Player)
497 {
498 needToRotate = 1;
499 }
500 else
501 {
502 needToRotate = 0;
503 }
504
505 if (needToRotate)
506 {
507 MATRIXCH matrix = dPtr->ObMat;
508 TransposeMatrixCH(&matrix);
509 RotateVector(&viewVectorBeta,&matrix);
510 RotateVector(&viewVectorAlpha,&matrix);
511 }
512
513 numberOfItems = SetupPolygonAccess(dPtr);
514 if (!dPtr->ObShape)
515 {
516 // PrintDebuggingText("polys %d\n",numberOfItems);
517 }
518
519 while(numberOfItems--)
520 {
521 extern POLYHEADER *PolyheaderPtr;
522 VECTORCH polyNormal;
523 struct ColPolyTag polyData;
524 VECTORCH pointOnPlane;
525 int lambda;
526 int axis1;
527 int axis2;
528
529 /* scanning through polys */
530 AccessNextPolygon();
531
532 if( (PolyheaderPtr->PolyFlags & iflag_notvis) && !(PolyheaderPtr->PolyFlags & iflag_mirror)) continue;
533
534
535 {
536 int normDotBeta;
537
538 GetPolygonNormal(&polyData);
539 polyNormal = polyData.PolyNormal;
540
541 normDotBeta = DotProduct(&(polyNormal),&viewVectorBeta);
542 {
543 /* if the polygon is flagged as double-sided, and it's pointing
544 the wrong way, consider it to be flipped round */
545 //if((PolyheaderPtr->PolyFlags) & iflag_no_bfc)
546 /* KJL 16:06:11 10/07/98 - treat all polys as no bfc */
547 {
548 if (normDotBeta>0)
549 {
550 normDotBeta=-normDotBeta;
551 polyNormal.vx = -polyNormal.vx;
552 polyNormal.vy = -polyNormal.vy;
553 polyNormal.vz = -polyNormal.vz;
554 }
555 }
556 }
557
558 /* trivial rejection of poly if it is not facing LOS */
559 if (normDotBeta>-POLY_REJECT_RANGE)
560 {
561 continue;
562 }
563
564 GetPolygonVertices(&polyData);
565 /* calculate coords of plane-line intersection */
566 {
567 int d;
568 {
569 /* get a pt in the poly */
570 VECTORCH pop=polyData.PolyPoint[0];
571 pop.vx -= viewVectorAlpha.vx;
572 pop.vy -= viewVectorAlpha.vy;
573 pop.vz -= viewVectorAlpha.vz;
574
575 d = DotProduct(&(polyNormal),&pop);
576 }
577
578 if (d>0) continue;
579
580 lambda = DIV_FIXED(d,normDotBeta);
581
582 if (lambda>=LOS_Lambda)
583 {
584 continue;
585 }
586 pointOnPlane.vx = viewVectorAlpha.vx + MUL_FIXED(lambda,viewVectorBeta.vx);
587 pointOnPlane.vy = viewVectorAlpha.vy + MUL_FIXED(lambda,viewVectorBeta.vy);
588 pointOnPlane.vz = viewVectorAlpha.vz + MUL_FIXED(lambda,viewVectorBeta.vz);
589
590 }
591
592 /* decide which 2d plane to project onto */
593
594 {
595 VECTORCH absNormal = (polyNormal);
596 if (absNormal.vx<0) absNormal.vx=-absNormal.vx;
597 if (absNormal.vy<0) absNormal.vy=-absNormal.vy;
598 if (absNormal.vz<0) absNormal.vz=-absNormal.vz;
599
600 if (absNormal.vx > absNormal.vy)
601 {
602 if (absNormal.vx > absNormal.vz)
603 {
604 axis1=iy;
605 axis2=iz;
606 }
607 else
608 {
609 axis1=ix;
610 axis2=iy;
611 }
612 }
613 else
614 {
615 if (absNormal.vy > absNormal.vz)
616 {
617 axis1=ix;
618 axis2=iz;
619 }
620 else
621 {
622 axis1=ix;
623 axis2=iy;
624 }
625 }
626 }
627
628 }
629
630 {
631 int projectedPolyVertex[20];
632 int projectedPointOnPlane[2];
633 int *popPtr = &pointOnPlane.vx;
634
635 projectedPointOnPlane[0]=*(popPtr+axis1);
636 projectedPointOnPlane[1]=*(popPtr+axis2);
637
638 {
639 VECTORCH *vertexPtr = &polyData.PolyPoint[0];
640 int *projectedVertexPtr= &projectedPolyVertex[0];
641 int noOfVertices = polyData.NumberOfVertices;
642
643 do
644 {
645 *projectedVertexPtr++ = *((int*)vertexPtr + axis1);
646 *projectedVertexPtr++ = *((int*)vertexPtr + axis2);
647
648 vertexPtr++;
649 noOfVertices--;
650 }
651 while(noOfVertices);
652
653 }
654
655
656 if (PointInPolygon(&projectedPointOnPlane[0],&projectedPolyVertex[0],polyData.NumberOfVertices,2))
657 {
658 /* rotate vector back into World Space if it's not a module */
659 LOS_ObjectNormal = polyNormal;
660 if (needToRotate)
661 {
662 MATRIXCH matrix = dPtr->ObMat;
663 RotateVector(&pointOnPlane,&matrix);
664
665 RotateVector(&LOS_ObjectNormal,&matrix);
666 }
667
668 /* and translate origin */
669 pointOnPlane.vx += position.vx;
670 pointOnPlane.vy += position.vy;
671 pointOnPlane.vz += position.vz;
672
673 LOS_Point=pointOnPlane;
674 LOS_ObjectHitPtr = dPtr;
675 LOS_Lambda=lambda;
676 LOS_HModel_Section = 0;
677 }
678 }
679 }
680 return;
681 }
682
683 /* KJL 15:35:58 14/05/98 - IsObjectVisibleFromThisPoint
684
685 Returns a non-zero value if an object can be seen from a given point in world space
686 (viewpointPositionPtr), with a given field of view (fieldOfView) about a given
687 direction (viewpointDirectionPtr).
688 */
IsObjectVisibleFromThisPoint(DISPLAYBLOCK * dispPtr,VECTORCH * viewpointDirectionPtr,VECTORCH * viewpointPositionPtr,int fieldOfView)689 int IsObjectVisibleFromThisPoint(DISPLAYBLOCK *dispPtr, VECTORCH *viewpointDirectionPtr, VECTORCH *viewpointPositionPtr, int fieldOfView)
690 {
691
692 return 0;
693 }
694
695
696
697
698
699
700
701