{"action":"opened","issue":{"url":"https://api.github.com/repos/bulletphysics/bullet3/issues/1253","repository_url":"https://api.github.com/repos/bulletphysics/bullet3","labels_url":"https://api.github.com/repos/bulletphysics/bullet3/issues/1253/labels{/name}","comments_url":"https://api.github.com/repos/bulletphysics/bullet3/issues/1253/comments","events_url":"https://api.github.com/repos/bulletphysics/bullet3/issues/1253/events","html_url":"https://github.com/bulletphysics/bullet3/issues/1253","id":249977542,"number":1253,"title":"contactManifold->getNumContacts() always 0 [assistance]","user":{"login":"kenkit","id":1732471,"avatar_url":"https://avatars1.githubusercontent.com/u/1732471?v=4","gravatar_id":"","url":"https://api.github.com/users/kenkit","html_url":"https://github.com/kenkit","followers_url":"https://api.github.com/users/kenkit/followers","following_url":"https://api.github.com/users/kenkit/following{/other_user}","gists_url":"https://api.github.com/users/kenkit/gists{/gist_id}","starred_url":"https://api.github.com/users/kenkit/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kenkit/subscriptions","organizations_url":"https://api.github.com/users/kenkit/orgs","repos_url":"https://api.github.com/users/kenkit/repos","events_url":"https://api.github.com/users/kenkit/events{/privacy}","received_events_url":"https://api.github.com/users/kenkit/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2017-08-14T09:28:58Z","updated_at":"2017-08-14T09:28:58Z","closed_at":null,"body":"I am using bullet only for collision detection for now, I am self-taught programmer.\r\nThis is the only code that I could manage to get working. I can't find enough information.\r\nI intend to use this code in a game I'm working on in Ogre3d.\r\n\r\n\r\nWhy dpes` getNumContacts()` always return zero even after collisions were detected ?\r\n\r\n```\r\n#include <iostream>\r\n#include <fstream>\r\n#include <vector>\r\n#include <string>\r\n#include <windows.h>\r\n#include <btBulletDynamicsCommon.h>\r\n#include \"vld.h\"\r\n\r\n#define PRINTF_FLOAT \"%7.3f\"\r\n\r\nconstexpr float gravity = -10.0f;\r\nconstexpr float initialY = 10.0f;\r\nconstexpr float timeStep = 1.0f / 60.0f;\r\n// TODO some combinations of coefficients smaller than 1.0\r\n// make the ball go up higher / not lose height. Why?\r\nconstexpr float groundRestitution = 0.9f;\r\nconstexpr float sphereRestitution = 0.9f;\r\nconstexpr int maxNPoints = 500;\r\n\r\nstruct my_box {\r\n\tstd::string box_name;\r\n};\r\n\r\nstd::vector<btVector3> collisions;\r\nvoid myTickCallback(btDynamicsWorld *dynamicsWorld, btScalar timeStep) {\r\n\t\r\n\r\n    int numManifolds = dynamicsWorld->getDispatcher()->getNumManifolds();\r\n    for (int i = 0; i < numManifolds; i++) {\r\n\t\tstd::cout << \"--------------------Collisions found--------------------\" << std::endl;\r\n        btPersistentManifold *contactManifold = dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i);\r\n        // TODO those are unused. What can be done with them?\r\n        // I think they are the same objects as those in the main loop\r\n        // dynamicsWorld->getCollisionObjectArray() and we could compare\r\n        // the pointers to see which object collided with which.\r\n\t\t\r\n            const btCollisionObject *objA = contactManifold->getBody0();\r\n            const btCollisionObject *objB = contactManifold->getBody1();\r\n\r\n\t\t\tmy_box *kks = (my_box*)objA->getUserPointer();\r\n\t\t\tmy_box *kkv = (my_box*)objB->getUserPointer();\r\n\t\t\tstd::cout << \"Collision detected BTWN :\" <<kks->box_name<<\" & \"<< kkv->box_name;\r\n\t\t\r\n\t\t\tint numContacts = contactManifold->getNumContacts();\r\n\t\tstd::cout << \" CONTACTS:\" << numContacts << std::endl;\r\n\r\n\t\tfor (int j = 0; j<numContacts; j++)\r\n\t\t{\r\n\t\t\tbtManifoldPoint& pt = contactManifold->getContactPoint(j);\r\n\t\t\tif (1/*pt.getDistance()<100.f*/)\r\n\t\t\t{\r\n\t\t\t\tconst btVector3& ptA = pt.getPositionWorldOnA();\r\n\t\t\t\tconst btVector3& ptB = pt.getPositionWorldOnB();\r\n\t\t\t\tconst btVector3& normalOnB = pt.m_normalWorldOnB;\r\n\t\t\t\tmy_box *kks = (my_box*)objA->getUserPointer();\r\n\t\t\t\tmy_box *kkv = (my_box*)objB->getUserPointer();\r\n\t\t\t\t\r\n\t\t\t}\r\n\t\t}\r\n    }\r\n}\r\n\r\nint main() {\r\n    int i, j;\r\n\r\n\tmy_box *mybox1 = new my_box;\r\n\tmy_box *mybox2 = new my_box;\r\n\tmybox1->box_name = \"Box1\";\r\n\tmybox2->box_name = \"Box2\";\r\n\r\n    btDefaultCollisionConfiguration *collisionConfiguration = new btDefaultCollisionConfiguration();\r\n    btCollisionDispatcher *dispatcher = new btCollisionDispatcher(collisionConfiguration);\r\n    btBroadphaseInterface *overlappingPairCache = new btDbvtBroadphase();\r\n    btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;\r\n    btDiscreteDynamicsWorld *dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, overlappingPairCache, solver, collisionConfiguration);\r\n\tdynamicsWorld->setGravity(btVector3(0, gravity, 0));\r\n    dynamicsWorld->setInternalTickCallback(myTickCallback);\r\n\r\n\tbtVector3 fallInertia(0, 0, 0);\r\n\tbtScalar mass = 1;\r\n    // Ground.\r\n\r\n\t\tbtDefaultMotionState* fallMotionState =\r\n\t\tnew btDefaultMotionState(btTransform(btQuaternion(0, 0, 0, 1), btVector3(0, 0, 0)));\r\n        btTransform groundTransform;\r\n        groundTransform.setIdentity();\r\n        groundTransform.setOrigin(btVector3(0, 0, 0));\r\n        btCollisionShape* boxShape;\r\n\t\tboxShape = new btSphereShape(1);\r\n\t\tbtRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass, fallMotionState, boxShape, fallInertia);\r\n\t\t\r\n\t\t\r\n\r\n\r\n\t\tbtRigidBody *box1 = new btRigidBody(fallRigidBodyCI);\r\n\t\tbox1->setUserPointer(mybox1);\r\n\t\tdynamicsWorld->addRigidBody(box1);\r\n\t\r\n\t\tbtRigidBody  *box2 = new btRigidBody(fallRigidBodyCI);\r\n\t\tbox2->setUserPointer(mybox2);\r\n\t\tdynamicsWorld->addRigidBody(box2);\r\n\r\n\r\n    // Main loop.\r\n   \r\n\tint y_box = 100;\r\n\tint y_box2 = 0;\r\n\tmy_box *kks;\r\n\tbtTransform k;\r\n\tfor (int i = 0; i < 100;i++) {\r\n\t\t//std::cout << \"bx 1:\" << y_box<<\" bx 2:\"<<y_box2 << std::endl;\r\n\t\tconst btCollisionObjectArray coA = dynamicsWorld->getCollisionObjectArray();\r\n\t\t//std::cout << \"size:\"<< coA.size() << std::endl;\r\n\t\tfor (int j = 0; j < coA.size(); j++) {\r\n\t\t\tkks = (my_box*)coA.at(j)->getUserPointer();\r\n\t\t\tif (kks->box_name == \"Box1\") {\r\n\t\t\t\t\r\n\t\t\t\tk.setOrigin(btVector3((btScalar)0, (btScalar)y_box, (btScalar)0));\r\n\t\t\t\tcoA.at(j)->setWorldTransform(k);\r\n\t\t\t\tstd::cout << \"SETTING BOX 1:\" << coA.at(j)->getWorldTransform().getOrigin().getY() << std::endl;\r\n\t\t\t}\r\n\t\t\tif (kks->box_name == \"Box2\") {\r\n\t\t\t\tstd::cout << \"SETTING BOX 2:\" << y_box2 << std::endl;\r\n\t\t\t\tk.setOrigin(btVector3((btScalar)0, (btScalar)y_box2, (btScalar)0));\r\n\t\t\t\tcoA.at(j)->setWorldTransform(k);\r\n\t\t\t}\r\n\t\t}\r\n\t\tdynamicsWorld->stepSimulation(timeStep);\r\n\t\ty_box--;\r\n\t\ty_box2++;\r\n    }\r\n\r\n\r\n\tSleep(10000);\r\n    // Cleanup.\r\n    for (i = dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; --i) {\r\n        btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[i];\r\n        btRigidBody* body = btRigidBody::upcast(obj);\r\n\t\tmy_box *kks = (my_box*)obj->getUserPointer();\r\n        dynamicsWorld->removeCollisionObject(obj);\r\n\t\tdelete body;\r\n\t\tdelete kks;\r\n    }\r\n  \r\n\tdelete boxShape;\r\n    delete dynamicsWorld;\r\n    delete solver;\r\n    delete overlappingPairCache;\r\n    delete dispatcher;\r\n    delete collisionConfiguration;\r\n\tdelete fallMotionState;\r\n  \r\n}\r\n```\r\n\r\n"}}
{"actor":{"display_login":"kenkit"}}