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

📄 nmfileio.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
 *  NmFileIO.cpp -- File IO routines for normal mapper.
 ******************************************************************************
 $Header: //depot/3darg/Tools/NormalMapper/NmFileIO.cpp#11 $
 ******************************************************************************
 *  (C) 2000 ATI Research, Inc.  All rights reserved.
 ******************************************************************************/

#include <stdarg.h>
#include <stdlib.h>
#include <iostream.h>
#include <fstream.h>
#include <string.h>
#include <math.h>

#include "NmFileIO.h"

#define EPSILON 1.0e-7
static const double ATI_VERT_TINY = EPSILON;
static const double ATI_NORM_TINY = EPSILON;
static const double ATI_TEX_TINY = EPSILON;
static const double ATI_TAN_ANGLE = 0.3;

////////////////////////////////////////////////////////////////////
// Write a block of triangles to the file
////////////////////////////////////////////////////////////////////
bool
NmWriteTriangles (FILE* fp, int numTris, NmRawTriangle* tris)
{
   // Write the number of triangles.
   if (fwrite (&numTris, sizeof (int), 1, fp) != 1)
   {
      cerr << "Unable to write number of triangles\n";
      return false;
   }
   
   // Write the triangles.
   if (fwrite (tris, sizeof(NmRawTriangle), numTris, fp) !=
          (unsigned)numTris)
   {
      cerr << "Unable to write triangles\n";
      return false;
   }
   return true;
} // end NmWriteTriangles

////////////////////////////////////////////////////////////////////
// Read a block of triangles from the file
////////////////////////////////////////////////////////////////////
bool
NmReadTriangles (FILE* fp, int* numTris, NmRawTriangle** tris)
{
   // Read the number of triangles.
   if (fread (numTris, sizeof (int), 1, fp) != 1)
   {
      cerr << "Unable to read number of triangles\n";
      return false;
   }
   if ((*numTris) < 1)
   {
      cerr << "No triangles found in file\n";
      return false;
   }
   
   // Allocate space for triangles
   (*tris) = new NmRawTriangle [(*numTris)];
   if ((*tris) == NULL)
   {
      cerr << "Unable to allocate space for " << (*tris) << " triangles\n";
      return false;
   }

   // Now read the triangles into the allocated space.
   if (fread ((*tris), sizeof (NmRawTriangle), (*numTris), fp) != 
       (unsigned)(*numTris))
   {
      cerr << "Unable to read triangles\n";
#ifdef _DEBUG
      if (ferror (fp))
      {
         perror ("Read Triangles");
      }
      else if (feof (fp))
      {
         cerr << "End of file!\n";
      }
#endif
      return false;
   }
   
   // success
   return true;
} // end NmReadTriangles

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

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

   // Cheat and use the double version to compute then convert into floats
   NmRawTangentSpaceD* tanD;
   if (!NmComputeTangentsD(numTris, tris, &tanD))
   {
      return false;
   }

   // Now find tangent space
   for (int i = 0; i < numTris; i++)
   {
      for (int j = 0; j < 3; j++)
      {
         (*tan)[i].tangent[j].x = (float)(tanD[i].tangent[j].x);
         (*tan)[i].tangent[j].y = (float)(tanD[i].tangent[j].y);
         (*tan)[i].tangent[j].z = (float)(tanD[i].tangent[j].z);
         (*tan)[i].binormal[j].x = (float)(tanD[i].binormal[j].x);
         (*tan)[i].binormal[j].y = (float)(tanD[i].binormal[j].y);
         (*tan)[i].binormal[j].z = (float)(tanD[i].binormal[j].z);
      }
   }
   delete [] tanD;
   return true;
} // end NmComputeTangents

//==========================================================================
// Normalize a vector
//==========================================================================
static inline void
NormalizeD (double v[3])
{
   double len = sqrt((v[0]*v[0])+(v[1]*v[1])+(v[2]*v[2]));
   if (len < EPSILON)
   {
      v[0] = 1.0;
      v[1] = 0.0;
      v[2] = 0.0;
   }
   else
   {
      v[0] = v[0]/len;
      v[1] = v[1]/len;
      v[2] = v[2]/len;
   }
}

//==========================================================================
// Calculates the dot product of two vectors.
//==========================================================================
static inline double
DotProduct3D (double vectorA[3], double vectorB[3])
{
   return( (vectorA[0] * vectorB[0]) + (vectorA[1] * vectorB[1]) +
           (vectorA[2] * vectorB[2]) );
} // end of DotProduct

//=============================================================================
// Compare the values
//=============================================================================
static int
NmCompareD (NmTangentPointD* v0, NmTangentPointD* v1)
{
   if (fabs(v0->vertex[0] - v1->vertex[0]) > ATI_VERT_TINY)
   {
      if (v0->vertex[0] > v1->vertex[0])
      {
         return -1;
      }
      else
      {
         return 1;
      }
   }
   if (fabs(v0->vertex[1] - v1->vertex[1]) > ATI_VERT_TINY)
   {
      if (v0->vertex[1] > v1->vertex[1])
      {
         return -1;
      }
      else
      {
         return 1;
      }
   }
   if (fabs(v0->vertex[2] - v1->vertex[2]) > ATI_VERT_TINY)
   {
      if (v0->vertex[2] > v1->vertex[2])
      {
         return -1;
      }
      else
      {
         return 1;
      }
   }
   
   if (fabs(v0->normal[0] - v1->normal[0]) > ATI_NORM_TINY)
   {
      if (v0->normal[0] > v1->normal[0])
      {
         return -1;
      }
      else
      {
         return 1;
      }
   }
   if (fabs(v0->normal[1] - v1->normal[1]) > ATI_NORM_TINY)
   {
      if (v0->normal[1] > v1->normal[1])
      {
         return -1;
      }
      else
      {
         return 1;
      }
   }
   if (fabs(v0->normal[2] - v1->normal[2]) > ATI_NORM_TINY)
   {
      if (v0->normal[2] > v1->normal[2])
      {
         return -1;
      }
      else
      {
         return 1;
      }
   }

   if (fabs(v0->uv[0] - v1->uv[0]) > ATI_TEX_TINY)
   {
      if (v0->uv[0] > v1->uv[0])
      {
         return -1;
      }
      else
      {
         return 1;
      }
   }
   if (fabs(v0->uv[1] - v1->uv[1]) > ATI_TEX_TINY)
   {
      if (v0->uv[1] > v1->uv[1])
      {
         return -1;
      }
      else
      {
         return 1;
      }
   }
   double t0[3] = {v0->tangent[0], v0->tangent[1], v0->tangent[2]};
   NormalizeD (t0);
   double t1[3] = {v1->tangent[0], v1->tangent[1], v1->tangent[2]};
   NormalizeD (t1);
   double dp3 = DotProduct3D (t0, t1);
   if (dp3 < ATI_TAN_ANGLE)
   {
      if (dp3 < 0.0)
      {
         return -1;
      }
      else
      {
         return 1;
      }
   }
   double b0[3] = {v0->binormal[0], v0->binormal[1], v0->binormal[2]};
   NormalizeD (b0);
   double b1[3] = {v1->binormal[0], v1->binormal[1], v1->binormal[2]};
   NormalizeD (b1);
   dp3 = DotProduct3D (b0, b1);
   if (dp3 < ATI_TAN_ANGLE)
   {
      if (dp3 < 0.0)
      {
         return -1;
      }
      else
      {
         return 1;
      }
   }
   return 0;
}

//=============================================================================
// Binary traversal function
//=============================================================================
static int 
NmIndexBinaryTraverseD(NmTangentPointD* value, // The reference element
                       NmTangentPointD* data,// pointer to the indexed data
                       int* indices,         // pointer index

⌨️ 快捷键说明

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