/*! \brief Clamp point to scene. \ingroup Render */ dmz::Boolean dmz::isect_clamp_point ( const Vector Value, RenderModuleIsect &isect, Vector &point, Vector &normal) { Boolean result (False); Vector offset (0.0, 1.5, 0.0); Vector start (Value + offset); IsectParameters parameters; IsectTestContainer test; IsectResultContainer isectResults; test.set_test (1, IsectRayTest, start, Down); if (isect.do_isect (parameters, test, isectResults)) { result = isect_validate_point (Value, Down, isectResults, point, normal); } if (!result) { start = Value - offset; test.set_test (1, IsectRayTest, start, Up); if (isect.do_isect (parameters, test, isectResults)) { result = isect_validate_point (Value, Up, isectResults, point, normal); } } return result; }
// TimeSlice Interface void dmz::WeaponPluginGravityBullet::update_time_slice (const Float64 TimeDelta) { ObjectModule *objMod (get_object_module ()); if (objMod && _isectMod) { const Vector GravityVel (0.0, (-_gravity) * TimeDelta, 0.0); HashTableHandleIterator it; IsectParameters params; params.set_test_result_type (IsectClosestPoint); Float64 *speedPtr (_objectTable.get_first (it)); while (speedPtr) { Handle obj (it.get_hash_key ()); Vector pos; Matrix ori; Vector vel; objMod->lookup_position (obj, _defaultHandle, pos); objMod->lookup_orientation (obj, _defaultHandle, ori); objMod->lookup_velocity (obj, _defaultHandle, vel); vel += GravityVel; objMod->store_velocity (obj, _defaultHandle, vel); const Vector NewPos (pos + (vel * TimeDelta)); IsectTestContainer test; IsectResultContainer isectResults; test.set_test (1, IsectSegmentTest, pos, NewPos); _isectMod->disable_isect (obj); if (_isectMod->do_isect (params, test, isectResults)) { if (_eventMod) { IsectResult value; isectResults.get_first (value); Handle target (0); value.get_object_handle (target); _eventMod->create_detonation_event (obj, target); } objMod->destroy_object (obj); } else { objMod->store_position (obj, _defaultHandle, NewPos); objMod->store_velocity (obj, _defaultHandle, vel); } _isectMod->enable_isect (obj); speedPtr = _objectTable.get_next (it); } } }
dmz::Boolean dmz::RenderModuleIsectOSG::do_isect ( const IsectParameters &Parameters, const IsectTestContainer &TestValues, IsectResultContainer &resultContainer) { if (_core) { osg::ref_ptr<osg::Group> scene = _core->get_isect (); // osg::ref_ptr<osg::Group> scene = _core->get_static_objects (); osg::BoundingSphere bs = scene->getBound(); std::vector<osg::LineSegment*> lsList;// = new osg::LineSegment[TestValues]; osgUtil::IntersectVisitor visitor; visitor.setTraversalMask (_isectMask); UInt32 testHandle; IsectTestTypeEnum testType; Vector vec1, vec2; std::vector<UInt32> handleArray; std::vector<Vector> sourceArray; TestValues.get_first_test (testHandle, testType, vec1, vec2); do { if (testType == IsectRayTest) { vec2 = (vec1 + (vec2 * (bs.radius () * 2))); } osg::LineSegment *ls = new osg::LineSegment; ls->set (to_osg_vector (vec1), to_osg_vector (vec2)); visitor.addLineSegment (ls); lsList.push_back (ls); handleArray.push_back (testHandle); sourceArray.push_back (vec1); } while (TestValues.get_next_test (testHandle, testType, vec1, vec2)); scene->accept (visitor); IsectTestResultTypeEnum param = Parameters.get_test_result_type (); bool closestPoint = (param == IsectClosestPoint); bool firstPoint = (param == IsectFirstPoint); if (closestPoint && !Parameters.get_calculate_distance ()) { firstPoint = true; closestPoint = false; } Boolean result (False); for (unsigned int ix = 0; ix < lsList.size () && !result; ix++) { osgUtil::IntersectVisitor::HitList resultHits; resultHits = visitor.getHitList (lsList[ix]); if (!resultHits.empty ()) { for (unsigned int jy = 0; jy < resultHits.size (); jy++) { Handle objHandle (0); osgUtil::Hit currentHit = resultHits[jy]; Boolean disabled (False); osg::CullFace *cf (0); osg::NodePath path = currentHit.getNodePath (); for ( osg::NodePath::iterator it = path.begin (); (it != path.end ()) && !disabled; it++) { osg::Node *node (*it); if (node) { osg::StateSet *sSet = (node->getStateSet ()); if (sSet) { osg::CullFace *cfTmp ( (osg::CullFace*)(sSet->getAttribute ( osg::StateAttribute::CULLFACE))); if (cfTmp) { cf = cfTmp; } } osg::Referenced *r (node->getUserData ()); if (r) { RenderObjectDataOSG *data ( dynamic_cast<RenderObjectDataOSG *> (r)); if (data) { if (!data->do_isect ()) { // Should never reach here now disabled = True; } else { objHandle = data->get_handle (); } } } } } if (!disabled) { Vector lsPoint = to_dmz_vector (currentHit.getWorldIntersectPoint ()); IsectResult lsResult; lsResult.set_isect_test_id (handleArray[ix]); lsResult.set_point (lsPoint); if (Parameters.get_calculate_object_handle ()) { lsResult.set_object_handle (objHandle); } if (Parameters.get_calculate_normal ()) { lsResult.set_normal ( to_dmz_vector (currentHit.getWorldIntersectNormal ())); } if (Parameters.get_calculate_distance ()) { lsResult.set_distance ((lsPoint - sourceArray[ix]).magnitude ()); } if (Parameters.get_calculate_cull_mode ()) { UInt32 cullMask = 0; if (cf) { if (cf->getMode () == osg::CullFace::FRONT || cf->getMode () == osg::CullFace::FRONT_AND_BACK) { cullMask |= IsectPolygonFrontCulledMask; } if (cf->getMode () == osg::CullFace::BACK || cf->getMode () == osg::CullFace::FRONT_AND_BACK) { cullMask |= IsectPolygonBackCulledMask; } } else { cullMask |= IsectPolygonBackCulledMask; } lsResult.set_cull_mode (cullMask); } if (Parameters.get_calculate_object_handle ()) { osg::Geode *hitObject = currentHit.getGeode (); } resultContainer.add_result (lsResult); if (firstPoint) { result = true; } } } } } if (closestPoint && resultContainer.get_result_count () > 1) { IsectResult current; resultContainer.get_first (current); IsectResult closest (current); double closestDist; current.get_distance (closestDist); while (resultContainer.get_next (current)) { double testDist; if (current.get_distance (testDist)) { if (testDist < closestDist) { closest = current; } } } IsectResultContainer closestContainer; closestContainer.add_result (closest); resultContainer = closestContainer; } } return resultContainer.get_result_count () > 0; }