Physics Simulation Forum

 

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Sun Mar 31, 2013 2:42 am 
Offline

Joined: Sat Dec 29, 2012 7:20 pm
Posts: 24
EDIT2: Objects seem to collide when they spawn in each others's AABB

EDIT: Turns out it's not the btTriangleMesh! That's fine. :) It's the tiny object that somehow has a huge hitbox the first frame. See my later posts for information and screenshots.

Hey guys,

I'm creating a btTriangleMesh like this:

Code:
   std::shared_ptr<btTriangleMesh> Mesh::get_bt_mesh(Scale scale) const {
      std::shared_ptr<btTriangleMesh> triangle_mesh{new btTriangleMesh()};
      COUT << indices.size() << std::endl;
      for(unsigned int i = 0; i < indices.size(); i += 3){
         auto const pv = [&](size_t const n){
            return vertices[indices[i+n]].position.slice<0,3>() * scale * .95f;
         };
         
         auto const v = [&](size_t const i){
            return convert<btVector3>(pv(i));
         };
         
         // CERR << pv(0) << std::endl
         //     << pv(1) << std::endl
         //     << pv(2) << std::endl;
         
         triangle_mesh->addTriangle(v(0), v(1), v(2), false);
         COUT << i << std::endl;
      }
      return triangle_mesh;
   }


But my other objects are constantly colliding with it, even when they are not near touching it according to the debugdrawer, I attached a screenshot.

I'm using the btTriangleMesh as a collision shape like so:

Code:
      bt_mesh = mesh->get_bt_mesh(get_scale());
      collision_shape = std::make_shared<btBvhTriangleMeshShape>(bt_mesh.get(), true);
      physical_body->setCollisionShape(collision_shape.get());


where bt_mesh is the btTriangleMesh, collision_shape is an std::shared_ptr<btCollisionShape> and physical_body is a std::shared_ptr<btRigidBody>.

As you can see in the debug draw, everything seems to be fine, but my objects are still colliding with it and I don't know why. Not *all* objects collide with it, it's in some specific places. I couldn't figure out a pattern though, but I think it's worth mentioning.

Thanks in advance,


Attachments:
File comment: The center block is the player, the block to the right will collide with the planet in the next tick.
example.png
example.png [ 299.24 KiB | Viewed 287 times ]


Last edited by Nickert on Sun Apr 07, 2013 6:14 pm, edited 2 times in total.
Top
 Profile  
 
PostPosted: Sun Mar 31, 2013 2:43 am 
Offline

Joined: Sat Dec 29, 2012 7:20 pm
Posts: 24
I encircled the block that will collide with the sphere at the bottom.


Attachments:
example.png
example.png [ 353.65 KiB | Viewed 286 times ]
Top
 Profile  
 
PostPosted: Sun Mar 31, 2013 6:32 pm 
Offline

Joined: Sat Dec 29, 2012 7:20 pm
Posts: 24
So my question is basically if there's some known issue or how I can debug this. Anyone? :D


Top
 Profile  
 
PostPosted: Sun Mar 31, 2013 11:19 pm 
Offline

Joined: Sat Dec 29, 2012 7:20 pm
Posts: 24
<irrelevant post>


Last edited by Nickert on Sun Apr 07, 2013 6:21 pm, edited 1 time in total.

Top
 Profile  
 
PostPosted: Sun Apr 07, 2013 6:19 pm 
Offline

Joined: Sat Dec 29, 2012 7:20 pm
Posts: 24
I have made a small testcase (for me small) and it seems like objects are reported as colliding when checking for collisions like this:

Code:
void Physics::check_collisions(){
   std::vector<std::pair<btCollisionObject const*, btCollisionObject const*>> bullet_objects_colliding;
   int const manifolds = dynamics_world->getDispatcher()->getNumManifolds();
   for(int manifold_index = 0; manifold_index < manifolds; ++manifold_index){
      auto const manifold = dynamics_world->getDispatcher()->getManifoldByIndexInternal(manifold_index);

      btCollisionObject const* first_object = manifold->getBody0();
      btCollisionObject const* second_object = manifold->getBody1();

      bullet_objects_colliding.emplace_back(first_object, second_object);
   }

   for(auto const& c : bullet_objects_colliding){
      if(!astrant::contains(bullet_objects_in_collision_previous_frame, c)){
         bullet_objects_entered_collision(c.first, c.second);
      }
   }

   for(auto const& c : bullet_objects_in_collision_previous_frame){
      if(!astrant::contains(bullet_objects_colliding, c)){
         bullet_objects_exited_collision(c.first, c.second);
      }
   }

   bullet_objects_in_collision_previous_frame = bullet_objects_colliding;
}


Attached are some screenshots: the red cubes have been noted as colliding with the cow.

How can I fix this? Is there something wrong with my collision detection detection? Any hints/tips are welcome!


Attachments:
File comment: Debug draw, not really useful but figured I might as well attach it.
Screen Shot 2013-04-07 at 20.12.49.533.png
Screen Shot 2013-04-07 at 20.12.49.533.png [ 53.35 KiB | Viewed 137 times ]
File comment: Removed all the never-collided cubes.
Screen Shot 2013-04-07 at 20.12.24.950.png
Screen Shot 2013-04-07 at 20.12.24.950.png [ 57.8 KiB | Viewed 137 times ]
File comment: Cow with a ton of cubes, red ones are colliding.
Screen Shot 2013-04-07 at 20.12.19.718.png
Screen Shot 2013-04-07 at 20.12.19.718.png [ 193.94 KiB | Viewed 137 times ]
Top
 Profile  
 
PostPosted: Sun Apr 07, 2013 6:59 pm 
Offline

Joined: Sat Dec 29, 2012 7:20 pm
Posts: 24
checkCollideWith also says the bodies are colliding... but they are not. :evil:


Top
 Profile  
 
PostPosted: Sun Apr 07, 2013 7:43 pm 
Offline

Joined: Sat Dec 29, 2012 7:20 pm
Posts: 24
The objects don't seem to have any contact points when drawn with the debugdrawer. Interesting.

The getNumContacts in the manifold is also 0! But why are the objects even "colliding" then? Because they are about to?

Long story short, fixed it by checking the number of contacts in the manifold. Actual touch-detection code:

Code:
void Physics::check_collisions(){
   std::vector<std::pair<btCollisionObject const*, btCollisionObject const*>> bullet_objects_colliding;
   int const manifolds = dynamics_world->getDispatcher()->getNumManifolds();
   for(int manifold_index = 0; manifold_index < manifolds; ++manifold_index){
      auto const manifold = dynamics_world->getDispatcher()->getManifoldByIndexInternal(manifold_index);

      btCollisionObject const* first_object = manifold->getBody0();
      btCollisionObject const* second_object = manifold->getBody1();

      if(manifold->getNumContacts() > 0){
         bullet_objects_colliding.emplace_back(first_object, second_object);
      }
   }

   for(auto const& c : bullet_objects_colliding){
      if(!astrant::contains(bullet_objects_in_collision_previous_frame, c)){
         bullet_objects_entered_collision(c.first, c.second);
      }
   }

   for(auto const& c : bullet_objects_in_collision_previous_frame){
      if(!astrant::contains(bullet_objects_colliding, c)){
         bullet_objects_exited_collision(c.first, c.second);
      }
   }

   bullet_objects_in_collision_previous_frame = bullet_objects_colliding;
}


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC


Who is online

Users browsing this forum: Google [Bot], yamasaki and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group