diff options
author | Lukas Tönne <lukas.toenne@gmail.com> | 2022-06-29 22:50:35 +0300 |
---|---|---|
committer | Lukas Tönne <lukas.toenne@gmail.com> | 2022-06-29 22:50:35 +0300 |
commit | fa2084ae58a77b1201289b6bedac427f73c762d1 (patch) | |
tree | fd99401eb8e742415f59332d115f0f34699f92b6 /intern | |
parent | 0ea282f7462070041b2599389ba61c7ef50426b5 (diff) |
Geometry Nodes: Experimental rigid body integration.
This is an exploration of how geometry nodes might be coupled with
rigid bodies and iterative simulations in general. It's a very
rough-and-ready implementation, not meant as a final version, but rather
to prove the possiblity and to find challenging areas where redesign is
needed.
The core additions are:
- Geometry nodes to flag points and/or instances as rigid bodies.
- Depsgraph integration to ensure the necessary order of operations
between modifiers and rigid body pre/post simulation updates.
- Simple cache feature to store arbitrary geometry and loop back into
the next iteration.
Diffstat (limited to 'intern')
-rw-r--r-- | intern/rigidbody/RBI_api.h | 24 | ||||
-rw-r--r-- | intern/rigidbody/rb_bullet_api.cpp | 80 |
2 files changed, 99 insertions, 5 deletions
diff --git a/intern/rigidbody/RBI_api.h b/intern/rigidbody/RBI_api.h index 13b1c096a80..8f2822f679f 100644 --- a/intern/rigidbody/RBI_api.h +++ b/intern/rigidbody/RBI_api.h @@ -87,7 +87,13 @@ void RB_dworld_export(rbDynamicsWorld *world, const char *filename); /* Add RigidBody to dynamics world */ void RB_dworld_add_body(rbDynamicsWorld *world, rbRigidBody *body, int col_groups); -/* Remove RigidBody from dynamics world */ +void RB_dworld_add_body_ex(rbDynamicsWorld *world, + rbRigidBody *object, + int col_groups, + int filter_group, + int filter_mask); + + /* Remove RigidBody from dynamics world */ void RB_dworld_remove_body(rbDynamicsWorld *world, rbRigidBody *body); /* Collision detection */ @@ -119,6 +125,9 @@ void RB_body_set_type(rbRigidBody *body, int type, float mass); /* Collision Shape */ void RB_body_set_collision_shape(rbRigidBody *body, rbCollisionShape *shape); +int RB_body_get_collision_groups(rbRigidBody *body); +void RB_body_get_collision_group_ex(rbRigidBody *body, int *r_col_groups, int *r_filter_group, int *r_filter_mask); + /* ............ */ /* Mass */ @@ -182,7 +191,12 @@ void RB_body_set_loc_rot(rbRigidBody *body, const float loc[3], const float rot[ /* Set RigidBody's local scaling */ void RB_body_set_scale(rbRigidBody *body, const float scale[3]); -/* ............ */ +void RB_body_reset_loc_rot(rbDynamicsWorld *world, + rbRigidBody *object, + const float loc[3], + const float rot[4]); + + /* ............ */ /* Get RigidBody's position as a vector */ void RB_body_get_position(rbRigidBody *body, float v_out[3]); @@ -194,6 +208,10 @@ void RB_body_get_scale(rbRigidBody *object, float v_out[3]); /* ............ */ void RB_body_apply_central_force(rbRigidBody *body, const float v_in[3]); +void RB_body_clear_forces(rbDynamicsWorld *world, rbRigidBody *body); + +void RB_dworld_rebuild_islands(rbDynamicsWorld *world); + /* ********************************** */ /* Collision Shape Methods */ @@ -354,6 +372,8 @@ void RB_constraint_set_breaking_threshold(rbConstraint *con, float threshold); /* ********************************** */ +int RB_debug_get_world_index(rbDynamicsWorld *dworld, rbRigidBody *body); + #ifdef __cplusplus } #endif diff --git a/intern/rigidbody/rb_bullet_api.cpp b/intern/rigidbody/rb_bullet_api.cpp index ac8026be41b..8866892a824 100644 --- a/intern/rigidbody/rb_bullet_api.cpp +++ b/intern/rigidbody/rb_bullet_api.cpp @@ -50,6 +50,7 @@ #include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h" #include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h" #include "BulletCollision/Gimpact/btGImpactShape.h" +#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.h" struct rbDynamicsWorld { btDiscreteDynamicsWorld *dynamicsWorld; @@ -238,6 +239,14 @@ void RB_dworld_add_body(rbDynamicsWorld *world, rbRigidBody *object, int col_gro world->dynamicsWorld->addRigidBody(body); } +void RB_dworld_add_body_ex(rbDynamicsWorld *world, rbRigidBody *object, int col_groups, int filter_group, int filter_mask) +{ + btRigidBody *body = object->body; + object->col_groups = col_groups; + + world->dynamicsWorld->addRigidBody(body, filter_group, filter_mask); +} + void RB_dworld_remove_body(rbDynamicsWorld *world, rbRigidBody *object) { btRigidBody *body = object->body; @@ -372,6 +381,24 @@ void RB_body_set_collision_shape(rbRigidBody *object, rbCollisionShape *shape) RB_body_set_mass(object, RB_body_get_mass(object)); } +int RB_body_get_collision_groups(rbRigidBody *body) +{ + return body->col_groups; +} + +void RB_body_get_collision_group_ex(rbRigidBody *body, int *r_col_groups, int *r_filter_group, int *r_filter_mask) +{ + if (r_col_groups) { + *r_col_groups = body->col_groups; + } + if (r_filter_group) { + *r_filter_group = body->body->getBroadphaseHandle()->m_collisionFilterGroup; + } + if (r_filter_mask) { + *r_filter_mask = body->body->getBroadphaseHandle()->m_collisionFilterMask; + } +} + /* ............ */ float RB_body_get_mass(rbRigidBody *object) @@ -502,7 +529,9 @@ void RB_body_set_linear_velocity(rbRigidBody *object, const float v_in[3]) { btRigidBody *body = object->body; - body->setLinearVelocity(btVector3(v_in[0], v_in[1], v_in[2])); + btVector3 bt_vec{v_in[0], v_in[1], v_in[2]}; + body->setLinearVelocity(bt_vec); + body->setInterpolationLinearVelocity(bt_vec); } void RB_body_get_angular_velocity(rbRigidBody *object, float v_out[3]) @@ -516,7 +545,9 @@ void RB_body_set_angular_velocity(rbRigidBody *object, const float v_in[3]) { btRigidBody *body = object->body; - body->setAngularVelocity(btVector3(v_in[0], v_in[1], v_in[2])); + btVector3 bt_vec{v_in[0], v_in[1], v_in[2]}; + body->setAngularVelocity(bt_vec); + body->setInterpolationAngularVelocity(bt_vec); } void RB_body_set_linear_factor(rbRigidBody *object, float x, float y, float z) @@ -586,7 +617,9 @@ void RB_body_get_transform_matrix(rbRigidBody *object, float m_out[4][4]) trans.getOpenGLMatrix((btScalar *)m_out); } -void RB_body_set_loc_rot(rbRigidBody *object, const float loc[3], const float rot[4]) +void RB_body_set_loc_rot(rbRigidBody *object, + const float loc[3], + const float rot[4]) { btRigidBody *body = object->body; btMotionState *ms = body->getMotionState(); @@ -600,6 +633,27 @@ void RB_body_set_loc_rot(rbRigidBody *object, const float loc[3], const float ro ms->setWorldTransform(trans); } +void RB_body_reset_loc_rot(rbDynamicsWorld *world, + rbRigidBody *object, + const float loc[3], + const float rot[4]) +{ + btRigidBody *body = object->body; + + /* set transform matrix */ + btTransform trans; + trans.setIdentity(); + trans.setOrigin(btVector3(loc[0], loc[1], loc[2])); + trans.setRotation(btQuaternion(rot[1], rot[2], rot[3], rot[0])); + + body->setWorldTransform(trans); + body->setInterpolationWorldTransform(trans); + /* XXX Should be explicit parameters */ + body->setLinearVelocity(btVector3(0, 0, 0)); + body->setAngularVelocity(btVector3(0, 0, 0)); + world->dynamicsWorld->synchronizeSingleMotionState(object->body); +} + void RB_body_set_scale(rbRigidBody *object, const float scale[3]) { btRigidBody *body = object->body; @@ -653,6 +707,21 @@ void RB_body_apply_central_force(rbRigidBody *object, const float v_in[3]) body->applyCentralForce(btVector3(v_in[0], v_in[1], v_in[2])); } +void RB_body_clear_forces(rbDynamicsWorld *world, rbRigidBody *object) +{ + btRigidBody *body = object->body; + body->clearForces(); + world->dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs( + object->body->getBroadphaseProxy(), world->dynamicsWorld->getDispatcher()); +} + +void RB_dworld_rebuild_islands(rbDynamicsWorld *world) +{ + //world->dynamicsWorld->computeOverlappingPairs(); + //world->dynamicsWorld->getSimulationIslandManager()->buildIslands( + // world->dynamicsWorld->getDispatcher(), world->dynamicsWorld); +} + /* ********************************** */ /* Collision Shape Methods */ @@ -1287,3 +1356,8 @@ void RB_constraint_set_target_velocity_motor(rbConstraint *con, } /* ********************************** */ + +int RB_debug_get_world_index(rbDynamicsWorld *dworld, rbRigidBody *body) +{ + return body->body->getWorldArrayIndex(); +}
\ No newline at end of file |