├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── assets ├── config.toml ├── font │ ├── SourceCodePro-Regular-20.json │ ├── SourceCodePro-Regular-20.png │ ├── UbuntuMono-20.json │ └── UbuntuMono-20.png └── mesh │ ├── cone.mtl │ ├── cone.obj │ ├── cube.mtl │ ├── cube.obj │ ├── hex.mtl │ ├── hex.obj │ ├── hex3d.mtl │ ├── hex3d.obj │ ├── person.mtl │ └── person.obj ├── font-atlas ├── Cargo.lock ├── Cargo.toml └── src │ └── main.rs ├── src ├── config.rs ├── events.rs ├── game.rs ├── grid.rs ├── input │ ├── keyboard.rs │ ├── mod.rs │ └── mouse.rs ├── interface.rs ├── lib.rs ├── main.rs └── ui │ ├── atlas.rs │ ├── camera.rs │ ├── color.rs │ ├── glyphs.rs │ ├── map.rs │ ├── mesh.rs │ ├── mod.rs │ ├── render.rs │ ├── tiles.rs │ ├── transforms.rs │ └── window.rs └── thule-game-ss.png /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | *~ 3 | *# 4 | map.dat 5 | map.png -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | [root] 2 | name = "thule" 3 | version = "0.1.0" 4 | dependencies = [ 5 | "bincode 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 6 | "clock_ticks 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 7 | "font-atlas 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 8 | "font-atlas-image 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 9 | "genmesh 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 10 | "glium 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)", 11 | "hex2d 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 12 | "image 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 13 | "nalgebra 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 14 | "ncollide 0.6.0 (git+https://github.com/sebcrozet/ncollide)", 15 | "noise 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 16 | "obj 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 17 | "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 18 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 19 | "toml 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)", 20 | ] 21 | 22 | [[package]] 23 | name = "android_glue" 24 | version = "0.1.3" 25 | source = "registry+https://github.com/rust-lang/crates.io-index" 26 | 27 | [[package]] 28 | name = "backtrace" 29 | version = "0.1.8" 30 | source = "registry+https://github.com/rust-lang/crates.io-index" 31 | dependencies = [ 32 | "backtrace-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 33 | "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 34 | "dbghelp-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 35 | "debug-builders 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 36 | "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 37 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 38 | "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 39 | ] 40 | 41 | [[package]] 42 | name = "backtrace-sys" 43 | version = "0.1.3" 44 | source = "registry+https://github.com/rust-lang/crates.io-index" 45 | dependencies = [ 46 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 47 | ] 48 | 49 | [[package]] 50 | name = "bincode" 51 | version = "0.3.0" 52 | source = "registry+https://github.com/rust-lang/crates.io-index" 53 | dependencies = [ 54 | "byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", 55 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 56 | ] 57 | 58 | [[package]] 59 | name = "bincode" 60 | version = "0.4.0" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | dependencies = [ 63 | "byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", 64 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 65 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 66 | "serde 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", 67 | ] 68 | 69 | [[package]] 70 | name = "bitflags" 71 | version = "0.3.3" 72 | source = "registry+https://github.com/rust-lang/crates.io-index" 73 | 74 | [[package]] 75 | name = "bitflags" 76 | version = "0.4.0" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | 79 | [[package]] 80 | name = "byteorder" 81 | version = "0.3.13" 82 | source = "registry+https://github.com/rust-lang/crates.io-index" 83 | 84 | [[package]] 85 | name = "byteorder" 86 | version = "0.4.2" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | 89 | [[package]] 90 | name = "cfg-if" 91 | version = "0.1.0" 92 | source = "registry+https://github.com/rust-lang/crates.io-index" 93 | 94 | [[package]] 95 | name = "cgl" 96 | version = "0.1.4" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | dependencies = [ 99 | "gleam 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 100 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 101 | ] 102 | 103 | [[package]] 104 | name = "cgmath" 105 | version = "0.2.0" 106 | source = "registry+https://github.com/rust-lang/crates.io-index" 107 | dependencies = [ 108 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 109 | "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 110 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 111 | ] 112 | 113 | [[package]] 114 | name = "cgmath" 115 | version = "0.3.1" 116 | source = "registry+https://github.com/rust-lang/crates.io-index" 117 | dependencies = [ 118 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 119 | "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 120 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 121 | ] 122 | 123 | [[package]] 124 | name = "clock_ticks" 125 | version = "0.1.0" 126 | source = "registry+https://github.com/rust-lang/crates.io-index" 127 | dependencies = [ 128 | "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 129 | ] 130 | 131 | [[package]] 132 | name = "cocoa" 133 | version = "0.2.4" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | dependencies = [ 136 | "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 137 | "core-graphics 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 138 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 139 | "objc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 140 | ] 141 | 142 | [[package]] 143 | name = "color_quant" 144 | version = "1.0.0" 145 | source = "registry+https://github.com/rust-lang/crates.io-index" 146 | 147 | [[package]] 148 | name = "core-foundation" 149 | version = "0.2.0" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | dependencies = [ 152 | "core-foundation-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 153 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 154 | ] 155 | 156 | [[package]] 157 | name = "core-foundation-sys" 158 | version = "0.2.0" 159 | source = "registry+https://github.com/rust-lang/crates.io-index" 160 | dependencies = [ 161 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 162 | ] 163 | 164 | [[package]] 165 | name = "core-graphics" 166 | version = "0.2.1" 167 | source = "registry+https://github.com/rust-lang/crates.io-index" 168 | dependencies = [ 169 | "core-foundation 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 170 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 171 | "serde 0.6.14 (registry+https://github.com/rust-lang/crates.io-index)", 172 | ] 173 | 174 | [[package]] 175 | name = "dbghelp-sys" 176 | version = "0.2.0" 177 | source = "registry+https://github.com/rust-lang/crates.io-index" 178 | dependencies = [ 179 | "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 180 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 181 | ] 182 | 183 | [[package]] 184 | name = "debug-builders" 185 | version = "0.1.0" 186 | source = "registry+https://github.com/rust-lang/crates.io-index" 187 | 188 | [[package]] 189 | name = "dlib" 190 | version = "0.1.1" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | dependencies = [ 193 | "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 194 | ] 195 | 196 | [[package]] 197 | name = "dwmapi-sys" 198 | version = "0.1.0" 199 | source = "registry+https://github.com/rust-lang/crates.io-index" 200 | dependencies = [ 201 | "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 202 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 203 | ] 204 | 205 | [[package]] 206 | name = "dylib" 207 | version = "0.0.2" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | dependencies = [ 210 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 211 | ] 212 | 213 | [[package]] 214 | name = "enum_primitive" 215 | version = "0.0.1" 216 | source = "registry+https://github.com/rust-lang/crates.io-index" 217 | dependencies = [ 218 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 219 | ] 220 | 221 | [[package]] 222 | name = "enum_primitive" 223 | version = "0.1.0" 224 | source = "registry+https://github.com/rust-lang/crates.io-index" 225 | dependencies = [ 226 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 227 | ] 228 | 229 | [[package]] 230 | name = "flate2" 231 | version = "0.2.13" 232 | source = "registry+https://github.com/rust-lang/crates.io-index" 233 | dependencies = [ 234 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 235 | "miniz-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 236 | ] 237 | 238 | [[package]] 239 | name = "font-atlas" 240 | version = "0.1.1" 241 | source = "registry+https://github.com/rust-lang/crates.io-index" 242 | dependencies = [ 243 | "glyph_packer 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 244 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 245 | ] 246 | 247 | [[package]] 248 | name = "font-atlas-image" 249 | version = "0.1.1" 250 | source = "registry+https://github.com/rust-lang/crates.io-index" 251 | dependencies = [ 252 | "bincode 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 253 | "font-atlas 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 254 | "image 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 255 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 256 | ] 257 | 258 | [[package]] 259 | name = "gcc" 260 | version = "0.3.24" 261 | source = "registry+https://github.com/rust-lang/crates.io-index" 262 | 263 | [[package]] 264 | name = "gdi32-sys" 265 | version = "0.1.1" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | dependencies = [ 268 | "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 269 | ] 270 | 271 | [[package]] 272 | name = "genmesh" 273 | version = "0.3.3" 274 | source = "registry+https://github.com/rust-lang/crates.io-index" 275 | dependencies = [ 276 | "cgmath 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 277 | ] 278 | 279 | [[package]] 280 | name = "gif" 281 | version = "0.5.1" 282 | source = "registry+https://github.com/rust-lang/crates.io-index" 283 | dependencies = [ 284 | "color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 285 | "lzw 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", 286 | ] 287 | 288 | [[package]] 289 | name = "gif" 290 | version = "0.7.0" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | dependencies = [ 293 | "color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 294 | "lzw 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 295 | ] 296 | 297 | [[package]] 298 | name = "gl_common" 299 | version = "0.1.0" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | dependencies = [ 302 | "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 303 | ] 304 | 305 | [[package]] 306 | name = "gl_generator" 307 | version = "0.1.0" 308 | source = "registry+https://github.com/rust-lang/crates.io-index" 309 | dependencies = [ 310 | "khronos_api 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)", 311 | "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 312 | "xml-rs 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)", 313 | ] 314 | 315 | [[package]] 316 | name = "gl_generator" 317 | version = "0.4.2" 318 | source = "registry+https://github.com/rust-lang/crates.io-index" 319 | dependencies = [ 320 | "khronos_api 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 321 | "log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 322 | "xml-rs 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 323 | ] 324 | 325 | [[package]] 326 | name = "gleam" 327 | version = "0.2.5" 328 | source = "registry+https://github.com/rust-lang/crates.io-index" 329 | dependencies = [ 330 | "gl_generator 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 331 | "khronos_api 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 332 | ] 333 | 334 | [[package]] 335 | name = "glium" 336 | version = "0.9.3" 337 | source = "registry+https://github.com/rust-lang/crates.io-index" 338 | dependencies = [ 339 | "backtrace 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 340 | "cgmath 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 341 | "gl_common 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 342 | "gl_generator 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 343 | "glutin 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", 344 | "image 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)", 345 | "khronos_api 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)", 346 | "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 347 | "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 348 | "nalgebra 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", 349 | "smallvec 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", 350 | ] 351 | 352 | [[package]] 353 | name = "glob" 354 | version = "0.2.10" 355 | source = "registry+https://github.com/rust-lang/crates.io-index" 356 | 357 | [[package]] 358 | name = "glutin" 359 | version = "0.3.7" 360 | source = "registry+https://github.com/rust-lang/crates.io-index" 361 | dependencies = [ 362 | "android_glue 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 363 | "cgl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 364 | "cocoa 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", 365 | "core-foundation 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", 366 | "core-graphics 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 367 | "dwmapi-sys 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 368 | "gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 369 | "gl_common 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 370 | "gl_generator 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 371 | "kernel32-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 372 | "khronos_api 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)", 373 | "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 374 | "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 375 | "objc 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", 376 | "osmesa-sys 0.0.5 (registry+https://github.com/rust-lang/crates.io-index)", 377 | "shared_library 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 378 | "shell32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 379 | "user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 380 | "wayland-client 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 381 | "wayland-kbd 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 382 | "wayland-window 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 383 | "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 384 | "x11-dl 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 385 | ] 386 | 387 | [[package]] 388 | name = "glyph_packer" 389 | version = "0.0.0" 390 | source = "registry+https://github.com/rust-lang/crates.io-index" 391 | dependencies = [ 392 | "image 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", 393 | ] 394 | 395 | [[package]] 396 | name = "hex2d" 397 | version = "0.1.0" 398 | source = "registry+https://github.com/rust-lang/crates.io-index" 399 | dependencies = [ 400 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 401 | "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 402 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 403 | ] 404 | 405 | [[package]] 406 | name = "image" 407 | version = "0.3.15" 408 | source = "registry+https://github.com/rust-lang/crates.io-index" 409 | dependencies = [ 410 | "byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", 411 | "enum_primitive 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 412 | "gif 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 413 | "glob 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", 414 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 415 | "png 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 416 | ] 417 | 418 | [[package]] 419 | name = "image" 420 | version = "0.6.1" 421 | source = "registry+https://github.com/rust-lang/crates.io-index" 422 | dependencies = [ 423 | "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 424 | "enum_primitive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 425 | "gif 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 426 | "glob 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", 427 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 428 | "png 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 429 | ] 430 | 431 | [[package]] 432 | name = "inflate" 433 | version = "0.1.0" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | 436 | [[package]] 437 | name = "kernel32-sys" 438 | version = "0.1.4" 439 | source = "registry+https://github.com/rust-lang/crates.io-index" 440 | dependencies = [ 441 | "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 442 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 443 | ] 444 | 445 | [[package]] 446 | name = "kernel32-sys" 447 | version = "0.2.1" 448 | source = "registry+https://github.com/rust-lang/crates.io-index" 449 | dependencies = [ 450 | "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 451 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 452 | ] 453 | 454 | [[package]] 455 | name = "khronos_api" 456 | version = "0.0.7" 457 | source = "registry+https://github.com/rust-lang/crates.io-index" 458 | 459 | [[package]] 460 | name = "khronos_api" 461 | version = "0.0.8" 462 | source = "registry+https://github.com/rust-lang/crates.io-index" 463 | 464 | [[package]] 465 | name = "khronos_api" 466 | version = "1.0.0" 467 | source = "registry+https://github.com/rust-lang/crates.io-index" 468 | 469 | [[package]] 470 | name = "lazy_static" 471 | version = "0.1.15" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | 474 | [[package]] 475 | name = "libc" 476 | version = "0.1.12" 477 | source = "registry+https://github.com/rust-lang/crates.io-index" 478 | 479 | [[package]] 480 | name = "libc" 481 | version = "0.2.7" 482 | source = "registry+https://github.com/rust-lang/crates.io-index" 483 | 484 | [[package]] 485 | name = "log" 486 | version = "0.3.5" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | dependencies = [ 489 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 490 | ] 491 | 492 | [[package]] 493 | name = "lzw" 494 | version = "0.8.0" 495 | source = "registry+https://github.com/rust-lang/crates.io-index" 496 | 497 | [[package]] 498 | name = "lzw" 499 | version = "0.9.0" 500 | source = "registry+https://github.com/rust-lang/crates.io-index" 501 | 502 | [[package]] 503 | name = "malloc_buf" 504 | version = "0.0.6" 505 | source = "registry+https://github.com/rust-lang/crates.io-index" 506 | dependencies = [ 507 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 508 | ] 509 | 510 | [[package]] 511 | name = "miniz-sys" 512 | version = "0.1.7" 513 | source = "registry+https://github.com/rust-lang/crates.io-index" 514 | dependencies = [ 515 | "gcc 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)", 516 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 517 | ] 518 | 519 | [[package]] 520 | name = "mmap" 521 | version = "0.1.1" 522 | source = "registry+https://github.com/rust-lang/crates.io-index" 523 | dependencies = [ 524 | "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 525 | "tempdir 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", 526 | ] 527 | 528 | [[package]] 529 | name = "nalgebra" 530 | version = "0.2.23" 531 | source = "registry+https://github.com/rust-lang/crates.io-index" 532 | dependencies = [ 533 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 534 | "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 535 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 536 | ] 537 | 538 | [[package]] 539 | name = "nalgebra" 540 | version = "0.5.1" 541 | source = "registry+https://github.com/rust-lang/crates.io-index" 542 | dependencies = [ 543 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 544 | "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 545 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 546 | ] 547 | 548 | [[package]] 549 | name = "ncollide" 550 | version = "0.6.0" 551 | source = "git+https://github.com/sebcrozet/ncollide#83df936309e15261451a8e9277fbc4fd78a4a211" 552 | dependencies = [ 553 | "ncollide_entities 0.4.0 (git+https://github.com/sebcrozet/ncollide)", 554 | "ncollide_math 0.2.1 (git+https://github.com/sebcrozet/ncollide)", 555 | "ncollide_pipeline 0.5.0 (git+https://github.com/sebcrozet/ncollide)", 556 | "ncollide_procedural 0.2.4 (git+https://github.com/sebcrozet/ncollide)", 557 | "ncollide_queries 0.3.1 (git+https://github.com/sebcrozet/ncollide)", 558 | "ncollide_transformation 0.2.2 (git+https://github.com/sebcrozet/ncollide)", 559 | "ncollide_utils 0.2.4 (git+https://github.com/sebcrozet/ncollide)", 560 | ] 561 | 562 | [[package]] 563 | name = "ncollide_entities" 564 | version = "0.4.0" 565 | source = "git+https://github.com/sebcrozet/ncollide#83df936309e15261451a8e9277fbc4fd78a4a211" 566 | dependencies = [ 567 | "nalgebra 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 568 | "ncollide_math 0.2.1 (git+https://github.com/sebcrozet/ncollide)", 569 | "ncollide_utils 0.2.4 (git+https://github.com/sebcrozet/ncollide)", 570 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 571 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 572 | ] 573 | 574 | [[package]] 575 | name = "ncollide_math" 576 | version = "0.2.1" 577 | source = "git+https://github.com/sebcrozet/ncollide#83df936309e15261451a8e9277fbc4fd78a4a211" 578 | dependencies = [ 579 | "nalgebra 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 580 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 581 | "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 582 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 583 | ] 584 | 585 | [[package]] 586 | name = "ncollide_pipeline" 587 | version = "0.5.0" 588 | source = "git+https://github.com/sebcrozet/ncollide#83df936309e15261451a8e9277fbc4fd78a4a211" 589 | dependencies = [ 590 | "nalgebra 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 591 | "ncollide_entities 0.4.0 (git+https://github.com/sebcrozet/ncollide)", 592 | "ncollide_math 0.2.1 (git+https://github.com/sebcrozet/ncollide)", 593 | "ncollide_queries 0.3.1 (git+https://github.com/sebcrozet/ncollide)", 594 | "ncollide_utils 0.2.4 (git+https://github.com/sebcrozet/ncollide)", 595 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 596 | ] 597 | 598 | [[package]] 599 | name = "ncollide_procedural" 600 | version = "0.2.4" 601 | source = "git+https://github.com/sebcrozet/ncollide#83df936309e15261451a8e9277fbc4fd78a4a211" 602 | dependencies = [ 603 | "nalgebra 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 604 | "ncollide_math 0.2.1 (git+https://github.com/sebcrozet/ncollide)", 605 | "ncollide_utils 0.2.4 (git+https://github.com/sebcrozet/ncollide)", 606 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 607 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 608 | ] 609 | 610 | [[package]] 611 | name = "ncollide_queries" 612 | version = "0.3.1" 613 | source = "git+https://github.com/sebcrozet/ncollide#83df936309e15261451a8e9277fbc4fd78a4a211" 614 | dependencies = [ 615 | "nalgebra 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 616 | "ncollide_entities 0.4.0 (git+https://github.com/sebcrozet/ncollide)", 617 | "ncollide_math 0.2.1 (git+https://github.com/sebcrozet/ncollide)", 618 | "ncollide_utils 0.2.4 (git+https://github.com/sebcrozet/ncollide)", 619 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 620 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 621 | ] 622 | 623 | [[package]] 624 | name = "ncollide_transformation" 625 | version = "0.2.2" 626 | source = "git+https://github.com/sebcrozet/ncollide#83df936309e15261451a8e9277fbc4fd78a4a211" 627 | dependencies = [ 628 | "nalgebra 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 629 | "ncollide_entities 0.4.0 (git+https://github.com/sebcrozet/ncollide)", 630 | "ncollide_math 0.2.1 (git+https://github.com/sebcrozet/ncollide)", 631 | "ncollide_procedural 0.2.4 (git+https://github.com/sebcrozet/ncollide)", 632 | "ncollide_queries 0.3.1 (git+https://github.com/sebcrozet/ncollide)", 633 | "ncollide_utils 0.2.4 (git+https://github.com/sebcrozet/ncollide)", 634 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 635 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 636 | ] 637 | 638 | [[package]] 639 | name = "ncollide_utils" 640 | version = "0.2.4" 641 | source = "git+https://github.com/sebcrozet/ncollide#83df936309e15261451a8e9277fbc4fd78a4a211" 642 | dependencies = [ 643 | "nalgebra 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 644 | "ncollide_math 0.2.1 (git+https://github.com/sebcrozet/ncollide)", 645 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 646 | "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 647 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 648 | ] 649 | 650 | [[package]] 651 | name = "noise" 652 | version = "0.1.5" 653 | source = "registry+https://github.com/rust-lang/crates.io-index" 654 | dependencies = [ 655 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 656 | "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 657 | ] 658 | 659 | [[package]] 660 | name = "num" 661 | version = "0.1.31" 662 | source = "registry+https://github.com/rust-lang/crates.io-index" 663 | dependencies = [ 664 | "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 665 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 666 | ] 667 | 668 | [[package]] 669 | name = "obj" 670 | version = "0.3.0" 671 | source = "registry+https://github.com/rust-lang/crates.io-index" 672 | dependencies = [ 673 | "genmesh 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 674 | ] 675 | 676 | [[package]] 677 | name = "objc" 678 | version = "0.1.8" 679 | source = "registry+https://github.com/rust-lang/crates.io-index" 680 | dependencies = [ 681 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 682 | "malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 683 | ] 684 | 685 | [[package]] 686 | name = "osmesa-sys" 687 | version = "0.0.5" 688 | source = "registry+https://github.com/rust-lang/crates.io-index" 689 | dependencies = [ 690 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 691 | "shared_library 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", 692 | ] 693 | 694 | [[package]] 695 | name = "png" 696 | version = "0.3.1" 697 | source = "registry+https://github.com/rust-lang/crates.io-index" 698 | dependencies = [ 699 | "bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 700 | "flate2 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", 701 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 702 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 703 | ] 704 | 705 | [[package]] 706 | name = "png" 707 | version = "0.4.1" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | dependencies = [ 710 | "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 711 | "flate2 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", 712 | "inflate 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 713 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 714 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 715 | ] 716 | 717 | [[package]] 718 | name = "rand" 719 | version = "0.3.14" 720 | source = "registry+https://github.com/rust-lang/crates.io-index" 721 | dependencies = [ 722 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 723 | ] 724 | 725 | [[package]] 726 | name = "rustc-serialize" 727 | version = "0.3.18" 728 | source = "registry+https://github.com/rust-lang/crates.io-index" 729 | 730 | [[package]] 731 | name = "serde" 732 | version = "0.6.14" 733 | source = "registry+https://github.com/rust-lang/crates.io-index" 734 | dependencies = [ 735 | "num 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", 736 | ] 737 | 738 | [[package]] 739 | name = "shared_library" 740 | version = "0.1.4" 741 | source = "registry+https://github.com/rust-lang/crates.io-index" 742 | dependencies = [ 743 | "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 744 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 745 | ] 746 | 747 | [[package]] 748 | name = "shell32-sys" 749 | version = "0.1.1" 750 | source = "registry+https://github.com/rust-lang/crates.io-index" 751 | dependencies = [ 752 | "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 753 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 754 | ] 755 | 756 | [[package]] 757 | name = "smallvec" 758 | version = "0.1.6" 759 | source = "registry+https://github.com/rust-lang/crates.io-index" 760 | 761 | [[package]] 762 | name = "tempdir" 763 | version = "0.3.4" 764 | source = "registry+https://github.com/rust-lang/crates.io-index" 765 | dependencies = [ 766 | "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 767 | ] 768 | 769 | [[package]] 770 | name = "tempfile" 771 | version = "1.1.3" 772 | source = "registry+https://github.com/rust-lang/crates.io-index" 773 | dependencies = [ 774 | "kernel32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 775 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 776 | "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", 777 | "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 778 | ] 779 | 780 | [[package]] 781 | name = "toml" 782 | version = "0.1.27" 783 | source = "registry+https://github.com/rust-lang/crates.io-index" 784 | dependencies = [ 785 | "rustc-serialize 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)", 786 | ] 787 | 788 | [[package]] 789 | name = "user32-sys" 790 | version = "0.1.2" 791 | source = "registry+https://github.com/rust-lang/crates.io-index" 792 | dependencies = [ 793 | "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 794 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 795 | ] 796 | 797 | [[package]] 798 | name = "wayland-client" 799 | version = "0.2.1" 800 | source = "registry+https://github.com/rust-lang/crates.io-index" 801 | dependencies = [ 802 | "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 803 | "dlib 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 804 | "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 805 | "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 806 | ] 807 | 808 | [[package]] 809 | name = "wayland-kbd" 810 | version = "0.2.1" 811 | source = "registry+https://github.com/rust-lang/crates.io-index" 812 | dependencies = [ 813 | "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 814 | "dlib 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 815 | "lazy_static 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)", 816 | "mmap 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 817 | "wayland-client 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 818 | ] 819 | 820 | [[package]] 821 | name = "wayland-window" 822 | version = "0.1.2" 823 | source = "registry+https://github.com/rust-lang/crates.io-index" 824 | dependencies = [ 825 | "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 826 | "tempfile 1.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 827 | "wayland-client 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 828 | ] 829 | 830 | [[package]] 831 | name = "winapi" 832 | version = "0.2.5" 833 | source = "registry+https://github.com/rust-lang/crates.io-index" 834 | 835 | [[package]] 836 | name = "winapi-build" 837 | version = "0.1.1" 838 | source = "registry+https://github.com/rust-lang/crates.io-index" 839 | 840 | [[package]] 841 | name = "x11-dl" 842 | version = "2.0.1" 843 | source = "registry+https://github.com/rust-lang/crates.io-index" 844 | dependencies = [ 845 | "dylib 0.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 846 | "libc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 847 | ] 848 | 849 | [[package]] 850 | name = "xml-rs" 851 | version = "0.1.26" 852 | source = "registry+https://github.com/rust-lang/crates.io-index" 853 | dependencies = [ 854 | "bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 855 | ] 856 | 857 | [[package]] 858 | name = "xml-rs" 859 | version = "0.2.2" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | dependencies = [ 862 | "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 863 | ] 864 | 865 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "thule" 3 | version = "0.1.0" 4 | authors = ["viperscape "] 5 | 6 | [dependencies] 7 | nalgebra = "*" 8 | 9 | font-atlas = "0.1.0" 10 | font-atlas-image = "0.1.0" 11 | image = "0.3.14" 12 | 13 | rustc-serialize = "0.3.16" 14 | bincode = "*" 15 | rand = "0.3.11" 16 | 17 | glium = "0.9.1" 18 | 19 | clock_ticks = "*" 20 | 21 | hex2d = "*" 22 | genmesh = "0.3.2" 23 | obj = "0.3.0" 24 | 25 | noise = "*" 26 | 27 | toml = "0.1.25" 28 | 29 | ncollide = { version = "0.6.0", git="https://github.com/sebcrozet/ncollide" } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![screenshot](thule-game-ss.png?raw=true) 2 | -------------------------------------------------------------------------------- /assets/config.toml: -------------------------------------------------------------------------------- 1 | [keys] 2 | A = "move_left" 3 | D = "move_right" 4 | W = "move_up" 5 | S = "move_down" 6 | M = "map_view" 7 | Tab = "focus" -------------------------------------------------------------------------------- /assets/font/SourceCodePro-Regular-20.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viperscape/thule/2aec64acc7ee9a664830250b88532256a61c7017/assets/font/SourceCodePro-Regular-20.json -------------------------------------------------------------------------------- /assets/font/SourceCodePro-Regular-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viperscape/thule/2aec64acc7ee9a664830250b88532256a61c7017/assets/font/SourceCodePro-Regular-20.png -------------------------------------------------------------------------------- /assets/font/UbuntuMono-20.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viperscape/thule/2aec64acc7ee9a664830250b88532256a61c7017/assets/font/UbuntuMono-20.json -------------------------------------------------------------------------------- /assets/font/UbuntuMono-20.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viperscape/thule/2aec64acc7ee9a664830250b88532256a61c7017/assets/font/UbuntuMono-20.png -------------------------------------------------------------------------------- /assets/mesh/cone.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 1 3 | 4 | newmtl None 5 | Ns 0 6 | Ka 0.000000 0.000000 0.000000 7 | Kd 0.8 0.8 0.8 8 | Ks 0.8 0.8 0.8 9 | d 1 10 | illum 2 11 | -------------------------------------------------------------------------------- /assets/mesh/cone.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.75 (sub 0) OBJ File: '' 2 | # www.blender.org 3 | mtllib cone.mtl 4 | v 0.000000 -0.500000 -0.500000 5 | v 0.097545 -0.500000 -0.490393 6 | v 0.191342 -0.500000 -0.461940 7 | v 0.277785 -0.500000 -0.415735 8 | v 0.353553 -0.500000 -0.353553 9 | v 0.415735 -0.500000 -0.277785 10 | v 0.461940 -0.500000 -0.191342 11 | v 0.490393 -0.500000 -0.097545 12 | v 0.500000 -0.500000 -0.000000 13 | v 0.000000 0.500000 0.000000 14 | v 0.490393 -0.500000 0.097545 15 | v 0.461940 -0.500000 0.191342 16 | v 0.415735 -0.500000 0.277785 17 | v 0.353553 -0.500000 0.353553 18 | v 0.277785 -0.500000 0.415735 19 | v 0.191342 -0.500000 0.461940 20 | v 0.097545 -0.500000 0.490393 21 | v -0.000000 -0.500000 0.500000 22 | v -0.097545 -0.500000 0.490393 23 | v -0.191342 -0.500000 0.461940 24 | v -0.277785 -0.500000 0.415735 25 | v -0.353554 -0.500000 0.353553 26 | v -0.415735 -0.500000 0.277785 27 | v -0.461940 -0.500000 0.191341 28 | v -0.490393 -0.500000 0.097545 29 | v -0.500000 -0.500000 -0.000000 30 | v -0.490393 -0.500000 -0.097546 31 | v -0.461940 -0.500000 -0.191342 32 | v -0.415734 -0.500000 -0.277786 33 | v -0.353553 -0.500000 -0.353554 34 | v -0.277785 -0.500000 -0.415735 35 | v -0.191341 -0.500000 -0.461940 36 | v -0.097544 -0.500000 -0.490393 37 | vn -0.259900 0.445500 -0.856700 38 | vn 0.087800 0.445500 -0.891000 39 | vn -0.422000 0.445500 -0.789600 40 | vn -0.568000 0.445500 -0.692100 41 | vn -0.692100 0.445500 -0.568000 42 | vn -0.789600 0.445500 -0.422000 43 | vn -0.856700 0.445500 -0.259900 44 | vn -0.891000 0.445500 -0.087800 45 | vn -0.891000 0.445500 0.087800 46 | vn -0.856700 0.445500 0.259900 47 | vn -0.789600 0.445500 0.422000 48 | vn -0.692100 0.445500 0.568000 49 | vn -0.568000 0.445500 0.692100 50 | vn -0.422000 0.445500 0.789600 51 | vn -0.259900 0.445500 0.856700 52 | vn -0.087800 0.445500 0.891000 53 | vn 0.087800 0.445500 0.891000 54 | vn 0.259900 0.445500 0.856700 55 | vn 0.422000 0.445500 0.789600 56 | vn 0.568000 0.445500 0.692100 57 | vn 0.692100 0.445500 0.568000 58 | vn 0.789600 0.445500 0.422000 59 | vn 0.856700 0.445500 0.259900 60 | vn 0.891000 0.445500 0.087800 61 | vn 0.891000 0.445500 -0.087800 62 | vn 0.856700 0.445500 -0.259900 63 | vn 0.789600 0.445500 -0.422000 64 | vn 0.692100 0.445500 -0.568000 65 | vn 0.568000 0.445500 -0.692100 66 | vn 0.422000 0.445500 -0.789600 67 | vn -0.087800 0.445500 -0.891000 68 | vn 0.259900 0.445500 -0.856700 69 | vn 0.000000 -1.000000 0.000000 70 | usemtl None 71 | s off 72 | f 32//1 10//1 33//1 73 | f 1//2 10//2 2//2 74 | f 31//3 10//3 32//3 75 | f 30//4 10//4 31//4 76 | f 29//5 10//5 30//5 77 | f 28//6 10//6 29//6 78 | f 27//7 10//7 28//7 79 | f 26//8 10//8 27//8 80 | f 25//9 10//9 26//9 81 | f 24//10 10//10 25//10 82 | f 23//11 10//11 24//11 83 | f 22//12 10//12 23//12 84 | f 21//13 10//13 22//13 85 | f 20//14 10//14 21//14 86 | f 19//15 10//15 20//15 87 | f 18//16 10//16 19//16 88 | f 17//17 10//17 18//17 89 | f 16//18 10//18 17//18 90 | f 15//19 10//19 16//19 91 | f 14//20 10//20 15//20 92 | f 13//21 10//21 14//21 93 | f 12//22 10//22 13//22 94 | f 11//23 10//23 12//23 95 | f 9//24 10//24 11//24 96 | f 8//25 10//25 9//25 97 | f 7//26 10//26 8//26 98 | f 6//27 10//27 7//27 99 | f 5//28 10//28 6//28 100 | f 4//29 10//29 5//29 101 | f 3//30 10//30 4//30 102 | f 33//31 10//31 1//31 103 | f 2//32 10//32 3//32 104 | f 1//33 9//33 14//33 105 | f 30//33 33//33 1//33 106 | f 30//33 31//33 32//33 107 | f 28//33 29//33 30//33 108 | f 26//33 27//33 28//33 109 | f 22//33 25//33 26//33 110 | f 22//33 23//33 24//33 111 | f 20//33 21//33 22//33 112 | f 18//33 19//33 20//33 113 | f 14//33 17//33 18//33 114 | f 14//33 15//33 16//33 115 | f 12//33 13//33 14//33 116 | f 9//33 11//33 12//33 117 | f 7//33 8//33 9//33 118 | f 5//33 6//33 7//33 119 | f 3//33 4//33 5//33 120 | f 1//33 2//33 3//33 121 | f 30//33 32//33 33//33 122 | f 26//33 28//33 30//33 123 | f 22//33 24//33 25//33 124 | f 26//33 20//33 22//33 125 | f 14//33 16//33 17//33 126 | f 9//33 12//33 14//33 127 | f 1//33 7//33 9//33 128 | f 1//33 3//33 5//33 129 | f 18//33 30//33 1//33 130 | f 18//33 20//33 26//33 131 | f 1//33 14//33 18//33 132 | f 1//33 5//33 7//33 133 | f 18//33 26//33 30//33 134 | -------------------------------------------------------------------------------- /assets/mesh/cube.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 1 3 | 4 | newmtl Material 5 | Ns 96.078431 6 | Ka 0.000000 0.000000 0.000000 7 | Kd 0.640000 0.640000 0.640000 8 | Ks 0.500000 0.500000 0.500000 9 | Ni 1.000000 10 | d 1.000000 11 | illum 2 12 | -------------------------------------------------------------------------------- /assets/mesh/cube.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.75 (sub 0) OBJ File: '' 2 | # www.blender.org 3 | mtllib cube.mtl 4 | v 0.250000 0.250000 -0.250000 5 | v 0.250000 -0.250000 -0.250000 6 | v -0.250000 -0.250000 -0.250000 7 | v -0.250000 0.250000 -0.250000 8 | v 0.250000 0.250000 0.250000 9 | v 0.250000 -0.250000 0.250000 10 | v -0.250000 -0.250000 0.250000 11 | v -0.250000 0.250000 0.250000 12 | vn -0.000000 0.000000 -1.000000 13 | vn 0.000000 0.000000 1.000000 14 | vn 1.000000 -0.000000 0.000000 15 | vn -0.000000 -1.000000 0.000000 16 | vn -1.000000 0.000000 -0.000000 17 | vn 0.000000 1.000000 0.000000 18 | usemtl Material 19 | s off 20 | f 1//1 2//1 3//1 21 | f 8//2 7//2 6//2 22 | f 5//3 6//3 2//3 23 | f 6//4 7//4 3//4 24 | f 7//5 8//5 4//5 25 | f 1//6 4//6 8//6 26 | f 4//1 1//1 3//1 27 | f 5//2 8//2 6//2 28 | f 1//3 5//3 2//3 29 | f 2//4 6//4 3//4 30 | f 3//5 7//5 4//5 31 | f 5//6 1//6 8//6 32 | -------------------------------------------------------------------------------- /assets/mesh/hex.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 1 3 | 4 | newmtl None 5 | Ns 0.000000 6 | Ka 0.000000 0.000000 0.000000 7 | Kd 0.640000 0.640000 0.640000 8 | Ks 0.800000 0.800000 0.800000 9 | Ni 1.000000 10 | d 1.000000 11 | illum 2 12 | -------------------------------------------------------------------------------- /assets/mesh/hex.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.75 (sub 0) OBJ File: '' 2 | # www.blender.org 3 | mtllib hex.mtl 4 | v 0.433013 0.000000 -0.250000 5 | v 0.000000 0.000000 0.000000 6 | v 0.433013 -0.000000 0.250000 7 | v 0.000000 0.000000 -0.500000 8 | v 0.000000 -0.000000 0.500000 9 | v -0.433013 0.000000 -0.250000 10 | v -0.433010 -0.000000 0.250000 11 | vn 0.000000 1.000000 0.000000 12 | usemtl None 13 | s 1 14 | f 1//1 2//1 3//1 15 | f 2//1 1//1 4//1 16 | f 2//1 5//1 3//1 17 | f 4//1 6//1 2//1 18 | f 5//1 2//1 7//1 19 | f 6//1 7//1 2//1 20 | -------------------------------------------------------------------------------- /assets/mesh/hex3d.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 1 3 | 4 | newmtl None 5 | Ns 0.000000 6 | Ka 0.000000 0.000000 0.000000 7 | Kd 0.640000 0.640000 0.640000 8 | Ks 0.800000 0.800000 0.800000 9 | Ni 1.000000 10 | d 1.000000 11 | illum 2 12 | -------------------------------------------------------------------------------- /assets/mesh/hex3d.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.75 (sub 0) OBJ File: '' 2 | # www.blender.org 3 | mtllib hex3d.mtl 4 | v 0.433013 0.650000 -0.250000 5 | v -0.433013 0.650000 0.250000 6 | v 0.433013 0.650000 0.250000 7 | v 0.000000 0.000000 -0.500000 8 | v 0.433013 0.000000 0.250000 9 | v -0.433013 0.000000 0.250000 10 | v -0.433013 0.000000 -0.250000 11 | v -0.433013 0.650000 -0.250000 12 | v 0.433013 0.000000 -0.250000 13 | v 0.000000 0.650000 -0.500000 14 | v 0.000000 0.000000 0.500000 15 | v 0.000000 0.650000 0.500000 16 | vn 0.000000 1.000000 0.000000 17 | vn 0.000000 -1.000000 0.000000 18 | vn -0.500000 0.000000 -0.866000 19 | vn 0.500000 0.000000 -0.866000 20 | vn 0.500000 -0.000000 0.866000 21 | vn -1.000000 0.000000 0.000000 22 | vn 1.000000 0.000000 0.000000 23 | vn -0.500000 -0.000000 0.866000 24 | usemtl None 25 | s 1 26 | f 1//1 2//1 3//1 27 | f 4//2 5//2 6//2 28 | f 4//3 7//3 8//3 29 | f 9//4 4//4 10//4 30 | f 11//5 5//5 3//5 31 | f 7//6 6//6 2//6 32 | f 5//7 9//7 1//7 33 | f 6//8 11//8 12//8 34 | f 2//1 1//1 10//1 35 | f 2//1 12//1 3//1 36 | f 10//1 8//1 2//1 37 | f 6//2 7//2 4//2 38 | f 5//2 11//2 6//2 39 | f 4//2 9//2 5//2 40 | f 10//3 4//3 8//3 41 | f 1//4 9//4 10//4 42 | f 12//5 11//5 3//5 43 | f 8//6 7//6 2//6 44 | f 3//7 5//7 1//7 45 | f 2//8 6//8 12//8 46 | -------------------------------------------------------------------------------- /assets/mesh/person.mtl: -------------------------------------------------------------------------------- 1 | # Blender MTL File: 'None' 2 | # Material Count: 1 3 | 4 | newmtl Material.001 5 | Ns 96.078431 6 | Ka 0.000000 0.000000 0.000000 7 | Kd 0.640000 0.640000 0.640000 8 | Ks 0.500000 0.500000 0.500000 9 | Ni 1.000000 10 | d 1.000000 11 | illum 2 12 | -------------------------------------------------------------------------------- /assets/mesh/person.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.75 (sub 0) OBJ File: '' 2 | # www.blender.org 3 | mtllib person.mtl 4 | v 0.000000 0.000000 -0.250000 5 | v 0.000000 1.000000 -0.250000 6 | v 0.048773 0.000000 -0.245196 7 | v 0.048773 1.000000 -0.245196 8 | v 0.095671 0.000000 -0.230970 9 | v 0.095671 1.000000 -0.230970 10 | v 0.138893 0.000000 -0.207867 11 | v 0.138893 1.000000 -0.207867 12 | v 0.176777 0.000000 -0.176777 13 | v 0.176777 1.000000 -0.176777 14 | v 0.207867 0.000000 -0.138893 15 | v 0.207867 1.000000 -0.138893 16 | v 0.230970 0.000000 -0.095671 17 | v 0.230970 1.000000 -0.095671 18 | v 0.245196 0.000000 -0.048773 19 | v 0.245196 1.000000 -0.048773 20 | v 0.250000 0.000000 -0.000000 21 | v 0.250000 1.000000 -0.000000 22 | v 0.245196 0.000000 0.048773 23 | v 0.245196 1.000000 0.048773 24 | v 0.230970 0.000000 0.095671 25 | v 0.230970 1.000000 0.095671 26 | v 0.207867 0.000000 0.138893 27 | v 0.207867 1.000000 0.138893 28 | v 0.176777 0.000000 0.176777 29 | v 0.176777 1.000000 0.176777 30 | v 0.138893 0.000000 0.207867 31 | v 0.138893 1.000000 0.207867 32 | v 0.095671 0.000000 0.230970 33 | v 0.095671 1.000000 0.230970 34 | v 0.048773 0.000000 0.245196 35 | v 0.048773 1.000000 0.245196 36 | v -0.000000 0.000000 0.250000 37 | v -0.000000 1.000000 0.250000 38 | v -0.048773 0.000000 0.245196 39 | v -0.048773 1.000000 0.245196 40 | v -0.095671 0.000000 0.230970 41 | v -0.095671 1.000000 0.230970 42 | v -0.138893 0.000000 0.207867 43 | v -0.138893 1.000000 0.207867 44 | v -0.176777 0.000000 0.176777 45 | v -0.176777 1.000000 0.176777 46 | v -0.207868 0.000000 0.138892 47 | v -0.207868 1.000000 0.138892 48 | v -0.230970 0.000000 0.095671 49 | v -0.230970 1.000000 0.095671 50 | v -0.245196 0.000000 0.048772 51 | v -0.245196 1.000000 0.048772 52 | v -0.250000 0.000000 -0.000000 53 | v -0.250000 1.000000 -0.000000 54 | v -0.245196 0.000000 -0.048773 55 | v -0.245196 1.000000 -0.048773 56 | v -0.230970 0.000000 -0.095671 57 | v -0.230970 1.000000 -0.095671 58 | v -0.207867 0.000000 -0.138893 59 | v -0.207867 1.000000 -0.138893 60 | v -0.176776 0.000000 -0.176777 61 | v -0.176776 1.000000 -0.176777 62 | v -0.138892 0.000000 -0.207868 63 | v -0.138892 1.000000 -0.207868 64 | v -0.095671 0.000000 -0.230970 65 | v -0.095671 1.000000 -0.230970 66 | v -0.048772 0.000000 -0.245196 67 | v -0.048772 1.000000 -0.245196 68 | v 0.000000 1.051067 -0.218660 69 | v 0.042659 1.051067 -0.214459 70 | v 0.083678 1.051067 -0.202016 71 | v 0.121481 1.051067 -0.181809 72 | v 0.154616 1.051067 -0.154616 73 | v 0.181809 1.051067 -0.121481 74 | v 0.202016 1.051067 -0.083678 75 | v 0.214459 1.051067 -0.042659 76 | v 0.218660 1.051067 -0.000000 77 | v 0.214459 1.051067 0.042658 78 | v 0.202016 1.051067 0.083678 79 | v 0.181809 1.051067 0.121481 80 | v 0.154616 1.051067 0.154616 81 | v 0.121481 1.051067 0.181809 82 | v 0.083678 1.051067 0.202016 83 | v 0.042658 1.051067 0.214459 84 | v -0.000000 1.051067 0.218660 85 | v -0.042659 1.051067 0.214459 86 | v -0.083678 1.051067 0.202016 87 | v -0.121481 1.051067 0.181809 88 | v -0.154616 1.051067 0.154616 89 | v -0.181809 1.051067 0.121481 90 | v -0.202016 1.051067 0.083677 91 | v -0.214459 1.051067 0.042658 92 | v -0.218660 1.051067 -0.000000 93 | v -0.214459 1.051067 -0.042659 94 | v -0.202016 1.051067 -0.083678 95 | v -0.181809 1.051067 -0.121481 96 | v -0.154616 1.051067 -0.154616 97 | v -0.121481 1.051067 -0.181810 98 | v -0.083677 1.051067 -0.202016 99 | v -0.042658 1.051067 -0.214459 100 | vn 0.098000 0.000000 -0.995200 101 | vn 0.290300 0.000000 -0.956900 102 | vn 0.471400 0.000000 -0.881900 103 | vn 0.634400 0.000000 -0.773000 104 | vn 0.773000 0.000000 -0.634400 105 | vn 0.881900 0.000000 -0.471400 106 | vn 0.956900 0.000000 -0.290300 107 | vn 0.995200 0.000000 -0.098000 108 | vn 0.995200 0.000000 0.098000 109 | vn 0.956900 0.000000 0.290300 110 | vn 0.881900 0.000000 0.471400 111 | vn 0.773000 0.000000 0.634400 112 | vn 0.634400 0.000000 0.773000 113 | vn 0.471400 0.000000 0.881900 114 | vn 0.290300 0.000000 0.956900 115 | vn 0.098000 0.000000 0.995200 116 | vn -0.098000 0.000000 0.995200 117 | vn -0.290300 0.000000 0.956900 118 | vn -0.471400 0.000000 0.881900 119 | vn -0.634400 0.000000 0.773000 120 | vn -0.773000 0.000000 0.634400 121 | vn -0.881900 0.000000 0.471400 122 | vn -0.956900 0.000000 0.290300 123 | vn -0.995200 0.000000 0.098000 124 | vn -0.995200 0.000000 -0.098000 125 | vn -0.956900 0.000000 -0.290300 126 | vn -0.881900 0.000000 -0.471400 127 | vn -0.773000 0.000000 -0.634400 128 | vn -0.634400 0.000000 -0.773000 129 | vn -0.471400 0.000000 -0.881900 130 | vn -0.247700 0.521200 -0.816700 131 | vn -0.098000 0.000000 -0.995200 132 | vn -0.290300 0.000000 -0.956900 133 | vn 0.000000 -1.000000 0.000000 134 | vn 0.000000 1.000000 0.000000 135 | vn 0.849300 0.521200 0.083600 136 | vn -0.247700 0.521200 0.816700 137 | vn -0.752600 0.521200 -0.402300 138 | vn 0.659700 0.521200 -0.541400 139 | vn 0.402300 0.521200 0.752600 140 | vn -0.816700 0.521200 0.247700 141 | vn 0.083600 0.521200 -0.849300 142 | vn -0.083600 0.521200 -0.849300 143 | vn 0.816700 0.521200 0.247700 144 | vn -0.402300 0.521200 0.752600 145 | vn -0.659700 0.521200 -0.541400 146 | vn 0.752600 0.521200 -0.402300 147 | vn 0.247700 0.521200 0.816700 148 | vn -0.849300 0.521200 0.083600 149 | vn 0.247700 0.521200 -0.816700 150 | vn 0.752600 0.521200 0.402300 151 | vn -0.541400 0.521200 0.659700 152 | vn -0.541400 0.521200 -0.659700 153 | vn 0.816700 0.521200 -0.247700 154 | vn 0.083600 0.521200 0.849300 155 | vn -0.849300 0.521200 -0.083600 156 | vn 0.402300 0.521200 -0.752700 157 | vn 0.659700 0.521200 0.541400 158 | vn -0.659700 0.521200 0.541400 159 | vn -0.402300 0.521200 -0.752600 160 | vn 0.849300 0.521200 -0.083600 161 | vn -0.083600 0.521200 0.849300 162 | vn -0.816700 0.521200 -0.247700 163 | vn 0.541400 0.521200 -0.659700 164 | vn 0.541400 0.521200 0.659700 165 | vn -0.752600 0.521200 0.402300 166 | vn 0.083700 0.521200 -0.849300 167 | vn -0.849300 0.521200 -0.083700 168 | vn 0.402300 0.521200 -0.752600 169 | vn -0.083700 0.521200 0.849300 170 | usemtl Material.001 171 | s off 172 | f 2//1 4//1 3//1 173 | f 4//2 6//2 5//2 174 | f 6//3 8//3 7//3 175 | f 8//4 10//4 9//4 176 | f 10//5 12//5 11//5 177 | f 12//6 14//6 13//6 178 | f 14//7 16//7 15//7 179 | f 16//8 18//8 17//8 180 | f 18//9 20//9 19//9 181 | f 20//10 22//10 21//10 182 | f 22//11 24//11 23//11 183 | f 24//12 26//12 25//12 184 | f 26//13 28//13 27//13 185 | f 28//14 30//14 29//14 186 | f 30//15 32//15 31//15 187 | f 32//16 34//16 33//16 188 | f 34//17 36//17 35//17 189 | f 36//18 38//18 37//18 190 | f 38//19 40//19 39//19 191 | f 40//20 42//20 41//20 192 | f 42//21 44//21 43//21 193 | f 44//22 46//22 45//22 194 | f 46//23 48//23 47//23 195 | f 48//24 50//24 49//24 196 | f 50//25 52//25 51//25 197 | f 52//26 54//26 53//26 198 | f 54//27 56//27 55//27 199 | f 56//28 58//28 57//28 200 | f 58//29 60//29 59//29 201 | f 60//30 62//30 61//30 202 | f 62//31 95//31 96//31 203 | f 64//32 2//32 1//32 204 | f 62//33 64//33 63//33 205 | f 1//34 17//34 33//34 206 | f 66//35 94//35 82//35 207 | f 20//36 18//36 73//36 208 | f 38//37 36//37 82//37 209 | f 56//38 54//38 91//38 210 | f 12//39 10//39 69//39 211 | f 28//40 78//40 79//40 212 | f 48//41 46//41 87//41 213 | f 4//42 2//42 65//42 214 | f 64//43 96//43 65//43 215 | f 22//44 20//44 74//44 216 | f 38//45 83//45 84//45 217 | f 58//46 56//46 92//46 218 | f 12//47 70//47 71//47 219 | f 32//48 30//48 79//48 220 | f 48//49 88//49 89//49 221 | f 4//50 66//50 67//50 222 | f 22//51 75//51 76//51 223 | f 40//52 84//52 85//52 224 | f 60//53 58//53 93//53 225 | f 14//54 71//54 72//54 226 | f 34//55 32//55 80//55 227 | f 50//56 89//56 90//56 228 | f 6//57 67//57 68//57 229 | f 24//58 76//58 77//58 230 | f 44//59 42//59 85//59 231 | f 62//60 60//60 94//60 232 | f 16//61 72//61 73//61 233 | f 36//62 34//62 81//62 234 | f 52//63 90//63 91//63 235 | f 8//64 68//64 69//64 236 | f 26//65 77//65 78//65 237 | f 46//66 44//66 86//66 238 | f 1//1 2//1 3//1 239 | f 3//2 4//2 5//2 240 | f 5//3 6//3 7//3 241 | f 7//4 8//4 9//4 242 | f 9//5 10//5 11//5 243 | f 11//6 12//6 13//6 244 | f 13//7 14//7 15//7 245 | f 15//8 16//8 17//8 246 | f 17//9 18//9 19//9 247 | f 19//10 20//10 21//10 248 | f 21//11 22//11 23//11 249 | f 23//12 24//12 25//12 250 | f 25//13 26//13 27//13 251 | f 27//14 28//14 29//14 252 | f 29//15 30//15 31//15 253 | f 31//16 32//16 33//16 254 | f 33//17 34//17 35//17 255 | f 35//18 36//18 37//18 256 | f 37//19 38//19 39//19 257 | f 39//20 40//20 41//20 258 | f 41//21 42//21 43//21 259 | f 43//22 44//22 45//22 260 | f 45//23 46//23 47//23 261 | f 47//24 48//24 49//24 262 | f 49//25 50//25 51//25 263 | f 51//26 52//26 53//26 264 | f 53//27 54//27 55//27 265 | f 55//28 56//28 57//28 266 | f 57//29 58//29 59//29 267 | f 59//30 60//30 61//30 268 | f 64//31 62//31 96//31 269 | f 63//32 64//32 1//32 270 | f 61//33 62//33 63//33 271 | f 57//34 63//34 1//34 272 | f 57//34 59//34 61//34 273 | f 53//34 55//34 57//34 274 | f 49//34 51//34 53//34 275 | f 41//34 47//34 49//34 276 | f 41//34 43//34 45//34 277 | f 37//34 39//34 41//34 278 | f 33//34 35//34 37//34 279 | f 25//34 31//34 33//34 280 | f 25//34 27//34 29//34 281 | f 21//34 23//34 25//34 282 | f 17//34 19//34 21//34 283 | f 13//34 15//34 17//34 284 | f 9//34 11//34 13//34 285 | f 5//34 7//34 9//34 286 | f 1//34 3//34 5//34 287 | f 57//34 61//34 63//34 288 | f 49//34 53//34 57//34 289 | f 41//34 45//34 47//34 290 | f 49//34 37//34 41//34 291 | f 25//34 29//34 31//34 292 | f 33//34 21//34 25//34 293 | f 1//34 13//34 17//34 294 | f 1//34 5//34 9//34 295 | f 33//34 57//34 1//34 296 | f 33//34 37//34 49//34 297 | f 17//34 21//34 33//34 298 | f 1//34 9//34 13//34 299 | f 33//34 49//34 57//34 300 | f 70//35 67//35 66//35 301 | f 70//35 69//35 68//35 302 | f 72//35 71//35 70//35 303 | f 74//35 73//35 72//35 304 | f 76//35 75//35 74//35 305 | f 74//35 77//35 76//35 306 | f 80//35 79//35 78//35 307 | f 82//35 81//35 80//35 308 | f 84//35 83//35 82//35 309 | f 86//35 85//35 84//35 310 | f 88//35 87//35 86//35 311 | f 90//35 89//35 88//35 312 | f 94//35 91//35 90//35 313 | f 94//35 93//35 92//35 314 | f 96//35 95//35 94//35 315 | f 66//35 65//35 96//35 316 | f 70//35 68//35 67//35 317 | f 66//35 72//35 70//35 318 | f 78//35 77//35 74//35 319 | f 74//35 80//35 78//35 320 | f 86//35 84//35 82//35 321 | f 82//35 88//35 86//35 322 | f 94//35 92//35 91//35 323 | f 66//35 96//35 94//35 324 | f 74//35 72//35 66//35 325 | f 82//35 80//35 74//35 326 | f 90//35 88//35 82//35 327 | f 82//35 94//35 90//35 328 | f 82//35 74//35 66//35 329 | f 74//36 20//36 73//36 330 | f 83//37 38//37 82//37 331 | f 92//38 56//38 91//38 332 | f 70//39 12//39 69//39 333 | f 30//40 28//40 79//40 334 | f 88//41 48//41 87//41 335 | f 66//67 4//67 65//67 336 | f 2//43 64//43 65//43 337 | f 75//44 22//44 74//44 338 | f 40//45 38//45 84//45 339 | f 93//46 58//46 92//46 340 | f 14//47 12//47 71//47 341 | f 80//48 32//48 79//48 342 | f 50//49 48//49 89//49 343 | f 6//50 4//50 67//50 344 | f 24//51 22//51 76//51 345 | f 42//52 40//52 85//52 346 | f 94//53 60//53 93//53 347 | f 16//54 14//54 72//54 348 | f 81//55 34//55 80//55 349 | f 52//68 50//68 90//68 350 | f 8//69 6//69 68//69 351 | f 26//58 24//58 77//58 352 | f 86//59 44//59 85//59 353 | f 95//60 62//60 94//60 354 | f 18//61 16//61 73//61 355 | f 82//70 36//70 81//70 356 | f 54//63 52//63 91//63 357 | f 10//64 8//64 69//64 358 | f 28//65 26//65 78//65 359 | f 87//66 46//66 86//66 360 | -------------------------------------------------------------------------------- /font-atlas/Cargo.lock: -------------------------------------------------------------------------------- 1 | [root] 2 | name = "atlas_gen" 3 | version = "0.1.0" 4 | dependencies = [ 5 | "font-atlas 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 6 | "font-atlas-freetype 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 7 | "font-atlas-image 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 8 | "freetype-rs 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 9 | "image 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", 10 | ] 11 | 12 | [[package]] 13 | name = "advapi32-sys" 14 | version = "0.1.2" 15 | source = "registry+https://github.com/rust-lang/crates.io-index" 16 | dependencies = [ 17 | "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 18 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 19 | ] 20 | 21 | [[package]] 22 | name = "bincode" 23 | version = "0.3.0" 24 | source = "registry+https://github.com/rust-lang/crates.io-index" 25 | dependencies = [ 26 | "byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", 27 | "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", 28 | ] 29 | 30 | [[package]] 31 | name = "bitflags" 32 | version = "0.3.3" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | 35 | [[package]] 36 | name = "byteorder" 37 | version = "0.3.13" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | 40 | [[package]] 41 | name = "byteorder" 42 | version = "0.4.2" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | 45 | [[package]] 46 | name = "color_quant" 47 | version = "1.0.0" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | 50 | [[package]] 51 | name = "enum_primitive" 52 | version = "0.0.1" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | dependencies = [ 55 | "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", 56 | ] 57 | 58 | [[package]] 59 | name = "enum_primitive" 60 | version = "0.1.0" 61 | source = "registry+https://github.com/rust-lang/crates.io-index" 62 | dependencies = [ 63 | "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", 64 | ] 65 | 66 | [[package]] 67 | name = "flate2" 68 | version = "0.2.11" 69 | source = "registry+https://github.com/rust-lang/crates.io-index" 70 | dependencies = [ 71 | "libc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 72 | "miniz-sys 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", 73 | ] 74 | 75 | [[package]] 76 | name = "font-atlas" 77 | version = "0.1.1" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | dependencies = [ 80 | "glyph_packer 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 81 | "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", 82 | ] 83 | 84 | [[package]] 85 | name = "font-atlas-freetype" 86 | version = "0.1.0" 87 | source = "registry+https://github.com/rust-lang/crates.io-index" 88 | dependencies = [ 89 | "font-atlas 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 90 | "font-atlas-image 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 91 | "freetype-rs 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", 92 | "glyph_packer 0.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 93 | "image 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", 94 | ] 95 | 96 | [[package]] 97 | name = "font-atlas-image" 98 | version = "0.1.2" 99 | source = "registry+https://github.com/rust-lang/crates.io-index" 100 | dependencies = [ 101 | "bincode 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 102 | "font-atlas 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 103 | "image 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 104 | "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", 105 | ] 106 | 107 | [[package]] 108 | name = "freetype-rs" 109 | version = "0.3.1" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | dependencies = [ 112 | "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 113 | "freetype-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 114 | "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 115 | ] 116 | 117 | [[package]] 118 | name = "freetype-rs" 119 | version = "0.4.1" 120 | source = "registry+https://github.com/rust-lang/crates.io-index" 121 | dependencies = [ 122 | "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 123 | "freetype-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 124 | "libc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 125 | ] 126 | 127 | [[package]] 128 | name = "freetype-sys" 129 | version = "0.1.2" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | dependencies = [ 132 | "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 133 | "libz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", 134 | "pkg-config 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 135 | ] 136 | 137 | [[package]] 138 | name = "freetype-sys" 139 | version = "0.2.1" 140 | source = "registry+https://github.com/rust-lang/crates.io-index" 141 | dependencies = [ 142 | "libc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 143 | "libz-sys 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 144 | "pkg-config 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 145 | ] 146 | 147 | [[package]] 148 | name = "gcc" 149 | version = "0.3.20" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | dependencies = [ 152 | "advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 153 | "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 154 | ] 155 | 156 | [[package]] 157 | name = "gif" 158 | version = "0.6.0" 159 | source = "registry+https://github.com/rust-lang/crates.io-index" 160 | dependencies = [ 161 | "color_quant 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 162 | "lzw 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", 163 | ] 164 | 165 | [[package]] 166 | name = "glob" 167 | version = "0.2.10" 168 | source = "registry+https://github.com/rust-lang/crates.io-index" 169 | 170 | [[package]] 171 | name = "glyph_packer" 172 | version = "0.0.0" 173 | source = "registry+https://github.com/rust-lang/crates.io-index" 174 | dependencies = [ 175 | "image 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)", 176 | ] 177 | 178 | [[package]] 179 | name = "image" 180 | version = "0.3.9" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | dependencies = [ 183 | "byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)", 184 | "enum_primitive 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 185 | "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", 186 | ] 187 | 188 | [[package]] 189 | name = "image" 190 | version = "0.5.4" 191 | source = "registry+https://github.com/rust-lang/crates.io-index" 192 | dependencies = [ 193 | "byteorder 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", 194 | "enum_primitive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 195 | "gif 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", 196 | "glob 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", 197 | "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", 198 | "png 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 199 | ] 200 | 201 | [[package]] 202 | name = "inflate" 203 | version = "0.1.0" 204 | source = "registry+https://github.com/rust-lang/crates.io-index" 205 | 206 | [[package]] 207 | name = "libc" 208 | version = "0.1.12" 209 | source = "registry+https://github.com/rust-lang/crates.io-index" 210 | 211 | [[package]] 212 | name = "libc" 213 | version = "0.2.2" 214 | source = "registry+https://github.com/rust-lang/crates.io-index" 215 | 216 | [[package]] 217 | name = "libz-sys" 218 | version = "0.1.9" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | dependencies = [ 221 | "gcc 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", 222 | "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", 223 | "pkg-config 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 224 | ] 225 | 226 | [[package]] 227 | name = "libz-sys" 228 | version = "1.0.0" 229 | source = "registry+https://github.com/rust-lang/crates.io-index" 230 | dependencies = [ 231 | "gcc 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", 232 | "libc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 233 | "pkg-config 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", 234 | ] 235 | 236 | [[package]] 237 | name = "lzw" 238 | version = "0.9.0" 239 | source = "registry+https://github.com/rust-lang/crates.io-index" 240 | 241 | [[package]] 242 | name = "miniz-sys" 243 | version = "0.1.7" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | dependencies = [ 246 | "gcc 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)", 247 | "libc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 248 | ] 249 | 250 | [[package]] 251 | name = "num" 252 | version = "0.1.28" 253 | source = "registry+https://github.com/rust-lang/crates.io-index" 254 | dependencies = [ 255 | "rand 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)", 256 | "rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", 257 | ] 258 | 259 | [[package]] 260 | name = "pkg-config" 261 | version = "0.3.6" 262 | source = "registry+https://github.com/rust-lang/crates.io-index" 263 | 264 | [[package]] 265 | name = "png" 266 | version = "0.4.0" 267 | source = "registry+https://github.com/rust-lang/crates.io-index" 268 | dependencies = [ 269 | "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", 270 | "flate2 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", 271 | "inflate 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 272 | "libc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 273 | "num 0.1.28 (registry+https://github.com/rust-lang/crates.io-index)", 274 | ] 275 | 276 | [[package]] 277 | name = "rand" 278 | version = "0.3.12" 279 | source = "registry+https://github.com/rust-lang/crates.io-index" 280 | dependencies = [ 281 | "advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", 282 | "libc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 283 | "winapi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", 284 | ] 285 | 286 | [[package]] 287 | name = "rustc-serialize" 288 | version = "0.3.16" 289 | source = "registry+https://github.com/rust-lang/crates.io-index" 290 | 291 | [[package]] 292 | name = "winapi" 293 | version = "0.2.5" 294 | source = "registry+https://github.com/rust-lang/crates.io-index" 295 | 296 | [[package]] 297 | name = "winapi-build" 298 | version = "0.1.1" 299 | source = "registry+https://github.com/rust-lang/crates.io-index" 300 | 301 | -------------------------------------------------------------------------------- /font-atlas/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "atlas_gen" 3 | version = "0.1.0" 4 | authors = ["viperscape "] 5 | 6 | [dependencies] 7 | font-atlas = "0.1.0" 8 | font-atlas-freetype = "0.1.0" 9 | font-atlas-image = "0.1.0" 10 | freetype-rs = "0.3.1" 11 | image = "0.3.15" -------------------------------------------------------------------------------- /font-atlas/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate font_atlas; 2 | extern crate font_atlas_freetype as freetype_atlas; 3 | extern crate font_atlas_image as image_atlas; 4 | extern crate freetype; 5 | extern crate image; 6 | 7 | use std::vec; 8 | 9 | fn ascii() -> vec::IntoIter { 10 | let mut v = Vec::with_capacity(256); 11 | for i in 0u8 .. 255 { 12 | let c = i as char; 13 | if !c.is_control() { 14 | v.push(c); 15 | } 16 | } 17 | v.into_iter() 18 | } 19 | 20 | // ./atlas_generator SomeFont.ttf 38 20 10 OtherFont.ttf 20 10 30 21 | fn main() { 22 | let mut targets: Vec<(String, Vec)> = vec![]; 23 | 24 | for arg in std::env::args().skip(1) { 25 | match arg.parse::().ok() { 26 | Some(i) => { 27 | if let Some(last) = targets.last_mut() { 28 | last.1.push(i); 29 | } else { 30 | println!("ERROR: The size {} must be matched to a font", i); 31 | std::process::exit(1); 32 | } 33 | } 34 | None => { 35 | targets.push((arg, vec![])); 36 | } 37 | } 38 | } 39 | 40 | for target in &targets { 41 | if target.1.len() == 0 { 42 | println!("ERROR: The font {} has no given sizes!", target.0); 43 | std::process::exit(2); 44 | } 45 | } 46 | 47 | let library = freetype::Library::init().ok().expect("Freetype library failed to open!"); 48 | 49 | for (file, sizes) in targets { 50 | render_face(&library, file, sizes); 51 | } 52 | } 53 | 54 | fn render_face(library: &freetype::Library, file: String, sizes: Vec) { 55 | if let Some(mut face) = library.new_face(file.clone(), 0).ok() { 56 | for size in sizes { 57 | let _ = face.set_pixel_sizes(0, size); 58 | match freetype_atlas::render(&mut face, ascii(), true) { 59 | Ok(rendered) => { 60 | let name = file.split('.').nth(0).unwrap_or(&file[..]); 61 | let img_path = format!("{}-{}.png", name, size); 62 | let meta_path = format!("{}-{}.json", name, size); 63 | image_atlas::save_atlas(rendered, image::ImageFormat::PNG, img_path, meta_path).ok().expect("Unable to save atlas"); 64 | } 65 | Err(_) => panic!("Atlas unable to render"), 66 | } 67 | } 68 | } 69 | else { panic!("No font face found") } 70 | } 71 | -------------------------------------------------------------------------------- /src/config.rs: -------------------------------------------------------------------------------- 1 | /// toml parser and config for keybindings, etc. 2 | use toml::{Parser,Value}; 3 | use std::fs::File; 4 | use std::io::Read; 5 | 6 | use glium::glutin::VirtualKeyCode; 7 | use std::collections::{HashMap,BTreeMap}; 8 | 9 | pub type Bindings = HashMap; 10 | pub trait Default{ 11 | fn default() -> Self; 12 | } 13 | pub type Config = BTreeMap; 14 | fn load (path: &str) -> Config { 15 | let mut input = String::new(); 16 | if let Some(mut file) = File::open(path).ok() { 17 | let _ = file.read_to_string(&mut input); 18 | } 19 | 20 | Parser::new(&input).parse().unwrap_or(BTreeMap::new()) 21 | } 22 | 23 | impl Default for Bindings { 24 | fn default() -> Bindings { 25 | let r = load("assets/config.toml"); 26 | let mut bindings = HashMap::new(); 27 | 28 | { 29 | if let Some(table) = r.get("keys") { 30 | match table { 31 | &Value::Table(ref keys) => { 32 | for key in keys.iter() { 33 | let vkey = { 34 | match key.0 as &str { 35 | "A" => VirtualKeyCode::A, 36 | "S" => VirtualKeyCode::S, 37 | "D" => VirtualKeyCode::D, 38 | "W" => VirtualKeyCode::W, 39 | "M" => VirtualKeyCode::M, 40 | "Tab" => VirtualKeyCode::Tab, 41 | _ => VirtualKeyCode::F12, 42 | } 43 | }; 44 | if let Some(action) = Actions::parse_string(key.1) { 45 | bindings.insert(action,vkey); 46 | } 47 | 48 | } 49 | } 50 | _ => {}, 51 | } 52 | } 53 | } 54 | 55 | bindings 56 | } 57 | } 58 | 59 | struct Actions; 60 | impl Actions { 61 | fn parse_string(action: &Value) -> Option { 62 | match action { 63 | &Value::String(ref action) => Some(action.clone()), 64 | _ => None, 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/events.rs: -------------------------------------------------------------------------------- 1 | use na::Vec2; 2 | 3 | pub enum Events { 4 | Quit, 5 | 6 | MouseClick(Vec2), 7 | MouseDrag((Vec2,Vec2)), 8 | 9 | Zoom(f32), 10 | } 11 | -------------------------------------------------------------------------------- /src/game.rs: -------------------------------------------------------------------------------- 1 | use std::path::Path; 2 | use std::fs::File; 3 | use std::io::{Read,Write}; 4 | 5 | use bincode::SizeLimit; 6 | use bincode::rustc_serialize::{encode, decode}; 7 | 8 | use ::{Grid,MAPSIZE,GridGroup}; 9 | 10 | use na::{zero,Vec3,Vec2}; 11 | use clock_ticks::precise_time_s; 12 | 13 | pub const MOVE_TIME: f64 = 0.095; 14 | 15 | pub struct GameState { 16 | pub player: Player, 17 | pub map: GridGroup, 18 | pub world: Grid, 19 | pub minimap: ::glium::Texture2d, 20 | pub map_view: bool, 21 | } 22 | 23 | impl GameState { 24 | pub fn new (display: &::glium::Display) -> GameState { 25 | let biome_seeds = ::grid::BiomeSeed::default(); 26 | let m = { 27 | if let Some(mut f) = File::open(&Path::new("map.dat")).ok() { 28 | let mut b = vec!(); 29 | let _ = f.read_to_end(&mut b); 30 | decode(&b[..]).unwrap() 31 | } 32 | else { 33 | let m = Grid::gen_map(Some(biome_seeds)); 34 | if let Some(mut f) = File::create(&Path::new("map.dat")).ok() { 35 | let b = encode(&m,SizeLimit::Infinite).unwrap(); 36 | let _ = f.write(&b); 37 | } 38 | m 39 | } 40 | }; 41 | 42 | let img = { 43 | if let Some(img) = ::image::open(&Path::new("map.png")).ok() { 44 | img 45 | } 46 | else { 47 | let img = Grid::export(&m); 48 | 49 | let mut f = File::create(&Path::new("map.png")).unwrap(); 50 | let _ = ::image::ImageRgb8(img.to_rgb()). 51 | save(&mut f, ::image::PNG); 52 | 53 | img 54 | } 55 | }; 56 | 57 | GameState { 58 | player: Player::new(), 59 | map: GridGroup::new(), 60 | world: m, 61 | minimap: ::glium::Texture2d::new(display,img).unwrap(), 62 | map_view: false, 63 | } 64 | } 65 | } 66 | 67 | pub struct Player { 68 | pub grid_pos: Vec2, 69 | time: f64, 70 | } 71 | 72 | impl Player { 73 | 74 | pub fn new() -> Player { 75 | Player { 76 | grid_pos: zero(), 77 | time: precise_time_s(), 78 | } 79 | } 80 | 81 | pub fn pos(&self,size: f32) -> Vec3 { 82 | Grid::hex_pos(self.grid_pos.y,self.grid_pos.x,size) 83 | } 84 | 85 | /// this shifts the player, after checking bounds of map 86 | /// then will generate the next set of tiles in the grid 87 | pub fn shift(&mut self, offset: Vec2, _grids: &GridGroup) { 88 | let time = precise_time_s(); 89 | if time-self.time < MOVE_TIME { return } 90 | let mut pos = self.grid_pos; 91 | 92 | if offset.x < 0 { 93 | if pos.x > 0 { 94 | pos.x -= 1; 95 | } 96 | } 97 | else if offset.x > 0 { 98 | if pos.x < MAPSIZE-1 { 99 | pos.x += 1; 100 | } 101 | } 102 | 103 | if offset.y < 0 { 104 | if pos.y > 0 { 105 | pos.y -= 1; 106 | } 107 | } 108 | else if offset.y > 0 { 109 | if pos.y < MAPSIZE-1 { 110 | pos.y += 1; 111 | } 112 | } 113 | 114 | //let tile = &grid.tiles[pos.x][pos.y]; 115 | //if tile.kind != TileKind::Stone { 116 | self.grid_pos = pos; 117 | self.time = time; 118 | //} 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/grid.rs: -------------------------------------------------------------------------------- 1 | use noise::{open_simplex2,Brownian2, Seed}; 2 | 3 | use na::{Vec3,Vec2,zero}; 4 | use ::ui::{Colorable}; 5 | 6 | pub const TILESIZE: f32 = 100.; 7 | pub const MAPSIZE: usize = 1000; // square 8 | pub const GRIDSIZE: usize = 25; 9 | pub const GROUPSIZE: usize = 3; 10 | 11 | #[derive(Debug,Clone,RustcEncodable, RustcDecodable, PartialEq)] 12 | pub struct Tile { 13 | pub kind: TileKind, 14 | } 15 | 16 | #[derive(Debug,Clone,RustcEncodable, RustcDecodable, PartialEq)] 17 | pub enum TileKind { 18 | Grass, 19 | Water, 20 | Stone, 21 | Sand, 22 | Snow, 23 | Ice, 24 | } 25 | 26 | 27 | #[derive(Debug,Clone,RustcEncodable, RustcDecodable, PartialEq)] 28 | pub struct Grid { 29 | pub tiles: Vec>, 30 | } 31 | 32 | impl Grid { 33 | pub fn new (seed: &BiomeSeed, start: Vec2, size: usize) -> Grid { 34 | let mut v = vec![vec![(Tile { kind: TileKind::Grass }, 35 | Biome::zero()); size];size]; 36 | let g = Grid::gen(seed,start, 37 | Vec2::new(size,size),); 38 | 39 | for (i,r) in g.iter().enumerate() { 40 | for (j,t) in r.iter().enumerate() { 41 | let tile = Biome::gen_tile(t); 42 | v[i][j] = (Tile { kind: tile }, 43 | t.clone()); 44 | } 45 | } 46 | 47 | Grid { tiles: v } 48 | } 49 | 50 | pub fn default () -> Grid { 51 | Grid::new(&BiomeSeed::default(),zero(),GRIDSIZE) 52 | } 53 | 54 | pub fn regen(s: &BiomeSeed, start: Vec2, size: Vec2, 55 | b: &mut Vec>) { 56 | 57 | for (i,r) in (start.y .. size.y+start.y).enumerate() { 58 | for (j,c) in (start.x .. size.x+start.x).enumerate() { 59 | let y = r as f32 * s.terra.1.y; 60 | let x = c as f32 * s.terra.1.x; 61 | 62 | let terra = Brownian2::new(open_simplex2, 4). 63 | wavelength(16.0). 64 | apply(&s.terra.0,&[x,y]); 65 | 66 | let y = r as f32 * s.humid.1.y; 67 | let x = c as f32 * s.humid.1.x; 68 | 69 | let humid = open_simplex2(&s.humid.0,&[x,y]); 70 | 71 | let y = r as f32 * s.temp.1.y; 72 | let x = c as f32 * s.temp.1.x; 73 | 74 | let temp = open_simplex2(&s.temp.0,&[x,y]); 75 | let temp = temp / s.temp.1.y; 76 | 77 | b[i][j] = Biome { 78 | humid: humid, 79 | temp: temp, 80 | terra: terra, 81 | }; 82 | } 83 | } 84 | } 85 | 86 | // TODO: reuse vec in regen/gen for gridgroup 87 | pub fn gen(s: &BiomeSeed, 88 | start: Vec2, 89 | size: Vec2,) -> Vec> { 90 | let mut pixels: Vec> = 91 | vec![vec![ Biome::zero();size.y]; size.x]; 92 | 93 | Grid::regen(s,start,size, &mut pixels); 94 | 95 | pixels 96 | } 97 | 98 | /// returns the appropriate real-coordinates of a grid's coords 99 | pub fn hex_pos (r: usize, c: usize, size: f32) -> Vec3 { 100 | let off = (r & 1) as f32 * (size / 2.); 101 | Vec3::new((c as f32 * size + off) * 0.866, 102 | 0., 103 | r as f32 * size * 0.75) 104 | } 105 | 106 | pub fn gen_map (seed: Option) -> Grid { 107 | let seed = seed.unwrap_or(BiomeSeed::default()); 108 | Grid::new(&seed, 109 | Vec2::new(0,0), 110 | MAPSIZE) 111 | } 112 | 113 | /// exports game map at larger size 114 | pub fn export (m: &Grid) -> ::image::DynamicImage { 115 | let mut v = vec!(); 116 | for n in m.tiles.iter() { 117 | for t in n.iter() { 118 | let b = ::ui::Render::get_tile_color(&t.0).to_bytes(); { 119 | v.push(b); 120 | } 121 | } 122 | } 123 | let mut img = ::image::ImageBuffer::new(MAPSIZE as u32, 124 | MAPSIZE as u32); 125 | 126 | let mut i = 0; 127 | for (_,_, pixel) in img.enumerate_pixels_mut() { 128 | *pixel = ::image::Rgb(v[i]); 129 | i += 1; 130 | } 131 | 132 | img = ::image::imageops::rotate180(&img); 133 | ::image::ImageRgb8(img) 134 | } 135 | /* /// intersects ray, based on dimensions and cam position 136 | pub fn has_ray (&self,cam:&Camera, with_mouse: Option<(&Mouse,Vec2)>) -> bool { 137 | let size = (self.size as f32 * 1. * cam.zoom) / 2.; 138 | let cube = Cuboid::new(Vec3::new(size, 1., size)); 139 | 140 | let r; 141 | 142 | if let Some(mouse) = with_mouse { 143 | r = cam.get_mouse_ray(mouse.0,mouse.1); 144 | } 145 | else { 146 | r = cam.get_ray(); 147 | } 148 | 149 | //let iso = Iso3::new(zero(),zero()); 150 | let rr = cube.toi_with_ray(&Identity::new(), &r, true); 151 | if let Some(rr) = rr { println!("rr:{:?}",rr); } 152 | rr.is_some() 153 | }*/ 154 | 155 | // NOTE: this should be deprecated soon 156 | pub fn debug (v: &Vec) -> Vec<&str> { 157 | let mut t = vec!(); 158 | for n in v { 159 | if n > &0. { 160 | if n > &0.5 { 161 | t.push("^"); //peak 162 | } 163 | else { 164 | t.push("|"); //grass 165 | } 166 | } 167 | else { 168 | if n > &-0.5 { 169 | t.push("~"); //water 170 | } 171 | else { 172 | t.push("*"); //surf 173 | } 174 | } 175 | } 176 | 177 | t 178 | } 179 | 180 | pub fn debug_prn(v: &Vec>,) { 181 | for n in v { 182 | let l = Grid::debug(n); 183 | let mut s = String::new(); 184 | for c in l { s.push_str(c); } 185 | println!("{}",s); 186 | } 187 | } 188 | } 189 | 190 | pub struct GridGroup { 191 | pub grids: Vec>, // relative origin coordinate 192 | } 193 | 194 | impl GridGroup { 195 | pub fn new() -> GridGroup { 196 | let mut grids = vec!(); 197 | 198 | for y in 0..GROUPSIZE { 199 | for x in 0..GROUPSIZE { 200 | let coord = Vec2::new(x*GRIDSIZE,y*GRIDSIZE); 201 | grids.push(coord); 202 | } 203 | } 204 | 205 | GridGroup { grids: grids } 206 | } 207 | 208 | /// updates grids based on player position 209 | /// this determines where the player is in terms of grid & 210 | /// position in list of gridgroup 211 | /// then finds which grid side to build and reposition for the 212 | /// grid instances 213 | // NOTE: I'll have to fix if pos > MAPSIZE 214 | pub fn update(&mut self,pos:Vec2) -> bool { 215 | let mut is_updated = true; 216 | for coord in self.grids.iter_mut() { 217 | if pos.x > coord.x + GRIDSIZE * 2 { 218 | coord.x += GRIDSIZE * 3; 219 | } 220 | else if (pos.x as isize) < coord.x as isize - GRIDSIZE as isize 221 | { 222 | let x = coord.x as isize - (GRIDSIZE * 3) as isize; 223 | if x >= 0 { 224 | coord.x = x as usize; 225 | } 226 | } 227 | else { is_updated = false } 228 | 229 | if pos.y > coord.y + GRIDSIZE * 2 { 230 | coord.y += GRIDSIZE * 3; 231 | } 232 | else if (pos.y as isize) < coord.y as isize - GRIDSIZE as isize 233 | { 234 | let y = coord.y as isize - (GRIDSIZE * 3) as isize; 235 | if y >= 0 { 236 | coord.y = y as usize; 237 | } 238 | } 239 | else { is_updated = false } 240 | } 241 | 242 | is_updated 243 | } 244 | } 245 | 246 | pub struct BiomeSeed { 247 | pub temp: (Seed,Vec2), 248 | pub humid: (Seed,Vec2), 249 | pub terra: (Seed,Vec2), 250 | } 251 | 252 | impl BiomeSeed { 253 | pub fn default () -> BiomeSeed { 254 | let terra_s = Seed::new(0); 255 | let terra_m = Vec2::new(0.05,0.05); 256 | 257 | let humid_s = Seed::new(1); 258 | let humid_m = Vec2::new(0.65,0.65); 259 | 260 | let temp_s = Seed::new(2); 261 | let temp_m = Vec2::new(0.01,0.025); 262 | 263 | BiomeSeed { 264 | temp: (temp_s,temp_m), 265 | humid: (humid_s,humid_m), 266 | terra: (terra_s,terra_m), 267 | } 268 | } 269 | } 270 | 271 | #[derive(Debug,Clone,RustcEncodable, RustcDecodable, PartialEq)] 272 | pub struct Biome { 273 | pub temp: f32, 274 | pub humid: f32, 275 | pub terra: f32, 276 | } 277 | 278 | impl Biome { 279 | pub fn zero() -> Biome { 280 | Biome { 281 | temp: 0., 282 | humid: 0., 283 | terra: 0., 284 | } 285 | } 286 | pub fn gen_tile(&self) -> TileKind { 287 | let water = - 0.25; 288 | if self.terra > water { 289 | if self.terra > 0.35 { 290 | if self.temp < -0.2 && 291 | self.humid > 0.45 { 292 | TileKind::Stone//TileKind::Snow 293 | } 294 | else { TileKind::Stone } 295 | } 296 | else if self.terra > water+0.15 { TileKind::Grass } 297 | else { TileKind::Sand } 298 | } 299 | else { 300 | if self.temp < -0.2 && 301 | self.humid < 0.45 { 302 | TileKind::Water//TileKind::Ice 303 | } 304 | else { TileKind::Water } 305 | } 306 | } 307 | } 308 | -------------------------------------------------------------------------------- /src/input/keyboard.rs: -------------------------------------------------------------------------------- 1 | use glium::glutin::Event as glutin_events; 2 | use glium::glutin::Event::{KeyboardInput}; 3 | use glium::glutin::VirtualKeyCode; 4 | use glium::glutin::ElementState::{Pressed,Released}; 5 | 6 | /// Keyboard Input Controller 7 | pub struct Keyboard { 8 | held_keys: [bool;256], //keys currently being pressed 9 | rel_keys: [bool;256], //keys currently being pressed 10 | } 11 | 12 | impl Keyboard { 13 | pub fn new () -> Keyboard { 14 | Keyboard { held_keys: [false;256], 15 | rel_keys: [false;256] } 16 | } 17 | 18 | pub fn get_held_keys(&self) -> &[bool;256] { 19 | &self.held_keys 20 | } 21 | 22 | pub fn get_released_keys(&self) -> &[bool;256] { 23 | &self.rel_keys 24 | } 25 | 26 | pub fn update( 27 | &mut self, 28 | window_events: &Vec,) 29 | { 30 | // reset released keys 31 | for key in self.rel_keys.iter_mut() { 32 | *key = false; 33 | } 34 | 35 | for event in window_events.iter() { 36 | match *event { 37 | KeyboardInput(Pressed, _, Some(key)) => { 38 | self.held_keys[key as usize] = true; 39 | }, 40 | KeyboardInput(Released, _, Some(key)) => { 41 | let nkey = key as usize; 42 | self.held_keys[nkey] = false; 43 | self.rel_keys[nkey] = true; 44 | 45 | //special case for caps lock 46 | if key == VirtualKeyCode::Capital { 47 | self.held_keys[nkey] != self.held_keys[nkey]; 48 | } 49 | }, 50 | _ => {}, 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/input/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod mouse; 2 | pub mod keyboard; 3 | 4 | pub use self::keyboard::Keyboard; 5 | -------------------------------------------------------------------------------- /src/input/mouse.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | 3 | use clock_ticks::precise_time_s; 4 | use na::{Vec2, 5 | Pnt3,Vec3}; 6 | 7 | use glium::glutin::Event as glutin_events; 8 | use glium::glutin::ElementState; 9 | use glium::glutin::MouseButton; 10 | use glium::glutin::MouseScrollDelta; 11 | use glium::glutin::Event::{ 12 | MouseMoved, 13 | MouseInput, 14 | MouseWheel, 15 | }; 16 | use ::events::Events; 17 | use ::ui::Camera; 18 | 19 | const DRAGMIN_PX: i32 = 5i32; // arbitrary 5px minimum 20 | const DRAGMIN_TIME: f64 = 0.30f64; // 30ms time minimum 21 | 22 | #[derive(Debug)] 23 | pub struct Mouse { 24 | pos: (i32,i32), 25 | drag: (Option<(i32,i32)>,Option<(i32,i32)>), 26 | drag_start: f64, 27 | click: Option<(i32,i32)>, 28 | } 29 | 30 | impl Mouse { 31 | pub fn new() -> Mouse { 32 | Mouse { 33 | pos: (0,0), 34 | drag: (None,None), 35 | drag_start: precise_time_s(), 36 | click: None, 37 | } 38 | } 39 | pub fn update ( &mut self, 40 | window_events: &Vec, 41 | events: &mut Vec, 42 | window_size: Vec2) { 43 | for event in window_events.iter() { 44 | match *event { 45 | MouseMoved(pos) => { 46 | self.pos = pos; 47 | }, 48 | MouseInput(ElementState::Pressed,MouseButton::Left) => { 49 | self.drag.0 = Some(self.pos); 50 | self.drag_start = precise_time_s(); 51 | }, 52 | MouseInput(ElementState::Released,MouseButton::Left) => { 53 | if ((precise_time_s()-self.drag_start) > DRAGMIN_TIME) & 54 | (((self.drag.0).unwrap().0 - self.pos.0).abs() > 55 | DRAGMIN_PX) & 56 | (((self.drag.0).unwrap().1 - self.pos.1).abs() > 57 | DRAGMIN_PX) 58 | { 59 | self.drag.1 = Some(self.pos); 60 | self.click = None; 61 | } 62 | else { 63 | self.click = self.drag.0; 64 | self.drag.0 = None; 65 | } 66 | 67 | self.handler(events,window_size); 68 | }, 69 | MouseWheel(d) => { 70 | match d { 71 | MouseScrollDelta::LineDelta(_,y) => { 72 | events.push(Events::Zoom(y as f32)); 73 | }, 74 | MouseScrollDelta::PixelDelta(_,y) => { 75 | events.push(Events::Zoom(y as f32)); 76 | }, 77 | } 78 | }, 79 | _ => { }, 80 | } 81 | } 82 | } 83 | pub fn is_dragging (&self) -> bool { 84 | self.drag.0.is_some() 85 | } 86 | 87 | pub fn get_drag(&mut self) -> Option<((i32,i32),(i32,i32))> { 88 | if let Some(s) = self.drag.0 { 89 | if let Some(e) = self.drag.1 { 90 | let drag = Some((s,e)); 91 | self.drag = (None,None); 92 | drag 93 | } 94 | else { None } 95 | } 96 | else { None } 97 | } 98 | 99 | pub fn get_click(&mut self) -> Option<(i32,i32)> { 100 | let click = self.click; 101 | self.click = None; 102 | click 103 | } 104 | 105 | fn handler(&mut self, 106 | events: &mut Vec, 107 | _win_size: Vec2,) { 108 | 109 | if let Some(click) = self.click { 110 | let click = Vec2::new(click.0 as f32, click.1 as f32); 111 | events.push(Events::MouseClick(click)); 112 | } 113 | else if let Some(end) = self.drag.1 { 114 | let start = self.drag.0.unwrap(); 115 | let start = Vec2::new(start.0 as f32,start.1 as f32); 116 | let end = Vec2::new(end.0 as f32,end.1 as f32); 117 | events.push(Events::MouseDrag((start,end))); 118 | } 119 | } 120 | 121 | /// determines if point is within other points 122 | fn within_bounds(p: f32, start: f32, end: f32) -> bool { 123 | let mut within = false; 124 | if start < end { 125 | if (p > start) & 126 | (p < end) { within = true; } 127 | } 128 | else { 129 | if (p < start) & 130 | (p > end) { within = true; } 131 | } 132 | 133 | within 134 | } 135 | 136 | /// converts mouse coordinate to world position 137 | pub fn convert_ui_coord(pos: Vec2, window_size: Vec2) -> Vec2 { 138 | let x = pos.x - window_size.x / 2.0; 139 | let y = pos.y - window_size.y / 2.0; 140 | 141 | Vec2::new(x,-1.0*y) 142 | } 143 | 144 | /// returns base (start,dir) for building a ray 145 | pub fn get_ray (&self, win_size: Vec2, cam: &Camera, is_2d: bool) -> (Pnt3,Vec3) { 146 | let pos = Vec2::new(self.pos.0 as f32,self.pos.1 as f32); 147 | if is_2d { 148 | let coord = Mouse::convert_ui_coord(pos,win_size) * cam.zoom; 149 | let dir = Vec3::new(0.0,0.0,1.0); //NOTE: might need inv 150 | return (Pnt3::new(coord.x,coord.y,0.0),dir) 151 | } 152 | 153 | let pv = ::ui::transforms::Transforms::grid(win_size,cam).to_pv(); 154 | 155 | let r = ::ui::transforms::unproject(pv, &pos, &win_size); 156 | (*cam.pos.as_pnt(),r.1) 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /src/interface.rs: -------------------------------------------------------------------------------- 1 | use glium::glutin::Event as glutin_event; 2 | use glium::{Display}; 3 | use na::{Vec2,zero}; 4 | 5 | use ::ui::{Target,Colors,Render,Camera}; 6 | use ::input::keyboard::Keyboard; 7 | use ::input::mouse::Mouse; 8 | use ::events::Events; 9 | use ::{GameState,Bindings}; 10 | 11 | pub struct Interface { 12 | display: Display, 13 | pub render: Render, 14 | pub keyboard: Keyboard, 15 | pub bindings: Bindings, 16 | mouse: Mouse, 17 | 18 | pub events: Vec, 19 | 20 | pub dt: f64, 21 | 22 | pub cam: Camera, 23 | } 24 | 25 | impl Interface { 26 | pub fn new (size_x: u32, size_y: u32,bindings:Bindings) -> Interface { 27 | let mut display: Display = Target::new(size_x, size_y); 28 | let render = Render::new(&mut display); 29 | 30 | Interface { 31 | display: display, 32 | render: render, 33 | keyboard: Keyboard::new(), 34 | bindings: bindings, 35 | mouse: Mouse::new(), 36 | events: vec!(), 37 | dt: 0.0, 38 | cam: Camera::default(), 39 | } 40 | } 41 | 42 | pub fn update (&mut self, 43 | game: &GameState) { 44 | let mut window_events = vec!(); 45 | for e in self.display.poll_events() { 46 | window_events.push(e); 47 | } 48 | 49 | // handle a closed-window event 50 | for event in window_events.iter() { 51 | match *event { 52 | glutin_event::Closed => self.events.push(Events::Quit), 53 | //glutin_event::Resized(x,y) => { 54 | //rebuild context? 55 | //}, 56 | _ => {}, 57 | } 58 | } 59 | 60 | self.keyboard.update(&window_events,); 61 | if let Some(win_size) = self.get_win_size() { 62 | self.mouse.update(&window_events, 63 | &mut self.events, 64 | win_size); 65 | 66 | // if game.map.has_ray(&self.cam,None) { //Some((&self.mouse,win_size))) { 67 | // println!("r!"); 68 | // } 69 | 70 | 71 | if win_size != zero() { 72 | self.dt = self.render.update(&mut self.display, 73 | Colors::grey_dark(), 74 | game, 75 | &self.cam); 76 | } 77 | } 78 | } 79 | 80 | pub fn get_display_mut (&mut self) -> &mut Display { 81 | &mut self.display 82 | } 83 | 84 | pub fn get_win_size(&self) -> Option> { 85 | if let Some(size) = Target::get_size(&self.display) { 86 | return Some(Vec2::new(size.0 as f32,size.1 as f32)) 87 | } 88 | None 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | 3 | extern crate rustc_serialize; 4 | extern crate rand; 5 | extern crate bincode; 6 | 7 | #[macro_use] extern crate glium; 8 | extern crate nalgebra as na; 9 | extern crate ncollide as nc; 10 | 11 | extern crate font_atlas; 12 | extern crate font_atlas_image; 13 | extern crate image; 14 | 15 | extern crate clock_ticks; 16 | 17 | extern crate obj; 18 | extern crate genmesh; 19 | 20 | extern crate hex2d; 21 | 22 | extern crate noise; 23 | extern crate toml; 24 | 25 | mod ui; 26 | mod input; 27 | mod events; 28 | mod interface; 29 | mod grid; 30 | mod game; 31 | mod config; 32 | 33 | pub use font_atlas::{RenderedFont}; 34 | pub use image::DynamicImage; 35 | pub type Font = RenderedFont; 36 | 37 | pub use events::Events; 38 | pub use interface::Interface; 39 | pub use grid::{Grid,GridGroup,TileKind,Tile, 40 | GRIDSIZE,GROUPSIZE,MAPSIZE}; 41 | pub use game::{GameState,Player}; 42 | pub use input::Keyboard; 43 | pub use config::{Bindings,Default}; 44 | pub use ui::Camera; 45 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate rand; 2 | 3 | extern crate thule; 4 | use thule::{Interface,Events,GameState,Keyboard, 5 | Bindings,Default}; 6 | 7 | extern crate glium; 8 | use glium::glutin::VirtualKeyCode; 9 | 10 | extern crate nalgebra as na; 11 | use na::{Vec3,Vec2,zero}; 12 | 13 | fn main() { 14 | let mut iface = Interface::new(800,800,Bindings::default()); 15 | let mut game = GameState::new(&iface.get_display_mut()); 16 | 17 | 'main: loop { 18 | check_keys(&mut game,&mut iface); 19 | let offset = move_cam(&iface.keyboard); 20 | iface.cam.pos = iface.cam.pos + offset; 21 | 22 | let size = 100. * iface.cam.zoom; 23 | let offset = move_player(&iface); 24 | game.player.shift(offset,&game.map); 25 | iface.cam.repos(game.player.pos(size)); 26 | 27 | // update world mesh data if needed 28 | if game.map.update(game.player.grid_pos) { 29 | 30 | } 31 | 32 | 33 | iface.update(&game); 34 | 35 | for e in iface.events.drain(..) { 36 | match e { 37 | Events::Quit => break 'main, 38 | Events::Zoom(z) => { // TODO: reset camera pos? 39 | if z > 0. { iface.cam.zoom *= 1.1; } 40 | else { iface.cam.zoom *= 0.9; } 41 | }, 42 | _ => {}, 43 | } 44 | } 45 | } 46 | } 47 | 48 | fn check_keys (gs: &mut GameState,iface: &mut Interface) { 49 | let keys = iface.keyboard.get_released_keys(); 50 | 51 | if when("map_view",&iface,) { 52 | gs.map_view = !gs.map_view; 53 | } 54 | 55 | let size = 100. * iface.cam.zoom; 56 | if when("focus",&iface) { 57 | iface.cam.look_at(gs.player.pos(size)); 58 | } 59 | 60 | let held = iface.keyboard.get_held_keys(); 61 | if held[VirtualKeyCode::F12 as usize] & 62 | held[VirtualKeyCode::Escape as usize] { 63 | iface.events.push(Events::Quit); 64 | } 65 | } 66 | 67 | 68 | fn when_action(action: &str, iface: &Interface, held: bool) -> bool { 69 | let bindings = &iface.bindings; 70 | let keys = { 71 | if held { iface.keyboard.get_held_keys() } 72 | else { iface.keyboard.get_released_keys() } 73 | }; 74 | if let Some(vkey) = bindings.get(action) { 75 | keys[*vkey as usize] 76 | } 77 | else { false } 78 | } 79 | 80 | fn when_held(action: &str, iface: &Interface,) -> bool { 81 | when_action(action,iface,true) 82 | } 83 | fn when(action: &str, iface: &Interface,) -> bool { 84 | when_action(action,iface,false) 85 | } 86 | 87 | 88 | // TODO: investigate how poor this hmap lookup is 89 | fn move_player(iface: &Interface) -> Vec2 { 90 | let mut v = na::zero(); 91 | 92 | let up = Vec2::new(0,1); 93 | let down = Vec2::new(0,-1); 94 | let left = Vec2::new(1,0); 95 | let right = Vec2::new(-1,0); 96 | 97 | if when_held("move_up",&iface) { 98 | v = v + up + left 99 | } 100 | if when_held("move_down",&iface) { 101 | v = v + down + right 102 | } 103 | if when_held("move_left",&iface) { 104 | v = v + down + left 105 | } 106 | if when_held("move_right",&iface) { 107 | v = v + up + right 108 | } 109 | 110 | v 111 | } 112 | 113 | fn move_cam(kb: &Keyboard,) -> Vec3 { 114 | let mut v = na::zero(); 115 | let keys = kb.get_held_keys(); 116 | 117 | if keys[VirtualKeyCode::Up as usize] { 118 | v = v + Vec3::new(10.,0.,10.) 119 | } 120 | if keys[VirtualKeyCode::Down as usize] { 121 | v = v + Vec3::new(-10.,0.,-10.) 122 | } 123 | if keys[VirtualKeyCode::Left as usize] { 124 | v = v + Vec3::new(5.,0.,-5.) 125 | } 126 | if keys[VirtualKeyCode::Right as usize] { 127 | v = v + Vec3::new(-5.,0.,5.) 128 | } 129 | 130 | v 131 | } 132 | -------------------------------------------------------------------------------- /src/ui/atlas.rs: -------------------------------------------------------------------------------- 1 | use std::fs::File; 2 | 3 | use font_atlas::{RenderedFont}; 4 | use font_atlas_image::{read_atlas}; 5 | use image::{DynamicImage}; 6 | 7 | use glium::texture::{Texture2d}; 8 | use glium::Display; 9 | 10 | use ::Font; 11 | 12 | pub struct Atlas; 13 | 14 | impl Atlas { 15 | pub fn new (path: &str) -> Option> { 16 | let atlas_img = format!("{}.png",path); 17 | let atlas_meta = format!("{}.json",path); 18 | 19 | if let Some(mut atlas_img) = File::open(atlas_img).ok() { 20 | if let Some(mut atlas_meta) = File::open(atlas_meta).ok() { 21 | let data = 22 | read_atlas(&mut atlas_img, 23 | &mut atlas_meta).ok(). 24 | expect("Error loading atlas!"); 25 | 26 | return Some(data) 27 | 28 | } 29 | } 30 | None 31 | } 32 | 33 | pub fn sample_tex<'a> (c: char, 34 | font: &mut Font, 35 | display: &Display) -> 36 | Option { //RawImage2d<'a,u8>> { 37 | 38 | if let Some(c) = font.char_info(c) { 39 | if c.image_size.0 == 0 { return None } //no char found! 40 | let img = font.image_mut(); 41 | let img = img.crop(c.image_position.0, 42 | c.image_position.1, 43 | c.image_size.0, 44 | c.image_size.1).flipv(); 45 | // let raw = img.into_raw(); 46 | //return Some(raw) 47 | if let Some(tex) = Texture2d::new(display, img).ok() { 48 | return Some(tex) 49 | } 50 | } 51 | None 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/ui/camera.rs: -------------------------------------------------------------------------------- 1 | use na::{self, 2 | Vec3,zero, 3 | Iso3,Rot3, 4 | Vec2, 5 | Pnt3,}; 6 | use nc::ray::{Ray,}; 7 | use ::input::mouse::Mouse; 8 | 9 | pub struct Camera { 10 | offset: Vec3, 11 | pub pos: Vec3, 12 | iso: Iso3, 13 | pub zoom: f32, 14 | 15 | at: Vec3, // NOTE: this is for cam dir, ideally we'd turn iso into this, somehow 16 | } 17 | 18 | impl Camera { 19 | pub fn default () -> Camera { 20 | let offset = Vec3::new(40.,-40.,40.); 21 | let mut cam = Camera { 22 | offset: offset, 23 | pos: offset, 24 | iso: Iso3::new(zero(),zero()), 25 | zoom: 0.45, 26 | at: zero(), 27 | }; 28 | 29 | cam.look_at(Vec3::new(0.,0.,0.)); 30 | cam 31 | } 32 | 33 | pub fn new () -> Camera { 34 | Camera { 35 | offset: zero(), 36 | pos: Vec3::new(0.,0.,1.), 37 | iso: Iso3::new(zero(),zero()), 38 | zoom: 1., 39 | at: zero(), 40 | } 41 | } 42 | 43 | /// updates lookat iso transform 44 | pub fn look_at (&mut self, at: Vec3) { 45 | self.at = at; // store for camera ray 46 | 47 | let at = at - self.pos; 48 | let rot = Rot3::look_at_z(&at, 49 | &Vec3::y()); 50 | self.iso = Iso3 { translation: self.pos, 51 | rotation: rot, }; 52 | } 53 | 54 | pub fn repos(&mut self, to:Vec3) { 55 | self.pos = to + self.offset; 56 | } 57 | 58 | /// get's direction pointing 59 | pub fn dir(&self) -> Vec3 { 60 | na::normalize(&(self.at - self.pos)) 61 | } 62 | 63 | pub fn update (&self,) -> Iso3 { 64 | let mut iso = self.iso; 65 | iso.translation = self.pos; 66 | iso 67 | } 68 | 69 | pub fn get_mouse_ray (&self, mouse: &Mouse, win_size: Vec2) -> Ray> { 70 | let r = mouse.get_ray(win_size, 71 | &self,false); 72 | Ray::new(r.0,r.1) 73 | } 74 | 75 | pub fn get_ray (&self,) -> Ray> { 76 | Ray::new(*self.pos.as_pnt(), 77 | self.dir()) 78 | } 79 | } 80 | 81 | -------------------------------------------------------------------------------- /src/ui/color.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | use rand; 3 | 4 | use rustc_serialize::hex::{FromHex, ToHex}; 5 | 6 | pub type Color = [f32;3]; 7 | 8 | pub trait Colorable { 9 | fn from_bytes(b: &[u8;3]) -> Color; 10 | fn from_hex(hex: &str) -> Option; 11 | fn to_bytes(&self) -> [u8;3]; 12 | fn to_hex(&self) -> String; 13 | fn mix(&self, other: Color) -> Color; 14 | fn add(&self, other: Color) -> Color; 15 | fn greyscale_ntsc(&self) -> Color; 16 | fn greyscale_atsc(&self) -> Color; 17 | } 18 | 19 | // TODO: implement rgba alpha, this will change mix functions 20 | impl Colorable for Color { 21 | fn from_bytes(b: &[u8;3]) -> Color { 22 | [b[0] as f32 / 255.0, 23 | b[1] as f32 / 255.0, 24 | b[2] as f32 / 255.0] 25 | } 26 | fn from_hex(hex: &str) -> Option { 27 | if let Ok(ref hex) = hex.from_hex() { 28 | return Some(Color::from_bytes(&[hex[0],hex[1],hex[2]])) 29 | } 30 | 31 | None 32 | } 33 | 34 | fn to_bytes(&self) -> [u8;3] { 35 | [(self[0] * 255.0) as u8, 36 | (self[1] * 255.0) as u8, 37 | (self[2] * 255.0) as u8] 38 | } 39 | fn to_hex(&self) -> String { 40 | let r = self.to_bytes(); 41 | let mut v: Vec = vec!(); 42 | v.extend(&r); 43 | v.to_hex() 44 | } 45 | 46 | // NOTE: this may be separated out to different trait 47 | /// this will mix two colors, additively based on average (natural) 48 | fn mix(&self, other: Color) -> Color { 49 | [(self[0]+other[0])/2.0, 50 | (self[1]+other[1])/2.0, 51 | (self[2]+other[2])/2.0,] 52 | } 53 | /// this will add two colors, typical RGB additive 54 | fn add(&self, other: Color) -> Color { 55 | [min((self[0]+other[0]),255.0), 56 | min((self[1]+other[1]),255.0), 57 | min((self[2]+other[2]),255.0),] 58 | } 59 | /// convert to greyscale 60 | /// https://en.wikipedia.org/wiki/Grayscale#Luma_coding_in_video_systems 61 | // TODO: fix precision mismatch with clamping? 62 | // eg: cyan should equal b3b3b3, not b2b2b2 63 | fn greyscale_ntsc(&self) -> Color { 64 | let gs = 65 | self[0] * 0.2989 + 66 | self[1] * 0.5870 + 67 | self[2] * 0.1140; 68 | 69 | [gs,gs,gs] 70 | } 71 | fn greyscale_atsc(&self) -> Color { 72 | let gs = 73 | self[0] * 0.2126 + 74 | self[1] * 0.7152 + 75 | self[2] * 0.0722; 76 | 77 | [gs,gs,gs] 78 | } 79 | } 80 | 81 | 82 | // predefined colors 83 | pub struct Colors; 84 | impl Colors { 85 | pub fn black() -> Color { 86 | [0.0,0.0,0.0] 87 | } 88 | pub fn white() -> Color { 89 | [1.0,1.0,1.0] 90 | } 91 | 92 | pub fn red() -> Color { 93 | [1.0,0.0,0.0] 94 | } 95 | pub fn green() -> Color { 96 | [0.0,1.0,0.0] 97 | } 98 | pub fn blue() -> Color { 99 | [0.0,0.0,1.0] 100 | } 101 | 102 | pub fn yellow() -> Color { 103 | [1.0,1.0,0.0] 104 | } 105 | pub fn magenta() -> Color { 106 | [1.0,0.0,1.0] 107 | } 108 | pub fn cyan() -> Color { 109 | [0.0,1.0,1.0] 110 | } 111 | 112 | pub fn orange() -> Color { 113 | Color::from_bytes(&[255, 165, 0]) 114 | } 115 | pub fn indigo() -> Color { 116 | Color::from_bytes(&[75, 0, 130]) 117 | } 118 | pub fn violet() -> Color { 119 | Color::from_bytes(&[238, 130, 238]) 120 | } 121 | 122 | pub fn red_brick() -> Color { 123 | Color::from_bytes(&[132,31,39]) 124 | } 125 | pub fn green_spring() -> Color { 126 | Color::from_bytes(&[0,255,127]) 127 | } 128 | pub fn blue_sky() -> Color { 129 | Color::from_bytes(&[135, 206, 235]) 130 | } 131 | pub fn gold() -> Color { 132 | Color::from_bytes(&[255, 215, 0]) 133 | } 134 | pub fn grey_dark() -> Color { 135 | Color::from_bytes(&[105,105,105]) 136 | } 137 | pub fn grey_light() -> Color { 138 | Color::from_bytes(&[190,190,190]) 139 | } 140 | pub fn white_smoke() -> Color { 141 | Color::from_bytes(&[245,245,245]) 142 | } 143 | pub fn white_ghost() -> Color { 144 | Color::from_bytes(&[248,248,255]) 145 | } 146 | 147 | pub fn random() -> Color { 148 | Color::from_bytes(&[rand::random::(), 149 | rand::random::(), 150 | rand::random::()]) 151 | } 152 | } 153 | 154 | 155 | fn min(a: f32,b: f32) -> f32 { 156 | if a < b { a } 157 | else { b } 158 | } 159 | -------------------------------------------------------------------------------- /src/ui/glyphs.rs: -------------------------------------------------------------------------------- 1 | use std::collections::HashMap; 2 | 3 | use na::{Mat4,Vec2,Vec3}; 4 | 5 | use glium::{self,Surface,Display}; 6 | use glium::vertex::VertexBufferAny; 7 | 8 | use font_atlas::{CharInfo}; 9 | use glium::texture::{Texture2d}; 10 | 11 | use ::image::GenericImage; 12 | 13 | use ui::color; 14 | 15 | use ::Font; 16 | use ::ui::atlas::{Atlas}; 17 | 18 | static VERT_SRC: &'static str = r" 19 | #version 140 20 | 21 | in vec2 pos; 22 | in vec2 tex; 23 | 24 | in int visible; 25 | 26 | uniform mat4 transform; 27 | 28 | in vec2 g_pos; 29 | in vec2 size; 30 | in vec4 frame; 31 | 32 | out vec2 v_tex_coord; 33 | out vec2 frame_size; 34 | out vec2 frame_off; 35 | 36 | out vec2 v_pos; 37 | in vec4 o_color; 38 | out vec4 v_color; 39 | 40 | void main() { 41 | if (visible == 1) { v_pos = pos * size; } 42 | else { v_pos = vec2(-3000.0,-3000.0); } 43 | 44 | gl_Position = transform * vec4(v_pos + g_pos, 0.0, 1.0); 45 | v_tex_coord = tex; 46 | frame_size = frame.zw; 47 | frame_off = frame.xy; 48 | v_color = o_color; 49 | } 50 | "; 51 | 52 | static FRAG_SRC: &'static str = r" 53 | #version 140 54 | 55 | uniform sampler2D sample; 56 | in vec2 v_tex_coord; 57 | in vec2 frame_size; 58 | in vec2 frame_off; 59 | 60 | in vec4 v_color; 61 | out vec4 f_color; 62 | 63 | void main() { 64 | f_color = v_color * texture2D(sample, fract(v_tex_coord) * frame_size + frame_off); 65 | //f_color = v_color * texture2D(sample, v_tex_coord); 66 | } 67 | "; 68 | 69 | #[derive(Copy,Clone)] 70 | pub struct Vertex { 71 | pub pos: [f32; 2], 72 | pub tex: [f32; 2], 73 | } 74 | 75 | #[derive(Copy, Clone)] 76 | pub struct Attr { 77 | pub visible: i32, 78 | pub g_pos: (f32,f32), 79 | pub size: (f32,f32), 80 | pub o_color: (f32,f32,f32,f32), 81 | pub frame: (f32,f32,f32,f32), 82 | } 83 | 84 | pub type GlyphCache = HashMap; 85 | 86 | pub struct GlyphDrawer { 87 | vbo: glium::vertex::VertexBufferAny, 88 | program: glium::Program, 89 | font: Font, 90 | //cache: GlyphCache, 91 | pub inst: glium::vertex::VertexBuffer, 92 | //index_buf: glium::index::IndexBuffer, 93 | sample: Texture2d, 94 | pub texts: Vec, 95 | } 96 | 97 | // NOTE: Consider using instancing, at least for sentences, 98 | // maybe for all text ever on the screen at once 99 | 100 | // FIXME: make like mapdrawer with index buffer and proper coordinates! 101 | impl GlyphDrawer { 102 | pub fn new(mut font: Font, display: &Display) -> GlyphDrawer { 103 | implement_vertex!(Vertex, pos, tex); 104 | let verts = vec![ 105 | Vertex { pos: [ -0.5, 0.5 ], tex: [ 0.0, 0.0 ] }, 106 | Vertex { pos: [ -0.5, -0.5 ], tex: [ 0.0, 1.0 ] }, 107 | Vertex { pos: [ 0.5, 0.5 ], tex: [ 1.0, 0.0 ] }, 108 | Vertex { pos: [ 0.5, -0.5 ], tex: [ 1.0, 1.0 ] }, 109 | ]; 110 | 111 | let program = program!(display, 112 | 140 => { vertex: VERT_SRC, 113 | fragment: FRAG_SRC, } ).unwrap(); 114 | let vbo = glium::vertex::VertexBuffer::new(display, &verts).unwrap().into_vertex_buffer_any(); 115 | 116 | let dims = font.image().dimensions(); 117 | let img = font.image_mut().crop(0,0,dims.0,dims.1).flipv(); 118 | 119 | let sample = Texture2d::new(display, 120 | img).unwrap(); 121 | 122 | let inst = { 123 | implement_vertex!(Attr, 124 | visible, 125 | g_pos, 126 | size, 127 | o_color, 128 | frame); 129 | 130 | let data = vec![ 131 | Attr { 132 | visible: 0, 133 | g_pos: (0.,0.), 134 | size: (0.,0.), 135 | o_color: (0.,0.,0.,0.), 136 | frame: (0.,0.,0.,0.), 137 | } 138 | ;2500]; 139 | 140 | glium::vertex::VertexBuffer::dynamic(display, &data).expect("unable to build glyph drawer attr inst vbo") 141 | }; 142 | 143 | GlyphDrawer { 144 | vbo: vbo, 145 | program: program, 146 | inst: inst, 147 | font: font, 148 | sample: sample, 149 | texts: vec!(), 150 | } 151 | } 152 | 153 | pub fn push(&mut self,text: Text) { 154 | self.texts.push(text); 155 | } 156 | 157 | pub fn draw(&mut self, 158 | pv: Mat4, // persp*view mat 159 | target: &mut glium::Frame,) { 160 | let mut texts = self.texts.drain(..); 161 | let mut i = 0; 162 | 163 | let mut text = texts.next(); 164 | let mut chars = get_chars(&text); 165 | 166 | for q in self.inst.map().iter_mut() { 167 | 168 | let c = { 169 | if i < chars.len() { 170 | Some(chars[i]) 171 | } 172 | else { 173 | chars = { 174 | text = texts.next(); 175 | i = 0; 176 | get_chars(&text) 177 | }; 178 | 179 | if i < chars.len() { 180 | Some(chars[i]) 181 | } 182 | else { None } 183 | } 184 | }; 185 | i += 1; 186 | 187 | q.visible = 0; 188 | 189 | if let Some(c) = c { 190 | if let Some(cache) = self.font.char_info(c) { 191 | if let Some(ref t) = text { // this is technically unwrappable 192 | let mut offset_x = 0; 193 | if t.center { 194 | offset_x = (chars.len() as i32 * 195 | cache.advance.0) / 2; 196 | } 197 | let pos = Vec2::new((i as f32 * 198 | cache.advance.0 as f32) 199 | - offset_x as f32, 200 | cache.advance.1 as f32) * t.size; 201 | 202 | let img_size = Vec2::new(cache.image_size.0 as f32, 203 | cache.image_size.1 as f32); 204 | let img_pos = Vec2::new(cache.image_position.0 as f32, 205 | cache.image_position.1 as f32); 206 | 207 | let pos = Vec2::new(t.pos.x,t.pos.y) + pos + 208 | (img_size * 0.5); 209 | 210 | /* let translation = Iso3::new( 211 | Vec3::new(position.x, position.y, 0.0), 212 | Vec3::new(0.0, 0.0, 0.0), 213 | ); 214 | let transform = transform * 215 | translation.to_homogeneous();*/ 216 | 217 | q.visible = 1; 218 | q.g_pos = (pos.x,pos.y); 219 | let size = t.size * img_size; 220 | q.size = (size.x,size.y); 221 | q.frame = (img_pos.x/256., //(img_pos.x + 0.5)/256., 222 | img_pos.y/256., //(256. - (img_pos.y + 0.5)) - img_size.y/256., 223 | img_size.x/256., 224 | img_size.y/256.); 225 | q.o_color = (t.color[0], 226 | t.color[1], 227 | t.color[2], 228 | 1.0); 229 | } 230 | } 231 | } 232 | 233 | } 234 | 235 | let params = glium::DrawParameters { 236 | blend: glium::Blend::alpha_blending(), 237 | .. Default::default() 238 | }; 239 | 240 | let uniforms = uniform! { 241 | transform: *pv.as_ref(), 242 | sample: &self.sample, 243 | }; 244 | 245 | target.draw((&self.vbo,self.inst.per_instance(). 246 | expect("unable to instance glyph drawer")), 247 | &glium::index::NoIndices( 248 | glium::index::PrimitiveType::TriangleStrip), 249 | &self.program, &uniforms, ¶ms). 250 | expect("glyph drawer target draw failure"); 251 | 252 | } 253 | 254 | /*fn load_glyphs (mut font: &mut Font, 255 | display: &Display) -> Texture2dArray { 256 | let mut cache = vec!(); 257 | 258 | for c in ascii().into_iter().rev() { 259 | let g = Atlas::sample_tex(c, 260 | &mut font, 261 | display); 262 | if let Some(g) = g { 263 | cache.push(g); 264 | } 265 | 266 | } 267 | 268 | Texture2dArray::new(display,cache).unwrap() 269 | }*/ 270 | 271 | pub fn new_from_path(path: &str, display: &Display) -> GlyphDrawer { 272 | let atlas = Atlas::new(path).expect("Font atlas cannot load, missing fonts?"); 273 | 274 | GlyphDrawer::new(atlas,display) 275 | } 276 | } 277 | 278 | 279 | fn ascii() -> Vec { 280 | let mut v = Vec::with_capacity(256); 281 | for i in 0u8 .. 255 { 282 | let c = i as char; 283 | if !c.is_control() { 284 | v.push(c); 285 | } 286 | } 287 | v 288 | } 289 | 290 | fn get_chars (text:&Option) -> Vec { 291 | if let &Some(ref t) = text { 292 | (&*t.text).chars().collect() 293 | } 294 | else { 295 | vec!() 296 | } 297 | } 298 | 299 | #[derive(Clone)] 300 | pub struct Text { 301 | pub text: String, 302 | pub size: Vec2, 303 | pub color: color::Color, 304 | pub center: bool, 305 | pub pos: Vec3, 306 | } 307 | -------------------------------------------------------------------------------- /src/ui/map.rs: -------------------------------------------------------------------------------- 1 | use na::{Mat4,Vec2}; 2 | 3 | use glium::{self,Surface,Display}; 4 | use glium::vertex::VertexBufferAny; 5 | 6 | use glium::texture::{Texture2d}; 7 | 8 | static VERT_SRC: &'static str = r" 9 | #version 140 10 | 11 | in vec2 pos; 12 | in vec2 tex; 13 | 14 | uniform mat4 transform; 15 | uniform vec2 size; 16 | 17 | out vec2 v_tex_coord; 18 | 19 | void main() { 20 | gl_Position = transform * vec4(pos * size, 0.0, 1.0); 21 | v_tex_coord = tex; 22 | } 23 | "; 24 | 25 | static FRAG_SRC: &'static str = r" 26 | #version 140 27 | 28 | in vec2 v_tex_coord; 29 | 30 | uniform sampler2D sample; 31 | 32 | void main() { 33 | gl_FragColor = texture2D(sample, v_tex_coord); 34 | } 35 | "; 36 | 37 | #[derive(Copy,Clone)] 38 | pub struct Vertex { 39 | pub pos: [f32; 2], 40 | pub tex: [f32; 2], 41 | } 42 | 43 | pub struct MapDrawer { 44 | vbo: glium::vertex::VertexBufferAny, 45 | program: glium::Program, 46 | index_buf: glium::index::IndexBuffer, 47 | } 48 | 49 | impl MapDrawer { 50 | pub fn new(display: &Display) -> MapDrawer { 51 | implement_vertex!(Vertex, pos, tex); 52 | 53 | let verts = vec![ 54 | Vertex { pos: [-1.0, -1.0], tex: [0.0, 0.0] }, 55 | Vertex { pos: [-1.0, 1.0], tex: [0.0, 1.0] }, 56 | Vertex { pos: [ 1.0, 1.0], tex: [1.0, 1.0] }, 57 | Vertex { pos: [ 1.0, -1.0], tex: [1.0, 0.0] } 58 | ]; 59 | 60 | let program = program!(display, 61 | 140 => { vertex: VERT_SRC, 62 | fragment: FRAG_SRC, } ).unwrap(); 63 | let vbo = glium::vertex::VertexBuffer::new(display, &verts).unwrap().into_vertex_buffer_any(); 64 | 65 | MapDrawer { 66 | vbo: vbo, 67 | program: program, 68 | index_buf: glium::index::IndexBuffer::new( 69 | display, 70 | glium::index::PrimitiveType::TriangleStrip, 71 | &[1 as u16, 2, 0, 3], 72 | ).unwrap() 73 | } 74 | } 75 | 76 | pub fn draw( 77 | &mut self, 78 | size: Vec2, 79 | _player_pos: Vec2, 80 | transform: Mat4, 81 | tex: &Texture2d, 82 | target: &mut glium::Frame, 83 | ) { 84 | 85 | let uniforms = uniform! { 86 | transform: *transform.as_ref(), 87 | size: *size.as_ref(), 88 | sample: tex, 89 | }; 90 | 91 | // draw parameters 92 | let params = glium::DrawParameters { 93 | blend: glium::Blend::alpha_blending(), 94 | .. Default::default() 95 | }; 96 | 97 | target.draw(&self.vbo, 98 | &self.index_buf, 99 | &self.program, &uniforms, ¶ms).unwrap(); 100 | 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/ui/mesh.rs: -------------------------------------------------------------------------------- 1 | use std::fs::File; 2 | use std::sync::Arc; 3 | 4 | use na::{Mat4,Vec3}; 5 | 6 | use glium::{self,Surface,Display}; 7 | use glium::vertex::VertexBufferAny; 8 | 9 | use obj; 10 | use genmesh; 11 | 12 | use ::ui::{ 13 | color, 14 | }; 15 | 16 | 17 | static VERT_SRC: &'static str = r" 18 | #version 140 19 | 20 | in vec3 pos; 21 | in vec3 norm; 22 | 23 | uniform mat4 transform; 24 | uniform vec3 size; 25 | uniform vec3 color; 26 | 27 | out vec3 v_color; 28 | out vec3 v_position; 29 | out vec3 v_normal; 30 | 31 | void main() { 32 | v_position = pos * size; 33 | v_normal = norm; 34 | gl_Position = transform * vec4(v_position, 1.0); 35 | v_color = color; 36 | } 37 | "; 38 | 39 | static FRAG_SRC: &'static str = r" 40 | #version 140 41 | in vec3 v_normal; 42 | in vec3 v_color; 43 | 44 | const vec3 LIGHT = vec3(-0.2, 0.8, 0.1); 45 | void main() { 46 | float lum = max(dot(normalize(v_normal), normalize(LIGHT)), 0.0); 47 | vec3 color = (0.3 + 0.7 * lum) * v_color; 48 | gl_FragColor = vec4(color, 1.0); 49 | } 50 | "; 51 | 52 | #[derive(Copy,Clone)] 53 | pub struct Vertex { 54 | pub pos: [f32; 3], 55 | pub norm: [f32; 3], 56 | pub tex: [f32; 2], 57 | } 58 | 59 | pub struct MeshDrawer { 60 | pub verts: Arc>, 61 | vbo: glium::vertex::VertexBufferAny, 62 | // params: glium::DrawParameters, 63 | program: glium::Program, 64 | } 65 | 66 | impl MeshDrawer { 67 | pub fn new(verts : Vec, 68 | display: &Display) -> MeshDrawer { 69 | implement_vertex!(Vertex, pos, norm, tex); 70 | 71 | // let v = verts.iter().map(|vert| *Pnt3::from_array_ref(&vert.pos)).collect(); 72 | 73 | let program = program!(display, 74 | 140 => { vertex: VERT_SRC, 75 | fragment: FRAG_SRC, } ).unwrap(); 76 | let vbo = glium::vertex::VertexBuffer::new(display, &verts).unwrap().into_vertex_buffer_any(); 77 | MeshDrawer { 78 | verts: Arc::new(verts), 79 | vbo: vbo, 80 | // params: params, 81 | program: program, 82 | } 83 | } 84 | 85 | pub fn draw( 86 | &mut self, 87 | size: Vec3, 88 | color: color::Color, 89 | transform: Mat4, 90 | target: &mut glium::Frame, 91 | ) { 92 | let uniforms = uniform! { 93 | transform: *transform.as_ref(), 94 | size: *size.as_ref(), 95 | color: color, 96 | }; 97 | 98 | // draw parameters 99 | let params = glium::DrawParameters { 100 | depth: glium::Depth { 101 | test: glium::DepthTest::IfLess, 102 | write: true, 103 | .. Default::default() 104 | }, 105 | .. Default::default() 106 | }; 107 | 108 | 109 | target.draw(&self.vbo, 110 | &glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList), 111 | &self.program, &uniforms, ¶ms).unwrap(); 112 | } 113 | 114 | pub fn new_from_path(path: &str, display: &Display) -> MeshDrawer { 115 | if let Some(f) = File::open(path).ok() { 116 | let mut data = ::std::io::BufReader::new(f); 117 | let data = obj::Obj::load(&mut data); 118 | 119 | let verts = load_wavefront(data); 120 | MeshDrawer::new(verts,display,) 121 | } 122 | else { panic!("mesh asset not found: {:?}", path); } 123 | } 124 | } 125 | 126 | /// to be rendered as a gl triangles list 127 | // TODO: update to latest obj/genmesh, incorporating materials/groups 128 | pub fn load_wavefront(data: obj::Obj) -> Vec { 129 | let mut vertex_data = Vec::new(); 130 | 131 | for shape in data.object_iter().next().unwrap().group_iter().flat_map(|g| g.indices().iter()) { 132 | match shape { 133 | &genmesh::Polygon::PolyTri(genmesh::Triangle { x: v1, y: v2, z: v3 }) => { 134 | for v in [v1, v2, v3].iter() { 135 | let position = data.position()[v.0]; 136 | let texture = v.1.map(|index| data.texture()[index]); 137 | let normal = v.2.map(|index| data.normal()[index]); 138 | 139 | let texture = texture.unwrap_or([0.0, 0.0]); 140 | let normal = normal.unwrap_or([0.0, 0.0, 0.0]); 141 | 142 | vertex_data.push(Vertex { 143 | pos: position, 144 | norm: normal, 145 | tex: texture, 146 | }) 147 | } 148 | }, 149 | _ => unimplemented!() 150 | } 151 | } 152 | 153 | vertex_data 154 | } 155 | -------------------------------------------------------------------------------- /src/ui/mod.rs: -------------------------------------------------------------------------------- 1 | mod atlas; 2 | mod window; 3 | mod glyphs; 4 | pub mod color; 5 | pub mod transforms; 6 | mod render; 7 | pub mod mesh; 8 | mod tiles; 9 | mod camera; 10 | mod map; 11 | 12 | pub use self::window::Target; 13 | pub use self::color::{Color,Colorable,Colors}; 14 | pub use self::render::Render; 15 | pub use self::glyphs::{GlyphDrawer,Text}; 16 | pub use self::atlas::Atlas; 17 | pub use self::transforms::{Transforms,translation}; 18 | pub use self::mesh::MeshDrawer; 19 | pub use self::camera::Camera; 20 | pub use self::tiles::TileDrawer; 21 | pub use self::map::MapDrawer; 22 | -------------------------------------------------------------------------------- /src/ui/render.rs: -------------------------------------------------------------------------------- 1 | use glium::{Display,Surface}; 2 | use ::ui::{Color,Colors,Transforms}; 3 | use ::ui::{GlyphDrawer,TileDrawer,MeshDrawer,MapDrawer}; 4 | use ::ui::glyphs::Text; 5 | use na::{Vec2,Vec3}; 6 | use clock_ticks::precise_time_s; 7 | 8 | use ::ui::{Target,Camera}; 9 | use ::GameState; 10 | use ::{TileKind,Tile,Grid}; 11 | 12 | const FRAME_SAMPLE: usize = 120; 13 | const COLOR_SAND: Color = [1., 0.92156863, 0.8039216]; //FFEBCD 14 | 15 | pub struct Render { 16 | pub text: GlyphDrawer, 17 | pub tile: Vec, 18 | pub person: MeshDrawer, 19 | 20 | pub map: MapDrawer, 21 | 22 | fps: Timing, 23 | } 24 | 25 | impl Render { 26 | pub fn new (display: &mut Display,) -> Render { 27 | 28 | let mut tiles = vec!(); 29 | for _ in 0 .. ::GROUPSIZE { 30 | for _ in 0 .. ::GROUPSIZE { 31 | tiles.push(TileDrawer::new_from_path( 32 | "assets/mesh/hex3d.obj",display)); 33 | } 34 | } 35 | 36 | Render { 37 | text: GlyphDrawer::new_from_path( 38 | "assets/font/SourceCodePro-Regular-20",display), 39 | 40 | tile: tiles, 41 | 42 | person: MeshDrawer::new_from_path( 43 | "assets/mesh/person.obj",display), 44 | 45 | map: MapDrawer::new(display), 46 | 47 | fps: Timing::new(), 48 | } 49 | } 50 | pub fn update(&mut self, 51 | display: &mut Display, 52 | color: Color, 53 | game: &GameState, 54 | cam: &Camera,) -> f64 { 55 | let dt = precise_time_s()-self.fps.time; 56 | self.fps.time = precise_time_s(); 57 | 58 | if let Some(win_size) = Target::get_size(display) { 59 | let win_size = Vec2::new(win_size.0 as f32,win_size.1 as f32); 60 | 61 | self.fps.log_frame_time(); 62 | let frame_time_avg = self.fps.frame_time_avg; 63 | 64 | let mut target = display.draw(); 65 | target.clear_color_and_depth((color[0], 66 | color[1], 67 | color[2], 68 | 1.0), 1.0); 69 | 70 | let ui_view = Transforms::ui(win_size); 71 | let grid_view = Transforms::grid(win_size,&cam); 72 | 73 | let size = 100. * cam.zoom; 74 | let mut player_pos = game.player.pos(size); 75 | 76 | // iter 2d tiles 77 | let mut c = -1; 78 | for (g,tiles) in self.tile.iter_mut().enumerate() { 79 | 80 | for (i,tile) in tiles.inst.map().iter_mut().enumerate() { 81 | c += 1; 82 | let r = i/::GRIDSIZE; 83 | if c > ::GRIDSIZE as isize - 1 { c = 0; } 84 | 85 | let coord = &game.map.grids[g]; 86 | let coords = [coord.y + r,coord.x + c as usize]; 87 | 88 | let game_tile = &game.world.tiles 89 | [coords[0]] 90 | [coords[1]]; 91 | let h = game_tile.1.terra*10.; 92 | 93 | tile.color_fog = (color[0], 94 | color[1], 95 | color[2]); 96 | 97 | let aposy = r + game.map.grids[g].y; 98 | let aposx = c as usize + game.map.grids[g].x; 99 | 100 | let tile_color = { 101 | if game.player.grid_pos == Vec2::new(aposx, 102 | aposy) { 103 | player_pos.y += h*size + 25.; // 25. offset player size 104 | Colors::yellow() 105 | } 106 | else { 107 | Render::get_tile_color(&game_tile.0) 108 | } 109 | }; 110 | 111 | tile.color = (tile_color[0], 112 | tile_color[1], 113 | tile_color[2]); 114 | 115 | let pos = Grid::hex_pos(aposy, 116 | aposx, 117 | size); 118 | 119 | 120 | tile.height = h; 121 | 122 | tile.pos_tile = (pos.x,pos.y,pos.z); 123 | tile.pos_player = (player_pos.x, 124 | player_pos.y, 125 | player_pos.z); 126 | 127 | } 128 | } 129 | 130 | 131 | 132 | 133 | for drawer in self.tile.iter_mut() { 134 | drawer.draw(Vec3::new(size,size,size), 135 | grid_view.to_pv(), 136 | &mut target); 137 | } 138 | 139 | self.person.draw(Vec3::new(size,size,size), 140 | Colors::gold(), 141 | grid_view.to_screen(player_pos), 142 | &mut target,); 143 | 144 | // rebind minimap, incase we updated it 145 | let map = { 146 | if !game.map_view { (Vec2::new(100.,100.), 147 | Vec3::new(290.,-290.,0.)) } 148 | else { (Vec2::new(400.,400.), 149 | Vec3::new(0.,0.,0.)) } 150 | }; 151 | self.map.draw(map.0, 152 | game.player.grid_pos, 153 | ui_view.to_screen(map.1), 154 | &game.minimap, 155 | &mut target); 156 | 157 | 158 | 159 | 160 | self.text.push(Text { 161 | text: format!("fps:{:0.2?}",frame_time_avg), 162 | size: Vec2::new(1.,1.), 163 | color: Colors::black(), 164 | center: false, 165 | pos: Vec3::new(-390.,-390.,0.), 166 | }); 167 | 168 | self.text.push(Text { 169 | text: format!("pos:{:?}", game.player.grid_pos), 170 | size: Vec2::new(1.,1.), 171 | color: Colors::black(), 172 | center: false, 173 | pos: Vec3::new(-390.,-370.,0.), 174 | }); 175 | 176 | self.text.draw(ui_view.to_pv(),&mut target); 177 | 178 | target.finish().unwrap(); 179 | 180 | } 181 | 182 | dt 183 | } 184 | 185 | pub fn get_tile_color(tile: &Tile) -> [f32;3] { 186 | if tile.kind == TileKind::Grass { 187 | Colors::green_spring() } 188 | else if tile.kind == TileKind::Stone { 189 | Colors::red_brick() } 190 | else if tile.kind == TileKind::Sand { 191 | COLOR_SAND } 192 | else if tile.kind == TileKind::Ice { 193 | Colors::blue_sky() } 194 | else if tile.kind == TileKind::Snow { 195 | Colors::white_ghost() } 196 | else { Colors::blue() } 197 | 198 | } 199 | } 200 | 201 | 202 | struct Timing { 203 | frame_time_avg: f64, 204 | _frame_times: [f64;FRAME_SAMPLE], 205 | frame_time_idx: usize, 206 | frame_start: f64, 207 | 208 | time: f64, 209 | } 210 | 211 | impl Timing { 212 | fn new () -> Timing { 213 | Timing { 214 | frame_time_avg: 0.0, 215 | _frame_times: [0.0;FRAME_SAMPLE], 216 | frame_time_idx: 0, 217 | frame_start: precise_time_s(), 218 | 219 | time: precise_time_s(), 220 | } 221 | } 222 | 223 | fn log_frame_time (&mut self) { 224 | self.frame_time_idx += 1; 225 | if self.frame_time_idx > 119 { 226 | self.frame_time_avg = self.frame_time_idx as f64 / 227 | (precise_time_s() - self.frame_start); 228 | 229 | // reset 230 | self.frame_start = precise_time_s(); 231 | self.frame_time_idx = 0; 232 | } 233 | } 234 | } 235 | -------------------------------------------------------------------------------- /src/ui/tiles.rs: -------------------------------------------------------------------------------- 1 | use std::fs::File; 2 | use std::sync::Arc; 3 | 4 | use na::{Mat4,Vec3}; 5 | 6 | use glium::{self,Surface,Display}; 7 | use glium::vertex::VertexBufferAny; 8 | 9 | use obj; 10 | 11 | use ::ui::mesh::{Vertex,load_wavefront}; 12 | 13 | 14 | static VERT_SRC: &'static str = r" 15 | #version 140 16 | 17 | in vec3 pos; 18 | in vec3 norm; 19 | 20 | in vec3 pos_tile; 21 | in vec3 pos_player; 22 | in vec3 color; 23 | in int visible; 24 | 25 | in float height; 26 | 27 | in vec3 color_fog; 28 | 29 | uniform mat4 pv; 30 | //uniform mat4 m; 31 | uniform vec3 size; 32 | 33 | 34 | out vec4 v_color; 35 | out vec3 v_position; 36 | out vec3 v_normal; 37 | 38 | void main() { 39 | if (visible == 1) { 40 | vec3 off = vec3(0.0,height,0.0); 41 | v_position = (pos + off) * size; 42 | } 43 | else { v_position = vec3(-3000.0,-3000.0,-3000.0); } 44 | 45 | vec3 apos = v_position + pos_tile; 46 | v_normal = norm; 47 | gl_Position = pv * vec4(apos, 1.0); 48 | 49 | //distance of fragment in worldspace 50 | // TODO: move to frag 51 | float distx = apos.x-pos_player.x; 52 | float distz = apos.z-pos_player.z; 53 | float dist = sqrt(pow(distx,2.0)+pow(distz,2.0)); 54 | 55 | float fog_start = 1300 * (size.x / 100.); // this removes zoom 56 | float fog_end = 1900 * (size.x / 100.); 57 | 58 | //linear interpolation 59 | float fog_factor = (dist-fog_start)/(fog_end-fog_start); 60 | fog_factor = clamp(fog_factor,0,1); 61 | 62 | v_color = vec4(mix(color,color_fog,vec3(fog_factor)),1.0); 63 | } 64 | "; 65 | 66 | static FRAG_SRC: &'static str = r" 67 | #version 140 68 | in vec3 v_normal; 69 | in vec4 v_color; 70 | 71 | const vec3 LIGHT = vec3(-0.2, 0.8, 0.1); 72 | void main() { 73 | float lum = max(dot(normalize(v_normal), normalize(LIGHT)), 0.0); 74 | vec4 color = (0.3 + 0.7 * lum) * v_color; 75 | gl_FragColor = color; 76 | } 77 | "; 78 | 79 | #[derive(Copy, Clone)] 80 | pub struct Attr { 81 | pub pos_tile: (f32,f32,f32), 82 | pub pos_player: (f32,f32,f32), 83 | pub color: (f32,f32,f32), 84 | pub color_fog: (f32,f32,f32), 85 | pub visible: i32, 86 | pub height: f32, 87 | } 88 | 89 | // TODO: consider using MeshDrawer with traits instead of reimpl 90 | pub struct TileDrawer { 91 | pub verts: Arc>, 92 | vbo: glium::vertex::VertexBufferAny, 93 | program: glium::Program, 94 | pub inst: glium::vertex::VertexBuffer, 95 | } 96 | 97 | impl TileDrawer { 98 | pub fn new(verts : Vec, 99 | display: &Display) -> TileDrawer { 100 | //implement_vertex!(Vertex, pos, norm, tex); 101 | 102 | let program = program!(display, 103 | 140 => { vertex: VERT_SRC, 104 | fragment: FRAG_SRC, } ).expect("unable to build tile drawer program"); 105 | let vbo = glium::vertex::VertexBuffer::new(display, &verts).expect("unable to buld tile drawer vbo").into_vertex_buffer_any(); 106 | 107 | let tile_inst = { 108 | implement_vertex!(Attr, 109 | pos_tile, 110 | pos_player, 111 | color, 112 | color_fog, 113 | visible, 114 | height); 115 | 116 | let data = vec![ 117 | Attr { 118 | pos_tile: (0.,0.,0.), 119 | pos_player: (0.,0.,0.), 120 | color: (1.,1.,1.), 121 | visible: 1, 122 | color_fog: (1.,1.,1.), 123 | height: 0., 124 | } 125 | ;(::GRIDSIZE * ::GRIDSIZE)]; 126 | 127 | glium::vertex::VertexBuffer::dynamic(display, &data).expect("unable to build tile drawer attr inst vbo") 128 | }; 129 | 130 | TileDrawer { 131 | verts: Arc::new(verts), 132 | vbo: vbo, 133 | program: program, 134 | inst: tile_inst,//.into_vertex_buffer_any(), 135 | } 136 | } 137 | 138 | pub fn draw( 139 | &mut self, 140 | size: Vec3, 141 | pv: Mat4, // persp*view mat 142 | //m: Mat4, // model mat 143 | target: &mut glium::Frame, 144 | ) { 145 | let uniforms = uniform! { 146 | pv: *pv.as_ref(), 147 | //m: *m.as_array(), 148 | size: *size.as_ref(), 149 | }; 150 | 151 | let params = glium::DrawParameters { 152 | depth: glium::Depth { 153 | test: glium::DepthTest::IfLess, 154 | write: true, 155 | .. Default::default() 156 | }, 157 | .. Default::default() 158 | }; 159 | 160 | 161 | target.draw((&self.vbo,self.inst.per_instance().expect("unable to instance tile drawer")), 162 | &glium::index::NoIndices(glium::index::PrimitiveType::TrianglesList), 163 | &self.program, &uniforms, ¶ms).expect("tile drawer target draw failure"); 164 | } 165 | 166 | pub fn new_from_path(path: &str, display: &Display) -> TileDrawer { 167 | if let Some(f) = File::open(path).ok() { 168 | let mut data = ::std::io::BufReader::new(f); 169 | let data = obj::Obj::load(&mut data); 170 | 171 | let verts = load_wavefront(data); 172 | TileDrawer::new(verts,display,) 173 | } 174 | else { panic!("mesh asset not found: {:?}", path); } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/ui/transforms.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | use ::ui::Camera; 3 | 4 | use na::{ 5 | self, 6 | ToHomogeneous, 7 | Iso3, 8 | Mat4, 9 | Ortho3, 10 | Vec2,Vec3, 11 | zero, 12 | Inv, 13 | 14 | Persp3, 15 | 16 | Pnt2,Pnt3,Pnt4, 17 | }; 18 | 19 | pub struct Transforms { 20 | proj: Mat4, 21 | view: Mat4, 22 | } 23 | 24 | impl Transforms { 25 | /// straight forward ui placement with these camera-less transform 26 | pub fn ui (win_size: Vec2) -> Transforms { 27 | Transforms { 28 | proj: ortho(win_size), 29 | view: translation(zero(),None), 30 | } 31 | } 32 | 33 | pub fn grid (win_size: Vec2,cam: &Camera) -> Transforms { 34 | let iso = cam.update(); 35 | Transforms { 36 | proj: ortho(win_size), 37 | view: iso.to_homogeneous().inv().unwrap(), 38 | } 39 | } 40 | } 41 | 42 | impl Transforms { 43 | /// to be used with a 2d-camera, returns PVM matrix 44 | pub fn to_screen(&self, pos: Vec3) -> Mat4 { 45 | let model = translation(Vec3::new(pos.x,pos.y,pos.z), 46 | None); 47 | 48 | self.proj * self.view * model 49 | } 50 | 51 | /// gets persp*view matrix 52 | pub fn to_pv(&self) -> Mat4 { 53 | self.proj * self.view 54 | } 55 | } 56 | 57 | /// get new ortho transform matrix based on window size specified 58 | pub fn ortho(win_size: Vec2) -> Mat4 { 59 | let ortho = Ortho3::new( 60 | win_size.x, win_size.y, 61 | -2000., 2000. 62 | ); 63 | 64 | ortho.to_mat() 65 | } 66 | 67 | //straight translation, used for ui placement 68 | pub fn translation(v: Vec3, r: Option>) -> Mat4 { 69 | let translation = Iso3::new( 70 | Vec3::new(v.x, v.y, v.z), 71 | r.unwrap_or(zero()), 72 | ); 73 | 74 | translation.to_homogeneous() 75 | } 76 | 77 | /// fov in hundreths (0.75, not 75.0) 78 | pub fn persp(win_size: Vec2, fov: f32) -> Mat4 { 79 | let persp = Persp3::new( 80 | win_size.x / win_size.y, fov, 81 | 0.1, 1000.0 82 | ); 83 | 84 | persp.to_mat() 85 | } 86 | 87 | 88 | /// Converts a point in 2d screen coordinates to a ray (a 3d position and a direction) 89 | pub fn unproject(projview: Mat4, 90 | coord: &Vec2, 91 | win_size: &Vec2) 92 | -> (Pnt3, Vec3) { 93 | let normalized_coord = Pnt2::new( 94 | 2.0 * coord.x / win_size.x - 1.0, 95 | 2.0 * -coord.y / win_size.y + 1.0); 96 | 97 | let normalized_begin = Pnt4::new(normalized_coord.x, normalized_coord.y, -1.0, 1.0); 98 | let normalized_end = Pnt4::new(normalized_coord.x, normalized_coord.y, 1.0, 1.0); 99 | 100 | let cam = projview.inv().unwrap(); 101 | 102 | let h_unprojected_begin = cam * normalized_begin; 103 | let h_unprojected_end = cam * normalized_end; 104 | 105 | let unprojected_begin: Pnt3 = na::from_homogeneous(&h_unprojected_begin); 106 | let unprojected_end: Pnt3 = na::from_homogeneous(&h_unprojected_end); 107 | 108 | (unprojected_begin, na::normalize(&(unprojected_end - unprojected_begin))) 109 | } 110 | -------------------------------------------------------------------------------- /src/ui/window.rs: -------------------------------------------------------------------------------- 1 | use glium::glutin; 2 | use glium::{Display}; 3 | use glium::DisplayBuild; 4 | 5 | pub struct Target; 6 | impl Target { 7 | pub fn new(width: u32, height: u32) -> Display { 8 | let display = glutin::WindowBuilder::new() 9 | .with_title("Thule".to_string()) 10 | .with_dimensions(width, height) 11 | .with_vsync() 12 | .with_multisampling(8) 13 | .with_depth_buffer(24) 14 | .build_glium() 15 | .unwrap_or_else(|e| panic!("Error creating window: {}", e)); 16 | display 17 | } 18 | 19 | pub fn get_size (display: &Display) -> Option<(u32,u32)> { 20 | if let Some(window) = display.get_window() { 21 | return window.get_inner_size_pixels() 22 | } 23 | None 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /thule-game-ss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/viperscape/thule/2aec64acc7ee9a664830250b88532256a61c7017/thule-game-ss.png --------------------------------------------------------------------------------