Initial commit

master
stujones11 2018-05-24 22:28:00 +01:00
commit 9fbddb6ffe
36 changed files with 4223 additions and 0 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
## Generic ignorable patterns and files
*~
.*.swp
*bak*
tags
*.vim

42
CMakeLists.txt Normal file
View File

@ -0,0 +1,42 @@
cmake_minimum_required(VERSION 2.6)
project(samviewer)
set(CMAKE_CXX_STANDARD 11)
set(PROJECT_NAME_CAPITALIZED "SAM-Viewer")
set(PROJECT_LINK_URL "https://github.com/stujones11/SAM-Viewer")
set(PROJECT_LINK_TEXT "github.com/stujones11/SAM-Viewer")
set(VERSION_MAJOR 0)
set(VERSION_MINOR 1)
set(VERSION_PATCH 0)
set(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}")
add_definitions(-DUSE_CMAKE_CONFIG_H)
configure_file (
"${PROJECT_SOURCE_DIR}/src/cmake_config.h.in"
"${PROJECT_SOURCE_DIR}/src/cmake_config.h"
)
if(NOT IRRLICHT_INCLUDE_DIR)
set(IRRLICHT_INCLUDE_DIR "/usr/include/irrlicht")
endif()
if(NOT IRRLICHT_LIBRARY)
set(IRRLICHT_LIBRARY "/usr/local/lib/libIrrlicht.so")
endif()
include_directories(
${IRRLICHT_INCLUDE_DIR}
${PROJECT_SOURCE_DIR}/src
)
file(GLOB SRCS src/*.cpp)
file(MAKE_DIRECTORY "bin")
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/bin")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
add_executable(${PROJECT_NAME} ${SRCS})
target_link_libraries(${PROJECT_NAME} ${IRRLICHT_LIBRARY})

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2018
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

57
LICENSE.txt Normal file
View File

@ -0,0 +1,57 @@
SAM-Viewer
==========
License of SAM-Viewer source code
---------------------------------
Copyright (C) 2018, Stuart Jones - (MIT License)
License of SAM-Viewer media
---------------------------
Includes all textures and models contained in this distribution.
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
Minetest media files:
character.b3d
character.png
pickaxe.png
blank.png
Copyright (C) 2010-2018 celeron55, Perttu Ahola
Irrlicht media files:
fontlucida.png
All other media files:
Copyright (C) 2018, Stuart Jones - (CC BY-SA 3.0)
Irrlicht
--------
This program uses the Irrlicht Engine. http://irrlicht.sourceforge.net/
The Irrlicht Engine License:
Copyright (C) 2002-2015 Nikolaus Gebhardt
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgement in the product documentation would be
appreciated but is not required.
2. Altered source versions must be clearly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.

78
README.md Normal file
View File

@ -0,0 +1,78 @@
SAM-Viewer
==========
**Skin & Model Viewer - Version 0.1.0**
A simple 3d mesh viewer built with Irrlicht rendering engine.
Features
--------
* Wielded item or 'attachment' model support.
* Multiple textures, up to 6 material layers.
* Mesh debug view. (wire-frame, skeleton and normals)
* Animation playback amd frame controls.
Supported Formats
-----------------
Compatible with all mesh formats supported by Irrlicht engine.
* B3D files (.b3d)
* DirectX (.x)
* Alias Wavefront Maya (.obj)
* 3D Studio meshes (.3ds)
* Lightwave Objects (.lwo)
* COLLADA 1.4 (.xml, .dae)
Installation
------------
For now this assumes you are using some sane linux distro and have
a c++11 compliant compiler, although I am pretty sure it could be
made to work on any platform or device that meets the requirements.
**Requirements:** cmake, opengl, Irrlicht
```
cmake .
make -j2
```
**CMake options:** (defaults)
```
IRRLICHT_INCLUDE_DIR=/usr/include/irrlicht
IRRLICHT_LIBRARY="/usr/local/lib/libIrrlicht.so"
```
**Example:**
```
cmake . -DIRRLICHT_LIBRARY="/usr/lib/libIrrlicht.so"`
```
Controls
--------
| Control | Action |
|-------------------------------|----------------------------------------------------------------|
| Left mouse button + move | Trackball style rotation |
| Mouse wheel | Zoom |
| + | Zoom in |
| - | Zoom out |
| Arrow keys | Rotate around X and Y axes in 15 degree steps |
| Z, X | Rotate around Z axis in 15 degree steps |
| Home | Reset zoom and rotation |
| F5 | Reload textures |
| Space | Jump (experimental) |
To Do
-----
* Improve file-browser.
* Basic lighting.
* Image capture tools.
Screenshot
----------
![Imgur](https://i.imgur.com/xIS7pRj.png)

BIN
assets/browse.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 584 B

BIN
assets/fontlucida.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
assets/pause.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

BIN
assets/play_fwd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 B

BIN
assets/play_rev.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 B

414
assets/sam_icon.svg Normal file
View File

@ -0,0 +1,414 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg61"
width="682.66669"
height="682.66669"
viewBox="0 0 682.66669 682.66669"
sodipodi:docname="sam_head.svg"
inkscape:version="0.92.1 r15371">
<metadata
id="metadata67">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs65" />
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1920"
inkscape:window-height="1023"
id="namedview63"
showgrid="false"
inkscape:zoom="0.86696537"
inkscape:cx="341.33334"
inkscape:cy="177.24884"
inkscape:window-x="0"
inkscape:window-y="34"
inkscape:window-maximized="1"
inkscape:current-layer="svg61" />
<image
width="682.66669"
height="682.66669"
preserveAspectRatio="none"
style="image-rendering:optimizeQuality"
xlink:href="data:image/png;base64,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
YII=
"
id="image69"
x="0"
y="0" />
<g
id="g283">
<path
style="fill:#fefefe;stroke-width:1.33333337"
d="M 0,341.33334 V 0 H 341.33334 682.66669 V 341.33334 682.66669 H 341.33334 0 Z"
id="path315"
inkscape:connector-curvature="0" />
<path
style="fill:#ccac92;stroke-width:1.33333337"
d="m 318.00001,633.32721 -18.66667,-6.47002 -40.66666,-13.9282 -40.66667,-13.92818 -75.33334,-25.69238 -75.333334,-25.69238 -4.666667,-4.49672 -4.666667,-4.49674 -0.323152,-90.96621 -0.323153,-90.96622 -7.393739,-2.75893 -7.393739,-2.75894 -3.616442,-3.61644 -3.616442,-3.61644 V 239.32867 134.71795 l 4,-3.86977 4,-3.86977 L 192.05097,76.155871 340.7686,25.333334 h 3.23141 3.23142 l 148.71763,50.822537 148.71763,50.822539 4,3.86977 4,3.86977 v 202.61539 202.6154 l -4,3.91564 -4,3.91564 -37.40423,12.77667 -37.40424,12.77666 -4.59576,-0.10146 -4.59577,-0.10147 -4.47184,-1.61859 -4.47184,-1.61858 -58.19483,19.81686 -58.19483,19.81688 -9.33334,3.08362 -9.33333,3.08361 -35.31601,12.15287 -35.31602,12.15288 -4.68398,-0.10147 -4.68399,-0.10133 -18.66667,-6.47003 z m -10,-172.50861 v -17.84808 l -4.35333,-2.06578 -4.35334,-2.06579 -2.81029,-3.08614 -2.81029,-3.08613 -0.58183,-1.90303 -0.58183,-1.90302 -8.92121,-3.00938 -8.92121,-3.00936 v 22.25613 22.2561 l 15.66666,5.46698 15.66667,5.46698 1,0.1893 1,0.1893 z m -166.96777,-61.70228 -0.36557,-22.21703 -17,-5.68456 -17,-5.68456 v 22.2749 22.27489 l 16.33333,5.5122 16.33334,5.51219 1.03224,0.11453 1.03224,0.11453 -0.36558,-22.21702 z"
id="path313"
inkscape:connector-curvature="0" />
<path
style="fill:#c8a588;stroke-width:1.33333337"
d="m 318.00001,633.32721 -18.66667,-6.47002 -40.66666,-13.9282 -40.66667,-13.92818 -75.33334,-25.69238 -75.333334,-25.69238 -4.666667,-4.49672 -4.666667,-4.49674 -0.323152,-90.96621 -0.323153,-90.96622 -7.393739,-2.75893 -7.393739,-2.75894 -3.616442,-3.61644 -3.616442,-3.61644 V 239.32867 134.71795 l 4,-3.86977 4,-3.86977 L 192.05097,76.155871 340.7686,25.333334 h 3.23141 3.23142 l 148.71763,50.822537 148.71763,50.822539 4,3.86977 4,3.86977 v 202.61539 202.6154 l -4,3.91564 -4,3.91564 -37.40423,12.77667 -37.40424,12.77666 -4.59576,-0.10146 -4.59577,-0.10147 -4.47184,-1.61859 -4.47184,-1.61858 -58.19483,19.81686 -58.19483,19.81688 -9.33334,3.08362 -9.33333,3.08361 -35.31601,12.15287 -35.31602,12.15288 -4.68398,-0.10147 -4.68399,-0.10133 -18.66667,-6.47003 z m 58.98679,-65.64978 32.32013,-11.01074 0.0133,-22.19069 0.0133,-22.19068 2.33333,-0.90996 2.33334,-0.90996 28.69175,-9.82292 28.69174,-9.82292 2.30826,-0.88576 2.30825,-0.88576 v 22.28531 22.28531 l 1.66667,-0.61338 1.66666,-0.61337 15.04888,-4.98915 15.0489,-4.98913 -0.16156,-23.28265 -0.16156,-23.28264 -2.88734,-1.11603 -2.88757,-1.11603 -3.33333,-3.57884 -3.33334,-3.57882 -0.45469,-13.89598 -0.45471,-13.89596 h -0.91708 -0.91709 l -25.62821,8.56808 -25.62822,8.56808 v -17.3774 -17.3774 l -1.66666,0.59917 -1.66667,0.59919 -45.33334,15.41756 -45.33333,15.41756 -3.66667,0.81799 -3.66667,0.81797 0.003,28.9746 0.003,28.9746 0.87728,33.00001 0.87728,33 0.78649,0.0107 0.78651,0.0107 32.32012,-11.01076 z M 308.00001,482.8186 v -39.84808 l -4.35333,-2.06578 -4.35334,-2.06579 -3.31333,-3.52306 -3.31333,-3.52305 -0.41872,-21.56325 -0.41874,-21.56324 -46.24793,-15.76834 -46.24795,-15.76833 -5.33333,-2.45317 -5.33334,-2.45318 -3.33333,-3.54858 -3.33333,-3.54858 -0.41975,-21.64179 -0.41975,-21.64177 -10.46026,-3.42923 -10.46027,-3.42921 -0.45332,13.08993 -0.45332,13.08992 -3.8474,4.01294 -3.84741,4.01293 -6.40649,1.37395 -6.40648,1.37394 -5.21141,-1.83869 -5.21141,-1.83869 -1.39345,0.8698 -1.39345,0.86981 -0.47459,12.24744 -0.47458,12.24744 -3.82513,3.99092 -3.82512,3.99091 -4.84154,1.14251 -4.84154,1.14249 -0.32934,13.95248 -0.32934,13.95248 0.996,31.15271 0.99601,31.15271 32,11.02078 32,11.02078 66,22.69721 66.00001,22.69721 1.66666,0.12934 1.66667,0.12933 v -39.84808 z m -51.33333,-21.36741 -14.66667,-5.00581 -0.36558,-22.22269 -0.36557,-22.22268 h 1.07653 1.07652 l 15.28905,5.11719 15.28905,5.11719 0.36557,22.21615 0.36558,22.21614 -1.69891,-0.1048 -1.69891,-0.1048 -14.66666,-5.0058 z m -99.00001,-33.85903 -16.33333,-5.5122 V 399.564 377.04804 l 1.66666,0.59327 1.66667,0.59326 15,5.08942 15,5.08941 v 22.45997 22.45998 l -0.33333,-0.11454 -0.33333,-0.11453 -16.33334,-5.51219 z m 338.33335,-53.71263 v -19.21285 l -1.66667,0.0792 -1.66667,0.0793 -8,2.92458 -8,2.92456 -0.36852,19.58306 -0.36852,19.58306 10.03519,-3.37404 10.03519,-3.37404 v -19.21284 z"
id="path311"
inkscape:connector-curvature="0" />
<path
style="fill:#c6a184;stroke-width:1.33333337"
d="m 318.00001,633.32721 -18.66667,-6.47002 -40.66666,-13.9282 -40.66667,-13.92818 -75.33334,-25.69238 -75.333334,-25.69238 -4.666667,-4.49672 -4.666667,-4.49674 -0.323152,-90.96621 -0.323153,-90.96622 -7.393739,-2.75893 -7.393739,-2.75894 -3.616442,-3.61644 -3.616442,-3.61644 V 239.32867 134.71795 l 4,-3.86977 4,-3.86977 L 192.05097,76.155871 340.7686,25.333334 h 3.23141 3.23142 l 148.71763,50.822537 148.71763,50.822539 4,3.86977 4,3.86977 v 202.61539 202.6154 l -4,3.91564 -4,3.91564 -37.40423,12.77667 -37.40424,12.77666 -4.59576,-0.10146 -4.59577,-0.10147 -4.47184,-1.61859 -4.47184,-1.61858 -58.19483,19.81686 -58.19483,19.81688 -9.33334,3.08362 -9.33333,3.08361 -35.31601,12.15287 -35.31602,12.15288 -4.68398,-0.10147 -4.68399,-0.10133 -18.66667,-6.47003 z m 55.33334,-20.10035 31.33333,-10.75221 27.33333,-9.36059 27.33334,-9.36057 24.66667,-8.32335 24.66666,-8.32335 0.66667,-22.44454 0.66667,-22.44455 9.66666,-3.21995 9.66667,-3.21996 v -13.96757 -13.96758 l -1.17139,0.72395 -1.17137,0.72396 -4.09931,-2.045 -4.09929,-2.045 -3.06265,-3.62897 -3.06266,-3.62898 -4.68666,-2.21849 -4.68667,-2.21849 -3.31333,-3.52323 -3.31334,-3.52321 -0.44982,-14.50762 -0.44984,-14.5076 -8.70891,3.27803 -8.70892,3.27803 h -1.20683 -1.20682 l 0.36557,-22.22357 0.36557,-22.22354 9.66667,-3.2209 9.66667,-3.22089 v -19.22221 -19.22223 h -1.26364 -1.26364 l -11.31452,4.09407 -11.31452,4.09408 -0.42184,21.88385 -0.42184,21.88384 -4,3.95796 -4,3.95795 -56.66667,19.26044 -56.66667,19.26043 -3.66667,0.82909 -3.66666,0.82909 v 61.9746 61.97461 h -1.2043 -1.20429 l -13.12904,-4.5752 -13.12904,-4.5752 -2.33334,-0.90079 -2.33333,-0.90079 0.044,22.47599 0.044,22.47599 16.28935,5.56832 16.28933,5.56833 0.66667,0.0879 0.66667,0.0879 31.33333,-10.7522 z m -98.66667,-79.3695 v -22.14265 l 2.33333,0.95345 2.33333,0.95344 13.26198,4.52255 13.26198,4.52253 h 1.07135 1.07136 V 482.8186 442.97052 l -4.35333,-2.06578 -4.35334,-2.06579 -3.31333,-3.52306 -3.31333,-3.52305 -0.41875,-21.56535 -0.41876,-21.56534 -46.45847,-15.86854 -46.45847,-15.86853 -5.12277,-2.35087 -5.12279,-2.35088 -3.33333,-3.54858 -3.33333,-3.54858 -0.41975,-21.64179 -0.41975,-21.64177 -10.46026,-3.42923 -10.46027,-3.42921 -0.45332,13.08993 -0.45332,13.08992 -3.8474,4.01294 -3.84741,4.01293 -6.40649,1.37395 -6.40648,1.37394 -5.21141,-1.83869 -5.21141,-1.83869 -1.39345,0.8698 -1.39345,0.86981 -0.47459,12.24744 -0.47458,12.24744 -3.82513,3.99092 -3.82512,3.99091 -4.84154,1.14463 -4.84154,1.14461 -0.35087,44.78624 -0.35087,44.78624 17.01753,5.99931 17.01754,5.99929 0.66667,22.30978 0.66666,22.30978 16.30234,5.7431 16.30232,5.74309 0.36435,-22.23315 0.36433,-22.23313 33,11.1754 33,11.17539 v 22.36088 22.36088 l 15,5.29657 15,5.29658 1.66667,0.1789 1.66667,0.17891 z m -18,-72.40617 -14.66667,-5.00581 -0.36558,-22.22269 -0.36557,-22.22268 h 1.07653 1.07652 l 15.28905,5.11719 15.28905,5.11719 0.36557,22.21615 0.36558,22.21614 -1.69891,-0.1048 -1.69891,-0.1048 -14.66666,-5.0058 z m -99.00001,-33.85903 -16.33333,-5.5122 V 399.564 377.04804 l 1.66666,0.59327 1.66667,0.59326 15,5.08942 15,5.08941 v 22.45997 22.45998 l -0.33333,-0.11454 -0.33333,-0.11453 -16.33334,-5.51219 z m -51,93.18476 v -21.88976 l -15,-4.97285 -15.000001,-4.97285 -1.699609,-0.62602 -1.699609,-0.62601 0.366276,22.37797 0.366276,22.37798 14.666667,5.00581 14.66667,5.0058 1.66666,0.1048 1.66667,0.1049 z"
id="path309"
inkscape:connector-curvature="0" />
<path
style="fill:#ba9c85;stroke-width:1.33333337"
d="m 318.00001,633.32721 -18.66667,-6.47002 -40.66666,-13.9282 -40.66667,-13.92818 -75.33334,-25.69238 -75.333334,-25.69238 -4.666667,-4.49672 -4.666667,-4.49674 -0.323152,-90.96621 -0.323153,-90.96622 -7.393739,-2.75893 -7.393739,-2.75894 -3.616442,-3.61644 -3.616442,-3.61644 V 239.32867 134.71795 l 4,-3.86977 4,-3.86977 L 192.05097,76.155871 340.7686,25.333334 h 3.23141 3.23142 l 148.71763,50.822537 148.71763,50.822539 4,3.86977 4,3.86977 v 202.61539 202.6154 l -4,3.91564 -4,3.91564 -37.40423,12.77667 -37.40424,12.77666 -4.59576,-0.10146 -4.59577,-0.10147 -4.47184,-1.61859 -4.47184,-1.61858 -58.19483,19.81686 -58.19483,19.81688 -9.33334,3.08362 -9.33333,3.08361 -35.31601,12.15287 -35.31602,12.15288 -4.68398,-0.10147 -4.68399,-0.10133 -18.66667,-6.47003 z m 55.33334,-20.10035 31.33333,-10.75221 27.33333,-9.36638 27.33334,-9.36637 32.33333,-10.85411 32.33334,-10.8541 v -1.01684 -1.01683 h -1.75055 -1.75055 l -3.91612,-4.08755 -3.91612,-4.08756 v -7.15822 -7.15823 l 3.8866,-4.05674 3.88659,-4.05673 4.44675,-1.46756 4.44673,-1.46755 v -19.30862 -19.30862 l -1.17139,0.72395 -1.17137,0.72396 -4.09931,-2.045 -4.09929,-2.045 -3.06265,-3.62897 -3.06266,-3.62898 -4.68666,-2.21849 -4.68667,-2.21849 -3.31333,-3.52323 -3.31334,-3.52321 -0.44816,-14.44443 -0.44814,-14.44443 -9.45206,3.21484 -9.45204,3.21486 h -0.43313 -0.43313 v -21.86474 -21.86472 l 10,-3.6472 10,-3.64721 v -19.15474 -19.15473 h -1.26364 -1.26364 l -11.31452,4.09407 -11.31452,4.09408 -0.42184,21.88385 -0.42184,21.88384 -4,3.96017 -4,3.96018 -55.33334,18.91908 -55.33333,18.91908 -4.93498,1.13493 -4.93497,1.13494 -15.7317,-5.48562 -15.73169,-5.48561 -5.33333,-2.39199 -5.33334,-2.39197 -3.33333,-3.55144 -3.33333,-3.55143 -0.41875,-21.56535 -0.41876,-21.56534 -46.45847,-15.86854 -46.45847,-15.86853 -5.12277,-2.35087 -5.12279,-2.35088 -3.33333,-3.54858 -3.33333,-3.54858 -0.41975,-21.64179 -0.41975,-21.64177 -10.46026,-3.42923 -10.46027,-3.42921 -0.45332,13.08993 -0.45332,13.08992 -3.8474,4.01294 -3.84741,4.01293 -6.40649,1.37395 -6.40648,1.37394 -5.21141,-1.83869 -5.21141,-1.83869 -1.39345,0.8698 -1.39345,0.86981 -0.47459,12.24744 -0.47458,12.24744 -3.79557,3.96007 -3.79557,3.96007 -5.7885,1.45756 -5.78851,1.45756 -3.44099,-1.30827 -3.440985,-1.30825 -7.330806,1.90942 -7.330804,1.90944 -5.32065,-1.87724 -5.320649,-1.87724 0.343183,84.75833 0.343184,84.7583 80.666667,27.60755 80.66667,27.60756 34.66667,11.83802 34.66667,11.83801 18,6.31649 18,6.3165 0.66666,0.0801 0.66667,0.0801 31.33334,-10.7522 z m -147.33334,-73.28228 -14.66667,-5.22819 -18.33333,-6.13541 -18.33334,-6.13543 v -21.88943 -21.88944 h 1.29195 1.29195 l 32.04138,10.9 32.04139,10.90002 v 22.43332 22.43333 l -0.33333,-0.0803 -0.33334,-0.0803 -14.66666,-5.22819 z m 30.66667,-78.49339 -14.66667,-5.00581 -0.36558,-22.22269 -0.36557,-22.22268 h 1.07653 1.07652 l 15.28905,5.11719 15.28905,5.11719 0.36557,22.21615 0.36558,22.21614 -1.69891,-0.1048 -1.69891,-0.1048 -14.66666,-5.0058 z m -99.00001,-33.85903 -16.33333,-5.5122 V 399.564 377.04804 l 1.66666,0.59327 1.66667,0.59326 15,5.08942 15,5.08941 v 22.45997 22.45998 l -0.33333,-0.11454 -0.33333,-0.11453 -16.33334,-5.51219 z"
id="path307"
inkscape:connector-curvature="0" />
<path
style="fill:#b89478;stroke-width:1.33333337"
d="m 318.00001,633.32721 -18.66667,-6.47002 -40.66666,-13.9282 -40.66667,-13.92818 -75.33334,-25.69238 -75.333334,-25.69238 -4.666667,-4.49672 -4.666667,-4.49674 -0.323152,-90.96621 -0.323153,-90.96622 -7.393739,-2.75893 -7.393739,-2.75894 -3.616442,-3.61644 -3.616442,-3.61644 V 239.32867 134.71795 l 4,-3.86977 4,-3.86977 L 192.05097,76.155871 340.7686,25.333334 h 3.23141 3.23142 l 148.71763,50.822537 148.71763,50.822539 4,3.86977 4,3.86977 v 202.61539 202.6154 l -4,3.91564 -4,3.91564 -37.40423,12.77667 -37.40424,12.77666 -4.59576,-0.10146 -4.59577,-0.10147 -4.47184,-1.61859 -4.47184,-1.61858 -58.19483,19.81686 -58.19483,19.81688 -9.33334,3.08362 -9.33333,3.08361 -35.31601,12.15287 -35.31602,12.15288 -4.68398,-0.10147 -4.68399,-0.10133 -18.66667,-6.47003 z m 55.33334,-20.10035 31.33333,-10.75221 27.33333,-9.36638 27.33334,-9.36637 32.33333,-10.85411 32.33334,-10.8541 v -1.01684 -1.01683 h -1.75055 -1.75055 l -3.91612,-4.08755 -3.91612,-4.08756 v -7.15822 -7.15823 l 3.8866,-4.05674 3.88659,-4.05673 4.44675,-1.46756 4.44673,-1.46755 v -19.30862 -19.30862 l -1.17139,0.72395 -1.17137,0.72396 -4.09931,-2.045 -4.09929,-2.045 -3.06265,-3.62897 -3.06266,-3.62898 -4.68666,-2.21849 -4.68667,-2.21849 -3.31333,-3.52568 -3.31334,-3.52567 -0.37534,-55.89379 -0.37534,-55.8938 h -1.22164 -1.22162 l -11.31452,4.09407 -11.31452,4.09408 -0.42184,21.88385 -0.42184,21.88384 -4,3.96017 -4,3.96018 -55.33334,18.91908 -55.33333,18.91908 -4.93498,1.13493 -4.93497,1.13494 -15.7317,-5.48562 -15.73169,-5.48561 -5.33333,-2.39199 -5.33334,-2.39197 -3.33333,-3.55144 -3.33333,-3.55143 -0.41876,-21.56619 -0.41878,-21.56618 -46.24789,-15.81159 -46.24791,-15.81157 -5.33333,-2.40414 -5.33334,-2.40413 -3.33333,-3.55144 -3.33333,-3.55143 -0.41975,-21.64179 -0.41975,-21.64177 -10.46026,-3.42923 -10.46027,-3.42921 -0.45332,13.08993 -0.45332,13.08992 -3.8474,4.01294 -3.84741,4.01293 -6.40649,1.37395 -6.40648,1.37394 -5.21141,-1.83869 -5.21141,-1.83869 -1.39345,0.8698 -1.39345,0.86981 -0.47459,12.24744 -0.47458,12.24744 -3.79557,3.96007 -3.79557,3.96007 -5.7885,1.45756 -5.78851,1.45756 -3.44099,-1.30827 -3.440985,-1.30825 -7.330806,1.90942 -7.330804,1.90944 -5.32065,-1.87724 -5.320649,-1.87724 0.343183,84.75833 0.343184,84.7583 80.666667,27.60755 80.66667,27.60756 34.66667,11.83802 34.66667,11.83801 18,6.31649 18,6.3165 0.66667,0.0801 0.66666,0.0801 31.33334,-10.7522 z m -165.66668,-79.52767 -33,-11.39663 v -21.81794 -21.81794 l 1,-0.0237 1,-0.0237 32.33334,10.93474 32.33333,10.93474 v 22.42233 22.42232 l -0.33333,-0.1188 -0.33334,-0.1188 -33,-11.39663 z m 58.33334,-69.12105 -5.33333,-1.90064 -9.66667,-3.47402 -9.66667,-3.47401 v -21.86472 -21.86474 h 1.18963 1.18961 l 15.47706,5.50818 15.47704,5.50817 v 21.82516 21.82516 l -1.66667,-0.094 -1.66667,-0.094 -5.33333,-1.90065 z m -108,-37.00229 L 142,422.00001 l -0.36628,-22.48862 -0.36626,-22.48863 1.6996,0.61893 1.69961,0.61894 14.99283,5.20302 14.99283,5.20303 0.007,22.33333 0.007,22.33334 -0.33333,-0.0908 -0.33334,-0.0908 -16,-5.57586 z"
id="path305"
inkscape:connector-curvature="0" />
<path
style="fill:#2f2fd3;stroke-width:1.33333337"
d="m 318.00001,633.32721 -18.66667,-6.47002 -40.66666,-13.9282 -40.66667,-13.92818 -75.33334,-25.69238 -75.333334,-25.69238 -4.666667,-4.49672 -4.666667,-4.49674 -0.323152,-90.96621 -0.323153,-90.96622 -7.393739,-2.75893 -7.393739,-2.75894 -3.616442,-3.61644 -3.616442,-3.61644 V 239.32867 134.71795 l 4,-3.86977 4,-3.86977 L 192.05097,76.155871 340.7686,25.333334 h 3.23141 3.23142 l 148.71763,50.822537 148.71763,50.822539 4,3.86977 4,3.86977 v 202.61539 202.6154 l -4,3.91564 -4,3.91564 -37.40423,12.77667 -37.40424,12.77666 -4.59576,-0.10146 -4.59577,-0.10147 -4.47184,-1.61859 -4.47184,-1.61858 -58.19483,19.81686 -58.19483,19.81688 -9.33334,3.08362 -9.33333,3.08361 -35.31601,12.15287 -35.31602,12.15288 -4.68398,-0.10147 -4.68399,-0.10133 -18.66667,-6.47003 z m 55.33334,-20.10035 31.33333,-10.75221 27.33333,-9.36638 27.33334,-9.36637 32.33333,-10.85411 32.33334,-10.8541 v -1.01684 -1.01683 h -1.75055 -1.75055 l -3.91612,-4.08755 -3.91612,-4.08756 v -7.15822 -7.15823 l 3.8866,-4.05674 3.88659,-4.05673 4.44675,-1.46756 4.44673,-1.46755 v -19.30862 -19.30862 l -1.17139,0.72395 -1.17137,0.72396 -4.09931,-2.045 -4.09929,-2.045 -3.06265,-3.62897 -3.06266,-3.62898 -4.68666,-2.21849 -4.68667,-2.21849 -3.31333,-3.52568 -3.31334,-3.52567 -0.37534,-55.89379 -0.37534,-55.8938 h -1.22164 -1.22162 l -11.31452,4.09407 -11.31452,4.09408 -0.42184,21.88385 -0.42184,21.88384 -4,3.96017 -4,3.96018 -55.33334,18.91908 -55.33333,18.91908 -4.93508,1.13496 -4.93507,1.13495 -17.06494,-6.02719 -17.06492,-6.0272 -4.02,-1.8788 -4.02,-1.8788 -3.31333,-3.52306 -3.31333,-3.52305 -0.41891,-21.57743 -0.41892,-21.57742 -46.24775,-15.81456 -46.24776,-15.81456 -5.33333,-2.38992 -5.33334,-2.38991 -3.33333,-3.55144 -3.33333,-3.55143 -0.41975,-21.64179 -0.41975,-21.64177 -10.46026,-3.42923 -10.46027,-3.42921 -0.45332,13.08993 -0.45332,13.08992 -3.8474,4.01294 -3.84741,4.01293 -6.40649,1.37395 -6.40648,1.37394 -5.21141,-1.83869 -5.21141,-1.83869 -1.39345,0.8698 -1.39345,0.86981 -0.47459,12.24744 -0.47458,12.24744 -3.79557,3.96007 -3.79557,3.96007 -5.7885,1.45756 -5.78851,1.45756 -3.44099,-1.30827 -3.440985,-1.30825 -7.330806,1.90942 -7.330804,1.90944 -5.32065,-1.87724 -5.320649,-1.87724 0.343183,84.75833 0.343184,84.7583 80.666667,27.60755 80.66667,27.60756 34.66667,11.83802 34.66667,11.83801 18,6.31649 18,6.3165 0.66667,0.0801 0.66666,0.0801 31.33334,-10.7522 z m -107.33334,-148.64872 -5.33333,-1.90064 -9.66667,-3.47402 -9.66667,-3.47401 v -21.86472 -21.86474 h 1.18963 1.18961 l 15.47706,5.50818 15.47704,5.50817 v 21.82516 21.82516 l -1.66667,-0.094 -1.66667,-0.094 -5.33333,-1.90065 z m -108,-37.00229 L 142,422.00001 l -0.36628,-22.48862 -0.36626,-22.48863 1.6996,0.61893 1.69961,0.61894 14.99283,5.20302 14.99283,5.20303 0.007,22.33333 0.007,22.33334 -0.33333,-0.0908 -0.33334,-0.0908 -16,-5.57586 z"
id="path303"
inkscape:connector-curvature="0" />
<path
style="fill:#674427;stroke-width:1.33333337"
d="m 318.00001,633.32721 -18.66667,-6.47002 -40.66666,-13.9282 -40.66667,-13.92818 -75.33334,-25.69238 -75.333334,-25.69238 -4.666667,-4.49672 -4.666667,-4.49674 -0.323152,-90.96621 -0.323153,-90.96622 -7.393739,-2.75893 -7.393739,-2.75894 -3.616442,-3.61644 -3.616442,-3.61644 V 239.32867 134.71795 l 4,-3.86977 4,-3.86977 L 192.05097,76.155871 340.7686,25.333334 h 3.23141 3.23142 l 148.71763,50.822537 148.71763,50.822539 4,3.86977 4,3.86977 v 202.61539 202.6154 l -4,3.91564 -4,3.91564 -37.40423,12.77667 -37.40424,12.77666 -4.59576,-0.10146 -4.59577,-0.10147 -4.47184,-1.61859 -4.47184,-1.61858 -58.19483,19.81686 -58.19483,19.81688 -9.33334,3.08362 -9.33333,3.08361 -35.31601,12.15287 -35.31602,12.15288 -4.68398,-0.10147 -4.68399,-0.10133 -18.66667,-6.47003 z m 55.33334,-20.10035 31.33333,-10.75221 27.33333,-9.36638 27.33334,-9.36637 32.33333,-10.85411 32.33334,-10.8541 v -1.01684 -1.01683 h -1.75055 -1.75055 l -3.91612,-4.08755 -3.91612,-4.08756 v -7.15822 -7.15823 l 3.8866,-4.05674 3.88659,-4.05673 4.44675,-1.46756 4.44673,-1.46755 v -19.30862 -19.30862 l -1.17139,0.72395 -1.17137,0.72396 -4.09931,-2.045 -4.09929,-2.045 -3.06265,-3.62897 -3.06266,-3.62898 -4.68666,-2.21849 -4.68667,-2.21849 -3.31333,-3.52568 -3.31334,-3.52567 -0.37534,-55.89379 -0.37534,-55.8938 h -1.22164 -1.22162 l -11.31452,4.09407 -11.31452,4.09408 -0.42184,21.88385 -0.42184,21.88384 -4,3.96017 -4,3.96018 -55.33334,18.91908 -55.33333,18.91908 -4.93508,1.13496 -4.93507,1.13495 -17.06494,-6.02719 -17.06492,-6.0272 -4.02,-1.8788 -4.02,-1.8788 -3.31333,-3.52306 -3.31333,-3.52305 -0.41891,-21.57743 -0.41892,-21.57742 -46.24775,-15.81456 -46.24776,-15.81456 -5.33333,-2.38992 -5.33334,-2.38991 -3.33333,-3.55144 -3.33333,-3.55143 -0.41975,-21.64179 -0.41975,-21.64177 -10.46026,-3.42923 -10.46027,-3.42921 -0.45332,13.08993 -0.45332,13.08992 -3.8474,4.01294 -3.84741,4.01293 -6.40649,1.37395 -6.40648,1.37394 -5.21141,-1.83869 -5.21141,-1.83869 -1.39345,0.8698 -1.39345,0.86981 -0.47459,12.24744 -0.47458,12.24744 -3.79557,3.96007 -3.79557,3.96007 -5.7885,1.45756 -5.78851,1.45756 -3.44099,-1.30827 -3.440985,-1.30825 -7.330806,1.90942 -7.330804,1.90944 -5.32065,-1.87724 -5.320649,-1.87724 0.343183,84.75833 0.343184,84.7583 80.666667,27.60755 80.66667,27.60756 34.66667,11.83802 34.66667,11.83801 18,6.31649 18,6.3165 0.66667,0.0801 0.66666,0.0801 31.33334,-10.7522 z"
id="path301"
inkscape:connector-curvature="0" />
<path
style="fill:#603e24;stroke-width:1.33333337"
d="m 318.00001,633.32721 -18.66667,-6.47002 -40.66666,-13.9282 -40.66667,-13.92818 -75.33334,-25.69238 -75.333334,-25.69238 -4.666667,-4.49672 -4.666667,-4.49674 -0.323152,-90.96621 -0.323153,-90.96622 -7.393739,-2.75893 -7.393739,-2.75894 -3.616442,-3.61644 -3.616442,-3.61644 V 239.32867 134.71795 l 4,-3.86977 4,-3.86977 L 192.05097,76.155871 340.7686,25.333334 h 3.23141 3.23142 l 148.71763,50.822537 148.71763,50.822539 4,3.86977 4,3.86977 v 202.61539 202.6154 l -4,3.91564 -4,3.91564 -37.40423,12.77667 -37.40424,12.77666 -4.59576,-0.10146 -4.59577,-0.10147 -4.47184,-1.61859 -4.47184,-1.61858 -58.19483,19.81686 -58.19483,19.81688 -9.33334,3.08362 -9.33333,3.08361 -35.31601,12.15287 -35.31602,12.15288 -4.68398,-0.10147 -4.68399,-0.10133 -18.66667,-6.47003 z m 55.33334,-20.10035 31.33333,-10.75221 27.33333,-9.36638 27.33334,-9.36637 32.33333,-10.85411 32.33334,-10.8541 v -1.01684 -1.01683 h -1.75055 -1.75055 l -3.91612,-4.08755 -3.91612,-4.08756 v -7.15822 -7.15823 l 3.8866,-4.05674 3.88659,-4.05673 4.44675,-1.46756 4.44673,-1.46755 v -19.30862 -19.30862 l -1.27909,0.79052 -1.27911,0.79052 -3.05423,-1.71182 -3.05424,-1.71184 -3.66666,-3.24946 -3.66667,-3.24945 v -1.82924 -1.82923 l -1.17139,0.72395 -1.17137,0.72396 -3.8972,-1.94417 -3.89719,-1.94419 -3.26476,-3.47396 -3.26476,-3.47396 -0.37534,-55.89379 -0.37534,-55.8938 h -1.22164 -1.22162 l -11.31452,4.09407 -11.31452,4.09408 -0.42184,21.88385 -0.42184,21.88384 -4,3.96017 -4,3.96018 -55.33334,18.91908 -55.33333,18.91908 -4.89055,1.12495 -4.89053,1.12494 -17.10947,-6.03062 -17.10946,-6.03064 -4.02,-1.86536 -4.02,-1.86535 -3.31333,-3.52306 -3.31333,-3.52305 -0.41891,-21.57743 -0.41892,-21.57742 -46.24775,-15.81456 -46.24776,-15.81456 -5.33333,-2.38992 -5.33334,-2.38991 -3.33333,-3.55144 -3.33333,-3.55143 -0.41975,-21.64179 -0.41975,-21.64177 -10.46026,-3.42923 -10.46027,-3.42921 -0.45332,13.08993 -0.45332,13.08992 -3.8474,4.01294 -3.84741,4.01293 -6.40649,1.37395 -6.40648,1.37394 -5.21141,-1.83869 -5.21141,-1.83869 -1.39345,0.8698 -1.39345,0.86981 -0.47459,12.24744 -0.47458,12.24744 -3.85016,4.01706 -3.85017,4.01704 -6.03325,1.28677 -6.03325,1.28677 -3.14165,-1.19445 -3.141645,-1.19445 -7.330806,1.90942 -7.330804,1.90944 -5.32065,-1.87724 -5.320649,-1.87724 0.343183,84.75833 0.343184,84.7583 80.666667,27.60755 80.66667,27.60756 34.66667,11.83802 34.66667,11.83801 18,6.31649 18,6.3165 0.66667,0.0801 0.66666,0.0801 31.33334,-10.7522 z m 26.87102,-416.58047 17.57611,-6.02028 18.77643,6.12606 18.77644,6.12604 36.58437,-12.59728 36.58438,-12.59728 -17.58438,-5.80347 -17.58437,-5.80345 v -0.74339 -0.74339 l 17.43101,-5.75285 17.43103,-5.75284 -0.43103,-0.35899 -0.43101,-0.359 -34,-11.66397 -34,-11.66396 -1.78176,-0.96992 -1.78176,-0.96991 17.39311,-5.86054 17.39309,-5.86055 -1.70515,-0.95425 -1.70514,-0.95425 -34.46251,-11.63133 -34.46251,-11.631328 -18.57809,6.158408 -18.5781,6.15841 -18.30016,-6.396653 -18.30016,-6.396652 -16.56544,5.769482 -16.56543,5.769483 -54.66666,18.7199 -54.66667,18.7199 -2,0.75662 -2,0.75663 54,18.52299 54,18.52299 1.85343,0.0328 1.85344,0.0328 17.43534,-6.06559 17.43534,-6.0656 18.41511,6.386 18.41509,6.38599 -18.34831,6.11718 -18.3483,6.11718 5.97776,2.24533 5.97777,2.24533 11.33333,3.88338 11.33334,3.88337 1.64746,0.1004 1.64747,0.1004 17.57609,-6.02028 z m -295.5377,-49.90509 18.66667,-6.46482 -3.33334,-1.2594 -3.33333,-1.2594 -14.22953,-5.01808 -14.22953,-5.01808 -18.997258,6.6192 -18.99726,6.6192 17.893456,6.08145 17.893455,6.08145 v 0.0416 0.0416 l 18.666667,-6.4648 z m 514.5668,-12.25156 -18.52034,-6.46964 -17.02323,5.61826 -17.02321,5.61826 0.0107,0.70502 0.0107,0.70503 17.65643,6.09671 17.65642,6.09671 17.8769,-5.95035 17.87689,-5.95035 -18.52033,-6.46965 z M 361.863,46.428814 l -17.88385,-6.286862 -17.54166,6.189442 -17.54164,6.189441 1.21875,0.428793 1.21874,0.428794 16.6297,5.813544 16.62968,5.813544 17.57707,-6.144919 17.57706,-6.144917 z"
id="path299"
inkscape:connector-curvature="0" />
<path
style="fill:#5c3b22;stroke-width:1.33333337"
d="m 318.00001,633.32721 -18.66667,-6.47002 -40.66666,-13.9282 -40.66667,-13.92818 -75.33334,-25.69238 -75.333334,-25.69238 -4.666667,-4.49672 -4.666667,-4.49674 -0.323152,-90.96621 -0.323153,-90.96622 -7.393739,-2.75893 -7.393739,-2.75894 -3.616442,-3.61644 -3.616442,-3.61644 V 239.32867 134.71795 l 4,-3.86977 4,-3.86977 L 192.05097,76.155871 340.7686,25.333334 h 3.23141 3.23142 l 148.71763,50.822537 148.71763,50.822539 4,3.86977 4,3.86977 v 202.61539 202.6154 l -4,3.91564 -4,3.91564 -37.40423,12.77667 -37.40424,12.77666 -4.59576,-0.10146 -4.59577,-0.10147 -4.47184,-1.61859 -4.47184,-1.61858 -58.19483,19.81686 -58.19483,19.81688 -9.33334,3.08362 -9.33333,3.08361 -35.31601,12.15287 -35.31602,12.15288 -4.68398,-0.10147 -4.68399,-0.10133 -18.66667,-6.47003 z m 55.33334,-20.10035 31.33333,-10.75221 27.33333,-9.36638 27.33334,-9.36637 32.33333,-10.85411 32.33334,-10.8541 v -1.01684 -1.01683 h -1.75055 -1.75055 l -3.91612,-4.08755 -3.91612,-4.08756 v -7.15822 -7.15823 l 3.8866,-4.05674 3.88659,-4.05673 4.44675,-1.46756 4.44673,-1.46755 v -19.30862 -19.30862 l -1.27909,0.79052 -1.27911,0.79052 -3.05423,-1.71182 -3.05424,-1.71184 -3.66666,-3.24946 -3.66667,-3.24945 v -1.82924 -1.82923 l -1.17139,0.72395 -1.17137,0.72396 -3.8972,-1.94417 -3.89719,-1.94419 -3.26476,-3.47396 -3.26476,-3.47396 -0.37534,-55.89379 -0.37534,-55.8938 h -1.22164 -1.22162 l -11.31452,4.09407 -11.31452,4.09408 -0.42184,21.88385 -0.42184,21.88384 -4,3.96017 -4,3.96018 -55.33334,18.91908 -55.33333,18.91908 -4.89055,1.12495 -4.89053,1.12494 -17.10947,-6.03062 -17.10946,-6.03064 -4.02,-1.86536 -4.02,-1.86535 -3.31333,-3.52306 -3.31333,-3.52305 -0.41891,-21.57743 -0.41892,-21.57742 -46.24775,-15.81456 -46.24776,-15.81456 -5.33333,-2.38992 -5.33334,-2.38991 -3.33333,-3.55144 -3.33333,-3.55143 -0.41975,-21.64179 -0.41975,-21.64177 -10.46026,-3.42923 -10.46027,-3.42921 -0.45332,13.08993 -0.45332,13.08992 -3.8474,4.01294 -3.84741,4.01293 -6.40649,1.37395 -6.40648,1.37394 -5.21141,-1.83869 -5.21141,-1.83869 -1.39345,0.8698 -1.39345,0.86981 -0.47459,12.24744 -0.47458,12.24744 -3.85016,4.01706 -3.85017,4.01704 -6.03325,1.28677 -6.03325,1.28677 -3.14165,-1.19445 -3.141645,-1.19445 -7.330806,1.90942 -7.330804,1.90944 -5.32065,-1.87724 -5.320649,-1.87724 0.343183,84.75833 0.343184,84.7583 80.666667,27.60755 80.66667,27.60756 34.66667,11.83802 34.66667,11.83801 18,6.31649 18,6.3165 0.66667,0.0801 0.66666,0.0801 31.33334,-10.7522 z m -11,-378.55984 16.33333,-5.55455 v -1.11246 -1.11247 l -16.8864,-5.62743 -16.8864,-5.62741 18.22157,-6.36528 18.22159,-6.36528 18.33148,6.36684 18.33149,6.36685 46.00001,-15.82348 46,-15.82346 63.70109,-21.51558 63.7011,-21.51556 -0.36776,-0.28589 -0.36776,-0.28588 -73.01544,-24.9712 -73.01545,-24.97119 -18.02105,6.024069 -18.02104,6.024071 -18.27766,-6.425297 -18.27765,-6.425297 -18.15464,6.399847 -18.15463,6.399847 -36.18434,-12.220414 -36.18435,-12.220413 -0.0136,-0.721982 -0.0135,-0.721981 17.75612,-5.809578 17.75613,-5.809576 18.218,6.089904 18.218,6.089906 16.69254,-5.525703 16.69255,-5.525704 V 65.256516 64.447744 L 379.33335,52.372708 344.00001,40.297675 308.63478,52.38361 l -35.36522,12.085934 1.03189,0.932993 1.03189,0.932992 11.33334,3.712996 11.33333,3.712996 4.64857,1.935516 4.64858,1.935516 -71.31525,24.316007 -71.31524,24.31601 -2,0.65546 -2,0.65546 17.66667,5.84057 17.66667,5.84056 v 0.94605 0.94607 l -17.3698,5.73264 -17.3698,5.73264 6.3698,2.2392 6.3698,2.2392 83.33333,28.56667 83.33334,28.56666 1.94932,0.64802 1.94932,0.64801 -19.16131,6.50124 -19.16131,6.50125 18.54532,6.2937 18.54533,6.2937 1.33333,-0.44505 1.33333,-0.44505 z m -57.00001,-7.20835 v -0.54133 l -6.2261,-2.12144 -6.22611,-2.12145 -0.52389,0.52389 -0.5239,0.52389 5.75,2.03363 5.75,2.03363 1,0.1052 1,0.1052 v -0.54134 z m -46.66666,-16.00293 v -0.54425 l -8.23148,-2.77982 -8.23149,-2.77981 -0.51852,0.51852 -0.51852,0.51852 7.75001,2.70029 7.75,2.7003 1,0.1052 1,0.1052 v -0.54427 z m -54.66667,-18.66373 v -0.54134 l -6.22611,-2.12144 -6.22611,-2.12145 -0.52389,0.52389 -0.52389,0.5239 5.75,2.03362 5.75,2.03363 1,0.1052 1,0.1052 v -0.54133 z m -56,-19.33794 -2.00001,-1.13149 -3.33333,-0.81473 -3.33333,-0.81474 4,1.92664 4,1.92664 1.33333,0.0196 1.33334,0.0196 -2,-1.1315 z m -54.666673,-18.7874 -2.000001,-1.29249 H 90.000003 88.66667 l 2,1.29249 2,1.2925 h 1.333333 1.333334 z m 12.333333,-8.0956 17,-5.87724 v -0.73556 -0.73556 L 105,133.52727 l -17.666664,-5.69543 -18.552042,6.56674 -18.552042,6.56673 17.885376,6.07838 17.885375,6.07837 1.333333,-0.33687 1.333334,-0.33686 z"
id="path297"
inkscape:connector-curvature="0" />
<path
style="fill:#402915;stroke-width:1.33333337"
d="m 318.00001,633.32721 -18.66667,-6.47002 -40.66666,-13.9282 -40.66667,-13.92818 -75.33334,-25.69238 -75.333334,-25.69238 -4.666667,-4.49672 -4.666667,-4.49674 -0.323152,-90.96621 -0.323153,-90.96622 -7.393739,-2.75893 -7.393739,-2.75894 -3.616442,-3.61644 -3.616442,-3.61644 V 239.32867 134.71795 l 4,-3.86977 4,-3.86977 L 192.05097,76.155871 340.7686,25.333334 h 3.23141 3.23142 l 148.71763,50.822537 148.71763,50.822539 4,3.86977 4,3.86977 v 202.61539 202.6154 l -4,3.91564 -4,3.91564 -37.40423,12.77667 -37.40424,12.77666 -4.59576,-0.10146 -4.59577,-0.10147 -4.47184,-1.61859 -4.47184,-1.61858 -58.19483,19.81686 -58.19483,19.81688 -9.33334,3.08362 -9.33333,3.08361 -35.31601,12.15287 -35.31602,12.15288 -4.68398,-0.10147 -4.68399,-0.10133 -18.66667,-6.47003 z m 55.33334,-20.10035 31.33333,-10.75221 27.33333,-9.36638 27.33334,-9.36637 32.33333,-10.85411 32.33334,-10.8541 v -1.01684 -1.01683 h -1.75055 -1.75055 l -3.91612,-4.08755 -3.91612,-4.08756 v -7.15822 -7.15823 l 3.8866,-4.05674 3.88659,-4.05673 4.44675,-1.46756 4.44673,-1.46755 v -19.30862 -19.30862 l -1.27909,0.79052 -1.27911,0.79052 -3.05423,-1.71182 -3.05424,-1.71184 -3.66666,-3.24946 -3.66667,-3.24945 v -1.82924 -1.82923 l -1.17139,0.72395 -1.17137,0.72396 -3.8972,-1.94417 -3.89719,-1.94419 -3.26476,-3.47396 -3.26476,-3.47396 -0.37534,-55.89379 -0.37534,-55.8938 h -1.22164 -1.22162 l -11.31452,4.09407 -11.31452,4.09408 -0.42184,21.88385 -0.42184,21.88384 -4,3.96017 -4,3.96018 -55.33334,18.91908 -55.33333,18.91908 -4.89055,1.12495 -4.89053,1.12494 -17.10947,-6.03062 -17.10946,-6.03064 -4.02,-1.86536 -4.02,-1.86535 -3.31333,-3.52306 -3.31333,-3.52305 -0.41891,-21.57743 -0.41892,-21.57742 -46.24775,-15.81456 -46.24776,-15.81456 -5.33333,-2.38992 -5.33334,-2.38991 -3.33333,-3.55144 -3.33333,-3.55143 -0.41975,-21.64179 -0.41975,-21.64177 -10.46026,-3.42923 -10.46027,-3.42921 -0.45332,13.08993 -0.45332,13.08992 -3.8474,4.01294 -3.84741,4.01293 -6.40649,1.37395 -6.40648,1.37394 -5.21141,-1.83869 -5.21141,-1.83869 -1.39345,0.8698 -1.39345,0.86981 -0.47459,12.24744 -0.47458,12.24744 -3.85016,4.01706 -3.85017,4.01704 -6.03325,1.28677 -6.03325,1.28677 -3.14165,-1.19445 -3.141645,-1.19445 -7.330806,1.90942 -7.330804,1.90944 -5.32065,-1.87724 -5.320649,-1.87724 0.343183,84.75833 0.343184,84.7583 80.666667,27.60755 80.66667,27.60756 34.66667,11.83802 34.66667,11.83801 18,6.31649 18,6.3165 0.66667,0.0801 0.66666,0.0801 31.33334,-10.7522 z m 191.62687,-82.04443 -0.47771,-0.47769 -18.56492,6.20587 -18.56492,6.20588 18.65702,6.22342 18.657,6.22344 0.38561,-11.9516 0.38561,-11.95161 z m -144.29354,-316.2273 74.66667,-25.39952 70.57466,-24.13023 70.57465,-24.13024 0.3391,-0.3391 0.33909,-0.33909 L 490.58043,90.460204 344.00001,40.303459 197.41959,90.460204 50.839168,140.61695 l 0.329168,0.32916 0.329168,0.32917 145.917916,49.97273 145.91793,49.9727 1.33333,-0.43302 1.33333,-0.43303 z"
id="path295"
inkscape:connector-curvature="0" />
<path
style="fill:#3a2413;stroke-width:1.33333337"
d="m 318.00001,633.32721 -18.66667,-6.47002 -40.66666,-13.9282 -40.66667,-13.92818 -75.33334,-25.69238 -75.333334,-25.69238 -4.666667,-4.49672 -4.666667,-4.49674 -0.323152,-90.96621 -0.323153,-90.96622 -7.393739,-2.75893 -7.393739,-2.75894 -3.616442,-3.61644 -3.616442,-3.61644 V 239.32867 134.71795 l 4,-3.86977 4,-3.86977 L 192.05097,76.155871 340.7686,25.333334 h 3.23141 3.23142 l 148.71763,50.822537 148.71763,50.822539 4,3.86977 4,3.86977 v 202.61539 202.6154 l -4,3.91564 -4,3.91564 -37.40423,12.77667 -37.40424,12.77666 -4.59576,-0.10146 -4.59577,-0.10147 -4.47184,-1.61859 -4.47184,-1.61858 -58.19483,19.81686 -58.19483,19.81688 -9.33334,3.08362 -9.33333,3.08361 -35.31601,12.15287 -35.31602,12.15288 -4.68398,-0.10147 -4.68399,-0.10133 -18.66667,-6.47003 z m 55.33334,-20.10035 31.33333,-10.75221 27.33333,-9.36638 27.33334,-9.36637 32.33333,-10.85411 32.33334,-10.8541 v -1.01684 -1.01683 h -1.75055 -1.75055 l -3.91612,-4.08755 -3.91612,-4.08756 v -7.15822 -7.15823 l 3.8866,-4.05674 3.88659,-4.05673 4.44675,-1.46756 4.44673,-1.46755 v -19.30862 -19.30862 l -1.27909,0.79052 -1.27911,0.79052 -3.05423,-1.71182 -3.05424,-1.71184 -3.66666,-3.24946 -3.66667,-3.24945 v -1.82924 -1.82923 l -1.17139,0.72395 -1.17137,0.72396 -3.8972,-1.94417 -3.89719,-1.94419 -3.26476,-3.47396 -3.26476,-3.47396 -0.37534,-55.89379 -0.37534,-55.8938 h -1.22164 -1.22162 l -11.31452,4.09407 -11.31452,4.09408 -0.42184,21.88385 -0.42184,21.88384 -4,3.96017 -4,3.96018 -55.33334,18.91908 -55.33333,18.91908 -4.89055,1.12495 -4.89053,1.12494 -17.10947,-6.03062 -17.10946,-6.03064 -4.02,-1.86536 -4.02,-1.86535 -3.31333,-3.52306 -3.31333,-3.52305 -0.41891,-21.57743 -0.41892,-21.57742 -46.24775,-15.81456 -46.24776,-15.81456 -5.33333,-2.38992 -5.33334,-2.38991 -3.33333,-3.55144 -3.33333,-3.55143 -0.41975,-21.64179 -0.41975,-21.64177 -10.46026,-3.42923 -10.46027,-3.42921 -0.45332,13.08993 -0.45332,13.08992 -3.8474,4.01294 -3.84741,4.01293 -6.40649,1.37395 -6.40648,1.37394 -5.21141,-1.83869 -5.21141,-1.83869 -1.39345,0.8698 -1.39345,0.86981 -0.47459,12.24744 -0.47458,12.24744 -3.85016,4.01706 -3.85017,4.01704 -6.03325,1.28677 -6.03325,1.28677 -3.14165,-1.19445 -3.141645,-1.19445 -7.330806,1.90942 -7.330804,1.90944 -5.32065,-1.87724 -5.320649,-1.87724 0.343183,84.75833 0.343184,84.7583 80.666667,27.60755 80.66667,27.60756 34.66667,11.83802 34.66667,11.83801 18,6.31649 18,6.3165 0.66667,0.0801 0.66666,0.0801 31.33334,-10.7522 z m 191.62687,-82.04443 -0.47771,-0.47769 -18.56492,6.20587 -18.56492,6.20588 18.65702,6.22342 18.657,6.22344 0.38561,-11.9516 0.38561,-11.95161 z m -200.68054,-102.14406 17.05367,-5.6283 v -24.51435 -24.51435 l -1.66667,0.60184 -1.66667,0.60183 -16.33333,5.72239 -16.33333,5.7224 v 23.81842 23.81843 h 0.94633 0.94633 z m -93.613,-116.25121 v -48.54618 l -9.66667,-3.28065 -9.66667,-3.28067 -62.83388,-21.50649 -62.83388,-21.5065 h -0.86287 -0.86286 l 0.36341,24.1505 0.36341,24.15049 36,12.28 36,12.27999 0.37042,24.56952 0.37041,24.56951 35.62959,12.24739 35.62959,12.24738 1,0.086 1,0.086 v -48.54619 z m 202,-115.53497 128.00001,-43.8144 0.33333,-0.0523 0.33333,-0.0522 v 24 24 h 0.51846 0.51846 l 15.1482,-5.23515 15.14822,-5.23514 2.33333,-0.90751 2.33334,-0.90751 -10e-4,-24.19068 -10e-4,-24.19068 L 490.66539,90.485064 344.00001,40.303459 197.33463,90.485064 50.669248,140.66667 l -0.0013,24.13563 -0.0013,24.13561 17.000001,5.74588 17.000001,5.74587 1.666666,0.59449 1.666667,0.5945 V 177.6923 153.76595 l 109.666667,37.51098 109.66667,37.51097 0.3627,24.08828 0.3627,24.08828 17.6373,5.99794 17.63731,5.99793 0.66666,-23.94687 0.66667,-23.94687 z"
id="path293"
inkscape:connector-curvature="0" />
<path
style="fill:#352010;stroke-width:1.33333337"
d="m 318.00001,633.32721 -18.66667,-6.47002 -40.66666,-13.9282 -40.66667,-13.92818 -75.33334,-25.69238 -75.333334,-25.69238 -4.666667,-4.49672 -4.666667,-4.49674 -0.323152,-90.96621 -0.323153,-90.96622 -7.393739,-2.75893 -7.393739,-2.75894 -3.616442,-3.61644 -3.616442,-3.61644 V 239.32867 134.71795 l 4,-3.86977 4,-3.86977 L 192.05097,76.155871 340.7686,25.333334 h 3.23141 3.23142 l 148.71763,50.822537 148.71763,50.822539 4,3.86977 4,3.86977 v 202.61539 202.6154 l -4,3.91564 -4,3.91564 -37.40423,12.77667 -37.40424,12.77666 -4.59576,-0.10146 -4.59577,-0.10147 -4.47184,-1.61859 -4.47184,-1.61858 -58.19483,19.81686 -58.19483,19.81688 -9.33334,3.08362 -9.33333,3.08361 -35.31601,12.15287 -35.31602,12.15288 -4.68398,-0.10147 -4.68399,-0.10133 -18.66667,-6.47003 z m 55.33334,-20.10035 31.33333,-10.75221 27.33333,-9.36638 27.33334,-9.36637 32.33333,-10.85411 32.33334,-10.8541 v -1.01684 -1.01683 h -1.75055 -1.75055 l -3.91612,-4.08755 -3.91612,-4.08756 v -7.15822 -7.15823 l 3.8866,-4.05674 3.88659,-4.05673 4.44675,-1.46756 4.44673,-1.46755 v -19.30862 -19.30862 l -1.27909,0.79052 -1.27911,0.79052 -3.05423,-1.71182 -3.05424,-1.71184 -3.66666,-3.24946 -3.66667,-3.24945 v -1.82924 -1.82923 l -1.17139,0.72395 -1.17137,0.72396 -3.8972,-1.94417 -3.89719,-1.94419 -3.26476,-3.47396 -3.26476,-3.47396 -0.37534,-55.89379 -0.37534,-55.8938 h -1.22164 -1.22162 l -11.31452,4.09407 -11.31452,4.09408 -0.42184,21.88385 -0.42184,21.88384 -4,3.96017 -4,3.96018 -55.33334,18.91908 -55.33333,18.91908 -4.89055,1.12495 -4.89053,1.12494 -17.10947,-6.03062 -17.10946,-6.03064 -4.02,-1.86536 -4.02,-1.86535 -3.31333,-3.52306 -3.31333,-3.52305 -0.41923,-21.6014 -0.41921,-21.6014 -46.24746,-15.78812 -46.24744,-15.78812 -5.33333,-2.39239 -5.33334,-2.39237 -3.33333,-3.55144 -3.33333,-3.55143 -0.41975,-21.64179 -0.41975,-21.64177 -10.46026,-3.42923 -10.46027,-3.42921 -0.45332,13.08993 -0.45332,13.08992 -3.8474,4.01294 -3.84741,4.01293 -6.40649,1.37395 -6.40648,1.37394 -5.21141,-1.83869 -5.21141,-1.83869 -1.39345,0.8698 -1.39345,0.86981 -0.47459,12.24744 -0.47458,12.24744 -3.85016,4.01706 -3.85017,4.01704 -6.03325,1.28677 -6.03325,1.28677 -3.14165,-1.19445 -3.141645,-1.19445 -7.330806,1.90942 -7.330804,1.90944 -5.32065,-1.87724 -5.320649,-1.87724 0.343183,84.75833 0.343184,84.7583 80.666667,27.60755 80.66667,27.60756 34.66667,11.83802 34.66667,11.83801 18,6.31649 18,6.3165 0.66667,0.0801 0.66666,0.0801 31.33334,-10.7522 z m 228.16718,-69.48009 35.83283,-12.25326 v -73.08008 -73.08008 l -1.66667,0.0701 -1.66667,0.0701 -16,5.69706 -16,5.69704 -0.66667,24.46564 -0.66666,24.46565 -16,5.69704 -16,5.69706 -1.66667,0.0701 -1.66667,0.0701 V 360.18423 263.0351 l -50.33333,17.06562 -50.33334,17.0656 -60,20.51474 -60,20.51474 -0.34973,48.86895 -0.34972,48.86893 54.89194,-18.63349 54.89195,-18.63351 h 0.42836 0.42836 l 0.36275,-24.82391 0.36276,-24.8239 36.33333,-12.33666 36.33334,-12.33665 v 73.16056 73.16056 h 0.50681 0.50681 l 16.91363,-6 16.91364,-6 h 1.24622 1.24622 v 35.88944 35.88943 l -19,6.33224 -19,6.33223 18.66667,6.34 18.66667,6.34 0.5005,0.10507 0.50051,0.10506 35.83283,-12.25325 z M 308.40529,277.33334 h 0.37243 l 17.94448,6.02436 17.94448,6.02436 18.33333,-6.21456 18.33334,-6.21457 v -24.19425 -24.19426 l 91.66667,-31.36969 91.66667,-31.36971 0.36341,23.75416 0.36341,23.75416 h 1.23967 1.23968 l 16.73025,-5.90028 16.73024,-5.90028 v 24.51951 24.51949 l 18,-6.26952 18.00001,-6.26951 -10e-4,-48.68304 -10e-4,-48.68304 L 490.66539,90.485064 344.00001,40.303459 197.33463,90.485064 50.669248,140.66667 l -0.0013,24.22278 -0.0013,24.22276 18.666668,6.22113 18.666667,6.22113 v 48.92781 48.92778 l 17.053667,5.62831 17.05367,5.62831 H 123.05367 124 V 286.7004 262.73412 l 36.33334,12.39769 36.33333,12.39771 0.37356,24.56857 0.37358,24.56859 54.95976,18.77527 54.95977,18.77526 0.34976,-48.44193 0.34976,-48.44194 z"
id="path291"
inkscape:connector-curvature="0" />
<path
style="fill:#331f10;stroke-width:1.33333337"
d="m 318.00001,633.32721 -18.66667,-6.47002 -40.66666,-13.9282 -40.66667,-13.92818 -75.33334,-25.69238 -75.333334,-25.69238 -4.666667,-4.49672 -4.666667,-4.49674 -0.323152,-90.96621 -0.323153,-90.96622 -7.393739,-2.75893 -7.393739,-2.75894 -3.616442,-3.61644 -3.616442,-3.61644 V 239.32867 134.71795 l 4,-3.86977 4,-3.86977 L 192.05097,76.155871 340.7686,25.333334 h 3.23141 3.23142 l 148.71763,50.822537 148.71763,50.822539 4,3.86977 4,3.86977 v 202.61539 202.6154 l -4,3.91564 -4,3.91564 -37.40423,12.77667 -37.40424,12.77666 -4.59576,-0.10146 -4.59577,-0.10147 -4.47184,-1.61859 -4.47184,-1.61858 -58.19483,19.81686 -58.19483,19.81688 -9.33334,3.08362 -9.33333,3.08361 -35.31601,12.15287 -35.31602,12.15288 -4.68398,-0.10147 -4.68399,-0.10133 -18.66667,-6.47003 z m 55.33334,-20.10035 31.33333,-10.75221 27.33333,-9.36638 27.33334,-9.36637 32.33333,-10.85411 32.33334,-10.8541 v -1.01684 -1.01683 h -1.75055 -1.75055 l -3.91612,-4.08755 -3.91612,-4.08756 v -7.15822 -7.15823 l 3.8866,-4.05674 3.88659,-4.05673 4.44675,-1.46756 4.44673,-1.46755 v -19.30862 -19.30862 l -1.27909,0.79052 -1.27911,0.79052 -3.05423,-1.71182 -3.05424,-1.71184 -3.66666,-3.24946 -3.66667,-3.24945 v -1.82924 -1.82923 l -1.17139,0.72395 -1.17137,0.72396 -3.8972,-1.94417 -3.89719,-1.94419 -3.26476,-3.47396 -3.26476,-3.47396 -0.37534,-55.89379 -0.37534,-55.8938 h -1.22164 -1.22162 l -11.31452,4.09407 -11.31452,4.09408 -0.42184,21.88385 -0.42184,21.88384 -4,3.96017 -4,3.96018 -55.33334,18.91908 -55.33333,18.91908 -4.89055,1.12495 -4.89053,1.12494 -17.10947,-6.03062 -17.10946,-6.03064 -4.02,-1.86536 -4.02,-1.86535 -3.31333,-3.52306 -3.31333,-3.52305 -0.41923,-21.6014 -0.41921,-21.6014 -46.24746,-15.78812 -46.24744,-15.78812 -5.33333,-2.39239 -5.33334,-2.39237 -3.33333,-3.55144 -3.33333,-3.55143 -0.41975,-21.64179 -0.41975,-21.64177 -10.46026,-3.42923 -10.46027,-3.42921 -0.45332,13.08993 -0.45332,13.08992 -3.8474,4.01294 -3.84741,4.01293 -6.40649,1.37395 -6.40648,1.37394 -5.21141,-1.83869 -5.21141,-1.83869 -1.39345,0.8698 -1.39345,0.86981 -0.47459,12.24744 -0.47458,12.24744 -3.85016,4.01706 -3.85017,4.01704 -6.03325,1.28677 -6.03325,1.28677 -3.14165,-1.19445 -3.141645,-1.19445 -7.330806,1.90942 -7.330804,1.90944 -5.32065,-1.87724 -5.320649,-1.87724 0.343183,84.75833 0.343184,84.7583 80.666667,27.60755 80.66667,27.60756 34.66667,11.83802 34.66667,11.83801 18,6.31649 18,6.3165 0.66667,0.0801 0.66666,0.0801 31.33334,-10.7522 z m 228.16718,-69.48009 35.83283,-12.25326 -10e-4,-195.41342 -10e-4,-195.41342 L 490.66539,90.485064 344.00001,40.303459 197.33463,90.485064 50.669248,140.66667 l -0.0013,24.22278 -0.0013,24.22276 18.666668,6.22113 18.666667,6.22113 v 24.49459 24.49458 l -18.666667,-6.36028 -18.666668,-6.36029 v 24.29647 24.29647 l 6.333334,2.22064 6.333333,2.22065 29.223488,9.90468 29.223487,9.9047 H 122.89016 124 v -23.91239 -23.9124 l 9,3.03367 9,3.03366 0.7157,22.54539 0.71569,22.5454 0.28431,-22.29676 0.2843,-22.29676 26.33334,9.10852 26.33333,9.10852 0.3721,24.52157 0.37209,24.52158 50.29458,17.16036 50.29457,17.16037 23,7.98934 23,7.98934 v 24.47823 24.47824 l 54.87556,-18.62795 54.87555,-18.62793 h 0.42836 0.42836 l 0.36275,-24.84929 0.36276,-24.84931 36.33333,-12.2384 36.33334,-12.2384 v 73.08769 73.08771 h 0.57956 0.57954 l 16.91365,-6 16.91362,-6 h 1.17348 1.17348 v 35.17008 35.17007 l -1.66666,1.30763 -1.66667,1.30762 -6.57085,2.18898 -6.57086,2.18896 h -1.06357 -1.06357 l -0.42755,-21.66667 -0.42755,-21.66667 0.062,22.18015 0.062,22.18015 -9.33333,3.02275 -9.33334,3.02276 18.66667,6.35876 18.66667,6.35877 0.50051,0.10507 0.5005,0.10506 35.83283,-12.25325 z m -276.83385,-212.17092 -16,-5.57584 -0.3638,-24.43285 -0.36379,-24.43286 2.36379,0.7508 2.3638,0.7508 15.33333,5.13275 15.33334,5.13275 0.36341,24.21597 0.36341,24.21597 -1.69674,-0.0908 -1.69675,-0.0908 -16,-5.57585 z m 240.66667,-44.79247 v -23.8833 l 18,-6.01703 18,-6.01704 v 24.27203 24.27202 l -17.05366,5.62831 -17.05367,5.62831 h -0.94633 -0.94634 z m -37.33333,-35.95642 v -23.83973 l 17.44712,-6.16028 17.44713,-6.16028 h 1.24962 1.24962 l -0.36341,24.21686 -0.36341,24.21684 -17.29424,5.78316 -17.29425,5.78315 h -1.03909 -1.03909 z m -36,-35.92778 v -23.9472 l 2.33333,-0.95473 2.33333,-0.95475 15.27088,-5.18791 15.27088,-5.18792 h 0.42587 0.42587 l -0.36342,24.21598 -0.36341,24.21597 -15.33333,5.13275 -15.33334,5.13274 -2.33333,0.74114 -2.33333,0.74113 z"
id="path289"
inkscape:connector-curvature="0" />
<path
style="fill:#321e0e;stroke-width:1.33333337"
d="m 318.00001,633.32721 -18.66667,-6.47002 -40.66666,-13.9282 -40.66667,-13.92818 -75.33334,-25.69238 -75.333334,-25.69238 -4.666667,-4.49672 -4.666667,-4.49674 -0.323152,-90.96621 -0.323153,-90.96622 -7.393739,-2.75893 -7.393739,-2.75894 -3.616442,-3.61644 -3.616442,-3.61644 V 239.32867 134.71795 l 4,-3.86977 4,-3.86977 L 192.05097,76.155871 340.7686,25.333334 h 3.23141 3.23142 l 148.71763,50.822537 148.71763,50.822539 4,3.86977 4,3.86977 v 202.61539 202.6154 l -4,3.91564 -4,3.91564 -37.40423,12.77667 -37.40424,12.77666 -4.59576,-0.10146 -4.59577,-0.10147 -4.47184,-1.61859 -4.47184,-1.61858 -58.19483,19.81686 -58.19483,19.81688 -9.33334,3.08362 -9.33333,3.08361 -35.31601,12.15287 -35.31602,12.15288 -4.68398,-0.10147 -4.68399,-0.10133 -18.66667,-6.47003 z m 55.33334,-20.10035 31.33333,-10.75221 27.33333,-9.36638 27.33334,-9.36637 32.33333,-10.85411 32.33334,-10.8541 v -1.01684 -1.01683 h -1.75055 -1.75055 l -3.91612,-4.08755 -3.91612,-4.08756 v -7.15822 -7.15823 l 3.8866,-4.05674 3.88659,-4.05673 4.44675,-1.46756 4.44673,-1.46755 v -19.30862 -19.30862 l -1.27909,0.79052 -1.27911,0.79052 -3.05423,-1.71182 -3.05424,-1.71184 -3.66666,-3.24946 -3.66667,-3.24945 v -1.82924 -1.82923 l -1.17139,0.72395 -1.17137,0.72396 -3.8972,-1.94417 -3.89719,-1.94419 -3.26476,-3.47396 -3.26476,-3.47396 -0.37534,-55.89379 -0.37534,-55.8938 h -1.22164 -1.22162 l -11.31452,4.09407 -11.31452,4.09408 -0.42184,21.88385 -0.42184,21.88384 -4,3.96017 -4,3.96018 -55.33334,18.91908 -55.33333,18.91908 -4.89055,1.12495 -4.89053,1.12494 -17.10947,-6.03062 -17.10946,-6.03064 -4.02,-1.86536 -4.02,-1.86535 -3.31333,-3.52306 -3.31333,-3.52305 -0.41923,-21.6014 -0.41921,-21.6014 -46.24746,-15.78812 -46.24744,-15.78812 -5.33333,-2.39239 -5.33334,-2.39237 -3.33333,-3.55144 -3.33333,-3.55143 -0.41975,-21.64179 -0.41975,-21.64177 -10.46026,-3.42923 -10.46027,-3.42921 -0.45332,13.08993 -0.45332,13.08992 -3.8474,4.01294 -3.84741,4.01293 -6.40649,1.37395 -6.40648,1.37394 -5.21141,-1.83869 -5.21141,-1.83869 -1.39345,0.8698 -1.39345,0.86981 -0.47459,12.24744 -0.47458,12.24744 -3.85016,4.01706 -3.85017,4.01704 -6.03325,1.28677 -6.03325,1.28677 -3.14165,-1.19445 -3.141645,-1.19445 -7.330806,1.90942 -7.330804,1.90944 -5.32065,-1.87724 -5.320649,-1.87724 0.343183,84.75833 0.343184,84.7583 80.666667,27.60755 80.66667,27.60756 34.66667,11.83802 34.66667,11.83801 18,6.31649 18,6.3165 0.66667,0.0801 0.66666,0.0801 31.33334,-10.7522 z m 228.16718,-69.48009 35.83283,-12.25326 -10e-4,-195.41342 -10e-4,-195.41342 L 490.66539,90.485064 344.00001,40.303459 197.33463,90.485064 50.669248,140.66667 l -0.0013,24.22278 -0.0013,24.22276 18.666668,6.22113 18.666667,6.22113 v 24.52908 24.52909 l -18.666667,-6.56642 -18.666668,-6.56641 v 48.95597 48.95599 l 18.666668,6.18778 18.666667,6.18776 v -23.88365 -23.88365 h 1.062451 1.06245 L 106,305.33334 l 15.8751,5.33334 H 122.93755 124 v -23.91239 -23.9124 l 9,3.03367 9,3.03366 0.7157,22.54539 0.71569,22.5454 0.28431,-22.29676 0.2843,-22.29676 26.33334,9.10852 26.33333,9.10852 0.37356,24.52157 0.37358,24.52158 54.95976,18.7738 54.95977,18.77381 0.36167,24.59814 0.36167,24.59813 18.34585,6.08143 18.34586,6.08141 4.62581,-1.55239 4.62581,-1.5524 50.30447,-17.0522 50.30447,-17.0522 0.3622,-24.71646 0.3622,-24.71647 36.33333,-12.17803 36.33334,-12.17804 v 73.04574 73.04573 h 0.45793 0.45793 l 7.75081,-2.66666 7.7508,-2.66667 h 0.41609 0.41609 l 0.37518,35.84589 0.37517,35.84589 -9.33333,3.02368 -9.33334,3.02368 18.66667,6.35876 18.66667,6.35877 0.5005,0.10507 0.50051,0.10506 35.83283,-12.25325 z m -54.83384,-43.50018 v -35.75343 l 8.33333,-2.92673 8.33333,-2.92673 1,0.0135 1,0.0135 v 35.17008 35.17007 l -1.66666,1.30762 -1.66667,1.30763 -6.57085,2.18897 -6.57086,2.18896 h -1.09581 -1.09581 V 500.24654 Z M 324.66668,331.4447 l -16,-5.74138 -0.3638,-24.28451 -0.36379,-24.28451 2.36379,0.7508 2.3638,0.7508 15.33333,5.13275 15.33334,5.13275 0.36341,24.21597 0.36341,24.21597 -1.69674,-0.0736 -1.69675,-0.0736 -16,-5.74138 z"
id="path287"
inkscape:connector-curvature="0" />
<path
style="fill:#000000;stroke-width:1.33333337"
d="m 318.00001,633.32721 -18.66667,-6.47002 -40.66666,-13.9282 -40.66667,-13.92818 -75.33334,-25.69238 -75.333334,-25.69238 -4.666667,-4.49672 -4.666667,-4.49674 -0.323152,-90.96621 -0.323153,-90.96622 -7.393739,-2.75893 -7.393739,-2.75894 -3.616442,-3.61644 -3.616442,-3.61644 V 239.32867 134.71795 l 4,-3.86977 4,-3.86977 L 192.05097,76.155871 340.7686,25.333334 h 3.23141 3.23142 l 148.71763,50.822537 148.71763,50.822539 4,3.86977 4,3.86977 v 202.61539 202.6154 l -4,3.91564 -4,3.91564 -37.40423,12.77667 -37.40424,12.77666 -4.59576,-0.10146 -4.59577,-0.10147 -4.47184,-1.61859 -4.47184,-1.61858 -58.19483,19.81686 -58.19483,19.81688 -9.33334,3.08362 -9.33333,3.08361 -35.31601,12.15287 -35.31602,12.15288 -4.68398,-0.10147 -4.68399,-0.10133 -18.66667,-6.47003 z m 55.33334,-20.10035 31.33333,-10.75221 27.33333,-9.36638 27.33334,-9.36637 32.33333,-10.85411 32.33334,-10.8541 v -1.01684 -1.01683 h -1.75055 -1.75055 l -3.91612,-4.08755 -3.91612,-4.08756 v -7.15822 -7.15823 l 3.8866,-4.05674 3.88659,-4.05673 4.44675,-1.46756 4.44673,-1.46755 v -19.30862 -19.30862 l -1.27909,0.79052 -1.27911,0.79052 -3.05423,-1.71182 -3.05424,-1.71184 -3.66666,-3.24946 -3.66667,-3.24945 v -1.82924 -1.82923 l -1.17139,0.72395 -1.17137,0.72396 -3.8972,-1.94417 -3.89719,-1.94419 -3.26476,-3.47396 -3.26476,-3.47396 -0.37534,-55.89379 -0.37534,-55.8938 h -1.22164 -1.22162 l -11.31452,4.09407 -11.31452,4.09408 -0.42184,21.88385 -0.42184,21.88384 -4,3.96017 -4,3.96018 -55.33334,18.91908 -55.33333,18.91908 -4.89055,1.12495 -4.89053,1.12494 -17.10947,-6.03062 -17.10946,-6.03064 -4.02,-1.86536 -4.02,-1.86535 -3.31333,-3.52306 -3.31333,-3.52305 -0.41912,-21.59365 -0.41912,-21.59366 -46.24755,-15.80996 -46.24755,-15.80996 -5.33333,-2.37829 -5.33334,-2.37828 -3.33333,-3.55144 -3.33333,-3.55143 -0.41975,-21.64179 -0.41975,-21.64177 -10.46026,-3.42923 -10.46027,-3.42921 -0.45332,13.08993 -0.45332,13.08992 -3.8474,4.01294 -3.84741,4.01293 -6.40649,1.37395 -6.40648,1.37394 -5.21141,-1.83869 -5.21141,-1.83869 -1.39345,0.8698 -1.39345,0.86981 -0.47459,12.24744 -0.47458,12.24744 -3.85016,4.01706 -3.85017,4.01704 -6.01541,1.28297 -6.01541,1.28296 -2.81189,-1.28119 -2.811896,-1.28118 -7.6784,1.99997 -7.678399,1.99997 -5.32065,-1.87724 -5.320649,-1.87724 0.343183,84.75833 0.343184,84.7583 80.666667,27.60755 80.66667,27.60756 34.66667,11.83802 34.66667,11.83801 18,6.31649 18,6.3165 0.66666,0.0801 0.66667,0.0801 31.33334,-10.7522 z m 228.16718,-69.48009 35.83283,-12.25326 -10e-4,-195.41342 -10e-4,-195.41342 L 490.66539,90.485064 344.00001,40.303459 197.33463,90.485064 50.669248,140.66667 l -0.0013,97.36255 -0.0013,97.36255 18.666668,6.18778 18.666667,6.18776 v -3.88364 -3.88366 h 1.099797 1.099796 l 9.566871,3.25391 9.566873,3.25389 v -19.92056 -19.92057 h 0.42915 0.42914 l 6.38388,2.1752 6.38388,2.17521 1.03889,-1.68096 1.03889,-1.68095 8.40698,2.83908 8.40697,2.83908 H 142.92556 144 v -21.96342 -21.96343 l 26.33334,9.10852 26.33333,9.10852 0.36154,24.52233 0.36153,24.52234 38.9718,13.24477 38.9718,13.24478 16,5.61069 16,5.61068 0.36167,24.51572 0.36167,24.51572 18.3305,6.07633 18.33051,6.07634 9.30783,-3.09907 9.30783,-3.09908 45.6378,-15.49991 45.6378,-15.4999 0.3622,-24.73519 0.3622,-24.73517 27.30869,-9.11413 27.30868,-9.1141 h 1.02466 1.02464 v 64 64 l 1,-6.6e-4 1,-6.8e-4 7,-2.66056 7,-2.66056 v 8.66124 8.66122 h 0.45793 0.45793 l 7.75081,-2.66666 7.7508,-2.66667 h 0.45793 0.45793 v 35.89129 35.8913 l -9,2.99603 -9,2.99602 18.66667,6.34102 18.66667,6.34101 0.5005,0.10507 0.50051,0.10506 35.83283,-12.25325 z"
id="path285"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 72 KiB

BIN
assets/sam_icon_128.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
assets/sam_icon_16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 409 B

BIN
assets/skip_fwd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 B

BIN
assets/skip_rev.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 422 B

BIN
assets/title.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
media/blank.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 B

BIN
media/character.b3d Normal file

Binary file not shown.

BIN
media/character.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

881
media/pickaxe.obj Normal file
View File

@ -0,0 +1,881 @@
# Blender v2.78 (sub 0) OBJ File: 'pickaxe.blend'
# www.blender.org
o Cube
v 0.062500 0.353553 1.285178
v 0.062500 -0.353554 1.285177
v 0.062500 -0.000000 1.638731
v 0.062500 0.176777 1.108401
v 0.062500 -0.530330 1.461954
v 0.062500 0.176777 0.754847
v 0.062500 -0.176777 0.754847
v 0.062500 -0.176777 1.108401
v 0.062500 -0.883883 1.108400
v 0.062500 0.883883 1.108401
v 0.062500 -0.176776 0.047741
v 0.062500 0.176777 0.401294
v 0.062500 -0.176776 0.401294
v 0.062500 0.176777 0.047741
v 0.062500 -0.353554 1.638731
v 0.062500 0.088388 1.020012
v 0.062500 -0.618719 1.550342
v 0.062500 0.088388 0.843236
v 0.062500 -0.265165 1.196789
v 0.062500 -0.972272 1.196789
v 0.062500 0.088388 1.727119
v 0.062500 0.441942 1.196789
v 0.062500 0.088389 0.312906
v 0.062500 0.265165 1.196789
v 0.062500 -0.088388 0.843236
v 0.062500 -0.088388 1.020012
v 0.062500 -0.441942 1.196789
v 0.062500 -0.088389 1.727119
v 0.062500 0.972272 1.196789
v 0.062500 -0.088388 0.136129
v 0.062500 -0.088388 0.312906
v 0.062500 -0.088388 0.489682
v 0.062500 0.088388 0.666459
v 0.062500 -0.088388 0.666459
v 0.062500 0.088389 0.489682
v 0.062500 0.972272 1.020013
v 0.062500 0.618718 1.196789
v 0.062500 0.795495 1.373566
v 0.062500 0.795495 1.196789
v 0.062500 0.441941 1.550343
v 0.062500 -0.441942 1.550342
v 0.062500 -0.265165 1.550342
v 0.062500 -0.795495 1.196789
v 0.062500 -0.795495 1.373565
v 0.062500 -0.618718 1.196789
v 0.062500 -0.088388 1.196789
v 0.062500 0.088388 1.196789
v 0.062500 -0.972272 1.020012
v 0.062500 -0.088388 -0.040648
v 0.062500 0.088389 -0.217424
v 0.062500 0.176777 -0.129036
v 0.062500 -0.176776 -0.129036
v 0.062500 -1.060660 1.108400
v 0.062500 0.176777 1.285177
v 0.062500 -0.176777 1.285177
v 0.062500 -0.530330 1.285177
v 0.062500 -0.707107 1.461954
v 0.062500 -0.883884 1.285177
v 0.062500 -0.176777 0.931624
v 0.062500 -0.176777 1.638731
v 0.062500 0.176777 0.931624
v 0.062500 0.883883 1.285178
v 0.062500 0.530330 1.285178
v 0.062500 -0.176776 0.224517
v 0.062500 0.176777 0.578071
v 0.062500 -0.176776 0.578071
v 0.062500 0.707107 1.108401
v 0.062500 -0.707107 1.108400
v 0.062500 -0.000000 0.931624
v 0.062500 0.000000 0.224518
v 0.062500 0.530330 1.461954
v 0.062500 0.176777 1.461954
v 0.062500 -0.176777 1.461954
v 0.062500 0.000000 0.578071
v 0.062500 0.707107 1.285178
v 0.062500 0.353553 1.638731
v 0.062500 -0.707107 1.285177
v 0.062500 -0.000000 1.285177
v 0.062500 0.000000 -0.129036
v 0.062500 0.618718 1.550343
v 0.062500 -0.441942 1.373566
v 0.062500 0.265165 1.373566
v 0.062500 -0.088388 1.550342
v 0.062500 0.441942 1.373566
v 0.062500 0.088388 1.550343
v 0.062500 -0.265165 1.373566
v 0.062500 0.088388 0.136129
v 0.062500 0.618718 1.373566
v 0.062500 0.265165 1.550343
v 0.062500 -0.618718 1.373566
v 0.062500 -0.088388 1.373566
v 0.062500 0.088388 1.373566
v 0.062500 0.088388 -0.040648
v 0.062500 -0.088388 -0.217424
v 0.062500 0.000000 0.047741
v 0.062500 -0.000000 1.461954
v 0.062500 0.176777 1.638731
v 0.062500 1.060660 1.108401
v 0.062500 0.707107 1.461954
v 0.062500 0.176777 0.224517
v 0.062500 0.000000 0.754847
v 0.062500 0.000000 0.401294
v 0.062500 -0.353553 1.461954
v 0.062500 0.353553 1.461954
v 0.062500 -0.000000 1.108401
v 0.062500 0.000000 -0.305812
v -0.062500 0.088388 1.020012
v -0.062500 -0.000000 0.931624
v -0.062500 0.088388 0.843236
v -0.062500 0.441941 1.373566
v -0.062500 0.353553 1.285178
v -0.062500 -0.265165 1.196789
v -0.062500 -0.353554 1.285177
v -0.062500 -0.265165 1.373566
v -0.062500 0.088388 1.727119
v -0.062500 -0.000000 1.638731
v -0.062500 0.088388 1.550343
v -0.062500 0.441942 1.196789
v -0.062500 0.088389 0.312906
v -0.062500 0.000000 0.224517
v -0.062500 0.088389 0.136129
v -0.062500 -0.441942 1.373566
v -0.062500 -0.530330 1.461954
v -0.062500 -0.088388 0.843236
v -0.062500 -0.176777 0.754847
v -0.062500 0.618718 1.550343
v -0.062500 0.530330 1.461954
v -0.062500 -0.088388 1.020012
v -0.062500 -0.176777 1.108401
v -0.062500 -0.088389 1.550342
v -0.062500 -0.176777 1.461954
v -0.062500 0.265165 1.373566
v -0.062500 0.176776 1.461954
v -0.062500 0.972272 1.196789
v -0.062500 0.883883 1.108401
v -0.062500 -0.088388 0.136129
v -0.062500 -0.176776 0.047741
v -0.062500 -0.088388 0.312906
v -0.062500 -0.176776 0.401294
v -0.062500 -0.088388 0.489682
v -0.062500 0.088388 0.666459
v -0.062500 0.000000 0.578071
v -0.062500 -0.088388 0.666459
v -0.062500 0.088389 0.489682
v -0.062500 0.972272 1.020013
v -0.062500 0.795495 1.373566
v -0.062500 0.707107 1.285178
v -0.062500 0.618718 1.373566
v -0.062500 0.795495 1.196789
v -0.062500 0.265165 1.550343
v -0.062500 0.441941 1.550343
v -0.062500 0.353553 1.638731
v -0.062500 -0.441942 1.550342
v -0.062500 -0.265165 1.550342
v -0.062500 -0.353554 1.638731
v -0.062500 -0.795495 1.196789
v -0.062500 -0.883883 1.108400
v -0.062500 -0.618719 1.373566
v -0.062500 -0.707107 1.285177
v -0.062500 -0.618718 1.196789
v -0.062500 -0.088388 1.196789
v -0.062500 0.088388 1.373566
v -0.062500 -0.000000 1.285177
v -0.062500 -0.088388 1.373566
v -0.062500 0.088388 1.196789
v -0.062500 0.088389 -0.040647
v -0.062500 0.000000 -0.129036
v -0.062500 -0.088388 -0.040648
v -0.062500 0.088389 -0.217424
v -0.062500 0.176777 1.108401
v -0.062500 -0.618719 1.550342
v -0.062500 0.176777 0.754847
v -0.062500 -0.972272 1.196789
v -0.062500 0.176777 0.401294
v -0.062500 0.176777 0.047741
v -0.062500 0.265165 1.196789
v -0.062500 -0.441942 1.196789
v -0.062500 -0.088389 1.727119
v -0.062500 0.618718 1.196789
v -0.062500 -0.795495 1.373565
v -0.062500 -0.972272 1.020012
v -0.062500 -0.088388 -0.217424
v -0.062500 0.176777 -0.129036
v -0.062500 0.000000 0.047741
v -0.062500 -0.176776 -0.129036
v -0.062500 -1.060660 1.108400
v -0.062500 0.176777 1.285177
v -0.062500 -0.000000 1.461954
v -0.062500 -0.176777 1.285177
v -0.062500 -0.530330 1.285177
v -0.062500 -0.707107 1.461954
v -0.062500 -0.883884 1.285177
v -0.062500 -0.176777 0.931624
v -0.062500 -0.176777 1.638731
v -0.062500 0.176776 1.638731
v -0.062500 0.176777 0.931624
v -0.062500 0.883883 1.285178
v -0.062500 0.707107 1.461954
v -0.062500 0.530330 1.285178
v -0.062500 1.060660 1.108401
v -0.062500 -0.176776 0.224517
v -0.062500 0.176777 0.578071
v -0.062500 0.000000 0.754847
v -0.062500 -0.176776 0.578071
v -0.062500 0.176777 0.224518
v -0.062500 0.000000 0.401294
v -0.062500 0.707107 1.108401
v -0.062500 0.353553 1.461954
v -0.062500 -0.353554 1.461954
v -0.062500 -0.707107 1.108401
v -0.062500 -0.000000 1.108401
v -0.062500 0.000001 -0.305812
vt 0.4375 0.7500
vt 0.5000 0.7500
vt 0.5000 0.8125
vt 0.4375 0.8125
vt 0.4375 0.8750
vt 0.5000 0.8750
vt 0.5000 0.9375
vt 0.4375 0.9375
vt 0.4375 0.7500
vt 0.5000 0.7500
vt 0.5000 0.8125
vt 0.4375 0.8125
vt 0.3750 0.8750
vt 0.4375 0.8750
vt 0.4375 0.9375
vt 0.3750 0.9375
vt 0.5000 0.4375
vt 0.4375 0.4375
vt 0.4375 0.3750
vt 0.5000 0.3750
vt 0.4375 0.3750
vt 0.5000 0.3750
vt 0.5000 0.4375
vt 0.4375 0.4375
vt 0.8125 0.3750
vt 0.8750 0.3750
vt 0.8750 0.4375
vt 0.8125 0.4375
vt 0.2500 0.8750
vt 0.3125 0.8750
vt 0.3125 0.9375
vt 0.2500 0.9375
vt 0.8125 0.5000
vt 0.8750 0.5000
vt 0.8750 0.5625
vt 0.8125 0.5625
vt 0.4375 0.8750
vt 0.5000 0.8750
vt 0.5000 0.9375
vt 0.4375 0.9375
vt 0.1875 0.2500
vt 0.2500 0.2500
vt 0.2500 0.3125
vt 0.1875 0.3125
vt 0.7500 0.6875
vt 0.8125 0.6875
vt 0.8125 0.7500
vt 0.7500 0.7500
vt 0.3750 0.3125
vt 0.3125 0.3125
vt 0.3125 0.2500
vt 0.3750 0.2500
vt 0.7500 0.6250
vt 0.8125 0.6250
vt 0.8125 0.6875
vt 0.7500 0.6875
vt 0.7500 0.6875
vt 0.8125 0.6875
vt 0.8125 0.7500
vt 0.7500 0.7500
vt 0.1875 0.2500
vt 0.2500 0.2500
vt 0.2500 0.3125
vt 0.1875 0.3125
vt 0.2500 0.8750
vt 0.3125 0.8750
vt 0.3125 0.9375
vt 0.2500 0.9375
vt 0.6875 0.7500
vt 0.7500 0.7500
vt 0.7500 0.8125
vt 0.6875 0.8125
vt 0.3125 0.8750
vt 0.3750 0.8750
vt 0.3750 0.9375
vt 0.3125 0.9375
vt 0.5625 0.8125
vt 0.6250 0.8125
vt 0.6250 0.8750
vt 0.5625 0.8750
vt 0.0625 0.1250
vt 0.1250 0.1250
vt 0.1250 0.1875
vt 0.0625 0.1875
vt 0.2500 0.1875
vt 0.3125 0.1875
vt 0.3125 0.2500
vt 0.2500 0.2500
vt 0.3125 0.8125
vt 0.3750 0.8125
vt 0.3750 0.8750
vt 0.3125 0.8750
vt 0.0625 0.1250
vt 0.1250 0.1250
vt 0.1250 0.1875
vt 0.0625 0.1875
vt 0.1250 0.1875
vt 0.1875 0.1875
vt 0.1875 0.2500
vt 0.1250 0.2500
vt 0.3125 0.2500
vt 0.2500 0.2500
vt 0.2500 0.1875
vt 0.3125 0.1875
vt 0.7500 0.4375
vt 0.8125 0.4375
vt 0.8125 0.5000
vt 0.7500 0.5000
vt 0.3125 0.2500
vt 0.3750 0.2500
vt 0.3750 0.3125
vt 0.3125 0.3125
vt 0.3125 0.8125
vt 0.3750 0.8125
vt 0.3750 0.8750
vt 0.3125 0.8750
vt 0.4375 0.5000
vt 0.5000 0.5000
vt 0.5000 0.5625
vt 0.4375 0.5625
vt 0.8125 0.3125
vt 0.8750 0.3125
vt 0.8750 0.3750
vt 0.8125 0.3750
vt 0.3750 0.4375
vt 0.4375 0.4375
vt 0.4375 0.5000
vt 0.3750 0.5000
vt 0.2500 0.3125
vt 0.3125 0.3125
vt 0.3125 0.3750
vt 0.2500 0.3750
vt 0.2500 0.1875
vt 0.1875 0.1875
vt 0.1875 0.1250
vt 0.2500 0.1250
vt 0.6250 0.5625
vt 0.5625 0.5625
vt 0.5625 0.5000
vt 0.6250 0.5000
vt 0.8125 0.3125
vt 0.8750 0.3125
vt 0.8750 0.3750
vt 0.8125 0.3750
vt 0.8750 0.4375
vt 0.9375 0.4375
vt 0.9375 0.5000
vt 0.8750 0.5000
vt 0.1250 0.1875
vt 0.1875 0.1875
vt 0.1875 0.2500
vt 0.1250 0.2500
vt 0.4375 0.5000
vt 0.5000 0.5000
vt 0.5000 0.5625
vt 0.4375 0.5625
vt 0.5000 0.4375
vt 0.5625 0.4375
vt 0.5625 0.5000
vt 0.5000 0.5000
vt 0.5000 0.5625
vt 0.5625 0.5625
vt 0.5625 0.6250
vt 0.5000 0.6250
vt 0.6875 0.5000
vt 0.7500 0.5000
vt 0.7500 0.5625
vt 0.6875 0.5625
vt 0.3750 0.3125
vt 0.4375 0.3125
vt 0.4375 0.3750
vt 0.3750 0.3750
vt 0.2500 0.3125
vt 0.3125 0.3125
vt 0.3125 0.3750
vt 0.2500 0.3750
vt 0.6250 0.5625
vt 0.6875 0.5625
vt 0.6875 0.6250
vt 0.6250 0.6250
vt 0.5625 0.5000
vt 0.5000 0.5000
vt 0.5000 0.4375
vt 0.5625 0.4375
vt 0.8125 0.5625
vt 0.8750 0.5625
vt 0.8750 0.6250
vt 0.8125 0.6250
vt 0.4375 0.3750
vt 0.3750 0.3750
vt 0.3750 0.3125
vt 0.4375 0.3125
vt 0.3750 0.4375
vt 0.4375 0.4375
vt 0.4375 0.5000
vt 0.3750 0.5000
vt 0.8750 0.1875
vt 0.9375 0.1875
vt 0.9375 0.2500
vt 0.8750 0.2500
vt 0.8750 0.1875
vt 0.9375 0.1875
vt 0.9375 0.2500
vt 0.8750 0.2500
vt 0.1875 0.8750
vt 0.2500 0.8750
vt 0.2500 0.9375
vt 0.1875 0.9375
vt 0.0625 0.0625
vt 0.1250 0.0625
vt 0.1250 0.1250
vt 0.0625 0.1250
vt 0.6875 0.5000
vt 0.7500 0.5000
vt 0.7500 0.5625
vt 0.6875 0.5625
vt 0.0625 0.0625
vt 0.1250 0.0625
vt 0.1250 0.1250
vt 0.0625 0.1250
vt 0.8750 0.1875
vt 0.9375 0.1875
vt 0.9375 0.2500
vt 0.8750 0.2500
vt 0.1875 0.8750
vt 0.2500 0.8750
vt 0.2500 0.9375
vt 0.1875 0.9375
vt 0.8750 0.3125
vt 0.9375 0.3125
vt 0.9375 0.3750
vt 0.8750 0.3750
vt 0.8750 0.2500
vt 0.9375 0.2500
vt 0.9375 0.3125
vt 0.8750 0.3125
vt 0.1875 0.8750
vt 0.1875 0.9375
vt 0.5000 0.8125
vt 0.5625 0.8125
vt 0.5625 0.8750
vt 0.5000 0.8750
vt 0.8750 0.2500
vt 0.9375 0.2500
vt 0.9375 0.3125
vt 0.8750 0.3125
vt 0.6250 0.7500
vt 0.6875 0.7500
vt 0.6875 0.8125
vt 0.6250 0.8125
vt 0.5000 0.5625
vt 0.5625 0.5625
vt 0.5625 0.6250
vt 0.5000 0.6250
vt 0.6875 0.7500
vt 0.7500 0.7500
vt 0.7500 0.8125
vt 0.6875 0.8125
vt 0.5625 0.5625
vt 0.5625 0.5000
vt 0.5000 0.5000
vt 0.5000 0.5625
vt 0.5625 0.8125
vt 0.5625 0.7500
vt 0.5000 0.8125
vt 0.8125 0.5625
vt 0.8125 0.5000
vt 0.7500 0.5625
vt 0.3125 0.3125
vt 0.2500 0.2500
vt 0.2500 0.3125
vt 0.4375 0.4375
vt 0.3750 0.3750
vt 0.3750 0.4375
vt 0.3125 0.9375
vt 0.2500 0.9375
vt 0.4375 0.9375
vt 0.4375 0.8750
vt 0.3750 0.8750
vt 0.3750 0.9375
vt 0.8125 0.6875
vt 0.8125 0.6250
vt 0.7500 0.6250
vt 0.7500 0.6875
vt 0.6875 0.8125
vt 0.6875 0.7500
vt 0.6250 0.7500
vt 0.6250 0.8125
vt 0.9375 0.4375
vt 0.9375 0.3750
vt 0.8750 0.3750
vt 0.8750 0.4375
vt 0.9375 0.3125
vt 0.9375 0.2500
vt 0.8750 0.2500
vt 0.6875 0.6875
vt 0.6875 0.6250
vt 0.6250 0.6250
vt 0.6250 0.6875
vt 0.1875 0.1875
vt 0.1875 0.1250
vt 0.1250 0.1250
vt 0.1250 0.1875
vt 0.1875 0.0625
vt 0.1875 0.2500
vt 0.1250 0.2500
vt 0.2500 0.1250
vt 0.0625 0.1250
vt 0.0625 0.1875
vt 0.7500 0.7500
vt 0.5625 0.6875
vt 0.5000 0.6875
vt 0.5625 0.6250
vt 0.9375 0.5000
vt 0.8750 0.5000
vt 0.8125 0.4375
vt 0.7500 0.4375
vt 0.8125 0.3750
vt 0.7500 0.8125
vt 0.8125 0.7500
vt 0.1875 0.9375
vt 0.4375 0.8125
vt 0.5000 0.8750
vt 0.5000 0.9375
vt 0.4375 0.5000
vt 0.4375 0.5625
vt 0.1875 0.3125
vt 0.3750 0.5000
vt 0.3125 0.3750
vt 0.3125 0.4375
vt 0.2500 0.3750
vt 0.8750 0.6250
vt 0.8750 0.5625
vt 0.5625 0.8750
vt 0.6250 0.8750
vt 0.5000 0.6250
vt 0.6250 0.5000
vt 0.5625 0.5625
vt 0.5000 0.5625
vt 0.5000 0.5000
vt 0.5625 0.5000
vt 0.8125 0.5625
vt 0.7500 0.5625
vt 0.8125 0.5000
vt 0.5625 0.8125
vt 0.5000 0.8125
vt 0.5000 0.7500
vt 0.5625 0.7500
vt 0.3125 0.3125
vt 0.2500 0.3125
vt 0.2500 0.2500
vt 0.3125 0.2500
vt 0.4375 0.4375
vt 0.3750 0.4375
vt 0.3750 0.3750
vt 0.4375 0.3750
vt 0.4375 0.9375
vt 0.3750 0.9375
vt 0.3750 0.8750
vt 0.4375 0.8750
vt 0.3125 0.9375
vt 0.2500 0.9375
vt 0.2500 0.8750
vt 0.6875 0.8125
vt 0.6250 0.8125
vt 0.6250 0.7500
vt 0.6875 0.7500
vt 0.7500 0.6875
vt 0.7500 0.6250
vt 0.8125 0.6250
vt 0.9375 0.4375
vt 0.8750 0.4375
vt 0.8750 0.3750
vt 0.6875 0.6875
vt 0.6250 0.6875
vt 0.6250 0.6250
vt 0.6875 0.6250
vt 0.1875 0.1875
vt 0.1250 0.1875
vt 0.1250 0.1250
vt 0.1875 0.1250
vt 0.2500 0.1875
vt 0.1875 0.2500
vt 0.1250 0.0625
vt 0.1875 0.0625
vt 0.8750 0.1875
vt 0.9375 0.1875
vt 0.5625 0.6875
vt 0.5625 0.6250
vt 0.5000 0.6875
vt 0.7500 0.7500
vt 0.6875 0.5000
vt 0.6250 0.5625
vt 0.8750 0.5000
vt 0.7500 0.4375
vt 0.9375 0.5000
vt 0.5000 0.4375
vt 0.4375 0.5000
vt 0.5000 0.8750
vt 0.4375 0.7500
vt 0.3750 0.8125
vt 0.1875 0.8750
vt 0.3125 0.4375
vt 0.3125 0.3750
vt 0.3750 0.3125
vt 0.3125 0.8125
vt 0.6250 0.8750
vt 0.5625 0.8750
vt 0.8125 0.3125
vt 0.0625 0.0625
vt 0.1875 0.1250
vt 0.1250 0.1250
vt 0.1250 0.0625
vt 0.5625 0.6250
vt 0.6250 0.6250
vt 0.6250 0.6875
vt 0.6250 0.5625
vt 0.5625 0.5625
vt 0.5000 0.6875
vt 0.5625 0.6875
vt 0.5625 0.7500
vt 0.8125 0.5625
vt 0.8750 0.5625
vt 0.8750 0.6250
vt 0.8125 0.6250
vt 0.8125 0.5000
vt 0.7500 0.5000
vt 0.3125 0.3750
vt 0.3750 0.3750
vt 0.3750 0.4375
vt 0.1875 0.1250
vt 0.2500 0.1875
vt 0.1875 0.1875
vt 0.8750 0.3750
vt 0.9375 0.3750
vt 0.8750 0.4375
vt 0.4375 0.8750
vt 0.5625 0.8125
vt 0.6250 0.8125
vt 0.5625 0.8750
vt 0.8750 0.4375
vt 0.9375 0.4375
vt 0.8750 0.5000
vt 0.3125 0.3750
vt 0.3750 0.3750
vt 0.3750 0.4375
vt 0.3125 0.4375
vt 0.5625 0.7500
vt 0.5000 0.7500
vn 0.0000 0.7071 -0.7071
vn 0.0000 -0.7071 0.7071
vn 0.0000 -0.7071 -0.7071
vn 0.0000 0.7071 0.7071
vn 1.0000 0.0000 -0.0000
vn -1.0000 -0.0000 0.0000
s off
f 63/1/1 22/2/1 118/3/1 199/4/1
f 71/5/2 80/6/2 126/7/2 127/8/2
f 22/9/3 1/10/3 111/11/3 118/12/3
f 99/13/4 38/14/4 146/15/4 198/16/4
f 7/17/2 25/18/2 124/19/2 125/20/2
f 34/21/3 7/22/3 125/23/3 143/24/3
f 56/25/1 45/26/1 160/27/1 190/28/1
f 10/29/3 39/30/3 149/31/3 135/32/3
f 5/33/2 41/34/2 153/35/2 123/36/2
f 80/37/4 99/38/4 198/39/4 126/40/4
f 23/41/4 100/42/4 205/43/4 119/44/4
f 60/45/2 28/46/2 178/47/2 194/48/2
f 13/49/2 32/50/2 140/51/2 139/52/2
f 42/53/2 60/54/2 194/55/2 154/56/2
f 28/57/4 3/58/4 116/59/4 178/60/4
f 100/61/1 87/62/1 121/63/1 205/64/1
f 62/65/4 29/66/4 134/67/4 197/68/4
f 3/69/2 21/70/2 115/71/2 116/72/2
f 38/73/4 62/74/4 197/75/4 146/76/4
f 76/77/4 40/78/4 151/79/4 152/80/4
f 93/81/4 51/82/4 183/83/4 166/84/4
f 30/85/3 64/86/3 201/87/3 136/88/3
f 67/89/3 37/90/3 179/91/3 207/92/3
f 51/93/1 50/94/1 169/95/1 183/96/1
f 87/97/4 14/98/4 175/99/4 121/100/4
f 64/101/2 31/102/2 138/103/2 201/104/2
f 2/105/1 27/106/1 177/107/1 113/108/1
f 31/109/3 13/110/3 139/111/3 138/112/3
f 39/113/1 67/114/1 207/115/1 149/116/1
f 16/117/4 61/118/4 196/119/4 107/120/4
f 68/121/3 43/122/3 156/123/3 210/124/3
f 18/125/4 6/126/4 172/127/4 109/128/4
f 12/129/1 23/130/1 119/131/1 174/132/1
f 11/133/2 30/134/2 136/135/2 137/136/2
f 8/137/2 46/138/2 161/139/2 129/140/2
f 45/141/1 68/142/1 210/143/1 160/144/1
f 17/145/4 5/146/4 123/147/4 171/148/4
f 14/149/1 93/150/1 166/151/1 175/152/1
f 61/153/1 18/154/1 109/155/1 196/156/1
f 25/157/3 59/158/3 193/159/3 124/160/3
f 4/161/1 16/162/1 107/163/1 170/164/1
f 19/165/3 2/166/3 113/167/3 112/168/3
f 32/169/3 66/170/3 204/171/3 140/172/3
f 35/173/4 12/174/4 174/175/4 144/176/4
f 46/177/3 55/178/3 189/179/3 161/180/3
f 59/181/2 26/182/2 128/183/2 193/184/2
f 41/185/2 15/186/2 155/187/2 153/188/2
f 66/189/2 34/190/2 143/191/2 204/192/2
f 6/193/1 33/194/1 141/195/1 172/196/1
f 9/197/1 48/198/1 181/199/1 157/200/1
f 48/201/3 53/202/3 186/203/3 181/204/3
f 29/205/4 98/206/4 200/207/4 134/208/4
f 106/209/3 94/210/3 182/211/3 212/212/3
f 55/213/1 19/214/1 112/215/1 189/216/1
f 50/217/1 106/218/1 212/219/1 169/220/1
f 53/221/2 20/222/2 173/223/2 186/224/2
f 98/225/1 36/226/1 145/227/1 200/228/1
f 58/229/2 44/230/2 180/231/2 192/232/2
f 20/233/2 58/234/2 192/235/2 173/236/2
f 36/237/3 10/29/3 135/32/3 145/238/3
f 40/239/4 71/240/4 127/241/4 151/242/4
f 43/243/1 9/244/1 157/245/1 156/246/1
f 97/247/4 89/248/4 150/249/4 195/250/4
f 47/251/4 4/252/4 170/253/4 165/254/4
f 21/255/4 97/256/4 195/257/4 115/258/4
f 105/259/5 26/260/5 69/261/5 16/262/5
f 104/263/5 82/264/5 1/10/5 84/265/5
f 103/266/5 81/267/5 2/166/5 86/268/5
f 102/269/5 31/109/5 70/270/5 23/271/5
f 101/272/5 34/21/5 74/273/5 33/274/5
f 62/275/5 39/30/5 10/29/5 29/276/5
f 99/277/5 88/278/5 75/279/5 38/280/5
f 60/281/5 42/282/5 73/283/5 83/284/5
f 97/285/5 85/286/5 72/287/5 89/288/5
f 57/289/5 44/290/5 77/291/5 90/292/5
f 58/293/5 20/294/5 9/295/5 43/122/5
f 96/296/5 91/297/5 78/298/5 92/299/5
f 95/300/5 49/301/5 79/302/5 93/303/5
f 49/301/5 52/304/5 94/210/5 79/302/5
f 87/305/5 95/300/5 93/303/5 14/306/5
f 70/270/5 30/85/5 95/300/5 87/305/5
f 30/85/5 11/307/5 49/301/5 95/300/5
f 93/303/5 79/302/5 50/308/5 51/309/5
f 91/297/5 55/178/5 46/177/5 78/298/5
f 73/283/5 86/268/5 55/178/5 91/297/5
f 86/268/5 2/166/5 19/165/5 55/178/5
f 85/286/5 96/296/5 92/299/5 72/287/5
f 3/310/5 83/284/5 96/296/5 85/286/5
f 83/284/5 73/283/5 91/297/5 96/296/5
f 82/264/5 54/311/5 24/312/5 1/10/5
f 72/287/5 92/299/5 54/311/5 82/264/5
f 92/299/5 78/298/5 47/313/5 54/311/5
f 26/260/5 59/158/5 25/157/5 69/261/5
f 44/290/5 58/293/5 43/122/5 77/291/5
f 17/314/5 57/289/5 90/292/5 5/315/5
f 81/267/5 56/316/5 27/317/5 2/166/5
f 5/315/5 90/292/5 56/316/5 81/267/5
f 90/292/5 77/291/5 45/318/5 56/316/5
f 20/294/5 53/202/5 48/201/5 9/295/5
f 21/319/5 3/310/5 85/286/5 97/285/5
f 28/320/5 60/281/5 83/284/5 3/310/5
f 29/276/5 10/29/5 36/237/5 98/321/5
f 88/278/5 63/322/5 37/90/5 75/279/5
f 71/323/5 84/265/5 63/322/5 88/278/5
f 84/265/5 1/10/5 22/9/5 63/322/5
f 80/324/5 71/323/5 88/278/5 99/277/5
f 38/280/5 75/279/5 39/30/5 62/275/5
f 16/262/5 69/261/5 18/325/5 61/326/5
f 23/271/5 70/270/5 87/305/5 100/327/5
f 34/21/5 66/170/5 32/169/5 74/273/5
f 18/325/5 101/272/5 33/274/5 6/328/5
f 69/261/5 25/157/5 101/272/5 18/325/5
f 25/157/5 7/22/5 34/21/5 101/272/5
f 33/274/5 74/273/5 35/329/5 65/330/5
f 31/109/5 64/86/5 30/85/5 70/270/5
f 35/329/5 102/269/5 23/271/5 12/331/5
f 74/273/5 32/169/5 102/269/5 35/329/5
f 32/169/5 13/110/5 31/109/5 102/269/5
f 75/279/5 37/90/5 67/89/5 39/30/5
f 42/282/5 103/266/5 86/268/5 73/283/5
f 15/332/5 41/333/5 103/266/5 42/282/5
f 41/333/5 5/315/5 81/267/5 103/266/5
f 40/334/5 104/263/5 84/265/5 71/323/5
f 76/335/5 89/288/5 104/263/5 40/334/5
f 89/288/5 72/287/5 82/264/5 104/263/5
f 77/291/5 43/122/5 68/121/5 45/318/5
f 47/313/5 105/259/5 16/262/5 4/336/5
f 78/298/5 46/177/5 105/259/5 47/313/5
f 46/177/5 8/337/5 26/260/5 105/259/5
f 79/302/5 94/210/5 106/209/5 50/308/5
f 211/338/6 107/339/6 108/340/6 128/341/6
f 209/342/6 114/343/6 113/108/6 122/344/6
f 208/345/6 110/346/6 111/347/6 132/348/6
f 206/349/6 119/350/6 120/351/6 138/352/6
f 203/353/6 141/354/6 142/355/6 143/356/6
f 198/357/6 146/358/6 147/359/6 148/360/6
f 197/361/6 134/362/6 135/363/6 149/116/6
f 195/364/6 150/365/6 133/366/6 117/367/6
f 194/55/6 130/368/6 131/369/6 154/370/6
f 192/235/6 156/246/6 157/200/6 173/223/6
f 191/371/6 158/372/6 159/373/6 180/231/6
f 188/374/6 162/375/6 163/376/6 164/377/6
f 184/378/6 166/379/6 167/380/6 168/381/6
f 166/379/6 183/96/6 169/220/6 167/380/6
f 136/382/6 184/378/6 168/381/6 137/136/6
f 120/351/6 121/383/6 184/378/6 136/382/6
f 121/383/6 175/152/6 166/379/6 184/378/6
f 168/381/6 167/380/6 182/384/6 185/385/6
f 173/223/6 157/200/6 181/386/6 186/387/6
f 162/375/6 187/388/6 165/389/6 163/376/6
f 133/366/6 132/348/6 187/388/6 162/375/6
f 132/348/6 111/347/6 176/390/6 187/388/6
f 130/368/6 188/374/6 164/377/6 131/369/6
f 116/391/6 117/367/6 188/374/6 130/368/6
f 117/367/6 133/366/6 162/375/6 188/374/6
f 114/343/6 189/216/6 112/392/6 113/108/6
f 131/369/6 164/377/6 189/216/6 114/343/6
f 164/377/6 163/376/6 161/393/6 189/216/6
f 158/372/6 190/28/6 160/144/6 159/373/6
f 123/394/6 122/344/6 190/28/6 158/372/6
f 122/344/6 113/108/6 177/395/6 190/28/6
f 171/396/6 123/394/6 158/372/6 191/371/6
f 180/231/6 159/373/6 156/246/6 192/235/6
f 128/341/6 108/340/6 124/397/6 193/184/6
f 178/47/6 116/391/6 130/368/6 194/55/6
f 115/71/6 195/364/6 117/367/6 116/391/6
f 107/339/6 196/156/6 109/398/6 108/340/6
f 146/358/6 197/361/6 149/116/6 147/359/6
f 126/7/6 198/357/6 148/360/6 127/399/6
f 110/346/6 199/4/6 118/400/6 111/347/6
f 127/399/6 148/360/6 199/4/6 110/346/6
f 148/360/6 147/359/6 179/401/6 199/4/6
f 134/362/6 200/228/6 145/402/6 135/363/6
f 138/352/6 120/351/6 136/382/6 201/104/6
f 141/354/6 202/403/6 144/404/6 142/355/6
f 124/397/6 203/353/6 143/356/6 125/20/6
f 108/340/6 109/398/6 203/353/6 124/397/6
f 109/398/6 172/196/6 141/354/6 203/353/6
f 143/356/6 142/355/6 140/405/6 204/192/6
f 119/350/6 205/64/6 121/383/6 120/351/6
f 140/405/6 206/349/6 138/352/6 139/52/6
f 142/355/6 144/404/6 206/349/6 140/405/6
f 144/404/6 174/132/6 119/350/6 206/349/6
f 147/359/6 149/116/6 207/406/6 179/401/6
f 150/365/6 208/345/6 132/348/6 133/366/6
f 152/407/6 151/408/6 208/345/6 150/365/6
f 151/408/6 127/399/6 110/346/6 208/345/6
f 153/35/6 209/342/6 122/344/6 123/394/6
f 155/187/6 154/370/6 209/342/6 153/35/6
f 154/370/6 131/369/6 114/343/6 209/342/6
f 159/373/6 160/144/6 210/409/6 156/246/6
f 161/393/6 211/338/6 128/341/6 129/140/6
f 163/376/6 165/389/6 211/338/6 161/393/6
f 165/389/6 170/164/6 107/339/6 211/338/6
f 167/380/6 169/220/6 212/410/6 182/384/6
f 52/411/2 49/412/2 168/413/2 185/385/2
f 54/414/1 47/415/1 165/416/1 187/388/1
f 26/260/3 8/337/3 129/417/3 128/418/3
f 1/419/1 24/420/1 176/421/1 111/347/1
f 15/422/4 42/423/4 154/424/4 155/425/4
f 27/317/3 56/316/3 190/426/3 177/427/3
f 65/428/1 35/429/1 144/430/1 202/403/1
f 94/210/3 52/304/3 185/431/3 182/211/3
f 49/301/3 11/307/3 137/432/3 168/433/3
f 44/434/2 57/435/2 191/371/2 180/436/2
f 37/90/3 63/322/3 199/437/3 179/91/3
f 89/438/2 76/439/2 152/407/2 150/440/2
f 57/441/2 17/442/2 171/396/2 191/443/2
f 33/444/4 65/445/4 202/446/4 141/447/4
f 24/312/3 54/311/3 187/448/3 176/449/3

BIN
media/pickaxe.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 B

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

5
src/cmake_config.h.in Normal file
View File

@ -0,0 +1,5 @@
// Template for cmake_config.h
#define D_ABOUT_LINK_URL "@PROJECT_LINK_URL@"
#define D_ABOUT_LINK_TEXT "@PROJECT_LINK_TEXT@"
#define D_VERSION "@VERSION_STRING@"

82
src/config.cpp Normal file
View File

@ -0,0 +1,82 @@
#include <fstream>
#include <stdlib.h>
#include "config.h"
Vector::Vector(const std::string &str)
{
sscanf(str.c_str(), "%f,%f,%f", &x, &y, &z);
}
bool Config::load()
{
std::ifstream file(filename.c_str());
if (!file)
return false;
std::string line;
while (std::getline(file, line))
{
auto index = line.find("=");
std::string key = line.substr(0, index);
std::string value = line.substr(index + 1);
config[key] = value;
}
file.close();
return true;
}
bool Config::save()
{
std::ofstream file(filename.c_str());
if (!file)
return false;
for(std::map<std::string, std::string>::iterator it = config.begin();
it != config.end(); it++)
{
file << it->first << "=" << it->second << "\n";
}
file.close();
return true;
}
bool Config::hasKey(const std::string &key) const
{
return config.find(key) != config.end();
}
void Config::set(const std::string &key, const std::string &value)
{
config[key] = value;
}
const std::string &Config::get(const std::string &key) const
{
return config.find(key)->second;
}
const char *Config::getCStr(const std::string &key) const
{
return get(key).c_str();
}
int Config::getInt(const std::string &key) const
{
return atoi(getCStr(key));
}
int Config::getHex(const std::string &key) const
{
return std::stoul(get(key), nullptr, 16);
}
bool Config::getBool(const std::string &key) const
{
return get(key) == "true";
}
Vector Config::getVector(const std::string &key) const
{
return Vector(get(key));
}

37
src/config.h Normal file
View File

@ -0,0 +1,37 @@
#ifndef D_CONFIG_H
#define D_CONFIG_H
#include <map>
class Vector
{
public:
Vector() : x(0), y(0), z(0) {}
Vector(float x, float y, float z) : x(x), y(y), z(z) {}
Vector(const std::string &str);
float x;
float y;
float z;
};
class Config
{
public:
Config(const std::string &filename) : filename(filename) {}
bool load();
bool save();
bool hasKey(const std::string &key) const;
void set(const std::string &key, const std::string &value);
const std::string &get(const std::string &key) const;
const char *getCStr(const std::string &key) const;
int getInt(const std::string &key) const;
int getHex(const std::string &key) const;
bool getBool(const std::string &key) const;
Vector getVector(const std::string &key) const;
private:
std::map<std::string, std::string> config;
std::string filename;
};
#endif // D_CONFIG_H

492
src/dialog.cpp Normal file
View File

@ -0,0 +1,492 @@
#include <stdlib.h>
#include <iostream>
#include <irrlicht.h>
#ifdef USE_CMAKE_CONFIG_H
#include "cmake_config.h"
#else
#define D_ABOUT_LINK_URL "https://github.com/stujones11/SAM-Viewer"
#define D_ABOUT_LINK_TEXT "github.com/stujones11/SAM-Viewer"
#define D_VERSION "0.0.0"
#endif
#include "config.h"
#include "scene.h"
#include "dialog.h"
static inline void open_url(std::string url)
{
system((std::string("xdg-open \"") + url + std::string("\"")).c_str());
}
HyperlinkCtrl::HyperlinkCtrl(IGUIEnvironment *env, IGUIElement *parent, s32 id,
const rect<s32> &rectangle, const wchar_t *title, std::string url) :
IGUIElement(EGUIET_ELEMENT, env, parent, id, rectangle),
url(url),
is_active(false)
{
IGUIStaticText *text = env->addStaticText(title,
rect<s32>(0,0,rectangle.getWidth(),20), false, false, this);
text->setOverrideColor(SColor(255,0,0,255));
text->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER);
}
void HyperlinkCtrl::draw()
{
if (is_active)
{
IVideoDriver *driver = Environment->getVideoDriver();
rect<s32> pos = getAbsolutePosition();
vector2di end = pos.LowerRightCorner;
vector2di start = end - vector2di(pos.getWidth(), 0);
driver->draw2DLine(start, end, SColor(255,0,0,255));
}
IGUIElement::draw();
}
bool HyperlinkCtrl::OnEvent(const SEvent &event)
{
if (event.EventType == EET_GUI_EVENT)
{
if (event.GUIEvent.EventType == EGET_ELEMENT_HOVERED)
is_active = true;
else if (event.GUIEvent.EventType == EGET_ELEMENT_LEFT)
is_active = false;
}
else if (is_active && event.EventType == EET_MOUSE_INPUT_EVENT &&
event.MouseInput.Event == EMIE_LMOUSE_PRESSED_DOWN)
{
open_url(url);
}
return IGUIElement::OnEvent(event);
}
static inline bool isValidHexString(std::string hex)
{
return (hex.length() == 6 &&
hex.find_first_not_of("0123456789abcdefABCDEF") == std::string::npos);
}
ColorCtrl::ColorCtrl(IGUIEnvironment *env, IGUIElement *parent, s32 id,
const rect<s32> &rectangle, const wchar_t *label) :
IGUIElement(EGUIET_ELEMENT, env, parent, id, rectangle)
{
IVideoDriver *driver = env->getVideoDriver();
IGUIStaticText *text = env->addStaticText(label, rect<s32>(0,0,160,20),
false, false, this);
IGUIEditBox *edit = env->addEditBox(L"", rect<s32>(180,0,250,20), true,
this, E_DIALOG_ID_COLOR_EDIT);
edit->setMax(6);
edit->setToolTipText(L"Hex color string RRGGBB");
ITexture *texture = driver->findTexture("color_preview");
if (!texture)
{
IImage *image = driver->createImage(ECF_A8R8G8B8, dimension2du(30,20));
image->fill(SColor(255,255,255,255));
texture = driver->addTexture("color_preview", image);
image->drop();
}
IGUIImage *preview = env->addImage(rect<s32>(270,0,300,20), this,
E_DIALOG_ID_COLOR_PREVIEW);
preview->setImage(texture);
}
void ColorCtrl::setColor(const std::string &hex)
{
if (!isValidHexString(hex))
return;
stringw text = hex.c_str();
IGUIEditBox *edit = (IGUIEditBox*)
getElementFromId(E_DIALOG_ID_COLOR_EDIT);
if (edit)
edit->setText(text.c_str());
IGUIImage *preview = (IGUIImage*)
getElementFromId(E_DIALOG_ID_COLOR_PREVIEW);
if (preview)
{
SColor color;
color.color = std::stoul(hex, nullptr, 16);
color.setAlpha(255);
preview->setColor(color);
}
}
std::string ColorCtrl::getColor() const
{
std::string hex = "";
IGUIEditBox *edit = (IGUIEditBox*)
getElementFromId(E_DIALOG_ID_COLOR_EDIT);
if (edit)
hex = stringc(edit->getText()).c_str();
return hex;
}
bool ColorCtrl::OnEvent(const SEvent &event)
{
if (event.EventType == EET_GUI_EVENT &&
event.GUIEvent.EventType == EGET_EDITBOX_CHANGED &&
event.GUIEvent.Caller->getID() == E_DIALOG_ID_COLOR_EDIT)
{
IGUIEditBox *edit = (IGUIEditBox*)event.GUIEvent.Caller;
std::string hex = stringc(edit->getText()).c_str();
setColor(hex);
}
return IGUIElement::OnEvent(event);
}
AboutDialog::AboutDialog(IGUIEnvironment *env, IGUIElement *parent,
s32 id, const rect<s32> &rectangle) :
IGUIElement(EGUIET_ELEMENT, env, parent, id, rectangle)
{
IVideoDriver *driver = env->getVideoDriver();
ITexture *icon = driver->findTexture("sam_icon_128.png");
if (!icon)
icon = driver->getTexture("sam_icon_128.png");
if (icon)
{
IGUIImage *image = env->addImage(rect<s32>(86,10,214,138), this);
image->setImage(icon);
}
ITexture *title = driver->findTexture("title.png");
if (!title)
title = driver->getTexture("title.png");
if (title)
{
IGUIImage *image = env->addImage(rect<s32>(50,140,250,170), this);
image->setImage(title);
}
stringw desc = stringw("Skin & Model Viewer - Version ") + D_VERSION;
IGUIStaticText *text;
text = env->addStaticText(desc.c_str(), rect<s32>(20,175,280,195),
false, false, this);
text->setTextAlignment(EGUIA_CENTER, EGUIA_CENTER);
HyperlinkCtrl *link = new HyperlinkCtrl(env, this,
E_DIALOG_ID_ABOUT_LINK, rect<s32>(32,200,268,216),
stringw(D_ABOUT_LINK_TEXT).c_str(), D_ABOUT_LINK_URL);
link->drop();
IGUIButton *button = env->addButton(rect<s32>(110,235,190,265), this,
E_DIALOG_ID_ABOUT_OK, L"OK");
}
SettingsDialog::SettingsDialog(IGUIEnvironment *env, IGUIElement *parent,
s32 id, const rect<s32> &rectangle, Config *conf) :
IGUIElement(EGUIET_ELEMENT, env, parent, id, rectangle),
conf(conf)
{
IGUITabControl *tabs = env->addTabControl(rect<s32>(2,2,398,250),
this, true, true);
IGUITab *tab_general = tabs->addTab(L"General");
IGUITab *tab_debug = tabs->addTab(L"Debug");
IGUIStaticText *text;
IGUIEditBox *edit;
IGUISpinBox *spin;
IGUICheckBox *check;
IGUIButton *button;
ColorCtrl *color;
color = new ColorCtrl(env, tab_general, E_DIALOG_ID_BG_COLOR,
rect<s32>(20,20,320,40), L"Background Color:");
color->setColor(conf->get("bg_color"));
color->drop();
color = new ColorCtrl(env, tab_general, E_DIALOG_ID_GRID_COLOR,
rect<s32>(20,50,320,70), L"Grid Color:");
color->setColor(conf->get("grid_color"));
color->drop();
text = env->addStaticText(L"Wield Attachment Bone:", rect<s32>(20,80,180,100),
false, false, tab_general, -1);
stringw bone_name = conf->getCStr("wield_bone");
edit = env->addEditBox(bone_name.c_str(), rect<s32>(200,80,320,100),
true, tab_general, E_DIALOG_ID_WIELD_BONE);
text = env->addStaticText(L"Default Screen Width:",
rect<s32>(20,110,180,130), false, false, tab_general, -1);
spin = env->addSpinBox(L"", rect<s32>(200,110,270,130),
true, tab_general, E_DIALOG_ID_SCREEN_WIDTH);
spin->setValue(conf->getInt("screen_width"));
spin->setDecimalPlaces(0);
text = env->addStaticText(L"Default Screen Height:",
rect<s32>(20,140,180,160), false, false, tab_general, -1);
spin = env->addSpinBox(L"", rect<s32>(200,140,270,160),
true, tab_general, E_DIALOG_ID_SCREEN_HEIGHT);
spin->setValue(conf->getInt("screen_height"));
spin->setDecimalPlaces(0);
check = env->addCheckBox(false, rect<s32>(20,20,380,40), tab_debug,
E_DIALOG_ID_DEBUG_BBOX, L"Show bounding boxes");
check->setChecked(conf->getInt("debug_flags") & EDS_BBOX);
check = env->addCheckBox(false, rect<s32>(20,50,380,70), tab_debug,
E_DIALOG_ID_DEBUG_NORMALS, L"Show vertex normals");
check->setChecked(conf->getInt("debug_flags") & EDS_NORMALS);
check = env->addCheckBox(false, rect<s32>(20,80,380,100), tab_debug,
E_DIALOG_ID_DEBUG_SKELETON, L"Show skeleton");
check->setChecked(conf->getInt("debug_flags") & EDS_SKELETON);
check = env->addCheckBox(false, rect<s32>(20,110,380,130), tab_debug,
E_DIALOG_ID_DEBUG_WIREFRANE, L"Wireframe overaly");
check->setChecked(conf->getInt("debug_flags") & EDS_MESH_WIRE_OVERLAY);
check = env->addCheckBox(false, rect<s32>(20,140,380,160), tab_debug,
E_DIALOG_ID_DEBUG_ALPHA, L"Use transparent material");
check->setChecked(conf->getInt("debug_flags") & EDS_HALF_TRANSPARENCY);
check = env->addCheckBox(false, rect<s32>(20,170,380,190), tab_debug,
E_DIALOG_ID_DEBUG_BUFFERS, L"Show all mesh buffers");
check->setChecked(conf->getInt("debug_flags") & EDS_BBOX_BUFFERS);
button = env->addButton(rect<s32>(315,255,395,285), this,
E_DIALOG_ID_SETTINGS_OK, L"OK");
button = env->addButton(rect<s32>(230,255,310,285), this,
E_DIALOG_ID_SETTINGS_CANCEL, L"Cancel");
}
bool SettingsDialog::isBoxChecked(s32 id) const
{
IGUICheckBox *check = (IGUICheckBox*)getElementFromId(id, true);
if (check)
return check->isChecked();
return false;
}
bool SettingsDialog::OnEvent(const SEvent &event)
{
if (event.EventType == EET_GUI_EVENT &&
event.GUIEvent.EventType == EGET_BUTTON_CLICKED &&
event.GUIEvent.Caller->getID() == E_DIALOG_ID_SETTINGS_OK)
{
IGUIEditBox *edit;
IGUISpinBox *spin;
ColorCtrl *color;
color = (ColorCtrl*)getElementFromId(E_DIALOG_ID_BG_COLOR, true);
if (color)
{
const std::string hex = color->getColor();
if (isValidHexString(hex))
conf->set("bg_color", hex);
}
color = (ColorCtrl*)getElementFromId(E_DIALOG_ID_GRID_COLOR, true);
if (color)
{
const std::string hex = color->getColor();
if (isValidHexString(hex))
conf->set("grid_color", hex);
}
edit = (IGUIEditBox*)
getElementFromId(E_DIALOG_ID_WIELD_BONE, true);
std::string bone = stringc(edit->getText()).c_str();
conf->set("wield_bone", bone);
spin = (IGUISpinBox*)
getElementFromId(E_DIALOG_ID_SCREEN_WIDTH, true);
u32 width = spin->getValue();
conf->set("screen_width", std::to_string(width));
spin = (IGUISpinBox*)
getElementFromId(E_DIALOG_ID_SCREEN_HEIGHT, true);
u32 height = spin->getValue();
conf->set("screen_height", std::to_string(height));
u32 flags = 0;
if (isBoxChecked(E_DIALOG_ID_DEBUG_BBOX))
flags |= EDS_BBOX;
if (isBoxChecked(E_DIALOG_ID_DEBUG_NORMALS))
flags |= EDS_NORMALS;
if (isBoxChecked(E_DIALOG_ID_DEBUG_SKELETON))
flags |= EDS_SKELETON;
if (isBoxChecked(E_DIALOG_ID_DEBUG_WIREFRANE))
flags |= EDS_MESH_WIRE_OVERLAY;
if (isBoxChecked(E_DIALOG_ID_DEBUG_ALPHA))
flags |= EDS_HALF_TRANSPARENCY;
if (isBoxChecked(E_DIALOG_ID_DEBUG_BUFFERS))
flags |= EDS_BBOX_BUFFERS;
conf->set("debug_flags", std::to_string(flags));
}
return IGUIElement::OnEvent(event);
}
TexturesDialog::TexturesDialog(IGUIEnvironment *env, IGUIElement *parent,
s32 id, const rect<s32> &rectangle, Config *conf, ISceneManager *smgr) :
IGUIElement(EGUIET_ELEMENT, env, parent, id, rectangle),
conf(conf),
smgr(smgr)
{
IGUITabControl *tabs = env->addTabControl(rect<s32>(2,2,398,250), this,
true, true);
IGUITab *tab_model = tabs->addTab(L"Model");
IGUITab *tab_wield = tabs->addTab(L"Wield");
IGUIStaticText *text;
IGUIEditBox *edit;
IGUIButton *button;
stringw fn;
std::string key;
ITexture *image = getTexture("browse.png");
ISceneNode *model = smgr->getSceneNodeFromId(E_SCENE_ID_MODEL);
ISceneNode *wield = smgr->getSceneNodeFromId(E_SCENE_ID_WIELD);
u32 mc_model = (model) ? model->getMaterialCount() : 0;
u32 mc_wield = (wield) ? wield->getMaterialCount() : 0;
for (s32 i = 0; i < 6; ++i)
{
s32 top = i * 30 + 20;
stringw num = stringw(i + 1);
key = "model_texture_" + std::to_string(i + 1);
fn = conf->getCStr(key);
text = env->addStaticText(num.c_str(), rect<s32>(15,top,25,top+20),
false, false, tab_model, -1);
edit = env->addEditBox(fn.c_str(), rect<s32>(35,top,350,top+20),
true, tab_model, E_TEXTURE_ID_MODEL + i);
edit->setEnabled(i < mc_model);
edit->setOverrideColor(SColor(255,255,0,0));
edit->enableOverrideColor(false);
button = env->addButton(rect<s32>(360,top,380,top+20), tab_model,
E_BUTTON_ID_MODEL + i);
button->setToolTipText(L"Browse");
if (image)
{
button->setImage(image);
button->setUseAlphaChannel(true);
button->setDrawBorder(false);
}
button->setEnabled(i < mc_model);
key = "wield_texture_" + std::to_string(i + 1);
fn = conf->getCStr(key);
text = env->addStaticText(num.c_str(), rect<s32>(15,top,25,top+20),
false, false, tab_wield, -1);
edit = env->addEditBox(fn.c_str(), rect<s32>(35,top,350,top+20),
true, tab_wield, E_TEXTURE_ID_WIELD + i);
edit->setEnabled(i < mc_wield);
edit->setOverrideColor(SColor(255,255,0,0));
edit->enableOverrideColor(false);
button = env->addButton(rect<s32>(360,top,380,top+20), tab_wield,
E_BUTTON_ID_WIELD + i);
if (image)
{
button->setImage(image);
button->setUseAlphaChannel(true);
button->setDrawBorder(false);
}
button->setEnabled(i < mc_wield);
}
button = env->addButton(rect<s32>(315,255,395,285), this,
E_DIALOG_ID_TEXTURES_OK, L"OK");
button = env->addButton(rect<s32>(230,255,310,285), this,
E_DIALOG_ID_TEXTURES_CANCEL, L"Cancel");
}
ITexture *TexturesDialog::getTexture(const io::path &filename)
{
IVideoDriver *driver = Environment->getVideoDriver();
ITexture *texture = driver->findTexture(filename);
if (!texture)
texture = driver->getTexture(filename);
return texture;
}
bool TexturesDialog::OnEvent(const SEvent &event)
{
if (event.EventType == EET_GUI_EVENT)
{
s32 id = event.GUIEvent.Caller->getID();
if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
{
if (event.GUIEvent.Caller->getType() == EGUIET_EDIT_BOX)
{
IGUIEditBox *edit = (IGUIEditBox*)event.GUIEvent.Caller;
if (edit)
{
stringc fn = stringc(edit->getText()).c_str();
edit->enableOverrideColor(!(getTexture(fn)));
}
}
}
else if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
{
if (id == E_DIALOG_ID_TEXTURES_OK)
{
ISceneNode *model = smgr->getSceneNodeFromId(E_SCENE_ID_MODEL);
ISceneNode *wield = smgr->getSceneNodeFromId(E_SCENE_ID_WIELD);
IGUIEditBox *edit;
for (s32 i = 0; i < 6; ++i)
{
std::string idx = std::to_string(i + 1);
edit = (IGUIEditBox*)
getElementFromId(E_TEXTURE_ID_MODEL + i, true);
if (edit && model && i < model->getMaterialCount())
{
stringc fn = stringc(edit->getText()).c_str();
ITexture *texture = getTexture(fn);
if (texture)
{
std::string key = "model_texture_" + idx;
conf->set(key, fn.c_str());
SMaterial &material = model->getMaterial(i);
material.TextureLayer[0].Texture = texture;
}
}
edit = (IGUIEditBox*)
getElementFromId(E_TEXTURE_ID_WIELD + i, true);
if (edit && wield && i < wield->getMaterialCount())
{
stringc fn = stringc(edit->getText()).c_str();
ITexture *texture = getTexture(fn);
if (texture)
{
std::string key = "wield_texture_" + idx;
conf->set(key, fn.c_str());
SMaterial &material = wield->getMaterial(i);
material.TextureLayer[0].Texture = texture;
}
}
}
}
else
{
for (s32 i = 0; i < 6; ++i)
{
if (id == E_BUTTON_ID_MODEL + i)
{
Environment->addFileOpenDialog(L"Open Image File",
true, this, E_TEXTURE_ID_MODEL + i);
break;
}
else if (id == E_BUTTON_ID_WIELD + i)
{
Environment->addFileOpenDialog(L"Open Image File",
true, this, E_TEXTURE_ID_WIELD + i);
break;
}
}
}
}
else if (event.GUIEvent.EventType == EGET_FILE_SELECTED)
{
IGUIFileOpenDialog *dialog =
(IGUIFileOpenDialog*)event.GUIEvent.Caller;
stringw fn = stringw(dialog->getFileName());
if (!fn.empty())
{
s32 id = dialog->getID();
IGUIEditBox *edit = (IGUIEditBox*)getElementFromId(id, true);
if (edit)
{
edit->setText(fn.c_str());
edit->enableOverrideColor(!(getTexture(fn)));
}
}
}
}
return IGUIElement::OnEvent(event);
}

109
src/dialog.h Normal file
View File

@ -0,0 +1,109 @@
#ifndef D_DIALOG_H
#define D_DIALOG_H
using namespace irr;
using namespace core;
using namespace scene;
using namespace gui;
using namespace video;
enum
{
E_DIALOG_ID_ABOUT = 0x1000,
E_DIALOG_ID_SETTINGS,
E_DIALOG_ID_BG_COLOR,
E_DIALOG_ID_GRID_COLOR,
E_DIALOG_ID_COLOR_EDIT,
E_DIALOG_ID_COLOR_PREVIEW,
E_DIALOG_ID_WIELD_BONE,
E_DIALOG_ID_SCREEN_WIDTH,
E_DIALOG_ID_SCREEN_HEIGHT,
E_DIALOG_ID_DEBUG_BBOX,
E_DIALOG_ID_DEBUG_NORMALS,
E_DIALOG_ID_DEBUG_SKELETON,
E_DIALOG_ID_DEBUG_WIREFRANE,
E_DIALOG_ID_DEBUG_ALPHA,
E_DIALOG_ID_DEBUG_BUFFERS,
E_DIALOG_ID_ABOUT_OK,
E_DIALOG_ID_ABOUT_LINK,
E_DIALOG_ID_SETTINGS_OK,
E_DIALOG_ID_SETTINGS_CANCEL,
E_DIALOG_ID_TEXTURES,
E_DIALOG_ID_TEXTURES_OK,
E_DIALOG_ID_TEXTURES_CANCEL
};
enum
{
E_TEXTURE_ID_MODEL = 0x2000,
E_TEXTURE_ID_WIELD = 0x2010,
E_BUTTON_ID_MODEL = 0x2020,
E_BUTTON_ID_WIELD = 0x2030
};
class Config;
class HyperlinkCtrl : public IGUIElement
{
public:
HyperlinkCtrl(IGUIEnvironment *env, IGUIElement *parent, s32 id,
const rect<s32> &rectangle, const wchar_t *title, std::string url);
virtual ~HyperlinkCtrl() {}
virtual void draw();
virtual bool OnEvent(const SEvent &event);
private:
std::string url;
bool is_active;
};
class ColorCtrl : public IGUIElement
{
public:
ColorCtrl(IGUIEnvironment *env, IGUIElement *parent, s32 id,
const rect<s32> &rectangle, const wchar_t *label);
virtual ~ColorCtrl() {}
virtual bool OnEvent(const SEvent &event);
void setColor(const std::string &hex);
std::string getColor() const;
};
class AboutDialog : public IGUIElement
{
public:
AboutDialog(IGUIEnvironment *env, IGUIElement *parent, s32 id,
const rect<s32> &rectangle);
virtual ~AboutDialog() {}
};
class SettingsDialog : public IGUIElement
{
public:
SettingsDialog(IGUIEnvironment *env, IGUIElement *parent, s32 id,
const rect<s32> &rectangle, Config *conf);
virtual ~SettingsDialog() {}
virtual bool OnEvent(const SEvent &event);
private:
bool isBoxChecked(s32 id) const;
void colorFromHexStr(const std::string &hex);
Config *conf;
};
class TexturesDialog : public IGUIElement
{
public:
TexturesDialog(IGUIEnvironment *env, IGUIElement *parent, s32 id,
const rect<s32> &rectangle, Config *conf, ISceneManager *smgr);
virtual ~TexturesDialog() {}
virtual bool OnEvent(const SEvent &event);
private:
ITexture *getTexture(const io::path &filename);
Config *conf;
ISceneManager *smgr;
};
#endif // D_DIALOG_H

573
src/gui.cpp Normal file
View File

@ -0,0 +1,573 @@
#include <stdlib.h>
#include <iostream>
#include <irrlicht.h>
#include "config.h"
#include "scene.h"
#include "dialog.h"
#include "gui.h"
VertexCtrl::VertexCtrl(IGUIEnvironment *env, IGUIElement *parent, s32 id,
const rect<s32> &rectangle, f32 step, const wchar_t *label) :
IGUIElement(EGUIET_ELEMENT, env, parent, id, rectangle),
vertex(0)
{
IGUIStaticText *text = env->addStaticText(label,
rect<s32>(0,0,20,20), false, false, this);
IGUISpinBox *spin = env->addSpinBox(L"", rect<s32>(20,0,120,20),
true, this, E_GUI_ID_VERTEX);
spin->setDecimalPlaces(2);
spin->setValue(0);
spin->setStepSize(step);
spin->setRange(-1000, 1000);
}
void VertexCtrl::setValue(const f32 &value)
{
IGUISpinBox *spin = (IGUISpinBox*)getElementFromId(E_GUI_ID_VERTEX);
if (spin)
{
spin->setValue(value);
vertex = value;
}
}
bool VertexCtrl::OnEvent(const SEvent &event)
{
if (event.EventType == EET_GUI_EVENT)
{
if (event.GUIEvent.EventType == EGET_SPINBOX_CHANGED)
{
IGUISpinBox *spin = (IGUISpinBox*)event.GUIEvent.Caller;
if (spin)
vertex = spin->getValue();
}
}
else if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
{
setValue(vertex);
}
return IGUIElement::OnEvent(event);
}
VectorCtrl::VectorCtrl(IGUIEnvironment *env, IGUIElement *parent, s32 id,
const rect<s32> &rectangle, f32 step, const wchar_t *label) :
IGUIElement(EGUIET_ELEMENT, env, parent, id, rectangle),
vector(vector3df(0,0,0))
{
IGUIStaticText *text = env->addStaticText(label,
rect<s32>(10,0,150,20), false, false, this);
VertexCtrl *x = new VertexCtrl(env, this, E_GUI_ID_VECTOR_X,
rect<s32>(10,30,150,50), step, L"X");
x->drop();
VertexCtrl *y = new VertexCtrl(env, this, E_GUI_ID_VECTOR_Y,
rect<s32>(10,60,150,80), step, L"Y");
y->drop();
VertexCtrl *z = new VertexCtrl(env, this, E_GUI_ID_VECTOR_Z,
rect<s32>(10,90,150,110), step, L"Z");
z->drop();
}
void VectorCtrl::setVector(const vector3df &vec)
{
vector = vec;
VertexCtrl *vertex;
vertex = (VertexCtrl*)getElementFromId(E_GUI_ID_VECTOR_X);
if (vertex)
vertex->setValue(vector.X);
vertex = (VertexCtrl*)getElementFromId(E_GUI_ID_VECTOR_Y);
if (vertex)
vertex->setValue(vector.Y);
vertex = (VertexCtrl*)getElementFromId(E_GUI_ID_VECTOR_Z);
if (vertex)
vertex->setValue(vector.Z);
}
bool VectorCtrl::OnEvent(const SEvent &event)
{
if (event.EventType == EET_GUI_EVENT &&
event.GUIEvent.EventType == EGET_SPINBOX_CHANGED)
{
VertexCtrl *vertex = (VertexCtrl*)event.GUIEvent.Caller->getParent();
if (vertex)
{
switch (vertex->getID())
{
case E_GUI_ID_VECTOR_X:
vector.X = vertex->getValue();
break;
case E_GUI_ID_VECTOR_Y:
vector.Y = vertex->getValue();
break;
case E_GUI_ID_VECTOR_Z:
vector.Z = vertex->getValue();
break;
default:
break;
}
SEvent new_event = event;
new_event.GUIEvent.Caller = this;
return IGUIElement::OnEvent(new_event);
}
}
return IGUIElement::OnEvent(event);
}
AnimCtrl::AnimCtrl(IGUIEnvironment *env, IGUIElement *parent, s32 id,
const rect<s32> &rectangle) :
IGUIElement(EGUIET_ELEMENT, env, parent, id, rectangle),
button_id(E_GUI_ID_PAUSE)
{
IVideoDriver *driver = env->getVideoDriver();
ITexture *image;
IGUIButton *button;
image = driver->getTexture("skip_rev.png");
button = env->addButton(rect<s32>(0,4,23,27), this,
E_GUI_ID_SKIP_REV);
button->setImage(image);
button->setUseAlphaChannel(true);
image = driver->getTexture("play_rev.png");
button = env->addButton(rect<s32>(24,4,47,27), this,
E_GUI_ID_PLAY_REV);
button->setImage(image);
button->setUseAlphaChannel(true);
image = driver->getTexture("pause.png");
button = env->addButton(rect<s32>(48,4,71,27), this,
E_GUI_ID_PAUSE);
button->setImage(image);
button->setUseAlphaChannel(true);
image = driver->getTexture("play_fwd.png");
button = env->addButton(rect<s32>(72,4,95,27), this,
E_GUI_ID_PLAY_FWD);
button->setImage(image);
button->setUseAlphaChannel(true);
image = driver->getTexture("skip_fwd.png");
button = env->addButton(rect<s32>(96,4,119,27), this,
E_GUI_ID_SKIP_FWD);
button->setImage(image);
button->setUseAlphaChannel(true);
}
bool AnimCtrl::OnEvent(const SEvent &event)
{
if (event.EventType == EET_GUI_EVENT)
{
if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
{
reset(true);
IGUIButton *button = (IGUIButton*)event.GUIEvent.Caller;
button->setEnabled(false);
button->setPressed(true);
button_id = button->getID();
}
else if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
{
if (button_id == E_GUI_ID_SKIP_FWD ||
button_id == E_GUI_ID_SKIP_REV)
{
reset(true);
IGUIButton *button = (IGUIButton*)
getElementFromId(E_GUI_ID_PAUSE);
if (button)
button->setPressed(true);
button_id = E_GUI_ID_PAUSE;
}
}
}
return IGUIElement::OnEvent(event);
}
void AnimCtrl::reset(bool enabled)
{
const list<IGUIElement*> &children = getChildren();
list<IGUIElement*>::ConstIterator iter = children.begin();
while (iter != children.end())
{
if ((*iter)->getType() == EGUIET_BUTTON)
{
IGUIButton *button = (IGUIButton*)(*iter);
button->setEnabled(enabled);
button->setPressed(false);
}
++iter;
}
}
ToolBox::ToolBox(IGUIEnvironment *env, IGUIElement *parent, s32 id,
const rect<s32> &rectangle, ISceneNode *node) :
IGUIElement(EGUIET_ELEMENT, env, parent, id, rectangle)
{
smgr = node->getSceneManager();
node_id = node->getID();
IGUIWindow *dialog = (IGUIWindow*)parent;
dialog->setDraggable(false);
VectorCtrl *position = new VectorCtrl(env, this, E_GUI_ID_POSITION,
rect<s32>(10,0,150,120), 1.0, L"Position:");
VectorCtrl *rotation = new VectorCtrl(env, this, E_GUI_ID_ROTATION,
rect<s32>(10,130,150,250), 15.0, L"Rotation:");
IGUIStaticText *text;
text = env->addStaticText(L"Scale:",
rect<s32>(20,260,150,280), false, false, this);
text = env->addStaticText(L"%",
rect<s32>(20,290,40,310), false, false, this);
IGUISpinBox *scale = env->addSpinBox(L"", rect<s32>(40,290,140,310),
true, this, E_GUI_ID_SCALE);
scale->setDecimalPlaces(0);
scale->setStepSize(10.0);
scale->setRange(0, 1000);
position->setVector(node->getPosition());
position->drop();
rotation->setVector(node->getRotation());
rotation->drop();
scale->setValue(node->getScale().Y * 100);
text = env->addStaticText(L"Transparency:",
rect<s32>(20,330,150,350), false, false, this);
IGUIComboBox *combo = env->addComboBox(rect<s32>(20,360,140,380),
this, E_GUI_ID_MATERIAL);
combo->addItem(L"Opaque");
combo->addItem(L"Alpha Channel");
combo->addItem(L"Alpha Test");
switch (node->getMaterial(0).MaterialType)
{
case EMT_TRANSPARENT_ALPHA_CHANNEL:
combo->setSelected(1);
break;
case EMT_TRANSPARENT_ALPHA_CHANNEL_REF:
combo->setSelected(2);
break;
default:
break;
}
}
bool ToolBox::OnEvent(const SEvent &event)
{
if (event.EventType == EET_GUI_EVENT)
{
s32 id = event.GUIEvent.Caller->getID();
if (event.GUIEvent.EventType == EGET_SPINBOX_CHANGED)
{
ISceneNode *node = smgr->getSceneNodeFromId(node_id);
if (node)
{
IGUIElement *elem = (IGUIElement*)event.GUIEvent.Caller;
switch(id)
{
case E_GUI_ID_POSITION:
{
VectorCtrl *position = (VectorCtrl*)elem;
node->setPosition(position->getVector());
break;
}
case E_GUI_ID_ROTATION:
{
VectorCtrl *rotation = (VectorCtrl*)elem;
node->setRotation(rotation->getVector());
break;
}
case E_GUI_ID_SCALE:
{
IGUISpinBox *spin = (IGUISpinBox*)elem;
f32 s = spin->getValue() / 100;
node->setScale(vector3df(s,s,s));
break;
}
default:
break;
}
}
}
else if(event.GUIEvent.EventType == EGET_COMBO_BOX_CHANGED)
{
ISceneNode *node = smgr->getSceneNodeFromId(node_id);
if (node)
{
IGUIComboBox *combo = (IGUIComboBox*)event.GUIEvent.Caller;
switch (combo->getSelected())
{
case 0:
node->setMaterialType(EMT_SOLID);
break;
case 1:
node->setMaterialType(EMT_TRANSPARENT_ALPHA_CHANNEL);
break;
case 2:
node->setMaterialType(EMT_TRANSPARENT_ALPHA_CHANNEL_REF);
break;
}
}
}
}
return IGUIElement::OnEvent(event);
}
GUI::GUI(IrrlichtDevice *device, Config *config) :
device(device),
conf(config),
has_focus(false)
{
IGUIEnvironment *env = device->getGUIEnvironment();
IGUISkin *skin = env->getSkin();
IGUIFont *font = env->getFont("fontlucida.png");
if (font)
skin->setFont(font);
skin->setColor(EGDC_3D_FACE, SColor(255,232,232,232));
skin->setColor(EGDC_3D_DARK_SHADOW, SColor(255,160,160,160));
skin->setColor(EGDC_3D_HIGH_LIGHT, SColor(255,248,248,248));
skin->setColor(EGDC_3D_LIGHT, SColor(255,255,255,255));
skin->setColor(EGDC_3D_SHADOW, SColor(255,196,196,196));
skin->setColor(EGDC_ACTIVE_BORDER, SColor(255,232,232,232));
skin->setColor(EGDC_INACTIVE_BORDER, SColor(255,232,232,232));
skin->setColor(EGDC_GRAY_EDITABLE, SColor(255,172,172,172));
skin->setColor(EGDC_GRAY_TEXT, SColor(255,96,96,96));
skin->setColor(EGDC_ACTIVE_CAPTION, SColor(255,16,16,16));
skin->setColor(EGDC_INACTIVE_CAPTION, SColor(255,64,64,64));
for (s32 i=0; i < EGDC_COUNT; ++i)
{
SColor col = skin->getColor((EGUI_DEFAULT_COLOR)i);
col.setAlpha(255);
skin->setColor((EGUI_DEFAULT_COLOR)i, col);
}
}
void GUI::initMenu()
{
IGUIEnvironment *env = device->getGUIEnvironment();
IGUIContextMenu *menu = env->addMenu(0, E_GUI_ID_MENU);
menu->addItem(L"File", -1, true, true);
menu->addItem(L"Edit", -1, true, true);
menu->addItem(L"View", -1, true, true);
menu->addItem(L"Help", -1, true, true);
IGUIContextMenu *submenu;
submenu = menu->getSubMenu(0);
submenu->addItem(L"Load Model Mesh", E_GUI_ID_LOAD_MODEL_MESH);
submenu->addItem(L"Load Wield Mesh", E_GUI_ID_LOAD_WIELD_MESH);
submenu->addSeparator();
submenu->addItem(L"Save Configuration", E_GUI_ID_SAVE_CONFIG);
submenu->addSeparator();
submenu->addItem(L"Quit", E_GUI_ID_QUIT);
submenu = menu->getSubMenu(1);
submenu->addItem(L"Textures", E_GUI_ID_TEXTURES_DIALOG);
submenu->addSeparator();
submenu->addItem(L"Preferences", E_GUI_ID_SETTINGS_DIALOG);
submenu = menu->getSubMenu(2);
submenu->addItem(L"Model Toolbox", E_GUI_ID_TOOLBOX_MODEL, true, false,
false, true);
submenu->addItem(L"Wield Toolbox", E_GUI_ID_TOOLBOX_WIELD, true, false,
false, true);
submenu->addSeparator();
submenu->addItem(L"Show Grid", E_GUI_ID_SHOW_GRID, true, false,
true, true);
submenu->addItem(L"Show Axes", E_GUI_ID_SHOW_AXES, true, false,
true, true);
submenu->addSeparator();
submenu->addItem(L"Projection", -1, true, true);
submenu->addItem(L"Filters", -1, true, true);
submenu->addSeparator();
submenu->addItem(L"Show Wield Item", E_GUI_ID_ENABLE_WIELD, true, false,
conf->getBool("wield_show"), true);
submenu->addItem(L"Backface Culling", E_GUI_ID_BACK_FACE_CULL, true, false,
conf->getBool("backface_cull"), true);
submenu->addSeparator();
submenu->addItem(L"Model Debug Info", E_GUI_ID_DEBUG_INFO, true, false,
conf->getBool("debug_info"), true);
submenu = menu->getSubMenu(2)->getSubMenu(6);
submenu->addItem(L"Perspective", E_GUI_ID_PERSPECTIVE, true, false,
!conf->getBool("ortho"), true);
submenu->addItem(L"Orthogonal", E_GUI_ID_ORTHOGONAL, true, false,
conf->getBool("ortho"), true);
submenu = menu->getSubMenu(2)->getSubMenu(7);
submenu->addItem(L"Bilinear", E_GUI_ID_BILINEAR, true, false,
conf->getBool("bilinear"), true);
submenu->addItem(L"Trilinear", E_GUI_ID_TRILINEAR, true, false,
conf->getBool("trilinear"), true);
submenu->addItem(L"Anisotropic", E_GUI_ID_ANISOTROPIC, true, false,
conf->getBool("anisotropic"), true);
submenu = menu->getSubMenu(3);
submenu->addItem(L"About", E_DIALOG_ID_ABOUT);
}
void GUI::initToolBar()
{
IVideoDriver *driver = device->getVideoDriver();
IGUIEnvironment *env = device->getGUIEnvironment();
IGUIStaticText *text;
IGUISpinBox *spin;
IGUIToolBar *toolbar = env->addToolBar(0, E_GUI_ID_TOOLBAR);
text = env->addStaticText(L"Animation:",
rect<s32>(20,5,120,25), false, false, toolbar);
text = env->addStaticText(L"Start",
rect<s32>(130,5,160,25), false, false, toolbar);
spin = env->addSpinBox(L"", rect<s32>(170,5,230,25),
true, toolbar, E_GUI_ID_ANIM_START);
spin->setDecimalPlaces(0);
spin->setRange(0, 10000);
text = env->addStaticText(L"End",
rect<s32>(255,5,280,25), false, false, toolbar);
spin = env->addSpinBox(L"", rect<s32>(290,5,350,25),
true, toolbar, E_GUI_ID_ANIM_END);
spin->setDecimalPlaces(0);
spin->setRange(0, 10000);
text = env->addStaticText(L"Speed",
rect<s32>(370,5,410,25), false, false, toolbar);
spin = env->addSpinBox(L"", rect<s32>(420,5,480,25),
true, toolbar, E_GUI_ID_ANIM_SPEED);
spin->setDecimalPlaces(0);
spin->setRange(0, 10000);
text = env->addStaticText(L"Frame",
rect<s32>(495,5,535,25), false, false, toolbar);
spin = env->addSpinBox(L"", rect<s32>(550,5,610,25),
true, toolbar, E_GUI_ID_ANIM_FRAME);
spin->setDecimalPlaces(0);
spin->setRange(0, 10000);
s32 w = driver->getScreenSize().Width;
AnimCtrl *anim = new AnimCtrl(env, toolbar, E_GUI_ID_ANIM_CTRL,
rect<s32>(w-120,0,w,30));
anim->drop();
}
void GUI::showToolBox(s32 id)
{
ISceneManager *smgr = device->getSceneManager();
IGUIEnvironment *env = device->getGUIEnvironment();
IGUIElement *root = env->getRootGUIElement();
if (root->getElementFromId(id, true))
return;
switch (id)
{
case E_GUI_ID_TOOLBOX_MODEL:
{
IVideoDriver *driver = device->getVideoDriver();
s32 w = driver->getScreenSize().Width;
ISceneNode *node = smgr->getSceneNodeFromId(E_SCENE_ID_MODEL);
IGUIWindow *window = env->addWindow(rect<s32>(w-160,54,w,490),
false, L"Model Properties", root, id);
ToolBox *toolbox = new ToolBox(env, window, id,
rect<s32>(0,30,160,800), node);
toolbox->drop();
env->setFocus(window);
break;
}
case E_GUI_ID_TOOLBOX_WIELD:
{
ISceneNode *node = smgr->getSceneNodeFromId(E_SCENE_ID_WIELD);
IGUIWindow *window = env->addWindow(rect<s32>(0,54,160,490),
false, L"Wield Properties", root, id);
ToolBox *toolbox = new ToolBox(env, window, id,
rect<s32>(0,30,160,800), node);
toolbox->drop();
env->setFocus(window);
break;
}
default:
break;
}
}
void GUI::closeToolBox(s32 id)
{
IGUIElement *elem = getElement(id);
if (elem)
elem->remove();
}
void GUI::reloadToolBox(s32 id)
{
IGUIElement *elem = getElement(id);
if (elem)
{
elem->remove();
showToolBox(id);
}
}
void GUI::moveElement(s32 id, const vector2di &move)
{
IGUIElement *elem = getElement(id);
if (elem)
{
vector2di pos = elem->getRelativePosition().UpperLeftCorner + move;
elem->setRelativePosition(position2di(pos.X, pos.Y));
}
}
void GUI::showTexturesDialog()
{
IGUIEnvironment *env = device->getGUIEnvironment();
ISceneManager *smgr = device->getSceneManager();
IGUIWindow *window = env->addWindow(getWindowRect(400, 310),
true, L"Textures");
TexturesDialog *dialog = new TexturesDialog(env, window,
E_DIALOG_ID_TEXTURES, rect<s32>(0,20,400,310), conf, smgr);
dialog->drop();
}
void GUI::showSettingsDialog()
{
IGUIEnvironment *env = device->getGUIEnvironment();
IGUIWindow *window = env->addWindow(getWindowRect(400, 310),
true, L"Settings");
SettingsDialog *dialog = new SettingsDialog(env, window,
E_DIALOG_ID_SETTINGS, rect<s32>(0,20,400,310), conf);
dialog->drop();
}
void GUI::showAboutDialog()
{
IGUIEnvironment *env = device->getGUIEnvironment();
IGUIWindow *window = env->addWindow(getWindowRect(300, 300),
true, L"About");
AboutDialog *dialog = new AboutDialog(env, window,
E_DIALOG_ID_ABOUT, rect<s32>(0,20,300,300));
dialog->drop();
}
IGUIElement *GUI::getElement(s32 id)
{
IGUIEnvironment *env = device->getGUIEnvironment();
IGUIElement *root = env->getRootGUIElement();
return root->getElementFromId(id, true);
}
const rect<s32> GUI::getWindowRect(const u32 &width, const u32 &height) const
{
IVideoDriver *driver = device->getVideoDriver();
dimension2du s = driver->getScreenSize();
vector2di pos = vector2di((s.Width - width) / 2, (s.Height - height) / 2);
return rect<s32>(pos, pos + vector2di(width, height));
}

133
src/gui.h Normal file
View File

@ -0,0 +1,133 @@
#ifndef D_GUI_H
#define D_GUI_H
using namespace irr;
using namespace core;
using namespace scene;
using namespace gui;
using namespace video;
enum
{
E_GUI_ID_MENU,
E_GUI_ID_TOOLBAR,
E_GUI_ID_LOAD_MODEL_MESH,
E_GUI_ID_LOAD_WIELD_MESH,
E_GUI_ID_SAVE_CONFIG,
E_GUI_ID_QUIT,
E_GUI_ID_TEXTURES_DIALOG,
E_GUI_ID_SETTINGS_DIALOG,
E_GUI_ID_TOOLBOX_MODEL,
E_GUI_ID_TOOLBOX_WIELD,
E_GUI_ID_SHOW_GRID,
E_GUI_ID_SHOW_AXES,
E_GUI_ID_ENABLE_WIELD,
E_GUI_ID_BACK_FACE_CULL,
E_GUI_ID_ORTHOGONAL,
E_GUI_ID_PERSPECTIVE,
E_GUI_ID_BILINEAR,
E_GUI_ID_TRILINEAR,
E_GUI_ID_ANISOTROPIC,
E_GUI_ID_DEBUG_INFO,
E_GUI_ID_VERTEX,
E_GUI_ID_VECTOR_X,
E_GUI_ID_VECTOR_Y,
E_GUI_ID_VECTOR_Z,
E_GUI_ID_POSITION,
E_GUI_ID_ROTATION,
E_GUI_ID_SCALE,
E_GUI_ID_MATERIAL,
E_GUI_ID_ANIM_CTRL,
E_GUI_ID_ANIM_START,
E_GUI_ID_ANIM_END,
E_GUI_ID_ANIM_FRAME,
E_GUI_ID_ANIM_SPEED,
E_GUI_ID_SKIP_REV,
E_GUI_ID_PLAY_REV,
E_GUI_ID_PAUSE,
E_GUI_ID_PLAY_FWD,
E_GUI_ID_SKIP_FWD
};
class Config;
class VertexCtrl : public IGUIElement
{
public:
VertexCtrl(IGUIEnvironment *env, IGUIElement *parent, s32 id,
const rect<s32> &rectangle, f32 step, const wchar_t *label);
virtual ~VertexCtrl() {}
virtual bool OnEvent(const SEvent &event);
f32 getValue() const { return vertex; }
void setValue(const f32 &value);
private:
f32 vertex;
};
class VectorCtrl : public IGUIElement
{
public:
VectorCtrl(IGUIEnvironment *env, IGUIElement *parent, s32 id,
const rect<s32> &rectangle, f32 step, const wchar_t *label);
virtual ~VectorCtrl() {}
virtual bool OnEvent(const SEvent &event);
vector3df getVector() const { return vector; }
void setVector(const vector3df &vec);
private:
vector3df vector;
};
class AnimCtrl : public IGUIElement
{
public:
AnimCtrl(IGUIEnvironment *env, IGUIElement *parent, s32 id,
const rect<s32> &rectangle);
virtual ~AnimCtrl() {}
virtual bool OnEvent(const SEvent &event);
void reset(bool enabled);
private:
s32 button_id;
};
class ToolBox : public IGUIElement
{
public:
ToolBox(IGUIEnvironment *env, IGUIElement *parent, s32 id,
const rect<s32> &rectangle, ISceneNode *node);
virtual ~ToolBox() {}
virtual bool OnEvent(const SEvent &event);
private:
s32 node_id;
ISceneManager *smgr;
};
class GUI
{
public:
GUI(IrrlichtDevice *device, Config *config);
void initMenu();
void initToolBar();
void showToolBox(s32 id);
void closeToolBox(s32 id);
void reloadToolBox(s32 id);
IGUIElement *getElement(s32 id);
bool getFocused() const { return has_focus; }
void setFocused(const bool &focus) { has_focus = focus; }
void moveElement(s32 id, const vector2di &move);
void showTexturesDialog();
void showSettingsDialog();
void showAboutDialog();
private:
const rect<s32> getWindowRect(const u32 &width, const u32 &height) const;
IrrlichtDevice *device;
Config *conf;
bool has_focus;
};
#endif // D_GUI_H

74
src/main.cpp Normal file
View File

@ -0,0 +1,74 @@
#include <stdlib.h>
#include <iostream>
#include <irrlicht.h>
#include "config.h"
#include "viewer.h"
int main()
{
Config *conf = new Config("../bin/config.ini");
std::map<std::string, std::string> defaults = {
{"model_mesh", "character.b3d"},
{"model_position", "0,-10,0"},
{"model_rotation", "0,0,0"},
{"model_scale", "100"},
{"model_material", "14"},
{"model_texture_1", "character.png"},
{"model_texture_2", "blank.png"},
{"model_texture_3", "blank.png"},
{"model_texture_4", "blank.png"},
{"model_texture_5", "blank.png"},
{"model_texture_6", "blank.png"},
{"wield_mesh", "pickaxe.obj"},
{"wield_position", "0,5,0"},
{"wield_rotation", "0,0,0"},
{"wield_scale", "400"},
{"wield_material", "14"},
{"wield_show", "true"},
{"wield_bone", "Arm_Right"},
{"wield_texture_1", "pickaxe.png"},
{"wield_texture_2", "blank.png"},
{"wield_texture_3", "blank.png"},
{"wield_texture_4", "blank.png"},
{"wield_texture_5", "blank.png"},
{"wield_texture_6", "blank.png"},
{"anim_start", "168"},
{"anim_end", "187"},
{"anim_speed", "15"},
{"ortho", "false"},
{"bilinear", "false"},
{"trilinear", "false"},
{"anisotropic", "false"},
{"backface_cull", "true"},
{"bg_color", "808080"},
{"grid_color", "404040"},
{"screen_width", "800"},
{"screen_height","600"},
{"debug_info", "false"},
{"debug_flags", "1"},
};
conf->load();
for (std::map<std::string, std::string>::iterator it = defaults.begin();
it != defaults.end(); it++)
{
if (!conf->hasKey(it->first))
conf->set(it->first, it->second);
}
conf->save();
u32 width = conf->getInt("screen_width");
u32 height = conf->getInt("screen_height");
IrrlichtDevice *device = createDevice(EDT_OPENGL,
dimension2d<u32>(width, height), 16, false, false, false);
if (device && conf)
{
Viewer *viewer = new Viewer(conf);
viewer->run(device);
device->drop();
delete viewer;
delete conf;
}
return 1;
}

320
src/scene.cpp Normal file
View File

@ -0,0 +1,320 @@
#include <stdlib.h>
#include <iostream>
#include <irrlicht.h>
#include "config.h"
#include "scene.h"
Scene::Scene(ISceneNode *parent, ISceneManager *smgr, s32 id) :
ISceneNode(parent, smgr, id),
conf(0),
show_grid(true),
show_axes(true)
{
material.Lighting = false;
material.MaterialType = EMT_TRANSPARENT_ALPHA_CHANNEL;
material.BackfaceCulling = false;
grid_color = SColor(64,128,128,128);
}
bool Scene::load(Config *config)
{
conf = config;
if (!loadModelMesh(conf->getCStr("model_mesh")))
return false;
setAttachment();
loadWieldMesh(conf->getCStr("wield_mesh"));
setBackFaceCulling(conf->getBool("backface_cull"));
setGridColor(conf->getHex("grid_color"));
return true;
}
bool Scene::loadModelMesh(const io::path &filename)
{
if (!conf)
return false;
IAnimatedMesh *mesh = SceneManager->getMesh(filename);
if (!mesh)
return false;
ISceneNode *wield = getNode(E_SCENE_ID_WIELD);
if (wield)
wield->setParent(this);
ISceneNode *model = getNode(E_SCENE_ID_MODEL);
if (model)
{
model->remove();
model = 0;
}
model = SceneManager->addAnimatedMeshSceneNode(mesh, this,
E_SCENE_ID_MODEL);
if (!model)
return false;
Vector pos = conf->getVector("model_position");
Vector rot = conf->getVector("model_rotation");
f32 s = (f32)conf->getInt("model_scale") / 100;
u32 mat = conf->getInt("model_material");
model->setMaterialFlag(EMF_LIGHTING, false);
model->setPosition(vector3df(pos.x, pos.y, pos.z));
model->setRotation(vector3df(rot.x, rot.y, rot.z));
model->setScale(vector3df(s,s,s));
model->setMaterialType((E_MATERIAL_TYPE)mat);
model->setMaterialFlag(EMF_BILINEAR_FILTER,
conf->getBool("bilinear"));
model->setMaterialFlag(EMF_TRILINEAR_FILTER,
conf->getBool("trilinear"));
model->setMaterialFlag(EMF_ANISOTROPIC_FILTER,
conf->getBool("anisotropic"));
setDebugInfo(conf->getBool("debug_info"));
if (wield)
setAttachment();
loadTextures(model, "model");
return true;
}
bool Scene::loadWieldMesh(const io::path &filename)
{
if (!conf)
return false;
IMesh *mesh = SceneManager->getMesh(filename);
if (!mesh)
return false;
ISceneNode *wield = getNode(E_SCENE_ID_WIELD);
if (wield)
{
wield->remove();
wield = 0;
}
wield = SceneManager->addMeshSceneNode(mesh, this,
E_SCENE_ID_WIELD);
if (!wield)
return false;
Vector pos = conf->getVector("wield_position");
Vector rot = conf->getVector("wield_rotation");
f32 s = (f32)conf->getInt("wield_scale") / 100;
u32 mat = conf->getInt("wield_material");
wield->setMaterialFlag(EMF_LIGHTING, false);
wield->setPosition(vector3df(pos.x, pos.y, pos.z));
wield->setRotation(vector3df(rot.x, rot.y, rot.z));
wield->setScale(vector3df(s,s,s));
wield->setVisible(conf->getBool("wield_show"));
wield->setMaterialType((E_MATERIAL_TYPE)mat);
wield->setMaterialFlag(EMF_BILINEAR_FILTER,
conf->getBool("bilinear"));
wield->setMaterialFlag(EMF_TRILINEAR_FILTER,
conf->getBool("trilinear"));
wield->setMaterialFlag(EMF_ANISOTROPIC_FILTER,
conf->getBool("anisotropic"));
wield->setVisible(conf->getBool("wield_show"));
setAttachment();
loadTextures(wield, "wield");
return true;
}
void Scene::loadTextures(ISceneNode *node, const std::string &prefix)
{
IVideoDriver *driver = SceneManager->getVideoDriver();
for (u32 i = 0; i < node->getMaterialCount(); ++i)
{
std::string key = prefix + "_texture_" + std::to_string(i + 1);
io::path fn = conf->getCStr(key);
ITexture *texture = driver->getTexture(fn);
if (texture)
driver->removeTexture(texture);
texture = driver->getTexture(fn);
if (texture)
{
SMaterial &material = node->getMaterial(i);
material.TextureLayer[0].Texture = texture;
}
}
}
ISceneNode *Scene::getNode(s32 id)
{
return SceneManager->getSceneNodeFromId(id);
}
void Scene::setAttachment()
{
if (!conf)
return;
IAnimatedMeshSceneNode *model =
(IAnimatedMeshSceneNode*)getNode(E_SCENE_ID_MODEL);
ISceneNode *wield = getNode(E_SCENE_ID_WIELD);
if (!model || !wield)
return;
IBoneSceneNode *bone = 0;
if (model->getJointCount() > 0)
{
stringc wield_bone = conf->getCStr("wield_bone");
bone = model->getJointNode(wield_bone.c_str());
}
if (bone)
wield->setParent(bone);
else
wield->setParent(model);
}
void Scene::setAnimation(const u32 &start, const u32 &end, const s32 &speed)
{
if (!conf)
return;
IAnimatedMeshSceneNode *model =
(IAnimatedMeshSceneNode*)getNode(E_SCENE_ID_MODEL);
if (model)
{
model->setFrameLoop(start, end);
model->setAnimationSpeed(speed);
}
}
void Scene::setFilter(E_MATERIAL_FLAG flag, const bool &is_enabled)
{
ISceneNode *model = getNode(E_SCENE_ID_MODEL);
if (model)
model->setMaterialFlag(flag, is_enabled);
ISceneNode *wield = getNode(E_SCENE_ID_WIELD);
if (wield)
wield->setMaterialFlag(flag, is_enabled);
}
void Scene::setBackFaceCulling(const bool &is_enabled)
{
ISceneNode *model = getNode(E_SCENE_ID_MODEL);
if (model)
model->setMaterialFlag(EMF_BACK_FACE_CULLING, is_enabled);
ISceneNode *wield = getNode(E_SCENE_ID_WIELD);
if (wield)
wield->setMaterialFlag(EMF_BACK_FACE_CULLING, is_enabled);
}
void Scene::setDebugInfo(const bool &is_visible)
{
ISceneNode *model = getNode(E_SCENE_ID_MODEL);
if (model)
{
u32 state = (is_visible) ? conf->getInt("debug_flags") : EDS_OFF;
model->setDebugDataVisible(state);
}
}
void Scene::rotate(s32 axis, const s32 &step)
{
vector3df rot = getRotation();
switch (axis)
{
case E_SCENE_AXIS_X:
rot.X = int(rot.X / step) * step + step;
break;
case E_SCENE_AXIS_Y:
rot.Y = int(rot.Y / step) * step + step;
break;
case E_SCENE_AXIS_Z:
rot.Z = int(rot.Z / step) * step + step;
break;
}
setRotation(rot);
}
void Scene::refresh()
{
ISceneNode *model = getNode(E_SCENE_ID_MODEL);
if (model)
loadTextures(model, "model");
ISceneNode *wield = getNode(E_SCENE_ID_WIELD);
if (wield)
loadTextures(wield, "wield");
}
void Scene::jump()
{
// quick and dirty jump animation to test attachment inertia
// this should eventually be improved or removed
ISceneNode *model = getNode(E_SCENE_ID_MODEL);
if (!model)
return;
Vector p = conf->getVector("model_position");
vector3df start = vector3df(p.x,p.y,p.z);
vector3df end = start + vector3df(0,10,0);
ISceneNodeAnimator *anim =
SceneManager->createFlyStraightAnimator(start, end, 380, false, true);
model->removeAnimators();
model->addAnimator(anim);
anim->drop();
}
void Scene::OnRegisterSceneNode()
{
if (IsVisible)
SceneManager->registerNodeForRendering(this);
ISceneNode::OnRegisterSceneNode();
}
void Scene::render()
{
if (!show_grid)
return;
IVideoDriver *driver = SceneManager->getVideoDriver();
driver->setMaterial(material);
driver->setTransform(ETS_WORLD, AbsoluteTransformation);
SColor grid = grid_color;
grid.setAlpha(64);
for (f32 n = -10; n <= 10; n += 2)
{
driver->draw3DLine(vector3df(n,0,-10), vector3df(n,-0,10), grid);
driver->draw3DLine(vector3df(-10,0,n), vector3df(10,-0,n), grid);
}
if (!show_axes)
return;
SColor red(128,255,0,0);
SColor green(128,0,255,0);
SColor blue(128,0,0,255);
driver->draw3DLine(vector3df(-10,0,-10), vector3df(-8,0,-10), red);
driver->draw3DLine(vector3df(-8,0,-10), vector3df(-8.5,0,-9.8), red);
driver->draw3DLine(vector3df(-8,0,-10), vector3df(-8.5,0,-10.2), red);
driver->draw3DLine(vector3df(-10,0,-10), vector3df(-10,2,-10), green);
driver->draw3DLine(vector3df(-10,2,-10), vector3df(-9.8,1.5,-10), green);
driver->draw3DLine(vector3df(-10,2,-10), vector3df(-10.2,1.5,-10), green);
driver->draw3DLine(vector3df(-10,0,-10), vector3df(-10,0,-8), blue);
driver->draw3DLine(vector3df(-10,0,-8), vector3df(-9.8,0,-8.5), blue);
driver->draw3DLine(vector3df(-10,0,-8), vector3df(-10.2,0,-8.5), blue);
IGUIEnvironment *env = SceneManager->getGUIEnvironment();
IGUIFont *font = env->getFont("fontlucida.png");
if (font)
{
s32 btm = driver->getScreenSize().Height;
s32 top = btm - 20;
font->draw(L"X", rect<s32>(5,top,15,btm), red);
font->draw(L"Y", rect<s32>(15,top,25,btm), green);
font->draw(L"Z", rect<s32>(25,top,35,btm), blue);
}
}

64
src/scene.h Normal file
View File

@ -0,0 +1,64 @@
#ifndef D_SCENE_H
#define D_SCENE_H
enum
{
E_SCENE_ID,
E_SCENE_ID_MODEL,
E_SCENE_ID_WIELD
};
enum
{
E_SCENE_AXIS_X,
E_SCENE_AXIS_Y,
E_SCENE_AXIS_Z
};
using namespace irr;
using namespace core;
using namespace scene;
using namespace gui;
using namespace video;
class Config;
class Scene : public ISceneNode
{
public:
Scene(ISceneNode *parent, ISceneManager *mgr, s32 id);
~Scene() {}
bool load(Config *config);
bool loadModelMesh(const io::path &filename);
bool loadWieldMesh(const io::path &filename);
ISceneNode *getNode(s32 id);
void setAttachment();
void setAnimation(const u32 &start, const u32 &end, const s32 &speed);
void setFilter(E_MATERIAL_FLAG flag, const bool &is_enabled);
void setBackFaceCulling(const bool &is_enabled);
void setGridColor(SColor color) { grid_color = color; }
void setGridVisible(const bool &is_visible) { show_grid = is_visible; }
void setAxesVisible(const bool &is_visible) { show_axes = is_visible; }
void setDebugInfo(const bool &is_visible);
void rotate(s32 axis, const s32 &step);
void refresh();
void jump();
virtual void OnRegisterSceneNode();
virtual const aabbox3d<f32> &getBoundingBox() const { return box; }
virtual SMaterial &getMaterial(u32 i) { return material; }
virtual u32 getMaterialCount() const { return 1; }
virtual void render();
private:
void loadTextures(ISceneNode *node, const std::string &prefix);
Config *conf;
bool show_grid;
bool show_axes;
SColor grid_color;
aabbox3d<f32> box;
SMaterial material;
};
#endif // D_SCENE_H

84
src/trackball.cpp Normal file
View File

@ -0,0 +1,84 @@
#include <math.h>
#include <irrlicht.h>
#include "trackball.h"
Trackball::Trackball(const u32 &width, const u32 &height) :
is_clicked(false),
is_moving(false)
{
transform.makeIdentity();
setBounds(width, height);
}
vector3df Trackball::getVector(const position2df &pos) const
{
vector3df vect;
vect.X = 1.0 * pos.X / screen.Width * 2 - 1.0;
vect.Y = 1.0 * pos.Y / screen.Height * 2 - 1.0;
vect.Z = 0;
f32 len = vect.X * vect.X + vect.Y * vect.Y;
if (len > 1.0f)
vect.normalize();
else
vect.Z = -sqrt(1.0f - len);
return vect;
}
void Trackball::setBounds(const u32 &width, const u32 &height)
{
screen = dimension2di(width, height);
}
void Trackball::setDragPos(const s32 &x, const s32 &y)
{
drag_pos = position2df(x, y);
}
void Trackball::animateNode(ISceneNode *node, u32 timeMs)
{
if (!node)
return;
if (!is_moving)
{
if (is_clicked)
{
is_moving = true;
transform = node->getAbsoluteTransformation();
drag_start = drag_pos;
}
}
else
{
if (is_clicked)
{
matrix4 rotation;
quaternion quat;
vector3df start = getVector(drag_start);
vector3df end = getVector(drag_pos);
vector3df perp = start.crossProduct(end);
if (iszero(perp.getLength()))
{
quat.makeIdentity();
}
else
{
quat.X = perp.X;
quat.Y = perp.Y;
quat.Z = perp.Z;
quat.W = start.dotProduct(end);
}
quat.getMatrix(rotation);
rotation *= transform;
node->setRotation(rotation.getRotationDegrees());
node->updateAbsolutePosition();
}
else
{
is_moving = false;
}
}
}

33
src/trackball.h Normal file
View File

@ -0,0 +1,33 @@
#ifndef D_TRACKBALL_H
#define D_TRACKBALL_H
using namespace irr;
using namespace core;
using namespace scene;
class Trackball : public ISceneNodeAnimator
{
public:
Trackball(const u32 &width, const u32 &height);
~Trackball(void) {}
void setBounds(const u32 &width, const u32 &height);
void setDragPos(const s32 &x, const s32 &y);
void click() { is_clicked = true; }
void release() { is_clicked = false; }
bool isClicked() const { return is_clicked; }
virtual void animateNode(ISceneNode *node, u32 timeMs);
virtual ISceneNodeAnimator *createClone(ISceneNode *node,
ISceneManager *newManager = 0) { return 0; }
private:
vector3df getVector(const position2df &pos) const;
bool is_clicked;
bool is_moving;
position2df drag_start;
position2df drag_pos;
dimension2di screen;
matrix4 transform;
};
#endif // D_TRACKBALL_H

640
src/viewer.cpp Normal file
View File

@ -0,0 +1,640 @@
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <irrlicht.h>
#include "config.h"
#include "scene.h"
#include "trackball.h"
#include "gui.h"
#include "dialog.h"
#include "viewer.h"
#define M_ZOOM_IN(fov) std::max(fov - DEGTORAD * 2, PI * 0.0125f)
#define M_ZOOM_OUT(fov) std::min(fov + DEGTORAD * 2, PI * 0.5f)
Viewer::Viewer(Config *conf) :
conf(conf),
device(0),
camera(0),
scene(0),
trackball(0),
gui(0),
animation(0)
{}
Viewer::~Viewer()
{
if (scene)
scene->drop();
if (trackball)
delete trackball;
if (gui)
delete gui;
if (animation)
delete animation;
}
bool Viewer::run(IrrlichtDevice *irr_device)
{
device = irr_device;
device->getFileSystem()->addFileArchive("../assets/");
device->getFileSystem()->addFileArchive("../media/");
device->getFileSystem()->changeWorkingDirectoryTo("../media/");
device->setEventReceiver(this);
IVideoDriver *driver = device->getVideoDriver();
ISceneManager *smgr = device->getSceneManager();
IGUIEnvironment *env = device->getGUIEnvironment();
screen = driver->getScreenSize();
trackball = new Trackball(screen.Width, screen.Height);
scene = new Scene(smgr->getRootSceneNode(), smgr, E_SCENE_ID);
scene->addAnimator(trackball);
gui = new GUI(device, conf);
gui->initMenu();
gui->initToolBar();
if (!scene->load(conf))
return false;
animation = new AnimState(env);
animation->load(scene->getNode(E_SCENE_ID_MODEL));
animation->setField(E_GUI_ID_ANIM_START, conf->getInt("anim_start"));
animation->setField(E_GUI_ID_ANIM_END, conf->getInt("anim_end"));
animation->setField(E_GUI_ID_ANIM_SPEED, conf->getInt("anim_speed"));
animation->setField(E_GUI_ID_ANIM_FRAME, conf->getInt("anim_start"));
scene->setAnimation(conf->getInt("anim_start"),
conf->getInt("anim_start"), conf->getInt("anim_speed"));
camera = smgr->addCameraSceneNode(0, vector3df(0,0,30), vector3df(0,0,0));
fov = camera->getFOV();
fov_home = fov;
jump_time = 0;
setCaptionFileName(conf->getCStr("model_mesh"));
setBackgroundColor(conf->getHex("bg_color"));
setProjection();
while (device->run())
{
resize();
driver->beginScene(true, true, bg_color);
smgr->drawAll();
env->drawAll();
driver->endScene();
animation->update(scene->getNode(E_SCENE_ID_MODEL));
}
return true;
}
void Viewer::resize()
{
IVideoDriver *driver = device->getVideoDriver();
dimension2du dim = driver->getScreenSize();
if (screen == dim)
return;
const vector2di move = vector2di(dim.Width - screen.Width, 0);
gui->moveElement(E_GUI_ID_TOOLBOX_MODEL, move);
gui->moveElement(E_GUI_ID_ANIM_CTRL, move);
screen = dim;
trackball->setBounds(screen.Width, screen.Height);
camera->setAspectRatio((f32)screen.Width / (f32)screen.Height);
setProjection();
}
void Viewer::setProjection()
{
f32 width = (f32)screen.Width * fov / 20.0f;
f32 height = (f32)screen.Height * fov / 20.0f;
ortho.buildProjectionMatrixOrthoLH(width, height, 1.0f, 1000.f);
if (conf->getBool("ortho"))
camera->setProjectionMatrix(ortho, true);
else
camera->setFOV(fov);
}
void Viewer::setBackgroundColor(const u32 &color)
{
bg_color.color = color;
bg_color.setAlpha(255);
}
void Viewer::setCaptionFileName(const io::path &filename)
{
io::IFileSystem *fs = device->getFileSystem();
stringw caption = fs->getFileBasename(filename) + L" - SAM-Viewer";
device->setWindowCaption(caption.c_str());
}
static inline std::string boolToString(bool b)
{
return (b) ? "true" : "false";
}
static inline std::string vectorToString(vector3df v)
{
std::ostringstream ss;
ss << v.X << "," << v.Y << "," << v.Z;
std::string str(ss.str());
return str;
}
bool Viewer::OnEvent(const SEvent &event)
{
if (event.EventType == EET_GUI_EVENT)
{
if (event.GUIEvent.EventType == EGET_MENU_ITEM_SELECTED)
{
IGUIContextMenu *menu = (IGUIContextMenu*)event.GUIEvent.Caller;
s32 item = menu->getSelectedItem();
s32 id = menu->getItemCommandId(item);
IGUIEnvironment *env = device->getGUIEnvironment();
switch (id)
{
case E_GUI_ID_LOAD_MODEL_MESH:
env->addFileOpenDialog(L"Open main model file", true, 0,
E_GUI_ID_LOAD_MODEL_MESH);
break;
case E_GUI_ID_LOAD_WIELD_MESH:
env->addFileOpenDialog(L"Open wield model file", true, 0,
E_GUI_ID_LOAD_WIELD_MESH);
break;
case E_GUI_ID_ENABLE_WIELD:
{
ISceneNode *wield = scene->getNode(E_SCENE_ID_WIELD);
if (wield)
{
wield->setVisible(menu->isItemChecked(item));
conf->set("wield_show",
boolToString(menu->isItemChecked(item)));
}
break;
}
case E_GUI_ID_QUIT:
device->closeDevice();
break;
case E_GUI_ID_TEXTURES_DIALOG:
gui->showTexturesDialog();
break;
case E_GUI_ID_SETTINGS_DIALOG:
gui->showSettingsDialog();
break;
case E_GUI_ID_TOOLBOX_MODEL:
{
if (menu->isItemChecked(item))
gui->showToolBox(E_GUI_ID_TOOLBOX_MODEL);
else
gui->closeToolBox(E_GUI_ID_TOOLBOX_MODEL);
break;
}
case E_GUI_ID_TOOLBOX_WIELD:
{
if (menu->isItemChecked(item))
gui->showToolBox(E_GUI_ID_TOOLBOX_WIELD);
else
gui->closeToolBox(E_GUI_ID_TOOLBOX_WIELD);
break;
}
case E_GUI_ID_SHOW_GRID:
scene->setGridVisible(menu->isItemChecked(item));
menu->setItemEnabled(item + 1, menu->isItemChecked(item));
break;
case E_GUI_ID_SHOW_AXES:
scene->setAxesVisible(menu->isItemChecked(item));
break;
case E_GUI_ID_BILINEAR:
scene->setFilter(EMF_BILINEAR_FILTER,
menu->isItemChecked(item));
conf->set("bilinear",
boolToString(menu->isItemChecked(item)));
break;
case E_GUI_ID_TRILINEAR:
scene->setFilter(EMF_TRILINEAR_FILTER,
menu->isItemChecked(item));
conf->set("trilinear",
boolToString(menu->isItemChecked(item)));
break;
case E_GUI_ID_ANISOTROPIC:
scene->setFilter(EMF_ANISOTROPIC_FILTER,
menu->isItemChecked(item));
conf->set("anisotropic",
boolToString(menu->isItemChecked(item)));
break;
case E_GUI_ID_PERSPECTIVE:
menu->setItemChecked(item + 1, !menu->isItemChecked(item));
conf->set("ortho", boolToString(!menu->isItemChecked(item)));
setProjection();
break;
case E_GUI_ID_ORTHOGONAL:
menu->setItemChecked(item - 1, !menu->isItemChecked(item));
conf->set("ortho", boolToString(menu->isItemChecked(item)));
setProjection();
break;
case E_GUI_ID_BACK_FACE_CULL:
scene->setBackFaceCulling(menu->isItemChecked(item));
conf->set("backface_cull",
boolToString(menu->isItemChecked(item)));
break;
case E_GUI_ID_DEBUG_INFO:
scene->setDebugInfo(menu->isItemChecked(item));
conf->set("debug_info",
boolToString(menu->isItemChecked(item)));
break;
case E_DIALOG_ID_ABOUT:
gui->showAboutDialog();
break;
case E_GUI_ID_SAVE_CONFIG:
{
ISceneNode *model = scene->getNode(E_SCENE_ID_MODEL);
if (model)
{
conf->set("model_position",
vectorToString(model->getPosition()));
conf->set("model_rotation",
vectorToString(model->getRotation()));
conf->set("model_scale",
std::to_string(model->getScale().Y * 100));
conf->set("model_material",
std::to_string(model->getMaterial(0).MaterialType));
}
ISceneNode *wield = scene->getNode(E_SCENE_ID_WIELD);
if (wield)
{
conf->set("wield_position",
vectorToString(wield->getPosition()));
conf->set("wield_rotation",
vectorToString(wield->getRotation()));
conf->set("wield_scale",
std::to_string(wield->getScale().Y * 100));
conf->set("wield_material",
std::to_string(wield->getMaterial(0).MaterialType));
}
conf->set("anim_start",
std::to_string(animation->getField(E_GUI_ID_ANIM_START)));
conf->set("anim_end",
std::to_string(animation->getField(E_GUI_ID_ANIM_END)));
conf->set("anim_speed",
std::to_string(animation->getField(E_GUI_ID_ANIM_SPEED)));
conf->save();
break;
}
default:
break;
}
}
else if (event.GUIEvent.EventType == EGET_FILE_SELECTED)
{
IGUIFileOpenDialog *dialog =
(IGUIFileOpenDialog*)event.GUIEvent.Caller;
stringc fn = stringc(dialog->getFileName()).c_str();
if (!fn.empty())
{
s32 id = dialog->getID();
switch (id)
{
case E_GUI_ID_LOAD_MODEL_MESH:
{
if (scene->loadModelMesh(fn))
{
ISceneNode *model = scene->getNode(E_SCENE_ID_MODEL);
if (model)
{
animation->load(model);
setCaptionFileName(fn);
gui->reloadToolBox(E_GUI_ID_TOOLBOX_MODEL);
conf->set("model_mesh", fn.c_str());
}
}
break;
}
case E_GUI_ID_LOAD_WIELD_MESH:
{
if (scene->loadWieldMesh(fn))
{
gui->reloadToolBox(E_GUI_ID_TOOLBOX_WIELD);
conf->set("wield_mesh", fn.c_str());
}
break;
}
default:
break;
}
}
gui->setFocused(false);
}
else if (event.GUIEvent.EventType == EGET_FILE_CHOOSE_DIALOG_CANCELLED)
{
gui->setFocused(false);
}
else if (event.GUIEvent.EventType == EGET_ELEMENT_CLOSED)
{
IGUIContextMenu *menu =
(IGUIContextMenu*)gui->getElement(E_GUI_ID_MENU);
if (menu)
{
s32 id = event.GUIEvent.Caller->getID();
if (id == E_GUI_ID_TOOLBOX_MODEL)
menu->getSubMenu(2)->setItemChecked(0, false);
else if (id == E_GUI_ID_TOOLBOX_WIELD)
menu->getSubMenu(2)->setItemChecked(1, false);
}
gui->setFocused(false);
}
else if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
{
s32 id = event.GUIEvent.Caller->getID();
switch (id)
{
case E_GUI_ID_SKIP_REV:
scene->setAnimation(
animation->getField(E_GUI_ID_ANIM_START),
animation->getField(E_GUI_ID_ANIM_START),
animation->getField(E_GUI_ID_ANIM_SPEED));
animation->setState(E_ANIM_STATE_PAUSED);
gui->setFocused(false);
break;
case E_GUI_ID_PLAY_REV:
scene->setAnimation(
animation->getField(E_GUI_ID_ANIM_START),
animation->getField(E_GUI_ID_ANIM_END),
-animation->getField(E_GUI_ID_ANIM_SPEED));
animation->setState(E_ANIM_STATE_PLAY_REV);
gui->setFocused(false);
break;
case E_GUI_ID_PAUSE:
scene->setAnimation(
animation->getFrame(),
animation->getFrame(),
animation->getField(E_GUI_ID_ANIM_SPEED));
animation->setState(E_ANIM_STATE_PAUSED);
gui->setFocused(false);
break;
case E_GUI_ID_PLAY_FWD:
scene->setAnimation(
animation->getField(E_GUI_ID_ANIM_START),
animation->getField(E_GUI_ID_ANIM_END),
animation->getField(E_GUI_ID_ANIM_SPEED));
animation->setState(E_ANIM_STATE_PLAY_FWD);
gui->setFocused(false);
break;
case E_GUI_ID_SKIP_FWD:
scene->setAnimation(
animation->getField(E_GUI_ID_ANIM_END),
animation->getField(E_GUI_ID_ANIM_END),
animation->getField(E_GUI_ID_ANIM_SPEED));
animation->setState(E_ANIM_STATE_PAUSED);
gui->setFocused(false);
break;
case E_DIALOG_ID_SETTINGS_OK:
event.GUIEvent.Caller->getParent()->getParent()->remove();
gui->setFocused(false);
setBackgroundColor(conf->getHex("bg_color"));
scene->setGridColor(conf->getHex("grid_color"));
scene->setAttachment();
scene->setDebugInfo(conf->getBool("debug_info"));
break;
case E_DIALOG_ID_SETTINGS_CANCEL:
event.GUIEvent.Caller->getParent()->getParent()->remove();
gui->setFocused(false);
break;
case E_DIALOG_ID_ABOUT_OK:
case E_DIALOG_ID_TEXTURES_OK:
case E_DIALOG_ID_TEXTURES_CANCEL:
event.GUIEvent.Caller->getParent()->getParent()->remove();
gui->setFocused(false);
break;
default:
break;
}
}
else if (event.GUIEvent.EventType == EGET_SPINBOX_CHANGED)
{
s32 id = event.GUIEvent.Caller->getID();
switch (id)
{
case E_GUI_ID_ANIM_START:
case E_GUI_ID_ANIM_END:
{
if (animation->getState() != E_ANIM_STATE_PAUSED)
{
IAnimatedMeshSceneNode *model = (IAnimatedMeshSceneNode*)
scene->getNode(E_SCENE_ID_MODEL);
scene->setAnimation(
animation->getField(E_GUI_ID_ANIM_START),
animation->getField(E_GUI_ID_ANIM_END),
model->getAnimationSpeed());
}
break;
}
case E_GUI_ID_ANIM_SPEED:
{
IAnimatedMeshSceneNode *model = (IAnimatedMeshSceneNode*)
scene->getNode(E_SCENE_ID_MODEL);
s32 speed = animation->getField(E_GUI_ID_ANIM_SPEED);
if (animation->getState() == E_ANIM_STATE_PLAY_REV)
speed = -speed;
model->setAnimationSpeed(speed);
break;
}
case E_GUI_ID_ANIM_FRAME:
{
if (animation->getState() == E_ANIM_STATE_PAUSED)
{
u32 frame = animation->getField(E_GUI_ID_ANIM_FRAME);
scene->setAnimation(frame, frame,
animation->getField(E_GUI_ID_ANIM_SPEED));
}
break;
}
default:
break;
}
}
else if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
{
gui->setFocused(false);
}
else if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUSED)
{
gui->setFocused(true);
trackball->release();
}
}
else if (event.EventType == EET_KEY_INPUT_EVENT &&
event.KeyInput.PressedDown)
{
switch (event.KeyInput.Key)
{
case KEY_HOME:
{
scene->setRotation(vector3df(0,0,0));
fov = fov_home;
setProjection();
break;
}
case KEY_SPACE:
{
u32 now_time = device->getTimer()->getTime() + 1000;
if (jump_time + 800 < now_time)
{
jump_time = now_time;
scene->jump();
}
break;
}
case KEY_LEFT:
scene->rotate(E_SCENE_AXIS_Y, 15);
break;
case KEY_RIGHT:
scene->rotate(E_SCENE_AXIS_Y, -15);
break;
case KEY_UP:
scene->rotate(E_SCENE_AXIS_X, -15);
break;
case KEY_DOWN:
scene->rotate(E_SCENE_AXIS_X, 15);
break;
case KEY_KEY_Z:
scene->rotate(E_SCENE_AXIS_Z, -15);
break;
case KEY_KEY_X:
scene->rotate(E_SCENE_AXIS_Z, 15);
break;
case KEY_PLUS:
fov = M_ZOOM_IN(fov);
setProjection();
break;
case KEY_MINUS:
fov = M_ZOOM_OUT(fov);
setProjection();
break;
case KEY_F5:
scene->refresh();
break;
default:
break;
}
}
else if (event.EventType == EET_MOUSE_INPUT_EVENT && !gui->getFocused())
{
switch (event.MouseInput.Event)
{
case EMIE_LMOUSE_LEFT_UP:
trackball->release();
break;
case EMIE_MOUSE_MOVED:
{
if (event.MouseInput.isLeftPressed() && !trackball->isClicked())
trackball->click();
trackball->setDragPos(event.MouseInput.X, event.MouseInput.Y);
break;
}
case EMIE_MOUSE_WHEEL:
{
if (event.MouseInput.Wheel < 0)
fov = M_ZOOM_OUT(fov);
else
fov = M_ZOOM_IN(fov);
setProjection();
break;
}
default:
break;
}
}
return false;
}
AnimState::AnimState(IGUIEnvironment *env) :
env(env),
frame(0),
max(0),
state(E_ANIM_STATE_PAUSED)
{}
void AnimState::load(ISceneNode *node)
{
IAnimatedMeshSceneNode *model = (IAnimatedMeshSceneNode*)node;
if (!model)
return;
IGUIToolBar *toolbar = getToolBar();
if (!toolbar)
return;
max = model->getEndFrame();
model->setFrameLoop(0, 0);
state = E_ANIM_STATE_PAUSED;
setField(E_GUI_ID_ANIM_START, 0);
setField(E_GUI_ID_ANIM_END, max);
setField(E_GUI_ID_ANIM_FRAME, 0);
bool enabled = (max > 0);
const list<IGUIElement*> &children = toolbar->getChildren();
list<IGUIElement*>::ConstIterator iter = children.begin();
while (iter != children.end())
{
if ((*iter)->getID() == E_GUI_ID_ANIM_CTRL)
{
AnimCtrl *anim = (AnimCtrl*)(*iter);
anim->reset(enabled);
if (enabled)
{
IGUIButton *button =
(IGUIButton*)anim->getElementFromId(E_GUI_ID_PAUSE, true);
button->setPressed(true);
}
}
else if ((*iter)->getType() != EGUIET_STATIC_TEXT)
{
(*iter)->setEnabled(enabled);
}
++iter;
}
}
void AnimState::update(ISceneNode *node)
{
IAnimatedMeshSceneNode *model = (IAnimatedMeshSceneNode*)node;
frame = model->getFrameNr();
setField(E_GUI_ID_ANIM_FRAME, frame);
}
IGUIToolBar *AnimState::getToolBar()
{
IGUIElement *root = env->getRootGUIElement();
return (IGUIToolBar*)root->getElementFromId(E_GUI_ID_TOOLBAR, true);
}
u32 AnimState::getField(s32 id)
{
IGUIToolBar *toolbar = getToolBar();
if (!toolbar)
return 0;
IGUISpinBox *spin;
spin = (IGUISpinBox*)toolbar->getElementFromId(id, true);
return spin->getValue();
}
void AnimState::setField(s32 id, const u32 &value)
{
IGUIToolBar *toolbar = getToolBar();
if (!toolbar)
return;
IGUISpinBox *spin;
spin = (IGUISpinBox*)toolbar->getElementFromId(id, true);
spin->setRange(0, max);
spin->setValue(std::min(value, max));
}

78
src/viewer.h Normal file
View File

@ -0,0 +1,78 @@
#ifndef D_VIEWER_H
#define D_VIEWER_H
using namespace irr;
using namespace core;
using namespace scene;
using namespace gui;
using namespace video;
class Config;
class Scene;
class Trackball;
class GUI;
enum
{
E_ANIM_STATE_PLAY_FWD,
E_ANIM_STATE_PLAY_REV,
E_ANIM_STATE_PAUSED
};
enum
{
E_PROJECTION_PERSPECTIVE,
E_PROJECTION_ORTHOGRAPHIC
};
class AnimState
{
public:
AnimState(IGUIEnvironment *env);
void load(ISceneNode *node);
void update(ISceneNode *node);
void setField(s32 id, const u32 &value);
void setState(s32 id) { state = id; }
u32 getField(s32 id);
u32 getFrame() { return frame; }
s32 getState() { return state; }
private:
IGUIToolBar *getToolBar();
IGUIEnvironment *env;
u32 frame;
u32 max;
s32 state;
};
class Viewer : public IEventReceiver
{
public:
Viewer(Config *conf);
~Viewer();
bool run(IrrlichtDevice *irr_device);
virtual bool OnEvent(const SEvent &event);
private:
void resize();
void setProjection();
void setBackgroundColor(const u32 &color);
void setCaptionFileName(const io::path &filename);
Config *conf;
IrrlichtDevice *device;
ICameraSceneNode *camera;
Scene *scene;
Trackball *trackball;
GUI *gui;
AnimState *animation;
matrix4 ortho;
f32 fov;
f32 fov_home;
dimension2du screen;
SColor bg_color;
u32 jump_time;
};
#endif // D_VIEWER_H