#include "Node.h"
#include "glut.h"
#include <stdio.h>
FILE *file;
int g_num = 0;
Node::Node(void)
{
m_pNegChild = NULL;
m_pPosChild = NULL;
pPosMesh = NULL;
pNegMesh = NULL;
m_pMesh = NULL;
nDepth = 0;
m_vColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
Node::~Node(void)
{
m_ltClipFaces.clear();
if(m_pPosChild != NULL)
{
delete m_pPosChild;
}
if(m_pNegChild != NULL)
{
delete m_pNegChild;
}
if(m_pMesh != NULL)
{
delete m_pMesh;
}
}
void Node::CreateNodeTree(CMesh *pMesh, int nDepth, int *arr)
{
if(pMesh == 0)
return;
m_pMesh = pMesh;
m_vCenter = pMesh->GetCenter();
m_fRadius = pMesh->GetRadius();
m_vMin = pMesh->GetMin();
m_vMax = pMesh->GetMax();
this->nDepth = nDepth;
if(IsConvexSet(pMesh))
{
g_num++;
return;
}
else
{
m_vRender[0] = vec3(0.0f, 0.0f, 0.0f);
m_vRender[1] = vec3(0.0f, 0.0f, 0.0f);
m_vRender[2] = vec3(0.0f, 0.0f, 0.0f);
CalculateBestClipFace(m_vRender, pMesh);
m_vClipFace = GetFaceFrom3Points(m_vRender);
vec3 vTemp = vec3(m_vClipFace.x, m_vClipFace.y, m_vClipFace.z);
if(vTemp == vec3(0.0f, 0.0f, 0.0f))
{
for(int i=0; i<nDepth; i++)
{
int a = arr[i];
}
}
ClipMesh(m_vClipFace, pMesh, arr);
}
}
// 判断点与面的关系
int Node::CalculatePointSide(vec3 vPoint, vec3 *vClipFace)
{
vec4 vFace = GetFaceFrom3Points(vClipFace);
float fRes = vFace * vPoint -2.0f*vFace.v[3];
if(fRes > ELLIPSE)
{
return FORWARD;
}
else if(fRes < (-1.0f)*ELLIPSE)
{
return BACK;
}
else
{
return INSIDE;
}
}
int Node::CalculatePointSide(vec3 vPoint, vec4 &vClipFace)
{
float fRes = vClipFace*vPoint - 2.0f*vClipFace[3];
if(fRes > ELLIPSE)
{
return FORWARD;
}
else if(fRes < (-1.0f)*ELLIPSE)
{
return BACK;
}
else
{
return INSIDE;
}
}
// 判断面与分割面的关系
int Node::CalculateFaceSide(vec3 * vFace, vec3 * vClipFace)
{
int res[3];
for(int i=0; i<3; i++)
{
res[i] = CalculatePointSide(vFace[i], vClipFace);
}
if(res[0] >= 0 && res[1] >= 0 &&res[2] >= 0)
{
if(res[0]+res[1]+res[2] > 0)
{
return POSITIVE;
}
else
{
vec3 vNF = cross(vFace[1]-vFace[0], vFace[2]-vFace[0]);
vec3 vNC = cross(vClipFace[1]-vClipFace[0], vClipFace[2]-vClipFace[0]);
if(vNC *vNF > 0)
{
return POSITIVE;
}
else return NEGATIVE;
}
}
else if(res[0] <=0 && res[1] <= 0 && res[2] <=0)
{
return NEGATIVE;
}
else return SPANNING;
}
// 从三顶点得到面方程参数
vec4 Node::GetFaceFrom3Points(vec3 * vPoints)
{
if(vPoints[0].length() == 0 && vPoints[1].length() == 0 && vPoints[2].length() == 0)
{
vPoints[0] = vec3(0.0f, 0.0f, 0.0f);
}
vec3 v1 = vPoints[1] - vPoints[0];
vec3 v2 = vPoints[2] - vPoints[0];
vec3 vN = cross(v1, v2);
vN.normalize();
float fDis = vN*vPoints[0];
return vec4(vN, fDis);
}
// 获取最佳分割面
void Node::CalculateBestClipFace(vec3 * vFacePoints, CMesh * pMesh)
{
int fLeastSplits = LESTSPAN;
float fBestRelation;
float fMinRelation = 0.20f;
bool bFindFace = false;
while(fMinRelation > 0.001f)
{
fBestRelation = 0.0f;
bFindFace = false;
int numSurface = pMesh->GetNumSurfaces();
for(int i=0; i<numSurface; i++)
{
SSurface *pS1 = pMesh->GetSurfaces(i);
for(int j=0; j<pS1->numFaces; j++)
{
vec3 vClipFace[3];
vClipFace[0] = (pS1->pVertices[pS1->pIndices[3*j]]).xyz;
vClipFace[1] = (pS1->pVertices[pS1->pIndices[3*j+1]]).xyz;
vClipFace[2] = (pS1->pVertices[pS1->pIndices[3*j+2]]).xyz;
//////////////////////////////////////////////////////////////////////////////
//计算前后面的比率等信息
int numNegative = 0;
int numSpanning = 0;
int numPositive = 0;
for(int m=0; m<numSurface; m++)
{
SSurface *pS2 = pMesh->GetSurfaces(m);
for(int n=0; n<pS2->numFaces; n++)
{
vec3 vFace[3];
vFace[0] = (pS2->pVertices[pS2->pIndices[3*n]]).xyz;
vFace[1] = (pS2->pVertices[pS2->pIndices[3*n+1]]).xyz;
vFace[2] = (pS2->pVertices[pS2->pIndices[3*n+2]]).xyz;
int res = CalculateFaceSide(vFace, vClipFace);
if(res == POSITIVE)
{
numPositive++;
}
else if(res == NEGATIVE)
{
numNegative++;
}
else numSpanning++;
}
}
///////////////////////////////////////////////////////////////////
float fRelation = 0.0f;
if(numNegative > numPositive)
{
fRelation = (float)numPositive/(float)numNegative;
}
else
{
fRelation = (float)numNegative/(float)numPositive;
}
if( (fRelation >= fMinRelation) &&( (numSpanning < fLeastSplits) || ((numSpanning == fLeastSplits)&&fRelation>fBestRelation) ) )
{
fBestRelation = fRelation;
fLeastSplits = numSpanning;
vFacePoints[0] = vClipFace[0];
vFacePoints[1] = vClipFace[1];
vFacePoints[2] = vClipFace[2];
bFindFace = true;
}
}
}
if(bFindFace)
{
return;
}
fMinRelation /= 2.0f;
}
return;
}
// 用这个选好的面分割模型
void Node::ClipMesh(vec4 & vClipFace, CMesh * pMesh, int *arr)
{
pPosMesh = new CMesh();
pNegMesh = new CMesh();
int numSurfaces = pMesh->GetNumSurfaces();
for(int i=0; i<numSurfaces; i++)
{
SSurface *pSurface = pMesh->GetSurfaces(i);
int numFaces = pSurface->numFaces;
SVertex *pPositive = new SVertex[4*numFaces];
SVertex *pNegitive = new SVertex[4*numFaces];
int numPosV = 0;
int numNegV = 0;
int *pPosIndex = new int[6*numFaces];
int *pNegIndex = new int[6*numFaces];
int numPosI = 0;
int numNegI = 0;
SVertex vSrc[3];
SVertex vTPos[4];
SVertex vTNeg[4];
int numTPos = 0;
int numTNeg = 0;
for(int j=0; j<numFaces; j++)
{
vSrc[0] = pSurface->pVertices[pSurface->pIndices[3*j]];
vSrc[1] = pSurface->pVertices[pSurface->pIndices[3*j+1]];
vSrc[2] = pSurface->pVertices[pSurface->pIndices[3*j+2]];
ClipTriangle(vClipFace, vSrc, vTPos, numTPos, vTNeg, numTNeg);
if(numTNeg != 0 && numTNeg != 3 && numTNeg != 4)
{
return;
}
if(numTPos != 0 && numTPos != 3 && numTPos != 4)
{
return;
}
for(int k=0; k<numTPos; k++)
{
pPositive[numPosV++] = vTPos[k];
}
for(int k=0; k<numTNeg; k++)
{
pNegitive[numNegV++] = vTNeg[k];
}
//填充裁剪面前surface
if(numTPos == 3)
{
pPosIndex[numPosI++] = numPosV-3;
pPosIndex[numPosI++] = numPosV-2;
pPosIndex[numPosI++] = numPosV-1;
}
else if(numTPos == 4)
{
pPosIndex[numPosI++] = numPosV-4;
pPosIndex[numPosI++] = numPosV-3;
pPosIndex[numPosI++] = numPosV-2;
pPosIndex[numPosI++] = numPosV-4;
pPosIndex[numPosI++] = numPosV-2;
pPosIndex[numPosI++] = numPosV-1;
}
else{};
//填充裁剪面后surface
if(numTNeg == 3)
{
pNegIndex[numNegI++] = numNegV-3;
pNegIndex[numNegI++] = numNegV-2;
pNegIndex[numNegI++] = numNegV-1;
}
else if(numTNeg == 4)
{
pNegIndex[numNegI++] = numNegV-4;
pNegIndex[numNegI++] = numNegV-3;
pNegIndex[numNegI++] = numNegV-2;
pNegIndex[numNegI++] = numNegV-4;
pNegIndex[numNegI++] = numNegV-2;
pNegIndex[numNegI++] = numNegV-1;
}
else{};
}
if(numPosV > 0)
{
SSurface *pPosSurface = new SSurface();
pPosSurface->numFaces = numPosI/3;
pPosSurface->numVertices = numPosV;
pPosSurface->iTexId = pSurface->iTexId;
pPosSurface->material = pSurface->material;
pPosSurface->pIndices = new unsigned int[numPosI];
for(int i=0; i<numPosI; i++)
{
pPosSurface->pIndices[i] = pPosIndex[i];
}
pPosSurface->pVertices = new SVertex[numPosV];
for(int i=0; i<numPosV; i++)
{
pPosSurface->pVertices[i] = pPositive[i];
}
pPosMesh->AddSurface(pPosSurface);
}
if(numNegV > 0)
{
SSurface *pNegSurface = new SSurface();
pNegSurface->numFaces = numNegI/3;
pN