📄 nmfileio.cpp
字号:
/******************************************************************************
* 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 + -