📄 hotreadr.cpp
字号:
//-----------------------------------------------------------------------------
#include "hotreadr.h"
#include "..\..\3Dlib\util.h"
#include "..\..\3Dlib\inline.h"
#include "..\..\3Dlib\object.h"
#include "..\..\3Dlib\math.h"
//-----------------------------------------------------------------------------
#define MAX_DEGREE_OF_FREEDOM 100
#define MAX_SWITCH 100
#define MAX_SLOT 100
GLbeadSlot *GlobalSlotTable[MAX_SLOT];
GLbeadDegreeOfFreedom *GlobalDOFTable[MAX_DEGREE_OF_FREEDOM];
GLint GlobalSwitchTable[MAX_SWITCH];
GLint GlobalErrorFlag;
char inString[256], beadName[256];
//-----------------------------------------------------------------------------
GLuint CHOTReader::CacheColor (GLuint color)
{
GLint i;
if (ColorCacheWrap) {
for (i=0;i < MAX_COLOR_CACHE; i++) {
if (color == ColorCache[i]) return ColorIndexCache[i];
}
}
for (i=0;i < ColorCacheIndex; i++) {
if (color == ColorCache[i]) return ColorIndexCache[i];
}
ColorCache[ColorCacheIndex] = color;
i = SearchColor (color);
if (i < 0) return 0;
ColorIndexCache[ColorCacheIndex] = i;
ColorCacheIndex++;
if (ColorCacheIndex >= MAX_COLOR_CACHE) {
ColorCacheWrap = 1;
ColorCacheIndex = 0;
}
return i;
}
GLfloat CHOTReader::CalculateRadius (GLvertex *max, GLvertex *min)
{
GLvertex coord;
GLfloat dist, radius;
// minx, miny, minz
coord.x = min -> x;
coord.y = min -> y;
coord.z = min -> z;
radius = glVectorLength (&coord);
// minx, miny, maxz
coord.x = min -> x;
coord.y = min -> y;
coord.z = max -> z;
dist = glVectorLength (&coord);
if (radius < dist) radius = dist;
// minx, maxy, minz
coord.x = min -> x;
coord.y = max -> y;
coord.z = min -> z;
dist = glVectorLength (&coord);
if (radius < dist) radius = dist;
// minx, maxy, maxz
coord.x = min -> x;
coord.y = max -> y;
coord.z = max -> z;
dist = glVectorLength (&coord);
if (radius < dist) radius = dist;
// maxx, miny, minz
coord.x = max -> x;
coord.y = min -> y;
coord.z = min -> z;
dist = glVectorLength (&coord);
if (radius < dist) radius = dist;
// maxx, miny, maxz
coord.x = max -> x;
coord.y = min -> y;
coord.z = max -> z;
dist = glVectorLength (&coord);
if (radius < dist) radius = dist;
// maxx, maxy, minz
coord.x = max -> x;
coord.y = max -> y;
coord.z = min -> z;
dist = glVectorLength (&coord);
if (radius < dist) radius = dist;
// maxx, maxy, maxz
coord.x = max -> x;
coord.y = max -> y;
coord.z = max -> z;
dist = glVectorLength (&coord);
if (radius < dist) radius = dist;
return radius;
}
inline GLint CHOTReader::GetStringType (GLbyte *str)
{
union {
char c[4];
GLint l;
} type;
char c;
type.l = (GLint) *((GLint *) str);
c = type.c[0];
type.c[0] = type.c[3];
type.c[3] = c;
c = type.c[1];
type.c[1] = type.c[2];
type.c[2] = c;
return type.l;
}
GLint CHOTReader::SearchColor (GLuint color)
{
GLint i = SearchColorInTable (ColorTable, 0, ColorTableSize-1, color);
if (i < 0) {
printf ("Warning!! Can not find color 0x%x in color table\n", color);
}
return i;
}
GLint CHOTReader::SearchColorInTable (ColorListRecord *table, GLint colstart, GLint colend, GLuint color)
{
if (colstart > colend) return -1;
int mid = (colstart+colend) >> 1;
if (table[mid].color == color) return table[mid].colorindex;
else if (color < table[mid].color) {
if (mid == colstart) return -1;
return SearchColorInTable (table, colstart, mid, color);
}
return SearchColorInTable (table, mid+1, colend, color);
}
GLObjectData *CHOTReader::readHOT (char *filename, ColorListRecord *coltable, GLint totalcol, GLint texflag)
{
if (!in.openread ((char *) filename)) return 0;
ColorTableSize = totalcol;
ColorTable = coltable;
objData = (GLObjectData *) glAllocateMemory (sizeof (GLObjectData));
if (!objData) {
DisplayErrorMessage ((GLbyte *) "Can not allocate object data structure!");
in.closefile();
return 0;
}
Setup ();
if (readHeader ()) {
glReleaseMemory ((char*) objData);
Cleanup ();
DisplayErrorMessage ((GLbyte *) "Problem reading header file!");
return 0;
}
if (readVerticesList ()) {
glReleaseMemory ((char*) objData);
Cleanup ();
DisplayErrorMessage ((GLbyte *) "Problem reading vertices list!");
return 0;
}
if (readTextureList (texflag) < 0) {
glReleaseMemory ((char*) objData);
Cleanup ();
DisplayErrorMessage ((GLbyte *) "Problem reading texture list!");
return 0;
}
if (readBeadList ()) {
glReleaseMemory ((char*) objData);
Cleanup ();
DisplayErrorMessage ((GLbyte *) "Problem reading data file!");
return 0;
}
BSPproblem = 0;
removeBSPBead (&objData -> beadRoot);
if (BSPproblem) {
glReleaseMemory ((char*) objData);
Cleanup ();
DisplayErrorMessage ((GLbyte *) "Problem with BSP bead!");
return 0;
}
createDOFTree (objData -> beadRoot);
createSwitchList ();
createObjectSlot ();
removeBeadWithoutChild (&objData -> beadRoot);
if (CreateVertexList(objData, totaldynamicvertex, dynamicvertex)) {
glReleaseMemory ((char*) objData);
Cleanup ();
DisplayErrorMessage ((GLbyte *) "Problem with creating vertex table!");
return 0;
}
if (objData -> objectRadius == (GLfloat) 0.0) {
objData -> objectMax = BeadVertexMax;
objData -> objectMin = BeadVertexMin;
objData -> objectRadius = CalculateRadius (&BeadVertexMax, &BeadVertexMin);
}
objData -> TotalDynamicVertex = 0;
objData -> DynamicVertex = 0;
if (dynamicvertex) {
objData -> DynamicVertex = (GLdynamicVertex *) glAllocateMemory (sizeof(GLdynamicVertex)*totaldynamicvertex);
if (objData -> DynamicVertex) {
GLint i, j, k;
for (i=0;i < totaldynamicvertex;i++) {
j = dynamicvertex[i].index;
if (j != -1) {
k = objData -> VertexList[j].vtxindex;
objData -> DynamicVertex[i].vtx = objData -> VertexCoord[k].vtx;
objData -> DynamicVertex[i].index = j * sizeof (GLvertexCoord);
}
else objData -> DynamicVertex[i].index = -1;
}
objData -> TotalDynamicVertex = totaldynamicvertex;
objData -> objectFlag |= OBJECT_TYPE_HAS_DYNAMIC_VERTEX;
}
else {
DisplayErrorMessage ((GLbyte *) "Warning!! Can not allocate memory for Dynamic Vertex");
}
}
GLAnimation anim;
anim.TotalDOF = objData -> TotalDOF;
anim.TotalSwitch = objData -> TotalSwitch;
anim.Switchptr = objData -> switchList;
anim.TotalObjectSlot = objData -> TotalObjectSlot;
anim.Flags = animFlag;
anim.TotalDynamicVertex = objData -> TotalDynamicVertex;
objData -> objectAnimation = CreateAnimationData (&anim);
objData -> version = 100; // version 1.00
Cleanup ();
return objData;
}
void CHOTReader::Cleanup ()
{
CBSPUtil::Cleanup ();
in.closefile();
glReleaseMemory ((char*) colorpatch);
glReleaseMemory ((char*) dynamicvertex);
}
void CHOTReader::Setup ()
{
CBSPUtil::Setup ();
GLint i;
for (i=0;i < MAX_DEGREE_OF_FREEDOM;i++) {
GlobalDOFTable[i] = 0;
}
for (i=0;i < MAX_SLOT;i++) {
GlobalSlotTable[i] = 0;
}
colorpatch = 0;
totalcolorpatch = 0;
dynamicvertex = 0;
totaldynamicvertex = 0;
GlobalErrorFlag = 0;
animFlag = 0;
objectScale = (GLfloat) 1.0;
VertexListPos = TextureListPos = BeadListPos = -1;
BeadVertexMax.x = BeadVertexMax.y = BeadVertexMax.z = (GLfloat) -1e10;
BeadVertexMin.x = BeadVertexMin.y = BeadVertexMin.z = (GLfloat) 1e10;
objData -> objectAnimation = 0;
objData -> dofTree = 0;
objData -> Slotptr = 0;
objData -> switchList = 0;
objData -> beadRoot = 0;
objData -> beadTexture = 0;
objData -> TotalDOF = 0;
objData -> TotalSwitch = 0;
objData -> TotalObjectSlot = 0;
objData -> TotalTextures = 0;
objData -> objectFlag = 0;
objData -> objectRadius = (GLfloat) 0.0;
objData -> StructureSize = sizeof(GLObjectData);
objData -> TotalTextureSet = 1;
objData -> TextureSetSize = 0;
}
void CHOTReader::removeBeadWithoutChild (GLbeadTree **bead)
{
GLbeadTree *curbead = *bead;
if (curbead) {
if ((curbead -> type == BEAD_TYPE_GROUP) ||
(curbead -> type == BEAD_TYPE_OBJECT)) {
if (!curbead -> child) {
removeBeadWithoutChild (&curbead -> next);
*bead = curbead -> next;
glReleaseMemory ((char *) curbead);
return;
}
}
removeBeadWithoutChild (&curbead -> next);
removeBeadWithoutChild (&curbead -> child);
}
}
void CHOTReader::removeBSPBead (GLbeadTree **bead)
{
GLbeadTree *curbead = *bead;
if (curbead) {
if (curbead -> type == BEAD_TYPE_BSP) {
GLbeadTree *child = curbead -> child;
if (child) {
GLbeadTree *nextchild = child -> next;
if (nextchild -> type != BEAD_TYPE_POLYGON) {
GLbeadTree *lastchild = nextchild;
while (nextchild) {
if (nextchild -> type == BEAD_TYPE_POLYGON) {
lastchild -> next = 0;
break;
}
lastchild = nextchild;
nextchild = nextchild -> next;
}
if (!nextchild) BSPproblem = 1;
else if (!nextchild -> next) BSPproblem = 1;
}
else child -> next = 0;
nextchild -> child = child;
nextchild -> type = BEAD_TYPE_POLYGON_BSP;
glReleaseMemory ((char *) curbead -> beadElement);
if (curbead -> next) {
curbead -> child = nextchild;
curbead -> type = BEAD_TYPE_GROUP;
}
else {
glReleaseMemory ((char *) curbead);
*bead = nextchild;
curbead = nextchild;
}
}
}
removeBSPBead (&curbead -> next);
removeBSPBead (&curbead -> child);
}
}
void CHOTReader::createSwitchList ()
{
if (objData -> TotalSwitch) {
GLint i = objData -> TotalSwitch * sizeof (GLint);
objData -> switchList = (GLint *) glAllocateMemory (i);
if (!objData -> switchList) {
DisplayErrorMessage ((GLbyte *) "Can not allocate memory for Switch List!");
return;
}
objData -> objectFlag |= OBJECT_TYPE_USE_SWITCH;
memcpy (objData -> switchList, GlobalSwitchTable, i);
}
}
void CHOTReader::createObjectSlot ()
{
if (objData -> TotalObjectSlot) {
GLint i;
i = (objData -> TotalObjectSlot) * sizeof (GLbeadSlot);
objData -> Slotptr = (GLbeadSlot *) glAllocateMemory (i);
if (!objData -> Slotptr) {
DisplayErrorMessage ((GLbyte *) "Can not allocate memory for Object Slot!");
return;
}
objData -> objectFlag |= OBJECT_TYPE_HAS_OBJECT_SLOT;
traverseObjectSlotBead (objData -> beadRoot);
GLbeadSlot *slot = objData -> Slotptr;
for (i=0; i <= objData -> TotalObjectSlot; i++) {
if (GlobalSlotTable[i]) {
slot[i] = *(GlobalSlotTable[i]);
glReleaseMemory ((char *) GlobalSlotTable[i]);
}
}
}
}
void CHOTReader::traverseObjectSlotBead (GLbeadTree *bead)
{
if (bead) {
if (bead -> type == BEAD_TYPE_OBJECT_SLOT) {
GLbeadTree *child = bead -> child;
if (!child) {
DisplayErrorMessage ((GLbyte *) "ObjectSlot must have polygon child!");
return;
}
if (child -> child) {
DisplayErrorMessage ((GLbyte *) "ObjectSlot child can not have child!");
return;
}
if (child -> next) {
DisplayErrorMessage ((GLbyte *) "ObjectSlot can only have one child!");
return;
}
if (child -> type != BEAD_TYPE_POLYGON) {
DisplayErrorMessage ((GLbyte *) "ObjectSlot child must be polygon type!");
return;
}
GLbeadPolygon *poly = (GLbeadPolygon *) child -> beadElement;
if (poly -> subface) {
DisplayErrorMessage ((GLbyte *) "ObjectSlot child can not have subface!");
return;
}
GLbeadSlot *slot = GlobalSlotTable[(GLint) bead -> beadElement];
GLvertex *slotvtx = GetVertexCoord (poly -> vertices[0]);
slot -> objectCenter = *slotvtx;
slot -> slotMatrix.M11 = slot -> slotMatrix.M22 =
slot -> slotMatrix.M33 = 1.0f;
slot -> slotMatrix.M12 = slot -> slotMatrix.M13 =
slot -> slotMatrix.M21 = slot -> slotMatrix.M23 =
slot -> slotMatrix.M31 = slot -> slotMatrix.M32 = 0.0f;
GLbeadTree *next = bead -> next;
if (next && next -> type == BEAD_TYPE_MATRIX) {
GLmatrix *mat = (GLmatrix *) next -> beadElement;
slot -> slotMatrix = *mat;
}
RemovePolygon (child);
bead -> child = 0;
}
traverseObjectSlotBead (bead -> next);
traverseObjectSlotBead (bead -> child);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -