int CDistanceFuncGridModel<T>::PointInside(const CBoundingVolumeNode3<AABB3<T>,T,CTraits> *pNode, const Vector3<T> &vQuery) { //needed world transformed triangles, world transformed BVH //world transformed triangles in BVH, BVH is in world space typename std::list<const CBoundingVolumeNode3<AABB3<T>,T,CTraits> *>::const_iterator i; //early out test //test point in bvh if(!pNode->m_BV.isPointInside(vQuery)) return 0; //determine ray direction Vector3<T> dir(0.9,0.8,0.02);/// = vQuery - pNode->m_BV.GetCenter(); //CRay3(const Vector3<T> &vOrig, const Vector3<T> &vDir); Ray3<T> ray(vQuery,dir); Traverse(pNode,ray); //loop through nodes and test for intersection //with the contained triangles i=m_pNodes.begin(); int nIntersections=0; for(;i!=m_pNodes.end();i++) { const CBoundingVolumeNode3<AABB3<T>,T,CTraits> *node = *i; typename std::vector<Triangle3<T> >::const_iterator j=node->m_Traits.m_vTriangles.begin(); for(;j!=node->m_Traits.m_vTriangles.end();j++) { const Triangle3<T> &tri3 = *j; CIntersectorRay3Tri3<T> intersector(ray, tri3); //test for intersection if(intersector.Intersection()) nIntersections++; }//end for j }//end for i //we finished looping through the triangles //if the number of intersection is even //we return false else true if(!(nIntersections % 2 == 0)) { m_pNodes.clear(); return 1; } else { m_pNodes.clear(); return 0; } }
osg::Vec3f CSVRender::WorldspaceWidget::getIntersectionPoint (const QPoint& localPos, unsigned int interactionMask, bool ignoreHidden) const { // (0,0) is considered the lower left corner of an OpenGL window int x = localPos.x(); int y = height() - localPos.y(); osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector ( new osgUtil::LineSegmentIntersector (osgUtil::Intersector::WINDOW, x, y)); intersector->setIntersectionLimit (osgUtil::LineSegmentIntersector::NO_LIMIT); osgUtil::IntersectionVisitor visitor (intersector); unsigned int mask = interactionMask; if (ignoreHidden) mask &= getVisibilityMask(); visitor.setTraversalMask (mask); mView->getCamera()->accept (visitor); for (osgUtil::LineSegmentIntersector::Intersections::iterator iter = intersector->getIntersections().begin(); iter!=intersector->getIntersections().end(); ++iter) { // reject back-facing polygons osg::Vec3f normal = osg::Matrix::transform3x3 ( iter->getWorldIntersectNormal(), mView->getCamera()->getViewMatrix()); if (normal.z()>=0) return iter->getWorldIntersectPoint(); } osg::Matrixd matrix; matrix.preMult (mView->getCamera()->getViewport()->computeWindowMatrix()); matrix.preMult (mView->getCamera()->getProjectionMatrix()); matrix.preMult (mView->getCamera()->getViewMatrix()); matrix = osg::Matrixd::inverse (matrix); osg::Vec3d start = matrix.preMult (intersector->getStart()); osg::Vec3d end = matrix.preMult (intersector->getEnd()); osg::Vec3d direction = end-start; direction.normalize(); return start + direction * CSMPrefs::get()["Scene Drops"]["distance"].toInt(); }
CCLayerSorter::ABCompareResult CCLayerSorter::checkOverlap(GraphNode* a, GraphNode* b) { if (!a->boundingBox.intersects(b->boundingBox)) return None; // Make the early exit threshold proportional to the total Z range. float exitThreshold = m_zRange * 0.01; LayerIntersector intersector(a, b, exitThreshold); intersector.go(); if (intersector.zDiff > 0) return BBeforeA; if (intersector.zDiff < 0) return ABeforeB; return None; }
RenderingManager::RayResult RenderingManager::castCameraToViewportRay(const float nX, const float nY, float maxDistance, bool ignorePlayer, bool ignoreActors) { osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector (new osgUtil::LineSegmentIntersector(osgUtil::LineSegmentIntersector::PROJECTION, nX * 2.f - 1.f, nY * (-2.f) + 1.f)); osg::Vec3d dist (0.f, 0.f, -maxDistance); dist = dist * mViewer->getCamera()->getProjectionMatrix(); osg::Vec3d end = intersector->getEnd(); end.z() = dist.z(); intersector->setEnd(end); intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::LIMIT_NEAREST); mViewer->getCamera()->accept(*createIntersectionVisitor(intersector, ignorePlayer, ignoreActors)); return getIntersectionResult(intersector); }
int CDistanceFuncGridModel<T>::BruteForceInnerPointsStatic(const C3DModel &model, const Vector3<T> &vQuery) { //In this variable we count the number on intersections int nIntersections = 0; for(unsigned int i=0;i<model.m_vMeshes.size();i++) { const C3DMesh& mesh=model.m_vMeshes[i]; Ray3<T> ray3(vQuery,VECTOR3(0.9,0.8,0.02) ); CDynamicArray<TriFace>::const_iterator faceIter; //Get the bounding box of the 3d model const AABB3<T> &rBox = mesh.GetBox(); //Get the mesh if(!rBox.isPointInside(vQuery)) continue; //reset the number of intersection to zero for the current subobject nIntersections=0; for(faceIter=mesh.m_pFaces.begin();faceIter!=mesh.m_pFaces.end();faceIter++) { TriFace tri=*faceIter; //We loop through all triangular faces of the // model. This variable will hold the current face Triangle3<T> tri3(mesh.GetVertices()[tri[0]],mesh.GetVertices()[tri[1]],mesh.GetVertices()[tri[2]]); //init our intersector CIntersectorRay3Tri3<T> intersector(ray3, tri3); //test for intersection if(intersector.Intersection()) nIntersections++; }//end for faces //we finished looping through the faces of the subobject //look if the point is inside the subobject //if the number of intersection is even //we return false else true if(!(nIntersections % 2 == 0)) return 1; }//end for meshes //The query point is not inside of any of the //submeshes return 0; }//end BruteForceInnerPoints
RenderingManager::RayResult RenderingManager::castRay(const osg::Vec3f& origin, const osg::Vec3f& dest, bool ignorePlayer, bool ignoreActors) { osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector (new osgUtil::LineSegmentIntersector(osgUtil::LineSegmentIntersector::MODEL, origin, dest)); intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::LIMIT_NEAREST); osgUtil::IntersectionVisitor intersectionVisitor(intersector); int mask = intersectionVisitor.getTraversalMask(); mask &= ~(Mask_RenderToTexture|Mask_Sky|Mask_Debug|Mask_Effect|Mask_Water); if (ignorePlayer) mask &= ~(Mask_Player); if (ignoreActors) mask &= ~(Mask_Actor|Mask_Player); intersectionVisitor.setTraversalMask(mask); mRootNode->accept(intersectionVisitor); return getIntersectionResult(intersector); }
osg::ref_ptr<CSVRender::TagBase> CSVRender::WorldspaceWidget::mousePick (const QPoint& localPos) { // (0,0) is considered the lower left corner of an OpenGL window int x = localPos.x(); int y = height() - localPos.y(); osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector (new osgUtil::LineSegmentIntersector(osgUtil::Intersector::WINDOW, x, y)); intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT); osgUtil::IntersectionVisitor visitor(intersector); visitor.setTraversalMask(getInteractionMask()); mView->getCamera()->accept(visitor); for (osgUtil::LineSegmentIntersector::Intersections::iterator it = intersector->getIntersections().begin(); it != intersector->getIntersections().end(); ++it) { osgUtil::LineSegmentIntersector::Intersection intersection = *it; // reject back-facing polygons osg::Vec3f normal = intersection.getWorldIntersectNormal(); normal = osg::Matrix::transform3x3(normal, mView->getCamera()->getViewMatrix()); if (normal.z() < 0) continue; for (std::vector<osg::Node*>::iterator it = intersection.nodePath.begin(); it != intersection.nodePath.end(); ++it) { osg::Node* node = *it; if (osg::ref_ptr<CSVRender::TagBase> tag = dynamic_cast<CSVRender::TagBase *>(node->getUserData())) return tag; } // ignoring terrain for now // must be terrain, report coordinates // std::cout << "Terrain hit at " << intersection.getWorldIntersectPoint().x() << " " << intersection.getWorldIntersectPoint().y() << std::endl; // return; } return osg::ref_ptr<CSVRender::TagBase>(); }
void STGM::CBoolSphereSystem::IntersectWithPlane(STGM::Intersectors<STGM::CSphere>::Type &objects, STGM::CPlane &plane, int intern) { /// Intersect only objects fully inside the observation window int i=0,j=0; int l =plane.idx(); switch(l) { case 0: i=1; j=2; break; // YZ case 1: i=0; j=2; break; // XZ case 2: i=0; j=1; break; // XY } // assume left-down corner is origin of box CWindow win(m_box.m_size[i],m_box.m_size[j]); for(size_t i=0; i<m_spheres.size(); ++i) { STGM::Intersector<STGM::CSphere> intersector( m_spheres[i], plane, m_box.m_size); if(intersector.FindIntersection()) { if(intersector.getCircle().isInWindow(win)) objects.push_back( intersector ); } } }
IntersectionMatrix* RelateComputer::computeIM() { // since Geometries are finite and embedded in a 2-D space, the EE element must always be 2 im->set(Location::EXTERIOR,Location::EXTERIOR,2); // if the Geometries don't overlap there is nothing to do const Envelope *e1=(*arg)[0]->getGeometry()->getEnvelopeInternal(); const Envelope *e2=(*arg)[1]->getGeometry()->getEnvelopeInternal(); if (!e1->intersects(e2)) { computeDisjointIM(im.get()); return im.release(); } std::auto_ptr<SegmentIntersector> si1 ( (*arg)[0]->computeSelfNodes(&li,false) ); std::auto_ptr<SegmentIntersector> si2 ( (*arg)[1]->computeSelfNodes(&li,false) ); // compute intersections between edges of the two input geometries std::auto_ptr< SegmentIntersector> intersector ( (*arg)[0]->computeEdgeIntersections((*arg)[1], &li,false) ); computeIntersectionNodes(0); computeIntersectionNodes(1); /* * Copy the labelling for the nodes in the parent Geometries. * These override any labels determined by intersections * between the geometries. */ copyNodesAndLabels(0); copyNodesAndLabels(1); /* * complete the labelling for any nodes which only have a * label for a single geometry */ //Debug.addWatch(nodes.find(new Coordinate(110, 200))); //Debug.printWatch(); labelIsolatedNodes(); //Debug.printWatch(); /* * If a proper intersection was found, we can set a lower bound * on the IM. */ computeProperIntersectionIM(intersector.get(), im.get()); /* * Now process improper intersections * (eg where one or other of the geometrys has a vertex at the * intersection point) * We need to compute the edge graph at all nodes to determine * the IM. */ // build EdgeEnds for all intersections EdgeEndBuilder eeBuilder; std::auto_ptr< std::vector<EdgeEnd*> > ee0 ( eeBuilder.computeEdgeEnds((*arg)[0]->getEdges()) ); insertEdgeEnds(ee0.get()); std::auto_ptr< std::vector<EdgeEnd*> > ee1 ( eeBuilder.computeEdgeEnds((*arg)[1]->getEdges()) ); insertEdgeEnds(ee1.get()); //Debug.println("==== NodeList ==="); //Debug.print(nodes); labelNodeEdges(); /** * Compute the labeling for isolated components. * Isolated components are components that do not touch any * other components in the graph. * They can be identified by the fact that they will * contain labels containing ONLY a single element, the one for * their parent geometry. * We only need to check components contained in the input graphs, * since isolated components will not have been replaced by new * components formed by intersections. */ //debugPrintln("Graph A isolated edges - "); labelIsolatedEdges(0,1); //debugPrintln("Graph B isolated edges - "); labelIsolatedEdges(1,0); // update the IM from all components updateIM(im.get()); return im.release(); }
bool RendererServices::trace( TraceOpt& options, OSL::ShaderGlobals* sg, const OSL::Vec3& P, const OSL::Vec3& dPdx, const OSL::Vec3& dPdy, const OSL::Vec3& R, const OSL::Vec3& dRdx, const OSL::Vec3& dRdy) { assert(m_texture_store); TextureCache texture_cache(*m_texture_store); Intersector intersector(m_project.get_trace_context(), texture_cache); const ShadingPoint* parent = reinterpret_cast<const ShadingPoint*>(sg->renderstate); const ShadingPoint* origin_shading_point = 0; Vector3d pos = Vector3f(P); if (P == sg->P) { Vector3d front = Vector3f(P); Vector3d back = front; intersector.fixed_offset( parent->get_point(), parent->get_geometric_normal(), front, back); pos = sg->N.dot(R) >= 0.0f ? front : back; origin_shading_point = parent; } const Vector3d dir = Vector3f(R); const ShadingRay ray( pos, normalize(dir), options.mindist, options.maxdist, parent->get_ray().m_time, VisibilityFlags::ProbeRay, parent->get_ray().m_depth + 1); ShadingPoint shading_point; intersector.trace( ray, shading_point, origin_shading_point); ShadingPoint::OSLTraceData* trace_data = reinterpret_cast<ShadingPoint::OSLTraceData*>(sg->tracedata); trace_data->m_traced = true; if (shading_point.hit()) { trace_data->m_hit = true; trace_data->m_P = Imath::V3d(shading_point.get_point()); trace_data->m_hit_distance = static_cast<float>(shading_point.get_distance()); trace_data->m_N = Imath::V3d(shading_point.get_shading_normal()); trace_data->m_Ng = Imath::V3d(shading_point.get_geometric_normal()); const Vector2d& uv = shading_point.get_uv(0); trace_data->m_u = static_cast<float>(uv[0]); trace_data->m_v = static_cast<float>(uv[1]); return true; } return false; }
CSVRender::WorldspaceHitResult CSVRender::WorldspaceWidget::mousePick (const QPoint& localPos, unsigned int interactionMask) const { // (0,0) is considered the lower left corner of an OpenGL window int x = localPos.x(); int y = height() - localPos.y(); // Convert from screen space to world space osg::Matrixd wpvMat; wpvMat.preMult (mView->getCamera()->getViewport()->computeWindowMatrix()); wpvMat.preMult (mView->getCamera()->getProjectionMatrix()); wpvMat.preMult (mView->getCamera()->getViewMatrix()); wpvMat = osg::Matrixd::inverse (wpvMat); osg::Vec3d start = wpvMat.preMult (osg::Vec3d(x, y, 0)); osg::Vec3d end = wpvMat.preMult (osg::Vec3d(x, y, 1)); osg::Vec3d direction = end - start; // Get intersection osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector (new osgUtil::LineSegmentIntersector( osgUtil::Intersector::MODEL, start, end)); intersector->setIntersectionLimit(osgUtil::LineSegmentIntersector::NO_LIMIT); osgUtil::IntersectionVisitor visitor(intersector); visitor.setTraversalMask(interactionMask); mView->getCamera()->accept(visitor); // Get relevant data for (osgUtil::LineSegmentIntersector::Intersections::iterator it = intersector->getIntersections().begin(); it != intersector->getIntersections().end(); ++it) { osgUtil::LineSegmentIntersector::Intersection intersection = *it; // reject back-facing polygons if (direction * intersection.getWorldIntersectNormal() > 0) { continue; } for (std::vector<osg::Node*>::iterator it = intersection.nodePath.begin(); it != intersection.nodePath.end(); ++it) { osg::Node* node = *it; if (osg::ref_ptr<CSVRender::TagBase> tag = dynamic_cast<CSVRender::TagBase *>(node->getUserData())) { WorldspaceHitResult hit = { true, tag, 0, 0, 0, intersection.getWorldIntersectPoint() }; if (intersection.indexList.size() >= 3) { hit.index0 = intersection.indexList[0]; hit.index1 = intersection.indexList[1]; hit.index2 = intersection.indexList[2]; } return hit; } } // Something untagged, probably terrain WorldspaceHitResult hit = { true, 0, 0, 0, 0, intersection.getWorldIntersectPoint() }; if (intersection.indexList.size() >= 3) { hit.index0 = intersection.indexList[0]; hit.index1 = intersection.indexList[1]; hit.index2 = intersection.indexList[2]; } return hit; } // Default placement direction.normalize(); direction *= CSMPrefs::get()["Scene Drops"]["distance"].toInt(); WorldspaceHitResult hit = { false, 0, 0, 0, 0, start + direction }; return hit; }
float CCLayerSorter::calculateZDiff(const LayerShape& layerA, const LayerShape& layerB, float earlyExitThreshold) { LayerIntersector intersector(layerA, layerB, earlyExitThreshold); intersector.go(); return intersector.zDiff; }
void AOVoxelTree::build( const Scene& scene, BuilderType& builder) { // The voxel tree is built using the scene geometry at the middle of the shutter interval. const double time = scene.get_camera()->get_shutter_middle_time(); // Loop over the assembly instances of the scene. for (const_each<AssemblyInstanceContainer> i = scene.assembly_instances(); i; ++i) { // Retrieve the assembly instance. const AssemblyInstance& assembly_instance = *i; // Retrieve the assembly. const Assembly& assembly = assembly_instance.get_assembly(); // Loop over the object instances of the assembly. for (const_each<ObjectInstanceContainer> j = assembly.object_instances(); j; ++j) { // Retrieve the object instance. const ObjectInstance& object_instance = *j; // Compute the object space to world space transformation. const Transformd transform = assembly_instance.transform_sequence().evaluate(time) * object_instance.get_transform(); // Retrieve the object. Object& object = object_instance.get_object(); // Retrieve the region kit of the object. Access<RegionKit> region_kit(&object.get_region_kit()); // Loop over the regions of the object. const size_t region_count = region_kit->size(); for (size_t region_index = 0; region_index < region_count; ++region_index) { // Retrieve the region. const IRegion* region = (*region_kit)[region_index]; // Retrieve the tessellation of the region. Access<StaticTriangleTess> tess(®ion->get_static_triangle_tess()); // Push all triangles of the region into the tree. const size_t triangle_count = tess->m_primitives.size(); for (size_t triangle_index = 0; triangle_index < triangle_count; ++triangle_index) { // Fetch the triangle. const Triangle& triangle = tess->m_primitives[triangle_index]; // Retrieve object instance space vertices of the triangle. const GVector3& v0_os = tess->m_vertices[triangle.m_v0]; const GVector3& v1_os = tess->m_vertices[triangle.m_v1]; const GVector3& v2_os = tess->m_vertices[triangle.m_v2]; // Transform triangle vertices to world space. const GVector3 v0(transform.point_to_parent(v0_os)); const GVector3 v1(transform.point_to_parent(v1_os)); const GVector3 v2(transform.point_to_parent(v2_os)); // Push the triangle into the tree. TriangleIntersector intersector(v0, v1, v2); builder.push(intersector); } } } } }