int o_face( /* determine if face intersects cube */ OBJREC *o, CUBE *cu ) { FVECT cumin, cumax; FVECT v1, v2; double d1, d2; int vloc; register FACE *f; register int i, j; /* get face arguments */ f = getface(o); if (f->area == 0.0) /* empty face */ return(O_MISS); /* compute cube boundaries */ for (j = 0; j < 3; j++) cumax[j] = (cumin[j] = cu->cuorg[j]-FTINY) + cu->cusize + 2.0*FTINY; vloc = ABOVE | BELOW; /* check vertices */ for (i = 0; i < f->nv; i++) if ( (j = plocate(VERTEX(f,i), cumin, cumax)) ) vloc &= j; else return(O_HIT); /* vertex inside */ if (vloc) /* all to one side */ return(O_MISS); for (i = 0; i < f->nv; i++) { /* check edges */ if ((j = i + 1) >= f->nv) j = 0; /* wrap around */ VCOPY(v1, VERTEX(f,i)); /* clip modifies */ VCOPY(v2, VERTEX(f,j)); /* the vertices! */ if (clip(v1, v2, cumin, cumax)) return(O_HIT); /* edge inside */ } /* see if cube cuts plane */ for (j = 0; j < 3; j++) if (f->norm[j] > 0.0) { v1[j] = cumin[j]; v2[j] = cumax[j]; } else { v1[j] = cumax[j]; v2[j] = cumin[j]; } if ((d1 = DOT(v1, f->norm) - f->offset) > FTINY) return(O_MISS); if ((d2 = DOT(v2, f->norm) - f->offset) < -FTINY) return(O_MISS); /* intersect face */ for (j = 0; j < 3; j++) v1[j] = (v1[j]*d2 - v2[j]*d1)/(d2 - d1); if (inface(v1, f)) return(O_HIT); return(O_MISS); /* no intersection */ }
extern int o_face( /* compute intersection with polygonal face */ OBJREC *o, register RAY *r ) { double rdot; /* direction . normal */ double t; /* distance to intersection */ FVECT pisect; /* intersection point */ register FACE *f; /* face record */ f = getface(o); /* * First, we find the distance to the plane containing the * face. If this distance is less than zero or greater * than a previous intersection, we return. Otherwise, * we determine whether in fact the ray intersects the * face. The ray intersects the face if the * point of intersection with the plane of the face * is inside the face. */ /* compute dist. to plane */ rdot = -DOT(r->rdir, f->norm); if (rdot <= FTINY && rdot >= -FTINY) /* ray parallels plane */ t = FHUGE; else t = (DOT(r->rorg, f->norm) - f->offset) / rdot; if (t <= FTINY || t >= r->rot) /* not good enough */ return(0); /* compute intersection */ VSUM(pisect, r->rorg, r->rdir, t); if (!inface(pisect, f)) /* ray intersects face? */ return(0); r->ro = o; r->rot = t; VCOPY(r->rop, pisect); VCOPY(r->ron, f->norm); r->rod = rdot; r->pert[0] = r->pert[1] = r->pert[2] = 0.0; r->uv[0] = r->uv[1] = 0.0; r->rox = NULL; return(1); /* hit */ }