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

📄 nmfileio.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
                       int count,            // number of items in the array
                       int* result) // buffer for the result of the last compare
{
   int high;
   int low;
   int mid;
   int nextMid;
   
   high = count;
   low = 0;
   mid = low + ((high - low) >> 1);
   *result = -1;

   while (low != high) 
   {
      *result = NmCompareD (value, &(data[indices[mid]])); 
      if (*result == 0)
      {
         break;
      }
      else if (*result < 0)
      {
         high = mid;
      }
      else
      {
         low = mid;
      }
     
      nextMid = low + ((high - low) >> 1);
      if (mid == nextMid)
      {
         break;
      }

      mid = nextMid;
   }

   return mid;
}

////////////////////////////////////////////////////////////////////
// Compute tangent space for the given triangle
////////////////////////////////////////////////////////////////////
static void
ComputeTangentVectorsD (NmRawTriangle* pgon, int idx,
                        double tan[3], double norm[3], double binorm[3])
{
   // Clear outputs.
   tan[0] = 1.0; tan[1] = 0.0; tan[2] = 0.0;
   binorm[0] = 0.0; binorm[1] = 0.0; binorm[2] = 1.0;
   norm[0] = pgon->norm[idx].x;
   norm[1] = pgon->norm[idx].y;
   norm[2] = pgon->norm[idx].z;

   // Make sure we have valid data.
   if (pgon->texCoord[0].u == 0.0 && 
       pgon->texCoord[1].u == 0.0 && 
       pgon->texCoord[2].u == 0.0)
   {
      return;
   }

   // Compute edge vectors.
   double vec1[3];
   vec1[0] = pgon->vert[1].x - pgon->vert[0].x;
   vec1[1] = pgon->vert[1].y - pgon->vert[0].y;
   vec1[2] = pgon->vert[1].z - pgon->vert[0].z;
   double vec2[3];
   vec2[0] = pgon->vert[2].x - pgon->vert[0].x;
   vec2[1] = pgon->vert[2].y - pgon->vert[0].y;
   vec2[2] = pgon->vert[2].z - pgon->vert[0].z;

   // Calculate u vector
   double u1 = pgon->texCoord[1].u - pgon->texCoord[0].u;
   double u2 = pgon->texCoord[2].u - pgon->texCoord[0].u;
   double v1 = pgon->texCoord[1].v - pgon->texCoord[0].v;
   double v2 = pgon->texCoord[2].v - pgon->texCoord[0].v;

   double a = (u1 - v1*u2/v2);
   if (a != 0.0)
   {
      a = 1.0/a;
   }
   double b = (u2 - v2*u1/v1);
   if (b != 0.0)
   {
      b = 1.0/b;
   }

   double duTmp[3];
   duTmp[0] = a*vec1[0] + b*vec2[0];
   duTmp[1] = a*vec1[1] + b*vec2[1];
   duTmp[2] = a*vec1[2] + b*vec2[2];
   double tmpf = 1.0 / sqrt((duTmp[0]*duTmp[0]) + (duTmp[1]*duTmp[1]) +
                               (duTmp[2]*duTmp[2]));
   duTmp[0] *= tmpf;
   duTmp[1] *= tmpf;
   duTmp[2] *= tmpf;

   // Calculate v vector
   a = (v1 - u1*v2/u2);
   if (a != 0.0)
   {
      a = 1.0/a;
   }
   b = (v2 - u2*v1/u1);
   if (b != 0.0)
   {
      b = 1.0/b;
   }

   double dvTmp[3];
   dvTmp[0] = a*vec1[0] + b*vec2[0];
   dvTmp[1] = a*vec1[1] + b*vec2[1];
   dvTmp[2] = a*vec1[2] + b*vec2[2];
   tmpf = 1.0 / sqrt((dvTmp[0]*dvTmp[0]) + (dvTmp[1]*dvTmp[1]) +
                      (dvTmp[2]*dvTmp[2]));
   dvTmp[0] *= tmpf;
   dvTmp[1] *= tmpf;
   dvTmp[2] *= tmpf;

   // Project the vector into the plane defined by the normal.
   tmpf = (duTmp[0]*norm[0]) + (duTmp[1]*norm[1]) + (duTmp[2]*norm[2]);
   tan[0] = duTmp[0] - (tmpf * norm[0]);
   tan[1] = duTmp[1] - (tmpf * norm[1]);
   tan[2] = duTmp[2] - (tmpf * norm[2]);
   tmpf = 1.0 / sqrt(tan[0]*tan[0] + tan[1]*tan[1] + tan[2]*tan[2]);
   tan[0] *= tmpf;
   tan[1] *= tmpf;
   tan[2] *= tmpf;

   tmpf = (dvTmp[0]*norm[0]) + (dvTmp[1]*norm[1]) + (dvTmp[2]*norm[2]);
   binorm[0] = dvTmp[0] - (tmpf * norm[0]);
   binorm[1] = dvTmp[1] - (tmpf * norm[1]);
   binorm[2] = dvTmp[2] - (tmpf * norm[2]);
   tmpf = 1.0 / sqrt(binorm[0]*binorm[0] + binorm[1]*binorm[1] +
                             binorm[2]*binorm[2]);
   binorm[0] *= tmpf;
   binorm[1] *= tmpf;
   binorm[2] *= tmpf;
} // end ComputeTangentVectors

////////////////////////////////////////////////////////////////////
// Copy data into a point structure
////////////////////////////////////////////////////////////////////
static void
NmCopyPointD (NmRawTriangle* tri, int v, NmTangentPointD* point)
{
   point->vertex[0] = tri->vert[v].x;
   point->vertex[1] = tri->vert[v].y;
   point->vertex[2] = tri->vert[v].z;
   point->normal[0] = tri->norm[v].x;
   point->normal[1] = tri->norm[v].y;
   point->normal[2] = tri->norm[v].z;
   point->uv[0] = tri->texCoord[v].u;
   point->uv[1] = tri->texCoord[v].v;
   double norm[3];
   ComputeTangentVectorsD (tri, v, point->tangent, norm, point->binormal);
   point->count = 1;
}

////////////////////////////////////////////////////////////////////
// Insert a point and get it's index.
////////////////////////////////////////////////////////////////////
static int
NmInsertD (NmRawTriangle* tri, int v, int* num, int* sortIndex,
           NmTangentPointD* point)
{
   // Make sure we have some stuff to check.
   int ret = 0;
   if ((*num) > 0)
   {
      // Copy point into available slot.
      NmTangentPointD* pt = &(point[(*num)]);
      NmCopyPointD (tri, v, pt);

      // Search for it.
      int compValue;
      int pos = NmIndexBinaryTraverseD (pt, point, sortIndex, (*num),
                                        &compValue);
      
      // Now see if we need to insert.
      if (compValue == 0)
      {
         point[sortIndex[pos]].tangent[0] += pt->tangent[0];
         point[sortIndex[pos]].tangent[1] += pt->tangent[1];
         point[sortIndex[pos]].tangent[2] += pt->tangent[2];
         point[sortIndex[pos]].binormal[0] += pt->binormal[0];
         point[sortIndex[pos]].binormal[1] += pt->binormal[1];
         point[sortIndex[pos]].binormal[2] += pt->binormal[2];
         point[sortIndex[pos]].count++;
         ret = sortIndex[pos];
      }
      else if (compValue < 0) // we are inserting before this index
      {
         ret = (*num);
         memmove (&(sortIndex[pos + 1]), &(sortIndex[pos]), 
                  ((*num) - pos) * sizeof(int));
         
         sortIndex[pos] = (*num);
         (*num)++;
      }
      else // we are appending after this index
      {
         ret = (*num);
         if (pos < ((*num) - 1))
         {
            memmove(&(sortIndex[pos + 2]), &(sortIndex[pos + 1]), 
                    ((*num) - pos - 1) * sizeof(int));
         }
         sortIndex[pos + 1] = (*num);
         (*num)++;
      }
   }
   else
   {  // First point just add it into our list.
      NmCopyPointD (tri, v, &(point[(*num)]));
      sortIndex[(*num)] = 0;
      ret = (*num);
      (*num)++;
   }
   return ret;
}

////////////////////////////////////////////////////////////////////
// Compute tangent space for the given triangle list
////////////////////////////////////////////////////////////////////
bool 
NmComputeTangentsD (int numTris, NmRawTriangle* tris, NmRawTangentSpaceD** tan)
{
   // Check inputs
   if ((numTris == 0) || (tris == NULL) || (tan == NULL))
   {
      return false;
   }

   // First we need to allocate up the tangent space storage
   (*tan) = new NmRawTangentSpaceD [numTris];
   if ((*tan) == NULL)
   {
      return false;
   }

   // Allocate storage structures
   NmIndex* index = new NmIndex [numTris];
   if (index == NULL)
   {
      return false;
   }
   int* sortIndex = new int [numTris*3]; // Brute force it
   NmTangentPointD* point = new NmTangentPointD [numTris*3]; // Brute force it
   if (point == NULL)
   {
      return false;
   }
   
   // Now go through finding matching vertices and computing tangents.
   int count = 0;
   int i;
   for (i = 0; i < numTris; i++)
   {
      for (int j = 0; j < 3; j++)
      {
         index[i].idx[j] = NmInsertD (&tris[i], j, &count, sortIndex, point);
      }      
   }

   // Next we renormalize
   for (i = 0; i < count; i++)
   {
      point[i].tangent[0] = point[i].tangent[0]/(double)point[i].count;
      point[i].tangent[1] = point[i].tangent[1]/(double)point[i].count;
      point[i].tangent[2] = point[i].tangent[2]/(double)point[i].count;
      NormalizeD (point[i].tangent);

      point[i].binormal[0] = point[i].binormal[0]/(double)point[i].count;
      point[i].binormal[1] = point[i].binormal[1]/(double)point[i].count;
      point[i].binormal[2] = point[i].binormal[2]/(double)point[i].count;
      NormalizeD (point[i].binormal);
   }

   // Copy tangent data into structures
   for (i = 0; i < numTris; i++)
   {
      for (int j = 0; j < 3; j++)
      {
         (*tan)[i].tangent[j].x = point[index[i].idx[j]].tangent[0];
         (*tan)[i].tangent[j].y = point[index[i].idx[j]].tangent[1];
         (*tan)[i].tangent[j].z = point[index[i].idx[j]].tangent[2];
         (*tan)[i].binormal[j].x = point[index[i].idx[j]].binormal[0];
         (*tan)[i].binormal[j].y = point[index[i].idx[j]].binormal[1];
         (*tan)[i].binormal[j].z = point[index[i].idx[j]].binormal[2];
      }
   }

   // Clean up
   delete [] index;
   delete [] sortIndex;
   delete [] point;

   // Success!
   return true;
} // end NmComputeTangent

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -