mirror of
https://github.com/EQEmu/Server.git
synced 2026-09-01 07:26:36 +00:00
Merge branch 'master' of https://github.com/EQEmu/Server
This commit is contained in:
+172
-172
@@ -2,10 +2,10 @@
|
||||
|
||||
Father Nitwit's Zone to map conversion program.
|
||||
Copyright (C) 2004 Father Nitwit (eqemu@8ass.com)
|
||||
|
||||
|
||||
This thing uses code from freaku, so whatever license that comes under
|
||||
is relavent, if you care.
|
||||
|
||||
|
||||
the rest of it is GPL, even though I hate the GPL.
|
||||
|
||||
|
||||
@@ -19,13 +19,13 @@
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; version 2 of the License.
|
||||
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY except by those people which sell it, which
|
||||
are required to give you total support for your newly bought product;
|
||||
without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
||||
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
@@ -78,33 +78,33 @@ using namespace std;
|
||||
int main(int argc, char *argv[]) {
|
||||
|
||||
printf("AZONE2: EQEmu .MAP file generator with placeable object support.\n");
|
||||
|
||||
|
||||
if(argc != 2) {
|
||||
printf("Usage: %s (zone short name)\n", argv[0]);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
char bufm[250];
|
||||
|
||||
|
||||
sprintf(bufm, "%s.map", argv[1]);
|
||||
|
||||
|
||||
QTBuilder QT;
|
||||
|
||||
|
||||
if(!QT.build(argv[1]))
|
||||
return(1);
|
||||
|
||||
|
||||
if(!QT.writeMap(bufm))
|
||||
return(1);
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
QTBuilder::QTBuilder() {
|
||||
_root = NULL;
|
||||
|
||||
|
||||
faceCount = 0;
|
||||
faceBlock = NULL;
|
||||
|
||||
|
||||
#ifdef COUNT_MACTHES
|
||||
gEasyMatches = 0;
|
||||
gEasyExcludes = 0;
|
||||
@@ -123,8 +123,8 @@ QTBuilder::~QTBuilder() {
|
||||
}
|
||||
|
||||
bool QTBuilder::build(const char *shortname) {
|
||||
|
||||
|
||||
|
||||
|
||||
char bufs[96];
|
||||
Archive *archive;
|
||||
FileLoader *fileloader;
|
||||
@@ -133,12 +133,12 @@ bool QTBuilder::build(const char *shortname) {
|
||||
EQFileType FileType = UNKNOWN;
|
||||
|
||||
bool V4Zone = false;
|
||||
|
||||
|
||||
sprintf(bufs, "%s.s3d", shortname);
|
||||
|
||||
archive = new PFSLoader();
|
||||
fff = fopen(bufs, "rb");
|
||||
if(fff != NULL)
|
||||
if(fff != NULL)
|
||||
FileType = S3D;
|
||||
else {
|
||||
sprintf(bufs, "%s.eqg", shortname);
|
||||
@@ -158,7 +158,7 @@ bool QTBuilder::build(const char *shortname) {
|
||||
}
|
||||
|
||||
switch(FileType) {
|
||||
case S3D:
|
||||
case S3D:
|
||||
fileloader = new WLDLoader();
|
||||
if(fileloader->Open(NULL, (char *) shortname, archive) == 0) {
|
||||
printf("Error reading WLD from %s\n", bufs);
|
||||
@@ -183,7 +183,7 @@ bool QTBuilder::build(const char *shortname) {
|
||||
}
|
||||
|
||||
zm = fileloader->model_data.zone_model;
|
||||
|
||||
|
||||
long i;
|
||||
VERTEX v1, v2, v3;
|
||||
for(i = 0; i < zm->poly_count; ++i) {
|
||||
@@ -211,11 +211,11 @@ bool QTBuilder::build(const char *shortname) {
|
||||
v3.y = zm->verts[zm->polys[i]->v3]->y;
|
||||
#endif
|
||||
v3.z = zm->verts[zm->polys[i]->v3]->z;
|
||||
|
||||
|
||||
AddFace(v1, v2, v3);
|
||||
}
|
||||
|
||||
printf("There are %u vertices and %u faces.\n", _FaceList.size()*3, _FaceList.size());
|
||||
printf("There are %lu vertices and %lu faces.\n", _FaceList.size()*3, _FaceList.size());
|
||||
|
||||
if(fileloader->model_data.plac_count)
|
||||
{
|
||||
@@ -229,30 +229,30 @@ bool QTBuilder::build(const char *shortname) {
|
||||
else
|
||||
AddPlaceable(fileloader, bufs, false);
|
||||
}
|
||||
else
|
||||
else
|
||||
printf("No placeable objects (or perhaps %s_obj.s3d not present).\n", shortname);
|
||||
|
||||
printf("After processing placeable objects, there are %u vertices and %u faces.\n", _FaceList.size()*3, _FaceList.size());
|
||||
|
||||
printf("After processing placeable objects, there are %lu vertices and %lu faces.\n", _FaceList.size()*3, _FaceList.size());
|
||||
|
||||
unsigned long r;
|
||||
|
||||
|
||||
faceCount = _FaceList.size();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
faceBlock = new FACE[faceCount];
|
||||
//im not going to assume I know vectors are stored in contiguous blocks
|
||||
for(r = 0; r < faceCount; r++) {
|
||||
faceBlock[r] = _FaceList[r];
|
||||
}
|
||||
|
||||
|
||||
//build quad tree... prolly much slower than it needs to be.
|
||||
float minx, miny, maxx, maxy;
|
||||
minx = 1e12;
|
||||
miny = 1e12;
|
||||
maxx = -1e12;
|
||||
maxy = -1e12;
|
||||
|
||||
|
||||
//find our limits.
|
||||
for(r = 0; r < faceCount; r++) {
|
||||
//a bit of lazyness going on here...
|
||||
@@ -290,17 +290,17 @@ bool QTBuilder::build(const char *shortname) {
|
||||
miny = v.y;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
printf("Bounding box: %.2f < x < %.2f, %.2f < y < %.2f\n", minx, maxx, miny, maxy);
|
||||
|
||||
printf("Building quadtree.\n");
|
||||
|
||||
|
||||
_root = new QTNode(this, minx, maxx, miny, maxy);
|
||||
if(_root == NULL) {
|
||||
printf("Unable to allocate new QTNode.\n");
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
//build our initial set of faces... all of them:
|
||||
FACE *faceptr = faceBlock;
|
||||
_root->faces.resize(faceCount);
|
||||
@@ -309,9 +309,9 @@ bool QTBuilder::build(const char *shortname) {
|
||||
_root->faces[r].index = r;
|
||||
faceptr++;
|
||||
}
|
||||
|
||||
|
||||
_root->divideYourself(0);
|
||||
|
||||
|
||||
printf("Done building quad tree...\n");
|
||||
|
||||
#ifdef COUNT_MACTHES
|
||||
@@ -334,39 +334,39 @@ bool QTBuilder::build(const char *shortname) {
|
||||
bool QTBuilder::writeMap(const char *file) {
|
||||
if(_root == NULL)
|
||||
return(false);
|
||||
|
||||
|
||||
printf("Writing map file.\n");
|
||||
|
||||
|
||||
FILE *out = fopen(file, "wb");
|
||||
if(out == NULL) {
|
||||
printf("Unable to open output file '%s'.\n", file);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
mapHeader head;
|
||||
head.version = MAP_VERSION;
|
||||
head.face_count = faceCount;
|
||||
head.node_count = _root->countNodes();
|
||||
head.facelist_count = _root->countFacelists();
|
||||
|
||||
|
||||
if(fwrite(&head, sizeof(head), 1, out) != 1) {
|
||||
printf("Error writing map file header.\n");
|
||||
fclose(out);
|
||||
return(1);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
printf("Map header: Version: 0x%08lX. %lu faces, %u nodes, %lu facelists\n", head.version, head.face_count, head.node_count, head.facelist_count);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//write faceBlock
|
||||
if(fwrite(faceBlock, sizeof(FACE), faceCount, out) != faceCount) {
|
||||
printf("Error writing map file faces.\n");
|
||||
fclose(out);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
//make our node blocks to write out...
|
||||
nodeHeader *nodes = new nodeHeader[head.node_count];
|
||||
unsigned long *facelist = new unsigned long[head.facelist_count];
|
||||
@@ -375,11 +375,11 @@ bool QTBuilder::writeMap(const char *file) {
|
||||
fclose(out);
|
||||
return(1); //no memory
|
||||
}
|
||||
|
||||
|
||||
unsigned long hindex = 0;
|
||||
unsigned long findex = 0;
|
||||
_root->fillBlocks(nodes, facelist, hindex, findex);
|
||||
|
||||
|
||||
if(fwrite(nodes, sizeof(nodeHeader), head.node_count, out) != head.node_count) {
|
||||
printf("Error writing map file nodes.\n");
|
||||
fclose(out);
|
||||
@@ -390,15 +390,15 @@ bool QTBuilder::writeMap(const char *file) {
|
||||
fclose(out);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
long MapFileSize = ftell(out);
|
||||
fclose(out);
|
||||
delete[] nodes;
|
||||
delete[] facelist;
|
||||
|
||||
|
||||
printf("Done writing map (%3.2fMB).\n", (float)MapFileSize/1048576);
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
@@ -414,7 +414,7 @@ QTNode::QTNode(QTBuilder *b, float Tminx, float Tmaxx, float Tminy, float Tmaxy)
|
||||
maxy = Tmaxy;
|
||||
final = false;
|
||||
buildVertexes();
|
||||
|
||||
|
||||
builder = b;
|
||||
}
|
||||
|
||||
@@ -441,7 +441,7 @@ void QTNode::clearNodes() {
|
||||
void QTNode::fillBlocks(nodeHeader *heads, unsigned long *flist, unsigned long &hindex, unsigned long &findex) {
|
||||
nodeHeader *head = &heads[hindex];
|
||||
hindex++;
|
||||
|
||||
|
||||
head->minx = minx;
|
||||
head->maxx = maxx;
|
||||
head->miny = miny;
|
||||
@@ -462,7 +462,7 @@ void QTNode::fillBlocks(nodeHeader *heads, unsigned long *flist, unsigned long &
|
||||
} else {
|
||||
//branch node.
|
||||
head->flags = 0;
|
||||
|
||||
|
||||
if(node1 != NULL) {
|
||||
head->nodes[0] = hindex;
|
||||
node1->fillBlocks(heads, flist, hindex, findex);
|
||||
@@ -523,54 +523,54 @@ Map Format:
|
||||
head.face_count x FACE
|
||||
head.node_count x nodeHeader
|
||||
head.facelist_count x unsigned long (indexes into face array)
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
void QTNode::divideYourself(int depth) {
|
||||
// printf("Dividing in box (%.2f -> %.2f, %.2f -> %.2f) at depth %d with %d faces.\n",
|
||||
// printf("Dividing in box (%.2f -> %.2f, %.2f -> %.2f) at depth %d with %d faces.\n",
|
||||
// minx, maxx, miny, maxy, depth, faces.size());
|
||||
|
||||
|
||||
unsigned long cc;
|
||||
cc = faces.size();
|
||||
#ifdef MAX_QUADRENT_FACES
|
||||
if(cc <= MAX_QUADRENT_FACES) {
|
||||
#ifdef SPLIT_DEBUG
|
||||
printf("Stopping (facecount) on box (%.2f -> %.2f, %.2f -> %.2f) at depth %d with %d faces.\n",
|
||||
printf("Stopping (facecount) on box (%.2f -> %.2f, %.2f -> %.2f) at depth %d with %d faces.\n",
|
||||
minx, maxx, miny, maxy, depth, cc);
|
||||
#endif
|
||||
final = true;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef MIN_QUADRENT_SIZE
|
||||
if((maxx - minx) < MIN_QUADRENT_SIZE || (maxy - miny) < MIN_QUADRENT_SIZE) {
|
||||
#ifdef SPLIT_DEBUG
|
||||
printf("Stopping on box (size) (%.2f -> %.2f, %.2f -> %.2f) at depth %d with %d faces.\n",
|
||||
printf("Stopping on box (size) (%.2f -> %.2f, %.2f -> %.2f) at depth %d with %d faces.\n",
|
||||
minx, maxx, miny, maxy, depth, cc);
|
||||
#endif
|
||||
final = true;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
doSplit();
|
||||
|
||||
|
||||
//get counts on our split
|
||||
float c1, c2, c3, c4;
|
||||
c1 = node1? node1->faces.size() : 0;
|
||||
c2 = node2? node2->faces.size() : 0;
|
||||
c3 = node3? node3->faces.size() : 0;
|
||||
c4 = node4? node4->faces.size() : 0;
|
||||
|
||||
|
||||
#ifdef MIN_QUADRENT_GAIN
|
||||
int miss = 0;
|
||||
float gain1 = 1.0 - c1 / cc;
|
||||
float gain2 = 1.0 - c2 / cc;
|
||||
float gain3 = 1.0 - c3 / cc;
|
||||
float gain4 = 1.0 - c4 / cc;
|
||||
|
||||
|
||||
//see how many missed the gain mark
|
||||
if(gain1 < MIN_QUADRENT_GAIN)
|
||||
miss++;
|
||||
@@ -580,33 +580,33 @@ printf("Stopping on box (size) (%.2f -> %.2f, %.2f -> %.2f) at depth %d with %d
|
||||
miss++;
|
||||
if(gain4 < MIN_QUADRENT_GAIN)
|
||||
miss++;
|
||||
|
||||
|
||||
if(miss > MAX_QUADRENT_MISSES) {
|
||||
#ifdef SPLIT_DEBUG
|
||||
printf("Stopping (gain) on box (%.2f -> %.2f, %.2f -> %.2f) at depth %d with %d faces.\n",
|
||||
printf("Stopping (gain) on box (%.2f -> %.2f, %.2f -> %.2f) at depth %d with %d faces.\n",
|
||||
minx, maxx, miny, maxy, depth, cc);
|
||||
#endif
|
||||
final = true;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
//if all faces pass through all quadrents, then we are done
|
||||
//partially obsoleted by gain test.
|
||||
if(c1 == c2 && c1 == c3 && c1 == c4) {
|
||||
#ifdef SPLIT_DEBUG
|
||||
printf("Stopping (empty) on box (%.2f -> %.2f, %.2f -> %.2f) at depth %d with %d faces.\n",
|
||||
printf("Stopping (empty) on box (%.2f -> %.2f, %.2f -> %.2f) at depth %d with %d faces.\n",
|
||||
minx, maxx, miny, maxy, depth, cc);
|
||||
#endif
|
||||
final = true;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//there are prolly some more intelligent stopping criteria...
|
||||
|
||||
|
||||
depth++;
|
||||
|
||||
|
||||
if(node1 != NULL)
|
||||
node1->divideYourself(depth);
|
||||
if(node2 != NULL)
|
||||
@@ -615,18 +615,18 @@ printf("Stopping (empty) on box (%.2f -> %.2f, %.2f -> %.2f) at depth %d with %d
|
||||
node3->divideYourself(depth);
|
||||
if(node4 != NULL)
|
||||
node4->divideYourself(depth);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
void QTNode::buildVertexes() {
|
||||
|
||||
v[0].x = v[1].x = v[2].x = v[3].x = minx;
|
||||
v[4].x = v[5].x = v[6].x = v[7].x = maxx;
|
||||
|
||||
|
||||
v[0].y = v[1].y = v[4].y = v[5].y = miny;
|
||||
v[2].y = v[3].y = v[6].y = v[7].y = maxy;
|
||||
|
||||
|
||||
v[0].z = v[3].z = v[4].z = v[7].z = -999999;
|
||||
v[1].z = v[2].z = v[5].z = v[6].z = 9999999;
|
||||
}
|
||||
@@ -677,7 +677,7 @@ bool edges_cross(GPoint *pt1, GPoint *pt2, const VERTEX *pt3, const VERTEX *pt4)
|
||||
(p2->x > p1->x? \
|
||||
(p1->z + ((inter - p1->x)/(p2->x - p1->x) * (p2->z - p1->z))) \
|
||||
:(p2->z + ((inter - p2->x)/(p1->x - p2->x) * (p1->z - p2->z))))
|
||||
|
||||
|
||||
float denom = IntersectDenom(pt1, pt2, pt3, pt4);
|
||||
if(denom != 0) {
|
||||
|
||||
@@ -746,25 +746,25 @@ bool QTBuilder::FaceInNode(const QTNode *q, const FACE *f) {
|
||||
const VERTEX *v1 = &f->a;
|
||||
const VERTEX *v2 = &f->b;
|
||||
const VERTEX *v3 = &f->c;
|
||||
|
||||
|
||||
#ifdef COUNT_MACTHES
|
||||
gEasyMatches++;
|
||||
#endif
|
||||
|
||||
//Easy matches, points are within the quadrant.
|
||||
if( ! ( v1->x <= q->minx || v1->x > q->maxx
|
||||
if( ! ( v1->x <= q->minx || v1->x > q->maxx
|
||||
|| v1->y <= q->miny || v1->y > q->maxy ) ) {
|
||||
return(true);
|
||||
}
|
||||
if( ! ( v2->x <= q->minx || v2->x > q->maxx
|
||||
if( ! ( v2->x <= q->minx || v2->x > q->maxx
|
||||
|| v2->y <= q->miny || v2->y > q->maxy ) ) {
|
||||
return(true);
|
||||
}
|
||||
if( ! ( v3->x <= q->minx || v3->x > q->maxx
|
||||
if( ! ( v3->x <= q->minx || v3->x > q->maxx
|
||||
|| v3->y <= q->miny || v3->y > q->maxy ) ) {
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
||||
#ifdef COUNT_MACTHES
|
||||
gEasyMatches--;
|
||||
gEasyExcludes++;
|
||||
@@ -779,41 +779,41 @@ bool QTBuilder::FaceInNode(const QTNode *q, const FACE *f) {
|
||||
return(false);
|
||||
if( v1->y > q->maxy && v2->y > q->maxy && v3->y > q->maxy )
|
||||
return(false);
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef COUNT_MACTHES
|
||||
gEasyExcludes--;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef COUNT_MACTHES
|
||||
gHardMatches++;
|
||||
#endif
|
||||
// return(true);
|
||||
|
||||
|
||||
//harder: no points are in the cube
|
||||
|
||||
|
||||
//4 points of this node
|
||||
GPoint pt1(q->minx, q->miny, 0),
|
||||
pt2(q->minx, q->maxy, 0),
|
||||
pt3(q->maxx, q->miny, 0),
|
||||
pt4(q->maxx, q->maxy, 0);
|
||||
|
||||
|
||||
/*
|
||||
//box lines:
|
||||
pt1, pt2
|
||||
pt3, pt4
|
||||
pt1, pt3
|
||||
pt2, pt4
|
||||
|
||||
|
||||
//tri lines
|
||||
v1, v2
|
||||
v1, v3
|
||||
v2, v3
|
||||
*/
|
||||
|
||||
|
||||
#define CheckIntersect(p1, p2, p3, p4) \
|
||||
(((p4->y - p3->y)*(p2.x - p1.x) - (p4->x - p3->x)*(p2.y - p1.y)) != 0)
|
||||
|
||||
|
||||
int finaltest =
|
||||
(edges_cross(&pt1, &pt2, v1, v2)
|
||||
|| edges_cross(&pt1, &pt2, v1, v3)
|
||||
@@ -829,7 +829,7 @@ bool QTBuilder::FaceInNode(const QTNode *q, const FACE *f) {
|
||||
|| edges_cross(&pt2, &pt4, v2, v3));
|
||||
|
||||
if(finaltest) return finaltest;
|
||||
|
||||
|
||||
VERTEX Triangle[3];
|
||||
Triangle[0]=*v1; Triangle[1]=*v2; Triangle[2] = *v3;
|
||||
finaltest = PointInTriangle(Triangle, q->minx, q->miny) ||
|
||||
@@ -843,12 +843,12 @@ bool QTBuilder::FaceInNode(const QTNode *q, const FACE *f) {
|
||||
|
||||
|
||||
void QTNode::doSplit() {
|
||||
|
||||
|
||||
|
||||
|
||||
//find midpoints...
|
||||
float midx = minx + (maxx - minx) / 2.0;
|
||||
float midy = miny + (maxy - miny) / 2.0;
|
||||
|
||||
|
||||
//ordering following definitions in map.h
|
||||
node1 = new QTNode(builder, midx, maxx, midy, maxy);
|
||||
node2 = new QTNode(builder, minx, midx, midy, maxy);
|
||||
@@ -858,7 +858,7 @@ void QTNode::doSplit() {
|
||||
printf("Error: unable to allocate new QTNode, giving up.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
unsigned long r,l;
|
||||
l = faces.size();
|
||||
for(r = 0; r < l; r++) {
|
||||
@@ -872,7 +872,7 @@ void QTNode::doSplit() {
|
||||
if(builder->FaceInNode(node4, cur.face))
|
||||
node4->faces.push_back(cur);
|
||||
}
|
||||
|
||||
|
||||
//clean up empty sets.
|
||||
if(node1->faces.size() == 0) {
|
||||
delete node1;
|
||||
@@ -890,29 +890,29 @@ void QTNode::doSplit() {
|
||||
delete node4;
|
||||
node4 = NULL;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void QTBuilder::AddFace(VERTEX &v1, VERTEX &v2, VERTEX &v3) {
|
||||
FACE f;
|
||||
|
||||
|
||||
#ifdef MAX_Z
|
||||
if(v1.z > MAX_Z && v2.z > MAX_Z && v3.z > MAX_Z)
|
||||
return;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
//this still might not work
|
||||
f.nx = (v2.y - v1.y)*(v3.z - v1.z) - (v2.z - v1.z)*(v3.y - v1.y);
|
||||
f.ny = (v2.z - v1.z)*(v3.x - v1.x) - (v2.x - v1.x)*(v3.z - v1.z);
|
||||
f.nz = (v2.x - v1.x)*(v3.y - v1.y) - (v2.y - v1.y)*(v3.x - v1.x);
|
||||
NormalizeN(&f);
|
||||
f.nd = - f.nx * v1.x - f.ny * v1.y - f.nz * v1.z;
|
||||
|
||||
|
||||
f.a = v1;
|
||||
f.b = v2;
|
||||
f.c = v3;
|
||||
|
||||
|
||||
_FaceList.push_back(f);
|
||||
}
|
||||
|
||||
@@ -989,75 +989,75 @@ void GVector::normalize() {
|
||||
}
|
||||
|
||||
//stolen from: http://gamecode.tripod.com/tut/tut04.htm
|
||||
int QTBuilder::ClipPolygon(POLYGON *poly, GVector *plane) {
|
||||
int QTBuilder::ClipPolygon(POLYGON *poly, GVector *plane) {
|
||||
/* Plan: cycle through the vertices, considering pairs of them.
|
||||
If both vertices are visible, add them to the new array.
|
||||
If both vertices are invisible, add neither to the new array.
|
||||
If one vertex is visible and the other is not, move the one
|
||||
that's not, and then add both vertices to the new array.
|
||||
*/
|
||||
float dist1, dist2; // distances of points to plane
|
||||
float distratio; // fraction of distance between two points
|
||||
// new vertices might be created. Don't change
|
||||
// polygon's vertices because we might still need
|
||||
// them. Instead, use tempvtx array and update vertices
|
||||
float dist1, dist2; // distances of points to plane
|
||||
float distratio; // fraction of distance between two points
|
||||
// new vertices might be created. Don't change
|
||||
// polygon's vertices because we might still need
|
||||
// them. Instead, use tempvtx array and update vertices
|
||||
// array at the end. Create tempvtx array once only.
|
||||
int i, ii, j=0;
|
||||
int i, ii, j=0;
|
||||
|
||||
/* Check if plane is a valid plane */
|
||||
if (!(plane->x || plane->y || plane->z)) return -1;
|
||||
// if not valid plane, don't change polygon and return an error;
|
||||
/* Check if plane is a valid plane */
|
||||
if (!(plane->x || plane->y || plane->z)) return -1;
|
||||
// if not valid plane, don't change polygon and return an error;
|
||||
|
||||
/* The vertices should, as for all functions, be arranged in cyclic
|
||||
order. That is, if a line was drawn from each vertex to the next
|
||||
it would form the correct outline of the polygon in 3D space.
|
||||
This routine might create new vertices because of the clipping,
|
||||
but the cyclic order will be preserved.
|
||||
*/
|
||||
/* The vertices should, as for all functions, be arranged in cyclic
|
||||
order. That is, if a line was drawn from each vertex to the next
|
||||
it would form the correct outline of the polygon in 3D space.
|
||||
This routine might create new vertices because of the clipping,
|
||||
but the cyclic order will be preserved.
|
||||
*/
|
||||
|
||||
for (i=0; i<poly->count; i++)
|
||||
{
|
||||
for (i=0; i<poly->count; i++)
|
||||
{
|
||||
ii = (i+1)%poly->count;
|
||||
dist1 = plane->x * poly->c[i].x + plane->y * poly->c[i].y +
|
||||
plane->z * poly->c[i].z + plane->W;
|
||||
dist2 = plane->x * poly->c[ii].x + plane->y * poly->c[ii].y +
|
||||
plane->z * poly->c[ii].z + plane->W;
|
||||
if (dist1<0 && dist2<0) // line unclipped and invisible
|
||||
dist1 = plane->x * poly->c[i].x + plane->y * poly->c[i].y +
|
||||
plane->z * poly->c[i].z + plane->W;
|
||||
dist2 = plane->x * poly->c[ii].x + plane->y * poly->c[ii].y +
|
||||
plane->z * poly->c[ii].z + plane->W;
|
||||
if (dist1<0 && dist2<0) // line unclipped and invisible
|
||||
continue;
|
||||
if (dist1>0 && dist2>0) // line unclipped and visible
|
||||
tempvtx[j++]=poly->c[i];
|
||||
else // line partially visible
|
||||
if (dist1>0) // first vertex is visible
|
||||
{
|
||||
distratio = dist1/(dist1-dist2);
|
||||
else // line partially visible
|
||||
if (dist1>0) // first vertex is visible
|
||||
{
|
||||
distratio = dist1/(dist1-dist2);
|
||||
tempvtx[j] = poly->c[i];
|
||||
j++; // Copied 1st vertex
|
||||
tempvtx[j].x = poly->c[i].x +
|
||||
(poly->c[ii].x - poly->c[i].x) * distratio;
|
||||
tempvtx[j].y = poly->c[i].y +
|
||||
(poly->c[ii].y - poly->c[i].y) * distratio;
|
||||
tempvtx[j].z = poly->c[i].z +
|
||||
tempvtx[j].x = poly->c[i].x +
|
||||
(poly->c[ii].x - poly->c[i].x) * distratio;
|
||||
tempvtx[j].y = poly->c[i].y +
|
||||
(poly->c[ii].y - poly->c[i].y) * distratio;
|
||||
tempvtx[j].z = poly->c[i].z +
|
||||
(poly->c[ii].z - poly->c[i].z) * distratio;
|
||||
j++; // Copied second vertex
|
||||
}
|
||||
else // second vertex is visible
|
||||
{
|
||||
distratio = dist2/(dist2-dist1);
|
||||
tempvtx[j].x = poly->c[ii].x +
|
||||
(poly->c[i].x - poly->c[ii].x) * distratio;
|
||||
tempvtx[j].y = poly->c[ii].y +
|
||||
(poly->c[i].y - poly->c[ii].y) * distratio;
|
||||
tempvtx[j].z = poly->c[ii].z +
|
||||
(poly->c[i].z - poly->c[ii].z) * distratio;
|
||||
}
|
||||
else // second vertex is visible
|
||||
{
|
||||
distratio = dist2/(dist2-dist1);
|
||||
tempvtx[j].x = poly->c[ii].x +
|
||||
(poly->c[i].x - poly->c[ii].x) * distratio;
|
||||
tempvtx[j].y = poly->c[ii].y +
|
||||
(poly->c[i].y - poly->c[ii].y) * distratio;
|
||||
tempvtx[j].z = poly->c[ii].z +
|
||||
(poly->c[i].z - poly->c[ii].z) * distratio;
|
||||
j++; // Copy only first vertex. 2nd vertex will be copied
|
||||
// in next iteration of loop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<j; i++)
|
||||
for (i=0; i<j; i++)
|
||||
poly->c[i] = tempvtx[i]; // Update the vertices in polygon
|
||||
poly->count = j; // Update the vertex count
|
||||
return j;
|
||||
return j;
|
||||
}
|
||||
|
||||
|
||||
@@ -1160,7 +1160,7 @@ void QTBuilder::AddPlaceable(FileLoader *fileloader, char *ZoneFileName, bool Li
|
||||
continue;
|
||||
}
|
||||
IniBuffer[StrIndex++] = tolower(ch);
|
||||
}
|
||||
}
|
||||
fclose(IniFile);
|
||||
|
||||
if(INIEntryFound) {
|
||||
@@ -1173,7 +1173,7 @@ void QTBuilder::AddPlaceable(FileLoader *fileloader, char *ZoneFileName, bool Li
|
||||
else {
|
||||
printf("No azone.ini entry found for zone %s\n", ZoneFileName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
for(int i = 0; i < fileloader->model_data.plac_count; ++i) {
|
||||
@@ -1186,9 +1186,9 @@ void QTBuilder::AddPlaceable(FileLoader *fileloader, char *ZoneFileName, bool Li
|
||||
fileloader->model_data.placeable[i]->x,
|
||||
fileloader->model_data.placeable[i]->z,
|
||||
fileloader->model_data.placeable[i]->model,
|
||||
fileloader->model_data.models[fileloader->model_data.placeable[i]->model]->name);
|
||||
fileloader->model_data.models[fileloader->model_data.placeable[i]->model]->name);
|
||||
|
||||
|
||||
|
||||
if(!fileloader->model_data.models[fileloader->model_data.placeable[i]->model]->IncludeInMap)
|
||||
continue;
|
||||
printf("Including Placeable Object %4d using model %4d (%s).\n", i,
|
||||
@@ -1212,11 +1212,11 @@ void QTBuilder::AddPlaceable(FileLoader *fileloader, char *ZoneFileName, bool Li
|
||||
|
||||
Model *model = fileloader->model_data.models[fileloader->model_data.placeable[i]->model];
|
||||
|
||||
|
||||
|
||||
for(int j = 0; j < model->poly_count; ++j) {
|
||||
|
||||
poly = model->polys[j];
|
||||
|
||||
|
||||
verts[0] = model->verts[poly->v1];
|
||||
verts[1] = model->verts[poly->v2];
|
||||
verts[2] = model->verts[poly->v3];
|
||||
@@ -1234,22 +1234,22 @@ void QTBuilder::AddPlaceable(FileLoader *fileloader, char *ZoneFileName, bool Li
|
||||
ScaleVertex(v2, XScale, YScale, ZScale);
|
||||
ScaleVertex(v3, XScale, YScale, ZScale);
|
||||
|
||||
TranslateVertex(v1, XOffset, YOffset, ZOffset);
|
||||
TranslateVertex(v2, XOffset, YOffset, ZOffset);
|
||||
TranslateVertex(v3, XOffset, YOffset, ZOffset);
|
||||
TranslateVertex(v1, XOffset, YOffset, ZOffset);
|
||||
TranslateVertex(v2, XOffset, YOffset, ZOffset);
|
||||
TranslateVertex(v3, XOffset, YOffset, ZOffset);
|
||||
|
||||
|
||||
// Swap X & Y
|
||||
//
|
||||
tmpv = v1; v1.x = tmpv.y; v1.y = tmpv.x;
|
||||
tmpv = v1; v1.x = tmpv.y; v1.y = tmpv.x;
|
||||
tmpv = v2; v2.x = tmpv.y; v2.y = tmpv.x;
|
||||
tmpv = v3; v3.x = tmpv.y; v3.y = tmpv.x;
|
||||
|
||||
AddFace(v1, v2, v3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void QTBuilder::AddPlaceableV4(FileLoader *fileloader, char *ZoneFileName, bool ListPlaceable) {
|
||||
Polygon *poly;
|
||||
@@ -1262,7 +1262,7 @@ void QTBuilder::AddPlaceableV4(FileLoader *fileloader, char *ZoneFileName, bool
|
||||
//return;
|
||||
|
||||
printf("EQG V4 Placeable Zone Support\n");
|
||||
printf("ObjectGroupCount = %i\n", fileloader->model_data.ObjectGroups.size());
|
||||
printf("ObjectGroupCount = %lu\n", fileloader->model_data.ObjectGroups.size());
|
||||
|
||||
vector<ObjectGroupEntry>::iterator Iterator;
|
||||
|
||||
@@ -1302,7 +1302,7 @@ void QTBuilder::AddPlaceableV4(FileLoader *fileloader, char *ZoneFileName, bool
|
||||
if((ch=='#')&&(StrIndex==0)) { // Discard comment lines beginning with a hash
|
||||
while((ch!=EOF)&&(ch!='\n'))
|
||||
ch = fgetc(IniFile);
|
||||
|
||||
|
||||
continue;
|
||||
}
|
||||
if((ch=='\n') && (State==ReadingZoneName)) {
|
||||
@@ -1337,7 +1337,7 @@ void QTBuilder::AddPlaceableV4(FileLoader *fileloader, char *ZoneFileName, bool
|
||||
{
|
||||
if((ModelNumber >= 0) && ((unsigned int)ModelNumber < fileloader->model_data.ObjectGroups.size()))
|
||||
fileloader->model_data.ObjectGroups[ModelNumber].IncludeInMap = Exclude ? false : true;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1383,13 +1383,13 @@ void QTBuilder::AddPlaceableV4(FileLoader *fileloader, char *ZoneFileName, bool
|
||||
{
|
||||
if((ModelNumber >= 0) && ((unsigned int)ModelNumber < fileloader->model_data.ObjectGroups.size()))
|
||||
fileloader->model_data.ObjectGroups[ModelNumber].IncludeInMap = Exclude ? false : true;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
continue;
|
||||
}
|
||||
IniBuffer[StrIndex++] = tolower(ch);
|
||||
}
|
||||
}
|
||||
fclose(IniFile);
|
||||
|
||||
if(INIEntryFound)
|
||||
@@ -1397,7 +1397,7 @@ void QTBuilder::AddPlaceableV4(FileLoader *fileloader, char *ZoneFileName, bool
|
||||
else
|
||||
printf("No azone.ini entry found for zone %s\n", ZoneFileName);
|
||||
}
|
||||
|
||||
|
||||
Iterator = fileloader->model_data.ObjectGroups.begin();
|
||||
|
||||
while(Iterator != fileloader->model_data.ObjectGroups.end())
|
||||
@@ -1429,11 +1429,11 @@ void QTBuilder::AddPlaceableV4(FileLoader *fileloader, char *ZoneFileName, bool
|
||||
list<int>::iterator ModelIterator;
|
||||
|
||||
ModelIterator = (*Iterator).SubObjects.begin();
|
||||
|
||||
|
||||
while(ModelIterator != (*Iterator).SubObjects.end())
|
||||
{
|
||||
int SubModel = (*ModelIterator);
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
printf(" SubModel: %i\n", (*ModelIterator));
|
||||
#endif
|
||||
@@ -1519,8 +1519,8 @@ void QTBuilder::AddPlaceableV4(FileLoader *fileloader, char *ZoneFileName, bool
|
||||
RotateVertex(v1, RotX, 0, 0);
|
||||
RotateVertex(v2, RotX, 0, 0);
|
||||
RotateVertex(v3, RotX, 0, 0);
|
||||
|
||||
// Don't know why the Y rotation needs to be negative
|
||||
|
||||
// Don't know why the Y rotation needs to be negative
|
||||
//
|
||||
RotateVertex(v1, 0, -RotY, 0);
|
||||
RotateVertex(v2, 0, -RotY, 0);
|
||||
@@ -1556,12 +1556,12 @@ void QTBuilder::AddPlaceableV4(FileLoader *fileloader, char *ZoneFileName, bool
|
||||
TranslateVertex(v3, (*Iterator).x, (*Iterator).y, (*Iterator).z);
|
||||
// Swap X & Y
|
||||
//
|
||||
tmpv = v1; v1.x = tmpv.y; v1.y = tmpv.x;
|
||||
tmpv = v1; v1.x = tmpv.y; v1.y = tmpv.x;
|
||||
tmpv = v2; v2.x = tmpv.y; v2.y = tmpv.x;
|
||||
tmpv = v3; v3.x = tmpv.y; v3.y = tmpv.x;
|
||||
|
||||
AddFace(v1, v2, v3);
|
||||
|
||||
|
||||
}
|
||||
++ModelIterator;
|
||||
}
|
||||
@@ -1619,5 +1619,5 @@ void QTBuilder::TranslateVertex(VERTEX &v, float XOffset, float YOffset, float Z
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user