1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
|
package vendor_box2d
import "base:intrinsics"
import "core:c"
when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
@(private) VECTOR_EXT :: "_simd" when #config(VENDOR_BOX2D_ENABLE_SIMD128, intrinsics.has_target_feature("simd128")) else ""
} else {
@(private) VECTOR_EXT :: "avx2" when #config(VENDOR_BOX2D_ENABLE_AVX2, intrinsics.has_target_feature("avx2")) else "sse2"
}
when ODIN_OS == .Windows {
@(private) LIB_PATH :: "lib/box2d_windows_amd64_" + VECTOR_EXT + ".lib"
} else when ODIN_OS == .Darwin && ODIN_ARCH == .arm64 {
@(private) LIB_PATH :: "lib/box2d_darwin_arm64.a"
} else when ODIN_OS == .Darwin {
@(private) LIB_PATH :: "lib/box2d_darwin_amd64_" + VECTOR_EXT + ".a"
} else when ODIN_ARCH == .amd64 {
@(private) LIB_PATH :: "lib/box2d_other_amd64_" + VECTOR_EXT + ".a"
} else when ODIN_ARCH == .wasm32 || ODIN_ARCH == .wasm64p32 {
@(private) LIB_PATH :: "lib/box2d_wasm" + VECTOR_EXT + ".o"
} else {
@(private) LIB_PATH :: "lib/box2d_other.a"
}
when !#exists(LIB_PATH) {
#panic("Could not find the compiled box2d libraries at \"" + LIB_PATH + "\", they can be compiled by running the `build_box2d.sh` script at `" + ODIN_ROOT + "vendor/box2d/build_box2d.sh\"`")
}
foreign import lib {
LIB_PATH,
}
// Prototype for user allocation function
// @param size the allocation size in bytes
// @param alignment the required alignment, guaranteed to be a power of 2
AllocFcn :: #type proc "c" (size: u32, alignment: i32) -> rawptr
// Prototype for user free function
// @param mem the memory previously allocated through `b2AllocFcn`
FreeFcn :: #type proc "c" (mem: rawptr)
// Prototype for the user assert callback. Return 0 to skip the debugger break.
AssertFcn :: #type proc "c" (condition, file_name: cstring, line_number: i32) -> i32
// Version numbering scheme.
//
// See https://semver.org/
Version :: struct {
major: i32, // Significant changes
minor: i32, // Incremental changes
revision: i32, // Bug fixes
}
HASH_INIT :: 5381
@(link_prefix="b2", default_calling_convention="c", require_results)
foreign lib {
// This allows the user to override the allocation functions. These should be
// set during application startup.
SetAllocator :: proc(allocFcn: AllocFcn, freefcn: FreeFcn) ---
// @return the total bytes allocated by Box2D
GetByteCount :: proc() -> c.int ---
// Override the default assert callback
// @param assertFcn a non-null assert callback
SetAssertFcn :: proc(assertfcn: AssertFcn) ---
// Get the absolute number of system ticks. The value is platform specific.
GetTicks :: proc() -> u64 ---
// Get the milliseconds passed from an initial tick value.
GetMilliseconds :: proc(ticks: u64) -> f32 ---
// Get the milliseconds passed from an initial tick value. Resets the passed in
// value to the current tick value.
GetMillisecondsAndReset :: proc(ticks: ^u64) -> f32 ---
// Yield to be used in a busy loop.
Yield :: proc() ---
// Simple djb2 hash function for determinism testing.
Hash :: proc(hash: u32, data: [^]byte, count: c.int) -> u32 ---
// Box2D bases all length units on meters, but you may need different units for your game.
// You can set this value to use different units. This should be done at application startup
// and only modified once. Default value is 1.
// For example, if your game uses pixels for units you can use pixels for all length values
// sent to Box2D. There should be no extra cost. However, Box2D has some internal tolerances
// and thresholds that have been tuned for meters. By calling this function, Box2D is able
// to adjust those tolerances and thresholds to improve accuracy.
// A good rule of thumb is to pass the height of your player character to this function. So
// if your player character is 32 pixels high, then pass 32 to this function. Then you may
// confidently use pixels for all the length values sent to Box2D. All length values returned
// from Box2D will also be pixels because Box2D does not do any scaling internally.
// However, you are now on the hook for coming up with good values for gravity, density, and
// forces.
// @warning This must be modified before any calls to Box2D
SetLengthUnitsPerMeter :: proc(lengthUnits: f32) ---
// Get the current length units per meter.
GetLengthUnitsPerMeter :: proc() -> f32 ---
}
@(link_prefix="b2", default_calling_convention="c", require_results)
foreign lib {
// Use this to initialize your world definition
// @ingroup world
DefaultWorldDef :: proc() -> WorldDef ---
// Use this to initialize your body definition
// @ingroup body
DefaultBodyDef :: proc() -> BodyDef ---
// Use this to initialize your filter
// @ingroup shape
DefaultFilter :: proc() -> Filter ---
// Use this to initialize your query filter
// @ingroup shape
DefaultQueryFilter :: proc() -> QueryFilter ---
// Use this to initialize your surface material
// @ingroup shape
DefaultSurfaceMaterial :: proc() -> SurfaceMaterial ---
// Use this to initialize your shape definition
// @ingroup shape
DefaultShapeDef :: proc() -> ShapeDef ---
// Use this to initialize your chain definition
// @ingroup shape
DefaultChainDef :: proc() -> ChainDef ---
// Use this to initialize your joint definition
// @ingroup distance_joint
DefaultDistanceJointDef :: proc() -> DistanceJointDef ---
// Use this to initialize your joint definition
// @ingroup motor_joint
DefaultMotorJointDef :: proc() -> MotorJointDef ---
// Use this to initialize your joint definition
// @ingroup mouse_joint
DefaultMouseJointDef :: proc() -> MouseJointDef ---
// Use this to initialize your joint definition
// @ingroup filter_joint
DefaultFilterJointDef :: proc() -> FilterJointDef ---
// Use this to initialize your joint definition
// @ingroupd prismatic_joint
DefaultPrismaticJointDef :: proc() -> PrismaticJointDef ---
// Use this to initialize your joint definition.
// @ingroup revolute_joint
DefaultRevoluteJointDef :: proc() -> RevoluteJointDef ---
// Use this to initialize your joint definition
// @ingroup weld_joint
DefaultWeldJointDef :: proc() -> WeldJointDef ---
// Use this to initialize your joint definition
// @ingroup wheel_joint
DefaultWheelJointDef :: proc() -> WheelJointDef ---
// Use this to initialize your explosion definition
// @ingroup world
DefaultExplosionDef :: proc() -> ExplosionDef ---
// Use this to initialize your drawing interface. This allows you to implement a sub-set
// of the drawing functions.
DefaultDebugDraw :: proc() -> DebugDraw ---
}
@(link_prefix="b2", default_calling_convention="c", require_results)
foreign lib {
// Validate ray cast input data (NaN, etc)
IsValidRay :: proc(#by_ptr input: RayCastInput) -> bool ---
// Make a convex polygon from a convex hull. This will assert if the hull is not valid.
// @warning Do not manually fill in the hull data, it must come directly from b2ComputeHull
MakePolygon :: proc(#by_ptr hull: Hull, radius: f32) -> Polygon ---
// Make an offset convex polygon from a convex hull. This will assert if the hull is not valid.
// @warning Do not manually fill in the hull data, it must come directly from b2ComputeHull
MakeOffsetPolygon :: proc(#by_ptr hull: Hull, position: Vec2, rotation: Rot) -> Polygon ---
// Make an offset convex polygon from a convex hull. This will assert if the hull is not valid.
// @warning Do not manually fill in the hull data, it must come directly from b2ComputeHull
MakeOffsetRoundedPolygon :: proc(#by_ptr hull: Hull, position: Vec2, rotation: Rot, radius: f32) -> Polygon ---
// Make a square polygon, bypassing the need for a convex hull.
MakeSquare :: proc(halfWidth: f32) -> Polygon ---
// Make a box (rectangle) polygon, bypassing the need for a convex hull.
MakeBox :: proc(halfWidth, halfHeight: f32) -> Polygon ---
// Make a rounded box, bypassing the need for a convex hull.
MakeRoundedBox :: proc(halfWidth, halfHeight: f32, radius: f32) -> Polygon ---
// Make an offset box, bypassing the need for a convex hull.
MakeOffsetBox :: proc(halfWidth, halfHeight: f32, center: Vec2, rotation: Rot) -> Polygon ---
// Make an offset rounded box, bypassing the need for a convex hull.
MakeOffsetRoundedBox :: proc(halfWidth, halfHeight: f32, center: Vec2, rotation: Rot, radius: f32) -> Polygon ---
// Transform a polygon. This is useful for transferring a shape from one body to another.
TransformPolygon :: proc(transform: Transform, #by_ptr polygon: Polygon) -> Polygon ---
// Compute mass properties of a circle
ComputeCircleMass :: proc(#by_ptr shape: Circle, density: f32) -> MassData ---
// Compute mass properties of a capsule
ComputeCapsuleMass :: proc(#by_ptr shape: Capsule, density: f32) -> MassData ---
// Compute mass properties of a polygon
ComputePolygonMass :: proc(#by_ptr shape: Polygon, density: f32) -> MassData ---
// Compute the bounding box of a transformed circle
ComputeCircleAABB :: proc(#by_ptr shape: Circle, transform: Transform) -> AABB ---
// Compute the bounding box of a transformed capsule
ComputeCapsuleAABB :: proc(#by_ptr shape: Capsule, transform: Transform) -> AABB ---
// Compute the bounding box of a transformed polygon
ComputePolygonAABB :: proc(#by_ptr shape: Polygon, transform: Transform) -> AABB ---
// Compute the bounding box of a transformed line segment
ComputeSegmentAABB :: proc(#by_ptr shape: Segment, transform: Transform) -> AABB ---
// Test a point for overlap with a circle in local space
PointInCircle :: proc(point: Vec2, #by_ptr shape: Circle) -> bool ---
// Test a point for overlap with a capsule in local space
PointInCapsule :: proc(point: Vec2, #by_ptr shape: Capsule) -> bool ---
// Test a point for overlap with a convex polygon in local space
PointInPolygon :: proc(point: Vec2, #by_ptr shape: Polygon) -> bool ---
// Ray cast versus circle in shape local space. Initial overlap is treated as a miss.
RayCastCircle :: proc(#by_ptr input: RayCastInput, #by_ptr shape: Circle) -> CastOutput ---
// Ray cast versus capsule in shape local space. Initial overlap is treated as a miss.
RayCastCapsule :: proc(#by_ptr input: RayCastInput, #by_ptr shape: Capsule) -> CastOutput ---
// Ray cast versus segment in shape local space. Optionally treat the segment as one-sided with hits from
// the left side being treated as a miss.
RayCastSegment :: proc(#by_ptr input: RayCastInput, #by_ptr shape: Segment, oneSided: bool) -> CastOutput ---
// Ray cast versus polygon in shape local space. Initial overlap is treated as a miss.
RayCastPolygon :: proc(#by_ptr input: RayCastInput, #by_ptr shape: Polygon) -> CastOutput ---
// Shape cast versus a circle. Initial overlap is treated as a miss.
ShapeCastCircle :: proc(#by_ptr input: ShapeCastInput, #by_ptr shape: Circle) -> CastOutput ---
// Shape cast versus a capsule. Initial overlap is treated as a miss.
ShapeCastCapsule :: proc(#by_ptr input: ShapeCastInput, #by_ptr shape: Capsule) -> CastOutput ---
// Shape cast versus a line segment. Initial overlap is treated as a miss.
ShapeCastSegment :: proc(#by_ptr input: ShapeCastInput, #by_ptr shape: Segment) -> CastOutput ---
// Shape cast versus a convex polygon. Initial overlap is treated as a miss.
ShapeCastPolygon :: proc(#by_ptr input: ShapeCastInput, #by_ptr shape: Polygon) -> CastOutput ---
}
// Compute the convex hull of a set of points. Returns an empty hull if it fails.
// Some failure cases:
// - all points very close together
// - all points on a line
// - less than 3 points
// - more than MAX_POLYGON_VERTICES points
// This welds close points and removes collinear points.
// @warning Do not modify a hull once it has been computed
@(require_results)
ComputeHull :: proc "c" (points: []Vec2) -> Hull {
foreign lib {
b2ComputeHull :: proc "c" (points: [^]Vec2, count: i32) -> Hull ---
}
return b2ComputeHull(raw_data(points), i32(len(points)))
}
@(link_prefix="b2", default_calling_convention="c", require_results)
foreign lib {
// This determines if a hull is valid. Checks for:
// - convexity
// - collinear points
// This is expensive and should not be called at runtime.
ValidateHull :: proc(#by_ptr hull: Hull) -> bool ---
}
@(link_prefix="b2", default_calling_convention="c", require_results)
foreign lib {
// Compute the distance between two line segments, clamping at the end points if needed.
SegmentDistance :: proc(p1, q1: Vec2, p2, q2: Vec2) -> SegmentDistanceResult ---
}
// Compute the closest points between two shapes represented as point clouds.
// SimplexCache cache is input/output. On the first call set SimplexCache.count to zero.
// The underlying GJK algorithm may be debugged by passing in debug simplexes and capacity. You may pass in NULL and 0 for these.
@(require_results)
ShapeDistance :: proc "c" (#by_ptr input: DistanceInput, cache: ^SimplexCache, simplexes: []Simplex) -> DistanceOutput {
foreign lib {
b2ShapeDistance :: proc "c" (#by_ptr input: DistanceInput, cache: ^SimplexCache, simplexes: [^]Simplex, simplexCapacity: c.int) -> DistanceOutput ---
}
return b2ShapeDistance(input, cache, raw_data(simplexes), i32(len(simplexes)))
}
// Make a proxy for use in overlap, shape cast, and related functions. This is a deep copy of the points.
@(require_results)
MakeProxy :: proc "c" (points: []Vec2, radius: f32) -> ShapeProxy {
foreign lib {
b2MakeProxy :: proc "c" (points: [^]Vec2, count: i32, radius: f32) -> ShapeProxy ---
}
return b2MakeProxy(raw_data(points), i32(len(points)), radius)
}
// Make a proxy with a transform. This is a deep copy of the points.
@(require_results)
MakeOffsetProxy :: proc "c" (points: []Vec2, radius: f32, position: Vec2, rotation: Rot) -> ShapeProxy {
foreign lib {
b2MakeOffsetProxy :: proc "c" (points: [^]Vec2, count: i32, radius: f32, position: Vec2, rotation: Rot) -> ShapeProxy ---
}
return b2MakeOffsetProxy(raw_data(points), i32(len(points)), radius, position, rotation)
}
@(link_prefix="b2", default_calling_convention="c", require_results)
foreign lib {
// Perform a linear shape cast of shape B moving and shape A fixed. Determines the hit point, normal, and translation fraction.
// You may optionally supply an array to hold debug data.
ShapeCast :: proc(#by_ptr input: ShapeCastPairInput) -> CastOutput ---
// Evaluate the transform sweep at a specific time.
GetSweepTransform :: proc(#by_ptr sweep: Sweep, time: f32) -> Transform ---
// Compute the upper bound on time before two shapes penetrate. Time is represented as
// a fraction between [0,tMax]. This uses a swept separating axis and may miss some intermediate,
// non-tunneling collisions. If you change the time interval, you should call this function
// again.
TimeOfImpact :: proc(#by_ptr input: TOIInput) -> TOIOutput ---
}
@(link_prefix="b2", default_calling_convention="c", require_results)
foreign lib {
// Compute the contact manifold between two circles
CollideCircles :: proc(#by_ptr circleA: Circle, xfA: Transform, #by_ptr circleB: Circle, xfB: Transform) -> Manifold ---
// Compute the contact manifold between a capsule and circle
CollideCapsuleAndCircle :: proc(#by_ptr capsuleA: Capsule, xfA: Transform, #by_ptr circleB: Circle, xfB: Transform) -> Manifold ---
// Compute the contact manifold between an segment and a circle
CollideSegmentAndCircle :: proc(#by_ptr segmentA: Segment, xfA: Transform, #by_ptr circleB: Circle, xfB: Transform) -> Manifold ---
// Compute the contact manifold between a polygon and a circle
CollidePolygonAndCircle :: proc(#by_ptr polygonA: Polygon, xfA: Transform, #by_ptr circleB: Circle, xfB: Transform) -> Manifold ---
// Compute the contact manifold between a capsule and circle
CollideCapsules :: proc(#by_ptr capsuleA: Capsule, xfA: Transform, #by_ptr capsuleB: Capsule, xfB: Transform) -> Manifold ---
// Compute the contact manifold between an segment and a capsule
CollideSegmentAndCapsule :: proc(#by_ptr segmentA: Segment, xfA: Transform, #by_ptr capsuleB: Capsule, xfB: Transform) -> Manifold ---
// Compute the contact manifold between a polygon and capsule
CollidePolygonAndCapsule :: proc(#by_ptr polygonA: Polygon, xfA: Transform, #by_ptr capsuleB: Capsule, xfB: Transform) -> Manifold ---
// Compute the contact manifold between two polygons
CollidePolygons :: proc(#by_ptr polygonA: Polygon, xfA: Transform, #by_ptr polygonB: Polygon, xfB: Transform) -> Manifold ---
// Compute the contact manifold between an segment and a polygon
CollideSegmentAndPolygon :: proc(#by_ptr segmentA: Segment, xfA: Transform, #by_ptr polygonB: Polygon, xfB: Transform) -> Manifold ---
// Compute the contact manifold between a chain segment and a circle
CollideChainSegmentAndCircle :: proc(#by_ptr segmentA: ChainSegment, xfA: Transform, #by_ptr circleB: Circle, xfB: Transform) -> Manifold ---
// Compute the contact manifold between an segment and a capsule
CollideChainSegmentAndCapsule :: proc(#by_ptr segmentA: ChainSegment, xfA: Transform, #by_ptr capsuleB: Capsule, xfB: Transform, cache: ^SimplexCache) -> Manifold ---
// Compute the contact manifold between a chain segment and a rounded polygon
CollideChainSegmentAndPolygon :: proc(#by_ptr segmentA: ChainSegment, xfA: Transform, #by_ptr polygonB: Polygon, xfB: Transform, cache: ^SimplexCache) -> Manifold ---
}
@(link_prefix="b2", default_calling_convention="c", require_results)
foreign lib {
// Constructing the tree initializes the node pool.
DynamicTree_Create :: proc() -> DynamicTree ---
// Destroy the tree, freeing the node pool.
DynamicTree_Destroy :: proc(tree: ^DynamicTree) ---
// Create a proxy. Provide an AABB and a userData value.
DynamicTree_CreateProxy :: proc(tree: ^DynamicTree, aabb: AABB, categoryBits: u64, userData: u64) -> i32 ---
// Destroy a proxy. This asserts if the id is invalid.
DynamicTree_DestroyProxy :: proc(tree: ^DynamicTree, proxyId: i32) ---
// Move a proxy to a new AABB by removing and reinserting into the tree.
DynamicTree_MoveProxy :: proc(tree: ^DynamicTree, proxyId: i32, aabb: AABB) ---
// Enlarge a proxy and enlarge ancestors as necessary.
DynamicTree_EnlargeProxy :: proc(tree: ^DynamicTree, proxyId: i32, aabb: AABB) ---
// Modify the category bits on a proxy. This is an expensive operation.
DynamicTree_SetCategoryBits :: proc(tree: ^DynamicTree, proxyId: i32, categoryBits: u64) ---
// Get the category bits on a proxy.
DynamicTree_GetCategoryBits :: proc(tree: ^DynamicTree, proxyId: i32) ---
// Query an AABB for overlapping proxies. The callback class is called for each proxy that overlaps the supplied AABB.
// @return performance data
DynamicTree_Query :: proc(#by_ptr tree: DynamicTree, aabb: AABB, maskBits: u64, callback: TreeQueryCallbackFcn, ctx: rawptr) -> TreeStats ---
// Ray cast against the proxies in the tree. This relies on the callback
// to perform a exact ray cast in the case were the proxy contains a shape.
// The callback also performs the any collision filtering. This has performance
// roughly equal to k * log(n), where k is the number of collisions and n is the
// number of proxies in the tree.
// Bit-wise filtering using mask bits can greatly improve performance in some scenarios.
// However, this filtering may be approximate, so the user should still apply filtering to results.
// @param tree the dynamic tree to ray cast
// @param input the ray cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1)
// @param maskBits mask bit hint: `bool accept = (maskBits & node->categoryBits) != 0;`
// @param callback a callback class that is called for each proxy that is hit by the ray
// @param context user context that is passed to the callback
// @return performance data
DynamicTree_RayCast :: proc(#by_ptr tree: DynamicTree, #by_ptr input: RayCastInput, maskBits: u64, callback: TreeRayCastCallbackFcn, ctx: rawptr) -> TreeStats ---
// Ray cast against the proxies in the tree. This relies on the callback
// to perform a exact ray cast in the case were the proxy contains a shape.
// The callback also performs the any collision filtering. This has performance
// roughly equal to k * log(n), where k is the number of collisions and n is the
// number of proxies in the tree.
// @param tree the dynamic tree to ray cast
// @param input the ray cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
// @param maskBits filter bits: `bool accept = (maskBits & node->categoryBits) != 0 ---`
// @param callback a callback class that is called for each proxy that is hit by the shape
// @param context user context that is passed to the callback
// @return performance data
DynamicTree_ShapeCast :: proc(#by_ptr tree: DynamicTree, #by_ptr input: ShapeCastInput, maskBits: u32, callback: TreeShapeCastCallbackFcn, ctx: rawptr) -> TreeStats ---
// Get the height of the binary tree.
DynamicTree_GetHeight :: proc(#by_ptr tree: DynamicTree) -> c.int ---
// Get the ratio of the sum of the node areas to the root area.
DynamicTree_GetAreaRatio :: proc(#by_ptr tree: DynamicTree) -> f32 ---
// Get the bounding box that contains the entire tree
DynamicTree_GetRootBounds :: proc(#by_ptr tree: DynamicTree) -> AABB ---
// Get the number of proxies created
DynamicTree_GetProxyCount :: proc(#by_ptr tree: DynamicTree) -> c.int ---
// Rebuild the tree while retaining subtrees that haven't changed. Returns the number of boxes sorted.
DynamicTree_Rebuild :: proc(tree: ^DynamicTree, fullBuild: bool) -> c.int ---
// Get the number of bytes used by this tree
DynamicTree_GetByteCount :: proc(#by_ptr tree: DynamicTree) -> c.int ---
// Get proxy user data
DynamicTree_GetUserData :: proc(#by_ptr tree: DynamicTree, proxyId: c.int) -> u64 ---
// Get the AABB of a proxy
DynamicTree_GetAABB :: proc(#by_ptr tree: DynamicTree, proxyId: c.int) -> AABB ---
// Validate this tree. For testing.
DynamicTree_Validate :: proc(#by_ptr tree: DynamicTree) ---
// Validate this tree has no enlarged AABBs. For testing.
DynamicTree_ValidateNoEnlarged :: proc(#by_ptr tree: DynamicTree) ---
}
/**
* @defgroup character Character mover
* Character movement solver
* @{
*/
@(require_results)
SolvePlanes :: proc(position: Vec2, planes: []CollisionPlane) -> PlaneSolverResult {
foreign lib {
b2SolvePlanes :: proc "c" (position: Vec2, planes: [^]CollisionPlane, count: i32) -> PlaneSolverResult ---
}
return b2SolvePlanes(position, raw_data(planes), i32(len(planes)))
}
@(require_results)
ClipVector :: proc(vector: Vec2, planes: []CollisionPlane) -> Vec2 {
foreign lib {
b2ClipVector :: proc "c" (vector: Vec2, planes: [^]CollisionPlane, count: i32) -> Vec2 ---
}
return b2ClipVector(vector, raw_data(planes), i32(len(planes)))
}
/**@}*/
@(link_prefix="b2", default_calling_convention="c", require_results)
foreign lib {
/**
* @defgroup world World
* These functions allow you to create a simulation world.
*
* You can add rigid bodies and joint constraints to the world and run the simulation. You can get contact
* information to get contact points and normals as well as events. You can query to world, checking for overlaps and casting rays
* or shapes. There is also debugging information such as debug draw, timing information, and counters. You can find documentation
* here: https://box2d.org/
*/
// Create a world for rigid body simulation. A world contains bodies, shapes, and constraints. You make create
// up to 128 worlds. Each world is completely independent and may be simulated in parallel.
// @return the world id.
CreateWorld :: proc(#by_ptr def: WorldDef) -> WorldId ---
// Destroy a world
DestroyWorld :: proc(worldId: WorldId) ---
// World id validation. Provides validation for up to 64K allocations.
World_IsValid :: proc(id: WorldId) -> bool ---
// Simulate a world for one time step. This performs collision detection, integration, and constraint solution.
// @param worldId The world to simulate
// @param timeStep The amount of time to simulate, this should be a fixed number. Usually 1/60.
// @param subStepCount The number of sub-steps, increasing the sub-step count can increase accuracy. Usually 4.
World_Step :: proc(worldId: WorldId, timeStep: f32 , subStepCount: c.int) ---
// Call this to draw shapes and other debug draw data
World_Draw :: proc(worldId: WorldId, draw: ^DebugDraw) ---
// Get the body events for the current time step. The event data is transient. Do not store a reference to this data.
World_GetBodyEvents :: proc(worldId: WorldId) -> BodyEvents ---
// Get sensor events for the current time step. The event data is transient. Do not store a reference to this data.
World_GetSensorEvents :: proc(worldId: WorldId) -> SensorEvents ---
// Get contact events for this current time step. The event data is transient. Do not store a reference to this data.
World_GetContactEvents :: proc(worldId: WorldId) -> ContactEvents ---
// Overlap test for all shapes that *potentially* overlap the provided AABB
World_OverlapAABB :: proc(worldId: WorldId, aabb: AABB, filter: QueryFilter, fcn: OverlapResultFcn, ctx: rawptr) -> TreeStats ---
// Overlap test for all shapes that overlap the provided shape proxy.
World_OverlapShape :: proc(worldId: WorldId, #by_ptr proxy: ShapeProxy, filter: QueryFilter, fcn: OverlapResultFcn, ctx: rawptr) -> TreeStats ---
// Cast a ray into the world to collect shapes in the path of the ray.
// Your callback function controls whether you get the closest point, any point, or n-points.
// The ray-cast ignores shapes that contain the starting point.
// @note The callback function may receive shapes in any order
// @param worldId The world to cast the ray against
// @param origin The start point of the ray
// @param translation The translation of the ray from the start point to the end point
// @param filter Contains bit flags to filter unwanted shapes from the results
// @param fcn A user implemented callback function
// @param context A user context that is passed along to the callback function
// @return traversal performance counters
World_CastRay :: proc(worldId: WorldId, origin: Vec2, translation: Vec2, filter: QueryFilter, fcn: CastResultFcn, ctx: rawptr) -> TreeStats ---
// Cast a ray into the world to collect the closest hit. This is a convenience function.
// This is less general than b2World_CastRay() and does not allow for custom filtering.
World_CastRayClosest :: proc(worldId: WorldId, origin: Vec2, translation: Vec2, filter: QueryFilter) -> RayResult ---
// Cast a shape through the world. Similar to a cast ray except that a shape is cast instead of a point.
// @see World_CastRay
World_CastShape :: proc(worldId: WorldId, #by_ptr shape: ShapeProxy, translation: Vec2, filter: QueryFilter, fcn: CastResultFcn, ctx: rawptr) -> TreeStats ---
// Cast a capsule mover through the world. This is a special shape cast that handles sliding along other shapes while reducing
// clipping.
World_CastMover :: proc(worldId: WorldId, #by_ptr mover: Capsule, translation: Vec2, filter: QueryFilter) -> f32 ---
// Collide a capsule mover with the world, gathering collision planes that can be fed to b2SolvePlanes. Useful for
// kinematic character movement.
World_CollideMover :: proc(worldId: WorldId, #by_ptr mover: Capsule, filter: QueryFilter, fcn: PlaneResultFcn, ctx: rawptr) ---
// Enable/disable sleep. If your application does not need sleeping, you can gain some performance
// by disabling sleep completely at the world level.
// @see WorldDef
World_EnableSleeping :: proc(worldId: WorldId, flag: bool) ---
// Is body sleeping enabled?
World_IsSleepingEnabled :: proc(worldId: WorldId) -> bool ---
// Enable/disable continuous collision between dynamic and static bodies. Generally you should keep continuous
// collision enabled to prevent fast moving objects from going through static objects. The performance gain from
// disabling continuous collision is minor.
// @see WorldDef
World_EnableContinuous :: proc(worldId: WorldId, flag: bool) ---
// Is continuous collision enabled?
World_IsContinuousEnabled :: proc(worldId: WorldId) -> bool ---
// Adjust the restitution threshold. It is recommended not to make this value very small
// because it will prevent bodies from sleeping. Usually in meters per second.
// @see WorldDef
World_SetRestitutionThreshold :: proc(worldId: WorldId, value: f32) ---
// Get the restitution speed threshold. Usually in meters per second.
World_GetRestitutionThreshold :: proc(worldId: WorldId) -> f32 ---
// Adjust the hit event threshold. This controls the collision velocity needed to generate a b2ContactHitEvent.
// Usually in meters per second.
// @see WorldDef::hitEventThreshold
World_SetHitEventThreshold :: proc(worldId: WorldId, value: f32) ---
// Get the hit event speed threshold. Usually in meters per second.
World_GetHitEventThreshold :: proc(worldId: WorldId) -> f32 ---
// Register the custom filter callback. This is optional.
World_SetCustomFilterCallback :: proc(worldId: WorldId, fcn: CustomFilterFcn, ctx: rawptr) ---
// Register the pre-solve callback. This is optional.
World_SetPreSolveCallback :: proc(worldId: WorldId, fcn: PreSolveFcn, ctx: rawptr) ---
// Set the gravity vector for the entire world. Box2D has no concept of an up direction and this
// is left as a decision for the application. Usually in m/s^2.
// @see WorldDef
World_SetGravity :: proc(worldId: WorldId, gravity: Vec2) ---
// Get the gravity vector
World_GetGravity :: proc(worldId: WorldId) -> Vec2 ---
// Apply a radial explosion
// @param worldId The world id
// @param explosionDef The explosion definition
World_Explode :: proc(worldId: WorldId, #by_ptr explosionDef: ExplosionDef) ---
// Adjust contact tuning parameters
// @param worldId The world id
// @param hertz The contact stiffness (cycles per second)
// @param dampingRatio The contact bounciness with 1 being critical damping (non-dimensional)
// @param pushSpeed The maximum contact constraint push out speed (meters per second)
// @note Advanced feature
World_SetContactTuning :: proc(worldId: WorldId, hertz: f32, dampingRatio: f32, pushSpeed: f32) ---
// Adjust joint tuning parameters
// @param worldId The world id
// @param hertz The contact stiffness (cycles per second)
// @param dampingRatio The contact bounciness with 1 being critical damping (non-dimensional)
// @note Advanced feature
World_SetJointTuning :: proc(worldId: WorldId, hertz: f32, dampingRatio: f32) ---
// Set the maximum linear speed. Usually in m/s.
World_SetMaximumLinearSpeed :: proc(worldId: WorldId, maximumLinearSpeed: f32) ---
// Get the maximum linear speed. Usually in m/s.
World_GetMaximumLinearSpeed :: proc(worldId: WorldId) -> f32 ---
// Enable/disable constraint warm starting. Advanced feature for testing. Disabling
// warm starting greatly reduces stability and provides no performance gain.
World_EnableWarmStarting :: proc(worldId: WorldId, flag: bool) ---
// Is constraint warm starting enabled?
World_IsWarmStartingEnabled :: proc(worldId: WorldId) -> bool ---
// Get the number of awake bodies.
World_GetAwakeBodyCount :: proc(worldId: WorldId) -> c.int ---
// Get the current world performance profile
World_GetProfile :: proc(worldId: WorldId) -> Profile ---
// Get world counters and sizes
World_GetCounters :: proc(worldId: WorldId) -> Counters ---
// Set the user data pointer.
World_SetUserData :: proc(worldId: WorldId, userData: rawptr) ---
// Get the user data pointer.
World_GetUserData :: proc(worldId: WorldId) -> rawptr ---
// Set the friction callback. Passing nil resets to default.
World_SetFrictionCallback :: proc(worldId: WorldId, callback: FrictionCallback) ---
// Set the restitution callback. Passing nil resets to default.
World_SetRestitutionCallback :: proc(worldId: WorldId, callback: RestitutionCallback) ---
// Dump memory stats to box2d_memory.txt
World_DumpMemoryStats :: proc(worldId: WorldId) ---
// This is for internal testing
World_RebuildStaticTree :: proc(worldId: WorldId) ---
// This is for internal testing
World_EnableSpeculative :: proc(worldId: WorldId, flag: bool) ---
}
@(link_prefix="b2", default_calling_convention="c", require_results)
foreign lib {
/**
* @defgroup body Body
* This is the body API.
*/
// Create a rigid body given a definition. No reference to the definition is retained. So you can create the definition
// on the stack and pass it as a pointer.
// @code{.odin}
// body_def := b2.DefaultBodyDef()
// my_body_id =: b2.CreateBody(my_world_id, body_def)
// @endcode
// @warning This function is locked during callbacks.
CreateBody :: proc(worldId: WorldId, #by_ptr def: BodyDef) -> BodyId ---
// Destroy a rigid body given an id. This destroys all shapes and joints attached to the body.
// Do not keep references to the associated shapes and joints.
DestroyBody :: proc(bodyId: BodyId) ---
// Body identifier validation. Can be used to detect orphaned ids. Provides validation for up to 64K allocations.
Body_IsValid :: proc(id: BodyId) -> bool ---
// Get the body type: static, kinematic, or dynamic
Body_GetType :: proc(bodyId: BodyId) -> BodyType ---
// Change the body type. This is an expensive operation. This automatically updates the mass
// properties regardless of the automatic mass setting.
Body_SetType :: proc(bodyId: BodyId, type: BodyType) ---
// Set the body name. Up to 32 characters excluding 0 termination.
Body_SetName :: proc(bodyId: BodyId, name: cstring) ---
// Get the body name. May be nil.
Body_GetName :: proc(bodyId: BodyId) -> cstring ---
// Set the user data for a body
Body_SetUserData :: proc(bodyId: BodyId, userData: rawptr) ---
// Get the user data stored in a body
Body_GetUserData :: proc(bodyId: BodyId) -> rawptr ---
// Get the world position of a body. This is the location of the body origin.
Body_GetPosition :: proc(bodyId: BodyId) -> Vec2 ---
// Get the world rotation of a body as a cosine/sine pair (complex number)
Body_GetRotation :: proc(bodyId: BodyId) -> Rot ---
// Get the world transform of a body.
Body_GetTransform :: proc(bodyId: BodyId) -> Transform ---
// Set the world transform of a body. This acts as a teleport and is fairly expensive.
// @note Generally you should create a body with then intended transform.
// @see BodyDef::position and BodyDef::angle
Body_SetTransform :: proc(bodyId: BodyId, position: Vec2, rotation: Rot) ---
// Get a local point on a body given a world point
Body_GetLocalPoint :: proc(bodyId: BodyId, worldPoint: Vec2) -> Vec2 ---
// Get a world point on a body given a local point
Body_GetWorldPoint :: proc(bodyId: BodyId, localPoint: Vec2) -> Vec2 ---
// Get a local vector on a body given a world vector
Body_GetLocalVector :: proc(bodyId: BodyId, worldVector: Vec2) -> Vec2 ---
// Get a world vector on a body given a local vector
Body_GetWorldVector :: proc(bodyId: BodyId, localVector: Vec2) -> Vec2 ---
// Get the linear velocity of a body's center of mass. Usually in meters per second.
Body_GetLinearVelocity :: proc(bodyId: BodyId) -> Vec2 ---
// Get the angular velocity of a body in radians per second
Body_GetAngularVelocity :: proc(bodyId: BodyId) -> f32 ---
// Set the linear velocity of a body. Usually in meters per second.
Body_SetLinearVelocity :: proc(bodyId: BodyId, linearVelocity: Vec2) ---
// Set the angular velocity of a body in radians per second
Body_SetAngularVelocity :: proc(bodyId: BodyId, angularVelocity: f32) ---
// Set the velocity to reach the given transform after a given time step.
// The result will be close but maybe not exact. This is meant for kinematic bodies.
// This will automatically wake the body if asleep.
Body_SetTargetTransform :: proc(bodyId: BodyId, target: Transform, timeStep: f32) ---
// Get the linear velocity of a local point attached to a body. Usually in meters per second.
Body_GetLocalPointVelocity :: proc(bodyId: BodyId, localPoint: Vec2) -> Vec2 ---
// Get the linear velocity of a world point attached to a body. Usually in meters per second.
GetWorldPointVelocity :: proc(bodyId: BodyId, worldPoint: Vec2) -> Vec2 ---
// Apply a force at a world point. If the force is not applied at the center of mass,
// it will generate a torque and affect the angular velocity. This optionally wakes up the body.
// The force is ignored if the body is not awake.
// @param bodyId The body id
// @param force The world force vector, usually in newtons (N)
// @param point The world position of the point of application
// @param wake Option to wake up the body
Body_ApplyForce :: proc(bodyId: BodyId, force: Vec2, point: Vec2, wake: bool) ---
// Apply a force to the center of mass. This optionally wakes up the body.
// The force is ignored if the body is not awake.
// @param bodyId The body id
// @param force the world force vector, usually in newtons (N).
// @param wake also wake up the body
Body_ApplyForceToCenter :: proc(bodyId: BodyId, force: Vec2, wake: bool) ---
// Apply a torque. This affects the angular velocity without affecting the linear velocity.
// This optionally wakes the body. The torque is ignored if the body is not awake.
// @param bodyId The body id
// @param torque about the z-axis (out of the screen), usually in N*m.
// @param wake also wake up the body
Body_ApplyTorque :: proc(bodyId: BodyId, torque: f32, wake: bool) ---
// Apply an impulse at a point. This immediately modifies the velocity.
// It also modifies the angular velocity if the point of application
// is not at the center of mass. This optionally wakes the body.
// The impulse is ignored if the body is not awake.
// @param bodyId The body id
// @param impulse the world impulse vector, usually in N*s or kg*m/s.
// @param point the world position of the point of application.
// @param wake also wake up the body
// @warning This should be used for one-shot impulses. If you need a steady force,
// use a force instead, which will work better with the sub-stepping solver.
Body_ApplyLinearImpulse :: proc(bodyId: BodyId, impulse: Vec2, point: Vec2, wake: bool) ---
// Apply an impulse to the center of mass. This immediately modifies the velocity.
// The impulse is ignored if the body is not awake. This optionally wakes the body.
// @param bodyId The body id
// @param impulse the world impulse vector, usually in N*s or kg*m/s.
// @param wake also wake up the body
// @warning This should be used for one-shot impulses. If you need a steady force,
// use a force instead, which will work better with the sub-stepping solver.
Body_ApplyLinearImpulseToCenter :: proc(bodyId: BodyId, impulse: Vec2, wake: bool) ---
// Apply an angular impulse. The impulse is ignored if the body is not awake.
// This optionally wakes the body.
// @param bodyId The body id
// @param impulse the angular impulse, usually in units of kg*m*m/s
// @param wake also wake up the body
// @warning This should be used for one-shot impulses. If you need a steady force,
// use a force instead, which will work better with the sub-stepping solver.
Body_ApplyAngularImpulse :: proc(bodyId: BodyId, impulse: f32, wake: bool) ---
// Get the mass of the body, usually in kilograms
Body_GetMass :: proc(bodyId: BodyId) -> f32 ---
// Get the rotational inertia of the body, usually in kg*m^2
Body_GetRotationalInertia :: proc(bodyId: BodyId) -> f32 ---
// Get the center of mass position of the body in local space
Body_GetLocalCenterOfMass :: proc(bodyId: BodyId) -> Vec2 ---
// Get the center of mass position of the body in world space
Body_GetWorldCenterOfMass :: proc(bodyId: BodyId) -> Vec2 ---
// Override the body's mass properties. Normally this is computed automatically using the
// shape geometry and density. This information is lost if a shape is added or removed or if the
// body type changes.
Body_SetMassData :: proc(bodyId: BodyId, massData: MassData) ---
// Get the mass data for a body
Body_GetMassData :: proc(bodyId: BodyId) -> MassData ---
// This update the mass properties to the sum of the mass properties of the shapes.
// This normally does not need to be called unless you called SetMassData to override
// the mass and you later want to reset the mass.
// You may also use this when automatic mass computation has been disabled.
// You should call this regardless of body type.
Body_ApplyMassFromShapes :: proc(bodyId: BodyId) ---
// Adjust the linear damping. Normally this is set in BodyDef before creation.
Body_SetLinearDamping :: proc(bodyId: BodyId, linearDamping: f32) ---
// Get the current linear damping.
Body_GetLinearDamping :: proc(bodyId: BodyId) -> f32 ---
// Adjust the angular damping. Normally this is set in BodyDef before creation.
Body_SetAngularDamping :: proc(bodyId: BodyId, angularDamping: f32) ---
// Get the current angular damping.
Body_GetAngularDamping :: proc(bodyId: BodyId) -> f32 ---
// Adjust the gravity scale. Normally this is set in BodyDef before creation.
// @see BodyDef::gravityScale
Body_SetGravityScale :: proc(bodyId: BodyId, gravityScale: f32) ---
// Get the current gravity scale
Body_GetGravityScale :: proc(bodyId: BodyId) -> f32 ---
// @return true if this body is awake
Body_IsAwake :: proc(bodyId: BodyId) -> bool ---
// Wake a body from sleep. This wakes the entire island the body is touching.
// @warning Putting a body to sleep will put the entire island of bodies touching this body to sleep,
// which can be expensive and possibly unintuitive.
Body_SetAwake :: proc(bodyId: BodyId, awake: bool) ---
// Enable or disable sleeping for this body. If sleeping is disabled the body will wake.
Body_EnableSleep :: proc(bodyId: BodyId, enableSleep: bool) ---
// Returns true if sleeping is enabled for this body
Body_IsSleepEnabled :: proc(bodyId: BodyId) -> bool ---
// Set the sleep threshold, usually in meters per second
Body_SetSleepThreshold :: proc(bodyId: BodyId, sleepThreshold: f32) ---
// Get the sleep threshold, usually in meters per second.
Body_GetSleepThreshold :: proc(bodyId: BodyId) -> f32 ---
// Returns true if this body is enabled
Body_IsEnabled :: proc(bodyId: BodyId) -> bool ---
// Disable a body by removing it completely from the simulation. This is expensive.
Body_Disable :: proc(bodyId: BodyId) ---
// Enable a body by adding it to the simulation. This is expensive.
Body_Enable :: proc(bodyId: BodyId) ---
// Set this body to have fixed rotation. This causes the mass to be reset in all cases.
Body_SetFixedRotation :: proc(bodyId: BodyId, flag: bool) ---
// Does this body have fixed rotation?
Body_IsFixedRotation :: proc(bodyId: BodyId) -> bool ---
// Set this body to be a bullet. A bullet does continuous collision detection
// against dynamic bodies (but not other bullets).
Body_SetBullet :: proc(bodyId: BodyId, flag: bool) ---
// Is this body a bullet?
Body_IsBullet :: proc(bodyId: BodyId) -> bool ---
// Enable/disable contact events on all shapes.
// @see b2ShapeDef::enableContactEvents
// @warning changing this at runtime may cause mismatched begin/end touch events
Body_EnableContactEvents :: proc(bodyId: BodyId, flag: bool) ---
// Enable/disable hit events on all shapes
// @see b2ShapeDef::enableHitEvents
Body_EnableHitEvents :: proc(bodyId: BodyId, flag: bool) ---
// Get the world that owns this body
Body_GetWorld :: proc(bodyId: BodyId) -> WorldId ---
// Get the number of shapes on this body
Body_GetShapeCount :: proc(bodyId: BodyId) -> c.int ---
// Get the number of joints on this body
Body_GetJointCount :: proc(bodyId: BodyId) -> c.int ---
// Get the maximum capacity required for retrieving all the touching contacts on a body
Body_GetContactCapacity :: proc(bodyId: BodyId) -> c.int ---
// Get the current world AABB that contains all the attached shapes. Note that this may not encompass the body origin.
// If there are no shapes attached then the returned AABB is empty and centered on the body origin.
Body_ComputeAABB :: proc(bodyId: BodyId) -> AABB ---
}
// Get the shape ids for all shapes on this body, up to the provided capacity.
// @returns the shape ids stored in the user array
@(require_results)
Body_GetShapes :: proc "c" (bodyId: BodyId, shapeArray: []ShapeId) -> []ShapeId {
foreign lib {
b2Body_GetShapes :: proc "c" (bodyId: BodyId, shapeArray: [^]ShapeId, capacity: c.int) -> c.int ---
}
n := b2Body_GetShapes(bodyId, raw_data(shapeArray), c.int(len(shapeArray)))
return shapeArray[:n]
}
// Get the joint ids for all joints on this body, up to the provided capacity
// @returns the joint ids stored in the user array
@(require_results)
Body_GetJoints :: proc "c" (bodyId: BodyId, jointArray: []JointId) -> []JointId {
foreign lib {
b2Body_GetJoints :: proc "c" (bodyId: BodyId, jointArray: [^]JointId, capacity: c.int) -> c.int ---
}
n := b2Body_GetJoints(bodyId, raw_data(jointArray), c.int(len(jointArray)))
return jointArray[:n]
}
// Get the touching contact data for a body
@(require_results)
Body_GetContactData :: proc "c" (bodyId: BodyId, contactData: []ContactData) -> []ContactData {
foreign lib {
b2Body_GetContactData :: proc "c" (bodyId: BodyId, contactData: [^]ContactData, capacity: c.int) -> c.int ---
}
n := b2Body_GetContactData(bodyId, raw_data(contactData), c.int(len(contactData)))
return contactData[:n]
}
@(link_prefix="b2", default_calling_convention="c", require_results)
foreign lib {
/**
* @defgroup shape Shape
* Functions to create, destroy, and access.
* Shapes bind raw geometry to bodies and hold material properties including friction and restitution.
*/
// Create a circle shape and attach it to a body. The shape definition and geometry are fully cloned.
// Contacts are not created until the next time step.
// @return the shape id for accessing the shape
CreateCircleShape :: proc(bodyId: BodyId, #by_ptr def: ShapeDef, #by_ptr circle: Circle) -> ShapeId ---
// Create a line segment shape and attach it to a body. The shape definition and geometry are fully cloned.
// Contacts are not created until the next time step.
// @return the shape id for accessing the shape
CreateSegmentShape :: proc(bodyId: BodyId, #by_ptr def: ShapeDef, #by_ptr segment: Segment) -> ShapeId ---
// Create a capsule shape and attach it to a body. The shape definition and geometry are fully cloned.
// Contacts are not created until the next time step.
// @return the shape id for accessing the shape
CreateCapsuleShape :: proc(bodyId: BodyId, #by_ptr def: ShapeDef, #by_ptr capsule: Capsule) -> ShapeId ---
// Create a polygon shape and attach it to a body. The shape definition and geometry are fully cloned.
// Contacts are not created until the next time step.
// @return the shape id for accessing the shape
CreatePolygonShape :: proc(bodyId: BodyId, #by_ptr def: ShapeDef, #by_ptr polygon: Polygon) -> ShapeId ---
// Destroy a shape. You may defer the body mass update which can improve performance if several shapes on a
// body are destroyed at once.
// @see b2Body_ApplyMassFromShapes
DestroyShape :: proc(shapeId: ShapeId, updateBodyMass: bool) ---
// Shape identifier validation. Provides validation for up to 64K allocations.
Shape_IsValid :: proc(id: ShapeId) -> bool ---
// Get the type of a shape
Shape_GetType :: proc(shapeId: ShapeId) -> ShapeType ---
// Get the id of the body that a shape is attached to
Shape_GetBody :: proc(shapeId: ShapeId) -> BodyId ---
// Get the world that owns this shape.
Shape_GetWorld :: proc(shapeId: ShapeId) -> WorldId ---
// Returns true if the shape is a sensor. It is not possible to change a shape
// from sensor to solid dynamically because this breaks the contract for
// sensor events.
Shape_IsSensor :: proc(shapeId: ShapeId) -> bool ---
// Set the user data for a shape
Shape_SetUserData :: proc(shapeId: ShapeId, userData: rawptr) ---
// Get the user data for a shape. This is useful when you get a shape id
// from an event or query.
Shape_GetUserData :: proc(shapeId: ShapeId) -> rawptr ---
// Set the mass density of a shape, usually in kg/m^2.
// This will optionally update the mass properties on the parent body.
// @see b2ShapeDef::density, b2Body_ApplyMassFromShapes
Shape_SetDensity :: proc(shapeId: ShapeId, density: f32, updateBodyMass: bool) ---
// Get the density of a shape, usually in kg/m^2
Shape_GetDensity :: proc(shapeId: ShapeId) -> f32 ---
// Set the friction on a shape
// @see b2ShapeDef::friction
Shape_SetFriction :: proc(shapeId: ShapeId, friction: f32) ---
// Get the friction of a shape
Shape_GetFriction :: proc(shapeId: ShapeId) -> f32 ---
// Set the shape restitution (bounciness)
// @see b2ShapeDef::restitution
Shape_SetRestitution :: proc(shapeId: ShapeId, restitution: f32) ---
// Get the shape restitution
Shape_GetRestitution :: proc(shapeId: ShapeId) -> f32 ---
// Set the shape material identifier
// @see b2ShapeDef::material
Shape_SetMaterial :: proc(shapeId: ShapeId, material: c.int) ---
// Get the shape material identifier
Shape_GetMaterial :: proc(shapeId: ShapeId) -> c.int ---
// Get the shape filter
Shape_GetFilter :: proc(shapeId: ShapeId) -> Filter ---
// Set the current filter. This is almost as expensive as recreating the shape. This may cause
// contacts to be immediately destroyed. However contacts are not created until the next world step.
// Sensor overlap state is also not updated until the next world step.
// @see b2ShapeDef::filter
Shape_SetFilter :: proc(shapeId: ShapeId, filter: Filter) ---
// Enable sensor events for this shape.
// @see b2ShapeDef::enableSensorEvents
Shape_EnableSensorEvents :: proc(shapeId: ShapeId, flag: bool) ---
// Returns true if sensor events are enabled
Shape_AreSensorEventsEnabled :: proc(shapeId: ShapeId) -> bool ---
// Enable contact events for this shape. Only applies to kinematic and dynamic bodies. Ignored for sensors.
// @see b2ShapeDef::enableContactEvents
// @warning changing this at run-time may lead to lost begin/end events
Shape_EnableContactEvents :: proc(shapeId: ShapeId, flag: bool) ---
// Returns true if contact events are enabled
Shape_AreContactEventsEnabled :: proc(shapeId: ShapeId) -> bool ---
// Enable pre-solve contact events for this shape. Only applies to dynamic bodies. These are expensive
// and must be carefully handled due to multithreading. Ignored for sensors.
// @see b2PreSolveFcn
Shape_EnablePreSolveEvents :: proc(shapeId: ShapeId, flag: bool) ---
// Returns true if pre-solve events are enabled
Shape_ArePreSolveEventsEnabled :: proc(shapeId: ShapeId) -> bool ---
// Enable contact hit events for this shape. Ignored for sensors.
// @see WorldDef.hitEventThreshold
Shape_EnableHitEvents :: proc(shapeId: ShapeId, flag: bool) ---
// Returns true if hit events are enabled
Shape_AreHitEventsEnabled :: proc(shapeId: ShapeId) -> bool ---
// Test a point for overlap with a shape
Shape_TestPoint :: proc(shapeId: ShapeId, point: Vec2) -> bool ---
// Ray cast a shape directly
Shape_RayCast :: proc(shapeId: ShapeId, #by_ptr input: RayCastInput) -> CastOutput ---
// Get a copy of the shape's circle. Asserts the type is correct.
Shape_GetCircle :: proc(shapeId: ShapeId) -> Circle ---
// Get a copy of the shape's line segment. Asserts the type is correct.
Shape_GetSegment :: proc(shapeId: ShapeId) -> Segment ---
// Get a copy of the shape's chain segment. These come from chain shapes.
// Asserts the type is correct.
Shape_GetChainSegment :: proc(shapeId: ShapeId) -> ChainSegment ---
// Get a copy of the shape's capsule. Asserts the type is correct.
Shape_GetCapsule :: proc(shapeId: ShapeId) -> Capsule ---
// Get a copy of the shape's convex polygon. Asserts the type is correct.
Shape_GetPolygon :: proc(shapeId: ShapeId) -> Polygon ---
// Allows you to change a shape to be a circle or update the current circle.
// This does not modify the mass properties.
// @see b2Body_ApplyMassFromShapes
Shape_SetCircle :: proc(shapeId: ShapeId, #by_ptr circle: Circle) ---
// Allows you to change a shape to be a capsule or update the current capsule.
// This does not modify the mass properties.
// @see b2Body_ApplyMassFromShapes
Shape_SetCapsule :: proc(shapeId: ShapeId, #by_ptr capsule: Capsule) ---
// Allows you to change a shape to be a segment or update the current segment.
Shape_SetSegment :: proc(shapeId: ShapeId, #by_ptr segment: Segment) ---
// Allows you to change a shape to be a polygon or update the current polygon.
// This does not modify the mass properties.
// @see b2Body_ApplyMassFromShapes
Shape_SetPolygon :: proc(shapeId: ShapeId, #by_ptr polygon: Polygon) ---
// Get the parent chain id if the shape type is a chain segment, otherwise
// returns b2_nullChainId.
Shape_GetParentChain :: proc(shapeId: ShapeId) -> ChainId ---
// Get the maximum capacity required for retrieving all the touching contacts on a shape
Shape_GetContactCapacity :: proc(shapeId: ShapeId) -> c.int ---
// Get the maximum capacity required for retrieving all the overlapped shapes on a sensor shape.
// This returns 0 if the provided shape is not a sensor.
// @param shapeId the id of a sensor shape
// @returns the required capacity to get all the overlaps in b2Shape_GetSensorOverlaps
Shape_GetSensorCapacity :: proc(shapeId: ShapeId) -> c.int ---
// Get the overlapped shapes for a sensor shape.
// @param shapeId the id of a sensor shape
// @param overlaps a user allocated array that is filled with the overlapping shapes
// @param capacity the capacity of overlappedShapes
// @returns the number of elements filled in the provided array
// @warning do not ignore the return value, it specifies the valid number of elements
// @warning overlaps may contain destroyed shapes so use b2Shape_IsValid to confirm each overlap
Shape_GetSensorOverlaps :: proc(shapeId: ShapeId, overlaps: [^]ShapeId, capacity: c.int) -> c.int ---
// Get the current world AABB
Shape_GetAABB :: proc(shapeId: ShapeId) -> AABB ---
// Get the mass data of a shape
Shape_GetMassData :: proc(shapeId: ShapeId) -> MassData ---
// Get the closest point on a shape to a target point. Target and result are in world space.
Shape_GetClosestPoint :: proc(shapeId: ShapeId, target: Vec2) -> Vec2 ---
}
// Get the touching contact data for a shape. The provided shapeId will be either shapeIdA or shapeIdB on the contact data.
@(require_results)
Shape_GetContactData :: proc "c" (shapeId: ShapeId, contactData: []ContactData) -> []ContactData {
foreign lib {
b2Shape_GetContactData :: proc "c" (shapeId: ShapeId, contactData: [^]ContactData, capacity: c.int) -> c.int ---
}
n := b2Shape_GetContactData(shapeId, raw_data(contactData), c.int(len(contactData)))
return contactData[:n]
}
@(link_prefix="b2", default_calling_convention="c", require_results)
foreign lib {
// Chain Shape
// Create a chain shape
// @see b2ChainDef for details
CreateChain :: proc(bodyId: BodyId, #by_ptr def: ChainDef) -> ChainId ---
// Destroy a chain shape
DestroyChain :: proc(chainId: ChainId) ---
// Get the world that owns this chain shape
Chain_GetWorld :: proc(chainId: ChainId) -> WorldId ---
// Get the number of segments on this chain
Chain_GetSegmentCount :: proc(chainId: ChainId) -> c.int ---
// Fill a user array with chain segment shape ids up to the specified capacity. Returns
// the actual number of segments returned.
Chain_GetSegments :: proc(chainId: ChainId, segmentArray: [^]ShapeId, capacity: c.int) -> c.int ---
// Set the chain friction
// @see b2ChainDef::friction
Chain_SetFriction :: proc(chainId: ChainId, friction: f32) ---
// Get the chain friction
Chain_GetFriction :: proc(chainId: ChainId) -> f32 ---
// Set the chain restitution (bounciness)
// @see b2ChainDef::restitution
Chain_SetRestitution :: proc(chainId: ChainId, restitution: f32) ---
// Get the chain restitution
Chain_GetRestitution :: proc(chainId: ChainId) -> f32 ---
// Set the chain material
// @see b2ChainDef::material
Chain_SetMaterial :: proc(chainId: ChainId, material: c.int) ---
// Get the chain material
Chain_GetMaterial :: proc(chainId: ChainId) -> c.int ---
// Chain identifier validation. Provides validation for up to 64K allocations.
Chain_IsValid :: proc(id: ChainId) -> bool ---
/**
* @defgroup joint Joint
* @brief Joints allow you to connect rigid bodies together while allowing various forms of relative motions.
*/
// Destroy a joint
DestroyJoint :: proc(jointId: JointId) ---
// Joint identifier validation. Provides validation for up to 64K allocations.
Joint_IsValid :: proc(id: JointId) -> bool ---
// Get the joint type
Joint_GetType :: proc(jointId: JointId) -> JointType ---
// Get body A id on a joint
Joint_GetBodyA :: proc(jointId: JointId) -> BodyId ---
// Get body B id on a joint
Joint_GetBodyB :: proc(jointId: JointId) -> BodyId ---
// Get the world that owns this joint
Joint_GetWorld :: proc(jointId: JointId) -> WorldId ---
// Get the local anchor on bodyA
Joint_GetLocalAnchorA :: proc(jointId: JointId) -> Vec2 ---
// Get the local anchor on bodyB
Joint_GetLocalAnchorB :: proc(jointId: JointId) -> Vec2 ---
// Toggle collision between connected bodies
Joint_SetCollideConnected :: proc(jointId: JointId, shouldCollide: bool) ---
// Is collision allowed between connected bodies?
Joint_GetCollideConnected :: proc(jointId: JointId) -> bool ---
// Set the user data on a joint
Joint_SetUserData :: proc(jointId: JointId, userData: rawptr) ---
// Get the user data on a joint
Joint_GetUserData :: proc(jointId: JointId) -> rawptr ---
// Wake the bodies connect to this joint
Joint_WakeBodies :: proc(jointId: JointId) ---
// Get the current constraint force for this joint. Usually in Newtons.
Joint_GetConstraintForce :: proc(jointId: JointId) -> Vec2 ---
// Get the current constraint torque for this joint. Usually in Newton * meters.
Joint_GetConstraintTorque :: proc(jointId: JointId) -> f32 ---
/**
* @defgroup distance_joint Distance Joint
* @brief Functions for the distance joint.
*/
// Create a distance joint
// @see b2DistanceJointDef for details
CreateDistanceJoint :: proc(worldId: WorldId, #by_ptr def: DistanceJointDef) -> JointId ---
// Set the rest length of a distance joint
// @param jointId The id for a distance joint
// @param length The new distance joint length
DistanceJoint_SetLength :: proc(jointId: JointId, length: f32) ---
// Get the rest length of a distance joint
DistanceJoint_GetLength :: proc(jointId: JointId) -> f32 ---
// Enable/disable the distance joint spring. When disabled the distance joint is rigid.
DistanceJoint_EnableSpring :: proc(jointId: JointId, enableSpring: bool) ---
// Is the distance joint spring enabled?
DistanceJoint_IsSpringEnabled :: proc(jointId: JointId) -> bool ---
// Set the spring stiffness in Hertz
DistanceJoint_SetSpringHertz :: proc(jointId: JointId, hertz: f32) ---
// Set the spring damping ratio, non-dimensional
DistanceJoint_SetSpringDampingRatio :: proc(jointId: JointId, dampingRatio: f32) ---
// Get the spring Hertz
DistanceJoint_GetSpringHertz :: proc(jointId: JointId) -> f32 ---
// Get the spring damping ratio
DistanceJoint_GetSpringDampingRatio :: proc(jointId: JointId) -> f32 ---
// Enable joint limit. The limit only works if the joint spring is enabled. Otherwise the joint is rigid
// and the limit has no effect.
DistanceJoint_EnableLimit :: proc(jointId: JointId, enableLimit: bool) ---
// Is the distance joint limit enabled?
DistanceJoint_IsLimitEnabled :: proc(jointId: JointId) -> bool ---
// Set the minimum and maximum length parameters of a distance joint
DistanceJoint_SetLengthRange :: proc(jointId: JointId, minLength, maxLength: f32) ---
// Get the distance joint minimum length
DistanceJoint_GetMinLength :: proc(jointId: JointId) -> f32 ---
// Get the distance joint maximum length
DistanceJoint_GetMaxLength :: proc(jointId: JointId) -> f32 ---
// Get the current length of a distance joint
DistanceJoint_GetCurrentLength :: proc(jointId: JointId) -> f32 ---
// Enable/disable the distance joint motor
DistanceJoint_EnableMotor :: proc(jointId: JointId, enableMotor: bool) ---
// Is the distance joint motor enabled?
DistanceJoint_IsMotorEnabled :: proc(jointId: JointId) -> bool ---
// Set the distance joint motor speed, usually in meters per second
DistanceJoint_SetMotorSpeed :: proc(jointId: JointId, motorSpeed: f32) ---
// Get the distance joint motor speed, usually in meters per second
DistanceJoint_GetMotorSpeed :: proc(jointId: JointId) -> f32 ---
// Set the distance joint maximum motor force, usually in newtons
DistanceJoint_SetMaxMotorForce :: proc(jointId: JointId, force: f32) ---
// Get the distance joint maximum motor force, usually in newtons
DistanceJoint_GetMaxMotorForce :: proc(jointId: JointId) -> f32 ---
// Get the distance joint current motor force, usually in newtons
DistanceJoint_GetMotorForce :: proc(jointId: JointId) -> f32 ---
/**
* @defgroup motor_joint Motor Joint
* @brief Functions for the motor joint.
*
* The motor joint is used to drive the relative transform between two bodies. It takes
* a relative position and rotation and applies the forces and torques needed to achieve
* that relative transform over time.
*/
// Create a motor joint
// @see b2MotorJointDef for details
CreateMotorJoint :: proc(worldId: WorldId, #by_ptr def: MotorJointDef) -> JointId ---
// Set the motor joint linear offset target
MotorJoint_SetLinearOffset :: proc(jointId: JointId, linearOffset: Vec2) ---
// Get the motor joint linear offset target
MotorJoint_GetLinearOffset :: proc(jointId: JointId) -> Vec2 ---
// Set the motor joint angular offset target in radians
MotorJoint_SetAngularOffset :: proc(jointId: JointId, angularOffset: f32) ---
// Get the motor joint angular offset target in radians
MotorJoint_GetAngularOffset :: proc(jointId: JointId) -> f32 ---
// Set the motor joint maximum force, usually in newtons
MotorJoint_SetMaxForce :: proc(jointId: JointId, maxForce: f32) ---
// Get the motor joint maximum force, usually in newtons
MotorJoint_GetMaxForce :: proc(jointId: JointId) -> f32 ---
// Set the motor joint maximum torque, usually in newton-meters
MotorJoint_SetMaxTorque :: proc(jointId: JointId, maxTorque: f32) ---
// Get the motor joint maximum torque, usually in newton-meters
MotorJoint_GetMaxTorque :: proc(jointId: JointId) -> f32 ---
// Set the motor joint correction factor, usually in [0, 1]
MotorJoint_SetCorrectionFactor :: proc(jointId: JointId, correctionFactor: f32) ---
// Get the motor joint correction factor, usually in [0, 1]
MotorJoint_GetCorrectionFactor :: proc(jointId: JointId) -> f32 ---
/**@}*/
/**
* @defgroup mouse_joint Mouse Joint
* @brief Functions for the mouse joint.
*
* The mouse joint is designed for use in the samples application, but you may find it useful in applications where
* the user moves a rigid body with a cursor.
*/
// Create a mouse joint
// @see b2MouseJointDef for details
CreateMouseJoint :: proc(worldId: WorldId, #by_ptr def: MouseJointDef) -> JointId ---
// Set the mouse joint target
MouseJoint_SetTarget :: proc(jointId: JointId, target: Vec2) ---
// Get the mouse joint target
MouseJoint_GetTarget :: proc(jointId: JointId) -> Vec2 ---
// Set the mouse joint spring stiffness in Hertz
MouseJoint_SetSpringHertz :: proc(jointId: JointId, hertz: f32) ---
// Get the mouse joint spring stiffness in Hertz
MouseJoint_GetSpringHertz :: proc(jointId: JointId) -> f32 ---
// Set the mouse joint spring damping ratio, non-dimensional
MouseJoint_SetSpringDampingRatio :: proc(jointId: JointId, dampingRatio: f32) ---
// Get the mouse joint damping ratio, non-dimensional
MouseJoint_GetSpringDampingRatio :: proc(jointId: JointId) -> f32 ---
// Set the mouse joint maximum force, usually in newtons
MouseJoint_SetMaxForce :: proc(jointId: JointId, maxForce: f32) ---
// Get the mouse joint maximum force, usually in newtons
MouseJoint_GetMaxForce :: proc(jointId: JointId) -> f32 ---
/**@}*/
/**
* @defgroup filter_joint Filter Joint
* @brief Functions for the filter joint.
*
* The filter joint is used to disable collision between two bodies. As a side effect of being a joint, it also
* keeps the two bodies in the same simulation island.
* @{
*/
// Create a filter joint.
// @see b2FilterJointDef for details
CreateFilterJoint :: proc(worldId: WorldId, #by_ptr def: FilterJointDef) -> JointId ---
/**@}*/
/**
* @defgroup prismatic_joint Prismatic Joint
* @brief A prismatic joint allows for translation along a single axis with no rotation.
*
* The prismatic joint is useful for things like pistons and moving platforms, where you want a body to translate
* along an axis and have no rotation. Also called a *slider* joint.
*/
// Create a prismatic (slider) joint.
// @see b2PrismaticJointDef for details
CreatePrismaticJoint :: proc(worldId: WorldId, #by_ptr def: PrismaticJointDef) -> JointId ---
// Enable/disable the joint spring.
PrismaticJoint_EnableSpring :: proc(jointId: JointId, enableSpring: bool) ---
// Is the prismatic joint spring enabled or not?
PrismaticJoint_IsSpringEnabled :: proc(jointId: JointId) -> bool ---
// Set the prismatic joint stiffness in Hertz.
// This should usually be less than a quarter of the simulation rate. For example, if the simulation
// runs at 60Hz then the joint stiffness should be 15Hz or less.
PrismaticJoint_SetSpringHertz :: proc(jointId: JointId, hertz: f32) ---
// Get the prismatic joint stiffness in Hertz
PrismaticJoint_GetSpringHertz :: proc(jointId: JointId) -> f32 ---
// Set the prismatic joint damping ratio (non-dimensional)
PrismaticJoint_SetSpringDampingRatio :: proc(jointId: JointId, dampingRatio: f32) ---
// Get the prismatic spring damping ratio (non-dimensional)
PrismaticJoint_GetSpringDampingRatio :: proc(jointId: JointId) -> f32 ---
// Enable/disable a prismatic joint limit
PrismaticJoint_EnableLimit :: proc(jointId: JointId, enableLimit: bool) ---
// Is the prismatic joint limit enabled?
PrismaticJoint_IsLimitEnabled :: proc(jointId: JointId) -> bool ---
// Get the prismatic joint lower limit
PrismaticJoint_GetLowerLimit :: proc(jointId: JointId) -> f32 ---
// Get the prismatic joint upper limit
PrismaticJoint_GetUpperLimit :: proc(jointId: JointId) -> f32 ---
// Set the prismatic joint limits
PrismaticJoint_SetLimits :: proc(jointId: JointId, lower, upper: f32) ---
// Enable/disable a prismatic joint motor
PrismaticJoint_EnableMotor :: proc(jointId: JointId, enableMotor: bool) ---
// Is the prismatic joint motor enabled?
PrismaticJoint_IsMotorEnabled :: proc(jointId: JointId) -> bool ---
// Set the prismatic joint motor speed, usually in meters per second
PrismaticJoint_SetMotorSpeed :: proc(jointId: JointId, motorSpeed: f32) ---
// Get the prismatic joint motor speed, usually in meters per second
PrismaticJoint_GetMotorSpeed :: proc(jointId: JointId) -> f32 ---
// Set the prismatic joint maximum motor force, usually in newtons
PrismaticJoint_SetMaxMotorForce :: proc(jointId: JointId, force: f32) ---
// Get the prismatic joint maximum motor force, usually in newtons
PrismaticJoint_GetMaxMotorForce :: proc(jointId: JointId) -> f32 ---
// Get the prismatic joint current motor force, usually in newtons
PrismaticJoint_GetMotorForce :: proc(jointId: JointId) -> f32 ---
// Get the current joint translation, usually in meters.
PrismaticJoint_GetTranslation :: proc(jointId: JointId) -> f32 ---
// Get the current joint translation speed, usually in meters per second.
PrismaticJoint_GetSpeed :: proc(jointId: JointId) -> f32 ---
/**
* @defgroup revolute_joint Revolute Joint
* @brief A revolute joint allows for relative rotation in the 2D plane with no relative translation.
*
* The revolute joint is probably the most common joint. It can be used for ragdolls and chains.
* Also called a *hinge* or *pin* joint.
*/
// Create a revolute joint
// @see b2RevoluteJointDef for details
CreateRevoluteJoint :: proc(worldId: WorldId, #by_ptr def: RevoluteJointDef) -> JointId ---
// Enable/disable the revolute joint spring
RevoluteJoint_EnableSpring :: proc(jointId: JointId, enableSpring: bool) ---
// Is the revolute spring enabled?
RevoluteJoint_IsSpringEnabled :: proc(jointId: JointId) -> bool ---
// Set the revolute joint spring stiffness in Hertz
RevoluteJoint_SetSpringHertz :: proc(jointId: JointId, hertz: f32) ---
// Get the revolute joint spring stiffness in Hertz
RevoluteJoint_GetSpringHertz :: proc(jointId: JointId) -> f32 ---
// Set the revolute joint spring damping ratio, non-dimensional
RevoluteJoint_SetSpringDampingRatio :: proc(jointId: JointId, dampingRatio: f32) ---
// Get the revolute joint spring damping ratio, non-dimensional
RevoluteJoint_GetSpringDampingRatio :: proc(jointId: JointId) -> f32 ---
// Get the revolute joint current angle in radians relative to the reference angle
// @see b2RevoluteJointDef::referenceAngle
RevoluteJoint_GetAngle :: proc(jointId: JointId) -> f32 ---
// Enable/disable the revolute joint limit
RevoluteJoint_EnableLimit :: proc(jointId: JointId, enableLimit: bool) ---
// Is the revolute joint limit enabled?
RevoluteJoint_IsLimitEnabled :: proc(jointId: JointId) -> bool ---
// Get the revolute joint lower limit in radians
RevoluteJoint_GetLowerLimit :: proc(jointId: JointId) -> f32 ---
// Get the revolute joint upper limit in radians
RevoluteJoint_GetUpperLimit :: proc(jointId: JointId) -> f32 ---
// Set the revolute joint limits in radians. It is expected that lower <= upper
// and that -0.95 * B2_PI <= lower && upper <= -0.95 * B2_PI.
RevoluteJoint_SetLimits :: proc(jointId: JointId, lower, upper: f32) ---
// Enable/disable a revolute joint motor
RevoluteJoint_EnableMotor :: proc(jointId: JointId, enableMotor: bool) ---
// Is the revolute joint motor enabled?
RevoluteJoint_IsMotorEnabled :: proc(jointId: JointId) -> bool ---
// Set the revolute joint motor speed in radians per second
RevoluteJoint_SetMotorSpeed :: proc(jointId: JointId, motorSpeed: f32) ---
// Get the revolute joint motor speed in radians per second
RevoluteJoint_GetMotorSpeed :: proc(jointId: JointId) -> f32 ---
// Get the revolute joint current motor torque, usually in newton-meters
RevoluteJoint_GetMotorTorque :: proc(jointId: JointId) -> f32 ---
// Set the revolute joint maximum motor torque, usually in newton-meters
RevoluteJoint_SetMaxMotorTorque :: proc(jointId: JointId, torque: f32) ---
// Get the revolute joint maximum motor torque, usually in newton-meters
RevoluteJoint_GetMaxMotorTorque :: proc(jointId: JointId) -> f32 ---
/**@}*/
/**
* @defgroup weld_joint Weld Joint
* @brief A weld joint fully constrains the relative transform between two bodies while allowing for springiness
*
* A weld joint constrains the relative rotation and translation between two bodies. Both rotation and translation
* can have damped springs.
*
* @note The accuracy of weld joint is limited by the accuracy of the solver. Long chains of weld joints may flex.
*/
// Create a weld joint
// @see b2WeldJointDef for details
CreateWeldJoint :: proc(worldId: WorldId, #by_ptr def: WeldJointDef) -> JointId ---
// Get the weld joint reference angle in radians
WeldJoint_GetReferenceAngle :: proc(jointId: JointId) -> f32 ---
// Set the weld joint reference angle in radians, must be in [-pi,pi].
WeldJoint_SetReferenceAngle :: proc(jointId: JointId, angleInRadians: f32) ---
// Set the weld joint linear stiffness in Hertz. 0 is rigid.
WeldJoint_SetLinearHertz :: proc(jointId: JointId, hertz: f32) ---
// Get the weld joint linear stiffness in Hertz
WeldJoint_GetLinearHertz :: proc(jointId: JointId) -> f32 ---
// Set the weld joint linear damping ratio (non-dimensional)
WeldJoint_SetLinearDampingRatio :: proc(jointId: JointId, dampingRatio: f32) ---
// Get the weld joint linear damping ratio (non-dimensional)
WeldJoint_GetLinearDampingRatio :: proc(jointId: JointId) -> f32 ---
// Set the weld joint angular stiffness in Hertz. 0 is rigid.
WeldJoint_SetAngularHertz :: proc(jointId: JointId, hertz: f32) ---
// Get the weld joint angular stiffness in Hertz
WeldJoint_GetAngularHertz :: proc(jointId: JointId) -> f32 ---
// Set weld joint angular damping ratio, non-dimensional
WeldJoint_SetAngularDampingRatio :: proc(jointId: JointId, dampingRatio: f32) ---
// Get the weld joint angular damping ratio, non-dimensional
WeldJoint_GetAngularDampingRatio :: proc(jointId: JointId) -> f32 ---
/**
* @defgroup wheel_joint Wheel Joint
* The wheel joint can be used to simulate wheels on vehicles.
*
* The wheel joint restricts body B to move along a local axis in body A. Body B is free to
* rotate. Supports a linear spring, linear limits, and a rotational motor.
*
*/
// Create a wheel joint
// @see b2WheelJointDef for details
CreateWheelJoint :: proc(worldId: WorldId, #by_ptr def: WheelJointDef) -> JointId ---
// Enable/disable the wheel joint spring
WheelJoint_EnableSpring :: proc(jointId: JointId, enableSpring: bool) ---
// Is the wheel joint spring enabled?
WheelJoint_IsSpringEnabled :: proc(jointId: JointId) -> bool ---
// Set the wheel joint stiffness in Hertz
WheelJoint_SetSpringHertz :: proc(jointId: JointId, hertz: f32) ---
// Get the wheel joint stiffness in Hertz
WheelJoint_GetSpringHertz :: proc(jointId: JointId) -> f32 ---
// Set the wheel joint damping ratio, non-dimensional
WheelJoint_SetSpringDampingRatio :: proc(jointId: JointId, dampingRatio: f32) ---
// Get the wheel joint damping ratio, non-dimensional
WheelJoint_GetSpringDampingRatio :: proc(jointId: JointId) -> f32 ---
// Enable/disable the wheel joint limit
WheelJoint_EnableLimit :: proc(jointId: JointId, enableLimit: bool) ---
// Is the wheel joint limit enabled?
WheelJoint_IsLimitEnabled :: proc(jointId: JointId) -> bool ---
// Get the wheel joint lower limit
WheelJoint_GetLowerLimit :: proc(jointId: JointId) -> f32 ---
// Get the wheel joint upper limit
WheelJoint_GetUpperLimit :: proc(jointId: JointId) -> f32 ---
// Set the wheel joint limits
WheelJoint_SetLimits :: proc(jointId: JointId, lower, upper: f32) ---
// Enable/disable the wheel joint motor
WheelJoint_EnableMotor :: proc(jointId: JointId, enableMotor: bool) ---
// Is the wheel joint motor enabled?
WheelJoint_IsMotorEnabled :: proc(jointId: JointId) -> bool ---
// Set the wheel joint motor speed in radians per second
WheelJoint_SetMotorSpeed :: proc(jointId: JointId, motorSpeed: f32) ---
// Get the wheel joint motor speed in radians per second
WheelJoint_GetMotorSpeed :: proc(jointId: JointId) -> f32 ---
// Set the wheel joint maximum motor torque, usually in newton-meters
WheelJoint_SetMaxMotorTorque :: proc(jointId: JointId, torque: f32) ---
// Get the wheel joint maximum motor torque, usually in newton-meters
WheelJoint_GetMaxMotorTorque :: proc(jointId: JointId) -> f32 ---
// Get the wheel joint current motor torque, usually in newton-meters
WheelJoint_GetMotorTorque :: proc(jointId: JointId) -> f32 ---
}
IsValid :: proc{
IsValidFloat,
IsValidVec2,
IsValidRotation,
IsValidAABB,
IsValidPlane,
World_IsValid,
Body_IsValid,
Shape_IsValid,
Chain_IsValid,
Joint_IsValid,
IsValidRay,
}
|