Added source codes of JoltPhysics-5.0.0
@ -3,3 +3,4 @@ add_subdirectory(ShaderGen)
|
||||
add_subdirectory(SceneGraph)
|
||||
#add_subdirectory(Tools)
|
||||
add_subdirectory(GUI)
|
||||
add_subdirectory(JoltPhysics/Build)
|
||||
|
1
src/JoltPhysics/.clang-format
Normal file
@ -0,0 +1 @@
|
||||
DisableFormat: true
|
13
src/JoltPhysics/.editorconfig
Normal file
@ -0,0 +1,13 @@
|
||||
root = true
|
||||
|
||||
[*.{cpp,h,inl,cmake,sh,bat,hlsl}]
|
||||
indent_style = tab
|
||||
tab_width = 4
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[CMakeLists.txt]
|
||||
indent_style = tab
|
||||
tab_width = 4
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
18
src/JoltPhysics/.gitattributes
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
# Convert LF to CRLF on windows on checkout and convert back before submitting to the repository
|
||||
* text=auto
|
||||
|
||||
# Explicitly declare text files to always be normalized and converted to native line endings on checkout
|
||||
*.cpp text
|
||||
*.inl text
|
||||
*.h text
|
||||
*.tof text
|
||||
*.bat text
|
||||
|
||||
# Force shell files to use LF only
|
||||
*.sh text eol=lf
|
||||
gradlew text eol=lf
|
||||
|
||||
# Declare binary file types
|
||||
*.tga binary
|
||||
*.bof binary
|
||||
*.bin binary
|
8
src/JoltPhysics/.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
.vs
|
||||
.vscode
|
||||
.DS_Store
|
||||
/profile_chart_*.html
|
||||
/stats*.html
|
||||
/snapshot.bin
|
||||
/*.jor
|
||||
/detlog.txt
|
1654
src/JoltPhysics/Assets/Human.tof
Normal file
131
src/JoltPhysics/Assets/Human/dead_pose1.tof
Normal file
@ -0,0 +1,131 @@
|
||||
TOS 1.00
|
||||
|
||||
declare SkeletalAnimation 1
|
||||
mAnimatedJoints array instance SkeletalAnimation::AnimatedJoint
|
||||
|
||||
declare SkeletalAnimation::AnimatedJoint 2
|
||||
mJointName string
|
||||
mKeyframes array instance SkeletalAnimation::Keyframe
|
||||
|
||||
declare SkeletalAnimation::Keyframe 3
|
||||
mRotation quat
|
||||
mTranslation vec3
|
||||
mTime float
|
||||
|
||||
object SkeletalAnimation 00000001
|
||||
23
|
||||
"hipsBone"
|
||||
1
|
||||
-0.580907 0.662465 0.472926 -0.005293
|
||||
-0.511629 0.123338 0.102563
|
||||
0.000000
|
||||
"R_Leg_sjnt_0"
|
||||
1
|
||||
0.994683 0.029515 -0.098649 -0.001901
|
||||
-0.104854 -0.000224 0.000080
|
||||
0.000000
|
||||
"R_Leg_sjnt_1"
|
||||
1
|
||||
0.558236 0.082819 0.102170 0.819191
|
||||
-0.000000 0.461809 0.000000
|
||||
0.000000
|
||||
"R_Foot_sjnt_0"
|
||||
1
|
||||
-0.415795 -0.025903 -0.285547 0.863080
|
||||
0.000000 0.388174 0.000000
|
||||
0.000000
|
||||
"L_Leg_sjnt_0"
|
||||
1
|
||||
-0.096847 0.200302 0.053881 0.973446
|
||||
0.104854 -0.000225 0.000080
|
||||
0.000000
|
||||
"L_Leg_sjnt_1"
|
||||
1
|
||||
0.625317 0.040626 -0.068376 0.776307
|
||||
0.000000 -0.461808 0.000000
|
||||
0.000000
|
||||
"L_Foot_sjnt_0"
|
||||
1
|
||||
0.448028 0.016552 0.068711 -0.891222
|
||||
-0.000001 -0.388173 -0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_0"
|
||||
1
|
||||
0.031433 -0.000518 -0.001091 0.999505
|
||||
-0.000000 0.055442 -0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_1"
|
||||
1
|
||||
0.062272 0.003369 -0.006740 0.998031
|
||||
-0.000000 0.049000 0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_2"
|
||||
1
|
||||
0.093196 0.002904 -0.011009 0.995583
|
||||
0.000000 0.049000 -0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_4"
|
||||
1
|
||||
0.092643 0.004648 -0.011669 0.995620
|
||||
0.000000 0.098001 0.000000
|
||||
0.000000
|
||||
"L_Clavicle_sjnt_0"
|
||||
1
|
||||
0.856473 -0.498143 0.097625 0.093688
|
||||
0.007299 0.208857 0.030677
|
||||
0.000000
|
||||
"L_Arm_sjnt_0"
|
||||
1
|
||||
0.051326 0.583453 0.540585 0.603918
|
||||
0.070455 -0.150703 0.005819
|
||||
0.000000
|
||||
"L_Arm_sjnt_1"
|
||||
1
|
||||
0.749181 -0.055037 -0.190752 0.631912
|
||||
-0.000001 -0.260631 0.000000
|
||||
0.000000
|
||||
"L_Wrist_sjnt_0"
|
||||
1
|
||||
0.000688 -0.106898 0.049180 -0.993053
|
||||
0.000007 -0.242273 0.000003
|
||||
0.000000
|
||||
"R_Clavicle_sjnt_0"
|
||||
1
|
||||
-0.076883 -0.107965 0.509223 0.850367
|
||||
-0.007299 0.208857 0.030677
|
||||
0.000000
|
||||
"R_Arm_sjnt_0"
|
||||
1
|
||||
0.622778 -0.313061 0.547977 0.462453
|
||||
-0.070458 0.150703 -0.005820
|
||||
0.000000
|
||||
"R_Arm_sjnt_1"
|
||||
1
|
||||
0.570264 -0.066970 -0.307114 0.758944
|
||||
-0.000001 0.260632 -0.000000
|
||||
0.000000
|
||||
"R_Wrist_sjnt_0"
|
||||
1
|
||||
-0.107633 -0.182094 -0.068157 -0.974993
|
||||
0.000000 0.242268 -0.000000
|
||||
0.000000
|
||||
"C_Neck_sjnt_0"
|
||||
1
|
||||
0.148132 0.042497 -0.052729 0.986646
|
||||
0.000000 0.206349 -0.038118
|
||||
0.000000
|
||||
"C_Neck_sjnt_1"
|
||||
1
|
||||
-0.272572 0.021316 -0.048793 0.960661
|
||||
-0.000000 0.054000 0.000000
|
||||
0.000000
|
||||
"C_Neck_sjnt_2"
|
||||
1
|
||||
-0.054183 -0.008292 -0.029041 0.998074
|
||||
0.000000 0.054001 0.000000
|
||||
0.000000
|
||||
"C_Head_sjnt_0"
|
||||
1
|
||||
0.029305 0.088480 -0.137100 0.986162
|
||||
0.000000 0.054000 -0.000000
|
||||
0.000000
|
131
src/JoltPhysics/Assets/Human/dead_pose2.tof
Normal file
@ -0,0 +1,131 @@
|
||||
TOS 1.00
|
||||
|
||||
declare SkeletalAnimation 1
|
||||
mAnimatedJoints array instance SkeletalAnimation::AnimatedJoint
|
||||
|
||||
declare SkeletalAnimation::AnimatedJoint 2
|
||||
mJointName string
|
||||
mKeyframes array instance SkeletalAnimation::Keyframe
|
||||
|
||||
declare SkeletalAnimation::Keyframe 3
|
||||
mRotation quat
|
||||
mTranslation vec3
|
||||
mTime float
|
||||
|
||||
object SkeletalAnimation 00000001
|
||||
23
|
||||
"hipsBone"
|
||||
1
|
||||
0.580969 0.662434 0.472893 0.005230
|
||||
0.778002 0.123338 0.121363
|
||||
0.000000
|
||||
"R_Leg_sjnt_0"
|
||||
1
|
||||
-0.979544 0.029720 -0.196361 -0.032433
|
||||
-0.104854 -0.000224 0.000080
|
||||
0.000000
|
||||
"R_Leg_sjnt_1"
|
||||
1
|
||||
0.607629 0.107933 -0.014707 0.786715
|
||||
-0.000000 0.461809 0.000000
|
||||
0.000000
|
||||
"R_Foot_sjnt_0"
|
||||
1
|
||||
-0.601232 0.033798 -0.038697 0.797421
|
||||
0.000000 0.388174 0.000000
|
||||
0.000000
|
||||
"L_Leg_sjnt_0"
|
||||
1
|
||||
0.047909 -0.102469 -0.016701 0.993441
|
||||
0.104854 -0.000225 0.000080
|
||||
0.000000
|
||||
"L_Leg_sjnt_1"
|
||||
1
|
||||
-0.491497 -0.068754 -0.078845 -0.864573
|
||||
0.000000 -0.461808 0.000000
|
||||
0.000000
|
||||
"L_Foot_sjnt_0"
|
||||
1
|
||||
0.390997 -0.045090 0.421830 -0.816791
|
||||
-0.000001 -0.388173 -0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_0"
|
||||
1
|
||||
0.031433 0.000503 0.001038 0.999505
|
||||
-0.000000 0.055442 0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_1"
|
||||
1
|
||||
0.062272 -0.003358 0.006714 0.998031
|
||||
-0.000000 0.049000 0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_2"
|
||||
1
|
||||
0.093197 -0.002900 0.010957 0.995583
|
||||
0.000000 0.049000 -0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_4"
|
||||
1
|
||||
-0.092643 0.004635 -0.011603 -0.995621
|
||||
0.000000 0.098001 -0.000000
|
||||
0.000000
|
||||
"L_Clavicle_sjnt_0"
|
||||
1
|
||||
-0.850361 0.509199 0.108046 -0.077000
|
||||
0.007299 0.208857 0.030677
|
||||
0.000000
|
||||
"L_Arm_sjnt_0"
|
||||
1
|
||||
0.622797 -0.313095 0.547896 0.462500
|
||||
0.070455 -0.150703 0.005820
|
||||
0.000000
|
||||
"L_Arm_sjnt_1"
|
||||
1
|
||||
-0.570276 0.066909 0.307092 -0.758948
|
||||
-0.000001 -0.260631 -0.000000
|
||||
0.000000
|
||||
"L_Wrist_sjnt_0"
|
||||
1
|
||||
0.107622 0.182086 0.068178 0.974994
|
||||
0.000007 -0.242273 0.000002
|
||||
0.000000
|
||||
"R_Clavicle_sjnt_0"
|
||||
1
|
||||
-0.093524 0.097713 0.498124 0.856492
|
||||
-0.007299 0.208857 0.030677
|
||||
0.000000
|
||||
"R_Arm_sjnt_0"
|
||||
1
|
||||
0.051326 0.583528 0.540453 0.603963
|
||||
-0.070458 0.150703 -0.005820
|
||||
0.000000
|
||||
"R_Arm_sjnt_1"
|
||||
1
|
||||
-0.749170 0.055080 0.190723 -0.631930
|
||||
-0.000001 0.260632 0.000000
|
||||
0.000000
|
||||
"R_Wrist_sjnt_0"
|
||||
1
|
||||
-0.000687 0.106883 -0.049184 0.993054
|
||||
0.000000 0.242268 -0.000000
|
||||
0.000000
|
||||
"C_Neck_sjnt_0"
|
||||
1
|
||||
0.148136 -0.042494 0.052637 0.986651
|
||||
-0.000000 0.206349 -0.038118
|
||||
0.000000
|
||||
"C_Neck_sjnt_1"
|
||||
1
|
||||
-0.272569 -0.021317 0.048735 0.960665
|
||||
0.000000 0.054001 0.000000
|
||||
0.000000
|
||||
"C_Neck_sjnt_2"
|
||||
1
|
||||
-0.054186 0.008273 0.028994 0.998076
|
||||
0.000000 0.054001 0.000000
|
||||
0.000000
|
||||
"C_Head_sjnt_0"
|
||||
1
|
||||
0.029319 -0.088467 0.137075 0.986167
|
||||
0.000000 0.054000 -0.000000
|
||||
0.000000
|
131
src/JoltPhysics/Assets/Human/dead_pose3.tof
Normal file
@ -0,0 +1,131 @@
|
||||
TOS 1.00
|
||||
|
||||
declare SkeletalAnimation 1
|
||||
mAnimatedJoints array instance SkeletalAnimation::AnimatedJoint
|
||||
|
||||
declare SkeletalAnimation::AnimatedJoint 2
|
||||
mJointName string
|
||||
mKeyframes array instance SkeletalAnimation::Keyframe
|
||||
|
||||
declare SkeletalAnimation::Keyframe 3
|
||||
mRotation quat
|
||||
mTranslation vec3
|
||||
mTime float
|
||||
|
||||
object SkeletalAnimation 00000001
|
||||
23
|
||||
"hipsBone"
|
||||
1
|
||||
-0.253414 0.715602 -0.639670 0.120488
|
||||
-0.113085 0.196785 -0.745374
|
||||
0.000000
|
||||
"R_Leg_sjnt_0"
|
||||
1
|
||||
-0.940855 0.027320 -0.183670 -0.283391
|
||||
-0.104854 -0.000224 0.000080
|
||||
0.000000
|
||||
"R_Leg_sjnt_1"
|
||||
1
|
||||
0.732582 0.147108 -0.159629 0.645136
|
||||
0.000000 0.461808 0.000000
|
||||
0.000000
|
||||
"R_Foot_sjnt_0"
|
||||
1
|
||||
-0.543008 -0.043463 0.072346 0.835476
|
||||
0.000000 0.388174 0.000000
|
||||
0.000000
|
||||
"L_Leg_sjnt_0"
|
||||
1
|
||||
0.068071 -0.118484 0.183975 0.973386
|
||||
0.104854 -0.000225 0.000080
|
||||
0.000000
|
||||
"L_Leg_sjnt_1"
|
||||
1
|
||||
0.258573 0.111198 0.041401 0.958677
|
||||
0.000000 -0.461808 0.000000
|
||||
0.000000
|
||||
"L_Foot_sjnt_0"
|
||||
1
|
||||
-0.388386 -0.112771 -0.101140 0.908961
|
||||
-0.000001 -0.388173 -0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_0"
|
||||
1
|
||||
0.055573 0.116937 0.111430 0.985302
|
||||
0.000000 0.055442 0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_1"
|
||||
1
|
||||
0.037873 -0.006875 0.039870 0.998463
|
||||
0.000000 0.049000 0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_2"
|
||||
1
|
||||
0.057513 -0.003345 0.060246 0.996520
|
||||
-0.000000 0.049000 -0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_4"
|
||||
1
|
||||
0.058450 0.004523 0.059058 0.996532
|
||||
0.000000 0.098001 0.000000
|
||||
0.000000
|
||||
"L_Clavicle_sjnt_0"
|
||||
1
|
||||
-0.788890 0.552170 0.262911 0.060331
|
||||
0.007299 0.208857 0.030677
|
||||
0.000000
|
||||
"L_Arm_sjnt_0"
|
||||
1
|
||||
-0.242065 -0.166972 -0.682243 -0.669381
|
||||
0.070455 -0.150703 0.005819
|
||||
0.000000
|
||||
"L_Arm_sjnt_1"
|
||||
1
|
||||
0.293529 -0.405618 0.091549 0.860775
|
||||
-0.000001 -0.260631 0.000000
|
||||
0.000000
|
||||
"L_Wrist_sjnt_0"
|
||||
1
|
||||
-0.018010 -0.348798 0.050741 0.935650
|
||||
0.000007 -0.242273 0.000002
|
||||
0.000000
|
||||
"R_Clavicle_sjnt_0"
|
||||
1
|
||||
0.006775 0.017839 0.047960 0.998667
|
||||
-0.007299 0.208857 0.030677
|
||||
0.000000
|
||||
"R_Arm_sjnt_0"
|
||||
1
|
||||
-0.057684 0.616002 0.098229 0.779464
|
||||
-0.070458 0.150703 -0.005820
|
||||
0.000000
|
||||
"R_Arm_sjnt_1"
|
||||
1
|
||||
0.360633 -0.148932 -0.172766 0.904387
|
||||
-0.000001 0.260632 -0.000000
|
||||
0.000000
|
||||
"R_Wrist_sjnt_0"
|
||||
1
|
||||
-0.073581 -0.376053 0.364024 -0.848915
|
||||
0.000000 0.242268 -0.000000
|
||||
0.000000
|
||||
"C_Neck_sjnt_0"
|
||||
1
|
||||
0.208406 0.070974 -0.020180 0.975255
|
||||
-0.000000 0.206349 -0.038118
|
||||
0.000000
|
||||
"C_Neck_sjnt_1"
|
||||
1
|
||||
-0.214167 0.070851 -0.015228 0.974105
|
||||
-0.000000 0.054000 0.000000
|
||||
0.000000
|
||||
"C_Neck_sjnt_2"
|
||||
1
|
||||
0.013069 0.069734 0.004440 0.997470
|
||||
0.000000 0.054001 0.000000
|
||||
0.000000
|
||||
"C_Head_sjnt_0"
|
||||
1
|
||||
-0.011944 -0.296295 0.045126 0.953955
|
||||
0.000000 0.054000 0.000000
|
||||
0.000000
|
131
src/JoltPhysics/Assets/Human/dead_pose4.tof
Normal file
@ -0,0 +1,131 @@
|
||||
TOS 1.00
|
||||
|
||||
declare SkeletalAnimation 1
|
||||
mAnimatedJoints array instance SkeletalAnimation::AnimatedJoint
|
||||
|
||||
declare SkeletalAnimation::AnimatedJoint 2
|
||||
mJointName string
|
||||
mKeyframes array instance SkeletalAnimation::Keyframe
|
||||
|
||||
declare SkeletalAnimation::Keyframe 3
|
||||
mRotation quat
|
||||
mTranslation vec3
|
||||
mTime float
|
||||
|
||||
object SkeletalAnimation 00000001
|
||||
23
|
||||
"hipsBone"
|
||||
1
|
||||
-0.006100 0.596243 0.801570 0.044078
|
||||
0.158819 0.119626 0.352148
|
||||
0.000000
|
||||
"R_Leg_sjnt_0"
|
||||
1
|
||||
0.987181 -0.088292 0.091403 0.096563
|
||||
-0.104854 -0.000224 0.000080
|
||||
0.000000
|
||||
"R_Leg_sjnt_1"
|
||||
1
|
||||
0.518738 0.091591 -0.028278 0.849542
|
||||
-0.000000 0.461809 -0.000000
|
||||
0.000000
|
||||
"R_Foot_sjnt_0"
|
||||
1
|
||||
-0.446222 -0.027605 0.081585 0.890768
|
||||
0.000000 0.388174 0.000000
|
||||
0.000000
|
||||
"L_Leg_sjnt_0"
|
||||
1
|
||||
-0.004252 0.099688 0.099358 0.990036
|
||||
0.104854 -0.000225 0.000080
|
||||
0.000000
|
||||
"L_Leg_sjnt_1"
|
||||
1
|
||||
0.332849 0.214890 0.078034 0.914847
|
||||
0.000000 -0.461808 0.000000
|
||||
0.000000
|
||||
"L_Foot_sjnt_0"
|
||||
1
|
||||
-0.353947 -0.242590 0.059009 0.901326
|
||||
-0.000001 -0.388173 -0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_0"
|
||||
1
|
||||
0.040410 -0.000191 -0.035615 0.998548
|
||||
0.000000 0.055442 -0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_1"
|
||||
1
|
||||
0.078135 -0.005104 -0.037889 0.996210
|
||||
0.000000 0.049000 0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_2"
|
||||
1
|
||||
0.117588 0.001930 -0.056543 0.991450
|
||||
-0.000000 0.049000 0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_4"
|
||||
1
|
||||
0.116613 0.022537 -0.060157 0.991098
|
||||
0.000000 0.098001 -0.000000
|
||||
0.000000
|
||||
"L_Clavicle_sjnt_0"
|
||||
1
|
||||
0.820798 -0.461866 -0.218872 0.255080
|
||||
0.007299 0.208857 0.030677
|
||||
0.000000
|
||||
"L_Arm_sjnt_0"
|
||||
1
|
||||
-0.018640 0.550280 0.313113 0.773825
|
||||
0.070455 -0.150703 0.005819
|
||||
0.000000
|
||||
"L_Arm_sjnt_1"
|
||||
1
|
||||
0.502820 -0.083351 -0.423467 0.748933
|
||||
-0.000001 -0.260631 0.000000
|
||||
0.000000
|
||||
"L_Wrist_sjnt_0"
|
||||
1
|
||||
-0.127266 -0.436122 0.115708 -0.883296
|
||||
0.000007 -0.242273 0.000002
|
||||
0.000000
|
||||
"R_Clavicle_sjnt_0"
|
||||
1
|
||||
-0.254409 -0.049344 0.561585 0.785789
|
||||
-0.007299 0.208857 0.030677
|
||||
0.000000
|
||||
"R_Arm_sjnt_0"
|
||||
1
|
||||
-0.297704 0.588370 -0.433881 -0.613954
|
||||
-0.070457 0.150703 -0.005820
|
||||
0.000000
|
||||
"R_Arm_sjnt_1"
|
||||
1
|
||||
0.300035 -0.109892 -0.134453 0.937990
|
||||
-0.000001 0.260632 -0.000000
|
||||
0.000000
|
||||
"R_Wrist_sjnt_0"
|
||||
1
|
||||
-0.074182 0.083861 -0.170265 0.979017
|
||||
0.000000 0.242268 -0.000000
|
||||
0.000000
|
||||
"C_Neck_sjnt_0"
|
||||
1
|
||||
0.095959 0.024101 0.021582 0.994859
|
||||
0.000000 0.206349 -0.038118
|
||||
0.000000
|
||||
"C_Neck_sjnt_1"
|
||||
1
|
||||
-0.330366 0.030108 0.013511 0.943276
|
||||
0.000000 0.054001 0.000000
|
||||
0.000000
|
||||
"C_Neck_sjnt_2"
|
||||
1
|
||||
-0.116595 0.020825 0.025026 0.992646
|
||||
0.000000 0.054001 0.000000
|
||||
0.000000
|
||||
"C_Head_sjnt_0"
|
||||
1
|
||||
-0.225003 0.005643 -0.043020 0.973392
|
||||
-0.000000 0.054000 0.000000
|
||||
0.000000
|
12514
src/JoltPhysics/Assets/Human/jog_hd.tof
Normal file
131
src/JoltPhysics/Assets/Human/neutral.tof
Normal file
@ -0,0 +1,131 @@
|
||||
TOS 1.00
|
||||
|
||||
declare SkeletalAnimation 1
|
||||
mAnimatedJoints array instance SkeletalAnimation::AnimatedJoint
|
||||
|
||||
declare SkeletalAnimation::AnimatedJoint 2
|
||||
mJointName string
|
||||
mKeyframes array instance SkeletalAnimation::Keyframe
|
||||
|
||||
declare SkeletalAnimation::Keyframe 3
|
||||
mRotation quat
|
||||
mTranslation vec3
|
||||
mTime float
|
||||
|
||||
object SkeletalAnimation 00000001
|
||||
23
|
||||
"hipsBone"
|
||||
1
|
||||
0.000000 1.000000 0.000000 0.000000
|
||||
0.000000 0.931122 -0.023035
|
||||
0.000000
|
||||
"R_Leg_sjnt_0"
|
||||
1
|
||||
0.999643 -0.023767 -0.000290 0.012213
|
||||
-0.104854 -0.000224 0.000080
|
||||
0.000000
|
||||
"R_Leg_sjnt_1"
|
||||
1
|
||||
0.060151 0.000000 -0.000000 0.998189
|
||||
-0.000000 0.461809 -0.000000
|
||||
0.000000
|
||||
"R_Foot_sjnt_0"
|
||||
1
|
||||
-0.546992 0.011039 -0.021050 0.836800
|
||||
0.000000 0.388174 0.000000
|
||||
0.000000
|
||||
"L_Leg_sjnt_0"
|
||||
1
|
||||
-0.012213 -0.000290 0.023767 0.999643
|
||||
0.104854 -0.000225 0.000080
|
||||
0.000000
|
||||
"L_Leg_sjnt_1"
|
||||
1
|
||||
0.060151 0.000000 -0.000000 0.998189
|
||||
0.000000 -0.461807 0.000000
|
||||
0.000000
|
||||
"L_Foot_sjnt_0"
|
||||
1
|
||||
-0.546992 0.011039 -0.021050 0.836800
|
||||
-0.000001 -0.388173 -0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_0"
|
||||
1
|
||||
0.000000 0.000000 0.000000 1.000000
|
||||
0.000000 0.055442 -0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_1"
|
||||
1
|
||||
0.000000 0.000000 0.000000 1.000000
|
||||
0.000000 0.049000 0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_2"
|
||||
1
|
||||
0.000000 0.000000 0.000000 1.000000
|
||||
0.000000 0.049000 -0.000000
|
||||
0.000000
|
||||
"C_Spine_sjnt_4"
|
||||
1
|
||||
0.000000 0.000000 0.000000 1.000000
|
||||
0.000000 0.098001 0.000000
|
||||
0.000000
|
||||
"L_Clavicle_sjnt_0"
|
||||
1
|
||||
0.761695 -0.617813 -0.144681 0.131128
|
||||
0.007299 0.208857 0.030677
|
||||
0.000000
|
||||
"L_Arm_sjnt_0"
|
||||
1
|
||||
0.199254 -0.056730 0.463827 0.861362
|
||||
0.070456 -0.150703 0.005820
|
||||
0.000000
|
||||
"L_Arm_sjnt_1"
|
||||
1
|
||||
0.184809 -0.000000 -0.000000 0.982774
|
||||
-0.000001 -0.260631 0.000000
|
||||
0.000000
|
||||
"L_Wrist_sjnt_0"
|
||||
1
|
||||
-0.000000 0.000000 0.000000 1.000000
|
||||
0.000007 -0.242273 0.000002
|
||||
0.000000
|
||||
"R_Clavicle_sjnt_0"
|
||||
1
|
||||
-0.131128 -0.144681 0.617813 0.761696
|
||||
-0.007299 0.208857 0.030677
|
||||
0.000000
|
||||
"R_Arm_sjnt_0"
|
||||
1
|
||||
0.199254 -0.056730 0.463827 0.861362
|
||||
-0.070458 0.150703 -0.005820
|
||||
0.000000
|
||||
"R_Arm_sjnt_1"
|
||||
1
|
||||
0.184809 0.000000 0.000000 0.982774
|
||||
-0.000001 0.260632 -0.000000
|
||||
0.000000
|
||||
"R_Wrist_sjnt_0"
|
||||
1
|
||||
-0.000000 0.000000 -0.000000 1.000000
|
||||
0.000000 0.242268 -0.000000
|
||||
0.000000
|
||||
"C_Neck_sjnt_0"
|
||||
1
|
||||
0.216440 0.000000 0.000000 0.976296
|
||||
0.000000 0.206349 -0.038118
|
||||
0.000000
|
||||
"C_Neck_sjnt_1"
|
||||
1
|
||||
-0.216440 0.000000 0.000000 0.976296
|
||||
0.000000 0.054001 0.000000
|
||||
0.000000
|
||||
"C_Neck_sjnt_2"
|
||||
1
|
||||
0.000000 0.000000 0.000000 1.000000
|
||||
0.000000 0.054001 0.000000
|
||||
0.000000
|
||||
"C_Head_sjnt_0"
|
||||
1
|
||||
0.000000 0.000000 0.000000 1.000000
|
||||
0.000000 0.054000 -0.000000
|
||||
0.000000
|
373
src/JoltPhysics/Assets/Human/neutral_hd.tof
Normal file
@ -0,0 +1,373 @@
|
||||
TOS 1.00
|
||||
|
||||
declare SkeletalAnimation 2
|
||||
mAnimatedJoints array instance SkeletalAnimation::AnimatedJoint
|
||||
mIsLooping bool
|
||||
|
||||
declare SkeletalAnimation::AnimatedJoint 2
|
||||
mJointName string
|
||||
mKeyframes array instance SkeletalAnimation::Keyframe
|
||||
|
||||
declare SkeletalAnimation::Keyframe 3
|
||||
mRotation quat
|
||||
mTranslation vec3
|
||||
mTime float
|
||||
|
||||
object SkeletalAnimation 00000001
|
||||
71
|
||||
"rootBone"
|
||||
1
|
||||
-0.707106829 0 0 0.707106769
|
||||
0 0 0
|
||||
0
|
||||
"C_Neck_sjnt_2"
|
||||
1
|
||||
0 0 0 1
|
||||
6.31036857e-18 0.0540000014 0
|
||||
0
|
||||
"R_Clavicle_sjnt_0"
|
||||
1
|
||||
-0.131128147 -0.144681439 0.617813051 0.761695385
|
||||
-0.00729848538 0.20885624 0.0306759924
|
||||
0
|
||||
"R_Leg_sjnt_0"
|
||||
1
|
||||
0.999642909 -0.0237673745 -0.000290388998 0.0122136045
|
||||
-0.104853801 -0.000224408359 7.95794331e-05
|
||||
0
|
||||
"C_Spine_sjnt_4"
|
||||
1
|
||||
0 0 0 1
|
||||
4.77984621e-18 0.0489999987 3.10862448e-17
|
||||
0
|
||||
"L_Middle_sjnt_3"
|
||||
1
|
||||
0 0 0 1
|
||||
5.85307589e-07 -0.0180757623 3.17060227e-07
|
||||
0
|
||||
"C_Neck_sjnt_0"
|
||||
1
|
||||
0.21643962 0 0 0.976296008
|
||||
-6.33361028e-18 0.206347629 -0.0381180719
|
||||
0
|
||||
"C_Head_sjnt_0"
|
||||
1
|
||||
0 0 0 1
|
||||
6.31036857e-18 0.0540000014 2.8532731e-16
|
||||
0
|
||||
"C_Spine_sjnt_1"
|
||||
1
|
||||
0 0 0 1
|
||||
4.77984621e-18 0.0489999987 0
|
||||
0
|
||||
"L_Ring_sjnt_0"
|
||||
1
|
||||
0.119370371 -0.698211312 0.204397932 0.675628006
|
||||
-0.006254646 -0.0797718689 0.0093988115
|
||||
0
|
||||
"R_Index_sjnt_2"
|
||||
1
|
||||
0.175203487 0 0 0.984532237
|
||||
3.01980666e-16 0.0204999987 0
|
||||
0
|
||||
"R_Ring_sjnt_0"
|
||||
1
|
||||
0.119370371 -0.698211312 0.204397932 0.675628006
|
||||
0.00625085598 0.0797746703 -0.00940056238
|
||||
0
|
||||
"R_Index_sjnt_0"
|
||||
1
|
||||
-0.19517909 0.755869865 -0.161748767 -0.603658199
|
||||
-0.00134941039 0.0782186612 0.028039448
|
||||
0
|
||||
"R_Pinky_sjnt_1"
|
||||
1
|
||||
0.22303848 0 0 0.974809647
|
||||
-3.55271347e-16 0.0372027382 0
|
||||
0
|
||||
"L_Pinky_sjnt_1"
|
||||
1
|
||||
0.22303848 0 0 0.974809647
|
||||
3.70620683e-07 -0.0372028351 1.38079258e-07
|
||||
0
|
||||
"R_Middle_sjnt_0"
|
||||
1
|
||||
0.156041026 -0.732423544 0.191366434 0.63449657
|
||||
0.00616463134 0.0818372741 0.0097120041
|
||||
0
|
||||
"R_Arm_sjnt_1"
|
||||
1
|
||||
0.184809059 0 0 0.982774496
|
||||
-1.42108544e-16 0.260629684 4.440892e-18
|
||||
0
|
||||
"L_Foot_sjnt_2"
|
||||
1
|
||||
0 0 0 1
|
||||
-1.7763568e-17 -0.0488719977 4.88498128e-17
|
||||
0
|
||||
"L_Pinky_sjnt_2"
|
||||
1
|
||||
0.0992502794 0 0 0.99506253
|
||||
-1.85520605e-07 -0.0186209753 6.46735657e-07
|
||||
0
|
||||
"L_Ring_sjnt_3"
|
||||
1
|
||||
0 0 0 1
|
||||
4.95807114e-07 -0.0159507934 1.36332858e-07
|
||||
0
|
||||
"L_Clavicle_sjnt_0"
|
||||
1
|
||||
0.761695385 -0.617813051 -0.144681439 0.131128147
|
||||
0.00729848957 0.208856419 0.0306760129
|
||||
0
|
||||
"L_Pinky_sjnt_3"
|
||||
1
|
||||
0 0 0 1
|
||||
3.66131957e-07 -0.0121525498 -7.50564652e-07
|
||||
0
|
||||
"R_Thumb_sjnt_3"
|
||||
1
|
||||
0 0 0 1
|
||||
7.1054272e-17 0.0181292463 -2.62012622e-16
|
||||
0
|
||||
"R_Foot_sjnt_2"
|
||||
1
|
||||
0 0 0 1
|
||||
3.5527136e-17 0.0488717034 -3.99680272e-17
|
||||
0
|
||||
"L_Leg_sjnt_0"
|
||||
1
|
||||
-0.0122135505 -0.000290387718 0.0237673745 0.999642909
|
||||
0.104854003 -0.000224642019 7.96136592e-05
|
||||
0
|
||||
"L_Middle_sjnt_1"
|
||||
1
|
||||
0.184680417 0 0 0.982798636
|
||||
-2.44896114e-07 -0.0481087901 -7.74885621e-07
|
||||
0
|
||||
"L_Pinky_sjnt_0"
|
||||
1
|
||||
0.105012663 -0.656231523 0.23035267 0.710823596
|
||||
-0.00242854073 -0.0733879432 0.0260373093
|
||||
0
|
||||
"L_Wrist_sjnt_0"
|
||||
1
|
||||
0 0 0 1
|
||||
6.57227065e-06 -0.242271721 2.52947029e-06
|
||||
0
|
||||
"R_Ring_sjnt_1"
|
||||
1
|
||||
0.251216322 0 0 0.967930973
|
||||
-5.3290704e-17 0.0443951264 -5.68434176e-16
|
||||
0
|
||||
"R_Pinky_sjnt_2"
|
||||
1
|
||||
0.0992502794 0 0 0.99506253
|
||||
-1.06581408e-16 0.0186204202 -7.1054272e-17
|
||||
0
|
||||
"L_Prop_fjnt_0"
|
||||
1
|
||||
0 1 0 -4.37113883e-08
|
||||
0.0276746862 -0.0656316727 -0.000328583526
|
||||
0
|
||||
"L_Middle_sjnt_2"
|
||||
1
|
||||
0.157416984 0 0 0.987532258
|
||||
-6.02384603e-07 -0.0248495787 6.76881555e-08
|
||||
0
|
||||
"R_Middle_sjnt_1"
|
||||
1
|
||||
0.184680417 0 0 0.982798636
|
||||
-6.39488435e-16 0.048108764 1.42108544e-16
|
||||
0
|
||||
"L_Leg_sjnt_1"
|
||||
1
|
||||
0.060151346 0 0 0.99818927
|
||||
2.61005539e-07 -0.461806506 -3.93129014e-08
|
||||
0
|
||||
"L_Thumb_sjnt_2"
|
||||
1
|
||||
-0.0012165627 0 0 0.999999285
|
||||
5.15941792e-07 -0.0251661409 -5.85450152e-07
|
||||
0
|
||||
"L_Ring_sjnt_1"
|
||||
1
|
||||
0.251216322 0 0 0.967930973
|
||||
3.12667623e-07 -0.0443952158 -5.95922245e-07
|
||||
0
|
||||
"R_Foot_sjnt_1"
|
||||
1
|
||||
-0.251680881 0 0 0.967810273
|
||||
-8.88178367e-17 0.133286357 -0.00287180441
|
||||
0
|
||||
"C_Neck_sjnt_1"
|
||||
1
|
||||
-0.21643962 0 0 0.976296008
|
||||
5.18627479e-18 0.0540000014 0
|
||||
0
|
||||
"R_Ring_sjnt_3"
|
||||
1
|
||||
0 0 0 1
|
||||
-5.3290704e-17 0.0159499999 -7.1054272e-17
|
||||
0
|
||||
"L_Index_sjnt_0"
|
||||
1
|
||||
-0.19517909 0.755869865 -0.161748767 -0.603658199
|
||||
0.00134612026 -0.0782155693 -0.0280411374
|
||||
0
|
||||
"L_Index_sjnt_1"
|
||||
1
|
||||
0.229845911 0 0 0.973227024
|
||||
7.62208856e-07 -0.041899953 -1.70619145e-07
|
||||
0
|
||||
"R_Thumb_sjnt_1"
|
||||
1
|
||||
0.0813905671 0 0 0.996682286
|
||||
-2.13162816e-16 0.0301780477 1.42108544e-16
|
||||
0
|
||||
"L_Thumb_sjnt_3"
|
||||
1
|
||||
0 0 0 1
|
||||
-7.5862016e-07 -0.0181290414 5.47535365e-07
|
||||
0
|
||||
"R_Index_sjnt_3"
|
||||
1
|
||||
0 0 0 1
|
||||
3.10862442e-16 0.019439999 5.3290704e-17
|
||||
0
|
||||
"R_Middle_sjnt_2"
|
||||
1
|
||||
0.157416984 0 0 0.987532258
|
||||
-1.7763568e-17 0.0248499978 7.1054272e-17
|
||||
0
|
||||
"hipsBone"
|
||||
1
|
||||
3.09086232e-08 0.707106829 0.707106829 3.09086232e-08
|
||||
0 0.0230353847 0.931121647
|
||||
0
|
||||
"R_Pinky_sjnt_3"
|
||||
1
|
||||
0 0 0 1
|
||||
7.1054272e-17 0.0121525582 3.5527136e-17
|
||||
0
|
||||
"L_Foot_sjnt_0"
|
||||
1
|
||||
-0.546992362 0.0110395309 -0.0210499652 0.836800098
|
||||
-9.25209633e-07 -0.388170779 2.78088415e-08
|
||||
0
|
||||
"L_Index_sjnt_2"
|
||||
1
|
||||
0.175203487 0 0 0.984532237
|
||||
8.53871498e-08 -0.0204997063 3.77475885e-07
|
||||
0
|
||||
"C_Spine_sjnt_3"
|
||||
1
|
||||
0 0 0 1
|
||||
4.77984621e-18 0.0489999987 1.7763568e-17
|
||||
0
|
||||
"R_Foot_sjnt_0"
|
||||
1
|
||||
-0.546992362 0.0110395309 -0.0210499652 0.836800098
|
||||
0 0.38817063 0
|
||||
0
|
||||
"R_Ring_sjnt_2"
|
||||
1
|
||||
0.121089756 0 0 0.992641568
|
||||
-5.3290704e-17 0.0234420039 1.42108544e-16
|
||||
0
|
||||
"R_Wrist_sjnt_0"
|
||||
1
|
||||
0 0 0 1
|
||||
4.26325632e-16 0.24226594 -3.90798503e-16
|
||||
0
|
||||
"L_Middle_sjnt_0"
|
||||
1
|
||||
0.156041026 -0.732423544 0.191366434 0.63449657
|
||||
-0.00616830075 -0.0818345174 -0.0097129494
|
||||
0
|
||||
"L_Ring_sjnt_2"
|
||||
1
|
||||
0.121089756 0 0 0.992641568
|
||||
1.66412786e-08 -0.0234416053 4.04103446e-07
|
||||
0
|
||||
"L_Index_sjnt_3"
|
||||
1
|
||||
0 0 0 1
|
||||
-2.39056641e-09 -0.0194404367 -1.39765135e-07
|
||||
0
|
||||
"C_Spine_sjnt_0"
|
||||
1
|
||||
0 0 0 1
|
||||
3.76215184e-18 0.0554419272 8.881784e-18
|
||||
0
|
||||
"L_Arm_sjnt_1"
|
||||
1
|
||||
0.184809059 0 0 0.982774496
|
||||
-1.14686986e-06 -0.260628074 -4.16461354e-08
|
||||
0
|
||||
"R_Leg_sjnt_1"
|
||||
1
|
||||
0.060151346 0 0 0.99818927
|
||||
3.5527136e-17 0.461806893 8.881784e-18
|
||||
0
|
||||
"R_Thumb_sjnt_2"
|
||||
1
|
||||
-0.0012165627 0 0 0.999999285
|
||||
4.26325632e-16 0.0251665488 5.10702581e-16
|
||||
0
|
||||
"L_Foot_sjnt_1"
|
||||
1
|
||||
-0.251680881 0 0 0.967810273
|
||||
5.3290704e-17 -0.133285969 0.00287160906
|
||||
0
|
||||
"R_Pinky_sjnt_0"
|
||||
1
|
||||
0.105012663 -0.656231523 0.23035267 0.710823596
|
||||
0.00242519076 0.0733913928 -0.0260387883
|
||||
0
|
||||
"R_Middle_sjnt_3"
|
||||
1
|
||||
0 0 0 1
|
||||
2.48689959e-16 0.0180759132 -7.1054272e-17
|
||||
0
|
||||
"L_Thumb_sjnt_1"
|
||||
1
|
||||
0.0813905671 0 0 0.996682286
|
||||
-5.24074721e-07 -0.0301787555 -2.92531354e-07
|
||||
0
|
||||
"C_Spine_sjnt_2"
|
||||
1
|
||||
0 0 0 1
|
||||
4.7798458e-18 0.0489999987 -2.22044592e-17
|
||||
0
|
||||
"R_Prop_fjnt_0"
|
||||
1
|
||||
0 0 0 1
|
||||
-0.0276775807 0.0656346902 0.000327039947
|
||||
0
|
||||
"L_Thumb_sjnt_0"
|
||||
1
|
||||
0.416852266 -0.817598581 -0.284677148 -0.27699402
|
||||
0.020829184 -0.0239574499 -0.0221176092
|
||||
0
|
||||
"R_Thumb_sjnt_0"
|
||||
1
|
||||
0.416852266 -0.817598581 -0.284677148 -0.27699402
|
||||
-0.0208326261 0.0239606146 0.0221159924
|
||||
0
|
||||
"L_Arm_sjnt_0"
|
||||
1
|
||||
0.199253842 -0.0567296185 0.463827372 0.861361623
|
||||
0.0704552606 -0.150702849 0.00581921311
|
||||
0
|
||||
"R_Arm_sjnt_0"
|
||||
1
|
||||
0.199253842 -0.0567296185 0.463827372 0.861361623
|
||||
-0.0704575405 0.150702029 -0.00581940683
|
||||
0
|
||||
"R_Index_sjnt_1"
|
||||
1
|
||||
0.229845911 0 0 0.973227024
|
||||
-5.3290704e-17 0.0419000015 1.42108544e-16
|
||||
0
|
||||
true
|
153
src/JoltPhysics/Assets/Human/skeleton_hd.tof
Normal file
@ -0,0 +1,153 @@
|
||||
TOS 1.00
|
||||
|
||||
declare Skeleton 1
|
||||
mJoints array instance Skeleton::Joint
|
||||
|
||||
declare Skeleton::Joint 2
|
||||
mName string
|
||||
mParentName string
|
||||
|
||||
object Skeleton 00000001
|
||||
71
|
||||
"rootBone"
|
||||
""
|
||||
"hipsBone"
|
||||
"rootBone"
|
||||
"C_Spine_sjnt_0"
|
||||
"hipsBone"
|
||||
"C_Spine_sjnt_1"
|
||||
"C_Spine_sjnt_0"
|
||||
"C_Spine_sjnt_2"
|
||||
"C_Spine_sjnt_1"
|
||||
"C_Spine_sjnt_3"
|
||||
"C_Spine_sjnt_2"
|
||||
"C_Spine_sjnt_4"
|
||||
"C_Spine_sjnt_3"
|
||||
"R_Clavicle_sjnt_0"
|
||||
"C_Spine_sjnt_4"
|
||||
"R_Arm_sjnt_0"
|
||||
"R_Clavicle_sjnt_0"
|
||||
"R_Arm_sjnt_1"
|
||||
"R_Arm_sjnt_0"
|
||||
"R_Wrist_sjnt_0"
|
||||
"R_Arm_sjnt_1"
|
||||
"R_Thumb_sjnt_0"
|
||||
"R_Wrist_sjnt_0"
|
||||
"R_Thumb_sjnt_1"
|
||||
"R_Thumb_sjnt_0"
|
||||
"R_Thumb_sjnt_2"
|
||||
"R_Thumb_sjnt_1"
|
||||
"R_Thumb_sjnt_3"
|
||||
"R_Thumb_sjnt_2"
|
||||
"R_Index_sjnt_0"
|
||||
"R_Wrist_sjnt_0"
|
||||
"R_Index_sjnt_1"
|
||||
"R_Index_sjnt_0"
|
||||
"R_Index_sjnt_2"
|
||||
"R_Index_sjnt_1"
|
||||
"R_Index_sjnt_3"
|
||||
"R_Index_sjnt_2"
|
||||
"R_Middle_sjnt_0"
|
||||
"R_Wrist_sjnt_0"
|
||||
"R_Middle_sjnt_1"
|
||||
"R_Middle_sjnt_0"
|
||||
"R_Middle_sjnt_2"
|
||||
"R_Middle_sjnt_1"
|
||||
"R_Middle_sjnt_3"
|
||||
"R_Middle_sjnt_2"
|
||||
"R_Ring_sjnt_0"
|
||||
"R_Wrist_sjnt_0"
|
||||
"R_Ring_sjnt_1"
|
||||
"R_Ring_sjnt_0"
|
||||
"R_Ring_sjnt_2"
|
||||
"R_Ring_sjnt_1"
|
||||
"R_Ring_sjnt_3"
|
||||
"R_Ring_sjnt_2"
|
||||
"R_Pinky_sjnt_0"
|
||||
"R_Wrist_sjnt_0"
|
||||
"R_Pinky_sjnt_1"
|
||||
"R_Pinky_sjnt_0"
|
||||
"R_Pinky_sjnt_2"
|
||||
"R_Pinky_sjnt_1"
|
||||
"R_Pinky_sjnt_3"
|
||||
"R_Pinky_sjnt_2"
|
||||
"R_Prop_fjnt_0"
|
||||
"R_Wrist_sjnt_0"
|
||||
"C_Neck_sjnt_0"
|
||||
"C_Spine_sjnt_4"
|
||||
"C_Neck_sjnt_1"
|
||||
"C_Neck_sjnt_0"
|
||||
"C_Neck_sjnt_2"
|
||||
"C_Neck_sjnt_1"
|
||||
"C_Head_sjnt_0"
|
||||
"C_Neck_sjnt_2"
|
||||
"L_Clavicle_sjnt_0"
|
||||
"C_Spine_sjnt_4"
|
||||
"L_Arm_sjnt_0"
|
||||
"L_Clavicle_sjnt_0"
|
||||
"L_Arm_sjnt_1"
|
||||
"L_Arm_sjnt_0"
|
||||
"L_Wrist_sjnt_0"
|
||||
"L_Arm_sjnt_1"
|
||||
"L_Thumb_sjnt_0"
|
||||
"L_Wrist_sjnt_0"
|
||||
"L_Thumb_sjnt_1"
|
||||
"L_Thumb_sjnt_0"
|
||||
"L_Thumb_sjnt_2"
|
||||
"L_Thumb_sjnt_1"
|
||||
"L_Thumb_sjnt_3"
|
||||
"L_Thumb_sjnt_2"
|
||||
"L_Index_sjnt_0"
|
||||
"L_Wrist_sjnt_0"
|
||||
"L_Index_sjnt_1"
|
||||
"L_Index_sjnt_0"
|
||||
"L_Index_sjnt_2"
|
||||
"L_Index_sjnt_1"
|
||||
"L_Index_sjnt_3"
|
||||
"L_Index_sjnt_2"
|
||||
"L_Middle_sjnt_0"
|
||||
"L_Wrist_sjnt_0"
|
||||
"L_Middle_sjnt_1"
|
||||
"L_Middle_sjnt_0"
|
||||
"L_Middle_sjnt_2"
|
||||
"L_Middle_sjnt_1"
|
||||
"L_Middle_sjnt_3"
|
||||
"L_Middle_sjnt_2"
|
||||
"L_Ring_sjnt_0"
|
||||
"L_Wrist_sjnt_0"
|
||||
"L_Ring_sjnt_1"
|
||||
"L_Ring_sjnt_0"
|
||||
"L_Ring_sjnt_2"
|
||||
"L_Ring_sjnt_1"
|
||||
"L_Ring_sjnt_3"
|
||||
"L_Ring_sjnt_2"
|
||||
"L_Pinky_sjnt_0"
|
||||
"L_Wrist_sjnt_0"
|
||||
"L_Pinky_sjnt_1"
|
||||
"L_Pinky_sjnt_0"
|
||||
"L_Pinky_sjnt_2"
|
||||
"L_Pinky_sjnt_1"
|
||||
"L_Pinky_sjnt_3"
|
||||
"L_Pinky_sjnt_2"
|
||||
"L_Prop_fjnt_0"
|
||||
"L_Wrist_sjnt_0"
|
||||
"R_Leg_sjnt_0"
|
||||
"hipsBone"
|
||||
"R_Leg_sjnt_1"
|
||||
"R_Leg_sjnt_0"
|
||||
"R_Foot_sjnt_0"
|
||||
"R_Leg_sjnt_1"
|
||||
"R_Foot_sjnt_1"
|
||||
"R_Foot_sjnt_0"
|
||||
"R_Foot_sjnt_2"
|
||||
"R_Foot_sjnt_1"
|
||||
"L_Leg_sjnt_0"
|
||||
"hipsBone"
|
||||
"L_Leg_sjnt_1"
|
||||
"L_Leg_sjnt_0"
|
||||
"L_Foot_sjnt_0"
|
||||
"L_Leg_sjnt_1"
|
||||
"L_Foot_sjnt_1"
|
||||
"L_Foot_sjnt_0"
|
||||
"L_Foot_sjnt_2"
|
||||
"L_Foot_sjnt_1"
|
3443
src/JoltPhysics/Assets/Human/sprint.tof
Normal file
5927
src/JoltPhysics/Assets/Human/walk.tof
Normal file
8
src/JoltPhysics/Assets/LICENSE
Normal file
@ -0,0 +1,8 @@
|
||||
The following assets were taken from Horizon Zero Dawn:
|
||||
|
||||
terrain1.bof and terrain2.bof contain the 'Mothers Heart' scene
|
||||
convex_hulls.bin contains point clouds used as the source for convex hulls
|
||||
heightfield1.bin contains a single 'tile' of terrain data
|
||||
Human.tof and Human/*.tof contain the Aloy ragdoll setup and a couple of sample animations mapped onto the ragdoll
|
||||
|
||||
Permission was granted by Guerrilla Games to release this under the same MIT license as the rest of the project.
|
165
src/JoltPhysics/Assets/Racetracks/LICENSE.txt
Normal file
@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
3
src/JoltPhysics/Assets/Racetracks/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
Race tracks taken from: https://github.com/TUMFTM/racetrack-database
|
||||
|
||||
See LICENSE.txt for license for these race tracks.
|
865
src/JoltPhysics/Assets/Racetracks/Zandvoort.csv
Normal file
@ -0,0 +1,865 @@
|
||||
# x_m,y_m,w_tr_right_m,w_tr_left_m
|
||||
-1.683339,-1.878198,5.074,5.271
|
||||
0.151452,2.772507,5.099,5.295
|
||||
1.986397,7.423128,5.125,5.319
|
||||
3.821455,12.073677,5.150,5.343
|
||||
5.656587,16.724166,5.175,5.367
|
||||
7.491752,21.374607,5.200,5.391
|
||||
9.326909,26.025014,5.226,5.415
|
||||
11.162019,30.675397,5.251,5.439
|
||||
12.997042,35.325770,5.276,5.462
|
||||
14.831936,39.976144,5.301,5.486
|
||||
16.666662,44.626532,5.327,5.510
|
||||
18.501180,49.276946,5.352,5.534
|
||||
20.335449,53.927398,5.377,5.558
|
||||
22.169429,58.577901,5.402,5.582
|
||||
24.003080,63.228467,5.428,5.606
|
||||
25.836362,67.879107,5.453,5.630
|
||||
27.669244,72.529833,5.478,5.654
|
||||
29.501738,77.180644,5.503,5.678
|
||||
31.333865,81.831537,5.529,5.702
|
||||
33.165645,86.482511,5.554,5.726
|
||||
34.997100,91.133563,5.579,5.750
|
||||
36.828251,95.784691,5.604,5.774
|
||||
38.659117,100.435894,5.630,5.798
|
||||
40.489721,105.087167,5.655,5.822
|
||||
42.320083,109.738510,5.680,5.845
|
||||
44.150224,114.389921,5.706,5.869
|
||||
45.980165,119.041396,5.731,5.893
|
||||
47.809927,123.692934,5.756,5.917
|
||||
49.639531,128.344532,5.781,5.941
|
||||
51.468997,132.996189,5.807,5.965
|
||||
53.298346,137.647901,5.832,5.989
|
||||
55.127600,142.299668,5.857,6.013
|
||||
56.956780,146.951486,5.882,6.037
|
||||
58.785905,151.603353,5.908,6.061
|
||||
60.614998,156.255268,5.933,6.085
|
||||
62.444078,160.907227,5.958,6.109
|
||||
64.273168,165.559229,5.983,6.133
|
||||
66.102287,170.211271,6.009,6.157
|
||||
67.931458,174.863352,6.034,6.181
|
||||
69.760699,179.515468,6.059,6.205
|
||||
71.590034,184.167619,6.084,6.229
|
||||
73.419481,188.819800,6.110,6.252
|
||||
75.249063,193.472011,6.135,6.276
|
||||
77.078801,198.124249,6.160,6.300
|
||||
78.908714,202.776512,6.185,6.324
|
||||
80.738825,207.428798,6.211,6.348
|
||||
82.569153,212.081104,6.236,6.372
|
||||
84.399720,216.733428,6.261,6.396
|
||||
86.230547,221.385768,6.286,6.420
|
||||
88.061655,226.038121,6.312,6.444
|
||||
89.893064,230.690486,6.337,6.468
|
||||
91.724795,235.342861,6.362,6.492
|
||||
93.556870,239.995242,6.388,6.516
|
||||
95.389309,244.647628,6.413,6.540
|
||||
97.222133,249.300016,6.438,6.564
|
||||
99.055363,253.952405,6.463,6.588
|
||||
100.889021,258.604792,6.489,6.612
|
||||
102.723126,263.257175,6.514,6.635
|
||||
104.557699,267.909552,6.539,6.659
|
||||
106.392763,272.561920,6.564,6.683
|
||||
108.228337,277.214277,6.590,6.707
|
||||
110.064442,281.866621,6.615,6.731
|
||||
111.901100,286.518949,6.640,6.755
|
||||
113.738331,291.171261,6.665,6.779
|
||||
115.576156,295.823552,6.691,6.803
|
||||
117.414596,300.475821,6.716,6.827
|
||||
119.253672,305.128067,6.741,6.851
|
||||
121.093405,309.780286,6.766,6.875
|
||||
122.933816,314.432476,6.792,6.899
|
||||
124.774925,319.084635,6.816,6.923
|
||||
126.651699,323.714334,6.669,7.006
|
||||
128.738887,328.209430,6.522,7.089
|
||||
131.246183,332.435357,6.522,6.226
|
||||
134.379060,336.257639,6.092,6.062
|
||||
138.182494,339.545392,5.677,6.289
|
||||
142.495039,342.172347,5.848,6.230
|
||||
147.141834,344.013044,6.038,6.065
|
||||
151.981474,345.037089,5.885,6.029
|
||||
156.945280,345.420747,6.132,5.821
|
||||
161.974127,345.367418,6.058,5.924
|
||||
167.008204,345.065211,5.807,6.178
|
||||
171.977944,344.482774,5.789,6.230
|
||||
176.806475,343.424482,5.869,6.193
|
||||
181.417183,341.694720,5.987,6.121
|
||||
185.749365,339.242190,5.914,6.218
|
||||
189.762356,336.197440,5.948,6.207
|
||||
193.416775,332.702620,6.070,6.105
|
||||
196.666967,328.885936,6.207,5.965
|
||||
199.423062,324.777280,5.742,6.233
|
||||
201.576184,320.364273,5.591,6.084
|
||||
203.023502,315.640256,5.646,5.825
|
||||
203.748491,310.681493,5.785,5.710
|
||||
203.798453,305.625580,5.801,5.643
|
||||
203.222189,300.611552,5.651,5.577
|
||||
202.092240,295.744077,5.363,5.608
|
||||
200.571389,290.997188,5.182,5.600
|
||||
198.843858,286.313886,5.142,5.539
|
||||
197.076965,281.642398,5.102,5.479
|
||||
195.319515,276.967602,5.062,5.418
|
||||
193.569611,272.290054,5.022,5.358
|
||||
191.825166,267.610371,4.982,5.297
|
||||
190.084090,262.929171,4.942,5.236
|
||||
188.344295,258.247069,4.903,5.176
|
||||
186.603693,253.564683,4.863,5.115
|
||||
184.860195,248.882630,4.823,5.055
|
||||
183.111713,244.201525,4.783,4.994
|
||||
181.356158,239.521985,4.743,4.934
|
||||
179.591443,234.844628,4.703,4.873
|
||||
177.815478,230.170070,4.664,4.813
|
||||
176.026175,225.498928,4.624,4.752
|
||||
174.221466,220.831812,4.584,4.692
|
||||
172.402865,216.168291,4.544,4.631
|
||||
170.579569,211.505702,4.504,4.571
|
||||
168.761766,206.841091,4.464,4.510
|
||||
166.959647,202.171505,4.424,4.450
|
||||
165.183399,197.493991,4.385,4.389
|
||||
163.443211,192.805596,4.345,4.329
|
||||
161.749274,188.103367,4.305,4.268
|
||||
160.111775,183.384351,4.190,4.272
|
||||
158.540904,178.645594,4.021,4.323
|
||||
157.046851,173.884144,4.128,4.318
|
||||
155.639803,169.097048,4.247,4.300
|
||||
154.329950,164.281352,4.406,4.212
|
||||
153.127482,159.434104,4.493,4.107
|
||||
152.040841,154.553794,4.555,3.996
|
||||
151.071739,149.644481,4.460,4.003
|
||||
150.220267,144.711567,4.332,4.045
|
||||
149.486513,139.760453,4.374,4.113
|
||||
148.870566,134.796540,4.291,4.230
|
||||
148.372516,129.825230,4.183,4.336
|
||||
147.992434,124.851911,4.140,4.294
|
||||
147.726990,119.879465,4.200,4.285
|
||||
147.565511,114.905358,4.313,4.294
|
||||
147.496360,109.926350,4.273,4.313
|
||||
147.507905,104.939200,4.175,4.335
|
||||
147.588509,99.940667,4.077,4.357
|
||||
147.726539,94.927512,4.132,4.316
|
||||
147.909661,89.896706,4.206,4.266
|
||||
148.099958,84.853004,4.281,4.217
|
||||
148.227166,79.811000,4.355,4.167
|
||||
148.218945,74.785923,4.352,4.137
|
||||
148.002954,69.792997,4.281,4.126
|
||||
147.506854,64.847451,4.275,4.132
|
||||
146.658303,59.964509,4.310,4.205
|
||||
145.388472,55.160670,4.205,4.498
|
||||
143.678977,50.470695,4.146,4.624
|
||||
141.549258,45.943039,4.172,4.747
|
||||
139.019670,41.626490,4.262,4.889
|
||||
136.110565,37.569834,4.418,4.983
|
||||
132.842300,33.821858,4.451,4.599
|
||||
129.235227,30.431348,4.451,4.398
|
||||
125.312766,27.436881,4.418,4.409
|
||||
121.120144,24.804331,4.355,4.278
|
||||
116.712056,22.468034,4.270,4.348
|
||||
112.143230,20.362198,4.184,4.427
|
||||
107.468396,18.421033,4.099,4.507
|
||||
102.742286,16.578745,4.048,4.545
|
||||
98.019629,14.769545,4.095,4.463
|
||||
93.342513,12.942394,4.142,4.381
|
||||
88.704216,11.103219,4.189,4.300
|
||||
84.086235,9.271696,4.236,4.218
|
||||
79.470070,7.467499,4.284,4.136
|
||||
74.837217,5.710302,4.331,4.055
|
||||
70.169176,4.019780,4.278,4.105
|
||||
65.447529,2.415476,4.160,4.240
|
||||
60.669630,0.892412,4.042,4.375
|
||||
55.866984,-0.607489,4.038,4.423
|
||||
51.075564,-2.149247,4.236,4.314
|
||||
46.331341,-3.797882,4.434,4.205
|
||||
41.670287,-5.618416,4.632,4.096
|
||||
37.128373,-7.675868,4.635,4.242
|
||||
32.743211,-10.035645,4.623,4.392
|
||||
28.612354,-12.777269,4.606,4.509
|
||||
24.909111,-15.998105,4.888,4.185
|
||||
21.811325,-19.796169,4.673,4.211
|
||||
19.439269,-24.181707,4.222,4.435
|
||||
17.789594,-28.976489,4.444,4.545
|
||||
16.842948,-33.977887,4.564,4.573
|
||||
16.579252,-39.007227,4.818,4.705
|
||||
16.975636,-43.977492,5.060,4.754
|
||||
18.008569,-48.823586,5.137,4.584
|
||||
19.654514,-53.480415,4.896,4.452
|
||||
21.889938,-57.882883,4.802,4.511
|
||||
24.691308,-61.965894,4.744,4.612
|
||||
28.034938,-65.664418,4.670,4.685
|
||||
31.872160,-68.924115,4.762,4.498
|
||||
36.101648,-71.713185,4.797,4.469
|
||||
40.615402,-74.002680,4.672,4.788
|
||||
45.309127,-75.747824,4.864,4.612
|
||||
50.128975,-76.688113,5.130,4.321
|
||||
55.040283,-76.579563,4.952,4.341
|
||||
59.946477,-75.810565,4.752,4.290
|
||||
64.789826,-74.708054,4.543,4.150
|
||||
69.577538,-73.344400,4.460,4.132
|
||||
74.320695,-71.776786,4.424,4.159
|
||||
79.030380,-70.062396,4.388,4.186
|
||||
83.717677,-68.258412,4.352,4.213
|
||||
88.393668,-66.422017,4.316,4.240
|
||||
93.068996,-64.607786,4.280,4.268
|
||||
97.748404,-62.835178,4.244,4.295
|
||||
102.432408,-61.098522,4.208,4.322
|
||||
107.121432,-59.391600,4.172,4.349
|
||||
111.815902,-57.708192,4.136,4.377
|
||||
116.516242,-56.042081,4.100,4.404
|
||||
121.222878,-54.387047,4.064,4.431
|
||||
125.936245,-52.737906,4.028,4.458
|
||||
130.656867,-51.096499,3.992,4.485
|
||||
135.385298,-49.467589,3.956,4.513
|
||||
140.122098,-47.855949,4.007,4.456
|
||||
144.867821,-46.266353,4.087,4.372
|
||||
149.623025,-44.703573,4.167,4.288
|
||||
154.388268,-43.172382,4.247,4.203
|
||||
159.164104,-41.677554,4.298,4.120
|
||||
163.951092,-40.223862,4.334,4.036
|
||||
168.749789,-38.816079,4.370,3.953
|
||||
173.560750,-37.458978,4.405,3.869
|
||||
178.384534,-36.157332,4.254,4.031
|
||||
183.221696,-34.915914,4.064,4.244
|
||||
188.072792,-33.739486,3.874,4.456
|
||||
192.938144,-32.630868,3.876,4.512
|
||||
197.817589,-31.588837,3.951,4.510
|
||||
202.710900,-30.611665,4.026,4.507
|
||||
207.617853,-29.697620,4.115,4.497
|
||||
212.538223,-28.844975,4.216,4.481
|
||||
217.471784,-28.052000,4.345,4.438
|
||||
222.418294,-27.317078,4.570,4.297
|
||||
227.376885,-26.642445,4.794,4.157
|
||||
232.345927,-26.035039,4.806,4.423
|
||||
237.323747,-25.502088,4.795,4.733
|
||||
242.308667,-25.050816,4.804,4.968
|
||||
247.299013,-24.688449,4.870,4.985
|
||||
252.293109,-24.422213,4.936,5.003
|
||||
257.289037,-24.259478,4.961,5.020
|
||||
262.283974,-24.208158,4.971,5.038
|
||||
267.274885,-24.276290,4.800,5.101
|
||||
272.258736,-24.471913,4.628,5.164
|
||||
277.232491,-24.803068,4.505,5.156
|
||||
282.193116,-25.277793,4.486,5.000
|
||||
287.137588,-25.904062,4.466,4.845
|
||||
292.064716,-26.679188,4.474,4.579
|
||||
296.977157,-27.578124,4.488,4.286
|
||||
301.878054,-28.573005,4.503,3.993
|
||||
306.770548,-29.635967,4.404,3.982
|
||||
311.657780,-30.739145,4.285,4.017
|
||||
316.542892,-31.854674,4.167,4.051
|
||||
321.428992,-32.955036,4.096,4.095
|
||||
326.318026,-34.024611,4.133,4.158
|
||||
331.210506,-35.062414,4.169,4.222
|
||||
336.106862,-36.068357,4.205,4.286
|
||||
341.007518,-37.042351,4.225,4.300
|
||||
345.912902,-37.984309,4.219,4.240
|
||||
350.823442,-38.894142,4.214,4.181
|
||||
355.739563,-39.771763,4.209,4.121
|
||||
360.661693,-40.617082,4.204,4.062
|
||||
365.590258,-41.430014,4.198,4.003
|
||||
370.525686,-42.210468,4.181,3.995
|
||||
375.468403,-42.958358,4.141,4.092
|
||||
380.418836,-43.673594,4.100,4.190
|
||||
385.377412,-44.356090,4.194,4.121
|
||||
390.344264,-45.001791,4.371,3.948
|
||||
395.317475,-45.579028,4.443,3.916
|
||||
400.294259,-46.044395,4.418,4.015
|
||||
405.271826,-46.354443,4.385,4.118
|
||||
410.247385,-46.465723,4.282,4.258
|
||||
415.218148,-46.334784,4.178,4.398
|
||||
420.181323,-45.918177,4.224,4.298
|
||||
425.133987,-45.197781,4.323,4.108
|
||||
430.072713,-44.251288,4.344,4.070
|
||||
434.993954,-43.179046,4.316,4.125
|
||||
439.894009,-42.078959,4.281,4.177
|
||||
444.763823,-40.963691,4.231,4.223
|
||||
449.587719,-39.740469,4.201,4.249
|
||||
454.349640,-38.310236,4.266,4.175
|
||||
459.038639,-36.617037,4.326,4.089
|
||||
463.654604,-34.696295,4.371,3.972
|
||||
468.198805,-32.595092,4.383,3.886
|
||||
472.673103,-30.359601,3.976,4.184
|
||||
477.087549,-28.023365,3.990,4.182
|
||||
481.458197,-25.610672,4.119,4.098
|
||||
485.800998,-23.145258,4.249,4.014
|
||||
490.123304,-20.638911,4.379,3.930
|
||||
494.421825,-18.088632,4.371,3.952
|
||||
498.692612,-15.490497,4.249,4.062
|
||||
502.931711,-12.840586,4.126,4.173
|
||||
507.135172,-10.134977,4.004,4.283
|
||||
511.299044,-7.369750,4.089,4.144
|
||||
515.423163,-4.546296,4.176,4.003
|
||||
519.521744,-1.686182,4.263,3.862
|
||||
523.612415,1.184239,4.166,3.903
|
||||
527.712803,4.038614,3.966,4.047
|
||||
531.840536,6.850589,3.819,4.161
|
||||
536.013241,9.593812,3.869,4.167
|
||||
540.248511,12.241964,4.004,4.106
|
||||
544.557752,14.774904,4.127,4.031
|
||||
548.939186,17.185655,4.102,4.026
|
||||
553.389343,19.468929,4.048,4.004
|
||||
557.904756,21.619437,3.997,4.001
|
||||
562.481955,23.631891,3.949,4.032
|
||||
567.117471,25.501002,3.951,4.119
|
||||
571.807805,27.221672,3.978,4.235
|
||||
576.548384,28.795486,4.095,4.320
|
||||
581.333297,30.232374,4.258,4.389
|
||||
586.156546,31.542788,4.369,4.434
|
||||
591.012137,32.737181,4.398,4.439
|
||||
595.894073,33.826004,4.428,4.443
|
||||
600.796359,34.819711,4.342,4.407
|
||||
605.713335,35.726460,4.185,4.346
|
||||
610.644123,36.522011,4.027,4.284
|
||||
615.591378,37.158137,4.053,4.379
|
||||
620.557840,37.586044,4.089,4.483
|
||||
625.544317,37.776802,4.175,4.408
|
||||
630.544207,37.777603,4.261,4.331
|
||||
635.549133,37.653867,4.305,4.272
|
||||
640.551532,37.465775,4.266,4.246
|
||||
645.549590,37.236469,4.228,4.220
|
||||
650.543968,36.973127,4.189,4.195
|
||||
655.535339,36.682867,4.151,4.169
|
||||
660.524373,36.372805,4.113,4.143
|
||||
665.511744,36.050057,4.205,4.209
|
||||
670.498122,35.721741,4.298,4.277
|
||||
675.484179,35.394973,4.392,4.344
|
||||
680.470588,35.076869,4.485,4.411
|
||||
685.458019,34.774546,4.578,4.478
|
||||
690.447146,34.495121,4.672,4.545
|
||||
695.438639,34.245711,4.765,4.612
|
||||
700.433170,34.033432,4.859,4.679
|
||||
705.431408,33.865362,4.912,4.711
|
||||
710.433423,33.741608,4.827,4.620
|
||||
715.437997,33.647216,4.743,4.530
|
||||
720.443740,33.565270,4.658,4.439
|
||||
725.449265,33.478855,4.574,4.348
|
||||
730.453184,33.371056,4.489,4.258
|
||||
735.454108,33.224956,4.405,4.167
|
||||
740.450587,33.023502,4.286,4.211
|
||||
745.438840,32.744590,4.134,4.392
|
||||
750.412147,32.359732,3.981,4.572
|
||||
755.363599,31.840032,3.878,4.650
|
||||
760.286286,31.156595,3.899,4.616
|
||||
765.173300,30.280525,4.058,4.459
|
||||
770.017731,29.182924,4.231,4.252
|
||||
774.811717,27.841028,4.260,4.180
|
||||
779.543702,26.255866,4.236,4.158
|
||||
784.201230,24.434244,4.119,4.268
|
||||
788.771846,22.382966,4.080,4.251
|
||||
793.243097,20.108838,4.203,3.975
|
||||
797.602526,17.618665,4.216,4.021
|
||||
801.837680,14.919252,4.222,4.103
|
||||
805.936103,12.017403,4.226,4.225
|
||||
809.885342,8.919924,4.235,4.237
|
||||
813.672940,5.633620,4.249,4.191
|
||||
817.286445,2.165295,4.283,4.160
|
||||
820.713399,-1.478244,4.332,4.094
|
||||
823.941350,-5.290194,4.351,4.032
|
||||
826.957948,-9.263686,3.868,4.384
|
||||
829.754717,-13.389548,3.924,4.341
|
||||
832.328095,-17.655687,4.092,4.272
|
||||
834.674835,-22.049819,4.085,4.457
|
||||
836.791692,-26.559662,4.044,4.341
|
||||
838.675419,-31.172934,3.951,4.294
|
||||
840.322770,-35.877353,3.873,4.297
|
||||
841.730499,-40.660635,3.942,4.140
|
||||
842.895359,-45.510499,4.032,4.063
|
||||
843.814104,-50.414663,4.113,4.038
|
||||
844.483488,-55.360842,4.079,4.147
|
||||
844.900265,-60.336757,4.221,4.148
|
||||
845.061188,-65.330123,4.272,4.158
|
||||
844.963011,-70.328658,4.222,4.184
|
||||
844.603481,-75.319993,4.123,4.224
|
||||
843.987444,-80.291123,4.229,4.096
|
||||
843.122839,-85.228773,4.214,4.084
|
||||
842.017620,-90.119662,4.126,4.175
|
||||
840.679739,-94.950513,4.017,4.390
|
||||
839.117149,-99.708047,4.070,4.387
|
||||
837.337803,-104.378985,4.045,4.431
|
||||
835.352725,-108.954255,4.002,4.435
|
||||
833.184895,-113.441146,3.951,4.377
|
||||
830.860195,-117.850926,3.900,4.319
|
||||
828.404511,-122.194866,3.849,4.261
|
||||
825.843726,-126.484231,3.798,4.204
|
||||
823.203724,-130.730292,3.811,4.173
|
||||
820.510358,-134.944303,3.852,4.154
|
||||
817.783350,-139.135229,3.894,4.135
|
||||
815.029104,-143.307047,3.935,4.115
|
||||
812.252270,-147.463082,3.976,4.096
|
||||
809.457503,-151.606658,4.018,4.077
|
||||
806.649452,-155.741097,4.043,4.067
|
||||
803.832772,-159.869725,4.035,4.073
|
||||
801.012113,-163.995864,4.028,4.078
|
||||
798.192128,-168.122838,4.021,4.084
|
||||
795.377469,-172.253972,4.014,4.090
|
||||
792.572788,-176.392589,4.006,4.096
|
||||
789.782738,-180.542012,4.016,4.084
|
||||
787.011970,-184.705566,4.062,4.035
|
||||
784.265137,-188.886574,4.108,3.985
|
||||
781.548155,-193.088638,4.154,3.936
|
||||
778.871892,-197.316448,4.187,3.912
|
||||
776.248431,-201.574960,4.213,3.905
|
||||
773.689850,-205.869131,4.226,3.963
|
||||
771.208232,-210.203916,4.218,4.136
|
||||
768.815657,-214.584272,4.326,4.338
|
||||
766.524154,-219.015133,4.587,4.577
|
||||
764.335653,-223.497073,4.847,4.816
|
||||
762.229923,-228.021102,5.174,5.141
|
||||
760.183793,-232.576960,5.514,5.484
|
||||
758.174091,-237.154385,5.854,5.826
|
||||
756.177647,-241.743118,6.194,6.169
|
||||
754.171288,-246.332898,6.534,6.512
|
||||
752.132210,-250.913573,6.875,6.854
|
||||
750.051474,-255.479086,6.929,6.928
|
||||
747.937913,-260.028628,6.935,6.955
|
||||
745.801525,-264.561735,6.941,6.983
|
||||
743.652310,-269.077941,6.947,7.011
|
||||
741.500266,-273.576782,6.953,7.038
|
||||
739.355392,-278.057794,6.959,7.062
|
||||
737.227192,-282.522008,6.957,6.995
|
||||
735.117889,-286.992512,6.954,6.927
|
||||
733.024156,-291.509202,6.952,6.860
|
||||
730.942527,-296.112395,6.949,6.793
|
||||
728.838033,-300.796250,6.947,6.725
|
||||
726.550918,-305.372085,6.816,6.838
|
||||
723.890534,-309.605955,6.657,7.124
|
||||
720.690584,-313.287789,6.919,7.008
|
||||
716.962948,-316.382204,6.936,6.563
|
||||
712.798664,-318.931422,6.330,7.057
|
||||
708.289129,-320.978019,6.497,7.072
|
||||
703.525739,-322.564569,6.586,7.140
|
||||
698.599890,-323.733646,6.635,7.236
|
||||
693.602980,-324.527826,7.056,6.882
|
||||
688.609823,-324.991490,7.328,6.647
|
||||
683.631014,-325.176014,7.024,6.932
|
||||
678.661600,-325.134471,6.721,7.218
|
||||
673.696625,-324.919930,6.832,7.143
|
||||
668.731136,-324.585464,6.953,7.059
|
||||
663.760179,-324.184143,7.018,7.031
|
||||
658.778821,-323.768904,6.947,7.138
|
||||
653.786008,-323.367672,6.875,7.244
|
||||
648.789087,-322.954242,6.929,7.170
|
||||
643.796500,-322.495333,7.011,7.054
|
||||
638.816689,-321.957669,7.093,6.939
|
||||
633.858098,-321.307969,7.122,6.893
|
||||
628.929168,-320.512955,7.079,6.942
|
||||
624.038261,-319.539882,7.030,6.996
|
||||
619.190736,-318.375604,6.783,7.274
|
||||
614.388155,-317.031783,6.537,7.552
|
||||
609.631833,-315.521672,6.759,7.267
|
||||
604.923088,-313.858527,7.030,6.923
|
||||
600.263236,-312.055602,7.123,6.884
|
||||
595.653594,-310.126153,7.190,6.891
|
||||
591.095298,-308.081827,7.140,6.938
|
||||
586.588781,-305.928036,7.021,7.008
|
||||
582.134305,-303.668679,6.893,7.134
|
||||
577.732134,-301.307655,6.749,7.356
|
||||
573.382530,-298.848864,6.804,7.293
|
||||
569.085755,-296.296203,6.932,7.126
|
||||
564.842074,-293.653573,7.060,6.958
|
||||
560.651748,-290.924873,7.039,6.927
|
||||
556.515040,-288.114002,6.945,6.961
|
||||
552.432213,-285.224858,6.856,6.995
|
||||
548.403530,-282.261342,6.963,7.018
|
||||
544.429254,-279.227351,7.071,7.042
|
||||
540.509648,-276.126786,7.045,7.143
|
||||
536.646058,-272.962511,6.921,7.301
|
||||
532.879958,-269.699105,6.796,7.459
|
||||
529.303798,-266.252512,6.800,7.424
|
||||
526.013321,-262.535532,6.982,7.125
|
||||
523.106293,-258.472868,7.046,6.955
|
||||
520.695052,-254.074915,6.962,6.947
|
||||
518.898317,-249.389602,6.882,7.008
|
||||
517.832775,-244.470660,6.727,7.126
|
||||
517.585351,-239.453276,6.760,7.127
|
||||
518.220595,-234.533878,6.960,6.976
|
||||
519.802514,-229.910386,6.644,7.012
|
||||
522.334949,-225.730525,6.697,7.030
|
||||
525.588832,-221.947703,6.723,7.076
|
||||
529.278745,-218.468315,6.755,7.116
|
||||
533.145068,-215.207132,7.006,6.938
|
||||
537.111602,-212.138479,7.135,6.844
|
||||
541.181603,-209.262478,6.882,7.016
|
||||
545.358650,-206.579354,6.630,7.189
|
||||
549.646318,-204.089333,6.583,7.245
|
||||
554.048185,-201.792641,6.776,7.166
|
||||
558.567826,-199.689504,6.962,7.066
|
||||
563.205028,-197.787576,7.142,6.952
|
||||
567.944951,-196.123167,7.104,6.998
|
||||
572.769226,-194.739502,6.943,7.135
|
||||
577.659441,-193.677704,6.782,7.272
|
||||
582.595565,-192.902588,6.832,7.157
|
||||
587.555526,-192.282824,6.891,7.032
|
||||
592.517155,-191.681168,6.950,6.907
|
||||
597.464671,-191.000804,7.008,6.782
|
||||
602.396071,-190.232186,7.067,6.656
|
||||
607.311150,-189.377138,7.078,6.584
|
||||
612.209702,-188.437485,6.754,6.880
|
||||
617.091520,-187.415051,6.736,6.909
|
||||
621.956399,-186.311660,6.885,6.792
|
||||
626.804133,-185.129135,6.995,6.731
|
||||
631.634516,-183.869300,7.081,6.705
|
||||
636.447341,-182.533981,7.031,6.778
|
||||
641.242404,-181.125000,6.926,6.889
|
||||
646.019497,-179.644181,6.822,7.001
|
||||
650.778415,-178.093350,6.911,6.915
|
||||
655.518952,-176.474329,7.032,6.797
|
||||
660.238753,-174.785985,7.152,6.679
|
||||
664.927143,-173.015721,7.144,6.677
|
||||
669.571431,-171.148166,6.832,6.948
|
||||
674.158924,-169.167949,6.519,7.220
|
||||
678.676932,-167.059698,6.652,7.059
|
||||
683.112764,-164.808044,7.010,6.679
|
||||
687.453615,-162.397497,7.367,6.300
|
||||
691.665455,-159.790647,7.318,6.459
|
||||
695.668265,-156.902579,7.235,6.631
|
||||
699.376004,-153.642165,7.092,6.768
|
||||
702.706093,-149.926475,6.881,6.943
|
||||
705.625359,-145.789734,6.597,7.155
|
||||
708.137497,-141.353584,6.711,7.081
|
||||
710.246759,-136.740516,6.913,6.949
|
||||
711.945681,-132.028298,7.275,6.712
|
||||
713.212100,-127.238602,7.271,6.600
|
||||
714.022926,-122.389546,7.233,6.584
|
||||
714.355066,-117.499248,7.183,6.721
|
||||
714.185428,-112.585823,7.151,6.829
|
||||
713.490920,-107.667391,7.131,6.916
|
||||
712.250145,-102.766987,6.929,6.984
|
||||
710.465448,-97.976495,6.713,7.023
|
||||
708.156646,-93.438475,7.013,6.892
|
||||
705.343960,-89.296659,7.275,6.739
|
||||
702.055119,-85.657540,7.465,6.546
|
||||
698.346209,-82.486891,7.379,6.678
|
||||
694.280014,-79.717258,6.996,7.159
|
||||
689.919273,-77.291912,7.046,7.064
|
||||
685.326428,-75.228159,7.189,6.846
|
||||
680.563791,-73.574557,7.133,6.834
|
||||
675.693600,-72.379388,7.037,6.865
|
||||
670.765309,-71.627906,7.088,6.839
|
||||
665.801465,-71.172685,7.209,6.787
|
||||
660.821215,-70.849523,7.175,6.820
|
||||
655.840166,-70.524248,6.962,6.952
|
||||
650.860639,-70.175383,6.793,6.998
|
||||
645.881844,-69.807882,6.707,6.881
|
||||
640.902988,-69.426694,6.621,6.763
|
||||
635.923278,-69.036773,6.535,6.646
|
||||
630.941924,-68.643070,6.449,6.528
|
||||
625.958135,-68.250537,6.363,6.411
|
||||
620.971472,-67.864144,6.277,6.293
|
||||
615.982233,-67.488901,6.192,6.175
|
||||
610.990811,-67.129823,6.093,6.032
|
||||
605.997598,-66.791923,5.973,5.842
|
||||
601.002986,-66.480216,5.852,5.652
|
||||
596.007369,-66.199717,5.791,5.575
|
||||
591.011138,-65.955440,5.734,5.551
|
||||
586.014686,-65.752400,5.650,5.580
|
||||
581.018405,-65.595610,5.565,5.609
|
||||
576.022688,-65.490086,5.481,5.638
|
||||
571.027927,-65.440841,5.534,5.590
|
||||
566.034515,-65.452890,5.705,5.477
|
||||
561.042844,-65.531248,5.876,5.364
|
||||
556.053237,-65.679211,5.782,5.483
|
||||
551.065759,-65.893563,5.623,5.659
|
||||
546.080411,-66.169548,6.015,6.094
|
||||
541.097195,-66.502409,6.506,6.577
|
||||
536.116113,-66.887389,6.677,6.700
|
||||
531.137167,-67.319731,6.553,6.493
|
||||
526.160360,-67.794679,6.430,6.286
|
||||
521.185692,-68.307476,6.306,6.079
|
||||
516.213166,-68.853365,6.182,5.872
|
||||
511.242784,-69.427590,6.058,5.664
|
||||
506.274548,-70.025392,5.935,5.457
|
||||
501.308460,-70.642017,5.896,5.416
|
||||
496.344521,-71.272706,6.002,5.654
|
||||
491.382740,-71.912804,6.107,5.892
|
||||
486.423329,-72.561174,6.212,6.130
|
||||
481.466756,-73.221067,6.318,6.368
|
||||
476.513507,-73.896006,6.381,6.522
|
||||
471.564064,-74.589515,6.270,6.332
|
||||
466.618913,-75.305119,6.158,6.142
|
||||
461.678537,-76.046340,6.047,5.952
|
||||
456.743421,-76.816702,5.936,5.762
|
||||
451.814048,-77.619730,5.824,5.571
|
||||
446.890904,-78.458948,5.713,5.381
|
||||
441.974472,-79.337878,5.621,5.239
|
||||
437.065236,-80.260046,5.595,5.267
|
||||
432.163681,-81.228974,5.570,5.295
|
||||
427.270291,-82.248187,5.544,5.323
|
||||
422.385725,-83.321083,5.518,5.351
|
||||
417.511874,-84.450176,5.515,5.365
|
||||
412.651163,-85.637598,5.517,5.377
|
||||
407.806015,-86.885480,5.518,5.389
|
||||
402.978857,-88.195952,5.519,5.401
|
||||
398.172113,-89.571147,5.520,5.432
|
||||
393.388210,-91.013195,5.520,5.463
|
||||
388.624995,-92.511917,5.520,5.495
|
||||
383.862725,-94.009802,5.520,5.526
|
||||
379.077425,-95.437961,5.521,5.557
|
||||
374.245857,-96.729642,5.517,5.554
|
||||
369.371439,-97.895329,5.513,5.549
|
||||
364.491077,-99.042554,5.509,5.545
|
||||
359.643725,-100.284782,5.510,5.531
|
||||
354.853551,-101.692947,5.546,5.452
|
||||
350.112834,-103.246245,5.582,5.374
|
||||
345.409702,-104.911934,5.649,5.341
|
||||
340.732282,-106.657272,6.154,5.936
|
||||
336.068704,-108.449520,6.658,6.530
|
||||
331.407095,-110.255934,7.163,7.125
|
||||
326.735781,-112.044283,7.177,7.169
|
||||
322.050266,-113.800844,6.985,6.979
|
||||
317.355113,-115.535242,6.792,6.790
|
||||
312.655461,-117.258596,6.599,6.601
|
||||
307.956451,-118.982024,6.406,6.412
|
||||
303.263223,-120.716643,6.214,6.223
|
||||
298.580917,-122.473571,6.021,6.034
|
||||
293.913754,-124.262073,5.828,5.844
|
||||
289.262383,-126.084219,5.816,5.779
|
||||
284.626590,-127.940337,6.002,5.849
|
||||
280.006160,-129.830753,6.188,5.920
|
||||
275.400879,-131.755795,6.375,5.990
|
||||
270.810530,-133.715789,6.561,6.061
|
||||
266.234900,-135.711061,6.747,6.131
|
||||
261.673772,-137.741939,6.916,6.212
|
||||
257.126933,-139.808750,6.896,6.400
|
||||
252.594167,-141.911820,6.877,6.588
|
||||
248.075260,-144.051476,6.857,6.776
|
||||
243.569995,-146.228045,6.837,6.964
|
||||
239.078159,-148.441854,6.817,7.152
|
||||
234.599579,-150.693176,6.982,7.327
|
||||
230.135655,-152.980290,7.413,7.481
|
||||
225.689788,-155.298942,7.844,7.636
|
||||
221.265508,-157.644713,8.276,7.791
|
||||
216.866345,-160.013182,8.296,7.724
|
||||
212.495831,-162.399931,8.123,7.553
|
||||
208.157494,-164.800540,7.950,7.382
|
||||
203.853512,-167.212860,7.777,7.211
|
||||
199.566372,-169.667776,7.604,7.039
|
||||
195.263682,-172.221124,7.431,6.868
|
||||
190.912688,-174.929357,7.258,6.697
|
||||
186.487983,-177.724071,7.078,6.551
|
||||
181.992983,-180.047120,6.789,6.764
|
||||
177.438175,-181.220304,6.203,6.945
|
||||
172.870986,-180.656336,6.339,7.243
|
||||
168.602825,-178.417542,6.636,6.911
|
||||
165.010059,-174.878403,7.071,6.883
|
||||
162.122071,-170.618791,7.181,6.805
|
||||
159.750492,-166.150514,7.152,6.715
|
||||
157.558157,-161.658507,7.123,6.624
|
||||
155.189121,-157.286255,7.093,6.533
|
||||
152.359584,-153.167518,7.064,6.443
|
||||
149.057687,-149.399398,6.723,6.016
|
||||
145.335628,-146.070364,6.197,5.369
|
||||
141.245605,-143.268882,5.813,5.483
|
||||
136.839819,-141.083420,5.615,5.650
|
||||
132.170467,-139.602446,5.607,5.556
|
||||
127.289888,-138.914002,5.642,5.330
|
||||
122.272466,-139.038412,5.431,5.067
|
||||
117.238594,-139.854676,5.131,4.831
|
||||
112.314429,-141.224096,4.822,4.830
|
||||
107.623328,-143.018285,4.742,4.689
|
||||
103.250890,-145.248063,4.859,4.429
|
||||
99.255600,-148.024195,4.934,4.321
|
||||
95.696653,-151.455576,4.649,4.520
|
||||
92.675502,-155.519437,4.528,4.649
|
||||
90.344115,-160.035622,4.667,4.596
|
||||
88.856582,-164.815027,4.703,4.596
|
||||
88.243937,-169.712396,4.812,4.552
|
||||
88.286263,-174.671888,4.788,4.429
|
||||
88.733063,-179.648558,4.874,4.484
|
||||
89.374668,-184.606576,4.960,4.568
|
||||
90.149191,-189.543100,4.955,4.566
|
||||
91.028177,-194.462751,4.950,4.564
|
||||
91.983170,-199.370149,4.945,4.563
|
||||
92.985716,-204.269917,4.940,4.561
|
||||
94.007360,-209.166676,4.934,4.559
|
||||
95.019718,-214.065034,4.929,4.558
|
||||
96.004832,-218.967894,4.924,4.556
|
||||
96.965993,-223.874674,4.919,4.555
|
||||
97.909081,-228.784371,4.914,4.553
|
||||
98.839976,-233.695981,4.909,4.551
|
||||
99.764556,-238.608499,4.904,4.550
|
||||
100.688701,-243.520920,4.898,4.548
|
||||
101.618197,-248.432257,4.893,4.546
|
||||
102.555794,-253.342056,4.888,4.545
|
||||
103.500606,-258.250500,4.883,4.543
|
||||
104.451536,-263.157814,4.878,4.542
|
||||
105.407485,-268.064218,4.873,4.540
|
||||
106.367355,-272.969935,4.868,4.538
|
||||
107.330048,-277.875186,4.862,4.537
|
||||
108.294464,-282.780196,4.857,4.535
|
||||
109.259505,-287.685184,4.852,4.534
|
||||
110.224074,-292.590374,4.847,4.532
|
||||
111.187071,-297.495988,4.842,4.530
|
||||
112.147399,-302.402248,4.837,4.529
|
||||
113.103958,-307.309376,4.832,4.527
|
||||
114.055651,-312.217594,4.826,4.525
|
||||
115.001615,-317.127073,4.821,4.524
|
||||
115.942575,-322.037631,4.816,4.522
|
||||
116.879915,-326.948942,4.811,4.521
|
||||
117.815019,-331.860680,4.806,4.519
|
||||
118.749270,-336.772517,4.801,4.517
|
||||
119.684054,-341.684127,4.795,4.516
|
||||
120.620755,-346.595184,4.790,4.514
|
||||
121.560757,-351.505360,4.785,4.512
|
||||
122.505444,-356.414329,4.780,4.511
|
||||
123.456202,-361.321764,4.775,4.509
|
||||
124.414414,-366.227339,4.770,4.508
|
||||
125.381466,-371.130726,4.765,4.506
|
||||
126.358740,-376.031599,4.759,4.504
|
||||
127.347598,-380.929639,4.754,4.503
|
||||
128.345619,-385.825549,4.749,4.501
|
||||
129.342556,-390.722158,4.744,4.499
|
||||
130.327190,-395.622556,4.739,4.498
|
||||
131.288302,-400.529834,4.734,4.496
|
||||
132.214673,-405.447083,4.729,4.495
|
||||
133.095083,-410.377394,4.683,4.590
|
||||
133.917404,-415.323672,4.623,4.720
|
||||
134.638923,-420.282615,4.457,4.923
|
||||
135.179778,-425.243373,4.219,5.176
|
||||
135.457865,-430.194646,4.345,5.035
|
||||
135.391083,-435.125129,4.520,4.798
|
||||
134.897330,-440.023522,4.740,4.485
|
||||
133.894503,-444.878522,4.971,4.557
|
||||
132.336811,-449.670650,5.116,4.317
|
||||
130.312854,-454.350171,4.238,4.713
|
||||
127.942320,-458.860348,4.493,4.717
|
||||
125.341900,-463.144788,4.832,4.446
|
||||
122.528502,-467.158487,4.407,5.135
|
||||
119.398290,-470.870226,4.540,5.028
|
||||
115.840666,-474.249571,4.692,4.847
|
||||
111.815858,-477.260106,4.796,4.742
|
||||
107.429983,-479.853095,4.993,4.883
|
||||
102.807143,-481.978282,5.144,4.671
|
||||
98.066603,-483.592601,4.997,4.496
|
||||
93.262909,-484.749189,4.346,5.074
|
||||
88.404440,-485.569807,4.216,5.375
|
||||
83.498594,-486.176411,4.600,5.017
|
||||
78.553298,-486.648841,4.913,4.723
|
||||
73.577110,-487.016376,4.873,4.744
|
||||
68.578624,-487.305298,4.832,4.766
|
||||
63.566436,-487.541894,4.792,4.787
|
||||
58.549142,-487.752447,4.752,4.809
|
||||
53.535335,-487.963242,4.712,4.830
|
||||
48.533082,-488.198747,4.671,4.852
|
||||
43.543349,-488.459106,4.631,4.874
|
||||
38.562040,-488.727119,4.591,4.895
|
||||
33.584950,-488.985207,4.550,4.917
|
||||
28.607876,-489.215796,4.510,4.938
|
||||
23.626611,-489.401309,4.494,4.943
|
||||
18.636952,-489.524170,4.592,4.871
|
||||
13.635726,-489.567169,4.690,4.799
|
||||
8.626745,-489.515580,4.791,4.707
|
||||
3.616713,-489.355702,4.905,4.545
|
||||
-1.387655,-489.073840,4.987,4.419
|
||||
-6.379646,-488.656298,4.833,4.555
|
||||
-11.352545,-488.089378,4.681,4.685
|
||||
-16.299639,-487.359387,4.536,4.799
|
||||
-21.214299,-486.455141,4.463,4.853
|
||||
-26.090210,-485.374739,4.576,4.755
|
||||
-30.921130,-484.118421,4.582,4.768
|
||||
-35.700815,-482.686423,4.522,4.848
|
||||
-40.423024,-481.078986,4.498,4.905
|
||||
-45.081514,-479.296347,4.487,4.948
|
||||
-49.670044,-477.338752,4.568,4.879
|
||||
-54.182501,-475.207651,4.658,4.797
|
||||
-58.613044,-472.906981,4.765,4.683
|
||||
-62.955864,-470.440990,4.830,4.597
|
||||
-67.205151,-467.813926,4.720,4.624
|
||||
-71.355097,-465.030037,4.629,4.657
|
||||
-75.399894,-462.093570,4.584,4.703
|
||||
-79.333732,-459.008773,4.692,4.591
|
||||
-83.150802,-455.779894,4.790,4.495
|
||||
-86.845296,-452.411181,4.700,4.618
|
||||
-90.411405,-448.906882,4.501,4.828
|
||||
-93.843320,-445.271244,4.212,5.105
|
||||
-97.135232,-441.508515,4.502,4.728
|
||||
-100.281332,-437.622943,4.692,4.503
|
||||
-103.276256,-433.619225,4.728,4.508
|
||||
-106.116287,-429.503720,4.668,4.614
|
||||
-108.798092,-425.283176,4.513,4.820
|
||||
-111.318336,-420.964340,4.574,4.784
|
||||
-113.673685,-416.553957,4.674,4.702
|
||||
-115.860805,-412.058774,4.708,4.695
|
||||
-117.876362,-407.485538,4.717,4.717
|
||||
-119.717022,-402.840995,4.673,4.745
|
||||
-121.379450,-398.131892,4.621,4.775
|
||||
-122.860313,-393.364976,4.599,4.922
|
||||
-124.156277,-388.546993,4.577,5.032
|
||||
-125.264006,-383.684690,4.597,5.061
|
||||
-126.180169,-378.784813,4.804,4.887
|
||||
-126.901541,-373.854095,4.655,4.719
|
||||
-127.428676,-368.898797,4.516,4.593
|
||||
-127.766739,-363.924608,4.611,4.602
|
||||
-127.921173,-358.937177,4.759,4.548
|
||||
-127.897419,-353.942159,4.812,4.530
|
||||
-127.700923,-348.945204,4.747,4.569
|
||||
-127.337126,-343.951966,4.658,4.569
|
||||
-126.811472,-338.968095,4.573,4.609
|
||||
-126.129405,-333.999244,4.504,4.716
|
||||
-125.296367,-329.051065,4.458,4.741
|
||||
-124.317801,-324.129210,4.449,4.630
|
||||
-123.199151,-319.239331,4.425,4.558
|
||||
-121.945861,-314.387080,4.321,4.705
|
||||
-120.563372,-309.578109,4.473,4.754
|
||||
-119.058509,-304.816715,4.680,4.769
|
||||
-117.447588,-300.097872,4.829,4.771
|
||||
-115.750915,-295.412637,4.896,4.761
|
||||
-113.988811,-290.752052,4.861,4.736
|
||||
-112.181595,-286.107159,4.826,4.711
|
||||
-110.349589,-281.469002,4.791,4.686
|
||||
-108.513113,-276.828622,4.777,4.683
|
||||
-106.688459,-272.178978,4.764,4.680
|
||||
-104.876827,-267.520207,4.750,4.677
|
||||
-103.075877,-262.854130,4.737,4.675
|
||||
-101.283269,-258.182568,4.724,4.672
|
||||
-99.496665,-253.507342,4.711,4.669
|
||||
-97.713725,-248.830270,4.697,4.667
|
||||
-95.932114,-244.153172,4.684,4.664
|
||||
-94.150161,-239.477307,4.671,4.662
|
||||
-92.367593,-234.802761,4.658,4.659
|
||||
-90.584313,-230.129473,4.645,4.656
|
||||
-88.800227,-225.457379,4.631,4.654
|
||||
-87.015237,-220.786419,4.618,4.651
|
||||
-85.229248,-216.116530,4.605,4.648
|
||||
-83.442165,-211.447649,4.592,4.646
|
||||
-81.653892,-206.779715,4.578,4.643
|
||||
-79.864331,-202.112665,4.565,4.640
|
||||
-78.073389,-197.446438,4.552,4.638
|
||||
-76.280968,-192.780971,4.539,4.635
|
||||
-74.486973,-188.116201,4.526,4.632
|
||||
-72.691308,-183.452068,4.512,4.630
|
||||
-70.893901,-178.788517,4.499,4.627
|
||||
-69.094771,-174.125528,4.486,4.624
|
||||
-67.293958,-169.463089,4.473,4.622
|
||||
-65.491502,-164.801187,4.459,4.619
|
||||
-63.687444,-160.139812,4.446,4.617
|
||||
-61.881823,-155.478949,4.433,4.614
|
||||
-60.074681,-150.818588,4.420,4.611
|
||||
-58.266057,-146.158715,4.407,4.609
|
||||
-56.455991,-141.499319,4.393,4.606
|
||||
-54.644524,-136.840387,4.380,4.603
|
||||
-52.831697,-132.181907,4.367,4.601
|
||||
-51.017548,-127.523866,4.392,4.625
|
||||
-49.202119,-122.866254,4.417,4.649
|
||||
-47.385450,-118.209056,4.443,4.672
|
||||
-45.567581,-113.552261,4.468,4.696
|
||||
-43.748552,-108.895857,4.493,4.720
|
||||
-41.928403,-104.239831,4.518,4.744
|
||||
-40.107175,-99.584172,4.544,4.768
|
||||
-38.284908,-94.928866,4.569,4.792
|
||||
-36.461642,-90.273902,4.594,4.816
|
||||
-34.637418,-85.619267,4.619,4.840
|
||||
-32.812275,-80.964950,4.645,4.864
|
||||
-30.986254,-76.310937,4.670,4.888
|
||||
-29.159396,-71.657217,4.695,4.912
|
||||
-27.331740,-67.003778,4.720,4.936
|
||||
-25.503326,-62.350606,4.746,4.960
|
||||
-23.674195,-57.697691,4.771,4.984
|
||||
-21.844388,-53.045019,4.796,5.008
|
||||
-20.013943,-48.392578,4.821,5.032
|
||||
-18.182903,-43.740356,4.847,5.055
|
||||
-16.351306,-39.088341,4.872,5.079
|
||||
-14.519193,-34.436521,4.897,5.103
|
||||
-12.686605,-29.784883,4.923,5.127
|
||||
-10.853581,-25.133415,4.948,5.151
|
||||
-9.020162,-20.482105,4.973,5.175
|
||||
-7.186388,-15.830941,4.998,5.199
|
||||
-5.352300,-11.179909,5.024,5.223
|
||||
-3.517937,-6.528999,5.049,5.247
|
|
25
src/JoltPhysics/Assets/Shaders/FontPixelShader.hlsl
Normal file
@ -0,0 +1,25 @@
|
||||
Texture2D ShaderTexture : register(t2);
|
||||
SamplerState SampleType : register(s0);
|
||||
|
||||
struct PS_INPUT
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float2 Tex : TEXCOORD0;
|
||||
float4 Color : COLOR0;
|
||||
};
|
||||
|
||||
struct PS_OUTPUT
|
||||
{
|
||||
float4 RGBColor : SV_TARGET;
|
||||
};
|
||||
|
||||
PS_OUTPUT main(PS_INPUT In)
|
||||
{
|
||||
PS_OUTPUT Output;
|
||||
|
||||
float t = ShaderTexture.Sample(SampleType, In.Tex).r;
|
||||
|
||||
Output.RGBColor = float4(In.Color.rgb, t);
|
||||
|
||||
return Output;
|
||||
}
|
35
src/JoltPhysics/Assets/Shaders/FontVertexShader.hlsl
Normal file
@ -0,0 +1,35 @@
|
||||
#include "VertexConstants.h"
|
||||
|
||||
struct VS_INPUT
|
||||
{
|
||||
float3 vPos : POSITION;
|
||||
float2 vTex : TEXCOORD0;
|
||||
float4 vCol : COLOR;
|
||||
};
|
||||
|
||||
struct VS_OUTPUT
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float2 Tex : TEXCOORD0;
|
||||
float4 Color : COLOR0;
|
||||
};
|
||||
|
||||
VS_OUTPUT main(VS_INPUT input)
|
||||
{
|
||||
VS_OUTPUT Output;
|
||||
|
||||
float4 pos = float4(input.vPos, 1.0f);
|
||||
|
||||
// Transform the position from object space to homogeneous projection space
|
||||
pos = mul(View, pos);
|
||||
pos = mul(Projection, pos);
|
||||
Output.Position = pos;
|
||||
|
||||
// Output texture coordinates
|
||||
Output.Tex = input.vTex;
|
||||
|
||||
// Output color
|
||||
Output.Color = input.vCol;
|
||||
|
||||
return Output;
|
||||
}
|
19
src/JoltPhysics/Assets/Shaders/LinePixelShader.hlsl
Normal file
@ -0,0 +1,19 @@
|
||||
struct PS_INPUT
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float4 Color : COLOR0;
|
||||
};
|
||||
|
||||
struct PS_OUTPUT
|
||||
{
|
||||
float4 RGBColor : SV_TARGET;
|
||||
};
|
||||
|
||||
PS_OUTPUT main(PS_INPUT In)
|
||||
{
|
||||
PS_OUTPUT Output;
|
||||
|
||||
Output.RGBColor = In.Color;
|
||||
|
||||
return Output;
|
||||
}
|
30
src/JoltPhysics/Assets/Shaders/LineVertexShader.hlsl
Normal file
@ -0,0 +1,30 @@
|
||||
#include "VertexConstants.h"
|
||||
|
||||
struct VS_INPUT
|
||||
{
|
||||
float3 vPos : POSITION;
|
||||
float3 vColor : COLOR;
|
||||
};
|
||||
|
||||
struct VS_OUTPUT
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float4 Color : COLOR0;
|
||||
};
|
||||
|
||||
VS_OUTPUT main(VS_INPUT input)
|
||||
{
|
||||
VS_OUTPUT Output;
|
||||
|
||||
float4 pos = float4(input.vPos, 1.0f);
|
||||
|
||||
// Transform the position from object space to homogeneous projection space
|
||||
pos = mul(View, pos);
|
||||
pos = mul(Projection, pos);
|
||||
Output.Position = pos;
|
||||
|
||||
// Output color
|
||||
Output.Color = float4(input.vColor, 1.0f);
|
||||
|
||||
return Output;
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
// We only write depth, so this shader does nothing
|
||||
void main()
|
||||
{
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
#include "VertexConstants.h"
|
||||
|
||||
struct VS_INPUT
|
||||
{
|
||||
// Per vertex data
|
||||
float3 vPos : POSITION;
|
||||
float3 vNorm : NORMAL;
|
||||
float2 vTex : TEXCOORD0;
|
||||
float4 vCol : COLOR;
|
||||
|
||||
// Per instance data
|
||||
matrix iModel : INSTANCE_TRANSFORM; // model matrix
|
||||
matrix iModelInvTrans : INSTANCE_INV_TRANSFORM; // (model matrix^-1)^T
|
||||
float4 iCol : INSTANCE_COLOR; // color of the model
|
||||
};
|
||||
|
||||
struct VS_OUTPUT
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
};
|
||||
|
||||
VS_OUTPUT main(VS_INPUT input)
|
||||
{
|
||||
VS_OUTPUT output;
|
||||
|
||||
// Check if the alpha = 0
|
||||
if (input.vCol.a * input.iCol.a == 0.0)
|
||||
{
|
||||
// Don't draw the triangle by moving it to an invalid location
|
||||
output.Position = float4(0, 0, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Transform the position from world space to homogeneous projection space for the light
|
||||
float4 pos = float4(input.vPos, 1.0f);
|
||||
pos = mul(input.iModel, pos);
|
||||
pos = mul(LightView, pos);
|
||||
pos = mul(LightProjection, pos);
|
||||
output.Position = pos;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
121
src/JoltPhysics/Assets/Shaders/TrianglePixelShader.hlsl
Normal file
@ -0,0 +1,121 @@
|
||||
// Shader that uses a shadow map for rendering shadows, see:
|
||||
// http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-16-shadow-mapping/
|
||||
// https://takinginitiative.wordpress.com/2011/05/25/directx10-tutorial-10-shadow-mapping-part-2/
|
||||
|
||||
Texture2D LightDepthTexture : register(t2);
|
||||
SamplerComparisonState LightDepthSampler : register(s2);
|
||||
|
||||
cbuffer PixelShaderConstantBuffer : register(b1)
|
||||
{
|
||||
float3 CameraPos;
|
||||
float3 LightPos;
|
||||
};
|
||||
|
||||
struct PS_INPUT
|
||||
{
|
||||
float4 Position : SV_POSITION; // interpolated vertex position
|
||||
float3 Normal : TEXCOORD0;
|
||||
float3 WorldPos : TEXCOORD1;
|
||||
float2 Tex : TEXCOORD2;
|
||||
float4 PositionL : TEXCOORD3; // interpolated vertex position in light space
|
||||
float4 Color : COLOR0;
|
||||
};
|
||||
|
||||
struct PS_OUTPUT
|
||||
{
|
||||
float4 RGBColor : SV_TARGET;
|
||||
};
|
||||
|
||||
PS_OUTPUT main(PS_INPUT input)
|
||||
{
|
||||
// Constants
|
||||
float AmbientFactor = 0.3;
|
||||
float3 DiffuseColor = float3(input.Color.r, input.Color.g, input.Color.b);
|
||||
float3 SpecularColor = float3(1, 1, 1);
|
||||
float SpecularPower = 100.0;
|
||||
float bias = 1.0e-7;
|
||||
|
||||
// Homogenize position in light space
|
||||
input.PositionL.xyz /= input.PositionL.w;
|
||||
|
||||
// Calculate dot product between direction to light and surface normal and clamp between [0, 1]
|
||||
float3 view_dir = normalize(CameraPos - input.WorldPos);
|
||||
float3 world_to_light = LightPos - input.WorldPos;
|
||||
float3 light_dir = normalize(world_to_light);
|
||||
float3 normal = normalize(input.Normal);
|
||||
if (dot(view_dir, normal) < 0) // If we're viewing the triangle from the back side, flip the normal to get the correct lighting
|
||||
normal = -normal;
|
||||
float normal_dot_light_dir = saturate(dot(normal, light_dir));
|
||||
|
||||
// Calculate texture coordinates in light depth texture
|
||||
float2 tex_coord;
|
||||
tex_coord.x = input.PositionL.x / 2.0 + 0.5;
|
||||
tex_coord.y = -input.PositionL.y / 2.0 + 0.5;
|
||||
|
||||
// Check that the texture coordinate is inside the depth texture, if not we don't know if it is lit or not so we assume lit
|
||||
float shadow_factor = 1.0;
|
||||
if (input.Color.a > 0 // Alpha = 0 means don't receive shadows
|
||||
&& tex_coord.x == saturate(tex_coord.x) && tex_coord.y == saturate(tex_coord.y))
|
||||
{
|
||||
// Modify shadow bias according to the angle between the normal and the light dir
|
||||
float modified_bias = bias * tan(acos(normal_dot_light_dir));
|
||||
modified_bias = min(modified_bias, 10.0 * bias);
|
||||
|
||||
// Get texture size
|
||||
float width, height, levels;
|
||||
LightDepthTexture.GetDimensions(0, width, height, levels);
|
||||
width = 1.0 / width;
|
||||
height = 1.0 / height;
|
||||
|
||||
// Samples to take
|
||||
uint num_samples = 16;
|
||||
float2 offsets[] = {
|
||||
float2(-1.5 * width, -1.5 * height),
|
||||
float2(-0.5 * width, -1.5 * height),
|
||||
float2(0.5 * width, -1.5 * height),
|
||||
float2(1.5 * width, -1.5 * height),
|
||||
|
||||
float2(-1.5 * width, -0.5 * height),
|
||||
float2(-0.5 * width, -0.5 * height),
|
||||
float2(0.5 * width, -0.5 * height),
|
||||
float2(1.5 * width, -0.5 * height),
|
||||
|
||||
float2(-1.5 * width, 0.5 * height),
|
||||
float2(-0.5 * width, 0.5 * height),
|
||||
float2(0.5 * width, 0.5 * height),
|
||||
float2(1.5 * width, 0.5 * height),
|
||||
|
||||
float2(-1.5 * width, 1.5 * height),
|
||||
float2(-0.5 * width, 1.5 * height),
|
||||
float2(0.5 * width, 1.5 * height),
|
||||
float2(1.5 * width, 1.5 * height),
|
||||
};
|
||||
|
||||
// Calculate depth of this pixel relative to the light
|
||||
float light_depth = input.PositionL.z + modified_bias;
|
||||
|
||||
// Sample shadow factor
|
||||
shadow_factor = 0.0;
|
||||
[unroll] for (uint i = 0; i < num_samples; ++i)
|
||||
shadow_factor += LightDepthTexture.SampleCmp(LightDepthSampler, tex_coord + offsets[i], light_depth);
|
||||
shadow_factor /= num_samples;
|
||||
}
|
||||
|
||||
// Calculate diffuse and specular
|
||||
float diffuse = normal_dot_light_dir;
|
||||
float specular = diffuse > 0.0? pow(saturate(-dot(reflect(light_dir, normal), view_dir)), SpecularPower) : 0.0;
|
||||
|
||||
// Apply procedural pattern based on the uv coordinates
|
||||
bool2 less_half = input.Tex - floor(input.Tex) < float2(0.5, 0.5);
|
||||
float darken_factor = less_half.r ^ less_half.g? 0.5 : 1.0;
|
||||
|
||||
// Fade out checkerboard pattern when it tiles too often
|
||||
float2 dx = ddx(input.Tex), dy = ddy(input.Tex);
|
||||
float texel_distance = sqrt(dot(dx, dx) + dot(dy, dy));
|
||||
darken_factor = lerp(darken_factor, 0.75, clamp(5.0 * texel_distance - 1.5, 0.0, 1.0));
|
||||
|
||||
// Calculate color
|
||||
PS_OUTPUT output;
|
||||
output.RGBColor = float4(saturate((AmbientFactor + diffuse * shadow_factor) * darken_factor * DiffuseColor + SpecularColor * specular * shadow_factor), 1);
|
||||
return output;
|
||||
}
|
59
src/JoltPhysics/Assets/Shaders/TriangleVertexShader.hlsl
Normal file
@ -0,0 +1,59 @@
|
||||
#include "VertexConstants.h"
|
||||
|
||||
struct VS_INPUT
|
||||
{
|
||||
// Per vertex data
|
||||
float3 vPos : POSITION;
|
||||
float3 vNorm : NORMAL;
|
||||
float2 vTex : TEXCOORD0;
|
||||
float4 vCol : COLOR;
|
||||
|
||||
// Per instance data
|
||||
matrix iModel : INSTANCE_TRANSFORM; // model matrix
|
||||
matrix iModelInvTrans : INSTANCE_INV_TRANSFORM; // (model matrix^-1)^T
|
||||
float4 iCol : INSTANCE_COLOR; // color of the model
|
||||
};
|
||||
|
||||
struct VS_OUTPUT
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float3 Normal : TEXCOORD0;
|
||||
float3 WorldPos : TEXCOORD1;
|
||||
float2 Tex : TEXCOORD2;
|
||||
float4 PositionL : TEXCOORD3;
|
||||
float4 Color : COLOR0;
|
||||
};
|
||||
|
||||
VS_OUTPUT main(VS_INPUT input)
|
||||
{
|
||||
VS_OUTPUT output;
|
||||
|
||||
// Get world position
|
||||
float4 pos = float4(input.vPos, 1.0f);
|
||||
float4 world_pos = mul(input.iModel, pos);
|
||||
|
||||
// Transform the position from world space to homogeneous projection space
|
||||
float4 proj_pos = mul(View, world_pos);
|
||||
proj_pos = mul(Projection, proj_pos);
|
||||
output.Position = proj_pos;
|
||||
|
||||
// Transform the position from world space to projection space of the light
|
||||
float4 proj_lpos = mul(LightView, world_pos);
|
||||
proj_lpos = mul(LightProjection, proj_lpos);
|
||||
output.PositionL = proj_lpos;
|
||||
|
||||
// output normal
|
||||
float4 norm = float4(input.vNorm, 0.0f);
|
||||
output.Normal = normalize(mul(input.iModelInvTrans, norm).xyz);
|
||||
|
||||
// output world position of the vertex
|
||||
output.WorldPos = world_pos.xyz;
|
||||
|
||||
// output texture coordinates
|
||||
output.Tex = input.vTex;
|
||||
|
||||
// output color
|
||||
output.Color = input.vCol * input.iCol;
|
||||
|
||||
return output;
|
||||
}
|
23
src/JoltPhysics/Assets/Shaders/UIPixelShader.hlsl
Normal file
@ -0,0 +1,23 @@
|
||||
Texture2D ShaderTexture : register(t2);
|
||||
SamplerState SampleType : register(s1);
|
||||
|
||||
struct PS_INPUT
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float2 Tex : TEXCOORD0;
|
||||
float4 Color : COLOR0;
|
||||
};
|
||||
|
||||
struct PS_OUTPUT
|
||||
{
|
||||
float4 RGBColor : SV_TARGET;
|
||||
};
|
||||
|
||||
PS_OUTPUT main(PS_INPUT In)
|
||||
{
|
||||
PS_OUTPUT Output;
|
||||
|
||||
Output.RGBColor = In.Color * ShaderTexture.Sample(SampleType, In.Tex);
|
||||
|
||||
return Output;
|
||||
}
|
20
src/JoltPhysics/Assets/Shaders/UIPixelShaderUntextured.hlsl
Normal file
@ -0,0 +1,20 @@
|
||||
struct PS_INPUT
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float2 Tex : TEXCOORD0;
|
||||
float4 Color : COLOR0;
|
||||
};
|
||||
|
||||
struct PS_OUTPUT
|
||||
{
|
||||
float4 RGBColor : SV_TARGET;
|
||||
};
|
||||
|
||||
PS_OUTPUT main(PS_INPUT In)
|
||||
{
|
||||
PS_OUTPUT Output;
|
||||
|
||||
Output.RGBColor = In.Color;
|
||||
|
||||
return Output;
|
||||
}
|
34
src/JoltPhysics/Assets/Shaders/UIVertexShader.hlsl
Normal file
@ -0,0 +1,34 @@
|
||||
#include "VertexConstants.h"
|
||||
|
||||
struct VS_INPUT
|
||||
{
|
||||
float3 vPos : POSITION;
|
||||
float2 vTex : TEXCOORD0;
|
||||
float4 vCol : COLOR;
|
||||
};
|
||||
|
||||
struct VS_OUTPUT
|
||||
{
|
||||
float4 Position : SV_POSITION;
|
||||
float2 Tex : TEXCOORD0;
|
||||
float4 Color : COLOR0;
|
||||
};
|
||||
|
||||
VS_OUTPUT main(VS_INPUT input)
|
||||
{
|
||||
VS_OUTPUT Output;
|
||||
|
||||
float4 pos = float4(input.vPos, 1.0f);
|
||||
|
||||
// Transform the position from object space to ortho space
|
||||
pos = mul(Projection, pos);
|
||||
Output.Position = pos;
|
||||
|
||||
// Output texture coordinates
|
||||
Output.Tex = input.vTex;
|
||||
|
||||
// Output color
|
||||
Output.Color = input.vCol;
|
||||
|
||||
return Output;
|
||||
}
|
7
src/JoltPhysics/Assets/Shaders/VertexConstants.h
Normal file
@ -0,0 +1,7 @@
|
||||
cbuffer VertexShaderConstantBuffer : register(b0)
|
||||
{
|
||||
matrix View; // view matrix
|
||||
matrix Projection; // projection matrix
|
||||
matrix LightView; // view matrix of the light
|
||||
matrix LightProjection; // projection matrix of the light
|
||||
};
|
BIN
src/JoltPhysics/Assets/convex_hulls.bin
Normal file
BIN
src/JoltPhysics/Assets/heightfield1.bin
Normal file
BIN
src/JoltPhysics/Assets/terrain1.bof
Normal file
BIN
src/JoltPhysics/Assets/terrain2.bof
Normal file
BIN
src/JoltPhysics/Assets/ui.tga
Normal file
After Width: | Height: | Size: 64 KiB |
6
src/JoltPhysics/Build/.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
/Linux*
|
||||
/VS20*
|
||||
/XCode*
|
||||
/MinGW*
|
||||
/Doxygen
|
||||
/CoverageReport
|
5
src/JoltPhysics/Build/Android/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
.idea
|
||||
.gradle
|
||||
.cxx
|
||||
build
|
||||
local.properties
|
51
src/JoltPhysics/Build/Android/PerformanceTest/build.gradle
Normal file
@ -0,0 +1,51 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk 33
|
||||
ndkVersion "26.1.10909125"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.joltphysics.performancetest"
|
||||
minSdk 21
|
||||
targetSdk 33
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
ndk.abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86_64', 'x86'
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
cppFlags '-std=c++17 -Wall -Werror -ffp-model=precise -ffp-contract=off -DJPH_PROFILE_ENABLED -DJPH_DEBUG_RENDERER'
|
||||
arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=c++_static', '-DCROSS_PLATFORM_DETERMINISTIC=ON'
|
||||
}
|
||||
}
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path file('src/main/cpp/CMakeLists.txt')
|
||||
version '3.22.1'
|
||||
}
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
namespace 'com.joltphysics.performancetest'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:label="Jolt Physics Performance Test"
|
||||
android:supportsRtl="false"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
||||
<activity
|
||||
android:name="android.app.NativeActivity"
|
||||
android:exported="true">
|
||||
<meta-data android:name="android.app.lib_name" android:value="PerformanceTest"/>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.10.2)
|
||||
|
||||
project("JoltPhysicsPerformanceTest")
|
||||
|
||||
# Make sure we include the app glue sources
|
||||
set(APP_GLUE_DIR ${ANDROID_NDK}/sources/android/native_app_glue)
|
||||
include_directories(${APP_GLUE_DIR})
|
||||
|
||||
# Set repository root
|
||||
set(PHYSICS_REPO_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../")
|
||||
|
||||
# Make targets
|
||||
include(${PHYSICS_REPO_ROOT}/Jolt/Jolt.cmake)
|
||||
include(${PHYSICS_REPO_ROOT}/PerformanceTest/PerformanceTest.cmake)
|
||||
|
||||
# Link shared native library
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")
|
||||
add_library(PerformanceTest SHARED ${PERFORMANCE_TEST_SRC_FILES} ${APP_GLUE_DIR}/android_native_app_glue.c)
|
||||
target_include_directories(PerformanceTest PUBLIC Jolt ${JOLT_PHYSICS_ROOT} ${PERFORMANCE_TEST_ROOT})
|
||||
target_link_libraries(PerformanceTest Jolt android log)
|
51
src/JoltPhysics/Build/Android/UnitTests/build.gradle
Normal file
@ -0,0 +1,51 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdk 33
|
||||
ndkVersion "26.1.10909125"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.joltphysics.unittests"
|
||||
minSdk 21
|
||||
targetSdk 33
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
ndk.abiFilters 'arm64-v8a', 'armeabi-v7a', 'x86_64', 'x86'
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
cppFlags '-std=c++17 -Wall -Werror -ffp-contract=off -DJPH_PROFILE_ENABLED -DJPH_DEBUG_RENDERER'
|
||||
arguments '-DANDROID_TOOLCHAIN=clang', '-DANDROID_STL=c++_static'
|
||||
}
|
||||
}
|
||||
signingConfig signingConfigs.debug
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path file('src/main/cpp/CMakeLists.txt')
|
||||
version '3.22.1'
|
||||
}
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
namespace 'com.joltphysics.unittests'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:label="Jolt Physics Unit Tests"
|
||||
android:supportsRtl="false"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
|
||||
<activity
|
||||
android:name="android.app.NativeActivity"
|
||||
android:exported="true">
|
||||
<meta-data android:name="android.app.lib_name" android:value="UnitTests"/>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -0,0 +1,20 @@
|
||||
cmake_minimum_required(VERSION 3.10.2)
|
||||
|
||||
project("JoltPhysicsUnitTests")
|
||||
|
||||
# Make sure we include the app glue sources
|
||||
set(APP_GLUE_DIR ${ANDROID_NDK}/sources/android/native_app_glue)
|
||||
include_directories(${APP_GLUE_DIR})
|
||||
|
||||
# Set repository root
|
||||
set(PHYSICS_REPO_ROOT "${CMAKE_CURRENT_SOURCE_DIR}/../../../../../../")
|
||||
|
||||
# Make targets
|
||||
include(${PHYSICS_REPO_ROOT}/Jolt/Jolt.cmake)
|
||||
include(${PHYSICS_REPO_ROOT}/UnitTests/UnitTests.cmake)
|
||||
|
||||
# Link shared native library
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -u ANativeActivity_onCreate")
|
||||
add_library(UnitTests SHARED ${UNIT_TESTS_SRC_FILES} ${APP_GLUE_DIR}/android_native_app_glue.c)
|
||||
target_include_directories(UnitTests PUBLIC Jolt ${JOLT_PHYSICS_ROOT} ${UNIT_TESTS_ROOT})
|
||||
target_link_libraries(UnitTests Jolt android log)
|
17
src/JoltPhysics/Build/Android/build.gradle
Normal file
@ -0,0 +1,17 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
buildscript {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.1.2'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
22
src/JoltPhysics/Build/Android/gradle.properties
Normal file
@ -0,0 +1,22 @@
|
||||
# Project-wide Gradle settings.
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||
# Android operating system, and which are packaged with your app"s APK
|
||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||
android.useAndroidX=true
|
||||
# Automatically convert third-party libraries to use AndroidX
|
||||
android.enableJetifier=true
|
||||
android.defaults.buildfeatures.buildconfig=true
|
||||
android.nonTransitiveRClass=false
|
||||
android.nonFinalResIds=false
|
BIN
src/JoltPhysics/Build/Android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
5
src/JoltPhysics/Build/Android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
|
||||
distributionPath=wrapper/dists
|
||||
zipStorePath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
185
src/JoltPhysics/Build/Android/gradlew
vendored
Normal file
@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
89
src/JoltPhysics/Build/Android/gradlew.bat
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
10
src/JoltPhysics/Build/Android/settings.gradle
Normal file
@ -0,0 +1,10 @@
|
||||
dependencyResolutionManagement {
|
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
rootProject.name = "Jolt Physics"
|
||||
include ':UnitTests'
|
||||
include ':PerformanceTest'
|
319
src/JoltPhysics/Build/CMakeLists.txt
Normal file
@ -0,0 +1,319 @@
|
||||
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
|
||||
|
||||
project(JoltPhysics CXX)
|
||||
|
||||
# When turning this option on, the library will be compiled using doubles for positions. This allows for much bigger worlds.
|
||||
option(DOUBLE_PRECISION "Use double precision math" OFF)
|
||||
|
||||
# When turning this option on, the library will be compiled with debug symbols
|
||||
option(GENERATE_DEBUG_SYMBOLS "Generate debug symbols" ON)
|
||||
|
||||
# When turning this option on, the library will override the default CMAKE_CXX_FLAGS_DEBUG/RELEASE values, otherwise they will use the platform defaults
|
||||
option(OVERRIDE_CXX_FLAGS "Override CMAKE_CXX_FLAGS_DEBUG/RELEASE" ON)
|
||||
|
||||
# When turning this option on, the library will be compiled in such a way to attempt to keep the simulation deterministic across platforms
|
||||
option(CROSS_PLATFORM_DETERMINISTIC "Cross platform deterministic" OFF)
|
||||
|
||||
# When turning this option on, the library will be compiled for ARM (aarch64-linux-gnu), requires compiling with clang
|
||||
option(CROSS_COMPILE_ARM "Cross compile to aarch64-linux-gnu" OFF)
|
||||
|
||||
# When turning this option on, Jolt will be compiled as a shared library and public symbols will be exported.
|
||||
option(BUILD_SHARED_LIBS "Compile Jolt as a shared library" OFF)
|
||||
|
||||
# When turning this option on, the library will be compiled with interprocedural optimizations enabled, also known as link-time optimizations or link-time code generation.
|
||||
# Note that if you turn this on you need to use SET_INTERPROCEDURAL_OPTIMIZATION() or set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) to enable LTO specifically for your own project as well.
|
||||
# If you don't do this you may get an error: /usr/bin/ld: libJolt.a: error adding symbols: file format not recognized
|
||||
option(INTERPROCEDURAL_OPTIMIZATION "Enable interprocedural optimizations" ON)
|
||||
|
||||
# When turning this on, in Debug and Release mode, the library will emit extra code to ensure that the 4th component of a 3-vector is kept the same as the 3rd component
|
||||
# and will enable floating point exceptions during simulation to detect divisions by zero.
|
||||
# Note that this currently only works using MSVC. Clang turns Float2 into a SIMD vector sometimes causing floating point exceptions (the option is ignored).
|
||||
option(FLOATING_POINT_EXCEPTIONS_ENABLED "Enable floating point exceptions" ON)
|
||||
|
||||
# Number of bits to use in ObjectLayer. Can be 16 or 32.
|
||||
option(OBJECT_LAYER_BITS "Number of bits in ObjectLayer" 16)
|
||||
|
||||
# Select X86 processor features to use (if everything is off it will be SSE2 compatible)
|
||||
option(USE_SSE4_1 "Enable SSE4.1" ON)
|
||||
option(USE_SSE4_2 "Enable SSE4.2" ON)
|
||||
option(USE_AVX "Enable AVX" ON)
|
||||
option(USE_AVX2 "Enable AVX2" ON)
|
||||
option(USE_AVX512 "Enable AVX512" OFF)
|
||||
option(USE_LZCNT "Enable LZCNT" ON)
|
||||
option(USE_TZCNT "Enable TZCNT" ON)
|
||||
option(USE_F16C "Enable F16C" ON)
|
||||
option(USE_FMADD "Enable FMADD" ON)
|
||||
|
||||
# Enable all warnings
|
||||
option(ENABLE_ALL_WARNINGS "Enable all warnings and warnings as errors" ON)
|
||||
|
||||
# Setting to periodically trace broadphase stats to help determine if the broadphase layer configuration is optimal
|
||||
option(TRACK_BROADPHASE_STATS "Track Broadphase Stats" OFF)
|
||||
|
||||
# Setting to periodically trace narrowphase stats to help determine which collision queries could be optimized
|
||||
option(TRACK_NARROWPHASE_STATS "Track Narrowphase Stats" OFF)
|
||||
|
||||
# Enable the debug renderer in the Debug and Release builds. Note that DEBUG_RENDERER_IN_DISTRIBUTION will override this setting.
|
||||
option(DEBUG_RENDERER_IN_DEBUG_AND_RELEASE "Enable debug renderer in Debug and Release builds" ON)
|
||||
|
||||
# Setting to enable the debug renderer in all builds.
|
||||
# Note that enabling this reduces the performance of the library even if you're not drawing anything.
|
||||
option(DEBUG_RENDERER_IN_DISTRIBUTION "Enable debug renderer in all builds" OFF)
|
||||
|
||||
# Enable the profiler in Debug and Release builds. Note that PROFILER_IN_DISTRIBUTION will override this setting.
|
||||
option(PROFILER_IN_DEBUG_AND_RELEASE "Enable the profiler in Debug and Release builds" ON)
|
||||
|
||||
# Enable the profiler in all builds.
|
||||
# Note that enabling this reduces the performance of the library.
|
||||
option(PROFILER_IN_DISTRIBUTION "Enable the profiler in all builds" OFF)
|
||||
|
||||
# Setting this option will force the library to use malloc/free instead of allowing the user to override the memory allocator
|
||||
option(DISABLE_CUSTOM_ALLOCATOR "Disable support for a custom memory allocator" OFF)
|
||||
|
||||
include(CMakeDependentOption)
|
||||
|
||||
# Ability to toggle between the static and DLL versions of the MSVC runtime library
|
||||
# Windows Store only supports the DLL version
|
||||
cmake_dependent_option(USE_STATIC_MSVC_RUNTIME_LIBRARY "Use the static MSVC runtime library" ON "MSVC;NOT WINDOWS_STORE" OFF)
|
||||
|
||||
# Determine which configurations exist
|
||||
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) # Only do this when we're at the top level, see: https://gitlab.kitware.com/cmake/cmake/-/issues/24181
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
set(CMAKE_CONFIGURATION_TYPES "Debug;Release;Distribution")
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
|
||||
set(CMAKE_CONFIGURATION_TYPES "Debug;Release;ReleaseASAN;ReleaseUBSAN;ReleaseCoverage;Distribution")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (MSVC)
|
||||
# Fill in the path to the asan libraries
|
||||
set(CLANG_LIB_PATH "\"$(VSInstallDir)\\VC\\Tools\\Llvm\\x64\\lib\\clang\\${CMAKE_CXX_COMPILER_VERSION}\\lib\\windows\"")
|
||||
|
||||
# 64 bit architecture
|
||||
set(CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE "x64")
|
||||
|
||||
# Set runtime library
|
||||
if (USE_STATIC_MSVC_RUNTIME_LIBRARY)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
endif()
|
||||
|
||||
# Set general compiler flags
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zc:__cplusplus /Gm- /MP /nologo /diagnostics:classic /FC /fp:except- /Zc:inline")
|
||||
|
||||
# Enable warnings
|
||||
if (ENABLE_ALL_WARNINGS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Wall /WX")
|
||||
endif()
|
||||
|
||||
# Optionally generate debug symbols
|
||||
if (GENERATE_DEBUG_SYMBOLS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Zi")
|
||||
endif()
|
||||
|
||||
# Remove any existing compiler flag that enables RTTI
|
||||
string(REPLACE "/GR" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
||||
|
||||
# Set compiler flag for disabling RTTI
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-")
|
||||
|
||||
if ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "ARM")
|
||||
# On ARM the exception handling flag is missing which causes warnings
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
|
||||
endif()
|
||||
|
||||
# Set compiler flags for various configurations
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "/GS /Od /Ob0 /RTC1")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "/GS- /Gy /O2 /Oi /Ot")
|
||||
set(CMAKE_CXX_FLAGS_DISTRIBUTION "/GS- /Gy /O2 /Oi /Ot")
|
||||
set(CMAKE_CXX_FLAGS_RELEASEASAN "-fsanitize=address /Od")
|
||||
set(CMAKE_CXX_FLAGS_RELEASEUBSAN "-fsanitize=undefined,implicit-conversion,float-divide-by-zero,local-bounds -fno-sanitize-recover=all")
|
||||
set(CMAKE_CXX_FLAGS_RELEASECOVERAGE "-fprofile-instr-generate -fcoverage-mapping")
|
||||
|
||||
# Set linker flags
|
||||
set(CMAKE_EXE_LINKER_FLAGS "/SUBSYSTEM:WINDOWS /ignore:4221")
|
||||
if (GENERATE_DEBUG_SYMBOLS)
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /DEBUG")
|
||||
endif()
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
|
||||
if (CROSS_PLATFORM_DETERMINISTIC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:precise")
|
||||
else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:fast") # Clang doesn't use fast math because it cannot be turned off inside a single compilation unit
|
||||
endif()
|
||||
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /showFilenames")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Qunused-arguments") # Clang emits warnings about unused arguments such as /MP and /GL
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASEASAN "/SUBSYSTEM:CONSOLE /LIBPATH:${CLANG_LIB_PATH} clang_rt.asan-x86_64.lib -wholearchive:clang_rt.asan-x86_64.lib clang_rt.asan_cxx-x86_64.lib -wholearchive:clang_rt.asan_cxx-x86_64.lib")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASEUBSAN "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LIBPATH:${CLANG_LIB_PATH}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASECOVERAGE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LIBPATH:${CLANG_LIB_PATH}")
|
||||
endif()
|
||||
else()
|
||||
# Enable warnings
|
||||
if (ENABLE_ALL_WARNINGS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror")
|
||||
endif()
|
||||
|
||||
# Optionally generate debug symbols
|
||||
if (GENERATE_DEBUG_SYMBOLS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
|
||||
endif()
|
||||
|
||||
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
|
||||
# Also disable -Wstringop-overflow or it will generate false positives that can't be disabled from code when link-time optimizations are enabled
|
||||
# Also turn off automatic fused multiply add contractions, there doesn't seem to be a way to do this selectively through the macro JPH_PRECISE_MATH_OFF
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-stringop-overflow -ffp-contract=off")
|
||||
else()
|
||||
# Do not use -ffast-math since it cannot be turned off in a single compilation unit under clang, see Core.h
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffp-model=precise")
|
||||
|
||||
# On clang 14 and later we can turn off float contraction through a pragma, older versions and deterministic versions need it off always, see Core.h
|
||||
if (CMAKE_CXX_COMPILER_VERSION LESS 14 OR CROSS_PLATFORM_DETERMINISTIC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffp-contract=off")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# See https://github.com/jrouwe/JoltPhysics/issues/922. When compiling with DOUBLE_PRECISION=YES and CMAKE_OSX_DEPLOYMENT_TARGET=10.12 clang triggers a warning that we silence here.
|
||||
if ("${CMAKE_SYSTEM_NAME}" MATCHES "Darwin" AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -faligned-allocation")
|
||||
endif()
|
||||
|
||||
# Cross compiler flags
|
||||
if (CROSS_COMPILE_ARM)
|
||||
set(CMAKE_CXX_FLAGS "--target=aarch64-linux-gnu ${CMAKE_CXX_FLAGS}")
|
||||
endif()
|
||||
|
||||
# Set compiler flags for various configurations
|
||||
if (OVERRIDE_CXX_FLAGS)
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS_DISTRIBUTION "${CMAKE_CXX_FLAGS_RELEASE}")
|
||||
set(CMAKE_CXX_FLAGS_RELEASEASAN "-fsanitize=address")
|
||||
set(CMAKE_CXX_FLAGS_RELEASEUBSAN "-fsanitize=undefined,implicit-conversion,float-divide-by-zero,local-bounds -fno-sanitize-recover=all")
|
||||
set(CMAKE_CXX_FLAGS_RELEASECOVERAGE "-O0 -DJPH_NO_FORCE_INLINE -fprofile-instr-generate -fcoverage-mapping")
|
||||
|
||||
# Set linker flags
|
||||
if (NOT ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows"))
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -pthread")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Set linker flags
|
||||
set(CMAKE_EXE_LINKER_FLAGS_DISTRIBUTION "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
|
||||
|
||||
# Enable link time optimization in Release and Distribution mode if requested and available
|
||||
function(SET_INTERPROCEDURAL_OPTIMIZATION)
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE OFF PARENT_SCOPE)
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_DISTRIBUTION OFF PARENT_SCOPE)
|
||||
|
||||
# On ARM, whole program optimization triggers an internal compiler error during code gen, so we don't turn it on
|
||||
if (INTERPROCEDURAL_OPTIMIZATION AND NOT ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "ARM64") AND NOT ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "ARM"))
|
||||
include(CheckIPOSupported)
|
||||
check_ipo_supported(RESULT IS_IPO_SUPPORTED OUTPUT IPO_CHECK_OUTPUT)
|
||||
|
||||
if (IS_IPO_SUPPORTED)
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE ON PARENT_SCOPE)
|
||||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_DISTRIBUTION ON PARENT_SCOPE)
|
||||
else()
|
||||
message(WARNING "Interprocedural optimizations are not supported: ${IPO_CHECK_OUTPUT}")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
SET_INTERPROCEDURAL_OPTIMIZATION()
|
||||
|
||||
# Set repository root
|
||||
set(PHYSICS_REPO_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/../)
|
||||
|
||||
# Make Jolt Library
|
||||
include(${PHYSICS_REPO_ROOT}/Jolt/Jolt.cmake)
|
||||
if (XCODE)
|
||||
# Ensure that we enable SSE4.2 for the x86_64 build, XCode builds multiple architectures
|
||||
set_property(TARGET Jolt PROPERTY XCODE_ATTRIBUTE_OTHER_CPLUSPLUSFLAGS[arch=x86_64] "$(inherited) -msse4.2 -mpopcnt")
|
||||
endif()
|
||||
|
||||
# Install Jolt library and includes
|
||||
install(TARGETS Jolt DESTINATION lib)
|
||||
foreach(SRC_FILE ${JOLT_PHYSICS_SRC_FILES})
|
||||
string(REPLACE ${PHYSICS_REPO_ROOT} "" RELATIVE_SRC_FILE ${SRC_FILE})
|
||||
get_filename_component(DESTINATION_PATH ${RELATIVE_SRC_FILE} DIRECTORY)
|
||||
if (NOT RELATIVE_SRC_FILE MATCHES "\.cpp")
|
||||
install(FILES ${SRC_FILE} DESTINATION include/${DESTINATION_PATH})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# Check if we're the root CMakeLists.txt, if not we are included by another CMake file and we should disable everything except for the main library
|
||||
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
# Ability to turn ON/OFF individual applications
|
||||
option(TARGET_UNIT_TESTS "Build Unit Tests" ON)
|
||||
option(TARGET_HELLO_WORLD "Build Hello World" ON)
|
||||
option(TARGET_PERFORMANCE_TEST "Build Performance Test" ON)
|
||||
option(TARGET_SAMPLES "Build Samples" ON)
|
||||
option(TARGET_VIEWER "Build JoltViewer" ON)
|
||||
|
||||
if (TARGET_UNIT_TESTS)
|
||||
# Create UnitTests executable
|
||||
include(${PHYSICS_REPO_ROOT}/UnitTests/UnitTests.cmake)
|
||||
add_executable(UnitTests ${UNIT_TESTS_SRC_FILES})
|
||||
target_include_directories(UnitTests PUBLIC ${UNIT_TESTS_ROOT})
|
||||
target_link_libraries(UnitTests LINK_PUBLIC Jolt)
|
||||
target_precompile_headers(UnitTests PRIVATE ${JOLT_PHYSICS_ROOT}/Jolt.h)
|
||||
if (MSVC)
|
||||
target_link_options(UnitTests PUBLIC "/SUBSYSTEM:CONSOLE")
|
||||
endif()
|
||||
if (IOS)
|
||||
# Set the bundle information
|
||||
set_property(TARGET UnitTests PROPERTY MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/iOS/UnitTestsInfo.plist")
|
||||
set_property(TARGET UnitTests PROPERTY XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "com.joltphysics.unittests")
|
||||
endif()
|
||||
if (XCODE)
|
||||
# Ensure that we enable SSE4.2 for the x86_64 build, XCode builds multiple architectures
|
||||
set_property(TARGET UnitTests PROPERTY XCODE_ATTRIBUTE_OTHER_CPLUSPLUSFLAGS[arch=x86_64] "$(inherited) -msse4.2 -mpopcnt")
|
||||
endif()
|
||||
|
||||
# Register unit tests as a test so that it can be run with:
|
||||
# ctest --output-on-failure
|
||||
enable_testing()
|
||||
add_test(UnitTests UnitTests)
|
||||
endif()
|
||||
|
||||
if (NOT "${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsStore")
|
||||
if (TARGET_HELLO_WORLD)
|
||||
# Example 'Hello World' application
|
||||
include(${PHYSICS_REPO_ROOT}/HelloWorld/HelloWorld.cmake)
|
||||
add_executable(HelloWorld ${HELLO_WORLD_SRC_FILES})
|
||||
target_include_directories(HelloWorld PUBLIC ${HELLO_WORLD_ROOT})
|
||||
target_link_libraries(HelloWorld LINK_PUBLIC Jolt)
|
||||
if (MSVC)
|
||||
target_link_options(HelloWorld PUBLIC "/SUBSYSTEM:CONSOLE")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (TARGET_PERFORMANCE_TEST)
|
||||
# Performance Test application
|
||||
include(${PHYSICS_REPO_ROOT}/PerformanceTest/PerformanceTest.cmake)
|
||||
add_executable(PerformanceTest ${PERFORMANCE_TEST_SRC_FILES})
|
||||
target_include_directories(PerformanceTest PUBLIC ${PERFORMANCE_TEST_ROOT})
|
||||
target_link_libraries(PerformanceTest LINK_PUBLIC Jolt)
|
||||
if (MSVC)
|
||||
target_link_options(PerformanceTest PUBLIC "/SUBSYSTEM:CONSOLE")
|
||||
endif()
|
||||
set_property(TARGET PerformanceTest PROPERTY VS_DEBUGGER_WORKING_DIRECTORY "${PHYSICS_REPO_ROOT}")
|
||||
|
||||
# Copy the assets folder
|
||||
add_custom_command(TARGET PerformanceTest PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${PHYSICS_REPO_ROOT}/Assets/ $<TARGET_FILE_DIR:PerformanceTest>/Assets/)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if ("${CMAKE_SYSTEM_NAME}" STREQUAL "Windows" AND NOT ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "ARM")) # ARM 32-bit is missing dinput8.lib
|
||||
# Windows only targets
|
||||
if (TARGET_SAMPLES OR TARGET_VIEWER)
|
||||
include(${PHYSICS_REPO_ROOT}/TestFramework/TestFramework.cmake)
|
||||
endif()
|
||||
if (TARGET_SAMPLES)
|
||||
include(${PHYSICS_REPO_ROOT}/Samples/Samples.cmake)
|
||||
endif()
|
||||
if (TARGET_VIEWER)
|
||||
include(${PHYSICS_REPO_ROOT}/JoltViewer/JoltViewer.cmake)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
237
src/JoltPhysics/Build/README.md
Normal file
@ -0,0 +1,237 @@
|
||||
# Building and Using Jolt Physics
|
||||
|
||||
## Build Types
|
||||
|
||||
Each platform supports multiple build targets
|
||||
|
||||
- Debug - Debug version of the library, turns on asserts
|
||||
- Release - Release version of the library, no asserts but includes profiling support and can draw the world and simulation properties
|
||||
- ReleaseASAN - As Release but turns on Address Sanitizer (clang only) to find bugs
|
||||
- ReleaseUBSAN - As Release but turns on Undefined Behavior Sanitizer (clang only) to find bugs
|
||||
- ReleaseCoverage - As Release but turns on Coverage reporting (clang only) to find which areas of the code are not executed
|
||||
- Distribution - Shippable version of the library, turns off all debugging support
|
||||
|
||||
## Includes
|
||||
|
||||
The Jolt headers don't include Jolt/Jolt.h. Always include Jolt/Jolt.h before including any other Jolt header.
|
||||
You can use Jolt/Jolt.h in your precompiled header to speed up compilation.
|
||||
|
||||
## Defines
|
||||
|
||||
There are a number of user configurable defines that turn on/off certain features:
|
||||
<details>
|
||||
<summary>General Options (click to see more)</summary>
|
||||
<ul>
|
||||
<li>JPH_PROFILE_ENABLED - Turns on the internal profiler.</li>
|
||||
<li>JPH_EXTERNAL_PROFILE - Turns on the internal profiler but forwards the information to a user defined external system (see Profiler.h).</li>
|
||||
<li>JPH_DEBUG_RENDERER - Adds support to draw lines and triangles, used to be able to debug draw the state of the world.</li>
|
||||
<li>JPH_DISABLE_TEMP_ALLOCATOR - Disables the temporary memory allocator, used mainly to allow ASAN to do its job.</li>
|
||||
<li>JPH_DISABLE_CUSTOM_ALLOCATOR - Disables the ability to override the memory allocator.</li>
|
||||
<li>JPH_FLOATING_POINT_EXCEPTIONS_ENABLED - Turns on division by zero and invalid floating point exception support in order to detect bugs (Windows only).</li>
|
||||
<li>JPH_CROSS_PLATFORM_DETERMINISTIC - Turns on behavior to attempt cross platform determinism. If this is set, JPH_USE_FMADD is ignored.</li>
|
||||
<li>JPH_DOUBLE_PRECISION - Compiles the library so that all positions are stored in doubles instead of floats. This makes larger worlds possible.</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>CPU Instruction Sets (click to see more)</summary>
|
||||
<ul>
|
||||
<li>JPH_USE_SSE4_1 - Enable SSE4.1 CPU instructions (default: on, x86/x64 only)</li>
|
||||
<li>JPH_USE_SSE4_2 - Enable SSE4.2 CPU instructions (default: on, x86/x64 only)</li>
|
||||
<li>JPH_USE_F16C - Enable half float CPU instructions (default: on, x86/x64 only)</li>
|
||||
<li>JPH_USE_LZCNT - Enable the lzcnt CPU instruction (default: on, x86/x64 only)</li>
|
||||
<li>JPH_USE_TZCNT - Enable the tzcnt CPU instruction (default: on, x86/x64 only)</li>
|
||||
<li>JPH_USE_AVX - Enable AVX CPU instructions (default: on, x86/x64 only)</li>
|
||||
<li>JPH_USE_AVX2 - Enable AVX2 CPU instructions (default: on, x86/x64 only)</li>
|
||||
<li>JPH_USE_AVX512 - Enable AVX512F+AVX512VL CPU instructions (default: off, x86/x64 only)</li>
|
||||
<li>JPH_USE_FMADD - Enable fused multiply add CPU instructions (default: on, x86/x64 only)</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
## Logging & Asserting
|
||||
|
||||
To override the default trace and assert mechanism install your own custom handlers in Trace and AssertFailed (see IssueReporting.h).
|
||||
|
||||
## Custom Memory Allocator
|
||||
|
||||
To implement your custom memory allocator override Allocate, Free, AlignedAllocate and AlignedFree (see Memory.h).
|
||||
|
||||
## Building
|
||||
|
||||
<details>
|
||||
<summary>Windows 10+</summary>
|
||||
<ul style="list-style: none"><li>
|
||||
<details>
|
||||
<summary>MSVC CL (default compiler)</summary>
|
||||
<ul>
|
||||
<li>Download Visual Studio 2022 (Community or other edition)</li>
|
||||
<li>Download CMake 3.15+ (https://cmake.org/download/)</li>
|
||||
<li>Run cmake_vs2022_cl.bat</li>
|
||||
<li>Open the resulting project file VS2022_CL\JoltPhysics.sln</li>
|
||||
<li>Compile and run either 'Samples' or 'UnitTests'</li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>MSVC CL - 32 bit</summary>
|
||||
<ul>
|
||||
<li>Download Visual Studio 2022 (Community or other edition)</li>
|
||||
<li>Download CMake 3.15+ (https://cmake.org/download/)</li>
|
||||
<li>Run cmake_vs2022_cl_32bit.bat</li>
|
||||
<li>Open the resulting project file VS2022_CL_32BIT\JoltPhysics.sln</li>
|
||||
<li>Compile and run either 'Samples' or 'UnitTests'</li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>MSVC Clang compiler</summary>
|
||||
<ul>
|
||||
<li>Download Visual Studio 2022 (Community or other edition)</li>
|
||||
<li>Make sure to install "C++ Clang Compiler for Windows 11.0.0+" and "C++ Clang-cl for v142+ build tools (x64/x86)" using the Visual Studio Installer</li>
|
||||
<li>Download CMake 3.15+ (https://cmake.org/download/)</li>
|
||||
<li>Run cmake_vs2022_clang.bat</li>
|
||||
<li>Open the resulting project file VS2022_Clang\JoltPhysics.sln</li>
|
||||
<li>Compile and run either 'Samples' or 'UnitTests'</li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>MSVC Universal Windows Platform</summary>
|
||||
<ul>
|
||||
<li>Download Visual Studio 2022+ (Community or other edition)</li>
|
||||
<li>Make sure to install "Universal Windows Platform development" using the Visual Studio Installer</li>
|
||||
<li>Download CMake 3.15+ (https://cmake.org/download/)</li>
|
||||
<li>Run cmake_vs2022_uwp.bat</li>
|
||||
<li>Open the resulting project file VS2022_UWP\JoltPhysics.sln</li>
|
||||
<li>Compile and run 'UnitTests'</li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>MinGW</summary>
|
||||
<ul>
|
||||
<li>Follow download instructions for MSYS2 (https://www.msys2.org/)</li>
|
||||
<li>From the MSYS2 MSYS app run: pacman -S --needed mingw-w64-x86_64-toolchain mingw-w64-x86_64-cmake</li>
|
||||
<li>From the MSYS2 MINGW x64 app, in the Build folder run: ./cmake_windows_mingw.sh</li>
|
||||
<li>Run: cmake --build MinGW_Debug</li>
|
||||
<li>Run: MinGW_Debug/UnitTests.exe</li>
|
||||
</ul>
|
||||
</details>
|
||||
</li></ul>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Linux</summary>
|
||||
<ul style="list-style: none"><li>
|
||||
<details>
|
||||
<summary>Debian flavor, x64 or ARM64</summary>
|
||||
<ul>
|
||||
<li>Install clang (apt-get install clang)</li>
|
||||
<li>Install cmake (apt-get install cmake)</li>
|
||||
<li>Run: ./cmake_linux_clang_gcc.sh</li>
|
||||
<li>Go to the Linux_Debug folder</li>
|
||||
<li>Run: make -j$(nproc) && ./UnitTests</li>
|
||||
</ul>
|
||||
</details>
|
||||
<details>
|
||||
<summary>Debian flavor, MinGW Cross Compile</summary>
|
||||
<ul>
|
||||
<li>This setup can be used to run samples on Linux using wine and vkd3d. Tested on Ubuntu 22.04</li>
|
||||
<li>Graphics card must support Vulkan and related drivers must be installed</li>
|
||||
<li>Install mingw-w64 (apt-get install mingw-w64)</li>
|
||||
<li>Run: update-alternatives --config x86_64-w64-mingw32-g++ (Select /usr/bin/x86_64-w64-mingw32-g++-posix)</li>
|
||||
<li>Install cmake (apt-get install cmake)</li>
|
||||
<li>Install wine64 (apt-get install wine64)</li>
|
||||
<li>Run: export WINEPATH="/usr/x86_64-w64-mingw32/lib;/usr/lib/gcc/x86_64-w64-mingw32/10-posix" (change it based on your environment)</li>
|
||||
<li>Run: ./cmake_linux_mingw.sh Release (Debug doesn't work)</li>
|
||||
<li>Go to the MinGW_Release folder</li>
|
||||
<li>Run: make -j$(nproc) && wine UnitTests.exe</li>
|
||||
<li>Run: wine Samples.exe</li>
|
||||
</ul>
|
||||
</details>
|
||||
</li></ul>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>Android</summary>
|
||||
<ul>
|
||||
<li>Install Android Studio 2020.3.1+ (https://developer.android.com/studio/)</li>
|
||||
<li>Open the 'Android' folder in Android Studio and wait until gradle finishes</li>
|
||||
<li>Select 'Run' / 'Run...' and 'UnitTests'</li>
|
||||
<li>If the screen turns green after a while the unit tests succeeded, when red they failed (see the android log for details)</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>macOS</summary>
|
||||
<ul>
|
||||
<li>Install XCode</li>
|
||||
<li>Download CMake 3.23+ (https://cmake.org/download/)</li>
|
||||
<li>Run: ./cmake_xcode_macos.sh</li>
|
||||
<li>This will open XCode with a newly generated project</li>
|
||||
<li>Build and run the project</li>
|
||||
<li>Note that you can also follow the steps in the 'Linux' section if you wish to build without XCode.</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>iOS</summary>
|
||||
<ul>
|
||||
<li>Install XCode</li>
|
||||
<li>Download CMake 3.23+ (https://cmake.org/download/)</li>
|
||||
<li>Run: ./cmake_xcode.ios.sh</li>
|
||||
<li>This will open XCode with a newly generated project</li>
|
||||
<li>Build and run the project (note that this will only work in the simulator as the code signing information is not set up)</li>
|
||||
</ul>
|
||||
</details>
|
||||
|
||||
## Other Build Tools
|
||||
|
||||
* A vcpkg package is available [here](https://github.com/microsoft/vcpkg/tree/master/ports/joltphysics).
|
||||
* A xmake package is available [here](https://github.com/xmake-io/xmake-repo/tree/dev/packages/j/joltphysics).
|
||||
* Jolt has been verified to build with [ninja](https://ninja-build.org/) through CMake.
|
||||
|
||||
## Errors
|
||||
|
||||
### Link Error: File Format Not Recognized
|
||||
|
||||
If you receive the following error when linking:
|
||||
|
||||
```
|
||||
/usr/bin/ld: libJolt.a: error adding symbols: file format not recognized
|
||||
```
|
||||
|
||||
Then you have not enabled interprocedural optimizations (link time optimizations) for your own application. See the INTERPROCEDURAL_OPTIMIZATION option in CMakeLists.txt.
|
||||
|
||||
### Link Error: Unresolved External Symbol
|
||||
|
||||
If you receive a link error that looks like:
|
||||
|
||||
```
|
||||
error LNK2001: unresolved external symbol "public: virtual void __cdecl JPH::ConvexShape::GetSubmergedVolume(...) const"
|
||||
```
|
||||
|
||||
you have a mismatch in defines between your own code and the Jolt library. In this case the mismatch is in the define `JPH_DEBUG_RENDERER` which is most likely defined in `Jolt.lib` and not in your own project. In `Debug` and `Release` builds, Jolt by default has `JPH_DEBUG_RENDERER` defined, in `Distribution` it is not defined. The cmake options `DEBUG_RENDERER_IN_DEBUG_AND_RELEASE` and `DEBUG_RENDERER_IN_DISTRIBUTION` override this behavior.
|
||||
|
||||
The `RegisterTypes` function (which you have to call to initialize the library) checks the other important defines and will trace and abort if there are more mismatches.
|
||||
|
||||
### DirectX Error
|
||||
|
||||
The samples use DirectX for the graphics implementation, when attempting to run the samples you may get a DirectX error pop-up which may say "The GPU device instance has been suspended", in your debugger you may see the message "Using the Redistributable D3D12 SDKLayers dll also requires that the latest SDKLayers for Windows 10 is installed.".
|
||||
|
||||
Fix this by enabling "Graphics Tools" which is an optional Windows settings. To enable it you have to press the windows key, search for "Manage Optional Features", and then click "Add a Feature", and install "Graphics Tools".
|
||||
|
||||
### Illegal Instruction Error
|
||||
|
||||
If your CPU doesn't support all of the instructions you'll get an `Illegal instruction` exception.
|
||||
|
||||
On Linux to see what instructions your CPU supports run `lscpu` and then look at the flags section, on Windows you can use a program like [`coreinfo`](https://learn.microsoft.com/en-us/sysinternals/downloads/coreinfo). Once you know what instructions your cpu supports you can configure the project through cmake and for example disable all special instructions:
|
||||
|
||||
```
|
||||
./cmake_linux_clang_gcc.sh Release clang++ -DUSE_SSE4_1=OFF -DUSE_SSE4_2=OFF -DUSE_AVX=OFF -DUSE_AVX2=OFF -DUSE_AVX512=OFF -DUSE_LZCNT=OFF -DUSE_TZCNT=OFF -DUSE_F16C=OFF -DUSE_FMADD=OFF
|
||||
```
|
||||
|
||||
Note that this example is for Linux but the cmake settings work on Windows too.
|
||||
|
||||
## Doxygen on Windows
|
||||
|
||||
Documentation can be generated through doxygen:
|
||||
|
||||
- Install Doxygen (https://www.doxygen.nl/download.html)
|
||||
- Run: run_doxygen.bat
|
28
src/JoltPhysics/Build/cmake_linux_clang_gcc.sh
Normal file
@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z $1 ]
|
||||
then
|
||||
BUILD_TYPE=Debug
|
||||
else
|
||||
BUILD_TYPE=$1
|
||||
shift
|
||||
fi
|
||||
|
||||
if [ -z $1 ]
|
||||
then
|
||||
COMPILER=clang++
|
||||
else
|
||||
COMPILER=$1
|
||||
shift
|
||||
fi
|
||||
|
||||
BUILD_DIR=Linux_$BUILD_TYPE
|
||||
|
||||
echo Usage: ./cmake_linux_clang_gcc.sh [Configuration] [Compiler]
|
||||
echo "Possible configurations: Debug (default), Release, Distribution, ReleaseUBSAN, ReleaseASAN, ReleaseCoverage"
|
||||
echo "Possible compilers: clang++, clang++-XX, g++, g++-XX where XX is the version"
|
||||
echo Generating Makefile for build type \"$BUILD_TYPE\" and compiler \"$COMPILER\" in folder \"$BUILD_DIR\"
|
||||
|
||||
cmake -S . -B $BUILD_DIR -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_COMPILER=$COMPILER "${@}"
|
||||
|
||||
echo Compile by running \"make -j 8 \&\& ./UnitTests\" in folder \"$BUILD_DIR\"
|
19
src/JoltPhysics/Build/cmake_linux_mingw.sh
Normal file
@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z $1 ]
|
||||
then
|
||||
BUILD_TYPE=Release
|
||||
else
|
||||
BUILD_TYPE=$1
|
||||
shift
|
||||
fi
|
||||
|
||||
BUILD_DIR=MinGW_$BUILD_TYPE
|
||||
|
||||
echo Usage: ./cmake_linux_mingw.sh [Configuration]
|
||||
echo "Possible configurations: Debug, Release (default), Distribution"
|
||||
echo Generating Makefile for build type \"$BUILD_TYPE\" in folder \"$BUILD_DIR\"
|
||||
|
||||
cmake -S . -B $BUILD_DIR -DCMAKE_TOOLCHAIN_FILE=mingw-w64-x86_64.cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE "${@}"
|
||||
|
||||
echo Compile by running \"cmake --build $BUILD_DIR -j 8\"
|
3
src/JoltPhysics/Build/cmake_vs2019_cl.bat
Normal file
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
cmake -S . -B VS2019_CL -G "Visual Studio 16 2019" -A x64 %*
|
||||
echo Open VS2019_CL\JoltPhysics.sln to build the project.
|
3
src/JoltPhysics/Build/cmake_vs2019_cl_arm.bat
Normal file
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
cmake -S . -B VS2019_CL_ARM -G "Visual Studio 16 2019" -A ARM64 %*
|
||||
echo Open VS2019_CL_ARM\JoltPhysics.sln to build the project.
|
3
src/JoltPhysics/Build/cmake_vs2019_cl_arm_32bit.bat
Normal file
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
cmake -S . -B VS2019_CL_ARM_32BIT -G "Visual Studio 16 2019" -A ARM %*
|
||||
echo Open VS2019_CL_ARM_32BIT\JoltPhysics.sln to build the project.
|
10
src/JoltPhysics/Build/cmake_vs2019_clang.bat
Normal file
@ -0,0 +1,10 @@
|
||||
@echo off
|
||||
cmake -S . -B VS2019_Clang -G "Visual Studio 16 2019" -A x64 -T ClangCL %*
|
||||
echo:
|
||||
echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
echo Make sure to install:
|
||||
echo - C++ Clang Compiler for Windows 11.0.0+
|
||||
echo - C++ Clang-cl for v142+ build tools (x64/x86)
|
||||
echo Using the Visual Studio Installer
|
||||
echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
echo Open VS2019_Clang/JoltPhysics.sln to build the project.
|
3
src/JoltPhysics/Build/cmake_vs2022_cl.bat
Normal file
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
cmake -S . -B VS2022_CL -G "Visual Studio 17 2022" -A x64 %*
|
||||
echo Open VS2022_CL\JoltPhysics.sln to build the project.
|
3
src/JoltPhysics/Build/cmake_vs2022_cl_32bit.bat
Normal file
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
cmake -S . -B VS2022_CL_32BIT -G "Visual Studio 17 2022" -A Win32 -DUSE_SSE4_1=OFF -DUSE_SSE4_2=OFF -DUSE_AVX=OFF -DUSE_AVX2=OFF -DUSE_AVX512=OFF -DUSE_LZCNT=OFF -DUSE_TZCNT=OFF -DUSE_F16C=OFF -DUSE_FMADD=OFF %*
|
||||
echo Open VS2022_CL_32BIT\JoltPhysics.sln to build the project.
|
3
src/JoltPhysics/Build/cmake_vs2022_cl_arm.bat
Normal file
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
cmake -S . -B VS2022_CL_ARM -G "Visual Studio 17 2022" -A ARM64 %*
|
||||
echo Open VS2022_CL_ARM\JoltPhysics.sln to build the project.
|
3
src/JoltPhysics/Build/cmake_vs2022_cl_arm_32bit.bat
Normal file
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
cmake -S . -B VS2022_CL_ARM_32BIT -G "Visual Studio 17 2022" -A ARM %*
|
||||
echo Open VS2022_CL_ARM_32BIT\JoltPhysics.sln to build the project.
|
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
cmake -S . -B VS2022_CL_CPD -G "Visual Studio 17 2022" -A x64 -DCROSS_PLATFORM_DETERMINISTIC=ON %*
|
||||
echo Open VS2022_CL_CPD\JoltPhysics.sln to build the project.
|
3
src/JoltPhysics/Build/cmake_vs2022_cl_double.bat
Normal file
@ -0,0 +1,3 @@
|
||||
@echo off
|
||||
cmake -S . -B VS2022_CL_Double -G "Visual Studio 17 2022" -A x64 -DDOUBLE_PRECISION=ON %*
|
||||
echo Open VS2022_CL_Double\JoltPhysics.sln to build the project.
|
10
src/JoltPhysics/Build/cmake_vs2022_clang.bat
Normal file
@ -0,0 +1,10 @@
|
||||
@echo off
|
||||
cmake -S . -B VS2022_Clang -G "Visual Studio 17 2022" -A x64 -T ClangCL %*
|
||||
echo:
|
||||
echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
echo Make sure to install:
|
||||
echo - C++ Clang Compiler for Windows 12.0.0+
|
||||
echo - C++ Clang-cl for v143+ build tools (x64/x86)
|
||||
echo Using the Visual Studio Installer
|
||||
echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
echo Open VS2022_Clang/JoltPhysics.sln to build the project.
|
10
src/JoltPhysics/Build/cmake_vs2022_clang_double.bat
Normal file
@ -0,0 +1,10 @@
|
||||
@echo off
|
||||
cmake -S . -B VS2022_Clang_Double -G "Visual Studio 17 2022" -A x64 -T ClangCL -DDOUBLE_PRECISION=YES %*
|
||||
echo:
|
||||
echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
echo Make sure to install:
|
||||
echo - C++ Clang Compiler for Windows 12.0.0+
|
||||
echo - C++ Clang-cl for v143+ build tools (x64/x86)
|
||||
echo Using the Visual Studio Installer
|
||||
echo !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
echo Open VS2022_Clang_Double/JoltPhysics.sln to build the project.
|
5
src/JoltPhysics/Build/cmake_vs2022_uwp.bat
Normal file
@ -0,0 +1,5 @@
|
||||
@echo off
|
||||
cmake -S . -B VS2022_UWP -G "Visual Studio 17 2022" -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0 %*
|
||||
echo If cmake failed then be sure to check the "Universal Windows Platform development" checkbox in the Visual Studio Installer
|
||||
echo Open VS2022_UWP\JoltPhysics.sln to build the project.
|
||||
echo Note that none of the sample applications are available for the Universal Windows Platform (use cmake_vs2022_cl.bat instead).
|
5
src/JoltPhysics/Build/cmake_vs2022_uwp_arm.bat
Normal file
@ -0,0 +1,5 @@
|
||||
@echo off
|
||||
cmake -S . -B VS2022_UWP_ARM -G "Visual Studio 17 2022" -A ARM64 -DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0 %*
|
||||
echo If cmake failed then be sure to check the "Universal Windows Platform development" checkbox in the Visual Studio Installer
|
||||
echo Open VS2022_UWP_ARM\JoltPhysics.sln to build the project.
|
||||
echo Note that none of the sample applications are available for the Universal Windows Platform (use cmake_vs2022_cl_arm.bat instead).
|
19
src/JoltPhysics/Build/cmake_windows_mingw.sh
Normal file
@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z $1 ]
|
||||
then
|
||||
BUILD_TYPE=Debug
|
||||
else
|
||||
BUILD_TYPE=$1
|
||||
shift
|
||||
fi
|
||||
|
||||
BUILD_DIR=MinGW_$BUILD_TYPE
|
||||
|
||||
echo Usage: ./cmake_windows_mingw.sh [Configuration]
|
||||
echo "Possible configurations: Debug (default), Release, Distribution"
|
||||
echo Generating Makefile for build type \"$BUILD_TYPE\" in folder \"$BUILD_DIR\"
|
||||
|
||||
cmake -S . -B $BUILD_DIR -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=$BUILD_TYPE "${@}"
|
||||
|
||||
echo Compile by running \"cmake --build $BUILD_DIR -j 8\"
|
4
src/JoltPhysics/Build/cmake_xcode_ios.sh
Normal file
@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
cmake -S . -B XCode_iOS -DTARGET_HELLO_WORLD=OFF -DTARGET_PERFORMANCE_TEST=OFF -DCMAKE_SYSTEM_NAME=iOS -GXcode
|
||||
open XCode_iOS/JoltPhysics.xcodeproj
|
4
src/JoltPhysics/Build/cmake_xcode_macos.sh
Normal file
@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
|
||||
cmake -S . -B XCode_MacOS -GXcode -D"CMAKE_OSX_ARCHITECTURES=x86_64;arm64"
|
||||
open XCode_MacOS/JoltPhysics.xcodeproj
|
34
src/JoltPhysics/Build/iOS/UnitTestsInfo.plist
Normal file
@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleGetInfoString</key>
|
||||
<string></string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.joltphysics.unittests</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleLongVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>UnitTests</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>CSResourcesFileMapped</key>
|
||||
<true/>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
123
src/JoltPhysics/ContributorAgreement.md
Normal file
@ -0,0 +1,123 @@
|
||||
## Fiduciary License Agreement 2.0
|
||||
|
||||
based on the
|
||||
|
||||
## Individual Contributor Exclusive License Agreement
|
||||
|
||||
## (including the Traditional Patent License OPTION)
|
||||
|
||||
Thank you for your interest in contributing to Jolt Physics ("We" or "Us").
|
||||
|
||||
The purpose of this contributor agreement ("Agreement") is to clarify and document the rights granted by contributors to Us.
|
||||
|
||||
### 0\. Preamble
|
||||
|
||||
Software is deeply embedded in all aspects of our lives and it is important that it empower, rather than restrict us. Free Software gives everybody the rights to use, understand, adapt and share software. These rights help support other fundamental freedoms like freedom of speech, press and privacy.
|
||||
|
||||
Development of Free Software can follow many patterns. In some cases whole development is handled by a sole programmer or a small group of people. But usually, the creation and maintenance of software is a complex process that requires the contribution of many individuals. This also affects who owns the rights to the software. In the latter case, rights in software are owned jointly by a great number of individuals.
|
||||
|
||||
To tackle this issue some projects require a full copyright assignment to be signed by all contributors. The problem with such assignments is that they often lack checks and balances that would protect the contributors from potential abuse of power from the new copyright holder.
|
||||
|
||||
FSFE’s Fiduciary License Agreement (FLA) was created by the Free Software Foundation Europe e.V. with just that in mind – to concentrate all deciding power within one entity and prevent fragmentation of rights on one hand, while on the other preventing that single entity from abusing its power. The main aim is to ensure that the software covered under the FLA will forever remain Free Software.
|
||||
|
||||
This process only serves for the transfer of economic rights. So-called moral rights (e.g. authors right to be identified as author) remain with the original author(s) and are inalienable.
|
||||
|
||||
### How to use this FLA
|
||||
|
||||
If You are an employee and have created the Contribution as part of your employment, You need to have Your employer approve this Agreement or sign the Entity version of this document. If You do not own the Copyright in the entire work of authorship, any other author of the Contribution should also sign this – in any event, please contact Us at jorrit@jrouwe.nl
|
||||
|
||||
### 1\. Definitions
|
||||
|
||||
**"You"** means the individual Copyright owner who Submits a Contribution to Us.
|
||||
|
||||
**"Legal Entity"** means an entity that is not a natural person.
|
||||
|
||||
**"Affiliate"** means any other Legal Entity that controls, is controlled by, or under common control with that Legal Entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such Legal Entity, whether by contract or otherwise, (ii) ownership of fifty percent (50%) or more of the outstanding shares or securities that vote to elect the management or other persons who direct such Legal Entity or (iii) beneficial ownership of such entity.
|
||||
|
||||
**"Contribution"** means any original work of authorship, including any original modifications or additions to an existing work of authorship, Submitted by You to Us, in which You own the Copyright.
|
||||
|
||||
**"Copyright"** means all rights protecting works of authorship, including copyright, moral and neighboring rights, as appropriate, for the full term of their existence.
|
||||
|
||||
**"Material"** means the software or documentation made available by Us to third parties. When this Agreement covers more than one software project, the Material means the software or documentation to which the Contribution was Submitted. After You Submit the Contribution, it may be included in the Material.
|
||||
|
||||
**"Submit"** means any act by which a Contribution is transferred to Us by You by means of tangible or intangible media, including but not limited to electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, Us, but excluding any transfer that is conspicuously marked or otherwise designated in writing by You as "Not a Contribution."
|
||||
|
||||
**"Documentation"** means any non-software portion of a Contribution.
|
||||
|
||||
### 2\. License grant
|
||||
|
||||
#### 2.1 Copyright license to Us
|
||||
|
||||
Subject to the terms and conditions of this Agreement, You hereby grant to Us a worldwide, royalty-free, exclusive, perpetual and irrevocable (except as stated in Section 8.2) license, with the right to transfer an unlimited number of non-exclusive licenses or to grant sublicenses to third parties, under the Copyright covering the Contribution to use the Contribution by all means, including, but not limited to:
|
||||
|
||||
* publish the Contribution,
|
||||
* modify the Contribution,
|
||||
* prepare derivative works based upon or containing the Contribution and/or to combine the Contribution with other Materials,
|
||||
* reproduce the Contribution in original or modified form,
|
||||
* distribute, to make the Contribution available to the public, display and publicly perform the Contribution in original or modified form.
|
||||
|
||||
#### 2.2 Moral rights
|
||||
|
||||
Moral Rights remain unaffected to the extent they are recognized and not waivable by applicable law. Notwithstanding, You may add your name to the attribution mechanism customary used in the Materials you Contribute to, such as the header of the source code files of Your Contribution, and We will respect this attribution when using Your Contribution.
|
||||
|
||||
#### 2.3 Copyright license back to You
|
||||
|
||||
Upon such grant of rights to Us, We immediately grant to You a worldwide, royalty-free, non-exclusive, perpetual and irrevocable license, with the right to transfer an unlimited number of non-exclusive licenses or to grant sublicenses to third parties, under the Copyright covering the Contribution to use the Contribution by all means, including, but not limited to:
|
||||
|
||||
* publish the Contribution,
|
||||
* modify the Contribution,
|
||||
* prepare derivative works based upon or containing the Contribution and/or to combine the Contribution with other Materials,
|
||||
* reproduce the Contribution in original or modified form,
|
||||
* distribute, to make the Contribution available to the public, display and publicly perform the Contribution in original or modified form.
|
||||
|
||||
This license back is limited to the Contribution and does not provide any rights to the Material.
|
||||
|
||||
### 3\. Patents
|
||||
|
||||
#### 3.1 Patent license
|
||||
|
||||
Subject to the terms and conditions of this Agreement You hereby grant to Us and to recipients of Materials distributed by Us a worldwide, royalty-free, non-exclusive, perpetual and irrevocable (except as stated in Section 3.2) patent license, with the right to transfer an unlimited number of non-exclusive licenses or to grant sublicenses to third parties, to make, have made, use, sell, offer for sale, import and otherwise transfer the Contribution and the Contribution in combination with any Material (and portions of such combination). This license applies to all patents owned or controlled by You, whether already acquired or hereafter acquired, that would be infringed by making, having made, using, selling, offering for sale, importing or otherwise transferring of Your Contribution(s) alone or by combination of Your Contribution(s) with any Material.
|
||||
|
||||
#### 3.2 Revocation of patent license
|
||||
|
||||
You reserve the right to revoke the patent license stated in section 3.1 if We make any infringement claim that is targeted at your Contribution and not asserted for a Defensive Purpose. An assertion of claims of the Patents shall be considered for a "Defensive Purpose" if the claims are asserted against an entity that has filed, maintained, threatened, or voluntarily participated in a patent infringement lawsuit against Us or any of Our licensees.
|
||||
|
||||
### 4\. License obligations by Us
|
||||
|
||||
We agree to (sub)license the Contribution or any Materials containing, based on or derived from your Contribution under the terms of any licenses the Free Software Foundation classifies as Free Software License and which are approved by the Open Source Initiative as Open Source licenses.
|
||||
|
||||
More specifically and in strict accordance with the above paragraph, we agree to (sub)license the Contribution or any Materials containing, based on or derived from the Contribution only under the terms of the following license(s) MIT (including any right to adopt any future version of a license if permitted).
|
||||
|
||||
We agree to license patents owned or controlled by You only to the extent necessary to (sub)license Your Contribution(s) and the combination of Your Contribution(s) with the Material under the terms of any licenses the Free Software Foundation classifies as Free Software licenses and which are approved by the Open Source Initiative as Open Source licenses..
|
||||
|
||||
### 5. Disclaimer
|
||||
|
||||
THE CONTRIBUTION IS PROVIDED "AS IS". MORE PARTICULARLY, ALL EXPRESS OR IMPLIED WARRANTIES INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTY OF SATISFACTORY QUALITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE EXPRESSLY DISCLAIMED BY YOU TO US AND BY US TO YOU. TO THE EXTENT THAT ANY SUCH WARRANTIES CANNOT BE DISCLAIMED, SUCH WARRANTY IS LIMITED IN DURATION AND EXTENT TO THE MINIMUM PERIOD AND EXTENT PERMITTED BY LAW.
|
||||
|
||||
### 6. Consequential damage waiver
|
||||
|
||||
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL YOU OR WE BE LIABLE FOR ANY LOSS OF PROFITS, LOSS OF ANTICIPATED SAVINGS, LOSS OF DATA, INDIRECT, SPECIAL, INCIDENTAL, CONSEQUENTIAL AND EXEMPLARY DAMAGES ARISING OUT OF THIS AGREEMENT REGARDLESS OF THE LEGAL OR EQUITABLE THEORY (CONTRACT, TORT OR OTHERWISE) UPON WHICH THE CLAIM IS BASED.
|
||||
|
||||
### 7. Approximation of disclaimer and damage waiver
|
||||
|
||||
IF THE DISCLAIMER AND DAMAGE WAIVER MENTIONED IN SECTION 5. AND SECTION 6. CANNOT BE GIVEN LEGAL EFFECT UNDER APPLICABLE LOCAL LAW, REVIEWING COURTS SHALL APPLY LOCAL LAW THAT MOST CLOSELY APPROXIMATES AN ABSOLUTE WAIVER OF ALL CIVIL OR CONTRACTUAL LIABILITY IN CONNECTION WITH THE CONTRIBUTION.
|
||||
|
||||
### 8. Term
|
||||
|
||||
8.1 This Agreement shall come into effect upon Your acceptance of the terms and conditions.
|
||||
|
||||
8.2 This Agreement shall apply for the term of the copyright and patents licensed here. However, You shall have the right to terminate the Agreement if We do not fulfill the obligations as set forth in Section 4. Such termination must be made in writing.
|
||||
|
||||
8.3 In the event of a termination of this Agreement Sections 5., 6., 7., 8., and 9. shall survive such termination and shall remain in full force thereafter. For the avoidance of doubt, Free and Open Source Software (sub)licenses that have already been granted for Contributions at the date of the termination shall remain in full force after the termination of this Agreement.
|
||||
|
||||
### 9. Miscellaneous
|
||||
|
||||
9.1 This Agreement and all disputes, claims, actions, suits or other proceedings arising out of this agreement or relating in any way to it shall be governed by the laws of Netherlands excluding its private international law provisions.
|
||||
|
||||
9.2 This Agreement sets out the entire agreement between You and Us for Your Contributions to Us and overrides all other agreements or understandings.
|
||||
|
||||
9.3 In case of Your death, this agreement shall continue with Your heirs. In case of more than one heir, all heirs must exercise their rights through a commonly authorized person.
|
||||
|
||||
9.4 If any provision of this Agreement is found void and unenforceable, such provision will be replaced to the extent possible with a provision that comes closest to the meaning of the original provision and that is enforceable. The terms and conditions set forth in this Agreement shall apply notwithstanding any failure of essential purpose of this Agreement or any limited remedy to the maximum extent possible under law.
|
||||
|
||||
9.5 You agree to notify Us of any facts or circumstances of which you become aware that would make this Agreement inaccurate in any respect.
|
111
src/JoltPhysics/Docs/APIChanges.md
Normal file
@ -0,0 +1,111 @@
|
||||
# Breaking API Changes
|
||||
|
||||
This document lists all breaking API changes by date and by release tag. Note that not all API changes are listed here, trivial changes (that cause a compile error and require an obvious fix) are not listed.
|
||||
|
||||
Changes that make some state saved through SaveBinaryState from a prior version of the library unreadable by the new version is marked as *SBS*. See [Saving Shapes](https://jrouwe.github.io/JoltPhysics/#saving-shapes) for further information.
|
||||
|
||||
## Changes between v4.0.2 and v5.0.0
|
||||
|
||||
* 20240327 - *SBS* - SoftBodySharedSettings::CreateEdges was renamed to CreateConstraints and can now also create shear and bend constraints. This also breaks the serialization format for SoftBodySharedSettings. (8e4bf3fa03f59cff6af7394d69cdf62abaf7a1d2)
|
||||
* 20240310 - *SBS* - Soft body skinned constraints now use a sphere as backstop instead of an infinite plane. This also breaks the serialization format for SoftBodySharedSettings. (17db6d3f245d2198319c3787f62498fe5935b7c8)
|
||||
* 20240225 - *SBS* - Changes were made to SoftBodySharedSettings that break the binary serialization format of that class. (277b818ffefed4f15477ff1e6d0cc07065899903)
|
||||
* 20240223 - Added ConvexShape::ESupportMode::Default. If you have custom convex shapes you need to handle this in ConvexShape::GetSupportFunction. (0f67cc2915c5e34a4a38480580dad73888a1952e)
|
||||
* 20240216 - Restriction angular motion using EAllowedDOFs now works in world space rather than in local space. This change was made to be more in line with other physics engines and to fix some issues with constraints. If you need the old behavior then copy [this](https://github.com/jrouwe/JoltPhysics/blob/9631e217e54b8492ac36471f2aa966df40d6c2ad/Jolt/Physics/Body/MotionProperties.cpp#L33-L118) code into your own code base and call MotionProperties::SetInverseInertia(diagonal, rotation) where diagonal is called mInvInertiaDiagonal and rotation is called mInertiaRotation in the code snippet. (191536d51d71ee29147205aa09d1acab52789e5f)
|
||||
* 20240210 - Fixed spelling error EPathRotationConstraintType::ConstaintToPath to EPathRotationConstraintType::ConstrainToPath (6c095bbf7906b01f427b52d43212f5ebf760fc81)
|
||||
* 20240210 - Added extra parameter fraction hint to PathConstraintPath::GetClosestPoint. This can be used to speed up the search along the curve and to disambiguate fractions in case a path reaches the same point multiple times (i.e. a figure-8) (b91e729e6e2c34df16cc03f5ac3b3f6d3fa8b762)
|
||||
* 20240203 - Longitudinal friction impulse for wheeled/tracked vehicles could become much higher than the calculated max because each iteration it was clamped to the max friction impulse which meant the total friction impulse could be PhysicsSettings::mNumVelocitySteps times too high. In case this breaks your vehicle, the new max tire impulse callback can be used to restore the old behavior, see [the vehicle constraint test](https://github.com/jrouwe/JoltPhysics/blob/a456b244aa2ad2ce0a8124d27823377ed0b1c4b4/Samples/Tests/Vehicle/VehicleConstraintTest.cpp#L156-L164). (a456b244aa2ad2ce0a8124d27823377ed0b1c4b4)
|
||||
* 20240120 - *SBS* - Implemented enhanced internal edge removal algorithm. This breaks the binary serialization format for BodyCreationSettings. (94c1ad811b95c72f4d3bb6841c73c1c3461caa91)
|
||||
* 20240113 - VehicleConstraint::CombineFunction now calculates both longitudinal and lateral friction in 1 call so there can be dependencies between the two. (d6ed5b3e7b22904af555088b6ae4770f8fb0e00f)
|
||||
* 20240105 - CharacterVirtual will now receive an OnContactAdded callback when it collides with a sensor (but will have no further interaction). You may need to update the logic in your CharacterContactListener to ignore those contacts. (fb778c568d3ba14556559324671ffec172957f5c)
|
||||
* 20240101 - Renamed SensorDetectsStatic to CollideKinematicVsNonDynamic and made it work for non-sensors. This means that kinematic bodies can now get collision callbacks when they collide with other static / kinematic objects. It can also affect the order in which bodies are passed in the ContactListener::OnContactValidate callback. (2d607c4161a65201d66558a2cc76d1265aea527e)
|
||||
* 20231220 - *SBS* - Added ability to enable gyroscopic forces on BodyCreationSettings. This breaks the binary serialization format for this class. (9d7748eaa91341adc17554f32bf991bfed04e47e)
|
||||
* 20231219 - *SBS* - Added a 'swing type' attribute to SixDOFConstraint and SwingTwistConstraint. This breaks the binary serialization format. (41016256e2cf1262ec05cff3cfa7645668ee0bf0)
|
||||
* 20231208 - Changed the meaning of Constraint::mNumVelocity/PositionStepsOverride. Before the number of steps would be the maximum of all constraints and the default value, now an overridden value of 0 means that the constraint uses the default value, otherwise it will use the value as specified. This means that if all constraints in an island have a lower value than the default, we will now use the lower value instead of the default. (0771808a03b850d16f1c64156f0aee827ca3706b)
|
||||
* 20231208 - *SBS* - Bodies can now also override the default number of solver iterations. This breaks the binary serialization format. (0771808a03b850d16f1c64156f0aee827ca3706b)
|
||||
* 20231203 - VehicleConstraint::CombineFunction got two additional parameters to identify which wheel is requesting friction. (8d80155f93d0d0c3ffe3dd46550650b9c830d304)
|
||||
|
||||
## Changes between v4.0.0 and v4.0.2
|
||||
|
||||
* No breaking changes.
|
||||
|
||||
## Changes between v3.0.1 and v4.0.0
|
||||
|
||||
* 20231003 - *SBS* - Bug fix in serialization of SoftBodySharedSettings breaks binary serialization format. (ccb250747eee4dedebfa02d950775478fb52f786)
|
||||
* 20230914 - Removed GetProcessorTicksPerSecond as it was not correctly implemented for all platforms. (d44f4bad0872075d5cef2779742c89203d4f4488)
|
||||
* 20230819 - *SBS* - RagdollSettings got the ability to have constraints that do not follow the skeleton. This changes the binary serialization format for this class. (08fc49d2d7abfa1a69e21971785d37724c748bb6)
|
||||
* 20230807 - Renamed ContactSettings::mRelativeSurfaceVelocity to mRelativeLinearSurfaceVelocity. (76b809ddb1abf96641acc587fffa70101323d323)
|
||||
* 20230807 - *SBS* - PhysicsScene is now able to load/save soft bodies. This changes the binary serialization format. (779ba3673beebdc4021842516f4ff6aa7c1e09b4)
|
||||
* 20230805 - Body::SaveState and MotionProperties::SaveState now only save the state that can be changed by the simulation. Configuration properties like friction, restitution etc. must be saved by the user if desired. (7ff50429abd53f1914fd25a9e80ff47f22bc9f0e)
|
||||
* 20230801 - *SBS* - Constraint priority was added to all constraints which changes the binary serialization format. (e341bb3e959460fbe196032095c1ab0346d7e746)
|
||||
* 20230704 - *SBS* - A new flag was added to BodyCreationSettings that changes the binary serialization format. (2dd3a033a41e422eb470484029324cc9bbaf0825)
|
||||
* 20230629 - Fix for engine RPM being much higher than wheel RPM when measured at clutch. Before we were ignoring bake and wheel torques in engine RPM calculation. Now they're much closer but this unfortunately means that the simulation of the vehicle has changed and mainly the engine torque and clutch strength need to be re-tweaked. (b40090766c545a68dccfac76cde8c6345ca626a6)
|
||||
* 20230623 - The parameter inIntegrationSubSteps was removed from PhysicsSystem::Update because more and more features didn't support it. If you were using it multiply inCollisionSteps with the value of inIntegrationSubSteps to get roughly the same behavior. (8fcc7a78ec051b215bf13b037b9f975baa803b6f)
|
||||
* 20230618 - *SBS* - A new flag was added to BodyCreationSettings that changes the binary serialization format. (107b70c7585909f0757a62c318261a18d670ff97)
|
||||
* 20230610 - A bug was fixed that causes the vehicle suspension to be weaker when driving over low mass objects. This also changes suspension behavior a bit when driving over static objects. (44b82e395697ea553574df3cd806ffe264bfa5c4)
|
||||
* 20230609 - *SBS* - The MotorcycleController lean controller is now a full PID controller. This changes binary serialization format. (70e7bb3e5808dabc17ee38fb823fbfa7e9140a91)
|
||||
* 20230609 - *SBS* - VehicleConstraint uses the new SpringSettings class as a member which contains the mFrequency and mDamping members. This requires minor code changes. (0da97d8f3345f14c5b4b0ee3571c05832c556f98)
|
||||
* 20230609 - *SBS* - DistanceConstraintSettings, SliderConstraintSettings and MotorSettings now use the new SpringSettings class as a member which contains the mFrequency and mDamping members. This requires minor code changes. (3cabc057c1267fde288c1ab2a23076702c71eb79)
|
||||
* 20230520 - A bug was fixed in CharacterVirtual that makes mPenetrationRecoverySpeed behave according to the documentation (1 = fully resolve collision in 1 update). With the bug the recovery was too little. If you want the penetration recovery to work as before with the bug multiply it by 1 / delta_time. (8dd93317d66a9a72d3afeff4ecb17c257a7e9d91)
|
||||
* 20230420 - To support compiling Jolt as a shared library, the RTTI macros were changed to be able to specify if a symbol should be exported or not. If you're using Jolt's RTTI system in your own project you need to change e.g. JPH_DECLARE_RTTI_VIRTUAL(XXX) to JPH_DECLARE_RTTI_VIRTUAL(JPH_NO_EXPORT, XXX). (d2f1d97004d036c6f759203c42e264e401472037)
|
||||
|
||||
## Changes between v2.0.1 and v3.0.0
|
||||
|
||||
* 20230331 - *SBS* - Vehicle wheels now support specifying the steering axis and wheel forward and up axis separately. This breaks the serialization format and requires setting extra properties on the wheels. (4269d8bbc77b889552a842c2e8476ba7ffc6b9a1)
|
||||
* 20230328 - Vehicle now supports suspension under an angle. The behavior of the suspension, even if it is under 90 degrees with the vehicle body, changed so this may require tweaking the spring constants. (172a99c718bded5faa169ac440517286684fa2f0)
|
||||
* 20230316 - The signature of ShapeFilter changed and the ShouldCollide function is no longer called for triangles inside a mesh/heightfield shape (you can use CollisionCollector::AddHit to filter per triangle). The previous implementation didn't pass in enough context for the application to fully determine which sub shapes were colliding. See [#473](https://github.com/jrouwe/JoltPhysics/discussions/473) for more information. (bc4fa997f15f2953dc87ee5c1ba51ecf2077c287)
|
||||
* 20230313 - VehicleCollisionTester::Collide parameter outSuspensionLength was returning suspension length + wheel radius, now it returns the suspension length. If you have your own implementation of VehicleCollisionTester you need to update your code. (fcd9cb0f1677709e30951f2748aefd5f72ffdae1)
|
||||
* 20230212 - Sensors are now able to detect other Sensors, make sure you put sensors in an ObjectLayer that doesn't collide with other sensors if you want to preserve the old behavior. (a76f5891ee429ae4fcde659c19f1eb769f9d8a21)
|
||||
* 20230205 - *SBS* - Added 'IsSensor' and 'UseManifoldReduction' to BodyCreationSettings::SaveBinaryState. (8f6f210f53fc71e43760e20aeb2eae28ea168f4b)
|
||||
* 20221231 - ObjectLayerPairFilter and ObjectVsBroadPhaseLayerFilter are now objects instead of function pointers. (4315ad53e354f094f753664fcf7a52870f6915e4)
|
||||
* 20221208 - ContactListener::OnContactValidate is reporting collisions relative to inBaseOffset. Add this to the contact point if you want world space positions. (428611482825e369e60e0a5daf17c69a4d0f2a6f)
|
||||
* 20221204 - Changes related to double precision support for positions (a2c1c22059fa031faf0208258e654bcff79a63e4)
|
||||
* In many places in the public API Vec3 has been replaced by RVec3 (a Vec3 of Real values which can either be double or float depending on if JPH_DOUBLE_PRECISION is defined). In the same way RMat44 replaces Mat44. When compiling in single precision mode (the default) you should not notice a change.
|
||||
* Shape::GetSubmergedVolume now takes a plane that's relative to inCenterOfMassTransform instead of one in world space
|
||||
* Many of the NarrowPhaseQuery and TransformedShape collision queries now have a 'base offset' that you need to specify. Go to [Big Worlds](https://jrouwe.github.io/JoltPhysics/#big-worlds) for more info.
|
||||
* The NarrowPhaseQuery/TransformedShape CastRay / CastShape functions now take a RRayCast / RShapeCast struct as input. When compiling in single precision mode this is the same as a RayCast or ShapeCast so only the type name needs to be updated.
|
||||
* If you implement your own TempAllocator and want to compile in double precision, make sure you align to JPH_RVECTOR_ALIGNMENT bytes (instead of 16)
|
||||
* The SkeletonPose got a 'root offset' member, this means that the ragdoll will now make the joint transform of the first body zero and put that offset in the 'root offset'.
|
||||
* ContactManifold now stores the contacts relative to mBaseOffset, the arrays containing the contact points have been renamed from mWorldSpaceContactPointsOn1/2 to mRelativeContactPointsOn1/2 to reflect this.
|
||||
* The DebugRenderer::DrawLine function now takes RVec3Arg parameters instead of Float3 parameters.
|
||||
* The format of a recording recorded with DebugRendererRecorder has changed, this invalidates any prior recordings.
|
||||
* 20221128 - MotionProperties::SetMotionQuality has been removed because changing it for an active body could cause crashes. Use BodyInterface::SetMotionQuality instead. (64802d163a7336e60916365ad9bce764cec4ca70)
|
||||
|
||||
## Changes between v1.1.0 and v2.0.0
|
||||
|
||||
* 20221027 - *SBS* (vehicles only) - Rewrote engine model for wheeled vehicle. Before engine inertia was only used when the clutch was pressed, now it is always used, so you may want to use a lower value. The way torque is distributed over the wheels has also changed and may require tweaking the vehicle parameters. (5ac751cee9afcc097fd4f884308f5e4dc9fdaeaf)
|
||||
* 20220903 - *SBS* - Added overrides for number of position/velocity solver iterations. Only affects serialization. (38ec33942ead4968a83409bd13d868f60e6397c4)
|
||||
* 20220826 - *SBS* - Removed FixedConstraintSettings and SliderConstraintSettings SetPoint functions. If you were calling this function replace it by setting mAutoDetectPoint = true. (d16a0b05bfeed42b1618e3774a9c953e6922d22b)
|
||||
* 20220614 - It is now possible to override the memory allocator, register the default using RegisterDefaultAllocator(). This means that the public API now takes STL containers that use a custom memory allocator so use Array instead of vector, UnorderedMap instead of unordered_map etc. If you're using placement new, add ```::``` in front of new. Define JPH_DISABLE_CUSTOM_ALLOCATOR to disable this new behavior (b68097f582148d6f66c18a6ff95c5ca9b40b48cc)
|
||||
* 20220606 - *SBS* - The slider constraint now has frequency and damping for its limits (09d6d9d51c46fbd159bf98abfd43cc639f6c0403)
|
||||
* 20220606 - *SBS* - The rack and pinion and gear constraints were added (09d6d9d51c46fbd159bf98abfd43cc639f6c0403)
|
||||
* 20220517 - Note: Superseded by d16a0b05bfeed42b1618e3774a9c953e6922d22b. When constructing a FixedConstraint you now need to call FixedConstraintSettings::SetPoint to configure the point where the bodies attach (4f7c925c31f39eda1d8d68e4e72456b5def93d9b)
|
||||
* 20220516 - Constraint::GetType was renamed to GetSubType, a new GetType function was introduced (3e2151a009e8f11ca724754b2bd25e14d2654fb6)
|
||||
* 20220516 - *SBS* - Added possibility to save the current state of the physics world as a scene (3e2151a009e8f11ca724754b2bd25e14d2654fb6)
|
||||
* 20220510 - Factory::sInstance must now be allocated by the application prior to calling RegisterTypes() and has changed to a pointer (3ca62973dae7cda7a9ceece698438a45b9ad1433)
|
||||
* 20220503 - Unused function SerializableObject::OnLoaded was removed (388d47254a236c053a472e54c10b264765badc09)
|
||||
* 20220502 - ContactConstraintManager::CombineFunction has additional parameters: the SubShapeIDs from both bodies (6b873563739dfd3d77263c2c50af2f3f418ec15b)
|
||||
* 20220415 - Removed Body::GetDebugName / SetDebugName, keep this info in a lookaside table if you need it (6db4d3beac6760e55f65102db00f93dfbc56ac26)
|
||||
* 20220406 - Renamed CollisionDispatch::sCastShapeVsShape to sCastShapeVsShapeLocalSpace (6ba21f50dcf17bd506080ec30759724a7f3097d8)
|
||||
* 20220327 - Changed the default include path, ```#include <xxx>``` must be replaced by ```#include <Jolt/xxx>``` (06e9d17d385814cd24d3b77d689c0a29d854e194)
|
||||
* 20220318 - Added support for SSE2. If you want to use later versions of SSE make sure you have JPH_USE_SSE4_1 and JPH_USE_SSE4_2 defined (28f363856a007d03f657e46e8f6d90ccd7c6487a)
|
||||
* 20220303 - Note: Partially superseded by d16a0b05bfeed42b1618e3774a9c953e6922d22b. When constructing a SliderConstraint you now need to call SliderConstraintSettings::SetPoint to configure the point where the bodies attach. Also replace mSliderAxis = x with SetSliderAxis(x) (5a327ec182d0436d435c62d0bccb4e76c6324659)
|
||||
* 20220228 - PointConstraint::mCommonPoint is now mPoint1 / mPoint2. Replace mCommonPoint = x with mPoint1 = mPoint2 = x (066dfb8940ba3e7dbf8ed47e9a1eeb194730e04b)
|
||||
* 20220226 - ObjectToBroadPhaseLayer and BroadPhaseLayerToString changed to BroadPhaseLayerInterface, this makes mapping a broadphase layer to an object layer more flexible (36dd3f8c8c31ef1aeb7585b2b615c23bc8b76f13)
|
||||
* 20220222 - Shape and body user data changed from void * / uint32 to uint64 (14e062ac96abd571c6eff5e40b1df4d8b2333f55)
|
||||
|
||||
## Changes between v1.0.0 and v1.1.0
|
||||
|
||||
* No breaking changes.
|
||||
|
||||
## Changes between v0.0.0 and v1.0.0
|
||||
|
||||
* 20220107 - PhysicsSettings::mBodyPairCacheCosMaxDeltaRotation was renamed to mBodyPairCacheCosMaxDeltaRotationDiv2
|
||||
* 20211219 - *SBS* - Now storing 3 components for a Vec3 instead of 4 in SaveBinaryState (23c1b9d9029d74076c0549c8779b3b5ac2179ea3)
|
||||
* 20211212 - Removed StatCollector (92a117e0f05a08de154e86d3cd0b354783aa5593)
|
||||
* 20210711 - HeightFieldShapeSettings::mBlockSize is subdivided one more time at run-time, so this is effectively 2x the block size (2aa3b443bf71785616f3140c32e6a04c49516535)
|
||||
* 20211106 - Mutex class now has its own implementation on Platform Blue, users must implement the JPH_PLATFORM_BLUE_MUTEX_* functions (a61dc67503a87ef0e190f7fb31d495ac51aa43de)
|
||||
* 20211019 - ShapeCast::mShape no longer keeps a reference, the caller is responsible for keeping the reference now (e2bbdda9110b083b49ba323f8fd0d88c19847c2e)
|
||||
* 20211004 - Removed RTTI from Shape class, use Shape::GetType / GetSubType now (6d5cafd53501c2c1e313f1b1f29d5161db074fd5)
|
||||
* 20210930 - Changed RestoreMaterialState and RestoreSubShapeState to use pointers instead of vectors to allow loading shapes with fewer memory allocations (b8953791f35a91fcd12568c7dc4cc2f68f40fb3f)
|
||||
* 20210918 - PhysicsSystem::Init takes an extra parameter to specify the amount of mutexes to use (ef371411af878023f062b9930db09f17411f01ba)
|
||||
* 20210827 - BroadPhaseLayerPairFilter was changed to ObjectVsBroadPhaseLayerFilter to avoid testing too many layers during collision queries (33883574bbc6fe208a4b62054d00b582872da6f4)
|
755
src/JoltPhysics/Docs/Architecture.md
Normal file
@ -0,0 +1,755 @@
|
||||
[TOC]
|
||||
|
||||
# Architecture of Jolt Physics {#architecture-jolt-physics}
|
||||
|
||||
For demos and videos go to the [Samples](Samples.md) section.
|
||||
|
||||
# Bodies {#bodies}
|
||||
|
||||
We use a pretty traditional physics engine setup, so \ref Body "bodies" in our simulation are objects which have attached collision \ref Shape "shapes"
|
||||
|
||||
## Types {#body-types}
|
||||
|
||||
Bodies can either be:
|
||||
- [static](@ref EMotionType) (not moving or simulating)
|
||||
- [dynamic](@ref EMotionType) (moved by forces) or
|
||||
- [kinematic](@ref EMotionType) (moved by velocities only).
|
||||
|
||||
Moving bodies have a [MotionProperties](@ref MotionProperties) object that contains information about the movement of the object. Static bodies do not have this to save space (but they can be configured to have it if a static body needs to become dynamic during its lifetime by setting [BodyCreationSettings::mAllowDynamicOrKinematic](@ref BodyCreationSettings::mAllowDynamicOrKinematic)).
|
||||
|
||||
## Creating Bodies {#creating-bodies}
|
||||
|
||||
Bodies are inserted into the [PhysicsSystem](@ref PhysicsSystem) and interacted with through the [BodyInterface](@ref BodyInterface).
|
||||
|
||||
## Multithreaded Access
|
||||
|
||||
Jolt is designed to be accessed from multiple threads so the body interface comes in two flavors: A locking and a non-locking variant. The locking variant uses a mutex array (a fixed size array of mutexes, bodies are associated with a mutex through hashing and multiple bodies use the same mutex, see [MutexArray](@ref MutexArray)) to prevent concurrent access to the same body. The non-locking variant doesn't use mutexes, so requires the user to be careful.
|
||||
|
||||
In general, body ID's ([BodyID](@ref BodyID)) are used to refer to bodies. You can access a body through the following construct:
|
||||
|
||||
JPH::BodyLockInterface lock_interface = physics_system.GetBodyLockInterface(); // Or GetBodyLockInterfaceNoLock
|
||||
JPH::BodyID body_id = ...; // Obtain ID to body
|
||||
|
||||
// Scoped lock
|
||||
{
|
||||
JPH::BodyLockRead lock(lock_interface, body_id);
|
||||
if (lock.Succeeded()) // body_id may no longer be valid
|
||||
{
|
||||
const JPH::Body &body = lock.GetBody();
|
||||
|
||||
// Do something with body
|
||||
...
|
||||
}
|
||||
}
|
||||
|
||||
When another thread has removed the body between the time the body ID was obtained and the lock, the lock will fail. While the lock is taken, other threads cannot modify the body, so it is safe to work with it. Each body ID contains a sequence number, so body ID's will only be reused after many add/remove cycles. To write to a body use [BodyLockWrite](@ref BodyLockWrite).
|
||||
|
||||
You cannot use BodyLockRead to lock multiple bodies (if two threads lock the same bodies in opposite order you'll get a deadlock). Use [BodyLockMultiRead](@ref BodyLockMultiRead) or [BodyLockMultiWrite](@ref BodyLockMultiWrite) to lock them in a consistent order.
|
||||
|
||||
Note that a lot of convenience functions are exposed through the BodyInterface, but not all functionality is available, so you may need to lock the body to get the pointer and then call the function directly on the body.
|
||||
|
||||
## Single Threaded Access {#single-threaded-access}
|
||||
|
||||
If you're only accessing the physics system from a single thread, you can use Body pointers instead of BodyID's. In this case you can also use the non-locking variant of the body interface.
|
||||
|
||||
Note that there are still some restrictions:
|
||||
|
||||
* You cannot read from / write to bodies or constraints while PhysicsSystem::Update is running. As soon as the Update starts, all body / constraint mutexes are locked.
|
||||
* Collision callbacks (see ContactListener) are called from within the PhysicsSystem::Update call from multiple threads. You can only read the body data during a callback.
|
||||
* Activation callbacks (see BodyActivationListener) are called in the same way. Again you should only read the body during the callback and not make any modifications.
|
||||
* Step callbacks (see PhysicsStepListener) are also called from PhysicsSystem::Update from multiple threads. You're responsible for making sure that there are no race conditions. In a step listener you can read/write bodies or constraints but you cannot add/remove them.
|
||||
|
||||
If you are accessing the physics system from multiple threads, you should probably use BodyID's and the locking variant of the body interface. It is however still possible to use Body pointers if you're really careful. E.g. if there is a clear owner of a Body and you ensure that this owner does not read/write state during PhysicsSystem::Update or while other threads are reading the Body there will not be any race conditions.
|
||||
|
||||
## Shapes {#shapes}
|
||||
|
||||
Each body has a shape attached that determines the collision volume. The following shapes are available (in order of computational complexity):
|
||||
|
||||
* [SphereShape](@ref SphereShape) - A sphere centered around zero.
|
||||
* [BoxShape](@ref BoxShape) - A box centered around zero.
|
||||
* [CapsuleShape](@ref CapsuleShape) - A capsule centered around zero.
|
||||
* [TaperedCapsuleShape](@ref TaperedCapsuleShape) - A capsule with different radii at the bottom and top.
|
||||
* [CylinderShape](@ref CylinderShape) - A cylinder shape. Note that cylinders are the least stable of all shapes, so use another shape if possible.
|
||||
* [ConvexHullShape](@ref ConvexHullShape) - A convex hull defined by a set of points.
|
||||
* [StaticCompoundShape](@ref StaticCompoundShape) - A shape containing other shapes. This shape is constructed once and cannot be changed afterwards. Child shapes are organized in a tree to speed up collision detection.
|
||||
* [MutableCompoundShape](@ref MutableCompoundShape) - A shape containing other shapes. This shape can be constructed/changed at runtime and trades construction time for runtime performance. Child shapes are organized in a list to make modification easy.
|
||||
* [MeshShape](@ref MeshShape) - A shape consisting of triangles. They are mostly used for static geometry.
|
||||
* [HeightFieldShape](@ref HeightFieldShape) - A shape consisting of NxN points that define the height at each point, very suitable for representing hilly terrain. Any body that uses this shape needs to be static.
|
||||
|
||||
Next to this there are a number of decorator shapes that change the behavior of their children:
|
||||
|
||||
* [ScaledShape](@ref ScaledShape) - This shape can scale a child shape. Note that if a shape is rotated first and then scaled, you can introduce shearing which is not supported by the library.
|
||||
* [RotatedTranslatedShape](@ref RotatedTranslatedShape) - This shape can rotate and translate a child shape, it can e.g. be used to offset a sphere from the origin.
|
||||
* [OffsetCenterOfMassShape](@ref OffsetCenterOfMassShape) - This shape does not change its child shape but it does shift the calculated center of mass for that shape. It allows you to e.g. shift the center of mass of a vehicle down to improve its handling.
|
||||
|
||||
### Dynamic Mesh Shapes {#dynamic-mesh-shapes}
|
||||
|
||||
Meshes are usually static, but they can be made kinematic or dynamic provided that they don't collide with other mesh- or heightfield shapes (an assert will trigger when this happens and the collision will be ignored).
|
||||
|
||||
Mesh shapes also cannot calculate their mass and inertia, so when you want a dynamic mesh, you need to provide these yourself by setting BodyCreationSettings::mOverrideMassProperties = EOverrideMassProperties::MassAndInertiaProvided and supplying the mass and inertia in BodyCreationSettings::mMassPropertiesOverride.
|
||||
|
||||
An example can be found [here](https://github.com/jrouwe/JoltPhysics/blob/master/Samples/Tests/General/DynamicMeshTest.cpp).
|
||||
|
||||
Note that you should try to avoid dynamic mesh shapes as they are fairly expensive to simulate. Also, mesh shapes don't have a clear inside/outside so a mesh is only considered to be colliding when one of its triangles intersect with the other object. This can result in objects getting stuck inside the mesh without knowing which way is out.
|
||||
|
||||
### Creating Shapes {#creating-shapes}
|
||||
|
||||
Simple shapes like spheres and boxes can be constructed immediately by simply new-ing them. Other shapes need to be converted into an optimized format in order to be usable in the physics simulation. The uncooked data is usually stored in a [ShapeSettings](@ref ShapeSettings) object and then converted to cooked format by a [Create](@ref ShapeSettings::Create) function that returns a [Result](@ref Result) object that indicates success or failure and provides the cooked object.
|
||||
|
||||
Creating a convex hull for example looks like:
|
||||
|
||||
// Shapes are refcounted and can be shared between bodies
|
||||
JPH::Ref<Shape> shape;
|
||||
|
||||
// The ShapeSettings object is only required for building the shape, all information is copied into the Shape class
|
||||
{
|
||||
// Create an array of vertices
|
||||
JPH::Array<JPH::Vec3> vertices = { ... };
|
||||
|
||||
// Create the settings object for a convex hull
|
||||
JPH::ConvexHullShapeSettings settings(vertices, JPH::cDefaultConvexRadius);
|
||||
|
||||
// Create shape
|
||||
JPH::Shape::ShapeResult result = settings.Create();
|
||||
if (result.IsValid())
|
||||
shape = result.Get();
|
||||
else
|
||||
... // Error handling
|
||||
}
|
||||
|
||||
Note that after you call Create, the shape is cached and ShapeSettings keeps a reference to your shape (see @ref memory-management). If you call Create again, the same shape will be returned regardless of what changed to the settings object (unless you call [ClearCachedResult](@ref ShapeSettings::ClearCachedResult) to clear the cache).
|
||||
|
||||
### Saving Shapes {#saving-shapes}
|
||||
|
||||
There are two ways of serializing data:
|
||||
|
||||
* The uncooked data can be serialized using the [ObjectStream](@ref ObjectStream) system (either in [binary](@ref ObjectStreamBinaryOut) or in [text](@ref ObjectStreamTextOut) format), data stored in this way is likely to be compatible with future versions of the library (although there is no 100% guarantee of this).
|
||||
* The cooked data can be serialized using the [SaveBinaryState](@ref Shape::SaveBinaryState) interface that various objects provide. Data stored in this way is optimized for simulation performance and loading speed but is very likely to change between versions of the library, so this should never be your primary data format.
|
||||
|
||||
An example of saving a shape in binary format:
|
||||
|
||||
// Create a sphere of radius 1
|
||||
JPH::Ref<Shape> sphere = new JPH::SphereShape(1.0f);
|
||||
|
||||
// For this example we'll be saving the shape in a STL string stream, but if you implement StreamOut you don't have to use STL.
|
||||
stringstream data;
|
||||
JPH::StreamOutWrapper stream_out(data);
|
||||
|
||||
// Save the shape (note this function handles CompoundShape too).
|
||||
// The maps are there to avoid saving the same shape twice (it will assign an ID to each shape the first time it encounters them).
|
||||
// If you don't want certain shapes to be saved, add them to the map and give them an ID.
|
||||
// You can save many shapes to the same stream by repeatedly calling SaveWithChildren on different shapes.
|
||||
JPH::Shape::ShapeToIDMap shape_to_id;
|
||||
JPH::Shape::MaterialToIDMap material_to_id;
|
||||
sphere->SaveWithChildren(stream_out, shape_to_id, material_to_id);
|
||||
|
||||
// Wrap the STL stream in a StreamIn
|
||||
JPH::StreamInWrapper stream_in(data);
|
||||
|
||||
// Load the shape
|
||||
// If you have assigned custom ID's on save, you need to ensure that the shapes exist in this map on restore too.
|
||||
JPH::Shape::IDToShapeMap id_to_shape;
|
||||
JPH::Shape::IDToMaterialMap id_to_material;
|
||||
JPH::Shape::ShapeResult result = JPH::Shape::sRestoreWithChildren(stream_in, id_to_shape, id_to_material);
|
||||
|
||||
JPH::Ref<Shape> restored_shape;
|
||||
if (result.IsValid())
|
||||
restored_shape = result.Get();
|
||||
else
|
||||
... // Error handling
|
||||
|
||||
As the library does not offer an exporter from content creation packages and since most games will have their own content pipeline, we encourage you to store data in your own format, cook data while cooking the game data and store the result using the SaveBinaryState interface (and provide a way to force a re-cook when the library is updated).
|
||||
|
||||
### Convex Radius {#convex-radius}
|
||||
|
||||
In order to speed up the collision detection system, all convex shapes use a convex radius. The provided shape will first be shrunken by the convex radius and then inflated again by the same amount, resulting in a rounded off shape:
|
||||
|
||||

|
||||
|
||||
### Center of Mass {#center-of-mass}
|
||||
|
||||
__Beware: When a shape is created, it will automatically recenter itself around its center of mass.__ The center of mass can be obtained by calling [Shape::GetCenterOfMass](@ref Shape::GetCenterOfMass) and most functions operate in this Center of Mass (COM) space. Some functions work in the original space the shape was created in, they usually have World Space (WS) or Shape Space (SS) in their name (or documentation).
|
||||
|
||||

|
||||
|
||||
As an example, say we create a box and then translate it:
|
||||
|
||||
// Create box of 2x2x2 m (you specify half the side)
|
||||
JPH::BoxShapeSettings box(JPH::Vec3(1, 1, 1));
|
||||
JPH::Ref<Shape> box_shape = box.Create().Get();
|
||||
|
||||
// Offset it by 10 m
|
||||
JPH::RotatedTranslatedShapeSettings translated_box(JPH::Vec3(10, 0, 0), JPH::Quat::sIdentity(), box_shape);
|
||||
JPH::Ref<Shape> translated_box_shape = translated_box.Create().Get();
|
||||
|
||||
// Cast a ray against the offset box (WRONG!)
|
||||
JPH::RayCast ray;
|
||||
ray.mOrigin = JPH::Vec3(10, 2, 0);
|
||||
ray.mDirection = JPH::Vec3(0, -2, 0);
|
||||
|
||||
// Cast ray
|
||||
JPH::RayCastResult hit;
|
||||
bool had_hit = translated_box_shape->CastRay(ray, JPH::SubShapeIDCreator(), hit);
|
||||
JPH_ASSERT(!had_hit); // There's no hit because we did not correct for COM!
|
||||
|
||||
// Convert the ray to center of mass space for the shape (CORRECT!)
|
||||
ray.mOrigin -= translated_box_shape->GetCenterOfMass();
|
||||
|
||||
// Cast ray
|
||||
had_hit = translated_box_shape->CastRay(ray, JPH::SubShapeIDCreator(), hit);
|
||||
JPH_ASSERT(had_hit); // Ray was in COM space, now there's a hit!
|
||||
|
||||
In the same way calling:
|
||||
|
||||
translated_box_shape->GetLocalBounds();
|
||||
|
||||
will return a box of size 2x2x2 centered around the origin, so in order to get it back to the space in which it was originally created you need to offset the bounding box:
|
||||
|
||||
JPH::AABox shape_bounds = translated_box_shape->GetLocalBounds();
|
||||
shape_bounds.Translate(translated_box_shape->GetCenterOfMass());
|
||||
JPH_ASSERT(shape_bounds == JPH::AABox(JPH::Vec3(9, -1, -1), JPH::Vec3(11, 1, 1))); // Now we have the box relative to how we created it
|
||||
|
||||
Note that when you work with interface of [BroadPhaseQuery](@ref BroadPhaseQuery), [NarrowPhaseQuery](@ref NarrowPhaseQuery) or [TransformedShape](@ref TransformedShape) this transformation is done for you.
|
||||
|
||||
### Creating Custom Shapes {#creating-custom-shapes}
|
||||
|
||||
If the defined Shape classes are not sufficient, or if your application can make a more efficient implementation because it has specific domain knowledge, it is possible to create a custom collision shape:
|
||||
|
||||
* Derive a new class from Shape (e.g. MyShape). If your shape is convex you can consider deriving from ConvexShape, if it contains multiple sub shapes you can derive from CompoundShape or if it wraps a single other shape it can be derived from DecoratedShape.
|
||||
* Create a settings class that configures your shape (e.g. MyShapeSettings) and inherit it from the corresponding settings class (e.g. ShapeSettings, CompoundShapeSettings or DecoratedShapeSettings).
|
||||
* Override the ```MyShapeSettings::Create``` function to construct an instance of MyShape.
|
||||
* If you want to serialize the settings class, register it with the factory: ```Factory::sInstance->Register(RTTI_OF(MyShapeSettings))```
|
||||
* If you inherited from Shape you need to select a shape type, use e.g. ```EShapeType::User1```
|
||||
* In all cases you will need to specify a sub shape type, use e.g. ```EShapeSubType::User1```
|
||||
* If you inherited from ConvexShape you can also specify a convex sub shape type, e.g. ```EShapeSubType::UserConvex1```, in which case you don't need to implement or register the collision detection functions mentioned below.
|
||||
* Implement the virtual functions that your selected base class exposes. Some functions could be implemented as a dummy if you don't care about the functionality, e.g. if you don't care about buoyancy then GetSubmergedVolume does not need to be implemented.
|
||||
* Create a ```MyShape::sRegister()``` function to register all collision functions, make sure you call this function after calling ```RegisterTypes()```, see [MeshShape::sRegister](@ref MeshShape::sRegister) for an example.
|
||||
* Now write collision detection functions to test collision with all other shape types that this shape could collide with and register them with [CollisionDispatch::sRegisterCollideShape](@ref CollisionDispatch::sRegisterCollideShape) and [CollisionDispatch::sRegisterCastShape](@ref CollisionDispatch::sRegisterCastShape). This can be a lot of work, but there are some helper functions that you can use to reduce the work:
|
||||
* If you have implemented a collision test for type A vs B then you can register [CollisionDispatch::sReversedCastShape](@ref CollisionDispatch::sReversedCastShape) and [CollisionDispatch::sReversedCollideShape](@ref CollisionDispatch::sReversedCollideShape) for B vs A.
|
||||
* If your shape is triangle based, you can forward the testing of a shape vs a single triangle to the [CollideConvexVsTriangles](@ref CollideConvexVsTriangles) and [CastConvexVsTriangles](@ref CastConvexVsTriangles) classes.
|
||||
* If your shape contains sub shapes and you have determined that the shape intersects with one of the sub shapes you can forward the sub shape to the collision dispatch again through [CollisionDispatch::sCollideShapeVsShape](@ref CollisionDispatch::sCollideShapeVsShape) and [CollisionDispatch::sCastShapeVsShapeLocalSpace](@ref CollisionDispatch::sCastShapeVsShapeLocalSpace).
|
||||
|
||||
## Sensors {#sensors}
|
||||
|
||||
Sensors are normal rigid bodies that report contacts with other Dynamic or Kinematic bodies through the [ContactListener](@ref ContactListener) interface. Any detected penetrations will however not be resolved. Sensors can be used to implement triggers that detect when an object enters their area.
|
||||
|
||||
The cheapest sensor has a Static motion type. This type of sensor will only detect active bodies entering their area. As soon as a body goes to sleep, the contact will be lost. Note that you can still move a Static sensor around using [BodyInterface::SetPosition](@ref BodyInterface::SetPosition).
|
||||
|
||||
When you make a sensor Kinematic or Dynamic and activate it, it will also detect collisions with sleeping bodies, albeit with a higher run-time cost.
|
||||
|
||||
To create a sensor, either set [BodyCreationSettings::mIsSensor](@ref BodyCreationSettings::mIsSensor) to true when constructing a body or set it after construction through [Body::SetIsSensor](@ref Body::SetIsSensor). A sensor can only use the discrete motion quality type at this moment.
|
||||
|
||||
To make sensors detect collisions with static objects, set the [BodyCreationSettings::mCollideKinematicVsNonDynamic](@ref BodyCreationSettings::mCollideKinematicVsNonDynamic) to true or call [Body::SetCollideKinematicVsNonDynamic](@ref Body::SetCollideKinematicVsNonDynamic). Note that it can place a large burden on the collision detection system if you have a large sensor intersect with e.g. a large mesh terrain or a height field as you will get many contact callbacks and these contacts will take up a lot of space in the contact cache. Ensure that your sensor is in an object layer that collides with as few static bodies as possible.
|
||||
|
||||
## Sleeping {#sleeping-bodies}
|
||||
|
||||
During the simulation step, bodies are divided in 'islands'. Each island consists of a set of dynamic bodies that are either in contact with each other, or that are connected through a constraint:
|
||||
|
||||

|
||||
|
||||
At the end of each step, all the bodies in an island are checked to see if they have come to rest, if this is the case then the entire island is put to sleep. When a body is sleeping, it can still detect collisions with other objects that are not sleeping, but it will not move or otherwise participate in the simulation to conserve CPU cycles. Sleeping bodies wake up automatically when they're in contact with non-sleeping objects or they can be explicitly woken through an API call like BodyInterface::ActivateBody. Unlike some other physics engines, removing a Body from the world doesn't wake up any surrounding bodies. If you want this you can call BodyInterface::ActivateBodiesInAABox with the bounding box of the removed body (or the combined bounding box if you're removing multiple bodies). Also, things like setting the velocity through Body::SetLinearVelocity will not wake up the Body, use BodyInterface::SetLinearVelocity instead. You can configure the definition of a body 'at rest' through PhysicsSettings::mTimeBeforeSleep and PhysicsSettings::mPointVelocitySleepThreshold.
|
||||
|
||||
## Soft Bodies {#soft-bodies}
|
||||
|
||||
Soft bodies (also known as deformable bodies) can be used to create e.g. a soft ball or a piece of cloth. They are created in a very similar way to normal rigid bodies:
|
||||
|
||||
* First allocate a new SoftBodySharedSettings object on the heap. This object will contain the initial positions of all particles and the constraints between the particles. This object can be shared between multiple soft bodies and should remain constant during its lifetime.
|
||||
* Then create a SoftBodyCreationSettings object (e.g. on the stack) and fill in the desired properties of the soft body.
|
||||
* Finally construct the body and add it to the world through BodyInterface::CreateAndAddSoftBody.
|
||||
|
||||
Soft bodies use the Body class just like rigid bodies but can be identified by checking Body::IsSoftBody. To get to the soft body state, cast the result of Body::GetMotionProperties to SoftBodyMotionProperties and use its API.
|
||||
|
||||
Soft bodies try to implement as much as possible of the normal Body interface, but this interface provides a simplified version of reality, e.g. Body::GetLinearVelocity will return the average particle speed and Body::GetPosition returns the average particle position. During simulation, a soft body will never update its rotation. Internally it stores particle velocities in local space, so if you rotate a soft body e.g. by calling BodyInterface::SetRotation, the body will rotate but its velocity will as well.
|
||||
|
||||
### Soft Body Contact Listeners {#soft-body-contact-listener}
|
||||
|
||||
Soft Bodies provide contacts with other bodies through the SoftBodyContactListener class. This contact listener works a little bit different from the normal contact listener as you will not receive a contact callback per colliding vertex.
|
||||
|
||||
After the broad phase has detected an overlap and the normal layer / collision group filters have had a chance to reject the collision, you will receive a SoftBodyContactListener::OnSoftBodyContactValidate callback. This callback allows you to specify how the vertices of the soft body should interact with the other body. You can override the mass for both bodies and you can turn the contact into a sensor contact.
|
||||
|
||||
The simulation will then proceed to do all collision detection and response and after that is finished, you will receive a SoftBodyContactListener::OnSoftBodyContactAdded callback that allows you to inspect all collisions that happened during the simulation step. In order to do this a SoftBodyManifold is provided which allows you to loop over the vertices and ask each vertex what it collided with.
|
||||
|
||||
Note that at the time of the callback, multiple threads are operating at the same time. The soft body is stable and can be safely read. The other body that is collided with is not stable however, so you cannot safely read its position/orientation and velocity as it may be modified by another soft body collision at the same time.
|
||||
|
||||
### Skinning Soft Bodies {#skinning-soft-bodies}
|
||||
|
||||
Using the [skinning](@ref SoftBodySharedSettings::Skinned) constraints, a soft body can be (partially) skinned to joints. This can be used e.g. to partially drive cloth with a character animation. The [vertices](@ref SoftBodySharedSettings::Vertex::mPosition) of the soft body need to be placed in the neutral pose of the character and the joints for this pose need to be calculated in model space (relative to these vertices). The inverted matrices of this neutral pose need to be stored as the [inverse bind matrices](@ref SoftBodySharedSettings::InvBind) and the skinning constraints can then be [weighted](@ref SoftBodySharedSettings::SkinWeight) to these joints. SoftBodySharedSettings::CalculateSkinnedConstraintNormals must be called to gather information needed to calculate the face normals at run-time.
|
||||
|
||||
At run-time, you need to provide the animated joints every simulation step through the SoftBodyMotionProperties::SkinVertices call. During simulation, each skinned vertex will calculate its position and this position will be used to limit the movement of its simulated counterpart.
|
||||
|
||||

|
||||
|
||||
The adjacent faces of the soft body will be used to calculate the normal of each vertex (shown in red), the vertex is then free to move inside the sphere formed by the skinned vertex position with radius [MaxDistance](@ref SoftBodySharedSettings::Skinned::mMaxDistance) (green sphere). To prevent the vertex from intersecting with the character, it is possible to specify a [BackStopDistance](@ref SoftBodySharedSettings::Skinned::mBackStopDistance) and [BackStopRadius](@ref SoftBodySharedSettings::Skinned::mBackStopRadius), together these form the red sphere. The vertex is not allowed to move inside this sphere.
|
||||
|
||||
### Soft Body Work In Progress {#soft-body-wip}
|
||||
|
||||
Soft bodies are currently in development, please note the following:
|
||||
|
||||
* Soft bodies can only collide with rigid bodies, collisions between soft bodies are not implemented yet.
|
||||
* AddForce/AddTorque/SetLinearVelocity/SetLinearVelocityClamped/SetAngularVelocity/SetAngularVelocityClamped/AddImpulse/AddAngularImpulse have no effect on soft bodies as the velocity is stored per particle rather than per body.
|
||||
* Buoyancy calculations have not been implemented yet.
|
||||
* Constraints cannot operate on soft bodies, set the inverse mass of a particle to zero and move it by setting a velocity to constrain a soft body to something else.
|
||||
* When calculating friction / restitution an empty SubShapeID will be passed to the ContactConstraintManager::CombineFunction because this is called once per body pair rather than once per sub shape as is common for rigid bodies.
|
||||
|
||||
# Constraints {#constraints}
|
||||
|
||||
Bodies can be connected to each other using constraints ([Constraint](@ref Constraint)).
|
||||
|
||||
The following constraints are available:
|
||||
|
||||
* [FixedConstraint](@ref FixedConstraintSettings) - Will attach a body to another without any degrees of freedom.
|
||||
* [DistanceConstraint](@ref DistanceConstraintSettings) - Will attach two bodies with a stick (removing 1 degree of freedom).
|
||||
* [PointConstraint](@ref PointConstraintSettings) - Will attach two bodies in a single point (removing 3 degrees of freedom)
|
||||
* [HingeConstraint](@ref HingeConstraintSettings) - Will attach two bodies through a hinge.
|
||||
* [ConeConstraint](@ref ConeConstraintSettings) - Attaches two bodies in a point and will limit the rotation within a cone.
|
||||
* [SliderConstraint](@ref SliderConstraintSettings) - Attaches two bodies and allows only movement in a single translation axis (also known as prismatic constraint).
|
||||
* [SwingTwistConstraint](@ref SwingTwistConstraintSettings) - Attaches two bodies using a point constraint and a swing-twist constraint which approximates the shoulder joint of a human.
|
||||
* [SixDOFConstraint](@ref SixDOFConstraintSettings) - The most configurable joint allows specifying per translation axis and rotation axis what the limits are.
|
||||
* [PathConstraint](@ref PathConstraintSettings) - This constraint allows attaching two bodies connected through a Hermite spline path.
|
||||
* [GearConstraint](@ref GearConstraintSettings) - This constraint connects to two hinge joints and constrains them to connect two gears.
|
||||
* [RackAndPinionConstraint](@ref RackAndPinionConstraintSettings) - This constraint connects a hinge and a slider constraint to connect a rack and pinion.
|
||||
* [PulleyConstraint](@ref PulleyConstraintSettings) - This constraint connects two bodies through two fixed points creating something that behaves like two bodies connected through a rope.
|
||||
* [VehicleConstraint](@ref VehicleConstraintSettings) - This constraint adds virtual wheels or tracks to a body and allows it to behave as a vehicle.
|
||||
|
||||
If you want to constrain a dynamic object to the unmovable 'world' you can use [Body::sFixedToWorld](@ref Body::sFixedToWorld) instead of creating a static body.
|
||||
|
||||
Bodies do not keep track of the constraints that are connected to them. This means that you're responsible for removing any constraints attached to a body before removing the body from the PhysicsSystem.
|
||||
|
||||
Adding and removing constraints can be done from multiple threads, but the constraints themselves do not have any protection against concurrent access. We assume that constraints are owned by some object (e.g. a Ragdoll) and that object ensures that it only modifies its own constraints and contains its own synchronization logic. Constraints can be freely modified except during the physics simulation step.
|
||||
|
||||
Contact constraints (when bodies collide) are not handled through the [Constraint](@ref Constraint) class but through the [ContactConstraintManager](@ref ContactConstraintManager) which is considered an internal class.
|
||||
|
||||
## Constraint Motors {#constraint-motors}
|
||||
|
||||
Most of the constraints support motors (see [MotorSettings](@ref MotorSettings)) which allow you to apply forces/torques on two constrained bodies to drive them to a relative position/orientation. There are two types of motors:
|
||||
* Linear motors: These motors drive the relative position between two bodies. A linear motor would, for example, slide a body along a straight line when you use a slider constraint.
|
||||
* Angular motors: These motors drive the relative rotation between two bodies. An example is a hinge constraint. The motor drives the rotation along the hinge axis.
|
||||
|
||||
Motors can have three states (see [EMotorState](@ref EMotorState) or e.g. SliderConstraint::SetMotorState):
|
||||
* Off: The motor is not doing any work.
|
||||
* Velocity: This type of motor drives the relative velocity between bodies. For a slider constraint, you would push the bodies towards/away from each other with constant velocity. For a hinge constraint, you would rotate the bodies relative to each other with constant velocity. Set the target velocity through e.g. SliderConstraint::SetTargetVelocity / HingeConstraint::SetTargetAngularVelocity.
|
||||
* Position: This type of motor drives the relative position between bodies. For a slider constraint, you can specify the relative distance you want to achieve between the bodies. For a hinge constraint you can specify the relative angle you want to achieve between the bodies. Set the target position through e.g. SliderConstraint::SetTargetPosition / HingeConstraint::SetTargetAngle.
|
||||
|
||||
Motors apply a force (when driving position) or torque (when driving angle) every simulation step to achieve the desired velocity or position. You can control the maximum force/torque that the motor can apply through MotorSettings::mMinForceLimit, MotorSettings::mMaxForceLimit, MotorSettings::mMinTorqueLimit and MotorSettings::mMaxTorqueLimit. Note that if a motor is driving to a position, the torque limits are not used. If a constraint is driving to an angle, the force limits are not used.
|
||||
|
||||
Usually the limits are symmetric, so you would set -mMinForceLimit = mMaxForceLimit. This way the motor can push at an equal rate as it can pull. If you would set the range to e.g. [0, FLT_MAX] then the motor would only be able to push in the positive direction. The units for the force limits are Newtons and the values can get pretty big. If your motor doesn't seem to do anything, chances are that you have set the value too low. Since Force = Mass * Acceleration you can calculate the approximate force that a motor would need to supply in order to be effective. Usually the range is set to [-FLT_MAX, FLT_MAX] which lets the motor achieve its target as fast as possible.
|
||||
|
||||
For an angular motor, the units are Newton Meters. The formula is Torque = Inertia * Angular Acceleration. Inertia of a solid sphere is 2/5 * Mass * Radius^2. You can use this to get a sense of the amount of torque needed to get the angular acceleration you want. Again, you'd usually set the range to [-FLT_MAX, FLT_MAX] to not limit the motor.
|
||||
|
||||
When settings the force or torque limits to [-FLT_MAX, FLT_MAX] a velocity motor will accelerate the bodies to the desired relative velocity in a single time step (if no other forces act on those bodies).
|
||||
|
||||
Position motors have two additional parameters: Frequency (MotorSettings::mSpringSettings.mFrequency, Hz) and damping (MotorSettings::mSpringSettings.mDamping, no units). They are implemented as described in [Soft Constraints: Reinventing The Spring - Erin Catto - GDC 2011](https://box2d.org/files/ErinCatto_SoftConstraints_GDC2011.pdf).
|
||||
|
||||
You can see a position motor as a spring between the target position and the rigid body. The force applied to reach the target is linear with the distance between current position and target position. When there is no damping, the position motor will cause the rigid body to oscillate around its target.
|
||||
|
||||

|
||||
|
||||
Valid frequencies are in the range (0, 0.5 * simulation frequency]. A frequency of 0 results in no force being applied, a frequency larger than half of the physics simulation frequency will result in instability. For a 60 Hz physics simulation, 20 is a good value for a stiff spring (without damping it will reach its target in 1/(4 * 20) = 0.0125 s), 2 is good for a soft spring (will reach its target in 1/(4 * 2) = 0.125 s).
|
||||
|
||||
In order to prevent the motor from overshooting its target, we use damping.
|
||||
|
||||

|
||||
|
||||
Sensible values for damping are [0, 1] but higher values are also possible. When the damping is below 1, the body will still oscillate around its target, but that oscillation will die out. When the damping is 1 (called critical damping) there is no oscillation at all but it will take longer for the motor to reach its target. When damping is bigger than 1, the system is over dampened. There will not be any oscillation, but it will take even longer for the motor to reach its target.
|
||||
|
||||
Because Jolt Physics uses a Symplectic Euler integrator, there will still be a small amount of damping when damping is 0, so you cannot get infinite oscillation (allowing this would make it very likely for the system to become unstable).
|
||||
|
||||
## Breakable Constraints {#breakable-constraints}
|
||||
|
||||
Constraints can be turned on / off by calling Constraint::SetEnabled. After every simulation step, check the total 'lambda' applied on each constraint and disable the constraint if the value goes over a certain threshold. Use e.g. SliderConstraint::GetTotalLambdaPosition / HingeConstraint::GetTotalLambdaRotation. You can see 'lambda' as the linear/angular impulse applied at the constraint in the last physics step to keep the constraint together.
|
||||
|
||||
# Collision Detection {#collision-detection}
|
||||
|
||||
## Broad Phase {#broad-phase}
|
||||
|
||||
When bodies are added to the PhysicsSystem, they are inserted in the broad phase ([BroadPhaseQuadTree](@ref BroadPhaseQuadTree)). This provides quick coarse collision detection based on the axis aligned bounding box (AABB) of a body.
|
||||
|
||||

|
||||
|
||||
Our broad phase is a quad tree, which means each node has 4 children. In the following image you see a random collection of spheres and triangles and a possible way to split the tree.
|
||||
|
||||

|
||||
|
||||
At the highest level we split all objects in 4 mostly disjoint sets. Note that nodes are allowed to overlap, but for efficiency reasons we want the amount of overlap to be minimal. The example split here is indicated by a red, blue, green and yellow box and you can see them appear in the tree on the right. Three out of four nodes: blue, yellow and red, have 4 or less shapes in them, so the tree can directly point at the shapes rather than at a next node. One node: green, has more than 4 shapes in it so needs a further split. The three shapes can be added directly to the node and we need to create a new node, dotted green, to hold the last two shapes. The reason why we pick 4 children is that modern CPUs support doing 4 math operations in a single instruction, so when we walk the tree from top to bottom during a collision query, we can handle 4 children at the same time and quickly get to a minimal set of colliding objects.
|
||||
|
||||
Since we want to access bodies concurrently the broad phase has special behavior. When a body moves, all nodes in the AABB tree from root to the node where the body resides will be expanded using a lock-free approach. This way multiple threads can move bodies at the same time without requiring a lock on the broad phase. Nodes that have been expanded are marked and during the next physics step a new tight-fitting tree will be built in the background while the physics step is running. This new tree will replace the old tree before the end of the simulation step. This is possible since no bodies can be added/removed during the physics step. For more information about this see the [GDC 2022 talk](https://jrouwe.nl/architectingjolt/ArchitectingJoltPhysics_Rouwe_Jorrit_Notes.pdf).
|
||||
|
||||
The broad phase is divided in layers (BroadPhaseLayer), each broad phase layer has an AABB quad tree associated with it. A standard setup would be to have at least 2 broad phase layers: One for all static bodies (which is infrequently updated but is expensive to update since it usually contains most bodies) and one for all dynamic bodies (which is updated every simulation step but cheaper to update since it contains fewer objects). In general you should only have a few broad phase layers as there is overhead in querying and maintaining many different broad phase trees.
|
||||
|
||||
When doing a query against the broad phase ([BroadPhaseQuery](@ref BroadPhaseQuery)), you generally will get a body ID for intersecting objects. If a collision query takes a long time to process the resulting bodies (e.g. across multiple simulation steps), you can safely keep using the body ID's as specified in the @ref bodies section.
|
||||
|
||||
## Narrow Phase {#narrow-phase}
|
||||
|
||||
A narrow phase query ([NarrowPhaseQuery](@ref NarrowPhaseQuery)) will first query the broad phase for intersecting bodies and will under the protection of a body lock construct a transformed shape ([TransformedShape](@ref TransformedShape)) object. This object contains the transform, a reference counted shape and a body ID. Since the shape will not be deleted until you destroy the TransformedShape object, it is a consistent snapshot of the collision information of the body. This ensures that the body is only locked for a short time frame and makes it possible to do the bulk of the collision detection work outside the protection of a lock.
|
||||
|
||||
For very long running jobs (e.g. navigation mesh creation) it is possible to query all transformed shapes in an area and then do the processing work using a long running thread without requiring additional locks (see [NarrowPhaseQuery::CollectTransformedShapes](@ref NarrowPhaseQuery::CollectTransformedShapes)).
|
||||
|
||||
The narrow phase queries are all handled through the [GJK](@ref GJKClosestPoint) and [EPA](@ref EPAPenetrationDepth) algorithms.
|
||||
|
||||
## Collision Filtering {#collision-filtering}
|
||||
|
||||
Each Body is in an [ObjectLayer](@ref ObjectLayer). If two object layers don't collide, the bodies inside those layers cannot collide. You can define object layers in any way you like, it could be a simple number from 0 to N or it could be a bitmask. Jolt supports 16 or 32 bit ObjectLayers through the JPH_OBJECT_LAYER_BITS define and you're free to define as many as you like as they don't incur any overhead in the system.
|
||||
|
||||
When constructing the PhysicsSystem you need to provide a number of filtering interfaces:
|
||||
* BroadPhaseLayerInterface: This class defines a mapping from ObjectLayer to BroadPhaseLayer through the BroadPhaseLayerInterface::GetBroadPhaseLayer function. Each Body can only be in 1 BroadPhaseLayer so an ObjectLayer maps to 1 BroadphaseLayer. In general there will be multiple ObjectLayers mapping to the same BroadPhaseLayer (because each broad phase layer comes at a cost). If there are multiple object layers in a single broad phase layer, they are stored in the same tree. When a query visits the tree it will visit all objects whose AABB overlaps with the query and only when the overlap is detected, the actual object layer will be checked. This means that you should carefully design which object layers end up in which broad phase layer, balancing the requirement of having few broad phase layers with the number of needless objects that are visited because multiple object layers share the same broad phase layer. You can define JPH_TRACK_BROADPHASE_STATS to let Jolt print out some statistics about the query patterns your application is using. In general it is wise to start with only 2 broad phase layers as listed in the \ref broad-phase section.
|
||||
* ObjectVsBroadPhaseLayerFilter: This class defines a ObjectVsBroadPhaseLayerFilter::ShouldCollide function that checks if an ObjectLayer collides with objects that reside in a particular BroadPhaseLayer. ObjectLayers can collide with as many BroadPhaseLayers as needed, so it is possible for a collision query to visit multiple broad phase trees.
|
||||
* ObjectLayerPairFilter: This class defines a ObjectLayerPairFilter::ShouldCollide function that checks if an ObjectLayer collides with another ObjectLayer.
|
||||
|
||||
As an example we will use a simple enum as ObjectLayer:
|
||||
* NON_MOVING - Layer for all static objects.
|
||||
* MOVING - Layer for all regular dynamic bodies.
|
||||
* DEBRIS - Layer for all debris dynamic bodies, we want to test these only against the static geometry because we want to save some simulation cost.
|
||||
* BULLET - Layer for high detail collision bodies that we attach to regular dynamic bodies. These are not used for simulation but we want extra precision when we shoot with bullets.
|
||||
* WEAPON - This is a query layer so we don't create any bodies with this layer but we use it when doing ray cast querying for our weapon system.
|
||||
|
||||
We define the following object layers to collide:
|
||||
* MOVING vs NON_MOVING, MOVING vs MOVING - These are for our regular dynamic objects that need to collide with the static world and with each other.
|
||||
* DEBRIS vs NON_MOVING - As said, we only want debris to collide with the static world and not with anything else.
|
||||
* WEAPON vs BULLET, WEAPON vs NON_MOVING - We want our weapon ray cast to hit the high detail BULLET collision instead of the normal MOVING collision and we want bullets to be blocked by the static world (obviously the static world could also have a high detail version, but not in this example).
|
||||
|
||||
This means that we need to implement a ObjectLayerPairFilter::ShouldCollide that returns true for the permutations listed above. Note that if ShouldCollide(A, B) returns true, ShouldCollide(B, A) should return true too.
|
||||
|
||||
We define the following broad phase layers:
|
||||
* BP_NON_MOVING - For everything static (contains object layer: NON_MOVING).
|
||||
* BP_MOVING - The default layer for dynamic objects (contains object layers: MOVING, BULLET).
|
||||
* BP_DEBRIS - An extra layer that contains only debris (contains object layers: DEBRIS).
|
||||
|
||||
This means we now implement a BroadPhaseLayerInterface::GetBroadPhaseLayer that maps: NON_MOVING -> BP_NON_MOVING, MOVING -> BP_MOVING, BULLET -> BP_MOVING and DEBRIS -> BP_DEBRIS. We can map WEAPON to anything as we won't create any objects with this layer.
|
||||
|
||||
We also need to implement a ObjectVsBroadPhaseLayerFilter::ShouldCollide that determines which object layer should collide with what broad phase layers, these can be deduced from the two lists above:
|
||||
* NON_MOVING: BP_MOVING, BP_DEBRIS
|
||||
* MOVING: BP_NON_MOVING, BP_MOVING
|
||||
* DEBRIS: BP_NON_MOVING
|
||||
* BULLET: None (these are not simulated so need no collision with other objects)
|
||||
* WEAPON: BP_NON_MOVING, BP_MOVING
|
||||
|
||||
So you can see now that when we simulate DEBRIS we only need to visit a single broad phase tree to check for collision, we did this because in our example we know that there are going to be 1000s of debris objects so it is important that their queries are as fast as possible. We could have moved the BULLET layer to its own broad phase layer too because now BP_MOVING contains a lot of bodies that WEAPON is not interested in, but in this example we didn't because we know that there are not enough of these objects for this to be a performance problem.
|
||||
|
||||
For convenience two filtering implementations are provided:
|
||||
* ObjectLayerPairFilterTable, ObjectVsBroadPhaseLayerFilterTable and BroadPhaseLayerInterfaceTable: These three implement collision layers as a simple table. You construct ObjectLayerPairFilterTable with a fixed number of object layers and then call ObjectLayerPairFilterTable::EnableCollision or ObjectLayerPairFilterTable::DisableCollision to selectively enable or disable collisions between layers. BroadPhaseLayerInterfaceTable is constructed with a number of broad phase layers. You can then map each object layer to a broad phase layer through BroadPhaseLayerInterfaceTable::MapObjectToBroadPhaseLayer.
|
||||
* ObjectLayerPairFilterMask, ObjectVsBroadPhaseLayerFilterMask and BroadPhaseLayerInterfaceMask: These split an ObjectLayer in an equal amount of bits for group and mask. Two objects collide if (object1.group & object2.mask) != 0 && (object2.group & object1.mask) != 0. This behavior is similar to e.g. Bullet. In order to map groups to broad phase layers, you call BroadPhaseLayerInterfaceMask::ConfigureLayer for each broad phase layer. You determine which groups can be put in that layer and which group must be excluded from that layer. E.g. a broad phase layer could include everything that has the STATIC group but should exclude everything that has the SENSOR group, so that if an object has both STATIC and SENSOR bits set, this broad phase layer will not be used. The broad phase layers are checked one by one and the first one that meets the condition is the one that the body will be put in. If you use this implementation, consider setting the cmake option OBJECT_LAYER_BITS to 32 to get a 32-bit ObjectLayer instead of a 16-bit one.
|
||||
|
||||
Now that we know about the basics, we list the order in which the collision detection pipeline goes through the various collision filters:
|
||||
|
||||
* Broadphase layer: At this stage, the object layer is tested against the broad phase trees that are relevant by checking the [ObjectVsBroadPhaseLayerFilter](@ref ObjectVsBroadPhaseLayerFilter).
|
||||
* Object layer: Once the broad phase layer test succeeds, we will test object layers vs object layers through [ObjectLayerPairFilter](@ref ObjectLayerPairFilter) (used for simulation) and [ObjectLayerFilter](@ref ObjectLayerFilter) (used for collision queries). The default implementation of ObjectLayerFilter is DefaultObjectLayerFilter and uses ObjectLayerPairFilter so the behavior is consistent between simulation and collision queries.
|
||||
* Group filter: Most expensive filtering (bounding boxes already overlap), used only during simulation. Allows you fine tune collision e.g. by discarding collisions between bodies connected by a constraint. See [GroupFilter](@ref GroupFilter) and implementation for ragdolls [GroupFilterTable](@ref GroupFilterTable).
|
||||
* Body filter: This filter is used instead of the group filter if you do collision queries like CastRay. See [BodyFilter](@ref BodyFilter).
|
||||
* Shape filter: This filter is used only during collision queries and can be used to filter out individual (sub)shapes. See [ShapeFilter](@ref ShapeFilter).
|
||||
* Contact listener: During simulation, after all collision detection work has been performed you can still choose to discard a contact point. This is a very expensive way of rejecting collisions as most of the work is already done. See [ContactListener](@ref ContactListener).
|
||||
|
||||
To avoid work, try to filter out collisions as early as possible.
|
||||
|
||||
## Continuous Collision Detection {#continuous-collision-detection}
|
||||
|
||||
Each body has a motion quality setting ([EMotionQuality](@ref EMotionQuality)). By default the motion quality is [Discrete](@ref Discrete). This means that at the beginning of each simulation step we will perform collision detection and if no collision is found, the body is free to move according to its velocity. This usually works fine for big or slow moving objects. Fast and small objects can easily 'tunnel' through thin objects because they can completely move through them in a single time step. For these objects there is the motion quality [LinearCast](@ref LinearCast). Objects that have this motion quality setting will do the same collision detection at the beginning of the simulation step, but once their new position is known, they will do an additional CastShape to check for any collisions that may have been missed. If this is the case, the object is placed back to where the collision occurred and will remain there until the next time step. This is called 'time stealing' and has the disadvantage that an object may appear to move much slower for a single time step and then speed up again. The alternative, back stepping the entire simulation, is computationally heavy so was not implemented.
|
||||
|
||||

|
||||
|
||||
Fast rotating long objects are also to be avoided, as the LinearCast motion quality will fully rotate the object at the beginning of the time step and from that orientation perform the CastShape, there is a chance that the object misses a collision because it rotated through it.
|
||||
|
||||

|
||||
|
||||
## Ghost Collisions {#ghost-collisions}
|
||||
|
||||
A ghost collision can occur when a body slides over another body and hits an internal edge of that body. The most common case is where a body hits an edge of a triangle in a mesh shape but it can also happen on 2 box shapes as shown below.
|
||||
|
||||

|
||||
|
||||
There are a couple of ways to avoid ghost collisions in Jolt. MeshShape and HeightFieldShape keep track of active edges during construction.
|
||||
|
||||

|
||||
|
||||
Whenever a body hits an inactive edge, the contact normal is the face normal. When it hits an active edge, it can be somewhere in between the connecting face normals so the movement of the body is impeded in the scenario below.
|
||||
|
||||

|
||||
|
||||
By tweaking MeshShapeSettings::mActiveEdgeCosThresholdAngle or HeightFieldShapeSettings::mActiveEdgeCosThresholdAngle you can determine the angle at which an edge is considered an active edge. By default this is 5 degrees, making this bigger reduces the amount of ghost collisions but can create simulation artifacts if you hit the edge straight on.
|
||||
|
||||
To further reduce ghost collisions, you can turn on BodyCreationSettings::mEnhancedInternalEdgeRemoval. When enabling this setting, additional checks will be made at run-time to detect if an edge is active or inactive based on all of the contact points between the two bodies. Beware that this algorithm only considers 2 bodies at a time, so if the two green boxes above belong to two different bodies, the ghost collision can still occur. Use a StaticCompoundShape to combine the boxes in a single body to allow the system to eliminate ghost collisions between the blue and the two green boxes. You can also use this functionality for your custom collision tests by making use of InternalEdgeRemovingCollector.
|
||||
|
||||
# Character Controllers {#character-controllers}
|
||||
|
||||
The [Character](@ref Character) and [CharacterVirtual](@ref CharacterVirtual) classes can be used to create a character controller. These are usually used to represent the player as a simple capsule or tall box and perform collision detection while the character navigates through the world.
|
||||
|
||||
The Character class is the simplest controller and is essentially a rigid body that has been configured to only allow translation (and no rotation so it stays upright). It is simulated together with the other rigid bodies so it properly reacts to them. Because it is simulated, it is usually not the best solution for a player as the player usually requires a lot of behavior that is non-physical. This character controller is cheap so it is recommended for e.g. simple AI characters. After every PhysicsSystem::Update call you must call Character::PostSimulation to update the ground contacts.
|
||||
|
||||
The CharacterVirtual class is much more advanced. It is implemented using collision detection functionality only (through NarrowPhaseQuery) and is simulated when CharacterVirtual::Update is called. Since the character is not 'added' to the world, it is not visible to rigid bodies and it only interacts with them during the CharacterVirtual::Update function by applying impulses. This does mean there can be some update order artifacts, like the character slightly hovering above an elevator going down, because the characters moves at a different time than the other rigid bodies. Separating it has the benefit that the update can happen at the appropriate moment in the game code. Multiple CharacterVirtuals can update concurrently, so it is not an issue if the game code is parallelized.
|
||||
|
||||
CharacterVirtual has the following extra functionality:
|
||||
* Sliding along walls
|
||||
* Interaction with elevators and moving platforms
|
||||
* Enhanced steep slope detection (standing in a funnel whose sides are too steep to stand on will not be considered as too steep)
|
||||
* Stair stepping through the CharacterVirtual::ExtendedUpdate call
|
||||
* Sticking to the ground when walking down a slope through the CharacterVirtual::ExtendedUpdate call
|
||||
* Support for specifying a local coordinate system that allows e.g. [walking around in a flying space ship](https://github.com/jrouwe/JoltPhysics/blob/master/Samples/Tests/Character/CharacterSpaceShipTest.cpp) that is equipped with 'inertial dampers' (a sci-fi concept often used in games).
|
||||
|
||||
If you want CharacterVirtual to have presence in the world, it is recommended to pair it with a slightly smaller [Kinematic](@ref EMotionType) body (or Character). After each update, move this body using BodyInterface::MoveKinematic to the new location. This ensures that standard collision tests like ray casts are able to find the character in the world and that fast moving objects with motion quality [LinearCast](@ref EMotionQuality) will not pass through the character in 1 update. As an alternative to a Kinematic body, you can also use a regular Dynamic body with a [gravity factor](@ref BodyCreationSettings::mGravityFactor) of 0. Ensure that the character only collides with dynamic objects in this case. The advantage of this approach is that the paired body doesn't have infinite mass so is less strong.
|
||||
|
||||
Characters are usually driven in a kinematic way (i.e. by calling Character::SetLinearVelocity or CharacterVirtual::SetLinearVelocity before their update).
|
||||
|
||||
To get started take a look at the [Character](https://github.com/jrouwe/JoltPhysics/blob/master/Samples/Tests/Character/CharacterTest.cpp) and [CharacterVirtual](https://github.com/jrouwe/JoltPhysics/blob/master/Samples/Tests/Character/CharacterVirtualTest.cpp) examples.
|
||||
|
||||
# The Simulation Step {#the-simulation-step}
|
||||
|
||||
The simulation step [PhysicsSystem::Update](@ref PhysicsSystem::Update) uses jobs ([JobSystem](@ref JobSystem)) to perform the needed work. This allows spreading the workload across multiple CPU's. We use a Sequential Impulse solver with warm starting as described in [Modeling and Solving Constraints - Erin Catto](https://box2d.org/files/ErinCatto_ModelingAndSolvingConstraints_GDC2009.pdf)
|
||||
|
||||
Each physics step can be divided into multiple collision steps. So if you run the simulation at 60 Hz with 2 collision steps we run:
|
||||
|
||||
* Collision (1/120s)
|
||||
* Integration (1/120s)
|
||||
* Collision (1/120s)
|
||||
* Integration (1/120s)
|
||||
|
||||
In general, the system is stable when running at 60 Hz with 1 collision step.
|
||||
|
||||
# Conventions and Limits {#conventions-and-limits}
|
||||
|
||||
Jolt Physics uses a right handed coordinate system with Y-up. It is easy to use another axis as up axis by changing the gravity vector using [PhysicsSystem::SetGravity](@ref PhysicsSystem::SetGravity). Some shapes like the [HeightFieldShape](@ref HeightFieldShapeSettings) will need an additional [RotatedTranslatedShape](@ref RotatedTranslatedShapeSettings) to rotate it to the new up axis and vehicles ([VehicleConstraint](@ref VehicleConstraintSettings)) and characters ([CharacterBaseSettings](@ref CharacterBaseSettings)) will need their new up-axis specified too.
|
||||
|
||||
We use column-major vectors and matrices, this means that to transform a point you need to multiply it on the right hand side: TransformedPoint = Matrix * Point.
|
||||
|
||||
Note that the physics simulation works best if you use SI units (meters, radians, seconds, kg). In order for the simulation to be accurate, dynamic objects should be in the order [0.1, 10] meters long, have speeds in the order of [0, 500] m/s and have gravity in the order of [0, 10] m/s^2. Static object should be in the order [0.1, 2000] meter long. If you are using different units, consider scaling the objects before passing them on to the physics simulation.
|
||||
|
||||
# Big Worlds {#big-worlds}
|
||||
|
||||
By default the library compiles using floats. This means that the simulation gets less accurate the further you go from the origin. If all simulation takes place within roughly 5 km from the origin, floating point precision is accurate enough.
|
||||
|
||||
If you have a bigger world, you may want to compile the library using the JPH_DOUBLE_PRECISION define. When you do this, all positions will be stored as doubles, which will make the simulation accurate even at thousands of kilometers away from the origin.
|
||||
|
||||
Calculations with doubles are much slower than calculations with floats. A naive implementation that changes all calculations to doubles has been measured to run more than 2x slower than the same calculations using floats. Because of this, Jolt Physics will only use doubles where necessary and drop down to floats as soon as possible. In order to do this, many of the collision query functions will need a 'base offset'. All collision results will be returned as floats relative to this base offset. By choosing the base offset wisely (i.e. close to where collision results are expected) the results will be accurate. Make sure your base offset is not kilometers away from the collision result.
|
||||
|
||||
Keep in mind that:
|
||||
|
||||
* There are a lot of 'epsilons' in the code that have been tuned for objects of sizes/speeds as described in the @ref conventions-and-limits section. Try to keep the individual objects to the specified scale even if they're really far from the origin.
|
||||
* When the collision results of a single query are kilometers apart, precision will suffer as they will be far away from the 'base offset'.
|
||||
* The effectiveness of the broad phase (which works in floats) will become less at large distances from the origin, e.g. at 10000 km from the origin, the resolution of the broad phase is reduced to 1 m which means that everything that's closer than 1 m will be considered colliding. This will not impact the quality of the simulation but it will result in extra collision tests in the narrow phase so will hurt performance.
|
||||
|
||||
Because of the minimal use of doubles, the simulation runs 5-10% slower in double precision mode compared to float precision mode.
|
||||
|
||||
# Deterministic Simulation {#deterministic-simulation}
|
||||
|
||||
The physics simulation is deterministic provided that:
|
||||
|
||||
* The APIs that modify the simulation are called in exactly the same order. For example, bodies and constraints need to be added/removed/modified in exactly the same order so that the state at the beginning of a simulation step is exactly the same for both simulations.
|
||||
* The same binary code is used to run the simulation. For example, when you run the simulation on Windows it doesn't matter if you have an AMD or Intel processor.
|
||||
|
||||
If you want cross platform determinism then please turn on the CROSS_PLATFORM_DETERMINISTIC option in CMake. This will make the library approximately 8% slower but the simulation will be deterministic regardless of:
|
||||
|
||||
* Compiler used to compile the library (tested MSVC2022 vs clang)
|
||||
* Configuration (Debug, Release or Distribution)
|
||||
* OS (tested Windows, macOS, Linux)
|
||||
* Architecture (x86 or ARM).
|
||||
|
||||
Some caveats:
|
||||
|
||||
* The same source code must be used to compile the library on all platforms.
|
||||
* The source code must be compiled with the same defines, e.g. you can't have one platform using JPH_DOUBLE_PRECISION and another not.
|
||||
|
||||
It is quite difficult to verify cross platform determinism, so this feature is less tested than other features. With every build, the following architectures are verified to produce the same results:
|
||||
|
||||
* Windows MSVC x86 64-bit with AVX2
|
||||
* Windows MSVC x86 32-bit with SSE2
|
||||
* macOS clang x86 64-bit with AVX
|
||||
* Linux clang x86 64-bit with AVX2
|
||||
* Linux clang ARM 64-bit with NEON
|
||||
|
||||
The most important things to look out for in your own application:
|
||||
|
||||
* Compile your application mode in Precise mode (clang: -ffp-model=precise, MSVC: /fp:precise)
|
||||
* Turn off floating point contract operations (clang: -ffp-contract=off)
|
||||
* Do not use the standard trigonometry functions (sin, cos etc.) as they have different implementations on different platforms, use Jolt's functions (Sin, Cos etc.)
|
||||
* Do not use std::sort as it has a different implementation on different platforms, use Jolt's QuickSort function
|
||||
|
||||
When running the Samples Application you can press ESC, Physics Settings and check the 'Check Determinism' checkbox. Before every simulation step we will record the state using the [StateRecorder](@ref StateRecorder) interface, rewind the simulation and do the step again to validate that the simulation runs deterministically. Some of the tests (e.g. the MultiThreaded) test will explicitly disable the check because they randomly add/remove bodies from different threads. This violates the rule that the API calls must be done in the same order so will not result in a deterministic simulation.
|
||||
|
||||
# Rolling Back a Simulation {#rolling-back-a-simulation}
|
||||
|
||||
When synchronizing two simulations via a network, it is possible that a change that needed to be applied at frame N is received at frame N + M. This will require rolling back the simulation to the state of frame N and repeating the simulation with the new inputs. This can be implemented by saving the physics state using [SaveState](@ref PhysicsSystem::SaveState) at every frame. To roll back, call [RestoreState](@ref PhysicsSystem::RestoreState) with the state at frame N. SaveState only records the state that the physics engine modifies during its update step (positions, velocities etc.), so if you change anything else you need to restore this yourself. E.g. if you did a [SetFriction](@ref Body::SetFriction) on frame N + 2 then, when rewinding, you need to restore the friction to what is was on frame N and update it again on frame N + 2 when you replay. If you start adding/removing objects (e.g. bodies or constraints) during these frames, the RestoreState function will not work. If you added a body on frame N + 1, you'll need to remove it when rewinding and then add it back on frame N + 1 again (with the proper initial position/velocity etc. because it won't be contained in the snapshot at frame N).
|
||||
|
||||
If you wish to share saved state between server and client, you need to ensure that all APIs that modify the state of the world are called in the exact same order. So if the client creates physics objects for player 1 then 2 and the server creates the objects for 2 then 1 you already have a problem (the body IDs will be different, which will render the save state snapshots incompatible). When rolling back a simulation, you'll also need to ensure that the BodyIDs are kept the same, so you need to remove/add the body from/to the physics system instead of destroy/re-create them or you need to create bodies with the same ID on both sides using [BodyInterface::CreateBodyWithID](@ref BodyInterface::CreateBodyWithID).
|
||||
|
||||
# Working With Multiple Physics Systems {#working-with-multiple-physics-systems}
|
||||
|
||||
You can create, simulate and interact with multiple PhysicsSystems at the same time provided that you do not share any objects (bodies, constraints) between the systems.
|
||||
When a Body is created it receives a BodyID that is unique for the PhysicsSystem that it was created for, so it cannot be shared. The only object that can be shared between PhysicsSystems is a Shape.
|
||||
If you want to move a body from one PhysicsSystem to another, use Body::GetBodyCreationSettings to get the settings needed to create the body in the other PhysicsSystem.
|
||||
|
||||
PhysicsSystems are not completely independent:
|
||||
|
||||
* There is only 1 RTTI factory (Factory::sInstance).
|
||||
* There is only 1 default material (PhysicsMaterial::sDefault).
|
||||
* There is only 1 debug renderer (DebugRenderer::sInstance) although many functions take a custom DebugRenderer for drawing.
|
||||
* Custom shapes and CollisionDispatch functions are shared.
|
||||
* The custom memory allocation functions (e.g. Allocate), Trace and AssertFailed functions are shared.
|
||||
|
||||
These functions / systems need to be registered in advance.
|
||||
|
||||
# Debug Rendering {#debug-rendering}
|
||||
|
||||
When the define JPH_DEBUG_RENDERER is defined (which by default is defined in Debug and Release but not Distribution), Jolt is able to render its internal state. To integrate this into your own application you must inherit from the DebugRenderer class and implement the pure virtual functions DebugRenderer::DrawLine, DebugRenderer::DrawTriangle, DebugRenderer::CreateTriangleBatch, DebugRenderer::DrawGeometry and DebugRenderer::DrawText3D. The CreateTriangleBatch is used to prepare a batch of triangles to be drawn by a single DrawGeometry call, which means that Jolt can render a complex scene much more efficiently than when each triangle in that scene would have been drawn through DrawTriangle. At run-time create an instance of your DebugRenderer which will internally assign itself to DebugRenderer::sInstance. Finally call for example PhysicsSystem::DrawBodies or PhysicsSystem::DrawConstraints to draw the state of the simulation. For an example implementation see [the DebugRenderer from the Samples application](https://github.com/jrouwe/JoltPhysics/blob/master/TestFramework/Renderer/DebugRendererImp.h) or to get started quickly take a look at DebugRendererSimple.
|
||||
|
||||
# Memory Management {#memory-management}
|
||||
|
||||
Jolt uses reference counting for a number of its classes (everything that inherits from RefTarget). The most important classes are:
|
||||
|
||||
* ShapeSettings
|
||||
* Shape
|
||||
* ConstraintSettings
|
||||
* Constraint
|
||||
* PhysicsMaterial
|
||||
* GroupFilter
|
||||
* PhysicsScene
|
||||
* SoftBodySharedSettings
|
||||
* VehicleCollisionTester
|
||||
* VehicleController
|
||||
* WheelSettings
|
||||
* CharacterBaseSettings
|
||||
* CharacterBase
|
||||
* RagdollSettings
|
||||
* Ragdoll
|
||||
* Skeleton
|
||||
* SkeletalAnimation
|
||||
* SkeletonMapper
|
||||
|
||||
Reference counting objects start with a reference count of 0. If you want to keep ownership of the object, you need to call [object->AddRef()](@ref RefTarget::AddRef), this will increment the reference count. If you want to release ownership you call [object->ReleaseRef()](@ref RefTarget::Release), this will decrement the reference count and if the reference count reaches 0 the object will be destroyed. If, after newing, you pass a reference counted object on to another object (e.g. a ShapeSettings to a CompoundShapeSettings or a Shape to a Body) then that other object will take a reference, in that case it is not needed take a reference yourself beforehand so you can skip the calls to ```AddRef/Release```. Note that it is also possible to do ```auto x = new XXX``` followed by ```delete x``` for a reference counted object if no one ever took a reference. The safest way of working with reference counting objects is to use the Ref or RefConst classes, these automatically manage the reference count for you when assigning a new value or on destruction:
|
||||
|
||||
```
|
||||
// Calls 'AddRef' to keep a reference the shape
|
||||
JPH::Ref<Shape> shape = new JPH::SphereShape(1.0f);
|
||||
|
||||
// Calls 'Release' to release and delete the shape (note that this also happens if JPH::Ref goes out of scope)
|
||||
shape = nullptr;
|
||||
```
|
||||
|
||||
The Body class is a special case, it is destroyed through BodyInterface::DestroyBody (which internally destroys the Body).
|
||||
|
||||
Jolt also supports routing all of its internal allocations through a custom allocation function. See: [Allocate](@ref Allocate), [Free](@ref Free), [AlignedAllocate](@ref AlignedAllocate) and [AlignedFree](@ref AlignedFree).
|
||||
|
||||
# The Simulation Step in Detail {#the-simulation-step-in-detail}
|
||||
|
||||
The job graph looks like this:
|
||||
|
||||

|
||||
|
||||
Note that each job indicates if it reads/writes positions/velocities and if it deactivates/activates bodies. We do not allow jobs to read/write the same data concurrently. The arrows indicate the order in which jobs are executed. Yellow blocks mean that there are multiple jobs of this type. Dotted arrows have special meaning and are explained below.
|
||||
|
||||
## Broad Phase Update Prepare {#broad-phase-update-prepare}
|
||||
|
||||
This job will refit the AABBs of the broad phase. It does this by building a new tree while keeping the old one available as described in the @ref broad-phase section.
|
||||
|
||||
## Broad Phase Update Finalize {#broad-phase-update-finalize}
|
||||
|
||||
This job will simply swap the new tree with the old tree. The old tree will be discarded at the beginning of the next PhysicsSystem::Update call so that any broad phase query can continue to run.
|
||||
|
||||
## Step Listeners {#step-listeners-update}
|
||||
|
||||
You can register one or more step listeners (See [PhysicsSystem::AddStepListener](@ref PhysicsSystem::AddStepListener)). This job will call [PhysicsStepListener::OnStep](@ref PhysicsStepListener::OnStep) for every listener. This can be used to do work that needs to be done at the beginning of each step, e.g. set velocities on ragdoll bodies.
|
||||
|
||||
## Apply Gravity {#apply-gravity-update}
|
||||
|
||||
A number of these jobs run in parallel. Each job takes a batch of active bodies and applies gravity and damping (updating linear and angular velocity).
|
||||
|
||||
## Determine Active Constraints {#determine-active-constraints}
|
||||
|
||||
This job will go through all non-contact constraints and determine which constraints are active based on if the bodies that the constraint connects to are active.
|
||||
|
||||
## Build Islands from Constraints {#build-islands-from-constraints}
|
||||
|
||||
This job will go through all non-contact constraints and assign the involved bodies and constraint to the same island. Since we allow concurrent insertion/removal of bodies we do not want to keep island data across multiple simulation steps, so we recreate the islands from scratch every simulation step. The operation is lock-free and O(N) where N is the number of constraints.
|
||||
|
||||
If a constraint connects an active and a non-active body, the non-active body is woken up. One find collisions job will not start until this job has finished in order to pick up any collision testing for newly activated bodies.
|
||||
|
||||
## Find Collisions {#find-collisions}
|
||||
|
||||
This job will do broad and narrow phase checks. Initially a number of jobs are started based on the amount of active bodies. The job will do the following:
|
||||
|
||||
- Take a batch of active bodies and collide them against the broadphase.
|
||||
- When a collision pair is found it is inserted in a lock free queue to be processed later.
|
||||
- If the queue is full, it will be processed immediately (more Find Collisions jobs are spawned if not all CPU cores are occupied yet as the queue starts to fill up).
|
||||
- If there are no more active bodies to process, the job will start to perform narrow phase collision detection and set up contact constraints if any collisions are found.
|
||||
- As soon as a narrow phase pair is processed it will recheck if there are new active bodies to be processed (active bodies can be generated by an active body colliding with an inactive body) and if so process them.
|
||||
- When there are no more active bodies to test and no more collision pairs to be processed the job terminates.
|
||||
|
||||
Note that this job cannot start until apply gravity is done because the velocity needs to be known for elastic collisions to be calculated properly.
|
||||
|
||||
The contact points between the two bodies will be determined by the [GJK](@ref GJKClosestPoint) and [EPA](@ref EPAPenetrationDepth) algorithms. For each contact point we will calculate the face that belongs to that contact point. The faces of both bodies are clipped against each other ([ManifoldBetweenTwoFaces](@ref ManifoldBetweenTwoFaces)) so that we have a polygon (or point / line) that represents the contact between the two bodies (contact manifold).
|
||||
|
||||
Multiple contact manifolds with similar normals are merged together (PhysicsSystem::ProcessBodyPair::ReductionCollideShapeCollector). After this the contact constraints are created in the [ContactConstraintManager](@ref ContactConstraintManager) and their Jacobians / effective masses calculated.
|
||||
|
||||
Contacting bodies are also linked together to form islands. This is the same operation as described in the @ref build-islands-from-constraints section.
|
||||
|
||||
The narrow phase makes use of a lock free contact cache. We have 2 caches, one that is used for reading (which contains the contacts from the previous step) and one for writing new contact pairs. When a contact point is preserved from the last simulation step, it will be copied from the read cache to the write cache.
|
||||
|
||||
## Setup Velocity Constraints {#setup-velocity-constraints}
|
||||
|
||||
This job will go through all non-contact constraints and prepare them for execution. This involves calculating Jacobians and effective masses for each constraint part.
|
||||
|
||||
## Finalize Islands {#finalize-islands}
|
||||
|
||||
This job will finalize the building of the simulation islands. Each island contains bodies that interact with each other through a contact point or through a constraint. These islands will be simulated separately in different jobs later. The finalization of the islands is an O(N) operation where N is the amount of active bodies (see [IslandBuilder::Finalize](@ref IslandBuilder::Finalize)).
|
||||
|
||||
## Set Body Island Idx {#set-body-island-idx}
|
||||
|
||||
This job does some housekeeping work that can be executed concurrent to the solver:
|
||||
|
||||
* It will assign the island ID to all bodies (which is mainly used for debugging purposes)
|
||||
|
||||
## Solve Velocity Constraints {#solve-velocity-constraints}
|
||||
|
||||
A number of these jobs will run in parallel. Each job takes the next unprocessed island and will run the iterative constraint solver for that island. It will first apply the impulses applied from the previous simulation step (which are stored in the contact cache) to warm start the solver. It will then repeatedly iterate over all contact and non-contact constraints until either the applied impulses are too small or a max iteration count is reached ([PhysicsSettings::mNumVelocitySteps](@ref PhysicsSettings::mNumVelocitySteps)). The result will be that the new velocities are known for all active bodies. The applied impulses are stored in the contact cache for the next step.
|
||||
|
||||
When an island consists of more than LargeIslandSplitter::cLargeIslandTreshold contacts plus constraints it is considered a large island. In order to not do all work on a single thread, this island will be split up by the LargeIslandSplitter. This follows an algorithm described in High-Performance Physical Simulations on Next-Generation Architecture with Many Cores by Chen et al. This is basically a greedy algorithm that tries to group contacts and constraints into groups where no contact or constraint affects the same body. Within a group, the order of execution does not matter since every memory location is only read/written once, so we can parallelize the update. At the end of each group, we need to synchronize the CPU cores before starting on the next group. When the number of groups becomes too large, a final group is created that contains all other contacts and constraints and these are solved on a single thread. The groups are processed PhysicsSettings::mNumVelocitySteps times so the end result is almost the same as an island that was not split up (only the evaluation order changes in a consistent way).
|
||||
|
||||
## Pre Integrate {#pre-integrate}
|
||||
|
||||
This job prepares the CCD buffers.
|
||||
|
||||
## Integrate & Clamp Velocities {#integrate-and-clamp-velocities}
|
||||
|
||||
This job will integrate the velocity and update the position. It will clamp the velocity to the max velocity.
|
||||
|
||||
Depending on the motion quality ([EMotionQuality](@ref EMotionQuality)) of the body, it will schedule a body for continuous collision detection (CCD) if its movement is bigger than some threshold based on the [inner radius](@ref Shape::GetInnerRadius)) of the shape.
|
||||
|
||||
## Post Integrate {#post-integrate}
|
||||
|
||||
Find CCD Contact jobs are created on the fly depending on how many CCD bodies were found. If there are no CCD bodies it will immediately start Resolve CCD Contacts.
|
||||
|
||||
## Find CCD Contacts {#find-ccd-contacts}
|
||||
|
||||
A number of jobs will run in parallel and pick up bodies that have been scheduled for CCD and will do a linear cast to detect the first collision. It always allows movement of the object by a fraction if its inner radius in order to prevent it from getting fully stuck.
|
||||
|
||||
## Resolve CCD Contacts {#resolve-ccd-contacts}
|
||||
|
||||
This job will take the collision results from the previous job and update position and velocity of the involved bodies. If an object hits another object, its time will be 'stolen' (it will move less far than it should according to its velocity).
|
||||
|
||||
## Finalize Contact Cache, Contact Removed Callbacks {#finalize-contact-cache}
|
||||
|
||||
This job will:
|
||||
|
||||
* Swap the read/write contact cache and prepare the contact cache for the next step.
|
||||
* It will detect all contacts that existed previous step and do not exist anymore to fire callbacks for them through the [ContactListener](@ref ContactListener) interface.
|
||||
|
||||
## Solve Position Constraints, Update Bodies Broad Phase {#solve-position-constraints}
|
||||
|
||||
A number of these jobs will run in parallel. Each job takes the next unprocessed island and run the position based constraint solver. This fixes numerical drift that may have caused constrained bodies to separate (remember that the constraints are solved in the velocity domain, so errors get introduced when doing a linear integration step). It will run until either the applied position corrections are too small or until the max amount of iterations is reached ([PhysicsSettings::mNumPositionSteps](@ref PhysicsSettings::mNumPositionSteps)). Here there is also support for large islands, the island splits that were calculated in the Solve Velocity Constraints job are reused to solve partial islands in the same way as before.
|
||||
|
||||
It will also notify the broad phase of the new body positions / AABBs.
|
||||
|
||||
When objects move too little the body will be put to sleep. This is detected by taking the biggest two axis of the local space bounding box of the shape together with the center of mass of the shape (all points in world space) and keep track of 3 bounding spheres for those points over time. If the bounding spheres become too big, the bounding spheres are reset and the timer restarted. When the timer reaches a certain time, the object has is considered non-moving and is put to sleep.
|
||||
|
||||
## Soft Body Prepare {#soft-body-prepare}
|
||||
|
||||
If there are any active soft bodies, this job will create the Soft Body Collide, Simulate and Finalize Jobs. It will also create a list of sorted SoftBodyUpdateContext objects that forms the context for those jobs.
|
||||
|
||||
## Soft Body Collide {#soft-body-collide}
|
||||
|
||||
These jobs will do broadphase checks for all of the soft bodies. A thread picks up a single soft body and uses the bounding box of the soft body to find intersecting rigid bodies. Once found, information will be collected about that rigid body so that Simulate can run in parallel.
|
||||
|
||||
## Soft Body Simulate {#soft-body-simulate}
|
||||
|
||||
These jobs will do the actual simulation of the soft bodies. They first collide batches of soft body vertices with the rigid bodies found during the Collide job (multiple threads can work on a single soft body) and then perform the simulation using XPBD (also partially distributing a single soft body on multiple threads).
|
||||
|
||||
## Soft Body Finalize {#soft-body-finalize}
|
||||
|
||||
This job writes back all the rigid body velocity changes and updates the positions and velocities of the soft bodies. It can activate/deactivate bodies as needed.
|
BIN
src/JoltPhysics/Docs/Images/ActiveEdge.jpg
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
src/JoltPhysics/Docs/Images/ActiveVsInactiveContactNormal.jpg
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
src/JoltPhysics/Docs/Images/ConvexRadius.jpg
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
src/JoltPhysics/Docs/Images/EllipsoidAABB.png
Normal file
After Width: | Height: | Size: 155 KiB |
BIN
src/JoltPhysics/Docs/Images/GhostCollision.jpg
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
src/JoltPhysics/Docs/Images/LongAndThin.jpg
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
src/JoltPhysics/Docs/Images/MotionQuality.jpg
Normal file
After Width: | Height: | Size: 32 KiB |
BIN
src/JoltPhysics/Docs/Images/MotorDamping.jpg
Normal file
After Width: | Height: | Size: 94 KiB |
BIN
src/JoltPhysics/Docs/Images/MotorFrequency.jpg
Normal file
After Width: | Height: | Size: 99 KiB |
BIN
src/JoltPhysics/Docs/Images/QuadTreeExample.png
Normal file
After Width: | Height: | Size: 64 KiB |
BIN
src/JoltPhysics/Docs/Images/ShapeCenterOfMass.jpg
Normal file
After Width: | Height: | Size: 30 KiB |
BIN
src/JoltPhysics/Docs/Images/SimulationIsland.jpg
Normal file
After Width: | Height: | Size: 19 KiB |
BIN
src/JoltPhysics/Docs/Images/SoftBodySkinnedConstraint.jpg
Normal file
After Width: | Height: | Size: 27 KiB |
BIN
src/JoltPhysics/Docs/Logo.png
Normal file
After Width: | Height: | Size: 1.8 MiB |
BIN
src/JoltPhysics/Docs/LogoDark.png
Normal file
After Width: | Height: | Size: 2.4 MiB |
BIN
src/JoltPhysics/Docs/LogoSmall.png
Normal file
After Width: | Height: | Size: 14 KiB |
36
src/JoltPhysics/Docs/PerformanceTest.md
Normal file
@ -0,0 +1,36 @@
|
||||
# Performance Test
|
||||
|
||||
The performance test application contains a couple of simple scenes to test performance of Jolt Physics. It will output the results to the TTY in CSV format.
|
||||
|
||||
## Commandline options
|
||||
|
||||
- -s=[scene]: This allows you to select a scene, [scene] can be;
|
||||
- Ragdoll: A scene with 16 piles of 10 ragdolls (3680 bodies) with motors active dropping on a level section.
|
||||
- RagdollSinglePile: A single pile of 160 ragdolls (3680 bodies) with motors active dropping on a level section.
|
||||
- ConvexVsMesh: A simpler scene of 484 convex shapes (sphere, box, convex hull, capsule) falling on a 2000 triangle mesh.
|
||||
- Pyramid: A pyramid of 1240 boxes stacked on top of each other to profile large island splitting.
|
||||
- -i=[iterations]: Number of physics steps before the test finishes.
|
||||
- -q=[quality]: This limits the motion quality types that the test will run on. By default it will test both. [quality] can be:
|
||||
- Discrete: Discrete collision detection
|
||||
- LinearCast: Linear cast continous collision detection
|
||||
- -t=[num]: This sets the amount of threads the test will run on. By default it will test 1 .. number of virtual processors. Can be 'max' to run on as many thread as the CPU has.
|
||||
- -no_sleep: Disable sleeping.
|
||||
- -p: Outputs a profile snapshot every 100 iterations
|
||||
- -r: Outputs a performance_test_[tag].jor file that contains a recording to be played back with JoltViewer
|
||||
- -f: Outputs the time taken per frame to per_frame_[tag].csv
|
||||
- -h: Displays a help text
|
||||
- -rs: Record the simulation state in state_[tag].bin.
|
||||
- -vs: Validate the recorded simulation state from state_[tag].bin. This will after every simulation step check that the state is the same as the recorded state and trigger a breakpoint if this is not the case. This is used to validate cross platform determinism.
|
||||
- -repeat=[num]: Repeats all tests num times.
|
||||
- -validate_hash=[hash]: Will validate that the hash of the simulation matches the supplied hash. Program terminates with return code 1 if it doesn't. Can be used to automatically validate determinism.
|
||||
|
||||
## Output
|
||||
|
||||
- Motion Quality: Shows the motion quality for the test.
|
||||
- Thread Count: The amount of threads used for the test.
|
||||
- Steps / Second: Average amount of physics steps / second over the entire duration of the test.
|
||||
- Hash: A hash of all positions and rotations of the bodies at the end of the test. Can be used to verify that the test was deterministic.
|
||||
|
||||
## Results
|
||||
|
||||
If you're interested in how Jolt scales with multiple CPUs and compares to other physics engines, take a look at [this document](https://jrouwe.nl/jolt/JoltPhysicsMulticoreScaling.pdf).
|
537
src/JoltPhysics/Docs/PhysicsSystemUpdate.drawio
Normal file
@ -0,0 +1,537 @@
|
||||
<mxfile host="app.diagrams.net" modified="2024-01-22T19:21:08.802Z" agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" etag="1-bB5xyBy8A0LU8A59eh" version="22.1.18" type="device">
|
||||
<diagram id="rLFVS3KHCrdhIcSo5p6n" name="Page-1">
|
||||
<mxGraphModel dx="1562" dy="810" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" background="#FFFFFF" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="2" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#d9d9d9;strokeColor=#333333;gradientColor=#FFFFFF;gradientDirection=north;opacity=100.0;gliffyId=319;" parent="1" vertex="1">
|
||||
<mxGeometry x="22.5" y="101.75" width="2167.5" height="478" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="4" value="<div style='width: 93.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Apply Gravity </span></div><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">(in batches)</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#fff2cc;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=3;" parent="1" vertex="1">
|
||||
<mxGeometry x="209.8640594482422" y="458.3939208984375" width="100" height="65.1060791015625" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="5" style="shape=ellipse;perimeter=ellipsePerimeter;shadow=0;strokeWidth=2;fillColor=#ffffff;strokeColor=#333333;opacity=100.0;gliffyId=8;" parent="1" vertex="1">
|
||||
<mxGeometry x="34.15999984741211" y="406.5" width="15" height="15" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="6" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=11;edgeStyle=orthogonalEdgeStyle;" parent="1" source="5" target="37" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="41.660003662109375" y="406.5" />
|
||||
<mxPoint x="41.660003662109375" y="169.875" />
|
||||
<mxPoint x="150" y="169.875" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="7" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=15;exitX=1.0;exitY=0.5;exitPerimeter=0;entryX=0.0;entryY=0.5;entryPerimeter=0;" parent="1" source="112" target="4" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="182.5" y="413.80303955078125" />
|
||||
<mxPoint x="209.8640594482422" y="490.94696044921875" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="8" value="<div style='width: 93.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Setup Velocity Constraints</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#FFF2CC;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=30;" parent="1" vertex="1">
|
||||
<mxGeometry x="360.3299865722656" y="197.25" width="100" height="62.75" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="9" value="<div style='width: 93.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Pre Integrate</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ffffff;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=48;" parent="1" vertex="1">
|
||||
<mxGeometry x="848" y="144.25" width="100" height="75" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="10" value="<div style='width: 93.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Finalize Islands</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ffffff;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=53;" parent="1" vertex="1">
|
||||
<mxGeometry x="565" y="315.69696044921875" width="100" height="65.1060791015625" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="11" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=73;exitX=1.0;exitY=0.5;exitPerimeter=0;entryX=0.0;entryY=0.7071067690849304;entryPerimeter=0;" parent="1" source="10" target="41" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="665" y="348.25" />
|
||||
<mxPoint x="713.6599731445312" y="244.7830047607422" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="12" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=88;exitX=1.0;exitY=0.5;exitPerimeter=0;entryX=0.0;entryY=0.5;entryPerimeter=0;" parent="1" source="37" target="54" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="250" y="169.875" />
|
||||
<mxPoint x="565" y="169.75" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="13" value="<div style='width: 93.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Solve Position Constraints, </span></div><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Update Bodies Broadphase </span></div><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">(per island)</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#fff2cc;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=96;" parent="1" vertex="1">
|
||||
<mxGeometry x="1456.2425537109375" y="136.25" width="100" height="92" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="14" style="shape=ellipse;perimeter=ellipsePerimeter;shadow=0;strokeWidth=2;fillColor=#000000;strokeColor=#333333;opacity=100.0;gliffyId=100;" parent="1" vertex="1">
|
||||
<mxGeometry x="2200.0025537109377" y="174.04999999999998" width="15" height="15" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="15" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=114;exitX=1.0;exitY=0.5;exitPerimeter=0;entryX=1.1102230246251565E-16;entryY=0.2928932309150696;entryPerimeter=0;" parent="1" source="77" target="71" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="310.5" y="349" />
|
||||
<mxPoint x="359.5240478515625" y="477.4320068359375" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="16" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=117;exitX=1.0;exitY=0.5;exitPerimeter=0;entryX=0.0;entryY=0.5;entryPerimeter=0;" parent="1" source="8" target="41" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="460.33001708984375" y="228.625" />
|
||||
<mxPoint x="713.6600341796875" y="229.25" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="17" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=120;exitX=1.0;exitY=0.5;exitPerimeter=0;entryX=0.0;entryY=0.7071067690849304;entryPerimeter=0;" parent="1" source="41" target="9" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="813.6599731445312" y="229.25" />
|
||||
<mxPoint x="848" y="197.28302001953125" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="18" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;dashed=1;fixDash=1;dashPattern=2.0 2.0;gliffyId=123;exitX=1.0;exitY=0.5;exitPerimeter=0;entryX=0.0;entryY=0.5;entryPerimeter=0;" parent="1" source="117" target="86" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="1184.232421875" y="180.75" />
|
||||
<mxPoint x="1208.242431640625" y="181.25" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="20" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=135;exitX=1.0;exitY=0.5;exitPerimeter=0;entryX=0.0;entryY=0.5;entryPerimeter=0;" parent="1" source="112" target="77" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="182.5" y="413.80303955078125" />
|
||||
<mxPoint x="210.5" y="349" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="21" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=139;exitX=1.0;exitY=0.5;exitPerimeter=0;entryX=0.0;entryY=0.5;entryPerimeter=0;" parent="1" source="66" target="10" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="459.5240478515625" y="349" />
|
||||
<mxPoint x="565" y="348.25" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="22" value="<div style='width: 141.96px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Set Body Island Idx</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ffffff;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=3.02;spacingRight=0;whiteSpace=wrap;gliffyId=152;" parent="1" vertex="1">
|
||||
<mxGeometry x="713.6599731445314" y="315.6960791015625" width="151" height="65.1060791015625" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="23" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=154;exitX=1.0;exitY=0.5;exitPerimeter=0;entryX=0.0;entryY=0.5;entryPerimeter=0;" parent="1" source="10" target="22" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="24" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=155;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;edgeStyle=orthogonalEdgeStyle;" parent="1" source="22" target="13" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="26" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=171;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="13" target="2HlbSkl1Hx2XcQlONuJN-122" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<mxPoint x="1560" y="180" as="sourcePoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="28" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">P</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#00ff00;strokeColor=#333333;gradientColor=#AAFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=191;" parent="1" vertex="1">
|
||||
<mxGeometry x="23.5" y="12" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="29" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">V</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#00ff00;strokeColor=#333333;gradientColor=#AAFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=194;" parent="1" vertex="1">
|
||||
<mxGeometry x="23.5" y="46" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="30" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">P</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff0000;strokeColor=#333333;gradientColor=#FFAAAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=200;" parent="1" vertex="1">
|
||||
<mxGeometry x="23.5" y="29" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="31" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">V</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff0000;strokeColor=#333333;gradientColor=#FFAAAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=198;" parent="1" vertex="1">
|
||||
<mxGeometry x="23.5" y="63" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="32" value="<div style='width: 147.0px;height:auto;word-break: break-word;'><div align="left"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Read position</span></div></div>" style="text;html=1;nl2Br=0;html=1;nl2Br=0;verticalAlign=middle;align=left;spacingLeft=0.0;spacingRight=0;whiteSpace=wrap;gliffyId=205;" parent="1" vertex="1">
|
||||
<mxGeometry x="46.15999984741211" y="14" width="150" height="14" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="33" value="<div style='width: 147.0px;height:auto;word-break: break-word;'><div align="left"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Read/write position</span></div></div>" style="text;html=1;nl2Br=0;html=1;nl2Br=0;verticalAlign=middle;align=left;spacingLeft=0.0;spacingRight=0;whiteSpace=wrap;gliffyId=206;" parent="1" vertex="1">
|
||||
<mxGeometry x="46.15999984741211" y="30.5" width="150" height="14" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="34" value="<div style='width: 147.0px;height:auto;word-break: break-word;'><div align="left"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Read velocity</span></div></div>" style="text;html=1;nl2Br=0;html=1;nl2Br=0;verticalAlign=middle;align=left;spacingLeft=0.0;spacingRight=0;whiteSpace=wrap;gliffyId=207;" parent="1" vertex="1">
|
||||
<mxGeometry x="44.15999984741211" y="47.5" width="150" height="14" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="35" value="<div style='width: 147.0px;height:auto;word-break: break-word;'><div align="left"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Read/write velocity</span></div></div>" style="text;html=1;nl2Br=0;html=1;nl2Br=0;verticalAlign=middle;align=left;spacingLeft=0.0;spacingRight=0;whiteSpace=wrap;gliffyId=208;" parent="1" vertex="1">
|
||||
<mxGeometry x="44.15999984741211" y="63" width="150" height="14" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="36" style="group;gliffyId=598;" parent="1" vertex="1">
|
||||
<mxGeometry x="150" y="135.75" width="100" height="85.25" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="37" value="<div style='width: 93.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Broad Phase Update Prepare</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ffffff;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=0;" parent="36" vertex="1">
|
||||
<mxGeometry width="100" height="68.25" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="38" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">P</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#00ff00;strokeColor=#333333;gradientColor=#AAFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=211;" parent="36" vertex="1">
|
||||
<mxGeometry x="0.6359397172927856" y="68.25" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="39" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">P</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#00ff00;strokeColor=#333333;gradientColor=#AAFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=213;" parent="1" vertex="1">
|
||||
<mxGeometry x="360.3299865722656" y="260.5" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="40" style="group;gliffyId=596;" parent="1" vertex="1">
|
||||
<mxGeometry x="713.6599731445312" y="191.75" width="100" height="92" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="41" value="<div style='width: 93.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Solve Velocity Constraints </span></div><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">(per island)</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#fff2cc;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=44;" parent="40" vertex="1">
|
||||
<mxGeometry width="100" height="75" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="42" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">V</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff0000;strokeColor=#333333;gradientColor=#FFAAAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=226;" parent="40" vertex="1">
|
||||
<mxGeometry x="18.65999984741211" y="75" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="43" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">P</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#00ff00;strokeColor=#333333;gradientColor=#AAFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=224;" parent="40" vertex="1">
|
||||
<mxGeometry x="1.1368683772161603e-13" y="75" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="48" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">V</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff0000;strokeColor=#333333;gradientColor=#FFAAAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=240;" parent="1" vertex="1">
|
||||
<mxGeometry x="228.52406311035156" y="523.5" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="49" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">P</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#00ff00;strokeColor=#333333;gradientColor=#AAFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=238;" parent="1" vertex="1">
|
||||
<mxGeometry x="209.8640594482422" y="523.5" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="50" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">V</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff0000;strokeColor=#333333;gradientColor=#FFAAAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=258;" parent="1" vertex="1">
|
||||
<mxGeometry x="984.6599731445312" y="219.75" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="51" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">P</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff0000;strokeColor=#333333;gradientColor=#FFAAAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=256;" parent="1" vertex="1">
|
||||
<mxGeometry x="966" y="219.75" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="52" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">P</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff0000;strokeColor=#333333;gradientColor=#FFAAAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=270;" parent="1" vertex="1">
|
||||
<mxGeometry x="1456.2425537109375" y="228.25" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="53" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=295;exitX=1.0;exitY=0.5;exitPerimeter=0;entryX=0.0;entryY=0.5;entryPerimeter=0;" parent="1" source="4" target="71" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="309.86407470703125" y="490.94696044921875" />
|
||||
<mxPoint x="359.5240783691406" y="490.8939208984375" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="54" value="<div style='width: 93.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Broad Phase Update Finalize</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ffffff;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=296;" parent="1" vertex="1">
|
||||
<mxGeometry x="565" y="132.25" width="100" height="75" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="55" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=298;exitX=1.0;exitY=0.7071067690849304;exitPerimeter=0;entryX=0.0;entryY=0.7071067690849304;entryPerimeter=0;" parent="1" source="71" target="54" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="459.5240478515625" y="504.3558654785156" />
|
||||
<mxPoint x="565" y="185.2830047607422" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="56" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=299;exitX=1.0;exitY=0.5;exitPerimeter=0;entryX=0.0;entryY=0.5;entryPerimeter=0;" parent="1" source="54" target="9" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="665" y="169.75" />
|
||||
<mxPoint x="848" y="181.75" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="57" value="<div style='width: 93.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Start Next Step</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ffffff;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=311;" parent="1" vertex="1">
|
||||
<mxGeometry x="1963.757548828125" y="528.43" width="100" height="37.3939208984375" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="58" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=313;exitX=1.0;exitY=0.5;exitPerimeter=0;" parent="1" source="104" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<mxPoint x="2200" y="182.5" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="59" value="<div style='width: 178.16px;height:auto;word-break: break-word;'><div align="left"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; line-height: 14px; color: rgb(0, 0, 0);">Repeat CollisionStep Times</span></div></div>" style="text;html=1;nl2Br=0;html=1;nl2Br=0;verticalAlign=middle;align=left;spacingLeft=0.0;spacingRight=0;whiteSpace=wrap;gliffyId=323;" parent="1" vertex="1">
|
||||
<mxGeometry x="148" y="101.75" width="181.16000366210938" height="14" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="60" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=327;edgeStyle=orthogonalEdgeStyle;" parent="1" source="57" target="5" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="42" y="550" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="61" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">A</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#00ff00;strokeColor=#333333;gradientColor=#AAFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=343;" parent="1" vertex="1">
|
||||
<mxGeometry x="181.5" y="12" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="62" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">A</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff0000;strokeColor=#333333;gradientColor=#FFAAAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=341;" parent="1" vertex="1">
|
||||
<mxGeometry x="181.8640594482422" y="47.5" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="63" value="<div style='width: 147.0px;height:auto;word-break: break-word;'><div align="left"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Reads active bodies</span></div></div>" style="text;html=1;nl2Br=0;html=1;nl2Br=0;verticalAlign=middle;align=left;spacingLeft=0.0;spacingRight=0;whiteSpace=wrap;gliffyId=340;" parent="1" vertex="1">
|
||||
<mxGeometry x="205.16000366210938" y="14" width="150" height="14" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="64" value="<div style='width: 147.0px;height:auto;word-break: break-word;'><div align="left"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Deactivates bodies</span></div></div>" style="text;html=1;nl2Br=0;html=1;nl2Br=0;verticalAlign=middle;align=left;spacingLeft=0.0;spacingRight=0;whiteSpace=wrap;gliffyId=339;" parent="1" vertex="1">
|
||||
<mxGeometry x="204.52406311035156" y="49" width="150" height="14" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="65" style="group;gliffyId=450;" parent="1" vertex="1">
|
||||
<mxGeometry x="359.5240478515625" y="319" width="100" height="77" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="66" value="<div style='width: 93.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Build Islands from Constraints</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ffffff;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=133;" parent="65" vertex="1">
|
||||
<mxGeometry width="100" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="67" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">P</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#00ff00;strokeColor=#333333;gradientColor=#AAFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=334;" parent="65" vertex="1">
|
||||
<mxGeometry y="60" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="68" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">A</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff9900;strokeColor=#333333;gradientColor=#FFFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=346;" parent="65" vertex="1">
|
||||
<mxGeometry x="18.65999984741211" y="60" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="69" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">A</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff0000;strokeColor=#333333;gradientColor=#FFAAAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=350;" parent="1" vertex="1">
|
||||
<mxGeometry x="1474.9024658203125" y="227.75" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="70" style="group;gliffyId=555;" parent="1" vertex="1">
|
||||
<mxGeometry x="359.5240478515625" y="458.3939208984375" width="100" height="82.1060791015625" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="71" value="<div style='width: 93.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Find Collisions </span></div><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">(per batch of active bodies and per pair)</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#fff2cc;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=6;" parent="70" vertex="1">
|
||||
<mxGeometry width="100" height="65" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="72" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">P</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#00ff00;strokeColor=#333333;gradientColor=#AAFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=215;" parent="70" vertex="1">
|
||||
<mxGeometry y="65.1060791015625" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="73" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">V</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#00ff00;strokeColor=#333333;gradientColor=#AAFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=354;" parent="70" vertex="1">
|
||||
<mxGeometry x="18.65999984741211" y="65.1060791015625" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="74" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">A</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff9900;strokeColor=#333333;gradientColor=#FFFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=362;" parent="70" vertex="1">
|
||||
<mxGeometry x="37.31999969482422" y="65" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="75" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#fff2cc;strokeColor=#333333;opacity=100.0;gliffyId=380;" parent="1" vertex="1">
|
||||
<mxGeometry x="182.5" y="69.25" width="15.65999984741211" height="15.5" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="76" value="<div style='width: 147.0px;height:auto;word-break: break-word;'><div align="left"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Multiple concurrent jobs</span></div></div>" style="text;html=1;nl2Br=0;html=1;nl2Br=0;verticalAlign=middle;align=left;spacingLeft=0.0;spacingRight=0;whiteSpace=wrap;gliffyId=382;" parent="1" vertex="1">
|
||||
<mxGeometry x="205.3300018310547" y="70.75" width="150" height="14" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="77" value="<div style='width: 93.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Determine Active Constraints </span></div><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">(in batches)</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#fff2cc;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=392;" parent="1" vertex="1">
|
||||
<mxGeometry x="210.5" y="319" width="100" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="78" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=394;edgeStyle=orthogonalEdgeStyle;" parent="1" source="77" target="66" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="310.5" y="349" />
|
||||
<mxPoint x="326.8413391113281" y="349" />
|
||||
<mxPoint x="343.1827087402344" y="349" />
|
||||
<mxPoint x="359.5240478515625" y="349" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="79" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=399;exitX=1.0;exitY=0.5;exitPerimeter=0;entryX=0.0;entryY=0.5;entryPerimeter=0;" parent="1" source="77" target="8" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="310.5" y="349" />
|
||||
<mxPoint x="360.3299865722656" y="228.625" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="80" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">A</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff9900;strokeColor=#333333;gradientColor=#FFFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=438;" parent="1" vertex="1">
|
||||
<mxGeometry x="181.8640594482422" y="29.5" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="81" value="<div style='width: 147.0px;height:auto;word-break: break-word;'><div align="left"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Activates bodies</span></div></div>" style="text;html=1;nl2Br=0;html=1;nl2Br=0;verticalAlign=middle;align=left;spacingLeft=0.0;spacingRight=0;whiteSpace=wrap;gliffyId=437;" parent="1" vertex="1">
|
||||
<mxGeometry x="204.52406311035156" y="31" width="150" height="14" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="82" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">A</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#00ff00;strokeColor=#333333;gradientColor=#AAFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=444;" parent="1" vertex="1">
|
||||
<mxGeometry x="210.5" y="379" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="83" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=468;exitX=1.0;exitY=0.7071067690849304;exitPerimeter=0;entryX=0.0;entryY=0.7071067690849304;entryPerimeter=0;" parent="1" source="71" target="10" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="459.5240478515625" y="504.3558654785156" />
|
||||
<mxPoint x="565" y="361.7339172363281" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="84" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;dashed=1;fixDash=1;dashPattern=2.0 2.0;gliffyId=471;edgeStyle=orthogonalEdgeStyle;" parent="1" source="71" target="71" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="430.2347412109375" y="458.3939208984375" />
|
||||
<mxPoint x="430.2347412109375" y="437.8939208984375" />
|
||||
<mxPoint x="388.8133850097656" y="437.8939208984375" />
|
||||
<mxPoint x="388.8133850097656" y="458.3939208984375" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="85" value="<div style='width: 67.0px;height:auto;word-break: break-word;'><div align="left"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Can spawn </span></div><div align="left"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">more jobs</span></div></div>" style="text;html=1;nl2Br=0;html=1;nl2Br=0;verticalAlign=middle;align=left;spacingLeft=0.0;spacingRight=0;whiteSpace=wrap;gliffyId=472;" parent="1" vertex="1">
|
||||
<mxGeometry x="380.5040588378906" y="408.75" width="70" height="28" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="86" value="<div style='width: 93.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Find CCD Contacts </span></div><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">(per body)</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#fff2cc;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=484;" parent="1" vertex="1">
|
||||
<mxGeometry x="1208.2425537109375" y="143.75" width="100" height="75" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="87" value="<div style='width: 93.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Resolve CCD Contacts </span></div><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);"></span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ffffff;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=486;" parent="1" vertex="1">
|
||||
<mxGeometry x="1330.2425537109375" y="143.75" width="100" height="75" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="88" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=488;exitX=1.0;exitY=0.5;exitPerimeter=0;entryX=0.0;entryY=0.5;entryPerimeter=0;" parent="1" source="87" target="13" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="1430.2425537109375" y="181.25" />
|
||||
<mxPoint x="1456.2425537109375" y="182.25" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="89" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=489;edgeStyle=orthogonalEdgeStyle;" parent="1" source="86" target="87" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="1308.2425537109375" y="181.25" />
|
||||
<mxPoint x="1330.2425537109375" y="181.25" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="90" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;dashed=1;fixDash=1;dashPattern=2.0 2.0;gliffyId=490;edgeStyle=orthogonalEdgeStyle;" parent="1" source="117" target="87" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="1134.232421875" y="143.25" />
|
||||
<mxPoint x="1134.232421875" y="125.75" />
|
||||
<mxPoint x="1380.242431640625" y="125.75" />
|
||||
<mxPoint x="1380.242431640625" y="143.75" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="91" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">V</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff0000;strokeColor=#333333;gradientColor=#FFAAAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=496;" parent="1" vertex="1">
|
||||
<mxGeometry x="1348.9024658203125" y="218.75" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="92" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">P</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff0000;strokeColor=#333333;gradientColor=#FFAAAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=494;" parent="1" vertex="1">
|
||||
<mxGeometry x="1330.2425537109375" y="218.75" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="93" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">A</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff9900;strokeColor=#333333;gradientColor=#FFFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=498;" parent="1" vertex="1">
|
||||
<mxGeometry x="1367.5625" y="218.75" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="94" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">P</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#00ff00;strokeColor=#333333;gradientColor=#AAFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=532;" parent="1" vertex="1">
|
||||
<mxGeometry x="1208.2425537109375" y="218.75" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="95" value="<div style='width: 165.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Finalize Contact Cache, </span></div><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Contact Removed Callbacks</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ffffff;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=3.5;spacingRight=0;whiteSpace=wrap;gliffyId=538;" parent="1" vertex="1">
|
||||
<mxGeometry x="1292.7425097656248" y="265.6015197753906" width="175" height="60.69696044921875" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="96" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;fixDash=1;gliffyId=540;edgeStyle=orthogonalEdgeStyle;" parent="1" source="86" target="95" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="1258" y="296" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="97" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=542;exitX=1;exitY=0.5;entryX=0;entryY=0.5;entryDx=0;entryDy=0;elbow=vertical;exitDx=0;exitDy=0;edgeStyle=orthogonalEdgeStyle;" parent="1" source="95" target="104" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="2071" y="296" />
|
||||
</Array>
|
||||
<mxPoint x="1467.742509765625" y="270.85" as="sourcePoint" />
|
||||
<mxPoint x="2091.0025537109377" y="315.69999999999993" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="98" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">V</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#00ff00;strokeColor=#333333;gradientColor=#AAFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=543;" parent="1" vertex="1">
|
||||
<mxGeometry x="1226.9024658203125" y="218.75" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="104" style="shape=rhombus;perimeter=rhombusPerimeter;shadow=0;strokeWidth=2;fillColor=#FFFFFF;strokeColor=#333333;opacity=100.0;gliffyId=566;" parent="1" vertex="1">
|
||||
<mxGeometry x="2071.0025537109377" y="167.65" width="34" height="29" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="105" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=568;edgeStyle=orthogonalEdgeStyle;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="104" target="57" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<mxPoint x="2073.7575488281254" y="485.73" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="106" value="<div style='width: 64.0px;height:auto;word-break: break-word;'><div align="left"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Not </span></div><div align="left"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Last </span></div><div align="left"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Step</span></div></div>" style="text;html=1;nl2Br=0;html=1;nl2Br=0;verticalAlign=middle;align=left;spacingLeft=0.0;spacingRight=0;whiteSpace=wrap;gliffyId=570;" parent="1" vertex="1">
|
||||
<mxGeometry x="2100" y="203.25" width="35.25" height="42" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="107" value="<div style='width: 68.5px;height:auto;word-break: break-word;'><div align="left"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Last Step</span></div></div>" style="text;html=1;nl2Br=0;html=1;nl2Br=0;verticalAlign=middle;align=left;spacingLeft=0.0;spacingRight=0;whiteSpace=wrap;gliffyId=571;" parent="1" vertex="1">
|
||||
<mxGeometry x="2105.0025537109377" y="160.05303955078125" width="71.5" height="14" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="110" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=581;exitX=1.0;exitY=0.5;exitPerimeter=0;entryX=0.0;entryY=0.5;entryPerimeter=0;" parent="1" source="5" target="112" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="49.160003662109375" y="414" />
|
||||
<mxPoint x="82.5" y="413.80303955078125" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="111" style="group;gliffyId=607;" parent="1" vertex="1">
|
||||
<mxGeometry x="82.5" y="383.80303955078125" width="100" height="77" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="112" value="<div style='width: 93.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Step Listeners </span></div><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">(in batches)</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#fff2cc;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=579;" parent="111" vertex="1">
|
||||
<mxGeometry width="100" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="113" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">P</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#00ff00;strokeColor=#333333;gradientColor=#AAFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=583;" parent="111" vertex="1">
|
||||
<mxGeometry y="60" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="114" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">V</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff0000;strokeColor=#333333;gradientColor=#FFAAAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=585;" parent="111" vertex="1">
|
||||
<mxGeometry x="18.65999984741211" y="60" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="115" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">A</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff9900;strokeColor=#333333;gradientColor=#FFFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=587;" parent="111" vertex="1">
|
||||
<mxGeometry x="36.31999969482422" y="60" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="116" value="<div style='width: 93.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Integrate &amp; Clamp Velocities (in batches)</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#fff2cc;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=609;" parent="1" vertex="1">
|
||||
<mxGeometry x="966" y="144.25" width="100" height="75" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="117" value="<div style='width: 93.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Post Integrate</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ffffff;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=611;" parent="1" vertex="1">
|
||||
<mxGeometry x="1084.2325439453125" y="143.25" width="100" height="75" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="118" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=615;exitX=1.0;exitY=0.5;exitPerimeter=0;entryX=0.0;entryY=0.5;entryPerimeter=0;" parent="1" source="116" target="117" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="1066" y="181.75" />
|
||||
<mxPoint x="1084.2325439453125" y="180.75" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="119" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;gliffyId=616;edgeStyle=orthogonalEdgeStyle;" parent="1" source="9" target="116" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="948" y="181.75" />
|
||||
<mxPoint x="966" y="181.75" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="120" value="<div style='width: 147.0px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">If no CCD bodies</span></div></div>" style="text;html=1;nl2Br=0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.0;spacingRight=0;whiteSpace=wrap;gliffyId=617;" parent="1" vertex="1">
|
||||
<mxGeometry x="1108.2425537109375" y="108.75" width="150" height="14" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="121" style="shape=filledEdge;strokeWidth=2;strokeColor=#000000;fillColor=none;startArrow=none;startFill=0;startSize=6;endArrow=block;endFill=1;endSize=6;rounded=0;dashed=1;fixDash=1;dashPattern=2.0 2.0;gliffyId=618;edgeStyle=orthogonalEdgeStyle;" parent="1" source="66" target="71" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<Array as="points">
|
||||
<mxPoint x="459.5240783691406" y="361.4263916015625" />
|
||||
<mxPoint x="483.5240783691406" y="361.4263916015625" />
|
||||
<mxPoint x="483.5240783691406" y="490.8939208984375" />
|
||||
<mxPoint x="459.5240783691406" y="490.8939208984375" />
|
||||
</Array>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="122" value="<div style='width: 67.0px;height:auto;word-break: break-word;'><div align="left"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">Starts the final job</span></div></div>" style="text;html=1;nl2Br=0;html=1;nl2Br=0;verticalAlign=middle;align=left;spacingLeft=0.0;spacingRight=0;whiteSpace=wrap;gliffyId=619;" parent="1" vertex="1">
|
||||
<mxGeometry x="427" y="381.94696044921875" width="70" height="28" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="2HlbSkl1Hx2XcQlONuJN-122" value="<div style="width: 93.0px;height:auto;word-break: break-word;"><div align="center"><font face="Arial" color="#000000"><span style="white-space-collapse: preserve;">Soft Body Prepare</span></font></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ffffff;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=48;" parent="1" vertex="1">
|
||||
<mxGeometry x="1580" y="151.74999999999997" width="100" height="59.6" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="2HlbSkl1Hx2XcQlONuJN-123" value="<div style="width: 93.0px;height:auto;word-break: break-word;"><div><font face="Arial" color="#000000"><span style="white-space-collapse: preserve;">Soft Body </span></font><span style="white-space-collapse: preserve; color: rgb(0, 0, 0); font-family: Arial; background-color: initial;">Collide</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#FFF2CC;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=48;" parent="1" vertex="1">
|
||||
<mxGeometry x="1700" y="151.74999999999997" width="110" height="59.6" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="2HlbSkl1Hx2XcQlONuJN-124" value="<div style="width: 93.0px;height:auto;word-break: break-word;"><div align="center"><font face="Arial" color="#000000"><span style="white-space-collapse: preserve;">Soft Body Simulate</span></font></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#FFF2CC;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=48;" parent="1" vertex="1">
|
||||
<mxGeometry x="1830" y="151.74999999999997" width="100" height="59.6" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="2HlbSkl1Hx2XcQlONuJN-125" value="<div style="width: 93.0px;height:auto;word-break: break-word;"><div align="center"><font face="Arial" color="#000000"><span style="white-space-collapse: preserve;">Soft Body Finalize</span></font></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ffffff;strokeColor=#333333;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=2.0;spacingRight=0;whiteSpace=wrap;gliffyId=48;" parent="1" vertex="1">
|
||||
<mxGeometry x="1950" y="151.74999999999997" width="100" height="59.6" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="2HlbSkl1Hx2XcQlONuJN-127" value="" style="endArrow=block;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeWidth=2;strokeColor=#000000;endFill=1;" parent="1" source="2HlbSkl1Hx2XcQlONuJN-122" target="2HlbSkl1Hx2XcQlONuJN-123" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="2210" y="118.85000000000005" as="sourcePoint" />
|
||||
<mxPoint x="2232.25" y="118.85000000000005" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="2HlbSkl1Hx2XcQlONuJN-128" value="" style="endArrow=block;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeWidth=2;strokeColor=#000000;endFill=1;" parent="1" source="2HlbSkl1Hx2XcQlONuJN-123" target="2HlbSkl1Hx2XcQlONuJN-124" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1688" y="191.35" as="sourcePoint" />
|
||||
<mxPoint x="1710" y="191.35" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="2HlbSkl1Hx2XcQlONuJN-129" value="" style="endArrow=block;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeWidth=2;strokeColor=#000000;endFill=1;" parent="1" source="2HlbSkl1Hx2XcQlONuJN-124" target="2HlbSkl1Hx2XcQlONuJN-125" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1698" y="201.35" as="sourcePoint" />
|
||||
<mxPoint x="1720" y="201.35" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="2HlbSkl1Hx2XcQlONuJN-130" value="" style="endArrow=block;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;strokeWidth=2;strokeColor=#000000;endFill=1;" parent="1" source="2HlbSkl1Hx2XcQlONuJN-125" target="104" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="1708" y="211.35" as="sourcePoint" />
|
||||
<mxPoint x="1730" y="211.35" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="2HlbSkl1Hx2XcQlONuJN-134" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">P</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#00ff00;strokeColor=#333333;gradientColor=#AAFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=191;" parent="1" vertex="1">
|
||||
<mxGeometry x="1580" y="212.45000000000002" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="2HlbSkl1Hx2XcQlONuJN-136" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">P</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff0000;strokeColor=#333333;gradientColor=#FFAAAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=200;" parent="1" vertex="1">
|
||||
<mxGeometry x="1950" y="211.35" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="2HlbSkl1Hx2XcQlONuJN-137" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">V</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff0000;strokeColor=#333333;gradientColor=#FFAAAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=198;" parent="1" vertex="1">
|
||||
<mxGeometry x="1967" y="211.35" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="2HlbSkl1Hx2XcQlONuJN-138" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">P</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#00ff00;strokeColor=#333333;gradientColor=#AAFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=191;" parent="1" vertex="1">
|
||||
<mxGeometry x="1700" y="211.35" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="2HlbSkl1Hx2XcQlONuJN-139" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">V</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#00ff00;strokeColor=#333333;gradientColor=#AAFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=194;" parent="1" vertex="1">
|
||||
<mxGeometry x="1717.6599999999999" y="211.35" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="2HlbSkl1Hx2XcQlONuJN-140" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">V</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff0000;strokeColor=#333333;gradientColor=#FFAAAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=198;" parent="1" vertex="1">
|
||||
<mxGeometry x="1830" y="212.45000000000002" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1HMQW9uxuVFfJUHc01B5-122" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">A</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff9900;strokeColor=#333333;gradientColor=#FFFFAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=438;" parent="1" vertex="1">
|
||||
<mxGeometry x="1984.0040594482423" y="211.35" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="1HMQW9uxuVFfJUHc01B5-123" value="<div style='width: 13.32px;height:auto;word-break: break-word;'><div align="center"><span style="font-size: 12px; font-family: Arial; white-space: pre-wrap; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);">A</span></div></div>" style="shape=rect;shadow=0;strokeWidth=2;fillColor=#ff0000;strokeColor=#333333;gradientColor=#FFAAAA;gradientDirection=north;opacity=100.0;html=1;nl2Br=0;verticalAlign=middle;align=center;spacingLeft=0.34;spacingRight=0;whiteSpace=wrap;gliffyId=341;" parent="1" vertex="1">
|
||||
<mxGeometry x="2001.0040594482423" y="211.35" width="17" height="17" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
4
src/JoltPhysics/Docs/PhysicsSystemUpdate.svg
Normal file
After Width: | Height: | Size: 116 KiB |
16
src/JoltPhysics/Docs/ProjectsUsingJolt.md
Normal file
@ -0,0 +1,16 @@
|
||||
# Projects Using Jolt
|
||||
|
||||
* [Dagor Engine](https://github.com/GaijinEntertainment/DagorEngine) - An open source engine used by [War Thunder](https://warthunder.com/). See [here](https://github.com/GaijinEntertainment/DagorEngine/tree/main/prog/engine/phys/physJolt).
|
||||
* [ezEngine](https://github.com/ezEngine/ezEngine) - An open source C++ game engine.
|
||||
* [Godot Jolt](https://github.com/godot-jolt/godot-jolt) - Godot extension that integrates the Jolt physics engine
|
||||
* [Horizon Forbidden West](https://www.playstation.com/en-us/games/horizon-forbidden-west/) - An open world action RPG adventure.
|
||||
* [HypeHype](https://www.hypehype.com/) - A mobile app to create, remix and play games. See [this](https://twitter.com/SebAaltonen/status/1726871354228482237) X post.
|
||||
* [Light Tracer Render](https://lighttracer.org/) - A rendering tool, uses Jolt for object placement. See [this](https://lighttracer.org/blog/light-tracer-render-2-4-0/) announcement.
|
||||
* [The Mirror](https://themirror.space/) - A game development platform designed to empower developers and artists with real-time, limitless creativity. See [this](https://twitter.com/themirrorgdp/status/1718019599361323023?s=20) X post.
|
||||
* [NeoAxis Engine](https://www.neoaxis.com/) - A 3D game engine. See [this](https://www.neoaxis.com/news/neoaxis_engine_2023_1_released) announcement.
|
||||
* [Sceneri](https://www.sceneri.com/) - A mobile app for creating and sharing 3D games and experiences. See [this](https://www.sceneri.com/blog/2023-07-27-jolt-physics-bringing-sceneris-worlds-to-life) blog post.
|
||||
* [Substrata](https://substrata.info/) - A metaverse platform.
|
||||
* [VPhysics Jolt](https://github.com/Joshua-Ashton/VPhysics-Jolt), a replacement for Ipion Virtual Physics in the Source Engine. Can be used in e.g. [Garry's Mod](https://store.steampowered.com/app/4000/Garrys_Mod/).
|
||||
* [X4 Foundations](https://store.steampowered.com/app/392160/X4_Foundations/) - A space simulation game. See [this](https://forum.egosoft.com/viewtopic.php?t=451046) announcement.
|
||||
|
||||
If your project is using Jolt, open a discussion or send a PR to add it to the list.
|
209
src/JoltPhysics/Docs/ReleaseNotes.md
Normal file
@ -0,0 +1,209 @@
|
||||
# Release Notes
|
||||
|
||||
For breaking API changes see [this document](https://github.com/jrouwe/JoltPhysics/blob/master/Docs/APIChanges.md).
|
||||
|
||||
## v5.0.0
|
||||
|
||||
### New Functionality
|
||||
|
||||
#### Soft Body
|
||||
|
||||
* Added soft body skinning constraints. This can be used to limit the movement of soft body vertices based on a skinned mesh. See [documentation](https://jrouwe.github.io/JoltPhysics/index.html#skinning-soft-bodies) for more info or watch this [movie](https://www.youtube.com/watch?v=NXw8yMczHJg).
|
||||
* Added ability to turn on/off skinning constraints and to update the max distance for all constraints with a distance multiplier.
|
||||
* Added dihedral bend constraints for soft bodies. See [movie](https://www.youtube.com/watch?v=A1iswelnGH4).
|
||||
* Added long range attachment constraints (also called tethers) for soft bodies.
|
||||
* Added SoftBodyContactListener which allows you to get callbacks for collisions between soft bodies and rigid bodies. See [movie](https://www.youtube.com/watch?v=DmS_8d2bdOw).
|
||||
* Added support for a vertex radius for soft bodies. This keeps the vertices a fixed distance away from the surface which can be used to avoid z-fighting while rendering the soft body.
|
||||
* Added SoftBodySharedSettings::CreateConstraints function that can automatically generate constraints based on the faces of the soft body.
|
||||
* Added ability to update a soft body outside of the physics simulation step using SoftBodyMotionProperties::CustomUpdate. This is e.g. useful if the soft body is teleported and needs to 'settle'.
|
||||
|
||||
#### Vehicles
|
||||
|
||||
* Added support for less than 1 collision test per simulation step for vehicle wheels. This behavior can be configured differently when the vehicle is active / inactive. This can be used for LODding vehicles.
|
||||
* Added wheel index to VehicleConstraint::CombineFunction friction callback and calculating longitudinal and lateral friction in the same call so you can have more differentiation between wheels.
|
||||
* Added ability to override the max tire impulse calculations for wheeled vehicles. See WheeledVehicleController::SetTireMaxImpulseCallback.
|
||||
* Added ability to disable the lean steering limit for the motorcycle, turning this off makes the motorcycle more unstable, but gives you more control over the final steering angle.
|
||||
|
||||
#### Character
|
||||
|
||||
* CharacterVirtual will now receive an OnContactAdded callback when it collides with a sensor (but will have no further interaction).
|
||||
* Added user data to CharacterVirtual.
|
||||
|
||||
#### Constraints
|
||||
|
||||
* Swing limits do not need to be symmetrical anymore for SixDOFConstraints. This requires using the new pyramid shaped swing limits (ESwingType::Pyramid). SwingTwistConstraints still requires symmetrical limits but can use the pyramid swing limits too. These are cheaper to evaluate but are less smooth.
|
||||
* Twist limits no longer need to be centered around zero for SixDOFConstraints and SwingTwistConstraints, any value between -PI and PI is supported now.
|
||||
* Changed the meaning of Constraint::mNumVelocity/PositionStepsOverride. Before the number of steps would be the maximum of all constraints and the default value, now an overridden value of 0 means that the constraint uses the default value, otherwise it will use the value as specified. This means that if all constraints in an island have a lower value than the default, we will now use the lower value instead of the default. This allows simulating an island at a lower precision than the default.
|
||||
* Bodies can now also override the default number of solver iterations. This value is used when the body collides with another body and a contact constraint is created (for constraints, the constraint override is always used).
|
||||
* Added fraction hint to PathConstraintPath::GetClosestPoint. This can be used to speed up the search along the curve and to disambiguate fractions in case a path reaches the same point multiple times (i.e. a figure-8).
|
||||
* Added Constraint::ResetWarmStart and Ragdoll::ResetWarmStart. Used to notify the system that the configuration of the bodies and/or constraint has changed enough so that the warm start impulses should not be applied the next frame. You can use this function for example when repositioning a ragdoll through Ragdoll::SetPose in such a way that the orientation of the bodies completely changes so that the previous frame impulses are no longer a good approximation of what the impulses will be in the next frame.
|
||||
* Multithreading the SetupVelocityConstraints job. This was causing a bottleneck in the case that there are a lot of constraints but very few possible collisions.
|
||||
|
||||
#### Collision Detection
|
||||
|
||||
* Created an object layer filter implementation that is similar to Bullet's group & mask filtering, see ObjectLayerPairFilterMask.
|
||||
* Created implementations of BroadPhaseLayerInterface, ObjectVsBroadPhaseLayerFilter and ObjectLayerPairFilter that use a bit table internally. These make it easier to define ObjectLayers and with which object layers they collide.
|
||||
* Renamed SensorDetectsStatic to CollideKinematicVsNonDynamic and made it work for non-sensors. This means that kinematic bodies can now get collision callbacks when they collide with other static / kinematic objects.
|
||||
* Added function to query the bounding box of all bodies in the physics system, see PhysicsSystem::GetBounds.
|
||||
|
||||
#### Simulation
|
||||
|
||||
* Implemented enhanced internal edge removal algorithm. This should help reduce ghost collisions. See BodyCreationSettings::mEnhancedInternalEdgeRemoval and [movie](https://www.youtube.com/watch?v=Wh5MIiiPVDE).
|
||||
* Added BodyInterface::SetUseManifoldReduction which will clear the contact cache and ensure that you get consistent contact callbacks in case the body that you're changing already has contacts.
|
||||
|
||||
#### Various
|
||||
|
||||
* Ability to enable gyroscopic forces on bodies to create the [Dzhanibekov effect](https://en.wikipedia.org/wiki/Tennis_racket_theorem).
|
||||
* Supporting SIMD for WASM build. Use -msimd128 -msse4.2 options with emscripten to enable this.
|
||||
* Allowing WASM build to use a custom memory allocator.
|
||||
* Added DebugRendererSimple which can be used to simplify the creation of your own DebugRenderer implementation. It only requires a DrawLine, DrawTriangle and DrawText3D function to be implemented (which can be left empty).
|
||||
* Added ability to update the height field materials after creation.
|
||||
|
||||
### Removed functionality
|
||||
* Ability to restrict rotational degrees of freedom in local space, instead this is now done in world space.
|
||||
|
||||
### Bug fixes
|
||||
|
||||
* Fixed a bug in cast sphere vs triangle that could return a false positive hit against a degenerate triangle.
|
||||
* Fixed bug in soft body vs tapered capsule. The calculations were slightly off causing a normal on the top or bottom sphere to be returned while the tapered part was actually closest.
|
||||
* Fixed bug where colliding a cyclinder against a large triangle could return an incorrect contact point.
|
||||
* Fixed bug where soft bodies would collide with sensors as if they were normal bodies.
|
||||
* Sensors will no longer use speculative contacts, so will no longer report contacts before an actual contact is detected.
|
||||
* Hinge limit constraint forces were clamped wrongly when the hinge was exactly at the minimum limit, making it harder to push the hinge towards the maximum limit.
|
||||
* Fixed bug when a body with limited DOFs collides with static. If the resulting contact had an infinite effective mass, we would divide by zero and crash.
|
||||
* Fixed unit tests failing when compiling for 32-bit Linux. The compiler defaults to using x87 instructions in this case which does not work well with the collision detection pipeline. Now defaulting to the SSE instructions.
|
||||
* Fixed assert and improved interaction between a fast moving rigid body of quality LinearCast and a soft body.
|
||||
* When creating a MeshShape with triangles that have near identical positions it was possible that the degenerate check decided that a triangle was not degenerate while the triangle in fact would be degenerate after vertex quantization. The simulation would crash when colliding with this triangle.
|
||||
* A scaled compound shape with a center of mass of non zero would not apply the correct transform to its sub shapes when colliding with a soft body
|
||||
* A soft body without any edges would hang the solver
|
||||
* Fixed GCC 11.4 warning in JobSystemThreadPool.cpp: output may be truncated copying 15 bytes from a string of length 63
|
||||
* Longitudinal friction impulse for wheeled/tracked vehicles could become much higher than the calculated max because each iteration it was clamped to the max friction impulse which meant the total friction impulse could be PhysicsSettings::mNumVelocitySteps times too high.
|
||||
* Properly initializing current engine RPM to min RPM for wheeled/tracked vehicles. When min RPM was lower than the default min RPM the engine would not start at min RPM.
|
||||
* Fixed a possible division by zero in Body::GetBodyCreationSettings when the inverse inertia diagonal had 0's.
|
||||
* When specifying a -1 for min/max distance of a distance constraint and the calculated distance is incompatible with the other limit, we'll clamp it to that value now instead of ending up with min > max.
|
||||
* Fixed bug that contact cache was partially uninitialized when colliding two objects with inv mass override of 0. When the contact listener would report a non zero inv mass override the next simulation step this would mean that the simulation would read garbage and potentially crash due to NaNs.
|
||||
|
||||
## v4.0.2
|
||||
|
||||
### New functionality
|
||||
* Support for compiling with ninja on Windows.
|
||||
|
||||
### Bug fixes
|
||||
* Fixed bug in Indexify function that caused it to be really slow when passing 10K identical vertices. Also fixed a problem that could have led to some vertices not being welded.
|
||||
* Fixed bug in SixDOFConstraint::RestoreState that would cause motors to not properly turn on.
|
||||
* Fixed a determinism issue in CharacterVirtual. The order of the contacts returned by GetActiveContacts() was not deterministic.
|
||||
* Fixed issue in sample application that mouse is very sensitive when viewing with Parsec.
|
||||
|
||||
## v4.0.1
|
||||
|
||||
### New functionality
|
||||
* Ability to stop overriding CMAKE_CXX_FLAGS_DEBUG/CMAKE_CXX_FLAGS_RELEASE which is important for Android as it uses a lot of extra flags. Set the OVERRIDE_CXX_FLAGS=NO cmake flag to enable this.
|
||||
* Reduced size of a contact constraint which saves a bit of memory during simulation.
|
||||
* Can now build a linux shared library using GCC.
|
||||
|
||||
### Bug fixes
|
||||
* Fixed mass scaling (as provided by the ContactListener) not applied correctly to CCD objects & during solve position constraints. This led to kinematic objects being pushed by dynamic objects.
|
||||
* Workaround for MSVC 17.8, limits.h doesn't include corecrt.h and triggers an error that \_\_STDC_WANT_SECURE_LIB\_\_ is not defined.
|
||||
* Fixed bug in MustIncludeC logic in GetClosestPointOnTriangle.
|
||||
* Removed the need for specifying -Wno-comment when compiling with GCC.
|
||||
|
||||
## v4.0.0
|
||||
|
||||
### New functionality
|
||||
* Added support for soft bodies (feature still in development, see [announcement](https://x.com/jrouwe/status/1687051655898955776?s=20)).
|
||||
* Support for limiting the degrees of freedom of a body to support 2D simulations (see [announcement](https://x.com/jrouwe/status/1676311800797622279?s=20)).
|
||||
* Support for setting surface velocity of a body (see [announcement](https://x.com/jrouwe/status/1662727355553443844?s=20)).
|
||||
* Added ability to update a height field after creation (see [announcement](https://x.com/jrouwe/status/1713670512801390829?s=20)).
|
||||
* Support for non-power of 2 height fields.
|
||||
* Expose a function to compare the JOLT_VERSION_ID with the version the library was compiled with to detect mismatches between library and client code.
|
||||
* Added ability to specify extra ragdoll constraints that are not parent/child related.
|
||||
* Ability to selectively save the state of a physics system to support replicating state over the network.
|
||||
* Added constraint priority to control the order of evaluation of constraints (and thereby the most influential constraints).
|
||||
* Sensors can now detect static objects.
|
||||
* Ability to override mass and inertia of bodies from the ContactListener.
|
||||
* Ability to specify stiffness/damping for springs instead of frequency/damping.
|
||||
* Added option to disable the lean spring controller for motorcycles.
|
||||
* Added vehicle callbacks at the beginning of the step listener and after wheel checks.
|
||||
* Ability to override the position where the suspension and tire forces are applied.
|
||||
* Support for building Jolt as a shared library on Windows.
|
||||
* Optimized Indexify function from O(N^2) to O(N log(N)).
|
||||
|
||||
### Removed functionality
|
||||
* Removed support for integration sub steps for PhysicsSystem::Update.
|
||||
|
||||
### New supported platforms
|
||||
* 32-bit versions of Android on ARM and x86.
|
||||
|
||||
### Bug fixes
|
||||
* Motor frequency/stiffness of 0 should turn the motor off.
|
||||
* RotatedTranslatedShape::GetPosition returned the wrong value.
|
||||
* If a body is removed between the broad phase detecting an overlap and the narrow phase locking the body, callbacks could be called on a body that has already been removed.
|
||||
* Fixed flipped normals in EPA penetration depth algorithm which could cause the normal to point in the wrong direction for collision tests.
|
||||
* Respecting the IsSensor flag for CCD bodies.
|
||||
* Fixed double locking issue that could cause a deadlock while updating the AABB of a body during simulation.
|
||||
* Fixed a crash when fetching a body using an invalid BodyID.
|
||||
* Windows 32 vs 64-bit versions produce the same deterministic results now.
|
||||
* Heightfield vs convex was not filled in in collision dispatch table. This caused sensors to assert and not detect collisions with heightfields.
|
||||
* The friction applied during continuous collision detection could be sqrt(2) times too large.
|
||||
* The friction was clamped independently on both tangential axis which meant that the total friction could be larger than the amount of friction that should have been allowed. It also meant that an object would slow down quicker on one axis than on another causing a curved trajectory.
|
||||
* When an object wasn't moving fast enough to trigger restitution for a speculative contact, the contact was enforced at the current position rather than at the distance of the speculative contact.
|
||||
* Fixed CharacterVirtual jittering issue when moving down on elevator.
|
||||
* CharacterVirtual was speeding up beyond the requested speed when sliding along a wall.
|
||||
* CharacterVirtual reported to be on ground for one more frame after jumping against a wall.
|
||||
* Added missing delta time term in CharacterVirtual::DetermineConstraints.
|
||||
* CastShape had incorrect early out condition which could cause it to miss the deepest penetration.
|
||||
* Pitch/roll limit constraint for vehicles didn't work when local vehicle up did not match world up.
|
||||
* Wheel contact point did not return deepest point in certain cases.
|
||||
* Fix for engine RPM being much higher than wheel RPM when measured at clutch. Before we were ignoring bake and wheel torques in engine RPM calculation.
|
||||
* Don't allow the vehicle to sleep when the transmission is switching.
|
||||
* Fixed bug that caused suspension to be weaker when driving a vehicle over dynamic bodies.
|
||||
|
||||
## v3.0.0
|
||||
|
||||
* Support for double precision simulation for large worlds (see [announcement](https://twitter.com/jrouwe/status/1599366630273712128))
|
||||
* Performance optimization that allows solving large islands on multiple threads (see [announcement](https://twitter.com/jrouwe/status/1633229953775828994))
|
||||
* Vehicles now support suspensions that are at an angle with the vehicle body (instead of 90 degrees)
|
||||
* Supporting cylinder based wheels for vehicles
|
||||
* Experimental motor cycle physics (see [announcement](https://twitter.com/jrouwe/status/1642479907383959553))
|
||||
* CharacterVirtual can now move relative to a moving object (e.g. a space ship)
|
||||
* Added 2D physics example
|
||||
* Added functionality to estimate the collision impulse in the contact added callback
|
||||
* Added a JobSystemWithBarrier class that makes it easier to integrate with your own job system
|
||||
* Support for 32-bit object layers to allow easier integration with existing collision filtering systems
|
||||
|
||||
## v2.0.1
|
||||
|
||||
* Adds ARM 32-bit support to support vcpkg-tool
|
||||
|
||||
## v2.0.0
|
||||
|
||||
### Major new functionality
|
||||
* Simulation is now deterministic between Windows, Linux and macOS.
|
||||
* Support for custom memory allocators.
|
||||
* A new character class that lives outside the main simulation update and is mainly used for player movement (CharacterVirtual).
|
||||
* Implemented skeleton mapper that can convert an animated skeleton to a ragdoll skeleton and back.
|
||||
* Rack and pinion, gear and pulley constraints have been added.
|
||||
* Ability for sensors to detect collisions with sleeping bodies.
|
||||
* Improved engine model for wheeled vehicles.
|
||||
* Most constraints can now also be configured in local space.
|
||||
|
||||
### New supported compilers
|
||||
* MinGW
|
||||
* GCC
|
||||
|
||||
### New supported platforms
|
||||
* All intel platforms supporting SSE2 and higher (was SSE4.2)
|
||||
* 32-bit applications (was 64 bit only)
|
||||
* Windows on ARM
|
||||
* Windows UWP
|
||||
* macOS
|
||||
* iOS
|
||||
* WebAssembly
|
||||
|
||||
## v1.1.0
|
||||
|
||||
* Optimizations.
|
||||
|
||||
## v1.0.0
|
||||
|
||||
* Initial stable release.
|
168
src/JoltPhysics/Docs/Samples.md
Normal file
@ -0,0 +1,168 @@
|
||||
# Jolt Physics Samples
|
||||
|
||||
This document describes the demos in the Samples application (currently compiles only under Windows). When you run the samples application the application will initially start paused, press P to unpause it. The menu is accessible through pressing ESC, it has the following options:
|
||||
|
||||
* Select Test - This allows you to select between the different types of physics tests
|
||||
* Test Settings - Some tests will allow extra configuration, if not this setting will be greyed out
|
||||
* Restart Test (R) - When selecting this, the test will go back to its initial state
|
||||
* Run All Tests - This will run every tests for 10 seconds before proceeding to the next. This is a good way of visually inspecting the simulation before commiting a code change.
|
||||
* Next Test (N) - When running all tests, this option can be used to quickly skip to the next test.
|
||||
* Physics Settings - This menu contains all physics configuration.
|
||||
* Drawing Options - This menu shows all the options for drawing the internal state of the physics simulation.
|
||||
* Mouse Probe - This allows you to switch between various collision detection modes to test the different collision detection algorithms
|
||||
* Shoot Object - A sample application is not complete without being able to shoot some balls at the simulation (B key). This menu allows additional settings.
|
||||
* Help - A quick help text.
|
||||
|
||||
## General Controls
|
||||
|
||||
* Use the Mouse and WSAD keys to move around, hold Shift to speed up and Ctrl to slow down
|
||||
* Hold the Space key to pick up an object in the center of the screen and move it around with the mouse and WSAD.
|
||||
* P - Pause / unpause simulation.
|
||||
* O - Single step the simulation.
|
||||
* , - Step back (only when Physics Settings / Record State for Playback is on).
|
||||
* . - Step forward (only when Physics Settings / Record State for Playback is on).
|
||||
* Shift + , - Play reverse (only when Physics Settings / Record State for Playback is on).
|
||||
* Shift + . - Replay forward (only when Physics Settings / Record State for Playback is on).
|
||||
* T - Dump frame timing information to profile_*.html (when JPH_PROFILE_ENABLED defined).
|
||||
|
||||
## The Tests
|
||||
|
||||
Note that you can watch all movies below in [a single YouTube playlist](https://www.youtube.com/watch?v=pwyCW0yNKMA&list=PLYXVwtOr1CBxbA50jVg2dKUQvHW_5OOom).
|
||||
|
||||
### Vehicles
|
||||
|
||||
This categories shows vehicles created through the VehicleConstraint. These vehicles use ray- or shape casts to detect collision with the ground and simulate a vehicle with an engine, gearbox, differentials and suspension.
|
||||
|
||||
|[](https://www.youtube.com/watch?v=A_gvLH4KKDA)|
|
||||
|:-|
|
||||
|*A wheeled vehicle.*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=QwlPOKbxsqU)|
|
||||
|:-|
|
||||
|*Demonstrates a tracked vehicle with a turret constrained to the main body with hinge constraints.*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=umI8FF0gVxs)|
|
||||
|:-|
|
||||
|*Demonstrates a motor cycle.*|
|
||||
|
||||
### Rig (Ragdolls)
|
||||
|
||||
This category demonstrates how ragdolls can be made and controlled using keyframing or motors.
|
||||
|
||||
|[](https://www.youtube.com/watch?v=gvq6qdU3ZTs)|
|
||||
|:-|
|
||||
|*A ragdoll set to kinematic mode (infinite mass, simulated using velocities only) interacting with dynamic objects.*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=lYHhe6HLbs4)|
|
||||
|:-|
|
||||
|*Demonstrating a humanoid ragdoll driven by motors which are trying to match a sprint animation in local space (green sticks).*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=hrnmgNN-m-U)|
|
||||
|:-|
|
||||
|*An animation is played back on a high detail skeleton ('Animation') and then mapped onto a low detail ragdoll skeleton ('Reversed Mapped'). This animation is used to drive the motors of the ragdoll. The resulting pose is mapped back to the high detail skeleton ('Mapped'). Note that the skeletons are drawn offset to make them clearer..*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=pwyCW0yNKMA)|
|
||||
|:-|
|
||||
|*160 Ragdolls being dropped on a scene from Horizon Zero Dawn.*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=7ZMm7yObpqs)|
|
||||
|:-|
|
||||
|*160 Ragdolls dropping on a pile, simulated using the Jolt Physics engine. Yellow means the ragdoll is simulated, red means the simulation is sleeping.*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=jhpsIqbsU4I)|
|
||||
|:-|
|
||||
|*A pile of ragdolls that are driven to a specific animated death pose. This gives the ragdolls 'stiffness'.*|
|
||||
|
||||
### Soft Body
|
||||
|
||||
|[](https://www.youtube.com/watch?v=vJX_3FNISkw)|
|
||||
|:-|
|
||||
|*Demonstrates Soft Body physics as simulated by Jolt Physics. Soft body physics can be used for things like cloth and soft balls.*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=DmS_8d2bdOw)|
|
||||
|:-|
|
||||
|*Demonstrates the use of soft body contact listeners. You can use these to affect the collision response between a soft body and a rigid body by e.g. artificially making the mass of one of the two higher so that the other is less affected by the collision. Finally you can also turn a contact into a sensor contact which means you get the contact points but there will not be any collision response..*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=A1iswelnGH4)|
|
||||
|:-|
|
||||
|*This video shows the effect of bend constraints on a wrinkled cloth. The left most patch has no constraints to preserve the wrinkles, the middle uses distance constrains ('sticks') to preserve the wrinkles and the last one uses dihedral angle constraints to preserve the angle between two triangles on their shared edge.*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=NXw8yMczHJg)|
|
||||
|:-|
|
||||
|*This demo shows a soft body that is connected to a skinned mesh via distance constraints. Each simulated vertex can deviate from its skinned position by a fixed length. The green lines indicate the animated joints of the skinned mesh.*|
|
||||
|
||||
### Character
|
||||
|
||||
This category shows how you can simulate a (humanoid) character using a capsule.
|
||||
|
||||
|[](https://www.youtube.com/watch?v=YjaJT9of7UE)|
|
||||
|:-|
|
||||
|*A demonstration of a game Character. Demonstrates moving, sliding against the environment, crouching and jumping.*|
|
||||
|
||||
### Water
|
||||
|
||||
This category shows how you can implement a water simulation in your game.
|
||||
|
||||
|[](https://www.youtube.com/watch?v=CEr_LtQLGeg)|
|
||||
|:-|
|
||||
|*Water buoyancy and friction simulation. Demonstrates how various shapes and compound shapes behave in the water. The right most object has a lowered center of mass.*|
|
||||
|
||||
### Constraints
|
||||
|
||||
This category shows the various constraints that are supported. Constraints connect two or more bodies together and limit the relative movement.
|
||||
|
||||
|[](https://www.youtube.com/watch?v=6xMKNMjD5pE)|
|
||||
|:-|
|
||||
|*Showing the path constraint in action.*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=8aQ9x8SQSuM)|
|
||||
|:-|
|
||||
|*Demonstrates a chain of swing-twist constraints (usable for humanoid shoulders). The green cones show the swing limit and the pink pie shows the twist limit.*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=3w5SgElroBw)|
|
||||
|:-|
|
||||
|*Demonstrates a gear constraint. Note that the gears can be placed at any relative angle of each other, so you could e.g. create a bevel or worm gear.*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=e588KG-ZSxc)|
|
||||
|:-|
|
||||
|*Demonstrates a rack and pinion constraint.*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=9P8OaahtU-4)|
|
||||
|:-|
|
||||
|*Shows two boxes connected through a pulley constraint. In this case the constraint is configured as a block and tackle with and advantage of 2: the right block moves 2x as slow as the left block.*|
|
||||
|
||||
### General
|
||||
|
||||
This category contains general simulation tests. It demonstrates things like friction, restitution, damping, modifying gravity and continous collision detection. Some highlights:
|
||||
|
||||
|[](https://www.youtube.com/watch?v=fTtjBLYBxco)|
|
||||
|:-|
|
||||
|*A YouTube video showing stability of a pile of boxes.*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=EanFxlkZgcA)|
|
||||
|:-|
|
||||
|*Demonstrates objects sliding along a polygon mesh. Internal mesh edges are ignored and do not cause objects to bounce off.*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=Y-UgylH992A)|
|
||||
|:-|
|
||||
|*1000 random shapes in a funnel.*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=_Lv5xlWtCpM)|
|
||||
|:-|
|
||||
|*We will automatically split up the simulation in islands of non-interacting bodies and distribute the work across multiple threads. Each island has its own color.*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=KGnlYSW3550)|
|
||||
|:-|
|
||||
|*Shows the difference between compiling Jolt Physics in single precision and double precision (define JPH_DOUBLE_PRECISION).*|
|
||||
|
||||
|[](https://www.youtube.com/watch?v=p_H6egZzbZE)|
|
||||
|:-|
|
||||
|*A demo of setting the surface velocity of a body to create a conveyor belt. The boxes have decreasing friction from front to back (last one has zero friction so slowly slides down the ramp).*|
|
||||
|
||||
### Shapes & Scaled Shapes
|
||||
|
||||
These categories show off all of the supported shapes and how they can be scaled at run-time.
|
||||
|
||||
|[](https://www.youtube.com/watch?v=u9cPBGUFurc)|
|
||||
|:-|
|
||||
|*A height field shape using various scales in Jolt Physics: Uniform, Non uniform, Mirrored, Inside out*|
|
BIN
src/JoltPhysics/Docs/SwingTwistConstraint.png
Normal file
After Width: | Height: | Size: 90 KiB |