home *** CD-ROM | disk | FTP | other *** search
- /* writelwob.c - write a LightWave3D object file
- * - by traversing the TTDDDLIB database
- * - written by Glenn M. Lewis - 8/7/92
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include "t3dlib.h"
- #ifdef __STDC__
- #include <stdlib.h>
- #include <strings.h>
- #include "writelwob_protos.h"
- #endif
-
- #ifdef AZTEC_C
- #include <fcntl.h>
- #include <exec/types.h>
- #endif
-
- static void process_INFO();
- static void process_OBJ();
- static void process_EXTR();
- static void process_DESC();
-
- /* Here are a few necessary utilities */
-
- static void put_name(world, name, size)
- WORLD *world;
- register char *name;
- register int size;
- {
- while (*name && size) {
- fputc(*name++, world->inp);
- size--;
- }
- while (size--) fputc(0, world->inp); /* Pad the rest of the string w/ 0 */
- }
-
- static void put_UBYTE(world, u)
- WORLD *world;
- UBYTE u;
- {
- fputc((char)u, world->inp);
- }
-
- static void put_UWORD(world, w)
- WORLD *world;
- UWORD w;
- {
- put_UBYTE(world, (UBYTE)(w>>8));
- put_UBYTE(world, (UBYTE)(w&0xFF));
- }
-
- static void put_ULONG(world, l)
- WORLD *world;
- ULONG l;
- {
- put_UWORD(world, (UWORD)(l>>16));
- put_UWORD(world, (UWORD)(l&0xFFFF));
- }
-
- static void put_FRACT(world, f)
- WORLD *world;
- double f;
- {
- union { /* Nasty... pass it a double, get it as a ULONG */
- double f;
- ULONG l;
- } num;
- num.f = f;
- put_ULONG(world, num.l);
- }
-
- static void put_XYZ(world, st) /* Write a common string */
- WORLD *world;
- XYZ_st *st;
- {
- put_FRACT(world, st->x);
- put_FRACT(world, st->z); /* Swap Y & Z for LightWave3D */
- put_FRACT(world, st->y);
- }
-
- static void put_RGB(world, st) /* Write a common string */
- WORLD *world;
- RGB_st *st;
- {
- put_UBYTE(world, 0); /* PAD */
- put_UBYTE(world, st->r);
- put_UBYTE(world, st->g);
- put_UBYTE(world, st->b);
- }
-
- static void write_size(world, pos)
- WORLD *world;
- long pos;
- {
- long size;
- long cur = ftell(world->inp);
- size = cur-pos;
- if (size&1) { size++; put_UBYTE(world, (UBYTE)0); }
- fseek(world->inp, pos-4L, 0);
- put_ULONG(world, (ULONG)size);
- fseek(world->inp, cur, 0);
- }
-
- /********************/
- /* The MAIN section */
- /********************/
-
- int write_LWOB(world, myfile)
- WORLD *world;
- FILE *myfile;
- {
- long pos, pos2;
- OBJECT *obj;
-
- if (!world || !myfile) return(0);
- world->inp = myfile;
-
- /* Start the IFF TDDD file */
- put_name(world, "FORM", 4);
- put_ULONG(world, 0L); /* Fill this in later [seek(,4L,0)] */
- pos = ftell(world->inp); /* Save where this starting position is */
- put_name(world, "LWOB", 4);
-
- /* First, write *all* of the points in the entire object, up to 64K */
- /* Swap the Y and Z values because of the changed axis orientation */
- put_name(world, "PNTS", 4);
- put_ULONG(world, 0L);
- pos2 = ftell(world->inp); /* Save for later */
- for (obj=world->object; obj; obj=obj->next) {
- dump_points(world, obj);
- }
- write_size(world, pos2);
-
- /* All done. Close up shop. */
- write_size(world, pos);
- fclose(world->inp);
- return(1);
- }
-
- void dump_points(world, object)
- WORLD *world;
- register OBJECT *object;
- {
- register int i;
- register XYZ_st *p;
- OBJECT *obj;
-
- if (object->desc && object->desc->pcount) {
- p = object->desc->pnts;
- for (i=object->desc->pcount; i--; p++)
- put_XYZ(world, p);
- }
-
- /* Process children */
- for (obj=object->child; obj; obj=obj->next)
- dump_points(world, obj);
- }
-
- static void process_INFO(world, info)
- WORLD *world;
- INFO *info;
- {
- register ULONG i;
- long pos;
-
- put_name(world, "INFO", 4);
- put_ULONG(world, 0L);
- pos = ftell(world->inp); /* Save for later */
-
- for (i=0; i<8; i++)
- if (info->brsh[i][0]) {
- put_name(world, "BRSH", 4);
- put_ULONG(world, 82L);
- put_UWORD(world, (UWORD)i);
- put_name(world, info->brsh[i], 80);
- }
-
- for (i=0; i<8; i++)
- if (info->stnc[i][0]) {
- put_name(world, "STNC", 4);
- put_ULONG(world, 82L);
- put_UWORD(world, (UWORD)i);
- put_name(world, info->stnc[i], 80);
- }
-
- for (i=0; i<8; i++)
- if (info->txtr[i][0]) {
- put_name(world, "TXTR", 4);
- put_ULONG(world, 82L);
- put_UWORD(world, (UWORD)i);
- put_name(world, info->txtr[i], 80);
- }
-
- if (info->otrk[0]) {
- put_name(world, "OTRK", 4);
- put_ULONG(world, 18L);
- put_name(world, info->otrk, 18);
- }
-
- if (info->ambi) {
- put_name(world, "AMBI", 4);
- put_ULONG(world, 4L);
- put_RGB(world, info->ambi);
- }
-
- if (info->obsv) {
- put_name(world, "OBSV", 4);
- put_ULONG(world, 28L);
- put_XYZ(world, &info->obsv->came);
- put_XYZ(world, &info->obsv->rota);
- put_FRACT(world, info->obsv->foca);
- }
-
- if (info->ostr) {
- put_name(world, "OSTR", 4);
- put_ULONG(world, 56L);
- put_name(world, info->ostr->path, 18);
- put_XYZ(world, &info->ostr->tran);
- put_XYZ(world, &info->ostr->rota);
- put_XYZ(world, &info->ostr->scal);
- put_UWORD(world, info->ostr->info);
- }
-
- if (info->fade) {
- put_name(world, "FADE", 4);
- put_ULONG(world, 12L);
- put_FRACT(world, info->fade->at);
- put_FRACT(world, info->fade->by);
- put_RGB(world, &info->fade->to);
- }
-
- if (info->skyc) {
- put_name(world, "SKYC", 4);
- put_ULONG(world, 8L);
- put_RGB(world, &info->skyc->hori);
- put_RGB(world, &info->skyc->zeni);
- }
-
- if (info->glb0) {
- put_name(world, "GLB0", 4);
- put_ULONG(world, 8L);
- for (i=0; i<8; i++)
- put_UBYTE(world, (UBYTE)info->glb0[i]);
- }
- write_size(world, pos);
- }
-
- static void process_OBJ(world, obj)
- WORLD *world;
- OBJECT *obj;
- {
- OBJECT *o;
-
- if (obj->extr) process_EXTR(world, obj);
- else process_DESC(world, obj);
-
- for (o=obj->child; o; o=o->next)
- process_OBJ(world, o);
-
- put_name(world, "TOBJ", 4);
- put_ULONG(world, 0L);
- }
-
- static void process_EXTR(world, obj)
- WORLD *world;
- OBJECT *obj;
- {
- long pos;
-
- put_name(world, "EXTR", 4);
- put_ULONG(world, 0L);
- pos = ftell(world->inp); /* Save for later */
-
- put_name(world, "LOAD", 4);
- put_ULONG(world, 80L);
- put_name(world, obj->extr->filename, 80);
-
- put_name(world, "MTRX", 4);
- put_ULONG(world, 60L);
- put_XYZ(world, &obj->extr->mtrx.tran);
- put_XYZ(world, &obj->extr->mtrx.scal);
- put_XYZ(world, &obj->extr->mtrx.rota1);
- put_XYZ(world, &obj->extr->mtrx.rota2);
- put_XYZ(world, &obj->extr->mtrx.rota3);
-
- write_size(world, pos);
- }
-
- static void process_DESC(world, obj)
- WORLD *world;
- OBJECT *obj;
- {
- register int i;
- register DESC *desc;
- FGRP *fgrp;
- long pos;
-
- if (!obj) return;
- desc = obj->desc;
- if (!desc) return;
-
- put_name(world, "DESC", 4);
- put_ULONG(world, 0L);
- pos = ftell(world->inp); /* Save for later */
-
- if (desc->name) {
- put_name(world, "NAME", 4);
- put_ULONG(world, 18L);
- put_name(world, desc->name, 18);
- }
-
- if (desc->posi) {
- put_name(world, "POSI", 4);
- put_ULONG(world, 12L);
- put_XYZ(world, desc->posi);
- }
-
- if (desc->size) {
- put_name(world, "SIZE", 4);
- put_ULONG(world, 12L);
- put_XYZ(world, desc->size);
- }
-
- if (desc->colr) {
- put_name(world, "COLR", 4);
- put_ULONG(world, 4L);
- put_RGB(world, desc->colr);
- }
-
- if (desc->refl) {
- put_name(world, "REFL", 4);
- put_ULONG(world, 4L);
- put_RGB(world, desc->refl);
- }
-
- if (desc->tran) {
- put_name(world, "TRAN", 4);
- put_ULONG(world, 4L);
- put_RGB(world, desc->tran);
- }
-
- if (desc->spc1) {
- put_name(world, "SPC1", 4);
- put_ULONG(world, 4L);
- put_RGB(world, desc->spc1);
- }
-
- if (desc->ints) {
- put_name(world, "INTS", 4);
- put_ULONG(world, 4L);
- put_FRACT(world, (*desc->ints));
- }
-
- /* Mandatory field... stuff it, regardless */
- if (desc->shap) {
- put_name(world, "SHAP", 4);
- put_ULONG(world, 4L);
- put_UWORD(world, (UWORD)desc->shap[0]);
- put_UWORD(world, (UWORD)desc->shap[1]);
- } else {
- put_name(world, "SHAP", 4);
- put_ULONG(world, 4L);
- put_UWORD(world, (UWORD)2);
- put_UWORD(world, (UWORD)1);
- }
-
- if (desc->axis) {
- put_name(world, "AXIS", 4);
- put_ULONG(world, 36L);
- put_XYZ(world, &desc->axis->xaxi);
- put_XYZ(world, &desc->axis->yaxi);
- put_XYZ(world, &desc->axis->zaxi);
- }
-
- if (desc->tpar) {
- put_name(world, "TPAR", 4);
- put_ULONG(world, 64L);
- for (i=0; i<16; i++) put_FRACT(world, desc->tpar[i]);
- }
-
- if (desc->surf) {
- put_name(world, "SURF", 4);
- put_ULONG(world, 5L);
- for (i=0; i<5; i++) put_UBYTE(world, desc->surf[i]);
- put_UBYTE(world, (UBYTE)0); /* To make this chunk even-sized */
- }
-
- if (desc->mttr) {
- put_name(world, "MTTR", 4);
- put_ULONG(world, 2L);
- put_UBYTE(world, desc->mttr->type);
- put_UBYTE(world, (UBYTE)(((int)((desc->mttr->indx-1.0)*100.0))&0xFF));
- }
-
- if (desc->spec) {
- put_name(world, "SPEC", 4);
- put_ULONG(world, 2L);
- put_UBYTE(world, desc->spec[0]);
- put_UBYTE(world, desc->spec[1]);
- }
-
- if (desc->prp0) {
- put_name(world, "PRP0", 4);
- put_ULONG(world, 6L);
- for (i=0; i<6; i++) put_UBYTE(world, desc->prp0[i]);
- }
-
- if (desc->prp1) {
- put_name(world, "PRP1", 4);
- put_ULONG(world, 8L);
- for (i=0; i<8; i++) put_UBYTE(world, desc->prp1[i]);
- }
-
- if (desc->stry) {
- put_name(world, "STRY", 4);
- put_ULONG(world, 56L);
- put_name(world, desc->stry->path, 18);
- put_XYZ(world, &desc->stry->tran);
- put_XYZ(world, &desc->stry->rota);
- put_XYZ(world, &desc->stry->scal);
- put_UWORD(world, desc->stry->info);
- }
-
- if (desc->pcount) {
- put_name(world, "PNTS", 4);
- put_ULONG(world, (ULONG)desc->pcount*12L+2L);
- put_UWORD(world, desc->pcount);
- for (i=0; i<desc->pcount; i++)
- put_XYZ(world, &desc->pnts[i]);
- }
-
- if (desc->ecount) {
- put_name(world, "EDGE", 4);
- put_ULONG(world, (ULONG)desc->ecount*4L+2L);
- put_UWORD(world, desc->ecount);
- for (i=0; i<2*desc->ecount; i++)
- put_UWORD(world, desc->edge[i]);
- }
-
- if (desc->eflg) {
- put_name(world, "EFLG", 4);
- put_ULONG(world, (ULONG)desc->eflg->num+2L);
- put_UWORD(world, desc->eflg->num);
- for (i=0; i<desc->eflg->num; i++)
- put_UBYTE(world, desc->eflg->eflg[i]);
- if (desc->eflg->num&1) put_UBYTE(world, 0); /* Pad on even boundary */
- }
-
- if (desc->fcount) {
- put_name(world, "FACE", 4);
- put_ULONG(world, (ULONG)desc->fcount*6L+2L);
- put_UWORD(world, desc->fcount);
- for (i=0; i<3*desc->fcount; i++)
- put_UWORD(world, desc->face[i]);
-
- if (desc->clst) {
- put_name(world, "CLST", 4);
- put_ULONG(world, (ULONG)desc->fcount*3L+2L);
- put_UWORD(world, desc->fcount);
- for (i=0; i<3*desc->fcount; i++)
- put_UBYTE(world, desc->clst[i]);
- if (desc->fcount&1) put_UBYTE(world, 0); /* Pad to even length */
- }
- if (desc->rlst) {
- put_name(world, "RLST", 4);
- put_ULONG(world, (ULONG)desc->fcount*3L+2L);
- put_UWORD(world, desc->fcount);
- for (i=0; i<3*desc->fcount; i++)
- put_UBYTE(world, desc->rlst[i]);
- if (desc->fcount&1) put_UBYTE(world, 0); /* Pad to even length */
- }
- if (desc->tlst) {
- put_name(world, "TLST", 4);
- put_ULONG(world, (ULONG)desc->fcount*3L+2L);
- put_UWORD(world, desc->fcount);
- for (i=0; i<3*desc->fcount; i++)
- put_UBYTE(world, desc->tlst[i]);
- if (desc->fcount&1) put_UBYTE(world, 0); /* Pad to even length */
- }
- }
-
- for (fgrp=desc->fgrp; fgrp; fgrp=fgrp->next) {
- put_name(world, "FGRP", 4);
- put_ULONG(world, (ULONG)fgrp->num*2L+2L+18L);
- put_UWORD(world, fgrp->num);
- put_name(world, fgrp->name, 18);
- for (i=0; i<fgrp->num; i++)
- put_UWORD(world, fgrp->face[i]);
- }
- write_size(world, pos);
- }
-
-