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

View file

@ -1,6 +1,6 @@
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "objects/part.h"
#include "objects/part/part.h"
#include "rendering/renderer.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 resizeCallback(GLFWwindow* window, int width, int height);
std::shared_ptr<Part> lastPart;
std::shared_ptr<BasePart> lastPart;
int main() {
Logger::init();
@ -58,7 +58,7 @@ int main() {
for (std::shared_ptr<Instance> inst : gWorkspace()->GetChildren()) {
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);
}

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)
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")
# 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}")
endforeach()
### /Autogen
# Add version info into the build
include(gitversion)
add_custom_target(autogen_build ALL
DEPENDS ${AUTOGEN_OUTS}
)
file(GLOB_RECURSE SOURCES "src/*.cpp" "src/*.h")
list(APPEND SOURCES ${AUTOGEN_OUTS})
list(APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/src/version.cpp)
add_library(openblocks STATIC ${SOURCES})
set_target_properties(openblocks PROPERTIES OUTPUT_NAME "openblocks")
target_link_directories(openblocks PUBLIC ${LUAJIT_LIBRARY_DIRS})

View file

@ -6,6 +6,7 @@
#include <iomanip>
#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(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:
DEF_DATA_CTOR Color3(float r, float g, float b);
Color3();
Color3(const glm::vec3&);
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::PhysicsWorld* world = common.createPhysicsWorld();
std::shared_ptr<Part> getHandleAdornee() {
std::shared_ptr<BasePart> getHandleAdornee() {
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
for (std::weak_ptr<Instance> inst : selection->Get()) {
if (!inst.expired() && inst.lock()->IsA<Part>())
return inst.lock()->CastTo<Part>().expect();
if (!inst.expired() && inst.lock()->IsA<BasePart>())
return inst.lock()->CastTo<BasePart>().expect();
}
return {};
@ -82,8 +82,8 @@ static int getAABBOfSelection(glm::vec3& pos, glm::vec3& size, glm::vec3& min, g
int count = 0;
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
for (std::weak_ptr<Instance> inst : selection->Get()) {
if (inst.expired() || !inst.lock()->IsA<Part>()) continue;
std::shared_ptr<Part> part = inst.lock()->CastTo<Part>().expect();
if (inst.expired() || !inst.lock()->IsA<BasePart>()) continue;
std::shared_ptr<BasePart> part = inst.lock()->CastTo<BasePart>().expect();
if (count == 0)
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;
}
static std::shared_ptr<Part> getFirstSelectedPart() {
static std::shared_ptr<BasePart> getFirstSelectedPart() {
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
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 {};

View file

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

View file

@ -4,7 +4,7 @@
#include "datatypes/ref.h"
#include "objects/datamodel.h"
#include "objects/service/jointsservice.h"
#include "objects/part.h"
#include "objects/part/part.h"
#include "objects/service/workspace.h"
#include <memory>
#include <reactphysics3d/constraint/FixedJoint.h>
@ -54,6 +54,6 @@ void JointInstance::onUpdated(std::string property) {
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();
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,5 +1,5 @@
#include "part.h"
#include "base/instance.h"
#include "basepart.h"
#include "objects/base/instance.h"
#include "common.h"
#include "datatypes/base.h"
#include "datatypes/cframe.h"
@ -19,15 +19,14 @@
#include <memory>
#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),
size(params.size), color(params.color), anchored(params.anchored), locked(params.locked) {
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) {
}
Part::~Part() {
BasePart::~BasePart() {
// This relies on physicsCommon still existing. Be very careful.
if (this->rigidBody && workspace()) {
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)
this->rigidBody->setIsActive(workspace().has_value());
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
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
}
void Part::OnWorkspaceAdded(std::optional<std::shared_ptr<Workspace>> oldWorkspace, std::shared_ptr<Workspace> newWorkspace) {
newWorkspace->AddBody(shared<Part>());
void BasePart::OnWorkspaceAdded(std::optional<std::shared_ptr<Workspace>> oldWorkspace, std::shared_ptr<Workspace> newWorkspace) {
newWorkspace->AddBody(shared<BasePart>());
}
void Part::OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace) {
void BasePart::OnWorkspaceRemoved(std::shared_ptr<Workspace> oldWorkspace) {
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
if (property != "Velocity")
velocity = Vector3::ZERO;
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
if (property != "Anchored")
@ -88,7 +87,7 @@ static Vector3 verts[8] {
{1, 1, 1},
};
Vector3 Part::GetAABB() {
Vector3 BasePart::GetAABB() {
Vector3 min(0, 0, 0);
Vector3 max(0, 0, 0);
for (Vector3 vert : verts) {
@ -99,7 +98,7 @@ Vector3 Part::GetAABB() {
return (min - max).Abs() / 2;
}
void Part::BreakJoints() {
void BasePart::BreakJoints() {
for (std::weak_ptr<JointInstance> joint : primaryJoints) {
if (joint.expired()) continue;
joint.lock()->Destroy();
@ -120,7 +119,7 @@ static Vector3 FACES[6] = {
{0, 0, -1},
};
SurfaceType Part::surfaceFromFace(NormalId face) {
SurfaceType BasePart::surfaceFromFace(NormalId face) {
switch (face) {
case Top: return topSurface;
case Bottom: return bottomSurface;
@ -132,7 +131,7 @@ SurfaceType Part::surfaceFromFace(NormalId face) {
return SurfaceType::Smooth; // Unreachable
}
float Part::GetSurfaceParamA(Vector3 face) {
float BasePart::GetSurfaceParamA(Vector3 face) {
switch (faceFromNormal(face)) {
case Top: return topParamA;
case Bottom: return bottomParamA;
@ -144,7 +143,7 @@ float Part::GetSurfaceParamA(Vector3 face) {
return 0; // Unreachable
}
float Part::GetSurfaceParamB(Vector3 face) {
float BasePart::GetSurfaceParamB(Vector3 face) {
switch (faceFromNormal(face)) {
case Top: return topParamB;
case Bottom: return bottomParamB;
@ -156,14 +155,18 @@ float Part::GetSurfaceParamB(Vector3 face) {
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
return checkJointContinuityUp(otherPart) && checkJointContinuityDown(otherPart);
}
bool Part::checkJointContinuityDown(std::shared_ptr<Part> otherPart) {
if (shared<Part>() == otherPart) return false;
bool BasePart::checkJointContinuityDown(std::shared_ptr<BasePart> otherPart) {
if (shared<BasePart>() == otherPart) return false;
for (auto joint : primaryJoints) {
if (joint.expired() || joint.lock()->part1.expired()) continue;
if (!joint.lock()->part1.lock()->checkJointContinuityDown(otherPart))
@ -172,8 +175,8 @@ bool Part::checkJointContinuityDown(std::shared_ptr<Part> otherPart) {
return true;
}
bool Part::checkJointContinuityUp(std::shared_ptr<Part> otherPart) {
if (shared<Part>() == otherPart) return false;
bool BasePart::checkJointContinuityUp(std::shared_ptr<BasePart> otherPart) {
if (shared<BasePart>() == otherPart) return false;
for (auto joint : secondaryJoints) {
if (joint.expired() || joint.lock()->part0.expired()) continue;
if (!joint.lock()->part0.lock()->checkJointContinuityUp(otherPart))
@ -182,7 +185,7 @@ bool Part::checkJointContinuityUp(std::shared_ptr<Part> otherPart) {
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 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;
}
void Part::MakeJoints() {
void BasePart::MakeJoints() {
// Algorithm: Find nearby parts
// Make sure parts are not dependant on each other (via primary/secondaryJoints)
// 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++) {
std::shared_ptr<Instance> obj = *it;
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
std::shared_ptr<Part> otherPart = obj->CastTo<Part>().expect();
if (!obj->IsA<BasePart>()) continue;
std::shared_ptr<BasePart> otherPart = obj->CastTo<BasePart>().expect();
for (Vector3 myFace : FACES) {
Vector3 myWorldNormal = cframe.Rotation() * myFace;
@ -278,8 +281,8 @@ void Part::MakeJoints() {
auto joint_ = makeJointFromSurfaces(mySurface, otherSurface);
if (!joint_) continue;
std::shared_ptr<JointInstance> joint = joint_.value();
joint->part0 = shared<Part>();
joint->part1 = otherPart->shared<Part>();
joint->part0 = shared<BasePart>();
joint->part1 = otherPart->shared<BasePart>();
joint->c0 = contact0;
joint->c1 = contact1;
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()) {
for (auto it = primaryJoints.begin(); it != primaryJoints.end();) {
// 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();) {
// Clean expired refs
if (it->expired() || it->lock() == joint) {

View file

@ -12,9 +12,11 @@
#include "enum/surface.h"
#include <mutex>
#include <optional>
#include <reactphysics3d/body/RigidBody.h>
#include <reactphysics3d/engine/PhysicsCommon.h>
#include <reactphysics3d/reactphysics3d.h>
#include <vector>
#include "annotation.h"
#include "objects/annotation.h"
#include "objects/pvinstance.h"
namespace rp = reactphysics3d;
@ -34,11 +36,11 @@ class Workspace;
#ifndef __SIMULATION_TICKET
#define __SIMULATION_TICKET
class Part;
typedef std::list<std::shared_ptr<Part>>::iterator SimulationTicket;
class BasePart;
typedef std::list<std::shared_ptr<BasePart>>::iterator SimulationTicket;
#endif
class DEF_INST_(explorer_icon="part") Part : public PVInstance {
class DEF_INST_ABSTRACT_(explorer_icon="part") BasePart : public PVInstance {
AUTOGEN_PREAMBLE
protected:
// Joints where this part is Part0
@ -50,10 +52,10 @@ protected:
void untrackJoint(std::shared_ptr<JointInstance>);
SurfaceType surfaceFromFace(NormalId);
bool checkJointContinuity(std::shared_ptr<Part>);
bool checkJointContinuityUp(std::shared_ptr<Part>);
bool checkJointContinuityDown(std::shared_ptr<Part>);
bool checkSurfacesTouching(CFrame surfaceFrame, Vector3 size, Vector3 myFace, Vector3 otherFace, std::shared_ptr<Part> otherPart);
bool checkJointContinuity(std::shared_ptr<BasePart>);
bool checkJointContinuityUp(std::shared_ptr<BasePart>);
bool checkJointContinuityDown(std::shared_ptr<BasePart>);
bool checkSurfacesTouching(CFrame surfaceFrame, Vector3 size, Vector3 myFace, Vector3 otherFace, std::shared_ptr<BasePart> otherPart);
friend JointInstance;
friend Workspace;
@ -62,6 +64,11 @@ protected:
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 onUpdated(std::string);
virtual void updateCollider(rp::PhysicsCommon* common) = 0;
BasePart(const InstanceType*);
BasePart(const InstanceType*, PartConstructParams params);
public:
DEF_PROP_CATEGORY(DATA)
DEF_PROP_(on_update=onUpdated) Vector3 velocity;
@ -115,14 +122,9 @@ public:
inline SurfaceType GetSurfaceFromFace(NormalId face) { return surfaceFromFace(face); }
float GetSurfaceParamA(Vector3 face);
float GetSurfaceParamB(Vector3 face);
virtual Vector3 GetEffectiveSize();
Part();
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>(); };
~BasePart() override;
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 "logger.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/joint/jointinstance.h"
#include "objects/datamodel.h"
@ -39,8 +40,8 @@ void PhysicsEventListener::onContact(const rp::CollisionCallback::CallbackData&
continue;
ContactItem contact;
contact.part0 = reinterpret_cast<Part*>(pair.getBody1()->getUserData())->shared<Part>();
contact.part1 = reinterpret_cast<Part*>(pair.getBody2()->getUserData())->shared<Part>();
contact.part0 = reinterpret_cast<BasePart*>(pair.getBody1()->getUserData())->shared<BasePart>();
contact.part1 = reinterpret_cast<BasePart*>(pair.getBody2()->getUserData())->shared<BasePart>();
contact.action = type == reactphysics3d::CollisionCallback::ContactPair::EventType::ContactStart ? ContactItem::CONTACTITEM_TOUCHED : ContactItem::CONTACTITEM_TOUCHENDED;
workspace->contactQueue.push(contact);
@ -55,8 +56,8 @@ void PhysicsEventListener::onTrigger(const rp::OverlapCallback::CallbackData& da
auto type = pair.getEventType();
if (type == rp::OverlapCallback::OverlapPair::EventType::OverlapStay) continue;
auto part0 = reinterpret_cast<Part*>(pair.getBody1()->getUserData())->shared<Part>();
auto part1 = reinterpret_cast<Part*>(pair.getBody2()->getUserData())->shared<Part>();
auto part0 = reinterpret_cast<BasePart*>(pair.getBody1()->getUserData())->shared<BasePart>();
auto part1 = reinterpret_cast<BasePart*>(pair.getBody2()->getUserData())->shared<BasePart>();
if (type == reactphysics3d::OverlapCallback::OverlapPair::EventType::OverlapStart) {
part0->Touched->Fire({ (Variant)InstanceRef(part1) });
@ -82,11 +83,15 @@ void Workspace::InitService() {
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++) {
std::shared_ptr<Instance> obj = *it;
if (!obj->IsA<Part>()) continue;
std::shared_ptr<Part> part = obj->CastTo<Part>().expect();
if (!it->IsA<BasePart>()) continue;
std::shared_ptr<BasePart> part = it->CastTo<BasePart>().expect();
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;
if (!part->rigidBody) {
part->rigidBody = physicsWorld->createRigidBody(transform);
@ -113,18 +118,7 @@ void Workspace::updatePartPhysics(std::shared_ptr<Part> part) {
part->rigidBody->setTransform(transform);
}
rp::BoxShape* shape = physicsCommon->createBoxShape(glmToRp(part->size * glm::vec3(0.5f)));
// 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->updateCollider(physicsCommon);
part->rigidBody->setType(part->anchored ? rp::BodyType::STATIC : rp::BodyType::DYNAMIC);
part->rigidBody->getCollider(0)->setCollisionCategoryBits(0b11);
@ -162,7 +156,7 @@ void Workspace::ProcessContactEvents() {
contactQueueLock.unlock();
}
void Workspace::SyncPartPhysics(std::shared_ptr<Part> part) {
void Workspace::SyncPartPhysics(std::shared_ptr<BasePart> part) {
if (globalPhysicsLock.try_lock()) {
updatePartPhysics(part);
globalPhysicsLock.unlock();
@ -192,7 +186,7 @@ void Workspace::PhysicsStep(float deltaTime) {
queueLock.unlock();
// 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 (part->rigidBodyDirty) {
updatePartPhysics(part);
@ -261,7 +255,7 @@ class NearestRayHit : public rp::RaycastCallback {
return 1;
}
std::shared_ptr<Part> part = partFromBody(raycastInfo.body);
std::shared_ptr<BasePart> part = partFromBody(raycastInfo.body);
FilterResult result = filter.value()(part);
if (result == FilterResult::BLOCK) {
nearestHit = std::nullopt;
@ -305,14 +299,14 @@ rp::Joint* Workspace::CreateJoint(const rp::JointInfo& jointInfo) {
return joint;
}
void Workspace::AddBody(std::shared_ptr<Part> part) {
void Workspace::AddBody(std::shared_ptr<BasePart> part) {
queueLock.lock();
bodyQueue.push_back({part, QueueItem::QUEUEITEM_ADD});
part->rigidBodyDirty = true;
queueLock.unlock();
}
void Workspace::RemoveBody(std::shared_ptr<Part> part) {
void Workspace::RemoveBody(std::shared_ptr<BasePart> part) {
queueLock.lock();
bodyQueue.push_back({part, QueueItem::QUEUEITEM_REMOVE});
queueLock.unlock();

View file

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

View file

@ -5,13 +5,13 @@
#include "datatypes/vector.h"
#include "math_helper.h"
#include "objects/base/instance.h"
#include "objects/part.h"
#include "objects/part/part.h"
#include "objects/service/selection.h"
#include <glm/common.hpp>
#include <memory>
#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() == 1 && !worldMode) {
_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) {
std::vector<std::shared_ptr<Part>> selection;
std::vector<std::shared_ptr<BasePart>> selection;
for (std::shared_ptr<Instance> obj : newSelection) {
if (!obj->IsA<PVInstance>()) continue;
if (obj->IsA<Part>())
selection.push_back(obj->CastTo<Part>().expect());
if (obj->IsA<BasePart>())
selection.push_back(obj->CastTo<BasePart>().expect());
// Add object descendants
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) {
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]->UpdateProperty("Size");
sendPropertyUpdatedSignal(parts[0], "Size", Variant(parts[0]->size));

View file

@ -4,12 +4,12 @@
#include <memory>
#include <vector>
class Part;
class BasePart;
class Instance;
class Selection;
struct PartTransformState {
std::shared_ptr<Part> part;
std::shared_ptr<BasePart> part;
Vector3 size;
CFrame cframe;
};
@ -19,9 +19,9 @@ class PartAssembly {
Vector3 _bounds;
Vector3 _size;
std::vector<std::shared_ptr<Part>> parts;
std::vector<std::shared_ptr<BasePart>> parts;
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::shared_ptr<Selection> selection);

View file

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

File diff suppressed because it is too large Load diff

View file

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

View file

@ -18,10 +18,12 @@
#include "datatypes/cframe.h"
#include "datatypes/color3.h"
#include "datatypes/vector.h"
#include "enum/part.h"
#include "handles.h"
#include "math_helper.h"
#include "objects/hint.h"
#include "objects/message.h"
#include "objects/part/wedgepart.h"
#include "objects/service/selection.h"
#include "partassembly.h"
#include "rendering/font.h"
@ -31,9 +33,9 @@
#include "shader.h"
#include "mesh.h"
#include "defaultmeshes.h"
#include "../camera.h"
#include "../common.h"
#include "../objects/part.h"
#include "camera.h"
#include "common.h"
#include "objects/part/part.h"
#include "skybox.h"
#include "enum/surface.h"
#include "texture3d.h"
@ -76,6 +78,7 @@ void renderInit(int width, int height) {
glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glEnable(GL_MULTISAMPLE);
glFrontFace(GL_CW);
glBlendFunc(GL_ONE, 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");
}
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() {
glDepthMask(GL_TRUE);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CW);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Use shader
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
glm::mat4 projection = glm::perspective(glm::radians(45.f), (float)viewportWidth / (float)viewportHeight, 0.1f, 1000.0f);
glm::mat4 view = camera.getLookAt();
shader->set("projection", projection);
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 {
.direction = glm::vec3(-0.2f, -1.0f, -0.3f),
.ambient = glm::vec3(0.2f, 0.2f, 0.2f),
@ -152,15 +182,6 @@ void renderParts() {
.specular = glm::vec3(1.0f, 1.0f, 1.0f),
});
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);
shader->set("studs", 0);
@ -170,68 +191,24 @@ void renderParts() {
shader->set("viewPos", camera.cameraPos);
// 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++) {
std::shared_ptr<Instance> inst = *it;
if (inst->GetClass()->className != "Part") continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst);
if (!it->IsA<BasePart>()) continue;
std::shared_ptr<BasePart> part = std::dynamic_pointer_cast<BasePart>(*it);
if (part->transparency > 0.00001) {
float distance = glm::length(glm::vec3(Vector3(camera.cameraPos) - part->position()));
sorted[distance] = part;
} else {
glm::mat4 model = part->cframe;
// 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);
renderPart(part);
}
}
// TODO: Same as todo in src/physics/simulation.cpp
// 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++) {
std::shared_ptr<Part> part = it->second;
glm::mat4 model = part->cframe;
// 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);
for (std::map<float, std::shared_ptr<BasePart>>::reverse_iterator it = sorted.rbegin(); it != sorted.rend(); it++) {
std::shared_ptr<BasePart> part = it->second;
renderPart(part);
}
}
@ -248,7 +225,6 @@ void renderSurfaceExtras() {
glDepthMask(GL_TRUE);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -268,7 +244,7 @@ void renderSurfaceExtras() {
for (auto it = gWorkspace()->GetDescendantsStart(); it != gWorkspace()->GetDescendantsEnd(); it++) {
std::shared_ptr<Instance> inst = *it;
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++) {
NormalId face = (NormalId)i;
SurfaceType type = part->GetSurfaceFromFace(face);
@ -289,7 +265,6 @@ void renderSurfaceExtras() {
void renderSkyBox() {
glDepthMask(GL_FALSE);
glCullFace(GL_FRONT);
glFrontFace(GL_CW);
skyboxShader->use();
@ -316,7 +291,6 @@ void renderHandles() {
glDepthMask(GL_TRUE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW); // This is right... Probably.....
// Use shader
handleShader->use();
@ -396,7 +370,7 @@ void renderAABB() {
// Sort by nearest
for (std::shared_ptr<Instance> inst : gWorkspace()->GetChildren()) {
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();
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());
@ -436,7 +410,7 @@ void renderWireframe() {
// Sort by nearest
for (std::shared_ptr<Instance> inst : gWorkspace()->GetChildren()) {
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;
model = glm::scale(model, (glm::vec3)part->size);
wireframeShader->set("model", model);
@ -454,7 +428,6 @@ void renderOutlines() {
glDepthMask(GL_TRUE);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -478,8 +451,8 @@ void renderOutlines() {
std::shared_ptr<Selection> selection = gDataModel->GetService<Selection>();
for (auto inst : selection->Get()) {
if (inst->GetClass() != &Part::TYPE) continue;
std::shared_ptr<Part> part = std::dynamic_pointer_cast<Part>(inst);
if (inst->GetClass() != &BasePart::TYPE) continue;
std::shared_ptr<BasePart> part = std::dynamic_pointer_cast<BasePart>(inst);
if (first)
min = part->position(), max = part->position();
@ -518,7 +491,6 @@ void renderSelectionAssembly() {
glDepthMask(GL_TRUE);
glEnable(GL_CULL_FACE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@ -606,7 +578,6 @@ std::vector<std::pair<CFrame, Color3>> DEBUG_CFRAMES;
void renderDebugCFrames() {
glDepthMask(GL_TRUE);
glCullFace(GL_BACK);
glFrontFace(GL_CCW); // This is right... Probably.....
// Use shader
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__`:
#ifdef __AUTOGEN_EXTRA_INCLUDES__
#include "objects/part.h"
#include "objects/part/part.h"
#endif
class Part;

View file

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

View file

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

View file

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

View file

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