rigidbody: Add function to perform convex sweep test
This is a experimental collision detection function, so the API might change in the future. Note: The simulation needs to be stepped before this function can be used, otherwise the rigid body world might not be valid. Patch [#34989] Bullet Convex sweep test API by Vilem Novak (pildanovak), thanks!
This commit is contained in:
@@ -110,6 +110,12 @@ extern void RB_dworld_add_body(rbDynamicsWorld *world, rbRigidBody *body, int co
|
|||||||
/* Remove RigidBody from dynamics world */
|
/* Remove RigidBody from dynamics world */
|
||||||
extern void RB_dworld_remove_body(rbDynamicsWorld *world, rbRigidBody *body);
|
extern void RB_dworld_remove_body(rbDynamicsWorld *world, rbRigidBody *body);
|
||||||
|
|
||||||
|
/* Collision detection */
|
||||||
|
|
||||||
|
void RB_world_convex_sweep_test(rbDynamicsWorld *world, rbRigidBody *object,
|
||||||
|
const float loc_start[3], const float loc_end[3],
|
||||||
|
float v_location[3], float v_hitpoint[3], float v_normal[3], int *r_hit);
|
||||||
|
|
||||||
/* ............ */
|
/* ............ */
|
||||||
|
|
||||||
/* Create new RigidBody instance */
|
/* Create new RigidBody instance */
|
||||||
|
@@ -242,6 +242,56 @@ void RB_dworld_remove_body(rbDynamicsWorld *world, rbRigidBody *object)
|
|||||||
world->dynamicsWorld->removeRigidBody(body);
|
world->dynamicsWorld->removeRigidBody(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Collision detection */
|
||||||
|
|
||||||
|
void RB_world_convex_sweep_test(rbDynamicsWorld *world, rbRigidBody *object, const float loc_start[3], const float loc_end[3], float v_location[3], float v_hitpoint[3], float v_normal[3], int *r_hit)
|
||||||
|
{
|
||||||
|
btRigidBody *body = object->body;
|
||||||
|
btCollisionShape *collisionShape = body->getCollisionShape();
|
||||||
|
/* only convex shapes are supported, but user can specify a non convex shape */
|
||||||
|
if (collisionShape->isConvex()) {
|
||||||
|
btCollisionWorld::ClosestConvexResultCallback result(btVector3(loc_start[0], loc_start[1], loc_start[2]), btVector3(loc_end[0], loc_end[1], loc_end[2]));
|
||||||
|
|
||||||
|
btQuaternion obRot = body->getWorldTransform().getRotation();
|
||||||
|
|
||||||
|
btTransform rayFromTrans;
|
||||||
|
rayFromTrans.setIdentity();
|
||||||
|
rayFromTrans.setRotation(obRot);
|
||||||
|
rayFromTrans.setOrigin(btVector3(loc_start[0], loc_start[1], loc_start[2]));
|
||||||
|
|
||||||
|
btTransform rayToTrans;
|
||||||
|
rayToTrans.setIdentity();
|
||||||
|
rayToTrans.setRotation(obRot);
|
||||||
|
rayToTrans.setOrigin(btVector3(loc_end[0], loc_end[1], loc_end[2]));
|
||||||
|
|
||||||
|
world->dynamicsWorld->convexSweepTest((btConvexShape*) collisionShape, rayFromTrans, rayToTrans, result, 0);
|
||||||
|
|
||||||
|
if (result.hasHit()) {
|
||||||
|
*r_hit = 1;
|
||||||
|
|
||||||
|
v_location[0] = result.m_convexFromWorld[0]+(result.m_convexToWorld[0]-result.m_convexFromWorld[0])*result.m_closestHitFraction;
|
||||||
|
v_location[1] = result.m_convexFromWorld[1]+(result.m_convexToWorld[1]-result.m_convexFromWorld[1])*result.m_closestHitFraction;
|
||||||
|
v_location[2] = result.m_convexFromWorld[2]+(result.m_convexToWorld[2]-result.m_convexFromWorld[2])*result.m_closestHitFraction;
|
||||||
|
|
||||||
|
v_hitpoint[0] = result.m_hitPointWorld[0];
|
||||||
|
v_hitpoint[1] = result.m_hitPointWorld[1];
|
||||||
|
v_hitpoint[2] = result.m_hitPointWorld[2];
|
||||||
|
|
||||||
|
v_normal[0] = result.m_hitNormalWorld[0];
|
||||||
|
v_normal[1] = result.m_hitNormalWorld[1];
|
||||||
|
v_normal[2] = result.m_hitNormalWorld[2];
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*r_hit = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
/* we need to return a value if user passes non convex body, to report */
|
||||||
|
*r_hit = -2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* ............ */
|
/* ............ */
|
||||||
|
|
||||||
rbRigidBody *RB_body_new(rbCollisionShape *shape, const float loc[3], const float rot[4])
|
rbRigidBody *RB_body_new(rbCollisionShape *shape, const float loc[3], const float rot[4])
|
||||||
|
@@ -594,6 +594,24 @@ static void rna_RigidBodyCon_motor_ang_target_velocity_set(PointerRNA *ptr, floa
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sweep test */
|
||||||
|
static void rna_RigidBodyWorld_convex_sweep_test(RigidBodyWorld *rbw, ReportList *reports, Object *object, float ray_start[3], float ray_end[3], float r_location[3], float r_hitpoint[3], float r_normal[3], int *r_hit)
|
||||||
|
{
|
||||||
|
#ifdef WITH_BULLET
|
||||||
|
RigidBodyOb *rob = object->rigidbody_object;
|
||||||
|
|
||||||
|
if (rbw->physics_world != NULL && rob->physics_object != NULL) {
|
||||||
|
RB_world_convex_sweep_test(rbw->physics_world, rob->physics_object, ray_start, ray_end, r_location, r_hitpoint, r_normal, r_hit);
|
||||||
|
if (*r_hit == -2) {
|
||||||
|
BKE_report(reports, RPT_ERROR, "A non convex collision shape was passed to the function. Use only convex collision shapes.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*r_hit=-1;
|
||||||
|
BKE_report(reports, RPT_ERROR, "Rigidbody world was not properly initialized, need to step the simulation first");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@@ -601,6 +619,7 @@ static void rna_def_rigidbody_world(BlenderRNA *brna)
|
|||||||
{
|
{
|
||||||
StructRNA *srna;
|
StructRNA *srna;
|
||||||
PropertyRNA *prop;
|
PropertyRNA *prop;
|
||||||
|
FunctionRNA *func;
|
||||||
|
|
||||||
srna = RNA_def_struct(brna, "RigidBodyWorld", NULL);
|
srna = RNA_def_struct(brna, "RigidBodyWorld", NULL);
|
||||||
RNA_def_struct_sdna(srna, "RigidBodyWorld");
|
RNA_def_struct_sdna(srna, "RigidBodyWorld");
|
||||||
@@ -678,6 +697,39 @@ static void rna_def_rigidbody_world(BlenderRNA *brna)
|
|||||||
RNA_def_property_struct_type(prop, "EffectorWeights");
|
RNA_def_property_struct_type(prop, "EffectorWeights");
|
||||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||||
RNA_def_property_ui_text(prop, "Effector Weights", "");
|
RNA_def_property_ui_text(prop, "Effector Weights", "");
|
||||||
|
|
||||||
|
/* Sweep test */
|
||||||
|
func = RNA_def_function(srna, "convex_sweep_test", "rna_RigidBodyWorld_convex_sweep_test");
|
||||||
|
RNA_def_function_ui_description(func, "Sweep test convex rigidbody against the current rigidbody world");
|
||||||
|
RNA_def_function_flag(func, FUNC_USE_REPORTS);
|
||||||
|
|
||||||
|
prop = RNA_def_pointer(func, "object", "Object", "", "Rigidbody object with a convex collision shape");
|
||||||
|
RNA_def_property_flag(prop, PROP_REQUIRED | PROP_NEVER_NULL);
|
||||||
|
RNA_def_property_clear_flag(prop, PROP_THICK_WRAP);
|
||||||
|
|
||||||
|
/* ray start and end */
|
||||||
|
prop = RNA_def_float_vector(func, "start", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
|
||||||
|
RNA_def_property_flag(prop, PROP_REQUIRED);
|
||||||
|
prop = RNA_def_float_vector(func, "end", 3, NULL, -FLT_MAX, FLT_MAX, "", "", -1e4, 1e4);
|
||||||
|
RNA_def_property_flag(prop, PROP_REQUIRED);
|
||||||
|
|
||||||
|
prop = RNA_def_float_vector(func, "object_location", 3, NULL, -FLT_MAX, FLT_MAX, "Location",
|
||||||
|
"The hit location of this sweep test", -1e4, 1e4);
|
||||||
|
RNA_def_property_flag(prop, PROP_THICK_WRAP);
|
||||||
|
RNA_def_function_output(func, prop);
|
||||||
|
|
||||||
|
prop = RNA_def_float_vector(func, "hitpoint", 3, NULL, -FLT_MAX, FLT_MAX, "Hitpoint",
|
||||||
|
"The hit location of this sweep test", -1e4, 1e4);
|
||||||
|
RNA_def_property_flag(prop, PROP_THICK_WRAP);
|
||||||
|
RNA_def_function_output(func, prop);
|
||||||
|
|
||||||
|
prop = RNA_def_float_vector(func, "normal", 3, NULL, -FLT_MAX, FLT_MAX, "Normal",
|
||||||
|
"The face normal at the sweep test hit location", -1e4, 1e4);
|
||||||
|
RNA_def_property_flag(prop, PROP_THICK_WRAP);
|
||||||
|
RNA_def_function_output(func, prop);
|
||||||
|
|
||||||
|
prop = RNA_def_int(func, "has_hit", 0, 0, 0, "", "If the function has found collision point, value is 1, otherwise 0", 0, 0);
|
||||||
|
RNA_def_function_output(func, prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rna_def_rigidbody_object(BlenderRNA *brna)
|
static void rna_def_rigidbody_object(BlenderRNA *brna)
|
||||||
|
Reference in New Issue
Block a user