polyadvent

A game engine from scratch in C
git clone git://jb55.com/polyadvent
Log | Files | Refs | README

commit 250c31bfacae9a899611ad2c6e560e081136bc98
parent 046e3ba072688a64510041578886d564c8322855
Author: William Casarin <jb55@jb55.com>
Date:   Thu, 27 Jun 2019 23:43:32 -0700

Merge branch 'animation' into dynamic-wip

Diffstat:
M.gitignore | 1+
MMakefile | 20+++++++++++++++-----
ATODOs.org | 42++++++++++++++++++++++++++++++++++++++++++
Mdata/models/pirate-officer.blend | 0
Adata/models/pirate-officer.dae | 532+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Metc/shaders/shadows.glsl | 7++++---
Asrc/animation.c | 187+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/animation.h | 34++++++++++++++++++++++++++++++++++
Msrc/entity.c | 14+++++++-------
Msrc/entity.h | 10+++++-----
Msrc/file.c | 2+-
Msrc/file.h | 7++-----
Msrc/game.c | 53++++++++++++++++++++++++++++++++++++++++++++++++++++-
Msrc/game.h | 5+++--
Msrc/geometry.c | 148+++++++++++++++++++++++++++++++++++++------------------------------------------
Msrc/geometry.h | 28+++++++++++++---------------
Msrc/gl.h | 6++++++
Asrc/half-edge.c | 24++++++++++++++++++++++++
Asrc/half-edge.h | 24++++++++++++++++++++++++
Msrc/main.c | 9++++++---
Msrc/mat4.h | 8++++++++
Msrc/model.c | 24+++++++++++++++++++-----
Msrc/model.h | 14+++++++++-----
Msrc/ply.c | 2+-
Msrc/ply.h | 2+-
Asrc/quickhull.c | 1245+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/quickhull.h | 88+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/render.c | 8++++----
Msrc/scene.c | 4++--
Msrc/skybox.c | 6+++---
Msrc/skybox.h | 2+-
Msrc/terrain.c | 2+-
Msrc/terrain.h | 2+-
Msrc/ui.c | 10+++++-----
Msrc/ui.h | 4++--
Msrc/update.c | 10+++++++---
Msrc/util.c | 8--------
Msrc/util.h | 10+++++++---
Msrc/vbo.c | 128+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Msrc/vbo.h | 68++++++++++++++++++++++++++++++++++++++++++++++++--------------------
Msrc/vec3.h | 8++++++++
Asrc/xml.c | 459+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Asrc/xml.h | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Atest/test-half-edge.c | 7+++++++
Atest/test_animation.c | 30++++++++++++++++++++++++++++++
45 files changed, 3152 insertions(+), 223 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -3,3 +3,4 @@ polyadvent /TAGS *.d +/test/test_animation diff --git a/Makefile b/Makefile @@ -2,7 +2,7 @@ NAME ?= polyadvent BIN ?= $(NAME) PREFIX ?= /usr/local DEFS= -DGLFW_INCLUDE_NONE -DDEBUG -CFLAGS = $(DEFS) -ggdb -Ofast -I src -Wall -Werror -Wextra -std=c99 \ +CFLAGS = $(DEFS) -ggdb -O2 -I src -Wall -Werror -Wextra -std=c99 \ -Wno-unused-function \ -Wno-unused-parameter \ -Wno-unused-variable \ @@ -14,6 +14,8 @@ SRC=src OBJS = $(SRC)/window.o OBJS += $(SRC)/vbo.o OBJS += $(SRC)/camera.o +OBJS += $(SRC)/xml.o +OBJS += $(SRC)/animation.o OBJS += $(SRC)/debug.o OBJS += $(SRC)/delaunay.o OBJS += $(SRC)/entity.o @@ -23,7 +25,6 @@ OBJS += $(SRC)/game.o OBJS += $(SRC)/geometry.o OBJS += $(SRC)/hires.o OBJS += $(SRC)/input.o -OBJS += $(SRC)/main.o OBJS += $(SRC)/mat4.o OBJS += $(SRC)/mat_util.o OBJS += $(SRC)/model.o @@ -46,17 +47,20 @@ OBJS += $(SRC)/util.o OBJS += $(SRC)/vec3.o OBJS += $(SRC)/scene.o OBJS += $(SRC)/resource.o +OBJS += $(SRC)/quickhull.o +TESTS = test/test_animation SRCS=$(OBJS:.o=.c) - all: $(BIN) clean: - rm -f src/main.o $(OBJS) $(SHLIB) $(BIN) $(SRC)/*.d* + rm -f src/main.o $(OBJS) $(TESTS) $(SHLIB) $(BIN) $(SRC)/*.d* include $(OBJS:.o=.d) +include src/main.d +include test/test_animation.d %.d: %.c @rm -f $@; \ @@ -64,7 +68,13 @@ include $(OBJS:.o=.d) sed 's,\(.*\)\.o[ :]*,src/\1.o $@ : ,g' < $@.$$$$ > $@; \ rm -f $@.$$$$ -$(BIN): $(OBJS) +test/%: test/%.o $(OBJS) + $(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@ + +check: $(TESTS) + ./$(TESTS) + +$(BIN): src/main.o $(OBJS) $(CC) $(CFLAGS) $^ $(LDFLAGS) -o $@ install: $(BIN) diff --git a/TODOs.org b/TODOs.org @@ -0,0 +1,42 @@ + +* Rendering + +** TODO Debris on ground + +To create a sense of movement + +** TODO Half edge subdivision for tessellation + +* Multicore + +** TODO Simple pthreads job system + +* Animation + +** DONE Initial animation system +CLOSED: [2019-06-22 Sat 12:52] +** DONE Load poses in engine +CLOSED: [2019-06-22 Sat 12:52] +** TODO Load bone weights +** TODO Run pose +** TODO Simple animation test +** TODO Procedural animation? + + +* Physics + +** TODO Initial physics system +* Entity + +** TODO Entity loading stress test + +* Procedural + +** TODO Trees +** DONE quickhull tests +CLOSED: [2019-04-12 Fri 09:37] + +* Terrain + +** TODO Infinite terrain + diff --git a/data/models/pirate-officer.blend b/data/models/pirate-officer.blend Binary files differ. diff --git a/data/models/pirate-officer.dae b/data/models/pirate-officer.dae @@ -0,0 +1,531 @@ +<?xml version="1.0" encoding="utf-8"?> +<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <asset> + <contributor> + <author>Blender User</author> + <authoring_tool>Blender 2.79.0</authoring_tool> + </contributor> + <created>2019-06-22T11:19:51</created> + <modified>2019-06-22T11:19:51</modified> + <unit name="meter" meter="1"/> + <up_axis>Z_UP</up_axis> + </asset> + <library_cameras> + <camera id="Camera-camera" name="Camera"> + <optics> + <technique_common> + <perspective> + <xfov sid="xfov">49.13434</xfov> + <aspect_ratio>1.777778</aspect_ratio> + <znear sid="znear">0.1</znear> + <zfar sid="zfar">100</zfar> + </perspective> + </technique_common> + </optics> + <extra> + <technique profile="blender"> + <shiftx sid="shiftx" type="float">0</shiftx> + <shifty sid="shifty" type="float">0</shifty> + <YF_dofdist sid="YF_dofdist" type="float">0</YF_dofdist> + </technique> + </extra> + </camera> + </library_cameras> + <library_lights> + <light id="Lamp-light" name="Lamp"> + <technique_common> + <ambient> + <color>0.11 0.11 0.11</color> + </ambient> + </technique_common> + <extra> + <technique profile="blender"> + <type sid="type" type="int">3</type> + <flag sid="flag" type="int">0</flag> + <mode sid="mode" type="int">12288</mode> + <gamma sid="blender_gamma" type="float">1</gamma> + <red sid="red" type="float">1</red> + <green sid="green" type="float">1</green> + <blue sid="blue" type="float">1</blue> + <shadow_r sid="blender_shadow_r" type="float">0</shadow_r> + <shadow_g sid="blender_shadow_g" type="float">0</shadow_g> + <shadow_b sid="blender_shadow_b" type="float">0</shadow_b> + <energy sid="blender_energy" type="float">0.11</energy> + <dist sid="blender_dist" type="float">29.99998</dist> + <spotsize sid="spotsize" type="float">75</spotsize> + <spotblend sid="spotblend" type="float">0.15</spotblend> + <halo_intensity sid="blnder_halo_intensity" type="float">1</halo_intensity> + <att1 sid="att1" type="float">0</att1> + <att2 sid="att2" type="float">1</att2> + <falloff_type sid="falloff_type" type="int">2</falloff_type> + <clipsta sid="clipsta" type="float">1.000799</clipsta> + <clipend sid="clipend" type="float">30.002</clipend> + <bias sid="bias" type="float">1</bias> + <soft sid="soft" type="float">3</soft> + <compressthresh sid="compressthresh" type="float">0.04999995</compressthresh> + <bufsize sid="bufsize" type="int">2880</bufsize> + <samp sid="samp" type="int">3</samp> + <buffers sid="buffers" type="int">1</buffers> + <filtertype sid="filtertype" type="int">0</filtertype> + <bufflag sid="bufflag" type="int">0</bufflag> + <buftype sid="buftype" type="int">2</buftype> + <ray_samp sid="ray_samp" type="int">1</ray_samp> + <ray_sampy sid="ray_sampy" type="int">1</ray_sampy> + <ray_sampz sid="ray_sampz" type="int">1</ray_sampz> + <ray_samp_type sid="ray_samp_type" type="int">0</ray_samp_type> + <area_shape sid="area_shape" type="int">1</area_shape> + <area_size sid="area_size" type="float">0.1</area_size> + <area_sizey sid="area_sizey" type="float">0.1</area_sizey> + <area_sizez sid="area_sizez" type="float">1</area_sizez> + <adapt_thresh sid="adapt_thresh" type="float">0.000999987</adapt_thresh> + <ray_samp_method sid="ray_samp_method" type="int">1</ray_samp_method> + <shadhalostep sid="shadhalostep" type="int">0</shadhalostep> + <sun_effect_type sid="sun_effect_type" type="int">0</sun_effect_type> + <skyblendtype sid="skyblendtype" type="int">1</skyblendtype> + <horizon_brightness sid="horizon_brightness" type="float">1</horizon_brightness> + <spread sid="spread" type="float">1</spread> + <sun_brightness sid="sun_brightness" type="float">1</sun_brightness> + <sun_size sid="sun_size" type="float">1</sun_size> + <backscattered_light sid="backscattered_light" type="float">1</backscattered_light> + <sun_intensity sid="sun_intensity" type="float">1</sun_intensity> + <atm_turbidity sid="atm_turbidity" type="float">2</atm_turbidity> + <atm_extinction_factor sid="atm_extinction_factor" type="float">1</atm_extinction_factor> + <atm_distance_factor sid="atm_distance_factor" type="float">1</atm_distance_factor> + <skyblendfac sid="skyblendfac" type="float">1</skyblendfac> + <sky_exposure sid="sky_exposure" type="float">1</sky_exposure> + <sky_colorspace sid="sky_colorspace" type="int">0</sky_colorspace> + </technique> + </extra> + </light> + </library_lights> + <library_images/> + <library_effects> + <effect id="sand_001-effect"> + <profile_COMMON> + <technique sid="common"> + <phong> + <emission> + <color sid="emission">0 0 0 1</color> + </emission> + <ambient> + <color sid="ambient">0 0 0 1</color> + </ambient> + <diffuse> + <color sid="diffuse">0.8470588 0.7607843 0.6078432 1</color> + </diffuse> + <specular> + <color sid="specular">0.33 0.33 0.33 1</color> + </specular> + <shininess> + <float sid="shininess">50</float> + </shininess> + <index_of_refraction> + <float sid="index_of_refraction">1</float> + </index_of_refraction> + </phong> + </technique> + </profile_COMMON> + </effect> + <effect id="textile_001-effect"> + <profile_COMMON> + <technique sid="common"> + <phong> + <emission> + <color sid="emission">0 0 0 1</color> + </emission> + <ambient> + <color sid="ambient">0 0 0 1</color> + </ambient> + <diffuse> + <color sid="diffuse">0.8196079 0.7529412 0.6705883 1</color> + </diffuse> + <specular> + <color sid="specular">0.33 0.33 0.33 1</color> + </specular> + <shininess> + <float sid="shininess">50</float> + </shininess> + <index_of_refraction> + <float sid="index_of_refraction">1</float> + </index_of_refraction> + </phong> + </technique> + </profile_COMMON> + </effect> + <effect id="textileBlue_001-effect"> + <profile_COMMON> + <technique sid="common"> + <phong> + <emission> + <color sid="emission">0 0 0 1</color> + </emission> + <ambient> + <color sid="ambient">0 0 0 1</color> + </ambient> + <diffuse> + <color sid="diffuse">0.3568628 0.5411765 0.6980392 1</color> + </diffuse> + <specular> + <color sid="specular">0.33 0.33 0.33 1</color> + </specular> + <shininess> + <float sid="shininess">50</float> + </shininess> + <index_of_refraction> + <float sid="index_of_refraction">1</float> + </index_of_refraction> + </phong> + </technique> + </profile_COMMON> + </effect> + <effect id="iron_001-effect"> + <profile_COMMON> + <technique sid="common"> + <phong> + <emission> + <color sid="emission">0 0 0 1</color> + </emission> + <ambient> + <color sid="ambient">0 0 0 1</color> + </ambient> + <diffuse> + <color sid="diffuse">0.3764706 0.3764706 0.3764706 1</color> + </diffuse> + <specular> + <color sid="specular">0.33 0.33 0.33 1</color> + </specular> + <shininess> + <float sid="shininess">50</float> + </shininess> + <index_of_refraction> + <float sid="index_of_refraction">1</float> + </index_of_refraction> + </phong> + </technique> + </profile_COMMON> + </effect> + <effect id="wood_001-effect"> + <profile_COMMON> + <technique sid="common"> + <phong> + <emission> + <color sid="emission">0 0 0 1</color> + </emission> + <ambient> + <color sid="ambient">0 0 0 1</color> + </ambient> + <diffuse> + <color sid="diffuse">0.7294118 0.4627451 0.2784314 1</color> + </diffuse> + <specular> + <color sid="specular">0.33 0.33 0.33 1</color> + </specular> + <shininess> + <float sid="shininess">50</float> + </shininess> + <index_of_refraction> + <float sid="index_of_refraction">1</float> + </index_of_refraction> + </phong> + </technique> + </profile_COMMON> + </effect> + </library_effects> + <library_materials> + <material id="sand_001-material" name="sand_001"> + <instance_effect url="#sand_001-effect"/> + </material> + <material id="textile_001-material" name="textile_001"> + <instance_effect url="#textile_001-effect"/> + </material> + <material id="textileBlue_001-material" name="textileBlue_001"> + <instance_effect url="#textileBlue_001-effect"/> + </material> + <material id="iron_001-material" name="iron_001"> + <instance_effect url="#iron_001-effect"/> + </material> + <material id="wood_001-material" name="wood_001"> + <instance_effect url="#wood_001-effect"/> + </material> + </library_materials> + <library_geometries> + <geometry id="armRight_2-mesh" name="armRight 2"> + <mesh> + <source id="armRight_2-mesh-positions"> + <float_array id="armRight_2-mesh-positions-array" count="735">3.119424 4.474335 0.4653273 3.119424 4.846886 -0.9250495 3.119424 5.704739 -0.6951884 3.119424 5.332189 0.6951884 1.68 4.474335 0.4653273 1.68 5.332189 0.6951884 1.68 5.704739 -0.6951884 1.68 4.846886 -0.9250495 1.68 3.505581 -1.284451 1.68 3.13303 0.1059257 3.119424 3.616482 0.2354661 3.119424 3.989032 -1.154911 2.618918 3.505581 -1.284451 2.618918 3.13303 0.1059257 2.599066 7.7952 -0.719712 2.599066 7.7952 0.719712 3.119424 5.704739 0.6988978 1.68 7.7952 -0.719712 1.68 7.7952 0.719712 -1.1424 9.203529 0.1723 -1.1424 9.203529 -0.1777 -1.5924 9.203529 -0.1059499 -1.5924 9.203529 0.10055 -1.1424 8.553528 -0.1777 -1.5924 8.553528 -0.1059499 -1.1424 8.878528 -0.1777 0.8585536 9.12486 -1.1424 0.8585536 8.73846 -1.1424 0.8163304 8.780964 -0.9924 0.8163304 9.082355 -0.9924 0.4747072 8.73846 -1.1424 0.5169303 8.780964 -0.9924 0.4747072 9.12486 -1.1424 0.5169303 9.082355 -0.9924 -1.1424 7.7952 1.1424 1.1424 7.7952 1.1424 1.1424 8.044856 1.1424 -1.1424 8.044856 1.1424 1.5924 8.553528 -0.1059499 1.5924 9.203529 -0.1059499 1.5924 9.203529 0.10055 1.5924 8.553528 0.10055 -1.5924 8.553528 0.10055 -1.1424 8.553528 0.1723 1.1424 8.553528 0.1723 1.1424 9.203529 0.1723 1.1424 9.203529 -0.1777 0.2501961 8.507093 -1.3424 -0.2501961 8.507093 -1.3424 -0.2501961 8.73846 -1.3424 0.2501961 8.73846 -1.3424 1.1424 8.553528 -0.1777 1.1424 8.878528 -0.1777 -0.2501961 9.226147 -1.1424 0.2501961 9.226147 -1.1424 1.1424 7.7952 -1.1424 1.1424 9.417567 -1.1424 1.1424 9.203529 -0.3924 1.1424 8.878528 -0.3924 1.1424 8.044856 0.1723 -1.1424 8.353384 -1.1424 -1.1424 7.7952 -1.1424 -1.1424 8.044856 0.1723 -1.1424 8.554254 -1.1424 -1.1424 8.878528 -0.3924 -1.1424 9.203529 -0.3924 -1.1424 9.750949 -1.1424 0.2501961 8.507093 -1.1424 -0.2501961 8.507093 -1.1424 -1.05984 8.637173 -1.1424 -0.9598404 8.737608 -1.1424 -0.9598404 9.226147 -1.1424 -0.4734204 9.226147 -1.1424 0.005060195 9.706711 -1.1424 -0.1689486 9.750949 -1.1424 0.6902345 8.507093 -1.1424 0.4702153 8.426183 -1.1424 0.4702153 8.079505 -1.1424 0.3239235 7.7952 -1.1424 0.1646611 9.666136 -1.1424 -0.2734204 9.226147 -1.1424 -0.3734204 9.12571 -1.1424 -0.3734204 8.637173 -1.1424 -0.8598404 8.637173 -1.1424 -0.6902345 8.507093 -1.1424 -1.0424 8.453819 -1.1424 -0.4702153 8.079505 -1.1424 -0.3239235 7.7952 -1.1424 0 7.969101 -1.1424 -0.4702153 8.426183 -1.1424 0 8.160416 -1.1424 -1.1424 9.9452 1.1424 -1.1424 9.9452 -1.1424 1.1424 9.9452 1.1424 1.1424 9.9452 -1.1424 0 7.165683 -1.1424 0.3239235 7.7952 -1.2924 -0.3239235 7.7952 -1.2924 1.744405 9.70115 1.331605 1.744405 10.34961 -1.088463 1.244635 10.5666 -1.030319 1.244635 9.918148 1.389749 2.2848 9.757251 -1.000771 1.744405 9.818854 -1.230678 2.2848 10.38262 -0.8332043 2.165931 10.52767 -0.8485405 2.2848 9.232002 0.959484 1.744405 9.170399 1.18939 -1.744405 9.170399 1.18939 -1.744405 9.818854 -1.230678 -2.2848 9.232002 0.959484 -2.2848 9.757251 -1.000771 2.165931 9.975322 1.212859 0.7217082 11.54546 -0.7680354 0.7217082 10.897 1.652033 -1.49012e-7 11.74588 -0.7143339 -1.49012e-7 11.09742 1.705734 2.2848 9.857371 1.127051 -1.744405 9.70115 1.331605 -2.2848 9.857371 1.127051 -2.16593 9.975322 1.212859 -2.16593 10.52767 -0.8485405 -2.2848 10.38262 -0.8332043 -1.244635 9.918148 1.389749 -1.244635 10.5666 -1.030319 -1.744405 10.34961 -1.088463 -0.7217084 10.897 1.652033 -0.7217084 11.54546 -0.7680354 -0.175 10.28041 -1.107004 -0.175 10.51285 -1.044724 -0.2474873 10.56657 -1.030328 -0.3031088 10.63659 -1.011567 -0.3380738 10.71813 -0.9897187 -0.3499998 10.80563 -0.9662732 -0.3380738 10.89313 -0.9428276 -0.3031088 10.97466 -0.9209799 -0.2474873 11.04468 -0.9022188 -0.175 11.09841 -0.8878228 -0.09058654 11.13218 -0.8787732 -1.49012e-7 11.1437 -0.8756865 0.1750001 10.28041 -1.107004 0.09058666 11.13218 -0.8787732 0.1750001 11.09841 -0.8878228 0.2474874 11.04468 -0.9022188 0.303109 10.97466 -0.9209799 0.338074 10.89313 -0.9428276 0.35 10.80563 -0.9662732 0.338074 10.71813 -0.9897187 0.303109 10.63659 -1.011567 0.2474874 10.56657 -1.030328 0.1750001 10.51285 -1.044724 -0.112896 2.0328 -0.8877119 -1.55232 2.0328 -0.8877119 -1.55232 4.0656 -0.719712 -0.112896 4.0656 -0.719712 -1.55232 2.0328 0.551712 -1.55232 4.0656 0.719712 -0.112896 4.0656 0.719712 -0.112896 2.0328 0.551712 -0.112896 0 -1.069712 -0.112896 0 0.719712 -1.55232 0 0.719712 -1.55232 0 -1.069712 -0.112896 0.7555377 -0.7821531 -0.112896 0.4500002 -1.069712 -1.55232 0.4500002 -1.069712 -1.55232 0.7555377 -0.7821531 1.55232 2.0328 0.551712 1.55232 2.0328 -0.8877119 1.55232 4.0656 -0.719712 1.55232 4.0656 0.719712 0.112896 2.0328 -0.8877119 0.112896 4.0656 -0.719712 0.112896 2.0328 0.551712 0.112896 4.0656 0.719712 1.230997 1.6328 0.2303889 1.415575 1.6328 -0.7509667 1.415575 1.6328 0.4149667 0.2496412 1.6328 0.4149667 0.434219 1.6328 0.2303889 0.434219 1.6328 -0.5663889 1.230997 1.6328 -0.5663889 0.2496412 1.6328 -0.7509667 1.107496 0 -0.4428884 1.107496 0 0.1068884 0.5577196 0 0.1068884 0.5577196 0 -0.4428884 -1.68 7.7952 0.719712 -1.68 7.7952 -0.719712 -2.599066 7.7952 -0.719712 -2.599066 7.7952 0.719712 -1.68 5.704739 -0.6951884 -1.68 5.332189 0.6951884 -3.119424 5.332189 0.6951884 -3.119424 5.704739 -0.6951884 -3.119424 5.704739 0.6988978 -1.68 4.474335 0.4653273 -1.68 4.846886 -0.9250495 -3.119424 4.846886 -0.9250495 -3.119424 4.474335 0.4653273 -1.68 3.505581 -1.284451 -1.68 3.13303 0.1059257 -2.618918 3.13303 0.1059257 -2.618918 3.505581 -1.284451 -3.119424 3.989032 -1.154911 -3.119424 3.616482 0.2354661 -1.68 5.9304 1.1424 -1.68 5.9304 -1.1424 -1.594673 4.684178 -1.05842 -1.594673 4.684178 1.05842 -0.00607562 5.22702 -1.095001 1.594673 4.684178 -1.05842 -0.8598863 5.9304 -1.1424 1.68 5.9304 -1.1424 0.8332732 5.9304 -1.1424 1.68 7.7952 -1.1424 1.68 7.7952 1.1424 1.68 5.9304 1.1424 -1.25199 7.7952 0.7156732 -1.25199 7.7952 -1.1424 -1.68 7.7952 -1.1424 -1.68 7.7952 1.1424 1.253273 7.7952 0.7156732 1.253273 7.7952 -1.1424 1.594673 4.684178 1.05842 -1.55232 4.0656 1.016736 1.55232 4.0656 1.016736 1.55232 4.0656 -1.016736 -1.55232 4.0656 -1.016736 0.7105495 7.22044 -1.1424 0.3052405 7.0503 -1.1424 0.4802405 7.353409 -1.1424 0.63 6.8628 -1.1424 0.42 5.9304 -1.1424 0.84 7.7952 -1.1424 -0.009909689 5.569582 -1.118085 -0.4478963 5.9304 -1.1424 -0.84 7.7952 0.3024 -0.84 7.7952 -1.1424 -0.8387169 7.7952 0.3024 0.84 7.7952 0.3024 -0.6439482 6.8628 -1.1424 -0.7197267 7.223194 -1.1424 -0.3191886 7.0503 -1.1424 -0.4941886 7.353409 -1.1424</float_array> + <technique_common> + <accessor source="#armRight_2-mesh-positions-array" count="245" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <source id="armRight_2-mesh-normals"> + <float_array id="armRight_2-mesh-normals-array" count="1038">1 1.86501e-7 0 1 0 0 0 -0.2588187 0.9659259 0 -0.2588189 0.9659259 -1 -3.73003e-7 0 -1 3.73003e-7 0 0 0.2588193 -0.9659259 0 0.2588191 -0.9659259 -1 0 0 1 0 0 1 -3.73003e-7 0 0 0.258819 -0.9659259 -4.09321e-7 0.2588185 -0.965926 0 0.2588194 -0.9659258 1.491e-7 -0.2588189 0.9659259 0 -0.2588194 0.9659258 0 -0.9659258 -0.2588195 0 -0.9659258 -0.2588192 0.7071062 -0.6830132 -0.1830131 0.7071071 -0.6830124 -0.1830125 0.9703885 0.2415493 0 0.9703885 0.2415493 0 0 1 0 1 0 0 -1 0 0 -1 -1.32362e-7 0 0 -0.00995624 0.9999505 0 -0.00995624 0.9999505 0 -0.00995624 0.9999505 0 -0.965926 -0.2588185 0 -0.9659259 -0.258819 0 -0.01173037 -0.9999313 0 -0.01173037 -0.9999313 -0.1574554 0 -0.9875262 -0.1574562 0 -0.9875261 -0.1574552 0 -0.9875262 -0.9625917 0 -0.2709566 -0.9625911 0 -0.2709585 0 0.962118 -0.2726333 0 0.962122 -0.2726193 0.9625914 0 -0.2709576 0.9625917 0 -0.2709561 0 0 1 0 -0.962117 -0.272637 0 -0.9621193 -0.2726288 -0.1574553 0 0.9875261 -0.1574557 0 0.9875261 0 -1 0 0.1574555 0 0.9875262 0.1574556 0 0.9875261 0 0 -1 0.1574552 0 -0.9875261 0.1574559 0 -0.9875261 0.1574552 0 -0.9875262 0 0.3794304 -0.9252203 0 0.3794317 -0.9252198 4.9808e-7 0 -1 6.87081e-7 0 -1 -2.82943e-6 0 -1 -8.51006e-6 0 -1 5.17736e-7 0 -1 -5.43448e-7 0 -1 -1.45756e-7 0 -1 1.3454e-6 0 -1 0 -1 -5.09971e-7 0 -1 -1.28857e-6 -1 -9.1846e-7 0 1.36172e-7 0 -1 1 1.34736e-7 0 1 5.61471e-7 0 1 -9.1846e-7 0 3.24601e-7 0 -1 0.8891892 -0.4575399 0 -0.8891892 -0.4575399 0 0 0.6531524 -0.7572265 -0.4730046 0.88106 0 0.4730046 0.88106 0 0 -0.2317884 -0.9727663 0.4136754 0.8788906 0.2375375 0.4140881 0.8792212 0.2355869 0.4140881 0.8792213 0.2355866 0.4108711 0.879479 0.240212 0.4140571 0.879235 0.2355897 0.4140586 0.8794009 0.2349672 0.2511874 0.2505195 -0.9349572 0.2511874 0.250527 -0.9349551 0.2658935 0.3164102 -0.9105962 0.2629953 0.1883165 -0.9462403 0.2804316 0.1544244 -0.9473707 0.2904886 0.3515082 -0.8899767 0.3303799 0.1040372 -0.9380967 0.2511869 0.250519 -0.9349575 0.2676317 0.319876 -0.9088745 -1.10059e-6 -0.9659258 -0.2588193 1.28769e-6 -0.9659261 -0.2588183 0 -0.965926 -0.2588186 0 -0.9659259 -0.258819 8.47453e-7 -0.9659262 -0.2588182 -1.53539e-6 -0.9659258 -0.2588195 -0.4862245 0.8453422 0.2213196 -0.4899744 0.8420331 0.2256221 -0.4899296 0.8418701 0.2263268 -0.4897733 0.8425438 0.2241475 -0.4899435 0.8420499 0.2256268 -0.4899402 0.8420006 0.2258181 0.8907816 0.4385933 0.1189299 0.8908709 0.4387781 0.1175703 0.8895793 0.442347 0.1139199 0.8908914 0.4387395 0.1175593 0.8908696 0.4387807 0.1175709 0.8907104 0.4395453 0.1159106 0.2790742 0.9272097 0.2497994 0.2793917 0.9274601 0.248512 0.2793456 0.927473 0.2485152 0.2771788 0.92729 0.2516056 0.2793444 0.9274728 0.2485176 0.2792869 0.9276473 0.2479304 0.2686784 -0.1752076 0.9471612 0.2511866 -0.2505208 0.9349571 0.3290852 -0.3783835 0.8651757 0.2622632 -0.3082784 0.9144302 0.2521263 -0.23292 0.9392448 0.2567674 -0.292184 0.9212487 0.2676345 -0.1774217 0.9470446 0.2511896 -0.2505303 0.9349538 0.3303834 -0.3789553 0.8644303 1 -7.25836e-7 0 1 7.25836e-7 0 0.7571557 0.6308901 0.1693899 0.757162 0.6309691 0.1690679 0.7549043 0.6348614 0.1645314 0.7571707 0.6309517 0.1690933 0.7571708 0.6309592 0.1690649 0.7564296 0.6326802 0.165922 -0.2511866 -0.2505226 0.9349566 -0.2511867 -0.2505153 0.9349585 -0.2658928 -0.1812797 0.9468045 -0.2629947 -0.3100323 0.9136267 -0.2804313 -0.3399488 0.8976598 -0.2904874 -0.140572 0.9464971 -0.3303838 -0.3789533 0.8644311 -0.2511898 -0.2505284 0.9349542 -0.2676345 -0.1774199 0.947045 -0.7549027 0.634863 0.164533 -0.7571595 0.6309717 0.1690683 -0.7571534 0.6308925 0.1693913 -0.7564269 0.6326833 0.1659221 -0.7571681 0.6309621 0.1690657 -0.7571682 0.6309546 0.1690943 -0.4108562 0.881764 0.23171 -0.4140883 0.8792213 0.2355861 -0.414046 0.8790728 0.2362139 -0.4136883 0.8799036 0.2337348 -0.4141006 0.8792158 0.2355855 -0.4141006 0.8792157 0.2355858 0 -0.2588204 0.9659255 0 -0.2588199 0.9659257 0 -0.2588201 0.9659256 0 -0.2588154 0.9659268 0 -0.2588203 0.9659255 0 -0.2588198 0.9659257 0 -0.2588147 0.965927 -0.2686555 0.3218024 -0.9078918 -0.2511871 0.2505196 -0.9349573 -0.3290857 0.1048969 -0.9384558 -0.2622641 0.1902384 -0.9460587 -0.2521276 0.2679077 -0.9298694 -0.2567822 0.2075331 -0.9439242 -0.2676294 0.319877 -0.9088747 -0.2511848 0.2505203 -0.9349577 -0.3303778 0.1040385 -0.9380973 -0.2771908 0.9288671 0.2457055 -0.2793457 0.9274725 0.2485171 -0.279289 0.9273309 0.2491092 -0.2790711 0.927888 0.2472717 -0.2793904 0.9274604 0.2485122 -0.2793904 0.9274603 0.2485126 -1 -8.16566e-7 0 -1 4.08283e-7 0 -0.8895705 0.4423529 0.1139667 -0.8908711 0.4387779 0.117571 -0.8907816 0.4385932 0.1189291 -0.8907103 0.4395455 0.1159099 -0.8908916 0.4387394 0.1175591 -0.8908698 0.4387806 0.1175705 0.489724 0.8417677 0.2271507 0.4899759 0.8420324 0.2256218 0.4899725 0.8420857 0.2254301 0.4862444 0.8427247 0.2310444 0.4899873 0.8420262 0.2256202 0.4899011 0.8422584 0.22494 0 0.2588169 -0.9659265 7.78629e-7 0.2588261 -0.965924 1.57825e-7 0.258809 -0.9659286 -1.7786e-6 0.258832 -0.9659225 -1.07481e-6 0.2588399 -0.9659203 -1.23697e-6 0.258816 -0.9659268 -1.82149e-6 0.258819 -0.9659259 -1.16126e-4 0.2586479 -0.9659717 -4.85832e-6 0.258821 -0.9659253 -3.48107e-6 0.2588196 -0.9659258 1.99589e-5 0.2588316 -0.9659225 -4.00742e-6 0.2588152 -0.965927 -7.57182e-6 0.2588132 -0.9659274 6.21074e-6 0.2588286 -0.9659233 1.20727e-7 0.2588152 -0.9659268 0 0.2588173 -0.9659263 0 0.2588189 -0.9659259 0 0.2588173 -0.9659263 -6.14684e-6 0.2588335 -0.9659219 7.45522e-6 0.2588095 -0.9659284 3.77168e-6 0.2588143 -0.9659271 -2.02252e-5 0.2588337 -0.9659219 2.78481e-6 0.2588154 -0.9659269 4.85839e-6 0.2588226 -0.9659249 9.78455e-5 0.2588013 -0.9659306 1.82149e-6 0.2588187 -0.965926 1.23693e-6 0.2588089 -0.9659286 1.02745e-6 0.2588405 -0.9659201 -1.57826e-7 0.2588115 -0.9659278 1.77861e-6 0.2588328 -0.9659222 -5.52945e-7 0.2588167 -0.9659265 0 0.2588137 -0.9659273 0 0.2588121 -0.9659278 0 0.2588108 -0.9659281 0 0.2588397 -0.9659203 0 0.258843 -0.9659195 0 0.2588137 -0.9659273 0 0.2588095 -0.9659284 0 0.2588077 -0.9659289 0 0.2588177 -0.9659262 0 0.2588229 -0.9659249 0 0.2588156 -0.9659268 0 0.2588168 -0.9659264 0 0.2588159 -0.9659268 0 0.2588475 -0.9659183 0 0.2588374 -0.965921 0 0.2588115 -0.9659278 0 0.258812 -0.9659277 0 0.2588028 -0.9659302 0 0.2588086 -0.9659287 0 0.2588181 -0.9659262 0 0.2588508 -0.9659174 0 0.2588396 -0.9659203 0 0.08236372 -0.9966024 0 0.08236378 -0.9966024 -1 -1.62962e-7 0 1 0 0 1 0 0 0 -0.08236384 0.9966024 0 -0.08236384 0.9966024 0 0.08236384 0.9966024 0 0.08236384 0.9966024 1 0 0 1 0 0 -1 0 0 -1 2.59359e-7 0 0 -0.08236372 -0.9966024 0 -0.08236372 -0.9966024 0 0.6853573 -0.728207 0 0.6853575 -0.7282068 1 -1.83332e-7 0 1 0 0 0 0.08236372 -0.9966024 0 0.08236372 -0.9966024 0 -0.08236378 0.9966024 0 -0.08236384 0.9966024 -1 0 0 -1 0 0 0 -1 -1.10786e-6 0 -1 1.62115e-6 0 -1 1.10786e-6 0 -1 -1.21586e-6 -0.9462342 -0.3234825 0 -0.9462343 -0.3234824 0 0 -0.3234826 0.9462342 0 -0.3234824 0.9462342 0 -0.3234823 -0.9462343 0 -0.3234823 -0.9462342 0.9462345 -0.3234815 0 0.9462344 -0.3234819 0 0 -0.07542181 -0.9971517 -0.9971518 -0.07542186 0 -0.9971517 -0.07542175 0 0.9971517 -0.0754221 0 0.9971517 -0.07542198 0 0 -0.07542181 0.9971517 0 -0.07542181 0.9971518 1 -1.38872e-7 0 -1 7.17275e-7 0 0 -0.009956181 0.9999505 -0.9703885 0.2415494 0 -0.9703887 0.2415493 0 1 -3.26378e-7 0 1 2.33127e-7 0 0 -0.2588187 0.9659259 0 -0.2588189 0.9659259 0 -0.9659258 -0.2588195 0 -0.9659259 -0.2588192 -0.7071062 -0.6830133 -0.1830131 -0.7071072 -0.6830124 -0.1830126 0 0.2588183 -0.9659261 2.3856e-7 0.2588189 -0.9659259 -1 -7.46006e-7 0 0 -0.2588189 0.9659259 -2.68617e-7 -0.2588187 0.9659259 1 0 0 1 0 0 -0.9976643 -0.06830847 0 -0.9976643 -0.06830853 0 0 -0.06723552 -0.9977372 0 -0.06723523 -0.9977372 0 -0.06723499 -0.9977372 0 -0.06723523 -0.9977372 0 -0.06723481 -0.9977372 0 1 -8.92066e-7 0 1 -2.66055e-6 0.9976643 -0.06830853 0 0.9976643 -0.06830859 0 0 -0.06723523 0.9977372 0 -0.06723523 0.9977372 0 -0.06723415 0.9977373 0 -0.06723415 0.9977372 0.9976643 -0.06830835 0 0.9976642 -0.068309 0 0 -0.06723415 -0.9977373 0 -0.06723415 -0.9977372 -0.9976643 -0.06830823 0 -0.9976642 -0.06830888 0 -6.40372e-7 0 -1 2.27065e-7 0 -1 -8.0654e-7 0 -1 6.18729e-7 0 -1 8.20878e-7 -0.06723392 -0.9977372 0 -0.06723576 -0.9977371 -6.14725e-7 -0.06723386 -0.9977373 0 -0.06723618 -0.9977371 0 1 -6.87314e-7 0 1 3.68442e-6 -6.20657e-7 0 -1 4.01433e-7 0 -1 -2.27065e-7 0 -1 3.26958e-7 0 -1 0 -0.06723588 -0.9977372 0 1 7.86402e-7 -1.99233e-7 0 -1</float_array> + <technique_common> + <accessor source="#armRight_2-mesh-normals-array" count="346" stride="3"> + <param name="X" type="float"/> + <param name="Y" type="float"/> + <param name="Z" type="float"/> + </accessor> + </technique_common> + </source> + <source id="armRight_2-mesh-map-0"> + <float_array id="armRight_2-mesh-map-0-array" count="2796">-3.663994 -20.24303 7.283854 -17.30956 5.473925 -10.55481 5.473925 -10.55481 -5.473925 -13.48828 -3.663994 -20.24303 0 -18.60495 11.33405 -18.60495 11.33405 -11.61192 11.33405 -11.61192 0 -11.61192 0 -18.60495 -5.473925 -10.55481 -7.283854 -17.30956 3.663994 -20.24303 3.663994 -20.24303 5.473925 -13.48828 -5.473925 -10.55481 -11.33405 -11.61192 -11.33405 -18.60495 0 -18.60495 0 -18.60495 0 -11.61192 -11.33405 -11.61192 -7.283854 -17.30956 -10.11379 -27.87102 0.8340612 -30.80448 0.8340612 -30.80448 3.663994 -20.24303 -7.283854 -17.30956 -1.854064 -26.99778 9.093785 -24.06431 7.283854 -17.30956 7.283854 -17.30956 -3.663994 -20.24303 -1.854064 -26.99778 -7.393058 -29.53897 0 -29.53897 0 -18.60495 0 -18.60495 -11.33405 -25.59799 -7.393058 -29.53897 0 -18.60495 -11.33405 -18.60495 -11.33405 -25.59799 0 -29.53897 7.393058 -29.53897 11.33405 -25.59799 11.33405 -25.59799 0 -18.60495 0 -29.53897 11.33405 -25.59799 11.33405 -18.60495 0 -18.60495 -7.393058 2.555619 -7.393058 -8.778429 0 -8.778429 0 -8.778429 0 2.555619 -7.393058 2.555619 -2.65988 -17.75406 7.938736 -13.73785 5.963806 -8.526088 5.963806 -8.526088 -4.634811 -12.5423 -2.65988 -17.75406 5.473925 -12.98 5.667024 3.982612 -5.667024 3.982612 -5.667024 3.982612 -5.503132 -12.98 5.473925 -12.98 -7.236743 5.667024 -7.236743 -5.667024 0 -5.667024 0 -5.667024 0 5.667024 -7.236743 5.667024 -5.473925 -13.48828 5.473925 -10.55481 -5.503132 -10.55481 5.667024 5.905512 -5.667024 5.905512 -5.473925 -10.55481 -5.473925 -10.55481 5.473925 -13.48828 5.667024 5.905512 0 -13.43311 11.33405 -13.43311 11.33405 -10.4995 11.33405 -10.4995 0 5.961641 0 -13.43311 11.33405 -10.4995 7.236743 5.961641 0 5.961641 -11.33405 2.555619 -11.33405 -8.778429 0 -8.778429 0 -8.778429 0 2.555619 -11.33405 2.555619 -11.33405 -10.48987 0 -10.48987 0 5.971582 0 5.971582 -7.236743 5.971582 -11.33405 -10.48987 8.995275 1.356693 8.995275 -1.399212 12.53858 -0.8342516 12.53858 -0.8342516 12.53858 0.7917326 8.995275 1.356693 8.662755 5.971089 12.25082 5.971089 12.25082 11.0892 12.25082 11.0892 8.662755 8.530145 8.662755 5.971089 12.25082 11.0892 8.662755 11.0892 8.662755 8.530145 -10.49052 10.46976 -10.49052 7.427242 -9.263516 7.761919 -9.263516 7.761919 -9.263516 10.13508 -10.49052 10.46976 -6.427799 -5.402069 -6.760264 -6.629673 -3.737852 -6.629673 -3.737852 -6.629673 -4.070317 -5.402069 -6.427799 -5.402069 7.645977 7.427242 7.645977 10.46976 6.418973 10.13508 6.418973 10.13508 6.418973 7.761919 7.645977 7.427242 -8.995275 0 8.995275 0 8.995275 1.965796 8.995275 1.965796 -8.995275 1.965796 -8.995275 0 0.8342516 5.971089 0.8342516 11.0892 -0.7917326 11.0892 -0.7917326 11.0892 -0.7917326 5.971089 0.8342516 5.971089 -0.8342516 11.0892 -0.8342516 5.971089 0.7917326 5.971089 0.7917326 5.971089 0.7917326 11.0892 -0.8342516 11.0892 -3.737852 11.50887 -6.760264 11.50887 -6.427799 10.28126 -6.427799 10.28126 -4.070317 10.28126 -3.737852 11.50887 -12.25751 5.971089 -8.669451 5.971089 -8.669451 11.0892 -8.669451 11.0892 -12.25751 11.0892 -12.25751 5.971089 -8.995275 -1.399212 -8.995275 1.356693 -12.53858 0.7917326 -12.53858 0.7917326 -12.53858 -0.8342516 -8.995275 -1.399212 8.669451 5.971089 12.25751 5.971089 12.25751 11.0892 12.25751 11.0892 8.669451 11.0892 8.669451 5.971089 -12.53858 0.7917326 -12.53858 -0.8342516 -8.995275 -1.399212 -8.995275 -1.399212 -8.995275 1.356693 -12.53858 0.7917326 -1.970048 5.605457 1.970048 5.605457 1.970048 7.427242 1.970048 7.427242 -1.970048 7.427242 -1.970048 5.605457 -12.25082 5.971089 -8.662755 5.971089 -8.662755 8.530145 -8.662755 8.530145 -12.25082 11.0892 -12.25082 5.971089 -8.662755 8.530145 -8.662755 11.0892 -12.25082 11.0892 12.53858 -0.8342516 12.53858 0.7917326 8.995275 1.356693 8.995275 1.356693 8.995275 -1.399212 12.53858 -0.8342516 -1.970048 2.861205 1.970048 2.861205 1.970048 7.011629 1.970048 7.011629 -1.970048 7.011629 -1.970048 2.861205 8.995275 0 8.995275 12.77454 3.089764 11.0892 3.089764 11.0892 3.089764 8.530145 8.995275 0 3.089764 8.530145 1.399212 5.971089 8.995275 0 1.399212 5.971089 -1.356693 1.965796 8.995275 0 -1.356693 1.965796 -8.995275 0 8.995275 0 3.089764 8.530145 1.399212 8.530145 1.399212 5.971089 1.399212 5.971089 -1.356693 5.971089 -1.356693 1.965796 -1.356693 1.965796 -8.995275 1.965796 -8.995275 0 -8.995275 4.395141 -8.995275 0 8.995275 0 8.995275 0 1.356693 1.965796 -8.995275 4.395141 1.356693 1.965796 -8.995275 5.976802 -8.995275 4.395141 1.356693 1.965796 -1.399212 5.971089 -8.995275 5.976802 -1.399212 5.971089 -3.089764 8.530145 -8.995275 5.976802 8.995275 0 8.995275 1.965796 1.356693 1.965796 -1.399212 5.971089 1.356693 1.965796 1.356693 5.971089 -3.089764 8.530145 -1.399212 5.971089 -1.399212 8.530145 -8.995275 5.976802 -3.089764 8.530145 -3.089764 11.0892 -3.089764 11.0892 -8.995275 15.3996 -8.995275 5.976802 10.57008 5.605457 10.57008 7.427242 8.995275 11.2673 8.995275 11.2673 8.995275 5.605457 10.57008 5.605457 1.970048 -10.57008 1.970048 -8.995275 -1.970048 -8.995275 -1.970048 -8.995275 -1.970048 -10.57008 1.970048 -10.57008 -10.57008 7.427242 -10.57008 5.605457 -8.995275 5.605457 -8.995275 5.605457 -8.995275 11.2673 -10.57008 7.427242 8.3452 6.629708 8.995275 5.976802 8.995275 15.3996 8.995275 15.3996 7.557798 7.420538 8.3452 6.629708 8.995275 15.3996 7.557798 11.2673 7.557798 7.420538 8.995275 15.3996 3.72772 11.2673 7.557798 11.2673 8.995275 15.3996 -0.03984409 15.05127 3.72772 11.2673 8.995275 15.3996 1.330304 15.3996 -0.03984409 15.05127 -5.434917 5.605457 -3.702483 4.96837 -1.970048 5.605457 -1.970048 5.605457 -3.737852 7.427242 -5.434917 5.605457 -1.970048 5.605457 -1.970048 11.2673 -3.737852 7.427242 -1.970048 11.2673 -3.737852 10.46976 -3.737852 7.427242 -1.970048 11.2673 -6.760264 10.46976 -3.737852 10.46976 -5.434917 5.605457 -3.737852 7.427242 -6.760264 7.427242 -3.702483 2.238624 -5.434917 5.605457 -6.760264 7.427242 -2.550579 0 -3.702483 2.238624 -6.760264 7.427242 -8.995275 0 -2.550579 0 -6.760264 7.427242 -6.760264 7.427242 -8.995275 12.77454 -8.995275 0 -6.760264 7.427242 -6.760264 10.46976 -8.995275 12.77454 -6.760264 10.46976 -1.970048 11.2673 -8.995275 12.77454 -1.296544 14.73178 -8.995275 12.77454 -1.970048 11.2673 -1.296544 14.73178 -1.970048 11.2673 1.970048 11.2673 2.152916 11.2673 -1.296544 14.73178 1.970048 11.2673 2.940318 10.47647 2.152916 11.2673 1.970048 11.2673 2.940318 6.629708 2.940318 10.47647 1.970048 11.2673 2.940318 6.629708 1.970048 11.2673 1.970048 5.605457 6.770397 6.629708 2.940318 6.629708 1.970048 5.605457 6.770397 6.629708 1.970048 5.605457 5.434917 5.605457 8.207875 5.185971 6.770397 6.629708 5.434917 5.605457 8.995275 4.395141 8.207875 5.185971 5.434917 5.605457 8.995275 4.395141 5.434917 5.605457 3.702483 2.238624 8.995275 4.395141 3.702483 2.238624 2.550579 0 2.550579 0 8.995275 0 8.995275 4.395141 3.702483 2.238624 0 1.369303 2.550579 0 0 1.369303 3.702483 2.238624 -3.702483 2.238624 -2.550579 0 0 1.369303 -3.702483 2.238624 3.702483 4.96837 5.434917 5.605457 1.970048 5.605457 -3.702483 2.238624 3.702483 2.238624 0 2.875711 8.995275 -8.995275 8.995275 8.995275 -8.995275 8.995275 -8.995275 8.995275 2.550579 -8.995275 8.995275 -8.995275 -8.995275 8.995275 -2.550579 -8.995275 2.550579 -8.995275 -8.995275 8.995275 -8.995275 -8.995275 -2.550579 -8.995275 -6.427799 7.761919 -4.070317 7.761919 -4.070317 10.13508 -4.070317 10.13508 -6.427799 10.13508 -6.427799 7.761919 -3.089764 11.0892 -3.089764 8.530145 -1.399212 8.530145 -3.089764 11.0892 -1.399212 8.530145 -1.399212 11.0892 -3.089764 11.0892 -1.399212 11.0892 8.995275 16.92913 -3.089764 11.0892 8.995275 16.92913 -8.995275 16.92913 -8.995275 16.92913 -8.995275 15.3996 -3.089764 11.0892 -1.399212 11.0892 1.356693 11.0892 8.995275 16.92913 1.356693 11.0892 8.995275 1.965796 8.995275 16.92913 8.995275 1.965796 1.356693 11.0892 1.356693 5.971089 1.356693 5.971089 1.356693 1.965796 8.995275 1.965796 -8.995275 1.965796 8.995275 1.965796 8.995275 16.92913 8.995275 16.92913 -8.995275 16.92913 -8.995275 1.965796 0 2.875711 3.702483 2.238624 5.434917 5.605457 5.434917 5.605457 3.702483 4.96837 0 2.875711 0 2.875711 3.702483 4.96837 -3.702483 4.96837 -3.702483 4.96837 3.702483 4.96837 1.970048 5.605457 1.970048 5.605457 -1.970048 5.605457 -3.702483 4.96837 0 2.875711 -3.702483 4.96837 -5.434917 5.605457 -5.434917 5.605457 -3.702483 2.238624 0 2.875711 -8.995275 8.995275 -8.995275 -8.995275 8.995275 -8.995275 8.995275 -8.995275 8.995275 8.995275 -8.995275 8.995275 8.995275 12.77454 8.995275 16.92913 -8.995275 16.92913 -8.995275 16.92913 3.089764 11.0892 8.995275 12.77454 -8.995275 16.92913 1.399212 11.0892 3.089764 11.0892 1.399212 11.0892 3.089764 8.530145 3.089764 11.0892 -8.995275 16.92913 -1.356693 11.0892 1.399212 11.0892 -8.995275 16.92913 -1.356693 5.971089 -1.356693 11.0892 -8.995275 16.92913 -1.356693 1.965796 -1.356693 5.971089 -8.995275 16.92913 -8.995275 1.965796 -1.356693 1.965796 3.089764 8.530145 1.399212 11.0892 1.399212 8.530145 8.207875 5.185971 8.995275 4.395141 8.995275 5.976802 8.995275 5.976802 6.770397 6.629708 8.207875 5.185971 8.995275 5.976802 8.3452 6.629708 6.770397 6.629708 8.3452 6.629708 7.557798 7.420538 6.770397 6.629708 7.557798 7.420538 2.940318 6.629708 6.770397 6.629708 7.557798 7.420538 2.940318 10.47647 2.940318 6.629708 7.557798 7.420538 7.557798 11.2673 2.940318 10.47647 7.557798 11.2673 2.152916 11.2673 2.940318 10.47647 7.557798 11.2673 3.72772 11.2673 2.152916 11.2673 3.72772 11.2673 -0.03984409 15.05127 2.152916 11.2673 -0.03984409 15.05127 -1.296544 14.73178 2.152916 11.2673 -1.296544 14.73178 -0.03984409 15.05127 -8.995275 16.92913 -8.995275 16.92913 -8.995275 12.77454 -1.296544 14.73178 -0.03984409 15.05127 1.330304 15.3996 -8.995275 16.92913 1.330304 15.3996 8.995275 16.92913 -8.995275 16.92913 1.330304 15.3996 8.995275 15.3996 8.995275 16.92913 0 -4.956824 2.550579 0 -2.550579 0 10.17638 1.166992 8.995275 1.166992 8.995275 -4.407553 -8.995275 1.166992 -10.17638 1.166992 -8.995275 -4.407553 -2.550579 -6.64672 2.550579 -6.64672 0 -4.838408 -8.995275 0.6476873 -10.17638 -2.247212 -8.995275 -2.247212 8.995275 -2.247212 10.17638 -2.247212 8.995275 0.6476873 0 -2.736826 2.550579 2.358771 -2.550579 2.358771 -31.61385 16.0528 1.19685 16.0528 1.19685 28.25752 1.19685 28.25752 -31.61385 28.25752 -31.61385 16.0528 -0.4822902 0 11.92764 0 11.92764 12.36163 11.92764 12.36163 -0.4822902 14.56534 -0.4822902 0 11.92764 12.36163 2.247496 17.62813 -0.4822902 14.56534 0 1.920166 0 28.49684 -12.01211 31.61385 -12.01211 31.61385 -12.01211 -1.19685 0 1.920166 -12.01211 -1.19685 -12.01211 31.61385 -89.5627 31.61385 -89.5627 31.61385 -89.5627 -1.19685 -12.01211 -1.19685 -89.5627 -1.19685 -89.5627 31.61385 -101.5748 28.49684 -101.5748 28.49684 -101.5748 1.920166 -89.5627 -1.19685 29.18248 6.333999 1.234523 6.333999 -1.19685 -4.414476 -1.19685 -4.414476 31.61385 -4.414476 29.18248 6.333999 1.19685 26.01761 1.19685 51.60816 -31.61385 51.60816 -31.61385 51.60816 -31.61385 26.01761 1.19685 26.01761 -31.61385 44.59658 1.19685 44.59658 1.19685 61.3043 1.19685 61.3043 -31.61385 61.3043 -31.61385 44.59658 -19.56752 0 -7.157581 0 -7.157581 14.56534 -7.157581 14.56534 -19.56752 12.36163 -19.56752 0 -7.157581 14.56534 -9.887368 17.62813 -19.56752 12.36163 -1.920166 0 -1.920166 14.56534 -28.49684 14.56534 -28.49684 14.56534 -28.49684 0 -1.920166 0 -1.920166 11.02847 -1.234523 15.07351 -29.18248 15.07351 -29.18248 15.07351 -28.49684 11.02847 -1.920166 11.02847 -91.16101 0 -78.75109 0 -78.75109 12.36163 -78.75109 12.36163 -91.16101 14.56534 -91.16101 0 -78.75109 12.36163 -88.43122 17.62813 -91.16101 14.56534 29.18248 -51.27668 1.234523 -51.27668 1.920166 -55.32171 1.920166 -55.32171 28.49684 -55.32171 29.18248 -51.27668 31.61385 -64.1987 -1.19685 -64.1987 -1.19685 -76.40343 -1.19685 -76.40343 31.61385 -76.40343 31.61385 -64.1987 -89.5627 0 -12.01211 0 -12.01211 12.36163 -12.01211 12.36163 -89.5627 12.36163 -89.5627 0 -12.01211 12.36163 -23.12119 17.4157 -89.5627 12.36163 -23.12119 17.4157 -78.45362 17.4157 -89.5627 12.36163 -23.12119 17.4157 -34.745 40.21402 -78.45362 17.4157 -34.745 40.21402 -66.82981 40.21402 -78.45362 17.4157 -34.745 40.21402 -50.7874 44.88189 -66.82981 40.21402 86.39096 0 98.80088 0 98.80088 14.56534 98.80088 14.56534 86.39096 12.36163 86.39096 0 98.80088 14.56534 96.07109 17.62813 86.39096 12.36163 31.61385 -36.22573 -1.19685 -36.22573 -1.19685 -52.93346 -1.19685 -52.93346 31.61385 -52.93346 31.61385 -36.22573 28.49684 14.56534 1.920166 14.56534 1.920166 0 1.920166 0 28.49684 0 28.49684 14.56534 31.61385 5.470592 -1.19685 5.470592 -1.19685 -20.11996 -1.19685 -20.11996 31.61385 -20.11996 31.61385 5.470592 -31.61385 84.13191 1.19685 84.13191 -1.234523 94.88039 -1.234523 94.88039 -29.18248 94.88039 -31.61385 84.13191 12.01211 0 89.5627 0 89.5627 12.36163 89.5627 12.36163 54.67737 10.75001 12.01211 0 89.5627 12.36163 54.67737 16.16361 54.67737 10.75001 89.5627 12.36163 78.45362 17.4157 54.67737 16.16361 78.45362 17.4157 56.28865 17.41494 54.67737 16.16361 78.45362 17.4157 57.52502 19.0457 56.28865 17.41494 78.45362 17.4157 66.82981 40.21402 57.52502 19.0457 66.82981 40.21402 58.30224 20.94476 57.52502 19.0457 66.82981 40.21402 58.56733 22.98271 58.30224 20.94476 66.82981 40.21402 58.30224 25.02065 58.56733 22.98271 66.82981 40.21402 57.52502 26.91972 58.30224 25.02065 66.82981 40.21402 56.28865 28.55048 57.52502 26.91972 66.82981 40.21402 54.67737 29.80181 56.28865 28.55048 66.82981 40.21402 52.80099 30.58842 54.67737 29.80181 66.82981 40.21402 50.7874 30.85672 52.80099 30.58842 12.01211 0 54.67737 10.75001 46.89743 10.75001 50.7874 30.85672 66.82981 40.21402 34.745 40.21402 48.77381 30.58842 50.7874 30.85672 34.745 40.21402 46.89743 29.80181 48.77381 30.58842 34.745 40.21402 45.28616 28.55048 46.89743 29.80181 34.745 40.21402 44.04978 26.91972 45.28616 28.55048 34.745 40.21402 43.27256 25.02065 44.04978 26.91972 34.745 40.21402 43.00747 22.98271 43.27256 25.02065 34.745 40.21402 43.27256 20.94476 43.00747 22.98271 34.745 40.21402 44.04978 19.0457 43.27256 20.94476 34.745 40.21402 44.04978 19.0457 34.745 40.21402 23.12119 17.4157 45.28616 17.41494 44.04978 19.0457 23.12119 17.4157 46.89743 16.16361 45.28616 17.41494 23.12119 17.4157 46.89743 10.75001 46.89743 16.16361 12.01211 12.36163 46.89743 16.16361 23.12119 17.4157 12.01211 12.36163 46.89743 10.75001 12.01211 12.36163 12.01211 0 66.82981 40.21402 50.7874 44.88189 34.745 40.21402 46.89743 10.75001 54.67737 10.75001 54.67737 16.16361 54.67737 16.16361 46.89743 16.16361 46.89743 10.75001 54.67737 16.16361 56.28865 17.41494 46.89743 16.16361 56.28865 17.41494 45.28616 17.41494 46.89743 16.16361 56.28865 17.41494 57.52502 19.0457 45.28616 17.41494 57.52502 19.0457 44.04978 19.0457 45.28616 17.41494 57.52502 19.0457 58.30224 20.94476 44.04978 19.0457 58.30224 20.94476 43.27256 20.94476 44.04978 19.0457 58.30224 20.94476 43.00747 22.98271 43.27256 20.94476 58.30224 20.94476 58.56733 22.98271 43.00747 22.98271 58.56733 22.98271 58.30224 25.02065 43.00747 22.98271 58.30224 25.02065 43.27256 25.02065 43.00747 22.98271 58.30224 25.02065 57.52502 26.91972 43.27256 25.02065 57.52502 26.91972 44.04978 26.91972 43.27256 25.02065 57.52502 26.91972 56.28865 28.55048 44.04978 26.91972 56.28865 28.55048 45.28616 28.55048 44.04978 26.91972 56.28865 28.55048 54.67737 29.80181 45.28616 28.55048 54.67737 29.80181 46.89743 29.80181 45.28616 28.55048 54.67737 29.80181 52.80099 30.58842 46.89743 29.80181 52.80099 30.58842 48.77381 30.58842 46.89743 29.80181 52.80099 30.58842 50.7874 30.85672 48.77381 30.58842 -11.33405 -16.52763 0 -16.52763 0 -0.4667578 0 -0.4667578 -11.33405 -0.4667578 -11.33405 -16.52763 -5.667024 0 -6.989858 -16.0063 4.344189 -16.0063 4.344189 -16.0063 5.667024 0 -5.667024 0 -11.33405 5.667024 -11.33405 -5.667024 0 -5.667024 0 -5.667024 0 5.667024 -11.33405 5.667024 -4.344189 -16.0063 6.989858 -16.0063 5.667024 0 5.667024 0 -5.667024 0 -4.344189 -16.0063 0 -15.59411 11.33405 -15.59411 11.33405 0.4667578 11.33405 0.4667578 0 0.4667578 0 -15.59411 11.33405 -8.422929 11.33405 5.667024 0 5.667024 0 5.667024 0 -8.422929 11.33405 -8.422929 0 -32.37059 11.33405 -32.37059 11.33405 -16.30972 11.33405 -16.30972 0 -16.30972 0 -32.37059 6.158686 -26.06348 6.989858 -16.0063 -4.344189 -16.0063 6.158686 -26.06348 -4.344189 -16.0063 -5.667024 -32.0126 6.158686 -26.06348 -5.667024 -32.0126 8.422929 -32.0126 8.422929 -32.0126 8.422929 -28.46929 6.158686 -26.06348 -8.422929 -28.46929 -8.422929 -32.0126 5.667024 -32.0126 5.667024 -32.0126 -6.158686 -26.06348 -8.422929 -28.46929 5.667024 -32.0126 4.344189 -16.0063 -6.158686 -26.06348 -6.989858 -16.0063 -6.158686 -26.06348 4.344189 -16.0063 -11.33405 -25.46767 0 -25.46767 0 -15.3762 0 -15.3762 -11.33405 -15.3762 -11.33405 -25.46767 -11.33405 -26.50426 0 -26.50426 0 -23.20052 0 -23.20052 -11.33405 -23.20052 -11.33405 -26.50426 -11.33405 -32.0126 0 -32.0126 0 -28.46929 0 -28.46929 -11.33405 -28.46929 -11.33405 -32.0126 -4.344189 -16.0063 6.989858 -16.0063 5.667024 0 5.667024 0 -5.667024 0 -4.344189 -16.0063 0 -16.52763 11.33405 -16.52763 11.33405 -0.4667578 11.33405 -0.4667578 0 -0.4667578 0 -16.52763 -11.33405 -15.59411 0 -15.59411 0 0.4667578 0 0.4667578 -11.33405 0.4667578 -11.33405 -15.59411 -5.667024 0 -6.989858 -16.0063 4.344189 -16.0063 4.344189 -16.0063 5.667024 0 -5.667024 0 0 5.667024 0 -5.667024 11.33405 -5.667024 11.33405 -5.667024 11.33405 5.667024 0 5.667024 -2.530103 1.814086 -1.076735 -5.913124 -1.076735 3.267454 -1.076735 3.267454 -10.25731 3.267454 -2.530103 1.814086 -10.25731 3.267454 -8.803945 1.814086 -2.530103 1.814086 -10.25731 3.267454 -8.803945 -4.459755 -8.803945 1.814086 -1.076735 -5.913124 -2.530103 1.814086 -2.530103 -4.459755 -2.530103 -4.459755 -10.25731 -5.913124 -1.076735 -5.913124 -2.530103 -4.459755 -8.803945 -4.459755 -10.25731 -5.913124 -8.803945 -4.459755 -10.25731 3.267454 -10.25731 -5.913124 4.344189 -11.47934 -6.989858 -11.47934 -5.913124 -14.80791 -5.913124 -14.80791 3.267454 -14.80791 4.344189 -11.47934 -10.25731 -17.06901 -1.076735 -17.06901 0 -13.74044 0 -13.74044 -11.33405 -13.74044 -10.25731 -17.06901 1.076735 -16.21318 10.25731 -16.21318 11.33405 -12.88461 11.33405 -12.88461 0 -12.88461 1.076735 -16.21318 5.913124 -18.47428 6.989858 -15.14571 -4.344189 -15.14571 -4.344189 -15.14571 -3.267454 -18.47428 5.913124 -18.47428 -3.502548 -3.48731 -3.502548 0.8416407 -7.831499 0.8416407 -7.831499 0.8416407 -7.831499 -3.48731 -3.502548 -3.48731 3.502548 -31.6584 7.831499 -31.6584 8.803945 -18.76498 8.803945 -18.76498 2.530103 -18.76498 3.502548 -31.6584 1.814086 -18.43733 -4.459755 -18.43733 -3.48731 -31.33075 -3.48731 -31.33075 0.8416407 -31.33075 1.814086 -18.43733 3.48731 -32.18559 4.459755 -19.29217 -1.814086 -19.29217 -1.814086 -19.29217 -0.8416407 -32.18559 3.48731 -32.18559 -7.831499 -31.85794 -3.502548 -31.85794 -2.530103 -18.96452 -2.530103 -18.96452 -8.803945 -18.96452 -7.831499 -31.85794 0 5.667024 0 -5.667024 7.236743 -5.667024 7.236743 -5.667024 7.236743 5.667024 0 5.667024 0 2.555619 0 -8.778429 11.33405 -8.778429 11.33405 -8.778429 11.33405 2.555619 0 2.555619 0 -10.48987 11.33405 -10.48987 7.236743 5.971582 7.236743 5.971582 0 5.971582 0 -10.48987 5.473925 -10.55481 5.667024 5.905512 -5.667024 5.905512 -5.667024 5.905512 -5.473925 -13.48828 5.473925 -10.55481 -5.473925 -10.55481 5.473925 -13.48828 5.503132 -10.55481 -11.33405 -13.43311 0 -13.43311 0 5.961641 0 5.961641 -11.33405 -10.4995 -11.33405 -13.43311 0 5.961641 -7.236743 5.961641 -11.33405 -10.4995 5.667024 3.982612 -5.667024 3.982612 -5.473925 -12.98 -5.473925 -12.98 5.503132 -12.98 5.667024 3.982612 -3.663994 -20.24303 7.283854 -17.30956 5.473925 -10.55481 5.473925 -10.55481 -5.473925 -13.48828 -3.663994 -20.24303 -5.473925 -10.55481 -7.283854 -17.30956 3.663994 -20.24303 3.663994 -20.24303 5.473925 -13.48828 -5.473925 -10.55481 -11.33405 -18.60495 0 -18.60495 0 -11.61192 0 -11.61192 -11.33405 -11.61192 -11.33405 -18.60495 0 -18.60495 11.33405 -18.60495 11.33405 -11.61192 11.33405 -11.61192 0 -11.61192 0 -18.60495 0 2.555619 0 -8.778429 7.393058 -8.778429 7.393058 -8.778429 7.393058 2.555619 0 2.555619 -5.963806 -8.526088 -7.938736 -13.73785 2.65988 -17.75406 2.65988 -17.75406 4.634811 -12.5423 -5.963806 -8.526088 0 -29.53897 7.393058 -29.53897 11.33405 -25.59799 11.33405 -25.59799 0 -18.60495 0 -29.53897 11.33405 -25.59799 11.33405 -18.60495 0 -18.60495 -7.283854 -17.30956 -9.093785 -24.06431 1.854064 -26.99778 1.854064 -26.99778 3.663994 -20.24303 -7.283854 -17.30956 -7.393058 -29.53897 0 -29.53897 0 -18.60495 0 -18.60495 -11.33405 -25.59799 -7.393058 -29.53897 0 -18.60495 -11.33405 -18.60495 -11.33405 -25.59799 -0.8340612 -30.80448 10.11379 -27.87102 7.283854 -17.30956 7.283854 -17.30956 -3.663994 -20.24303 -0.8340612 -30.80448 8.995275 15.55278 -8.995275 15.55278 -8.334019 5.717031 -8.334019 5.717031 8.334019 5.717031 8.995275 15.55278 0.04783993 9.704052 -12.55648 5.420008 12.55648 5.420008 12.55648 5.420008 13.22835 15.25503 0.04783993 9.704052 13.22835 15.25503 6.770758 15.25503 0.04783993 9.704052 -13.22835 15.25503 -12.55648 5.420008 0.04783993 9.704052 0.04783993 9.704052 -6.561206 15.25503 -13.22835 15.25503 8.995275 14.68347 8.995275 29.36693 -8.995275 29.36693 -8.995275 29.36693 -8.995275 14.68347 8.995275 14.68347 9.858189 5.635222 9.858189 -8.995275 13.22835 -8.995275 9.858189 5.635222 13.22835 -8.995275 13.22835 8.995275 -9.868293 5.635222 9.858189 5.635222 13.22835 8.995275 -9.868293 5.635222 13.22835 8.995275 -13.22835 8.995275 -9.868293 -8.995275 -9.868293 5.635222 -13.22835 8.995275 -13.22835 8.995275 -13.22835 -8.995275 -9.868293 -8.995275 -8.995275 29.36693 -8.995275 14.68347 8.995275 14.68347 8.995275 14.68347 8.995275 29.36693 -8.995275 29.36693 -13.22835 14.68347 13.22835 14.68347 13.22835 29.36693 13.22835 29.36693 -13.22835 29.36693 -13.22835 14.68347 8.334019 5.717031 8.995275 15.55278 -8.995275 15.55278 -8.995275 15.55278 -8.334019 5.717031 8.334019 5.717031 -12.55648 5.420008 12.55648 5.420008 13.22835 15.25503 13.22835 15.25503 -13.22835 15.25503 -12.55648 5.420008 -13.22835 14.68347 -6.561206 14.68347 -9.868293 29.36693 -9.868293 29.36693 -13.22835 29.36693 -13.22835 14.68347 6.770758 14.68347 13.22835 14.68347 13.22835 29.36693 13.22835 29.36693 9.858189 29.36693 6.770758 14.68347 -12.22299 0.5382689 12.22299 0.5382689 12.55648 5.420008 12.55648 5.420008 -12.55648 5.420008 -12.22299 0.5382689 8.005795 0.8349348 8.334019 5.717031 -8.334019 5.717031 -8.334019 5.717031 -8.005795 0.8349348 8.005795 0.8349348 12.22299 -8.005795 12.22299 8.005795 -12.22299 8.005795 -12.22299 8.005795 -12.22299 -8.005795 12.22299 -8.005795 -12.22299 0.5382689 12.22299 0.5382689 12.55648 5.420008 12.55648 5.420008 -12.55648 5.420008 -12.22299 0.5382689 8.334019 5.717031 -8.334019 5.717031 -8.005795 0.8349348 -8.005795 0.8349348 8.005795 0.8349348 8.334019 5.717031 -5.594878 24.84126 -2.403468 23.50158 -3.781421 25.88826 -4.96063 22.0252 -2.403468 23.50158 -5.594878 24.84126 -4.96063 22.0252 -5.594878 24.84126 -9.868293 29.36693 -4.96063 22.0252 -9.868293 29.36693 -6.561206 14.68347 -6.561206 14.68347 -3.307087 14.68347 -4.96063 22.0252 -5.594878 24.84126 -6.614173 29.36693 -9.868293 29.36693 0.07802933 12.4075 0.04783993 9.704052 6.770758 15.25503 6.770758 15.25503 3.526742 15.25503 0.07802933 12.4075 -6.561206 15.25503 0.04783993 9.704052 0.07802933 12.4075 0.07802933 12.4075 -3.307087 15.25503 -6.561206 15.25503 6.614173 2.381102 6.614173 -8.995275 9.858189 -8.995275 6.614173 2.381102 9.858189 -8.995275 9.858189 5.635222 6.60407 2.381102 6.614173 2.381102 9.858189 5.635222 -6.614173 2.381102 6.60407 2.381102 9.858189 5.635222 -6.614173 2.381102 9.858189 5.635222 -9.868293 5.635222 -6.614173 -8.995275 -6.614173 2.381102 -9.868293 5.635222 -9.868293 5.635222 -9.868293 -8.995275 -6.614173 -8.995275 3.526742 14.68347 6.770758 14.68347 9.858189 29.36693 9.858189 29.36693 5.070458 22.0252 3.526742 14.68347 9.858189 29.36693 5.66714 24.86295 5.070458 22.0252 5.66714 24.86295 2.513296 23.50158 5.070458 22.0252 9.858189 29.36693 6.614173 29.36693 5.66714 24.86295 2.513296 23.50158 5.66714 24.86295 3.891249 25.88826 0.07802933 12.4075 3.526742 15.25503 -3.307087 15.25503 -6.614173 2.381102 -6.614173 -8.995275 6.614173 -8.995275 6.614173 -8.995275 6.60407 2.381102 -6.614173 2.381102 6.614173 -8.995275 6.614173 2.381102 6.60407 2.381102 3.891249 25.88826 5.66714 24.86295 6.614173 29.36693 6.614173 29.36693 -3.781421 25.88826 3.891249 25.88826 -3.781421 25.88826 6.614173 29.36693 -6.614173 29.36693 -6.614173 29.36693 -5.594878 24.84126 -3.781421 25.88826 3.891249 25.88826 -3.781421 25.88826 -2.403468 23.50158 2.513296 23.50158 3.891249 25.88826 -2.403468 23.50158 5.070458 22.0252 2.513296 23.50158 -2.403468 23.50158 5.070458 22.0252 -2.403468 23.50158 -4.96063 22.0252 5.070458 22.0252 -4.96063 22.0252 -3.307087 14.68347 -3.307087 14.68347 3.526742 14.68347 5.070458 22.0252</float_array> + <technique_common> + <accessor source="#armRight_2-mesh-map-0-array" count="1398" stride="2"> + <param name="S" type="float"/> + <param name="T" type="float"/> + </accessor> + </technique_common> + </source> + <source id="armRight_2-mesh-colors-Col" name="Col"> + <float_array id="armRight_2-mesh-colors-Col-array" count="4194">0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 1 1 1 1 1 1 1 1 1 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.6470589 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.9294118 0.8862745 0.8039216 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.6313726 0.7607843 0.854902 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.8705883 0.7098039 0.5647059 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157 0.9176471 0.882353 0.8392157</float_array> + <technique_common> + <accessor source="#armRight_2-mesh-colors-Col-array" count="1398" stride="3"> + <param name="R" type="float"/> + <param name="G" type="float"/> + <param name="B" type="float"/> + </accessor> + </technique_common> + </source> + <vertices id="armRight_2-mesh-vertices"> + <input semantic="POSITION" source="#armRight_2-mesh-positions"/> + </vertices> + <triangles material="sand_001-material" count="128"> + <input semantic="VERTEX" source="#armRight_2-mesh-vertices" offset="0"/> + <input semantic="NORMAL" source="#armRight_2-mesh-normals" offset="1"/> + <input semantic="TEXCOORD" source="#armRight_2-mesh-map-0" offset="2" set="0"/> + <input semantic="COLOR" source="#armRight_2-mesh-colors-Col" offset="3" set="0"/> + <p>7 8 24 24 8 8 25 25 9 8 26 26 9 8 27 27 4 8 28 28 7 8 29 29 10 9 30 30 11 9 31 31 1 9 32 32 1 10 33 33 0 10 34 34 10 10 35 35 12 11 36 36 8 11 37 37 7 11 38 38 7 12 39 39 11 12 40 40 12 12 41 41 7 13 42 42 1 13 43 43 11 13 44 44 9 2 45 45 13 2 46 46 10 2 47 47 10 14 48 48 4 14 49 49 9 14 50 50 10 15 51 51 0 15 52 52 4 15 53 53 12 16 54 54 13 16 55 55 9 16 56 56 9 17 57 57 8 17 58 58 12 17 59 59 13 18 60 60 12 18 61 61 11 18 62 62 11 19 63 63 10 19 64 64 13 19 65 65 19 22 108 108 20 22 109 109 21 22 110 110 21 22 111 111 22 22 112 112 19 22 113 113 23 33 114 114 24 33 115 115 21 33 116 116 21 34 117 117 25 34 118 118 23 34 119 119 21 35 120 120 20 35 121 121 25 35 122 122 26 36 123 123 27 36 124 124 28 36 125 125 28 37 126 126 29 37 127 127 26 37 128 128 28 38 129 129 27 38 130 130 30 38 131 131 30 39 132 132 31 39 133 133 28 39 134 134 30 40 135 135 32 40 136 136 33 40 137 137 33 41 138 138 31 41 139 139 30 41 140 140 34 42 141 141 35 42 142 142 36 42 143 143 36 42 144 144 37 42 145 145 34 42 146 146 38 23 147 147 39 23 148 148 40 23 149 149 40 23 150 150 41 23 151 151 38 23 152 152 21 8 153 153 24 8 154 154 42 8 155 155 42 8 156 156 22 8 157 157 21 8 158 158 32 43 159 159 26 43 160 160 29 43 161 161 29 44 162 162 33 44 163 163 32 44 164 164 42 45 165 165 43 45 166 166 19 45 167 167 19 46 168 168 22 46 169 169 42 46 170 170 23 47 171 171 43 47 172 172 42 47 173 173 42 47 174 174 24 47 175 175 23 47 176 176 44 48 177 177 41 48 178 178 40 48 179 179 40 49 180 180 45 49 181 181 44 49 182 182 40 22 183 183 39 22 184 184 46 22 185 185 46 22 186 186 45 22 187 187 40 22 188 188 47 50 189 189 48 50 190 190 49 50 191 191 49 50 192 192 50 50 193 193 47 50 194 194 38 51 195 195 51 51 196 196 52 51 197 197 52 52 198 198 39 52 199 199 38 52 200 200 52 53 201 201 46 53 202 202 39 53 203 203 38 47 204 204 41 47 205 205 44 47 206 206 44 47 207 207 51 47 208 208 38 47 209 209 50 54 210 210 49 54 211 211 53 54 212 212 53 55 213 213 54 55 214 214 50 55 215 215 55 23 216 216 56 23 217 217 57 23 218 218 57 23 219 219 58 23 220 220 55 23 221 221 58 23 222 222 51 23 223 223 55 23 224 224 51 23 225 225 59 23 226 226 55 23 227 227 59 23 228 228 35 23 229 229 55 23 230 230 58 23 231 231 52 23 232 232 51 23 233 233 51 23 234 234 44 23 235 235 59 23 236 236 59 23 237 237 36 23 238 238 35 23 239 239 60 8 240 240 61 8 241 241 34 8 242 242 34 8 243 243 62 8 244 244 60 8 245 245 62 8 246 246 63 8 247 247 60 8 248 248 62 8 249 249 23 8 250 250 63 8 251 251 23 8 252 252 64 8 253 253 63 8 254 254 34 8 255 255 37 8 256 256 62 8 257 257 23 8 258 258 62 8 259 259 43 8 260 260 64 8 261 261 23 8 262 262 25 8 263 263 63 8 264 264 64 8 265 265 65 8 266 266 65 8 267 267 66 8 268 268 63 8 269 269 47 23 270 270 50 23 271 271 54 23 272 272 54 23 273 273 67 23 274 274 47 23 275 275 47 47 276 276 67 47 277 277 68 47 278 278 68 47 279 279 48 47 280 280 47 47 281 281 49 8 282 282 48 8 283 283 68 8 284 284 68 8 285 285 53 8 286 286 49 8 287 287 69 50 288 288 63 50 289 289 66 50 290 290 66 56 291 291 70 56 292 292 69 56 293 293 66 50 294 294 71 50 295 295 70 50 296 296 66 50 297 297 72 50 298 298 71 50 299 299 66 50 300 300 73 50 301 301 72 50 302 302 66 50 303 303 74 50 304 304 73 50 305 305 75 50 306 306 76 50 307 307 67 50 308 308 67 50 309 309 30 50 310 310 75 50 311 311 67 50 312 312 54 50 313 313 30 50 314 314 54 57 315 315 32 57 316 316 30 57 317 317 54 50 318 318 26 50 319 319 32 50 320 320 75 50 321 321 30 50 322 322 27 50 323 323 77 58 324 324 75 58 325 325 27 58 326 326 78 59 327 327 77 59 328 328 27 59 329 329 55 50 330 330 78 50 331 331 27 50 332 332 27 60 333 333 56 60 334 334 55 60 335 335 27 61 336 336 26 61 337 337 56 61 338 338 26 50 339 339 54 50 340 340 56 50 341 341 79 62 342 342 56 62 343 343 54 62 344 344 79 50 345 345 54 50 346 346 53 50 347 347 80 50 348 348 79 50 349 349 53 50 350 350 81 50 351 351 80 50 352 352 53 50 353 353 82 50 354 354 81 50 355 355 53 50 356 356 82 63 357 357 53 63 358 358 68 63 359 359 83 50 360 360 82 50 361 361 68 50 362 362 83 50 363 363 68 50 364 364 84 50 365 365 85 50 366 366 83 50 367 367 84 50 368 368 60 50 369 369 85 50 370 370 84 50 371 371 60 50 372 372 84 50 373 373 86 50 374 374 60 50 375 375 86 50 376 376 87 50 377 377 87 50 378 378 61 50 379 379 60 50 380 380 86 50 381 381 88 50 382 382 87 50 383 383 88 50 384 384 86 50 385 385 77 50 386 386 78 50 387 387 88 50 388 388 77 50 389 389 89 50 390 390 84 50 391 391 68 50 392 392 77 50 393 393 86 50 394 394 90 50 395 395 55 47 396 396 35 47 397 397 34 47 398 398 34 64 399 399 78 64 400 400 55 64 401 401 34 65 402 402 87 65 403 403 78 65 404 404 34 47 405 405 61 47 406 406 87 47 407 407 200 297 1134 1134 201 297 1135 1135 202 297 1136 1136 202 298 1137 1137 203 298 1138 1138 200 298 1139 1139 204 299 1140 1140 203 299 1141 1141 202 299 1142 1142 202 300 1143 1143 205 300 1144 1144 204 300 1145 1145 200 301 1146 1146 203 301 1147 1147 204 301 1148 1148 204 302 1149 1149 197 302 1150 1150 200 302 1151 1151 204 13 1152 1152 198 13 1153 1153 197 13 1154 1154 198 8 1155 1155 204 8 1156 1156 205 8 1157 1157 205 303 1158 1158 199 303 1159 1159 198 303 1160 1160 202 304 1161 1161 201 304 1162 1162 196 304 1163 1163 196 305 1164 1164 205 305 1165 1165 202 305 1166 1166 196 15 1167 1167 199 15 1168 1168 205 15 1169 1169 201 306 1170 1170 200 306 1171 1171 197 306 1172 1172 197 307 1173 1173 196 307 1174 1174 201 307 1175 1175</p> + </triangles> + <triangles material="textile_001-material" count="67"> + <input semantic="VERTEX" source="#armRight_2-mesh-vertices" offset="0"/> + <input semantic="NORMAL" source="#armRight_2-mesh-normals" offset="1"/> + <input semantic="TEXCOORD" source="#armRight_2-mesh-map-0" offset="2" set="0"/> + <input semantic="COLOR" source="#armRight_2-mesh-colors-Col" offset="3" set="0"/> + <p>0 0 0 0 1 0 1 1 2 0 2 2 2 1 3 3 3 1 4 4 0 1 5 5 4 2 6 6 0 2 7 7 3 2 8 8 3 3 9 9 5 3 10 10 4 3 11 11 6 4 12 12 7 4 13 13 4 4 14 14 4 5 15 15 5 5 16 16 6 5 17 17 2 6 18 18 1 6 19 19 7 6 20 20 7 7 21 21 6 7 22 22 2 7 23 23 140 223 813 813 128 223 814 814 129 223 815 815 129 224 816 816 150 224 817 817 140 224 818 818 129 225 819 819 130 225 820 820 150 225 821 821 130 226 822 822 149 226 823 823 150 226 824 824 130 227 825 825 131 227 826 826 149 227 827 827 131 228 828 828 148 228 829 829 149 228 830 830 131 229 831 831 132 229 832 832 148 229 833 833 132 230 834 834 147 230 835 835 148 230 836 836 132 231 837 837 146 231 838 838 147 231 839 839 132 232 840 840 133 232 841 841 146 232 842 842 133 233 843 843 134 233 844 844 146 233 845 845 134 234 846 846 145 234 847 847 146 234 848 848 134 235 849 849 135 235 850 850 145 235 851 851 135 236 852 852 144 236 853 853 145 236 854 854 135 237 855 855 136 237 856 856 144 237 857 857 136 238 858 858 143 238 859 859 144 238 860 860 136 239 861 861 137 239 862 862 143 239 863 863 137 240 864 864 142 240 865 865 143 240 866 866 137 241 867 867 138 241 868 868 142 241 869 869 138 242 870 870 141 242 871 871 142 242 872 872 138 243 873 873 139 243 874 874 141 243 875 875 175 47 990 990 176 47 991 991 177 47 992 992 177 269 993 993 178 269 994 994 175 269 995 995 178 270 996 996 179 270 997 997 175 270 998 998 178 47 999 999 180 47 1000 1000 179 47 1001 1001 176 47 1002 1002 175 47 1003 1003 181 47 1004 1004 181 271 1005 1005 182 271 1006 1006 176 271 1007 1007 181 272 1008 1008 180 272 1009 1009 182 272 1010 1010 180 47 1011 1011 178 47 1012 1012 182 47 1013 1013 173 273 1014 1014 171 273 1015 1015 182 273 1016 1016 182 274 1017 1017 178 274 1018 1018 173 274 1019 1019 178 275 1020 1020 177 275 1021 1021 167 275 1022 1022 167 276 1023 1023 173 276 1024 1024 178 276 1025 1025 176 277 1026 1026 182 277 1027 1027 171 277 1028 1028 171 278 1029 1029 168 278 1030 1030 176 278 1031 1031 176 279 1032 1032 168 279 1033 1033 167 279 1034 1034 167 280 1035 1035 177 280 1036 1036 176 280 1037 1037 196 293 1110 1110 197 293 1111 1111 191 293 1112 1112 191 294 1113 1113 192 294 1114 1114 196 294 1115 1115 194 8 1116 1116 198 8 1117 1117 199 8 1118 1118 199 8 1119 1119 193 8 1120 1120 194 8 1121 1121 199 295 1122 1122 196 295 1123 1123 192 295 1124 1124 192 296 1125 1125 193 296 1126 1126 199 296 1127 1127 197 6 1128 1128 198 6 1129 1129 194 6 1130 1130 194 7 1131 1131 191 7 1132 1132 197 7 1133 1133 235 343 1356 1356 236 343 1357 1357 233 343 1358 1358 240 22 1359 1359 234 22 1360 1360 238 22 1361 1361 238 344 1362 1362 239 344 1363 1363 240 344 1364 1364 238 22 1365 1365 237 22 1366 1366 239 22 1367 1367 244 50 1368 1368 242 50 1369 1369 238 50 1370 1370 238 50 1371 1371 231 50 1372 1372 244 50 1373 1373 231 50 1374 1374 238 50 1375 1375 234 50 1376 1376 234 345 1377 1377 229 345 1378 1378 231 345 1379 1379 244 50 1380 1380 231 50 1381 1381 230 50 1382 1382 243 50 1383 1383 244 50 1384 1384 230 50 1385 1385 241 50 1386 1386 243 50 1387 1387 230 50 1388 1388 241 50 1389 1389 230 50 1390 1390 232 50 1391 1391 241 50 1392 1392 232 50 1393 1393 233 50 1394 1394 233 50 1395 1395 236 50 1396 1396 241 50 1397 1397</p> + </triangles> + <triangles material="textileBlue_001-material" count="55"> + <input semantic="VERTEX" source="#armRight_2-mesh-vertices" offset="0"/> + <input semantic="NORMAL" source="#armRight_2-mesh-normals" offset="1"/> + <input semantic="TEXCOORD" source="#armRight_2-mesh-map-0" offset="2" set="0"/> + <input semantic="COLOR" source="#armRight_2-mesh-colors-Col" offset="3" set="0"/> + <p>2 20 66 66 14 20 67 67 15 20 68 68 15 21 69 69 16 21 70 70 2 21 71 71 15 22 72 72 14 22 73 73 17 22 74 74 17 22 75 75 18 22 76 76 15 22 77 77 3 23 78 78 2 23 79 79 16 23 80 80 18 24 81 81 17 24 82 82 6 24 83 83 6 25 84 84 5 25 85 85 18 25 86 86 5 26 87 87 3 26 88 88 16 26 89 89 16 27 90 90 18 27 91 91 5 27 92 92 16 28 93 93 15 28 94 94 18 28 95 95 2 29 96 96 3 29 97 97 5 29 98 98 5 30 99 99 6 30 100 100 2 30 101 101 2 31 102 102 6 31 103 103 17 31 104 104 17 32 105 105 14 32 106 106 2 32 107 107 187 22 1068 1068 188 22 1069 1069 189 22 1070 1070 189 22 1071 1071 190 22 1072 1072 187 22 1073 1073 191 29 1074 1074 192 29 1075 1075 193 29 1076 1076 193 30 1077 1077 194 30 1078 1078 191 30 1079 1079 191 31 1080 1080 194 31 1081 1081 189 31 1082 1082 189 32 1083 1083 188 32 1084 1084 191 32 1085 1085 191 23 1086 1086 188 23 1087 1087 187 23 1088 1088 187 288 1089 1089 192 288 1090 1090 191 288 1091 1091 194 289 1092 1092 193 289 1093 1093 195 289 1094 1094 193 27 1095 1095 192 27 1096 1096 187 27 1097 1097 187 290 1098 1098 195 290 1099 1099 193 290 1100 1100 187 28 1101 1101 190 28 1102 1102 195 28 1103 1103 190 291 1104 1104 189 291 1105 1105 194 291 1106 1106 194 292 1107 1107 195 292 1108 1108 190 292 1109 1109 206 308 1176 1176 207 308 1177 1177 208 308 1178 1178 208 309 1179 1179 209 309 1180 1180 206 309 1181 1181 210 310 1182 1182 211 310 1183 1183 208 310 1184 1184 208 311 1185 1185 207 311 1186 1186 210 311 1187 1187 207 312 1188 1188 212 312 1189 1189 210 312 1190 1190 213 313 1191 1191 211 313 1192 1192 210 313 1193 1193 210 314 1194 1194 214 314 1195 1195 213 314 1196 1196 213 23 1197 1197 215 23 1198 1198 216 23 1199 1199 216 23 1200 1200 217 23 1201 1201 213 23 1202 1202 218 22 1203 1203 219 22 1204 1204 220 22 1205 1205 218 22 1206 1206 220 22 1207 1207 221 22 1208 1208 222 315 1209 1209 218 315 1210 1210 221 315 1211 1211 222 316 1212 1212 221 316 1213 1213 216 316 1214 1214 223 22 1215 1215 222 22 1216 1216 216 22 1217 1217 216 22 1218 1218 215 22 1219 1219 223 22 1220 1220 220 8 1221 1221 207 8 1222 1222 206 8 1223 1223 206 8 1224 1224 221 8 1225 1225 220 8 1226 1226 206 42 1227 1227 217 42 1228 1228 216 42 1229 1229 216 42 1230 1230 221 42 1231 1231 206 42 1232 1232 211 317 1233 1233 213 317 1234 1234 217 317 1235 1235 217 318 1236 1236 224 318 1237 1237 211 318 1238 1238 209 319 1239 1239 224 319 1240 1240 217 319 1241 1241 217 320 1242 1242 206 320 1243 1243 209 320 1244 1244 213 50 1245 1245 214 50 1246 1246 223 50 1247 1247 223 50 1248 1248 215 50 1249 1249 213 50 1250 1250 212 50 1251 1251 207 50 1252 1252 220 50 1253 1253 220 50 1254 1254 219 50 1255 1255 212 50 1256 1256</p> + </triangles> + <triangles material="iron_001-material" count="155"> + <input semantic="VERTEX" source="#armRight_2-mesh-vertices" offset="0"/> + <input semantic="NORMAL" source="#armRight_2-mesh-normals" offset="1"/> + <input semantic="TEXCOORD" source="#armRight_2-mesh-map-0" offset="2" set="0"/> + <input semantic="COLOR" source="#armRight_2-mesh-colors-Col" offset="3" set="0"/> + <p>28 50 408 408 31 50 409 409 33 50 410 410 33 50 411 411 29 50 412 412 28 50 413 413 65 8 414 414 64 8 415 415 25 8 416 416 65 8 417 417 25 8 418 418 20 8 419 419 65 8 420 420 20 8 421 421 91 8 422 422 65 8 423 423 91 8 424 424 92 8 425 425 92 8 426 426 66 8 427 427 65 8 428 428 20 66 429 429 19 66 430 430 91 66 431 431 19 8 432 432 37 8 433 433 91 8 434 434 37 8 435 435 19 8 436 436 43 8 437 437 43 8 438 438 62 8 439 439 37 8 440 440 37 42 441 441 36 42 442 442 93 42 443 443 93 42 444 444 91 42 445 445 37 42 446 446 90 50 447 447 86 50 448 448 84 50 449 449 84 50 450 450 89 50 451 451 90 50 452 452 90 50 453 453 89 50 454 454 76 50 455 455 76 50 456 456 89 50 457 457 68 50 458 458 68 50 459 459 67 50 460 460 76 50 461 461 90 50 462 462 76 50 463 463 75 50 464 464 75 67 465 465 77 67 466 466 90 67 467 467 93 22 468 468 94 22 469 469 92 22 470 470 92 22 471 471 91 22 472 472 93 22 473 473 56 23 474 474 94 23 475 475 93 23 476 476 93 68 477 477 57 68 478 478 56 68 479 479 93 69 480 480 46 69 481 481 57 69 482 482 46 23 483 483 58 23 484 484 57 23 485 485 93 70 486 486 45 70 487 487 46 70 488 488 93 23 489 489 44 23 490 490 45 23 491 491 93 23 492 492 59 23 493 493 44 23 494 494 93 23 495 495 36 23 496 496 59 23 497 497 58 23 498 498 46 23 499 499 52 23 500 500 85 50 501 501 60 50 502 502 63 50 503 503 63 50 504 504 83 50 505 505 85 50 506 506 63 50 507 507 69 50 508 508 83 50 509 509 69 50 510 510 70 50 511 511 83 50 512 512 70 50 513 513 82 50 514 514 83 50 515 515 70 50 516 516 81 50 517 517 82 50 518 518 70 50 519 519 71 50 520 520 81 50 521 521 71 50 522 522 80 50 523 523 81 50 524 524 71 50 525 525 72 50 526 526 80 50 527 527 72 50 528 528 73 50 529 529 80 50 530 530 73 50 531 531 79 50 532 532 80 50 533 533 79 50 534 534 73 50 535 535 94 50 536 536 94 50 537 537 56 50 538 538 79 50 539 539 73 71 540 540 74 71 541 541 94 71 542 542 74 50 543 543 92 50 544 544 94 50 545 545 74 50 546 546 66 50 547 547 92 50 548 548 95 42 549 549 78 42 550 550 87 42 551 551 96 72 552 552 78 72 553 553 95 72 554 554 87 73 555 555 97 73 556 556 95 73 557 557 96 74 558 558 97 74 559 559 88 74 560 560 88 75 561 561 97 75 562 562 87 75 563 563 78 76 564 564 96 76 565 565 88 76 566 566 95 77 567 567 97 77 568 568 96 77 569 569 98 78 570 570 99 79 571 571 100 80 572 572 100 81 573 573 101 82 574 574 98 83 575 575 102 84 576 576 103 85 577 577 99 86 578 578 99 87 579 579 104 88 580 580 102 89 581 581 99 90 582 582 105 91 583 583 104 92 584 584 102 93 585 585 106 93 586 586 107 93 587 587 107 94 588 588 103 94 589 589 102 94 590 590 103 95 591 591 107 95 592 592 108 95 593 593 108 96 594 594 109 96 595 595 103 96 596 596 109 97 597 597 108 97 598 598 110 97 599 599 110 98 600 600 111 98 601 601 109 98 602 602 112 99 603 603 105 100 604 604 99 101 605 605 99 102 606 606 98 103 607 607 112 104 608 608 100 105 609 609 113 106 610 610 114 107 611 611 114 108 612 612 101 109 613 613 100 110 614 614 114 111 615 615 113 112 616 616 115 113 617 617 115 114 618 618 116 115 619 619 114 116 620 620 107 117 621 621 106 118 622 622 117 119 623 623 117 120 624 624 98 121 625 625 107 122 626 626 117 123 627 627 112 124 628 628 98 125 629 629 102 126 630 630 104 126 631 631 117 126 632 632 117 127 633 633 106 127 634 634 102 127 635 635 104 128 636 636 105 129 637 637 112 130 638 638 112 131 639 639 117 132 640 640 104 133 641 641 110 134 642 642 108 135 643 643 118 136 644 644 118 137 645 645 119 138 646 646 110 139 647 647 118 140 648 648 120 141 649 649 119 142 650 650 120 143 651 651 121 144 652 652 122 145 653 653 122 146 654 654 119 147 655 655 120 148 656 656 123 149 657 657 124 150 658 658 125 151 659 659 125 152 660 660 118 153 661 661 123 154 662 662 108 155 663 663 107 155 664 664 98 155 665 665 98 156 666 666 118 156 667 667 108 156 668 668 98 157 669 669 101 157 670 670 118 157 671 671 101 158 672 672 123 158 673 673 118 158 674 674 101 159 675 675 114 159 676 676 123 159 677 677 114 160 678 678 126 160 679 679 123 160 680 680 114 161 681 681 116 161 682 682 126 161 683 683 109 162 684 684 111 163 685 685 122 164 686 686 122 165 687 687 125 166 688 688 109 167 689 689 122 168 690 690 121 169 691 691 125 170 692 692 116 171 693 693 115 172 694 694 127 173 695 695 127 174 696 696 126 175 697 697 116 176 698 698 119 177 699 699 122 177 700 700 111 177 701 701 111 178 702 702 110 178 703 703 119 178 704 704 126 179 705 705 127 180 706 706 124 181 707 707 124 182 708 708 123 183 709 709 126 184 710 710 118 185 711 711 125 186 712 712 121 187 713 713 121 188 714 714 120 189 715 715 118 190 716 716 103 191 717 717 109 191 718 718 125 191 719 719 125 192 720 720 128 192 721 721 103 192 722 722 125 193 723 723 129 193 724 724 128 193 725 725 125 194 726 726 124 194 727 727 129 194 728 728 124 195 729 729 130 195 730 730 129 195 731 731 124 196 732 732 131 196 733 733 130 196 734 734 124 197 735 735 127 197 736 736 131 197 737 737 127 198 738 738 132 198 739 739 131 198 740 740 127 199 741 741 133 199 742 742 132 199 743 743 127 200 744 744 134 200 745 745 133 200 746 746 127 201 747 747 135 201 748 748 134 201 749 749 127 202 750 750 136 202 751 751 135 202 752 752 127 203 753 753 137 203 754 754 136 203 755 755 127 204 756 756 138 204 757 757 137 204 758 758 127 205 759 759 139 205 760 760 138 205 761 761 103 206 762 762 128 206 763 763 140 206 764 764 139 207 765 765 127 207 766 766 113 207 767 767 141 208 768 768 139 208 769 769 113 208 770 770 142 209 771 771 141 209 772 772 113 209 773 773 143 210 774 774 142 210 775 775 113 210 776 776 144 211 777 777 143 211 778 778 113 211 779 779 145 212 780 780 144 212 781 781 113 212 782 782 146 213 783 783 145 213 784 784 113 213 785 785 147 214 786 786 146 214 787 787 113 214 788 788 148 215 789 789 147 215 790 790 113 215 791 791 148 216 792 792 113 216 793 793 100 216 794 794 149 217 795 795 148 217 796 796 100 217 797 797 150 218 798 798 149 218 799 799 100 218 800 800 140 219 801 801 150 219 802 802 99 219 803 803 150 220 804 804 100 220 805 805 99 220 806 806 140 221 807 807 99 221 808 808 103 221 809 809 127 222 810 810 115 222 811 811 113 222 812 812 151 244 876 876 152 244 877 877 153 244 878 878 153 245 879 879 154 245 880 880 151 245 881 881 153 246 882 882 152 246 883 883 155 246 884 884 155 8 885 885 156 8 886 886 153 8 887 887 157 22 888 888 154 22 889 889 153 22 890 890 153 22 891 891 156 22 892 892 157 22 893 893 158 247 894 894 151 247 895 895 154 247 896 896 154 248 897 897 157 248 898 898 158 248 899 899 155 249 900 900 158 249 901 901 157 249 902 902 157 250 903 903 156 250 904 904 155 250 905 905 167 261 960 960 168 261 961 961 169 261 962 962 169 262 963 963 170 262 964 964 167 262 965 965 168 263 966 966 171 263 967 967 172 263 968 968 172 264 969 969 169 264 970 970 168 264 971 971 173 265 972 972 167 265 973 973 170 265 974 974 170 266 975 975 174 266 976 976 173 266 977 977 172 267 978 978 171 267 979 979 173 267 980 980 173 268 981 981 174 268 982 982 172 268 983 983 170 22 984 984 169 22 985 985 172 22 986 986 172 22 987 987 174 22 988 988 170 22 989 989</p> + </triangles> + <triangles material="wood_001-material" count="61"> + <input semantic="VERTEX" source="#armRight_2-mesh-vertices" offset="0"/> + <input semantic="NORMAL" source="#armRight_2-mesh-normals" offset="1"/> + <input semantic="TEXCOORD" source="#armRight_2-mesh-map-0" offset="2" set="0"/> + <input semantic="COLOR" source="#armRight_2-mesh-colors-Col" offset="3" set="0"/> + <p>159 47 906 906 160 47 907 907 161 47 908 908 161 47 909 909 162 47 910 910 159 47 911 911 161 251 912 912 160 251 913 913 158 251 914 914 158 252 915 915 155 252 916 916 161 252 917 917 163 253 918 918 151 253 919 919 158 253 920 920 163 254 921 921 158 254 922 922 160 254 923 923 163 23 924 924 160 23 925 925 159 23 926 926 159 23 927 927 164 23 928 928 163 23 929 929 165 8 930 930 162 8 931 931 161 8 932 932 161 255 933 933 166 255 934 934 165 255 935 935 161 8 936 936 155 8 937 937 166 8 938 938 152 256 939 939 166 256 940 940 155 256 941 941 163 257 942 942 166 257 943 943 152 257 944 944 152 258 945 945 151 258 946 946 163 258 947 947 164 259 948 948 165 259 949 949 166 259 950 950 166 260 951 951 163 260 952 952 164 260 953 953 159 50 954 954 162 50 955 955 165 50 956 956 165 50 957 957 164 50 958 958 159 50 959 959 183 47 1038 1038 184 47 1039 1039 185 47 1040 1040 185 47 1041 1041 186 47 1042 1042 183 47 1043 1043 183 281 1044 1044 186 281 1045 1045 180 281 1046 1046 180 281 1047 1047 181 281 1048 1048 183 281 1049 1049 179 282 1050 1050 180 282 1051 1051 186 282 1052 1052 186 283 1053 1053 185 283 1054 1054 179 283 1055 1055 183 284 1056 1056 181 284 1057 1057 175 284 1058 1058 175 285 1059 1059 184 285 1060 1060 183 285 1061 1061 185 286 1062 1062 184 286 1063 1063 175 286 1064 1064 175 287 1065 1065 179 287 1066 1066 185 287 1067 1067 225 321 1257 1257 226 321 1258 1258 224 321 1259 1259 224 322 1260 1260 209 322 1261 1261 225 322 1262 1262 227 323 1263 1263 211 323 1264 1264 224 323 1265 1265 224 324 1266 1266 226 324 1267 1267 227 324 1268 1268 227 47 1269 1269 226 47 1270 1270 225 47 1271 1271 225 47 1272 1272 228 47 1273 1273 227 47 1274 1274 227 325 1275 1275 228 325 1276 1276 208 325 1277 1277 208 326 1278 1278 211 326 1279 1279 227 326 1280 1280 209 327 1281 1281 208 327 1282 1282 228 327 1283 1283 228 328 1284 1284 225 328 1285 1285 209 328 1286 1286 229 329 1287 1287 230 329 1288 1288 231 329 1289 1289 232 330 1290 1290 230 330 1291 1291 229 330 1292 1292 232 331 1293 1293 229 331 1294 1294 223 331 1295 1295 232 332 1296 1296 223 332 1297 1297 214 332 1298 1298 214 50 1299 1299 233 50 1300 1300 232 50 1301 1301 229 50 1302 1302 234 50 1303 1303 223 50 1304 1304 235 333 1305 1305 210 333 1306 1306 212 333 1307 1307 212 334 1308 1308 236 334 1309 1309 235 334 1310 1310 214 335 1311 1311 210 335 1312 1312 235 335 1313 1313 235 336 1314 1314 233 336 1315 1315 214 336 1316 1316 237 22 1317 1317 238 22 1318 1318 219 22 1319 1319 237 22 1320 1320 219 22 1321 1321 218 22 1322 1322 239 22 1323 1323 237 22 1324 1324 218 22 1325 1325 240 337 1326 1326 239 337 1327 1327 218 337 1328 1328 240 338 1329 1329 218 338 1330 1330 222 338 1331 1331 234 22 1332 1332 240 22 1333 1333 222 22 1334 1334 222 22 1335 1335 223 22 1336 1336 234 22 1337 1337 236 50 1338 1338 212 50 1339 1339 219 50 1340 1340 219 339 1341 1341 241 339 1342 1342 236 339 1343 1343 219 340 1344 1344 242 340 1345 1345 241 340 1346 1346 242 341 1347 1347 243 341 1348 1348 241 341 1349 1349 219 50 1350 1350 238 50 1351 1351 242 50 1352 1352 243 342 1353 1353 242 342 1354 1354 244 342 1355 1355</p> + </triangles> + </mesh> + </geometry> + </library_geometries> + <library_controllers> + <controller id="Armature_pirate-officer-skin" name="Armature"> + <skin source="#armRight_2-mesh"> + <bind_shape_matrix>0.1514977 -2.01481e-4 -6.3167e-5 0.003487766 -6.33061e-5 -1.02032e-4 -0.1514978 0.001529097 2.01393e-4 0.1514977 -1.02117e-4 7.57932e-4 0 0 0 1</bind_shape_matrix> + <source id="Armature_pirate-officer-skin-joints"> + <Name_array id="Armature_pirate-officer-skin-joints-array" count="11">Step core arm_r arm_r_1 arm_l arm_l_1 head leg_l leg_l_1 leg_r leg_r_1</Name_array> + <technique_common> + <accessor source="#Armature_pirate-officer-skin-joints-array" count="11" stride="1"> + <param name="JOINT" type="name"/> + </accessor> + </technique_common> + </source> + <source id="Armature_pirate-officer-skin-bind_poses"> + <float_array id="Armature_pirate-officer-skin-bind_poses-array" count="176">0.9999153 -4.08413e-4 -0.01301229 0.0116567 0.01301199 -6.79513e-4 0.9999151 -0.670503 -4.17221e-4 -0.9999997 -6.74089e-4 0.02088719 0 0 0 1 0.9999992 -4.17846e-4 0.00132966 -0.001190602 -0.001329898 -6.73586e-4 0.9999989 -0.8957912 -4.1695e-4 -0.9999997 -6.74089e-4 0.02088707 0 0 0 1 -4.17256e-4 -1.000002 -6.74165e-4 0.02088737 0.2405146 5.54513e-4 -0.9706454 0.9874006 0.9706456 -5.67168e-4 0.2405143 -0.5605208 0 0 0 1 4.17114e-4 1.000002 6.74084e-4 -0.02088713 -0.03126174 6.87273e-4 -0.9995108 0.8813203 -0.9995113 3.95717e-4 0.03126209 0.3343999 0 0 0 1 -4.17256e-4 -1.000002 -6.74015e-4 0.02088695 -0.237932 7.53543e-4 -0.9712815 0.9871978 0.9712818 -2.44893e-4 -0.2379322 0.5613447 0 0 0 1 4.16871e-4 1.000002 6.74041e-4 -0.02088713 0.03392028 6.59136e-4 -0.9994247 0.8813487 -0.9994245 4.39378e-4 -0.03391999 -0.3352481 0 0 0 1 0.9999856 -0.001201391 -0.005246043 0.006351053 0.00503534 -0.1352643 0.9907967 -1.13126 -0.001899957 -0.9908088 -0.1352563 0.1747332 0 0 0 1 -0.9997861 2.27078e-4 0.00772494 -0.12509 -0.007727622 0.00974065 -0.9999226 0.6469785 -9.32847e-4 -0.9994118 -0.009721815 0.0203334 0 0 0 1 0.9997422 1.37847e-4 -0.01215755 0.1263704 -0.01213753 0.04115223 -0.9990785 0.2890269 9.93053e-4 0.9986117 0.0411511 -0.02947407 0 0 0 1 -0.9998788 1.57881e-4 0.01514071 0.1219941 -0.01513856 0.008916616 -0.9998458 0.6501998 -2.40851e-4 -0.9998601 -0.008912146 0.01985657 0 0 0 1 0.9999924 -4.16031e-4 0.001330256 -0.1262257 0.001345455 0.04410344 -0.999026 0.2551205 3.04984e-4 0.9989264 0.04410648 -0.02886915 0 0 0 1</float_array> + <technique_common> + <accessor source="#Armature_pirate-officer-skin-bind_poses-array" count="11" stride="16"> + <param name="TRANSFORM" type="float4x4"/> + </accessor> + </technique_common> + </source> + <source id="Armature_pirate-officer-skin-weights"> + <float_array id="Armature_pirate-officer-skin-weights-array" count="389">0.05213558 0.9478644 0.1899004 0.8100996 0.84301 0.15699 0.1773984 0.8226016 0.1195933 0.8804067 0.7800852 0.2199148 0.9080803 0.09191966 0.1737173 0.8262827 0.02473646 0.9752635 1 1 0.06139206 0.9386079 0.01378506 0.9862149 1 1 0.9226101 0.07738989 0.2226876 0.7773125 1 0.9937509 0.00624901 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0.9047116 0.09528845 0.9059758 0.09402424 1 0.9717712 0.02822875 0.9402328 0.05976724 1 0.9845243 0.01547574 0.9395211 0.06047892 0.04861068 0.9513894 0.08833265 0.9116673 0.08538228 0.9146177 0.04269641 0.9573035 0.1260594 0.8739406 0.07733201 0.9226679 0.07454377 0.9254563 0.1288383 0.8711618 1 1 1 1 1 1 1 1 0.9603103 0.03968966 0.9827364 0.01726359 0.9943599 0.005640029 1 0.9694613 0.03053873 0.9494155 0.05058455 0.9436487 0.05635124 0.9874487 0.0125513 0.01423943 0.9857605 0.02413737 0.9758626 0.01615571 0.9838443 0.01339161 0.9866085 0.9303661 0.0696339 0.9964635 0.003536581 0.9391304 0.06086957 0.9212784 0.07872152 0.8224475 0.1775525 0.1542633 0.8457366 0.4910525 0.5089476 0.1145493 0.8854507 0.3708948 0.6291052 0.02560091 0.9743991 0.1465738 0.8534262 0.03300833 0.9669916 0.08633691 0.9136631 0.006125152 0.9938749 1 1 1 1 1 0.718256 0.2185608 0.06318312 0.07384365 0.606957 0.3011262 0.0180732 0.1280035 0.16171 0.6958557 0.0144307 0.2175812 0.6860687 0.09635001 0.5727672 0.1842584 0.1096959 0.1332785 0.1003786 0.1050215 0.7945998 0.1588721 0.6609361 0.1397838 0.04040789 0.06267875 0.528815 0.4085063 0.1537362 0.6480134 0.01249241 0.1857578 0.005560278 0.8144975 0.1799421 0.6885762 0.02777433 0.2836494 0.4025522 0.0555787 0.5418691 0.8466262 0.09489125 0.0584824 0.904197 0.08448588 0.01131713 0.8654766 0.117038 0.01748532 0.8216587 0.1221829 0.05615836 0.7661764 0.02213209 0.2116914 0.8670787 0.1329212 0.1071336 0.04174888 0.8511176 0.01670169 0.1939637 0.622469 0.1668655 0.05870777 0.05072677 0.8905654 0.03537517 0.05136573 0.004890501 0.9083685 0.1032173 0.1552547 0.6174408 0.1240872 0.04038077 0.8784406 0.08117854 0.05065423 0.8918457 0.0575 0.01714318 0.9239619 0.05889481 0.06628447 0.8511596 0.08255594 0.2015518 0.6648296 0.02822512 0.1053933 0.9193989 0.08060121 0.476592 0.3615991 0.07283937 0.0889694 0.1913447 0.6778306 0.0835464 0.04727816 0.8874095 0.06110209 0.05148833 0.9444072 0.04936325 0.006229579 0.88745 0.06103748 0.05151247 0.8605926 0.008665084 0.1307423 0.08605635 0.8358218 0.06047517 0.01764667 0.05510008 0.8763101 0.05619597 0.01239371 0.05999439 0.8799242 0.03371661 0.0263648 0.02918142 0.9247466 0.03212571 0.01394611</float_array> + <technique_common> + <accessor source="#Armature_pirate-officer-skin-weights-array" count="389" stride="1"> + <param name="WEIGHT" type="float"/> + </accessor> + </technique_common> + </source> + <joints> + <input semantic="JOINT" source="#Armature_pirate-officer-skin-joints"/> + <input semantic="INV_BIND_MATRIX" source="#Armature_pirate-officer-skin-bind_poses"/> + </joints> + <vertex_weights count="245"> + <input semantic="JOINT" source="#Armature_pirate-officer-skin-joints" offset="0"/> + <input semantic="WEIGHT" source="#Armature_pirate-officer-skin-weights" offset="1"/> + <vcount>2 2 2 2 2 2 2 2 2 1 1 2 2 1 1 2 2 1 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 1 2 2 1 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 3 4 4 3 4 3 4 3 4 3 3 3 3 3 3 3 3 2 3 4 3 4 4 3 3 3 3 4 2 4 4 3 3 3 3 4 4 4 4 </vcount> + <v>2 0 3 1 2 2 3 3 2 4 3 5 2 6 3 7 2 8 3 9 2 10 3 11 2 12 3 13 2 14 3 15 2 16 3 17 3 18 3 19 2 20 3 21 2 22 3 23 3 24 2 25 2 26 3 27 2 28 3 29 2 30 2 31 3 32 6 33 6 34 6 35 6 36 6 37 6 38 6 39 6 40 6 41 6 42 6 43 6 44 6 45 6 46 6 47 6 48 6 49 6 50 6 51 6 52 6 53 6 54 6 55 6 56 6 57 6 58 6 59 6 60 6 61 6 62 6 63 6 64 6 65 6 66 6 67 6 68 6 69 6 70 6 71 6 72 6 73 6 74 6 75 6 76 6 77 6 78 6 79 6 80 6 81 6 82 6 83 6 84 6 85 6 86 6 87 6 88 6 89 6 90 6 91 6 92 6 93 6 94 6 95 6 96 6 97 6 98 6 99 6 100 6 101 6 102 6 103 6 104 6 105 6 106 6 107 6 108 6 109 6 110 6 111 6 112 6 113 6 114 6 115 6 116 6 117 6 118 6 119 6 120 6 121 6 122 6 123 6 124 6 125 6 126 6 127 6 128 6 129 6 130 6 131 6 132 6 133 6 134 6 135 6 136 6 137 6 138 6 139 6 140 6 141 6 142 6 143 6 144 6 145 6 146 6 147 6 148 6 149 6 150 6 151 6 152 6 153 6 154 6 155 6 156 6 157 6 158 6 159 6 160 6 161 6 162 6 163 6 164 7 165 8 166 7 167 8 168 7 169 7 170 8 171 7 172 8 173 7 174 7 175 8 176 7 177 8 178 7 179 8 180 7 181 8 182 7 183 8 184 7 185 8 186 7 187 8 188 7 189 8 190 7 191 8 192 7 193 8 194 9 195 9 196 9 197 9 198 9 199 9 200 9 201 9 202 9 203 10 204 9 205 10 206 9 207 10 208 9 209 9 210 10 211 9 212 10 213 9 214 10 215 9 216 10 217 9 218 10 219 9 220 10 221 9 222 10 223 9 224 10 225 4 226 5 227 4 228 5 229 4 230 5 231 4 232 5 233 4 234 5 235 4 236 5 237 4 238 5 239 4 240 5 241 4 242 5 243 4 244 5 245 4 246 5 247 4 248 5 249 4 250 5 251 4 252 5 253 5 254 5 255 5 256 5 257 5 258 1 259 7 260 9 261 0 262 1 263 7 264 9 265 0 266 1 267 7 268 9 269 1 270 7 271 9 272 0 273 1 274 7 275 9 276 0 277 1 278 9 279 0 280 1 281 7 282 9 283 0 284 1 285 9 286 0 287 1 288 7 289 9 290 0 291 1 292 9 293 1 294 7 295 9 296 1 297 7 298 9 299 1 300 7 301 9 302 1 303 7 304 9 305 1 306 7 307 9 308 1 309 7 310 9 311 1 312 7 313 9 314 1 315 9 316 1 317 7 318 9 319 0 320 1 321 7 322 9 323 1 324 7 325 9 326 0 327 1 328 7 329 9 330 0 331 1 332 7 333 9 334 0 335 1 336 9 337 0 338 1 339 9 340 0 341 1 342 9 343 0 344 1 345 9 346 0 347 1 348 7 349 9 350 1 351 9 352 0 353 1 354 7 355 9 356 0 357 1 358 7 359 9 360 1 361 7 362 9 363 1 364 7 365 9 366 1 367 7 368 9 369 1 370 7 371 9 372 0 373 1 374 7 375 9 376 0 377 1 378 7 379 9 380 0 381 1 382 7 383 9 384 0 385 1 386 7 387 9 388</v> + </vertex_weights> + </skin> + </controller> + </library_controllers> + <library_visual_scenes> + <visual_scene id="Scene" name="Scene"> + <node id="Camera" name="Camera" type="NODE"> + <matrix sid="transform">-0.9050078 -0.1924185 0.3793888 1.108588 0.425187 -0.3812937 0.8208721 2.385299 -0.01329242 0.9042069 0.4268877 2.293916 0 0 0 1</matrix> + <instance_camera url="#Camera-camera"/> + </node> + <node id="Lamp" name="Lamp" type="NODE"> + <matrix sid="transform">-0.2908646 -0.7711008 0.5663932 4.076245 0.9551712 -0.1998834 0.2183912 1.005454 -0.05518906 0.6045247 0.7946723 5.903862 0 0 0 1</matrix> + <instance_light url="#Lamp-light"/> + </node> + <node id="Armature" name="Armature" type="NODE"> + <matrix sid="transform">0.999999 4.1695e-4 -0.001329935 -1.711201 -4.17846e-4 0.9999997 -6.73537e-4 1.125701 0.001329654 6.74093e-4 0.9999989 5.59892 0 0 0 1</matrix> + <node id="Armature_Step" name="Step" sid="Step" type="JOINT"> + <matrix sid="transform">0.9998971 0.01434185 -2.70712e-7 1.702186 -2.70917e-7 0 -1 -1.107874 -0.01434185 0.9998972 -4.87489e-8 -4.92983 0 0 0 1</matrix> + <node id="Armature_core" name="core" sid="core" type="JOINT"> + <matrix sid="transform">0.9998971 -0.01434187 2.70684e-7 -1.19209e-7 0.01434209 0.9998972 3.88241e-9 0.225214 -2.95751e-7 -3.88545e-9 1 0 0 0 0 1</matrix> + <node id="Armature_arm_r" name="arm.r" sid="arm_r" type="JOINT"> + <matrix sid="transform">-2.01166e-7 0.2392236 0.9709646 0.3068454 -5.06639e-7 -0.9709644 0.2392235 0.1970296 0.9999982 3.815e-9 3.13159e-7 0 0 0 0 1</matrix> + <node id="Armature_arm_r_1" name="arm.r.1" sid="arm_r_1" type="JOINT"> + <matrix sid="transform">-1 9.01595e-8 1.76802e-7 0 4.47552e-8 0.9626524 -0.2707413 0.2295313 -1.5717e-7 -0.2707414 -0.9626522 1.78814e-7 0 0 0 1</matrix> + <extra> + <technique profile="blender"> + <connect sid="connect" type="bool">1</connect> + <layer sid="layer" type="string">0</layer> + <roll sid="roll" type="float">-1.538199</roll> + <tip_x sid="tip_x" type="float">-0.009689807</tip_x> + <tip_y sid="tip_y" type="float">0</tip_y> + <tip_z sid="tip_z" type="float">-0.2971559</tip_z> + </technique> + </extra> + </node> + <extra> + <technique profile="blender"> + <layer sid="layer" type="string">0</layer> + <roll sid="roll" type="float">1.329231</roll> + </technique> + </extra> + </node> + <node id="Armature_arm_l" name="arm.l" sid="arm_l" type="JOINT"> + <matrix sid="transform">-2.01166e-7 -0.2392235 0.9709646 -0.3100756 5.06639e-7 -0.9709644 -0.2392235 0.1970296 0.9999982 3.73026e-9 3.15018e-7 0 0 0 0 1</matrix> + <node id="Armature_arm_l_1" name="arm.l.1" sid="arm_l_1" type="JOINT"> + <matrix sid="transform">-0.9999999 1.18232e-8 3.48963e-7 0 6.69024e-8 0.962652 0.2707412 0.2295313 -3.80185e-7 0.2707412 -0.962652 0 0 0 0 1</matrix> + <extra> + <technique profile="blender"> + <connect sid="connect" type="bool">1</connect> + <layer sid="layer" type="string">0</layer> + <roll sid="roll" type="float">-1.603393</roll> + <tip_x sid="tip_x" type="float">0.009689807</tip_x> + <tip_y sid="tip_y" type="float">0</tip_y> + <tip_z sid="tip_z" type="float">-0.2971559</tip_z> + </technique> + </extra> + </node> + <extra> + <technique profile="blender"> + <layer sid="layer" type="string">0</layer> + <roll sid="roll" type="float">1.812363</roll> + </technique> + </extra> + </node> + <node id="Armature_head" name="head" sid="head" type="JOINT"> + <matrix sid="transform">0.9999781 0.006409289 -0.001665825 0 -0.006575178 0.99088 -0.1345863 0.2487102 7.8803e-4 0.1345943 0.9909005 0 0 0 0 1</matrix> + <extra> + <technique profile="blender"> + <connect sid="connect" type="bool">1</connect> + <layer sid="layer" type="string">0</layer> + <roll sid="roll" type="float">0.005672931</roll> + <tip_x sid="tip_x" type="float">0.003229975</tip_x> + <tip_y sid="tip_y" type="float">-0.06782901</tip_y> + <tip_z sid="tip_z" type="float">0.4993556</tip_z> + </technique> + </extra> + </node> + <extra> + <technique profile="blender"> + <connect sid="connect" type="bool">1</connect> + <layer sid="layer" type="string">0</layer> + </technique> + </extra> + </node> + <node id="Armature_leg_l" name="leg.l" sid="leg_l" type="JOINT"> + <matrix sid="transform">-1.00017 0.005284196 2.32905e-4 -0.1168782 -0.005277731 -0.999945 -0.00906714 -0.02403545 -4.46175e-4 -0.009056773 1.0005 0.006347179 0 0 0 1</matrix> + <node id="Armature_leg_l_1" name="leg.l.1" sid="leg_l_1" type="JOINT"> + <matrix sid="transform">-0.9999901 0.00444414 1.8229e-4 0 0.004436177 0.9994961 -0.03143509 0.3566098 -3.21921e-4 -0.03143401 -0.9995057 1.19209e-7 0 0 0 1</matrix> + <extra> + <technique profile="blender"> + <connect sid="connect" type="bool">1</connect> + <layer sid="layer" type="string">0</layer> + <roll sid="roll" type="float">0.0129652</roll> + <tip_x sid="tip_x" type="float">-0.003229856</tip_x> + <tip_y sid="tip_y" type="float">0.009689927</tip_y> + <tip_z sid="tip_z" type="float">-0.2390165</tip_z> + </technique> + </extra> + </node> + <extra> + <technique profile="blender"> + <layer sid="layer" type="string">0</layer> + <roll sid="roll" type="float">3.150466</roll> + </technique> + </extra> + </node> + <node id="Armature_leg_r" name="leg.r" sid="leg_r" type="JOINT"> + <matrix sid="transform">-1.000004 -0.002130879 2.31564e-4 0.1350323 0.002128042 -0.9999638 -0.008237626 -0.02042198 3.01088e-4 -0.008235401 1.000067 0.00634706 0 0 0 1</matrix> + <node id="Armature_leg_r_1" name="leg.r.1" sid="leg_r_1" type="JOINT"> + <matrix sid="transform">-0.9998644 -0.0164662 4.68626e-4 0 -0.01647241 0.9992446 -0.03519817 0.3921766 1.11315e-4 -0.03520112 -0.9993803 1.19209e-7 0 0 0 1</matrix> + <extra> + <technique profile="blender"> + <connect sid="connect" type="bool">1</connect> + <layer sid="layer" type="string">0</layer> + <roll sid="roll" type="float">-2.38419e-6</roll> + <tip_x sid="tip_x" type="float">1.19209e-7</tip_x> + <tip_y sid="tip_y" type="float">0.009689927</tip_y> + <tip_z sid="tip_z" type="float">-0.2228665</tip_z> + </technique> + </extra> + </node> + <extra> + <technique profile="blender"> + <layer sid="layer" type="string">0</layer> + <roll sid="roll" type="float">3.157817</roll> + </technique> + </extra> + </node> + <extra> + <technique profile="blender"> + <layer sid="layer" type="string">0</layer> + <roll sid="roll" type="float">0.01434206</roll> + </technique> + </extra> + </node> + </node> + <node id="pirate-officer" name="pirate-officer" type="NODE"> + <translate sid="location">0 0 0</translate> + <rotate sid="rotationZ">0 0 1 0</rotate> + <rotate sid="rotationY">0 1 0 0</rotate> + <rotate sid="rotationX">1 0 0 0</rotate> + <scale sid="scale">1 1 1</scale> + <instance_controller url="#Armature_pirate-officer-skin"> + <skeleton>#Armature_Step</skeleton> + <bind_material> + <technique_common> + <instance_material symbol="sand_001-material" target="#sand_001-material"/> + <instance_material symbol="textile_001-material" target="#textile_001-material"/> + <instance_material symbol="textileBlue_001-material" target="#textileBlue_001-material"/> + <instance_material symbol="iron_001-material" target="#iron_001-material"/> + <instance_material symbol="wood_001-material" target="#wood_001-material"/> + </technique_common> + </bind_material> + </instance_controller> + </node> + </visual_scene> + </library_visual_scenes> + <scene> + <instance_visual_scene url="#Scene"/> + </scene> +</COLLADA>+ \ No newline at end of file diff --git a/etc/shaders/shadows.glsl b/etc/shaders/shadows.glsl @@ -10,16 +10,17 @@ vec3 shadow_strength(vec4 position, vec4 normal, vec4 v_shadow_coord) { // vec4 shadow_coord = depth_vp * ((world * position) + shadow_offset); vec4 shadow_sample = texture(shadow_map, v_shadow_coord.xy); - + float light_angle = dot(light_dir, normal.xyz); float bias = 0.0002; + bool in_shadow = shadow_sample.z < v_shadow_coord.z - bias && shadow_sample.y < 1.0; if (light_dir.z > 0.0 && in_shadow) { - float factor = 1.0/(dot(light_dir, vec3(0.0, 0.0, 1.0))); + float factor = 1.0-abs(light_angle); // float factor = 1.0; - visibility = vec3(clamp(0.2 * factor, 0.5, 1.0)); + visibility = vec3(1.0)*factor; // visibility = shadow_sample; } diff --git a/src/animation.c b/src/animation.c @@ -0,0 +1,187 @@ + +#include <stdio.h> +#include "xml.h" +#include "util.h" +#include "animation.h" + +enum dae_state { + PARSING_START, + PARSING_NODE, + PARSING_POSE, + PARSING_JOINT, + PARSING_JOINT_MATRIX, +}; + +struct dae_data { + int node_level; + int state; + FILE *dae_file; + struct pose *poses; + int *nposes; + char current_name[JOINT_LABEL_SIZE]; +}; + +void init_joint(struct joint *joint) +{ + memset(joint->children, -1, sizeof(joint->children)); + joint->id = -1; + mat4_id(joint->mat); +} + +void init_pose(struct pose *pose) +{ + pose->njoints = 0; +} + +static void parse_joint(const char *t, int id, struct joint *joint) +{ + float *m = joint->mat; + init_joint(joint); + joint->id = id; + /* printf(" parsing joint %d: %s\n", id, t); */ + + sscanf(t, "%f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f", + &m[0], &m[1], &m[2], &m[3], + &m[4], &m[5], &m[6], &m[7], + &m[8], &m[9], &m[10], &m[11], + &m[12], &m[13], &m[14], &m[15] + ); +} + +static void dae_tag_start(struct xmlparser *x, const char *t, size_t tl) +{ + struct dae_data *data = (struct dae_data*)x->user_data; + + if (streq(t, "node")) { + data->state = PARSING_NODE; + data->node_level++; + } + else if (data->state == PARSING_JOINT && streq(t, "matrix")) + data->state = PARSING_JOINT_MATRIX; + else + return; + + /* printf("\n"); */ + /* for (int i = 0; i < data->opened; i++) { */ + /* putchar(' '); */ + /* } */ + /* printf("%s", t); */ +} + +static void dae_tag_end(struct xmlparser *x, const char *t, size_t tl, int what) +{ + struct dae_data *data = (struct dae_data*)x->user_data; + + if (streq(t, "node")) + data->node_level--; + + if (data->state == PARSING_NODE) { + data->state = PARSING_START; + } +} + +static void dae_tagbody(struct xmlparser *x, const char *d, size_t dl) +{ + struct dae_data *data = (struct dae_data*)x->user_data; + + if (data->state == PARSING_JOINT_MATRIX) { + assert(*data->nposes); + struct pose *pose = &data->poses[*data->nposes - 1]; + struct joint *joint = &pose->joints[pose->njoints]; + parse_joint(d, pose->njoints, joint); + strncpy(joint->name, data->current_name, sizeof(data->current_name)); + joint->children[0] = data->node_level; + pose->njoints++; + data->state = PARSING_POSE; + } +} + +static int dae_getc(struct xmlparser *x) +{ + struct dae_data *data = (struct dae_data*)x->user_data; + return fgetc(data->dae_file); +} + +void dae_attr(struct xmlparser *x, const char *t, size_t tl, + const char *a, size_t al, const char *v, size_t vl) +{ + struct dae_data *data = (struct dae_data*)x->user_data; + + if (data->state == PARSING_NODE + && streq(a, "id") + && streq(v, "Armature")) + { + struct pose *pose = &data->poses[(*data->nposes)++]; + data->state = PARSING_POSE; + init_pose(pose); + } + else if (data->state == PARSING_NODE + && streq(a, "name")) + { + strncpy(data->current_name, v, sizeof(data->current_name)); + } + else if (data->state == PARSING_NODE + && streq(a, "type") + && streq(v, "JOINT")) + { + data->state = PARSING_JOINT; + } +} + +static void process_joint_children(struct joint *joints, int njoints) +{ + struct joint *joint, *j2; + for (int i = 0; i < njoints; i++) { + joint = &joints[i]; + + // node level is stored in here on the first parser pass + int level = joint->children[0]; + + for (int j = i+1; j < njoints; j++) { + j2 = &joints[j]; + if (j2->children[0] == level + 1) { + /* printf("%s(%d) assigning child %s(%d)\n", */ + /* joint->name, level, j2->name, j2->children[0]); */ + + assert(joint->nchildren+1 < MAX_JOINT_CHILDREN); + joint->children[joint->nchildren++] = j; + } + else if (j2->children[0] <= level) + break; + } + } +} + +void load_poses(const char *filename, struct pose *poses, int *nposes) +{ + *nposes = 0; + + struct xmlparser x = {0}; + struct dae_data data = { + .node_level = 0, + .state = PARSING_START, + .poses = poses, + .nposes = nposes, + }; + + data.dae_file = fopen("data/models/pirate-officer.dae", "rb"); + if (data.dae_file == NULL) + exit(1); + + x.user_data = &data; + x.xmltagstart = dae_tag_start; + x.xmltagend = dae_tag_end; + x.xmlattr = dae_attr; + x.xmldata = dae_tagbody; + /* x.xmlattrend = dae_attr_end; */ + x.getnext = dae_getc; + + xml_parse(&x); + + for (int i = 0; i < *nposes; i++) { + struct pose *pose = &poses[i]; + process_joint_children(pose->joints, pose->njoints); + } + + fclose(data.dae_file); +} diff --git a/src/animation.h b/src/animation.h @@ -0,0 +1,34 @@ + +#ifndef POLYADVENT_ANIMATION_H +#define POLYADVENT_ANIMATION_H + +#include "common.h" + +#define MAX_JOINT_CHILDREN 4 +#define MAX_JOINTS 16 +#define JOINT_LABEL_SIZE 8 + +struct joint +{ + int children[MAX_JOINT_CHILDREN]; + int nchildren; + int id; + char name[JOINT_LABEL_SIZE]; + float mat[MAT4_ELEMS]; +}; + + + +struct pose +{ + struct joint joints[MAX_JOINTS]; + int njoints; +}; + + +void load_poses(const char *filename, struct pose *poses, int *nposes); + +void init_joint(struct joint *joint); + + +#endif /* POLYADVENT_ANIMATION_H */ diff --git a/src/entity.c b/src/entity.c @@ -9,7 +9,7 @@ static struct resource_manager esys; -struct entity *get_all_entities(u32 *count, entity_id_t **ids) { +struct entity *get_all_entities(u32 *count, entity_id **ids) { return get_all_resources(&esys, count, ids); } @@ -19,26 +19,26 @@ struct entity *init_entity(struct entity *ent) { return ent; } -struct entity *get_entity(entity_id_t *ent_id) { +struct entity *get_entity(entity_id *ent_id) { return get_resource(&esys, ent_id); } -static inline struct entity *new_uninitialized_entity(entity_id_t *id) { +static inline struct entity *new_uninitialized_entity(entity_id *id) { return new_resource(&esys, id); } -struct entity *new_entity(entity_id_t *id) { +struct entity *new_entity(entity_id *id) { return init_entity(new_uninitialized_entity(id)); } -struct entity *add_entity(struct entity *e, entity_id_t *id) { +struct entity *add_entity(struct entity *e, entity_id *id) { struct entity *new = new_uninitialized_entity(id); *new = *e; return new; } void destroy_entities() { - entity_id_t *ids; + entity_id *ids; u32 count; get_all_resources(&esys, &count, &ids); for (u32 i = RESERVED_ENTITIES; i < count; i++) { @@ -46,7 +46,7 @@ void destroy_entities() { } }; -void destroy_entity(entity_id_t *id) { +void destroy_entity(entity_id *id) { struct entity *ent = get_entity(id); node_detach_from_parent(&ent->node); destroy_resource(&esys, id); diff --git a/src/entity.h b/src/entity.h @@ -23,15 +23,15 @@ struct entity { int casts_shadows; }; -typedef struct resource_id entity_id_t; +typedef struct resource_id entity_id; struct entity *init_entity(struct entity *); void destroy_entities(); -void destroy_entity(entity_id_t *); +void destroy_entity(entity_id *); void init_entity_system(); -struct entity *get_entity(entity_id_t *); -struct entity *get_all_entities(u32 *count, entity_id_t **ids); -struct entity *new_entity(entity_id_t *id); +struct entity *get_entity(entity_id *); +struct entity *get_all_entities(u32 *count, entity_id **ids); +struct entity *new_entity(entity_id *id); #endif /* ENTITY_H */ diff --git a/src/file.c b/src/file.c @@ -13,7 +13,7 @@ time_t file_mtime(const char *filename) { return stats.st_mtime; } -void *file_contents(const char *filename, size_t *length) { +char *file_contents(const char *filename, size_t *length) { FILE *f = fopen(filename, "r"); char *buffer; diff --git a/src/file.h b/src/file.h @@ -3,10 +3,7 @@ #include <time.h> -time_t -file_mtime(const char *filename); - -void * -file_contents(const char *filename, size_t *length); +time_t file_mtime(const char *filename); +char *file_contents(const char *filename, size_t *length); #endif /* POLYADVEMT_FILE_H */ diff --git a/src/game.c b/src/game.c @@ -11,6 +11,9 @@ #include "texture.h" #include "stb_image.h" #include "skybox.h" +#include "quickhull.h" +#include "util.h" + #include <assert.h> mat4 *cam_init = (float[16]){ @@ -44,11 +47,59 @@ struct entity *get_terrain_entity(struct terrain *t) { return ent; } + static void init_user_settings(struct user_settings *settings) { SDL_SetRelativeMouseMode(SDL_TRUE); settings->mouse_sens = 0.1; } + +static void qh_mesh_to_geom(qh_mesh_t *qh, struct make_geometry *geom) { + assert(!geom->vertices); + assert(!geom->indices); + float *new_normals = malloc(sizeof(float) * 3 * qh->nvertices); + + geom->vertices = (float*)qh->vertices; + geom->normals = (float*)qh->normals; + geom->indices = qh->indices; + geom->num_verts = qh->nvertices; + geom->num_indices = qh->nindices; + + for (u32 i = 0; i < qh->nnormals; i++) { + int ndv = i * 9; + + qh_vertex_t *n = &qh->normals[i]; + for (int j = 0; j < 9; j++) { + new_normals[ndv+j] = n->v[j%3]; + } + } + + geom->normals = new_normals; +} + + +void proc_sphere(struct make_geometry *mkgeom, geometry_id *geom_id) { + const int n = 50; + qh_vertex_t *vertices = malloc(n*sizeof(qh_vertex_t)); + const float radius = 2.0; + + + for (int i = 0; i < n; ++i) { + float a0 = (rand_0to1() * TAU); + float a1 = (rand_0to1() * TAU); + vertices[i].z = sin(a0) * radius; + vertices[i].x = cos(a1) * cos(a0) * rand_0to1() * radius; + vertices[i].y = sin(a1) * cos(a0) * rand_0to1() * radius; + } + + qh_mesh_t mesh = qh_quickhull3d(vertices, n); + qh_mesh_to_geom(&mesh, mkgeom); + make_buffer_geometry(mkgeom, geom_id); + + qh_free_mesh(mesh); +} + + void game_init(struct game *game, int width, int height) { init_gl(&game->test_resources, width, height); init_entity_system(); @@ -126,7 +177,7 @@ void game_init(struct game *game, int width, int height) { // player entity player = new_entity(&res->player_id); assert(res->player_id.index == 1); - player->model = get_model(model_pirateofficer); + player->model = get_model(MODEL_PIRATEOFFICER); player->node.label = "player"; node_attach(&player->node, root); node_translate(&player->node, V3(terrain->size/2.,terrain->size/2.,0.0)); diff --git a/src/game.h b/src/game.h @@ -56,10 +56,11 @@ struct resources { GLint view_proj; } uniforms; - struct attributes attributes; + gpu_addr vertex_attrs[n_vertex_attrs]; struct node root; - entity_id_t player_id; + entity_id player_id; + struct geometry qh_test; struct orbit orbit_camera; struct node free_camera; const struct node *camera_node; diff --git a/src/geometry.c b/src/geometry.c @@ -8,16 +8,12 @@ static struct resource_manager geom_manager; void -destroy_buffer_geometry(geometry_id_t *geom_id) { +destroy_buffer_geometry(geometry_id *geom_id) { struct geometry *geom = get_geometry(geom_id); + gpu_addr buffers[n_vertex_attrs]; - gpu_addr buffers[] = { - geom->vertex.handle, - geom->normal.handle, - geom->color.handle, - geom->index.handle, - geom->tex_coord.handle - }; + for (int i = 0; i < n_vertex_attrs; i++) + buffers[i] = geom->vbos[i].handle; /* void glDeleteVertexArrays(GLsizei n, const GLuint *arrays); */ /* glDisableVertexAttribArray(geom->buffer.vertex_buffer.handle); */ /* check_gl(); */ @@ -33,23 +29,14 @@ destroy_buffer_geometry(geometry_id_t *geom_id) { geom->has_vbos = 0; } -void bind_geometry(struct geometry *geom, struct attributes *attrs) { - bind_vbo(&geom->vertex, attrs->position); - check_gl(); - if (geom->normal.handle && attrs->normal != 0xFFFFFFFF) { - bind_vbo(&geom->normal, attrs->normal); - check_gl(); - } - if (geom->color.handle && attrs->color != 0xFFFFFFFF) { - bind_vbo(&geom->color, attrs->color); +void bind_geometry(struct geometry *geom, gpu_addr *vertex_attrs) { + struct vbo *vbo; + for (int i = 0; i < n_vertex_attrs; i++) { + vbo = &geom->vbos[i]; + if (vbo->handle && vertex_attrs[i] != 0xFFFFFFFF) + bind_vbo(vbo, vertex_attrs[i], vbo->component_type); check_gl(); } - if (geom->tex_coord.handle && attrs->tex_coord != 0xFFFFFFFF) { - bind_vbo(&geom->tex_coord, attrs->tex_coord); - check_gl(); - } - bind_ibo(&geom->index); - check_gl(); } static void check_for_patches(struct gpu_program *program, int *type) { @@ -63,12 +50,12 @@ static void check_for_patches(struct gpu_program *program, int *type) { } -void render_geometry(struct geometry *geom, struct attributes *attrs, +void render_geometry(struct geometry *geom, gpu_addr *vertex_attrs, struct gpu_program *program) { int type = GL_TRIANGLES; //check_for_patches(program, &type); - bind_geometry(geom, attrs); + bind_geometry(geom, vertex_attrs); if (geom->num_indices) { glDrawElements(type, geom->num_indices, /* count */ @@ -85,23 +72,27 @@ void render_geometry(struct geometry *geom, struct attributes *attrs, } void init_make_geometry(struct make_geometry *mkgeom) { - mkgeom->colors = NULL; - mkgeom->normals = NULL; - mkgeom->indices = NULL; - mkgeom->vertices = NULL; - mkgeom->tex_coords = NULL; - mkgeom->num_uv_components = 2; - mkgeom->num_verts = 0; - mkgeom->num_indices = 0; + *mkgeom = (struct make_geometry){ + .colors = NULL, + .normals = NULL, + .indices = NULL, + .vertices = NULL, + .tex_coords = NULL, + .joint_ids = NULL, + .joint_weights = NULL, + .num_uv_components = 2, + .num_verts = 0, + .num_indices = 0, + }; } void init_geometry(struct geometry *geom) { geom->has_vbos = 0; - init_vbo(&geom->vertex); - init_vbo(&geom->color); - init_vbo(&geom->normal); - init_vbo(&geom->tex_coord); - init_vbo(&geom->index); + + for (int i = 0; i < n_vertex_attrs; i++) + init_vbo(&geom->vbos[i]); + + geom->num_uv_components = 2; } void @@ -119,69 +110,68 @@ make_buffer_geometry_(struct make_geometry *mkgeom, struct geometry *geom) { /* assert(geom->num_indices >= 1); */ /* printf("making vertex buffer\n"); */ - make_vertex_buffer( - GL_ARRAY_BUFFER, - mkgeom->vertices, - mkgeom->num_verts * 3 * (int)sizeof(*mkgeom->vertices), - &geom->vertex - ); + make_float_vertex_buffer(&geom->vbos[va_position], + mkgeom->vertices, + mk_num_elements(mkgeom->num_verts), + mk_components(3) + ); /* printf("making normal buffer\n"); */ // cube normals - if (mkgeom->normals != NULL) - make_vertex_buffer( - GL_ARRAY_BUFFER, - mkgeom->normals, - mkgeom->num_verts * 3 * (int)sizeof(*mkgeom->normals), - &geom->normal - ); + if (mkgeom->normals) + make_float_vertex_buffer(&geom->vbos[va_normal], + mkgeom->normals, + mk_num_elements(mkgeom->num_verts), + mk_components(3) + ); + + if (mkgeom->joint_ids) { + make_int_vertex_buffer(&geom->vbos[va_joint_ids], + mkgeom->joint_ids, + mk_num_elements(mkgeom->num_verts), + mk_components(3) + ); + } // vertex colors - if (mkgeom->colors != NULL) - make_vertex_buffer( - GL_ARRAY_BUFFER, - mkgeom->colors, - mkgeom->num_verts * 3 * (int)sizeof(*mkgeom->colors), - &geom->color - ); + if (mkgeom->colors) { + make_float_vertex_buffer(&geom->vbos[va_color], + mkgeom->colors, + mk_num_elements(mkgeom->num_verts), + mk_components(3) + ); + } if (mkgeom->tex_coords != NULL) { assert(geom->num_uv_components); - printf("%f %f %f %f\n", - mkgeom->tex_coords[0], - mkgeom->tex_coords[1], - mkgeom->tex_coords[2], - mkgeom->tex_coords[3] - ); - - make_uv_buffer(GL_ARRAY_BUFFER, + + make_uv_buffer(&geom->vbos[va_tex_coord], mkgeom->tex_coords, - mkgeom->num_verts * mkgeom->num_uv_components * (int)sizeof(*mkgeom->tex_coords), - &geom->tex_coord, geom->num_uv_components); + mk_num_elements(geom->num_verts), + mk_components(geom->num_uv_components) + ); } /* printf("making index buffer\n"); */ // cube indices if (mkgeom->indices) - make_index_buffer( - GL_ELEMENT_ARRAY_BUFFER, - mkgeom->indices, - mkgeom->num_indices * (int)sizeof(*mkgeom->indices), - &geom->index - ); + make_index_buffer(&geom->vbos[va_index], + mkgeom->indices, + mk_num_elements(mkgeom->num_indices) + ); geom->has_vbos = 1; } void -make_buffer_geometry(struct make_geometry *mkgeom, geometry_id_t *geom_id) { +make_buffer_geometry(struct make_geometry *mkgeom, geometry_id *geom_id) { + struct geometry *geom = new_geometry(geom_id); make_buffer_geometry_(mkgeom, geom); } - void geometry_centroid(struct geometry *geom, float *dest) { vec3_subtract(geom->max, geom->min, dest); vec3_scale(dest, 0.5, dest); @@ -192,15 +182,15 @@ void init_geometry_manager() { DEF_NUM_GEOMETRY, MAX_GEOMETRY); } -struct geometry *get_geometry(geometry_id_t *geom_id) { +struct geometry *get_geometry(geometry_id *geom_id) { return get_resource(&geom_manager, geom_id); } -struct geometry *new_geometry(geometry_id_t *geom_id) { +struct geometry *new_geometry(geometry_id *geom_id) { return new_resource(&geom_manager, geom_id); } -struct geometry *get_all_geometry(u32 *count, geometry_id_t **ids) { +struct geometry *get_all_geometry(u32 *count, geometry_id **ids) { return get_all_resources(&geom_manager, count, ids); } diff --git a/src/geometry.h b/src/geometry.h @@ -11,15 +11,10 @@ #define MAX_GEOMETRY 1024 // -1 is uninitialized -typedef struct resource_id geometry_id_t; +typedef struct resource_id geometry_id; struct geometry { - struct vbo vertex; - struct vbo index; - struct vbo normal; - struct vbo color; - struct vbo tex_coord; - + struct vbo vbos[n_vertex_attrs]; float min[3]; float max[3]; @@ -40,6 +35,9 @@ struct make_geometry { float *tex_coords; int num_uv_components; + + int *joint_ids; + float *joint_weights; }; struct geometry_manager { @@ -47,18 +45,18 @@ struct geometry_manager { int num_geometry; }; -void render_geometry(struct geometry *geom, struct attributes *, +void render_geometry(struct geometry *geom, gpu_addr *vertex_attrs, struct gpu_program *current_program); -void bind_geometry(struct geometry *geom, struct attributes *); +void bind_geometry(struct geometry *geom, gpu_addr *vertex_attrs); void init_geometry(struct geometry *geom); void init_make_geometry(struct make_geometry *mkgeom); -void make_buffer_geometry(struct make_geometry *mkgeom, geometry_id_t *); -void destroy_buffer_geometry(geometry_id_t *geom); +void make_buffer_geometry(struct make_geometry *mkgeom, geometry_id *); +void destroy_buffer_geometry(geometry_id *geom); void geometry_centroid(struct geometry *geom, float *v3); void init_geometry_manager(); -void init_geometry_id(geometry_id_t *); -struct geometry *new_geometry(geometry_id_t *); -struct geometry *get_geometry(geometry_id_t *); -struct geometry *get_all_geometry(u32 *count, geometry_id_t **ids); +void init_geometry_id(geometry_id *); +struct geometry *new_geometry(geometry_id *); +struct geometry *get_geometry(geometry_id *); +struct geometry *get_all_geometry(u32 *count, geometry_id **ids); #endif /* GEOMETRY_H */ diff --git a/src/gl.h b/src/gl.h @@ -29,6 +29,12 @@ void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid * pointer); +void glVertexAttribIPointer(GLuint index, + GLint size, + GLenum type, + GLsizei stride, + const GLvoid * pointer); + void glUniform1i(GLint location, GLint i); void glUniform3f(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); GLuint glCreateProgram(void); diff --git a/src/half-edge.c b/src/half-edge.c @@ -0,0 +1,24 @@ + + +#include "half-edge.h" + +// NOTE: end = start(next(e)) + +inline u32 he_start(struct half_edge *he) +{ + return he->start; +} + +inline struct half_edge *he_next(struct half_edge *edges, struct half_edge *he) +{ + return &edges[he->next]; +} + +inline u32 he_end(struct half_edge *edges, struct half_edge *he) +{ + return he_start(he_next(edges, he)); +} + +inline u32 he_prev_vert(struct half_edge *he) +{ +} diff --git a/src/half-edge.h b/src/half-edge.h @@ -0,0 +1,24 @@ + +#ifndef HALF_EDGE_H +#define HALF_EDGE_H + + + +#include "common.h" + +struct point + +struct half_edge { + u32 opposite; + struct half_edge *next; + struct half_edge *prev; + u32 start; +}; + +struct face { +}; + + + + +#endif /* HALF-EDGE_H */ diff --git a/src/main.c b/src/main.c @@ -1,4 +1,5 @@ +#include "animation.h" #include "event.h" #include "fbo.h" #include "file.h" @@ -8,21 +9,22 @@ #include "hires.h" #include "ply.h" #include "poisson.h" +#include "quickhull.h" #include "render.h" #include "scene.h" -#include "slab.h" -#include "slab.h" #include "slab_geom.h" +#include "slab.h" #include "terrain.h" #include "uniform.h" #include "update.h" #include "util.h" #include "window.h" + + #include <assert.h> #include <time.h> - int main(void) { int nsamples; @@ -82,6 +84,7 @@ int main(void) .depth_vp = depth_vp }; + while (1) { game.frame++; process_events(&game.input, game.frame); diff --git a/src/mat4.h b/src/mat4.h @@ -1,4 +1,9 @@ +#ifndef MAT4_H +#define MAT4_H + + + typedef float mat4; #define M_X 12 @@ -30,3 +35,6 @@ mat4 *mat4_rotate(const mat4 *mat, const float angle, mat4 *mat4_remove_translations(mat4 *mat); + + +#endif /* MAT4_H */ diff --git a/src/model.c b/src/model.c @@ -1,21 +1,25 @@ #include "model.h" #include "ply.h" +#include "resource.h" #include <assert.h> -#define MODELDEF(name) { .id = model_##name, .loaded = 0, .file = #name } +#define MODELDEF(name) { .id = MODEL_##name, .loaded = 0, .file = #name } static struct model_def static_models[NUM_STATIC_MODELS] = { - MODELDEF(tower), - MODELDEF(icosphere), - MODELDEF(pirateofficer), + MODELDEF(TOWER), + MODELDEF(ICOSPHERE), + MODELDEF(PIRATEOFFICER), }; +static struct resource_manager dyn_modelman; + static int static_models_initialized = 0; -void init_model(struct model *model) { +struct model *init_model(struct model *model) { model->shading = SHADING_VERT_COLOR; model->texture = 0; + return model; } static void initialize_static_models() { @@ -27,6 +31,16 @@ static void initialize_static_models() { static_models_initialized = 1; } +static inline struct model *new_uninitialized_model(model_id *id) { + return new_resource(&dyn_modelman, id); +} + + +struct model *new_dynamic_model(model_id *id) +{ + return init_model(new_uninitialized_model(id)); +} + struct model *get_model(enum static_model m) { static char path[128] = {0}; diff --git a/src/model.h b/src/model.h @@ -9,11 +9,14 @@ #include "common.h" #define MAX_STATIC_MODELS 128 +#define MAX_DYNAMIC_MODELS 512 + +typedef struct resource_id model_id; enum static_model { - model_tower, - model_icosphere, - model_pirateofficer, + MODEL_TOWER, + MODEL_ICOSPHERE, + MODEL_PIRATEOFFICER, NUM_STATIC_MODELS }; @@ -24,7 +27,7 @@ enum shading { }; struct model { - geometry_id_t geom_id; + geometry_id geom_id; enum shading shading; u32 texture; }; @@ -37,8 +40,9 @@ struct model_def { }; -void init_model(struct model *model); +struct model *init_model(struct model *model); struct model *get_model(enum static_model); +struct model *new_dynamic_model(model_id *); #endif /* MODEL_H */ diff --git a/src/ply.c b/src/ply.c @@ -105,7 +105,7 @@ static int parse_magic(const char **cursor) { } -int parse_ply(const char *filename, geometry_id_t *geom_id) { +int parse_ply(const char *filename, geometry_id *geom_id) { size_t len; int success = 0; int nverts = 0; diff --git a/src/ply.h b/src/ply.h @@ -5,6 +5,6 @@ #include "geometry.h" -int parse_ply(const char *filename, geometry_id_t *geom_id); +int parse_ply(const char *filename, geometry_id *geom_id); #endif /* PLYPARSER_H */ diff --git a/src/quickhull.c b/src/quickhull.c @@ -0,0 +1,1245 @@ + +#include "quickhull.h" + +#include <math.h> // sqrt & fabs +#include <stdio.h> // FILE +#include <string.h> // memcpy + +// Quickhull helpers, define your own if needed +#ifndef QUICKHULL_HELPERS +#include <stdlib.h> // malloc, free, realloc +#define QUICKHULL_HELPERS 1 +#define QH_MALLOC(T, N) ((T*) malloc(N * sizeof(T))) +#define QH_REALLOC(T, P, N) ((T*)realloc(P, sizeof(T) * N)) +#define QH_FREE(T) free(T) +#define QH_SWAP(T, A, B) { T tmp = B; B = A; A = tmp; } +#ifdef QUICKHULL_DEBUG +#define QH_ASSERT(STMT) if (!(STMT)) { *(int *)0 = 0; } +#define QH_LOG(FMT, ...) printf(FMT, ## __VA_ARGS__) +#else +#define QH_ASSERT(STMT) +#define QH_LOG(FMT, ...) +#endif // QUICKHULL_DEBUG +#endif // QUICKHULL_HELPERS + +#ifndef QH_FLT_MAX +#define QH_FLT_MAX 1e+37F +#endif + +#ifndef QH_FLT_EPS +#define QH_FLT_EPS 1E-5F +#endif + +#ifndef QH_VERTEX_SET_SIZE +#define QH_VERTEX_SET_SIZE 128 +#endif + +typedef long qh_index_t; + +typedef struct qh_half_edge { + qh_index_t opposite_he; // index of the opposite half edge + qh_index_t next_he; // index of the next half edge + qh_index_t previous_he; // index of the previous half edge + qh_index_t he; // index of the current half edge + qh_index_t to_vertex; // index of the next vertex + qh_index_t adjacent_face; // index of the ajacent face +} qh_half_edge_t; + +typedef struct qh_index_set { + qh_index_t* indices; + unsigned int size; + unsigned int capacity; +} qh_index_set_t; + +typedef struct qh_face { + qh_index_set_t iset; + qh_vec3_t normal; + qh_vertex_t centroid; + qh_index_t edges[3]; + qh_index_t face; + float sdist; + int visitededges; +} qh_face_t; + +typedef struct qh_index_stack { + qh_index_t* begin; + unsigned int size; +} qh_index_stack_t; + +typedef struct qh_context { + qh_face_t* faces; + qh_half_edge_t* edges; + qh_vertex_t* vertices; + qh_vertex_t centroid; + qh_index_stack_t facestack; + qh_index_stack_t scratch; + qh_index_stack_t horizonedges; + qh_index_stack_t newhorizonedges; + char* valid; + unsigned int nedges; + unsigned int nvertices; + unsigned int nfaces; + + #ifdef QUICKHULL_DEBUG + unsigned int maxfaces; + unsigned int maxedges; + #endif +} qh_context_t; + +void qh__find_6eps(qh_vertex_t* vertices, unsigned int nvertices, qh_index_t* eps) +{ + qh_vertex_t* ptr = vertices; + + float minxy = +QH_FLT_MAX; + float minxz = +QH_FLT_MAX; + float minyz = +QH_FLT_MAX; + + float maxxy = -QH_FLT_MAX; + float maxxz = -QH_FLT_MAX; + float maxyz = -QH_FLT_MAX; + + unsigned int i = 0; + for (i = 0; i < 6; ++i) { + eps[i] = 0; + } + + for (i = 0; i < nvertices; ++i) { + if (ptr->z < minxy) { + eps[0] = i; + minxy = ptr->z; + } + if (ptr->y < minxz) { + eps[1] = i; + minxz = ptr->y; + } + if (ptr->x < minyz) { + eps[2] = i; + minyz = ptr->x; + } + if (ptr->z > maxxy) { + eps[3] = i; + maxxy = ptr->z; + } + if (ptr->y > maxxz) { + eps[4] = i; + maxxz = ptr->y; + } + if (ptr->x > maxyz) { + eps[5] = i; + maxyz = ptr->x; + } + ptr++; + } +} + +float qh__vertex_segment_length2(qh_vertex_t* p, qh_vertex_t* a, qh_vertex_t* b) +{ + float dx = b->x - a->x; + float dy = b->y - a->y; + float dz = b->z - a->z; + + float d = dx * dx + dy * dy + dz * dz; + + float x = a->x; + float y = a->y; + float z = a->z; + + if (d != 0) { + float t = ((p->x - a->x) * dx + + (p->y - a->y) * dy + + (p->z - a->z) * dz) / d; + + if (t > 1) { + x = b->x; + y = b->y; + z = b->z; + } else if (t > 0) { + x += dx * t; + y += dy * t; + z += dz * t; + } + } + + dx = p->x - x; + dy = p->y - y; + dz = p->z - z; + + return dx * dx + dy * dy + dz * dz; +} + +void qh__vec3_sub(qh_vec3_t* a, qh_vec3_t* b) +{ + a->x -= b->x; + a->y -= b->y; + a->z -= b->z; +} + +void qh__vec3_add(qh_vec3_t* a, qh_vec3_t* b) +{ + a->x += b->x; + a->y += b->y; + a->z += b->z; +} + +void qh__vec3_multiply(qh_vec3_t* a, float v) +{ + a->x *= v; + a->y *= v; + a->z *= v; +} + +int qh__vertex_equals_epsilon(qh_vertex_t* a, qh_vertex_t* b, float epsilon) +{ + return fabs(a->x - b->x) <= epsilon && + fabs(a->y - b->y) <= epsilon && + fabs(a->z - b->z) <= epsilon; +} + +float qh__vec3_length2(qh_vec3_t* v) +{ + return v->x * v->x + v->y * v->y + v->z * v->z; +} + +float qh__vec3_dot(qh_vec3_t* v1, qh_vec3_t* v2) +{ + return v1->x * v2->x + v1->y * v2->y + v1->z * v2->z; +} + +void qh__vec3_normalize(qh_vec3_t* v) +{ + qh__vec3_multiply(v, 1.f / sqrt(qh__vec3_length2(v))); +} + +void qh__find_2dps_6eps(qh_vertex_t* vertices, qh_index_t* eps, int* ii, int* jj) +{ + int i, j; + float max = -QH_FLT_MAX; + + for (i = 0; i < 6; ++i) { + for (j = 0; j < 6; ++j) { + qh_vertex_t d; + float d2; + + if (i == j) { + continue; + } + + d = vertices[eps[i]]; + qh__vec3_sub(&d, &vertices[eps[j]]); + d2 = qh__vec3_length2(&d); + + if (d2 > max) { + *ii = i; + *jj = j; + max = d2; + } + } + } +} + +qh_vec3_t qh__vec3_cross(qh_vec3_t* v1, qh_vec3_t* v2) +{ + qh_vec3_t cross; + + cross.x = v1->y * v2->z - v1->z * v2->y; + cross.y = v1->z * v2->x - v1->x * v2->z; + cross.z = v1->x * v2->y - v1->y * v2->x; + + return cross; +} + +qh_vertex_t qh__face_centroid(qh_index_t vertices[3], qh_context_t* context) +{ + qh_vertex_t centroid; + int i; + + centroid.x = centroid.y = centroid.z = 0.0; + for (i = 0; i < 3; ++i) { + qh__vec3_add(&centroid, context->vertices + vertices[i]); + } + + qh__vec3_multiply(&centroid, 1.0 / 3.0); + + return centroid; +} + +float qh__dist_point_plane(qh_vertex_t* v, qh_vec3_t* normal, float sdist) +{ + return fabs(qh__vec3_dot(v, normal) - sdist); +} + +void qh__init_half_edge(qh_half_edge_t* half_edge) { + half_edge->adjacent_face = -1; + half_edge->he = -1; + half_edge->next_he = -1; + half_edge->opposite_he = -1; + half_edge->to_vertex = -1; + half_edge->previous_he = -1; +} + +qh_half_edge_t* qh__next_edge(qh_context_t* context) +{ + qh_half_edge_t* edge = context->edges + context->nedges; + + qh__init_half_edge(edge); + + edge->he = context->nedges; + context->nedges++; + + QH_ASSERT(context->nedges < context->maxedges); + + return edge; +} + +qh_face_t* qh__next_face(qh_context_t* context) +{ + qh_face_t* face = context->faces + context->nfaces; + + face->face = context->nfaces; + face->iset.indices = NULL; + context->valid[context->nfaces] = 1; + context->nfaces++; + + QH_ASSERT(context->nfaces < context->maxfaces); + + return face; +} + +qh_vec3_t qh__edge_vec3(qh_half_edge_t* edge, qh_context_t* context) +{ + qh_half_edge_t prevhe = context->edges[edge->previous_he]; + qh_vec3_t v0, v1; + + v0 = context->vertices[prevhe.to_vertex]; + v1 = context->vertices[edge->to_vertex]; + + qh__vec3_sub(&v1, &v0); + qh__vec3_normalize(&v1); + + return v1; +} + +void qh__face_init(qh_face_t* face, qh_index_t vertices[3], qh_context_t* context) +{ + qh_half_edge_t* e0 = qh__next_edge(context); + qh_half_edge_t* e1 = qh__next_edge(context); + qh_half_edge_t* e2 = qh__next_edge(context); + qh_vec3_t v0, v1; + qh_vertex_t centroid, normal; + + e2->to_vertex = vertices[0]; + e0->to_vertex = vertices[1]; + e1->to_vertex = vertices[2]; + + e0->next_he = e1->he; + e2->previous_he = e1->he; + face->edges[1] = e1->he; + + e1->next_he = e2->he; + e0->previous_he = e2->he; + face->edges[2] = e2->he; + v1 = qh__edge_vec3(e2, context); + + e2->next_he = e0->he; + e1->previous_he = e0->he; + face->edges[0] = e0->he; + v0 = qh__edge_vec3(e0, context); + + e2->adjacent_face = face->face; + e1->adjacent_face = face->face; + e0->adjacent_face = face->face; + + qh__vec3_multiply(&v1, -1.f); + normal = qh__vec3_cross(&v0, &v1); + + qh__vec3_normalize(&normal); + centroid = qh__face_centroid(vertices, context); + face->centroid = centroid; + face->sdist = qh__vec3_dot(&normal, &centroid); + face->normal = normal; + face->iset.indices = QH_MALLOC(qh_index_t, QH_VERTEX_SET_SIZE); + face->iset.capacity = QH_VERTEX_SET_SIZE; + face->iset.size = 0; + face->visitededges = 0; +} + +void qh__tetrahedron_basis(qh_context_t* context, qh_index_t vertices[3]) +{ + qh_index_t eps[6]; + int i, j, k, l = 0; + float max = -QH_FLT_MAX; + + qh__find_6eps(context->vertices, context->nvertices, eps); + qh__find_2dps_6eps(context->vertices, eps, &j, &k); + + for (i = 0; i < 6; ++i) { + float d2; + + if (i == j || i == k) { + continue; + } + + d2 = qh__vertex_segment_length2(context->vertices + eps[i], + context->vertices + eps[j], + context->vertices + eps[k]); + + if (d2 > max) { + max = d2; + l = i; + } + } + + vertices[0] = eps[j]; + vertices[1] = eps[k]; + vertices[2] = eps[l]; +} + +void qh__push_stack(qh_index_stack_t* stack, qh_index_t index) +{ + stack->begin[stack->size] = index; + stack->size++; +} + +qh_index_t qh__pop_stack(qh_index_stack_t* stack) +{ + qh_index_t top = -1; + + if (stack->size > 0) { + top = stack->begin[stack->size - 1]; + stack->size--; + } + + return top; +} + +qh_index_t qh__furthest_point_from_plane(qh_context_t* context, + qh_index_t* indices, + int nindices, + qh_vec3_t* normal, + float sdist) +{ + int i, j = 0; + float max = -QH_FLT_MAX; + + for (i = 0; i < nindices; ++i) { + qh_index_t index = indices ? *(indices + i) : i; + float dist = qh__dist_point_plane(context->vertices + index, normal, sdist); + + if (dist > max) { + j = i; + max = dist; + } + } + + return j; +} + +int qh__face_can_see_vertex(qh_face_t* face, qh_vertex_t* v) +{ + qh_vec3_t tov = *v; + + qh__vec3_sub(&tov, &face->centroid); + return qh__vec3_dot(&tov, &face->normal) > 0; +} + +int qh__face_can_see_vertex_epsilon(qh_context_t* context, qh_face_t* face, qh_vertex_t* v, float epsilon) +{ + float dot; + qh_vec3_t tov = *v; + + qh__vec3_sub(&tov, &face->centroid); + dot = qh__vec3_dot(&tov, &face->normal); + + if (dot > epsilon) { + return 1; + } else { + dot = fabsf(dot); + + if (dot <= epsilon && dot >= 0) { + qh_vec3_t n = face->normal; + + // allow epsilon degeneration along the face normal + qh__vec3_multiply(&n, epsilon); + qh__vec3_add(v, &n); + + return 1; + } + } + + return 0; +} + +static inline void qh__assert_half_edge(qh_half_edge_t* edge, qh_context_t* context) +{ + QH_ASSERT(edge->opposite_he != -1); + QH_ASSERT(edge->he != -1); + QH_ASSERT(edge->adjacent_face != -1); + QH_ASSERT(edge->next_he != -1); + QH_ASSERT(edge->previous_he != -1); + QH_ASSERT(edge->to_vertex != -1); + QH_ASSERT(context->edges[edge->opposite_he].to_vertex != edge->to_vertex); +} + +static inline void qh__assert_face(qh_face_t* face, qh_context_t* context) +{ + int i; + + for (i = 0; i < 3; ++i) { + qh__assert_half_edge(context->edges + face->edges[i], context); + } + + QH_ASSERT(context->valid[face->face]); +} + +#ifdef QUICKHULL_DEBUG + +void qh__log_face(qh_context_t* context, qh_face_t const* face) { + QH_LOG("Face %ld:\n", face->face); + for (int i = 0; i < 3; ++i) { + qh_half_edge_t edge = context->edges[face->edges[i]]; + QH_LOG("\te%d %ld\n", i, edge.he); + QH_LOG("\t\te%d.opposite_he %ld\n", i, edge.opposite_he); + QH_LOG("\t\te%d.next_he %ld\n", i, edge.next_he); + QH_LOG("\t\te%d.previous_he %ld\n", i, edge.previous_he); + QH_LOG("\t\te%d.to_vertex %ld\n", i, edge.to_vertex); + QH_LOG("\t\te%d.adjacent_face %ld\n", i, edge.adjacent_face); + } + QH_LOG("\tnormal %f %f %f\n", face->normal.x, face->normal.y, face->normal.z); + QH_LOG("\tsdist %f\n", face->sdist); + QH_LOG("\tcentroid %f %f %f\n", face->centroid.x, face->centroid.y, face->centroid.z); +} + +#endif + +int qh__test_hull(qh_context_t* context, float epsilon, int testiset) +{ + unsigned int i, j, k; + + for (i = 0; i < context->nvertices; ++i) { + qh_index_t vindex = i; + char valid = 1; + + for (j = 0; j < context->nfaces; ++j) { + if (!context->valid[j]) { + continue; + } + qh_face_t* face = context->faces + j; + + qh_half_edge_t* e0 = context->edges + face->edges[0]; + qh_half_edge_t* e1 = context->edges + face->edges[1]; + qh_half_edge_t* e2 = context->edges + face->edges[2]; + + if (e0->to_vertex == vindex || + e1->to_vertex == vindex || + e2->to_vertex == vindex) { + valid = 0; + break; + } + + if (testiset) { + for (k = 0; k < face->iset.size; ++k) { + if (vindex == face->iset.indices[k]) { + valid = 0; + } + } + } + } + + if (!valid) { + continue; + } + + for (j = 0; j < context->nfaces; ++j) { + if (!context->valid[j]) { + continue; + } + qh_face_t* face = context->faces + j; + + qh_vertex_t vertex = context->vertices[vindex]; + qh__vec3_sub(&vertex, &face->centroid); + if (qh__vec3_dot(&face->normal, &vertex) > epsilon) { + #ifdef QUICKHULL_DEBUG + qh__log_face(context, face); + #endif + return 0; + } + } + } + + return 1; +} + +#ifdef QUICKHULL_DEBUG +void qh__build_hull(qh_context_t* context, float epsilon, unsigned int step, unsigned int* failurestep) +#else +void qh__build_hull(qh_context_t* context, float epsilon) +#endif +{ + qh_index_t topface = qh__pop_stack(&context->facestack); + unsigned int i, j, k; + + #ifdef QUICKHULL_DEBUG + unsigned int iteration = 0; + #endif + + while (topface != -1) { + qh_face_t* face = context->faces + topface; + qh_index_t fvi, apex; + qh_vertex_t* fv; + int reversed = 0; + + #ifdef QUICKHULL_DEBUG + if (!context->valid[topface] || face->iset.size == 0 || iteration == step) + #else + if (!context->valid[topface] || face->iset.size == 0) + #endif + { + topface = qh__pop_stack(&context->facestack); + continue; + } + + #ifdef QUICKHULL_DEBUG + if (failurestep != NULL && !qh__test_hull(context, epsilon, 1)) { + if (*failurestep == 0) { + *failurestep = iteration; + break; + } + } + + iteration++; + #endif + + fvi = qh__furthest_point_from_plane(context, face->iset.indices, + face->iset.size, &face->normal, face->sdist); + fv = context->vertices + *(face->iset.indices + fvi); + + qh__assert_face(face, context); + + // Reset visited flag for faces + { + for (i = 0; i < context->nfaces; ++i) { + context->faces[i].visitededges = 0; + } + } + + // Find horizon edge + { + qh_index_t tovisit = topface; + qh_face_t* facetovisit = context->faces + tovisit; + + // Release scratch + context->scratch.size = 0; + + while (tovisit != -1) { + if (facetovisit->visitededges >= 3) { + context->valid[tovisit] = 0; + tovisit = qh__pop_stack(&context->scratch); + facetovisit = context->faces + tovisit; + } else { + qh_index_t edgeindex = facetovisit->edges[facetovisit->visitededges]; + qh_half_edge_t* edge; + qh_half_edge_t* oppedge; + qh_face_t* adjface; + + facetovisit->visitededges++; + + edge = context->edges + edgeindex; + oppedge = context->edges + edge->opposite_he; + adjface = context->faces + oppedge->adjacent_face; + + if (!context->valid[oppedge->adjacent_face]) { continue; } + + qh__assert_half_edge(oppedge, context); + qh__assert_half_edge(edge, context); + qh__assert_face(adjface, context); + + if (!qh__face_can_see_vertex(adjface, fv)) { + qh__push_stack(&context->horizonedges, edge->he); + } else { + context->valid[tovisit] = 0; + qh__push_stack(&context->scratch, adjface->face); + } + } + } + } + + apex = face->iset.indices[fvi]; + + // Sort horizon edges in CCW order + { + qh_vertex_t triangle[3]; + int vindex = 0; + qh_vec3_t v0, v1, toapex; + qh_vertex_t n; + + for (i = 0; i < context->horizonedges.size; ++i) { + qh_index_t he0 = context->horizonedges.begin[i]; + qh_index_t he0vert = context->edges[he0].to_vertex; + qh_index_t phe0 = context->edges[he0].previous_he; + qh_index_t phe0vert = context->edges[phe0].to_vertex; + + for (j = i + 2; j < context->horizonedges.size; ++j) { + qh_index_t he1 = context->horizonedges.begin[j]; + qh_index_t he1vert = context->edges[he1].to_vertex; + qh_index_t phe1 = context->edges[he1].previous_he; + qh_index_t phe1vert = context->edges[phe1].to_vertex; + + if (phe1vert == he0vert || phe0vert == he1vert) { + QH_SWAP(qh_index_t, context->horizonedges.begin[j], + context->horizonedges.begin[i + 1]); + break; + } + } + + if (vindex < 3) { + triangle[vindex++] = context->vertices[context->edges[he0].to_vertex]; + } + } + + if (vindex == 3) { + // Detect first triangle face ordering + v0 = triangle[0]; + v1 = triangle[2]; + + qh__vec3_sub(&v0, &triangle[1]); + qh__vec3_sub(&v1, &triangle[1]); + + n = qh__vec3_cross(&v0, &v1); + + // Get the vector to the apex + toapex = triangle[0]; + + qh__vec3_sub(&toapex, context->vertices + apex); + + reversed = qh__vec3_dot(&n, &toapex) < 0.f; + } + } + + // Create new faces + { + qh_index_t top = qh__pop_stack(&context->horizonedges); + qh_index_t last = qh__pop_stack(&context->horizonedges); + qh_index_t first = top; + int looped = 0; + + QH_ASSERT(context->newhorizonedges.size == 0); + + // Release scratch + context->scratch.size = 0; + + while (!looped) { + qh_half_edge_t* prevhe; + qh_half_edge_t* nexthe; + qh_half_edge_t* oppedge; + qh_vec3_t normal; + qh_vertex_t fcentroid; + qh_index_t verts[3]; + qh_face_t* newface; + + if (last == -1) { + looped = 1; + last = first; + } + + prevhe = context->edges + last; + nexthe = context->edges + top; + + if (reversed) { + QH_SWAP(qh_half_edge_t*, prevhe, nexthe); + } + + verts[0] = prevhe->to_vertex; + verts[1] = nexthe->to_vertex; + verts[2] = apex; + + context->valid[nexthe->adjacent_face] = 0; + + oppedge = context->edges + nexthe->opposite_he; + newface = qh__next_face(context); + + qh__face_init(newface, verts, context); + + oppedge->opposite_he = context->edges[newface->edges[0]].he; + context->edges[newface->edges[0]].opposite_he = oppedge->he; + + qh__push_stack(&context->scratch, newface->face); + qh__push_stack(&context->newhorizonedges, newface->edges[0]); + + top = last; + last = qh__pop_stack(&context->horizonedges); + } + } + + // Attach point sets to newly created faces + { + for (k = 0; k < context->nfaces; ++k) { + qh_face_t* f = context->faces + k; + + if (context->valid[k] || f->iset.size == 0) { + continue; + } + + if (f->visitededges == 3) { + context->valid[k] = 0; + } + + for (i = 0; i < f->iset.size; ++i) { + qh_index_t vertex = f->iset.indices[i]; + qh_vertex_t* v = context->vertices + vertex; + qh_face_t* dface = NULL; + + for (j = 0; j < context->scratch.size; ++j) { + qh_face_t* newface = context->faces + context->scratch.begin[j]; + qh_half_edge_t* e0 = context->edges + newface->edges[0]; + qh_half_edge_t* e1 = context->edges + newface->edges[1]; + qh_half_edge_t* e2 = context->edges + newface->edges[2]; + qh_vertex_t cv; + + if (e0->to_vertex == vertex || + e1->to_vertex == vertex || + e2->to_vertex == vertex) { + continue; + } + + if (qh__face_can_see_vertex_epsilon(context, newface, context->vertices + vertex, epsilon)) { + dface = newface; + break; + } + } + + if (dface) { + if (dface->iset.size + 1 >= dface->iset.capacity) { + dface->iset.capacity *= 2; + dface->iset.indices = QH_REALLOC(qh_index_t, + dface->iset.indices, dface->iset.capacity); + } + + dface->iset.indices[dface->iset.size++] = vertex; + } + } + + f->iset.size = 0; + } + } + + // Link new faces together + { + for (i = 0; i < context->newhorizonedges.size; ++i) { + qh_index_t phe0, nhe1; + qh_half_edge_t* he0; + qh_half_edge_t* he1; + int ii; + + if (reversed) { + ii = (i == 0) ? context->newhorizonedges.size - 1 : (i-1); + } else { + ii = (i+1) % context->newhorizonedges.size; + } + + phe0 = context->edges[context->newhorizonedges.begin[i]].previous_he; + nhe1 = context->edges[context->newhorizonedges.begin[ii]].next_he; + + he0 = context->edges + phe0; + he1 = context->edges + nhe1; + + QH_ASSERT(he1->to_vertex == apex); + QH_ASSERT(he0->opposite_he == -1); + QH_ASSERT(he1->opposite_he == -1); + + he0->opposite_he = he1->he; + he1->opposite_he = he0->he; + } + + context->newhorizonedges.size = 0; + } + + // Push new face to stack + { + for (i = 0; i < context->scratch.size; ++i) { + qh_face_t* face = context->faces + context->scratch.begin[i]; + + if (face->iset.size > 0) { + qh__push_stack(&context->facestack, face->face); + } + } + + // Release scratch + context->scratch.size = 0; + } + + topface = qh__pop_stack(&context->facestack); + + // TODO: push all non-valid faces for reuse in face stack memory pool + } +} + +//void qh_mesh_export(qh_mesh_t const* mesh, char const* filename) +//{ +// FILE* objfile = fopen(filename, "wt"); +// fprintf(objfile, "o\n"); +// unsigned int i, j; +// +// for (i = 0; i < mesh->nvertices; ++i) { +// qh_vertex_t v = mesh->vertices[i]; +// fprintf(objfile, "v %f %f %f\n", v.x, v.y, v.z); +// } +// +// for (i = 0; i < mesh->nnormals; ++i) { +// qh_vec3_t n = mesh->normals[i]; +// fprintf(objfile, "vn %f %f %f\n", n.x, n.y, n.z); +// } +// +// for (i = 0, j = 0; i < mesh->nindices; i += 3, j++) { +// fprintf(objfile, "f %u/%u %u/%u %u/%u\n", +// mesh->indices[i+0] + 1, mesh->normalindices[j] + 1, +// mesh->indices[i+1] + 1, mesh->normalindices[j] + 1, +// mesh->indices[i+2] + 1, mesh->normalindices[j] + 1); +// } +// +// fclose(objfile); +//} + +qh_face_t* qh__build_tetrahedron(qh_context_t* context, float epsilon) +{ + unsigned int i, j; + qh_index_t vertices[3]; + qh_index_t apex; + qh_face_t* faces; + qh_vertex_t normal, centroid, vapex, tcentroid; + + // Get the initial tetrahedron basis (first face) + qh__tetrahedron_basis(context, &vertices[0]); + + // Find apex from the tetrahedron basis + { + float sdist; + qh_vec3_t v0, v1; + + v0 = context->vertices[vertices[1]]; + v1 = context->vertices[vertices[2]]; + + qh__vec3_sub(&v0, context->vertices + vertices[0]); + qh__vec3_sub(&v1, context->vertices + vertices[0]); + + normal = qh__vec3_cross(&v0, &v1); + qh__vec3_normalize(&normal); + + centroid = qh__face_centroid(vertices, context); + sdist = qh__vec3_dot(&normal, &centroid); + + apex = qh__furthest_point_from_plane(context, NULL, + context->nvertices, &normal, sdist); + vapex = context->vertices[apex]; + + qh__vec3_sub(&vapex, &centroid); + + // Whether the face is looking towards the apex + if (qh__vec3_dot(&vapex, &normal) > 0) { + QH_SWAP(qh_index_t, vertices[1], vertices[2]); + } + } + + faces = qh__next_face(context); + qh__face_init(&faces[0], vertices, context); + + // Build faces from the tetrahedron basis to the apex + { + qh_index_t facevertices[3]; + for (i = 0; i < 3; ++i) { + qh_half_edge_t* edge = context->edges + faces[0].edges[i]; + qh_half_edge_t prevedge = context->edges[edge->previous_he]; + qh_face_t* face = faces+i+1; + qh_half_edge_t* e0; + + facevertices[0] = edge->to_vertex; + facevertices[1] = prevedge.to_vertex; + facevertices[2] = apex; + + qh__next_face(context); + qh__face_init(face, facevertices, context); + + e0 = context->edges + faces[i+1].edges[0]; + edge->opposite_he = e0->he; + e0->opposite_he = edge->he; + } + } + + // Attach half edges to faces tied to the apex + { + for (i = 0; i < 3; ++i) { + qh_face_t* face; + qh_face_t* nextface; + qh_half_edge_t* e1; + qh_half_edge_t* e2; + + j = (i+2) % 3; + + face = faces+i+1; + nextface = faces+j+1; + + e1 = context->edges + face->edges[1]; + e2 = context->edges + nextface->edges[2]; + + QH_ASSERT(e1->opposite_he == -1); + QH_ASSERT(e2->opposite_he == -1); + + e1->opposite_he = e2->he; + e2->opposite_he = e1->he; + + qh__assert_half_edge(e1, context); + qh__assert_half_edge(e2, context); + } + } + + // Create initial point set; every point is + // attached to the first face it can see + { + for (i = 0; i < context->nvertices; ++i) { + qh_vertex_t* v; + qh_face_t* dface = NULL; + + if (vertices[0] == i || vertices[1] == i || vertices[2] == i) { + continue; + } + + for (j = 0; j < 4; ++j) { + if (qh__face_can_see_vertex_epsilon(context, context->faces + j, context->vertices + i, epsilon)) { + dface = context->faces + j; + break; + } + } + + if (dface) { + int valid = 1; + + for (int j = 0; j < 3; ++j) { + qh_half_edge_t* e = context->edges + dface->edges[j]; + if (i == e->to_vertex) { + valid = 0; + break; + } + } + + if (!valid) { continue; } + + if (dface->iset.size + 1 >= dface->iset.capacity) { + dface->iset.capacity *= 2; + dface->iset.indices = QH_REALLOC(qh_index_t, + dface->iset.indices, dface->iset.capacity); + } + + dface->iset.indices[dface->iset.size++] = i; + } + } + } + + // Add initial tetrahedron faces to the face stack + tcentroid.x = tcentroid.y = tcentroid.z = 0.0; + for (i = 0; i < 4; ++i) { + context->valid[i] = 1; + qh__assert_face(context->faces + i, context); + qh__push_stack(&context->facestack, i); + qh__vec3_add(&tcentroid, &context->faces[i].centroid); + } + + // Assign the tetrahedron centroid + qh__vec3_multiply(&tcentroid, 0.25); + context->centroid = tcentroid; + + QH_ASSERT(context->nedges == context->nfaces * 3); + QH_ASSERT(context->nfaces == 4); + QH_ASSERT(context->facestack.size == 4); + + return faces; +} + +void qh__remove_vertex_duplicates(qh_context_t* context, float epsilon) +{ + unsigned int i, j, k; + for (i = 0; i < context->nvertices; ++i) { + qh_vertex_t* v = context->vertices + i; + if (v->x == 0) v->x = 0; + if (v->y == 0) v->y = 0; + if (v->z == 0) v->z = 0; + for (j = i + 1; j < context->nvertices; ++j) { + if (qh__vertex_equals_epsilon(context->vertices + i, + context->vertices + j, epsilon)) + { + for (k = j; k < context->nvertices - 1; ++k) { + context->vertices[k] = context->vertices[k+1]; + } + context->nvertices--; + } + } + } +} + +void qh__init_context(qh_context_t* context, qh_vertex_t const* vertices, unsigned int nvertices) +{ + // TODO: + // size_t nedges = 3 * nvertices - 6; + // size_t nfaces = 2 * nvertices - 4; + unsigned int nfaces = nvertices * (nvertices - 1); + unsigned int nedges = nfaces * 3; + + context->edges = QH_MALLOC(qh_half_edge_t, nedges); + context->faces = QH_MALLOC(qh_face_t, nfaces); + context->facestack.begin = QH_MALLOC(qh_index_t, nfaces); + context->scratch.begin = QH_MALLOC(qh_index_t, nfaces); + context->horizonedges.begin = QH_MALLOC(qh_index_t, nedges); + context->newhorizonedges.begin = QH_MALLOC(qh_index_t, nedges); + context->valid = QH_MALLOC(char, nfaces); + + context->vertices = QH_MALLOC(qh_vertex_t, nvertices); + memcpy(context->vertices, vertices, sizeof(qh_vertex_t) * nvertices); + + context->nvertices = nvertices; + context->nedges = 0; + context->nfaces = 0; + context->facestack.size = 0; + context->scratch.size = 0; + context->horizonedges.size = 0; + context->newhorizonedges.size = 0; + + #ifdef QUICKHULL_DEBUG + context->maxfaces = nfaces; + context->maxedges = nedges; + #endif +} + +void qh__free_context(qh_context_t* context) +{ + unsigned int i; + + for (i = 0; i < context->nfaces; ++i) { + QH_FREE(context->faces[i].iset.indices); + context->faces[i].iset.size = 0; + } + + context->nvertices = 0; + context->nfaces = 0; + + QH_FREE(context->edges); + + QH_FREE(context->faces); + QH_FREE(context->facestack.begin); + QH_FREE(context->scratch.begin); + QH_FREE(context->horizonedges.begin); + QH_FREE(context->newhorizonedges.begin); + QH_FREE(context->vertices); + QH_FREE(context->valid); +} + +void qh_free_mesh(qh_mesh_t mesh) +{ + QH_FREE(mesh.vertices); + QH_FREE(mesh.indices); + QH_FREE(mesh.normalindices); + QH_FREE(mesh.normals); +} + +float qh__compute_epsilon(qh_vertex_t const* vertices, unsigned int nvertices) +{ + float epsilon; + unsigned int i; + + float maxxi = -QH_FLT_MAX; + float maxyi = -QH_FLT_MAX; + + for (i = 0; i < nvertices; ++i) { + float fxi = fabsf(vertices[i].x); + float fyi = fabsf(vertices[i].y); + + if (fxi > maxxi) { + maxxi = fxi; + } + if (fyi > maxyi) { + maxyi = fyi; + } + } + + epsilon = 2 * (maxxi + maxyi) * QH_FLT_EPS; + + return epsilon; +} + +qh_mesh_t qh_quickhull3d(qh_vertex_t const* vertices, unsigned int nvertices) +{ + qh_mesh_t m; + qh_context_t context; + unsigned int* indices; + unsigned int nfaces = 0, i, index, nindices; + float epsilon; + + epsilon = qh__compute_epsilon(vertices, nvertices); + + qh__init_context(&context, vertices, nvertices); + + qh__remove_vertex_duplicates(&context, epsilon); + + // Build the initial tetrahedron + qh__build_tetrahedron(&context, epsilon); + + // Build the convex hull + #ifdef QUICKHULL_DEBUG + qh__build_hull(&context, epsilon, -1, NULL); + #else + qh__build_hull(&context, epsilon); + #endif + + // QH_ASSERT(qh__test_hull(&context, epsilon)); + + for (i = 0; i < context.nfaces; ++i) { + if (context.valid[i]) { nfaces++; } + } + + nindices = nfaces * 3; + + m.normals = QH_MALLOC(qh_vertex_t, nfaces); + m.normalindices = QH_MALLOC(unsigned int, nfaces); + m.vertices = QH_MALLOC(qh_vertex_t, nindices); + m.indices = QH_MALLOC(unsigned int, nindices); + m.nindices = nindices; + m.nnormals = nfaces; + m.nvertices = 0; + + { + index = 0; + for (i = 0; i < context.nfaces; ++i) { + if (!context.valid[i]) { continue; } + m.normals[index] = context.faces[i].normal; + index++; + } + + index = 0; + for (i = 0; i < context.nfaces; ++i) { + if (!context.valid[i]) { continue; } + m.normalindices[index] = index; + index++; + } + + index = 0; + for (i = 0; i < context.nfaces; ++i) { + if (!context.valid[i]) { continue; } + m.indices[index+0] = index+0; + m.indices[index+1] = index+1; + m.indices[index+2] = index+2; + index += 3; + } + + for (i = 0; i < context.nfaces; ++i) { + if (!context.valid[i]) { continue; } + qh_half_edge_t e0 = context.edges[context.faces[i].edges[0]]; + qh_half_edge_t e1 = context.edges[context.faces[i].edges[1]]; + qh_half_edge_t e2 = context.edges[context.faces[i].edges[2]]; + + m.vertices[m.nvertices++] = context.vertices[e0.to_vertex]; + m.vertices[m.nvertices++] = context.vertices[e1.to_vertex]; + m.vertices[m.nvertices++] = context.vertices[e2.to_vertex]; + } + } + + qh__free_context(&context); + + return m; +} diff --git a/src/quickhull.h b/src/quickhull.h @@ -0,0 +1,88 @@ +// +// LICENCE: +// The MIT License (MIT) +// +// Copyright (c) 2016 Karim Naaji, karim.naaji@gmail.com +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE +// +// REFERENCES: +// [1] http://box2d.org/files/GDC2014/DirkGregorius_ImplementingQuickHull.pdf +// [2] http://www.cs.smith.edu/~orourke/books/compgeom.html +// [3] http://www.flipcode.com/archives/The_Half-Edge_Data_Structure.shtml +// [4] http://doc.cgal.org/latest/HalfedgeDS/index.html +// [5] http://thomasdiewald.com/blog/?p=1888 +// [6] https://fgiesen.wordpress.com/2012/02/21/half-edge-based-mesh-representations-theory/ +// +// HOWTO: +// #define QUICKHULL_IMPLEMENTATION +// #define QUICKHULL_DEBUG // Only if assertions need to be checked +// #include "quickhull.h" +// +// HISTORY: +// - 1.0.1 (2016-11-01): Various improvements over epsilon issues and degenerate faces +// Debug functionalities to test final results dynamically +// API to export hull meshes in OBJ files +// - 1.0 (2016-09-10): Initial +// +// TODO: +// - use float* from public interface +// - reduce memory usage + +#ifndef QUICKHULL_H +#define QUICKHULL_H + +// ------------------------------------------------------------------------------------------------ +// QUICKHULL PUBLIC API +// + +typedef struct qh_vertex { + union { + float v[3]; + struct { + float x; + float y; + float z; + }; + }; +} qh_vertex_t; + +typedef qh_vertex_t qh_vec3_t; + +typedef struct qh_mesh { + qh_vertex_t* vertices; + qh_vec3_t* normals; + unsigned int* indices; + unsigned int* normalindices; + unsigned int nindices; + unsigned int nvertices; + unsigned int nnormals; +} qh_mesh_t; + +qh_mesh_t qh_quickhull3d(qh_vertex_t const* vertices, unsigned int nvertices); + +void qh_mesh_export(qh_mesh_t const* mesh, char const* filename); + +void qh_free_mesh(qh_mesh_t mesh); + +// +// END QUICKHULL PUBLIC API +// ------------------------------------------------------------------------------------------------ + +#endif // QUICKHULL_H + diff --git a/src/render.c b/src/render.c @@ -198,18 +198,18 @@ check_gl(); glGetUniformLocation(handle, "normal_matrix"); check_gl(); - resources->attributes.normal = + resources->vertex_attrs[va_normal] = (gpu_addr)glGetAttribLocation(handle, "normal"); check_gl(); - resources->attributes.position = + resources->vertex_attrs[va_position] = (gpu_addr)glGetAttribLocation(handle, "position"); check_gl(); } // TODO: auto-generate these somehow? - resources->attributes.color = + resources->vertex_attrs[va_color] = (gpu_addr)glGetAttribLocation(resources->programs[DEFAULT_PROGRAM] .handle, "color"); /* assert(resources->attributes.color != 0xFFFFFFFF); */ @@ -346,7 +346,7 @@ void render (struct game *game, struct render_config *config) { recalc_normals(res->uniforms.normal_matrix, model_view, normal_matrix); check_gl(); - render_geometry(get_geometry(&entity->model->geom_id), &res->attributes, current_program); + render_geometry(get_geometry(&entity->model->geom_id), res->vertex_attrs, current_program); check_gl(); } diff --git a/src/scene.c b/src/scene.c @@ -26,7 +26,7 @@ void default_scene(struct game *game) { player->flags &= ~ENT_INVISIBLE; struct entity *tower = new_entity(NULL); - tower->model = get_model(model_tower); + tower->model = get_model(MODEL_TOWER); tower->node.label = "tower"; node_attach(&tower->node, &player->node); node_translate(&tower->node, V3(0.0, 50.0, 0.0)); @@ -40,5 +40,5 @@ void default_scene(struct game *game) { } void pbr_scene(struct game *game) { - struct model *sphere = get_model(model_icosphere); + struct model *sphere = get_model(MODEL_ICOSPHERE); } diff --git a/src/skybox.c b/src/skybox.c @@ -89,10 +89,10 @@ void create_skybox(struct skybox *skybox, struct gpu_program *program) { skybox->uniforms.mvp = glGetUniformLocation(skybox->program->handle, "mvp"); - skybox->attrs.position = (gpu_addr) + skybox->attrs[va_position] = (gpu_addr) glGetAttribLocation(skybox->program->handle, "position"); - skybox->attrs.tex_coord = (gpu_addr) + skybox->attrs[va_tex_coord] = (gpu_addr) glGetAttribLocation(skybox->program->handle, "tex_coord"); } @@ -111,7 +111,7 @@ void render_skybox(struct skybox *skybox, mat4 *camera) { glBindTexture(GL_TEXTURE_CUBE_MAP, skybox->model.texture); check_gl(); - render_geometry(get_geometry(&skybox->model.geom_id), &skybox->attrs, skybox->program); + render_geometry(get_geometry(&skybox->model.geom_id), skybox->attrs, skybox->program); check_gl(); glDepthMask(GL_TRUE); diff --git a/src/skybox.h b/src/skybox.h @@ -10,7 +10,7 @@ struct skybox { struct gpu_program *program; struct model model; - struct attributes attrs; + gpu_addr attrs[n_vertex_attrs]; struct node node; struct { int mvp; diff --git a/src/terrain.c b/src/terrain.c @@ -192,7 +192,7 @@ void create_terrain(struct terrain *terrain, float scale) { vec3_normalize(tmp2, tmp2); for (int j = 0; j < 9; ++j) { - del_norms[ndv+j] = tmp2[j%3]; + del_norms[ndv+j] = tmp2[j%3]; } del_indices[nv+0] = nv+0; diff --git a/src/terrain.h b/src/terrain.h @@ -21,7 +21,7 @@ struct perlin_settings { struct terrain { - entity_id_t entity_id; + entity_id entity_id; struct perlin_settings settings; struct point *samples; struct model model; diff --git a/src/ui.c b/src/ui.c @@ -34,7 +34,7 @@ static GLfloat quad_uvs[] = }; -static void create_quad(geometry_id_t *id) +static void create_quad(geometry_id *id) { struct make_geometry mkgeom = { .indices = quad_indices, @@ -70,7 +70,7 @@ void render_ui(struct ui *ui, float *view) { check_gl(); // render quad - render_geometry(get_geometry(&ui->quad_geom_id), &ui->attrs, ui->shader); + render_geometry(get_geometry(&ui->quad_geom_id), ui->attrs, ui->shader); check_gl(); } @@ -115,9 +115,9 @@ void create_ui(struct ui *ui, int width, int height, struct gpu_program *shader) glGetUniformLocation(program, "screen_texture"); /* ui->attrs.normal = (gpu_addr)glGetAttribLocation(program, "normal"); */ - ui->attrs.position = (gpu_addr)glGetAttribLocation(program, "position"); - ui->attrs.color = (gpu_addr)glGetAttribLocation(program, "color"); - ui->attrs.tex_coord = (gpu_addr)glGetAttribLocation(program, "tex_coords"); + ui->attrs[va_position] = (gpu_addr)glGetAttribLocation(program, "position"); + ui->attrs[va_color] = (gpu_addr)glGetAttribLocation(program, "color"); + ui->attrs[va_tex_coord] = (gpu_addr)glGetAttribLocation(program, "tex_coords"); check_gl(); resize_ui(ui, width, height); diff --git a/src/ui.h b/src/ui.h @@ -8,8 +8,8 @@ struct ui { struct gpu_program *shader; - geometry_id_t quad_geom_id; - struct attributes attrs; + geometry_id quad_geom_id; + gpu_addr attrs[n_vertex_attrs]; struct ui_uniforms { GLint mvp; diff --git a/src/update.c b/src/update.c @@ -192,14 +192,14 @@ void resize_fbos(struct entity *player, struct fbo *shadow_buffer, } // TODO: compute better bounds based - const float factor = 1.5; + const float factor = 4.5; struct geometry *geom = get_geometry(&player->model->geom_id); float left = geom->min[0] - factor; float right = geom->max[0] + factor; float bottom = geom->min[1] - factor; float top = geom->max[1] + factor/2.0; - const float near = -1.0; + const float near = -5.0; const float far = 5.0; // default ortho screenspace projection @@ -301,8 +301,12 @@ void orbit_update_from_mouse(struct orbit *camera, struct input *input, else camera->coords.radius -= dt * 100.0; - camera->coords.radius = max(5.0, camera->coords.radius); } + else if (input->wheel_y) { + camera->coords.radius += input->wheel_y * dt * 100.0; + } + + camera->coords.radius = max(5.0, camera->coords.radius); camera->coords.azimuth += mx; camera->coords.inclination += my; diff --git a/src/util.c b/src/util.c @@ -15,14 +15,6 @@ int clampi(int a, int mina, int maxa) { return a; } -double max(double a, double b) { - return a > b ? a : b; -} - -double min(double a, double b) { - return a < b ? a : b; -} - double clamp(double a, double mina, double maxa) { if (a > maxa) return maxa; diff --git a/src/util.h b/src/util.h @@ -6,7 +6,7 @@ #include "vec3.h" #include "mat4.h" #include <assert.h> - +#include <string.h> #define check_gl() { \ unsigned int e = glGetError(); \ @@ -22,13 +22,17 @@ #define RAD(x) ((x)*TAU/360.0) +#define EPSILON 0.0001 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define min(a,b) (a < b ? a : b) +#define max(a,b) (a > b ? a : b) +#define streq(a,b) (strcmp(a,b) == 0) +#define memeq(a,b,n1,n2) (memcmp(a,b,min(n1, n2)) == 0) +#define approxeq(a, b) (fabs(a-b) < EPSILON) void look_at(vec3 *eye, vec3 *target, vec3 *up, mat4 *dest); int clampi(int a, int mina, int maxa); double clamp(double a, double mina, double maxa); -double max(double a, double b); -double min(double a, double b); double rand_0to1(); diff --git a/src/vbo.c b/src/vbo.c @@ -20,36 +20,85 @@ make_buffer(GLenum target, const void *buffer_data, GLsizei buffer_size) { return buffer; } + +static struct vbo* +make_vertex_buffer(struct vbo *vbo, const void *data, + GLenum type, + GLenum component_type, + struct element_size element_size, + struct num_elements num_elements, + struct components components) +{ + vbo->components = components.components; + vbo->handle = make_buffer(type, + data, + num_elements.num_elements * + element_size.element_size * + components.components); + vbo->type = type; + vbo->component_type = component_type; + return vbo; +} + struct vbo* -make_index_buffer(GLenum target, const void *data, GLsizei buffer_size, - struct vbo *vbo) { - vbo->components = 3; - vbo->handle = make_buffer(target, data, buffer_size); - vbo->type = GL_ELEMENT_ARRAY_BUFFER; - return vbo; +make_index_buffer(struct vbo *vbo, const void *data, + struct num_elements num_elements) +{ + return make_vertex_buffer(vbo, + data, + GL_ELEMENT_ARRAY_BUFFER, + GL_INT, + mk_element_size(sizeof(u32)), + num_elements, + mk_components(3) + ); } +struct vbo* make_float_vertex_buffer(struct vbo *vbo, const void *data, + struct num_elements num_elements, + struct components components) +{ + return make_vertex_buffer(vbo, + data, + GL_ARRAY_BUFFER, + GL_FLOAT, + mk_element_size(sizeof(GLfloat)), + num_elements, + components); +} -struct vbo* -make_vertex_buffer(GLenum target, const void *data, - GLsizei buffer_size, struct vbo *vbo) { - vbo->components = 3; - vbo->handle = make_buffer(target, data, buffer_size); - vbo->type = GL_ARRAY_BUFFER; - return vbo; + +struct vbo* make_int_vertex_buffer(struct vbo *vbo, const int *data, + struct num_elements num_elements, + struct components components) +{ + return make_vertex_buffer(vbo, + data, + GL_ARRAY_BUFFER, + GL_INT, + mk_element_size(sizeof(u32)), + num_elements, + components); } -struct vbo* -make_uv_buffer(GLenum target, const void *data, - GLsizei buffer_size, struct vbo *vbo, int components) { - vbo->components = components; - vbo->handle = make_buffer(target, data, buffer_size); - vbo->type = GL_ARRAY_BUFFER; - return vbo; + +struct vbo * make_uv_buffer(struct vbo *vbo, const void *data, + struct num_elements num_elements, + struct components components) +{ + return make_vertex_buffer(vbo, + data, + GL_ARRAY_BUFFER, + GL_FLOAT, + mk_element_size(sizeof(float)), + num_elements, + components); } -void bind_ibo(struct vbo *vbo) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo->handle); + +static void bind_ibo(struct vbo *vbo) +{ + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo->handle); } struct vbo* init_vbo(struct vbo *vbo) { @@ -59,20 +108,35 @@ struct vbo* init_vbo(struct vbo *vbo) { return vbo; } -static void bind_vbo_internal(struct vbo *vbo, gpu_addr slot) { +static void bind_vbo_internal(struct vbo *vbo, gpu_addr slot, GLenum type) { glEnableVertexAttribArray(slot); check_gl(); glBindBuffer(vbo->type, vbo->handle); check_gl(); - glVertexAttribPointer(slot, // attribute - vbo->components, // size - GL_FLOAT, // type - GL_FALSE, // normalized? - 0, // stride - (void*)0 // array buffer offset - ); + + // should use bind_ibo instead... + assert(vbo->type != GL_ELEMENT_ARRAY_BUFFER); + + if (vbo->component_type == GL_INT) { + glVertexAttribIPointer(slot, + vbo->components, + type, + 0, // stride + (void*)0); + } + else { + glVertexAttribPointer(slot, // attribute + vbo->components, // size + type, // type + GL_FALSE, // normalized? + 0, // stride + (void*)0 // array buffer offset + ); + } } -void bind_vbo(struct vbo *vbo, gpu_addr slot) { - bind_vbo_internal(vbo, slot); +void bind_vbo(struct vbo *vbo, gpu_addr slot, GLenum type) { + if (vbo->type == GL_ELEMENT_ARRAY_BUFFER) + return bind_ibo(vbo); + bind_vbo_internal(vbo, slot, type); } diff --git a/src/vbo.h b/src/vbo.h @@ -6,40 +6,68 @@ typedef GLuint gpu_addr; -struct attributes { - gpu_addr position; - gpu_addr normal; - gpu_addr color; - gpu_addr tex_coord; +#define VERT_ATTRS 6 + +enum vertex_attr { + va_position, + va_normal, + va_color, + va_index, + va_tex_coord, + va_joint_ids, + va_joint_weights, + n_vertex_attrs }; struct vbo { - u32 type; - int components; - gpu_addr handle; + u32 type; + int component_type; + int components; + gpu_addr handle; +}; + +struct num_elements { + int num_elements; }; +#define mk_num_elements(x) ((struct num_elements){ .num_elements = x }) + +struct element_size { + int element_size; +}; +#define mk_element_size(x) ((struct element_size){ .element_size = x }) + +struct components { + int components; +}; +#define mk_components(c) ((struct components){ .components = c }) #define NUM_VBO_SLOTS 1 -gpu_addr make_buffer(GLenum target, const void *buffer_data, - GLsizei buffer_size); +gpu_addr make_buffer(GLenum target, const void *buffer_data, GLsizei buffer_size); struct vbo *init_vbo(struct vbo *); -struct vbo * -make_vertex_buffer(GLenum target, const void *buffer_data, - GLsizei buffer_size, struct vbo *vbo); +struct vbo* make_float_vertex_buffer(struct vbo *vbo, + const void *data, + struct num_elements, + struct components); -struct vbo * -make_index_buffer(GLenum target, const void *buffer_data, - GLsizei buffer_size, struct vbo *vbo); +struct vbo* make_index_buffer(struct vbo *vbo, + const void *data, + struct num_elements); + +struct vbo * make_uv_buffer(struct vbo *vbo, + const void *data, + struct num_elements, + struct components); struct vbo * -make_uv_buffer(GLenum target, const void *data, - GLsizei buffer_size, struct vbo *vbo, int components); +make_int_vertex_buffer(struct vbo *vbo, const int *data, + struct num_elements num_elements, + struct components components); + void bind_uv_vbo(struct vbo *vbo, gpu_addr slot); -void bind_vbo(struct vbo *vbo, gpu_addr slot); -void bind_ibo(struct vbo *vbo); +void bind_vbo(struct vbo *vbo, gpu_addr slot, GLenum type); #endif /* POLYADVENT_BUFFER_H */ diff --git a/src/vec3.h b/src/vec3.h @@ -1,3 +1,8 @@ + +#ifndef VEC3_H +#define VEC3_H + + typedef float vec3; #define V3(x,y,z) ((vec3[3]){x,y,z}) @@ -22,3 +27,6 @@ vec3 *vec3_all(vec3 *vec, float n); vec3 *vec3_add(vec3 *vec, vec3 *vec2, vec3 *dest); int vec3_eq(vec3 *a, vec3 *b, float precision); void vec3_copy(vec3 *a, vec3 *dest); + + +#endif /* VEC3_H */ diff --git a/src/xml.c b/src/xml.c @@ -0,0 +1,459 @@ +#include <sys/types.h> + +#include <ctype.h> +#include <errno.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "xml.h" + +static void +xml_parseattrs(struct xmlparser *x) +{ + size_t namelen = 0, valuelen; + int c, endsep, endname = 0, valuestart = 0; + + while ((c = GETNEXT) != EOF) { + if (isspace(c)) { + if (namelen) + endname = 1; + continue; + } else if (c == '?') + ; /* ignore */ + else if (c == '=') { + x->name[namelen] = '\0'; + valuestart = 1; + endname = 1; + } else if (namelen && ((endname && !valuestart && isalpha(c)) || (c == '>' || c == '/'))) { + /* attribute without value */ + x->name[namelen] = '\0'; + if (x->xmlattrstart) + x->xmlattrstart(x, x->tag, x->taglen, x->name, namelen); + if (x->xmlattr) + x->xmlattr(x, x->tag, x->taglen, x->name, namelen, "", 0); + if (x->xmlattrend) + x->xmlattrend(x, x->tag, x->taglen, x->name, namelen); + endname = 0; + x->name[0] = c; + namelen = 1; + } else if (namelen && valuestart) { + /* attribute with value */ + if (x->xmlattrstart) + x->xmlattrstart(x, x->tag, x->taglen, x->name, namelen); + + valuelen = 0; + if (c == '\'' || c == '"') { + endsep = c; + } else { + endsep = ' '; /* isspace() */ + goto startvalue; + } + + while ((c = GETNEXT) != EOF) { +startvalue: + if (c == '&') { /* entities */ + x->data[valuelen] = '\0'; + /* call data function with data before entity if there is data */ + if (valuelen && x->xmlattr) + x->xmlattr(x, x->tag, x->taglen, x->name, namelen, x->data, valuelen); + x->data[0] = c; + valuelen = 1; + while ((c = GETNEXT) != EOF) { + if (c == endsep || (endsep == ' ' && (c == '>' || isspace(c)))) + break; + if (valuelen < sizeof(x->data) - 1) + x->data[valuelen++] = c; + else { + /* entity too long for buffer, handle as normal data */ + x->data[valuelen] = '\0'; + if (x->xmlattr) + x->xmlattr(x, x->tag, x->taglen, x->name, namelen, x->data, valuelen); + x->data[0] = c; + valuelen = 1; + break; + } + if (c == ';') { + x->data[valuelen] = '\0'; + if (x->xmlattrentity) + x->xmlattrentity(x, x->tag, x->taglen, x->name, namelen, x->data, valuelen); + valuelen = 0; + break; + } + } + } else if (c != endsep && !(endsep == ' ' && (c == '>' || isspace(c)))) { + if (valuelen < sizeof(x->data) - 1) { + x->data[valuelen++] = c; + } else { + x->data[valuelen] = '\0'; + if (x->xmlattr) + x->xmlattr(x, x->tag, x->taglen, x->name, namelen, x->data, valuelen); + x->data[0] = c; + valuelen = 1; + } + } + if (c == endsep || (endsep == ' ' && (c == '>' || isspace(c)))) { + x->data[valuelen] = '\0'; + if (x->xmlattr) + x->xmlattr(x, x->tag, x->taglen, x->name, namelen, x->data, valuelen); + if (x->xmlattrend) + x->xmlattrend(x, x->tag, x->taglen, x->name, namelen); + break; + } + } + namelen = endname = valuestart = 0; + } else if (namelen < sizeof(x->name) - 1) { + x->name[namelen++] = c; + } + if (c == '>') { + break; + } else if (c == '/') { + x->isshorttag = 1; + x->name[0] = '\0'; + namelen = 0; + } + } +} + +static void +xml_parsecomment(struct xmlparser *x) +{ + size_t datalen = 0, i = 0; + int c; + + if (x->xmlcommentstart) + x->xmlcommentstart(x); + while ((c = GETNEXT) != EOF) { + if (c == '-' || c == '>') { + if (x->xmlcomment && datalen) { + x->data[datalen] = '\0'; + x->xmlcomment(x, x->data, datalen); + datalen = 0; + } + } + + if (c == '-') { + if (++i > 2) { + if (x->xmlcomment) + for (; i > 2; i--) + x->xmlcomment(x, "-", 1); + i = 2; + } + continue; + } else if (c == '>' && i == 2) { + if (x->xmlcommentend) + x->xmlcommentend(x); + return; + } else if (i) { + if (x->xmlcomment) { + for (; i > 0; i--) + x->xmlcomment(x, "-", 1); + } + i = 0; + } + + if (datalen < sizeof(x->data) - 1) { + x->data[datalen++] = c; + } else { + x->data[datalen] = '\0'; + if (x->xmlcomment) + x->xmlcomment(x, x->data, datalen); + x->data[0] = c; + datalen = 1; + } + } +} + +static void +xml_parsecdata(struct xmlparser *x) +{ + size_t datalen = 0, i = 0; + int c; + + if (x->xmlcdatastart) + x->xmlcdatastart(x); + while ((c = GETNEXT) != EOF) { + if (c == ']' || c == '>') { + if (x->xmlcdata && datalen) { + x->data[datalen] = '\0'; + x->xmlcdata(x, x->data, datalen); + datalen = 0; + } + } + + if (c == ']') { + if (++i > 2) { + if (x->xmlcdata) + for (; i > 2; i--) + x->xmlcdata(x, "]", 1); + i = 2; + } + continue; + } else if (c == '>' && i == 2) { + if (x->xmlcdataend) + x->xmlcdataend(x); + return; + } else if (i) { + if (x->xmlcdata) + for (; i > 0; i--) + x->xmlcdata(x, "]", 1); + i = 0; + } + + if (datalen < sizeof(x->data) - 1) { + x->data[datalen++] = c; + } else { + x->data[datalen] = '\0'; + if (x->xmlcdata) + x->xmlcdata(x, x->data, datalen); + x->data[0] = c; + datalen = 1; + } + } +} + +static int +codepointtoutf8(long r, char *s) +{ + if (r == 0) { + return 0; /* NUL byte */ + } else if (r <= 0x7F) { + /* 1 byte: 0aaaaaaa */ + s[0] = r; + return 1; + } else if (r <= 0x07FF) { + /* 2 bytes: 00000aaa aabbbbbb */ + s[0] = 0xC0 | ((r & 0x0007C0) >> 6); /* 110aaaaa */ + s[1] = 0x80 | (r & 0x00003F); /* 10bbbbbb */ + return 2; + } else if (r <= 0xFFFF) { + /* 3 bytes: aaaabbbb bbcccccc */ + s[0] = 0xE0 | ((r & 0x00F000) >> 12); /* 1110aaaa */ + s[1] = 0x80 | ((r & 0x000FC0) >> 6); /* 10bbbbbb */ + s[2] = 0x80 | (r & 0x00003F); /* 10cccccc */ + return 3; + } else { + /* 4 bytes: 000aaabb bbbbcccc ccdddddd */ + s[0] = 0xF0 | ((r & 0x1C0000) >> 18); /* 11110aaa */ + s[1] = 0x80 | ((r & 0x03F000) >> 12); /* 10bbbbbb */ + s[2] = 0x80 | ((r & 0x000FC0) >> 6); /* 10cccccc */ + s[3] = 0x80 | (r & 0x00003F); /* 10dddddd */ + return 4; + } +} + +static int +namedentitytostr(const char *e, char *buf, size_t bufsiz) +{ + static const struct { + const char *entity; + int c; + } entities[] = { + { "amp;", '&' }, + { "lt;", '<' }, + { "gt;", '>' }, + { "apos;", '\'' }, + { "quot;", '"' }, + { "AMP;", '&' }, + { "LT;", '<' }, + { "GT;", '>' }, + { "APOS;", '\'' }, + { "QUOT;", '"' } + }; + size_t i; + + /* buffer is too small */ + if (bufsiz < 2) + return -1; + + for (i = 0; i < sizeof(entities) / sizeof(*entities); i++) { + if (!strcmp(e, entities[i].entity)) { + buf[0] = entities[i].c; + buf[1] = '\0'; + return 1; + } + } + return 0; +} + +static int +numericentitytostr(const char *e, char *buf, size_t bufsiz) +{ + long l; + int len; + char *end; + + /* buffer is too small */ + if (bufsiz < 5) + return -1; + + errno = 0; + /* hex (16) or decimal (10) */ + if (*e == 'x') + l = strtoul(e + 1, &end, 16); + else + l = strtoul(e, &end, 10); + /* invalid value or not a well-formed entity or too high codepoint */ + if (errno || *end != ';' || l > 0x10FFFF) + return 0; + len = codepointtoutf8(l, buf); + buf[len] = '\0'; + + return len; +} + +/* convert named- or numeric entity string to buffer string + * returns byte-length of string. */ +int +xml_entitytostr(const char *e, char *buf, size_t bufsiz) +{ + /* doesn't start with & */ + if (e[0] != '&') + return 0; + /* numeric entity */ + if (e[1] == '#') + return numericentitytostr(e + 2, buf, bufsiz); + else /* named entity */ + return namedentitytostr(e + 1, buf, bufsiz); +} + +void +xml_parse(struct xmlparser *x) +{ + size_t datalen, tagdatalen; + int c, isend; + + while ((c = GETNEXT) != EOF && c != '<') + ; /* skip until < */ + + while (c != EOF) { + if (c == '<') { /* parse tag */ + if ((c = GETNEXT) == EOF) + return; + + if (c == '!') { /* cdata and comments */ + for (tagdatalen = 0; (c = GETNEXT) != EOF;) { + /* NOTE: sizeof(x->data) must be atleast sizeof("[CDATA[") */ + if (tagdatalen <= sizeof("[CDATA[") - 1) + x->data[tagdatalen++] = c; + if (c == '>') + break; + else if (c == '-' && tagdatalen == sizeof("--") - 1 && + (x->data[0] == '-')) { + xml_parsecomment(x); + break; + } else if (c == '[') { + if (tagdatalen == sizeof("[CDATA[") - 1 && + !strncmp(x->data, "[CDATA[", tagdatalen)) { + xml_parsecdata(x); + break; + } + } + } + } else { + /* normal tag (open, short open, close), processing instruction. */ + x->tag[0] = c; + x->taglen = 1; + x->isshorttag = isend = 0; + + /* treat processing instruction as shorttag, don't strip "?" prefix. */ + if (c == '?') { + x->isshorttag = 1; + } else if (c == '/') { + if ((c = GETNEXT) == EOF) + return; + x->tag[0] = c; + isend = 1; + } + + while ((c = GETNEXT) != EOF) { + if (c == '/') + x->isshorttag = 1; /* short tag */ + else if (c == '>' || isspace(c)) { + x->tag[x->taglen] = '\0'; + if (isend) { /* end tag, starts with </ */ + if (x->xmltagend) + x->xmltagend(x, x->tag, x->taglen, x->isshorttag); + x->tag[0] = '\0'; + x->taglen = 0; + } else { + /* start tag */ + if (x->xmltagstart) + x->xmltagstart(x, x->tag, x->taglen); + if (isspace(c)) + xml_parseattrs(x); + if (x->xmltagstartparsed) + x->xmltagstartparsed(x, x->tag, x->taglen, x->isshorttag); + } + /* call tagend for shortform or processing instruction */ + if (x->isshorttag) { + if (x->xmltagend) + x->xmltagend(x, x->tag, x->taglen, x->isshorttag); + x->tag[0] = '\0'; + x->taglen = 0; + } + break; + } else if (x->taglen < sizeof(x->tag) - 1) + x->tag[x->taglen++] = c; /* NOTE: tag name truncation */ + } + } + } else { + /* parse tag data */ + datalen = 0; + if (x->xmldatastart) + x->xmldatastart(x); + while ((c = GETNEXT) != EOF) { + if (c == '&') { + if (datalen) { + x->data[datalen] = '\0'; + if (x->xmldata) + x->xmldata(x, x->data, datalen); + } + x->data[0] = c; + datalen = 1; + while ((c = GETNEXT) != EOF) { + if (c == '<') + break; + if (datalen < sizeof(x->data) - 1) + x->data[datalen++] = c; + else { + /* entity too long for buffer, handle as normal data */ + x->data[datalen] = '\0'; + if (x->xmldata) + x->xmldata(x, x->data, datalen); + x->data[0] = c; + datalen = 1; + break; + } + if (c == ';') { + x->data[datalen] = '\0'; + if (x->xmldataentity) + x->xmldataentity(x, x->data, datalen); + datalen = 0; + break; + } + } + } else if (c != '<') { + if (datalen < sizeof(x->data) - 1) { + x->data[datalen++] = c; + } else { + x->data[datalen] = '\0'; + if (x->xmldata) + x->xmldata(x, x->data, datalen); + x->data[0] = c; + datalen = 1; + } + } + if (c == '<') { + x->data[datalen] = '\0'; + if (x->xmldata && datalen) + x->xmldata(x, x->data, datalen); + if (x->xmldataend) + x->xmldataend(x); + break; + } + } + } + } +} diff --git a/src/xml.h b/src/xml.h @@ -0,0 +1,73 @@ +#ifndef _XML_H +#define _XML_H + +#define XML_BUFSIZ 1024 + +#include <stdlib.h> + +struct xmlparser { + /* handlers */ + void (*xmlattr)(struct xmlparser *, const char *, size_t, + const char *, size_t, const char *, size_t); + void (*xmlattrend)(struct xmlparser *, const char *, size_t, + const char *, size_t); + void (*xmlattrstart)(struct xmlparser *, const char *, size_t, + const char *, size_t); + void (*xmlattrentity)(struct xmlparser *, const char *, size_t, + const char *, size_t, const char *, size_t); + void (*xmlcdatastart)(struct xmlparser *); + void (*xmlcdata)(struct xmlparser *, const char *, size_t); + void (*xmlcdataend)(struct xmlparser *); + void (*xmlcommentstart)(struct xmlparser *); + void (*xmlcomment)(struct xmlparser *, const char *, size_t); + void (*xmlcommentend)(struct xmlparser *); + void (*xmldata)(struct xmlparser *, const char *, size_t); + void (*xmldataend)(struct xmlparser *); + void (*xmldataentity)(struct xmlparser *, const char *, size_t); + void (*xmldatastart)(struct xmlparser *); + void (*xmltagend)(struct xmlparser *, const char *, size_t, int); + void (*xmltagstart)(struct xmlparser *, const char *, size_t); + void (*xmltagstartparsed)(struct xmlparser *, const char *, + size_t, int); + +#ifndef GETNEXT + #define GETNEXT (x)->getnext(x) + int (*getnext)(struct xmlparser *); +#endif + + /* current tag */ + char tag[1024]; + size_t taglen; + void *user_data; + /* current tag is in short form ? <tag /> */ + int isshorttag; + /* current attribute name */ + char name[1024]; + /* data buffer used for tag data, cdata and attribute data */ + char data[XML_BUFSIZ]; +}; + +int xml_entitytostr(const char *, char *, size_t); +void xml_parse(struct xmlparser *); +#endif + +/* +void xmlattr(struct xmlparser *x, const char *t, size_t tl, const char *a, size_t al, const char *v, size_t vl) +void xmlattrentity(struct xmlparser *x, const char *t, size_t tl, const char *a, size_t al, const char *v, size_t vl) +void xmlattrend(struct xmlparser *x, const char *t, size_t tl, const char *a, size_t al) +void xmlattrstart(struct xmlparser *x, const char *t, size_t tl, const char *a, size_t al) +void xmlcdatastart(struct xmlparser *x) +void xmlcdata(struct xmlparser *x, const char *d, size_t dl) +void xmlcdataend(struct xmlparser *x) +void xmlcommentstart(struct xmlparser *x) +void xmlcomment(struct xmlparser *x, const char *c, size_t cl) +void xmlcommentend(struct xmlparser *x) +void xmldata(struct xmlparser *x, const char *d, size_t dl) +void xmldataend(struct xmlparser *x) +void xmldataentity(struct xmlparser *x, const char *d, size_t dl) +void xmldatastart(struct xmlparser *x) +void xmltagend(struct xmlparser *x, const char *t, size_t tl, int isshort) +void xmltagstart(struct xmlparser *x, const char *t, size_t tl) +void xmltagstartparsed(struct xmlparser *x, const char *t, size_t tl, int isshort) + +*/ diff --git a/test/test-half-edge.c b/test/test-half-edge.c @@ -0,0 +1,7 @@ + +#include "half-edge.h" + +int main(int argc, char *argv[]) +{ + return 0; +} diff --git a/test/test_animation.c b/test/test_animation.c @@ -0,0 +1,30 @@ + +#include "animation.h" +#include "util.h" +#include <assert.h> +#include <stdio.h> + + +int main(int argc, char *argv[]) +{ + struct pose *pose; + struct joint *joint; + struct pose poses[4]; + int nposes; + + load_poses("data/models/pirate-officer.dae", poses, &nposes); + assert(nposes == 1); + + pose = &poses[0]; + assert(pose->njoints == 11); + + joint = &pose->joints[0]; + assert(approxeq(joint->mat[0], 0.999897)); + + joint = &pose->joints[1]; + assert(approxeq(joint->mat[1], -0.01434187)); + + assert(pose->joints[0].nchildren == 3); + + return 0; +}