summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/io/http_client.cpp6
-rw-r--r--core/variant_call.cpp6
-rw-r--r--doc/classes/Navigation.xml2
-rw-r--r--doc/classes/ProjectSettings.xml2
-rw-r--r--doc/classes/String.xml21
-rwxr-xr-xdoc/tools/makerst.py47
-rw-r--r--drivers/gles2/rasterizer_scene_gles2.cpp19
-rw-r--r--drivers/gles2/rasterizer_storage_gles2.cpp8
-rw-r--r--editor/code_editor.cpp18
-rw-r--r--editor/code_editor.h1
-rw-r--r--editor/connections_dialog.cpp70
-rw-r--r--editor/connections_dialog.h8
-rw-r--r--editor/dependency_editor.cpp2
-rw-r--r--editor/editor_file_dialog.cpp9
-rw-r--r--editor/editor_file_dialog.h1
-rw-r--r--editor/editor_help.cpp3
-rw-r--r--editor/editor_inspector.cpp5
-rw-r--r--editor/plugins/asset_library_editor_plugin.cpp4
-rw-r--r--editor/plugins/script_editor_plugin.cpp11
-rw-r--r--editor/plugins/script_editor_plugin.h1
-rw-r--r--editor/plugins/script_text_editor.cpp5
-rw-r--r--editor/plugins/script_text_editor.h1
-rw-r--r--editor/plugins/text_editor.cpp5
-rw-r--r--editor/plugins/text_editor.h1
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp6
-rw-r--r--editor/scene_tree_editor.cpp25
-rw-r--r--editor/scene_tree_editor.h2
-rw-r--r--modules/bullet/SCsub6
-rw-r--r--modules/gdscript/gdscript_parser.cpp44
-rw-r--r--modules/mono/build_scripts/patches/fix-mono-android-pthread_mutexattr_setprotocol.diff13
-rw-r--r--modules/visual_script/visual_script_editor.cpp3
-rw-r--r--modules/visual_script/visual_script_editor.h1
-rw-r--r--platform/server/detect.py6
-rw-r--r--platform/uwp/export/export.cpp4
-rw-r--r--platform/x11/detect.py6
-rw-r--r--platform/x11/os_x11.cpp27
-rw-r--r--scene/2d/animated_sprite.cpp1
-rw-r--r--scene/2d/cpu_particles_2d.h2
-rw-r--r--scene/2d/line_2d.cpp1
-rw-r--r--scene/2d/tile_map.cpp7
-rw-r--r--scene/gui/line_edit.cpp2
-rw-r--r--scene/gui/text_edit.cpp2
-rw-r--r--thirdparty/README.md2
-rw-r--r--thirdparty/bullet/Bullet3Common/b3Quaternion.h5
-rw-r--r--thirdparty/bullet/Bullet3Common/b3Vector3.h2
-rw-r--r--thirdparty/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp5
-rw-r--r--thirdparty/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp4
-rw-r--r--thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionObject.cpp1
-rw-r--r--thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h12
-rw-r--r--thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp14
-rw-r--r--thirdparty/bullet/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp6
-rw-r--r--thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp206
-rw-r--r--thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h27
-rw-r--r--thirdparty/bullet/BulletCollision/Gimpact/btGImpactBvhStructs.h23
-rw-r--r--thirdparty/bullet/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp16
-rw-r--r--thirdparty/bullet/BulletCollision/Gimpact/btGImpactShape.h2
-rw-r--r--thirdparty/bullet/BulletCollision/Gimpact/gim_box_set.h23
-rw-r--r--thirdparty/bullet/BulletCollision/Gimpact/gim_pair.h28
-rw-r--r--thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btConvexCast.h12
-rw-r--r--thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp2
-rw-r--r--thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h1
-rw-r--r--thirdparty/bullet/BulletDynamics/ConstraintSolver/btBatchedConstraints.cpp4
-rw-r--r--thirdparty/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp5
-rw-r--r--thirdparty/bullet/BulletDynamics/ConstraintSolver/btConstraintSolver.h1
-rw-r--r--thirdparty/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h2
-rw-r--r--thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp13
-rw-r--r--thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h2
-rw-r--r--thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp877
-rw-r--r--thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h164
-rw-r--r--thirdparty/bullet/BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp4
-rw-r--r--thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp15
-rw-r--r--thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h45
-rw-r--r--thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp86
-rw-r--r--thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h5
-rw-r--r--thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp37
-rw-r--r--thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h2
-rw-r--r--thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyLinkCollider.h4
-rw-r--r--thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.cpp12
-rw-r--r--thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.h2
-rw-r--r--thirdparty/bullet/BulletDynamics/MLCPSolvers/btLemkeSolver.h6
-rw-r--r--thirdparty/bullet/BulletInverseDynamics/MultiBodyTree.cpp2
-rw-r--r--thirdparty/bullet/BulletInverseDynamics/details/MultiBodyTreeImpl.cpp33
-rw-r--r--thirdparty/bullet/BulletSoftBody/btSoftBody.cpp4
-rw-r--r--thirdparty/bullet/LinearMath/TaskScheduler/btThreadSupportPosix.cpp6
-rw-r--r--thirdparty/bullet/LinearMath/btAlignedObjectArray.h15
-rw-r--r--thirdparty/bullet/LinearMath/btMatrixX.h7
-rw-r--r--thirdparty/bullet/LinearMath/btScalar.h4
-rw-r--r--thirdparty/bullet/LinearMath/btVector3.h2
-rw-r--r--thirdparty/bullet/btBulletCollisionAll.cpp96
-rw-r--r--thirdparty/bullet/btBulletDynamicsAll.cpp42
-rw-r--r--thirdparty/bullet/btLinearMathAll.cpp14
91 files changed, 1749 insertions, 567 deletions
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index ce2054db36..891fb7b0ca 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -346,6 +346,12 @@ Error HTTPClient::poll() {
} else {
// We are already handshaking, which means we can use your already active SSL connection
ssl = static_cast<Ref<StreamPeerSSL> >(connection);
+ if (ssl.is_null()) {
+ close();
+ status = STATUS_SSL_HANDSHAKE_ERROR;
+ return ERR_CANT_CONNECT;
+ }
+
ssl->poll(); // Try to finish the handshake
}
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index 24f12df5db..b3a4a13b08 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -1519,9 +1519,9 @@ void register_variant_methods() {
ADDFUNC2R(STRING, STRING, String, replacen, STRING, "what", STRING, "forwhat", varray());
ADDFUNC2R(STRING, STRING, String, insert, INT, "position", STRING, "what", varray());
ADDFUNC0R(STRING, STRING, String, capitalize, varray());
- ADDFUNC3R(STRING, POOL_STRING_ARRAY, String, split, STRING, "divisor", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0));
- ADDFUNC3R(STRING, POOL_STRING_ARRAY, String, rsplit, STRING, "divisor", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0));
- ADDFUNC2R(STRING, POOL_REAL_ARRAY, String, split_floats, STRING, "divisor", BOOL, "allow_empty", varray(true));
+ ADDFUNC3R(STRING, POOL_STRING_ARRAY, String, split, STRING, "delimiter", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0));
+ ADDFUNC3R(STRING, POOL_STRING_ARRAY, String, rsplit, STRING, "delimiter", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0));
+ ADDFUNC2R(STRING, POOL_REAL_ARRAY, String, split_floats, STRING, "delimiter", BOOL, "allow_empty", varray(true));
ADDFUNC0R(STRING, STRING, String, to_upper, varray());
ADDFUNC0R(STRING, STRING, String, to_lower, varray());
diff --git a/doc/classes/Navigation.xml b/doc/classes/Navigation.xml
index 3690c1d682..f0ae3fef99 100644
--- a/doc/classes/Navigation.xml
+++ b/doc/classes/Navigation.xml
@@ -59,7 +59,7 @@
<argument index="2" name="optimize" type="bool" default="true">
</argument>
<description>
- Returns the path between two given points. Points are in local coordinate space. If [code]optimize[/code] is [code]true[/code] (the default), the agent properties associated with each [NavigationMesh] (raidus, height, etc.) are considered in the path calculation, otherwise they are ignored.
+ Returns the path between two given points. Points are in local coordinate space. If [code]optimize[/code] is [code]true[/code] (the default), the agent properties associated with each [NavigationMesh] (radius, height, etc.) are considered in the path calculation, otherwise they are ignored.
</description>
</method>
<method name="navmesh_add">
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 5bcd39a8d6..460db5e792 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -723,7 +723,7 @@
Shaders have a time variable that constantly increases. At some point, it needs to be rolled back to zero to avoid precision errors on shader animations. This setting specifies when (in seconds).
</member>
<member name="rendering/quality/2d/gles2_use_nvidia_rect_flicker_workaround" type="bool" setter="" getter="">
- Some NVIDIA GPU drivers have a bug which produces flickering issues for the [code]draw_rect[/code] method, especially as used in [TileMap]. Refer to [url=https://github.com/godotengine/godot/issues/9913][/url] for details.
+ Some NVIDIA GPU drivers have a bug which produces flickering issues for the [code]draw_rect[/code] method, especially as used in [TileMap]. Refer to [url=https://github.com/godotengine/godot/issues/9913]GitHub issue 9913[/url] for details.
If [code]true[/code], this option enables a "safe" code path for such NVIDIA GPUs at the cost of performance. This option only impacts the GLES2 rendering backend (so the bug stays if you use GLES3), and only desktop platforms.
</member>
<member name="rendering/quality/2d/use_pixel_snap" type="bool" setter="" getter="">
diff --git a/doc/classes/String.xml b/doc/classes/String.xml
index a5a8766ca0..af7e5a395a 100644
--- a/doc/classes/String.xml
+++ b/doc/classes/String.xml
@@ -662,16 +662,17 @@
<method name="rsplit">
<return type="PoolStringArray">
</return>
- <argument index="0" name="divisor" type="String">
+ <argument index="0" name="delimiter" type="String">
</argument>
<argument index="1" name="allow_empty" type="bool" default="True">
</argument>
<argument index="2" name="maxsplit" type="int" default="0">
</argument>
<description>
- Splits the string by a [code]divisor[/code] string and returns an array of the substrings, starting from right.
- [b]Example:[/b] [code]"One,Two,Three"[/code] will return [code]["One","Two","Three"][/code] if split by [code]","[/code].
- If [code]maxsplit[/code] is specified, then it is number of splits to do, default is 0 which splits all the items.
+ Splits the string by a [code]delimiter[/code] string and returns an array of the substrings, starting from right.
+ The splits in the returned array are sorted in the same order as the original string, from left to right.
+ If [code]maxsplit[/code] is specified, it defines the number of splits to do from the right up to [code]maxsplit[/code]. The default value of 0 means that all items are split, thus giving the same result as [method split].
+ [b]Example:[/b] [code]"One,Two,Three,Four"[/code] will return [code]["Three","Four"][/code] if split by [code]","[/code] with [code]maxsplit[/code] of 2.
</description>
</method>
<method name="rstrip">
@@ -709,27 +710,27 @@
<method name="split">
<return type="PoolStringArray">
</return>
- <argument index="0" name="divisor" type="String">
+ <argument index="0" name="delimiter" type="String">
</argument>
<argument index="1" name="allow_empty" type="bool" default="True">
</argument>
<argument index="2" name="maxsplit" type="int" default="0">
</argument>
<description>
- Splits the string by a divisor string and returns an array of the substrings.
- [b]Example:[/b] [code]"One,Two,Three"[/code] will return [code]["One","Two","Three"][/code] if split by [code]","[/code].
- If [code]maxsplit[/code] is given, at most maxsplit number of splits occur, and the remainder of the string is returned as the final element of the list (thus, the list will have at most maxsplit+1 elements)
+ Splits the string by a [code]delimiter[/code] string and returns an array of the substrings.
+ If [code]maxsplit[/code] is specified, it defines the number of splits to do from the left up to [code]maxsplit[/code]. The default value of 0 means that all items are split.
+ [b]Example:[/b] [code]"One,Two,Three"[/code] will return [code]["One","Two"][/code] if split by [code]","[/code] with [code]maxsplit[/code] of 2.
</description>
</method>
<method name="split_floats">
<return type="PoolRealArray">
</return>
- <argument index="0" name="divisor" type="String">
+ <argument index="0" name="delimiter" type="String">
</argument>
<argument index="1" name="allow_empty" type="bool" default="True">
</argument>
<description>
- Splits the string in floats by using a divisor string and returns an array of the substrings.
+ Splits the string in floats by using a delimiter string and returns an array of the substrings.
[b]Example:[/b] [code]"1,2.5,3"[/code] will return [code][1,2.5,3][/code] if split by [code]","[/code].
</description>
</method>
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
index c3e15b2f9a..454c71d3c7 100755
--- a/doc/tools/makerst.py
+++ b/doc/tools/makerst.py
@@ -478,24 +478,7 @@ def make_rst_class(class_def, state, dry_run, output_dir): # type: (ClassDef, S
f.write(make_heading('Tutorials', '-'))
for t in class_def.tutorials:
link = t.strip()
- match = GODOT_DOCS_PATTERN.search(link)
- if match:
- groups = match.groups()
- if match.lastindex == 2:
- # Doc reference with fragment identifier: emit direct link to section with reference to page, for example:
- # `#calling-javascript-from-script in Exporting For Web`
- f.write("- `" + groups[1] + " <../" + groups[0] + ".html" + groups[1] + ">`_ in :doc:`../" + groups[0] + "`\n\n")
- # Commented out alternative: Instead just emit:
- # `Subsection in Exporting For Web`
- # f.write("- `Subsection <../" + groups[0] + ".html" + groups[1] + ">`_ in :doc:`../" + groups[0] + "`\n\n")
- elif match.lastindex == 1:
- # Doc reference, for example:
- # `Math`
- f.write("- :doc:`../" + groups[0] + "`\n\n")
- else:
- # External link, for example:
- # `http://enet.bespin.org/usergroup0.html`
- f.write("- `" + link + " <" + link + ">`_\n\n")
+ f.write("- " + make_url(link) + "\n\n")
# Property descriptions
if len(class_def.properties) > 0:
@@ -802,15 +785,16 @@ def rstize_text(text, state): # type: (str, State) -> str
tag_text = "" # '![](' + cmd[6:] + ')'
elif cmd.find('url=') == 0:
url_link = cmd[4:]
- tag_text = ':ref:`'
+ tag_text = '`'
tag_depth += 1
- url_has_name = False
inside_url = True
+ url_has_name = False
elif cmd == '/url':
- tag_text = ('' if url_has_name else url_link) + '<' + url_link + ">`"
+ tag_text = ('' if url_has_name else url_link) + " <" + url_link + ">`_"
tag_depth -= 1
escape_post = True
inside_url = False
+ url_has_name = False
elif cmd == 'center':
tag_depth += 1
tag_text = ''
@@ -996,5 +980,26 @@ def make_heading(title, underline): # type: (str, str) -> str
return title + '\n' + (underline * len(title)) + "\n\n"
+def make_url(link): # type: (str) -> str
+ match = GODOT_DOCS_PATTERN.search(link)
+ if match:
+ groups = match.groups()
+ if match.lastindex == 2:
+ # Doc reference with fragment identifier: emit direct link to section with reference to page, for example:
+ # `#calling-javascript-from-script in Exporting For Web`
+ return "`" + groups[1] + " <../" + groups[0] + ".html" + groups[1] + ">`_ in :doc:`../" + groups[0] + "`"
+ # Commented out alternative: Instead just emit:
+ # `Subsection in Exporting For Web`
+ # return "`Subsection <../" + groups[0] + ".html" + groups[1] + ">`__ in :doc:`../" + groups[0] + "`"
+ elif match.lastindex == 1:
+ # Doc reference, for example:
+ # `Math`
+ return ":doc:`../" + groups[0] + "`"
+ else:
+ # External link, for example:
+ # `http://enet.bespin.org/usergroup0.html`
+ return "`" + link + " <" + link + ">`_"
+
+
if __name__ == '__main__':
main()
diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp
index 50cb39b13f..35694f000c 100644
--- a/drivers/gles2/rasterizer_scene_gles2.cpp
+++ b/drivers/gles2/rasterizer_scene_gles2.cpp
@@ -2931,14 +2931,16 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
#elif IPHONE_ENABLED
+
glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->multisample_fbo);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo);
glResolveMultisampleFramebufferAPPLE();
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
-#else
- // In GLES2 Blit is not available, so just copy color texture manually
+#elif ANDROID_ENABLED
+
+ // In GLES2 AndroidBlit is not available, so just copy color texture manually
_copy_texture_to_front_buffer(storage->frame.current_rt->multisample_color);
#endif
}
@@ -2972,8 +2974,17 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
-#else
- // In GLES2 Blit is not available, so just copy color texture manually
+#elif IPHONE_ENABLED
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->multisample_fbo);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->fbo);
+ glResolveMultisampleFramebufferAPPLE();
+
+ glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
+#elif ANDROID_ENABLED
+
+ // In GLES2 Android Blit is not available, so just copy color texture manually
_copy_texture_to_front_buffer(storage->frame.current_rt->multisample_color);
#endif
}
diff --git a/drivers/gles2/rasterizer_storage_gles2.cpp b/drivers/gles2/rasterizer_storage_gles2.cpp
index c610f31bc1..7b5f193b2b 100644
--- a/drivers/gles2/rasterizer_storage_gles2.cpp
+++ b/drivers/gles2/rasterizer_storage_gles2.cpp
@@ -91,7 +91,7 @@ GLuint RasterizerStorageGLES2::system_fbo = 0;
//void *glRenderbufferStorageMultisampleAPPLE;
//void *glResolveMultisampleFramebufferAPPLE;
#define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleAPPLE
-#else
+#elif ANDROID_ENABLED
#include <GLES2/gl2ext.h>
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT;
@@ -4719,7 +4719,7 @@ void RasterizerStorageGLES2::_render_target_allocate(RenderTarget *rt) {
glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, color_internal_format, rt->width, rt->height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rt->multisample_color);
-#else
+#elif ANDROID_ENABLED
// Render to a texture in android
glGenTextures(1, &rt->multisample_color);
glBindTexture(GL_TEXTURE_2D, rt->multisample_color);
@@ -5602,11 +5602,11 @@ void RasterizerStorageGLES2::initialize() {
//Manually load extensions for android and ios
#ifdef IPHONE_ENABLED
-
+ // appears that IPhone doesn't need to dlopen TODO: test this rigorously before removing
//void *gles2_lib = dlopen(NULL, RTLD_LAZY);
//glRenderbufferStorageMultisampleAPPLE = dlsym(gles2_lib, "glRenderbufferStorageMultisampleAPPLE");
//glResolveMultisampleFramebufferAPPLE = dlsym(gles2_lib, "glResolveMultisampleFramebufferAPPLE");
-#else
+#elif ANDROID_ENABLED
void *gles2_lib = dlopen("libGLESv2.so", RTLD_LAZY);
glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)dlsym(gles2_lib, "glRenderbufferStorageMultisampleEXT");
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index 33adb33c8c..4a440510db 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -804,6 +804,24 @@ void CodeTextEditor::trim_trailing_whitespace() {
}
}
+void CodeTextEditor::insert_final_newline() {
+ int final_line = text_editor->get_line_count() - 1;
+
+ String line = text_editor->get_line(final_line);
+
+ //length 0 means it's already an empty line,
+ //no need to add a newline
+ if (line.length() > 0 && !line.ends_with("\n")) {
+ text_editor->begin_complex_operation();
+
+ line += "\n";
+ text_editor->set_line(final_line, line);
+
+ text_editor->end_complex_operation();
+ text_editor->update();
+ }
+}
+
void CodeTextEditor::convert_indent_to_spaces() {
int indent_size = EditorSettings::get_singleton()->get("text_editor/indent/size");
String indent = "";
diff --git a/editor/code_editor.h b/editor/code_editor.h
index 5c6b54ae44..cf97f30b72 100644
--- a/editor/code_editor.h
+++ b/editor/code_editor.h
@@ -195,6 +195,7 @@ protected:
public:
void trim_trailing_whitespace();
+ void insert_final_newline();
void convert_indent_to_spaces();
void convert_indent_to_tabs();
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index a9a96da7b1..82fc8e5cfa 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -307,39 +307,42 @@ void ConnectDialog::init(Connection c, bool bEdit) {
bEditMode = bEdit;
}
-void ConnectDialog::popup_dialog(const String &p_for_signal, bool p_advanced) {
+void ConnectDialog::popup_dialog(const String &p_for_signal) {
- advanced->set_pressed(p_advanced);
from_signal->set_text(p_for_signal);
error_label->add_color_override("font_color", get_color("error_color", "Editor"));
- vbc_right->set_visible(p_advanced);
+ if (!advanced->is_pressed())
+ error_label->set_visible(!_find_first_script(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root()));
- if (p_advanced) {
+ popup_centered();
+}
+
+void ConnectDialog::_advanced_pressed() {
- popup_centered(Size2(900, 500) * EDSCALE);
- connect_to_label->set_text("Connect to Node:");
+ if (advanced->is_pressed()) {
+ set_custom_minimum_size(Size2(900, 500) * EDSCALE);
+ connect_to_label->set_text(TTR("Connect to Node:"));
tree->set_connect_to_script_mode(false);
+
+ vbc_right->show();
error_label->hide();
} else {
- popup_centered(Size2(700, 500) * EDSCALE);
- connect_to_label->set_text("Connect to Script:");
+ set_custom_minimum_size(Size2(600, 500) * EDSCALE);
+ set_size(Size2());
+ connect_to_label->set_text(TTR("Connect to Script:"));
tree->set_connect_to_script_mode(true);
- if (!_find_first_script(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root())) {
- error_label->show();
- } else {
- error_label->hide();
- }
+ vbc_right->hide();
+ error_label->set_visible(!_find_first_script(get_tree()->get_edited_scene_root(), get_tree()->get_edited_scene_root()));
}
-}
-void ConnectDialog::_advanced_pressed() {
-
- popup_dialog(from_signal->get_text(), advanced->is_pressed());
+ set_position((get_viewport_rect().size - get_custom_minimum_size()) / 2);
}
ConnectDialog::ConnectDialog() {
+ set_custom_minimum_size(Size2(600, 500) * EDSCALE);
+
VBoxContainer *vbc = memnew(VBoxContainer);
add_child(vbc);
@@ -356,6 +359,7 @@ ConnectDialog::ConnectDialog() {
vbc_left->add_margin_child(TTR("From Signal:"), from_signal);
tree = memnew(SceneTreeEditor(false));
+ tree->set_connecting_signal(true);
tree->get_scene_tree()->connect("item_activated", this, "_ok");
tree->connect("node_selected", this, "_tree_node_selected");
tree->set_connect_to_script_mode(true);
@@ -381,7 +385,7 @@ ConnectDialog::ConnectDialog() {
type_list->add_item("bool", Variant::BOOL);
type_list->add_item("int", Variant::INT);
type_list->add_item("real", Variant::REAL);
- type_list->add_item("string", Variant::STRING);
+ type_list->add_item("String", Variant::STRING);
type_list->add_item("Vector2", Variant::VECTOR2);
type_list->add_item("Rect2", Variant::RECT2);
type_list->add_item("Vector3", Variant::VECTOR3);
@@ -416,28 +420,26 @@ ConnectDialog::ConnectDialog() {
dst_method->set_h_size_flags(SIZE_EXPAND_FILL);
dstm_hb->add_child(dst_method);
- advanced = memnew(CheckBox);
+ advanced = memnew(CheckButton);
dstm_hb->add_child(advanced);
- advanced->set_text(TTR("Advanced..."));
+ advanced->set_text(TTR("Advanced"));
advanced->connect("pressed", this, "_advanced_pressed");
- /*
- dst_method_list = memnew( MenuButton );
- dst_method_list->set_text("List...");
- dst_method_list->set_anchor( MARGIN_RIGHT, ANCHOR_END );
- dst_method_list->set_anchor( MARGIN_LEFT, ANCHOR_END );
- dst_method_list->set_anchor( MARGIN_TOP, ANCHOR_END );
- dst_method_list->set_anchor( MARGIN_BOTTOM, ANCHOR_END );
- dst_method_list->set_begin( Point2( 70,59) );
- dst_method_list->set_end( Point2( 15,39 ) );
- */
+ // Add spacing so the tree and inspector are the same size.
+ Control *spacing = memnew(Control);
+ spacing->set_custom_minimum_size(Size2(0, 4) * EDSCALE);
+ vbc_right->add_child(spacing);
- deferred = memnew(CheckButton);
+ deferred = memnew(CheckBox);
+ deferred->set_h_size_flags(0);
deferred->set_text(TTR("Deferred"));
+ deferred->set_tooltip(TTR("Defers the signal, storing it in a queue and only firing it at idle time."));
vbc_right->add_child(deferred);
- oneshot = memnew(CheckButton);
+ oneshot = memnew(CheckBox);
+ oneshot->set_h_size_flags(0);
oneshot->set_text(TTR("Oneshot"));
+ oneshot->set_tooltip(TTR("Disconnects the signal after its first emission."));
vbc_right->add_child(oneshot);
set_as_toplevel(true);
@@ -662,9 +664,7 @@ void ConnectionsDock::_open_connection_dialog(TreeItem &item) {
c.signal = StringName(signalname);
c.target = dst_node;
c.method = dst_method;
-
- //connect_dialog->set_title(TTR("Connect Signal: ") + signalname);
- connect_dialog->popup_dialog(signalname, false);
+ connect_dialog->popup_dialog(signalname);
connect_dialog->init(c);
connect_dialog->set_title(TTR("Connect a Signal to a Method"));
}
diff --git a/editor/connections_dialog.h b/editor/connections_dialog.h
index 9b35d84426..94f1510810 100644
--- a/editor/connections_dialog.h
+++ b/editor/connections_dialog.h
@@ -67,9 +67,9 @@ class ConnectDialog : public ConfirmationDialog {
AcceptDialog *error;
EditorInspector *bind_editor;
OptionButton *type_list;
- CheckButton *deferred;
- CheckButton *oneshot;
- CheckBox *advanced;
+ CheckBox *deferred;
+ CheckBox *oneshot;
+ CheckButton *advanced;
Label *error_label;
@@ -99,7 +99,7 @@ public:
void init(Connection c, bool bEdit = false);
- void popup_dialog(const String &p_for_signal, bool p_advanced);
+ void popup_dialog(const String &p_for_signal);
ConnectDialog();
~ConnectDialog();
};
diff --git a/editor/dependency_editor.cpp b/editor/dependency_editor.cpp
index bde73e9268..cc9e2c12e8 100644
--- a/editor/dependency_editor.cpp
+++ b/editor/dependency_editor.cpp
@@ -725,7 +725,7 @@ bool OrphanResourcesDialog::_fill_owners(EditorFileSystemDirectory *efsd, HashMa
int ds = efsd->get_file_deps(i).size();
ti->set_text(1, itos(ds));
if (ds) {
- ti->add_button(1, get_icon("GuiVisibilityVisible", "EditorIcons"));
+ ti->add_button(1, get_icon("GuiVisibilityVisible", "EditorIcons"), -1, false, TTR("Show Dependencies"));
}
ti->set_metadata(0, path);
has_children = true;
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index 3d198dec67..1a293adb4b 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -1253,6 +1253,12 @@ void EditorFileDialog::_favorite_toggled(bool p_toggle) {
_update_favorites();
}
+void EditorFileDialog::_favorite_pressed() {
+
+ favorite->set_pressed(!favorite->is_pressed());
+ _favorite_toggled(favorite->is_pressed());
+}
+
void EditorFileDialog::_recent_selected(int p_idx) {
Vector<String> recentd = EditorSettings::get_singleton()->get_recent_dirs();
@@ -1376,6 +1382,7 @@ void EditorFileDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("_go_up"), &EditorFileDialog::_go_up);
ClassDB::bind_method(D_METHOD("_favorite_toggled"), &EditorFileDialog::_favorite_toggled);
+ ClassDB::bind_method(D_METHOD("_favorite_pressed"), &EditorFileDialog::_favorite_pressed);
ClassDB::bind_method(D_METHOD("_favorite_selected"), &EditorFileDialog::_favorite_selected);
ClassDB::bind_method(D_METHOD("_favorite_move_up"), &EditorFileDialog::_favorite_move_up);
ClassDB::bind_method(D_METHOD("_favorite_move_down"), &EditorFileDialog::_favorite_move_down);
@@ -1519,7 +1526,7 @@ EditorFileDialog::EditorFileDialog() {
favorite->set_flat(true);
favorite->set_toggle_mode(true);
favorite->set_tooltip(TTR("(Un)favorite current folder."));
- favorite->connect("toggled", this, "_favorite_toggled");
+ favorite->connect("pressed", this, "_favorite_pressed");
pathhb->add_child(favorite);
Ref<ButtonGroup> view_mode_group;
diff --git a/editor/editor_file_dialog.h b/editor/editor_file_dialog.h
index edaccac51d..529aaa71de 100644
--- a/editor/editor_file_dialog.h
+++ b/editor/editor_file_dialog.h
@@ -151,6 +151,7 @@ private:
void _update_favorites();
void _favorite_toggled(bool p_toggle);
+ void _favorite_pressed();
void _favorite_selected(int p_idx);
void _favorite_move_up();
void _favorite_move_down();
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index 5917869988..df25b08b4c 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -203,8 +203,9 @@ String EditorHelp::_fix_constant(const String &p_constant) const {
if (p_constant.strip_edges() == "2147483647") {
return "0x7FFFFFFF";
}
+
if (p_constant.strip_edges() == "1048575") {
- return "0xfffff";
+ return "0xFFFFF";
}
return p_constant;
diff --git a/editor/editor_inspector.cpp b/editor/editor_inspector.cpp
index ecb9ea5f35..e4ddf44bc4 100644
--- a/editor/editor_inspector.cpp
+++ b/editor/editor_inspector.cpp
@@ -66,7 +66,7 @@ Size2 EditorProperty::get_minimum_size() const {
if (checkable) {
Ref<Texture> check = get_icon("checked", "CheckBox");
- ms.width += check->get_width() + get_constant("hseparator", "Tree");
+ ms.width += check->get_width() + get_constant("hseparation", "CheckBox") + get_constant("hseparator", "Tree");
}
if (bottom_editor != NULL && bottom_editor->is_visible()) {
@@ -228,8 +228,7 @@ void EditorProperty::_notification(int p_what) {
}
check_rect = Rect2(ofs, ((size.height - checkbox->get_height()) / 2), checkbox->get_width(), checkbox->get_height());
draw_texture(checkbox, check_rect.position, color2);
- ofs += get_constant("hseparator", "Tree");
- ofs += checkbox->get_width();
+ ofs += get_constant("hseparator", "Tree") + checkbox->get_width() + get_constant("hseparation", "CheckBox");
text_limit -= ofs;
} else {
check_rect = Rect2();
diff --git a/editor/plugins/asset_library_editor_plugin.cpp b/editor/plugins/asset_library_editor_plugin.cpp
index 0dfb53b34a..a0774ac696 100644
--- a/editor/plugins/asset_library_editor_plugin.cpp
+++ b/editor/plugins/asset_library_editor_plugin.cpp
@@ -733,6 +733,7 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PoolByt
image_data = cached_data;
file->close();
+ memdelete(file);
}
}
@@ -807,6 +808,7 @@ void EditorAssetLibrary::_image_request_completed(int p_status, int p_code, cons
if (file) {
file->store_line(new_etag);
file->close();
+ memdelete(file);
}
int len = p_data.size();
@@ -816,6 +818,7 @@ void EditorAssetLibrary::_image_request_completed(int p_status, int p_code, cons
file->store_32(len);
file->store_buffer(r.ptr(), len);
file->close();
+ memdelete(file);
}
break;
@@ -855,6 +858,7 @@ void EditorAssetLibrary::_update_image_queue() {
if (file) {
headers.push_back("If-None-Match: " + file->get_line());
file->close();
+ memdelete(file);
}
}
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index 641c387c64..f45e6a2c9a 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -723,6 +723,8 @@ void ScriptEditor::_resave_scripts(const String &p_str) {
se->trim_trailing_whitespace();
}
+ se->insert_final_newline();
+
if (convert_indent_on_save) {
if (use_space_indentation) {
se->convert_indent_to_spaces();
@@ -1078,6 +1080,8 @@ void ScriptEditor::_menu_option(int p_option) {
if (trim_trailing_whitespace_on_save)
current->trim_trailing_whitespace();
+ current->insert_final_newline();
+
if (convert_indent_on_save) {
if (use_space_indentation) {
current->convert_indent_to_spaces();
@@ -1097,7 +1101,10 @@ void ScriptEditor::_menu_option(int p_option) {
} break;
case FILE_SAVE_AS: {
- current->trim_trailing_whitespace();
+ if (trim_trailing_whitespace_on_save)
+ current->trim_trailing_whitespace();
+
+ current->insert_final_newline();
if (convert_indent_on_save) {
if (use_space_indentation) {
@@ -2121,6 +2128,8 @@ void ScriptEditor::save_all_scripts() {
se->trim_trailing_whitespace();
}
+ se->insert_final_newline();
+
if (!se->is_unsaved())
continue;
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index 683fa881f8..fae98d6ec8 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -99,6 +99,7 @@ public:
virtual void set_executing_line(int p_line) = 0;
virtual void clear_executing_line() = 0;
virtual void trim_trailing_whitespace() = 0;
+ virtual void insert_final_newline() = 0;
virtual void convert_indent_to_spaces() = 0;
virtual void convert_indent_to_tabs() = 0;
virtual void ensure_focus() = 0;
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 1fe4ac1372..79867f40ca 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -457,6 +457,11 @@ void ScriptTextEditor::trim_trailing_whitespace() {
code_editor->trim_trailing_whitespace();
}
+void ScriptTextEditor::insert_final_newline() {
+
+ code_editor->insert_final_newline();
+}
+
void ScriptTextEditor::convert_indent_to_spaces() {
code_editor->convert_indent_to_spaces();
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index bdfdf18d45..7f5b6c065d 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -194,6 +194,7 @@ public:
virtual void set_edit_state(const Variant &p_state);
virtual void ensure_focus();
virtual void trim_trailing_whitespace();
+ virtual void insert_final_newline();
virtual void convert_indent_to_spaces();
virtual void convert_indent_to_tabs();
virtual void tag_saved_version();
diff --git a/editor/plugins/text_editor.cpp b/editor/plugins/text_editor.cpp
index a0f3c253d1..d036d7e965 100644
--- a/editor/plugins/text_editor.cpp
+++ b/editor/plugins/text_editor.cpp
@@ -251,6 +251,11 @@ void TextEditor::trim_trailing_whitespace() {
code_editor->trim_trailing_whitespace();
}
+void TextEditor::insert_final_newline() {
+
+ code_editor->insert_final_newline();
+}
+
void TextEditor::convert_indent_to_spaces() {
code_editor->convert_indent_to_spaces();
diff --git a/editor/plugins/text_editor.h b/editor/plugins/text_editor.h
index 2da7474793..e06d816177 100644
--- a/editor/plugins/text_editor.h
+++ b/editor/plugins/text_editor.h
@@ -130,6 +130,7 @@ public:
virtual void set_executing_line(int p_line);
virtual void clear_executing_line();
virtual void trim_trailing_whitespace();
+ virtual void insert_final_newline();
virtual void convert_indent_to_spaces();
virtual void convert_indent_to_tabs();
virtual void ensure_focus();
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index 3f513de30f..5e1d818ce9 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -780,7 +780,8 @@ void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p
r.position += (r.size + Vector2(spacing, spacing)) * offset;
}
Size2 sc = p_xform.get_scale();
- Size2 cell_size = node->get_cell_size();
+ /* For a future CheckBox to Center Texture:
+ Size2 cell_size = node->get_cell_size(); */
Rect2 rect = Rect2();
rect.position = node->map_to_world(p_point) + node->get_cell_draw_offset();
@@ -792,10 +793,11 @@ void TileMapEditor::_draw_cell(Control *p_viewport, int p_cell, const Point2i &p
if (p_transpose) {
SWAP(tile_ofs.x, tile_ofs.y);
+ /* For a future CheckBox to Center Texture:
rect.position.x += cell_size.x / 2 - rect.size.y / 2;
rect.position.y += cell_size.y / 2 - rect.size.x / 2;
} else {
- rect.position += cell_size / 2 - rect.size / 2;
+ rect.position += cell_size / 2 - rect.size / 2; */
}
if (p_flip_h) {
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index 5ca3448693..e1b4320378 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -51,6 +51,7 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
if (connect_to_script_mode) {
return; //don't do anything in this mode
}
+
TreeItem *item = Object::cast_to<TreeItem>(p_item);
ERR_FAIL_COND(!item);
@@ -220,23 +221,27 @@ bool SceneTreeEditor::_add_nodes(Node *p_node, TreeItem *p_parent) {
}
if (marked.has(p_node)) {
- item->set_text(0, String(p_node->get_name()) + " " + TTR("(Connecting From)"));
-
+ String node_name = p_node->get_name();
+ if (connecting_signal) {
+ node_name += " " + TTR("(Connecting From)");
+ }
+ item->set_text(0, node_name);
item->set_custom_color(0, accent);
}
} else if (part_of_subscene) {
- //item->set_selectable(0,marked_selectable);
if (valid_types.size() == 0) {
item->set_custom_color(0, get_color("disabled_font_color", "Editor"));
}
-
} else if (marked.has(p_node)) {
- if (!connect_to_script_mode) {
- item->set_selectable(0, marked_selectable);
+ String node_name = p_node->get_name();
+ if (connecting_signal) {
+ node_name += " " + TTR("(Connecting From)");
}
- item->set_custom_color(0, get_color("error_color", "Editor"));
+ item->set_text(0, node_name);
+ item->set_selectable(0, marked_selectable);
+ item->set_custom_color(0, get_color("accent_color", "Editor"));
} else if (!marked_selectable && !marked_children_selectable) {
Node *node = p_node;
@@ -1033,6 +1038,11 @@ void SceneTreeEditor::set_connect_to_script_mode(bool p_enable) {
update_tree();
}
+void SceneTreeEditor::set_connecting_signal(bool p_enable) {
+ connecting_signal = p_enable;
+ update_tree();
+}
+
void SceneTreeEditor::_bind_methods() {
ClassDB::bind_method("_tree_changed", &SceneTreeEditor::_tree_changed);
@@ -1077,6 +1087,7 @@ void SceneTreeEditor::_bind_methods() {
SceneTreeEditor::SceneTreeEditor(bool p_label, bool p_can_rename, bool p_can_open_instance) {
connect_to_script_mode = false;
+ connecting_signal = false;
undo_redo = NULL;
tree_dirty = true;
selected = NULL;
diff --git a/editor/scene_tree_editor.h b/editor/scene_tree_editor.h
index 1c14da0d3a..68642910e8 100644
--- a/editor/scene_tree_editor.h
+++ b/editor/scene_tree_editor.h
@@ -68,6 +68,7 @@ class SceneTreeEditor : public Control {
AcceptDialog *warning;
bool connect_to_script_mode;
+ bool connecting_signal;
int blocked;
@@ -155,6 +156,7 @@ public:
void update_tree() { _update_tree(); }
void set_connect_to_script_mode(bool p_enable);
+ void set_connecting_signal(bool p_enable);
Tree *get_scene_tree() { return tree; }
diff --git a/modules/bullet/SCsub b/modules/bullet/SCsub
index 16d694c238..2fe7a1b4c0 100644
--- a/modules/bullet/SCsub
+++ b/modules/bullet/SCsub
@@ -186,7 +186,11 @@ if env['builtin_bullet']:
thirdparty_sources = [thirdparty_dir + file for file in bullet2_src]
- env_bullet.Prepend(CPPPATH=[thirdparty_dir])
+ # Treat Bullet headers as system headers to avoid raising warnings. Not supported on MSVC.
+ if not env.msvc:
+ env_bullet.Append(CPPFLAGS=['-isystem', Dir(thirdparty_dir).path])
+ else:
+ env_bullet.Prepend(CPPPATH=[thirdparty_dir])
# if env['target'] == "debug" or env['target'] == "release_debug":
# env_bullet.Append(CPPFLAGS=['-DBT_DEBUG'])
diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp
index 44a91303e9..596be7cbb0 100644
--- a/modules/gdscript/gdscript_parser.cpp
+++ b/modules/gdscript/gdscript_parser.cpp
@@ -4068,6 +4068,50 @@ void GDScriptParser::_parse_class(ClassNode *p_class) {
break;
}
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_2D_RENDER") {
+
+ tokenizer->advance();
+ if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
+ _set_error("Expected ')' in layers 2D render hint.");
+ return;
+ }
+ current_export.hint = PROPERTY_HINT_LAYERS_2D_RENDER;
+ break;
+ }
+
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_2D_PHYSICS") {
+
+ tokenizer->advance();
+ if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
+ _set_error("Expected ')' in layers 2D physics hint.");
+ return;
+ }
+ current_export.hint = PROPERTY_HINT_LAYERS_2D_PHYSICS;
+ break;
+ }
+
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_3D_RENDER") {
+
+ tokenizer->advance();
+ if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
+ _set_error("Expected ')' in layers 3D render hint.");
+ return;
+ }
+ current_export.hint = PROPERTY_HINT_LAYERS_3D_RENDER;
+ break;
+ }
+
+ if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "LAYERS_3D_PHYSICS") {
+
+ tokenizer->advance();
+ if (tokenizer->get_token() != GDScriptTokenizer::TK_PARENTHESIS_CLOSE) {
+ _set_error("Expected ')' in layers 3D physics hint.");
+ return;
+ }
+ current_export.hint = PROPERTY_HINT_LAYERS_3D_PHYSICS;
+ break;
+ }
+
if (tokenizer->get_token() == GDScriptTokenizer::TK_CONSTANT && tokenizer->get_token_constant().get_type() == Variant::STRING) {
//enumeration
current_export.hint = PROPERTY_HINT_ENUM;
diff --git a/modules/mono/build_scripts/patches/fix-mono-android-pthread_mutexattr_setprotocol.diff b/modules/mono/build_scripts/patches/fix-mono-android-pthread_mutexattr_setprotocol.diff
deleted file mode 100644
index 21cb1a0cf8..0000000000
--- a/modules/mono/build_scripts/patches/fix-mono-android-pthread_mutexattr_setprotocol.diff
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/mono/utils/mono-os-mutex.h b/mono/utils/mono-os-mutex.h
-index e8039bf4094..ee39c0330b3 100644
---- a/mono/utils/mono-os-mutex.h
-+++ b/mono/utils/mono-os-mutex.h
-@@ -57,7 +57,7 @@ mono_os_mutex_init_type (mono_mutex_t *mutex, int type)
- if (G_UNLIKELY (res != 0))
- g_error ("%s: pthread_mutexattr_settype failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-
--#ifdef PTHREAD_PRIO_INHERIT
-+#if defined(PTHREAD_PRIO_INHERIT) && __ANDROID_API__ >= 28
- /* use PTHREAD_PRIO_INHERIT if possible */
- res = pthread_mutexattr_setprotocol (&attr, PTHREAD_PRIO_INHERIT);
- if (G_UNLIKELY (res != 0 && res != ENOTSUP))
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index aad6e95845..f84f2c90cd 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -2111,6 +2111,9 @@ void VisualScriptEditor::clear_executing_line() {
void VisualScriptEditor::trim_trailing_whitespace() {
}
+void VisualScriptEditor::insert_final_newline() {
+}
+
void VisualScriptEditor::convert_indent_to_spaces() {
}
diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h
index 3d3a49f672..6072e77342 100644
--- a/modules/visual_script/visual_script_editor.h
+++ b/modules/visual_script/visual_script_editor.h
@@ -266,6 +266,7 @@ public:
virtual void set_executing_line(int p_line);
virtual void clear_executing_line();
virtual void trim_trailing_whitespace();
+ virtual void insert_final_newline();
virtual void convert_indent_to_spaces();
virtual void convert_indent_to_tabs();
virtual void ensure_focus();
diff --git a/platform/server/detect.py b/platform/server/detect.py
index 08c2eb6aaf..a5648d8d9d 100644
--- a/platform/server/detect.py
+++ b/platform/server/detect.py
@@ -145,12 +145,12 @@ def configure(env):
env.ParseConfig('pkg-config libpng --cflags --libs')
if not env['builtin_bullet']:
- # We need at least version 2.88
+ # We need at least version 2.89
import subprocess
bullet_version = subprocess.check_output(['pkg-config', 'bullet', '--modversion']).strip()
- if str(bullet_version) < "2.88":
+ if str(bullet_version) < "2.89":
# Abort as system bullet was requested but too old
- print("Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(bullet_version, "2.88"))
+ print("Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(bullet_version, "2.89"))
sys.exit(255)
env.ParseConfig('pkg-config bullet --cflags --libs')
diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp
index cdcad33f6d..ec43a4c26f 100644
--- a/platform/uwp/export/export.cpp
+++ b/platform/uwp/export/export.cpp
@@ -241,7 +241,6 @@ void AppxPackager::make_block_map() {
tmp_file->close();
memdelete(tmp_file);
- tmp_file = NULL;
}
String AppxPackager::content_type(String p_extension) {
@@ -291,7 +290,6 @@ void AppxPackager::make_content_types() {
tmp_file->close();
memdelete(tmp_file);
- tmp_file = NULL;
}
Vector<uint8_t> AppxPackager::make_file_header(FileMeta p_file_meta) {
@@ -606,7 +604,6 @@ void AppxPackager::finish() {
blockmap_file->close();
memdelete(blockmap_file);
- blockmap_file = NULL;
// Add content types
EditorNode::progress_task_step("export", "Setting content types...", 5);
@@ -622,7 +619,6 @@ void AppxPackager::finish() {
types_file->close();
memdelete(types_file);
- types_file = NULL;
// Pre-process central directory before signing
for (int i = 0; i < file_metadata.size(); i++) {
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index 933ee6b72e..a502308eee 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -219,12 +219,12 @@ def configure(env):
env.ParseConfig('pkg-config libpng --cflags --libs')
if not env['builtin_bullet']:
- # We need at least version 2.88
+ # We need at least version 2.89
import subprocess
bullet_version = subprocess.check_output(['pkg-config', 'bullet', '--modversion']).strip()
- if str(bullet_version) < "2.88":
+ if str(bullet_version) < "2.89":
# Abort as system bullet was requested but too old
- print("Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(bullet_version, "2.88"))
+ print("Bullet: System version {0} does not match minimal requirements ({1}). Aborting.".format(bullet_version, "2.89"))
sys.exit(255)
env.ParseConfig('pkg-config bullet --cflags --libs')
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 311b42be22..494ae41220 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -1017,12 +1017,12 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) {
XFree(xsh);
}
- if (!p_enabled && !get_borderless_window()) {
- // put decorations back if the window wasn't suppoesed to be borderless
+ if (!p_enabled) {
+ // put back or remove decorations according to the last set borderless state
Hints hints;
Atom property;
hints.flags = 2;
- hints.decorations = 1;
+ hints.decorations = current_videomode.borderless_window ? 0 : 1;
property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
}
@@ -1531,7 +1531,7 @@ bool OS_X11::is_window_always_on_top() const {
void OS_X11::set_borderless_window(bool p_borderless) {
- if (current_videomode.borderless_window == p_borderless)
+ if (get_borderless_window() == p_borderless)
return;
if (!p_borderless && layered_window)
@@ -1551,7 +1551,24 @@ void OS_X11::set_borderless_window(bool p_borderless) {
}
bool OS_X11::get_borderless_window() {
- return current_videomode.borderless_window;
+
+ bool borderless = current_videomode.borderless_window;
+ Atom prop = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
+ if (prop != None) {
+
+ Atom type;
+ int format;
+ unsigned long len;
+ unsigned long remaining;
+ unsigned char *data = NULL;
+ if (XGetWindowProperty(x11_display, x11_window, prop, 0, sizeof(Hints), False, AnyPropertyType, &type, &format, &len, &remaining, &data) == Success) {
+ if (data && (format == 32) && (len >= 5)) {
+ borderless = !((Hints *)data)->decorations;
+ }
+ XFree(data);
+ }
+ }
+ return borderless;
}
void OS_X11::request_attention() {
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp
index 25ad6bd5c9..075b0e6252 100644
--- a/scene/2d/animated_sprite.cpp
+++ b/scene/2d/animated_sprite.cpp
@@ -646,6 +646,7 @@ void AnimatedSprite::_reset_timeout() {
void AnimatedSprite::set_animation(const StringName &p_animation) {
ERR_EXPLAIN(vformat("There is no animation with name '%s'.", p_animation));
+ ERR_FAIL_COND(frames == NULL)
ERR_FAIL_COND(frames->get_animation_names().find(p_animation) == -1);
if (animation == p_animation)
diff --git a/scene/2d/cpu_particles_2d.h b/scene/2d/cpu_particles_2d.h
index 23d2586331..81343a4604 100644
--- a/scene/2d/cpu_particles_2d.h
+++ b/scene/2d/cpu_particles_2d.h
@@ -116,7 +116,7 @@ private:
const Particle *particles;
bool operator()(int p_a, int p_b) const {
- return particles[p_a].time < particles[p_b].time;
+ return particles[p_a].time > particles[p_b].time;
}
};
diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp
index ba06b3ebff..e116d404d6 100644
--- a/scene/2d/line_2d.cpp
+++ b/scene/2d/line_2d.cpp
@@ -105,6 +105,7 @@ void Line2D::set_point_position(int i, Vector2 pos) {
}
Vector2 Line2D::get_point_position(int i) const {
+ ERR_FAIL_INDEX_V(i, _points.size(), Vector2())
return _points.get(i);
}
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 2b43861eea..b3b6f3175d 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -220,8 +220,8 @@ void TileMap::_fix_cell_transform(Transform2D &xform, const Cell &p_cell, const
xform.elements[1].y = -xform.elements[1].y;
offset.y = s.y - offset.y;
}
-
- offset += cell_size / 2 - s / 2;
+ /* For a future CheckBox to Center Texture:
+ offset += cell_size / 2 - s / 2; */
xform.elements[2] += offset;
}
@@ -372,10 +372,11 @@ void TileMap::update_dirty_quadrants() {
if (c.transpose) {
SWAP(tile_ofs.x, tile_ofs.y);
+ /* For a future CheckBox to Center Texture:
rect.position.x += cell_size.x / 2 - rect.size.y / 2;
rect.position.y += cell_size.y / 2 - rect.size.x / 2;
} else {
- rect.position += cell_size / 2 - rect.size / 2;
+ rect.position += cell_size / 2 - rect.size / 2; */
}
if (c.flip_h) {
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 58bdde1ffd..da6bff8ab8 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -539,7 +539,7 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) {
if (handled) {
accept_event();
- } else if (!k->get_alt() && !k->get_command()) {
+ } else if (!k->get_command()) {
if (k->get_unicode() >= 32 && k->get_scancode() != KEY_DELETE) {
if (editable) {
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 6203b15992..2258141385 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -4682,6 +4682,8 @@ bool TextEdit::has_keyword_color(String p_keyword) const {
}
Color TextEdit::get_keyword_color(String p_keyword) const {
+
+ ERR_FAIL_COND_V(!keywords.has(p_keyword), Color())
return keywords[p_keyword];
}
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 732c08fdea..3e1e8f9734 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -26,7 +26,7 @@ comments.
## bullet
- Upstream: https://github.com/bulletphysics/bullet3
-- Version: 2.88
+- Version: git (5ec8339, 2019)
- License: zlib
Files extracted from upstream source:
diff --git a/thirdparty/bullet/Bullet3Common/b3Quaternion.h b/thirdparty/bullet/Bullet3Common/b3Quaternion.h
index 9bd5ff7d90..4fdd72dcc4 100644
--- a/thirdparty/bullet/Bullet3Common/b3Quaternion.h
+++ b/thirdparty/bullet/Bullet3Common/b3Quaternion.h
@@ -92,8 +92,11 @@ public:
/**@brief Set the rotation using axis angle notation
* @param axis The axis around which to rotate
* @param angle The magnitude of the rotation in Radians */
- void setRotation(const b3Vector3& axis, const b3Scalar& _angle)
+ void setRotation(const b3Vector3& axis1, const b3Scalar& _angle)
{
+ b3Vector3 axis = axis1;
+ axis.safeNormalize();
+
b3Scalar d = axis.length();
b3Assert(d != b3Scalar(0.0));
if (d < B3_EPSILON)
diff --git a/thirdparty/bullet/Bullet3Common/b3Vector3.h b/thirdparty/bullet/Bullet3Common/b3Vector3.h
index 56e6c13311..a70d68d6e1 100644
--- a/thirdparty/bullet/Bullet3Common/b3Vector3.h
+++ b/thirdparty/bullet/Bullet3Common/b3Vector3.h
@@ -36,7 +36,7 @@ subject to the following restrictions:
#pragma warning(disable : 4556) // value of intrinsic immediate argument '4294967239' is out of range '0 - 255'
#endif
-#define B3_SHUFFLE(x, y, z, w) ((w) << 6 | (z) << 4 | (y) << 2 | (x))
+#define B3_SHUFFLE(x, y, z, w) (((w) << 6 | (z) << 4 | (y) << 2 | (x)) & 0xff)
//#define b3_pshufd_ps( _a, _mask ) (__m128) _mm_shuffle_epi32((__m128i)(_a), (_mask) )
#define b3_pshufd_ps(_a, _mask) _mm_shuffle_ps((_a), (_a), (_mask))
#define b3_splat3_ps(_a, _i) b3_pshufd_ps((_a), B3_SHUFFLE(_i, _i, _i, 3))
diff --git a/thirdparty/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp b/thirdparty/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp
index 37156fd589..166cb04c0b 100644
--- a/thirdparty/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp
+++ b/thirdparty/bullet/BulletCollision/BroadphaseCollision/btDbvt.cpp
@@ -37,7 +37,7 @@ static DBVT_INLINE int indexof(const btDbvtNode* node)
static DBVT_INLINE btDbvtVolume merge(const btDbvtVolume& a,
const btDbvtVolume& b)
{
-#if (DBVT_MERGE_IMPL == DBVT_IMPL_SSE)
+#ifdef BT_USE_SSE
ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtAabbMm)]);
btDbvtVolume* ptr = (btDbvtVolume*)locals;
btDbvtVolume& res = *ptr;
@@ -80,6 +80,7 @@ static DBVT_INLINE void deletenode(btDbvt* pdbvt,
static void recursedeletenode(btDbvt* pdbvt,
btDbvtNode* node)
{
+ if (node == 0) return;
if (!node->isleaf())
{
recursedeletenode(pdbvt, node->childs[0]);
@@ -298,7 +299,7 @@ static int split(btDbvtNode** leaves,
static btDbvtVolume bounds(btDbvtNode** leaves,
int count)
{
-#if DBVT_MERGE_IMPL == DBVT_IMPL_SSE
+#ifdef BT_USE_SSE
ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtVolume)]);
btDbvtVolume* ptr = (btDbvtVolume*)locals;
btDbvtVolume& volume = *ptr;
diff --git a/thirdparty/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp b/thirdparty/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
index 166cf771fe..b7fe0a1f34 100644
--- a/thirdparty/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
+++ b/thirdparty/bullet/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp
@@ -123,11 +123,11 @@ protected:
void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg, btDispatcher* dispatcher)
{
+ m_pairCache->removeOverlappingPairsContainingProxy(proxyOrg, dispatcher);
+
btSimpleBroadphaseProxy* proxy0 = static_cast<btSimpleBroadphaseProxy*>(proxyOrg);
freeHandle(proxy0);
- m_pairCache->removeOverlappingPairsContainingProxy(proxyOrg, dispatcher);
-
//validate();
}
diff --git a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionObject.cpp b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionObject.cpp
index 98a02d0c45..b48d9301d7 100644
--- a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionObject.cpp
+++ b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionObject.cpp
@@ -43,6 +43,7 @@ btCollisionObject::btCollisionObject()
m_userObjectPointer(0),
m_userIndex2(-1),
m_userIndex(-1),
+ m_userIndex3(-1),
m_hitFraction(btScalar(1.)),
m_ccdSweptSphereRadius(btScalar(0.)),
m_ccdMotionThreshold(btScalar(0.)),
diff --git a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h
index 56b3d89e56..85dc488c8c 100644
--- a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h
+++ b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionObject.h
@@ -101,6 +101,8 @@ protected:
int m_userIndex;
+ int m_userIndex3;
+
///time of impact calculation
btScalar m_hitFraction;
@@ -526,6 +528,11 @@ public:
return m_userIndex2;
}
+ int getUserIndex3() const
+ {
+ return m_userIndex3;
+ }
+
///users can point to their objects, userPointer is not used by Bullet
void setUserPointer(void* userPointer)
{
@@ -543,6 +550,11 @@ public:
m_userIndex2 = index;
}
+ void setUserIndex3(int index)
+ {
+ m_userIndex3 = index;
+ }
+
int getUpdateRevisionInternal() const
{
return m_updateRevision;
diff --git a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
index b30ce03164..71184f36ac 100644
--- a/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
+++ b/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp
@@ -19,10 +19,10 @@ subject to the following restrictions:
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
#include "BulletCollision/CollisionShapes/btConvexShape.h"
#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h"
-#include "BulletCollision/CollisionShapes/btSphereShape.h" //for raycasting
-#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" //for raycasting
-#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h" //for raycasting
-#include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h" //for raycasting
+#include "BulletCollision/CollisionShapes/btSphereShape.h" //for raycasting
+#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" //for raycasting
+#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h" //for raycasting
+#include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h" //for raycasting
#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h"
#include "BulletCollision/CollisionShapes/btCompoundShape.h"
#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h"
@@ -414,7 +414,9 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans, co
rcb.m_hitFraction = resultCallback.m_closestHitFraction;
triangleMesh->performRaycast(&rcb, rayFromLocalScaled, rayToLocalScaled);
}
- else if (collisionShape->getShapeType()==TERRAIN_SHAPE_PROXYTYPE)
+ else if (((resultCallback.m_flags&btTriangleRaycastCallback::kF_DisableHeightfieldAccelerator)==0)
+ && collisionShape->getShapeType() == TERRAIN_SHAPE_PROXYTYPE
+ )
{
///optimized version for btHeightfieldTerrainShape
btHeightfieldTerrainShape* heightField = (btHeightfieldTerrainShape*)collisionShape;
@@ -422,7 +424,7 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans, co
btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin();
btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin();
- BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),heightField,colObjWorldTransform);
+ BridgeTriangleRaycastCallback rcb(rayFromLocal, rayToLocal, &resultCallback, collisionObjectWrap->getCollisionObject(), heightField, colObjWorldTransform);
rcb.m_hitFraction = resultCallback.m_closestHitFraction;
heightField->performRaycast(&rcb, rayFromLocal, rayToLocal);
}
diff --git a/thirdparty/bullet/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp b/thirdparty/bullet/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp
index 65b669e1c0..9694f4ddb3 100644
--- a/thirdparty/bullet/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp
+++ b/thirdparty/bullet/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp
@@ -27,7 +27,7 @@ btConvexPolyhedron::~btConvexPolyhedron()
{
}
-inline bool IsAlmostZero(const btVector3& v)
+inline bool IsAlmostZero1(const btVector3& v)
{
if (btFabs(v.x()) > 1e-6 || btFabs(v.y()) > 1e-6 || btFabs(v.z()) > 1e-6) return false;
return true;
@@ -122,8 +122,8 @@ void btConvexPolyhedron::initialize()
for (int p = 0; p < m_uniqueEdges.size(); p++)
{
- if (IsAlmostZero(m_uniqueEdges[p] - edge) ||
- IsAlmostZero(m_uniqueEdges[p] + edge))
+ if (IsAlmostZero1(m_uniqueEdges[p] - edge) ||
+ IsAlmostZero1(m_uniqueEdges[p] + edge))
{
found = true;
break;
diff --git a/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp b/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
index 4adf27e6bb..34ec2d8c45 100644
--- a/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
+++ b/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp
@@ -71,9 +71,10 @@ void btHeightfieldTerrainShape::initialize(
m_flipQuadEdges = flipQuadEdges;
m_useDiamondSubdivision = false;
m_useZigzagSubdivision = false;
+ m_flipTriangleWinding = false;
m_upAxis = upAxis;
m_localScaling.setValue(btScalar(1.), btScalar(1.), btScalar(1.));
- m_vboundsGrid = NULL;
+
m_vboundsChunkSize = 0;
m_vboundsGridWidth = 0;
m_vboundsGridLength = 0;
@@ -335,30 +336,37 @@ void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback
for (int x = startX; x < endX; x++)
{
btVector3 vertices[3];
+ int indices[3] = { 0, 1, 2 };
+ if (m_flipTriangleWinding)
+ {
+ indices[0] = 2;
+ indices[2] = 0;
+ }
+
if (m_flipQuadEdges || (m_useDiamondSubdivision && !((j + x) & 1)) || (m_useZigzagSubdivision && !(j & 1)))
{
//first triangle
- getVertex(x, j, vertices[0]);
- getVertex(x, j + 1, vertices[1]);
- getVertex(x + 1, j + 1, vertices[2]);
+ getVertex(x, j, vertices[indices[0]]);
+ getVertex(x, j + 1, vertices[indices[1]]);
+ getVertex(x + 1, j + 1, vertices[indices[2]]);
callback->processTriangle(vertices, x, j);
//second triangle
// getVertex(x,j,vertices[0]);//already got this vertex before, thanks to Danny Chapman
- getVertex(x + 1, j + 1, vertices[1]);
- getVertex(x + 1, j, vertices[2]);
+ getVertex(x + 1, j + 1, vertices[indices[1]]);
+ getVertex(x + 1, j, vertices[indices[2]]);
callback->processTriangle(vertices, x, j);
}
else
{
//first triangle
- getVertex(x, j, vertices[0]);
- getVertex(x, j + 1, vertices[1]);
- getVertex(x + 1, j, vertices[2]);
+ getVertex(x, j, vertices[indices[0]]);
+ getVertex(x, j + 1, vertices[indices[1]]);
+ getVertex(x + 1, j, vertices[indices[2]]);
callback->processTriangle(vertices, x, j);
//second triangle
- getVertex(x + 1, j, vertices[0]);
+ getVertex(x + 1, j, vertices[indices[0]]);
//getVertex(x,j+1,vertices[1]);
- getVertex(x + 1, j + 1, vertices[2]);
+ getVertex(x + 1, j + 1, vertices[indices[2]]);
callback->processTriangle(vertices, x, j);
}
}
@@ -381,39 +389,42 @@ const btVector3& btHeightfieldTerrainShape::getLocalScaling() const
return m_localScaling;
}
-
-
-struct GridRaycastState
+namespace
{
- int x; // Next quad coords
- int z;
- int prev_x; // Previous quad coords
- int prev_z;
- btScalar param; // Exit param for previous quad
- btScalar prevParam; // Enter param for previous quad
- btScalar maxDistanceFlat;
- btScalar maxDistance3d;
-};
-
+ struct GridRaycastState
+ {
+ int x; // Next quad coords
+ int z;
+ int prev_x; // Previous quad coords
+ int prev_z;
+ btScalar param; // Exit param for previous quad
+ btScalar prevParam; // Enter param for previous quad
+ btScalar maxDistanceFlat;
+ btScalar maxDistance3d;
+ };
+}
// TODO Does it really need to take 3D vectors?
/// Iterates through a virtual 2D grid of unit-sized square cells,
/// and executes an action on each cell intersecting the given segment, ordered from begin to end.
/// Initially inspired by http://www.cse.yorku.ca/~amana/research/grid.pdf
template <typename Action_T>
-void gridRaycast(Action_T &quadAction, const btVector3 &beginPos, const btVector3 &endPos)
+void gridRaycast(Action_T& quadAction, const btVector3& beginPos, const btVector3& endPos, int indices[3])
{
GridRaycastState rs;
rs.maxDistance3d = beginPos.distance(endPos);
if (rs.maxDistance3d < 0.0001)
+ {
// Consider the ray is too small to hit anything
return;
+ }
+
- btScalar rayDirectionFlatX = endPos[0] - beginPos[0];
- btScalar rayDirectionFlatZ = endPos[2] - beginPos[2];
+ btScalar rayDirectionFlatX = endPos[indices[0]] - beginPos[indices[0]];
+ btScalar rayDirectionFlatZ = endPos[indices[2]] - beginPos[indices[2]];
rs.maxDistanceFlat = btSqrt(rayDirectionFlatX * rayDirectionFlatX + rayDirectionFlatZ * rayDirectionFlatZ);
- if(rs.maxDistanceFlat < 0.0001)
+ if (rs.maxDistanceFlat < 0.0001)
{
// Consider the ray vertical
rayDirectionFlatX = 0;
@@ -433,34 +444,46 @@ void gridRaycast(Action_T &quadAction, const btVector3 &beginPos, const btVector
const btScalar paramDeltaZ = ziStep != 0 ? 1.f / btFabs(rayDirectionFlatZ) : infinite;
// pos = param * dir
- btScalar paramCrossX; // At which value of `param` we will cross a x-axis lane?
- btScalar paramCrossZ; // At which value of `param` we will cross a z-axis lane?
+ btScalar paramCrossX; // At which value of `param` we will cross a x-axis lane?
+ btScalar paramCrossZ; // At which value of `param` we will cross a z-axis lane?
// paramCrossX and paramCrossZ are initialized as being the first cross
// X initialization
if (xiStep != 0)
{
if (xiStep == 1)
- paramCrossX = (ceil(beginPos[0]) - beginPos[0]) * paramDeltaX;
+ {
+ paramCrossX = (ceil(beginPos[indices[0]]) - beginPos[indices[0]]) * paramDeltaX;
+ }
else
- paramCrossX = (beginPos[0] - floor(beginPos[0])) * paramDeltaX;
+ {
+ paramCrossX = (beginPos[indices[0]] - floor(beginPos[indices[0]])) * paramDeltaX;
+ }
}
else
- paramCrossX = infinite; // Will never cross on X
+ {
+ paramCrossX = infinite; // Will never cross on X
+ }
// Z initialization
if (ziStep != 0)
{
if (ziStep == 1)
- paramCrossZ = (ceil(beginPos[2]) - beginPos[2]) * paramDeltaZ;
+ {
+ paramCrossZ = (ceil(beginPos[indices[2]]) - beginPos[indices[2]]) * paramDeltaZ;
+ }
else
- paramCrossZ = (beginPos[2] - floor(beginPos[2])) * paramDeltaZ;
+ {
+ paramCrossZ = (beginPos[indices[2]] - floor(beginPos[indices[2]])) * paramDeltaZ;
+ }
}
else
- paramCrossZ = infinite; // Will never cross on Z
+ {
+ paramCrossZ = infinite; // Will never cross on Z
+ }
- rs.x = static_cast<int>(floor(beginPos[0]));
- rs.z = static_cast<int>(floor(beginPos[2]));
+ rs.x = static_cast<int>(floor(beginPos[indices[0]]));
+ rs.z = static_cast<int>(floor(beginPos[indices[2]]));
// Workaround cases where the ray starts at an integer position
if (paramCrossX == 0.0)
@@ -469,7 +492,9 @@ void gridRaycast(Action_T &quadAction, const btVector3 &beginPos, const btVector
// If going backwards, we should ignore the position we would get by the above flooring,
// because the ray is not heading in that direction
if (xiStep == -1)
+ {
rs.x -= 1;
+ }
}
if (paramCrossZ == 0.0)
@@ -513,14 +538,15 @@ void gridRaycast(Action_T &quadAction, const btVector3 &beginPos, const btVector
break;
}
else
+ {
quadAction(rs);
+ }
}
}
-
struct ProcessTrianglesAction
{
- const btHeightfieldTerrainShape *shape;
+ const btHeightfieldTerrainShape* shape;
bool flipQuadEdges;
bool useDiamondSubdivision;
int width;
@@ -529,11 +555,15 @@ struct ProcessTrianglesAction
void exec(int x, int z) const
{
- if(x < 0 || z < 0 || x >= width || z >= length)
+ if (x < 0 || z < 0 || x >= width || z >= length)
+ {
return;
+ }
btVector3 vertices[3];
+ // TODO Since this is for raycasts, we could greatly benefit from an early exit on the first hit
+
// Check quad
if (flipQuadEdges || (useDiamondSubdivision && (((z + x) & 1) > 0)))
{
@@ -565,16 +595,15 @@ struct ProcessTrianglesAction
}
}
- void operator ()(const GridRaycastState &bs) const
+ void operator()(const GridRaycastState& bs) const
{
exec(bs.prev_x, bs.prev_z);
}
};
-
struct ProcessVBoundsAction
{
- const btHeightfieldTerrainShape::Range *vbounds;
+ const btAlignedObjectArray<btHeightfieldTerrainShape::Range>& vbounds;
int width;
int length;
int chunkSize;
@@ -583,15 +612,23 @@ struct ProcessVBoundsAction
btVector3 rayEnd;
btVector3 rayDir;
+ int* m_indices;
ProcessTrianglesAction processTriangles;
- void operator ()(const GridRaycastState &rs) const
+ ProcessVBoundsAction(const btAlignedObjectArray<btHeightfieldTerrainShape::Range>& bnd, int* indices)
+ : vbounds(bnd),
+ m_indices(indices)
+ {
+ }
+ void operator()(const GridRaycastState& rs) const
{
int x = rs.prev_x;
int z = rs.prev_z;
- if(x < 0 || z < 0 || x >= width || z >= length)
+ if (x < 0 || z < 0 || x >= width || z >= length)
+ {
return;
+ }
const btHeightfieldTerrainShape::Range chunk = vbounds[x + z * width];
@@ -608,10 +645,14 @@ struct ProcessVBoundsAction
// We did enter the flat projection of the AABB,
// but we have to check if we intersect it on the vertical axis
- if (enterPos[1] > chunk.max && exitPos[1] > chunk.max)
+ if (enterPos[1] > chunk.max && exitPos[m_indices[1]] > chunk.max)
+ {
return;
- if (enterPos[1] < chunk.min && exitPos[1] < chunk.min)
+ }
+ if (enterPos[1] < chunk.min && exitPos[m_indices[1]] < chunk.min)
+ {
return;
+ }
}
else
{
@@ -621,13 +662,12 @@ struct ProcessVBoundsAction
exitPos = rayEnd;
}
- gridRaycast(processTriangles, enterPos, exitPos);
+ gridRaycast(processTriangles, enterPos, exitPos, m_indices);
// Note: it could be possible to have more than one grid at different levels,
// to do this there would be a branch using a pointer to another ProcessVBoundsAction
}
};
-
// TODO How do I interrupt the ray when there is a hit? `callback` does not return any result
/// Performs a raycast using a hierarchical Bresenham algorithm.
/// Does not allocate any memory by itself.
@@ -648,10 +688,16 @@ void btHeightfieldTerrainShape::performRaycast(btTriangleCallback* callback, con
processTriangles.length = m_heightStickLength - 1;
// TODO Transform vectors to account for m_upAxis
- int iBeginX = static_cast<int>(floor(beginPos[0]));
- int iBeginZ = static_cast<int>(floor(beginPos[2]));
- int iEndX = static_cast<int>(floor(endPos[0]));
- int iEndZ = static_cast<int>(floor(endPos[2]));
+ int indices[3] = { 0, 1, 2 };
+ if (m_upAxis == 2)
+ {
+ indices[1] = 2;
+ indices[2] = 1;
+ }
+ int iBeginX = static_cast<int>(floor(beginPos[indices[0]]));
+ int iBeginZ = static_cast<int>(floor(beginPos[indices[2]]));
+ int iEndX = static_cast<int>(floor(endPos[indices[0]]));
+ int iEndZ = static_cast<int>(floor(endPos[indices[2]]));
if (iBeginX == iEndX && iBeginZ == iEndZ)
{
@@ -662,36 +708,36 @@ void btHeightfieldTerrainShape::performRaycast(btTriangleCallback* callback, con
return;
}
- if (m_vboundsGrid == NULL)
+
+
+ if (m_vboundsGrid.size()==0)
{
// Process all quads intersecting the flat projection of the ray
- gridRaycast(processTriangles, beginPos, endPos);
+ gridRaycast(processTriangles, beginPos, endPos, &indices[0]);
}
else
{
btVector3 rayDiff = endPos - beginPos;
- btScalar flatDistance2 = rayDiff[0] * rayDiff[0] + rayDiff[2] * rayDiff[2];
+ btScalar flatDistance2 = rayDiff[indices[0]] * rayDiff[indices[0]] + rayDiff[indices[2]] * rayDiff[indices[2]];
if (flatDistance2 < m_vboundsChunkSize * m_vboundsChunkSize)
{
// Don't use chunks, the ray is too short in the plane
- gridRaycast(processTriangles, beginPos, endPos);
+ gridRaycast(processTriangles, beginPos, endPos, &indices[0]);
}
- ProcessVBoundsAction processVBounds;
+ ProcessVBoundsAction processVBounds(m_vboundsGrid, &indices[0]);
processVBounds.width = m_vboundsGridWidth;
processVBounds.length = m_vboundsGridLength;
- processVBounds.vbounds = m_vboundsGrid;
processVBounds.rayBegin = beginPos;
processVBounds.rayEnd = endPos;
processVBounds.rayDir = rayDiff.normalized();
processVBounds.processTriangles = processTriangles;
processVBounds.chunkSize = m_vboundsChunkSize;
// The ray is long, run raycast on a higher-level grid
- gridRaycast(processVBounds, beginPos / m_vboundsChunkSize, endPos / m_vboundsChunkSize);
+ gridRaycast(processVBounds, beginPos / m_vboundsChunkSize, endPos / m_vboundsChunkSize, indices);
}
}
-
/// Builds a grid data structure storing the min and max heights of the terrain in chunks.
/// if chunkSize is zero, that accelerator is removed.
/// If you modify the heights, you need to rebuild this accelerator.
@@ -708,11 +754,15 @@ void btHeightfieldTerrainShape::buildAccelerator(int chunkSize)
int nChunksZ = m_heightStickLength / chunkSize;
if (m_heightStickWidth % chunkSize > 0)
- ++nChunksX; // In case terrain size isn't dividable by chunk size
+ {
+ ++nChunksX; // In case terrain size isn't dividable by chunk size
+ }
if (m_heightStickLength % chunkSize > 0)
+ {
++nChunksZ;
+ }
- if(m_vboundsGridWidth != nChunksX || m_vboundsGridLength != nChunksZ)
+ if (m_vboundsGridWidth != nChunksX || m_vboundsGridLength != nChunksZ)
{
clearAccelerator();
m_vboundsGridWidth = nChunksX;
@@ -720,13 +770,13 @@ void btHeightfieldTerrainShape::buildAccelerator(int chunkSize)
}
if (nChunksX == 0 || nChunksZ == 0)
+ {
return;
+ }
- // TODO What is the recommended way to allocate this?
// This data structure is only reallocated if the required size changed
- if (m_vboundsGrid == NULL)
- m_vboundsGrid = new Range[nChunksX * nChunksZ];
-
+ m_vboundsGrid.resize(nChunksX * nChunksZ);
+
// Compute min and max height for all chunks
for (int cz = 0; cz < nChunksZ; ++cz)
{
@@ -760,19 +810,27 @@ void btHeightfieldTerrainShape::buildAccelerator(int chunkSize)
for (int z = z0; z < z0 + chunkSize + 1; ++z)
{
if (z >= m_heightStickLength)
+ {
continue;
+ }
for (int x = x0; x < x0 + chunkSize + 1; ++x)
{
if (x >= m_heightStickWidth)
+ {
continue;
+ }
btScalar height = getRawHeightFieldValue(x, z);
if (height < r.min)
+ {
r.min = height;
+ }
else if (height > r.max)
+ {
r.max = height;
+ }
}
}
@@ -781,15 +839,7 @@ void btHeightfieldTerrainShape::buildAccelerator(int chunkSize)
}
}
-
void btHeightfieldTerrainShape::clearAccelerator()
{
- if (m_vboundsGrid)
- {
- // TODO What is the recommended way to deallocate this?
- delete[] m_vboundsGrid;
- m_vboundsGrid = 0;
- }
-}
-
-
+ m_vboundsGrid.clear();
+} \ No newline at end of file
diff --git a/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h b/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
index e23b548cb2..43e1d25e3d 100644
--- a/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
+++ b/thirdparty/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h
@@ -17,7 +17,7 @@ subject to the following restrictions:
#define BT_HEIGHTFIELD_TERRAIN_SHAPE_H
#include "btConcaveShape.h"
-
+#include "LinearMath/btAlignedObjectArray.h"
///btHeightfieldTerrainShape simulates a 2D heightfield terrain
/**
@@ -73,7 +73,8 @@ ATTRIBUTE_ALIGNED16(class)
btHeightfieldTerrainShape : public btConcaveShape
{
public:
- struct Range {
+ struct Range
+ {
btScalar min;
btScalar max;
};
@@ -102,13 +103,13 @@ protected:
bool m_flipQuadEdges;
bool m_useDiamondSubdivision;
bool m_useZigzagSubdivision;
-
+ bool m_flipTriangleWinding;
int m_upAxis;
btVector3 m_localScaling;
// Accelerator
- Range *m_vboundsGrid;
+ btAlignedObjectArray<Range> m_vboundsGrid;
int m_vboundsGridWidth;
int m_vboundsGridLength;
int m_vboundsChunkSize;
@@ -157,6 +158,10 @@ public:
///could help compatibility with Ogre heightfields. See https://code.google.com/p/bullet/issues/detail?id=625
void setUseZigzagSubdivision(bool useZigzagSubdivision = true) { m_useZigzagSubdivision = useZigzagSubdivision; }
+ void setFlipTriangleWinding(bool flipTriangleWinding)
+ {
+ m_flipTriangleWinding = flipTriangleWinding;
+ }
virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const;
virtual void processAllTriangles(btTriangleCallback * callback, const btVector3& aabbMin, const btVector3& aabbMax) const;
@@ -166,16 +171,20 @@ public:
virtual void setLocalScaling(const btVector3& scaling);
virtual const btVector3& getLocalScaling() const;
-
- void getVertex(int x,int y,btVector3& vertex) const;
- void performRaycast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget) const;
+ void getVertex(int x, int y, btVector3& vertex) const;
+
+ void performRaycast(btTriangleCallback * callback, const btVector3& raySource, const btVector3& rayTarget) const;
- void buildAccelerator(int chunkSize=16);
+ void buildAccelerator(int chunkSize = 16);
void clearAccelerator();
+ int getUpAxis() const
+ {
+ return m_upAxis;
+ }
//debugging
virtual const char* getName() const { return "HEIGHTFIELD"; }
};
-#endif //BT_HEIGHTFIELD_TERRAIN_SHAPE_H
+#endif //BT_HEIGHTFIELD_TERRAIN_SHAPE_H \ No newline at end of file
diff --git a/thirdparty/bullet/BulletCollision/Gimpact/btGImpactBvhStructs.h b/thirdparty/bullet/BulletCollision/Gimpact/btGImpactBvhStructs.h
index 54888c6757..8f78c234b4 100644
--- a/thirdparty/bullet/BulletCollision/Gimpact/btGImpactBvhStructs.h
+++ b/thirdparty/bullet/BulletCollision/Gimpact/btGImpactBvhStructs.h
@@ -28,28 +28,7 @@ subject to the following restrictions:
#include "btBoxCollision.h"
#include "btTriangleShapeEx.h"
-
-//! Overlapping pair
-struct GIM_PAIR
-{
- int m_index1;
- int m_index2;
- GIM_PAIR()
- {
- }
-
- GIM_PAIR(const GIM_PAIR& p)
- {
- m_index1 = p.m_index1;
- m_index2 = p.m_index2;
- }
-
- GIM_PAIR(int index1, int index2)
- {
- m_index1 = index1;
- m_index2 = index2;
- }
-};
+#include "gim_pair.h" //for GIM_PAIR
///GIM_BVH_DATA is an internal GIMPACT collision structure to contain axis aligned bounding box
struct GIM_BVH_DATA
diff --git a/thirdparty/bullet/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp b/thirdparty/bullet/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp
index 3d8ab9f520..73e3db1010 100644
--- a/thirdparty/bullet/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp
+++ b/thirdparty/bullet/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp
@@ -18,7 +18,7 @@ subject to the following restrictions:
3. This notice may not be removed or altered from any source distribution.
*/
/*
-Author: Francisco Len Nßjera
+Author: Francisco Leon Najera
Concave-Concave Collision
*/
@@ -590,14 +590,16 @@ void btGImpactCollisionAlgorithm::gimpact_vs_shape(const btCollisionObjectWrappe
}
btCollisionObjectWrapper ob0(body0Wrap, colshape0, body0Wrap->getCollisionObject(), body0Wrap->getWorldTransform(), m_part0, m_triface0);
- const btCollisionObjectWrapper* prevObj0 = m_resultOut->getBody0Wrap();
+ const btCollisionObjectWrapper* prevObj;
if (m_resultOut->getBody0Wrap()->getCollisionObject() == ob0.getCollisionObject())
{
+ prevObj = m_resultOut->getBody0Wrap();
m_resultOut->setBody0Wrap(&ob0);
}
else
{
+ prevObj = m_resultOut->getBody1Wrap();
m_resultOut->setBody1Wrap(&ob0);
}
@@ -610,7 +612,15 @@ void btGImpactCollisionAlgorithm::gimpact_vs_shape(const btCollisionObjectWrappe
{
shape_vs_shape_collision(&ob0, body1Wrap, colshape0, shape1);
}
- m_resultOut->setBody0Wrap(prevObj0);
+
+ if (m_resultOut->getBody0Wrap()->getCollisionObject() == ob0.getCollisionObject())
+ {
+ m_resultOut->setBody0Wrap(prevObj);
+ }
+ else
+ {
+ m_resultOut->setBody1Wrap(prevObj);
+ }
}
shape0->unlockChildShapes();
diff --git a/thirdparty/bullet/BulletCollision/Gimpact/btGImpactShape.h b/thirdparty/bullet/BulletCollision/Gimpact/btGImpactShape.h
index 5b85e87041..eb33ce05e2 100644
--- a/thirdparty/bullet/BulletCollision/Gimpact/btGImpactShape.h
+++ b/thirdparty/bullet/BulletCollision/Gimpact/btGImpactShape.h
@@ -1,5 +1,5 @@
/*! \file btGImpactShape.h
-\author Francisco Len Nßjera
+\author Francisco Leon Najera
*/
/*
This source file is part of GIMPACT Library.
diff --git a/thirdparty/bullet/BulletCollision/Gimpact/gim_box_set.h b/thirdparty/bullet/BulletCollision/Gimpact/gim_box_set.h
index 0522007e4f..afc591dac0 100644
--- a/thirdparty/bullet/BulletCollision/Gimpact/gim_box_set.h
+++ b/thirdparty/bullet/BulletCollision/Gimpact/gim_box_set.h
@@ -37,28 +37,7 @@ email: projectileman@yahoo.com
#include "gim_radixsort.h"
#include "gim_box_collision.h"
#include "gim_tri_collision.h"
-
-//! Overlapping pair
-struct GIM_PAIR
-{
- GUINT m_index1;
- GUINT m_index2;
- GIM_PAIR()
- {
- }
-
- GIM_PAIR(const GIM_PAIR& p)
- {
- m_index1 = p.m_index1;
- m_index2 = p.m_index2;
- }
-
- GIM_PAIR(GUINT index1, GUINT index2)
- {
- m_index1 = index1;
- m_index2 = index2;
- }
-};
+#include "gim_pair.h"
//! A pairset array
class gim_pair_set : public gim_array<GIM_PAIR>
diff --git a/thirdparty/bullet/BulletCollision/Gimpact/gim_pair.h b/thirdparty/bullet/BulletCollision/Gimpact/gim_pair.h
new file mode 100644
index 0000000000..56c185a5dc
--- /dev/null
+++ b/thirdparty/bullet/BulletCollision/Gimpact/gim_pair.h
@@ -0,0 +1,28 @@
+#ifndef GIM_PAIR_H
+#define GIM_PAIR_H
+
+
+//! Overlapping pair
+struct GIM_PAIR
+{
+ int m_index1;
+ int m_index2;
+ GIM_PAIR()
+ {
+ }
+
+ GIM_PAIR(const GIM_PAIR& p)
+ {
+ m_index1 = p.m_index1;
+ m_index2 = p.m_index2;
+ }
+
+ GIM_PAIR(int index1, int index2)
+ {
+ m_index1 = index1;
+ m_index2 = index2;
+ }
+};
+
+#endif //GIM_PAIR_H
+
diff --git a/thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btConvexCast.h b/thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btConvexCast.h
index 76f54699c5..77b19be599 100644
--- a/thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btConvexCast.h
+++ b/thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btConvexCast.h
@@ -23,11 +23,11 @@ class btMinkowskiSumShape;
#include "LinearMath/btIDebugDraw.h"
#ifdef BT_USE_DOUBLE_PRECISION
-#define MAX_ITERATIONS 64
-#define MAX_EPSILON (SIMD_EPSILON * 10)
+#define MAX_CONVEX_CAST_ITERATIONS 64
+#define MAX_CONVEX_CAST_EPSILON (SIMD_EPSILON * 10)
#else
-#define MAX_ITERATIONS 32
-#define MAX_EPSILON btScalar(0.0001)
+#define MAX_CONVEX_CAST_ITERATIONS 32
+#define MAX_CONVEX_CAST_EPSILON btScalar(0.0001)
#endif
///Typically the conservative advancement reaches solution in a few iterations, clip it to 32 for degenerate cases.
///See discussion about this here http://continuousphysics.com/Bullet/phpBB2/viewtopic.php?t=565
@@ -58,8 +58,8 @@ public:
: m_fraction(btScalar(BT_LARGE_FLOAT)),
m_debugDrawer(0),
m_allowedPenetration(btScalar(0)),
- m_subSimplexCastMaxIterations(MAX_ITERATIONS),
- m_subSimplexCastEpsilon(MAX_EPSILON)
+ m_subSimplexCastMaxIterations(MAX_CONVEX_CAST_ITERATIONS),
+ m_subSimplexCastEpsilon(MAX_CONVEX_CAST_EPSILON)
{
}
diff --git a/thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp b/thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
index 803f6e0671..4339b2ea75 100644
--- a/thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
+++ b/thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp
@@ -1,4 +1,4 @@
-/*
+/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
diff --git a/thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h b/thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
index 2b2dfabec2..2d0df718a2 100644
--- a/thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
+++ b/thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
@@ -37,6 +37,7 @@ public:
///SubSimplexConvexCastRaytest is the default, even if kF_None is set.
kF_UseSubSimplexConvexCastRaytest = 1 << 2, // Uses an approximate but faster ray versus convex intersection algorithm
kF_UseGjkConvexCastRaytest = 1 << 3,
+ kF_DisableHeightfieldAccelerator = 1 << 4, //don't use the heightfield raycast accelerator. See https://github.com/bulletphysics/bullet3/pull/2062
kF_Terminator = 0xFFFFFFFF
};
unsigned int m_flags;
diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btBatchedConstraints.cpp b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btBatchedConstraints.cpp
index b51dfaad3c..2a5efc6495 100644
--- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btBatchedConstraints.cpp
+++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btBatchedConstraints.cpp
@@ -22,6 +22,8 @@ subject to the following restrictions:
#include <string.h> //for memset
+#include <cmath>
+
const int kNoMerge = -1;
bool btBatchedConstraints::s_debugDrawBatches = false;
@@ -520,7 +522,7 @@ static void writeGrainSizes(btBatchedConstraints* bc)
{
const Range& phase = bc->m_phases[iPhase];
int numBatches = phase.end - phase.begin;
- float grainSize = floor((0.25f * numBatches / float(numThreads)) + 0.0f);
+ float grainSize = std::floor((0.25f * numBatches / float(numThreads)) + 0.0f);
bc->m_phaseGrainSize[iPhase] = btMax(1, int(grainSize));
}
}
diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
index 10678b2a61..ac046aa6ea 100644
--- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
+++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp
@@ -19,6 +19,7 @@ Written by: Marcus Hennix
#include "BulletDynamics/Dynamics/btRigidBody.h"
#include "LinearMath/btTransformUtil.h"
#include "LinearMath/btMinMax.h"
+#include <cmath>
#include <new>
//#define CONETWIST_USE_OBSOLETE_SOLVER true
@@ -842,7 +843,7 @@ void btConeTwistConstraint::computeConeLimitInfo(const btQuaternion& qCone,
btScalar norm = 1 / (m_swingSpan2 * m_swingSpan2);
norm += surfaceSlope2 / (m_swingSpan1 * m_swingSpan1);
btScalar swingLimit2 = (1 + surfaceSlope2) / norm;
- swingLimit = sqrt(swingLimit2);
+ swingLimit = std::sqrt(swingLimit2);
}
// test!
@@ -887,7 +888,7 @@ btVector3 btConeTwistConstraint::GetPointForAngle(btScalar fAngleInRadians, btSc
btScalar norm = 1 / (m_swingSpan2 * m_swingSpan2);
norm += surfaceSlope2 / (m_swingSpan1 * m_swingSpan1);
btScalar swingLimit2 = (1 + surfaceSlope2) / norm;
- swingLimit = sqrt(swingLimit2);
+ swingLimit = std::sqrt(swingLimit2);
}
// convert into point in constraint space:
diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btConstraintSolver.h b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btConstraintSolver.h
index 808433477c..68a4a07a1d 100644
--- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btConstraintSolver.h
+++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btConstraintSolver.h
@@ -35,6 +35,7 @@ enum btConstraintSolverType
BT_MLCP_SOLVER = 2,
BT_NNCG_SOLVER = 4,
BT_MULTIBODY_SOLVER = 8,
+ BT_BLOCK_SOLVER = 16,
};
class btConstraintSolver
diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
index 89f8db8b1a..63d7c98e16 100644
--- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
+++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btContactSolverInfo.h
@@ -64,6 +64,7 @@ struct btContactSolverInfoData
btScalar m_restitutionVelocityThreshold;
bool m_jointFeedbackInWorldSpace;
bool m_jointFeedbackInJointFrame;
+ int m_reportSolverAnalytics;
};
struct btContactSolverInfo : public btContactSolverInfoData
@@ -98,6 +99,7 @@ struct btContactSolverInfo : public btContactSolverInfoData
m_restitutionVelocityThreshold = 0.2f; //if the relative velocity is below this threshold, there is zero restitution
m_jointFeedbackInWorldSpace = false;
m_jointFeedbackInJointFrame = false;
+ m_reportSolverAnalytics = 0;
}
};
diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp
index 49c8d9bbf7..9a3b39e6f8 100644
--- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp
+++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp
@@ -32,7 +32,7 @@ Cons:
/*
2007-09-09
-btGeneric6DofConstraint Refactored by Francisco Le?n
+btGeneric6DofConstraint Refactored by Francisco Leon
email: projectileman@yahoo.com
http://gimpact.sf.net
*/
@@ -40,6 +40,7 @@ http://gimpact.sf.net
#include "btGeneric6DofSpring2Constraint.h"
#include "BulletDynamics/Dynamics/btRigidBody.h"
#include "LinearMath/btTransformUtil.h"
+#include <cmath>
#include <new>
btGeneric6DofSpring2Constraint::btGeneric6DofSpring2Constraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, RotateOrder rotOrder)
@@ -310,9 +311,9 @@ void btGeneric6DofSpring2Constraint::calculateAngleInfo()
case RO_XYZ:
{
//Is this the "line of nodes" calculation choosing planes YZ (B coordinate system) and xy (A coordinate system)? (http://en.wikipedia.org/wiki/Euler_angles)
- //The two planes are non-homologous, so this is a Tait–Bryan angle formalism and not a proper Euler
+ //The two planes are non-homologous, so this is a Tait-Bryan angle formalism and not a proper Euler
//Extrinsic rotations are equal to the reversed order intrinsic rotations so the above xyz extrinsic rotations (axes are fixed) are the same as the zy'x" intrinsic rotations (axes are refreshed after each rotation)
- //that is why xy and YZ planes are chosen (this will describe a zy'x" intrinsic rotation) (see the figure on the left at http://en.wikipedia.org/wiki/Euler_angles under Tait–Bryan angles)
+ //that is why xy and YZ planes are chosen (this will describe a zy'x" intrinsic rotation) (see the figure on the left at http://en.wikipedia.org/wiki/Euler_angles under Tait-Bryan angles)
// x' = Nperp = N.cross(axis2)
// y' = N = axis2.cross(axis0)
// z' = z
@@ -845,7 +846,7 @@ int btGeneric6DofSpring2Constraint::get_limit_motor_info2(
if (m_rbA.getInvMass() == 0) m = mB; else
if (m_rbB.getInvMass() == 0) m = mA; else
m = mA*mB / (mA + mB);
- btScalar angularfreq = sqrt(ks / m);
+ btScalar angularfreq = btSqrt(ks / m);
//limit stiffness (the spring should not be sampled faster that the quarter of its angular frequency)
if (limot->m_springStiffnessLimited && 0.25 < angularfreq * dt)
@@ -865,7 +866,7 @@ int btGeneric6DofSpring2Constraint::get_limit_motor_info2(
// vel + f / m * (rotational ? -1 : 1)
// so in theory this should be set here for m_constraintError
// (with m_constraintError we set a desired velocity for the affected body(es))
- // however in practice any value is fine as long as it is greater then the "proper" velocity,
+ // however in practice any value is fine as long as it is greater than the "proper" velocity,
// because the m_lowerLimit and the m_upperLimit will determinate the strength of the final pulling force
// so it is much simpler (and more robust) just to simply use inf (with the proper sign)
// (Even with our best intent the "new" velocity is only an estimation. If we underestimate
@@ -1085,7 +1086,7 @@ void btGeneric6DofSpring2Constraint::setServoTarget(int index, btScalar targetOr
btScalar target = targetOrg + SIMD_PI;
if (1)
{
- btScalar m = target - SIMD_2_PI * floor(target / SIMD_2_PI);
+ btScalar m = target - SIMD_2_PI * std::floor(target / SIMD_2_PI);
// handle boundary cases resulted from floating-point cut off:
{
if (m >= SIMD_2_PI)
diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h
index bc3ee6d210..00e24364e0 100644
--- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h
+++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h
@@ -294,7 +294,7 @@ protected:
bool m_hasStaticBody;
int m_flags;
- btGeneric6DofSpring2Constraint& operator=(btGeneric6DofSpring2Constraint&)
+ btGeneric6DofSpring2Constraint& operator=(const btGeneric6DofSpring2Constraint&)
{
btAssert(0);
return *this;
diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
index def3227b43..d3b71e4583 100644
--- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
+++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp
@@ -394,6 +394,18 @@ btSingleConstraintRowSolver btSequentialImpulseConstraintSolver::getScalarConstr
return gResolveSingleConstraintRowLowerLimit_scalar_reference;
}
+btSingleConstraintRowSolver btSequentialImpulseConstraintSolver::getScalarSplitPenetrationImpulseGeneric()
+{
+ return gResolveSplitPenetrationImpulse_scalar_reference;
+}
+
+btSingleConstraintRowSolver btSequentialImpulseConstraintSolver::getSSE2SplitPenetrationImpulseGeneric()
+{
+ return gResolveSplitPenetrationImpulse_sse2;
+}
+
+
+
#ifdef USE_SIMD
btSingleConstraintRowSolver btSequentialImpulseConstraintSolver::getSSE2ConstraintRowSolverGeneric()
{
@@ -421,6 +433,11 @@ unsigned long btSequentialImpulseConstraintSolver::btRand2()
return m_btSeed2;
}
+unsigned long btSequentialImpulseConstraintSolver::btRand2a(unsigned long& seed)
+{
+ seed = (1664525L * seed + 1013904223L) & 0xffffffff;
+ return seed;
+}
//See ODE: adam's all-int straightforward(?) dRandInt (0..n-1)
int btSequentialImpulseConstraintSolver::btRandInt2(int n)
{
@@ -454,42 +471,44 @@ int btSequentialImpulseConstraintSolver::btRandInt2(int n)
return (int)(r % un);
}
-void btSequentialImpulseConstraintSolver::initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject, btScalar timeStep)
+int btSequentialImpulseConstraintSolver::btRandInt2a(int n, unsigned long& seed)
{
- btRigidBody* rb = collisionObject ? btRigidBody::upcast(collisionObject) : 0;
-
- solverBody->internalGetDeltaLinearVelocity().setValue(0.f, 0.f, 0.f);
- solverBody->internalGetDeltaAngularVelocity().setValue(0.f, 0.f, 0.f);
- solverBody->internalGetPushVelocity().setValue(0.f, 0.f, 0.f);
- solverBody->internalGetTurnVelocity().setValue(0.f, 0.f, 0.f);
+ // seems good; xor-fold and modulus
+ const unsigned long un = static_cast<unsigned long>(n);
+ unsigned long r = btSequentialImpulseConstraintSolver::btRand2a(seed);
- if (rb)
- {
- solverBody->m_worldTransform = rb->getWorldTransform();
- solverBody->internalSetInvMass(btVector3(rb->getInvMass(), rb->getInvMass(), rb->getInvMass()) * rb->getLinearFactor());
- solverBody->m_originalBody = rb;
- solverBody->m_angularFactor = rb->getAngularFactor();
- solverBody->m_linearFactor = rb->getLinearFactor();
- solverBody->m_linearVelocity = rb->getLinearVelocity();
- solverBody->m_angularVelocity = rb->getAngularVelocity();
- solverBody->m_externalForceImpulse = rb->getTotalForce() * rb->getInvMass() * timeStep;
- solverBody->m_externalTorqueImpulse = rb->getTotalTorque() * rb->getInvInertiaTensorWorld() * timeStep;
- }
- else
+ // note: probably more aggressive than it needs to be -- might be
+ // able to get away without one or two of the innermost branches.
+ if (un <= 0x00010000UL)
{
- solverBody->m_worldTransform.setIdentity();
- solverBody->internalSetInvMass(btVector3(0, 0, 0));
- solverBody->m_originalBody = 0;
- solverBody->m_angularFactor.setValue(1, 1, 1);
- solverBody->m_linearFactor.setValue(1, 1, 1);
- solverBody->m_linearVelocity.setValue(0, 0, 0);
- solverBody->m_angularVelocity.setValue(0, 0, 0);
- solverBody->m_externalForceImpulse.setValue(0, 0, 0);
- solverBody->m_externalTorqueImpulse.setValue(0, 0, 0);
+ r ^= (r >> 16);
+ if (un <= 0x00000100UL)
+ {
+ r ^= (r >> 8);
+ if (un <= 0x00000010UL)
+ {
+ r ^= (r >> 4);
+ if (un <= 0x00000004UL)
+ {
+ r ^= (r >> 2);
+ if (un <= 0x00000002UL)
+ {
+ r ^= (r >> 1);
+ }
+ }
+ }
+ }
}
+
+ return (int)(r % un);
}
-btScalar btSequentialImpulseConstraintSolver::restitutionCurve(btScalar rel_vel, btScalar restitution, btScalar velocityThreshold)
+void btSequentialImpulseConstraintSolver::initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject, btScalar timeStep)
+{
+ btSISolverSingleIterationData::initSolverBody(solverBody, collisionObject, timeStep);
+}
+
+btScalar btSequentialImpulseConstraintSolver::restitutionCurveInternal(btScalar rel_vel, btScalar restitution, btScalar velocityThreshold)
{
//printf("rel_vel =%f\n", rel_vel);
if (btFabs(rel_vel) < velocityThreshold)
@@ -498,6 +517,10 @@ btScalar btSequentialImpulseConstraintSolver::restitutionCurve(btScalar rel_vel,
btScalar rest = restitution * -rel_vel;
return rest;
}
+btScalar btSequentialImpulseConstraintSolver::restitutionCurve(btScalar rel_vel, btScalar restitution, btScalar velocityThreshold)
+{
+ return btSequentialImpulseConstraintSolver::restitutionCurveInternal(rel_vel, restitution, velocityThreshold);
+}
void btSequentialImpulseConstraintSolver::applyAnisotropicFriction(btCollisionObject* colObj, btVector3& frictionDirection, int frictionMode)
{
@@ -513,13 +536,13 @@ void btSequentialImpulseConstraintSolver::applyAnisotropicFriction(btCollisionOb
}
}
-void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstraint& solverConstraint, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip)
+void btSequentialImpulseConstraintSolver::setupFrictionConstraintInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool, btSolverConstraint& solverConstraint, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip)
{
- btSolverBody& solverBodyA = m_tmpSolverBodyPool[solverBodyIdA];
- btSolverBody& solverBodyB = m_tmpSolverBodyPool[solverBodyIdB];
+ btSolverBody& solverBodyA = tmpSolverBodyPool[solverBodyIdA];
+ btSolverBody& solverBodyB = tmpSolverBodyPool[solverBodyIdB];
- btRigidBody* body0 = m_tmpSolverBodyPool[solverBodyIdA].m_originalBody;
- btRigidBody* bodyA = m_tmpSolverBodyPool[solverBodyIdB].m_originalBody;
+ btRigidBody* body0 = tmpSolverBodyPool[solverBodyIdA].m_originalBody;
+ btRigidBody* bodyA = tmpSolverBodyPool[solverBodyIdB].m_originalBody;
solverConstraint.m_solverBodyIdA = solverBodyIdA;
solverConstraint.m_solverBodyIdB = solverBodyIdB;
@@ -605,30 +628,47 @@ void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstr
}
}
+void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstraint& solverConstraint, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip)
+{
+ btSequentialImpulseConstraintSolver::setupFrictionConstraintInternal(m_tmpSolverBodyPool, solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal, desiredVelocity, cfmSlip);
+}
+
+btSolverConstraint& btSequentialImpulseConstraintSolver::addFrictionConstraintInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool, btConstraintArray& tmpSolverContactFrictionConstraintPool, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip)
+{
+ btSolverConstraint& solverConstraint = tmpSolverContactFrictionConstraintPool.expandNonInitializing();
+ solverConstraint.m_frictionIndex = frictionIndex;
+ setupFrictionConstraintInternal(tmpSolverBodyPool, solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2,
+ colObj0, colObj1, relaxation, infoGlobal, desiredVelocity, cfmSlip);
+ return solverConstraint;
+}
+
+
+
btSolverConstraint& btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip)
{
btSolverConstraint& solverConstraint = m_tmpSolverContactFrictionConstraintPool.expandNonInitializing();
solverConstraint.m_frictionIndex = frictionIndex;
setupFrictionConstraint(solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2,
- colObj0, colObj1, relaxation, infoGlobal, desiredVelocity, cfmSlip);
+ colObj0, colObj1, relaxation, infoGlobal, desiredVelocity, cfmSlip);
return solverConstraint;
}
-void btSequentialImpulseConstraintSolver::setupTorsionalFrictionConstraint(btSolverConstraint& solverConstraint, const btVector3& normalAxis1, int solverBodyIdA, int solverBodyIdB,
- btManifoldPoint& cp, btScalar combinedTorsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2,
- btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation,
- btScalar desiredVelocity, btScalar cfmSlip)
+
+void btSequentialImpulseConstraintSolver::setupTorsionalFrictionConstraintInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool, btSolverConstraint& solverConstraint, const btVector3& normalAxis1, int solverBodyIdA, int solverBodyIdB,
+ btManifoldPoint& cp, btScalar combinedTorsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2,
+ btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation,
+ btScalar desiredVelocity, btScalar cfmSlip)
{
btVector3 normalAxis(0, 0, 0);
solverConstraint.m_contactNormal1 = normalAxis;
solverConstraint.m_contactNormal2 = -normalAxis;
- btSolverBody& solverBodyA = m_tmpSolverBodyPool[solverBodyIdA];
- btSolverBody& solverBodyB = m_tmpSolverBodyPool[solverBodyIdB];
+ btSolverBody& solverBodyA = tmpSolverBodyPool[solverBodyIdA];
+ btSolverBody& solverBodyB = tmpSolverBodyPool[solverBodyIdB];
- btRigidBody* body0 = m_tmpSolverBodyPool[solverBodyIdA].m_originalBody;
- btRigidBody* bodyA = m_tmpSolverBodyPool[solverBodyIdB].m_originalBody;
+ btRigidBody* body0 = tmpSolverBodyPool[solverBodyIdA].m_originalBody;
+ btRigidBody* bodyA = tmpSolverBodyPool[solverBodyIdB].m_originalBody;
solverConstraint.m_solverBodyIdA = solverBodyIdA;
solverConstraint.m_solverBodyIdB = solverBodyIdB;
@@ -677,15 +717,250 @@ void btSequentialImpulseConstraintSolver::setupTorsionalFrictionConstraint(btSol
}
}
+
+void btSequentialImpulseConstraintSolver::setupTorsionalFrictionConstraint(btSolverConstraint& solverConstraint, const btVector3& normalAxis1, int solverBodyIdA, int solverBodyIdB,
+ btManifoldPoint& cp, btScalar combinedTorsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2,
+ btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation,
+ btScalar desiredVelocity, btScalar cfmSlip)
+
+{
+ setupTorsionalFrictionConstraintInternal(m_tmpSolverBodyPool, solverConstraint, normalAxis1, solverBodyIdA, solverBodyIdB,
+ cp, combinedTorsionalFriction, rel_pos1, rel_pos2,
+ colObj0, colObj1, relaxation,
+ desiredVelocity, cfmSlip);
+
+}
+
+btSolverConstraint& btSequentialImpulseConstraintSolver::addTorsionalFrictionConstraintInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool, btConstraintArray& tmpSolverContactRollingFrictionConstraintPool, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, btScalar combinedTorsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity, btScalar cfmSlip)
+{
+ btSolverConstraint& solverConstraint = tmpSolverContactRollingFrictionConstraintPool.expandNonInitializing();
+ solverConstraint.m_frictionIndex = frictionIndex;
+ setupTorsionalFrictionConstraintInternal(tmpSolverBodyPool, solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, combinedTorsionalFriction, rel_pos1, rel_pos2,
+ colObj0, colObj1, relaxation, desiredVelocity, cfmSlip);
+ return solverConstraint;
+}
+
+
btSolverConstraint& btSequentialImpulseConstraintSolver::addTorsionalFrictionConstraint(const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, btScalar combinedTorsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity, btScalar cfmSlip)
{
btSolverConstraint& solverConstraint = m_tmpSolverContactRollingFrictionConstraintPool.expandNonInitializing();
solverConstraint.m_frictionIndex = frictionIndex;
setupTorsionalFrictionConstraint(solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, combinedTorsionalFriction, rel_pos1, rel_pos2,
- colObj0, colObj1, relaxation, desiredVelocity, cfmSlip);
+ colObj0, colObj1, relaxation, desiredVelocity, cfmSlip);
return solverConstraint;
}
+int btSISolverSingleIterationData::getOrInitSolverBody(btCollisionObject & body, btScalar timeStep)
+{
+#if BT_THREADSAFE
+ int solverBodyId = -1;
+ bool isRigidBodyType = btRigidBody::upcast(&body) != NULL;
+ if (isRigidBodyType && !body.isStaticOrKinematicObject())
+ {
+ // dynamic body
+ // Dynamic bodies can only be in one island, so it's safe to write to the companionId
+ solverBodyId = body.getCompanionId();
+ if (solverBodyId < 0)
+ {
+ solverBodyId = m_tmpSolverBodyPool.size();
+ btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
+ initSolverBody(&solverBody, &body, timeStep);
+ body.setCompanionId(solverBodyId);
+ }
+ }
+ else if (isRigidBodyType && body.isKinematicObject())
+ {
+ //
+ // NOTE: must test for kinematic before static because some kinematic objects also
+ // identify as "static"
+ //
+ // Kinematic bodies can be in multiple islands at once, so it is a
+ // race condition to write to them, so we use an alternate method
+ // to record the solverBodyId
+ int uniqueId = body.getWorldArrayIndex();
+ const int INVALID_SOLVER_BODY_ID = -1;
+ if (uniqueId >= m_kinematicBodyUniqueIdToSolverBodyTable.size())
+ {
+ m_kinematicBodyUniqueIdToSolverBodyTable.resize(uniqueId + 1, INVALID_SOLVER_BODY_ID);
+ }
+ solverBodyId = m_kinematicBodyUniqueIdToSolverBodyTable[uniqueId];
+ // if no table entry yet,
+ if (solverBodyId == INVALID_SOLVER_BODY_ID)
+ {
+ // create a table entry for this body
+ solverBodyId = m_tmpSolverBodyPool.size();
+ btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
+ initSolverBody(&solverBody, &body, timeStep);
+ m_kinematicBodyUniqueIdToSolverBodyTable[uniqueId] = solverBodyId;
+ }
+ }
+ else
+ {
+ bool isMultiBodyType = (body.getInternalType() & btCollisionObject::CO_FEATHERSTONE_LINK);
+ // Incorrectly set collision object flags can degrade performance in various ways.
+ if (!isMultiBodyType)
+ {
+ btAssert(body.isStaticOrKinematicObject());
+ }
+ //it could be a multibody link collider
+ // all fixed bodies (inf mass) get mapped to a single solver id
+ if (m_fixedBodyId < 0)
+ {
+ m_fixedBodyId = m_tmpSolverBodyPool.size();
+ btSolverBody& fixedBody = m_tmpSolverBodyPool.expand();
+ initSolverBody(&fixedBody, 0, timeStep);
+ }
+ solverBodyId = m_fixedBodyId;
+ }
+ btAssert(solverBodyId >= 0 && solverBodyId < m_tmpSolverBodyPool.size());
+ return solverBodyId;
+#else // BT_THREADSAFE
+
+ int solverBodyIdA = -1;
+
+ if (body.getCompanionId() >= 0)
+ {
+ //body has already been converted
+ solverBodyIdA = body.getCompanionId();
+ btAssert(solverBodyIdA < m_tmpSolverBodyPool.size());
+ }
+ else
+ {
+ btRigidBody* rb = btRigidBody::upcast(&body);
+ //convert both active and kinematic objects (for their velocity)
+ if (rb && (rb->getInvMass() || rb->isKinematicObject()))
+ {
+ solverBodyIdA = m_tmpSolverBodyPool.size();
+ btSolverBody& solverBody = m_tmpSolverBodyPool.expand();
+ initSolverBody(&solverBody, &body, timeStep);
+ body.setCompanionId(solverBodyIdA);
+ }
+ else
+ {
+ if (m_fixedBodyId < 0)
+ {
+ m_fixedBodyId = m_tmpSolverBodyPool.size();
+ btSolverBody& fixedBody = m_tmpSolverBodyPool.expand();
+ initSolverBody(&fixedBody, 0, timeStep);
+ }
+ return m_fixedBodyId;
+ // return 0;//assume first one is a fixed solver body
+ }
+ }
+
+ return solverBodyIdA;
+#endif // BT_THREADSAFE
+}
+void btSISolverSingleIterationData::initSolverBody(btSolverBody * solverBody, btCollisionObject * collisionObject, btScalar timeStep)
+{
+ btRigidBody* rb = collisionObject ? btRigidBody::upcast(collisionObject) : 0;
+
+ solverBody->internalGetDeltaLinearVelocity().setValue(0.f, 0.f, 0.f);
+ solverBody->internalGetDeltaAngularVelocity().setValue(0.f, 0.f, 0.f);
+ solverBody->internalGetPushVelocity().setValue(0.f, 0.f, 0.f);
+ solverBody->internalGetTurnVelocity().setValue(0.f, 0.f, 0.f);
+
+ if (rb)
+ {
+ solverBody->m_worldTransform = rb->getWorldTransform();
+ solverBody->internalSetInvMass(btVector3(rb->getInvMass(), rb->getInvMass(), rb->getInvMass()) * rb->getLinearFactor());
+ solverBody->m_originalBody = rb;
+ solverBody->m_angularFactor = rb->getAngularFactor();
+ solverBody->m_linearFactor = rb->getLinearFactor();
+ solverBody->m_linearVelocity = rb->getLinearVelocity();
+ solverBody->m_angularVelocity = rb->getAngularVelocity();
+ solverBody->m_externalForceImpulse = rb->getTotalForce() * rb->getInvMass() * timeStep;
+ solverBody->m_externalTorqueImpulse = rb->getTotalTorque() * rb->getInvInertiaTensorWorld() * timeStep;
+ }
+ else
+ {
+ solverBody->m_worldTransform.setIdentity();
+ solverBody->internalSetInvMass(btVector3(0, 0, 0));
+ solverBody->m_originalBody = 0;
+ solverBody->m_angularFactor.setValue(1, 1, 1);
+ solverBody->m_linearFactor.setValue(1, 1, 1);
+ solverBody->m_linearVelocity.setValue(0, 0, 0);
+ solverBody->m_angularVelocity.setValue(0, 0, 0);
+ solverBody->m_externalForceImpulse.setValue(0, 0, 0);
+ solverBody->m_externalTorqueImpulse.setValue(0, 0, 0);
+ }
+}
+
+int btSISolverSingleIterationData::getSolverBody(btCollisionObject& body) const
+{
+#if BT_THREADSAFE
+ int solverBodyId = -1;
+ bool isRigidBodyType = btRigidBody::upcast(&body) != NULL;
+ if (isRigidBodyType && !body.isStaticOrKinematicObject())
+ {
+ // dynamic body
+ // Dynamic bodies can only be in one island, so it's safe to write to the companionId
+ solverBodyId = body.getCompanionId();
+ btAssert(solverBodyId >= 0);
+ }
+ else if (isRigidBodyType && body.isKinematicObject())
+ {
+ //
+ // NOTE: must test for kinematic before static because some kinematic objects also
+ // identify as "static"
+ //
+ // Kinematic bodies can be in multiple islands at once, so it is a
+ // race condition to write to them, so we use an alternate method
+ // to record the solverBodyId
+ int uniqueId = body.getWorldArrayIndex();
+ const int INVALID_SOLVER_BODY_ID = -1;
+ if (uniqueId >= m_kinematicBodyUniqueIdToSolverBodyTable.size())
+ {
+ m_kinematicBodyUniqueIdToSolverBodyTable.resize(uniqueId + 1, INVALID_SOLVER_BODY_ID);
+ }
+ solverBodyId = m_kinematicBodyUniqueIdToSolverBodyTable[uniqueId];
+ btAssert(solverBodyId != INVALID_SOLVER_BODY_ID);
+ }
+ else
+ {
+ bool isMultiBodyType = (body.getInternalType() & btCollisionObject::CO_FEATHERSTONE_LINK);
+ // Incorrectly set collision object flags can degrade performance in various ways.
+ if (!isMultiBodyType)
+ {
+ btAssert(body.isStaticOrKinematicObject());
+ }
+ btAssert(m_fixedBodyId >= 0);
+ solverBodyId = m_fixedBodyId;
+ }
+ btAssert(solverBodyId >= 0 && solverBodyId < m_tmpSolverBodyPool.size());
+ return solverBodyId;
+#else // BT_THREADSAFE
+ int solverBodyIdA = -1;
+
+ if (body.getCompanionId() >= 0)
+ {
+ //body has already been converted
+ solverBodyIdA = body.getCompanionId();
+ btAssert(solverBodyIdA < m_tmpSolverBodyPool.size());
+ }
+ else
+ {
+ btRigidBody* rb = btRigidBody::upcast(&body);
+ //convert both active and kinematic objects (for their velocity)
+ if (rb && (rb->getInvMass() || rb->isKinematicObject()))
+ {
+ btAssert(0);
+ }
+ else
+ {
+ if (m_fixedBodyId < 0)
+ {
+ btAssert(0);
+ }
+ return m_fixedBodyId;
+ // return 0;//assume first one is a fixed solver body
+ }
+ }
+
+ return solverBodyIdA;
+#endif // BT_THREADSAFE
+}
+
int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject& body, btScalar timeStep)
{
#if BT_THREADSAFE
@@ -789,17 +1064,20 @@ int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject&
}
#include <stdio.h>
-void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstraint& solverConstraint,
- int solverBodyIdA, int solverBodyIdB,
- btManifoldPoint& cp, const btContactSolverInfo& infoGlobal,
- btScalar& relaxation,
- const btVector3& rel_pos1, const btVector3& rel_pos2)
+
+
+void btSequentialImpulseConstraintSolver::setupContactConstraintInternal(btSISolverSingleIterationData& siData,
+ btSolverConstraint& solverConstraint,
+ int solverBodyIdA, int solverBodyIdB,
+ btManifoldPoint& cp, const btContactSolverInfo& infoGlobal,
+ btScalar& relaxation,
+ const btVector3& rel_pos1, const btVector3& rel_pos2)
{
// const btVector3& pos1 = cp.getPositionWorldOnA();
// const btVector3& pos2 = cp.getPositionWorldOnB();
- btSolverBody* bodyA = &m_tmpSolverBodyPool[solverBodyIdA];
- btSolverBody* bodyB = &m_tmpSolverBodyPool[solverBodyIdB];
+ btSolverBody* bodyA = &siData.m_tmpSolverBodyPool[solverBodyIdA];
+ btSolverBody* bodyB = &siData.m_tmpSolverBodyPool[solverBodyIdB];
btRigidBody* rb0 = bodyA->m_originalBody;
btRigidBody* rb1 = bodyB->m_originalBody;
@@ -906,7 +1184,7 @@ void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstra
solverConstraint.m_friction = cp.m_combinedFriction;
- restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution, infoGlobal.m_restitutionVelocityThreshold);
+ restitution = btSequentialImpulseConstraintSolver::restitutionCurveInternal(rel_vel, cp.m_combinedRestitution, infoGlobal.m_restitutionVelocityThreshold);
if (restitution <= btScalar(0.))
{
restitution = 0.f;
@@ -920,7 +1198,7 @@ void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstra
if (rb0)
bodyA->internalApplyImpulse(solverConstraint.m_contactNormal1 * bodyA->internalGetInvMass(), solverConstraint.m_angularComponentA, solverConstraint.m_appliedImpulse);
if (rb1)
- bodyB->internalApplyImpulse(-solverConstraint.m_contactNormal2 * bodyB->internalGetInvMass() , -solverConstraint.m_angularComponentB, -(btScalar)solverConstraint.m_appliedImpulse);
+ bodyB->internalApplyImpulse(-solverConstraint.m_contactNormal2 * bodyB->internalGetInvMass(), -solverConstraint.m_angularComponentB, -(btScalar)solverConstraint.m_appliedImpulse);
}
else
{
@@ -974,25 +1252,59 @@ void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstra
}
}
-void btSequentialImpulseConstraintSolver::setFrictionConstraintImpulse(btSolverConstraint& solverConstraint,
- int solverBodyIdA, int solverBodyIdB,
- btManifoldPoint& cp, const btContactSolverInfo& infoGlobal)
+void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstraint& solverConstraint,
+ int solverBodyIdA, int solverBodyIdB,
+ btManifoldPoint& cp, const btContactSolverInfo& infoGlobal,
+ btScalar& relaxation,
+ const btVector3& rel_pos1, const btVector3& rel_pos2)
+{
+ btSISolverSingleIterationData siData(m_tmpSolverBodyPool,
+ m_tmpSolverContactConstraintPool,
+ m_tmpSolverNonContactConstraintPool,
+ m_tmpSolverContactFrictionConstraintPool,
+ m_tmpSolverContactRollingFrictionConstraintPool,
+ m_orderTmpConstraintPool,
+ m_orderNonContactConstraintPool,
+ m_orderFrictionConstraintPool,
+ m_tmpConstraintSizesPool,
+ m_resolveSingleConstraintRowGeneric,
+ m_resolveSingleConstraintRowLowerLimit,
+ m_resolveSplitPenetrationImpulse,
+ m_kinematicBodyUniqueIdToSolverBodyTable,
+ m_btSeed2,
+ m_fixedBodyId,
+ m_maxOverrideNumSolverIterations
+ );
+
+
+ setupContactConstraintInternal(siData, solverConstraint,
+ solverBodyIdA, solverBodyIdB,
+ cp, infoGlobal,
+ relaxation,
+ rel_pos1, rel_pos2);
+}
+
+
+void btSequentialImpulseConstraintSolver::setFrictionConstraintImpulseInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool, btConstraintArray& tmpSolverContactFrictionConstraintPool,
+ btSolverConstraint& solverConstraint,
+ int solverBodyIdA, int solverBodyIdB,
+ btManifoldPoint& cp, const btContactSolverInfo& infoGlobal)
{
- btSolverBody* bodyA = &m_tmpSolverBodyPool[solverBodyIdA];
- btSolverBody* bodyB = &m_tmpSolverBodyPool[solverBodyIdB];
+ btSolverBody* bodyA = &tmpSolverBodyPool[solverBodyIdA];
+ btSolverBody* bodyB = &tmpSolverBodyPool[solverBodyIdB];
btRigidBody* rb0 = bodyA->m_originalBody;
btRigidBody* rb1 = bodyB->m_originalBody;
{
- btSolverConstraint& frictionConstraint1 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex];
+ btSolverConstraint& frictionConstraint1 = tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex];
if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
{
frictionConstraint1.m_appliedImpulse = cp.m_appliedImpulseLateral1 * infoGlobal.m_warmstartingFactor;
if (rb0)
- bodyA->internalApplyImpulse(frictionConstraint1.m_contactNormal1 * rb0->getInvMass() , frictionConstraint1.m_angularComponentA, frictionConstraint1.m_appliedImpulse);
+ bodyA->internalApplyImpulse(frictionConstraint1.m_contactNormal1 * rb0->getInvMass(), frictionConstraint1.m_angularComponentA, frictionConstraint1.m_appliedImpulse);
if (rb1)
- bodyB->internalApplyImpulse(-frictionConstraint1.m_contactNormal2 * rb1->getInvMass() , -frictionConstraint1.m_angularComponentB, -(btScalar)frictionConstraint1.m_appliedImpulse);
+ bodyB->internalApplyImpulse(-frictionConstraint1.m_contactNormal2 * rb1->getInvMass(), -frictionConstraint1.m_angularComponentB, -(btScalar)frictionConstraint1.m_appliedImpulse);
}
else
{
@@ -1002,7 +1314,7 @@ void btSequentialImpulseConstraintSolver::setFrictionConstraintImpulse(btSolverC
if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
{
- btSolverConstraint& frictionConstraint2 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex + 1];
+ btSolverConstraint& frictionConstraint2 = tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex + 1];
if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
{
frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor;
@@ -1018,21 +1330,31 @@ void btSequentialImpulseConstraintSolver::setFrictionConstraintImpulse(btSolverC
}
}
-void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* manifold, const btContactSolverInfo& infoGlobal)
+void btSequentialImpulseConstraintSolver::setFrictionConstraintImpulse(btSolverConstraint& solverConstraint,
+ int solverBodyIdA, int solverBodyIdB,
+ btManifoldPoint& cp, const btContactSolverInfo& infoGlobal)
+{
+ setFrictionConstraintImpulseInternal(m_tmpSolverBodyPool, m_tmpSolverContactFrictionConstraintPool,
+ solverConstraint,
+ solverBodyIdA, solverBodyIdB,
+ cp, infoGlobal);
+
+}
+void btSequentialImpulseConstraintSolver::convertContactInternal(btSISolverSingleIterationData& siData, btPersistentManifold* manifold, const btContactSolverInfo& infoGlobal)
{
btCollisionObject *colObj0 = 0, *colObj1 = 0;
colObj0 = (btCollisionObject*)manifold->getBody0();
colObj1 = (btCollisionObject*)manifold->getBody1();
- int solverBodyIdA = getOrInitSolverBody(*colObj0, infoGlobal.m_timeStep);
- int solverBodyIdB = getOrInitSolverBody(*colObj1, infoGlobal.m_timeStep);
+ int solverBodyIdA = siData.getOrInitSolverBody(*colObj0, infoGlobal.m_timeStep);
+ int solverBodyIdB = siData.getOrInitSolverBody(*colObj1, infoGlobal.m_timeStep);
// btRigidBody* bodyA = btRigidBody::upcast(colObj0);
// btRigidBody* bodyB = btRigidBody::upcast(colObj1);
- btSolverBody* solverBodyA = &m_tmpSolverBodyPool[solverBodyIdA];
- btSolverBody* solverBodyB = &m_tmpSolverBodyPool[solverBodyIdB];
+ btSolverBody* solverBodyA = &siData.m_tmpSolverBodyPool[solverBodyIdA];
+ btSolverBody* solverBodyB = &siData.m_tmpSolverBodyPool[solverBodyIdB];
///avoid collision response between two static objects
if (!solverBodyA || (solverBodyA->m_invMass.fuzzyZero() && (!solverBodyB || solverBodyB->m_invMass.fuzzyZero())))
@@ -1049,8 +1371,8 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
btVector3 rel_pos2;
btScalar relaxation;
- int frictionIndex = m_tmpSolverContactConstraintPool.size();
- btSolverConstraint& solverConstraint = m_tmpSolverContactConstraintPool.expandNonInitializing();
+ int frictionIndex = siData.m_tmpSolverContactConstraintPool.size();
+ btSolverConstraint& solverConstraint = siData.m_tmpSolverContactConstraintPool.expandNonInitializing();
solverConstraint.m_solverBodyIdA = solverBodyIdA;
solverConstraint.m_solverBodyIdB = solverBodyIdB;
@@ -1071,16 +1393,20 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
btVector3 vel = vel1 - vel2;
btScalar rel_vel = cp.m_normalWorldOnB.dot(vel);
- setupContactConstraint(solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal, relaxation, rel_pos1, rel_pos2);
+ setupContactConstraintInternal(siData, solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal, relaxation, rel_pos1, rel_pos2);
/////setup the friction constraints
- solverConstraint.m_frictionIndex = m_tmpSolverContactFrictionConstraintPool.size();
+ solverConstraint.m_frictionIndex = siData.m_tmpSolverContactFrictionConstraintPool.size();
if ((cp.m_combinedRollingFriction > 0.f) && (rollingFriction > 0))
{
{
- addTorsionalFrictionConstraint(cp.m_normalWorldOnB, solverBodyIdA, solverBodyIdB, frictionIndex, cp, cp.m_combinedSpinningFriction, rel_pos1, rel_pos2, colObj0, colObj1, relaxation);
+
+ btSequentialImpulseConstraintSolver::addTorsionalFrictionConstraintInternal(siData.m_tmpSolverBodyPool,
+ siData.m_tmpSolverContactRollingFrictionConstraintPool,
+ cp.m_normalWorldOnB, solverBodyIdA, solverBodyIdB, frictionIndex, cp, cp.m_combinedSpinningFriction, rel_pos1, rel_pos2, colObj0, colObj1, relaxation);
+
btVector3 axis0, axis1;
btPlaneSpace1(cp.m_normalWorldOnB, axis0, axis1);
axis0.normalize();
@@ -1091,11 +1417,17 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
applyAnisotropicFriction(colObj0, axis1, btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
applyAnisotropicFriction(colObj1, axis1, btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
if (axis0.length() > 0.001)
- addTorsionalFrictionConstraint(axis0, solverBodyIdA, solverBodyIdB, frictionIndex, cp,
- cp.m_combinedRollingFriction, rel_pos1, rel_pos2, colObj0, colObj1, relaxation);
+ {
+ btSequentialImpulseConstraintSolver::addTorsionalFrictionConstraintInternal(siData.m_tmpSolverBodyPool,
+ siData.m_tmpSolverContactRollingFrictionConstraintPool, axis0, solverBodyIdA, solverBodyIdB, frictionIndex, cp,
+ cp.m_combinedRollingFriction, rel_pos1, rel_pos2, colObj0, colObj1, relaxation);
+ }
if (axis1.length() > 0.001)
- addTorsionalFrictionConstraint(axis1, solverBodyIdA, solverBodyIdB, frictionIndex, cp,
- cp.m_combinedRollingFriction, rel_pos1, rel_pos2, colObj0, colObj1, relaxation);
+ {
+ btSequentialImpulseConstraintSolver::addTorsionalFrictionConstraintInternal(siData.m_tmpSolverBodyPool,
+ siData.m_tmpSolverContactRollingFrictionConstraintPool, axis1, solverBodyIdA, solverBodyIdB, frictionIndex, cp,
+ cp.m_combinedRollingFriction, rel_pos1, rel_pos2, colObj0, colObj1, relaxation);
+ }
}
}
@@ -1124,7 +1456,8 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
cp.m_lateralFrictionDir1 *= 1.f / btSqrt(lat_rel_vel);
applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION);
applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION);
- addFrictionConstraint(cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal);
+ btSequentialImpulseConstraintSolver::addFrictionConstraintInternal(siData.m_tmpSolverBodyPool, siData.m_tmpSolverContactFrictionConstraintPool,
+ cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal);
if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
{
@@ -1132,7 +1465,8 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
cp.m_lateralFrictionDir2.normalize(); //??
applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION);
applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION);
- addFrictionConstraint(cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal);
+ btSequentialImpulseConstraintSolver::addFrictionConstraintInternal(siData.m_tmpSolverBodyPool, siData.m_tmpSolverContactFrictionConstraintPool,
+ cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal);
}
}
else
@@ -1141,13 +1475,15 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION);
applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION);
- addFrictionConstraint(cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal);
+ btSequentialImpulseConstraintSolver::addFrictionConstraintInternal(siData.m_tmpSolverBodyPool, siData.m_tmpSolverContactFrictionConstraintPool,
+ cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal);
if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
{
applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION);
applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION);
- addFrictionConstraint(cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal);
+ btSequentialImpulseConstraintSolver::addFrictionConstraintInternal(siData.m_tmpSolverBodyPool, siData.m_tmpSolverContactFrictionConstraintPool,
+ cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal);
}
if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) && (infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION))
@@ -1158,16 +1494,44 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m
}
else
{
- addFrictionConstraint(cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal, cp.m_contactMotion1, cp.m_frictionCFM);
+ btSequentialImpulseConstraintSolver::addFrictionConstraintInternal(siData.m_tmpSolverBodyPool, siData.m_tmpSolverContactFrictionConstraintPool,
+ cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal, cp.m_contactMotion1, cp.m_frictionCFM);
if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
- addFrictionConstraint(cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal, cp.m_contactMotion2, cp.m_frictionCFM);
+ {
+ btSequentialImpulseConstraintSolver::addFrictionConstraintInternal(siData.m_tmpSolverBodyPool, siData.m_tmpSolverContactFrictionConstraintPool,
+ cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal, cp.m_contactMotion2, cp.m_frictionCFM);
+ }
}
- setFrictionConstraintImpulse(solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal);
+ btSequentialImpulseConstraintSolver::setFrictionConstraintImpulseInternal(
+ siData.m_tmpSolverBodyPool, siData.m_tmpSolverContactFrictionConstraintPool,
+ solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal);
}
}
}
+void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* manifold, const btContactSolverInfo& infoGlobal)
+{
+ btSISolverSingleIterationData siData(m_tmpSolverBodyPool,
+ m_tmpSolverContactConstraintPool,
+ m_tmpSolverNonContactConstraintPool,
+ m_tmpSolverContactFrictionConstraintPool,
+ m_tmpSolverContactRollingFrictionConstraintPool,
+ m_orderTmpConstraintPool,
+ m_orderNonContactConstraintPool,
+ m_orderFrictionConstraintPool,
+ m_tmpConstraintSizesPool,
+ m_resolveSingleConstraintRowGeneric,
+ m_resolveSingleConstraintRowLowerLimit,
+ m_resolveSplitPenetrationImpulse,
+ m_kinematicBodyUniqueIdToSolverBodyTable,
+ m_btSeed2,
+ m_fixedBodyId,
+ m_maxOverrideNumSolverIterations);
+
+ btSequentialImpulseConstraintSolver::convertContactInternal(siData, manifold, infoGlobal);
+}
+
void btSequentialImpulseConstraintSolver::convertContacts(btPersistentManifold** manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal)
{
int i;
@@ -1181,22 +1545,24 @@ void btSequentialImpulseConstraintSolver::convertContacts(btPersistentManifold**
}
}
-void btSequentialImpulseConstraintSolver::convertJoint(btSolverConstraint* currentConstraintRow,
- btTypedConstraint* constraint,
- const btTypedConstraint::btConstraintInfo1& info1,
- int solverBodyIdA,
- int solverBodyIdB,
- const btContactSolverInfo& infoGlobal)
+void btSequentialImpulseConstraintSolver::convertJointInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool,
+ int& maxOverrideNumSolverIterations,
+ btSolverConstraint* currentConstraintRow,
+ btTypedConstraint* constraint,
+ const btTypedConstraint::btConstraintInfo1& info1,
+ int solverBodyIdA,
+ int solverBodyIdB,
+ const btContactSolverInfo& infoGlobal)
{
const btRigidBody& rbA = constraint->getRigidBodyA();
const btRigidBody& rbB = constraint->getRigidBodyB();
- const btSolverBody* bodyAPtr = &m_tmpSolverBodyPool[solverBodyIdA];
- const btSolverBody* bodyBPtr = &m_tmpSolverBodyPool[solverBodyIdB];
+ const btSolverBody* bodyAPtr = &tmpSolverBodyPool[solverBodyIdA];
+ const btSolverBody* bodyBPtr = &tmpSolverBodyPool[solverBodyIdB];
int overrideNumSolverIterations = constraint->getOverrideNumSolverIterations() > 0 ? constraint->getOverrideNumSolverIterations() : infoGlobal.m_numIterations;
- if (overrideNumSolverIterations > m_maxOverrideNumSolverIterations)
- m_maxOverrideNumSolverIterations = overrideNumSolverIterations;
+ if (overrideNumSolverIterations > maxOverrideNumSolverIterations)
+ maxOverrideNumSolverIterations = overrideNumSolverIterations;
for (int j = 0; j < info1.m_numConstraintRows; j++)
{
@@ -1236,7 +1602,7 @@ void btSequentialImpulseConstraintSolver::convertJoint(btSolverConstraint* curre
info2.m_J2linearAxis = currentConstraintRow->m_contactNormal2;
info2.m_J2angularAxis = currentConstraintRow->m_relpos2CrossNormal;
info2.rowskip = sizeof(btSolverConstraint) / sizeof(btScalar); //check this
- ///the size of btSolverConstraint needs be a multiple of btScalar
+ ///the size of btSolverConstraint needs be a multiple of btScalar
btAssert(info2.rowskip * sizeof(btScalar) == sizeof(btSolverConstraint));
info2.m_constraintError = &currentConstraintRow->m_rhs;
currentConstraintRow->m_cfm = infoGlobal.m_globalCfm;
@@ -1313,7 +1679,16 @@ void btSequentialImpulseConstraintSolver::convertJoint(btSolverConstraint* curre
}
}
-void btSequentialImpulseConstraintSolver::convertJoints(btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal)
+void btSequentialImpulseConstraintSolver::convertJoint(btSolverConstraint* currentConstraintRow,
+ btTypedConstraint* constraint,
+ const btTypedConstraint::btConstraintInfo1& info1,
+ int solverBodyIdA,
+ int solverBodyIdB,
+ const btContactSolverInfo& infoGlobal)
+{
+}
+
+void btSequentialImpulseConstraintSolver::convertJointsInternal(btSISolverSingleIterationData& siData, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal)
{
BT_PROFILE("convertJoints");
for (int j = 0; j < numConstraints; j++)
@@ -1325,11 +1700,11 @@ void btSequentialImpulseConstraintSolver::convertJoints(btTypedConstraint** cons
int totalNumRows = 0;
- m_tmpConstraintSizesPool.resizeNoInitialize(numConstraints);
+ siData.m_tmpConstraintSizesPool.resizeNoInitialize(numConstraints);
//calculate the total number of contraint rows
for (int i = 0; i < numConstraints; i++)
{
- btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
+ btTypedConstraint::btConstraintInfo1& info1 = siData.m_tmpConstraintSizesPool[i];
btJointFeedback* fb = constraints[i]->getJointFeedback();
if (fb)
{
@@ -1350,34 +1725,58 @@ void btSequentialImpulseConstraintSolver::convertJoints(btTypedConstraint** cons
}
totalNumRows += info1.m_numConstraintRows;
}
- m_tmpSolverNonContactConstraintPool.resizeNoInitialize(totalNumRows);
+ siData.m_tmpSolverNonContactConstraintPool.resizeNoInitialize(totalNumRows);
///setup the btSolverConstraints
int currentRow = 0;
for (int i = 0; i < numConstraints; i++)
{
- const btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i];
+ const btTypedConstraint::btConstraintInfo1& info1 = siData.m_tmpConstraintSizesPool[i];
if (info1.m_numConstraintRows)
{
btAssert(currentRow < totalNumRows);
- btSolverConstraint* currentConstraintRow = &m_tmpSolverNonContactConstraintPool[currentRow];
+ btSolverConstraint* currentConstraintRow = &siData.m_tmpSolverNonContactConstraintPool[currentRow];
btTypedConstraint* constraint = constraints[i];
btRigidBody& rbA = constraint->getRigidBodyA();
btRigidBody& rbB = constraint->getRigidBodyB();
- int solverBodyIdA = getOrInitSolverBody(rbA, infoGlobal.m_timeStep);
- int solverBodyIdB = getOrInitSolverBody(rbB, infoGlobal.m_timeStep);
+ int solverBodyIdA = siData.getOrInitSolverBody(rbA, infoGlobal.m_timeStep);
+ int solverBodyIdB = siData.getOrInitSolverBody(rbB, infoGlobal.m_timeStep);
- convertJoint(currentConstraintRow, constraint, info1, solverBodyIdA, solverBodyIdB, infoGlobal);
+ convertJointInternal(siData.m_tmpSolverBodyPool, siData.m_maxOverrideNumSolverIterations,
+ currentConstraintRow, constraint, info1, solverBodyIdA, solverBodyIdB, infoGlobal);
}
currentRow += info1.m_numConstraintRows;
}
}
-void btSequentialImpulseConstraintSolver::convertBodies(btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal)
+void btSequentialImpulseConstraintSolver::convertJoints(btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal)
+{
+ btSISolverSingleIterationData siData(m_tmpSolverBodyPool,
+ m_tmpSolverContactConstraintPool,
+ m_tmpSolverNonContactConstraintPool,
+ m_tmpSolverContactFrictionConstraintPool,
+ m_tmpSolverContactRollingFrictionConstraintPool,
+ m_orderTmpConstraintPool,
+ m_orderNonContactConstraintPool,
+ m_orderFrictionConstraintPool,
+ m_tmpConstraintSizesPool,
+ m_resolveSingleConstraintRowGeneric,
+ m_resolveSingleConstraintRowLowerLimit,
+ m_resolveSplitPenetrationImpulse,
+ m_kinematicBodyUniqueIdToSolverBodyTable,
+ m_btSeed2,
+ m_fixedBodyId,
+ m_maxOverrideNumSolverIterations);
+
+ convertJointsInternal(siData, constraints, numConstraints, infoGlobal);
+}
+
+
+void btSequentialImpulseConstraintSolver::convertBodiesInternal(btSISolverSingleIterationData& siData, btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal)
{
BT_PROFILE("convertBodies");
for (int i = 0; i < numBodies; i++)
@@ -1385,23 +1784,23 @@ void btSequentialImpulseConstraintSolver::convertBodies(btCollisionObject** bodi
bodies[i]->setCompanionId(-1);
}
#if BT_THREADSAFE
- m_kinematicBodyUniqueIdToSolverBodyTable.resize(0);
+ siData.m_kinematicBodyUniqueIdToSolverBodyTable.resize(0);
#endif // BT_THREADSAFE
- m_tmpSolverBodyPool.reserve(numBodies + 1);
- m_tmpSolverBodyPool.resize(0);
+ siData.m_tmpSolverBodyPool.reserve(numBodies + 1);
+ siData.m_tmpSolverBodyPool.resize(0);
//btSolverBody& fixedBody = m_tmpSolverBodyPool.expand();
//initSolverBody(&fixedBody,0);
for (int i = 0; i < numBodies; i++)
{
- int bodyId = getOrInitSolverBody(*bodies[i], infoGlobal.m_timeStep);
+ int bodyId = siData.getOrInitSolverBody(*bodies[i], infoGlobal.m_timeStep);
btRigidBody* body = btRigidBody::upcast(bodies[i]);
if (body && body->getInvMass())
{
- btSolverBody& solverBody = m_tmpSolverBodyPool[bodyId];
+ btSolverBody& solverBody = siData.m_tmpSolverBodyPool[bodyId];
btVector3 gyroForce(0, 0, 0);
if (body->getFlags() & BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT)
{
@@ -1422,6 +1821,29 @@ void btSequentialImpulseConstraintSolver::convertBodies(btCollisionObject** bodi
}
}
+
+void btSequentialImpulseConstraintSolver::convertBodies(btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal)
+{
+ btSISolverSingleIterationData siData(m_tmpSolverBodyPool,
+ m_tmpSolverContactConstraintPool,
+ m_tmpSolverNonContactConstraintPool,
+ m_tmpSolverContactFrictionConstraintPool,
+ m_tmpSolverContactRollingFrictionConstraintPool,
+ m_orderTmpConstraintPool,
+ m_orderNonContactConstraintPool,
+ m_orderFrictionConstraintPool,
+ m_tmpConstraintSizesPool,
+ m_resolveSingleConstraintRowGeneric,
+ m_resolveSingleConstraintRowLowerLimit,
+ m_resolveSplitPenetrationImpulse,
+ m_kinematicBodyUniqueIdToSolverBodyTable,
+ m_btSeed2,
+ m_fixedBodyId,
+ m_maxOverrideNumSolverIterations);
+
+ convertBodiesInternal(siData, bodies, numBodies, infoGlobal);
+}
+
btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer)
{
m_fixedBodyId = -1;
@@ -1545,14 +1967,14 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol
return 0.f;
}
-btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration, btCollisionObject** /*bodies */, int /*numBodies*/, btPersistentManifold** /*manifoldPtr*/, int /*numManifolds*/, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* /*debugDrawer*/)
+btScalar btSequentialImpulseConstraintSolver::solveSingleIterationInternal(btSISolverSingleIterationData& siData, int iteration, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal)
{
BT_PROFILE("solveSingleIteration");
btScalar leastSquaresResidual = 0.f;
- int numNonContactPool = m_tmpSolverNonContactConstraintPool.size();
- int numConstraintPool = m_tmpSolverContactConstraintPool.size();
- int numFrictionPool = m_tmpSolverContactFrictionConstraintPool.size();
+ int numNonContactPool = siData.m_tmpSolverNonContactConstraintPool.size();
+ int numConstraintPool = siData.m_tmpSolverContactConstraintPool.size();
+ int numFrictionPool = siData.m_tmpSolverContactFrictionConstraintPool.size();
if (infoGlobal.m_solverMode & SOLVER_RANDMIZE_ORDER)
{
@@ -1560,10 +1982,10 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
{
for (int j = 0; j < numNonContactPool; ++j)
{
- int tmp = m_orderNonContactConstraintPool[j];
- int swapi = btRandInt2(j + 1);
- m_orderNonContactConstraintPool[j] = m_orderNonContactConstraintPool[swapi];
- m_orderNonContactConstraintPool[swapi] = tmp;
+ int tmp = siData.m_orderNonContactConstraintPool[j];
+ int swapi = btRandInt2a(j + 1, siData.m_seed);
+ siData.m_orderNonContactConstraintPool[j] = siData.m_orderNonContactConstraintPool[swapi];
+ siData.m_orderNonContactConstraintPool[swapi] = tmp;
}
//contact/friction constraints are not solved more than
@@ -1571,30 +1993,30 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
{
for (int j = 0; j < numConstraintPool; ++j)
{
- int tmp = m_orderTmpConstraintPool[j];
- int swapi = btRandInt2(j + 1);
- m_orderTmpConstraintPool[j] = m_orderTmpConstraintPool[swapi];
- m_orderTmpConstraintPool[swapi] = tmp;
+ int tmp = siData.m_orderTmpConstraintPool[j];
+ int swapi = btRandInt2a(j + 1, siData.m_seed);
+ siData.m_orderTmpConstraintPool[j] = siData.m_orderTmpConstraintPool[swapi];
+ siData.m_orderTmpConstraintPool[swapi] = tmp;
}
for (int j = 0; j < numFrictionPool; ++j)
{
- int tmp = m_orderFrictionConstraintPool[j];
- int swapi = btRandInt2(j + 1);
- m_orderFrictionConstraintPool[j] = m_orderFrictionConstraintPool[swapi];
- m_orderFrictionConstraintPool[swapi] = tmp;
+ int tmp = siData.m_orderFrictionConstraintPool[j];
+ int swapi = btRandInt2a(j + 1, siData.m_seed);
+ siData.m_orderFrictionConstraintPool[j] = siData.m_orderFrictionConstraintPool[swapi];
+ siData.m_orderFrictionConstraintPool[swapi] = tmp;
}
}
}
}
///solve all joint constraints
- for (int j = 0; j < m_tmpSolverNonContactConstraintPool.size(); j++)
+ for (int j = 0; j < siData.m_tmpSolverNonContactConstraintPool.size(); j++)
{
- btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[m_orderNonContactConstraintPool[j]];
+ btSolverConstraint& constraint = siData.m_tmpSolverNonContactConstraintPool[siData.m_orderNonContactConstraintPool[j]];
if (iteration < constraint.m_overrideNumSolverIterations)
{
- btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[constraint.m_solverBodyIdA], m_tmpSolverBodyPool[constraint.m_solverBodyIdB], constraint);
+ btScalar residual = siData.m_resolveSingleConstraintRowGeneric(siData.m_tmpSolverBodyPool[constraint.m_solverBodyIdA], siData.m_tmpSolverBodyPool[constraint.m_solverBodyIdB], constraint);
leastSquaresResidual = btMax(leastSquaresResidual, residual * residual);
}
}
@@ -1605,10 +2027,10 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
{
if (constraints[j]->isEnabled())
{
- int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA(), infoGlobal.m_timeStep);
- int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB(), infoGlobal.m_timeStep);
- btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid];
- btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid];
+ int bodyAid = siData.getSolverBody(constraints[j]->getRigidBodyA());
+ int bodyBid = siData.getSolverBody(constraints[j]->getRigidBodyB());
+ btSolverBody& bodyA = siData.m_tmpSolverBodyPool[bodyAid];
+ btSolverBody& bodyB = siData.m_tmpSolverBodyPool[bodyBid];
constraints[j]->solveConstraintObsolete(bodyA, bodyB, infoGlobal.m_timeStep);
}
}
@@ -1616,7 +2038,7 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
///solve all contact constraints
if (infoGlobal.m_solverMode & SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS)
{
- int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
+ int numPoolConstraints = siData.m_tmpSolverContactConstraintPool.size();
int multiplier = (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) ? 2 : 1;
for (int c = 0; c < numPoolConstraints; c++)
@@ -1624,8 +2046,8 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
btScalar totalImpulse = 0;
{
- const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[c]];
- btScalar residual = resolveSingleConstraintRowLowerLimit(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold);
+ const btSolverConstraint& solveManifold = siData.m_tmpSolverContactConstraintPool[siData.m_orderTmpConstraintPool[c]];
+ btScalar residual = siData.m_resolveSingleConstraintRowLowerLimit(siData.m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], siData.m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold);
leastSquaresResidual = btMax(leastSquaresResidual, residual * residual);
totalImpulse = solveManifold.m_appliedImpulse;
@@ -1634,28 +2056,28 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
if (applyFriction)
{
{
- btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[c * multiplier]];
+ btSolverConstraint& solveManifold = siData.m_tmpSolverContactFrictionConstraintPool[siData.m_orderFrictionConstraintPool[c * multiplier]];
if (totalImpulse > btScalar(0))
{
solveManifold.m_lowerLimit = -(solveManifold.m_friction * totalImpulse);
solveManifold.m_upperLimit = solveManifold.m_friction * totalImpulse;
- btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold);
+ btScalar residual = siData.m_resolveSingleConstraintRowGeneric(siData.m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], siData.m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold);
leastSquaresResidual = btMax(leastSquaresResidual, residual * residual);
}
}
if (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)
{
- btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[c * multiplier + 1]];
+ btSolverConstraint& solveManifold = siData.m_tmpSolverContactFrictionConstraintPool[siData.m_orderFrictionConstraintPool[c * multiplier + 1]];
if (totalImpulse > btScalar(0))
{
solveManifold.m_lowerLimit = -(solveManifold.m_friction * totalImpulse);
solveManifold.m_upperLimit = solveManifold.m_friction * totalImpulse;
- btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold);
+ btScalar residual = siData.m_resolveSingleConstraintRowGeneric(siData.m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], siData.m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold);
leastSquaresResidual = btMax(leastSquaresResidual, residual * residual);
}
}
@@ -1665,40 +2087,40 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
else //SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS
{
//solve the friction constraints after all contact constraints, don't interleave them
- int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
+ int numPoolConstraints = siData.m_tmpSolverContactConstraintPool.size();
int j;
for (j = 0; j < numPoolConstraints; j++)
{
- const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
- btScalar residual = resolveSingleConstraintRowLowerLimit(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold);
+ const btSolverConstraint& solveManifold = siData.m_tmpSolverContactConstraintPool[siData.m_orderTmpConstraintPool[j]];
+ btScalar residual = siData.m_resolveSingleConstraintRowLowerLimit(siData.m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], siData.m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold);
leastSquaresResidual = btMax(leastSquaresResidual, residual * residual);
}
///solve all friction constraints
- int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size();
+ int numFrictionPoolConstraints = siData.m_tmpSolverContactFrictionConstraintPool.size();
for (j = 0; j < numFrictionPoolConstraints; j++)
{
- btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]];
- btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
+ btSolverConstraint& solveManifold = siData.m_tmpSolverContactFrictionConstraintPool[siData.m_orderFrictionConstraintPool[j]];
+ btScalar totalImpulse = siData.m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
if (totalImpulse > btScalar(0))
{
solveManifold.m_lowerLimit = -(solveManifold.m_friction * totalImpulse);
solveManifold.m_upperLimit = solveManifold.m_friction * totalImpulse;
- btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold);
+ btScalar residual = siData.m_resolveSingleConstraintRowGeneric(siData.m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], siData.m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold);
leastSquaresResidual = btMax(leastSquaresResidual, residual * residual);
}
}
}
- int numRollingFrictionPoolConstraints = m_tmpSolverContactRollingFrictionConstraintPool.size();
+ int numRollingFrictionPoolConstraints = siData.m_tmpSolverContactRollingFrictionConstraintPool.size();
for (int j = 0; j < numRollingFrictionPoolConstraints; j++)
{
- btSolverConstraint& rollingFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[j];
- btScalar totalImpulse = m_tmpSolverContactConstraintPool[rollingFrictionConstraint.m_frictionIndex].m_appliedImpulse;
+ btSolverConstraint& rollingFrictionConstraint = siData.m_tmpSolverContactRollingFrictionConstraintPool[j];
+ btScalar totalImpulse = siData.m_tmpSolverContactConstraintPool[rollingFrictionConstraint.m_frictionIndex].m_appliedImpulse;
if (totalImpulse > btScalar(0))
{
btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction * totalImpulse;
@@ -1708,7 +2130,7 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude;
rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude;
- btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA], m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB], rollingFrictionConstraint);
+ btScalar residual = siData.m_resolveSingleConstraintRowGeneric(siData.m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA], siData.m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB], rollingFrictionConstraint);
leastSquaresResidual = btMax(leastSquaresResidual, residual * residual);
}
}
@@ -1716,8 +2138,56 @@ btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration
return leastSquaresResidual;
}
+
+btScalar btSequentialImpulseConstraintSolver::solveSingleIteration(int iteration, btCollisionObject** /*bodies */, int /*numBodies*/, btPersistentManifold** /*manifoldPtr*/, int /*numManifolds*/, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* /*debugDrawer*/)
+{
+ btSISolverSingleIterationData siData(m_tmpSolverBodyPool,
+ m_tmpSolverContactConstraintPool,
+ m_tmpSolverNonContactConstraintPool,
+ m_tmpSolverContactFrictionConstraintPool,
+ m_tmpSolverContactRollingFrictionConstraintPool,
+ m_orderTmpConstraintPool,
+ m_orderNonContactConstraintPool,
+ m_orderFrictionConstraintPool,
+ m_tmpConstraintSizesPool,
+ m_resolveSingleConstraintRowGeneric,
+ m_resolveSingleConstraintRowLowerLimit,
+ m_resolveSplitPenetrationImpulse,
+ m_kinematicBodyUniqueIdToSolverBodyTable,
+ m_btSeed2,
+ m_fixedBodyId,
+ m_maxOverrideNumSolverIterations);
+
+ btScalar leastSquaresResidual = btSequentialImpulseConstraintSolver::solveSingleIterationInternal(siData,
+ iteration, constraints, numConstraints, infoGlobal);
+ return leastSquaresResidual;
+}
+
void btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer)
{
+ btSISolverSingleIterationData siData(m_tmpSolverBodyPool,
+ m_tmpSolverContactConstraintPool,
+ m_tmpSolverNonContactConstraintPool,
+ m_tmpSolverContactFrictionConstraintPool,
+ m_tmpSolverContactRollingFrictionConstraintPool,
+ m_orderTmpConstraintPool,
+ m_orderNonContactConstraintPool,
+ m_orderFrictionConstraintPool,
+ m_tmpConstraintSizesPool,
+ m_resolveSingleConstraintRowGeneric,
+ m_resolveSingleConstraintRowLowerLimit,
+ m_resolveSplitPenetrationImpulse,
+ m_kinematicBodyUniqueIdToSolverBodyTable,
+ m_btSeed2,
+ m_fixedBodyId,
+ m_maxOverrideNumSolverIterations);
+
+ solveGroupCacheFriendlySplitImpulseIterationsInternal(siData,
+ bodies, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer);
+
+}
+void btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySplitImpulseIterationsInternal(btSISolverSingleIterationData& siData, btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer)
+{
BT_PROFILE("solveGroupCacheFriendlySplitImpulseIterations");
int iteration;
if (infoGlobal.m_splitImpulse)
@@ -1727,13 +2197,13 @@ void btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySplitImpulseIte
{
btScalar leastSquaresResidual = 0.f;
{
- int numPoolConstraints = m_tmpSolverContactConstraintPool.size();
+ int numPoolConstraints = siData.m_tmpSolverContactConstraintPool.size();
int j;
for (j = 0; j < numPoolConstraints; j++)
{
- const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]];
+ const btSolverConstraint& solveManifold = siData.m_tmpSolverContactConstraintPool[siData.m_orderTmpConstraintPool[j]];
- btScalar residual = resolveSplitPenetrationImpulse(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold);
+ btScalar residual = siData.m_resolveSplitPenetrationImpulse(siData.m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], siData.m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold);
leastSquaresResidual = btMax(leastSquaresResidual, residual * residual);
}
}
@@ -1760,7 +2230,7 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(
int maxIterations = m_maxOverrideNumSolverIterations > infoGlobal.m_numIterations ? m_maxOverrideNumSolverIterations : infoGlobal.m_numIterations;
for (int iteration = 0; iteration < maxIterations; iteration++)
- //for ( int iteration = maxIterations-1 ; iteration >= 0;iteration--)
+ //for ( int iteration = maxIterations-1 ; iteration >= 0;iteration--)
{
m_leastSquaresResidual = solveSingleIteration(iteration, bodies, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer);
@@ -1769,6 +2239,14 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(
#ifdef VERBOSE_RESIDUAL_PRINTF
printf("residual = %f at iteration #%d\n", m_leastSquaresResidual, iteration);
#endif
+ m_analyticsData.m_numSolverCalls++;
+ m_analyticsData.m_numIterationsUsed = iteration+1;
+ m_analyticsData.m_islandId = -2;
+ if (numBodies>0)
+ m_analyticsData.m_islandId = bodies[0]->getCompanionId();
+ m_analyticsData.m_numBodies = numBodies;
+ m_analyticsData.m_numContactManifolds = numManifolds;
+ m_analyticsData.m_remainingLeastSquaresResidual = m_leastSquaresResidual;
break;
}
}
@@ -1776,31 +2254,42 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(
return 0.f;
}
-void btSequentialImpulseConstraintSolver::writeBackContacts(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal)
+void btSequentialImpulseConstraintSolver::writeBackContactsInternal(btConstraintArray& tmpSolverContactConstraintPool, btConstraintArray& tmpSolverContactFrictionConstraintPool, int iBegin, int iEnd, const btContactSolverInfo& infoGlobal)
{
for (int j = iBegin; j < iEnd; j++)
{
- const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[j];
+ const btSolverConstraint& solveManifold = tmpSolverContactConstraintPool[j];
btManifoldPoint* pt = (btManifoldPoint*)solveManifold.m_originalContactPoint;
btAssert(pt);
pt->m_appliedImpulse = solveManifold.m_appliedImpulse;
// float f = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
// printf("pt->m_appliedImpulseLateral1 = %f\n", f);
- pt->m_appliedImpulseLateral1 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
+ pt->m_appliedImpulseLateral1 = tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse;
//printf("pt->m_appliedImpulseLateral1 = %f\n", pt->m_appliedImpulseLateral1);
if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
{
- pt->m_appliedImpulseLateral2 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex + 1].m_appliedImpulse;
+ pt->m_appliedImpulseLateral2 = tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex + 1].m_appliedImpulse;
}
//do a callback here?
}
}
+void btSequentialImpulseConstraintSolver::writeBackContacts(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal)
+{
+ writeBackContactsInternal(m_tmpSolverContactConstraintPool, m_tmpSolverContactFrictionConstraintPool, iBegin, iEnd, infoGlobal);
+
+}
+
void btSequentialImpulseConstraintSolver::writeBackJoints(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal)
{
+ writeBackJointsInternal(m_tmpSolverNonContactConstraintPool, iBegin, iEnd, infoGlobal);
+}
+
+void btSequentialImpulseConstraintSolver::writeBackJointsInternal(btConstraintArray& tmpSolverNonContactConstraintPool, int iBegin, int iEnd, const btContactSolverInfo& infoGlobal)
+{
for (int j = iBegin; j < iEnd; j++)
{
- const btSolverConstraint& solverConstr = m_tmpSolverNonContactConstraintPool[j];
+ const btSolverConstraint& solverConstr = tmpSolverNonContactConstraintPool[j];
btTypedConstraint* constr = (btTypedConstraint*)solverConstr.m_originalContactPoint;
btJointFeedback* fb = constr->getJointFeedback();
if (fb)
@@ -1821,53 +2310,79 @@ void btSequentialImpulseConstraintSolver::writeBackJoints(int iBegin, int iEnd,
void btSequentialImpulseConstraintSolver::writeBackBodies(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal)
{
+ writeBackBodiesInternal(m_tmpSolverBodyPool, iBegin, iEnd, infoGlobal);
+}
+void btSequentialImpulseConstraintSolver::writeBackBodiesInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool, int iBegin, int iEnd, const btContactSolverInfo& infoGlobal)
+{
for (int i = iBegin; i < iEnd; i++)
{
- btRigidBody* body = m_tmpSolverBodyPool[i].m_originalBody;
+ btRigidBody* body = tmpSolverBodyPool[i].m_originalBody;
if (body)
{
if (infoGlobal.m_splitImpulse)
- m_tmpSolverBodyPool[i].writebackVelocityAndTransform(infoGlobal.m_timeStep, infoGlobal.m_splitImpulseTurnErp);
+ tmpSolverBodyPool[i].writebackVelocityAndTransform(infoGlobal.m_timeStep, infoGlobal.m_splitImpulseTurnErp);
else
- m_tmpSolverBodyPool[i].writebackVelocity();
+ tmpSolverBodyPool[i].writebackVelocity();
- m_tmpSolverBodyPool[i].m_originalBody->setLinearVelocity(
- m_tmpSolverBodyPool[i].m_linearVelocity +
- m_tmpSolverBodyPool[i].m_externalForceImpulse);
+ tmpSolverBodyPool[i].m_originalBody->setLinearVelocity(
+ tmpSolverBodyPool[i].m_linearVelocity +
+ tmpSolverBodyPool[i].m_externalForceImpulse);
- m_tmpSolverBodyPool[i].m_originalBody->setAngularVelocity(
- m_tmpSolverBodyPool[i].m_angularVelocity +
- m_tmpSolverBodyPool[i].m_externalTorqueImpulse);
+ tmpSolverBodyPool[i].m_originalBody->setAngularVelocity(
+ tmpSolverBodyPool[i].m_angularVelocity +
+ tmpSolverBodyPool[i].m_externalTorqueImpulse);
if (infoGlobal.m_splitImpulse)
- m_tmpSolverBodyPool[i].m_originalBody->setWorldTransform(m_tmpSolverBodyPool[i].m_worldTransform);
+ tmpSolverBodyPool[i].m_originalBody->setWorldTransform(tmpSolverBodyPool[i].m_worldTransform);
- m_tmpSolverBodyPool[i].m_originalBody->setCompanionId(-1);
+ tmpSolverBodyPool[i].m_originalBody->setCompanionId(-1);
}
}
}
-btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish(btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal)
+btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinishInternal(btSISolverSingleIterationData& siData, btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal)
{
BT_PROFILE("solveGroupCacheFriendlyFinish");
if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING)
{
- writeBackContacts(0, m_tmpSolverContactConstraintPool.size(), infoGlobal);
+ writeBackContactsInternal(siData.m_tmpSolverContactConstraintPool, siData.m_tmpSolverContactFrictionConstraintPool, 0, siData.m_tmpSolverContactConstraintPool.size(), infoGlobal);
}
- writeBackJoints(0, m_tmpSolverNonContactConstraintPool.size(), infoGlobal);
- writeBackBodies(0, m_tmpSolverBodyPool.size(), infoGlobal);
+ writeBackJointsInternal(siData.m_tmpSolverNonContactConstraintPool, 0, siData.m_tmpSolverNonContactConstraintPool.size(), infoGlobal);
+ writeBackBodiesInternal(siData.m_tmpSolverBodyPool, 0, siData.m_tmpSolverBodyPool.size(), infoGlobal);
- m_tmpSolverContactConstraintPool.resizeNoInitialize(0);
- m_tmpSolverNonContactConstraintPool.resizeNoInitialize(0);
- m_tmpSolverContactFrictionConstraintPool.resizeNoInitialize(0);
- m_tmpSolverContactRollingFrictionConstraintPool.resizeNoInitialize(0);
+ siData.m_tmpSolverContactConstraintPool.resizeNoInitialize(0);
+ siData.m_tmpSolverNonContactConstraintPool.resizeNoInitialize(0);
+ siData.m_tmpSolverContactFrictionConstraintPool.resizeNoInitialize(0);
+ siData.m_tmpSolverContactRollingFrictionConstraintPool.resizeNoInitialize(0);
- m_tmpSolverBodyPool.resizeNoInitialize(0);
+ siData.m_tmpSolverBodyPool.resizeNoInitialize(0);
return 0.f;
}
+btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish(btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal)
+{
+ btSISolverSingleIterationData siData(m_tmpSolverBodyPool,
+ m_tmpSolverContactConstraintPool,
+ m_tmpSolverNonContactConstraintPool,
+ m_tmpSolverContactFrictionConstraintPool,
+ m_tmpSolverContactRollingFrictionConstraintPool,
+ m_orderTmpConstraintPool,
+ m_orderNonContactConstraintPool,
+ m_orderFrictionConstraintPool,
+ m_tmpConstraintSizesPool,
+ m_resolveSingleConstraintRowGeneric,
+ m_resolveSingleConstraintRowLowerLimit,
+ m_resolveSplitPenetrationImpulse,
+ m_kinematicBodyUniqueIdToSolverBodyTable,
+ m_btSeed2,
+ m_fixedBodyId,
+ m_maxOverrideNumSolverIterations);
+
+ return btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinishInternal(siData, bodies, numBodies, infoGlobal);
+}
+
/// btSequentialImpulseConstraintSolver Sequentially applies impulses
btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer, btDispatcher* /*dispatcher*/)
{
@@ -1886,4 +2401,4 @@ btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bod
void btSequentialImpulseConstraintSolver::reset()
{
m_btSeed2 = 0;
-}
+} \ No newline at end of file
diff --git a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
index 70db83b063..2b88e25be7 100644
--- a/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
+++ b/thirdparty/bullet/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h
@@ -29,10 +29,91 @@ class btCollisionObject;
typedef btScalar (*btSingleConstraintRowSolver)(btSolverBody&, btSolverBody&, const btSolverConstraint&);
+struct btSISolverSingleIterationData
+{
+ btAlignedObjectArray<btSolverBody>& m_tmpSolverBodyPool;
+ btConstraintArray& m_tmpSolverContactConstraintPool;
+ btConstraintArray& m_tmpSolverNonContactConstraintPool;
+ btConstraintArray& m_tmpSolverContactFrictionConstraintPool;
+ btConstraintArray& m_tmpSolverContactRollingFrictionConstraintPool;
+
+ btAlignedObjectArray<int>& m_orderTmpConstraintPool;
+ btAlignedObjectArray<int>& m_orderNonContactConstraintPool;
+ btAlignedObjectArray<int>& m_orderFrictionConstraintPool;
+ btAlignedObjectArray<btTypedConstraint::btConstraintInfo1>& m_tmpConstraintSizesPool;
+ unsigned long& m_seed;
+
+ btSingleConstraintRowSolver& m_resolveSingleConstraintRowGeneric;
+ btSingleConstraintRowSolver& m_resolveSingleConstraintRowLowerLimit;
+ btSingleConstraintRowSolver& m_resolveSplitPenetrationImpulse;
+ btAlignedObjectArray<int>& m_kinematicBodyUniqueIdToSolverBodyTable;
+ int& m_fixedBodyId;
+ int& m_maxOverrideNumSolverIterations;
+ int getOrInitSolverBody(btCollisionObject & body, btScalar timeStep);
+ static void initSolverBody(btSolverBody * solverBody, btCollisionObject * collisionObject, btScalar timeStep);
+ int getSolverBody(btCollisionObject& body) const;
+
+
+ btSISolverSingleIterationData(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool,
+ btConstraintArray& tmpSolverContactConstraintPool,
+ btConstraintArray& tmpSolverNonContactConstraintPool,
+ btConstraintArray& tmpSolverContactFrictionConstraintPool,
+ btConstraintArray& tmpSolverContactRollingFrictionConstraintPool,
+ btAlignedObjectArray<int>& orderTmpConstraintPool,
+ btAlignedObjectArray<int>& orderNonContactConstraintPool,
+ btAlignedObjectArray<int>& orderFrictionConstraintPool,
+ btAlignedObjectArray<btTypedConstraint::btConstraintInfo1>& tmpConstraintSizesPool,
+ btSingleConstraintRowSolver& resolveSingleConstraintRowGeneric,
+ btSingleConstraintRowSolver& resolveSingleConstraintRowLowerLimit,
+ btSingleConstraintRowSolver& resolveSplitPenetrationImpulse,
+ btAlignedObjectArray<int>& kinematicBodyUniqueIdToSolverBodyTable,
+ unsigned long& seed,
+ int& fixedBodyId,
+ int& maxOverrideNumSolverIterations
+ )
+ :m_tmpSolverBodyPool(tmpSolverBodyPool),
+ m_tmpSolverContactConstraintPool(tmpSolverContactConstraintPool),
+ m_tmpSolverNonContactConstraintPool(tmpSolverNonContactConstraintPool),
+ m_tmpSolverContactFrictionConstraintPool(tmpSolverContactFrictionConstraintPool),
+ m_tmpSolverContactRollingFrictionConstraintPool(tmpSolverContactRollingFrictionConstraintPool),
+ m_orderTmpConstraintPool(orderTmpConstraintPool),
+ m_orderNonContactConstraintPool(orderNonContactConstraintPool),
+ m_orderFrictionConstraintPool(orderFrictionConstraintPool),
+ m_tmpConstraintSizesPool(tmpConstraintSizesPool),
+ m_seed(seed),
+ m_resolveSingleConstraintRowGeneric(resolveSingleConstraintRowGeneric),
+ m_resolveSingleConstraintRowLowerLimit(resolveSingleConstraintRowLowerLimit),
+ m_resolveSplitPenetrationImpulse(resolveSplitPenetrationImpulse),
+ m_kinematicBodyUniqueIdToSolverBodyTable(kinematicBodyUniqueIdToSolverBodyTable),
+ m_fixedBodyId(fixedBodyId),
+ m_maxOverrideNumSolverIterations(maxOverrideNumSolverIterations)
+ {
+ }
+};
+
+struct btSolverAnalyticsData
+{
+ btSolverAnalyticsData()
+ {
+ m_numSolverCalls = 0;
+ m_numIterationsUsed = -1;
+ m_remainingLeastSquaresResidual = -1;
+ m_islandId = -2;
+ }
+ int m_islandId;
+ int m_numBodies;
+ int m_numContactManifolds;
+ int m_numSolverCalls;
+ int m_numIterationsUsed;
+ double m_remainingLeastSquaresResidual;
+};
+
///The btSequentialImpulseConstraintSolver is a fast SIMD implementation of the Projected Gauss Seidel (iterative LCP) method.
ATTRIBUTE_ALIGNED16(class)
btSequentialImpulseConstraintSolver : public btConstraintSolver
{
+
+
protected:
btAlignedObjectArray<btSolverBody> m_tmpSolverBodyPool;
btConstraintArray m_tmpSolverContactConstraintPool;
@@ -64,26 +145,26 @@ protected:
btScalar m_leastSquaresResidual;
void setupFrictionConstraint(btSolverConstraint & solverConstraint, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB,
- btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2,
- btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation,
- const btContactSolverInfo& infoGlobal,
- btScalar desiredVelocity = 0., btScalar cfmSlip = 0.);
+ btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2,
+ btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation,
+ const btContactSolverInfo& infoGlobal,
+ btScalar desiredVelocity = 0., btScalar cfmSlip = 0.);
void setupTorsionalFrictionConstraint(btSolverConstraint & solverConstraint, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB,
- btManifoldPoint& cp, btScalar combinedTorsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2,
- btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation,
- btScalar desiredVelocity = 0., btScalar cfmSlip = 0.);
+ btManifoldPoint& cp, btScalar combinedTorsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2,
+ btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation,
+ btScalar desiredVelocity = 0., btScalar cfmSlip = 0.);
btSolverConstraint& addFrictionConstraint(const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity = 0., btScalar cfmSlip = 0.);
btSolverConstraint& addTorsionalFrictionConstraint(const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, btScalar torsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity = 0, btScalar cfmSlip = 0.f);
void setupContactConstraint(btSolverConstraint & solverConstraint, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp,
- const btContactSolverInfo& infoGlobal, btScalar& relaxation, const btVector3& rel_pos1, const btVector3& rel_pos2);
+ const btContactSolverInfo& infoGlobal, btScalar& relaxation, const btVector3& rel_pos1, const btVector3& rel_pos2);
static void applyAnisotropicFriction(btCollisionObject * colObj, btVector3 & frictionDirection, int frictionMode);
void setFrictionConstraintImpulse(btSolverConstraint & solverConstraint, int solverBodyIdA, int solverBodyIdB,
- btManifoldPoint& cp, const btContactSolverInfo& infoGlobal);
+ btManifoldPoint& cp, const btContactSolverInfo& infoGlobal);
///m_btSeed2 is used for re-arranging the constraint rows. improves convergence/quality of friction
unsigned long m_btSeed2;
@@ -97,6 +178,7 @@ protected:
virtual void convertJoints(btTypedConstraint * *constraints, int numConstraints, const btContactSolverInfo& infoGlobal);
void convertJoint(btSolverConstraint * currentConstraintRow, btTypedConstraint * constraint, const btTypedConstraint::btConstraintInfo1& info1, int solverBodyIdA, int solverBodyIdB, const btContactSolverInfo& infoGlobal);
+
virtual void convertBodies(btCollisionObject * *bodies, int numBodies, const btContactSolverInfo& infoGlobal);
btScalar resolveSplitPenetrationSIMD(btSolverBody & bodyA, btSolverBody & bodyB, const btSolverConstraint& contactConstraint)
@@ -122,7 +204,8 @@ protected:
return m_resolveSplitPenetrationImpulse(bodyA, bodyB, contactConstraint);
}
-protected:
+public:
+
void writeBackContacts(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal);
void writeBackJoints(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal);
void writeBackBodies(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal);
@@ -130,6 +213,7 @@ protected:
virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject * *bodies, int numBodies, const btContactSolverInfo& infoGlobal);
virtual btScalar solveSingleIteration(int iteration, btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
+
virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
virtual btScalar solveGroupCacheFriendlyIterations(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
@@ -141,13 +225,52 @@ public:
virtual btScalar solveGroup(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifold, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btDispatcher* dispatcher);
+ static btScalar solveSingleIterationInternal(btSISolverSingleIterationData& siData, int iteration, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal);
+ static void convertBodiesInternal(btSISolverSingleIterationData& siData, btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal);
+ static void convertJointsInternal(btSISolverSingleIterationData& siData, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal);
+ static void convertContactInternal(btSISolverSingleIterationData& siData, btPersistentManifold * manifold, const btContactSolverInfo& infoGlobal);
+ static void setupContactConstraintInternal(btSISolverSingleIterationData& siData, btSolverConstraint& solverConstraint, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp, const btContactSolverInfo& infoGlobal, btScalar& relaxation,
+ const btVector3& rel_pos1, const btVector3& rel_pos2);
+ static btScalar restitutionCurveInternal(btScalar rel_vel, btScalar restitution, btScalar velocityThreshold);
+ static btSolverConstraint& addTorsionalFrictionConstraintInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool, btConstraintArray& tmpSolverContactRollingFrictionConstraintPool, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, btScalar combinedTorsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity = 0, btScalar cfmSlip = 0.);
+ static void setupTorsionalFrictionConstraintInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool, btSolverConstraint& solverConstraint, const btVector3& normalAxis1, int solverBodyIdA, int solverBodyIdB,
+ btManifoldPoint& cp, btScalar combinedTorsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2,
+ btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation,
+ btScalar desiredVelocity, btScalar cfmSlip);
+ static void setupFrictionConstraintInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool, btSolverConstraint& solverConstraint, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip);
+ static btSolverConstraint& addFrictionConstraintInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool, btConstraintArray& tmpSolverContactFrictionConstraintPool, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity = 0., btScalar cfmSlip = 0.);
+ static void setFrictionConstraintImpulseInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool, btConstraintArray& tmpSolverContactFrictionConstraintPool,
+
+ btSolverConstraint& solverConstraint,
+ int solverBodyIdA, int solverBodyIdB,
+ btManifoldPoint& cp, const btContactSolverInfo& infoGlobal);
+ static void convertJointInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool,
+ int& maxOverrideNumSolverIterations,
+ btSolverConstraint* currentConstraintRow,
+ btTypedConstraint* constraint,
+ const btTypedConstraint::btConstraintInfo1& info1,
+ int solverBodyIdA,
+ int solverBodyIdB,
+ const btContactSolverInfo& infoGlobal);
+
+ static btScalar solveGroupCacheFriendlyFinishInternal(btSISolverSingleIterationData& siData, btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal);
+
+ static void writeBackContactsInternal(btConstraintArray& tmpSolverContactConstraintPool, btConstraintArray& tmpSolverContactFrictionConstraintPool, int iBegin, int iEnd, const btContactSolverInfo& infoGlobal);
+
+ static void writeBackJointsInternal(btConstraintArray& tmpSolverNonContactConstraintPool, int iBegin, int iEnd, const btContactSolverInfo& infoGlobal);
+ static void writeBackBodiesInternal(btAlignedObjectArray<btSolverBody>& tmpSolverBodyPool, int iBegin, int iEnd, const btContactSolverInfo& infoGlobal);
+ static void solveGroupCacheFriendlySplitImpulseIterationsInternal(btSISolverSingleIterationData& siData, btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer);
+
+
///clear internal cached data and reset random seed
virtual void reset();
unsigned long btRand2();
-
int btRandInt2(int n);
+ static unsigned long btRand2a(unsigned long& seed);
+ static int btRandInt2a(int n, unsigned long& seed);
+
void setRandSeed(unsigned long seed)
{
m_btSeed2 = seed;
@@ -179,15 +302,22 @@ public:
m_resolveSingleConstraintRowLowerLimit = rowSolver;
}
+
+
///Various implementations of solving a single constraint row using a generic equality constraint, using scalar reference, SSE2 or SSE4
- btSingleConstraintRowSolver getScalarConstraintRowSolverGeneric();
- btSingleConstraintRowSolver getSSE2ConstraintRowSolverGeneric();
- btSingleConstraintRowSolver getSSE4_1ConstraintRowSolverGeneric();
+ static btSingleConstraintRowSolver getScalarConstraintRowSolverGeneric();
+ static btSingleConstraintRowSolver getSSE2ConstraintRowSolverGeneric();
+ static btSingleConstraintRowSolver getSSE4_1ConstraintRowSolverGeneric();
///Various implementations of solving a single constraint row using an inequality (lower limit) constraint, using scalar reference, SSE2 or SSE4
- btSingleConstraintRowSolver getScalarConstraintRowSolverLowerLimit();
- btSingleConstraintRowSolver getSSE2ConstraintRowSolverLowerLimit();
- btSingleConstraintRowSolver getSSE4_1ConstraintRowSolverLowerLimit();
+ static btSingleConstraintRowSolver getScalarConstraintRowSolverLowerLimit();
+ static btSingleConstraintRowSolver getSSE2ConstraintRowSolverLowerLimit();
+ static btSingleConstraintRowSolver getSSE4_1ConstraintRowSolverLowerLimit();
+
+ static btSingleConstraintRowSolver getScalarSplitPenetrationImpulseGeneric();
+ static btSingleConstraintRowSolver getSSE2SplitPenetrationImpulseGeneric();
+
+ btSolverAnalyticsData m_analyticsData;
};
#endif //BT_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H
diff --git a/thirdparty/bullet/BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp b/thirdparty/bullet/BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp
index 17287aa82a..5353fe009e 100644
--- a/thirdparty/bullet/BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp
+++ b/thirdparty/bullet/BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp
@@ -65,7 +65,7 @@ inline int getIslandId(const btPersistentManifold* lhs)
return islandId;
}
-SIMD_FORCE_INLINE int btGetConstraintIslandId(const btTypedConstraint* lhs)
+SIMD_FORCE_INLINE int btGetConstraintIslandId1(const btTypedConstraint* lhs)
{
const btCollisionObject& rcolObj0 = lhs->getRigidBodyA();
const btCollisionObject& rcolObj1 = lhs->getRigidBodyB();
@@ -452,7 +452,7 @@ void btSimulationIslandManagerMt::addConstraintsToIslands(btAlignedObjectArray<b
btTypedConstraint* constraint = constraints[i];
if (constraint->isEnabled())
{
- int islandId = btGetConstraintIslandId(constraint);
+ int islandId = btGetConstraintIslandId1(constraint);
// if island is not sleeping,
if (Island* island = getIsland(islandId))
{
diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp
index 53fc48d4b9..3e210d7520 100644
--- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp
+++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.cpp
@@ -106,6 +106,7 @@ btMultiBody::btMultiBody(int n_links,
m_fixedBase(fixedBase),
m_awake(true),
m_canSleep(canSleep),
+ m_canWakeup(true),
m_sleepTimer(0),
m_userObjectPointer(0),
m_userIndex2(-1),
@@ -343,6 +344,7 @@ void btMultiBody::finalizeMultiDof()
m_deltaV.resize(6 + m_dofCount);
m_realBuf.resize(6 + m_dofCount + m_dofCount * m_dofCount + 6 + m_dofCount); //m_dofCount for joint-space vels + m_dofCount^2 for "D" matrices + delta-pos vector (6 base "vels" + joint "vels")
m_vectorBuf.resize(2 * m_dofCount); //two 3-vectors (i.e. one six-vector) for each system dof ("h" matrices)
+ m_matrixBuf.resize(m_links.size() + 1);
for (int i = 0; i < m_vectorBuf.size(); i++)
{
m_vectorBuf[i].setValue(0, 0, 0);
@@ -350,9 +352,9 @@ void btMultiBody::finalizeMultiDof()
updateLinksDofOffsets();
}
-int btMultiBody::getParent(int i) const
+int btMultiBody::getParent(int link_num) const
{
- return m_links[i].m_parent;
+ return m_links[link_num].m_parent;
}
btScalar btMultiBody::getLinkMass(int i) const
@@ -1882,6 +1884,8 @@ void btMultiBody::checkMotionAndSleepIfRequired(btScalar timestep)
return;
}
+
+
// motion is computed as omega^2 + v^2 + (sum of squares of joint velocities)
btScalar motion = 0;
{
@@ -1900,8 +1904,11 @@ void btMultiBody::checkMotionAndSleepIfRequired(btScalar timestep)
else
{
m_sleepTimer = 0;
- if (!m_awake)
- wakeUp();
+ if (m_canWakeup)
+ {
+ if (!m_awake)
+ wakeUp();
+ }
}
}
diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h
index e5c0f1806b..c0b0d003be 100644
--- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h
+++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBody.h
@@ -65,7 +65,7 @@ public:
virtual ~btMultiBody();
//note: fixed link collision with parent is always disabled
- void setupFixed(int linkIndex,
+ void setupFixed(int i, //linkIndex
btScalar mass,
const btVector3 &inertia,
int parent,
@@ -83,7 +83,7 @@ public:
const btVector3 &thisPivotToThisComOffset,
bool disableParentCollision);
- void setupRevolute(int linkIndex, // 0 to num_links-1
+ void setupRevolute(int i, // 0 to num_links-1
btScalar mass,
const btVector3 &inertia,
int parentIndex,
@@ -93,7 +93,7 @@ public:
const btVector3 &thisPivotToThisComOffset, // vector from joint axis to my COM, in MY frame
bool disableParentCollision = false);
- void setupSpherical(int linkIndex, // 0 to num_links-1
+ void setupSpherical(int i, // linkIndex, 0 to num_links-1
btScalar mass,
const btVector3 &inertia,
int parent,
@@ -182,7 +182,10 @@ public:
// get/set pos/vel/rot/omega for the base link
//
- const btVector3 &getBasePos() const { return m_basePos; } // in world frame
+ const btVector3 &getBasePos() const
+ {
+ return m_basePos;
+ } // in world frame
const btVector3 getBaseVel() const
{
return btVector3(m_realBuf[3], m_realBuf[4], m_realBuf[5]);
@@ -274,15 +277,15 @@ public:
//
// transform vectors in local frame of link i to world frame (or vice versa)
//
- btVector3 localPosToWorld(int i, const btVector3 &vec) const;
- btVector3 localDirToWorld(int i, const btVector3 &vec) const;
- btVector3 worldPosToLocal(int i, const btVector3 &vec) const;
- btVector3 worldDirToLocal(int i, const btVector3 &vec) const;
+ btVector3 localPosToWorld(int i, const btVector3 &local_pos) const;
+ btVector3 localDirToWorld(int i, const btVector3 &local_dir) const;
+ btVector3 worldPosToLocal(int i, const btVector3 &world_pos) const;
+ btVector3 worldDirToLocal(int i, const btVector3 &world_dir) const;
//
// transform a frame in local coordinate to a frame in world coordinate
//
- btMatrix3x3 localFrameToWorld(int i, const btMatrix3x3 &mat) const;
+ btMatrix3x3 localFrameToWorld(int i, const btMatrix3x3 &local_frame) const;
//
// calculate kinetic energy and angular momentum
@@ -451,7 +454,10 @@ public:
//
void setCanSleep(bool canSleep)
{
- m_canSleep = canSleep;
+ if (m_canWakeup)
+ {
+ m_canSleep = canSleep;
+ }
}
bool getCanSleep() const
@@ -459,6 +465,15 @@ public:
return m_canSleep;
}
+ bool getCanWakeup() const
+ {
+ return m_canWakeup;
+ }
+
+ void setCanWakeup(bool canWakeup)
+ {
+ m_canWakeup = canWakeup;
+ }
bool isAwake() const { return m_awake; }
void wakeUp();
void goToSleep();
@@ -469,6 +484,11 @@ public:
return m_fixedBase;
}
+ void setFixedBase(bool fixedBase)
+ {
+ m_fixedBase = fixedBase;
+ }
+
int getCompanionId() const
{
return m_companionId;
@@ -556,11 +576,11 @@ public:
{
return m_internalNeedsJointFeedback;
}
- void forwardKinematics(btAlignedObjectArray<btQuaternion> & scratch_q, btAlignedObjectArray<btVector3> & scratch_m);
+ void forwardKinematics(btAlignedObjectArray<btQuaternion>& world_to_local, btAlignedObjectArray<btVector3> & local_origin);
void compTreeLinkVelocities(btVector3 * omega, btVector3 * vel) const;
- void updateCollisionObjectWorldTransforms(btAlignedObjectArray<btQuaternion> & scratch_q, btAlignedObjectArray<btVector3> & scratch_m);
+ void updateCollisionObjectWorldTransforms(btAlignedObjectArray<btQuaternion> & world_to_local, btAlignedObjectArray<btVector3> & local_origin);
virtual int calculateSerializeBufferSize() const;
@@ -688,6 +708,7 @@ private:
// Sleep parameters.
bool m_awake;
bool m_canSleep;
+ bool m_canWakeup;
btScalar m_sleepTimer;
void *m_userObjectPointer;
diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp
index e97bd71cc4..23e163f0e8 100644
--- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp
+++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp
@@ -70,6 +70,30 @@ btScalar btMultiBodyConstraintSolver::solveSingleIteration(int iteration, btColl
//solve featherstone frictional contact
if (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS && ((infoGlobal.m_solverMode & SOLVER_DISABLE_IMPLICIT_CONE_FRICTION) == 0))
{
+ for (int j1 = 0; j1 < this->m_multiBodySpinningFrictionContactConstraints.size(); j1++)
+ {
+ if (iteration < infoGlobal.m_numIterations)
+ {
+ int index = j1;
+
+ btMultiBodySolverConstraint& frictionConstraint = m_multiBodySpinningFrictionContactConstraints[index];
+ btScalar totalImpulse = m_multiBodyNormalContactConstraints[frictionConstraint.m_frictionIndex].m_appliedImpulse;
+ //adjust friction limits here
+ if (totalImpulse > btScalar(0))
+ {
+ frictionConstraint.m_lowerLimit = -(frictionConstraint.m_friction * totalImpulse);
+ frictionConstraint.m_upperLimit = frictionConstraint.m_friction * totalImpulse;
+ btScalar residual = resolveSingleConstraintRowGeneric(frictionConstraint);
+ leastSquaredResidual = btMax(leastSquaredResidual, residual * residual);
+
+ if (frictionConstraint.m_multiBodyA)
+ frictionConstraint.m_multiBodyA->setPosUpdated(false);
+ if (frictionConstraint.m_multiBodyB)
+ frictionConstraint.m_multiBodyB->setPosUpdated(false);
+ }
+ }
+ }
+
for (int j1 = 0; j1 < this->m_multiBodyTorsionalFrictionContactConstraints.size(); j1++)
{
if (iteration < infoGlobal.m_numIterations)
@@ -78,18 +102,29 @@ btScalar btMultiBodyConstraintSolver::solveSingleIteration(int iteration, btColl
btMultiBodySolverConstraint& frictionConstraint = m_multiBodyTorsionalFrictionContactConstraints[index];
btScalar totalImpulse = m_multiBodyNormalContactConstraints[frictionConstraint.m_frictionIndex].m_appliedImpulse;
+ j1++;
+ int index2 = j1;
+ btMultiBodySolverConstraint& frictionConstraintB = m_multiBodyTorsionalFrictionContactConstraints[index2];
//adjust friction limits here
- if (totalImpulse > btScalar(0))
+ if (totalImpulse > btScalar(0) && frictionConstraint.m_frictionIndex == frictionConstraintB.m_frictionIndex)
{
frictionConstraint.m_lowerLimit = -(frictionConstraint.m_friction * totalImpulse);
frictionConstraint.m_upperLimit = frictionConstraint.m_friction * totalImpulse;
- btScalar residual = resolveSingleConstraintRowGeneric(frictionConstraint);
+ frictionConstraintB.m_lowerLimit = -(frictionConstraintB.m_friction * totalImpulse);
+ frictionConstraintB.m_upperLimit = frictionConstraintB.m_friction * totalImpulse;
+
+ btScalar residual = resolveConeFrictionConstraintRows(frictionConstraint, frictionConstraintB);
leastSquaredResidual = btMax(leastSquaredResidual, residual * residual);
if (frictionConstraint.m_multiBodyA)
frictionConstraint.m_multiBodyA->setPosUpdated(false);
if (frictionConstraint.m_multiBodyB)
frictionConstraint.m_multiBodyB->setPosUpdated(false);
+
+ if (frictionConstraintB.m_multiBodyA)
+ frictionConstraintB.m_multiBodyA->setPosUpdated(false);
+ if (frictionConstraintB.m_multiBodyB)
+ frictionConstraintB.m_multiBodyB->setPosUpdated(false);
}
}
}
@@ -164,6 +199,7 @@ btScalar btMultiBodyConstraintSolver::solveGroupCacheFriendlySetup(btCollisionOb
m_multiBodyNormalContactConstraints.resize(0);
m_multiBodyFrictionContactConstraints.resize(0);
m_multiBodyTorsionalFrictionContactConstraints.resize(0);
+ m_multiBodySpinningFrictionContactConstraints.resize(0);
m_data.m_jacobians.resize(0);
m_data.m_deltaVelocitiesUnitImpulse.resize(0);
@@ -1169,6 +1205,43 @@ btMultiBodySolverConstraint& btMultiBodyConstraintSolver::addMultiBodyTorsionalF
return solverConstraint;
}
+btMultiBodySolverConstraint& btMultiBodyConstraintSolver::addMultiBodySpinningFrictionConstraint(const btVector3& normalAxis, btPersistentManifold* manifold, int frictionIndex, btManifoldPoint& cp,
+ btScalar combinedTorsionalFriction,
+ btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip)
+{
+ BT_PROFILE("addMultiBodyRollingFrictionConstraint");
+
+ btMultiBodySolverConstraint& solverConstraint = m_multiBodySpinningFrictionContactConstraints.expandNonInitializing();
+ solverConstraint.m_orgConstraint = 0;
+ solverConstraint.m_orgDofIndex = -1;
+
+ solverConstraint.m_frictionIndex = frictionIndex;
+ bool isFriction = true;
+
+ const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(manifold->getBody0());
+ const btMultiBodyLinkCollider* fcB = btMultiBodyLinkCollider::upcast(manifold->getBody1());
+
+ btMultiBody* mbA = fcA ? fcA->m_multiBody : 0;
+ btMultiBody* mbB = fcB ? fcB->m_multiBody : 0;
+
+ int solverBodyIdA = mbA ? -1 : getOrInitSolverBody(*colObj0, infoGlobal.m_timeStep);
+ int solverBodyIdB = mbB ? -1 : getOrInitSolverBody(*colObj1, infoGlobal.m_timeStep);
+
+ solverConstraint.m_solverBodyIdA = solverBodyIdA;
+ solverConstraint.m_solverBodyIdB = solverBodyIdB;
+ solverConstraint.m_multiBodyA = mbA;
+ if (mbA)
+ solverConstraint.m_linkA = fcA->m_link;
+
+ solverConstraint.m_multiBodyB = mbB;
+ if (mbB)
+ solverConstraint.m_linkB = fcB->m_link;
+
+ solverConstraint.m_originalContactPoint = &cp;
+
+ setupMultiBodyTorsionalFrictionConstraint(solverConstraint, normalAxis, cp, combinedTorsionalFriction, infoGlobal, relaxation, isFriction, desiredVelocity, cfmSlip);
+ return solverConstraint;
+}
void btMultiBodyConstraintSolver::convertMultiBodyContact(btPersistentManifold* manifold, const btContactSolverInfo& infoGlobal)
{
const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(manifold->getBody0());
@@ -1258,7 +1331,7 @@ void btMultiBodyConstraintSolver::convertMultiBodyContact(btPersistentManifold*
{
if (cp.m_combinedSpinningFriction > 0)
{
- addMultiBodyTorsionalFrictionConstraint(cp.m_normalWorldOnB, manifold, frictionIndex, cp, cp.m_combinedSpinningFriction, colObj0, colObj1, relaxation, infoGlobal);
+ addMultiBodySpinningFrictionConstraint(cp.m_normalWorldOnB, manifold, frictionIndex, cp, cp.m_combinedSpinningFriction, colObj0, colObj1, relaxation, infoGlobal);
}
if (cp.m_combinedRollingFriction > 0)
{
@@ -1267,11 +1340,8 @@ void btMultiBodyConstraintSolver::convertMultiBodyContact(btPersistentManifold*
applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION);
- if (cp.m_lateralFrictionDir1.length() > 0.001)
- addMultiBodyTorsionalFrictionConstraint(cp.m_lateralFrictionDir1, manifold, frictionIndex, cp, cp.m_combinedRollingFriction, colObj0, colObj1, relaxation, infoGlobal);
-
- if (cp.m_lateralFrictionDir2.length() > 0.001)
- addMultiBodyTorsionalFrictionConstraint(cp.m_lateralFrictionDir2, manifold, frictionIndex, cp, cp.m_combinedRollingFriction, colObj0, colObj1, relaxation, infoGlobal);
+ addMultiBodyTorsionalFrictionConstraint(cp.m_lateralFrictionDir1, manifold, frictionIndex, cp, cp.m_combinedRollingFriction, colObj0, colObj1, relaxation, infoGlobal);
+ addMultiBodyTorsionalFrictionConstraint(cp.m_lateralFrictionDir2, manifold, frictionIndex, cp, cp.m_combinedRollingFriction, colObj0, colObj1, relaxation, infoGlobal);
}
rollingFriction--;
}
diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h
index f39f2879fc..abf5718839 100644
--- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h
+++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h
@@ -34,6 +34,7 @@ protected:
btMultiBodyConstraintArray m_multiBodyNormalContactConstraints;
btMultiBodyConstraintArray m_multiBodyFrictionContactConstraints;
btMultiBodyConstraintArray m_multiBodyTorsionalFrictionContactConstraints;
+ btMultiBodyConstraintArray m_multiBodySpinningFrictionContactConstraints;
btMultiBodyJacobianData m_data;
@@ -54,6 +55,10 @@ protected:
btScalar combinedTorsionalFriction,
btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity = 0, btScalar cfmSlip = 0);
+ btMultiBodySolverConstraint& addMultiBodySpinningFrictionConstraint(const btVector3& normalAxis, btPersistentManifold* manifold, int frictionIndex, btManifoldPoint& cp,
+ btScalar combinedTorsionalFriction,
+ btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity = 0, btScalar cfmSlip = 0);
+
void setupMultiBodyJointLimitConstraint(btMultiBodySolverConstraint & constraintRow,
btScalar * jacA, btScalar * jacB,
btScalar penetration, btScalar combinedFrictionCoeff, btScalar combinedRestitutionCoeff,
diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp
index 1557987bc3..1131e5378c 100644
--- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp
+++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp
@@ -207,6 +207,7 @@ public:
}
};
+
struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::IslandCallback
{
btContactSolverInfo* m_solverInfo;
@@ -224,6 +225,8 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::
btAlignedObjectArray<btTypedConstraint*> m_constraints;
btAlignedObjectArray<btMultiBodyConstraint*> m_multiBodyConstraints;
+ btAlignedObjectArray<btSolverAnalyticsData> m_islandAnalyticsData;
+
MultiBodyInplaceSolverIslandCallback(btMultiBodyConstraintSolver* solver,
btDispatcher* dispatcher)
: m_solverInfo(NULL),
@@ -235,7 +238,7 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::
{
}
- MultiBodyInplaceSolverIslandCallback& operator=(MultiBodyInplaceSolverIslandCallback& other)
+ MultiBodyInplaceSolverIslandCallback& operator=(const MultiBodyInplaceSolverIslandCallback& other)
{
btAssert(0);
(void)other;
@@ -244,6 +247,7 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::
SIMD_FORCE_INLINE void setup(btContactSolverInfo* solverInfo, btTypedConstraint** sortedConstraints, int numConstraints, btMultiBodyConstraint** sortedMultiBodyConstraints, int numMultiBodyConstraints, btIDebugDraw* debugDrawer)
{
+ m_islandAnalyticsData.clear();
btAssert(solverInfo);
m_solverInfo = solverInfo;
@@ -270,6 +274,11 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::
{
///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id
m_solver->solveMultiBodyGroup(bodies, numBodies, manifolds, numManifolds, m_sortedConstraints, m_numConstraints, &m_multiBodySortedConstraints[0], m_numConstraints, *m_solverInfo, m_debugDrawer, m_dispatcher);
+ if (m_solverInfo->m_reportSolverAnalytics&1)
+ {
+ m_solver->m_analyticsData.m_islandId = islandId;
+ m_islandAnalyticsData.push_back(m_solver->m_analyticsData);
+ }
}
else
{
@@ -335,7 +344,7 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::
if ((m_multiBodyConstraints.size() + m_constraints.size() + m_manifolds.size()) > m_solverInfo->m_minimumSolverBatchSize)
{
- processConstraints();
+ processConstraints(islandId);
}
else
{
@@ -344,7 +353,7 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::
}
}
}
- void processConstraints()
+ void processConstraints(int islandId=-1)
{
btCollisionObject** bodies = m_bodies.size() ? &m_bodies[0] : 0;
btPersistentManifold** manifold = m_manifolds.size() ? &m_manifolds[0] : 0;
@@ -354,6 +363,11 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::
//printf("mb contacts = %d, mb constraints = %d\n", mbContacts, m_multiBodyConstraints.size());
m_solver->solveMultiBodyGroup(bodies, m_bodies.size(), manifold, m_manifolds.size(), constraints, m_constraints.size(), multiBodyConstraints, m_multiBodyConstraints.size(), *m_solverInfo, m_debugDrawer, m_dispatcher);
+ if (m_bodies.size() && (m_solverInfo->m_reportSolverAnalytics&1))
+ {
+ m_solver->m_analyticsData.m_islandId = islandId;
+ m_islandAnalyticsData.push_back(m_solver->m_analyticsData);
+ }
m_bodies.resize(0);
m_manifolds.resize(0);
m_constraints.resize(0);
@@ -361,6 +375,11 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::
}
};
+void btMultiBodyDynamicsWorld::getAnalyticsData(btAlignedObjectArray<btSolverAnalyticsData>& islandAnalyticsData) const
+{
+ islandAnalyticsData = m_solverMultiBodyIslandCallback->m_islandAnalyticsData;
+}
+
btMultiBodyDynamicsWorld::btMultiBodyDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btMultiBodyConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration)
: btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration),
m_multiBodyConstraintSolver(constraintSolver)
@@ -717,13 +736,17 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo)
m_scratch_v.resize(bod->getNumLinks() + 1);
m_scratch_m.resize(bod->getNumLinks() + 1);
+ if (bod->internalNeedsJointFeedback())
{
if (!bod->isUsingRK4Integration())
{
- bool isConstraintPass = true;
- bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(solverInfo.m_timeStep, m_scratch_r, m_scratch_v, m_scratch_m, isConstraintPass,
- getSolverInfo().m_jointFeedbackInWorldSpace,
- getSolverInfo().m_jointFeedbackInJointFrame);
+ if (bod->internalNeedsJointFeedback())
+ {
+ bool isConstraintPass = true;
+ bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(solverInfo.m_timeStep, m_scratch_r, m_scratch_v, m_scratch_m, isConstraintPass,
+ getSolverInfo().m_jointFeedbackInWorldSpace,
+ getSolverInfo().m_jointFeedbackInJointFrame);
+ }
}
}
}
diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h
index 641238f3bb..e36c2f7aad 100644
--- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h
+++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h
@@ -109,5 +109,7 @@ public:
virtual void serialize(btSerializer* serializer);
virtual void setMultiBodyConstraintSolver(btMultiBodyConstraintSolver* solver);
virtual void setConstraintSolver(btConstraintSolver* solver);
+ virtual void getAnalyticsData(btAlignedObjectArray<struct btSolverAnalyticsData>& m_islandAnalyticsData) const;
+
};
#endif //BT_MULTIBODY_DYNAMICS_WORLD_H
diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyLinkCollider.h b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyLinkCollider.h
index f91c001f12..bc909990c2 100644
--- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyLinkCollider.h
+++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyLinkCollider.h
@@ -36,6 +36,10 @@ public:
btMultiBody* m_multiBody;
int m_link;
+ virtual ~btMultiBodyLinkCollider()
+ {
+
+ }
btMultiBodyLinkCollider(btMultiBody* multiBody, int link)
: m_multiBody(multiBody),
m_link(link)
diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.cpp b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.cpp
index 338e8af0ab..f2186a93e9 100644
--- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.cpp
+++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.cpp
@@ -22,9 +22,9 @@ subject to the following restrictions:
#define DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS
-static bool interleaveContactAndFriction = false;
+static bool interleaveContactAndFriction1 = false;
-struct btJointNode
+struct btJointNode1
{
int jointIndex; // pointer to enclosing dxJoint object
int otherBodyIndex; // *other* body this joint is connected to
@@ -241,7 +241,7 @@ void btMultiBodyMLCPConstraintSolver::createMLCPFast(const btContactSolverInfo&
void btMultiBodyMLCPConstraintSolver::createMLCPFastRigidBody(const btContactSolverInfo& infoGlobal)
{
- int numContactRows = interleaveContactAndFriction ? 3 : 1;
+ int numContactRows = interleaveContactAndFriction1 ? 3 : 1;
int numConstraintRows = m_allConstraintPtrArray.size();
@@ -301,7 +301,7 @@ void btMultiBodyMLCPConstraintSolver::createMLCPFastRigidBody(const btContactSol
BT_PROFILE("bodyJointNodeArray.resize");
bodyJointNodeArray.resize(numBodies, -1);
}
- btAlignedObjectArray<btJointNode> jointNodeArray;
+ btAlignedObjectArray<btJointNode1> jointNodeArray;
{
BT_PROFILE("jointNodeArray.reserve");
jointNodeArray.reserve(2 * m_allConstraintPtrArray.size());
@@ -729,7 +729,7 @@ btScalar btMultiBodyMLCPConstraintSolver::solveGroupCacheFriendlySetup(
int firstContactConstraintOffset = dindex;
// The btSequentialImpulseConstraintSolver moves all friction constraints at the very end, we can also interleave them instead
- if (interleaveContactAndFriction)
+ if (interleaveContactAndFriction1)
{
for (int i = 0; i < m_tmpSolverContactConstraintPool.size(); i++)
{
@@ -785,7 +785,7 @@ btScalar btMultiBodyMLCPConstraintSolver::solveGroupCacheFriendlySetup(
firstContactConstraintOffset = dindex;
// The btSequentialImpulseConstraintSolver moves all friction constraints at the very end, we can also interleave them instead
- if (interleaveContactAndFriction)
+ if (interleaveContactAndFriction1)
{
for (int i = 0; i < m_multiBodyNormalContactConstraints.size(); ++i)
{
diff --git a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.h b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.h
index 6be36ba142..77fdb86bb9 100644
--- a/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.h
+++ b/thirdparty/bullet/BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.h
@@ -156,7 +156,7 @@ protected:
btTypedConstraint** constraints,
int numConstraints,
const btContactSolverInfo& infoGlobal,
- btIDebugDraw* debugDrawer) BT_OVERRIDE;
+ btIDebugDraw* debugDrawer) ;
public:
BT_DECLARE_ALIGNED_ALLOCATOR()
diff --git a/thirdparty/bullet/BulletDynamics/MLCPSolvers/btLemkeSolver.h b/thirdparty/bullet/BulletDynamics/MLCPSolvers/btLemkeSolver.h
index 3f215e56bb..ac2fc46ab0 100644
--- a/thirdparty/bullet/BulletDynamics/MLCPSolvers/btLemkeSolver.h
+++ b/thirdparty/bullet/BulletDynamics/MLCPSolvers/btLemkeSolver.h
@@ -20,7 +20,7 @@ subject to the following restrictions:
#include "btMLCPSolverInterface.h"
#include "btLemkeAlgorithm.h"
-///The btLemkeSolver is based on "Fast Implementation of Lemke’s Algorithm for Rigid Body Contact Simulation (John E. Lloyd) "
+///The btLemkeSolver is based on "Fast Implementation of Lemke's Algorithm for Rigid Body Contact Simulation (John E. Lloyd) "
///It is a slower but more accurate solver. Increase the m_maxLoops for better convergence, at the cost of more CPU time.
///The original implementation of the btLemkeAlgorithm was done by Kilian Grundl from the MBSim team
class btLemkeSolver : public btMLCPSolverInterface
@@ -67,7 +67,7 @@ public:
btMatrixXu A1;
btMatrixXu B(n, n);
{
- BT_PROFILE("inverse(slow)");
+ //BT_PROFILE("inverse(slow)");
A1.resize(A.rows(), A.cols());
for (int row = 0; row < A.rows(); row++)
{
@@ -174,7 +174,7 @@ public:
y1.resize(n, 1);
btLemkeAlgorithm lemke(M, qq, m_debugLevel);
{
- BT_PROFILE("lemke.solve");
+ //BT_PROFILE("lemke.solve");
lemke.setSystem(M, qq);
z1 = lemke.solve(m_maxLoops);
}
diff --git a/thirdparty/bullet/BulletInverseDynamics/MultiBodyTree.cpp b/thirdparty/bullet/BulletInverseDynamics/MultiBodyTree.cpp
index f150b5ae4c..9326b0d098 100644
--- a/thirdparty/bullet/BulletInverseDynamics/MultiBodyTree.cpp
+++ b/thirdparty/bullet/BulletInverseDynamics/MultiBodyTree.cpp
@@ -349,7 +349,7 @@ int MultiBodyTree::finalize()
const int &num_bodies = m_init_cache->numBodies();
const int &num_dofs = m_init_cache->numDoFs();
- if (num_dofs <= 0)
+ if (num_dofs < 0)
{
bt_id_error_message("Need num_dofs>=1, but num_dofs= %d\n", num_dofs);
//return -1;
diff --git a/thirdparty/bullet/BulletInverseDynamics/details/MultiBodyTreeImpl.cpp b/thirdparty/bullet/BulletInverseDynamics/details/MultiBodyTreeImpl.cpp
index befbc2e2a4..ec9a562295 100644
--- a/thirdparty/bullet/BulletInverseDynamics/details/MultiBodyTreeImpl.cpp
+++ b/thirdparty/bullet/BulletInverseDynamics/details/MultiBodyTreeImpl.cpp
@@ -479,9 +479,17 @@ int MultiBodyTree::MultiBodyImpl::calculateKinematics(const vecx &q, const vecx
//todo: review
RigidBody &body = m_body_list[m_body_spherical_list[i]];
- body.m_body_T_parent = transformZ(q(body.m_q_index + 2)) *
- transformY(q(body.m_q_index + 1)) *
- transformX(q(body.m_q_index));
+ mat33 T;
+
+ T = transformX(q(body.m_q_index)) *
+ transformY(q(body.m_q_index + 1)) *
+ transformZ(q(body.m_q_index + 2));
+ body.m_body_T_parent = T * body.m_body_T_parent_ref;
+
+ body.m_parent_pos_parent_body(0)=0;
+ body.m_parent_pos_parent_body(1)=0;
+ body.m_parent_pos_parent_body(2)=0;
+
body.m_parent_pos_parent_body = body.m_body_T_parent * body.m_parent_pos_parent_body;
if (type >= POSITION_VELOCITY)
@@ -832,6 +840,25 @@ int MultiBodyTree::MultiBodyImpl::calculateMassMatrix(const vecx &q, const bool
body.m_parent_pos_parent_body = body.m_body_T_parent * body.m_parent_pos_parent_body;
}
+
+ for (idArrayIdx i = 0; i < m_body_spherical_list.size(); i++)
+ {
+ //todo: review
+ RigidBody &body = m_body_list[m_body_spherical_list[i]];
+
+ mat33 T;
+
+ T = transformX(q(body.m_q_index)) *
+ transformY(q(body.m_q_index + 1)) *
+ transformZ(q(body.m_q_index + 2));
+ body.m_body_T_parent = T * body.m_body_T_parent_ref;
+
+ body.m_parent_pos_parent_body(0)=0;
+ body.m_parent_pos_parent_body(1)=0;
+ body.m_parent_pos_parent_body(2)=0;
+
+ body.m_parent_pos_parent_body = body.m_body_T_parent * body.m_parent_pos_parent_body;
+ }
}
for (int i = m_body_list.size() - 1; i >= 0; i--)
{
diff --git a/thirdparty/bullet/BulletSoftBody/btSoftBody.cpp b/thirdparty/bullet/BulletSoftBody/btSoftBody.cpp
index 58796a88d0..7463bdc019 100644
--- a/thirdparty/bullet/BulletSoftBody/btSoftBody.cpp
+++ b/thirdparty/bullet/BulletSoftBody/btSoftBody.cpp
@@ -518,7 +518,7 @@ void btSoftBody::addAeroForceToNode(const btVector3& windVelocity, int nodeIndex
fDrag = 0.5f * kDG * medium.m_density * rel_v2 * tri_area * n_dot_v * (-rel_v_nrm);
// Check angle of attack
- // cos(10º) = 0.98480
+ // cos(10°) = 0.98480
if (0 < n_dot_v && n_dot_v < 0.98480f)
fLift = 0.5f * kLF * medium.m_density * rel_v_len * tri_area * btSqrt(1.0f - n_dot_v * n_dot_v) * (nrm.cross(rel_v_nrm).cross(rel_v_nrm));
@@ -604,7 +604,7 @@ void btSoftBody::addAeroForceToFace(const btVector3& windVelocity, int faceIndex
fDrag = 0.5f * kDG * medium.m_density * rel_v2 * tri_area * n_dot_v * (-rel_v_nrm);
// Check angle of attack
- // cos(10º) = 0.98480
+ // cos(10°) = 0.98480
if (0 < n_dot_v && n_dot_v < 0.98480f)
fLift = 0.5f * kLF * medium.m_density * rel_v_len * tri_area * btSqrt(1.0f - n_dot_v * n_dot_v) * (nrm.cross(rel_v_nrm).cross(rel_v_nrm));
diff --git a/thirdparty/bullet/LinearMath/TaskScheduler/btThreadSupportPosix.cpp b/thirdparty/bullet/LinearMath/TaskScheduler/btThreadSupportPosix.cpp
index 02f4ed1631..a03f6dc570 100644
--- a/thirdparty/bullet/LinearMath/TaskScheduler/btThreadSupportPosix.cpp
+++ b/thirdparty/bullet/LinearMath/TaskScheduler/btThreadSupportPosix.cpp
@@ -45,14 +45,14 @@ subject to the following restrictions:
int btGetNumHardwareThreads()
{
- return btMin<int>(BT_MAX_THREAD_COUNT, std::thread::hardware_concurrency());
+ return btMax(1u, btMin(BT_MAX_THREAD_COUNT, std::thread::hardware_concurrency()));
}
#else
int btGetNumHardwareThreads()
{
- return btMin<int>(BT_MAX_THREAD_COUNT, sysconf(_SC_NPROCESSORS_ONLN));
+ return btMax(1, btMin<int>(BT_MAX_THREAD_COUNT, sysconf(_SC_NPROCESSORS_ONLN)));
}
#endif
@@ -304,8 +304,8 @@ void btThreadSupportPosix::stopThreads()
checkPThreadFunction(sem_post(threadStatus.startSemaphore));
checkPThreadFunction(sem_wait(m_mainSemaphore));
- destroySem(threadStatus.startSemaphore);
checkPThreadFunction(pthread_join(threadStatus.thread, 0));
+ destroySem(threadStatus.startSemaphore);
}
destroySem(m_mainSemaphore);
m_activeThreadStatus.clear();
diff --git a/thirdparty/bullet/LinearMath/btAlignedObjectArray.h b/thirdparty/bullet/LinearMath/btAlignedObjectArray.h
index b4671bc19f..b3d5d64b58 100644
--- a/thirdparty/bullet/LinearMath/btAlignedObjectArray.h
+++ b/thirdparty/bullet/LinearMath/btAlignedObjectArray.h
@@ -38,13 +38,6 @@ subject to the following restrictions:
#include <new> //for placement new
#endif //BT_USE_PLACEMENT_NEW
-// The register keyword is deprecated in C++11 so don't use it.
-#if __cplusplus > 199711L
-#define BT_REGISTER
-#else
-#define BT_REGISTER register
-#endif
-
///The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods
///It is developed to replace stl::vector to avoid portability issues, including STL alignment issues to add SIMD/SSE data
template <typename T>
@@ -209,7 +202,7 @@ public:
SIMD_FORCE_INLINE void resize(int newsize, const T& fillData = T())
{
- const BT_REGISTER int curSize = size();
+ const int curSize = size();
if (newsize < curSize)
{
@@ -236,7 +229,7 @@ public:
}
SIMD_FORCE_INLINE T& expandNonInitializing()
{
- const BT_REGISTER int sz = size();
+ const int sz = size();
if (sz == capacity())
{
reserve(allocSize(size()));
@@ -248,7 +241,7 @@ public:
SIMD_FORCE_INLINE T& expand(const T& fillValue = T())
{
- const BT_REGISTER int sz = size();
+ const int sz = size();
if (sz == capacity())
{
reserve(allocSize(size()));
@@ -263,7 +256,7 @@ public:
SIMD_FORCE_INLINE void push_back(const T& _Val)
{
- const BT_REGISTER int sz = size();
+ const int sz = size();
if (sz == capacity())
{
reserve(allocSize(size()));
diff --git a/thirdparty/bullet/LinearMath/btMatrixX.h b/thirdparty/bullet/LinearMath/btMatrixX.h
index 9df9e49469..388c57c2d7 100644
--- a/thirdparty/bullet/LinearMath/btMatrixX.h
+++ b/thirdparty/bullet/LinearMath/btMatrixX.h
@@ -263,7 +263,10 @@ struct btMatrixX
{
{
BT_PROFILE("storage=0");
- btSetZero(&m_storage[0], m_storage.size());
+ if (m_storage.size())
+ {
+ btSetZero(&m_storage[0], m_storage.size());
+ }
//memset(&m_storage[0],0,sizeof(T)*m_storage.size());
//for (int i=0;i<m_storage.size();i++)
// m_storage[i]=0;
@@ -281,7 +284,7 @@ struct btMatrixX
}
}
- void printMatrix(const char* msg)
+ void printMatrix(const char* msg) const
{
printf("%s ---------------------\n", msg);
for (int i = 0; i < rows(); i++)
diff --git a/thirdparty/bullet/LinearMath/btScalar.h b/thirdparty/bullet/LinearMath/btScalar.h
index c198bd4b35..ba49d6700b 100644
--- a/thirdparty/bullet/LinearMath/btScalar.h
+++ b/thirdparty/bullet/LinearMath/btScalar.h
@@ -124,7 +124,7 @@ inline int btGetVersion()
#ifdef BT_DEBUG
#ifdef _MSC_VER
#include <stdio.h>
- #define btAssert(x) { if(!(x)){printf("Assert "__FILE__ ":%u (%s)\n", __LINE__, #x);__debugbreak(); }}
+ #define btAssert(x) { if(!(x)){printf("Assert " __FILE__ ":%u (%s)\n", __LINE__, #x);__debugbreak(); }}
#else//_MSC_VER
#include <assert.h>
#define btAssert assert
@@ -152,7 +152,7 @@ inline int btGetVersion()
#ifdef __SPU__
#include <spu_printf.h>
#define printf spu_printf
- #define btAssert(x) {if(!(x)){printf("Assert "__FILE__ ":%u ("#x")\n", __LINE__);spu_hcmpeq(0,0);}}
+ #define btAssert(x) {if(!(x)){printf("Assert " __FILE__ ":%u ("#x")\n", __LINE__);spu_hcmpeq(0,0);}}
#else
#define btAssert assert
#endif
diff --git a/thirdparty/bullet/LinearMath/btVector3.h b/thirdparty/bullet/LinearMath/btVector3.h
index 61fd8d1e46..d65ed9808d 100644
--- a/thirdparty/bullet/LinearMath/btVector3.h
+++ b/thirdparty/bullet/LinearMath/btVector3.h
@@ -36,7 +36,7 @@ subject to the following restrictions:
#pragma warning(disable : 4556) // value of intrinsic immediate argument '4294967239' is out of range '0 - 255'
#endif
-#define BT_SHUFFLE(x, y, z, w) ((w) << 6 | (z) << 4 | (y) << 2 | (x))
+#define BT_SHUFFLE(x, y, z, w) (((w) << 6 | (z) << 4 | (y) << 2 | (x)) & 0xff)
//#define bt_pshufd_ps( _a, _mask ) (__m128) _mm_shuffle_epi32((__m128i)(_a), (_mask) )
#define bt_pshufd_ps(_a, _mask) _mm_shuffle_ps((_a), (_a), (_mask))
#define bt_splat3_ps(_a, _i) bt_pshufd_ps((_a), BT_SHUFFLE(_i, _i, _i, 3))
diff --git a/thirdparty/bullet/btBulletCollisionAll.cpp b/thirdparty/bullet/btBulletCollisionAll.cpp
new file mode 100644
index 0000000000..2851fb3b73
--- /dev/null
+++ b/thirdparty/bullet/btBulletCollisionAll.cpp
@@ -0,0 +1,96 @@
+#include "BulletCollision/BroadphaseCollision/btAxisSweep3.cpp"
+#include "BulletCollision/BroadphaseCollision/btDbvt.cpp"
+#include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp"
+#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp"
+#include "BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp"
+#include "BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp"
+#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp"
+#include "BulletCollision/BroadphaseCollision/btDispatcher.cpp"
+#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp"
+#include "BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp"
+#include "BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btHashedSimplePairCache.cpp"
+#include "BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp"
+#include "BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btManifoldResult.cpp"
+#include "BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp"
+#include "BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp"
+#include "BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp"
+#include "BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btCollisionObject.cpp"
+#include "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp"
+#include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btCollisionWorld.cpp"
+#include "BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp"
+#include "BulletCollision/CollisionDispatch/btUnionFind.cpp"
+#include "BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp"
+#include "BulletCollision/CollisionDispatch/btGhostObject.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btConvexCast.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp"
+#include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp"
+#include "BulletCollision/CollisionShapes/btBox2dShape.cpp"
+#include "BulletCollision/CollisionShapes/btConvexPolyhedron.cpp"
+#include "BulletCollision/CollisionShapes/btShapeHull.cpp"
+#include "BulletCollision/CollisionShapes/btBoxShape.cpp"
+#include "BulletCollision/CollisionShapes/btConvexShape.cpp"
+#include "BulletCollision/CollisionShapes/btSphereShape.cpp"
+#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp"
+#include "BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp"
+#include "BulletCollision/CollisionShapes/btStaticPlaneShape.cpp"
+#include "BulletCollision/CollisionShapes/btCapsuleShape.cpp"
+#include "BulletCollision/CollisionShapes/btCylinderShape.cpp"
+#include "BulletCollision/CollisionShapes/btStridingMeshInterface.cpp"
+#include "BulletCollision/CollisionShapes/btCollisionShape.cpp"
+#include "BulletCollision/CollisionShapes/btEmptyShape.cpp"
+#include "BulletCollision/CollisionShapes/btTetrahedronShape.cpp"
+#include "BulletCollision/CollisionShapes/btCompoundShape.cpp"
+#include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp"
+#include "BulletCollision/CollisionShapes/btTriangleBuffer.cpp"
+#include "BulletCollision/CollisionShapes/btConcaveShape.cpp"
+#include "BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp"
+#include "BulletCollision/CollisionShapes/btTriangleCallback.cpp"
+#include "BulletCollision/CollisionShapes/btConeShape.cpp"
+#include "BulletCollision/CollisionShapes/btMultiSphereShape.cpp"
+#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp"
+#include "BulletCollision/CollisionShapes/btConvex2dShape.cpp"
+#include "BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp"
+#include "BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp"
+#include "BulletCollision/CollisionShapes/btConvexHullShape.cpp"
+#include "BulletCollision/CollisionShapes/btOptimizedBvh.cpp"
+#include "BulletCollision/CollisionShapes/btTriangleMesh.cpp"
+#include "BulletCollision/CollisionShapes/btConvexInternalShape.cpp"
+#include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp"
+#include "BulletCollision/CollisionShapes/btTriangleMeshShape.cpp"
+#include "BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp"
+#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp"
+#include "BulletCollision/CollisionShapes/btSdfCollisionShape.cpp"
+#include "BulletCollision/CollisionShapes/btMiniSDF.cpp"
+#include "BulletCollision/CollisionShapes/btUniformScalingShape.cpp"
+#include "BulletCollision/Gimpact/btContactProcessing.cpp"
+#include "BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp"
+#include "BulletCollision/Gimpact/btTriangleShapeEx.cpp"
+#include "BulletCollision/Gimpact/gim_memory.cpp"
+#include "BulletCollision/Gimpact/btGImpactBvh.cpp"
+#include "BulletCollision/Gimpact/btGImpactShape.cpp"
+#include "BulletCollision/Gimpact/gim_box_set.cpp"
+#include "BulletCollision/Gimpact/gim_tri_collision.cpp"
+#include "BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp"
+#include "BulletCollision/Gimpact/btGenericPoolAllocator.cpp"
+#include "BulletCollision/Gimpact/gim_contact.cpp"
diff --git a/thirdparty/bullet/btBulletDynamicsAll.cpp b/thirdparty/bullet/btBulletDynamicsAll.cpp
new file mode 100644
index 0000000000..a8069e30ae
--- /dev/null
+++ b/thirdparty/bullet/btBulletDynamicsAll.cpp
@@ -0,0 +1,42 @@
+#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp"
+#include "BulletDynamics/Dynamics/btRigidBody.cpp"
+#include "BulletDynamics/Dynamics/btSimulationIslandManagerMt.cpp"
+#include "BulletDynamics/Dynamics/btDiscreteDynamicsWorldMt.cpp"
+#include "BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp"
+#include "BulletDynamics/ConstraintSolver/btBatchedConstraints.cpp"
+#include "BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btSliderConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btContactConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btFixedConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btHingeConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btTypedConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btGearConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btNNCGConstraintSolver.cpp"
+#include "BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp"
+#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp"
+#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolverMt.cpp"
+#include "BulletDynamics/MLCPSolvers/btDantzigLCP.cpp"
+#include "BulletDynamics/MLCPSolvers/btLemkeAlgorithm.cpp"
+#include "BulletDynamics/MLCPSolvers/btMLCPSolver.cpp"
+#include "BulletDynamics/Featherstone/btMultiBody.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodyJointMotor.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodyGearConstraint.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodyConstraint.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodyFixedConstraint.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodyPoint2Point.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodySliderConstraint.cpp"
+#include "BulletDynamics/Featherstone/btMultiBodySphericalJointMotor.cpp"
+#include "BulletDynamics/Vehicle/btRaycastVehicle.cpp"
+#include "BulletDynamics/Vehicle/btWheelInfo.cpp"
+#include "BulletDynamics/Character/btKinematicCharacterController.cpp"
+
diff --git a/thirdparty/bullet/btLinearMathAll.cpp b/thirdparty/bullet/btLinearMathAll.cpp
new file mode 100644
index 0000000000..808f412803
--- /dev/null
+++ b/thirdparty/bullet/btLinearMathAll.cpp
@@ -0,0 +1,14 @@
+#include "LinearMath/btAlignedAllocator.cpp"
+#include "LinearMath/btGeometryUtil.cpp"
+#include "LinearMath/btSerializer.cpp"
+#include "LinearMath/btVector3.cpp"
+#include "LinearMath/btConvexHull.cpp"
+#include "LinearMath/btPolarDecomposition.cpp"
+#include "LinearMath/btSerializer64.cpp"
+#include "LinearMath/btConvexHullComputer.cpp"
+#include "LinearMath/btQuickprof.cpp"
+#include "LinearMath/btThreads.cpp"
+#include "LinearMath/TaskScheduler/btTaskScheduler.cpp"
+#include "LinearMath/TaskScheduler/btThreadSupportPosix.cpp"
+#include "LinearMath/TaskScheduler/btThreadSupportWin32.cpp"
+