1 /* bzflag
2  * Copyright (c) 1993-2021 Tim Riker
3  *
4  * This package is free software;  you can redistribute it and/or
5  * modify it under the terms of the license found in the file
6  * named COPYING that should have accompanied this file.
7  *
8  * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
9  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
10  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11  */
12 
13 /*
14  * Utilities for doing intersection calculations.
15  */
16 
17 #ifndef BZF_INTERSECT_H
18 #define BZF_INTERSECT_H
19 
20 #include "common.h"
21 #include "Ray.h"
22 #include "Frustum.h"
23 
24 class Extents;
25 
26 enum IntersectLevel
27 {
28     Outside,
29     Partial,
30     Contained
31 };
32 
33 // returns normal to 2d rect (size 2dx x 2dy) by point p
34 void getNormalRect(const float* p, const float* boxPos,
35                    float boxAngle, float dx,
36                    float dy, float* n);
37 
38 // true iff 2d rect (size 2dx x 2dy) intersects circle (in z = const plane)
39 bool testRectCircle(const float* boxPos, float boxAngle,
40                     float dx, float dy,
41                     const float* circPos, float circRadius);
42 
43 // ray r1 started at time t1 minus ray r2 started at time t2
44 Ray rayMinusRay(const Ray& r1, float t1,
45                 const Ray& r2, float t2);
46 
47 // return t at which ray passes through sphere at origin of given radius
48 float rayAtDistanceFromOrigin(const Ray& r, float radius);
49 
50 // return t at which ray intersects box (size 2dx x 2dy x dz)
51 // (-1 if never, 0 if starts inside).
52 float timeRayHitsBlock(const Ray& r, const float* boxPos,
53                        float boxAngle, float dx,
54                        float dy, float dz);
55 
56 // return t at which ray intersects pyramid (size 2dx x 2dy x dz)
57 // (-1 if never, 0 if starts inside).
58 float timeRayHitsPyramids(const Ray& r,
59                           const float* pyrPos,
60                           float pyrAngle,
61                           float dx, float dy, float dz,
62                           bool flipZ);
63 
64 // return t at which ray intersects tetra (size 2dx x 2dy x dz)
65 // (-1 if never, 0 if starts inside).
66 float timeRayHitsTetra(const Ray& r,
67                        const float (*vertices)[4][3],
68                        const float (*planes)[4][4],
69                        const float* mins, const float *maxs);
70 
71 // true if rectangles intersect (in z = const plane)
72 bool testRectRect(const float* p1, float angle1,
73                   float dx1, float dy1,
74                   const float* p2, float angle2,
75                   float dx2, float dy2);
76 
77 // true if first rectangle contains second intersect (in z = const plane)
78 bool testRectInRect(const float* bigPos, float angle1,
79                     float dx1, float dy1,
80                     const float* smallPos, float angle2,
81                     float dx2, float dy2);
82 
83 // return t at which ray intersects 2d rect (size 2dx x 2dy) and side
84 // of intersection.  0,1,2,3 for east, north, west, south;  -1 if never;
85 // -2 if starts inside.
86 float timeAndSideRayHitsOrigRect(
87     const float* rayOrigin,
88     const float* rayDir,
89     float dx, float dy, int& side);
90 float timeAndSideRayHitsRect(const Ray& r,
91                              const float* boxPos, float boxAngle,
92                              float dx, float dy, int& side);
93 
94 // return true if polygon touches the axis aligned box
95 bool testPolygonInAxisBox(int pointCount, const float (*points)[3],
96                           const float* plane, const Extents& extents);
97 
98 // return level of axis box intersection with Frumstum
99 // possible values are Outside, Partial, and Contained.
100 // the frustum plane normals point inwards
101 IntersectLevel testAxisBoxInFrustum(const Extents& extents,
102                                     const Frustum* frustum);
103 
104 // return true if the axis aligned bounding box
105 // is contained within all of the planes.
106 // the occluder plane normals point inwards
107 IntersectLevel testAxisBoxOcclusion(const Extents& extents,
108                                     const float (*planes)[4],
109                                     int planeCount);
110 
111 // return true if the ray will intersect with the
112 // axis aligned bounding box defined by the mins
113 // and maxs. it will also fill in enterTime and
114 // leaveTime if there is an intersection.
115 bool textRayInAxisBox(const Ray& ray, const Extents& extents,
116                       float& enterTime, float& leaveTime);
117 
118 
119 // return true if the ray hits the box
120 // if it does hit, set the inTime value
121 bool testRayHitsAxisBox(const Ray* ray, const Extents& extents,
122                         float* inTime);
123 
124 // return true if the ray hits the box
125 // if it does hit, set the inTime and outTime values
126 bool testRayHitsAxisBox(const Ray* ray, const Extents& extents,
127                         float* inTime, float* outTime);
128 
129 
130 #endif // BZF_INTERSECT_H
131 
132 // Local Variables: ***
133 // mode: C++ ***
134 // tab-width: 4 ***
135 // c-basic-offset: 4 ***
136 // indent-tabs-mode: nil ***
137 // End: ***
138 // ex: shiftwidth=4 tabstop=4
139