brender-1997/fmt/loadasc.c

243 lines
5 KiB
C
Raw Normal View History

2022-05-03 16:30:35 -05:00
/*
* Copyright (c) 1993-1995 by Argonaut Technologies Limited. All rights reserved.
*
* $Id: loadasc.c 2.3 1996/10/01 14:13:41 sam Exp $
* $Locker: $
*
* Loader for 3D-Studio .ASC format
*
*/
#include "brender.h"
#include "fmt.h"
BR_RCS_ID("$Id: loadasc.c 2.3 1996/10/01 14:13:41 sam Exp $")
/*
* Various keywords than can appear in 3D-Studio .ASC file
*/
#define K_NOP 0
#define K_AMBIENT_LIGHT 1
#define K_NAMED_OBJECT 2
#define K_TRI_MESH 3
#define K_VERTEX 4
#define K_FACE 5
#define K_SMOOTHING 6
#define K_MATERIAL 7
#define K_DIRECT_LIGHT 8
#define K_POSITION 9
#define K_LIGHT_COLOR 10
#define K_CAMERA 11
#define K_TARGET 12
#define K_BANK_ANGLE 13
#define K_EOF 255
static struct {
char *word;
short length;
short token;
#define K(word,token) {word,sizeof(word)-1,token,},
} Keywords[] = {
K("Ambient light color:", K_AMBIENT_LIGHT)
K("Named object: ", K_NAMED_OBJECT)
K("Tri-mesh,", K_TRI_MESH)
K("Vertex list:", K_NOP)
K("Vertex", K_VERTEX)
K("Face list:", K_NOP)
K("Face", K_FACE)
K("Smoothing:", K_SMOOTHING)
K("Material:", K_MATERIAL)
K("Direct light", K_DIRECT_LIGHT)
K("Position:", K_POSITION)
K("Light color:", K_LIGHT_COLOR)
K("Camera ", K_CAMERA)
K("Target ", K_TARGET)
K("Bank angle: ", K_BANK_ANGLE)
};
#undef K
#define MAX_LINE 512
#define MAX_NAME 64
#define TABLE_SIZE 16
static br_model *LoadModels;
static br_material *LoadMaterials;
static br_camera *LoadCameras;
static br_light *LoadLights;
static br_actor *LoadActors;
/*
* Load a 3D-Studio .ASC file and produce -
*
* Models
*
* TODO:
* Actors
* Materials
* Cameras
* Lights
*/
br_uint_32 BR_PUBLIC_ENTRY BrFmtASCLoad(char *name,
br_model **mtable, br_uint_16 max_models)
{
void *fh;
char line[MAX_LINE];
char object_name[MAX_NAME+1] = "";
char material_name[MAX_NAME+1] = "";
char *line_tail;
int token,cvert,cface,vnum,i;
float vx,vy,vz,vu,vv;
int fnum,fa,fb,fc,fab,fbc,fca;
br_model *mp = NULL;
int nmodels = 0,nvertices,nfaces;
int open_mode = BR_FS_MODE_TEXT;
/*
* Open input file
*/
fh = BrFileOpenRead(name,0,NULL,&open_mode);
if(fh == NULL)
BR_ERROR1("Could not open '%s' for reading",name);
/*
* Read lines from input file
*/
while(!BrFileEof(fh)) {
/*
* Pull next line and look at the front to see what it contains:
*/
if(BrFileGetLine(line,MAX_LINE,fh) == 0) {
token = K_NOP;
} else {
token = K_NOP;
for(i=0; i< BR_ASIZE(Keywords); i++) {
if(!BrStrNICmp(Keywords[i].word,line,Keywords[i].length)) {
token = Keywords[i].token;
line_tail = line+Keywords[i].length;
break;
}
}
}
/*
* Perform action for current line
*/
switch(token) {
case K_NAMED_OBJECT:
/*
* Extract name
*/
BrSScanf(line_tail,"\"%64[^\"]",object_name);
break;
case K_MATERIAL:
BrSScanf(line_tail,"\"%64[^\"]",material_name);
/*
* make sure a face has been read
*/
if(cface > 0)
mp->faces[cface-1].material = BrMaterialFind(material_name);
break;
case K_TRI_MESH:
/*
* Fail if no enough space in output table
*/
if(nmodels >= max_models)
return nmodels;
/*
* Allocate a new model and buffers
*/
BrSScanf(line_tail," Vertices: %d Faces: %d",&nvertices,&nfaces);
mp = BrModelAllocate((object_name[0] != '0')?object_name:NULL,nvertices,nfaces);
cvert = 0;
cface = 0;
/*
* Record model in output table
*/
mtable[nmodels++] = mp;
break;
case K_VERTEX:
/*
* Add vertex to current mesh
*/
vx = vy = vz = vu = vv = 0.0F;
BrSScanf(line_tail,"%d: X: %f Y: %f Z: %f U: %f V: %f",&vnum,&vx,&vy,&vz,&vu,&vv);
/*
* Only process if things are consistent
*/
if(cvert != vnum || cvert >= mp->nvertices)
break;
mp->vertices[cvert].p.v[0] = BrFloatToScalar(vx);
mp->vertices[cvert].p.v[1] = BrFloatToScalar(vy);
mp->vertices[cvert].p.v[2] = BrFloatToScalar(vz);
mp->vertices[cvert].map.v[0] = BrFloatToScalar(vu);
mp->vertices[cvert].map.v[1] = BrFloatToScalar(vv);
cvert++;
break;
case K_FACE:
/*
* Add face to current mesh
*/
BrSScanf(line_tail,"%d: A:%d B:%d C:%d AB:%d BC:%d CA:%d",
&fnum,&fa,&fb,&fc,&fab,&fbc,&fca);
/*
* Only process if things are consistent
*/
if(cface != fnum || cface >= mp->nfaces)
break;
mp->faces[cface].vertices[0] = fa;
mp->faces[cface].vertices[1] = fb;
mp->faces[cface].vertices[2] = fc;
mp->faces[cface].material = 0; /* default material */
mp->faces[cface].flags = (fab?0:1) | (fbc?0:2) | (fca?0:4);
cface++;
break;
case K_SMOOTHING:
/*
* Add smoothing group to last face
*/
if(cface > 0) {
mp->faces[cface-1].smoothing = 0;
while(i = BrStrToL(line_tail,&line_tail,0)) {
mp->faces[cface-1].smoothing |= 1<<((i-1) % 16);
while(*line_tail == ',' || *line_tail == ' ')
line_tail++;
}
}
break;
/*
* Ignore everything else
*/
case K_NOP:
default:
;
}
}
BrFileClose(fh);
return nmodels;
}