[Bf-blender-cvs] [aa644d7b31b] temp-fracture-modifier-2.8: some more rigidbody refactor and crash fix for fracturing in debug mode
Martin Felke
noreply at git.blender.org
Sun Aug 12 01:23:07 CEST 2018
Commit: aa644d7b31bd9805255c34dd0cd76f68fe3a2048
Author: Martin Felke
Date: Sun Aug 12 01:22:23 2018 +0200
Branches: temp-fracture-modifier-2.8
https://developer.blender.org/rBaa644d7b31bd9805255c34dd0cd76f68fe3a2048
some more rigidbody refactor and crash fix for fracturing in debug mode
===================================================================
M source/blender/blenkernel/BKE_fracture.h
M source/blender/blenkernel/intern/boolean.c
M source/blender/blenkernel/intern/fracture_rigidbody.c
M source/blender/blenkernel/intern/rigidbody.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_fracture.h b/source/blender/blenkernel/BKE_fracture.h
index fac481cd14b..4416824f0a9 100644
--- a/source/blender/blenkernel/BKE_fracture.h
+++ b/source/blender/blenkernel/BKE_fracture.h
@@ -41,6 +41,7 @@ struct Mesh;
struct RigidBodyWorld;
struct FractureModifierData;
+struct ModifierData;
struct Object;
struct Group;
struct MeshIsland;
@@ -197,6 +198,7 @@ struct BMesh* BKE_fracture_mesh_to_bmesh(struct Mesh* me);
struct Mesh* BKE_fracture_bmesh_to_mesh(struct BMesh* bm);
void BKE_update_velocity_layer(struct FractureModifierData *fmd);
+bool BKE_rigidbody_remove_modifier(struct RigidBodyWorld* rbw, struct ModifierData *md, struct Object *ob);
#endif /* BKE_FRACTURE_H */
diff --git a/source/blender/blenkernel/intern/boolean.c b/source/blender/blenkernel/intern/boolean.c
index cf720bdc3d6..56ef6e021fc 100644
--- a/source/blender/blenkernel/intern/boolean.c
+++ b/source/blender/blenkernel/intern/boolean.c
@@ -238,7 +238,7 @@ Mesh *BKE_boolean_operation(Mesh *mesh, struct Object *ob,
bool use_island_connect = true;
/* change for testing */
- if (G.debug & G_DEBUG) {
+ if (G.debug & G_DEBUG && bmd) {
use_separate = (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_Separate) != 0;
use_dissolve = (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_NoDissolve) == 0;
use_island_connect = (bmd->bm_flag & eBooleanModifierBMeshFlag_BMesh_NoConnectRegions) == 0;
diff --git a/source/blender/blenkernel/intern/fracture_rigidbody.c b/source/blender/blenkernel/intern/fracture_rigidbody.c
index e01baaf1125..3c516a0dd3c 100644
--- a/source/blender/blenkernel/intern/fracture_rigidbody.c
+++ b/source/blender/blenkernel/intern/fracture_rigidbody.c
@@ -22,8 +22,10 @@
#include "RBI_api.h"
#endif
+#include "BKE_collection.h"
#include "BKE_fracture.h"
#include "BKE_rigidbody.h"
+#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_mesh_runtime.h"
#include "BKE_object.h"
@@ -2810,6 +2812,280 @@ bool BKE_restoreKinematic(RigidBodyWorld *rbw, bool override_bind)
return did_it;
}
+/* Add rigid body settings to the specified shard */
+RigidBodyOb *BKE_rigidbody_create_shard(Main* bmain, Scene *scene, Object *ob, Object *target, MeshIsland *mi)
+{
+ RigidBodyOb *rbo;
+ RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
+ float centr[3], size[3], mat[4][4];
+ bool added = false;
+
+ /* sanity checks
+ * - rigidbody world must exist
+ * - shard must exist
+ * - cannot add rigid body if it already exists
+ */
+ if (mi == NULL || (mi->rigidbody != NULL))
+ return NULL;
+
+ if (ob->type != OB_MESH) {
+ return NULL;
+ }
+
+ if ((ob->type == OB_MESH) && (((Mesh *)ob->data)->totvert == 0)) {
+ return NULL;
+ }
+
+ /* Add rigid body world and group if they don't exist for convenience */
+ if (rbw == NULL) {
+ rbw = BKE_rigidbody_create_world(scene);
+ BKE_rigidbody_validate_sim_world(scene, rbw, false);
+ scene->rigidbody_world = rbw;
+ }
+ if (rbw->group == NULL) {
+ rbw->group = BKE_collection_add(bmain, NULL, "RigidBodyWorld");
+ }
+
+ /* make rigidbody object settings */
+ if (ob->rigidbody_object == NULL) {
+ ob->rigidbody_object = BKE_rigidbody_create_object(scene, ob, RBO_TYPE_ACTIVE, NULL);
+ }
+ else {
+ ob->rigidbody_object->type = RBO_TYPE_ACTIVE;
+ ob->rigidbody_object->flag |= RBO_FLAG_NEEDS_VALIDATE;
+ }
+
+ if (!BKE_collection_has_object(rbw->group, ob)) {
+ BKE_collection_object_add(bmain, rbw->group, ob);
+ }
+
+ /* since we are always member of an object, dupe its settings,
+ * create new settings data, and link it up */
+ if (target && target->rigidbody_object)
+ {
+ rbo = BKE_rigidbody_copy_object(target, 0);
+ mat4_to_loc_quat(rbo->pos, rbo->orn, target->obmat);
+ zero_v3(rbo->lin_vel);
+ zero_v3(rbo->ang_vel);
+ }
+ else
+ {
+ /* regular FM case */
+ rbo = BKE_rigidbody_copy_object(ob, 0);
+ rbo->type = mi->ground_weight > 0.01f ? RBO_TYPE_PASSIVE : RBO_TYPE_ACTIVE;
+
+ /* set initial transform */
+ mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat);
+ mat4_to_size(size, ob->obmat);
+
+ //add initial "offset" (centroid), maybe subtract ob->obmat ?? (not sure)
+ copy_v3_v3(centr, mi->centroid);
+ mul_v3_v3(centr, size);
+ mul_qt_v3(rbo->orn, centr);
+ add_v3_v3(rbo->pos, centr);
+ zero_v3(rbo->lin_vel);
+ zero_v3(rbo->ang_vel);
+ }
+
+ /* return this object */
+ return rbo;
+}
+
+/* Add rigid body constraint to the specified object */
+RigidBodyShardCon *BKE_rigidbody_create_shard_constraint(Scene *scene, short type, bool reset)
+{
+ RigidBodyShardCon *rbc;
+ RigidBodyWorld *rbw = scene->rigidbody_world;
+
+ /* sanity checks
+ * - rigidbody world must exist
+ * - object must exist
+ * - cannot add constraint if it already exists
+ */
+
+ /* create new settings data, and link it up */
+ rbc = MEM_callocN(sizeof(RigidBodyShardCon), "RigidBodyShardCon");
+
+ /* set default settings */
+ rbc->type = type;
+
+ rbc->mi1 = NULL;
+ rbc->mi2 = NULL;
+
+ rbc->flag |= RBC_FLAG_ENABLED;
+ rbc->flag &= ~RBC_FLAG_DISABLE_COLLISIONS;
+ rbc->flag |= RBC_FLAG_USE_BREAKING;
+
+ rbc->breaking_threshold = 10.0f; /* no good default here, just use 10 for now */
+ rbc->num_solver_iterations = 10; /* 10 is Bullet default */
+
+ rbc->limit_lin_x_lower = -1.0f;
+ rbc->limit_lin_x_upper = 1.0f;
+ rbc->limit_lin_y_lower = -1.0f;
+ rbc->limit_lin_y_upper = 1.0f;
+ rbc->limit_lin_z_lower = -1.0f;
+ rbc->limit_lin_z_upper = 1.0f;
+ rbc->limit_ang_x_lower = -M_PI_4;
+ rbc->limit_ang_x_upper = M_PI_4;
+ rbc->limit_ang_y_lower = -M_PI_4;
+ rbc->limit_ang_y_upper = M_PI_4;
+ rbc->limit_ang_z_lower = -M_PI_4;
+ rbc->limit_ang_z_upper = M_PI_4;
+
+ rbc->spring_damping_x = 0.5f;
+ rbc->spring_damping_y = 0.5f;
+ rbc->spring_damping_z = 0.5f;
+ rbc->spring_damping_ang_x = 0.5f;
+ rbc->spring_damping_ang_y = 0.5f;
+ rbc->spring_damping_ang_z = 0.5f;
+ rbc->spring_stiffness_x = 10.0f;
+ rbc->spring_stiffness_y = 10.0f;
+ rbc->spring_stiffness_z = 10.0f;
+ rbc->spring_stiffness_ang_x = 10.0f;
+ rbc->spring_stiffness_ang_y = 10.0f;
+ rbc->spring_stiffness_ang_z = 10.0f;
+
+ rbc->motor_lin_max_impulse = 1.0f;
+ rbc->motor_lin_target_velocity = 1.0f;
+ rbc->motor_ang_max_impulse = 1.0f;
+ rbc->motor_ang_target_velocity = 1.0f;
+ strcpy(rbc->name, "");
+ zero_v3(rbc->pos);
+ unit_qt(rbc->orn);
+
+ /* flag cache as outdated */
+ if (reset)
+ BKE_rigidbody_cache_reset(rbw);
+
+ /* return this object */
+ return rbc;
+}
+
+void BKE_rigidbody_remove_shard_con(Scene *scene, RigidBodyShardCon *con)
+{
+ RigidBodyWorld *rbw = scene->rigidbody_world;
+ if (rbw && rbw->shared->physics_world && con && con->physics_constraint) {
+ RB_dworld_remove_constraint(rbw->shared->physics_world, con->physics_constraint);
+ RB_constraint_delete(con->physics_constraint);
+ con->physics_constraint = NULL;
+ }
+}
+
+void BKE_rigidbody_remove_shard(Scene *scene, MeshIsland *mi)
+{
+ RigidBodyWorld *rbw = scene->rigidbody_world;
+ int i = 0;
+
+ /* rbw can be NULL directly after linking / appending objects without their original scenes
+ * if an attempt to refracture is done then, this would crash here with null pointer access */
+ if (mi->rigidbody != NULL && rbw != NULL) {
+
+ RigidBodyShardCon *con;
+
+ for (i = 0; i < mi->participating_constraint_count; i++) {
+ con = mi->participating_constraints[i];
+ BKE_rigidbody_remove_shard_con(scene, con);
+ }
+
+ if (rbw->shared->physics_world && mi->rigidbody && mi->rigidbody->shared->physics_object)
+ RB_dworld_remove_body(rbw->shared->physics_world, mi->rigidbody->shared->physics_object);
+
+ if (mi->rigidbody->shared->physics_object) {
+ RB_body_delete(mi->rigidbody->shared->physics_object);
+ mi->rigidbody->shared->physics_object = NULL;
+ }
+
+ if (mi->rigidbody->shared->physics_shape) {
+ RB_shape_delete(mi->rigidbody->shared->physics_shape);
+ mi->rigidbody->shared->physics_shape = NULL;
+ }
+
+ /* this SHOULD be the correct global index, mark with NULL as 'dirty' BEFORE deleting */
+ /* need to check whether we didnt create the rigidbody world manually already, prior to fracture, in this
+ * case cache_index_map might be not initialized ! checking numbodies here, they should be 0 in a fresh
+ * rigidbody world */
+#if 0
+ if ((rbw->cache_index_map != NULL) && (rbw->numbodies > 0) && mi->linear_index < rbw->numbodies) {
+ //mi->rigidbody = NULL;
+ rbw->cache_index_map[mi->linear_index] = NULL;
+ }
+#endif
+
+ if (rbw->shared->cache_index_map != NULL) {
+ MEM_freeN(rbw->shared->cache_index_map);
+ rbw->shared->cache_index_map = NULL;
+ }
+
+ //BKE_rigidbody_update_ob_array(rbw);
+ }
+}
+
+bool BKE_rigidbody_remove_modifier(RigidBodyWorld* rbw, ModifierData *md, Object *ob)
+{
+ RigidBodyShardCon *con;
+ MeshIsland *mi;
+ FractureModifierData *fmd;
+ bool modFound = false;
+
+ if (md->type == eModifierType_Fracture)
+ {
+ fmd = (FractureModifierData *)md;
+ modFound = true;
+ CollectionObject *go;
+
+ for (con = fmd->shared->meshConstraints.first; con; con = con->next) {
+ if (rbw && rbw->shared->physics_world && con->physics_constraint) {
+ RB_dworld_remove_constraint(rbw->shared->physics_world, con->physics_constraint);
+ RB_constraint_delete(con->physics_constraint);
+ con->physics_constraint = NULL;
+ }
+ }
+
+ /*if we are part of a connected object, delete the parent's constraints here too*/
+ for (go = rbw->group->gobject.first; go; go = go->next)
+ {
+ FractureModifierData *fmdi = (FractureModifierData*)modifiers_findByType(go->ob, eModifierType_Fracture);
+ if (fmdi && ob != go->ob)
+ {
+ for (con = fmdi->shared->meshConstraints.first; con; con = con->next) {
+ if (rbw && rbw->shared->physics_world && con->physics_constraint) {
+ RB_dworld_remove_constraint(rbw->shared->physics_world, con->physics_constraint);
+ RB_constraint_delete(con->physics_constraint);
+ con->physics_constraint = NULL;
+ }
+ }
+ }
+ }
+
+
+ for (mi = fmd->shared->meshIslands.first; mi; mi = mi->next) {
+ if (mi->rigidbody != NULL) {
+ if (rbw->shared->physics_world && mi->rigidbody && mi->rigidbody->shared->physics_object)
+ RB_dworld_remove_body(rbw->shar
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list