📄 normalmapper.cpp
字号:
{
return true;
}
return false;
case NORM_RULE_FRONT_CLOSEST:
// Pick the closest in front of the low res.
if ( (nIntersect->x >= -gEpsilon) &&
(nIntersect->x < gDistance) &&
(nIntersect->x < lIntersect->x) )
{
return true;
}
return false;
case NORM_RULE_BEST_CLOSEST:
// Pick the closest, if equal pick the one closer to low res norm
if ( (fabs(nIntersect->x) < gDistance) &&
(fabs(nIntersect->x) < fabs(lIntersect->x)) )
{
return true;
}
else if ( (fabs(nIntersect->x) < gDistance) &&
(fabs(nIntersect->x) == fabs(lIntersect->x)) &&
(VEC_DotProduct (nNorm, norm->v) >
VEC_DotProduct (lNorm, norm->v)) )
{
return true;
}
return false;
case NORM_RULE_FRONT_BEST_CLOSEST:
// Pick the closest in front of low res,
// if equal pick the one closer to low res norm
if ( (nIntersect->x >= -gEpsilon) &&
(nIntersect->x < gDistance) &&
(nIntersect->x < lIntersect->x) )
{
return true;
}
else if ( (nIntersect->x < gDistance) &&
(nIntersect->x == lIntersect->x) &&
(VEC_DotProduct (nNorm, norm->v) >
VEC_DotProduct (lNorm, norm->v)))
{
return true;
}
return false;
case NORM_RULE_FARTHEST:
// Pick the furthest
if ( (fabs(nIntersect->x) < gDistance) &&
(fabs(nIntersect->x) > fabs(lIntersect->x)) )
{
return true;
}
return false;
case NORM_RULE_FRONT_FURTHEST:
// Pick the furthest in front of low res
if ( (nIntersect->x >= -gEpsilon) &&
(nIntersect->x < gDistance) &&
(nIntersect->x > lIntersect->x))
{
return true;
}
return false;
case NORM_RULE_BEST_FARTHEST:
// Pick the furthest, if equal pick the one closer to low res norm
if ( (fabs (nIntersect->x) < gDistance) &&
(fabs(nIntersect->x) > fabs(lIntersect->x)) )
{
return true;
}
else if ( (fabs (nIntersect->x) < gDistance) &&
(fabs(nIntersect->x) == fabs(lIntersect->x)) &&
(VEC_DotProduct (nNorm, norm->v) >
VEC_DotProduct (lNorm, norm->v)) )
{
return true;
}
return false;
case NORM_RULE_FRONT_BEST_FURTHEST:
// Pick the furthest in front of low res,
// if equal pick the one closer to low res norm
if ( (nIntersect->x >= -gEpsilon) &&
(nIntersect->x < gDistance) &&
(nIntersect->x > lIntersect->x) )
{
return true;
}
else if ( (nIntersect->x < gDistance) &&
(fabs(nIntersect->x) == fabs(lIntersect->x)) &&
(VEC_DotProduct (nNorm, norm->v) >
VEC_DotProduct (lNorm, norm->v)) )
{
return true;
}
return false;
case NORM_RULE_MIXED:
// See if this is an intersection behind low res face
if (nIntersect->x <= 0)
{
// We prefer normals that are in front of the low res face, if
// the last intersection was in front ignore this one.
if (lIntersect->x > 0)
{
return false;
}
// Pick the closer of the two since this intersection is behind
// the low res face.
if ( (fabs (nIntersect->x) < gDistance) &&
(fabs(nIntersect->x) < fabs(lIntersect->x)) )
{
return true;
}
}
else // Intersection in front of low res face
{
// Pick the furthest intersection since the intersection is in
// front of the low res face.
if ( (fabs (nIntersect->x) < gDistance) &&
(fabs(nIntersect->x) > fabs(lIntersect->x)) )
{
return true;
}
}
return false;
case NORM_RULE_BEST_MIXED:
// See if this is an intersection behind low res face
if (nIntersect->x <= 0)
{
// We prefer normals that are in front of the low res face, if
// the last intersection was in front ignore this one.
if (lIntersect->x > 0)
{
return false;
}
// Pick the closer of the two since this intersection is behind
// the low res face. If the two intersections are equidistant
// pick the normal that more closely matches the low res normal
if ( (fabs (nIntersect->x) < gDistance) &&
(fabs(nIntersect->x) < fabs(lIntersect->x)) )
{
return true;
}
else if ( (fabs (nIntersect->x) < gDistance) &&
(fabs(nIntersect->x) == fabs(lIntersect->x)) &&
(VEC_DotProduct (nNorm, norm->v) >
VEC_DotProduct (lNorm, norm->v)) )
{
return true;
}
}
else // Intersection in front of low res face
{
// Pick the furthest intersection since the intersection is in
// front of the low res face. If they are equidistant pick the
// normal that most closely matches the low res normal.
if (fabs(nIntersect->x) > fabs(lIntersect->x))
{
return true;
}
else if ( (fabs (nIntersect->x) < gDistance) &&
(fabs(nIntersect->x) == fabs(lIntersect->x)) &&
(VEC_DotProduct (nNorm, norm->v) >
VEC_DotProduct (lNorm, norm->v)) )
{
return true;
}
}
return false;
case NORM_RULE_BEST:
// Pick the one closer to low res norm
if ( (fabs (nIntersect->x) < gDistance) &&
(VEC_DotProduct (nNorm, norm->v) >
VEC_DotProduct (lNorm, norm->v)) )
{
return true;
}
return false;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////////
// Normalize a vector
//////////////////////////////////////////////////////////////////////////////
void
Normalize(double v[3])
{
double len = sqrt((v[0]*v[0])+(v[1]*v[1])+(v[2]*v[2]));
if (len < EPSILON)
{
v[0] = 1.0f;
v[1] = 0.0f;
v[2] = 0.0f;
}
else
{
v[0] = v[0]/len;
v[1] = v[1]/len;
v[2] = v[2]/len;
}
}
//////////////////////////////////////////////////////////////////////////
// See if the ray intersects the triangle.
// Drew's adaption from Real Time Rendering
//////////////////////////////////////////////////////////////////////////
bool
IntersectTriangle(double *orig, double *dir,
float *v1, float *v2, float *v3,
double *t, double *u, double *v)
{
double edge1[3], edge2[3], tvec[3], pvec[3], qvec[3];
double det,inv_det;
// find vectors for two edges sharing vert0
VEC_Subtract(v2, v1, edge1);
VEC_Subtract(v3, v1, edge2);
// begin calculating determinant - also used to calculate U parameter
VEC_Cross(dir, edge2, pvec);
// if determinant is near zero, ray lies in plane of triangle
det = VEC_DotProduct(edge1, pvec);
// if (det > -gEpsilon && det < gEpsilon)
if (det == 0.0)
{
return false;
}
inv_det = 1.0 / det;
// calculate distance from vert0 to ray origin
VEC_Subtract(orig, v1, tvec);
// calculate U parameter and test bounds
*u = VEC_DotProduct(tvec, pvec) * inv_det;
//if (*u < 0.0 || *u > 1.0)
//if (*u < -0.1 || *u > 1.1)
//if ((*u < -EPSILON) || (*u > (1.0 + EPSILON)))
if (*u < -gEpsilon || *u > (1.0 + gEpsilon))
{
return false;
}
// prepare to test V parameter
VEC_Cross(tvec, edge1, qvec);
// calculate V parameter and test bounds
*v = VEC_DotProduct(dir, qvec) * inv_det;
//if ((*v < 0.0) || ((*u + *v) > 1.0))
//if ((*v < -0.1) || ((*u + *v) > 1.1))
//if ((*v < -EPSILON) || ((*u + *v) > (1.0 + EPSILON)))
if ((*v < -gEpsilon) || ((*u + *v) > (1.0 + gEpsilon)))
{
return false;
}
// calculate t, ray intersects triangle
*t = VEC_DotProduct(edge2, qvec) * inv_det;
return true;
}
/////////////////////////////////////
// Get edge info
/////////////////////////////////////
inline void
GetEdge (NmEdge* edge, NmRawTriangle* tri, int idx0, int idx1)
{
// Based on the Y/v coordinate fill in the structure.
if (tri->texCoord[idx0].v <= tri->texCoord[idx1].v)
{
edge->idx0 = idx0;
edge->idx1 = idx1;
edge->yMin = INT_ROUND_TEXCOORD_V (tri->texCoord[idx0].v);
edge->yMax = INT_ROUND_TEXCOORD_V (tri->texCoord[idx1].v);
edge->x = INT_ROUND_TEXCOORD_U (tri->texCoord[idx0].u);
edge->x1 = INT_ROUND_TEXCOORD_U (tri->texCoord[idx1].u);
edge->increment = edge->denominator = edge->yMax - edge->yMin;
edge->numerator = edge->x1 - edge->x;
}
else
{
edge->idx0 = idx1;
edge->idx1 = idx0;
edge->yMin = INT_ROUND_TEXCOORD_V (tri->texCoord[idx1].v);
edge->yMax = INT_ROUND_TEXCOORD_V (tri->texCoord[idx0].v);
edge->x = INT_ROUND_TEXCOORD_U (tri->texCoord[idx1].u);
edge->x1 = INT_ROUND_TEXCOORD_U (tri->texCoord[idx0].u);
edge->increment = edge->denominator = edge->yMax - edge->yMin;
edge->numerator = edge->x1 - edge->x;
}
} // GetEdge
///////////////////////////////////////////////////////////////////////////////
// Simple spinner display for progress indication
///////////////////////////////////////////////////////////////////////////////
int gSpinner = 0;
void
ShowSpinner (char* header = NULL)
{
char* lineStart = header;
if (header == NULL)
{
static char empty[] = "";
lineStart = empty;
}
switch (gSpinner)
{
case 0:
printf ("\r%s\\", lineStart);
gSpinner++;
break;
case 1:
printf ("\r%s|", lineStart);
gSpinner++;
break;
case 2:
printf ("\r%s/", lineStart);
gSpinner++;
break;
default:
case 3:
printf ("\r%s-", lineStart);
gSpinner = 0;
break;
}
}
////////////////////////////////////////////////////////////////////
// Multiply a 3x3 matrix with a 3 space vector (assuming w = 1), ignoring
// the last row of the matrix
////////////////////////////////////////////////////////////////////
void
ConvertFromTangentSpace (double* m, double *vec, double *result)
{
double tmp[3];
if ((result == NULL) || (vec == NULL))
return;
tmp[0] = vec[0]*m[0] + vec[1]*m[1] + vec[2]*m[2];
tmp[1] = vec[0]*m[3] + vec[1]*m[4] + vec[2]*m[5];
tmp[2] = vec[0]*m[6] + vec[1]*m[7] + vec[2]*m[8];
result[0] = tmp[0];
result[1] = tmp[1];
result[2] = tmp[2];
}
////////////////////////////////////////////////////////////////////
// Multiply a 3x3 matrix with a 3 space vector (assuming w = 1), ignoring
// the last row of the matrix
////////////////////////////////////////////////////////////////////
void
ConvertToTangentSpace (double* m, double *vec, double *result)
{
double tmp[3];
if ((result == NULL) || (vec == NULL))
return;
tmp[0] = vec[0]*m[0] + vec[1]*m[3] + vec[2]*m[6];
tmp[1] = vec[0]*m[1] + vec[1]*m[4] + vec[2]*m[7];
tmp[2] = vec[0]*m[2] + vec[1]*m[5] + vec[2]*m[8];
result[0] = tmp[0];
result[1] = tmp[1];
result[2] = tmp[2];
}
//////////////////////////////////////////////////////////////////////////
// Compute plane equation
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -