diff options
author | David Thompson <dthompson2@worcester.edu> | 2019-10-24 08:04:43 -0400 |
---|---|---|
committer | David Thompson <dthompson2@worcester.edu> | 2019-10-24 08:04:43 -0400 |
commit | b43c4058c9a968aa4c0625711ce27ad0187ddce2 (patch) | |
tree | 77dd25f8ce0b2546ba80511b460a8b75f79e04e0 | |
parent | c55914d815d8828c15f11c4be4364614ca83cee8 (diff) |
render: Restructure 3D modules and add basic support for OBJ models.
-rw-r--r-- | Makefile.am | 5 | ||||
-rw-r--r-- | chickadee/render/asset.scm | 493 | ||||
-rw-r--r-- | chickadee/render/model.scm | 911 | ||||
-rw-r--r-- | chickadee/render/pbr.scm | 130 | ||||
-rw-r--r-- | chickadee/render/phong.scm | 160 | ||||
-rw-r--r-- | chickadee/render/scene.scm | 252 | ||||
-rw-r--r-- | data/shaders/pbr/pbr-frag.glsl | 10 | ||||
-rw-r--r-- | data/shaders/pbr/pbr-vert.glsl | 11 | ||||
-rw-r--r-- | examples/model.scm | 73 | ||||
-rw-r--r-- | examples/models/suzanne.obj | 2580 |
10 files changed, 3857 insertions, 768 deletions
diff --git a/Makefile.am b/Makefile.am index 7754081..171a4ce 100644 --- a/Makefile.am +++ b/Makefile.am @@ -68,9 +68,10 @@ SOURCES = \ chickadee/render/sprite.scm \ chickadee/render/font.scm \ chickadee/render/tiled.scm \ - chickadee/render/scene.scm \ - chickadee/render/asset.scm \ chickadee/render/particles.scm \ + chickadee/render/phong.scm \ + chickadee/render/pbr.scm \ + chickadee/render/model.scm \ chickadee/render.scm \ chickadee/scripting/agenda.scm \ chickadee/scripting/script.scm \ diff --git a/chickadee/render/asset.scm b/chickadee/render/asset.scm deleted file mode 100644 index 44e7afc..0000000 --- a/chickadee/render/asset.scm +++ /dev/null @@ -1,493 +0,0 @@ -;;; Chickadee Game Toolkit -;;; Copyright © 2017 David Thompson <davet@gnu.org> -;;; -;;; Chickadee is free software: you can redistribute it and/or modify -;;; it under the terms of the GNU General Public License as published -;;; by the Free Software Foundation, either version 3 of the License, -;;; or (at your option) any later version. -;;; -;;; Chickadee is distributed in the hope that it will be useful, but -;;; WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;;; General Public License for more details. -;;; -;;; You should have received a copy of the GNU General Public License -;;; along with this program. If not, see -;;; <http://www.gnu.org/licenses/>. - -;;; Commentary: -;; -;; Implementation of the glTF 2.0 specification -;; -;;; Code: - -(define-module (chickadee render asset) - #:use-module (chickadee json) - #:use-module (chickadee math matrix) - #:use-module (chickadee math vector) - #:use-module (chickadee render buffer) - #:use-module (chickadee render color) - #:use-module (chickadee render scene) - #:use-module (chickadee render shader) - #:use-module (chickadee render texture) - #:use-module (ice-9 format) - #:use-module (ice-9 match) - #:use-module (rnrs base) - #:use-module (rnrs bytevectors) - #:use-module (rnrs io ports) - #:use-module (srfi srfi-9) - #:use-module (srfi srfi-9 gnu) - #:use-module ((srfi srfi-43) #:select (vector-every)) - #:export (load-asset - asset? - asset-copyright - asset-generator - asset-scenes - asset-default-scene - draw-asset)) - -(define-record-type <asset> - (make-asset copyright generator scenes default-scene) - asset? - (copyright asset-copyright) - (generator asset-generator) - (scenes asset-scenes) - (default-scene asset-default-scene)) - -(define (display-asset asset port) - (format port "#<asset generator: ~s scene: ~s>" - (asset-generator asset) - (scene-name (asset-default-scene asset)))) - -(set-record-type-printer! <asset> display-asset) - -(define (read-gltf port file) - (define (object-ref obj key) - (let ((value (assoc-ref obj key))) - (unless (pair? value) - (error "expected object for key" key value)) - value)) - (define (object-ref/optional obj key) - (let ((value (assoc-ref obj key))) - (unless (or (not value) (pair? value)) - (error "expected object for optional key" key value)) - value)) - (define (array-ref obj key) - (let ((value (assoc-ref obj key))) - (unless (vector? value) - (error "expected array for key" key value)) - value)) - (define (array-ref/optional obj key) - (let ((value (assoc-ref obj key))) - (unless (or (not value) (vector? value)) - (error "expected array for optional key" key value)) - value)) - (define (string-ref obj key) - (let ((value (assoc-ref obj key))) - (unless (string? value) - (error "expected string for key" key value)) - value)) - (define (string-ref/optional obj key) - (let ((value (assoc-ref obj key))) - (unless (or (not value) (string? value)) - (error "expected string for optional key" key value)) - value)) - (define (number-ref obj key) - (let ((value (assoc-ref obj key))) - (unless (number? value) - (error "expected number for key" key value)) - value)) - (define (number-ref/optional obj key) - (let ((value (assoc-ref obj key))) - (unless (or (not value) (number? value)) - (error "expected number for key" key value)) - value)) - (define (boolean-ref/optional obj key) - (let ((value (assoc-ref obj key))) - (unless (boolean? value) - (error "expected boolean for key" key value)) - value)) - (define (number-array-ref/optional obj key) - (let ((value (assoc-ref obj key))) - (unless (or (not value) - (and (vector? value) (vector-every number? value))) - (error "expected numeric array for key" key value)) - value)) - (define (matrix-ref/optional obj key) - (let ((value (assoc-ref obj key))) - (cond - ((not value) #f) - ((and (vector? value) - (= (vector-length value) 16) - (vector-every number? value)) - ;; glTF matrices are in column-major order. - (make-matrix4 (vector-ref value 0) - (vector-ref value 4) - (vector-ref value 8) - (vector-ref value 12) - (vector-ref value 1) - (vector-ref value 5) - (vector-ref value 9) - (vector-ref value 13) - (vector-ref value 2) - (vector-ref value 6) - (vector-ref value 10) - (vector-ref value 14) - (vector-ref value 3) - (vector-ref value 7) - (vector-ref value 11) - (vector-ref value 15))) - (else - (error "expected 4x4 matrix for key" key value))))) - (define (assert-color v) - (if (and (= (vector-length v) 4) - (vector-every (lambda (x) (and (>= x 0.0) (<= x 1.0))) v)) - (make-color (vector-ref v 0) - (vector-ref v 1) - (vector-ref v 2) - (vector-ref v 3)) - (error "not a color vector" v))) - (define scope-file - (let ((gltf-root (dirname - (if (absolute-file-name? file) - file - (string-append (getcwd) "/" file))))) - (lambda (file) - (if (absolute-file-name? file) - file - (string-append gltf-root "/" file))))) - (define (parse-buffer obj) - ;; TODO: support base64 encoded buffer data as uri - ;; TODO: support glb-stored buffers: - ;; https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-stored-buffer - (let* ((uri (string-ref/optional obj "uri")) - (length (number-ref obj "byteLength")) - (name (or (string-ref/optional obj "name") "anonymous")) - (extensions (object-ref/optional obj "extensions")) - (extras (assoc-ref obj "extras")) - (data (if uri - (call-with-input-file (scope-file uri) - (lambda (port) - (get-bytevector-n port length))) - (make-bytevector length)))) - data)) - (define (parse-buffer-view obj buffers) - (let ((name (string-ref/optional obj "name")) - (data (vector-ref buffers (number-ref obj "buffer"))) - (offset (or (number-ref/optional obj "byteOffset") 0)) - (length (number-ref obj "byteLength")) - (stride (number-ref/optional obj "byteStride")) - (target (match (or (number-ref/optional obj "target") 34962) - (34962 'vertex) - (34963 'index))) - (extensions (object-ref/optional obj "extensions")) - (extras (assoc-ref obj "extras"))) - (make-buffer data - #:name name - #:offset offset - #:length length - #:stride stride - #:target target))) - (define (parse-accessor obj buffer-views) - (define (type-length type) - (match type - ('scalar 1) - ('vec2 2) - ('vec3 3) - ('vec4 4) - ('mat2 4) - ('mat3 9) - ('mat4 16))) - (let ((name (or (string-ref/optional obj "name") "anonymous")) - (view (match (number-ref/optional obj "bufferView") - (#f #f) - (n (vector-ref buffer-views n)))) - (offset (or (number-ref/optional obj "byteOffset") 0)) - (component-type (match (number-ref obj "componentType") - (5120 'byte) - (5121 'unsigned-byte) - (5122 'short) - (5123 'unsigned-short) - (5125 'unsigned-int) - (5126 'float))) - (normalized? (boolean-ref/optional obj "normalized")) - (length (number-ref obj "count")) - (type (match (string-ref obj "type") - ("SCALAR" 'scalar) - ("VEC2" 'vec2) - ("VEC3" 'vec3) - ("VEC4" 'vec4) - ("MAT2" 'mat2) - ("MAT3" 'mat3) - ("MAT4" 'mat4))) - (max (number-array-ref/optional obj "max")) - (min (number-array-ref/optional obj "min")) - (sparse (object-ref/optional obj "sparse")) - (extensions (object-ref/optional obj "extensions")) - (extras (assoc-ref obj "extras"))) - (unless (>= length 1) - (error "count must be greater than 0" length)) - (when (and (vector? max) - (not (= (vector-length max) (type-length type)))) - (error "not enough elements for max" max type)) - (when (and (vector? min) - (not (= (vector-length min) (type-length type)))) - (error "not enough elements for min" min type)) - (make-buffer-view #:name name - #:buffer view - #:offset offset - #:component-type component-type - #:normalized? normalized? - #:length length - #:type type - #:max max - #:min min - #:sparse sparse))) - (define (texture-filter n) - (match n - (9728 'nearest) - ((or #f 9729) 'linear) - ;; TODO: Support mip-mapping - ;; (9984 'nearest-mipmap-nearest) - ;; (9985 'linear-mipmap-nearest) - ;; (9986 'nearest-mipmap-linear) - ;; (9987 'linear-mipmap-linear) - (_ 'linear))) - (define (texture-wrap n) - (match n - (10496 'clamp) - ((or #f 10497) 'repeat) - (33069 'clamp-to-border) - (33071 'clamp-to-edge))) - (define (parse-texture obj images samplers) - (let ((image (vector-ref images (number-ref obj "source"))) - (sampler - (vector-ref samplers (or (number-ref/optional obj "sampler") 0)))) - (load-image (scope-file (string-ref image "uri")) - #:min-filter (texture-filter - (number-ref/optional sampler "minFilter")) - #:mag-filter (texture-filter - (number-ref/optional sampler "magFilter")) - #:wrap-s (texture-wrap (number-ref/optional sampler "wrapS")) - #:wrap-t (texture-wrap (number-ref/optional sampler "wrapT"))))) - (define (parse-material obj textures) - (let* ((name (or (string-ref/optional obj "name") "anonymous")) - (pbrmr (or (object-ref/optional obj "pbrMetallicRoughness") '())) - (base-color-factor - (let ((v (or (number-array-ref/optional pbrmr "baseColorFactor") - #(1.0 1.0 1.0 1.0)))) - (vec3 (vector-ref v 0) (vector-ref v 1) (vector-ref v 2)))) - (base-color-texture - (match (object-ref/optional pbrmr "baseColorTexture") - (#f null-texture) - (obj - (vector-ref textures (number-ref obj "index"))))) - (metallic-factor - (or (number-ref/optional pbrmr "metallicFactor") - 1.0)) - (roughness-factor - (or (number-ref/optional pbrmr "roughnessFactor") - 1.0)) - (metallic-roughness-texture - (match (object-ref/optional pbrmr "metallicRoughnessTexture") - (#f null-texture) - (obj - (vector-ref textures (number-ref obj "index"))))) - (normal-factor - (let ((v (or (array-ref/optional obj "normalFactor") - #(1.0 1.0 1.0)))) - (vec3 (vector-ref v 0) (vector-ref v 1) (vector-ref v 2)))) - (normal-texture - (match (object-ref/optional obj "normalTexture") - (#f null-texture) - (obj (vector-ref textures (number-ref obj "index"))))) - (occlusion-factor - (let ((v (or (array-ref/optional obj "occlusionFactor") - #(1.0 1.0 1.0)))) - (vec3 (vector-ref v 0) (vector-ref v 1) (vector-ref v 2)))) - (occlusion-texture - (match (object-ref/optional obj "occlusionTexture") - (#f null-texture) - (obj (vector-ref textures (number-ref obj "index"))))) - (emissive-factor - (let ((v (or (array-ref/optional obj "emissiveFactor") - #(1.0 1.0 1.0)))) - (vec3 (vector-ref v 0) (vector-ref v 1) (vector-ref v 2)))) - (emissive-texture - (match (object-ref/optional obj "emissiveTexture") - (#f null-texture) - (obj (vector-ref textures (number-ref obj "index"))))) - (alpha-mode (match (or (string-ref/optional obj "alphaMode") - "BLEND") - ("OPAQUE" 'opaque) - ("MASK" 'mask) - ("BLEND" 'blend))) - (alpha-cutoff (or (number-ref/optional obj "alphaCutoff") 0.5)) - (double-sided? (boolean-ref/optional obj "doubleSided")) - (extensions (object-ref/optional obj "extensions")) - (extras (assoc-ref obj "extras"))) - (make-material #:name name - #:base-color-factor base-color-factor - #:base-color-texture base-color-texture - #:metallic-factor metallic-factor - #:roughness-factor roughness-factor - #:metallic-roughness-texture metallic-roughness-texture - #:normal-factor normal-factor - #:normal-texture normal-texture - #:occlusion-factor occlusion-factor - #:occlusion-texture occlusion-texture - #:emissive-factor emissive-factor - #:emissive-texture emissive-texture - #:alpha-mode alpha-mode - #:alpha-cutoff alpha-cutoff - #:double-sided? double-sided?))) - (define (attribute-name->index name) - (match name - ("POSITION" - (attribute-location - (hash-ref (shader-attributes (pbr-shader)) "position"))) - ("NORMAL" 1) - ("TANGENT" 2) - ("TEXCOORD_0" - (attribute-location - (hash-ref (shader-attributes (pbr-shader)) "texcoord_0"))) - ("TEXCOORD_1" 4) - ("COLOR_0" 5) - ("JOINTS_0" 6) - ("WEIGHTS_0" 7))) - (define (parse-primitive obj materials accessors) - (let ((attributes (map (match-lambda - ((name . n) - (cons (attribute-name->index name) - (vector-ref accessors n)))) - (object-ref obj "attributes"))) - (indices (match (number-ref/optional obj "indices") - (#f #f) - (n (vector-ref accessors n)))) - ;; TODO: Set a default material when none is given. - (material (match (number-ref/optional obj "material") - (#f #f) - (n (vector-ref materials n)))) - (mode (match (or (number-ref/optional obj "mode") 4) - (0 'points) - (1 'lines) - (2 'line-loop) - (3 'line-strip) - (4 'triangles) - (5 'triangle-strip) - (6 'triangle-fan))) - ;; TODO: Support morph targets. - (targets #f)) - (make-primitive #:vertex-array - (make-vertex-array #:indices indices - #:attributes attributes - #:mode mode) - #:material material - #:targets targets))) - (define (parse-mesh obj materials accessors) - (let ((name (or (string-ref/optional obj "name") "anonymous")) - (primitives - (map (lambda (obj) - (parse-primitive obj materials accessors)) - (vector->list (array-ref obj "primitives")))) - (weights (number-array-ref/optional obj "weights"))) - (make-mesh #:name name - #:primitives primitives - #:weights weights))) - (define (parse-node obj parse-child meshes) - ;; TODO: Parse all fields of nodes. - (let ((name (or (string-ref/optional obj "name") "anonymous")) - ;; TODO: Parse camera. - (camera #f) - ;; TODO: Parse skin. - (skin #f) - (matrix (or (matrix-ref/optional obj "matrix") - (make-identity-matrix4))) - (mesh (match (number-ref/optional obj "mesh") - (#f #f) - (n (vector-ref meshes n)))) - ;; TODO: Parse rotation, scale, translation - (rotation #f) - (scale #f) - (translation #f) - ;; TODO: Parse weights. - (weights #f) - (children (map parse-child - (vector->list - (or (array-ref/optional obj "children") - #()))))) - (make-scene-node #:name name - #:children children - #:camera camera - #:skin skin - #:matrix matrix - #:mesh mesh - #:rotation rotation - #:scale scale - #:translation translation - #:weights weights))) - (define (parse-nodes array meshes) - (define nodes (make-vector (vector-length array) #f)) - (define (parse-node* i) - (let ((node (vector-ref nodes i))) - (or node - (let ((node (parse-node (vector-ref array i) - parse-node* - meshes))) - (vector-set! nodes i node) - node)))) - (let loop ((i 0)) - (when (< i (vector-length array)) - (parse-node* i) - (loop (+ i 1)))) - nodes) - (define (parse-scene obj nodes) - (let ((name (or (string-ref/optional obj "name") "anonymous")) - (children - (map (lambda (i) (vector-ref nodes i)) - (vector->list - (or (number-array-ref/optional obj "nodes") - #()))))) - (make-scene #:name name #:nodes children))) - (let* ((tree (read-json port)) - (asset (object-ref tree "asset")) - (version (string-ref asset "version")) - (copyright (string-ref/optional asset "copyright")) - (generator (string-ref/optional asset "generator")) - (minimum-version (string-ref/optional asset "minVersion")) - (extensions (object-ref/optional asset "extensions")) - ;; TODO: Figure out how to parse extras in a user-defined way - (extras (assoc-ref asset "extras")) - (buffers (vector-map parse-buffer - (or (assoc-ref tree "buffers") #()))) - (buffer-views (vector-map (lambda (obj) - (parse-buffer-view obj buffers)) - (or (assoc-ref tree "bufferViews") #()))) - (accessors (vector-map (lambda (obj) - (parse-accessor obj buffer-views)) - (or (assoc-ref tree "accessors") #()))) - (images (or (assoc-ref tree "images") #())) - (samplers (or (assoc-ref tree "samplers") #(()))) - (textures (vector-map (lambda (obj) - (parse-texture obj images samplers)) - (or (assoc-ref tree "textures") #()))) - (materials (vector-map (lambda (obj) - (parse-material obj textures)) - (or (assoc-ref tree "materials") #()))) - (meshes (vector-map (lambda (obj) - (parse-mesh obj materials accessors)) - (or (assoc-ref tree "meshes") #()))) - (nodes (parse-nodes (or (assoc-ref tree "nodes") #()) meshes)) - (scenes (map (lambda (obj) - (parse-scene obj nodes)) - (vector->list - (or (assoc-ref tree "scenes") #())))) - (default-scene (list-ref scenes - (or (number-ref/optional tree "scene") - 0)))) - (unless (string=? version "2.0") - (error "unsupported glTF version" version)) - (make-asset copyright generator scenes default-scene))) - -(define (load-asset file) - (call-with-input-file file (lambda (port) (read-gltf port file)))) diff --git a/chickadee/render/model.scm b/chickadee/render/model.scm new file mode 100644 index 0000000..1a9356d --- /dev/null +++ b/chickadee/render/model.scm @@ -0,0 +1,911 @@ +;;; Chickadee Game Toolkit +;;; Copyright © 2019 David Thompson <davet@gnu.org> +;;; +;;; Chickadee is free software: you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published +;;; by the Free Software Foundation, either version 3 of the License, +;;; or (at your option) any later version. +;;; +;;; Chickadee is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with this program. If not, see +;;; <http://www.gnu.org/licenses/>. + +;;; Commentary: +;; +;; 3D Model loading and rendering. +;; +;;; Code: + +(define-module (chickadee render model) + #:use-module (chickadee array-list) + #:use-module (chickadee json) + #:use-module (chickadee math matrix) + #:use-module (chickadee math vector) + #:use-module (chickadee render) + #:use-module (chickadee render buffer) + #:use-module (chickadee render color) + #:use-module (chickadee render pbr) + #:use-module (chickadee render phong) + #:use-module (chickadee render shader) + #:use-module (chickadee render texture) + #:use-module (ice-9 format) + #:use-module (ice-9 match) + #:use-module (ice-9 rdelim) + #:use-module (rnrs bytevectors) + #:use-module (rnrs io ports) + #:use-module (srfi srfi-9) + #:use-module ((srfi srfi-43) #:select (vector-every)) + #:export (model? + draw-model + load-obj + load-gltf)) + + +;;; +;;; Rendering State +;;; + +(define-record-type <render-state> + (%make-render-state shader renderer world-matrix view-matrix) + render-state? + (shader render-state-shader) + (renderer render-state-renderer) + (world-matrix render-state-world-matrix) + (view-matrix render-state-view-matrix)) + +(define* (make-render-state #:key shader renderer) + (%make-render-state shader renderer + (make-identity-matrix4) + (make-identity-matrix4))) + +(define (render-state-reset! state) + (matrix4-identity! (render-state-world-matrix state)) + (matrix4-identity! (render-state-view-matrix state))) + +(define (render-state-world-matrix-mult! state matrix) + (let ((world (render-state-world-matrix state))) + (matrix4-mult! world world matrix))) + +(define (render-state-view-matrix-mult! state matrix) + (let ((view (render-state-view-matrix state))) + (matrix4-mult! view view matrix))) + + +;;; +;;; Primitives +;;; + +;; A piece of a mesh. Represents a single draw call. +(define-record-type <primitive> + (make-primitive name vertex-array material) + primitive? + (name primitive-name) + (vertex-array primitive-vertex-array) + (material primitive-material)) + +(define (draw-primitive/phong primitive state) + (gpu-apply/phong (render-state-shader state) + (primitive-vertex-array primitive) + (primitive-material primitive) + (render-state-world-matrix state) + (render-state-view-matrix state))) + +(define (draw-primitive/pbr primitive state) + (gpu-apply/pbr (render-state-shader state) + (primitive-vertex-array primitive) + (primitive-material primitive) + (render-state-world-matrix state) + (render-state-view-matrix state))) + + +;;; +;;; Meshes +;;; + +;; A complete 3D model composed of many primitives. +(define-record-type <mesh> + (make-mesh name primitives) + mesh? + (name mesh-name) + (primitives mesh-primitives)) + +(define (draw-mesh mesh state) + (let ((render (render-state-renderer state))) + (for-each (lambda (primitive) (render primitive state)) + (mesh-primitives mesh)))) + + +;;; +;;; Scene Node +;;; + +;; A tree of meshes with their own transformation matrices. +(define-record-type <scene-node> + (%make-scene-node name mesh matrix children) + node? + (name scene-node-name) + (mesh scene-node-mesh) + (matrix scene-node-matrix) + (children scene-node-children)) + +(define* (make-scene-node #:key + (name "anonymous") + mesh + (matrix (make-identity-matrix4)) + (children '())) + (%make-scene-node name mesh matrix children)) + +(define (draw-scene-node node state) + ;; TODO: Apply push/pop model matrix stuff. + (for-each (lambda (child) + (draw-scene-node child state)) + (scene-node-children node)) + (let ((mesh (scene-node-mesh node))) + (when mesh + (draw-mesh mesh state)))) + + +;;; +;;; Model +;;; + +;; A collection of scenes and the associated information about *how* +;; to actually render the darn thing. +(define-record-type <model> + (%make-model name scenes default-scene render-state) + model? + (name model-name) + (scenes model-scenes) + (default-scene model-default-scene) + (render-state model-render-state)) + +(define* (make-model #:key name scenes (default-scene (car scenes)) render-state) + (%make-model name scenes default-scene render-state)) + +(define (draw-model model model-matrix view-matrix) + ;; TODO: Support drawing non-default scenes. + (let ((state (model-render-state model))) + (render-state-reset! state) + (render-state-view-matrix-mult! state view-matrix) + (render-state-world-matrix-mult! state model-matrix) + (draw-scene-node (model-default-scene model) state))) + + +;;; +;;; OBJ Format +;;; + +(define (load-obj file-name) + (define (scope-file other-file) + (string-append (dirname file-name) "/" other-file)) + (call-with-input-file file-name + (lambda (port) + (let ((vertices (make-array-list)) + (texcoords (make-array-list)) + (normals (make-array-list)) + (faces (make-array-list)) + (face-map (make-hash-table)) + (face-indices-map (make-hash-table)) + (material-map (make-hash-table))) + (define (load-mtl mtl-file-name) + (call-with-input-file mtl-file-name + (lambda (port) + (let loop ((name #f) + (ambient #f) + (diffuse #f) + (specular #f) + (shininess #f)) + (define (maybe-add-material) + (when name + (hash-set! material-map + name + (make-phong-material + #:name name + #:ambient ambient + #:diffuse diffuse + #:specular specular + #:shininess shininess)))) + (match (read-line port) + ((? eof-object?) + (maybe-add-material)) + (line + (match (delete "" (string-split line char-set:whitespace)) + ((or () ("#" . _)) ; ignore comments and blank lines + (loop name ambient diffuse specular shininess)) + (("Ka" r g b) + (let ((new-ambient (vec3 (string->number r) + (string->number g) + (string->number b)))) + (loop name new-ambient diffuse specular shininess))) + (("Kd" r g b) + (let ((new-diffuse (vec3 (string->number r) + (string->number g) + (string->number b)))) + (loop name ambient new-diffuse specular shininess))) + (("Ks" r g b) + (let ((new-specular (vec3 (string->number r) + (string->number g) + (string->number b)))) + (loop name ambient diffuse new-specular shininess))) + (("Ns" n) + (let ((new-exp (* (string->number n) 1.0))) ; force it to be a float + (loop name ambient diffuse specular new-exp))) + (("newmtl" new-name) + ;; Begin new material + (maybe-add-material) + (loop new-name + (vec3 0.0 0.0 0.0) + (vec3 0.0 0.0 0.0) + (vec3 0.0 0.0 0.0) + 1.0)) + (data + (format (current-error-port) + "warning: ~a:~d: unsupported MTL data: ~s~%" + mtl-file-name + (port-line port) + data) + (loop name ambient diffuse specular shininess))))))))) + (define (parse-error message args) + (apply error (format #f "OBJ parser error @ ~a:~d: ~a" + file-name + (port-line port) + message) + args)) + (define (parse-vertex args) + (array-list-push! vertices + (match args + ((x y z) + (vec3 (string->number x) + (string->number y) + (string->number z))) + ;; TODO: handle w properly + ((x y z w) + (vec3 (string->number x) + (string->number y) + (string->number z))) + (_ + (parse-error "wrong number of vertex arguments" args))))) + (define (parse-texcoord args) + ;; TODO: Handle w properly. + (array-list-push! texcoords + (match args + ((u) + (vec2 (string->number u) 0.0)) + ((u v) + (vec2 (string->number u) (string->number v))) + ((u v w) + (vec2 (string->number u) + (string->number v))) + (_ + (parse-error "wrong number of texcoord arguments" args))))) + (define (parse-normal args) + (array-list-push! normals + (match args + ((i j k) + (vec3 (string->number i) + (string->number j) + (string->number k))) + (_ + (parse-error "wrong number of normal arguments" args))))) + (define (parse-face-index arg) + (- (string->number arg) 1)) + (define (parse-face-element arg) + (match (string-split arg #\/) + ((v) + (list (parse-face-index v) #f #f)) + ((v t) + (list (parse-face-index v) + (parse-face-index t) + #f)) + ((v "" n) + (list (parse-face-index v) + #f + (parse-face-index n))) + ((v t n) + (list (parse-face-index v) + (parse-face-index t) + (parse-face-index n))) + (_ + (parse-error "invalid face syntax" (list arg))))) + (define (indices-for-material material) + (or (hash-ref face-indices-map material) + (let ((new-indices (make-array-list))) + (hash-set! face-indices-map material new-indices) + new-indices))) + (define (parse-face args material) + (match args + ((and (_ _ _ . _) args) + (for-each (lambda (e) + ;; Faces may very well be redundant, so we + ;; deduplicate in order to make the VBOs we + ;; build later as small as possible. + (let ((cached-index (hash-ref face-map e)) + (face-indices (indices-for-material material))) + (if cached-index + (array-list-push! face-indices cached-index) + (let ((i (array-list-size faces))) + (array-list-push! faces (parse-face-element e)) + (array-list-push! face-indices i) + (hash-set! face-map e i))))) + args)) + (_ + (parse-error "wrong number of face arguments" args)))) + ;; Register default material + (hash-set! material-map "default" default-phong-material) + ;; Parse file. + (let loop ((material "default")) + (match (read-line port) + ((? eof-object?) + #f) + (line + (match (delete "" (string-split line char-set:whitespace)) + ((or () ("#" . _)) ; ignore comments and blank lines + (loop material)) + (("f" . args) + (parse-face args material) + (loop material)) + (("g" . _) ; ignore + (loop material)) + (("mtllib" mtl-file-name) + (load-mtl (scope-file mtl-file-name)) + (loop material)) + (("s" . _) ; ignore + (loop material)) + (("usemtl" new-material) + (loop new-material)) + (("v" . args) + (parse-vertex args) + (loop material)) + (("vn" . args) + (parse-normal args) + (loop material)) + (("vt" . args) + (parse-texcoord args) + (loop material)) + (data + (format (current-error-port) + "warning: ~a:~d: unsupported OBJ data: ~s~%" + file-name + (port-line port) + data) + (loop material)))))) + ;; Build a vertex array for all the faces of a single + ;; material. + ;; + ;; XXX: We assume there is normal and texture data. Models + ;; that don't have one or both will still use up as much + ;; memory as if they did. Maybe that's just fine? Dunno. + (define (make-primitive-for-material material) + (let* ((face-indices (indices-for-material material)) + (vertex-count (array-list-size faces)) + (index-count (array-list-size face-indices)) + (stride 8) + (mesh-data (make-f32vector (* vertex-count stride))) + (mesh-indices (make-u32vector index-count)) + (null-texcoord (vec2 0.0 0.0)) + (null-normal (vec3 0.0 0.0 0.0))) + ;; The mesh vertex data is packed like so: + ;; - 3 floats for vertex + ;; - 2 floats for texture coordinate + ;; - 3 floats for normal + ;; - repeat for each face + (let loop ((i 0)) + (when (< i vertex-count) + (let ((offset (* i stride))) + (match (array-list-ref faces i) + ((vert-index tex-index norm-index) + ;; Vertex + (let ((v (array-list-ref vertices vert-index))) + (f32vector-set! mesh-data offset (vec3-x v)) + (f32vector-set! mesh-data (+ offset 1) (vec3-y v)) + (f32vector-set! mesh-data (+ offset 2) (vec3-z v))) + ;; Texture coordinate + (let ((t (if tex-index + (array-list-ref texcoords tex-index) + null-texcoord))) + (f32vector-set! mesh-data (+ offset 3) (vec2-x t)) + (f32vector-set! mesh-data (+ offset 4) (vec2-y t))) + ;; Normal + (let ((n (if norm-index + (array-list-ref normals norm-index) + null-normal))) + (f32vector-set! mesh-data (+ offset 5) (vec3-x n)) + (f32vector-set! mesh-data (+ offset 6) (vec3-y n)) + (f32vector-set! mesh-data (+ offset 7) (vec3-z n)))))) + (loop (+ i 1)))) + ;; Pack indices. + (let loop ((i 0)) + (when (< i index-count) + (u32vector-set! mesh-indices i (array-list-ref face-indices i)) + (loop (+ i 1)))) + ;; Construct vertex array. + ;; TODO: Add names to buffers and views. + (let* ((index-buffer (make-buffer mesh-indices #:target 'index)) + (index-view (make-buffer-view #:type 'scalar + #:component-type 'unsigned-int + #:buffer index-buffer)) + (data-buffer (make-buffer mesh-data #:stride (* stride 4))) + (vertex-view (make-buffer-view #:type 'vec3 + #:component-type 'float + #:buffer data-buffer)) + (texcoord-view (make-buffer-view #:type 'vec2 + #:component-type 'float + #:buffer data-buffer + #:offset 12)) + (normal-view (make-buffer-view #:type 'vec3 + #:component-type 'float + #:buffer data-buffer + #:offset 20))) + (make-primitive material + (make-vertex-array + #:indices index-view + #:attributes `((0 . ,vertex-view) + (1 . ,texcoord-view) + (2 . ,normal-view))) + (or (hash-ref material-map material) + (hash-ref material-map "default")))))) + ;; Construct a mesh by composing primitives. One primitive + ;; per material. + (let* ((model-name (basename file-name)) + (mesh (make-mesh model-name + (hash-fold (lambda (material indices memo) + ;; It's possible that a material has + ;; no data associated with it, so we + ;; drop those. + (if (array-list-empty? indices) + memo + (cons (make-primitive-for-material material) + memo))) + '() + face-indices-map))) + (scene (make-scene-node #:name model-name + #:mesh mesh))) + (make-model #:name model-name + #:scenes (list scene) + #:render-state + (make-render-state #:shader (load-phong-shader) + #:renderer draw-primitive/phong))))))) + + +;;; +;;; glTF 2.0 +;;; + +(define (load-gltf file-name) + (define (object-ref obj key) + (let ((value (assoc-ref obj key))) + (unless (pair? value) + (error "expected object for key" key value)) + value)) + (define (object-ref/optional obj key) + (let ((value (assoc-ref obj key))) + (unless (or (not value) (pair? value)) + (error "expected object for optional key" key value)) + value)) + (define (array-ref obj key) + (let ((value (assoc-ref obj key))) + (unless (vector? value) + (error "expected array for key" key value)) + value)) + (define (array-ref/optional obj key) + (let ((value (assoc-ref obj key))) + (unless (or (not value) (vector? value)) + (error "expected array for optional key" key value)) + value)) + (define (string-ref obj key) + (let ((value (assoc-ref obj key))) + (unless (string? value) + (error "expected string for key" key value)) + value)) + (define (string-ref/optional obj key) + (let ((value (assoc-ref obj key))) + (unless (or (not value) (string? value)) + (error "expected string for optional key" key value)) + value)) + (define (number-ref obj key) + (let ((value (assoc-ref obj key))) + (unless (number? value) + (error "expected number for key" key value)) + value)) + (define (number-ref/optional obj key) + (let ((value (assoc-ref obj key))) + (unless (or (not value) (number? value)) + (error "expected number for key" key value)) + value)) + (define (boolean-ref/optional obj key) + (let ((value (assoc-ref obj key))) + (unless (boolean? value) + (error "expected boolean for key" key value)) + value)) + (define (number-array-ref/optional obj key) + (let ((value (assoc-ref obj key))) + (unless (or (not value) + (and (vector? value) (vector-every number? value))) + (error "expected numeric array for key" key value)) + value)) + (define (matrix-ref/optional obj key) + (let ((value (assoc-ref obj key))) + (cond + ((not value) #f) + ((and (vector? value) + (= (vector-length value) 16) + (vector-every number? value)) + ;; glTF matrices are in column-major order. + (make-matrix4 (vector-ref value 0) + (vector-ref value 4) + (vector-ref value 8) + (vector-ref value 12) + (vector-ref value 1) + (vector-ref value 5) + (vector-ref value 9) + (vector-ref value 13) + (vector-ref value 2) + (vector-ref value 6) + (vector-ref value 10) + (vector-ref value 14) + (vector-ref value 3) + (vector-ref value 7) + (vector-ref value 11) + (vector-ref value 15))) + (else + (error "expected 4x4 matrix for key" key value))))) + (define (assert-color v) + (if (and (= (vector-length v) 4) + (vector-every (lambda (x) (and (>= x 0.0) (<= x 1.0))) v)) + (make-color (vector-ref v 0) + (vector-ref v 1) + (vector-ref v 2) + (vector-ref v 3)) + (error "not a color vector" v))) + (define scope-file + (let ((gltf-root (dirname + (if (absolute-file-name? file-name) + file-name + (string-append (getcwd) "/" file-name))))) + (lambda (other-file) + (if (absolute-file-name? other-file) + other-file + (string-append gltf-root "/" other-file))))) + (define (parse-buffer obj) + ;; TODO: support base64 encoded buffer data as uri + ;; TODO: support glb-stored buffers: + ;; https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#glb-stored-buffer + (let* ((uri (string-ref/optional obj "uri")) + (length (number-ref obj "byteLength")) + (name (or (string-ref/optional obj "name") "anonymous")) + (extensions (object-ref/optional obj "extensions")) + (extras (assoc-ref obj "extras")) + (data (if uri + (call-with-input-file (scope-file uri) + (lambda (port) + (get-bytevector-n port length))) + (make-bytevector length)))) + data)) + (define (parse-buffer-view obj buffers) + (let ((name (string-ref/optional obj "name")) + (data (vector-ref buffers (number-ref obj "buffer"))) + (offset (or (number-ref/optional obj "byteOffset") 0)) + (length (number-ref obj "byteLength")) + (stride (number-ref/optional obj "byteStride")) + (target (match (or (number-ref/optional obj "target") 34962) + (34962 'vertex) + (34963 'index))) + (extensions (object-ref/optional obj "extensions")) + (extras (assoc-ref obj "extras"))) + (make-buffer data + #:name name + #:offset offset + #:length length + #:stride stride + #:target target))) + (define (parse-accessor obj buffer-views) + (define (type-length type) + (match type + ('scalar 1) + ('vec2 2) + ('vec3 3) + ('vec4 4) + ('mat2 4) + ('mat3 9) + ('mat4 16))) + (let ((name (or (string-ref/optional obj "name") "anonymous")) + (view (match (number-ref/optional obj "bufferView") + (#f #f) + (n (vector-ref buffer-views n)))) + (offset (or (number-ref/optional obj "byteOffset") 0)) + (component-type (match (number-ref obj "componentType") + (5120 'byte) + (5121 'unsigned-byte) + (5122 'short) + (5123 'unsigned-short) + (5125 'unsigned-int) + (5126 'float))) + (normalized? (boolean-ref/optional obj "normalized")) + (length (number-ref obj "count")) + (type (match (string-ref obj "type") + ("SCALAR" 'scalar) + ("VEC2" 'vec2) + ("VEC3" 'vec3) + ("VEC4" 'vec4) + ("MAT2" 'mat2) + ("MAT3" 'mat3) + ("MAT4" 'mat4))) + (max (number-array-ref/optional obj "max")) + (min (number-array-ref/optional obj "min")) + (sparse (object-ref/optional obj "sparse")) + (extensions (object-ref/optional obj "extensions")) + (extras (assoc-ref obj "extras"))) + (unless (>= length 1) + (error "count must be greater than 0" length)) + (when (and (vector? max) + (not (= (vector-length max) (type-length type)))) + (error "not enough elements for max" max type)) + (when (and (vector? min) + (not (= (vector-length min) (type-length type)))) + (error "not enough elements for min" min type)) + (make-buffer-view #:name name + #:buffer view + #:offset offset + #:component-type component-type + #:normalized? normalized? + #:length length + #:type type + #:max max + #:min min + #:sparse sparse))) + (define (texture-filter n) + (match n + (9728 'nearest) + ((or #f 9729) 'linear) + ;; TODO: Support mip-mapping + ;; (9984 'nearest-mipmap-nearest) + ;; (9985 'linear-mipmap-nearest) + ;; (9986 'nearest-mipmap-linear) + ;; (9987 'linear-mipmap-linear) + (_ 'linear))) + (define (texture-wrap n) + (match n + (10496 'clamp) + ((or #f 10497) 'repeat) + (33069 'clamp-to-border) + (33071 'clamp-to-edge))) + (define (parse-texture obj images samplers) + (let ((image (vector-ref images (number-ref obj "source"))) + (sampler + (vector-ref samplers (or (number-ref/optional obj "sampler") 0)))) + (load-image (scope-file (string-ref image "uri")) + #:min-filter (texture-filter + (number-ref/optional sampler "minFilter")) + #:mag-filter (texture-filter + (number-ref/optional sampler "magFilter")) + #:wrap-s (texture-wrap (number-ref/optional sampler "wrapS")) + #:wrap-t (texture-wrap (number-ref/optional sampler "wrapT"))))) + (define (parse-material obj textures) + (let* ((name (or (string-ref/optional obj "name") "anonymous")) + (pbrmr (or (object-ref/optional obj "pbrMetallicRoughness") '())) + (base-color-factor + (let ((v (or (number-array-ref/optional pbrmr "baseColorFactor") + #(1.0 1.0 1.0 1.0)))) + (vec3 (vector-ref v 0) (vector-ref v 1) (vector-ref v 2)))) + (base-color-texture + (match (object-ref/optional pbrmr "baseColorTexture") + (#f null-texture) + (obj + (vector-ref textures (number-ref obj "index"))))) + (metallic-factor + (or (number-ref/optional pbrmr "metallicFactor") + 1.0)) + (roughness-factor + (or (number-ref/optional pbrmr "roughnessFactor") + 1.0)) + (metallic-roughness-texture + (match (object-ref/optional pbrmr "metallicRoughnessTexture") + (#f null-texture) + (obj + (vector-ref textures (number-ref obj "index"))))) + (normal-factor + (let ((v (or (array-ref/optional obj "normalFactor") + #(1.0 1.0 1.0)))) + (vec3 (vector-ref v 0) (vector-ref v 1) (vector-ref v 2)))) + (normal-texture + (match (object-ref/optional obj "normalTexture") + (#f null-texture) + (obj (vector-ref textures (number-ref obj "index"))))) + (occlusion-factor + (let ((v (or (array-ref/optional obj "occlusionFactor") + #(1.0 1.0 1.0)))) + (vec3 (vector-ref v 0) (vector-ref v 1) (vector-ref v 2)))) + (occlusion-texture + (match (object-ref/optional obj "occlusionTexture") + (#f null-texture) + (obj (vector-ref textures (number-ref obj "index"))))) + (emissive-factor + (let ((v (or (array-ref/optional obj "emissiveFactor") + #(1.0 1.0 1.0)))) + (vec3 (vector-ref v 0) (vector-ref v 1) (vector-ref v 2)))) + (emissive-texture + (match (object-ref/optional obj "emissiveTexture") + (#f null-texture) + (obj (vector-ref textures (number-ref obj "index"))))) + (alpha-mode (match (or (string-ref/optional obj "alphaMode") + "BLEND") + ("OPAQUE" 'opaque) + ("MASK" 'mask) + ("BLEND" 'blend))) + (alpha-cutoff (or (number-ref/optional obj "alphaCutoff") 0.5)) + (double-sided? (boolean-ref/optional obj "doubleSided")) + (extensions (object-ref/optional obj "extensions")) + (extras (assoc-ref obj "extras"))) + (make-pbr-material #:name name + #:base-color-factor base-color-factor + #:base-color-texture base-color-texture + #:metallic-factor metallic-factor + #:roughness-factor roughness-factor + #:metallic-roughness-texture metallic-roughness-texture + #:normal-factor normal-factor + #:normal-texture normal-texture + #:occlusion-factor occlusion-factor + #:occlusion-texture occlusion-texture + #:emissive-factor emissive-factor + #:emissive-texture emissive-texture + #:alpha-mode alpha-mode + #:alpha-cutoff alpha-cutoff + #:double-sided? double-sided?))) + (define (attribute-name->index name) + (let ((shader (load-pbr-shader))) + (match name + ("POSITION" + (attribute-location + (hash-ref (shader-attributes shader) "position"))) + ("NORMAL" 1) + ("TANGENT" 2) + ("TEXCOORD_0" + (attribute-location + (hash-ref (shader-attributes shader) "texcoord0"))) + ("TEXCOORD_1" 4) + ("COLOR_0" 5) + ("JOINTS_0" 6) + ("WEIGHTS_0" 7)))) + (define (parse-primitive obj materials accessors) + (let ((attributes (map (match-lambda + ((name . n) + (cons (attribute-name->index name) + (vector-ref accessors n)))) + (object-ref obj "attributes"))) + (indices (match (number-ref/optional obj "indices") + (#f #f) + (n (vector-ref accessors n)))) + ;; TODO: Set a default material when none is given. + (material (match (number-ref/optional obj "material") + (#f #f) + (n (vector-ref materials n)))) + (mode (match (or (number-ref/optional obj "mode") 4) + (0 'points) + (1 'lines) + (2 'line-loop) + (3 'line-strip) + (4 'triangles) + (5 'triangle-strip) + (6 'triangle-fan))) + ;; TODO: Support morph targets. + (targets #f)) + (make-primitive "primitive" + (make-vertex-array #:indices indices + #:attributes attributes + #:mode mode) + material))) + (define (parse-mesh obj materials accessors) + (let ((name (or (string-ref/optional obj "name") "anonymous")) + (primitives + (map (lambda (obj) + (parse-primitive obj materials accessors)) + (vector->list (array-ref obj "primitives")))) + (weights (number-array-ref/optional obj "weights"))) + ;; TODO: Support weights. + (make-mesh name primitives))) + (define (parse-node obj parse-child meshes) + ;; TODO: Parse all fields of nodes. + (let ((name (or (string-ref/optional obj "name") "anonymous")) + ;; TODO: Parse camera. + (camera #f) + ;; TODO: Parse skin. + (skin #f) + (matrix (or (matrix-ref/optional obj "matrix") + (make-identity-matrix4))) + (mesh (match (number-ref/optional obj "mesh") + (#f #f) + (n (vector-ref meshes n)))) + ;; TODO: Parse rotation, scale, translation + (rotation #f) + (scale #f) + (translation #f) + ;; TODO: Parse weights. + (weights #f) + (children (map parse-child + (vector->list + (or (array-ref/optional obj "children") + #()))))) + (make-scene-node #:name name + #:children children + #:matrix matrix + #:mesh mesh))) + (define (parse-nodes array meshes) + (define nodes (make-vector (vector-length array) #f)) + (define (parse-node* i) + (let ((node (vector-ref nodes i))) + (or node + (let ((node (parse-node (vector-ref array i) + parse-node* + meshes))) + (vector-set! nodes i node) + node)))) + (let loop ((i 0)) + (when (< i (vector-length array)) + (parse-node* i) + (loop (+ i 1)))) + nodes) + (define (parse-scene obj nodes) + (let ((name (or (string-ref/optional obj "name") "anonymous")) + (children + (map (lambda (i) (vector-ref nodes i)) + (vector->list + (or (number-array-ref/optional obj "nodes") + #()))))) + (make-scene-node #:name name #:children children))) + (define (vector-map proc v) + (let ((new-v (make-vector (vector-length v)))) + (let loop ((i 0)) + (when (< i (vector-length v)) + (vector-set! new-v i (proc (vector-ref v i))) + (loop (+ i 1)))) + new-v)) + (call-with-input-file file-name + (lambda (port) + (let* ((tree (read-json port)) + (asset (object-ref tree "asset")) + (version (string-ref asset "version")) + (copyright (string-ref/optional asset "copyright")) + (generator (string-ref/optional asset "generator")) + (minimum-version (string-ref/optional asset "minVersion")) + (extensions (object-ref/optional asset "extensions")) + ;; TODO: Figure out how to parse extras in a user-defined way + (extras (assoc-ref asset "extras")) + (buffers (vector-map parse-buffer + (or (assoc-ref tree "buffers") #()))) + (buffer-views (vector-map (lambda (obj) + (parse-buffer-view obj buffers)) + (or (assoc-ref tree "bufferViews") #()))) + (accessors (vector-map (lambda (obj) + (parse-accessor obj buffer-views)) + (or (assoc-ref tree "accessors") #()))) + (images (or (assoc-ref tree "images") #())) + (samplers (or (assoc-ref tree "samplers") #(()))) + (textures (vector-map (lambda (obj) + (parse-texture obj images samplers)) + (or (assoc-ref tree "textures") #()))) + (materials (vector-map (lambda (obj) + (parse-material obj textures)) + (or (assoc-ref tree "materials") #()))) + (meshes (vector-map (lambda (obj) + (parse-mesh obj materials accessors)) + (or (assoc-ref tree "meshes") #()))) + (nodes (parse-nodes (or (assoc-ref tree "nodes") #()) meshes)) + (scenes (map (lambda (obj) + (parse-scene obj nodes)) + (vector->list + (or (assoc-ref tree "scenes") #())))) + (default-scene (list-ref scenes + (or (number-ref/optional tree "scene") + 0)))) + (unless (string=? version "2.0") + (error "unsupported glTF version" version)) + (make-model #:name (basename file-name) + #:scenes (list default-scene) + #:render-state + (make-render-state #:shader (load-pbr-shader) + #:renderer draw-primitive/pbr)))))) diff --git a/chickadee/render/pbr.scm b/chickadee/render/pbr.scm new file mode 100644 index 0000000..2738b77 --- /dev/null +++ b/chickadee/render/pbr.scm @@ -0,0 +1,130 @@ +;;; Chickadee Game Toolkit +;;; Copyright © 2019 David Thompson <davet@gnu.org> +;;; +;;; Chickadee is free software: you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published +;;; by the Free Software Foundation, either version 3 of the License, +;;; or (at your option) any later version. +;;; +;;; Chickadee is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with this program. If not, see +;;; <http://www.gnu.org/licenses/>. + +;;; Commentary: +;; +;; Physically based lighting model. +;; +;;; Code: + +(define-module (chickadee render pbr) + #:use-module (chickadee math vector) + #:use-module (chickadee render) + #:use-module (chickadee render color) + #:use-module (chickadee render shader) + #:use-module (chickadee render texture) + #:use-module (srfi srfi-9) + #:export (make-pbr-material + pbr-material? + pbr-material-name + pbr-material-base-color-factor + pbr-material-base-color-texture + pbr-material-metallic-factor + pbr-material-roughness-factor + pbr-material-metallic-roughness-texture + pbr-material-normal-factor + pbr-material-normal-texture + pbr-material-occlusion-facgor + pbr-material-occlusion-texture + pbr-material-emissive-factor + pbr-material-emissive-texture + pbr-material-alpha-mode + pbr-material-alpha-cutoff + pbr-material-double-sided? + default-pbr-material + load-pbr-shader + gpu-apply/pbr)) + +(define-shader-type <pbr-material> + make-pbr-material + pbr-material? + (local-field name pbr-material-name) + (float-vec3 base-color-factor pbr-material-base-color-factor) + (local-field base-color-texture pbr-material-base-color-texture) + (float metallic-factor pbr-material-metallic-factor) + (float roughness-factor pbr-material-roughness-factor) + (local-field metallic-roughness-texture pbr-material-metallic-roughness-texture) + (float-vec3 normal-factor pbr-material-normal-factor) + (local-field normal-texture pbr-material-normal-texture) + (float-vec3 occlusion-factor pbr-material-occlusion-factor) + (local-field occlusion-texture pbr-material-occlusion-texture) + (float-vec3 emissive-factor pbr-material-emissive-factor) + (local-field emissive-texture pbr-material-emissive-texture) + (local-field alpha-mode pbr-material-alpha-mode) + (float alpha-cutoff pbr-material-alpha-cutoff) + (bool double-sided? pbr-material-double-sided?)) + +(define default-pbr-material + (make-pbr-material #:name "default" + #:base-color-factor #v(1.0 1.0 1.0) + #:base-color-texture null-texture + #:metallic-factor 1.0 + #:roughness-factor 1.0 + #:metallic-roughness-texture null-texture + #:normal-factor #v(1.0 1.0 1.0) + #:normal-texture null-texture + #:occlusion-factor #v(1.0 1.0 1.0) + #:occlusion-texture null-texture + #:emissive-factor #v(1.0 1.0 1.0) + #:emissive-texture null-texture + #:alpha-mode 'opaque + #:alpha-cutoff 0.5 + #:double-sided? #f)) + +;; TODO: Actually implement PBR. For now it's just the minimal amount +;; of code needed to render the base texture of a mesh. +(define pbr-shader + (delay + (strings->shader + " +#version 130 + +in vec3 position; +in vec2 texcoord0; +out vec2 fragTex; +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +void main(void) { + fragTex = texcoord0; + gl_Position = projection * view * model * vec4(position.xyz, 1.0); +} +" + " +#version 130 + +in vec2 fragTex; +uniform vec3 baseColorFactor; +uniform sampler2D baseColorTexture; + +void main (void) { + gl_FragColor = texture2D(baseColorTexture, fragTex) * + vec4(baseColorFactor, 1.0); +} +"))) + +(define (load-pbr-shader) + (force pbr-shader)) + +(define (gpu-apply/pbr shader vertex-array material model-matrix view-matrix) + (with-texture 0 (pbr-material-base-color-texture material) + (gpu-apply shader vertex-array + #:model model-matrix + #:view view-matrix + #:projection (current-projection) + #:base-color-factor (pbr-material-base-color-factor material)))) diff --git a/chickadee/render/phong.scm b/chickadee/render/phong.scm new file mode 100644 index 0000000..07c0eeb --- /dev/null +++ b/chickadee/render/phong.scm @@ -0,0 +1,160 @@ +;;; Chickadee Game Toolkit +;;; Copyright © 2019 David Thompson <davet@gnu.org> +;;; +;;; Chickadee is free software: you can redistribute it and/or modify +;;; it under the terms of the GNU General Public License as published +;;; by the Free Software Foundation, either version 3 of the License, +;;; or (at your option) any later version. +;;; +;;; Chickadee is distributed in the hope that it will be useful, but +;;; WITHOUT ANY WARRANTY; without even the implied warranty of +;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +;;; General Public License for more details. +;;; +;;; You should have received a copy of the GNU General Public License +;;; along with this program. If not, see +;;; <http://www.gnu.org/licenses/>. + +;;; Commentary: +;; +;; Simple forward rendered Phong lighting model. +;; +;;; Code: + +(define-module (chickadee render phong) + #:use-module (chickadee math vector) + #:use-module (chickadee render) + #:use-module (chickadee render color) + #:use-module (chickadee render shader) + #:use-module (srfi srfi-9) + #:export (make-phong-material + phong-material? + phong-material-name + phong-material-ambient + phong-material-diffuse + phong-material-specular + phong-material-specular-exponent + default-phong-material + load-phong-shader + gpu-apply/phong)) + + +;;; +;;; Phong Material +;;; + +(define-shader-type <phong-material> + make-phong-material + phong-material? + (local-field name phong-material-name) + (float-vec3 ambient phong-material-ambient) + (float-vec3 diffuse phong-material-diffuse) + (float-vec3 specular phong-material-specular) + (float shininess phong-material-shininess)) + +(define default-phong-material + (make-phong-material #:name "default" + #:ambient (vec3 0.5 0.5 0.5) + #:diffuse (vec3 0.5 0.5 0.5) + #:specular (vec3 0.5 0.5 0.5) + #:shininess 32.0)) + + +;;; +;;; Lights +;;; + +(define-shader-type <directional-light> + make-directional-light + directional-light? + (float-vec4 color directional-light-color) + (float-vec3 direction directional-light-direction) + (float-vec3 ambient directional-light-ambient) + (float-vec3 diffuse directional-light-diffuse) + (float-vec3 specular directional-light-specular) + (float shininess directional-light-shininess)) + +(define default-directional-light + (make-directional-light #:color white + #:direction (vec3 -1.0 0.0 -1.0) + #:ambient (vec3 0.5 0.5 0.5) + #:diffuse (vec3 0.5 0.5 0.5) + #:specular (vec3 0.5 0.5 0.5) + #:shininess 32.0)) + + +;;; +;;; Phong Shader +;;; + +(define phong-shader + (delay + (strings->shader + " +#version 130 + +in vec3 position; +in vec2 texcoord; +in vec3 normal; + +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + +out vec3 fragNorm; +out vec2 fragTex; + +void main() { + gl_Position = projection * view * model * vec4(position, 1.0); + // TODO: Calculate normal matrix on CPU + fragNorm = normalize(model * vec4(normal, 1.0)).xyz; + fragTex = texcoord; +} +" + " +#version 130 + +struct Material { + vec3 ambient; + vec3 diffuse; + vec3 specular; + float shininess; +}; + +struct DirectionalLight { + vec4 color; + vec3 direction; + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; + +in vec3 fragNorm; +in vec2 fragTex; + +uniform Material material; +uniform DirectionalLight directionalLight; + +void main() { + vec3 lightColor = directionalLight.color.xyz; + vec3 ambientColor = material.ambient * lightColor; + vec3 lightDir = normalize(-directionalLight.direction); + float diffuseFactor = max(dot(lightDir, fragNorm), 0.0); + vec3 diffuseColor = diffuseFactor * material.diffuse * lightColor; + vec3 reflectDir = reflect(-lightDir, fragNorm); + float specularFactor = pow(max(dot(lightDir, reflectDir), 0.0), material.shininess); + vec3 specularColor = specularFactor * material.specular * lightColor; + gl_FragColor = vec4(ambientColor + diffuseColor + specularColor, 1.0); +} +"))) + +(define (load-phong-shader) + (force phong-shader)) + +(define (gpu-apply/phong shader vertex-array material model-matrix view-matrix) + (gpu-apply shader vertex-array + #:model model-matrix + #:view view-matrix + #:projection (current-projection) + #:material material + #:directional-light default-directional-light)) diff --git a/chickadee/render/scene.scm b/chickadee/render/scene.scm deleted file mode 100644 index 818957e..0000000 --- a/chickadee/render/scene.scm +++ /dev/null @@ -1,252 +0,0 @@ -;;; Chickadee Game Toolkit -;;; Copyright © 2017 David Thompson <davet@gnu.org> -;;; -;;; Chickadee is free software: you can redistribute it and/or modify -;;; it under the terms of the GNU General Public License as published -;;; by the Free Software Foundation, either version 3 of the License, -;;; or (at your option) any later version. -;;; -;;; Chickadee is distributed in the hope that it will be useful, but -;;; WITHOUT ANY WARRANTY; without even the implied warranty of -;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;;; General Public License for more details. -;;; -;;; You should have received a copy of the GNU General Public License -;;; along with this program. If not, see -;;; <http://www.gnu.org/licenses/>. - -;;; Commentary: -;; -;; 3D scene graph with physically based rendering. -;; -;;; Code: - -(define-module (chickadee render scene) - #:use-module (chickadee config) - #:use-module (chickadee math matrix) - #:use-module (chickadee math quaternion) - #:use-module (chickadee math vector) - #:use-module (chickadee render) - #:use-module (chickadee render color) - #:use-module (chickadee render buffer) - #:use-module (chickadee render texture) - #:use-module (chickadee render shader) - #:use-module (srfi srfi-9) - #:use-module (srfi srfi-9 gnu) - #:export (make-material - default-material - material? - material-name - material-base-color-factor - material-base-color-texture - material-metallic-factor - material-roughness-factor - material-metallic-roughness-texture - material-normal-factor - material-normal-texture - material-occlusion-facgor - material-occlusion-texture - material-emissive-factor - material-emissive-texture - material-alpha-mode - material-alpha-cutoff - material-double-sided? - pbr-shader - make-primitive - primitive? - primitive-vertex-array - primitive-material - primitive-targets - make-mesh - mesh? - mesh-name - mesh-primitives - mesh-weights - make-scene-node - scene-node? - scene-node-name - scene-node-children - scene-node-camera - scene-node-skin - scene-node-matrix - scene-node-mesh - scene-node-rotation - scene-node-scale - scene-node-translation - scene-node-weights - make-scene - scene? - scene-name - scene-nodes - draw-scene)) - -(define-record-type <material> - (%make-material name base-color-factor base-color-texture - metallic-factor roughness-factor metallic-roughness-texture - normal-factor normal-texture - occlusion-factor occlusion-texture - emissive-texture emissive-factor - alpha-mode alpha-cutoff - double-sided?) - material? - (name material-name) - (base-color-factor material-base-color-factor) - (base-color-texture material-base-color-texture) - (metallic-factor material-metallic-factor) - (roughness-factor material-roughness-factor) - (metallic-roughness-texture material-metallic-roughness-texture) - (normal-factor material-normal-factor) - (normal-texture material-normal-texture) - (occlusion-factor material-occlusion-factor) - (occlusion-texture material-occlusion-texture) - (emissive-factor material-emissive-factor) - (emissive-texture material-emissive-texture) - (alpha-mode material-alpha-mode) - (alpha-cutoff material-alpha-cutoff) - (double-sided? material-double-sided?)) - -(define* (make-material #:key - (name "anonymous") - (base-color-factor #v(1.0 1.0 1.0)) - (base-color-texture null-texture) - (metallic-factor 1.0) - (roughness-factor 1.0) - (metallic-roughness-texture null-texture) - (normal-factor #v(1.0 1.0 1.0)) - (normal-texture null-texture) - (occlusion-factor #v(1.0 1.0 1.0)) - (occlusion-texture null-texture) - (emissive-factor #v(1.0 1.0 1.0)) - (emissive-texture null-texture) - (alpha-mode 'opaque) - (alpha-cutoff 0.5) - double-sided?) - (%make-material name base-color-factor base-color-texture - metallic-factor roughness-factor metallic-roughness-texture - normal-factor normal-texture - occlusion-factor occlusion-texture - emissive-texture emissive-factor - alpha-mode alpha-cutoff double-sided?)) - -(define default-material (make-material)) - -(define pbr-shader - (let ((shader - (delay - (load-shader (scope-datadir "shaders/pbr/pbr-vert.glsl") - (scope-datadir "shaders/pbr/pbr-frag.glsl"))))) - (lambda () - (force shader)))) - -(define-record-type <primitive> - (%make-primitive vertex-array material targets matrix) - primitive? - (vertex-array primitive-vertex-array) - (material primitive-material) - (targets primitive-targets) - (matrix primitive-matrix)) - -(define (display-primitive primitive port) - (format port "#<primitive material: ~s targets: ~s>" - (primitive-material primitive) - (primitive-targets primitive))) - -(set-record-type-printer! <primitive> display-primitive) - -(define* (make-primitive #:key - vertex-array - (material default-material) - targets) - (%make-primitive vertex-array material targets (make-identity-matrix4))) - -(define-record-type <mesh> - (%make-mesh name primitives weights) - mesh? - (name mesh-name) - (primitives mesh-primitives) - (weights mesh-weights)) - -(define (display-mesh mesh port) - (format port "#<mesh name: ~s>" (mesh-name mesh))) - -(set-record-type-printer! <mesh> display-mesh) - -(define* (make-mesh #:key - (name "anonymous") - primitives - weights) - (%make-mesh name primitives weights)) - -(define-record-type <scene-node> - (%make-scene-node name children camera skin matrix world-matrix - mesh rotation scale translation weights) - node? - (name scene-node-name) - (children scene-node-children) - (camera scene-node-camera) - (skin scene-node-skin) - (matrix scene-node-matrix) - (world-matrix scene-node-world-matrix) - (mesh scene-node-mesh) - (rotation scene-node-rotation) - (scale scene-node-scale) - (translation scene-node-translation) - (weights scene-node-weights)) - -(define (display-scene-node scene port) - (format port "#<scene-node name: ~s>" (scene-node-name scene))) - -(set-record-type-printer! <scene-node> display-scene-node) - -(define* (make-scene-node #:key - (name "anonymous") - (children #()) - camera - skin - (matrix (make-identity-matrix4)) - mesh - (rotation (quaternion 0.0 0.0 0.0 1.0)) - (scale (vec3 1.0 1.0 1.0)) - (translation (vec3 0.0 0.0 0.0)) - weights) - (%make-scene-node name children camera skin matrix (make-identity-matrix4) - mesh rotation scale translation weights)) - -(define-record-type <scene> - (%make-scene name nodes) - scene? - (name scene-name) - (nodes scene-nodes)) - -(define* (make-scene #:key (name "anonymous") (nodes '())) - (%make-scene name nodes)) - -(define (draw-primitive primitive matrix) - ;; TODO: Actually use physically based rendering. - (let ((mvp (primitive-matrix primitive)) - (material (primitive-material primitive))) - (matrix4-mult! mvp matrix (current-projection)) - (with-texture 0 (material-base-color-texture material) - (gpu-apply (pbr-shader) - (primitive-vertex-array primitive) - #:mvp mvp - #:base_color_factor (material-base-color-factor material))))) - -(define (draw-mesh mesh matrix) - (for-each (lambda (primitive) - (draw-primitive primitive matrix)) - (mesh-primitives mesh))) - -(define (draw-scene-node node matrix) - (let ((world-matrix (scene-node-world-matrix node))) - (matrix4-mult! world-matrix matrix (scene-node-matrix node)) - (when (scene-node-mesh node) - (draw-mesh (scene-node-mesh node) world-matrix)) - (for-each (lambda (node) - (draw-scene-node node world-matrix)) - (scene-node-children node)))) - -(define (draw-scene scene) - (for-each (lambda (scene) - (draw-scene-node scene (scene-node-world-matrix scene))) - (scene-nodes scene))) diff --git a/data/shaders/pbr/pbr-frag.glsl b/data/shaders/pbr/pbr-frag.glsl deleted file mode 100644 index 1552880..0000000 --- a/data/shaders/pbr/pbr-frag.glsl +++ /dev/null @@ -1,10 +0,0 @@ -#version 130 - -in vec2 frag_tex; -uniform vec3 base_color_factor; -uniform sampler2D base_color_texture; - -void main (void) { - gl_FragColor = texture2D(base_color_texture, frag_tex) * - vec4(base_color_factor, 1.0); -} diff --git a/data/shaders/pbr/pbr-vert.glsl b/data/shaders/pbr/pbr-vert.glsl deleted file mode 100644 index b6fefef..0000000 --- a/data/shaders/pbr/pbr-vert.glsl +++ /dev/null @@ -1,11 +0,0 @@ -#version 130 - -in vec3 position; -in vec2 texcoord_0; -out vec2 frag_tex; -uniform mat4 mvp; - -void main(void) { - frag_tex = texcoord_0; - gl_Position = mvp * vec4(position.xyz, 1.0); -} diff --git a/examples/model.scm b/examples/model.scm new file mode 100644 index 0000000..cc73918 --- /dev/null +++ b/examples/model.scm @@ -0,0 +1,73 @@ +(use-modules (chickadee) + (chickadee math) + (chickadee math matrix) + (chickadee math vector) + (chickadee render) + (chickadee render model) + (chickadee render font) + (ice-9 format)) + +(define projection (perspective-projection (/ pi 3) (/ 4.0 3.0) 0.1 500.0)) +(define rotation (make-identity-matrix4)) +(define translation (make-identity-matrix4)) +(define view-matrix (make-identity-matrix4)) +(define model-matrix (make-identity-matrix4)) +(define position (vec3 0.0 0.0 0.0)) +(define velocity (vec3 0.0 0.0 0.0)) +(define model #f) +(define text-position #v(4.0 464.0)) +(define text "") +(define y-rotation 0.0) + +(define (reset-position) + (set-vec3! position 0.0 0.0 -4.0)) + +(define (load) + (set! model (load-obj "models/suzanne.obj")) + (reset-position)) + +(define (draw alpha) + (with-projection projection + (with-depth-test #t + (draw-model model model-matrix view-matrix))) + (draw-text text text-position)) + +(define (update dt) + ;; Update camera position + (set-vec3! velocity + (+ (if (key-pressed? 'd) -1.0 0.0) + (if (key-pressed? 'a) 1.0 0.0)) + 0.0 + (+ (if (key-pressed? 's) -1.0 0.0) + (if (key-pressed? 'w) 1.0 0.0))) + (vec3-normalize! velocity) + (vec3-mult! velocity 0.1) + (vec3-add! position velocity) + (set! text (format #f "(~6,2f, ~6,2f, ~6,2f)" + (vec3-x position) + (vec3-y position) + (vec3-z position))) + + ;; Compute new view matrix + (matrix4-rotate-y! rotation theta) + (matrix4-translate! translation position) + (matrix4-identity! view-matrix) + (matrix4-mult! view-matrix view-matrix rotation) + (matrix4-mult! view-matrix view-matrix translation) + + ;; Rotate the model about the y-axis + (set! y-rotation (+ y-rotation 0.03)) + (matrix4-rotate-y! model-matrix y-rotation)) + +(define (key-press key scancode modifiers repeat?) + (cond + ((eq? key 'q) + (abort-game)) + ((eq? key 'r) + (reset-position)))) + +(run-game #:window-title "3D!" + #:load load + #:draw draw + #:update update + #:key-press key-press) diff --git a/examples/models/suzanne.obj b/examples/models/suzanne.obj new file mode 100644 index 0000000..7d657dc --- /dev/null +++ b/examples/models/suzanne.obj @@ -0,0 +1,2580 @@ +# Blender3D v249 OBJ File: suzanne.blend +# www.blender3d.org +v 0.437500 0.164063 0.765625 +v -0.437500 0.164063 0.765625 +v 0.500000 0.093750 0.687500 +v -0.500000 0.093750 0.687500 +v 0.546875 0.054688 0.578125 +v -0.546875 0.054688 0.578125 +v 0.351563 -0.023438 0.617188 +v -0.351563 -0.023438 0.617188 +v 0.351563 0.031250 0.718750 +v -0.351563 0.031250 0.718750 +v 0.351563 0.132813 0.781250 +v -0.351563 0.132813 0.781250 +v 0.273438 0.164063 0.796875 +v -0.273438 0.164063 0.796875 +v 0.203125 0.093750 0.742188 +v -0.203125 0.093750 0.742188 +v 0.156250 0.054688 0.648438 +v -0.156250 0.054688 0.648438 +v 0.078125 0.242188 0.656250 +v -0.078125 0.242188 0.656250 +v 0.140625 0.242188 0.742188 +v -0.140625 0.242188 0.742188 +v 0.242188 0.242188 0.796875 +v -0.242188 0.242188 0.796875 +v 0.273438 0.328125 0.796875 +v -0.273438 0.328125 0.796875 +v 0.203125 0.390625 0.742188 +v -0.203125 0.390625 0.742188 +v 0.156250 0.437500 0.648438 +v -0.156250 0.437500 0.648438 +v 0.351563 0.515625 0.617188 +v -0.351563 0.515625 0.617188 +v 0.351563 0.453125 0.718750 +v -0.351563 0.453125 0.718750 +v 0.351563 0.359375 0.781250 +v -0.351563 0.359375 0.781250 +v 0.437500 0.328125 0.765625 +v -0.437500 0.328125 0.765625 +v 0.500000 0.390625 0.687500 +v -0.500000 0.390625 0.687500 +v 0.546875 0.437500 0.578125 +v -0.546875 0.437500 0.578125 +v 0.625000 0.242188 0.562500 +v -0.625000 0.242188 0.562500 +v 0.562500 0.242188 0.671875 +v -0.562500 0.242188 0.671875 +v 0.468750 0.242188 0.757813 +v -0.468750 0.242188 0.757813 +v 0.476563 0.242188 0.773438 +v -0.476563 0.242188 0.773438 +v 0.445313 0.335938 0.781250 +v -0.445313 0.335938 0.781250 +v 0.351563 0.375000 0.804688 +v -0.351563 0.375000 0.804688 +v 0.265625 0.335938 0.820313 +v -0.265625 0.335938 0.820313 +v 0.226563 0.242188 0.820313 +v -0.226563 0.242188 0.820313 +v 0.265625 0.156250 0.820313 +v -0.265625 0.156250 0.820313 +v 0.351563 0.242188 0.828125 +v -0.351563 0.242188 0.828125 +v 0.351563 0.117188 0.804688 +v -0.351563 0.117188 0.804688 +v 0.445313 0.156250 0.781250 +v -0.445313 0.156250 0.781250 +v 0.000000 0.429688 0.742188 +v 0.000000 0.351563 0.820313 +v 0.000000 -0.679688 0.734375 +v 0.000000 -0.320313 0.781250 +v 0.000000 -0.187500 0.796875 +v 0.000000 -0.773438 0.718750 +v 0.000000 0.406250 0.601563 +v 0.000000 0.570313 0.570313 +v 0.000000 0.898438 -0.546875 +v 0.000000 0.562500 -0.851563 +v 0.000000 0.070313 -0.828125 +v 0.000000 -0.382813 -0.351563 +v 0.203125 -0.187500 0.562500 +v -0.203125 -0.187500 0.562500 +v 0.312500 -0.437500 0.570313 +v -0.312500 -0.437500 0.570313 +v 0.351563 -0.695313 0.570313 +v -0.351563 -0.695313 0.570313 +v 0.367188 -0.890625 0.531250 +v -0.367188 -0.890625 0.531250 +v 0.328125 -0.945313 0.523438 +v -0.328125 -0.945313 0.523438 +v 0.179688 -0.968750 0.554688 +v -0.179688 -0.968750 0.554688 +v 0.000000 -0.984375 0.578125 +v 0.437500 -0.140625 0.531250 +v -0.437500 -0.140625 0.531250 +v 0.632813 -0.039063 0.539063 +v -0.632813 -0.039063 0.539063 +v 0.828125 0.148438 0.445313 +v -0.828125 0.148438 0.445313 +v 0.859375 0.429688 0.593750 +v -0.859375 0.429688 0.593750 +v 0.710938 0.484375 0.625000 +v -0.710938 0.484375 0.625000 +v 0.492188 0.601563 0.687500 +v -0.492188 0.601563 0.687500 +v 0.320313 0.757813 0.734375 +v -0.320313 0.757813 0.734375 +v 0.156250 0.718750 0.757813 +v -0.156250 0.718750 0.757813 +v 0.062500 0.492188 0.750000 +v -0.062500 0.492188 0.750000 +v 0.164063 0.414063 0.773438 +v -0.164063 0.414063 0.773438 +v 0.125000 0.304688 0.765625 +v -0.125000 0.304688 0.765625 +v 0.203125 0.093750 0.742188 +v -0.203125 0.093750 0.742188 +v 0.375000 0.015625 0.703125 +v -0.375000 0.015625 0.703125 +v 0.492188 0.062500 0.671875 +v -0.492188 0.062500 0.671875 +v 0.625000 0.187500 0.648438 +v -0.625000 0.187500 0.648438 +v 0.640625 0.296875 0.648438 +v -0.640625 0.296875 0.648438 +v 0.601563 0.375000 0.664063 +v -0.601563 0.375000 0.664063 +v 0.429688 0.437500 0.718750 +v -0.429688 0.437500 0.718750 +v 0.250000 0.468750 0.757813 +v -0.250000 0.468750 0.757813 +v 0.000000 -0.765625 0.734375 +v 0.109375 -0.718750 0.734375 +v -0.109375 -0.718750 0.734375 +v 0.117188 -0.835938 0.710938 +v -0.117188 -0.835938 0.710938 +v 0.062500 -0.882813 0.695313 +v -0.062500 -0.882813 0.695313 +v 0.000000 -0.890625 0.687500 +v 0.000000 -0.195313 0.750000 +v 0.000000 -0.140625 0.742188 +v 0.101563 -0.148438 0.742188 +v -0.101563 -0.148438 0.742188 +v 0.125000 -0.226563 0.750000 +v -0.125000 -0.226563 0.750000 +v 0.085938 -0.289063 0.742188 +v -0.085938 -0.289063 0.742188 +v 0.398438 -0.046875 0.671875 +v -0.398438 -0.046875 0.671875 +v 0.617188 0.054688 0.625000 +v -0.617188 0.054688 0.625000 +v 0.726563 0.203125 0.601563 +v -0.726563 0.203125 0.601563 +v 0.742188 0.375000 0.656250 +v -0.742188 0.375000 0.656250 +v 0.687500 0.414063 0.726563 +v -0.687500 0.414063 0.726563 +v 0.437500 0.546875 0.796875 +v -0.437500 0.546875 0.796875 +v 0.312500 0.640625 0.835938 +v -0.312500 0.640625 0.835938 +v 0.203125 0.617188 0.851563 +v -0.203125 0.617188 0.851563 +v 0.101563 0.429688 0.843750 +v -0.101563 0.429688 0.843750 +v 0.125000 -0.101563 0.812500 +v -0.125000 -0.101563 0.812500 +v 0.210938 -0.445313 0.710938 +v -0.210938 -0.445313 0.710938 +v 0.250000 -0.703125 0.687500 +v -0.250000 -0.703125 0.687500 +v 0.265625 -0.820313 0.664063 +v -0.265625 -0.820313 0.664063 +v 0.234375 -0.914063 0.632813 +v -0.234375 -0.914063 0.632813 +v 0.164063 -0.929688 0.632813 +v -0.164063 -0.929688 0.632813 +v 0.000000 -0.945313 0.640625 +v 0.000000 0.046875 0.726563 +v 0.000000 0.210938 0.765625 +v 0.328125 0.476563 0.742188 +v -0.328125 0.476563 0.742188 +v 0.164063 0.140625 0.750000 +v -0.164063 0.140625 0.750000 +v 0.132813 0.210938 0.757813 +v -0.132813 0.210938 0.757813 +v 0.117188 -0.687500 0.734375 +v -0.117188 -0.687500 0.734375 +v 0.078125 -0.445313 0.750000 +v -0.078125 -0.445313 0.750000 +v 0.000000 -0.445313 0.750000 +v 0.000000 -0.328125 0.742188 +v 0.093750 -0.273438 0.781250 +v -0.093750 -0.273438 0.781250 +v 0.132813 -0.226563 0.796875 +v -0.132813 -0.226563 0.796875 +v 0.109375 -0.132813 0.781250 +v -0.109375 -0.132813 0.781250 +v 0.039063 -0.125000 0.781250 +v -0.039063 -0.125000 0.781250 +v 0.000000 -0.203125 0.828125 +v 0.046875 -0.148438 0.812500 +v -0.046875 -0.148438 0.812500 +v 0.093750 -0.156250 0.812500 +v -0.093750 -0.156250 0.812500 +v 0.109375 -0.226563 0.828125 +v -0.109375 -0.226563 0.828125 +v 0.078125 -0.250000 0.804688 +v -0.078125 -0.250000 0.804688 +v 0.000000 -0.289063 0.804688 +v 0.257813 -0.312500 0.554688 +v -0.257813 -0.312500 0.554688 +v 0.164063 -0.242188 0.710938 +v -0.164063 -0.242188 0.710938 +v 0.179688 -0.312500 0.710938 +v -0.179688 -0.312500 0.710938 +v 0.234375 -0.250000 0.554688 +v -0.234375 -0.250000 0.554688 +v 0.000000 -0.875000 0.687500 +v 0.046875 -0.867188 0.687500 +v -0.046875 -0.867188 0.687500 +v 0.093750 -0.820313 0.710938 +v -0.093750 -0.820313 0.710938 +v 0.093750 -0.742188 0.726563 +v -0.093750 -0.742188 0.726563 +v 0.000000 -0.781250 0.656250 +v 0.093750 -0.750000 0.664063 +v -0.093750 -0.750000 0.664063 +v 0.093750 -0.812500 0.640625 +v -0.093750 -0.812500 0.640625 +v 0.046875 -0.851563 0.632813 +v -0.046875 -0.851563 0.632813 +v 0.000000 -0.859375 0.632813 +v 0.171875 0.218750 0.781250 +v -0.171875 0.218750 0.781250 +v 0.187500 0.156250 0.773438 +v -0.187500 0.156250 0.773438 +v 0.335938 0.429688 0.757813 +v -0.335938 0.429688 0.757813 +v 0.273438 0.421875 0.773438 +v -0.273438 0.421875 0.773438 +v 0.421875 0.398438 0.773438 +v -0.421875 0.398438 0.773438 +v 0.562500 0.351563 0.695313 +v -0.562500 0.351563 0.695313 +v 0.585938 0.289063 0.687500 +v -0.585938 0.289063 0.687500 +v 0.578125 0.195313 0.679688 +v -0.578125 0.195313 0.679688 +v 0.476563 0.101563 0.718750 +v -0.476563 0.101563 0.718750 +v 0.375000 0.062500 0.742188 +v -0.375000 0.062500 0.742188 +v 0.226563 0.109375 0.781250 +v -0.226563 0.109375 0.781250 +v 0.179688 0.296875 0.781250 +v -0.179688 0.296875 0.781250 +v 0.210938 0.375000 0.781250 +v -0.210938 0.375000 0.781250 +v 0.234375 0.359375 0.757813 +v -0.234375 0.359375 0.757813 +v 0.195313 0.296875 0.757813 +v -0.195313 0.296875 0.757813 +v 0.242188 0.125000 0.757813 +v -0.242188 0.125000 0.757813 +v 0.375000 0.085938 0.726563 +v -0.375000 0.085938 0.726563 +v 0.460938 0.117188 0.703125 +v -0.460938 0.117188 0.703125 +v 0.546875 0.210938 0.671875 +v -0.546875 0.210938 0.671875 +v 0.554688 0.281250 0.671875 +v -0.554688 0.281250 0.671875 +v 0.531250 0.335938 0.679688 +v -0.531250 0.335938 0.679688 +v 0.414063 0.390625 0.750000 +v -0.414063 0.390625 0.750000 +v 0.281250 0.398438 0.765625 +v -0.281250 0.398438 0.765625 +v 0.335938 0.406250 0.750000 +v -0.335938 0.406250 0.750000 +v 0.203125 0.171875 0.750000 +v -0.203125 0.171875 0.750000 +v 0.195313 0.226563 0.750000 +v -0.195313 0.226563 0.750000 +v 0.109375 0.460938 0.609375 +v -0.109375 0.460938 0.609375 +v 0.195313 0.664063 0.617188 +v -0.195313 0.664063 0.617188 +v 0.335938 0.687500 0.593750 +v -0.335938 0.687500 0.593750 +v 0.484375 0.554688 0.554688 +v -0.484375 0.554688 0.554688 +v 0.679688 0.453125 0.492188 +v -0.679688 0.453125 0.492188 +v 0.796875 0.406250 0.460938 +v -0.796875 0.406250 0.460938 +v 0.773438 0.164063 0.375000 +v -0.773438 0.164063 0.375000 +v 0.601563 0.000000 0.414063 +v -0.601563 0.000000 0.414063 +v 0.437500 -0.093750 0.468750 +v -0.437500 -0.093750 0.468750 +v 0.000000 0.898438 0.289063 +v 0.000000 0.984375 -0.078125 +v 0.000000 -0.195313 -0.671875 +v 0.000000 -0.460938 0.187500 +v 0.000000 -0.976563 0.460938 +v 0.000000 -0.804688 0.343750 +v 0.000000 -0.570313 0.320313 +v 0.000000 -0.484375 0.281250 +v 0.851563 0.234375 0.054688 +v -0.851563 0.234375 0.054688 +v 0.859375 0.320313 -0.046875 +v -0.859375 0.320313 -0.046875 +v 0.773438 0.265625 -0.437500 +v -0.773438 0.265625 -0.437500 +v 0.460938 0.437500 -0.703125 +v -0.460938 0.437500 -0.703125 +v 0.734375 -0.046875 0.070313 +v -0.734375 -0.046875 0.070313 +v 0.593750 -0.125000 -0.164063 +v -0.593750 -0.125000 -0.164063 +v 0.640625 -0.007813 -0.429688 +v -0.640625 -0.007813 -0.429688 +v 0.335938 0.054688 -0.664063 +v -0.335938 0.054688 -0.664063 +v 0.234375 -0.351563 0.406250 +v -0.234375 -0.351563 0.406250 +v 0.179688 -0.414063 0.257813 +v -0.179688 -0.414063 0.257813 +v 0.289063 -0.710938 0.382813 +v -0.289063 -0.710938 0.382813 +v 0.250000 -0.500000 0.390625 +v -0.250000 -0.500000 0.390625 +v 0.328125 -0.914063 0.398438 +v -0.328125 -0.914063 0.398438 +v 0.140625 -0.757813 0.367188 +v -0.140625 -0.757813 0.367188 +v 0.125000 -0.539063 0.359375 +v -0.125000 -0.539063 0.359375 +v 0.164063 -0.945313 0.437500 +v -0.164063 -0.945313 0.437500 +v 0.218750 -0.281250 0.429688 +v -0.218750 -0.281250 0.429688 +v 0.210938 -0.226563 0.468750 +v -0.210938 -0.226563 0.468750 +v 0.203125 -0.171875 0.500000 +v -0.203125 -0.171875 0.500000 +v 0.210938 -0.390625 0.164063 +v -0.210938 -0.390625 0.164063 +v 0.296875 -0.312500 -0.265625 +v -0.296875 -0.312500 -0.265625 +v 0.343750 -0.148438 -0.539063 +v -0.343750 -0.148438 -0.539063 +v 0.453125 0.867188 -0.382813 +v -0.453125 0.867188 -0.382813 +v 0.453125 0.929688 -0.070313 +v -0.453125 0.929688 -0.070313 +v 0.453125 0.851563 0.234375 +v -0.453125 0.851563 0.234375 +v 0.460938 0.523438 0.429688 +v -0.460938 0.523438 0.429688 +v 0.726563 0.406250 0.335938 +v -0.726563 0.406250 0.335938 +v 0.632813 0.453125 0.281250 +v -0.632813 0.453125 0.281250 +v 0.640625 0.703125 0.054688 +v -0.640625 0.703125 0.054688 +v 0.796875 0.562500 0.125000 +v -0.796875 0.562500 0.125000 +v 0.796875 0.617188 -0.117188 +v -0.796875 0.617188 -0.117188 +v 0.640625 0.750000 -0.195313 +v -0.640625 0.750000 -0.195313 +v 0.640625 0.679688 -0.445313 +v -0.640625 0.679688 -0.445313 +v 0.796875 0.539063 -0.359375 +v -0.796875 0.539063 -0.359375 +v 0.617188 0.328125 -0.585938 +v -0.617188 0.328125 -0.585938 +v 0.484375 0.023438 -0.546875 +v -0.484375 0.023438 -0.546875 +v 0.820313 0.328125 -0.203125 +v -0.820313 0.328125 -0.203125 +v 0.406250 -0.171875 0.148438 +v -0.406250 -0.171875 0.148438 +v 0.429688 -0.195313 -0.210938 +v -0.429688 -0.195313 -0.210938 +v 0.890625 0.406250 -0.234375 +v -0.890625 0.406250 -0.234375 +v 0.773438 -0.140625 -0.125000 +v -0.773438 -0.140625 -0.125000 +v 1.039063 -0.101563 -0.328125 +v -1.039063 -0.101563 -0.328125 +v 1.281250 0.054688 -0.429688 +v -1.281250 0.054688 -0.429688 +v 1.351563 0.320313 -0.421875 +v -1.351563 0.320313 -0.421875 +v 1.234375 0.507813 -0.421875 +v -1.234375 0.507813 -0.421875 +v 1.023438 0.476563 -0.312500 +v -1.023438 0.476563 -0.312500 +v 1.015625 0.414063 -0.289063 +v -1.015625 0.414063 -0.289063 +v 1.187500 0.437500 -0.390625 +v -1.187500 0.437500 -0.390625 +v 1.265625 0.289063 -0.406250 +v -1.265625 0.289063 -0.406250 +v 1.210938 0.078125 -0.406250 +v -1.210938 0.078125 -0.406250 +v 1.031250 -0.039063 -0.304688 +v -1.031250 -0.039063 -0.304688 +v 0.828125 -0.070313 -0.132813 +v -0.828125 -0.070313 -0.132813 +v 0.921875 0.359375 -0.218750 +v -0.921875 0.359375 -0.218750 +v 0.945313 0.304688 -0.289063 +v -0.945313 0.304688 -0.289063 +v 0.882813 -0.023438 -0.210938 +v -0.882813 -0.023438 -0.210938 +v 1.039063 0.000000 -0.367188 +v -1.039063 0.000000 -0.367188 +v 1.187500 0.093750 -0.445313 +v -1.187500 0.093750 -0.445313 +v 1.234375 0.250000 -0.445313 +v -1.234375 0.250000 -0.445313 +v 1.171875 0.359375 -0.437500 +v -1.171875 0.359375 -0.437500 +v 1.023438 0.343750 -0.359375 +v -1.023438 0.343750 -0.359375 +v 0.843750 0.289063 -0.210938 +v -0.843750 0.289063 -0.210938 +v 0.835938 0.171875 -0.273438 +v -0.835938 0.171875 -0.273438 +v 0.757813 0.093750 -0.273438 +v -0.757813 0.093750 -0.273438 +v 0.820313 0.085938 -0.273438 +v -0.820313 0.085938 -0.273438 +v 0.843750 0.015625 -0.273438 +v -0.843750 0.015625 -0.273438 +v 0.812500 -0.015625 -0.273438 +v -0.812500 -0.015625 -0.273438 +v 0.726563 0.000000 -0.070313 +v -0.726563 0.000000 -0.070313 +v 0.718750 -0.023438 -0.171875 +v -0.718750 -0.023438 -0.171875 +v 0.718750 0.039063 -0.187500 +v -0.718750 0.039063 -0.187500 +v 0.796875 0.203125 -0.210938 +v -0.796875 0.203125 -0.210938 +v 0.890625 0.242188 -0.265625 +v -0.890625 0.242188 -0.265625 +v 0.890625 0.234375 -0.320313 +v -0.890625 0.234375 -0.320313 +v 0.812500 -0.015625 -0.320313 +v -0.812500 -0.015625 -0.320313 +v 0.851563 0.015625 -0.320313 +v -0.851563 0.015625 -0.320313 +v 0.828125 0.078125 -0.320313 +v -0.828125 0.078125 -0.320313 +v 0.765625 0.093750 -0.320313 +v -0.765625 0.093750 -0.320313 +v 0.843750 0.171875 -0.320313 +v -0.843750 0.171875 -0.320313 +v 1.039063 0.328125 -0.414063 +v -1.039063 0.328125 -0.414063 +v 1.187500 0.343750 -0.484375 +v -1.187500 0.343750 -0.484375 +v 1.257813 0.242188 -0.492188 +v -1.257813 0.242188 -0.492188 +v 1.210938 0.085938 -0.484375 +v -1.210938 0.085938 -0.484375 +v 1.046875 0.000000 -0.421875 +v -1.046875 0.000000 -0.421875 +v 0.882813 -0.015625 -0.265625 +v -0.882813 -0.015625 -0.265625 +v 0.953125 0.289063 -0.343750 +v -0.953125 0.289063 -0.343750 +v 0.890625 0.109375 -0.328125 +v -0.890625 0.109375 -0.328125 +v 0.937500 0.062500 -0.335938 +v -0.937500 0.062500 -0.335938 +v 1.000000 0.125000 -0.367188 +v -1.000000 0.125000 -0.367188 +v 0.960938 0.171875 -0.351563 +v -0.960938 0.171875 -0.351563 +v 1.015625 0.234375 -0.375000 +v -1.015625 0.234375 -0.375000 +v 1.054688 0.187500 -0.382813 +v -1.054688 0.187500 -0.382813 +v 1.109375 0.210938 -0.390625 +v -1.109375 0.210938 -0.390625 +v 1.085938 0.273438 -0.390625 +v -1.085938 0.273438 -0.390625 +v 1.023438 0.437500 -0.484375 +v -1.023438 0.437500 -0.484375 +v 1.250000 0.468750 -0.546875 +v -1.250000 0.468750 -0.546875 +v 1.367188 0.296875 -0.500000 +v -1.367188 0.296875 -0.500000 +v 1.312500 0.054688 -0.531250 +v -1.312500 0.054688 -0.531250 +v 1.039063 -0.085938 -0.492188 +v -1.039063 -0.085938 -0.492188 +v 0.789063 -0.125000 -0.328125 +v -0.789063 -0.125000 -0.328125 +v 0.859375 0.382813 -0.382813 +v -0.859375 0.382813 -0.382813 +v -1.023438 0.476563 -0.312500 +v -1.234375 0.507813 -0.421875 +v -0.890625 0.406250 -0.234375 +v -0.820313 0.328125 -0.203125 +vt 0.315596 0.792535 +vt 0.331462 0.787091 +vt 0.331944 0.799704 +vt 0.049262 0.798007 +vt 0.050304 0.785428 +vt 0.065913 0.791570 +vt 0.321453 0.778649 +vt 0.060677 0.777438 +vt 0.310368 0.778802 +vt 0.071744 0.778083 +vt 0.302416 0.786560 +vt 0.079345 0.786186 +vt 0.301514 0.798474 +vt 0.079717 0.798128 +vt 0.308740 0.806873 +vt 0.072125 0.806199 +vt 0.321648 0.808687 +vt 0.059149 0.807438 +vt 0.048462 0.201858 +vt 0.040084 0.207259 +vt 0.043232 0.202821 +vt 0.043249 0.220655 +vt 0.040093 0.216224 +vt 0.048480 0.221607 +vt 0.563710 0.649220 +vt 0.540594 0.657349 +vt 0.547067 0.627433 +vt 0.974643 0.218739 +vt 0.968169 0.188824 +vt 0.991286 0.196952 +vt 0.166564 0.702856 +vt 0.160061 0.635503 +vt 0.218800 0.643864 +vt 0.646379 0.202310 +vt 0.587641 0.210669 +vt 0.594146 0.143318 +vt 0.231653 0.710981 +vt 0.181122 0.727399 +vt 0.174315 0.716236 +vt 0.601897 0.129938 +vt 0.608704 0.118775 +vt 0.659234 0.135195 +vt 0.266169 0.503056 +vt 0.270502 0.531304 +vt 0.237927 0.525958 +vt 0.665505 0.320215 +vt 0.698081 0.314870 +vt 0.693747 0.343118 +vt 0.392095 0.783569 +vt 0.421339 0.774990 +vt 0.422693 0.793271 +vt 0.628129 0.465996 +vt 0.613733 0.456434 +vt 0.634389 0.436387 +vt 0.501778 0.870396 +vt 0.507486 0.857499 +vt 0.528577 0.865850 +vt 0.643384 0.583025 +vt 0.644052 0.562152 +vt 0.656465 0.561923 +vt 0.766386 0.787223 +vt 0.745292 0.810963 +vt 0.708792 0.802136 +vt 0.769147 0.634951 +vt 0.732033 0.641034 +vt 0.711181 0.618495 +vt 0.849461 0.545148 +vt 0.823375 0.497849 +vt 0.897469 0.500666 +vt 0.902318 0.546395 +vt 0.572425 0.679855 +vt 0.643837 0.668801 +vt 0.623443 0.718088 +vt 0.572425 0.724426 +vt 0.726607 0.540494 +vt 0.753364 0.518460 +vt 0.715449 0.680462 +vt 0.749227 0.698466 +vt 0.695922 0.534580 +vt 0.693526 0.510498 +vt 0.772837 0.655221 +vt 0.784620 0.679820 +vt 0.718163 0.580185 +vt 0.809389 0.599417 +vt 0.761761 0.743313 +vt 0.667750 0.767676 +vt 0.693110 0.564191 +vt 0.797155 0.722534 +vt 0.682009 0.616616 +vt 0.795802 0.787304 +vt 0.719538 0.655221 +vt 0.756895 0.826983 +vt 0.782765 0.655221 +vt 0.695179 0.821970 +vt 0.843059 0.610497 +vt 0.635588 0.780626 +vt 0.634422 0.561399 +vt 0.628274 0.581967 +vt 0.511020 0.847430 +vt 0.533908 0.850607 +vt 0.633815 0.551490 +vt 0.613046 0.571327 +vt 0.530368 0.831407 +vt 0.501394 0.842435 +vt 0.626589 0.538875 +vt 0.604527 0.544684 +vt 0.508929 0.810914 +vt 0.492547 0.829318 +vt 0.618247 0.522587 +vt 0.602583 0.501781 +vt 0.480939 0.813120 +vt 0.469234 0.787943 +vt 0.616652 0.502716 +vt 0.613925 0.497595 +vt 0.459358 0.796431 +vt 0.462840 0.801566 +vt 0.644899 0.511966 +vt 0.630336 0.517087 +vt 0.628893 0.504351 +vt 0.635735 0.498392 +vt 0.458270 0.813966 +vt 0.469630 0.821874 +vt 0.457144 0.833207 +vt 0.449054 0.817297 +vt 0.637359 0.534149 +vt 0.654293 0.524569 +vt 0.464258 0.849211 +vt 0.482600 0.837505 +vt 0.644187 0.548520 +vt 0.659377 0.540935 +vt 0.478087 0.863369 +vt 0.493557 0.851414 +vt 0.597230 0.539263 +vt 0.595257 0.495349 +vt 0.466971 0.777596 +vt 0.507407 0.801398 +vt 0.605628 0.572478 +vt 0.534801 0.825096 +vt 0.627145 0.592333 +vt 0.544318 0.853620 +vt 0.651887 0.586528 +vt 0.528822 0.875551 +vt 0.665532 0.557472 +vt 0.492878 0.878439 +vt 0.669345 0.535984 +vt 0.467321 0.871200 +vt 0.612569 0.491986 +vt 0.454710 0.792385 +vt 0.619277 0.495381 +vt 0.454636 0.800448 +vt 0.628580 0.496763 +vt 0.451294 0.809743 +vt 0.636682 0.490206 +vt 0.440853 0.813605 +vt 0.652342 0.504728 +vt 0.446182 0.836397 +vt 0.664409 0.519225 +vt 0.453285 0.856119 +vt 0.666191 0.492411 +vt 0.717596 0.474672 +vt 0.382398 0.879324 +vt 0.427166 0.842398 +vt 0.681733 0.511408 +vt 0.427493 0.877628 +vt 0.435523 0.867805 +vt 0.685777 0.532869 +vt 0.453231 0.887054 +vt 0.588528 0.478377 +vt 0.454313 0.762782 +vt 0.446975 0.900429 +vt 0.713425 0.237886 +vt 0.709019 0.215724 +vt 0.755152 0.224403 +vt 0.762923 0.242445 +vt 0.327574 0.621771 +vt 0.281440 0.630451 +vt 0.285847 0.608289 +vt 0.335345 0.603729 +vt 0.576794 0.465515 +vt 0.583867 0.423087 +vt 0.405805 0.730353 +vt 0.448347 0.745304 +vt 0.686035 0.253032 +vt 0.258456 0.593142 +vt 0.683851 0.556229 +vt 0.482266 0.899349 +vt 0.670531 0.597684 +vt 0.532990 0.898426 +vt 0.630909 0.604157 +vt 0.553941 0.861896 +vt 0.596864 0.576275 +vt 0.542184 0.818594 +vt 0.585561 0.529242 +vt 0.503791 0.785451 +vt 0.572425 0.529736 +vt 0.510638 0.773572 +vt 0.587548 0.588270 +vt 0.557294 0.815416 +vt 0.629961 0.623919 +vt 0.572425 0.868524 +vt 0.548104 0.914571 +vt 0.488130 0.914571 +vt 0.658830 0.266292 +vt 0.631691 0.281488 +vt 0.204112 0.564686 +vt 0.231252 0.579881 +vt 0.706402 0.288928 +vt 0.278823 0.557246 +vt 0.743528 0.317934 +vt 0.752264 0.346660 +vt 0.324686 0.499513 +vt 0.315950 0.528240 +vt 0.743309 0.289810 +vt 0.315731 0.556363 +vt 0.700326 0.147967 +vt 0.272746 0.698208 +vt 0.795874 0.266472 +vt 0.775660 0.289442 +vt 0.757507 0.263314 +vt 0.348083 0.556732 +vt 0.329929 0.582860 +vt 0.368297 0.579702 +vt 0.804056 0.232825 +vt 0.376478 0.613349 +vt 0.810124 0.179100 +vt 0.382547 0.667075 +vt 0.753847 0.157090 +vt 0.811201 0.146834 +vt 0.383624 0.699341 +vt 0.326269 0.689085 +vt 0.879685 0.183943 +vt 0.888071 0.157228 +vt 0.460496 0.688946 +vt 0.452109 0.662231 +vt 0.925222 0.140531 +vt 0.947451 0.149372 +vt 0.519876 0.696801 +vt 0.497647 0.705643 +vt 0.876420 0.258223 +vt 0.946138 0.286262 +vt 0.518561 0.559910 +vt 0.448843 0.587951 +vt 0.829953 0.196170 +vt 0.837053 0.152275 +vt 0.409477 0.693900 +vt 0.402377 0.650004 +vt 0.829888 0.255993 +vt 0.402311 0.590181 +vt 0.852096 0.297194 +vt 0.813695 0.289418 +vt 0.424519 0.548979 +vt 0.386117 0.556756 +vt 0.820842 0.328587 +vt 0.789451 0.311961 +vt 0.393264 0.517587 +vt 0.361873 0.534212 +vt 0.840465 0.403536 +vt 0.762603 0.423087 +vt 0.412887 0.442637 +vt 0.335024 0.423087 +vt 0.909248 0.345901 +vt 0.481670 0.500271 +vt 0.676670 0.402805 +vt 0.249092 0.443369 +vt 0.573469 0.193539 +vt 0.579214 0.151927 +vt 0.151632 0.694246 +vt 0.145888 0.652633 +vt 0.546919 0.227092 +vt 0.536510 0.214419 +vt 0.119340 0.619080 +vt 0.108931 0.631753 +vt 0.588792 0.317539 +vt 0.161214 0.528634 +vt 0.630429 0.371564 +vt 0.202851 0.474609 +vt 0.657494 0.118541 +vt 0.164237 0.319427 +vt 0.169464 0.304721 +vt 0.210459 0.345510 +vt 0.169574 0.118572 +vt 0.164356 0.103821 +vt 0.210731 0.077759 +vt 0.229913 0.727634 +vt 0.589956 0.115821 +vt 0.153468 0.300432 +vt 0.153526 0.122857 +vt 0.162374 0.730353 +vt 0.578472 0.119429 +vt 0.553653 0.120209 +vt 0.126070 0.725964 +vt 0.150890 0.726744 +vt 0.546510 0.159800 +vt 0.509384 0.119033 +vt 0.081800 0.727137 +vt 0.118929 0.686371 +vt 0.534072 0.185482 +vt 0.106492 0.660689 +vt 0.462352 0.161885 +vt 0.478174 0.145123 +vt 0.493641 0.175543 +vt 0.505521 0.150780 +vt 0.077939 0.695390 +vt 0.050592 0.701044 +vt 0.066060 0.670626 +vt 0.034770 0.684282 +vt 0.476706 0.124129 +vt 0.049122 0.722039 +vt 0.465324 0.131169 +vt 0.037741 0.714998 +vt 0.446348 0.149671 +vt 0.018765 0.696495 +vt 0.445483 0.184898 +vt 0.427581 0.175095 +vt 0.000000 0.671069 +vt 0.017903 0.661268 +vt 0.480167 0.198327 +vt 0.052588 0.647841 +vt 0.521714 0.207472 +vt 0.094135 0.638699 +vt 0.701979 0.120236 +vt 0.274400 0.725940 +vt 0.757541 0.138176 +vt 0.329963 0.708000 +vt 0.817327 0.117813 +vt 0.389751 0.728363 +vt 0.844767 0.126748 +vt 0.417191 0.719428 +vt 0.893893 0.126476 +vt 0.466319 0.719698 +vt 0.936543 0.115821 +vt 0.508970 0.730353 +vt 0.965717 0.128368 +vt 0.538144 0.717805 +vt 0.989276 0.166159 +vt 0.561701 0.680013 +vt 1.000000 0.175243 +vt 0.572425 0.670929 +vt 0.289028 0.269037 +vt 0.283878 0.263049 +vt 0.299187 0.258321 +vt 0.300964 0.267357 +vt 0.299421 0.165436 +vt 0.284101 0.160633 +vt 0.289287 0.154655 +vt 0.301244 0.156393 +vt 0.317793 0.260767 +vt 0.316733 0.267304 +vt 0.318078 0.163079 +vt 0.317052 0.156521 +vt 0.335398 0.269583 +vt 0.330421 0.276220 +vt 0.335777 0.154335 +vt 0.330824 0.147649 +vt 0.278552 0.277080 +vt 0.273734 0.272912 +vt 0.273975 0.150706 +vt 0.278818 0.146548 +vt 0.271078 0.306358 +vt 0.264864 0.305818 +vt 0.265194 0.117691 +vt 0.271427 0.117166 +vt 0.278613 0.324240 +vt 0.274006 0.327477 +vt 0.274436 0.095993 +vt 0.279049 0.099253 +vt 0.298062 0.342565 +vt 0.294660 0.349561 +vt 0.295240 0.073895 +vt 0.298634 0.080932 +vt 0.312476 0.342961 +vt 0.315033 0.350198 +vt 0.315702 0.073322 +vt 0.313108 0.080584 +vt 0.323281 0.337709 +vt 0.328696 0.344302 +vt 0.329405 0.079293 +vt 0.323940 0.085897 +vt 0.335361 0.313857 +vt 0.339396 0.315576 +vt 0.340031 0.108187 +vt 0.335968 0.109893 +vt 0.339920 0.298303 +vt 0.345292 0.298556 +vt 0.345869 0.125306 +vt 0.340471 0.125531 +vt 0.339277 0.286081 +vt 0.344398 0.284332 +vt 0.344895 0.139582 +vt 0.339764 0.137799 +vt 0.345671 0.260159 +vt 0.355483 0.280619 +vt 0.356003 0.143373 +vt 0.346021 0.163854 +vt 0.356162 0.297750 +vt 0.356783 0.126174 +vt 0.349494 0.319809 +vt 0.350195 0.103982 +vt 0.333524 0.354692 +vt 0.334295 0.068869 +vt 0.317323 0.364551 +vt 0.318050 0.058911 +vt 0.293154 0.361782 +vt 0.293765 0.061619 +vt 0.263750 0.335417 +vt 0.264168 0.087998 +vt 0.251373 0.309082 +vt 0.251676 0.114380 +vt 0.264926 0.265507 +vt 0.265122 0.158092 +vt 0.278030 0.255522 +vt 0.278212 0.168150 +vt 0.320744 0.246538 +vt 0.320956 0.177355 +vt 0.296570 0.247318 +vt 0.296748 0.176443 +vt 0.038845 0.211743 +vt 0.047440 0.211734 +vt 0.055230 0.211728 +vt 0.057303 0.228458 +vt 0.057278 0.194991 +vt 0.041287 0.229096 +vt 0.041253 0.194380 +vt 0.032564 0.220061 +vt 0.032546 0.203437 +vt 0.030743 0.211752 +vt 0.029931 0.223131 +vt 0.028053 0.211756 +vt 0.029906 0.200372 +vt 0.038587 0.233067 +vt 0.038544 0.190412 +vt 0.061533 0.231825 +vt 0.061505 0.191616 +vt 0.057382 0.211726 +vt 0.168191 0.258703 +vt 0.213958 0.246887 +vt 0.214040 0.176591 +vt 0.168236 0.164676 +vt 0.148297 0.258447 +vt 0.138777 0.299079 +vt 0.138791 0.124216 +vt 0.148319 0.164919 +vt 0.115455 0.259296 +vt 0.109657 0.296761 +vt 0.109611 0.126556 +vt 0.115440 0.164070 +vt 0.119233 0.228698 +vt 0.156540 0.233552 +vt 0.156556 0.189842 +vt 0.119230 0.194690 +vt 0.173998 0.244074 +vt 0.174035 0.179329 +vt 0.195860 0.238258 +vt 0.195909 0.185188 +vt 0.203534 0.211734 +vt 0.252997 0.211802 +vt 0.171285 0.225095 +vt 0.164455 0.211704 +vt 0.180017 0.211713 +vt 0.177113 0.227468 +vt 0.171300 0.198319 +vt 0.177134 0.195952 +vt 0.185539 0.227013 +vt 0.187516 0.221322 +vt 0.187531 0.202116 +vt 0.185563 0.196419 +vt 0.176585 0.232500 +vt 0.165993 0.229894 +vt 0.176611 0.190916 +vt 0.166011 0.193512 +vt 0.189406 0.230672 +vt 0.189438 0.192766 +vt 0.193574 0.221791 +vt 0.193592 0.201656 +vt 0.186479 0.211718 +vt 0.156919 0.211701 +vt 0.148476 0.211699 +vt 0.427853 0.115821 +vt 0.427581 0.104121 +vt 0.441185 0.104121 +vt 0.427581 0.011703 +vt 0.427581 0.000000 +vt 0.441181 0.011386 +vt 0.067509 0.234045 +vt 0.071465 0.211716 +vt 0.067479 0.189385 +vt 0.119764 0.211696 +vt 0.060932 0.261035 +vt 0.038121 0.261699 +vt 0.038025 0.161756 +vt 0.060860 0.162382 +vt 0.019864 0.255578 +vt 0.019760 0.167921 +vt 0.016617 0.242679 +vt 0.016537 0.180842 +vt 0.014466 0.211775 +vt 0.297831 0.211892 +vt 0.340508 0.212027 +vt 0.356498 0.241635 +vt 0.356742 0.182510 +vt 0.236517 0.317748 +vt 0.236802 0.105655 +vt 0.264789 0.363401 +vt 0.265286 0.059917 +vt 0.296951 0.385966 +vt 0.297650 0.037339 +vt 0.337996 0.385300 +vt 0.338890 0.038126 +vt 0.349401 0.368365 +vt 0.350300 0.055183 +vt 0.377282 0.319664 +vt 0.378129 0.104260 +vt 0.394788 0.292204 +vt 0.395576 0.131978 +vt 0.391029 0.270263 +vt 0.391643 0.154015 +vt 0.368661 0.212151 +vt 0.379482 0.228055 +vt 0.379686 0.196331 +vt 0.420379 0.261837 +vt 0.421104 0.162716 +vt 0.426533 0.298960 +vt 0.427581 0.125377 +vt 0.396664 0.342212 +vt 0.397734 0.081667 +vt 0.365156 0.387054 +vt 0.366203 0.036443 +vt 0.346744 0.416452 +vt 0.347768 0.006839 +vt 0.278009 0.423087 +vt 0.278714 0.000000 +vt 0.241964 0.376122 +vt 0.242399 0.047096 +vt 0.055563 0.291878 +vt 0.055443 0.131506 +vt 0.014495 0.288026 +vt 0.014318 0.135436 +vt 0.003828 0.279132 +vt 0.003650 0.144368 +vt 0.000113 0.248111 +vt 0.000000 0.175447 +vt 0.000000 0.211799 +vt 0.046962 0.798865 +vt 0.047306 0.784561 +vt 0.334495 0.786358 +vt 0.334204 0.800664 +vt 0.058429 0.773633 +vt 0.323868 0.774947 +vt 0.072992 0.774071 +vt 0.309301 0.774739 +vt 0.084403 0.784016 +vt 0.297459 0.784168 +vt 0.083417 0.800146 +vt 0.297728 0.800325 +vt 0.073091 0.810538 +vt 0.307582 0.811166 +vt 0.057505 0.810093 +vt 0.323173 0.811412 +vt 0.024988 0.807478 +vt 0.047717 0.829014 +vt 0.332112 0.830749 +vt 0.355774 0.810244 +vt 0.000000 0.817350 +vt 0.033121 0.852785 +vt 0.345638 0.855146 +vt 0.380299 0.821215 +vt 0.083391 0.855019 +vt 0.078555 0.829097 +vt 0.301299 0.829463 +vt 0.295318 0.855146 +vt 0.100718 0.807888 +vt 0.280100 0.807291 +vt 0.123146 0.821929 +vt 0.257070 0.820323 +vt 0.127501 0.768220 +vt 0.103229 0.776171 +vt 0.279000 0.775494 +vt 0.255105 0.766472 +vt 0.079351 0.756089 +vt 0.303746 0.756492 +vt 0.089008 0.730353 +vt 0.295241 0.730353 +vt 0.049398 0.755271 +vt 0.035422 0.733227 +vt 0.333706 0.757005 +vt 0.348646 0.735604 +vt 0.026877 0.776230 +vt 0.355274 0.778943 +vt 0.000000 0.770061 +vt 0.382398 0.773973 +vn 0.189764 -0.003571 0.981811 +vn 0.646809 -0.758202 0.082095 +vn 0.999573 -0.014496 -0.024445 +vn -0.999573 -0.014496 -0.024445 +vn -0.646809 -0.758202 0.082095 +vn -0.189764 -0.003571 0.981811 +vn -0.085788 -0.982971 0.162389 +vn 0.085788 -0.982971 0.162389 +vn -0.744835 -0.623768 0.236824 +vn 0.744835 -0.623768 0.236824 +vn -0.870968 -0.014710 0.491104 +vn 0.870968 -0.014710 0.491104 +vn -0.758354 0.606128 0.239692 +vn 0.758354 0.606128 0.239692 +vn -0.085788 0.982513 0.165105 +vn 0.085788 0.982513 0.165105 +vn 0.655141 0.750633 0.085574 +vn -0.655141 0.750633 0.085574 +vn -0.349284 -0.719932 0.599719 +vn -0.173681 0.215735 0.960845 +vn -0.809839 0.388287 0.439741 +vn 0.809839 0.388287 0.439741 +vn 0.173681 0.215735 0.960845 +vn 0.349284 -0.719932 0.599719 +vn 0.000000 0.794183 0.607654 +vn -0.508652 0.858119 -0.069887 +vn 0.000000 0.487075 0.873348 +vn 0.508652 0.858119 -0.069887 +vn 0.981414 -0.186682 0.043947 +vn 0.569811 -0.821711 0.007813 +vn 0.563463 -0.814570 0.137669 +vn -0.563463 -0.814570 0.137669 +vn -0.569811 -0.821711 0.007813 +vn -0.981414 -0.186682 0.043947 +vn 0.475845 -0.876247 0.075381 +vn 0.850520 -0.525529 -0.020692 +vn 0.876949 -0.163823 0.451766 +vn -0.876949 -0.163823 0.451766 +vn -0.850520 -0.525529 -0.020692 +vn -0.475845 -0.876247 0.075381 +vn 0.448286 -0.367870 -0.814661 +vn 0.530534 -0.539445 -0.653829 +vn 0.513077 -0.674673 -0.530595 +vn -0.513077 -0.674673 -0.530595 +vn -0.530534 -0.539445 -0.653829 +vn -0.448286 -0.367870 -0.814661 +vn 0.888180 -0.439955 -0.132389 +vn 0.588519 0.226966 0.775933 +vn 0.911527 -0.115268 0.394665 +vn -0.911527 -0.115268 0.394665 +vn -0.588519 0.226966 0.775933 +vn -0.888180 -0.439955 -0.132389 +vn 0.468886 -0.304727 0.829005 +vn 0.251564 0.260781 0.932005 +vn -0.003082 -0.330882 0.943632 +vn 0.003082 -0.330882 0.943632 +vn -0.251564 0.260781 0.932005 +vn -0.468886 -0.304727 0.829005 +vn 0.473067 0.578997 -0.664022 +vn 0.992462 0.028626 -0.118900 +vn 0.459975 -0.380261 -0.802362 +vn -0.459975 -0.380261 -0.802362 +vn -0.992462 0.028626 -0.118900 +vn -0.473067 0.578997 -0.664022 +vn -0.059908 -0.804712 -0.590594 +vn -0.346141 -0.637287 -0.688498 +vn -0.330546 -0.943236 0.031281 +vn -0.073672 -0.594989 0.800317 +vn 0.330546 -0.943236 0.031281 +vn 0.346141 -0.637287 -0.688498 +vn 0.059908 -0.804712 -0.590594 +vn 0.073672 -0.594989 0.800317 +vn 0.593738 0.595264 -0.541368 +vn -0.626057 -0.002686 -0.779748 +vn 0.626057 -0.002686 -0.779748 +vn -0.593738 0.595264 -0.541368 +vn 0.127689 0.703757 0.698843 +vn -0.713828 0.382183 0.586810 +vn 0.713828 0.382183 0.586810 +vn -0.127689 0.703757 0.698843 +vn 0.378063 0.560045 -0.737144 +vn 0.036805 -0.708457 -0.704764 +vn -0.378063 0.560045 -0.737144 +vn -0.036805 -0.708457 -0.704764 +vn -0.031556 0.838710 0.543626 +vn 0.031556 0.838710 0.543626 +vn -0.361156 0.848689 0.386303 +vn 0.361156 0.848689 0.386303 +vn -0.716392 0.204474 0.667043 +vn 0.716392 0.204474 0.667043 +vn -0.662038 -0.413770 0.624866 +vn 0.662038 -0.413770 0.624866 +vn -0.530229 -0.655751 0.537370 +vn 0.530229 -0.655751 0.537370 +vn -0.437483 0.001221 0.899197 +vn 0.550981 -0.138096 0.822993 +vn 0.437483 0.001221 0.899197 +vn -0.550981 -0.138096 0.822993 +vn -0.315958 -0.102298 0.943205 +vn 0.608539 0.296121 0.736167 +vn -0.608539 0.296121 0.736167 +vn 0.315958 -0.102298 0.943205 +vn -0.445479 -0.088778 0.890866 +vn -0.257698 0.600024 0.757317 +vn 0.257698 0.600024 0.757317 +vn 0.445479 -0.088778 0.890866 +vn -0.327799 0.169927 0.929319 +vn 0.041780 0.927213 0.372112 +vn 0.327799 0.169927 0.929319 +vn -0.041780 0.927213 0.372112 +vn -0.277932 0.260201 0.924680 +vn -0.750725 0.111545 0.651112 +vn 0.750725 0.111545 0.651112 +vn 0.277932 0.260201 0.924680 +vn -0.437910 -0.293985 0.849574 +vn -0.183782 0.036836 0.982269 +vn -0.554216 0.387219 0.736808 +vn -0.814325 0.253426 0.522111 +vn 0.554216 0.387219 0.736808 +vn 0.183782 0.036836 0.982269 +vn 0.437910 -0.293985 0.849574 +vn 0.814325 0.253426 0.522111 +vn -0.326670 -0.001617 0.945128 +vn -0.704337 -0.526872 0.475692 +vn 0.704337 -0.526872 0.475692 +vn 0.326670 -0.001617 0.945128 +vn -0.308786 0.134617 0.941527 +vn -0.629170 -0.371441 0.682730 +vn 0.629170 -0.371441 0.682730 +vn 0.308786 0.134617 0.941527 +vn 0.146184 0.948637 0.280465 +vn -0.137516 0.905820 0.400708 +vn 0.137516 0.905820 0.400708 +vn -0.146184 0.948637 0.280465 +vn 0.723746 0.690023 -0.005219 +vn -0.723746 0.690023 -0.005219 +vn 0.994690 -0.078005 0.067019 +vn -0.994690 -0.078005 0.067019 +vn 0.200934 -0.758141 0.620350 +vn -0.200934 -0.758141 0.620350 +vn -0.541246 -0.672658 0.504501 +vn 0.541246 -0.672658 0.504501 +vn -0.690054 -0.553209 0.466628 +vn 0.690054 -0.553209 0.466628 +vn -0.464003 0.686666 0.559557 +vn 0.464003 0.686666 0.559557 +vn -0.827448 -0.135899 0.544786 +vn 0.827448 -0.135899 0.544786 +vn -0.466231 0.808863 0.358196 +vn 0.466231 0.808863 0.358196 +vn -0.743980 -0.022919 0.667776 +vn 0.743980 -0.022919 0.667776 +vn -0.711295 -0.638325 0.294137 +vn 0.711295 -0.638325 0.294137 +vn -0.709769 -0.501999 0.494125 +vn 0.709769 -0.501999 0.494125 +vn -0.818903 -0.425520 0.385113 +vn -0.992523 -0.071444 -0.098758 +vn 0.992523 -0.071444 -0.098758 +vn 0.818903 -0.425520 0.385113 +vn -0.439192 -0.273568 0.855708 +vn 0.439192 -0.273568 0.855708 +vn -0.414686 -0.059877 0.907956 +vn 0.414686 -0.059877 0.907956 +vn -0.341563 0.452132 0.823939 +vn 0.341563 0.452132 0.823939 +vn -0.724509 -0.684927 0.076632 +vn -0.987548 -0.123020 0.097995 +vn 0.987548 -0.123020 0.097995 +vn 0.724509 -0.684927 0.076632 +vn -0.572741 -0.088443 0.814936 +vn 0.572741 -0.088443 0.814936 +vn -0.291818 -0.152104 0.944273 +vn 0.291818 -0.152104 0.944273 +vn 0.239662 -0.128605 0.962279 +vn -0.239662 -0.128605 0.962279 +vn 0.187017 0.370678 0.909696 +vn -0.187017 0.370678 0.909696 +vn -0.455794 0.423170 0.783044 +vn 0.455794 0.423170 0.783044 +vn -0.543504 -0.813379 -0.207343 +vn -0.560045 -0.814417 -0.151738 +vn 0.560045 -0.814417 -0.151738 +vn 0.543504 -0.813379 -0.207343 +vn -0.615375 -0.087649 -0.783319 +vn -0.447310 0.229530 -0.864406 +vn 0.447310 0.229530 -0.864406 +vn 0.615375 -0.087649 -0.783319 +vn -0.547166 -0.832179 -0.089785 +vn 0.547166 -0.832179 -0.089785 +vn -0.873135 0.486984 -0.020264 +vn -0.865352 0.331217 -0.376049 +vn 0.865352 0.331217 -0.376049 +vn 0.873135 0.486984 -0.020264 +vn -0.748741 0.518387 0.413038 +vn 0.748741 0.518387 0.413038 +vn -0.766167 0.634816 0.099612 +vn 0.766167 0.634816 0.099612 +vn -0.953185 -0.248299 -0.172430 +vn -0.665639 0.602496 -0.440321 +vn 0.665639 0.602496 -0.440321 +vn 0.953185 -0.248299 -0.172430 +vn -0.322642 0.847713 0.421033 +vn -0.188574 0.788934 -0.584765 +vn 0.188574 0.788934 -0.584765 +vn 0.322642 0.847713 0.421033 +vn -0.239784 0.745262 -0.622120 +vn 0.494247 0.520585 -0.696158 +vn -0.494247 0.520585 -0.696158 +vn 0.239784 0.745262 -0.622120 +vn -0.480697 0.731223 0.483932 +vn 0.000000 0.758690 0.651418 +vn 0.480697 0.731223 0.483932 +vn -0.489242 0.762963 0.422498 +vn -0.363109 0.908567 -0.206458 +vn 0.363109 0.908567 -0.206458 +vn 0.489242 0.762963 0.422498 +vn -0.645039 0.694540 0.318613 +vn 0.645039 0.694540 0.318613 +vn -0.492843 0.869015 0.043062 +vn -0.679434 0.728965 -0.083468 +vn 0.492843 0.869015 0.043062 +vn 0.679434 0.728965 -0.083468 +vn -0.391736 0.826014 -0.405225 +vn -0.644398 0.527207 -0.553880 +vn 0.391736 0.826014 -0.405225 +vn 0.644398 0.527207 -0.553880 +vn 0.000000 0.800714 -0.599017 +vn 0.000000 0.330729 -0.943693 +vn 0.000000 0.999664 0.025636 +vn 0.000000 -0.271462 -0.962432 +vn -0.685293 -0.583148 -0.436232 +vn -0.907224 0.252602 -0.336253 +vn 0.907224 0.252602 -0.336253 +vn 0.685293 -0.583148 -0.436232 +vn 0.000000 -0.984344 -0.176214 +vn 0.000000 -0.736351 -0.676565 +vn 0.000000 -0.948759 -0.315928 +vn 0.000000 -0.648244 -0.761406 +vn -0.317362 -0.946959 -0.049959 +vn -0.838282 -0.408155 0.361461 +vn 0.838282 -0.408155 0.361461 +vn 0.317362 -0.946959 -0.049959 +vn -0.939360 0.325999 0.106113 +vn 0.939360 0.325999 0.106113 +vn -0.930631 0.340159 0.134770 +vn -0.960143 0.231361 0.156774 +vn 0.960143 0.231361 0.156774 +vn 0.930631 0.340159 0.134770 +vn -0.812555 -0.001068 -0.582842 +vn -0.979583 0.093387 0.177862 +vn 0.979583 0.093387 0.177862 +vn 0.812555 -0.001068 -0.582842 +vn -0.272530 -0.301157 -0.913785 +vn 0.272530 -0.301157 -0.913785 +vn -0.090915 -0.776330 -0.623707 +vn -0.506851 -0.488144 -0.710471 +vn -0.142521 -0.147282 -0.978759 +vn -0.637257 0.093326 -0.764946 +vn 0.637257 0.093326 -0.764946 +vn 0.506851 -0.488144 -0.710471 +vn 0.142521 -0.147282 -0.978759 +vn 0.090915 -0.776330 -0.623707 +vn -0.937284 -0.254250 0.238350 +vn 0.937284 -0.254250 0.238350 +vn -0.430525 -0.895260 0.114597 +vn 0.430525 -0.895260 0.114597 +vn -0.158391 -0.974822 0.156774 +vn 0.158391 -0.974822 0.156774 +vn 0.000000 -0.915860 -0.401440 +vn 0.000000 -0.946440 0.322855 +vn 0.000000 -0.336802 -0.941557 +vn 0.000000 -0.175726 -0.984436 +vn -0.599231 -0.773980 0.204566 +vn 0.599231 -0.773980 0.204566 +vn -0.890988 -0.423261 -0.164037 +vn 0.890988 -0.423261 -0.164037 +vn -0.851985 0.219275 0.475387 +vn 0.851985 0.219275 0.475387 +vn -0.509171 0.852229 0.119999 +vn 0.509171 0.852229 0.119999 +vn -0.610431 0.759148 0.225867 +vn 0.610431 0.759148 0.225867 +vn -0.182470 0.981780 0.052492 +vn 0.182470 0.981780 0.052492 +vn 0.520371 0.770348 0.368389 +vn -0.520371 0.770348 0.368389 +vn 0.852718 0.504257 0.136204 +vn -0.852718 0.504257 0.136204 +vn 0.000000 0.970214 0.242164 +vn -0.709647 0.261818 0.654042 +vn 0.067293 -0.064272 0.995636 +vn -0.246590 -0.034089 0.968505 +vn -0.809717 -0.010224 0.586688 +vn 0.246590 -0.034089 0.968505 +vn -0.067293 -0.064272 0.995636 +vn 0.709647 0.261818 0.654042 +vn 0.809717 -0.010224 0.586688 +vn -0.465835 -0.080325 0.881191 +vn -0.737114 -0.244179 0.630085 +vn 0.465835 -0.080325 0.881191 +vn 0.737114 -0.244179 0.630085 +vn -0.211951 -0.085971 0.973479 +vn -0.367504 -0.376476 0.850398 +vn 0.211951 -0.085971 0.973479 +vn 0.367504 -0.376476 0.850398 +vn -0.430280 0.556597 0.710624 +vn -0.020081 -0.072939 0.997131 +vn 0.020081 -0.072939 0.997131 +vn 0.430280 0.556597 0.710624 +vn -0.090976 0.597339 0.796777 +vn -0.187933 -0.091617 0.977874 +vn 0.187933 -0.091617 0.977874 +vn 0.090976 0.597339 0.796777 +vn 0.165929 0.609363 0.775292 +vn -0.203314 0.092532 0.974700 +vn 0.203314 0.092532 0.974700 +vn -0.165929 0.609363 0.775292 +vn 0.269295 0.241676 0.932218 +vn -0.314219 -0.132420 0.940062 +vn 0.314219 -0.132420 0.940062 +vn -0.269295 0.241676 0.932218 +vn 0.420057 -0.118992 0.899625 +vn -0.119755 -0.070925 0.990234 +vn 0.119755 -0.070925 0.990234 +vn -0.420057 -0.118992 0.899625 +vn 0.226142 -0.606586 0.762139 +vn -0.320841 0.040712 0.946226 +vn 0.320841 0.040712 0.946226 +vn -0.226142 -0.606586 0.762139 +vn 0.232612 -0.746055 0.623890 +vn -0.074557 -0.391644 0.917081 +vn 0.074557 -0.391644 0.917081 +vn -0.232612 -0.746055 0.623890 +vn -0.121250 -0.313883 0.941679 +vn -0.146702 -0.035707 0.988525 +vn 0.146702 -0.035707 0.988525 +vn 0.121250 -0.313883 0.941679 +vn -0.216834 -0.273721 0.937010 +vn -0.187445 0.001160 0.982269 +vn 0.187445 0.001160 0.982269 +vn 0.216834 -0.273721 0.937010 +vn -0.303018 -0.201941 0.931333 +vn -0.253090 -0.161809 0.953795 +vn 0.253090 -0.161809 0.953795 +vn 0.303018 -0.201941 0.931333 +vn -0.140110 -0.091189 0.985900 +vn 0.140110 -0.091189 0.985900 +vn -0.237983 0.050172 0.969939 +vn 0.237983 0.050172 0.969939 +vn -0.312662 -0.237922 0.919553 +vn 0.312662 -0.237922 0.919553 +vn -0.373791 -0.105197 0.921506 +vn 0.373791 -0.105197 0.921506 +vn -0.470595 -0.164647 0.866817 +vn 0.470595 -0.164647 0.866817 +vn -0.439222 -0.376141 0.815821 +vn 0.439222 -0.376141 0.815821 +vn -0.219611 -0.540635 0.812037 +vn 0.219611 -0.540635 0.812037 +vn 0.166967 -0.374828 0.911893 +vn -0.166967 -0.374828 0.911893 +vn 0.201849 -0.277596 0.939238 +vn -0.201849 -0.277596 0.939238 +vn 0.001160 -0.165563 0.986175 +vn -0.001160 -0.165563 0.986175 +vn 0.292917 -0.174108 0.940123 +vn -0.292917 -0.174108 0.940123 +vn 0.000000 0.732200 0.681051 +vn 0.000000 -0.603626 0.797266 +vn 0.000000 -0.971740 0.235908 +vn 0.131779 -0.608295 0.782678 +vn -0.131779 -0.608295 0.782678 +vn 0.759117 0.068392 0.647298 +vn -0.759117 0.068392 0.647298 +vn 0.405957 0.643605 0.648793 +vn -0.405957 0.643605 0.648793 +vn 0.000000 0.598346 0.801202 +vn 0.073855 -0.330546 0.940855 +vn 0.000000 -0.124516 0.992187 +vn -0.073855 -0.330546 0.940855 +vn -0.085116 -0.339244 0.936827 +vn 0.085116 -0.339244 0.936827 +vn -0.141881 -0.148350 0.978698 +vn 0.141881 -0.148350 0.978698 +vn 0.000000 -0.482803 0.875698 +vn -0.692984 -0.001343 0.720908 +vn -0.095523 -0.326090 0.940489 +vn 0.095523 -0.326090 0.940489 +vn 0.692984 -0.001343 0.720908 +vn -0.646687 0.162603 0.745201 +vn 0.646687 0.162603 0.745201 +vn -0.593463 0.121860 0.795556 +vn 0.593463 0.121860 0.795556 +vn -0.124363 0.009674 0.992187 +vn -0.509995 -0.457717 0.728233 +vn 0.509995 -0.457717 0.728233 +vn 0.124363 0.009674 0.992187 +vn -0.972137 -0.167882 0.163549 +vn 0.972137 -0.167882 0.163549 +vn -0.715995 0.572161 0.399945 +vn 0.715995 0.572161 0.399945 +vn 0.000000 0.430525 0.902554 +vn 0.000000 0.010865 0.999939 +vn -0.221839 -0.606037 0.763848 +vn 0.000000 -0.492935 0.870022 +vn 0.000000 0.010315 0.999939 +vn -0.294320 -0.184484 0.937712 +vn 0.221839 -0.606037 0.763848 +vn 0.294320 -0.184484 0.937712 +vn -0.396924 0.534989 0.745781 +vn 0.247780 0.568224 0.784661 +vn -0.247780 0.568224 0.784661 +vn 0.396924 0.534989 0.745781 +vn -0.868221 -0.261330 0.421735 +vn -0.555986 -0.690695 0.462355 +vn 0.868221 -0.261330 0.421735 +vn 0.555986 -0.690695 0.462355 +vn -0.753075 0.649892 0.102298 +vn 0.753075 0.649892 0.102298 +vn 0.194189 0.935697 0.294473 +vn -0.194189 0.935697 0.294473 +vn 0.000000 0.788965 0.614399 +vn 0.000000 -0.888638 0.458571 +vn 0.000000 -0.336772 0.941557 +vn 0.000000 -0.251991 0.967711 +vn -0.188360 -0.040132 0.981262 +vn 0.000000 -0.032899 0.999451 +vn 0.188360 -0.040132 0.981262 +vn 0.000000 0.000000 1.000000 +vn -0.572039 -0.018708 0.820002 +vn -0.536332 -0.212409 0.816828 +vn 0.536332 -0.212409 0.816828 +vn 0.572039 -0.018708 0.820002 +vn -0.357707 -0.638325 0.681570 +vn 0.357707 -0.638325 0.681570 +vn -0.154302 -0.754112 0.638325 +vn 0.154302 -0.754112 0.638325 +vn 0.000000 -0.743461 0.668752 +vn 0.000000 -0.189123 0.981933 +vn 0.000000 -0.114475 0.993408 +vn 0.001404 -0.055635 0.998444 +vn -0.001404 -0.055635 0.998444 +vn -0.336283 -0.512833 0.789850 +vn 0.336283 -0.512833 0.789850 +vn -0.454543 -0.337077 0.824458 +vn 0.454543 -0.337077 0.824458 +vn -0.543474 -0.308603 0.780602 +vn 0.543474 -0.308603 0.780602 +vn -0.387158 -0.187811 0.902646 +vn 0.387158 -0.187811 0.902646 +vn -0.430647 -0.144902 0.890805 +vn 0.430647 -0.144902 0.890805 +vn -0.234016 -0.120548 0.964721 +vn 0.234016 -0.120548 0.964721 +vn -0.263833 0.168798 0.949675 +vn 0.263833 0.168798 0.949675 +vn 0.196722 0.141881 0.970122 +vn -0.196722 0.141881 0.970122 +vn -0.906766 -0.008332 0.421522 +vn -0.744133 -0.640919 0.188269 +vn 0.744133 -0.640919 0.188269 +vn 0.906766 -0.008332 0.421522 +vn -0.044191 -0.974395 0.220313 +vn 0.044191 -0.974395 0.220313 +vn 0.639943 -0.761498 0.102786 +vn -0.639943 -0.761498 0.102786 +vn 0.955504 -0.011444 0.294717 +vn -0.955504 -0.011444 0.294717 +vn 0.649678 0.754387 0.093570 +vn -0.649678 0.754387 0.093570 +vn -0.037049 0.978881 0.200903 +vn 0.037049 0.978881 0.200903 +vn -0.752342 0.635395 0.173742 +vn 0.752342 0.635395 0.173742 +vn -0.811792 -0.002777 0.583880 +vn -0.596942 0.486770 0.637684 +vn 0.596942 0.486770 0.637684 +vn 0.811792 -0.002777 0.583880 +vn -0.868221 -0.005829 0.496109 +vn -0.719504 0.473006 0.508469 +vn 0.719504 0.473006 0.508469 +vn 0.868221 -0.005829 0.496109 +vn -0.204260 0.828761 0.520951 +vn -0.095767 0.717277 0.690146 +vn 0.095767 0.717277 0.690146 +vn 0.204260 0.828761 0.520951 +vn 0.451704 0.459883 0.764458 +vn -0.451704 0.459883 0.764458 +vn 0.450362 0.693899 0.561815 +vn -0.450362 0.693899 0.561815 +vn 0.805536 0.109409 0.582324 +vn 0.691488 -0.074099 0.718558 +vn -0.691488 -0.074099 0.718558 +vn -0.805536 0.109409 0.582324 +vn 0.386212 -0.474685 0.790857 +vn -0.386212 -0.474685 0.790857 +vn 0.557756 -0.629109 0.541368 +vn -0.557756 -0.629109 0.541368 +vn -0.091159 -0.723716 0.684011 +vn -0.199744 -0.858058 0.473067 +vn 0.091159 -0.723716 0.684011 +vn 0.199744 -0.858058 0.473067 +vn -0.597949 -0.496475 0.629231 +vn 0.597949 -0.496475 0.629231 +vn -0.723197 -0.488907 0.487747 +vn 0.723197 -0.488907 0.487747 +usemtl Material_ray.png +s 1 +f 61/1/1 65/2/2 49/3/3 +f 50/4/4 66/5/5 62/6/6 +f 63/7/7 65/2/2 61/1/1 +f 62/6/6 66/5/5 64/8/8 +f 61/1/1 59/9/9 63/7/7 +f 64/8/8 60/10/10 62/6/6 +f 61/1/1 57/11/11 59/9/9 +f 60/10/10 58/12/12 62/6/6 +f 61/1/1 55/13/13 57/11/11 +f 58/12/12 56/14/14 62/6/6 +f 61/1/1 53/15/15 55/13/13 +f 56/14/14 54/16/16 62/6/6 +f 61/1/1 51/17/17 53/15/15 +f 54/16/16 52/18/18 62/6/6 +f 61/1/1 49/3/3 51/17/17 +f 52/18/18 50/4/4 62/6/6 +f 225/19/19 229/20/20 227/21/21 +f 228/22/22 230/23/23 226/24/24 +f 73/25/25 284/26/26 74/27/27 +f 74/28/27 285/29/28 73/30/25 +f 342/31/29 348/32/30 384/33/31 +f 385/34/32 349/35/33 343/36/34 +f 300/37/35 346/38/36 344/39/37 +f 345/40/38 347/41/39 301/42/40 +f 324/43/41 380/44/42 352/45/43 +f 353/46/44 381/47/45 325/48/46 +f 442/49/47 444/50/48 446/51/49 +f 447/52/50 445/53/51 443/54/52 +f 464/55/53 492/56/54 466/57/55 +f 467/58/56 493/59/57 465/60/58 +f 496/61/59 498/62/60 500/63/61 +f 501/64/62 499/65/63 497/66/64 +f 505/67/65 323/68/66 321/69/67 +f 505/67/65 321/69/67 391/70/68 +f 320/71/69 322/72/70 504/73/71 +f 320/71/69 504/73/71 390/74/72 +f 505/67/65 507/75/73 315/76/74 +f 505/67/65 315/76/74 323/68/66 +f 314/77/75 506/78/76 504/73/71 +f 314/77/75 504/73/71 322/72/70 +f 389/79/77 383/80/78 507/75/73 +f 383/80/78 315/76/74 507/75/73 +f 314/77/75 382/81/79 506/78/76 +f 382/81/79 388/82/80 506/78/76 +f 501/64/62 497/66/64 495/83/81 +f 501/64/62 495/83/81 503/84/82 +f 494/85/83 496/61/59 500/63/61 +f 494/85/83 500/63/61 502/86/84 +f 505/67/65 503/84/82 507/75/73 +f 503/84/82 495/83/81 507/75/73 +f 494/85/83 502/86/84 506/78/76 +f 502/86/84 504/73/71 506/78/76 +f 495/83/81 401/87/85 507/75/73 +f 401/87/85 389/79/77 507/75/73 +f 388/82/80 400/88/86 506/78/76 +f 400/88/86 494/85/83 506/78/76 +f 497/66/64 399/89/87 495/83/81 +f 399/89/87 401/87/85 495/83/81 +f 400/88/86 398/90/88 494/85/83 +f 398/90/88 496/61/59 494/85/83 +f 499/65/63 397/91/89 497/66/64 +f 397/91/89 399/89/87 497/66/64 +f 398/90/88 396/92/90 496/61/59 +f 396/92/90 498/62/60 496/61/59 +f 501/64/62 395/93/91 499/65/63 +f 395/93/91 397/91/89 499/65/63 +f 396/92/90 394/94/92 498/62/60 +f 394/94/92 500/63/61 498/62/60 +f 503/84/82 393/95/93 395/93/91 +f 503/84/82 395/93/91 501/64/62 +f 394/94/92 392/96/94 502/86/84 +f 394/94/92 502/86/84 500/63/61 +f 505/67/65 391/70/68 393/95/93 +f 505/67/65 393/95/93 503/84/82 +f 392/96/94 390/74/72 504/73/71 +f 392/96/94 504/73/71 502/86/84 +f 491/97/95 493/59/57 467/58/56 +f 491/97/95 467/58/56 469/98/96 +f 466/57/55 492/56/54 490/99/97 +f 466/57/55 490/99/97 468/100/98 +f 489/101/99 491/97/95 471/102/100 +f 491/97/95 469/98/96 471/102/100 +f 468/100/98 490/99/97 470/103/101 +f 490/99/97 488/104/102 470/103/101 +f 483/105/103 489/101/99 473/106/104 +f 489/101/99 471/102/100 473/106/104 +f 470/103/101 488/104/102 472/107/105 +f 488/104/102 482/108/106 472/107/105 +f 481/109/107 483/105/103 473/106/104 +f 481/109/107 473/106/104 475/110/108 +f 472/107/105 482/108/106 480/111/109 +f 472/107/105 480/111/109 474/112/110 +f 481/109/107 475/110/108 457/113/111 +f 475/110/108 455/114/112 457/113/111 +f 454/115/113 474/112/110 456/116/114 +f 474/112/110 480/111/109 456/116/114 +f 463/117/115 479/118/116 459/119/117 +f 463/117/115 459/119/117 461/120/118 +f 458/121/119 478/122/120 462/123/121 +f 458/121/119 462/123/121 460/124/122 +f 479/118/116 463/117/115 485/125/123 +f 463/117/115 453/126/124 485/125/123 +f 452/127/125 462/123/121 484/128/126 +f 462/123/121 478/122/120 484/128/126 +f 487/129/127 485/125/123 477/130/128 +f 485/125/123 453/126/124 477/130/128 +f 452/127/125 484/128/126 476/131/129 +f 484/128/126 486/132/130 476/131/129 +f 487/129/127 477/130/128 465/60/58 +f 487/129/127 465/60/58 493/59/57 +f 464/55/53 476/131/129 486/132/130 +f 464/55/53 486/132/130 492/56/54 +f 491/97/95 489/101/99 493/59/57 +f 489/101/99 487/129/127 493/59/57 +f 486/132/130 488/104/102 492/56/54 +f 488/104/102 490/99/97 492/56/54 +f 489/101/99 483/105/103 485/125/123 +f 489/101/99 485/125/123 487/129/127 +f 484/128/126 482/108/106 488/104/102 +f 484/128/126 488/104/102 486/132/130 +f 483/105/103 481/109/107 485/125/123 +f 481/109/107 479/118/116 485/125/123 +f 478/122/120 480/111/109 484/128/126 +f 480/111/109 482/108/106 484/128/126 +f 481/109/107 457/113/111 479/118/116 +f 457/113/111 459/119/117 479/118/116 +f 458/121/119 456/116/114 478/122/120 +f 456/116/114 480/111/109 478/122/120 +f 473/106/104 421/133/131 475/110/108 +f 421/133/131 419/134/132 475/110/108 +f 418/135/133 420/136/134 474/112/110 +f 420/136/134 472/107/105 474/112/110 +f 471/102/100 423/137/135 473/106/104 +f 423/137/135 421/133/131 473/106/104 +f 420/136/134 422/138/136 472/107/105 +f 422/138/136 470/103/101 472/107/105 +f 469/98/96 425/139/137 471/102/100 +f 425/139/137 423/137/135 471/102/100 +f 422/138/136 424/140/138 470/103/101 +f 424/140/138 468/100/98 470/103/101 +f 467/58/56 427/141/139 425/139/137 +f 467/58/56 425/139/137 469/98/96 +f 424/140/138 426/142/140 466/57/55 +f 424/140/138 466/57/55 468/100/98 +f 465/60/58 429/143/141 427/141/139 +f 465/60/58 427/141/139 467/58/56 +f 426/142/140 428/144/142 464/55/53 +f 426/142/140 464/55/53 466/57/55 +f 477/130/128 417/145/143 429/143/141 +f 477/130/128 429/143/141 465/60/58 +f 428/144/142 416/146/144 476/131/129 +f 428/144/142 476/131/129 464/55/53 +f 475/110/108 419/134/132 441/147/145 +f 475/110/108 441/147/145 455/114/112 +f 440/148/146 418/135/133 474/112/110 +f 440/148/146 474/112/110 454/115/113 +f 455/114/112 441/147/145 439/149/147 +f 455/114/112 439/149/147 457/113/111 +f 438/150/148 440/148/146 454/115/113 +f 438/150/148 454/115/113 456/116/114 +f 457/113/111 439/149/147 459/119/117 +f 439/149/147 437/151/149 459/119/117 +f 436/152/150 438/150/148 458/121/119 +f 438/150/148 456/116/114 458/121/119 +f 459/119/117 437/151/149 461/120/118 +f 437/151/149 435/153/151 461/120/118 +f 434/154/152 436/152/150 460/124/122 +f 436/152/150 458/121/119 460/124/122 +f 461/120/118 435/153/151 433/155/153 +f 461/120/118 433/155/153 463/117/115 +f 432/156/154 434/154/152 460/124/122 +f 432/156/154 460/124/122 462/123/121 +f 463/117/115 433/155/153 453/126/124 +f 433/155/153 451/157/155 453/126/124 +f 450/158/156 432/156/154 452/127/125 +f 432/156/154 462/123/121 452/127/125 +f 453/126/124 451/157/155 417/145/143 +f 453/126/124 417/145/143 477/130/128 +f 416/146/144 450/158/156 452/127/125 +f 416/146/144 452/127/125 476/131/129 +f 447/52/50 443/54/52 449/159/157 +f 443/54/52 313/160/158 449/159/157 +f 312/161/159 442/49/47 448/162/160 +f 442/49/47 446/51/49 448/162/160 +f 431/163/161 449/159/157 383/80/78 +f 449/159/157 313/160/158 383/80/78 +f 312/161/159 448/162/160 382/164/79 +f 448/162/160 430/165/162 382/164/79 +f 451/157/155 431/163/161 417/145/143 +f 431/163/161 415/166/163 417/145/143 +f 414/167/164 430/165/162 416/146/144 +f 430/165/162 450/158/156 416/146/144 +f 433/155/153 449/159/157 451/157/155 +f 449/159/157 431/163/161 451/157/155 +f 430/165/162 448/162/160 450/158/156 +f 448/162/160 432/156/154 450/158/156 +f 447/52/50 449/159/157 435/153/151 +f 449/159/157 433/155/153 435/153/151 +f 432/156/154 448/162/160 434/154/152 +f 448/162/160 446/51/49 434/154/152 +f 439/149/147 447/52/50 435/153/151 +f 439/149/147 435/153/151 437/151/149 +f 434/154/152 446/51/49 438/150/148 +f 434/154/152 438/150/148 436/152/150 +f 445/53/51 447/52/50 441/147/145 +f 447/52/50 439/149/147 441/147/145 +f 438/150/148 446/51/49 440/148/146 +f 446/51/49 444/50/48 440/148/146 +f 441/147/145 419/134/132 413/168/165 +f 441/147/145 413/168/165 445/53/51 +f 412/169/166 418/135/133 440/148/146 +f 412/169/166 440/148/146 444/50/48 +f 415/166/163 431/163/161 383/80/78 +f 415/166/163 383/80/78 389/79/77 +f 382/164/79 430/165/162 414/167/164 +f 382/164/79 414/167/164 388/170/80 +f 443/171/52 319/172/167 311/173/168 +f 443/171/52 311/173/168 313/174/158 +f 310/175/169 318/176/170 442/177/47 +f 310/175/169 442/177/47 312/178/159 +f 413/168/165 391/179/68 445/53/51 +f 391/179/68 321/180/67 445/53/51 +f 320/181/69 390/182/72 444/50/48 +f 390/182/72 412/169/166 444/50/48 +f 445/53/51 321/180/67 443/54/52 +f 321/183/67 319/172/167 443/171/52 +f 318/176/170 320/184/69 442/177/47 +f 320/181/69 444/50/48 442/49/47 +f 417/145/143 415/166/163 403/185/171 +f 417/145/143 403/185/171 429/143/141 +f 402/186/172 414/167/164 416/146/144 +f 402/186/172 416/146/144 428/144/142 +f 427/141/139 429/143/141 405/187/173 +f 429/143/141 403/185/171 405/187/173 +f 402/186/172 428/144/142 404/188/174 +f 428/144/142 426/142/140 404/188/174 +f 425/139/137 427/141/139 407/189/175 +f 427/141/139 405/187/173 407/189/175 +f 404/188/174 426/142/140 406/190/176 +f 426/142/140 424/140/138 406/190/176 +f 423/137/135 425/139/137 409/191/177 +f 425/139/137 407/189/175 409/191/177 +f 406/190/176 424/140/138 408/192/178 +f 424/140/138 422/138/136 408/192/178 +f 421/133/131 423/137/135 409/191/177 +f 421/133/131 409/191/177 411/193/179 +f 408/192/178 422/138/136 420/136/134 +f 408/192/178 420/136/134 410/194/180 +f 419/134/132 421/133/131 411/193/179 +f 419/134/132 411/193/179 413/168/165 +f 410/194/180 420/136/134 418/135/133 +f 410/194/180 418/135/133 412/169/166 +f 413/168/165 411/193/179 393/195/93 +f 413/168/165 393/195/93 391/179/68 +f 392/196/94 410/194/180 412/169/166 +f 392/196/94 412/169/166 390/182/72 +f 411/193/179 409/191/177 393/195/93 +f 409/191/177 395/197/91 393/195/93 +f 394/198/92 408/192/178 392/196/94 +f 408/192/178 410/194/180 392/196/94 +f 409/191/177 407/189/175 395/197/91 +f 407/189/175 397/199/89 395/197/91 +f 396/200/90 406/190/176 394/198/92 +f 406/190/176 408/192/178 394/198/92 +f 407/189/175 405/187/173 397/199/89 +f 405/187/173 399/89/87 397/199/89 +f 398/201/88 404/188/174 396/200/90 +f 404/188/174 406/190/176 396/200/90 +f 405/187/173 403/185/171 401/87/85 +f 405/187/173 401/87/85 399/89/87 +f 400/202/86 402/186/172 404/188/174 +f 400/202/86 404/188/174 398/201/88 +f 415/166/163 389/79/77 403/185/171 +f 389/79/77 401/87/85 403/185/171 +f 400/202/86 388/170/80 402/186/172 +f 388/170/80 414/167/164 402/186/172 +f 381/47/45 353/46/44 387/203/181 +f 353/46/44 351/204/182 387/203/181 +f 350/205/183 352/45/43 386/206/184 +f 352/45/43 380/44/42 386/206/184 +f 381/47/45 387/203/181 323/207/66 +f 387/203/181 321/183/67 323/207/66 +f 320/184/69 386/206/184 322/208/70 +f 386/206/184 380/44/42 322/208/70 +f 381/47/45 379/209/185 325/48/46 +f 379/209/185 317/210/186 325/48/46 +f 316/211/187 378/212/188 324/43/41 +f 378/212/188 380/44/42 324/43/41 +f 381/47/45 323/207/66 379/209/185 +f 323/207/66 315/213/74 379/209/185 +f 314/214/75 322/208/70 378/212/188 +f 322/208/70 380/44/42 378/212/188 +f 343/36/34 345/40/38 301/42/40 +f 343/36/34 301/42/40 385/34/32 +f 300/37/35 344/39/37 342/31/29 +f 300/37/35 342/31/29 384/33/31 +f 385/34/32 301/42/40 299/215/189 +f 385/34/32 299/215/189 319/172/167 +f 298/216/190 300/37/35 384/33/31 +f 298/216/190 384/33/31 318/176/170 +f 387/203/181 385/34/32 321/183/67 +f 385/34/32 319/172/167 321/183/67 +f 318/176/170 384/33/31 320/184/69 +f 384/33/31 386/206/184 320/184/69 +f 387/203/181 351/204/182 385/34/32 +f 351/204/182 349/35/33 385/34/32 +f 348/32/30 350/205/183 384/33/31 +f 350/205/183 386/206/184 384/33/31 +f 371/217/191 377/218/192 383/219/78 +f 377/218/192 315/213/74 383/219/78 +f 314/214/75 376/220/193 382/221/79 +f 376/220/193 370/222/194 382/221/79 +f 371/217/191 383/219/78 313/174/158 +f 371/217/191 313/174/158 369/223/195 +f 312/178/159 382/221/79 370/222/194 +f 312/178/159 370/222/194 368/224/196 +f 369/223/195 313/174/158 311/173/168 +f 369/223/195 311/173/168 363/225/197 +f 310/175/169 312/178/159 368/224/196 +f 310/175/169 368/224/196 362/226/198 +f 311/173/168 297/227/199 363/225/197 +f 297/227/199 295/228/200 363/225/197 +f 294/229/201 296/230/202 362/226/198 +f 296/230/202 310/175/169 362/226/198 +f 361/231/203 291/232/204 285/29/28 +f 361/231/203 285/29/28 74/28/27 +f 284/26/26 290/233/205 360/234/206 +f 284/26/26 360/234/206 74/27/27 +f 289/235/207 287/236/208 291/232/204 +f 287/236/208 285/29/28 291/232/204 +f 284/26/26 286/237/209 290/233/205 +f 286/237/209 288/238/210 290/233/205 +f 359/239/211 361/231/203 302/240/212 +f 361/231/203 74/28/27 302/240/212 +f 74/27/27 360/234/206 302/241/212 +f 360/234/206 358/242/213 302/241/212 +f 365/243/214 293/244/215 361/231/203 +f 293/244/215 291/232/204 361/231/203 +f 290/233/205 292/245/216 360/234/206 +f 292/245/216 364/246/217 360/234/206 +f 365/243/214 361/231/203 359/239/211 +f 365/243/214 359/239/211 367/247/218 +f 358/242/213 360/234/206 364/246/217 +f 358/242/213 364/246/217 366/248/219 +f 367/247/218 359/239/211 357/249/220 +f 367/247/218 357/249/220 373/250/221 +f 356/251/222 358/242/213 366/248/219 +f 356/251/222 366/248/219 372/252/223 +f 373/250/221 357/249/220 355/253/224 +f 373/250/221 355/253/224 375/254/225 +f 354/255/226 356/251/222 372/252/223 +f 354/255/226 372/252/223 374/256/227 +f 375/254/225 355/253/224 317/210/186 +f 375/254/225 317/210/186 379/209/185 +f 316/211/187 354/255/226 374/256/227 +f 316/211/187 374/256/227 378/212/188 +f 375/254/225 379/209/185 377/218/192 +f 379/209/185 315/213/74 377/218/192 +f 314/214/75 378/212/188 376/220/193 +f 378/212/188 374/256/227 376/220/193 +f 377/218/192 371/217/191 373/250/221 +f 377/218/192 373/250/221 375/254/225 +f 372/252/223 370/222/194 376/220/193 +f 372/252/223 376/220/193 374/256/227 +f 371/217/191 369/223/195 367/247/218 +f 371/217/191 367/247/218 373/250/221 +f 366/248/219 368/224/196 370/222/194 +f 366/248/219 370/222/194 372/252/223 +f 369/223/195 363/225/197 365/243/214 +f 369/223/195 365/243/214 367/247/218 +f 364/246/217 362/226/198 368/224/196 +f 364/246/217 368/224/196 366/248/219 +f 363/225/197 295/228/200 293/244/215 +f 363/225/197 293/244/215 365/243/214 +f 292/245/216 294/229/201 362/226/198 +f 292/245/216 362/226/198 364/246/217 +f 317/210/186 355/253/224 75/257/228 +f 317/210/186 75/257/228 76/258/229 +f 75/259/228 354/255/226 316/211/187 +f 75/259/228 316/211/187 76/260/229 +f 355/253/224 357/249/220 303/261/230 +f 355/253/224 303/261/230 75/257/228 +f 303/262/230 356/251/222 354/255/226 +f 303/262/230 354/255/226 75/259/228 +f 357/249/220 359/239/211 303/261/230 +f 359/239/211 302/240/212 303/261/230 +f 302/241/212 358/242/213 303/262/230 +f 358/242/213 356/251/222 303/262/230 +f 325/48/46 317/210/186 77/263/231 +f 317/210/186 76/258/229 77/263/231 +f 76/260/229 316/211/187 77/264/231 +f 316/211/187 324/43/41 77/264/231 +f 319/172/167 299/215/189 297/227/199 +f 319/172/167 297/227/199 311/173/168 +f 296/230/202 298/216/190 318/176/170 +f 296/230/202 318/176/170 310/175/169 +f 349/35/33 329/265/232 343/36/34 +f 329/265/232 327/266/233 343/36/34 +f 326/267/234 328/268/235 342/31/29 +f 328/268/235 348/32/30 342/31/29 +f 329/265/232 349/35/33 305/269/236 +f 329/265/232 305/269/236 309/270/237 +f 305/271/236 348/32/30 328/268/235 +f 305/271/236 328/268/235 309/272/237 +f 349/35/33 351/204/182 78/273/238 +f 349/35/33 78/273/238 305/269/236 +f 78/274/238 350/205/183 348/32/30 +f 78/274/238 348/32/30 305/271/236 +f 351/204/182 353/46/44 78/273/238 +f 353/46/44 304/275/239 78/273/238 +f 304/276/239 352/45/43 78/274/238 +f 352/45/43 350/205/183 78/274/238 +f 353/46/44 325/48/46 304/275/239 +f 325/48/46 77/263/231 304/275/239 +f 77/264/231 324/43/41 304/276/239 +f 324/43/41 352/45/43 304/276/239 +f 301/42/40 347/41/39 93/277/240 +f 347/278/39 80/279/241 93/280/240 +f 79/281/242 346/282/36 92/283/243 +f 346/38/36 300/37/35 92/284/243 +f 345/40/38 216/285/244 347/41/39 +f 216/286/244 80/279/241 347/278/39 +f 79/281/242 215/287/245 346/282/36 +f 215/288/245 344/39/37 346/38/36 +f 343/36/34 327/266/233 210/289/246 +f 327/266/233 82/290/247 210/289/246 +f 81/291/248 326/267/234 209/292/249 +f 326/267/234 342/31/29 209/292/249 +f 345/40/38 343/36/34 216/285/244 +f 343/36/34 210/289/246 216/285/244 +f 209/292/249 342/31/29 215/288/245 +f 342/31/29 344/39/37 215/288/245 +f 333/293/250 84/294/251 82/290/247 +f 333/293/250 82/290/247 327/266/233 +f 81/291/248 83/295/252 332/296/253 +f 81/291/248 332/296/253 326/267/234 +f 339/297/254 333/293/250 329/265/232 +f 333/293/250 327/266/233 329/265/232 +f 326/267/234 332/296/253 328/268/235 +f 332/296/253 338/298/255 328/268/235 +f 341/299/256 335/300/257 337/301/258 +f 335/300/257 331/302/259 337/301/258 +f 330/303/260 334/304/261 336/305/262 +f 334/304/261 340/306/263 336/305/262 +f 339/297/254 337/301/258 331/302/259 +f 339/297/254 331/302/259 333/293/250 +f 330/303/260 336/305/262 338/298/255 +f 330/303/260 338/298/255 332/296/253 +f 331/302/259 86/307/264 84/294/251 +f 331/302/259 84/294/251 333/293/250 +f 83/295/252 85/308/265 330/303/260 +f 83/295/252 330/303/260 332/296/253 +f 335/300/257 88/309/266 86/307/264 +f 335/300/257 86/307/264 331/302/259 +f 85/308/265 87/310/267 334/304/261 +f 85/308/265 334/304/261 330/303/260 +f 341/299/256 90/311/268 88/309/266 +f 341/299/256 88/309/266 335/300/257 +f 87/310/267 89/312/269 340/306/263 +f 87/310/267 340/306/263 334/304/261 +f 306/313/270 91/314/271 90/311/268 +f 306/313/270 90/311/268 341/299/256 +f 89/312/269 91/315/271 306/316/270 +f 89/312/269 306/316/270 340/306/263 +f 337/301/258 307/317/272 341/299/256 +f 307/317/272 306/313/270 341/299/256 +f 306/316/270 307/318/272 340/306/263 +f 307/318/272 336/305/262 340/306/263 +f 339/297/254 308/319/273 337/301/258 +f 308/319/273 307/317/272 337/301/258 +f 307/318/272 308/320/273 336/305/262 +f 308/320/273 338/298/255 336/305/262 +f 329/265/232 309/270/237 339/297/254 +f 309/270/237 308/319/273 339/297/254 +f 308/320/273 309/272/237 338/298/255 +f 309/272/237 328/268/235 338/298/255 +f 301/42/40 93/277/240 95/321/274 +f 301/42/40 95/321/274 299/215/189 +f 94/322/275 92/284/243 300/37/35 +f 94/322/275 300/37/35 298/216/190 +f 299/215/189 95/321/274 97/323/276 +f 299/215/189 97/323/276 297/227/199 +f 96/324/277 94/322/275 298/216/190 +f 96/324/277 298/216/190 296/230/202 +f 297/227/199 97/323/276 295/228/200 +f 97/323/276 99/325/278 295/228/200 +f 98/326/279 96/324/277 294/229/201 +f 96/324/277 296/230/202 294/229/201 +f 295/228/200 99/325/278 101/327/280 +f 295/228/200 101/327/280 293/244/215 +f 100/328/281 98/326/279 294/229/201 +f 100/328/281 294/229/201 292/245/216 +f 293/244/215 101/327/280 291/232/204 +f 101/327/280 103/329/282 291/232/204 +f 102/330/283 100/328/281 290/233/205 +f 100/328/281 292/245/216 290/233/205 +f 291/232/204 103/329/282 289/235/207 +f 103/329/282 105/331/284 289/235/207 +f 104/332/285 102/330/283 288/238/210 +f 102/330/283 290/233/205 288/238/210 +f 289/235/207 105/331/284 287/236/208 +f 105/331/284 107/333/286 287/236/208 +f 106/334/287 104/332/285 286/237/209 +f 104/332/285 288/238/210 286/237/209 +f 287/236/208 107/333/286 109/335/288 +f 287/236/208 109/335/288 285/29/28 +f 108/336/289 106/334/287 286/237/209 +f 108/336/289 286/237/209 284/26/26 +f 285/29/28 109/335/288 67/337/290 +f 285/29/28 67/337/290 73/30/25 +f 67/338/290 108/336/289 284/26/26 +f 67/338/290 284/26/26 73/25/25 +f 281/339/291 235/340/292 233/341/293 +f 281/339/291 233/341/293 283/342/294 +f 232/343/295 234/344/296 280/345/297 +f 232/343/295 280/345/297 282/346/298 +f 283/342/294 233/341/293 255/347/299 +f 283/342/294 255/347/299 261/348/300 +f 254/349/301 232/343/295 282/346/298 +f 254/349/301 282/346/298 260/350/302 +f 261/348/300 255/347/299 257/351/303 +f 261/348/300 257/351/303 259/352/304 +f 256/353/305 254/349/301 260/350/302 +f 256/353/305 260/350/302 258/354/306 +f 263/355/307 253/356/308 235/340/292 +f 263/355/307 235/340/292 281/339/291 +f 234/344/296 252/357/309 262/358/310 +f 234/344/296 262/358/310 280/345/297 +f 265/359/311 251/360/312 263/355/307 +f 251/360/312 253/356/308 263/355/307 +f 252/357/309 250/361/313 262/358/310 +f 250/361/313 264/362/314 262/358/310 +f 267/363/315 249/364/316 265/359/311 +f 249/364/316 251/360/312 265/359/311 +f 250/361/313 248/365/317 264/362/314 +f 248/365/317 266/366/318 264/362/314 +f 269/367/319 247/368/320 249/364/316 +f 269/367/319 249/364/316 267/363/315 +f 248/365/317 246/369/321 268/370/322 +f 248/365/317 268/370/322 266/366/318 +f 271/371/323 245/372/324 269/367/319 +f 245/372/324 247/368/320 269/367/319 +f 246/369/321 244/373/325 268/370/322 +f 244/373/325 270/374/326 268/370/322 +f 273/375/327 243/376/328 245/372/324 +f 273/375/327 245/372/324 271/371/323 +f 244/373/325 242/377/329 272/378/330 +f 244/373/325 272/378/330 270/374/326 +f 275/379/331 241/380/332 273/375/327 +f 241/380/332 243/376/328 273/375/327 +f 242/377/329 240/381/333 272/378/330 +f 240/381/333 274/382/334 272/378/330 +f 279/383/335 237/384/336 275/379/331 +f 237/384/336 241/380/332 275/379/331 +f 240/381/333 236/385/337 274/382/334 +f 236/385/337 278/386/338 274/382/334 +f 277/387/339 239/388/340 237/384/336 +f 277/387/339 237/384/336 279/383/335 +f 236/385/337 238/389/341 276/390/342 +f 236/385/337 276/390/342 278/386/338 +f 259/352/304 257/351/303 239/388/340 +f 259/352/304 239/388/340 277/387/339 +f 238/389/341 256/353/305 258/354/306 +f 238/389/341 258/354/306 276/390/342 +f 257/351/303 111/391/343 129/392/344 +f 257/351/303 129/392/344 239/388/340 +f 128/393/345 110/394/346 256/353/305 +f 128/393/345 256/353/305 238/389/341 +f 239/388/340 129/392/344 180/395/347 +f 239/388/340 180/395/347 237/384/336 +f 179/396/348 128/393/345 238/389/341 +f 179/396/348 238/389/341 236/385/337 +f 237/384/336 180/395/347 127/397/349 +f 237/384/336 127/397/349 241/380/332 +f 126/398/350 179/396/348 236/385/337 +f 126/398/350 236/385/337 240/381/333 +f 241/380/332 127/397/349 243/376/328 +f 127/397/349 125/399/351 243/376/328 +f 124/400/352 126/398/350 242/377/329 +f 126/398/350 240/381/333 242/377/329 +f 243/376/328 125/399/351 245/372/324 +f 125/399/351 123/401/353 245/372/324 +f 122/402/354 124/400/352 244/373/325 +f 124/400/352 242/377/329 244/373/325 +f 245/372/324 123/401/353 121/403/355 +f 245/372/324 121/403/355 247/368/320 +f 120/404/356 122/402/354 244/373/325 +f 120/404/356 244/373/325 246/369/321 +f 247/368/320 121/403/355 119/405/357 +f 247/368/320 119/405/357 249/364/316 +f 118/406/358 120/404/356 246/369/321 +f 118/406/358 246/369/321 248/365/317 +f 249/364/316 119/405/357 117/407/359 +f 249/364/316 117/407/359 251/360/312 +f 116/408/360 118/406/358 248/365/317 +f 116/408/360 248/365/317 250/361/313 +f 251/360/312 117/407/359 115/409/361 +f 251/360/312 115/409/361 253/356/308 +f 114/410/362 116/408/360 250/361/313 +f 114/410/362 250/361/313 252/357/309 +f 253/356/308 115/409/361 235/340/292 +f 115/409/361 182/411/363 235/340/292 +f 181/412/364 114/410/362 234/344/296 +f 114/410/362 252/357/309 234/344/296 +f 255/347/299 113/413/365 257/351/303 +f 113/413/365 111/391/343 257/351/303 +f 110/394/346 112/414/366 256/353/305 +f 112/414/366 254/349/301 256/353/305 +f 233/341/293 184/415/367 113/413/365 +f 233/341/293 113/413/365 255/347/299 +f 112/414/366 183/416/368 232/343/295 +f 112/414/366 232/343/295 254/349/301 +f 235/340/292 182/411/363 184/415/367 +f 235/340/292 184/415/367 233/341/293 +f 183/416/368 181/412/364 234/344/296 +f 183/416/368 234/344/296 232/343/295 +f 230/23/23 231/417/369 224/418/370 +f 230/23/23 224/418/370 226/24/24 +f 224/418/370 231/417/369 229/20/20 +f 224/418/370 229/20/20 225/19/19 +f 224/418/370 72/419/371 226/24/24 +f 72/419/371 223/420/372 226/24/24 +f 222/421/373 72/419/371 225/19/19 +f 72/419/371 224/418/370 225/19/19 +f 226/24/24 223/420/372 221/422/374 +f 226/24/24 221/422/374 228/22/22 +f 220/423/375 222/421/373 225/19/19 +f 220/423/375 225/19/19 227/21/21 +f 228/22/22 221/422/374 219/424/376 +f 228/22/22 219/424/376 230/23/23 +f 218/425/377 220/423/375 227/21/21 +f 218/425/377 227/21/21 229/20/20 +f 230/23/23 219/424/376 231/417/369 +f 219/424/376 217/426/378 231/417/369 +f 217/426/378 218/425/377 231/417/369 +f 218/425/377 229/20/20 231/417/369 +f 219/424/376 136/427/379 137/428/380 +f 219/424/376 137/428/380 217/426/378 +f 137/428/380 135/429/381 218/425/377 +f 137/428/380 218/425/377 217/426/378 +f 221/422/374 134/430/382 136/427/379 +f 221/422/374 136/427/379 219/424/376 +f 135/429/381 133/431/383 220/423/375 +f 135/429/381 220/423/375 218/425/377 +f 223/420/372 132/432/384 134/430/382 +f 223/420/372 134/430/382 221/422/374 +f 133/431/383 131/433/385 222/421/373 +f 133/431/383 222/421/373 220/423/375 +f 72/419/371 130/434/386 223/420/372 +f 130/434/386 132/432/384 223/420/372 +f 131/433/385 130/434/386 222/421/373 +f 130/434/386 72/419/371 222/421/373 +f 212/435/387 165/436/388 80/279/241 +f 212/435/387 80/279/241 216/286/244 +f 79/281/242 164/437/389 211/438/390 +f 79/281/242 211/438/390 215/287/245 +f 212/435/387 216/286/244 214/439/391 +f 216/286/244 210/440/246 214/439/391 +f 209/441/249 215/287/245 213/442/392 +f 215/287/245 211/438/390 213/442/392 +f 214/439/391 210/440/246 167/443/393 +f 210/440/246 82/444/247 167/443/393 +f 81/445/248 209/441/249 166/446/394 +f 209/441/249 213/442/392 166/446/394 +f 167/443/393 188/447/395 214/439/391 +f 188/447/395 145/448/396 214/439/391 +f 144/449/397 187/450/398 213/442/392 +f 187/450/398 166/446/394 213/442/392 +f 214/439/391 145/448/396 212/435/387 +f 145/448/396 143/451/399 212/435/387 +f 142/452/400 144/449/397 211/438/390 +f 144/449/397 213/442/392 211/438/390 +f 212/435/387 143/451/399 141/453/401 +f 212/435/387 141/453/401 165/436/388 +f 140/454/402 142/452/400 211/438/390 +f 140/454/402 211/438/390 164/437/389 +f 165/436/388 141/453/401 139/455/403 +f 165/436/388 139/455/403 177/456/404 +f 139/455/403 140/454/402 164/437/389 +f 139/455/403 164/437/389 177/456/404 +f 207/457/405 208/458/406 199/459/407 +f 207/457/405 199/459/407 205/460/408 +f 199/459/407 208/458/406 206/461/409 +f 199/459/407 206/461/409 204/462/410 +f 203/463/411 205/460/408 201/464/412 +f 205/460/408 199/459/407 201/464/412 +f 199/459/407 204/462/410 200/465/413 +f 204/462/410 202/466/414 200/465/413 +f 207/457/405 205/460/408 194/467/415 +f 207/457/405 194/467/415 192/468/416 +f 193/469/417 204/462/410 206/461/409 +f 193/469/417 206/461/409 191/470/418 +f 205/460/408 203/463/411 194/467/415 +f 203/463/411 196/471/419 194/467/415 +f 195/472/420 202/466/414 193/469/417 +f 202/466/414 204/462/410 193/469/417 +f 203/463/411 201/464/412 198/473/421 +f 203/463/411 198/473/421 196/471/419 +f 197/474/422 200/465/413 202/466/414 +f 197/474/422 202/466/414 195/472/420 +f 201/464/412 199/459/407 71/475/423 +f 201/464/412 71/475/423 198/473/421 +f 71/475/423 199/459/407 200/465/413 +f 71/475/423 200/465/413 197/474/422 +f 207/457/405 192/468/416 208/458/406 +f 192/468/416 70/476/424 208/458/406 +f 70/476/424 191/470/418 208/458/406 +f 191/470/418 206/461/409 208/458/406 +f 192/468/416 145/448/396 70/476/424 +f 145/448/396 190/477/425 70/476/424 +f 190/477/425 144/449/397 70/476/424 +f 144/449/397 191/470/418 70/476/424 +f 198/473/421 71/475/423 139/455/403 +f 71/478/423 138/479/426 139/480/403 +f 138/481/426 71/482/423 139/483/403 +f 71/475/423 197/474/422 139/455/403 +f 196/471/419 198/473/421 141/453/401 +f 198/473/421 139/455/403 141/453/401 +f 139/455/403 197/474/422 140/454/402 +f 197/474/422 195/472/420 140/454/402 +f 194/467/415 196/471/419 143/451/399 +f 196/471/419 141/453/401 143/451/399 +f 140/454/402 195/472/420 142/452/400 +f 195/472/420 193/469/417 142/452/400 +f 192/468/416 194/467/415 143/451/399 +f 192/468/416 143/451/399 145/448/396 +f 142/452/400 193/469/417 191/470/418 +f 142/452/400 191/470/418 144/449/397 +f 186/484/427 132/432/384 69/485/428 +f 132/432/384 130/434/386 69/485/428 +f 130/434/386 131/433/385 69/485/428 +f 131/433/385 185/486/429 69/485/428 +f 189/487/430 188/447/395 69/485/428 +f 188/447/395 186/484/427 69/485/428 +f 185/486/429 187/450/398 69/485/428 +f 187/450/398 189/487/430 69/485/428 +f 189/487/430 190/477/425 188/447/395 +f 190/477/425 145/448/396 188/447/395 +f 144/449/397 190/477/425 187/450/398 +f 190/477/425 189/487/430 187/450/398 +f 169/488/431 171/489/432 132/432/384 +f 169/488/431 132/432/384 186/484/427 +f 131/433/385 170/490/433 168/491/434 +f 131/433/385 168/491/434 185/486/429 +f 186/484/427 188/447/395 167/443/393 +f 186/484/427 167/443/393 169/488/431 +f 166/446/394 187/450/398 185/486/429 +f 166/446/394 185/486/429 168/491/434 +f 173/492/435 134/430/382 171/489/432 +f 134/430/382 132/432/384 171/489/432 +f 131/433/385 133/431/383 170/490/433 +f 133/431/383 172/493/436 170/490/433 +f 175/494/437 136/427/379 134/430/382 +f 175/494/437 134/430/382 173/492/435 +f 133/431/383 135/429/381 174/495/438 +f 133/431/383 174/495/438 172/493/436 +f 176/496/439 137/428/380 136/427/379 +f 176/496/439 136/427/379 175/494/437 +f 135/429/381 137/428/380 176/496/439 +f 135/429/381 176/496/439 174/495/438 +f 184/415/367 182/411/363 178/497/440 +f 182/411/363 177/456/404 178/497/440 +f 177/456/404 181/412/364 178/497/440 +f 181/412/364 183/416/368 178/497/440 +f 178/497/440 68/498/441 113/413/365 +f 178/497/440 113/413/365 184/415/367 +f 112/414/366 68/498/441 178/497/440 +f 112/414/366 178/497/440 183/416/368 +f 68/498/441 163/499/442 113/413/365 +f 163/499/442 111/391/343 113/413/365 +f 110/394/346 162/500/443 112/414/366 +f 162/500/443 68/498/441 112/414/366 +f 177/456/404 182/411/363 115/409/361 +f 177/456/404 115/409/361 165/436/388 +f 114/410/362 181/412/364 177/456/404 +f 114/410/362 177/456/404 164/437/389 +f 147/501/444 165/436/388 115/409/361 +f 147/501/444 115/409/361 117/407/359 +f 114/410/362 164/437/389 146/502/445 +f 114/410/362 146/502/445 116/408/360 +f 149/503/446 147/501/444 119/405/357 +f 147/501/444 117/407/359 119/405/357 +f 116/408/360 146/502/445 118/406/358 +f 146/502/445 148/504/447 118/406/358 +f 151/505/448 149/503/446 121/403/355 +f 149/503/446 119/405/357 121/403/355 +f 118/406/358 148/504/447 120/404/356 +f 148/504/447 150/506/449 120/404/356 +f 153/507/450 151/505/448 123/401/353 +f 151/505/448 121/403/355 123/401/353 +f 120/404/356 150/506/449 122/402/354 +f 150/506/449 152/508/451 122/402/354 +f 155/509/452 153/507/450 125/399/351 +f 153/507/450 123/401/353 125/399/351 +f 122/402/354 152/508/451 124/400/352 +f 152/508/451 154/510/453 124/400/352 +f 157/511/454 155/509/452 127/397/349 +f 155/509/452 125/399/351 127/397/349 +f 124/400/352 154/510/453 126/398/350 +f 154/510/453 156/512/455 126/398/350 +f 159/513/456 157/511/454 180/395/347 +f 157/511/454 127/397/349 180/395/347 +f 126/398/350 156/512/455 179/396/348 +f 156/512/455 158/514/457 179/396/348 +f 159/513/456 180/395/347 129/392/344 +f 159/513/456 129/392/344 161/515/458 +f 128/393/345 179/396/348 158/514/457 +f 128/393/345 158/514/457 160/516/459 +f 161/515/458 129/392/344 163/499/442 +f 129/392/344 111/391/343 163/499/442 +f 110/394/346 128/393/345 162/500/443 +f 128/393/345 160/516/459 162/500/443 +f 68/498/441 67/517/290 163/499/442 +f 67/517/290 109/518/288 163/499/442 +f 108/519/289 67/517/290 162/500/443 +f 67/517/290 68/498/441 162/500/443 +f 163/499/442 109/518/288 161/515/458 +f 109/518/288 107/520/286 161/515/458 +f 106/521/287 108/519/289 160/516/459 +f 108/519/289 162/500/443 160/516/459 +f 161/515/458 107/520/286 159/513/456 +f 107/520/286 105/522/284 159/513/456 +f 104/523/285 106/521/287 158/514/457 +f 106/521/287 160/516/459 158/514/457 +f 159/513/456 105/522/284 103/524/282 +f 159/513/456 103/524/282 157/511/454 +f 102/525/283 104/523/285 158/514/457 +f 102/525/283 158/514/457 156/512/455 +f 157/511/454 103/524/282 155/509/452 +f 103/524/282 101/526/280 155/509/452 +f 100/527/281 102/525/283 154/510/453 +f 102/525/283 156/512/455 154/510/453 +f 155/509/452 101/526/280 153/507/450 +f 101/526/280 99/528/278 153/507/450 +f 98/529/279 100/527/281 152/508/451 +f 100/527/281 154/510/453 152/508/451 +f 153/507/450 99/528/278 151/505/448 +f 99/528/278 97/530/276 151/505/448 +f 96/531/277 98/529/279 150/506/449 +f 98/529/279 152/508/451 150/506/449 +f 151/505/448 97/530/276 95/532/274 +f 151/505/448 95/532/274 149/503/446 +f 94/533/275 96/531/277 150/506/449 +f 94/533/275 150/506/449 148/504/447 +f 149/503/446 95/532/274 147/501/444 +f 95/532/274 93/280/240 147/501/444 +f 92/283/243 94/533/275 146/502/445 +f 94/533/275 148/504/447 146/502/445 +f 147/501/444 93/280/240 80/279/241 +f 147/501/444 80/279/241 165/436/388 +f 79/281/242 92/283/243 146/502/445 +f 79/281/242 146/502/445 164/437/389 +f 169/488/431 167/443/393 82/444/247 +f 169/488/431 82/444/247 84/534/251 +f 81/445/248 166/446/394 168/491/434 +f 81/445/248 168/491/434 83/535/252 +f 171/489/432 169/488/431 84/534/251 +f 171/489/432 84/534/251 86/536/264 +f 83/535/252 168/491/434 170/490/433 +f 83/535/252 170/490/433 85/537/265 +f 173/492/435 171/489/432 86/536/264 +f 173/492/435 86/536/264 88/538/266 +f 85/537/265 170/490/433 172/493/436 +f 85/537/265 172/493/436 87/539/267 +f 175/494/437 173/492/435 90/540/268 +f 173/492/435 88/538/266 90/540/268 +f 87/539/267 172/493/436 89/541/269 +f 172/493/436 174/495/438 89/541/269 +f 176/496/439 175/494/437 91/542/271 +f 175/494/437 90/540/268 91/542/271 +f 89/541/269 174/495/438 91/542/271 +f 174/495/438 176/496/439 91/542/271 +f 50/4/4 48/543/460 2/544/461 +f 50/4/4 2/544/461 66/5/5 +f 1/545/462 47/546/463 49/3/3 +f 1/545/462 49/3/3 65/2/2 +f 66/5/5 2/544/461 12/547/464 +f 66/5/5 12/547/464 64/8/8 +f 11/548/465 1/545/462 65/2/2 +f 11/548/465 65/2/2 63/7/7 +f 64/8/8 12/547/464 14/549/466 +f 64/8/8 14/549/466 60/10/10 +f 13/550/467 11/548/465 63/7/7 +f 13/550/467 63/7/7 59/9/9 +f 60/10/10 14/549/466 24/551/468 +f 60/10/10 24/551/468 58/12/12 +f 23/552/469 13/550/467 59/9/9 +f 23/552/469 59/9/9 57/11/11 +f 58/12/12 24/551/468 56/14/14 +f 24/551/468 26/553/470 56/14/14 +f 25/554/471 23/552/469 55/13/13 +f 23/552/469 57/11/11 55/13/13 +f 56/14/14 26/553/470 54/16/16 +f 26/553/470 36/555/472 54/16/16 +f 35/556/473 25/554/471 53/15/15 +f 25/554/471 55/13/13 53/15/15 +f 54/16/16 36/555/472 52/18/18 +f 36/555/472 38/557/474 52/18/18 +f 37/558/475 35/556/473 51/17/17 +f 35/556/473 53/15/15 51/17/17 +f 52/18/18 38/557/474 50/4/4 +f 38/557/474 48/543/460 50/4/4 +f 47/546/463 37/558/475 49/3/3 +f 37/558/475 51/17/17 49/3/3 +f 46/559/476 48/543/460 40/560/477 +f 48/543/460 38/557/474 40/560/477 +f 37/558/475 47/546/463 39/561/478 +f 47/546/463 45/562/479 39/561/478 +f 44/563/480 46/559/476 42/564/481 +f 46/559/476 40/560/477 42/564/481 +f 39/561/478 45/562/479 41/565/482 +f 45/562/479 43/566/483 41/565/482 +f 42/564/481 40/560/477 32/567/484 +f 40/560/477 34/568/485 32/567/484 +f 33/569/486 39/561/478 31/570/487 +f 39/561/478 41/565/482 31/570/487 +f 40/560/477 38/557/474 34/568/485 +f 38/557/474 36/555/472 34/568/485 +f 35/556/473 37/558/475 33/569/486 +f 37/558/475 39/561/478 33/569/486 +f 34/568/485 36/555/472 28/571/488 +f 36/555/472 26/553/470 28/571/488 +f 25/554/471 35/556/473 27/572/489 +f 35/556/473 33/569/486 27/572/489 +f 32/567/484 34/568/485 30/573/490 +f 34/568/485 28/571/488 30/573/490 +f 27/572/489 33/569/486 29/574/491 +f 33/569/486 31/570/487 29/574/491 +f 30/573/490 28/571/488 20/575/492 +f 28/571/488 22/576/493 20/575/492 +f 21/577/494 27/572/489 19/578/495 +f 27/572/489 29/574/491 19/578/495 +f 28/571/488 26/553/470 24/551/468 +f 28/571/488 24/551/468 22/576/493 +f 23/552/469 25/554/471 27/572/489 +f 23/552/469 27/572/489 21/577/494 +f 22/576/493 24/551/468 16/579/496 +f 24/551/468 14/549/466 16/579/496 +f 13/550/467 23/552/469 15/580/497 +f 23/552/469 21/577/494 15/580/497 +f 20/575/492 22/576/493 18/581/498 +f 22/576/493 16/579/496 18/581/498 +f 15/580/497 21/577/494 17/582/499 +f 21/577/494 19/578/495 17/582/499 +f 18/581/498 16/579/496 10/583/500 +f 18/581/498 10/583/500 8/584/501 +f 9/585/502 15/580/497 17/582/499 +f 9/585/502 17/582/499 7/586/503 +f 16/579/496 14/549/466 12/547/464 +f 16/579/496 12/547/464 10/583/500 +f 11/548/465 13/550/467 15/580/497 +f 11/548/465 15/580/497 9/585/502 +f 10/583/500 12/547/464 2/544/461 +f 10/583/500 2/544/461 4/587/504 +f 1/545/462 11/548/465 9/585/502 +f 1/545/462 9/585/502 3/588/505 +f 8/584/501 10/583/500 4/587/504 +f 8/584/501 4/587/504 6/589/506 +f 3/588/505 9/585/502 7/586/503 +f 3/588/505 7/586/503 5/590/507 +f 6/589/506 4/587/504 46/559/476 +f 6/589/506 46/559/476 44/563/480 +f 45/562/479 3/588/505 5/590/507 +f 45/562/479 5/590/507 43/566/483 +f 4/587/504 2/544/461 48/543/460 +f 4/587/504 48/543/460 46/559/476 +f 47/546/463 1/545/462 3/588/505 +f 47/546/463 3/588/505 45/562/479 |