⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 normalmapper.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            {
               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 + -