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:
Diffstat (limited to 'source/blender/blenkernel/intern/rigidbody.c')
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c93
1 files changed, 83 insertions, 10 deletions
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 7c6dceeb821..6f86c68dc07 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -62,6 +62,7 @@
#include "BKE_library_query.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
+#include "BKE_pointcache.h"
#include "BKE_rigidbody.h"
#include "BKE_scene.h"
@@ -117,6 +118,10 @@ void BKE_rigidbody_free_world(RigidBodyWorld *rbw)
if (rbw->objects)
free(rbw->objects);
+ /* free cache */
+ BKE_ptcache_free_list(&(rbw->ptcaches));
+ rbw->pointcache = NULL;
+
/* free effector weights */
if (rbw->effector_weights)
MEM_freeN(rbw->effector_weights);
@@ -933,6 +938,9 @@ RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene)
rbw->steps_per_second = 60; /* Bullet default (60 Hz) */
rbw->num_solver_iterations = 10; /* 10 is bullet default */
+ rbw->pointcache = BKE_ptcache_add(&(rbw->ptcaches));
+ rbw->pointcache->step = 1;
+
/* return this sim world */
return rbw;
}
@@ -948,6 +956,8 @@ RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw)
if (rbwn->constraints)
id_us_plus(&rbwn->constraints->id);
+ rbwn->pointcache = BKE_ptcache_copy_list(&rbwn->ptcaches, &rbw->ptcaches, false);
+
rbwn->objects = NULL;
rbwn->physics_world = NULL;
rbwn->numbodies = 0;
@@ -977,9 +987,10 @@ void BKE_rigidbody_world_id_loop(RigidBodyWorld *rbw, RigidbodyWorldIDFunc func,
}
/* Add rigid body settings to the specified object */
-RigidBodyOb *BKE_rigidbody_create_object(Scene *UNUSED(scene), Object *ob, short type)
+RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
{
RigidBodyOb *rbo;
+ RigidBodyWorld *rbw = scene->rigidbody_world;
/* sanity checks
* - rigidbody world must exist
@@ -1023,14 +1034,18 @@ RigidBodyOb *BKE_rigidbody_create_object(Scene *UNUSED(scene), Object *ob, short
/* set initial transform */
mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat);
+ /* flag cache as outdated */
+ BKE_rigidbody_cache_reset(rbw);
+
/* return this object */
return rbo;
}
/* Add rigid body constraint to the specified object */
-RigidBodyCon *BKE_rigidbody_create_constraint(Scene *UNUSED(scene), Object *ob, short type)
+RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short type)
{
RigidBodyCon *rbc;
+ RigidBodyWorld *rbw = scene->rigidbody_world;
/* sanity checks
* - rigidbody world must exist
@@ -1086,6 +1101,9 @@ RigidBodyCon *BKE_rigidbody_create_constraint(Scene *UNUSED(scene), Object *ob,
rbc->motor_ang_max_impulse = 1.0f;
rbc->motor_ang_target_velocity = 1.0f;
+ /* flag cache as outdated */
+ BKE_rigidbody_cache_reset(rbw);
+
/* return this object */
return rbc;
}
@@ -1145,6 +1163,9 @@ void BKE_rigidbody_remove_object(Scene *scene, Object *ob)
/* remove object's settings */
BKE_rigidbody_free_object(ob);
+
+ /* flag cache as outdated */
+ BKE_rigidbody_cache_reset(rbw);
}
void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob)
@@ -1158,6 +1179,9 @@ void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob)
}
/* remove object's settings */
BKE_rigidbody_free_constraint(ob);
+
+ /* flag cache as outdated */
+ BKE_rigidbody_cache_reset(rbw);
}
@@ -1251,7 +1275,7 @@ static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *o
ListBase *effectors;
/* get effectors present in the group specified by effector_weights */
- effectors = pdInitEffectors(scene, ob, effector_weights, true);
+ effectors = pdInitEffectors(scene, ob, NULL, effector_weights, true);
if (effectors) {
float eff_force[3] = {0.0f, 0.0f, 0.0f};
float eff_loc[3], eff_vel[3];
@@ -1424,9 +1448,9 @@ static void rigidbody_update_simulation_post_step(RigidBodyWorld *rbw)
}
}
-bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float UNUSED(ctime))
+bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime)
{
- return (rbw && (rbw->flag & RBW_FLAG_MUTED) == 0);
+ return (rbw && (rbw->flag & RBW_FLAG_MUTED) == 0 && ctime > rbw->pointcache->startframe);
}
/* Sync rigid body and object transformations */
@@ -1489,6 +1513,12 @@ void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], flo
// 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)
+ rbw->pointcache->flag |= PTCACHE_OUTDATED;
+}
+
/* ------------------ */
/* Rebuild rigid body world */
@@ -1496,10 +1526,27 @@ void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], flo
void BKE_rigidbody_rebuild_world(Scene *scene, float ctime)
{
RigidBodyWorld *rbw = scene->rigidbody_world;
- int startframe = scene->r.sfra;
+ PointCache *cache;
+ PTCacheID pid;
+ int startframe, endframe;
+
+ BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw);
+ BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
+ cache = rbw->pointcache;
+
+ /* flag cache as outdated if we don't have a world or number of objects in the simulation has changed */
+ if (rbw->physics_world == NULL || rbw->numbodies != BLI_listbase_count(&rbw->group->gobject)) {
+ cache->flag |= PTCACHE_OUTDATED;
+ }
if (ctime == startframe + 1 && rbw->ltime == startframe) {
- rigidbody_update_simulation(scene, rbw, true);
+ if (cache->flag & PTCACHE_OUTDATED) {
+ BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+ rigidbody_update_simulation(scene, rbw, true);
+ BKE_ptcache_validate(cache, (int)ctime);
+ cache->last_exact = 0;
+ cache->flag &= ~PTCACHE_REDO_NEEDED;
+ }
}
}
@@ -1508,7 +1555,13 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
{
float timestep;
RigidBodyWorld *rbw = scene->rigidbody_world;
- int startframe = scene->r.sfra, endframe = scene->r.efra;
+ PointCache *cache;
+ PTCacheID pid;
+ int startframe, endframe;
+
+ BKE_ptcache_id_from_rigidbody(&pid, NULL, rbw);
+ BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
+ cache = rbw->pointcache;
if (ctime <= startframe) {
rbw->ltime = startframe;
@@ -1519,14 +1572,29 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
ctime = endframe;
}
- /* don't try to run the simulation if we don't have a world yet */
- if (rbw->physics_world == NULL)
+ /* don't try to run the simulation if we don't have a world yet but allow reading baked cache */
+ if (rbw->physics_world == NULL && !(cache->flag & PTCACHE_BAKED))
return;
else if (rbw->objects == NULL)
rigidbody_update_ob_array(rbw);
+ /* try to read from cache */
+ // RB_TODO deal with interpolated, old and baked results
+ bool can_simulate = (ctime == rbw->ltime + 1) && !(cache->flag & PTCACHE_BAKED);
+
+ if (BKE_ptcache_read(&pid, ctime, can_simulate)) {
+ BKE_ptcache_validate(cache, (int)ctime);
+ rbw->ltime = ctime;
+ return;
+ }
+
/* advance simulation, we can only step one frame forward */
if (ctime == rbw->ltime + 1) {
+ /* write cache for first frame when on second frame */
+ if (rbw->ltime == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0)) {
+ BKE_ptcache_write(&pid, startframe);
+ }
+
/* update and validate simulation */
rigidbody_update_simulation(scene, rbw, false);
@@ -1537,6 +1605,10 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
rigidbody_update_simulation_post_step(rbw);
+ /* write cache for current frame */
+ BKE_ptcache_validate(cache, (int)ctime);
+ BKE_ptcache_write(&pid, (unsigned int)ctime);
+
rbw->ltime = ctime;
}
}
@@ -1567,6 +1639,7 @@ void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob) {}
void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, 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) {}
bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime) { return false; }
+void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) {}
void BKE_rigidbody_rebuild_world(Scene *scene, float ctime) {}
void BKE_rigidbody_do_simulation(Scene *scene, float ctime) {}