home *** CD-ROM | disk | FTP | other *** search
- #include <math.h>
- #include "mytypes.h"
- #include "scrnio.h"
- #include "bezpt.h"
- #include "revolve.h"
- #include "control.h"
- #include "poly.h"
- #include "readilbm.h"
- #include "menuexp.h"
-
- bool SpecOn = false; /* specular lighting enable - default off */
-
- float Ambience = DefAmbience;
- float PtIntensity = (float)DefIntensity;
- float Kd = DefKd,
- Ks = DefKs;
-
- Pt3 LightSrc = {
- DefLightSrcX,
- DefLightSrcY,
- DefLightSrcZ
- };
-
- static
- Rhomboid *polylist = null,
- *nextpoly;
-
- MapRhomboid *mpolylist = null,
- *mnextpoly;
-
- static
- int polyspace = 0;
-
-
- static bool shadeflag;
-
- long CalcMaxPolyNum() {
- return( GetNumSegs() * BezMesh * RevMesh );
- }
-
- static
- bool PrepPoly()
- {
- if( polylist ) free( (char *)polylist );
- polylist = (Rhomboid *)malloc( CalcMaxPolyNum() * sizeof(Rhomboid));
- if( !polylist ) {
- OutErr("PrepPoly: not enough memory");
- return( true );
- }
- nextpoly = polylist;
- return(false); /* success = 0 */
- }
-
-
- static bool
- PrepMPoly()
- {
- if( mpolylist ) free( (char *)mpolylist );
- mpolylist = (MapRhomboid *)
- malloc( CalcMaxPolyNum() * sizeof(MapRhomboid));
- if( !mpolylist ) {
- OutErr("PrepPoly: not enough memory");
- return( true );
- }
- mnextpoly = mpolylist;
- return(false); /* success = 0 */
- }
-
-
- /*
- * Multiply a vector by scalar quantity
- */
- void ScaleVec( fact, src, dst )
- float fact;
- Pt3 *src, *dst;
- {
- dst->x = src->x * fact;
- dst->y = src->y * fact;
- dst->z = src->z * fact;
- }
- /*
- * convert a vector to a unitized vector
- * if possible
- */
- void Unitize( vec )
- Pt3 *vec;
- {
- float len;
-
- len = vec->x*vec->x + vec->y*vec->y + vec->z*vec->z;
- len = sqrt( len );
- if( len != 0.0 ) {
- vec->x /= len;
- vec->y /= len;
- vec->z /= len;
- }
- }
-
- /*
- * calculate a vector from two points
- */
- void CalcVector( src1, src2, dest )
- Pt3 *src1, *src2, *dest ;
- {
- dest->x = src1->x - src2->x;
- dest->y = src1->y - src2->y;
- dest->z = src1->z - src2->z;
- }
-
-
-
-
- /*
- * calculate a normal from a list of polygons. This routine does the
- * logical trick of trying to exclude each point in turn if the
- * normal can not be calculated, or something of the sort.
- * a value of true is returned if a normal with a nonzero z component
- * could not be calculated
- */
-
- bool CalcNormal( vxlist, normal)
- PtGen *vxlist[];
- register Pt3 *normal;
- {
- int i, k, m;
- Pt3 *j[3];
- Pt3 v1, v2;
-
- for( i = 0; i < RhomVxNum; i++ ) {
- for( k = 0, m = 3; m--; k++ ) {
- if( k == i ) {
- k++;
- }
- j[m] = &vxlist[k]->d3;
- }
- CalcVector( j[1], j[0], &v1 );
- CalcVector( j[2], j[1], &v2 );
-
- normal->z = v1.x*v2.y - v1.y*v2.x;
- if( normal->z == 0 ) {
- continue;
- }
- normal->x = v1.y*v2.z - v1.z*v2.y;
- normal->y = v1.z*v2.x - v1.x*v2.z;
- if( normal->z < 0 ) {
- normal->x = -normal->x;
- normal->y = -normal->y;
- normal->z = -normal->z;
- }
- Unitize(normal);
- return( false );
- }
- return(true);
- }
-
-
- /*
- * Euclidean dot product.
- * I wonder what the minkowski dot product would look like
- */
- float DotProd( v1, v2 )
- Pt3 *v1, *v2;
- {
- return( v1->x*v2->x + v1->y*v2->y + v1->z*v2->z );
- }
-
-
-
-
-
- /*
- * define a polygon as a set of four points
- * returns true if polygon created
- */
- static bool CreatePoly(curpoly, p0, p1, p2, p3)
- register Rhomboid *curpoly;
- PtGen *p0, *p1, *p2, *p3;
- {
-
- Pt3 normal;
- PtGen *list[RhomVxNum];
-
- list[0] = p0; list[1] = p1; list[2] = p2; list[3] = p3;
- /*
- * compute stuff needed only if producing shaded image
- */
- if( shadeflag ) {
- Pt3 lvec;
- Pt3 center;
- float ptintens;
- float ldotn; /* light vector dot normal */
- /*
- * if cant compute normal, then junk polygon
- */
- if( CalcNormal( list, &normal )) {
- return(false);
- }
-
- curpoly->intensity = Ambience;
- center.x = ( list[0]->d3.x
- + list[1]->d3.x
- + list[2]->d3.x
- + list[3]->d3.x)/4.0;
- center.y = ( list[0]->d3.y
- + list[1]->d3.y
- + list[2]->d3.y
- + list[3]->d3.y)/4.0;
- center.z = ( list[0]->d3.z
- + list[1]->d3.z
- + list[2]->d3.z
- + list[3]->d3.z)/4.0;
-
- curpoly->depth = center.z;
-
- CalcVector( ¢er, &LightSrc, &lvec );
- Unitize( &lvec );
- ldotn = DotProd( &lvec, &normal );
- if( ldotn < 0 ) {
- ptintens = PtIntensity * Kd * -ldotn;
- curpoly->intensity += ptintens;
- }
- /*
- * calculate specular component
- */
- if( SpecOn && ldotn < 0 ) {
- float Kspec, Is;
- Pt3 rvec; /* lvec reflected through poly */
-
- ScaleVec( 2*ldotn, &normal, &rvec );
- CalcVector(&lvec, &rvec, &rvec );
- Unitize( ¢er );
- Kspec = DotProd( &rvec, ¢er);
-
- if( Kspec <= 0.0 ) {
- Is = Ks * Kspec * Kspec* PtIntensity;
- curpoly->intensity += Is;
- }
- }
-
- if( curpoly->intensity > 1.0 ) {
- curpoly->intensity = 1.0;
- }
- }
- else {
- /*
- * calculate depth of polygon
- * for now, try an average of the vertex depths
- */
- curpoly->depth =( list[0]->d3.z
- + list[1]->d3.z
- + list[2]->d3.z
- + list[3]->d3.z)/4.0;
- }
- /*
- * store index to screen coordinates
- */
- curpoly->pt[0] = p0->d2;
- curpoly->pt[1] = p1->d2;
- curpoly->pt[2] = p2->d2;
- curpoly->pt[3] = p3->d2;
-
- return(true);
- }
- /*
- * passable procedure for creating polygons without mapping
- */
- static
- void AcceptPoly(p0, p1, p2, p3)
- PtGen *p0, *p1, *p2, *p3;
- {
- if( CreatePoly(nextpoly, p0, p1, p2,p3)) {
- nextpoly++;
- }
- }
-
- static
- void AcceptMPoly( p0, p1, p2, p3)
- PtGen *p0, *p1, *p2, *p3;
- {
- if( CreatePoly(&mnextpoly->rhom, p0, p1, p2,p3)) {
- mnextpoly->bezindex = RevImageB;
- mnextpoly->revindex = RevImageR;
- mnextpoly++;
- }
- }
-
-
-
-
-
- /*
- * compare the depth of two polygons for SortPoly
- */
- static int CmpDepth( a, b )
- Rhomboid *a, *b;
- {
- if( a->depth < b->depth ) return(-1);
- else if( a->depth > b->depth ) return(1);
- else return(0);
- }
-
- static int CmpMDepth( a, b )
- MapRhomboid *a, *b;
- {
- if( a->rhom.depth < b->rhom.depth ) return(-1);
- else if( a->rhom.depth > b->rhom.depth ) return(1);
- else return(0);
- }
-
-
-
-
-
- void RevNoShade() {
- Rhomboid *i;
- if( GetNumSegs() < 1 ) {
- return;
- }
-
- ClrAbort();
- shadeflag = false;
- if( PrepPoly() ) return;
- if( Revolve(AcceptPoly) ) return;
- CurMode = NOTACTIVE;
-
- qsort( (char *)polylist, nextpoly - polylist,
- sizeof(Rhomboid), CmpDepth);
-
- ClrWindow(false);
-
- for( i = polylist; i< nextpoly; i++ ) {
- if( AbortDraw ) return;
- DrawRhomFrame( i->pt );
- }
- }
-
-
-
-
- void RevShade() {
- register Rhomboid *i;
-
- if( !AllocDither()) return; /* not enough memory */
- if( GetNumSegs() < 1 ) {
- return;
- }
- CurMode = NOTACTIVE;
- ClrAbort();
- shadeflag = true;
- if( PrepPoly() || Revolve(AcceptPoly) ) {
- return;
- }
- qsort( (char *)polylist, nextpoly-polylist,
- sizeof(Rhomboid), CmpDepth);
-
- ClrWindow(false);
-
- for( i = polylist; i< nextpoly; i++ ) {
- if( AbortDraw ) return;
- DrawRhomShade( i );
- }
- }
-
-
-
- void RevMap() {
- register MapRhomboid *i;
-
- ClrAbort();
- if( GetNumSegs() < 1 ) {
- return;
- }
- if( InitMapping() ) {
- return;
- }
- CurMode = NOTACTIVE;
- shadeflag = true;
-
-
- if( PrepMPoly() || Revolve(AcceptMPoly) ) {
- return;
- }
- qsort( (char *)mpolylist, mnextpoly-mpolylist,
- sizeof(MapRhomboid), CmpMDepth);
- ClrWindow(false);
-
- for( i = mpolylist; i< mnextpoly; i++ ) {
- if( AbortDraw ) return;
- DrawRhomMap(i);
- }
- }
-