// Returns an Intersection of the ray with a sphere Intersection Mesh::intersectImpl(const Ray &ray) const { Intersection i = Intersection(); i.t = -1.0f; i.normal = glm::vec3(0.f); float smallestT = FLT_MAX; // check every triangle in the mesh int num_triangles = indices_.size() / 3; for (int n = 0; n < num_triangles; ++n) { // triangle vertices glm::vec3 p1 = vertices_.at(indices_.at(n * 3)); glm::vec3 p2 = vertices_.at(indices_.at(n * 3 + 1)); glm::vec3 p3 = vertices_.at(indices_.at(n * 3 + 2)); // triangle intersection Intersection triI = triangleIntersect(ray, p1, p2, p3); // return only the closest triangle if (triI.t != -1.0 && triI.t < smallestT) { smallestT = triI.t; i = triI; } } return i; }
void LinkedNode::subdivide(DirectX::XMFLOAT3 p_min, DirectX::XMFLOAT3 p_max, std::vector<unsigned int> p_indices, std::vector<Triangle> p_triangles) { std::vector<unsigned int> triIndices; bool intersect = false; for(unsigned int i=0; i<p_indices.size(); i++) { intersect = triangleIntersect(p_triangles[p_indices[i]]); if(intersect) triIndices.push_back(p_indices[i]); } if(triIndices.size() > MAX_NUM_TRIS) { DirectX::XMFLOAT3 minValues[8]; DirectX::XMFLOAT3 maxValues[8]; minValues[0] = p_min; maxValues[0] = DirectX::XMFLOAT3( (p_min.x+p_max.x)/2, (p_min.y+p_max.y)/2 , (p_min.z+p_max.z)/2 ); minValues[1] = DirectX::XMFLOAT3( (p_min.x+p_max.x)/2, p_min.y, p_min.z ); maxValues[1] = DirectX::XMFLOAT3( p_max.x, (p_min.y+p_max.y)/2 , (p_min.z+p_max.z)/2 ); minValues[2] = DirectX::XMFLOAT3( p_min.x, p_min.y, (p_min.z+p_max.z)/2 ); maxValues[2] = DirectX::XMFLOAT3( (p_min.x+p_max.x)/2, (p_min.y+p_max.y)/2 , p_max.z ); minValues[3] = DirectX::XMFLOAT3( (p_min.x+p_max.x)/2, p_min.y, (p_min.z+p_max.z)/2 ); maxValues[3] = DirectX::XMFLOAT3( p_max.x, (p_min.y+p_max.y)/2 , p_max.z ); minValues[4] = DirectX::XMFLOAT3( p_min.x, (p_min.y+p_max.y)/2, p_min.z ); maxValues[4] = DirectX::XMFLOAT3( (p_min.x+p_max.x)/2, p_max.y , (p_min.z+p_max.z)/2 ); minValues[5] = DirectX::XMFLOAT3( (p_min.x+p_max.x)/2, (p_min.y+p_max.y)/2, p_min.z ); maxValues[5] = DirectX::XMFLOAT3( p_max.x, p_max.y , (p_min.z+p_max.z)/2 ); minValues[6] = DirectX::XMFLOAT3( p_min.x, (p_min.y+p_max.y)/2, (p_min.z+p_max.z)/2 ); maxValues[6] = DirectX::XMFLOAT3( (p_min.x+p_max.x)/2, p_max.y, p_max.z ); minValues[7] = DirectX::XMFLOAT3( (p_min.x+p_max.x)/2, (p_min.y+p_max.y)/2, (p_min.z+p_max.z)/2 ); maxValues[7] = DirectX::XMFLOAT3( p_max.x, p_max.y, p_max.z ); for(unsigned int i=0; i<NUM_CHILDREN; i++) { m_children[i] = new LinkedNode(minValues[i], maxValues[i]); m_children[i]->subdivide(minValues[i], maxValues[i], triIndices, p_triangles); } } else m_triIndices = triIndices; }
char BaseMesh::intersect(unsigned idx, IntersectionContext * ctx) const { Vector3F threeCorners[3]; threeCorners[0] = _vertices[_indices[idx * 3]]; threeCorners[1] = _vertices[_indices[idx * 3 + 1]]; threeCorners[2] = _vertices[_indices[idx * 3 + 2]]; if(!triangleIntersect(threeCorners, ctx)) return 0; postIntersection(idx, ctx); return 1; }
// custom implement R04922067 begin bool Heightfield2::Intersect(const Ray &r, float *tHit, float *rayEpsilon, DifferentialGeometry *dg) const { // Transform _Ray_ to object space Ray ray; (*WorldToObject)(r, &ray); // simplify 3D DDA to 2D DDA int x, y; bool has = false; for (y = 0; y < ny-1; ++y) { for (x = 0; x < nx-1; ++x) { float tx[2], ty[2]; float tz[4] = {z[y*nx+x], z[y*nx+(x+1)], z[(y+1)*nx+x], z[(y+1)*nx+x+1]}; tx[0] = (float)x / (float) (nx-1); ty[0] = (float)y / (float) (ny-1); tx[1] = (float)(x+1) / (float) (nx-1); ty[1] = (float)(y+1) / (float) (ny-1); Point p[4]; p[0].x = tx[0], p[0].y = ty[0], p[0].z = tz[0]; // (0, 0) p[1].x = tx[1], p[1].y = ty[0], p[1].z = tz[1]; // (1, 0) p[2].x = tx[0], p[2].y = ty[1], p[2].z = tz[2]; // (0, 1) p[3].x = tx[1], p[3].y = ty[1], p[3].z = tz[3]; // (1, 1) { Point triangle[3] = {p[0], p[1], p[3]}; if (triangleIntersect(r, tHit, rayEpsilon, dg, triangle)) { has = true; } } { Point triangle[3] = {p[0], p[3], p[2]}; if (triangleIntersect(r, tHit, rayEpsilon, dg, triangle)) { has = true; } } } } return has; }
char BaseMesh::selectComponent(IntersectionContext * ctx) const { Vector3F threeCorners[3]; unsigned fvi[3]; const unsigned nf = getNumTriangles(); for(unsigned i = 0; i < nf; i++) { getTriangle(i, fvi); threeCorners[0] = _vertices[fvi[0]]; threeCorners[1] = _vertices[fvi[1]]; threeCorners[2] = _vertices[fvi[2]]; if(triangleIntersect(threeCorners, ctx)) { ctx->m_componentIdx = BaseMesh::closestVertex(i, ctx->m_hitP);; return 1; } } return 0; }