int DistanceTransform::inOrOut(const dynamic_array<int> &triList, const Point3f& vert, const Point3f& nearPnt) { int i, j, len = triList.length(); assert(len > 1); Point3f center, cpnt; Point3f v0, v1, v2; p_Surf->getTriVerts(triList[0], v0, v1, v2); double tnear = 1; int nearTri = 0; for(i = 0; i < 3; i++) { center[i] = (v0[i] + v1[i] + v2[i])/ 3; cpnt[i] = 0.9 * nearPnt[i] + 0.1 * center[i]; } for(i = 1; i < len; i++) { double t = rayTriangleIntersection(triList[i], vert, cpnt); if(t < tnear) { tnear = t; nearTri = i; } } Vector3f trinorm; p_Surf->getTriNormal(triList[nearTri], trinorm); p_Surf->getTriVerts(triList[nearTri], v0, v1, v2); Vector3f diff = vert - v0; if (DotProduct(diff, trinorm) < 0) { return -1; } return 1; }
// Slow method to do object-ray intersection .. bool Pawn::test_intersect(ray3D& ray) { vector<vec3> verts; pawnObj.getVertices(verts); vector<vec3> normals; pawnObj.getVertexNormals(normals); vector<uvec3> elements; pawnObj.getElements(elements); vec3 minBB, maxBB; pawnObj.boundingBox(minBB, maxBB); vector<vec3> vertices_tr(3); vector<vec3> normals_tr(3); if(rayBoxIntersection(ray, minBB, maxBB)) { for(int i = 0; i < elements.size(); i++) { vertices_tr[0] = verts[elements[i].x]; vertices_tr[1] = verts[elements[i].y]; vertices_tr[2] = verts[elements[i].z]; normals_tr[0] = normals[elements[i].x]; normals_tr[1] = normals[elements[i].y]; normals_tr[2] = normals[elements[i].z]; rayTriangleIntersection(ray, vertices_tr, normals_tr); } } return(!ray.intersection.none); }
// raytracing bool isMeshRaytraced ( const MVector3 & origin, const MVector3 & direction, const void * indices, M_TYPES indicesType, const MVector3 * vertices, unsigned int size) { switch(indicesType) { case M_USHORT: { unsigned int v; unsigned short * idx = (unsigned short *)indices; for(v = 0; v < size; v += 3) { const MVector3 * v1 = &vertices[idx[v]]; const MVector3 * v2 = &vertices[idx[v+1]]; const MVector3 * v3 = &vertices[idx[v+2]]; float u, v; if(rayTriangleIntersection(origin, direction, *v1, *v2, *v3, u, v) > 0) return true; } break; } case M_UINT: { unsigned int v; unsigned int * idx = (unsigned int *)indices; for(v = 0; v < size; v += 3) { const MVector3 * v1 = &vertices[idx[v]]; const MVector3 * v2 = &vertices[idx[v+1]]; const MVector3 * v3 = &vertices[idx[v+2]]; float u, v; if(rayTriangleIntersection(origin, direction, *v1, *v2, *v3, u, v) > 0) return true; } break; } default: break; } return false; }
// ---------------------------------------------------------------------- bool ObjMesh::rayCast(const NxVec3 &orig, const NxVec3 &dir, NxReal &t) { t = -1.0f; for (int i = 0; i < (int)mTriangles.size(); i++) { ObjMeshTriangle &mt = mTriangles[i]; NxReal ti, u,v; if (!rayTriangleIntersection(orig, dir, mt, ti, u,v)) continue; if (ti < 0.0f) continue; if (t < 0.0f || ti < t) t = ti; } return t >= 0.0f; }
bool CheckerBoard::intersect(ray3D& ray) { vector<vec3> vertices_tr(3); vector<vec3> normals_tr(3); for(int i = 0; i < 2; i++) { vertices_tr[0] = vertices[faces[i].x]; vertices_tr[1] = vertices[faces[i].y]; vertices_tr[2] = vertices[faces[i].z]; normals_tr[0] = vertices[faces[i].x]; normals_tr[1] = normals[faces[i].y]; normals_tr[2] = normals[faces[i].z]; rayTriangleIntersection(ray, vertices_tr, normals_tr); } return(!ray.intersection.none); }
float rayMeshIntersection ( const MVector3 & origin, const MVector3 & direction, const void * indices, M_TYPES indicesType, const MVector3 * vertices, unsigned int size) { float nearDist = 0; switch(indicesType) { case M_USHORT: { unsigned int v; unsigned short * idx = (unsigned short *)indices; for(v = 0; v < size; v += 3) { const MVector3 * v1 = &vertices[idx[v]]; const MVector3 * v2 = &vertices[idx[v+1]]; const MVector3 * v3 = &vertices[idx[v+2]]; // cull face /*if(cullMode != M_CULL_NONE) { MVector3 normal = ((*v1)-(*v2)).crossProduct((*v1)-(*v3)); if(direction.dotProduct(normal) < 0) continue; }*/ float u, v; float dist = rayTriangleIntersection(origin, direction, *v1, *v2, *v3, u, v); if(dist > 0) { if(dist < nearDist || nearDist == 0) nearDist = dist; } } break; } case M_UINT: { unsigned int v; unsigned int * idx = (unsigned int *)indices; for(v = 0; v < size; v += 3) { const MVector3 * v1 = &vertices[idx[v]]; const MVector3 * v2 = &vertices[idx[v+1]]; const MVector3 * v3 = &vertices[idx[v+2]]; float u, v; float dist = rayTriangleIntersection(origin, direction, *v1, *v2, *v3, u, v); if(dist > 0) { if(dist < nearDist || nearDist == 0) nearDist = dist; } } break; } default: break; } return nearDist; }
/* * Randomly pick points inside the mesh and use these points to estimate the center of gravity * @param triangles (the mesh object) * @param values (the structure that contains the centerpoint, counter, accumulator) */ void monteCarlo(const QList <FAHTriangle> &triangles, MonteCarloReturnValues *values) { //the minimum possible x,y,z bounds FAHVector3 minBoundary; //the maximum possible x,y,z bounds FAHVector3 maxBoundary; //store the random points that are inside the mesh FAHVector3 acc; //used for efficiency, higher variance yields more checks with more vertices on mesh, data will be more accurate, but longer processing time double variance=10; //initialize vars acc.zero(); maxBoundary.set(triangles.at(0).v[0]); minBoundary.set(triangles.at(0).v[0]); //check all points in triangles //store min/max x,y,z for(int i=0;i<triangles.length();i++) { maxBoundary.max(triangles.at(i).v[0]); maxBoundary.max(triangles.at(i).v[1]); maxBoundary.max(triangles.at(i).v[2]); minBoundary.min(triangles.at(i).v[0]); minBoundary.min(triangles.at(i).v[1]); minBoundary.min(triangles.at(i).v[2]); } //end for FAHVector3 centerPoint; centerPoint.set(maxBoundary.copy().add(minBoundary)).scale(1/2); //declare infinity FAHVector3 infinity; int counter=0; for(int i=0;i<300;i++) { //randomly find a point FAHVector3 randPoint; randPoint.set(((maxBoundary.copy().sub(minBoundary)).scale(qrand()/double(RAND_MAX))).add(minBoundary)); //define infinity to be directly above the random point infinity.set(randPoint); infinity.z = fabs(infinity.z) * 2; //create a ray of the point FAHVector3 ray; ray.set(infinity).sub(randPoint); int intersectionCounter=0; //check all nearby triangles to see how many the ray intersects for(int j=0;j<triangles.length();j++) { //the three points that make up the vertices of a triangle FAHVector3 p1; FAHVector3 p2; FAHVector3 p3; //calculate plausible triangles that the ray of your point to infinity could intersect p1.set(triangles.at(j).v[0]); p2.set(triangles.at(j).v[1]); p3.set(triangles.at(j).v[2]); //increment intersection counter if at least one vertex of the triangle has a z coordinate greater than the random point's z coordinate, //and if the ray and triangle intersect. For ease of reading, it is broken into 2 if statements. if ((fabs(p1.x-randPoint.x)<variance&&fabs(p1.y-randPoint.y)<variance&&p1.z>randPoint.z) ||fabs((p2.x-randPoint.x)<variance&&fabs(p2.y-randPoint.y)<variance&&p3.z>randPoint.z)|| fabs((p3.x-randPoint.x)<variance&&fabs(p3.y-randPoint.y)<variance&&p3.z>randPoint.z)) if (rayTriangleIntersection(randPoint,ray,p1,p2,p3)==1) intersectionCounter++; } //end for j //if the ray intersects an odd number of triangles, it is an interior point, therefore, increase vars if(intersectionCounter%2==1) { acc.set(randPoint); counter++; } //end if } //end for i values->centerPoint=centerPoint; values->acc=acc; values->counter=counter; } //end monteCarlo