--- ray/src/common/cone.c 1991/01/19 13:43:28 1.3 +++ ray/src/common/cone.c 1992/11/19 21:32:48 2.4 @@ -1,4 +1,4 @@ -/* Copyright (c) 1991 Regents of the University of California */ +/* Copyright (c) 1992 Regents of the University of California */ #ifndef lint static char SCCSid[] = "$SunId$ LBL"; @@ -48,7 +48,7 @@ getcone(o, getxf) /* get cone structure */ register OBJREC *o; int getxf; { - double fabs(), sqrt(); + int sgn0, sgn1; register CONE *co; if ((co = (CONE *)o->os) == NULL) { @@ -59,38 +59,68 @@ int getxf; co->ca = o->oargs.farg; /* get radii */ - if (o->otype == OBJ_CYLINDER || o->otype == OBJ_TUBE) { + if (o->otype == OBJ_CYLINDER | o->otype == OBJ_TUBE) { if (o->oargs.nfargs != 7) goto argcerr; - if (co->ca[6] <= FTINY) + if (co->ca[6] < -FTINY) { + objerror(o, WARNING, "negative radius"); + o->otype = o->otype == OBJ_CYLINDER ? + OBJ_TUBE : OBJ_CYLINDER; + co->ca[6] = -co->ca[6]; + } else if (co->ca[6] <= FTINY) goto raderr; + co->p0 = 0; co->p1 = 3; co->r0 = co->r1 = 6; } else { if (o->oargs.nfargs != 8) goto argcerr; - if (co->ca[6] < -FTINY || co->ca[7] < -FTINY) + if (co->ca[6] < -FTINY) sgn0 = -1; + else if (co->ca[6] > FTINY) sgn0 = 1; + else sgn0 = 0; + if (co->ca[7] < -FTINY) sgn1 = -1; + else if (co->ca[7] > FTINY) sgn1 = 1; + else sgn1 = 0; + if (sgn0+sgn1 == 0) goto raderr; - if (co->ca[6] < 0.0) co->ca[6] = 0.0; - if (co->ca[7] < 0.0) co->ca[7] = 0.0; - if (fabs(co->ca[7] - co->ca[6]) <= FTINY) - goto raderr; - co->r0 = 6; - co->r1 = 7; + if (sgn0 < 0 | sgn1 < 0) { + objerror(o, o->otype==OBJ_RING?USER:WARNING, + "negative radii"); + o->otype = o->otype == OBJ_CONE ? + OBJ_CUP : OBJ_CONE; + } + co->ca[6] = co->ca[6]*sgn0; + co->ca[7] = co->ca[7]*sgn1; + if (co->ca[7] - co->ca[6] > FTINY) { + if (o->otype == OBJ_RING) + co->p0 = co->p1 = 0; + else { + co->p0 = 0; co->p1 = 3; + } + co->r0 = 6; co->r1 = 7; + } else if (co->ca[6] - co->ca[7] > FTINY) { + if (o->otype == OBJ_RING) + co->p0 = co->p1 = 0; + else { + co->p0 = 3; co->p1 = 0; + } + co->r0 = 7; co->r1 = 6; + } else { + if (o->otype == OBJ_RING) + goto raderr; + o->otype = o->otype == OBJ_CONE ? + OBJ_CYLINDER : OBJ_TUBE; + o->oargs.nfargs = 7; + co->p0 = 0; co->p1 = 3; + co->r0 = co->r1 = 6; + } } /* get axis orientation */ - co->p0 = 0; - if (o->otype == OBJ_RING) { - if (co->ca[6] > co->ca[7]) { /* make r0 smaller */ - co->r0 = 7; - co->r1 = 6; - } - co->p1 = 0; + if (o->otype == OBJ_RING) VCOPY(co->ad, o->oargs.farg+3); - } else { - co->p1 = 3; - co->ad[0] = co->ca[3] - co->ca[0]; - co->ad[1] = co->ca[4] - co->ca[1]; - co->ad[2] = co->ca[5] - co->ca[2]; + else { + co->ad[0] = CO_P1(co)[0] - CO_P0(co)[0]; + co->ad[1] = CO_P1(co)[1] - CO_P0(co)[1]; + co->ad[2] = CO_P1(co)[2] - CO_P0(co)[2]; } co->al = normalize(co->ad); if (co->al == 0.0) @@ -98,11 +128,11 @@ int getxf; /* compute axis and side lengths */ if (o->otype == OBJ_RING) { co->al = 0.0; - co->sl = co->ca[co->r1] - co->ca[co->r0]; - } else if (o->otype == OBJ_CONE || o->otype == OBJ_CUP) { + co->sl = CO_R1(co) - CO_R0(co); + } else if (o->otype == OBJ_CONE | o->otype == OBJ_CUP) { co->sl = co->ca[7] - co->ca[6]; co->sl = sqrt(co->sl*co->sl + co->al*co->al); - } else { /* OBJ_CYLINDER || OBJ_TUBE */ + } else { /* OBJ_CYLINDER or OBJ_TUBE */ co->sl = co->al; } co->tm = NULL; @@ -124,9 +154,11 @@ OBJREC *o; { register CONE *co = (CONE *)o->os; + if (co == NULL) + return; if (co->tm != NULL) free((char *)co->tm); - free(o->os); + free((char *)co); o->os = NULL; } @@ -134,12 +166,11 @@ OBJREC *o; conexform(co) /* get cone transformation matrix */ register CONE *co; { - double sqrt(), fabs(); - double m4[4][4]; + MAT4 m4; register double d; register int i; - co->tm = (double (*)[4])malloc(sizeof(m4)); + co->tm = (FLOAT (*)[4])malloc(sizeof(MAT4)); if (co->tm == NULL) error(SYSTEM, "out of memory in conexform"); @@ -148,10 +179,10 @@ register CONE *co; if (co->r0 == co->r1) d = 0.0; else - d = co->ca[co->r0] / (co->ca[co->r1] - co->ca[co->r0]); + d = CO_R0(co) / (CO_R1(co) - CO_R0(co)); for (i = 0; i < 3; i++) - co->tm[3][i] = d*(co->ca[co->p1+i] - co->ca[co->p0+i]) - - co->ca[co->p0+i]; + co->tm[3][i] = d*(CO_P1(co)[i] - CO_P0(co)[i]) + - CO_P0(co)[i]; /* rotate to positive z-axis */ setident4(m4); @@ -175,10 +206,9 @@ register CONE *co; multmat4(co->tm, co->tm, m4); /* scale z-axis */ - setident4(m4); - if (co->p0 != co->p1 && co->r0 != co->r1) { - d = fabs(co->ca[co->r1] - co->ca[co->r0]); - m4[2][2] = d/co->al; + if (co->p0 != co->p1 & co->r0 != co->r1) { + setident4(m4); + m4[2][2] = (CO_R1(co) - CO_R0(co)) / co->al; + multmat4(co->tm, co->tm, m4); } - multmat4(co->tm, co->tm, m4); }