Newton Dynamics  4.00
ndFastRay.h
1 /* Copyright (c) <2003-2022> <Julio Jerez, Newton Game Dynamics>
2 *
3 * This software is provided 'as-is', without any express or implied
4 * warranty. In no event will the authors be held liable for any damages
5 * arising from the use of this software.
6 *
7 * Permission is granted to anyone to use this software for any purpose,
8 * including commercial applications, and to alter it and redistribute it
9 * freely, subject to the following restrictions:
10 *
11 * 1. The origin of this software must not be misrepresented; you must not
12 * claim that you wrote the original software. If you use this software
13 * in a product, an acknowledgment in the product documentation would be
14 * appreciated but is not required.
15 *
16 * 2. Altered source versions must be plainly marked as such, and must not be
17 * misrepresented as being the original software.
18 *
19 * 3. This notice may not be removed or altered from any source distribution.
20 */
21 
22 #ifndef __ND_FAST_RAY_H__
23 #define __ND_FAST_RAY_H__
24 
25 #include "ndCoreStdafx.h"
26 #include "ndDebug.h"
27 #include "ndVector.h"
28 #include "ndClassAlloc.h"
29 
30 D_MSV_NEWTON_ALIGN_32
31 class ndRay: public ndClassAlloc
32 {
33  public:
34  ndRay(const ndVector& l0, const ndVector& l1)
35  :ndClassAlloc()
36  ,m_p0(l0 & ndVector::m_triplexMask)
37  ,m_p1(l1 & ndVector::m_triplexMask)
38  {
39  }
40 
41  const ndVector m_p0;
42  const ndVector m_p1;
43 } D_GCC_NEWTON_ALIGN_32;
44 
45 
46 D_MSV_NEWTON_ALIGN_32
47 class ndFastRay: public ndRay
48 {
49  public:
50  ndFastRay(const ndVector& l0, const ndVector& l1);
51 
52  ndInt32 BoxTest(const ndVector& minBox, const ndVector& maxBox) const;
53  ndFloat32 BoxIntersect(const ndVector& minBox, const ndVector& maxBox) const;
54 
55  ndRay PointDistance(const ndVector& point) const;
56  D_CORE_API ndRay RayDistance(const ndVector& ray_p0, const ndVector& ray_p1) const;
57  D_CORE_API ndFloat32 PolygonIntersect(const ndVector& normal, ndFloat32 maxT, const ndFloat32* const polygon, ndInt32 strideInBytes, const ndInt32* const indexArray, ndInt32 indexCount) const;
58 
59  const ndVector m_diff;
60  ndVector m_dpInv;
61  ndVector m_minT;
62  ndVector m_maxT;
63  ndVector m_unitDir;
64  ndVector m_isParallel;
65 } D_GCC_NEWTON_ALIGN_32 ;
66 
67 inline ndFastRay::ndFastRay(const ndVector& l0, const ndVector& l1)
68  :ndRay(l0, l1)
69  ,m_diff(m_p1 - m_p0)
70  ,m_minT(ndFloat32(0.0f))
71  ,m_maxT(ndFloat32(1.0f))
72 {
73  ndAssert(m_p0.m_w == ndFloat32(0.0f));
74  ndAssert(m_p1.m_w == ndFloat32(0.0f));
75  ndAssert(m_diff.m_w == ndFloat32(0.0f));
76 
77  ndAssert(m_diff.DotProduct(m_diff).GetScalar() > ndFloat32(0.0f));
78  m_isParallel = (m_diff.Abs() < ndVector(1.0e-8f));
79  m_dpInv = m_diff.Select(ndVector(ndFloat32(1.0e-20f)), m_isParallel).Reciproc() & ndVector::m_triplexMask;
80  m_unitDir = m_diff.Normalize();
81 }
82 
83 inline ndRay ndFastRay::PointDistance(const ndVector& point) const
84 {
85  //dBigVector dp(ray_p1 - ray_p0);
86  //ndAssert(dp.m_w == ndFloat32(0.0f));
87  ndFloat32 t = ndClamp(m_diff.DotProduct(point - m_p0).GetScalar() / m_diff.DotProduct(m_diff).GetScalar(), ndFloat32(0.0f), ndFloat32(1.0f));
88  return ndRay (m_p0 + m_diff.Scale(t), point);
89 }
90 
91 inline ndInt32 ndFastRay::BoxTest(const ndVector& minBox, const ndVector& maxBox) const
92 {
93 #if 1
94  ndVector test(((m_p0 <= minBox) | (m_p0 >= maxBox)) & m_isParallel);
95  if (test.GetSignMask() & 0x07)
96  {
97  return 0;
98  }
99 
100  ndVector tt0(m_dpInv * (minBox - m_p0));
101  ndVector tt1(m_dpInv * (maxBox - m_p0));
102 
103  ndVector t0(m_minT.GetMax(tt0.GetMin(tt1)));
104  ndVector t1(m_maxT.GetMin(tt0.GetMax(tt1)));
105  t0 = t0.GetMax(t0.ShiftTripleRight());
106  t1 = t1.GetMin(t1.ShiftTripleRight());
107  t0 = t0.GetMax(t0.ShiftTripleRight());
108  t1 = t1.GetMin(t1.ShiftTripleRight());
109  return ((t0 < t1).GetSignMask() & 1);
110 
111 #else
112 
113  ndFloat32 tmin = 0.0f;
114  ndFloat32 tmax = 1.0f;
115 
116  for (ndInt32 i = 0; i < 3; ++i)
117  {
118  if (m_isParallel[i])
119  {
120  if (m_p0[i] <= minBox[i] || m_p0[i] >= maxBox[i])
121  {
122  return 0;
123  }
124  }
125  else
126  {
127  ndFloat32 t1 = (minBox[i] - m_p0[i]) * m_dpInv[i];
128  ndFloat32 t2 = (maxBox[i] - m_p0[i]) * m_dpInv[i];
129 
130  if (t1 > t2)
131  {
132  ndSwap(t1, t2);
133  }
134  if (t1 > tmin)
135  {
136  tmin = t1;
137  }
138  if (t2 < tmax)
139  {
140  tmax = t2;
141  }
142  if (tmin > tmax)
143  {
144  return 0;
145  }
146  }
147  }
148  return 0x1;
149 #endif
150 }
151 
152 inline ndFloat32 ndFastRay::BoxIntersect(const ndVector& minBox, const ndVector& maxBox) const
153 {
154  ndVector test(((m_p0 <= minBox) | (m_p0 >= maxBox)) & m_isParallel);
155  if (test.GetSignMask() & 0x07)
156  {
157  return ndFloat32(1.2f);
158  }
159  ndVector tt0(m_dpInv * (minBox - m_p0));
160  ndVector tt1(m_dpInv * (maxBox - m_p0));
161  ndVector t0(m_minT.GetMax(tt0.GetMin(tt1)));
162  ndVector t1(m_maxT.GetMin(tt0.GetMax(tt1)));
163  t0 = t0.GetMax(t0.ShiftTripleRight());
164  t1 = t1.GetMin(t1.ShiftTripleRight());
165  t0 = t0.GetMax(t0.ShiftTripleRight());
166  t1 = t1.GetMin(t1.ShiftTripleRight());
167  ndVector mask(t0 < t1);
168  ndVector maxDist(ndFloat32(1.2f));
169  t0 = maxDist.Select(t0, mask);
170  ndAssert((mask.GetSignMask() & 1) == (t0.m_x < ndFloat32(1.0f)));
171  return t0.GetScalar();
172 }
173 
174 #endif
175 
ndClassAlloc
Base class for providing memory allocation for all other engine classes.
Definition: ndClassAlloc.h:30
ndRay
Definition: ndFastRay.h:32
ndFastRay
Definition: ndFastRay.h:48
ndClassAlloc::ndClassAlloc
ndClassAlloc()
Empty default constructor.
Definition: ndClassAlloc.h:33
ndVector
Definition: ndVectorArmNeon.h:41