Ogre collision detection, accurate to the object mesh Triangle Surface

Source: Internet
Author: User
Ogre collision detection, accurate to the object mesh Triangle Surface

(19:14:27)

Reprinted
Tags:

Miscellaneous
Category: MSN migration

      The final project of our course is a three-dimensional game of mosquito-sucking blood. Because the volume of mosquitoes is small, and mosquitoes need to fly in 3D scenarios. Therefore, the regular model detection for the box is insufficient. For example, there is a desk lamp in the scenario. From the perspective of the model's surrounding box, the desk lamp is a cuboid. If we use this method for collision detection, as a result, mosquitoes cannot fly through the arch bridge hole formed by the long arc trunk of the lamp, even though it does not seem to have hit the lamp. This is unacceptable in reality.      I have tried several methods: one is to use a few rays starting from a mosquito pointing to each direction to detect a collision, and the other is to use a sphere to enclose a mosquito, then, the number of objects in the sphere is checked to detect the collision. However, the final failure is due to the fact that these collisions can only detect the point of intersection with the model surrounding box.      It seems that you must find a better solution.      Fortunately, I found a third-party open-source library called   Minimal ogre collision . You can find the region on http://www.ogre3d.org/wiki/index.php/minimal_ogre_collision.      I decided to pick out the core piece of code and explain it in detail.// Ray, X-ray. Result: intersection of the model surface. Target: intersection object. closest_distance: distance from the closest intersection. querymask: bool collisiontools :: raycast (const ogre: Ray & ray, ogre: vector3 & result, ogre: movableobject * & target, float & closest_distance, const ogre: uint32 querymask)
{
  Target = NULL;      // Test whether the ray is valid
      If (mrayscenequery! = NULL)
      {
              // Create a ray Query    Mrayscenequery-> setray (Ray );
    Mrayscenequery-> setsortbydistance (true); // the query results are sorted by distance.
    Mrayscenequery-> setquerymask (querymask); // sets the mask.
              // Execute Query
              If (mrayscenequery-> execute (). Size () <= 0)
              {                      Return (false );
              }
      }
      Else
      {
              // Log_error <"cannot raycast without rayscenequery instance" <endlog;
              Return (false );
      }      // Note: here we have obtained a series of models detected by the box.
      // We need to find the first intersecting object.
      // This means that we do not have to detect the following objects, which greatly saves time.
      // But unfortunately, we have to traverse every object's triangle. It sounds so painful and we have to endure it.
      //
      // The minimum initialization distance is-1.
  Closest_distance =-1.0f;
      Ogre: vector3 closest_result;
      Ogre: rayscenequeryresult & query_result = mrayscenequery-> getlastresults (); // retrieve the query result because it was not saved before.
      For (size_t qr_idx = 0; qr_idx <query_result.size (); qr_idx ++)
      {
              // If the next collision object is far behind this, of course we should ignore it.                             If (closest_distance >=0.0f )&&
                      (Closest_distance <query_result [qr_idx]. Distance ))
              {
                      Break;
              }              // We only care about collision as an object.              If (query_result [qr_idx]. movable! = NULL) &&
                      (Query_result [qr_idx]. movable-> getmovabletype (). Compare ("entity") = 0 ))
              {
                      // Obtain the collided object                      Ogre: movableobject * pentity = static_cast <ogre: movableobject *> (query_result [qr_idx]. movable );                      // The vertex is the vertex, and the index is the index. Don't worry. Let's look down.
                      Size_t vertex_count;
                      Size_t index_count;
                      Ogre: vector3 * vertices;
                      Ogre: uint32 * indices;                      // The following function gets detailed information about the model.
      Getmeshinformation (Ogre: entity *) pentity)-> getmesh (), vertex_count, vertices, index_count, indices,
                                                          Pentity-> getparentnode ()-> _ getderivedposition (),
                                                          Pentity-> getparentnode ()-> _ getderivedorientation (),
                                                          Pentity-> getparentnode ()-> _ getderivedscale ());                      // Once again, find the intersection of each triangle and record the latest vertex.                      Bool new_closest_found = false;
                      For (size_t I = 0; I <index_count; I + = 3)
                      {
                              // The following function calculates the intersection of a ray and a triangle, returns a pair, "whether or not intersection, distance from intersection"
                              STD: pair <bool, ogre: Real> hit = ogre: Math: intersects (Ray, vertices [indices [I],
                                      Vertices [indices [I + 1], vertices [indices [I + 2], true, false); // you know why the index is used, the index is the index of the vertex.                              // If a collision occurs, check whether it is the current minimum distance.
                              If (hit. First)
                              {
                                      If (closest_distance <0.0f) |
                                              (Hit. Second <closest_distance ))
                                      {
                                              // Update if yes
                                              Closest_distance = hit. Second;
                                              New_closest_found = true;
                                      }
                              }
                      }      // Release the memory you just applied for. Of course, this kind of stuff will be written in pairs when you write the application, just as at the same time writing {}                      Delete [] vertices;
                      Delete [] indices;                      // If a new vertex is found, do not forget to update the corresponding information.
                      If (new_closest_found)
                      {
                              Target = pentity;
                              Closest_result = Ray. getpoint (closest_distance); // calculate the closest vertex, a simple linear equation.
                      }
              }
      }      // Returned results      If (closest_distance> = 0.0f)
      {
              // Succeeded            Result = closest_result;
              Return (true );
      }
      Else
      {
              // Failed              Return (false );
      }
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.