2017-04-26 17:20:15 +02:00
|
|
|
/*************************************************************************/
|
|
|
|
/* */
|
|
|
|
/* Copyright (c) 1994 Stanford University */
|
|
|
|
/* */
|
|
|
|
/* All rights reserved. */
|
|
|
|
/* */
|
|
|
|
/* Permission is given to use, copy, and modify this software for any */
|
|
|
|
/* non-commercial purpose as long as this copyright notice is not */
|
|
|
|
/* removed. All other uses, including redistribution in whole or in */
|
|
|
|
/* part, are forbidden without prior written permission. */
|
|
|
|
/* */
|
|
|
|
/* This software is provided with absolutely no warranty and no */
|
|
|
|
/* support. */
|
|
|
|
/* */
|
|
|
|
/*************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* NAME
|
|
|
|
* geo.c
|
|
|
|
*
|
|
|
|
* DESCRIPTION
|
|
|
|
* This file contains routines that read both ascii and binary geometry
|
|
|
|
* files, as well as routines to normalize, print, and make a linked
|
|
|
|
* list of the geometry info.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
#include <stdio.h>
|
2017-04-26 17:20:15 +02:00
|
|
|
#include <fcntl.h>
|
2017-04-26 18:03:02 +02:00
|
|
|
#include <math.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include "rt.h"
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocate and initialize sphere function pointer array.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static PPROCS SphProcs =
|
2017-04-26 18:03:02 +02:00
|
|
|
{
|
|
|
|
SphName,
|
|
|
|
SphPrint,
|
|
|
|
SphRead,
|
|
|
|
NULL,
|
|
|
|
SphTransform,
|
|
|
|
SphIntersect,
|
|
|
|
SphPeIntersect,
|
|
|
|
SphNormal,
|
|
|
|
SphDataNormalize,
|
|
|
|
SphBoundBox
|
|
|
|
};
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocate and initialize polygon function pointer array.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static PPROCS PolyProcs =
|
2017-04-26 18:03:02 +02:00
|
|
|
{
|
|
|
|
PolyName,
|
|
|
|
PolyPrint,
|
|
|
|
PolyRead,
|
|
|
|
NULL,
|
|
|
|
PolyTransform,
|
|
|
|
PolyIntersect,
|
|
|
|
PolyPeIntersect,
|
|
|
|
PolyNormal,
|
|
|
|
PolyDataNormalize,
|
|
|
|
PolyBoundBox
|
|
|
|
};
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Allocate and initialize triangle function pointer array.
|
|
|
|
*/
|
|
|
|
|
|
|
|
static PPROCS TriProcs =
|
2017-04-26 18:03:02 +02:00
|
|
|
{
|
|
|
|
TriName,
|
|
|
|
TriPrint,
|
|
|
|
TriRead,
|
|
|
|
NULL,
|
|
|
|
TriTransform,
|
|
|
|
TriIntersect,
|
|
|
|
TriPeIntersect,
|
|
|
|
TriNormal,
|
|
|
|
TriDataNormalize,
|
|
|
|
TriBoundBox
|
|
|
|
};
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* NAME
|
|
|
|
* MakeElementArray - make array of all primitive elements
|
|
|
|
*
|
|
|
|
* SYNOPSIS
|
|
|
|
* ELEMENT **MakeElementArray(totalElements)
|
|
|
|
* INT *totalElements;
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Pointer to array of primitives.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
ELEMENT **MakeElementArray(INT *totalElements)
|
2017-04-26 18:03:02 +02:00
|
|
|
{
|
|
|
|
INT i;
|
|
|
|
OBJECT *po; /* Ptr to object. */
|
|
|
|
INT currArrayPosition = 0;
|
|
|
|
ELEMENT **npepa;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
po = gm->modelroot;
|
|
|
|
*totalElements = 0;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
while (po)
|
|
|
|
{
|
|
|
|
(*totalElements) += po->numelements;
|
|
|
|
po = po->next;
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
po = gm->modelroot;
|
|
|
|
npepa = ObjectMalloc(OT_PEPARRAY, *totalElements);
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
while (po)
|
|
|
|
{
|
|
|
|
for (i = 0; i < po->numelements; i++)
|
|
|
|
npepa[currArrayPosition++] = po->pelem + i;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
po = po->next;
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
return (npepa);
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* NAME
|
|
|
|
* PrintGeo - print object geometry list
|
|
|
|
*
|
|
|
|
* SYNOPSIS
|
|
|
|
* VOID PrintGeo(po)
|
|
|
|
* OBJECT *po; // Ptr to object list to print.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Nothing.
|
|
|
|
*/
|
|
|
|
|
|
|
|
VOID PrintGeo(OBJECT *po)
|
2017-04-26 18:03:02 +02:00
|
|
|
{
|
|
|
|
while (po)
|
|
|
|
{
|
|
|
|
fprintf(stdout, "Object %s\n", po->name);
|
|
|
|
fprintf(stdout, "\tcolor %f %f %f %f %f %f\n",
|
|
|
|
po->surf->fcolor[0], po->surf->fcolor[1],
|
|
|
|
po->surf->fcolor[2], po->surf->bcolor[0],
|
|
|
|
po->surf->bcolor[1], po->surf->bcolor[2]);
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
fprintf(stdout, "\tcoeffs %f %f %f %f %f\n",
|
|
|
|
po->surf->kdiff, po->surf->kspec, po->surf->ktran,
|
|
|
|
po->surf->refrindex, po->surf->kspecn);
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
(*po->procs->print)(po);
|
|
|
|
po = po->next;
|
|
|
|
}
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* NAME
|
|
|
|
* NormalizeGeo - normalize geometry to be within unit cube
|
|
|
|
*
|
|
|
|
* SYNOPSIS
|
|
|
|
* VOID NormalizeData(po, model, modelInvT)
|
|
|
|
* OBJECT *po; // Ptr to object list to normalize.
|
|
|
|
* MATRIX model; // Model matrix.
|
|
|
|
* MATRIX modelInvT; // Model inverse transpose.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Nothing.
|
|
|
|
*/
|
|
|
|
|
|
|
|
VOID NormalizeGeo(OBJECT *po, MATRIX model, MATRIX modelInvT)
|
2017-04-26 18:03:02 +02:00
|
|
|
{
|
|
|
|
REAL norm_minx; /* Normalize min values. */
|
|
|
|
REAL norm_miny;
|
|
|
|
REAL norm_minz;
|
|
|
|
REAL norm_maxx; /* Normalize max values. */
|
|
|
|
REAL norm_maxy;
|
|
|
|
REAL norm_maxz;
|
|
|
|
REAL scale_min; /* Object min max values. */
|
|
|
|
REAL scale_max;
|
|
|
|
REAL scale; /* Normalization scale val. */
|
|
|
|
REAL trans; /* Normalization xlat val. */
|
|
|
|
OBJECT *poHead; /* Ptr to head of object list*/
|
|
|
|
MATRIX normMat; /* Normalization matrix. */
|
|
|
|
MATRIX tempMat; /* Temporary work matrix. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
poHead = po; /* Save ptr to head of list. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
if (! (TraversalType == TT_LIST && ModelNorm == FALSE) )
|
|
|
|
{
|
|
|
|
/* Find global bound box min/max. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
norm_minx = norm_miny = norm_minz = HUGE_REAL;
|
|
|
|
norm_maxx = norm_maxy = norm_maxz = -HUGE_REAL;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
while (po)
|
|
|
|
{
|
|
|
|
norm_minx = Min(norm_minx, po->bv.dnear[0]);
|
|
|
|
norm_miny = Min(norm_miny, po->bv.dnear[1]);
|
|
|
|
norm_minz = Min(norm_minz, po->bv.dnear[2]);
|
|
|
|
norm_maxx = Max(norm_maxx, po->bv.dfar[0]);
|
|
|
|
norm_maxy = Max(norm_maxy, po->bv.dfar[1]);
|
|
|
|
norm_maxz = Max(norm_maxz, po->bv.dfar[2]);
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
po = po->next;
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Compute scale factor. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
scale_min = Min(norm_minx, norm_miny);
|
|
|
|
scale_min = Min(scale_min, norm_minz);
|
|
|
|
scale_max = Max(norm_maxx, norm_maxy);
|
|
|
|
scale_max = Max(scale_max, norm_maxz);
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
scale = 1.0/(scale_max - scale_min);
|
|
|
|
trans = (-scale_min*scale);
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
Scale(tempMat, scale, scale, scale);
|
|
|
|
Translate(normMat, trans, trans, trans);
|
|
|
|
MatrixMult(normMat, tempMat, normMat);
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Now, normalize object data. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
po = poHead;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
while (po)
|
|
|
|
{
|
|
|
|
(*po->procs->normalize)(po, normMat);
|
|
|
|
po = po->next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* NAME
|
|
|
|
* ReadGeoFile - read in the geometry file
|
|
|
|
*
|
|
|
|
* SYNOPSIS
|
|
|
|
* VOID ReadGeoFile(GeoFileName)
|
|
|
|
* CHAR *GeoFileName; // File to open.
|
|
|
|
*
|
|
|
|
* DESCRIPTION
|
|
|
|
* Read in the model file - call primitive object routines to read in
|
|
|
|
* their own data. Objects are put in a linked list.
|
|
|
|
*
|
|
|
|
* Transform objects by modeling transformation if any.
|
|
|
|
*
|
|
|
|
* If TT_LIST traversal, ModelNorm parameter indicates whether data will
|
|
|
|
* be normalized.
|
|
|
|
*
|
|
|
|
* RETURNS
|
|
|
|
* Nothing.
|
|
|
|
*/
|
|
|
|
|
|
|
|
VOID ReadGeoFile(CHAR *GeoFileName)
|
2017-04-26 18:03:02 +02:00
|
|
|
{
|
|
|
|
INT i;
|
|
|
|
INT dummy;
|
|
|
|
INT stat; /* Input read counter. */
|
|
|
|
CHAR comchar;
|
|
|
|
CHAR primop; /* Primitive opcode. */
|
|
|
|
CHAR objstr[NAME_LEN]; /* Object descriptions. */
|
|
|
|
CHAR objname[NAME_LEN];
|
|
|
|
FILE *pf; /* Ptr to geo file desc. */
|
|
|
|
SURF *ps; /* Ptr to surface desc. */
|
|
|
|
MATRIX model; /* Model matrix. */
|
|
|
|
MATRIX modelInv; /* Model matrix inverse. */
|
|
|
|
MATRIX modelInvT; /* Model matrix inv transpose*/
|
|
|
|
OBJECT *prev; /* Ptr to previous object. */
|
|
|
|
OBJECT *curr; /* Ptr to current object. */
|
|
|
|
ELEMENT *pe; /* Ptr to the element list. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Open the model file. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
pf = fopen(GeoFileName, "r");
|
|
|
|
if (!pf)
|
|
|
|
{
|
|
|
|
printf("Unable to open model file %s.\n", GeoFileName);
|
|
|
|
exit(1);
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Initialize pointers and counters. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
curr = NULL;
|
|
|
|
prev = NULL;
|
|
|
|
gm->modelroot = NULL;
|
|
|
|
prim_obj_cnt = 0;
|
|
|
|
prim_elem_cnt = 0;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Retrieve model transform. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
MatrixCopy(model, View.model);
|
|
|
|
MatrixInverse(modelInv, model);
|
|
|
|
MatrixTranspose(modelInvT, modelInv);
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Check for comments. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
if ((comchar = getc(pf)) != '#')
|
|
|
|
ungetc(comchar, pf);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
comchar = '\0'; /* Set to other than '#'. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
while (comchar != '#')
|
|
|
|
if ((comchar = getc(pf)) == EOF)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "Incorrect comment in geometry file.\n");
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Process the file data for each object. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
while ((stat = fscanf(pf, "%s %s", objstr, objname)) != EOF)
|
|
|
|
{
|
|
|
|
if (stat != 2 || strcmp(objstr, "object") != 0)
|
|
|
|
{
|
|
|
|
printf("Invalid object definition %s.\n", objstr);
|
|
|
|
exit(-1);
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Allocate next object and set list pointers. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
prim_obj_cnt++;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
curr = GlobalMalloc(sizeof(OBJECT), "geo.c");
|
|
|
|
curr->index = prim_obj_cnt;
|
|
|
|
curr->next = NULL;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
strcpy(curr->name, objname);
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
if (gm->modelroot == NULL)
|
|
|
|
gm->modelroot = curr;
|
|
|
|
else
|
|
|
|
prev->next = curr;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Get surface characteristics. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
ps = GlobalMalloc(sizeof(SURF), "geo.c");
|
|
|
|
curr->surf = ps;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
stat = fscanf(pf, "%lf %lf %lf %lf %lf %lf",
|
|
|
|
&(ps->fcolor[0]), &(ps->fcolor[1]), &(ps->fcolor[2]),
|
|
|
|
&(ps->bcolor[0]), &(ps->bcolor[1]), &(ps->bcolor[2]));
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
if (stat != 6)
|
|
|
|
{
|
|
|
|
printf("Object color incorrect.\n");
|
|
|
|
exit(-1);
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
stat = fscanf(pf, "%lf %lf %lf %lf %lf",
|
|
|
|
&(ps->kdiff), &(ps->kspec), &(ps->ktran),
|
|
|
|
&(ps->refrindex), &(ps->kspecn));
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
if (stat != 5)
|
|
|
|
{
|
|
|
|
printf("Object surface coefficients incorrect.\n");
|
|
|
|
exit(-1);
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Get texture and flag information. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
stat = fscanf(pf, "%ld %ld %ld %ld\n", &dummy, &dummy, &dummy, &dummy);
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
if (stat != 4)
|
|
|
|
{
|
|
|
|
printf("Texture and/or flag information not all present.\n");
|
|
|
|
exit(-1);
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Get primitive opcode. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
stat = fscanf(pf, "%c %ld", &primop, &(curr->numelements));
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
if (stat != 2)
|
|
|
|
{
|
|
|
|
printf("Object primitive opcode.\n");
|
|
|
|
exit(-1);
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
switch (primop)
|
|
|
|
{
|
|
|
|
case 's':
|
|
|
|
curr->procs = &SphProcs;
|
|
|
|
break;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
case 'p':
|
|
|
|
curr->procs = &PolyProcs;
|
|
|
|
break;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
case 't':
|
|
|
|
curr->procs = &TriProcs;
|
|
|
|
break;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
case 'c':
|
|
|
|
case 'q':
|
|
|
|
printf("Code for cylinders and quadrics not implemented yet.\n");
|
|
|
|
exit(-1);
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
default:
|
|
|
|
printf("Invalid primitive type \'%c\'.\n", primop);
|
|
|
|
exit(-1);
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Allocate primitive elements and create indices. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
pe = GlobalMalloc(sizeof(ELEMENT)*curr->numelements, "geo.c");
|
|
|
|
curr->pelem = pe;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
prim_elem_cnt += curr->numelements;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
for (i = 1; i <= curr->numelements; i++, pe++)
|
|
|
|
pe->index = i;
|
2017-04-26 17:20:15 +02:00
|
|
|
|
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
/* Read, transform, and compute bounding box for object. */
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
(*curr->procs->read)(curr, pf);
|
|
|
|
(*curr->procs->transform)(curr, model, modelInvT);
|
|
|
|
(*curr->procs->bbox)(curr);
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
prev = curr;
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|
2017-04-26 18:03:02 +02:00
|
|
|
NormalizeGeo(gm->modelroot, model, modelInvT);
|
|
|
|
fclose(pf);
|
|
|
|
}
|
2017-04-26 17:20:15 +02:00
|
|
|
|