This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/editors/physics/rigidbody_constraint.c
Campbell Barton de13d0a80c doxygen: add newline after \file
While \file doesn't need an argument, it can't have another doxy
command after it.
2019-02-18 08:22:12 +11:00

201 lines
5.6 KiB
C

/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2013 Blender Foundation
* All rights reserved.
*/
/** \file
* \ingroup editor_physics
* \brief Rigid Body constraint editing operators
*/
#include <stdlib.h>
#include <string.h>
#include "DNA_object_types.h"
#include "DNA_rigidbody_types.h"
#include "DNA_scene_types.h"
#include "BKE_collection.h"
#include "BKE_context.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_report.h"
#include "BKE_rigidbody.h"
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
#include "WM_api.h"
#include "WM_types.h"
#include "ED_physics.h"
#include "ED_screen.h"
#include "physics_intern.h"
/* ********************************************** */
/* Helper API's for RigidBody Constraint Editing */
static bool ED_operator_rigidbody_con_active_poll(bContext *C)
{
if (ED_operator_object_active_editable(C)) {
Object *ob = CTX_data_active_object(C);
return (ob && ob->rigidbody_constraint);
}
else
return 0;
}
bool ED_rigidbody_constraint_add(Main *bmain, Scene *scene, Object *ob, int type, ReportList *reports)
{
RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
/* check that object doesn't already have a constraint */
if (ob->rigidbody_constraint) {
BKE_reportf(reports, RPT_INFO, "Object '%s' already has a Rigid Body Constraint", ob->id.name + 2);
return false;
}
/* create constraint group if it doesn't already exits */
if (rbw->constraints == NULL) {
rbw->constraints = BKE_collection_add(bmain, NULL, "RigidBodyConstraints");
id_fake_user_set(&rbw->constraints->id);
}
/* make rigidbody constraint settings */
ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, type);
/* add constraint to rigid body constraint group */
BKE_collection_object_add(bmain, rbw->constraints, ob);
DEG_relations_tag_update(bmain);
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
DEG_id_tag_update(&rbw->constraints->id, ID_RECALC_COPY_ON_WRITE);
return true;
}
void ED_rigidbody_constraint_remove(Main *bmain, Scene *scene, Object *ob)
{
RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
BKE_rigidbody_remove_constraint(scene, ob);
if (rbw) {
BKE_collection_object_remove(bmain, rbw->constraints, ob, false);
DEG_id_tag_update(&rbw->constraints->id, ID_RECALC_COPY_ON_WRITE);
}
DEG_relations_tag_update(bmain);
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
}
/* ********************************************** */
/* Active Object Add/Remove Operators */
/* ************ Add Rigid Body Constraint ************** */
static int rigidbody_con_add_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
Object *ob = OBACT(view_layer);
int type = RNA_enum_get(op->ptr, "type");
bool changed;
/* sanity checks */
if (ELEM(NULL, scene, rbw)) {
BKE_report(op->reports, RPT_ERROR, "No Rigid Body World to add Rigid Body Constraint to");
return OPERATOR_CANCELLED;
}
/* apply to active object */
changed = ED_rigidbody_constraint_add(bmain, scene, ob, type, op->reports);
if (changed) {
/* send updates */
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
/* done */
return OPERATOR_FINISHED;
}
else {
return OPERATOR_CANCELLED;
}
}
void RIGIDBODY_OT_constraint_add(wmOperatorType *ot)
{
/* identifiers */
ot->idname = "RIGIDBODY_OT_constraint_add";
ot->name = "Add Rigid Body Constraint";
ot->description = "Add Rigid Body Constraint to active object";
/* callbacks */
ot->exec = rigidbody_con_add_exec;
ot->poll = ED_operator_object_active_editable;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
ot->prop = RNA_def_enum(ot->srna, "type", rna_enum_rigidbody_constraint_type_items, RBC_TYPE_FIXED, "Rigid Body Constraint Type", "");
}
/* ************ Remove Rigid Body Constraint ************** */
static int rigidbody_con_remove_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
ViewLayer *view_layer = CTX_data_view_layer(C);
Object *ob = OBACT(view_layer);
/* apply to active object */
if (ELEM(NULL, ob, ob->rigidbody_constraint)) {
BKE_report(op->reports, RPT_ERROR, "Object has no Rigid Body Constraint to remove");
return OPERATOR_CANCELLED;
}
else {
ED_rigidbody_constraint_remove(bmain, scene, ob);
}
/* send updates */
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
/* done */
return OPERATOR_FINISHED;
}
void RIGIDBODY_OT_constraint_remove(wmOperatorType *ot)
{
/* identifiers */
ot->idname = "RIGIDBODY_OT_constraint_remove";
ot->name = "Remove Rigid Body Constraint";
ot->description = "Remove Rigid Body Constraint from Object";
/* callbacks */
ot->exec = rigidbody_con_remove_exec;
ot->poll = ED_operator_rigidbody_con_active_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}