502 Commits

Author SHA1 Message Date
erwincoumans
6428ed5e5f Merge pull request #2563 from Lopuska/patch-1
add btCollisionDispatcherMt.cpp on unity build
2020-01-12 09:05:34 -08:00
erwincoumans
2f09c7c224 Merge pull request #2581 from erwincoumans/master
bump up pybullet version to 2.6.4
2020-01-12 08:13:03 -08:00
Erwin Coumans
1be6a1d16b fix loadpanda video generation
remove duplicate code (formerly Windows ffpmeg needed different settings?)
2020-01-12 08:07:54 -08:00
Erwin Coumans
84e2ea918c add xarm, modify loadpanda to work with pybullet_robots module 2020-01-12 07:20:32 -08:00
Erwin Coumans
fb15aea414 add example robots in pybullet_robots module 2020-01-12 07:11:57 -08:00
Erwin Coumans
3ca233193f : 2020-01-12 07:03:38 -08:00
Erwin Coumans
2f08938110 Merge branch 'master' of https://github.com/erwincoumans/bullet3 2020-01-11 16:52:01 -08:00
Erwin Coumans
e73de6ea00 bump up pybullet version to 2.6.4 2020-01-11 16:06:14 -08:00
erwincoumans
66ffa329c8 Merge pull request #2577 from xhan0619/master
Add position error into deformable vs. rigid contact
2020-01-11 16:05:15 -08:00
erwincoumans
a9615258d3 Merge pull request #2580 from erwincoumans/master
add --mp4fps=30 command line parameter for ExampleBrowser, various other fixes
2020-01-11 15:14:11 -08:00
erwincoumans
61fa943994 Merge pull request #2558 from Lopuska/crash_fix_btMt
[crash fix for btCollisionDispatcherMt] a better approach to merge new manifolds when using the jobs CPU dispatcher
2020-01-11 13:54:34 -08:00
Erwin Coumans
d328406cfa Merge branch 'master' of https://github.com/erwincoumans/bullet3 2020-01-11 13:17:00 -08:00
Erwin Coumans
8b578093a3 Merge branch 'master' of https://github.com/erwincoumans/bullet3 2020-01-11 13:16:47 -08:00
Erwin Coumans
eee7bcbc14 remove debug/profile tag 2020-01-11 13:16:12 -08:00
Erwin Coumans
3f11b03255 add friction anchors for Panda gripper (prevents/reduces sliding objects out of gripper) 2020-01-11 13:13:28 -08:00
Erwin Coumans
8f8bbbee3b example how to create a video using PyBullet using GUI mode with ffmpeg, synchronizing video with stepSimulation at specific frame rate (240 Hz for example) 2020-01-11 13:06:45 -08:00
Erwin Coumans
2336dfcb9e Remove a temporary global static work matrix in the BussIK, since it conflicts with multithreaded applications.
Instead, let the user pass it in explicitly.
2020-01-11 12:43:27 -08:00
Erwin Coumans
83bdef8254 add --mp4fps=30 command line parameter for ExampleBrowser (and using pybullet.connect(p.GUI, options="--mp4fps=30 --mp4=\"testvideo.mp4\"") 2020-01-11 12:19:42 -08:00
erwincoumans
5bf6adcf9d Update btCollisionDispatcherMt.h
add a space to fix compile errors
2020-01-11 06:57:35 -08:00
erwincoumans
88826da6b5 Merge pull request #2576 from dmcconachie/DeformableGravity
[BUGFIX] Update existing deformable gravity forces on gravity change.
2020-01-09 21:30:48 -08:00
Erwin Coumans
8ebdf7862c fix b3RobotSimulatorClientAPI_NoDirect::changeConstraint API 2020-01-09 17:56:21 -08:00
Dale McConachie
b526c01bec Update existing deformable gravity forces on gravity change. 2020-01-09 16:24:32 -05:00
Erwin Coumans
5cd4647943 fix submitProfileTiming API in b3RobotSimulatorClientAPI_NoDirect 2020-01-09 10:40:14 -08:00
erwincoumans
c85e8f038b Merge pull request #2574 from erwincoumans/master
fix indexing issue removing graphics shape in tinyrenderer plugin (us…
2020-01-08 21:20:52 -08:00
Erwin Coumans
07cdae8c6e also apply TinyRenderer remove shape fix for rigid body and soft body/deformable 2020-01-08 14:02:32 -08:00
Erwin Coumans
6fde189735 fix indexing issue removing graphics shape in tinyrenderer plugin (use getUserIndex3 instead of broadphase uid) 2020-01-08 13:49:41 -08:00
erwincoumans
2dcb372080 Merge pull request #2565 from araffin/feat/sb-example
Add Stable-Baselines example with SAC and TD3
2020-01-08 11:51:35 -08:00
erwincoumans
40fdfbd236 Merge pull request #2573 from erwincoumans/master
add Python version 3.7 and 3.8 to setup.py
2020-01-08 11:51:05 -08:00
Xuchen Han
ee2a811c09 parameter tweaks after testing on robot 2020-01-04 19:29:52 -08:00
Erwin Coumans
02d48d743f add Python version 3.7 and 3.8 to setup.py 2020-01-02 21:31:48 -08:00
erwincoumans
b57557c6cf Merge pull request #2567 from erwincoumans/master
one more fix in previous commit related to bullet_client.py
2020-01-02 20:00:24 -08:00
Erwin Coumans
3cdbc4cc29 fix CartPoleBulletEnv-v1 and add CartPoleContinuousBulletEnv-v0 (continuous version) 2020-01-02 19:33:57 -08:00
Erwin Coumans
ea3857c2c4 bump up version, fix due to regression in bullet_client 2020-01-02 14:51:26 -08:00
Erwin Coumans
3c8cf390d4 one more fix in previous commit related to bullet_client.py 2020-01-02 14:45:42 -08:00
Antonin RAFFIN
adad4dc402 Update buffer size 2020-01-02 14:47:30 +01:00
Antonin RAFFIN
59c61a46bb Simplify imports 2020-01-02 11:12:45 +01:00
Antonin RAFFIN
da0483b03a Add colab notebook 2020-01-02 11:06:39 +01:00
Antonin RAFFIN
9c969614bc Add Stable-Baselines example with SAC and TD3 2020-01-02 11:00:45 +01:00
erwincoumans
aae8048722 Merge pull request #2564 from erwincoumans/master
fix a few pybullet Gym environments for rendering in stable_baselines
2020-01-01 21:31:57 -08:00
Erwin Coumans
c39afa61cb revert bullet_client.py 2020-01-01 20:27:27 -08:00
Erwin Coumans
a9455ce891 add 'runServer.py' script in pybullet_utils, this will run a GUI server
that accepts SHARED_MEMORY connections. Handy if you run a pybullet_envs Gym environment
and want to visualize it. By default, bullet_client will try to connect to a shared memory connection first.
2020-01-01 18:53:32 -08:00
Erwin Coumans
b6dea7ba64 fix a few pybullet Gym environments for rendering in stable_baselines
if PYBULLET_EGL environment is set, try to enable EGL for faster rendering
bump up pybullet to 2.6.2
2020-01-01 18:47:46 -08:00
Xuchen Han
a274bcbfa3 add position error into deformable vs. rigid solve 2019-12-31 19:18:37 -08:00
Erwin Coumans
528bd28e34 increase plane from 30 to 200 (to allow quadrupeds to run further, not fall off cliff)
fix issue with gym.wrappers in pybullet_envs.agents.visualize_ppo.py
2019-12-31 18:13:49 -08:00
Xuchen Han
78a8ddb466 change default damping model for mass spring to the angular momentum conserving one 2019-12-31 14:08:21 -08:00
Lopuska
8f03a69e95 add btCollisionDispatcherMt,cpp on unity build 2019-12-31 23:07:03 +01:00
Xuchen Han
4ab550d358 update deformable demos 2019-12-31 14:05:45 -08:00
Xuchen Han
d7442cee21 add strain rate limiting 2019-12-31 14:04:18 -08:00
Xuchen Han
79c1343b6a change number of quadrature points from 3 to 2 2019-12-31 14:03:54 -08:00
erwincoumans
ed29ba61d4 Merge pull request #2561 from Qix-/no-vector-math
Remove unused custom vector math cmake option
2019-12-30 18:07:52 -08:00
Josh Junon
dfb0d4deae remove unused custom vector math cmake option 2019-12-31 01:34:47 +01:00
Xuchen Han
a808d74895 fix bug in the pretransform of rigid body interpolation transform 2019-12-30 10:55:30 -08:00
Anis
de9ac113c4 a better approach to merge new manifolds on multithreaded CPU dispatcher 2019-12-30 02:17:59 +01:00
Xuchen Han
442047a862 more bug fixes 2019-12-27 13:16:31 -08:00
Xuchen Han
65b75e5937 bug fixes for face contact to prevent sticking 2019-12-27 12:43:08 -08:00
erwincoumans
c9a0646bda Merge pull request #2548 from dbartolini/cleanup-dbvt-init-order
Fix warning with -Wreorder
2019-12-24 10:03:35 -08:00
erwincoumans
56f199a0b6 Merge pull request #2553 from erwincoumans/master
add xarm 6 example with inverse kinematics (IK) that runs about 150 m…
2019-12-23 13:41:00 -08:00
Erwin Coumans
386afaa2b7 Merge branch 'master' of https://github.com/erwincoumans/bullet3 2019-12-23 10:39:48 -08:00
Erwin Coumans
c2d52750da enable rolling/spinning friction for all contacts 2019-12-23 10:39:39 -08:00
Erwin Coumans
ffc76fbf6d add xarm 6 example with inverse kinematics (IK) that runs about 150 microseconds (Ryzen 3900x) 2019-12-22 17:17:37 -08:00
erwincoumans
c85dca497b Merge pull request #2552 from erwincoumans/master
bump up pybullet to version 2.6.1
2019-12-20 18:46:41 -08:00
Erwin Coumans
3fa67ea7d4 fix memory leak in previous commit (delete m_solverDeformableBodyIslandCallback!) 2019-12-20 18:18:45 -08:00
Erwin Coumans
d7ac3e9cc1 update PyBullet quickstart guide.pdf 2019-12-20 16:30:15 -08:00
Erwin Coumans
9afe9757be bump up pybullet to version 2.6.1 2019-12-20 16:27:50 -08:00
erwincoumans
830f0a9565 Merge pull request #2550 from xhan0619/master
Group deformable constraint solves by islands
2019-12-20 16:26:32 -08:00
Xuchen Han
6a8973d2f4 address PR comment and tune parameters for cloth 2019-12-19 21:51:54 -08:00
erwincoumans
d6bde9271b Merge pull request #2551 from erwincoumans/master
enable programmatic creation of spherical joint
2019-12-19 21:04:03 -08:00
Erwin Coumans
7a4023430a fix pybullet.submitProfileTiming 2019-12-19 18:05:41 -08:00
Erwin Coumans
9c7e6d6a48 enable programmatic creation of spherical joint 2019-12-19 16:56:09 -08:00
Xuchen Han
4ab0387262 Merge remote-tracking branch 'origin/master'
merge origin/master
2019-12-18 23:18:16 -08:00
Xuchen Han
89553c44e7 solve constraints involving deformable objects according to islands 2019-12-18 23:11:34 -08:00
Daniele Bartolini
94f0a14e43 Fix warning with -Wreorder 2019-12-18 21:20:49 +01:00
erwincoumans
4414136f32 Merge pull request #2541 from dbartolini/cleanup-fix-multi-line-warning
Fix multi-line comment warning with -Wcomment
2019-12-17 19:10:07 -08:00
erwincoumans
63843dffc2 Merge pull request #2543 from dbartolini/cleanup-fix-user-headers
Fix warning with -Wunused-parameter
2019-12-17 19:09:20 -08:00
erwincoumans
2d66858918 Merge pull request #2544 from dbartolini/cleanup-dbvt
Remove unnecessary copy constructor in btDbvt
2019-12-17 19:08:52 -08:00
erwincoumans
613f39988c Merge pull request #2540 from dbartolini/cleanup-broadphase-proxy
Remove unnecessary copy constructor in btBroadphasePair
2019-12-17 19:08:36 -08:00
erwincoumans
7584847f33 Merge pull request #2537 from erwincoumans/master
fix pybullet_envs path, pybullet version to 2.6.0, allow clang-cl on Windows
2019-12-17 19:06:11 -08:00
Xuchen Han
f65a8b03c0 separate deformable contact solve by islands WIP 2019-12-17 18:27:23 -08:00
erwincoumans
bb3c87681c Merge pull request #2546 from fuchuyuan/smallfix
add link index to setdamping C APIs. If link index is not set, the co…
2019-12-17 15:45:49 -08:00
Chuyuan Fu
0f477e27ae add link index to setdamping C APIs. If link index is not set, the command is igored for rigidbody 2019-12-17 13:48:34 -08:00
Daniele Bartolini
4ea4c7ef6a Remove unnecessary copy constructor in btDbvt 2019-12-15 01:21:24 +01:00
Daniele Bartolini
78398df00e Fix warning with -Wunused-parameter 2019-12-15 01:03:01 +01:00
Daniele Bartolini
b91124b012 Fix multi-line comment warning with -Wcomment 2019-12-15 00:41:00 +01:00
Daniele Bartolini
0aa4974b98 Remove unnecessary copy constructor in btBroadphasePair 2019-12-15 00:35:44 +01:00
Xuchen Han
d38ea87027 add gripper with deformable cloth demo 2019-12-13 14:33:54 -08:00
Erwin Coumans
7241fe19b9 Merge branch 'master' of https://github.com/erwincoumans/bullet3 2019-12-13 09:21:00 -08:00
Erwin Coumans
30b42a14f0 add single-link arm urdf files for debugging 2019-12-13 09:20:46 -08:00
Erwin Coumans
3668bc5e2a tweak premake4 default batch file.
add manual control for joint angles in XArm6 example.
2019-12-12 07:02:27 -08:00
Erwin Coumans
082a1ddbfe remove bla 2019-12-11 17:08:59 -08:00
Erwin Coumans
1a245f4e11 Merge branch 'master' of https://github.com/erwincoumans/bullet3 2019-12-11 16:49:04 -08:00
Erwin Coumans
2f6eb59e16 add z-up version of Laikago, centered along the chassis center of mass 2019-12-11 16:47:52 -08:00
Erwin Coumans
2ced9c504a make it a one-liner, so clang-cl doesn't fail on Windows 2019-12-11 14:04:55 -08:00
erwincoumans
08321b96ba Update main_opengl_single_example.cpp
Apply fix from PR #2526 manually, thanks to  Andrew Meadows
2019-12-11 13:59:44 -08:00
Erwin Coumans
202cf18995 allow to compile using clang-cl on visual studio (disable SSE) 2019-12-11 13:07:53 -08:00
Erwin Coumans
9a981f4736 bump up pybullet to 2.6.0 2019-12-10 15:49:31 -08:00
Erwin Coumans
d254b65fee Merge remote-tracking branch 'bp/master' 2019-12-10 15:48:24 -08:00
Erwin Coumans
e7778502e7 fix pybullet_envs path 2019-12-10 15:48:07 -08:00
erwincoumans
6c722f8f94 Merge pull request #2528 from jackson-waschura/master
Actually use self collisions when specified
2019-12-09 09:35:06 -08:00
erwincoumans
880faef997 Merge pull request #2535 from erwincoumans/master
Googley colors for xarm (debugging) and tweak example with table etc.…
2019-12-09 09:26:47 -08:00
Erwin Coumans
1a491dc700 Googley colors for xarm (debugging) and tweak example with table etc. Add missing link6_vhacd.obj 2019-12-09 09:25:15 -08:00
erwincoumans
e0a43fb116 Merge pull request #2534 from erwincoumans/master
remove duplicate xarm6.urdf
2019-12-09 08:57:00 -08:00
Erwin Coumans
0a8ade5233 remove duplicate xarm6.urdf 2019-12-09 08:54:56 -08:00
erwincoumans
1b8d7be2b6 Merge pull request #2533 from erwincoumans/master
also enable simplified convex decomposition collision meshes for xarm…
2019-12-09 08:53:27 -08:00
Erwin Coumans
67905efd0f also enable simplified convex decomposition collision meshes for xarm6_robot.urdf 2019-12-09 08:51:02 -08:00
erwincoumans
e57fb497eb Merge pull request #2530 from davidrusu/unify-uses-of-bullet-client
Unify usage of BulletClient in examples
2019-12-08 19:35:49 -08:00
David Rusu
dd3bdf0da1 Use pybullet_utils.bullet_client for all our BulletClient needs 2019-12-08 20:10:12 -05:00
jackson-waschura
0b33d940e4 Actually use self collisions when specified 2019-12-08 13:54:38 +01:00
erwincoumans
08bc887b19 Merge pull request #2527 from erwincoumans/master
add Franka Panda and XArm6 URDF and examples
2019-12-08 00:41:11 -08:00
Erwin Coumans
70329ca2ad added Apache 2 license for Panda Franka URDF 2019-12-08 00:40:10 -08:00
Erwin Coumans
4cfd30f19c add Franka Panda URDF and example (python3 -m pybullet_envs.examples.loadpanda)
add XArm6 URDF with optimized collision meshes and example (XArm gripper needs more work) python3 -m pybullet_envs.examples.xarm
2019-12-08 00:38:49 -08:00
erwincoumans
d57546b645 Merge pull request #2524 from erwincoumans/master
fix clang warning
2019-12-05 09:04:03 -08:00
Erwin Coumans
146a751eb4 enable intermediate log for walk, so you can restart if stuck in local maximum 2019-12-05 08:34:34 -08:00
Erwin Coumans
8113bc72d5 Merge remote-tracking branch 'bp/master' 2019-12-05 08:06:16 -08:00
Erwin Coumans
7b072f1f28 fix clang warning unction 'btSoftBody::checkDeformableFaceContact' has a definition with different parameter names 2019-12-05 08:05:32 -08:00
erwincoumans
c74b88b436 Merge pull request #2522 from erwincoumans/master
update Laikago robot with textures, and a version with toes to enable…
2019-12-04 21:14:21 -08:00
Erwin Coumans
91328f9280 Merge branch 'master' of https://github.com/erwincoumans/bullet3 2019-12-04 15:49:30 -08:00
Erwin Coumans
7f3059c7a9 increase max number of parameters (to around 300) in debug GUI 2019-12-04 15:49:06 -08:00
Erwin Coumans
7c5796b67d update Laikago robot with textures, and a version with toes to enable inverse kinematics. 2019-12-04 14:48:28 -08:00
erwincoumans
ef08e9b415 Merge pull request #2517 from erwincoumans/master
enable self-collision for deep_mimic pybullet_envs, fix Mac Catalina pybullet pip build
2019-12-04 08:56:42 -08:00
erwincoumans
44f21e462a Merge pull request #2509 from xhan0619/separate-bending-stiffness
Separate in-plane and bending stiffness for mass spring model
2019-12-04 07:34:28 -08:00
Erwin Coumans
763e25dd37 fix Mac Catalina pybullet build (setup.py) 2019-12-03 20:49:08 -08:00
Erwin Coumans
7f9f514b7e enable self-collision for deep_mimic pybullet_envs and make it easier to try it out:
python3 -m pybullet_envs.deep_mimic.testrl
2019-11-30 13:19:28 -08:00
erwincoumans
c4300dc299 Merge pull request #2505 from stephenjust/update-gitignore
Add common CMake and Visual Studio project files to gitignore
2019-11-29 10:31:42 -08:00
erwincoumans
70c064ca0d Merge pull request #2501 from erwincoumans/master
bump up pybullet version, fix old examples
2019-11-29 09:32:15 -08:00
Erwin Coumans
cf67e7af0a Merge remote-tracking branch 'bp/master' 2019-11-29 08:06:53 -08:00
Erwin Coumans
56d0b7a09a deep_mimic, read velocity from poseInterpolator, not kinematic model
This fixes issue #2401
2019-11-29 08:05:54 -08:00
Xuchen Han
8fde74ecea update SHARED_MEMORY_MAGIC_NUMBER 2019-11-28 12:14:40 -08:00
erwincoumans
7546541c85 Merge pull request #2506 from xhan0619/master
Deformable vs. Rigid face contact improvement and Deformable vs. Deformable contact improvement
2019-11-28 06:49:04 -08:00
Xuchen Han
7bce5d61f4 separate in-plane and bending stiffness for mass spring model for easier parameter tuning 2019-11-27 11:40:10 -08:00
Xuchen Han
39df98465e set a smaller dt for deformable_ball.py for stability and typo fix 2019-11-25 17:07:00 -08:00
Xuchen Han
abd7a556e1 Merge remote-tracking branch 'origin/master' 2019-11-25 15:29:25 -08:00
Stephen Just
35d8005b72 Add common CMake and Visual Studio project files to gitignore 2019-11-24 16:40:54 -08:00
Erwin Coumans
d9ab536682 Merge branch 'master' of https://github.com/erwincoumans/bullet3 2019-11-21 19:37:11 -08:00
Erwin Coumans
6502409b26 bump up pybullet version 2019-11-21 19:36:46 -08:00
Erwin Coumans
824fd6410f Use -> Set in API 2019-11-21 19:07:11 -08:00
erwincoumans
574343405d Merge pull request #2499 from xhan0619/fix-render-mesh
Fix render mesh
2019-11-21 16:38:54 -08:00
Xuchen Han
f237a40621 add a pybullet example to compare the result of soft body and deformable body 2019-11-21 00:09:32 -08:00
Xuchen Han
fa7cb25c95 revert the default world to SOFT_MULTIBODY_WORLD 2019-11-20 23:47:15 -08:00
erwincoumans
e5cd117c01 Merge pull request #2500 from fuchuyuan/softbodyAABB
get correct AABB for softbody instead of using default AABB
2019-11-20 21:00:36 -08:00
Erwin Coumans
46a7fbe92f fix old threading examples 2019-11-20 17:06:05 -08:00
Chuyuan Fu
593fc872ab get correct AABB for softbody 2019-11-20 16:42:04 -08:00
Xuchen Han
edffb0cc55 update pybullet examples 2019-11-19 23:10:13 -08:00
Xuchen Han
00add5490f fix separate render and sim mesh 2019-11-19 23:10:08 -08:00
Xuchen Han
64e5e007e3 load render mesh from command 2019-11-19 21:07:26 -08:00
erwincoumans
49cf4dfc56 Merge pull request #2498 from erwincoumans/master
enable compilation without deformables/soft bodies (for some unit tests
2019-11-19 20:58:13 -08:00
Erwin Coumans
66951ac102 fix Mac version of deformable_anchor.py 2019-11-19 19:35:28 -08:00
Erwin Coumans
96deb42aa5 pybullet.createSoftBodyAnchor 2019-11-19 19:20:08 -08:00
Erwin Coumans
431a71ebad fix indexing in tetrahedra 2019-11-19 16:27:57 -08:00
Erwin Coumans
bf7b107aec Merge remote-tracking branch 'bp/master' 2019-11-19 16:07:44 -08:00
erwincoumans
ebf742e265 Update README.md
add citation for usage of PyBullet
2019-11-19 13:11:24 -08:00
Erwin Coumans
d42cf2d0ca enable compilation without deformables/soft bodies (for some unit tests
in premake)
2019-11-19 12:20:33 -08:00
erwincoumans
c7d91b686a Merge pull request #2497 from erwincoumans/master
tweak hash function (sdf)
2019-11-19 11:51:05 -08:00
Xuchen Han
6c34c91ca7 load render mesh from command 2019-11-18 23:37:23 -08:00
Xuchen Han
f5400b40d2 Add faces to volumetric objects in deformable demos 2019-11-18 23:37:23 -08:00
Erwin Coumans
e5ed15c3b2 fix memory issues in btSparseSDF.h
(hash function on structure with uninitialized padding, and  Reset not called in destructor)
expose sparseSdfVoxelSize in PyBullet.setPhysicsEngineParameter
don't call deformable wireframe drawing in the wrong thread/place (it can cause crashes)
2019-11-18 23:37:23 -08:00
Erwin Coumans
4ee788e2af update quickstart guide from https://docs.google.com/document/d/10sXEhzFRSnvFcl3XxNGhnD4N2SedqwdAvK3dsihxVUA 2019-11-18 23:37:23 -08:00
Xuchen Han
6268911a43 enable real time simulation 2019-11-18 23:37:22 -08:00
Xuchen Han
22fb2cfb5e add python binding to allow loading deformable objects 2019-11-18 23:37:22 -08:00
Erwin Coumans
655981c6ad fix load_soft_body.py example.
add optional flags in pybullet.resetSimulation.
fix compile issue due to SKIP_DEFORMABLE_WORLD
fix issue in .obj importer (todo: replace with tiny_obj_loader)
todo: replace std::ifstream fs; by fileIO usage.
2019-11-18 23:37:22 -08:00
Erwin Coumans
dc26d2e360 PyBullet: fix memory leak in changeTexture command
Fixes #2481
2019-11-18 23:37:22 -08:00
Erwin Coumans
8f16332708 expose the double sided flag 2019-11-18 23:37:22 -08:00
Erwin Coumans
920b253e87 Deformables: enable double sided rendering, reduced the number of debug lines in regular rendering. 2019-11-18 23:37:22 -08:00
sjdrc
c0836939ec Update bullet.pc.cmake
Change pkgconfig file to match example in pkg-config man files
2019-11-18 23:37:22 -08:00
Erwin Coumans
363dc8d431 tweak hash function (sdf) 2019-11-18 21:46:05 -08:00
erwincoumans
d26752b232 Merge pull request #2496 from xhan0619/add-deformable-faces
Add faces to volumetric objects in deformable demos
2019-11-18 16:07:07 -08:00
erwincoumans
e0a73cbc45 Merge pull request #2495 from erwincoumans/master
various deformable fixes and reimplement #2494
2019-11-18 16:06:29 -08:00
Xuchen Han
c4e73ec8a7 Add faces to volumetric objects in deformable demos 2019-11-18 14:47:57 -08:00
Erwin Coumans
1f6d504e44 fix memory issues in btSparseSDF.h
(hash function on structure with uninitialized padding, and  Reset not called in destructor)
expose sparseSdfVoxelSize in PyBullet.setPhysicsEngineParameter
don't call deformable wireframe drawing in the wrong thread/place (it can cause crashes)
2019-11-18 10:22:56 -08:00
erwincoumans
d258bbf7ac Merge pull request #2493 from erwincoumans/master
update quickstart guide from https://docs.google.com/document/d/10sXE…
2019-11-17 14:55:35 -08:00
Erwin Coumans
4527966ae1 update quickstart guide from https://docs.google.com/document/d/10sXEhzFRSnvFcl3XxNGhnD4N2SedqwdAvK3dsihxVUA 2019-11-17 14:54:34 -08:00
erwincoumans
b4a5558c6b Merge pull request #2489 from xhan0619/pybullet-deformable
Add python binding to allow loading deformable objects
2019-11-16 10:45:36 -08:00
Xuchen Han
bca87426f4 enable real time simulation 2019-11-15 22:38:47 -08:00
Xuchen Han
a86710c5b6 add python binding to allow loading deformable objects 2019-11-15 21:25:11 -08:00
erwincoumans
28039903b1 Merge pull request #2487 from erwincoumans/master
PyBullet: fix memory leak in changeTexture command
2019-11-15 07:33:18 -08:00
Erwin Coumans
72e0e7c223 fix load_soft_body.py example.
add optional flags in pybullet.resetSimulation.
fix compile issue due to SKIP_DEFORMABLE_WORLD
fix issue in .obj importer (todo: replace with tiny_obj_loader)
todo: replace std::ifstream fs; by fileIO usage.
2019-11-14 21:20:42 -08:00
Erwin Coumans
8d56986206 Merge branch 'master' of https://github.com/erwincoumans/bullet3 2019-11-14 17:07:19 -08:00
Erwin Coumans
24a76614f8 PyBullet: fix memory leak in changeTexture command
Fixes #2481
2019-11-14 17:07:08 -08:00
erwincoumans
7ffa68beb8 Merge pull request #2460 from sjdrc/patch-1
Update bullet.pc.cmake
2019-11-13 13:21:28 -08:00
erwincoumans
6bf8419d56 Merge pull request #2482 from erwincoumans/master
Deformables: enable double sided rendering
2019-11-13 11:41:23 -08:00
Erwin Coumans
cabef63b1c expose the double sided flag 2019-11-12 20:36:20 -08:00
Erwin Coumans
9ca957387f Deformables: enable double sided rendering, reduced the number of debug lines in regular rendering. 2019-11-12 20:08:49 -08:00
Xuchen Han
2edd94c722 add option to approximate face contact with collision quadrature points 2019-11-12 17:10:39 -08:00
Xuchen Han
42b5c93bad approximate face contact WIP 2019-11-12 11:50:47 -08:00
Xuchen Han
794614f269 change collision detection between deformables to from continuous to discrete 2019-11-11 13:58:03 -08:00
erwincoumans
b25d806b14 Merge pull request #2475 from xhan0619/fix-issue-#2473
Fix issue #2473
2019-11-08 20:45:05 -08:00
erwincoumans
886895e0bd Merge pull request #2478 from xhan0619/fix-pd
fix the bug that prevents the pd control forces/torques being added
2019-11-08 20:44:17 -08:00
erwincoumans
a2e7c772cf Merge pull request #2477 from erwincoumans/master
fix colors in URDF file
2019-11-08 17:32:32 -08:00
Xuchen Han
362bc6d9a3 fix the bug that prevents the pd control forces/torques being added 2019-11-08 17:08:59 -08:00
Erwin Coumans
bbf983bfbb reserve faces (minor performance improvement?) 2019-11-08 16:10:05 -08:00
Erwin Coumans
e9117dc195 fix colors in URDF file 2019-11-08 14:28:11 -08:00
Xuchen Han
059e23d381 fix old soft body collision issue #2473 2019-11-07 13:00:13 -08:00
Xuchen Han
baa9dcdf08 move erp for deformable into a separate parameter 2019-11-07 12:13:51 -08:00
erwincoumans
e66982d658 Merge pull request #2472 from erwincoumans/master
fix issue in BulletClient (pybullet_utils.bullet_client) that may dis…
2019-11-07 11:50:53 -08:00
Erwin Coumans
9f44d76b67 fix issue in BulletClient (pybullet_utils.bullet_client) that may disconnect multiple times, causing issues when repeatedly creating a gym env
bump up pybullet to version 2.5.7
2019-11-07 10:47:56 -08:00
erwincoumans
0cdddb874c Merge pull request #2461 from aaronfranke/seperate-typo
Fix "seperate" typos
2019-11-06 14:26:06 -08:00
erwincoumans
35c028880d Merge pull request #2465 from erwincoumans/master
add simple sceneAABB example
2019-11-06 14:23:38 -08:00
erwincoumans
d6dbc9d3ca Merge pull request #2467 from xhan0619/split-impulse
Split impulse
2019-11-06 14:23:26 -08:00
erwincoumans
2f9d7be172 Merge pull request #2468 from xhan0619/fix-sleep
Fix sleep
2019-11-06 12:07:20 -08:00
Xuchen Han
9068b7ed91 turn off SVD 2019-11-05 18:16:13 -08:00
Xuchen Han
b55ebac2d9 update CMakeLists 2019-11-05 18:09:38 -08:00
Xuchen Han
13314360a8 add option for deformable rigid split impulse 2019-11-05 18:07:58 -08:00
Xuchen Han
fb85b2e05f add a linear elasticity model 2019-11-05 18:07:58 -08:00
Chuyuan Fu
09ca930ca8 make consistent for other models 2019-11-05 18:07:58 -08:00
Chuyuan Fu
05bc387081 update example to use absolute path 2019-11-05 18:07:58 -08:00
Erwin Coumans
b5715c96cf Merge branch 'master' of https://github.com/erwincoumans/bullet3 2019-11-04 15:46:23 -08:00
Erwin Coumans
f1f04aef53 add simple sceneAABB example 2019-11-04 15:45:58 -08:00
Xuchen Han
4347c03459 turn on SVD and use fewer CG iterations 2019-11-03 12:47:08 -08:00
Xuchen Han
1bd0eee0ff fix indexing bug in deformable sleeping 2019-11-03 12:44:45 -08:00
Xuchen Han
457ed0e735 Merge pull request #3 from fuchuyuan/pathfix
update example to use absolute path
2019-10-31 15:15:38 -07:00
erwincoumans
aac7370179 Merge pull request #2462 from xhan0619/master
Deformable Improvement
2019-10-31 15:13:21 -07:00
Chuyuan Fu
7f310e6124 make consistent for other models 2019-10-31 15:07:10 -07:00
Chuyuan Fu
36a2f306f6 update example to use absolute path 2019-10-31 14:31:51 -07:00
Xuchen Han
93835c195b turn off SVD 2019-10-31 12:57:19 -07:00
Xuchen Han
3f1e061966 turn on SVD 2019-10-31 12:53:12 -07:00
Xuchen Han
9ebbab959c use safenorm 2019-10-31 12:53:12 -07:00
Xuchen Han
ec1ef0c465 add strain limiting to face contact to improve stability 2019-10-31 12:53:12 -07:00
Chuyuan Fu
41eb074406 avoid dividing by 0 2019-10-31 12:53:12 -07:00
Chuyuan Fu
ae7c3e0dee compute COM taking non-uniform model into account 2019-10-31 12:53:12 -07:00
Chuyuan Fu
74571d79e7 add compute softbody com 2019-10-31 12:53:12 -07:00
Chuyuan Fu
618c85325c give softbody name 2019-10-31 12:53:12 -07:00
Aaron Franke
133fd3a73c Fix "seperate" typos 2019-10-31 08:29:09 -04:00
sjdrc
f78a72ec64 Update bullet.pc.cmake
Change pkgconfig file to match example in pkg-config man files
2019-10-31 13:53:00 +11:00
erwincoumans
bda04cf904 Merge pull request #2459 from erwincoumans/master
bump up to Bullet version 2.89 and update serialization structures
2019-10-30 13:14:49 -07:00
erwincoumans
a1cb87cdb6 Merge pull request #2424 from grdowns/vcpkg-instructions
Add vcpkg installation instructions
2019-10-30 12:26:27 -07:00
Erwin Coumans
b2732b16be Merge remote-tracking branch 'bp/master' 2019-10-30 10:32:58 -07:00
Erwin Coumans
5a9b862ef5 bump up to Bullet version 2.89 and update serialization structures 2019-10-30 10:32:14 -07:00
erwincoumans
8aa7f93bf1 Merge pull request #2448 from fuchuyuan/mergechange
merge warmstart
2019-10-30 10:31:43 -07:00
erwincoumans
8e245d959e Merge pull request #2458 from xhan0619/cull-SVD
cull out most of the SVD calculation when stress is low
2019-10-30 08:31:54 -07:00
Xuchen Han
6dce8e4ff5 cull out most of the SVD calculation when stress is low 2019-10-29 22:39:10 -07:00
erwincoumans
959a48a1a0 Merge pull request #2454 from krishpop/patch-1
Fix call to convert_to_leg_model
2019-10-29 21:16:01 -07:00
erwincoumans
501d1acea9 Merge pull request #2457 from erwincoumans/master
return a value in a degenerate svd case
2019-10-29 21:13:59 -07:00
Erwin Coumans
938ac51da7 return a value in a degenerate svd case
re-disable svd by default
2019-10-29 20:40:57 -07:00
erwincoumans
7acbb77535 Merge pull request #2456 from erwincoumans/master
use mult instead of max to combine friction properties in deformable, add epsilon checks to avoid nan, termination condition if count > max_count (100)
2019-10-29 20:15:37 -07:00
Erwin Coumans
7bffbb2351 add check against FLT_EPSILON/DBL_EPSILON for sqrt and division to avoid nan.
add max_iterations count in svd as safety termination condition
2019-10-29 18:28:30 -07:00
Krishnan Srinivasan
0d4108f307 Fix call to convert_to_leg_model
Fix call to convert_to_leg_model which is defined as a static method without an underscore in MinitaurExtendedEnv
2019-10-29 16:00:55 -07:00
Erwin Coumans
136607151e use mult instead of max to combine friction properties
use 0.5 friction for ground for a demo, and also a larger grid size
update description of deformable algorithm
disable SVD for now, has some issue with some compilers
2019-10-28 12:53:59 -07:00
Erwin Coumans
574c240fbc Merge branch 'master' of https://github.com/erwincoumans/bullet3 2019-10-28 10:07:50 -07:00
Erwin Coumans
3f3175e314 disable Extras BulletRobotics by default in cmake 2019-10-28 10:07:22 -07:00
erwincoumans
74b173c30d Merge pull request #2449 from xhan0619/fix-deformable-performance
Fix deformable performance
2019-10-24 17:54:48 -07:00
Chuyuan Fu
404e4b9187 align multibody warmstart default value with rigidbody 2019-10-24 15:53:18 -07:00
Xuchen Han
23dbea16f3 initialize m_useSelfCollision 2019-10-24 15:28:21 -07:00
Xuchen Han
270028363b Fix some performance issues caused by unneccessarily small sdf grid size. 2019-10-24 15:03:23 -07:00
Chuyuan Fu
8c3ddac521 restore default behavior
take out condition
2019-10-23 21:36:26 -07:00
Chuyuan Fu
913400eba1 add SOLVER_USE_ARTICULATED_WARMSTARTING option and APIs
fix compile
2019-10-23 21:36:26 -07:00
Chuyuan Fu
ac680be673 fix space 2019-10-23 21:36:08 -07:00
Chuyuan Fu
08f53fc38d add warmstart 2019-10-23 21:36:08 -07:00
erwincoumans
e4ba8be582 Merge pull request #2447 from xhan0619/fix-cloth-friction
fix bug in deformable vs. deformable friction
2019-10-23 19:31:12 -07:00
Xuchen Han
c6af3aa3f8 fix bug in deformable vs. deformable friction 2019-10-23 12:17:21 -07:00
erwincoumans
9e72e01dad Merge pull request #2438 from MarkSakharov/fix/division_by_zero
Fixing division by zero
2019-10-19 17:39:32 -04:00
erwincoumans
fe79395d39 Merge pull request #2430 from xhan0619/master
Configure damping coefficients for neohookean models
2019-10-19 17:35:48 -04:00
Mark S
88e4ca1970 Update btBatchedConstraints.cpp
btVector3 constructor added.
2019-10-19 02:34:45 +03:00
Xuchen Han
36f7441790 support anchor constraint between deformable and multibody 2019-10-17 16:45:28 -07:00
Xuchen Han
60dfe1fe69 add support for anchor constraint between deformable and rigid 2019-10-16 19:23:01 -07:00
Mark Sakharov
95fd362857 Fixing division by zero 2019-10-16 23:36:02 +03:00
Xuchen Han
3d622a3bee enable deformable sleeping 2019-10-16 12:00:02 -07:00
Xuchen Han
3ae193ff15 bool->int 2019-10-15 15:43:26 -07:00
Xuchen Han
774937bcd6 add option to turn face contact on/off 2019-10-15 13:53:27 -07:00
Xuchen Han
05c25a27de address comment from ldowns 2019-10-15 13:51:33 -07:00
Xuchen Han
a1afc66817 remove std::fabs and std::max 2019-10-15 13:51:33 -07:00
Xuchen Han
30238b2fbc remove std::copysign 2019-10-15 13:51:33 -07:00
Xuchen Han
a7222d8a9f add option to set stress clamping limit 2019-10-15 13:51:33 -07:00
Xuchen Han
9e29f7108d remove Eigen 2019-10-15 13:50:13 -07:00
Xuchen Han
9546390fd6 clamp stress for NeoHookean in singular value space 2019-10-15 13:50:13 -07:00
Xuchen Han
e87df18544 switch to damping model from Irvine 05 for its SPDness 2019-10-15 13:50:13 -07:00
Xuchen Han
87546bb7c3 prevent velocity of deformable from getting too big from explicit force 2019-10-15 13:50:13 -07:00
Xuchen Han
45c4497711 fix compile 2019-10-15 13:50:13 -07:00
Xuchen Han
0d742273c1 set default drag coefficient to 0 2019-10-15 13:50:13 -07:00
Xuchen Han
992e1454b6 turn on SKIP_DEFORMABLE 2019-10-15 13:50:13 -07:00
Xuchen Han
25a566c378 finish deformable sleeping and add option for drag 2019-10-15 13:50:13 -07:00
Xuchen Han
0d7ff567e6 bug fix in deformable predict motion 2019-10-15 13:50:13 -07:00
Xuchen Han
c808bb78c7 delete lagrangian force when deleting dynamics world from command processor 2019-10-15 13:50:13 -07:00
Xuchen Han
58a67f82fb set default integration scheme to explicit 2019-10-15 13:50:13 -07:00
Xuchen Han
94facf0029 typo fix 2019-10-15 13:50:13 -07:00
Xuchen Han
ca92cf067e fix removeCollisionObject for Deformable world 2019-10-15 13:50:12 -07:00
Xuchen Han
3b945597d1 prevent narrow phase collision detection between rigid and soft when both are sleeping 2019-10-15 13:50:12 -07:00
Xuchen Han
c610ba49df fix bug in computing rhs in momentum solve 2019-10-15 13:47:55 -07:00
Xuchen Han
0cb7cb2445 bool->int 2019-10-15 13:47:55 -07:00
Xuchen Han
e13578fee3 add option to turn self-collision on/off 2019-10-15 13:47:55 -07:00
Xuchen Han
4220c7f94c tune CG tolerance 2019-10-15 13:47:54 -07:00
Xuchen Han
d0e4bbf04d fix gravity set up 2019-10-15 13:47:54 -07:00
Xuchen Han
ec91a0ffa4 configure damping coefficients for neohookean models 2019-10-15 13:47:54 -07:00
erwincoumans
837e333ab2 Merge pull request #2432 from erwincoumans/master
bump PyBullet version, fix mac osx compilation, suppress debug warning, fix slow full matrix multiply (unused)
2019-10-10 09:44:27 -04:00
Erwin Coumans
31e778c913 avoid crashes in TinyRenderer 2019-10-09 22:26:20 -04:00
Erwin Coumans
3a4159c793 fix slow full btMatrixX operator* (was not used) 2019-10-08 19:31:58 -07:00
Erwin Coumans
2caf4505f0 pybullet: suppress debug printf (obj texture coordinate out-of-range) 2019-10-03 09:25:54 -07:00
Erwin Coumans
9a6c6a3fb4 Merge remote-tracking branch 'bp/master' 2019-10-02 22:39:51 -07:00
erwincoumans
3d87fb3b84 Merge pull request #2426 from xhan0619/faceContact
Face contact
2019-10-02 08:33:12 -07:00
Xuchen Han
5a55374d85 pass render nodes instead of simulated nodes to renderer 2019-10-01 14:48:34 -07:00
Xuchen Han
96bf2f2ff5 address PR comments 2019-10-01 14:47:49 -07:00
Erwin Coumans
b6e5609f90 fix mac osx compilation 2019-09-30 14:08:22 -07:00
Erwin Coumans
0d948a2c56 Merge remote-tracking branch 'bp/master' 2019-09-30 09:10:45 -07:00
Erwin Coumans
1d123b6ceb bump up PyBullet version to 2.5.6 2019-09-30 09:09:26 -07:00
Xuchen Han
187019268c enable deformable vs. deformable and self-collision in deformable loading 2019-09-28 15:10:06 -07:00
Xuchen Han
2d045de589 parameter change in ClothFriction Demo 2019-09-28 14:44:42 -07:00
Xuchen Han
132f7fe751 update pybullet binding 2019-09-28 14:44:42 -07:00
Xuchen Han
212b990b0e remove auto and add include 2019-09-28 14:44:42 -07:00
Xuchen Han
9f11ac5d4d add include 2019-09-28 14:44:42 -07:00
Xuchen Han
11ad0f0dfd add btMatrix3x3 constructor from vectors 2019-09-28 14:44:42 -07:00
Xuchen Han
c178905998 remove siData 2019-09-28 14:44:42 -07:00
Xuchen Han
ccaddfca21 documentation and optimization 2019-09-28 14:44:42 -07:00
Xuchen Han
a0acfd5195 code clean up and optimization 2019-09-28 14:44:42 -07:00
Chuyuan Fu
cd27ffd8b0 add body type info to dynamics info 2019-09-28 14:44:42 -07:00
Xuchen Han
977bdb4e0e adjust parameters 2019-09-28 14:44:41 -07:00
Xuchen Han
cb46440e17 add normal cone optimization for self-collision 2019-09-28 14:44:41 -07:00
Xuchen Han
657a7468b3 documentation and optimization 2019-09-28 14:44:41 -07:00
Xuchen Han
20abbc9ee7 add dynamic friction for deformable contact 2019-09-28 14:44:41 -07:00
Xuchen Han
416e516735 add naive implementation of self collision 2019-09-28 14:44:41 -07:00
Xuchen Han
be7383cc03 update examples to test different time stepping schemes (namely explicit, implicit and implicit with line search)/ 2019-09-28 14:44:41 -07:00
Xuchen Han
2f9184acc9 remove position correction 2019-09-28 14:44:41 -07:00
Xuchen Han
ef5aa6e73b add options to toggle between whether line search is used & add more documentation 2019-09-28 14:44:41 -07:00
Xuchen Han
0501fe1bbd add cloth demo to show deformable friction 2019-09-28 14:44:41 -07:00
Xuchen Han
55ebafc755 add demo to test soft body friction 2019-09-28 14:44:41 -07:00
Xuchen Han
cca220eb27 add damping energy to mass spring 2019-09-28 14:44:41 -07:00
Xuchen Han
d761b2cd68 add some documentation 2019-09-28 14:44:41 -07:00
Xuchen Han
ae42cc561e add damping energy in line search 2019-09-28 14:44:41 -07:00
Xuchen Han
3dcfcda19a typo fix 2019-09-28 14:44:41 -07:00
Xuchen Han
a92a8f1135 add demo for deformable contact 2019-09-28 14:44:41 -07:00
Xuchen Han
1bfb226be8 add support for deformable vs. deformable contact 2019-09-28 14:44:41 -07:00
Xuchen Han
403eb62dfa code clean up and optimization 2019-09-28 14:44:41 -07:00
Xuchen Han
109d9353af switched to deformable rigid contact from Jacobi to Gauss Seidel 2019-09-28 14:44:41 -07:00
Xuchen Han
f99cf56149 finished refactoring; start adding face contact 2019-09-28 14:44:41 -07:00
Xuchen Han
f813cb1c88 modify loadSoftBody to enable separate render mesh from simulation mesh 2019-09-28 14:44:41 -07:00
Xuchen Han
1bc75cc833 add relative tolerance for linear solver and newton with line search 2019-09-28 14:43:40 -07:00
Xuchen Han
36278edc00 add back preTickCallback & disable position Correction for more stability 2019-09-28 14:43:40 -07:00
Xuchen Han
acfcc3fc9a updates to interpolation for rendering mesh 2019-09-28 14:43:40 -07:00
Chuyuan Fu
e74ffa2f65 add body type info to dynamics info 2019-09-28 14:43:40 -07:00
Xuchen Han
27bf4d3372 new vtk mesh 2019-09-28 14:43:40 -07:00
Xuchen Han
a47eeb8225 add render mesh interpolation from simulation mesh 2019-09-28 14:43:40 -07:00
Xuchen Han
1febf8d612 change CG tolerance criterion 2019-09-28 14:43:40 -07:00
erwincoumans
3a29b1c32d Merge pull request #2421 from erwincoumans/master
fix use of uninitialized variable
2019-09-27 17:15:41 -07:00
Erwin Coumans
0549fd4ecc PyBullet eglPlugin:
use -1 as default egl render device
clear m_cachedVisualShapes at reset
2019-09-27 17:14:36 -07:00
grdowns
e7cf32acfd Add vcpkg installation instructions 2019-09-27 01:08:15 -07:00
Erwin Coumans
391411b660 fix use of uninitialized variable 2019-09-25 13:49:11 -07:00
erwincoumans
65af42d1ce Merge pull request #2420 from erwincoumans/master
fix define SKIP_DEFORMABE_BODY -> SKIP_DEFORMABLE_BODY 677fe1a
2019-09-25 19:11:00 +02:00
Erwin Coumans
2e5455def1 Merge branch 'master' of https://github.com/erwincoumans/bullet3 2019-09-25 09:10:44 -07:00
Erwin Coumans
677fe1a368 fix define SKIP_DEFORMABE_BODY -> SKIP_DEFORMABLE_BODY 2019-09-25 09:08:48 -07:00
erwincoumans
34b322b7fc Merge pull request #2419 from erwincoumans/master
remove 'disableVRCamera' to fix issue #2390
2019-09-24 17:52:51 -07:00
Erwin Coumans
bdf24bd4e7 Merge branch 'master' of https://github.com/erwincoumans/bullet3 2019-09-24 13:43:20 -07:00
Erwin Coumans
32c38cd3dc remove 'disableVRCamera' to fix issue #2390 2019-09-24 13:42:45 -07:00
erwincoumans
ce28bd5369 Merge pull request #2408 from erwincoumans/master
fix compile issues
2019-09-13 20:02:26 -07:00
Erwin Coumans
275a2aecb0 fix compile issues 2019-09-13 09:37:23 -07:00
erwincoumans
8ad4afad70 Merge pull request #2407 from erwincoumans/master
fix multithreaded solver
2019-09-13 07:39:05 -07:00
Erwin Coumans
95a7488310 PyBullet: fix createMultiBodyBatch.py example 2019-09-13 07:38:00 -07:00
Erwin Coumans
b86bf6c571 remove BlockSolver/* 2019-09-11 10:20:37 -07:00
Erwin Coumans
25c61a40b5 remove BlockSolver/* 2019-09-11 10:19:43 -07:00
Erwin Coumans
dee463eaae Merge branch 'master' of https://github.com/erwincoumans/bullet3 2019-09-11 08:39:11 -07:00
Erwin Coumans
93810cb09a revert constraint solver changes to allow block solver, since it breaks the multithreaded solver.
(re-enable if/when we can redo those changes without breaking multithreading)
2019-09-11 08:39:05 -07:00
erwincoumans
66fc3a9ce9 Update btDeformableGravityForce.h 2019-09-09 20:42:21 -07:00
erwincoumans
0d4db1a6f2 Update btDeformableMassSpringForce.h 2019-09-09 20:41:42 -07:00
erwincoumans
0722400f33 Update btConjugateGradient.h
add ; to btAssert
2019-09-09 20:39:53 -07:00
erwincoumans
80f12f8886 Merge pull request #2404 from erwincoumans/master
fix issues in previous softbody commits (always check for m_multibodyWorld == 0 before using the pointer in ::render method)
2019-09-09 19:17:50 -07:00
Erwin Coumans
db9bc4f835 PyBullet: write body sync data to larger shared memory 2019-09-09 18:05:29 -07:00
Erwin Coumans
64ea8e9f27 PyBullet createMultiBody(Batch), return all body unique ids
PyBullet: fix crash: always check for existance m_multibodyWorld in ::render method
2019-09-09 16:41:25 -07:00
Erwin Coumans
5a3c60c709 PyBullet: Fix syncBodyInfo for over 512 bodies.
PyBullet: Fix issue related to recent change in drawDebugDrawerLines (soft body)
2019-09-09 14:56:26 -07:00
erwincoumans
33260e9406 Merge pull request #2402 from erwincoumans/master
disable warmstarting for friction (btRigidBody) since friction direct…
2019-09-07 08:54:46 -07:00
Erwin Coumans
4515fcbfaf disable warmstarting for friction (btRigidBody) since friction directions are changing it can cause artifacts. 2019-09-06 21:22:14 -07:00
erwincoumans
bcc7ea31ff Merge pull request #2386 from xhan0619/newton
Newton solver
2019-09-06 10:32:59 -07:00
erwincoumans
bb25634af9 Merge pull request #2398 from erwincoumans/master
fix asan int overflow in hash
2019-09-06 10:32:32 -07:00
Erwin Coumans
74abd99192 fix asan int overflow in hash 2019-09-05 17:42:18 -07:00
Xuchen Han
899bf9afd1 update setup.py 2019-09-04 18:55:16 -07:00
Xuchen Han
d5afccf3f1 update CMakeLists 2019-09-04 18:49:44 -07:00
Xuchen Han
1965f46959 update CMakeLists 2019-09-04 18:49:44 -07:00
Xuchen Han
1ded85e62e remove extra gravity field 2019-09-04 18:49:44 -07:00
Xuchen Han
3d2f945f9c address PR comments 2019-09-04 18:49:44 -07:00
Xuchen Han
8a08e32f51 update CMakeLists 2019-09-04 18:49:43 -07:00
Xuchen Han
5330396c70 enabled mass preconditioner 2019-09-04 18:49:43 -07:00
Xuchen Han
f392d8ceb1 clean up memory when exiting 2019-09-04 18:49:43 -07:00
Xuchen Han
ca3e25d4e2 add Rayleigh damping for NeoHookean 2019-09-04 18:49:43 -07:00
Xuchen Han
e124c62a70 each node only allows a single contact; initial guess for newton set to x = x_n + dt*v_n 2019-09-04 18:49:43 -07:00
Xuchen Han
482458c9df improve deformable objects loading 2019-09-04 18:49:43 -07:00
Xuchen Han
7d1b93cc17 contact solve for newton 2019-09-04 18:48:00 -07:00
Xuchen Han
5826492020 add elastic force differential for mass spring 2019-09-04 18:48:00 -07:00
Xuchen Han
d4a15e016e add newton solver 2019-09-04 18:48:00 -07:00
Xuchen Han
c722630fc7 bug fix in neohookean force 2019-09-04 18:48:00 -07:00
Xuchen Han
e73f70efa2 swap m_x and m_q in softbody to align with rendering convention 2019-09-04 18:48:00 -07:00
Xuchen Han
7c39052163 clean up forces 2019-09-04 18:48:00 -07:00
Xuchen Han
0b391798b7 hook deformable world into the physics server 2019-09-04 18:48:00 -07:00
erwincoumans
9cf50846d6 Merge pull request #2393 from muupan/fix-typo-duration
Fix typo: s/duraction/duration/g
2019-09-04 09:37:57 -07:00
erwincoumans
85ba3ba957 Merge pull request #2396 from fuchuyuan/bodytypeAPI
Add body type to dynamics info
2019-09-04 09:37:31 -07:00
erwincoumans
6b95d12dc6 Merge pull request #2397 from mbreyer/fix-leak-in-state-restore
Fix memory leak in RestoreState
2019-09-04 08:31:20 -07:00
Michel Breyer
c374d01587 Deallocate importer in RestoreState 2019-09-04 13:10:34 +02:00
Chuyuan Fu
ecc28d6472 revert testing example 2019-09-03 14:35:33 -07:00
Chuyuan Fu
e4a5f9e06e add body type info to dynamics info 2019-09-03 14:27:19 -07:00
muupan
4c209a4834 Fix typo: s/duraction/duration/g 2019-09-03 17:29:43 +09:00
erwincoumans
25cc1fa386 Merge pull request #2373 from xhan0619/DeformableImprovement
Deformable improvement
2019-08-24 18:09:47 -07:00
erwincoumans
ceee3e075b Merge pull request #2377 from bulletphysics/erwincoumans-patch-7
Update PhysicsServerCommandProcessor.cpp
2019-08-24 17:13:44 -07:00
Xuchen Han
908cf69f06 change deformable/multibody solve to be in dv space 2019-08-24 14:58:11 -07:00
Xuchen Han
8b38076376 update license 2019-08-24 12:44:58 -07:00
Xuchen Han
b0a91bb306 float->btScalar 2019-08-24 11:55:34 -07:00
Xuchen Han
bb4a554e68 bug fix in multibody interpolation world transform: update cached rotation and vector 2019-08-24 11:51:33 -07:00
Xuchen Han
f2d8ed71ac float->btScalar 2019-08-23 20:06:41 -07:00
Xuchen Han
6beeac7065 refactor contact solve 2019-08-23 17:32:41 -07:00
Xuchen Han
ccd8c3a47c fix scope override in btMultiBody and scalar type inconsistency in btDeformableBodySolver 2019-08-22 10:12:14 -07:00
erwincoumans
64097c9eec Merge pull request #2375 from bulletphysics/erwincoumans-patch-6
Update btMultiBodyConstraintSolver.cpp (markup for clangtidy)
2019-08-22 07:47:44 -07:00
erwincoumans
9a7b89c95a Update PhysicsServerCommandProcessor.cpp
also allow to extract collision info (pybullet. getCollisionShapeData ) for concave meshes. Thanks to Brent.
2019-08-22 07:38:23 -07:00
Xuchen Han
3fbd7a7edd delete forces in exitPhysics 2019-08-21 23:00:18 -07:00
Xuchen Han
b93c3c56ed delete preconditioner in destructor 2019-08-21 22:44:10 -07:00
Xuchen Han
750ff33f26 remove the std::istream version of vtkfileread 2019-08-21 22:39:07 -07:00
Xuchen Han
4df31305a8 remove iostream dependency 2019-08-21 22:31:30 -07:00
Xuchen Han
75d0cfaf69 restore default voxelsz and add option to change voxelsz 2019-08-21 22:29:53 -07:00
Xuchen Han
4e1c1a30a7 remove world dependency from btDeformableBodySolver,btDeformableBackwardEulerObjective, and btCGProjection; reduce invasion into multibody world, all chnages are cosmetic now 2019-08-21 22:17:46 -07:00
Xuchen Han
f33532273a sync interpolationTransform for multibody in integrateTransform; revert changes to voxel size in sparseSDF 2019-08-21 16:03:54 -07:00
Xuchen Han
076c8b11df revert the changes to damping of multibody external forces 2019-08-20 18:13:38 -07:00
Xuchen Han
fadf6aa612 prevent division by zero in mass spring 2019-08-20 16:26:19 -07:00
Xuchen Han
7e971d9f63 safe guard against NaN in dv after CG solve 2019-08-20 11:12:36 -07:00
Xuchen Han
76d37ec475 bug fix in updateDeformation 2019-08-20 10:37:25 -07:00
erwincoumans
3d42a770fc Update btMultiBodyConstraintSolver.cpp 2019-08-20 07:29:49 -07:00
Xuchen Han
3bf3b66fb7 add method to remove softbody 2019-08-19 19:18:02 -07:00
Xuchen Han
ef65d6422b remove CG printf outputs 2019-08-19 17:28:22 -07:00
Xuchen Han
5cdfbf3313 add CMakeLists 2019-08-19 13:09:14 -07:00
Xuchen Han
9f559af2a8 set m_contact_iterations to solverInfo.m_solverIterations 2019-08-19 13:07:26 -07:00
Xuchen Han
9af25430ac update examples to include NeoHookean Model and new damping model 2019-08-19 12:04:10 -07:00
Xuchen Han
44e7c4a96d add stable NeoHookean Model 2019-08-19 12:03:45 -07:00
Xuchen Han
04595961cd add velocity clamp to prevent deformable objects from going too fast 2019-08-19 12:02:57 -07:00
Xuchen Han
54bd93aad2 move deformation update to before explicit force calculation to prevent repetition of F calculation 2019-08-19 11:30:25 -07:00
Xuchen Han
74adce7322 bug fix in momentum conserving damping model for mass spring; update default damping model to momentum conserving one 2019-08-19 11:28:41 -07:00
Xuchen Han
6d4e93d3bf mods for compatibility with older compiler 2019-08-16 14:03:14 -07:00
Xuchen Han
bf215a3ce1 rename btDeformableRigidDynamicsWorld to btDeformableMultiBodyDynamicsWorld 2019-08-16 13:45:30 -07:00
Xuchen Han
8860f8bacc remove unused functions 2019-08-16 13:45:30 -07:00
Xuchen Han
86a1312875 add author info 2019-08-16 13:45:30 -07:00
Xuchen Han
c9ab033a8b check in a good set of parameters for grasping deformable ball with nonlinear damping force (not as stable as linear damping) 2019-08-16 13:45:30 -07:00
Xuchen Han
aa4d5bda3e add elastic and damping stiffness of spring into the force class 2019-08-16 13:45:29 -07:00
Xuchen Han
df7f216bf8 fix bugs introduced in merging 2019-08-16 13:45:29 -07:00
Xuchen Han
10cb0c368d solve CG with more accuracy 2019-08-16 13:45:29 -07:00
Xuchen Han
23cf657a1a change voxel size in sparseSDF to handle contact with smaller objects 2019-08-16 13:45:29 -07:00
Xuchen Han
b507fe77ca check in a good set of parameters for grasping deformable ball 2019-08-16 13:45:29 -07:00
Xuchen Han
f8c60e9e3c add option for angular momentum conserving damping for mass spring 2019-08-16 13:45:29 -07:00
Xuchen Han
bedaa760c2 speed up corotated force computation 2019-08-16 13:45:29 -07:00
Xuchen Han
fce1296413 fix the issue that compound objects's child does not get rotated in the material space in interpolationWorldTransform 2019-08-16 13:45:29 -07:00
Xuchen Han
07bf736aeb build islands once and process islands arbitrary number of times in update constraints 2019-08-16 13:45:29 -07:00
Xuchen Han
9e6e571732 add options to perturb the softbody patch's initial position 2019-08-16 13:45:29 -07:00
Xuchen Han
cfbd6c512a fix bug introduced in clearing m_manifold; 7e37d3fd21069571adb4c1e4ffacbd71dd02c0ba 2019-08-16 13:45:29 -07:00
Xuchen Han
081497a812 reset dt to 1/240 for grasping demos 2019-08-16 13:45:29 -07:00
Xuchen Han
991be52681 add more volumetric meshes for grasping tests 2019-08-16 13:45:29 -07:00
Xuchen Han
cb7257d27b add reader to create softbodies from vtk files 2019-08-16 13:45:29 -07:00
Xuchen Han
f7cd1edf4a code clean up 2019-08-16 13:45:29 -07:00
Xuchen Han
fa5741d07e improve dynamic friction 2019-08-16 13:45:29 -07:00
Xuchen Han
fb6612c0be friction fixes 2019-08-16 13:45:08 -07:00
Xuchen Han
5b8df6a708 switch to Baraff style constraint 2019-08-16 13:45:08 -07:00
Xuchen Han
27492887bf move files and update license 2019-08-16 13:45:08 -07:00
Xuchen Han
26983b05e2 modify constraint setup so that contact constraints are persistent in a single CG solve but motor constraints are applied only once 2019-08-16 13:45:05 -07:00
Xuchen Han
deb7c152c4 add corotated model to lagrangian forces 2019-08-16 13:45:05 -07:00
Xuchen Han
94aeb4657b add comment and initialization 2019-08-16 13:45:05 -07:00
Xuchen Han
10e819db8e add grasping with joint motor example 2019-08-16 13:45:05 -07:00
Xuchen Han
6d31c73216 style fix and remove unused variable 2019-08-16 13:44:59 -07:00
erwincoumans
cb654ddc80 Merge pull request #2367 from erwincoumans/master
allow to update heightfield, see PyBullet: allow to update an existing heightfield shape Also, use flags = p.GEOM_CONCAVE_INTERNAL_EDGE to enable internal edge filtering for heightfield (disabled by default) See https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/heightfield.py
2019-08-14 21:47:45 -07:00
Erwin Coumans
648844e898 minor fixes, bump up pybullet to 2.5.5 2019-08-14 21:30:10 -07:00
Erwin Coumans
f09cefabe8 Merge remote-tracking branch 'bp/master' 2019-08-14 21:14:56 -07:00
erwincoumans
6feb1b25db Merge pull request #2365 from fuchuyuan/updateLoadingSoftBody
update loading softbody
2019-08-14 21:14:10 -07:00
erwincoumans
7fa70c3857 Merge pull request #2351 from xhan0619/Deformable
Add deformable body world and solver
2019-08-14 21:13:41 -07:00
Erwin Coumans
88d1788ee5 PyBullet: allow to update an existing heightfield shape
Also, use flags = p.GEOM_CONCAVE_INTERNAL_EDGE to enable internal edge filtering for heightfield (disabled by default)
See https://github.com/bulletphysics/bullet3/blob/master/examples/pybullet/examples/heightfield.py
2019-08-14 21:06:10 -07:00
erwincoumans
75df77611a Merge pull request #2366 from fuchuyuan/tinyObjUpdate
update obj loader
2019-08-14 13:37:14 -07:00
Chuyuan Fu
eacebc80d5 fix compile 2019-08-14 11:01:48 -07:00
Chuyuan Fu
10108cd3ea update obj loader 2019-08-13 16:53:51 -07:00
Chuyuan Fu
b90097803e update loading softbody 2019-08-13 14:56:26 -07:00
Xuchen Han
69a02302aa fix gripper in pinch example 2019-08-10 12:12:59 -07:00
Xuchen Han
12653f9f19 add back files accidentally removed 2019-08-09 10:14:35 -07:00
Xuchen Han
7adb6fdff3 2016 -> 2019 2019-08-08 17:43:49 -07:00
Xuchen Han
817e64a769 remove one softbody array copy 2019-08-08 17:31:59 -07:00
Xuchen Han
436b6c6963 separate multibody position prediction into standalone function 2019-08-08 17:14:13 -07:00
Xuchen Han
96e8dcef0f fix bug caused by not reseting to zero 2019-08-08 16:45:19 -07:00
Xuchen Han
9a7e30d09f move deformable examples to a single folder and rename them; change license to google 2016 2019-08-08 15:00:55 -07:00
Xuchen Han
02c5b99b2f add algorithm overview 2019-08-06 11:42:48 -07:00
Xuchen Han
e5231b5cc5 restore behaviors of btSoftBody 2019-08-06 10:52:19 -07:00
Xuchen Han
6a599bde87 setDt in reinitialize and remove unused variables 2019-08-06 10:16:56 -07:00
Xuchen Han
73f5eb6a8f add profiling and code clean up 2019-08-05 16:49:04 -07:00
Xuchen Han
02d3a9469f code clean up + Zlib copyright header 2019-08-05 11:54:17 -07:00
Xuchen Han
c5d84c1a0b get rid of nullptr and std::function 2019-08-03 00:12:34 -07:00
Xuchen Han
021cbb2a0e include numeric_limits 2019-08-02 23:50:15 -07:00
Xuchen Han
8c04a78c9b switch from std::unordered_map to btHashMap 2019-08-02 23:26:11 -07:00
Xuchen Han
dae230912b typo fix 2019-08-02 15:51:38 -07:00
Xuchen Han
9a5ef6c849 update CMakeList 2019-08-02 15:41:10 -07:00
Xuchen Han
7f33d8cdb9 get rid of 'using' 2019-08-02 15:27:10 -07:00
Xuchen Han
f624b60c19 get rid of auto 2019-08-02 15:19:37 -07:00
Xuchen Han
753b2d9f15 add new demos to CMakeList 2019-08-02 15:02:15 -07:00
Xuchen Han
8cc7cb59d7 clean up examples 2019-08-02 14:06:42 -07:00
Xuchen Han
54303e02b1 perform position correction only when objects are penetrating 2019-08-02 13:21:06 -07:00
Xuchen Han
3dc8abcf36 only call buildIslands once for multibody in each timestep 2019-08-02 13:15:06 -07:00
Xuchen Han
f1e7ce9ce1 add multibody interpolation transform so that collision detection is consistent with rigidbody 2019-08-02 13:15:06 -07:00
Xuchen Han
ec403f790d factor out force; now btDeformableLagrangianceForce can be specified at configuration time and to specific softbody 2019-08-02 13:15:06 -07:00
Xuchen Han
233a381e7c add correct impulse matrix to multibody-deformable contact 2019-08-02 13:15:00 -07:00
Xuchen Han
243b9fc8c7 combat friction drift in positionCorrect by changing velocity and change it back (effectively only changing position) 2019-08-02 13:14:15 -07:00
Xuchen Han
a90cad2a96 deformable code refactor 2019-08-02 13:13:21 -07:00
Xuchen Han
dc10336d45 code clean up + check in examples 2019-08-02 13:12:59 -07:00
Xuchen Han
3430192db7 reformulate friction 2019-08-02 13:12:51 -07:00
Xuchen Han
7846dd38dd switch explicit elastic force 2019-08-02 13:12:51 -07:00
Xuchen Han
2fc376e8f5 bug fix in friction; accumulate friction impulses in cg; forbid switching from static to dynamic friction 2019-08-02 13:12:51 -07:00
Xuchen Han
befab4eab6 reorganize the contact constraints 2019-08-02 13:12:51 -07:00
Xuchen Han
bac7d461c5 fix bugs in poststablize and projection of colinear constraints 2019-08-02 13:12:51 -07:00
Xuchen Han
ac628f4d39 add two way coupled penetration resolution; not momentum conserving, but seem to work fine 2019-08-02 13:12:42 -07:00
Xuchen Han
98cd9a85e4 generalize preconditioner, now supports mass preconditioning 2019-08-02 13:12:41 -07:00
Xuchen Han
696c96f392 bug fix in projection; start friction 2019-08-02 13:12:41 -07:00
Xuchen Han
4e5f4b9fe9 reformulate how constraints are managed in the projection class 2019-08-02 13:12:41 -07:00
Xuchen Han
b28f1fdac3 add support for more than one constraint for a single deformable node 2019-08-02 13:12:41 -07:00
Xuchen Han
b7e512a5f9 sync gravity with substeps 2019-08-02 13:12:41 -07:00
Xuchen Han
77d670ae41 separate external force solve from constraint solve and eliminate damping in external force solve 2019-08-02 13:12:41 -07:00
Xuchen Han
c4e316f005 btDeformableRigidWorld now inherits from btMultiBodyDynamicsWorld instead of btSoftRigidDynamicsWorld 2019-08-02 13:12:41 -07:00
Xuchen Han
13d4e1cc2b bug fixes in constraints projections; cpplized various functions 2019-08-02 13:12:41 -07:00
Xuchen Han
786b0436ec fixed gravity issue in rigid body and deformable body contact solve 2019-08-02 13:12:27 -07:00
Xuchen Han
b8997c36b2 update contact projection 2019-08-02 13:10:56 -07:00
Xuchen Han
35ce2ae0e2 add contact constraint as projections in CG 2019-08-02 13:10:56 -07:00
Xuchen Han
32836b0694 set up deformable world and solver (does not support contact or friction yet) 2019-08-02 13:10:17 -07:00
370 changed files with 496645 additions and 22915 deletions

11
.gitignore vendored
View File

@@ -19,3 +19,14 @@ pip-selfcheck.json
/build
/dist
*.eggs
# CMake
CMakeFiles/
CMakeCache.txt
cmake_install.cmake
CTestTestFile.cmake
# Visual Studio build files
*.vcxproj
*.vcxproj.filters
*.sln

View File

@@ -55,7 +55,6 @@ IF(NOT WIN32)
ENDIF(NOT WIN32)
OPTION(USE_MSVC_INCREMENTAL_LINKING "Use MSVC Incremental Linking" OFF)
OPTION(USE_CUSTOM_VECTOR_MATH "Use custom vectormath library" OFF)
#statically linking VC++ isn't supported for WindowsPhone/WindowsStore
IF (CMAKE_SYSTEM_NAME STREQUAL WindowsPhone OR CMAKE_SYSTEM_NAME STREQUAL WindowsStore)

View File

@@ -290,7 +290,6 @@ IF (INSTALL_EXTRA_LIBS)
SET_TARGET_PROPERTIES(BulletRobotics PROPERTIES FRAMEWORK true)
SET_TARGET_PROPERTIES(BulletRobotics PROPERTIES PUBLIC_HEADER "PhysicsClientC_API.h" )
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
ENDIF (INSTALL_EXTRA_LIBS)
IF(NOT MSVC)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/bullet_robotics.pc.cmake
@@ -301,4 +300,6 @@ IF(NOT MSVC)
DESTINATION
${PKGCONFIG_INSTALL_PREFIX}
)
ENDIF(NOT MSVC)
ENDIF(NOT MSVC)
ENDIF (INSTALL_EXTRA_LIBS)

View File

@@ -176,7 +176,7 @@ public:
mHard[(int)c] = ST_DATA;
}
void DefaultSymbols(void); // set up default symbols for hard seperator and comment symbol of the '#' character.
void DefaultSymbols(void); // set up default symbols for hard separator and comment symbol of the '#' character.
bool EOS(char c)
{
@@ -197,7 +197,7 @@ private:
inline bool IsHard(char c);
inline char *SkipSpaces(char *foo);
inline bool IsWhiteSpace(char c);
inline bool IsNonSeparator(char c); // non seperator,neither hard nor soft
inline bool IsNonSeparator(char c); // non separator, neither hard nor soft
bool mMyAlloc; // whether or not *I* allocated the buffer and am responsible for deleting it.
char *mData; // ascii data to parse.

File diff suppressed because it is too large Load Diff

View File

@@ -77,9 +77,10 @@ int main(int argc, char* argv[])
b3FileUtils::extractPath(fileNameWithPath, materialPrefixPath, MAX_PATH_LEN);
std::vector<tinyobj::shape_t> shapes;
tinyobj::attrib_t attribute;
b3BulletDefaultFileIO fileIO;
std::string err = tinyobj::LoadObj(shapes, fileNameWithPath, materialPrefixPath,&fileIO);
std::string err = tinyobj::LoadObj(attribute, shapes, fileNameWithPath, materialPrefixPath,&fileIO);
char sdfFileName[MAX_PATH_LEN];
sprintf(sdfFileName, "%s%s.sdf", materialPrefixPath, "newsdf");
@@ -117,20 +118,20 @@ int main(int argc, char* argv[])
int curTexcoords = shapeC->texcoords.size() / 2;
int faceCount = shape.mesh.indices.size();
int vertexCount = shape.mesh.positions.size();
int vertexCount = attribute.vertices.size();
for (int v = 0; v < vertexCount; v++)
{
shapeC->positions.push_back(shape.mesh.positions[v]);
shapeC->positions.push_back(attribute.vertices[v]);
}
int numNormals = int(shape.mesh.normals.size());
int numNormals = int(attribute.normals.size());
for (int vn = 0; vn < numNormals; vn++)
{
shapeC->normals.push_back(shape.mesh.normals[vn]);
shapeC->normals.push_back(attribute.normals[vn]);
}
int numTexCoords = int(shape.mesh.texcoords.size());
int numTexCoords = int(attribute.texcoords.size());
for (int vt = 0; vt < numTexCoords; vt++)
{
shapeC->texcoords.push_back(shape.mesh.texcoords[vt]);
shapeC->texcoords.push_back(attribute.texcoords[vt]);
}
for (int face = 0; face < faceCount; face += 3)
@@ -140,9 +141,9 @@ int main(int argc, char* argv[])
continue;
}
shapeC->indices.push_back(shape.mesh.indices[face] + curPositions);
shapeC->indices.push_back(shape.mesh.indices[face + 1] + curPositions);
shapeC->indices.push_back(shape.mesh.indices[face + 2] + curPositions);
shapeC->indices.push_back(shape.mesh.indices[face].vertex_index + curPositions);
shapeC->indices.push_back(shape.mesh.indices[face + 1].vertex_index + curPositions);
shapeC->indices.push_back(shape.mesh.indices[face + 2].vertex_index + curPositions);
}
}
}
@@ -329,7 +330,7 @@ int main(int argc, char* argv[])
}
int faceCount = shape.mesh.indices.size();
int vertexCount = shape.mesh.positions.size();
int vertexCount = attribute.vertices.size();
tinyobj::material_t mat = shape.material;
if (shape.name.length())
{
@@ -339,7 +340,7 @@ int main(int argc, char* argv[])
}
for (int v = 0; v < vertexCount / 3; v++)
{
fprintf(f, "v %f %f %f\n", shape.mesh.positions[v * 3 + 0], shape.mesh.positions[v * 3 + 1], shape.mesh.positions[v * 3 + 2]);
fprintf(f, "v %f %f %f\n", attribute.vertices[v * 3 + 0], attribute.vertices[v * 3 + 1], attribute.vertices[v * 3 + 2]);
}
if (mat.name.length())
@@ -352,18 +353,18 @@ int main(int argc, char* argv[])
}
fprintf(f, "\n");
int numNormals = int(shape.mesh.normals.size());
int numNormals = int(attribute.normals.size());
for (int vn = 0; vn < numNormals / 3; vn++)
{
fprintf(f, "vn %f %f %f\n", shape.mesh.normals[vn * 3 + 0], shape.mesh.normals[vn * 3 + 1], shape.mesh.normals[vn * 3 + 2]);
fprintf(f, "vn %f %f %f\n", attribute.normals[vn * 3 + 0], attribute.normals[vn * 3 + 1], attribute.normals[vn * 3 + 2]);
}
fprintf(f, "\n");
int numTexCoords = int(shape.mesh.texcoords.size());
int numTexCoords = int(attribute.texcoords.size());
for (int vt = 0; vt < numTexCoords / 2; vt++)
{
fprintf(f, "vt %f %f\n", shape.mesh.texcoords[vt * 2 + 0], shape.mesh.texcoords[vt * 2 + 1]);
fprintf(f, "vt %f %f\n", attribute.texcoords[vt * 2 + 0], attribute.texcoords[vt * 2 + 1]);
}
fprintf(f, "s off\n");
@@ -375,9 +376,9 @@ int main(int argc, char* argv[])
continue;
}
fprintf(f, "f %d/%d/%d %d/%d/%d %d/%d/%d\n",
shape.mesh.indices[face] + 1, shape.mesh.indices[face] + 1, shape.mesh.indices[face] + 1,
shape.mesh.indices[face + 1] + 1, shape.mesh.indices[face + 1] + 1, shape.mesh.indices[face + 1] + 1,
shape.mesh.indices[face + 2] + 1, shape.mesh.indices[face + 2] + 1, shape.mesh.indices[face + 2] + 1);
shape.mesh.indices[face].vertex_index + 1, shape.mesh.indices[face].vertex_index + 1, shape.mesh.indices[face].vertex_index + 1,
shape.mesh.indices[face + 1].vertex_index + 1, shape.mesh.indices[face + 1].vertex_index + 1, shape.mesh.indices[face + 1].vertex_index + 1,
shape.mesh.indices[face + 2].vertex_index + 1, shape.mesh.indices[face + 2].vertex_index + 1, shape.mesh.indices[face + 2].vertex_index + 1);
}
fclose(f);
@@ -437,4 +438,4 @@ int main(int argc, char* argv[])
fclose(sdfFile);
return 0;
}
}

View File

@@ -5,7 +5,20 @@
This is the official C++ source code repository of the Bullet Physics SDK: real-time collision detection and multi-physics simulation for VR, games, visual effects, robotics, machine learning etc.
New in Bullet 2.85: pybullet Python bindings, improved support for robotics and VR. Use pip install pybullet and see [PyBullet Quickstart Guide](https://docs.google.com/document/d/10sXEhzFRSnvFcl3XxNGhnD4N2SedqwdAvK3dsihxVUA/edit#heading=h.2ye70wns7io3).
## PyBullet ##
New in Bullet 2.85: pybullet Python bindings, improved support for robotics and VR. Use pip install pybullet and checkout the [PyBullet Quickstart Guide](https://docs.google.com/document/d/10sXEhzFRSnvFcl3XxNGhnD4N2SedqwdAvK3dsihxVUA/edit#heading=h.2ye70wns7io3).
If you use PyBullet in your research, please cite it like this:
```
@MISC{coumans2019,
author = {Erwin Coumans and Yunfei Bai},
title = {PyBullet, a Python module for physics simulation for games, robotics and machine learning},
howpublished = {\url{http://pybullet.org}},
year = {2016--2019}
}
```
The Bullet 2 API will stay default and up-to-date while slowly moving to a new API.
The steps towards a new API is in a nutshell:
@@ -44,6 +57,18 @@ track down the issue, but more work is required to cover all OpenCL kernels.
All source code files are licensed under the permissive zlib license
(http://opensource.org/licenses/Zlib) unless marked differently in a particular folder/file.
## Build instructions for Bullet using vcpkg
You can download and install Bullet using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
vcpkg install bullet3
The Bullet port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
## Build instructions for Bullet using premake. You can also use cmake instead.
**Windows**

View File

@@ -1 +1 @@
2.88
2.89

View File

@@ -18,7 +18,7 @@ rem SET myvar=c:\python-3.5.2
cd build3
premake4 --double --enable_multithreading --midi --enable_static_vr_plugin --enable_openvr --enable_pybullet --python_include_dir="%myvar%/include" --python_lib_dir="%myvar%/libs" --targetdir="../bin" vs2010
premake4 --double --standalone-examples --enable_stable_pd --enable_multithreading --midi --enable_static_vr_plugin --enable_openvr --enable_pybullet --python_include_dir="%myvar%/include" --python_lib_dir="%myvar%/libs" --targetdir="../bin" vs2010
rem premake4 --double --enable_multithreading --midi --enable_static_vr_plugin --enable_openvr --enable_pybullet --python_include_dir="%myvar%/include" --python_lib_dir="%myvar%/libs" --targetdir="../binserver" vs2010
rem premake4 --double --enable_grpc --enable_multithreading --midi --enable_static_vr_plugin --enable_openvr --enable_pybullet --python_include_dir="%myvar%/include" --python_lib_dir="%myvar%/libs" --targetdir="../binserver" vs2010

View File

@@ -1,6 +1,11 @@
prefix=@CMAKE_INSTALL_PREFIX@
exec_prefix=${prefix}
libdir=${exec_prefix}/@LIB_DESTINATION@
includedir=${prefix}/@INCLUDE_INSTALL_DIR@
Name: bullet
Description: Bullet Continuous Collision Detection and Physics Library
Requires:
Version: @BULLET_VERSION@
Libs: -L@CMAKE_INSTALL_PREFIX@/@LIB_DESTINATION@ -lBulletSoftBody -lBulletDynamics -lBulletCollision -lLinearMath
Cflags: @BULLET_DOUBLE_DEF@ -I@CMAKE_INSTALL_PREFIX@/@INCLUDE_INSTALL_DIR@ -I@CMAKE_INSTALL_PREFIX@/include
Requires:
Libs: -L${libdir} -lBulletSoftBody -lBulletDynamics -lBulletCollision -lLinearMath
Cflags: @BULLET_DOUBLE_DEF@ -I${includedir} -I${prefix}/include

5681
data/ball.vtk Normal file

File diff suppressed because it is too large Load Diff

5524
data/banana.vtk Normal file

File diff suppressed because it is too large Load Diff

5457
data/boot.vtk Normal file

File diff suppressed because it is too large Load Diff

5459
data/bread.vtk Normal file

File diff suppressed because it is too large Load Diff

64
data/cloth.obj Normal file
View File

@@ -0,0 +1,64 @@
# Blender v2.79 (sub 0) OBJ File: ''
# www.blender.org
mtllib cloth.mtl
o Plane_Plane.001
v -1.000000 0.000000 1.000000
v 1.000000 0.000000 1.000000
v -1.000000 0.000000 -1.000000
v 1.000000 0.000000 -1.000000
v -1.000000 0.000000 0.000000
v 0.000000 0.000000 1.000000
v 1.000000 0.000000 0.000000
v 0.000000 0.000000 -1.000000
v 0.000000 0.000000 0.000000
v -1.000000 0.000000 0.500000
v 0.500000 0.000000 1.000000
v 1.000000 0.000000 -0.500000
v -0.500000 0.000000 -1.000000
v -1.000000 0.000000 -0.500000
v -0.500000 0.000000 1.000000
v 1.000000 0.000000 0.500000
v 0.500000 0.000000 -1.000000
v 0.000000 0.000000 -0.500000
v 0.000000 0.000000 0.500000
v -0.500000 0.000000 0.000000
v 0.500000 0.000000 0.000000
v 0.500000 0.000000 0.500000
v -0.500000 0.000000 0.500000
v -0.500000 0.000000 -0.500000
v 0.500000 0.000000 -0.500000
vn 0.0000 1.0000 0.0000
usemtl None
s off
f 12//1 17//1 25//1
f 18//1 13//1 24//1
f 19//1 20//1 23//1
f 16//1 21//1 22//1
f 22//1 9//1 19//1
f 11//1 19//1 6//1
f 2//1 22//1 11//1
f 23//1 5//1 10//1
f 15//1 10//1 1//1
f 6//1 23//1 15//1
f 24//1 3//1 14//1
f 20//1 14//1 5//1
f 9//1 24//1 20//1
f 25//1 8//1 18//1
f 21//1 18//1 9//1
f 7//1 25//1 21//1
f 12//1 4//1 17//1
f 18//1 8//1 13//1
f 19//1 9//1 20//1
f 16//1 7//1 21//1
f 22//1 21//1 9//1
f 11//1 22//1 19//1
f 2//1 16//1 22//1
f 23//1 20//1 5//1
f 15//1 23//1 10//1
f 6//1 19//1 23//1
f 24//1 13//1 3//1
f 20//1 24//1 14//1
f 9//1 18//1 24//1
f 25//1 17//1 8//1
f 21//1 25//1 18//1
f 7//1 12//1 25//1

64
data/cloth_z_up.obj Normal file
View File

@@ -0,0 +1,64 @@
# Blender v2.79 (sub 0) OBJ File: ''
# www.blender.org
mtllib cloth_z_up.mtl
o Plane_Plane.001
v -1.000000 -1.000000 0.000000
v 1.000000 -1.000000 0.000000
v -1.000000 1.000000 -0.000000
v 1.000000 1.000000 -0.000000
v -1.000000 0.000000 0.000000
v -0.000000 -1.000000 0.000000
v 1.000000 -0.000000 -0.000000
v 0.000000 1.000000 -0.000000
v 0.000000 0.000000 0.000000
v -1.000000 -0.500000 0.000000
v 0.500000 -1.000000 0.000000
v 1.000000 0.500000 -0.000000
v -0.500000 1.000000 -0.000000
v -1.000000 0.500000 -0.000000
v -0.500000 -1.000000 0.000000
v 1.000000 -0.500000 0.000000
v 0.500000 1.000000 -0.000000
v 0.000000 0.500000 -0.000000
v -0.000000 -0.500000 0.000000
v -0.500000 0.000000 0.000000
v 0.500000 -0.000000 -0.000000
v 0.500000 -0.500000 0.000000
v -0.500000 -0.500000 0.000000
v -0.500000 0.500000 -0.000000
v 0.500000 0.500000 -0.000000
vn 0.0000 0.0000 1.0000
usemtl None
s off
f 12//1 17//1 25//1
f 18//1 13//1 24//1
f 19//1 20//1 23//1
f 16//1 21//1 22//1
f 22//1 9//1 19//1
f 11//1 19//1 6//1
f 2//1 22//1 11//1
f 23//1 5//1 10//1
f 15//1 10//1 1//1
f 6//1 23//1 15//1
f 24//1 3//1 14//1
f 20//1 14//1 5//1
f 9//1 24//1 20//1
f 25//1 8//1 18//1
f 21//1 18//1 9//1
f 7//1 25//1 21//1
f 12//1 4//1 17//1
f 18//1 8//1 13//1
f 19//1 9//1 20//1
f 16//1 7//1 21//1
f 22//1 21//1 9//1
f 11//1 22//1 19//1
f 2//1 16//1 22//1
f 23//1 20//1 5//1
f 15//1 23//1 10//1
f 6//1 19//1 23//1
f 24//1 13//1 3//1
f 20//1 24//1 14//1
f 9//1 18//1 24//1
f 25//1 17//1 8//1
f 21//1 25//1 18//1
f 7//1 12//1 25//1

23419
data/ditto.vtk Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

3225
data/paper_collision.vtk Normal file

File diff suppressed because it is too large Load Diff

5057
data/paper_roll.vtk Normal file

File diff suppressed because it is too large Load Diff

15
data/single_tet.vtk Normal file
View File

@@ -0,0 +1,15 @@
# vtk DataFile Version 2.0
ball_, Created by Gmsh
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 4 double
0 0 0
1 0 0
0 1 0
0 0 1
CELLS 1 1
4 0 1 2 3
CELL_TYPES 1
10

View File

@@ -29,21 +29,21 @@
<geometry>
<mesh filename="table.obj" scale="0.1 0.1 0.58"/>
</geometry>
<material name="framemat0"/>
<material name="white"/>
</visual>
<visual>
<origin rpy="0 0 0" xyz="-0.65 0.4 0.29"/>
<geometry>
<mesh filename="table.obj" scale="0.1 0.1 0.58"/>
</geometry>
<material name="framemat0"/>
<material name="white"/>
</visual>
<visual>
<origin rpy="0 0 0" xyz="0.65 -0.4 0.29"/>
<geometry>
<mesh filename="table.obj" scale="0.1 0.1 0.58"/>
</geometry>
<material name="framemat0"/>
<material name="white"/>
</visual>
<visual>
<origin rpy="0 0 0" xyz="0.65 0.4 0.29"/>

9917
data/torus.vtk Normal file

File diff suppressed because it is too large Load Diff

5051
data/tube.vtk Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -1,209 +0,0 @@
#include "BlockSolverExample.h"
#include "BulletDynamics/MLCPSolvers/btDantzigSolver.h"
#include "BulletDynamics/MLCPSolvers/btSolveProjectedGaussSeidel.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
#include "BulletDynamics/Featherstone/btMultiBodyMLCPConstraintSolver.h"
#include "btBlockSolver.h"
//for URDF import support
#include "../Importers/ImportURDFDemo/BulletUrdfImporter.h"
#include "../Importers/ImportURDFDemo/MyMultiBodyCreator.h"
#include "../Importers/ImportURDFDemo/URDF2Bullet.h"
#include "../CommonInterfaces/CommonMultiBodyBase.h"
class BlockSolverExample : public CommonMultiBodyBase
{
int m_option;
public:
BlockSolverExample(GUIHelperInterface* helper, int option);
virtual ~BlockSolverExample();
virtual void initPhysics();
virtual void stepSimulation(float deltaTime);
virtual void resetCamera()
{
float dist = 3;
float pitch = -35;
float yaw = 50;
float targetPos[3] = {0, 0, .1};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
void createMultiBodyStack();
btMultiBody* createMultiBody(btScalar mass, const btTransform& trans, btCollisionShape* collisionShape);
btMultiBody* loadRobot(std::string filepath);
};
BlockSolverExample::BlockSolverExample(GUIHelperInterface* helper, int option)
: CommonMultiBodyBase(helper),
m_option(option)
{
m_guiHelper->setUpAxis(2);
}
BlockSolverExample::~BlockSolverExample()
{
// Do nothing
}
void BlockSolverExample::stepSimulation(float deltaTime)
{
//use a smaller internal timestep, there are stability issues
btScalar internalTimeStep = 1. / 240.f;
m_dynamicsWorld->stepSimulation(deltaTime, 10, internalTimeStep);
}
void BlockSolverExample::initPhysics()
{
///collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btDefaultCollisionConfiguration();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
btMLCPSolverInterface* mlcp;
if (m_option & BLOCK_SOLVER_SI)
{
btAssert(!m_solver);
m_solver = new btMultiBodyConstraintSolver;
b3Printf("Constraint Solver: Sequential Impulse");
}
if (m_option & BLOCK_SOLVER_MLCP_PGS)
{
btAssert(!m_solver);
mlcp = new btSolveProjectedGaussSeidel();
m_solver = new btMultiBodyMLCPConstraintSolver(mlcp);
b3Printf("Constraint Solver: MLCP + PGS");
}
if (m_option & BLOCK_SOLVER_MLCP_DANTZIG)
{
btAssert(!m_solver);
mlcp = new btDantzigSolver();
m_solver = new btMultiBodyMLCPConstraintSolver(mlcp);
b3Printf("Constraint Solver: MLCP + Dantzig");
}
if (m_option & BLOCK_SOLVER_BLOCK)
{
m_solver = new btBlockSolver();
}
btAssert(m_solver);
btMultiBodyDynamicsWorld* world = new btMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
m_dynamicsWorld = world;
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
m_dynamicsWorld->setGravity(btVector3(0, 0, -10));
m_dynamicsWorld->getSolverInfo().m_numIterations = 50;
m_dynamicsWorld->getSolverInfo().m_globalCfm = btScalar(1e-6); //todo: what value is good?
if (m_option & BLOCK_SOLVER_SCENE_MB_STACK)
{
createMultiBodyStack();
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void BlockSolverExample::createMultiBodyStack()
{
///create a few basic rigid bodies
bool loadPlaneFromURDF = false;
if (loadPlaneFromURDF)
{
btMultiBody* mb = loadRobot("plane.urdf");
printf("!\n");
}
else
{
btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.)));
m_collisionShapes.push_back(groundShape);
btScalar mass = 0;
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(0, 0, -50));
btMultiBody* body = createMultiBody(mass, tr, groundShape);
}
for (int i = 0; i < 10; i++)
{
btBoxShape* boxShape = createBoxShape(btVector3(btScalar(.1), btScalar(.1), btScalar(.1)));
m_collisionShapes.push_back(boxShape);
btScalar mass = 1;
if (i == 9)
mass = 100;
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(0, 0, 0.1 + i * 0.2));
btMultiBody* body = createMultiBody(mass, tr, boxShape);
}
if (/* DISABLES CODE */ (0))
{
btMultiBody* mb = loadRobot("cube_small.urdf");
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(0, 0, 1.));
mb->setBaseWorldTransform(tr);
}
}
btMultiBody* BlockSolverExample::createMultiBody(btScalar mass, const btTransform& trans, btCollisionShape* collisionShape)
{
btVector3 inertia;
collisionShape->calculateLocalInertia(mass, inertia);
bool canSleep = false;
bool isDynamic = mass > 0;
btMultiBody* mb = new btMultiBody(0, mass, inertia, !isDynamic, canSleep);
btMultiBodyLinkCollider* collider = new btMultiBodyLinkCollider(mb, -1);
collider->setWorldTransform(trans);
mb->setBaseWorldTransform(trans);
collider->setCollisionShape(collisionShape);
int collisionFilterGroup = isDynamic ? int(btBroadphaseProxy::DefaultFilter) : int(btBroadphaseProxy::StaticFilter);
int collisionFilterMask = isDynamic ? int(btBroadphaseProxy::AllFilter) : int(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter);
this->m_dynamicsWorld->addCollisionObject(collider, collisionFilterGroup, collisionFilterMask);
mb->setBaseCollider(collider);
mb->finalizeMultiDof();
this->m_dynamicsWorld->addMultiBody(mb);
m_dynamicsWorld->forwardKinematics();
return mb;
}
btMultiBody* BlockSolverExample::loadRobot(std::string filepath)
{
btMultiBody* m_multiBody = 0;
BulletURDFImporter u2b(m_guiHelper, 0, 0, 1, 0);
bool loadOk = u2b.loadURDF(filepath.c_str()); // lwr / kuka.urdf");
if (loadOk)
{
int rootLinkIndex = u2b.getRootLinkIndex();
b3Printf("urdf root link index = %d\n", rootLinkIndex);
MyMultiBodyCreator creation(m_guiHelper);
btTransform identityTrans;
identityTrans.setIdentity();
ConvertURDF2Bullet(u2b, creation, identityTrans, m_dynamicsWorld, true, u2b.getPathPrefix());
for (int i = 0; i < u2b.getNumAllocatedCollisionShapes(); i++)
{
m_collisionShapes.push_back(u2b.getAllocatedCollisionShape(i));
}
m_multiBody = creation.getBulletMultiBody();
if (m_multiBody)
{
b3Printf("Root link name = %s", u2b.getLinkName(u2b.getRootLinkIndex()).c_str());
}
}
return m_multiBody;
}
CommonExampleInterface* BlockSolverExampleCreateFunc(CommonExampleOptions& options)
{
return new BlockSolverExample(options.m_guiHelper, options.m_option);
}

View File

@@ -1,7 +0,0 @@
#ifndef BLOCK_SOLVER_EXAMPLE_H
#define BLOCK_SOLVER_EXAMPLE_H
class CommonExampleInterface* BlockSolverExampleCreateFunc(struct CommonExampleOptions& options);
#endif //BLOCK_SOLVER_EXAMPLE_H

View File

@@ -1,151 +0,0 @@
#include "RigidBodyBoxes.h"
#include "../CommonInterfaces/CommonParameterInterface.h"
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "BlockSolverExample.h"
#include "btBlockSolver.h"
class RigidBodyBoxes : public CommonRigidBodyBase
{
int m_option;
int m_numIterations;
int m_numBoxes;
btAlignedObjectArray<btRigidBody*> boxes;
static btScalar numSolverIterations;
public:
RigidBodyBoxes(GUIHelperInterface* helper, int option);
virtual ~RigidBodyBoxes();
virtual void initPhysics();
virtual void stepSimulation(float deltaTime);
void resetCubePosition();
virtual void resetCamera()
{
float dist = 3;
float pitch = -35;
float yaw = 50;
float targetPos[3] = {0, 0, .1};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1],
targetPos[2]);
}
void createRigidBodyStack();
};
btScalar RigidBodyBoxes::numSolverIterations = 50;
RigidBodyBoxes::RigidBodyBoxes(GUIHelperInterface* helper, int option)
: CommonRigidBodyBase(helper),
m_option(option),
m_numIterations(numSolverIterations),
m_numBoxes(4)
{
m_guiHelper->setUpAxis(2);
}
RigidBodyBoxes::~RigidBodyBoxes()
{
// Do nothing
}
void RigidBodyBoxes::createRigidBodyStack()
{
// create ground
btBoxShape* groundShape =
createBoxShape(btVector3(btScalar(5.), btScalar(5.), btScalar(5.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0, 0, -5));
btScalar mass(0.);
btRigidBody* body = createRigidBody(mass, groundTransform, groundShape,
btVector4(0, 0, 1, 1));
// create a few boxes
mass = 1;
for (int i = 0; i < m_numBoxes; i++)
{
btBoxShape* boxShape =
createBoxShape(btVector3(btScalar(.1), btScalar(.1), btScalar(.1)));
m_collisionShapes.push_back(boxShape);
mass *= 4;
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(0, 0, 0.1 + i * 0.2));
boxes.push_back(createRigidBody(mass, tr, boxShape));
}
}
void RigidBodyBoxes::initPhysics()
{
/// collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btDefaultCollisionConfiguration();
/// use the default collision dispatcher. For parallel processing you can use
/// a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
{
SliderParams slider("numSolverIterations", &numSolverIterations);
slider.m_minVal = 5;
slider.m_maxVal = 500;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
if (m_option & BLOCK_SOLVER_SI)
{
m_solver = new btSequentialImpulseConstraintSolver;
b3Printf("Constraint Solver: Sequential Impulse");
}
if (m_option & BLOCK_SOLVER_BLOCK)
{
m_solver = new btBlockSolver();
b3Printf("Constraint Solver: Block solver");
}
btAssert(m_solver);
m_dynamicsWorld = new btDiscreteDynamicsWorld(
m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration);
m_dynamicsWorld->setGravity(btVector3(0, 0, -10));
createRigidBodyStack();
m_dynamicsWorld->getSolverInfo().m_numIterations = numSolverIterations;
m_dynamicsWorld->getSolverInfo().m_globalCfm = btScalar(1e-6);
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void RigidBodyBoxes::resetCubePosition()
{
for (int i = 0; i < m_numBoxes; i++)
{
btTransform tr;
tr.setIdentity();
tr.setOrigin(btVector3(0, 0, 0.1 + i * 0.2));
boxes[i]->setWorldTransform(tr);
}
}
void RigidBodyBoxes::stepSimulation(float deltaTime)
{
if ((int)numSolverIterations != m_numIterations)
{
resetCubePosition();
m_numIterations = (int)numSolverIterations;
m_dynamicsWorld->getSolverInfo().m_numIterations = m_numIterations;
b3Printf("New num iterations; %d", m_numIterations);
}
m_dynamicsWorld->stepSimulation(deltaTime);
}
CommonExampleInterface* RigidBodyBoxesCreateFunc(
CommonExampleOptions& options)
{
return new RigidBodyBoxes(options.m_guiHelper, options.m_option);
}

View File

@@ -1,6 +0,0 @@
#ifndef BLOCKSOLVER_RIGIDBODYBOXES_H_
#define BLOCKSOLVER_RIGIDBODYBOXES_H_
class CommonExampleInterface* RigidBodyBoxesCreateFunc(struct CommonExampleOptions& options);
#endif //BLOCKSOLVER_RIGIDBODYBOXES_H_

View File

@@ -1,374 +0,0 @@
#include "btBlockSolver.h"
#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
#include "BulletDynamics/MLCPSolvers/btDantzigSolver.h"
#include "BulletDynamics/MLCPSolvers/btMLCPSolver.h"
#include "BulletDynamics/MLCPSolvers/btSolveProjectedGaussSeidel.h"
#include "LinearMath/btQuickprof.h"
void setupHelper(btSISolverSingleIterationData& siData,
btCollisionObject** bodies, int numBodies,
const btContactSolverInfo& info,
btTypedConstraint** constraintStart, int constrainNums,
btPersistentManifold** manifoldPtr, int numManifolds);
struct btBlockSolverInternalData
{
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_btSeed2;
int m_fixedBodyId;
int m_maxOverrideNumSolverIterations;
btAlignedObjectArray<int>
m_kinematicBodyUniqueIdToSolverBodyTable; // only used for multithreading
btSingleConstraintRowSolver m_resolveSingleConstraintRowGeneric;
btSingleConstraintRowSolver m_resolveSingleConstraintRowLowerLimit;
btSingleConstraintRowSolver m_resolveSplitPenetrationImpulse;
btBlockSolverInternalData()
: m_btSeed2(0),
m_fixedBodyId(-1),
m_maxOverrideNumSolverIterations(0),
m_resolveSingleConstraintRowGeneric(
btSequentialImpulseConstraintSolver::
getScalarConstraintRowSolverGeneric()),
m_resolveSingleConstraintRowLowerLimit(
btSequentialImpulseConstraintSolver::
getScalarConstraintRowSolverLowerLimit()),
m_resolveSplitPenetrationImpulse(
btSequentialImpulseConstraintSolver::
getScalarSplitPenetrationImpulseGeneric()) {}
};
btBlockSolver::btBlockSolver()
{
m_data21 = new btBlockSolverInternalData;
m_data22 = new btBlockSolverInternalData;
}
btBlockSolver::~btBlockSolver()
{
delete m_data21;
delete m_data22;
}
btScalar btBlockSolver::solveGroupInternalBlock(
btCollisionObject** bodies, int numBodies,
btPersistentManifold** manifoldPtr, int numManifolds,
btTypedConstraint** constraints, int numConstraints,
const btContactSolverInfo& info, btIDebugDraw* debugDrawer,
btDispatcher* dispatcher)
{
// initialize data for two children solvers
btSISolverSingleIterationData siData1(
m_data21->m_tmpSolverBodyPool, m_data21->m_tmpSolverContactConstraintPool,
m_data21->m_tmpSolverNonContactConstraintPool,
m_data21->m_tmpSolverContactFrictionConstraintPool,
m_data21->m_tmpSolverContactRollingFrictionConstraintPool,
m_data21->m_orderTmpConstraintPool,
m_data21->m_orderNonContactConstraintPool,
m_data21->m_orderFrictionConstraintPool,
m_data21->m_tmpConstraintSizesPool,
m_data21->m_resolveSingleConstraintRowGeneric,
m_data21->m_resolveSingleConstraintRowLowerLimit,
m_data21->m_resolveSplitPenetrationImpulse,
m_data21->m_kinematicBodyUniqueIdToSolverBodyTable, m_data21->m_btSeed2,
m_data21->m_fixedBodyId, m_data21->m_maxOverrideNumSolverIterations);
btSISolverSingleIterationData siData2(
m_data22->m_tmpSolverBodyPool, m_data22->m_tmpSolverContactConstraintPool,
m_data22->m_tmpSolverNonContactConstraintPool,
m_data22->m_tmpSolverContactFrictionConstraintPool,
m_data22->m_tmpSolverContactRollingFrictionConstraintPool,
m_data22->m_orderTmpConstraintPool,
m_data22->m_orderNonContactConstraintPool,
m_data22->m_orderFrictionConstraintPool,
m_data22->m_tmpConstraintSizesPool,
m_data22->m_resolveSingleConstraintRowGeneric,
m_data22->m_resolveSingleConstraintRowLowerLimit,
m_data22->m_resolveSplitPenetrationImpulse,
m_data22->m_kinematicBodyUniqueIdToSolverBodyTable, m_data22->m_btSeed2,
m_data22->m_fixedBodyId, m_data22->m_maxOverrideNumSolverIterations);
m_data21->m_fixedBodyId = -1;
m_data22->m_fixedBodyId = -1;
// set up
int halfNumConstraints1 = numConstraints / 2;
int halfNumConstraints2 = numConstraints - halfNumConstraints1;
int halfNumManifolds1 = numConstraints / 2;
int halfNumManifolds2 = numManifolds - halfNumManifolds1;
setupHelper(siData1, bodies, numBodies, info, constraints,
halfNumConstraints1, manifoldPtr, halfNumManifolds1);
setupHelper(siData2, bodies, numBodies, info,
constraints + halfNumConstraints1, halfNumConstraints2,
manifoldPtr + halfNumManifolds1, halfNumManifolds2);
// set up complete
// begin solve
btScalar leastSquaresResidual = 0;
{
BT_PROFILE("solveGroupCacheFriendlyIterations");
/// this is a special step to resolve penetrations (just for contacts)
btSequentialImpulseConstraintSolver::
solveGroupCacheFriendlySplitImpulseIterationsInternal(
siData1, bodies, numBodies, manifoldPtr, halfNumManifolds1,
constraints, halfNumConstraints1, info, debugDrawer);
btSequentialImpulseConstraintSolver::
solveGroupCacheFriendlySplitImpulseIterationsInternal(
siData2, bodies, numBodies, manifoldPtr + halfNumManifolds1,
halfNumManifolds2, constraints + halfNumConstraints1,
halfNumConstraints2, info, debugDrawer);
int maxIterations =
siData1.m_maxOverrideNumSolverIterations > info.m_numIterations
? siData1.m_maxOverrideNumSolverIterations
: info.m_numIterations;
for (int iteration = 0; iteration < maxIterations; iteration++)
{
btScalar res1 =
btSequentialImpulseConstraintSolver::solveSingleIterationInternal(
siData1, iteration, constraints, halfNumConstraints1, info);
btScalar res2 =
btSequentialImpulseConstraintSolver::solveSingleIterationInternal(
siData2, iteration, constraints + halfNumConstraints1,
halfNumConstraints2, info);
leastSquaresResidual = btMax(res1, res2);
if (leastSquaresResidual <= info.m_leastSquaresResidualThreshold ||
(iteration >= (maxIterations - 1)))
{
#ifdef VERBOSE_RESIDUAL_PRINTF
printf("residual = %f at iteration #%d\n", m_leastSquaresResidual,
iteration);
#endif
break;
}
}
}
btScalar res = btSequentialImpulseConstraintSolver::
solveGroupCacheFriendlyFinishInternal(siData1, bodies, numBodies, info);
+btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinishInternal(
siData2, bodies, numBodies, info);
return res;
}
void setupHelper(btSISolverSingleIterationData& siData,
btCollisionObject** bodies, int numBodies,
const btContactSolverInfo& info,
btTypedConstraint** constraintStart, int constrainNums,
btPersistentManifold** manifoldPtr, int numManifolds)
{
btSequentialImpulseConstraintSolver::convertBodiesInternal(siData, bodies,
numBodies, info);
btSequentialImpulseConstraintSolver::convertJointsInternal(
siData, constraintStart, constrainNums, info);
int i;
btPersistentManifold* manifold = 0;
for (i = 0; i < numManifolds; i++)
{
manifold = manifoldPtr[i];
btSequentialImpulseConstraintSolver::convertContactInternal(siData,
manifold, info);
int numNonContactPool = siData.m_tmpSolverNonContactConstraintPool.size();
int numConstraintPool = siData.m_tmpSolverContactConstraintPool.size();
int numFrictionPool =
siData.m_tmpSolverContactFrictionConstraintPool.size();
siData.m_orderNonContactConstraintPool.resizeNoInitialize(
numNonContactPool);
if ((info.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
siData.m_orderTmpConstraintPool.resizeNoInitialize(numConstraintPool * 2);
else
siData.m_orderTmpConstraintPool.resizeNoInitialize(numConstraintPool);
siData.m_orderFrictionConstraintPool.resizeNoInitialize(numFrictionPool);
{
int i;
for (i = 0; i < numNonContactPool; i++)
{
siData.m_orderNonContactConstraintPool[i] = i;
}
for (i = 0; i < numConstraintPool; i++)
{
siData.m_orderTmpConstraintPool[i] = i;
}
for (i = 0; i < numFrictionPool; i++)
{
siData.m_orderFrictionConstraintPool[i] = i;
}
}
}
}
btScalar btBlockSolver::solveGroup(btCollisionObject** bodies, int numBodies,
btPersistentManifold** manifoldPtr,
int numManifolds,
btTypedConstraint** constraints,
int numConstraints,
const btContactSolverInfo& info,
btIDebugDraw* debugDrawer,
btDispatcher* dispatcher)
{
// if (m_childSolvers.size())
// hard code to use block solver for now
return solveGroupInternalBlock(bodies, numBodies, manifoldPtr, numManifolds,
constraints, numConstraints, info, debugDrawer,
dispatcher);
// else
// return solveGroupInternal(bodies, numBodies, manifoldPtr, numManifolds,
// constraints, numConstraints, info, debugDrawer,
// dispatcher);
}
btScalar btBlockSolver::solveGroupInternal(
btCollisionObject** bodies, int numBodies,
btPersistentManifold** manifoldPtr, int numManifolds,
btTypedConstraint** constraints, int numConstraints,
const btContactSolverInfo& info, btIDebugDraw* debugDrawer,
btDispatcher* dispatcher)
{
btSISolverSingleIterationData siData(
m_data21->m_tmpSolverBodyPool, m_data21->m_tmpSolverContactConstraintPool,
m_data21->m_tmpSolverNonContactConstraintPool,
m_data21->m_tmpSolverContactFrictionConstraintPool,
m_data21->m_tmpSolverContactRollingFrictionConstraintPool,
m_data21->m_orderTmpConstraintPool,
m_data21->m_orderNonContactConstraintPool,
m_data21->m_orderFrictionConstraintPool,
m_data21->m_tmpConstraintSizesPool,
m_data21->m_resolveSingleConstraintRowGeneric,
m_data21->m_resolveSingleConstraintRowLowerLimit,
m_data21->m_resolveSplitPenetrationImpulse,
m_data21->m_kinematicBodyUniqueIdToSolverBodyTable, m_data21->m_btSeed2,
m_data21->m_fixedBodyId, m_data21->m_maxOverrideNumSolverIterations);
m_data21->m_fixedBodyId = -1;
// todo: setup sse2/4 constraint row methods
btSequentialImpulseConstraintSolver::convertBodiesInternal(siData, bodies,
numBodies, info);
btSequentialImpulseConstraintSolver::convertJointsInternal(
siData, constraints, numConstraints, info);
int i;
btPersistentManifold* manifold = 0;
// btCollisionObject* colObj0=0,*colObj1=0;
for (i = 0; i < numManifolds; i++)
{
manifold = manifoldPtr[i];
btSequentialImpulseConstraintSolver::convertContactInternal(siData,
manifold, info);
}
int numNonContactPool = siData.m_tmpSolverNonContactConstraintPool.size();
int numConstraintPool = siData.m_tmpSolverContactConstraintPool.size();
int numFrictionPool = siData.m_tmpSolverContactFrictionConstraintPool.size();
// @todo: use stack allocator for such temporarily memory, same for solver
// bodies/constraints
siData.m_orderNonContactConstraintPool.resizeNoInitialize(numNonContactPool);
if ((info.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS))
siData.m_orderTmpConstraintPool.resizeNoInitialize(numConstraintPool * 2);
else
siData.m_orderTmpConstraintPool.resizeNoInitialize(numConstraintPool);
siData.m_orderFrictionConstraintPool.resizeNoInitialize(numFrictionPool);
{
int i;
for (i = 0; i < numNonContactPool; i++)
{
siData.m_orderNonContactConstraintPool[i] = i;
}
for (i = 0; i < numConstraintPool; i++)
{
siData.m_orderTmpConstraintPool[i] = i;
}
for (i = 0; i < numFrictionPool; i++)
{
siData.m_orderFrictionConstraintPool[i] = i;
}
}
btScalar leastSquaresResidual = 0;
{
BT_PROFILE("solveGroupCacheFriendlyIterations");
/// this is a special step to resolve penetrations (just for contacts)
btSequentialImpulseConstraintSolver::
solveGroupCacheFriendlySplitImpulseIterationsInternal(
siData, bodies, numBodies, manifoldPtr, numManifolds, constraints,
numConstraints, info, debugDrawer);
int maxIterations =
siData.m_maxOverrideNumSolverIterations > info.m_numIterations
? siData.m_maxOverrideNumSolverIterations
: info.m_numIterations;
for (int iteration = 0; iteration < maxIterations; iteration++)
{
leastSquaresResidual =
btSequentialImpulseConstraintSolver::solveSingleIterationInternal(
siData, iteration, constraints, numConstraints, info);
if (leastSquaresResidual <= info.m_leastSquaresResidualThreshold ||
(iteration >= (maxIterations - 1)))
{
#ifdef VERBOSE_RESIDUAL_PRINTF
printf("residual = %f at iteration #%d\n", m_leastSquaresResidual,
iteration);
#endif
break;
}
}
}
btScalar res = btSequentialImpulseConstraintSolver::
solveGroupCacheFriendlyFinishInternal(siData, bodies, numBodies, info);
return res;
}
void btBlockSolver::solveMultiBodyGroup(
btCollisionObject** bodies, int numBodies, btPersistentManifold** manifold,
int numManifolds, btTypedConstraint** constraints, int numConstraints,
btMultiBodyConstraint** multiBodyConstraints, int numMultiBodyConstraints,
const btContactSolverInfo& info, btIDebugDraw* debugDrawer,
btDispatcher* dispatcher)
{
btMultiBodyConstraintSolver::solveMultiBodyGroup(
bodies, numBodies, manifold, numManifolds, constraints, numConstraints,
multiBodyConstraints, numMultiBodyConstraints, info, debugDrawer,
dispatcher);
}
void btBlockSolver::reset()
{
// or just set m_data2->m_btSeed2=0?
delete m_data21;
delete m_data22;
m_data21 = new btBlockSolverInternalData;
m_data22 = new btBlockSolverInternalData;
}

View File

@@ -1,77 +0,0 @@
#ifndef BT_BLOCK_SOLVER_H
#define BT_BLOCK_SOLVER_H
#include "BulletDynamics/ConstraintSolver/btConstraintSolver.h"
#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
#include "BulletDynamics/MLCPSolvers/btDantzigSolver.h"
#include "BulletDynamics/MLCPSolvers/btMLCPSolver.h"
#include "BulletDynamics/MLCPSolvers/btSolveProjectedGaussSeidel.h"
#include "Bullet3Common/b3Logging.h"
enum BlockSolverOptions
{
BLOCK_SOLVER_SI = 1 << 0,
BLOCK_SOLVER_MLCP_PGS = 1 << 1,
BLOCK_SOLVER_MLCP_DANTZIG = 1 << 2,
BLOCK_SOLVER_BLOCK = 1 << 3,
BLOCK_SOLVER_SCENE_MB_STACK = 1 << 5,
BLOCK_SOLVER_SCENE_CHAIN = 1 << 6,
};
class btBlockSolver : public btMultiBodyConstraintSolver
{
struct btBlockSolverInternalData* m_data21;
struct btBlockSolverInternalData* m_data22;
public
: btBlockSolver();
virtual ~btBlockSolver();
// btRigidBody
virtual btScalar solveGroup(btCollisionObject** bodies, int numBodies,
btPersistentManifold** manifoldPtr,
int numManifolds, btTypedConstraint** constraints,
int numConstraints,
const btContactSolverInfo& info,
class btIDebugDraw* debugDrawer,
btDispatcher* dispatcher);
btScalar solveGroupInternal(btCollisionObject** bodies, int numBodies,
btPersistentManifold** manifoldPtr,
int numManifolds,
btTypedConstraint** constraints,
int numConstraints,
const btContactSolverInfo& info,
btIDebugDraw* debugDrawer,
btDispatcher* dispatcher);
btScalar solveGroupInternalBlock(btCollisionObject** bodies, int numBodies,
btPersistentManifold** manifoldPtr,
int numManifolds,
btTypedConstraint** constraints,
int numConstraints,
const btContactSolverInfo& info,
btIDebugDraw* debugDrawer,
btDispatcher* dispatcher);
// btMultibody
virtual void solveMultiBodyGroup(
btCollisionObject** bodies, int numBodies,
btPersistentManifold** manifold, int numManifolds,
btTypedConstraint** constraints, int numConstraints,
btMultiBodyConstraint** multiBodyConstraints, int numMultiBodyConstraints,
const btContactSolverInfo& info, btIDebugDraw* debugDrawer,
btDispatcher* dispatcher);
/// clear internal cached data and reset random seed
virtual void reset();
virtual btConstraintSolverType getSolverType() const
{
return BT_BLOCK_SOLVER;
}
};
#endif //BT_BLOCK_SOLVER_H

View File

@@ -1,4 +1,4 @@
SUBDIRS( HelloWorld BasicDemo )
SUBDIRS( HelloWorld BasicDemo)
IF(BUILD_BULLET3)
SUBDIRS( ExampleBrowser RobotSimulator SharedMemory ThirdPartyLibs/Gwen ThirdPartyLibs/BussIK ThirdPartyLibs/clsocket OpenGLWindow TwoJoint )
ENDIF()

View File

@@ -1,6 +1,5 @@
#ifndef GUI_HELPER_INTERFACE_H
#define GUI_HELPER_INTERFACE_H
class btRigidBody;
class btVector3;
class btCollisionObject;
@@ -44,10 +43,11 @@ struct GUIHelperInterface
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) = 0;
virtual void removeAllGraphicsInstances() = 0;
virtual void removeGraphicsInstance(int graphicsUid) {}
virtual void changeInstanceFlags(int instanceUid, int flags) {}
virtual void changeRGBAColor(int instanceUid, const double rgbaColor[4]) {}
virtual void changeSpecularColor(int instanceUid, const double specularColor[3]) {}
virtual void changeTexture(int textureUniqueId, const unsigned char* rgbTexels, int width, int height) {}
virtual void updateShape(int shapeIndex, float* vertices) {}
virtual int getShapeIndexFromInstance(int instanceUid) { return -1; }
virtual void replaceTexture(int shapeIndex, int textureUid) {}
virtual void removeTexture(int textureUid) {}
@@ -118,6 +118,8 @@ struct GUIHelperInterface
//empty name stops dumping video
virtual void dumpFramesToVideo(const char* mp4FileName){};
virtual void drawDebugDrawerLines(){}
virtual void clearLines(){}
};
///the DummyGUIHelper does nothing, so we can test the examples without GUI/graphics (in 'console mode')

View File

@@ -93,6 +93,7 @@ struct CommonGraphicsApp
if (blue)
*blue = m_backgroundColorRGB[2];
}
virtual void setMp4Fps(int fps) {}
virtual void setBackgroundColor(float red, float green, float blue)
{
m_backgroundColorRGB[0] = red;

View File

@@ -9,6 +9,13 @@ enum
B3_GL_POINTS
};
enum
{
B3_INSTANCE_TRANSPARANCY = 1,
B3_INSTANCE_TEXTURE = 2,
B3_INSTANCE_DOUBLE_SIDED = 4,
};
enum
{
B3_DEFAULT_RENDERMODE = 1,
@@ -94,7 +101,8 @@ struct CommonRenderInterface
virtual void writeSingleInstanceScaleToCPU(const double* scale, int srcIndex) = 0;
virtual void writeSingleInstanceSpecularColorToCPU(const double* specular, int srcIndex) = 0;
virtual void writeSingleInstanceSpecularColorToCPU(const float* specular, int srcIndex) = 0;
virtual void writeSingleInstanceFlagsToCPU(int flags, int srcIndex) = 0;
virtual int getTotalNumInstances() const = 0;
virtual void writeTransforms() = 0;

View File

@@ -0,0 +1,253 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "ClothFriction.h"
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
#include "btBulletDynamicsCommon.h"
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
#include "BulletSoftBody/btSoftBody.h"
#include "BulletSoftBody/btSoftBodyHelpers.h"
#include "BulletSoftBody/btDeformableBodySolver.h"
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
#include <stdio.h> //printf debugging
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../Utils/b3ResourcePath.h"
///The ClothFriction shows the use of deformable friction.
class ClothFriction : public CommonRigidBodyBase
{
btAlignedObjectArray<btDeformableLagrangianForce*> m_forces;
public:
ClothFriction(struct GUIHelperInterface* helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~ClothFriction()
{
}
void initPhysics();
void exitPhysics();
void resetCamera()
{
float dist = 12;
float pitch = -50;
float yaw = 120;
float targetPos[3] = {0, -3, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
void stepSimulation(float deltaTime)
{
float internalTimeStep = 1. / 240.f;
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
}
virtual const btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld() const
{
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld()
{
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual void renderScene()
{
CommonRigidBodyBase::renderScene();
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
{
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
{
//btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), fDrawFlags::Faces);// deformableWorld->getDrawFlags());
}
}
}
};
void ClothFriction::initPhysics()
{
m_guiHelper->setUpAxis(1);
///collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
sol->setDeformableSolver(deformableBodySolver);
m_solver = sol;
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
btVector3 gravity = btVector3(0, -10, 0);
m_dynamicsWorld->setGravity(gravity);
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.Reset();
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
{
///create a ground
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150), btScalar(25.), btScalar(150)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0, -32, 0));
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.1));
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
btScalar mass(0.);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
groundShape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
body->setFriction(3);
//add the ground to the dynamics world
m_dynamicsWorld->addRigidBody(body);
}
// create a piece of cloth
{
btScalar s = 4;
btScalar h = 0;
btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
btVector3(+s, h, -s),
btVector3(-s, h, +s),
btVector3(+s, h, +s),
10,10,
0, true);
psb->getCollisionShape()->setMargin(0.05);
psb->generateBendingConstraints(2);
psb->setTotalMass(1);
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
psb->m_cfg.kDF = 3;
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
psb->m_cfg.collisions |= btSoftBody::fCollision::VF_DD;
getDeformableDynamicsWorld()->addSoftBody(psb);
btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(10,1, true);
getDeformableDynamicsWorld()->addForce(psb, mass_spring);
m_forces.push_back(mass_spring);
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
m_forces.push_back(gravity_force);
h = 2;
s = 2;
btSoftBody* psb2 = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
btVector3(+s, h, -s),
btVector3(-s, h, +s),
btVector3(+s, h, +s),
5,5,
0, true);
psb2->getCollisionShape()->setMargin(0.05);
psb2->generateBendingConstraints(2);
psb2->setTotalMass(1);
psb2->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb2->m_cfg.kCHR = 1; // collision hardness with rigid body
psb2->m_cfg.kDF = 20;
psb2->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
psb2->m_cfg.collisions |= btSoftBody::fCollision::VF_DD;
psb->translate(btVector3(0,0,0));
getDeformableDynamicsWorld()->addSoftBody(psb2);
btDeformableMassSpringForce* mass_spring2 = new btDeformableMassSpringForce(10,1, true);
getDeformableDynamicsWorld()->addForce(psb2, mass_spring2);
m_forces.push_back(mass_spring2);
btDeformableGravityForce* gravity_force2 = new btDeformableGravityForce(gravity);
getDeformableDynamicsWorld()->addForce(psb2, gravity_force2);
m_forces.push_back(gravity_force2);
}
getDeformableDynamicsWorld()->setImplicit(false);
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void ClothFriction::exitPhysics()
{
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
int i;
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
m_dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
// delete forces
for (int j = 0; j < m_forces.size(); j++)
{
btDeformableLagrangianForce* force = m_forces[j];
delete force;
}
m_forces.clear();
//delete collision shapes
for (int j = 0; j < m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
}
m_collisionShapes.clear();
delete m_dynamicsWorld;
delete m_solver;
delete m_broadphase;
delete m_dispatcher;
delete m_collisionConfiguration;
}
class CommonExampleInterface* ClothFrictionCreateFunc(struct CommonExampleOptions& options)
{
return new ClothFriction(options.m_guiHelper);
}

View File

@@ -0,0 +1,19 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef CLOTH_FRICTION_H
#define CLOTH_FRICTION_H
class CommonExampleInterface* ClothFrictionCreateFunc(struct CommonExampleOptions& options);
#endif //CLOTH_FRICTION_H

View File

@@ -0,0 +1,236 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "DeformableClothAnchor.h"
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
#include "btBulletDynamicsCommon.h"
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
#include "BulletSoftBody/btSoftBody.h"
#include "BulletSoftBody/btSoftBodyHelpers.h"
#include "BulletSoftBody/btDeformableBodySolver.h"
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
#include <stdio.h> //printf debugging
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../Utils/b3ResourcePath.h"
///The DeformableClothAnchor shows contact between deformable objects and rigid objects.
class DeformableClothAnchor : public CommonRigidBodyBase
{
btAlignedObjectArray<btDeformableLagrangianForce*> m_forces;
public:
DeformableClothAnchor(struct GUIHelperInterface* helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~DeformableClothAnchor()
{
}
void initPhysics();
void exitPhysics();
void resetCamera()
{
float dist = 20;
float pitch = -45;
float yaw = 100;
float targetPos[3] = {0, -3, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
void stepSimulation(float deltaTime)
{
//use a smaller internal timestep, there are stability issues
float internalTimeStep = 1. / 240.f;
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
}
virtual const btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld() const
{
///just make it a btSoftRigidDynamicsWorld please
///or we will add type checking
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld()
{
///just make it a btSoftRigidDynamicsWorld please
///or we will add type checking
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual void renderScene()
{
CommonRigidBodyBase::renderScene();
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
{
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
//if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
{
//btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), fDrawFlags::Faces);// deformableWorld->getDrawFlags());
}
}
}
};
void DeformableClothAnchor::initPhysics()
{
m_guiHelper->setUpAxis(1);
///collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
sol->setDeformableSolver(deformableBodySolver);
m_solver = sol;
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
// deformableBodySolver->setWorld(getDeformableDynamicsWorld());
// m_dynamicsWorld->getSolverInfo().m_singleAxisDeformableThreshold = 0.f;//faster but lower quality
btVector3 gravity = btVector3(0, -10, 0);
m_dynamicsWorld->setGravity(gravity);
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
// getDeformableDynamicsWorld()->before_solver_callbacks.push_back(dynamics);
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
{
///create a ground
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0, -50, 0));
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
btScalar mass(0.);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
groundShape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
body->setFriction(1);
//add the ground to the dynamics world
m_dynamicsWorld->addRigidBody(body);
}
// create a piece of cloth
{
const btScalar s = 4;
const btScalar h = 6;
const int r = 9;
btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
btVector3(+s, h, -s),
btVector3(-s, h, +s),
btVector3(+s, h, +s), r, r, 4 + 8, true);
psb->getCollisionShape()->setMargin(0.1);
psb->generateBendingConstraints(2);
psb->setTotalMass(1);
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
psb->m_cfg.kDF = 2;
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
getDeformableDynamicsWorld()->addSoftBody(psb);
btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(100,1, true);
getDeformableDynamicsWorld()->addForce(psb, mass_spring);
m_forces.push_back(mass_spring);
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
m_forces.push_back(gravity_force);
btTransform startTransform;
startTransform.setIdentity();
startTransform.setOrigin(btVector3(0, h, -(s + 3.5)));
btRigidBody* body = createRigidBody(2, startTransform, new btBoxShape(btVector3(s, 1, 3)));
psb->appendDeformableAnchor(0, body);
psb->appendDeformableAnchor(r - 1, body);
}
getDeformableDynamicsWorld()->setImplicit(false);
getDeformableDynamicsWorld()->setLineSearch(false);
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void DeformableClothAnchor::exitPhysics()
{
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
int i;
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
m_dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
// delete forces
for (int j = 0; j < m_forces.size(); j++)
{
btDeformableLagrangianForce* force = m_forces[j];
delete force;
}
m_forces.clear();
//delete collision shapes
for (int j = 0; j < m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
}
m_collisionShapes.clear();
delete m_dynamicsWorld;
delete m_solver;
delete m_broadphase;
delete m_dispatcher;
delete m_collisionConfiguration;
}
class CommonExampleInterface* DeformableClothAnchorCreateFunc(struct CommonExampleOptions& options)
{
return new DeformableClothAnchor(options.m_guiHelper);
}

View File

@@ -0,0 +1,19 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef DEFORMABLE_CLOTH_ANCHOR_H
#define DEFORMABLE_CLOTH_ANCHOR_H
class CommonExampleInterface* DeformableClothAnchorCreateFunc(struct CommonExampleOptions& options);
#endif //DEFORMABLE_CLOTH_ANCHOR_H

View File

@@ -0,0 +1,264 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "DeformableContact.h"
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
#include "btBulletDynamicsCommon.h"
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
#include "BulletSoftBody/btSoftBody.h"
#include "BulletSoftBody/btSoftBodyHelpers.h"
#include "BulletSoftBody/btDeformableBodySolver.h"
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
#include <stdio.h> //printf debugging
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../Utils/b3ResourcePath.h"
///The DeformableContact shows the contact between deformable objects
class DeformableContact : public CommonRigidBodyBase
{
btAlignedObjectArray<btDeformableLagrangianForce*> m_forces;
public:
DeformableContact(struct GUIHelperInterface* helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~DeformableContact()
{
}
void initPhysics();
void exitPhysics();
void resetCamera()
{
float dist = 12;
float pitch = -50;
float yaw = 120;
float targetPos[3] = {0, -3, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
void stepSimulation(float deltaTime)
{
float internalTimeStep = 1. / 240.f;
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
}
virtual const btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld() const
{
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld()
{
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual void renderScene()
{
CommonRigidBodyBase::renderScene();
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
{
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
{
//btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), fDrawFlags::Faces);// StddeformableWorld->getDrawFlags());
}
}
}
};
void DeformableContact::initPhysics()
{
m_guiHelper->setUpAxis(1);
///collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
sol->setDeformableSolver(deformableBodySolver);
m_solver = sol;
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
btVector3 gravity = btVector3(0, -10, 0);
m_dynamicsWorld->setGravity(gravity);
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.Reset();
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
{
///create a ground
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150), btScalar(25.), btScalar(150)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0, -32, 0));
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
btScalar mass(0.);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
groundShape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
body->setFriction(2);
//add the ground to the dynamics world
m_dynamicsWorld->addRigidBody(body);
}
// create a piece of cloth
{
btScalar s = 4;
btScalar h = 0;
btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
btVector3(+s, h, -s),
btVector3(-s, h, +s),
btVector3(+s, h, +s),
20,20,
1 + 2 + 4 + 8, true);
psb->getCollisionShape()->setMargin(0.1);
psb->generateBendingConstraints(2);
psb->setTotalMass(1);
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
psb->m_cfg.kDF = 0;
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
psb->m_cfg.collisions |= btSoftBody::fCollision::VF_DD;
getDeformableDynamicsWorld()->addSoftBody(psb);
btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(10,1, true);
getDeformableDynamicsWorld()->addForce(psb, mass_spring);
m_forces.push_back(mass_spring);
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
m_forces.push_back(gravity_force);
h = 2;
s = 2;
btSoftBody* psb2 = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
btVector3(+s, h, -s),
btVector3(-s, h, +s),
btVector3(+s, h, +s),
10,10,
0, true);
psb2->getCollisionShape()->setMargin(0.1);
psb2->generateBendingConstraints(2);
psb2->setTotalMass(1);
psb2->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb2->m_cfg.kCHR = 1; // collision hardness with rigid body
psb2->m_cfg.kDF = 0.5;
psb2->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
psb2->m_cfg.collisions |= btSoftBody::fCollision::VF_DD;
psb->translate(btVector3(3.5,0,0));
getDeformableDynamicsWorld()->addSoftBody(psb2);
btDeformableMassSpringForce* mass_spring2 = new btDeformableMassSpringForce(10,1, true);
getDeformableDynamicsWorld()->addForce(psb2, mass_spring2);
m_forces.push_back(mass_spring2);
btDeformableGravityForce* gravity_force2 = new btDeformableGravityForce(gravity);
getDeformableDynamicsWorld()->addForce(psb2, gravity_force2);
m_forces.push_back(gravity_force2);
}
getDeformableDynamicsWorld()->setImplicit(false);
getDeformableDynamicsWorld()->setLineSearch(false);
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
int numInstances = m_guiHelper->getRenderInterface()->getTotalNumInstances();
double rgbaColors[3][4] = { { 1, 0, 0, 1 } , { 0, 1, 0, 1 } ,{ 0, 0, 1, 1 } };
for (int i = 0; i < numInstances; i++)
{
m_guiHelper->changeInstanceFlags(i, B3_INSTANCE_DOUBLE_SIDED);
}
}
void DeformableContact::exitPhysics()
{
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
int i;
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
m_dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
// delete forces
for (int j = 0; j < m_forces.size(); j++)
{
btDeformableLagrangianForce* force = m_forces[j];
delete force;
}
m_forces.clear();
//delete collision shapes
for (int j = 0; j < m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
}
m_collisionShapes.clear();
delete m_dynamicsWorld;
delete m_solver;
delete m_broadphase;
delete m_dispatcher;
delete m_collisionConfiguration;
}
class CommonExampleInterface* DeformableContactCreateFunc(struct CommonExampleOptions& options)
{
return new DeformableContact(options.m_guiHelper);
}

View File

@@ -0,0 +1,19 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef DEFORMABLE_CONTACT_H
#define DEFORMABLE_CONTACT_H
class CommonExampleInterface* DeformableContactCreateFunc(struct CommonExampleOptions& options);
#endif //_DEFORMABLE_CONTACT_H

View File

@@ -0,0 +1,402 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "DeformableMultibody.h"
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
#include "btBulletDynamicsCommon.h"
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
#include "BulletSoftBody/btSoftBody.h"
#include "BulletSoftBody/btSoftBodyHelpers.h"
#include "BulletSoftBody/btDeformableBodySolver.h"
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
#include <stdio.h> //printf debugging
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../Utils/b3ResourcePath.h"
#include "../SoftDemo/BunnyMesh.h"
#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h"
#include "BulletDynamics/Featherstone/btMultiBodyJointFeedback.h"
#include "../CommonInterfaces/CommonMultiBodyBase.h"
#include "../Utils/b3ResourcePath.h"
///The DeformableMultibody demo deformable bodies self-collision
static bool g_floatingBase = true;
static float friction = 1.;
class DeformableMultibody : public CommonMultiBodyBase
{
btAlignedObjectArray<btDeformableLagrangianForce*> m_forces;
public:
DeformableMultibody(struct GUIHelperInterface* helper)
: CommonMultiBodyBase(helper)
{
}
virtual ~DeformableMultibody()
{
}
void initPhysics();
void exitPhysics();
void resetCamera()
{
float dist = 30;
float pitch = -30;
float yaw = 100;
float targetPos[3] = {0, -10, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
virtual void stepSimulation(float deltaTime);
btMultiBody* createFeatherstoneMultiBody_testMultiDof(class btMultiBodyDynamicsWorld* world, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical = false, bool floating = false);
void addColliders_testMultiDof(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents);
virtual const btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld() const
{
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld()
{
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual void renderScene()
{
CommonMultiBodyBase::renderScene();
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
{
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
{
btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), fDrawFlags::Faces);// deformableWorld->getDrawFlags());
}
}
}
};
void DeformableMultibody::initPhysics()
{
m_guiHelper->setUpAxis(1);
///collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
btDeformableMultiBodyConstraintSolver* sol;
sol = new btDeformableMultiBodyConstraintSolver;
sol->setDeformableSolver(deformableBodySolver);
m_solver = sol;
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
btVector3 gravity = btVector3(0, -10, 0);
m_dynamicsWorld->setGravity(gravity);
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.Reset();
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
{
///create a ground
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0, -40, 0));
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
btScalar mass(0.);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
groundShape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
body->setFriction(0.5);
//add the ground to the dynamics world
m_dynamicsWorld->addRigidBody(body,1,1+2);
}
{
bool damping = true;
bool gyro = false;
int numLinks = 4;
bool spherical = false; //set it ot false -to use 1DoF hinges instead of 3DoF sphericals
bool canSleep = false;
bool selfCollide = true;
btVector3 linkHalfExtents(.4, 1, .4);
btVector3 baseHalfExtents(.4, 1, .4);
btMultiBody* mbC = createFeatherstoneMultiBody_testMultiDof(m_dynamicsWorld, numLinks, btVector3(0.f, 10.f,0.f), linkHalfExtents, baseHalfExtents, spherical, g_floatingBase);
mbC->setCanSleep(canSleep);
mbC->setHasSelfCollision(selfCollide);
mbC->setUseGyroTerm(gyro);
//
if (!damping)
{
mbC->setLinearDamping(0.0f);
mbC->setAngularDamping(0.0f);
}
else
{
mbC->setLinearDamping(0.04f);
mbC->setAngularDamping(0.04f);
}
if (numLinks > 0)
{
btScalar q0 = 0.f * SIMD_PI / 180.f;
if (!spherical)
{
mbC->setJointPosMultiDof(0, &q0);
}
else
{
btQuaternion quat0(btVector3(1, 1, 0).normalized(), q0);
quat0.normalize();
mbC->setJointPosMultiDof(0, quat0);
}
}
///
addColliders_testMultiDof(mbC, m_dynamicsWorld, baseHalfExtents, linkHalfExtents);
}
// create a patch of cloth
{
btScalar h = 0;
const btScalar s = 4;
btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
btVector3(+s, h, -s),
btVector3(-s, h, +s),
btVector3(+s, h, +s),
20,20,
// 3,3,
1 + 2 + 4 + 8, true);
psb->getCollisionShape()->setMargin(0.25);
psb->generateBendingConstraints(2);
psb->setTotalMass(1);
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
psb->m_cfg.kDF = 2;
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
psb->setCollisionFlags(0);
getDeformableDynamicsWorld()->addSoftBody(psb);
btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(30, 1, true);
getDeformableDynamicsWorld()->addForce(psb, mass_spring);
m_forces.push_back(mass_spring);
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
m_forces.push_back(gravity_force);
}
getDeformableDynamicsWorld()->setImplicit(false);
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void DeformableMultibody::exitPhysics()
{
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
int i;
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
m_dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
// delete forces
for (int j = 0; j < m_forces.size(); j++)
{
btDeformableLagrangianForce* force = m_forces[j];
delete force;
}
m_forces.clear();
//delete collision shapes
for (int j = 0; j < m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
}
m_collisionShapes.clear();
delete m_dynamicsWorld;
delete m_solver;
delete m_broadphase;
delete m_dispatcher;
delete m_collisionConfiguration;
}
void DeformableMultibody::stepSimulation(float deltaTime)
{
// getDeformableDynamicsWorld()->getMultiBodyDynamicsWorld()->stepSimulation(deltaTime);
m_dynamicsWorld->stepSimulation(deltaTime, 5, 1./250.);
}
btMultiBody* DeformableMultibody::createFeatherstoneMultiBody_testMultiDof(btMultiBodyDynamicsWorld* pWorld, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical, bool floating)
{
//init the base
btVector3 baseInertiaDiag(0.f, 0.f, 0.f);
float baseMass = .1f;
if (baseMass)
{
btCollisionShape* pTempBox = new btBoxShape(btVector3(baseHalfExtents[0], baseHalfExtents[1], baseHalfExtents[2]));
pTempBox->calculateLocalInertia(baseMass, baseInertiaDiag);
delete pTempBox;
}
bool canSleep = false;
btMultiBody* pMultiBody = new btMultiBody(numLinks, baseMass, baseInertiaDiag, !floating, canSleep);
btQuaternion baseOriQuat(0.f, 0.f, 0.f, 1.f);
pMultiBody->setBasePos(basePosition);
pMultiBody->setWorldToBaseRot(baseOriQuat);
btVector3 vel(0, 0, 0);
// pMultiBody->setBaseVel(vel);
//init the links
btVector3 hingeJointAxis(1, 0, 0);
float linkMass = .1f;
btVector3 linkInertiaDiag(0.f, 0.f, 0.f);
btCollisionShape* pTempBox = new btBoxShape(btVector3(linkHalfExtents[0], linkHalfExtents[1], linkHalfExtents[2]));
pTempBox->calculateLocalInertia(linkMass, linkInertiaDiag);
delete pTempBox;
//y-axis assumed up
btVector3 parentComToCurrentCom(0, -linkHalfExtents[1] * 2.f, 0); //par body's COM to cur body's COM offset
btVector3 currentPivotToCurrentCom(0, -linkHalfExtents[1], 0); //cur body's COM to cur body's PIV offset
btVector3 parentComToCurrentPivot = parentComToCurrentCom - currentPivotToCurrentCom; //par body's COM to cur body's PIV offset
//////
btScalar q0 = 0.f * SIMD_PI / 180.f;
btQuaternion quat0(btVector3(0, 1, 0).normalized(), q0);
quat0.normalize();
/////
for (int i = 0; i < numLinks; ++i)
{
if (!spherical)
pMultiBody->setupRevolute(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), hingeJointAxis, parentComToCurrentPivot, currentPivotToCurrentCom, true);
else
//pMultiBody->setupPlanar(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f)/*quat0*/, btVector3(1, 0, 0), parentComToCurrentPivot*2, false);
pMultiBody->setupSpherical(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), parentComToCurrentPivot, currentPivotToCurrentCom, true);
}
pMultiBody->finalizeMultiDof();
///
pWorld->addMultiBody(pMultiBody);
///
return pMultiBody;
}
void DeformableMultibody::addColliders_testMultiDof(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents)
{
btAlignedObjectArray<btQuaternion> world_to_local;
world_to_local.resize(pMultiBody->getNumLinks() + 1);
btAlignedObjectArray<btVector3> local_origin;
local_origin.resize(pMultiBody->getNumLinks() + 1);
world_to_local[0] = pMultiBody->getWorldToBaseRot();
local_origin[0] = pMultiBody->getBasePos();
{
btScalar quat[4] = {-world_to_local[0].x(), -world_to_local[0].y(), -world_to_local[0].z(), world_to_local[0].w()};
btCollisionShape* box = new btBoxShape(baseHalfExtents);
btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, -1);
col->setCollisionShape(box);
btTransform tr;
tr.setIdentity();
tr.setOrigin(local_origin[0]);
tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
col->setWorldTransform(tr);
pWorld->addCollisionObject(col, 2, 1 + 2);
col->setFriction(friction);
pMultiBody->setBaseCollider(col);
}
for (int i = 0; i < pMultiBody->getNumLinks(); ++i)
{
const int parent = pMultiBody->getParent(i);
world_to_local[i + 1] = pMultiBody->getParentToLocalRot(i) * world_to_local[parent + 1];
local_origin[i + 1] = local_origin[parent + 1] + (quatRotate(world_to_local[i + 1].inverse(), pMultiBody->getRVector(i)));
}
for (int i = 0; i < pMultiBody->getNumLinks(); ++i)
{
btVector3 posr = local_origin[i + 1];
btScalar quat[4] = {-world_to_local[i + 1].x(), -world_to_local[i + 1].y(), -world_to_local[i + 1].z(), world_to_local[i + 1].w()};
btCollisionShape* box = new btBoxShape(linkHalfExtents);
btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, i);
col->setCollisionShape(box);
btTransform tr;
tr.setIdentity();
tr.setOrigin(posr);
tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
col->setWorldTransform(tr);
col->setFriction(friction);
pWorld->addCollisionObject(col, 2, 1 + 2);
pMultiBody->getLink(i).m_collider = col;
}
}
class CommonExampleInterface* DeformableMultibodyCreateFunc(struct CommonExampleOptions& options)
{
return new DeformableMultibody(options.m_guiHelper);
}

View File

@@ -0,0 +1,19 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _DEFORMABLE_MULTIBODY_H
#define _DEFORMABLE_MULTIBODY_H
class CommonExampleInterface* DeformableMultibodyCreateFunc(struct CommonExampleOptions& options);
#endif //_DEFORMABLE_MULTIBODY_H

View File

@@ -0,0 +1,291 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "DeformableRigid.h"
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
#include "btBulletDynamicsCommon.h"
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
#include "BulletSoftBody/btSoftBody.h"
#include "BulletSoftBody/btSoftBodyHelpers.h"
#include "BulletSoftBody/btDeformableBodySolver.h"
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
#include <stdio.h> //printf debugging
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../Utils/b3ResourcePath.h"
///The DeformableRigid shows contact between deformable objects and rigid objects.
class DeformableRigid : public CommonRigidBodyBase
{
btAlignedObjectArray<btDeformableLagrangianForce*> m_forces;
public:
DeformableRigid(struct GUIHelperInterface* helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~DeformableRigid()
{
}
void initPhysics();
void exitPhysics();
void resetCamera()
{
float dist = 20;
float pitch = -45;
float yaw = 100;
float targetPos[3] = {0, -3, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
void stepSimulation(float deltaTime)
{
//use a smaller internal timestep, there are stability issues
float internalTimeStep = 1. / 240.f;
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
}
void Ctor_RbUpStack(int count)
{
float mass = 0.2;
btCompoundShape* cylinderCompound = new btCompoundShape;
btCollisionShape* cylinderShape = new btCylinderShapeX(btVector3(2, .5, .5));
btCollisionShape* boxShape = new btBoxShape(btVector3(2, .5, .5));
btTransform localTransform;
localTransform.setIdentity();
cylinderCompound->addChildShape(localTransform, boxShape);
btQuaternion orn(SIMD_HALF_PI, 0, 0);
localTransform.setRotation(orn);
// localTransform.setOrigin(btVector3(1,1,1));
cylinderCompound->addChildShape(localTransform, cylinderShape);
btCollisionShape* shape[] = {
new btBoxShape(btVector3(1, 1, 1)),
// new btSphereShape(0.75),
// cylinderCompound
};
// static const int nshapes = sizeof(shape) / sizeof(shape[0]);
// for (int i = 0; i < count; ++i)
// {
// btTransform startTransform;
// startTransform.setIdentity();
// startTransform.setOrigin(btVector3(0, 2+ 2 * i, 0));
// startTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
// createRigidBody(mass, startTransform, shape[i % nshapes]);
// }
btTransform startTransform;
startTransform.setIdentity();
startTransform.setOrigin(btVector3(1, 1.5, 1));
createRigidBody(mass, startTransform, shape[0]);
startTransform.setOrigin(btVector3(1, 1.5, -1));
createRigidBody(mass, startTransform, shape[0]);
startTransform.setOrigin(btVector3(-1, 1.5, 1));
createRigidBody(mass, startTransform, shape[0]);
startTransform.setOrigin(btVector3(-1, 1.5, -1));
createRigidBody(mass, startTransform, shape[0]);
startTransform.setOrigin(btVector3(0, 3.5, 0));
createRigidBody(mass, startTransform, shape[0]);
}
virtual const btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld() const
{
///just make it a btSoftRigidDynamicsWorld please
///or we will add type checking
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld()
{
///just make it a btSoftRigidDynamicsWorld please
///or we will add type checking
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual void renderScene()
{
CommonRigidBodyBase::renderScene();
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
{
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
//if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
{
btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), fDrawFlags::Faces);// deformableWorld->getDrawFlags());
}
}
}
};
void DeformableRigid::initPhysics()
{
m_guiHelper->setUpAxis(1);
///collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
sol->setDeformableSolver(deformableBodySolver);
m_solver = sol;
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
// deformableBodySolver->setWorld(getDeformableDynamicsWorld());
// m_dynamicsWorld->getSolverInfo().m_singleAxisDeformableThreshold = 0.f;//faster but lower quality
btVector3 gravity = btVector3(0, -10, 0);
m_dynamicsWorld->setGravity(gravity);
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.Reset();
// getDeformableDynamicsWorld()->before_solver_callbacks.push_back(dynamics);
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
{
///create a ground
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0, -32, 0));
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
btScalar mass(0.);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
groundShape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
body->setFriction(1);
//add the ground to the dynamics world
m_dynamicsWorld->addRigidBody(body);
}
// create a piece of cloth
{
bool onGround = false;
const btScalar s = 4;
const btScalar h = 0;
btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
btVector3(+s, h, -s),
btVector3(-s, h, +s),
btVector3(+s, h, +s),
// 3,3,
20,20,
1 + 2 + 4 + 8, true);
// 0, true);
if (onGround)
psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, 0, -s),
btVector3(+s, 0, -s),
btVector3(-s, 0, +s),
btVector3(+s, 0, +s),
// 20,20,
2,2,
0, true);
psb->getCollisionShape()->setMargin(0.1);
psb->generateBendingConstraints(2);
psb->setTotalMass(1);
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
psb->m_cfg.kDF = .4;
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
getDeformableDynamicsWorld()->addSoftBody(psb);
btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(30,1, true);
getDeformableDynamicsWorld()->addForce(psb, mass_spring);
m_forces.push_back(mass_spring);
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
m_forces.push_back(gravity_force);
// add a few rigid bodies
Ctor_RbUpStack(1);
}
getDeformableDynamicsWorld()->setImplicit(false);
getDeformableDynamicsWorld()->setLineSearch(false);
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void DeformableRigid::exitPhysics()
{
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
int i;
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
m_dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
// delete forces
for (int j = 0; j < m_forces.size(); j++)
{
btDeformableLagrangianForce* force = m_forces[j];
delete force;
}
m_forces.clear();
//delete collision shapes
for (int j = 0; j < m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
}
m_collisionShapes.clear();
delete m_dynamicsWorld;
delete m_solver;
delete m_broadphase;
delete m_dispatcher;
delete m_collisionConfiguration;
}
class CommonExampleInterface* DeformableRigidCreateFunc(struct CommonExampleOptions& options)
{
return new DeformableRigid(options.m_guiHelper);
}

View File

@@ -0,0 +1,19 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _DEFORMABLE_RIGID_H
#define _DEFORMABLE_RIGID_H
class CommonExampleInterface* DeformableRigidCreateFunc(struct CommonExampleOptions& options);
#endif //_DEFORMABLE_RIGID_H

View File

@@ -0,0 +1,234 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "DeformableSelfCollision.h"
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
#include "btBulletDynamicsCommon.h"
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
#include "BulletSoftBody/btSoftBody.h"
#include "BulletSoftBody/btSoftBodyHelpers.h"
#include "BulletSoftBody/btDeformableBodySolver.h"
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
#include <stdio.h> //printf debugging
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../Utils/b3ResourcePath.h"
///The DeformableSelfCollision shows deformable self collisions
class DeformableSelfCollision : public CommonRigidBodyBase
{
btAlignedObjectArray<btDeformableLagrangianForce*> m_forces;
public:
DeformableSelfCollision(struct GUIHelperInterface* helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~DeformableSelfCollision()
{
}
void initPhysics();
void exitPhysics();
void resetCamera()
{
float dist = 10;
float pitch = -8;
float yaw = 100;
float targetPos[3] = {0, -10, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
void stepSimulation(float deltaTime)
{
float internalTimeStep = 1. / 240.f;
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
}
virtual const btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld() const
{
///just make it a btSoftRigidDynamicsWorld please
///or we will add type checking
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld()
{
///just make it a btSoftRigidDynamicsWorld please
///or we will add type checking
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual void renderScene()
{
CommonRigidBodyBase::renderScene();
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
{
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
{
btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), fDrawFlags::Faces);// deformableWorld->getDrawFlags());
}
}
}
};
void DeformableSelfCollision::initPhysics()
{
m_guiHelper->setUpAxis(1);
///collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
sol->setDeformableSolver(deformableBodySolver);
m_solver = sol;
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
// deformableBodySolver->setWorld(getDeformableDynamicsWorld());
// m_dynamicsWorld->getSolverInfo().m_singleAxisDeformableThreshold = 0.f;//faster but lower quality
btVector3 gravity = btVector3(0, -100, 0);
m_dynamicsWorld->setGravity(gravity);
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
// getDeformableDynamicsWorld()->before_solver_callbacks.push_back(dynamics);
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
{
///create a ground
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0, -35, 0));
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
btScalar mass(0.);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
groundShape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
body->setFriction(40);
//add the ground to the dynamics world
m_dynamicsWorld->addRigidBody(body);
}
// create a piece of cloth
{
const btScalar s = 2;
const btScalar h = 0;
btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -4*s),
btVector3(+s, h, -4*s),
btVector3(-s, h, +4*s),
btVector3(+s, h, +4*s),
10,40,
0, true, 0.01);
psb->getCollisionShape()->setMargin(0.2);
psb->generateBendingConstraints(2);
psb->setTotalMass(1);
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
psb->m_cfg.kDF = 0.2;
psb->rotate(btQuaternion(0,SIMD_PI / 2, 0));
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
psb->m_cfg.collisions |= btSoftBody::fCollision::VF_DD;
getDeformableDynamicsWorld()->addSoftBody(psb);
psb->setSelfCollision(true);
btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(10,0.2, true);
getDeformableDynamicsWorld()->addForce(psb, mass_spring);
m_forces.push_back(mass_spring);
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
m_forces.push_back(gravity_force);
}
getDeformableDynamicsWorld()->setImplicit(false);
getDeformableDynamicsWorld()->setLineSearch(false);
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void DeformableSelfCollision::exitPhysics()
{
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
int i;
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
m_dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
// delete forces
for (int j = 0; j < m_forces.size(); j++)
{
btDeformableLagrangianForce* force = m_forces[j];
delete force;
}
m_forces.clear();
//delete collision shapes
for (int j = 0; j < m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
}
m_collisionShapes.clear();
delete m_dynamicsWorld;
delete m_solver;
delete m_broadphase;
delete m_dispatcher;
delete m_collisionConfiguration;
}
class CommonExampleInterface* DeformableSelfCollisionCreateFunc(struct CommonExampleOptions& options)
{
return new DeformableSelfCollision(options.m_guiHelper);
}

View File

@@ -0,0 +1,19 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef DEFORMABLE_SELF_COLLISION_H
#define DEFORMABLE_SELF_COLLISION_H
class CommonExampleInterface* DeformableSelfCollisionCreateFunc(struct CommonExampleOptions& options);
#endif //_DEFORMABLE_SELF_COLLISION_H

View File

@@ -0,0 +1,545 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "GraspDeformable.h"
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
#include "btBulletDynamicsCommon.h"
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
#include "BulletSoftBody/btSoftBody.h"
#include "BulletSoftBody/btSoftBodyHelpers.h"
#include "BulletSoftBody/btDeformableBodySolver.h"
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
#include "BulletDynamics/Featherstone/btMultiBodyJointMotor.h"
#include <stdio.h> //printf debugging
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../Utils/b3ResourcePath.h"
#include "../Importers/ImportURDFDemo/BulletUrdfImporter.h"
#include "../Importers/ImportURDFDemo/MyMultiBodyCreator.h"
#include "../Importers/ImportURDFDemo/URDF2Bullet.h"
#include "../Utils/b3BulletDefaultFileIO.h"
#include "../CommonInterfaces/CommonMultiBodyBase.h"
#include "../CommonInterfaces/CommonGraphicsAppInterface.h"
#include "../CommonInterfaces/CommonParameterInterface.h"
#include "../CommonInterfaces/CommonFileIOInterface.h"
#include "Bullet3Common/b3FileUtils.h"
///The GraspDeformable shows grasping a volumetric deformable objects with multibody gripper with moter constraints.
static btScalar sGripperVerticalVelocity = 0.f;
static btScalar sGripperClosingTargetVelocity = 0.f;
static float friction = 1.;
struct TetraCube
{
#include "../SoftDemo/cube.inl"
};
struct TetraBunny
{
#include "../SoftDemo/bunny.inl"
};
static bool supportsJointMotor(btMultiBody* mb, int mbLinkIndex)
{
bool canHaveMotor = (mb->getLink(mbLinkIndex).m_jointType == btMultibodyLink::eRevolute
|| mb->getLink(mbLinkIndex).m_jointType == btMultibodyLink::ePrismatic);
return canHaveMotor;
}
class GraspDeformable : public CommonRigidBodyBase
{
btAlignedObjectArray<btDeformableLagrangianForce*> m_forces;
public:
GraspDeformable(struct GUIHelperInterface* helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~GraspDeformable()
{
}
void initPhysics();
void exitPhysics();
void resetCamera()
{
float dist = 2;
float pitch = -45;
float yaw = 100;
float targetPos[3] = {0, -0, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
btMultiBody* createFeatherstoneMultiBody(btMultiBodyDynamicsWorld* pWorld,const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool floating);
void addColliders(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents);
btMultiBody* createFeatherstoneMultiBody_testMultiDof(btMultiBodyDynamicsWorld* pWorld, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical, bool floating);
void stepSimulation(float deltaTime)
{
double fingerTargetVelocities[2] = {sGripperVerticalVelocity, sGripperClosingTargetVelocity};
int num_multiBody = getDeformableDynamicsWorld()->getNumMultibodies();
for (int i = 0; i < num_multiBody; ++i)
{
btMultiBody* mb = getDeformableDynamicsWorld()->btMultiBodyDynamicsWorld::getMultiBody(i);
mb->setBaseVel(btVector3(0,sGripperVerticalVelocity, 0));
int dofIndex = 6; //skip the 3 linear + 3 angular degree of freedom entries of the base
for (int link = 0; link < mb->getNumLinks(); link++)
{
if (supportsJointMotor(mb, link))
{
btMultiBodyJointMotor* motor = (btMultiBodyJointMotor*)mb->getLink(link).m_userPtr;
if (motor)
{
if (dofIndex == 6)
{
motor->setVelocityTarget(-fingerTargetVelocities[1], 1);
motor->setMaxAppliedImpulse(2);
}
if (dofIndex == 7)
{
motor->setVelocityTarget(fingerTargetVelocities[1], 1);
motor->setMaxAppliedImpulse(2);
}
motor->setMaxAppliedImpulse(1);
}
}
dofIndex += mb->getLink(link).m_dofCount;
}
}
//use a smaller internal timestep, there are stability issues
float internalTimeStep = 1. / 240.f;
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
}
void createGrip()
{
int count = 2;
float mass = 2;
btCollisionShape* shape[] = {
new btBoxShape(btVector3(3, 3, 0.5)),
};
static const int nshapes = sizeof(shape) / sizeof(shape[0]);
for (int i = 0; i < count; ++i)
{
btTransform startTransform;
startTransform.setIdentity();
startTransform.setOrigin(btVector3(10, 0, 0));
startTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
createRigidBody(mass, startTransform, shape[i % nshapes]);
}
}
virtual const btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld() const
{
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld()
{
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual void renderScene()
{
CommonRigidBodyBase::renderScene();
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
{
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
{
btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), fDrawFlags::Faces);// deformableWorld->getDrawFlags());
}
}
}
};
void GraspDeformable::initPhysics()
{
m_guiHelper->setUpAxis(1);
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
sol->setDeformableSolver(deformableBodySolver);
m_solver = sol;
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
btVector3 gravity = btVector3(0, -9.81, 0);
m_dynamicsWorld->setGravity(gravity);
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
// build a gripper
if(1)
{
bool damping = true;
bool gyro = false;
bool canSleep = false;
bool selfCollide = true;
int numLinks = 2;
btVector3 linkHalfExtents(.1, .2, .04);
btVector3 baseHalfExtents(.1, 0.02, .2);
btMultiBody* mbC = createFeatherstoneMultiBody(getDeformableDynamicsWorld(), btVector3(0.f, .7f,0.f), linkHalfExtents, baseHalfExtents, false);
mbC->setCanSleep(canSleep);
mbC->setHasSelfCollision(selfCollide);
mbC->setUseGyroTerm(gyro);
for (int i = 0; i < numLinks; i++)
{
int mbLinkIndex = i;
float maxMotorImpulse = 1.f;
if (supportsJointMotor(mbC, mbLinkIndex))
{
int dof = 0;
btScalar desiredVelocity = 0.f;
btMultiBodyJointMotor* motor = new btMultiBodyJointMotor(mbC, mbLinkIndex, dof, desiredVelocity, maxMotorImpulse);
motor->setPositionTarget(0, 0);
motor->setVelocityTarget(0, 1);
mbC->getLink(mbLinkIndex).m_userPtr = motor;
getDeformableDynamicsWorld()->addMultiBodyConstraint(motor);
motor->finalizeMultiDof();
}
}
if (!damping)
{
mbC->setLinearDamping(0.0f);
mbC->setAngularDamping(0.0f);
}
else
{
mbC->setLinearDamping(0.04f);
mbC->setAngularDamping(0.04f);
}
btScalar q0 = 0.f * SIMD_PI / 180.f;
if (numLinks > 0)
mbC->setJointPosMultiDof(0, &q0);
addColliders(mbC, getDeformableDynamicsWorld(), baseHalfExtents, linkHalfExtents);
}
//create a ground
{
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0, -25-.6, 0));
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
btScalar mass(0.);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
groundShape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
body->setFriction(0.1);
//add the ground to the dynamics world
m_dynamicsWorld->addRigidBody(body,1,1+2);
}
// create a soft block
if (1)
{
char absolute_path[1024];
b3BulletDefaultFileIO fileio;
fileio.findResourcePath("ditto.vtk", absolute_path, 1024);
// fileio.findResourcePath("banana.vtk", absolute_path, 1024);
// fileio.findResourcePath("ball.vtk", absolute_path, 1024);
// fileio.findResourcePath("deformable_crumpled_napkin_sim.vtk", absolute_path, 1024);
// fileio.findResourcePath("single_tet.vtk", absolute_path, 1024);
// fileio.findResourcePath("tube.vtk", absolute_path, 1024);
// fileio.findResourcePath("torus.vtk", absolute_path, 1024);
// fileio.findResourcePath("paper_roll.vtk", absolute_path, 1024);
// fileio.findResourcePath("bread.vtk", absolute_path, 1024);
// fileio.findResourcePath("boot.vtk", absolute_path, 1024);
// btSoftBody* psb = btSoftBodyHelpers::CreateFromTetGenData(getDeformableDynamicsWorld()->getWorldInfo(),
// TetraCube::getElements(),
// 0,
// TetraCube::getNodes(),
// false, true, true);
btSoftBody* psb = btSoftBodyHelpers::CreateFromVtkFile(getDeformableDynamicsWorld()->getWorldInfo(), absolute_path);
// psb->scale(btVector3(30, 30, 30)); // for banana
psb->scale(btVector3(.7, .7, .7));
// psb->scale(btVector3(2, 2, 2));
// psb->scale(btVector3(.3, .3, .3)); // for tube, torus, boot
psb->scale(btVector3(.1, .1, .1)); // for ditto
// psb->translate(btVector3(.25, 10, 0.4));
psb->getCollisionShape()->setMargin(0.0005);
psb->setMaxStress(50);
psb->setTotalMass(.01);
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
psb->m_cfg.kDF = 20;
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
getDeformableDynamicsWorld()->addSoftBody(psb);
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
m_forces.push_back(gravity_force);
btDeformableNeoHookeanForce* neohookean = new btDeformableNeoHookeanForce(8,32, .05);
getDeformableDynamicsWorld()->addForce(psb, neohookean);
m_forces.push_back(neohookean);
}
getDeformableDynamicsWorld()->setImplicit(false);
// create a piece of cloth
if(0)
{
bool onGround = false;
const btScalar s = .1;
const btScalar h = 1;
btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
btVector3(+s, h, -s),
btVector3(-s, h, +s),
btVector3(+s, h, +s),
20,20,
0, true);
if (onGround)
psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, 0, -s),
btVector3(+s, 0, -s),
btVector3(-s, 0, +s),
btVector3(+s, 0, +s),
// 20,20,
2,2,
0, true);
psb->getCollisionShape()->setMargin(0.005);
psb->generateBendingConstraints(2);
psb->setTotalMass(.01);
psb->setSpringStiffness(10);
psb->setDampingCoefficient(0.05);
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
psb->m_cfg.kDF = 1;
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
psb->m_cfg.collisions |= btSoftBody::fCollision::VF_DD;
getDeformableDynamicsWorld()->addSoftBody(psb);
// getDeformableDynamicsWorld()->addForce(psb, new btDeformableMassSpringForce(.0,0.0, true));
getDeformableDynamicsWorld()->addForce(psb, new btDeformableMassSpringForce(1,0.05, false));
getDeformableDynamicsWorld()->addForce(psb, new btDeformableGravityForce(gravity));
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
{
SliderParams slider("Moving velocity", &sGripperVerticalVelocity);
slider.m_minVal = -.2;
slider.m_maxVal = .2;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{
SliderParams slider("Closing velocity", &sGripperClosingTargetVelocity);
slider.m_minVal = -.3;
slider.m_maxVal = .3;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
}
void GraspDeformable::exitPhysics()
{
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
int i;
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
m_dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
// delete forces
for (int j = 0; j < m_forces.size(); j++)
{
btDeformableLagrangianForce* force = m_forces[j];
delete force;
}
m_forces.clear();
//delete collision shapes
for (int j = 0; j < m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
}
m_collisionShapes.clear();
delete m_dynamicsWorld;
delete m_solver;
delete m_broadphase;
delete m_dispatcher;
delete m_collisionConfiguration;
}
btMultiBody* GraspDeformable::createFeatherstoneMultiBody(btMultiBodyDynamicsWorld* pWorld, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool floating)
{
//init the base
btVector3 baseInertiaDiag(0.f, 0.f, 0.f);
float baseMass = 100.f;
float linkMass = 100.f;
int numLinks = 2;
if (baseMass)
{
btCollisionShape* pTempBox = new btBoxShape(btVector3(baseHalfExtents[0], baseHalfExtents[1], baseHalfExtents[2]));
pTempBox->calculateLocalInertia(baseMass, baseInertiaDiag);
delete pTempBox;
}
bool canSleep = false;
btMultiBody* pMultiBody = new btMultiBody(numLinks, baseMass, baseInertiaDiag, !floating, canSleep);
btQuaternion baseOriQuat(0.f, 0.f, 0.f, 1.f);
pMultiBody->setBasePos(basePosition);
pMultiBody->setWorldToBaseRot(baseOriQuat);
//init the links
btVector3 hingeJointAxis(1, 0, 0);
btVector3 linkInertiaDiag(0.f, 0.f, 0.f);
btCollisionShape* pTempBox = new btBoxShape(btVector3(linkHalfExtents[0], linkHalfExtents[1], linkHalfExtents[2]));
pTempBox->calculateLocalInertia(linkMass, linkInertiaDiag);
delete pTempBox;
//y-axis assumed up
btAlignedObjectArray<btVector3> parentComToCurrentCom;
parentComToCurrentCom.push_back(btVector3(0, -linkHalfExtents[1] * 8.f, -baseHalfExtents[2] * 4.f));
parentComToCurrentCom.push_back(btVector3(0, -linkHalfExtents[1] * 8.f, +baseHalfExtents[2] * 4.f));//par body's COM to cur body's COM offset
btVector3 currentPivotToCurrentCom(0, -linkHalfExtents[1]*8.f, 0); //cur body's COM to cur body's PIV offset
btAlignedObjectArray<btVector3> parentComToCurrentPivot;
parentComToCurrentPivot.push_back(btVector3(parentComToCurrentCom[0] - currentPivotToCurrentCom));
parentComToCurrentPivot.push_back(btVector3(parentComToCurrentCom[1] - currentPivotToCurrentCom));//par body's COM to cur body's PIV offset
//////
btScalar q0 = 0.f * SIMD_PI / 180.f;
btQuaternion quat0(btVector3(0, 1, 0).normalized(), q0);
quat0.normalize();
/////
for (int i = 0; i < numLinks; ++i)
{
pMultiBody->setupRevolute(i, linkMass, linkInertiaDiag, - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), hingeJointAxis, parentComToCurrentPivot[i], currentPivotToCurrentCom, true);
}
pMultiBody->finalizeMultiDof();
///
pWorld->addMultiBody(pMultiBody);
///
return pMultiBody;
}
void GraspDeformable::addColliders(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents)
{
btAlignedObjectArray<btQuaternion> world_to_local;
world_to_local.resize(pMultiBody->getNumLinks() + 1);
btAlignedObjectArray<btVector3> local_origin;
local_origin.resize(pMultiBody->getNumLinks() + 1);
world_to_local[0] = pMultiBody->getWorldToBaseRot();
local_origin[0] = pMultiBody->getBasePos();
{
btScalar quat[4] = {-world_to_local[0].x(), -world_to_local[0].y(), -world_to_local[0].z(), world_to_local[0].w()};
if (1)
{
btCollisionShape* box = new btBoxShape(baseHalfExtents);
btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, -1);
col->setCollisionShape(box);
btTransform tr;
tr.setIdentity();
tr.setOrigin(local_origin[0]);
tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
col->setWorldTransform(tr);
pWorld->addCollisionObject(col, 2, 1 + 2);
col->setFriction(friction);
pMultiBody->setBaseCollider(col);
}
}
for (int i = 0; i < pMultiBody->getNumLinks(); ++i)
{
const int parent = pMultiBody->getParent(i);
world_to_local[i + 1] = pMultiBody->getParentToLocalRot(i) * world_to_local[parent + 1];
local_origin[i + 1] = local_origin[parent + 1] + (quatRotate(world_to_local[i + 1].inverse(), pMultiBody->getRVector(i)));
}
for (int i = 0; i < pMultiBody->getNumLinks(); ++i)
{
btVector3 posr = local_origin[i + 1];
btScalar quat[4] = {-world_to_local[i + 1].x(), -world_to_local[i + 1].y(), -world_to_local[i + 1].z(), world_to_local[i + 1].w()};
btCollisionShape* box = new btBoxShape(linkHalfExtents);
btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, i);
col->setCollisionShape(box);
btTransform tr;
tr.setIdentity();
tr.setOrigin(posr);
tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
col->setWorldTransform(tr);
col->setFriction(friction);
pWorld->addCollisionObject(col, 2, 1 + 2);
pMultiBody->getLink(i).m_collider = col;
}
}
class CommonExampleInterface* GraspDeformableCreateFunc(struct CommonExampleOptions& options)
{
return new GraspDeformable(options.m_guiHelper);
}

View File

@@ -0,0 +1,19 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _GRASP_DEFORMABLE_H
#define _GRASP_DEFORMABLE_H
class CommonExampleInterface* GraspDeformableCreateFunc(struct CommonExampleOptions& options);
#endif //_GRASP_DEFORMABLE_H

View File

@@ -0,0 +1,395 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "MultibodyClothAnchor.h"
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
#include "btBulletDynamicsCommon.h"
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
#include "BulletSoftBody/btSoftBody.h"
#include "BulletSoftBody/btSoftBodyHelpers.h"
#include "BulletSoftBody/btDeformableBodySolver.h"
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
#include <stdio.h> //printf debugging
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../Utils/b3ResourcePath.h"
///The MultibodyClothAnchor shows contact between deformable objects and rigid objects.
class MultibodyClothAnchor : public CommonRigidBodyBase
{
btAlignedObjectArray<btDeformableLagrangianForce*> m_forces;
public:
MultibodyClothAnchor(struct GUIHelperInterface* helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~MultibodyClothAnchor()
{
}
void initPhysics();
void exitPhysics();
void resetCamera()
{
float dist = 20;
float pitch = -45;
float yaw = 100;
float targetPos[3] = {0, -3, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
void stepSimulation(float deltaTime)
{
//use a smaller internal timestep, there are stability issues
float internalTimeStep = 1. / 240.f;
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
}
virtual const btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld() const
{
///just make it a btSoftRigidDynamicsWorld please
///or we will add type checking
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld()
{
///just make it a btSoftRigidDynamicsWorld please
///or we will add type checking
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual void renderScene()
{
CommonRigidBodyBase::renderScene();
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
{
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
//if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
{
btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), fDrawFlags::Faces);// deformableWorld->getDrawFlags());
}
}
}
btMultiBody* createMultiBody(class btMultiBodyDynamicsWorld* world, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical = false, bool floating = false);
void addColliders(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents);
};
void MultibodyClothAnchor::initPhysics()
{
m_guiHelper->setUpAxis(1);
///collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
sol->setDeformableSolver(deformableBodySolver);
m_solver = sol;
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
// deformableBodySolver->setWorld(getDeformableDynamicsWorld());
// m_dynamicsWorld->getSolverInfo().m_singleAxisDeformableThreshold = 0.f;//faster but lower quality
btVector3 gravity = btVector3(0, -20, 0);
m_dynamicsWorld->setGravity(gravity);
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
// getDeformableDynamicsWorld()->before_solver_callbacks.push_back(dynamics);
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
{
///create a ground
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0, -35, 0));
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
btScalar mass(0.);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
groundShape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
body->setFriction(1);
//add the ground to the dynamics world
m_dynamicsWorld->addRigidBody(body,1,1+2);
}
// create a piece of cloth
{
const btScalar s = 4;
const btScalar h = 6;
const int r = 9;
btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
btVector3(+s, h, -s),
btVector3(-s, h, +s),
btVector3(+s, h, +s), r, r, 4 + 8, true);
psb->getCollisionShape()->setMargin(0.1);
psb->generateBendingConstraints(2);
psb->setTotalMass(1);
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
psb->m_cfg.kDF = 2;
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
getDeformableDynamicsWorld()->addSoftBody(psb);
btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(30,1, true);
getDeformableDynamicsWorld()->addForce(psb, mass_spring);
m_forces.push_back(mass_spring);
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
m_forces.push_back(gravity_force);
bool damping = true;
bool gyro = false;
int numLinks = 5;
bool spherical = false; //set it ot false -to use 1DoF hinges instead of 3DoF sphericals
bool canSleep = false;
bool selfCollide = true;
btVector3 linkHalfExtents(1.5, .5, .5);
btVector3 baseHalfExtents(1.5, .5, .5);
btMultiBody* mbC = createMultiBody(getDeformableDynamicsWorld(), numLinks, btVector3(s+3.5f, h, -s-0.6f), linkHalfExtents, baseHalfExtents, spherical, true);
mbC->setCanSleep(canSleep);
mbC->setHasSelfCollision(selfCollide);
mbC->setUseGyroTerm(gyro);
//
if (!damping)
{
mbC->setLinearDamping(0.0f);
mbC->setAngularDamping(0.0f);
}
else
{
mbC->setLinearDamping(0.04f);
mbC->setAngularDamping(0.04f);
}
if (numLinks > 0)
{
btScalar q0 = 0.f * SIMD_PI / 180.f;
if (!spherical)
{
mbC->setJointPosMultiDof(0, &q0);
}
else
{
btQuaternion quat0(btVector3(1, 1, 0).normalized(), q0);
quat0.normalize();
mbC->setJointPosMultiDof(0, quat0);
}
}
///
addColliders(mbC, getDeformableDynamicsWorld(), baseHalfExtents, linkHalfExtents);
// quick hack: advance time to populate the variables in multibody
m_dynamicsWorld->stepSimulation(SIMD_EPSILON, 0);
btAlignedObjectArray<btQuaternion> scratch_q;
btAlignedObjectArray<btVector3> scratch_m;
mbC->forwardKinematics(scratch_q, scratch_m);
psb->appendDeformableAnchor(0, mbC->getLink(3).m_collider);
psb->appendDeformableAnchor(r - 1, mbC->getLink(0).m_collider);
}
getDeformableDynamicsWorld()->setImplicit(false);
getDeformableDynamicsWorld()->setLineSearch(false);
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void MultibodyClothAnchor::exitPhysics()
{
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
int i;
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
m_dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
// delete forces
for (int j = 0; j < m_forces.size(); j++)
{
btDeformableLagrangianForce* force = m_forces[j];
delete force;
}
m_forces.clear();
//delete collision shapes
for (int j = 0; j < m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
}
m_collisionShapes.clear();
delete m_dynamicsWorld;
delete m_solver;
delete m_broadphase;
delete m_dispatcher;
delete m_collisionConfiguration;
}
btMultiBody* MultibodyClothAnchor::createMultiBody(btMultiBodyDynamicsWorld* pWorld, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical, bool floating)
{
//init the base
btVector3 baseInertiaDiag(0.f, 0.f, 0.f);
float baseMass = 1.f;
if (baseMass)
{
btCollisionShape* pTempBox = new btBoxShape(btVector3(baseHalfExtents[0], baseHalfExtents[1], baseHalfExtents[2]));
pTempBox->calculateLocalInertia(baseMass, baseInertiaDiag);
delete pTempBox;
}
bool canSleep = false;
btMultiBody* pMultiBody = new btMultiBody(numLinks, baseMass, baseInertiaDiag, !floating, canSleep);
btQuaternion baseOriQuat(0.f, 0.f, 0.f, 1.f);
pMultiBody->setBasePos(basePosition);
pMultiBody->setWorldToBaseRot(baseOriQuat);
btVector3 vel(0, 0, 0);
//init the links
btVector3 hingeJointAxis(0, 1, 0);
float linkMass = 1.f;
btVector3 linkInertiaDiag(0.f, 0.f, 0.f);
btCollisionShape* pTempBox = new btBoxShape(btVector3(linkHalfExtents[0], linkHalfExtents[1], linkHalfExtents[2]));
pTempBox->calculateLocalInertia(linkMass, linkInertiaDiag);
delete pTempBox;
//y-axis assumed up
btVector3 parentComToCurrentCom(-linkHalfExtents[0] * 2.f, 0, 0); //par body's COM to cur body's COM offset
btVector3 currentPivotToCurrentCom(-linkHalfExtents[0], 0, 0); //cur body's COM to cur body's PIV offset
btVector3 parentComToCurrentPivot = parentComToCurrentCom - currentPivotToCurrentCom; //par body's COM to cur body's PIV offset
//////
btScalar q0 = 0.f * SIMD_PI / 180.f;
btQuaternion quat0(btVector3(0, 1, 0).normalized(), q0);
quat0.normalize();
/////
for (int i = 0; i < numLinks; ++i)
{
if (!spherical)
pMultiBody->setupRevolute(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), hingeJointAxis, parentComToCurrentPivot, currentPivotToCurrentCom, true);
else
pMultiBody->setupSpherical(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), parentComToCurrentPivot, currentPivotToCurrentCom, true);
}
pMultiBody->finalizeMultiDof();
///
pWorld->addMultiBody(pMultiBody);
///
return pMultiBody;
}
void MultibodyClothAnchor::addColliders(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents)
{
btAlignedObjectArray<btQuaternion> world_to_local;
world_to_local.resize(pMultiBody->getNumLinks() + 1);
btAlignedObjectArray<btVector3> local_origin;
local_origin.resize(pMultiBody->getNumLinks() + 1);
world_to_local[0] = pMultiBody->getWorldToBaseRot();
local_origin[0] = pMultiBody->getBasePos();
{
btScalar quat[4] = {-world_to_local[0].x(), -world_to_local[0].y(), -world_to_local[0].z(), world_to_local[0].w()};
btCollisionShape* box = new btBoxShape(baseHalfExtents);
btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, -1);
col->setCollisionShape(box);
btTransform tr;
tr.setIdentity();
tr.setOrigin(local_origin[0]);
tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
col->setWorldTransform(tr);
pWorld->addCollisionObject(col, 2, 1+2);
col->setFriction(1);
pMultiBody->setBaseCollider(col);
}
for (int i = 0; i < pMultiBody->getNumLinks(); ++i)
{
const int parent = pMultiBody->getParent(i);
world_to_local[i + 1] = pMultiBody->getParentToLocalRot(i) * world_to_local[parent + 1];
local_origin[i + 1] = local_origin[parent + 1] + (quatRotate(world_to_local[i + 1].inverse(), pMultiBody->getRVector(i)));
}
for (int i = 0; i < pMultiBody->getNumLinks(); ++i)
{
btVector3 posr = local_origin[i + 1];
btScalar quat[4] = {-world_to_local[i + 1].x(), -world_to_local[i + 1].y(), -world_to_local[i + 1].z(), world_to_local[i + 1].w()};
btCollisionShape* box = new btBoxShape(linkHalfExtents);
btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, i);
col->setCollisionShape(box);
btTransform tr;
tr.setIdentity();
tr.setOrigin(posr);
tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
col->setWorldTransform(tr);
col->setFriction(1);
pWorld->addCollisionObject(col, 2, 1+2);
pMultiBody->getLink(i).m_collider = col;
}
}
class CommonExampleInterface* MultibodyClothAnchorCreateFunc(struct CommonExampleOptions& options)
{
return new MultibodyClothAnchor(options.m_guiHelper);
}

View File

@@ -0,0 +1,19 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef MULTIBODY_CLOTH_ANCHOR_H
#define MULTIBODY_CLOTH_ANCHOR_H
class CommonExampleInterface* MultibodyClothAnchorCreateFunc(struct CommonExampleOptions& options);
#endif //MULTIBODY_CLOTH_ANCHOR_H

View File

@@ -0,0 +1,387 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "Pinch.h"
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
#include "btBulletDynamicsCommon.h"
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
#include "BulletSoftBody/btSoftBody.h"
#include "BulletSoftBody/btSoftBodyHelpers.h"
#include "BulletSoftBody/btDeformableBodySolver.h"
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
#include <stdio.h> //printf debugging
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../Utils/b3ResourcePath.h"
///The Pinch shows the frictional contact between kinematic rigid objects with deformable objects
struct TetraCube
{
#include "../SoftDemo/cube.inl"
};
class Pinch : public CommonRigidBodyBase
{
btAlignedObjectArray<btDeformableLagrangianForce*> m_forces;
public:
Pinch(struct GUIHelperInterface* helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~Pinch()
{
}
void initPhysics();
void exitPhysics();
void resetCamera()
{
float dist = 25;
float pitch = -30;
float yaw = 100;
float targetPos[3] = {0, -0, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
void stepSimulation(float deltaTime)
{
//use a smaller internal timestep, there are stability issues
float internalTimeStep = 1. / 240.f;
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
}
void createGrip()
{
int count = 2;
float mass = 1e6;
btCollisionShape* shape[] = {
new btBoxShape(btVector3(3, 3, 0.5)),
};
static const int nshapes = sizeof(shape) / sizeof(shape[0]);
for (int i = 0; i < count; ++i)
{
btTransform startTransform;
startTransform.setIdentity();
startTransform.setOrigin(btVector3(10, 0, 0));
startTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
createRigidBody(mass, startTransform, shape[i % nshapes]);
}
}
virtual const btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld() const
{
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld()
{
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual void renderScene()
{
CommonRigidBodyBase::renderScene();
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
{
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
{
btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
}
}
}
};
void dynamics(btScalar time, btDeformableMultiBodyDynamicsWorld* world)
{
btAlignedObjectArray<btRigidBody*>& rbs = world->getNonStaticRigidBodies();
if (rbs.size()<2)
return;
btRigidBody* rb0 = rbs[0];
btScalar pressTime = 0.9;
btScalar liftTime = 2.5;
btScalar shiftTime = 3.5;
btScalar holdTime = 4.5*1000;
btScalar dropTime = 5.3*1000;
btTransform rbTransform;
rbTransform.setIdentity();
btVector3 translation;
btVector3 velocity;
btVector3 initialTranslationLeft = btVector3(0.5,3,4);
btVector3 initialTranslationRight = btVector3(0.5,3,-4);
btVector3 pinchVelocityLeft = btVector3(0,0,-2);
btVector3 pinchVelocityRight = btVector3(0,0,2);
btVector3 liftVelocity = btVector3(0,5,0);
btVector3 shiftVelocity = btVector3(0,0,5);
btVector3 holdVelocity = btVector3(0,0,0);
btVector3 openVelocityLeft = btVector3(0,0,4);
btVector3 openVelocityRight = btVector3(0,0,-4);
if (time < pressTime)
{
velocity = pinchVelocityLeft;
translation = initialTranslationLeft + pinchVelocityLeft * time;
}
else if (time < liftTime)
{
velocity = liftVelocity;
translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (time - pressTime);
}
else if (time < shiftTime)
{
velocity = shiftVelocity;
translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (time - liftTime);
}
else if (time < holdTime)
{
velocity = btVector3(0,0,0);
translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (time - shiftTime);
}
else if (time < dropTime)
{
velocity = openVelocityLeft;
translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityLeft * (time - holdTime);
}
else
{
velocity = holdVelocity;
translation = initialTranslationLeft + pinchVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityLeft * (dropTime - holdTime);
}
rbTransform.setOrigin(translation);
rbTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
rb0->setCenterOfMassTransform(rbTransform);
rb0->setAngularVelocity(btVector3(0,0,0));
rb0->setLinearVelocity(velocity);
btRigidBody* rb1 = rbs[1];
if (time < pressTime)
{
velocity = pinchVelocityRight;
translation = initialTranslationRight + pinchVelocityRight * time;
}
else if (time < liftTime)
{
velocity = liftVelocity;
translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (time - pressTime);
}
else if (time < shiftTime)
{
velocity = shiftVelocity;
translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (time - liftTime);
}
else if (time < holdTime)
{
velocity = btVector3(0,0,0);
translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (time - shiftTime);
}
else if (time < dropTime)
{
velocity = openVelocityRight;
translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityRight * (time - holdTime);
}
else
{
velocity = holdVelocity;
translation = initialTranslationRight + pinchVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityRight * (dropTime - holdTime);
}
rbTransform.setOrigin(translation);
rbTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
rb1->setCenterOfMassTransform(rbTransform);
rb1->setAngularVelocity(btVector3(0,0,0));
rb1->setLinearVelocity(velocity);
rb0->setFriction(20);
rb1->setFriction(20);
}
void Pinch::initPhysics()
{
m_guiHelper->setUpAxis(1);
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
sol->setDeformableSolver(deformableBodySolver);
m_solver = sol;
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
btVector3 gravity = btVector3(0, -10, 0);
m_dynamicsWorld->setGravity(gravity);
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
getDeformableDynamicsWorld()->setSolverCallback(dynamics);
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
//create a ground
{
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0, -25, 0));
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
btScalar mass(0.);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
groundShape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
body->setFriction(0.5);
//add the ground to the dynamics world
m_dynamicsWorld->addRigidBody(body);
}
// create a soft block
{
btScalar verts[24] = {0.f, 0.f, 0.f,
1.f, 0.f, 0.f,
0.f, 1.f, 0.f,
0.f, 0.f, 1.f,
1.f, 1.f, 0.f,
0.f, 1.f, 1.f,
1.f, 0.f, 1.f,
1.f, 1.f, 1.f
};
int triangles[60] = {0, 6, 3,
0,1,6,
7,5,3,
7,3,6,
4,7,6,
4,6,1,
7,2,5,
7,4,2,
0,3,2,
2,3,5,
0,2,4,
0,4,1,
0,6,5,
0,6,4,
3,4,2,
3,4,7,
2,7,3,
2,7,1,
4,5,0,
4,5,6,
};
// btSoftBody* psb = btSoftBodyHelpers::CreateFromTriMesh(getDeformableDynamicsWorld()->getWorldInfo(), &verts[0], &triangles[0], 20);
////
btSoftBody* psb = btSoftBodyHelpers::CreateFromTetGenData(getDeformableDynamicsWorld()->getWorldInfo(),
TetraCube::getElements(),
0,
TetraCube::getNodes(),
false, true, true);
psb->scale(btVector3(2, 2, 2));
psb->translate(btVector3(0, 4, 0));
psb->getCollisionShape()->setMargin(0.1);
psb->setTotalMass(1);
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
psb->m_cfg.kDF = 2;
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
getDeformableDynamicsWorld()->addSoftBody(psb);
btSoftBodyHelpers::generateBoundaryFaces(psb);
btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(1,0.05);
getDeformableDynamicsWorld()->addForce(psb, mass_spring);
m_forces.push_back(mass_spring);
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
m_forces.push_back(gravity_force);
btDeformableNeoHookeanForce* neohookean = new btDeformableNeoHookeanForce(.2,1);
getDeformableDynamicsWorld()->addForce(psb, neohookean);
m_forces.push_back(neohookean);
// add a grippers
createGrip();
}
getDeformableDynamicsWorld()->setImplicit(false);
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void Pinch::exitPhysics()
{
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
int i;
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
m_dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
// delete forces
for (int j = 0; j < m_forces.size(); j++)
{
btDeformableLagrangianForce* force = m_forces[j];
delete force;
}
m_forces.clear();
//delete collision shapes
for (int j = 0; j < m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
}
m_collisionShapes.clear();
delete m_dynamicsWorld;
delete m_solver;
delete m_broadphase;
delete m_dispatcher;
delete m_collisionConfiguration;
}
class CommonExampleInterface* PinchCreateFunc(struct CommonExampleOptions& options)
{
return new Pinch(options.m_guiHelper);
}

View File

@@ -0,0 +1,19 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _PINCH_H
#define _PINCH_H
class CommonExampleInterface* PinchCreateFunc(struct CommonExampleOptions& options);
#endif //_PINCH_H

View File

@@ -0,0 +1,400 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "PinchFriction.h"
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
#include "btBulletDynamicsCommon.h"
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
#include "BulletSoftBody/btSoftBody.h"
#include "BulletSoftBody/btSoftBodyHelpers.h"
#include "BulletSoftBody/btDeformableBodySolver.h"
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
#include <stdio.h> //printf debugging
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../Utils/b3ResourcePath.h"
///The PinchFriction shows the frictional contacts among volumetric deformable objects
struct TetraCube
{
#include "../SoftDemo/cube.inl"
};
class PinchFriction : public CommonRigidBodyBase
{
btAlignedObjectArray<btDeformableLagrangianForce*> m_forces;
public:
PinchFriction(struct GUIHelperInterface* helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~PinchFriction()
{
}
void initPhysics();
void exitPhysics();
void resetCamera()
{
float dist = 25;
float pitch = -30;
float yaw = 100;
float targetPos[3] = {0, -0, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
void stepSimulation(float deltaTime)
{
//use a smaller internal timestep, there are stability issues
float internalTimeStep = 1. / 240.f;
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
}
void createGrip()
{
int count = 2;
float mass = 1e6;
btCollisionShape* shape[] = {
new btBoxShape(btVector3(3, 3, 0.5)),
};
static const int nshapes = sizeof(shape) / sizeof(shape[0]);
for (int i = 0; i < count; ++i)
{
btTransform startTransform;
startTransform.setIdentity();
startTransform.setOrigin(btVector3(10, 0, 0));
startTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
createRigidBody(mass, startTransform, shape[i % nshapes]);
}
}
virtual const btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld() const
{
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld()
{
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual void renderScene()
{
CommonRigidBodyBase::renderScene();
}
};
void dynamics2(btScalar time, btDeformableMultiBodyDynamicsWorld* world)
{
btAlignedObjectArray<btRigidBody*>& rbs = world->getNonStaticRigidBodies();
if (rbs.size()<2)
return;
btRigidBody* rb0 = rbs[0];
btScalar pressTime = 0.45;
btScalar liftTime = 5;
btScalar shiftTime = 1.75;
btScalar holdTime = 7.5;
btScalar dropTime = 8.3;
btTransform rbTransform;
rbTransform.setIdentity();
btVector3 translation;
btVector3 velocity;
btVector3 initialTranslationLeft = btVector3(0.5,3,4);
btVector3 initialTranslationRight = btVector3(0.5,3,-4);
btVector3 PinchFrictionVelocityLeft = btVector3(0,0,-2);
btVector3 PinchFrictionVelocityRight = btVector3(0,0,2);
btVector3 liftVelocity = btVector3(0,2,0);
btVector3 shiftVelocity = btVector3(0,0,0);
btVector3 holdVelocity = btVector3(0,0,0);
btVector3 openVelocityLeft = btVector3(0,0,4);
btVector3 openVelocityRight = btVector3(0,0,-4);
if (time < pressTime)
{
velocity = PinchFrictionVelocityLeft;
translation = initialTranslationLeft + PinchFrictionVelocityLeft * time;
}
else if (time < liftTime)
{
velocity = liftVelocity;
translation = initialTranslationLeft + PinchFrictionVelocityLeft * pressTime + liftVelocity * (time - pressTime);
}
else if (time < shiftTime)
{
velocity = shiftVelocity;
translation = initialTranslationLeft + PinchFrictionVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (time - liftTime);
}
else if (time < holdTime)
{
velocity = btVector3(0,0,0);
translation = initialTranslationLeft + PinchFrictionVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (time - shiftTime);
}
else if (time < dropTime)
{
velocity = openVelocityLeft;
translation = initialTranslationLeft + PinchFrictionVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityLeft * (time - holdTime);
}
else
{
velocity = holdVelocity;
translation = initialTranslationLeft + PinchFrictionVelocityLeft * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityLeft * (dropTime - holdTime);
}
rbTransform.setOrigin(translation);
rbTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
rb0->setCenterOfMassTransform(rbTransform);
rb0->setAngularVelocity(btVector3(0,0,0));
rb0->setLinearVelocity(velocity);
btRigidBody* rb1 = rbs[1];
if (time < pressTime)
{
velocity = PinchFrictionVelocityRight;
translation = initialTranslationRight + PinchFrictionVelocityRight * time;
}
else if (time < liftTime)
{
velocity = liftVelocity;
translation = initialTranslationRight + PinchFrictionVelocityRight * pressTime + liftVelocity * (time - pressTime);
}
else if (time < shiftTime)
{
velocity = shiftVelocity;
translation = initialTranslationRight + PinchFrictionVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (time - liftTime);
}
else if (time < holdTime)
{
velocity = btVector3(0,0,0);
translation = initialTranslationRight + PinchFrictionVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (time - shiftTime);
}
else if (time < dropTime)
{
velocity = openVelocityRight;
translation = initialTranslationRight + PinchFrictionVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityRight * (time - holdTime);
}
else
{
velocity = holdVelocity;
translation = initialTranslationRight + PinchFrictionVelocityRight * pressTime + liftVelocity * (liftTime-pressTime) + shiftVelocity * (shiftTime - liftTime) + holdVelocity * (holdTime - shiftTime)+ openVelocityRight * (dropTime - holdTime);
}
rbTransform.setOrigin(translation);
rbTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
rb1->setCenterOfMassTransform(rbTransform);
rb1->setAngularVelocity(btVector3(0,0,0));
rb1->setLinearVelocity(velocity);
rb0->setFriction(200);
rb1->setFriction(200);
}
void PinchFriction::initPhysics()
{
m_guiHelper->setUpAxis(1);
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
sol->setDeformableSolver(deformableBodySolver);
m_solver = sol;
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
btVector3 gravity = btVector3(0, -10, 0);
m_dynamicsWorld->setGravity(gravity);
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.Reset();
getDeformableDynamicsWorld()->setSolverCallback(dynamics2);
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
//create a ground
{
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0, -25, 0));
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0));
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
btScalar mass(0.);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
groundShape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
body->setFriction(0.5);
//add the ground to the dynamics world
m_dynamicsWorld->addRigidBody(body);
}
// create a soft block
{
btSoftBody* psb = btSoftBodyHelpers::CreateFromTetGenData(getDeformableDynamicsWorld()->getWorldInfo(),
TetraCube::getElements(),
0,
TetraCube::getNodes(),
false, true, true);
psb->scale(btVector3(2, 2, 1));
psb->translate(btVector3(0, 2.1, 2.2));
psb->getCollisionShape()->setMargin(0.05);
psb->setTotalMass(.6);
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
psb->m_cfg.kDF = 2;
btSoftBodyHelpers::generateBoundaryFaces(psb);
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
psb->m_cfg.collisions |= btSoftBody::fCollision::VF_DD;
getDeformableDynamicsWorld()->addSoftBody(psb);
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
m_forces.push_back(gravity_force);
btDeformableNeoHookeanForce* neohookean = new btDeformableNeoHookeanForce(4,8,.1);
getDeformableDynamicsWorld()->addForce(psb, neohookean);
m_forces.push_back(neohookean);
}
// create a second soft block
{
btSoftBody* psb2 = btSoftBodyHelpers::CreateFromTetGenData(getDeformableDynamicsWorld()->getWorldInfo(),
TetraCube::getElements(),
0,
TetraCube::getNodes(),
false, true, true);
psb2->scale(btVector3(2, 2, 1));
psb2->translate(btVector3(0, 2.1, -2.2));
psb2->getCollisionShape()->setMargin(0.05);
psb2->setTotalMass(.6);
psb2->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb2->m_cfg.kCHR = 1; // collision hardness with rigid body
psb2->m_cfg.kDF = 2;
psb2->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
psb2->m_cfg.collisions |= btSoftBody::fCollision::VF_DD;
btSoftBodyHelpers::generateBoundaryFaces(psb2);
getDeformableDynamicsWorld()->addSoftBody(psb2);
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
getDeformableDynamicsWorld()->addForce(psb2, gravity_force);
m_forces.push_back(gravity_force);
btDeformableNeoHookeanForce* neohookean = new btDeformableNeoHookeanForce(4,8,.1);
getDeformableDynamicsWorld()->addForce(psb2, neohookean);
m_forces.push_back(neohookean);
}
// create a third soft block
{
btSoftBody* psb3 = btSoftBodyHelpers::CreateFromTetGenData(getDeformableDynamicsWorld()->getWorldInfo(),
TetraCube::getElements(),
0,
TetraCube::getNodes(),
false, true, true);
psb3->scale(btVector3(2, 2, 1));
psb3->translate(btVector3(0, 2.1, 0));
psb3->getCollisionShape()->setMargin(0.05);
psb3->setTotalMass(.6);
psb3->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb3->m_cfg.kCHR = 1; // collision hardness with rigid body
psb3->m_cfg.kDF = 2;
psb3->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
psb3->m_cfg.collisions |= btSoftBody::fCollision::VF_DD;
btSoftBodyHelpers::generateBoundaryFaces(psb3);
getDeformableDynamicsWorld()->addSoftBody(psb3);
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
getDeformableDynamicsWorld()->addForce(psb3, gravity_force);
m_forces.push_back(gravity_force);
btDeformableNeoHookeanForce* neohookean = new btDeformableNeoHookeanForce(4,8,.1);
getDeformableDynamicsWorld()->addForce(psb3, neohookean);
m_forces.push_back(neohookean);
}
getDeformableDynamicsWorld()->setImplicit(false);
// add a pair of grippers
createGrip();
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void PinchFriction::exitPhysics()
{
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
int i;
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
m_dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
// delete forces
for (int j = 0; j < m_forces.size(); j++)
{
btDeformableLagrangianForce* force = m_forces[j];
delete force;
}
m_forces.clear();
//delete collision shapes
for (int j = 0; j < m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
}
m_collisionShapes.clear();
delete m_dynamicsWorld;
delete m_solver;
delete m_broadphase;
delete m_dispatcher;
delete m_collisionConfiguration;
}
class CommonExampleInterface* PinchFrictionCreateFunc(struct CommonExampleOptions& options)
{
return new PinchFriction(options.m_guiHelper);
}

View File

@@ -0,0 +1,19 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _PINCH_FRICTION_H
#define _PINCH_FRICTION_H
class CommonExampleInterface* PinchFrictionCreateFunc(struct CommonExampleOptions& options);
#endif //_PINCH_FRICTION_H

View File

@@ -0,0 +1,259 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SplitImpulse.h"
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
#include "btBulletDynamicsCommon.h"
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
#include "BulletSoftBody/btSoftBody.h"
#include "BulletSoftBody/btSoftBodyHelpers.h"
#include "BulletSoftBody/btDeformableBodySolver.h"
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
#include <stdio.h> //printf debugging
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../Utils/b3ResourcePath.h"
#define USE_SPLIT_IMPULSE 1
///The SplitImpulse shows the effect of split impulse in deformable rigid contact.
class SplitImpulse : public CommonRigidBodyBase
{
btAlignedObjectArray<btDeformableLagrangianForce*> m_forces;
public:
SplitImpulse(struct GUIHelperInterface* helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~SplitImpulse()
{
}
void initPhysics();
void exitPhysics();
void resetCamera()
{
float dist = 20;
float pitch = -45;
float yaw = 100;
float targetPos[3] = {0, -3, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
void stepSimulation(float deltaTime)
{
//use a smaller internal timestep, there are stability issues
float internalTimeStep = 1. / 240.f;
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
}
void Ctor_RbUpStack(int count)
{
float mass = 0.2;
btCollisionShape* shape[] = {
new btBoxShape(btVector3(1, 1, 1)),
};
btTransform startTransform;
startTransform.setIdentity();
startTransform.setOrigin(btVector3(0, 0.7, 0));
createRigidBody(mass, startTransform, shape[0]);
}
virtual const btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld() const
{
///just make it a btSoftRigidDynamicsWorld please
///or we will add type checking
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld()
{
///just make it a btSoftRigidDynamicsWorld please
///or we will add type checking
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual void renderScene()
{
CommonRigidBodyBase::renderScene();
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
{
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
//if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
{
btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
}
}
}
};
void SplitImpulse::initPhysics()
{
m_guiHelper->setUpAxis(1);
///collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded)
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
sol->setDeformableSolver(deformableBodySolver);
m_solver = sol;
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
// deformableBodySolver->setWorld(getDeformableDynamicsWorld());
// m_dynamicsWorld->getSolverInfo().m_singleAxisDeformableThreshold = 0.f;//faster but lower quality
btVector3 gravity = btVector3(0, -50, 0);
m_dynamicsWorld->setGravity(gravity);
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.Reset();
// getDeformableDynamicsWorld()->before_solver_callbacks.push_back(dynamics);
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
{
///create a ground
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0, -32, 0));
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
btScalar mass(0.);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
groundShape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
body->setFriction(1);
//add the ground to the dynamics world
m_dynamicsWorld->addRigidBody(body);
}
#ifdef USE_SPLIT_IMPULSE
getDeformableDynamicsWorld()->getSolverInfo().m_deformable_erp = 0.03;
#else
getDeformableDynamicsWorld()->getSolverInfo().m_deformable_erp = 0.0;
#endif
// create a piece of cloth
{
const btScalar s = 4;
const btScalar h = 0;
btSoftBody* psb = btSoftBodyHelpers::CreatePatch(getDeformableDynamicsWorld()->getWorldInfo(), btVector3(-s, h, -s),
btVector3(+s, h, -s),
btVector3(-s, h, +s),
btVector3(+s, h, +s),
// 3,3,
20,20,
1 + 2 + 4 + 8, true);
// 0, true);
psb->getCollisionShape()->setMargin(0.15);
psb->generateBendingConstraints(2);
psb->setTotalMass(1);
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
psb->m_cfg.kDF = 2;
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
getDeformableDynamicsWorld()->addSoftBody(psb);
btDeformableMassSpringForce* mass_spring = new btDeformableMassSpringForce(30,1, true);
getDeformableDynamicsWorld()->addForce(psb, mass_spring);
m_forces.push_back(mass_spring);
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
m_forces.push_back(gravity_force);
// add a few rigid bodies
Ctor_RbUpStack(1);
}
getDeformableDynamicsWorld()->setImplicit(false);
getDeformableDynamicsWorld()->setLineSearch(false);
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void SplitImpulse::exitPhysics()
{
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
int i;
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
m_dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
// delete forces
for (int j = 0; j < m_forces.size(); j++)
{
btDeformableLagrangianForce* force = m_forces[j];
delete force;
}
m_forces.clear();
//delete collision shapes
for (int j = 0; j < m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
}
m_collisionShapes.clear();
delete m_dynamicsWorld;
delete m_solver;
delete m_broadphase;
delete m_dispatcher;
delete m_collisionConfiguration;
}
class CommonExampleInterface* SplitImpulseCreateFunc(struct CommonExampleOptions& options)
{
return new SplitImpulse(options.m_guiHelper);
}

View File

@@ -0,0 +1,19 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _SPLIT_IMPULSE_H
#define _SPLIT_IMPULSE_H
class CommonExampleInterface* SplitImpulseCreateFunc(struct CommonExampleOptions& options);
#endif //_SPLIT_IMPULSE_H

View File

@@ -0,0 +1,293 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "VolumetricDeformable.h"
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
#include "btBulletDynamicsCommon.h"
#include "BulletSoftBody/btDeformableMultiBodyDynamicsWorld.h"
#include "BulletSoftBody/btSoftBody.h"
#include "BulletSoftBody/btSoftBodyHelpers.h"
#include "BulletSoftBody/btDeformableBodySolver.h"
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
#include <stdio.h> //printf debugging
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../Utils/b3ResourcePath.h"
///The VolumetricDeformable shows the contact between volumetric deformable objects and rigid objects.
struct TetraCube
{
#include "../SoftDemo/cube.inl"
};
class VolumetricDeformable : public CommonRigidBodyBase
{
btAlignedObjectArray<btDeformableLagrangianForce*> m_forces;
public:
VolumetricDeformable(struct GUIHelperInterface* helper)
: CommonRigidBodyBase(helper)
{
}
virtual ~VolumetricDeformable()
{
}
void initPhysics();
void exitPhysics();
void resetCamera()
{
float dist = 20;
float pitch = -45;
float yaw = 100;
float targetPos[3] = {0, 3, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
void stepSimulation(float deltaTime)
{
//use a smaller internal timestep, there are stability issues
float internalTimeStep = 1. / 240.f;
m_dynamicsWorld->stepSimulation(deltaTime, 4, internalTimeStep);
}
void createStaticBox(const btVector3& halfEdge, const btVector3& translation)
{
btCollisionShape* box = new btBoxShape(halfEdge);
m_collisionShapes.push_back(box);
btTransform Transform;
Transform.setIdentity();
Transform.setOrigin(translation);
Transform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.0));
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
btScalar mass(0.);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
box->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(Transform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, box, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
body->setFriction(0.5);
//add the ground to the dynamics world
m_dynamicsWorld->addRigidBody(body);
}
void Ctor_RbUpStack(int count)
{
float mass = 1;
btCompoundShape* cylinderCompound = new btCompoundShape;
btCollisionShape* cylinderShape = new btCylinderShapeX(btVector3(2, .5, .5));
btCollisionShape* boxShape = new btBoxShape(btVector3(2, .5, .5));
btTransform localTransform;
localTransform.setIdentity();
cylinderCompound->addChildShape(localTransform, boxShape);
btQuaternion orn(SIMD_HALF_PI, 0, 0);
localTransform.setRotation(orn);
// localTransform.setOrigin(btVector3(1,1,1));
cylinderCompound->addChildShape(localTransform, cylinderShape);
btCollisionShape* shape[] = {
new btBoxShape(btVector3(1, 1, 1)),
};
static const int nshapes = sizeof(shape) / sizeof(shape[0]);
for (int i = 0; i < count; ++i)
{
btTransform startTransform;
startTransform.setIdentity();
startTransform.setOrigin(btVector3(i, 10 + 2 * i, i-1));
createRigidBody(mass, startTransform, shape[i % nshapes]);
}
}
virtual const btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld() const
{
///just make it a btSoftRigidDynamicsWorld please
///or we will add type checking
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual btDeformableMultiBodyDynamicsWorld* getDeformableDynamicsWorld()
{
///just make it a btSoftRigidDynamicsWorld please
///or we will add type checking
return (btDeformableMultiBodyDynamicsWorld*)m_dynamicsWorld;
}
virtual void renderScene()
{
CommonRigidBodyBase::renderScene();
btDeformableMultiBodyDynamicsWorld* deformableWorld = getDeformableDynamicsWorld();
for (int i = 0; i < deformableWorld->getSoftBodyArray().size(); i++)
{
btSoftBody* psb = (btSoftBody*)deformableWorld->getSoftBodyArray()[i];
//if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe)))
{
btSoftBodyHelpers::DrawFrame(psb, deformableWorld->getDebugDrawer());
btSoftBodyHelpers::Draw(psb, deformableWorld->getDebugDrawer(), deformableWorld->getDrawFlags());
}
}
}
};
void VolumetricDeformable::initPhysics()
{
m_guiHelper->setUpAxis(1);
///collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
btDeformableBodySolver* deformableBodySolver = new btDeformableBodySolver();
btDeformableMultiBodyConstraintSolver* sol = new btDeformableMultiBodyConstraintSolver();
sol->setDeformableSolver(deformableBodySolver);
m_solver = sol;
m_dynamicsWorld = new btDeformableMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration, deformableBodySolver);
btVector3 gravity = btVector3(0, -100, 0);
m_dynamicsWorld->setGravity(gravity);
getDeformableDynamicsWorld()->getWorldInfo().m_gravity = gravity;
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.setDefaultVoxelsz(0.25);
getDeformableDynamicsWorld()->getWorldInfo().m_sparsesdf.Reset();
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
{
///create a ground
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(50.), btScalar(150.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0, -50, 0));
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.0));
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
btScalar mass(0.);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
groundShape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
body->setFriction(0.5);
//add the ground to the dynamics world
m_dynamicsWorld->addRigidBody(body);
}
createStaticBox(btVector3(1, 5, 5), btVector3(-5,0,0));
createStaticBox(btVector3(1, 5, 5), btVector3(5,0,0));
createStaticBox(btVector3(5, 5, 1), btVector3(0,0,5));
createStaticBox(btVector3(5, 5, 1), btVector3(0,0,-5));
// create volumetric soft body
{
btSoftBody* psb = btSoftBodyHelpers::CreateFromTetGenData(getDeformableDynamicsWorld()->getWorldInfo(),
TetraCube::getElements(),
0,
TetraCube::getNodes(),
false, true, true);
getDeformableDynamicsWorld()->addSoftBody(psb);
psb->scale(btVector3(2, 2, 2));
psb->translate(btVector3(0, 5, 0));
psb->getCollisionShape()->setMargin(0.25);
psb->setTotalMass(1);
psb->m_cfg.kKHR = 1; // collision hardness with kinematic objects
psb->m_cfg.kCHR = 1; // collision hardness with rigid body
psb->m_cfg.kDF = 0.5;
psb->m_cfg.collisions = btSoftBody::fCollision::SDF_RD;
btSoftBodyHelpers::generateBoundaryFaces(psb);
btDeformableGravityForce* gravity_force = new btDeformableGravityForce(gravity);
getDeformableDynamicsWorld()->addForce(psb, gravity_force);
m_forces.push_back(gravity_force);
btDeformableNeoHookeanForce* neohookean = new btDeformableNeoHookeanForce(30,100,0.05);
getDeformableDynamicsWorld()->addForce(psb, neohookean);
m_forces.push_back(neohookean);
}
getDeformableDynamicsWorld()->setImplicit(false);
getDeformableDynamicsWorld()->setLineSearch(false);
// add a few rigid bodies
Ctor_RbUpStack(4);
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void VolumetricDeformable::exitPhysics()
{
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
int i;
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
m_dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
// delete forces
for (int j = 0; j < m_forces.size(); j++)
{
btDeformableLagrangianForce* force = m_forces[j];
delete force;
}
m_forces.clear();
//delete collision shapes
for (int j = 0; j < m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
}
m_collisionShapes.clear();
delete m_dynamicsWorld;
delete m_solver;
delete m_broadphase;
delete m_dispatcher;
delete m_collisionConfiguration;
}
class CommonExampleInterface* VolumetricDeformableCreateFunc(struct CommonExampleOptions& options)
{
return new VolumetricDeformable(options.m_guiHelper);
}

View File

@@ -0,0 +1,19 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2019 Google Inc. http://bulletphysics.org
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _VOLUMETRIC_DEFORMABLE_H
#define _VOLUMETRIC_DEFORMABLE_H
class CommonExampleInterface* VolumetricDeformableCreateFunc(struct CommonExampleOptions& options);
#endif //_VOLUMETRIC_DEFORMABLE__H

View File

@@ -220,12 +220,6 @@ SET(BulletExampleBrowser_SRCS
../MultiThreadedDemo/CommonRigidBodyMTBase.h
../Heightfield/HeightfieldExample.cpp
../Heightfield/HeightfieldExample.h
../BlockSolver/btBlockSolver.cpp
../BlockSolver/btBlockSolver.h
../BlockSolver/BlockSolverExample.cpp
../BlockSolver/BlockSolverExample.h
../BlockSolver/RigidBodyBoxes.cpp
../BlockSolver/RigidBodyBoxes.h
../Tutorial/Tutorial.cpp
../Tutorial/Tutorial.h
../Tutorial/Dof6ConstraintTutorial.cpp
@@ -359,6 +353,30 @@ SET(BulletExampleBrowser_SRCS
../MultiBody/MultiBodyConstraintFeedback.cpp
../SoftDemo/SoftDemo.cpp
../SoftDemo/SoftDemo.h
../DeformableDemo/DeformableContact.cpp
../DeformableDemo/DeformableContact.h
../DeformableDemo/GraspDeformable.cpp
../DeformableDemo/GraspDeformable.h
../DeformableDemo/Pinch.cpp
../DeformableDemo/Pinch.h
../DeformableDemo/DeformableSelfCollision.cpp
../DeformableDemo/DeformableSelfCollision.h
../DeformableDemo/PinchFriction.cpp
../DeformableDemo/PinchFriction.h
../DeformableDemo/ClothFriction.cpp
../DeformableDemo/ClothFriction.h
../DeformableDemo/DeformableMultibody.cpp
../DeformableDemo/DeformableMultibody.h
../DeformableDemo/DeformableRigid.cpp
../DeformableDemo/DeformableRigid.h
../DeformableDemo/SplitImpulse.cpp
../DeformableDemo/SplitImpulse.h
../DeformableDemo/VolumetricDeformable.cpp
../DeformableDemo/VolumetricDeformable.h
../DeformableDemo/DeformableClothAnchor.cpp
../DeformableDemo/DeformableClothAnchor.h
../DeformableDemo/MultibodyClothAnchor.cpp
../DeformableDemo/MultibodyClothAnchor.h
../MultiBody/MultiDofDemo.cpp
../MultiBody/MultiDofDemo.h
../RigidBody/RigidBodySoftContact.cpp

View File

@@ -1,8 +1,5 @@
#include "ExampleEntries.h"
#include "../BlockSolver/btBlockSolver.h"
#include "../BlockSolver/BlockSolverExample.h"
#include "../BlockSolver/RigidBodyBoxes.h"
#include "LinearMath/btAlignedObjectArray.h"
#include "EmptyExample.h"
#include "../Heightfield/HeightfieldExample.h"
@@ -47,6 +44,18 @@
#include "../FractureDemo/FractureDemo.h"
#include "../DynamicControlDemo/MotorDemo.h"
#include "../RollingFrictionDemo/RollingFrictionDemo.h"
#include "../DeformableDemo/DeformableRigid.h"
#include "../DeformableDemo/SplitImpulse.h"
#include "../DeformableDemo/ClothFriction.h"
#include "../DeformableDemo/Pinch.h"
#include "../DeformableDemo/DeformableSelfCollision.h"
#include "../DeformableDemo/PinchFriction.h"
#include "../DeformableDemo/DeformableMultibody.h"
#include "../DeformableDemo/VolumetricDeformable.h"
#include "../DeformableDemo/GraspDeformable.h"
#include "../DeformableDemo/DeformableContact.h"
#include "../DeformableDemo/DeformableClothAnchor.h"
#include "../DeformableDemo/MultibodyClothAnchor.h"
#include "../SharedMemory/PhysicsServerExampleBullet2.h"
#include "../SharedMemory/PhysicsServerExample.h"
#include "../SharedMemory/PhysicsClientExample.h"
@@ -117,7 +126,7 @@ static ExampleEntry gDefaultExamples[] =
ExampleEntry(1, "Basic Example", "Create some rigid bodies using box collision shapes. This is a good example to familiarize with the basic initialization of Bullet. The Basic Example can also be compiled without graphical user interface, as a console application. Press W for wireframe, A to show AABBs, I to suspend/restart physics simulation. Press D to toggle auto-deactivation of the simulation. ", BasicExampleCreateFunc),
ExampleEntry(1, "Rolling Friction", "Damping is often not good enough to keep rounded objects from rolling down a sloped surface. Instead, you can set the rolling friction of a rigid body. Generally it is best to leave the rolling friction to zero, to avoid artifacts.", RollingFrictionCreateFunc),
ExampleEntry(1, "Constraints", "Show the use of the various constraints in Bullet. Press the L key to visualize the constraint limits. Press the C key to visualize the constraint frames.",
AllConstraintCreateFunc),
@@ -159,13 +168,6 @@ static ExampleEntry gDefaultExamples[] =
//
// ExampleEntry(1, "Physics Client (Direct)", "Create a physics client that can communicate with a physics server directly in-process.", PhysicsClientCreateFunc,eCLIENTEXAMPLE_DIRECT),
ExampleEntry(0, "BlockSolver"),
ExampleEntry(1, "Stack MultiBody SI", "Create a stack of blocks, with heavy block at the top", BlockSolverExampleCreateFunc, BLOCK_SOLVER_SCENE_MB_STACK + BLOCK_SOLVER_SI),
ExampleEntry(1, "Stack MultiBody MLCP PGS", "Create a stack of blocks, with heavy block at the top", BlockSolverExampleCreateFunc, BLOCK_SOLVER_SCENE_MB_STACK + BLOCK_SOLVER_MLCP_PGS),
ExampleEntry(1, "Stack MultiBody MLCP Dantzig", "Create a stack of blocks, with heavy block at the top", BlockSolverExampleCreateFunc, BLOCK_SOLVER_SCENE_MB_STACK + BLOCK_SOLVER_MLCP_DANTZIG),
ExampleEntry(1, "Stack MultiBody Block", "Create a stack of blocks, with heavy block at the top", BlockSolverExampleCreateFunc, BLOCK_SOLVER_SCENE_MB_STACK + BLOCK_SOLVER_BLOCK),
//ExampleEntry(1, "Stack RigidBody SI", "Create a stack of blocks, with heavy block at the top", RigidBodyBoxesCreateFunc, BLOCK_SOLVER_SI),
//ExampleEntry(1, "Stack RigidBody Block", "Create a stack of blocks, with heavy block at the top", RigidBodyBoxesCreateFunc, BLOCK_SOLVER_BLOCK),
ExampleEntry(0, "Inverse Dynamics"),
ExampleEntry(1, "Inverse Dynamics URDF", "Create a btMultiBody from URDF. Create an inverse MultiBodyTree model from that. Use either decoupled PD control or computed torque control using the inverse model to track joint position targets", InverseDynamicsExampleCreateFunc, BT_ID_LOAD_URDF),
@@ -190,6 +192,21 @@ static ExampleEntry gDefaultExamples[] =
ExampleEntry(1, "Spheres & Plane C-API (Bullet2)", "Collision C-API using Bullet 2.x backend", CollisionTutorialBullet2CreateFunc, TUT_SPHERE_PLANE_BULLET2),
//ExampleEntry(1, "Spheres & Plane C-API (Bullet3)", "Collision C-API using Bullet 3.x backend", CollisionTutorialBullet2CreateFunc,TUT_SPHERE_PLANE_RTB3),
ExampleEntry(0, "Deformabe Body"),
ExampleEntry(1, "Deformable Self Collision", "Deformable Self Collision", DeformableSelfCollisionCreateFunc),
ExampleEntry(1, "Deformable-Deformable Contact", "Deformable contact", DeformableContactCreateFunc),
ExampleEntry(1, "Cloth Friction", "Cloth friction contact", ClothFrictionCreateFunc),
ExampleEntry(1, "Deformable-Deformable Friction Contact", "Deformable friction contact", PinchFrictionCreateFunc),
ExampleEntry(1, "Deformable-RigidBody Contact", "Deformable test", DeformableRigidCreateFunc),
ExampleEntry(1, "Split Impulse Contact", "Split impulse test", SplitImpulseCreateFunc),
ExampleEntry(1, "Grasp Deformable Cube", "Grasping test", PinchCreateFunc),
ExampleEntry(1, "Grasp Deformable with Motor", "Grasping test", GraspDeformableCreateFunc),
ExampleEntry(1, "Volumetric Deformable Objects", "Volumetric Deformable test", VolumetricDeformableCreateFunc),
ExampleEntry(1, "Rigid Cloth Anchor", "Deformable Rigid body Anchor test", DeformableClothAnchorCreateFunc),
ExampleEntry(1, "Multibody Cloth Anchor", "Deformable Multibody Anchor test", MultibodyClothAnchorCreateFunc),
ExampleEntry(1, "Deformable-MultiBody Contact", "MultiBody and Deformable contact", DeformableMultibodyCreateFunc),
// ExampleEntry(1, "MultiBody Baseline", "MultiBody Baseline", MultiBodyBaselineCreateFunc),
#ifdef INCLUDE_CLOTH_DEMOS
ExampleEntry(0, "Soft Body"),
ExampleEntry(1, "Cloth", "Simulate a patch of cloth.", SoftDemoCreateFunc, 0),
@@ -286,6 +303,7 @@ static ExampleEntry gDefaultExamples[] =
ExampleEntry(1, "Rolling friction", "Experiment on multibody rolling friction", R2D2GraspExampleCreateFunc, eROBOTIC_LEARN_ROLLING_FRICTION),
ExampleEntry(1, "Gripper Grasp", "Grasp experiment with a gripper to improve contact model", GripperGraspExampleCreateFunc, eGRIPPER_GRASP),
ExampleEntry(1, "Two Point Grasp", "Grasp experiment with two point contact to test rolling friction", GripperGraspExampleCreateFunc, eTWO_POINT_GRASP),
ExampleEntry(1, "Grasp Deformable Cloth", "Grasp experiment with deformable cloth", GripperGraspExampleCreateFunc, eGRASP_DEFORMABLE_CLOTH),
ExampleEntry(1, "One Motor Gripper Grasp", "Grasp experiment with a gripper with one motor to test slider constraint for closed loop structure", GripperGraspExampleCreateFunc, eONE_MOTOR_GRASP),
#ifndef SKIP_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD
ExampleEntry(1, "Grasp Soft Body", "Grasp soft body experiment", GripperGraspExampleCreateFunc, eGRASP_SOFT_BODY),

View File

@@ -290,7 +290,7 @@ void GwenUserInterface::init(int width, int height, Gwen::Renderer::Base* render
//tab->SetHeight(300);
tab->SetWidth(240);
tab->SetHeight(1250);
tab->SetHeight(13250);
//tab->Dock(Gwen::Pos::Left);
tab->Dock(Gwen::Pos::Fill);
//tab->SetMargin( Gwen::Margin( 2, 2, 2, 2 ) );

View File

@@ -921,6 +921,13 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[])
m_internalData->m_app = s_app;
char* gVideoFileName = 0;
args.GetCmdLineArgument("mp4", gVideoFileName);
int gVideoFps = 0;
args.GetCmdLineArgument("mp4fps", gVideoFps);
if (gVideoFps)
{
simpleApp->setMp4Fps(gVideoFps);
}
#ifndef NO_OPENGL3
if (gVideoFileName)
simpleApp->dumpFramesToVideo(gVideoFileName);

View File

@@ -380,6 +380,14 @@ void OpenGLGuiHelper::replaceTexture(int shapeIndex, int textureUid)
m_data->m_glApp->m_renderer->replaceTexture(shapeIndex, textureUid);
};
}
void OpenGLGuiHelper::changeInstanceFlags(int instanceUid, int flags)
{
if (instanceUid >= 0)
{
//careful, flags/instanceUid is swapped
m_data->m_glApp->m_renderer->writeSingleInstanceFlagsToCPU( flags, instanceUid);
}
}
void OpenGLGuiHelper::changeRGBAColor(int instanceUid, const double rgbaColor[4])
{
if (instanceUid >= 0)
@@ -1433,6 +1441,11 @@ void OpenGLGuiHelper::autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWor
color.setValue(1, 1, 1, 1);
}
createCollisionObjectGraphicsObject(colObj, color);
if (sb)
{
int graphicsInstanceId = colObj->getUserIndex();
changeInstanceFlags(graphicsInstanceId, B3_INSTANCE_DOUBLE_SIDED);
}
}
}
@@ -1496,3 +1509,8 @@ void OpenGLGuiHelper::computeSoftBodyVertices(btCollisionShape* collisionShape,
}
}
}
void OpenGLGuiHelper::updateShape(int shapeIndex, float* vertices)
{
m_data->m_glApp->m_renderer->updateShape(shapeIndex, vertices);
}

View File

@@ -27,12 +27,14 @@ struct OpenGLGuiHelper : public GUIHelperInterface
virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling);
virtual void removeAllGraphicsInstances();
virtual void removeGraphicsInstance(int graphicsUid);
virtual void changeInstanceFlags(int instanceUid, int flags);
virtual void changeRGBAColor(int instanceUid, const double rgbaColor[4]);
virtual void changeSpecularColor(int instanceUid, const double specularColor[3]);
virtual void changeTexture(int textureUniqueId, const unsigned char* rgbTexels, int width, int height);
virtual void removeTexture(int textureUid);
virtual int getShapeIndexFromInstance(int instanceUid);
virtual void replaceTexture(int shapeIndex, int textureUid);
virtual void updateShape(int shapeIndex, float* vertices);
virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape);

View File

@@ -168,7 +168,6 @@ project "App_BulletExampleBrowser"
"../Evolution/NN3DWalkers.h",
"../Collision/*",
"../RoboticsLearning/*",
"../BlockSolver/*",
"../Collision/Internal/*",
"../Benchmarks/*",
"../MultiThreadedDemo/*",
@@ -182,6 +181,7 @@ project "App_BulletExampleBrowser"
"../RenderingExamples/*",
"../VoronoiFracture/*",
"../SoftDemo/*",
"../DeformableDemo/*",
"../RollingFrictionDemo/*",
"../rbdl/*",
"../FractureDemo/*",
@@ -199,7 +199,6 @@ project "App_BulletExampleBrowser"
"../RigidBody/RigidBodySoftContact.cpp",
"../ThirdPartyLibs/stb_image/stb_image.cpp",
"../ThirdPartyLibs/Wavefront/tiny_obj_loader.*",
"../ThirdPartyLibs/BussIK/*",
"../GyroscopicDemo/GyroscopicSetup.cpp",
"../GyroscopicDemo/GyroscopicSetup.h",
"../ThirdPartyLibs/tinyxml2/tinyxml2.cpp",

View File

@@ -2265,7 +2265,7 @@ int BulletMJCFImporter::getBodyUniqueId() const
return m_data->m_activeBodyUniqueId;
}
static btCollisionShape* MjcfCreateConvexHullFromShapes(std::vector<tinyobj::shape_t>& shapes, const btVector3& geomScale, btScalar collisionMargin)
static btCollisionShape* MjcfCreateConvexHullFromShapes(const tinyobj::attrib_t& attribute, std::vector<tinyobj::shape_t>& shapes, const btVector3& geomScale, btScalar collisionMargin)
{
btCompoundShape* compound = new btCompoundShape();
compound->setMargin(collisionMargin);
@@ -2278,25 +2278,26 @@ static btCollisionShape* MjcfCreateConvexHullFromShapes(std::vector<tinyobj::sha
btConvexHullShape* convexHull = new btConvexHullShape();
convexHull->setMargin(collisionMargin);
tinyobj::shape_t& shape = shapes[s];
int faceCount = shape.mesh.indices.size();
for (int f = 0; f < faceCount; f += 3)
{
btVector3 pt;
pt.setValue(shape.mesh.positions[shape.mesh.indices[f] * 3 + 0],
shape.mesh.positions[shape.mesh.indices[f] * 3 + 1],
shape.mesh.positions[shape.mesh.indices[f] * 3 + 2]);
pt.setValue(attribute.vertices[3 * shape.mesh.indices[f].vertex_index + 0],
attribute.vertices[3 * shape.mesh.indices[f].vertex_index + 1],
attribute.vertices[3 * shape.mesh.indices[f].vertex_index + 2]);
convexHull->addPoint(pt * geomScale, false);
pt.setValue(shape.mesh.positions[shape.mesh.indices[f + 1] * 3 + 0],
shape.mesh.positions[shape.mesh.indices[f + 1] * 3 + 1],
shape.mesh.positions[shape.mesh.indices[f + 1] * 3 + 2]);
pt.setValue(attribute.vertices[3 * shape.mesh.indices[f + 1].vertex_index + 0],
attribute.vertices[3 * shape.mesh.indices[f + 1].vertex_index + 1],
attribute.vertices[3 * shape.mesh.indices[f + 1].vertex_index + 2]);
convexHull->addPoint(pt * geomScale, false);
pt.setValue(shape.mesh.positions[shape.mesh.indices[f + 2] * 3 + 0],
shape.mesh.positions[shape.mesh.indices[f + 2] * 3 + 1],
shape.mesh.positions[shape.mesh.indices[f + 2] * 3 + 2]);
pt.setValue(attribute.vertices[3 * shape.mesh.indices[f + 2].vertex_index + 0],
attribute.vertices[3 * shape.mesh.indices[f + 2].vertex_index + 1],
attribute.vertices[3 * shape.mesh.indices[f + 2].vertex_index + 2]);
convexHull->addPoint(pt * geomScale, false);
}
@@ -2391,10 +2392,11 @@ class btCompoundShape* BulletMJCFImporter::convertLinkCollisionShapes(int linkIn
else
{
std::vector<tinyobj::shape_t> shapes;
std::string err = tinyobj::LoadObj(shapes, col->m_geometry.m_meshFileName.c_str(),"",m_data->m_fileIO);
tinyobj::attrib_t attribute;
std::string err = tinyobj::LoadObj(attribute, shapes, col->m_geometry.m_meshFileName.c_str(), "", m_data->m_fileIO);
//create a convex hull for each shape, and store it in a btCompoundShape
childShape = MjcfCreateConvexHullFromShapes(shapes, col->m_geometry.m_meshScale, m_data->m_globalDefaults.m_defaultCollisionMargin);
childShape = MjcfCreateConvexHullFromShapes(attribute, shapes, col->m_geometry.m_meshScale, m_data->m_globalDefaults.m_defaultCollisionMargin);
}
break;
}

View File

@@ -65,13 +65,14 @@ bool b3ImportMeshUtility::loadAndRegisterMeshFromFileInternal(const std::string&
btVector3 shift(0, 0, 0);
std::vector<tinyobj::shape_t> shapes;
tinyobj::attrib_t attribute;
{
B3_PROFILE("tinyobj::LoadObj");
std::string err = LoadFromCachedOrFromObj(shapes, relativeFileName, pathPrefix,fileIO);
std::string err = LoadFromCachedOrFromObj(attribute, shapes, relativeFileName, pathPrefix, fileIO);
//std::string err = tinyobj::LoadObj(shapes, relativeFileName, pathPrefix);
}
GLInstanceGraphicsShape* gfxShape = btgCreateGraphicsShapeFromWavefrontObj(shapes);
GLInstanceGraphicsShape* gfxShape = btgCreateGraphicsShapeFromWavefrontObj(attribute, shapes);
{
B3_PROFILE("Load Texture");
//int textureIndex = -1;
@@ -84,7 +85,7 @@ bool b3ImportMeshUtility::loadAndRegisterMeshFromFileInternal(const std::string&
meshData.m_rgbaColor[2] = shape.material.diffuse[2];
meshData.m_rgbaColor[3] = shape.material.transparency;
meshData.m_flags |= B3_IMPORT_MESH_HAS_RGBA_COLOR;
meshData.m_specularColor[0] = shape.material.specular[0];
meshData.m_specularColor[1] = shape.material.specular[1];
meshData.m_specularColor[2] = shape.material.specular[2];

View File

@@ -12,6 +12,7 @@ struct CachedObjResult
{
std::string m_msg;
std::vector<tinyobj::shape_t> m_shapes;
tinyobj::attrib_t m_attribute;
};
static b3HashMap<b3HashString, CachedObjResult> gCachedObjResults;
@@ -31,24 +32,26 @@ void b3EnableFileCaching(int enable)
}
std::string LoadFromCachedOrFromObj(
tinyobj::attrib_t& attribute,
std::vector<tinyobj::shape_t>& shapes, // [output]
const char* filename,
const char* mtl_basepath,
struct CommonFileIOInterface* fileIO
)
struct CommonFileIOInterface* fileIO)
{
CachedObjResult* resultPtr = gCachedObjResults[filename];
if (resultPtr)
{
const CachedObjResult& result = *resultPtr;
shapes = result.m_shapes;
attribute = result.m_attribute;
return result.m_msg;
}
std::string err = tinyobj::LoadObj(shapes, filename, mtl_basepath,fileIO);
std::string err = tinyobj::LoadObj(attribute, shapes, filename, mtl_basepath, fileIO);
CachedObjResult result;
result.m_msg = err;
result.m_shapes = shapes;
result.m_attribute = attribute;
if (gEnableFileCaching)
{
gCachedObjResults.insert(filename, result);
@@ -60,14 +63,15 @@ GLInstanceGraphicsShape* LoadMeshFromObj(const char* relativeFileName, const cha
{
B3_PROFILE("LoadMeshFromObj");
std::vector<tinyobj::shape_t> shapes;
tinyobj::attrib_t attribute;
{
B3_PROFILE("tinyobj::LoadObj2");
std::string err = LoadFromCachedOrFromObj(shapes, relativeFileName, materialPrefixPath,fileIO);
std::string err = LoadFromCachedOrFromObj(attribute, shapes, relativeFileName, materialPrefixPath, fileIO);
}
{
B3_PROFILE("btgCreateGraphicsShapeFromWavefrontObj");
GLInstanceGraphicsShape* gfxShape = btgCreateGraphicsShapeFromWavefrontObj(shapes);
GLInstanceGraphicsShape* gfxShape = btgCreateGraphicsShapeFromWavefrontObj(attribute, shapes);
return gfxShape;
}
}

View File

@@ -8,8 +8,8 @@ struct GLInstanceGraphicsShape;
int b3IsFileCachingEnabled();
void b3EnableFileCaching(int enable);
std::string LoadFromCachedOrFromObj(
tinyobj::attrib_t& attribute,
std::vector<tinyobj::shape_t>& shapes, // [output]
const char* filename,
const char* mtl_basepath,

View File

@@ -9,7 +9,7 @@
#include "../../OpenGLWindow/GLInstancingRenderer.h"
#include "../../OpenGLWindow/GLInstanceGraphicsShape.h"
GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(std::vector<tinyobj::shape_t>& shapes, bool flatShading)
GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(const tinyobj::attrib_t& attribute, std::vector<tinyobj::shape_t>& shapes, bool flatShading)
{
b3AlignedObjectArray<GLInstanceVertex>* vertices = new b3AlignedObjectArray<GLInstanceVertex>;
{
@@ -36,19 +36,20 @@ GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(std::vector<tiny
}
GLInstanceVertex vtx0;
vtx0.xyzw[0] = shape.mesh.positions[shape.mesh.indices[f] * 3 + 0];
vtx0.xyzw[1] = shape.mesh.positions[shape.mesh.indices[f] * 3 + 1];
vtx0.xyzw[2] = shape.mesh.positions[shape.mesh.indices[f] * 3 + 2];
tinyobj::index_t v_0 = shape.mesh.indices[f];
vtx0.xyzw[0] = attribute.vertices[3 * v_0.vertex_index];
vtx0.xyzw[1] = attribute.vertices[3 * v_0.vertex_index + 1];
vtx0.xyzw[2] = attribute.vertices[3 * v_0.vertex_index + 2];
vtx0.xyzw[3] = 0.f;
if (shape.mesh.texcoords.size())
if (attribute.texcoords.size())
{
int uv0Index = shape.mesh.indices[f] * 2 + 0;
int uv1Index = shape.mesh.indices[f] * 2 + 1;
if (uv0Index >= 0 && uv1Index >= 0 && (uv0Index < int(shape.mesh.texcoords.size()) && (uv1Index < shape.mesh.texcoords.size())))
int uv0Index = 2 * v_0.texcoord_index;
int uv1Index = 2 * v_0.texcoord_index + 1;
if (uv0Index >= 0 && uv1Index >= 0 && (uv0Index < int(attribute.texcoords.size()) && (uv1Index < attribute.texcoords.size())))
{
vtx0.uv[0] = shape.mesh.texcoords[uv0Index];
vtx0.uv[1] = shape.mesh.texcoords[uv1Index];
vtx0.uv[0] = attribute.texcoords[uv0Index];
vtx0.uv[1] = attribute.texcoords[uv1Index];
}
else
{
@@ -64,19 +65,20 @@ GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(std::vector<tiny
}
GLInstanceVertex vtx1;
vtx1.xyzw[0] = shape.mesh.positions[shape.mesh.indices[f + 1] * 3 + 0];
vtx1.xyzw[1] = shape.mesh.positions[shape.mesh.indices[f + 1] * 3 + 1];
vtx1.xyzw[2] = shape.mesh.positions[shape.mesh.indices[f + 1] * 3 + 2];
tinyobj::index_t v_1 = shape.mesh.indices[f + 1];
vtx1.xyzw[0] = attribute.vertices[3 * v_1.vertex_index];
vtx1.xyzw[1] = attribute.vertices[3 * v_1.vertex_index + 1];
vtx1.xyzw[2] = attribute.vertices[3 * v_1.vertex_index + 2];
vtx1.xyzw[3] = 0.f;
if (shape.mesh.texcoords.size())
if (attribute.texcoords.size())
{
int uv0Index = shape.mesh.indices[f + 1] * 2 + 0;
int uv1Index = shape.mesh.indices[f + 1] * 2 + 1;
if (uv0Index >= 0 && uv1Index >= 0 && (uv0Index < shape.mesh.texcoords.size()) && (uv1Index < shape.mesh.texcoords.size()))
int uv0Index = 2 * v_1.texcoord_index;
int uv1Index = 2 * v_1.texcoord_index + 1;
if (uv0Index >= 0 && uv1Index >= 0 && (uv0Index < attribute.texcoords.size()) && (uv1Index < attribute.texcoords.size()))
{
vtx1.uv[0] = shape.mesh.texcoords[uv0Index];
vtx1.uv[1] = shape.mesh.texcoords[uv1Index];
vtx1.uv[0] = attribute.texcoords[uv0Index];
vtx1.uv[1] = attribute.texcoords[uv1Index];
}
else
{
@@ -92,22 +94,24 @@ GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(std::vector<tiny
}
GLInstanceVertex vtx2;
vtx2.xyzw[0] = shape.mesh.positions[shape.mesh.indices[f + 2] * 3 + 0];
vtx2.xyzw[1] = shape.mesh.positions[shape.mesh.indices[f + 2] * 3 + 1];
vtx2.xyzw[2] = shape.mesh.positions[shape.mesh.indices[f + 2] * 3 + 2];
tinyobj::index_t v_2 = shape.mesh.indices[f + 2];
vtx2.xyzw[0] = attribute.vertices[3 * v_2.vertex_index];
vtx2.xyzw[1] = attribute.vertices[3 * v_2.vertex_index + 1];
vtx2.xyzw[2] = attribute.vertices[3 * v_2.vertex_index + 2];
vtx2.xyzw[3] = 0.f;
if (shape.mesh.texcoords.size())
if (attribute.texcoords.size())
{
int uv0Index = shape.mesh.indices[f + 2] * 2 + 0;
int uv1Index = shape.mesh.indices[f + 2] * 2 + 1;
if (uv0Index >= 0 && uv1Index >= 0 && (uv0Index < shape.mesh.texcoords.size()) && (uv1Index < shape.mesh.texcoords.size()))
int uv0Index = 2 * v_2.texcoord_index;
int uv1Index = 2 * v_2.texcoord_index + 1;
if (uv0Index >= 0 && uv1Index >= 0 && (uv0Index < attribute.texcoords.size()) && (uv1Index < attribute.texcoords.size()))
{
vtx2.uv[0] = shape.mesh.texcoords[uv0Index];
vtx2.uv[1] = shape.mesh.texcoords[uv1Index];
vtx2.uv[0] = attribute.texcoords[uv0Index];
vtx2.uv[1] = attribute.texcoords[uv1Index];
}
else
{
b3Warning("obj texture coordinate out-of-range!");
//b3Warning("obj texture coordinate out-of-range!");
vtx2.uv[0] = 0;
vtx2.uv[1] = 0;
}
@@ -123,16 +127,21 @@ GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(std::vector<tiny
btVector3 v2(vtx2.xyzw[0], vtx2.xyzw[1], vtx2.xyzw[2]);
unsigned int maxIndex = 0;
maxIndex = b3Max(maxIndex, shape.mesh.indices[f] * 3 + 0);
maxIndex = b3Max(maxIndex, shape.mesh.indices[f] * 3 + 1);
maxIndex = b3Max(maxIndex, shape.mesh.indices[f] * 3 + 2);
maxIndex = b3Max(maxIndex, shape.mesh.indices[f + 1] * 3 + 0);
maxIndex = b3Max(maxIndex, shape.mesh.indices[f + 1] * 3 + 1);
maxIndex = b3Max(maxIndex, shape.mesh.indices[f + 1] * 3 + 2);
maxIndex = b3Max(maxIndex, shape.mesh.indices[f + 2] * 3 + 0);
maxIndex = b3Max(maxIndex, shape.mesh.indices[f + 2] * 3 + 1);
maxIndex = b3Max(maxIndex, shape.mesh.indices[f + 2] * 3 + 2);
bool hasNormals = (shape.mesh.normals.size() && maxIndex < shape.mesh.normals.size());
unsigned n0Index = shape.mesh.indices[f].normal_index;
unsigned n1Index = shape.mesh.indices[f + 1].normal_index;
unsigned n2Index = shape.mesh.indices[f + 2].normal_index;
maxIndex = b3Max(maxIndex, 3 * n0Index + 0);
maxIndex = b3Max(maxIndex, 3 * n0Index + 1);
maxIndex = b3Max(maxIndex, 3 * n0Index + 2);
maxIndex = b3Max(maxIndex, 3 * n1Index + 0);
maxIndex = b3Max(maxIndex, 3 * n1Index + 1);
maxIndex = b3Max(maxIndex, 3 * n1Index + 2);
maxIndex = b3Max(maxIndex, 3 * n2Index + 0);
maxIndex = b3Max(maxIndex, 3 * n2Index + 1);
maxIndex = b3Max(maxIndex, 3 * n2Index + 2);
bool hasNormals = (attribute.normals.size() && maxIndex < attribute.normals.size());
if (flatShading || !hasNormals)
{
@@ -159,15 +168,15 @@ GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(std::vector<tiny
}
else
{
vtx0.normal[0] = shape.mesh.normals[shape.mesh.indices[f] * 3 + 0];
vtx0.normal[1] = shape.mesh.normals[shape.mesh.indices[f] * 3 + 1];
vtx0.normal[2] = shape.mesh.normals[shape.mesh.indices[f] * 3 + 2]; //shape.mesh.indices[f+1]*3+0
vtx1.normal[0] = shape.mesh.normals[shape.mesh.indices[f + 1] * 3 + 0];
vtx1.normal[1] = shape.mesh.normals[shape.mesh.indices[f + 1] * 3 + 1];
vtx1.normal[2] = shape.mesh.normals[shape.mesh.indices[f + 1] * 3 + 2];
vtx2.normal[0] = shape.mesh.normals[shape.mesh.indices[f + 2] * 3 + 0];
vtx2.normal[1] = shape.mesh.normals[shape.mesh.indices[f + 2] * 3 + 1];
vtx2.normal[2] = shape.mesh.normals[shape.mesh.indices[f + 2] * 3 + 2];
vtx0.normal[0] = attribute.normals[3 * n0Index+ 0];
vtx0.normal[1] = attribute.normals[3 * n0Index+ 1];
vtx0.normal[2] = attribute.normals[3 * n0Index+ 2];
vtx1.normal[0] = attribute.normals[3 * n1Index+ 0];
vtx1.normal[1] = attribute.normals[3 * n1Index+ 1];
vtx1.normal[2] = attribute.normals[3 * n1Index+ 2];
vtx2.normal[0] = attribute.normals[3 * n2Index+ 0];
vtx2.normal[1] = attribute.normals[3 * n2Index+ 1];
vtx2.normal[2] = attribute.normals[3 * n2Index+ 2];
}
vertices->push_back(vtx0);
vertices->push_back(vtx1);

View File

@@ -4,6 +4,6 @@
#include "../../ThirdPartyLibs/Wavefront/tiny_obj_loader.h"
#include <vector>
struct GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(std::vector<tinyobj::shape_t>& shapes, bool flatShading = false);
struct GLInstanceGraphicsShape* btgCreateGraphicsShapeFromWavefrontObj(const tinyobj::attrib_t& attribute, std::vector<tinyobj::shape_t>& shapes, bool flatShading = false);
#endif //WAVEFRONT2GRAPHICS_H

View File

@@ -509,7 +509,7 @@ bool BulletURDFImporter::getRootTransformInWorld(btTransform& rootTransformInWor
return true;
}
static btCollisionShape* createConvexHullFromShapes(std::vector<tinyobj::shape_t>& shapes, const btVector3& geomScale, int flags)
static btCollisionShape* createConvexHullFromShapes(const tinyobj::attrib_t& attribute, std::vector<tinyobj::shape_t>& shapes, const btVector3& geomScale, int flags)
{
B3_PROFILE("createConvexHullFromShapes");
btCompoundShape* compound = new btCompoundShape();
@@ -528,20 +528,20 @@ static btCollisionShape* createConvexHullFromShapes(std::vector<tinyobj::shape_t
for (int f = 0; f < faceCount; f += 3)
{
btVector3 pt;
pt.setValue(shape.mesh.positions[shape.mesh.indices[f] * 3 + 0],
shape.mesh.positions[shape.mesh.indices[f] * 3 + 1],
shape.mesh.positions[shape.mesh.indices[f] * 3 + 2]);
pt.setValue(attribute.vertices[3 * shape.mesh.indices[f + 0].vertex_index + 0],
attribute.vertices[3 * shape.mesh.indices[f + 0].vertex_index + 1],
attribute.vertices[3 * shape.mesh.indices[f + 0].vertex_index + 2]);
convexHull->addPoint(pt * geomScale, false);
pt.setValue(shape.mesh.positions[shape.mesh.indices[f + 1] * 3 + 0],
shape.mesh.positions[shape.mesh.indices[f + 1] * 3 + 1],
shape.mesh.positions[shape.mesh.indices[f + 1] * 3 + 2]);
pt.setValue(attribute.vertices[3 * shape.mesh.indices[f + 1].vertex_index + 0],
attribute.vertices[3 * shape.mesh.indices[f + 1].vertex_index + 1],
attribute.vertices[3 * shape.mesh.indices[f + 1].vertex_index + 2]);
convexHull->addPoint(pt * geomScale, false);
pt.setValue(shape.mesh.positions[shape.mesh.indices[f + 2] * 3 + 0],
shape.mesh.positions[shape.mesh.indices[f + 2] * 3 + 1],
shape.mesh.positions[shape.mesh.indices[f + 2] * 3 + 2]);
pt.setValue(attribute.vertices[3 * shape.mesh.indices[f + 2].vertex_index + 0],
attribute.vertices[3 * shape.mesh.indices[f + 2].vertex_index + 1],
attribute.vertices[3 * shape.mesh.indices[f + 2].vertex_index + 2]);
convexHull->addPoint(pt * geomScale, false);
}
@@ -558,8 +558,6 @@ static btCollisionShape* createConvexHullFromShapes(std::vector<tinyobj::shape_t
return compound;
}
int BulletURDFImporter::getUrdfFromCollisionShape(const btCollisionShape* collisionShape, UrdfCollision& collision) const
{
UrdfCollision* col = m_data->m_bulletCollisionShape2UrdfCollision.find(collisionShape);
@@ -718,10 +716,10 @@ btCollisionShape* BulletURDFImporter::convertURDFToCollisionShape(const UrdfColl
else
{
std::vector<tinyobj::shape_t> shapes;
std::string err = tinyobj::LoadObj(shapes, collision->m_geometry.m_meshFileName.c_str(),"",m_data->m_fileIO);
tinyobj::attrib_t attribute;
std::string err = tinyobj::LoadObj(attribute, shapes, collision->m_geometry.m_meshFileName.c_str(), "", m_data->m_fileIO);
//create a convex hull for each shape, and store it in a btCompoundShape
shape = createConvexHullFromShapes(shapes, collision->m_geometry.m_meshScale, m_data->m_flags);
shape = createConvexHullFromShapes(attribute, shapes, collision->m_geometry.m_meshScale, m_data->m_flags);
m_data->m_bulletCollisionShape2UrdfCollision.insert(shape, *collision);
return shape;
}

View File

@@ -45,6 +45,10 @@ static bool UrdfFindMeshFile(
{
*out_type = UrdfGeometry::FILE_CDF;
}
else if (ext == ".vtk")
{
*out_type = UrdfGeometry::FILE_VTK;
}
else
{
b3Warning("%s: invalid mesh filename extension '%s'\n", error_message_prefix.c_str(), ext.c_str());
@@ -115,4 +119,4 @@ static bool UrdfFindMeshFile(
}
}
#endif //URDF_FIND_MESH_FILE_H
#endif //URDF_FIND_MESH_FILE_H

View File

@@ -82,6 +82,7 @@ struct UrdfGeometry
FILE_OBJ = 3,
FILE_CDF = 4,
MEMORY_VERTICES = 5,
FILE_VTK = 6,
};
int m_meshFileType;

View File

@@ -100,7 +100,7 @@ void DoUpdateStep(double Tstep, Tree& treeY, Jacobian* jacob, int ikMethod)
jacob->SetJendActive();
}
jacob->ComputeJacobian(targetaa); // Set up Jacobian and deltaS vectors
MatrixRmn AugMat;
// Calculate the change in theta values
switch (ikMethod)
{
@@ -108,7 +108,7 @@ void DoUpdateStep(double Tstep, Tree& treeY, Jacobian* jacob, int ikMethod)
jacob->CalcDeltaThetasTranspose(); // Jacobian transpose method
break;
case IK_DLS:
jacob->CalcDeltaThetasDLS(); // Damped least squares method
jacob->CalcDeltaThetasDLS(AugMat); // Damped least squares method
break;
case IK_DLS_SVD:
jacob->CalcDeltaThetasDLSwithSVD();

View File

@@ -0,0 +1,358 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
///create 125 (5x5x5) dynamic object
#define ARRAY_SIZE_X 5
#define ARRAY_SIZE_Y 5
#define ARRAY_SIZE_Z 5
//maximum number of objects (and allow user to shoot additional boxes)
#define MAX_PROXIES (ARRAY_SIZE_X * ARRAY_SIZE_Y * ARRAY_SIZE_Z + 1024)
///scaling of the objects (0.1 = 20 centimeter boxes )
#define SCALING 1.
#define START_POS_X -5
#define START_POS_Y -5
#define START_POS_Z -3
#include "MultiBodyBaseline.h"
///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files.
#include "btBulletDynamicsCommon.h"
#include "BulletSoftBody/btDeformableRigidDynamicsWorld.h"
#include "BulletSoftBody/btSoftBody.h"
#include "BulletSoftBody/btSoftBodyHelpers.h"
#include "BulletSoftBody/btDeformableBodySolver.h"
#include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
#include "BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h"
#include <stdio.h> //printf debugging
#include "../CommonInterfaces/CommonRigidBodyBase.h"
#include "../Utils/b3ResourcePath.h"
#include "../SoftDemo/BunnyMesh.h"
#include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h"
#include "BulletDynamics/Featherstone/btMultiBodyJointFeedback.h"
#include "../CommonInterfaces/CommonMultiBodyBase.h"
#include "../Utils/b3ResourcePath.h"
///The MultiBodyBaseline demo deformable bodies self-collision
static bool g_floatingBase = true;
static float friction = 1.;
class MultiBodyBaseline : public CommonMultiBodyBase
{
btMultiBody* m_multiBody;
btAlignedObjectArray<btMultiBodyJointFeedback*> m_jointFeedbacks;
public:
MultiBodyBaseline(struct GUIHelperInterface* helper)
: CommonMultiBodyBase(helper)
{
}
virtual ~MultiBodyBaseline()
{
}
void initPhysics();
void exitPhysics();
void resetCamera()
{
float dist = 30;
float pitch = -30;
float yaw = 100;
float targetPos[3] = {0, -10, 0};
m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]);
}
virtual void stepSimulation(float deltaTime);
btMultiBody* createFeatherstoneMultiBody_testMultiDof(class btMultiBodyDynamicsWorld* world, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical = false, bool floating = false);
void addColliders_testMultiDof(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents);
};
void MultiBodyBaseline::initPhysics()
{
m_guiHelper->setUpAxis(1);
///collision configuration contains default setup for memory, collision setup
m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration();
///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded)
m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration);
m_broadphase = new btDbvtBroadphase();
btMultiBodyConstraintSolver* sol;
sol = new btMultiBodyConstraintSolver;
m_solver = sol;
btMultiBodyDynamicsWorld* world = new btMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, sol, m_collisionConfiguration);
m_dynamicsWorld = world;
// m_dynamicsWorld->setDebugDrawer(&gDebugDraw);
m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld);
m_dynamicsWorld->setGravity(btVector3(0, -10, 0));
{
///create a ground
btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(150.), btScalar(25.), btScalar(150.)));
m_collisionShapes.push_back(groundShape);
btTransform groundTransform;
groundTransform.setIdentity();
groundTransform.setOrigin(btVector3(0, -40, 0));
groundTransform.setRotation(btQuaternion(btVector3(1, 0, 0), SIMD_PI * 0.));
//We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here:
btScalar mass(0.);
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.f);
btVector3 localInertia(0, 0, 0);
if (isDynamic)
groundShape->calculateLocalInertia(mass, localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform);
btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia);
btRigidBody* body = new btRigidBody(rbInfo);
body->setFriction(0.5);
//add the ground to the dynamics world
m_dynamicsWorld->addRigidBody(body,1,1+2);
}
{
bool damping = true;
bool gyro = false;
int numLinks = 4;
bool spherical = false; //set it ot false -to use 1DoF hinges instead of 3DoF sphericals
bool canSleep = false;
bool selfCollide = true;
btVector3 linkHalfExtents(1, 1, 1);
btVector3 baseHalfExtents(1, 1, 1);
btMultiBody* mbC = createFeatherstoneMultiBody_testMultiDof(m_dynamicsWorld, numLinks, btVector3(0.f, 10.f,0.f), linkHalfExtents, baseHalfExtents, spherical, g_floatingBase);
mbC->setCanSleep(canSleep);
mbC->setHasSelfCollision(selfCollide);
mbC->setUseGyroTerm(gyro);
//
if (!damping)
{
mbC->setLinearDamping(0.0f);
mbC->setAngularDamping(0.0f);
}
else
{
mbC->setLinearDamping(0.04f);
mbC->setAngularDamping(0.04f);
}
if (numLinks > 0)
{
btScalar q0 = 0.f * SIMD_PI / 180.f;
if (!spherical)
{
mbC->setJointPosMultiDof(0, &q0);
}
else
{
btQuaternion quat0(btVector3(1, 1, 0).normalized(), q0);
quat0.normalize();
mbC->setJointPosMultiDof(0, quat0);
}
}
///
addColliders_testMultiDof(mbC, m_dynamicsWorld, baseHalfExtents, linkHalfExtents);
}
m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld);
}
void MultiBodyBaseline::exitPhysics()
{
//cleanup in the reverse order of creation/initialization
//remove the rigidbodies from the dynamics world and delete them
int i;
for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--)
{
btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i];
btRigidBody* body = btRigidBody::upcast(obj);
if (body && body->getMotionState())
{
delete body->getMotionState();
}
m_dynamicsWorld->removeCollisionObject(obj);
delete obj;
}
//delete collision shapes
for (int j = 0; j < m_collisionShapes.size(); j++)
{
btCollisionShape* shape = m_collisionShapes[j];
delete shape;
}
m_collisionShapes.clear();
delete m_dynamicsWorld;
delete m_solver;
delete m_broadphase;
delete m_dispatcher;
delete m_collisionConfiguration;
}
void MultiBodyBaseline::stepSimulation(float deltaTime)
{
// getDeformableDynamicsWorld()->getMultiBodyDynamicsWorld()->stepSimulation(deltaTime);
m_dynamicsWorld->stepSimulation(deltaTime, 5, 1./250.);
}
btMultiBody* MultiBodyBaseline::createFeatherstoneMultiBody_testMultiDof(btMultiBodyDynamicsWorld* pWorld, int numLinks, const btVector3& basePosition, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents, bool spherical, bool floating)
{
//init the base
btVector3 baseInertiaDiag(0.f, 0.f, 0.f);
float baseMass = .1f;
if (baseMass)
{
btCollisionShape* pTempBox = new btBoxShape(btVector3(baseHalfExtents[0], baseHalfExtents[1], baseHalfExtents[2]));
pTempBox->calculateLocalInertia(baseMass, baseInertiaDiag);
delete pTempBox;
}
bool canSleep = false;
btMultiBody* pMultiBody = new btMultiBody(numLinks, baseMass, baseInertiaDiag, !floating, canSleep);
btQuaternion baseOriQuat(0.f, 0.f, 0.f, 1.f);
pMultiBody->setBasePos(basePosition);
pMultiBody->setWorldToBaseRot(baseOriQuat);
btVector3 vel(0, 0, 0);
// pMultiBody->setBaseVel(vel);
//init the links
btVector3 hingeJointAxis(1, 0, 0);
float linkMass = .1f;
btVector3 linkInertiaDiag(0.f, 0.f, 0.f);
btCollisionShape* pTempBox = new btBoxShape(btVector3(linkHalfExtents[0], linkHalfExtents[1], linkHalfExtents[2]));
pTempBox->calculateLocalInertia(linkMass, linkInertiaDiag);
delete pTempBox;
//y-axis assumed up
btVector3 parentComToCurrentCom(0, -linkHalfExtents[1] * 2.f, 0); //par body's COM to cur body's COM offset
btVector3 currentPivotToCurrentCom(0, -linkHalfExtents[1], 0); //cur body's COM to cur body's PIV offset
btVector3 parentComToCurrentPivot = parentComToCurrentCom - currentPivotToCurrentCom; //par body's COM to cur body's PIV offset
//////
btScalar q0 = 0.f * SIMD_PI / 180.f;
btQuaternion quat0(btVector3(0, 1, 0).normalized(), q0);
quat0.normalize();
/////
for (int i = 0; i < numLinks; ++i)
{
if (!spherical)
pMultiBody->setupRevolute(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), hingeJointAxis, parentComToCurrentPivot, currentPivotToCurrentCom, true);
else
//pMultiBody->setupPlanar(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f)/*quat0*/, btVector3(1, 0, 0), parentComToCurrentPivot*2, false);
pMultiBody->setupSpherical(i, linkMass, linkInertiaDiag, i - 1, btQuaternion(0.f, 0.f, 0.f, 1.f), parentComToCurrentPivot, currentPivotToCurrentCom, true);
}
pMultiBody->finalizeMultiDof();
///
pWorld->addMultiBody(pMultiBody);
///
return pMultiBody;
}
void MultiBodyBaseline::addColliders_testMultiDof(btMultiBody* pMultiBody, btMultiBodyDynamicsWorld* pWorld, const btVector3& baseHalfExtents, const btVector3& linkHalfExtents)
{
btAlignedObjectArray<btQuaternion> world_to_local;
world_to_local.resize(pMultiBody->getNumLinks() + 1);
btAlignedObjectArray<btVector3> local_origin;
local_origin.resize(pMultiBody->getNumLinks() + 1);
world_to_local[0] = pMultiBody->getWorldToBaseRot();
local_origin[0] = pMultiBody->getBasePos();
{
// float pos[4]={local_origin[0].x(),local_origin[0].y(),local_origin[0].z(),1};
btScalar quat[4] = {-world_to_local[0].x(), -world_to_local[0].y(), -world_to_local[0].z(), world_to_local[0].w()};
if (1)
{
btCollisionShape* box = new btBoxShape(baseHalfExtents);
btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, -1);
col->setCollisionShape(box);
btTransform tr;
tr.setIdentity();
tr.setOrigin(local_origin[0]);
tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
col->setWorldTransform(tr);
pWorld->addCollisionObject(col, 2, 1 + 2);
col->setFriction(friction);
pMultiBody->setBaseCollider(col);
}
}
for (int i = 0; i < pMultiBody->getNumLinks(); ++i)
{
const int parent = pMultiBody->getParent(i);
world_to_local[i + 1] = pMultiBody->getParentToLocalRot(i) * world_to_local[parent + 1];
local_origin[i + 1] = local_origin[parent + 1] + (quatRotate(world_to_local[i + 1].inverse(), pMultiBody->getRVector(i)));
}
for (int i = 0; i < pMultiBody->getNumLinks(); ++i)
{
btVector3 posr = local_origin[i + 1];
// float pos[4]={posr.x(),posr.y(),posr.z(),1};
btScalar quat[4] = {-world_to_local[i + 1].x(), -world_to_local[i + 1].y(), -world_to_local[i + 1].z(), world_to_local[i + 1].w()};
btCollisionShape* box = new btBoxShape(linkHalfExtents);
btMultiBodyLinkCollider* col = new btMultiBodyLinkCollider(pMultiBody, i);
col->setCollisionShape(box);
btTransform tr;
tr.setIdentity();
tr.setOrigin(posr);
tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3]));
col->setWorldTransform(tr);
col->setFriction(friction);
pWorld->addCollisionObject(col, 2, 1 + 2);
pMultiBody->getLink(i).m_collider = col;
}
}
class CommonExampleInterface* MultiBodyBaselineCreateFunc(struct CommonExampleOptions& options)
{
return new MultiBodyBaseline(options.m_guiHelper);
}

View File

@@ -0,0 +1,20 @@
/*
Bullet Continuous Collision Detection and Physics Library
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
This software is provided 'as-is', without any express or implied warranty.
In no event will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it freely,
subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _MULTIBODY_BASELINE_H
#define _MULTIBODY_BASELINE_H
class CommonExampleInterface* MultiBodyBaselineCreateFunc(struct CommonExampleOptions& options);
#endif //_MULTIBODY_BASELINE_H

View File

@@ -29,13 +29,14 @@ void SamplelsMemoryReleaseFunc(void* ptr);
#ifndef _WIN32
#include "b3PosixThreadSupport.h"
b3ThreadSupportInterface* createThreadSupport(int numThreads)
{
b3PosixThreadSupport::ThreadConstructionInfo constructionInfo("testThreads",
SampleThreadFunc,
SamplelsMemoryFunc,
SamplelsMemoryReleaseFunc,
numThreads);
SampleThreadFunc,
SamplelsMemoryFunc,
SamplelsMemoryReleaseFunc,
numThreads);
b3ThreadSupportInterface* threadSupport = new b3PosixThreadSupport(constructionInfo);
return threadSupport;

View File

@@ -22,7 +22,7 @@ subject to the following restrictions:
void SampleThreadFunc(void* userPtr, void* lsMemory);
void* SamplelsMemoryFunc();
void SamplelsMemoryReleaseFunc(void* ptr);
#include <stdio.h>
//#include "BulletMultiThreaded/PlatformDefinitions.h"
@@ -34,6 +34,7 @@ b3ThreadSupportInterface* createThreadSupport(int numThreads)
b3PosixThreadSupport::ThreadConstructionInfo constructionInfo("testThreads",
SampleThreadFunc,
SamplelsMemoryFunc,
SamplelsMemoryReleaseFunc,
numThreads);
b3ThreadSupportInterface* threadSupport = new b3PosixThreadSupport(constructionInfo);
@@ -99,6 +100,13 @@ void* SamplelsMemoryFunc()
return new SampleThreadLocalStorage;
}
void SamplelsMemoryReleaseFunc(void* ptr)
{
SampleThreadLocalStorage* p = (SampleThreadLocalStorage*)ptr;
delete p;
}
int main(int argc, char** argv)
{
int numThreads = 8;

View File

@@ -139,11 +139,7 @@ static InternalDataRenderer* sData2;
GLint lineWidthRange[2] = {1, 1};
enum
{
eGfxTransparency = 1,
eGfxHasTexture = 2,
};
struct b3GraphicsInstance
{
@@ -492,6 +488,26 @@ void GLInstancingRenderer::readSingleInstanceTransformFromCPU(int srcIndex2, flo
orientation[2] = m_data->m_instance_quaternion_ptr[srcIndex * 4 + 2];
orientation[3] = m_data->m_instance_quaternion_ptr[srcIndex * 4 + 3];
}
void GLInstancingRenderer::writeSingleInstanceFlagsToCPU(int flags, int srcIndex2)
{
b3PublicGraphicsInstance* pg = m_data->m_publicGraphicsInstances.getHandle(srcIndex2);
b3Assert(pg);
int srcIndex = pg->m_internalInstanceIndex;
int shapeIndex = pg->m_shapeIndex;
b3GraphicsInstance* gfxObj = m_graphicsInstances[shapeIndex];
if (flags & B3_INSTANCE_DOUBLE_SIDED)
{
gfxObj->m_flags |= B3_INSTANCE_DOUBLE_SIDED;
}
else
{
gfxObj->m_flags &= ~B3_INSTANCE_DOUBLE_SIDED;
}
}
void GLInstancingRenderer::writeSingleInstanceColorToCPU(const double* color, int srcIndex2)
{
b3PublicGraphicsInstance* pg = m_data->m_publicGraphicsInstances.getHandle(srcIndex2);
@@ -502,11 +518,11 @@ void GLInstancingRenderer::writeSingleInstanceColorToCPU(const double* color, in
b3GraphicsInstance* gfxObj = m_graphicsInstances[shapeIndex];
if (color[3] < 1)
{
gfxObj->m_flags |= eGfxTransparency;
gfxObj->m_flags |= B3_INSTANCE_TRANSPARANCY;
}
else
{
gfxObj->m_flags &= ~eGfxTransparency;
gfxObj->m_flags &= ~B3_INSTANCE_TRANSPARANCY;
}
m_data->m_instance_colors_ptr[srcIndex * 4 + 0] = float(color[0]);
@@ -525,11 +541,11 @@ void GLInstancingRenderer::writeSingleInstanceColorToCPU(const float* color, int
if (color[3] < 1)
{
gfxObj->m_flags |= eGfxTransparency;
gfxObj->m_flags |= B3_INSTANCE_TRANSPARANCY;
}
else
{
gfxObj->m_flags &= ~eGfxTransparency;
gfxObj->m_flags &= ~B3_INSTANCE_TRANSPARANCY;
}
m_data->m_instance_colors_ptr[srcIndex * 4 + 0] = color[0];
@@ -916,7 +932,7 @@ int GLInstancingRenderer::registerGraphicsInstanceInternal(int newUid, const flo
if (color[3] < 1 && color[3] > 0)
{
gfxObj->m_flags |= eGfxTransparency;
gfxObj->m_flags |= B3_INSTANCE_TRANSPARANCY;
}
gfxObj->m_numGraphicsInstances++;
m_data->m_totalNumInstances++;
@@ -1018,11 +1034,11 @@ void GLInstancingRenderer::replaceTexture(int shapeIndex, int textureId)
if (textureId >= 0 && textureId < m_data->m_textureHandles.size())
{
gfxObj->m_textureIndex = textureId;
gfxObj->m_flags |= eGfxHasTexture;
gfxObj->m_flags |= B3_INSTANCE_TEXTURE;
} else
{
gfxObj->m_textureIndex = -1;
gfxObj->m_flags &= ~eGfxHasTexture;
gfxObj->m_flags &= ~B3_INSTANCE_TEXTURE;
}
}
}
@@ -1110,7 +1126,7 @@ int GLInstancingRenderer::registerShape(const float* vertices, int numvertices,
if (textureId >= 0)
{
gfxObj->m_textureIndex = textureId;
gfxObj->m_flags |= eGfxHasTexture;
gfxObj->m_flags |= B3_INSTANCE_TEXTURE;
}
gfxObj->m_primitiveType = primitiveType;
@@ -1754,6 +1770,7 @@ static void b3CreateLookAt(const b3Vector3& eye, const b3Vector3& center, const
result[3 * 4 + 3] = 1.f;
}
void GLInstancingRenderer::drawTexturedTriangleMesh(float worldPosition[3], float worldOrientation[4], const float* vertices, int numvertices, const unsigned int* indices, int numIndices, float colorRGBA[4], int textureIndex, int vertexLayout)
{
int sz = sizeof(GfxVertexFormat0);
@@ -2263,7 +2280,7 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode)
inst.m_shapeIndex = obj;
if ((gfxObj->m_flags & eGfxTransparency) == 0)
if ((gfxObj->m_flags & B3_INSTANCE_TRANSPARANCY) == 0)
{
inst.m_instanceId = curOffset;
b3Vector3 centerPosition;
@@ -2313,10 +2330,10 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode)
b3GraphicsInstance* gfxObj = m_graphicsInstances[shapeIndex];
//only draw stuff (opaque/transparent) if it is the right pass
int drawThisPass = (pass == 0) == ((gfxObj->m_flags & eGfxTransparency) == 0);
int drawThisPass = (pass == 0) == ((gfxObj->m_flags & B3_INSTANCE_TRANSPARANCY) == 0);
//transparent objects don't cast shadows (to simplify things)
if (gfxObj->m_flags & eGfxTransparency)
if (gfxObj->m_flags & B3_INSTANCE_TRANSPARANCY)
{
if (renderMode == B3_CREATE_SHADOWMAP_RENDERMODE)
drawThisPass = 0;
@@ -2326,7 +2343,7 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode)
{
glActiveTexture(GL_TEXTURE0);
GLuint curBindTexture = 0;
if (gfxObj->m_flags & eGfxHasTexture)
if (gfxObj->m_flags & B3_INSTANCE_TEXTURE)
{
curBindTexture = m_data->m_textureHandles[gfxObj->m_textureIndex].m_glTexture;
@@ -2432,6 +2449,11 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode)
}
else
{
if (gfxObj->m_flags & B3_INSTANCE_DOUBLE_SIDED)
{
glDisable(GL_CULL_FACE);
}
switch (renderMode)
{
case B3_SEGMENTATION_MASK_RENDERMODE:
@@ -2445,7 +2467,7 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode)
}
case B3_DEFAULT_RENDERMODE:
{
if (gfxObj->m_flags & eGfxTransparency)
if (gfxObj->m_flags & B3_INSTANCE_TRANSPARANCY)
{
glDepthMask(false);
glEnable(GL_BLEND);
@@ -2462,7 +2484,7 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode)
glUniform1i(uniform_texture_diffuse, 0);
if (gfxObj->m_flags & eGfxTransparency)
if (gfxObj->m_flags & B3_INSTANCE_TRANSPARANCY)
{
int instanceId = transparentInstances[i].m_instanceId;
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid*)((instanceId)*4 * sizeof(float) + m_data->m_maxShapeCapacityInBytes));
@@ -2477,7 +2499,7 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode)
glDrawElementsInstanced(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, indexOffset, gfxObj->m_numGraphicsInstances);
}
if (gfxObj->m_flags & eGfxTransparency)
if (gfxObj->m_flags & B3_INSTANCE_TRANSPARANCY)
{
glDisable(GL_BLEND);
glDepthMask(true);
@@ -2495,7 +2517,7 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode)
case B3_USE_SHADOWMAP_RENDERMODE:
{
if (gfxObj->m_flags & eGfxTransparency)
if (gfxObj->m_flags & B3_INSTANCE_TRANSPARANCY)
{
glDepthMask(false);
glEnable(GL_BLEND);
@@ -2549,7 +2571,7 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode)
//gfxObj->m_instanceOffset
if (gfxObj->m_flags & eGfxTransparency)
if (gfxObj->m_flags & B3_INSTANCE_TRANSPARANCY)
{
int instanceId = transparentInstances[i].m_instanceId;
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid*)((instanceId)*4 * sizeof(float) + m_data->m_maxShapeCapacityInBytes));
@@ -2563,7 +2585,7 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode)
glDrawElementsInstanced(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, indexOffset, gfxObj->m_numGraphicsInstances);
}
if (gfxObj->m_flags & eGfxTransparency)
if (gfxObj->m_flags & B3_INSTANCE_TRANSPARANCY)
{
glDisable(GL_BLEND);
glDepthMask(true);
@@ -2577,7 +2599,7 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode)
}
case B3_USE_PROJECTIVE_TEXTURE_RENDERMODE:
{
if (gfxObj->m_flags & eGfxTransparency)
if (gfxObj->m_flags & B3_INSTANCE_TRANSPARANCY)
{
glDepthMask(false);
glEnable(GL_BLEND);
@@ -2617,7 +2639,7 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode)
glUniformMatrix4fv(projectiveTexture_TextureMVP, 1, false, &textureMVP[0]);
//sort transparent objects
if (gfxObj->m_flags & eGfxTransparency)
if (gfxObj->m_flags & B3_INSTANCE_TRANSPARANCY)
{
int instanceId = transparentInstances[i].m_instanceId;
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 0, (GLvoid*)((instanceId)*4 * sizeof(float) + m_data->m_maxShapeCapacityInBytes));
@@ -2631,7 +2653,7 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode)
glDrawElementsInstanced(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, indexOffset, gfxObj->m_numGraphicsInstances);
}
if (gfxObj->m_flags & eGfxTransparency)
if (gfxObj->m_flags & B3_INSTANCE_TRANSPARANCY)
{
glDisable(GL_BLEND);
glDepthMask(true);
@@ -2646,6 +2668,10 @@ void GLInstancingRenderer::renderSceneInternal(int orgRenderMode)
// b3Assert(0);
}
};
if (gfxObj->m_flags & B3_INSTANCE_DOUBLE_SIDED)
{
glEnable(GL_CULL_FACE);
}
}
//glDrawElementsInstanced(GL_LINE_LOOP, indexCount, GL_UNSIGNED_INT, (void*)indexOffset, gfxObj->m_numGraphicsInstances);

View File

@@ -95,6 +95,7 @@ public:
virtual void writeSingleInstanceColorToCPU(const float* color, int srcIndex);
virtual void writeSingleInstanceColorToCPU(const double* color, int srcIndex);
virtual void writeSingleInstanceFlagsToCPU(int flags, int srcIndex2);
virtual void writeSingleInstanceSpecularColorToCPU(const double* specular, int srcIndex2);
virtual void writeSingleInstanceSpecularColorToCPU(const float* specular, int srcIndex2);

View File

@@ -1,8 +1,11 @@
#ifndef B3_USE_GLFW
#define __OBJC2__ 1
#include <Foundation/NSExtensionContext.h>
#include "MacOpenGLWindowObjC.h"
#define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
#import <Cocoa/Cocoa.h>
#include "OpenGLInclude.h"

View File

@@ -40,7 +40,7 @@ public:
virtual void writeSingleInstanceScaleToCPU(const double* scale, int srcIndex);
virtual void writeSingleInstanceSpecularColorToCPU(const double* specular, int srcIndex) {}
virtual void writeSingleInstanceSpecularColorToCPU(const float* specular, int srcIndex) {}
virtual void writeSingleInstanceFlagsToCPU(int flags, int srcIndex) {}
virtual void getCameraViewMatrix(float viewMat[16]) const;
virtual void getCameraProjectionMatrix(float projMat[16]) const;
virtual void drawTexturedTriangleMesh(float worldPosition[3], float worldOrientation[4], const float* vertices, int numvertices, const unsigned int* indices, int numIndices, float color[4], int textureIndex = -1, int vertexLayout = 0)

View File

@@ -66,6 +66,8 @@ struct SimpleInternalData
int m_upAxis; //y=1 or z=2 is supported
int m_customViewPortWidth;
int m_customViewPortHeight;
int m_mp4Fps;
SimpleInternalData()
: m_fontTextureId(0),
m_largeFontTextureId(0),
@@ -82,7 +84,8 @@ struct SimpleInternalData
m_userPointer(0),
m_upAxis(1),
m_customViewPortWidth(-1),
m_customViewPortHeight(-1)
m_customViewPortHeight(-1),
m_mp4Fps(60)
{
}
};
@@ -1089,6 +1092,11 @@ void SimpleOpenGL3App::swapBuffer()
m_window->startRendering();
}
void SimpleOpenGL3App::setMp4Fps(int fps)
{
m_data->m_mp4Fps = fps;
}
// see also http://blog.mmacklin.com/2013/06/11/real-time-video-capture-with-ffmpeg/
void SimpleOpenGL3App::dumpFramesToVideo(const char* mp4FileName)
{
@@ -1098,27 +1106,11 @@ void SimpleOpenGL3App::dumpFramesToVideo(const char* mp4FileName)
int height = (int)m_window->getRetinaScale() * m_instancingRenderer->getScreenHeight();
char cmd[8192];
#ifdef _WIN32
sprintf(cmd,
"ffmpeg -r 60 -f rawvideo -pix_fmt rgba -s %dx%d -i - "
"ffmpeg -r %d -f rawvideo -pix_fmt rgba -s %dx%d -i - "
"-threads 0 -y -b:v 50000k -c:v libx264 -preset slow -crf 22 -an -pix_fmt yuv420p -vf vflip %s",
width, height, mp4FileName);
m_data->m_mp4Fps, width, height, mp4FileName);
//sprintf(cmd, "ffmpeg -r 60 -f rawvideo -pix_fmt rgba -s %dx%d -i - "
// "-y -crf 0 -b:v 1500000 -an -vcodec h264 -vf vflip %s", width, height, mp4FileName);
#else
sprintf(cmd,
"ffmpeg -r 60 -f rawvideo -pix_fmt rgba -s %dx%d -i - "
"-threads 0 -y -b 50000k -c:v libx264 -preset slow -crf 22 -an -pix_fmt yuv420p -vf vflip %s",
width, height, mp4FileName);
#endif
//sprintf(cmd,"ffmpeg -r 60 -f rawvideo -pix_fmt rgba -s %dx%d -i - "
// "-threads 0 -y -crf 0 -b 50000k -vf vflip %s",width,height,mp4FileName);
// sprintf(cmd,"ffmpeg -r 60 -f rawvideo -pix_fmt rgba -s %dx%d -i - "
// "-threads 0 -preset fast -y -crf 21 -vf vflip %s",width,height,mp4FileName);
if (m_data->m_ffmpegFile)
{

View File

@@ -14,6 +14,7 @@ struct SimpleOpenGL3App : public CommonGraphicsApp
class GLPrimitiveRenderer* m_primRenderer;
class GLInstancingRenderer* m_instancingRenderer;
virtual void setBackgroundColor(float red, float green, float blue);
virtual void setMp4Fps(int fps);
SimpleOpenGL3App(const char* title, int width, int height, bool allowRetina = true, int windowType = 0, int renderDevice = -1, int maxNumObjectCapacity = 128 * 1024, int maxShapeCapacityInBytes = 128 * 1024 * 1024);

View File

@@ -294,6 +294,102 @@ public:
slider.m_maxVal = 1;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{
b3RobotSimulatorLoadFileResults results;
m_robotSim.loadSDF("gripper/wsg50_one_motor_gripper_new.sdf", results);
if (results.m_uniqueObjectIds.size() == 1)
{
m_gripperIndex = results.m_uniqueObjectIds[0];
int numJoints = m_robotSim.getNumJoints(m_gripperIndex);
b3Printf("numJoints = %d", numJoints);
for (int i = 0; i < numJoints; i++)
{
b3JointInfo jointInfo;
m_robotSim.getJointInfo(m_gripperIndex, i, &jointInfo);
b3Printf("joint[%d].m_jointName=%s", i, jointInfo.m_jointName);
}
for (int i = 0; i < 8; i++)
{
b3RobotSimulatorJointMotorArgs controlArgs(CONTROL_MODE_VELOCITY);
controlArgs.m_maxTorqueValue = 0.0;
m_robotSim.setJointMotorControl(m_gripperIndex, i, controlArgs);
}
}
}
{
b3RobotSimulatorLoadUrdfFileArgs args;
args.m_startPosition.setValue(0, 0, -0.2);
args.m_startOrientation.setEulerZYX(0, 0, 0);
m_robotSim.loadURDF("plane.urdf", args);
}
m_robotSim.setGravity(btVector3(0, 0, -10));
b3RobotSimulatorLoadSoftBodyArgs args(0.1, 1, 0.02);
args.m_startPosition.setValue(0, 0, 5);
args.m_startOrientation.setValue(1, 0, 0, 1);
m_robotSim.loadSoftBody("bunny.obj", args);
b3JointInfo revoluteJoint1;
revoluteJoint1.m_parentFrame[0] = -0.055;
revoluteJoint1.m_parentFrame[1] = 0;
revoluteJoint1.m_parentFrame[2] = 0.02;
revoluteJoint1.m_parentFrame[3] = 0;
revoluteJoint1.m_parentFrame[4] = 0;
revoluteJoint1.m_parentFrame[5] = 0;
revoluteJoint1.m_parentFrame[6] = 1.0;
revoluteJoint1.m_childFrame[0] = 0;
revoluteJoint1.m_childFrame[1] = 0;
revoluteJoint1.m_childFrame[2] = 0;
revoluteJoint1.m_childFrame[3] = 0;
revoluteJoint1.m_childFrame[4] = 0;
revoluteJoint1.m_childFrame[5] = 0;
revoluteJoint1.m_childFrame[6] = 1.0;
revoluteJoint1.m_jointAxis[0] = 1.0;
revoluteJoint1.m_jointAxis[1] = 0.0;
revoluteJoint1.m_jointAxis[2] = 0.0;
revoluteJoint1.m_jointType = ePoint2PointType;
b3JointInfo revoluteJoint2;
revoluteJoint2.m_parentFrame[0] = 0.055;
revoluteJoint2.m_parentFrame[1] = 0;
revoluteJoint2.m_parentFrame[2] = 0.02;
revoluteJoint2.m_parentFrame[3] = 0;
revoluteJoint2.m_parentFrame[4] = 0;
revoluteJoint2.m_parentFrame[5] = 0;
revoluteJoint2.m_parentFrame[6] = 1.0;
revoluteJoint2.m_childFrame[0] = 0;
revoluteJoint2.m_childFrame[1] = 0;
revoluteJoint2.m_childFrame[2] = 0;
revoluteJoint2.m_childFrame[3] = 0;
revoluteJoint2.m_childFrame[4] = 0;
revoluteJoint2.m_childFrame[5] = 0;
revoluteJoint2.m_childFrame[6] = 1.0;
revoluteJoint2.m_jointAxis[0] = 1.0;
revoluteJoint2.m_jointAxis[1] = 0.0;
revoluteJoint2.m_jointAxis[2] = 0.0;
revoluteJoint2.m_jointType = ePoint2PointType;
m_robotSim.createConstraint(0, 2, 0, 4, &revoluteJoint1);
m_robotSim.createConstraint(0, 3, 0, 6, &revoluteJoint2);
}
if ((m_options & eGRASP_DEFORMABLE_CLOTH) != 0)
{
m_robotSim.resetSimulation(RESET_USE_DEFORMABLE_WORLD);
{
SliderParams slider("Vertical velocity", &sGripperVerticalVelocity);
slider.m_minVal = -2;
slider.m_maxVal = 2;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{
SliderParams slider("Closing velocity", &sGripperClosingTargetVelocity);
slider.m_minVal = -1;
slider.m_maxVal = 1;
m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider);
}
{
b3RobotSimulatorLoadFileResults results;
m_robotSim.loadSDF("gripper/wsg50_one_motor_gripper_new.sdf", results);
@@ -326,10 +422,19 @@ public:
m_robotSim.loadURDF("plane.urdf", args);
}
m_robotSim.setGravity(btVector3(0, 0, -10));
b3RobotSimulatorLoadSoftBodyArgs args(0.1, 1, 0.02);
args.m_startPosition.setValue(0, 0, 5);
args.m_startOrientation.setValue(1, 0, 0, 1);
m_robotSim.loadSoftBody("bunny.obj", args);
m_robotSim.setGravity(btVector3(0, 0, -10));
b3RobotSimulatorLoadDeformableBodyArgs args(2, .01, 0.006);
args.m_springElasticStiffness = 1;
args.m_springDampingStiffness = .01;
args.m_springBendingStiffness = .1;
args.m_frictionCoeff = 10;
args.m_useSelfCollision = false;
args.m_useFaceContact = true;
args.m_useBendingSprings = true;
args.m_startPosition.setValue(0, 0, 0);
args.m_startOrientation.setValue(0, 0, 1, 1);
m_robotSim.loadDeformableBody("flat_napkin.obj", args);
b3JointInfo revoluteJoint1;
revoluteJoint1.m_parentFrame[0] = -0.055;
@@ -371,7 +476,8 @@ public:
revoluteJoint2.m_jointType = ePoint2PointType;
m_robotSim.createConstraint(0, 2, 0, 4, &revoluteJoint1);
m_robotSim.createConstraint(0, 3, 0, 6, &revoluteJoint2);
}
m_robotSim.setNumSimulationSubSteps(2);
}
if ((m_options & eSOFTBODY_MULTIBODY_COUPLING) != 0)
{
@@ -462,6 +568,21 @@ public:
m_robotSim.setJointMotorControl(m_gripperIndex, fingerJointIndices[i], controlArgs);
}
}
if ((m_options & eGRASP_DEFORMABLE_CLOTH) != 0)
{
int fingerJointIndices[2] = {0, 1};
double fingerTargetVelocities[2] = {sGripperVerticalVelocity, sGripperClosingTargetVelocity};
double maxTorqueValues[2] = {250.0, 50.0};
for (int i = 0; i < 2; i++)
{
b3RobotSimulatorJointMotorArgs controlArgs(CONTROL_MODE_VELOCITY);
controlArgs.m_targetVelocity = fingerTargetVelocities[i];
controlArgs.m_maxTorqueValue = maxTorqueValues[i];
controlArgs.m_kd = 1.;
m_robotSim.setJointMotorControl(m_gripperIndex, fingerJointIndices[i], controlArgs);
}
}
if ((m_options & eSOFTBODY_MULTIBODY_COUPLING) != 0)
{

View File

@@ -23,6 +23,7 @@ enum GripperGraspExampleOptions
eONE_MOTOR_GRASP = 4,
eGRASP_SOFT_BODY = 8,
eSOFTBODY_MULTIBODY_COUPLING = 16,
eGRASP_DEFORMABLE_CLOTH = 32,
};
class CommonExampleInterface* GripperGraspExampleCreateFunc(struct CommonExampleOptions& options);

View File

@@ -44,6 +44,7 @@ bool IKTrajectoryHelper::computeIK(const double endEffectorTargetPosition[3],
const double* q_current, int numQ, int endEffectorIndex,
double* q_new, int ikMethod, const double* linear_jacobian, const double* angular_jacobian, int jacobian_size, const double dampIk[6])
{
MatrixRmn AugMat;
bool useAngularPart = (ikMethod == IK2_VEL_DLS_WITH_ORIENTATION || ikMethod == IK2_VEL_DLS_WITH_ORIENTATION_NULLSPACE || ikMethod == IK2_VEL_SDLS_WITH_ORIENTATION) ? true : false;
Jacobian ikJacobian(useAngularPart, numQ, 1);
@@ -142,12 +143,12 @@ bool IKTrajectoryHelper::computeIK(const double endEffectorTargetPosition[3],
case IK2_VEL_DLS:
//ikJacobian.CalcDeltaThetasDLS(); // Damped least squares method
assert(m_data->m_dampingCoeff.GetLength() == numQ);
ikJacobian.CalcDeltaThetasDLS2(m_data->m_dampingCoeff);
ikJacobian.CalcDeltaThetasDLS2(m_data->m_dampingCoeff, AugMat);
break;
case IK2_VEL_DLS_WITH_NULLSPACE:
case IK2_VEL_DLS_WITH_ORIENTATION_NULLSPACE:
assert(m_data->m_nullSpaceVelocity.GetLength() == numQ);
ikJacobian.CalcDeltaThetasDLSwithNullspace(m_data->m_nullSpaceVelocity);
ikJacobian.CalcDeltaThetasDLSwithNullspace(m_data->m_nullSpaceVelocity, AugMat);
break;
case IK2_DLS_SVD:
ikJacobian.CalcDeltaThetasDLSwithSVD();
@@ -193,6 +194,7 @@ bool IKTrajectoryHelper::computeIK2(
const double* q_current, int numQ,
double* q_new, int ikMethod, const double* linear_jacobians, const double dampIk[6])
{
MatrixRmn AugMat;
bool useAngularPart = false;//for now (ikMethod == IK2_VEL_DLS_WITH_ORIENTATION || ikMethod == IK2_VEL_DLS_WITH_ORIENTATION_NULLSPACE || ikMethod == IK2_VEL_SDLS_WITH_ORIENTATION) ? true : false;
Jacobian ikJacobian(useAngularPart, numQ, numEndEffectors);
@@ -250,12 +252,12 @@ bool IKTrajectoryHelper::computeIK2(
case IK2_VEL_DLS:
//ikJacobian.CalcDeltaThetasDLS(); // Damped least squares method
assert(m_data->m_dampingCoeff.GetLength() == numQ);
ikJacobian.CalcDeltaThetasDLS2(m_data->m_dampingCoeff);
ikJacobian.CalcDeltaThetasDLS2(m_data->m_dampingCoeff, AugMat);
break;
case IK2_VEL_DLS_WITH_NULLSPACE:
case IK2_VEL_DLS_WITH_ORIENTATION_NULLSPACE:
assert(m_data->m_nullSpaceVelocity.GetLength() == numQ);
ikJacobian.CalcDeltaThetasDLSwithNullspace(m_data->m_nullSpaceVelocity);
ikJacobian.CalcDeltaThetasDLSwithNullspace(m_data->m_nullSpaceVelocity, AugMat);
break;
case IK2_DLS_SVD:
ikJacobian.CalcDeltaThetasDLSwithSVD();

View File

@@ -338,6 +338,109 @@ B3_SHARED_API int b3LoadSoftBodySetStartOrientation(b3SharedMemoryCommandHandle
return 0;
}
B3_SHARED_API int b3LoadSoftBodyUpdateSimMesh(b3SharedMemoryCommandHandle commandHandle, const char* filename)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
b3Assert(command->m_type == CMD_LOAD_SOFT_BODY);
int len = strlen(filename);
if (len < MAX_FILENAME_LENGTH)
{
strcpy(command->m_loadSoftBodyArguments.m_simFileName, filename);
}
else
{
command->m_loadSoftBodyArguments.m_simFileName[0] = 0;
}
command->m_updateFlags |= LOAD_SOFT_BODY_SIM_MESH;
return 0;
}
B3_SHARED_API int b3LoadSoftBodyAddCorotatedForce(b3SharedMemoryCommandHandle commandHandle, double corotatedMu, double corotatedLambda)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
b3Assert(command->m_type == CMD_LOAD_SOFT_BODY);
command->m_loadSoftBodyArguments.m_corotatedMu = corotatedMu;
command->m_loadSoftBodyArguments.m_corotatedLambda = corotatedLambda;
command->m_updateFlags |= LOAD_SOFT_BODY_ADD_COROTATED_FORCE;
return 0;
}
B3_SHARED_API int b3LoadSoftBodyAddNeoHookeanForce(b3SharedMemoryCommandHandle commandHandle, double NeoHookeanMu, double NeoHookeanLambda, double NeoHookeanDamping)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
b3Assert(command->m_type == CMD_LOAD_SOFT_BODY);
command->m_loadSoftBodyArguments.m_NeoHookeanMu = NeoHookeanMu;
command->m_loadSoftBodyArguments.m_NeoHookeanLambda = NeoHookeanLambda;
command->m_loadSoftBodyArguments.m_NeoHookeanDamping = NeoHookeanDamping;
command->m_updateFlags |= LOAD_SOFT_BODY_ADD_NEOHOOKEAN_FORCE;
return 0;
}
B3_SHARED_API int b3LoadSoftBodyAddMassSpringForce(b3SharedMemoryCommandHandle commandHandle, double springElasticStiffness , double springDampingStiffness)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
b3Assert(command->m_type == CMD_LOAD_SOFT_BODY);
command->m_loadSoftBodyArguments.m_springElasticStiffness = springElasticStiffness;
command->m_loadSoftBodyArguments.m_springDampingStiffness = springDampingStiffness;
command->m_updateFlags |= LOAD_SOFT_BODY_ADD_MASS_SPRING_FORCE;
return 0;
}
B3_SHARED_API int b3LoadSoftBodyAddGravityForce(b3SharedMemoryCommandHandle commandHandle, double gravityX, double gravityY, double gravityZ)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
b3Assert(command->m_type == CMD_LOAD_SOFT_BODY);
command->m_updateFlags |= LOAD_SOFT_BODY_ADD_GRAVITY_FORCE;
return 0;
}
B3_SHARED_API int b3LoadSoftBodySetCollisionHardness(b3SharedMemoryCommandHandle commandHandle, double collisionHardness)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
b3Assert(command->m_type == CMD_LOAD_SOFT_BODY);
command->m_loadSoftBodyArguments.m_collisionHardness = collisionHardness;
command->m_updateFlags |= LOAD_SOFT_BODY_SET_COLLISION_HARDNESS;
return 0;
}
B3_SHARED_API int b3LoadSoftBodySetSelfCollision(b3SharedMemoryCommandHandle commandHandle, int useSelfCollision)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
b3Assert(command->m_type == CMD_LOAD_SOFT_BODY);
command->m_loadSoftBodyArguments.m_useSelfCollision = useSelfCollision;
command->m_updateFlags |= LOAD_SOFT_BODY_USE_SELF_COLLISION;
return 0;
}
B3_SHARED_API int b3LoadSoftBodySetFrictionCoefficient(b3SharedMemoryCommandHandle commandHandle, double frictionCoefficient)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
b3Assert(command->m_type == CMD_LOAD_SOFT_BODY);
command->m_loadSoftBodyArguments.m_frictionCoeff = frictionCoefficient;
command->m_updateFlags |= LOAD_SOFT_BODY_SET_FRICTION_COEFFICIENT;
return 0;
}
B3_SHARED_API int b3LoadSoftBodyUseBendingSprings(b3SharedMemoryCommandHandle commandHandle, int useBendingSprings, double bendingStiffness)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
b3Assert(command->m_type == CMD_LOAD_SOFT_BODY);
command->m_loadSoftBodyArguments.m_useBendingSprings = useBendingSprings;
command->m_loadSoftBodyArguments.m_springBendingStiffness = bendingStiffness;
command->m_updateFlags |= LOAD_SOFT_BODY_ADD_BENDING_SPRINGS;
return 0;
}
B3_SHARED_API int b3LoadSoftBodyUseFaceContact(b3SharedMemoryCommandHandle commandHandle, int useFaceContact)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
b3Assert(command->m_type == CMD_LOAD_SOFT_BODY);
command->m_loadSoftBodyArguments.m_useFaceContact = useFaceContact;
command->m_updateFlags |= LOAD_SOFT_BODY_USE_FACE_CONTACT;
return 0;
}
B3_SHARED_API b3SharedMemoryCommandHandle b3LoadUrdfCommandInit(b3PhysicsClientHandle physClient, const char* urdfFileName)
{
PhysicsClient* cl = (PhysicsClient*)physClient;
@@ -677,6 +780,14 @@ B3_SHARED_API int b3PhysicsParamSetWarmStartingFactor(b3SharedMemoryCommandHandl
return 0;
}
B3_SHARED_API int b3PhysicsParamSetArticulatedWarmStartingFactor(b3SharedMemoryCommandHandle commandHandle, double warmStartingFactor)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
b3Assert(command->m_type == CMD_SEND_PHYSICS_SIMULATION_PARAMETERS);
command->m_physSimParamArgs.m_articulatedWarmStartingFactor = warmStartingFactor;
command->m_updateFlags |= SIM_PARAM_UPDATE_ARTICULATED_WARM_STARTING_FACTOR;
return 0;
}
B3_SHARED_API int b3PhysicsParamSetSolverResidualThreshold(b3SharedMemoryCommandHandle commandHandle, double solverResidualThreshold)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
@@ -803,6 +914,15 @@ B3_SHARED_API int b3PhysicsParamSetDefaultFrictionCFM(b3SharedMemoryCommandHandl
return 0;
}
B3_SHARED_API int b3PhysicsParameterSetSparseSdfVoxelSize(b3SharedMemoryCommandHandle commandHandle, double sparseSdfVoxelSize)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
b3Assert(command->m_type == CMD_SEND_PHYSICS_SIMULATION_PARAMETERS);
command->m_updateFlags |= SIM_PARAM_UPDATE_SPARSE_SDF;
command->m_physSimParamArgs.m_sparseSdfVoxelSize = sparseSdfVoxelSize;
return 0;
}
B3_SHARED_API b3SharedMemoryCommandHandle b3InitStepSimulationCommand(b3PhysicsClientHandle physClient)
{
PhysicsClient* cl = (PhysicsClient*)physClient;
@@ -840,6 +960,19 @@ B3_SHARED_API b3SharedMemoryCommandHandle b3InitResetSimulationCommand2(b3Shared
return (b3SharedMemoryCommandHandle)command;
}
B3_SHARED_API int b3InitResetSimulationSetFlags(b3SharedMemoryCommandHandle commandHandle, int flags)
{
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
b3Assert(command);
btAssert(command->m_type == CMD_RESET_SIMULATION);
if (command->m_type == CMD_RESET_SIMULATION)
{
command->m_updateFlags = flags;
}
return 0;
}
B3_SHARED_API b3SharedMemoryCommandHandle b3JointControlCommandInit(b3PhysicsClientHandle physClient, int controlMode)
{
return b3JointControlCommandInit2(physClient, 0, controlMode);
@@ -1340,6 +1473,8 @@ B3_SHARED_API int b3CreateCollisionShapeAddHeightfield(b3SharedMemoryCommandHand
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_heightfieldTextureScaling = textureScaling;
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_numHeightfieldRows = -1;
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_numHeightfieldColumns = -1;
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_replaceHeightfieldIndex = -1;
command->m_createUserShapeArgs.m_numUserShapes++;
return shapeIndex;
}
@@ -1347,7 +1482,7 @@ B3_SHARED_API int b3CreateCollisionShapeAddHeightfield(b3SharedMemoryCommandHand
return -1;
}
B3_SHARED_API int b3CreateCollisionShapeAddHeightfield2(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, const double meshScale[/*3*/], double textureScaling, float* heightfieldData, int numHeightfieldRows, int numHeightfieldColumns)
B3_SHARED_API int b3CreateCollisionShapeAddHeightfield2(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, const double meshScale[/*3*/], double textureScaling, float* heightfieldData, int numHeightfieldRows, int numHeightfieldColumns, int replaceHeightfieldIndex)
{
PhysicsClient* cl = (PhysicsClient*)physClient;
b3Assert(cl);
@@ -1370,6 +1505,7 @@ B3_SHARED_API int b3CreateCollisionShapeAddHeightfield2(b3PhysicsClientHandle ph
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_heightfieldTextureScaling = textureScaling;
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_numHeightfieldRows = numHeightfieldRows;
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_numHeightfieldColumns = numHeightfieldColumns;
command->m_createUserShapeArgs.m_shapes[shapeIndex].m_replaceHeightfieldIndex = replaceHeightfieldIndex;
cl->uploadBulletFileToSharedMemory((const char*)heightfieldData, numHeightfieldRows*numHeightfieldColumns* sizeof(float));
command->m_createUserShapeArgs.m_numUserShapes++;
return shapeIndex;
@@ -3035,6 +3171,7 @@ B3_SHARED_API int b3ChangeDynamicsInfoSetLinearDamping(b3SharedMemoryCommandHand
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
b3Assert(command->m_type == CMD_CHANGE_DYNAMICS_INFO);
command->m_changeDynamicsInfoArgs.m_bodyUniqueId = bodyUniqueId;
command->m_changeDynamicsInfoArgs.m_linkIndex = -1;
command->m_changeDynamicsInfoArgs.m_linearDamping = linearDamping;
command->m_updateFlags |= CHANGE_DYNAMICS_INFO_SET_LINEAR_DAMPING;
return 0;
@@ -3045,6 +3182,7 @@ B3_SHARED_API int b3ChangeDynamicsInfoSetAngularDamping(b3SharedMemoryCommandHan
struct SharedMemoryCommand* command = (struct SharedMemoryCommand*)commandHandle;
b3Assert(command->m_type == CMD_CHANGE_DYNAMICS_INFO);
command->m_changeDynamicsInfoArgs.m_bodyUniqueId = bodyUniqueId;
command->m_changeDynamicsInfoArgs.m_linkIndex = -1;
command->m_changeDynamicsInfoArgs.m_angularDamping = angularDamping;
command->m_updateFlags |= CHANGE_DYNAMICS_INFO_SET_ANGULAR_DAMPING;
return 0;
@@ -3131,6 +3269,30 @@ B3_SHARED_API int b3ChangeDynamicsInfoSetActivationState(b3SharedMemoryCommandHa
return 0;
}
B3_SHARED_API b3SharedMemoryCommandHandle b3InitCreateSoftBodyAnchorConstraintCommand(b3PhysicsClientHandle physClient, int softBodyUniqueId, int nodeIndex, int bodyUniqueId, int linkIndex, const double bodyFramePosition[3])
{
PhysicsClient* cl = (PhysicsClient*)physClient;
b3Assert(cl);
b3Assert(cl->canSubmitCommand());
struct SharedMemoryCommand* command = cl->getAvailableSharedMemoryCommand();
b3Assert(command);
command->m_type = CMD_USER_CONSTRAINT;
command->m_updateFlags = USER_CONSTRAINT_ADD_SOFT_BODY_ANCHOR;
command->m_userConstraintArguments.m_parentBodyIndex = softBodyUniqueId;
command->m_userConstraintArguments.m_parentJointIndex = nodeIndex;
command->m_userConstraintArguments.m_childBodyIndex = bodyUniqueId;
command->m_userConstraintArguments.m_childJointIndex = linkIndex;
command->m_userConstraintArguments.m_childFrame[0] = bodyFramePosition[0];
command->m_userConstraintArguments.m_childFrame[1] = bodyFramePosition[1];
command->m_userConstraintArguments.m_childFrame[2] = bodyFramePosition[2];
command->m_userConstraintArguments.m_childFrame[3] = 0.;
command->m_userConstraintArguments.m_childFrame[4] = 0.;
command->m_userConstraintArguments.m_childFrame[5] = 0.;
command->m_userConstraintArguments.m_childFrame[6] = 1.;
return (b3SharedMemoryCommandHandle)command;
}
B3_SHARED_API b3SharedMemoryCommandHandle b3InitCreateUserConstraintCommand(b3PhysicsClientHandle physClient, int parentBodyUniqueId, int parentJointIndex, int childBodyUniqueId, int childJointIndex, struct b3JointInfo* info)
{
PhysicsClient* cl = (PhysicsClient*)physClient;
@@ -5319,18 +5481,16 @@ B3_SHARED_API b3SharedMemoryCommandHandle b3ProfileTimingCommandInit(b3PhysicsCl
b3Assert(command);
int len = name ? strlen(name) : 0;
command->m_type = CMD_PROFILE_TIMING;
if (len > 0 && len < (MAX_FILENAME_LENGTH + 1))
{
command->m_type = CMD_PROFILE_TIMING;
strcpy(command->m_profile.m_name, name);
command->m_profile.m_name[len] = 0;
}
else
{
const char* invalid = "InvalidProfileTimingName";
int len = strlen(invalid);
strcpy(command->m_profile.m_name, invalid);
command->m_profile.m_name[len] = 0;
command->m_profile.m_name[0] = 0;
}
command->m_profile.m_type = -1;
command->m_profile.m_durationInMicroSeconds = 0;

View File

@@ -339,6 +339,7 @@ extern "C"
B3_SHARED_API int b3PhysicsParamSetRealTimeSimulation(b3SharedMemoryCommandHandle commandHandle, int enableRealTimeSimulation);
B3_SHARED_API int b3PhysicsParamSetNumSolverIterations(b3SharedMemoryCommandHandle commandHandle, int numSolverIterations);
B3_SHARED_API int b3PhysicsParamSetWarmStartingFactor(b3SharedMemoryCommandHandle commandHandle, double warmStartingFactor);
B3_SHARED_API int b3PhysicsParamSetArticulatedWarmStartingFactor(b3SharedMemoryCommandHandle commandHandle, double warmStartingFactor);
B3_SHARED_API int b3PhysicsParamSetCollisionFilterMode(b3SharedMemoryCommandHandle commandHandle, int filterMode);
B3_SHARED_API int b3PhysicsParamSetUseSplitImpulse(b3SharedMemoryCommandHandle commandHandle, int useSplitImpulse);
B3_SHARED_API int b3PhysicsParamSetSplitImpulsePenetrationThreshold(b3SharedMemoryCommandHandle commandHandle, double splitImpulsePenetrationThreshold);
@@ -356,7 +357,8 @@ extern "C"
B3_SHARED_API int b3PhysicsParameterSetConstraintSolverType(b3SharedMemoryCommandHandle commandHandle, int constraintSolverType);
B3_SHARED_API int b3PhysicsParameterSetMinimumSolverIslandSize(b3SharedMemoryCommandHandle commandHandle, int minimumSolverIslandSize);
B3_SHARED_API int b3PhysicsParamSetSolverAnalytics(b3SharedMemoryCommandHandle commandHandle, int reportSolverAnalytics);
B3_SHARED_API int b3PhysicsParameterSetSparseSdfVoxelSize(b3SharedMemoryCommandHandle commandHandle, double sparseSdfVoxelSize);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitRequestPhysicsParamCommand(b3PhysicsClientHandle physClient);
B3_SHARED_API int b3GetStatusPhysicsSimulationParameters(b3SharedMemoryStatusHandle statusHandle, struct b3PhysicsSimulationParameters* params);
@@ -372,7 +374,7 @@ extern "C"
B3_SHARED_API b3SharedMemoryCommandHandle b3InitResetSimulationCommand(b3PhysicsClientHandle physClient);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitResetSimulationCommand2(b3SharedMemoryCommandHandle commandHandle);
B3_SHARED_API int b3InitResetSimulationSetFlags(b3SharedMemoryCommandHandle commandHandle, int flags);
///Load a robot from a URDF file. Status type will CMD_URDF_LOADING_COMPLETED.
///Access the robot from the unique body index, through b3GetStatusBodyIndex(statusHandle);
B3_SHARED_API b3SharedMemoryCommandHandle b3LoadUrdfCommandInit(b3PhysicsClientHandle physClient, const char* urdfFileName);
@@ -490,7 +492,7 @@ extern "C"
B3_SHARED_API int b3CreateCollisionShapeAddCapsule(b3SharedMemoryCommandHandle commandHandle, double radius, double height);
B3_SHARED_API int b3CreateCollisionShapeAddCylinder(b3SharedMemoryCommandHandle commandHandle, double radius, double height);
B3_SHARED_API int b3CreateCollisionShapeAddHeightfield(b3SharedMemoryCommandHandle commandHandle, const char* fileName, const double meshScale[/*3*/], double textureScaling);
B3_SHARED_API int b3CreateCollisionShapeAddHeightfield2(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, const double meshScale[/*3*/], double textureScaling, float* heightfieldData, int numHeightfieldRows, int numHeightfieldColumns);
B3_SHARED_API int b3CreateCollisionShapeAddHeightfield2(b3PhysicsClientHandle physClient, b3SharedMemoryCommandHandle commandHandle, const double meshScale[/*3*/], double textureScaling, float* heightfieldData, int numHeightfieldRows, int numHeightfieldColumns, int replaceHeightfieldIndex);
B3_SHARED_API int b3CreateCollisionShapeAddPlane(b3SharedMemoryCommandHandle commandHandle, const double planeNormal[/*3*/], double planeConstant);
B3_SHARED_API int b3CreateCollisionShapeAddMesh(b3SharedMemoryCommandHandle commandHandle, const char* fileName, const double meshScale[/*3*/]);
@@ -631,6 +633,19 @@ extern "C"
B3_SHARED_API int b3LoadSoftBodySetCollisionMargin(b3SharedMemoryCommandHandle commandHandle, double collisionMargin);
B3_SHARED_API int b3LoadSoftBodySetStartPosition(b3SharedMemoryCommandHandle commandHandle, double startPosX, double startPosY, double startPosZ);
B3_SHARED_API int b3LoadSoftBodySetStartOrientation(b3SharedMemoryCommandHandle commandHandle, double startOrnX, double startOrnY, double startOrnZ, double startOrnW);
B3_SHARED_API int b3LoadSoftBodyUpdateSimMesh(b3SharedMemoryCommandHandle commandHandle, const char* filename);
B3_SHARED_API int b3LoadSoftBodyAddCorotatedForce(b3SharedMemoryCommandHandle commandHandle, double corotatedMu, double corotatedLambda);
B3_SHARED_API int b3LoadSoftBodyAddCorotatedForce(b3SharedMemoryCommandHandle commandHandle, double corotatedMu, double corotatedLambda);
B3_SHARED_API int b3LoadSoftBodyAddNeoHookeanForce(b3SharedMemoryCommandHandle commandHandle, double NeoHookeanMu, double NeoHookeanLambda, double NeoHookeanDamping);
B3_SHARED_API int b3LoadSoftBodyAddMassSpringForce(b3SharedMemoryCommandHandle commandHandle, double springElasticStiffness , double springDampingStiffness);
B3_SHARED_API int b3LoadSoftBodyAddGravityForce(b3SharedMemoryCommandHandle commandHandle, double gravityX, double gravityY, double gravityZ);
B3_SHARED_API int b3LoadSoftBodySetCollisionHardness(b3SharedMemoryCommandHandle commandHandle, double collisionHardness);
B3_SHARED_API int b3LoadSoftBodySetSelfCollision(b3SharedMemoryCommandHandle commandHandle, int useSelfCollision);
B3_SHARED_API int b3LoadSoftBodyUseFaceContact(b3SharedMemoryCommandHandle commandHandle, int useFaceContact);
B3_SHARED_API int b3LoadSoftBodySetFrictionCoefficient(b3SharedMemoryCommandHandle commandHandle, double frictionCoefficient);
B3_SHARED_API int b3LoadSoftBodyUseBendingSprings(b3SharedMemoryCommandHandle commandHandle, int useBendingSprings, double bendingStiffness);
B3_SHARED_API b3SharedMemoryCommandHandle b3InitCreateSoftBodyAnchorConstraintCommand(b3PhysicsClientHandle physClient, int softBodyUniqueId, int nodeIndex, int bodyUniqueId, int linkIndex, const double bodyFramePosition[3]);
B3_SHARED_API b3SharedMemoryCommandHandle b3RequestVREventsCommandInit(b3PhysicsClientHandle physClient);
B3_SHARED_API void b3VREventsSetDeviceTypeFilter(b3SharedMemoryCommandHandle commandHandle, int deviceTypeFilter);

View File

@@ -1458,7 +1458,7 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus()
BodyJointInfoCache* bodyJoints = new BodyJointInfoCache;
m_data->m_bodyJointMap.insert(bodyUniqueId, bodyJoints);
bodyJoints->m_bodyName = serverCmd.m_dataStreamArguments.m_bodyName;
bodyJoints->m_baseName = "baseLink";
bodyJoints->m_baseName = serverCmd.m_dataStreamArguments.m_bodyName;
if (bf.ok())
{
@@ -1529,19 +1529,45 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus()
{
B3_PROFILE("CMD_LOADING_COMPLETED");
int numConstraints = serverCmd.m_sdfLoadedArgs.m_numUserConstraints;
for (int i = 0; i < numConstraints; i++)
{
int constraintUid = serverCmd.m_sdfLoadedArgs.m_userConstraintUniqueIds[i];
m_data->m_constraintIdsRequestInfo.push_back(constraintUid);
}
int numBodies = serverCmd.m_sdfLoadedArgs.m_numBodies;
if (serverCmd.m_type == CMD_SYNC_BODY_INFO_COMPLETED)
{
int* ids = (int*)m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor;
int* constraintUids = ids + numBodies;
for (int i = 0; i < numConstraints; i++)
{
int constraintUid = constraintUids[i];
m_data->m_constraintIdsRequestInfo.push_back(constraintUid);
}
}
else
{
for (int i = 0; i < numConstraints; i++)
{
int constraintUid = serverCmd.m_sdfLoadedArgs.m_userConstraintUniqueIds[i];
m_data->m_constraintIdsRequestInfo.push_back(constraintUid);
}
}
if (numBodies > 0)
{
m_data->m_tempBackupServerStatus = m_data->m_lastServerStatus;
for (int i = 0; i < numBodies; i++)
if (serverCmd.m_type == CMD_SYNC_BODY_INFO_COMPLETED)
{
m_data->m_bodyIdsRequestInfo.push_back(serverCmd.m_sdfLoadedArgs.m_bodyUniqueIds[i]);
int* bodyIds = (int*)m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor;
for (int i = 0; i < numBodies; i++)
{
m_data->m_bodyIdsRequestInfo.push_back(bodyIds[i]);
}
}
else
{
for (int i = 0; i < numBodies; i++)
{
m_data->m_bodyIdsRequestInfo.push_back(serverCmd.m_sdfLoadedArgs.m_bodyUniqueIds[i]);
}
}
int bodyId = m_data->m_bodyIdsRequestInfo[m_data->m_bodyIdsRequestInfo.size() - 1];

View File

@@ -688,7 +688,10 @@ void PhysicsDirect::processBodyJointInfo(int bodyUniqueId, const SharedMemorySta
{
bf.setFileDNAisMemoryDNA();
}
bf.parse(false);
{
BT_PROFILE("bf.parse");
bf.parse(false);
}
BodyJointInfoCache2* bodyJoints = new BodyJointInfoCache2;
m_data->m_bodyJointMap.insert(bodyUniqueId, bodyJoints);
@@ -718,7 +721,8 @@ void PhysicsDirect::processBodyJointInfo(int bodyUniqueId, const SharedMemorySta
bodyJoints->m_baseName = mb->m_baseName;
}
addJointInfoFromMultiBodyData(mb, bodyJoints, m_data->m_verboseOutput);
}
}
}
if (bf.ok())
{
@@ -919,17 +923,57 @@ void PhysicsDirect::postProcessStatus(const struct SharedMemoryStatus& serverCmd
break;
}
case CMD_SYNC_BODY_INFO_COMPLETED:
clearCachedBodies();
case CMD_MJCF_LOADING_COMPLETED:
case CMD_SDF_LOADING_COMPLETED:
{
//we'll stream further info from the physics server
//so serverCmd will be invalid, make a copy
btAlignedObjectArray<int> bodyIdArray;
btAlignedObjectArray<int> constraintIdArray;
int numConstraints = serverCmd.m_sdfLoadedArgs.m_numUserConstraints;
int numBodies = serverCmd.m_sdfLoadedArgs.m_numBodies;
bodyIdArray.reserve(numBodies);
constraintIdArray.reserve(numConstraints);
if (serverCmd.m_type == CMD_SYNC_BODY_INFO_COMPLETED)
{
clearCachedBodies();
const int* bodyIds = (int*)m_data->m_bulletStreamDataServerToClient;
const int* constaintIds = bodyIds + numBodies;
for (int i = 0; i < numConstraints; i++)
{
int constraintUid = constaintIds[i];
constraintIdArray.push_back(constraintUid);
}
for (int i = 0; i < numBodies; i++)
{
int bodyUid = bodyIds[i];
bodyIdArray.push_back(bodyUid);
}
}
else
{
for (int i = 0; i < numConstraints; i++)
{
int constraintUid = serverCmd.m_sdfLoadedArgs.m_userConstraintUniqueIds[i];
constraintIdArray.push_back(constraintUid);
}
for (int i = 0; i < numBodies; i++)
{
int bodyUid = serverCmd.m_sdfLoadedArgs.m_bodyUniqueIds[i];
bodyIdArray.push_back(bodyUid);
}
}
for (int i = 0; i < numConstraints; i++)
{
int constraintUid = serverCmd.m_sdfLoadedArgs.m_userConstraintUniqueIds[i];
int constraintUid = constraintIdArray[i];
m_data->m_tmpInfoRequestCommand.m_type = CMD_USER_CONSTRAINT;
m_data->m_tmpInfoRequestCommand.m_updateFlags = USER_CONSTRAINT_REQUEST_INFO;
@@ -953,10 +997,10 @@ void PhysicsDirect::postProcessStatus(const struct SharedMemoryStatus& serverCmd
}
}
int numBodies = serverCmd.m_sdfLoadedArgs.m_numBodies;
for (int i = 0; i < numBodies; i++)
{
int bodyUniqueId = serverCmd.m_sdfLoadedArgs.m_bodyUniqueIds[i];
int bodyUniqueId = bodyIdArray[i];
m_data->m_tmpInfoRequestCommand.m_type = CMD_REQUEST_BODY_INFO;
m_data->m_tmpInfoRequestCommand.m_sdfRequestInfoArgs.m_bodyUniqueId = bodyUniqueId;
@@ -1174,7 +1218,7 @@ void PhysicsDirect::postProcessStatus(const struct SharedMemoryStatus& serverCmd
BodyJointInfoCache2* bodyJoints = new BodyJointInfoCache2;
m_data->m_bodyJointMap.insert(bodyUniqueId, bodyJoints);
bodyJoints->m_bodyName = serverCmd.m_dataStreamArguments.m_bodyName;
bodyJoints->m_baseName = "baseLink";
bodyJoints->m_baseName = serverCmd.m_dataStreamArguments.m_bodyName;
break;
}
case CMD_SYNC_USER_DATA_FAILED:

File diff suppressed because it is too large Load Diff

View File

@@ -17,9 +17,12 @@ class PhysicsServerCommandProcessor : public CommandProcessorInterface
{
struct PhysicsServerCommandProcessorInternalData* m_data;
void resetSimulation();
void resetSimulation(int flags=0);
void createThreadPool();
class btDeformableMultiBodyDynamicsWorld* getDeformableWorld();
class btSoftMultiBodyDynamicsWorld* getSoftWorld();
protected:
bool processStateLoggingCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
bool processRequestCameraImageCommand(const struct SharedMemoryCommand& clientCmd, struct SharedMemoryStatus& serverStatusOut, char* bufferServerToClient, int bufferSizeInBytes);
@@ -114,7 +117,7 @@ public:
void createJointMotors(class btMultiBody* body);
virtual void createEmptyDynamicsWorld();
virtual void createEmptyDynamicsWorld(int flags=0);
virtual void deleteDynamicsWorld();
virtual bool connect()

View File

@@ -127,6 +127,7 @@ enum MultiThreadedGUIHelperCommunicationEnums
eGUIHelperChangeTexture,
eGUIHelperRemoveTexture,
eGUIHelperSetVisualizerFlagCheckRenderedFrame,
eGUIHelperUpdateShape,
};
#include <stdio.h>
@@ -545,7 +546,7 @@ MultithreadedDebugDrawer : public btIDebugDraw
btHashMap<ColorWidth, int> m_hashedLines;
public:
void drawDebugDrawerLines()
virtual void drawDebugDrawerLines()
{
if (m_hashedLines.size())
{
@@ -627,7 +628,7 @@ public:
return m_debugMode;
}
virtual void clearLines()
virtual void clearLines() override
{
m_hashedLines.clear();
m_sortedIndices.clear();
@@ -649,13 +650,26 @@ class MultiThreadedOpenGLGuiHelper : public GUIHelperInterface
public:
MultithreadedDebugDrawer* m_debugDraw;
void drawDebugDrawerLines()
virtual void drawDebugDrawerLines()
{
if (m_debugDraw)
{
m_csGUI->lock();
//draw stuff and flush?
m_debugDraw->drawDebugDrawerLines();
m_csGUI->unlock();
}
}
virtual void clearLines()
{
m_csGUI->lock();
if (m_debugDraw)
{
m_debugDraw->clearLines();
}
m_csGUI->unlock();
}
GUIHelperInterface* m_childGuiHelper;
btHashMap<btHashPtr, int> m_cachedTextureIds;
@@ -846,10 +860,8 @@ public:
delete m_debugDraw;
m_debugDraw = 0;
}
m_debugDraw = new MultithreadedDebugDrawer(this);
rbWorld->setDebugDrawer(m_debugDraw);
m_debugDraw = new MultithreadedDebugDrawer(this);
rbWorld->setDebugDrawer(m_debugDraw);
//m_childGuiHelper->createPhysicsDebugDrawer(rbWorld);
}
@@ -865,6 +877,18 @@ public:
workerThreadWait();
}
int m_updateShapeIndex;
float* m_updateShapeVertices;
virtual void updateShape(int shapeIndex, float* vertices)
{
m_updateShapeIndex = shapeIndex;
m_updateShapeVertices = vertices;
m_cs->lock();
m_cs->setSharedParam(1, eGUIHelperUpdateShape);
workerThreadWait();
}
virtual int registerTexture(const unsigned char* texels, int width, int height)
{
int* cachedTexture = m_cachedTextureIds[texels];
@@ -1916,6 +1940,15 @@ void PhysicsServerExample::updateGraphics()
m_multiThreadedHelper->mainThreadRelease();
break;
}
case eGUIHelperUpdateShape:
{
B3_PROFILE("eGUIHelperUpdateShape");
m_multiThreadedHelper->m_childGuiHelper->updateShape(m_multiThreadedHelper->m_updateShapeIndex, m_multiThreadedHelper->m_updateShapeVertices);
m_multiThreadedHelper->mainThreadRelease();
break;
}
case eGUIHelperRegisterGraphicsShape:
{
B3_PROFILE("eGUIHelperRegisterGraphicsShape");
@@ -2039,6 +2072,7 @@ void PhysicsServerExample::updateGraphics()
break;
}
case eGUIHelperSetVisualizerFlagCheckRenderedFrame:
{
if (m_renderedFrames != m_multiThreadedHelper->m_renderedFrames)

View File

@@ -483,17 +483,29 @@ enum EnumSimParamUpdateFlags
SIM_PARAM_CONSTRAINT_MIN_SOLVER_ISLAND_SIZE = 1 << 25,
SIM_PARAM_REPORT_CONSTRAINT_SOLVER_ANALYTICS = 1 << 26,
SIM_PARAM_UPDATE_WARM_STARTING_FACTOR = 1 << 27,
SIM_PARAM_UPDATE_ARTICULATED_WARM_STARTING_FACTOR = 1 << 28,
SIM_PARAM_UPDATE_SPARSE_SDF = 1 << 29,
};
enum EnumLoadSoftBodyUpdateFlags
{
LOAD_SOFT_BODY_FILE_NAME = 1,
LOAD_SOFT_BODY_UPDATE_SCALE = 2,
LOAD_SOFT_BODY_UPDATE_MASS = 4,
LOAD_SOFT_BODY_UPDATE_COLLISION_MARGIN = 8,
LOAD_SOFT_BODY_INITIAL_POSITION = 16,
LOAD_SOFT_BODY_INITIAL_ORIENTATION = 32
LOAD_SOFT_BODY_UPDATE_SCALE = 1<<1,
LOAD_SOFT_BODY_UPDATE_MASS = 1<<2,
LOAD_SOFT_BODY_UPDATE_COLLISION_MARGIN = 1<<3,
LOAD_SOFT_BODY_INITIAL_POSITION = 1<<4,
LOAD_SOFT_BODY_INITIAL_ORIENTATION = 1<<5,
LOAD_SOFT_BODY_ADD_COROTATED_FORCE = 1<<6,
LOAD_SOFT_BODY_ADD_MASS_SPRING_FORCE = 1<<7,
LOAD_SOFT_BODY_ADD_GRAVITY_FORCE = 1<<8,
LOAD_SOFT_BODY_SET_COLLISION_HARDNESS = 1<<9,
LOAD_SOFT_BODY_SET_FRICTION_COEFFICIENT = 1<<10,
LOAD_SOFT_BODY_ADD_BENDING_SPRINGS = 1<<11,
LOAD_SOFT_BODY_ADD_NEOHOOKEAN_FORCE = 1<<12,
LOAD_SOFT_BODY_USE_SELF_COLLISION = 1<<13,
LOAD_SOFT_BODY_USE_FACE_CONTACT = 1<<14,
LOAD_SOFT_BODY_SIM_MESH = 1<<15,
};
enum EnumSimParamInternalSimFlags
@@ -511,7 +523,21 @@ struct LoadSoftBodyArgs
double m_mass;
double m_collisionMargin;
double m_initialPosition[3];
double m_initialOrientation[4];
double m_initialOrientation[4];
double m_springElasticStiffness;
double m_springDampingStiffness;
double m_springBendingStiffness;
double m_corotatedMu;
double m_corotatedLambda;
int m_useBendingSprings;
double m_collisionHardness;
double m_useSelfCollision;
double m_frictionCoeff;
double m_NeoHookeanMu;
double m_NeoHookeanLambda;
double m_NeoHookeanDamping;
int m_useFaceContact;
char m_simFileName[MAX_FILENAME_LENGTH];
};
struct b3LoadSoftBodyResultArgs
@@ -763,21 +789,6 @@ struct CalculateInverseKinematicsResultArgs
double m_jointPositions[MAX_DEGREE_OF_FREEDOM];
};
enum EnumUserConstraintFlags
{
USER_CONSTRAINT_ADD_CONSTRAINT = 1,
USER_CONSTRAINT_REMOVE_CONSTRAINT = 2,
USER_CONSTRAINT_CHANGE_CONSTRAINT = 4,
USER_CONSTRAINT_CHANGE_PIVOT_IN_B = 8,
USER_CONSTRAINT_CHANGE_FRAME_ORN_IN_B = 16,
USER_CONSTRAINT_CHANGE_MAX_FORCE = 32,
USER_CONSTRAINT_REQUEST_INFO = 64,
USER_CONSTRAINT_CHANGE_GEAR_RATIO = 128,
USER_CONSTRAINT_CHANGE_GEAR_AUX_LINK = 256,
USER_CONSTRAINT_CHANGE_RELATIVE_POSITION_TARGET = 512,
USER_CONSTRAINT_CHANGE_ERP = 1024,
USER_CONSTRAINT_REQUEST_STATE = 2048,
};
enum EnumBodyChangeFlags
{
@@ -965,6 +976,7 @@ struct b3CreateUserShapeData
int m_numHeightfieldColumns;
double m_rgbaColor[4];
double m_specularColor[3];
int m_replaceHeightfieldIndex;
};
#define MAX_COMPOUND_COLLISION_SHAPES 16

View File

@@ -7,7 +7,10 @@
//Please don't replace an existing magic number:
//instead, only ADD a new one at the top, comment-out previous one
#define SHARED_MEMORY_MAGIC_NUMBER 201908110
#define SHARED_MEMORY_MAGIC_NUMBER 201911280
//#define SHARED_MEMORY_MAGIC_NUMBER 201911180
//#define SHARED_MEMORY_MAGIC_NUMBER 201909030
//#define SHARED_MEMORY_MAGIC_NUMBER 201908110
//#define SHARED_MEMORY_MAGIC_NUMBER 201908050
//#define SHARED_MEMORY_MAGIC_NUMBER 2019060190
//#define SHARED_MEMORY_MAGIC_NUMBER 201904030
@@ -306,6 +309,23 @@ struct b3UserDataValue
const char* m_data1;
};
enum EnumUserConstraintFlags
{
USER_CONSTRAINT_ADD_CONSTRAINT = 1,
USER_CONSTRAINT_REMOVE_CONSTRAINT = 2,
USER_CONSTRAINT_CHANGE_CONSTRAINT = 4,
USER_CONSTRAINT_CHANGE_PIVOT_IN_B = 8,
USER_CONSTRAINT_CHANGE_FRAME_ORN_IN_B = 16,
USER_CONSTRAINT_CHANGE_MAX_FORCE = 32,
USER_CONSTRAINT_REQUEST_INFO = 64,
USER_CONSTRAINT_CHANGE_GEAR_RATIO = 128,
USER_CONSTRAINT_CHANGE_GEAR_AUX_LINK = 256,
USER_CONSTRAINT_CHANGE_RELATIVE_POSITION_TARGET = 512,
USER_CONSTRAINT_CHANGE_ERP = 1024,
USER_CONSTRAINT_REQUEST_STATE = 2048,
USER_CONSTRAINT_ADD_SOFT_BODY_ANCHOR = 4096,
};
struct b3UserConstraint
{
int m_parentBodyIndex;
@@ -340,6 +360,13 @@ enum DynamicsActivationState
eActivationStateDisableWakeup = 32,
};
enum b3BodyType
{
BT_RIGID_BODY = 1,
BT_MULTI_BODY = 2,
BT_SOFT_BODY = 3,
};
struct b3DynamicsInfo
{
double m_mass;
@@ -353,6 +380,7 @@ struct b3DynamicsInfo
double m_contactStiffness;
double m_contactDamping;
int m_activationState;
int m_bodyType;
double m_angularDamping;
double m_linearDamping;
double m_ccdSweptSphereRadius;
@@ -554,6 +582,13 @@ enum b3NotificationType
SOFTBODY_CHANGED = 9,
};
enum b3ResetSimulationFlags
{
RESET_USE_DEFORMABLE_WORLD=1,
RESET_USE_DISCRETE_DYNAMICS_WORLD=2,
RESET_USE_SIMPLE_BROADPHASE=4,
};
struct b3BodyNotificationArgs
{
int m_bodyUniqueId;
@@ -938,6 +973,7 @@ struct b3PhysicsSimulationParameters
int m_numSimulationSubSteps;
int m_numSolverIterations;
double m_warmStartingFactor;
double m_articulatedWarmStartingFactor;
int m_useRealTimeSimulation;
int m_useSplitImpulse;
double m_splitImpulsePenetrationThreshold;
@@ -961,6 +997,7 @@ struct b3PhysicsSimulationParameters
int m_constraintSolverType;
int m_minimumSolverIslandSize;
int m_reportSolverAnalytics;
double m_sparseSdfVoxelSize;
};

View File

@@ -89,6 +89,19 @@ void b3RobotSimulatorClientAPI_NoDirect::resetSimulation()
m_data->m_physicsClientHandle, b3InitResetSimulationCommand(m_data->m_physicsClientHandle));
}
void b3RobotSimulatorClientAPI_NoDirect::resetSimulation(int flag)
{
if (!isConnected())
{
b3Warning("Not connected");
return;
}
b3SharedMemoryStatusHandle statusHandle;
b3SharedMemoryCommandHandle command = b3InitResetSimulationCommand(m_data->m_physicsClientHandle);
b3InitResetSimulationSetFlags(command, flag);
statusHandle = b3SubmitClientCommandAndWaitStatus(m_data->m_physicsClientHandle, command);
}
bool b3RobotSimulatorClientAPI_NoDirect::canSubmitCommand() const
{
if (!isConnected())
@@ -607,7 +620,7 @@ int b3RobotSimulatorClientAPI_NoDirect::createConstraint(int parentBodyIndex, in
return -1;
}
int b3RobotSimulatorClientAPI_NoDirect::changeConstraint(int constraintId, b3JointInfo* jointInfo)
int b3RobotSimulatorClientAPI_NoDirect::changeConstraint(int constraintId, b3RobotUserConstraint* jointInfo)
{
if (!isConnected())
{
@@ -616,16 +629,35 @@ int b3RobotSimulatorClientAPI_NoDirect::changeConstraint(int constraintId, b3Joi
}
b3SharedMemoryCommandHandle commandHandle = b3InitChangeUserConstraintCommand(m_data->m_physicsClientHandle, constraintId);
if (jointInfo->m_flags & eJointChangeMaxForce)
if (jointInfo->m_userUpdateFlags & USER_CONSTRAINT_CHANGE_MAX_FORCE)
{
b3InitChangeUserConstraintSetMaxForce(commandHandle, jointInfo->m_jointMaxForce);
b3InitChangeUserConstraintSetMaxForce(commandHandle, jointInfo->m_maxAppliedForce);
}
if (jointInfo->m_flags & eJointChangeChildFramePosition)
if (jointInfo->m_userUpdateFlags & USER_CONSTRAINT_CHANGE_GEAR_RATIO)
{
b3InitChangeUserConstraintSetGearRatio(commandHandle, jointInfo->m_gearRatio);
}
if (jointInfo->m_userUpdateFlags & USER_CONSTRAINT_CHANGE_ERP)
{
b3InitChangeUserConstraintSetERP(commandHandle, jointInfo->m_erp);
}
if (jointInfo->m_userUpdateFlags & USER_CONSTRAINT_CHANGE_GEAR_AUX_LINK)
{
b3InitChangeUserConstraintSetGearAuxLink(commandHandle, jointInfo->m_gearAuxLink);
}
if (jointInfo->m_userUpdateFlags & USER_CONSTRAINT_CHANGE_RELATIVE_POSITION_TARGET)
{
b3InitChangeUserConstraintSetRelativePositionTarget(commandHandle, jointInfo->m_relativePositionTarget);
}
if (jointInfo->m_userUpdateFlags & USER_CONSTRAINT_CHANGE_PIVOT_IN_B)
{
b3InitChangeUserConstraintSetPivotInB(commandHandle, &jointInfo->m_childFrame[0]);
}
if (jointInfo->m_flags & eJointChangeChildFrameOrientation)
if (jointInfo->m_userUpdateFlags & USER_CONSTRAINT_CHANGE_FRAME_ORN_IN_B)
{
b3InitChangeUserConstraintSetFrameInB(commandHandle, &jointInfo->m_childFrame[3]);
}
@@ -1118,7 +1150,7 @@ void b3RobotSimulatorClientAPI_NoDirect::resetDebugVisualizerCamera(double camer
}
}
void b3RobotSimulatorClientAPI_NoDirect::submitProfileTiming(const std::string& profileName, int durationInMicroSeconds)
void b3RobotSimulatorClientAPI_NoDirect::submitProfileTiming(const std::string& profileName)
{
if (!isConnected())
{
@@ -1127,10 +1159,16 @@ void b3RobotSimulatorClientAPI_NoDirect::submitProfileTiming(const std::string&
}
b3SharedMemoryCommandHandle commandHandle = b3ProfileTimingCommandInit(m_data->m_physicsClientHandle, profileName.c_str());
if (durationInMicroSeconds >= 0)
if (profileName.length())
{
b3SetProfileTimingDuractionInMicroSeconds(commandHandle, durationInMicroSeconds);
b3SetProfileTimingType(commandHandle, 0);
}
else
{
b3SetProfileTimingType(commandHandle, 1);
}
b3SubmitClientCommandAndWaitStatus(m_data->m_physicsClientHandle, commandHandle);
}
@@ -1151,6 +1189,35 @@ void b3RobotSimulatorClientAPI_NoDirect::loadSoftBody(const std::string& fileNam
b3SubmitClientCommandAndWaitStatus(m_data->m_physicsClientHandle, command);
}
void b3RobotSimulatorClientAPI_NoDirect::loadDeformableBody(const std::string& fileName, const struct b3RobotSimulatorLoadDeformableBodyArgs& args)
{
if (!isConnected())
{
b3Warning("Not connected");
return;
}
b3SharedMemoryCommandHandle command = b3LoadSoftBodyCommandInit(m_data->m_physicsClientHandle, fileName.c_str());
b3LoadSoftBodySetStartPosition(command, args.m_startPosition[0], args.m_startPosition[1], args.m_startPosition[2]);
b3LoadSoftBodySetStartOrientation(command, args.m_startOrientation[0], args.m_startOrientation[1], args.m_startOrientation[2], args.m_startOrientation[3]);
b3LoadSoftBodySetScale(command, args.m_scale);
b3LoadSoftBodySetMass(command, args.m_mass);
b3LoadSoftBodySetCollisionMargin(command, args.m_collisionMargin);
if (args.m_NeoHookeanMu > 0)
{
b3LoadSoftBodyAddNeoHookeanForce(command, args.m_NeoHookeanMu, args.m_NeoHookeanLambda, args.m_NeoHookeanDamping);
}
if (args.m_springElasticStiffness > 0)
{
b3LoadSoftBodyAddMassSpringForce(command, args.m_springElasticStiffness, args.m_springDampingStiffness);
}
b3LoadSoftBodySetSelfCollision(command, args.m_useSelfCollision);
b3LoadSoftBodyUseFaceContact(command, args.m_useFaceContact);
b3LoadSoftBodySetFrictionCoefficient(command, args.m_frictionCoeff);
b3LoadSoftBodyUseBendingSprings(command, args.m_useBendingSprings, args.m_springBendingStiffness);
b3SubmitClientCommandAndWaitStatus(m_data->m_physicsClientHandle, command);
}
void b3RobotSimulatorClientAPI_NoDirect::getMouseEvents(b3MouseEventsData* mouseEventsData)
{
mouseEventsData->m_numMouseEvents = 0;

View File

@@ -89,6 +89,64 @@ struct b3RobotSimulatorLoadSoftBodyArgs
}
};
struct b3RobotSimulatorLoadDeformableBodyArgs
{
btVector3 m_startPosition;
btQuaternion m_startOrientation;
double m_scale;
double m_mass;
double m_collisionMargin;
double m_springElasticStiffness;
double m_springDampingStiffness;
double m_springBendingStiffness;
double m_NeoHookeanMu;
double m_NeoHookeanLambda;
double m_NeoHookeanDamping;
bool m_useSelfCollision;
bool m_useFaceContact;
bool m_useBendingSprings;
double m_frictionCoeff;
b3RobotSimulatorLoadDeformableBodyArgs(const btVector3 &startPos, const btQuaternion &startOrn, const double &scale, const double &mass, const double &collisionMargin)
: m_startPosition(startPos),
m_startOrientation(startOrn),
m_scale(scale),
m_mass(mass),
m_collisionMargin(collisionMargin),
m_springElasticStiffness(-1),
m_springDampingStiffness(-1),
m_springBendingStiffness(-1),
m_NeoHookeanMu(-1),
m_NeoHookeanDamping(-1),
m_useSelfCollision(false),
m_useFaceContact(false),
m_useBendingSprings(false),
m_frictionCoeff(0)
{
}
b3RobotSimulatorLoadDeformableBodyArgs(const btVector3 &startPos, const btQuaternion &startOrn)
{
b3RobotSimulatorLoadSoftBodyArgs(startPos, startOrn, 1.0, 1.0, 0.02);
}
b3RobotSimulatorLoadDeformableBodyArgs()
{
b3RobotSimulatorLoadSoftBodyArgs(btVector3(0, 0, 0), btQuaternion(0, 0, 0, 1));
}
b3RobotSimulatorLoadDeformableBodyArgs(double scale, double mass, double collisionMargin)
: m_startPosition(btVector3(0, 0, 0)),
m_startOrientation(btQuaternion(0, 0, 0, 1)),
m_scale(scale),
m_mass(mass),
m_collisionMargin(collisionMargin)
{
}
};
struct b3RobotSimulatorLoadFileResults
{
btAlignedObjectArray<int> m_uniqueObjectIds;
@@ -468,6 +526,100 @@ struct b3RobotSimulatorCreateMultiBodyArgs
}
};
struct b3RobotUserConstraint : public b3UserConstraint
{
int m_userUpdateFlags;//see EnumUserConstraintFlags
void setErp(double erp)
{
m_erp = erp;
m_userUpdateFlags |= USER_CONSTRAINT_CHANGE_ERP;
}
void setMaxAppliedForce(double maxForce)
{
m_maxAppliedForce = maxForce;
m_userUpdateFlags |= USER_CONSTRAINT_CHANGE_MAX_FORCE;
}
void setGearRatio(double gearRatio)
{
m_gearRatio = gearRatio;
m_userUpdateFlags |= USER_CONSTRAINT_CHANGE_GEAR_RATIO;
}
void setGearAuxLink(int link)
{
m_gearAuxLink = link;
m_userUpdateFlags |= USER_CONSTRAINT_CHANGE_GEAR_AUX_LINK;
}
void setRelativePositionTarget(double target)
{
m_relativePositionTarget = target;
m_userUpdateFlags |= USER_CONSTRAINT_CHANGE_RELATIVE_POSITION_TARGET;
}
void setChildPivot(double pivot[3])
{
m_childFrame[0] = pivot[0];
m_childFrame[1] = pivot[1];
m_childFrame[2] = pivot[2];
m_userUpdateFlags |= USER_CONSTRAINT_CHANGE_PIVOT_IN_B;
}
void setChildFrameOrientation(double orn[4])
{
m_childFrame[3] = orn[0];
m_childFrame[4] = orn[1];
m_childFrame[5] = orn[2];
m_childFrame[6] = orn[3];
m_userUpdateFlags |= USER_CONSTRAINT_CHANGE_FRAME_ORN_IN_B;
}
b3RobotUserConstraint()
:m_userUpdateFlags(0)
{
m_parentBodyIndex = -1;
m_parentJointIndex = -1;
m_childBodyIndex = -1;
m_childJointIndex = -1;
//position
m_parentFrame[0] = 0;
m_parentFrame[1] = 0;
m_parentFrame[2] = 0;
//orientation quaternion [x,y,z,w]
m_parentFrame[3] = 0;
m_parentFrame[4] = 0;
m_parentFrame[5] = 0;
m_parentFrame[6] = 1;
//position
m_childFrame[0] = 0;
m_childFrame[1] = 0;
m_childFrame[2] = 0;
//orientation quaternion [x,y,z,w]
m_childFrame[3] = 0;
m_childFrame[4] = 0;
m_childFrame[5] = 0;
m_childFrame[6] = 1;
m_jointAxis[0] = 0;
m_jointAxis[1] = 0;
m_jointAxis[2] = 1;
m_jointType = eFixedType;
m_maxAppliedForce = 500;
m_userConstraintUniqueId = -1;
m_gearRatio = -1;
m_gearAuxLink = -1;
m_relativePositionTarget = 0;
m_erp = 0;
}
};
struct b3RobotJointInfo : public b3JointInfo
{
b3RobotJointInfo()
@@ -534,6 +686,8 @@ public:
void syncBodies();
void resetSimulation();
void resetSimulation(int flag);
btQuaternion getQuaternionFromEuler(const btVector3 &rollPitchYaw);
btVector3 getEulerFromQuaternion(const btQuaternion &quat);
@@ -564,7 +718,7 @@ public:
int createConstraint(int parentBodyIndex, int parentJointIndex, int childBodyIndex, int childJointIndex, b3JointInfo *jointInfo);
int changeConstraint(int constraintId, b3JointInfo *jointInfo);
int changeConstraint(int constraintId, b3RobotUserConstraint*jointInfo);
void removeConstraint(int constraintId);
@@ -610,7 +764,7 @@ public:
void getVREvents(b3VREventsData *vrEventsData, int deviceTypeFilter);
void getKeyboardEvents(b3KeyboardEventsData *keyboardEventsData);
void submitProfileTiming(const std::string &profileName, int durationInMicroSeconds = 1);
void submitProfileTiming(const std::string &profileName);
// JFC: added these 24 methods
@@ -685,6 +839,8 @@ public:
int getConstraintUniqueId(int serialIndex);
void loadSoftBody(const std::string &fileName, const struct b3RobotSimulatorLoadSoftBodyArgs &args);
void loadDeformableBody(const std::string &fileName, const struct b3RobotSimulatorLoadDeformableBodyArgs &args);
virtual void setGuiHelper(struct GUIHelperInterface *guiHelper);
virtual struct GUIHelperInterface *getGuiHelper();

Some files were not shown because too many files have changed in this diff Show More