diff --git a/Assets/Shaders/frag_uniforms.glsl b/Assets/Shaders/frag_uniforms.glsl new file mode 100644 index 00000000..abe18eba --- /dev/null +++ b/Assets/Shaders/frag_uniforms.glsl @@ -0,0 +1,15 @@ +#define MAX_LIGHTS 16 + +struct Light { + vec3 position; + vec3 rotation; + vec3 color; + float distance_dropoff; + int type; +}; + +layout(std140, binding = 1) uniform SceneLightsUBO { + Light lights[MAX_LIGHTS]; + vec4 ambient_light; + int light_count; +}; \ No newline at end of file diff --git a/Assets/Shaders/lastpass.fs b/Assets/Shaders/lastpass.fs index 7d9406c1..98582031 100644 --- a/Assets/Shaders/lastpass.fs +++ b/Assets/Shaders/lastpass.fs @@ -1,4 +1,4 @@ -#version 330 core +#version 420 core out vec4 fragColor; diff --git a/Assets/Shaders/lastpass.vs b/Assets/Shaders/lastpass.vs index 8fc78f1c..1812a240 100644 --- a/Assets/Shaders/lastpass.vs +++ b/Assets/Shaders/lastpass.vs @@ -1,4 +1,4 @@ -#version 330 core +#version 420 core layout (location = 0) in vec3 aPos; layout (location = 1) in vec2 aUV; diff --git a/Assets/Shaders/normal.fs b/Assets/Shaders/normal.fs index 1368ef7d..770248b4 100644 --- a/Assets/Shaders/normal.fs +++ b/Assets/Shaders/normal.fs @@ -1,4 +1,4 @@ -#version 330 core +#version 420 core out vec4 frag_color; diff --git a/Assets/Shaders/normal.vs b/Assets/Shaders/normal.vs index ef8b4d26..f45c8194 100644 --- a/Assets/Shaders/normal.vs +++ b/Assets/Shaders/normal.vs @@ -1,15 +1,15 @@ -#version 330 core +#version 420 core + +#include "vert_uniforms.glsl" layout (location = 0) in vec3 vertex; layout (location = 1) in vec3 normal; -uniform mat4 projection; -uniform mat4 view; uniform mat4 model; out vec3 f_normal; void main() { f_normal = abs(normal); - gl_Position = projection * view * model * vec4(vertex, 1.0); + gl_Position = uProjection * uView * model * vec4(vertex, 1.0); } \ No newline at end of file diff --git a/Assets/Shaders/phong.fs b/Assets/Shaders/phong.fs index 64fc5128..9dab910c 100644 --- a/Assets/Shaders/phong.fs +++ b/Assets/Shaders/phong.fs @@ -1,15 +1,8 @@ -#version 330 core -#define ICE_MAX_LIGHTS (16) +#version 420 core -out vec4 frag_color; +#include "frag_uniforms.glsl" -struct Light { - vec3 position; - vec3 rotation; - vec3 color; - int type; //0 = Point, 1 = Directional, 2 = Spot - float distance_dropoff; -}; +out vec4 frag_color; struct Material { vec4 albedo; @@ -26,9 +19,6 @@ struct Material { sampler2D normal_map; }; -uniform vec3 ambient_light; -uniform Light lights[ICE_MAX_LIGHTS]; -uniform int light_count; uniform Material material; in vec3 fnormal; @@ -88,7 +78,7 @@ void main() { normal = fnormal; } //ambient - vec4 color_accumulator = material.ambient * vec4(ambient_light, 1.0); + vec4 color_accumulator = material.ambient * ambient_light; if(material.use_ambient_map) { color_accumulator *= texture(material.ambient_map, ftex_coords); } diff --git a/Assets/Shaders/phong.vs b/Assets/Shaders/phong.vs index dec176ed..a49b8419 100644 --- a/Assets/Shaders/phong.vs +++ b/Assets/Shaders/phong.vs @@ -1,22 +1,67 @@ -#version 330 core +#version 420 core + +#include "vert_uniforms.glsl" +#define MAX_BONES 100 +#define MAX_BONE_INFLUENCE 4 layout (location = 0) in vec3 vertex; layout (location = 1) in vec3 normal; layout (location = 2) in vec2 tex_coords; +layout (location = 3) in vec3 tangent; +layout (location = 4) in vec3 bitangent; +layout (location = 5) in ivec4 bone_ids; +layout (location = 6) in vec4 bone_weights; -uniform mat4 projection; -uniform mat4 view; uniform mat4 model; +uniform mat4 bonesTransformMatrices[MAX_BONES]; +uniform mat4 bonesOffsetMatrices[MAX_BONES]; out vec3 fnormal; +out vec3 ftangent; +out vec3 fbitangent; out vec3 fposition; out vec3 fview; out vec2 ftex_coords; void main() { - fview = (inverse(view) * vec4(0, 0, 0, 1)).xyz; - fnormal = normalize(mat3(transpose(inverse(model))) * normal); - fposition = (model * vec4(vertex, 1.0)).xyz; + vec4 totalPosition = vec4(0.0f); + vec3 totalNormal = vec3(0.0f); + vec3 totalTangent = vec3(0.0f); + vec3 totalBitangent = vec3(0.0f); + + if(bone_ids == ivec4(-1)) { + totalPosition = vec4(vertex, 1.0f); + totalNormal = normal; + } else { + for(int i = 0 ; i < MAX_BONE_INFLUENCE ; i++) { + if(bone_ids[i] == -1) continue; + + if(bone_ids[i] >= MAX_BONES) { + totalPosition = vec4(vertex, 1.0f); + totalNormal = normal; + break; + } + + mat4 finalBonesMatrix = bonesTransformMatrices[bone_ids[i]] * bonesOffsetMatrices[bone_ids[i]]; + + totalPosition += finalBonesMatrix * vec4(vertex, 1.0f) * bone_weights[i]; + + mat3 normalMatrix = mat3(transpose(inverse(finalBonesMatrix))); + totalNormal += normalMatrix * normal * bone_weights[i]; + totalTangent += normalMatrix * tangent * bone_weights[i]; + totalBitangent += normalMatrix * bitangent * bone_weights[i]; + } + } + + + fposition = (model * totalPosition).xyz; + mat3 normalModelMatrix = mat3(transpose(inverse(model))); + fnormal = normalize(normalModelMatrix * totalNormal); + ftangent = normalize(normalModelMatrix * totalTangent); + fbitangent = normalize(normalModelMatrix * totalBitangent); + + gl_Position = uProjection * uView * model * totalPosition; + + fview = (inverse(uView) * vec4(0, 0, 0, 1)).xyz; ftex_coords = tex_coords; - gl_Position = projection * view * model * vec4(vertex, 1.0); } \ No newline at end of file diff --git a/Assets/Shaders/picking.fs b/Assets/Shaders/picking.fs index e8f7fe11..74642cb8 100644 --- a/Assets/Shaders/picking.fs +++ b/Assets/Shaders/picking.fs @@ -1,4 +1,4 @@ -#version 330 core +#version 420 core uniform int objectID; diff --git a/Assets/Shaders/picking.vs b/Assets/Shaders/picking.vs index b2320b25..e309f5a0 100644 --- a/Assets/Shaders/picking.vs +++ b/Assets/Shaders/picking.vs @@ -1,12 +1,12 @@ -#version 330 core +#version 420 core + +#include "vert_uniforms.glsl" layout (location = 0) in vec3 vertex; layout (location = 1) in vec3 normal; -uniform mat4 projection; -uniform mat4 view; uniform mat4 model; void main() { - gl_Position = projection * view * model * vec4(vertex, 1.0); + gl_Position = uProjection * uView * model * vec4(vertex, 1.0); } \ No newline at end of file diff --git a/Assets/Shaders/skybox.fs b/Assets/Shaders/skybox.fs index 9cede7a7..5ee05b3e 100644 --- a/Assets/Shaders/skybox.fs +++ b/Assets/Shaders/skybox.fs @@ -1,4 +1,4 @@ -#version 330 core +#version 420 core out vec4 FragColor; in vec3 TexCoords; diff --git a/Assets/Shaders/skybox.vs b/Assets/Shaders/skybox.vs index b7c2dfc1..0817ad8f 100644 --- a/Assets/Shaders/skybox.vs +++ b/Assets/Shaders/skybox.vs @@ -1,13 +1,15 @@ -#version 330 core +#version 420 core + +#include "vert_uniforms.glsl" + + layout (location = 0) in vec3 aPos; out vec3 TexCoords; -uniform mat4 projection; -uniform mat4 view; void main() { TexCoords = aPos; - gl_Position = projection * view * vec4(aPos, 1.0); + gl_Position = uProjection * uView * vec4(aPos, 1.0); } \ No newline at end of file diff --git a/Assets/Shaders/solid.fs b/Assets/Shaders/solid.fs index 2bc2b148..ffdd27a1 100644 --- a/Assets/Shaders/solid.fs +++ b/Assets/Shaders/solid.fs @@ -1,4 +1,4 @@ -#version 330 core +#version 420 core out vec4 frag_color; diff --git a/Assets/Shaders/solid.vs b/Assets/Shaders/solid.vs index c457cfbd..b3b2f510 100644 --- a/Assets/Shaders/solid.vs +++ b/Assets/Shaders/solid.vs @@ -1,13 +1,13 @@ -#version 330 core +#version 420 core + +#include "vert_uniforms.glsl" layout (location = 0) in vec3 vertex; layout (location = 1) in vec3 normal; layout (location = 2) in vec2 tex_coords; -uniform mat4 projection; -uniform mat4 view; uniform mat4 model; void main() { - gl_Position = projection * view * model * vec4(vertex, 1.0); + gl_Position = uProjection * uView * model * vec4(vertex, 1.0); } \ No newline at end of file diff --git a/Assets/Shaders/vert_uniforms.glsl b/Assets/Shaders/vert_uniforms.glsl new file mode 100644 index 00000000..2a813dc5 --- /dev/null +++ b/Assets/Shaders/vert_uniforms.glsl @@ -0,0 +1,4 @@ +layout(std140, binding = 0) uniform SceneData { + mat4 uProjection; + mat4 uView; +}; \ No newline at end of file diff --git a/Assets/bunny.obj b/Assets/bunny.obj deleted file mode 100644 index 18de1a37..00000000 --- a/Assets/bunny.obj +++ /dev/null @@ -1,4048 +0,0 @@ -#### -# -# OBJ File Generated by Meshlab -# -#### -# Object bunny.obj -# -# Vertices: 1016 -# Faces: 2000 -# -#### -vn 3.094766 -3.957421 2.571340 -v -0.022632 0.157543 -0.004347 -vn -3.352937 4.642061 2.162993 -v -0.075174 0.167976 -0.025192 -vn -5.335856 2.490041 1.505438 -v -0.077239 0.163912 -0.021716 -vn -1.354921 2.677570 5.483067 -v -0.016734 0.110903 0.040898 -vn 0.625443 2.202277 5.399317 -v -0.076174 0.133648 0.052091 -vn 3.137585 4.552284 2.231628 -v -0.067581 0.162514 -0.013916 -vn 1.757145 5.957641 -0.629532 -v -0.034495 0.127246 0.005205 -vn -0.354196 3.603699 4.325252 -v -0.054989 0.044232 0.045269 -vn -1.267852 2.433462 5.073477 -v -0.039189 0.043347 0.041535 -vn 0.978163 -2.073041 5.294097 -v 0.006055 0.043707 0.045479 -vn 1.293697 1.756783 5.366480 -v -0.039456 0.168482 0.002719 -vn -1.910909 4.988601 3.166912 -v -0.015853 0.123285 0.031129 -vn -0.215986 3.895658 4.180577 -v -0.022979 0.047265 0.051674 -vn 0.385011 -0.461055 5.132621 -v -0.010664 0.046795 0.047826 -vn 0.431796 -1.765497 4.977530 -v 0.000109 0.044727 0.046148 -vn 2.119135 2.474565 4.371812 -v -0.048237 0.118063 0.030649 -vn -0.330534 5.090180 3.252033 -v -0.052978 0.047284 0.041192 -vn -0.442288 -4.360488 4.418675 -v -0.001039 0.048756 0.050981 -vn -0.925855 0.715390 4.496519 -v -0.016677 0.049287 0.047116 -vn -1.750692 -3.126344 4.851878 -v -0.012694 0.049776 0.049879 -vn 0.332566 -1.057794 5.443482 -v -0.071538 0.119432 0.053754 -vn -0.733410 2.731809 5.376121 -v -0.045683 0.048783 0.039154 -vn -0.721246 0.696525 6.123454 -v -0.042500 0.050665 0.039371 -vn -0.640319 3.011006 4.592459 -v -0.033737 0.050229 0.038469 -vn -1.672931 4.460975 3.280887 -v -0.025961 0.048758 0.049144 -vn -2.176725 2.191547 3.809460 -v -0.020594 0.050686 0.045394 -vn -0.227480 -1.733775 4.713461 -v -0.001180 0.052466 0.054806 -vn 0.134422 -0.820915 5.740516 -v 0.041168 0.050011 0.032719 -vn 1.153504 -0.685041 6.118216 -v -0.038283 0.052792 0.039210 -vn 2.489824 -1.332598 4.916564 -v 0.011200 0.054657 0.052333 -vn 0.874980 2.935273 4.351535 -v -0.035554 0.172881 -0.000252 -vn 5.222351 2.693640 1.601598 -v -0.063228 0.157493 -0.014585 -vn -2.571881 -1.880636 5.043581 -v -0.016423 0.053993 0.050415 -vn 1.022703 -2.421208 5.356022 -v 0.002994 0.051586 0.053297 -vn 3.438566 2.806768 2.577215 -v -0.056579 0.152747 0.030669 -vn -1.950585 -1.930631 5.565226 -v -0.012987 0.056778 0.051762 -vn 3.152490 1.908031 3.973677 -v -0.059871 0.149768 0.035859 -vn -1.119143 1.556231 3.575322 -v -0.028411 0.053001 0.036275 -vn 0.183280 -1.656104 5.935799 -v -0.000784 0.058271 0.054461 -vn 0.736503 1.122158 5.296014 -v 0.046480 0.058611 0.032273 -vn -1.319849 -2.360526 5.574702 -v -0.006618 0.053914 0.053241 -vn 0.164065 3.517445 5.146259 -v -0.036309 0.112896 0.034500 -vn -1.380083 5.852649 1.221236 -v -0.078187 0.155111 0.025574 -vn -0.316837 -1.136033 5.896620 -v -0.040382 0.059825 0.040868 -vn -1.721913 -1.506967 5.409180 -v -0.009937 0.060109 0.055295 -vn 1.695966 -1.291977 5.796677 -v 0.007708 0.058148 0.053117 -vn 0.957974 3.805042 4.546082 -v 0.009784 0.122290 0.035151 -vn -1.624216 -0.660921 4.661459 -v -0.027750 0.059877 0.036835 -vn -1.516021 5.959760 0.557596 -v -0.014970 0.129219 0.015705 -vn 0.879719 -1.238429 5.293655 -v 0.003769 0.062082 0.056814 -vn 2.458633 1.170214 4.118223 -v 0.040765 0.061943 0.029168 -vn 1.269830 2.434664 5.635268 -v 0.013123 0.114191 0.038027 -vn 1.927009 -0.994879 5.882141 -v -0.033531 0.057993 0.038350 -vn -1.235572 -1.173458 5.961074 -v -0.007891 0.068203 0.055874 -vn 0.312522 3.140684 5.175601 -v -0.000590 0.117009 0.040304 -vn -0.387106 -0.618100 6.060271 -v -0.003723 0.063692 0.056549 -vn -2.126080 -1.397157 5.491000 -v -0.081658 0.121900 0.049490 -vn -2.454829 2.440252 -4.713358 -v -0.028901 0.093527 -0.024842 -vn -4.086711 1.656504 -4.191994 -v -0.022248 0.180636 -0.020957 -vn 0.089017 3.277874 4.887360 -v 0.049333 0.065921 0.028380 -vn -2.139113 -1.184721 5.761744 -v -0.014837 0.064001 0.053545 -vn 0.674115 -0.509226 6.134180 -v 0.001206 0.068895 0.056091 -vn 1.241177 -0.883773 5.813328 -v -0.036372 0.066188 0.041816 -vn -3.218146 1.351646 -4.959758 -v -0.034116 0.171485 -0.014923 -vn -3.855127 -1.646155 4.186658 -v -0.027132 0.068677 0.039985 -vn -1.364807 -1.391624 5.937181 -v -0.013509 0.072324 0.055321 -vn 2.173125 2.133322 -1.326270 -v -0.062384 0.178712 -0.060118 -vn -0.904304 3.511562 5.075599 -v -0.007649 0.118256 0.038606 -vn 5.793472 0.963254 -1.660520 -v -0.062109 0.146794 -0.005135 -vn 0.368345 -1.151219 5.778279 -v -0.029990 0.070984 0.039578 -vn -5.926123 1.651647 0.316675 -v -0.088318 0.104127 0.015646 -vn -0.113716 -1.069734 5.411078 -v -0.004569 0.073133 0.059031 -vn -0.293794 -2.286711 5.664225 -v -0.047443 0.073211 0.041693 -vn -1.405224 -1.064870 5.797318 -v -0.043171 0.068714 0.041768 -vn 1.687957 -0.140487 5.756138 -v 0.000783 0.079041 0.057911 -vn -1.168983 -3.065621 5.117674 -v -0.059251 0.074127 0.041652 -vn 1.108791 -0.024260 5.882131 -v 0.007199 0.074598 0.056746 -vn -0.149953 -0.877953 6.034171 -v -0.039500 0.079658 0.043297 -vn -2.379262 -1.881085 5.429995 -v -0.019374 0.076997 0.055391 -vn -1.677857 4.428647 4.071449 -v -0.025821 0.117485 0.032251 -vn -1.723330 4.031852 4.345165 -v -0.016792 0.119452 0.035398 -vn 1.145654 5.918700 0.773983 -v 0.009481 0.131167 0.018514 -vn -1.095332 6.051566 -0.101883 -v -0.077346 0.156087 0.016429 -vn -0.177736 -1.617727 5.560285 -v -0.055247 0.080917 0.045032 -vn 0.729490 -2.043393 5.276521 -v -0.049241 0.075309 0.043370 -vn 0.354106 -0.623176 6.032168 -v -0.043726 0.081527 0.042423 -vn 1.247137 2.844611 5.360134 -v 0.006799 0.116434 0.039090 -vn -1.796515 4.364497 3.741938 -v -0.078484 0.147136 0.041514 -vn 0.977957 -1.786209 5.901249 -v -0.051671 0.081136 0.044260 -vn -0.871932 0.057646 6.120081 -v -0.008032 0.077902 0.058098 -vn 1.985831 -0.373681 5.738019 -v 0.002797 0.078605 0.056563 -vn -0.792526 -0.923510 5.985878 -v -0.077226 0.124510 0.052531 -vn 1.173299 -0.690842 6.098456 -v -0.035132 0.078318 0.041951 -vn -0.993705 -1.367374 5.994335 -v -0.014755 0.077626 0.056744 -vn 0.371292 0.795110 6.212221 -v -0.005822 0.085265 0.057191 -vn -0.927732 0.028606 5.267187 -v -0.018322 0.082931 0.057966 -vn -0.853811 1.100726 6.044978 -v -0.014548 0.087675 0.056935 -vn -1.098176 5.857864 1.744862 -v -0.025186 0.125020 0.018505 -vn -0.712738 4.533755 4.066230 -v -0.006815 0.123672 0.034343 -vn -1.336699 -1.796043 5.837923 -v -0.061846 0.079310 0.042931 -vn 0.870475 0.838895 5.843807 -v 0.003308 0.085766 0.057417 -vn 0.282488 4.719956 3.605405 -v -0.037277 0.122401 0.027860 -vn 2.437248 1.449543 3.970111 -v -0.024564 0.181758 -0.009287 -vn 1.053348 0.457579 5.395002 -v -0.049399 0.087256 0.045901 -vn 0.361377 6.172206 -0.343408 -v 0.004877 0.131719 0.008993 -vn -1.245738 -0.128705 5.572842 -v -0.064320 0.088733 0.045416 -vn -0.119381 -0.177199 6.217679 -v -0.057121 0.088104 0.044655 -vn 0.484618 -0.177087 5.400366 -v -0.037733 0.084103 0.044251 -vn -0.573746 -0.595544 6.132878 -v -0.035888 0.088835 0.043456 -vn 0.142328 1.905210 5.707716 -v -0.008528 0.091508 0.056852 -vn 4.050235 -0.212567 1.545237 -v -0.009886 0.166722 -0.017511 -vn 0.293594 0.299991 6.053345 -v -0.042104 0.087286 0.042611 -vn 3.070954 5.152725 1.024659 -v 0.021778 0.126056 0.020005 -vn 0.084260 1.594863 5.296378 -v -0.059599 0.093932 0.045485 -vn -1.008162 2.740681 5.187271 -v -0.012990 0.092703 0.056065 -vn 1.082044 2.749430 5.381898 -v 0.004070 0.092302 0.054987 -vn 4.317272 -0.801272 4.176701 -v -0.059869 0.143487 0.035797 -vn -0.076046 0.780789 6.134088 -v -0.053239 0.094273 0.043815 -vn -0.994936 5.523821 2.201892 -v -0.006917 0.129109 0.026115 -vn -1.681131 3.062509 4.480684 -v -0.023644 0.095822 0.044726 -vn 0.441037 3.918304 4.747963 -v 0.007387 0.098533 0.048771 -vn 1.837102 1.674652 5.361540 -v 0.018439 0.091823 0.047938 -vn 2.014802 2.331324 5.124097 -v 0.021023 0.099320 0.046217 -vn -0.677194 6.145686 0.147623 -v -0.002793 0.131514 0.013755 -vn 0.178340 1.010761 5.985486 -v -0.041403 0.095527 0.042055 -vn -1.336100 0.038610 5.748745 -v -0.035209 0.093345 0.044619 -vn -2.420201 2.124227 4.906639 -v -0.026239 0.093563 0.045214 -vn 5.730315 2.358134 0.102314 -v -0.048370 0.137251 0.011910 -vn -1.745998 -1.310281 5.245662 -v -0.075848 0.118852 0.053013 -vn -0.077953 4.363782 4.431350 -v -0.030870 0.117520 0.031465 -vn 0.258411 2.076190 5.862804 -v -0.047342 0.101440 0.041883 -vn -1.288335 3.383083 4.368934 -v -0.019016 0.098239 0.044663 -vn 2.015697 -2.836348 -2.116434 -v -0.009759 0.167842 -0.023732 -vn 1.587561 2.378162 5.523959 -v 0.012564 0.097906 0.048449 -vn -0.884537 1.502818 5.991148 -v -0.062452 0.098249 0.042647 -vn -0.616705 1.960715 5.915828 -v -0.028858 0.100001 0.043282 -vn 0.266736 0.742426 5.441052 -v -0.049157 0.096445 0.044787 -vn -0.308518 2.968567 4.351229 -v -0.007748 0.101613 0.043852 -vn -2.407340 0.644880 5.570633 -v -0.073209 0.105383 0.037186 -vn -0.743845 2.147017 5.631745 -v -0.062385 0.102987 0.041882 -vn -1.328710 3.178347 5.230953 -v -0.029049 0.106680 0.040203 -vn -0.598888 1.895476 5.931429 -v -0.017728 0.104776 0.042847 -vn 0.237100 3.081248 4.766045 -v 0.012293 0.102676 0.047244 -vn 5.642019 1.498931 1.749087 -v 0.043380 0.095176 0.023644 -vn -0.022555 3.743685 4.700986 -v -0.074645 0.143883 0.045580 -vn -0.316966 1.857881 5.917602 -v -0.053840 0.099162 0.043133 -vn -1.025945 2.163476 5.671541 -v -0.033397 0.099353 0.043336 -vn 0.221163 3.190629 4.436065 -v 0.001455 0.102087 0.043717 -vn 4.691329 3.704555 1.186367 -v 0.034532 0.114319 0.022279 -vn 5.897046 1.208744 0.917447 -v -0.062543 0.152623 -0.011515 -vn -1.685541 5.225436 2.572695 -v -0.078392 0.152598 0.033218 -vn -2.165875 5.032029 2.181965 -v -0.035838 0.176094 -0.004875 -vn 0.364634 2.663470 5.451436 -v -0.038430 0.105140 0.038948 -vn -0.737732 1.924380 5.725494 -v -0.023640 0.103170 0.043565 -vn 0.744581 1.967038 5.334632 -v -0.043712 0.105017 0.041432 -vn -0.720472 1.865637 5.759243 -v -0.011017 0.109063 0.043214 -vn 1.616586 3.309888 5.073047 -v 0.020312 0.107668 0.040045 -vn -0.039919 3.158636 5.416228 -v -0.050937 0.109405 0.038213 -vn 0.240754 2.643583 5.065606 -v 0.008412 0.107166 0.040919 -vn 1.236884 1.505575 5.833599 -v 0.002875 0.110461 0.042399 -vn 0.718403 3.537205 5.053177 -v -0.041817 0.111863 0.036380 -vn -1.650954 3.350686 4.912292 -v -0.022286 0.112333 0.038935 -vn 0.072845 3.697677 4.994920 -v 0.013237 0.108390 0.040931 -vn 0.284569 3.365786 -4.577050 -v -0.005593 0.100397 -0.023626 -vn 3.714252 4.090246 2.393250 -v 0.028553 0.118568 0.027351 -vn 1.216376 -3.030059 3.611988 -v 0.013840 0.035778 0.044177 -vn 0.618182 1.893739 5.149255 -v -0.021573 0.044152 0.053786 -vn 1.803096 0.432669 5.998221 -v -0.003448 0.039522 0.047731 -vn 2.232999 0.299057 5.266601 -v 0.017782 0.043171 0.044133 -vn -0.704631 1.028686 5.158418 -v -0.056022 0.040278 0.047317 -vn 1.439404 -1.307021 5.148934 -v -0.044655 0.036493 0.044874 -vn 3.658055 -0.615402 4.448274 -v 0.023074 0.042970 0.040731 -vn -1.031086 1.145430 -5.711343 -v -0.052975 0.098550 -0.022329 -vn 5.684490 2.363640 0.122282 -v 0.042865 0.101843 0.010188 -vn 3.768438 -3.653101 3.234857 -v 0.031994 0.048007 0.032376 -vn 1.372108 2.730400 5.321715 -v -0.046777 0.043103 0.043730 -vn 2.357095 1.367761 3.871970 -v -0.032079 0.174511 -0.002531 -vn 3.619740 -3.956558 2.991062 -v 0.050238 0.047308 0.024532 -vn 3.184967 2.908583 4.509330 -v -0.014239 0.171118 -0.017749 -vn 5.725510 0.493050 2.375154 -v -0.054385 0.146748 0.026987 -vn -5.486488 1.655423 -2.492476 -v -0.084794 0.103733 0.000530 -vn 2.450629 -1.319229 5.095459 -v 0.015867 0.047316 0.043528 -vn 2.002371 3.259158 4.942435 -v 0.022732 0.112679 0.036283 -vn 2.592729 2.182607 3.994351 -v -0.042660 0.157810 0.004583 -vn 1.623961 3.829529 4.317648 -v -0.037161 0.160873 0.000365 -vn 2.770036 1.065387 3.339553 -v -0.018041 0.161479 -0.006288 -vn 1.631466 -3.926208 4.055352 -v 0.007884 0.046671 0.048882 -vn 3.942245 -1.882241 4.441726 -v 0.027775 0.047288 0.036817 -vn 2.591851 -2.189430 4.782357 -v 0.045687 0.050252 0.031469 -vn 2.496937 -2.147558 4.475423 -v 0.020156 0.054169 0.047523 -vn 3.177914 -2.557964 4.711590 -v 0.025271 0.052639 0.040636 -vn 5.203628 1.956359 -2.827335 -v 0.040625 0.095875 -0.006116 -vn -0.128667 1.414716 5.979097 -v -0.065217 0.110091 0.037575 -vn 2.601575 -1.908917 5.262579 -v 0.015462 0.055027 0.048849 -vn 1.927370 -2.337471 4.968058 -v 0.033759 0.048788 0.031363 -vn 1.755159 -0.327688 5.136786 -v 0.038256 0.056776 0.031141 -vn 0.323107 0.724080 6.042971 -v -0.002328 0.105934 0.044142 -vn 3.827743 -1.835371 4.173399 -v 0.053375 0.054835 0.027934 -vn 3.476335 0.453366 2.990467 -v -0.014586 0.162885 -0.010125 -vn 4.663794 1.871406 3.222214 -v -0.049703 0.129792 0.031100 -vn 4.312537 -1.553022 3.995542 -v -0.061115 0.120220 0.041955 -vn 5.032962 -1.051812 3.258023 -v 0.038800 0.063605 0.034213 -vn 5.095171 -1.700923 2.262838 -v 0.058312 0.055108 0.021584 -vn 3.446926 -0.566987 5.085696 -v 0.025048 0.061820 0.045199 -vn 1.459877 1.264210 3.974623 -v -0.035351 0.158370 0.004120 -vn 3.116712 -0.945555 5.330387 -v 0.019016 0.062966 0.048660 -vn 3.611860 -1.847927 4.557545 -v 0.031160 0.057816 0.040002 -vn 3.349772 0.698855 4.390854 -v 0.054587 0.062151 0.028386 -vn 2.518140 -1.321157 5.358851 -v 0.010261 0.064409 0.054523 -vn 3.888513 0.954593 3.914598 -v -0.062627 0.137487 0.035970 -vn 2.919071 2.362424 4.555372 -v -0.069222 0.141816 0.045434 -vn 4.796776 1.897909 3.501544 -v -0.013596 0.181454 -0.022994 -vn 3.674356 -0.616925 4.606893 -v 0.035195 0.064774 0.038909 -vn 2.718727 3.138192 3.924523 -v 0.054990 0.068160 0.025302 -vn 2.996061 -1.577720 5.122630 -v 0.011936 0.061458 0.051702 -vn -5.740675 -1.293159 -0.271905 -v -0.089676 0.089115 0.011992 -vn 2.970165 -1.405626 5.250880 -v 0.013992 0.065896 0.052786 -vn 3.635901 -1.895913 3.365978 -v -0.065901 0.117453 0.050750 -vn 1.157068 3.437505 4.681839 -v 0.044728 0.068216 0.025148 -vn 4.026200 0.184060 4.141020 -v -0.037332 0.163692 -0.000866 -vn 2.183929 1.404454 4.063305 -v -0.028334 0.178587 -0.005976 -vn 4.549428 -0.211835 4.307021 -v 0.036982 0.071601 0.036530 -vn 5.397528 0.625255 2.995015 -v 0.044153 0.070434 0.024656 -vn 3.102727 1.753740 3.351305 -v -0.021751 0.183608 -0.012089 -vn 3.687994 -0.852355 4.950009 -v 0.032313 0.071764 0.040470 -vn 3.823063 -1.369466 4.693820 -v 0.020799 0.068880 0.049069 -vn 3.454532 -0.920757 4.808846 -v 0.025894 0.070197 0.043900 -vn -5.001193 -3.552527 1.275367 -v -0.081235 0.076312 0.023820 -vn 5.398329 2.428570 -1.338366 -v 0.041795 0.102982 0.002083 -vn 4.136786 -0.184161 4.312547 -v -0.029255 0.170727 -0.008452 -vn 2.976370 2.577192 4.831935 -v 0.026315 0.103891 0.039915 -vn 3.795969 -1.007732 4.672986 -v 0.031169 0.075669 0.043029 -vn 4.578857 -0.401115 4.154040 -v 0.036619 0.076278 0.037820 -vn 5.670611 0.331080 2.481464 -v 0.043883 0.083725 0.026448 -vn 4.409471 0.200501 4.062643 -v -0.049598 0.149922 0.011833 -vn 3.761862 -0.310466 2.485315 -v -0.012650 0.164076 -0.012638 -vn 2.454954 1.926445 5.295071 -v -0.046165 0.159492 0.007645 -vn 2.300028 -0.675841 5.773763 -v 0.013192 0.074119 0.054188 -vn 2.147017 0.188036 5.444361 -v 0.016207 0.078297 0.054029 -vn 2.659225 1.062280 5.424681 -v 0.022384 0.084471 0.049678 -vn 5.231865 0.156885 3.342188 -v 0.040548 0.080473 0.032775 -vn -5.219738 -1.187020 -2.200430 -v -0.085564 0.109959 0.006691 -vn 2.040293 1.345493 3.748146 -v -0.025997 0.159898 -0.000378 -vn 3.752166 -0.869909 4.866561 -v 0.025611 0.077034 0.047414 -vn 4.274515 2.152036 3.950105 -v -0.055193 0.137655 0.031052 -vn 4.778208 0.553183 3.962800 -v -0.056663 0.142334 0.031414 -vn 1.895524 0.267344 5.952645 -v 0.008797 0.080996 0.055269 -vn 2.685038 2.647466 4.793501 -v -0.026675 0.167340 -0.009261 -vn 2.572105 -2.557608 4.363059 -v -0.063136 0.113212 0.037309 -vn 3.314872 -0.099920 4.622317 -v -0.039398 0.165215 0.003096 -vn 1.616328 4.517775 3.934582 -v -0.023048 0.163626 -0.007644 -vn 2.762914 2.599517 4.676960 -v 0.027285 0.108584 0.037517 -vn 1.206805 -3.498194 4.227875 -v -0.069801 0.109329 0.037844 -vn 3.747622 1.234770 4.658076 -v -0.064598 0.144892 0.039496 -vn 4.592640 -0.224758 4.169909 -v -0.019936 0.179943 -0.016051 -vn 2.656923 1.333205 5.377681 -v 0.016104 0.085391 0.051297 -vn 4.139162 -0.025463 4.707720 -v 0.030880 0.082256 0.042955 -vn 5.143444 1.020655 3.310843 -v -0.047061 0.124863 0.028049 -vn 2.915268 0.626547 4.412439 -v -0.067391 0.122228 0.052778 -vn 1.045301 4.878822 3.709212 -v -0.030525 0.161569 -0.002387 -vn 1.642749 3.110179 5.004900 -v 0.017862 0.118015 0.035502 -vn 3.222754 2.483788 4.568747 -v -0.057193 0.130341 0.038022 -vn 3.760767 0.259540 4.920477 -v 0.026169 0.083575 0.047343 -vn 3.667639 0.150010 4.474477 -v 0.033382 0.088441 0.042187 -vn 5.020711 0.093914 3.747091 -v 0.037217 0.086010 0.036563 -vn 3.072363 0.579712 4.791952 -v -0.042036 0.155272 0.006780 -vn 4.528713 1.753974 3.932786 -v -0.067517 0.132815 0.046060 -vn 2.466482 0.892711 5.306850 -v 0.011669 0.088506 0.054544 -vn 2.999462 2.223691 4.362226 -v 0.014667 0.092195 0.051846 -vn 6.091884 0.872875 -0.408722 -v 0.045858 0.090064 0.006853 -vn 3.610504 -0.173509 4.571314 -v -0.055584 0.122895 0.039367 -vn 5.035666 2.635417 2.047851 -v 0.038141 0.107162 0.025644 -vn 3.822092 1.666329 4.678015 -v -0.015537 0.176512 -0.019205 -vn 3.236660 3.429851 3.682322 -v 0.029226 0.113282 0.032753 -vn -5.756518 1.095186 0.663424 -v -0.093174 0.123594 0.039183 -vn 2.835000 -2.559091 4.779950 -v -0.028891 0.158063 0.000681 -vn 4.107653 1.648150 4.321459 -v -0.061559 0.126903 0.042100 -vn 2.446284 1.998310 3.284959 -v -0.047009 0.120810 0.027667 -vn 3.311918 1.683383 4.945812 -v 0.027912 0.093581 0.044346 -vn 1.991673 1.444735 5.526487 -v -0.072818 0.129250 0.052148 -vn 1.689075 0.715737 5.170299 -v -0.054867 0.114510 0.034993 -vn 4.560048 1.535726 3.636522 -v 0.036564 0.093872 0.037137 -vn 5.636822 1.471644 0.434213 -v -0.061496 0.161015 -0.029952 -vn 2.120607 -5.426591 -1.584703 -v 0.020578 0.035131 -0.002113 -vn 2.587788 -5.182961 -1.866215 -v 0.040168 0.039433 0.002850 -vn 2.956754 -4.936349 -0.780024 -v 0.018618 0.035206 -0.007891 -vn 3.954210 2.893853 -0.481261 -v -0.011316 0.182508 -0.027395 -vn -0.360845 0.566247 -6.221670 -v -0.043479 0.095813 -0.022175 -vn 4.103764 -3.880840 -2.196748 -v 0.023103 0.042010 -0.008406 -vn 2.893077 -4.532371 -1.058532 -v 0.017395 0.035068 -0.014539 -vn 1.802929 -4.133441 -2.626518 -v 0.013275 0.034932 -0.020460 -vn 4.464798 -3.195609 2.618988 -v 0.024751 0.041279 0.037482 -vn 3.837847 -1.567000 -3.464164 -v 0.020165 0.043510 -0.021471 -vn -4.605818 2.202359 -3.498247 -v -0.081165 0.108525 -0.002671 -vn 1.688255 0.159017 -2.029551 -v -0.060770 0.172871 -0.062223 -vn 3.539078 -4.996346 -0.345194 -v 0.049360 0.043275 0.010619 -vn 4.485715 -3.029796 -2.135710 -v 0.055521 0.050320 0.003859 -vn 3.373318 -4.502402 -2.338031 -v 0.048670 0.044885 0.002308 -vn 4.264922 -3.808944 -2.261333 -v 0.022558 0.044480 -0.016002 -vn 5.124133 0.612471 1.751263 -v -0.008995 0.170743 -0.022234 -vn 5.502688 -1.333245 1.725175 -v -0.049245 0.144438 0.008739 -vn 3.702993 -3.710806 2.379018 -v -0.043032 0.147796 0.004361 -vn 4.623991 -3.363169 1.370073 -v 0.056859 0.050577 0.018961 -vn 3.899296 -3.995941 -2.214014 -v 0.027089 0.047336 -0.015999 -vn 4.542627 -0.345970 -1.289463 -v -0.008485 0.173924 -0.027117 -vn -0.952284 2.145038 -5.539727 -v -0.027238 0.104761 -0.023147 -vn 4.608087 2.242475 3.513731 -v 0.036337 0.100368 0.033065 -vn 5.004035 -3.238740 -0.417539 -v 0.057477 0.050787 0.011439 -vn 4.788811 -3.148919 -2.504355 -v 0.031618 0.051716 -0.010657 -vn 6.038418 0.247692 0.386332 -v -0.061439 0.155996 -0.022037 -vn -5.708359 -0.430176 0.328975 -v -0.095150 0.122524 0.020828 -vn 3.539445 -0.201987 -4.307279 -v 0.053738 0.058051 -0.003026 -vn 4.483680 -2.341901 -3.604957 -v 0.031438 0.056335 -0.014912 -vn -4.854239 1.421386 -3.443982 -v -0.083446 0.100310 -0.004261 -vn 6.121156 1.186982 0.486103 -v 0.044971 0.092888 0.014163 -vn 5.820365 -0.936269 -0.152972 -v 0.061018 0.059729 0.012378 -vn 5.186820 -0.307332 -2.523736 -v 0.059284 0.060697 0.004208 -vn 6.164331 -0.164121 0.580500 -v -0.061739 0.168050 -0.053719 -vn 5.043853 -1.714810 -3.085265 -v 0.038215 0.062163 -0.010182 -vn 4.316995 -2.122327 -3.743112 -v 0.033799 0.059079 -0.014761 -vn 5.058934 2.038069 0.117292 -v 0.060856 0.068056 0.013685 -vn 4.170927 -0.877568 -4.469988 -v 0.029676 0.061299 -0.019624 -vn 5.837342 0.404021 -1.532704 -v 0.044685 0.088766 -0.001641 -vn 5.811692 1.502155 1.111640 -v -0.062517 0.168278 -0.048159 -vn 5.129776 -0.428435 -3.008827 -v 0.040553 0.069487 -0.009589 -vn 3.831105 3.942505 -1.329023 -v 0.058096 0.070952 0.008360 -vn 5.235800 2.117617 2.660476 -v -0.052670 0.137724 0.027072 -vn 4.402230 -0.589750 -4.344035 -v 0.032905 0.068512 -0.017939 -vn 4.086227 -0.594648 -4.540856 -v 0.029676 0.072549 -0.021977 -vn 6.005601 0.901536 -0.036226 -v -0.062119 0.163568 -0.039854 -vn 0.361682 5.859539 -1.784732 -v -0.028699 0.124174 0.000045 -vn 2.901078 -4.465433 2.349806 -v -0.033265 0.152755 -0.000935 -vn 5.316133 3.002438 1.399777 -v -0.049588 0.137208 0.019728 -vn -5.332762 -2.716557 0.415736 -v -0.091761 0.117734 0.028047 -vn 5.315184 0.532222 -2.842642 -v -0.050570 0.139278 0.002373 -vn -5.511374 0.018763 -2.576079 -v -0.092000 0.124335 0.007559 -vn 5.999914 -1.516922 -0.543700 -v -0.062895 0.160255 -0.045117 -vn -4.153564 -3.020171 -3.553796 -v -0.086854 0.115536 0.002130 -vn 5.588541 -0.518128 -2.781567 -v 0.042336 0.078603 -0.005669 -vn -4.655971 -3.245469 -0.006853 -v -0.092211 0.113719 0.015803 -vn -1.973225 -1.888964 3.544886 -v -0.060160 0.036142 0.045824 -vn 5.871296 0.943136 1.559232 -v -0.052327 0.144649 0.017802 -vn 5.787077 0.916558 -1.813593 -v 0.046325 0.073679 0.004710 -vn 5.065163 1.502548 -2.815784 -v 0.041690 0.091117 -0.008432 -vn -3.548909 -4.646294 -1.599968 -v -0.073040 0.142854 -0.008478 -vn -5.049344 -2.277116 1.327268 -v -0.086717 0.109949 0.017997 -vn 5.576437 -2.090809 -0.868370 -v -0.062831 0.146571 -0.013245 -vn -3.426531 -4.554816 1.371157 -v -0.071194 0.062750 0.017971 -vn 5.836531 0.112567 -1.917511 -v 0.045495 0.079596 0.000727 -vn 4.772102 -0.640213 -3.815825 -v 0.037230 0.076270 -0.012165 -vn 6.067169 0.559199 1.233306 -v 0.045180 0.085436 0.021900 -vn 5.831976 -0.068505 -2.298472 -v 0.043601 0.081985 -0.003165 -vn 4.857678 -0.777680 -3.402729 -v 0.039433 0.082994 -0.013421 -vn -6.105674 0.694372 0.053635 -v -0.089655 0.097872 0.016003 -vn -5.150023 0.679012 -3.229882 -v -0.084996 0.143869 0.006146 -vn 6.026113 0.718501 1.335790 -v 0.046452 0.075105 0.017808 -vn -5.809597 1.531652 -1.164955 -v -0.092602 0.130410 0.011750 -vn 4.952139 3.525631 1.318580 -v -0.064530 0.169186 -0.041589 -vn 5.610267 -1.978293 -0.980791 -v -0.062167 0.154307 -0.031775 -vn 1.198130 5.856568 1.663475 -v -0.031334 0.125679 0.017991 -vn -2.074432 3.369980 -1.806647 -v -0.072326 0.181192 -0.055142 -vn 1.407635 5.070174 1.212614 -v -0.069451 0.181345 -0.054185 -vn -0.994283 3.704290 4.178440 -v -0.043952 0.167869 0.003076 -vn -2.597573 5.270875 -1.373814 -v -0.083523 0.153771 0.011018 -vn 0.391499 6.066924 0.807585 -v -0.065965 0.156338 0.023925 -vn 0.405464 4.692683 2.791539 -v 0.052485 0.072116 0.022090 -vn 4.148013 3.943976 2.393467 -v -0.066355 0.174273 -0.047584 -vn 1.271963 5.205061 2.476993 -v -0.060944 0.153978 0.031726 -vn 0.160968 6.253486 -0.391569 -v -0.066162 0.156175 0.014162 -vn 2.563544 5.060296 2.670963 -v -0.071352 0.176337 -0.045404 -vn -1.125632 5.112562 1.877706 -v -0.073963 0.179891 -0.049902 -vn 5.669150 1.486904 1.713825 -v -0.051657 0.149961 0.015696 -vn 1.940121 4.814428 2.814738 -v 0.014120 0.127185 0.027892 -vn -3.937955 -4.448478 0.762496 -v -0.084427 0.111720 0.028693 -vn 1.432097 3.894052 -4.037507 -v -0.039787 0.123160 -0.010744 -vn -4.956427 1.138147 -3.530294 -v -0.081741 0.145435 0.000182 -vn -4.591177 -0.424988 -1.796376 -v -0.075599 0.151048 -0.009429 -vn -5.777192 0.430090 -2.157034 -v -0.086395 0.096987 0.000674 -vn 1.690336 3.668887 -0.658081 -v -0.014641 0.185918 -0.024973 -vn -4.260851 2.509016 -1.388882 -v -0.090869 0.150100 0.013951 -vn -4.148738 3.257659 1.423426 -v -0.078250 0.175147 -0.044456 -vn -0.853663 5.173003 3.055238 -v -0.009294 0.099140 0.050199 -vn 0.187851 4.764116 3.959755 -v 0.001684 0.125513 0.032285 -vn 1.105869 2.640572 0.918792 -v -0.017752 0.187453 -0.018494 -vn -0.424456 5.379393 2.472621 -v -0.073737 0.174083 -0.038885 -vn 1.356126 4.555872 3.201677 -v -0.043564 0.122982 0.024784 -vn -5.423351 -1.898461 -0.394247 -v -0.092777 0.117053 0.034803 -vn 0.860369 4.262375 4.025424 -v -0.068912 0.150059 0.038982 -vn 0.420919 6.169803 0.687315 -v -0.057871 0.155743 0.012829 -vn -0.154562 5.317085 3.017347 -v -0.028710 0.121121 0.025743 -vn 1.937456 5.688474 1.040771 -v -0.069086 0.156094 0.000189 -vn -2.485508 4.425166 -0.301309 -v -0.020906 0.186391 -0.017334 -vn 2.933247 5.172490 1.769837 -v -0.069242 0.172311 -0.038155 -vn -0.605938 5.270441 2.747777 -v -0.071882 0.161382 -0.009418 -vn 1.156050 5.432137 -1.451054 -v 0.054112 0.073180 0.009224 -vn 2.145806 5.425278 0.330070 -v 0.047882 0.073529 0.014713 -vn 5.244991 2.619354 1.730502 -v -0.046363 0.131718 0.021925 -vn 5.056289 3.493795 -0.723384 -v 0.037029 0.111384 0.004942 -vn 2.853272 5.083090 -1.718533 -v 0.020200 0.126017 0.001594 -vn -5.254146 -0.613127 -0.482019 -v -0.076308 0.149985 -0.015676 -vn 1.355125 4.720862 1.437473 -v 0.053961 0.073685 0.018761 -vn 0.234429 5.665096 2.150027 -v 0.004460 0.130159 0.024964 -vn 1.423464 5.984650 0.624725 -v -0.035611 0.127806 0.012376 -vn -2.960577 4.792154 2.219521 -v -0.074001 0.157470 -0.004167 -vn 3.066196 4.897271 -1.422764 -v -0.045250 0.129319 0.003323 -vn -1.129174 4.554727 1.843489 -v -0.024152 0.184139 -0.011798 -vn 2.415711 4.752096 3.229428 -v 0.017505 0.124269 0.028518 -vn -0.306560 5.678154 2.418344 -v -0.070930 0.153929 0.032368 -vn 4.637616 1.903230 2.104799 -v 0.059501 0.067622 0.020380 -vn 0.499025 5.654412 2.110123 -v -0.037173 0.126552 0.019782 -vn -0.381038 6.195147 0.034129 -v -0.071667 0.155616 0.005508 -vn -4.300800 0.071478 -3.924859 -v -0.080277 0.111457 -0.001608 -vn 0.482006 4.396123 3.775440 -v -0.001152 0.098689 0.051948 -vn -3.958242 4.197694 -2.017481 -v -0.027487 0.181071 -0.014028 -vn -0.016262 5.308342 2.245415 -v -0.071988 0.169123 -0.024625 -vn 2.916259 4.139410 2.099079 -v -0.043609 0.126626 0.018789 -vn -3.809404 -0.618573 -4.535503 -v -0.071170 0.178641 -0.056502 -vn 2.010828 4.065274 3.515700 -v 0.021124 0.121417 0.031710 -vn -1.718535 4.786687 2.206586 -v -0.029362 0.180309 -0.007715 -vn 3.676759 2.873815 1.512413 -v -0.054698 0.152990 0.027194 -vn -3.197552 5.253566 -0.401559 -v -0.076599 0.154132 0.001804 -vn 1.663596 4.604503 3.230547 -v -0.054148 0.155336 0.011804 -vn 3.578112 4.724551 0.387337 -v -0.043750 0.129665 0.011703 -vn 4.363053 4.368498 0.037657 -v 0.031009 0.119396 0.011805 -vn 3.538241 5.021770 -0.639298 -v 0.025235 0.123945 0.007875 -vn 0.334614 6.097376 -0.181203 -v -0.028928 0.125631 0.009146 -vn 3.640355 4.399567 1.614547 -v -0.066692 0.168011 -0.027462 -vn -0.233089 5.905298 -1.594494 -v 0.001229 0.130758 0.001703 -vn -5.948376 1.237487 -1.220472 -v -0.087983 0.102812 0.008913 -vn -3.517885 4.290505 -1.612052 -v -0.038158 0.174988 -0.008662 -vn 2.171919 5.800751 -0.228056 -v 0.014571 0.129719 0.010288 -vn -3.762906 -2.616167 1.034528 -v -0.072508 0.035045 0.006886 -vn -3.539536 -0.905314 3.258482 -v -0.068612 0.035925 0.013364 -vn -4.165895 -0.824512 -2.265473 -v -0.064587 0.035434 0.024123 -vn -4.860264 -0.362750 1.628607 -v -0.066421 0.036780 0.037772 -vn -3.774728 0.915285 3.995933 -v -0.033256 0.040429 0.050438 -vn -2.161576 0.767358 4.945210 -v -0.028793 0.040250 0.053660 -vn 0.595360 -2.194332 4.492339 -v -0.022254 0.036397 0.054172 -vn -2.468129 0.643499 -5.420550 -v -0.057178 0.095339 -0.021407 -vn -4.664717 0.842293 3.712944 -v -0.063719 0.035889 0.018077 -vn -4.510514 3.128947 0.527595 -v -0.060660 0.037999 0.020107 -vn -5.347980 1.948649 -1.580589 -v -0.065758 0.039184 0.028824 -vn -3.060553 4.016160 1.511542 -v -0.061581 0.046403 0.038949 -vn -4.739681 0.941019 3.872519 -v -0.036281 0.040350 0.046080 -vn -4.663043 1.682945 1.289949 -v -0.072582 0.038446 0.007256 -vn -5.270750 3.327163 -0.653439 -v -0.071075 0.039616 0.003991 -vn -3.761410 1.041319 4.825982 -v -0.075463 0.097646 0.038226 -vn -3.695707 2.431126 3.531357 -v -0.061670 0.042861 0.042835 -vn -0.926462 3.391644 4.298962 -v -0.012919 0.100443 0.044281 -vn -3.152135 3.928678 3.401736 -v -0.065104 0.042809 0.011917 -vn -2.496847 2.449704 4.654127 -v -0.081575 0.134705 0.050585 -vn -3.702577 4.093661 2.389956 -v -0.057810 0.047856 0.008749 -vn -3.787189 3.412211 3.466524 -v -0.034397 0.044450 0.045915 -vn -3.392372 4.594159 1.498398 -v -0.049347 0.166351 0.000744 -vn -3.013031 -3.444648 3.876493 -v -0.071883 0.073139 0.035410 -vn -4.502184 2.427100 2.599777 -v -0.087491 0.141165 0.040141 -vn -3.435941 3.755981 3.232703 -v -0.022403 0.093695 0.050239 -vn -2.522241 4.493736 3.017286 -v -0.050515 0.049618 0.036537 -vn -5.325298 -1.107564 1.683973 -v -0.089312 0.090546 0.021851 -vn -3.868876 3.957101 2.197943 -v -0.075877 0.162385 -0.014929 -vn -2.282869 5.117870 2.484348 -v -0.029778 0.050450 0.042358 -vn -0.348236 3.565649 4.638061 -v -0.046632 0.163856 0.005708 -vn -2.817534 -0.429144 4.903159 -v -0.030127 0.088091 0.043822 -vn -4.056412 -1.000199 4.171714 -v -0.078787 0.085191 0.036634 -vn -4.156331 1.886567 0.796096 -v -0.050132 0.047725 0.016827 -vn -3.753857 1.195405 -4.626152 -v -0.044383 0.165379 -0.009203 -vn -4.712823 3.046287 1.897702 -v -0.051813 0.051098 0.031670 -vn -5.269024 -0.563730 2.661666 -v -0.083520 0.108044 0.025686 -vn -4.171581 -0.643931 3.802685 -v -0.025083 0.082194 0.053862 -vn -3.767498 0.363726 4.829728 -v -0.046851 0.055265 0.037404 -vn -3.016042 2.729937 3.080582 -v -0.023529 0.051721 0.042321 -vn -3.277483 -0.093411 0.873466 -v -0.050184 0.054513 0.015440 -vn -4.665541 -0.523760 2.388376 -v -0.092681 0.120446 0.043376 -vn -5.298493 0.931009 1.316224 -v -0.091732 0.145774 0.025047 -vn -3.483220 -1.863635 -0.025102 -v -0.052279 0.056758 0.020813 -vn -3.210667 -1.460555 4.831923 -v -0.017320 0.061776 0.052119 -vn -4.893488 -1.387324 -0.762990 -v -0.074839 0.150076 -0.030050 -vn -4.937909 -0.317477 3.779040 -v -0.082227 0.090383 0.032092 -vn -3.986070 -2.761930 2.931170 -v -0.051912 0.061602 0.030372 -vn -1.988187 1.129251 5.577729 -v -0.070160 0.097143 0.041714 -vn -5.122376 -1.085538 3.355680 -v -0.022767 0.062836 0.044230 -vn -1.235594 -0.368716 4.927263 -v -0.079813 0.127549 0.053639 -vn -2.906489 0.634298 -1.399307 -v -0.077317 0.177933 -0.051513 -vn -3.357311 -2.565623 3.593840 -v -0.088870 0.116757 0.046080 -vn -4.528044 -1.804694 3.807382 -v -0.049720 0.063025 0.034634 -vn -3.442483 -0.220479 5.132259 -v -0.085947 0.124511 0.048612 -vn -4.691182 0.606698 3.817549 -v -0.083826 0.096831 0.030757 -vn -1.890426 -1.078978 4.611037 -v -0.031068 0.081841 0.041494 -vn -3.309379 0.103908 -4.997811 -v -0.075107 0.113630 -0.006024 -vn -1.907898 4.157027 3.646714 -v -0.016614 0.095750 0.052691 -vn -3.481753 1.764462 4.257040 -v -0.023684 0.086888 0.054410 -vn -2.924878 4.987013 1.872182 -v -0.058430 0.157205 0.007613 -vn -0.254358 -0.295486 -6.251141 -v -0.052027 0.088561 -0.021977 -vn -4.644541 1.495275 3.463665 -v -0.087371 0.130918 0.046734 -vn -2.211095 0.851495 -5.622077 -v -0.071457 0.115205 -0.007847 -vn -1.778540 -2.465528 5.239796 -v -0.080527 0.116727 0.048561 -vn -5.506599 1.378833 2.051031 -v -0.088232 0.100321 0.022327 -vn -2.927709 0.157523 5.364776 -v -0.071665 0.090209 0.041841 -vn -0.277282 2.198507 -5.762552 -v -0.040638 0.107702 -0.019971 -vn -4.244422 -1.972437 3.921573 -v -0.022796 0.074705 0.052353 -vn -5.297521 -1.968002 2.745181 -v -0.026444 0.075095 0.045684 -vn -2.520885 -1.955608 5.220235 -v -0.068977 0.081628 0.041791 -vn -4.462826 -1.842593 -2.095818 -v -0.045100 0.034475 -0.023192 -vn -5.717920 2.101159 0.381723 -v -0.093349 0.130605 0.021401 -vn -4.685751 1.926454 -3.036557 -v -0.061763 0.038716 0.023717 -vn -5.473397 -1.810462 -2.329371 -v -0.071489 0.166078 -0.046220 -vn -5.058003 1.977053 -2.517068 -v -0.044718 0.038309 -0.022782 -vn -4.059040 3.185980 -3.288708 -v -0.060254 0.040382 0.021811 -vn -5.475415 -1.131330 -2.748893 -v -0.068504 0.168672 -0.053981 -vn -4.114663 -1.361141 -1.764503 -v -0.078775 0.173264 -0.046197 -vn -3.873200 2.427289 -3.809093 -v -0.041897 0.038847 -0.026470 -vn -5.258497 0.701612 -3.319133 -v -0.088313 0.129687 0.002588 -vn -3.273174 3.867993 -2.517677 -v -0.040571 0.045501 -0.021744 -vn -3.982594 3.759423 -1.323691 -v -0.069088 0.043131 0.001424 -vn -3.280848 4.328462 0.183596 -v -0.056003 0.042040 0.019429 -vn -4.137817 3.685533 -0.408955 -v -0.063781 0.044721 0.032596 -vn -4.114463 3.279706 -2.182618 -v -0.063794 0.042954 0.028103 -vn -4.221366 -3.469511 -2.634172 -v -0.073957 0.165765 -0.040067 -vn -4.887263 -2.016220 -2.155654 -v -0.091421 0.115996 0.007407 -vn -5.472220 2.249179 -1.685037 -v -0.046069 0.039473 -0.017248 -vn -3.252862 4.562538 -2.680660 -v -0.057799 0.046964 -0.002707 -vn -3.109763 4.453841 0.972929 -v -0.067150 0.045233 0.006394 -vn -3.794018 4.756464 -0.582268 -v -0.054828 0.048688 0.030215 -vn -4.388919 3.016360 -2.412828 -v -0.053441 0.162029 -0.001213 -vn -4.494921 3.212618 -2.236346 -v -0.053216 0.046657 0.023316 -vn -2.034922 5.720964 1.318421 -v -0.053382 0.049317 0.035167 -vn -3.482963 -3.617813 -3.614501 -v -0.074107 0.171918 -0.047624 -vn -3.221081 2.060237 -4.195560 -v -0.027558 0.049037 -0.024812 -vn -2.670611 5.402469 -1.596012 -v -0.032408 0.049091 -0.019049 -vn -4.321980 3.752576 -0.910490 -v -0.058354 0.048352 0.002063 -vn -4.069468 0.745106 -4.370874 -v -0.079702 0.139501 -0.004318 -vn -5.546577 1.660439 1.179043 -v -0.078972 0.166589 -0.031500 -vn -4.486548 2.297696 -1.602006 -v -0.030923 0.050998 -0.014993 -vn -5.449053 0.516589 2.910882 -v -0.055477 0.053838 0.008835 -vn -6.115006 0.323959 -0.510519 -v -0.052227 0.053524 0.025391 -vn -2.418352 0.199386 -5.111060 -v -0.065675 0.176297 -0.060702 -vn -5.130173 1.754356 -2.499742 -v -0.029589 0.050777 -0.020655 -vn -5.198124 -0.841899 -3.250017 -v -0.054647 0.055404 -0.004958 -vn -5.686954 -1.852813 -0.343353 -v -0.057533 0.056760 0.003189 -vn -5.937036 -0.841103 -1.788525 -v -0.030896 0.056784 -0.016670 -vn -2.924379 -5.292533 -0.953841 -v -0.059570 0.059136 0.004220 -vn -3.257044 -2.732197 1.468646 -v -0.055125 0.056655 0.010047 -vn -5.735948 1.283473 -1.637237 -v -0.089346 0.137701 0.012789 -vn -4.483919 -1.670480 -1.181222 -v -0.079310 0.167698 -0.037783 -vn -6.087029 1.140606 0.664260 -v -0.091950 0.127848 0.031773 -vn 1.048131 1.323979 -6.040297 -v 0.001459 0.103554 -0.022208 -vn -2.424145 -1.782817 -2.746691 -v -0.042156 0.034149 -0.027953 -vn -5.591403 1.772020 1.334513 -v -0.076973 0.157861 -0.011049 -vn -1.509918 -3.821166 -4.649479 -v -0.016632 0.166879 -0.019839 -vn -4.426495 -1.006108 -2.875471 -v -0.068878 0.157607 -0.053241 -vn -4.306664 -1.653861 -3.993627 -v -0.025959 0.056063 -0.028477 -vn -5.713107 -1.408136 -2.082056 -v -0.028993 0.059922 -0.023623 -vn -3.838073 2.953544 -3.793759 -v -0.040396 0.171737 -0.009624 -vn -5.928720 1.730234 0.949654 -v -0.090167 0.132068 0.034669 -vn -0.469121 5.483239 -2.956070 -v -0.025370 0.121886 -0.007301 -vn -5.238899 -2.283546 -2.428878 -v -0.032937 0.061785 -0.014457 -vn 1.374102 -3.257416 -4.076581 -v -0.019791 0.034699 -0.027622 -vn -3.706697 4.090268 -1.909637 -v -0.058744 0.157320 0.002895 -vn 4.055600 2.161165 -4.162670 -v 0.033895 0.095496 -0.013888 -vn -3.583514 -4.547219 -1.879148 -v -0.071104 0.064618 0.001461 -vn -4.383003 2.484955 -3.276150 -v -0.085939 0.138620 0.002605 -vn -5.313048 -1.680559 -2.580730 -v -0.029027 0.063647 -0.028167 -vn 5.591245 -1.034597 -2.625534 -v 0.041889 0.065322 -0.003134 -vn -0.006474 2.923205 -5.425916 -v -0.043650 0.116244 -0.015638 -vn -4.964347 -1.995424 -3.124882 -v -0.029045 0.067975 -0.030204 -vn 0.356758 5.097700 -3.118715 -v -0.044443 0.126214 -0.007543 -vn 2.688652 1.928320 -4.775914 -v 0.012771 0.090022 -0.030352 -vn -4.842363 1.677036 -2.727569 -v -0.089617 0.133793 0.004686 -vn -3.996927 -4.469086 -1.802557 -v -0.075737 0.070220 -0.000006 -vn -3.926754 3.793914 -1.588145 -v -0.046374 0.168998 -0.004678 -vn -3.338250 -1.447873 -5.065185 -v -0.035549 0.073546 -0.018811 -vn -3.618954 -3.751968 -2.479409 -v -0.076740 0.072279 -0.005263 -vn -5.081039 -2.616633 -2.003323 -v -0.082266 0.076728 0.000412 -vn -5.055360 -3.541048 0.774614 -v -0.082193 0.075612 0.016612 -vn -4.396467 1.090321 -3.067734 -v -0.089346 0.148423 0.010296 -vn -5.904637 1.286613 0.316107 -v -0.090520 0.135806 0.020071 -vn -6.020581 0.206336 -1.011939 -v -0.073001 0.155262 -0.031430 -vn -4.909943 -2.881738 -1.663398 -v -0.074173 0.159711 -0.030151 -vn -4.318497 2.732601 -2.989066 -v -0.081797 0.150429 0.002131 -vn 2.781409 1.281605 -5.311362 -v 0.026497 0.089950 -0.022537 -vn -6.034796 -1.082136 -0.627063 -v -0.076930 0.153451 -0.009182 -vn -5.772584 -0.960103 -1.792278 -v -0.033418 0.076311 -0.027297 -vn 0.897459 1.608931 -5.946432 -v 0.006391 0.109745 -0.020190 -vn -5.333162 -2.438507 -1.964347 -v -0.082992 0.080904 -0.000199 -vn -5.519381 -2.090490 -0.800946 -v -0.085986 0.079884 0.008747 -vn -5.111777 -2.405573 0.665693 -v -0.086312 0.079733 0.016721 -vn -4.123626 -0.720675 -4.267666 -v -0.075420 0.143697 -0.006221 -vn -5.147453 -0.724552 -0.618276 -v -0.075903 0.150586 -0.020560 -vn -5.008947 -0.725029 -3.063275 -v -0.031744 0.077065 -0.032159 -vn -4.839126 0.811560 -3.566641 -v -0.033376 0.084634 -0.025796 -vn -5.744068 -2.265728 -0.512528 -v -0.086610 0.083724 0.008909 -vn -5.549580 -1.993589 1.999849 -v -0.085174 0.084182 0.024246 -vn -3.992902 3.623828 2.488717 -v -0.086749 0.147938 0.032787 -vn 4.300764 4.026931 -1.587035 -v 0.032397 0.116112 0.000109 -vn -5.829935 -2.012132 0.503632 -v -0.086908 0.084821 0.015355 -vn -3.453119 4.511027 0.799767 -v -0.088933 0.152068 0.020562 -vn 3.538670 0.543402 -5.141011 -v 0.029339 0.085435 -0.020728 -vn -5.544555 1.012051 -2.474277 -v -0.032198 0.081905 -0.030406 -vn -5.024198 -0.597393 -2.880268 -v -0.078821 0.084413 -0.010431 -vn -5.039504 -1.887022 -2.426510 -v -0.084719 0.084231 -0.002304 -vn -5.206524 -1.673001 -1.471460 -v -0.087722 0.085773 0.003947 -vn -5.814547 -0.546874 -1.541406 -v -0.091350 0.144282 0.015552 -vn -5.037554 -0.979019 -1.151433 -v -0.074679 0.153763 -0.018695 -vn -5.636609 1.512849 0.279312 -v -0.091723 0.148034 0.019605 -vn -5.035193 -0.241919 -3.213140 -v -0.084103 0.091128 -0.005384 -vn -5.080513 -1.912513 -0.675305 -v -0.077751 0.156342 -0.017998 -vn -4.994093 -1.696939 -0.504176 -v -0.078594 0.161463 -0.026169 -vn -2.283951 -1.890689 -3.631057 -v -0.066289 0.162096 -0.058357 -vn -5.117329 -1.217907 -0.592836 -v -0.086325 0.109140 0.013157 -vn -5.651597 -0.446094 -2.420356 -v -0.086453 0.092696 0.002756 -vn -5.970924 0.239591 -1.763871 -v -0.088479 0.092153 0.006769 -vn -5.546511 0.352805 0.734027 -v -0.088759 0.137175 0.026184 -vn -4.668717 3.130157 1.437229 -v -0.078630 0.170060 -0.036333 -vn -6.066381 0.059517 -1.520558 -v -0.070421 0.158643 -0.046573 -vn -3.434155 1.435655 -4.016772 -v -0.028368 0.084787 -0.035920 -vn -2.994592 -0.028308 -5.281935 -v -0.073472 0.086184 -0.015753 -vn -3.841007 0.638149 -4.658265 -v -0.077540 0.094106 -0.012339 -vn -6.010108 0.479576 1.120610 -v -0.089567 0.141268 0.031055 -vn -5.672987 -1.492905 -0.791484 -v -0.076688 0.148007 -0.007775 -vn -5.372464 2.424027 -1.112657 -v -0.077171 0.152803 -0.002345 -vn -4.710579 1.066993 -3.952303 -v -0.082137 0.138333 -0.000940 -vn -0.213426 3.361748 -4.799176 -v 0.002527 0.116488 -0.018202 -vn 0.728090 3.685807 -4.417110 -v -0.000446 0.099976 -0.023363 -vn 2.045355 4.161624 -3.897235 -v 0.014292 0.121076 -0.011654 -vn -2.781228 3.648100 -3.078499 -v -0.016798 0.185640 -0.024425 -vn 1.858568 2.900206 -4.450298 -v 0.053184 0.066141 -0.000503 -vn -0.395873 1.983380 -5.587629 -v -0.053018 0.111057 -0.018184 -vn -3.089411 2.906894 -3.642850 -v -0.066550 0.040888 -0.005388 -vn 4.991074 3.107578 -2.158695 -v 0.035673 0.108457 -0.004447 -vn 1.274703 3.328767 -4.597878 -v -0.052004 0.127157 -0.004911 -vn -0.360586 3.859335 -4.161891 -v -0.012572 0.099355 -0.024359 -vn -0.591463 5.764256 -1.360058 -v -0.063471 0.154517 0.003520 -vn -0.422500 2.222833 -3.463716 -v -0.013693 0.183749 -0.028075 -vn -1.028085 0.664265 -5.943066 -v -0.056978 0.149608 -0.001673 -vn 1.913785 3.078248 -5.012307 -v 0.020577 0.106778 -0.016469 -vn 2.496604 4.063100 -3.460741 -v 0.047538 0.071364 0.004894 -vn 1.184667 3.066413 -5.118007 -v 0.013475 0.096868 -0.023723 -vn -1.333376 -2.067802 -3.582000 -v -0.051518 0.034089 -0.012737 -vn 2.482683 4.036065 -2.694777 -v -0.063224 0.151897 -0.000698 -vn 2.799732 1.795544 -4.876194 -v -0.059888 0.145116 -0.002657 -vn -1.498024 1.755812 -5.461653 -v -0.065792 0.117422 -0.008993 -vn 2.706365 3.291737 -4.546779 -v 0.025516 0.112749 -0.011402 -vn 4.044629 0.866009 -4.366913 -v 0.036900 0.087095 -0.016224 -vn 1.424047 3.721227 -4.223684 -v 0.003562 0.095315 -0.031202 -vn 0.612912 4.125947 -4.297299 -v 0.008165 0.120763 -0.014191 -vn 0.830109 2.468724 -5.525443 -v 0.013518 0.105177 -0.019403 -vn 1.803360 2.207177 -5.404728 -v 0.012725 0.111949 -0.018267 -vn 0.832823 3.064453 -4.700019 -v 0.006610 0.100083 -0.021669 -vn -1.429163 4.911261 -3.511646 -v -0.014096 0.121539 -0.009385 -vn -1.483934 3.453614 -4.238971 -v -0.024072 0.096002 -0.025153 -vn 3.230238 0.659414 -5.201444 -v -0.054766 0.142467 -0.001550 -vn 0.113363 3.503714 -5.046353 -v -0.034816 0.113775 -0.017117 -vn 0.035804 -0.814338 -5.430084 -v -0.033852 0.035368 -0.031063 -vn 3.062070 2.082974 -4.983165 -v 0.026890 0.096733 -0.019807 -vn -0.601313 4.196719 -4.442304 -v -0.011368 0.119297 -0.014104 -vn 0.513313 4.714929 -3.813689 -v -0.005209 0.096249 -0.031846 -vn -2.638945 2.340240 -5.073604 -v -0.053254 0.045200 -0.007933 -vn 0.848995 1.139777 -5.978301 -v -0.010635 0.085729 -0.038418 -vn -1.540852 2.887154 -4.533394 -v -0.034508 0.043483 -0.029064 -vn 3.105134 0.688823 -5.158306 -v -0.062065 0.140970 -0.006217 -vn 3.044163 2.536781 -3.017878 -v 0.057450 0.068677 0.003243 -vn -0.299660 3.681948 -4.895190 -v -0.018780 0.113551 -0.018448 -vn -0.407176 4.134895 -4.678569 -v -0.004136 0.116658 -0.016049 -vn 0.851834 2.701036 -4.981826 -v 0.017516 0.102001 -0.022248 -vn -2.216035 2.485471 -4.429418 -v -0.042107 0.047843 -0.011358 -vn -2.558224 4.656334 -2.788987 -v -0.036907 0.046150 -0.024111 -vn 1.535727 1.370578 -5.832878 -v 0.006856 0.088557 -0.032704 -vn 3.695477 2.026347 -4.413884 -v 0.033743 0.091737 -0.017191 -vn 2.909027 1.389085 -5.210147 -v 0.017026 0.086869 -0.028615 -vn 2.832581 4.446975 -2.939241 -v -0.047427 0.129259 -0.000267 -vn 2.608176 0.281911 -4.328668 -v 0.039365 0.058578 -0.004760 -vn -3.169234 1.804911 -3.823170 -v -0.048050 0.036456 -0.012517 -vn -0.369310 2.501712 -5.719421 -v -0.045563 0.111365 -0.017278 -vn 0.019763 2.731796 -4.914706 -v -0.006231 0.110966 -0.022038 -vn -0.217545 3.423695 -5.151430 -v -0.013133 0.112795 -0.018098 -vn -0.647178 5.330300 -2.991719 -v -0.013120 0.096813 -0.030895 -vn 3.284957 0.891990 -4.685681 -v -0.057428 0.138324 -0.005332 -vn 1.998423 1.052634 -5.750774 -v -0.059891 0.133375 -0.007156 -vn -0.545308 3.605767 -5.033075 -v -0.027254 0.111286 -0.017954 -vn 2.804976 2.643938 -4.801428 -v 0.026498 0.102745 -0.017429 -vn 4.881342 2.507492 -2.854039 -v -0.049012 0.133343 0.001109 -vn -0.694675 3.668845 -4.197451 -v -0.017438 0.098212 -0.024657 -vn 2.445362 2.256860 -4.331510 -v 0.044176 0.066522 0.000295 -vn -0.948689 -2.246251 -2.828583 -v -0.037263 0.033693 -0.030427 -vn 4.180097 1.869415 -3.717965 -v 0.035769 0.102443 -0.011071 -vn -0.327554 2.856490 -2.513732 -v -0.066354 0.180335 -0.059708 -vn 3.309835 2.043236 -4.429143 -v -0.052784 0.132589 -0.004133 -vn 1.597489 5.656709 -1.712684 -v -0.037473 0.127192 -0.001114 -vn 1.406698 5.621265 -1.636024 -v 0.010617 0.130194 0.002153 -vn -0.246060 2.983001 -5.295377 -v -0.021638 0.108672 -0.021670 -vn -2.155078 3.762225 -3.496416 -v -0.023139 0.092875 -0.034198 -vn -1.330705 6.015928 -1.051121 -v -0.018555 0.127641 0.005405 -vn 0.585591 2.845164 -5.482149 -v -0.001362 0.111962 -0.019876 -vn 3.851923 3.385612 -3.113956 -v 0.032018 0.112252 -0.007289 -vn -0.581315 4.679611 -4.107591 -v -0.022510 0.117696 -0.013437 -vn -0.564657 2.408912 -5.451535 -v -0.060099 0.120701 -0.009062 -vn -0.071736 3.507671 -4.837597 -v -0.013956 0.092589 -0.036088 -vn -0.796297 3.704876 -4.780685 -v -0.050540 0.120139 -0.013137 -vn 0.990625 5.003748 -3.513777 -v -0.032764 0.121061 -0.008637 -vn -0.647147 4.709548 -3.602543 -v -0.006674 0.125611 -0.008770 -vn 0.635920 5.135188 -3.281871 -v 0.006304 0.126625 -0.006712 -vn 3.048514 4.450634 -2.911419 -v 0.023744 0.120248 -0.005538 -vn 0.963798 2.520165 -5.229930 -v 0.049896 0.062123 -0.003628 -vn -1.404216 5.426106 -2.739289 -v -0.016137 0.125226 -0.003857 -vn -1.156643 5.755827 -1.845091 -v -0.008677 0.128549 -0.001683 -vn 0.537982 -5.591938 -1.850918 -v 0.005402 0.034121 -0.021028 -vn 0.561050 -3.609666 -4.534167 -v -0.001155 0.035187 -0.024178 -vn 0.910445 -3.387452 -5.058351 -v -0.010776 0.035392 -0.025187 -vn 1.029354 -2.215189 -5.054176 -v 0.005162 0.036596 -0.024174 -vn -2.664245 1.720335 -5.391418 -v -0.069064 0.101583 -0.014812 -vn -3.200632 1.141410 -4.532271 -v -0.067338 0.036440 -0.006804 -vn -2.470987 -2.136166 -2.061054 -v -0.068844 0.033871 -0.005651 -vn 2.158489 -5.130451 -2.847184 -v 0.023889 0.036159 -0.000526 -vn 0.721441 -0.527770 -6.143589 -v -0.006619 0.039887 -0.025918 -vn 1.049471 -2.837200 -4.609525 -v -0.025639 0.035034 -0.029055 -vn -2.950443 1.138120 -5.358952 -v -0.078607 0.132765 -0.005546 -vn -1.291233 -2.298125 -3.135402 -v -0.063059 0.033881 -0.008786 -vn 1.753909 -4.266781 -3.657057 -v 0.036740 0.040222 -0.001837 -vn 1.528978 -2.373367 -5.265629 -v -0.016949 0.036119 -0.027097 -vn 1.698999 -2.216789 -5.567635 -v 0.012593 0.039094 -0.022718 -vn 0.732738 -2.254253 -5.222185 -v -0.004555 0.042975 -0.025542 -vn 1.244219 0.346220 -5.971521 -v -0.020553 0.041618 -0.028786 -vn -1.605101 2.258870 -5.534973 -v -0.052658 0.041002 -0.010570 -vn -5.186438 1.607212 -3.051773 -v -0.069939 0.037201 -0.002200 -vn -3.671365 2.088877 -4.368409 -v -0.028539 0.177149 -0.016796 -vn 2.181900 -4.181639 -4.086436 -v 0.024904 0.039334 -0.004110 -vn -2.401276 -3.434235 2.485825 -v -0.033521 0.035342 0.048740 -vn 1.723695 -2.386110 -5.418097 -v 0.012950 0.046859 -0.025875 -vn 0.430755 -1.508382 -5.789563 -v -0.016501 0.044196 -0.027443 -vn 0.321220 1.735906 -5.773506 -v -0.029921 0.041870 -0.029797 -vn 2.284586 -3.813135 -4.270525 -v 0.042608 0.045705 -0.003640 -vn -2.257079 0.833659 -5.694993 -v -0.060656 0.096277 -0.018730 -vn 3.394227 -2.475448 -4.313583 -v 0.020563 0.047260 -0.021115 -vn 0.786958 -2.831846 -5.467429 -v 0.006584 0.045097 -0.025424 -vn -0.093187 -3.756371 -4.469017 -v -0.006634 0.045713 -0.029357 -vn 0.781202 -1.941594 4.614951 -v -0.051201 0.036266 0.046696 -vn -3.393321 2.466035 -4.021859 -v -0.046634 0.041753 -0.011715 -vn 3.575802 -1.462354 -3.453103 -v 0.027361 0.050602 -0.020193 -vn 1.391885 -2.547979 -5.009366 -v 0.001191 0.048251 -0.030116 -vn 0.664783 -1.793236 -5.942995 -v -0.004183 0.051663 -0.031592 -vn -4.704611 1.232496 -3.876639 -v -0.054532 0.048794 -0.005607 -vn 1.031067 -1.886816 -5.588934 -v 0.039717 0.048196 -0.006273 -vn 2.833501 -3.334690 -3.768507 -v 0.029573 0.046826 -0.006942 -vn 1.894240 -1.005548 -5.623591 -v 0.014876 0.055388 -0.028906 -vn -0.146267 -3.519603 -5.102991 -v -0.011675 0.046714 -0.029536 -vn -1.154963 -0.019472 -5.788070 -v -0.021969 0.046638 -0.027647 -vn -0.649189 2.553441 -5.653012 -v -0.033239 0.106954 -0.020055 -vn -2.673129 -0.893073 -5.394556 -v -0.023665 0.172923 -0.020503 -vn 2.878637 -2.873295 -4.307651 -v 0.047593 0.048979 -0.003745 -vn -0.792952 -3.178947 -4.646562 -v -0.069480 0.141087 -0.008223 -vn -0.356856 -4.108925 -3.617630 -v -0.067465 0.155828 -0.052825 -vn 2.550919 -1.422135 -4.752334 -v 0.035448 0.053226 -0.006698 -vn 2.566608 -2.880515 -4.490339 -v 0.022027 0.051394 -0.024219 -vn 0.538059 -1.267633 -5.698787 -v 0.008179 0.054473 -0.030646 -vn 1.396882 -2.129105 -5.680023 -v 0.004858 0.051410 -0.029406 -vn -0.616774 -0.846350 -6.104668 -v -0.043317 0.054322 -0.011249 -vn 3.146122 -0.824063 -4.550228 -v 0.022929 0.056484 -0.026263 -vn 1.829072 -1.858322 -5.585440 -v 0.002296 0.057525 -0.032250 -vn -1.692216 -2.664045 -5.299651 -v -0.017362 0.051882 -0.031852 -vn -2.033151 1.678500 -2.965024 -v -0.032890 0.050995 -0.010667 -vn -2.490085 1.172872 -5.636971 -v -0.068941 0.096173 -0.016213 -vn 1.033723 -1.678642 -5.935401 -v -0.002724 0.055123 -0.031988 -vn -0.261678 -2.271012 -5.631395 -v -0.014241 0.055933 -0.034546 -vn -0.682749 -1.158479 -5.678084 -v -0.035203 0.056818 -0.010542 -vn 1.274792 0.193884 -5.505945 -v 0.046443 0.055228 -0.006332 -vn -4.143450 -0.836806 -3.835458 -v -0.086920 0.121543 -0.001967 -vn 2.425514 -1.551958 -5.258655 -v 0.005380 0.060006 -0.031052 -vn -2.688803 -2.159238 -5.070685 -v -0.021206 0.063178 -0.035407 -vn -0.081434 2.109581 -5.882597 -v -0.014822 0.104813 -0.022748 -vn 1.209774 -0.760586 -5.894783 -v -0.001089 0.063134 -0.034806 -vn 1.183066 -1.207467 -6.016953 -v -0.009726 0.063159 -0.035872 -vn -3.668478 -1.594434 -3.437469 -v -0.032502 0.058736 -0.012148 -vn 0.143391 -2.190269 -5.860161 -v -0.041493 0.062512 -0.013150 -vn -1.193304 1.628470 -5.905185 -v -0.055494 0.103961 -0.019197 -vn -0.420886 0.331960 -6.100231 -v -0.069104 0.127700 -0.009258 -vn 2.836908 -0.033424 -5.520826 -v 0.020632 0.060902 -0.026612 -vn -3.238084 -0.257091 -5.285370 -v -0.050623 0.052431 -0.008290 -vn -3.485631 -3.570259 -3.094790 -v -0.056845 0.061046 -0.003982 -vn -2.151558 0.389041 -5.724267 -v -0.077177 0.127417 -0.007440 -vn 1.129343 -1.017294 -5.154598 -v 0.010593 0.067871 -0.030774 -vn 1.960793 -1.114228 -5.751751 -v 0.006767 0.064712 -0.032530 -vn 0.039676 -1.523710 -5.837566 -v -0.015485 0.064992 -0.037611 -vn -2.314391 -4.711298 -2.531625 -v -0.065281 0.062413 -0.002734 -vn 3.757053 -0.498878 -4.771686 -v 0.026823 0.064951 -0.021337 -vn 2.016375 -0.811496 -5.760109 -v 0.015081 0.066669 -0.030260 -vn -1.766122 -1.274123 -5.577400 -v -0.029944 0.167187 -0.017059 -vn -3.406791 -1.285182 -4.973622 -v -0.017586 0.175944 -0.024574 -vn -1.297792 1.763809 -5.872314 -v -0.032719 0.102131 -0.022168 -vn 1.274720 -0.573349 -6.020175 -v -0.000142 0.068984 -0.033959 -vn 1.464581 -0.691912 -6.010160 -v -0.008058 0.066827 -0.035712 -vn -3.803025 -1.381012 -4.428134 -v -0.027915 0.073585 -0.035382 -vn -2.408362 -2.540107 -4.686806 -v -0.035279 0.066010 -0.014882 -vn -1.882806 -2.061697 -5.508840 -v -0.047000 0.064668 -0.013751 -vn -1.833576 -4.671825 -3.748458 -v -0.060980 0.065642 -0.008172 -vn 1.076484 0.352520 -2.498531 -v -0.010119 0.178375 -0.030193 -vn -2.290289 2.764254 -5.010884 -v -0.061801 0.112880 -0.014394 -vn 0.201073 -0.311417 -6.186754 -v -0.067821 0.139100 -0.008020 -vn -5.402851 -1.841468 -2.491268 -v -0.032818 0.068429 -0.019995 -vn -2.204504 -3.158869 -4.620412 -v -0.053317 0.065128 -0.010205 -vn -2.053773 -1.499814 -5.343858 -v -0.038357 0.160898 -0.012890 -vn -4.535330 -3.603331 0.832002 -v -0.080383 0.071096 0.015962 -vn 3.169443 -0.352102 -5.192020 -v 0.022221 0.069765 -0.027275 -vn -3.980627 0.638005 -4.083691 -v -0.086087 0.126739 -0.002898 -vn 1.420061 -0.640139 -5.996555 -v -0.008005 0.075874 -0.037911 -vn -1.676597 -0.772072 -5.517219 -v -0.022256 0.073469 -0.038837 -vn -0.618755 -2.109227 -5.732773 -v -0.038298 0.073022 -0.017410 -vn -1.037982 -3.893235 -4.346249 -v -0.059352 0.070117 -0.015245 -vn -3.030084 -4.398011 -3.272894 -v -0.068926 0.068296 -0.005829 -vn -3.239716 2.221931 -4.834121 -v -0.065003 0.106783 -0.014640 -vn 2.220161 -1.212501 -5.681921 -v 0.009044 0.070669 -0.032635 -vn -0.422505 -1.958643 -5.517745 -v -0.043296 0.071283 -0.017836 -vn -2.280412 -1.171559 -5.507233 -v -0.076730 0.118361 -0.007049 -vn 2.865802 0.124832 -5.568679 -v 0.013139 0.075411 -0.030629 -vn 2.088827 -0.737078 -5.471972 -v 0.007789 0.073786 -0.034176 -vn 1.605410 -0.649805 -6.010971 -v -0.002096 0.077350 -0.036286 -vn 3.421686 0.391841 -5.196198 -v 0.026025 0.075864 -0.024615 -vn 0.575536 -0.538209 -6.219788 -v -0.014101 0.076218 -0.038681 -vn -0.456441 -2.807613 -5.393512 -v -0.056861 0.075425 -0.018800 -vn -2.969008 -4.130794 -3.507520 -v -0.069305 0.072272 -0.011337 -vn 2.279690 0.499347 -5.757993 -v 0.008278 0.079888 -0.033425 -vn 0.168602 -2.332073 -5.800937 -v -0.045800 0.079265 -0.019488 -vn -1.098329 -2.723700 -5.296250 -v -0.048511 0.072361 -0.015755 -vn 0.741605 -0.228991 -6.003376 -v -0.014679 0.080905 -0.039415 -vn -1.373470 0.275419 -5.892548 -v -0.021161 0.081146 -0.039114 -vn -3.274830 -1.724252 -3.767007 -v -0.035381 0.077826 -0.019690 -vn -1.938116 -0.921117 -5.842093 -v -0.061745 0.081517 -0.019408 -vn -2.651678 -0.999888 -5.423191 -v -0.050646 0.154061 -0.005029 -vn -0.350031 1.499208 -6.047258 -v -0.039408 0.101985 -0.021012 -vn 1.891169 0.309517 -5.518405 -v -0.001989 0.084029 -0.037308 -vn -0.647381 -1.442424 -5.711532 -v -0.055540 0.081356 -0.021564 -vn -2.380841 -2.328468 -4.964579 -v -0.067606 0.076998 -0.016588 -vn -3.552002 -3.157693 -3.938307 -v -0.072835 0.075479 -0.011548 -vn -2.309867 0.900221 -5.315913 -v -0.063403 0.102667 -0.018109 -vn -3.555196 -1.074805 -4.635286 -v -0.074352 0.083824 -0.015033 -vn -4.761543 -2.017496 -3.415118 -v -0.079865 0.080647 -0.007037 -vn -3.251969 1.603944 -4.971340 -v -0.075044 0.099103 -0.012772 -vn 1.284948 -1.992727 -5.521970 -v -0.053079 0.145367 -0.001062 -vn 3.932287 -0.287469 -4.694476 -v 0.033453 0.080862 -0.018831 -vn 3.275712 0.933640 -5.219936 -v 0.024434 0.084201 -0.024724 -vn -0.689848 1.769053 -5.726588 -v -0.018231 0.086384 -0.038771 -vn -2.075829 -0.187702 -5.840717 -v -0.036341 0.087714 -0.023736 -vn -2.292516 -3.041260 -4.876693 -v -0.036038 0.081294 -0.022184 -vn -0.699799 -1.756535 -5.934102 -v -0.042168 0.084087 -0.021148 -vn -4.150049 1.130184 -4.477622 -v -0.055194 0.155854 -0.001816 -vn 1.954654 1.983075 -5.605588 -v 0.020022 0.095055 -0.023044 -vn 2.025712 0.912203 -5.839200 -v 0.003429 0.084856 -0.034063 -vn -1.983852 0.078786 -5.796405 -v -0.057716 0.087047 -0.021331 -vn -1.395693 0.800818 -5.888027 -v -0.064327 0.093460 -0.018729 -vn 1.483109 2.538232 -5.349003 -v -0.002486 0.091428 -0.035022 -vn -0.718306 -0.565213 -6.189129 -v -0.043559 0.089715 -0.022140 -vn 0.586543 -4.735065 -2.507626 -v -0.031048 0.033506 -0.029307 -vn 0.461403 -6.029703 -0.899170 -v -0.027066 0.033518 -0.026370 -vn 0.653404 -5.623094 -1.431303 -v -0.018731 0.033526 -0.024855 -vn 0.361228 -5.864080 -1.355607 -v -0.000795 0.033932 -0.021875 -vn 0.305339 -5.407276 -1.620411 -v -0.010702 0.033665 -0.023378 -vn -0.153150 -6.141954 1.056340 -v 0.000102 0.034145 -0.018265 -vn -1.605566 -5.607874 -0.812614 -v -0.043525 0.033522 -0.023573 -vn 0.616189 -5.788922 1.577282 -v -0.033769 0.033782 -0.021216 -vn -0.256033 -5.011223 2.793563 -v -0.020336 0.033995 -0.020220 -vn -0.871023 -5.627550 1.155264 -v 0.009041 0.034156 -0.014319 -vn 0.457766 -4.303330 4.473708 -v -0.031051 0.035395 -0.019693 -vn -1.109514 -4.547956 3.936728 -v 0.002955 0.034746 -0.015846 -vn -0.536194 -4.832527 3.247339 -v -0.006928 0.034726 -0.017440 -vn -1.075396 -5.837102 -0.047997 -v 0.011382 0.034284 -0.009887 -vn -0.256683 -4.864142 2.679157 -v -0.020731 0.038564 -0.017034 -vn -1.591560 -4.476742 2.600860 -v 0.004305 0.038447 -0.013091 -vn 0.317911 -4.704145 2.560043 -v -0.028384 0.038714 -0.017394 -vn -2.659887 -4.592800 -0.887015 -v 0.006240 0.038638 -0.007066 -vn -2.484054 -2.901412 -1.531463 -v -0.047781 0.033668 -0.014869 -vn 0.087610 -6.281501 -0.095898 -v -0.021419 0.038598 -0.008727 -vn -0.321557 -6.186838 0.352081 -v 0.000226 0.039294 -0.010373 -vn -2.020763 -4.937644 -1.228935 -v 0.005207 0.034351 -0.000718 -vn 1.985232 -4.933501 1.826085 -v -0.034292 0.038263 -0.015016 -vn 2.072284 -5.459241 1.006790 -v -0.040013 0.034067 -0.013197 -vn 0.264455 -4.185878 -0.133220 -v 0.016893 0.034277 0.001943 -vn 1.090160 -5.949840 -1.237476 -v 0.023702 0.034745 0.002605 -vn 1.389204 -5.853153 -1.345016 -v 0.029995 0.035479 0.004802 -vn -1.054663 -2.186803 -2.963243 -v -0.058090 0.033677 -0.010831 -vn 0.036047 -6.266556 -0.260097 -v -0.053264 0.033387 -0.007121 -vn 1.003562 -4.337029 0.157190 -v -0.041975 0.033808 -0.006000 -vn -0.335594 -4.924673 2.478639 -v -0.007668 0.039045 -0.014558 -vn 0.000934 -3.842632 -0.022509 -v 0.021880 0.034389 0.006310 -vn 1.487663 -3.469343 0.507254 -v -0.038045 0.038252 -0.007312 -vn 0.041220 -3.695655 -0.108052 -v -0.029324 0.038238 0.002867 -vn -1.827541 -5.590177 -0.528605 -v -0.003362 0.038557 0.007072 -vn -2.043914 -4.958871 -0.871053 -v 0.001322 0.034177 0.006204 -vn 1.936477 -5.782485 0.069930 -v 0.034929 0.035896 0.011608 -vn 0.023908 -3.749604 -0.014085 -v -0.040483 0.033589 0.000777 -vn -2.288744 -5.148731 -1.490148 -v 0.000503 0.038624 0.000359 -vn 0.281534 -3.749377 0.262137 -v 0.007974 0.035303 0.005239 -vn -0.473364 -5.961977 0.158068 -v 0.025749 0.034373 0.012316 -vn 0.055369 -2.953012 -0.041502 -v -0.034541 0.038318 -0.002259 -vn 0.093556 -6.279986 0.071934 -v -0.011604 0.038268 0.017443 -vn -0.074952 -4.038264 -0.004326 -v 0.004670 0.033954 0.011450 -vn 0.418699 -5.828279 1.457961 -v -0.048354 0.033471 0.005871 -vn -0.925940 -6.100485 -0.191933 -v -0.068580 0.033439 -0.001794 -vn 0.121964 -6.280165 -0.147315 -v -0.014635 0.038471 0.001285 -vn -1.573628 -2.622198 0.055418 -v 0.022591 0.036265 0.012193 -vn 2.620239 -5.560765 0.944825 -v 0.042604 0.039957 0.016454 -vn -0.906931 -4.394035 4.006791 -v -0.056703 0.066649 0.036198 -vn 0.113319 -4.284014 0.352542 -v -0.053385 0.033554 0.010046 -vn -3.394146 -3.469792 -1.179729 -v -0.071524 0.034206 0.000364 -vn -0.159408 -6.265806 -0.192391 -v -0.061312 0.033359 -0.004212 -vn 0.050473 -2.633273 0.059969 -v -0.032691 0.033779 0.007960 -vn -2.315114 -5.047698 1.041707 -v 0.001078 0.034485 0.016979 -vn 0.153018 -4.528936 0.198768 -v 0.020599 0.034822 0.020436 -vn -4.804029 0.027972 -1.735587 -v -0.072546 0.036146 0.000873 -vn 0.300105 -2.153215 1.837942 -v -0.047468 0.035702 0.008340 -vn -0.028522 -3.993120 0.336888 -v -0.038997 0.033805 0.008230 -vn -0.006024 -4.176673 0.188747 -v 0.008542 0.034574 0.019458 -vn 1.518244 -5.860992 1.271450 -v 0.030524 0.035652 0.017933 -vn 0.121771 -4.116627 0.088345 -v -0.034337 0.033842 0.013477 -vn 2.058368 -4.783494 3.234198 -v 0.031776 0.039405 0.026306 -vn 3.364819 -4.909647 1.400233 -v 0.049007 0.043889 0.019645 -vn -1.860308 -5.653318 0.535986 -v -0.003089 0.038241 0.016826 -vn 0.342031 -6.271612 0.086597 -v -0.022988 0.038014 0.018836 -vn -1.457573 -5.533040 1.581061 -v 0.000752 0.038601 0.023468 -vn -1.627662 -5.360640 1.701665 -v 0.007801 0.034790 0.024562 -vn -4.063713 -4.470137 1.557654 -v -0.073774 0.067281 0.021567 -vn -0.281993 -3.549576 0.050529 -v -0.054487 0.033508 0.018481 -vn -0.105478 -5.854477 0.423681 -v -0.033270 0.033792 0.021070 -vn 2.116701 -3.692899 0.647432 -v -0.029582 0.034443 0.017371 -vn 0.863276 -4.246927 0.201679 -v -0.026321 0.037804 0.015218 -vn 3.079411 -4.668875 2.641291 -v 0.026089 0.039285 0.030790 -vn 2.413568 -5.019984 2.592252 -v 0.042374 0.042416 0.025062 -vn -1.759407 -5.404191 1.442599 -v -0.067210 0.033946 0.011670 -vn -1.661236 -3.293296 1.135918 -v 0.007571 0.039379 0.030260 -vn 1.066742 -3.289505 4.462430 -v 0.040646 0.045861 0.031129 -vn -3.614755 -3.687841 2.339877 -v -0.053419 0.060334 0.026371 -vn -1.571296 -2.527946 -1.278923 -v -0.037211 0.035607 0.024040 -vn 0.025373 -6.043966 -0.746673 -v -0.038045 0.034099 0.027078 -vn 2.985725 -4.691442 0.976426 -v -0.028801 0.037509 0.021160 -vn -1.232923 -5.870563 0.061972 -v 0.012965 0.034937 0.030999 -vn -3.301684 -4.171348 0.667302 -v -0.089636 0.112264 0.038288 -vn -2.934777 -3.787755 0.031071 -v -0.061875 0.034283 0.020793 -vn -2.271023 -2.125395 -1.156838 -v 0.009042 0.037872 0.033309 -vn 1.480080 -5.892271 1.042617 -v 0.021603 0.035333 0.026006 -vn -2.263909 -5.780048 0.636655 -v -0.081163 0.109601 0.036369 -vn 3.359541 -4.607021 1.244864 -v -0.031112 0.034889 0.023586 -vn -0.593628 -4.042698 -0.587479 -v 0.007740 0.034745 0.037242 -vn -4.898901 -2.076441 2.203662 -v -0.083078 0.080713 0.028931 -vn -1.832477 -5.790102 -1.409158 -v -0.062974 0.060790 0.000987 -vn 0.142420 -3.484636 0.431723 -v -0.042326 0.033754 0.027276 -vn 0.222945 -6.266785 0.371365 -v -0.018901 0.038543 0.030074 -vn -3.111623 -5.130745 -1.151401 -v -0.071774 0.146677 -0.023282 -vn 0.067569 -3.170924 0.199903 -v -0.005679 0.039194 0.035725 -vn 3.284361 -3.723039 2.566025 -v 0.019719 0.036687 0.040338 -vn -2.245846 -5.371774 -1.021697 -v -0.072229 0.147934 -0.030656 -vn -0.022145 -2.986455 -0.123519 -v -0.005215 0.034847 0.041086 -vn 0.228551 -6.201661 0.392281 -v 0.009956 0.034539 0.039923 -vn 1.443631 -5.718741 1.135563 -v 0.016139 0.034969 0.040147 -vn 0.904384 -5.913854 -1.327276 -v -0.068403 0.147440 -0.029282 -vn -0.253220 -6.258934 0.257634 -v -0.058390 0.034190 0.027637 -vn 0.699566 -4.661230 0.336862 -v -0.035365 0.034571 0.034394 -vn 1.771916 -3.461829 0.743734 -v -0.031632 0.037947 0.032015 -vn -3.860110 -1.900667 2.998550 -v -0.078008 0.107205 0.032959 -vn 0.368451 -5.845762 1.415197 -v -0.006013 0.034624 0.046154 -vn -1.834245 -5.837148 0.437239 -v -0.063268 0.058824 0.013903 -vn -3.532793 -2.694383 -0.918064 -v -0.066256 0.035227 0.029091 -vn 0.036536 -4.482576 0.260501 -v -0.051471 0.034420 0.028042 -vn -0.034162 -6.236789 0.600134 -v -0.043812 0.034534 0.031004 -vn 0.099008 -3.737389 0.475318 -v -0.014431 0.034640 0.045422 -vn 0.280048 -5.883874 1.405071 -v 0.002573 0.034637 0.044014 -vn 1.066722 -2.804399 4.626234 -v 0.001973 0.035858 0.046304 -vn 1.431298 -4.025555 3.229284 -v -0.070262 0.112896 0.049789 -vn -1.430649 -3.419052 4.373636 -v -0.075806 0.114207 0.050642 -vn -1.361290 -4.428194 1.716416 -v -0.057157 0.058702 0.020854 -vn -2.602861 -4.907753 0.553019 -v -0.065535 0.034645 0.035249 -vn -0.792534 -6.080646 0.755981 -v -0.037498 0.034655 0.041837 -vn -0.066416 -3.886854 0.201852 -v -0.029741 0.034716 0.042303 -vn 0.127962 -2.439027 0.264266 -v -0.027066 0.038888 0.037210 -vn 0.042459 -2.534974 0.224597 -v -0.013872 0.039457 0.039436 -vn -1.702588 -4.923590 2.760331 -v -0.080347 0.110762 0.044546 -vn -4.130605 -4.560011 -1.240261 -v -0.077079 0.069098 0.006337 -vn -4.232856 -4.580774 -0.210441 -v -0.075456 0.066787 0.010644 -vn -4.909468 -0.837325 0.161120 -v -0.067206 0.036241 0.033334 -vn -1.244093 -3.861351 3.282135 -v -0.039450 0.035397 0.042800 -vn 1.237205 -3.224719 3.762014 -v -0.013804 0.035777 0.050707 -vn 1.370618 -2.422428 4.595876 -v -0.006285 0.036186 0.048918 -vn -1.243862 -3.686680 4.786521 -v -0.051269 0.068258 0.037389 -vn -2.275620 -5.242646 2.368794 -v -0.065692 0.062670 0.024009 -vn 0.426692 -5.740020 1.767862 -v -0.020574 0.034875 0.051289 -vn -0.225544 -5.668032 2.114560 -v -0.076746 0.109783 0.043694 -vn -2.982723 -5.219554 -0.358499 -v -0.069295 0.061043 0.011518 -vn -2.421857 -2.777637 2.002935 -v -0.063434 0.034779 0.041935 -vn -1.573385 -1.993822 4.509330 -v -0.085006 0.116812 0.048965 -vn 1.843655 1.163222 5.781137 -v -0.010037 0.042225 0.049743 -vn -2.576740 -4.717890 2.987446 -v -0.068510 0.067619 0.030981 -vn -4.044535 -4.091052 2.047774 -v -0.076623 0.071171 0.026666 -vn -1.769626 -5.135836 2.640703 -v -0.076355 0.108199 0.036986 -vn -4.656030 -3.814600 -0.891315 -v -0.081301 0.072740 0.006377 -vn 0.280904 -5.515228 2.010120 -v -0.050956 0.034633 0.044418 -vn -1.336963 -3.287436 2.925502 -v -0.028522 0.035165 0.052652 -vn 2.936245 -3.933468 0.486108 -v -0.016774 0.159536 -0.009411 -vn -2.922822 -2.469049 -2.082016 -v -0.070793 0.152810 -0.047562 -vn -0.389003 -3.097667 -5.346172 -v -0.031176 0.161019 -0.014200 -vn 2.344335 -4.263570 -1.417995 -v -0.013049 0.162775 -0.015775 -vn 0.311267 -5.638084 -1.580442 -v -0.068503 0.145629 -0.023406 -vn 0.194476 -2.295120 -4.254563 -v -0.010404 0.173137 -0.028363 -vn 4.013311 -4.209590 -1.328950 -v -0.064382 0.148615 -0.027080 -vn 2.877273 -4.973421 -1.524262 -v -0.065059 0.145172 -0.016596 -vn 2.113569 -1.333188 -2.476233 -v -0.061667 0.165526 -0.060411 -vn 0.293456 -4.684650 -3.905239 -v -0.020459 0.161121 -0.014151 -vn 0.644213 -4.558288 -4.049148 -v -0.029866 0.157369 -0.011341 -vn 3.414769 -2.991915 -2.228133 -v -0.063618 0.159690 -0.055655 -vn 4.150385 -3.777009 -1.639226 -v -0.049063 0.143476 0.002949 -vn -2.425833 -4.921269 -1.640010 -v -0.071721 0.144075 -0.014849 -vn 2.668813 -4.217816 -1.740614 -v -0.066664 0.152838 -0.047598 -vn 4.303092 -2.791105 -2.795282 -v -0.063526 0.143289 -0.008565 -vn 1.724447 -5.173141 -2.074986 -v -0.040941 0.148870 -0.003017 -vn 5.183498 -3.295669 -1.142609 -v -0.064800 0.154312 -0.041287 -vn 5.687422 -2.333261 -0.634689 -v -0.062677 0.150486 -0.023576 -vn 1.863927 -5.082564 -1.442444 -v -0.068470 0.149689 -0.040031 -vn 2.062991 -5.539170 -1.393987 -v -0.027723 0.155172 -0.006445 -vn -2.958652 -2.518410 -1.496984 -v -0.072019 0.150779 -0.042902 -vn -0.513124 -3.745934 -4.685424 -v -0.044036 0.150708 -0.005709 -# 1016 vertices, 0 vertices normals - -f 124//124 692//692 49//49 -f 705//705 692//692 124//124 -f 364//364 83//83 411//411 -f 448//448 8//8 443//443 -f 497//497 468//468 71//71 -f 686//686 362//362 67//67 -f 49//49 98//98 119//119 -f 504//504 576//576 543//543 -f 414//414 419//419 406//406 -f 672//672 869//869 638//638 -f 426//426 403//403 360//360 -f 585//585 586//586 591//591 -f 426//426 98//98 49//49 -f 1015//1015 995//995 1008//1008 -f 902//902 724//724 712//712 -f 390//390 102//102 130//130 -f 113//113 82//82 373//373 -f 119//119 12//12 99//99 -f 358//358 393//393 427//427 -f 401//401 409//409 321//321 -f 119//119 99//99 383//383 -f 404//404 421//421 411//411 -f 422//422 372//372 235//235 -f 422//422 420//420 372//372 -f 60//60 366//366 219//219 -f 362//362 361//361 371//371 -f 543//543 355//355 561//561 -f 57//57 92//92 482//482 -f 819//819 831//831 807//807 -f 458//458 526//526 17//17 -f 5//5 451//451 482//482 -f 145//145 88//88 451//451 -f 586//586 595//595 591//591 -f 415//415 2//2 460//460 -f 105//105 124//124 82//82 -f 991//991 801//801 574//574 -f 411//411 369//369 632//632 -f 5//5 145//145 451//451 -f 1016//1016 996//996 1004//1004 -f 417//417 483//483 361//361 -f 806//806 825//825 571//571 -f 362//362 370//370 367//367 -f 323//323 270//270 352//352 -f 786//786 64//64 725//725 -f 428//428 124//124 105//105 -f 129//129 280//280 92//92 -f 92//92 280//280 482//482 -f 482//482 280//280 5//5 -f 203//203 409//409 208//208 -f 678//678 660//660 677//677 -f 21//21 280//280 129//129 -f 5//5 211//211 145//145 -f 21//21 259//259 280//280 -f 335//335 1006//1006 301//301 -f 355//355 602//602 575//575 -f 354//354 611//611 216//216 -f 105//105 82//82 689//689 -f 402//402 119//119 383//383 -f 337//337 1005//1005 318//318 -f 402//402 124//124 119//119 -f 480//480 193//193 139//139 -f 143//143 148//148 121//121 -f 818//818 830//830 821//821 -f 705//705 124//124 428//428 -f 193//193 253//253 139//139 -f 18//18 27//27 41//41 -f 15//15 10//10 18//18 -f 1009//1009 1001//1001 347//347 -f 421//421 364//364 411//411 -f 689//689 82//82 431//431 -f 75//75 90//90 72//72 -f 46//46 50//50 39//39 -f 187//187 18//18 10//10 -f 34//34 27//27 18//18 -f 339//339 349//349 563//563 -f 692//692 426//426 49//49 -f 135//135 480//480 498//498 -f 140//140 193//193 480//480 -f 143//143 231//231 157//157 -f 101//101 116//116 95//95 -f 987//987 15//15 14//14 -f 54//54 62//62 72//72 -f 39//39 41//41 27//27 -f 91//91 101//101 75//75 -f 209//209 50//50 46//46 -f 211//211 254//254 388//388 -f 356//356 343//343 270//270 -f 43//43 596//596 151//151 -f 114//114 498//498 106//106 -f 140//140 480//480 135//135 -f 30//30 46//46 34//34 -f 98//98 360//360 390//390 -f 502//502 100//100 106//106 -f 114//114 135//135 498//498 -f 39//39 50//50 56//56 -f 726//726 289//289 743//743 -f 268//268 269//269 116//116 -f 28//28 928//928 189//189 -f 122//122 143//143 134//134 -f 148//148 160//160 197//197 -f 368//368 389//389 365//365 -f 76//76 100//100 502//502 -f 522//522 452//452 530//530 -f 390//390 130//130 80//80 -f 107//107 106//106 100//100 -f 30//30 34//34 187//187 -f 107//107 114//114 106//106 -f 14//14 15//15 18//18 -f 98//98 390//390 12//12 -f 76//76 84//84 100//100 -f 84//84 107//107 100//100 -f 95//95 116//116 110//110 -f 68//68 55//55 99//99 -f 143//143 159//159 148//148 -f 146//146 140//140 135//135 -f 158//158 193//193 140//140 -f 281//281 249//249 193//193 -f 116//116 121//121 413//413 -f 391//391 404//404 411//411 -f 800//800 996//996 1016//1016 -f 779//779 803//803 716//716 -f 526//526 443//443 17//17 -f 360//360 102//102 390//390 -f 748//748 786//786 725//725 -f 114//114 118//118 135//135 -f 118//118 146//146 135//135 -f 91//91 75//75 62//62 -f 160//160 87//87 55//55 -f 75//75 101//101 95//95 -f 84//84 104//104 107//107 -f 146//146 158//158 140//140 -f 158//158 281//281 193//193 -f 269//269 134//134 121//121 -f 122//122 123//123 143//143 -f 753//753 322//322 313//313 -f 474//474 604//604 576//576 -f 437//437 727//727 993//993 -f 89//89 84//84 76//76 -f 89//89 104//104 84//84 -f 104//104 118//118 107//107 -f 107//107 118//118 114//114 -f 56//56 62//62 54//54 -f 138//138 197//197 156//156 -f 329//329 328//328 784//784 -f 340//340 311//311 519//519 -f 76//76 85//85 89//89 -f 56//56 50//50 62//62 -f 52//52 261//261 47//47 -f 367//367 393//393 358//358 -f 137//137 146//146 118//118 -f 158//158 161//161 281//281 -f 209//209 77//77 62//62 -f 62//62 77//77 91//91 -f 750//750 345//345 1007//1007 -f 998//998 952//952 1000//1000 -f 28//28 196//196 195//195 -f 104//104 112//112 118//118 -f 112//112 137//137 118//118 -f 137//137 131//131 146//146 -f 146//146 131//131 158//158 -f 928//928 28//28 195//195 -f 60//60 219//219 40//40 -f 17//17 22//22 458//458 -f 428//428 105//105 689//689 -f 86//86 104//104 89//89 -f 161//161 16//16 281//281 -f 422//422 235//235 237//237 -f 422//422 237//237 462//462 -f 67//67 367//367 324//324 -f 22//22 470//470 458//458 -f 86//86 89//89 85//85 -f 125//125 137//137 112//112 -f 845//845 637//637 664//664 -f 52//52 183//183 261//261 -f 157//157 183//183 52//52 -f 122//122 240//240 123//123 -f 1003//1003 786//786 549//549 -f 176//176 22//22 17//17 -f 86//86 85//85 73//73 -f 137//137 125//125 131//131 -f 155//155 158//158 131//131 -f 995//995 751//751 1008//1008 -f 116//116 269//269 121//121 -f 82//82 124//124 402//402 -f 155//155 161//161 158//158 -f 102//102 16//16 161//161 -f 143//143 157//157 163//163 -f 268//268 101//101 247//247 -f 73//73 74//74 86//86 -f 112//112 104//104 86//86 -f 125//125 155//155 131//131 -f 102//102 278//278 16//16 -f 163//163 157//157 52//52 -f 23//23 44//44 470//470 -f 74//74 78//78 86//86 -f 301//301 235//235 372//372 -f 176//176 9//9 22//22 -f 74//74 470//470 44//44 -f 363//363 11//11 31//31 -f 23//23 22//22 9//9 -f 23//23 29//29 44//44 -f 78//78 112//112 86//86 -f 125//125 153//153 155//155 -f 155//155 153//153 161//161 -f 50//50 209//209 62//62 -f 163//163 52//52 159//159 -f 250//250 11//11 363//363 -f 462//462 250//250 363//363 -f 402//402 383//383 373//373 -f 44//44 63//63 74//74 -f 78//78 108//108 112//112 -f 651//651 837//837 335//335 -f 74//74 93//93 78//78 -f 108//108 109//109 112//112 -f 112//112 109//109 125//125 -f 109//109 126//126 125//125 -f 147//147 153//153 125//125 -f 23//23 24//24 29//29 -f 108//108 78//78 93//93 -f 126//126 147//147 125//125 -f 153//153 42//42 161//161 -f 161//161 42//42 102//102 -f 290//290 289//289 286//286 -f 250//250 31//31 11//11 -f 53//53 63//63 44//44 -f 63//63 93//93 74//74 -f 130//130 102//102 42//42 -f 53//53 44//44 29//29 -f 93//93 109//109 108//108 -f 141//141 42//42 153//153 -f 187//187 34//34 18//18 -f 1014//1014 1003//1003 994//994 -f 332//332 1010//1010 1014//1014 -f 285//285 298//298 296//296 -f 70//70 63//63 53//53 -f 70//70 488//488 63//63 -f 63//63 488//488 93//93 -f 488//488 109//109 93//93 -f 488//488 463//463 109//109 -f 109//109 463//463 126//126 -f 141//141 153//153 147//147 -f 163//163 159//159 143//143 -f 152//152 177//177 419//419 -f 38//38 53//53 29//29 -f 315//315 270//270 174//174 -f 48//48 70//70 53//53 -f 126//126 127//127 147//147 -f 130//130 42//42 141//141 -f 197//197 138//138 148//148 -f 156//156 55//55 68//68 -f 586//586 585//585 574//574 -f 48//48 53//53 38//38 -f 70//70 65//65 488//488 -f 127//127 136//136 147//147 -f 147//147 136//136 141//141 -f 31//31 177//177 152//152 -f 536//536 295//295 608//608 -f 62//62 75//75 72//72 -f 134//134 143//143 121//121 -f 463//463 127//127 126//126 -f 80//80 130//130 141//141 -f 517//517 525//525 508//508 -f 525//525 515//515 508//508 -f 110//110 116//116 413//413 -f 358//358 324//324 367//367 -f 48//48 65//65 70//70 -f 34//34 39//39 27//27 -f 310//310 347//347 1012//1012 -f 124//124 49//49 119//119 -f 127//127 120//120 136//136 -f 136//136 154//154 141//141 -f 247//247 101//101 91//91 -f 167//167 13//13 437//437 -f 192//192 559//559 685//685 -f 145//145 388//388 88//88 -f 154//154 162//162 141//141 -f 162//162 80//80 141//141 -f 254//254 37//37 388//388 -f 321//321 661//661 326//326 -f 323//323 192//192 229//229 -f 913//913 928//928 195//195 -f 46//46 39//39 34//34 -f 991//991 585//585 573//573 -f 415//415 460//460 394//394 -f 136//136 132//132 154//154 -f 13//13 26//26 25//25 -f 26//26 471//471 25//25 -f 52//52 47//47 87//87 -f 167//167 19//19 13//13 -f 19//19 26//26 13//13 -f 604//604 596//596 380//380 -f 568//568 543//543 561//561 -f 407//407 47//47 261//261 -f 81//81 80//80 162//162 -f 47//47 383//383 87//87 -f 208//208 60//60 40//40 -f 368//368 388//388 37//37 -f 132//132 142//142 154//154 -f 142//142 162//162 154//154 -f 81//81 12//12 80//80 -f 449//449 132//132 382//382 -f 325//325 339//339 563//563 -f 689//689 431//431 399//399 -f 4//4 162//162 142//142 -f 321//321 317//317 661//661 -f 792//792 806//806 571//571 -f 77//77 247//247 91//91 -f 167//167 14//14 19//19 -f 79//79 94//94 96//96 -f 97//97 491//491 96//96 -f 4//4 81//81 162//162 -f 1007//1007 1001//1001 750//750 -f 10//10 169//169 182//182 -f 40//40 219//219 51//51 -f 26//26 19//19 33//33 -f 66//66 94//94 79//79 -f 115//115 491//491 97//97 -f 115//115 490//490 491//491 -f 40//40 51//51 196//196 -f 33//33 36//36 476//476 -f 61//61 66//66 79//79 -f 94//94 97//97 96//96 -f 156//156 4//4 142//142 -f 563//563 349//349 343//343 -f 40//40 196//196 28//28 -f 101//101 268//268 116//116 -f 19//19 20//20 33//33 -f 1001//1001 1012//1012 347//347 -f 797//797 1009//1009 660//660 -f 298//298 297//297 296//296 -f 168//168 10//10 15//15 -f 14//14 20//20 19//19 -f 20//20 36//36 33//33 -f 270//270 229//229 174//174 -f 157//157 252//252 183//183 -f 90//90 97//97 94//94 -f 1004//1004 1003//1003 1014//1014 -f 82//82 113//113 431//431 -f 61//61 54//54 66//66 -f 110//110 115//115 97//97 -f 68//68 4//4 156//156 -f 68//68 81//81 4//4 -f 68//68 99//99 81//81 -f 99//99 12//12 81//81 -f 39//39 56//56 41//41 -f 20//20 41//41 36//36 -f 45//45 54//54 61//61 -f 66//66 90//90 94//94 -f 90//90 110//110 97//97 -f 749//749 312//312 297//297 -f 36//36 41//41 45//45 -f 382//382 138//138 449//449 -f 197//197 160//160 55//55 -f 54//54 72//72 66//66 -f 66//66 72//72 90//90 -f 115//115 413//413 382//382 -f 110//110 413//413 115//115 -f 197//197 55//55 156//156 -f 14//14 18//18 20//20 -f 18//18 41//41 20//20 -f 45//45 56//56 54//54 -f 95//95 110//110 90//90 -f 56//56 45//45 41//41 -f 90//90 75//75 95//95 -f 243//243 205//205 276//276 -f 269//269 122//122 134//134 -f 177//177 250//250 220//220 -f 595//595 216//216 591//591 -f 203//203 198//198 178//178 -f 51//51 202//202 196//196 -f 203//203 208//208 198//198 -f 897//897 923//923 884//884 -f 80//80 12//12 390//390 -f 977//977 9//9 171//171 -f 843//843 842//842 825//825 -f 232//232 257//257 244//244 -f 306//306 788//788 747//747 -f 40//40 28//28 189//189 -f 349//349 352//352 270//270 -f 328//328 325//325 319//319 -f 280//280 211//211 5//5 -f 182//182 187//187 10//10 -f 239//239 247//247 238//238 -f 236//236 179//179 199//199 -f 1001//1001 1000//1000 1012//1012 -f 217//217 238//238 77//77 -f 259//259 267//267 280//280 -f 280//280 267//267 211//211 -f 1015//1015 1008//1008 1013//1013 -f 256//256 268//268 247//247 -f 259//259 277//277 267//267 -f 788//788 828//828 747//747 -f 219//219 223//223 51//51 -f 223//223 241//241 51//51 -f 234//234 282//282 265//265 -f 218//218 201//201 259//259 -f 201//201 277//277 259//259 -f 267//267 254//254 211//211 -f 226//226 239//239 238//238 -f 17//17 8//8 176//176 -f 952//952 1013//1013 1000//1000 -f 307//307 274//274 252//252 -f 231//231 282//282 307//307 -f 253//253 249//249 965//965 -f 201//201 218//218 249//249 -f 199//199 179//179 251//251 -f 241//241 222//222 202//202 -f 265//265 282//282 264//264 -f 193//193 249//249 253//253 -f 277//277 210//210 267//267 -f 297//297 317//317 308//308 -f 862//862 860//860 866//866 -f 191//191 188//188 207//207 -f 172//172 182//182 169//169 -f 738//738 304//304 299//299 -f 210//210 254//254 267//267 -f 792//792 556//556 772//772 -f 111//111 236//236 997//997 -f 1//1 243//243 276//276 -f 311//311 357//357 336//336 -f 231//231 143//143 123//123 -f 201//201 271//271 277//277 -f 271//271 262//262 277//277 -f 828//828 499//499 747//747 -f 257//257 233//233 265//265 -f 249//249 281//281 201//201 -f 210//210 117//117 254//254 -f 254//254 117//117 37//37 -f 356//356 270//270 315//315 -f 224//224 103//103 255//255 -f 317//317 316//316 308//308 -f 262//262 210//210 277//277 -f 199//199 251//251 186//186 -f 227//227 232//232 244//244 -f 281//281 271//271 201//201 -f 167//167 987//987 14//14 -f 176//176 8//8 170//170 -f 736//736 176//176 170//170 -f 250//250 237//237 184//184 -f 273//273 230//230 248//248 -f 245//245 246//246 210//210 -f 246//246 117//117 210//210 -f 262//262 245//245 210//210 -f 1009//1009 69//69 660//660 -f 682//682 306//306 690//690 -f 230//230 273//273 255//255 -f 209//209 217//217 77//77 -f 947//947 937//937 292//292 -f 504//504 543//543 357//357 -f 271//271 200//200 262//262 -f 208//208 409//409 214//214 -f 226//226 244//244 239//239 -f 200//200 245//245 262//262 -f 246//246 180//180 117//117 -f 35//35 37//37 117//117 -f 180//180 35//35 117//117 -f 176//176 736//736 171//171 -f 21//21 965//965 218//218 -f 190//190 204//204 206//206 -f 994//994 186//186 1//1 -f 175//175 195//195 188//188 -f 996//996 1003//1003 1004//1004 -f 179//179 273//273 248//248 -f 751//751 608//608 1005//1005 -f 9//9 176//176 171//171 -f 213//213 222//222 225//225 -f 448//448 170//170 8//8 -f 15//15 987//987 168//168 -f 263//263 279//279 240//240 -f 271//271 258//258 200//200 -f 255//255 103//103 230//230 -f 207//207 225//225 204//204 -f 279//279 231//231 123//123 -f 16//16 271//271 281//281 -f 16//16 258//258 271//271 -f 327//327 180//180 246//246 -f 245//245 327//327 246//246 -f 244//244 257//257 263//263 -f 221//221 103//103 419//419 -f 238//238 247//247 77//77 -f 187//187 182//182 194//194 -f 179//179 248//248 251//251 -f 222//222 233//233 225//225 -f 248//248 220//220 185//185 -f 223//223 234//234 241//241 -f 188//188 172//172 292//292 -f 16//16 278//278 258//258 -f 187//187 194//194 30//30 -f 265//265 264//264 257//257 -f 279//279 282//282 231//231 -f 274//274 165//165 183//183 -f 750//750 1009//1009 797//797 -f 227//227 225//225 232//232 -f 166//166 169//169 10//10 -f 159//159 160//160 148//148 -f 718//718 713//713 726//726 -f 195//195 207//207 188//188 -f 179//179 300//300 273//273 -f 876//876 284//284 713//713 -f 166//166 172//172 169//169 -f 225//225 227//227 204//204 -f 659//659 684//684 547//547 -f 251//251 260//260 243//243 -f 333//333 327//327 397//397 -f 244//244 263//263 240//240 -f 251//251 248//248 260//260 -f 240//240 256//256 239//239 -f 579//579 364//364 421//421 -f 200//200 258//258 397//397 -f 270//270 323//323 229//229 -f 1//1 1014//1014 994//994 -f 243//243 1//1 186//186 -f 256//256 122//122 269//269 -f 672//672 723//723 737//737 -f 160//160 52//52 87//87 -f 296//296 297//297 308//308 -f 230//230 221//221 177//177 -f 223//223 356//356 234//234 -f 260//260 248//248 185//185 -f 51//51 241//241 202//202 -f 974//974 569//569 560//560 -f 207//207 204//204 191//191 -f 186//186 251//251 243//243 -f 178//178 198//198 189//189 -f 244//244 240//240 239//239 -f 239//239 256//256 247//247 -f 46//46 215//215 209//209 -f 690//690 769//769 682//682 -f 613//613 2//2 385//385 -f 236//236 111//111 179//179 -f 343//343 349//349 270//270 -f 10//10 168//168 964//964 -f 190//190 206//206 194//194 -f 1011//1011 1008//1008 337//337 -f 231//231 252//252 157//157 -f 233//233 257//257 232//232 -f 335//335 301//301 128//128 -f 795//795 287//287 305//305 -f 178//178 303//303 203//203 -f 749//749 298//298 731//731 -f 1016//1016 1010//1010 1006//1006 -f 301//301 342//342 128//128 -f 269//269 268//268 256//256 -f 40//40 198//198 208//208 -f 225//225 233//233 232//232 -f 302//302 235//235 301//301 -f 202//202 222//222 213//213 -f 257//257 264//264 279//279 -f 302//302 266//266 235//235 -f 266//266 184//184 237//237 -f 235//235 266//266 237//237 -f 978//978 987//987 167//167 -f 230//230 177//177 220//220 -f 753//753 313//313 738//738 -f 194//194 206//206 215//215 -f 215//215 206//206 217//217 -f 243//243 260//260 205//205 -f 384//384 224//224 255//255 -f 241//241 265//265 233//233 -f 234//234 144//144 282//282 -f 196//196 202//202 195//195 -f 300//300 212//212 273//273 -f 260//260 185//185 205//205 -f 206//206 226//226 217//217 -f 276//276 205//205 332//332 -f 222//222 241//241 233//233 -f 924//924 175//175 292//292 -f 354//354 429//429 611//611 -f 653//653 684//684 659//659 -f 274//274 183//183 252//252 -f 215//215 217//217 209//209 -f 217//217 226//226 238//238 -f 1013//1013 1008//1008 1011//1011 -f 339//339 352//352 349//349 -f 198//198 40//40 189//189 -f 356//356 315//315 351//351 -f 207//207 213//213 225//225 -f 273//273 212//212 255//255 -f 128//128 681//681 335//335 -f 264//264 282//282 279//279 -f 220//220 250//250 184//184 -f 255//255 212//212 384//384 -f 307//307 272//272 274//274 -f 159//159 52//52 160//160 -f 353//353 323//323 352//352 -f 257//257 279//279 263//263 -f 191//191 190//190 182//182 -f 183//183 418//418 261//261 -f 265//265 241//241 234//234 -f 205//205 184//184 266//266 -f 172//172 188//188 182//182 -f 204//204 227//227 206//206 -f 227//227 244//244 226//226 -f 248//248 230//230 220//220 -f 185//185 184//184 205//205 -f 184//184 185//185 220//220 -f 31//31 250//250 177//177 -f 168//168 987//987 979//979 -f 301//301 1006//1006 302//302 -f 332//332 266//266 302//302 -f 332//332 205//205 266//266 -f 227//227 226//226 206//206 -f 188//188 191//191 182//182 -f 462//462 237//237 250//250 -f 290//290 299//299 289//289 -f 175//175 188//188 292//292 -f 282//282 144//144 307//307 -f 182//182 190//190 194//194 -f 183//183 165//165 418//418 -f 385//385 381//381 613//613 -f 231//231 307//307 252//252 -f 202//202 207//207 195//195 -f 317//317 321//321 316//316 -f 202//202 213//213 207//207 -f 240//240 279//279 123//123 -f 21//21 129//129 965//965 -f 30//30 194//194 215//215 -f 749//749 297//297 298//298 -f 191//191 204//204 190//190 -f 430//430 570//570 152//152 -f 359//359 310//310 1012//1012 -f 359//359 283//283 310//310 -f 346//346 340//340 609//609 -f 341//341 448//448 985//985 -f 529//529 513//513 760//760 -f 212//212 300//300 287//287 -f 612//612 474//474 576//576 -f 604//604 474//474 596//596 -f 838//838 597//597 643//643 -f 505//505 442//442 508//508 -f 305//305 300//300 133//133 -f 71//71 468//468 346//346 -f 939//939 954//954 931//931 -f 792//792 798//798 556//556 -f 330//330 358//358 283//283 -f 310//310 283//283 32//32 -f 67//67 324//324 318//318 -f 757//757 322//322 753//753 -f 803//803 779//779 766//766 -f 228//228 941//941 592//592 -f 923//923 932//932 922//922 -f 870//870 897//897 884//884 -f 359//359 337//337 283//283 -f 337//337 330//330 283//283 -f 602//602 604//604 380//380 -f 467//467 535//535 523//523 -f 764//764 773//773 792//792 -f 320//320 328//328 319//319 -f 364//364 380//380 596//596 -f 663//663 655//655 700//700 -f 543//543 602//602 355//355 -f 650//650 788//788 306//306 -f 635//635 664//664 646//646 -f 242//242 340//340 519//519 -f 357//357 543//543 568//568 -f 374//374 346//346 468//468 -f 708//708 707//707 855//855 -f 359//359 1011//1011 337//337 -f 802//802 329//329 784//784 -f 738//738 313//313 309//309 -f 535//535 475//475 472//472 -f 199//199 997//997 236//236 -f 300//300 179//179 111//111 -f 304//304 738//738 309//309 -f 625//625 384//384 379//379 -f 111//111 133//133 300//300 -f 293//293 299//299 290//290 -f 338//338 242//242 519//519 -f 609//609 242//242 429//429 -f 592//592 595//595 586//586 -f 303//303 308//308 316//316 -f 309//309 752//752 743//743 -f 357//357 568//568 336//336 -f 304//304 309//309 743//743 -f 324//324 358//358 330//330 -f 838//838 353//353 350//350 -f 644//644 567//567 667//667 -f 1000//1000 359//359 1012//1012 -f 289//289 304//304 743//743 -f 855//855 707//707 854//854 -f 559//559 668//668 654//654 -f 309//309 320//320 752//752 -f 496//496 966//966 129//129 -f 720//720 293//293 291//291 -f 310//310 150//150 347//347 -f 525//525 465//465 515//515 -f 339//339 353//353 352//352 -f 932//932 955//955 939//939 -f 325//325 328//328 350//350 -f 310//310 32//32 150//150 -f 32//32 283//283 6//6 -f 319//319 563//563 671//671 -f 337//337 324//324 330//330 -f 706//706 854//854 707//707 -f 329//329 838//838 350//350 -f 631//631 682//682 769//769 -f 841//841 58//58 590//590 -f 347//347 150//150 69//69 -f 329//329 350//350 328//328 -f 534//534 539//539 530//530 -f 286//286 289//289 284//284 -f 1013//1013 1011//1011 359//359 -f 295//295 67//67 318//318 -f 517//517 523//523 525//525 -f 752//752 319//319 671//671 -f 319//319 325//325 563//563 -f 429//429 378//378 611//611 -f 242//242 609//609 340//340 -f 322//322 320//320 313//313 -f 350//350 353//353 339//339 -f 353//353 643//643 344//344 -f 483//483 371//371 361//361 -f 662//662 679//679 695//695 -f 289//289 726//726 284//284 -f 353//353 344//344 323//323 -f 275//275 545//545 387//387 -f 602//602 380//380 575//575 -f 465//465 535//535 472//472 -f 199//199 186//186 994//994 -f 554//554 275//275 494//494 -f 322//322 328//328 320//320 -f 291//291 293//293 290//290 -f 166//166 947//947 172//172 -f 256//256 240//240 122//122 -f 806//806 843//843 825//825 -f 730//730 659//659 528//528 -f 706//706 709//709 291//291 -f 208//208 214//214 60//60 -f 272//272 307//307 144//144 -f 1003//1003 549//549 997//997 -f 325//325 350//350 339//339 -f 313//313 320//320 309//309 -f 733//733 299//299 293//293 -f 351//351 144//144 234//234 -f 1//1 276//276 332//332 -f 733//733 738//738 299//299 -f 128//128 342//342 333//333 -f 1010//1010 1016//1016 1004//1004 -f 342//342 180//180 327//327 -f 337//337 318//318 324//324 -f 320//320 319//319 752//752 -f 299//299 304//304 289//289 -f 356//356 351//351 234//234 -f 344//344 192//192 323//323 -f 342//342 327//327 333//333 -f 180//180 372//372 420//420 -f 312//312 317//317 297//297 -f 342//342 301//301 372//372 -f 192//192 685//685 229//229 -f 795//795 633//633 287//287 -f 292//292 172//172 947//947 -f 316//316 409//409 203//203 -f 315//315 144//144 351//351 -f 174//174 272//272 144//144 -f 180//180 342//342 372//372 -f 318//318 1005//1005 1002//1002 -f 315//315 174//174 144//144 -f 296//296 308//308 303//303 -f 229//229 629//629 398//398 -f 914//914 296//296 303//303 -f 303//303 316//316 203//203 -f 316//316 321//321 409//409 -f 964//964 168//168 979//979 -f 369//369 83//83 365//365 -f 150//150 32//32 391//391 -f 391//391 411//411 632//632 -f 366//366 214//214 409//409 -f 25//25 436//436 437//437 -f 321//321 326//326 401//401 -f 401//401 366//366 409//409 -f 467//467 470//470 479//479 -f 395//395 401//401 326//326 -f 408//408 43//43 151//151 -f 394//394 404//404 391//391 -f 401//401 219//219 366//366 -f 396//396 401//401 395//395 -f 396//396 219//219 401//401 -f 423//423 128//128 397//397 -f 223//223 219//219 396//396 -f 119//119 98//98 12//12 -f 364//364 596//596 83//83 -f 356//356 223//223 396//396 -f 492//492 389//389 422//422 -f 83//83 596//596 43//43 -f 618//618 612//612 554//554 -f 150//150 391//391 639//639 -f 395//395 636//636 396//396 -f 343//343 356//356 396//396 -f 405//405 681//681 128//128 -f 200//200 397//397 245//245 -f 387//387 545//545 334//334 -f 229//229 398//398 174//174 -f 370//370 393//393 367//367 -f 7//7 403//403 426//426 -f 519//519 311//311 336//336 -f 710//710 495//495 809//809 -f 327//327 245//245 397//397 -f 688//688 7//7 331//331 -f 368//368 408//408 388//388 -f 385//385 415//415 393//393 -f 403//403 423//423 416//416 -f 410//410 403//403 416//416 -f 346//346 609//609 71//71 -f 150//150 639//639 69//69 -f 362//362 367//367 67//67 -f 128//128 333//333 397//397 -f 686//686 361//361 362//362 -f 545//545 504//504 311//311 -f 410//410 416//416 386//386 -f 1001//1001 998//998 1000//1000 -f 99//99 55//55 383//383 -f 7//7 426//426 331//331 -f 420//420 368//368 35//35 -f 393//393 415//415 427//427 -f 360//360 403//403 410//410 -f 595//595 459//459 216//216 -f 347//347 69//69 1009//1009 -f 611//611 378//378 610//610 -f 411//411 83//83 369//369 -f 593//593 596//596 474//474 -f 287//287 633//633 379//379 -f 837//837 1006//1006 335//335 -f 899//899 887//887 296//296 -f 174//174 149//149 272//272 -f 405//405 423//423 688//688 -f 152//152 363//363 31//31 -f 46//46 30//30 215//215 -f 410//410 386//386 102//102 -f 103//103 224//224 406//406 -f 750//750 1001//1001 1009//1009 -f 83//83 43//43 365//365 -f 394//394 460//460 404//404 -f 369//369 365//365 389//389 -f 575//575 380//380 364//364 -f 165//165 272//272 149//149 -f 165//165 274//274 272//272 -f 416//416 397//397 258//258 -f 405//405 128//128 423//423 -f 422//422 389//389 420//420 -f 492//492 632//632 389//389 -f 385//385 393//393 370//370 -f 416//416 258//258 386//386 -f 258//258 278//278 386//386 -f 443//443 523//523 516//516 -f 406//406 419//419 103//103 -f 632//632 369//369 389//389 -f 423//423 397//397 416//416 -f 23//23 470//470 22//22 -f 371//371 385//385 370//370 -f 508//508 515//515 441//441 -f 398//398 424//424 149//149 -f 149//149 424//424 165//165 -f 151//151 88//88 388//388 -f 694//694 398//398 629//629 -f 415//415 6//6 427//427 -f 423//423 403//403 7//7 -f 415//415 394//394 6//6 -f 424//424 113//113 165//165 -f 542//542 534//534 472//472 -f 368//368 365//365 408//408 -f 594//594 398//398 694//694 -f 398//398 594//594 424//424 -f 660//660 678//678 797//797 -f 6//6 391//391 32//32 -f 423//423 7//7 688//688 -f 426//426 692//692 331//331 -f 420//420 389//389 368//368 -f 379//379 384//384 212//212 -f 405//405 670//670 681//681 -f 501//501 488//488 65//65 -f 218//218 259//259 21//21 -f 368//368 37//37 35//35 -f 283//283 358//358 427//427 -f 594//594 425//425 424//424 -f 113//113 418//418 165//165 -f 55//55 87//87 383//383 -f 584//584 585//585 591//591 -f 1003//1003 997//997 994//994 -f 121//121 148//148 413//413 -f 573//573 585//585 584//584 -f 594//594 702//702 425//425 -f 418//418 407//407 261//261 -f 408//408 151//151 388//388 -f 424//424 425//425 113//113 -f 113//113 407//407 418//418 -f 426//426 360//360 98//98 -f 148//148 138//138 413//413 -f 1008//1008 751//751 1005//1005 -f 6//6 394//394 391//391 -f 702//702 399//399 425//425 -f 221//221 230//230 103//103 -f 523//523 526//526 467//467 -f 542//542 539//539 534//534 -f 419//419 177//177 221//221 -f 373//373 47//47 407//407 -f 601//601 216//216 611//611 -f 373//373 407//407 113//113 -f 138//138 382//382 413//413 -f 406//406 392//392 414//414 -f 443//443 516//516 976//976 -f 355//355 575//575 579//579 -f 355//355 579//579 376//376 -f 519//519 336//336 512//512 -f 399//399 431//431 425//425 -f 419//419 430//430 152//152 -f 283//283 427//427 6//6 -f 379//379 212//212 287//287 -f 431//431 113//113 425//425 -f 386//386 278//278 102//102 -f 385//385 2//2 415//415 -f 360//360 410//410 102//102 -f 512//512 336//336 568//568 -f 82//82 402//402 373//373 -f 373//373 383//383 47//47 -f 371//371 381//381 385//385 -f 447//447 498//498 480//480 -f 365//365 43//43 408//408 -f 574//574 585//585 991//991 -f 362//362 371//371 370//370 -f 462//462 492//492 422//422 -f 591//591 216//216 601//601 -f 142//142 449//449 156//156 -f 471//471 481//481 48//48 -f 448//448 443//443 435//435 -f 48//48 481//481 65//65 -f 800//800 64//64 786//786 -f 92//92 57//57 129//129 -f 787//787 633//633 795//795 -f 794//794 807//807 799//799 -f 732//732 848//848 710//710 -f 461//461 471//471 38//38 -f 2//2 532//532 3//3 -f 764//764 792//792 772//772 -f 3//3 460//460 2//2 -f 438//438 437//437 993//993 -f 553//553 430//430 64//64 -f 96//96 491//491 469//469 -f 501//501 500//500 469//469 -f 570//570 454//454 152//152 -f 453//453 461//461 24//24 -f 476//476 500//500 481//481 -f 491//491 457//457 463//463 -f 997//997 199//199 994//994 -f 341//341 170//170 448//448 -f 469//469 491//491 463//463 -f 8//8 17//17 443//443 -f 437//437 13//13 25//25 -f 479//479 470//470 485//485 -f 535//535 929//929 475//475 -f 453//453 444//444 436//436 -f 363//363 152//152 454//454 -f 45//45 61//61 36//36 -f 178//178 914//914 303//303 -f 863//863 859//859 855//855 -f 444//444 453//453 9//9 -f 151//151 596//596 593//593 -f 471//471 26//26 476//476 -f 620//620 404//404 548//548 -f 922//922 939//939 921//921 -f 488//488 469//469 463//463 -f 457//457 132//132 120//120 -f 800//800 466//466 64//64 -f 79//79 469//469 500//500 -f 937//937 924//924 292//292 -f 485//485 470//470 74//74 -f 25//25 461//461 453//453 -f 115//115 382//382 490//490 -f 106//106 498//498 502//502 -f 451//451 88//88 456//456 -f 945//945 952//952 998//998 -f 496//496 129//129 57//57 -f 501//501 469//469 488//488 -f 837//837 1016//1016 1006//1006 -f 471//471 48//48 38//38 -f 986//986 57//57 486//486 -f 189//189 928//928 178//178 -f 490//490 132//132 457//457 -f 494//494 482//482 451//451 -f 482//482 494//494 486//486 -f 65//65 481//481 501//501 -f 61//61 500//500 476//476 -f 438//438 167//167 437//437 -f 710//710 833//833 732//732 -f 496//496 57//57 986//986 -f 797//797 716//716 750//750 -f 96//96 469//469 79//79 -f 453//453 24//24 9//9 -f 473//473 486//486 494//494 -f 482//482 486//486 57//57 -f 467//467 458//458 470//470 -f 494//494 451//451 456//456 -f 502//502 498//498 464//464 -f 445//445 446//446 907//907 -f 60//60 214//214 366//366 -f 381//381 371//371 483//483 -f 665//665 764//764 760//760 -f 61//61 476//476 36//36 -f 432//432 445//445 907//907 -f 461//461 25//25 471//471 -f 941//941 455//455 464//464 -f 716//716 561//561 621//621 -f 443//443 976//976 435//435 -f 444//444 9//9 977//977 -f 986//986 486//486 473//473 -f 436//436 25//25 453//453 -f 929//929 967//967 475//475 -f 462//462 363//363 454//454 -f 79//79 500//500 61//61 -f 447//447 480//480 139//139 -f 522//522 446//446 445//445 -f 514//514 907//907 446//446 -f 848//848 732//732 826//826 -f 442//442 434//434 959//959 -f 498//498 447//447 464//464 -f 764//764 772//772 760//760 -f 848//848 761//761 710//710 -f 976//976 442//442 959//959 -f 800//800 786//786 996//996 -f 773//773 806//806 792//792 -f 445//445 450//450 522//522 -f 517//517 976//976 516//516 -f 1010//1010 332//332 302//302 -f 457//457 127//127 463//463 -f 465//465 452//452 515//515 -f 490//490 382//382 132//132 -f 459//459 487//487 497//497 -f 24//24 461//461 38//38 -f 976//976 517//517 442//442 -f 999//999 305//305 133//133 -f 986//986 473//473 484//484 -f 1010//1010 1004//1004 1014//1014 -f 404//404 620//620 421//421 -f 433//433 450//450 445//445 -f 850//850 841//841 842//842 -f 843//843 850//850 842//842 -f 487//487 468//468 497//497 -f 593//593 474//474 618//618 -f 467//467 479//479 535//535 -f 171//171 736//736 992//992 -f 592//592 478//478 459//459 -f 478//478 487//487 459//459 -f 956//956 468//468 487//487 -f 447//447 139//139 956//956 -f 941//941 478//478 592//592 -f 963//963 957//957 949//949 -f 491//491 490//490 457//457 -f 288//288 828//828 788//788 -f 730//730 653//653 659//659 -f 859//859 863//863 881//881 -f 435//435 985//985 448//448 -f 481//481 500//500 501//501 -f 535//535 479//479 929//929 -f 433//433 440//440 450//450 -f 58//58 288//288 788//788 -f 502//502 464//464 455//455 -f 534//534 465//465 472//472 -f 487//487 447//447 956//956 -f 433//433 926//926 440//440 -f 522//522 450//450 452//452 -f 716//716 531//531 587//587 -f 457//457 120//120 127//127 -f 653//653 715//715 851//851 -f 941//941 464//464 478//478 -f 23//23 9//9 24//24 -f 136//136 120//120 132//132 -f 492//492 454//454 558//558 -f 440//440 441//441 450//450 -f 913//913 175//175 924//924 -f 29//29 24//24 38//38 -f 151//151 593//593 88//88 -f 581//581 620//620 548//548 -f 657//657 741//741 777//777 -f 341//341 736//736 170//170 -f 462//462 454//454 492//492 -f 441//441 515//515 450//450 -f 460//460 548//548 404//404 -f 471//471 476//476 481//481 -f 450//450 515//515 452//452 -f 464//464 447//447 478//478 -f 447//447 487//487 478//478 -f 456//456 88//88 593//593 -f 476//476 26//26 33//33 -f 452//452 465//465 534//534 -f 616//616 826//826 831//831 -f 841//841 288//288 58//58 -f 608//608 295//295 1002//1002 -f 663//663 675//675 655//655 -f 67//67 295//295 536//536 -f 663//663 693//693 674//674 -f 675//675 663//663 674//674 -f 803//803 561//561 716//716 -f 536//536 608//608 509//509 -f 623//623 648//648 644//644 -f 417//417 361//361 536//536 -f 509//509 417//417 536//536 -f 614//614 608//608 550//550 -f 614//614 509//509 608//608 -f 614//614 506//506 509//509 -f 509//509 506//506 417//417 -f 506//506 527//527 417//417 -f 417//417 527//527 483//483 -f 527//527 510//510 483//483 -f 995//995 614//614 550//550 -f 518//518 527//527 506//506 -f 518//518 510//510 527//527 -f 1015//1015 614//614 995//995 -f 544//544 613//613 381//381 -f 510//510 544//544 381//381 -f 518//518 544//544 510//510 -f 2//2 613//613 532//532 -f 517//517 508//508 442//442 -f 545//545 275//275 554//554 -f 577//577 506//506 614//614 -f 668//668 597//597 580//580 -f 428//428 701//701 700//700 -f 577//577 518//518 506//506 -f 636//636 343//343 396//396 -f 1015//1015 577//577 614//614 -f 700//700 655//655 649//649 -f 543//543 576//576 602//602 -f 577//577 578//578 518//518 -f 477//477 577//577 1015//1015 -f 518//518 578//578 544//544 -f 589//589 615//615 791//791 -f 589//589 598//598 615//615 -f 791//791 768//768 565//565 -f 615//615 58//58 691//691 -f 58//58 788//788 650//650 -f 544//544 532//532 613//613 -f 631//631 164//164 676//676 -f 791//791 565//565 589//589 -f 578//578 607//607 544//544 -f 607//607 532//532 544//544 -f 598//598 590//590 615//615 -f 551//551 562//562 565//565 -f 565//565 582//582 589//589 -f 589//589 582//582 598//598 -f 406//406 224//224 392//392 -f 590//590 58//58 615//615 -f 224//224 384//384 392//392 -f 354//354 459//459 497//497 -f 701//701 645//645 663//663 -f 607//607 3//3 532//532 -f 562//562 798//798 565//565 -f 582//582 590//590 598//598 -f 142//142 132//132 449//449 -f 648//648 637//637 644//644 -f 507//507 511//511 547//547 -f 644//644 637//637 567//567 -f 565//565 798//798 582//582 -f 507//507 666//666 511//511 -f 997//997 133//133 111//111 -f 551//551 552//552 562//562 -f 552//552 798//798 562//562 -f 577//577 603//603 578//578 -f 603//603 607//607 578//578 -f 513//513 666//666 507//507 -f 528//528 537//537 551//551 -f 551//551 537//537 552//552 -f 825//825 842//842 590//590 -f 582//582 825//825 590//590 -f 705//705 700//700 704//704 -f 588//588 603//603 477//477 -f 603//603 577//577 477//477 -f 529//529 537//537 528//528 -f 571//571 825//825 798//798 -f 798//798 825//825 582//582 -f 504//504 554//554 576//576 -f 554//554 612//612 576//576 -f 519//519 512//512 766//766 -f 354//354 71//71 429//429 -f 520//520 513//513 507//507 -f 537//537 540//540 552//552 -f 549//549 133//133 997//997 -f 523//523 535//535 525//525 -f 603//603 606//606 607//607 -f 606//606 3//3 607//607 -f 520//520 507//507 869//869 -f 552//552 540//540 798//798 -f 533//533 529//529 760//760 -f 786//786 1003//1003 996//996 -f 533//533 537//537 529//529 -f 612//612 618//618 474//474 -f 414//414 392//392 59//59 -f 922//922 921//921 912//912 -f 540//540 556//556 798//798 -f 701//701 624//624 645//645 -f 658//658 840//840 697//697 -f 945//945 400//400 588//588 -f 588//588 400//400 603//603 -f 606//606 548//548 3//3 -f 537//537 533//533 540//540 -f 540//540 772//772 556//556 -f 525//525 535//535 465//465 -f 548//548 460//460 3//3 -f 414//414 59//59 725//725 -f 719//719 855//855 853//853 -f 869//869 672//672 520//520 -f 334//334 545//545 311//311 -f 665//665 513//513 520//520 -f 533//533 772//772 540//540 -f 760//760 772//772 533//533 -f 855//855 859//859 853//853 -f 664//664 654//654 845//845 -f 377//377 603//603 400//400 -f 603//603 377//377 606//606 -f 593//593 618//618 456//456 -f 599//599 617//617 616//616 -f 71//71 609//609 429//429 -f 1007//1007 619//619 400//400 -f 619//619 377//377 400//400 -f 377//377 581//581 606//606 -f 581//581 548//548 606//606 -f 387//387 473//473 275//275 -f 604//604 602//602 576//576 -f 592//592 459//459 595//595 -f 1007//1007 345//345 619//619 -f 579//579 575//575 364//364 -f 616//616 848//848 826//826 -f 64//64 430//430 725//725 -f 430//430 414//414 725//725 -f 354//354 497//497 71//71 -f 522//522 514//514 446//446 -f 430//430 419//419 414//414 -f 357//357 311//311 504//504 -f 334//334 311//311 340//340 -f 452//452 534//534 530//530 -f 314//314 836//836 617//617 -f 473//473 494//494 275//275 -f 216//216 459//459 354//354 -f 623//623 644//644 656//656 -f 674//674 769//769 675//675 -f 834//834 835//835 599//599 -f 599//599 835//835 617//617 -f 679//679 747//747 652//652 -f 737//737 665//665 520//520 -f 171//171 992//992 977//977 -f 398//398 149//149 174//174 -f 345//345 587//587 619//619 -f 10//10 964//964 166//166 -f 777//777 538//538 799//799 -f 799//799 538//538 778//778 -f 680//680 654//654 664//664 -f 572//572 835//835 832//832 -f 314//314 617//617 605//605 -f 644//644 849//849 656//656 -f 516//516 523//523 517//517 -f 570//570 553//553 466//466 -f 570//570 430//430 553//553 -f 656//656 697//697 676//676 -f 835//835 605//605 617//617 -f 619//619 620//620 581//581 -f 377//377 619//619 581//581 -f 521//521 741//741 657//657 -f 777//777 741//741 538//538 -f 378//378 314//314 605//605 -f 572//572 573//573 835//835 -f 835//835 600//600 605//605 -f 331//331 704//704 555//555 -f 587//587 620//620 619//619 -f 514//514 521//521 628//628 -f 741//741 539//539 538//538 -f 783//783 560//560 808//808 -f 573//573 584//584 835//835 -f 584//584 600//600 835//835 -f 412//412 489//489 294//294 -f 64//64 466//466 553//553 -f 650//650 682//682 691//691 -f 669//669 567//567 637//637 -f 376//376 587//587 531//531 -f 466//466 524//524 570//570 -f 514//514 628//628 724//724 -f 530//530 741//741 521//521 -f 808//808 569//569 572//572 -f 610//610 378//378 605//605 -f 181//181 314//314 378//378 -f 682//682 676//676 691//691 -f 376//376 620//620 587//587 -f 524//524 454//454 570//570 -f 530//530 539//539 741//741 -f 538//538 539//539 778//778 -f 560//560 569//569 808//808 -f 569//569 573//573 572//572 -f 600//600 610//610 605//605 -f 376//376 531//531 621//621 -f 554//554 456//456 618//618 -f 600//600 601//601 610//610 -f 181//181 294//294 314//314 -f 512//512 561//561 803//803 -f 355//355 376//376 621//621 -f 844//844 558//558 524//524 -f 584//584 601//601 600//600 -f 601//601 611//611 610//610 -f 568//568 561//561 512//512 -f 579//579 620//620 376//376 -f 421//421 620//620 579//579 -f 381//381 483//483 510//510 -f 242//242 294//294 181//181 -f 242//242 338//338 412//412 -f 294//294 242//242 412//412 -f 338//338 519//519 766//766 -f 561//561 355//355 621//621 -f 792//792 571//571 798//798 -f 454//454 524//524 558//558 -f 522//522 530//530 514//514 -f 378//378 429//429 181//181 -f 429//429 242//242 181//181 -f 512//512 803//803 766//766 -f 504//504 545//545 554//554 -f 584//584 591//591 601//601 -f 708//708 855//855 719//719 -f 872//872 886//886 889//889 -f 663//663 645//645 622//622 -f 878//878 723//723 638//638 -f 645//645 647//647 622//622 -f 836//836 761//761 617//617 -f 1007//1007 998//998 1001//1001 -f 59//59 392//392 625//625 -f 653//653 851//851 684//684 -f 563//563 683//683 671//671 -f 331//331 699//699 688//688 -f 644//644 667//667 846//846 -f 694//694 642//642 702//702 -f 703//703 626//626 312//312 -f 192//192 668//668 559//559 -f 680//680 559//559 654//654 -f 647//647 583//583 622//622 -f 931//931 961//961 943//943 -f 694//694 629//629 685//685 -f 668//668 643//643 597//597 -f 622//622 693//693 663//663 -f 536//536 686//686 67//67 -f 624//624 642//642 647//647 -f 526//526 458//458 467//467 -f 765//765 671//671 703//703 -f 395//395 661//661 636//636 -f 399//399 702//702 624//624 -f 594//594 694//694 702//702 -f 654//654 668//668 580//580 -f 691//691 676//676 697//697 -f 690//690 306//306 747//747 -f 530//530 521//521 514//514 -f 343//343 683//683 563//563 -f 391//391 632//632 639//639 -f 647//647 642//642 635//635 -f 529//529 528//528 666//666 -f 290//290 864//864 291//291 -f 703//703 671//671 683//683 -f 626//626 317//317 312//312 -f 597//597 839//839 580//580 -f 331//331 692//692 704//704 -f 597//597 816//816 839//839 -f 954//954 969//969 961//961 -f 954//954 961//961 931//931 -f 661//661 317//317 626//626 -f 701//701 689//689 624//624 -f 705//705 704//704 692//692 -f 642//642 624//624 702//702 -f 343//343 636//636 683//683 -f 730//730 715//715 653//653 -f 69//69 640//640 660//660 -f 635//635 680//680 664//664 -f 164//164 656//656 676//676 -f 699//699 555//555 695//695 -f 558//558 632//632 492//492 -f 466//466 844//844 524//524 -f 922//922 912//912 904//904 -f 632//632 558//558 639//639 -f 640//640 69//69 639//639 -f 668//668 344//344 643//643 -f 636//636 661//661 626//626 -f 634//634 639//639 558//558 -f 634//634 640//640 639//639 -f 849//849 697//697 656//656 -f 650//650 691//691 58//58 -f 844//844 634//634 558//558 -f 420//420 35//35 180//180 -f 697//697 840//840 691//691 -f 1006//1006 1010//1010 302//302 -f 838//838 643//643 353//353 -f 511//511 666//666 659//659 -f 546//546 674//674 693//693 -f 769//769 164//164 631//631 -f 675//675 662//662 655//655 -f 726//726 713//713 284//284 -f 704//704 700//700 649//649 -f 666//666 528//528 659//659 -f 608//608 1002//1002 1005//1005 -f 760//760 513//513 665//665 -f 881//881 870//870 865//865 -f 859//859 881//881 865//865 -f 675//675 769//769 662//662 -f 662//662 690//690 679//679 -f 332//332 1014//1014 1//1 -f 654//654 580//580 845//845 -f 634//634 651//651 640//640 -f 757//757 784//784 322//322 -f 677//677 335//335 678//678 -f 646//646 664//664 648//648 -f 698//698 796//796 696//696 -f 322//322 784//784 328//328 -f 335//335 687//687 678//678 -f 630//630 698//698 696//696 -f 192//192 344//344 668//668 -f 694//694 680//680 642//642 -f 335//335 681//681 687//687 -f 747//747 679//679 690//690 -f 681//681 630//630 687//687 -f 769//769 690//690 662//662 -f 555//555 704//704 695//695 -f 704//704 649//649 695//695 -f 681//681 670//670 630//630 -f 630//630 566//566 698//698 -f 673//673 627//627 698//698 -f 694//694 685//685 680//680 -f 649//649 655//655 695//695 -f 164//164 623//623 656//656 -f 564//564 673//673 698//698 -f 682//682 650//650 306//306 -f 597//597 329//329 816//816 -f 670//670 566//566 630//630 -f 375//375 698//698 566//566 -f 375//375 564//564 698//698 -f 331//331 555//555 699//699 -f 655//655 662//662 695//695 -f 587//587 345//345 750//750 -f 670//670 405//405 566//566 -f 636//636 626//626 683//683 -f 513//513 529//529 666//666 -f 680//680 685//685 559//559 -f 428//428 689//689 701//701 -f 399//399 624//624 689//689 -f 688//688 566//566 405//405 -f 845//845 669//669 637//637 -f 624//624 647//647 645//645 -f 652//652 673//673 564//564 -f 395//395 326//326 661//661 -f 521//521 657//657 628//628 -f 566//566 688//688 375//375 -f 652//652 499//499 673//673 -f 695//695 679//679 652//652 -f 723//723 628//628 657//657 -f 700//700 701//701 663//663 -f 699//699 564//564 375//375 -f 699//699 652//652 564//564 -f 703//703 683//683 626//626 -f 642//642 680//680 635//635 -f 699//699 695//695 652//652 -f 392//392 384//384 625//625 -f 845//845 580//580 839//839 -f 699//699 375//375 688//688 -f 682//682 631//631 676//676 -f 845//845 839//839 669//669 -f 428//428 700//700 705//705 -f 1008//1008 1005//1005 337//337 -f 836//836 314//314 489//489 -f 717//717 711//711 628//628 -f 826//826 847//847 830//830 -f 710//710 836//836 495//495 -f 796//796 495//495 641//641 -f 834//834 599//599 616//616 -f 761//761 836//836 710//710 -f 921//921 931//931 930//930 -f 749//749 765//765 312//312 -f 945//945 588//588 477//477 -f 799//799 822//822 793//793 -f 439//439 732//732 774//774 -f 285//285 731//731 298//298 -f 731//731 742//742 749//749 -f 749//749 742//742 765//765 -f 285//285 718//718 731//731 -f 847//847 732//732 439//439 -f 851//851 715//715 852//852 -f 439//439 173//173 493//493 -f 852//852 557//557 853//853 -f 557//557 852//852 715//715 -f 590//590 842//842 841//841 -f 742//742 752//752 765//765 -f 752//752 671//671 765//765 -f 712//712 724//724 711//711 -f 412//412 812//812 489//489 -f 766//766 779//779 812//812 -f 812//812 775//775 641//641 -f 711//711 724//724 628//628 -f 812//812 641//641 495//495 -f 718//718 742//742 731//731 -f 715//715 730//730 722//722 -f 774//774 833//833 627//627 -f 696//696 678//678 630//630 -f 834//834 616//616 831//831 -f 843//843 493//493 850//850 -f 847//847 439//439 493//493 -f 583//583 693//693 622//622 -f 779//779 716//716 797//797 -f 821//821 843//843 806//806 -f 718//718 743//743 742//742 -f 743//743 752//752 742//742 -f 807//807 818//818 822//822 -f 756//756 764//764 665//665 -f 640//640 651//651 660//660 -f 970//970 993//993 727//727 -f 294//294 489//489 314//314 -f 718//718 726//726 743//743 -f 677//677 660//660 651//651 -f 931//931 943//943 930//930 -f 832//832 835//835 834//834 -f 783//783 794//794 778//778 -f 664//664 637//637 648//648 -f 793//793 822//822 811//811 -f 778//778 794//794 799//799 -f 912//912 921//921 930//930 -f 832//832 834//834 831//831 -f 554//554 494//494 456//456 -f 335//335 677//677 651//651 -f 737//737 657//657 665//665 -f 833//833 809//809 796//796 -f 878//878 717//717 723//723 -f 329//329 802//802 816//816 -f 821//821 830//830 843//843 -f 999//999 133//133 549//549 -f 449//449 138//138 156//156 -f 572//572 832//832 808//808 -f 714//714 707//707 708//708 -f 493//493 173//173 288//288 -f 499//499 173//173 673//673 -f 827//827 800//800 1016//1016 -f 546//546 646//646 648//648 -f 934//934 387//387 334//334 -f 832//832 819//819 808//808 -f 738//738 733//733 753//753 -f 784//784 776//776 802//802 -f 756//756 793//793 773//773 -f 229//229 685//685 629//629 -f 827//827 466//466 800//800 -f 489//489 812//812 495//495 -f 828//828 173//173 499//499 -f 775//775 779//779 797//797 -f 776//776 785//785 802//802 -f 816//816 669//669 839//839 -f 811//811 821//821 806//806 -f 753//753 744//744 757//757 -f 744//744 776//776 757//757 -f 733//733 744//744 753//753 -f 813//813 802//802 785//785 -f 813//813 816//816 802//802 -f 816//816 813//813 669//669 -f 329//329 597//597 838//838 -f 939//939 931//931 921//921 -f 775//775 797//797 678//678 -f 293//293 728//728 733//733 -f 733//733 728//728 744//744 -f 813//813 820//820 669//669 -f 765//765 703//703 312//312 -f 822//822 821//821 811//811 -f 672//672 638//638 723//723 -f 293//293 720//720 728//728 -f 767//767 776//776 744//744 -f 696//696 796//796 641//641 -f 773//773 811//811 806//806 -f 300//300 305//305 287//287 -f 776//776 767//767 785//785 -f 785//785 810//810 813//813 -f 499//499 652//652 747//747 -f 827//827 1016//1016 837//837 -f 667//667 669//669 820//820 -f 669//669 667//667 567//567 -f 592//592 586//586 228//228 -f 728//728 754//754 744//744 -f 767//767 781//781 785//785 -f 781//781 780//780 785//785 -f 780//780 810//810 785//785 -f 514//514 724//724 907//907 -f 777//777 756//756 657//657 -f 826//826 830//830 818//818 -f 412//412 766//766 812//812 -f 754//754 767//767 744//744 -f 810//810 814//814 813//813 -f 813//813 814//814 820//820 -f 793//793 811//811 773//773 -f 969//969 977//977 961//961 -f 583//583 647//647 646//646 -f 546//546 583//583 646//646 -f 728//728 734//734 754//754 -f 977//977 992//992 961//961 -f 493//493 288//288 850//850 -f 720//720 734//734 728//728 -f 734//734 755//755 754//754 -f 781//781 810//810 780//780 -f 846//846 820//820 814//814 -f 827//827 844//844 466//466 -f 291//291 709//709 720//720 -f 709//709 721//721 720//720 -f 720//720 721//721 734//734 -f 767//767 754//754 755//755 -f 777//777 793//793 756//756 -f 734//734 739//739 755//755 -f 789//789 814//814 810//810 -f 846//846 667//667 820//820 -f 716//716 587//587 750//750 -f 623//623 546//546 648//648 -f 693//693 583//583 546//546 -f 847//847 826//826 732//732 -f 755//755 758//758 767//767 -f 767//767 758//758 781//781 -f 758//758 770//770 781//781 -f 779//779 775//775 812//812 -f 706//706 707//707 709//709 -f 789//789 810//810 781//781 -f 770//770 789//789 781//781 -f 815//815 846//846 814//814 -f 849//849 644//644 846//846 -f 737//737 520//520 672//672 -f 698//698 627//627 796//796 -f 338//338 766//766 412//412 -f 739//739 762//762 755//755 -f 755//755 762//762 758//758 -f 818//818 821//821 822//822 -f 737//737 723//723 657//657 -f 815//815 829//829 846//846 -f 734//734 721//721 739//739 -f 739//739 740//740 762//762 -f 762//762 770//770 758//758 -f 829//829 849//849 846//846 -f 775//775 678//678 696//696 -f 789//789 815//815 814//814 -f 808//808 794//794 783//783 -f 808//808 819//819 794//794 -f 831//831 826//826 818//818 -f 634//634 837//837 651//651 -f 714//714 721//721 709//709 -f 770//770 790//790 789//789 -f 634//634 844//844 827//827 -f 721//721 735//735 739//739 -f 735//735 740//740 739//739 -f 789//789 790//790 815//815 -f 164//164 674//674 546//546 -f 709//709 707//707 714//714 -f 657//657 756//756 665//665 -f 815//815 790//790 804//804 -f 804//804 658//658 815//815 -f 815//815 658//658 829//829 -f 658//658 849//849 829//829 -f 762//762 771//771 770//770 -f 771//771 790//790 770//770 -f 286//286 875//875 864//864 -f 634//634 827//827 837//837 -f 740//740 763//763 762//762 -f 658//658 697//697 849//849 -f 164//164 769//769 674//674 -f 809//809 495//495 796//796 -f 557//557 719//719 853//853 -f 646//646 647//647 635//635 -f 627//627 833//833 796//796 -f 745//745 735//735 721//721 -f 745//745 740//740 735//735 -f 745//745 763//763 740//740 -f 762//762 763//763 771//771 -f 732//732 833//833 774//774 -f 819//819 807//807 794//794 -f 719//719 721//721 714//714 -f 804//804 817//817 658//658 -f 633//633 625//625 379//379 -f 976//976 968//968 435//435 -f 771//771 782//782 790//790 -f 782//782 804//804 790//790 -f 850//850 288//288 841//841 -f 659//659 547//547 511//511 -f 830//830 493//493 843//843 -f 799//799 793//793 777//777 -f 708//708 719//719 714//714 -f 729//729 721//721 719//719 -f 729//729 745//745 721//721 -f 817//817 823//823 658//658 -f 288//288 173//173 828//828 -f 756//756 773//773 764//764 -f 787//787 795//795 999//999 -f 763//763 782//782 771//771 -f 823//823 840//840 658//658 -f 774//774 627//627 673//673 -f 799//799 807//807 822//822 -f 717//717 712//712 711//711 -f 955//955 954//954 939//939 -f 727//727 977//977 969//969 -f 729//729 759//759 745//745 -f 782//782 817//817 804//804 -f 902//902 907//907 724//724 -f 549//549 787//787 999//999 -f 550//550 608//608 751//751 -f 745//745 759//759 763//763 -f 831//831 818//818 807//807 -f 830//830 847//847 493//493 -f 890//890 886//886 872//872 -f 59//59 633//633 787//787 -f 782//782 805//805 817//817 -f 824//824 823//823 817//817 -f 625//625 633//633 59//59 -f 557//557 722//722 719//719 -f 719//719 722//722 729//729 -f 768//768 782//782 763//763 -f 823//823 824//824 840//840 -f 935//935 434//434 441//441 -f 746//746 759//759 729//729 -f 768//768 763//763 759//759 -f 832//832 831//831 819//819 -f 439//439 774//774 173//173 -f 505//505 508//508 441//441 -f 748//748 787//787 549//549 -f 768//768 805//805 782//782 -f 817//817 805//805 824//824 -f 836//836 489//489 495//495 -f 848//848 616//616 761//761 -f 173//173 774//774 673//673 -f 434//434 442//442 505//505 -f 557//557 715//715 722//722 -f 746//746 729//729 722//722 -f 628//628 723//723 717//717 -f 940//940 963//963 949//949 -f 59//59 787//787 748//748 -f 505//505 441//441 434//434 -f 833//833 710//710 809//809 -f 551//551 759//759 746//746 -f 551//551 768//768 759//759 -f 617//617 761//761 616//616 -f 678//678 687//687 630//630 -f 893//893 897//897 885//885 -f 528//528 551//551 746//746 -f 551//551 565//565 768//768 -f 791//791 805//805 768//768 -f 546//546 623//623 164//164 -f 305//305 999//999 795//795 -f 361//361 686//686 536//536 -f 786//786 748//748 549//549 -f 775//775 696//696 641//641 -f 722//722 730//730 746//746 -f 730//730 528//528 746//746 -f 791//791 824//824 805//805 -f 824//824 615//615 840//840 -f 840//840 615//615 691//691 -f 1007//1007 400//400 945//945 -f 1000//1000 1013//1013 359//359 -f 526//526 523//523 443//443 -f 615//615 824//824 791//791 -f 748//748 725//725 59//59 -f 776//776 784//784 757//757 -f 621//621 531//531 716//716 -f 951//951 950//950 933//933 -f 891//891 906//906 898//898 -f 877//877 876//876 713//713 -f 718//718 877//877 713//713 -f 477//477 1015//1015 948//948 -f 982//982 978//978 438//438 -f 166//166 963//963 950//950 -f 972//972 971//971 944//944 -f 906//906 933//933 910//910 -f 937//937 951//951 933//933 -f 951//951 166//166 950//950 -f 296//296 914//914 899//899 -f 914//914 925//925 899//899 -f 952//952 948//948 1013//1013 -f 917//917 946//946 893//893 -f 948//948 945//945 477//477 -f 507//507 503//503 869//869 -f 891//891 876//876 877//877 -f 945//945 948//948 952//952 -f 436//436 727//727 437//437 -f 899//899 925//925 911//911 -f 862//862 863//863 856//856 -f 936//936 933//933 940//940 -f 970//970 969//969 954//954 -f 864//864 872//872 868//868 -f 917//917 893//893 915//915 -f 979//979 978//978 957//957 -f 905//905 917//917 915//915 -f 889//889 885//885 871//871 -f 444//444 727//727 436//436 -f 897//897 916//916 923//923 -f 340//340 346//346 334//334 -f 932//932 939//939 922//922 -f 978//978 979//979 987//987 -f 963//963 166//166 964//964 -f 1002//1002 295//295 318//318 -f 876//876 891//891 882//882 -f 891//891 898//898 882//882 -f 911//911 906//906 891//891 -f 863//863 862//862 866//866 -f 911//911 937//937 906//906 -f 933//933 918//918 910//910 -f 947//947 166//166 951//951 -f 950//950 963//963 940//940 -f 946//946 944//944 893//893 -f 346//346 374//374 334//334 -f 374//374 934//934 334//334 -f 886//886 905//905 915//915 -f 957//957 964//964 979//979 -f 875//875 890//890 872//872 -f 881//881 897//897 870//870 -f 868//868 872//872 889//889 -f 286//286 864//864 290//290 -f 875//875 872//872 864//864 -f 947//947 951//951 937//937 -f 933//933 936//936 927//927 -f 484//484 473//473 934//934 -f 882//882 875//875 876//876 -f 962//962 982//982 970//970 -f 915//915 893//893 885//885 -f 863//863 866//866 881//881 -f 925//925 913//913 911//911 -f 957//957 978//978 962//962 -f 569//569 991//991 573//573 -f 374//374 938//938 934//934 -f 978//978 982//982 962//962 -f 866//866 871//871 881//881 -f 956//956 374//374 468//468 -f 938//938 973//973 934//934 -f 991//991 569//569 974//974 -f 374//374 956//956 938//938 -f 986//986 484//484 934//934 -f 973//973 986//986 934//934 -f 963//963 964//964 957//957 -f 885//885 881//881 871//871 -f 887//887 891//891 877//877 -f 574//574 228//228 586//586 -f 944//944 971//971 955//955 -f 854//854 856//856 855//855 -f 388//388 145//145 211//211 -f 916//916 944//944 955//955 -f 856//856 863//863 855//855 -f 990//990 973//973 938//938 -f 916//916 932//932 923//923 -f 970//970 727//727 969//969 -f 991//991 975//975 801//801 -f 801//801 989//989 574//574 -f 938//938 956//956 990//990 -f 974//974 975//975 991//991 -f 990//990 983//983 973//973 -f 560//560 975//975 974//974 -f 982//982 993//993 970//970 -f 973//973 496//496 986//986 -f 574//574 989//989 228//228 -f 989//989 941//941 228//228 -f 982//982 438//438 993//993 -f 975//975 989//989 801//801 -f 966//966 496//496 973//973 -f 957//957 962//962 949//949 -f 139//139 990//990 956//956 -f 432//432 433//433 445//445 -f 927//927 946//946 917//917 -f 560//560 984//984 975//975 -f 975//975 919//919 989//989 -f 139//139 253//253 990//990 -f 983//983 966//966 973//973 -f 218//218 965//965 249//249 -f 918//918 933//933 927//927 -f 975//975 348//348 919//919 -f 253//253 983//983 990//990 -f 965//965 966//966 983//983 -f 984//984 348//348 975//975 -f 885//885 886//886 915//915 -f 935//935 440//440 926//926 -f 783//783 942//942 560//560 -f 560//560 942//942 984//984 -f 455//455 941//941 989//989 -f 965//965 983//983 253//253 -f 712//712 896//896 902//902 -f 902//902 432//432 907//907 -f 887//887 911//911 891//891 -f 988//988 455//455 989//989 -f 860//860 856//856 706//706 -f 866//866 864//864 868//868 -f 910//910 905//905 894//894 -f 876//876 875//875 284//284 -f 919//919 981//981 989//989 -f 913//913 924//924 937//937 -f 284//284 875//875 286//286 -f 896//896 926//926 902//902 -f 926//926 432//432 902//902 -f 727//727 444//444 977//977 -f 981//981 988//988 989//989 -f 918//918 917//917 905//905 -f 1007//1007 945//945 998//998 -f 778//778 541//541 942//942 -f 783//783 778//778 942//942 -f 195//195 175//175 913//913 -f 903//903 712//712 717//717 -f 995//995 550//550 751//751 -f 348//348 981//981 919//919 -f 860//860 862//862 856//856 -f 878//878 903//903 717//717 -f 432//432 926//926 433//433 -f 541//541 984//984 942//942 -f 864//864 866//866 860//860 -f 903//903 896//896 712//712 -f 959//959 434//434 935//935 -f 984//984 958//958 348//348 -f 958//958 981//981 348//348 -f 910//910 918//918 905//905 -f 913//913 937//937 911//911 -f 926//926 896//896 903//903 -f 984//984 541//541 958//958 -f 291//291 860//860 706//706 -f 541//541 542//542 958//958 -f 868//868 871//871 866//866 -f 879//879 903//903 878//878 -f 958//958 967//967 981//981 -f 455//455 76//76 502//502 -f 178//178 928//928 925//925 -f 387//387 934//934 473//473 -f 988//988 900//900 455//455 -f 868//868 889//889 871//871 -f 285//285 887//887 877//877 -f 879//879 901//901 903//903 -f 901//901 926//926 903//903 -f 929//929 981//981 967//967 -f 981//981 900//900 988//988 -f 900//900 76//76 455//455 -f 894//894 905//905 886//886 -f 879//879 878//878 638//638 -f 542//542 967//967 958//958 -f 929//929 900//900 981//981 -f 869//869 879//879 638//638 -f 935//935 926//926 901//901 -f 916//916 955//955 932//932 -f 950//950 940//940 933//933 -f 547//547 857//857 503//503 -f 503//503 857//857 869//869 -f 959//959 968//968 976//976 -f 920//920 935//935 901//901 -f 440//440 935//935 441//441 -f 1015//1015 1013//1013 948//948 -f 684//684 857//857 547//547 -f 880//880 879//879 869//869 -f 880//880 895//895 879//879 -f 895//895 901//901 879//879 -f 953//953 959//959 935//935 -f 953//953 968//968 959//959 -f 296//296 887//887 285//285 -f 874//874 869//869 857//857 -f 968//968 985//985 435//435 -f 890//890 894//894 886//886 -f 893//893 916//916 897//897 -f 953//953 985//985 968//968 -f 479//479 900//900 929//929 -f 858//858 874//874 857//857 -f 920//920 953//953 935//935 -f 889//889 886//886 885//885 -f 937//937 933//933 906//906 -f 858//858 857//857 684//684 -f 874//874 880//880 869//869 -f 908//908 901//901 895//895 -f 778//778 539//539 541//541 -f 479//479 980//980 900//900 -f 900//900 980//980 76//76 -f 888//888 895//895 880//880 -f 485//485 980//980 479//479 -f 980//980 85//85 76//76 -f 706//706 856//856 854//854 -f 858//858 684//684 851//851 -f 960//960 985//985 953//953 -f 980//980 73//73 85//85 -f 914//914 178//178 925//925 -f 873//873 874//874 858//858 -f 873//873 883//883 874//874 -f 883//883 880//880 874//874 -f 909//909 895//895 888//888 -f 895//895 909//909 908//908 -f 960//960 953//953 920//920 -f 992//992 341//341 985//985 -f 539//539 542//542 541//541 -f 861//861 873//873 858//858 -f 960//960 992//992 985//985 -f 965//965 129//129 966//966 -f 485//485 74//74 980//980 -f 74//74 73//73 980//980 -f 291//291 864//864 860//860 -f 852//852 858//858 851//851 -f 167//167 438//438 978//978 -f 861//861 867//867 873//873 -f 892//892 883//883 873//873 -f 736//736 341//341 992//992 -f 285//285 877//877 718//718 -f 503//503 507//507 547//547 -f 867//867 892//892 873//873 -f 899//899 911//911 887//887 -f 893//893 944//944 916//916 -f 946//946 972//972 944//944 -f 918//918 927//927 917//917 -f 943//943 961//961 960//960 -f 859//859 861//861 858//858 -f 881//881 885//885 897//897 -f 852//852 859//859 858//858 -f 904//904 909//909 888//888 -f 925//925 928//928 913//913 -f 861//861 865//865 867//867 -f 865//865 870//870 867//867 -f 870//870 892//892 867//867 -f 904//904 912//912 909//909 -f 861//861 859//859 865//865 -f 884//884 892//892 870//870 -f 961//961 992//992 960//960 -f 853//853 859//859 852//852 -# 2000 faces, 0 coords texture - -# End of File diff --git a/ICE/Assets/test/AssetBankTest.cpp b/ICE/Assets/test/AssetBankTest.cpp index 28c789e2..7c7ccd11 100644 --- a/ICE/Assets/test/AssetBankTest.cpp +++ b/ICE/Assets/test/AssetBankTest.cpp @@ -1,65 +1,63 @@ -// -// Created by Thomas Ibanez on 24.02.21. -// -#define STB_IMAGE_IMPLEMENTATION -#include - -#include "AssetBank.h" -#include "NoneGraphicsFactory.h" - -using namespace ICE; - - -TEST(AssetBankTest, AddedAssetsCanBeRetrieved) { - NoneGraphicsFactory g_fac; - AssetBank ab(std::make_shared(g_fac)); - auto mtl = std::make_shared(); - ab.addAsset("a_ice_test_mtl", mtl); - ASSERT_EQ(ab.getAsset("a_ice_test_mtl"), mtl); - ASSERT_EQ(ab.getAsset("lol"), nullptr); - - auto dummy_vert = std::vector(); - dummy_vert.emplace_back(1, 1, 1); - auto mesh = std::make_shared(dummy_vert, std::vector(), std::vector(), std::vector()); - ab.addAsset("a_ice_test_mesh", mesh); - ASSERT_EQ(ab.getAsset("a_ice_test_mesh"), mesh); - ASSERT_EQ(ab.getAsset("lel"), nullptr); - - auto tex = g_fac.createTexture2D("Not needed for this"); - ab.addAsset("a_ice_test_tex", tex); - ASSERT_EQ(ab.getAsset("a_ice_test_tex"), tex); - ASSERT_EQ(ab.getAsset("lil"), nullptr); - - auto shader = g_fac.createShader("", ""); - ab.addAsset("a_ice_test_shader", shader); - ASSERT_EQ(ab.getAsset("a_ice_test_shader"), shader); - ASSERT_EQ(ab.getAsset("lul"), nullptr); -} - -TEST(AssetBankTest, AssetsCanBeRenamed) { - AssetBank ab(std::make_shared()); - auto mtl = std::make_shared(); - ab.addAsset("a_ice_test_mtl", mtl); - ASSERT_EQ(ab.getAsset("a_ice_test_mtl"), mtl); - ASSERT_EQ(ab.getAsset("lol"), nullptr); - - ab.renameAsset(AssetPath("Materials/a_ice_test_mtl"), AssetPath("Materials/lol")); - ASSERT_EQ(ab.getAsset("lol"), mtl); - ASSERT_EQ(ab.getAsset("a_ice_test_mtl"), nullptr); -} - -TEST(AssetBankTest, GetNameReturnsCorrectName) { - AssetBank ab(std::make_shared()); - auto mtl = std::make_shared(); - ab.addAsset("a_ice_test_mtl", mtl); - ASSERT_EQ(AssetPath("Materials/a_ice_test_mtl"), ab.getName(ab.getUID(AssetPath("Materials/a_ice_test_mtl")))); - ASSERT_EQ(AssetPath(""), ab.getName(0)); -} - -TEST(AssetBankTest, NameInUseBehavesCorrectly) { - AssetBank ab(std::make_shared()); - auto mtl = std::make_shared(); - ab.addAsset("a_ice_test_mtl", mtl); - ASSERT_TRUE(ab.nameInUse(AssetPath::WithTypePrefix("a_ice_test_mtl"))); - ASSERT_FALSE(ab.nameInUse(AssetPath::WithTypePrefix("hey"))); -} +// +// Created by Thomas Ibanez on 24.02.21. +// +#define STB_IMAGE_IMPLEMENTATION +#include + +#include "AssetBank.h" +#include "NoneGraphicsFactory.h" + +using namespace ICE; + + +TEST(AssetBankTest, AddedAssetsCanBeRetrieved) { + NoneGraphicsFactory g_fac; + AssetBank ab(std::make_shared(g_fac)); + auto mtl = std::make_shared(); + ab.addAsset("a_ice_test_mtl", mtl); + ASSERT_EQ(ab.getAsset("a_ice_test_mtl"), mtl); + ASSERT_EQ(ab.getAsset("lol"), nullptr); + + auto mesh = std::make_shared(MeshData{{Eigen::Vector3f()}}); + ab.addAsset("a_ice_test_mesh", mesh); + ASSERT_EQ(ab.getAsset("a_ice_test_mesh"), mesh); + ASSERT_EQ(ab.getAsset("lel"), nullptr); + + auto tex = g_fac.createTexture2D("Not needed for this"); + ab.addAsset("a_ice_test_tex", tex); + ASSERT_EQ(ab.getAsset("a_ice_test_tex"), tex); + ASSERT_EQ(ab.getAsset("lil"), nullptr); + + auto shader = g_fac.createShader("", ""); + ab.addAsset("a_ice_test_shader", shader); + ASSERT_EQ(ab.getAsset("a_ice_test_shader"), shader); + ASSERT_EQ(ab.getAsset("lul"), nullptr); +} + +TEST(AssetBankTest, AssetsCanBeRenamed) { + AssetBank ab(std::make_shared()); + auto mtl = std::make_shared(); + ab.addAsset("a_ice_test_mtl", mtl); + ASSERT_EQ(ab.getAsset("a_ice_test_mtl"), mtl); + ASSERT_EQ(ab.getAsset("lol"), nullptr); + + ab.renameAsset(AssetPath("Materials/a_ice_test_mtl"), AssetPath("Materials/lol")); + ASSERT_EQ(ab.getAsset("lol"), mtl); + ASSERT_EQ(ab.getAsset("a_ice_test_mtl"), nullptr); +} + +TEST(AssetBankTest, GetNameReturnsCorrectName) { + AssetBank ab(std::make_shared()); + auto mtl = std::make_shared(); + ab.addAsset("a_ice_test_mtl", mtl); + ASSERT_EQ(AssetPath("Materials/a_ice_test_mtl"), ab.getName(ab.getUID(AssetPath("Materials/a_ice_test_mtl")))); + ASSERT_EQ(AssetPath(""), ab.getName(0)); +} + +TEST(AssetBankTest, NameInUseBehavesCorrectly) { + AssetBank ab(std::make_shared()); + auto mtl = std::make_shared(); + ab.addAsset("a_ice_test_mtl", mtl); + ASSERT_TRUE(ab.nameInUse(AssetPath::WithTypePrefix("a_ice_test_mtl"))); + ASSERT_FALSE(ab.nameInUse(AssetPath::WithTypePrefix("hey"))); +} diff --git a/ICE/Components/include/AnimationComponent.h b/ICE/Components/include/AnimationComponent.h new file mode 100644 index 00000000..d60c360e --- /dev/null +++ b/ICE/Components/include/AnimationComponent.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +namespace ICE { +struct AnimationComponent { + std::string currentAnimation; + double currentTime = 0.0; + double speed = 1.0; + bool playing = true; + bool loop = true; +}; +} // namespace ICE \ No newline at end of file diff --git a/ICE/Components/include/Component.h b/ICE/Components/include/Component.h index a1bf9fac..8d916063 100644 --- a/ICE/Components/include/Component.h +++ b/ICE/Components/include/Component.h @@ -1,172 +1,172 @@ -// -// Created by Thomas Ibanez on 16.11.20. -// - -#ifndef ICE_COMPONENT_H -#define ICE_COMPONENT_H - -#include - -#include -#include -#include - -namespace ICE { - -using ComponentType = std::uint8_t; - -struct Component {}; - -class IComponentArray { - public: - virtual ~IComponentArray() = default; - virtual void entityDestroyed(Entity entity) = 0; -}; - -template -class ComponentArray : public IComponentArray { - public: - void insertData(Entity entity, T component) { - assert(entityToIndexMap.find(entity) == entityToIndexMap.end() && "Component added to same entity more than once."); - - // Put new entry at end and update the maps - size_t newIndex = size; - entityToIndexMap[entity] = newIndex; - indexToEntityMap[newIndex] = entity; - if (size < componentArray.size()) { - componentArray[newIndex] = component; - } else { - componentArray.push_back(component); - } - size++; - } - - void removeData(Entity entity) { - assert(entityToIndexMap.find(entity) != entityToIndexMap.end() && "Removing non-existent component."); - - // Copy element at end into deleted element's place to maintain density - size_t indexOfRemovedEntity = entityToIndexMap[entity]; - size_t indexOfLastElement = size - 1; - componentArray[indexOfRemovedEntity] = componentArray[indexOfLastElement]; - - // Update map to point to moved spot - Entity entityOfLastElement = indexToEntityMap[indexOfLastElement]; - entityToIndexMap[entityOfLastElement] = indexOfRemovedEntity; - indexToEntityMap[indexOfRemovedEntity] = entityOfLastElement; - - entityToIndexMap.erase(entity); - indexToEntityMap.erase(indexOfLastElement); - - size--; - } - - T* getData(Entity entity) { - assert(entityToIndexMap.find(entity) != entityToIndexMap.end() && "Retrieving non-existent component."); - - // Return a reference to the entity's component - return &(componentArray[entityToIndexMap[entity]]); - } - - void entityDestroyed(Entity entity) override { - if (entityToIndexMap.find(entity) != entityToIndexMap.end()) { - // Remove the entity's component if it existed - removeData(entity); - } - } - - private: - // The packed array of components (of generic type T), - // set to a specified maximum amount, matching the maximum number - // of entities allowed to exist simultaneously, so that each entity - // has a unique spot. - std::vector componentArray; - - // Map from an entity ID to an array index. - std::unordered_map entityToIndexMap; - - // Map from an array index to an entity ID. - std::unordered_map indexToEntityMap; - - // Total size of valid entries in the array. - size_t size; -}; - -class ComponentManager { - public: - template - void registerComponent() { - auto const& type = typeid(T); - - assert(componentTypes.find(type) == componentTypes.end() && "Registering component type more than once."); - - // Add this component type to the component type map - componentTypes.insert({type, nextComponentType}); - - // Create a ComponentArray pointer and add it to the component arrays map - componentArrays.insert({type, std::make_shared>()}); - - // Increment the value so that the next component registered will be different - ++nextComponentType; - } - - template - ComponentType getComponentType() { - auto const& type = typeid(T); - - assert(componentTypes.find(type) != componentTypes.end() && "Component not registered before use."); - - // Return this component's type - used for creating signatures - return componentTypes[type]; - } - - template - void addComponent(Entity entity, T component) { - // Add a component to the array for an entity - getComponentArray()->insertData(entity, component); - } - - template - void removeComponent(Entity entity) { - // Remove a component from the array for an entity - getComponentArray()->removeData(entity); - } - - template - T* getComponent(Entity entity) { - // Get a reference to a component from the array for an entity - return getComponentArray()->getData(entity); - } - - void entityDestroyed(Entity entity) { - // Notify each component array that an entity has been destroyed - // If it has a component for that entity, it will remove it - for (auto const& pair : componentArrays) { - auto const& component = pair.second; - - component->entityDestroyed(entity); - } - } - - private: - // Map from type string pointer to a component type - std::unordered_map componentTypes{}; - - // Map from type string pointer to a component array - std::unordered_map> componentArrays{}; - - // The component type to be assigned to the next registered component - starting at 0 - ComponentType nextComponentType{}; - - // Convenience function to get the statically casted pointer to the ComponentArray of type T. - template - std::shared_ptr> getComponentArray() { - auto const& type = typeid(T); - - assert(componentTypes.find(type) != componentTypes.end() && "Component not registered before use."); - - return std::static_pointer_cast>(componentArrays[type]); - } -}; -} // namespace ICE - -#endif //ICE_COMPONENT_H +// +// Created by Thomas Ibanez on 16.11.20. +// + +#ifndef ICE_COMPONENT_H +#define ICE_COMPONENT_H + +#include + +#include +#include +#include + +namespace ICE { + +using ComponentType = std::uint8_t; + +struct Component {}; + +class IComponentArray { + public: + virtual ~IComponentArray() = default; + virtual void entityDestroyed(Entity entity) = 0; +}; + +template +class ComponentArray : public IComponentArray { + public: + void insertData(Entity entity, T component) { + assert(entityToIndexMap.find(entity) == entityToIndexMap.end() && "Component added to same entity more than once."); + + // Put new entry at end and update the maps + size_t newIndex = size; + entityToIndexMap[entity] = newIndex; + indexToEntityMap[newIndex] = entity; + if (size < componentArray.size()) { + componentArray[newIndex] = component; + } else { + componentArray.push_back(component); + } + size++; + } + + void removeData(Entity entity) { + assert(entityToIndexMap.find(entity) != entityToIndexMap.end() && "Removing non-existent component."); + + // Copy element at end into deleted element's place to maintain density + size_t indexOfRemovedEntity = entityToIndexMap[entity]; + size_t indexOfLastElement = size - 1; + componentArray[indexOfRemovedEntity] = componentArray[indexOfLastElement]; + + // Update map to point to moved spot + Entity entityOfLastElement = indexToEntityMap[indexOfLastElement]; + entityToIndexMap[entityOfLastElement] = indexOfRemovedEntity; + indexToEntityMap[indexOfRemovedEntity] = entityOfLastElement; + + entityToIndexMap.erase(entity); + indexToEntityMap.erase(indexOfLastElement); + + size--; + } + + T* getData(Entity entity) { + assert(entityToIndexMap.find(entity) != entityToIndexMap.end() && "Retrieving non-existent component."); + + // Return a reference to the entity's component + return &(componentArray[entityToIndexMap[entity]]); + } + + void entityDestroyed(Entity entity) override { + if (entityToIndexMap.find(entity) != entityToIndexMap.end()) { + // Remove the entity's component if it existed + removeData(entity); + } + } + + private: + // The packed array of components (of generic type T), + // set to a specified maximum amount, matching the maximum number + // of entities allowed to exist simultaneously, so that each entity + // has a unique spot. + std::vector componentArray; + + // Map from an entity ID to an array index. + std::unordered_map entityToIndexMap; + + // Map from an array index to an entity ID. + std::unordered_map indexToEntityMap; + + // Total size of valid entries in the array. + size_t size; +}; + +class ComponentManager { + public: + template + void registerComponent() { + auto const& type = typeid(T); + + assert(componentTypes.find(type) == componentTypes.end() && "Registering component type more than once."); + + // Add this component type to the component type map + componentTypes.insert({type, nextComponentType}); + + // Create a ComponentArray pointer and add it to the component arrays map + componentArrays.insert({type, std::make_shared>()}); + + // Increment the value so that the next component registered will be different + ++nextComponentType; + } + + template + ComponentType getComponentType() const { + auto const& type = typeid(T); + + assert(componentTypes.find(type) != componentTypes.end() && "Component not registered before use."); + + // Return this component's type - used for creating signatures + return componentTypes.at(type); + } + + template + void addComponent(Entity entity, T component) { + // Add a component to the array for an entity + getComponentArray()->insertData(entity, component); + } + + template + void removeComponent(Entity entity) { + // Remove a component from the array for an entity + getComponentArray()->removeData(entity); + } + + template + T* getComponent(Entity entity) { + // Get a reference to a component from the array for an entity + return getComponentArray()->getData(entity); + } + + void entityDestroyed(Entity entity) { + // Notify each component array that an entity has been destroyed + // If it has a component for that entity, it will remove it + for (auto const& pair : componentArrays) { + auto const& component = pair.second; + + component->entityDestroyed(entity); + } + } + + private: + // Map from type string pointer to a component type + std::unordered_map componentTypes{}; + + // Map from type string pointer to a component array + std::unordered_map> componentArrays{}; + + // The component type to be assigned to the next registered component - starting at 0 + ComponentType nextComponentType{}; + + // Convenience function to get the statically casted pointer to the ComponentArray of type T. + template + std::shared_ptr> getComponentArray() { + auto const& type = typeid(T); + + assert(componentTypes.find(type) != componentTypes.end() && "Component not registered before use."); + + return std::static_pointer_cast>(componentArrays[type]); + } +}; +} // namespace ICE + +#endif //ICE_COMPONENT_H diff --git a/ICE/Components/include/TransformComponent.h b/ICE/Components/include/TransformComponent.h index d14aa282..1ac2de52 100644 --- a/ICE/Components/include/TransformComponent.h +++ b/ICE/Components/include/TransformComponent.h @@ -20,7 +20,7 @@ struct TransformComponent : public Component { Eigen::Vector3f getRotation() const { return m_rotation; } Eigen::Vector3f getScale() const { return m_scale; } - Eigen::Matrix4f getModelMatrix() { + Eigen::Matrix4f getModelMatrix() const { if (m_dirty) { m_model_matrix = transformationMatrix(m_position, m_rotation, m_scale); m_dirty = false; @@ -56,7 +56,7 @@ struct TransformComponent : public Component { private: Eigen::Vector3f m_position, m_rotation, m_scale; - Eigen::Matrix4f m_model_matrix; - bool m_dirty = true; + mutable Eigen::Matrix4f m_model_matrix; + mutable bool m_dirty = true; }; } // namespace ICE diff --git a/ICE/Core/include/ICEEngine.h b/ICE/Core/include/ICEEngine.h index ad37c1c5..a2f71f54 100644 --- a/ICE/Core/include/ICEEngine.h +++ b/ICE/Core/include/ICEEngine.h @@ -1,66 +1,68 @@ -// -// Created by Thomas Ibanez on 25.11.20. -// - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace ICE { -class ICEEngine { - public: - ICEEngine(); - - void initialize(const std::shared_ptr& graphics_factor, const std::shared_ptr& window); - - void step(); - - void setupScene(const std::shared_ptr& camera_); - - std::shared_ptr getCamera(); - - std::shared_ptr getAssetBank(); - - Entity getSelected() const; - - std::shared_ptr getApi() const; - - std::shared_ptr getProject() const; - - void setProject(const std::shared_ptr& project); - - void setSelected(Entity selected); - - EngineConfig& getConfig(); - - std::shared_ptr getGraphicsFactory() const; - - std::shared_ptr getContext() const; - - std::shared_ptr getInternalFramebuffer() const; - void setRenderFramebufferInternal(bool use_internal); - - private: - std::shared_ptr m_graphics_factory; - std::shared_ptr ctx; - std::shared_ptr api; - std::shared_ptr internalFB; - std::shared_ptr m_target_fb = nullptr; - std::shared_ptr m_window; - - std::shared_ptr camera; - std::shared_ptr project = nullptr; - - EngineConfig config; - Registry registry; -}; -} // namespace ICE +// +// Created by Thomas Ibanez on 25.11.20. +// + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace ICE { +class ICEEngine { + public: + ICEEngine(); + + void initialize(const std::shared_ptr& graphics_factor, const std::shared_ptr& window); + + void step(); + + void setupScene(const std::shared_ptr& camera_); + + std::shared_ptr getCamera(); + + std::shared_ptr getAssetBank(); + + Entity getSelected() const; + + std::shared_ptr getApi() const; + + std::shared_ptr getProject() const; + + void setProject(const std::shared_ptr& project); + + void setSelected(Entity selected); + + EngineConfig& getConfig(); + + std::shared_ptr getGraphicsFactory() const; + + std::shared_ptr getContext() const; + + std::shared_ptr getInternalFramebuffer() const; + void setRenderFramebufferInternal(bool use_internal); + + private: + std::shared_ptr m_graphics_factory; + std::shared_ptr ctx; + std::shared_ptr api; + std::shared_ptr internalFB; + std::shared_ptr m_target_fb = nullptr; + std::shared_ptr m_window; + + std::shared_ptr camera; + std::shared_ptr project = nullptr; + + std::chrono::steady_clock::time_point lastFrameTime; + + EngineConfig config; + Registry registry; +}; +} // namespace ICE diff --git a/ICE/Core/src/ICEEngine.cpp b/ICE/Core/src/ICEEngine.cpp index 2d901755..9b226ed2 100644 --- a/ICE/Core/src/ICEEngine.cpp +++ b/ICE/Core/src/ICEEngine.cpp @@ -1,98 +1,101 @@ -#define STB_IMAGE_IMPLEMENTATION - -#include "ICEEngine.h" - -#include -#include -#include -#include -#include -#include -#include - -namespace ICE { -ICEEngine::ICEEngine() : camera(std::make_shared(60, 16.f / 9.f, 0.1f, 100000)), config(EngineConfig::LoadFromFile()) { -} - -void ICEEngine::initialize(const std::shared_ptr &graphics_factory, const std::shared_ptr &window) { - Logger::Log(Logger::INFO, "Core", "Engine starting up..."); - m_graphics_factory = graphics_factory; - m_window = window; - m_window->setSwapInterval(1); - m_window->setResizeCallback([this](int w, int h) { - if (project) { - project->getCurrentScene()->getRegistry()->getSystem()->setViewport(0, 0, w, h); - project->getCurrentScene()->getRegistry()->getSystem()->getCamera()->resize(w, h); - } - }); - ctx = graphics_factory->createContext(m_window); - ctx->initialize(); - api = graphics_factory->createRendererAPI(); - api->initialize(); - internalFB = graphics_factory->createFramebuffer({720, 720, 1}); -} - -void ICEEngine::step() { - auto render_system = project->getCurrentScene()->getRegistry()->getSystem(); - render_system->setTarget(m_target_fb); - project->getCurrentScene()->getRegistry()->updateSystems(0.0); -} - -void ICEEngine::setupScene(const std::shared_ptr &camera_) { - auto renderer = std::make_shared(api, m_graphics_factory, project->getCurrentScene()->getRegistry(), project->getAssetBank()); - auto rs = std::make_shared(); - rs->setCamera(camera_); - rs->setRenderer(renderer); - project->getCurrentScene()->getRegistry()->addSystem(rs); - - auto [w, h] = m_window->getSize(); - renderer->resize(w, h); -} - -std::shared_ptr ICEEngine::getCamera() { - return camera; -} - -std::shared_ptr ICEEngine::getAssetBank() { - return project->getAssetBank(); -} - -std::shared_ptr ICEEngine::getApi() const { - return api; -} - -std::shared_ptr ICEEngine::getProject() const { - return project; -} - -std::shared_ptr ICEEngine::getInternalFramebuffer() const { - return internalFB; -} - -void ICEEngine::setRenderFramebufferInternal(bool use_internal) { - if (use_internal) { - m_target_fb = internalFB; - } else { - m_target_fb = nullptr; - } -} - -void ICEEngine::setProject(const std::shared_ptr &project) { - this->project = project; - this->camera->getPosition() = project->getCameraPosition(); - this->camera->getRotation() = project->getCameraRotation(); - setupScene(camera); -} - -EngineConfig &ICEEngine::getConfig() { - return config; -} - -std::shared_ptr ICEEngine::getGraphicsFactory() const { - return m_graphics_factory; -} - -std::shared_ptr ICEEngine::getContext() const { - return ctx; -} -} // namespace ICE +#define STB_IMAGE_IMPLEMENTATION + +#include "ICEEngine.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace ICE { +ICEEngine::ICEEngine() : camera(std::make_shared(60, 16.f / 9.f, 0.1f, 100000)), config(EngineConfig::LoadFromFile()) { +} + +void ICEEngine::initialize(const std::shared_ptr &graphics_factory, const std::shared_ptr &window) { + Logger::Log(Logger::INFO, "Core", "Engine starting up..."); + m_graphics_factory = graphics_factory; + m_window = window; + m_window->setSwapInterval(1); + m_window->setResizeCallback([this](int w, int h) { + if (project) { + project->getCurrentScene()->getRegistry()->getSystem()->setViewport(0, 0, w, h); + project->getCurrentScene()->getRegistry()->getSystem()->getCamera()->resize(w, h); + } + }); + ctx = graphics_factory->createContext(m_window); + ctx->initialize(); + api = graphics_factory->createRendererAPI(); + api->initialize(); + internalFB = graphics_factory->createFramebuffer({720, 720, 1}); +} + +void ICEEngine::step() { + auto now = std::chrono::steady_clock::now(); + auto dt = std::chrono::duration_cast(now - lastFrameTime).count(); + lastFrameTime = now; + auto render_system = project->getCurrentScene()->getRegistry()->getSystem(); + render_system->setTarget(m_target_fb); + project->getCurrentScene()->getRegistry()->updateSystems(dt); +} + +void ICEEngine::setupScene(const std::shared_ptr &camera_) { + auto renderer = std::make_shared(api, m_graphics_factory, project->getCurrentScene()->getRegistry(), project->getAssetBank()); + auto rs = std::make_shared(); + rs->setCamera(camera_); + rs->setRenderer(renderer); + project->getCurrentScene()->getRegistry()->addSystem(rs); + + auto [w, h] = m_window->getSize(); + renderer->resize(w, h); +} + +std::shared_ptr ICEEngine::getCamera() { + return camera; +} + +std::shared_ptr ICEEngine::getAssetBank() { + return project->getAssetBank(); +} + +std::shared_ptr ICEEngine::getApi() const { + return api; +} + +std::shared_ptr ICEEngine::getProject() const { + return project; +} + +std::shared_ptr ICEEngine::getInternalFramebuffer() const { + return internalFB; +} + +void ICEEngine::setRenderFramebufferInternal(bool use_internal) { + if (use_internal) { + m_target_fb = internalFB; + } else { + m_target_fb = nullptr; + } +} + +void ICEEngine::setProject(const std::shared_ptr &project) { + this->project = project; + this->camera->getPosition() = project->getCameraPosition(); + this->camera->getRotation() = project->getCameraRotation(); + setupScene(camera); +} + +EngineConfig &ICEEngine::getConfig() { + return config; +} + +std::shared_ptr ICEEngine::getGraphicsFactory() const { + return m_graphics_factory; +} + +std::shared_ptr ICEEngine::getContext() const { + return ctx; +} +} // namespace ICE diff --git a/ICE/Graphics/CMakeLists.txt b/ICE/Graphics/CMakeLists.txt index d1e42010..86100b0d 100644 --- a/ICE/Graphics/CMakeLists.txt +++ b/ICE/Graphics/CMakeLists.txt @@ -1,32 +1,32 @@ -cmake_minimum_required(VERSION 3.19) -project(graphics) - -message(STATUS "Building ${PROJECT_NAME} module") - -add_library(${PROJECT_NAME} STATIC) - -target_sources(${PROJECT_NAME} PRIVATE - src/PerspectiveCamera.cpp - src/OrthographicCamera.cpp - src/ForwardRenderer.cpp - src/Material.cpp - src/Mesh.cpp - src/Model.cpp - src/GeometryPass.cpp) - -target_link_libraries(${PROJECT_NAME} - PUBLIC - assets - math - entity - scene -) - -target_include_directories(${PROJECT_NAME} PUBLIC - $ - $ - PRIVATE - ${CMAKE_SOURCE_DIR}/src) - -enable_testing() -#add_subdirectory(test) +cmake_minimum_required(VERSION 3.19) +project(graphics) + +message(STATUS "Building ${PROJECT_NAME} module") + +add_library(${PROJECT_NAME} STATIC) + +target_sources(${PROJECT_NAME} PRIVATE + src/PerspectiveCamera.cpp + src/OrthographicCamera.cpp + src/ForwardRenderer.cpp + src/Material.cpp + src/Mesh.cpp + src/Model.cpp + src/GeometryPass.cpp) + +target_link_libraries(${PROJECT_NAME} + PUBLIC + assets + math + entity + scene +) + +target_include_directories(${PROJECT_NAME} PUBLIC + $ + $ + PRIVATE + ${CMAKE_SOURCE_DIR}/src) + +enable_testing() +#add_subdirectory(test) diff --git a/ICE/Graphics/include/Animation.h b/ICE/Graphics/include/Animation.h new file mode 100644 index 00000000..00044da4 --- /dev/null +++ b/ICE/Graphics/include/Animation.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include + +namespace ICE { +struct BoneAnimation { + struct PositionKey { + float timeStamp; + Eigen::Vector3f position; + }; + struct RotationKey { + float timeStamp; + Eigen::Quaternionf rotation; + }; + struct ScaleKey { + float timeStamp; + Eigen::Vector3f scale; + }; + + std::vector positions; + std::vector rotations; + std::vector scales; +}; + +struct Animation { + float duration; + float ticksPerSecond; + + std::unordered_map tracks; +}; +} \ No newline at end of file diff --git a/ICE/Graphics/include/Buffers.h b/ICE/Graphics/include/Buffers.h index afdfcdde..50d4baa0 100644 --- a/ICE/Graphics/include/Buffers.h +++ b/ICE/Graphics/include/Buffers.h @@ -8,20 +8,30 @@ #include namespace ICE { - class VertexBuffer { - public: - virtual void bind() const = 0; - virtual void unbind() const = 0; - virtual void putData(const void* data, uint32_t size) = 0; - virtual uint32_t getSize() const = 0; - }; +class VertexBuffer { + public: + virtual void bind() const = 0; + virtual void unbind() const = 0; + virtual void putData(const void* data, uint32_t size) = 0; + virtual uint32_t getSize() const = 0; +}; - class IndexBuffer { - public: - virtual void bind() const = 0; - virtual void unbind() const = 0; - virtual void putData(const void* data, uint32_t size) = 0; - virtual uint32_t getSize() const = 0; - }; -} -#endif //ICE_BUFFERS_H +class IndexBuffer { + public: + virtual void bind() const = 0; + virtual void unbind() const = 0; + virtual void putData(const void* data, uint32_t size) = 0; + virtual uint32_t getSize() const = 0; +}; + +class UniformBuffer { + public: + virtual void bind() const = 0; + virtual void unbind() const = 0; + virtual void putData(const void* data, uint32_t size, uint32_t offset = 0) = 0; + virtual uint32_t getSize() const = 0; + virtual ~UniformBuffer() = default; +}; + +} // namespace ICE +#endif //ICE_BUFFERS_H diff --git a/ICE/Graphics/include/ForwardRenderer.h b/ICE/Graphics/include/ForwardRenderer.h index 62d9a4be..28f604aa 100644 --- a/ICE/Graphics/include/ForwardRenderer.h +++ b/ICE/Graphics/include/ForwardRenderer.h @@ -19,6 +19,7 @@ #include "RendererConfig.h" namespace ICE { + class ForwardRenderer : public Renderer { public: ForwardRenderer(const std::shared_ptr& api, const std::shared_ptr& factory, @@ -41,6 +42,9 @@ class ForwardRenderer : public Renderer { void setViewport(int x, int y, int w, int h) override; private: + void submitModel(int node_idx, const std::vector& nodes, const std::vector>& meshes, + const std::vector& materials, const Eigen::Matrix4f& transform); + std::shared_ptr m_api; std::shared_ptr m_registry; std::shared_ptr m_asset_bank; @@ -55,6 +59,9 @@ class ForwardRenderer : public Renderer { std::shared_ptr m_quad_vao; + std::shared_ptr m_camera_ubo; + std::shared_ptr m_light_ubo; + RendererConfig config; }; } // namespace ICE \ No newline at end of file diff --git a/ICE/Graphics/include/GraphicsFactory.h b/ICE/Graphics/include/GraphicsFactory.h index 329684c9..dac8290b 100644 --- a/ICE/Graphics/include/GraphicsFactory.h +++ b/ICE/Graphics/include/GraphicsFactory.h @@ -27,6 +27,8 @@ class GraphicsFactory { virtual std::shared_ptr createIndexBuffer() const = 0; + virtual std::shared_ptr createUniformBuffer(size_t size, size_t binding) const = 0; + virtual std::shared_ptr createShader(const std::string& vertexFile, const std::string& fragmentFile) const = 0; virtual std::shared_ptr createShader(const std::string& vertexFile, const std::string& geometryFile, diff --git a/ICE/Graphics/include/Mesh.h b/ICE/Graphics/include/Mesh.h index b1881ca3..da0ae0de 100644 --- a/ICE/Graphics/include/Mesh.h +++ b/ICE/Graphics/include/Mesh.h @@ -1,46 +1,70 @@ -// -// Created by Thomas Ibanez on 16.11.20. -// - -#pragma once - -#include -#include - -#include -#include - -#include "VertexArray.h" - -namespace ICE { -class Mesh : public Asset { - public: - Mesh(const std::vector &vertices, const std::vector &normals, const std::vector &uvCoords, - const std::vector &indices); - Mesh(std::vector &&vertices, std::vector &&normals, std::vector &&uvCoords, - std::vector &&indices); - - const std::vector &getVertices() const; - - const std::vector &getNormals() const; - - const std::vector &getUVCoords() const; - - const std::vector &getIndices() const; - - const std::shared_ptr getVertexArray() const; - void setVertexArray(const std::shared_ptr &vao); - - const AABB &getBoundingBox() const; - - std::string getTypeName() const override; - AssetType getType() const override; - - private: - std::vector vertices, normals; - std::vector uvCoords; - std::vector indices; - std::shared_ptr vertexArray; - AABB boundingBox; -}; +// +// Created by Thomas Ibanez on 16.11.20. +// + +#pragma once + +#include +#include + +#include +#include + +#include "VertexArray.h" + +namespace ICE { + +constexpr int MAX_BONES_PER_VERTEX = 4; +constexpr int MAX_BONES = 100; +constexpr int INVALID_BONE_ID = -1; + +struct MeshData { + std::vector vertices; + std::vector normals; + std::vector uvCoords; + std::vector tangents; + std::vector bitangents; + std::vector boneIDs; + std::vector boneWeights; + std::vector indices; +}; + +struct SkinningData { + std::unordered_map boneOffsetMatrices; +}; + +class Mesh : public Asset { + public: + Mesh(const MeshData &data); + Mesh(MeshData &&data); + + const std::vector &getVertices() const; + + const std::vector &getNormals() const; + + const std::vector &getUVCoords() const; + + const std::vector &getIndices() const; + + const std::shared_ptr getVertexArray() const; + void setVertexArray(const std::shared_ptr &vao); + + const AABB &getBoundingBox() const; + + std::string getTypeName() const override; + AssetType getType() const override; + bool usesBones() const { return m_has_bones; } + void setSkinningData(const SkinningData &skinningData) { + m_skinningData = skinningData; + m_has_bones = true; + } + + SkinningData getSkinningData() const { return m_skinningData; } + private: + MeshData m_data; + SkinningData m_skinningData; + bool m_has_bones = false; + std::shared_ptr vertexArray; + AABB boundingBox; +}; } // namespace ICE \ No newline at end of file diff --git a/ICE/Graphics/include/Model.h b/ICE/Graphics/include/Model.h index 653c7bfe..28558c4a 100644 --- a/ICE/Graphics/include/Model.h +++ b/ICE/Graphics/include/Model.h @@ -1,23 +1,51 @@ #pragma once +#include "Animation.h" #include "Asset.h" #include "Mesh.h" namespace ICE { class Model : public Asset { public: - Model(const std::vector> &meshes, const std::vector &materials); + struct Node { + std::string name; + Eigen::Matrix4f localTransform; // default transform + Eigen::Matrix4f animatedTransform; // For mesh-only animation (no bones) + std::vector meshIndices; // Meshes used by this node + std::vector children; // Node indices + }; + struct BoneInfo { + Eigen::Matrix4f finalTransformation; + }; + + struct Skeleton { + std::unordered_map boneMapping; + std::vector bones; + Eigen::Matrix4f globalInverseTransform; + }; + + Model(const std::vector &nodes, const std::vector> &meshes, const std::vector &materials); + + std::vector getNodes() const { return m_nodes; } + std::vector &getNodes() { return m_nodes; } std::vector> getMeshes() const { return m_meshes; } std::vector getMaterialsIDs() const { return m_materials; } AABB getBoundingBox() const { return m_boundingbox; } + std::unordered_map getAnimations() const { return m_animations; } + Skeleton &getSkeleton() { return m_skeleton; } + void setSkeleton(const Skeleton &skeleton) { m_skeleton = skeleton; } + void setAnimations(const std::unordered_map &animations) { m_animations = animations; } AssetType getType() const override { return AssetType::EModel; } std::string getTypeName() const override { return "Model"; } private: + std::vector m_nodes; std::vector> m_meshes; std::vector m_materials; + std::unordered_map m_animations; + Skeleton m_skeleton; AABB m_boundingbox{{0, 0, 0}, {0, 0, 0}}; }; } // namespace ICE \ No newline at end of file diff --git a/ICE/Graphics/include/Renderer.h b/ICE/Graphics/include/Renderer.h index 1022c4eb..48c00aa3 100644 --- a/ICE/Graphics/include/Renderer.h +++ b/ICE/Graphics/include/Renderer.h @@ -17,6 +17,31 @@ namespace ICE { class Scene; +constexpr int MAX_LIGHTS = 16; + +struct alignas(16) LightUBO { + Eigen::Vector3f position; + float __padding0; //align to vec4 + Eigen::Vector3f rotation; + float __padding1; //align to vec4 + Eigen::Vector3f color; + + float distance_dropoff; + int type; +}; + +struct alignas(16) SceneLightsUBO { + LightUBO lights[MAX_LIGHTS]; + Eigen::Vector4f ambient_light; + int light_count; + float __padding[3]; +}; + +struct alignas(16) CameraUBO { + Eigen::Matrix4f projection; + Eigen::Matrix4f view; +}; + class Renderer { public: virtual void submit(Entity e) = 0; diff --git a/ICE/Graphics/src/ForwardRenderer.cpp b/ICE/Graphics/src/ForwardRenderer.cpp index dda1cd23..da8fd7f3 100644 --- a/ICE/Graphics/src/ForwardRenderer.cpp +++ b/ICE/Graphics/src/ForwardRenderer.cpp @@ -35,6 +35,9 @@ ForwardRenderer::ForwardRenderer(const std::shared_ptr& api, const auto quad_ibo = factory->createIndexBuffer(); quad_ibo->putData(full_quad_idx.data(), full_quad_idx.size() * sizeof(int)); m_quad_vao->setIndexBuffer(quad_ibo); + + m_camera_ubo = factory->createUniformBuffer(sizeof(CameraUBO), 0); + m_light_ubo = factory->createUniformBuffer(sizeof(SceneLightsUBO), 1); } void ForwardRenderer::submit(Entity e) { @@ -89,9 +92,30 @@ void ForwardRenderer::prepareFrame(Camera& camera) { .depthTest = false}); } - std::unordered_set prepared_shaders; auto view_mat = camera.lookThrough(); - auto frustum = extractFrustumPlanes(camera.getProjection() * view_mat); + auto proj_mat = camera.getProjection(); + + CameraUBO camera_ubo_data{.projection = proj_mat, .view = view_mat}; + m_camera_ubo->putData(&camera_ubo_data, sizeof(CameraUBO)); + + SceneLightsUBO light_ubo_data; + light_ubo_data.light_count = m_lights.size(); + light_ubo_data.ambient_light = Eigen::Vector4f(0.1f, 0.1f, 0.1f, 1.0f); + for (int i = 0; i < m_lights.size(); i++) { + auto light = m_lights[i]; + auto lc = m_registry->getComponent(light); + auto tc = m_registry->getComponent(light); + if (i >= MAX_LIGHTS) + break; + light_ubo_data.lights[i].position = tc->getPosition(); + light_ubo_data.lights[i].rotation = tc->getRotation(); + light_ubo_data.lights[i].color = lc->color; + light_ubo_data.lights[i].distance_dropoff = lc->distance_dropoff; + light_ubo_data.lights[i].type = static_cast(lc->type); + } + m_light_ubo->putData(&light_ubo_data, sizeof(SceneLightsUBO)); + + auto frustum = extractFrustumPlanes(proj_mat * view_mat); for (const auto& e : m_render_queue) { auto rc = m_registry->getComponent(e); auto tc = m_registry->getComponent(e); @@ -106,64 +130,24 @@ void ForwardRenderer::prepareFrame(Camera& camera) { if (!isAABBInFrustum(frustum, aabb)) { continue; } + auto meshes = model->getMeshes(); + auto materials = model->getMaterialsIDs(); + auto nodes = model->getNodes(); - for (int i = 0; i < model->getMeshes().size(); i++) { - auto mtl_id = model->getMaterialsIDs().at(i); - auto mesh = model->getMeshes().at(i); - auto material = m_asset_bank->getAsset(mtl_id); - if (!material) { - continue; - } + for (const auto& mtl : materials) { + auto material = m_asset_bank->getAsset(mtl); auto shader = m_asset_bank->getAsset(material->getShader()); + if (!shader) { continue; } - - if (!prepared_shaders.contains(material->getShader())) { - shader->bind(); - - shader->loadMat4("projection", camera.getProjection()); - shader->loadMat4("view", view_mat); - - shader->loadFloat3("ambient_light", Eigen::Vector3f(0.1f, 0.1f, 0.1f)); - int i = 0; - for (const auto& e : m_lights) { - auto light = m_registry->getComponent(e); - auto transform = m_registry->getComponent(e); - std::string light_name = (std::string("lights[") + std::to_string(i) + std::string("].")); - shader->loadFloat3((light_name + std::string("position")).c_str(), transform->getPosition()); - shader->loadFloat3((light_name + std::string("rotation")).c_str(), transform->getRotation()); - shader->loadFloat3((light_name + std::string("color")).c_str(), light->color); - shader->loadFloat((light_name + std::string("distance_dropoff")).c_str(), light->distance_dropoff); - shader->loadInt((light_name + std::string("type")).c_str(), static_cast(light->type)); - i++; - } - shader->loadInt("light_count", i); - prepared_shaders.emplace(material->getShader()); - } - - if (!mesh) { - return; - } - - std::unordered_map> texs; - for (const auto& [name, value] : material->getAllUniforms()) { - if (std::holds_alternative(value)) { - auto v = std::get(value); - if (auto tex = m_asset_bank->getAsset(v); tex) { - texs.try_emplace(v, tex); - } - } + shader->bind(); + for (int i = 0; i < model->getSkeleton().bones.size(); i++) { + shader->loadMat4("bonesTransformMatrices[" + std::to_string(i) + "]", model->getSkeleton().bones[i].finalTransformation); } - - m_render_commands.push_back(RenderCommand{.mesh = mesh, - .material = material, - .shader = shader, - .textures = texs, - .model_matrix = tc->getModelMatrix(), - .faceCulling = true, - .depthTest = true}); } + + submitModel(0, nodes, meshes, materials, tc->getModelMatrix()); } std::sort(m_render_commands.begin(), m_render_commands.end(), [this](const RenderCommand& a, const RenderCommand& b) { @@ -179,6 +163,59 @@ void ForwardRenderer::prepareFrame(Camera& camera) { m_geometry_pass.submit(&m_render_commands); } +void ForwardRenderer::submitModel(int node_idx, const std::vector& nodes, const std::vector>& meshes, + const std::vector& materials, const Eigen::Matrix4f& transform) { + auto node = nodes.at(node_idx); + for (const auto& i : node.meshIndices) { + if (i >= meshes.size()) { + continue; + } + auto mtl_id = materials.at(i); + auto mesh = meshes.at(i); + auto material = m_asset_bank->getAsset(mtl_id); + if (!material) { + continue; + } + auto shader = m_asset_bank->getAsset(material->getShader()); + if (!shader) { + continue; + } + + if (!mesh) { + continue; + } + + Eigen::Matrix4f node_transform; + if (mesh->usesBones()) { + node_transform = transform; + } else { + node_transform = transform * node.animatedTransform; + } + + std::unordered_map> texs; + for (const auto& [name, value] : material->getAllUniforms()) { + if (std::holds_alternative(value)) { + auto v = std::get(value); + if (auto tex = m_asset_bank->getAsset(v); tex) { + texs.try_emplace(v, tex); + } + } + } + + m_render_commands.push_back(RenderCommand{.mesh = mesh, + .material = material, + .shader = shader, + .textures = texs, + .model_matrix = node_transform, + .faceCulling = true, + .depthTest = true}); + } + + for (const auto& child_idx : node.children) { + submitModel(child_idx, nodes, meshes, materials, transform); + } +} + void ForwardRenderer::render() { m_geometry_pass.execute(); auto result = m_geometry_pass.getResult(); @@ -202,9 +239,7 @@ void ForwardRenderer::render() { void ForwardRenderer::endFrame() { m_api->checkAndLogErrors(); - //TODO: Cleanup and restore state m_render_commands.clear(); - if (this->target != nullptr) this->target->unbind(); } diff --git a/ICE/Graphics/src/GeometryPass.cpp b/ICE/Graphics/src/GeometryPass.cpp index 36ad1f6e..ce00e7f2 100644 --- a/ICE/Graphics/src/GeometryPass.cpp +++ b/ICE/Graphics/src/GeometryPass.cpp @@ -26,6 +26,13 @@ void GeometryPass::execute() { shader->bind(); current_shader = shader; } + + if (mesh->usesBones()) { + for (const auto& [boneID, offsetMatrix] : mesh->getSkinningData().boneOffsetMatrices) { + current_shader->loadMat4("bonesOffsetMatrices[" + std::to_string(boneID) + "]", offsetMatrix); + } + } + if (material != current_material) { auto& textures = command.textures; current_material = material; diff --git a/ICE/Graphics/src/Mesh.cpp b/ICE/Graphics/src/Mesh.cpp index ae1b2265..44f689b2 100644 --- a/ICE/Graphics/src/Mesh.cpp +++ b/ICE/Graphics/src/Mesh.cpp @@ -10,36 +10,24 @@ #include namespace ICE { -Mesh::Mesh(const std::vector &vertices, const std::vector &normals, const std::vector &uvCoords, - const std::vector &indices) - : vertices(vertices), - normals(normals), - uvCoords(uvCoords), - indices(indices), - boundingBox(vertices) { -} -Mesh::Mesh(std::vector &&vertices, std::vector &&normals, std::vector &&uvCoords, - std::vector &&indices) - : vertices(std::move(vertices)), - normals(std::move(normals)), - uvCoords(std::move(uvCoords)), - indices(std::move(indices)), - boundingBox(this->vertices) { +Mesh::Mesh(const MeshData &data) : m_data(data), boundingBox(data.vertices) { +} +Mesh::Mesh(MeshData &&data) : m_data(std::move(data)), boundingBox(getVertices()) { } const std::vector &Mesh::getVertices() const { - return vertices; + return m_data.vertices; } const std::vector &Mesh::getNormals() const { - return normals; + return m_data.normals; } const std::vector &Mesh::getUVCoords() const { - return uvCoords; + return m_data.uvCoords; } const std::vector &Mesh::getIndices() const { - return indices; + return m_data.indices; } const std::shared_ptr Mesh::getVertexArray() const { diff --git a/ICE/Graphics/src/Model.cpp b/ICE/Graphics/src/Model.cpp index 0a9ad74f..2ecaa30f 100644 --- a/ICE/Graphics/src/Model.cpp +++ b/ICE/Graphics/src/Model.cpp @@ -1,8 +1,9 @@ #include "Model.h" namespace ICE { -Model::Model(const std::vector> &meshes, const std::vector &materials) - : m_meshes(meshes), +Model::Model(const std::vector &nodes, const std::vector> &meshes, const std::vector &materials) + : m_nodes(nodes), + m_meshes(meshes), m_materials(materials) { for (const auto &mesh : meshes) { m_boundingbox = m_boundingbox.unionWith(mesh->getBoundingBox()); diff --git a/ICE/GraphicsAPI/None/NoneGraphics.h b/ICE/GraphicsAPI/None/NoneGraphics.h index 685c2ec7..15b74f94 100644 --- a/ICE/GraphicsAPI/None/NoneGraphics.h +++ b/ICE/GraphicsAPI/None/NoneGraphics.h @@ -27,6 +27,14 @@ class NoneIndexBuffer : public IndexBuffer { void putData(const void *data, uint32_t size) override {} }; +class NoneUniformBuffer : public UniformBuffer { + public: + void bind() const override {} + void unbind() const override {} + uint32_t getSize() const override { return 0; } + void putData(const void *data, uint32_t size, uint32_t offset) override {} +}; + class NoneContext : public Context { public: void swapBuffers() override {} diff --git a/ICE/GraphicsAPI/None/NoneGraphicsFactory.h b/ICE/GraphicsAPI/None/NoneGraphicsFactory.h index 2baeac67..5dd4eb69 100644 --- a/ICE/GraphicsAPI/None/NoneGraphicsFactory.h +++ b/ICE/GraphicsAPI/None/NoneGraphicsFactory.h @@ -26,6 +26,8 @@ class NoneGraphicsFactory : public GraphicsFactory { std::shared_ptr createIndexBuffer() const override { return std::make_shared(); } + std::shared_ptr createUniformBuffer(size_t size, size_t binding) const override { return std::make_shared(); } + std::shared_ptr createShader(const std::string& vertexFile, const std::string& fragmentFile) const override { return createShader(vertexFile, "", fragmentFile); } diff --git a/ICE/GraphicsAPI/OpenGL/include/OpenGLBuffers.h b/ICE/GraphicsAPI/OpenGL/include/OpenGLBuffers.h index 9e8b5681..57de3812 100644 --- a/ICE/GraphicsAPI/OpenGL/include/OpenGLBuffers.h +++ b/ICE/GraphicsAPI/OpenGL/include/OpenGLBuffers.h @@ -5,47 +5,53 @@ #ifndef ICE_OPENGLBUFFERS_H #define ICE_OPENGLBUFFERS_H -#include #include +#include namespace ICE { - class OpenGLVertexBuffer : public VertexBuffer { - public: - void bind() const override; - - void unbind() const override; - - void putData(const void *data, uint32_t size) override; - - uint32_t getSize() const override; - - OpenGLVertexBuffer(): OpenGLVertexBuffer(0) {} - - OpenGLVertexBuffer(uint32_t size); - - private: - GLuint id; - uint32_t size; - }; - - class OpenGLIndexBuffer : public IndexBuffer { - public: - void bind() const override; - - void unbind() const override; - - uint32_t getSize() const override; - - void putData(const void *data, uint32_t size) override; - - OpenGLIndexBuffer(); - - private: - GLuint id; - uint32_t size; - }; -} - - -#endif //ICE_OPENGLBUFFERS_H +class OpenGLVertexBuffer : public VertexBuffer { + public: + void bind() const override; + void unbind() const override; + void putData(const void *data, uint32_t size) override; + uint32_t getSize() const override; + OpenGLVertexBuffer() : OpenGLVertexBuffer(0) {} + OpenGLVertexBuffer(uint32_t size); + + private: + GLuint id; + uint32_t size; +}; + +class OpenGLIndexBuffer : public IndexBuffer { + public: + void bind() const override; + void unbind() const override; + uint32_t getSize() const override; + void putData(const void *data, uint32_t size) override; + + OpenGLIndexBuffer(); + + private: + GLuint id; + uint32_t size; +}; + +class OpenGLUniformBuffer : public UniformBuffer { + public: + void bind() const override; + void unbind() const override; + uint32_t getSize() const override; + void putData(const void *data, uint32_t size, uint32_t offset = 0) override; + OpenGLUniformBuffer(uint32_t _size, uint32_t _binding); + ~OpenGLUniformBuffer() override; + + private: + GLuint id; + uint32_t size; + uint32_t binding; +}; +} // namespace ICE + +#endif //ICE_OPENGLBUFFERS_H diff --git a/ICE/GraphicsAPI/OpenGL/include/OpenGLContext.h b/ICE/GraphicsAPI/OpenGL/include/OpenGLContext.h index b6dfe7a3..59d7b35e 100644 --- a/ICE/GraphicsAPI/OpenGL/include/OpenGLContext.h +++ b/ICE/GraphicsAPI/OpenGL/include/OpenGLContext.h @@ -5,29 +5,29 @@ #ifndef ICE_OPENGLCONTEXT_H #define ICE_OPENGLCONTEXT_H +#include #include #include -#include #include + #include namespace ICE { - class OpenGLContext : public Context { - public: - void swapBuffers() override; - - void wireframeMode() override; +class OpenGLContext : public Context { + public: + void swapBuffers() override; - void fillMode() override; + void wireframeMode() override; - void initialize() override; + void fillMode() override; - OpenGLContext(const std::shared_ptr &window); + void initialize() override; - private: - std::shared_ptr m_window; - }; -} + OpenGLContext(const std::shared_ptr &window); + private: + std::shared_ptr m_window; +}; +} // namespace ICE -#endif //ICE_OPENGLCONTEXT_H +#endif //ICE_OPENGLCONTEXT_H diff --git a/ICE/GraphicsAPI/OpenGL/include/OpenGLFactory.h b/ICE/GraphicsAPI/OpenGL/include/OpenGLFactory.h index 89a7d543..a23d74f8 100644 --- a/ICE/GraphicsAPI/OpenGL/include/OpenGLFactory.h +++ b/ICE/GraphicsAPI/OpenGL/include/OpenGLFactory.h @@ -32,6 +32,10 @@ class OpenGLFactory : public GraphicsFactory { std::shared_ptr createVertexBuffer() const override { return std::make_shared(); } + std::shared_ptr createUniformBuffer(size_t size, size_t binding) const override { + return std::make_shared(size, binding); + } + std::shared_ptr createIndexBuffer() const override { return std::make_shared(); } std::shared_ptr createShader(const std::string& vertex_src, const std::string& fragment_src) const override { @@ -44,7 +48,9 @@ class OpenGLFactory : public GraphicsFactory { } std::shared_ptr createTexture2D(const std::string& file) const override { return std::make_shared(file); } - std::shared_ptr createTexture2D(const void* data, size_t w, size_t h, TextureFormat fmt) const override { return std::make_shared(data, w, h, fmt); } + std::shared_ptr createTexture2D(const void* data, size_t w, size_t h, TextureFormat fmt) const override { + return std::make_shared(data, w, h, fmt); + } std::shared_ptr createTextureCube(const std::string& file) const override { return std::make_shared(file); } }; diff --git a/ICE/GraphicsAPI/OpenGL/src/OpenGLBuffers.cpp b/ICE/GraphicsAPI/OpenGL/src/OpenGLBuffers.cpp index 510421c4..7759d889 100644 --- a/ICE/GraphicsAPI/OpenGL/src/OpenGLBuffers.cpp +++ b/ICE/GraphicsAPI/OpenGL/src/OpenGLBuffers.cpp @@ -3,50 +3,91 @@ // #include "OpenGLBuffers.h" + #include -ICE::OpenGLVertexBuffer::OpenGLVertexBuffer(uint32_t size) : size(size) { - glGenBuffers(1, &id); -} +namespace ICE { -void ICE::OpenGLIndexBuffer::bind() const { +/////////////////////////////////// INDEX BUFFER ////////////////////////////////// + +void OpenGLIndexBuffer::bind() const { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->id); } -void ICE::OpenGLIndexBuffer::unbind() const { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //not sure this makes sense +void OpenGLIndexBuffer::unbind() const { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //not sure this makes sense } -uint32_t ICE::OpenGLIndexBuffer::getSize() const { +uint32_t OpenGLIndexBuffer::getSize() const { return this->size; } -void ICE::OpenGLIndexBuffer::putData(const void *data, uint32_t size) { +void OpenGLIndexBuffer::putData(const void *data, uint32_t size) { this->bind(); glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); this->size = size; this->unbind(); } -ICE::OpenGLIndexBuffer::OpenGLIndexBuffer() { +OpenGLIndexBuffer::OpenGLIndexBuffer() { glGenBuffers(1, &id); } -void ICE::OpenGLVertexBuffer::bind() const { +/////////////////////////////////// VERTEX BUFFER ////////////////////////////////// + +OpenGLVertexBuffer::OpenGLVertexBuffer(uint32_t size) : size(size) { + glGenBuffers(1, &id); +} + +void OpenGLVertexBuffer::bind() const { glBindBuffer(GL_ARRAY_BUFFER, this->id); } -void ICE::OpenGLVertexBuffer::unbind() const { +void OpenGLVertexBuffer::unbind() const { glBindBuffer(GL_ARRAY_BUFFER, 0); } -void ICE::OpenGLVertexBuffer::putData(const void *data, uint32_t size) { +void OpenGLVertexBuffer::putData(const void *data, uint32_t size) { this->bind(); glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); this->size = size; this->unbind(); } -uint32_t ICE::OpenGLVertexBuffer::getSize() const { +uint32_t OpenGLVertexBuffer::getSize() const { return this->size; } + +////////////////////////////////// UNIFORM BUFFER ////////////////////////////////// + +OpenGLUniformBuffer::OpenGLUniformBuffer(uint32_t _size, uint32_t _binding) : size(_size), binding(_binding) { + glGenBuffers(1, &id); + glBindBuffer(GL_UNIFORM_BUFFER, id); + glBufferData(GL_UNIFORM_BUFFER, size, nullptr, GL_DYNAMIC_DRAW); + glBindBufferBase(GL_UNIFORM_BUFFER, binding, id); + glBindBuffer(GL_UNIFORM_BUFFER, 0); +} + +OpenGLUniformBuffer::~OpenGLUniformBuffer() { + glDeleteBuffers(1, &id); +} + +void OpenGLUniformBuffer::bind() const { + glBindBuffer(GL_UNIFORM_BUFFER, id); +} + +uint32_t OpenGLUniformBuffer::getSize() const { + return size; +} + +void OpenGLUniformBuffer::unbind() const { + glBindBuffer(GL_UNIFORM_BUFFER, 0); +} + +void OpenGLUniformBuffer::putData(const void *data, uint32_t _size, uint32_t offset) { + bind(); + glBufferSubData(GL_UNIFORM_BUFFER, offset, size, data); + unbind(); + size = _size; +} +} // namespace ICE diff --git a/ICE/IO/include/ModelLoader.h b/ICE/IO/include/ModelLoader.h index 5dfd1af9..453bdb77 100644 --- a/ICE/IO/include/ModelLoader.h +++ b/ICE/IO/include/ModelLoader.h @@ -1,35 +1,45 @@ -// -// Created by Thomas Ibanez on 31.07.21. -// - -#pragma once - -#include -#include - -#include - -#include "Asset.h" -#include "IAssetLoader.h" -#include "Model.h" - -namespace ICE { -class AssetBank; - -class ModelLoader : public IAssetLoader { - public: - ModelLoader(const std::shared_ptr &factory, AssetBank &bank) - : ref_bank(bank), - m_graphics_factory(factory), - IAssetLoader(factory) {} - std::shared_ptr load(const std::vector &file) override; - AssetUID extractMaterial(const aiMaterial *material, const std::string &model_name, const aiScene *scene); - AssetUID extractTexture(const aiMaterial *material, const std::string &tex_path, const aiScene *scene, aiTextureType type); - - private: - Eigen::Vector4f colorToVec(aiColor4D *color); - - AssetBank &ref_bank; - std::shared_ptr m_graphics_factory; -}; -} // namespace ICE +// +// Created by Thomas Ibanez on 31.07.21. +// + +#pragma once + +#include +#include + +#include + +#include "Asset.h" +#include "IAssetLoader.h" +#include "Model.h" + +namespace ICE { +class AssetBank; + +class ModelLoader : public IAssetLoader { + public: + ModelLoader(const std::shared_ptr &factory, AssetBank &bank) + : ref_bank(bank), + m_graphics_factory(factory), + IAssetLoader(factory) {} + + std::shared_ptr load(const std::vector &file) override; + + int processNode(const aiNode *node, std::vector &nodes, Model::Skeleton &skeleton, std::unordered_set &used_names, + const Eigen::Matrix4f &parent_transform); + std::shared_ptr extractMesh(const aiMesh *mesh, const std::string &model_name, const aiScene *scene, Model::Skeleton &skeleton); + AssetUID extractMaterial(const aiMaterial *material, const std::string &model_name, const aiScene *scene); + AssetUID extractTexture(const aiMaterial *material, const std::string &tex_path, const aiScene *scene, aiTextureType type); + void extractBoneData(const aiMesh *mesh, const aiScene *scene, MeshData &data, SkinningData &skinning_data, Model::Skeleton &skeleton); + std::unordered_map extractAnimations(const aiScene *scene, Model::Skeleton &skeleton); + + private: + Eigen::Vector4f colorToVec(aiColor4D *color); + Eigen::Matrix4f aiMat4ToEigen(const aiMatrix4x4 &mat); + Eigen::Vector3f aiVec3ToEigen(const aiVector3D &vec); + Eigen::Quaternionf aiQuatToEigen(const aiQuaternion &q); + + AssetBank &ref_bank; + std::shared_ptr m_graphics_factory; +}; +} // namespace ICE diff --git a/ICE/IO/include/ShaderLoader.h b/ICE/IO/include/ShaderLoader.h index 99415fb4..648f96e0 100644 --- a/ICE/IO/include/ShaderLoader.h +++ b/ICE/IO/include/ShaderLoader.h @@ -15,5 +15,6 @@ class ShaderLoader : public IAssetLoader { public: ShaderLoader(const std::shared_ptr &factory) : IAssetLoader(factory) {} std::shared_ptr load(const std::vector &file) override; + std::string readAndResolveIncludes(const std::filesystem::path &file); }; } // namespace ICE diff --git a/ICE/IO/src/ModelLoader.cpp b/ICE/IO/src/ModelLoader.cpp index b78dd350..6557ca80 100644 --- a/ICE/IO/src/ModelLoader.cpp +++ b/ICE/IO/src/ModelLoader.cpp @@ -1,177 +1,361 @@ -// -// Created by Thomas Ibanez on 31.07.21. -// - -#include "ModelLoader.h" - -#include -#include -#include -#include -#include - -#include -#include - -namespace ICE { -std::shared_ptr ModelLoader::load(const std::vector &file) { - Assimp::Importer importer; - - const aiScene *scene = importer.ReadFile(file[0].string(), - aiProcess_PreTransformVertices | aiProcess_FlipUVs | aiProcess_ValidateDataStructure | aiProcess_SortByPType | aiProcess_GenSmoothNormals - | aiProcess_CalcTangentSpace | aiProcess_Triangulate); - - std::vector> meshes; - std::vector materials; - - for (int m = 0; m < scene->mNumMeshes; m++) { - auto vertices = std::vector(); - auto normals = std::vector(); - auto uvs = std::vector(); - auto indices = std::vector(); - // Loop over faces(polygon) - auto mesh = scene->mMeshes[m]; - auto material = scene->mMaterials[mesh->mMaterialIndex]; - - materials.push_back(extractMaterial(material, file[0].filename().stem().string(), scene)); - - for (int i = 0; i < mesh->mNumVertices; i++) { - auto v = mesh->mVertices[i]; - auto n = mesh->mNormals ? mesh->mNormals[i] : aiVector3D{0, 0, 0}; - Eigen::Vector2f uv(0, 0); - if (mesh->mTextureCoords[0] != nullptr) { - auto uv_file = mesh->mTextureCoords[0][i]; - uv.x() = uv_file.x; - uv.y() = uv_file.y; - } - vertices.emplace_back(v.x, v.y, v.z); - normals.emplace_back(n.x, n.y, n.z); - uvs.push_back(uv); - } - for (int i = 0; i < mesh->mNumFaces; i++) { - auto f = mesh->mFaces[i]; - assert(f.mNumIndices == 3); - indices.emplace_back(f.mIndices[0], f.mIndices[1], f.mIndices[2]); - } - - meshes.push_back(std::make_shared(vertices, normals, uvs, indices)); - - meshes.back()->setSources(file); - - auto vertexArray = graphics_factory->createVertexArray(); - - auto vertexBuffer = graphics_factory->createVertexBuffer(); - auto normalsBuffer = graphics_factory->createVertexBuffer(); - auto uvBuffer = graphics_factory->createVertexBuffer(); - auto indexBuffer = graphics_factory->createIndexBuffer(); - - vertexBuffer->putData(BufferUtils::CreateFloatBuffer(meshes.back()->getVertices()), 3 * meshes.back()->getVertices().size() * sizeof(float)); - normalsBuffer->putData(BufferUtils::CreateFloatBuffer(meshes.back()->getNormals()), 3 * meshes.back()->getNormals().size() * sizeof(float)); - uvBuffer->putData(BufferUtils::CreateFloatBuffer(meshes.back()->getUVCoords()), 2 * meshes.back()->getUVCoords().size() * sizeof(float)); - indexBuffer->putData(BufferUtils::CreateIntBuffer(meshes.back()->getIndices()), 3 * meshes.back()->getIndices().size() * sizeof(int)); - - vertexArray->pushVertexBuffer(vertexBuffer, 3); - vertexArray->pushVertexBuffer(normalsBuffer, 3); - vertexArray->pushVertexBuffer(uvBuffer, 2); - vertexArray->setIndexBuffer(indexBuffer); - - meshes.back()->setVertexArray(vertexArray); - } - auto model = std::make_shared(meshes, materials); - model->setSources(file); - return model; -} - -AssetUID ModelLoader::extractMaterial(const aiMaterial *material, const std::string &model_name, const aiScene *scene) { - auto mtl_name = material->GetName(); - if (mtl_name.length == 0) { - mtl_name = "DefaultMat"; - } - auto bank_name = model_name + "/" + mtl_name.C_Str(); - auto mtl = std::make_shared(); - mtl->setUniform("material.use_diffuse_map", false); - mtl->setUniform("material.use_ambient_map", false); - mtl->setUniform("material.use_specular_map", false); - mtl->setUniform("material.use_normal_map", false); - if (auto ambient_map = extractTexture(material, bank_name + "/ambient_map", scene, aiTextureType_AMBIENT); ambient_map != 0) { - mtl->setUniform("material.ambient_map", ambient_map); - mtl->setUniform("material.use_ambient_map", true); - } - if (auto diffuse_tex = extractTexture(material, bank_name + "/diffuse_map", scene, aiTextureType_DIFFUSE); diffuse_tex != 0) { - mtl->setUniform("material.diffuse_map", diffuse_tex); - mtl->setUniform("material.use_diffuse_map", true); - } - if (auto specular_tex = extractTexture(material, bank_name + "/specular_map", scene, aiTextureType_SPECULAR); specular_tex != 0) { - mtl->setUniform("material.specular_map", specular_tex); - mtl->setUniform("material.use_specular_map", true); - } - if (auto normal_tex = extractTexture(material, bank_name + "/normal_map", scene, aiTextureType_NORMALS); normal_tex != 0) { - mtl->setUniform("material.normal_map", normal_tex); - mtl->setUniform("material.use_normal_map", true); - } - - if (ref_bank.getUID(AssetPath::WithTypePrefix(bank_name)) != 0) { - return ref_bank.getUID(AssetPath::WithTypePrefix(bank_name)); - } - mtl->setShader(ref_bank.getUID(AssetPath::WithTypePrefix("phong"))); - - aiColor4D diffuse; - aiColor4D specular; - aiColor4D ambient; - ai_real alpha = 1.0; - - if (aiGetMaterialColor(material, AI_MATKEY_COLOR_DIFFUSE, &diffuse) == aiReturn_SUCCESS) - mtl->setUniform("material.albedo", colorToVec(&diffuse)); - if (aiGetMaterialColor(material, AI_MATKEY_COLOR_SPECULAR, &specular) == aiReturn_SUCCESS) - mtl->setUniform("material.specular", colorToVec(&specular)); - if (aiGetMaterialColor(material, AI_MATKEY_COLOR_AMBIENT, &ambient) == aiReturn_SUCCESS) - mtl->setUniform("material.ambient", colorToVec(&ambient)); - if (aiGetMaterialFloat(material, AI_MATKEY_SHININESS, &alpha) == aiReturn_SUCCESS) - mtl->setUniform("material.alpha", std::max(alpha, 1.0f)); - - ref_bank.addAsset(bank_name, mtl); - return ref_bank.getUID(AssetPath::WithTypePrefix(bank_name)); -} - -AssetUID ModelLoader::extractTexture(const aiMaterial *material, const std::string &tex_path, const aiScene *scene, aiTextureType type) { - AssetUID tex_id = 0; - aiString texture_file; - if (material->Get(AI_MATKEY_TEXTURE(type, 0), texture_file) == aiReturn_SUCCESS) { - if (auto texture = scene->GetEmbeddedTexture(texture_file.C_Str())) { - unsigned char *data = reinterpret_cast(texture->pcData); - void *data2 = nullptr; - int width = texture->mWidth; - int height = texture->mHeight; - int channels = 0; - if (height == 0) { - //Compressed memory, use stbi to load - data2 = stbi_load_from_memory(data, texture->mWidth, &width, &height, &channels, 4); - } else { - data2 = data; - } - auto texture_ice = m_graphics_factory->createTexture2D(data2, width, height, TextureFormat::RGBA); - if (tex_id = ref_bank.getUID(AssetPath::WithTypePrefix(tex_path)); tex_id != 0) { - ref_bank.removeAsset(AssetPath::WithTypePrefix(tex_path)); - ref_bank.addAssetWithSpecificUID(AssetPath::WithTypePrefix(tex_path), texture_ice, tex_id); - } else { - ref_bank.addAsset(tex_path, texture_ice); - tex_id = ref_bank.getUID(AssetPath::WithTypePrefix(tex_path)); - } - } else { - //regular file, check if it exists and read it - //TODO :) - } - } - return tex_id; -} - -Eigen::Vector4f ModelLoader::colorToVec(aiColor4D *color) { - Eigen::Vector4f v; - v.x() = color->r; - v.y() = color->g; - v.z() = color->b; - v.w() = color->a; - return v; -} - -} // namespace ICE +// +// Created by Thomas Ibanez on 31.07.21. +// + +#include "ModelLoader.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace ICE { +std::shared_ptr ModelLoader::load(const std::vector &file) { + Assimp::Importer importer; + + const aiScene *scene = + importer.ReadFile(file[0].string(), + aiProcess_OptimizeGraph | aiProcess_FlipUVs | aiProcess_ValidateDataStructure | aiProcess_SortByPType + | aiProcess_GenSmoothNormals | aiProcess_CalcTangentSpace | aiProcess_Triangulate | aiProcess_LimitBoneWeights); + + std::vector> meshes; + std::vector materials; + std::vector nodes; + Model::Skeleton skeleton; + skeleton.globalInverseTransform = aiMat4ToEigen(scene->mRootNode->mTransformation).inverse(); + for (int m = 0; m < scene->mNumMeshes; m++) { + auto mesh = scene->mMeshes[m]; + auto material = scene->mMaterials[mesh->mMaterialIndex]; + auto model_name = file[0].filename().stem().string(); + meshes.push_back(extractMesh(mesh, model_name, scene, skeleton)); + materials.push_back(extractMaterial(material, model_name, scene)); + meshes.back()->setSources(file); + } + std::unordered_set used_node_names; + processNode(scene->mRootNode, nodes, skeleton, used_node_names, Eigen::Matrix4f::Identity()); + auto model = std::make_shared(nodes, meshes, materials); + + if (scene->HasAnimations()) { + auto animations = extractAnimations(scene, skeleton); + model->setAnimations(animations); + model->setSkeleton(skeleton); + } + model->setSources(file); + return model; +} + +int ModelLoader::processNode(const aiNode *ainode, std::vector &nodes, Model::Skeleton &skeleton, + std::unordered_set &used_names, const Eigen::Matrix4f &parent_transform) { + std::string name = ainode->mName.C_Str(); + if (used_names.contains(name)) { + name = name + "_" + std::to_string(used_names.size()); + } + used_names.insert(name); + + Model::Node node; + node.name = name; + + aiMatrix4x4 local = ainode->mTransformation; + node.localTransform = aiMat4ToEigen(local); + node.animatedTransform = parent_transform * node.localTransform; + + for (unsigned int i = 0; i < ainode->mNumMeshes; ++i) { + unsigned int mesh_idx = ainode->mMeshes[i]; + node.meshIndices.push_back(mesh_idx); + } + auto insert_pos = nodes.size(); + + if (skeleton.boneMapping.contains(name)) { + int boneID = skeleton.boneMapping.at(name); + skeleton.bones[boneID].finalTransformation = skeleton.globalInverseTransform * node.animatedTransform; + } + + nodes.push_back(node); + + for (unsigned int c = 0; c < ainode->mNumChildren; ++c) { + const aiNode *child = ainode->mChildren[c]; + int child_pos = processNode(child, nodes, skeleton, used_names, node.animatedTransform); + nodes.at(insert_pos).children.push_back(child_pos); + } + return insert_pos; +} + +std::shared_ptr ModelLoader::extractMesh(const aiMesh *mesh, const std::string &model_name, const aiScene *scene, Model::Skeleton &skeleton) { + MeshData data; + + for (int i = 0; i < mesh->mNumVertices; i++) { + auto v = mesh->mVertices[i]; + auto n = mesh->HasNormals() ? mesh->mNormals[i] : aiVector3D{0, 0, 0}; + auto t = mesh->HasTangentsAndBitangents() ? mesh->mTangents[i] : aiVector3D{0, 0, 0}; + auto b = mesh->HasTangentsAndBitangents() ? mesh->mBitangents[i] : aiVector3D{0, 0, 0}; + Eigen::Vector2f uv(0, 0); + if (mesh->mTextureCoords[0] != nullptr) { + auto uv_file = mesh->mTextureCoords[0][i]; + uv.x() = uv_file.x; + uv.y() = uv_file.y; + } + data.vertices.emplace_back(v.x, v.y, v.z); + data.normals.emplace_back(n.x, n.y, n.z); + data.uvCoords.push_back(uv); + data.tangents.emplace_back(t.x, t.y, t.z); + data.bitangents.emplace_back(b.x, b.y, b.z); + data.boneIDs.emplace_back(Eigen::Vector4i::Constant(-1)); + data.boneWeights.emplace_back(Eigen::Vector4f::Zero()); + } + for (int i = 0; i < mesh->mNumFaces; i++) { + auto f = mesh->mFaces[i]; + assert(f.mNumIndices == 3); + data.indices.emplace_back(f.mIndices[0], f.mIndices[1], f.mIndices[2]); + } + + SkinningData skinning_data; + if (mesh->HasBones()) { + extractBoneData(mesh, scene, data, skinning_data, skeleton); + } + + auto mesh_ = std::make_shared(data); + if (skinning_data.boneOffsetMatrices.size() > 0) { + mesh_->setSkinningData(skinning_data); + } + + auto vertexArray = graphics_factory->createVertexArray(); + + auto vertexBuffer = graphics_factory->createVertexBuffer(); + auto normalsBuffer = graphics_factory->createVertexBuffer(); + auto uvBuffer = graphics_factory->createVertexBuffer(); + auto tangentBuffer = graphics_factory->createVertexBuffer(); + auto biTangentBuffer = graphics_factory->createVertexBuffer(); + auto boneIDBuffer = graphics_factory->createVertexBuffer(); + auto boneWeightBuffer = graphics_factory->createVertexBuffer(); + auto indexBuffer = graphics_factory->createIndexBuffer(); + + vertexBuffer->putData(BufferUtils::CreateFloatBuffer(data.vertices), 3 * data.vertices.size() * sizeof(float)); + normalsBuffer->putData(BufferUtils::CreateFloatBuffer(data.normals), 3 * data.normals.size() * sizeof(float)); + tangentBuffer->putData(BufferUtils::CreateFloatBuffer(data.tangents), 3 * data.tangents.size() * sizeof(float)); + biTangentBuffer->putData(BufferUtils::CreateFloatBuffer(data.bitangents), 3 * data.bitangents.size() * sizeof(float)); + boneIDBuffer->putData(BufferUtils::CreateIntBuffer(data.boneIDs), 4 * data.boneIDs.size() * sizeof(int)); + boneWeightBuffer->putData(BufferUtils::CreateFloatBuffer(data.boneWeights), 4 * data.boneWeights.size() * sizeof(float)); + uvBuffer->putData(BufferUtils::CreateFloatBuffer(data.uvCoords), 2 * data.uvCoords.size() * sizeof(float)); + indexBuffer->putData(BufferUtils::CreateIntBuffer(data.indices), 3 * data.indices.size() * sizeof(int)); + + vertexArray->pushVertexBuffer(vertexBuffer, 0, 3); + vertexArray->pushVertexBuffer(normalsBuffer, 1, 3); + vertexArray->pushVertexBuffer(uvBuffer, 2, 2); + vertexArray->pushVertexBuffer(tangentBuffer, 3, 3); + vertexArray->pushVertexBuffer(biTangentBuffer, 4, 3); + vertexArray->pushVertexBuffer(boneIDBuffer, 5, 4); + vertexArray->pushVertexBuffer(boneWeightBuffer, 6, 4); + vertexArray->setIndexBuffer(indexBuffer); + + mesh_->setVertexArray(vertexArray); + return mesh_; +} + +AssetUID ModelLoader::extractMaterial(const aiMaterial *material, const std::string &model_name, const aiScene *scene) { + auto mtl_name = material->GetName(); + if (mtl_name.length == 0) { + mtl_name = "DefaultMat"; + } + auto bank_name = model_name + "/" + mtl_name.C_Str(); + auto mtl = std::make_shared(); + mtl->setUniform("material.use_diffuse_map", false); + mtl->setUniform("material.use_ambient_map", false); + mtl->setUniform("material.use_specular_map", false); + mtl->setUniform("material.use_normal_map", false); + if (auto ambient_map = extractTexture(material, bank_name + "/ambient_map", scene, aiTextureType_AMBIENT); ambient_map != 0) { + mtl->setUniform("material.ambient_map", ambient_map); + mtl->setUniform("material.use_ambient_map", true); + } + if (auto diffuse_tex = extractTexture(material, bank_name + "/diffuse_map", scene, aiTextureType_DIFFUSE); diffuse_tex != 0) { + mtl->setUniform("material.diffuse_map", diffuse_tex); + mtl->setUniform("material.use_diffuse_map", true); + } + if (auto specular_tex = extractTexture(material, bank_name + "/specular_map", scene, aiTextureType_SPECULAR); specular_tex != 0) { + mtl->setUniform("material.specular_map", specular_tex); + mtl->setUniform("material.use_specular_map", true); + } + if (auto normal_tex = extractTexture(material, bank_name + "/normal_map", scene, aiTextureType_NORMALS); normal_tex != 0) { + mtl->setUniform("material.normal_map", normal_tex); + mtl->setUniform("material.use_normal_map", true); + } + + if (ref_bank.getUID(AssetPath::WithTypePrefix(bank_name)) != 0) { + return ref_bank.getUID(AssetPath::WithTypePrefix(bank_name)); + } + mtl->setShader(ref_bank.getUID(AssetPath::WithTypePrefix("phong"))); + + aiColor4D diffuse; + aiColor4D specular; + aiColor4D ambient; + ai_real alpha = 1.0; + + if (aiGetMaterialColor(material, AI_MATKEY_COLOR_DIFFUSE, &diffuse) == aiReturn_SUCCESS) + mtl->setUniform("material.albedo", colorToVec(&diffuse)); + if (aiGetMaterialColor(material, AI_MATKEY_COLOR_SPECULAR, &specular) == aiReturn_SUCCESS) + mtl->setUniform("material.specular", colorToVec(&specular)); + if (aiGetMaterialColor(material, AI_MATKEY_COLOR_AMBIENT, &ambient) == aiReturn_SUCCESS) + mtl->setUniform("material.ambient", colorToVec(&ambient)); + if (aiGetMaterialFloat(material, AI_MATKEY_SHININESS, &alpha) == aiReturn_SUCCESS) + mtl->setUniform("material.alpha", std::max(alpha, 1.0f)); + + ref_bank.addAsset(bank_name, mtl); + return ref_bank.getUID(AssetPath::WithTypePrefix(bank_name)); +} + +AssetUID ModelLoader::extractTexture(const aiMaterial *material, const std::string &tex_path, const aiScene *scene, aiTextureType type) { + AssetUID tex_id = 0; + aiString texture_file; + if (material->Get(AI_MATKEY_TEXTURE(type, 0), texture_file) == aiReturn_SUCCESS) { + if (auto texture = scene->GetEmbeddedTexture(texture_file.C_Str())) { + unsigned char *data = reinterpret_cast(texture->pcData); + void *data2 = nullptr; + int width = texture->mWidth; + int height = texture->mHeight; + int channels = 0; + if (height == 0) { + //Compressed memory, use stbi to load + data2 = stbi_load_from_memory(data, texture->mWidth, &width, &height, &channels, 4); + } else { + data2 = data; + } + auto texture_ice = m_graphics_factory->createTexture2D(data2, width, height, TextureFormat::RGBA); + if (tex_id = ref_bank.getUID(AssetPath::WithTypePrefix(tex_path)); tex_id != 0) { + ref_bank.removeAsset(AssetPath::WithTypePrefix(tex_path)); + ref_bank.addAssetWithSpecificUID(AssetPath::WithTypePrefix(tex_path), texture_ice, tex_id); + } else { + ref_bank.addAsset(tex_path, texture_ice); + tex_id = ref_bank.getUID(AssetPath::WithTypePrefix(tex_path)); + } + } else { + //regular file, check if it exists and read it + //TODO :) + } + } + return tex_id; +} + +void ModelLoader::extractBoneData(const aiMesh *mesh, const aiScene *scene, MeshData &data, SkinningData &skinning_data, Model::Skeleton &skeleton) { + for (unsigned int boneIndex = 0; boneIndex < mesh->mNumBones; ++boneIndex) { + std::string boneName = mesh->mBones[boneIndex]->mName.C_Str(); + int boneID = -1; + // If the bone is new (hasn't been added by a previous mesh) + if (!skeleton.boneMapping.contains(boneName)) { + boneID = skeleton.boneMapping.size(); + skeleton.boneMapping[boneName] = boneID; + Model::BoneInfo newBoneInfo = {.finalTransformation = Eigen::Matrix4f::Identity()}; + skeleton.bones.push_back(newBoneInfo); + } else { + //Bone Already Exists + boneID = skeleton.boneMapping.at(boneName); + } + + skinning_data.boneOffsetMatrices.try_emplace(boneID, aiMat4ToEigen(mesh->mBones[boneIndex]->mOffsetMatrix)); + + aiVertexWeight *weights = mesh->mBones[boneIndex]->mWeights; + unsigned int numWeights = mesh->mBones[boneIndex]->mNumWeights; + + for (int weightIndex = 0; weightIndex < numWeights; ++weightIndex) { + unsigned int vertexId = weights[weightIndex].mVertexId; + float weight = weights[weightIndex].mWeight; + + for (int i = 0; i < 4; ++i) { + if (data.boneIDs[vertexId][i] < 0) { + data.boneWeights[vertexId][i] = weight; + data.boneIDs[vertexId][i] = boneID; + break; + } + } + } + } +} + +std::unordered_map ModelLoader::extractAnimations(const aiScene *scene, Model::Skeleton &skeleton) { + std::unordered_map out; + for (unsigned int i = 0; i < scene->mNumAnimations; i++) { + aiAnimation *anim = scene->mAnimations[i]; + + Animation a; + a.duration = anim->mDuration; + a.ticksPerSecond = anim->mTicksPerSecond != 0 ? anim->mTicksPerSecond : 25.0f; + + for (unsigned int c = 0; c < anim->mNumChannels; c++) { + aiNodeAnim *channel = anim->mChannels[c]; + std::string boneName = channel->mNodeName.C_Str(); + + BoneAnimation track; + + for (int k = 0; k < channel->mNumPositionKeys; k++) { + track.positions.push_back({(float) channel->mPositionKeys[k].mTime, aiVec3ToEigen(channel->mPositionKeys[k].mValue)}); + } + + for (int k = 0; k < channel->mNumRotationKeys; k++) { + track.rotations.push_back({(float) channel->mRotationKeys[k].mTime, aiQuatToEigen(channel->mRotationKeys[k].mValue)}); + } + + for (int k = 0; k < channel->mNumScalingKeys; k++) { + track.scales.push_back({(float) channel->mScalingKeys[k].mTime, aiVec3ToEigen(channel->mScalingKeys[k].mValue)}); + } + + a.tracks[boneName] = std::move(track); + } + + out.try_emplace(anim->mName.C_Str(), std::move(a)); + } + return out; +} + +Eigen::Vector4f ModelLoader::colorToVec(aiColor4D *color) { + Eigen::Vector4f v; + v.x() = color->r; + v.y() = color->g; + v.z() = color->b; + v.w() = color->a; + return v; +} + +Eigen::Matrix4f ModelLoader::aiMat4ToEigen(const aiMatrix4x4 &m) { + Eigen::Matrix4f out; + + out(0, 0) = m.a1; + out(0, 1) = m.a2; + out(0, 2) = m.a3; + out(0, 3) = m.a4; + out(1, 0) = m.b1; + out(1, 1) = m.b2; + out(1, 2) = m.b3; + out(1, 3) = m.b4; + out(2, 0) = m.c1; + out(2, 1) = m.c2; + out(2, 2) = m.c3; + out(2, 3) = m.c4; + out(3, 0) = m.d1; + out(3, 1) = m.d2; + out(3, 2) = m.d3; + out(3, 3) = m.d4; + + return out; +} + +Eigen::Vector3f ModelLoader::aiVec3ToEigen(const aiVector3D &vec) { + Eigen::Vector3f v; + v.x() = vec.x; + v.y() = vec.y; + v.z() = vec.z; + return v; +} + +Eigen::Quaternionf ModelLoader::aiQuatToEigen(const aiQuaternion &q) { + Eigen::Quaternionf quat; + quat.w() = q.w; + quat.x() = q.x; + quat.y() = q.y; + quat.z() = q.z; + return quat; +} + +} // namespace ICE diff --git a/ICE/IO/src/Project.cpp b/ICE/IO/src/Project.cpp index 397fb3dc..e88c2034 100644 --- a/ICE/IO/src/Project.cpp +++ b/ICE/IO/src/Project.cpp @@ -1,355 +1,338 @@ -// -// Created by Thomas Ibanez on 09.12.20. -// - -#include "Project.h" - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "MaterialExporter.h" - -namespace ICE { -Project::Project(const fs::path &base_directory, const std::string &name) - : m_base_directory(base_directory / name), - name(name), - assetBank(std::make_shared(std::make_shared())) { - cameraPosition.setZero(); - cameraRotation.setZero(); - constexpr std::string_view assets_folder = "Assets"; - m_materials_directory = m_base_directory / assets_folder / "Materials"; - m_shaders_directory = m_base_directory / assets_folder / "Shaders"; - m_textures_directory = m_base_directory / assets_folder / "Textures"; - m_cubemaps_directory = m_base_directory / assets_folder / "Cubemaps"; - m_meshes_directory = m_base_directory / assets_folder / "Models"; - m_scenes_directory = m_base_directory / "Scenes"; -} - -bool Project::CreateDirectories() { - fs::create_directories(m_materials_directory); - fs::create_directories(m_shaders_directory); - fs::create_directories(m_textures_directory); - fs::create_directories(m_cubemaps_directory); - fs::create_directories(m_meshes_directory); - fs::create_directories(m_scenes_directory); - - copyAssetFile("Models", "cube", "Assets/Models/cube.obj"); - copyAssetFile("Models", "sphere", "Assets/Models/sphere.obj"); - copyAssetFile("Shaders", "phong", "Assets/Shaders/phong.vs"); - copyAssetFile("Shaders", "phong", "Assets/Shaders/phong.fs"); - copyAssetFile("Shaders", "solid", "Assets/Shaders/solid.vs"); - copyAssetFile("Shaders", "solid", "Assets/Shaders/solid.fs"); - copyAssetFile("Shaders", "normal", "Assets/Shaders/normal.vs"); - copyAssetFile("Shaders", "normal", "Assets/Shaders/normal.fs"); - copyAssetFile("Shaders", "picking", "Assets/Shaders/picking.vs"); - copyAssetFile("Shaders", "picking", "Assets/Shaders/picking.fs"); - copyAssetFile("Shaders", "lastpass", "Assets/Shaders/lastpass.vs"); - copyAssetFile("Shaders", "lastpass", "Assets/Shaders/lastpass.fs"); - copyAssetFile("Cubemaps", "skybox", "Assets/Textures/skybox.png"); - copyAssetFile("Materials", "base_mat", "Assets/Materials/base_mat.icm"); - - assetBank->addAsset("solid", {m_shaders_directory / "solid.vs", m_shaders_directory / "solid.fs"}); - assetBank->addAsset("phong", {m_shaders_directory / "phong.vs", m_shaders_directory / "phong.fs"}); - assetBank->addAsset("normal", {m_shaders_directory / "normal.vs", m_shaders_directory / "normal.fs"}); - assetBank->addAsset("lastpass", {m_shaders_directory / "lastpass.vs", m_shaders_directory / "lastpass.fs"}); - assetBank->addAsset("__ice__picking_shader", {m_shaders_directory / "picking.vs", m_shaders_directory / "picking.fs"}); - - assetBank->addAsset("skybox", {m_cubemaps_directory / "skybox.png"}); - - assetBank->addAsset("base_mat", {m_materials_directory / "base_mat.icm"}); - - assetBank->addAsset("cube", {m_meshes_directory / "cube.obj"}); - assetBank->addAsset("sphere", {m_meshes_directory / "sphere.obj"}); - - scenes.push_back(std::make_shared("MainScene")); - setCurrentScene(getScenes()[0]); - return true; -} - -fs::path Project::getBaseDirectory() const { - return m_base_directory; -} - -std::string Project::getName() const { - return name; -} - -void Project::writeToFile(const std::shared_ptr &editorCamera) { - std::ofstream outstream; - outstream.open(m_base_directory / (name + ".ice")); - json j; - - j["camera_position"] = dumpVec3(editorCamera->getPosition()); - j["camera_rotation"] = dumpVec3(editorCamera->getRotation()); - - std::vector vec; - for (const auto &s : scenes) { - vec.push_back(s->getName()); - } - j["scenes"] = vec; - vec.clear(); - - for (const auto &[asset_id, mesh] : assetBank->getAll()) { - vec.push_back(dumpAsset(asset_id, mesh)); - } - j["models"] = vec; - vec.clear(); - - for (const auto &[asset_id, material] : assetBank->getAll()) { - auto mtlName = assetBank->getName(asset_id).getName(); - - fs::path path = m_materials_directory.parent_path() / (assetBank->getName(asset_id).prefix() + mtlName + ".icm"); - fs::create_directories(path.parent_path()); - MaterialExporter().writeToJson(path, *material); - - material->setSources({path}); - - vec.push_back(dumpAsset(asset_id, material)); - } - j["materials"] = vec; - vec.clear(); - - for (const auto &[asset_id, shader] : assetBank->getAll()) { - vec.push_back(dumpAsset(asset_id, shader)); - } - j["shaders"] = vec; - vec.clear(); - - for (const auto &[asset_id, texture] : assetBank->getAll()) { - vec.push_back(dumpAsset(asset_id, texture)); - } - j["textures2D"] = vec; - vec.clear(); - - for (const auto &[asset_id, texture] : assetBank->getAll()) { - vec.push_back(dumpAsset(asset_id, texture)); - } - j["cubeMaps"] = vec; - - outstream << j.dump(4); - outstream.close(); - - for (const auto &s : scenes) { - outstream.open(m_scenes_directory / (s->getName() + ".ics")); - j.clear(); - - j["name"] = s->getName(); - json entities = json::array(); - for (auto e : s->getRegistry()->getEntities()) { - json entity; - entity["id"] = e; - entity["name"] = s->getAlias(e); - entity["parent"] = s->getGraph()->getParentID(e); - - if (s->getRegistry()->entityHasComponent(e)) { - RenderComponent rc = *s->getRegistry()->getComponent(e); - json renderjson; - renderjson["model"] = rc.model; - entity["renderComponent"] = renderjson; - } - if (s->getRegistry()->entityHasComponent(e)) { - TransformComponent tc = *s->getRegistry()->getComponent(e); - json transformjson; - transformjson["position"] = dumpVec3(tc.getPosition()); - transformjson["rotation"] = dumpVec3(tc.getRotation()); - transformjson["scale"] = dumpVec3(tc.getScale()); - entity["transformComponent"] = transformjson; - } - if (s->getRegistry()->entityHasComponent(e)) { - LightComponent lc = *s->getRegistry()->getComponent(e); - json lightjson; - lightjson["color"] = dumpVec3(lc.color); - lightjson["type"] = lc.type; - entity["lightComponent"] = lightjson; - } - entities.push_back(entity); - } - j["entities"] = entities; - outstream << j.dump(4); - outstream.close(); - } -} - -json Project::dumpAsset(AssetUID uid, const std::shared_ptr &asset) { - auto asset_path = assetBank->getName(uid); - json tmp; - auto paths = asset->getSources(); - std::vector sources(paths.size()); - std::transform(paths.begin(), paths.end(), sources.begin(), [this](const fs::path &path) { - auto relative = path.lexically_relative(m_base_directory); - return relative.string(); - }); - tmp["bank_path"] = asset_path.toString(); - tmp["uid"] = uid; - tmp["sources"] = sources; - return tmp; -} - -void Project::loadFromFile() { - std::ifstream infile = std::ifstream(m_base_directory / (name + ".ice")); - json j; - infile >> j; - infile.close(); - - std::vector sceneNames = j["scenes"]; - json meshes = j["models"]; - json material = j["materials"]; - json shader = j["shaders"]; - json texture = j["textures2D"]; - json cubeMap = j["cubeMaps"]; - - cameraPosition = JsonParser::parseVec3(j["camera_position"]); - cameraRotation = JsonParser::parseVec3(j["camera_rotation"]); - - loadAssetsOfType(shader); - loadAssetsOfType(texture); - loadAssetsOfType(cubeMap); - loadAssetsOfType(material); - loadAssetsOfType(meshes); - - for (const auto &s : sceneNames) { - infile = std::ifstream(m_scenes_directory / (s + ".ics")); - json scenejson; - infile >> scenejson; - infile.close(); - - Scene scene = Scene(scenejson["name"]); - - for (json jentity : scenejson["entities"]) { - Entity e = jentity["id"]; - Entity parent = jentity["parent"]; - std::string alias = jentity["name"]; - - scene.addEntity(e, alias, 0); - - if (!jentity["transformComponent"].is_null()) { - json tj = jentity["transformComponent"]; - TransformComponent tc(JsonParser::parseVec3(tj["position"]), JsonParser::parseVec3(tj["rotation"]), - JsonParser::parseVec3(tj["scale"])); - scene.getRegistry()->addComponent(e, tc); - } - if (!jentity["renderComponent"].is_null()) { - json rj = jentity["renderComponent"]; - RenderComponent rc(rj["model"]); - scene.getRegistry()->addComponent(e, rc); - } - if (!jentity["lightComponent"].is_null()) { - json lj = jentity["lightComponent"]; - LightComponent lc(static_cast((int) lj["type"]), JsonParser::parseVec3(lj["color"])); - scene.getRegistry()->addComponent(e, lc); - } - } - for (json jentity : scenejson["entities"]) { - Entity e = jentity["id"]; - Entity parent = jentity["parent"]; - scene.getGraph()->setParent(e, parent, true); - } - addScene(scene); - //TODO: it would be better to save the current scene index - setCurrentScene(getScenes()[0]); - } -} - -void Project::copyAssetFile(const fs::path &folder, const std::string &assetName, const fs::path &src) { - auto subfolder = m_base_directory / "Assets" / folder; - fs::create_directories(subfolder); - - auto dst = subfolder / (assetName + src.extension().string()); - std::ifstream srcStream(src, std::ios::binary); - std::ofstream dstStream(dst, std::ios::binary); - - dstStream << srcStream.rdbuf(); - dstStream.flush(); - srcStream.close(); - dstStream.close(); -} - -bool Project::renameAsset(const AssetPath &oldName, const AssetPath &newName) { - if (newName.getName() == "" || newName.prefix() != oldName.prefix()) { - return false; - } - if (assetBank->renameAsset(oldName, newName)) { - auto path = m_base_directory / "Assets"; - for (const auto &file : getFilesInDir(path / oldName.prefix())) { - if (file.substr(0, file.find_last_of(".")) == oldName.getName()) { - if (rename((path / oldName.prefix() / file).string().c_str(), - (path / oldName.prefix() / (newName.getName() + file.substr(file.find_last_of(".")))).string().c_str()) - == 0) { - return true; - } - } - } - return true; - } - return false; -} - -std::vector Project::getFilesInDir(const fs::path &folder) { - std::vector files; - for (const auto &entry : fs::directory_iterator(folder)) { - std::string sp = entry.path().string(); - files.push_back(sp.substr(sp.find_last_of("/") + 1)); - } - return files; -} - -std::vector> Project::getScenes() { - return scenes; -} - -void Project::setScenes(const std::vector> &scenes) { - Project::scenes = scenes; -} - -std::shared_ptr Project::getAssetBank() { - return assetBank; -} - -void Project::setAssetBank(const std::shared_ptr &assetBank) { - Project::assetBank = assetBank; -} - -void Project::addScene(const Scene &scene) { - scenes.push_back(std::make_shared(scene)); -} - -void Project::setCurrentScene(const std::shared_ptr &scene) { - m_current_scene = scene; -} -std::shared_ptr Project::getCurrentScene() const { - return m_current_scene; -} - -json Project::dumpVec3(const Eigen::Vector3f &v) { - json r; - r["x"] = v.x(); - r["y"] = v.y(); - r["z"] = v.z(); - return r; -} - -json Project::dumpVec4(const Eigen::Vector4f &v) { - json r; - r["x"] = v.x(); - r["y"] = v.y(); - r["z"] = v.z(); - r["w"] = v.w(); - return r; -} - -const Eigen::Vector3f &Project::getCameraPosition() const { - return cameraPosition; -} - -const Eigen::Vector3f &Project::getCameraRotation() const { - return cameraRotation; -} +// +// Created by Thomas Ibanez on 09.12.20. +// + +#include "Project.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "MaterialExporter.h" + +namespace ICE { +Project::Project(const fs::path &base_directory, const std::string &name) + : m_base_directory(base_directory / name), + name(name), + assetBank(std::make_shared(std::make_shared())) { + cameraPosition.setZero(); + cameraRotation.setZero(); + constexpr std::string_view assets_folder = "Assets"; + m_materials_directory = m_base_directory / assets_folder / "Materials"; + m_shaders_directory = m_base_directory / assets_folder / "Shaders"; + m_textures_directory = m_base_directory / assets_folder / "Textures"; + m_cubemaps_directory = m_base_directory / assets_folder / "Cubemaps"; + m_meshes_directory = m_base_directory / assets_folder / "Models"; + m_scenes_directory = m_base_directory / "Scenes"; +} + +bool Project::CreateDirectories() { + fs::create_directories(m_scenes_directory); + try { + fs::create_directories(m_base_directory / "Assets"); + fs::copy("Assets", m_base_directory / "Assets", fs::copy_options::recursive); + } catch (std::filesystem::filesystem_error &e) { + Logger::Log(Logger::FATAL, "IO", "Could not copy default assets: %s", e.what()); + } + assetBank->addAsset("solid", {m_shaders_directory / "solid.vs", m_shaders_directory / "solid.fs"}); + assetBank->addAsset("phong", {m_shaders_directory / "phong.vs", m_shaders_directory / "phong.fs"}); + assetBank->addAsset("normal", {m_shaders_directory / "normal.vs", m_shaders_directory / "normal.fs"}); + assetBank->addAsset("lastpass", {m_shaders_directory / "lastpass.vs", m_shaders_directory / "lastpass.fs"}); + assetBank->addAsset("__ice__picking_shader", {m_shaders_directory / "picking.vs", m_shaders_directory / "picking.fs"}); + + assetBank->addAsset("base_mat", {m_materials_directory / "base_mat.icm"}); + + assetBank->addAsset("cube", {m_meshes_directory / "cube.obj"}); + assetBank->addAsset("sphere", {m_meshes_directory / "sphere.obj"}); + + scenes.push_back(std::make_shared("MainScene")); + setCurrentScene(getScenes()[0]); + return true; +} + +fs::path Project::getBaseDirectory() const { + return m_base_directory; +} + +std::string Project::getName() const { + return name; +} + +void Project::writeToFile(const std::shared_ptr &editorCamera) { + std::ofstream outstream; + outstream.open(m_base_directory / (name + ".ice")); + json j; + + j["camera_position"] = dumpVec3(editorCamera->getPosition()); + j["camera_rotation"] = dumpVec3(editorCamera->getRotation()); + + std::vector vec; + for (const auto &s : scenes) { + vec.push_back(s->getName()); + } + j["scenes"] = vec; + vec.clear(); + + for (const auto &[asset_id, mesh] : assetBank->getAll()) { + vec.push_back(dumpAsset(asset_id, mesh)); + } + j["models"] = vec; + vec.clear(); + + for (const auto &[asset_id, material] : assetBank->getAll()) { + auto mtlName = assetBank->getName(asset_id).getName(); + + fs::path path = m_materials_directory.parent_path() / (assetBank->getName(asset_id).prefix() + mtlName + ".icm"); + fs::create_directories(path.parent_path()); + MaterialExporter().writeToJson(path, *material); + + material->setSources({path}); + + vec.push_back(dumpAsset(asset_id, material)); + } + j["materials"] = vec; + vec.clear(); + + for (const auto &[asset_id, shader] : assetBank->getAll()) { + vec.push_back(dumpAsset(asset_id, shader)); + } + j["shaders"] = vec; + vec.clear(); + + for (const auto &[asset_id, texture] : assetBank->getAll()) { + vec.push_back(dumpAsset(asset_id, texture)); + } + j["textures2D"] = vec; + vec.clear(); + + for (const auto &[asset_id, texture] : assetBank->getAll()) { + vec.push_back(dumpAsset(asset_id, texture)); + } + j["cubeMaps"] = vec; + + outstream << j.dump(4); + outstream.close(); + + for (const auto &s : scenes) { + outstream.open(m_scenes_directory / (s->getName() + ".ics")); + j.clear(); + + j["name"] = s->getName(); + json entities = json::array(); + for (auto e : s->getRegistry()->getEntities()) { + json entity; + entity["id"] = e; + entity["name"] = s->getAlias(e); + entity["parent"] = s->getGraph()->getParentID(e); + + if (s->getRegistry()->entityHasComponent(e)) { + RenderComponent rc = *s->getRegistry()->getComponent(e); + json renderjson; + renderjson["model"] = rc.model; + entity["renderComponent"] = renderjson; + } + if (s->getRegistry()->entityHasComponent(e)) { + TransformComponent tc = *s->getRegistry()->getComponent(e); + json transformjson; + transformjson["position"] = dumpVec3(tc.getPosition()); + transformjson["rotation"] = dumpVec3(tc.getRotation()); + transformjson["scale"] = dumpVec3(tc.getScale()); + entity["transformComponent"] = transformjson; + } + if (s->getRegistry()->entityHasComponent(e)) { + LightComponent lc = *s->getRegistry()->getComponent(e); + json lightjson; + lightjson["color"] = dumpVec3(lc.color); + lightjson["type"] = lc.type; + entity["lightComponent"] = lightjson; + } + entities.push_back(entity); + } + j["entities"] = entities; + outstream << j.dump(4); + outstream.close(); + } +} + +json Project::dumpAsset(AssetUID uid, const std::shared_ptr &asset) { + auto asset_path = assetBank->getName(uid); + json tmp; + auto paths = asset->getSources(); + std::vector sources(paths.size()); + std::transform(paths.begin(), paths.end(), sources.begin(), [this](const fs::path &path) { + auto relative = path.lexically_relative(m_base_directory); + return relative.string(); + }); + tmp["bank_path"] = asset_path.toString(); + tmp["uid"] = uid; + tmp["sources"] = sources; + return tmp; +} + +void Project::loadFromFile() { + std::ifstream infile = std::ifstream(m_base_directory / (name + ".ice")); + json j; + infile >> j; + infile.close(); + + std::vector sceneNames = j["scenes"]; + json meshes = j["models"]; + json material = j["materials"]; + json shader = j["shaders"]; + json texture = j["textures2D"]; + json cubeMap = j["cubeMaps"]; + + cameraPosition = JsonParser::parseVec3(j["camera_position"]); + cameraRotation = JsonParser::parseVec3(j["camera_rotation"]); + + loadAssetsOfType(shader); + loadAssetsOfType(texture); + loadAssetsOfType(cubeMap); + loadAssetsOfType(material); + loadAssetsOfType(meshes); + + for (const auto &s : sceneNames) { + infile = std::ifstream(m_scenes_directory / (s + ".ics")); + json scenejson; + infile >> scenejson; + infile.close(); + + Scene scene = Scene(scenejson["name"]); + + for (json jentity : scenejson["entities"]) { + Entity e = jentity["id"]; + Entity parent = jentity["parent"]; + std::string alias = jentity["name"]; + + scene.addEntity(e, alias, 0); + + if (!jentity["transformComponent"].is_null()) { + json tj = jentity["transformComponent"]; + TransformComponent tc(JsonParser::parseVec3(tj["position"]), JsonParser::parseVec3(tj["rotation"]), + JsonParser::parseVec3(tj["scale"])); + scene.getRegistry()->addComponent(e, tc); + } + if (!jentity["renderComponent"].is_null()) { + json rj = jentity["renderComponent"]; + RenderComponent rc(rj["model"]); + scene.getRegistry()->addComponent(e, rc); + } + if (!jentity["lightComponent"].is_null()) { + json lj = jentity["lightComponent"]; + LightComponent lc(static_cast((int) lj["type"]), JsonParser::parseVec3(lj["color"])); + scene.getRegistry()->addComponent(e, lc); + } + } + for (json jentity : scenejson["entities"]) { + Entity e = jentity["id"]; + Entity parent = jentity["parent"]; + scene.getGraph()->setParent(e, parent, true); + } + addScene(scene); + //TODO: it would be better to save the current scene index + setCurrentScene(getScenes()[0]); + } +} + +void Project::copyAssetFile(const fs::path &folder, const std::string &assetName, const fs::path &src) { + auto subfolder = m_base_directory / "Assets" / folder; + fs::create_directories(subfolder); + + auto dst = subfolder / (assetName + src.extension().string()); + std::ifstream srcStream(src, std::ios::binary); + std::ofstream dstStream(dst, std::ios::binary); + + dstStream << srcStream.rdbuf(); + dstStream.flush(); + srcStream.close(); + dstStream.close(); +} + +bool Project::renameAsset(const AssetPath &oldName, const AssetPath &newName) { + if (newName.getName() == "" || newName.prefix() != oldName.prefix()) { + return false; + } + if (assetBank->renameAsset(oldName, newName)) { + auto path = m_base_directory / "Assets"; + for (const auto &file : getFilesInDir(path / oldName.prefix())) { + if (file.substr(0, file.find_last_of(".")) == oldName.getName()) { + if (rename((path / oldName.prefix() / file).string().c_str(), + (path / oldName.prefix() / (newName.getName() + file.substr(file.find_last_of(".")))).string().c_str()) + == 0) { + return true; + } + } + } + return true; + } + return false; +} + +std::vector Project::getFilesInDir(const fs::path &folder) { + std::vector files; + for (const auto &entry : fs::directory_iterator(folder)) { + std::string sp = entry.path().string(); + files.push_back(sp.substr(sp.find_last_of("/") + 1)); + } + return files; +} + +std::vector> Project::getScenes() { + return scenes; +} + +void Project::setScenes(const std::vector> &scenes) { + Project::scenes = scenes; +} + +std::shared_ptr Project::getAssetBank() { + return assetBank; +} + +void Project::setAssetBank(const std::shared_ptr &assetBank) { + Project::assetBank = assetBank; +} + +void Project::addScene(const Scene &scene) { + scenes.push_back(std::make_shared(scene)); +} + +void Project::setCurrentScene(const std::shared_ptr &scene) { + m_current_scene = scene; +} +std::shared_ptr Project::getCurrentScene() const { + return m_current_scene; +} + +json Project::dumpVec3(const Eigen::Vector3f &v) { + json r; + r["x"] = v.x(); + r["y"] = v.y(); + r["z"] = v.z(); + return r; +} + +json Project::dumpVec4(const Eigen::Vector4f &v) { + json r; + r["x"] = v.x(); + r["y"] = v.y(); + r["z"] = v.z(); + r["w"] = v.w(); + return r; +} + +const Eigen::Vector3f &Project::getCameraPosition() const { + return cameraPosition; +} + +const Eigen::Vector3f &Project::getCameraRotation() const { + return cameraRotation; +} } // namespace ICE \ No newline at end of file diff --git a/ICE/IO/src/ShaderLoader.cpp b/ICE/IO/src/ShaderLoader.cpp index a5cf484b..8668c50d 100644 --- a/ICE/IO/src/ShaderLoader.cpp +++ b/ICE/IO/src/ShaderLoader.cpp @@ -7,19 +7,20 @@ #include #include -#include "FileUtils.h" +#include +#include namespace ICE { std::shared_ptr ShaderLoader::load(const std::vector &files) { if (files.size() < 2) { throw ICEException("Shaders must have at least 2 files"); } + std::shared_ptr shader; if (files.size() == 2) { - shader = graphics_factory->createShader(FileUtils::readFile(files[0].string()), FileUtils::readFile(files[1].string())); + shader = graphics_factory->createShader(readAndResolveIncludes(files[0]), readAndResolveIncludes(files[1])); } else if (files.size() == 3) { - shader = graphics_factory->createShader(FileUtils::readFile(files[0].string()), FileUtils::readFile(files[1].string()), - FileUtils::readFile(files[2].string())); + shader = graphics_factory->createShader(readAndResolveIncludes(files[0]), readAndResolveIncludes(files[1]), readAndResolveIncludes(files[2])); } else { throw ICEException("Too many files for shader"); } @@ -27,4 +28,35 @@ std::shared_ptr ShaderLoader::load(const std::vectorsetSources(files); return shader; } + +std::string ShaderLoader::readAndResolveIncludes(const std::filesystem::path &file_path) { + std::ifstream file(file_path); + if (!file.is_open()) { + throw std::runtime_error("Failed to open shader file: " + file_path.string()); + } + + std::stringstream result; + std::string line; + + while (std::getline(file, line)) { + // Trim whitespace + auto trimmed = line; + trimmed.erase(0, trimmed.find_first_not_of(" \t\r\n")); + trimmed.erase(trimmed.find_last_not_of(" \t\r\n") + 1); + + if (trimmed.starts_with("#include")) { + size_t startQuote = trimmed.find('"'); + size_t endQuote = trimmed.find('"', startQuote + 1); + if (startQuote != std::string::npos && endQuote != std::string::npos) { + std::filesystem::path includePath = file_path.parent_path() / trimmed.substr(startQuote + 1, endQuote - startQuote - 1); + result << readAndResolveIncludes(includePath) << "\n"; + continue; + } + } + result << line << "\n"; + } + + return result.str(); +} + } // namespace ICE \ No newline at end of file diff --git a/ICE/Math/include/ICEMath.h b/ICE/Math/include/ICEMath.h index aef5a91e..c326e258 100644 --- a/ICE/Math/include/ICEMath.h +++ b/ICE/Math/include/ICEMath.h @@ -28,6 +28,7 @@ Eigen::Matrix4f rotationMatrix(Eigen::Vector3f angles, bool yaw_first = true); Eigen::Matrix4f translationMatrix(Eigen::Vector3f translation); Eigen::Matrix4f scaleMatrix(Eigen::Vector3f scale); Eigen::Matrix4f transformationMatrix(const Eigen::Vector3f &translation, const Eigen::Vector3f &angles, const Eigen::Vector3f &scale); +void decomposeMatrix(const Eigen::Matrix4f &M, Eigen::Vector3f &position, Eigen::Vector3f &rotation_eulers, Eigen::Vector3f &scale); Eigen::Vector3f orientation(int face, float x, float y); int clamp(int x, int a, int b); diff --git a/ICE/Math/src/ICEMath.cpp b/ICE/Math/src/ICEMath.cpp index 13fd4a1c..f5e5fc2c 100644 --- a/ICE/Math/src/ICEMath.cpp +++ b/ICE/Math/src/ICEMath.cpp @@ -58,6 +58,54 @@ Eigen::Matrix4f transformationMatrix(const Eigen::Vector3f &translation, const E return translationMatrix(translation) * rotationMatrix(angles) * scaleMatrix(scale); } +void decomposeMatrix(const Eigen::Matrix4f &M, Eigen::Vector3f &position, Eigen::Vector3f &rotation_eulers, Eigen::Vector3f &scale) { + // --- 1. Extract Translation (Position) --- + position = M.block<3, 1>(0, 3); + + // --- 2. Extract Scale and Rotation --- + + // The 3x3 rotational/scaling block (top-left) + Eigen::Matrix3f R_S = M.block<3, 3>(0, 0); + + // --- Extract Scale (S) --- + // Scale factors are the magnitudes (norms) of the basis vectors (columns) + scale.x() = R_S.col(0).norm(); + scale.y() = R_S.col(1).norm(); + scale.z() = R_S.col(2).norm(); + + // Check for negative scale (reflection) + if (R_S.determinant() < 0.0f) { + scale.x() *= -1.0f; // Negate one component to account for reflection + } + + // --- Extract Rotation (R) --- + + // Create the pure rotation matrix R by dividing the R_S block by the extracted scale. + Eigen::Matrix3f R = R_S; + + // Divide each column by its corresponding scale factor to normalize it to a unit vector. + if (scale.x() != 0.0f) + R.col(0) /= scale.x(); + if (scale.y() != 0.0f) + R.col(1) /= scale.y(); + if (scale.z() != 0.0f) + R.col(2) /= scale.z(); + + // Convert the resulting 3x3 rotation matrix (R) to Z-Y-X Euler angles. + // Eigen's toEulerAngles(Z, Y, X) returns (alpha, beta, gamma) where: + // alpha = Rotation around Z (Yaw) + // beta = Rotation around Y (Pitch) + // gamma = Rotation around X (Roll) + rotation_eulers = R.eulerAngles(2, 1, 0); // 2=Z, 1=Y, 0=X + + // Note: The returned angles are in radians. + + // The Euler angles returned are in the following order based on the specified Eigen constants: + // rotation_eulers.x() is the Z-axis rotation (Yaw) + // rotation_eulers.y() is the Y-axis rotation (Pitch) + // rotation_eulers.z() is the X-axis rotation (Roll) +} + Eigen::Vector3f orientation(int face, float x, float y) { Eigen::Vector3f out; if (face == ICE_CUBEMAP_PZ) { diff --git a/ICE/System/CMakeLists.txt b/ICE/System/CMakeLists.txt index 932e0c79..fe990d96 100644 --- a/ICE/System/CMakeLists.txt +++ b/ICE/System/CMakeLists.txt @@ -1,23 +1,23 @@ -cmake_minimum_required(VERSION 3.19) -project(system) - -message(STATUS "Building ${PROJECT_NAME} module") - -add_library(${PROJECT_NAME} STATIC) - -target_sources(${PROJECT_NAME} PRIVATE - src/RenderSystem.cpp -) - -target_link_libraries(${PROJECT_NAME} - PUBLIC - graphics - entity -) - -target_include_directories(${PROJECT_NAME} PUBLIC - $ - $) - -enable_testing() -#add_subdirectory(test) +cmake_minimum_required(VERSION 3.19) +project(system) + +message(STATUS "Building ${PROJECT_NAME} module") + +add_library(${PROJECT_NAME} STATIC) + +target_sources(${PROJECT_NAME} PRIVATE + src/RenderSystem.cpp + src/AnimationSystem.cpp) + +target_link_libraries(${PROJECT_NAME} + PUBLIC + graphics + entity +) + +target_include_directories(${PROJECT_NAME} PUBLIC + $ + $) + +enable_testing() +#add_subdirectory(test) diff --git a/ICE/System/include/AnimationSystem.h b/ICE/System/include/AnimationSystem.h new file mode 100644 index 00000000..ecd7d381 --- /dev/null +++ b/ICE/System/include/AnimationSystem.h @@ -0,0 +1,47 @@ +#pragma once + +#include + +#include "Animation.h" +#include "AnimationComponent.h" +#include "System.h" + +namespace ICE { +class AnimationSystem : public System { + public: + AnimationSystem(const std::shared_ptr& reg, const std::shared_ptr& bank); + void update(double delta) override; + + std::vector getSignatures(const ComponentManager& comp_manager) const override { + Signature signature; + signature.set(comp_manager.getComponentType()); + signature.set(comp_manager.getComponentType()); + return {signature}; + } + + private: + template + size_t findKeyIndex(double animationTime, const std::vector& keys) { + for (size_t i = 0; i < keys.size() - 1; ++i) { + if (animationTime < keys[i + 1].timeStamp) { + return i; + } + } + return keys.size() - 1; + } + + void updateSkeleton(const std::shared_ptr& model, double time, const Animation& anim); + + Eigen::Matrix4f interpolatePosition(double timeInTicks, const BoneAnimation& track); + + Eigen::Matrix4f interpolateScale(double timeInTicks, const BoneAnimation& track); + + Eigen::Matrix4f interpolateRotation(double time, const BoneAnimation& track); + + void applyTransforms(Model::Node* node, const Eigen::Matrix4f& parentTransform, Model::Skeleton& skeleton, double time, const Animation& anim, + std::vector& allModelNodes); + + std::shared_ptr m_registry; + std::shared_ptr m_asset_bank; +}; +} // namespace ICE diff --git a/ICE/System/include/Registry.h b/ICE/System/include/Registry.h index 882cb3d1..45e28287 100644 --- a/ICE/System/include/Registry.h +++ b/ICE/System/include/Registry.h @@ -1,122 +1,111 @@ -// -// Created by Thomas Ibanez on 26.01.23. -// - -#ifndef ICE_REGISTRY_H -#define ICE_REGISTRY_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace ICE { -class Registry { - public: - Registry(/* args */) { - componentManager.registerComponent(); - componentManager.registerComponent(); - componentManager.registerComponent(); - componentManager.registerComponent(); - componentManager.registerComponent(); - - Signature signature; - signature.set(componentManager.getComponentType()); - signature.set(componentManager.getComponentType()); - systemManager.registerSystem(); - systemManager.addSignature(signature); - signature.reset(); - signature.set(componentManager.getComponentType()); - signature.set(componentManager.getComponentType()); - systemManager.addSignature(signature); - signature.reset(); - signature.set(componentManager.getComponentType()); - systemManager.addSignature(signature); - } - ~Registry(){}; - - template - void registerCustomComponent() { - componentManager.registerComponent(); - } - - Entity createEntity() { - Entity e = entityManager.createEntity(); - entities.push_back(e); - return e; - } - - void addEntity(Entity e) { - entityManager.createEntity(e); - entities.push_back(e); - } - - void removeEntity(Entity e) { - auto it = std::find(entities.begin(), entities.end(), e); - entities.erase(it); - componentManager.entityDestroyed(e); - entityManager.releaseEntity(e); - systemManager.entityDestroyed(e); - } - - std::vector getEntities() const { return entities; } - - template - bool entityHasComponent(Entity e) { - return entityManager.getSignature(e).test(componentManager.getComponentType()); - } - - template - T *getComponent(Entity e) { - return componentManager.getComponent(e); - } - - template - void addComponent(Entity e, T component) { - componentManager.addComponent(e, component); - auto signature = entityManager.getSignature(e); - signature.set(componentManager.getComponentType(), true); - entityManager.setSignature(e, signature); - systemManager.entitySignatureChanged(e, signature); - } - - template - void removeComponent(Entity e) { - componentManager.removeComponent(e); - auto signature = entityManager.getSignature(e); - signature.set(componentManager.getComponentType(), false); - entityManager.setSignature(e, signature); - systemManager.entitySignatureChanged(e, signature); - } - - template - void addSystem(const std::shared_ptr &system) { - systemManager.addSystem(system); - for (const auto e : entities) { - systemManager.entitySignatureChanged(e, entityManager.getSignature(e)); - } - } - - template - std::shared_ptr getSystem() { - return systemManager.getSystem(); - } - - void updateSystems(double delta) { systemManager.updateSystems(delta); } - - private: - EntityManager entityManager; - ComponentManager componentManager; - SystemManager systemManager; - std::vector entities; -}; -} // namespace ICE - -#endif //ICE_REGISTRY_H +// +// Created by Thomas Ibanez on 26.01.23. +// + +#ifndef ICE_REGISTRY_H +#define ICE_REGISTRY_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace ICE { +class Registry { + public: + Registry() { + componentManager.registerComponent(); + componentManager.registerComponent(); + componentManager.registerComponent(); + componentManager.registerComponent(); + componentManager.registerComponent(); + componentManager.registerComponent(); + } + ~Registry() = default; + + template + void registerCustomComponent() { + componentManager.registerComponent(); + } + + Entity createEntity() { + Entity e = entityManager.createEntity(); + entities.push_back(e); + return e; + } + + void addEntity(Entity e) { + entityManager.createEntity(e); + entities.push_back(e); + } + + void removeEntity(Entity e) { + auto it = std::find(entities.begin(), entities.end(), e); + entities.erase(it); + componentManager.entityDestroyed(e); + entityManager.releaseEntity(e); + systemManager.entityDestroyed(e); + } + + std::vector getEntities() const { return entities; } + + template + bool entityHasComponent(Entity e) { + return entityManager.getSignature(e).test(componentManager.getComponentType()); + } + + template + T *getComponent(Entity e) { + return componentManager.getComponent(e); + } + + template + void addComponent(Entity e, T component) { + componentManager.addComponent(e, component); + auto signature = entityManager.getSignature(e); + signature.set(componentManager.getComponentType(), true); + entityManager.setSignature(e, signature); + systemManager.entitySignatureChanged(e, signature, componentManager); + } + + template + void removeComponent(Entity e) { + componentManager.removeComponent(e); + auto signature = entityManager.getSignature(e); + signature.set(componentManager.getComponentType(), false); + entityManager.setSignature(e, signature); + systemManager.entitySignatureChanged(e, signature, componentManager); + } + + template + void addSystem(const std::shared_ptr &system) { + systemManager.addSystem(system); + for (const auto e : entities) { + systemManager.entitySignatureChanged(e, entityManager.getSignature(e), componentManager); + } + } + + template + std::shared_ptr getSystem() { + return systemManager.getSystem(); + } + + void updateSystems(double delta) { systemManager.updateSystems(delta); } + + private: + EntityManager entityManager; + ComponentManager componentManager; + SystemManager systemManager; + std::vector entities; +}; +} // namespace ICE + +#endif //ICE_REGISTRY_H diff --git a/ICE/System/include/RenderSystem.h b/ICE/System/include/RenderSystem.h index f6d18aa4..5efba999 100644 --- a/ICE/System/include/RenderSystem.h +++ b/ICE/System/include/RenderSystem.h @@ -1,34 +1,50 @@ -// -// Created by Thomas Ibanez on 19.11.20. -// -#pragma once - -#include -#include -#include -#include - -namespace ICE { -class Scene; - -class RenderSystem : public System { - public: - RenderSystem(){}; - - void onEntityAdded(Entity e) override; - void onEntityRemoved(Entity e) override; - void update(double delta) override; - - std::shared_ptr getRenderer() const; - void setRenderer(const std::shared_ptr &renderer); - std::shared_ptr getCamera() const; - void setCamera(const std::shared_ptr &camera); - - void setTarget(const std::shared_ptr &fb); - void setViewport(int x, int y, int w, int h); - - private: - std::shared_ptr m_renderer; - std::shared_ptr m_camera; -}; -} // namespace ICE +// +// Created by Thomas Ibanez on 19.11.20. +// +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include + +namespace ICE { +class Scene; + +class RenderSystem : public System { + public: + RenderSystem() {}; + + void onEntityAdded(Entity e) override; + void onEntityRemoved(Entity e) override; + void update(double delta) override; + + std::shared_ptr getRenderer() const; + void setRenderer(const std::shared_ptr &renderer); + std::shared_ptr getCamera() const; + void setCamera(const std::shared_ptr &camera); + + void setTarget(const std::shared_ptr &fb); + void setViewport(int x, int y, int w, int h); + + std::vector getSignatures(const ComponentManager &comp_manager) const override { + Signature signature0; + signature0.set(comp_manager.getComponentType()); + signature0.set(comp_manager.getComponentType()); + Signature signature1; + signature1.set(comp_manager.getComponentType()); + signature1.set(comp_manager.getComponentType()); + Signature signature2; + signature2.set(comp_manager.getComponentType()); + return {signature0, signature1, signature2}; + } + + private: + std::shared_ptr m_renderer; + std::shared_ptr m_camera; +}; +} // namespace ICE diff --git a/ICE/System/include/System.h b/ICE/System/include/System.h index 7b68ff93..7001b006 100644 --- a/ICE/System/include/System.h +++ b/ICE/System/include/System.h @@ -1,104 +1,91 @@ -// -// Created by Thomas Ibanez on 19.11.20. -// - -#pragma once - -#include - -#include -#include -#include -#include -#include - -namespace ICE { -class Scene; - -class System { - public: - virtual void update(double delta) = 0; - virtual void onEntityAdded(Entity e) = 0; - virtual void onEntityRemoved(Entity e) = 0; - - protected: - std::unordered_set entities; - - friend class SystemManager; -}; - -class SystemManager { - public: - template - void registerSystem() { - assert(systems.find(typeid(T)) == systems.end() && "Registering system more than once."); - signatures.insert({typeid(T), std::vector()}); - } - - template - void addSignature(Signature signature) { - assert(signatures.find(typeid(T)) != signatures.end() && "System used before registered."); - - // Set the signature for this system - signatures[typeid(T)].push_back(signature); - } - - void entityDestroyed(Entity entity) { - // Erase a destroyed entity from all system lists - // mEntities is a set so no check needed - for (auto const& pair : systems) { - auto const& system = pair.second; - - system->entities.erase(entity); - system->onEntityRemoved(entity); - } - } - - void entitySignatureChanged(Entity entity, Signature entitySignature) { - // Notify each system that an entity's signature changed - for (auto const& pair : systems) { - auto const& system = pair.second; - auto const& systemSignature = signatures[pair.first]; - - // Entity signature matches system signature - insert into set - bool match = false; - for (const auto& s : systemSignature) { - if ((entitySignature & s) == s) { - system->entities.insert(entity); - system->onEntityAdded(entity); - match = true; - break; - } - } - // Entity signature does not match system signature - erase from set - if (!match) { - system->entities.erase(entity); - system->onEntityRemoved(entity); - } - } - } - - void updateSystems(double delta) { - for (auto const& [signature, system] : systems) { - system->update(delta); - } - } - - template - void addSystem(const std::shared_ptr& system) { - systems.try_emplace(typeid(T), system); - } - - template - std::shared_ptr getSystem() { - return std::static_pointer_cast(systems.at(typeid(T))); - } - - private: - // Map from system type string pointer to a signature - std::unordered_map> signatures; - - // Map from system type string pointer to a system pointer - std::unordered_map> systems; -}; -} // namespace ICE +// +// Created by Thomas Ibanez on 19.11.20. +// + +#pragma once + +#include + +#include +#include +#include +#include +#include + +namespace ICE { +class Scene; +class ComponentManager; + +class System { + public: + virtual void update(double delta) = 0; + virtual void onEntityAdded(Entity e) {}; + virtual void onEntityRemoved(Entity e) {}; + + virtual std::vector getSignatures(const ComponentManager& comp_manager) const = 0; + virtual ~System() = default; + + protected: + std::unordered_set entities; + + friend class SystemManager; +}; + +class SystemManager { + public: + void entityDestroyed(Entity entity) { + // Erase a destroyed entity from all system lists + // mEntities is a set so no check needed + for (auto const& pair : systems) { + auto const& system = pair.second; + + system->entities.erase(entity); + system->onEntityRemoved(entity); + } + } + + void entitySignatureChanged(Entity entity, Signature entitySignature, const ComponentManager& comp_manager) { + // Notify each system that an entity's signature changed + for (auto const& pair : systems) { + auto const& system = pair.second; + auto const& systemSignature = system->getSignatures(comp_manager); + + // Entity signature matches system signature - insert into set + bool match = false; + for (const auto& s : systemSignature) { + if ((entitySignature & s) == s) { + system->entities.insert(entity); + system->onEntityAdded(entity); + match = true; + break; + } + } + // Entity signature does not match system signature - erase from set + if (!match) { + system->entities.erase(entity); + system->onEntityRemoved(entity); + } + } + } + + void updateSystems(double delta) { + for (auto const& [signature, system] : systems) { + system->update(delta); + } + } + + template + void addSystem(const std::shared_ptr& system) { + systems.try_emplace(typeid(T), system); + } + + template + std::shared_ptr getSystem() { + return std::static_pointer_cast(systems.at(typeid(T))); + } + + private: + // Map from system type string pointer to a system pointer + std::unordered_map> systems; +}; +} // namespace ICE diff --git a/ICE/System/src/AnimationSystem.cpp b/ICE/System/src/AnimationSystem.cpp new file mode 100644 index 00000000..374078ff --- /dev/null +++ b/ICE/System/src/AnimationSystem.cpp @@ -0,0 +1,153 @@ +#include "AnimationSystem.h" + +#include + +namespace ICE { +AnimationSystem::AnimationSystem(const std::shared_ptr& reg, const std::shared_ptr& bank) : m_registry(reg), m_asset_bank(bank) { +} + +void AnimationSystem::update(double dt) { + for (auto e : entities) { + auto anim = m_registry->getComponent(e); + auto rc = m_registry->getComponent(e); + if (!anim->playing) + continue; + + anim->currentTime += dt * anim->speed; + + auto model = m_asset_bank->getAsset(rc->model); + auto animation = model->getAnimations().at(anim->currentAnimation); + + if (anim->currentTime > animation.duration) { + if (anim->loop) { + anim->currentTime = std::fmod(anim->currentTime, animation.duration); + } else { + anim->currentTime = animation.duration; + anim->playing = false; + } + } + updateSkeleton(model, anim->currentTime, animation); + } +} + +void AnimationSystem::updateSkeleton(const std::shared_ptr& model, double time, const Animation& anim) { + auto& all_nodes = model->getNodes(); + applyTransforms(&all_nodes[0], Eigen::Matrix4f::Identity(), model->getSkeleton(), time, anim, all_nodes); +} + +void AnimationSystem::applyTransforms(Model::Node* node, const Eigen::Matrix4f& parentTransform, Model::Skeleton& skeleton, double time, + const Animation& anim, std::vector& allModelNodes) { + Eigen::Matrix4f nodeLocalTransform = node->localTransform; + std::string nodeName = node->name; + Eigen::Matrix4f globalTransform; + if (anim.tracks.contains(nodeName)) { + const BoneAnimation& track = anim.tracks.at(nodeName); + + Eigen::Matrix4f posMatrix = interpolatePosition(time, track); + Eigen::Matrix4f rotMatrix = interpolateRotation(time, track); + Eigen::Matrix4f scaleMatrix = interpolateScale(time, track); + + nodeLocalTransform = posMatrix * rotMatrix * scaleMatrix; + } + + globalTransform = parentTransform * nodeLocalTransform; + node->animatedTransform = globalTransform; + + if (skeleton.boneMapping.contains(nodeName)) { + int boneID = skeleton.boneMapping.at(nodeName); + skeleton.bones[boneID].finalTransformation = skeleton.globalInverseTransform * globalTransform; + } + + for (int childIndex : node->children) { + applyTransforms(&allModelNodes[childIndex], globalTransform, skeleton, time, anim, allModelNodes); + } +} + +Eigen::Matrix4f AnimationSystem::interpolatePosition(double timeInTicks, const BoneAnimation& track) { + if (track.positions.empty()) { + return Eigen::Matrix4f::Identity(); + } + if (track.positions.size() == 1) { + Eigen::Matrix4f positionMatrix = Eigen::Matrix4f::Identity(); + positionMatrix.block<3, 1>(0, 3) = track.positions[0].position; + return positionMatrix; + } + + size_t startIndex = findKeyIndex(timeInTicks, track.positions); + size_t nextIndex = startIndex + 1; + + const auto& startKey = track.positions[startIndex]; + const auto& nextKey = track.positions[nextIndex]; + + double totalTime = nextKey.timeStamp - startKey.timeStamp; + if (totalTime == 0.0) + return Eigen::Matrix4f::Identity(); + + double currentTime = timeInTicks - startKey.timeStamp; + float factor = (float) (currentTime / totalTime); + + Eigen::Vector3f interpolatedPosition = startKey.position + factor * (nextKey.position - startKey.position); + + Eigen::Matrix4f positionMatrix = Eigen::Matrix4f::Identity(); + positionMatrix.block<3, 1>(0, 3) = interpolatedPosition; + + return positionMatrix; +} + +Eigen::Matrix4f AnimationSystem::interpolateScale(double timeInTicks, const BoneAnimation& track) { + if (track.scales.empty()) { + return Eigen::Matrix4f::Identity(); + } + if (track.scales.size() == 1) { + Eigen::Matrix4f scaleMatrix = Eigen::Matrix4f::Identity(); + scaleMatrix.block<3, 3>(0, 0) = track.scales[0].scale.asDiagonal(); + return scaleMatrix; + } + + size_t startIndex = findKeyIndex(timeInTicks, track.scales); + size_t nextIndex = startIndex + 1; + + const auto& startKey = track.scales[startIndex]; + const auto& nextKey = track.scales[nextIndex]; + + double totalTime = nextKey.timeStamp - startKey.timeStamp; + if (totalTime == 0.0) + return Eigen::Matrix4f::Identity(); + + double currentTime = timeInTicks - startKey.timeStamp; + float factor = (float) (currentTime / totalTime); + + Eigen::Vector3f interpolatedScale = startKey.scale + factor * (nextKey.scale - startKey.scale); + + Eigen::Matrix4f scaleMatrix = Eigen::Matrix4f::Identity(); + scaleMatrix.block<3, 3>(0, 0) = interpolatedScale.asDiagonal(); + return scaleMatrix; +} + +Eigen::Matrix4f AnimationSystem::interpolateRotation(double time, const BoneAnimation& track) { + if (track.rotations.size() == 1) { + Eigen::Matrix4f rotation_matrix = Eigen::Matrix4f::Identity(); + rotation_matrix.block<3, 3>(0, 0) = track.rotations[0].rotation.toRotationMatrix(); + + return rotation_matrix; + } + + size_t startIdx = findKeyIndex(time, track.rotations); + size_t nextIdx = startIdx + 1; + + const auto& startKey = track.rotations[startIdx]; + const auto& nextKey = track.rotations[nextIdx]; + + double totalTime = nextKey.timeStamp - startKey.timeStamp; + double factor = (time - startKey.timeStamp) / totalTime; + + Eigen::Quaternionf finalQuat = startKey.rotation.slerp((float) factor, nextKey.rotation); + finalQuat.normalize(); + + Eigen::Matrix4f rotation_matrix = Eigen::Matrix4f::Identity(); + rotation_matrix.block<3, 3>(0, 0) = finalQuat.toRotationMatrix(); + + return rotation_matrix; +} + +} // namespace ICE \ No newline at end of file diff --git a/ICE/Util/include/BufferUtils.h b/ICE/Util/include/BufferUtils.h index f60e0f67..c02bb62a 100644 --- a/ICE/Util/include/BufferUtils.h +++ b/ICE/Util/include/BufferUtils.h @@ -25,6 +25,19 @@ namespace ICE { return buffer; } + static float* CreateFloatBuffer(const std::vector& vectors) { + auto buffer = static_cast(malloc(sizeof(float) * 4 * vectors.size())); + uint32_t i = 0; + for (const auto& v : vectors) { + buffer[i] = (float) v.x(); + buffer[i + 1] = (float) v.y(); + buffer[i + 2] = (float) v.z(); + buffer[i + 3] = (float) v.w(); + i += 4; + } + return buffer; + } + static float* CreateFloatBuffer(const std::vector& vectors) { auto* buffer = static_cast(malloc(sizeof(float) * 2 * vectors.size())); uint32_t i = 0; @@ -48,6 +61,19 @@ namespace ICE { return buffer; } + static int* CreateIntBuffer(const std::vector& vectors) { + auto* buffer = static_cast(malloc(sizeof(int) * 4 * vectors.size())); + uint32_t i = 0; + for (const auto& v : vectors) { + buffer[i] = v.x(); + buffer[i + 1] = v.y(); + buffer[i + 2] = v.z(); + buffer[i + 3] = v.w(); + i += 4; + } + return buffer; + } + static std::vector CreateCharBuffer(const std::vector& strings) { std::vector pointerVec(strings.size()); for(unsigned i = 0; i < strings.size(); ++i) diff --git a/ICEBERG/src/Iceberg.cpp b/ICEBERG/src/Iceberg.cpp index 3207d995..e0909a96 100644 --- a/ICEBERG/src/Iceberg.cpp +++ b/ICEBERG/src/Iceberg.cpp @@ -92,7 +92,7 @@ int main(int argc, char const* argv[]) { ImGuiIO& io = ImGui::GetIO(); io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls ImGui_ImplGlfw_InitForOpenGL(static_cast(window->getHandle()), true); - ImGui_ImplOpenGL3_Init("#version 330 core"); + ImGui_ImplOpenGL3_Init("#version 420 core"); Iceberg iceberg(window); diff --git a/ICEFIELD/Assets/cube.obj b/ICEFIELD/Assets/cube.obj deleted file mode 100644 index ce1ad5a0..00000000 --- a/ICEFIELD/Assets/cube.obj +++ /dev/null @@ -1,44 +0,0 @@ -# Blender v2.82 (sub 7) OBJ File: '' -# www.blender.org -o Cube -v 0.500097 0.500097 -0.500097 -v 0.500097 -0.500097 -0.500097 -v 0.500097 0.500097 0.500097 -v 0.500097 -0.500097 0.500097 -v -0.500097 0.500097 -0.500097 -v -0.500097 -0.500097 -0.500097 -v -0.500097 0.500097 0.500097 -v -0.500097 -0.500097 0.500097 -vt 0.875000 0.500000 -vt 0.625000 0.750000 -vt 0.625000 0.500000 -vt 0.375000 1.000000 -vt 0.375000 0.750000 -vt 0.625000 0.000000 -vt 0.375000 0.250000 -vt 0.375000 0.000000 -vt 0.375000 0.500000 -vt 0.125000 0.750000 -vt 0.125000 0.500000 -vt 0.625000 0.250000 -vt 0.875000 0.750000 -vt 0.625000 1.000000 -vn 0.0000 1.0000 0.0000 -vn 0.0000 0.0000 1.0000 -vn -1.0000 0.0000 0.0000 -vn 0.0000 -1.0000 0.0000 -vn 1.0000 0.0000 0.0000 -vn 0.0000 0.0000 -1.0000 -s off -f 5/1/1 3/2/1 1/3/1 -f 3/2/2 8/4/2 4/5/2 -f 7/6/3 6/7/3 8/8/3 -f 2/9/4 8/10/4 6/11/4 -f 1/3/5 4/5/5 2/9/5 -f 5/12/6 2/9/6 6/7/6 -f 5/1/1 7/13/1 3/2/1 -f 3/2/2 7/14/2 8/4/2 -f 7/6/3 5/12/3 6/7/3 -f 2/9/4 4/5/4 8/10/4 -f 1/3/5 3/2/5 4/5/5 -f 5/12/6 1/3/6 2/9/6 diff --git a/ICEFIELD/Assets/solid.fs b/ICEFIELD/Assets/solid.fs deleted file mode 100644 index 2bc2b148..00000000 --- a/ICEFIELD/Assets/solid.fs +++ /dev/null @@ -1,9 +0,0 @@ -#version 330 core - -out vec4 frag_color; - -uniform vec3 uAlbedo; - -void main() { - frag_color = vec4(uAlbedo, 1.0); -} \ No newline at end of file diff --git a/ICEFIELD/Assets/solid.vs b/ICEFIELD/Assets/solid.vs deleted file mode 100644 index c457cfbd..00000000 --- a/ICEFIELD/Assets/solid.vs +++ /dev/null @@ -1,13 +0,0 @@ -#version 330 core - -layout (location = 0) in vec3 vertex; -layout (location = 1) in vec3 normal; -layout (location = 2) in vec2 tex_coords; - -uniform mat4 projection; -uniform mat4 view; -uniform mat4 model; - -void main() { - gl_Position = projection * view * model * vec4(vertex, 1.0); -} \ No newline at end of file diff --git a/ICEFIELD/CMakeLists.txt b/ICEFIELD/CMakeLists.txt index d1c27fc5..dc48c186 100644 --- a/ICEFIELD/CMakeLists.txt +++ b/ICEFIELD/CMakeLists.txt @@ -1,17 +1,18 @@ -cmake_minimum_required(VERSION 3.19) -project(ICEFIELD) - -message(STATUS "Building ${PROJECT_NAME}") - -add_executable(${PROJECT_NAME} - icefield.cpp - ${GL3W_SRC} -) - -target_include_directories(${PROJECT_NAME} PUBLIC - $ - ${CMAKE_SOURCE_DIR} -) - -target_link_libraries(${PROJECT_NAME} PUBLIC ICE glfw) -file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/Assets DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) \ No newline at end of file +cmake_minimum_required(VERSION 3.19) +project(ICEFIELD) + +message(STATUS "Building ${PROJECT_NAME}") + +add_executable(${PROJECT_NAME} + icefield.cpp + ${GL3W_SRC} +) + +target_include_directories(${PROJECT_NAME} PUBLIC + $ + ${CMAKE_SOURCE_DIR} +) + +target_link_libraries(${PROJECT_NAME} PUBLIC ICE glfw) +file(COPY ${ICE_ROOT_SOURCE_DIR}/Assets DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) +file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/ImportAssets DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/ICEFIELD/ImportAssets/Adventurer.glb b/ICEFIELD/ImportAssets/Adventurer.glb new file mode 100644 index 00000000..883c5193 Binary files /dev/null and b/ICEFIELD/ImportAssets/Adventurer.glb differ diff --git a/ICEFIELD/ImportAssets/glock.glb b/ICEFIELD/ImportAssets/glock.glb new file mode 100644 index 00000000..39b0dd95 Binary files /dev/null and b/ICEFIELD/ImportAssets/glock.glb differ diff --git a/ICEFIELD/ImportAssets/pistol.glb b/ICEFIELD/ImportAssets/pistol.glb new file mode 100644 index 00000000..3c3869f4 Binary files /dev/null and b/ICEFIELD/ImportAssets/pistol.glb differ diff --git a/ICEFIELD/icefield.cpp b/ICEFIELD/icefield.cpp index a2d3851b..25d9877c 100644 --- a/ICEFIELD/icefield.cpp +++ b/ICEFIELD/icefield.cpp @@ -1,69 +1,73 @@ -#include -#include -#include -#include -#include - -#include - -using namespace ICE; - -int main(void) { - ICEEngine engine; - WindowFactory win_factory; - auto window = win_factory.createWindow(WindowBackend::GLFW, 1280, 720, "IceField"); - auto g_factory = std::make_shared(); - - engine.initialize(g_factory, window); - - auto project = std::make_shared(".", "IceField"); - project->addScene(Scene("TestScene")); - auto scene = project->getScenes().front(); - project->setCurrentScene(scene); - - engine.setProject(project); - - engine.getAssetBank()->addAsset("cube", {"Assets/cube.obj"}); - - engine.getAssetBank()->addAsset("solid", {"Assets/solid.vs", "Assets/solid.fs"}); - auto shader_id = engine.getAssetBank()->getUID(std::string("Shaders/solid")); - - auto mat = std::make_shared(); - mat->setShader(shader_id); - mat->setUniform("uAlbedo", Eigen::Vector3f(0.2, 0.5, 1)); - engine.getAssetBank()->addAsset("mat", mat); - - auto mesh_id = engine.getAssetBank()->getUID(std::string("Models/cube")); - auto material_id = engine.getAssetBank()->getUID(std::string("Materials/mat")); - - auto entity = scene->createEntity(); - scene->getRegistry()->addComponent(entity, TransformComponent(Eigen::Vector3f::Zero(), Eigen::Vector3f::Zero(), Eigen::Vector3f(1, 1, 1))); - scene->getRegistry()->addComponent(entity, RenderComponent(mesh_id)); - - auto camera = std::make_shared(60.0, 16.0 / 9.0, 0.01, 10000.0); - camera->backward(2); - camera->up(1); - camera->pitch(-30); - scene->getRegistry()->getSystem()->setCamera(camera); - - int i = 0; - while (!window->shouldClose()) { - window->pollEvents(); - - engine.step(); - - mat->setUniform("uAlbedo", Eigen::Vector3f(abs(sin(i / 100.0)), 0.5, 1)); - scene->getRegistry()->getComponent(entity)->rotation().y() = i; - - //Render system duty - int display_w, display_h; - window->getFramebufferSize(&display_w, &display_h); - engine.getApi()->setViewport(0, 0, display_w, display_h); - window->swapBuffers(); - i++; - } - - MaterialExporter().writeToJson("base_mat.icm", *mat); - - return 0; +#include +#include +#include +#include +#include +#include +#include + +using namespace ICE; + +int main(void) { + std::filesystem::remove_all("IceField_project"); + ICEEngine engine; + WindowFactory win_factory; + auto window = win_factory.createWindow(WindowBackend::GLFW, 1280, 720, "IceField"); + auto g_factory = std::make_shared(); + + engine.initialize(g_factory, window); + + auto project = std::make_shared(".", "IceField_project"); + project->CreateDirectories(); + project->addScene(Scene("TestScene")); + auto scene = project->getScenes().front(); + project->setCurrentScene(scene); + + engine.getApi()->setClearColor(0.5f, 0.5f, 0.5f, 1.0f); + + engine.setProject(project); + project->getCurrentScene()->getRegistry()->addSystem(std::make_shared(scene->getRegistry(), engine.getAssetBank())); + + engine.getProject()->copyAssetFile("Models", "glock", "ImportAssets/glock.glb"); + engine.getAssetBank()->addAsset("glock", {engine.getProject()->getBaseDirectory() / "Assets" / "Models" / "glock.glb"}); + engine.getProject()->copyAssetFile("Models", "pistol", "ImportAssets/pistol.glb"); + engine.getAssetBank()->addAsset("pistol", {engine.getProject()->getBaseDirectory() / "Assets" / "Models" / "pistol.glb"}); + engine.getProject()->copyAssetFile("Models", "Adventurer", "ImportAssets/Adventurer.glb"); + engine.getAssetBank()->addAsset("Adventurer", {engine.getProject()->getBaseDirectory() / "Assets" / "Models" / "Adventurer.glb"}); + + auto entity = scene->createEntity(); + scene->getRegistry()->addComponent(entity, TransformComponent({0, 1000, 0}, Eigen::Vector3f::Zero(), Eigen::Vector3f(0.1, 0.1, 0.1))); + scene->getRegistry()->addComponent(entity, LightComponent(LightType::PointLight, {1, 1, 1})); + + auto mesh_id_2 = engine.getAssetBank()->getUID(AssetPath::WithTypePrefix("Adventurer")); + + auto entity2 = scene->createEntity(); + scene->getRegistry()->addComponent( + entity2, TransformComponent(Eigen::Vector3f::Zero(), Eigen::Vector3f(0, 0, 0), Eigen::Vector3f::Constant(1))); + scene->getRegistry()->addComponent(entity2, RenderComponent(mesh_id_2)); + scene->getRegistry()->addComponent(entity2, AnimationComponent{.currentAnimation = "CharacterArmature|Walk", .loop = true}); + + auto camera = std::make_shared(60.0, 16.0 / 9.0, 0.01, 10000.0); + camera->backward(5); + camera->up(5); + camera->pitch(-30); + scene->getRegistry()->getSystem()->setCamera(camera); + + int i = 0; + while (!window->shouldClose()) { + window->pollEvents(); + + engine.step(); + + scene->getRegistry()->getComponent(entity2)->rotation().y() += 0.1f; + + //Render system duty + int display_w, display_h; + window->getFramebufferSize(&display_w, &display_h); + engine.getApi()->setViewport(0, 0, display_w, display_h); + window->swapBuffers(); + i++; + } + + return 0; } \ No newline at end of file diff --git a/includes/ImGUI/imgui_impl_opengl3.cpp b/includes/ImGUI/imgui_impl_opengl3.cpp index 6aa49ea3..c4963dd4 100644 --- a/includes/ImGUI/imgui_impl_opengl3.cpp +++ b/includes/ImGUI/imgui_impl_opengl3.cpp @@ -96,7 +96,7 @@ // 3.0 130 "#version 130" // 3.1 140 "#version 140" // 3.2 150 "#version 150" -// 3.3 330 "#version 330 core" +// 3.3 330 "#version 420 core" // 4.0 400 "#version 400 core" // 4.1 410 "#version 410 core" // 4.2 420 "#version 410 core"