This shared state between original data and depsgraphs was added in
98a0bcd425. Other physics systems also share
the pointcache, but not the simulation state to this extent, which leads
to this kind of crash.
The mutex lock is not a great solution, you don't really want both render and viewport to be filling the same cache in parallel. However
this kind of problem also exists in other physics systems, and solving
that is certainly beyond the scope of 4.4, and probably needs to wait
for a bigger physics rewrite. In general the recommendation is to bake
everything before rendering.
Pull Request: https://projects.blender.org/blender/blender/pulls/134779
200 lines
5.2 KiB
C++
200 lines
5.2 KiB
C++
/* SPDX-FileCopyrightText: 2013 Blender Authors
|
|
*
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
/** \file
|
|
* \ingroup editor_physics
|
|
* \brief Rigid Body world editing operators
|
|
*/
|
|
|
|
#include <cstdlib>
|
|
#include <cstring>
|
|
|
|
#include "DNA_rigidbody_types.h"
|
|
#include "DNA_scene_types.h"
|
|
|
|
#ifdef WITH_BULLET
|
|
# include "RBI_api.h"
|
|
#endif
|
|
|
|
#include "BKE_context.hh"
|
|
#include "BKE_report.hh"
|
|
#include "BKE_rigidbody.h"
|
|
|
|
#include "DEG_depsgraph.hh"
|
|
#include "DEG_depsgraph_build.hh"
|
|
|
|
#include "RNA_access.hh"
|
|
|
|
#include "WM_api.hh"
|
|
#include "WM_types.hh"
|
|
|
|
#include "ED_screen.hh"
|
|
|
|
#include "physics_intern.hh"
|
|
|
|
/* ********************************************** */
|
|
/* API */
|
|
|
|
/* check if there is an active rigid body world */
|
|
static bool ED_rigidbody_world_active_poll(bContext *C)
|
|
{
|
|
Scene *scene = CTX_data_scene(C);
|
|
return (scene && scene->rigidbody_world);
|
|
}
|
|
static bool ED_rigidbody_world_add_poll(bContext *C)
|
|
{
|
|
Scene *scene = CTX_data_scene(C);
|
|
return (scene && scene->rigidbody_world == nullptr);
|
|
}
|
|
|
|
/* ********************************************** */
|
|
/* OPERATORS - Management */
|
|
|
|
/* ********** Add RigidBody World **************** */
|
|
|
|
static int rigidbody_world_add_exec(bContext *C, wmOperator * /*op*/)
|
|
{
|
|
Main *bmain = CTX_data_main(C);
|
|
Scene *scene = CTX_data_scene(C);
|
|
RigidBodyWorld *rbw;
|
|
|
|
rbw = BKE_rigidbody_create_world(scene);
|
|
// BKE_rigidbody_validate_sim_world(scene, rbw, false);
|
|
scene->rigidbody_world = rbw;
|
|
|
|
/* Full rebuild of DEG! */
|
|
DEG_relations_tag_update(bmain);
|
|
DEG_id_tag_update_ex(bmain, &scene->id, ID_RECALC_ANIMATION);
|
|
|
|
return OPERATOR_FINISHED;
|
|
}
|
|
|
|
void RIGIDBODY_OT_world_add(wmOperatorType *ot)
|
|
{
|
|
/* identifiers */
|
|
ot->idname = "RIGIDBODY_OT_world_add";
|
|
ot->name = "Add Rigid Body World";
|
|
ot->description = "Add Rigid Body simulation world to the current scene";
|
|
|
|
/* callbacks */
|
|
ot->exec = rigidbody_world_add_exec;
|
|
ot->poll = ED_rigidbody_world_add_poll;
|
|
|
|
/* flags */
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
|
}
|
|
|
|
/* ********** Remove RigidBody World ************* */
|
|
|
|
static int rigidbody_world_remove_exec(bContext *C, wmOperator *op)
|
|
{
|
|
Main *bmain = CTX_data_main(C);
|
|
Scene *scene = CTX_data_scene(C);
|
|
RigidBodyWorld *rbw = scene->rigidbody_world;
|
|
|
|
/* sanity checks */
|
|
if (ELEM(nullptr, scene, rbw)) {
|
|
BKE_report(op->reports, RPT_ERROR, "No Rigid Body World to remove");
|
|
return OPERATOR_CANCELLED;
|
|
}
|
|
|
|
BKE_rigidbody_free_world(scene);
|
|
|
|
/* Full rebuild of DEG! */
|
|
DEG_relations_tag_update(bmain);
|
|
DEG_id_tag_update_ex(bmain, &scene->id, ID_RECALC_ANIMATION);
|
|
|
|
/* done */
|
|
return OPERATOR_FINISHED;
|
|
}
|
|
|
|
void RIGIDBODY_OT_world_remove(wmOperatorType *ot)
|
|
{
|
|
/* identifiers */
|
|
ot->idname = "RIGIDBODY_OT_world_remove";
|
|
ot->name = "Remove Rigid Body World";
|
|
ot->description = "Remove Rigid Body simulation world from the current scene";
|
|
|
|
/* callbacks */
|
|
ot->exec = rigidbody_world_remove_exec;
|
|
ot->poll = ED_rigidbody_world_active_poll;
|
|
|
|
/* flags */
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
|
}
|
|
|
|
/* ********************************************** */
|
|
/* UTILITY OPERATORS */
|
|
|
|
/* ********** Export RigidBody World ************* */
|
|
|
|
static int rigidbody_world_export_exec(bContext *C, wmOperator *op)
|
|
{
|
|
Scene *scene = CTX_data_scene(C);
|
|
RigidBodyWorld *rbw = scene->rigidbody_world;
|
|
char filepath[FILE_MAX];
|
|
|
|
/* sanity checks */
|
|
if (ELEM(nullptr, scene, rbw)) {
|
|
BKE_report(op->reports, RPT_ERROR, "No Rigid Body World to export");
|
|
return OPERATOR_CANCELLED;
|
|
}
|
|
rbDynamicsWorld *physics_world = BKE_rigidbody_world_physics(rbw);
|
|
if (physics_world == nullptr) {
|
|
BKE_report(
|
|
op->reports, RPT_ERROR, "Rigid Body World has no associated physics data to export");
|
|
return OPERATOR_CANCELLED;
|
|
}
|
|
|
|
RNA_string_get(op->ptr, "filepath", filepath);
|
|
#ifdef WITH_BULLET
|
|
RB_dworld_export(physics_world, filepath);
|
|
#endif
|
|
return OPERATOR_FINISHED;
|
|
}
|
|
|
|
static int rigidbody_world_export_invoke(bContext *C, wmOperator *op, const wmEvent * /*event*/)
|
|
{
|
|
if (!RNA_struct_property_is_set(op->ptr, "relative_path")) {
|
|
RNA_boolean_set(op->ptr, "relative_path", (U.flag & USER_RELPATHS) != 0);
|
|
}
|
|
|
|
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
|
|
return rigidbody_world_export_exec(C, op);
|
|
}
|
|
|
|
/* TODO: use the actual rigidbody world's name + .bullet instead of this temp crap */
|
|
RNA_string_set(op->ptr, "filepath", "rigidbodyworld_export.bullet");
|
|
WM_event_add_fileselect(C, op);
|
|
|
|
return OPERATOR_RUNNING_MODAL;
|
|
}
|
|
|
|
void RIGIDBODY_OT_world_export(wmOperatorType *ot)
|
|
{
|
|
/* identifiers */
|
|
ot->idname = "RIGIDBODY_OT_world_export";
|
|
ot->name = "Export Rigid Body World";
|
|
ot->description =
|
|
"Export Rigid Body world to the simulator's own fileformat (i.e. '.bullet' for Bullet "
|
|
"Physics)";
|
|
|
|
/* callbacks */
|
|
ot->invoke = rigidbody_world_export_invoke;
|
|
ot->exec = rigidbody_world_export_exec;
|
|
ot->poll = ED_rigidbody_world_active_poll;
|
|
|
|
/* flags */
|
|
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
|
|
|
/* properties */
|
|
WM_operator_properties_filesel(ot,
|
|
FILE_TYPE_FOLDER,
|
|
FILE_SPECIAL,
|
|
FILE_SAVE,
|
|
WM_FILESEL_RELPATH,
|
|
FILE_DEFAULTDISPLAY,
|
|
FILE_SORT_DEFAULT);
|
|
}
|