HDK
Main Page
Related Pages
Modules
Namespaces
Classes
Files
Examples
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Groups
Pages
GU_MikkT.h
Go to the documentation of this file.
1
/*
2
* PROPRIETARY INFORMATION. This software is proprietary to
3
* Side Effects Software Inc., and is not to be reproduced,
4
* transmitted, or disclosed in any way without written permission.
5
*
6
* NAME: GU_MikkT.C
7
*
8
* COMMENTS: contains an implementation of Morten Mikkelsen's tangent space
9
* generation for normal mapping as well as an GU interface to the
10
* generator.
11
*/
12
13
/** \file mikktspace/mikktspace.h
14
* \ingroup mikktspace
15
*/
16
/**
17
* Copyright (C) 2011 by Morten S. Mikkelsen
18
*
19
* This software is provided 'as-is', without any express or implied
20
* warranty. In no event will the authors be held liable for any damages
21
* arising from the use of this software.
22
*
23
* Permission is granted to anyone to use this software for any purpose,
24
* including commercial applications, and to alter it and redistribute it
25
* freely, subject to the following restrictions:
26
*
27
* 1. The origin of this software must not be misrepresented; you must not
28
* claim that you wrote the original software. If you use this software
29
* in a product, an acknowledgment in the product documentation would be
30
* appreciated but is not required.
31
* 2. Altered source versions must be plainly marked as such, and must not be
32
* misrepresented as being the original software.
33
* 3. This notice may not be removed or altered from any source distribution.
34
*/
35
36
#ifndef __GU_MIKKTSPACE_H__
37
#define __GU_MIKKTSPACE_H__
38
39
#include "
GU_API.h
"
40
#include <
GA/GA_Handle.h
>
41
#include <
UT/UT_Vector3.h
>
42
43
namespace
GU
44
{
45
46
#define TFALSE 0
47
#define TTRUE 1
48
49
#define INTERNAL_RND_SORT_SEED 39871946
50
51
/* Author: Morten S. Mikkelsen
52
* Version: 1.0
53
*
54
* The files mikktspace.h and mikktspace.c are designed to be
55
* stand-alone files and it is important that they are kept this way.
56
* Not having dependencies on structures/classes/libraries specific
57
* to the program, in which they are used, allows them to be copied
58
* and used as is into any tool, program or plugin.
59
* The code is designed to consistently generate the same
60
* tangent spaces, for a given mesh, in any tool in which it is used.
61
* This is done by performing an internal welding step and subsequently an
62
* order-independent evaluation of tangent space for meshes consisting of
63
* triangles and quads. This means faces can be received in any order and the
64
* same is true for the order of vertices of each face. The generated result
65
* will not be affected by such reordering. Additionally, whether degenerate
66
* (vertices or texture coordinates) primitives are present or not will not
67
* affect the generated results either. Once tangent space calculation is done
68
* the vertices of degenerate primitives will simply inherit tangent space from
69
* neighboring non degenerate primitives. The analysis behind this
70
* implementation can be found in my master's thesis which is available for
71
* download --> http://image.diku.dk/projects/media/morten.mikkelsen.08.pdf Note
72
* that though the tangent spaces at the vertices are generated in an
73
* order-independent way, by this implementation, the interpolated tangent space
74
* is still affected by which diagonal is chosen to split each quad. A sensible
75
* solution is to have your tools pipeline always split quads by the shortest
76
* diagonal. This choice is order-independent and works with mirroring. If these
77
* have the same length then compare the diagonals defined by the texture
78
* coordinates. XNormal which is a tool for baking normal maps allows you to
79
* write your own tangent space plugin and also quad triangulator plugin.
80
*/
81
82
typedef
int
tbool
;
83
typedef
struct
SMikkTSpaceContext
SMikkTSpaceContext
;
84
85
typedef
struct
86
{
87
// Returns the number of faces (triangles/quads) on the mesh to be
88
// processed.
89
int
(*m_getNumFaces)(
const
SMikkTSpaceContext
*pContext);
90
91
// Returns the number of vertices on face number iFace
92
// iFace is a number in the range {0, 1, ..., getNumFaces()-1}
93
int
(*m_getNumVerticesOfFace)(
94
const
SMikkTSpaceContext
*pContext,
95
const
int
iFace);
96
97
// returns the position/normal/texcoord of the referenced face of vertex
98
// number iVert. iVert is in the range {0,1,2} for triangles and {0,1,2,3}
99
// for quads.
100
void
(*m_getPosition)(
101
const
SMikkTSpaceContext
*pContext,
102
float
fvPosOut[],
103
const
int
iFace,
104
const
int
iVert);
105
void
(*m_getNormal)(
106
const
SMikkTSpaceContext
*pContext,
107
float
fvNormOut[],
108
const
int
iFace,
109
const
int
iVert);
110
void
(*m_getTexCoord)(
111
const
SMikkTSpaceContext
*pContext,
112
float
fvTexcOut[],
113
const
int
iFace,
114
const
int
iVert);
115
116
// either (or both) of the two setTSpace callbacks can be set.
117
// The call-back m_setTSpaceBasic() is sufficient for basic normal mapping.
118
119
// This function is used to return the tangent and fSign to the application.
120
// fvTangent is a unit length vector.
121
// For normal maps it is sufficient to use the following simplified version
122
// of the bitangent which is generated at pixel/vertex level. bitangent =
123
// fSign * cross(vN, tangent); Note that the results are returned unindexed.
124
// It is possible to generate a new index list But averaging/overwriting
125
// tangent spaces by using an already existing index list WILL produce
126
// INCRORRECT results. DO NOT! use an already existing index list.
127
void
(*m_setTSpaceBasic)(
128
const
SMikkTSpaceContext
*pContext,
129
const
float
fvTangent[],
130
const
float
fSign,
131
const
int
iFace,
132
const
int
iVert);
133
134
// This function is used to return tangent space results to the application.
135
// fvTangent and fvBiTangent are unit length vectors and fMagS and fMagT are
136
// their true magnitudes which can be used for relief mapping effects.
137
// fvBiTangent is the "real" bitangent and thus may not be perpendicular to
138
// fvTangent. However, both are perpendicular to the vertex normal. For
139
// normal maps it is sufficient to use the following simplified version of
140
// the bitangent which is generated at pixel/vertex level. fSign =
141
// bIsOrientationPreserving ? 1.0f : (-1.0f); bitangent = fSign * cross(vN,
142
// tangent); Note that the results are returned unindexed. It is possible to
143
// generate a new index list But averaging/overwriting tangent spaces by
144
// using an already existing index list WILL produce INCRORRECT results. DO
145
// NOT! use an already existing index list.
146
void
(*m_setTSpace)(
147
const
SMikkTSpaceContext
*pContext,
148
const
float
fvTangent[],
149
const
float
fvBiTangent[],
150
const
float
fMagS,
151
const
float
fMagT,
152
const
tbool
bIsOrientationPreserving,
153
const
int
iFace,
154
const
int
iVert);
155
156
int
(*m_getPositionIndex)(
157
const
SMikkTSpaceContext
*pContext,
158
const
int
iVert);
159
int
(*m_getPositionVertex)(
160
const
SMikkTSpaceContext
*pContext,
161
const
int
iPoint,
162
const
int
iVert);
163
int
(*m_getPositionVertices)(
164
const
SMikkTSpaceContext
*pContext,
165
const
int
iPoint);
166
int
(*m_getPositionFaces)(
167
const
SMikkTSpaceContext
*pContext,
168
const
int
iPoint);
169
void
(*m_getPositionFacesArr)(
170
const
SMikkTSpaceContext
*pContext,
171
const
int
iPoint,
172
int
*&faces);
173
void
(*m_addPositionFace)(
174
const
SMikkTSpaceContext
*pContext,
175
const
int
iPoint,
176
int
face);
177
void
(*m_setPointFaceMapSize)(
178
const
SMikkTSpaceContext
*pContext,
179
const
int
size
);
180
181
// This flag is used to set whether or not UT_Hashmaps will be used when
182
// handling tangent space assignments for degenerate triangles
183
tbool
m_useHashmap
;
184
185
// This flag is used to set whether or not a point cache will be used
186
// when handling vertex merging. The point cache is expected to be
187
// set-up before calling genTangSpace() by calling initCache()
188
// from MikkTUserData
189
tbool
m_usePointCache
;
190
191
// This flag is used to set whether or not a point to face map will be
192
// used when building a list of neighboring triangles
193
tbool
m_usePointFaceMap
;
194
}
SMikkTSpaceInterface
;
195
196
struct
SMikkTSpaceContext
197
{
198
SMikkTSpaceInterface
*
m_pInterface
;
// initialized with callback functions
199
void
*
m_pUserData
;
// pointer to client side mesh data etc. (passed as the
200
// first parameter with every interface call)
201
};
202
203
// these are both thread safe!
204
GU_API
205
tbool
genTangSpaceDefault
(
206
const
SMikkTSpaceContext
207
*pContext);
// Default (recommended) fAngularThreshold is 180
208
// degrees (which means threshold disabled)
209
GU_API
210
tbool
genTangSpace
(
211
const
SMikkTSpaceContext
*pContext,
212
const
float
fAngularThreshold);
213
214
// To avoid visual errors (distortions/unwanted hard edges in lighting), when
215
// using sampled normal maps, the normal map sampler must use the exact inverse
216
// of the pixel shader transformation. The most efficient transformation we can
217
// possibly do in the pixel shader is achieved by using, directly, the
218
// "unnormalized" interpolated tangent, bitangent and vertex normal: vT, vB and
219
// vN. pixel shader (fast transform out) vNout = normalize( vNt.x * vT + vNt.y *
220
// vB + vNt.z * vN ); where vNt is the tangent space normal. The normal map
221
// sampler must likewise use the interpolated and "unnormalized" tangent,
222
// bitangent and vertex normal to be compliant with the pixel shader. sampler
223
// does (exact inverse of pixel shader): float3 row0 = cross(vB, vN); float3
224
// row1 = cross(vN, vT); float3 row2 = cross(vT, vB); float fSign = dot(vT,
225
// row0)<0 ? -1 : 1; vNt = normalize( fSign * float3(dot(vNout,row0),
226
// dot(vNout,row1), dot(vNout,row2)) ); where vNout is the sampled normal in
227
// some chosen 3D space.
228
//
229
// Should you choose to reconstruct the bitangent in the pixel shader instead
230
// of the vertex shader, as explained earlier, then be sure to do this in the
231
// normal map sampler also. Finally, beware of quad triangulations. If the
232
// normal map sampler doesn't use the same triangulation of quads as your
233
// renderer then problems will occur since the interpolated tangent spaces will
234
// differ eventhough the vertex level tangent spaces match. This can be solved
235
// either by triangulating before sampling/exporting or by using the
236
// order-independent choice of diagonal for splitting quads suggested earlier.
237
// However, this must be used both by the sampler and your tools/rendering
238
// pipeline.
239
240
}
// end namespace GU
241
242
class
GU_Detail
;
243
class
GA_PrimitiveGroup
;
244
class
GA_PointGroup
;
245
246
class
GU_API
GU_MikkT
247
{
248
public
:
249
250
//! Compute MikkT tangents
251
/// The result of the computation will be written out to per-vertex
252
/// attributes: tangents, bitangents, and signs. Not all output handles
253
/// need to be valid (invalid handles will be ignored).
254
static
bool
computeTangentsBasic(
const
GU_Detail
*gdp,
255
const
GA_PrimitiveGroup
*group,
256
const
UT_StringHolder
&uvattrname,
257
const
GA_RWHandleV3
&tangents,
258
const
GA_RWHandleV3
&bitangents,
259
const
GA_RWHandleF
&signs);
260
261
static
bool
computeTangentsBasic(
const
GU_Detail
*gdp,
262
const
GA_PrimitiveGroup
*group,
263
const
GA_PointGroup
*ptgroup,
264
const
UT_StringHolder
&uvattrname,
265
const
GA_RWHandleV3
&tangents,
266
const
GA_RWHandleV3
&bitangents,
267
const
GA_RWHandleF
&signs);
268
};
269
270
#endif
int
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
GA_PrimitiveGroup
Definition:
GA_ElementGroup.h:74
void
void
Definition:
png.h:1083
GU::SMikkTSpaceInterface::m_useHashmap
tbool m_useHashmap
Definition:
GU_MikkT.h:183
UT_Vector3.h
GU::SMikkTSpaceContext
Definition:
GU_MikkT.h:196
GU::SMikkTSpaceContext::m_pInterface
SMikkTSpaceInterface * m_pInterface
Definition:
GU_MikkT.h:198
GU::SMikkTSpaceContext::m_pUserData
void * m_pUserData
Definition:
GU_MikkT.h:199
GU::SMikkTSpaceInterface::m_usePointFaceMap
tbool m_usePointFaceMap
Definition:
GU_MikkT.h:193
GA_PointGroup
Definition:
GA_ElementGroup.h:33
GU_MikkT
Definition:
GU_MikkT.h:246
GU::genTangSpaceDefault
GU_API tbool genTangSpaceDefault(const SMikkTSpaceContext *pContext)
UT_StringHolder
Definition:
UT_StringHolder.h:999
GA_RWHandleT< UT_Vector3F >
GA_Handle.h
GU_API
#define GU_API
Definition:
GU_API.h:14
size
GLsizeiptr size
Definition:
glcorearb.h:664
GU::SMikkTSpaceInterface::m_usePointCache
tbool m_usePointCache
Definition:
GU_MikkT.h:189
GU_Detail
Definition:
GU_Detail.h:154
GU::SMikkTSpaceInterface
Definition:
GU_MikkT.h:85
GU_API.h
GU::tbool
int tbool
Definition:
GU_MikkT.h:82
GU::genTangSpace
GU_API tbool genTangSpace(const SMikkTSpaceContext *pContext, const float fAngularThreshold)
GU
GU_MikkT.h
Generated on Sun Nov 17 2024 03:01:17 for HDK by
1.8.6