/***************************************************************************
file : relief.cpp
created : Tue Mar 6 23:15:19 CET 2001
copyright : (C) 2000 by Eric Espie
email : eric.espie@torcs.org
version : $Id: relief.cpp,v 1.6 2003/05/18 20:41:32 torcs Exp $
***************************************************************************/
/***************************************************************************
* *
* 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; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
/** @file
@author Eric Espie
@version $Id: relief.cpp,v 1.6 2003/05/18 20:41:32 torcs Exp $
*/
#include
#include
#include
#include
#ifndef WIN32
#include
#else
#include
#endif
#include
#include
#include
#include
#include
#include "trackgen.h"
#include "easymesh.h"
#include "relief.h"
typedef struct Line
{
GF_TAILQ_ENTRY(struct Line) link;
ssgBranch *branch;
} tLine;
GF_TAILQ_HEAD(RingListHead, tLine);
tRingListHead InteriorList;
tRingListHead ExteriorList;
static tdble GridStep;
static ssgEntity *Root = NULL;
/*
* Read the faces from AC3D file
* separate between interior and exterior lines
*/
static ssgBranch *
hookNode(char *s)
{
tLine *line;
line = (tLine*)calloc(1, sizeof(tLine));
line->branch = new ssgBranch();
if (strncmp(s, "interior", 8) == 0) {
GF_TAILQ_INSERT_TAIL(&InteriorList, line, link);
} else {
GF_TAILQ_INSERT_TAIL(&ExteriorList, line, link);
}
return line->branch;
}
/*
Load a simple database
*/
void
LoadRelief(void *TrackHandle, char *reliefFile)
{
GF_TAILQ_INIT(&InteriorList);
GF_TAILQ_INIT(&ExteriorList);
GridStep = GfParmGetNum(TrackHandle, TRK_SECT_TERRAIN, TRK_ATT_BSTEP, NULL, GridStep);
ssgLoaderOptions *loaderopt = new ssgLoaderOptions();
loaderopt->setCreateBranchCallback(hookNode);
printf("\nLoading relief file %s\n", reliefFile);
Root = ssgLoadAC(reliefFile, loaderopt);
}
static void
countRec(ssgEntity *e, int *nb_vert, int *nb_seg)
{
if (e->isAKindOf(_SSG_TYPE_BRANCH)) {
ssgBranch *br = (ssgBranch *)e;
for (int i = 0; i < br->getNumKids(); i++) {
countRec(br->getKid(i), nb_vert, nb_seg);
}
} else {
if (e->isAKindOf(_SSG_TYPE_VTXTABLE)) {
ssgVtxTable *vt = (ssgVtxTable *)e;
*nb_vert += vt->getNumVertices();
*nb_seg += vt->getNumLines();
}
}
}
void
CountRelief(int interior, int *nb_vert, int *nb_seg)
{
tLine *curLine;
tRingListHead *curHead;
*nb_vert = *nb_seg = 0;
if (Root == NULL) {
return;
}
if (interior) {
curHead = &InteriorList;
} else {
curHead = &ExteriorList;
}
curLine = GF_TAILQ_FIRST(curHead);
while (curLine != NULL) {
ssgBranch *br = curLine->branch->getParent(0);
ssgBranch *br2 = new ssgBranch();
br2->addKid(br);
ssgFlatten(br);
curLine->branch = br2;
countRec((ssgEntity *)curLine->branch, nb_vert, nb_seg);
curLine = GF_TAILQ_NEXT(curLine, link);
}
}
static void
genRec(ssgEntity *e)
{
if (e->isAKindOf(_SSG_TYPE_BRANCH)) {
ssgBranch *br = (ssgBranch *)e;
for (int i = 0; i < br->getNumKids(); i++) {
genRec(br->getKid(i));
}
} else {
if (e->isAKindOf(_SSG_TYPE_VTXTABLE)) {
ssgVtxTable *vt = (ssgVtxTable *)e;
int nv = vt->getNumVertices();
int nl = vt->getNumLines();
int sv = Nc;
int i;
for (i = 0; i < nv; i++) {
float *vtx = vt->getVertex(i);
point[Nc].x = vtx[0];
point[Nc].y = vtx[1];
point[Nc].z = vtx[2];
point[Nc].F = GridStep;
point[Nc].mark = 100000;
Nc++;
}
for (i = 0; i < nl; i++) {
short vv0, vv1;
vt->getLine(i, &vv0, &vv1);
segment[Fl].n0 = vv0 + sv;
segment[Fl].n1 = vv1 + sv;
segment[Fl].mark = 100000;
Fl++;
}
}
}
}
void
GenRelief(int interior)
{
tLine *curLine;
tRingListHead *curHead;
if (Root == NULL) {
return;
}
if (interior) {
curHead = &InteriorList;
} else {
curHead = &ExteriorList;
}
curLine = GF_TAILQ_FIRST(curHead);
while (curLine != NULL) {
genRec((ssgEntity *)curLine->branch);
curLine = GF_TAILQ_NEXT(curLine, link);
}
}