| 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) |
| 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; |
| 674 |
– |
XF myxf; |
| 675 |
– |
FVECT vec; |
| 761 |
|
|
| 762 |
|
if ((sc == NULL) | (xfm == NULL)) |
| 763 |
|
return(0); |
| 764 |
< |
while (isspace(*xfm)) /* find first word */ |
| 764 |
> |
/* skip spaces at beginning */ |
| 765 |
> |
while (isspace(*xfm)) |
| 766 |
|
xfm++; |
| 767 |
|
if (!*xfm) |
| 768 |
|
return(0); |
| 769 |
< |
/* break into words for xf() */ |
| 769 |
> |
/* parse string into words */ |
| 770 |
|
xav[0] = strcpy((char *)malloc(strlen(xfm)+1), xfm); |
| 771 |
|
xac = 1; i = 0; |
| 772 |
|
for ( ; ; ) { |
| 777 |
|
xav[0][i++] = '\0'; |
| 778 |
|
if (!xfm[i]) |
| 779 |
|
break; |
| 780 |
< |
if (xac >= MAXAC-1) |
| 781 |
< |
goto bad_xform; |
| 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 |
< |
if (xf(&myxf, xac, xav) < xac) |
| 700 |
< |
goto bad_xform; |
| 787 |
> |
i = xfScene(sc, xac, xav); |
| 788 |
|
free(xav[0]); |
| 789 |
< |
/* transform vertices */ |
| 703 |
< |
for (i = 0; i < sc->nverts; i++) { |
| 704 |
< |
VCOPY(vec, sc->vert[i].p); |
| 705 |
< |
multp3(vec, vec, myxf.xfm); |
| 706 |
< |
VCOPY(sc->vert[i].p, vec); |
| 707 |
< |
} |
| 708 |
< |
/* transform normals */ |
| 709 |
< |
for (i = 0; i < sc->nnorms; i++) { |
| 710 |
< |
VCOPY(vec, sc->norm[i]); |
| 711 |
< |
multv3(vec, vec, myxf.xfm); |
| 712 |
< |
vec[0] /= myxf.sca; vec[1] /= myxf.sca; vec[2] /= myxf.sca; |
| 713 |
< |
VCOPY(sc->norm[i], vec); |
| 714 |
< |
} |
| 715 |
< |
return xac; /* finito */ |
| 716 |
< |
bad_xform: |
| 717 |
< |
free(xav[0]); |
| 718 |
< |
return(0); |
| 789 |
> |
return(i); |
| 790 |
|
} |
| 791 |
|
#undef MAXAC |
| 792 |
|
|