Compare commits

...

13 commits

53 changed files with 6244 additions and 1800 deletions

View file

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View file

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View file

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View file

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

Before

Width:  |  Height:  |  Size: 3.7 KiB

After

Width:  |  Height:  |  Size: 3.7 KiB

View file

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB

View file

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View file

@ -0,0 +1,9 @@
sphere.obj was made by subdividing a cube, unwrapping it using cube projection, and then using the "To-sphere" tool in Blender to fully smoothen it out.
Make sure you select "shade smooth" before exporting!
Other settings:
Up axis: Y
Forward axis: -Z
The winding order in .obj files is always counter-clockwise, so my script (genmesh.py) uses reversed() to reverse this and homogenous the winding order
across meshes

565
asset-srcs/models/arc.obj Normal file
View file

@ -0,0 +1,565 @@
# Blender 4.4.0
# www.blender.org
mtllib arc.mtl
o Torus.001
v 1.090000 0.000000 0.000000
v 1.060000 0.051962 0.000000
v 1.000000 0.051962 0.000000
v 0.970000 0.000000 0.000000
v 1.000000 -0.051962 0.000000
v 1.060000 -0.051962 0.000000
v 1.030941 0.000000 -0.353922
v 1.002566 0.051962 -0.344181
v 0.945817 0.051962 -0.324699
v 0.917443 0.000000 -0.314958
v 0.945817 -0.051962 -0.324699
v 1.002566 -0.051962 -0.344181
v 0.860163 0.000000 -0.669492
v 0.836489 0.051962 -0.651065
v 0.789140 0.051962 -0.614213
v 0.765466 0.000000 -0.595786
v 0.789140 -0.051962 -0.614213
v 0.836489 -0.051962 -0.651065
v 0.596173 0.000000 -0.912512
v 0.579765 0.051962 -0.887396
v 0.546948 0.051962 -0.837166
v 0.530540 0.000000 -0.812051
v 0.546948 -0.051962 -0.837166
v 0.579765 -0.051962 -0.887396
v 0.267579 0.000000 -1.056646
v 0.260214 0.051962 -1.027564
v 0.245485 0.051962 -0.969400
v 0.238121 0.000000 -0.940318
v 0.245485 -0.051962 -0.969400
v 0.260214 -0.051962 -1.027564
v -0.090011 0.000000 -1.086277
v -0.087534 0.051962 -1.056379
v -0.082579 0.051962 -0.996584
v -0.080102 0.000000 -0.966687
v -0.082579 -0.051962 -0.996584
v -0.087534 -0.051962 -1.056379
v -0.437848 0.000000 -0.998193
v -0.425797 0.051962 -0.970720
v -0.401695 0.051962 -0.915773
v -0.389644 0.000000 -0.888300
v -0.401695 -0.051962 -0.915773
v -0.425797 -0.051962 -0.970720
v -0.738237 0.000000 -0.801939
v -0.717918 0.051962 -0.779867
v -0.677281 0.051962 -0.735724
v -0.656963 0.000000 -0.713652
v -0.677281 -0.051962 -0.735724
v -0.717918 -0.051962 -0.779867
v -0.958627 0.000000 -0.518782
v -0.932242 0.051962 -0.504504
v -0.879474 0.051962 -0.475947
v -0.853090 0.000000 -0.461669
v -0.879474 -0.051962 -0.475947
v -0.932242 -0.051962 -0.504504
v -1.075134 0.000000 -0.179408
v -1.045543 0.051962 -0.174470
v -0.986361 0.051962 -0.164595
v -0.956770 0.000000 -0.159657
v -0.986361 -0.051962 -0.164595
v -1.045543 -0.051962 -0.174470
v -1.075134 0.000000 0.179408
v -1.045543 0.051962 0.174470
v -0.986361 0.051962 0.164594
v -0.956771 0.000000 0.159656
v -0.986361 -0.051962 0.164594
v -1.045543 -0.051962 0.174470
v -0.958627 0.000000 0.518782
v -0.932242 0.051962 0.504504
v -0.879474 0.051962 0.475947
v -0.853090 0.000000 0.461669
v -0.879474 -0.051962 0.475947
v -0.932242 -0.051962 0.504504
v -0.738237 0.000000 0.801939
v -0.717918 0.051962 0.779867
v -0.677281 0.051962 0.735724
v -0.656963 0.000000 0.713652
v -0.677281 -0.051962 0.735724
v -0.717918 -0.051962 0.779867
v -0.437848 0.000000 0.998193
v -0.425797 0.051962 0.970720
v -0.401695 0.051962 0.915773
v -0.389644 0.000000 0.888300
v -0.401695 -0.051962 0.915773
v -0.425797 -0.051962 0.970720
v -0.090012 0.000000 1.086277
v -0.087535 0.051962 1.056379
v -0.082580 0.051962 0.996584
v -0.080102 0.000000 0.966687
v -0.082580 -0.051962 0.996584
v -0.087535 -0.051962 1.056379
v 0.267579 0.000000 1.056646
v 0.260214 0.051962 1.027564
v 0.245485 0.051962 0.969400
v 0.238121 0.000000 0.940318
v 0.245485 -0.051962 0.969400
v 0.260214 -0.051962 1.027564
v 0.596173 0.000000 0.912512
v 0.579765 0.051962 0.887396
v 0.546948 0.051962 0.837166
v 0.530540 0.000000 0.812051
v 0.546948 -0.051962 0.837166
v 0.579765 -0.051962 0.887396
v 0.860163 0.000000 0.669492
v 0.836489 0.051962 0.651065
v 0.789141 0.051962 0.614212
v 0.765466 0.000000 0.595786
v 0.789141 -0.051962 0.614212
v 0.836489 -0.051962 0.651065
v 1.030941 0.000000 0.353923
v 1.002566 0.051962 0.344182
v 0.945817 0.051962 0.324700
v 0.917443 0.000000 0.314959
v 0.945817 -0.051962 0.324700
v 1.002566 -0.051962 0.344182
vn 0.8571 0.4949 -0.1430
vn -0.0000 1.0000 -0.0000
vn -0.8571 0.4949 0.1430
vn -0.8571 -0.4949 0.1430
vn -0.0000 -1.0000 -0.0000
vn 0.8571 -0.4949 -0.1430
vn 0.7642 0.4949 -0.4136
vn -0.7642 0.4949 0.4136
vn -0.7642 -0.4949 0.4136
vn 0.7642 -0.4949 -0.4136
vn 0.5885 0.4949 -0.6393
vn -0.5885 0.4949 0.6393
vn -0.5885 -0.4949 0.6393
vn 0.5885 -0.4949 -0.6393
vn 0.3491 0.4949 -0.7958
vn -0.3491 0.4949 0.7958
vn -0.3491 -0.4949 0.7958
vn 0.3491 -0.4949 -0.7958
vn 0.0718 0.4949 -0.8660
vn -0.0718 0.4949 0.8660
vn -0.0718 -0.4949 0.8660
vn 0.0718 -0.4949 -0.8660
vn -0.2133 0.4949 -0.8424
vn 0.2133 0.4949 0.8424
vn 0.2133 -0.4949 0.8424
vn -0.2133 -0.4949 -0.8424
vn -0.4753 0.4949 -0.7275
vn 0.4753 0.4949 0.7275
vn 0.4753 -0.4949 0.7275
vn -0.4753 -0.4949 -0.7275
vn -0.6857 0.4949 -0.5337
vn 0.6857 0.4949 0.5337
vn 0.6857 -0.4949 0.5337
vn -0.6857 -0.4949 -0.5337
vn -0.8219 0.4949 -0.2822
vn 0.8219 0.4949 0.2822
vn 0.8219 -0.4949 0.2822
vn -0.8219 -0.4949 -0.2822
vn -0.8690 0.4949 -0.0000
vn 0.8690 0.4949 -0.0000
vn 0.8690 -0.4949 -0.0000
vn -0.8690 -0.4949 -0.0000
vn -0.8219 0.4949 0.2822
vn 0.8219 0.4949 -0.2822
vn 0.8219 -0.4949 -0.2822
vn -0.8219 -0.4949 0.2822
vn -0.6857 0.4949 0.5337
vn 0.6857 0.4949 -0.5337
vn 0.6857 -0.4949 -0.5337
vn -0.6857 -0.4949 0.5337
vn -0.4753 0.4949 0.7275
vn 0.4753 0.4949 -0.7275
vn 0.4753 -0.4949 -0.7275
vn -0.4753 -0.4949 0.7275
vn -0.2133 0.4949 0.8424
vn 0.2133 0.4949 -0.8424
vn 0.2133 -0.4949 -0.8424
vn -0.2133 -0.4949 0.8424
vn 0.0718 0.4949 0.8660
vn -0.0718 0.4949 -0.8660
vn -0.0718 -0.4949 -0.8660
vn 0.0718 -0.4949 0.8660
vn 0.3491 0.4949 0.7958
vn -0.3491 0.4949 -0.7958
vn -0.3491 -0.4949 -0.7958
vn 0.3491 -0.4949 0.7958
vn 0.5885 0.4949 0.6393
vn -0.5885 0.4949 -0.6393
vn -0.5885 -0.4949 -0.6393
vn 0.5885 -0.4949 0.6393
vn 0.7642 0.4949 0.4136
vn -0.7642 0.4949 -0.4136
vn -0.7642 -0.4949 -0.4136
vn 0.7642 -0.4949 0.4136
vn 0.8571 0.4949 0.1430
vn -0.8571 0.4949 -0.1430
vn -0.8571 -0.4949 -0.1430
vn 0.8571 -0.4949 0.1430
vt 0.526316 0.500000
vt 0.578947 0.666667
vt 0.526316 0.666667
vt 0.526316 0.833333
vt 0.578947 0.833333
vt 0.526316 1.000000
vt 0.578947 -0.000000
vt 0.526316 0.166667
vt 0.526316 -0.000000
vt 0.578947 0.333333
vt 0.526316 0.333333
vt 0.578947 0.500000
vt 0.631579 0.500000
vt 0.631579 0.666667
vt 0.631579 0.833333
vt 0.578947 1.000000
vt 0.631579 -0.000000
vt 0.578947 0.166667
vt 0.631579 0.166667
vt 0.684211 0.500000
vt 0.684211 0.666667
vt 0.684211 0.833333
vt 0.631579 1.000000
vt 0.684211 0.166667
vt 0.631579 0.333333
vt 0.684211 0.333333
vt 0.736842 0.666667
vt 0.736842 0.833333
vt 0.684211 1.000000
vt 0.736842 -0.000000
vt 0.684211 -0.000000
vt 0.736842 0.333333
vt 0.789474 0.500000
vt 0.736842 0.500000
vt 0.789474 0.666667
vt 0.789474 0.833333
vt 0.736842 1.000000
vt 0.789474 -0.000000
vt 0.736842 0.166667
vt 0.789474 0.166667
vt 0.789474 0.333333
vt 0.842105 0.666667
vt 0.842105 0.833333
vt 0.789474 1.000000
vt 0.842105 -0.000000
vt 0.842105 0.166667
vt 0.842105 0.333333
vt 0.842105 0.500000
vt 0.894737 0.666667
vt 0.894737 0.833333
vt 0.842105 1.000000
vt 0.894737 -0.000000
vt 0.894737 0.333333
vt 0.894737 0.500000
vt 0.947368 0.666667
vt 0.947368 0.833333
vt 0.894737 1.000000
vt 0.947368 -0.000000
vt 0.894737 0.166667
vt 0.947368 0.333333
vt 0.947368 0.500000
vt 1.000000 0.666667
vt 1.000000 0.833333
vt 0.947368 1.000000
vt 1.000000 -0.000000
vt 0.947368 0.166667
vt 1.000000 0.166667
vt 1.000000 0.333333
vt 0.052632 0.500000
vt -0.000000 0.666667
vt -0.000000 0.500000
vt 0.052632 0.666667
vt -0.000000 0.833333
vt 0.052632 1.000000
vt -0.000000 1.000000
vt 0.052632 -0.000000
vt -0.000000 0.166667
vt -0.000000 -0.000000
vt 0.052632 0.166667
vt -0.000000 0.333333
vt 0.052632 0.333333
vt 0.105263 0.500000
vt 0.105263 0.833333
vt 0.052632 0.833333
vt 0.105263 1.000000
vt 0.105263 -0.000000
vt 0.105263 0.166667
vt 0.157895 0.500000
vt 0.105263 0.666667
vt 0.157895 0.666667
vt 0.157895 0.833333
vt 0.157895 0.166667
vt 0.105263 0.333333
vt 0.210526 0.500000
vt 0.210526 0.833333
vt 0.157895 1.000000
vt 0.210526 -0.000000
vt 0.157895 -0.000000
vt 0.210526 0.166667
vt 0.157895 0.333333
vt 0.210526 0.333333
vt 0.263158 0.500000
vt 0.210526 0.666667
vt 0.263158 0.666667
vt 0.263158 0.833333
vt 0.210526 1.000000
vt 0.263158 0.166667
vt 0.263158 0.333333
vt 0.315789 0.500000
vt 0.315789 0.833333
vt 0.263158 1.000000
vt 0.315789 -0.000000
vt 0.263158 -0.000000
vt 0.315789 0.166667
vt 0.315789 0.333333
vt 0.368421 0.500000
vt 0.315789 0.666667
vt 0.368421 0.833333
vt 0.315789 1.000000
vt 0.368421 -0.000000
vt 0.368421 0.166667
vt 0.421053 0.666667
vt 0.368421 0.666667
vt 0.421053 0.833333
vt 0.368421 1.000000
vt 0.421053 -0.000000
vt 0.421053 0.333333
vt 0.368421 0.333333
vt 0.421053 0.500000
vt 0.473684 0.666667
vt 0.473684 0.833333
vt 0.421053 1.000000
vt 0.473684 -0.000000
vt 0.421053 0.166667
vt 0.473684 0.166667
vt 0.473684 0.333333
vt 0.473684 0.500000
vt 0.473684 1.000000
vt 1.000000 0.500000
vt 1.000000 1.000000
s 0
f 1/1/1 8/2/1 2/3/1
f 8/2/2 3/4/2 2/3/2
f 9/5/3 4/6/3 3/4/3
f 10/7/4 5/8/4 4/9/4
f 5/8/5 12/10/5 6/11/5
f 6/11/6 7/12/6 1/1/6
f 13/13/7 8/2/7 7/12/7
f 14/14/2 9/5/2 8/2/2
f 15/15/8 10/16/8 9/5/8
f 16/17/9 11/18/9 10/7/9
f 17/19/5 12/10/5 11/18/5
f 12/10/10 13/13/10 7/12/10
f 19/20/11 14/14/11 13/13/11
f 20/21/2 15/15/2 14/14/2
f 21/22/12 16/23/12 15/15/12
f 16/17/13 23/24/13 17/19/13
f 23/24/5 18/25/5 17/19/5
f 24/26/14 13/13/14 18/25/14
f 19/20/15 26/27/15 20/21/15
f 20/21/2 27/28/2 21/22/2
f 27/28/16 22/29/16 21/22/16
f 28/30/17 23/24/17 22/31/17
f 23/24/5 30/32/5 24/26/5
f 30/32/18 19/20/18 24/26/18
f 31/33/19 26/27/19 25/34/19
f 32/35/2 27/28/2 26/27/2
f 33/36/20 28/37/20 27/28/20
f 34/38/21 29/39/21 28/30/21
f 35/40/5 30/32/5 29/39/5
f 36/41/22 25/34/22 30/32/22
f 31/33/23 38/42/23 32/35/23
f 32/35/2 39/43/2 33/36/2
f 39/43/24 34/44/24 33/36/24
f 40/45/25 35/40/25 34/38/25
f 41/46/5 36/41/5 35/40/5
f 42/47/26 31/33/26 36/41/26
f 37/48/27 44/49/27 38/42/27
f 44/49/2 39/43/2 38/42/2
f 45/50/28 40/51/28 39/43/28
f 46/52/29 41/46/29 40/45/29
f 41/46/5 48/53/5 42/47/5
f 48/53/30 37/48/30 42/47/30
f 43/54/31 50/55/31 44/49/31
f 44/49/2 51/56/2 45/50/2
f 51/56/32 46/57/32 45/50/32
f 52/58/33 47/59/33 46/52/33
f 47/59/5 54/60/5 48/53/5
f 54/60/34 43/54/34 48/53/34
f 49/61/35 56/62/35 50/55/35
f 56/62/2 51/56/2 50/55/2
f 57/63/36 52/64/36 51/56/36
f 58/65/37 53/66/37 52/58/37
f 59/67/5 54/60/5 53/66/5
f 60/68/38 49/61/38 54/60/38
f 61/69/39 56/70/39 55/71/39
f 62/72/2 57/73/2 56/70/2
f 57/73/40 64/74/40 58/75/40
f 64/76/41 59/77/41 58/78/41
f 65/79/5 60/80/5 59/77/5
f 66/81/42 55/71/42 60/80/42
f 67/82/43 62/72/43 61/69/43
f 62/72/2 69/83/2 63/84/2
f 63/84/44 70/85/44 64/74/44
f 70/86/45 65/79/45 64/76/45
f 71/87/5 66/81/5 65/79/5
f 66/81/46 67/82/46 61/69/46
f 73/88/47 68/89/47 67/82/47
f 74/90/2 69/83/2 68/89/2
f 75/91/48 70/85/48 69/83/48
f 70/86/49 77/92/49 71/87/49
f 77/92/5 72/93/5 71/87/5
f 72/93/50 73/88/50 67/82/50
f 79/94/51 74/90/51 73/88/51
f 74/90/2 81/95/2 75/91/2
f 81/95/52 76/96/52 75/91/52
f 82/97/53 77/92/53 76/98/53
f 83/99/5 78/100/5 77/92/5
f 84/101/54 73/88/54 78/100/54
f 85/102/55 80/103/55 79/94/55
f 86/104/2 81/95/2 80/103/2
f 87/105/56 82/106/56 81/95/56
f 82/97/57 89/107/57 83/99/57
f 89/107/5 84/101/5 83/99/5
f 90/108/58 79/94/58 84/101/58
f 91/109/59 86/104/59 85/102/59
f 86/104/2 93/110/2 87/105/2
f 93/110/60 88/111/60 87/105/60
f 94/112/61 89/107/61 88/113/61
f 95/114/5 90/108/5 89/107/5
f 96/115/62 85/102/62 90/108/62
f 97/116/63 92/117/63 91/109/63
f 92/117/2 99/118/2 93/110/2
f 99/118/64 94/119/64 93/110/64
f 100/120/65 95/114/65 94/112/65
f 101/121/5 96/115/5 95/114/5
f 96/115/66 97/116/66 91/109/66
f 97/116/67 104/122/67 98/123/67
f 104/122/2 99/118/2 98/123/2
f 105/124/68 100/125/68 99/118/68
f 106/126/69 101/121/69 100/120/69
f 101/121/5 108/127/5 102/128/5
f 108/127/70 97/116/70 102/128/70
f 103/129/71 110/130/71 104/122/71
f 110/130/2 105/124/2 104/122/2
f 111/131/72 106/132/72 105/124/72
f 112/133/73 107/134/73 106/126/73
f 113/135/5 108/127/5 107/134/5
f 114/136/74 103/129/74 108/127/74
f 1/1/75 110/130/75 109/137/75
f 2/3/2 111/131/2 110/130/2
f 3/4/76 112/138/76 111/131/76
f 4/9/77 113/135/77 112/133/77
f 5/8/5 114/136/5 113/135/5
f 6/11/78 109/137/78 114/136/78
f 1/1/1 7/12/1 8/2/1
f 8/2/2 9/5/2 3/4/2
f 9/5/3 10/16/3 4/6/3
f 10/7/4 11/18/4 5/8/4
f 5/8/5 11/18/5 12/10/5
f 6/11/6 12/10/6 7/12/6
f 13/13/7 14/14/7 8/2/7
f 14/14/2 15/15/2 9/5/2
f 15/15/8 16/23/8 10/16/8
f 16/17/9 17/19/9 11/18/9
f 17/19/5 18/25/5 12/10/5
f 12/10/10 18/25/10 13/13/10
f 19/20/11 20/21/11 14/14/11
f 20/21/2 21/22/2 15/15/2
f 21/22/12 22/29/12 16/23/12
f 16/17/13 22/31/13 23/24/13
f 23/24/5 24/26/5 18/25/5
f 24/26/14 19/20/14 13/13/14
f 19/20/15 25/34/15 26/27/15
f 20/21/2 26/27/2 27/28/2
f 27/28/16 28/37/16 22/29/16
f 28/30/17 29/39/17 23/24/17
f 23/24/5 29/39/5 30/32/5
f 30/32/18 25/34/18 19/20/18
f 31/33/19 32/35/19 26/27/19
f 32/35/2 33/36/2 27/28/2
f 33/36/20 34/44/20 28/37/20
f 34/38/21 35/40/21 29/39/21
f 35/40/5 36/41/5 30/32/5
f 36/41/22 31/33/22 25/34/22
f 31/33/23 37/48/23 38/42/23
f 32/35/2 38/42/2 39/43/2
f 39/43/24 40/51/24 34/44/24
f 40/45/25 41/46/25 35/40/25
f 41/46/5 42/47/5 36/41/5
f 42/47/26 37/48/26 31/33/26
f 37/48/27 43/54/27 44/49/27
f 44/49/2 45/50/2 39/43/2
f 45/50/28 46/57/28 40/51/28
f 46/52/29 47/59/29 41/46/29
f 41/46/5 47/59/5 48/53/5
f 48/53/30 43/54/30 37/48/30
f 43/54/31 49/61/31 50/55/31
f 44/49/2 50/55/2 51/56/2
f 51/56/32 52/64/32 46/57/32
f 52/58/33 53/66/33 47/59/33
f 47/59/5 53/66/5 54/60/5
f 54/60/34 49/61/34 43/54/34
f 49/61/35 55/139/35 56/62/35
f 56/62/2 57/63/2 51/56/2
f 57/63/36 58/140/36 52/64/36
f 58/65/37 59/67/37 53/66/37
f 59/67/5 60/68/5 54/60/5
f 60/68/38 55/139/38 49/61/38
f 61/69/39 62/72/39 56/70/39
f 62/72/2 63/84/2 57/73/2
f 57/73/40 63/84/40 64/74/40
f 64/76/41 65/79/41 59/77/41
f 65/79/5 66/81/5 60/80/5
f 66/81/42 61/69/42 55/71/42
f 67/82/43 68/89/43 62/72/43
f 62/72/2 68/89/2 69/83/2
f 63/84/44 69/83/44 70/85/44
f 70/86/45 71/87/45 65/79/45
f 71/87/5 72/93/5 66/81/5
f 66/81/46 72/93/46 67/82/46
f 73/88/47 74/90/47 68/89/47
f 74/90/2 75/91/2 69/83/2
f 75/91/48 76/96/48 70/85/48
f 70/86/49 76/98/49 77/92/49
f 77/92/5 78/100/5 72/93/5
f 72/93/50 78/100/50 73/88/50
f 79/94/51 80/103/51 74/90/51
f 74/90/2 80/103/2 81/95/2
f 81/95/52 82/106/52 76/96/52
f 82/97/53 83/99/53 77/92/53
f 83/99/5 84/101/5 78/100/5
f 84/101/54 79/94/54 73/88/54
f 85/102/55 86/104/55 80/103/55
f 86/104/2 87/105/2 81/95/2
f 87/105/56 88/111/56 82/106/56
f 82/97/57 88/113/57 89/107/57
f 89/107/5 90/108/5 84/101/5
f 90/108/58 85/102/58 79/94/58
f 91/109/59 92/117/59 86/104/59
f 86/104/2 92/117/2 93/110/2
f 93/110/60 94/119/60 88/111/60
f 94/112/61 95/114/61 89/107/61
f 95/114/5 96/115/5 90/108/5
f 96/115/62 91/109/62 85/102/62
f 97/116/63 98/123/63 92/117/63
f 92/117/2 98/123/2 99/118/2
f 99/118/64 100/125/64 94/119/64
f 100/120/65 101/121/65 95/114/65
f 101/121/5 102/128/5 96/115/5
f 96/115/66 102/128/66 97/116/66
f 97/116/67 103/129/67 104/122/67
f 104/122/2 105/124/2 99/118/2
f 105/124/68 106/132/68 100/125/68
f 106/126/69 107/134/69 101/121/69
f 101/121/5 107/134/5 108/127/5
f 108/127/70 103/129/70 97/116/70
f 103/129/71 109/137/71 110/130/71
f 110/130/2 111/131/2 105/124/2
f 111/131/72 112/138/72 106/132/72
f 112/133/73 113/135/73 107/134/73
f 113/135/5 114/136/5 108/127/5
f 114/136/74 109/137/74 103/129/74
f 1/1/75 2/3/75 110/130/75
f 2/3/2 3/4/2 111/131/2
f 3/4/76 4/6/76 112/138/76
f 4/9/77 5/8/77 113/135/77
f 5/8/5 6/11/5 114/136/5
f 6/11/78 1/1/78 109/137/78

119
asset-srcs/models/arrow.obj Normal file
View file

@ -0,0 +1,119 @@
# Blender 4.3.2
# www.blender.org
mtllib arrow.mtl
o Cylinder.001
v 0.189969 0.008460 -1.749730
v 0.189969 0.008460 1.759116
v 0.134756 -0.124837 -1.749730
v 0.134756 -0.124837 1.759116
v 0.001459 -0.180050 -1.749730
v 0.001459 -0.180050 1.759116
v -0.131837 -0.124837 -1.749730
v -0.131837 -0.124837 1.759116
v -0.187050 0.008460 -1.749730
v -0.187050 0.008460 1.759116
v -0.131837 0.141756 -1.749730
v -0.131837 0.141756 1.759116
v 0.001459 0.196969 -1.749730
v 0.001459 0.196969 1.759116
v 0.134756 0.141756 -1.749730
v 0.134756 0.141756 1.759116
v 0.398640 0.008460 1.759116
v 0.282308 -0.272389 1.759116
v 0.001459 -0.388721 1.759116
v -0.279390 -0.272389 1.759116
v -0.395722 0.008460 1.759116
v -0.279390 0.289309 1.759116
v 0.001459 0.405641 1.759116
v 0.282308 0.289309 1.759116
v 0.001459 0.010576 2.759115
vn 0.9239 -0.3827 -0.0000
vn 0.3827 -0.9239 -0.0000
vn -0.3827 -0.9239 -0.0000
vn -0.9239 -0.3827 -0.0000
vn -0.9239 0.3827 -0.0000
vn -0.3827 0.9239 -0.0000
vn -0.0000 -0.0000 -1.0000
vn 0.3827 0.9239 -0.0000
vn 0.9239 0.3827 -0.0000
vn 0.8676 0.3594 0.3438
vn -0.3595 0.8679 0.3429
vn -0.8671 -0.3592 0.3452
vn 0.3590 -0.8668 0.3461
vn 0.3595 0.8679 0.3429
vn -0.8676 0.3594 0.3438
vn -0.3590 -0.8668 0.3461
vn 0.8671 -0.3592 0.3452
vt 1.000000 1.000000
vt 0.875000 0.500000
vt 1.000000 0.500000
vt 0.875000 1.000000
vt 0.750000 0.500000
vt 0.750000 1.000000
vt 0.625000 0.500000
vt 0.625000 1.000000
vt 0.500000 0.500000
vt 0.500000 1.000000
vt 0.375000 0.500000
vt 0.375000 1.000000
vt 0.250000 0.500000
vt 0.250000 1.000000
vt 0.125000 0.500000
vt 0.125000 1.000000
vt 0.000000 0.500000
vt 0.919706 0.080294
vt 0.580294 0.080294
vt 0.580294 0.419706
vt 0.000000 1.000000
vt 0.750000 0.490000
vt 0.919706 0.419706
vt 0.990000 0.250000
vt 0.750000 0.010000
vt 0.510000 0.250000
s 0
f 2/1/1 3/2/1 1/3/1
f 4/4/2 5/5/2 3/2/2
f 6/6/3 7/7/3 5/5/3
f 8/8/4 9/9/4 7/7/4
f 10/10/5 11/11/5 9/9/5
f 12/12/6 13/13/6 11/11/6
f 8/8/7 21/10/7 10/10/7
f 14/14/8 15/15/8 13/13/8
f 16/16/9 1/17/9 15/15/9
f 7/18/7 11/19/7 15/20/7
f 17/21/10 24/16/10 25/21/10
f 14/14/7 24/16/7 16/16/7
f 4/4/7 19/6/7 6/6/7
f 10/10/7 22/12/7 12/12/7
f 16/16/7 17/21/7 2/21/7
f 2/1/7 18/4/7 4/4/7
f 6/6/7 20/8/7 8/8/7
f 12/12/7 23/14/7 14/14/7
f 23/14/11 22/12/11 25/14/11
f 21/10/12 20/8/12 25/10/12
f 19/6/13 18/4/13 25/6/13
f 24/16/14 23/14/14 25/16/14
f 22/12/15 21/10/15 25/12/15
f 20/8/16 19/6/16 25/8/16
f 18/4/17 17/1/17 25/4/17
f 2/1/1 4/4/1 3/2/1
f 4/4/2 6/6/2 5/5/2
f 6/6/3 8/8/3 7/7/3
f 8/8/4 10/10/4 9/9/4
f 10/10/5 12/12/5 11/11/5
f 12/12/6 14/14/6 13/13/6
f 8/8/7 20/8/7 21/10/7
f 14/14/8 16/16/8 15/15/8
f 16/16/9 2/21/9 1/17/9
f 15/20/7 1/22/7 3/23/7
f 3/23/7 5/24/7 7/18/7
f 7/18/7 9/25/7 11/19/7
f 11/19/7 13/26/7 15/20/7
f 15/20/7 3/23/7 7/18/7
f 14/14/7 23/14/7 24/16/7
f 4/4/7 18/4/7 19/6/7
f 10/10/7 21/10/7 22/12/7
f 16/16/7 24/16/7 17/21/7
f 2/1/7 17/1/7 18/4/7
f 6/6/7 19/6/7 20/8/7
f 12/12/7 22/12/7 23/14/7

View file

@ -0,0 +1,36 @@
# Blender 4.3.2
# www.blender.org
mtllib cube.mtl
o Cube
v 1.000000 1.000000 -1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 1.000000 -1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 1.000000
vn -0.0000 1.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -1.0000 -0.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vt 0.000000 1.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 0.000000 0.000000
s 0
usemtl Material
f 5/1/1 3/2/1 1/3/1
f 3/3/2 8/4/2 4/2/2
f 7/1/3 6/2/3 8/4/3
f 2/3/4 8/4/4 6/1/4
f 1/3/5 4/4/5 2/2/5
f 5/1/6 2/2/6 6/4/6
f 5/1/1 7/4/1 3/2/1
f 3/3/2 7/1/2 8/4/2
f 7/1/3 5/3/3 6/2/3
f 2/3/4 4/2/4 8/4/4
f 1/3/5 3/1/5 4/4/5
f 5/1/6 1/3/6 2/2/6

View file

@ -0,0 +1,137 @@
# Blender 4.4.1
# www.blender.org
mtllib cylinder.mtl
o Cylinder
v 0.000000 -1.000000 1.000000
v 0.000000 -1.000000 -1.000000
v 0.500000 -0.866025 1.000000
v 0.500000 -0.866025 -1.000000
v 0.866025 -0.500000 1.000000
v 0.866025 -0.500000 -1.000000
v 1.000000 0.000000 1.000000
v 1.000000 -0.000000 -1.000000
v 0.866025 0.500000 1.000000
v 0.866025 0.500000 -1.000000
v 0.500000 0.866025 1.000000
v 0.500000 0.866025 -1.000000
v 0.000000 1.000000 1.000000
v 0.000000 1.000000 -1.000000
v -0.500000 0.866025 1.000000
v -0.500000 0.866025 -1.000000
v -0.866025 0.500000 1.000000
v -0.866025 0.500000 -1.000000
v -1.000000 0.000000 1.000000
v -1.000000 -0.000000 -1.000000
v -0.866025 -0.500000 1.000000
v -0.866025 -0.500000 -1.000000
v -0.500000 -0.866025 1.000000
v -0.500000 -0.866025 -1.000000
vn 0.2588 -0.9659 -0.0000
vn 0.7071 -0.7071 -0.0000
vn 0.9659 -0.2588 -0.0000
vn 0.9659 0.2588 -0.0000
vn 0.7071 0.7071 -0.0000
vn 0.2588 0.9659 -0.0000
vn -0.2588 0.9659 -0.0000
vn -0.7071 0.7071 -0.0000
vn -0.9659 0.2588 -0.0000
vn -0.9659 -0.2588 -0.0000
vn -0.0000 -0.0000 -1.0000
vn -0.7071 -0.7071 -0.0000
vn -0.2588 -0.9659 -0.0000
vn -0.0000 -0.0000 1.0000
vt 1.000000 1.000000
vt 0.916667 0.500000
vt 1.000000 0.500000
vt 0.916667 1.000000
vt 0.833333 0.500000
vt 0.833333 1.000000
vt 0.750000 0.500000
vt 0.750000 1.000000
vt 0.666667 0.500000
vt 0.666667 1.000000
vt 0.583333 0.500000
vt 0.583333 1.000000
vt 0.500000 0.500000
vt 0.500000 1.000000
vt 0.416667 0.500000
vt 0.416667 1.000000
vt 0.333333 0.500000
vt 0.333333 1.000000
vt 0.250000 0.500000
vt 0.250000 1.000000
vt 0.166667 0.500000
vt 0.042154 0.370000
vt 0.250000 0.010000
vt 0.457846 0.370000
vt 0.166667 1.000000
vt 0.083333 0.500000
vt 0.083333 1.000000
vt 0.000000 0.500000
vt 0.990000 0.250000
vt 0.630000 0.042154
vt 0.630000 0.457846
vt 0.370000 0.457846
vt 0.250000 0.490000
vt 0.130000 0.457846
vt 0.010000 0.250000
vt 0.042154 0.130000
vt 0.130000 0.042154
vt 0.370000 0.042154
vt 0.457846 0.130000
vt 0.490000 0.250000
vt 0.000000 1.000000
vt 0.750000 0.490000
vt 0.870000 0.457846
vt 0.957846 0.370000
vt 0.957846 0.130000
vt 0.870000 0.042154
vt 0.750000 0.010000
vt 0.542154 0.130000
vt 0.510000 0.250000
vt 0.542154 0.370000
s 0
f 2/1/1 3/2/1 1/3/1
f 4/4/2 5/5/2 3/2/2
f 6/6/3 7/7/3 5/5/3
f 8/8/4 9/9/4 7/7/4
f 10/10/5 11/11/5 9/9/5
f 12/12/6 13/13/6 11/11/6
f 14/14/7 15/15/7 13/13/7
f 16/16/8 17/17/8 15/15/8
f 18/18/9 19/19/9 17/17/9
f 20/20/10 21/21/10 19/19/10
f 22/22/11 14/23/11 6/24/11
f 22/25/12 23/26/12 21/21/12
f 24/27/13 1/28/13 23/26/13
f 7/29/14 15/30/14 23/31/14
f 2/1/1 4/4/1 3/2/1
f 4/4/2 6/6/2 5/5/2
f 6/6/3 8/8/3 7/7/3
f 8/8/4 10/10/4 9/9/4
f 10/10/5 12/12/5 11/11/5
f 12/12/6 14/14/6 13/13/6
f 14/14/7 16/16/7 15/15/7
f 16/16/8 18/18/8 17/17/8
f 18/18/9 20/20/9 19/19/9
f 20/20/10 22/25/10 21/21/10
f 6/24/11 4/32/11 2/33/11
f 2/33/11 24/34/11 22/22/11
f 22/22/11 20/35/11 18/36/11
f 18/36/11 16/37/11 22/22/11
f 16/37/11 14/23/11 22/22/11
f 14/23/11 12/38/11 10/39/11
f 10/39/11 8/40/11 14/23/11
f 8/40/11 6/24/11 14/23/11
f 6/24/11 2/33/11 22/22/11
f 22/25/12 24/27/12 23/26/12
f 24/27/13 2/41/13 1/28/13
f 23/31/14 1/42/14 3/43/14
f 3/43/14 5/44/14 23/31/14
f 5/44/14 7/29/14 23/31/14
f 7/29/14 9/45/14 11/46/14
f 11/46/14 13/47/14 7/29/14
f 13/47/14 15/30/14 7/29/14
f 15/30/14 17/48/14 19/49/14
f 19/49/14 21/50/14 23/31/14
f 15/30/14 19/49/14 23/31/14

View file

@ -0,0 +1,295 @@
# Blender 4.4.0
# www.blender.org
mtllib outline.mtl
o Cube
v -1.000000 -1.000000 1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -1.000000
v -0.500000 -1.000000 -1.000000
v -0.500000 1.000000 -1.000000
v -0.500000 -1.000000 1.000000
v -0.500000 1.000000 1.000000
v 0.500000 1.000000 -1.000000
v 0.500000 -1.000000 1.000000
v 0.500000 -1.000000 -1.000000
v 0.500000 1.000000 1.000000
v -1.000000 -1.000000 -0.500000
v -1.000000 1.000000 -0.500000
v 1.000000 -1.000000 -0.500000
v 1.000000 1.000000 -0.500000
v -0.500000 1.000000 -0.500000
v -0.500000 -1.000000 -0.500000
v 0.500000 1.000000 -0.500000
v 0.500000 -1.000000 -0.500000
v -1.000000 -1.000000 0.500000
v 1.000000 1.000000 0.500000
v -0.500000 1.000000 0.500000
v -0.500000 -1.000000 0.500000
v 0.500000 1.000000 0.500000
v 0.500000 -1.000000 0.500000
v -1.000000 1.000000 0.500000
v 1.000000 -1.000000 0.500000
v -1.000000 0.500000 1.000000
v -1.000000 0.500000 -1.000000
v 1.000000 0.500000 -1.000000
v 1.000000 0.500000 1.000000
v -0.500000 0.500000 1.000000
v -0.500000 0.500000 -1.000000
v 0.500000 0.500000 1.000000
v 0.500000 0.500000 -1.000000
v 1.000000 0.500000 -0.500000
v -1.000000 0.500000 -0.500000
v -1.000000 0.500000 0.500000
v 1.000000 0.500000 0.500000
v -1.000000 -0.500000 -1.000000
v 1.000000 -0.500000 -1.000000
v 1.000000 -0.500000 1.000000
v -0.500000 -0.500000 1.000000
v -0.500000 -0.500000 -1.000000
v 0.500000 -0.500000 1.000000
v 0.500000 -0.500000 -1.000000
v 1.000000 -0.500000 -0.500000
v -1.000000 -0.500000 -0.500000
v -1.000000 -0.500000 0.500000
v 1.000000 -0.500000 0.500000
v -1.000000 -0.500000 1.000000
v 0.500000 0.500000 0.500000
v -0.500000 -0.500000 0.500000
v 0.500000 0.500000 -0.500000
v 0.500000 -0.500000 -0.500000
v -0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.500000
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 -0.0000 1.0000
vn -0.0000 -1.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vt 0.625000 0.187500
vt 0.562500 0.250000
vt 0.562500 0.187500
vt 0.625000 0.437500
vt 0.562500 0.500000
vt 0.562500 0.437500
vt 0.625000 0.687500
vt 0.562500 0.750000
vt 0.562500 0.687500
vt 0.625000 0.937500
vt 0.562500 1.000000
vt 0.562500 0.937500
vt 0.375000 0.687500
vt 0.312500 0.750000
vt 0.312500 0.687500
vt 0.875000 0.687500
vt 0.812500 0.750000
vt 0.812500 0.687500
vt 0.687500 0.750000
vt 0.687500 0.687500
vt 0.187500 0.687500
vt 0.125000 0.750000
vt 0.125000 0.687500
vt 0.625000 0.812500
vt 0.562500 0.812500
vt 0.625000 0.250000
vt 0.562500 0.312500
vt 0.625000 0.750000
vt 0.187500 0.750000
vt 0.625000 0.312500
vt 0.312500 0.500000
vt 0.187500 0.562500
vt 0.187500 0.500000
vt 0.687500 0.500000
vt 0.625000 0.562500
vt 0.625000 0.500000
vt 0.125000 0.562500
vt 0.125000 0.500000
vt 0.812500 0.500000
vt 0.687500 0.562500
vt 0.875000 0.500000
vt 0.812500 0.562500
vt 0.375000 0.500000
vt 0.312500 0.562500
vt 0.562500 0.562500
vt 0.625000 0.062500
vt 0.562500 0.062500
vt 0.625000 0.000000
vt 0.562500 0.000000
vt 0.875000 0.562500
vt 0.375000 0.562500
vt 0.437500 0.562500
vt 0.437500 0.062500
vt 0.437500 0.000000
vt 0.437500 0.500000
vt 0.437500 0.437500
vt 0.437500 0.812500
vt 0.437500 0.750000
vt 0.437500 0.312500
vt 0.437500 0.250000
vt 0.437500 1.000000
vt 0.437500 0.937500
vt 0.437500 0.687500
vt 0.437500 0.187500
vt 0.375000 0.250000
vt 0.375000 0.187500
vt 0.375000 0.437500
vt 0.375000 0.750000
vt 0.375000 1.000000
vt 0.375000 0.937500
vt 0.375000 0.812500
vt 0.375000 0.312500
vt 0.375000 0.062500
vt 0.375000 0.000000
vt 0.625000 1.000000
vt 0.875000 0.750000
s 0
f 18/1/1 34/2/1 42/3/1
f 13/4/2 35/5/2 40/6/2
f 26/7/3 36/8/3 44/9/3
f 12/10/4 33/11/4 37/12/4
f 32/13/5 14/14/5 30/15/5
f 31/16/6 12/17/6 27/18/6
f 27/18/6 16/19/6 29/20/6
f 28/21/5 1/22/5 25/23/5
f 16/24/4 37/12/4 39/25/4
f 4/26/2 38/27/2 34/2/2
f 6/28/4 39/25/4 36/8/4
f 29/20/6 6/28/6 26/7/6
f 30/15/5 11/29/5 28/21/5
f 10/30/2 40/6/2 38/27/2
f 15/31/5 22/32/5 9/33/5
f 13/34/6 20/35/6 8/36/6
f 9/33/5 17/37/5 3/38/5
f 10/39/6 23/40/6 13/34/6
f 4/41/6 21/42/6 10/39/6
f 7/43/5 24/44/5 15/31/5
f 8/36/3 41/45/3 35/5/3
f 31/46/1 42/3/1 43/47/1
f 2/48/1 43/47/1 33/49/1
f 28/21/2 62/15/2 30/15/2
f 23/40/6 26/7/6 20/35/6
f 22/32/5 25/23/5 17/37/5
f 27/18/3 64/42/3 21/42/3
f 18/50/6 27/18/6 21/42/6
f 19/51/5 30/15/5 24/44/5
f 20/35/3 44/9/3 41/45/3
f 41/45/4 60/52/4 52/52/4
f 33/49/1 54/53/1 56/54/1
f 43/47/2 58/53/2 54/53/2
f 35/5/3 52/52/3 46/55/3
f 51/56/1 59/6/1 40/6/1
f 36/8/4 50/57/4 47/58/4
f 34/2/2 49/59/2 45/60/2
f 39/25/1 62/57/1 50/57/1
f 37/12/4 56/61/4 48/62/4
f 44/9/3 47/58/3 55/63/3
f 40/6/2 46/55/2 51/56/2
f 42/3/1 45/60/1 53/64/1
f 53/64/1 3/65/1 17/66/1
f 51/56/2 7/43/2 15/67/2
f 55/63/3 5/68/3 32/13/3
f 48/62/4 1/69/4 11/70/4
f 50/57/4 11/70/4 14/71/4
f 45/60/2 9/72/2 3/65/2
f 47/58/4 14/71/4 5/68/4
f 49/59/2 15/67/2 9/72/2
f 46/55/3 19/51/3 7/43/3
f 54/53/1 17/66/1 25/73/1
f 56/54/1 25/73/1 1/74/1
f 52/52/3 32/13/3 19/51/3
f 50/57/6 58/62/6 48/62/6
f 48/62/3 63/12/3 37/12/3
f 37/12/5 57/25/5 39/25/5
f 52/52/6 62/63/6 55/63/6
f 44/9/5 59/45/5 41/45/5
f 55/63/2 57/9/2 44/9/2
f 38/27/3 61/59/3 49/59/3
f 40/6/5 64/27/5 38/27/5
f 49/59/6 60/56/6 51/56/6
f 29/20/2 63/18/2 27/18/2
f 21/42/4 59/40/4 23/40/4
f 23/40/1 57/20/1 29/20/1
f 30/15/1 60/44/1 24/44/1
f 24/44/4 61/32/4 22/32/4
f 22/32/3 58/21/3 28/21/3
f 42/3/5 63/47/5 43/47/5
f 54/53/6 61/64/6 53/64/6
f 53/64/4 64/3/4 42/3/4
f 18/1/1 4/26/1 34/2/1
f 13/4/2 8/36/2 35/5/2
f 26/7/3 6/28/3 36/8/3
f 12/10/4 2/75/4 33/11/4
f 32/13/5 5/68/5 14/14/5
f 31/16/6 2/76/6 12/17/6
f 27/18/6 12/17/6 16/19/6
f 28/21/5 11/29/5 1/22/5
f 16/24/4 12/10/4 37/12/4
f 4/26/2 10/30/2 38/27/2
f 6/28/4 16/24/4 39/25/4
f 29/20/6 16/19/6 6/28/6
f 30/15/5 14/14/5 11/29/5
f 10/30/2 13/4/2 40/6/2
f 15/31/5 24/44/5 22/32/5
f 13/34/6 23/40/6 20/35/6
f 9/33/5 22/32/5 17/37/5
f 10/39/6 21/42/6 23/40/6
f 4/41/6 18/50/6 21/42/6
f 7/43/5 19/51/5 24/44/5
f 8/36/3 20/35/3 41/45/3
f 31/46/1 18/1/1 42/3/1
f 2/48/1 31/46/1 43/47/1
f 28/21/2 58/21/2 62/15/2
f 23/40/6 29/20/6 26/7/6
f 22/32/5 28/21/5 25/23/5
f 27/18/3 63/18/3 64/42/3
f 18/50/6 31/16/6 27/18/6
f 19/51/5 32/13/5 30/15/5
f 20/35/3 26/7/3 44/9/3
f 41/45/4 59/45/4 60/52/4
f 33/49/1 43/47/1 54/53/1
f 43/47/2 63/47/2 58/53/2
f 35/5/3 41/45/3 52/52/3
f 51/56/1 60/56/1 59/6/1
f 36/8/4 39/25/4 50/57/4
f 34/2/2 38/27/2 49/59/2
f 39/25/1 57/25/1 62/57/1
f 37/12/4 33/11/4 56/61/4
f 44/9/3 36/8/3 47/58/3
f 40/6/2 35/5/2 46/55/2
f 42/3/1 34/2/1 45/60/1
f 53/64/1 45/60/1 3/65/1
f 51/56/2 46/55/2 7/43/2
f 55/63/3 47/58/3 5/68/3
f 48/62/4 56/61/4 1/69/4
f 50/57/4 48/62/4 11/70/4
f 45/60/2 49/59/2 9/72/2
f 47/58/4 50/57/4 14/71/4
f 49/59/2 51/56/2 15/67/2
f 46/55/3 52/52/3 19/51/3
f 54/53/1 53/64/1 17/66/1
f 56/54/1 54/53/1 25/73/1
f 52/52/3 55/63/3 32/13/3
f 50/57/6 62/57/6 58/62/6
f 48/62/3 58/62/3 63/12/3
f 37/12/5 63/12/5 57/25/5
f 52/52/6 60/52/6 62/63/6
f 44/9/5 57/9/5 59/45/5
f 55/63/2 62/63/2 57/9/2
f 38/27/3 64/27/3 61/59/3
f 40/6/5 59/6/5 64/27/5
f 49/59/6 61/59/6 60/56/6
f 29/20/2 57/20/2 63/18/2
f 21/42/4 64/42/4 59/40/4
f 23/40/1 59/40/1 57/20/1
f 30/15/1 62/15/1 60/44/1
f 24/44/4 60/44/4 61/32/4
f 22/32/3 61/32/3 58/21/3
f 42/3/5 64/3/5 63/47/5
f 54/53/6 58/53/6 61/64/6
f 53/64/4 61/64/4 64/3/4

1627
asset-srcs/models/sphere.obj Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,36 @@
# Blender 4.4.3
# www.blender.org
mtllib wedge.mtl
o Cube
v 1.000000 -1.000000 -1.000000
v 1.000000 1.000000 1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v -1.000000 1.000000 1.000000
v -1.000000 -1.000000 1.000000
vn -0.0000 -0.0000 1.0000
vn -1.0000 -0.0000 -0.0000
vn -0.0000 -1.0000 -0.0000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 0.7071 -0.7071
vt 0.625000 0.750000
vt 0.375000 1.000000
vt 0.375000 0.750000
vt 0.375000 0.000000
vt 0.625000 0.000000
vt 0.375000 0.250000
vt 0.375000 0.500000
vt 0.125000 0.750000
vt 0.125000 0.500000
vt 0.875000 0.750000
vt 0.625000 1.000000
s 0
usemtl Material
f 2/1/1 6/2/1 3/3/1
f 6/4/2 5/5/2 4/6/2
f 1/7/3 6/8/3 4/9/3
f 1/7/4 2/1/4 3/3/4
f 5/10/5 1/7/5 4/6/5
f 2/1/1 5/11/1 6/2/1
f 1/7/3 3/3/3 6/8/3
f 5/10/5 2/1/5 1/7/5

View file

@ -9,6 +9,7 @@ const int FaceBack = 2;
const int FaceLeft = 3; const int FaceLeft = 3;
const int FaceBottom = 4; const int FaceBottom = 4;
const int FaceFront = 5; const int FaceFront = 5;
const int FaceNone = 6;
const int SurfaceSmooth = 0; const int SurfaceSmooth = 0;
const int SurfaceGlue = 1; const int SurfaceGlue = 1;
@ -31,6 +32,8 @@ uniform mat4 projection;
uniform int surfaces[6]; uniform int surfaces[6];
uniform vec3 texScale; uniform vec3 texScale;
const float faceThreshold = sqrt(2)/2;
void main() void main()
{ {
gl_Position = projection * view * model * vec4(aPos, 1.0); gl_Position = projection * view * model * vec4(aPos, 1.0);
@ -38,12 +41,20 @@ void main()
lPos = aPos; lPos = aPos;
vNormal = normalMatrix * aNormal; vNormal = normalMatrix * aNormal;
lNormal = aNormal; lNormal = aNormal;
int vFace = aNormal == vec3(0,1,0) ? FaceTop : int vFace = FaceNone;
aNormal == vec3(0, -1, 0) ? FaceBottom :
aNormal == vec3(1, 0, 0) ? FaceRight : if (dot(vec3(0, 1, 0), aNormal) > faceThreshold)
aNormal == vec3(-1, 0, 0) ? FaceLeft : vFace = FaceTop;
aNormal == vec3(0, 0, -1) ? FaceFront : else if (dot(vec3(0, -1, 0), aNormal) > faceThreshold)
aNormal == vec3(0, 0, 1) ? FaceBack : -1; vFace = FaceBottom;
else if (dot(vec3(1, 0, 0), aNormal) > faceThreshold)
vFace = FaceRight;
else if (dot(vec3(-1, 0, 0), aNormal) > faceThreshold)
vFace = FaceLeft;
else if (dot(vec3(0, 0, -1), aNormal) > faceThreshold)
vFace = FaceFront;
else if (dot(vec3(0, 0, 1), aNormal) > faceThreshold)
vFace = FaceBack;
vSurfaceZ = surfaces[vFace]; vSurfaceZ = surfaces[vFace];
if (surfaces[vFace] > SurfaceUniversal) vSurfaceZ = 0; if (surfaces[vFace] > SurfaceUniversal) vSurfaceZ = 0;

View file

@ -1,6 +1,6 @@
#include <GL/glew.h> #include <GL/glew.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include "objects/part.h" #include "objects/part/part.h"
#include "rendering/renderer.h" #include "rendering/renderer.h"
#include "common.h" #include "common.h"
@ -15,7 +15,7 @@ void mouseCallback(GLFWwindow* window, double xpos, double ypos);
void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods); void mouseButtonCallback(GLFWwindow* window, int button, int action, int mods);
void resizeCallback(GLFWwindow* window, int width, int height); void resizeCallback(GLFWwindow* window, int width, int height);
std::shared_ptr<Part> lastPart; std::shared_ptr<BasePart> lastPart;
int main() { int main() {
Logger::init(); Logger::init();
@ -58,7 +58,7 @@ int main() {
for (std::shared_ptr<Instance> inst : gWorkspace()->GetChildren()) { for (std::shared_ptr<Instance> inst : gWorkspace()->GetChildren()) {
if (inst->GetClass()->className != "Part") continue; if (inst->GetClass()->className != "Part") continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst); std::shared_ptr<BasePart> part = std::dynamic_pointer_cast<BasePart>(inst);
gWorkspace()->SyncPartPhysics(part); gWorkspace()->SyncPartPhysics(part);
} }

40
cmake/gitversion.cmake Normal file
View file

@ -0,0 +1,40 @@
# https://jonathanhamberg.com/post/cmake-embedding-git-hash/
# Detect current version from git
execute_process(
COMMAND git rev-parse HEAD
OUTPUT_VARIABLE GIT_COMMIT_HASH RESULT_VARIABLE GIT_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
execute_process(
COMMAND git describe --abbrev=0
OUTPUT_VARIABLE GIT_VERSION RESULT_VARIABLE GIT_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
execute_process(
COMMAND git describe --dirty
OUTPUT_VARIABLE GIT_VERSION_LONG RESULT_VARIABLE GIT_RESULT OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
# For some reason, CMake sets CMAKE_*_DIR all to be CMAKE_CURRENT_BINARY_DIR
# so we have to bypass this by passing in custom "orig_" variables
if (NOT GIT_STATE_WITHIN)
# Re-run this target always so that the version can be checked
add_custom_target(recheck_git_version ALL COMMAND ${CMAKE_COMMAND}
-DGIT_STATE_WITHIN=1
-DORIG_BINARY_DIR=${CMAKE_BINARY_DIR}
-DORIG_CURRENT_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}
-DORIG_SOURCE_DIR=${CMAKE_SOURCE_DIR}
-DORIG_CURRENT_SOURCE_DIR=${CMAKE_CURRENT_SOURCE_DIR}
-P ${CMAKE_MODULE_PATH}/gitversion.cmake
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/src/version.cpp
)
else ()
# # Set defaults if the git commands fail
if (NOT GIT_RESULT EQUAL 0)
set(GIT_COMMIT_HASH "unknown")
set(GIT_VERSION "unknown")
set(GIT_VERSION_LONG "unknown")
endif ()
# configure_file only touches the file if it has been changed, so no caching is necessary
configure_file(${ORIG_CURRENT_SOURCE_DIR}/src/version.cpp.in ${ORIG_CURRENT_BINARY_DIR}/src/version.cpp @ONLY)
endif ()

View file

@ -17,7 +17,7 @@ find_package(PkgConfig REQUIRED)
pkg_check_modules(LUAJIT REQUIRED luajit) pkg_check_modules(LUAJIT REQUIRED luajit)
link_directories(${LUAJIT_LIBRARY_DIRS}) link_directories(${LUAJIT_LIBRARY_DIRS})
# Run autogen ### Autogen
file(GLOB_RECURSE AUTOGEN_SOURCES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/src" "src/objects/*.h" "src/datatypes/*.h" "src/enum/*.h") file(GLOB_RECURSE AUTOGEN_SOURCES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/src" "src/objects/*.h" "src/datatypes/*.h" "src/enum/*.h")
# https://cmake.org/cmake/help/book/mastering-cmake/chapter/Custom%20Commands.html # https://cmake.org/cmake/help/book/mastering-cmake/chapter/Custom%20Commands.html
@ -36,12 +36,18 @@ foreach (SRC ${AUTOGEN_SOURCES})
list(APPEND AUTOGEN_OUTS "${OUT_PATH}") list(APPEND AUTOGEN_OUTS "${OUT_PATH}")
endforeach() endforeach()
### /Autogen
# Add version info into the build
include(gitversion)
add_custom_target(autogen_build ALL add_custom_target(autogen_build ALL
DEPENDS ${AUTOGEN_OUTS} DEPENDS ${AUTOGEN_OUTS}
) )
file(GLOB_RECURSE SOURCES "src/*.cpp" "src/*.h") file(GLOB_RECURSE SOURCES "src/*.cpp" "src/*.h")
list(APPEND SOURCES ${AUTOGEN_OUTS}) list(APPEND SOURCES ${AUTOGEN_OUTS})
list(APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/src/version.cpp)
add_library(openblocks STATIC ${SOURCES}) add_library(openblocks STATIC ${SOURCES})
set_target_properties(openblocks PROPERTIES OUTPUT_NAME "openblocks") set_target_properties(openblocks PROPERTIES OUTPUT_NAME "openblocks")
target_link_directories(openblocks PUBLIC ${LUAJIT_LIBRARY_DIRS}) target_link_directories(openblocks PUBLIC ${LUAJIT_LIBRARY_DIRS})

View file

@ -6,6 +6,7 @@
#include <iomanip> #include <iomanip>
#include <algorithm> #include <algorithm>
Color3::Color3() {};
Color3::Color3(float r, float g, float b) : r(std::clamp(r, 0.f, 1.f)), g(std::clamp(g, 0.f, 1.f)), b(std::clamp(b, 0.f, 1.f)) {}; Color3::Color3(float r, float g, float b) : r(std::clamp(r, 0.f, 1.f)), g(std::clamp(g, 0.f, 1.f)), b(std::clamp(b, 0.f, 1.f)) {};
Color3::Color3(const glm::vec3& vec) : r(std::clamp(vec.x, 0.f, 1.f)), g(std::clamp(vec.y, 0.f, 1.f)), b(std::clamp(vec.z, 0.f, 1.f)) {}; Color3::Color3(const glm::vec3& vec) : r(std::clamp(vec.x, 0.f, 1.f)), g(std::clamp(vec.y, 0.f, 1.f)), b(std::clamp(vec.z, 0.f, 1.f)) {};

View file

@ -14,6 +14,7 @@ class DEF_DATA Color3 {
public: public:
DEF_DATA_CTOR Color3(float r, float g, float b); DEF_DATA_CTOR Color3(float r, float g, float b);
Color3();
Color3(const glm::vec3&); Color3(const glm::vec3&);
virtual ~Color3(); virtual ~Color3();

14
core/src/enum/part.h Normal file
View file

@ -0,0 +1,14 @@
#pragma once
#include "datatypes/enum.h"
#include "enum/annotation.h"
enum class DEF_ENUM PartType {
Ball = 0,
Block = 1,
};
namespace EnumType {
extern const Enum PartType;
};

View file

@ -27,11 +27,11 @@ static CFrame XYZToZXY(glm::vec3(0, 0, 0), -glm::vec3(1, 0, 0), glm::vec3(0, 0,
static rp3d::PhysicsCommon common; static rp3d::PhysicsCommon common;
static rp3d::PhysicsWorld* world = common.createPhysicsWorld(); static rp3d::PhysicsWorld* world = common.createPhysicsWorld();
std::shared_ptr<Part> getHandleAdornee() { std::shared_ptr<BasePart> getHandleAdornee() {
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>(); std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
for (std::weak_ptr<Instance> inst : selection->Get()) { for (std::weak_ptr<Instance> inst : selection->Get()) {
if (!inst.expired() && inst.lock()->IsA<Part>()) if (!inst.expired() && inst.lock()->IsA<BasePart>())
return inst.lock()->CastTo<Part>().expect(); return inst.lock()->CastTo<BasePart>().expect();
} }
return {}; return {};
@ -82,8 +82,8 @@ static int getAABBOfSelection(glm::vec3& pos, glm::vec3& size, glm::vec3& min, g
int count = 0; int count = 0;
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>(); std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
for (std::weak_ptr<Instance> inst : selection->Get()) { for (std::weak_ptr<Instance> inst : selection->Get()) {
if (inst.expired() || !inst.lock()->IsA<Part>()) continue; if (inst.expired() || !inst.lock()->IsA<BasePart>()) continue;
std::shared_ptr<Part> part = inst.lock()->CastTo<Part>().expect(); std::shared_ptr<BasePart> part = inst.lock()->CastTo<BasePart>().expect();
if (count == 0) if (count == 0)
min = part->position(), max = part->position(); min = part->position(), max = part->position();
@ -99,12 +99,12 @@ static int getAABBOfSelection(glm::vec3& pos, glm::vec3& size, glm::vec3& min, g
return count; return count;
} }
static std::shared_ptr<Part> getFirstSelectedPart() { static std::shared_ptr<BasePart> getFirstSelectedPart() {
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>(); std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
for (std::weak_ptr<Instance> inst : selection->Get()) { for (std::weak_ptr<Instance> inst : selection->Get()) {
if (inst.expired() || !inst.lock()->IsA<Part>()) continue; if (inst.expired() || !inst.lock()->IsA<BasePart>()) continue;
return inst.lock()->CastTo<Part>().expect(); return inst.lock()->CastTo<BasePart>().expect();
} }
return {}; return {};

View file

@ -1,7 +1,7 @@
#pragma once #pragma once
#include "datatypes/cframe.h" #include "datatypes/cframe.h"
#include "objects/part.h" #include "objects/part/part.h"
#include <array> #include <array>
#include <memory> #include <memory>
@ -36,7 +36,7 @@ struct Handles {
bool worldMode = false; bool worldMode = false;
}; };
std::shared_ptr<Part> getHandleAdornee(); std::shared_ptr<BasePart> getHandleAdornee();
CFrame getHandleCFrame(HandleFace face); CFrame getHandleCFrame(HandleFace face);
CFrame partCFrameFromHandlePos(HandleFace face, Vector3 newPos); CFrame partCFrameFromHandlePos(HandleFace face, Vector3 newPos);
Vector3 handleSize(HandleFace face); Vector3 handleSize(HandleFace face);

View file

@ -4,7 +4,7 @@
#include "datatypes/ref.h" #include "datatypes/ref.h"
#include "objects/datamodel.h" #include "objects/datamodel.h"
#include "objects/service/jointsservice.h" #include "objects/service/jointsservice.h"
#include "objects/part.h" #include "objects/part/part.h"
#include "objects/service/workspace.h" #include "objects/service/workspace.h"
#include <memory> #include <memory>
#include <reactphysics3d/constraint/FixedJoint.h> #include <reactphysics3d/constraint/FixedJoint.h>
@ -54,6 +54,6 @@ void JointInstance::onUpdated(std::string property) {
oldPart1 = part1; oldPart1 = part1;
} }
std::optional<std::shared_ptr<Workspace>> JointInstance::workspaceOfPart(std::shared_ptr<Part> part) { std::optional<std::shared_ptr<Workspace>> JointInstance::workspaceOfPart(std::shared_ptr<BasePart> part) {
return part->workspace(); return part->workspace();
} }

View file

@ -8,31 +8,31 @@
//this is necessary ebcause we use std::weak_ptr<Part> without including it in this file //this is necessary ebcause we use std::weak_ptr<Part> without including it in this file
#ifdef __AUTOGEN_EXTRA_INCLUDES__ #ifdef __AUTOGEN_EXTRA_INCLUDES__
#include "../part.h" #include "objects/part/part.h"
#endif #endif
class Part; class BasePart;
class Workspace; class Workspace;
class DEF_INST_ABSTRACT JointInstance : public Instance { class DEF_INST_ABSTRACT JointInstance : public Instance {
AUTOGEN_PREAMBLE AUTOGEN_PREAMBLE
std::weak_ptr<Part> oldPart0; std::weak_ptr<BasePart> oldPart0;
std::weak_ptr<Part> oldPart1; std::weak_ptr<BasePart> oldPart1;
protected: protected:
// The workspace the joint was created in, if it exists // The workspace the joint was created in, if it exists
std::weak_ptr<Workspace> jointWorkspace; std::weak_ptr<Workspace> jointWorkspace;
void OnAncestryChanged(std::optional<std::shared_ptr<Instance>>, std::optional<std::shared_ptr<Instance>>) override; void OnAncestryChanged(std::optional<std::shared_ptr<Instance>>, std::optional<std::shared_ptr<Instance>>) override;
std::optional<std::shared_ptr<Workspace>> workspaceOfPart(std::shared_ptr<Part>); std::optional<std::shared_ptr<Workspace>> workspaceOfPart(std::shared_ptr<BasePart>);
void onUpdated(std::string property); void onUpdated(std::string property);
virtual void buildJoint() = 0; virtual void buildJoint() = 0;
virtual void breakJoint() = 0; virtual void breakJoint() = 0;
public: public:
DEF_PROP_(on_update=onUpdated) std::weak_ptr<Part> part0; DEF_PROP_(on_update=onUpdated) std::weak_ptr<BasePart> part0;
DEF_PROP_(on_update=onUpdated) std::weak_ptr<Part> part1; DEF_PROP_(on_update=onUpdated) std::weak_ptr<BasePart> part1;
DEF_PROP_(on_update=onUpdated) CFrame c0; DEF_PROP_(on_update=onUpdated) CFrame c0;
DEF_PROP_(on_update=onUpdated) CFrame c1; DEF_PROP_(on_update=onUpdated) CFrame c1;

View file

@ -1,6 +1,6 @@
#include "rotate.h" #include "rotate.h"
#include "objects/service/jointsservice.h" #include "objects/service/jointsservice.h"
#include "objects/part.h" #include "objects/part/part.h"
#include "objects/service/workspace.h" #include "objects/service/workspace.h"
#include "rendering/renderer.h" #include "rendering/renderer.h"
#include <reactphysics3d/constraint/HingeJoint.h> #include <reactphysics3d/constraint/HingeJoint.h>

View file

@ -1,6 +1,6 @@
#include "rotatev.h" #include "rotatev.h"
#include "objects/service/jointsservice.h" #include "objects/service/jointsservice.h"
#include "objects/part.h" #include "objects/part/part.h"
#include "objects/service/workspace.h" #include "objects/service/workspace.h"
#include "rendering/renderer.h" #include "rendering/renderer.h"
#include <reactphysics3d/constraint/HingeJoint.h> #include <reactphysics3d/constraint/HingeJoint.h>

View file

@ -4,7 +4,7 @@
#include "objects/datamodel.h" #include "objects/datamodel.h"
#include "objects/joint/jointinstance.h" #include "objects/joint/jointinstance.h"
#include "objects/service/jointsservice.h" #include "objects/service/jointsservice.h"
#include "objects/part.h" #include "objects/part/part.h"
#include "objects/service/workspace.h" #include "objects/service/workspace.h"
#include <memory> #include <memory>
#include <reactphysics3d/constraint/FixedJoint.h> #include <reactphysics3d/constraint/FixedJoint.h>

View file

@ -4,7 +4,7 @@
#include "objects/datamodel.h" #include "objects/datamodel.h"
#include "objects/joint/jointinstance.h" #include "objects/joint/jointinstance.h"
#include "objects/service/jointsservice.h" #include "objects/service/jointsservice.h"
#include "objects/part.h" #include "objects/part/part.h"
#include "objects/service/workspace.h" #include "objects/service/workspace.h"
#include <memory> #include <memory>
#include <reactphysics3d/constraint/FixedJoint.h> #include <reactphysics3d/constraint/FixedJoint.h>

View file

@ -6,9 +6,10 @@
#include "objects/joint/rotatev.h" #include "objects/joint/rotatev.h"
#include "objects/joint/weld.h" #include "objects/joint/weld.h"
#include "objects/message.h" #include "objects/message.h"
#include "objects/part/wedgepart.h"
#include "objects/service/jointsservice.h" #include "objects/service/jointsservice.h"
#include "objects/model.h" #include "objects/model.h"
#include "objects/part.h" #include "objects/part/part.h"
#include "objects/joint/snap.h" #include "objects/joint/snap.h"
#include "objects/script.h" #include "objects/script.h"
#include "objects/service/script/scriptcontext.h" #include "objects/service/script/scriptcontext.h"
@ -21,7 +22,9 @@ std::map<std::string, const InstanceType*> INSTANCE_MAP = {
{ "Instance", &Instance::TYPE }, { "Instance", &Instance::TYPE },
{ "DataModel", &DataModel::TYPE }, { "DataModel", &DataModel::TYPE },
{ "BasePart", &BasePart::TYPE },
{ "Part", &Part::TYPE }, { "Part", &Part::TYPE },
{ "WedgePart", &WedgePart::TYPE },
{ "Snap", &Snap::TYPE }, { "Snap", &Snap::TYPE },
{ "Weld", &Weld::TYPE }, { "Weld", &Weld::TYPE },
{ "Rotate", &Rotate::TYPE }, { "Rotate", &Rotate::TYPE },

View file

@ -1,5 +1,5 @@
#include "part.h" #include "basepart.h"
#include "base/instance.h" #include "objects/base/instance.h"
#include "common.h" #include "common.h"
#include "datatypes/base.h" #include "datatypes/base.h"
#include "datatypes/cframe.h" #include "datatypes/cframe.h"
@ -19,15 +19,14 @@
#include <memory> #include <memory>
#include <optional> #include <optional>
Part::Part(): Part(PartConstructParams { .size = glm::vec3(2, 1.2, 4), .color = Color3(0.639216f, 0.635294f, 0.647059f) }) { BasePart::BasePart(const InstanceType* type): BasePart(type, PartConstructParams { .size = glm::vec3(4, 1.2, 2), .color = Color3(0.639216f, 0.635294f, 0.647059f) }) {
} }
Part::Part(PartConstructParams params): PVInstance(&TYPE), cframe(CFrame::FromEulerAnglesXYZ((Vector3)params.rotation) + params.position), BasePart::BasePart(const InstanceType* type, PartConstructParams params): PVInstance(type), cframe(CFrame::FromEulerAnglesXYZ((Vector3)params.rotation) + params.position),
size(params.size), color(params.color), anchored(params.anchored), locked(params.locked) { size(params.size), color(params.color), anchored(params.anchored), locked(params.locked) {
} }
Part::~Part() { BasePart::~BasePart() {
// This relies on physicsCommon still existing. Be very careful. // This relies on physicsCommon still existing. Be very careful.
if (this->rigidBody && workspace()) { if (this->rigidBody && workspace()) {
workspace().value()->DestroyRigidBody(rigidBody); workspace().value()->DestroyRigidBody(rigidBody);
@ -36,12 +35,12 @@ Part::~Part() {
} }
void Part::OnAncestryChanged(std::optional<std::shared_ptr<Instance>> child, std::optional<std::shared_ptr<Instance>> newParent) { void BasePart::OnAncestryChanged(std::optional<std::shared_ptr<Instance>> child, std::optional<std::shared_ptr<Instance>> newParent) {
if (this->rigidBody) if (this->rigidBody)
this->rigidBody->setIsActive(workspace().has_value()); this->rigidBody->setIsActive(workspace().has_value());
if (workspace()) if (workspace())
workspace().value()->SyncPartPhysics(std::dynamic_pointer_cast<Part>(this->shared_from_this())); workspace().value()->SyncPartPhysics(std::dynamic_pointer_cast<BasePart>(this->shared_from_this()));
// Destroy joints // Destroy joints
if (!workspace()) BreakJoints(); if (!workspace()) BreakJoints();
@ -49,22 +48,22 @@ void Part::OnAncestryChanged(std::optional<std::shared_ptr<Instance>> child, std
// TODO: Sleeping bodies that touch this one also need to be updated // TODO: Sleeping bodies that touch this one also need to be updated
} }
void Part::OnWorkspaceAdded(std::optional<std::shared_ptr<Workspace>> oldWorkspace, std::shared_ptr<Workspace> newWorkspace) { void BasePart::OnWorkspaceAdded(std::optional<std::shared_ptr<Workspace>> oldWorkspace, std::shared_ptr<Workspace> newWorkspace) {
newWorkspace->AddBody(shared<Part>()); newWorkspace->AddBody(shared<BasePart>());
} }
void Part::OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace) { void BasePart::OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace) {
if (simulationTicket.has_value()) if (simulationTicket.has_value())
oldWorkspace->RemoveBody(shared<Part>()); oldWorkspace->RemoveBody(shared<BasePart>());
} }
void Part::onUpdated(std::string property) { void BasePart::onUpdated(std::string property) {
// Reset velocity // Reset velocity
if (property != "Velocity") if (property != "Velocity")
velocity = Vector3::ZERO; velocity = Vector3::ZERO;
if (workspace()) if (workspace())
workspace().value()->SyncPartPhysics(std::dynamic_pointer_cast<Part>(this->shared_from_this())); workspace().value()->SyncPartPhysics(std::dynamic_pointer_cast<BasePart>(this->shared_from_this()));
// When position/rotation/size is manually edited, break all joints, they don't apply anymore // When position/rotation/size is manually edited, break all joints, they don't apply anymore
if (property != "Anchored") if (property != "Anchored")
@ -88,7 +87,7 @@ static Vector3 verts[8] {
{1, 1, 1}, {1, 1, 1},
}; };
Vector3 Part::GetAABB() { Vector3 BasePart::GetAABB() {
Vector3 min(0, 0, 0); Vector3 min(0, 0, 0);
Vector3 max(0, 0, 0); Vector3 max(0, 0, 0);
for (Vector3 vert : verts) { for (Vector3 vert : verts) {
@ -99,7 +98,7 @@ Vector3 Part::GetAABB() {
return (min - max).Abs() / 2; return (min - max).Abs() / 2;
} }
void Part::BreakJoints() { void BasePart::BreakJoints() {
for (std::weak_ptr<JointInstance> joint : primaryJoints) { for (std::weak_ptr<JointInstance> joint : primaryJoints) {
if (joint.expired()) continue; if (joint.expired()) continue;
joint.lock()->Destroy(); joint.lock()->Destroy();
@ -120,7 +119,7 @@ static Vector3 FACES[6] = {
{0, 0, -1}, {0, 0, -1},
}; };
SurfaceType Part::surfaceFromFace(NormalId face) { SurfaceType BasePart::surfaceFromFace(NormalId face) {
switch (face) { switch (face) {
case Top: return topSurface; case Top: return topSurface;
case Bottom: return bottomSurface; case Bottom: return bottomSurface;
@ -132,7 +131,7 @@ SurfaceType Part::surfaceFromFace(NormalId face) {
return SurfaceType::Smooth; // Unreachable return SurfaceType::Smooth; // Unreachable
} }
float Part::GetSurfaceParamA(Vector3 face) { float BasePart::GetSurfaceParamA(Vector3 face) {
switch (faceFromNormal(face)) { switch (faceFromNormal(face)) {
case Top: return topParamA; case Top: return topParamA;
case Bottom: return bottomParamA; case Bottom: return bottomParamA;
@ -144,7 +143,7 @@ float Part::GetSurfaceParamA(Vector3 face) {
return 0; // Unreachable return 0; // Unreachable
} }
float Part::GetSurfaceParamB(Vector3 face) { float BasePart::GetSurfaceParamB(Vector3 face) {
switch (faceFromNormal(face)) { switch (faceFromNormal(face)) {
case Top: return topParamB; case Top: return topParamB;
case Bottom: return bottomParamB; case Bottom: return bottomParamB;
@ -156,14 +155,18 @@ float Part::GetSurfaceParamB(Vector3 face) {
return 0; // Unreachable return 0; // Unreachable
} }
bool Part::checkJointContinuity(std::shared_ptr<Part> otherPart) { Vector3 BasePart::GetEffectiveSize() {
return size;
}
bool BasePart::checkJointContinuity(std::shared_ptr<BasePart> otherPart) {
// Make sure that the two parts don't depend on one another // Make sure that the two parts don't depend on one another
return checkJointContinuityUp(otherPart) && checkJointContinuityDown(otherPart); return checkJointContinuityUp(otherPart) && checkJointContinuityDown(otherPart);
} }
bool Part::checkJointContinuityDown(std::shared_ptr<Part> otherPart) { bool BasePart::checkJointContinuityDown(std::shared_ptr<BasePart> otherPart) {
if (shared<Part>() == otherPart) return false; if (shared<BasePart>() == otherPart) return false;
for (auto joint : primaryJoints) { for (auto joint : primaryJoints) {
if (joint.expired() || joint.lock()->part1.expired()) continue; if (joint.expired() || joint.lock()->part1.expired()) continue;
if (!joint.lock()->part1.lock()->checkJointContinuityDown(otherPart)) if (!joint.lock()->part1.lock()->checkJointContinuityDown(otherPart))
@ -172,8 +175,8 @@ bool Part::checkJointContinuityDown(std::shared_ptr<Part> otherPart) {
return true; return true;
} }
bool Part::checkJointContinuityUp(std::shared_ptr<Part> otherPart) { bool BasePart::checkJointContinuityUp(std::shared_ptr<BasePart> otherPart) {
if (shared<Part>() == otherPart) return false; if (shared<BasePart>() == otherPart) return false;
for (auto joint : secondaryJoints) { for (auto joint : secondaryJoints) {
if (joint.expired() || joint.lock()->part0.expired()) continue; if (joint.expired() || joint.lock()->part0.expired()) continue;
if (!joint.lock()->part0.lock()->checkJointContinuityUp(otherPart)) if (!joint.lock()->part0.lock()->checkJointContinuityUp(otherPart))
@ -182,7 +185,7 @@ bool Part::checkJointContinuityUp(std::shared_ptr<Part> otherPart) {
return true; return true;
} }
bool Part::checkSurfacesTouching(CFrame surfaceFrame, Vector3 size, Vector3 myFace, Vector3 otherFace, std::shared_ptr<Part> otherPart) { bool BasePart::checkSurfacesTouching(CFrame surfaceFrame, Vector3 size, Vector3 myFace, Vector3 otherFace, std::shared_ptr<BasePart> otherPart) {
Vector3 farCorner0 = surfaceFrame.Inverse() * otherPart->cframe * (Vector3::ONE * (otherPart->size / 2.f)); Vector3 farCorner0 = surfaceFrame.Inverse() * otherPart->cframe * (Vector3::ONE * (otherPart->size / 2.f));
Vector3 farCorner1 = surfaceFrame.Inverse() * otherPart->cframe * (-Vector3::ONE * (otherPart->size / 2.f)); Vector3 farCorner1 = surfaceFrame.Inverse() * otherPart->cframe * (-Vector3::ONE * (otherPart->size / 2.f));
@ -218,7 +221,7 @@ std::optional<std::shared_ptr<JointInstance>> makeJointFromSurfaces(SurfaceType
return std::nullopt; return std::nullopt;
} }
void Part::MakeJoints() { void BasePart::MakeJoints() {
// Algorithm: Find nearby parts // Algorithm: Find nearby parts
// Make sure parts are not dependant on each other (via primary/secondaryJoints) // Make sure parts are not dependant on each other (via primary/secondaryJoints)
// Find matching surfaces (surface normal dot product < -0.999) // Find matching surfaces (surface normal dot product < -0.999)
@ -233,8 +236,8 @@ void Part::MakeJoints() {
for (auto it = workspace().value()->GetDescendantsStart(); it != workspace().value()->GetDescendantsEnd(); it++) { for (auto it = workspace().value()->GetDescendantsStart(); it != workspace().value()->GetDescendantsEnd(); it++) {
std::shared_ptr<Instance> obj = *it; std::shared_ptr<Instance> obj = *it;
if (obj == shared_from_this()) continue; // Skip ourselves if (obj == shared_from_this()) continue; // Skip ourselves
if (obj->GetClass()->className != "Part") continue; // TODO: Replace this with a .IsA call instead of comparing the class name directly if (!obj->IsA<BasePart>()) continue;
std::shared_ptr<Part> otherPart = obj->CastTo<Part>().expect(); std::shared_ptr<BasePart> otherPart = obj->CastTo<BasePart>().expect();
for (Vector3 myFace : FACES) { for (Vector3 myFace : FACES) {
Vector3 myWorldNormal = cframe.Rotation() * myFace; Vector3 myWorldNormal = cframe.Rotation() * myFace;
@ -278,8 +281,8 @@ void Part::MakeJoints() {
auto joint_ = makeJointFromSurfaces(mySurface, otherSurface); auto joint_ = makeJointFromSurfaces(mySurface, otherSurface);
if (!joint_) continue; if (!joint_) continue;
std::shared_ptr<JointInstance> joint = joint_.value(); std::shared_ptr<JointInstance> joint = joint_.value();
joint->part0 = shared<Part>(); joint->part0 = shared<BasePart>();
joint->part1 = otherPart->shared<Part>(); joint->part1 = otherPart->shared<BasePart>();
joint->c0 = contact0; joint->c0 = contact0;
joint->c1 = contact1; joint->c1 = contact1;
dataModel().value()->GetService<JointsService>()->AddChild(joint); dataModel().value()->GetService<JointsService>()->AddChild(joint);
@ -291,7 +294,7 @@ void Part::MakeJoints() {
} }
} }
void Part::trackJoint(std::shared_ptr<JointInstance> joint) { void BasePart::trackJoint(std::shared_ptr<JointInstance> joint) {
if (!joint->part0.expired() && joint->part0.lock() == shared_from_this()) { if (!joint->part0.expired() && joint->part0.lock() == shared_from_this()) {
for (auto it = primaryJoints.begin(); it != primaryJoints.end();) { for (auto it = primaryJoints.begin(); it != primaryJoints.end();) {
// Clean expired refs // Clean expired refs
@ -325,7 +328,7 @@ void Part::trackJoint(std::shared_ptr<JointInstance> joint) {
} }
} }
void Part::untrackJoint(std::shared_ptr<JointInstance> joint) { void BasePart::untrackJoint(std::shared_ptr<JointInstance> joint) {
for (auto it = primaryJoints.begin(); it != primaryJoints.end();) { for (auto it = primaryJoints.begin(); it != primaryJoints.end();) {
// Clean expired refs // Clean expired refs
if (it->expired() || it->lock() == joint) { if (it->expired() || it->lock() == joint) {

View file

@ -12,9 +12,11 @@
#include "enum/surface.h" #include "enum/surface.h"
#include <mutex> #include <mutex>
#include <optional> #include <optional>
#include <reactphysics3d/body/RigidBody.h>
#include <reactphysics3d/engine/PhysicsCommon.h>
#include <reactphysics3d/reactphysics3d.h> #include <reactphysics3d/reactphysics3d.h>
#include <vector> #include <vector>
#include "annotation.h" #include "objects/annotation.h"
#include "objects/pvinstance.h" #include "objects/pvinstance.h"
namespace rp = reactphysics3d; namespace rp = reactphysics3d;
@ -34,11 +36,11 @@ class Workspace;
#ifndef __SIMULATION_TICKET #ifndef __SIMULATION_TICKET
#define __SIMULATION_TICKET #define __SIMULATION_TICKET
class Part; class BasePart;
typedef std::list<std::shared_ptr<Part>>::iterator SimulationTicket; typedef std::list<std::shared_ptr<BasePart>>::iterator SimulationTicket;
#endif #endif
class DEF_INST_(explorer_icon="part") Part : public PVInstance { class DEF_INST_ABSTRACT_(explorer_icon="part") BasePart : public PVInstance {
AUTOGEN_PREAMBLE AUTOGEN_PREAMBLE
protected: protected:
// Joints where this part is Part0 // Joints where this part is Part0
@ -50,10 +52,10 @@ protected:
void untrackJoint(std::shared_ptr<JointInstance>); void untrackJoint(std::shared_ptr<JointInstance>);
SurfaceType surfaceFromFace(NormalId); SurfaceType surfaceFromFace(NormalId);
bool checkJointContinuity(std::shared_ptr<Part>); bool checkJointContinuity(std::shared_ptr<BasePart>);
bool checkJointContinuityUp(std::shared_ptr<Part>); bool checkJointContinuityUp(std::shared_ptr<BasePart>);
bool checkJointContinuityDown(std::shared_ptr<Part>); bool checkJointContinuityDown(std::shared_ptr<BasePart>);
bool checkSurfacesTouching(CFrame surfaceFrame, Vector3 size, Vector3 myFace, Vector3 otherFace, std::shared_ptr<Part> otherPart); bool checkSurfacesTouching(CFrame surfaceFrame, Vector3 size, Vector3 myFace, Vector3 otherFace, std::shared_ptr<BasePart> otherPart);
friend JointInstance; friend JointInstance;
friend Workspace; friend Workspace;
@ -62,6 +64,11 @@ protected:
virtual void OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace) override; virtual void OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace) override;
void OnAncestryChanged(std::optional<std::shared_ptr<Instance>> child, std::optional<std::shared_ptr<Instance>> newParent) override; void OnAncestryChanged(std::optional<std::shared_ptr<Instance>> child, std::optional<std::shared_ptr<Instance>> newParent) override;
void onUpdated(std::string); void onUpdated(std::string);
virtual void updateCollider(rp::PhysicsCommon* common) = 0;
BasePart(const InstanceType*);
BasePart(const InstanceType*, PartConstructParams params);
public: public:
DEF_PROP_CATEGORY(DATA) DEF_PROP_CATEGORY(DATA)
DEF_PROP_(on_update=onUpdated) Vector3 velocity; DEF_PROP_(on_update=onUpdated) Vector3 velocity;
@ -115,14 +122,9 @@ public:
inline SurfaceType GetSurfaceFromFace(NormalId face) { return surfaceFromFace(face); } inline SurfaceType GetSurfaceFromFace(NormalId face) { return surfaceFromFace(face); }
float GetSurfaceParamA(Vector3 face); float GetSurfaceParamA(Vector3 face);
float GetSurfaceParamB(Vector3 face); float GetSurfaceParamB(Vector3 face);
virtual Vector3 GetEffectiveSize();
Part(); ~BasePart() override;
Part(PartConstructParams params);
~Part() override;
static inline std::shared_ptr<Part> New() { return std::make_shared<Part>(); };
static inline std::shared_ptr<Part> New(PartConstructParams params) { return std::make_shared<Part>(params); };
static inline std::shared_ptr<Instance> Create() { return std::make_shared<Part>(); };
inline Vector3 position() { return cframe.Position(); } inline Vector3 position() { return cframe.Position(); }

View file

@ -0,0 +1,42 @@
#include "part.h"
#include "enum/part.h"
#include "physics/util.h"
#include <glm/common.hpp>
Part::Part(): BasePart(&TYPE) {
_lastShape = shape;
_lastSize = size;
}
Part::Part(PartConstructParams params): BasePart(&TYPE, params) {
_lastShape = shape;
_lastSize = size;
}
void Part::updateCollider(rp::PhysicsCommon* common) {
rp::CollisionShape* physShape;
if (shape == PartType::Ball) {
physShape = common->createSphereShape(glm::min(size.X(), size.Y(), size.Z()) * 0.5f);
} else if (shape == PartType::Block) {
physShape = common->createBoxShape(glmToRp(size * glm::vec3(0.5f)));
}
// Recreate the rigidbody if the shape changes
if (rigidBody->getNbColliders() > 0 && (_lastShape != shape || _lastSize != size)) {
// TODO: This causes Touched to get called twice. Fix this.
rigidBody->removeCollider(rigidBody->getCollider(0));
rigidBody->addCollider(physShape, rp::Transform());
}
if (rigidBody->getNbColliders() == 0)
rigidBody->addCollider(physShape, rp::Transform());
_lastShape = shape;
_lastSize = size;
}
Vector3 Part::GetEffectiveSize() {
return shape == PartType::Ball ? (Vector3)glm::vec3(glm::min(size.X(), size.Y(), size.Z())) : size;
}

View file

@ -0,0 +1,26 @@
#pragma once
#include "basepart.h"
#include "enum/part.h"
#include "objects/annotation.h"
class DEF_INST Part : public BasePart {
AUTOGEN_PREAMBLE
PartType _lastShape;
Vector3 _lastSize;
protected:
void updateCollider(rp::PhysicsCommon* common) override;
public:
Part();
Part(PartConstructParams params);
DEF_PROP_(on_update=onUpdated) PartType shape = PartType::Block;
Vector3 GetEffectiveSize() override;
static inline std::shared_ptr<Part> New() { return std::make_shared<Part>(); };
static inline std::shared_ptr<Part> New(PartConstructParams params) { return std::make_shared<Part>(params); };
static inline std::shared_ptr<Instance> Create() { return std::make_shared<Part>(); };
};

View file

@ -0,0 +1,91 @@
#include "wedgepart.h"
#include "physics/util.h"
#include <reactphysics3d/collision/ConvexMesh.h>
#include <reactphysics3d/collision/shapes/ConvexMeshShape.h>
rp::ConvexMesh* wedgePhysMesh;
WedgePart::WedgePart(): BasePart(&TYPE) {
}
WedgePart::WedgePart(PartConstructParams params): BasePart(&TYPE, params) {
}
void WedgePart::updateCollider(rp::PhysicsCommon* common) {
rp::ConvexMeshShape* shape = common->createConvexMeshShape(wedgePhysMesh, glmToRp(size * glm::vec3(0.5f)));
// Recreate the rigidbody if the shape changes
if (rigidBody->getNbColliders() > 0
&& dynamic_cast<rp::ConvexMeshShape*>(rigidBody->getCollider(0)->getCollisionShape())->getScale() != shape->getScale()) {
// TODO: This causes Touched to get called twice. Fix this.
rigidBody->removeCollider(rigidBody->getCollider(0));
rigidBody->addCollider(shape, rp::Transform());
}
if (rigidBody->getNbColliders() == 0)
rigidBody->addCollider(shape, rp::Transform());
}
void WedgePart::createWedgeShape(rp::PhysicsCommon* common) {
// https://www.reactphysics3d.com/documentation/index.html#creatingbody
float vertices[] = {
// X Y Z
/*0*/ -1, 1, 1, // 0
/*1*/ -1, -1, 1, // |
/*2*/ -1, -1, -1, // 1---2
/*3*/ 1, 1, 1,
/*4*/ 1, -1, 1,
/*5*/ 1, -1, -1,
};
// -x +x
// +z 1----------4
// | bottom |
// -z 2----------5
// -x +x
// +y 0----------3
// | front |
// -y 1----------4
// -x +x
// +yz 0----------3
// | slope |
// -yz 2----------5
int indices[] = {
// Base
1, 2, 5, 4,
// Back-face
0, 1, 4, 3,
// 4, 1, 0, 3,
// Slope
0, 2, 5, 3,
// 3, 5, 2, 0,
// Sides
0, 1, 2,
3, 4, 5,
};
// Description of the six faces of the convex mesh
rp::PolygonVertexArray::PolygonFace* polygonFaces = new rp::PolygonVertexArray::PolygonFace[5];
polygonFaces[0] = { 4, 0 }; // Bottom
polygonFaces[1] = { 4, 4 }; // Front
polygonFaces[2] = { 4, 8 }; // Slope
polygonFaces[3] = { 3, 12 }; // Side
polygonFaces[4] = { 3, 15 }; // Side
// Create the polygon vertex array
rp::PolygonVertexArray polygonVertexArray(6, vertices, 3 * sizeof(float), indices, sizeof(int), 5, polygonFaces,
rp::PolygonVertexArray::VertexDataType::VERTEX_FLOAT_TYPE,
rp::PolygonVertexArray::IndexDataType::INDEX_INTEGER_TYPE);
// Create the convex mesh
std::vector<rp3d::Message> messages;
wedgePhysMesh = common->createConvexMesh(polygonVertexArray, messages);
}

View file

@ -0,0 +1,21 @@
#pragma once
#include "basepart.h"
#include "objects/annotation.h"
class DEF_INST WedgePart : public BasePart {
AUTOGEN_PREAMBLE
protected:
void updateCollider(rp::PhysicsCommon* common) override;
static void createWedgeShape(rp::PhysicsCommon* common);
friend Workspace;
public:
WedgePart();
WedgePart(PartConstructParams params);
static inline std::shared_ptr<WedgePart> New() { return std::make_shared<WedgePart>(); };
static inline std::shared_ptr<WedgePart> New(PartConstructParams params) { return std::make_shared<WedgePart>(params); };
static inline std::shared_ptr<Instance> Create() { return std::make_shared<WedgePart>(); };
};

View file

@ -4,7 +4,8 @@
#include "datatypes/vector.h" #include "datatypes/vector.h"
#include "logger.h" #include "logger.h"
#include "objects/base/instance.h" #include "objects/base/instance.h"
#include "objects/part.h" #include "objects/part/part.h"
#include "objects/part/wedgepart.h"
#include "objects/service/jointsservice.h" #include "objects/service/jointsservice.h"
#include "objects/joint/jointinstance.h" #include "objects/joint/jointinstance.h"
#include "objects/datamodel.h" #include "objects/datamodel.h"
@ -39,8 +40,8 @@ void PhysicsEventListener::onContact(const rp::CollisionCallback::CallbackData&
continue; continue;
ContactItem contact; ContactItem contact;
contact.part0 = reinterpret_cast<Part*>(pair.getBody1()->getUserData())->shared<Part>(); contact.part0 = reinterpret_cast<BasePart*>(pair.getBody1()->getUserData())->shared<BasePart>();
contact.part1 = reinterpret_cast<Part*>(pair.getBody2()->getUserData())->shared<Part>(); contact.part1 = reinterpret_cast<BasePart*>(pair.getBody2()->getUserData())->shared<BasePart>();
contact.action = type == reactphysics3d::CollisionCallback::ContactPair::EventType::ContactStart ? ContactItem::CONTACTITEM_TOUCHED : ContactItem::CONTACTITEM_TOUCHENDED; contact.action = type == reactphysics3d::CollisionCallback::ContactPair::EventType::ContactStart ? ContactItem::CONTACTITEM_TOUCHED : ContactItem::CONTACTITEM_TOUCHENDED;
workspace->contactQueue.push(contact); workspace->contactQueue.push(contact);
@ -55,8 +56,8 @@ void PhysicsEventListener::onTrigger(const rp::OverlapCallback::CallbackData& da
auto type = pair.getEventType(); auto type = pair.getEventType();
if (type == rp::OverlapCallback::OverlapPair::EventType::OverlapStay) continue; if (type == rp::OverlapCallback::OverlapPair::EventType::OverlapStay) continue;
auto part0 = reinterpret_cast<Part*>(pair.getBody1()->getUserData())->shared<Part>(); auto part0 = reinterpret_cast<BasePart*>(pair.getBody1()->getUserData())->shared<BasePart>();
auto part1 = reinterpret_cast<Part*>(pair.getBody2()->getUserData())->shared<Part>(); auto part1 = reinterpret_cast<BasePart*>(pair.getBody2()->getUserData())->shared<BasePart>();
if (type == reactphysics3d::OverlapCallback::OverlapPair::EventType::OverlapStart) { if (type == reactphysics3d::OverlapCallback::OverlapPair::EventType::OverlapStart) {
part0->Touched->Fire({ (Variant)InstanceRef(part1) }); part0->Touched->Fire({ (Variant)InstanceRef(part1) });
@ -82,11 +83,15 @@ void Workspace::InitService() {
physicsWorld->setEventListener(&physicsEventListener); physicsWorld->setEventListener(&physicsEventListener);
// Sync all parts // Create meshes
WedgePart::createWedgeShape(physicsCommon);
}
void Workspace::OnRun() {
// Make joints
for (auto it = this->GetDescendantsStart(); it != this->GetDescendantsEnd(); it++) { for (auto it = this->GetDescendantsStart(); it != this->GetDescendantsEnd(); it++) {
std::shared_ptr<Instance> obj = *it; if (!it->IsA<BasePart>()) continue;
if (!obj->IsA<Part>()) continue; std::shared_ptr<BasePart> part = it->CastTo<BasePart>().expect();
std::shared_ptr<Part> part = obj->CastTo<Part>().expect();
part->MakeJoints(); part->MakeJoints();
} }
@ -105,7 +110,7 @@ void Workspace::InitService() {
} }
} }
void Workspace::updatePartPhysics(std::shared_ptr<Part> part) { void Workspace::updatePartPhysics(std::shared_ptr<BasePart> part) {
rp::Transform transform = part->cframe; rp::Transform transform = part->cframe;
if (!part->rigidBody) { if (!part->rigidBody) {
part->rigidBody = physicsWorld->createRigidBody(transform); part->rigidBody = physicsWorld->createRigidBody(transform);
@ -113,18 +118,7 @@ void Workspace::updatePartPhysics(std::shared_ptr<Part> part) {
part->rigidBody->setTransform(transform); part->rigidBody->setTransform(transform);
} }
rp::BoxShape* shape = physicsCommon->createBoxShape(glmToRp(part->size * glm::vec3(0.5f))); part->updateCollider(physicsCommon);
// Recreate the rigidbody if the shape changes
if (part->rigidBody->getNbColliders() > 0
&& dynamic_cast<rp::BoxShape*>(part->rigidBody->getCollider(0)->getCollisionShape())->getHalfExtents() != shape->getHalfExtents()) {
// TODO: This causes Touched to get called twice. Fix this.
part->rigidBody->removeCollider(part->rigidBody->getCollider(0));
part->rigidBody->addCollider(shape, rp::Transform());
}
if (part->rigidBody->getNbColliders() == 0)
part->rigidBody->addCollider(shape, rp::Transform());
part->rigidBody->setType(part->anchored ? rp::BodyType::STATIC : rp::BodyType::DYNAMIC); part->rigidBody->setType(part->anchored ? rp::BodyType::STATIC : rp::BodyType::DYNAMIC);
part->rigidBody->getCollider(0)->setCollisionCategoryBits(0b11); part->rigidBody->getCollider(0)->setCollisionCategoryBits(0b11);
@ -162,7 +156,7 @@ void Workspace::ProcessContactEvents() {
contactQueueLock.unlock(); contactQueueLock.unlock();
} }
void Workspace::SyncPartPhysics(std::shared_ptr<Part> part) { void Workspace::SyncPartPhysics(std::shared_ptr<BasePart> part) {
if (globalPhysicsLock.try_lock()) { if (globalPhysicsLock.try_lock()) {
updatePartPhysics(part); updatePartPhysics(part);
globalPhysicsLock.unlock(); globalPhysicsLock.unlock();
@ -192,7 +186,7 @@ void Workspace::PhysicsStep(float deltaTime) {
queueLock.unlock(); queueLock.unlock();
// TODO: Add list of tracked parts in workspace based on their ancestry using inWorkspace property of Instance // TODO: Add list of tracked parts in workspace based on their ancestry using inWorkspace property of Instance
for (std::shared_ptr<Part> part : simulatedBodies) { for (std::shared_ptr<BasePart> part : simulatedBodies) {
// If the part's body is dirty, update it now instead // If the part's body is dirty, update it now instead
if (part->rigidBodyDirty) { if (part->rigidBodyDirty) {
updatePartPhysics(part); updatePartPhysics(part);
@ -261,7 +255,7 @@ class NearestRayHit : public rp::RaycastCallback {
return 1; return 1;
} }
std::shared_ptr<Part> part = partFromBody(raycastInfo.body); std::shared_ptr<BasePart> part = partFromBody(raycastInfo.body);
FilterResult result = filter.value()(part); FilterResult result = filter.value()(part);
if (result == FilterResult::BLOCK) { if (result == FilterResult::BLOCK) {
nearestHit = std::nullopt; nearestHit = std::nullopt;
@ -305,14 +299,14 @@ rp::Joint* Workspace::CreateJoint(const rp::JointInfo& jointInfo) {
return joint; return joint;
} }
void Workspace::AddBody(std::shared_ptr<Part> part) { void Workspace::AddBody(std::shared_ptr<BasePart> part) {
queueLock.lock(); queueLock.lock();
bodyQueue.push_back({part, QueueItem::QUEUEITEM_ADD}); bodyQueue.push_back({part, QueueItem::QUEUEITEM_ADD});
part->rigidBodyDirty = true; part->rigidBodyDirty = true;
queueLock.unlock(); queueLock.unlock();
} }
void Workspace::RemoveBody(std::shared_ptr<Part> part) { void Workspace::RemoveBody(std::shared_ptr<BasePart> part) {
queueLock.lock(); queueLock.lock();
bodyQueue.push_back({part, QueueItem::QUEUEITEM_REMOVE}); bodyQueue.push_back({part, QueueItem::QUEUEITEM_REMOVE});
queueLock.unlock(); queueLock.unlock();

View file

@ -32,7 +32,7 @@ enum FilterResult {
PASS, // The object is transparent, ignore it PASS, // The object is transparent, ignore it
}; };
class Part; class BasePart;
class Snap; class Snap;
class Weld; class Weld;
class Rotate; class Rotate;
@ -40,13 +40,13 @@ class RotateV;
#ifndef __SIMULATION_TICKET #ifndef __SIMULATION_TICKET
#define __SIMULATION_TICKET #define __SIMULATION_TICKET
typedef std::list<std::shared_ptr<Part>>::iterator SimulationTicket; typedef std::list<std::shared_ptr<BasePart>>::iterator SimulationTicket;
#endif #endif
typedef std::function<FilterResult(std::shared_ptr<Part>)> RaycastFilter; typedef std::function<FilterResult(std::shared_ptr<BasePart>)> RaycastFilter;
struct QueueItem { struct QueueItem {
std::shared_ptr<Part> part; std::shared_ptr<BasePart> part;
enum { enum {
QUEUEITEM_ADD, QUEUEITEM_ADD,
QUEUEITEM_REMOVE, QUEUEITEM_REMOVE,
@ -54,8 +54,8 @@ struct QueueItem {
}; };
struct ContactItem { struct ContactItem {
std::shared_ptr<Part> part0; std::shared_ptr<BasePart> part0;
std::shared_ptr<Part> part1; std::shared_ptr<BasePart> part1;
enum { enum {
CONTACTITEM_TOUCHED, CONTACTITEM_TOUCHED,
CONTACTITEM_TOUCHENDED, CONTACTITEM_TOUCHENDED,
@ -78,7 +78,7 @@ class DEF_INST_SERVICE_(explorer_icon="workspace") Workspace : public Service {
friend PhysicsEventListener; friend PhysicsEventListener;
std::list<std::shared_ptr<Part>> simulatedBodies; std::list<std::shared_ptr<BasePart>> simulatedBodies;
std::list<QueueItem> bodyQueue; std::list<QueueItem> bodyQueue;
std::queue<ContactItem> contactQueue; std::queue<ContactItem> contactQueue;
std::mutex contactQueueLock; std::mutex contactQueueLock;
@ -86,9 +86,10 @@ class DEF_INST_SERVICE_(explorer_icon="workspace") Workspace : public Service {
static rp::PhysicsCommon* physicsCommon; static rp::PhysicsCommon* physicsCommon;
PhysicsEventListener physicsEventListener; PhysicsEventListener physicsEventListener;
void updatePartPhysics(std::shared_ptr<Part> part); void updatePartPhysics(std::shared_ptr<BasePart> part);
protected: protected:
void InitService() override; void InitService() override;
void OnRun() override;
bool initialized = false; bool initialized = false;
public: public:
@ -103,10 +104,10 @@ public:
// static inline std::shared_ptr<Workspace> New() { return std::make_shared<Workspace>(); }; // static inline std::shared_ptr<Workspace> New() { return std::make_shared<Workspace>(); };
static inline std::shared_ptr<Instance> Create() { return std::make_shared<Workspace>(); }; static inline std::shared_ptr<Instance> Create() { return std::make_shared<Workspace>(); };
void AddBody(std::shared_ptr<Part> part); void AddBody(std::shared_ptr<BasePart> part);
void RemoveBody(std::shared_ptr<Part> part); void RemoveBody(std::shared_ptr<BasePart> part);
void DestroyRigidBody(rp::RigidBody* rigidBody); void DestroyRigidBody(rp::RigidBody* rigidBody);
void SyncPartPhysics(std::shared_ptr<Part> part); void SyncPartPhysics(std::shared_ptr<BasePart> part);
rp::Joint* CreateJoint(const rp::JointInfo& jointInfo); rp::Joint* CreateJoint(const rp::JointInfo& jointInfo);
void DestroyJoint(rp::Joint* joint); void DestroyJoint(rp::Joint* joint);

View file

@ -5,13 +5,13 @@
#include "datatypes/vector.h" #include "datatypes/vector.h"
#include "math_helper.h" #include "math_helper.h"
#include "objects/base/instance.h" #include "objects/base/instance.h"
#include "objects/part.h" #include "objects/part/part.h"
#include "objects/service/selection.h" #include "objects/service/selection.h"
#include <glm/common.hpp> #include <glm/common.hpp>
#include <memory> #include <memory>
#include <vector> #include <vector>
PartAssembly::PartAssembly(std::vector<std::shared_ptr<Part>> parts, bool worldMode) : parts(parts) { PartAssembly::PartAssembly(std::vector<std::shared_ptr<BasePart>> parts, bool worldMode) : parts(parts) {
if (parts.size() == 0) return; if (parts.size() == 0) return;
if (parts.size() == 1 && !worldMode) { if (parts.size() == 1 && !worldMode) {
_assemblyOrigin = parts[0]->cframe; _assemblyOrigin = parts[0]->cframe;
@ -36,19 +36,19 @@ PartAssembly::PartAssembly(std::vector<std::shared_ptr<Part>> parts, bool worldM
} }
PartAssembly PartAssembly::FromSelection(std::vector<std::shared_ptr<Instance>> newSelection) { PartAssembly PartAssembly::FromSelection(std::vector<std::shared_ptr<Instance>> newSelection) {
std::vector<std::shared_ptr<Part>> selection; std::vector<std::shared_ptr<BasePart>> selection;
for (std::shared_ptr<Instance> obj : newSelection) { for (std::shared_ptr<Instance> obj : newSelection) {
if (!obj->IsA<PVInstance>()) continue; if (!obj->IsA<PVInstance>()) continue;
if (obj->IsA<Part>()) if (obj->IsA<BasePart>())
selection.push_back(obj->CastTo<Part>().expect()); selection.push_back(obj->CastTo<BasePart>().expect());
// Add object descendants // Add object descendants
for (DescendantsIterator it = obj->GetDescendantsStart(); it != obj->GetDescendantsEnd(); it++) { for (DescendantsIterator it = obj->GetDescendantsStart(); it != obj->GetDescendantsEnd(); it++) {
if (!(*it)->IsA<Part>()) continue; if (!(*it)->IsA<BasePart>()) continue;
selection.push_back((*it)->CastTo<Part>().expect()); selection.push_back((*it)->CastTo<BasePart>().expect());
} }
} }
@ -90,7 +90,7 @@ void PartAssembly::TransformBy(CFrame transform) {
} }
void PartAssembly::Scale(Vector3 newSize, bool scaleUp) { void PartAssembly::Scale(Vector3 newSize, bool scaleUp) {
if (parts.size() == 1) { if (parts.size() == 1 && (!parts[0]->IsA<Part>() || parts[0]->CastTo<Part>().expect()->shape != PartType::Ball)) {
parts[0]->size = newSize; parts[0]->size = newSize;
parts[0]->UpdateProperty("Size"); parts[0]->UpdateProperty("Size");
sendPropertyUpdatedSignal(parts[0], "Size", Variant(parts[0]->size)); sendPropertyUpdatedSignal(parts[0], "Size", Variant(parts[0]->size));

View file

@ -4,12 +4,12 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
class Part; class BasePart;
class Instance; class Instance;
class Selection; class Selection;
struct PartTransformState { struct PartTransformState {
std::shared_ptr<Part> part; std::shared_ptr<BasePart> part;
Vector3 size; Vector3 size;
CFrame cframe; CFrame cframe;
}; };
@ -19,9 +19,9 @@ class PartAssembly {
Vector3 _bounds; Vector3 _bounds;
Vector3 _size; Vector3 _size;
std::vector<std::shared_ptr<Part>> parts; std::vector<std::shared_ptr<BasePart>> parts;
public: public:
PartAssembly(std::vector<std::shared_ptr<Part>>, bool worldMode = false); PartAssembly(std::vector<std::shared_ptr<BasePart>>, bool worldMode = false);
static PartAssembly FromSelection(std::vector<std::shared_ptr<Instance>> selection); static PartAssembly FromSelection(std::vector<std::shared_ptr<Instance>> selection);
static PartAssembly FromSelection(std::shared_ptr<Selection> selection); static PartAssembly FromSelection(std::shared_ptr<Selection> selection);

View file

@ -7,7 +7,7 @@
#include <reactphysics3d/mathematics/Vector3.h> #include <reactphysics3d/mathematics/Vector3.h>
#include <reactphysics3d/mathematics/mathematics.h> #include <reactphysics3d/mathematics/mathematics.h>
#include <glm/ext.hpp> #include <glm/ext.hpp>
#include "objects/part.h" #include "objects/part/part.h"
namespace rp = reactphysics3d; namespace rp = reactphysics3d;
@ -32,8 +32,8 @@ inline glm::quat rpToGlm(rp::Quaternion quat) {
} }
// Make this std::optional // Make this std::optional
inline std::shared_ptr<Part> partFromBody(rp::Body* body) { inline std::shared_ptr<BasePart> partFromBody(rp::Body* body) {
Part* raw = reinterpret_cast<Part*>(body->getUserData()); BasePart* raw = reinterpret_cast<BasePart*>(body->getUserData());
std::shared_ptr<Part> shared = std::dynamic_pointer_cast<Part>(raw->shared_from_this()); std::shared_ptr<BasePart> shared = std::dynamic_pointer_cast<BasePart>(raw->shared_from_this());
return shared; return shared;
} }

File diff suppressed because it is too large Load diff

View file

@ -2,6 +2,7 @@
#include "mesh.h" #include "mesh.h"
extern Mesh* CUBE_MESH; extern Mesh* CUBE_MESH;
extern Mesh* WEDGE_MESH;
extern Mesh* SPHERE_MESH; extern Mesh* SPHERE_MESH;
extern Mesh* ARROW_MESH; extern Mesh* ARROW_MESH;
extern Mesh* OUTLINE_MESH; extern Mesh* OUTLINE_MESH;

View file

@ -18,10 +18,12 @@
#include "datatypes/cframe.h" #include "datatypes/cframe.h"
#include "datatypes/color3.h" #include "datatypes/color3.h"
#include "datatypes/vector.h" #include "datatypes/vector.h"
#include "enum/part.h"
#include "handles.h" #include "handles.h"
#include "math_helper.h" #include "math_helper.h"
#include "objects/hint.h" #include "objects/hint.h"
#include "objects/message.h" #include "objects/message.h"
#include "objects/part/wedgepart.h"
#include "objects/service/selection.h" #include "objects/service/selection.h"
#include "partassembly.h" #include "partassembly.h"
#include "rendering/font.h" #include "rendering/font.h"
@ -31,9 +33,9 @@
#include "shader.h" #include "shader.h"
#include "mesh.h" #include "mesh.h"
#include "defaultmeshes.h" #include "defaultmeshes.h"
#include "../camera.h" #include "camera.h"
#include "../common.h" #include "common.h"
#include "../objects/part.h" #include "objects/part/part.h"
#include "skybox.h" #include "skybox.h"
#include "enum/surface.h" #include "enum/surface.h"
#include "texture3d.h" #include "texture3d.h"
@ -76,6 +78,7 @@ void renderInit(int width, int height) {
glEnable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glEnable(GL_MULTISAMPLE); glEnable(GL_MULTISAMPLE);
glFrontFace(GL_CW);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
// glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -121,30 +124,57 @@ void renderInit(int width, int height) {
sansSerif = loadFont("LiberationSans-Regular.ttf"); sansSerif = loadFont("LiberationSans-Regular.ttf");
} }
static void renderPart(std::shared_ptr<BasePart> part) {
glm::mat4 model = part->cframe;
Vector3 size = part->GetEffectiveSize();
model = glm::scale(model, (glm::vec3)size);
shader->set("model", model);
shader->set("material", Material {
.diffuse = part->color,
.specular = glm::vec3(0.5f, 0.5f, 0.5f),
.shininess = 16.0f,
});
glm::mat3 normalMatrix = glm::mat3(glm::transpose(glm::inverse(model)));
shader->set("normalMatrix", normalMatrix);
shader->set("texScale", size);
shader->set("transparency", part->transparency);
shader->set("surfaces[" + std::to_string(NormalId::Right) + "]", (int)part->rightSurface);
shader->set("surfaces[" + std::to_string(NormalId::Top) + "]", (int)part->topSurface);
shader->set("surfaces[" + std::to_string(NormalId::Back) + "]", (int)part->backSurface);
shader->set("surfaces[" + std::to_string(NormalId::Left) + "]", (int)part->leftSurface);
shader->set("surfaces[" + std::to_string(NormalId::Bottom) + "]", (int)part->bottomSurface);
shader->set("surfaces[" + std::to_string(NormalId::Front) + "]", (int)part->frontSurface);
PartType shape = part->IsA<Part>() ? part->CastTo<Part>().expect()->shape : PartType::Block;
if (part->IsA<WedgePart>()) {
WEDGE_MESH->bind();
glDrawArrays(GL_TRIANGLES, 0, WEDGE_MESH->vertexCount);
} else if (shape == PartType::Ball) { // Part
SPHERE_MESH->bind();
glDrawArrays(GL_TRIANGLES, 0, SPHERE_MESH->vertexCount);
} else if (shape == PartType::Block) {
glFrontFace(GL_CW);
CUBE_MESH->bind();
glDrawArrays(GL_TRIANGLES, 0, CUBE_MESH->vertexCount);
}
}
void renderParts() { void renderParts() {
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glCullFace(GL_BACK); glCullFace(GL_BACK);
glFrontFace(GL_CW);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Use shader // Use shader
shader->use(); shader->use();
// shader->set("objectColor", glm::vec3(1.0f, 0.5f, 0.31f));
// shader->set("lightColor", glm::vec3(1.0f, 1.0f, 1.0f));
// view/projection transformations // view/projection transformations
glm::mat4 projection = glm::perspective(glm::radians(45.f), (float)viewportWidth / (float)viewportHeight, 0.1f, 1000.0f); glm::mat4 projection = glm::perspective(glm::radians(45.f), (float)viewportWidth / (float)viewportHeight, 0.1f, 1000.0f);
glm::mat4 view = camera.getLookAt(); glm::mat4 view = camera.getLookAt();
shader->set("projection", projection); shader->set("projection", projection);
shader->set("view", view); shader->set("view", view);
// shader->set("material", Material {
// // .ambient = glm::vec3(1.0f, 0.5f, 0.31f),
// .diffuse = glm::vec3(0.639216f, 0.635294f, 0.647059f),
// .specular = glm::vec3(0.5f, 0.5f, 0.5f),
// .shininess = 16.0f,
// });
shader->set("sunLight", DirLight { shader->set("sunLight", DirLight {
.direction = glm::vec3(-0.2f, -1.0f, -0.3f), .direction = glm::vec3(-0.2f, -1.0f, -0.3f),
.ambient = glm::vec3(0.2f, 0.2f, 0.2f), .ambient = glm::vec3(0.2f, 0.2f, 0.2f),
@ -152,15 +182,6 @@ void renderParts() {
.specular = glm::vec3(1.0f, 1.0f, 1.0f), .specular = glm::vec3(1.0f, 1.0f, 1.0f),
}); });
shader->set("numPointLights", 0); shader->set("numPointLights", 0);
// shader->set("pointLights[0]", PointLight {
// .position = lightPos,
// .ambient = glm::vec3(0.4f, 0.4f, 0.4f),
// .diffuse = glm::vec3(1.0f, 1.0f, 1.0f),
// .specular = glm::vec3(1.0f, 1.0f, 1.0f),
// .constant = 1.0,
// .linear = 0.9,
// .quadratic = 0.32,
// });
studsTexture->activate(0); studsTexture->activate(0);
shader->set("studs", 0); shader->set("studs", 0);
@ -170,68 +191,24 @@ void renderParts() {
shader->set("viewPos", camera.cameraPos); shader->set("viewPos", camera.cameraPos);
// Sort by nearest // Sort by nearest
std::map<float, std::shared_ptr<Part>> sorted; std::map<float, std::shared_ptr<BasePart>> sorted;
for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) { for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) {
std::shared_ptr<Instance> inst = *it; if (!it->IsA<BasePart>()) continue;
if (inst->GetClass()->className != "Part") continue; std::shared_ptr<BasePart> part = std::dynamic_pointer_cast<BasePart>(*it);
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst);
if (part->transparency > 0.00001) { if (part->transparency > 0.00001) {
float distance = glm::length(glm::vec3(Vector3(camera.cameraPos) - part->position())); float distance = glm::length(glm::vec3(Vector3(camera.cameraPos) - part->position()));
sorted[distance] = part; sorted[distance] = part;
} else { } else {
glm::mat4 model = part->cframe; renderPart(part);
// if (part->name == "camera") model = camera.getLookAt();
model = glm::scale(model, (glm::vec3)part->size);
shader->set("model", model);
shader->set("material", Material {
.diffuse = part->color,
.specular = glm::vec3(0.5f, 0.5f, 0.5f),
.shininess = 16.0f,
});
glm::mat3 normalMatrix = glm::mat3(glm::transpose(glm::inverse(model)));
shader->set("normalMatrix", normalMatrix);
shader->set("texScale", part->size);
shader->set("transparency", part->transparency);
shader->set("surfaces[" + std::to_string(NormalId::Right) + "]", (int)part->rightSurface);
shader->set("surfaces[" + std::to_string(NormalId::Top) + "]", (int)part->topSurface);
shader->set("surfaces[" + std::to_string(NormalId::Back) + "]", (int)part->backSurface);
shader->set("surfaces[" + std::to_string(NormalId::Left) + "]", (int)part->leftSurface);
shader->set("surfaces[" + std::to_string(NormalId::Bottom) + "]", (int)part->bottomSurface);
shader->set("surfaces[" + std::to_string(NormalId::Front) + "]", (int)part->frontSurface);
CUBE_MESH->bind();
glDrawArrays(GL_TRIANGLES, 0, CUBE_MESH->vertexCount);
} }
} }
// TODO: Same as todo in src/physics/simulation.cpp // TODO: Same as todo in src/physics/simulation.cpp
// According to LearnOpenGL, std::map automatically sorts its contents. // According to LearnOpenGL, std::map automatically sorts its contents.
for (std::map<float, std::shared_ptr<Part>>::reverse_iterator it = sorted.rbegin(); it != sorted.rend(); it++) { for (std::map<float, std::shared_ptr<BasePart>>::reverse_iterator it = sorted.rbegin(); it != sorted.rend(); it++) {
std::shared_ptr<Part> part = it->second; std::shared_ptr<BasePart> part = it->second;
glm::mat4 model = part->cframe; renderPart(part);
// if (part->name == "camera") model = camera.getLookAt();
model = glm::scale(model, (glm::vec3)part->size);
shader->set("model", model);
shader->set("material", Material {
.diffuse = part->color,
.specular = glm::vec3(0.5f, 0.5f, 0.5f),
.shininess = 16.0f,
});
glm::mat3 normalMatrix = glm::mat3(glm::transpose(glm::inverse(model)));
shader->set("normalMatrix", normalMatrix);
shader->set("texScale", part->size);
shader->set("transparency", part->transparency);
shader->set("surfaces[" + std::to_string(NormalId::Right) + "]", (int)part->rightSurface);
shader->set("surfaces[" + std::to_string(NormalId::Top) + "]", (int)part->topSurface);
shader->set("surfaces[" + std::to_string(NormalId::Back) + "]", (int)part->backSurface);
shader->set("surfaces[" + std::to_string(NormalId::Left) + "]", (int)part->leftSurface);
shader->set("surfaces[" + std::to_string(NormalId::Bottom) + "]", (int)part->bottomSurface);
shader->set("surfaces[" + std::to_string(NormalId::Front) + "]", (int)part->frontSurface);
CUBE_MESH->bind();
glDrawArrays(GL_TRIANGLES, 0, CUBE_MESH->vertexCount);
} }
} }
@ -248,7 +225,6 @@ void renderSurfaceExtras() {
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glCullFace(GL_BACK); glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -268,7 +244,7 @@ void renderSurfaceExtras() {
for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) { for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) {
std::shared_ptr<Instance> inst = *it; std::shared_ptr<Instance> inst = *it;
if (!inst->IsA("Part")) continue; if (!inst->IsA("Part")) continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst); std::shared_ptr<BasePart> part = std::dynamic_pointer_cast<BasePart>(inst);
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
NormalId face = (NormalId)i; NormalId face = (NormalId)i;
SurfaceType type = part->GetSurfaceFromFace(face); SurfaceType type = part->GetSurfaceFromFace(face);
@ -289,7 +265,6 @@ void renderSurfaceExtras() {
void renderSkyBox() { void renderSkyBox() {
glDepthMask(GL_FALSE); glDepthMask(GL_FALSE);
glCullFace(GL_FRONT); glCullFace(GL_FRONT);
glFrontFace(GL_CW);
skyboxShader->use(); skyboxShader->use();
@ -316,7 +291,6 @@ void renderHandles() {
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
glCullFace(GL_BACK); glCullFace(GL_BACK);
glFrontFace(GL_CCW); // This is right... Probably.....
// Use shader // Use shader
handleShader->use(); handleShader->use();
@ -396,7 +370,7 @@ void renderAABB() {
// Sort by nearest // Sort by nearest
for (std::shared_ptr<Instance> inst : gWorkspace()->GetChildren()) { for (std::shared_ptr<Instance> inst : gWorkspace()->GetChildren()) {
if (inst->GetClass()->className != "Part") continue; if (inst->GetClass()->className != "Part") continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst); std::shared_ptr<BasePart> part = std::dynamic_pointer_cast<BasePart>(inst);
glm::mat4 model = CFrame::IDENTITY + part->cframe.Position(); glm::mat4 model = CFrame::IDENTITY + part->cframe.Position();
printf("AABB is supposedly (%f, %f, %f)\n", part->GetAABB().X(), part->GetAABB().Y(), part->GetAABB().Z()); printf("AABB is supposedly (%f, %f, %f)\n", part->GetAABB().X(), part->GetAABB().Y(), part->GetAABB().Z());
model = glm::scale(model, (glm::vec3)part->GetAABB()); model = glm::scale(model, (glm::vec3)part->GetAABB());
@ -436,7 +410,7 @@ void renderWireframe() {
// Sort by nearest // Sort by nearest
for (std::shared_ptr<Instance> inst : gWorkspace()->GetChildren()) { for (std::shared_ptr<Instance> inst : gWorkspace()->GetChildren()) {
if (inst->GetClass()->className != "Part") continue; if (inst->GetClass()->className != "Part") continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst); std::shared_ptr<BasePart> part = std::dynamic_pointer_cast<BasePart>(inst);
glm::mat4 model = part->cframe; glm::mat4 model = part->cframe;
model = glm::scale(model, (glm::vec3)part->size); model = glm::scale(model, (glm::vec3)part->size);
wireframeShader->set("model", model); wireframeShader->set("model", model);
@ -454,7 +428,6 @@ void renderOutlines() {
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glCullFace(GL_BACK); glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -478,8 +451,8 @@ void renderOutlines() {
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>(); std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
for (auto inst : selection->Get()) { for (auto inst : selection->Get()) {
if (inst->GetClass() != &Part::TYPE) continue; if (inst->GetClass() != &BasePart::TYPE) continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst); std::shared_ptr<BasePart> part = std::dynamic_pointer_cast<BasePart>(inst);
if (first) if (first)
min = part->position(), max = part->position(); min = part->position(), max = part->position();
@ -518,7 +491,6 @@ void renderSelectionAssembly() {
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
glCullFace(GL_BACK); glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_BLEND); glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -606,7 +578,6 @@ std::vector<std::pair<CFrame, Color3>> DEBUG_CFRAMES;
void renderDebugCFrames() { void renderDebugCFrames() {
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
glCullFace(GL_BACK); glCullFace(GL_BACK);
glFrontFace(GL_CCW); // This is right... Probably.....
// Use shader // Use shader
handleShader->use(); handleShader->use();

5
core/src/version.cpp.in Normal file
View file

@ -0,0 +1,5 @@
#include "version.h"
const char* BUILD_COMMIT_HASH = "@GIT_COMMIT_HASH@"; // Commit hash of the current build
const char* BUILD_VERSION = "@GIT_VERSION@"; // Short form of the build version v1.2.3
const char* BUILD_VERSION_LONG = "@GIT_VERSION_LONG@"; // Long form of the build version v1.2.3-12-g1234567

8
core/src/version.h Normal file
View file

@ -0,0 +1,8 @@
#pragma once
// Allows files to read the version of the current build from git
// https://jonathanhamberg.com/post/cmake-embedding-git-hash/
extern const char* BUILD_COMMIT_HASH; // Commit hash of the current build
extern const char* BUILD_VERSION; // Short form of the build version v1.2.3
extern const char* BUILD_VERSION_LONG; // Long form of the build version v1.2.3-12-g1234567

View file

@ -105,7 +105,7 @@ However, Autogen cannot tell where this class came from to automatically include
block via `__AUTOGEN_EXTRA_INCLUDES__`: block via `__AUTOGEN_EXTRA_INCLUDES__`:
#ifdef __AUTOGEN_EXTRA_INCLUDES__ #ifdef __AUTOGEN_EXTRA_INCLUDES__
#include "objects/part.h" #include "objects/part/part.h"
#endif #endif
class Part; class Part;

View file

@ -59,7 +59,7 @@ void MainGLWidget::resizeGL(int w, int h) {
glm::vec2 firstPoint; glm::vec2 firstPoint;
glm::vec2 secondPoint; glm::vec2 secondPoint;
extern std::weak_ptr<Part> draggingObject; extern std::weak_ptr<BasePart> draggingObject;
extern std::optional<HandleFace> draggingHandle; extern std::optional<HandleFace> draggingHandle;
extern Shader* shader; extern Shader* shader;
void MainGLWidget::paintGL() { void MainGLWidget::paintGL() {
@ -125,7 +125,7 @@ std::vector<PartTransformState> initialTransforms;
bool tryMouseContextMenu = false; bool tryMouseContextMenu = false;
bool isMouseDragging = false; bool isMouseDragging = false;
std::weak_ptr<Part> draggingObject; std::weak_ptr<BasePart> draggingObject;
std::optional<HandleFace> draggingHandle; std::optional<HandleFace> draggingHandle;
Vector3 initialHitPos; Vector3 initialHitPos;
Vector3 initialHitNormal; Vector3 initialHitNormal;
@ -396,7 +396,7 @@ void MainGLWidget::mousePressEvent(QMouseEvent* evt) {
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>(); std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
std::optional<const RaycastResult> rayHit = gWorkspace()->CastRayNearest(camera.cameraPos, pointDir, 50000); std::optional<const RaycastResult> rayHit = gWorkspace()->CastRayNearest(camera.cameraPos, pointDir, 50000);
if (!rayHit || !partFromBody(rayHit->body)) { selection->Set({}); return; } if (!rayHit || !partFromBody(rayHit->body)) { selection->Set({}); return; }
std::shared_ptr<Part> part = partFromBody(rayHit->body); std::shared_ptr<BasePart> part = partFromBody(rayHit->body);
if (part->locked) { selection->Set({}); return; } if (part->locked) { selection->Set({}); return; }
std::shared_ptr<PVInstance> selObject = part; std::shared_ptr<PVInstance> selObject = part;

View file

@ -1,7 +1,7 @@
#ifndef MAINGLWIDGET_H #ifndef MAINGLWIDGET_H
#define MAINGLWIDGET_H #define MAINGLWIDGET_H
#include "objects/part.h" #include "objects/part/part.h"
#include "qevent.h" #include "qevent.h"
#include <QOpenGLWidget> #include <QOpenGLWidget>
#include <QWidget> #include <QWidget>
@ -15,7 +15,7 @@ class MainGLWidget : public QOpenGLWidget {
public: public:
MainGLWidget(QWidget *parent = nullptr); MainGLWidget(QWidget *parent = nullptr);
void updateCycle(); void updateCycle();
std::shared_ptr<Part> lastPart; std::shared_ptr<BasePart> lastPart;
void buildContextMenu(); void buildContextMenu();
protected: protected:

View file

@ -130,7 +130,7 @@ void PlaceDocument::closeEvent(QCloseEvent *closeEvent) {
closeEvent->ignore(); closeEvent->ignore();
} }
std::shared_ptr<Part> shit; std::shared_ptr<BasePart> shit;
void PlaceDocument::timerEvent(QTimerEvent* evt) { void PlaceDocument::timerEvent(QTimerEvent* evt) {
if (evt->timerId() != timer.timerId()) { if (evt->timerId() != timer.timerId()) {
QWidget::timerEvent(evt); QWidget::timerEvent(evt);
@ -148,7 +148,7 @@ void PlaceDocument::init() {
timer.start(33, this); timer.start(33, this);
placeWidget->buildContextMenu(); placeWidget->buildContextMenu();
std::shared_ptr<Part> lastPart; std::shared_ptr<BasePart> lastPart;
// Baseplate // Baseplate
gWorkspace()->AddChild(lastPart = Part::New({ gWorkspace()->AddChild(lastPart = Part::New({
.position = glm::vec3(0, -5, 0), .position = glm::vec3(0, -5, 0),

View file

@ -58,7 +58,7 @@ for line in file:
if line.startswith('f '): if line.startswith('f '):
verts = line.split(' ')[1:] verts = line.split(' ')[1:]
for vert in verts: for vert in reversed(verts):
coords, uv, normal = vert.split('/') coords, uv, normal = vert.split('/')
coords, uv, normal = int(coords), int(uv), int(normal) coords, uv, normal = int(coords), int(uv), int(normal)
coords, uv, normal = vert_coords[coords-1], vert_uvs[uv-1], vert_norms[normal-1] coords, uv, normal = vert_coords[coords-1], vert_uvs[uv-1], vert_norms[normal-1]