Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/BKE_rigidbody.h1
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c57
-rw-r--r--source/blender/editors/transform/transform.h1
-rw-r--r--source/blender/editors/transform/transform_conversions.c25
4 files changed, 81 insertions, 3 deletions
diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h
index 26a003841c4..607c3026388 100644
--- a/source/blender/blenkernel/BKE_rigidbody.h
+++ b/source/blender/blenkernel/BKE_rigidbody.h
@@ -87,6 +87,7 @@ void BKE_rigidbody_remove_constraint(struct Scene *scene, struct Object *ob);
/* -------------- */
/* Simulation */
+void BKE_rigidbody_aftertrans_update(struct Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle);
void BKE_rigidbody_sync_transforms(struct Scene *scene, struct Object *ob, float ctime);
void BKE_rigidbody_cache_reset(struct RigidBodyWorld *rbw);
void BKE_rigidbody_do_simulation(struct Scene *scene, float ctime);
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 9feb6d43bce..ea127542962 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -953,8 +953,14 @@ static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *o
if (!(rbo->flag & RBO_FLAG_USE_MARGIN) && rbo->shape == RB_SHAPE_CONVEXH)
RB_shape_set_margin(rbo->physics_shape, RBO_GET_MARGIN(rbo) * MIN3(scale[0], scale[1], scale[2]));
+ /* make transformed objects temporarily kinmatic so that they can be moved by the user during simulation */
+ if ((ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ) || rbo->type == RBO_TYPE_PASSIVE) {
+ RB_body_set_kinematic_state(rbo->physics_object, TRUE);
+ RB_body_set_mass(rbo->physics_object, 0.0f);
+ }
+
/* update rigid body location and rotation for kinematic bodies */
- if (rbo->flag & RBO_FLAG_KINEMATIC) {
+ if (rbo->flag & RBO_FLAG_KINEMATIC || (ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) {
RB_body_activate(rbo->physics_object);
RB_body_set_loc_rot(rbo->physics_object, loc, rot);
}
@@ -1095,6 +1101,24 @@ static void rigidbody_update_simulation(Scene *scene, RigidBodyWorld *rbw, int r
}
}
+static void rigidbody_update_simulation_post_step(RigidBodyWorld *rbw)
+{
+ GroupObject *go;
+
+ for (go = rbw->group->gobject.first; go; go = go->next) {
+ Object *ob = go->ob;
+
+ if (ob) {
+ RigidBodyOb *rbo = ob->rigidbody_object;
+ /* reset kinematic state for transformed objects */
+ if (ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ) {
+ RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
+ RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo));
+ }
+ }
+ }
+}
+
/* Sync rigid body and object transformations */
void BKE_rigidbody_sync_transforms(Scene *scene, Object *ob, float ctime)
{
@@ -1105,8 +1129,8 @@ void BKE_rigidbody_sync_transforms(Scene *scene, Object *ob, float ctime)
if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE)
return;
- /* use rigid body transform after cache start frame */
- if (ctime > rbw->pointcache->startframe) {
+ /* use rigid body transform after cache start frame if objects is not being transformed */
+ if (ctime > rbw->pointcache->startframe && !(ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) {
float mat[4][4], size_mat[4][4], size[3];
/* keep original transform when the simulation is muted */
@@ -1129,6 +1153,31 @@ void BKE_rigidbody_sync_transforms(Scene *scene, Object *ob, float ctime)
}
}
+void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle)
+{
+ RigidBodyOb *rbo = ob->rigidbody_object;
+
+ /* return rigid body and objext to their initial states */
+ copy_v3_v3(rbo->pos, ob->loc);
+ copy_v3_v3(ob->loc, loc);
+
+ if (ob->rotmode > 0) {
+ eulO_to_quat(rbo->orn, ob->rot, ob->rotmode);
+ copy_v3_v3(ob->rot, rot);
+ }
+ else if (ob->rotmode == ROT_MODE_AXISANGLE) {
+ axis_angle_to_quat(rbo->orn, ob->rotAxis, ob->rotAngle);
+ copy_v3_v3(ob->rotAxis, rotAxis);
+ ob->rotAngle = rotAngle;
+ }
+ else {
+ copy_qt_qt(rbo->orn, ob->quat);
+ copy_qt_qt(ob->quat, quat);
+ }
+ RB_body_set_loc_rot(rbo->physics_object, rbo->pos, rbo->orn);
+ // RB_TODO update rigid body physics object's loc/rot for dynamic objects here as well (needs to be done outside bullet's update loop)
+}
+
void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw)
{
if (rbw)
@@ -1206,6 +1255,8 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
/* step simulation by the requested timestep, steps per second are adjusted to take time scale into account */
RB_dworld_step_simulation(rbw->physics_world, timestep, INT_MAX, 1.0f / (float)rbw->steps_per_second * min_ff(rbw->time_scale, 1.0f));
+ rigidbody_update_simulation_post_step(rbw);
+
/* write cache for current frame */
BKE_ptcache_validate(cache, (int)ctime);
BKE_ptcache_write(&pid, (unsigned int)ctime);
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index f7256d6d03a..c72c6a83d82 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -137,6 +137,7 @@ typedef struct TransDataExtension {
* namely when a bone is in "NoLocal" or "Hinge" mode)... */
float r_smtx[3][3]; /* Invers of previous one. */
int rotOrder; /* rotation mode, as defined in eRotationModes (DNA_action_types.h) */
+ float oloc[3], orot[3], oquat[4], orotAxis[3], orotAngle; /* Original object transformation used for rigid bodies */
} TransDataExtension;
typedef struct TransData2D {
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 49ea64fac17..39c51ff456e 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -85,6 +85,7 @@
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_report.h"
+#include "BKE_rigidbody.h"
#include "BKE_scene.h"
#include "BKE_sequencer.h"
#include "BKE_tessmesh.h"
@@ -4541,6 +4542,27 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
short constinv;
short skip_invert = 0;
+ if (ob->rigidbody_object) {
+ float rot[3][3], scale[3];
+
+ /* save original object transform */
+ copy_v3_v3(td->ext->oloc, ob->loc);
+
+ if (ob->rotmode > 0) {
+ copy_v3_v3(td->ext->orot, ob->rot);
+ }
+ else if (ob->rotmode == ROT_MODE_AXISANGLE) {
+ td->ext->orotAngle = ob->rotAngle;
+ copy_v3_v3(td->ext->orotAxis, ob->rotAxis);
+ }
+ else {
+ copy_qt_qt(td->ext->oquat, ob->quat);
+ }
+ /* update object's loc/rot to get current rigid body transform */
+ mat4_to_loc_rot_size(ob->loc, rot, scale, ob->obmat);
+ BKE_object_mat3_to_rot(ob, rot, FALSE);
+ }
+
/* axismtx has the real orientation */
copy_m3_m4(td->axismtx, ob->obmat);
normalize_m3(td->axismtx);
@@ -5494,6 +5516,9 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
if (ob->avs.path_bakeflag & MOTIONPATH_BAKE_HAS_PATHS)
recalcObPaths = 1;
}
+ /* restore rigid body transform */
+ if (ob->rigidbody_object && canceled)
+ BKE_rigidbody_aftertrans_update(ob, td->ext->oloc, td->ext->orot, td->ext->oquat, td->ext->orotAxis, td->ext->orotAngle);
}
/* recalculate motion paths for objects (if necessary)