2013-01-23 05:56:22 +00:00
|
|
|
/*
|
|
|
|
* ***** BEGIN GPL LICENSE BLOCK *****
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
* The Original Code is: all of this file.
|
|
|
|
*
|
|
|
|
* Contributor(s): Joshua Leung, Sergej Reich
|
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
|
|
|
/** \file rigidbody.c
|
|
|
|
* \ingroup blenkernel
|
|
|
|
* \brief Blender-side interface and methods for dealing with Rigid Body simulations
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <float.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include <limits.h>
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
|
|
|
#include "BLI_math.h"
|
|
|
|
|
2013-01-23 07:26:39 +00:00
|
|
|
#ifdef WITH_BULLET
|
|
|
|
# include "RBI_api.h"
|
|
|
|
#endif
|
2013-01-23 05:56:22 +00:00
|
|
|
|
2016-12-12 15:05:19 +01:00
|
|
|
#include "DNA_ID.h"
|
2013-01-23 05:56:22 +00:00
|
|
|
#include "DNA_group_types.h"
|
2018-06-15 10:45:08 +02:00
|
|
|
#include "DNA_mesh_types.h"
|
2013-01-23 05:56:22 +00:00
|
|
|
#include "DNA_meshdata_types.h"
|
|
|
|
#include "DNA_object_types.h"
|
2018-02-07 11:14:08 +11:00
|
|
|
#include "DNA_object_force_types.h"
|
2013-01-23 05:56:22 +00:00
|
|
|
#include "DNA_rigidbody_types.h"
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
#include "BKE_collection.h"
|
2013-01-23 05:56:22 +00:00
|
|
|
#include "BKE_effect.h"
|
2013-04-24 23:09:25 +00:00
|
|
|
#include "BKE_global.h"
|
2018-06-11 11:40:26 +02:00
|
|
|
#include "BKE_layer.h"
|
2013-04-24 23:09:25 +00:00
|
|
|
#include "BKE_library.h"
|
2015-10-08 14:59:24 +02:00
|
|
|
#include "BKE_library_query.h"
|
2014-07-11 12:06:13 +02:00
|
|
|
#include "BKE_mesh.h"
|
2018-06-15 10:45:08 +02:00
|
|
|
#include "BKE_mesh_runtime.h"
|
2013-04-24 23:09:25 +00:00
|
|
|
#include "BKE_object.h"
|
2016-12-28 17:30:58 +01:00
|
|
|
#include "BKE_pointcache.h"
|
2013-01-23 05:56:22 +00:00
|
|
|
#include "BKE_rigidbody.h"
|
2015-05-12 13:57:11 +05:00
|
|
|
#include "BKE_scene.h"
|
2013-01-23 05:56:22 +00:00
|
|
|
|
2018-03-16 11:14:38 +01:00
|
|
|
#include "DEG_depsgraph.h"
|
2018-05-18 18:04:27 +02:00
|
|
|
#include "DEG_depsgraph_query.h"
|
2018-03-16 11:14:38 +01:00
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
/* ************************************** */
|
|
|
|
/* Memory Management */
|
|
|
|
|
|
|
|
/* Freeing Methods --------------------- */
|
|
|
|
|
2016-11-08 11:54:04 +01:00
|
|
|
#ifndef WITH_BULLET
|
|
|
|
|
|
|
|
static void RB_dworld_remove_constraint(void *UNUSED(world), void *UNUSED(con)) {}
|
|
|
|
static void RB_dworld_remove_body(void *UNUSED(world), void *UNUSED(body)) {}
|
|
|
|
static void RB_dworld_delete(void *UNUSED(world)) {}
|
|
|
|
static void RB_body_delete(void *UNUSED(body)) {}
|
|
|
|
static void RB_shape_delete(void *UNUSED(shape)) {}
|
|
|
|
static void RB_constraint_delete(void *UNUSED(con)) {}
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
/* Free rigidbody world */
|
|
|
|
void BKE_rigidbody_free_world(RigidBodyWorld *rbw)
|
|
|
|
{
|
|
|
|
/* sanity check */
|
|
|
|
if (!rbw)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (rbw->physics_world) {
|
|
|
|
/* free physics references, we assume that all physics objects in will have been added to the world */
|
2013-01-23 05:56:56 +00:00
|
|
|
if (rbw->constraints) {
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, object)
|
2017-12-01 11:24:21 -02:00
|
|
|
{
|
|
|
|
if (object->rigidbody_constraint) {
|
|
|
|
RigidBodyCon *rbc = object->rigidbody_constraint;
|
|
|
|
if (rbc->physics_constraint) {
|
2013-01-23 05:56:56 +00:00
|
|
|
RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
|
2017-12-01 11:24:21 -02:00
|
|
|
}
|
2013-01-23 05:56:56 +00:00
|
|
|
}
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
|
2013-01-23 05:56:56 +00:00
|
|
|
}
|
2013-01-23 05:56:22 +00:00
|
|
|
|
2017-12-01 11:24:21 -02:00
|
|
|
if (rbw->group) {
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object)
|
2017-12-01 11:24:21 -02:00
|
|
|
{
|
|
|
|
if (object->rigidbody_object) {
|
|
|
|
RigidBodyOb *rbo = object->rigidbody_object;
|
|
|
|
if (rbo->physics_object) {
|
2013-01-23 05:56:22 +00:00
|
|
|
RB_dworld_remove_body(rbw->physics_world, rbo->physics_object);
|
2017-12-01 11:24:21 -02:00
|
|
|
}
|
2013-01-23 05:56:22 +00:00
|
|
|
}
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
|
2013-01-23 05:56:22 +00:00
|
|
|
}
|
|
|
|
/* free dynamics world */
|
|
|
|
RB_dworld_delete(rbw->physics_world);
|
|
|
|
}
|
|
|
|
if (rbw->objects)
|
|
|
|
free(rbw->objects);
|
|
|
|
|
2016-12-28 17:30:58 +01:00
|
|
|
/* free cache */
|
|
|
|
BKE_ptcache_free_list(&(rbw->ptcaches));
|
|
|
|
rbw->pointcache = NULL;
|
|
|
|
|
2013-01-23 05:56:27 +00:00
|
|
|
/* free effector weights */
|
|
|
|
if (rbw->effector_weights)
|
|
|
|
MEM_freeN(rbw->effector_weights);
|
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
/* free rigidbody world itself */
|
|
|
|
MEM_freeN(rbw);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Free RigidBody settings and sim instances */
|
|
|
|
void BKE_rigidbody_free_object(Object *ob)
|
|
|
|
{
|
|
|
|
RigidBodyOb *rbo = (ob) ? ob->rigidbody_object : NULL;
|
|
|
|
|
|
|
|
/* sanity check */
|
|
|
|
if (rbo == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* free physics references */
|
|
|
|
if (rbo->physics_object) {
|
|
|
|
RB_body_delete(rbo->physics_object);
|
|
|
|
rbo->physics_object = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rbo->physics_shape) {
|
|
|
|
RB_shape_delete(rbo->physics_shape);
|
|
|
|
rbo->physics_shape = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* free data itself */
|
|
|
|
MEM_freeN(rbo);
|
|
|
|
ob->rigidbody_object = NULL;
|
|
|
|
}
|
|
|
|
|
2013-01-23 05:56:56 +00:00
|
|
|
/* Free RigidBody constraint and sim instance */
|
|
|
|
void BKE_rigidbody_free_constraint(Object *ob)
|
|
|
|
{
|
|
|
|
RigidBodyCon *rbc = (ob) ? ob->rigidbody_constraint : NULL;
|
|
|
|
|
|
|
|
/* sanity check */
|
|
|
|
if (rbc == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* free physics reference */
|
|
|
|
if (rbc->physics_constraint) {
|
|
|
|
RB_constraint_delete(rbc->physics_constraint);
|
|
|
|
rbc->physics_constraint = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* free data itself */
|
|
|
|
MEM_freeN(rbc);
|
|
|
|
ob->rigidbody_constraint = NULL;
|
|
|
|
}
|
|
|
|
|
2016-11-08 11:54:04 +01:00
|
|
|
#ifdef WITH_BULLET
|
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
/* Copying Methods --------------------- */
|
|
|
|
|
|
|
|
/* These just copy the data, clearing out references to physics objects.
|
|
|
|
* Anything that uses them MUST verify that the copied object will
|
|
|
|
* be added to relevant groups later...
|
|
|
|
*/
|
|
|
|
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob, const int UNUSED(flag))
|
2013-01-23 05:56:22 +00:00
|
|
|
{
|
|
|
|
RigidBodyOb *rboN = NULL;
|
|
|
|
|
|
|
|
if (ob->rigidbody_object) {
|
|
|
|
/* just duplicate the whole struct first (to catch all the settings) */
|
|
|
|
rboN = MEM_dupallocN(ob->rigidbody_object);
|
|
|
|
|
|
|
|
/* tag object as needing to be verified */
|
|
|
|
rboN->flag |= RBO_FLAG_NEEDS_VALIDATE;
|
|
|
|
|
|
|
|
/* clear out all the fields which need to be revalidated later */
|
|
|
|
rboN->physics_object = NULL;
|
|
|
|
rboN->physics_shape = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return new copy of settings */
|
|
|
|
return rboN;
|
|
|
|
}
|
|
|
|
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob, const int UNUSED(flag))
|
2013-01-23 05:56:56 +00:00
|
|
|
{
|
|
|
|
RigidBodyCon *rbcN = NULL;
|
|
|
|
|
|
|
|
if (ob->rigidbody_constraint) {
|
|
|
|
/* just duplicate the whole struct first (to catch all the settings) */
|
|
|
|
rbcN = MEM_dupallocN(ob->rigidbody_constraint);
|
|
|
|
|
|
|
|
/* tag object as needing to be verified */
|
|
|
|
rbcN->flag |= RBC_FLAG_NEEDS_VALIDATE;
|
|
|
|
|
|
|
|
/* clear out all the fields which need to be revalidated later */
|
|
|
|
rbcN->physics_constraint = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return new copy of settings */
|
|
|
|
return rbcN;
|
|
|
|
}
|
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
/* ************************************** */
|
|
|
|
/* Setup Utilities - Validate Sim Instances */
|
|
|
|
|
2013-12-26 17:02:28 +01:00
|
|
|
/* get the appropriate DerivedMesh based on rigid body mesh source */
|
2018-06-15 10:45:08 +02:00
|
|
|
static Mesh *rigidbody_get_mesh(Object *ob)
|
2013-12-26 17:02:28 +01:00
|
|
|
{
|
2018-06-25 12:02:57 +02:00
|
|
|
switch (ob->rigidbody_object->mesh_source) {
|
2018-06-25 11:24:55 +02:00
|
|
|
case RBO_MESH_DEFORM:
|
|
|
|
return ob->runtime.mesh_deform_eval;
|
|
|
|
case RBO_MESH_FINAL:
|
|
|
|
return ob->runtime.mesh_eval;
|
|
|
|
case RBO_MESH_BASE:
|
|
|
|
/* This mesh may be used for computing looptris, which should be done
|
|
|
|
* on the original; otherwise every time the CoW is recreated it will
|
|
|
|
* have to be recomputed. */
|
|
|
|
BLI_assert(ob->rigidbody_object->mesh_source == RBO_MESH_BASE);
|
|
|
|
return DEG_get_original_object(ob)->data;
|
2013-12-26 17:02:28 +01:00
|
|
|
}
|
2018-06-25 11:24:55 +02:00
|
|
|
|
|
|
|
/* Just return something sensible so that at least Blender won't crash. */
|
|
|
|
BLI_assert(!"Unknown mesh source");
|
|
|
|
return ob->runtime.mesh_eval;
|
2013-12-26 17:02:28 +01:00
|
|
|
}
|
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
/* create collision shape of mesh - convex hull */
|
|
|
|
static rbCollisionShape *rigidbody_get_shape_convexhull_from_mesh(Object *ob, float margin, bool *can_embed)
|
|
|
|
{
|
|
|
|
rbCollisionShape *shape = NULL;
|
2018-06-15 10:45:08 +02:00
|
|
|
Mesh *mesh = NULL;
|
2013-12-26 17:02:28 +01:00
|
|
|
MVert *mvert = NULL;
|
|
|
|
int totvert = 0;
|
2013-01-23 05:56:22 +00:00
|
|
|
|
|
|
|
if (ob->type == OB_MESH && ob->data) {
|
2018-06-15 10:45:08 +02:00
|
|
|
mesh = rigidbody_get_mesh(ob);
|
|
|
|
mvert = (mesh) ? mesh->mvert : NULL;
|
|
|
|
totvert = (mesh) ? mesh->totvert : 0;
|
2013-01-23 05:56:22 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
printf("ERROR: cannot make Convex Hull collision shape for non-Mesh object\n");
|
|
|
|
}
|
|
|
|
|
2013-12-26 17:02:28 +01:00
|
|
|
if (totvert) {
|
|
|
|
shape = RB_shape_new_convex_hull((float *)mvert, sizeof(MVert), totvert, margin, can_embed);
|
2013-01-23 05:56:22 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
printf("ERROR: no vertices to define Convex Hull collision shape with\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
return shape;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create collision shape of mesh - triangulated mesh
|
|
|
|
* returns NULL if creation fails.
|
|
|
|
*/
|
|
|
|
static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
|
|
|
|
{
|
|
|
|
rbCollisionShape *shape = NULL;
|
|
|
|
|
|
|
|
if (ob->type == OB_MESH) {
|
2018-06-15 10:45:08 +02:00
|
|
|
Mesh *mesh = NULL;
|
2013-01-23 05:56:22 +00:00
|
|
|
MVert *mvert;
|
2015-07-21 12:01:03 +10:00
|
|
|
const MLoopTri *looptri;
|
2013-01-23 05:56:22 +00:00
|
|
|
int totvert;
|
2015-07-21 12:01:03 +10:00
|
|
|
int tottri;
|
|
|
|
const MLoop *mloop;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2018-06-15 10:45:08 +02:00
|
|
|
mesh = rigidbody_get_mesh(ob);
|
2013-12-26 17:02:28 +01:00
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
/* ensure mesh validity, then grab data */
|
2018-06-15 10:45:08 +02:00
|
|
|
if (mesh == NULL)
|
2013-12-26 17:02:28 +01:00
|
|
|
return NULL;
|
|
|
|
|
2018-06-15 10:45:08 +02:00
|
|
|
mvert = mesh->mvert;
|
|
|
|
totvert = mesh->totvert;
|
|
|
|
looptri = BKE_mesh_runtime_looptri_ensure(mesh);
|
|
|
|
tottri = mesh->runtime.looptris.len;
|
|
|
|
mloop = mesh->mloop;
|
2013-01-23 05:56:22 +00:00
|
|
|
|
|
|
|
/* sanity checking - potential case when no data will be present */
|
2015-07-19 19:10:41 +02:00
|
|
|
if ((totvert == 0) || (tottri == 0)) {
|
2013-01-23 05:56:22 +00:00
|
|
|
printf("WARNING: no geometry data converted for Mesh Collision Shape (ob = %s)\n", ob->id.name + 2);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rbMeshData *mdata;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
/* init mesh data for collision shape */
|
2015-07-19 19:10:41 +02:00
|
|
|
mdata = RB_trimesh_data_new(tottri, totvert);
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2013-12-30 10:53:09 +11:00
|
|
|
RB_trimesh_add_vertices(mdata, (float *)mvert, totvert, sizeof(MVert));
|
2013-01-23 05:56:22 +00:00
|
|
|
|
|
|
|
/* loop over all faces, adding them as triangles to the collision shape
|
|
|
|
* (so for some faces, more than triangle will get added)
|
|
|
|
*/
|
2015-07-20 17:07:40 +10:00
|
|
|
if (mvert && looptri) {
|
2015-07-19 19:10:41 +02:00
|
|
|
for (i = 0; i < tottri; i++) {
|
|
|
|
/* add first triangle - verts 1,2,3 */
|
2015-07-20 17:07:40 +10:00
|
|
|
const MLoopTri *lt = &looptri[i];
|
|
|
|
int vtri[3];
|
2015-07-19 19:10:41 +02:00
|
|
|
|
2015-07-20 17:07:40 +10:00
|
|
|
vtri[0] = mloop[lt->tri[0]].v;
|
|
|
|
vtri[1] = mloop[lt->tri[1]].v;
|
|
|
|
vtri[2] = mloop[lt->tri[2]].v;
|
2015-07-19 19:10:41 +02:00
|
|
|
|
2015-07-20 17:07:40 +10:00
|
|
|
RB_trimesh_add_triangle_indices(mdata, i, UNPACK3(vtri));
|
2013-01-23 05:56:22 +00:00
|
|
|
}
|
|
|
|
}
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2013-12-26 17:49:08 +01:00
|
|
|
RB_trimesh_finish(mdata);
|
2013-01-23 05:56:22 +00:00
|
|
|
|
|
|
|
/* construct collision shape
|
|
|
|
*
|
|
|
|
* These have been chosen to get better speed/accuracy tradeoffs with regards
|
|
|
|
* to limitations of each:
|
|
|
|
* - BVH-Triangle Mesh: for passive objects only. Despite having greater
|
|
|
|
* speed/accuracy, they cannot be used for moving objects.
|
|
|
|
* - GImpact Mesh: for active objects. These are slower and less stable,
|
|
|
|
* but are more flexible for general usage.
|
|
|
|
*/
|
|
|
|
if (ob->rigidbody_object->type == RBO_TYPE_PASSIVE) {
|
|
|
|
shape = RB_shape_new_trimesh(mdata);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
shape = RB_shape_new_gimpact_mesh(mdata);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
printf("ERROR: cannot make Triangular Mesh collision shape for non-Mesh object\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
return shape;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Create new physics sim collision shape for object and store it,
|
|
|
|
* or remove the existing one first and replace...
|
|
|
|
*/
|
2013-12-26 21:30:53 +01:00
|
|
|
static void rigidbody_validate_sim_shape(Object *ob, bool rebuild)
|
2013-01-23 05:56:22 +00:00
|
|
|
{
|
|
|
|
RigidBodyOb *rbo = ob->rigidbody_object;
|
|
|
|
rbCollisionShape *new_shape = NULL;
|
|
|
|
BoundBox *bb = NULL;
|
|
|
|
float size[3] = {1.0f, 1.0f, 1.0f};
|
|
|
|
float radius = 1.0f;
|
|
|
|
float height = 1.0f;
|
|
|
|
float capsule_height;
|
|
|
|
float hull_margin = 0.0f;
|
|
|
|
bool can_embed = true;
|
2013-02-25 15:51:53 +00:00
|
|
|
bool has_volume;
|
2013-01-23 05:56:22 +00:00
|
|
|
|
|
|
|
/* sanity check */
|
|
|
|
if (rbo == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* don't create a new shape if we already have one and don't want to rebuild it */
|
|
|
|
if (rbo->physics_shape && !rebuild)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* if automatically determining dimensions, use the Object's boundbox
|
|
|
|
* - assume that all quadrics are standing upright on local z-axis
|
|
|
|
* - assume even distribution of mass around the Object's pivot
|
2013-02-06 14:02:19 +00:00
|
|
|
* (i.e. Object pivot is centralized in boundbox)
|
2013-01-23 05:56:22 +00:00
|
|
|
*/
|
|
|
|
// XXX: all dimensions are auto-determined now... later can add stored settings for this
|
|
|
|
/* get object dimensions without scaling */
|
|
|
|
bb = BKE_object_boundbox_get(ob);
|
|
|
|
if (bb) {
|
|
|
|
size[0] = (bb->vec[4][0] - bb->vec[0][0]);
|
|
|
|
size[1] = (bb->vec[2][1] - bb->vec[0][1]);
|
|
|
|
size[2] = (bb->vec[1][2] - bb->vec[0][2]);
|
|
|
|
}
|
|
|
|
mul_v3_fl(size, 0.5f);
|
|
|
|
|
2014-07-20 01:30:29 +10:00
|
|
|
if (ELEM(rbo->shape, RB_SHAPE_CAPSULE, RB_SHAPE_CYLINDER, RB_SHAPE_CONE)) {
|
2013-01-23 05:56:22 +00:00
|
|
|
/* take radius as largest x/y dimension, and height as z-dimension */
|
|
|
|
radius = MAX2(size[0], size[1]);
|
|
|
|
height = size[2];
|
|
|
|
}
|
|
|
|
else if (rbo->shape == RB_SHAPE_SPHERE) {
|
2014-10-29 14:11:19 +01:00
|
|
|
/* take radius to the largest dimension to try and encompass everything */
|
2013-01-23 05:56:22 +00:00
|
|
|
radius = MAX3(size[0], size[1], size[2]);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create new shape */
|
|
|
|
switch (rbo->shape) {
|
|
|
|
case RB_SHAPE_BOX:
|
|
|
|
new_shape = RB_shape_new_box(size[0], size[1], size[2]);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RB_SHAPE_SPHERE:
|
|
|
|
new_shape = RB_shape_new_sphere(radius);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RB_SHAPE_CAPSULE:
|
|
|
|
capsule_height = (height - radius) * 2.0f;
|
|
|
|
new_shape = RB_shape_new_capsule(radius, (capsule_height > 0.0f) ? capsule_height : 0.0f);
|
|
|
|
break;
|
|
|
|
case RB_SHAPE_CYLINDER:
|
|
|
|
new_shape = RB_shape_new_cylinder(radius, height);
|
|
|
|
break;
|
|
|
|
case RB_SHAPE_CONE:
|
|
|
|
new_shape = RB_shape_new_cone(radius, height * 2.0f);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RB_SHAPE_CONVEXH:
|
|
|
|
/* try to emged collision margin */
|
2013-02-25 15:51:53 +00:00
|
|
|
has_volume = (MIN3(size[0], size[1], size[2]) > 0.0f);
|
|
|
|
|
|
|
|
if (!(rbo->flag & RBO_FLAG_USE_MARGIN) && has_volume)
|
2013-01-23 05:56:22 +00:00
|
|
|
hull_margin = 0.04f;
|
|
|
|
new_shape = rigidbody_get_shape_convexhull_from_mesh(ob, hull_margin, &can_embed);
|
|
|
|
if (!(rbo->flag & RBO_FLAG_USE_MARGIN))
|
2013-02-25 15:51:53 +00:00
|
|
|
rbo->margin = (can_embed && has_volume) ? 0.04f : 0.0f; /* RB_TODO ideally we shouldn't directly change the margin here */
|
2013-01-23 05:56:22 +00:00
|
|
|
break;
|
|
|
|
case RB_SHAPE_TRIMESH:
|
|
|
|
new_shape = rigidbody_get_shape_trimesh_from_mesh(ob);
|
|
|
|
break;
|
|
|
|
}
|
2015-02-10 12:49:34 +05:00
|
|
|
/* use box shape if we can't fall back to old shape */
|
|
|
|
if (new_shape == NULL && rbo->physics_shape == NULL) {
|
|
|
|
new_shape = RB_shape_new_box(size[0], size[1], size[2]);
|
|
|
|
}
|
2013-01-23 05:56:22 +00:00
|
|
|
/* assign new collision shape if creation was successful */
|
|
|
|
if (new_shape) {
|
|
|
|
if (rbo->physics_shape)
|
|
|
|
RB_shape_delete(rbo->physics_shape);
|
|
|
|
rbo->physics_shape = new_shape;
|
|
|
|
RB_shape_set_margin(rbo->physics_shape, RBO_GET_MARGIN(rbo));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------- */
|
|
|
|
|
2014-07-11 12:06:13 +02:00
|
|
|
/* helper function to calculate volume of rigidbody object */
|
|
|
|
// TODO: allow a parameter to specify method used to calculate this?
|
|
|
|
void BKE_rigidbody_calc_volume(Object *ob, float *r_vol)
|
|
|
|
{
|
|
|
|
RigidBodyOb *rbo = ob->rigidbody_object;
|
|
|
|
|
|
|
|
float size[3] = {1.0f, 1.0f, 1.0f};
|
|
|
|
float radius = 1.0f;
|
|
|
|
float height = 1.0f;
|
|
|
|
|
|
|
|
float volume = 0.0f;
|
|
|
|
|
|
|
|
/* if automatically determining dimensions, use the Object's boundbox
|
|
|
|
* - assume that all quadrics are standing upright on local z-axis
|
|
|
|
* - assume even distribution of mass around the Object's pivot
|
2014-07-18 11:54:09 +10:00
|
|
|
* (i.e. Object pivot is centralized in boundbox)
|
2014-07-11 12:06:13 +02:00
|
|
|
* - boundbox gives full width
|
|
|
|
*/
|
|
|
|
// XXX: all dimensions are auto-determined now... later can add stored settings for this
|
|
|
|
BKE_object_dimensions_get(ob, size);
|
|
|
|
|
2014-07-20 01:30:29 +10:00
|
|
|
if (ELEM(rbo->shape, RB_SHAPE_CAPSULE, RB_SHAPE_CYLINDER, RB_SHAPE_CONE)) {
|
2014-07-11 12:06:13 +02:00
|
|
|
/* take radius as largest x/y dimension, and height as z-dimension */
|
|
|
|
radius = MAX2(size[0], size[1]) * 0.5f;
|
|
|
|
height = size[2];
|
|
|
|
}
|
|
|
|
else if (rbo->shape == RB_SHAPE_SPHERE) {
|
2014-10-29 14:11:19 +01:00
|
|
|
/* take radius to the largest dimension to try and encompass everything */
|
2014-07-11 12:06:13 +02:00
|
|
|
radius = max_fff(size[0], size[1], size[2]) * 0.5f;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* calculate volume as appropriate */
|
|
|
|
switch (rbo->shape) {
|
|
|
|
case RB_SHAPE_BOX:
|
|
|
|
volume = size[0] * size[1] * size[2];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RB_SHAPE_SPHERE:
|
|
|
|
volume = 4.0f / 3.0f * (float)M_PI * radius * radius * radius;
|
|
|
|
break;
|
|
|
|
|
|
|
|
/* for now, assume that capsule is close enough to a cylinder... */
|
|
|
|
case RB_SHAPE_CAPSULE:
|
|
|
|
case RB_SHAPE_CYLINDER:
|
|
|
|
volume = (float)M_PI * radius * radius * height;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RB_SHAPE_CONE:
|
|
|
|
volume = (float)M_PI / 3.0f * radius * radius * height;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RB_SHAPE_CONVEXH:
|
|
|
|
case RB_SHAPE_TRIMESH:
|
|
|
|
{
|
|
|
|
if (ob->type == OB_MESH) {
|
2018-06-15 10:45:08 +02:00
|
|
|
Mesh *mesh = rigidbody_get_mesh(ob);
|
2014-07-11 12:06:13 +02:00
|
|
|
MVert *mvert;
|
2015-07-19 19:10:41 +02:00
|
|
|
const MLoopTri *lt = NULL;
|
|
|
|
int totvert, tottri = 0;
|
|
|
|
const MLoop *mloop = NULL;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2014-07-11 12:06:13 +02:00
|
|
|
/* ensure mesh validity, then grab data */
|
2018-06-15 10:45:08 +02:00
|
|
|
if (mesh == NULL)
|
2014-07-11 12:06:13 +02:00
|
|
|
return;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2018-06-15 10:45:08 +02:00
|
|
|
mvert = mesh->mvert;
|
|
|
|
totvert = mesh->totvert;
|
|
|
|
lt = BKE_mesh_runtime_looptri_ensure(mesh);
|
|
|
|
tottri = mesh->runtime.looptris.len;
|
|
|
|
mloop = mesh->mloop;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2015-07-19 19:10:41 +02:00
|
|
|
if (totvert > 0 && tottri > 0) {
|
|
|
|
BKE_mesh_calc_volume(mvert, totvert, lt, tottri, mloop, &volume, NULL);
|
2014-07-11 12:06:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* rough estimate from boundbox as fallback */
|
|
|
|
/* XXX could implement other types of geometry here (curves, etc.) */
|
|
|
|
volume = size[0] * size[1] * size[2];
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0 // XXX: not defined yet
|
|
|
|
case RB_SHAPE_COMPOUND:
|
|
|
|
volume = 0.0f;
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return the volume calculated */
|
|
|
|
if (r_vol) *r_vol = volume;
|
|
|
|
}
|
|
|
|
|
2015-07-20 05:19:47 +10:00
|
|
|
void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3])
|
2014-07-11 12:06:13 +02:00
|
|
|
{
|
|
|
|
RigidBodyOb *rbo = ob->rigidbody_object;
|
|
|
|
|
|
|
|
float size[3] = {1.0f, 1.0f, 1.0f};
|
|
|
|
float height = 1.0f;
|
|
|
|
|
2015-07-20 05:19:47 +10:00
|
|
|
zero_v3(r_center);
|
2014-07-11 12:06:13 +02:00
|
|
|
|
|
|
|
/* if automatically determining dimensions, use the Object's boundbox
|
|
|
|
* - assume that all quadrics are standing upright on local z-axis
|
|
|
|
* - assume even distribution of mass around the Object's pivot
|
2014-07-18 11:54:09 +10:00
|
|
|
* (i.e. Object pivot is centralized in boundbox)
|
2014-07-11 12:06:13 +02:00
|
|
|
* - boundbox gives full width
|
|
|
|
*/
|
|
|
|
// XXX: all dimensions are auto-determined now... later can add stored settings for this
|
|
|
|
BKE_object_dimensions_get(ob, size);
|
|
|
|
|
|
|
|
/* calculate volume as appropriate */
|
|
|
|
switch (rbo->shape) {
|
|
|
|
case RB_SHAPE_BOX:
|
|
|
|
case RB_SHAPE_SPHERE:
|
|
|
|
case RB_SHAPE_CAPSULE:
|
|
|
|
case RB_SHAPE_CYLINDER:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case RB_SHAPE_CONE:
|
|
|
|
/* take radius as largest x/y dimension, and height as z-dimension */
|
|
|
|
height = size[2];
|
|
|
|
/* cone is geometrically centered on the median,
|
|
|
|
* center of mass is 1/4 up from the base
|
|
|
|
*/
|
2015-07-20 05:19:47 +10:00
|
|
|
r_center[2] = -0.25f * height;
|
2014-07-11 12:06:13 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case RB_SHAPE_CONVEXH:
|
|
|
|
case RB_SHAPE_TRIMESH:
|
|
|
|
{
|
|
|
|
if (ob->type == OB_MESH) {
|
2018-06-15 10:45:08 +02:00
|
|
|
Mesh *mesh = rigidbody_get_mesh(ob);
|
2014-07-11 12:06:13 +02:00
|
|
|
MVert *mvert;
|
2015-07-20 17:07:40 +10:00
|
|
|
const MLoopTri *looptri;
|
2015-07-21 12:01:03 +10:00
|
|
|
int totvert, tottri;
|
|
|
|
const MLoop *mloop;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2014-07-11 12:06:13 +02:00
|
|
|
/* ensure mesh validity, then grab data */
|
2018-06-15 10:45:08 +02:00
|
|
|
if (mesh == NULL)
|
2014-07-11 12:06:13 +02:00
|
|
|
return;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2018-06-15 10:45:08 +02:00
|
|
|
mvert = mesh->mvert;
|
|
|
|
totvert = mesh->totvert;
|
|
|
|
looptri = BKE_mesh_runtime_looptri_ensure(mesh);
|
|
|
|
tottri = mesh->runtime.looptris.len;
|
|
|
|
mloop = mesh->mloop;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2015-07-19 19:10:41 +02:00
|
|
|
if (totvert > 0 && tottri > 0) {
|
2015-07-20 05:19:47 +10:00
|
|
|
BKE_mesh_calc_volume(mvert, totvert, looptri, tottri, mloop, NULL, r_center);
|
2014-07-11 12:06:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0 // XXX: not defined yet
|
|
|
|
case RB_SHAPE_COMPOUND:
|
|
|
|
volume = 0.0f;
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------- */
|
|
|
|
|
2014-05-29 21:16:04 +10:00
|
|
|
/**
|
|
|
|
* Create physics sim representation of object given RigidBody settings
|
|
|
|
*
|
|
|
|
* \param rebuild Even if an instance already exists, replace it
|
2013-01-23 05:56:22 +00:00
|
|
|
*/
|
2013-12-26 21:30:53 +01:00
|
|
|
static void rigidbody_validate_sim_object(RigidBodyWorld *rbw, Object *ob, bool rebuild)
|
2013-01-23 05:56:22 +00:00
|
|
|
{
|
|
|
|
RigidBodyOb *rbo = (ob) ? ob->rigidbody_object : NULL;
|
|
|
|
float loc[3];
|
|
|
|
float rot[4];
|
|
|
|
|
|
|
|
/* sanity checks:
|
|
|
|
* - object doesn't have RigidBody info already: then why is it here?
|
|
|
|
*/
|
|
|
|
if (rbo == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* make sure collision shape exists */
|
2013-01-23 05:56:56 +00:00
|
|
|
/* FIXME we shouldn't always have to rebuild collision shapes when rebuilding objects, but it's needed for constraints to update correctly */
|
2013-01-23 05:56:22 +00:00
|
|
|
if (rbo->physics_shape == NULL || rebuild)
|
2013-12-26 21:30:53 +01:00
|
|
|
rigidbody_validate_sim_shape(ob, true);
|
2013-01-23 05:56:22 +00:00
|
|
|
|
2013-12-26 21:30:53 +01:00
|
|
|
if (rbo->physics_object && rebuild == false) {
|
2013-12-30 10:53:09 +11:00
|
|
|
RB_dworld_remove_body(rbw->physics_world, rbo->physics_object);
|
2013-01-23 05:56:22 +00:00
|
|
|
}
|
|
|
|
if (!rbo->physics_object || rebuild) {
|
|
|
|
/* remove rigid body if it already exists before creating a new one */
|
|
|
|
if (rbo->physics_object) {
|
|
|
|
RB_body_delete(rbo->physics_object);
|
|
|
|
}
|
|
|
|
|
|
|
|
mat4_to_loc_quat(loc, rot, ob->obmat);
|
|
|
|
|
|
|
|
rbo->physics_object = RB_body_new(rbo->physics_shape, loc, rot);
|
|
|
|
|
|
|
|
RB_body_set_friction(rbo->physics_object, rbo->friction);
|
|
|
|
RB_body_set_restitution(rbo->physics_object, rbo->restitution);
|
|
|
|
|
|
|
|
RB_body_set_damping(rbo->physics_object, rbo->lin_damping, rbo->ang_damping);
|
|
|
|
RB_body_set_sleep_thresh(rbo->physics_object, rbo->lin_sleep_thresh, rbo->ang_sleep_thresh);
|
|
|
|
RB_body_set_activation_state(rbo->physics_object, rbo->flag & RBO_FLAG_USE_DEACTIVATION);
|
|
|
|
|
|
|
|
if (rbo->type == RBO_TYPE_PASSIVE || rbo->flag & RBO_FLAG_START_DEACTIVATED)
|
|
|
|
RB_body_deactivate(rbo->physics_object);
|
|
|
|
|
|
|
|
|
|
|
|
RB_body_set_linear_factor(rbo->physics_object,
|
2013-01-23 23:42:18 +00:00
|
|
|
(ob->protectflag & OB_LOCK_LOCX) == 0,
|
2013-01-23 05:56:22 +00:00
|
|
|
(ob->protectflag & OB_LOCK_LOCY) == 0,
|
|
|
|
(ob->protectflag & OB_LOCK_LOCZ) == 0);
|
|
|
|
RB_body_set_angular_factor(rbo->physics_object,
|
|
|
|
(ob->protectflag & OB_LOCK_ROTX) == 0,
|
|
|
|
(ob->protectflag & OB_LOCK_ROTY) == 0,
|
|
|
|
(ob->protectflag & OB_LOCK_ROTZ) == 0);
|
|
|
|
|
|
|
|
RB_body_set_mass(rbo->physics_object, RBO_GET_MASS(rbo));
|
|
|
|
RB_body_set_kinematic_state(rbo->physics_object, rbo->flag & RBO_FLAG_KINEMATIC || rbo->flag & RBO_FLAG_DISABLED);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rbw && rbw->physics_world)
|
|
|
|
RB_dworld_add_body(rbw->physics_world, rbo->physics_object, rbo->col_groups);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------- */
|
|
|
|
|
2018-06-06 22:17:06 +02:00
|
|
|
static void rigidbody_constraint_set_limits(
|
|
|
|
RigidBodyCon *rbc, void (*set_limits)(rbConstraint *, int, float, float))
|
2018-03-31 12:08:16 +03:00
|
|
|
{
|
|
|
|
if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X)
|
|
|
|
set_limits(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->limit_lin_x_lower, rbc->limit_lin_x_upper);
|
|
|
|
else
|
|
|
|
set_limits(rbc->physics_constraint, RB_LIMIT_LIN_X, 0.0f, -1.0f);
|
|
|
|
|
|
|
|
if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_Y)
|
|
|
|
set_limits(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->limit_lin_y_lower, rbc->limit_lin_y_upper);
|
|
|
|
else
|
|
|
|
set_limits(rbc->physics_constraint, RB_LIMIT_LIN_Y, 0.0f, -1.0f);
|
|
|
|
|
|
|
|
if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_Z)
|
|
|
|
set_limits(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->limit_lin_z_lower, rbc->limit_lin_z_upper);
|
|
|
|
else
|
|
|
|
set_limits(rbc->physics_constraint, RB_LIMIT_LIN_Z, 0.0f, -1.0f);
|
|
|
|
|
|
|
|
if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_X)
|
|
|
|
set_limits(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->limit_ang_x_lower, rbc->limit_ang_x_upper);
|
|
|
|
else
|
|
|
|
set_limits(rbc->physics_constraint, RB_LIMIT_ANG_X, 0.0f, -1.0f);
|
|
|
|
|
|
|
|
if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Y)
|
|
|
|
set_limits(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->limit_ang_y_lower, rbc->limit_ang_y_upper);
|
|
|
|
else
|
|
|
|
set_limits(rbc->physics_constraint, RB_LIMIT_ANG_Y, 0.0f, -1.0f);
|
|
|
|
|
|
|
|
if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Z)
|
|
|
|
set_limits(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->limit_ang_z_lower, rbc->limit_ang_z_upper);
|
|
|
|
else
|
|
|
|
set_limits(rbc->physics_constraint, RB_LIMIT_ANG_Z, 0.0f, -1.0f);
|
|
|
|
}
|
|
|
|
|
2014-05-29 21:16:04 +10:00
|
|
|
/**
|
|
|
|
* Create physics sim representation of constraint given rigid body constraint settings
|
|
|
|
*
|
|
|
|
* \param rebuild Even if an instance already exists, replace it
|
2013-01-23 05:56:56 +00:00
|
|
|
*/
|
2013-12-26 21:30:53 +01:00
|
|
|
static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, bool rebuild)
|
2013-01-23 05:56:56 +00:00
|
|
|
{
|
|
|
|
RigidBodyCon *rbc = (ob) ? ob->rigidbody_constraint : NULL;
|
|
|
|
float loc[3];
|
|
|
|
float rot[4];
|
|
|
|
float lin_lower;
|
|
|
|
float lin_upper;
|
|
|
|
float ang_lower;
|
|
|
|
float ang_upper;
|
|
|
|
|
|
|
|
/* sanity checks:
|
|
|
|
* - object should have a rigid body constraint
|
|
|
|
* - rigid body constraint should have at least one constrained object
|
|
|
|
*/
|
|
|
|
if (rbc == NULL) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-07-20 01:30:29 +10:00
|
|
|
if (ELEM(NULL, rbc->ob1, rbc->ob1->rigidbody_object, rbc->ob2, rbc->ob2->rigidbody_object)) {
|
2013-01-23 05:56:56 +00:00
|
|
|
if (rbc->physics_constraint) {
|
|
|
|
RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
|
|
|
|
RB_constraint_delete(rbc->physics_constraint);
|
|
|
|
rbc->physics_constraint = NULL;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-12-26 21:30:53 +01:00
|
|
|
if (rbc->physics_constraint && rebuild == false) {
|
2013-12-30 10:53:09 +11:00
|
|
|
RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
|
2013-01-23 05:56:56 +00:00
|
|
|
}
|
|
|
|
if (rbc->physics_constraint == NULL || rebuild) {
|
|
|
|
rbRigidBody *rb1 = rbc->ob1->rigidbody_object->physics_object;
|
|
|
|
rbRigidBody *rb2 = rbc->ob2->rigidbody_object->physics_object;
|
|
|
|
|
|
|
|
/* remove constraint if it already exists before creating a new one */
|
|
|
|
if (rbc->physics_constraint) {
|
|
|
|
RB_constraint_delete(rbc->physics_constraint);
|
|
|
|
rbc->physics_constraint = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
mat4_to_loc_quat(loc, rot, ob->obmat);
|
|
|
|
|
|
|
|
if (rb1 && rb2) {
|
|
|
|
switch (rbc->type) {
|
|
|
|
case RBC_TYPE_POINT:
|
|
|
|
rbc->physics_constraint = RB_constraint_new_point(loc, rb1, rb2);
|
|
|
|
break;
|
|
|
|
case RBC_TYPE_FIXED:
|
|
|
|
rbc->physics_constraint = RB_constraint_new_fixed(loc, rot, rb1, rb2);
|
|
|
|
break;
|
|
|
|
case RBC_TYPE_HINGE:
|
|
|
|
rbc->physics_constraint = RB_constraint_new_hinge(loc, rot, rb1, rb2);
|
|
|
|
if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_Z) {
|
|
|
|
RB_constraint_set_limits_hinge(rbc->physics_constraint, rbc->limit_ang_z_lower, rbc->limit_ang_z_upper);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
RB_constraint_set_limits_hinge(rbc->physics_constraint, 0.0f, -1.0f);
|
|
|
|
break;
|
|
|
|
case RBC_TYPE_SLIDER:
|
|
|
|
rbc->physics_constraint = RB_constraint_new_slider(loc, rot, rb1, rb2);
|
|
|
|
if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X)
|
|
|
|
RB_constraint_set_limits_slider(rbc->physics_constraint, rbc->limit_lin_x_lower, rbc->limit_lin_x_upper);
|
|
|
|
else
|
|
|
|
RB_constraint_set_limits_slider(rbc->physics_constraint, 0.0f, -1.0f);
|
|
|
|
break;
|
|
|
|
case RBC_TYPE_PISTON:
|
|
|
|
rbc->physics_constraint = RB_constraint_new_piston(loc, rot, rb1, rb2);
|
|
|
|
if (rbc->flag & RBC_FLAG_USE_LIMIT_LIN_X) {
|
|
|
|
lin_lower = rbc->limit_lin_x_lower;
|
|
|
|
lin_upper = rbc->limit_lin_x_upper;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
lin_lower = 0.0f;
|
|
|
|
lin_upper = -1.0f;
|
|
|
|
}
|
|
|
|
if (rbc->flag & RBC_FLAG_USE_LIMIT_ANG_X) {
|
|
|
|
ang_lower = rbc->limit_ang_x_lower;
|
|
|
|
ang_upper = rbc->limit_ang_x_upper;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
ang_lower = 0.0f;
|
|
|
|
ang_upper = -1.0f;
|
|
|
|
}
|
|
|
|
RB_constraint_set_limits_piston(rbc->physics_constraint, lin_lower, lin_upper, ang_lower, ang_upper);
|
|
|
|
break;
|
2013-01-23 05:57:01 +00:00
|
|
|
case RBC_TYPE_6DOF_SPRING:
|
|
|
|
rbc->physics_constraint = RB_constraint_new_6dof_spring(loc, rot, rb1, rb2);
|
|
|
|
|
|
|
|
RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->flag & RBC_FLAG_USE_SPRING_X);
|
|
|
|
RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_stiffness_x);
|
|
|
|
RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_X, rbc->spring_damping_x);
|
|
|
|
|
|
|
|
RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->flag & RBC_FLAG_USE_SPRING_Y);
|
|
|
|
RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_stiffness_y);
|
|
|
|
RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Y, rbc->spring_damping_y);
|
|
|
|
|
|
|
|
RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->flag & RBC_FLAG_USE_SPRING_Z);
|
|
|
|
RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_stiffness_z);
|
|
|
|
RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_LIN_Z, rbc->spring_damping_z);
|
|
|
|
|
2016-11-07 12:56:58 +03:00
|
|
|
RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->flag & RBC_FLAG_USE_SPRING_ANG_X);
|
|
|
|
RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_stiffness_ang_x);
|
|
|
|
RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_X, rbc->spring_damping_ang_x);
|
|
|
|
|
|
|
|
RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Y);
|
|
|
|
RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_stiffness_ang_y);
|
|
|
|
RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Y, rbc->spring_damping_ang_y);
|
|
|
|
|
|
|
|
RB_constraint_set_spring_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->flag & RBC_FLAG_USE_SPRING_ANG_Z);
|
|
|
|
RB_constraint_set_stiffness_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_stiffness_ang_z);
|
|
|
|
RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_damping_ang_z);
|
|
|
|
|
2013-01-23 05:57:01 +00:00
|
|
|
RB_constraint_set_equilibrium_6dof_spring(rbc->physics_constraint);
|
2013-01-23 05:56:56 +00:00
|
|
|
|
2018-03-31 12:08:16 +03:00
|
|
|
rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof_spring);
|
|
|
|
break;
|
|
|
|
case RBC_TYPE_6DOF:
|
|
|
|
rbc->physics_constraint = RB_constraint_new_6dof(loc, rot, rb1, rb2);
|
2013-01-23 05:56:56 +00:00
|
|
|
|
2018-03-31 12:08:16 +03:00
|
|
|
rigidbody_constraint_set_limits(rbc, RB_constraint_set_limits_6dof);
|
2013-01-23 05:56:56 +00:00
|
|
|
break;
|
2013-02-23 23:04:07 +00:00
|
|
|
case RBC_TYPE_MOTOR:
|
2013-03-15 10:48:48 +00:00
|
|
|
rbc->physics_constraint = RB_constraint_new_motor(loc, rot, rb1, rb2);
|
2013-02-23 23:04:07 +00:00
|
|
|
|
2013-03-15 10:48:48 +00:00
|
|
|
RB_constraint_set_enable_motor(rbc->physics_constraint, rbc->flag & RBC_FLAG_USE_MOTOR_LIN, rbc->flag & RBC_FLAG_USE_MOTOR_ANG);
|
2013-02-23 23:04:07 +00:00
|
|
|
RB_constraint_set_max_impulse_motor(rbc->physics_constraint, rbc->motor_lin_max_impulse, rbc->motor_ang_max_impulse);
|
|
|
|
RB_constraint_set_target_velocity_motor(rbc->physics_constraint, rbc->motor_lin_target_velocity, rbc->motor_ang_target_velocity);
|
2013-03-15 10:48:48 +00:00
|
|
|
break;
|
2013-01-23 05:56:56 +00:00
|
|
|
}
|
|
|
|
}
|
2013-02-20 00:45:53 +00:00
|
|
|
else { /* can't create constraint without both rigid bodies */
|
|
|
|
return;
|
|
|
|
}
|
2013-01-23 05:56:56 +00:00
|
|
|
|
|
|
|
RB_constraint_set_enabled(rbc->physics_constraint, rbc->flag & RBC_FLAG_ENABLED);
|
|
|
|
|
|
|
|
if (rbc->flag & RBC_FLAG_USE_BREAKING)
|
|
|
|
RB_constraint_set_breaking_threshold(rbc->physics_constraint, rbc->breaking_threshold);
|
|
|
|
else
|
|
|
|
RB_constraint_set_breaking_threshold(rbc->physics_constraint, FLT_MAX);
|
|
|
|
|
|
|
|
if (rbc->flag & RBC_FLAG_OVERRIDE_SOLVER_ITERATIONS)
|
|
|
|
RB_constraint_set_solver_iterations(rbc->physics_constraint, rbc->num_solver_iterations);
|
|
|
|
else
|
|
|
|
RB_constraint_set_solver_iterations(rbc->physics_constraint, -1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rbw && rbw->physics_world && rbc->physics_constraint) {
|
|
|
|
RB_dworld_add_constraint(rbw->physics_world, rbc->physics_constraint, rbc->flag & RBC_FLAG_DISABLE_COLLISIONS);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* --------------------- */
|
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
/* Create physics sim world given RigidBody world settings */
|
|
|
|
// NOTE: this does NOT update object references that the scene uses, in case those aren't ready yet!
|
2013-12-26 21:30:53 +01:00
|
|
|
void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, bool rebuild)
|
2013-01-23 05:56:22 +00:00
|
|
|
{
|
|
|
|
/* sanity checks */
|
|
|
|
if (rbw == NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* create new sim world */
|
|
|
|
if (rebuild || rbw->physics_world == NULL) {
|
|
|
|
if (rbw->physics_world)
|
|
|
|
RB_dworld_delete(rbw->physics_world);
|
|
|
|
rbw->physics_world = RB_dworld_new(scene->physics_settings.gravity);
|
|
|
|
}
|
|
|
|
|
|
|
|
RB_dworld_set_solver_iterations(rbw->physics_world, rbw->num_solver_iterations);
|
|
|
|
RB_dworld_set_split_impulse(rbw->physics_world, rbw->flag & RBW_FLAG_USE_SPLIT_IMPULSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ************************************** */
|
|
|
|
/* Setup Utilities - Create Settings Blocks */
|
|
|
|
|
|
|
|
/* Set up RigidBody world */
|
|
|
|
RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene)
|
|
|
|
{
|
|
|
|
/* try to get whatever RigidBody world that might be representing this already */
|
|
|
|
RigidBodyWorld *rbw;
|
|
|
|
|
|
|
|
/* sanity checks
|
|
|
|
* - there must be a valid scene to add world to
|
|
|
|
* - there mustn't be a sim world using this group already
|
|
|
|
*/
|
|
|
|
if (scene == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* create a new sim world */
|
|
|
|
rbw = MEM_callocN(sizeof(RigidBodyWorld), "RigidBodyWorld");
|
|
|
|
|
|
|
|
/* set default settings */
|
2013-01-23 05:56:27 +00:00
|
|
|
rbw->effector_weights = BKE_add_effector_weights(NULL);
|
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
rbw->ltime = PSFRA;
|
|
|
|
|
|
|
|
rbw->time_scale = 1.0f;
|
|
|
|
|
|
|
|
rbw->steps_per_second = 60; /* Bullet default (60 Hz) */
|
|
|
|
rbw->num_solver_iterations = 10; /* 10 is bullet default */
|
|
|
|
|
2016-12-28 17:30:58 +01:00
|
|
|
rbw->pointcache = BKE_ptcache_add(&(rbw->ptcaches));
|
|
|
|
rbw->pointcache->step = 1;
|
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
/* return this sim world */
|
|
|
|
return rbw;
|
|
|
|
}
|
|
|
|
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw, const int flag)
|
2013-04-24 23:09:25 +00:00
|
|
|
{
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
RigidBodyWorld *rbw_copy = MEM_dupallocN(rbw);
|
2013-04-24 23:09:25 +00:00
|
|
|
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
if (rbw->effector_weights) {
|
|
|
|
rbw_copy->effector_weights = MEM_dupallocN(rbw->effector_weights);
|
|
|
|
}
|
|
|
|
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
|
|
|
|
id_us_plus((ID *)rbw_copy->group);
|
|
|
|
id_us_plus((ID *)rbw_copy->constraints);
|
|
|
|
}
|
2013-04-24 23:09:25 +00:00
|
|
|
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
/* XXX Never copy caches here? */
|
|
|
|
rbw_copy->pointcache = BKE_ptcache_copy_list(&rbw_copy->ptcaches, &rbw->ptcaches, flag & ~LIB_ID_COPY_CACHES);
|
2016-12-28 17:30:58 +01:00
|
|
|
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
rbw_copy->objects = NULL;
|
|
|
|
rbw_copy->physics_world = NULL;
|
|
|
|
rbw_copy->numbodies = 0;
|
2013-04-24 23:09:25 +00:00
|
|
|
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
return rbw_copy;
|
2013-04-24 23:09:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void BKE_rigidbody_world_groups_relink(RigidBodyWorld *rbw)
|
|
|
|
{
|
2016-12-12 15:05:19 +01:00
|
|
|
ID_NEW_REMAP(rbw->group);
|
|
|
|
ID_NEW_REMAP(rbw->constraints);
|
|
|
|
ID_NEW_REMAP(rbw->effector_weights->group);
|
2013-04-24 23:09:25 +00:00
|
|
|
}
|
|
|
|
|
2015-10-08 14:59:24 +02:00
|
|
|
void BKE_rigidbody_world_id_loop(RigidBodyWorld *rbw, RigidbodyWorldIDFunc func, void *userdata)
|
|
|
|
{
|
2017-01-31 09:47:59 +01:00
|
|
|
func(rbw, (ID **)&rbw->group, userdata, IDWALK_CB_NOP);
|
|
|
|
func(rbw, (ID **)&rbw->constraints, userdata, IDWALK_CB_NOP);
|
|
|
|
func(rbw, (ID **)&rbw->effector_weights->group, userdata, IDWALK_CB_NOP);
|
2015-10-08 14:59:24 +02:00
|
|
|
|
|
|
|
if (rbw->objects) {
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < rbw->numbodies; i++) {
|
2017-01-31 09:47:59 +01:00
|
|
|
func(rbw, (ID **)&rbw->objects[i], userdata, IDWALK_CB_NOP);
|
2015-10-08 14:59:24 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
/* Add rigid body settings to the specified object */
|
2016-12-28 17:30:58 +01:00
|
|
|
RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
|
2013-01-23 05:56:22 +00:00
|
|
|
{
|
|
|
|
RigidBodyOb *rbo;
|
2016-12-28 17:30:58 +01:00
|
|
|
RigidBodyWorld *rbw = scene->rigidbody_world;
|
2013-01-23 05:56:22 +00:00
|
|
|
|
|
|
|
/* sanity checks
|
|
|
|
* - rigidbody world must exist
|
|
|
|
* - object must exist
|
|
|
|
* - cannot add rigid body if it already exists
|
|
|
|
*/
|
|
|
|
if (ob == NULL || (ob->rigidbody_object != NULL))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* create new settings data, and link it up */
|
|
|
|
rbo = MEM_callocN(sizeof(RigidBodyOb), "RigidBodyOb");
|
|
|
|
|
|
|
|
/* set default settings */
|
|
|
|
rbo->type = type;
|
|
|
|
|
|
|
|
rbo->mass = 1.0f;
|
|
|
|
|
|
|
|
rbo->friction = 0.5f; /* best when non-zero. 0.5 is Bullet default */
|
|
|
|
rbo->restitution = 0.0f; /* best when zero. 0.0 is Bullet default */
|
|
|
|
|
|
|
|
rbo->margin = 0.04f; /* 0.04 (in meters) is Bullet default */
|
|
|
|
|
|
|
|
rbo->lin_sleep_thresh = 0.4f; /* 0.4 is half of Bullet default */
|
|
|
|
rbo->ang_sleep_thresh = 0.5f; /* 0.5 is half of Bullet default */
|
|
|
|
|
2018-04-16 14:07:42 +02:00
|
|
|
rbo->lin_damping = 0.04f;
|
|
|
|
rbo->ang_damping = 0.1f;
|
2013-01-23 05:56:22 +00:00
|
|
|
|
|
|
|
rbo->col_groups = 1;
|
|
|
|
|
|
|
|
/* use triangle meshes for passive objects
|
|
|
|
* use convex hulls for active objects since dynamic triangle meshes are very unstable
|
|
|
|
*/
|
|
|
|
if (type == RBO_TYPE_ACTIVE)
|
|
|
|
rbo->shape = RB_SHAPE_CONVEXH;
|
|
|
|
else
|
|
|
|
rbo->shape = RB_SHAPE_TRIMESH;
|
|
|
|
|
2013-12-26 17:02:28 +01:00
|
|
|
rbo->mesh_source = RBO_MESH_DEFORM;
|
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
/* set initial transform */
|
|
|
|
mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat);
|
|
|
|
|
2016-12-28 17:30:58 +01:00
|
|
|
/* flag cache as outdated */
|
|
|
|
BKE_rigidbody_cache_reset(rbw);
|
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
/* return this object */
|
|
|
|
return rbo;
|
|
|
|
}
|
|
|
|
|
2013-01-23 05:56:56 +00:00
|
|
|
/* Add rigid body constraint to the specified object */
|
2016-12-28 17:30:58 +01:00
|
|
|
RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short type)
|
2013-01-23 05:56:56 +00:00
|
|
|
{
|
|
|
|
RigidBodyCon *rbc;
|
2016-12-28 17:30:58 +01:00
|
|
|
RigidBodyWorld *rbw = scene->rigidbody_world;
|
2013-01-23 05:56:56 +00:00
|
|
|
|
|
|
|
/* sanity checks
|
|
|
|
* - rigidbody world must exist
|
|
|
|
* - object must exist
|
|
|
|
* - cannot add constraint if it already exists
|
|
|
|
*/
|
|
|
|
if (ob == NULL || (ob->rigidbody_constraint != NULL))
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* create new settings data, and link it up */
|
|
|
|
rbc = MEM_callocN(sizeof(RigidBodyCon), "RigidBodyCon");
|
|
|
|
|
|
|
|
/* set default settings */
|
|
|
|
rbc->type = type;
|
|
|
|
|
|
|
|
rbc->ob1 = NULL;
|
|
|
|
rbc->ob2 = NULL;
|
|
|
|
|
|
|
|
rbc->flag |= RBC_FLAG_ENABLED;
|
|
|
|
rbc->flag |= RBC_FLAG_DISABLE_COLLISIONS;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
2013-01-23 05:57:01 +00:00
|
|
|
rbc->spring_damping_x = 0.5f;
|
|
|
|
rbc->spring_damping_y = 0.5f;
|
|
|
|
rbc->spring_damping_z = 0.5f;
|
2016-11-07 12:56:58 +03:00
|
|
|
rbc->spring_damping_ang_x = 0.5f;
|
|
|
|
rbc->spring_damping_ang_y = 0.5f;
|
|
|
|
rbc->spring_damping_ang_z = 0.5f;
|
2013-01-23 05:57:01 +00:00
|
|
|
rbc->spring_stiffness_x = 10.0f;
|
|
|
|
rbc->spring_stiffness_y = 10.0f;
|
|
|
|
rbc->spring_stiffness_z = 10.0f;
|
2016-11-07 12:56:58 +03:00
|
|
|
rbc->spring_stiffness_ang_x = 10.0f;
|
|
|
|
rbc->spring_stiffness_ang_y = 10.0f;
|
|
|
|
rbc->spring_stiffness_ang_z = 10.0f;
|
2013-01-23 05:57:01 +00:00
|
|
|
|
2013-02-23 23:04:07 +00:00
|
|
|
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;
|
|
|
|
|
2016-12-28 17:30:58 +01:00
|
|
|
/* flag cache as outdated */
|
|
|
|
BKE_rigidbody_cache_reset(rbw);
|
|
|
|
|
2013-01-23 05:56:56 +00:00
|
|
|
/* return this object */
|
|
|
|
return rbc;
|
|
|
|
}
|
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
/* ************************************** */
|
|
|
|
/* Utilities API */
|
|
|
|
|
|
|
|
/* Get RigidBody world for the given scene, creating one if needed
|
2014-05-29 21:16:04 +10:00
|
|
|
*
|
|
|
|
* \param scene Scene to find active Rigid Body world for
|
2013-01-23 05:56:22 +00:00
|
|
|
*/
|
|
|
|
RigidBodyWorld *BKE_rigidbody_get_world(Scene *scene)
|
|
|
|
{
|
|
|
|
/* sanity check */
|
|
|
|
if (scene == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
return scene->rigidbody_world;
|
|
|
|
}
|
|
|
|
|
2018-06-19 14:57:07 +02:00
|
|
|
void BKE_rigidbody_remove_object(struct Main *bmain, Scene *scene, Object *ob)
|
2013-01-23 05:56:22 +00:00
|
|
|
{
|
|
|
|
RigidBodyWorld *rbw = scene->rigidbody_world;
|
|
|
|
RigidBodyOb *rbo = ob->rigidbody_object;
|
2013-01-23 05:56:56 +00:00
|
|
|
RigidBodyCon *rbc;
|
2013-01-23 05:56:22 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
if (rbw) {
|
|
|
|
/* remove from rigidbody world, free object won't do this */
|
|
|
|
if (rbw->physics_world && rbo->physics_object)
|
|
|
|
RB_dworld_remove_body(rbw->physics_world, rbo->physics_object);
|
|
|
|
|
|
|
|
/* remove object from array */
|
|
|
|
if (rbw && rbw->objects) {
|
|
|
|
for (i = 0; i < rbw->numbodies; i++) {
|
|
|
|
if (rbw->objects[i] == ob) {
|
|
|
|
rbw->objects[i] = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-01-23 05:56:56 +00:00
|
|
|
|
|
|
|
/* remove object from rigid body constraints */
|
|
|
|
if (rbw->constraints) {
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, obt)
|
2017-12-01 11:24:21 -02:00
|
|
|
{
|
2013-02-04 23:50:31 +00:00
|
|
|
if (obt && obt->rigidbody_constraint) {
|
2013-01-23 05:56:56 +00:00
|
|
|
rbc = obt->rigidbody_constraint;
|
2014-05-12 14:55:54 +10:00
|
|
|
if (ELEM(ob, rbc->ob1, rbc->ob2)) {
|
2013-07-04 08:52:24 +00:00
|
|
|
BKE_rigidbody_remove_constraint(scene, obt);
|
2013-01-23 05:56:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
|
2013-01-23 05:56:56 +00:00
|
|
|
}
|
2018-06-19 14:57:07 +02:00
|
|
|
BKE_collection_object_remove(bmain, rbw->group, ob, false);
|
2013-01-23 05:56:22 +00:00
|
|
|
}
|
2013-01-23 05:56:56 +00:00
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
/* remove object's settings */
|
|
|
|
BKE_rigidbody_free_object(ob);
|
2016-12-28 17:30:58 +01:00
|
|
|
|
|
|
|
/* flag cache as outdated */
|
|
|
|
BKE_rigidbody_cache_reset(rbw);
|
2013-01-23 05:56:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob)
|
|
|
|
{
|
|
|
|
RigidBodyWorld *rbw = scene->rigidbody_world;
|
|
|
|
RigidBodyCon *rbc = ob->rigidbody_constraint;
|
|
|
|
|
2013-07-04 08:52:27 +00:00
|
|
|
/* remove from rigidbody world, free object won't do this */
|
|
|
|
if (rbw && rbw->physics_world && rbc->physics_constraint) {
|
|
|
|
RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
|
2013-01-23 05:56:56 +00:00
|
|
|
}
|
|
|
|
/* remove object's settings */
|
|
|
|
BKE_rigidbody_free_constraint(ob);
|
2016-12-28 17:30:58 +01:00
|
|
|
|
|
|
|
/* flag cache as outdated */
|
|
|
|
BKE_rigidbody_cache_reset(rbw);
|
2013-01-23 05:56:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* ************************************** */
|
|
|
|
/* Simulation Interface - Bullet */
|
|
|
|
|
|
|
|
/* Update object array and rigid body count so they're in sync with the rigid body group */
|
|
|
|
static void rigidbody_update_ob_array(RigidBodyWorld *rbw)
|
|
|
|
{
|
2018-06-08 19:26:46 +02:00
|
|
|
int n = 0;
|
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object)
|
|
|
|
{
|
|
|
|
(void)object;
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
|
2013-01-23 05:56:22 +00:00
|
|
|
|
|
|
|
if (rbw->numbodies != n) {
|
|
|
|
rbw->numbodies = n;
|
|
|
|
rbw->objects = realloc(rbw->objects, sizeof(Object *) * rbw->numbodies);
|
|
|
|
}
|
|
|
|
|
2018-06-08 19:26:46 +02:00
|
|
|
int i = 0;
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object)
|
2017-12-01 11:24:21 -02:00
|
|
|
{
|
|
|
|
rbw->objects[i] = object;
|
|
|
|
i++;
|
2013-01-23 05:56:22 +00:00
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
|
2013-01-23 05:56:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void rigidbody_update_sim_world(Scene *scene, RigidBodyWorld *rbw)
|
|
|
|
{
|
|
|
|
float adj_gravity[3];
|
|
|
|
|
|
|
|
/* adjust gravity to take effector weights into account */
|
|
|
|
if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
|
|
|
|
copy_v3_v3(adj_gravity, scene->physics_settings.gravity);
|
2013-01-23 05:56:27 +00:00
|
|
|
mul_v3_fl(adj_gravity, rbw->effector_weights->global_gravity * rbw->effector_weights->weight[0]);
|
2013-01-23 05:56:22 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
zero_v3(adj_gravity);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* update gravity, since this RNA setting is not part of RigidBody settings */
|
|
|
|
RB_dworld_set_gravity(rbw->physics_world, adj_gravity);
|
|
|
|
|
|
|
|
/* update object array in case there are changes */
|
|
|
|
rigidbody_update_ob_array(rbw);
|
|
|
|
}
|
|
|
|
|
2018-06-08 19:26:46 +02:00
|
|
|
static void rigidbody_update_sim_ob(Depsgraph *depsgraph, Scene *scene, RigidBodyWorld *rbw, Object *ob, RigidBodyOb *rbo)
|
2013-01-23 05:56:22 +00:00
|
|
|
{
|
|
|
|
float loc[3];
|
|
|
|
float rot[4];
|
|
|
|
float scale[3];
|
|
|
|
|
|
|
|
/* only update if rigid body exists */
|
|
|
|
if (rbo->physics_object == NULL)
|
|
|
|
return;
|
|
|
|
|
2013-12-26 18:15:56 +01:00
|
|
|
if (rbo->shape == RB_SHAPE_TRIMESH && rbo->flag & RBO_FLAG_USE_DEFORM) {
|
2018-06-15 10:45:08 +02:00
|
|
|
Mesh *mesh = ob->runtime.mesh_deform_eval;
|
|
|
|
if (mesh) {
|
|
|
|
MVert *mvert = mesh->mvert;
|
|
|
|
int totvert = mesh->totvert;
|
2013-12-26 18:15:56 +01:00
|
|
|
BoundBox *bb = BKE_object_boundbox_get(ob);
|
|
|
|
|
2013-12-30 10:53:09 +11:00
|
|
|
RB_shape_trimesh_update(rbo->physics_shape, (float *)mvert, totvert, sizeof(MVert), bb->vec[0], bb->vec[6]);
|
2013-12-26 18:15:56 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
mat4_decompose(loc, rot, scale, ob->obmat);
|
|
|
|
|
|
|
|
/* update scale for all objects */
|
|
|
|
RB_body_set_scale(rbo->physics_object, scale);
|
|
|
|
/* compensate for embedded convex hull collision margin */
|
|
|
|
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]));
|
|
|
|
|
2013-01-23 12:06:18 +00:00
|
|
|
/* make transformed objects temporarily kinmatic so that they can be moved by the user during simulation */
|
2013-02-04 23:50:38 +00:00
|
|
|
if (ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ) {
|
2014-04-01 11:34:00 +11:00
|
|
|
RB_body_set_kinematic_state(rbo->physics_object, true);
|
2013-01-23 12:06:18 +00:00
|
|
|
RB_body_set_mass(rbo->physics_object, 0.0f);
|
|
|
|
}
|
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
/* update rigid body location and rotation for kinematic bodies */
|
2013-01-23 12:06:18 +00:00
|
|
|
if (rbo->flag & RBO_FLAG_KINEMATIC || (ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) {
|
2013-01-23 05:56:22 +00:00
|
|
|
RB_body_activate(rbo->physics_object);
|
|
|
|
RB_body_set_loc_rot(rbo->physics_object, loc, rot);
|
|
|
|
}
|
2013-01-23 05:56:27 +00:00
|
|
|
/* update influence of effectors - but don't do it on an effector */
|
|
|
|
/* only dynamic bodies need effector update */
|
|
|
|
else if (rbo->type == RBO_TYPE_ACTIVE && ((ob->pd == NULL) || (ob->pd->forcefield == PFIELD_NULL))) {
|
|
|
|
EffectorWeights *effector_weights = rbw->effector_weights;
|
|
|
|
EffectedPoint epoint;
|
|
|
|
ListBase *effectors;
|
|
|
|
|
|
|
|
/* get effectors present in the group specified by effector_weights */
|
2018-06-22 14:42:03 +02:00
|
|
|
effectors = BKE_effectors_create(depsgraph, ob, NULL, effector_weights);
|
2013-01-23 05:56:27 +00:00
|
|
|
if (effectors) {
|
2013-03-26 20:34:13 +00:00
|
|
|
float eff_force[3] = {0.0f, 0.0f, 0.0f};
|
|
|
|
float eff_loc[3], eff_vel[3];
|
2013-01-23 05:56:27 +00:00
|
|
|
|
|
|
|
/* create dummy 'point' which represents last known position of object as result of sim */
|
|
|
|
// XXX: this can create some inaccuracies with sim position, but is probably better than using unsimulated vals?
|
2013-03-26 20:34:13 +00:00
|
|
|
RB_body_get_position(rbo->physics_object, eff_loc);
|
|
|
|
RB_body_get_linear_velocity(rbo->physics_object, eff_vel);
|
2013-01-23 05:56:27 +00:00
|
|
|
|
2013-03-26 20:34:13 +00:00
|
|
|
pd_point_from_loc(scene, eff_loc, eff_vel, 0, &epoint);
|
2013-01-23 05:56:27 +00:00
|
|
|
|
|
|
|
/* calculate net force of effectors, and apply to sim object
|
|
|
|
* - we use 'central force' since apply force requires a "relative position" which we don't have...
|
|
|
|
*/
|
2018-06-21 19:45:39 +02:00
|
|
|
BKE_effectors_apply(effectors, NULL, effector_weights, &epoint, eff_force, NULL);
|
2013-01-23 05:56:27 +00:00
|
|
|
if (G.f & G_DEBUG)
|
2013-03-26 20:34:13 +00:00
|
|
|
printf("\tapplying force (%f,%f,%f) to '%s'\n", eff_force[0], eff_force[1], eff_force[2], ob->id.name + 2);
|
2013-01-23 05:56:27 +00:00
|
|
|
/* activate object in case it is deactivated */
|
2013-03-26 20:34:13 +00:00
|
|
|
if (!is_zero_v3(eff_force))
|
2013-01-23 05:56:27 +00:00
|
|
|
RB_body_activate(rbo->physics_object);
|
2013-03-26 20:34:13 +00:00
|
|
|
RB_body_apply_central_force(rbo->physics_object, eff_force);
|
2013-01-23 05:56:27 +00:00
|
|
|
}
|
|
|
|
else if (G.f & G_DEBUG)
|
|
|
|
printf("\tno forces to apply to '%s'\n", ob->id.name + 2);
|
|
|
|
|
|
|
|
/* cleanup */
|
2018-06-21 19:45:39 +02:00
|
|
|
BKE_effectors_free(effectors);
|
2013-01-23 05:56:27 +00:00
|
|
|
}
|
2013-01-23 05:56:22 +00:00
|
|
|
/* NOTE: passive objects don't need to be updated since they don't move */
|
|
|
|
|
|
|
|
/* NOTE: no other settings need to be explicitly updated here,
|
|
|
|
* since RNA setters take care of the rest :)
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
|
2014-05-29 21:16:04 +10:00
|
|
|
/**
|
|
|
|
* Updates and validates world, bodies and shapes.
|
|
|
|
*
|
|
|
|
* \param rebuild Rebuild entire simulation
|
2013-01-23 05:56:22 +00:00
|
|
|
*/
|
2018-06-08 19:26:46 +02:00
|
|
|
static void rigidbody_update_simulation(Depsgraph *depsgraph, Scene *scene, RigidBodyWorld *rbw, bool rebuild)
|
2013-01-23 05:56:22 +00:00
|
|
|
{
|
|
|
|
/* update world */
|
|
|
|
if (rebuild)
|
|
|
|
BKE_rigidbody_validate_sim_world(scene, rbw, true);
|
|
|
|
rigidbody_update_sim_world(scene, rbw);
|
|
|
|
|
2014-05-14 11:42:45 +02:00
|
|
|
/* XXX TODO For rebuild: remove all constraints first.
|
|
|
|
* Otherwise we can end up deleting objects that are still
|
|
|
|
* referenced by constraints, corrupting bullet's internal list.
|
2018-06-17 17:05:51 +02:00
|
|
|
*
|
2014-05-14 11:42:45 +02:00
|
|
|
* Memory management needs redesign here, this is just a dirty workaround.
|
|
|
|
*/
|
|
|
|
if (rebuild && rbw->constraints) {
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, ob)
|
2017-12-01 11:24:21 -02:00
|
|
|
{
|
|
|
|
RigidBodyCon *rbc = ob->rigidbody_constraint;
|
|
|
|
if (rbc && rbc->physics_constraint) {
|
|
|
|
RB_dworld_remove_constraint(rbw->physics_world, rbc->physics_constraint);
|
|
|
|
RB_constraint_delete(rbc->physics_constraint);
|
|
|
|
rbc->physics_constraint = NULL;
|
2014-05-14 11:42:45 +02:00
|
|
|
}
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
|
2014-05-14 11:42:45 +02:00
|
|
|
}
|
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
/* update objects */
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, ob)
|
2017-12-01 11:24:21 -02:00
|
|
|
{
|
|
|
|
if (ob->type == OB_MESH) {
|
2013-01-23 05:56:22 +00:00
|
|
|
/* validate that we've got valid object set up here... */
|
|
|
|
RigidBodyOb *rbo = ob->rigidbody_object;
|
|
|
|
/* update transformation matrix of the object so we don't get a frame of lag for simple animations */
|
2018-04-06 12:07:27 +02:00
|
|
|
BKE_object_where_is_calc(depsgraph, scene, ob);
|
2013-01-23 05:56:22 +00:00
|
|
|
|
|
|
|
if (rbo == NULL) {
|
|
|
|
/* Since this object is included in the sim group but doesn't have
|
|
|
|
* rigid body settings (perhaps it was added manually), add!
|
|
|
|
* - assume object to be active? That is the default for newly added settings...
|
|
|
|
*/
|
|
|
|
ob->rigidbody_object = BKE_rigidbody_create_object(scene, ob, RBO_TYPE_ACTIVE);
|
2013-12-26 21:30:53 +01:00
|
|
|
rigidbody_validate_sim_object(rbw, ob, true);
|
2013-01-23 05:56:22 +00:00
|
|
|
|
|
|
|
rbo = ob->rigidbody_object;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* perform simulation data updates as tagged */
|
|
|
|
/* refresh object... */
|
|
|
|
if (rebuild) {
|
|
|
|
/* World has been rebuilt so rebuild object */
|
2013-12-26 21:30:53 +01:00
|
|
|
rigidbody_validate_sim_object(rbw, ob, true);
|
2013-01-23 05:56:22 +00:00
|
|
|
}
|
|
|
|
else if (rbo->flag & RBO_FLAG_NEEDS_VALIDATE) {
|
2013-12-26 21:30:53 +01:00
|
|
|
rigidbody_validate_sim_object(rbw, ob, false);
|
2013-01-23 05:56:22 +00:00
|
|
|
}
|
|
|
|
/* refresh shape... */
|
|
|
|
if (rbo->flag & RBO_FLAG_NEEDS_RESHAPE) {
|
|
|
|
/* mesh/shape data changed, so force shape refresh */
|
2013-12-26 21:30:53 +01:00
|
|
|
rigidbody_validate_sim_shape(ob, true);
|
2013-01-23 05:56:22 +00:00
|
|
|
/* now tell RB sim about it */
|
|
|
|
// XXX: we assume that this can only get applied for active/passive shapes that will be included as rigidbodies
|
|
|
|
RB_body_set_collision_shape(rbo->physics_object, rbo->physics_shape);
|
|
|
|
}
|
|
|
|
rbo->flag &= ~(RBO_FLAG_NEEDS_VALIDATE | RBO_FLAG_NEEDS_RESHAPE);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* update simulation object... */
|
2018-04-06 12:07:27 +02:00
|
|
|
rigidbody_update_sim_ob(depsgraph, scene, rbw, ob, rbo);
|
2013-01-23 05:56:22 +00:00
|
|
|
}
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
|
2018-06-17 17:05:51 +02:00
|
|
|
|
2013-01-23 05:56:56 +00:00
|
|
|
/* update constraints */
|
|
|
|
if (rbw->constraints == NULL) /* no constraints, move on */
|
|
|
|
return;
|
|
|
|
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->constraints, ob)
|
2017-12-01 11:24:21 -02:00
|
|
|
{
|
|
|
|
/* validate that we've got valid object set up here... */
|
|
|
|
RigidBodyCon *rbc = ob->rigidbody_constraint;
|
|
|
|
/* update transformation matrix of the object so we don't get a frame of lag for simple animations */
|
2018-04-06 12:07:27 +02:00
|
|
|
BKE_object_where_is_calc(depsgraph, scene, ob);
|
2013-01-23 05:56:56 +00:00
|
|
|
|
2017-12-01 11:24:21 -02:00
|
|
|
if (rbc == NULL) {
|
|
|
|
/* Since this object is included in the group but doesn't have
|
|
|
|
* constraint settings (perhaps it was added manually), add!
|
|
|
|
*/
|
|
|
|
ob->rigidbody_constraint = BKE_rigidbody_create_constraint(scene, ob, RBC_TYPE_FIXED);
|
|
|
|
rigidbody_validate_sim_constraint(rbw, ob, true);
|
2013-01-23 05:56:56 +00:00
|
|
|
|
2017-12-01 11:24:21 -02:00
|
|
|
rbc = ob->rigidbody_constraint;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* perform simulation data updates as tagged */
|
|
|
|
if (rebuild) {
|
|
|
|
/* World has been rebuilt so rebuild constraint */
|
|
|
|
rigidbody_validate_sim_constraint(rbw, ob, true);
|
2013-01-23 05:56:56 +00:00
|
|
|
}
|
2017-12-01 11:24:21 -02:00
|
|
|
else if (rbc->flag & RBC_FLAG_NEEDS_VALIDATE) {
|
|
|
|
rigidbody_validate_sim_constraint(rbw, ob, false);
|
2013-01-23 05:56:56 +00:00
|
|
|
}
|
2017-12-01 11:24:21 -02:00
|
|
|
rbc->flag &= ~RBC_FLAG_NEEDS_VALIDATE;
|
2013-01-23 05:56:56 +00:00
|
|
|
}
|
|
|
|
}
|
Collections and groups unification
OVERVIEW
* In 2.7 terminology, all layers and groups are now collection datablocks.
* These collections are nestable, linkable, instanceable, overrideable, ..
which opens up new ways to set up scenes and link + override data.
* Viewport/render visibility and selectability are now a part of the collection
and shared across all view layers and linkable.
* View layers define which subset of the scene collection hierarchy is excluded
for each. For many workflows one view layer can be used, these are more of an
advanced feature now.
OUTLINER
* The outliner now has a "View Layer" display mode instead of "Collections",
which can display the collections and/or objects in the view layer.
* In this display mode, collections can be excluded with the right click menu.
These will then be greyed out and their objects will be excluded.
* To view collections not linked to any scene, the "Blender File" display mode
can be used, with the new filtering option to just see Colleciton datablocks.
* The outliner right click menus for collections and objects were reorganized.
* Drag and drop still needs to be improved. Like before, dragging the icon or
text gives different results, we'll unify this later.
LINKING AND OVERRIDES
* Collections can now be linked into the scene without creating an instance,
with the link/append operator or from the collections view in the outliner.
* Collections can get static overrides with the right click menu in the outliner,
but this is rather unreliable and not clearly communicated at the moment.
* We still need to improve the make override operator to turn collection instances
into collections with overrides directly in the scene.
PERFORMANCE
* We tried to make performance not worse than before and improve it in some
cases. The main thing that's still a bit slower is multiple scenes, we have to
change the layer syncing to only updated affected scenes.
* Collections keep a list of their parent collections for faster incremental
updates in syncing and caching.
* View layer bases are now in a object -> base hash to avoid quadratic time
lookups internally and in API functions like visible_get().
VERSIONING
* Compatibility with 2.7 files should be improved due to the new visibility
controls. Of course users may not want to set up their scenes differently
now to avoid having separate layers and groups.
* Compatibility with 2.8 is mostly there, and was tested on Eevee demo and Hero
files. There's a few things which are know to be not quite compatible, like
nested layer collections inside groups.
* The versioning code for 2.8 files is quite complicated, and isolated behind
#ifdef so it can be removed at the end of the release cycle.
KNOWN ISSUES
* The G-key group operators in the 3D viewport were left mostly as is, they
need to be modified still to fit better.
* Same for the groups panel in the object properties. This needs to be updated
still, or perhaps replaced by something better.
* Collections must all have a unique name. Less restrictive namespacing is to
be done later, we'll have to see how important this is as all objects within
the collections must also have a unique name anyway.
* Full scene copy and delete scene are exactly doing the right thing yet.
Differential Revision: https://developer.blender.org/D3383
https://code.blender.org/2018/05/collections-and-groups/
2018-04-30 15:57:22 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
|
2013-01-23 05:56:22 +00:00
|
|
|
}
|
|
|
|
|
2018-06-08 19:26:46 +02:00
|
|
|
static void rigidbody_update_simulation_post_step(Depsgraph *depsgraph, RigidBodyWorld *rbw)
|
2013-01-23 12:06:18 +00:00
|
|
|
{
|
2018-06-08 19:26:46 +02:00
|
|
|
ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph);
|
|
|
|
|
2018-06-11 11:40:26 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, ob)
|
2017-12-01 11:24:21 -02:00
|
|
|
{
|
2018-06-11 11:40:26 +02:00
|
|
|
Base *base = BKE_view_layer_base_find(view_layer, ob);
|
2017-12-01 11:24:21 -02:00
|
|
|
RigidBodyOb *rbo = ob->rigidbody_object;
|
|
|
|
/* Reset kinematic state for transformed objects. */
|
2018-06-11 11:40:26 +02:00
|
|
|
if (rbo && base && (base->flag & BASE_SELECTED) && (G.moving & G_TRANSFORM_OBJ)) {
|
2017-12-01 11:24:21 -02:00
|
|
|
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));
|
|
|
|
/* Deactivate passive objects so they don't interfere with deactivation of active objects. */
|
|
|
|
if (rbo->type == RBO_TYPE_PASSIVE)
|
|
|
|
RB_body_deactivate(rbo->physics_object);
|
2013-01-23 12:06:18 +00:00
|
|
|
}
|
|
|
|
}
|
2018-06-11 11:40:26 +02:00
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
|
2013-01-23 12:06:18 +00:00
|
|
|
}
|
2013-04-07 14:09:29 +00:00
|
|
|
|
2016-12-28 17:30:58 +01:00
|
|
|
bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime)
|
2013-04-07 14:09:29 +00:00
|
|
|
{
|
2016-12-28 17:30:58 +01:00
|
|
|
return (rbw && (rbw->flag & RBW_FLAG_MUTED) == 0 && ctime > rbw->pointcache->startframe);
|
2013-04-07 14:09:29 +00:00
|
|
|
}
|
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
/* Sync rigid body and object transformations */
|
2013-02-16 16:17:45 +00:00
|
|
|
void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
|
2013-01-23 05:56:22 +00:00
|
|
|
{
|
2013-01-23 05:56:44 +00:00
|
|
|
RigidBodyOb *rbo = ob->rigidbody_object;
|
|
|
|
|
|
|
|
/* keep original transform for kinematic and passive objects */
|
2013-02-16 16:17:45 +00:00
|
|
|
if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE)
|
2013-01-23 05:56:44 +00:00
|
|
|
return;
|
|
|
|
|
2013-01-23 12:06:18 +00:00
|
|
|
/* use rigid body transform after cache start frame if objects is not being transformed */
|
2013-04-07 14:09:29 +00:00
|
|
|
if (BKE_rigidbody_check_sim_running(rbw, ctime) && !(ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) {
|
2013-01-23 05:56:44 +00:00
|
|
|
float mat[4][4], size_mat[4][4], size[3];
|
|
|
|
|
|
|
|
normalize_qt(rbo->orn); // RB_TODO investigate why quaternion isn't normalized at this point
|
|
|
|
quat_to_mat4(mat, rbo->orn);
|
|
|
|
copy_v3_v3(mat[3], rbo->pos);
|
|
|
|
|
|
|
|
mat4_to_size(size, ob->obmat);
|
|
|
|
size_to_mat4(size_mat, size);
|
2013-05-26 18:36:25 +00:00
|
|
|
mul_m4_m4m4(mat, mat, size_mat);
|
2013-01-23 05:56:44 +00:00
|
|
|
|
|
|
|
copy_m4_m4(ob->obmat, mat);
|
|
|
|
}
|
|
|
|
/* otherwise set rigid body transform to current obmat */
|
|
|
|
else {
|
|
|
|
mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat);
|
|
|
|
}
|
2013-01-23 05:56:22 +00:00
|
|
|
}
|
|
|
|
|
2013-10-31 14:10:01 +00:00
|
|
|
/* Used when canceling transforms - return rigidbody and object to initial states */
|
2013-01-23 12:06:18 +00:00
|
|
|
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;
|
2017-07-04 10:12:09 +02:00
|
|
|
bool correct_delta = !(rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE);
|
2013-01-23 12:06:18 +00:00
|
|
|
|
2013-01-24 03:49:30 +00:00
|
|
|
/* return rigid body and object to their initial states */
|
2013-01-23 12:06:18 +00:00
|
|
|
copy_v3_v3(rbo->pos, ob->loc);
|
|
|
|
copy_v3_v3(ob->loc, loc);
|
|
|
|
|
2017-07-04 10:12:09 +02:00
|
|
|
if (correct_delta) {
|
|
|
|
add_v3_v3(rbo->pos, ob->dloc);
|
|
|
|
}
|
|
|
|
|
2013-01-23 12:06:18 +00:00
|
|
|
if (ob->rotmode > 0) {
|
2017-07-04 10:12:09 +02:00
|
|
|
float qt[4];
|
|
|
|
eulO_to_quat(qt, ob->rot, ob->rotmode);
|
|
|
|
|
|
|
|
if (correct_delta) {
|
|
|
|
float dquat[4];
|
|
|
|
eulO_to_quat(dquat, ob->drot, ob->rotmode);
|
|
|
|
|
|
|
|
mul_qt_qtqt(rbo->orn, dquat, qt);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
copy_qt_qt(rbo->orn, qt);
|
|
|
|
}
|
|
|
|
|
2013-01-23 12:06:18 +00:00
|
|
|
copy_v3_v3(ob->rot, rot);
|
|
|
|
}
|
|
|
|
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
|
2017-07-04 10:12:09 +02:00
|
|
|
float qt[4];
|
|
|
|
axis_angle_to_quat(qt, ob->rotAxis, ob->rotAngle);
|
|
|
|
|
|
|
|
if (correct_delta) {
|
|
|
|
float dquat[4];
|
|
|
|
axis_angle_to_quat(dquat, ob->drotAxis, ob->drotAngle);
|
|
|
|
|
|
|
|
mul_qt_qtqt(rbo->orn, dquat, qt);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
copy_qt_qt(rbo->orn, qt);
|
|
|
|
}
|
|
|
|
|
2013-01-23 12:06:18 +00:00
|
|
|
copy_v3_v3(ob->rotAxis, rotAxis);
|
|
|
|
ob->rotAngle = rotAngle;
|
|
|
|
}
|
|
|
|
else {
|
2017-07-04 10:12:09 +02:00
|
|
|
if (correct_delta) {
|
|
|
|
mul_qt_qtqt(rbo->orn, ob->dquat, ob->quat);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
copy_qt_qt(rbo->orn, ob->quat);
|
|
|
|
}
|
|
|
|
|
2013-01-23 12:06:18 +00:00
|
|
|
copy_qt_qt(ob->quat, quat);
|
|
|
|
}
|
2017-07-04 10:12:09 +02:00
|
|
|
|
2013-02-04 23:50:38 +00:00
|
|
|
if (rbo->physics_object) {
|
|
|
|
/* allow passive objects to return to original transform */
|
|
|
|
if (rbo->type == RBO_TYPE_PASSIVE)
|
2014-04-01 11:34:00 +11:00
|
|
|
RB_body_set_kinematic_state(rbo->physics_object, true);
|
2013-01-24 03:49:30 +00:00
|
|
|
RB_body_set_loc_rot(rbo->physics_object, rbo->pos, rbo->orn);
|
2013-02-04 23:50:38 +00:00
|
|
|
}
|
2013-01-23 12:06:18 +00:00
|
|
|
// 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)
|
|
|
|
}
|
|
|
|
|
2016-12-28 17:30:58 +01:00
|
|
|
void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw)
|
|
|
|
{
|
2017-07-04 09:20:02 +02:00
|
|
|
if (rbw) {
|
2016-12-28 17:30:58 +01:00
|
|
|
rbw->pointcache->flag |= PTCACHE_OUTDATED;
|
2017-07-04 09:20:02 +02:00
|
|
|
}
|
2016-12-28 17:30:58 +01:00
|
|
|
}
|
|
|
|
|
2013-01-23 05:56:22 +00:00
|
|
|
/* ------------------ */
|
|
|
|
|
2013-03-03 06:09:45 +00:00
|
|
|
/* Rebuild rigid body world */
|
|
|
|
/* NOTE: this needs to be called before frame update to work correctly */
|
2018-06-08 19:26:46 +02:00
|
|
|
void BKE_rigidbody_rebuild_world(Depsgraph *depsgraph, Scene *scene, float ctime)
|
2013-01-23 05:56:22 +00:00
|
|
|
{
|
2013-01-23 05:56:44 +00:00
|
|
|
RigidBodyWorld *rbw = scene->rigidbody_world;
|
2016-12-28 17:30:58 +01:00
|
|
|
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 */
|
2018-06-08 19:26:46 +02:00
|
|
|
int n = 0;
|
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_BEGIN(rbw->group, object)
|
|
|
|
{
|
|
|
|
(void)object;
|
|
|
|
n++;
|
|
|
|
}
|
|
|
|
FOREACH_COLLECTION_OBJECT_RECURSIVE_END;
|
|
|
|
|
|
|
|
if (rbw->physics_world == NULL || rbw->numbodies != n) {
|
2016-12-28 17:30:58 +01:00
|
|
|
cache->flag |= PTCACHE_OUTDATED;
|
|
|
|
}
|
2013-01-23 05:56:44 +00:00
|
|
|
|
2014-01-29 15:02:45 +01:00
|
|
|
if (ctime == startframe + 1 && rbw->ltime == startframe) {
|
2016-12-28 17:30:58 +01:00
|
|
|
if (cache->flag & PTCACHE_OUTDATED) {
|
|
|
|
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
|
2018-04-06 12:07:27 +02:00
|
|
|
rigidbody_update_simulation(depsgraph, scene, rbw, true);
|
2016-12-28 17:30:58 +01:00
|
|
|
BKE_ptcache_validate(cache, (int)ctime);
|
|
|
|
cache->last_exact = 0;
|
|
|
|
cache->flag &= ~PTCACHE_REDO_NEEDED;
|
|
|
|
}
|
2013-01-23 05:56:44 +00:00
|
|
|
}
|
2013-03-03 06:09:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Run RigidBody simulation for the specified physics world */
|
2018-06-08 19:26:46 +02:00
|
|
|
void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime)
|
2013-03-03 06:09:45 +00:00
|
|
|
{
|
|
|
|
float timestep;
|
|
|
|
RigidBodyWorld *rbw = scene->rigidbody_world;
|
2016-12-28 17:30:58 +01:00
|
|
|
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;
|
2013-03-03 06:09:45 +00:00
|
|
|
|
2017-09-05 07:12:30 +02:00
|
|
|
if (ctime <= startframe) {
|
|
|
|
rbw->ltime = startframe;
|
|
|
|
return;
|
|
|
|
}
|
2013-01-23 05:56:44 +00:00
|
|
|
/* make sure we don't go out of cache frame range */
|
2017-09-05 07:12:30 +02:00
|
|
|
else if (ctime > endframe) {
|
2013-01-23 05:56:44 +00:00
|
|
|
ctime = endframe;
|
|
|
|
}
|
|
|
|
|
2016-12-28 17:30:58 +01:00
|
|
|
/* 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))
|
2013-01-23 05:56:44 +00:00
|
|
|
return;
|
|
|
|
else if (rbw->objects == NULL)
|
|
|
|
rigidbody_update_ob_array(rbw);
|
|
|
|
|
2016-12-28 17:30:58 +01:00
|
|
|
/* 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);
|
|
|
|
|
2017-09-05 07:12:30 +02:00
|
|
|
if (BKE_ptcache_read(&pid, ctime, can_simulate) == PTCACHE_READ_EXACT) {
|
2016-12-28 17:30:58 +01:00
|
|
|
BKE_ptcache_validate(cache, (int)ctime);
|
2017-09-05 07:12:30 +02:00
|
|
|
rbw->ltime = ctime;
|
2016-12-28 17:30:58 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-01-23 05:56:44 +00:00
|
|
|
/* advance simulation, we can only step one frame forward */
|
2018-06-19 12:16:18 +02:00
|
|
|
if (compare_ff_relative(ctime, rbw->ltime + 1, FLT_EPSILON, 64)) {
|
2016-12-28 17:30:58 +01:00
|
|
|
/* 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);
|
|
|
|
}
|
|
|
|
|
2013-01-23 05:56:44 +00:00
|
|
|
/* update and validate simulation */
|
2018-04-06 12:07:27 +02:00
|
|
|
rigidbody_update_simulation(depsgraph, scene, rbw, false);
|
2013-01-23 05:56:44 +00:00
|
|
|
|
|
|
|
/* calculate how much time elapsed since last step in seconds */
|
|
|
|
timestep = 1.0f / (float)FPS * (ctime - rbw->ltime) * rbw->time_scale;
|
|
|
|
/* 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));
|
|
|
|
|
2018-06-08 19:26:46 +02:00
|
|
|
rigidbody_update_simulation_post_step(depsgraph, rbw);
|
2013-01-23 12:06:18 +00:00
|
|
|
|
2016-12-28 17:30:58 +01:00
|
|
|
/* write cache for current frame */
|
|
|
|
BKE_ptcache_validate(cache, (int)ctime);
|
|
|
|
BKE_ptcache_write(&pid, (unsigned int)ctime);
|
|
|
|
|
2013-01-23 05:56:44 +00:00
|
|
|
rbw->ltime = ctime;
|
|
|
|
}
|
2013-01-23 05:56:22 +00:00
|
|
|
}
|
|
|
|
/* ************************************** */
|
2013-01-23 07:26:39 +00:00
|
|
|
|
|
|
|
#else /* WITH_BULLET */
|
|
|
|
|
|
|
|
/* stubs */
|
Windows: Add support for building with clang.
This commit contains the minimum to make clang build/work with blender, asan and ninja build support is forthcoming
Things to note:
1) Builds and runs, and is able to pass all tests (except for the freestyle_stroke_material.blend test which was broken at that time for all platforms by the looks of it)
2) It's slightly faster than msvc when using cycles. (time in seconds, on an i7-3370)
victor_cpu
msvc:3099.51
clang:2796.43
pavillon_barcelona_cpu
msvc:1872.05
clang:1827.72
koro_cpu
msvc:1097.58
clang:1006.51
fishy_cat_cpu
msvc:815.37
clang:722.2
classroom_cpu
msvc:1705.39
clang:1575.43
bmw27_cpu
msvc:552.38
clang:561.53
barbershop_interior_cpu
msvc:2134.93
clang:1922.33
3) clang on windows uses a drop in replacement for the Microsoft cl.exe (takes some of the Microsoft parameters, but not all, and takes some of the clang parameters but not all) and uses ms headers + libraries + linker, so you still need visual studio installed and will use our existing vc14 svn libs.
4) X64 only currently, X86 builds but crashes on startup.
5) Tested with llvm/clang 6.0.0
6) Requires visual studio integration, available at https://github.com/LazyDodo/llvm-vs2017-integration
7) The Microsoft compiler spawns a few copies of cl in parallel to get faster build times, clang doesn't, so the build time is 3-4x slower than with msvc.
8) No openmp support yet. Have not looked at this much, the binary distribution of clang doesn't seem to include it on windows.
9) No ASAN support yet, some of the sanitizers can be made to work, but it was decided to leave support out of this commit.
Reviewers: campbellbarton
Differential Revision: https://developer.blender.org/D3304
2018-05-28 14:34:47 -06:00
|
|
|
#if defined(__GNUC__) || defined(__clang__)
|
2013-01-23 07:26:39 +00:00
|
|
|
# pragma GCC diagnostic push
|
|
|
|
# pragma GCC diagnostic ignored "-Wunused-parameter"
|
|
|
|
#endif
|
|
|
|
|
2017-08-07 20:11:19 +02:00
|
|
|
struct RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob, const int flag) { return NULL; }
|
|
|
|
struct RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob, const int flag) { return NULL; }
|
2013-12-26 21:30:53 +01:00
|
|
|
void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, bool rebuild) {}
|
2014-07-11 12:06:13 +02:00
|
|
|
void BKE_rigidbody_calc_volume(Object *ob, float *r_vol) { if (r_vol) *r_vol = 0.0f; }
|
2015-07-20 05:19:47 +10:00
|
|
|
void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3]) { zero_v3(r_center); }
|
2013-01-23 07:26:39 +00:00
|
|
|
struct RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene) { return NULL; }
|
2017-08-07 20:11:19 +02:00
|
|
|
struct RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw, const int flag) { return NULL; }
|
2013-04-24 23:09:25 +00:00
|
|
|
void BKE_rigidbody_world_groups_relink(struct RigidBodyWorld *rbw) {}
|
2015-10-08 21:01:44 +05:00
|
|
|
void BKE_rigidbody_world_id_loop(struct RigidBodyWorld *rbw, RigidbodyWorldIDFunc func, void *userdata) {}
|
2013-01-23 07:26:39 +00:00
|
|
|
struct RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type) { return NULL; }
|
|
|
|
struct RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short type) { return NULL; }
|
|
|
|
struct RigidBodyWorld *BKE_rigidbody_get_world(Scene *scene) { return NULL; }
|
2018-06-19 16:18:23 +02:00
|
|
|
void BKE_rigidbody_remove_object(struct Main *bmain, Scene *scene, Object *ob) {}
|
2013-01-23 07:26:39 +00:00
|
|
|
void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob) {}
|
2013-02-17 03:57:20 +00:00
|
|
|
void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) {}
|
2013-01-23 14:55:41 +00:00
|
|
|
void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) {}
|
2013-04-07 14:09:29 +00:00
|
|
|
bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime) { return false; }
|
2016-12-28 17:30:58 +01:00
|
|
|
void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) {}
|
2018-06-08 19:26:46 +02:00
|
|
|
void BKE_rigidbody_rebuild_world(Depsgraph *depsgraph, Scene *scene, float ctime) {}
|
|
|
|
void BKE_rigidbody_do_simulation(Depsgraph *depsgraph, Scene *scene, float ctime) {}
|
2013-01-23 07:26:39 +00:00
|
|
|
|
Windows: Add support for building with clang.
This commit contains the minimum to make clang build/work with blender, asan and ninja build support is forthcoming
Things to note:
1) Builds and runs, and is able to pass all tests (except for the freestyle_stroke_material.blend test which was broken at that time for all platforms by the looks of it)
2) It's slightly faster than msvc when using cycles. (time in seconds, on an i7-3370)
victor_cpu
msvc:3099.51
clang:2796.43
pavillon_barcelona_cpu
msvc:1872.05
clang:1827.72
koro_cpu
msvc:1097.58
clang:1006.51
fishy_cat_cpu
msvc:815.37
clang:722.2
classroom_cpu
msvc:1705.39
clang:1575.43
bmw27_cpu
msvc:552.38
clang:561.53
barbershop_interior_cpu
msvc:2134.93
clang:1922.33
3) clang on windows uses a drop in replacement for the Microsoft cl.exe (takes some of the Microsoft parameters, but not all, and takes some of the clang parameters but not all) and uses ms headers + libraries + linker, so you still need visual studio installed and will use our existing vc14 svn libs.
4) X64 only currently, X86 builds but crashes on startup.
5) Tested with llvm/clang 6.0.0
6) Requires visual studio integration, available at https://github.com/LazyDodo/llvm-vs2017-integration
7) The Microsoft compiler spawns a few copies of cl in parallel to get faster build times, clang doesn't, so the build time is 3-4x slower than with msvc.
8) No openmp support yet. Have not looked at this much, the binary distribution of clang doesn't seem to include it on windows.
9) No ASAN support yet, some of the sanitizers can be made to work, but it was decided to leave support out of this commit.
Reviewers: campbellbarton
Differential Revision: https://developer.blender.org/D3304
2018-05-28 14:34:47 -06:00
|
|
|
#if defined(__GNUC__) || defined(__clang__)
|
2013-01-23 07:26:39 +00:00
|
|
|
# pragma GCC diagnostic pop
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif /* WITH_BULLET */
|
2015-05-12 13:57:11 +05:00
|
|
|
|
2018-06-19 11:33:48 +02:00
|
|
|
|
|
|
|
/* Copy the pointcache from the evaluated to the original scene.
|
|
|
|
* This allows the re-evaluation of the original scene to use the
|
|
|
|
* physics cache.
|
|
|
|
*/
|
|
|
|
static void rigidbody_copy_cache_to_orig(Scene *scene_eval)
|
|
|
|
{
|
|
|
|
if ((scene_eval->id.tag & LIB_TAG_COPIED_ON_WRITE) == 0) {
|
|
|
|
/* Scene is already an original, this function is a no-op. */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Scene *scene_orig = (Scene *)DEG_get_original_id(&scene_eval->id);
|
|
|
|
RigidBodyWorld *rbw_orig = scene_orig->rigidbody_world;
|
|
|
|
RigidBodyWorld *rbw_eval = scene_eval->rigidbody_world;
|
|
|
|
|
|
|
|
BKE_ptcache_free_list(&rbw_orig->ptcaches);
|
|
|
|
rbw_orig->pointcache = BKE_ptcache_copy_list(&rbw_orig->ptcaches, &rbw_eval->ptcaches, LIB_ID_COPY_CACHES);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-05-12 13:57:11 +05:00
|
|
|
/* -------------------- */
|
|
|
|
/* Depsgraph evaluation */
|
|
|
|
|
2018-06-08 19:26:46 +02:00
|
|
|
void BKE_rigidbody_rebuild_sim(Depsgraph *depsgraph,
|
2015-05-12 13:57:11 +05:00
|
|
|
Scene *scene)
|
|
|
|
{
|
2018-05-18 18:04:27 +02:00
|
|
|
float ctime = DEG_get_ctime(depsgraph);
|
2018-05-02 11:46:56 +02:00
|
|
|
DEG_debug_print_eval_time(depsgraph, __func__, scene->id.name, scene, ctime);
|
2015-05-12 13:57:11 +05:00
|
|
|
/* rebuild sim data (i.e. after resetting to start of timeline) */
|
|
|
|
if (BKE_scene_check_rigidbody_active(scene)) {
|
2018-04-06 12:07:27 +02:00
|
|
|
BKE_rigidbody_rebuild_world(depsgraph, scene, ctime);
|
2015-05-12 13:57:11 +05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-08 19:26:46 +02:00
|
|
|
void BKE_rigidbody_eval_simulation(Depsgraph *depsgraph,
|
2015-05-12 13:57:11 +05:00
|
|
|
Scene *scene)
|
|
|
|
{
|
2018-05-18 18:04:27 +02:00
|
|
|
float ctime = DEG_get_ctime(depsgraph);
|
2018-05-02 11:46:56 +02:00
|
|
|
DEG_debug_print_eval_time(depsgraph, __func__, scene->id.name, scene, ctime);
|
2018-06-19 11:33:48 +02:00
|
|
|
|
2015-05-12 13:57:11 +05:00
|
|
|
/* evaluate rigidbody sim */
|
2018-06-19 11:33:48 +02:00
|
|
|
if (!BKE_scene_check_rigidbody_active(scene)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
BKE_rigidbody_do_simulation(depsgraph, scene, ctime);
|
|
|
|
|
|
|
|
/* Make sure re-evaluation can use the cache from this simulation */
|
|
|
|
if (!DEG_is_active(depsgraph)) {
|
|
|
|
return;
|
2015-05-12 13:57:11 +05:00
|
|
|
}
|
2018-06-19 11:33:48 +02:00
|
|
|
rigidbody_copy_cache_to_orig(scene);
|
2015-05-12 13:57:11 +05:00
|
|
|
}
|
|
|
|
|
2018-06-08 19:26:46 +02:00
|
|
|
void BKE_rigidbody_object_sync_transforms(Depsgraph *depsgraph,
|
2015-05-12 13:57:11 +05:00
|
|
|
Scene *scene,
|
|
|
|
Object *ob)
|
|
|
|
{
|
|
|
|
RigidBodyWorld *rbw = scene->rigidbody_world;
|
2018-05-18 18:04:27 +02:00
|
|
|
float ctime = DEG_get_ctime(depsgraph);
|
2018-05-02 11:46:56 +02:00
|
|
|
DEG_debug_print_eval_time(depsgraph, __func__, ob->id.name, ob, ctime);
|
2015-05-12 13:57:11 +05:00
|
|
|
/* read values pushed into RBO from sim/cache... */
|
|
|
|
BKE_rigidbody_sync_transforms(rbw, ob, ctime);
|
|
|
|
}
|