RavEngine
Loading...
Searching...
No Matches
GuCubeIndex.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#ifndef GU_CUBE_INDEX_H
30#define GU_CUBE_INDEX_H
31
32#include "foundation/PxVec3.h"
33#include "foundation/PxFPU.h"
34
35namespace physx
36{
37
38 enum CubeIndex
39 {
40 CUBE_RIGHT,
41 CUBE_LEFT,
42 CUBE_TOP,
43 CUBE_BOTTOM,
44 CUBE_FRONT,
45 CUBE_BACK,
46
47 CUBE_FORCE_DWORD = 0x7fffffff
48 };
49
50 /*
51 It's pretty straightforwards in concept (though the execution in hardware is
52 a bit crufty and complex). You use a 3D texture coord to look up a texel in
53 a cube map. First you find which of the axis has the largest value (i.e.
54 X,Y,Z), and then the sign of that axis decides which face you are going to
55 use. Which is why the faces are called +X, -X, +Y, -Y, +Z, -Z - after their
56 principle axis. Then you scale the vector so that the largest value is +/-1.
57 Then use the other two as 2D coords to look up your texel (with a 0.5 scale
58 & offset).
59
60 For example, vector (0.4, -0.2, -0.5). Largest value is the Z axis, and it's
61 -ve, so we're reading from the -Z map. Scale so that this Z axis is +/-1,
62 and you get the vector (0.8, -0.4, -1.0). So now use the other two values to
63 look up your texel. So we look up texel (0.8, -0.4). The scale & offset move
64 the -1->+1 range into the usual 0->1 UV range, so we actually look up texel
65 (0.9, 0.3). The filtering is extremely complex, especially where three maps
66 meet, but that's a hardware problem :-)
67 */
68
70
84 PX_INLINE CubeIndex CubemapLookup(const PxVec3& direction, float& u, float& v);
85
86 PX_INLINE PxU32 ComputeCubemapOffset(const PxVec3& dir, PxU32 subdiv)
87 {
88 float u,v;
89 const CubeIndex CI = CubemapLookup(dir, u, v);
90
91 // Remap to [0, subdiv[
92 const float Coeff = 0.5f * float(subdiv-1);
93 u += 1.0f; u *= Coeff;
94 v += 1.0f; v *= Coeff;
95
96 // Compute offset
97 return PxU32(CI)*(subdiv*subdiv) + PxU32(u)*subdiv + PxU32(v);
98 }
99
100
101 PX_INLINE PxU32 ComputeCubemapNearestOffset(const PxVec3& dir, PxU32 subdiv)
102 {
103 float u,v;
104 const CubeIndex CI = CubemapLookup(dir, u, v);
105
106 // Remap to [0, subdiv]
107 const float Coeff = 0.5f * float(subdiv-1);
108 u += 1.0f; u *= Coeff;
109 v += 1.0f; v *= Coeff;
110
111 // Compute offset
112 return PxU32(CI)*(subdiv*subdiv) + PxU32(u + 0.5f)*subdiv + PxU32(v + 0.5f);
113 }
114
115
116 PX_INLINE CubeIndex CubemapLookup(const PxVec3& direction, float& u, float& v)
117 {
118 const PxU32* binary = reinterpret_cast<const PxU32*>(&direction.x);
119
120 const PxU32 absPx = binary[0] & ~PX_SIGN_BITMASK;
121 const PxU32 absNy = binary[1] & ~PX_SIGN_BITMASK;
122 const PxU32 absNz = binary[2] & ~PX_SIGN_BITMASK;
123
124 PxU32 Index1 = 0; //x biggest axis
125 PxU32 Index2 = 1;
126 PxU32 Index3 = 2;
127 if( (absNy > absPx) & (absNy > absNz))
128 {
129 //y biggest
130 Index2 = 2;
131 Index3 = 0;
132 Index1 = 1;
133 }
134 else if(absNz > absPx)
135 {
136 //z biggest
137 Index2 = 0;
138 Index3 = 1;
139 Index1 = 2;
140 }
141
142 const PxF32* data = &direction.x;
143 const float Coeff = 1.0f / fabsf(data[Index1]);
144 u = data[Index2] * Coeff;
145 v = data[Index3] * Coeff;
146
147 const PxU32 Sign = binary[Index1]>>31;
148 return CubeIndex(Sign|(Index1+Index1));
149 }
150
151}
152
153#endif
3 Element vector class.
Definition PxVec3.h:50
#define PX_INLINE
Definition PxPreprocessor.h:320
Sorts an array of objects in ascending order, assuming that the predicate implements the < operator:
Definition PxBoxController.h:39
PX_INLINE CubeIndex CubemapLookup(const PxVec3 &direction, float &u, float &v)
Definition GuCubeIndex.h:116