8CollisionWorld::CollisionBody::CollisionBody(btRigidBody::btRigidBodyConstructionInfo& inf,
CollisionWorld* owner)
9 :btRigidBody(inf), owner(owner) {
13 auto flags = this->getCollisionFlags();
15 if((flags & btCollisionObject::CF_STATIC_OBJECT)==0) {
16 owner->removeRigidBody(
this);
17 auto& rigid = owner->rigid;
18 for(
size_t i=0; i<rigid.size(); ++i) {
20 rigid[i] = rigid.back();
26 owner->removeCollisionObject(
this);
37 btDbvtProxy* proxy =
reinterpret_cast<btDbvtProxy*
>(leaf->data);
43 m_deferedcollide =
true;
47 void rayTest(
const btVector3& rayFrom,
const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,
48 const btVector3& aabbMin,
const btVector3& aabbMax) {
50 btAlignedObjectArray<const btDbvtNode*>* stack = &
rayTestStk;
52 m_sets[0].rayTestInternal(m_sets[0].m_root,
55 rayCallback.m_rayDirectionInverse,
57 rayCallback.m_lambda_max,
63 m_sets[1].rayTestInternal(m_sets[1].m_root,
66 rayCallback.m_rayDirectionInverse,
68 rayCallback.m_lambda_max,
81 conf .reset(
new btDefaultCollisionConfiguration());
84 disp .reset(
new btCollisionDispatcher(
conf.get()));
87 solver.reset(
new btSequentialImpulseConstraintSolver());
89 std::unique_ptr<btCollisionConfiguration>
conf;
90 std::unique_ptr<btCollisionDispatcher>
disp;
91 std::unique_ptr<btSequentialImpulseConstraintSolver>
solver;
92 std::unique_ptr<btBroadphaseInterface>
broad;
104 return {v.x*0.01f, v.y*0.01f, v.z*0.01f};
108 return {v.x()*100.f, v.y()*100.f, v.z()*100.f};
112 :btDiscreteDynamicsWorld(ci.disp.get(), ci.broad.get(), ci.solver.get(), ci.conf.get()) {
113 disp = std::move(ci.disp);
114 broad = std::move(ci.broad);
115 solver = std::move(ci.solver);
116 conf = std::move(ci.conf);
118 setForceUpdateAllAabbs(
false);
125 btDiscreteDynamicsWorld::updateAabbs();
136 struct rCallBack :
public btCollisionWorld::ContactResultCallback {
138 Tempest::Vec3 norm = {};
139 btCollisionObject* src =
nullptr;
142 explicit rCallBack(btCollisionObject* src):src(src){
143 m_collisionFilterMask = btBroadphaseProxy::DefaultFilter | btBroadphaseProxy::StaticFilter;
146 bool needsCollision(btBroadphaseProxy* proxy0)
const override {
147 auto obj=
reinterpret_cast<btCollisionObject*
>(proxy0->m_clientObject);
151 return ContactResultCallback::needsCollision(proxy0);
155 btScalar addSingleResult(btManifoldPoint& p,
156 const btCollisionObjectWrapper* proxy0,
int,
int,
157 const btCollisionObjectWrapper* proxy1,
int,
int)
override {
158 norm.x+=p.m_normalWorldOnB.x();
159 norm.y+=p.m_normalWorldOnB.y();
160 norm.z+=p.m_normalWorldOnB.z();
162 auto obj = proxy1->getCollisionObject();
164 vob =
reinterpret_cast<Interactive*
>(obj->getUserPointer());
170 norm /= norm.length();
174 rCallBack callback{&it};
177 contactTest(&it, callback);
179 if(callback.count>0){
180 callback.normalize();
181 normal = callback.norm;
184 return callback.count>0;
188 btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(
195 std::unique_ptr<CollisionBody> obj(
new CollisionBody(rigidBodyCI,
this));
196 obj->setCollisionFlags(btCollisionObject::CF_STATIC_OBJECT);
199 trans.setFromOpenGLMatrix(tr.data());
200 trans.getOrigin()*=0.01f;
202 obj->setWorldTransform(trans);
203 obj->setFriction(friction);
205 this->addCollisionObject(obj.get());
206 this->updateSingleAabb(obj.get());
211 float friction,
float mass) {
214 btVector3 localInertia = {};
215 shape.calculateLocalInertia(mass, localInertia);
217 btRigidBody::btRigidBodyConstructionInfo rigidBodyCI(
224 std::unique_ptr<DynamicBody> obj(
new DynamicBody(rigidBodyCI,
this));
229 trans.setFromOpenGLMatrix(tr.data());
230 trans.getOrigin()*=0.01f;
232 obj->setWorldTransform(trans);
233 obj->setFriction(friction);
234 obj->setActivationState(ACTIVE_TAG);
236 obj->setCcdSweptSphereRadius(0.1f);
237 obj->setCcdMotionThreshold(0.005f);
239 this->addRigidBody(obj.get());
240 this->updateSingleAabb(obj.get());
241 rigid.push_back(obj.get());
249 this->rayTest(s,f,cb);
253 static bool dynamic =
true;
254 const float dtF = float(dt);
258 this->stepSimulation(dtF/1000.f, 2);
261 const int numManifolds = getDispatcher()->getNumManifolds();
262 for(
int i=0; i<numManifolds; ++i) {
263 btPersistentManifold* contactManifold = getDispatcher()->getManifoldByIndexInternal(i);
264 const btCollisionObject* a = contactManifold->getBody0();
265 const btCollisionObject* b = contactManifold->getBody1();
267 for(
auto obj:{a,b}) {
270 const int numContacts = contactManifold->getNumContacts();
274 btManifoldPoint& pt = contactManifold->getContactPoint(0);
275 auto impulse = pt.getAppliedImpulse();
276 auto mass =
reinterpret_cast<const DynamicBody*
>(obj)->mass;
277 if(impulse/mass<0.9f)
280 auto land = (obj==a ? b : a);
284 auto matId = zenkit::MaterialGroup::STONE;
285 if(
auto shape = land->getCollisionShape()) {
286 auto s =
reinterpret_cast<const btMultimaterialTriangleMeshShape*
>(shape);
287 auto mt =
reinterpret_cast<const PhysicVbo*
>(s->getMeshInterface());
289 int part = (obj==a ? pt.m_partId1 : pt.m_partId0);
293 if(
auto ptr =
reinterpret_cast<::
Item*
>(obj->getUserPointer())) {
294 hitItem(*ptr,matId,impulse,mass);
302 i->setLinearVelocity(i->getLinearVelocity()+gravity*dtF);
304 uint64_t cnt = uint64_t(i->getLinearVelocity().length());
306 for(uint64_t r=1; active && r<=(cnt*dt) && r<150; ++r)
307 active &=
tick(1.f/
float(cnt*dt),*i);
310 i->setDeactivationTime(0);
311 i->setActivationState(ACTIVE_TAG);
313 i->setLinearVelocity(btVector3(0,0,0));
314 i->setActivationState(WANTS_DEACTIVATION);
315 i->setDeactivationTime(i->getDeactivationTime()+float(dt)/1000.f);
321 if(
auto ptr =
reinterpret_cast<::
Item*
>(i->getUserPointer())) {
322 auto t = i->getWorldTransform();
323 t.getOrigin()*=100.f;
324 Tempest::Matrix4x4 mt;
325 t.getOpenGLMatrix(
reinterpret_cast<btScalar*
>(&mt));
326 ptr->setObjMatrix(mt);
328 for(
size_t i=0; i<rigid.size(); ++i) {
330 if((it->wantsSleeping() && (it->getDeactivationTime()>3.f || !it->isActive())) ||
331 (it->getWorldTransform().getOrigin().y()<bbox[0].y()-100)) {
332 if(
auto ptr =
reinterpret_cast<::
Item*
>(it->getUserPointer()))
333 ptr->setPhysicsDisable();
350 btTransform prev = body.getWorldTransform();
352 auto& at = trans.getOrigin();
354 at+=body.getLinearVelocity()*step;
355 body.setWorldTransform(trans);
359 body.setWorldTransform(prev);
362 updateSingleAabb(&body);
366void CollisionWorld::saveKinematicState(btScalar ) {
std::unique_ptr< CollisionBody > addCollisionBody(btCollisionShape &shape, const Tempest::Matrix4x4 &tr, float friction)
static const Tempest::Vec3 toCentimeters(const btVector3 &v)
void setItemHitCallback(std::function< void(Item &itm, zenkit::MaterialGroup mat, float impulse, float mass)> f)
void rayCast(const Tempest::Vec3 &b, const Tempest::Vec3 &e, RayResultCallback &cb)
bool hasCollision(const btCollisionObject &it, Tempest::Vec3 &normal)
static float toMeters(const float v)
void setBBox(const btVector3 &min, const btVector3 &max)
std::unique_ptr< DynamicBody > addDynamicBody(btCollisionShape &shape, const Tempest::Matrix4x4 &tr, float friction, float mass)
void updateAabbs() override
static constexpr float gravityMS
zenkit::MaterialGroup materialId(size_t segment) const
BroadphaseRayTester(btBroadphaseRayCallback &orgCallback)
btBroadphaseRayCallback & m_rayCallback
void Process(const btDbvtNode *leaf)
btAlignedObjectArray< const btDbvtNode * > rayTestStk
void rayTest(const btVector3 &rayFrom, const btVector3 &rayTo, btBroadphaseRayCallback &rayCallback, const btVector3 &aabbMin, const btVector3 &aabbMax)
std::unique_ptr< btSequentialImpulseConstraintSolver > solver
std::unique_ptr< btCollisionConfiguration > conf
std::unique_ptr< btCollisionDispatcher > disp
std::unique_ptr< btBroadphaseInterface > broad