19 |
|
int |
20 |
|
findName(const char *nm, const char **nmlist, int n) |
21 |
|
{ |
22 |
< |
register int i; |
22 |
> |
int i; |
23 |
|
|
24 |
|
for (i = n; i-- > 0; ) |
25 |
|
if (!strcmp(nmlist[i], nm)) |
322 |
|
goto linkerr; |
323 |
|
/* XXX doesn't allow for multiple references to prev in face */ |
324 |
|
f->v[j].vid = repl; /* replace vertex itself */ |
325 |
< |
if (faceArea(sc, f, NULL) <= FTINY) |
325 |
> |
if (faceArea(sc, f, NULL) <= FTINY*FTINY) |
326 |
|
f->flags |= FACE_DEGENERATE; |
327 |
|
if (f->v[j].tid >= 0) /* replace texture if appropriate */ |
328 |
|
for (i = 0; repl_tex[i] >= 0; i++) { |
599 |
|
return(sc); |
600 |
|
} |
601 |
|
|
602 |
+ |
/* Add a vertex to a scene */ |
603 |
+ |
int |
604 |
+ |
addVertex(Scene *sc, double x, double y, double z) |
605 |
+ |
{ |
606 |
+ |
sc->vert = chunk_alloc(Vertex, sc->vert, sc->nverts); |
607 |
+ |
sc->vert[sc->nverts].p[0] = x; |
608 |
+ |
sc->vert[sc->nverts].p[1] = y; |
609 |
+ |
sc->vert[sc->nverts].p[2] = z; |
610 |
+ |
sc->vert[sc->nverts].vflist = NULL; |
611 |
+ |
return(sc->nverts++); |
612 |
+ |
} |
613 |
+ |
|
614 |
+ |
/* Add a texture coordinate to a scene */ |
615 |
+ |
int |
616 |
+ |
addTexture(Scene *sc, double u, double v) |
617 |
+ |
{ |
618 |
+ |
sc->tex = chunk_alloc(TexCoord, sc->tex, sc->ntex); |
619 |
+ |
sc->tex[sc->ntex].u = u; |
620 |
+ |
sc->tex[sc->ntex].v = v; |
621 |
+ |
return(sc->ntex++); |
622 |
+ |
} |
623 |
+ |
|
624 |
+ |
/* Add a surface normal to a scene */ |
625 |
+ |
int |
626 |
+ |
addNormal(Scene *sc, double xn, double yn, double zn) |
627 |
+ |
{ |
628 |
+ |
FVECT nrm; |
629 |
+ |
|
630 |
+ |
nrm[0] = xn; nrm[1] = yn; nrm[2] = zn; |
631 |
+ |
if (normalize(nrm) == .0) |
632 |
+ |
return(-1); |
633 |
+ |
sc->norm = chunk_alloc(Normal, sc->norm, sc->nnorms); |
634 |
+ |
VCOPY(sc->norm[sc->nnorms], nrm); |
635 |
+ |
return(sc->nnorms++); |
636 |
+ |
} |
637 |
+ |
|
638 |
+ |
/* Set current (last) group */ |
639 |
+ |
void |
640 |
+ |
setGroup(Scene *sc, const char *nm) |
641 |
+ |
{ |
642 |
+ |
sc->lastgrp = findName(nm, (const char **)sc->grpname, sc->ngrps); |
643 |
+ |
if (sc->lastgrp >= 0) |
644 |
+ |
return; |
645 |
+ |
sc->grpname = chunk_alloc(char *, sc->grpname, sc->ngrps); |
646 |
+ |
sc->grpname[sc->lastgrp=sc->ngrps++] = savqstr((char *)nm); |
647 |
+ |
} |
648 |
+ |
|
649 |
+ |
/* Set current (last) material */ |
650 |
+ |
void |
651 |
+ |
setMaterial(Scene *sc, const char *nm) |
652 |
+ |
{ |
653 |
+ |
sc->lastmat = findName(nm, (const char **)sc->matname, sc->nmats); |
654 |
+ |
if (sc->lastmat >= 0) |
655 |
+ |
return; |
656 |
+ |
sc->matname = chunk_alloc(char *, sc->matname, sc->nmats); |
657 |
+ |
sc->matname[sc->lastmat=sc->nmats++] = savqstr((char *)nm); |
658 |
+ |
} |
659 |
+ |
|
660 |
+ |
/* Add new face to a scene */ |
661 |
+ |
Face * |
662 |
+ |
addFace(Scene *sc, VNDX vid[], int nv) |
663 |
+ |
{ |
664 |
+ |
Face *f; |
665 |
+ |
int i; |
666 |
+ |
|
667 |
+ |
if (nv < 3) |
668 |
+ |
return(NULL); |
669 |
+ |
f = (Face *)emalloc(sizeof(Face)+sizeof(VertEnt)*(nv-3)); |
670 |
+ |
f->flags = 0; |
671 |
+ |
f->nv = nv; |
672 |
+ |
f->grp = sc->lastgrp; |
673 |
+ |
f->mat = sc->lastmat; |
674 |
+ |
for (i = 0; i < nv; i++) { /* add each vertex */ |
675 |
+ |
int j; |
676 |
+ |
f->v[i].vid = vid[i][0]; |
677 |
+ |
f->v[i].tid = vid[i][1]; |
678 |
+ |
f->v[i].nid = vid[i][2]; |
679 |
+ |
f->v[i].fnext = NULL; |
680 |
+ |
for (j = i; j-- > 0; ) |
681 |
+ |
if (f->v[j].vid == vid[i][0]) |
682 |
+ |
break; |
683 |
+ |
if (j < 0) { /* first occurrence? */ |
684 |
+ |
f->v[i].fnext = sc->vert[vid[i][0]].vflist; |
685 |
+ |
sc->vert[vid[i][0]].vflist = f; |
686 |
+ |
} else if (nv == 3) /* degenerate triangle? */ |
687 |
+ |
f->flags |= FACE_DEGENERATE; |
688 |
+ |
} |
689 |
+ |
f->next = sc->flist; /* push onto face list */ |
690 |
+ |
sc->flist = f; |
691 |
+ |
sc->nfaces++; |
692 |
+ |
/* check face area */ |
693 |
+ |
if (!(f->flags & FACE_DEGENERATE) && faceArea(sc, f, NULL) <= FTINY*FTINY) |
694 |
+ |
f->flags |= FACE_DEGENERATE; |
695 |
+ |
return(f); |
696 |
+ |
} |
697 |
+ |
|
698 |
|
/* Duplicate a scene */ |
699 |
|
Scene * |
700 |
|
dupScene(const Scene *osc) |
760 |
|
return(sc); |
761 |
|
} |
762 |
|
|
763 |
+ |
#define MAXAC 100 |
764 |
+ |
|
765 |
|
/* Transform entire scene */ |
766 |
|
int |
767 |
|
xfScene(Scene *sc, int xac, char *xav[]) |
768 |
|
{ |
769 |
+ |
char comm[24+MAXAC*8]; |
770 |
+ |
char *cp; |
771 |
|
XF myxf; |
772 |
|
FVECT vec; |
773 |
|
int i; |
790 |
|
vec[0] /= myxf.sca; vec[1] /= myxf.sca; vec[2] /= myxf.sca; |
791 |
|
VCOPY(sc->norm[i], vec); |
792 |
|
} |
793 |
+ |
/* add comment */ |
794 |
+ |
cp = strcpy(comm, "Transformed by:"); |
795 |
+ |
for (i = 0; i < xac; i++) { |
796 |
+ |
while (*cp) cp++; |
797 |
+ |
*cp++ = ' '; |
798 |
+ |
strcpy(cp, xav[i]); |
799 |
+ |
} |
800 |
+ |
addComment(sc, comm); |
801 |
|
return(xac); /* all done */ |
802 |
|
} |
803 |
|
|
804 |
|
/* Ditto, using transform string rather than pre-parsed words */ |
697 |
– |
#define MAXAC 100 |
805 |
|
int |
806 |
|
xfmScene(Scene *sc, const char *xfm) |
807 |
|
{ |