bool Face::triangleDistanceTest(XYZ &v_test,float dist_test) { float d; XYZ t,u,ret; Vector v; if (face_normal.x==face_normal.y==face_normal.z==0) calcFaceNormal(); d = planeDistanceTo(v_test); v = face_normal; v.makeUnit(); v *= d; t = v_test; t -= v; u = v_test; bool onTri = segmentIntersects(ret,t,u); // printf("ont: %d, dist: %f \n",onTri,d); if (onTri) { return (d <= dist_test); } else { return false; } }
int prepareObject(struct OBJ_Model * obj) { if (obj==0) { fprintf(stderr,"Cannot Prepare empty object \n"); return 0; } if (obj->numFaces==0) { fprintf(stderr,"Object has zero faces \n"); return 0; } if (obj->faceList==0) { fprintf(stderr,"Object has a null face list \n"); return 0; } if (obj->vertexList==0) { fprintf(stderr,"Object has a null vertex list \n"); return 0; } long unsigned int i; Normal tmpnrm; for(i=0;i<obj->numFaces;i++) { calcFaceNormal(&tmpnrm,obj->vertexList[obj->faceList[i].v[0]],obj->vertexList[obj->faceList[i].v[1]],obj->vertexList[obj->faceList[i].v[2]],0); obj->faceList[i].fc_normal.n1=tmpnrm.n1; obj->faceList[i].fc_normal.n2=tmpnrm.n2; obj->faceList[i].fc_normal.n3=tmpnrm.n3; } return 1; }
/* only works with triangles */ bool Face::segmentIntersects(XYZ &returned_intersect_point, XYZ &segment_start, XYZ &segment_end, float tolerance) { cvrFloat ang_a,ang_b,ang_c; cvrFloat denom,mu,d; Vector pa,pb,pc; calcFaceNormal(); d = - face_normal.x * points[0]->x - face_normal.y * points[0]->y - face_normal.z * points[0]->z; /* calculate position where the plane intersects the segment */ denom = face_normal.x * (segment_end.x - segment_start.x) + face_normal.y * (segment_end.y - segment_start.y) + face_normal.z * (segment_end.z - segment_start.z); if (fabs(denom) < FLOAT_TOLERANCE) return false; /* point on plane is outside of line, no intersection */ mu = - (d + face_normal.x * segment_start.x + face_normal.y * segment_start.y + face_normal.z * segment_start.z) / denom; returned_intersect_point = XYZ( (float)(segment_start.x + mu * (segment_end.x - segment_start.x)), (float)(segment_start.y + mu * (segment_end.y - segment_start.y)), (float)(segment_start.z + mu * (segment_end.z - segment_start.z)) ); if (mu < 0 || mu > 1) return false; pa = returned_intersect_point - *points[0]; pb = returned_intersect_point - *points[1]; pc = returned_intersect_point - *points[2]; pa.makeUnit(); pb.makeUnit(); pc.makeUnit(); ang_a = pa.x*pb.x + pa.y*pb.y + pa.z*pb.z; ang_b = pb.x*pc.x + pb.y*pc.y + pb.z*pc.z; ang_c = pc.x*pa.x + pc.y*pa.y + pc.z*pa.z; /* check to see if angles add up to 2*PI, if so the point lies within the triangle */ if (fabs((acos(ang_a) + acos(ang_b) + acos(ang_c)) - M_TWO_PI) > tolerance) return false; return true; }