├── .pre-commit-config.yaml ├── FUNDING.yml ├── README.md ├── __pycache__ ├── constants.cpython-39.pyc └── event.cpython-39.pyc ├── assets ├── deer.mtl ├── deer.obj ├── monkeyblender.mtl ├── monkeyblender.obj ├── sphere.mtl ├── sphere.obj ├── torus.mtl ├── torus.obj ├── utahteapot.mtl └── utahteapot.obj ├── engine ├── __pycache__ │ ├── constants.cpython-39.pyc │ └── event.cpython-39.pyc ├── constants.py ├── event.py ├── main.py ├── test.py └── utils │ ├── __pycache__ │ ├── camera.cpython-39.pyc │ ├── light.cpython-39.pyc │ ├── matrix.cpython-39.pyc │ ├── tools.cpython-39.pyc │ ├── transform.cpython-39.pyc │ ├── triangle.cpython-39.pyc │ ├── vector.cpython-39.pyc │ └── world.cpython-39.pyc │ ├── camera.py │ ├── light.py │ ├── matrix.py │ ├── mesh │ ├── __pycache__ │ │ ├── base.cpython-39.pyc │ │ ├── meshes.cpython-39.pyc │ │ ├── point.cpython-39.pyc │ │ └── spheres.cpython-39.pyc │ ├── base.py │ ├── meshes.py │ ├── point.py │ └── spheres.py │ ├── tools.py │ ├── transform.py │ ├── triangle.py │ ├── vector.py │ └── world.py └── requirements-dev.txt /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/ambv/black 3 | rev: stable 4 | hooks: 5 | - id: black 6 | language_version: python3.9 7 | - repo: https://gitlab.com/pycqa/flake8 8 | rev: 3.9.2 9 | hooks: 10 | - id: flake8 11 | -------------------------------------------------------------------------------- /FUNDING.yml: -------------------------------------------------------------------------------- 1 | patreon: auctux 2 | ko_fi: auctux 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 3D ENGINE WITH PYTHON FROM SCRATCH 2 | 3 | [![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/S6S64434Q) 4 | 5 | Youtube Channel: https://www.youtube.com/c/Auctux [auctux | YouTube] 6 | 7 | 8 | --- 9 | ### Package Requirement 10 | pip install -r requirements-dev.txt 11 | --- 12 | 13 | ### Development Setup 14 | pip install -r requirements-dev.txt 15 | pre-commit install 16 | 17 | --- 18 | ### Bugs (unsolved issues) 19 | - The z sorting of triangles still has some noticeable issues 20 | - still need some optimization to run faster ( maybe using numpy matrices can help a little bit) 21 | - issues with translate matrix , gonna fix it later still trying a couple of things 22 | 23 | --- 24 | ### Support `.obj` files although the z-sorting isn't working properly 25 | ![DeerGIF](https://user-images.githubusercontent.com/48150537/121646510-06faf980-cab3-11eb-9edf-b26271163645.gif) 26 | --- 27 | ### Directional lighting 28 | 29 | light = Light(position) 30 | # to disable the light in the scene you can set the light = None 31 | light = None 32 | ![Directional LightGIF](https://user-images.githubusercontent.com/48150537/121668156-a5de2080-cac8-11eb-9efa-9d5e8bf80428.gif) 33 | --- 34 | ### Controls 35 | Might work on a much better controls later but for now to move around the scene you can use "WASD" and "Arrows". 36 | The controls are weird , I'm gonna try to improve them. 37 | 38 | --- 39 | ### Parameters 40 | ![Screenshot (132)](https://user-images.githubusercontent.com/48150537/122714091-652e9600-d284-11eb-9349-d694e6f2b49a.png) 41 | 42 | 43 | --- 44 | ### Display normals: 45 | ShowNormals = True 46 | # you can set the normal lines length in the world.py file 47 | ![normalsGIF](https://user-images.githubusercontent.com/48150537/121646570-1712d900-cab3-11eb-8ae0-5a640291659b.gif) 48 | 49 | --- 50 | 51 | ### Camera Clipping 52 | It still has a couple of issues when it comes to the boundary clipping , since it's only clip the faces that are in front of the camera. 53 | 54 | ![clippingGIF](https://user-images.githubusercontent.com/48150537/121647190-bfc13880-cab3-11eb-8ee7-c0ee61f47849.gif) 55 | 56 | --- 57 | ### Wireframe Mode 58 | wireframe = True 59 | ![wireframe](https://user-images.githubusercontent.com/48150537/121646751-41649680-cab3-11eb-8a56-8ee20a5c08ab.gif) 60 | 61 | --- 62 | ### Display Point Vertices 63 | vertices = True 64 | ![cube](https://user-images.githubusercontent.com/48150537/121646975-7ec92400-cab3-11eb-8d73-f5eebe130b62.gif) 65 | 66 | --- 67 | ### Display Axis 68 | showAxis = True 69 | # red: x axis 70 | # green: y axis 71 | # blue: z axis 72 | 73 | ![ezgif com-gif-maker (4)](https://user-images.githubusercontent.com/48150537/122591036-000a5300-d080-11eb-82dd-8c29d3842702.gif) 74 | 75 | --- 76 | ![icosphereGIG](https://user-images.githubusercontent.com/48150537/121646963-7cff6080-cab3-11eb-9341-cb007f568611.gif) 77 | --- 78 | ### Utah Teapot 79 | 80 | ![Screenshot (131)](https://user-images.githubusercontent.com/48150537/122714245-a0c96000-d284-11eb-8da7-202bff79e0bc.png) 81 | 82 | --- 83 | # Enjoy✌ 84 | #### Subscribe to my YouTube 85 | #### https://www.youtube.com/c/Auctux 86 | 87 | 88 | [youtube]: https://www.youtube.com/channel/UCjPk9YDheKst1FlAf_KSpyA 89 | -------------------------------------------------------------------------------- /__pycache__/constants.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/3D-engine-from-scraph--pygame/b3ed330acd55026d93d95f243df3e10aad6f4779/__pycache__/constants.cpython-39.pyc -------------------------------------------------------------------------------- /__pycache__/event.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/3D-engine-from-scraph--pygame/b3ed330acd55026d93d95f243df3e10aad6f4779/__pycache__/event.cpython-39.pyc -------------------------------------------------------------------------------- /assets/deer.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 1 3 | 4 | newmtl Mat 5 | Ns 225.000000 6 | Ka 1.000000 1.000000 1.000000 7 | Kd 0.800000 0.800000 0.800000 8 | Ks 0.500000 0.500000 0.500000 9 | Ke 0.000000 0.000000 0.000000 10 | Ni 1.450000 11 | d 1.000000 12 | illum 2 13 | -------------------------------------------------------------------------------- /assets/monkeyblender.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 1 3 | 4 | newmtl None 5 | Ns 500 6 | Ka 0.8 0.8 0.8 7 | Kd 0.8 0.8 0.8 8 | Ks 0.8 0.8 0.8 9 | d 1 10 | illum 2 11 | -------------------------------------------------------------------------------- /assets/sphere.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 1 3 | 4 | newmtl None 5 | Ns 500 6 | Ka 0.8 0.8 0.8 7 | Kd 0.8 0.8 0.8 8 | Ks 0.8 0.8 0.8 9 | d 1 10 | illum 2 11 | -------------------------------------------------------------------------------- /assets/sphere.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.90.1 OBJ File: '' 2 | # www.blender.org 3 | mtllib sphere.mtl 4 | o Sphere 5 | v 0.000000 0.923880 -0.382683 6 | v 0.000000 0.831470 -0.555570 7 | v 0.000000 0.195090 -0.980785 8 | v 0.000000 0.000000 -1.000000 9 | v 0.000000 -0.195090 -0.980785 10 | v 0.000000 -0.382683 -0.923880 11 | v 0.050493 0.980785 -0.188443 12 | v 0.099046 0.923880 -0.369644 13 | v 0.143792 0.831470 -0.536640 14 | v 0.183013 0.707107 -0.683013 15 | v 0.215200 0.555570 -0.803138 16 | v 0.239118 0.382683 -0.892399 17 | v 0.253846 0.195090 -0.947366 18 | v 0.258819 0.000000 -0.965926 19 | v 0.253846 -0.195090 -0.947366 20 | v 0.239118 -0.382683 -0.892399 21 | v 0.215200 -0.555570 -0.803138 22 | v 0.183013 -0.707107 -0.683013 23 | v 0.143792 -0.831470 -0.536640 24 | v 0.099046 -0.923880 -0.369644 25 | v 0.050493 -0.980785 -0.188443 26 | v 0.097545 0.980785 -0.168953 27 | v 0.191342 0.923880 -0.331414 28 | v 0.277785 0.831470 -0.481138 29 | v 0.353554 0.707107 -0.612372 30 | v 0.415735 0.555570 -0.720074 31 | v 0.461940 0.382683 -0.800103 32 | v 0.490393 0.195090 -0.849385 33 | v 0.500000 0.000000 -0.866025 34 | v 0.490393 -0.195090 -0.849385 35 | v 0.461940 -0.382683 -0.800103 36 | v 0.415735 -0.555570 -0.720074 37 | v 0.353554 -0.707107 -0.612372 38 | v 0.277785 -0.831470 -0.481138 39 | v 0.191342 -0.923880 -0.331413 40 | v 0.097545 -0.980785 -0.168953 41 | v 0.137950 0.980785 -0.137950 42 | v 0.270598 0.923880 -0.270598 43 | v 0.392848 0.831470 -0.392847 44 | v 0.500000 0.707107 -0.500000 45 | v 0.587938 0.555570 -0.587938 46 | v 0.653282 0.382683 -0.653281 47 | v 0.693520 0.195090 -0.693520 48 | v 0.707107 0.000000 -0.707107 49 | v 0.693520 -0.195090 -0.693520 50 | v 0.653282 -0.382683 -0.653281 51 | v 0.587938 -0.555570 -0.587938 52 | v 0.500000 -0.707107 -0.500000 53 | v 0.392848 -0.831470 -0.392847 54 | v 0.270598 -0.923880 -0.270598 55 | v 0.137950 -0.980785 -0.137949 56 | v 0.168953 0.980785 -0.097545 57 | v 0.331414 0.923880 -0.191342 58 | v 0.481138 0.831470 -0.277785 59 | v 0.612373 0.707107 -0.353553 60 | v 0.720074 0.555570 -0.415735 61 | v 0.800103 0.382683 -0.461940 62 | v 0.849385 0.195090 -0.490392 63 | v 0.866026 0.000000 -0.500000 64 | v 0.849385 -0.195090 -0.490392 65 | v 0.800103 -0.382683 -0.461940 66 | v 0.720074 -0.555570 -0.415735 67 | v 0.612373 -0.707107 -0.353553 68 | v 0.481138 -0.831470 -0.277785 69 | v 0.331414 -0.923880 -0.191342 70 | v 0.168953 -0.980785 -0.097545 71 | v 0.188443 0.980785 -0.050493 72 | v 0.369644 0.923880 -0.099046 73 | v 0.536640 0.831470 -0.143792 74 | v 0.683013 0.707107 -0.183012 75 | v 0.803138 0.555570 -0.215200 76 | v 0.892399 0.382683 -0.239117 77 | v 0.947366 0.195090 -0.253846 78 | v 0.965926 0.000000 -0.258819 79 | v 0.947366 -0.195090 -0.253846 80 | v 0.892399 -0.382683 -0.239117 81 | v 0.803138 -0.555570 -0.215200 82 | v 0.683013 -0.707107 -0.183012 83 | v 0.536640 -0.831470 -0.143792 84 | v 0.369644 -0.923880 -0.099046 85 | v 0.188443 -0.980785 -0.050493 86 | v 0.195091 0.980785 0.000000 87 | v 0.382684 0.923880 0.000000 88 | v 0.555570 0.831470 0.000000 89 | v 0.707107 0.707107 0.000000 90 | v 0.831470 0.555570 0.000000 91 | v 0.923880 0.382683 0.000000 92 | v 0.980785 0.195090 0.000000 93 | v 1.000000 0.000000 0.000000 94 | v 0.980785 -0.195090 0.000000 95 | v 0.923880 -0.382683 0.000000 96 | v 0.831470 -0.555570 0.000000 97 | v 0.707107 -0.707107 0.000000 98 | v 0.555570 -0.831470 0.000000 99 | v 0.382684 -0.923880 0.000000 100 | v 0.195090 -0.980785 0.000000 101 | v 0.188443 0.980785 0.050494 102 | v 0.369644 0.923880 0.099046 103 | v 0.536640 0.831470 0.143793 104 | v 0.683013 0.707107 0.183013 105 | v 0.803138 0.555570 0.215201 106 | v 0.892399 0.382683 0.239118 107 | v 0.947366 0.195090 0.253846 108 | v 0.965926 0.000000 0.258819 109 | v 0.947366 -0.195090 0.253846 110 | v 0.892399 -0.382683 0.239118 111 | v 0.803138 -0.555570 0.215201 112 | v 0.683013 -0.707107 0.183013 113 | v 0.536640 -0.831470 0.143793 114 | v 0.369644 -0.923880 0.099046 115 | v 0.188443 -0.980785 0.050493 116 | v 0.168953 0.980785 0.097546 117 | v 0.331414 0.923880 0.191342 118 | v 0.481138 0.831470 0.277786 119 | v 0.612373 0.707107 0.353554 120 | v 0.720074 0.555570 0.415735 121 | v 0.800103 0.382683 0.461940 122 | v 0.849385 0.195090 0.490393 123 | v 0.866026 0.000000 0.500000 124 | v 0.849385 -0.195090 0.490393 125 | v 0.800103 -0.382683 0.461940 126 | v 0.720074 -0.555570 0.415735 127 | v 0.612373 -0.707107 0.353554 128 | v 0.481138 -0.831470 0.277786 129 | v 0.331414 -0.923880 0.191342 130 | v 0.168953 -0.980785 0.097546 131 | v 0.137950 0.980785 0.137950 132 | v 0.270598 0.923880 0.270599 133 | v 0.392848 0.831470 0.392848 134 | v 0.500000 0.707107 0.500000 135 | v 0.587938 0.555570 0.587938 136 | v 0.653282 0.382683 0.653282 137 | v 0.693520 0.195090 0.693520 138 | v 0.707107 0.000000 0.707107 139 | v 0.693520 -0.195090 0.693520 140 | v 0.653282 -0.382683 0.653282 141 | v 0.587938 -0.555570 0.587938 142 | v 0.500000 -0.707107 0.500000 143 | v 0.392848 -0.831470 0.392848 144 | v 0.270598 -0.923880 0.270598 145 | v 0.137950 -0.980785 0.137950 146 | v 0.097545 0.980785 0.168954 147 | v 0.191342 0.923880 0.331414 148 | v 0.277785 0.831470 0.481138 149 | v 0.353553 0.707107 0.612373 150 | v 0.415735 0.555570 0.720074 151 | v 0.461940 0.382683 0.800103 152 | v 0.490393 0.195090 0.849385 153 | v 0.500000 0.000000 0.866026 154 | v 0.490393 -0.195090 0.849385 155 | v 0.461940 -0.382683 0.800103 156 | v 0.415735 -0.555570 0.720074 157 | v 0.353553 -0.707107 0.612373 158 | v 0.277785 -0.831470 0.481138 159 | v 0.191342 -0.923880 0.331414 160 | v 0.097545 -0.980785 0.168954 161 | v 0.050493 0.980785 0.188443 162 | v 0.099046 0.923880 0.369644 163 | v 0.143792 0.831470 0.536640 164 | v 0.183013 0.707107 0.683013 165 | v 0.215200 0.555570 0.803138 166 | v 0.239118 0.382683 0.892399 167 | v 0.253846 0.195090 0.947366 168 | v 0.258819 0.000000 0.965926 169 | v 0.253846 -0.195090 0.947366 170 | v 0.239118 -0.382683 0.892399 171 | v 0.215200 -0.555570 0.803138 172 | v 0.183013 -0.707107 0.683013 173 | v 0.143792 -0.831470 0.536640 174 | v 0.099046 -0.923880 0.369644 175 | v 0.050493 -0.980785 0.188443 176 | v -0.000000 0.980785 0.195091 177 | v -0.000000 0.923880 0.382684 178 | v 0.000000 0.831470 0.555571 179 | v 0.000000 0.707107 0.707107 180 | v 0.000000 0.555570 0.831470 181 | v 0.000000 0.382683 0.923880 182 | v 0.000000 0.195090 0.980785 183 | v 0.000000 0.000000 1.000000 184 | v 0.000000 -0.195090 0.980786 185 | v 0.000000 -0.382683 0.923880 186 | v 0.000000 -0.555570 0.831470 187 | v 0.000000 -0.707107 0.707107 188 | v 0.000000 -0.831470 0.555571 189 | v 0.000000 -0.923880 0.382684 190 | v -0.000000 -0.980785 0.195091 191 | v -0.050493 0.980785 0.188443 192 | v -0.099046 0.923880 0.369644 193 | v -0.143792 0.831470 0.536640 194 | v -0.183013 0.707107 0.683013 195 | v -0.215200 0.555570 0.803138 196 | v -0.239117 0.382683 0.892399 197 | v -0.253846 0.195090 0.947366 198 | v -0.258819 0.000000 0.965926 199 | v -0.253846 -0.195090 0.947366 200 | v -0.239118 -0.382683 0.892399 201 | v -0.215200 -0.555570 0.803138 202 | v -0.183013 -0.707107 0.683013 203 | v -0.143792 -0.831470 0.536640 204 | v -0.099046 -0.923880 0.369644 205 | v -0.050493 -0.980785 0.188443 206 | v -0.000000 1.000000 0.000001 207 | v -0.097545 0.980785 0.168954 208 | v -0.191342 0.923880 0.331414 209 | v -0.277785 0.831470 0.481138 210 | v -0.353553 0.707107 0.612373 211 | v -0.415735 0.555570 0.720074 212 | v -0.461940 0.382683 0.800103 213 | v -0.490393 0.195090 0.849385 214 | v -0.500000 0.000000 0.866026 215 | v -0.490393 -0.195090 0.849385 216 | v -0.461940 -0.382683 0.800103 217 | v -0.415735 -0.555570 0.720074 218 | v -0.353553 -0.707107 0.612373 219 | v -0.277785 -0.831470 0.481138 220 | v -0.191342 -0.923880 0.331414 221 | v -0.097545 -0.980785 0.168954 222 | v -0.137950 0.980785 0.137950 223 | v -0.270598 0.923880 0.270599 224 | v -0.392847 0.831470 0.392848 225 | v -0.500000 0.707107 0.500000 226 | v -0.587938 0.555570 0.587938 227 | v -0.653281 0.382683 0.653282 228 | v -0.693520 0.195090 0.693520 229 | v -0.707107 0.000000 0.707107 230 | v -0.693520 -0.195090 0.693520 231 | v -0.653281 -0.382683 0.653282 232 | v -0.587938 -0.555570 0.587938 233 | v -0.500000 -0.707107 0.500000 234 | v -0.392847 -0.831470 0.392848 235 | v -0.270598 -0.923880 0.270598 236 | v -0.137950 -0.980785 0.137950 237 | v -0.168953 0.980785 0.097546 238 | v -0.331414 0.923880 0.191342 239 | v -0.481138 0.831470 0.277785 240 | v -0.612372 0.707107 0.353554 241 | v -0.720074 0.555570 0.415735 242 | v -0.800103 0.382683 0.461940 243 | v -0.849385 0.195090 0.490393 244 | v -0.866025 0.000000 0.500000 245 | v -0.849385 -0.195090 0.490393 246 | v -0.800103 -0.382683 0.461940 247 | v -0.720074 -0.555570 0.415735 248 | v -0.612372 -0.707107 0.353554 249 | v -0.481138 -0.831470 0.277785 250 | v -0.331414 -0.923880 0.191342 251 | v -0.168953 -0.980785 0.097545 252 | v -0.188443 0.980785 0.050493 253 | v -0.369644 0.923880 0.099046 254 | v -0.536640 0.831470 0.143792 255 | v -0.683013 0.707107 0.183013 256 | v -0.803138 0.555570 0.215200 257 | v -0.892399 0.382683 0.239118 258 | v -0.947366 0.195090 0.253846 259 | v -0.965926 0.000000 0.258819 260 | v -0.947366 -0.195090 0.253846 261 | v -0.892399 -0.382683 0.239118 262 | v -0.803138 -0.555570 0.215200 263 | v -0.683013 -0.707107 0.183013 264 | v -0.536640 -0.831470 0.143792 265 | v -0.369644 -0.923880 0.099046 266 | v -0.188443 -0.980785 0.050493 267 | v 0.000000 -1.000000 0.000000 268 | v -0.195091 0.980785 0.000000 269 | v -0.382684 0.923880 0.000000 270 | v -0.555570 0.831470 0.000000 271 | v -0.707107 0.707107 0.000000 272 | v -0.831470 0.555570 0.000000 273 | v -0.923879 0.382683 0.000000 274 | v -0.980785 0.195090 0.000000 275 | v -1.000000 0.000000 0.000000 276 | v -0.980785 -0.195090 0.000000 277 | v -0.923880 -0.382683 0.000000 278 | v -0.831470 -0.555570 0.000000 279 | v -0.707107 -0.707107 0.000000 280 | v -0.555570 -0.831470 0.000000 281 | v -0.382683 -0.923880 0.000000 282 | v -0.195090 -0.980785 0.000000 283 | v -0.188443 0.980785 -0.050493 284 | v -0.369644 0.923880 -0.099046 285 | v -0.536640 0.831470 -0.143792 286 | v -0.683013 0.707107 -0.183012 287 | v -0.803138 0.555570 -0.215200 288 | v -0.892399 0.382683 -0.239117 289 | v -0.947366 0.195090 -0.253846 290 | v -0.965926 0.000000 -0.258819 291 | v -0.947366 -0.195090 -0.253846 292 | v -0.892399 -0.382683 -0.239117 293 | v -0.803138 -0.555570 -0.215200 294 | v -0.683013 -0.707107 -0.183012 295 | v -0.536640 -0.831470 -0.143792 296 | v -0.369644 -0.923880 -0.099045 297 | v -0.188443 -0.980785 -0.050493 298 | v -0.168953 0.980785 -0.097545 299 | v -0.331414 0.923880 -0.191342 300 | v -0.481138 0.831470 -0.277785 301 | v -0.612372 0.707107 -0.353553 302 | v -0.720074 0.555570 -0.415734 303 | v -0.800103 0.382683 -0.461939 304 | v -0.849385 0.195090 -0.490392 305 | v -0.866025 0.000000 -0.500000 306 | v -0.849385 -0.195090 -0.490392 307 | v -0.800103 -0.382683 -0.461939 308 | v -0.720074 -0.555570 -0.415734 309 | v -0.612372 -0.707107 -0.353553 310 | v -0.481138 -0.831470 -0.277785 311 | v -0.331414 -0.923880 -0.191341 312 | v -0.168953 -0.980785 -0.097545 313 | v -0.137950 0.980785 -0.137950 314 | v -0.270598 0.923880 -0.270598 315 | v -0.392847 0.831470 -0.392847 316 | v -0.500000 0.707107 -0.500000 317 | v -0.587938 0.555570 -0.587937 318 | v -0.653282 0.382683 -0.653281 319 | v -0.693520 0.195090 -0.693520 320 | v -0.707107 0.000000 -0.707106 321 | v -0.693520 -0.195090 -0.693520 322 | v -0.653281 -0.382683 -0.653281 323 | v -0.587938 -0.555570 -0.587937 324 | v -0.500000 -0.707107 -0.500000 325 | v -0.392847 -0.831470 -0.392847 326 | v -0.270598 -0.923880 -0.270598 327 | v -0.137950 -0.980785 -0.137949 328 | v -0.097545 0.980785 -0.168953 329 | v -0.191342 0.923880 -0.331413 330 | v -0.277785 0.831470 -0.481138 331 | v -0.353553 0.707107 -0.612372 332 | v -0.415735 0.555570 -0.720074 333 | v -0.461940 0.382683 -0.800103 334 | v -0.490392 0.195090 -0.849385 335 | v -0.500000 0.000000 -0.866025 336 | v -0.490392 -0.195090 -0.849385 337 | v -0.461940 -0.382683 -0.800103 338 | v -0.415735 -0.555570 -0.720074 339 | v -0.353553 -0.707107 -0.612372 340 | v -0.277785 -0.831470 -0.481138 341 | v -0.191342 -0.923880 -0.331413 342 | v -0.097545 -0.980785 -0.168953 343 | v -0.050493 0.980785 -0.188443 344 | v -0.099046 0.923880 -0.369644 345 | v -0.143792 0.831470 -0.536639 346 | v -0.183013 0.707107 -0.683012 347 | v -0.215200 0.555570 -0.803138 348 | v -0.239118 0.382683 -0.892399 349 | v -0.253846 0.195090 -0.947365 350 | v -0.258819 0.000000 -0.965925 351 | v -0.253846 -0.195090 -0.947365 352 | v -0.239118 -0.382683 -0.892399 353 | v -0.215200 -0.555570 -0.803138 354 | v -0.183013 -0.707107 -0.683012 355 | v -0.143792 -0.831470 -0.536639 356 | v -0.099046 -0.923880 -0.369643 357 | v -0.050493 -0.980785 -0.188442 358 | v 0.000000 0.980785 -0.195090 359 | v -0.000000 0.707107 -0.707106 360 | v -0.000000 0.555570 -0.831469 361 | v -0.000000 0.382683 -0.923879 362 | v -0.000000 -0.555570 -0.831469 363 | v -0.000000 -0.707107 -0.707106 364 | v 0.000000 -0.831470 -0.555570 365 | v 0.000000 -0.923880 -0.382683 366 | v 0.000000 -0.980785 -0.195090 367 | vt 0.750000 0.750000 368 | vt 0.708333 0.812500 369 | vt 0.708333 0.750000 370 | vt 0.750000 0.312500 371 | vt 0.708333 0.250000 372 | vt 0.750000 0.250000 373 | vt 0.750000 0.687500 374 | vt 0.708333 0.687500 375 | vt 0.708333 0.187500 376 | vt 0.750000 0.187500 377 | vt 0.750000 0.625000 378 | vt 0.708333 0.625000 379 | vt 0.708333 0.125000 380 | vt 0.750000 0.125000 381 | vt 0.750000 0.562500 382 | vt 0.708333 0.562500 383 | vt 0.708333 0.062500 384 | vt 0.750000 0.062500 385 | vt 0.708333 0.500000 386 | vt 0.750000 0.500000 387 | vt 0.750000 0.937500 388 | vt 0.729167 1.000000 389 | vt 0.708333 0.937500 390 | vt 0.729167 0.000000 391 | vt 0.750000 0.437500 392 | vt 0.708333 0.437500 393 | vt 0.750000 0.875000 394 | vt 0.708333 0.875000 395 | vt 0.708333 0.375000 396 | vt 0.750000 0.375000 397 | vt 0.750000 0.812500 398 | vt 0.708333 0.312500 399 | vt 0.666667 0.375000 400 | vt 0.666667 0.812500 401 | vt 0.666667 0.312500 402 | vt 0.666667 0.750000 403 | vt 0.666667 0.250000 404 | vt 0.666667 0.687500 405 | vt 0.666667 0.187500 406 | vt 0.666667 0.625000 407 | vt 0.666667 0.125000 408 | vt 0.666667 0.562500 409 | vt 0.666667 0.062500 410 | vt 0.666667 0.500000 411 | vt 0.687500 1.000000 412 | vt 0.666667 0.937500 413 | vt 0.687500 0.000000 414 | vt 0.666667 0.437500 415 | vt 0.666667 0.875000 416 | vt 0.625000 0.125000 417 | vt 0.625000 0.625000 418 | vt 0.625000 0.562500 419 | vt 0.625000 0.062500 420 | vt 0.625000 0.500000 421 | vt 0.645833 1.000000 422 | vt 0.625000 0.937500 423 | vt 0.645833 0.000000 424 | vt 0.625000 0.437500 425 | vt 0.625000 0.875000 426 | vt 0.625000 0.375000 427 | vt 0.625000 0.812500 428 | vt 0.625000 0.312500 429 | vt 0.625000 0.750000 430 | vt 0.625000 0.250000 431 | vt 0.625000 0.687500 432 | vt 0.625000 0.187500 433 | vt 0.583333 0.375000 434 | vt 0.583333 0.312500 435 | vt 0.583333 0.750000 436 | vt 0.583333 0.250000 437 | vt 0.583333 0.687500 438 | vt 0.583333 0.187500 439 | vt 0.583333 0.625000 440 | vt 0.583333 0.125000 441 | vt 0.583333 0.562500 442 | vt 0.583333 0.062500 443 | vt 0.583333 0.500000 444 | vt 0.604166 1.000000 445 | vt 0.583333 0.937500 446 | vt 0.604166 0.000000 447 | vt 0.583333 0.437500 448 | vt 0.583333 0.875000 449 | vt 0.583333 0.812500 450 | vt 0.541667 0.125000 451 | vt 0.541666 0.062500 452 | vt 0.541667 0.562500 453 | vt 0.541667 0.500000 454 | vt 0.562500 1.000000 455 | vt 0.541666 0.937500 456 | vt 0.562500 0.000000 457 | vt 0.541667 0.437500 458 | vt 0.541667 0.875000 459 | vt 0.541667 0.375000 460 | vt 0.541667 0.812500 461 | vt 0.541667 0.312500 462 | vt 0.541667 0.750000 463 | vt 0.541667 0.250000 464 | vt 0.541667 0.687500 465 | vt 0.541667 0.187500 466 | vt 0.541667 0.625000 467 | vt 0.500000 0.750000 468 | vt 0.500000 0.312500 469 | vt 0.500000 0.250000 470 | vt 0.500000 0.687500 471 | vt 0.500000 0.187500 472 | vt 0.500000 0.625000 473 | vt 0.500000 0.125000 474 | vt 0.500000 0.562500 475 | vt 0.500000 0.062500 476 | vt 0.500000 0.500000 477 | vt 0.520833 1.000000 478 | vt 0.500000 0.937500 479 | vt 0.520833 0.000000 480 | vt 0.500000 0.437500 481 | vt 0.500000 0.875000 482 | vt 0.500000 0.375000 483 | vt 0.500000 0.812500 484 | vt 0.458333 0.562500 485 | vt 0.458333 0.500000 486 | vt 0.479166 1.000000 487 | vt 0.458333 0.937500 488 | vt 0.479166 0.000000 489 | vt 0.458333 0.062500 490 | vt 0.458333 0.437500 491 | vt 0.458333 0.875000 492 | vt 0.458333 0.375000 493 | vt 0.458333 0.812500 494 | vt 0.458333 0.312500 495 | vt 0.458333 0.750000 496 | vt 0.458333 0.250000 497 | vt 0.458333 0.687500 498 | vt 0.458333 0.187500 499 | vt 0.458333 0.625000 500 | vt 0.458333 0.125000 501 | vt 0.416667 0.312500 502 | vt 0.416667 0.250000 503 | vt 0.416667 0.687500 504 | vt 0.416667 0.187500 505 | vt 0.416667 0.625000 506 | vt 0.416667 0.125000 507 | vt 0.416667 0.562500 508 | vt 0.416666 0.062500 509 | vt 0.416667 0.500000 510 | vt 0.437499 1.000000 511 | vt 0.416666 0.937500 512 | vt 0.437500 0.000000 513 | vt 0.416667 0.437500 514 | vt 0.416667 0.875000 515 | vt 0.416667 0.375000 516 | vt 0.416667 0.812500 517 | vt 0.416667 0.750000 518 | vt 0.395833 1.000000 519 | vt 0.375000 0.937500 520 | vt 0.395833 0.000000 521 | vt 0.375000 0.062500 522 | vt 0.375000 0.500000 523 | vt 0.375000 0.437500 524 | vt 0.375000 0.875000 525 | vt 0.375000 0.375000 526 | vt 0.375000 0.812500 527 | vt 0.375000 0.312500 528 | vt 0.375000 0.750000 529 | vt 0.375000 0.250000 530 | vt 0.375000 0.687500 531 | vt 0.375000 0.187500 532 | vt 0.375000 0.625000 533 | vt 0.375000 0.125000 534 | vt 0.375000 0.562500 535 | vt 0.333333 0.687500 536 | vt 0.333333 0.187500 537 | vt 0.333333 0.625000 538 | vt 0.333333 0.125000 539 | vt 0.333333 0.562500 540 | vt 0.333333 0.062500 541 | vt 0.333333 0.500000 542 | vt 0.354166 1.000000 543 | vt 0.333333 0.937500 544 | vt 0.354166 0.000000 545 | vt 0.333333 0.437500 546 | vt 0.333333 0.875000 547 | vt 0.333333 0.375000 548 | vt 0.333333 0.812500 549 | vt 0.333333 0.312500 550 | vt 0.333333 0.750000 551 | vt 0.333333 0.250000 552 | vt 0.291667 0.437500 553 | vt 0.291667 0.875000 554 | vt 0.291667 0.375000 555 | vt 0.291667 0.812500 556 | vt 0.291667 0.312500 557 | vt 0.291667 0.750000 558 | vt 0.291667 0.250000 559 | vt 0.291667 0.687500 560 | vt 0.291667 0.187500 561 | vt 0.291667 0.625000 562 | vt 0.291667 0.125000 563 | vt 0.291667 0.562500 564 | vt 0.291667 0.062500 565 | vt 0.291667 0.500000 566 | vt 0.312500 1.000000 567 | vt 0.291667 0.937500 568 | vt 0.312500 0.000000 569 | vt 0.250000 0.250000 570 | vt 0.250000 0.187500 571 | vt 0.250000 0.625000 572 | vt 0.250000 0.125000 573 | vt 0.250000 0.562500 574 | vt 0.250000 0.062500 575 | vt 0.250000 0.500000 576 | vt 0.270833 1.000000 577 | vt 0.250000 0.937500 578 | vt 0.270833 0.000000 579 | vt 0.250000 0.437500 580 | vt 0.250000 0.875000 581 | vt 0.250000 0.375000 582 | vt 0.250000 0.812500 583 | vt 0.250000 0.312500 584 | vt 0.250000 0.750000 585 | vt 0.250000 0.687500 586 | vt 0.208333 0.375000 587 | vt 0.208333 0.812500 588 | vt 0.208333 0.312500 589 | vt 0.208333 0.750000 590 | vt 0.208333 0.250000 591 | vt 0.208333 0.687500 592 | vt 0.208333 0.187500 593 | vt 0.208333 0.625000 594 | vt 0.208333 0.125000 595 | vt 0.208333 0.562500 596 | vt 0.208333 0.062500 597 | vt 0.208333 0.500000 598 | vt 0.229167 1.000000 599 | vt 0.208333 0.937500 600 | vt 0.229167 0.000000 601 | vt 0.208333 0.437500 602 | vt 0.208333 0.875000 603 | vt 0.166667 0.187500 604 | vt 0.166667 0.125000 605 | vt 0.166667 0.625000 606 | vt 0.166667 0.562500 607 | vt 0.166667 0.062500 608 | vt 0.166667 0.500000 609 | vt 0.187500 1.000000 610 | vt 0.166667 0.937500 611 | vt 0.187500 0.000000 612 | vt 0.166667 0.437500 613 | vt 0.166667 0.875000 614 | vt 0.166667 0.375000 615 | vt 0.166667 0.812500 616 | vt 0.166667 0.312500 617 | vt 0.166667 0.750000 618 | vt 0.166667 0.250000 619 | vt 0.166667 0.687500 620 | vt 0.125000 0.812500 621 | vt 0.125000 0.312500 622 | vt 0.125000 0.750000 623 | vt 0.125000 0.250000 624 | vt 0.125000 0.687500 625 | vt 0.125000 0.187500 626 | vt 0.125000 0.625000 627 | vt 0.125000 0.125000 628 | vt 0.125000 0.562500 629 | vt 0.125000 0.062500 630 | vt 0.125000 0.500000 631 | vt 0.145834 1.000000 632 | vt 0.125000 0.937500 633 | vt 0.145834 0.000000 634 | vt 0.125000 0.437500 635 | vt 0.125000 0.875000 636 | vt 0.125000 0.375000 637 | vt 0.083333 0.625000 638 | vt 0.083333 0.562500 639 | vt 0.083333 0.125000 640 | vt 0.083334 0.062500 641 | vt 0.083333 0.500000 642 | vt 0.104167 1.000000 643 | vt 0.083334 0.937500 644 | vt 0.104167 0.000000 645 | vt 0.083333 0.437500 646 | vt 0.083333 0.875000 647 | vt 0.083333 0.375000 648 | vt 0.083333 0.812500 649 | vt 0.083333 0.312500 650 | vt 0.083333 0.750000 651 | vt 0.083333 0.250000 652 | vt 0.083333 0.687500 653 | vt 0.083333 0.187500 654 | vt 0.041667 0.312500 655 | vt 0.041667 0.750000 656 | vt 0.041667 0.250000 657 | vt 0.041667 0.687500 658 | vt 0.041667 0.187500 659 | vt 0.041667 0.625000 660 | vt 0.041667 0.125000 661 | vt 0.041667 0.562500 662 | vt 0.041667 0.062500 663 | vt 0.041667 0.500000 664 | vt 0.062500 1.000000 665 | vt 0.041667 0.937500 666 | vt 0.062500 0.000000 667 | vt 0.041667 0.437500 668 | vt 0.041667 0.875000 669 | vt 0.041667 0.375000 670 | vt 0.041667 0.812500 671 | vt 0.000000 0.125000 672 | vt 0.000000 0.062500 673 | vt 0.000000 0.500000 674 | vt 0.020834 1.000000 675 | vt 0.000000 0.937500 676 | vt 0.020834 0.000000 677 | vt 0.000000 0.437500 678 | vt 0.000000 0.875000 679 | vt 0.000000 0.375000 680 | vt 0.000000 0.812500 681 | vt 0.000000 0.312500 682 | vt 0.000000 0.750000 683 | vt 0.000000 0.250000 684 | vt 0.000000 0.687500 685 | vt 0.000000 0.187500 686 | vt 0.000000 0.625000 687 | vt 0.000000 0.562500 688 | vt 1.000000 0.812500 689 | vt 0.958333 0.750000 690 | vt 1.000000 0.750000 691 | vt 1.000000 0.312500 692 | vt 0.958333 0.250000 693 | vt 1.000000 0.250000 694 | vt 1.000000 0.687500 695 | vt 0.958333 0.687500 696 | vt 0.958333 0.187500 697 | vt 1.000000 0.187500 698 | vt 0.958333 0.625000 699 | vt 1.000000 0.625000 700 | vt 1.000000 0.125000 701 | vt 0.958333 0.125000 702 | vt 1.000000 0.562500 703 | vt 0.958333 0.562500 704 | vt 1.000000 0.062500 705 | vt 0.958334 0.062500 706 | vt 0.958333 0.500000 707 | vt 1.000000 0.500000 708 | vt 1.000000 0.937500 709 | vt 0.979167 1.000000 710 | vt 0.958334 0.937500 711 | vt 0.979167 0.000000 712 | vt 1.000000 0.437500 713 | vt 0.958333 0.437500 714 | vt 0.958333 0.875000 715 | vt 1.000000 0.875000 716 | vt 0.958333 0.375000 717 | vt 1.000000 0.375000 718 | vt 0.958333 0.812500 719 | vt 0.958333 0.312500 720 | vt 0.916667 0.500000 721 | vt 0.937500 1.000000 722 | vt 0.916667 0.937500 723 | vt 0.937500 0.000000 724 | vt 0.916667 0.062500 725 | vt 0.916667 0.437500 726 | vt 0.916667 0.875000 727 | vt 0.916667 0.375000 728 | vt 0.916667 0.812500 729 | vt 0.916667 0.312500 730 | vt 0.916667 0.750000 731 | vt 0.916667 0.250000 732 | vt 0.916667 0.687500 733 | vt 0.916667 0.187500 734 | vt 0.916667 0.625000 735 | vt 0.916667 0.125000 736 | vt 0.916667 0.562500 737 | vt 0.875000 0.250000 738 | vt 0.875000 0.750000 739 | vt 0.875000 0.687500 740 | vt 0.875000 0.187500 741 | vt 0.875000 0.625000 742 | vt 0.875000 0.125000 743 | vt 0.875000 0.562500 744 | vt 0.875000 0.062500 745 | vt 0.875000 0.500000 746 | vt 0.895834 1.000000 747 | vt 0.875000 0.937500 748 | vt 0.895834 0.000000 749 | vt 0.875000 0.437500 750 | vt 0.875000 0.875000 751 | vt 0.875000 0.375000 752 | vt 0.875000 0.812500 753 | vt 0.875000 0.312500 754 | vt 0.854167 0.000000 755 | vt 0.833333 0.062500 756 | vt 0.833333 0.500000 757 | vt 0.833333 0.437500 758 | vt 0.833333 0.937500 759 | vt 0.833333 0.875000 760 | vt 0.833333 0.375000 761 | vt 0.833333 0.812500 762 | vt 0.833333 0.312500 763 | vt 0.833333 0.750000 764 | vt 0.833333 0.250000 765 | vt 0.833333 0.687500 766 | vt 0.833333 0.187500 767 | vt 0.833333 0.625000 768 | vt 0.833333 0.125000 769 | vt 0.833333 0.562500 770 | vt 0.854167 1.000000 771 | vt 0.791667 0.250000 772 | vt 0.791667 0.187500 773 | vt 0.791667 0.625000 774 | vt 0.791667 0.125000 775 | vt 0.791667 0.562500 776 | vt 0.791667 0.062500 777 | vt 0.791667 0.500000 778 | vt 0.812500 1.000000 779 | vt 0.791667 0.937500 780 | vt 0.812500 0.000000 781 | vt 0.791667 0.437500 782 | vt 0.791667 0.875000 783 | vt 0.791667 0.375000 784 | vt 0.791667 0.812500 785 | vt 0.791667 0.312500 786 | vt 0.791667 0.750000 787 | vt 0.791667 0.687500 788 | vt 0.770833 1.000000 789 | vt 0.770833 0.000000 790 | vn 0.0832 0.7703 -0.6322 791 | vn 0.1012 -0.6311 -0.7690 792 | vn 0.1012 0.6311 -0.7690 793 | vn 0.0832 -0.7703 -0.6322 794 | vn 0.1153 0.4683 -0.8760 795 | vn 0.0619 -0.8802 -0.4705 796 | vn 0.1250 0.2880 -0.9494 797 | vn 0.0382 -0.9562 -0.2901 798 | vn 0.1299 0.0972 -0.9868 799 | vn 0.0129 0.9951 -0.0980 800 | vn 0.0129 -0.9951 -0.0980 801 | vn 0.1299 -0.0972 -0.9868 802 | vn 0.0382 0.9562 -0.2901 803 | vn 0.1250 -0.2880 -0.9494 804 | vn 0.0619 0.8802 -0.4705 805 | vn 0.1153 -0.4683 -0.8760 806 | vn 0.3665 -0.2880 -0.8847 807 | vn 0.1816 0.8802 -0.4384 808 | vn 0.3381 -0.4683 -0.8163 809 | vn 0.2440 0.7703 -0.5891 810 | vn 0.2968 -0.6311 -0.7166 811 | vn 0.2968 0.6311 -0.7166 812 | vn 0.2440 -0.7703 -0.5891 813 | vn 0.3381 0.4683 -0.8163 814 | vn 0.1816 -0.8802 -0.4384 815 | vn 0.3665 0.2880 -0.8847 816 | vn 0.1120 -0.9562 -0.2703 817 | vn 0.3809 0.0972 -0.9195 818 | vn 0.0378 0.9951 -0.0913 819 | vn 0.0378 -0.9951 -0.0913 820 | vn 0.3809 -0.0972 -0.9195 821 | vn 0.1120 0.9562 -0.2703 822 | vn 0.2889 -0.8802 -0.3765 823 | vn 0.5830 0.2880 -0.7597 824 | vn 0.1781 -0.9562 -0.2321 825 | vn 0.6059 0.0972 -0.7896 826 | vn 0.0602 0.9951 -0.0784 827 | vn 0.0602 -0.9951 -0.0784 828 | vn 0.6059 -0.0972 -0.7896 829 | vn 0.1781 0.9562 -0.2321 830 | vn 0.5830 -0.2880 -0.7597 831 | vn 0.2889 0.8802 -0.3765 832 | vn 0.5379 -0.4683 -0.7010 833 | vn 0.3882 0.7703 -0.5059 834 | vn 0.4722 -0.6311 -0.6154 835 | vn 0.4722 0.6311 -0.6154 836 | vn 0.3882 -0.7703 -0.5059 837 | vn 0.5379 0.4683 -0.7010 838 | vn 0.7010 -0.4683 -0.5379 839 | vn 0.5059 0.7703 -0.3882 840 | vn 0.6154 -0.6311 -0.4722 841 | vn 0.6154 0.6311 -0.4722 842 | vn 0.5059 -0.7703 -0.3882 843 | vn 0.7010 0.4683 -0.5379 844 | vn 0.3765 -0.8802 -0.2889 845 | vn 0.7597 0.2880 -0.5830 846 | vn 0.2321 -0.9562 -0.1781 847 | vn 0.7896 0.0972 -0.6059 848 | vn 0.0784 0.9951 -0.0602 849 | vn 0.0784 -0.9951 -0.0602 850 | vn 0.7896 -0.0972 -0.6059 851 | vn 0.2321 0.9562 -0.1781 852 | vn 0.7597 -0.2880 -0.5830 853 | vn 0.3765 0.8802 -0.2889 854 | vn 0.2703 -0.9562 -0.1120 855 | vn 0.9195 0.0972 -0.3809 856 | vn 0.0913 0.9951 -0.0378 857 | vn 0.0913 -0.9951 -0.0378 858 | vn 0.9195 -0.0972 -0.3809 859 | vn 0.2703 0.9562 -0.1120 860 | vn 0.8847 -0.2880 -0.3665 861 | vn 0.4384 0.8802 -0.1816 862 | vn 0.8163 -0.4683 -0.3381 863 | vn 0.5891 0.7703 -0.2440 864 | vn 0.7166 -0.6311 -0.2968 865 | vn 0.7166 0.6311 -0.2968 866 | vn 0.5891 -0.7703 -0.2440 867 | vn 0.8163 0.4683 -0.3381 868 | vn 0.4384 -0.8802 -0.1816 869 | vn 0.8847 0.2880 -0.3665 870 | vn 0.6322 0.7703 -0.0832 871 | vn 0.7690 -0.6311 -0.1012 872 | vn 0.7690 0.6311 -0.1012 873 | vn 0.6322 -0.7703 -0.0832 874 | vn 0.8760 0.4683 -0.1153 875 | vn 0.4705 -0.8802 -0.0619 876 | vn 0.9494 0.2880 -0.1250 877 | vn 0.2901 -0.9562 -0.0382 878 | vn 0.9868 0.0972 -0.1299 879 | vn 0.0980 0.9951 -0.0129 880 | vn 0.0980 -0.9951 -0.0129 881 | vn 0.9868 -0.0972 -0.1299 882 | vn 0.2901 0.9562 -0.0382 883 | vn 0.9494 -0.2880 -0.1250 884 | vn 0.4705 0.8802 -0.0619 885 | vn 0.8760 -0.4683 -0.1153 886 | vn 0.9868 0.0972 0.1299 887 | vn 0.0980 0.9951 0.0129 888 | vn 0.0980 -0.9951 0.0129 889 | vn 0.9868 -0.0972 0.1299 890 | vn 0.2901 0.9562 0.0382 891 | vn 0.9494 -0.2880 0.1250 892 | vn 0.4705 0.8802 0.0619 893 | vn 0.8760 -0.4683 0.1153 894 | vn 0.6322 0.7703 0.0832 895 | vn 0.7690 -0.6311 0.1012 896 | vn 0.7690 0.6311 0.1012 897 | vn 0.6322 -0.7703 0.0832 898 | vn 0.8760 0.4683 0.1153 899 | vn 0.4705 -0.8802 0.0619 900 | vn 0.9494 0.2880 0.1250 901 | vn 0.2901 -0.9562 0.0382 902 | vn 0.7166 -0.6311 0.2968 903 | vn 0.7166 0.6311 0.2968 904 | vn 0.5891 -0.7703 0.2440 905 | vn 0.8163 0.4683 0.3381 906 | vn 0.4384 -0.8802 0.1816 907 | vn 0.8847 0.2880 0.3665 908 | vn 0.2703 -0.9562 0.1120 909 | vn 0.9195 0.0972 0.3809 910 | vn 0.0913 0.9951 0.0378 911 | vn 0.0913 -0.9951 0.0378 912 | vn 0.9195 -0.0972 0.3809 913 | vn 0.2703 0.9562 0.1120 914 | vn 0.8847 -0.2880 0.3665 915 | vn 0.4384 0.8802 0.1816 916 | vn 0.8163 -0.4683 0.3381 917 | vn 0.5891 0.7703 0.2440 918 | vn 0.0784 0.9951 0.0602 919 | vn 0.0784 -0.9951 0.0602 920 | vn 0.7896 -0.0972 0.6059 921 | vn 0.2321 0.9562 0.1781 922 | vn 0.7597 -0.2880 0.5830 923 | vn 0.3765 0.8802 0.2889 924 | vn 0.7010 -0.4683 0.5379 925 | vn 0.5059 0.7703 0.3882 926 | vn 0.6154 -0.6311 0.4722 927 | vn 0.6154 0.6311 0.4722 928 | vn 0.5059 -0.7703 0.3882 929 | vn 0.7010 0.4683 0.5379 930 | vn 0.3765 -0.8802 0.2889 931 | vn 0.7597 0.2880 0.5830 932 | vn 0.2321 -0.9562 0.1781 933 | vn 0.7896 0.0972 0.6059 934 | vn 0.4722 0.6311 0.6154 935 | vn 0.3882 -0.7703 0.5059 936 | vn 0.5379 0.4683 0.7010 937 | vn 0.2889 -0.8802 0.3765 938 | vn 0.5830 0.2880 0.7597 939 | vn 0.1781 -0.9562 0.2321 940 | vn 0.6059 0.0972 0.7896 941 | vn 0.0602 0.9951 0.0784 942 | vn 0.0602 -0.9951 0.0784 943 | vn 0.6059 -0.0972 0.7896 944 | vn 0.1781 0.9562 0.2321 945 | vn 0.5830 -0.2880 0.7597 946 | vn 0.2889 0.8802 0.3765 947 | vn 0.5379 -0.4683 0.7010 948 | vn 0.3882 0.7703 0.5059 949 | vn 0.4722 -0.6311 0.6154 950 | vn 0.3809 -0.0972 0.9195 951 | vn 0.1120 0.9562 0.2703 952 | vn 0.3665 -0.2880 0.8847 953 | vn 0.1816 0.8802 0.4384 954 | vn 0.3381 -0.4683 0.8163 955 | vn 0.2440 0.7703 0.5891 956 | vn 0.2968 -0.6311 0.7166 957 | vn 0.2968 0.6311 0.7166 958 | vn 0.2440 -0.7703 0.5891 959 | vn 0.3381 0.4683 0.8163 960 | vn 0.1816 -0.8802 0.4384 961 | vn 0.3665 0.2880 0.8847 962 | vn 0.1120 -0.9562 0.2703 963 | vn 0.3809 0.0972 0.9195 964 | vn 0.0378 0.9951 0.0913 965 | vn 0.0378 -0.9951 0.0913 966 | vn 0.0832 -0.7703 0.6322 967 | vn 0.1153 0.4683 0.8760 968 | vn 0.0619 -0.8802 0.4705 969 | vn 0.1250 0.2880 0.9494 970 | vn 0.0382 -0.9562 0.2901 971 | vn 0.1299 0.0972 0.9868 972 | vn 0.0129 0.9951 0.0980 973 | vn 0.0129 -0.9951 0.0980 974 | vn 0.1299 -0.0972 0.9868 975 | vn 0.0382 0.9562 0.2901 976 | vn 0.1250 -0.2880 0.9494 977 | vn 0.0619 0.8802 0.4705 978 | vn 0.1153 -0.4683 0.8760 979 | vn 0.0832 0.7703 0.6322 980 | vn 0.1012 -0.6311 0.7690 981 | vn 0.1012 0.6311 0.7690 982 | vn -0.1250 -0.2880 0.9494 983 | vn -0.0619 0.8802 0.4705 984 | vn -0.1153 -0.4683 0.8760 985 | vn -0.0832 0.7703 0.6322 986 | vn -0.1012 -0.6311 0.7690 987 | vn -0.1012 0.6311 0.7690 988 | vn -0.0832 -0.7703 0.6322 989 | vn -0.1153 0.4683 0.8760 990 | vn -0.0619 -0.8802 0.4705 991 | vn -0.1250 0.2880 0.9494 992 | vn -0.0382 -0.9562 0.2901 993 | vn -0.1299 0.0972 0.9868 994 | vn -0.0129 0.9951 0.0980 995 | vn -0.0129 -0.9951 0.0980 996 | vn -0.1299 -0.0972 0.9868 997 | vn -0.0382 0.9562 0.2901 998 | vn -0.1816 -0.8802 0.4384 999 | vn -0.3665 0.2880 0.8847 1000 | vn -0.1120 -0.9562 0.2703 1001 | vn -0.3809 0.0972 0.9195 1002 | vn -0.0378 0.9951 0.0913 1003 | vn -0.0378 -0.9951 0.0913 1004 | vn -0.3809 -0.0972 0.9195 1005 | vn -0.1120 0.9562 0.2703 1006 | vn -0.3665 -0.2880 0.8847 1007 | vn -0.1816 0.8802 0.4384 1008 | vn -0.3381 -0.4683 0.8163 1009 | vn -0.2440 0.7703 0.5891 1010 | vn -0.2968 -0.6311 0.7166 1011 | vn -0.2968 0.6311 0.7166 1012 | vn -0.2440 -0.7703 0.5891 1013 | vn -0.3381 0.4683 0.8163 1014 | vn -0.2889 0.8802 0.3765 1015 | vn -0.5379 -0.4683 0.7010 1016 | vn -0.3882 0.7703 0.5059 1017 | vn -0.4722 -0.6311 0.6154 1018 | vn -0.4722 0.6311 0.6154 1019 | vn -0.3882 -0.7703 0.5059 1020 | vn -0.5379 0.4683 0.7010 1021 | vn -0.2889 -0.8802 0.3765 1022 | vn -0.5830 0.2880 0.7597 1023 | vn -0.1781 -0.9562 0.2321 1024 | vn -0.6059 0.0972 0.7896 1025 | vn -0.0602 0.9951 0.0784 1026 | vn -0.0602 -0.9951 0.0784 1027 | vn -0.6059 -0.0972 0.7896 1028 | vn -0.1781 0.9562 0.2321 1029 | vn -0.5830 -0.2880 0.7597 1030 | vn -0.7597 0.2880 0.5830 1031 | vn -0.2321 -0.9562 0.1781 1032 | vn -0.7896 0.0972 0.6059 1033 | vn -0.0784 0.9951 0.0602 1034 | vn -0.0784 -0.9951 0.0602 1035 | vn -0.7896 -0.0972 0.6059 1036 | vn -0.2321 0.9562 0.1781 1037 | vn -0.7597 -0.2880 0.5830 1038 | vn -0.3765 0.8802 0.2889 1039 | vn -0.7010 -0.4683 0.5379 1040 | vn -0.5059 0.7703 0.3882 1041 | vn -0.6154 -0.6311 0.4722 1042 | vn -0.6154 0.6311 0.4722 1043 | vn -0.5059 -0.7703 0.3882 1044 | vn -0.7010 0.4683 0.5379 1045 | vn -0.3765 -0.8802 0.2889 1046 | vn -0.8163 -0.4683 0.3381 1047 | vn -0.5891 0.7703 0.2440 1048 | vn -0.7166 -0.6311 0.2968 1049 | vn -0.7166 0.6311 0.2968 1050 | vn -0.5891 -0.7703 0.2440 1051 | vn -0.8163 0.4683 0.3381 1052 | vn -0.4384 -0.8802 0.1816 1053 | vn -0.8847 0.2880 0.3665 1054 | vn -0.2703 -0.9562 0.1120 1055 | vn -0.9195 0.0972 0.3809 1056 | vn -0.0913 0.9951 0.0378 1057 | vn -0.0913 -0.9951 0.0378 1058 | vn -0.9195 -0.0972 0.3809 1059 | vn -0.2703 0.9562 0.1120 1060 | vn -0.8847 -0.2880 0.3665 1061 | vn -0.4384 0.8802 0.1816 1062 | vn -0.2901 -0.9562 0.0382 1063 | vn -0.9868 0.0972 0.1299 1064 | vn -0.0980 0.9951 0.0129 1065 | vn -0.0980 -0.9951 0.0129 1066 | vn -0.9868 -0.0972 0.1299 1067 | vn -0.2901 0.9562 0.0382 1068 | vn -0.9494 -0.2880 0.1250 1069 | vn -0.4705 0.8802 0.0619 1070 | vn -0.8760 -0.4683 0.1153 1071 | vn -0.6322 0.7703 0.0832 1072 | vn -0.7690 -0.6311 0.1012 1073 | vn -0.7690 0.6311 0.1012 1074 | vn -0.6322 -0.7703 0.0832 1075 | vn -0.8760 0.4683 0.1153 1076 | vn -0.4705 -0.8802 0.0619 1077 | vn -0.9494 0.2880 0.1250 1078 | vn -0.6322 0.7703 -0.0832 1079 | vn -0.7690 -0.6311 -0.1012 1080 | vn -0.7690 0.6311 -0.1012 1081 | vn -0.6322 -0.7703 -0.0832 1082 | vn -0.8760 0.4683 -0.1153 1083 | vn -0.4705 -0.8802 -0.0619 1084 | vn -0.9494 0.2880 -0.1250 1085 | vn -0.2901 -0.9562 -0.0382 1086 | vn -0.9868 0.0972 -0.1299 1087 | vn -0.0980 0.9951 -0.0129 1088 | vn -0.0980 -0.9951 -0.0129 1089 | vn -0.9868 -0.0972 -0.1299 1090 | vn -0.2901 0.9562 -0.0382 1091 | vn -0.9494 -0.2880 -0.1250 1092 | vn -0.4705 0.8802 -0.0619 1093 | vn -0.8760 -0.4683 -0.1153 1094 | vn -0.9195 0.0972 -0.3809 1095 | vn -0.0913 0.9951 -0.0378 1096 | vn -0.0913 -0.9951 -0.0378 1097 | vn -0.9195 -0.0972 -0.3809 1098 | vn -0.2703 0.9562 -0.1120 1099 | vn -0.8847 -0.2880 -0.3665 1100 | vn -0.4384 0.8802 -0.1816 1101 | vn -0.8163 -0.4683 -0.3381 1102 | vn -0.5891 0.7703 -0.2440 1103 | vn -0.7166 -0.6311 -0.2968 1104 | vn -0.7166 0.6311 -0.2968 1105 | vn -0.5891 -0.7703 -0.2440 1106 | vn -0.8163 0.4683 -0.3381 1107 | vn -0.4384 -0.8802 -0.1816 1108 | vn -0.8847 0.2880 -0.3665 1109 | vn -0.2703 -0.9562 -0.1120 1110 | vn -0.6154 -0.6311 -0.4722 1111 | vn -0.6154 0.6311 -0.4722 1112 | vn -0.5059 -0.7703 -0.3882 1113 | vn -0.7010 0.4683 -0.5379 1114 | vn -0.3765 -0.8802 -0.2889 1115 | vn -0.7597 0.2880 -0.5830 1116 | vn -0.2321 -0.9562 -0.1781 1117 | vn -0.7896 0.0972 -0.6059 1118 | vn -0.0784 0.9951 -0.0602 1119 | vn -0.0784 -0.9951 -0.0602 1120 | vn -0.7896 -0.0972 -0.6059 1121 | vn -0.2321 0.9562 -0.1781 1122 | vn -0.7597 -0.2880 -0.5830 1123 | vn -0.3765 0.8802 -0.2889 1124 | vn -0.7010 -0.4683 -0.5379 1125 | vn -0.5059 0.7703 -0.3882 1126 | vn -0.0602 -0.9951 -0.0784 1127 | vn -0.6059 -0.0972 -0.7896 1128 | vn -0.1781 0.9562 -0.2321 1129 | vn -0.5830 -0.2880 -0.7597 1130 | vn -0.2889 0.8802 -0.3765 1131 | vn -0.5379 -0.4683 -0.7010 1132 | vn -0.3882 0.7703 -0.5059 1133 | vn -0.4722 -0.6311 -0.6154 1134 | vn -0.4722 0.6311 -0.6154 1135 | vn -0.3882 -0.7703 -0.5059 1136 | vn -0.5379 0.4683 -0.7010 1137 | vn -0.2889 -0.8802 -0.3765 1138 | vn -0.5830 0.2880 -0.7597 1139 | vn -0.1781 -0.9562 -0.2321 1140 | vn -0.6059 0.0972 -0.7896 1141 | vn -0.0602 0.9951 -0.0784 1142 | vn -0.2440 -0.7703 -0.5891 1143 | vn -0.3381 0.4683 -0.8163 1144 | vn -0.1816 -0.8802 -0.4384 1145 | vn -0.3665 0.2880 -0.8847 1146 | vn -0.1120 -0.9562 -0.2703 1147 | vn -0.3809 0.0972 -0.9195 1148 | vn -0.0378 0.9951 -0.0913 1149 | vn -0.0378 -0.9951 -0.0913 1150 | vn -0.3809 -0.0972 -0.9195 1151 | vn -0.1120 0.9562 -0.2703 1152 | vn -0.3665 -0.2880 -0.8847 1153 | vn -0.1816 0.8802 -0.4384 1154 | vn -0.3381 -0.4683 -0.8163 1155 | vn -0.2440 0.7703 -0.5891 1156 | vn -0.2968 -0.6311 -0.7166 1157 | vn -0.2968 0.6311 -0.7166 1158 | vn -0.0382 0.9562 -0.2901 1159 | vn -0.1250 -0.2880 -0.9494 1160 | vn -0.0619 0.8802 -0.4705 1161 | vn -0.1153 -0.4683 -0.8760 1162 | vn -0.0832 0.7703 -0.6322 1163 | vn -0.1012 -0.6311 -0.7690 1164 | vn -0.1012 0.6311 -0.7690 1165 | vn -0.0832 -0.7703 -0.6322 1166 | vn -0.1153 0.4683 -0.8760 1167 | vn -0.0619 -0.8802 -0.4705 1168 | vn -0.1250 0.2880 -0.9494 1169 | vn -0.0382 -0.9562 -0.2901 1170 | vn -0.1299 0.0972 -0.9868 1171 | vn -0.0129 0.9951 -0.0980 1172 | vn -0.0129 -0.9951 -0.0980 1173 | vn -0.1299 -0.0972 -0.9868 1174 | usemtl None 1175 | s off 1176 | f 355/1/1 9/2/1 10/3/1 1177 | f 358/4/2 18/5/2 359/6/2 1178 | f 356/7/3 10/3/3 11/8/3 1179 | f 359/6/4 19/9/4 360/10/4 1180 | f 357/11/5 11/8/5 12/12/5 1181 | f 360/10/6 20/13/6 361/14/6 1182 | f 3/15/7 12/12/7 13/16/7 1183 | f 361/14/8 21/17/8 362/18/8 1184 | f 3/15/9 14/19/9 4/20/9 1185 | f 354/21/10 202/22/10 7/23/10 1186 | f 263/24/11 362/18/11 21/17/11 1187 | f 5/25/12 14/19/12 15/26/12 1188 | f 1/27/13 7/23/13 8/28/13 1189 | f 5/25/14 16/29/14 6/30/14 1190 | f 1/27/15 9/2/15 2/31/15 1191 | f 6/30/16 17/32/16 358/4/16 1192 | f 15/26/17 31/33/17 16/29/17 1193 | f 8/28/18 24/34/18 9/2/18 1194 | f 16/29/19 32/35/19 17/32/19 1195 | f 9/2/20 25/36/20 10/3/20 1196 | f 18/5/21 32/35/21 33/37/21 1197 | f 10/3/22 26/38/22 11/8/22 1198 | f 19/9/23 33/37/23 34/39/23 1199 | f 11/8/24 27/40/24 12/12/24 1200 | f 19/9/25 35/41/25 20/13/25 1201 | f 12/12/26 28/42/26 13/16/26 1202 | f 20/13/27 36/43/27 21/17/27 1203 | f 13/16/28 29/44/28 14/19/28 1204 | f 7/23/29 202/45/29 22/46/29 1205 | f 263/47/30 21/17/30 36/43/30 1206 | f 15/26/31 29/44/31 30/48/31 1207 | f 7/23/32 23/49/32 8/28/32 1208 | f 34/39/33 50/50/33 35/41/33 1209 | f 28/42/34 42/51/34 43/52/34 1210 | f 35/41/35 51/53/35 36/43/35 1211 | f 28/42/36 44/54/36 29/44/36 1212 | f 22/46/37 202/55/37 37/56/37 1213 | f 263/57/38 36/43/38 51/53/38 1214 | f 30/48/39 44/54/39 45/58/39 1215 | f 22/46/40 38/59/40 23/49/40 1216 | f 30/48/41 46/60/41 31/33/41 1217 | f 23/49/42 39/61/42 24/34/42 1218 | f 31/33/43 47/62/43 32/35/43 1219 | f 24/34/44 40/63/44 25/36/44 1220 | f 33/37/45 47/62/45 48/64/45 1221 | f 25/36/46 41/65/46 26/38/46 1222 | f 33/37/47 49/66/47 34/39/47 1223 | f 26/38/48 42/51/48 27/40/48 1224 | f 47/62/49 61/67/49 62/68/49 1225 | f 39/61/50 55/69/50 40/63/50 1226 | f 48/64/51 62/68/51 63/70/51 1227 | f 40/63/52 56/71/52 41/65/52 1228 | f 48/64/53 64/72/53 49/66/53 1229 | f 41/65/54 57/73/54 42/51/54 1230 | f 49/66/55 65/74/55 50/50/55 1231 | f 43/52/56 57/73/56 58/75/56 1232 | f 51/53/57 65/74/57 66/76/57 1233 | f 44/54/58 58/75/58 59/77/58 1234 | f 37/56/59 202/78/59 52/79/59 1235 | f 263/80/60 51/53/60 66/76/60 1236 | f 44/54/61 60/81/61 45/58/61 1237 | f 37/56/62 53/82/62 38/59/62 1238 | f 45/58/63 61/67/63 46/60/63 1239 | f 38/59/64 54/83/64 39/61/64 1240 | f 66/76/65 80/84/65 81/85/65 1241 | f 59/77/66 73/86/66 74/87/66 1242 | f 52/79/67 202/88/67 67/89/67 1243 | f 263/90/68 66/76/68 81/85/68 1244 | f 59/77/69 75/91/69 60/81/69 1245 | f 52/79/70 68/92/70 53/82/70 1246 | f 60/81/71 76/93/71 61/67/71 1247 | f 53/82/72 69/94/72 54/83/72 1248 | f 62/68/73 76/93/73 77/95/73 1249 | f 54/83/74 70/96/74 55/69/74 1250 | f 63/70/75 77/95/75 78/97/75 1251 | f 55/69/76 71/98/76 56/71/76 1252 | f 64/72/77 78/97/77 79/99/77 1253 | f 56/71/78 72/100/78 57/73/78 1254 | f 65/74/79 79/99/79 80/84/79 1255 | f 58/75/80 72/100/80 73/86/80 1256 | f 69/94/81 85/101/81 70/96/81 1257 | f 78/97/82 92/102/82 93/103/82 1258 | f 70/96/83 86/104/83 71/98/83 1259 | f 79/99/84 93/103/84 94/105/84 1260 | f 71/98/85 87/106/85 72/100/85 1261 | f 80/84/86 94/105/86 95/107/86 1262 | f 73/86/87 87/106/87 88/108/87 1263 | f 81/85/88 95/107/88 96/109/88 1264 | f 74/87/89 88/108/89 89/110/89 1265 | f 67/89/90 202/111/90 82/112/90 1266 | f 263/113/91 81/85/91 96/109/91 1267 | f 74/87/92 90/114/92 75/91/92 1268 | f 67/89/93 83/115/93 68/92/93 1269 | f 75/91/94 91/116/94 76/93/94 1270 | f 68/92/95 84/117/95 69/94/95 1271 | f 77/95/96 91/116/96 92/102/96 1272 | f 89/110/97 103/118/97 104/119/97 1273 | f 82/112/98 202/120/98 97/121/98 1274 | f 263/122/99 96/109/99 111/123/99 1275 | f 89/110/100 105/124/100 90/114/100 1276 | f 82/112/101 98/125/101 83/115/101 1277 | f 90/114/102 106/126/102 91/116/102 1278 | f 83/115/103 99/127/103 84/117/103 1279 | f 92/102/104 106/126/104 107/128/104 1280 | f 84/117/105 100/129/105 85/101/105 1281 | f 93/103/106 107/128/106 108/130/106 1282 | f 85/101/107 101/131/107 86/104/107 1283 | f 94/105/108 108/130/108 109/132/108 1284 | f 86/104/109 102/133/109 87/106/109 1285 | f 94/105/110 110/134/110 95/107/110 1286 | f 87/106/111 103/118/111 88/108/111 1287 | f 96/109/112 110/134/112 111/123/112 1288 | f 108/130/113 122/135/113 123/136/113 1289 | f 100/129/114 116/137/114 101/131/114 1290 | f 109/132/115 123/136/115 124/138/115 1291 | f 101/131/116 117/139/116 102/133/116 1292 | f 109/132/117 125/140/117 110/134/117 1293 | f 102/133/118 118/141/118 103/118/118 1294 | f 111/123/119 125/140/119 126/142/119 1295 | f 103/118/120 119/143/120 104/119/120 1296 | f 97/121/121 202/144/121 112/145/121 1297 | f 263/146/122 111/123/122 126/142/122 1298 | f 105/124/123 119/143/123 120/147/123 1299 | f 97/121/124 113/148/124 98/125/124 1300 | f 105/124/125 121/149/125 106/126/125 1301 | f 98/125/126 114/150/126 99/127/126 1302 | f 107/128/127 121/149/127 122/135/127 1303 | f 99/127/128 115/151/128 100/129/128 1304 | f 112/145/129 202/152/129 127/153/129 1305 | f 263/154/130 126/142/130 141/155/130 1306 | f 120/147/131 134/156/131 135/157/131 1307 | f 112/145/132 128/158/132 113/148/132 1308 | f 120/147/133 136/159/133 121/149/133 1309 | f 113/148/134 129/160/134 114/150/134 1310 | f 122/135/135 136/159/135 137/161/135 1311 | f 114/150/136 130/162/136 115/151/136 1312 | f 123/136/137 137/161/137 138/163/137 1313 | f 115/151/138 131/164/138 116/137/138 1314 | f 124/138/139 138/163/139 139/165/139 1315 | f 116/137/140 132/166/140 117/139/140 1316 | f 124/138/141 140/167/141 125/140/141 1317 | f 118/141/142 132/166/142 133/168/142 1318 | f 126/142/143 140/167/143 141/155/143 1319 | f 118/141/144 134/156/144 119/143/144 1320 | f 130/162/145 146/169/145 131/164/145 1321 | f 138/163/146 154/170/146 139/165/146 1322 | f 131/164/147 147/171/147 132/166/147 1323 | f 140/167/148 154/170/148 155/172/148 1324 | f 133/168/149 147/171/149 148/173/149 1325 | f 141/155/150 155/172/150 156/174/150 1326 | f 133/168/151 149/175/151 134/156/151 1327 | f 127/153/152 202/176/152 142/177/152 1328 | f 263/178/153 141/155/153 156/174/153 1329 | f 134/156/154 150/179/154 135/157/154 1330 | f 127/153/155 143/180/155 128/158/155 1331 | f 135/157/156 151/181/156 136/159/156 1332 | f 128/158/157 144/182/157 129/160/157 1333 | f 137/161/158 151/181/158 152/183/158 1334 | f 129/160/159 145/184/159 130/162/159 1335 | f 138/163/160 152/183/160 153/185/160 1336 | f 149/175/161 165/186/161 150/179/161 1337 | f 142/177/162 158/187/162 143/180/162 1338 | f 150/179/163 166/188/163 151/181/163 1339 | f 143/180/164 159/189/164 144/182/164 1340 | f 152/183/165 166/188/165 167/190/165 1341 | f 144/182/166 160/191/166 145/184/166 1342 | f 153/185/167 167/190/167 168/192/167 1343 | f 145/184/168 161/193/168 146/169/168 1344 | f 154/170/169 168/192/169 169/194/169 1345 | f 146/169/170 162/195/170 147/171/170 1346 | f 155/172/171 169/194/171 170/196/171 1347 | f 148/173/172 162/195/172 163/197/172 1348 | f 156/174/173 170/196/173 171/198/173 1349 | f 149/175/174 163/197/174 164/199/174 1350 | f 142/177/175 202/200/175 157/201/175 1351 | f 263/202/176 156/174/176 171/198/176 1352 | f 169/194/177 183/203/177 184/204/177 1353 | f 161/193/178 177/205/178 162/195/178 1354 | f 170/196/179 184/204/179 185/206/179 1355 | f 163/197/180 177/205/180 178/207/180 1356 | f 171/198/181 185/206/181 186/208/181 1357 | f 164/199/182 178/207/182 179/209/182 1358 | f 157/201/183 202/210/183 172/211/183 1359 | f 263/212/184 171/198/184 186/208/184 1360 | f 165/186/185 179/209/185 180/213/185 1361 | f 157/201/186 173/214/186 158/187/186 1362 | f 165/186/187 181/215/187 166/188/187 1363 | f 158/187/188 174/216/188 159/189/188 1364 | f 166/188/189 182/217/189 167/190/189 1365 | f 159/189/190 175/218/190 160/191/190 1366 | f 168/192/191 182/217/191 183/203/191 1367 | f 160/191/192 176/219/192 161/193/192 1368 | f 180/213/193 196/220/193 181/215/193 1369 | f 173/214/194 189/221/194 174/216/194 1370 | f 182/217/195 196/220/195 197/222/195 1371 | f 174/216/196 190/223/196 175/218/196 1372 | f 183/203/197 197/222/197 198/224/197 1373 | f 175/218/198 191/225/198 176/219/198 1374 | f 183/203/199 199/226/199 184/204/199 1375 | f 176/219/200 192/227/200 177/205/200 1376 | f 185/206/201 199/226/201 200/228/201 1377 | f 178/207/202 192/227/202 193/229/202 1378 | f 186/208/203 200/228/203 201/230/203 1379 | f 178/207/204 194/231/204 179/209/204 1380 | f 172/211/205 202/232/205 187/233/205 1381 | f 263/234/206 186/208/206 201/230/206 1382 | f 180/213/207 194/231/207 195/235/207 1383 | f 172/211/208 188/236/208 173/214/208 1384 | f 200/228/209 215/237/209 216/238/209 1385 | f 193/229/210 208/239/210 209/240/210 1386 | f 201/230/211 216/238/211 217/241/211 1387 | f 193/229/212 210/242/212 194/231/212 1388 | f 187/233/213 202/243/213 203/244/213 1389 | f 263/245/214 201/230/214 217/241/214 1390 | f 195/235/215 210/242/215 211/246/215 1391 | f 188/236/216 203/244/216 204/247/216 1392 | f 195/235/217 212/248/217 196/220/217 1393 | f 188/236/218 205/249/218 189/221/218 1394 | f 196/220/219 213/250/219 197/222/219 1395 | f 189/221/220 206/251/220 190/223/220 1396 | f 198/224/221 213/250/221 214/252/221 1397 | f 190/223/222 207/253/222 191/225/222 1398 | f 198/224/223 215/237/223 199/226/223 1399 | f 191/225/224 208/239/224 192/227/224 1400 | f 204/247/225 220/254/225 205/249/225 1401 | f 212/248/226 228/255/226 213/250/226 1402 | f 205/249/227 221/256/227 206/251/227 1403 | f 214/252/228 228/255/228 229/257/228 1404 | f 206/251/229 222/258/229 207/253/229 1405 | f 214/252/230 230/259/230 215/237/230 1406 | f 207/253/231 223/260/231 208/239/231 1407 | f 216/238/232 230/259/232 231/261/232 1408 | f 209/240/233 223/260/233 224/262/233 1409 | f 217/241/234 231/261/234 232/263/234 1410 | f 209/240/235 225/264/235 210/242/235 1411 | f 203/244/236 202/265/236 218/266/236 1412 | f 263/267/237 217/241/237 232/263/237 1413 | f 211/246/238 225/264/238 226/268/238 1414 | f 203/244/239 219/269/239 204/247/239 1415 | f 211/246/240 227/270/240 212/248/240 1416 | f 224/262/241 238/271/241 239/272/241 1417 | f 232/263/242 246/273/242 247/274/242 1418 | f 224/262/243 240/275/243 225/264/243 1419 | f 218/266/244 202/276/244 233/277/244 1420 | f 263/278/245 232/263/245 247/274/245 1421 | f 226/268/246 240/275/246 241/279/246 1422 | f 218/266/247 234/280/247 219/269/247 1423 | f 226/268/248 242/281/248 227/270/248 1424 | f 219/269/249 235/282/249 220/254/249 1425 | f 227/270/250 243/283/250 228/255/250 1426 | f 220/254/251 236/284/251 221/256/251 1427 | f 229/257/252 243/283/252 244/285/252 1428 | f 221/256/253 237/286/253 222/258/253 1429 | f 229/257/254 245/287/254 230/259/254 1430 | f 222/258/255 238/271/255 223/260/255 1431 | f 231/261/256 245/287/256 246/273/256 1432 | f 242/281/257 258/288/257 243/283/257 1433 | f 235/282/258 251/289/258 236/284/258 1434 | f 243/283/259 259/290/259 244/285/259 1435 | f 236/284/260 252/291/260 237/286/260 1436 | f 245/287/261 259/290/261 260/292/261 1437 | f 237/286/262 253/293/262 238/271/262 1438 | f 246/273/263 260/292/263 261/294/263 1439 | f 239/272/264 253/293/264 254/295/264 1440 | f 247/274/265 261/294/265 262/296/265 1441 | f 239/272/266 255/297/266 240/275/266 1442 | f 233/277/267 202/298/267 248/299/267 1443 | f 263/300/268 247/274/268 262/296/268 1444 | f 241/279/269 255/297/269 256/301/269 1445 | f 233/277/270 249/302/270 234/280/270 1446 | f 241/279/271 257/303/271 242/281/271 1447 | f 234/280/272 250/304/272 235/282/272 1448 | f 262/296/273 277/305/273 278/306/273 1449 | f 254/295/274 271/307/274 255/297/274 1450 | f 248/299/275 202/308/275 264/309/275 1451 | f 263/310/276 262/296/276 278/306/276 1452 | f 256/301/277 271/307/277 272/311/277 1453 | f 248/299/278 265/312/278 249/302/278 1454 | f 256/301/279 273/313/279 257/303/279 1455 | f 249/302/280 266/314/280 250/304/280 1456 | f 257/303/281 274/315/281 258/288/281 1457 | f 251/289/282 266/314/282 267/316/282 1458 | f 258/288/283 275/317/283 259/290/283 1459 | f 252/291/284 267/316/284 268/318/284 1460 | f 259/290/285 276/319/285 260/292/285 1461 | f 252/291/286 269/320/286 253/293/286 1462 | f 261/294/287 276/319/287 277/305/287 1463 | f 254/295/288 269/320/288 270/321/288 1464 | f 266/322/289 282/323/289 267/324/289 1465 | f 274/325/290 290/326/290 275/327/290 1466 | f 268/328/291 282/323/291 283/329/291 1467 | f 275/327/292 291/330/292 276/331/292 1468 | f 268/328/293 284/332/293 269/333/293 1469 | f 277/334/294 291/330/294 292/335/294 1470 | f 270/336/295 284/332/295 285/337/295 1471 | f 278/338/296 292/335/296 293/339/296 1472 | f 270/336/297 286/340/297 271/341/297 1473 | f 264/342/298 202/343/298 279/344/298 1474 | f 263/345/299 278/338/299 293/339/299 1475 | f 272/346/300 286/340/300 287/347/300 1476 | f 264/342/301 280/348/301 265/349/301 1477 | f 272/346/302 288/350/302 273/351/302 1478 | f 265/349/303 281/352/303 266/322/303 1479 | f 273/351/304 289/353/304 274/325/304 1480 | f 285/337/305 301/354/305 286/340/305 1481 | f 279/344/306 202/355/306 294/356/306 1482 | f 263/357/307 293/339/307 308/358/307 1483 | f 287/347/308 301/354/308 302/359/308 1484 | f 279/344/309 295/360/309 280/348/309 1485 | f 287/347/310 303/361/310 288/350/310 1486 | f 280/348/311 296/362/311 281/352/311 1487 | f 288/350/312 304/363/312 289/353/312 1488 | f 281/352/313 297/364/313 282/323/313 1489 | f 289/353/314 305/365/314 290/326/314 1490 | f 283/329/315 297/364/315 298/366/315 1491 | f 291/330/316 305/365/316 306/367/316 1492 | f 283/329/317 299/368/317 284/332/317 1493 | f 292/335/318 306/367/318 307/369/318 1494 | f 285/337/319 299/368/319 300/370/319 1495 | f 293/339/320 307/369/320 308/358/320 1496 | f 304/363/321 320/371/321 305/365/321 1497 | f 298/366/322 312/372/322 313/373/322 1498 | f 305/365/323 321/374/323 306/367/323 1499 | f 298/366/324 314/375/324 299/368/324 1500 | f 307/369/325 321/374/325 322/376/325 1501 | f 300/370/326 314/375/326 315/377/326 1502 | f 308/358/327 322/376/327 323/378/327 1503 | f 300/370/328 316/379/328 301/354/328 1504 | f 294/356/329 202/380/329 309/381/329 1505 | f 263/382/330 308/358/330 323/378/330 1506 | f 302/359/331 316/379/331 317/383/331 1507 | f 295/360/332 309/381/332 310/384/332 1508 | f 302/359/333 318/385/333 303/361/333 1509 | f 295/360/334 311/386/334 296/362/334 1510 | f 303/361/335 319/387/335 304/363/335 1511 | f 296/362/336 312/372/336 297/364/336 1512 | f 263/388/337 323/378/337 338/389/337 1513 | f 317/383/338 331/390/338 332/391/338 1514 | f 310/384/339 324/392/339 325/393/339 1515 | f 317/383/340 333/394/340 318/385/340 1516 | f 310/384/341 326/395/341 311/386/341 1517 | f 318/385/342 334/396/342 319/387/342 1518 | f 311/386/343 327/397/343 312/372/343 1519 | f 319/387/344 335/398/344 320/371/344 1520 | f 313/373/345 327/397/345 328/399/345 1521 | f 321/374/346 335/398/346 336/400/346 1522 | f 313/373/347 329/401/347 314/375/347 1523 | f 322/376/348 336/400/348 337/402/348 1524 | f 315/377/349 329/401/349 330/403/349 1525 | f 323/378/350 337/402/350 338/389/350 1526 | f 315/377/351 331/390/351 316/379/351 1527 | f 309/381/352 202/404/352 324/392/352 1528 | f 336/400/353 350/405/353 351/406/353 1529 | f 328/399/354 344/407/354 329/401/354 1530 | f 337/402/355 351/406/355 352/408/355 1531 | f 330/403/356 344/407/356 345/409/356 1532 | f 338/389/357 352/408/357 353/410/357 1533 | f 330/403/358 346/411/358 331/390/358 1534 | f 324/392/359 202/412/359 339/413/359 1535 | f 263/414/360 338/389/360 353/410/360 1536 | f 332/391/361 346/411/361 347/415/361 1537 | f 325/393/362 339/413/362 340/416/362 1538 | f 332/391/363 348/417/363 333/394/363 1539 | f 325/393/364 341/418/364 326/395/364 1540 | f 333/394/365 349/419/365 334/396/365 1541 | f 326/395/366 342/420/366 327/397/366 1542 | f 334/396/367 350/405/367 335/398/367 1543 | f 327/397/368 343/421/368 328/399/368 1544 | f 340/416/369 354/21/369 1/27/369 1545 | f 347/415/370 6/30/370 348/417/370 1546 | f 341/418/371 1/27/371 2/31/371 1547 | f 348/417/372 358/4/372 349/419/372 1548 | f 342/420/373 2/31/373 355/1/373 1549 | f 350/405/374 358/4/374 359/6/374 1550 | f 342/420/375 356/7/375 343/421/375 1551 | f 351/406/376 359/6/376 360/10/376 1552 | f 343/421/377 357/11/377 344/407/377 1553 | f 352/408/378 360/10/378 361/14/378 1554 | f 345/409/379 357/11/379 3/15/379 1555 | f 352/408/380 362/18/380 353/410/380 1556 | f 345/409/381 4/20/381 346/411/381 1557 | f 339/413/382 202/422/382 354/21/382 1558 | f 263/423/383 353/410/383 362/18/383 1559 | f 347/415/384 4/20/384 5/25/384 1560 | f 355/1/1 2/31/1 9/2/1 1561 | f 358/4/2 17/32/2 18/5/2 1562 | f 356/7/3 355/1/3 10/3/3 1563 | f 359/6/4 18/5/4 19/9/4 1564 | f 357/11/5 356/7/5 11/8/5 1565 | f 360/10/6 19/9/6 20/13/6 1566 | f 3/15/7 357/11/7 12/12/7 1567 | f 361/14/8 20/13/8 21/17/8 1568 | f 3/15/9 13/16/9 14/19/9 1569 | f 5/25/12 4/20/12 14/19/12 1570 | f 1/27/13 354/21/13 7/23/13 1571 | f 5/25/14 15/26/14 16/29/14 1572 | f 1/27/15 8/28/15 9/2/15 1573 | f 6/30/16 16/29/16 17/32/16 1574 | f 15/26/17 30/48/17 31/33/17 1575 | f 8/28/18 23/49/18 24/34/18 1576 | f 16/29/19 31/33/19 32/35/19 1577 | f 9/2/20 24/34/20 25/36/20 1578 | f 18/5/21 17/32/21 32/35/21 1579 | f 10/3/22 25/36/22 26/38/22 1580 | f 19/9/23 18/5/23 33/37/23 1581 | f 11/8/24 26/38/24 27/40/24 1582 | f 19/9/25 34/39/25 35/41/25 1583 | f 12/12/26 27/40/26 28/42/26 1584 | f 20/13/27 35/41/27 36/43/27 1585 | f 13/16/28 28/42/28 29/44/28 1586 | f 15/26/31 14/19/31 29/44/31 1587 | f 7/23/32 22/46/32 23/49/32 1588 | f 34/39/33 49/66/33 50/50/33 1589 | f 28/42/34 27/40/34 42/51/34 1590 | f 35/41/35 50/50/35 51/53/35 1591 | f 28/42/36 43/52/36 44/54/36 1592 | f 30/48/39 29/44/39 44/54/39 1593 | f 22/46/40 37/56/40 38/59/40 1594 | f 30/48/41 45/58/41 46/60/41 1595 | f 23/49/42 38/59/42 39/61/42 1596 | f 31/33/43 46/60/43 47/62/43 1597 | f 24/34/44 39/61/44 40/63/44 1598 | f 33/37/45 32/35/45 47/62/45 1599 | f 25/36/46 40/63/46 41/65/46 1600 | f 33/37/47 48/64/47 49/66/47 1601 | f 26/38/48 41/65/48 42/51/48 1602 | f 47/62/49 46/60/49 61/67/49 1603 | f 39/61/50 54/83/50 55/69/50 1604 | f 48/64/51 47/62/51 62/68/51 1605 | f 40/63/52 55/69/52 56/71/52 1606 | f 48/64/53 63/70/53 64/72/53 1607 | f 41/65/54 56/71/54 57/73/54 1608 | f 49/66/55 64/72/55 65/74/55 1609 | f 43/52/56 42/51/56 57/73/56 1610 | f 51/53/57 50/50/57 65/74/57 1611 | f 44/54/58 43/52/58 58/75/58 1612 | f 44/54/61 59/77/61 60/81/61 1613 | f 37/56/62 52/79/62 53/82/62 1614 | f 45/58/63 60/81/63 61/67/63 1615 | f 38/59/64 53/82/64 54/83/64 1616 | f 66/76/65 65/74/65 80/84/65 1617 | f 59/77/66 58/75/66 73/86/66 1618 | f 59/77/69 74/87/69 75/91/69 1619 | f 52/79/70 67/89/70 68/92/70 1620 | f 60/81/71 75/91/71 76/93/71 1621 | f 53/82/72 68/92/72 69/94/72 1622 | f 62/68/73 61/67/73 76/93/73 1623 | f 54/83/74 69/94/74 70/96/74 1624 | f 63/70/75 62/68/75 77/95/75 1625 | f 55/69/76 70/96/76 71/98/76 1626 | f 64/72/77 63/70/77 78/97/77 1627 | f 56/71/78 71/98/78 72/100/78 1628 | f 65/74/79 64/72/79 79/99/79 1629 | f 58/75/80 57/73/80 72/100/80 1630 | f 69/94/81 84/117/81 85/101/81 1631 | f 78/97/82 77/95/82 92/102/82 1632 | f 70/96/83 85/101/83 86/104/83 1633 | f 79/99/84 78/97/84 93/103/84 1634 | f 71/98/85 86/104/85 87/106/85 1635 | f 80/84/86 79/99/86 94/105/86 1636 | f 73/86/87 72/100/87 87/106/87 1637 | f 81/85/88 80/84/88 95/107/88 1638 | f 74/87/89 73/86/89 88/108/89 1639 | f 74/87/92 89/110/92 90/114/92 1640 | f 67/89/93 82/112/93 83/115/93 1641 | f 75/91/94 90/114/94 91/116/94 1642 | f 68/92/95 83/115/95 84/117/95 1643 | f 77/95/96 76/93/96 91/116/96 1644 | f 89/110/97 88/108/97 103/118/97 1645 | f 89/110/100 104/119/100 105/124/100 1646 | f 82/112/101 97/121/101 98/125/101 1647 | f 90/114/102 105/124/102 106/126/102 1648 | f 83/115/103 98/125/103 99/127/103 1649 | f 92/102/104 91/116/104 106/126/104 1650 | f 84/117/105 99/127/105 100/129/105 1651 | f 93/103/106 92/102/106 107/128/106 1652 | f 85/101/107 100/129/107 101/131/107 1653 | f 94/105/108 93/103/108 108/130/108 1654 | f 86/104/109 101/131/109 102/133/109 1655 | f 94/105/110 109/132/110 110/134/110 1656 | f 87/106/111 102/133/111 103/118/111 1657 | f 96/109/112 95/107/112 110/134/112 1658 | f 108/130/113 107/128/113 122/135/113 1659 | f 100/129/114 115/151/114 116/137/114 1660 | f 109/132/115 108/130/115 123/136/115 1661 | f 101/131/116 116/137/116 117/139/116 1662 | f 109/132/117 124/138/117 125/140/117 1663 | f 102/133/118 117/139/118 118/141/118 1664 | f 111/123/119 110/134/119 125/140/119 1665 | f 103/118/120 118/141/120 119/143/120 1666 | f 105/124/123 104/119/123 119/143/123 1667 | f 97/121/124 112/145/124 113/148/124 1668 | f 105/124/125 120/147/125 121/149/125 1669 | f 98/125/126 113/148/126 114/150/126 1670 | f 107/128/127 106/126/127 121/149/127 1671 | f 99/127/128 114/150/128 115/151/128 1672 | f 120/147/131 119/143/131 134/156/131 1673 | f 112/145/132 127/153/132 128/158/132 1674 | f 120/147/133 135/157/133 136/159/133 1675 | f 113/148/134 128/158/134 129/160/134 1676 | f 122/135/135 121/149/135 136/159/135 1677 | f 114/150/136 129/160/136 130/162/136 1678 | f 123/136/137 122/135/137 137/161/137 1679 | f 115/151/138 130/162/138 131/164/138 1680 | f 124/138/139 123/136/139 138/163/139 1681 | f 116/137/140 131/164/140 132/166/140 1682 | f 124/138/141 139/165/141 140/167/141 1683 | f 118/141/142 117/139/142 132/166/142 1684 | f 126/142/143 125/140/143 140/167/143 1685 | f 118/141/144 133/168/144 134/156/144 1686 | f 130/162/145 145/184/145 146/169/145 1687 | f 138/163/146 153/185/146 154/170/146 1688 | f 131/164/147 146/169/147 147/171/147 1689 | f 140/167/148 139/165/148 154/170/148 1690 | f 133/168/149 132/166/149 147/171/149 1691 | f 141/155/150 140/167/150 155/172/150 1692 | f 133/168/151 148/173/151 149/175/151 1693 | f 134/156/154 149/175/154 150/179/154 1694 | f 127/153/155 142/177/155 143/180/155 1695 | f 135/157/156 150/179/156 151/181/156 1696 | f 128/158/157 143/180/157 144/182/157 1697 | f 137/161/158 136/159/158 151/181/158 1698 | f 129/160/159 144/182/159 145/184/159 1699 | f 138/163/160 137/161/160 152/183/160 1700 | f 149/175/161 164/199/161 165/186/161 1701 | f 142/177/162 157/201/162 158/187/162 1702 | f 150/179/163 165/186/163 166/188/163 1703 | f 143/180/164 158/187/164 159/189/164 1704 | f 152/183/165 151/181/165 166/188/165 1705 | f 144/182/166 159/189/166 160/191/166 1706 | f 153/185/167 152/183/167 167/190/167 1707 | f 145/184/168 160/191/168 161/193/168 1708 | f 154/170/169 153/185/169 168/192/169 1709 | f 146/169/170 161/193/170 162/195/170 1710 | f 155/172/171 154/170/171 169/194/171 1711 | f 148/173/172 147/171/172 162/195/172 1712 | f 156/174/173 155/172/173 170/196/173 1713 | f 149/175/174 148/173/174 163/197/174 1714 | f 169/194/177 168/192/177 183/203/177 1715 | f 161/193/178 176/219/178 177/205/178 1716 | f 170/196/179 169/194/179 184/204/179 1717 | f 163/197/180 162/195/180 177/205/180 1718 | f 171/198/181 170/196/181 185/206/181 1719 | f 164/199/182 163/197/182 178/207/182 1720 | f 165/186/185 164/199/185 179/209/185 1721 | f 157/201/186 172/211/186 173/214/186 1722 | f 165/186/187 180/213/187 181/215/187 1723 | f 158/187/188 173/214/188 174/216/188 1724 | f 166/188/189 181/215/189 182/217/189 1725 | f 159/189/190 174/216/190 175/218/190 1726 | f 168/192/191 167/190/191 182/217/191 1727 | f 160/191/192 175/218/192 176/219/192 1728 | f 180/213/193 195/235/193 196/220/193 1729 | f 173/214/194 188/236/194 189/221/194 1730 | f 182/217/195 181/215/195 196/220/195 1731 | f 174/216/196 189/221/196 190/223/196 1732 | f 183/203/197 182/217/197 197/222/197 1733 | f 175/218/198 190/223/198 191/225/198 1734 | f 183/203/199 198/224/199 199/226/199 1735 | f 176/219/200 191/225/200 192/227/200 1736 | f 185/206/201 184/204/201 199/226/201 1737 | f 178/207/202 177/205/202 192/227/202 1738 | f 186/208/203 185/206/203 200/228/203 1739 | f 178/207/204 193/229/204 194/231/204 1740 | f 180/213/207 179/209/207 194/231/207 1741 | f 172/211/208 187/233/208 188/236/208 1742 | f 200/228/209 199/226/209 215/237/209 1743 | f 193/229/210 192/227/210 208/239/210 1744 | f 201/230/211 200/228/211 216/238/211 1745 | f 193/229/212 209/240/212 210/242/212 1746 | f 195/235/215 194/231/215 210/242/215 1747 | f 188/236/216 187/233/216 203/244/216 1748 | f 195/235/217 211/246/217 212/248/217 1749 | f 188/236/218 204/247/218 205/249/218 1750 | f 196/220/219 212/248/219 213/250/219 1751 | f 189/221/220 205/249/220 206/251/220 1752 | f 198/224/221 197/222/221 213/250/221 1753 | f 190/223/222 206/251/222 207/253/222 1754 | f 198/224/223 214/252/223 215/237/223 1755 | f 191/225/224 207/253/224 208/239/224 1756 | f 204/247/225 219/269/225 220/254/225 1757 | f 212/248/226 227/270/226 228/255/226 1758 | f 205/249/227 220/254/227 221/256/227 1759 | f 214/252/228 213/250/228 228/255/228 1760 | f 206/251/229 221/256/229 222/258/229 1761 | f 214/252/230 229/257/230 230/259/230 1762 | f 207/253/231 222/258/231 223/260/231 1763 | f 216/238/232 215/237/232 230/259/232 1764 | f 209/240/233 208/239/233 223/260/233 1765 | f 217/241/234 216/238/234 231/261/234 1766 | f 209/240/235 224/262/235 225/264/235 1767 | f 211/246/238 210/242/238 225/264/238 1768 | f 203/244/239 218/266/239 219/269/239 1769 | f 211/246/240 226/268/240 227/270/240 1770 | f 224/262/241 223/260/241 238/271/241 1771 | f 232/263/242 231/261/242 246/273/242 1772 | f 224/262/243 239/272/243 240/275/243 1773 | f 226/268/246 225/264/246 240/275/246 1774 | f 218/266/247 233/277/247 234/280/247 1775 | f 226/268/248 241/279/248 242/281/248 1776 | f 219/269/249 234/280/249 235/282/249 1777 | f 227/270/250 242/281/250 243/283/250 1778 | f 220/254/251 235/282/251 236/284/251 1779 | f 229/257/252 228/255/252 243/283/252 1780 | f 221/256/253 236/284/253 237/286/253 1781 | f 229/257/254 244/285/254 245/287/254 1782 | f 222/258/255 237/286/255 238/271/255 1783 | f 231/261/256 230/259/256 245/287/256 1784 | f 242/281/257 257/303/257 258/288/257 1785 | f 235/282/258 250/304/258 251/289/258 1786 | f 243/283/259 258/288/259 259/290/259 1787 | f 236/284/260 251/289/260 252/291/260 1788 | f 245/287/261 244/285/261 259/290/261 1789 | f 237/286/262 252/291/262 253/293/262 1790 | f 246/273/263 245/287/263 260/292/263 1791 | f 239/272/264 238/271/264 253/293/264 1792 | f 247/274/265 246/273/265 261/294/265 1793 | f 239/272/266 254/295/266 255/297/266 1794 | f 241/279/269 240/275/269 255/297/269 1795 | f 233/277/270 248/299/270 249/302/270 1796 | f 241/279/271 256/301/271 257/303/271 1797 | f 234/280/272 249/302/272 250/304/272 1798 | f 262/296/273 261/294/273 277/305/273 1799 | f 254/295/274 270/321/274 271/307/274 1800 | f 256/301/277 255/297/277 271/307/277 1801 | f 248/299/278 264/309/278 265/312/278 1802 | f 256/301/279 272/311/279 273/313/279 1803 | f 249/302/280 265/312/280 266/314/280 1804 | f 257/303/281 273/313/281 274/315/281 1805 | f 251/289/282 250/304/282 266/314/282 1806 | f 258/288/283 274/315/283 275/317/283 1807 | f 252/291/284 251/289/284 267/316/284 1808 | f 259/290/285 275/317/285 276/319/285 1809 | f 252/291/286 268/318/286 269/320/286 1810 | f 261/294/287 260/292/287 276/319/287 1811 | f 254/295/288 253/293/288 269/320/288 1812 | f 266/322/289 281/352/289 282/323/289 1813 | f 274/325/290 289/353/290 290/326/290 1814 | f 268/328/291 267/324/291 282/323/291 1815 | f 275/327/292 290/326/292 291/330/292 1816 | f 268/328/293 283/329/293 284/332/293 1817 | f 277/334/294 276/331/294 291/330/294 1818 | f 270/336/295 269/333/295 284/332/295 1819 | f 278/338/296 277/334/296 292/335/296 1820 | f 270/336/297 285/337/297 286/340/297 1821 | f 272/346/300 271/341/300 286/340/300 1822 | f 264/342/301 279/344/301 280/348/301 1823 | f 272/346/302 287/347/302 288/350/302 1824 | f 265/349/303 280/348/303 281/352/303 1825 | f 273/351/304 288/350/304 289/353/304 1826 | f 285/337/305 300/370/305 301/354/305 1827 | f 287/347/308 286/340/308 301/354/308 1828 | f 279/344/309 294/356/309 295/360/309 1829 | f 287/347/310 302/359/310 303/361/310 1830 | f 280/348/311 295/360/311 296/362/311 1831 | f 288/350/312 303/361/312 304/363/312 1832 | f 281/352/313 296/362/313 297/364/313 1833 | f 289/353/314 304/363/314 305/365/314 1834 | f 283/329/315 282/323/315 297/364/315 1835 | f 291/330/316 290/326/316 305/365/316 1836 | f 283/329/317 298/366/317 299/368/317 1837 | f 292/335/318 291/330/318 306/367/318 1838 | f 285/337/319 284/332/319 299/368/319 1839 | f 293/339/320 292/335/320 307/369/320 1840 | f 304/363/321 319/387/321 320/371/321 1841 | f 298/366/322 297/364/322 312/372/322 1842 | f 305/365/323 320/371/323 321/374/323 1843 | f 298/366/324 313/373/324 314/375/324 1844 | f 307/369/325 306/367/325 321/374/325 1845 | f 300/370/326 299/368/326 314/375/326 1846 | f 308/358/327 307/369/327 322/376/327 1847 | f 300/370/328 315/377/328 316/379/328 1848 | f 302/359/331 301/354/331 316/379/331 1849 | f 295/360/332 294/356/332 309/381/332 1850 | f 302/359/333 317/383/333 318/385/333 1851 | f 295/360/334 310/384/334 311/386/334 1852 | f 303/361/335 318/385/335 319/387/335 1853 | f 296/362/336 311/386/336 312/372/336 1854 | f 317/383/338 316/379/338 331/390/338 1855 | f 310/384/339 309/381/339 324/392/339 1856 | f 317/383/340 332/391/340 333/394/340 1857 | f 310/384/341 325/393/341 326/395/341 1858 | f 318/385/342 333/394/342 334/396/342 1859 | f 311/386/343 326/395/343 327/397/343 1860 | f 319/387/344 334/396/344 335/398/344 1861 | f 313/373/345 312/372/345 327/397/345 1862 | f 321/374/346 320/371/346 335/398/346 1863 | f 313/373/347 328/399/347 329/401/347 1864 | f 322/376/348 321/374/348 336/400/348 1865 | f 315/377/349 314/375/349 329/401/349 1866 | f 323/378/350 322/376/350 337/402/350 1867 | f 315/377/351 330/403/351 331/390/351 1868 | f 336/400/353 335/398/353 350/405/353 1869 | f 328/399/354 343/421/354 344/407/354 1870 | f 337/402/355 336/400/355 351/406/355 1871 | f 330/403/356 329/401/356 344/407/356 1872 | f 338/389/357 337/402/357 352/408/357 1873 | f 330/403/358 345/409/358 346/411/358 1874 | f 332/391/361 331/390/361 346/411/361 1875 | f 325/393/362 324/392/362 339/413/362 1876 | f 332/391/363 347/415/363 348/417/363 1877 | f 325/393/364 340/416/364 341/418/364 1878 | f 333/394/365 348/417/365 349/419/365 1879 | f 326/395/366 341/418/366 342/420/366 1880 | f 334/396/367 349/419/367 350/405/367 1881 | f 327/397/368 342/420/368 343/421/368 1882 | f 340/416/369 339/413/369 354/21/369 1883 | f 347/415/370 5/25/370 6/30/370 1884 | f 341/418/371 340/416/371 1/27/371 1885 | f 348/417/372 6/30/372 358/4/372 1886 | f 342/420/373 341/418/373 2/31/373 1887 | f 350/405/374 349/419/374 358/4/374 1888 | f 342/420/375 355/1/375 356/7/375 1889 | f 351/406/376 350/405/376 359/6/376 1890 | f 343/421/377 356/7/377 357/11/377 1891 | f 352/408/378 351/406/378 360/10/378 1892 | f 345/409/379 344/407/379 357/11/379 1893 | f 352/408/380 361/14/380 362/18/380 1894 | f 345/409/381 3/15/381 4/20/381 1895 | f 347/415/384 346/411/384 4/20/384 1896 | -------------------------------------------------------------------------------- /assets/torus.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 1 3 | 4 | newmtl None 5 | Ns 500 6 | Ka 0.8 0.8 0.8 7 | Kd 0.8 0.8 0.8 8 | Ks 0.8 0.8 0.8 9 | d 1 10 | illum 2 11 | -------------------------------------------------------------------------------- /assets/torus.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.90.1 OBJ File: '' 2 | # www.blender.org 3 | mtllib Cone.mtl 4 | o Torus 5 | v 1.470000 0.000000 0.000000 6 | v 1.401673 0.255000 0.000000 7 | v 1.215000 0.441673 0.000000 8 | v 0.960000 0.510000 0.000000 9 | v 0.705000 0.441673 0.000000 10 | v 0.518327 0.255000 0.000000 11 | v 0.450000 0.000000 0.000000 12 | v 0.518327 -0.255000 0.000000 13 | v 0.705000 -0.441673 0.000000 14 | v 0.960000 -0.510000 0.000000 15 | v 1.215000 -0.441673 0.000000 16 | v 1.401673 -0.255000 0.000000 17 | v 1.189255 0.000000 -0.864044 18 | v 1.133977 0.255000 -0.823883 19 | v 0.982956 0.441673 -0.714159 20 | v 0.776656 0.510000 -0.564274 21 | v 0.570357 0.441673 -0.414389 22 | v 0.419336 0.255000 -0.304665 23 | v 0.364058 0.000000 -0.264504 24 | v 0.419336 -0.255000 -0.304665 25 | v 0.570357 -0.441673 -0.414389 26 | v 0.776656 -0.510000 -0.564274 27 | v 0.982956 -0.441673 -0.714159 28 | v 1.133977 -0.255000 -0.823883 29 | v 0.454255 0.000000 -1.398053 30 | v 0.433141 0.255000 -1.333070 31 | v 0.375456 0.441673 -1.155534 32 | v 0.296657 0.510000 -0.913014 33 | v 0.217857 0.441673 -0.670495 34 | v 0.160172 0.255000 -0.492959 35 | v 0.139058 0.000000 -0.427976 36 | v 0.160172 -0.255000 -0.492959 37 | v 0.217857 -0.441673 -0.670495 38 | v 0.296657 -0.510000 -0.913014 39 | v 0.375456 -0.441673 -1.155534 40 | v 0.433141 -0.255000 -1.333070 41 | v -0.454255 0.000000 -1.398053 42 | v -0.433141 0.255000 -1.333070 43 | v -0.375456 0.441673 -1.155534 44 | v -0.296656 0.510000 -0.913014 45 | v -0.217857 0.441673 -0.670495 46 | v -0.160172 0.255000 -0.492959 47 | v -0.139058 0.000000 -0.427976 48 | v -0.160172 -0.255000 -0.492959 49 | v -0.217857 -0.441673 -0.670495 50 | v -0.296656 -0.510000 -0.913014 51 | v -0.375456 -0.441673 -1.155534 52 | v -0.433141 -0.255000 -1.333070 53 | v -1.189255 0.000000 -0.864044 54 | v -1.133977 0.255000 -0.823882 55 | v -0.982956 0.441673 -0.714159 56 | v -0.776657 0.510000 -0.564274 57 | v -0.570357 0.441673 -0.414389 58 | v -0.419336 0.255000 -0.304665 59 | v -0.364058 0.000000 -0.264503 60 | v -0.419336 -0.255000 -0.304665 61 | v -0.570357 -0.441673 -0.414389 62 | v -0.776657 -0.510000 -0.564274 63 | v -0.982956 -0.441673 -0.714159 64 | v -1.133977 -0.255000 -0.823882 65 | v -1.470000 0.000000 -0.000000 66 | v -1.401673 0.255000 -0.000000 67 | v -1.215000 0.441673 -0.000000 68 | v -0.960000 0.510000 -0.000000 69 | v -0.705000 0.441673 -0.000000 70 | v -0.518327 0.255000 -0.000000 71 | v -0.450000 0.000000 -0.000000 72 | v -0.518327 -0.255000 -0.000000 73 | v -0.705000 -0.441673 -0.000000 74 | v -0.960000 -0.510000 -0.000000 75 | v -1.215000 -0.441673 -0.000000 76 | v -1.401673 -0.255000 -0.000000 77 | v -1.189255 0.000000 0.864044 78 | v -1.133977 0.255000 0.823882 79 | v -0.982956 0.441673 0.714159 80 | v -0.776657 0.510000 0.564274 81 | v -0.570357 0.441673 0.414389 82 | v -0.419336 0.255000 0.304665 83 | v -0.364058 0.000000 0.264503 84 | v -0.419336 -0.255000 0.304665 85 | v -0.570357 -0.441673 0.414389 86 | v -0.776657 -0.510000 0.564274 87 | v -0.982956 -0.441673 0.714159 88 | v -1.133977 -0.255000 0.823882 89 | v -0.454255 0.000000 1.398053 90 | v -0.433141 0.255000 1.333070 91 | v -0.375456 0.441673 1.155534 92 | v -0.296656 0.510000 0.913014 93 | v -0.217857 0.441673 0.670495 94 | v -0.160172 0.255000 0.492959 95 | v -0.139058 0.000000 0.427976 96 | v -0.160172 -0.255000 0.492959 97 | v -0.217857 -0.441673 0.670495 98 | v -0.296656 -0.510000 0.913014 99 | v -0.375456 -0.441673 1.155534 100 | v -0.433141 -0.255000 1.333070 101 | v 0.454255 0.000000 1.398053 102 | v 0.433141 0.255000 1.333070 103 | v 0.375456 0.441673 1.155534 104 | v 0.296657 0.510000 0.913014 105 | v 0.217857 0.441673 0.670495 106 | v 0.160172 0.255000 0.492959 107 | v 0.139058 0.000000 0.427976 108 | v 0.160172 -0.255000 0.492959 109 | v 0.217857 -0.441673 0.670495 110 | v 0.296657 -0.510000 0.913014 111 | v 0.375456 -0.441673 1.155534 112 | v 0.433141 -0.255000 1.333070 113 | v 1.189254 0.000000 0.864045 114 | v 1.133977 0.255000 0.823883 115 | v 0.982955 0.441673 0.714160 116 | v 0.776656 0.510000 0.564274 117 | v 0.570357 0.441673 0.414389 118 | v 0.419335 0.255000 0.304665 119 | v 0.364058 0.000000 0.264504 120 | v 0.419335 -0.255000 0.304665 121 | v 0.570357 -0.441673 0.414389 122 | v 0.776656 -0.510000 0.564274 123 | v 0.982955 -0.441673 0.714160 124 | v 1.133977 -0.255000 0.823883 125 | vt 0.600000 0.500000 126 | vt 0.700000 0.583333 127 | vt 0.600000 0.583333 128 | vt 0.600000 0.666667 129 | vt 0.700000 0.666667 130 | vt 0.600000 0.750000 131 | vt 0.700000 0.750000 132 | vt 0.600000 0.833333 133 | vt 0.700000 0.833333 134 | vt 0.600000 0.916667 135 | vt 0.700000 0.916667 136 | vt 0.600000 1.000000 137 | vt 0.700000 0.000000 138 | vt 0.600000 0.083333 139 | vt 0.600000 0.000000 140 | vt 0.700000 0.083333 141 | vt 0.600000 0.166667 142 | vt 0.700000 0.166667 143 | vt 0.600000 0.250000 144 | vt 0.700000 0.250000 145 | vt 0.600000 0.333333 146 | vt 0.700000 0.333333 147 | vt 0.600000 0.416667 148 | vt 0.700000 0.416667 149 | vt 0.800000 0.500000 150 | vt 0.700000 0.500000 151 | vt 0.800000 0.583333 152 | vt 0.800000 0.750000 153 | vt 0.800000 0.833333 154 | vt 0.800000 0.916667 155 | vt 0.700000 1.000000 156 | vt 0.800000 0.000000 157 | vt 0.800000 0.083333 158 | vt 0.800000 0.166667 159 | vt 0.800000 0.250000 160 | vt 0.800000 0.333333 161 | vt 0.800000 0.416667 162 | vt 0.900000 0.500000 163 | vt 0.900000 0.583333 164 | vt 0.800000 0.666667 165 | vt 0.900000 0.666667 166 | vt 0.900000 0.750000 167 | vt 0.900000 0.833333 168 | vt 0.900000 0.916667 169 | vt 0.800000 1.000000 170 | vt 0.900000 0.000000 171 | vt 0.900000 0.083333 172 | vt 0.900000 0.166667 173 | vt 0.900000 0.250000 174 | vt 0.900000 0.333333 175 | vt 0.900000 0.416667 176 | vt 1.000000 0.500000 177 | vt 1.000000 0.666667 178 | vt 1.000000 0.750000 179 | vt 1.000000 0.833333 180 | vt 1.000000 1.000000 181 | vt 0.900000 1.000000 182 | vt 1.000000 0.000000 183 | vt 1.000000 0.083333 184 | vt 1.000000 0.166667 185 | vt 1.000000 0.250000 186 | vt 1.000000 0.416667 187 | vt 0.100000 0.500000 188 | vt -0.000000 0.583333 189 | vt -0.000000 0.500000 190 | vt 0.100000 0.583333 191 | vt -0.000000 0.666667 192 | vt 0.100000 0.750000 193 | vt -0.000000 0.750000 194 | vt -0.000000 0.833333 195 | vt 0.100000 0.833333 196 | vt -0.000000 0.916667 197 | vt 0.100000 0.916667 198 | vt -0.000000 1.000000 199 | vt 0.100000 0.000000 200 | vt -0.000000 0.083333 201 | vt -0.000000 0.000000 202 | vt 0.100000 0.083333 203 | vt -0.000000 0.166667 204 | vt 0.100000 0.250000 205 | vt -0.000000 0.250000 206 | vt -0.000000 0.333333 207 | vt 0.100000 0.416667 208 | vt -0.000000 0.416667 209 | vt 0.200000 0.583333 210 | vt 0.100000 0.666667 211 | vt 0.200000 0.666667 212 | vt 0.200000 0.750000 213 | vt 0.200000 0.833333 214 | vt 0.200000 0.916667 215 | vt 0.100000 1.000000 216 | vt 0.200000 0.000000 217 | vt 0.200000 0.166667 218 | vt 0.100000 0.166667 219 | vt 0.200000 0.250000 220 | vt 0.100000 0.333333 221 | vt 0.200000 0.333333 222 | vt 0.200000 0.416667 223 | vt 0.200000 0.500000 224 | vt 0.300000 0.583333 225 | vt 0.300000 0.666667 226 | vt 0.300000 0.750000 227 | vt 0.300000 0.833333 228 | vt 0.300000 0.916667 229 | vt 0.200000 1.000000 230 | vt 0.300000 0.000000 231 | vt 0.200000 0.083333 232 | vt 0.300000 0.083333 233 | vt 0.300000 0.166667 234 | vt 0.300000 0.333333 235 | vt 0.300000 0.416667 236 | vt 0.400000 0.500000 237 | vt 0.300000 0.500000 238 | vt 0.400000 0.583333 239 | vt 0.400000 0.666667 240 | vt 0.400000 0.750000 241 | vt 0.400000 0.833333 242 | vt 0.400000 0.916667 243 | vt 0.300000 1.000000 244 | vt 0.400000 0.000000 245 | vt 0.400000 0.083333 246 | vt 0.400000 0.166667 247 | vt 0.300000 0.250000 248 | vt 0.400000 0.250000 249 | vt 0.400000 0.333333 250 | vt 0.400000 0.416667 251 | vt 0.500000 0.500000 252 | vt 0.500000 0.666667 253 | vt 0.500000 0.750000 254 | vt 0.500000 0.833333 255 | vt 0.500000 0.916667 256 | vt 0.400000 1.000000 257 | vt 0.500000 0.000000 258 | vt 0.500000 0.083333 259 | vt 0.500000 0.166667 260 | vt 0.500000 0.333333 261 | vt 0.500000 0.583333 262 | vt 0.500000 1.000000 263 | vt 0.500000 0.250000 264 | vt 0.500000 0.416667 265 | vt 1.000000 0.583333 266 | vt 1.000000 0.916667 267 | vt 1.000000 0.333333 268 | vn 0.9216 0.2469 -0.2994 269 | vn 0.6892 0.6892 -0.2239 270 | vn 0.2579 0.9625 -0.0838 271 | vn -0.2579 0.9625 0.0838 272 | vn -0.6892 0.6892 0.2239 273 | vn -0.9216 0.2469 0.2994 274 | vn -0.9216 -0.2469 0.2994 275 | vn -0.6892 -0.6892 0.2239 276 | vn -0.2579 -0.9625 0.0838 277 | vn 0.2579 -0.9625 -0.0838 278 | vn 0.6892 -0.6892 -0.2239 279 | vn 0.9216 -0.2469 -0.2994 280 | vn 0.5696 0.2469 -0.7840 281 | vn 0.4259 0.6892 -0.5862 282 | vn 0.1594 0.9625 -0.2194 283 | vn -0.1594 0.9625 0.2194 284 | vn -0.4259 0.6892 0.5862 285 | vn -0.5696 0.2469 0.7840 286 | vn -0.5696 -0.2469 0.7840 287 | vn -0.4259 -0.6892 0.5862 288 | vn -0.1594 -0.9625 0.2194 289 | vn 0.1594 -0.9625 -0.2194 290 | vn 0.4259 -0.6892 -0.5862 291 | vn 0.5696 -0.2469 -0.7840 292 | vn 0.0000 0.2469 -0.9690 293 | vn 0.0000 0.6892 -0.7246 294 | vn 0.0000 0.9625 -0.2712 295 | vn 0.0000 0.9625 0.2712 296 | vn 0.0000 0.6892 0.7246 297 | vn 0.0000 0.2469 0.9690 298 | vn 0.0000 -0.2469 0.9690 299 | vn 0.0000 -0.6892 0.7246 300 | vn 0.0000 -0.9625 0.2712 301 | vn 0.0000 -0.9625 -0.2712 302 | vn 0.0000 -0.6892 -0.7246 303 | vn 0.0000 -0.2469 -0.9690 304 | vn -0.5696 0.2469 -0.7840 305 | vn -0.4259 0.6892 -0.5862 306 | vn -0.1594 0.9625 -0.2194 307 | vn 0.1594 0.9625 0.2194 308 | vn 0.4259 0.6892 0.5862 309 | vn 0.5696 0.2469 0.7840 310 | vn 0.5696 -0.2469 0.7840 311 | vn 0.4259 -0.6892 0.5862 312 | vn 0.1594 -0.9625 0.2194 313 | vn -0.1594 -0.9625 -0.2194 314 | vn -0.4259 -0.6892 -0.5862 315 | vn -0.5696 -0.2469 -0.7840 316 | vn -0.9216 0.2469 -0.2994 317 | vn -0.6892 0.6892 -0.2239 318 | vn -0.2579 0.9625 -0.0838 319 | vn 0.2579 0.9625 0.0838 320 | vn 0.6892 0.6892 0.2239 321 | vn 0.9216 0.2469 0.2994 322 | vn 0.9216 -0.2469 0.2994 323 | vn 0.6892 -0.6892 0.2239 324 | vn 0.2579 -0.9625 0.0838 325 | vn -0.2579 -0.9625 -0.0838 326 | vn -0.6892 -0.6892 -0.2239 327 | vn -0.9216 -0.2469 -0.2994 328 | usemtl None 329 | s off 330 | f 1/1/1 14/2/1 2/3/1 331 | f 14/2/2 3/4/2 2/3/2 332 | f 15/5/3 4/6/3 3/4/3 333 | f 16/7/4 5/8/4 4/6/4 334 | f 17/9/5 6/10/5 5/8/5 335 | f 18/11/6 7/12/6 6/10/6 336 | f 19/13/7 8/14/7 7/15/7 337 | f 20/16/8 9/17/8 8/14/8 338 | f 21/18/9 10/19/9 9/17/9 339 | f 22/20/10 11/21/10 10/19/10 340 | f 23/22/11 12/23/11 11/21/11 341 | f 24/24/12 1/1/12 12/23/12 342 | f 25/25/13 14/2/13 13/26/13 343 | f 26/27/14 15/5/14 14/2/14 344 | f 15/5/15 28/28/15 16/7/15 345 | f 28/28/16 17/9/16 16/7/16 346 | f 29/29/17 18/11/17 17/9/17 347 | f 30/30/18 19/31/18 18/11/18 348 | f 31/32/19 20/16/19 19/13/19 349 | f 32/33/20 21/18/20 20/16/20 350 | f 33/34/21 22/20/21 21/18/21 351 | f 34/35/22 23/22/22 22/20/22 352 | f 35/36/23 24/24/23 23/22/23 353 | f 36/37/24 13/26/24 24/24/24 354 | f 37/38/25 26/27/25 25/25/25 355 | f 38/39/26 27/40/26 26/27/26 356 | f 39/41/27 28/28/27 27/40/27 357 | f 40/42/28 29/29/28 28/28/28 358 | f 41/43/29 30/30/29 29/29/29 359 | f 42/44/30 31/45/30 30/30/30 360 | f 43/46/31 32/33/31 31/32/31 361 | f 44/47/32 33/34/32 32/33/32 362 | f 45/48/33 34/35/33 33/34/33 363 | f 46/49/34 35/36/34 34/35/34 364 | f 47/50/35 36/37/35 35/36/35 365 | f 48/51/36 25/25/36 36/37/36 366 | f 49/52/37 38/39/37 37/38/37 367 | f 38/39/38 51/53/38 39/41/38 368 | f 39/41/39 52/54/39 40/42/39 369 | f 52/54/40 41/43/40 40/42/40 370 | f 53/55/41 42/44/41 41/43/41 371 | f 42/44/42 55/56/42 43/57/42 372 | f 55/58/43 44/47/43 43/46/43 373 | f 56/59/44 45/48/44 44/47/44 374 | f 57/60/45 46/49/45 45/48/45 375 | f 58/61/46 47/50/46 46/49/46 376 | f 47/50/47 60/62/47 48/51/47 377 | f 60/62/48 37/38/48 48/51/48 378 | f 61/63/49 50/64/49 49/65/49 379 | f 62/66/50 51/67/50 50/64/50 380 | f 51/67/51 64/68/51 52/69/51 381 | f 64/68/52 53/70/52 52/69/52 382 | f 65/71/53 54/72/53 53/70/53 383 | f 66/73/54 55/74/54 54/72/54 384 | f 67/75/55 56/76/55 55/77/55 385 | f 68/78/56 57/79/56 56/76/56 386 | f 57/79/57 70/80/57 58/81/57 387 | f 70/80/58 59/82/58 58/81/58 388 | f 59/82/59 72/83/59 60/84/59 389 | f 72/83/60 49/65/60 60/84/60 390 | f 61/63/6 74/85/6 62/66/6 391 | f 74/85/5 63/86/5 62/66/5 392 | f 75/87/4 64/68/4 63/86/4 393 | f 76/88/3 65/71/3 64/68/3 394 | f 77/89/2 66/73/2 65/71/2 395 | f 78/90/1 67/91/1 66/73/1 396 | f 79/92/12 68/78/12 67/75/12 397 | f 68/78/11 81/93/11 69/94/11 398 | f 81/93/10 70/80/10 69/94/10 399 | f 82/95/9 71/96/9 70/80/9 400 | f 83/97/8 72/83/8 71/96/8 401 | f 84/98/7 61/63/7 72/83/7 402 | f 73/99/18 86/100/18 74/85/18 403 | f 74/85/17 87/101/17 75/87/17 404 | f 87/101/16 76/88/16 75/87/16 405 | f 88/102/15 77/89/15 76/88/15 406 | f 89/103/14 78/90/14 77/89/14 407 | f 90/104/13 79/105/13 78/90/13 408 | f 91/106/24 80/107/24 79/92/24 409 | f 92/108/23 81/93/23 80/107/23 410 | f 93/109/22 82/95/22 81/93/22 411 | f 82/95/21 95/110/21 83/97/21 412 | f 83/97/20 96/111/20 84/98/20 413 | f 96/111/19 73/99/19 84/98/19 414 | f 97/112/30 86/100/30 85/113/30 415 | f 98/114/29 87/101/29 86/100/29 416 | f 99/115/28 88/102/28 87/101/28 417 | f 100/116/27 89/103/27 88/102/27 418 | f 101/117/26 90/104/26 89/103/26 419 | f 102/118/25 91/119/25 90/104/25 420 | f 103/120/36 92/108/36 91/106/36 421 | f 104/121/35 93/109/35 92/108/35 422 | f 105/122/34 94/123/34 93/109/34 423 | f 106/124/33 95/110/33 94/123/33 424 | f 107/125/32 96/111/32 95/110/32 425 | f 108/126/31 85/113/31 96/111/31 426 | f 109/127/42 98/114/42 97/112/42 427 | f 98/114/41 111/128/41 99/115/41 428 | f 111/128/40 100/116/40 99/115/40 429 | f 112/129/39 101/117/39 100/116/39 430 | f 113/130/38 102/118/38 101/117/38 431 | f 114/131/37 103/132/37 102/118/37 432 | f 115/133/48 104/121/48 103/120/48 433 | f 116/134/47 105/122/47 104/121/47 434 | f 117/135/46 106/124/46 105/122/46 435 | f 106/124/45 119/136/45 107/125/45 436 | f 119/136/44 108/126/44 107/125/44 437 | f 108/126/43 109/127/43 97/112/43 438 | f 1/1/54 110/137/54 109/127/54 439 | f 2/3/53 111/128/53 110/137/53 440 | f 3/4/52 112/129/52 111/128/52 441 | f 4/6/51 113/130/51 112/129/51 442 | f 5/8/50 114/131/50 113/130/50 443 | f 6/10/49 115/138/49 114/131/49 444 | f 7/15/60 116/134/60 115/133/60 445 | f 8/14/59 117/135/59 116/134/59 446 | f 9/17/58 118/139/58 117/135/58 447 | f 10/19/57 119/136/57 118/139/57 448 | f 11/21/56 120/140/56 119/136/56 449 | f 120/140/55 1/1/55 109/127/55 450 | f 1/1/1 13/26/1 14/2/1 451 | f 14/2/2 15/5/2 3/4/2 452 | f 15/5/3 16/7/3 4/6/3 453 | f 16/7/4 17/9/4 5/8/4 454 | f 17/9/5 18/11/5 6/10/5 455 | f 18/11/6 19/31/6 7/12/6 456 | f 19/13/7 20/16/7 8/14/7 457 | f 20/16/8 21/18/8 9/17/8 458 | f 21/18/9 22/20/9 10/19/9 459 | f 22/20/10 23/22/10 11/21/10 460 | f 23/22/11 24/24/11 12/23/11 461 | f 24/24/12 13/26/12 1/1/12 462 | f 25/25/13 26/27/13 14/2/13 463 | f 26/27/14 27/40/14 15/5/14 464 | f 15/5/15 27/40/15 28/28/15 465 | f 28/28/16 29/29/16 17/9/16 466 | f 29/29/17 30/30/17 18/11/17 467 | f 30/30/18 31/45/18 19/31/18 468 | f 31/32/19 32/33/19 20/16/19 469 | f 32/33/20 33/34/20 21/18/20 470 | f 33/34/21 34/35/21 22/20/21 471 | f 34/35/22 35/36/22 23/22/22 472 | f 35/36/23 36/37/23 24/24/23 473 | f 36/37/24 25/25/24 13/26/24 474 | f 37/38/25 38/39/25 26/27/25 475 | f 38/39/26 39/41/26 27/40/26 476 | f 39/41/27 40/42/27 28/28/27 477 | f 40/42/28 41/43/28 29/29/28 478 | f 41/43/29 42/44/29 30/30/29 479 | f 42/44/30 43/57/30 31/45/30 480 | f 43/46/31 44/47/31 32/33/31 481 | f 44/47/32 45/48/32 33/34/32 482 | f 45/48/33 46/49/33 34/35/33 483 | f 46/49/34 47/50/34 35/36/34 484 | f 47/50/35 48/51/35 36/37/35 485 | f 48/51/36 37/38/36 25/25/36 486 | f 49/52/37 50/141/37 38/39/37 487 | f 38/39/38 50/141/38 51/53/38 488 | f 39/41/39 51/53/39 52/54/39 489 | f 52/54/40 53/55/40 41/43/40 490 | f 53/55/41 54/142/41 42/44/41 491 | f 42/44/42 54/142/42 55/56/42 492 | f 55/58/43 56/59/43 44/47/43 493 | f 56/59/44 57/60/44 45/48/44 494 | f 57/60/45 58/61/45 46/49/45 495 | f 58/61/46 59/143/46 47/50/46 496 | f 47/50/47 59/143/47 60/62/47 497 | f 60/62/48 49/52/48 37/38/48 498 | f 61/63/49 62/66/49 50/64/49 499 | f 62/66/50 63/86/50 51/67/50 500 | f 51/67/51 63/86/51 64/68/51 501 | f 64/68/52 65/71/52 53/70/52 502 | f 65/71/53 66/73/53 54/72/53 503 | f 66/73/54 67/91/54 55/74/54 504 | f 67/75/55 68/78/55 56/76/55 505 | f 68/78/56 69/94/56 57/79/56 506 | f 57/79/57 69/94/57 70/80/57 507 | f 70/80/58 71/96/58 59/82/58 508 | f 59/82/59 71/96/59 72/83/59 509 | f 72/83/60 61/63/60 49/65/60 510 | f 61/63/6 73/99/6 74/85/6 511 | f 74/85/5 75/87/5 63/86/5 512 | f 75/87/4 76/88/4 64/68/4 513 | f 76/88/3 77/89/3 65/71/3 514 | f 77/89/2 78/90/2 66/73/2 515 | f 78/90/1 79/105/1 67/91/1 516 | f 79/92/12 80/107/12 68/78/12 517 | f 68/78/11 80/107/11 81/93/11 518 | f 81/93/10 82/95/10 70/80/10 519 | f 82/95/9 83/97/9 71/96/9 520 | f 83/97/8 84/98/8 72/83/8 521 | f 84/98/7 73/99/7 61/63/7 522 | f 73/99/18 85/113/18 86/100/18 523 | f 74/85/17 86/100/17 87/101/17 524 | f 87/101/16 88/102/16 76/88/16 525 | f 88/102/15 89/103/15 77/89/15 526 | f 89/103/14 90/104/14 78/90/14 527 | f 90/104/13 91/119/13 79/105/13 528 | f 91/106/24 92/108/24 80/107/24 529 | f 92/108/23 93/109/23 81/93/23 530 | f 93/109/22 94/123/22 82/95/22 531 | f 82/95/21 94/123/21 95/110/21 532 | f 83/97/20 95/110/20 96/111/20 533 | f 96/111/19 85/113/19 73/99/19 534 | f 97/112/30 98/114/30 86/100/30 535 | f 98/114/29 99/115/29 87/101/29 536 | f 99/115/28 100/116/28 88/102/28 537 | f 100/116/27 101/117/27 89/103/27 538 | f 101/117/26 102/118/26 90/104/26 539 | f 102/118/25 103/132/25 91/119/25 540 | f 103/120/36 104/121/36 92/108/36 541 | f 104/121/35 105/122/35 93/109/35 542 | f 105/122/34 106/124/34 94/123/34 543 | f 106/124/33 107/125/33 95/110/33 544 | f 107/125/32 108/126/32 96/111/32 545 | f 108/126/31 97/112/31 85/113/31 546 | f 109/127/42 110/137/42 98/114/42 547 | f 98/114/41 110/137/41 111/128/41 548 | f 111/128/40 112/129/40 100/116/40 549 | f 112/129/39 113/130/39 101/117/39 550 | f 113/130/38 114/131/38 102/118/38 551 | f 114/131/37 115/138/37 103/132/37 552 | f 115/133/48 116/134/48 104/121/48 553 | f 116/134/47 117/135/47 105/122/47 554 | f 117/135/46 118/139/46 106/124/46 555 | f 106/124/45 118/139/45 119/136/45 556 | f 119/136/44 120/140/44 108/126/44 557 | f 108/126/43 120/140/43 109/127/43 558 | f 1/1/54 2/3/54 110/137/54 559 | f 2/3/53 3/4/53 111/128/53 560 | f 3/4/52 4/6/52 112/129/52 561 | f 4/6/51 5/8/51 113/130/51 562 | f 5/8/50 6/10/50 114/131/50 563 | f 6/10/49 7/12/49 115/138/49 564 | f 7/15/60 8/14/60 116/134/60 565 | f 8/14/59 9/17/59 117/135/59 566 | f 9/17/58 10/19/58 118/139/58 567 | f 10/19/57 11/21/57 119/136/57 568 | f 11/21/56 12/23/56 120/140/56 569 | f 120/140/55 12/23/55 1/1/55 570 | -------------------------------------------------------------------------------- /assets/utahteapot.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 1 3 | 4 | newmtl Clear_Coat_Plastic 5 | Ns 96.078443 6 | Ka 1.000000 1.000000 1.000000 7 | Kd 0.727575 0.727575 0.727575 8 | Ks 0.027843 0.027843 0.027843 9 | Ke 0.000000 0.000000 0.000000 10 | Ni 1.000000 11 | d 1.000000 12 | illum 2 13 | -------------------------------------------------------------------------------- /engine/__pycache__/constants.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/3D-engine-from-scraph--pygame/b3ed330acd55026d93d95f243df3e10aad6f4779/engine/__pycache__/constants.cpython-39.pyc -------------------------------------------------------------------------------- /engine/__pycache__/event.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/3D-engine-from-scraph--pygame/b3ed330acd55026d93d95f243df3e10aad6f4779/engine/__pycache__/event.cpython-39.pyc -------------------------------------------------------------------------------- /engine/constants.py: -------------------------------------------------------------------------------- 1 | Size = 1000, 1000 2 | Width, Height = Size 3 | BackgroundColor = (0 , 0, 0) 4 | aspect = Height/Width #aspect ratio 5 | 6 | clipping = 1.5 7 | mouse_sensitivity = 200 8 | Zoffset = 7 9 | 10 | dim = 0.01 #the darkest spot on the screen 11 | 12 | #colors 13 | blue = (0, 0, 255) 14 | orange = (255, 160, 0) 15 | black = (0, 0, 0) 16 | white = (255, 255, 255) 17 | red = (255, 0, 0) 18 | green = (0, 255, 0) 19 | yellow = (0, 255, 255) 20 | 21 | # axis_offset = 50 22 | # axis_positions = { 23 | # "CENTER": (Width//2, Height//2), 24 | # "TOP-LEFT": (axis_offset, axis_offset), 25 | # "TOP-RIGHT": (Width-axis_offset, axis_offset), 26 | # "BOTTOM-LEFT": (axis_offset, Height-axis_offset), 27 | # "BOTTOM-RIGHT": (Width-axis_offset, Height-axis_offset) 28 | # } 29 | -------------------------------------------------------------------------------- /engine/event.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | from constants import * 3 | 4 | def HandleEvent(camera, deltaTime): 5 | running = True 6 | for event in pygame.event.get(): 7 | if event.type == pygame.QUIT: 8 | running = False 9 | if event.type == pygame.KEYDOWN: 10 | if event.key == pygame.K_ESCAPE: 11 | running = False 12 | if event.type == pygame.MOUSEMOTION: 13 | if pygame.mouse.get_pressed()[0]: 14 | x, y = event.rel 15 | x /= mouse_sensitivity 16 | y /= mouse_sensitivity 17 | camera.HandleMouseEvent(x, y, deltaTime) 18 | 19 | return running 20 | -------------------------------------------------------------------------------- /engine/main.py: -------------------------------------------------------------------------------- 1 | # subscribe to my youtube 2 | # https://www.youtube.com/c/Auctux 3 | import sys 4 | import pygame 5 | from pygame.locals import * 6 | from constants import * 7 | from event import HandleEvent 8 | from utils.vector import Vector3 9 | from utils.camera import Camera 10 | from utils.light import Light 11 | from utils.mesh.base import Mesh 12 | from utils.mesh.meshes import * 13 | from utils.mesh.spheres import * 14 | from utils.mesh.point import * 15 | from utils.matrix import * 16 | from utils.tools import * 17 | from utils.world import Scene 18 | 19 | pygame.init() 20 | # screen = pygame.display.set_mode(Size) 21 | flags = DOUBLEBUF 22 | screen = pygame.display.set_mode(Size, flags, 16) 23 | clock = pygame.time.Clock() 24 | fps = 60 25 | #mouse setup 26 | pygame.mouse.get_rel() 27 | pygame.mouse.set_visible(True) 28 | a = pygame.event.set_grab(False) 29 | 30 | #create mesh 31 | Deer = Mesh() 32 | Deer.triangles = LoadMesh("../assets/deer.obj",(186, 135, 89)) # load mesh triangles 33 | 34 | teapot = Mesh() 35 | teapot.triangles = LoadMesh("../assets/utahteapot.obj", (255, 255, 0)) 36 | 37 | cube = Mesh() 38 | cube.triangles = CubeTriangles((240,84,84)) 39 | cube.position = Vector3(5, -2, 0) 40 | 41 | sphere = Mesh() 42 | sphere.triangles = IcosphereTriangles((246,131,15), 2) 43 | sphere.position = Vector3(0, 0, 0) 44 | 45 | torus = Mesh() 46 | torus.triangles = LoadMesh("../assets/torus.obj", (56,147,147)) 47 | torus.position = Vector3(-3, -2, 0) 48 | 49 | # create scene and the world 50 | scene = Scene() 51 | #add object you want to display into the world 52 | scene.world.append(torus) 53 | scene.world.append(sphere) 54 | scene.world.append(cube) 55 | # scene.world.append(teapot) 56 | # scene.world.append(Deer) 57 | 58 | #camera setup 59 | camera = Camera(Vector3(0, 0, 0), 0.1, 1000.0, 75.0) 60 | camera.speed = 0.5 61 | camera.rotationSpeed = 0.8 62 | 63 | #light setup 64 | light = Light(Vector3(0.9, 0.9, -1)) 65 | hue = 0 66 | 67 | angle = 0 68 | moveLight = True 69 | run = True 70 | 71 | while run: 72 | screen.fill(BackgroundColor) 73 | clock.tick(fps) 74 | dt = clock.tick(fps)/100 75 | frameRate = clock.get_fps() 76 | pygame.display.set_caption(str(frameRate) + " fps") 77 | run = HandleEvent(camera, dt) 78 | hue = 0 79 | # handle input 80 | camera.HandleInput(dt) 81 | 82 | if moveLight == True and light != None: 83 | mx, my = pygame.mouse.get_pos() 84 | _x = translateValue( mx, 0, Width, -1, 1) 85 | _y = translateValue( my, 0, Height, -1, 1) 86 | light = Light(Vector3(-_x, -_y, -1)) 87 | 88 | # apply the transformation matrix here 89 | torus.transform = Matrix.rotation_x(angle) @ Matrix.scaling(1.9) 90 | cube.transform = Matrix.rotation_y(angle) @ Matrix.scaling(1.2) 91 | sphere.transform = Matrix.rotation_x(angle) @ ( 92 | Matrix.rotation_y(angle) @ Matrix.scaling(1.4) 93 | ) 94 | 95 | # display scene 96 | scene.update( 97 | dt = dt, 98 | camera=camera, 99 | light=light, 100 | screen=screen, 101 | showAxis=True, 102 | fill=True, 103 | wireframe=False, 104 | vertices=False, 105 | depth=True, 106 | clippingDebug=False, 107 | showNormals=False, 108 | radius=9, 109 | verticeColor=False, 110 | wireframeColor=(255, 255, 255), 111 | ChangingColor=hue) 112 | 113 | 114 | pygame.display.flip() 115 | angle += 0.01 116 | 117 | pygame.quit() 118 | sys.exit() 119 | -------------------------------------------------------------------------------- /engine/test.py: -------------------------------------------------------------------------------- 1 | # subscribe to my youtube 2 | # https://www.youtube.com/c/Auctux 3 | import sys 4 | import pygame 5 | from pygame.locals import * 6 | from constants import * 7 | from event import HandleEvent 8 | from utils.vector import Vector3 9 | from utils.camera import Camera 10 | from utils.light import Light 11 | from utils.mesh.base import Mesh 12 | from utils.mesh.meshes import * 13 | from utils.mesh.spheres import * 14 | from utils.mesh.point import * 15 | from utils.matrix import * 16 | from utils.tools import * 17 | from utils.world import Scene 18 | from random import randint 19 | pygame.init() 20 | # screen = pygame.display.set_mode(Size) 21 | flags = DOUBLEBUF 22 | screen = pygame.display.set_mode(Size, flags, 16) 23 | clock = pygame.time.Clock() 24 | fps = 60 25 | #mouse setup 26 | pygame.mouse.get_rel() 27 | pygame.mouse.set_visible(True) 28 | a = pygame.event.set_grab(False) 29 | 30 | # create scene and the world 31 | res = 3 32 | scene = Scene() 33 | 34 | for x in range(res): 35 | for y in range(res): 36 | for z in range(res): 37 | cube = Mesh() 38 | s = 5 39 | r = randint(10, 255) 40 | g = randint(10, 255) 41 | b = randint(10, 255) 42 | cube.triangles = CubeTriangles((r, g, b),Vector3(x * s, y * s, z * s), s) 43 | cube.position = Vector3(x * s, y * s, z * s) 44 | cube.transform = Matrix.scaling(0.1) 45 | scene.world.append(cube) 46 | 47 | #camera setup 48 | camera = Camera(Vector3(0, 0, 0), 0.1, 1000.0, 75.0) 49 | camera.speed = 0.5 50 | camera.rotationSpeed = 0.8 51 | 52 | #light setup 53 | light = Light(Vector3(0.9, 0.9, -1)) 54 | hue = 0 55 | 56 | angle = 0 57 | moveLight = True 58 | run = True 59 | 60 | while run: 61 | screen.fill(BackgroundColor) 62 | clock.tick(fps) 63 | dt = clock.tick(fps)/100 64 | frameRate = clock.get_fps() 65 | pygame.display.set_caption(str(frameRate) + " fps") 66 | run = HandleEvent(camera, dt) 67 | hue = 0 68 | # handle input 69 | camera.HandleInput(dt) 70 | 71 | if moveLight == True and light != None: 72 | mx, my = pygame.mouse.get_pos() 73 | _x = translateValue( mx, 0, Width, -1, 1) 74 | _y = translateValue( my, 0, Height, -1, 1) 75 | light = Light(Vector3(-_x, -_y, -1)) 76 | 77 | # apply the transformation matrix here 78 | # torus.transform = Matrix.rotation_x(angle) @ Matrix.scaling(1.9) 79 | # cube.transform = Matrix.rotation_y(angle) @ Matrix.scaling(1.2) 80 | # sphere.transform = Matrix.rotation_x(angle) @ ( 81 | # Matrix.rotation_y(angle) @ Matrix.scaling(1.4) 82 | # ) 83 | 84 | # display scene 85 | scene.update( 86 | dt = dt, 87 | camera=camera, 88 | light=light, 89 | screen=screen, 90 | showAxis=True, 91 | fill=True, 92 | wireframe=True, 93 | vertices=True, 94 | depth=True, 95 | clippingDebug=False, 96 | showNormals=False, 97 | radius=2, 98 | verticeColor=False, 99 | wireframeColor=(255, 255, 255), 100 | ChangingColor=hue) 101 | 102 | 103 | pygame.display.flip() 104 | angle += 0.01 105 | 106 | pygame.quit() 107 | sys.exit() 108 | -------------------------------------------------------------------------------- /engine/utils/__pycache__/camera.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/3D-engine-from-scraph--pygame/b3ed330acd55026d93d95f243df3e10aad6f4779/engine/utils/__pycache__/camera.cpython-39.pyc -------------------------------------------------------------------------------- /engine/utils/__pycache__/light.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/3D-engine-from-scraph--pygame/b3ed330acd55026d93d95f243df3e10aad6f4779/engine/utils/__pycache__/light.cpython-39.pyc -------------------------------------------------------------------------------- /engine/utils/__pycache__/matrix.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/3D-engine-from-scraph--pygame/b3ed330acd55026d93d95f243df3e10aad6f4779/engine/utils/__pycache__/matrix.cpython-39.pyc -------------------------------------------------------------------------------- /engine/utils/__pycache__/tools.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/3D-engine-from-scraph--pygame/b3ed330acd55026d93d95f243df3e10aad6f4779/engine/utils/__pycache__/tools.cpython-39.pyc -------------------------------------------------------------------------------- /engine/utils/__pycache__/transform.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/3D-engine-from-scraph--pygame/b3ed330acd55026d93d95f243df3e10aad6f4779/engine/utils/__pycache__/transform.cpython-39.pyc -------------------------------------------------------------------------------- /engine/utils/__pycache__/triangle.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/3D-engine-from-scraph--pygame/b3ed330acd55026d93d95f243df3e10aad6f4779/engine/utils/__pycache__/triangle.cpython-39.pyc -------------------------------------------------------------------------------- /engine/utils/__pycache__/vector.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/3D-engine-from-scraph--pygame/b3ed330acd55026d93d95f243df3e10aad6f4779/engine/utils/__pycache__/vector.cpython-39.pyc -------------------------------------------------------------------------------- /engine/utils/__pycache__/world.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/3D-engine-from-scraph--pygame/b3ed330acd55026d93d95f243df3e10aad6f4779/engine/utils/__pycache__/world.cpython-39.pyc -------------------------------------------------------------------------------- /engine/utils/camera.py: -------------------------------------------------------------------------------- 1 | from math import tan, pi 2 | import constants 3 | import utils.vector as vector 4 | from utils.matrix import Matrix 5 | import constants 6 | import pygame 7 | 8 | class Camera: 9 | def __init__(self, position, near, far, fov): 10 | self.position = position 11 | self.near = near 12 | self.far = far 13 | self.fov = fov 14 | self.yaw = 0 15 | self.phi = 0 16 | self.tangent = 1.0 / tan(self.fov * 0.5 / 180 * pi) 17 | self.direction = vector.Vector3() 18 | self.up = vector.Vector3() 19 | self.transform = Matrix.identity() 20 | self.target = position 21 | self.speed = 0.1 22 | self.rotationSpeed = 1.5 23 | self.temp = vector.Vector3() 24 | 25 | def HandleInput(self, dt): 26 | keys = pygame.key.get_pressed() 27 | delta = self.speed * dt 28 | 29 | if keys[pygame.K_UP]: 30 | self.position.y += delta 31 | if keys[pygame.K_DOWN]: 32 | self.position.y -= delta 33 | if keys[pygame.K_RIGHT]: 34 | self.position.x -= delta 35 | if keys[pygame.K_LEFT]: 36 | self.position.x += delta 37 | 38 | self.temp = self.target * delta 39 | 40 | if keys[pygame.K_w]: #zoom in 41 | self.position += self.temp 42 | if keys[pygame.K_s]: #zoom out 43 | self.position -= self.temp 44 | if keys[pygame.K_a]: 45 | self.yaw -= 0.04 46 | if keys[pygame.K_d]: 47 | self.yaw += 0.04 48 | 49 | def HandleMouseEvent(self, x, y, deltaTime): 50 | # not finished 51 | self.yaw += x 52 | 53 | def projection(self) -> Matrix: 54 | """Compute the projection Matrix corresponding to the current camera position 55 | and orientation. 56 | Returns: 57 | Matrix - the projection matrix 58 | """ 59 | matrix = Matrix() 60 | matrix.val = [ 61 | [constants.aspect * self.tangent, 0.0, 0.0, 0.0], 62 | [0.0, self.tangent, 0.0, 0.0], 63 | [0.0, 0.0, self.far / (self.far - self.near), 1], 64 | [0.0, 0.0, (-self.far * self.near) / (self.far - self.near), 0.0], 65 | ] 66 | return matrix 67 | -------------------------------------------------------------------------------- /engine/utils/light.py: -------------------------------------------------------------------------------- 1 | from utils.vector import Normalize 2 | 3 | class Light: # simple directional light 4 | def __init__(self, position): 5 | self.position = position 6 | self.direction = Normalize(self.position) 7 | -------------------------------------------------------------------------------- /engine/utils/matrix.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | from constants import * 3 | from utils.vector import * 4 | from math import cos, sin 5 | from copy import deepcopy 6 | from math import cos, sin 7 | from utils.vector import Vector3 8 | 9 | 10 | class Matrix: 11 | """Represents a matrix with standard operation support.""" 12 | 13 | def __init__(self, r: int = 4, c: int = 4): 14 | """Initialize new Matrix with r rows and c cols. Sets all values to 0.0.""" 15 | self.val = [[0.0 for _ in range(c)] for _ in range(r)] 16 | 17 | def __repr__(self) -> str: 18 | """repr(self)""" 19 | return f"matrix->{self.val}" 20 | 21 | @property 22 | def row(self) -> int: 23 | """The number of rows in self.""" 24 | return len(self.val) 25 | 26 | @property 27 | def col(self) -> int: 28 | """The number of cols in self.""" 29 | return len(self.val[0]) 30 | 31 | @classmethod 32 | def from_vector(cls, vec: Vector3) -> Matrix: 33 | """Construct a new Matrix formed by a Vector3. 34 | Returns: 35 | Matrix - matrix with size 1, 4 populated by vec's x, y, z, w. 36 | """ 37 | rv = cls(1, 4) 38 | rv.val = [[vec.x, vec.y, vec.z, vec.w]] 39 | return rv 40 | 41 | @classmethod 42 | def rotation_x(cls, angle: float) -> Matrix: 43 | """Construct a matrix which performs a rotation around the x-axis by angle radians 44 | Arguments: 45 | angle - angle in radians to for xrotmat to represent. 46 | Returns: 47 | Matrix - angle rotation around x-axis Matrix 48 | """ 49 | matrix = cls() 50 | matrix.val = [ 51 | [1, 0.0, 0.0, 0.0], 52 | [0.0, cos(angle), sin(angle), 0.0], 53 | [0.0, -sin(angle), cos(angle), 0.0], 54 | [0.0, 0.0, 0.0, 1], 55 | ] 56 | return matrix 57 | 58 | @classmethod 59 | def rotation_y(cls, angle: float) -> Matrix: 60 | """Construct a matrix which performs a rotation around the y-axis by angle radians 61 | Arguments: 62 | angle - angle in radians to for yrotmat to represent. 63 | Returns: 64 | Matrix - angle rotation around y-axis Matrix 65 | """ 66 | matrix = cls() 67 | matrix.val = [ 68 | [cos(angle), 0.0, -sin(angle), 0.0], 69 | [0.0, 1, 0.0, 0.0], 70 | [sin(angle), 0.0, cos(angle), 0.0], 71 | [0.0, 0.0, 0.0, 1], 72 | ] 73 | return matrix 74 | 75 | @classmethod 76 | def rotation_z(cls, angle: float) -> Matrix: 77 | """Construct a matrix which performs a rotation around the z-axis by angle radians 78 | Arguments: 79 | angle - angle in radians to for zrotmat to represent. 80 | Returns: 81 | Matrix - angle rotation around z-axis Matrix 82 | """ 83 | matrix = cls() 84 | matrix.val = [ 85 | [cos(angle), sin(angle), 0.0, 0.0], 86 | [-sin(angle), cos(angle), 0.0, 0.0], 87 | [0.0, 0.0, 1, 0.0], 88 | [0.0, 0.0, 0.0, 1], 89 | ] 90 | return matrix 91 | 92 | @classmethod 93 | def scaling(cls, scale: float) -> Matrix: 94 | """Construct a scaling matrix for the given scale factor. 95 | Arguments: 96 | scale - float, the scale value for Matrix to be constructed for 97 | Returns: 98 | Matrix - the scaling Matrix 99 | """ 100 | matrix = cls() 101 | matrix.val = [ 102 | [scale, 0.0, 0.0, 0.0], 103 | [0.0, scale, 0.0, 0.0], 104 | [0.0, 0.0, scale, 0.0], 105 | [0.0, 0.0, 0.0, 1], 106 | ] 107 | return matrix 108 | 109 | @classmethod 110 | def identity(cls, size: int = 4) -> Matrix: 111 | """Construct an identity matrix of the given size. Defined as a square matrix 112 | with 1s on the main diagonal, and 0s elsewhere. 113 | Arguments: 114 | size - int, the size of the identity matrix. 115 | Returns: 116 | Matrix - the specified identity matrix. 117 | """ 118 | matrix = cls() 119 | matrix.val = [ 120 | [1.0 if i == j else 0.0 for j in range(size)] for i in range(size) 121 | ] 122 | return matrix 123 | 124 | @classmethod 125 | def translate(cls, position: Vector3) -> Matrix: 126 | """Construct a Matrix that performs a translation specified by the give 127 | position. 128 | Arguments: 129 | position - the Vector3 to construct translation matrix by. 130 | Returns: 131 | Matrix - the constructed translation Matrix. 132 | """ 133 | matrix = cls() 134 | matrix.val = [ 135 | [1, 0.0, 0.0, position.x], 136 | [0.0, 1, 0.0, position.y], 137 | [0.0, 0.0, 1, position.z], 138 | [0.0, 0.0, 0.0, 1], 139 | ] 140 | return matrix 141 | 142 | def __matmul__(self, other: Matrix) -> Matrix: 143 | """Support for self @ other, defined as matrix multiplication. 144 | Raises: 145 | ValueError - if self and other have incompatible dimensions. 146 | Returns: 147 | Matrix - product of self and other, size is self.row x other.col. 148 | """ 149 | if not isinstance(other, Matrix): 150 | return NotImplemented 151 | 152 | if self.col != other.row: 153 | raise ValueError( 154 | "Matrices incompatible for multiplication, got: " 155 | f"{(self.row, self.col)}, {(other.row, other.col)}" 156 | ) 157 | 158 | rv = Matrix(self.row, other.col) 159 | for x in range(self.row): 160 | for y in range(other.col): 161 | val = sum(self.val[x][z] * other.val[z][y] for z in range(self.col)) 162 | rv.val[x][y] = round(val, 5) 163 | 164 | return rv 165 | 166 | def transpose(self) -> Matrix: 167 | """Compute the transpose of self. Defined as the matrix formed by swapping the 168 | rows and cols of self. 169 | Returns: 170 | Matrix - transpose of self. 171 | """ 172 | rv = Matrix(self.row, self.col) 173 | for x in range(self.row): 174 | for y in range(self.col): 175 | rv.val[x][y] = self.val[y][x] 176 | return rv 177 | 178 | def submatrix(self, row: int, col: int) -> Matrix: 179 | """Form the matrix resulting from removing the specified row and col 180 | from self. 181 | Returns: 182 | Matrix - self without row or col. 183 | """ 184 | temp = deepcopy(self) 185 | del temp.val[row] 186 | for i in range(self.row): 187 | del temp.val[i][col] 188 | 189 | return temp 190 | 191 | def det(self) -> float: 192 | """Calculate the determinant of self. 193 | Raises: 194 | ValueError - If self is not square. 195 | Returns: 196 | float - self's determinant. 197 | """ 198 | if self.row != self.col: 199 | raise ValueError("Matrix determinant only defined for square matrices.") 200 | 201 | if self.row == 2: 202 | return self.val[0][0] * self.val[1][1] - self.val[0][1] * self.val[1][0] 203 | 204 | d = 0.0 205 | for j in range(self.col): 206 | c = self.cofactor(0, j) 207 | d += c * self.val[0][j] 208 | return d 209 | 210 | def updateInfo(self): 211 | self.row = len(self.val) 212 | self.col = len(self.val[0]) 213 | 214 | def transpose(self): 215 | temp = [[0 for i in range(self.col)] for j in range(self.row)] 216 | for x in range(self.row): 217 | for y in range(self.col): 218 | temp[x][y] = self.val[y][x] 219 | self.val = temp 220 | 221 | def __repr__(self): 222 | ## DEBUG 223 | return f'matrix->{self.val}' 224 | 225 | 226 | def multiplyMatrix(m1, m2): 227 | m = Matrix(m1.row, m2.col) 228 | 229 | if m1.col != m2.row: 230 | print("we can't this two matricies") 231 | return None 232 | 233 | for x in range(m1.row): 234 | for y in range(m2.col): 235 | sum = 0 236 | for z in range(m1.col): 237 | sum += m1.val[x][z] * m2.val[z][y] 238 | m.val[x][y] = round(sum, 5) 239 | 240 | return m 241 | 242 | def multiplyMatrixVector(vec, mat): 243 | temp = Matrix(1, 4) 244 | temp.val = vec.toMatrix() 245 | m = multiplyMatrix(temp, mat) 246 | v = toVector3(m) 247 | if m.val[0][3] != 0: 248 | v = v / m.val[0][3] 249 | return v 250 | 251 | def TransposeMatrix(m): 252 | m1 = Matrix(m.row, m.col) 253 | for x in range(m.row): 254 | for y in range(m.col): 255 | m1.val[x][y] = m.val[y][x] 256 | 257 | return m1 258 | 259 | def Determinant2x2(matrix): 260 | # print(matrix.val) 261 | return matrix.val[0][0] * matrix.val[1][1] - matrix.val[0][1] * matrix.val[1][0] 262 | 263 | def submatrix(matrix, row, column): 264 | temp = deepcopy(matrix) 265 | del temp.val[row] 266 | for i in range(len(temp.val)): 267 | del temp.val[i][column] 268 | 269 | temp.updateInfo() 270 | # print(temp.val) 271 | return temp 272 | 273 | def Minor3x3(matrix, row, column): 274 | s = submatrix(matrix, row, column) 275 | 276 | if len(s.val) > 2: 277 | return Determinant(s) 278 | else: 279 | return Determinant2x2(s) 280 | 281 | def Cofactor3x3(matrix, row, column): 282 | minor = Minor3x3(matrix, row, column) 283 | if (row + column) % 2 == 0: 284 | return minor 285 | else: 286 | return -minor 287 | 288 | def Determinant(matrix): 289 | if matrix.row == 2: 290 | return Determinant2x2(matrix.val) 291 | else: 292 | d = 0 293 | for j in range(len(matrix.val[0])): 294 | c = Cofactor3x3(matrix, 0, j) 295 | 296 | d += c * matrix.val[0][j] 297 | return d 298 | 299 | def MatrixInversion(matrix): 300 | d = Determinant(matrix) 301 | if d == 0: 302 | print("this matrix is not invertible") 303 | return None 304 | 305 | new = Matrix(matrix.row, matrix.col) 306 | for x in range(matrix.row): 307 | for y in range(matrix.col): 308 | new.val[x][y] = round(Cofactor3x3(matrix, x, y) / d, 6) 309 | new.transpose() 310 | # print(new.val) 311 | return new 312 | 313 | def QuickInverse(m): 314 | matrix = Matrix() 315 | matrix.val[0][0], matrix.val[0][1], matrix.val[0][2], matrix.val[0][3] = m.val[0][0], m.val[1][0], m.val[2][0], 0.0 316 | matrix.val[1][0], matrix.val[1][1], matrix.val[1][2], matrix.val[1][3] = m.val[0][1], m.val[1][1], m.val[2][1], 0.0 317 | matrix.val[2][0], matrix.val[2][1], matrix.val[2][2], matrix.val[2][3] = m.val[0][2], m.val[1][2], m.val[2][2], 0.0 318 | matrix.val[3][0] = -(m.val[3][0] * matrix.val[0][0] + m.val[3][1] * matrix.val[1][0] + m.val[3][2] * matrix.val[2][0]) 319 | matrix.val[3][1] = -(m.val[3][0] * matrix.val[0][1] + m.val[3][1] * matrix.val[1][1] + m.val[3][2] * matrix.val[2][1]) 320 | matrix.val[3][2] = -(m.val[3][0] * matrix.val[0][2] + m.val[3][1] * matrix.val[1][2] + m.val[3][2] * matrix.val[2][2]) 321 | matrix.val[3][3] = 1.0 322 | return matrix 323 | 324 | 325 | -------------------------------------------------------------------------------- /engine/utils/mesh/__pycache__/base.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/3D-engine-from-scraph--pygame/b3ed330acd55026d93d95f243df3e10aad6f4779/engine/utils/mesh/__pycache__/base.cpython-39.pyc -------------------------------------------------------------------------------- /engine/utils/mesh/__pycache__/meshes.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/3D-engine-from-scraph--pygame/b3ed330acd55026d93d95f243df3e10aad6f4779/engine/utils/mesh/__pycache__/meshes.cpython-39.pyc -------------------------------------------------------------------------------- /engine/utils/mesh/__pycache__/point.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/3D-engine-from-scraph--pygame/b3ed330acd55026d93d95f243df3e10aad6f4779/engine/utils/mesh/__pycache__/point.cpython-39.pyc -------------------------------------------------------------------------------- /engine/utils/mesh/__pycache__/spheres.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josephbakulikira/3D-engine-from-scraph--pygame/b3ed330acd55026d93d95f243df3e10aad6f4779/engine/utils/mesh/__pycache__/spheres.cpython-39.pyc -------------------------------------------------------------------------------- /engine/utils/mesh/base.py: -------------------------------------------------------------------------------- 1 | from __future__ import annotations 2 | from typing import Optional 3 | from os import PathLike 4 | import pygame 5 | import utils.matrix as matrix 6 | from utils.vector import Vector3, Normalize, dotProduct, crossProduct 7 | from utils.triangle import Triangle 8 | from utils.tools import DrawTriangle, TriangleClipped, hsv2rgb 9 | from constants import Width, Height, Zoffset, clipping, dim 10 | import pygame 11 | 12 | class Mesh: 13 | def __init__(self, position=Vector3(), scale=1): 14 | self.triangles = [] 15 | self.position = position 16 | self.color = (255, 255, 255) 17 | self.transform = matrix.Matrix.identity() 18 | self.translate = matrix.Matrix.identity() 19 | self.scale = scale 20 | @classmethod 21 | def from_file( 22 | cls, 23 | fname: PathLike, 24 | color: tuple[int, int, int], 25 | position: Optional[Vector3] = None, 26 | ) -> Mesh: 27 | triangles = LoadMesh(fname, color) 28 | return cls(triangles, position) 29 | 30 | @classmethod 31 | def cube( 32 | cls, color: tuple[int, int, int], position: Optional[Vector3] = None, scale: optional[float] = 1 33 | ) -> Mesh: 34 | print(scale) 35 | tris = meshes.CubeTriangles(size, color) 36 | return cls(tris, position, scale) 37 | 38 | @classmethod 39 | def icosphere( 40 | cls, 41 | color: tuple[int, int, int], 42 | subdivision=0, 43 | radius=1, 44 | position: Optional[Vector3] = None, 45 | ) -> Mesh: 46 | tris = spheres.IcosphereTriangles(color, subdivision, radius) 47 | return cls(tris, position) 48 | 49 | # TODO: refactor this method, its way too long 50 | def update( 51 | self, screen, fill, wireframe, dt, camera, light, depth, clippingDebug, hue=0 52 | ): 53 | tris = [] 54 | normals = [] 55 | 56 | for index, triangle in enumerate(self.triangles): 57 | projected = Triangle() 58 | projected.verticeColor = triangle.verticeColor 59 | transformed = Triangle() 60 | 61 | transformed.vertex1 = matrix.multiplyMatrixVector(triangle.vertex1+self.position , self.transform) 62 | transformed.vertex2 = matrix.multiplyMatrixVector(triangle.vertex2+self.position , self.transform) 63 | transformed.vertex3 = matrix.multiplyMatrixVector(triangle.vertex3+self.position , self.transform) 64 | 65 | transformed.vertex1 += Vector3(0, 0, Zoffset) 66 | transformed.vertex2 += Vector3(0, 0, Zoffset) 67 | transformed.vertex3 += Vector3(0, 0, Zoffset) 68 | 69 | # get the normal vector 70 | line1 = transformed.vertex2 - transformed.vertex1 71 | line2 = transformed.vertex3 - transformed.vertex1 72 | normal = Normalize( crossProduct(line1, line2) ) 73 | 74 | temp = transformed.vertex1 - camera.position 75 | d = dotProduct( temp, normal) 76 | if d < 0.0 or depth == False: 77 | if hue != 0: 78 | triangle.color = hsv2rgb(hue, 1, 1) 79 | 80 | # print(normal) 81 | 82 | # directional light -> illumination 83 | # dim = 0.0001 84 | _light = max(dim, dotProduct(light.direction, normal) ) if light != None else 1 85 | transformed.color = triangle.Shade(_light) 86 | 87 | transformed.vertex1 = matrix.multiplyMatrixVector(transformed.vertex1, camera.viewMatrix ) 88 | transformed.vertex2 = matrix.multiplyMatrixVector(transformed.vertex2, camera.viewMatrix ) 89 | transformed.vertex3 = matrix.multiplyMatrixVector(transformed.vertex3, camera.viewMatrix ) 90 | 91 | clipped = 0 92 | clippedTriangles = [Triangle() for _ in range(2)] 93 | clipped = TriangleClipped(Vector3(0, 0, clipping), Vector3(0, 0, 1), transformed, clippedTriangles, clippingDebug) 94 | 95 | for i in range(clipped): 96 | #print(clippedTriangles) 97 | # project to 2D screen 98 | projected.vertex1 = matrix.multiplyMatrixVector(clippedTriangles[i].vertex1, camera.projection()) 99 | projected.vertex2 = matrix.multiplyMatrixVector(clippedTriangles[i].vertex2, camera.projection()) 100 | projected.vertex3 = matrix.multiplyMatrixVector(clippedTriangles[i].vertex3, camera.projection()) 101 | 102 | 103 | projected.color = clippedTriangles[i].color 104 | # fix the inverted x 105 | projected.vertex1 *= Vector3(1, -1, 1) 106 | projected.vertex2 *= Vector3(1, -1, 1) 107 | projected.vertex3 *= Vector3(1, -1, 1) 108 | 109 | offsetView = Vector3(1, 1, 0) 110 | projected.vertex1 = projected.vertex1 + offsetView 111 | projected.vertex2 = projected.vertex2 + offsetView 112 | projected.vertex3 = projected.vertex3 + offsetView 113 | 114 | # half_v1 = projected.vertex1 / 2 115 | # half_v2 = projected.vertex2 / 2 116 | # half_v3 = projected.vertex3 / 2 117 | 118 | projected.vertex1 *= Vector3(Width, Height, 1) * 0.5 119 | projected.vertex2 *= Vector3(Width, Height, 1) * 0.5 120 | projected.vertex3 *= Vector3(Width, Height, 1) * 0.5 121 | if i == 0 and wireframe == True: 122 | pygame.draw.line(screen, (255, 255,255), projected.vertex1.GetTuple(), projected.vertex2.GetTuple(), 1) 123 | pygame.draw.line(screen, (255, 255,255), projected.vertex2.GetTuple(), projected.vertex3.GetTuple(), 1) 124 | pygame.draw.line(screen, (255, 255,255), projected.vertex3.GetTuple(), projected.vertex1.GetTuple(), 1) 125 | #pygame.draw.polygon(screen, projected.color, projected.GetPolygons()) 126 | if i == 0 and fill==True: 127 | # have to fix this part 128 | pygame.draw.polygon(screen, projected.color, projected.GetPolygons()) 129 | 130 | tris.append(projected) 131 | #DrawTriangle(screen, projected, Fill, wireframe, wireframeColor) 132 | 133 | return tris 134 | -------------------------------------------------------------------------------- /engine/utils/mesh/meshes.py: -------------------------------------------------------------------------------- 1 | from utils.mesh.base import Mesh 2 | from utils.triangle import Triangle 3 | from utils.vector import Vector3, Vector2 4 | from math import sin, cos, pi 5 | 6 | def translate(value, min1, max1, min2, max2): 7 | return min2 + (max2 - min2) * ((value-min1)/(max1-min1)) 8 | 9 | def CubeTriangles(color, position=Vector3(), scale=1): 10 | return [ 11 | Triangle( Vector3(-1.0, -1.0, -1.0) * scale + position, Vector3(-1.0, 1.0, -1.0) * scale + position, Vector3(1.0, 1.0, -1.0) * scale + position, color), 12 | Triangle( Vector3(-1.0, -1.0, -1.0) * scale + position, Vector3(1.0, 1.0, -1.0) * scale + position, Vector3(1.0, -1.0, -1.0) * scale + position, color), 13 | 14 | Triangle( Vector3(1.0, -1.0, -1.0) * scale + position, Vector3(1.0, 1.0, -1.0) * scale + position, Vector3(1.0, 1.0, 1.0) * scale + position, color), 15 | Triangle( Vector3(1.0, -1.0, -1.0) * scale + position, Vector3(1.0, 1.0, 1.0) * scale + position, Vector3(1.0, -1.0, 1.0) * scale + position, color), 16 | 17 | Triangle( Vector3(1.0, -1.0, 1.0) * scale + position, Vector3(1.0, 1.0, 1.0) * scale + position, Vector3(-1.0, 1.0, 1.0) * scale + position, color), 18 | Triangle( Vector3(1.0, -1.0, 1.0) * scale + position, Vector3(-1.0, 1.0, 1.0) * scale + position, Vector3(-1.0, -1.0, 1.0) * scale + position, color), 19 | 20 | Triangle( Vector3(-1.0, -1.0, 1.0) * scale + position, Vector3(-1.0, 1.0, 1.0) * scale + position, Vector3(-1.0, 1.0, -1.0) * scale + position, color), 21 | Triangle( Vector3(-1.0, -1.0, 1.0) * scale + position, Vector3(-1.0, 1.0, -1.0) * scale + position, Vector3(-1.0, -1.0, -1.0) * scale + position, color), 22 | 23 | Triangle( Vector3(-1.0, 1.0, -1.0) * scale + position, Vector3(-1.0, 1.0, 1.0) * scale + position, Vector3(1.0, 1.0, 1.0) * scale + position, color), 24 | Triangle( Vector3(-1.0, 1.0, -1.0) * scale + position, Vector3(1.0, 1.0, 1.0) * scale + position, Vector3(1.0, 1.0, -1.0) * scale + position, color), 25 | 26 | Triangle( Vector3(1.0, -1.0, 1.0) * scale + position, Vector3(-1.0, -1.0, 1.0) * scale + position, Vector3(-1.0, -1.0, -1.0) * scale + position, color), 27 | Triangle( Vector3(1.0, -1.0, 1.0) * scale + position, Vector3(-1.0, -1.0, -1.0) * scale + position, Vector3(1.0, -1.0, -1.0) * scale + position, color), 28 | ] 29 | 30 | 31 | 32 | def QuadTriangles(color=(255, 255, 255), size=5): 33 | vertices = [ 34 | Vector3(-size, -size, -size), 35 | Vector3(-size, size, -size), 36 | Vector3(size, size, -size), 37 | Vector3(size, -size, -size) 38 | ] 39 | 40 | return [ 41 | Triangle(vertices[0], vertices[1], vertices[2], color), 42 | Triangle(vertices[0], vertices[2], vertices[3], color) 43 | ] 44 | 45 | def PlaneTriangles(color=(255, 255, 255), resolution=10, size=2): 46 | meshData = [] 47 | vertices = [[None for i in range(resolution)] for j in range(resolution)] 48 | 49 | for i in range(resolution): 50 | for j in range(resolution): 51 | x = translate(i, 0, resolution, -size, size) 52 | y = translate(j, 0, resolution, -size, size) 53 | vertices[i][j] = Vector3(x, 0, y) 54 | 55 | for i in range(resolution): 56 | for j in range(resolution): 57 | if i + 1 < resolution and j + 1 < resolution: 58 | v1 = vertices[i][j] 59 | v2 = vertices[i+1][j] 60 | v3 = vertices[i][j+1] 61 | v4 = vertices [i+1][j+1] 62 | meshData.append(Triangle(v1, v2, v3, color)) 63 | meshData.append(Triangle(v4, v3, v2, color)) 64 | 65 | 66 | return meshData 67 | -------------------------------------------------------------------------------- /engine/utils/mesh/point.py: -------------------------------------------------------------------------------- 1 | from utils.matrix import * 2 | from utils.transform import * 3 | from utils.vector import Vector3, crossProduct,dotProduct, Normalize 4 | from constants import Width, Height, Zoffset, clipping 5 | import pygame 6 | import utils.matrix as matrix 7 | from utils.vector import Vector3 8 | from constants import Width, Height, Zoffset 9 | from utils.camera import Camera 10 | 11 | 12 | class Point: 13 | def __init__(self, position=Vector3(), color=(255, 255, 255), radius=10): 14 | self.position = position 15 | self.color = color 16 | self.radius = radius 17 | self.transform = matrix.Matrix.identity() 18 | 19 | def update(self,screen, camera,showPoint=False): 20 | 21 | projected = None 22 | transformed = None 23 | transformed = multiplyMatrixVector(self.position, self.transform) 24 | transformed += Vector3(0, 0, Zoffset) 25 | transformed = multiplyMatrixVector(transformed, camera.viewMatrix) 26 | projected = multiplyMatrixVector(transformed, camera.projection()) 27 | projected *= Vector3(-1, -1, 1) 28 | 29 | offsetView = Vector3(1, 1, 0) 30 | projected = projected + offsetView 31 | projected *= Vector3(Width, Height, 1) * 0.5 32 | if showPoint: 33 | pygame.draw.circle(screen,self.color, projected.GetTuple(), self.radius) 34 | return projected 35 | -------------------------------------------------------------------------------- /engine/utils/mesh/spheres.py: -------------------------------------------------------------------------------- 1 | from utils.mesh.base import Mesh 2 | from utils.triangle import Triangle 3 | from utils.vector import Vector3, Vector2, Normalize 4 | from math import sin, cos, pi, sqrt, acos 5 | 6 | def SphereTriangles(color,n_subdivision=10, radius=1): 7 | #simple UV SPHERE 8 | meshData = [] 9 | vertices = [] 10 | 11 | #adding top vertex 12 | vertices.append(Vector3(0, radius, 0)) 13 | #generate vertices of the sphere 14 | for i in range(n_subdivision): 15 | phi = pi * (i+1) / n_subdivision 16 | for j in range(n_subdivision): 17 | theta = 2 * pi * j / n_subdivision 18 | x = radius * sin(phi) * cos(theta) 19 | y = radius * cos(phi) 20 | z = radius * sin(phi) * sin(theta) 21 | vertices.append(Vector3(x, y, z)) 22 | #add bottom vertex 23 | vertices.append(Vector3(0, -radius, 0)) 24 | 25 | #add top and bottom triangles 26 | for i in range(n_subdivision): 27 | i0 = i + 1 28 | i1 = (i+1) % n_subdivision + 1 29 | meshData.append(Triangle(vertices[0], vertices[i1], vertices[i0], color) ) 30 | i0 = i + n_subdivision * (n_subdivision - 2) + 1 31 | i1 = (i+1) % n_subdivision + n_subdivision * (n_subdivision - 2) + 1 32 | meshData.append( Triangle(vertices[-1], vertices[i1], vertices[i0], color) ) 33 | 34 | for j in range(n_subdivision-2): 35 | j0 = j * n_subdivision + 1 36 | j1 = (j+1) * n_subdivision + 1 37 | for i in range(n_subdivision): 38 | i0 = j0 + i 39 | i1 = j0 + (i + 1) % n_subdivision 40 | i2 = j1 + (i + 1) % n_subdivision 41 | i3 = j1 + i 42 | meshData.append( Triangle(vertices[i0], vertices[i1], vertices[i2], color)) 43 | meshData.append( Triangle(vertices[i0], vertices[i2], vertices[i3], color)) 44 | 45 | return meshData 46 | 47 | def GetMiddlePoint(vec1, vec2, vertices, middlePointCache): 48 | a = vertices.index(vec1) 49 | b = vertices.index(vec2) 50 | 51 | # check if the edge is already divided to avoid duplicated vertices 52 | smallerIndex, greaterIndex = b, a 53 | if a < b: 54 | smallerIndex = a 55 | greaterIndex = b 56 | key = f"{smallerIndex}, {greaterIndex}" 57 | 58 | if key in middlePointCache: 59 | return middlePointCache[key] 60 | 61 | vertex1 = vertices[a] 62 | vertex2 = vertices[b] 63 | 64 | middle = Normalize( (vertex1+vertex2)/2 ) 65 | vertices.append(middle) 66 | 67 | _index = vertices.index(middle) 68 | middlePointCache.update({key: _index}) 69 | 70 | return _index 71 | 72 | def IcosphereTriangles(color=(255, 255, 255), subdivision=0, radius=1): 73 | middlePointCache = {} 74 | g = (1 + sqrt(5))/2 #golden ratio 75 | 76 | vertices = [ 77 | Normalize(Vector3(-1, g, 0)), 78 | Normalize(Vector3( 1, g, 0)), 79 | Normalize(Vector3(-1, -g, 0)), 80 | Normalize(Vector3( 1, -g, 0)), 81 | 82 | Normalize(Vector3( 0, -1, g)), 83 | Normalize(Vector3( 0, 1, g)), 84 | Normalize(Vector3( 0, -1, -g)), 85 | Normalize(Vector3( 0, 1, -g)), 86 | 87 | Normalize(Vector3( g, 0, -1)), 88 | Normalize(Vector3( g, 0, 1)), 89 | Normalize(Vector3( -g, 0, -1)), 90 | Normalize(Vector3( -g, 0, 1)) 91 | ] 92 | triangles = [ 93 | # 5 faces around point 0 94 | Triangle(vertices[0], vertices[11], vertices[5], color), 95 | Triangle(vertices[0], vertices[5], vertices[1], color), 96 | Triangle(vertices[0], vertices[1], vertices[7], color), 97 | Triangle(vertices[0], vertices[7], vertices[10], color), 98 | Triangle(vertices[0], vertices[10], vertices[11], color), 99 | # Adjacent faces 100 | Triangle(vertices[1], vertices[5], vertices[9], color), 101 | Triangle(vertices[5], vertices[11], vertices[4], color), 102 | Triangle(vertices[11], vertices[10], vertices[2], color), 103 | Triangle(vertices[10], vertices[7], vertices[6], color), 104 | Triangle(vertices[7], vertices[1], vertices[8], color), 105 | # 5 faces around 3 106 | Triangle(vertices[3], vertices[9], vertices[4], color), 107 | Triangle(vertices[3], vertices[4], vertices[2], color), 108 | Triangle(vertices[3], vertices[2], vertices[6], color), 109 | Triangle(vertices[3], vertices[6], vertices[8], color), 110 | Triangle(vertices[3], vertices[8], vertices[9], color), 111 | # Adjacent faces 112 | Triangle(vertices[4], vertices[9], vertices[5], color), 113 | Triangle(vertices[2], vertices[4], vertices[11], color), 114 | Triangle(vertices[6], vertices[2], vertices[10], color), 115 | Triangle(vertices[8], vertices[6], vertices[7], color), 116 | Triangle(vertices[9], vertices[8], vertices[1], color) 117 | ] 118 | 119 | # subdivision 120 | for i in range(subdivision): 121 | subdivisions = [] 122 | for triangle in triangles: 123 | _i0 = GetMiddlePoint(triangle.vertex1, triangle.vertex2, vertices, middlePointCache) 124 | _i1 = GetMiddlePoint(triangle.vertex2, triangle.vertex3, vertices, middlePointCache) 125 | _i2 = GetMiddlePoint(triangle.vertex3, triangle.vertex1, vertices, middlePointCache) 126 | 127 | vertex1 = vertices[_i0] 128 | vertex2 = vertices[_i1] 129 | vertex3 = vertices[_i2] 130 | 131 | subdivisions.append(Triangle(triangle.vertex1, vertex1, vertex3, color)) 132 | subdivisions.append(Triangle(triangle.vertex2, vertex2, vertex1, color)) 133 | subdivisions.append(Triangle(triangle.vertex3, vertex3, vertex2, color)) 134 | subdivisions.append(Triangle(vertex1, vertex2, vertex3, color)) 135 | 136 | triangles = subdivisions 137 | #print(triangles) 138 | return triangles 139 | 140 | def FibonnaciSphereTriangles(color=(255, 255, 255), n=50): 141 | #not finished 142 | triangles = [] 143 | vertices = [] 144 | # golden ratio in radians 145 | g = pi * (3 - sqrt(5))/2 146 | 147 | for i in range(n): 148 | y = 1 - (i / float(n - 1)) * 2 # y goes from 1 to -1 149 | radius = sqrt(1 - y * y) # radius at y 150 | theta = g * i # golden angle increment 151 | x = cos(theta) * radius 152 | z = sin(theta) * radius 153 | vertices.append(Vector3(x, y, z)) 154 | 155 | for i in range(len(vertices)-3): 156 | vertex1 = vertices[i] 157 | vertex2 = vertices[i+1] 158 | vertex3 = vertices[i+2] 159 | triangles.append(Triangle(vertex1, vertex2, vertex3, color)) 160 | 161 | print("work in progress") 162 | return triangles 163 | -------------------------------------------------------------------------------- /engine/utils/tools.py: -------------------------------------------------------------------------------- 1 | import pygame 2 | from utils.vector import * 3 | from utils.triangle import Triangle 4 | from constants import * 5 | from utils.mesh.point import * 6 | import colorsys 7 | 8 | def hsv_to_rgb(h, s, v): 9 | return tuple(round(i * 255) for i in colorsys.hsv_to_rgb(h, s, v)) 10 | 11 | def DrawTriangle(screen, triangle, fill, wireframe, vertices, radius, verticeColor, wireframeColor, lineWidth): 12 | 13 | if fill == True: 14 | #print(triangle.color) 15 | pygame.draw.polygon(screen, triangle.color, triangle.GetPolygons()) 16 | 17 | if wireframe == True: 18 | pygame.draw.line(screen, wireframeColor, triangle.vertex1.GetTuple(), triangle.vertex2.GetTuple(), lineWidth) 19 | pygame.draw.line(screen, wireframeColor, triangle.vertex2.GetTuple(), triangle.vertex3.GetTuple(), lineWidth) 20 | pygame.draw.line(screen, wireframeColor, triangle.vertex3.GetTuple(), triangle.vertex1.GetTuple(), lineWidth) 21 | 22 | if vertices == True: 23 | color = (255, 255 ,255) if verticeColor==False else triangle.verticeColor 24 | 25 | pygame.draw.circle(screen, color, triangle.vertex1.GetTuple(), radius) 26 | pygame.draw.circle(screen, color, triangle.vertex2.GetTuple(), radius) 27 | pygame.draw.circle(screen, color, triangle.vertex3.GetTuple(), radius) 28 | 29 | def hsv2rgb(h,s,v): 30 | return tuple(round(i * 255) for i in colorsys.hsv_to_rgb(h,s,v)) 31 | 32 | def LoadMesh(objectPath, color=(255, 255, 255)): 33 | vert_data = [] 34 | triangle_indices = [] 35 | data = None 36 | meshData = [] 37 | 38 | #read and close file 39 | with open(objectPath, 'r') as objectFile: 40 | data = objectFile.readlines() 41 | 42 | # get data 43 | for _line in data: 44 | _line = _line.split(" ") 45 | if _line[0] == 'v': 46 | vert_data.append(Vector3(float(_line[1]), float(_line[2]), float(_line[3]))) 47 | elif _line[0] == 'f': 48 | temp = _line[1:] 49 | line_indices = [] 50 | for el in temp: 51 | indexList = el.split('/') 52 | line_indices.append(int(indexList[0]) ) 53 | 54 | triangle_indices.append(line_indices) 55 | 56 | for t in triangle_indices: 57 | triangle = Triangle( vert_data[t[0]-1], vert_data[t[1]-1],vert_data[t[2]-1], color) 58 | meshData.append(triangle) 59 | return meshData 60 | 61 | def translateValue(value, min1, max1, min2, max2): 62 | return min2 + (max2 - min2)* ((value-min1)/(max1-min1)) 63 | 64 | def SignedDist(pos, normal, p): 65 | n = Normalize(pos) 66 | return (normal.x * pos.x + normal.y * pos.y + normal.z * pos.z - dotProduct(normal, p)) 67 | 68 | def TriangleClipped(pos, normal, triangle, outTriangle, clippingDebug=False): 69 | #normal = Normalize(normal) 70 | 71 | insidePoints, insideCount = [None for _ in range(3)], 0 72 | outsidePoints, outsideCount = [None for _ in range(3)], 0 73 | 74 | d0 = SignedDist(triangle.vertex1, normal, pos) 75 | d1 = SignedDist(triangle.vertex2, normal, pos) 76 | d2 = SignedDist(triangle.vertex3, normal, pos) 77 | 78 | if d0 >= 0: 79 | insidePoints[insideCount] = triangle.vertex1 80 | insideCount += 1 81 | else: 82 | outsidePoints[outsideCount] = triangle.vertex1 83 | outsideCount += 1 84 | 85 | if d1 >= 0: 86 | insidePoints[insideCount] = triangle.vertex2 87 | insideCount += 1 88 | else: 89 | outsidePoints[outsideCount] = triangle.vertex2 90 | outsideCount += 1 91 | 92 | if d2 >= 0: 93 | insidePoints[insideCount] = triangle.vertex3 94 | insideCount += 1 95 | else: 96 | outsidePoints[outsideCount] = triangle.vertex3 97 | outsideCount += 1 98 | 99 | if insideCount == 0: 100 | return 0 101 | if insideCount == 3: 102 | outTriangle[0] = triangle 103 | 104 | return 1 105 | 106 | if insideCount == 1 and outsideCount == 2: 107 | # outTriangle[0].color = (0, 255,24) 108 | outTriangle[0].color = triangle.color if clippingDebug==False else red 109 | 110 | outTriangle[0].vertex1 = insidePoints[0] 111 | outTriangle[0].vertex2 = PlaneLineIntersection(pos, normal, insidePoints[0], outsidePoints[0]) 112 | outTriangle[0].vertex3 = PlaneLineIntersection(pos, normal, insidePoints[0], outsidePoints[1]) 113 | return 1 114 | 115 | if insideCount == 2 and outsideCount == 1: 116 | 117 | # outTriangle[0].color = (55, 60, 255) 118 | # outTriangle[1].color = (255,51, 12) 119 | outTriangle[0].color = triangle.color if clippingDebug==False else blue 120 | outTriangle[1].color = triangle.color if clippingDebug==False else green 121 | outTriangle[0].vertex1 = insidePoints[1] 122 | outTriangle[0].vertex2 = insidePoints[0] 123 | outTriangle[0].vertex3 = PlaneLineIntersection(pos, normal, insidePoints[0], outsidePoints[0]) 124 | 125 | outTriangle[1].vertex1 = insidePoints[1] 126 | outTriangle[1].vertex2 = outTriangle[0].vertex3 127 | outTriangle[1].vertex3 = PlaneLineIntersection(pos, normal, insidePoints[1], outsidePoints[0]) 128 | 129 | return 2 130 | 131 | def DrawAxis(screen, camera, scale=3,center=None, Xaxis=True, Yaxis=True, Zaxis=True, stroke=5): 132 | if center == None: 133 | center = Point(Vector3(0, 0, 0)) 134 | 135 | X = Point(Vector3(scale, 0, 0), (255, 0, 0)) 136 | Y = Point(Vector3(0, scale, 0), (0, 255, 0)) 137 | Z = Point(Vector3(0, 0, scale), (0, 0, 255)) 138 | origin = center.update(screen, camera) 139 | 140 | if Xaxis: 141 | x_axis = X.update(screen, camera, True) 142 | pygame.draw.line(screen, X.color, origin.GetTuple(),x_axis.GetTuple(), stroke) 143 | if Zaxis: 144 | z_axis = Z.update(screen, camera, True) 145 | pygame.draw.line(screen, Z.color, origin.GetTuple(), z_axis.GetTuple(), stroke) 146 | if Yaxis: 147 | y_axis = Y.update(screen, camera, True) 148 | pygame.draw.line(screen, Y.color, origin.GetTuple(), y_axis.GetTuple(), stroke) 149 | -------------------------------------------------------------------------------- /engine/utils/transform.py: -------------------------------------------------------------------------------- 1 | from utils.vector import Normalize, crossProduct, dotProduct 2 | import utils.matrix as matrix 3 | import utils.vector as vector 4 | 5 | # PointAt(vector3 cameraPosition, Vector3 cameraTarget, Vector3 cameraUpVector) 6 | def PointAt(current, next, up) -> matrix.Matrix: 7 | #f = (next - current).norm() 8 | #u = (up - f * up.dot(f)).norm() 9 | #r = u.cross(f) # right vector 10 | f = vector.Normalize(next - current) # forward vector 11 | u = (up - f * vector.dotProduct(up, f)) # up vector 12 | r = crossProduct(u, f) # right vector 13 | 14 | m = matrix.Matrix() 15 | m.val = [ 16 | [r.x, r.y, r.z, 0.0], 17 | [u.x, u.y, u.z, 0.0], 18 | [f.x, f.y, f.z, 0.0], 19 | [current.x, current.y, current.z, 1.0], 20 | ] 21 | return m 22 | 23 | 24 | # TODO: perhaps this function should take in a Matrix as arg 25 | # TODO: should move into matrix.Matrix class? 26 | def Shearing( 27 | xy: float, xz: float, yx: float, yz: float, zx: float, zy: float 28 | ) -> matrix.Matrix: 29 | m = matrix.Matrix() 30 | m.val = [ 31 | [1, xy, xz, 0.0], 32 | [yx, 1, yz, 0.0], 33 | [zx, zy, 1, 0.0], 34 | [0.0, 0.0, 0.0, 1], 35 | ] 36 | return m 37 | -------------------------------------------------------------------------------- /engine/utils/triangle.py: -------------------------------------------------------------------------------- 1 | from math import floor 2 | 3 | class Triangle: 4 | def __init__(self, v1=None, v2=None, v3=None, color=(255, 255, 255)): 5 | self.vertex1 = v1 6 | self.vertex2 = v2 7 | self.vertex3 = v3 8 | self.color = color 9 | self.verticeColor = color 10 | 11 | def Shade(self, val): 12 | r, g, b = 0, 0, 0 13 | if self.color[0] * val > 255: 14 | r = 255 15 | elif self.color[0] * val < 0: 16 | r = 0 17 | else: 18 | r = int(self.color[0] * val) 19 | 20 | if self.color[1] * val > 255: 21 | g = 255 22 | elif self.color[1] * val < 0: 23 | g = 0 24 | else: 25 | g = int(self.color[1] * val) 26 | 27 | if self.color[2] * val > 255: 28 | b = 255 29 | elif self.color[2] * val < 0: 30 | b = 0 31 | else: 32 | b = int(self.color[2] * val) 33 | 34 | return (r, g, b) 35 | 36 | def GetPolygons(self): 37 | return [(int(self.vertex1.x), int(self.vertex1.y)), 38 | (int(self.vertex2.x), int(self.vertex2.y)), 39 | (int(self.vertex3.x), int(self.vertex3.y))] 40 | 41 | def __repr__(self): 42 | #debug 43 | return f"triangle-> {(self.vertex1), (self.vertex2), (self.vertex3), {self.color}}" 44 | -------------------------------------------------------------------------------- /engine/utils/vector.py: -------------------------------------------------------------------------------- 1 | from math import pow, sqrt 2 | import colorsys 3 | 4 | class Vector3: 5 | def __init__(self, x=0, y=0, z=0): 6 | self.x = x 7 | self.y = y 8 | self.z = z 9 | self.w = 1 10 | 11 | def __add__(a, b): 12 | if type(b) == Vector3: 13 | return Vector3(a.x + b.x, a.y + b.y, a.z + b.z) 14 | return Vector3(a.x + b, a.y + b, a.z + b) 15 | 16 | def __sub__(a, b): 17 | if type(b) == Vector3: 18 | return Vector3(a.x - b.x, a.y - b.y, a.z - b.z) 19 | return Vector3(a.x - b, a.y - b, a.z - b) 20 | 21 | def __mul__(a, b): 22 | if type(b) == Vector3: 23 | return Vector3(a.x * b.x, a.y * b.y, a.z * b.z) 24 | return Vector3(a.x * b, a.y * b, a.z * b) 25 | 26 | def __truediv__(a, b): 27 | if type(b) == Vector3: 28 | return Vector3(a.x / b.x, a.y / b.y, a.z / b.z) 29 | return Vector3(a.x / b, a.y / b, a.z / b) 30 | 31 | def norm(self): 32 | mg = sqrt( pow(self.x,2) + pow(self.y,2) + pow(self.z,2) ) 33 | if mg == 0: 34 | self.x, self.y, self.z = 0, 0, 0 35 | else: 36 | self.x, self.y, self.z = self.x/mg, self.y/mg, self.z/mg 37 | 38 | def dot(self, b): 39 | return self.x * b.x + self.y * b.y + self.z * b.z 40 | 41 | 42 | def toMatrix(self): 43 | return [[self.x, self.y, self.z, self.w]] 44 | 45 | 46 | def GetTuple(self): 47 | return (int(self.x), int(self.y)) 48 | 49 | def __repr__(self): 50 | #debug 51 | return f" vec3-> ({self.x}, {self.y}, {self.z})" 52 | 53 | class Vector2: 54 | def __init__(self, x=0, y=0): 55 | self.x = x 56 | self.y = y 57 | def __add__(a, b): 58 | if type(b) == Vector2: 59 | return Vector2(a.x + b.x, a.y + b.y) 60 | return Vector2(a.x + b, a.y + b) 61 | 62 | def __sub__(a, b): 63 | if type(b) == Vector2: 64 | return Vector2(a.x - b.x, a.y - b.y) 65 | return Vector2(a.x - b, a.y - b) 66 | 67 | def __mul__(a, b): 68 | if type(b) == Vector2: 69 | return Vector2(a.x * b.x, a.y * b.y) 70 | return Vector2(a.x * b, a.y * b) 71 | 72 | def __truediv__(a, b): 73 | if type(b) == Vector2: 74 | return Vector2(a.x / b.x, a.y / b.y) 75 | return Vector2(a.x / b, a.y / b) 76 | 77 | def __repr__(self): 78 | return f"vec2-> ({self.x}, {self.y})" 79 | 80 | def toVector3(matrix): 81 | return Vector3(matrix.val[0][0], matrix.val[0][1], matrix.val[0][2]) 82 | 83 | def crossProduct(a, b): 84 | x = a.y * b.z - a.z * b.y 85 | y = a.z * b.x - a.x * b.z 86 | z = a.x * b.y - a.y * b.x 87 | return Vector3(x, y, z) 88 | 89 | def dotProduct(a, b): 90 | return a.x * b.x + a.y * b.y + a.z * b.z 91 | 92 | def GetMagnitude(a): 93 | if type(a) == Vector3: 94 | return sqrt( pow(a.x,2) + pow(a.y,2) + pow(a.z,2) ) 95 | else: 96 | return sqrt(pow(a.x,2) + pow(a.y,2)) 97 | 98 | def Normalize(a): 99 | mg = GetMagnitude(a) 100 | if mg == 0: 101 | return Vector3() 102 | return Vector3(a.x/mg, a.y/mg, a.z/mg) 103 | 104 | def PlaneLineIntersection(pos, normal, lineStart, lineEnd): 105 | normal = Normalize(normal) 106 | p = - dotProduct(normal, pos) 107 | ad = dotProduct(lineStart, normal) 108 | bd = dotProduct(lineEnd, normal) 109 | t = (-p -ad) / (bd - ad) 110 | lineStartEnd = lineEnd - lineStart 111 | lineTointersect = lineStartEnd * t 112 | return (lineStart + lineTointersect) 113 | -------------------------------------------------------------------------------- /engine/utils/world.py: -------------------------------------------------------------------------------- 1 | from utils.tools import * 2 | import utils.vector as vector 3 | from utils.transform import * 4 | from utils.matrix import * 5 | 6 | class Scene: 7 | def __init__(self, world=[]): 8 | self.world = world 9 | 10 | def update(self, dt, camera, light, screen, showAxis=False, 11 | fill=True, wireframe=False, vertices=False, depth=True, 12 | clippingDebug=False, showNormals=False, 13 | radius=8, verticeColor=False, 14 | wireframeColor=(255, 255, 255),ChangingColor=0, lineWidth=1): 15 | camera.HandleInput(dt) 16 | 17 | camera.direction = vector.Vector3(0, 0, 1) 18 | camera.up = vector.Vector3(0, 1, 0) 19 | camera.target = vector.Vector3(0, 0, 1) 20 | camera.rotation = matrix.Matrix.rotation_y(camera.yaw) 21 | camera.direction = matrix.multiplyMatrixVector(camera.target, camera.rotation) 22 | camera.target = camera.position + camera.direction 23 | lookAtMatrix = PointAt(camera.position, camera.target, camera.up) 24 | camera.viewMatrix = QuickInverse(lookAtMatrix) 25 | camera.target= Vector3(0, 0, 1) 26 | 27 | triangles = [] 28 | origins = [] 29 | for ob in self.world: 30 | triangles += ob.update(screen,fill, wireframe, dt, camera, light, depth, clippingDebug, ChangingColor) 31 | 32 | # sort the triangles list based on the average of their 33 | # z coordinate -> painters algorithm 34 | def Zsort(val): 35 | return (val.vertex1.z + val.vertex2.z + val.vertex3.z) / 3.0 36 | 37 | triangles.sort(key=Zsort) 38 | 39 | normals_length = 250 40 | normals = [] 41 | 42 | for projected in reversed(triangles): 43 | origin = (projected.vertex1+projected.vertex2+projected.vertex3)/3 44 | line1 = projected.vertex2 - projected.vertex1 45 | line2 = projected.vertex3 - projected.vertex1 46 | normal = crossProduct(line1, line2) * normals_length 47 | DrawTriangle(screen, projected, fill, wireframe,vertices, radius, verticeColor, wireframeColor, lineWidth) 48 | origins.append(origin) 49 | normals.append(normal) 50 | 51 | if showAxis: 52 | DrawAxis(screen, camera) 53 | 54 | if showNormals == True: #---to fix later 55 | # get the normal vectors 56 | for i, n in enumerate(normals): 57 | endPoint = origins[i] + (n) 58 | #pygame.draw.circle(screen, (0,255, 0), endPoint.GetTuple(), 10) 59 | pygame.draw.line(screen, (0, 255, 0), origins[i].GetTuple(), endPoint.GetTuple(), 2) 60 | -------------------------------------------------------------------------------- /requirements-dev.txt: -------------------------------------------------------------------------------- 1 | appdirs==1.4.4 2 | black==21.6b0 3 | cfgv==3.3.0 4 | click==8.0.1 5 | colorama==0.4.4 6 | distlib==0.3.2 7 | filelock==3.0.12 8 | flake8==3.9.2 9 | identify==2.2.10 10 | mccabe==0.6.1 11 | mypy-extensions==0.4.3 12 | nodeenv==1.6.0 13 | pathspec==0.8.1 14 | pre-commit==2.13.0 15 | pycodestyle==2.7.0 16 | pyflakes==2.3.1 17 | pygame==2.0.1 18 | PyYAML==5.4.1 19 | regex==2021.7.1 20 | six==1.16.0 21 | toml==0.10.2 22 | virtualenv==20.4.7 23 | --------------------------------------------------------------------------------