RavEngine
Loading...
Searching...
No Matches
GuBV4_BoxSweep_Params.h
1// Redistribution and use in source and binary forms, with or without
2// modification, are permitted provided that the following conditions
3// are met:
4// * Redistributions of source code must retain the above copyright
5// notice, this list of conditions and the following disclaimer.
6// * Redistributions in binary form must reproduce the above copyright
7// notice, this list of conditions and the following disclaimer in the
8// documentation and/or other materials provided with the distribution.
9// * Neither the name of NVIDIA CORPORATION nor the names of its
10// contributors may be used to endorse or promote products derived
11// from this software without specific prior written permission.
12//
13// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
14// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24//
25// Copyright (c) 2008-2022 NVIDIA Corporation. All rights reserved.
26// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved.
27// Copyright (c) 2001-2004 NovodeX AG. All rights reserved.
28
29// This is used by the box-sweep & capsule-sweep code
30
31#if PX_VC
32 #pragma warning(disable: 4505) // unreferenced local function has been removed
33#endif
34
35#include "foundation/PxBasicTemplates.h"
36
37namespace
38{
39#ifdef SWEEP_AABB_IMPL
40struct BoxSweepParams : RayParams
41#else
42struct BoxSweepParams : OBBTestParams
43#endif
44{
45 const IndTri32* PX_RESTRICT mTris32;
46 const IndTri16* PX_RESTRICT mTris16;
47 const PxVec3* PX_RESTRICT mVerts;
48
49#ifndef SWEEP_AABB_IMPL
50 Box mLocalBox;
51#endif
52 PxVec3 mLocalDir_Padded;
53 RaycastHitInternal mStabbedFace;
54
55 PxU32 mBackfaceCulling;
56 PxU32 mEarlyExit;
57
58 PxVec3 mP0, mP1, mP2;
59 PxVec3 mBestTriNormal;
60
61 float mOffset;
62 PxVec3 mProj;
63 PxVec3 mDP;
64
65#ifndef SWEEP_AABB_IMPL
66 PxMat33 mAR;
67#endif
68
69 PxMat33 mRModelToBox_Padded;
70 PxVec3 mTModelToBox_Padded;
71 PxVec3 mOriginalExtents_Padded;
72 PxVec3 mOriginalDir_Padded;
73 PxVec3 mOneOverDir_Padded;
74 PxVec3 mOneOverOriginalDir;
75
76#ifndef SWEEP_AABB_IMPL
77 PX_FORCE_INLINE void ShrinkOBB(float d)
78 {
79 const PxVec3 BoxExtents = mDP + d * mProj;
80 mTBoxToModel_PaddedAligned = mLocalBox.center + mLocalDir_Padded*d*0.5f;
81
82 setupBoxData(this, BoxExtents, &mAR);
83 }
84#endif
85};
86}
87
88// PT: TODO: check asm again in PhysX version, compare to original (TA34704)
89static void prepareSweepData(const Box& box, const PxVec3& dir, float maxDist, BoxSweepParams* PX_RESTRICT params)
90{
91 invertBoxMatrix(params->mRModelToBox_Padded, params->mTModelToBox_Padded, box);
92
93 params->mOriginalExtents_Padded = box.extents;
94
95 const PxVec3 OriginalDir = params->mRModelToBox_Padded.transform(dir);
96 params->mOriginalDir_Padded = OriginalDir;
97
98 const PxVec3 OneOverOriginalDir(OriginalDir.x!=0.0f ? 1.0f/OriginalDir.x : 0.0f,
99 OriginalDir.y!=0.0f ? 1.0f/OriginalDir.y : 0.0f,
100 OriginalDir.z!=0.0f ? 1.0f/OriginalDir.z : 0.0f);
101
102 params->mOneOverOriginalDir = OneOverOriginalDir;
103 params->mOneOverDir_Padded = OneOverOriginalDir / maxDist;
104
105 {
106 const Box& LocalBox = box;
107 const PxVec3& LocalDir = dir;
108
109 params->mLocalDir_Padded = LocalDir;
110 params->mStabbedFace.mDistance = maxDist;
111#ifndef SWEEP_AABB_IMPL
112 params->mLocalBox = LocalBox; // PT: TODO: check asm for operator=
113#endif
114
115 PxMat33 boxToModelR;
116
117 // Original code:
118 // OBB::CreateOBB(LocalBox, LocalDir, 0.5f)
119 {
120 PxVec3 R1, R2;
121 {
122 float dd[3];
123 dd[0] = fabsf(LocalBox.rot.column0.dot(LocalDir));
124 dd[1] = fabsf(LocalBox.rot.column1.dot(LocalDir));
125 dd[2] = fabsf(LocalBox.rot.column2.dot(LocalDir));
126 float dmax = dd[0];
127 PxU32 ax0=1;
128 PxU32 ax1=2;
129 if(dd[1]>dmax)
130 {
131 dmax=dd[1];
132 ax0=0;
133 ax1=2;
134 }
135 if(dd[2]>dmax)
136 {
137 dmax=dd[2];
138 ax0=0;
139 ax1=1;
140 }
141 if(dd[ax1]<dd[ax0])
142 PxSwap(ax0, ax1);
143
144 R1 = LocalBox.rot[ax0];
145 R1 -= R1.dot(LocalDir)*LocalDir; // Project to plane whose normal is dir
146 R1.normalize();
147 R2 = LocalDir.cross(R1);
148 }
149 // Original code:
150 // mRot = params->mRBoxToModel
151 boxToModelR.column0 = LocalDir;
152 boxToModelR.column1 = R1;
153 boxToModelR.column2 = R2;
154
155 // Original code:
156 // float Offset[3];
157 // 0.5f comes from the Offset[r]*0.5f, doesn't mean 'd' is 0.5f
158 params->mProj.x = 0.5f;
159 params->mProj.y = LocalDir.dot(R1)*0.5f;
160 params->mProj.z = LocalDir.dot(R2)*0.5f;
161
162 // Original code:
163 //mExtents[r] = Offset[r]*0.5f + fabsf(box.mRot[0]|R)*box.mExtents.x + fabsf(box.mRot[1]|R)*box.mExtents.y + fabsf(box.mRot[2]|R)*box.mExtents.z;
164 // => we store the first part of the computation, minus 'Offset[r]*0.5f'
165 for(PxU32 r=0;r<3;r++)
166 {
167 const PxVec3& R = boxToModelR[r];
168 params->mDP[r] = fabsf(LocalBox.rot.column0.dot(R)*LocalBox.extents.x)
169 + fabsf(LocalBox.rot.column1.dot(R)*LocalBox.extents.y)
170 + fabsf(LocalBox.rot.column2.dot(R)*LocalBox.extents.z);
171 }
172 // In the original code, both mCenter & mExtents depend on 'd', and thus we will need to recompute these two members.
173 //
174 // For mExtents we have:
175 //
176 // float Offset[3];
177 // Offset[0] = d;
178 // Offset[1] = d*(dir|R1);
179 // Offset[2] = d*(dir|R2);
180 //
181 // mExtents[r] = Offset[r]*0.5f + fabsf(box.mRot[0]|R)*box.mExtents.x + fabsf(box.mRot[1]|R)*box.mExtents.y + fabsf(box.mRot[2]|R)*box.mExtents.z;
182 // <=> mExtents[r] = Offset[r]*0.5f + Params.mDP[r]; We precompute the second part that doesn't depend on d, stored in mDP
183 // <=> mExtents[r] = Params.mProj[r]*d + Params.mDP[r]; We extract d from the first part, store what is left in mProj
184 //
185 // Thus in ShrinkOBB the code needed to update the extents is just:
186 // mBoxExtents = mDP + d * mProj;
187 //
188 // For mCenter we have:
189 //
190 // mCenter = box.mCenter + dir*d*0.5f;
191 //
192 // So we simply use this formula directly, with the new d. Result is stored in 'mTBoxToModel'
193/*
194 PX_FORCE_INLINE void ShrinkOBB(float d)
195 {
196 mBoxExtents = mDP + d * mProj;
197 mTBoxToModel = mLocalBox.mCenter + mLocalDir*d*0.5f;
198*/
199 }
200
201 // This one is for culling tris, unrelated to CreateOBB
202 params->mOffset = params->mDP.x + LocalBox.center.dot(LocalDir);
203
204#ifndef SWEEP_AABB_IMPL
205 precomputeData(params, &params->mAR, &boxToModelR);
206
207 params->ShrinkOBB(maxDist);
208#endif
209 }
210}
#define PX_RESTRICT
Definition PxPreprocessor.h:355
#define PX_FORCE_INLINE
Definition PxPreprocessor.h:335
Definition GuBV4_BoxOverlap_Internal.h:79
Definition GuBV4_BoxSweep_Internal.h:42