示例#1
0
/*!

\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);
      }
   }
}
示例#3
0
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;
}