8 |
|
*/ |
9 |
|
|
10 |
|
#include <stdlib.h> |
11 |
+ |
#include <ctype.h> |
12 |
|
#include "rtio.h" |
13 |
|
#include "rtmath.h" |
14 |
|
#include "rterror.h" |
599 |
|
return(sc); |
600 |
|
} |
601 |
|
|
602 |
+ |
/* Add a vertex to our 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 our 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 our 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 |
|
/* Duplicate a scene */ |
661 |
|
Scene * |
662 |
|
dupScene(const Scene *osc) |
721 |
|
} |
722 |
|
return(sc); |
723 |
|
} |
724 |
+ |
|
725 |
+ |
/* Transform entire scene */ |
726 |
+ |
int |
727 |
+ |
xfScene(Scene *sc, int xac, char *xav[]) |
728 |
+ |
{ |
729 |
+ |
XF myxf; |
730 |
+ |
FVECT vec; |
731 |
+ |
int i; |
732 |
+ |
|
733 |
+ |
if ((sc == NULL) | (xac <= 0) | (xav == NULL)) |
734 |
+ |
return(0); |
735 |
+ |
/* compute matrix */ |
736 |
+ |
if (xf(&myxf, xac, xav) < xac) |
737 |
+ |
return(0); |
738 |
+ |
/* transform vertices */ |
739 |
+ |
for (i = 0; i < sc->nverts; i++) { |
740 |
+ |
VCOPY(vec, sc->vert[i].p); |
741 |
+ |
multp3(vec, vec, myxf.xfm); |
742 |
+ |
VCOPY(sc->vert[i].p, vec); |
743 |
+ |
} |
744 |
+ |
/* transform normals */ |
745 |
+ |
for (i = 0; i < sc->nnorms; i++) { |
746 |
+ |
VCOPY(vec, sc->norm[i]); |
747 |
+ |
multv3(vec, vec, myxf.xfm); |
748 |
+ |
vec[0] /= myxf.sca; vec[1] /= myxf.sca; vec[2] /= myxf.sca; |
749 |
+ |
VCOPY(sc->norm[i], vec); |
750 |
+ |
} |
751 |
+ |
return(xac); /* all done */ |
752 |
+ |
} |
753 |
+ |
|
754 |
+ |
/* Ditto, using transform string rather than pre-parsed words */ |
755 |
+ |
#define MAXAC 100 |
756 |
+ |
int |
757 |
+ |
xfmScene(Scene *sc, const char *xfm) |
758 |
+ |
{ |
759 |
+ |
char *xav[MAXAC+1]; |
760 |
+ |
int xac, i; |
761 |
+ |
|
762 |
+ |
if ((sc == NULL) | (xfm == NULL)) |
763 |
+ |
return(0); |
764 |
+ |
/* skip spaces at beginning */ |
765 |
+ |
while (isspace(*xfm)) |
766 |
+ |
xfm++; |
767 |
+ |
if (!*xfm) |
768 |
+ |
return(0); |
769 |
+ |
/* parse string into words */ |
770 |
+ |
xav[0] = strcpy((char *)malloc(strlen(xfm)+1), xfm); |
771 |
+ |
xac = 1; i = 0; |
772 |
+ |
for ( ; ; ) { |
773 |
+ |
while (!isspace(xfm[++i])) |
774 |
+ |
if (!xfm[i]) |
775 |
+ |
break; |
776 |
+ |
while (isspace(xfm[i])) |
777 |
+ |
xav[0][i++] = '\0'; |
778 |
+ |
if (!xfm[i]) |
779 |
+ |
break; |
780 |
+ |
if (xac >= MAXAC-1) { |
781 |
+ |
free(xav[0]); |
782 |
+ |
return(0); |
783 |
+ |
} |
784 |
+ |
xav[xac++] = xav[0] + i; |
785 |
+ |
} |
786 |
+ |
xav[xac] = NULL; |
787 |
+ |
i = xfScene(sc, xac, xav); |
788 |
+ |
free(xav[0]); |
789 |
+ |
return(i); |
790 |
+ |
} |
791 |
+ |
#undef MAXAC |
792 |
|
|
793 |
|
/* Free a scene */ |
794 |
|
void |