/*===========================================*/ int VF_BackFaceCullViewPoint(ViewPort *view, Poly *poly_j) { int n; Vector *normal_i, *normal_j, r; normal_i = &(view->view_normal); normal_j = &(poly_j->normal); for (n=0; n<poly_j->np; n++) { V3_Sub(&(poly_j->p[n]), &(view->view_point), &r); if ((V3_Dot(&r, normal_i)>0.0) && (-V3_Dot(&r, normal_j)>0.0)) return 0; } return 1; }
/*====================================*/ int VF_RayIntersect(Ray *ray, double tmax, Poly *poly) { double t, n_dot_d; Vector q; n_dot_d = V3_Dot(&(poly->normal), &ray->D); if (fabs(n_dot_d)<VF_RAY_TEST) return 0; V3_Sub(&(poly->p[0]), &ray->O, &q); t = V3_Dot(&(poly->normal), &q)/n_dot_d; if (t<=0.0 || t>=tmax) return 0; if (poly->np!=2) { return (VF_InsidePoly(ray, t, poly)); } else { return (VF_InsideLine(ray, t, poly)); } }
/*===========================================*/ int VF_BackFaceCullPolys(Poly *poly_i, Poly *poly_j) { int n, m; double tmp; Vector *normal_i, *normal_j, r; normal_i = &(poly_i->normal); normal_j = &(poly_j->normal); for (m=0; m<poly_i->np; m++) { for (n=0; n<poly_j->np; n++) { V3_Sub(&(poly_j->p[n]), &(poly_i->p[m]), &r); V3_Normalize(&r,tmp); if ((V3_Dot(&r, normal_i)>0.0) && (-V3_Dot(&r, normal_j)>0.0)) return 0; } } return 1; }
/*=========================================*/ int VF_BehindPlane(Plane *plane, Poly *poly) { int n; double value, spatial_tol; VFtopology *topology=VF_CurrentTopology(); spatial_tol = topology->spatial_tol; for (n=0; n<poly->np; n++) { value = V3_Dot(&(poly->p[n]), &(plane->normal)) + plane->d; if (value > spatial_tol) return 0; } return 1; }
/*=========================================*/ int VF_BehindViewPoint(ViewPort *view, Poly *poly) { int n; double value, spatial_tol; VFtopology *topology=VF_CurrentTopology(); spatial_tol = topology->spatial_tol; for (n=0; n<poly->np; n++) { value = V3_Dot(&(poly->p[n]), &(view->view_normal)) + view->d; if (value > spatial_tol) return 0; } return 1; }
/*=========================================*/ int VF_BehindAndBackFaceCullViewPoint(ViewPort *view, Poly *poly) { int n; double value, spatial_tol; Vector *normal_i, *normal_j, r; VFtopology *topology=VF_CurrentTopology(); spatial_tol = topology->spatial_tol; for (n=0; n<poly->np; n++) { value = V3_Dot(&(poly->p[n]), &(view->view_normal)) + view->d; if (value > spatial_tol) { /*===========================================*/ /* THIS VERTEX IS IN FRONT OF THE VIEWPOINT, */ /* NOW CHECK IF IT IS ALSO FACING IT */ /*===========================================*/ normal_i = &(view->view_normal); normal_j = &(poly->normal); V3_Sub(&(poly->p[n]), &(view->view_point), &r); if ((V3_Dot(&r, normal_i)>0.0) && (-V3_Dot(&r, normal_j)>0.0)) return 0; break; } } return 1; }
static int NearestConstraintAxis (HVect loose, HVect *axes, int nAxes) { HVect onPlane; register double max, dot; register int i, nearest; max = -1; nearest = 0; for (i=0; i<nAxes; i++) { onPlane = ConstrainToAxis(loose, axes[i]); dot = V3_Dot(onPlane, loose); if (dot>max) { max = dot; nearest = i; } } return (nearest); }
static HVect ConstrainToAxis (HVect loose, HVect axis) { HVect onPlane; register double norm; onPlane = V3_Sub(loose, V3_Scale(axis, V3_Dot(axis, loose))); norm = V3_Norm(onPlane); if (norm > 0.0) { if (onPlane.z < 0.0) onPlane = V3_Negate(onPlane); return ( V3_Scale(onPlane, 1/sqrt(norm)) ); } /* else drop through */ /* ================= */ if (axis.z == 1) onPlane = V3_(1.0, 0.0, 0.0); else onPlane = V3_Unit(V3_(-axis.y, axis.x, 0.0)); return (onPlane); }
double VF_Visibility(Poly *poly_i, Poly *poly_j, CandidateList *candidates, int nc) { int i, j, n, ns, cnt, nt, test_vertices=0; double tmax, tmp, n_dot_d; Ray ray0,*ray; Point samples_i[4096], samples_j[4096]; Vector q; Adaptive *adaptive; VFenclosure *enclosure=VF_CurrentEnclosure(); adaptive = &(enclosure->adaptive); if (nc==0) return(1.0); VF_SamplesUVtoXYZ(poly_i, &(adaptive->visibility.sampling), adaptive->visibility.sampleuv_i, samples_i); VF_SamplesUVtoXYZ(poly_j, &(adaptive->visibility.sampling), adaptive->visibility.sampleuv_j, samples_j); ns = adaptive->visibility.sampling.n; if (test_vertices) { cnt = nt = ns+poly_i->np*poly_j->np; } else { cnt = nt = ns; } /*=================================================*/ /* TEST VISIBILITY OF RAYS BETWEEN SAMPLING POINTS */ /*=================================================*/ for (n=0; n<ns; n++) { ray = &(adaptive->visibility.ray[n]); ray->O = samples_i[n]; ray->vis = 0; V3_Sub(&(samples_j[n]), &(ray->O), &(ray->D)); V3_Normalize(&(ray->D),tmp); n_dot_d = V3_Dot(&(poly_j->normal), &(ray->D)); if (fabs(n_dot_d)<VF_RAY_TEST) { cnt--; } else { V3_Sub(&(poly_j->p[0]), &(ray->O), &q); tmax = V3_Dot(&(poly_j->normal), &q)/n_dot_d; if (VF_RayPatchListTest(&(adaptive->visibility.ray[n]), n, tmax, candidates, nc)) cnt--; } } if (test_vertices) { /*===============================================================*/ /* ALSO TEST RAYS BETWEEN ALL VERTEX COMBINATIONS FOR VISIBILITY */ /*===============================================================*/ for (i=0; i<poly_i->np; i++) { for (j=0; j<poly_j->np; j++) { ray0.vis = 0; ray0.O = poly_i->p[i]; V3_Sub(&(poly_j->p[j]), &(ray0.O), &(ray0.D)); V3_Normalize(&(ray0.D),tmp); n_dot_d = V3_Dot(&(poly_j->normal), &(ray0.D)); if (fabs(n_dot_d)<VF_RAY_TEST) { cnt--; } else { V3_Sub(&(poly_j->p[0]), &(ray0.O), &q); tmax = V3_Dot(&(poly_j->normal), &q)/n_dot_d; if (VF_RayPatchListTest(&ray0, n, tmax, candidates, nc)) { cnt--; } } } } } return ((double)(cnt)/(double)(nt)); }
void OBJECT::SortVertexEdges() { for (int x=0; x<VertexNum; x++) { if (VertexList[x].EdgeNum>2) { VECTOR3 vertvector; VECTOR3 normal = V3_Normalize(VertexList[x].Normal); VECTOR3 vx = VertexList[x].Position; float *szogek = new float[VertexList[x].EdgeNum]; int e=GetEdgeVertex(this,x,VertexList[x].EdgeList[0]); VECTOR3 refvector=VertexList[e].Position; refvector = V3_Sub(refvector,vx); VECTOR3 projvec=normal; projvec=V3_Mults(projvec,V3_Dot(refvector,normal)); refvector = V3_Normalize(V3_Sub(refvector,projvec)); int y; for (y=1; y<VertexList[x].EdgeNum; y++) { e=GetEdgeVertex(this,x,VertexList[x].EdgeList[y]); vertvector = V3_Sub(VertexList[e].Position,vx); projvec=V3_Mults(normal,V3_Dot(vertvector,normal)); vertvector = V3_Normalize(V3_Sub(vertvector,projvec)); float cosTheta = max(-1.0f,min(1.0f,V3_Dot(vertvector,refvector))); float angle = (float)acos(cosTheta) * 180.0f / 3.1415f; VECTOR3 crossProd=V3_Cross(vertvector,refvector); if (V3_Dot(crossProd,normal) < 0) angle = 360 - angle; szogek[y]=angle; } int smallest,b1; float smallestvalue, b2; for (int z=0; z<VertexList[x].EdgeNum; z++) { smallest=z; smallestvalue=szogek[z]; for (y=z; y<VertexList[x].EdgeNum; y++) { if (szogek[y]<=smallestvalue) { smallest=y; smallestvalue=szogek[y]; } } b2=szogek[smallest]; szogek[smallest]=szogek[z]; szogek[z]=b2; b1=VertexList[x].EdgeList[smallest]; VertexList[x].EdgeList[smallest]=VertexList[x].EdgeList[z]; VertexList[x].EdgeList[z]=b1; } delete[] szogek; } } }