home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 16
/
CD_ASCQ_16_0994.iso
/
news
/
vr386
/
objfile.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-09
|
11KB
|
423 lines
/* PLG file i/o */
// NEW version by Dave Stampe
/* Original PLG loader written by Bernie Roehl, March 1992 */
// PLG prescanning for total vertex pointers added by Dave Stampe, 22/11/93
// This is a COMPLETE REWRITE for VR-386, by Dave Stampe 8/1/94
/*
This code is part of the VR-386 project, created by Dave Stampe.
VR-386 is a desendent of REND386, created by Dave Stampe and
Bernie Roehl. Almost all the code has been rewritten by Dave
Stampre for VR-386.
Copyright (c) 1994 by Dave Stampe:
May be freely used to write software for release into the public domain
or for educational use; all commercial endeavours MUST contact Dave Stampe
(dstampe@psych.toronto.edu) for permission to incorporate any part of
this software or source code into their products! Usually there is no
charge for under 50-100 items for low-cost or shareware products, and terms
are reasonable. Any royalties are used for development, so equipment is
often acceptable payment.
ATTRIBUTION: If you use any part of this source code or the libraries
in your projects, you must give attribution to VR-386 and Dave Stampe,
and any other authors in your documentation, source code, and at startup
of your program. Let's keep the freeware ball rolling!
DEVELOPMENT: VR-386 is a effort to develop the process started by
REND386, improving programmer access by rewriting the code and supplying
a standard API. If you write improvements, add new functions rather
than rewriting current functions. This will make it possible to
include you improved code in the next API release. YOU can help advance
VR-386. Comments on the API are welcome.
CONTACT: dstampe@psych.toronto.edu
*/
#include <stdio.h>
#include <stdlib.h> /* atoi(), atol() */
#include <string.h>
#include <alloc.h>
#include <ctype.h> /* isalnum() */
#include "vr_api.h"
#include "intmath.h"
static int load_err = 0; /* set if an error was encountered during loading */
static int err_line = 1; /* line on which error occurred */
static char *plg_errmsgs[] = {
"No error",
"Bad syntax in header line",
"Couldn't create new object",
"Couldn't add representation",
"Early EOF while reading vertices",
"Bad syntax in vertex line",
"Early EOF while reading polygons",
"Missing vertex count in polygon line",
"Missing vertex index in polygon line",
"Couldn't add polygon",
"Vertex number out of range",
NULL };
static char errm[50];
char *plg_error(int *errnum)
{
if(errnum) *errnum = load_err;
if(!load_err) return NULL;
sprintf(errm, "File line %d: %s", plg_errmsgs[-load_err]);
return errm;
}
static float xrescale = 1, yrescale = 1, zrescale = 1;
static MATRIX obj_xform;
void strip_comment(char *buff) /* also trim newline character(s) */
{
char *p;
if ((p = strchr(buff, '\n')) != NULL) *p = '\0'; /* trim newline */
if ((p = strchr(buff, '#')) != NULL) *p = '\0'; /* trim comment */
if ((p = strchr(buff, '*')) != NULL) *p = '\0'; /* future expansion */
if(sscanf(buff,"%*s")==EOF) buff[0] = 0; /* dump tabs, etc */
}
static long default_size;
static int maxpolys;
static int maxverts;
static int multirep = 0;
static int prescan = 0; // PRESCAN to find total poly vertices
static int tpverts = 0;
static int tpvcount = 0;
// if <obj> is null, creates new fixed object
// else loads new representation to <obj>
static int load_in_plg_file(FILE *in, OBJECT **obj)
{
char tbuff[1000], objname[100];
int nv, np, i;
char *p;
int size = 0;
int multi = (*obj) ? 1 : 0; /* multi-reps if not null object */
tpvcount = 0;
multirep = 0;
/* skip blank lines */
do {
if (fgets(tbuff, sizeof(tbuff), in) == NULL) return -1;
++err_line;
if (strstr(tbuff,"#MULTI")) multi++;
if (multi) multirep++;
strip_comment(tbuff);
}
while (tbuff[0] == '\0'); // NEW NOW LOADS TPVERTS
if (sscanf(tbuff, "%s %d %d %d", objname, &nv, &np, &tpverts) < 3)
{
load_err = -1;
return -1;
}
if(tpverts) // we got our count!
{
prescan = 0;
}
if (multi && (p = strchr(objname, '_')) != NULL)
{
*p++ = 0;
size = atoi(p);
}
else size = default_size; /* default: use largest detail always */
if(!prescan)
{
if (*obj == NULL)
{
if ((*obj = create_fixed_object(nv, np, tpverts)) == NULL)
{
load_err = -2;
return -1;
}
set_representation_size(*obj, size);
}
else
{
if (add_representation(*obj, size, nv, np, tpverts) == NULL)
{
load_err = -3;
return -1;
}
}
}
maxpolys = np;
maxverts = nv;
for (i = 0; i < nv; ++i) /* load in vertices */
{
float x, y, z;
/* skip blank lines */
do
{
if (fgets(tbuff, sizeof(tbuff), in) == NULL)
{
load_err = -4;
return -1;
}
++err_line;
strip_comment(tbuff);
}
while (tbuff[0] == '\0');
if (sscanf(tbuff, "%f %f %f", &x, &y, &z) != 3)
{
load_err = -5;
return -1;
}
if(!prescan) // map the vertex
{
COORD xx = x*xrescale;
COORD yy = y*yrescale;
COORD zz = z*zrescale;
matrix_point(obj_xform, &xx, &yy, &zz);
add_vertex(*obj, xx, yy, zz);
}
}
for (i = 0; i < np; ++i) /* load polygons */
{
int j, npoints;
unsigned color;
POLY *poly;
char *p;
/* skip blank lines */
do
{
if (fgets(tbuff, sizeof(tbuff), in) == NULL)
{
load_err = -6;
return -1;
}
++err_line;
strip_comment(tbuff);
}
while (tbuff[0] == '\0');
color = convert_color(tbuff,&p);
if ((p = strtok(p, " \t")) == NULL)
{
load_err = -7;
return -1;
}
npoints = atoi(p);
if (prescan)
{
tpvcount += npoints; // this is all prescan wanted!
}
else
{
if ((poly = add_poly(*obj, color, npoints)) == NULL)
{
load_err = -9;
return -1;
}
for (j = 0; j < npoints; ++j)
{
int vertnum;
if ((p = strtok(NULL, " \t")) == NULL)
{
load_err = -8;
return -1;
}
vertnum = atoi(p);
if (vertnum < 0 || vertnum >= maxverts)
{
load_err = -10;
return -1;
}
add_point(*obj, poly, vertnum);
}
compute_object(*obj); /* will do current rep only */
}
}
load_err = 0;
return 0;
}
// read file with prescan if it doesn't have total poly verts
// if <obj> is null, creates new fixed object
// else loads new representation to <obj>
static int read_plg_file(FILE *in, VISOBJ **obj)
{
int retc;
long fptr = ftell(in);
prescan = 1;
tpverts = 0;
if (0!=(retc=load_in_plg_file(in, obj))) return retc;
if(!prescan) return retc; // we got total poly verts thru file!
fseek(in, fptr, 0);
prescan = 0;
tpverts = tpvcount;
return load_in_plg_file(in, obj);
}
// create the matrix and scales for object loading
void create_obj_xform(POSE *p, float xs, float ys, float zs)
{
if (p->x == DONTCARE) p->x = 0;
if (p->y == DONTCARE) p->y = 0;
if (p->z == DONTCARE) p->z = 0;
if (p->rx == DONTCARE) p->rx = 0;
if (p->ry == DONTCARE) p->ry = 0;
if (p->rz == DONTCARE) p->rz = 0;
multi_matrix(obj_xform, p->rx, p->ry, p->rz, p->x, p->y, p->z, RYXZ);
if (xs<=0.001) xrescale = 0.001; else xrescale = xs;
if (ys<=0.001) yrescale = 0.001; else yrescale = ys;
if (zs<=0.001) zrescale = 0.001; else zrescale = zs;
}
// loads a new rep to an old object.
// useful to create morphing animations
// just loads FIRST if not multi-rep file
OBJECT *load_extra_plg_representation(FILE *in, OBJECT *obj, POSE *p,
float sx, float sy, float sz, WORD size)
{
int ocount = 0;
default_size = size;
load_err = 0;
err_line = 1;
create_obj_xform(p, sx, sy, sz);
while (read_plg_file(in, &obj) == 0) // read all we can
{
ocount++;
if (!multirep) break;
}
default_size = 0;
if (ocount == 0) return NULL;
return obj;
}
// loads single and multi-rep files
// will load only one object: call again if not EOF
OBJECT *load_plg_object(FILE *in, POSE *p,
float sx, float sy, float sz, WORD depth)
{
OBJECT *obj = NULL;
int ocount = 0;
default_size = 0;
load_err = 0;
err_line = 1;
create_obj_xform(p, sx, sy, sz);
while (read_plg_file(in, &obj) == 0)
{
ocount++;
if (!multirep) break;
}
if (ocount == 0) return NULL;
set_object_sorting(obj, depth);
mark_object_invisible(obj); // invisible till placed in world
return obj;
}
WORD load_plg_to_objlist(FILE *in, OBJLIST *objlist, WORD maxobj, POSE *p,
float sx, float sy, float sz, WORD depth)
{
VISOBJ *obj;
int olcount = 0;
int ocount;
default_size = 0;
load_err = 0;
err_line = 1;
create_obj_xform(p, sx, sy, sz);
while(!feof(in) && olcount<maxobj)
{
ocount = 0;
obj = NULL;
while (read_plg_file(in, &obj) == 0)
{
ocount++;
if (!multirep) break;
}
if (ocount == 0) goto load_failed;
set_object_sorting(obj, depth);
mark_object_invisible(obj); // invisible to keep on list till placed in world
add_to_objlist(objlist, obj);
olcount++;
}
load_failed:
return olcount;
}
// save a PLG object
// no name
BOOL save_plg(OBJECT *obj, FILE *out, BOOL world)
{
int nv, np, tv, i; /* now saves all representations */
char buff[100];
int multi = 0;
if(!(obj=object2visobj(obj))) return -1; // is a segment!
select_first_representation(obj); // test if multiple representations
multi = select_next_representation(obj);
select_first_representation(obj); // back to first
if(multi) fprintf(out, "##MULTI\n");
do
{
get_obj_info(obj, &nv, &np);
tv = total_object_pverts(obj); // now saves total vtx count for future upgrades
fprintf(out, "SAVED %d %d *d\n", nv, np, tv);
for (i = 0; i < nv; ++i)
{
long x, y, z;
if (world) get_vertex_world_info(obj, i, &x, &y, &z);
else get_vertex_info(obj, i, &x, &y, &z);
fprintf(out, "%ld %ld %ld\n", x, y, z);
}
for (i = 0; i < np; ++i)
{
int j, n, verts[1000];
unsigned c;
get_poly_info(obj, i, &c, &n);
fprintf(out, "0x%04.4X %d", c & 0x7FFF, n);
for (j = 0; j < n; ++j)
{
fprintf(out, " %d", get_poly_vertex_index(obj, i, j));
}
fprintf(out, "\n");
}
}
while (!select_next_representation(obj));
return 0;
}