📄 bsputil.cpp
字号:
//-----------------------------------------------------------------------------
#include "bsputil.h"
//-----------------------------------------------------------------------------
GLvertexDataX *GlobalVertexList[MAX_VERTICES];
GLvertexCoordX *GlobalCoordList[MAX_VERTICES];
GLbeadTreeX GlobalPolygonList[MAX_FACES];
//-----------------------------------------------------------------------------
void CBSPUtil::CalculatePlane (GLbeadPolygon *face)
{
GLvertex *coord1, *coord2;
GLplane *plane;
GLint *vtxlist;
GLdouble nx, ny, nz, len, d;
GLint i;
nx = ny = nz = 0.0;
vtxlist = &(face -> vertices[0]);
i = face -> totalVertices;
while (i--) {
coord1 = GetVertexCoord (*(vtxlist));
coord2 = GetVertexCoord (*(vtxlist+1));
vtxlist++;
nx += ((coord1 -> y - coord2 -> y) * (coord1 -> z + coord2 -> z));
ny += ((coord1 -> z - coord2 -> z) * (coord1 -> x + coord2 -> x));
nz += ((coord1 -> x - coord2 -> x) * (coord1 -> y + coord2 -> y));
}
plane = &(face -> normal);
len = 1.0 / (sqrt(nx * nx + ny * ny + nz * nz));
plane -> a = (GLfloat) (nx * len);
plane -> b = (GLfloat) (ny * len);
plane -> c = (GLfloat) (nz * len);
d = 0.0;
vtxlist = &(face -> vertices[0]);
i = face -> totalVertices;
while (i--) {
coord1 = GetVertexCoord (*(vtxlist));
vtxlist++;
d -= (nx * coord1 -> x + ny * coord1 -> y + nz * coord1 -> z);
}
len = (len * d) / face -> totalVertices;
plane -> d = (GLfloat) len;
}
GLbeadTree *CBSPUtil::allocateBead ()
{
GLbeadTree *bead = (GLbeadTree *) glAllocateMemory (sizeof(GLbeadTree));
if (!bead) {
DisplayErrorMessage ((GLbyte *) "Can not allocate bead memory\n");
return 0;
}
bead -> child = bead -> next = 0;
bead -> beadElement = 0;
bead -> type = BEAD_TYPE_UNDEFINED;
return bead;
}
GLbeadPolygon *CBSPUtil::allocatePolygon (GLint totalvert)
{
GLint i = sizeof (GLbeadPolygon) + (totalvert * sizeof(GLint));
GLbeadPolygon *poly = (GLbeadPolygon *) glAllocateMemory (i);
if (!poly) {
DisplayErrorMessage ((GLbyte *) "Can not allocate memory for Polygon\n");
return 0;
}
return poly;
}
void CBSPUtil::Setup ()
{
VertexIndex = -1;
TotalPolygon = 0;
}
void CBSPUtil::Cleanup ()
{
}
void CBSPUtil::InsertPolygon (GLbeadTree *bead)
{
if (TotalPolygon < MAX_FACES) {
GlobalPolygonList[TotalPolygon].usedflag = 1;
GlobalPolygonList[TotalPolygon].bead = bead;
TotalPolygon++;
}
else
DisplayErrorMessage ((GLbyte *) "Total polygons exceed the maximum allowed\n");
}
void CBSPUtil::SetVertexDofPtr (void *dataptr)
{
GLint i;
for (i = 0; i <= VertexIndex; i++) {
GlobalCoordList[i] -> coord.dataptr = dataptr;
}
}
GLint CBSPUtil::InsertVertex (GLvertexData *vtx, GLvertex *coord, GLint flag, void *dataptr)
{
if (VertexIndex >= MAX_VERTICES-1) {
DisplayErrorMessage ((GLbyte *) "Total vertices exceed the maximum allowed\n");
return -1;
}
GLvertexDataX *newvtx = (GLvertexDataX *) glAllocateMemory (sizeof (GLvertexDataX));
if (!newvtx) {
DisplayErrorMessage ((GLbyte *) "Can not allocate vertex memory\n");
return -1;
}
GLvertexCoordX *newcoord = (GLvertexCoordX *) glAllocateMemory (sizeof (GLvertexCoordX));
if (!newcoord) {
DisplayErrorMessage ((GLbyte *) "Can not allocate coord memory\n");
return -1;
}
++VertexIndex;
newcoord -> coord.vtx = *coord;
newcoord -> coord.flag = flag;
newcoord -> coord.dataptr = dataptr;
newcoord -> flag = 0;
newvtx -> vd = *vtx;
newvtx -> vd.vtxindex = VertexIndex;
newvtx -> usedflag = 0;
GlobalVertexList[VertexIndex] = newvtx;
GlobalCoordList[VertexIndex] = newcoord;
return VertexIndex;
}
GLvertexData *CBSPUtil::GetVertex (GLint index)
{
return &(GlobalVertexList[index] -> vd);
}
GLvertex *CBSPUtil::GetCoord (GLint index)
{
return &(GlobalCoordList[index] -> coord.vtx);
}
GLvertex *CBSPUtil::GetVertexCoord (GLint index)
{
GLvertexData *vtx = &(GlobalVertexList[index] -> vd);
return &(GlobalCoordList[vtx -> vtxindex] -> coord.vtx);
}
void CBSPUtil::RemovePolygon (GLbeadTree *polybead)
{
GLint i;
for (i=0; i < TotalPolygon; i++) {
if (polybead == GlobalPolygonList[i].bead) {
GlobalPolygonList[i].usedflag = 0;
GLbeadPolygon *poly = (GLbeadPolygon *) polybead -> beadElement;
if (poly -> subface) RemovePolygon (poly -> subface);
glReleaseMemory ((char *) poly);
glReleaseMemory ((char *) polybead);
return;
}
}
}
GLint CBSPUtil::CreateVertexList (GLObjectData *data, GLint totaldynamic, DynamicVertexRecord *dynamicvtx)
{
GLint i, j, k, l;
GLbeadPolygon *poly;
GLbeadTree *bead;
for (i=0; i < TotalPolygon; i++) {
if (GlobalPolygonList[i].usedflag) {
bead = GlobalPolygonList[i].bead;
poly = (GLbeadPolygon *) bead -> beadElement;
for (j = 0; j < poly -> totalVertices; j++) {
GLvertexDataX *vtx = GlobalVertexList[poly -> vertices[j]];
vtx -> usedflag |= 1;
GLvertexCoordX *coord = GlobalCoordList[vtx -> vd.vtxindex];
coord -> flag |= 1;
}
}
}
j = 0;
for (i = 0; i <= VertexIndex; i++) {
GlobalVertexList[i] -> index = i;
if (GlobalVertexList[i] -> usedflag & 1) j++;
}
GLvertexData *vtxlist = (GLvertexData *) glAllocateMemory (j * sizeof (GLvertexData));
if (!vtxlist) {
DisplayErrorMessage ((GLbyte *) "Can not allocate Vertex List table\n");
return 1;
}
data -> TotalVertices = j;
data -> VertexList = vtxlist;
// remove duplicate coordinates
for (i = 0; i <= VertexIndex; i++) GlobalCoordList[i] -> index = i;
GLvertexCoord *coord1, *coord2;
for (i = 0; i < VertexIndex; i++) {
if (GlobalCoordList[i] -> flag & 1) {
coord1 = &GlobalCoordList[i] -> coord;
if (!(coord1 -> flag & (VERTEX_TYPE_DOF | VERTEX_TYPE_BILLBOARD | VERTEX_TYPE_TREE))) {
for (j = i+1; j <= VertexIndex; j++) {
if (GlobalCoordList[j] -> flag & 1) {
coord2 = &GlobalCoordList[j] -> coord;
if (!(coord2 -> flag & (VERTEX_TYPE_DOF | VERTEX_TYPE_BILLBOARD | VERTEX_TYPE_TREE))) {
if ((coord1 -> vtx.x == coord2 -> vtx.x) &&
(coord1 -> vtx.y == coord2 -> vtx.y) &&
(coord1 -> vtx.z == coord2 -> vtx.z)) {
GlobalCoordList[j] -> flag &= ~1;
GlobalCoordList[j] -> index = GlobalCoordList[i] -> index;
}
}
}
}
}
}
}
j = 0;
for (i = 0; i <= VertexIndex; i++) {
if (GlobalCoordList[i] -> flag & 1) j++;
}
GLvertexCoord *coordlist = (GLvertexCoord *) glAllocateMemory (j * sizeof (GLvertexCoord));
if (!coordlist) {
glReleaseMemory ((char *) vtxlist);
DisplayErrorMessage ((GLbyte *) "Can not allocate Coord List table\n");
return 1;
}
data -> TotalCoord = j;
data -> VertexCoord = coordlist;
j = 0;
for (i = 0; i <= VertexIndex; i++) {
if (GlobalCoordList[i] -> flag & 1) {
coordlist[j] = GlobalCoordList[i] -> coord;
GlobalCoordList[i] -> index = j;
j++;
}
else {
GlobalCoordList[i] -> index = GlobalCoordList[GlobalCoordList[i] -> index] -> index;
}
}
for (i=0; i < totaldynamic; i++) {
j = dynamicvtx[i].index;
if (j != -1) dynamicvtx[i].index = GlobalCoordList[j] -> index;
}
j = 0;
for (i = 0; i <= VertexIndex; i++) {
if (GlobalVertexList[i] -> usedflag & 1) {
vtxlist[j] = GlobalVertexList[i] -> vd;
vtxlist[j].vtxindex = GlobalCoordList[vtxlist[j].vtxindex] -> index;
GlobalVertexList[i] -> index = j;
j++;
}
}
for (k=0; k < TotalPolygon; k++) {
if (GlobalPolygonList[k].usedflag) {
bead = GlobalPolygonList[k].bead;
poly = (GLbeadPolygon *) bead -> beadElement;
for (l = 0; l <= poly -> totalVertices; l++) {
poly -> vertices[l] = GlobalVertexList[poly -> vertices[l]] -> index;
}
}
}
for (i = 0; i <= VertexIndex; i++) {
glReleaseMemory ((char *) GlobalVertexList[i]);
GlobalVertexList[i] = 0;
glReleaseMemory ((char *) GlobalCoordList[i]);
GlobalCoordList[i] = 0;
}
// convert 'vertices' index to the vertex address in array
AdjustVertexList (vtxlist);
return 0;
}
void CBSPUtil::AdjustVertexList (GLvertexData *vtxlist)
{
GLint i, j, k;
GLbeadPolygon *poly;
GLbeadTree *bead;
GLvertexData *vtx;
for (i=0; i < TotalPolygon; i++) {
if (GlobalPolygonList[i].usedflag) {
bead = GlobalPolygonList[i].bead;
poly = (GLbeadPolygon *) bead -> beadElement;
for (j = 0; j < poly -> totalVertices; j++) {
k = poly -> vertices[j];
vtx = &vtxlist[k];
if (vtx -> flag & VERTEX_TYPE_DYNAMIC)
poly -> faceType |= FACE_USE_DYNAMIC_VERTEX;
k *= sizeof (GLPolyVertex);
poly -> vertices[j] = k;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -