diff --git a/.gitignore b/.gitignore index aa724b7..377e1a6 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,5 @@ /captures .externalNativeBuild .cxx +.idea local.properties diff --git a/CMakeLists.txt b/CMakeLists.txt index 975bf74..ab55bea 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -26,6 +26,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Android") add_library(face_sdk SHARED app/src/main/cpp/main.cpp app/src/main/cpp/AndroidOut.cpp + app/src/main/cpp/DebugLog.h + app/src/main/cpp/DebugLog.cpp + app/src/main/cpp/CrashHandler.h + app/src/main/cpp/CrashHandler.cpp vulkan/AppBase.h vulkan/AppBase.cpp vulkan/Application.h @@ -49,7 +53,10 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Android") game-activity::game-activity_static Vulkan::Vulkan android - log) + log + # dl: needed by CrashHandler::dumpFrame -> dladdr() to map a + # PC back to "module + symbol + offset" in the crash log. + dl) target_compile_definitions(face_sdk PRIVATE VMA_STATIC_VULKAN_FUNCTIONS=0 diff --git a/DEBUG_GUIDE.md b/DEBUG_GUIDE.md new file mode 100644 index 0000000..d50a68e --- /dev/null +++ b/DEBUG_GUIDE.md @@ -0,0 +1,191 @@ +# Face SDK 崩溃调试指南 + +本文档说明如何配合 AI 定位 `libface_sdk.so` 里的崩溃 / 异常。核心思路:**把 Vulkan 每一次异常的上下文写进一个持久日志文件里,崩溃或画面卡住后把这份文件发给 AI 分析。** + +--- + +## 一、已经加好的东西(不需要你做什么) + +### 1. `DebugLog` 模块(`app/src/main/cpp/DebugLog.{h,cpp}`) + +- 线程安全; +- 每条日志带**时间戳 + 线程 ID(tid)**; +- 写到 App **私有目录下的文件** —— 不会被 logcat 自动清掉; +- 每写一行 `fflush`,进程挂了也不丢最后几行; +- 文件大小超过 2MB 自动滚动到 `.old`; +- 同步把日志镜像到 logcat,tag 是 `FACE_DBG`。 + +### 2. 打点位置 + +| 位置 | 打点内容 | 用途 | +|---|---|---| +| `android_main` 启动 | pid、tid、日志文件绝对路径 | 每次启动一条,作为分段锚点 | +| 渲染循环心跳 | 每 600 帧一条:`frame=X exceptions_so_far=Y` | 判断启动多久后崩溃 / 异常持续性 | +| `try/catch` 兜底 | 首 10 次异常每次都打,之后每 120 次打一次 | **Vulkan 异常不会再让进程硬崩**,留住现场 | +| `handle_cmd` | 每个 `APP_CMD_*` 事件(尤其 `INIT_WINDOW`/`TERM_WINDOW`/`CONFIG_CHANGED`) | 旋转 / 切后台 / 锁屏场景的时间线 | +| `FaceApp::initVulkan` 入/出口 | 调用次数、`_applicationInited` / `_faceAppInited` / `_sceondInited` 状态 | 判断是否被多次重复调用 | +| `processImageNative` / `passDataToNative` | 每 300 次调用打一条 tid | 验证"Java 两个回调在不同线程并发调 Vulkan"假设 | +| `Application::drawFrame` 里的 4 次 Vulkan 调用 | 非 `VK_SUCCESS` 时打印数值 + 字符串名(例如 `-4 (VK_ERROR_DEVICE_LOST)`) | **最关键的证据** | + +### 3. 关键行为变化 + +**⚠️ 现在 `drawFrame` 里 Vulkan 抛出的异常会被 `try/catch` 吃掉 —— App 不会再因为这类问题硬崩溃。** + +- 好处:你能继续跑、继续复现、日志一直在写; +- 代价:出问题时表现从"崩溃"变成"**画面卡住 / 黑屏 / 不再更新**"。 +- 如果想暂时回到硬崩行为:把 `app/src/main/cpp/main.cpp` 里那段 `try { g_Application->drawFrame(...); } catch (...) { ... }` 改回直接 `g_Application->drawFrame(frameTime);` 即可。 + +--- + +## 二、怎么把日志文件取出来 + +### 方式 A:`run-as`(推荐,不需要 root) + +```bash +adb shell "run-as com.inewme.uvmirror cat files/face_sdk_debug.log" > face_sdk_debug.log +adb shell "run-as com.inewme.uvmirror cat files/face_sdk_debug.log.old" > face_sdk_debug.log.old +``` + +> `.old` 只有文件滚动过一次才存在,没有可以忽略错误。 + +### 方式 B:直接看 logcat(实时) + +```bash +adb logcat -s FACE_DBG +``` + +和文件内容基本一致。跑较久的话还是文件更可靠。 + +### 方式 C:从 App 里拿路径 + +启动后 `FACE_DBG` 第一条日志长这样: + +``` +[10:12:03.041][tid=12345] android_main start, pid=23456 tid=12345, logPath=/data/user/0/com.inewme.uvmirror/files/face_sdk_debug.log +``` + +照这个路径走就对了。 + +--- + +## 三、你现在要做的事(B 方案:两种场景都复现一次) + +### 场景 1:旋转崩溃(已确认必现) + +1. 打开 App,等初始化完成(画面能看到人脸渲染)。 +2. **旋转一次屏幕**。 +3. 等 3~5 秒让日志写进去。 +4. 取 `face_sdk_debug.log`,**不要清文件**,继续场景 2。 + +期望看到的关键行: +``` +>> handle_cmd APP_CMD_TERM_WINDOW(...) +>> handle_cmd APP_CMD_INIT_WINDOW(...) +FaceApp::initVulkan enter, call#2 ... +drawFrame[NNN] vkAcquireNextImageKHR -> ??? (...) +!!! drawFrame std::exception (frame=NNN count=M): failed to ... +``` + +注意里面那个 `???` —— 这是整件事的核心证据。 + +### 场景 2:长时间运行崩溃(之前那个 10 分钟左右的) + +**不要退出 App,接着跑**。现在即使旋转触发了异常,进程没死,我们希望看后续会不会再出另一种 VkResult: + +1. 尽量不操作(不切后台、不旋转、不锁屏,让 App 持续渲染)。 +2. 连续跑 **15~20 分钟**,观察是否复现之前的"无外部事件崩溃"。 +3. 复现后(或稳定 20 分钟未复现也行),再取一次 `face_sdk_debug.log`(这次会覆盖场景 1 的那份,所以务必**先把场景 1 的单独保存好**)。 + +期望看到的关键行(如果真的是 DEVICE_LOST): +``` +drawFrame[NNN] vkQueueSubmit -> -4 (VK_ERROR_DEVICE_LOST) ... +``` +或者某个 Vulkan 调用返回其他错误码。 + +### 辅助信息(手边有就顺便记一下) + +| 项 | 为什么要 | +|---|---| +| 机型 + Android 版本 | GPU 驱动差异;Adreno / Mali / Xclipse 表现差别大 | +| 复现时手机是不是很烫 | 排查 GPU 温控 / thermal throttling | +| 旋转时是"横屏 → 竖屏"还是"竖屏 → 横屏" / 多次连续旋转? | 某些机型一次 vs 多次触发行为不同 | +| 10 分钟崩溃时 App 在做什么(有在切换 motion 吗?) | 帮助排除 `changeMotionList` 相关路径 | + +--- + +## 四、发给 AI 的时候包含什么 + +最小集: + +1. `face_sdk_debug.log`(场景 1 旋转那份) +2. `face_sdk_debug.log`(场景 2 长跑那份) +3. 如果文件很大,**完整发**比截断发强(AI 主要关心最后几千行) +4. 一句话说明这份日志对应场景 1 还是场景 2,是否复现了 + +不需要的: + +- logcat 完整 dump(体积太大且大多无关,除非 AI 主动问特定 tag) +- 录屏 +- 源代码(AI 已经能看到仓库) + +--- + +## 五、当前未解决的假设,等日志验证 + +| 假设 | 对应 VkResult | 修法 | +|---|---|---| +| 旋转导致 surface 失效未处理 | `VK_ERROR_OUT_OF_DATE_KHR` (-1000001004) 或 `VK_ERROR_SURFACE_LOST_KHR` (-1000000000) 或 `VK_SUBOPTIMAL_KHR` (1000001003) | 实现 `APP_CMD_TERM_WINDOW` 销毁流程 + swapchain 重建 | +| Java 多线程并发提交 graphicsQueue 导致 GPU 长时间后挂 | `VK_ERROR_DEVICE_LOST` (-4),且 `processImageNative` / `passDataToNative` 日志里 tid 不同 | 给所有 `vkQueueSubmit`/`vkQueuePresentKHR` 加全局 queue mutex | +| 驱动 bug / 温度导致 GPU hang | `VK_ERROR_DEVICE_LOST` (-4),单线程也出 | 捕获并尝试重建 device,或上报给机型厂商 | +| 资源累积泄漏 | `VK_ERROR_OUT_OF_DEVICE_MEMORY` (-2) 或 `VK_ERROR_TOO_MANY_OBJECTS` | 排查 `beginSingleTimeCommands`/`processWithVulkan` 路径 | + +--- + +## 六、日志样例(便于你确认打印是否正常) + +正常启动应该看到: +``` +========== DebugLog opened @ 2026-04-23 14:05:12 (pid=12345) ========== +[14:05:12.019][tid=12345] android_main start, pid=12345 tid=12345, logPath=/data/user/0/com.inewme.uvmirror/files/face_sdk_debug.log +[14:05:12.155][tid=12345] >> handle_cmd APP_CMD_START(10) tid=12345 +[14:05:12.155][tid=12345] << handle_cmd APP_CMD_START done +[14:05:12.210][tid=12345] >> handle_cmd APP_CMD_INIT_WINDOW(1) tid=12345 +[14:05:12.210][tid=12345] handle_cmd APP_CMD_INIT_WINDOW: calling initVulkan() +[14:05:12.210][tid=12345] FaceApp::initVulkan enter, call#1 _applicationInited=0 _faceAppInited=0 _secondfaceAppInited=0 +[14:05:13.420][tid=12345] FaceApp::initVulkan exit, call#1 _applicationInited=1 _faceAppInited=1 _secondfaceAppInited=1 +[14:05:13.420][tid=12345] handle_cmd APP_CMD_INIT_WINDOW: initVulkan() returned, isInited=1 +[14:05:13.421][tid=12345] << handle_cmd APP_CMD_INIT_WINDOW done +[14:05:14.005][tid=67890] processImageNative #1 tid=67890 w=480 h=480 +[14:05:14.008][tid=67891] passDataToNative #1 tid=67891 point_count=468 w=480 h=480 +[14:05:35.200][tid=12345] heartbeat: frame=600 exceptions_so_far=0 +``` + +旋转时如果触发异常应该看到: +``` +[14:06:10.112][tid=12345] >> handle_cmd APP_CMD_CONFIG_CHANGED(8) tid=12345 +[14:06:10.113][tid=12345] >> handle_cmd APP_CMD_TERM_WINDOW(2) tid=12345 +[14:06:10.113][tid=12345] handle_cmd APP_CMD_TERM_WINDOW: (no handler yet, ...) +[14:06:10.113][tid=12345] << handle_cmd APP_CMD_TERM_WINDOW done +[14:06:10.250][tid=12345] >> handle_cmd APP_CMD_INIT_WINDOW(1) tid=12345 +[14:06:10.250][tid=12345] FaceApp::initVulkan enter, call#2 _applicationInited=1 _faceAppInited=1 _secondfaceAppInited=0 +[14:06:10.250][tid=12345] FaceApp::initVulkan exit, call#2 _applicationInited=1 _faceAppInited=1 _secondfaceAppInited=1 +[14:06:10.280][tid=12345] drawFrame[1234] vkAcquireNextImageKHR -> -1000001004 (VK_ERROR_OUT_OF_DATE_KHR) currentFrame=0 +[14:06:10.280][tid=12345] !!! drawFrame std::exception (frame=1234 count=1): failed to acquire swap chain image! +``` + +**只要日志里能看到 `vkXxxKHR -> <数值> (<名字>)` 这一行,诊断就成立了。** + +--- + +## 七、文件清单(仅供参考,日常不用动) + +``` +app/src/main/cpp/ + DebugLog.h 新增 + DebugLog.cpp 新增 + main.cpp 改:日志初始化 / 心跳 / try-catch / cmd 日志 / JNI tid +vulkan/ + Application.cpp 改:drawFrame 4 处 VkResult 日志 + VkResultStr + FaceApp.cpp 改:initVulkan 入/出口日志 +CMakeLists.txt 改:加入 DebugLog.cpp 到 Android 构建 +``` diff --git a/app/build.gradle b/app/build.gradle index 76019ec..da81e90 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,7 +1,8 @@ plugins { //alias(libs.plugins.android.application) alias(libs.plugins.android.library) - id 'org.jetbrains.kotlin.android' + alias(libs.plugins.kotlin.android) + //id 'org.jetbrains.kotlin.android' } ext.vvl_version='1.4.321.0' @@ -30,6 +31,17 @@ android { debug { debuggable true jniDebuggable true + + externalNativeBuild { + cmake { + arguments "-DCMAKE_BUILD_TYPE=Debug" + cppFlags "-DDEBUG -O0 -g" + } + } + + ndk { + debugSymbolLevel 'FULL' // Debug 版本包含完整符号 + } } release { @@ -43,13 +55,13 @@ android { } // 添加 Kotlin 编译选项 - kotlinOptions { - jvmTarget = '17' // 与 Java 版本保持一致 - } +// kotlinOptions { +// jvmTarget = '17' // 与 Java 版本保持一致 +// } - kotlin { - jvmToolchain(17) - } +// kotlin { +// jvmToolchain(17) +// } buildFeatures { prefab true @@ -83,6 +95,9 @@ android { packagingOptions { pickFirst '**/*.jar' } + kotlinOptions { + jvmTarget = '17' + } } dependencies { @@ -90,6 +105,7 @@ dependencies { implementation libs.appcompat implementation libs.material implementation libs.games.activity + implementation libs.androidx.core.core.ktx testImplementation libs.junit androidTestImplementation libs.ext.junit androidTestImplementation libs.espresso.core diff --git a/app/src/main/assets/dummy.png b/app/src/main/assets/dummy.png new file mode 100644 index 0000000..eb5f4c9 Binary files /dev/null and b/app/src/main/assets/dummy.png differ diff --git a/app/src/main/assets/face_picture_3dmax.obj b/app/src/main/assets/face_picture_3dmax.obj index 3a3e208..a4c9eac 100644 --- a/app/src/main/assets/face_picture_3dmax.obj +++ b/app/src/main/assets/face_picture_3dmax.obj @@ -1,2270 +1,2279 @@ -# File produced by Open Asset Import Library (http://www.assimp.sf.net) -# (assimp v3.1.22885447) +# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware +# ļ:02.12.2025 18:33:58 -mtllib %E8%84%B8.mtl +mtllib 1202.mtl -# vertex positions -v 0.167637 0.509216 0.259111 -v 0.177059 0.514087 0.168544 -v 0.186469 0.461821 0.136133 -v 0.466962 0.757526 -0.063092 -v 0.467062 0.745795 -0.066963 -v 0.437903 0.739531 -0.063096 -v 0.389238 0.542616 -0.000696 -v 0.363110 0.550059 0.001772 -v 0.364803 0.569092 -0.002806 -v 0.438261 0.754670 -0.059357 -v 0.407977 0.749300 -0.046600 -v 0.414237 0.545312 -0.017224 -v 0.392943 0.558485 -0.011528 -v 0.395271 0.577667 -0.024868 -v 0.269263 0.355520 -0.004059 -v 0.331707 0.344147 -0.041662 -v 0.317584 0.290133 -0.020821 -v 0.464507 0.942523 0.014068 -v 0.413136 0.935902 0.020828 -v 0.414786 0.952424 0.056731 -v 0.276417 0.581113 0.017832 -v 0.261806 0.637181 0.020328 -v 0.321777 0.608335 -0.003644 -v 0.412971 0.759915 -0.044118 -v 0.388220 0.759748 -0.026723 -v 0.471632 0.416023 -0.075621 -v 0.471674 0.344787 -0.070144 -v 0.397564 0.343165 -0.063022 -v 0.396926 0.660358 -0.071706 -v 0.408236 0.650447 -0.098622 -v 0.408110 0.633988 -0.089813 -v 0.386594 0.864998 0.014582 -v 0.357618 0.842390 0.026772 -v 0.343730 0.864143 0.049587 -v 0.393994 0.765412 -0.025931 -v 0.375332 0.768900 -0.004101 -v 0.404155 0.776535 -0.014401 -v 0.399683 0.772161 -0.020518 -v 0.385800 0.774213 -0.003752 -v 0.365580 0.733497 -0.019201 -v 0.346488 0.751925 0.000480 -v 0.329733 0.554659 0.007817 -v 0.295052 0.553681 0.019481 -v 0.333021 0.812214 0.036132 -v 0.312055 0.779870 0.036284 -v 0.281683 0.782937 0.064271 -v 0.432675 0.853190 -0.005974 -v 0.465425 0.855243 -0.007018 -v 0.465605 0.829584 -0.036623 -v 0.369623 0.776764 0.014949 -v 0.366468 0.776998 0.019044 -v 0.376129 0.788711 0.004990 -v 0.307739 0.483887 0.004904 -v 0.290647 0.459548 -0.003086 -v 0.273893 0.470985 0.008940 -v 0.378989 0.471135 -0.005682 -v 0.373705 0.491947 0.000346 -v 0.391114 0.505672 0.006637 -v 0.375367 0.820565 0.008279 -v 0.272560 0.825464 0.122685 -v 0.249217 0.753891 0.098872 -v 0.364825 0.678127 -0.013256 -v 0.391294 0.720786 -0.033777 -v 0.404914 0.686707 -0.035283 -v 0.183914 0.397517 0.147351 -v 0.200012 0.417904 0.089272 -v 0.227123 0.380777 0.038453 -v 0.446084 0.610753 -0.133528 -v 0.444934 0.642024 -0.146969 -v 0.468261 0.642449 -0.150542 -v 0.312962 0.517404 0.012229 -v 0.309171 0.532791 0.011271 -v 0.333950 0.534484 0.003426 -v 0.380500 0.783211 0.000116 -v 0.389053 0.800812 -0.012551 -v 0.300167 0.671996 -0.000824 -v 0.247338 0.692416 0.053088 -v 0.424302 0.880677 0.000933 -v 0.465161 0.885233 -0.004399 -v 0.400760 0.839836 -0.002053 -v 0.393411 0.791262 -0.018024 -v 0.409027 0.815849 -0.025193 -v 0.436826 0.808074 -0.039855 -v 0.435490 0.825851 -0.034828 -v 0.338723 0.702052 -0.006057 -v 0.341347 0.642266 -0.014603 -v 0.370702 0.917123 0.045746 -v 0.439806 0.494623 -0.043856 -v 0.416326 0.492395 -0.009799 -v 0.420518 0.520790 -0.008720 -v 0.328646 0.480018 -0.002673 -v 0.350697 0.482228 -0.004417 -v 0.350749 0.457289 -0.013792 -v 0.265045 0.484804 0.025867 -v 0.288460 0.495851 0.024522 -v 0.295349 0.490217 0.014482 -v 0.429874 0.595196 -0.090683 -v 0.447844 0.584151 -0.110280 -v 0.446936 0.558968 -0.091927 -v 0.210046 0.350639 0.089907 -v 0.470406 0.490692 -0.062456 -v 0.470799 0.453844 -0.066575 -v 0.243788 0.570615 0.042531 -v 0.269432 0.545359 0.035658 -v 0.254709 0.534174 0.048883 -v 0.414711 0.447878 -0.057791 -v 0.438061 0.692458 -0.062061 -v 0.435785 0.688107 -0.063174 -v 0.399669 0.604901 -0.034009 -v 0.366612 0.592427 -0.013817 -v 0.415771 0.670406 -0.071497 -v 0.424025 0.666217 -0.098473 -v 0.416205 0.661774 -0.104022 -v 0.391473 0.516195 0.011460 -v 0.376213 0.516437 0.006785 -v 0.382657 0.528960 0.002935 -v 0.401542 0.626395 -0.048019 -v 0.395091 0.646812 -0.064670 -v 0.274494 0.852921 0.174736 -v 0.312135 0.888316 0.136456 -v 0.415640 0.587337 -0.051683 -v 0.309371 0.442669 -0.021019 -v 0.295842 0.423533 -0.033780 -v 0.259543 0.432048 -0.011239 -v 0.425650 0.618964 -0.116580 -v 0.336884 0.888674 0.073768 -v 0.355260 0.801228 0.018942 -v 0.326789 0.578480 0.004735 -v 0.248268 0.508241 0.054455 -v 0.267990 0.502299 0.042919 -v 0.244415 0.414169 0.000714 -v 0.444704 0.675975 -0.113192 -v 0.446753 0.681869 -0.088640 -v 0.451758 0.685477 -0.087966 -v 0.234498 0.450608 0.016593 -v 0.218553 0.437570 0.038421 -v 0.208014 0.472973 0.073311 -v 0.375785 0.776720 0.010899 -v 0.372368 0.776503 0.011537 -v 0.385963 0.780525 -0.000381 -v 0.201672 0.518117 0.102099 -v 0.179383 0.569978 0.181682 -v 0.207774 0.623503 0.094502 -v 0.226414 0.551594 0.065585 -v 0.448077 0.667742 -0.137418 -v 0.456504 0.680754 -0.123784 -v 0.468008 0.681980 -0.125534 -v 0.318636 0.733634 0.008760 -v 0.355088 0.518591 0.003539 -v 0.359970 0.533193 0.000930 -v 0.436164 0.713140 -0.058787 -v 0.416107 0.911703 0.004707 -v 0.375605 0.623699 -0.022220 -v 0.336964 0.775009 0.022872 -v 0.433438 0.682863 -0.062652 -v 0.223243 0.515192 0.074974 -v 0.248845 0.483523 0.033778 -v 0.318497 0.453708 -0.012975 -v 0.312400 0.832581 0.064374 -v 0.257379 0.462675 0.009683 -v 0.189163 0.626829 0.192041 -v 0.200390 0.567519 0.097145 -v 0.417593 0.769622 -0.038908 -v 0.440301 0.768545 -0.049466 -v 0.388524 0.659640 -0.021629 -v 0.396837 0.672077 -0.056104 -v 0.412712 0.683877 -0.050895 -v 0.390958 0.658634 -0.048649 -v 0.281116 0.712730 0.023496 -v 0.380133 0.771731 -0.003768 -v 0.305805 0.861097 0.098701 -v 0.343552 0.913182 0.106832 -v 0.376647 0.935536 0.076719 -v 0.285667 0.400636 -0.031016 -v 0.341269 0.402795 -0.057471 -v 0.446058 0.530738 -0.067788 -v 0.470164 0.525269 -0.078582 -v 0.217045 0.676636 0.107423 -v 0.346359 0.426904 -0.050094 -v 0.405508 0.411265 -0.071456 -v 0.398921 0.782913 -0.015209 -v 0.412381 0.799719 -0.029967 -v 0.182885 0.628468 0.290350 -v 0.466210 0.794147 -0.038816 -v 0.439509 0.791385 -0.035297 -v 0.466679 0.779918 -0.037969 -v 0.442872 0.777706 -0.034434 -v 0.333447 0.519696 0.005260 -v 0.404388 0.776784 -0.013236 -v 0.416790 0.786551 -0.026758 -v 0.391405 0.777034 0.000777 -v 0.241205 0.789624 0.154016 -v 0.243853 0.814007 0.221420 -v 0.216294 0.740293 0.186149 -v 0.217089 0.761115 0.261980 -v 0.404575 0.668411 -0.074284 -v 0.421778 0.775741 -0.025942 -v 0.469286 0.580724 -0.120274 -v 0.464492 0.917589 -0.002674 -v 0.442731 0.777014 -0.035416 -v 0.300234 0.513008 0.021014 -v 0.290367 0.527869 0.023187 -v 0.173273 0.567708 0.283550 -v 0.388818 0.279078 -0.051042 -v 0.406159 0.675856 -0.060571 -v 0.391087 0.776862 -0.000009 -v 0.349056 0.446298 -0.023987 -v 0.459069 0.688589 -0.087671 -v 0.394777 0.465143 -0.019429 -v 0.469319 0.554695 -0.098660 -v 0.279307 0.518180 0.033949 -v 0.291736 0.508164 0.028462 -v 0.283015 0.501210 0.037196 -v 0.425276 0.644499 -0.123855 -v 0.432243 0.663038 -0.124535 -v 0.429185 0.525863 -0.026617 -v 0.171185 0.447990 0.209113 -v 0.429873 0.544129 -0.050058 -v 0.430161 0.571064 -0.072173 -v 0.467944 0.694203 -0.069661 -v 0.448703 0.678837 -0.119920 -v 0.467651 0.713469 -0.061835 -v 0.467153 0.769587 -0.053605 -v 0.466621 0.778860 -0.038707 -v 0.414303 0.611683 -0.068351 -v 0.398939 0.514527 0.011440 -v 0.397886 0.523375 0.005801 -v 0.407413 0.515503 0.007273 -v 0.432992 0.667152 -0.111469 -v 0.401500 0.495720 0.000875 -v 0.375012 0.891405 0.027218 -v 0.422053 0.777060 -0.024827 -v 0.197696 0.693029 0.283490 -v 0.201744 0.685397 0.193015 -v 0.467991 0.668454 -0.139896 -v 0.226281 0.721344 0.120505 -v 0.416115 0.675117 -0.060686 -v 0.467854 0.689325 -0.089507 -v 0.421693 0.680261 -0.055051 -v 0.277975 0.449275 -0.008563 -v 0.407020 0.535158 -0.003377 -v 0.413398 0.561477 -0.035912 -v 0.227035 0.479965 0.046305 -v 0.774429 0.514900 0.250226 -v 0.771681 0.452676 0.200894 -v 0.756367 0.466614 0.128885 -v 0.496091 0.756368 -0.060273 -v 0.496797 0.740935 -0.064138 -v 0.551271 0.544589 -0.002790 -v 0.546982 0.560076 -0.013740 -v 0.575859 0.571707 -0.005724 -v 0.521688 0.763265 -0.045955 -v 0.526528 0.752564 -0.048661 -v 0.526295 0.546443 -0.018723 -v 0.525754 0.562796 -0.037634 -v 0.543960 0.579434 -0.027055 -v 0.532592 0.537003 -0.005141 -v 0.674936 0.357565 -0.009069 -v 0.691362 0.316941 0.024529 -v 0.626620 0.292346 -0.024958 -v 0.464360 0.957781 0.048444 -v 0.515053 0.953378 0.055198 -v 0.665506 0.585217 0.012683 -v 0.614804 0.581613 0.000972 -v 0.617711 0.611531 -0.007361 -v 0.541394 0.770189 -0.028504 -v 0.546980 0.764247 -0.029609 -v 0.538429 0.411760 -0.072540 -v 0.546163 0.344161 -0.064913 -v 0.540441 0.662453 -0.073698 -v 0.542043 0.648874 -0.066804 -v 0.529398 0.635585 -0.091532 -v 0.546265 0.866283 0.012332 -v 0.557217 0.892758 0.024830 -v 0.590357 0.865999 0.045972 -v 0.554620 0.776867 -0.007220 -v 0.559726 0.774641 -0.007757 -v 0.530285 0.779834 -0.016565 -v 0.543251 0.781245 -0.002875 -v 0.549372 0.779697 -0.006816 -v 0.589454 0.756647 -0.003601 -v 0.611371 0.558336 0.004030 -v 0.602867 0.815965 0.032056 -v 0.622165 0.835830 0.059723 -v 0.654923 0.787512 0.058647 -v 0.499023 0.853221 -0.006677 -v 0.497158 0.827108 -0.035790 -v 0.565996 0.782828 0.011263 -v 0.554482 0.788750 -0.003072 -v 0.559340 0.793209 0.001411 -v 0.634568 0.486852 0.000457 -v 0.647587 0.494153 0.009779 -v 0.670254 0.474385 0.003839 -v 0.563338 0.472372 -0.008293 -v 0.539664 0.497356 -0.001399 -v 0.549524 0.507170 0.004020 -v 0.558158 0.823352 0.005240 -v 0.532247 0.841117 -0.004216 -v 0.663025 0.829734 0.116698 -v 0.694579 0.793748 0.147332 -v 0.687852 0.758695 0.092601 -v 0.571877 0.680853 -0.015999 -v 0.548453 0.661791 -0.023770 -v 0.530889 0.688958 -0.036854 -v 0.759534 0.401869 0.139435 -v 0.733727 0.354285 0.082781 -v 0.716493 0.383690 0.032293 -v 0.490727 0.610810 -0.134245 -v 0.468629 0.608510 -0.142223 -v 0.628538 0.521553 0.007876 -v 0.608290 0.523562 0.001381 -v 0.607147 0.538778 -0.000486 -v 0.541012 0.795376 -0.020459 -v 0.545689 0.804677 -0.015149 -v 0.638355 0.675944 -0.005130 -v 0.656657 0.716614 0.018391 -v 0.691553 0.696974 0.047133 -v 0.506988 0.881973 -0.000281 -v 0.524677 0.817926 -0.027029 -v 0.521979 0.803092 -0.031775 -v 0.496046 0.809622 -0.040724 -v 0.466258 0.811689 -0.042687 -v 0.598939 0.705242 -0.009737 -v 0.596668 0.645433 -0.017900 -v 0.554798 0.936911 0.073758 -v 0.561426 0.918190 0.042854 -v 0.569966 0.736676 -0.022458 -v 0.544107 0.723374 -0.036184 -v 0.500682 0.495415 -0.044774 -v 0.511579 0.527284 -0.027817 -v 0.519627 0.522342 -0.009897 -v 0.614147 0.482406 -0.006729 -v 0.625089 0.455922 -0.017158 -v 0.592182 0.459287 -0.016982 -v 0.654400 0.499961 0.019656 -v 0.508352 0.595564 -0.091859 -v 0.508716 0.572168 -0.073406 -v 0.492163 0.559543 -0.092538 -v 0.528541 0.448306 -0.058852 -v 0.698586 0.575171 0.036415 -v 0.716042 0.556672 0.059275 -v 0.687697 0.538188 0.043216 -v 0.524827 0.493652 -0.011479 -v 0.547968 0.466370 -0.021716 -v 0.523698 0.685655 -0.052285 -v 0.499755 0.689081 -0.063914 -v 0.539131 0.606579 -0.036145 -v 0.562933 0.625961 -0.024805 -v 0.572574 0.594281 -0.016561 -v 0.520518 0.672167 -0.072981 -v 0.531698 0.670760 -0.075996 -v 0.519827 0.663032 -0.105511 -v 0.549504 0.518384 0.009077 -v 0.542813 0.525838 0.003548 -v 0.557697 0.531237 0.000535 -v 0.536449 0.628027 -0.050007 -v 0.523841 0.612486 -0.069959 -v 0.628140 0.863567 0.093837 -v 0.621284 0.890775 0.131471 -v 0.523196 0.588367 -0.053389 -v 0.635161 0.445156 -0.024795 -v 0.666783 0.452237 -0.013236 -v 0.686677 0.433771 -0.016200 -v 0.491840 0.643198 -0.147669 -v 0.511433 0.645635 -0.125391 -v 0.511534 0.620043 -0.117863 -v 0.555267 0.280019 -0.052966 -v 0.578912 0.805517 0.015171 -v 0.577356 0.552733 -0.001229 -v 0.694641 0.512810 0.048751 -v 0.695293 0.487465 0.028103 -v 0.679340 0.488849 0.020501 -v 0.701930 0.415974 -0.004755 -v 0.660374 0.401962 -0.035187 -v 0.649680 0.424499 -0.037621 -v 0.491245 0.676466 -0.113661 -v 0.486646 0.678947 -0.120525 -v 0.484033 0.686610 -0.088434 -v 0.711460 0.452884 0.010695 -v 0.717075 0.483771 0.040020 -v 0.736927 0.477054 0.066432 -v 0.559391 0.782499 0.007342 -v 0.543872 0.781419 -0.002219 -v 0.548502 0.785248 -0.003532 -v 0.727034 0.440066 0.032667 -v 0.741524 0.522489 0.095775 -v 0.741905 0.572089 0.090663 -v 0.761997 0.575336 0.173763 -v 0.732763 0.628826 0.087224 -v 0.487516 0.668275 -0.137893 -v 0.490404 0.584562 -0.111043 -v 0.617953 0.737722 0.004215 -v 0.564298 0.519489 0.003984 -v 0.581251 0.536502 -0.002325 -v 0.499312 0.714242 -0.059752 -v 0.515063 0.912805 0.003454 -v 0.598402 0.779391 0.018368 -v 0.489207 0.682534 -0.089080 -v 0.566936 0.493579 -0.002578 -v 0.720282 0.519614 0.068603 -v 0.653324 0.462467 -0.007751 -v 0.576573 0.844380 0.023463 -v 0.562327 0.782473 0.007880 -v 0.752027 0.631368 0.184366 -v 0.516662 0.773023 -0.040641 -v 0.539965 0.674074 -0.058138 -v 0.530254 0.677629 -0.062417 -v 0.535267 0.775884 -0.022808 -v 0.623884 0.783335 0.031408 -v 0.596037 0.890875 0.069967 -v 0.612180 0.345652 -0.044831 -v 0.493761 0.530929 -0.068508 -v 0.677631 0.641073 0.014930 -v 0.535715 0.786296 -0.017548 -v 0.598169 0.428015 -0.052769 -v 0.603997 0.403796 -0.060270 -v 0.517384 0.789593 -0.028365 -v 0.758205 0.634177 0.281847 -v 0.769017 0.573566 0.274906 -v 0.494281 0.792228 -0.036328 -v 0.585357 0.522007 0.000327 -v 0.530403 0.780224 -0.015483 -v 0.512999 0.779220 -0.026527 -v 0.659748 0.856197 0.168539 -v 0.721082 0.744657 0.178675 -v 0.691162 0.817946 0.214083 -v 0.528628 0.652453 -0.100278 -v 0.512935 0.778662 -0.027530 -v 0.568162 0.783238 0.015095 -v 0.517078 0.937305 0.019438 -v 0.493856 0.769880 -0.050285 -v 0.687116 0.465672 0.004385 -v 0.632659 0.537105 0.006804 -v 0.652009 0.531854 0.018197 -v 0.646619 0.557516 0.014800 -v 0.764866 0.519196 0.161034 -v 0.472010 0.277615 -0.058845 -v 0.594785 0.447575 -0.027030 -v 0.476708 0.688327 -0.087897 -v 0.659514 0.505195 0.031930 -v 0.662718 0.522682 0.028613 -v 0.674817 0.506744 0.037620 -v 0.509393 0.544815 -0.051129 -v 0.743598 0.421528 0.082285 -v 0.588915 0.915251 0.102937 -v 0.497553 0.692998 -0.062792 -v 0.503905 0.663941 -0.125677 -v 0.541340 0.516832 0.009196 -v 0.503107 0.668580 -0.112550 -v 0.532674 0.517356 0.005395 -v 0.479088 0.680734 -0.124141 -v 0.737325 0.690292 0.185226 -v 0.741749 0.697707 0.275626 -v 0.512812 0.667423 -0.099813 -v 0.722859 0.681360 0.100182 -v 0.711891 0.725651 0.113648 -v 0.519854 0.676829 -0.062316 -v 0.514679 0.681341 -0.056181 -v 0.673028 0.550008 0.030292 -v 0.502448 0.683405 -0.063431 -v 0.719571 0.764732 0.254569 -v 0.651012 0.512914 0.023524 -v 0.252945 0.313983 0.030323 -v 0.590631 0.483911 -0.007818 -v 0.546156 0.660545 -0.050788 -v 0.491020 0.779768 -0.035318 -v 0.491566 0.778718 -0.036259 -v 0.641894 0.517804 0.016409 +# +# object default +# -# UV coordinates -vt 0.014748 0.466787 -vt 0.104934 0.471580 -vt 0.129153 0.531285 -vt 0.500475 0.245776 -vt 0.500475 0.256974 -vt 0.474546 0.262771 -vt 0.385896 0.481781 -vt 0.364639 0.466905 -vt 0.369323 0.447075 -vt 0.475887 0.247942 -vt 0.442330 0.255529 -vt 0.411962 0.484552 -vt 0.393170 0.463888 -vt 0.400310 0.444198 -vt 0.278909 0.668004 -vt 0.350938 0.692272 -vt 0.323268 0.743243 -vt 0.500475 0.033783 -vt 0.444117 0.039719 -vt 0.431205 0.004769 -vt 0.286575 0.418384 -vt 0.281441 0.360883 -vt 0.336649 0.397144 -vt 0.447901 0.244089 -vt 0.418722 0.242438 -vt 0.501349 0.628534 -vt 0.500915 0.703969 -vt 0.422721 0.701893 -vt 0.436694 0.359889 -vt 0.454591 0.373411 -vt 0.447441 0.388042 -vt 0.412655 0.115374 -vt 0.377587 0.139673 -vt 0.356971 0.111754 -vt 0.424488 0.235796 -vt 0.399025 0.225675 -vt 0.429142 0.217558 -vt 0.427757 0.225709 -vt 0.408451 0.218320 -vt 0.391991 0.267052 -vt 0.370186 0.243241 -vt 0.334011 0.453865 -vt 0.299711 0.448771 -vt 0.348288 0.172633 -vt 0.327671 0.209060 -vt 0.288096 0.201957 -vt 0.464684 0.124419 -vt 0.500475 0.122259 -vt 0.500475 0.158416 -vt 0.388178 0.206032 -vt 0.384210 0.205520 -vt 0.400874 0.194941 -vt 0.324005 0.533235 -vt 0.308644 0.559620 -vt 0.289308 0.544234 -vt 0.390087 0.554371 -vt 0.385533 0.533501 -vt 0.396104 0.520245 -vt 0.402287 0.161184 -vt 0.241904 0.147524 -vt 0.235555 0.227391 -vt 0.383341 0.329336 -vt 0.416481 0.282874 -vt 0.423817 0.322203 -vt 0.109402 0.600999 -vt 0.169932 0.584901 -vt 0.222451 0.631473 -vt 0.486042 0.411521 -vt 0.492426 0.385414 -vt 0.501163 0.385769 -vt 0.313617 0.485267 -vt 0.313534 0.470414 -vt 0.337224 0.473973 -vt 0.406583 0.200645 -vt 0.422754 0.183171 -vt 0.323950 0.328499 -vt 0.258043 0.299347 -vt 0.456866 0.098245 -vt 0.500475 0.093433 -vt 0.431919 0.141062 -vt 0.428039 0.192661 -vt 0.447002 0.169813 -vt 0.474366 0.178985 -vt 0.473718 0.161484 -vt 0.359261 0.299131 -vt 0.358278 0.363779 -vt 0.390141 0.056784 -vt 0.460448 0.537767 -vt 0.421534 0.533785 -vt 0.419314 0.509122 -vt 0.346094 0.542274 -vt 0.366103 0.542986 -vt 0.366205 0.568558 -vt 0.273059 0.523807 -vt 0.294808 0.510594 -vt 0.306697 0.521151 -vt 0.458235 0.431425 -vt 0.481955 0.439412 -vt 0.478141 0.465395 -vt 0.168677 0.659081 -vt 0.500591 0.539316 -vt 0.500491 0.582605 -vt 0.248198 0.425762 -vt 0.269911 0.454234 -vt 0.251472 0.465000 -vt 0.443626 0.593752 -vt 0.465486 0.309674 -vt 0.459597 0.317904 -vt 0.405461 0.411624 -vt 0.374634 0.420937 -vt 0.447227 0.342111 -vt 0.463839 0.354089 -vt 0.462076 0.364363 -vt 0.385111 0.511119 -vt 0.369585 0.504331 -vt 0.378598 0.493665 -vt 0.416981 0.394116 -vt 0.430983 0.371400 -vt 0.198689 0.107233 -vt 0.265905 0.072699 -vt 0.425455 0.435579 -vt 0.330868 0.582828 -vt 0.322371 0.607546 -vt 0.282431 0.589691 -vt 0.469086 0.404367 -vt 0.337419 0.082770 -vt 0.376718 0.181739 -vt 0.335210 0.429413 -vt 0.243566 0.492177 -vt 0.266735 0.498919 -vt 0.264029 0.603750 -vt 0.486137 0.350975 -vt 0.477589 0.332786 -vt 0.482783 0.327343 -vt 0.250859 0.563328 -vt 0.224407 0.571249 -vt 0.195718 0.527819 -vt 0.395185 0.207459 -vt 0.391993 0.206904 -vt 0.410565 0.205301 -vt 0.175931 0.475196 -vt 0.100877 0.411668 -vt 0.195366 0.365969 -vt 0.221389 0.444805 -vt 0.489422 0.365045 -vt 0.496259 0.351216 -vt 0.501274 0.350627 -vt 0.340687 0.263165 -vt 0.350900 0.494925 -vt 0.359648 0.482356 -vt 0.468576 0.290843 -vt 0.451203 0.066169 -vt 0.385660 0.385594 -vt 0.356161 0.211319 -vt 0.455847 0.324178 -vt 0.211310 0.483012 -vt 0.254428 0.523702 -vt 0.336564 0.569313 -vt 0.318184 0.146493 -vt 0.273547 0.552684 -vt 0.101225 0.349403 -vt 0.184670 0.423460 -vt 0.450757 0.231820 -vt 0.475698 0.231457 -vt 0.401015 0.354387 -vt 0.430078 0.345959 -vt 0.436737 0.327080 -vt 0.421217 0.358002 -vt 0.302122 0.281828 -vt 0.403205 0.221895 -vt 0.291162 0.111752 -vt 0.317897 0.046852 -vt 0.372257 0.026357 -vt 0.311744 0.628072 -vt 0.371109 0.635725 -vt 0.473759 0.497499 -vt 0.500819 0.500683 -vt 0.197529 0.308201 -vt 0.374599 0.613509 -vt 0.436566 0.632735 -vt 0.429912 0.202425 -vt 0.449578 0.186100 -vt 0.005252 0.334839 -vt 0.500475 0.195429 -vt 0.474906 0.196835 -vt 0.500475 0.211488 -vt 0.476825 0.210742 -vt 0.331852 0.487753 -vt 0.432791 0.210151 -vt 0.450827 0.199959 -vt 0.413531 0.211033 -vt 0.189496 0.182364 -vt 0.129840 0.142855 -vt 0.138361 0.229038 -vt 0.068510 0.194505 -vt 0.441795 0.351436 -vt 0.449387 0.217063 -vt 0.500891 0.440000 -vt 0.500475 0.061929 -vt 0.474223 0.215706 -vt 0.300820 0.487599 -vt 0.292327 0.472168 -vt 0.000500 0.401518 -vt 0.406775 0.770708 -vt 0.436323 0.340481 -vt 0.412328 0.212149 -vt 0.368636 0.581564 -vt 0.491248 0.321418 -vt 0.409730 0.562504 -vt 0.500475 0.467856 -vt 0.279064 0.481915 -vt 0.291883 0.491773 -vt 0.282680 0.499379 -vt 0.473756 0.383152 -vt 0.479071 0.366818 -vt 0.433374 0.505560 -vt 0.054258 0.537778 -vt 0.445617 0.485148 -vt 0.451472 0.454152 -vt 0.500475 0.301517 -vt 0.491598 0.352132 -vt 0.500475 0.287141 -vt 0.500475 0.230853 -vt 0.500475 0.212722 -vt 0.434052 0.412663 -vt 0.394914 0.512649 -vt 0.392201 0.503938 -vt 0.401986 0.511717 -vt 0.475016 0.357189 -vt 0.405695 0.529580 -vt 0.401942 0.085654 -vt 0.454112 0.210188 -vt 0.027333 0.264836 -vt 0.114753 0.286299 -vt 0.501063 0.365109 -vt 0.198653 0.258626 -vt 0.442359 0.335394 -vt 0.500752 0.320820 -vt 0.443716 0.327548 -vt 0.298086 0.571718 -vt 0.402287 0.495645 -vt 0.420329 0.465777 -vt 0.228687 0.525919 -vt 0.984826 0.469223 -vt 0.945871 0.541160 -vt 0.871961 0.533767 -vt 0.526511 0.247195 -vt 0.527774 0.262250 -vt 0.615264 0.482364 -vt 0.607801 0.464761 -vt 0.632425 0.447451 -vt 0.554501 0.242599 -vt 0.559589 0.254160 -vt 0.589357 0.485122 -vt 0.580458 0.466194 -vt 0.600541 0.444737 -vt 0.598085 0.495922 -vt 0.722617 0.670642 -vt 0.760157 0.709118 -vt 0.677097 0.744532 -vt 0.500475 0.000500 -vt 0.571160 0.005422 -vt 0.716388 0.419391 -vt 0.667632 0.430103 -vt 0.665152 0.398244 -vt 0.578158 0.233738 -vt 0.583463 0.240696 -vt 0.567042 0.633753 -vt 0.579269 0.702289 -vt 0.564535 0.360645 -vt 0.570009 0.372195 -vt 0.553907 0.388758 -vt 0.590565 0.116777 -vt 0.601439 0.087310 -vt 0.646354 0.114030 -vt 0.598364 0.219754 -vt 0.602606 0.223487 -vt 0.572763 0.215706 -vt 0.589056 0.209677 -vt 0.593596 0.215882 -vt 0.631811 0.242777 -vt 0.667661 0.454096 -vt 0.654963 0.173554 -vt 0.684175 0.148238 -vt 0.714197 0.203462 -vt 0.537888 0.125226 -vt 0.529385 0.161647 -vt 0.614035 0.203887 -vt 0.595827 0.198568 -vt 0.601774 0.193931 -vt 0.677120 0.535062 -vt 0.693769 0.523201 -vt 0.713712 0.545583 -vt 0.610951 0.555818 -vt 0.594315 0.530277 -vt 0.603399 0.521473 -vt 0.600076 0.161646 -vt 0.571005 0.142099 -vt 0.759741 0.149370 -vt 0.811548 0.184574 -vt 0.766164 0.229155 -vt 0.617734 0.330119 -vt 0.599910 0.354997 -vt 0.577109 0.322430 -vt 0.890490 0.604529 -vt 0.830993 0.662451 -vt 0.778690 0.634553 -vt 0.515136 0.412133 -vt 0.500868 0.411905 -vt 0.687605 0.485532 -vt 0.669722 0.487763 -vt 0.664013 0.473613 -vt 0.574849 0.191498 -vt 0.580436 0.182423 -vt 0.678537 0.329555 -vt 0.700316 0.283688 -vt 0.744234 0.301328 -vt 0.545924 0.098274 -vt 0.556393 0.170103 -vt 0.553906 0.185002 -vt 0.528410 0.178734 -vt 0.500475 0.177185 -vt 0.643044 0.300203 -vt 0.643046 0.364624 -vt 0.630294 0.027961 -vt 0.613165 0.058969 -vt 0.609672 0.267390 -vt 0.584863 0.283151 -vt 0.540182 0.537843 -vt 0.567810 0.505464 -vt 0.581465 0.509189 -vt 0.655767 0.543781 -vt 0.665735 0.571231 -vt 0.635442 0.569683 -vt 0.705883 0.512359 -vt 0.543025 0.432244 -vt 0.549714 0.454411 -vt 0.523264 0.465620 -vt 0.558701 0.594957 -vt 0.754337 0.427149 -vt 0.780701 0.446085 -vt 0.750417 0.466682 -vt 0.578841 0.534275 -vt 0.591714 0.563851 -vt 0.564668 0.327765 -vt 0.541763 0.317417 -vt 0.595608 0.412255 -vt 0.615645 0.386394 -vt 0.626446 0.422268 -vt 0.554169 0.341946 -vt 0.559144 0.351439 -vt 0.539261 0.364828 -vt 0.615660 0.511460 -vt 0.608607 0.503893 -vt 0.622065 0.494257 -vt 0.584113 0.394824 -vt 0.567186 0.413840 -vt 0.710987 0.114136 -vt 0.735823 0.074789 -vt 0.575632 0.436432 -vt 0.672414 0.584141 -vt 0.705335 0.573309 -vt 0.722029 0.592733 -vt 0.509831 0.385118 -vt 0.527673 0.383548 -vt 0.532296 0.404776 -vt 0.594544 0.771259 -vt 0.625149 0.181525 -vt 0.636491 0.467378 -vt 0.758285 0.493254 -vt 0.748396 0.525335 -vt 0.730244 0.525025 -vt 0.739818 0.606879 -vt 0.692519 0.630375 -vt 0.681863 0.610094 -vt 0.515950 0.350582 -vt 0.510199 0.352066 -vt 0.518821 0.326895 -vt 0.752936 0.566726 -vt 0.773717 0.528171 -vt 0.806594 0.530420 -vt 0.606810 0.205423 -vt 0.588937 0.209414 -vt 0.591409 0.203899 -vt 0.779002 0.574713 -vt 0.826387 0.477601 -vt 0.817576 0.425886 -vt 0.899768 0.413847 -vt 0.805939 0.367828 -vt 0.512333 0.365103 -vt 0.519463 0.439592 -vt 0.661265 0.263945 -vt 0.630669 0.504399 -vt 0.641800 0.482222 -vt 0.533289 0.290519 -vt 0.552369 0.066830 -vt 0.645833 0.211548 -vt 0.524467 0.332496 -vt 0.614063 0.534670 -vt 0.790927 0.484860 -vt 0.694092 0.561281 -vt 0.625555 0.141459 -vt 0.609559 0.204904 -vt 0.899958 0.352363 -vt 0.551475 0.230258 -vt 0.570907 0.346894 -vt 0.564471 0.341239 -vt 0.574683 0.223979 -vt 0.674628 0.210719 -vt 0.665228 0.084689 -vt 0.651150 0.693855 -vt 0.527387 0.497862 -vt 0.720709 0.362790 -vt 0.572861 0.201771 -vt 0.628891 0.615017 -vt 0.633946 0.637989 -vt 0.552023 0.199114 -vt 0.994931 0.336941 -vt 0.999500 0.403755 -vt 0.528059 0.197096 -vt 0.649426 0.495159 -vt 0.569845 0.209289 -vt 0.549057 0.209871 -vt 0.802303 0.109313 -vt 0.862368 0.231571 -vt 0.870309 0.144870 -vt 0.546708 0.373668 -vt 0.552875 0.215823 -vt 0.617334 0.203407 -vt 0.558817 0.040156 -vt 0.526725 0.231156 -vt 0.729531 0.554698 -vt 0.688332 0.470520 -vt 0.709709 0.473001 -vt 0.702337 0.449681 -vt 0.895947 0.473912 -vt 0.500475 0.772406 -vt 0.633972 0.583170 -vt 0.510330 0.321385 -vt 0.718320 0.500433 -vt 0.722271 0.482505 -vt 0.734899 0.499657 -vt 0.555487 0.485755 -vt 0.831282 0.588142 -vt 0.684323 0.048627 -vt 0.535740 0.309624 -vt 0.522513 0.367316 -vt 0.605212 0.512782 -vt 0.526170 0.357463 -vt 0.598059 0.511984 -vt 0.505875 0.351259 -vt 0.885976 0.288643 -vt 0.973384 0.267300 -vt 0.538028 0.355038 -vt 0.803994 0.310800 -vt 0.802899 0.261316 -vt 0.558137 0.335244 -vt 0.557323 0.328294 -vt 0.732342 0.454898 -vt 0.545841 0.324005 -vt 0.932188 0.197194 -vt 0.709931 0.491822 -vt 0.239924 0.706618 -vt 0.634289 0.544507 -vt 0.579780 0.358957 -vt 0.525582 0.209703 -vt 0.528196 0.215213 -vt 0.700739 0.487493 +v 0.1676 0.5092 0.2591 +v 0.1771 0.5141 0.1685 +v 0.1865 0.4618 0.1361 +v 0.4670 0.7575 -0.0631 +v 0.4671 0.7458 -0.0670 +v 0.4379 0.7395 -0.0631 +v 0.3892 0.5426 -0.0007 +v 0.3631 0.5501 0.0018 +v 0.3648 0.5691 -0.0028 +v 0.4383 0.7547 -0.0594 +v 0.4080 0.7493 -0.0466 +v 0.4142 0.5453 -0.0172 +v 0.3929 0.5585 -0.0115 +v 0.3953 0.5777 -0.0249 +v 0.2693 0.3555 -0.0041 +v 0.3317 0.3441 -0.0417 +v 0.3176 0.2901 -0.0208 +v 0.4645 0.9425 0.0141 +v 0.4131 0.9359 0.0208 +v 0.4148 0.9524 0.0567 +v 0.2764 0.5811 0.0178 +v 0.2618 0.6372 0.0203 +v 0.3218 0.6083 -0.0036 +v 0.4130 0.7599 -0.0441 +v 0.3882 0.7597 -0.0267 +v 0.4716 0.4160 -0.0756 +v 0.4717 0.3448 -0.0701 +v 0.3976 0.3432 -0.0630 +v 0.3969 0.6604 -0.0717 +v 0.4082 0.6504 -0.0986 +v 0.4081 0.6340 -0.0898 +v 0.3866 0.8650 0.0146 +v 0.3576 0.8424 0.0268 +v 0.3437 0.8641 0.0496 +v 0.3940 0.7654 -0.0259 +v 0.3753 0.7689 -0.0041 +v 0.4042 0.7765 -0.0144 +v 0.3997 0.7722 -0.0205 +v 0.3858 0.7742 -0.0038 +v 0.3656 0.7335 -0.0192 +v 0.3465 0.7519 0.0005 +v 0.3297 0.5547 0.0078 +v 0.2951 0.5537 0.0195 +v 0.3330 0.8122 0.0361 +v 0.3121 0.7799 0.0363 +v 0.2817 0.7829 0.0643 +v 0.4327 0.8532 -0.0060 +v 0.4654 0.8552 -0.0070 +v 0.4656 0.8296 -0.0366 +v 0.3696 0.7768 0.0149 +v 0.3665 0.7770 0.0190 +v 0.3761 0.7887 0.0050 +v 0.3077 0.4839 0.0049 +v 0.2906 0.4595 -0.0031 +v 0.2739 0.4710 0.0089 +v 0.3790 0.4711 -0.0057 +v 0.3737 0.4919 0.0003 +v 0.3911 0.5057 0.0066 +v 0.3754 0.8206 0.0083 +v 0.2726 0.8255 0.1227 +v 0.2492 0.7539 0.0989 +v 0.3648 0.6781 -0.0133 +v 0.3913 0.7208 -0.0338 +v 0.4049 0.6867 -0.0353 +v 0.1839 0.3975 0.1474 +v 0.2000 0.4179 0.0893 +v 0.2271 0.3808 0.0385 +v 0.4461 0.6108 -0.1335 +v 0.4449 0.6420 -0.1470 +v 0.4683 0.6424 -0.1505 +v 0.3130 0.5174 0.0122 +v 0.3092 0.5328 0.0113 +v 0.3340 0.5345 0.0034 +v 0.3805 0.7832 0.0001 +v 0.3891 0.8008 -0.0126 +v 0.3002 0.6720 -0.0008 +v 0.2473 0.6924 0.0531 +v 0.4243 0.8807 0.0009 +v 0.4652 0.8852 -0.0044 +v 0.4008 0.8398 -0.0021 +v 0.3934 0.7913 -0.0180 +v 0.4090 0.8158 -0.0252 +v 0.4368 0.8081 -0.0399 +v 0.4355 0.8259 -0.0348 +v 0.3387 0.7021 -0.0061 +v 0.3413 0.6423 -0.0146 +v 0.3707 0.9171 0.0457 +v 0.4398 0.4946 -0.0439 +v 0.4163 0.4924 -0.0098 +v 0.4205 0.5208 -0.0087 +v 0.3286 0.4800 -0.0027 +v 0.3507 0.4822 -0.0044 +v 0.3507 0.4573 -0.0138 +v 0.2650 0.4848 0.0259 +v 0.2885 0.4959 0.0245 +v 0.2953 0.4902 0.0145 +v 0.4299 0.5952 -0.0907 +v 0.4478 0.5842 -0.1103 +v 0.4469 0.5590 -0.0919 +v 0.2100 0.3506 0.0899 +v 0.4704 0.4907 -0.0625 +v 0.4708 0.4538 -0.0666 +v 0.2438 0.5706 0.0425 +v 0.2694 0.5454 0.0357 +v 0.2547 0.5342 0.0489 +v 0.4147 0.4479 -0.0578 +v 0.4381 0.6925 -0.0621 +v 0.4358 0.6881 -0.0632 +v 0.3997 0.6049 -0.0340 +v 0.3666 0.5924 -0.0138 +v 0.4158 0.6704 -0.0715 +v 0.4240 0.6662 -0.0985 +v 0.4162 0.6618 -0.1040 +v 0.3915 0.5162 0.0115 +v 0.3762 0.5164 0.0068 +v 0.3827 0.5290 0.0029 +v 0.4015 0.6264 -0.0480 +v 0.3951 0.6468 -0.0647 +v 0.2745 0.8529 0.1747 +v 0.3121 0.8883 0.1365 +v 0.4156 0.5873 -0.0517 +v 0.3094 0.4427 -0.0210 +v 0.2958 0.4235 -0.0338 +v 0.2595 0.4320 -0.0112 +v 0.4257 0.6190 -0.1166 +v 0.3369 0.8887 0.0738 +v 0.3553 0.8012 0.0189 +v 0.3268 0.5785 0.0047 +v 0.2483 0.5082 0.0545 +v 0.2680 0.5023 0.0429 +v 0.2444 0.4142 0.0007 +v 0.4447 0.6760 -0.1132 +v 0.4468 0.6819 -0.0886 +v 0.4518 0.6855 -0.0880 +v 0.2345 0.4506 0.0166 +v 0.2186 0.4376 0.0384 +v 0.2080 0.4730 0.0733 +v 0.3758 0.7767 0.0109 +v 0.3724 0.7765 0.0115 +v 0.3860 0.7805 -0.0004 +v 0.2017 0.5181 0.1021 +v 0.1794 0.5700 0.1817 +v 0.2078 0.6235 0.0945 +v 0.2264 0.5516 0.0656 +v 0.4481 0.6677 -0.1374 +v 0.4565 0.6808 -0.1238 +v 0.4680 0.6820 -0.1255 +v 0.3186 0.7336 0.0088 +v 0.3551 0.5186 0.0035 +v 0.3600 0.5332 0.0009 +v 0.4362 0.7131 -0.0588 +v 0.4161 0.9117 0.0047 +v 0.3756 0.6237 -0.0222 +v 0.3370 0.7750 0.0229 +v 0.4334 0.6829 -0.0627 +v 0.2232 0.5152 0.0750 +v 0.2488 0.4835 0.0338 +v 0.3185 0.4537 -0.0130 +v 0.3124 0.8326 0.0644 +v 0.2574 0.4627 0.0097 +v 0.1892 0.6268 0.1920 +v 0.2004 0.5675 0.0971 +v 0.4176 0.7696 -0.0389 +v 0.4403 0.7685 -0.0495 +v 0.3885 0.6596 -0.0216 +v 0.3968 0.6721 -0.0561 +v 0.4127 0.6839 -0.0509 +v 0.3910 0.6586 -0.0486 +v 0.2811 0.7127 0.0235 +v 0.3801 0.7717 -0.0038 +v 0.3058 0.8611 0.0987 +v 0.3436 0.9132 0.1068 +v 0.3766 0.9355 0.0767 +v 0.2857 0.4006 -0.0310 +v 0.3413 0.4028 -0.0575 +v 0.4461 0.5307 -0.0678 +v 0.4702 0.5253 -0.0786 +v 0.2170 0.6766 0.1074 +v 0.3464 0.4269 -0.0501 +v 0.4055 0.4113 -0.0715 +v 0.3989 0.7829 -0.0152 +v 0.4124 0.7997 -0.0300 +v 0.1829 0.6285 0.2903 +v 0.4662 0.7941 -0.0388 +v 0.4395 0.7914 -0.0353 +v 0.4667 0.7799 -0.0380 +v 0.4429 0.7777 -0.0344 +v 0.3334 0.5197 0.0053 +v 0.4044 0.7768 -0.0132 +v 0.4168 0.7866 -0.0268 +v 0.3914 0.7770 0.0008 +v 0.2412 0.7896 0.1540 +v 0.2439 0.8140 0.2214 +v 0.2163 0.7403 0.1861 +v 0.2171 0.7611 0.2620 +v 0.4046 0.6684 -0.0743 +v 0.4218 0.7757 -0.0259 +v 0.4693 0.5807 -0.1203 +v 0.4645 0.9176 -0.0027 +v 0.4427 0.7770 -0.0354 +v 0.3002 0.5130 0.0210 +v 0.2904 0.5279 0.0232 +v 0.1733 0.5677 0.2835 +v 0.3888 0.2791 -0.0510 +v 0.4062 0.6759 -0.0606 +v 0.3911 0.7769 -0.0000 +v 0.3491 0.4463 -0.0240 +v 0.4591 0.6886 -0.0877 +v 0.3948 0.4651 -0.0194 +v 0.4693 0.5547 -0.0987 +v 0.2793 0.5182 0.0339 +v 0.2917 0.5082 0.0285 +v 0.2830 0.5012 0.0372 +v 0.4253 0.6445 -0.1239 +v 0.4322 0.6630 -0.1245 +v 0.4292 0.5259 -0.0266 +v 0.1712 0.4480 0.2091 +v 0.4299 0.5441 -0.0501 +v 0.4302 0.5711 -0.0722 +v 0.4679 0.6942 -0.0697 +v 0.4487 0.6788 -0.1199 +v 0.4677 0.7135 -0.0618 +v 0.4672 0.7696 -0.0536 +v 0.4666 0.7789 -0.0387 +v 0.4143 0.6117 -0.0684 +v 0.3989 0.5145 0.0114 +v 0.3979 0.5234 0.0058 +v 0.4074 0.5155 0.0073 +v 0.4330 0.6672 -0.1115 +v 0.4015 0.4957 0.0009 +v 0.3750 0.8914 0.0272 +v 0.4221 0.7771 -0.0248 +v 0.1977 0.6930 0.2835 +v 0.2017 0.6854 0.1930 +v 0.4680 0.6685 -0.1399 +v 0.2263 0.7213 0.1205 +v 0.4161 0.6751 -0.0607 +v 0.4679 0.6893 -0.0895 +v 0.4217 0.6803 -0.0551 +v 0.2780 0.4493 -0.0086 +v 0.4070 0.5352 -0.0034 +v 0.4134 0.5615 -0.0359 +v 0.2270 0.4800 0.0463 +v 0.7744 0.5149 0.2502 +v 0.7717 0.4527 0.2009 +v 0.7564 0.4666 0.1289 +v 0.4961 0.7564 -0.0603 +v 0.4968 0.7409 -0.0641 +v 0.5513 0.5446 -0.0028 +v 0.5470 0.5601 -0.0137 +v 0.5759 0.5717 -0.0057 +v 0.5217 0.7633 -0.0460 +v 0.5265 0.7526 -0.0487 +v 0.5263 0.5464 -0.0187 +v 0.5258 0.5628 -0.0376 +v 0.5440 0.5794 -0.0271 +v 0.5326 0.5370 -0.0051 +v 0.6749 0.3576 -0.0091 +v 0.6914 0.3169 0.0245 +v 0.6266 0.2923 -0.0250 +v 0.4644 0.9578 0.0484 +v 0.5151 0.9534 0.0552 +v 0.6655 0.5852 0.0127 +v 0.6148 0.5816 0.0010 +v 0.6177 0.6115 -0.0074 +v 0.5414 0.7702 -0.0285 +v 0.5470 0.7642 -0.0296 +v 0.5384 0.4118 -0.0725 +v 0.5462 0.3442 -0.0649 +v 0.5404 0.6625 -0.0737 +v 0.5420 0.6489 -0.0668 +v 0.5294 0.6356 -0.0915 +v 0.5463 0.8663 0.0123 +v 0.5572 0.8928 0.0248 +v 0.5904 0.8660 0.0460 +v 0.5546 0.7769 -0.0072 +v 0.5597 0.7746 -0.0078 +v 0.5303 0.7798 -0.0166 +v 0.5433 0.7812 -0.0029 +v 0.5494 0.7797 -0.0068 +v 0.5895 0.7566 -0.0036 +v 0.6114 0.5583 0.0040 +v 0.6029 0.8160 0.0321 +v 0.6222 0.8358 0.0597 +v 0.6549 0.7875 0.0586 +v 0.4990 0.8532 -0.0067 +v 0.4972 0.8271 -0.0358 +v 0.5660 0.7828 0.0113 +v 0.5545 0.7887 -0.0031 +v 0.5593 0.7932 0.0014 +v 0.6346 0.4869 0.0005 +v 0.6476 0.4942 0.0098 +v 0.6703 0.4744 0.0038 +v 0.5633 0.4724 -0.0083 +v 0.5397 0.4974 -0.0014 +v 0.5495 0.5072 0.0040 +v 0.5582 0.8234 0.0052 +v 0.5322 0.8411 -0.0042 +v 0.6630 0.8297 0.1167 +v 0.6946 0.7937 0.1473 +v 0.6879 0.7587 0.0926 +v 0.5719 0.6809 -0.0160 +v 0.5485 0.6618 -0.0238 +v 0.5309 0.6890 -0.0369 +v 0.7595 0.4019 0.1394 +v 0.7337 0.3543 0.0828 +v 0.7165 0.3837 0.0323 +v 0.4907 0.6108 -0.1342 +v 0.4686 0.6085 -0.1422 +v 0.6285 0.5216 0.0079 +v 0.6083 0.5236 0.0014 +v 0.6071 0.5388 -0.0005 +v 0.5410 0.7954 -0.0205 +v 0.5457 0.8047 -0.0151 +v 0.6384 0.6759 -0.0051 +v 0.6567 0.7166 0.0184 +v 0.6916 0.6970 0.0471 +v 0.5070 0.8820 -0.0003 +v 0.5247 0.8179 -0.0270 +v 0.5220 0.8031 -0.0318 +v 0.4960 0.8096 -0.0407 +v 0.4663 0.8117 -0.0427 +v 0.5989 0.7052 -0.0097 +v 0.5967 0.6454 -0.0179 +v 0.5548 0.9369 0.0738 +v 0.5614 0.9182 0.0429 +v 0.5700 0.7367 -0.0225 +v 0.5441 0.7234 -0.0362 +v 0.5007 0.4954 -0.0448 +v 0.5116 0.5273 -0.0278 +v 0.5196 0.5223 -0.0099 +v 0.6141 0.4824 -0.0067 +v 0.6251 0.4559 -0.0172 +v 0.5922 0.4593 -0.0170 +v 0.6544 0.5000 0.0197 +v 0.5084 0.5956 -0.0919 +v 0.5087 0.5722 -0.0734 +v 0.4922 0.5595 -0.0925 +v 0.5285 0.4483 -0.0589 +v 0.6986 0.5752 0.0364 +v 0.7160 0.5567 0.0593 +v 0.6877 0.5382 0.0432 +v 0.5248 0.4937 -0.0115 +v 0.5480 0.4664 -0.0217 +v 0.5237 0.6857 -0.0523 +v 0.4998 0.6891 -0.0639 +v 0.5391 0.6066 -0.0361 +v 0.5629 0.6260 -0.0248 +v 0.5726 0.5943 -0.0166 +v 0.5205 0.6722 -0.0730 +v 0.5317 0.6708 -0.0760 +v 0.5198 0.6630 -0.1055 +v 0.5495 0.5184 0.0091 +v 0.5428 0.5258 0.0035 +v 0.5577 0.5312 0.0005 +v 0.5364 0.6280 -0.0500 +v 0.5238 0.6125 -0.0700 +v 0.6281 0.8636 0.0938 +v 0.6213 0.8908 0.1315 +v 0.5232 0.5884 -0.0534 +v 0.6352 0.4452 -0.0248 +v 0.6668 0.4522 -0.0132 +v 0.6867 0.4338 -0.0162 +v 0.4918 0.6432 -0.1477 +v 0.5114 0.6456 -0.1254 +v 0.5115 0.6200 -0.1179 +v 0.5553 0.2800 -0.0530 +v 0.5789 0.8055 0.0152 +v 0.5774 0.5527 -0.0012 +v 0.6946 0.5128 0.0488 +v 0.6953 0.4875 0.0281 +v 0.6793 0.4888 0.0205 +v 0.7019 0.4160 -0.0048 +v 0.6604 0.4020 -0.0352 +v 0.6497 0.4245 -0.0376 +v 0.4912 0.6765 -0.1137 +v 0.4866 0.6789 -0.1205 +v 0.4840 0.6866 -0.0884 +v 0.7115 0.4529 0.0107 +v 0.7171 0.4838 0.0400 +v 0.7369 0.4771 0.0664 +v 0.5594 0.7825 0.0073 +v 0.5439 0.7814 -0.0022 +v 0.5485 0.7852 -0.0035 +v 0.7270 0.4401 0.0327 +v 0.7415 0.5225 0.0958 +v 0.7419 0.5721 0.0907 +v 0.7620 0.5753 0.1738 +v 0.7328 0.6288 0.0872 +v 0.4875 0.6683 -0.1379 +v 0.4904 0.5846 -0.1110 +v 0.6180 0.7377 0.0042 +v 0.5643 0.5195 0.0040 +v 0.5813 0.5365 -0.0023 +v 0.4993 0.7142 -0.0598 +v 0.5151 0.9128 0.0035 +v 0.5984 0.7794 0.0184 +v 0.4892 0.6825 -0.0891 +v 0.5669 0.4936 -0.0026 +v 0.7203 0.5196 0.0686 +v 0.6533 0.4625 -0.0078 +v 0.5766 0.8444 0.0235 +v 0.5623 0.7825 0.0079 +v 0.7520 0.6314 0.1844 +v 0.5167 0.7730 -0.0406 +v 0.5400 0.6741 -0.0581 +v 0.5303 0.6776 -0.0624 +v 0.5353 0.7759 -0.0228 +v 0.6239 0.7833 0.0314 +v 0.5960 0.8909 0.0700 +v 0.6122 0.3457 -0.0448 +v 0.4938 0.5309 -0.0685 +v 0.6776 0.6411 0.0149 +v 0.5357 0.7863 -0.0175 +v 0.5982 0.4280 -0.0528 +v 0.6040 0.4038 -0.0603 +v 0.5174 0.7896 -0.0284 +v 0.7582 0.6342 0.2818 +v 0.7690 0.5736 0.2749 +v 0.4943 0.7922 -0.0363 +v 0.5854 0.5220 0.0003 +v 0.5304 0.7802 -0.0155 +v 0.5130 0.7792 -0.0265 +v 0.6597 0.8562 0.1685 +v 0.7211 0.7447 0.1787 +v 0.6912 0.8179 0.2141 +v 0.5286 0.6525 -0.1003 +v 0.5129 0.7787 -0.0275 +v 0.5682 0.7832 0.0151 +v 0.5171 0.9373 0.0194 +v 0.4939 0.7699 -0.0503 +v 0.6871 0.4657 0.0044 +v 0.6327 0.5371 0.0068 +v 0.6520 0.5319 0.0182 +v 0.6466 0.5575 0.0148 +v 0.7649 0.5192 0.1610 +v 0.4720 0.2776 -0.0588 +v 0.5948 0.4476 -0.0270 +v 0.4767 0.6883 -0.0879 +v 0.6595 0.5052 0.0319 +v 0.6627 0.5227 0.0286 +v 0.6748 0.5067 0.0376 +v 0.5094 0.5448 -0.0511 +v 0.7436 0.4215 0.0823 +v 0.5889 0.9153 0.1029 +v 0.4976 0.6930 -0.0628 +v 0.5039 0.6639 -0.1257 +v 0.5413 0.5168 0.0092 +v 0.5031 0.6686 -0.1125 +v 0.5327 0.5174 0.0054 +v 0.4791 0.6807 -0.1241 +v 0.7373 0.6903 0.1852 +v 0.7417 0.6977 0.2756 +v 0.5128 0.6674 -0.0998 +v 0.7229 0.6814 0.1002 +v 0.7119 0.7257 0.1136 +v 0.5199 0.6768 -0.0623 +v 0.5147 0.6813 -0.0562 +v 0.6730 0.5500 0.0303 +v 0.5024 0.6834 -0.0634 +v 0.7196 0.7647 0.2546 +v 0.6510 0.5129 0.0235 +v 0.2529 0.3140 0.0303 +v 0.5906 0.4839 -0.0078 +v 0.5462 0.6605 -0.0508 +v 0.4910 0.7798 -0.0353 +v 0.4916 0.7787 -0.0363 +v 0.6419 0.5178 0.0164 +# 468 vertices -# vertex normals -vn -0.989154 0.091815 -0.114648 -vn -0.978839 0.023592 -0.203266 -vn -0.967707 -0.012120 -0.251785 -vn -0.028582 0.464143 -0.885299 -vn -0.020993 0.105897 -0.994155 -vn -0.296322 0.026292 -0.954726 -vn -0.265613 -0.373661 -0.888722 -vn -0.133311 -0.106166 -0.985371 -vn -0.298169 -0.306705 -0.903896 -vn -0.270117 0.406190 -0.872953 -vn -0.511751 0.180375 -0.839986 -vn -0.685800 -0.450796 -0.571367 -vn -0.459564 -0.436696 -0.773368 -vn -0.602375 -0.345938 -0.719355 -vn -0.669974 -0.257394 -0.696336 -vn -0.387408 -0.216008 -0.896245 -vn -0.487337 -0.218378 -0.845467 -vn -0.018731 0.763590 -0.645429 -vn -0.389466 0.689439 -0.610729 -vn -0.373035 0.847619 -0.377341 -vn -0.442508 -0.213470 -0.870987 -vn -0.639000 0.049707 -0.767599 -vn -0.324141 -0.183763 -0.927989 -vn -0.436113 0.494326 -0.751963 -vn -0.550943 0.479951 -0.682721 -vn -0.009559 0.104067 -0.994524 -vn -0.011704 -0.122131 -0.992445 -vn -0.209202 -0.132722 -0.968824 -vn -0.901063 0.267357 -0.341475 -vn -0.877600 0.059127 -0.475733 -vn -0.880403 -0.328711 -0.341818 -vn -0.505525 0.248590 -0.826225 -vn -0.590181 0.285502 -0.755099 -vn -0.692986 0.332220 -0.639844 -vn -0.468446 0.669380 -0.576619 -vn -0.427234 0.736848 -0.523953 -vn -0.285192 0.872663 -0.396389 -vn -0.353473 0.821553 -0.447334 -vn -0.311827 0.876737 -0.366191 -vn -0.524965 0.146679 -0.838390 -vn -0.472147 0.443746 -0.761687 -vn -0.245148 -0.026702 -0.969118 -vn -0.418674 -0.140684 -0.897173 -vn -0.571366 0.290779 -0.767456 -vn -0.527578 0.387853 -0.755799 -vn -0.722795 0.401394 -0.562538 -vn -0.183626 0.444923 -0.876542 -vn -0.012487 0.469328 -0.882936 -vn -0.021704 0.549019 -0.835528 -vn -0.748330 0.284092 -0.599410 -vn -0.450763 0.389446 -0.803209 -vn -0.721835 -0.197775 -0.663204 -vn -0.258924 0.477327 -0.839713 -vn -0.198514 0.550487 -0.810898 -vn -0.312693 0.580735 -0.751644 -vn -0.132535 0.549913 -0.824639 -vn 0.098803 0.310724 -0.945351 -vn -0.038284 0.425489 -0.904154 -vn -0.588901 0.272523 -0.760873 -vn -0.810287 0.477189 -0.340184 -vn -0.834781 0.369250 -0.408404 -vn -0.303002 -0.016075 -0.952854 -vn -0.498672 -0.094030 -0.861675 -vn -0.685735 0.201360 -0.699444 -vn -0.960096 -0.006251 -0.279601 -vn -0.940065 -0.081416 -0.331133 -vn -0.844260 -0.234792 -0.481766 -vn -0.519195 -0.457520 -0.721880 -vn -0.456043 -0.005334 -0.889942 -vn -0.014474 0.019138 -0.999712 -vn -0.400658 -0.157737 -0.902548 -vn -0.396123 -0.022364 -0.917925 -vn -0.193053 0.033679 -0.980610 -vn -0.635244 -0.387955 -0.667800 -vn -0.695676 0.147188 -0.703115 -vn -0.444957 0.112722 -0.888429 -vn -0.791980 0.253822 -0.555286 -vn -0.258765 0.139318 -0.955841 -vn -0.016050 0.075692 -0.997002 -vn -0.464036 0.373712 -0.803125 -vn -0.596455 -0.240230 -0.765853 -vn -0.523431 0.350991 -0.776419 -vn -0.237288 0.002036 -0.971437 -vn -0.281331 0.479103 -0.831453 -vn -0.358398 0.089163 -0.929301 -vn -0.254237 0.000218 -0.967142 -vn -0.670074 0.563024 -0.483741 -vn -0.703398 0.112141 -0.701895 -vn -0.650705 0.408330 -0.640195 -vn -0.779250 -0.192549 -0.596402 -vn -0.151524 0.397906 -0.904827 -vn -0.020938 0.351761 -0.935856 -vn -0.105769 0.563919 -0.819029 -vn -0.345032 0.654050 -0.673180 -vn -0.375194 0.724919 -0.577687 -vn -0.335630 0.607600 -0.719844 -vn -0.819766 -0.408062 -0.401832 -vn -0.604021 -0.511468 -0.611195 -vn -0.600285 -0.476912 -0.642038 -vn -0.897080 -0.147366 -0.416570 -vn -0.008768 -0.175594 -0.984424 -vn -0.013020 0.256558 -0.966441 -vn -0.672715 -0.146125 -0.725329 -vn -0.525261 -0.197801 -0.827633 -vn -0.555028 -0.154254 -0.817404 -vn -0.296176 0.504342 -0.811122 -vn -0.515058 0.378919 -0.768853 -vn -0.676941 0.435248 -0.593557 -vn -0.711889 -0.137630 -0.688674 -vn -0.386907 -0.272906 -0.880809 -vn -0.259326 0.910000 -0.323497 -vn -0.423222 0.872524 -0.244100 -vn -0.638842 0.634796 -0.434644 -vn 0.007496 -0.527226 -0.849692 -vn 0.143129 -0.327798 -0.933843 -vn 0.041677 -0.296840 -0.954017 -vn -0.918998 -0.291373 -0.265602 -vn -0.952454 -0.197541 -0.231966 -vn -0.821810 0.525865 -0.219306 -vn -0.771659 0.571693 -0.278765 -vn -0.840676 -0.247123 -0.481864 -vn -0.158942 0.620426 -0.767990 -vn -0.384450 0.393370 -0.835139 -vn -0.513484 0.229094 -0.826952 -vn -0.777451 -0.393102 -0.490959 -vn -0.759032 0.486958 -0.432137 -vn -0.533264 0.077212 -0.842418 -vn -0.251196 -0.232657 -0.939559 -vn -0.503703 0.280865 -0.816944 -vn -0.368391 0.340902 -0.864913 -vn -0.743609 -0.083195 -0.663419 -vn -0.611674 0.784735 -0.100229 -vn -0.529063 0.808039 -0.259163 -vn -0.450788 0.844293 -0.289756 -vn -0.692300 0.311042 -0.651133 -vn -0.889028 -0.021444 -0.457350 -vn -0.899735 0.132668 -0.415783 -vn -0.261516 0.061728 -0.963223 -vn -0.704174 -0.385083 -0.596532 -vn -0.404858 -0.718278 -0.565832 -vn -0.898124 0.060778 -0.435522 -vn -0.978799 0.124512 -0.162635 -vn -0.907937 0.136395 -0.396290 -vn -0.729764 -0.085842 -0.678289 -vn -0.410935 0.568263 -0.712888 -vn -0.275997 0.871465 -0.405432 -vn -0.005188 0.891595 -0.452804 -vn -0.476639 0.306831 -0.823815 -vn 0.005029 -0.177515 -0.984105 -vn -0.009101 -0.056171 -0.998380 -vn -0.336647 0.019776 -0.941423 -vn -0.367028 0.271658 -0.889658 -vn -0.333945 0.004642 -0.942581 -vn -0.339089 0.449521 -0.826408 -vn -0.610783 0.519047 -0.597942 -vn -0.707538 0.170561 -0.685783 -vn -0.437024 0.575640 -0.691121 -vn -0.137289 0.556285 -0.819572 -vn -0.683928 0.410425 -0.603153 -vn -0.411206 0.554680 -0.723354 -vn -0.971940 0.194990 -0.131571 -vn -0.896519 0.031354 -0.441894 -vn -0.306105 0.764040 -0.567929 -vn -0.209480 0.729542 -0.651066 -vn -0.676488 0.040355 -0.735347 -vn -0.774771 0.555102 -0.302642 -vn -0.335221 0.806201 -0.487511 -vn -0.982848 0.073736 -0.169034 -vn -0.629389 0.274581 -0.726963 -vn -0.400985 0.798998 -0.448121 -vn -0.768005 0.506514 -0.391935 -vn -0.731296 0.610169 -0.304795 -vn -0.638646 0.702397 -0.314277 -vn -0.540283 -0.066115 -0.838882 -vn -0.297203 0.039769 -0.953986 -vn -0.677554 -0.413624 -0.608141 -vn -0.002689 -0.520341 -0.853954 -vn -0.918361 0.251470 -0.305574 -vn -0.274751 0.570725 -0.773812 -vn -0.158382 0.128648 -0.978961 -vn -0.461589 -0.561757 -0.686560 -vn -0.429290 -0.092666 -0.898401 -vn -0.979295 0.192583 -0.062389 -vn -0.016126 -0.152253 -0.988210 -vn -0.225876 -0.222736 -0.948351 -vn -0.019724 -0.071972 -0.997212 -vn -0.263223 -0.125065 -0.956594 -vn -0.209349 -0.117703 -0.970731 -vn -0.446182 -0.595063 -0.668447 -vn -0.373408 -0.368784 -0.851214 -vn -0.412697 -0.792358 -0.449277 -vn -0.877500 0.415462 -0.239551 -vn -0.894094 0.431917 -0.118507 -vn -0.942922 0.302532 -0.139186 -vn -0.946835 0.312222 -0.077588 -vn -0.496746 0.777958 -0.384740 -vn -0.212876 0.895131 -0.391693 -vn -0.001050 -0.645701 -0.763589 -vn -0.019145 0.321976 -0.946554 -vn -0.200656 0.853980 -0.480057 -vn -0.526073 -0.229550 -0.818874 -vn -0.546882 -0.143799 -0.824768 -vn -0.988214 0.137894 -0.066468 -vn -0.260705 -0.141810 -0.954946 -vn -0.301007 0.820594 -0.485819 -vn -0.248583 0.923700 -0.291521 -vn -0.198627 0.733375 -0.650161 -vn -0.217063 0.945523 -0.242631 -vn -0.386997 0.689518 -0.612208 -vn -0.008716 -0.583948 -0.811744 -vn -0.543594 -0.189748 -0.817619 -vn -0.557047 -0.258937 -0.789082 -vn -0.450147 0.268510 -0.851628 -vn -0.792542 0.036181 -0.608743 -vn -0.669585 0.521122 -0.529233 -vn -0.857944 -0.263233 -0.441181 -vn -0.977439 0.066543 -0.200461 -vn -0.805878 -0.418871 -0.418459 -vn -0.833403 -0.331169 -0.442455 -vn -0.011272 0.750734 -0.660508 -vn -0.500024 0.802278 -0.326076 -vn -0.017934 0.116846 -0.992988 -vn -0.028038 0.734819 -0.677683 -vn -0.034078 0.851529 -0.523199 -vn -0.872848 -0.380703 -0.305290 -vn -0.292460 -0.125000 -0.948073 -vn -0.252126 -0.491308 -0.833696 -vn -0.575193 -0.147604 -0.804591 -vn -0.555827 0.787746 -0.265543 -vn -0.324352 0.459649 -0.826752 -vn -0.611845 0.247948 -0.751111 -vn -0.388309 -0.342022 -0.855709 -vn -0.970401 0.232736 -0.064460 -vn -0.966158 0.226045 -0.124271 -vn -0.016452 0.561171 -0.827537 -vn -0.899680 0.305623 -0.311722 -vn -0.153846 0.842331 -0.516536 -vn 0.010633 0.976070 -0.217198 -vn -0.419708 0.425569 -0.801708 -vn -0.258015 0.520575 -0.813898 -vn -0.509894 -0.437386 -0.740744 -vn -0.778570 -0.412323 -0.473095 -vn -0.667986 0.418462 -0.615373 -vn 0.988528 0.094637 -0.117711 -vn 0.976630 0.076274 -0.200939 -vn 0.970688 -0.005874 -0.240273 -vn 0.217470 0.416663 -0.882666 -vn 0.265463 0.033223 -0.963548 -vn 0.246521 -0.375790 -0.893313 -vn 0.450784 -0.432062 -0.781100 -vn 0.278675 -0.301722 -0.911759 -vn 0.386994 0.493634 -0.778820 -vn 0.477702 0.182683 -0.859318 -vn 0.680710 -0.452901 -0.575773 -vn 0.774885 -0.395963 -0.492713 -vn 0.592781 -0.335922 -0.731961 -vn 0.504125 -0.445715 -0.739727 -vn 0.660854 -0.268453 -0.700860 -vn 0.771135 -0.190605 -0.607471 -vn 0.469295 -0.214986 -0.856471 -vn -0.017578 0.913842 -0.405690 -vn 0.338461 0.861853 -0.377695 -vn 0.424141 -0.202192 -0.882736 -vn 0.228365 -0.224551 -0.947326 -vn 0.300898 -0.170780 -0.938240 -vn 0.415233 0.691372 -0.591258 -vn 0.526287 0.456885 -0.717132 -vn 0.137184 0.131518 -0.981776 -vn 0.188901 -0.129928 -0.973363 -vn 0.894137 0.290202 -0.341029 -vn 0.956467 -0.179643 -0.229997 -vn 0.882695 -0.306401 -0.356324 -vn 0.474877 0.272497 -0.836802 -vn 0.580280 0.268396 -0.768921 -vn 0.669832 0.360232 -0.649275 -vn 0.350162 0.808747 -0.472562 -vn 0.378904 0.756029 -0.533715 -vn 0.193947 0.902930 -0.383538 -vn 0.099204 0.969436 -0.224395 -vn 0.248246 0.886996 -0.389373 -vn 0.458940 0.434861 -0.774771 -vn 0.219899 -0.020789 -0.975301 -vn 0.544710 0.321704 -0.774466 -vn 0.660848 0.445626 -0.603902 -vn 0.704186 0.422487 -0.570638 -vn 0.141965 0.454806 -0.879203 -vn 0.233122 0.506290 -0.830256 -vn 0.850023 -0.055648 -0.523797 -vn 0.618646 -0.389341 -0.682415 -vn 0.705049 -0.200313 -0.680279 -vn 0.227813 0.473272 -0.850950 -vn 0.329042 0.597120 -0.731559 -vn 0.289620 0.577679 -0.763157 -vn 0.105725 0.552661 -0.826673 -vn 0.292287 0.469507 -0.833146 -vn 0.025028 0.417948 -0.908126 -vn 0.561065 0.311194 -0.767049 -vn 0.423306 0.405818 -0.810015 -vn 0.794832 0.504936 -0.336573 -vn 0.868002 0.438396 -0.233198 -vn 0.826633 0.390446 -0.405253 -vn 0.273159 -0.016464 -0.961828 -vn 0.663480 0.065798 -0.745296 -vn 0.664332 0.213759 -0.716219 -vn 0.960002 -0.000328 -0.279993 -vn 0.895983 -0.141424 -0.420967 -vn 0.845151 -0.250414 -0.472242 -vn 0.508929 -0.448065 -0.735003 -vn -0.008925 -0.431391 -0.902121 -vn 0.370818 -0.162628 -0.914356 -vn 0.192476 -0.112601 -0.974820 -vn 0.165775 0.047228 -0.985032 -vn 0.583060 -0.221009 -0.781790 -vn 0.666721 0.175661 -0.724311 -vn 0.423087 0.118662 -0.898285 -vn 0.608465 0.286772 -0.739954 -vn 0.776887 0.272252 -0.567738 -vn 0.223824 0.144513 -0.963856 -vn 0.482288 0.391437 -0.783693 -vn 0.405895 -0.070348 -0.911208 -vn 0.198425 0.014285 -0.980012 -vn -0.015566 0.069501 -0.997460 -vn 0.327326 0.092075 -0.940415 -vn 0.228590 0.005407 -0.973508 -vn 0.610203 0.722180 -0.325743 -vn 0.644265 0.580320 -0.498147 -vn 0.496880 0.141627 -0.856184 -vn 0.474895 -0.091041 -0.875321 -vn 0.686963 0.121366 -0.716486 -vn 0.857858 -0.267165 -0.438978 -vn 0.779553 -0.182516 -0.599154 -vn 0.120815 0.397070 -0.909802 -vn 0.107548 0.545135 -0.831421 -vn 0.076149 0.548565 -0.832633 -vn 0.365069 0.708688 -0.603726 -vn 0.820964 -0.390397 -0.416663 -vn 0.833076 -0.322834 -0.449179 -vn 0.598038 -0.467941 -0.650678 -vn 0.269537 0.510352 -0.816634 -vn 0.665168 -0.133550 -0.734654 -vn 0.726059 -0.075311 -0.683496 -vn 0.540766 -0.151426 -0.827431 -vn 0.620694 0.434641 -0.652554 -vn 0.360247 0.696867 -0.620160 -vn 0.292318 0.817448 -0.496315 -vn 0.654923 0.461574 -0.598353 -vn 0.701333 -0.121420 -0.702417 -vn 0.312651 0.014945 -0.949750 -vn 0.373004 -0.264639 -0.889288 -vn 0.206757 0.922462 -0.326061 -vn 0.442808 0.805742 -0.393321 -vn 0.612778 0.652270 -0.446146 -vn -0.028247 -0.521625 -0.852707 -vn 0.226947 -0.482260 -0.846121 -vn -0.062468 -0.296327 -0.953041 -vn 0.925512 -0.261216 -0.274215 -vn 0.878248 -0.358335 -0.316665 -vn 0.743057 0.535577 -0.401277 -vn 0.749726 0.597931 -0.283529 -vn 0.836928 -0.237663 -0.493019 -vn 0.130611 0.594679 -0.793282 -vn 0.239456 0.509770 -0.826314 -vn 0.494188 0.225578 -0.839579 -vn 0.438744 0.021082 -0.898365 -vn 0.780981 0.058828 -0.621778 -vn 0.775704 -0.376372 -0.506584 -vn 0.236710 -0.143646 -0.960903 -vn 0.507845 0.100276 -0.855592 -vn 0.103592 -0.100906 -0.989488 -vn 0.482897 0.288199 -0.826893 -vn 0.427303 0.574753 -0.697905 -vn 0.323085 0.648379 -0.689362 -vn 0.742235 -0.098605 -0.662846 -vn 0.522289 -0.070784 -0.849826 -vn 0.359685 0.384419 -0.850205 -vn 0.579482 0.806319 -0.118531 -vn 0.460319 0.825428 -0.326765 -vn 0.369098 0.883146 -0.289517 -vn 0.686149 0.312116 -0.657102 -vn 0.647312 0.440115 -0.622323 -vn 0.899320 0.148349 -0.411359 -vn 0.246754 0.039254 -0.968283 -vn 0.470198 -0.735721 -0.487471 -vn 0.452751 -0.680750 -0.575844 -vn 0.896589 -0.034317 -0.441532 -vn 0.898734 0.084325 -0.430310 -vn 0.895852 0.046640 -0.441897 -vn 0.977404 0.133951 -0.163518 -vn 0.900660 0.157487 -0.404980 -vn 0.372365 0.588174 -0.717911 -vn 0.600066 -0.502138 -0.622718 -vn 0.457941 0.311714 -0.832541 -vn -0.156725 -0.330596 -0.930668 -vn -0.015510 -0.050631 -0.998597 -vn 0.311873 0.019133 -0.949931 -vn 0.339223 0.282729 -0.897213 -vn 0.336197 0.457903 -0.822980 -vn 0.537399 0.799737 -0.267626 -vn -0.133176 0.290743 -0.947488 -vn 0.701175 0.184024 -0.688831 -vn 0.171422 0.545524 -0.820377 -vn 0.557965 0.312850 -0.768635 -vn 0.597142 0.301567 -0.743289 -vn 0.967454 0.214658 -0.133997 -vn 0.231442 0.783068 -0.577269 -vn 0.758040 0.578185 -0.301790 -vn 0.266957 0.837520 -0.476753 -vn 0.269345 0.859935 -0.433550 -vn 0.506708 0.394993 -0.766308 -vn 0.739446 0.513174 -0.435745 -vn 0.367340 -0.215619 -0.904748 -vn 0.677713 -0.398106 -0.618236 -vn 0.618500 0.066066 -0.783003 -vn 0.471141 -0.551720 -0.688208 -vn 0.250585 0.573355 -0.780046 -vn 0.272617 0.040434 -0.961273 -vn 0.366550 -0.339503 -0.866244 -vn 0.974410 0.214527 -0.067104 -vn 0.985748 0.150902 -0.074353 -vn 0.207445 -0.207059 -0.956082 -vn -0.032578 -0.188798 -0.981475 -vn 0.450907 -0.576718 -0.681233 -vn 0.395902 -0.296063 -0.869258 -vn 0.807714 0.551376 -0.208764 -vn 0.933151 0.332572 -0.136470 -vn 0.882050 0.456609 -0.116174 -vn 0.861651 0.106483 -0.496204 -vn 0.150394 0.908441 -0.390022 -vn 0.488503 0.352882 -0.798022 -vn 0.355644 0.705205 -0.613354 -vn 0.138676 0.736147 -0.662463 -vn 0.395106 0.549354 -0.736276 -vn 0.369026 -0.015964 -0.929282 -vn 0.527767 -0.143402 -0.837196 -vn 0.395273 -0.132009 -0.909029 -vn 0.979386 0.034363 -0.199056 -vn -0.010561 -0.165922 -0.986082 -vn 0.174483 0.721836 -0.669707 -vn 0.163300 0.956814 -0.240499 -vn 0.430649 0.294216 -0.853217 -vn 0.537128 -0.187188 -0.822468 -vn 0.350819 0.343816 -0.871044 -vn 0.810647 -0.395791 -0.431511 -vn 0.943050 -0.088390 -0.320693 -vn 0.710684 0.630300 -0.312488 -vn 0.490608 0.395586 -0.776412 -vn 0.637860 0.542034 -0.547114 -vn 0.264807 -0.135122 -0.954787 -vn 0.507025 0.829811 -0.233108 -vn 0.556414 -0.129443 -0.820761 -vn 0.261031 0.880593 -0.395498 -vn 0.958274 0.256982 -0.125183 -vn 0.961412 0.266257 -0.069238 -vn 0.394922 0.881069 -0.260295 -vn 0.910245 0.275428 -0.309182 -vn 0.888100 0.337531 -0.312011 -vn 0.114979 0.869521 -0.480326 -vn 0.365805 0.463122 -0.807282 -vn 0.506338 -0.198335 -0.839217 -vn 0.577234 0.550002 -0.603572 -vn 0.936082 0.343341 -0.076603 -vn 0.539172 -0.254163 -0.802929 -vn -0.776143 -0.192192 -0.600553 -vn -0.011546 0.348124 -0.937377 -vn 0.982699 0.077990 -0.167986 -vn 0.219797 -0.135832 -0.966043 -vn 0.134231 0.848129 -0.512503 -vn 0.487957 -0.244669 -0.837875 -# Mesh +vt 0.0147 0.4668 0.0000 +vt 0.1049 0.4716 0.0000 +vt 0.1292 0.5313 0.0000 +vt 0.5005 0.2458 0.0000 +vt 0.5005 0.2570 0.0000 +vt 0.4745 0.2628 0.0000 +vt 0.3859 0.4818 0.0000 +vt 0.3646 0.4669 0.0000 +vt 0.3693 0.4471 0.0000 +vt 0.4759 0.2479 0.0000 +vt 0.4423 0.2555 0.0000 +vt 0.4120 0.4846 0.0000 +vt 0.3932 0.4639 0.0000 +vt 0.4003 0.4442 0.0000 +vt 0.2789 0.6680 0.0000 +vt 0.3509 0.6923 0.0000 +vt 0.3233 0.7432 0.0000 +vt 0.5005 0.0338 0.0000 +vt 0.4441 0.0397 0.0000 +vt 0.4312 0.0048 0.0000 +vt 0.2866 0.4184 0.0000 +vt 0.2814 0.3609 0.0000 +vt 0.3366 0.3971 0.0000 +vt 0.4479 0.2441 0.0000 +vt 0.4187 0.2424 0.0000 +vt 0.5013 0.6285 0.0000 +vt 0.5009 0.7040 0.0000 +vt 0.4227 0.7019 0.0000 +vt 0.4367 0.3599 0.0000 +vt 0.4546 0.3734 0.0000 +vt 0.4474 0.3880 0.0000 +vt 0.4127 0.1154 0.0000 +vt 0.3776 0.1397 0.0000 +vt 0.3570 0.1118 0.0000 +vt 0.4245 0.2358 0.0000 +vt 0.3990 0.2257 0.0000 +vt 0.4291 0.2176 0.0000 +vt 0.4278 0.2257 0.0000 +vt 0.4085 0.2183 0.0000 +vt 0.3920 0.2671 0.0000 +vt 0.3702 0.2432 0.0000 +vt 0.3340 0.4539 0.0000 +vt 0.2997 0.4488 0.0000 +vt 0.3483 0.1726 0.0000 +vt 0.3277 0.2091 0.0000 +vt 0.2881 0.2020 0.0000 +vt 0.4647 0.1244 0.0000 +vt 0.5005 0.1223 0.0000 +vt 0.5005 0.1584 0.0000 +vt 0.3882 0.2060 0.0000 +vt 0.3842 0.2055 0.0000 +vt 0.4009 0.1949 0.0000 +vt 0.3240 0.5332 0.0000 +vt 0.3086 0.5596 0.0000 +vt 0.2893 0.5442 0.0000 +vt 0.3901 0.5544 0.0000 +vt 0.3855 0.5335 0.0000 +vt 0.3961 0.5202 0.0000 +vt 0.4023 0.1612 0.0000 +vt 0.2419 0.1475 0.0000 +vt 0.2356 0.2274 0.0000 +vt 0.3833 0.3293 0.0000 +vt 0.4165 0.2829 0.0000 +vt 0.4238 0.3222 0.0000 +vt 0.1094 0.6010 0.0000 +vt 0.1699 0.5849 0.0000 +vt 0.2225 0.6315 0.0000 +vt 0.4860 0.4115 0.0000 +vt 0.4924 0.3854 0.0000 +vt 0.5012 0.3858 0.0000 +vt 0.3136 0.4853 0.0000 +vt 0.3135 0.4704 0.0000 +vt 0.3372 0.4740 0.0000 +vt 0.4066 0.2006 0.0000 +vt 0.4228 0.1832 0.0000 +vt 0.3239 0.3285 0.0000 +vt 0.2580 0.2993 0.0000 +vt 0.4569 0.0982 0.0000 +vt 0.5005 0.0934 0.0000 +vt 0.4319 0.1411 0.0000 +vt 0.4280 0.1927 0.0000 +vt 0.4470 0.1698 0.0000 +vt 0.4744 0.1790 0.0000 +vt 0.4737 0.1615 0.0000 +vt 0.3593 0.2991 0.0000 +vt 0.3583 0.3638 0.0000 +vt 0.3901 0.0568 0.0000 +vt 0.4604 0.5378 0.0000 +vt 0.4215 0.5338 0.0000 +vt 0.4193 0.5091 0.0000 +vt 0.3461 0.5423 0.0000 +vt 0.3661 0.5430 0.0000 +vt 0.3662 0.5686 0.0000 +vt 0.2731 0.5238 0.0000 +vt 0.2948 0.5106 0.0000 +vt 0.3067 0.5212 0.0000 +vt 0.4582 0.4314 0.0000 +vt 0.4820 0.4394 0.0000 +vt 0.4781 0.4654 0.0000 +vt 0.1687 0.6591 0.0000 +vt 0.5006 0.5393 0.0000 +vt 0.5005 0.5826 0.0000 +vt 0.2482 0.4258 0.0000 +vt 0.2699 0.4542 0.0000 +vt 0.2515 0.4650 0.0000 +vt 0.4436 0.5938 0.0000 +vt 0.4655 0.3097 0.0000 +vt 0.4596 0.3179 0.0000 +vt 0.4055 0.4116 0.0000 +vt 0.3746 0.4209 0.0000 +vt 0.4472 0.3421 0.0000 +vt 0.4638 0.3541 0.0000 +vt 0.4621 0.3644 0.0000 +vt 0.3851 0.5111 0.0000 +vt 0.3696 0.5043 0.0000 +vt 0.3786 0.4937 0.0000 +vt 0.4170 0.3941 0.0000 +vt 0.4310 0.3714 0.0000 +vt 0.1987 0.1072 0.0000 +vt 0.2659 0.0727 0.0000 +vt 0.4255 0.4356 0.0000 +vt 0.3309 0.5828 0.0000 +vt 0.3224 0.6075 0.0000 +vt 0.2824 0.5897 0.0000 +vt 0.4691 0.4044 0.0000 +vt 0.3374 0.0828 0.0000 +vt 0.3767 0.1817 0.0000 +vt 0.3352 0.4294 0.0000 +vt 0.2436 0.4922 0.0000 +vt 0.2667 0.4989 0.0000 +vt 0.2640 0.6037 0.0000 +vt 0.4861 0.3510 0.0000 +vt 0.4776 0.3328 0.0000 +vt 0.4828 0.3273 0.0000 +vt 0.2509 0.5633 0.0000 +vt 0.2244 0.5712 0.0000 +vt 0.1957 0.5278 0.0000 +vt 0.3952 0.2075 0.0000 +vt 0.3920 0.2069 0.0000 +vt 0.4106 0.2053 0.0000 +vt 0.1759 0.4752 0.0000 +vt 0.1009 0.4117 0.0000 +vt 0.1954 0.3660 0.0000 +vt 0.2214 0.4448 0.0000 +vt 0.4894 0.3650 0.0000 +vt 0.4963 0.3512 0.0000 +vt 0.5013 0.3506 0.0000 +vt 0.3407 0.2632 0.0000 +vt 0.3509 0.4949 0.0000 +vt 0.3596 0.4824 0.0000 +vt 0.4679 0.2897 0.0000 +vt 0.4512 0.0662 0.0000 +vt 0.3857 0.3856 0.0000 +vt 0.3562 0.2113 0.0000 +vt 0.4558 0.3242 0.0000 +vt 0.2113 0.4830 0.0000 +vt 0.2544 0.5237 0.0000 +vt 0.3366 0.5693 0.0000 +vt 0.3182 0.1465 0.0000 +vt 0.2735 0.5527 0.0000 +vt 0.1012 0.3494 0.0000 +vt 0.1847 0.4235 0.0000 +vt 0.4508 0.2318 0.0000 +vt 0.4757 0.2315 0.0000 +vt 0.4010 0.3544 0.0000 +vt 0.4301 0.3460 0.0000 +vt 0.4367 0.3271 0.0000 +vt 0.4212 0.3580 0.0000 +vt 0.3021 0.2818 0.0000 +vt 0.4032 0.2219 0.0000 +vt 0.2912 0.1118 0.0000 +vt 0.3179 0.0469 0.0000 +vt 0.3723 0.0264 0.0000 +vt 0.3117 0.6281 0.0000 +vt 0.3711 0.6357 0.0000 +vt 0.4738 0.4975 0.0000 +vt 0.5008 0.5007 0.0000 +vt 0.1975 0.3082 0.0000 +vt 0.3746 0.6135 0.0000 +vt 0.4366 0.6327 0.0000 +vt 0.4299 0.2024 0.0000 +vt 0.4496 0.1861 0.0000 +vt 0.0053 0.3348 0.0000 +vt 0.5005 0.1954 0.0000 +vt 0.4749 0.1968 0.0000 +vt 0.5005 0.2115 0.0000 +vt 0.4768 0.2107 0.0000 +vt 0.3319 0.4878 0.0000 +vt 0.4328 0.2102 0.0000 +vt 0.4508 0.2000 0.0000 +vt 0.4135 0.2110 0.0000 +vt 0.1895 0.1824 0.0000 +vt 0.1298 0.1429 0.0000 +vt 0.1384 0.2290 0.0000 +vt 0.0685 0.1945 0.0000 +vt 0.4418 0.3514 0.0000 +vt 0.4494 0.2171 0.0000 +vt 0.5009 0.4400 0.0000 +vt 0.5005 0.0619 0.0000 +vt 0.4742 0.2157 0.0000 +vt 0.3008 0.4876 0.0000 +vt 0.2923 0.4722 0.0000 +vt 0.0005 0.4015 0.0000 +vt 0.4068 0.7707 0.0000 +vt 0.4363 0.3405 0.0000 +vt 0.4123 0.2121 0.0000 +vt 0.3686 0.5816 0.0000 +vt 0.4912 0.3214 0.0000 +vt 0.4097 0.5625 0.0000 +vt 0.5005 0.4679 0.0000 +vt 0.2791 0.4819 0.0000 +vt 0.2919 0.4918 0.0000 +vt 0.2827 0.4994 0.0000 +vt 0.4738 0.3832 0.0000 +vt 0.4791 0.3668 0.0000 +vt 0.4334 0.5056 0.0000 +vt 0.0543 0.5378 0.0000 +vt 0.4456 0.4851 0.0000 +vt 0.4515 0.4542 0.0000 +vt 0.5005 0.3015 0.0000 +vt 0.4916 0.3521 0.0000 +vt 0.5008 0.2886 0.0000 +vt 0.5005 0.2309 0.0000 +vt 0.5005 0.2127 0.0000 +vt 0.4341 0.4127 0.0000 +vt 0.3949 0.5126 0.0000 +vt 0.3922 0.5039 0.0000 +vt 0.4020 0.5117 0.0000 +vt 0.4750 0.3572 0.0000 +vt 0.4057 0.5296 0.0000 +vt 0.4019 0.0857 0.0000 +vt 0.4541 0.2102 0.0000 +vt 0.0273 0.2648 0.0000 +vt 0.1148 0.2863 0.0000 +vt 0.5011 0.3651 0.0000 +vt 0.1987 0.2586 0.0000 +vt 0.4424 0.3354 0.0000 +vt 0.5008 0.3208 0.0000 +vt 0.4437 0.3275 0.0000 +vt 0.2981 0.5717 0.0000 +vt 0.4023 0.4956 0.0000 +vt 0.4203 0.4658 0.0000 +vt 0.2287 0.5259 0.0000 +vt 0.9848 0.4692 0.0000 +vt 0.9459 0.5412 0.0000 +vt 0.8720 0.5338 0.0000 +vt 0.5265 0.2472 0.0000 +vt 0.5278 0.2623 0.0000 +vt 0.6153 0.4824 0.0000 +vt 0.6078 0.4648 0.0000 +vt 0.6324 0.4475 0.0000 +vt 0.5545 0.2426 0.0000 +vt 0.5596 0.2542 0.0000 +vt 0.5894 0.4851 0.0000 +vt 0.5805 0.4662 0.0000 +vt 0.6005 0.4447 0.0000 +vt 0.5981 0.4959 0.0000 +vt 0.7226 0.6706 0.0000 +vt 0.7602 0.7091 0.0000 +vt 0.6771 0.7445 0.0000 +vt 0.5005 0.0005 0.0000 +vt 0.5712 0.0054 0.0000 +vt 0.7164 0.4194 0.0000 +vt 0.6676 0.4301 0.0000 +vt 0.6652 0.3982 0.0000 +vt 0.5782 0.2337 0.0000 +vt 0.5835 0.2407 0.0000 +vt 0.5670 0.6338 0.0000 +vt 0.5793 0.7023 0.0000 +vt 0.5645 0.3606 0.0000 +vt 0.5700 0.3722 0.0000 +vt 0.5539 0.3888 0.0000 +vt 0.5906 0.1168 0.0000 +vt 0.6014 0.0873 0.0000 +vt 0.6464 0.1140 0.0000 +vt 0.5984 0.2198 0.0000 +vt 0.6026 0.2235 0.0000 +vt 0.5728 0.2157 0.0000 +vt 0.5891 0.2097 0.0000 +vt 0.5936 0.2159 0.0000 +vt 0.6318 0.2428 0.0000 +vt 0.6677 0.4541 0.0000 +vt 0.6550 0.1736 0.0000 +vt 0.6842 0.1482 0.0000 +vt 0.7142 0.2035 0.0000 +vt 0.5379 0.1252 0.0000 +vt 0.5294 0.1616 0.0000 +vt 0.6140 0.2039 0.0000 +vt 0.5958 0.1986 0.0000 +vt 0.6018 0.1939 0.0000 +vt 0.6771 0.5351 0.0000 +vt 0.6938 0.5232 0.0000 +vt 0.7137 0.5456 0.0000 +vt 0.6110 0.5558 0.0000 +vt 0.5943 0.5303 0.0000 +vt 0.6034 0.5215 0.0000 +vt 0.6001 0.1616 0.0000 +vt 0.5710 0.1421 0.0000 +vt 0.7597 0.1494 0.0000 +vt 0.8115 0.1846 0.0000 +vt 0.7662 0.2292 0.0000 +vt 0.6177 0.3301 0.0000 +vt 0.5999 0.3550 0.0000 +vt 0.5771 0.3224 0.0000 +vt 0.8905 0.6045 0.0000 +vt 0.8310 0.6625 0.0000 +vt 0.7787 0.6346 0.0000 +vt 0.5151 0.4121 0.0000 +vt 0.5009 0.4119 0.0000 +vt 0.6876 0.4855 0.0000 +vt 0.6697 0.4878 0.0000 +vt 0.6640 0.4736 0.0000 +vt 0.5748 0.1915 0.0000 +vt 0.5804 0.1824 0.0000 +vt 0.6785 0.3296 0.0000 +vt 0.7003 0.2837 0.0000 +vt 0.7442 0.3013 0.0000 +vt 0.5459 0.0983 0.0000 +vt 0.5564 0.1701 0.0000 +vt 0.5539 0.1850 0.0000 +vt 0.5284 0.1787 0.0000 +vt 0.5005 0.1772 0.0000 +vt 0.6430 0.3002 0.0000 +vt 0.6430 0.3646 0.0000 +vt 0.6303 0.0280 0.0000 +vt 0.6132 0.0590 0.0000 +vt 0.6097 0.2674 0.0000 +vt 0.5849 0.2832 0.0000 +vt 0.5402 0.5378 0.0000 +vt 0.5678 0.5055 0.0000 +vt 0.5815 0.5092 0.0000 +vt 0.6558 0.5438 0.0000 +vt 0.6657 0.5712 0.0000 +vt 0.6354 0.5697 0.0000 +vt 0.7059 0.5124 0.0000 +vt 0.5430 0.4322 0.0000 +vt 0.5497 0.4544 0.0000 +vt 0.5233 0.4656 0.0000 +vt 0.5587 0.5950 0.0000 +vt 0.7543 0.4271 0.0000 +vt 0.7807 0.4461 0.0000 +vt 0.7504 0.4667 0.0000 +vt 0.5788 0.5343 0.0000 +vt 0.5917 0.5639 0.0000 +vt 0.5647 0.3278 0.0000 +vt 0.5418 0.3174 0.0000 +vt 0.5956 0.4123 0.0000 +vt 0.6156 0.3864 0.0000 +vt 0.6264 0.4223 0.0000 +vt 0.5542 0.3419 0.0000 +vt 0.5591 0.3514 0.0000 +vt 0.5393 0.3648 0.0000 +vt 0.6157 0.5115 0.0000 +vt 0.6086 0.5039 0.0000 +vt 0.6221 0.4943 0.0000 +vt 0.5841 0.3948 0.0000 +vt 0.5672 0.4138 0.0000 +vt 0.7110 0.1141 0.0000 +vt 0.7358 0.0748 0.0000 +vt 0.5756 0.4364 0.0000 +vt 0.6724 0.5841 0.0000 +vt 0.7053 0.5733 0.0000 +vt 0.7220 0.5927 0.0000 +vt 0.5098 0.3851 0.0000 +vt 0.5277 0.3835 0.0000 +vt 0.5323 0.4048 0.0000 +vt 0.5945 0.7713 0.0000 +vt 0.6251 0.1815 0.0000 +vt 0.6365 0.4674 0.0000 +vt 0.7583 0.4933 0.0000 +vt 0.7484 0.5253 0.0000 +vt 0.7302 0.5250 0.0000 +vt 0.7398 0.6069 0.0000 +vt 0.6925 0.6304 0.0000 +vt 0.6819 0.6101 0.0000 +vt 0.5160 0.3506 0.0000 +vt 0.5102 0.3521 0.0000 +vt 0.5188 0.3269 0.0000 +vt 0.7529 0.5667 0.0000 +vt 0.7737 0.5282 0.0000 +vt 0.8066 0.5304 0.0000 +vt 0.6068 0.2054 0.0000 +vt 0.5889 0.2094 0.0000 +vt 0.5914 0.2039 0.0000 +vt 0.7790 0.5747 0.0000 +vt 0.8264 0.4776 0.0000 +vt 0.8176 0.4259 0.0000 +vt 0.8998 0.4138 0.0000 +vt 0.8059 0.3678 0.0000 +vt 0.5123 0.3651 0.0000 +vt 0.5195 0.4396 0.0000 +vt 0.6613 0.2639 0.0000 +vt 0.6307 0.5044 0.0000 +vt 0.6418 0.4822 0.0000 +vt 0.5337 0.2895 0.0000 +vt 0.5524 0.0668 0.0000 +vt 0.6458 0.2115 0.0000 +vt 0.5245 0.3325 0.0000 +vt 0.6141 0.5347 0.0000 +vt 0.7909 0.4849 0.0000 +vt 0.6941 0.5613 0.0000 +vt 0.6256 0.1415 0.0000 +vt 0.6096 0.2049 0.0000 +vt 0.9000 0.3524 0.0000 +vt 0.5515 0.2303 0.0000 +vt 0.5709 0.3469 0.0000 +vt 0.5645 0.3412 0.0000 +vt 0.5747 0.2240 0.0000 +vt 0.6746 0.2107 0.0000 +vt 0.6652 0.0847 0.0000 +vt 0.6511 0.6939 0.0000 +vt 0.5274 0.4979 0.0000 +vt 0.7207 0.3628 0.0000 +vt 0.5729 0.2018 0.0000 +vt 0.6289 0.6150 0.0000 +vt 0.6339 0.6380 0.0000 +vt 0.5520 0.1991 0.0000 +vt 0.9949 0.3369 0.0000 +vt 0.9995 0.4038 0.0000 +vt 0.5281 0.1971 0.0000 +vt 0.6494 0.4952 0.0000 +vt 0.5698 0.2093 0.0000 +vt 0.5491 0.2099 0.0000 +vt 0.8023 0.1093 0.0000 +vt 0.8624 0.2316 0.0000 +vt 0.8703 0.1449 0.0000 +vt 0.5467 0.3737 0.0000 +vt 0.5529 0.2158 0.0000 +vt 0.6173 0.2034 0.0000 +vt 0.5588 0.0402 0.0000 +vt 0.5267 0.2312 0.0000 +vt 0.7295 0.5547 0.0000 +vt 0.6883 0.4705 0.0000 +vt 0.7097 0.4730 0.0000 +vt 0.7023 0.4497 0.0000 +vt 0.8959 0.4739 0.0000 +vt 0.5005 0.7724 0.0000 +vt 0.6340 0.5832 0.0000 +vt 0.5103 0.3214 0.0000 +vt 0.7183 0.5004 0.0000 +vt 0.7223 0.4825 0.0000 +vt 0.7349 0.4997 0.0000 +vt 0.5555 0.4858 0.0000 +vt 0.8313 0.5881 0.0000 +vt 0.6843 0.0486 0.0000 +vt 0.5357 0.3096 0.0000 +vt 0.5225 0.3673 0.0000 +vt 0.6052 0.5128 0.0000 +vt 0.5262 0.3575 0.0000 +vt 0.5981 0.5120 0.0000 +vt 0.5059 0.3513 0.0000 +vt 0.8860 0.2886 0.0000 +vt 0.9734 0.2673 0.0000 +vt 0.5380 0.3550 0.0000 +vt 0.8040 0.3108 0.0000 +vt 0.8029 0.2613 0.0000 +vt 0.5581 0.3352 0.0000 +vt 0.5573 0.3283 0.0000 +vt 0.7323 0.4549 0.0000 +vt 0.5458 0.3240 0.0000 +vt 0.9322 0.1972 0.0000 +vt 0.7099 0.4918 0.0000 +vt 0.2399 0.7066 0.0000 +vt 0.6343 0.5445 0.0000 +vt 0.5798 0.3590 0.0000 +vt 0.5256 0.2097 0.0000 +vt 0.5282 0.2152 0.0000 +vt 0.7007 0.4875 0.0000 +# 468 texture coords + + +vn -0.9892 0.0918 -0.1146 +vn -0.9788 0.0236 -0.2033 +vn -0.9677 -0.0121 -0.2518 +vn -0.0286 0.4641 -0.8853 +vn -0.0210 0.1059 -0.9942 +vn -0.2963 0.0263 -0.9547 +vn -0.2656 -0.3737 -0.8887 +vn -0.1333 -0.1062 -0.9854 +vn -0.2982 -0.3067 -0.9039 +vn -0.2701 0.4062 -0.8730 +vn -0.5118 0.1804 -0.8400 +vn -0.6858 -0.4508 -0.5714 +vn -0.4596 -0.4367 -0.7734 +vn -0.6024 -0.3459 -0.7194 +vn -0.6700 -0.2574 -0.6963 +vn -0.3874 -0.2160 -0.8962 +vn -0.4873 -0.2184 -0.8455 +vn -0.0187 0.7636 -0.6454 +vn -0.3895 0.6894 -0.6107 +vn -0.3730 0.8476 -0.3773 +vn -0.4425 -0.2135 -0.8710 +vn -0.6390 0.0497 -0.7676 +vn -0.3241 -0.1838 -0.9280 +vn -0.4361 0.4943 -0.7520 +vn -0.5509 0.4800 -0.6827 +vn -0.0096 0.1041 -0.9945 +vn -0.0117 -0.1221 -0.9924 +vn -0.2092 -0.1327 -0.9688 +vn -0.9011 0.2674 -0.3415 +vn -0.8776 0.0591 -0.4757 +vn -0.8804 -0.3287 -0.3418 +vn -0.5055 0.2486 -0.8262 +vn -0.5902 0.2855 -0.7551 +vn -0.6930 0.3322 -0.6398 +vn -0.4684 0.6694 -0.5766 +vn -0.4272 0.7368 -0.5240 +vn -0.2852 0.8727 -0.3964 +vn -0.3535 0.8216 -0.4473 +vn -0.3118 0.8767 -0.3662 +vn -0.5250 0.1467 -0.8384 +vn -0.4721 0.4437 -0.7617 +vn -0.2451 -0.0267 -0.9691 +vn -0.4187 -0.1407 -0.8972 +vn -0.5714 0.2908 -0.7675 +vn -0.5276 0.3879 -0.7558 +vn -0.7228 0.4014 -0.5625 +vn -0.1836 0.4449 -0.8765 +vn -0.0125 0.4693 -0.8829 +vn -0.0217 0.5490 -0.8355 +vn -0.7483 0.2841 -0.5994 +vn -0.4508 0.3894 -0.8032 +vn -0.7218 -0.1978 -0.6632 +vn -0.2589 0.4773 -0.8397 +vn -0.1985 0.5505 -0.8109 +vn -0.3127 0.5807 -0.7516 +vn -0.1325 0.5499 -0.8246 +vn 0.0988 0.3107 -0.9454 +vn -0.0383 0.4255 -0.9042 +vn -0.5889 0.2725 -0.7609 +vn -0.8103 0.4772 -0.3402 +vn -0.8348 0.3692 -0.4084 +vn -0.3030 -0.0161 -0.9529 +vn -0.4987 -0.0940 -0.8617 +vn -0.6857 0.2014 -0.6994 +vn -0.9601 -0.0063 -0.2796 +vn -0.9401 -0.0814 -0.3311 +vn -0.8443 -0.2348 -0.4818 +vn -0.5192 -0.4575 -0.7219 +vn -0.4560 -0.0053 -0.8899 +vn -0.0145 0.0191 -0.9997 +vn -0.4007 -0.1577 -0.9025 +vn -0.3961 -0.0224 -0.9179 +vn -0.1931 0.0337 -0.9806 +vn -0.6352 -0.3880 -0.6678 +vn -0.6957 0.1472 -0.7031 +vn -0.4450 0.1127 -0.8884 +vn -0.7920 0.2538 -0.5553 +vn -0.2588 0.1393 -0.9558 +vn -0.0160 0.0757 -0.9970 +vn -0.4640 0.3737 -0.8031 +vn -0.5965 -0.2402 -0.7659 +vn -0.5234 0.3510 -0.7764 +vn -0.2373 0.0020 -0.9714 +vn -0.2813 0.4791 -0.8315 +vn -0.3584 0.0892 -0.9293 +vn -0.2542 0.0002 -0.9671 +vn -0.6701 0.5630 -0.4837 +vn -0.7034 0.1121 -0.7019 +vn -0.6507 0.4083 -0.6402 +vn -0.7793 -0.1925 -0.5964 +vn -0.1515 0.3979 -0.9048 +vn -0.0209 0.3518 -0.9359 +vn -0.1058 0.5639 -0.8190 +vn -0.3450 0.6540 -0.6732 +vn -0.3752 0.7249 -0.5777 +vn -0.3356 0.6076 -0.7198 +vn -0.8198 -0.4081 -0.4018 +vn -0.6040 -0.5115 -0.6112 +vn -0.6003 -0.4769 -0.6420 +vn -0.8971 -0.1474 -0.4166 +vn -0.0088 -0.1756 -0.9844 +vn -0.0130 0.2566 -0.9664 +vn -0.6727 -0.1461 -0.7253 +vn -0.5253 -0.1978 -0.8276 +vn -0.5550 -0.1543 -0.8174 +vn -0.2962 0.5043 -0.8111 +vn -0.5151 0.3789 -0.7689 +vn -0.6769 0.4352 -0.5936 +vn -0.7119 -0.1376 -0.6887 +vn -0.3869 -0.2729 -0.8808 +vn -0.2593 0.9100 -0.3235 +vn -0.4232 0.8725 -0.2441 +vn -0.6388 0.6348 -0.4346 +vn 0.0075 -0.5272 -0.8497 +vn 0.1431 -0.3278 -0.9338 +vn 0.0417 -0.2968 -0.9540 +vn -0.9190 -0.2914 -0.2656 +vn -0.9525 -0.1975 -0.2320 +vn -0.8218 0.5259 -0.2193 +vn -0.7717 0.5717 -0.2788 +vn -0.8407 -0.2471 -0.4819 +vn -0.1589 0.6204 -0.7680 +vn -0.3844 0.3934 -0.8351 +vn -0.5135 0.2291 -0.8270 +vn -0.7775 -0.3931 -0.4910 +vn -0.7590 0.4870 -0.4321 +vn -0.5333 0.0772 -0.8424 +vn -0.2512 -0.2327 -0.9396 +vn -0.5037 0.2809 -0.8169 +vn -0.3684 0.3409 -0.8649 +vn -0.7436 -0.0832 -0.6634 +vn -0.6117 0.7847 -0.1002 +vn -0.5291 0.8080 -0.2592 +vn -0.4508 0.8443 -0.2898 +vn -0.6923 0.3110 -0.6511 +vn -0.8890 -0.0214 -0.4573 +vn -0.8997 0.1327 -0.4158 +vn -0.2615 0.0617 -0.9632 +vn -0.7042 -0.3851 -0.5965 +vn -0.4049 -0.7183 -0.5658 +vn -0.8981 0.0608 -0.4355 +vn -0.9788 0.1245 -0.1626 +vn -0.9079 0.1364 -0.3963 +vn -0.7298 -0.0858 -0.6783 +vn -0.4109 0.5683 -0.7129 +vn -0.2760 0.8715 -0.4054 +vn -0.0052 0.8916 -0.4528 +vn -0.4766 0.3068 -0.8238 +vn 0.0050 -0.1775 -0.9841 +vn -0.0091 -0.0562 -0.9984 +vn -0.3366 0.0198 -0.9414 +vn -0.3670 0.2717 -0.8897 +vn -0.3339 0.0046 -0.9426 +vn -0.3391 0.4495 -0.8264 +vn -0.6108 0.5190 -0.5979 +vn -0.7075 0.1706 -0.6858 +vn -0.4370 0.5756 -0.6911 +vn -0.1373 0.5563 -0.8196 +vn -0.6839 0.4104 -0.6032 +vn -0.4112 0.5547 -0.7234 +vn -0.9719 0.1950 -0.1316 +vn -0.8965 0.0314 -0.4419 +vn -0.3061 0.7640 -0.5679 +vn -0.2095 0.7295 -0.6511 +vn -0.6765 0.0404 -0.7353 +vn -0.7748 0.5551 -0.3026 +vn -0.3352 0.8062 -0.4875 +vn -0.9828 0.0737 -0.1690 +vn -0.6294 0.2746 -0.7270 +vn -0.4010 0.7990 -0.4481 +vn -0.7680 0.5065 -0.3919 +vn -0.7313 0.6102 -0.3048 +vn -0.6386 0.7024 -0.3143 +vn -0.5403 -0.0661 -0.8389 +vn -0.2972 0.0398 -0.9540 +vn -0.6776 -0.4136 -0.6081 +vn -0.0027 -0.5203 -0.8540 +vn -0.9184 0.2515 -0.3056 +vn -0.2748 0.5707 -0.7738 +vn -0.1584 0.1286 -0.9790 +vn -0.4616 -0.5618 -0.6866 +vn -0.4293 -0.0927 -0.8984 +vn -0.9793 0.1926 -0.0624 +vn -0.0161 -0.1523 -0.9882 +vn -0.2259 -0.2227 -0.9484 +vn -0.0197 -0.0720 -0.9972 +vn -0.2632 -0.1251 -0.9566 +vn -0.2093 -0.1177 -0.9707 +vn -0.4462 -0.5951 -0.6684 +vn -0.3734 -0.3688 -0.8512 +vn -0.4127 -0.7924 -0.4493 +vn -0.8775 0.4155 -0.2396 +vn -0.8941 0.4319 -0.1185 +vn -0.9429 0.3025 -0.1392 +vn -0.9468 0.3122 -0.0776 +vn -0.4967 0.7780 -0.3847 +vn -0.2129 0.8951 -0.3917 +vn -0.0010 -0.6457 -0.7636 +vn -0.0191 0.3220 -0.9466 +vn -0.2007 0.8540 -0.4801 +vn -0.5261 -0.2296 -0.8189 +vn -0.5469 -0.1438 -0.8248 +vn -0.9882 0.1379 -0.0665 +vn -0.2607 -0.1418 -0.9549 +vn -0.3010 0.8206 -0.4858 +vn -0.2486 0.9237 -0.2915 +vn -0.1986 0.7334 -0.6502 +vn -0.2171 0.9455 -0.2426 +vn -0.3870 0.6895 -0.6122 +vn -0.0087 -0.5839 -0.8117 +vn -0.5436 -0.1897 -0.8176 +vn -0.5570 -0.2589 -0.7891 +vn -0.4501 0.2685 -0.8516 +vn -0.7925 0.0362 -0.6087 +vn -0.6696 0.5211 -0.5292 +vn -0.8579 -0.2632 -0.4412 +vn -0.9774 0.0665 -0.2005 +vn -0.8059 -0.4189 -0.4185 +vn -0.8334 -0.3312 -0.4425 +vn -0.0113 0.7507 -0.6605 +vn -0.5000 0.8023 -0.3261 +vn -0.0179 0.1168 -0.9930 +vn -0.0280 0.7348 -0.6777 +vn -0.0341 0.8515 -0.5232 +vn -0.8728 -0.3807 -0.3053 +vn -0.2925 -0.1250 -0.9481 +vn -0.2521 -0.4913 -0.8337 +vn -0.5752 -0.1476 -0.8046 +vn -0.5558 0.7877 -0.2655 +vn -0.3244 0.4596 -0.8268 +vn -0.6118 0.2479 -0.7511 +vn -0.3883 -0.3420 -0.8557 +vn -0.9704 0.2327 -0.0645 +vn -0.9662 0.2260 -0.1243 +vn -0.0165 0.5612 -0.8275 +vn -0.8997 0.3056 -0.3117 +vn -0.1538 0.8423 -0.5165 +vn 0.0106 0.9761 -0.2172 +vn -0.4197 0.4256 -0.8017 +vn -0.2580 0.5206 -0.8139 +vn -0.5099 -0.4374 -0.7407 +vn -0.7786 -0.4123 -0.4731 +vn -0.6680 0.4185 -0.6154 +vn 0.9885 0.0946 -0.1177 +vn 0.9766 0.0763 -0.2009 +vn 0.9707 -0.0059 -0.2403 +vn 0.2175 0.4167 -0.8827 +vn 0.2655 0.0332 -0.9635 +vn 0.2465 -0.3758 -0.8933 +vn 0.4508 -0.4321 -0.7811 +vn 0.2787 -0.3017 -0.9118 +vn 0.3870 0.4936 -0.7788 +vn 0.4777 0.1827 -0.8593 +vn 0.6807 -0.4529 -0.5758 +vn 0.7749 -0.3960 -0.4927 +vn 0.5928 -0.3359 -0.7320 +vn 0.5041 -0.4457 -0.7397 +vn 0.6609 -0.2685 -0.7009 +vn 0.7711 -0.1906 -0.6075 +vn 0.4693 -0.2150 -0.8565 +vn -0.0176 0.9138 -0.4057 +vn 0.3385 0.8619 -0.3777 +vn 0.4241 -0.2022 -0.8827 +vn 0.2284 -0.2246 -0.9473 +vn 0.3009 -0.1708 -0.9382 +vn 0.4152 0.6914 -0.5913 +vn 0.5263 0.4569 -0.7171 +vn 0.1372 0.1315 -0.9818 +vn 0.1889 -0.1299 -0.9734 +vn 0.8941 0.2902 -0.3410 +vn 0.9565 -0.1796 -0.2300 +vn 0.8827 -0.3064 -0.3563 +vn 0.4749 0.2725 -0.8368 +vn 0.5803 0.2684 -0.7689 +vn 0.6698 0.3602 -0.6493 +vn 0.3502 0.8087 -0.4726 +vn 0.3789 0.7560 -0.5337 +vn 0.1939 0.9029 -0.3835 +vn 0.0992 0.9694 -0.2244 +vn 0.2482 0.8870 -0.3894 +vn 0.4589 0.4349 -0.7748 +vn 0.2199 -0.0208 -0.9753 +vn 0.5447 0.3217 -0.7745 +vn 0.6608 0.4456 -0.6039 +vn 0.7042 0.4225 -0.5706 +vn 0.1420 0.4548 -0.8792 +vn 0.2331 0.5063 -0.8303 +vn 0.8500 -0.0556 -0.5238 +vn 0.6186 -0.3893 -0.6824 +vn 0.7050 -0.2003 -0.6803 +vn 0.2278 0.4733 -0.8510 +vn 0.3290 0.5971 -0.7316 +vn 0.2896 0.5777 -0.7632 +vn 0.1057 0.5527 -0.8267 +vn 0.2923 0.4695 -0.8331 +vn 0.0250 0.4179 -0.9081 +vn 0.5611 0.3112 -0.7670 +vn 0.4233 0.4058 -0.8100 +vn 0.7948 0.5049 -0.3366 +vn 0.8680 0.4384 -0.2332 +vn 0.8266 0.3904 -0.4053 +vn 0.2732 -0.0165 -0.9618 +vn 0.6635 0.0658 -0.7453 +vn 0.6643 0.2138 -0.7162 +vn 0.9600 -0.0003 -0.2800 +vn 0.8960 -0.1414 -0.4210 +vn 0.8452 -0.2504 -0.4722 +vn 0.5089 -0.4481 -0.7350 +vn -0.0089 -0.4314 -0.9021 +vn 0.3708 -0.1626 -0.9144 +vn 0.1925 -0.1126 -0.9748 +vn 0.1658 0.0472 -0.9850 +vn 0.5831 -0.2210 -0.7818 +vn 0.6667 0.1757 -0.7243 +vn 0.4231 0.1187 -0.8983 +vn 0.6085 0.2868 -0.7400 +vn 0.7769 0.2723 -0.5677 +vn 0.2238 0.1445 -0.9639 +vn 0.4823 0.3914 -0.7837 +vn 0.4059 -0.0703 -0.9112 +vn 0.1984 0.0143 -0.9800 +vn -0.0156 0.0695 -0.9975 +vn 0.3273 0.0921 -0.9404 +vn 0.2286 0.0054 -0.9735 +vn 0.6102 0.7222 -0.3257 +vn 0.6443 0.5803 -0.4981 +vn 0.4969 0.1416 -0.8562 +vn 0.4749 -0.0910 -0.8753 +vn 0.6870 0.1214 -0.7165 +vn 0.8579 -0.2672 -0.4390 +vn 0.7796 -0.1825 -0.5992 +vn 0.1208 0.3971 -0.9098 +vn 0.1075 0.5451 -0.8314 +vn 0.0761 0.5486 -0.8326 +vn 0.3651 0.7087 -0.6037 +vn 0.8210 -0.3904 -0.4167 +vn 0.8331 -0.3228 -0.4492 +vn 0.5980 -0.4679 -0.6507 +vn 0.2695 0.5104 -0.8166 +vn 0.6652 -0.1336 -0.7347 +vn 0.7261 -0.0753 -0.6835 +vn 0.5408 -0.1514 -0.8274 +vn 0.6207 0.4346 -0.6526 +vn 0.3602 0.6969 -0.6202 +vn 0.2923 0.8174 -0.4963 +vn 0.6549 0.4616 -0.5984 +vn 0.7013 -0.1214 -0.7024 +vn 0.3127 0.0149 -0.9498 +vn 0.3730 -0.2646 -0.8893 +vn 0.2068 0.9225 -0.3261 +vn 0.4428 0.8057 -0.3933 +vn 0.6128 0.6523 -0.4461 +vn -0.0282 -0.5216 -0.8527 +vn 0.2269 -0.4823 -0.8461 +vn -0.0625 -0.2963 -0.9530 +vn 0.9255 -0.2612 -0.2742 +vn 0.8782 -0.3583 -0.3167 +vn 0.7431 0.5356 -0.4013 +vn 0.7497 0.5979 -0.2835 +vn 0.8369 -0.2377 -0.4930 +vn 0.1306 0.5947 -0.7933 +vn 0.2395 0.5098 -0.8263 +vn 0.4942 0.2256 -0.8396 +vn 0.4387 0.0211 -0.8984 +vn 0.7810 0.0588 -0.6218 +vn 0.7757 -0.3764 -0.5066 +vn 0.2367 -0.1436 -0.9609 +vn 0.5078 0.1003 -0.8556 +vn 0.1036 -0.1009 -0.9895 +vn 0.4829 0.2882 -0.8269 +vn 0.4273 0.5748 -0.6979 +vn 0.3231 0.6484 -0.6894 +vn 0.7422 -0.0986 -0.6628 +vn 0.5223 -0.0708 -0.8498 +vn 0.3597 0.3844 -0.8502 +vn 0.5795 0.8063 -0.1185 +vn 0.4603 0.8254 -0.3268 +vn 0.3691 0.8831 -0.2895 +vn 0.6861 0.3121 -0.6571 +vn 0.6473 0.4401 -0.6223 +vn 0.8993 0.1483 -0.4114 +vn 0.2468 0.0393 -0.9683 +vn 0.4702 -0.7357 -0.4875 +vn 0.4528 -0.6808 -0.5758 +vn 0.8966 -0.0343 -0.4415 +vn 0.8987 0.0843 -0.4303 +vn 0.8959 0.0466 -0.4419 +vn 0.9774 0.1340 -0.1635 +vn 0.9007 0.1575 -0.4050 +vn 0.3724 0.5882 -0.7179 +vn 0.6001 -0.5021 -0.6227 +vn 0.4579 0.3117 -0.8325 +vn -0.1567 -0.3306 -0.9307 +vn -0.0155 -0.0506 -0.9986 +vn 0.3119 0.0191 -0.9499 +vn 0.3392 0.2827 -0.8972 +vn 0.3362 0.4579 -0.8230 +vn 0.5374 0.7997 -0.2676 +vn -0.1332 0.2907 -0.9475 +vn 0.7012 0.1840 -0.6888 +vn 0.1714 0.5455 -0.8204 +vn 0.5580 0.3128 -0.7686 +vn 0.5971 0.3016 -0.7433 +vn 0.9675 0.2147 -0.1340 +vn 0.2314 0.7831 -0.5773 +vn 0.7580 0.5782 -0.3018 +vn 0.2670 0.8375 -0.4768 +vn 0.2693 0.8599 -0.4336 +vn 0.5067 0.3950 -0.7663 +vn 0.7394 0.5132 -0.4357 +vn 0.3673 -0.2156 -0.9047 +vn 0.6777 -0.3981 -0.6182 +vn 0.6185 0.0661 -0.7830 +vn 0.4711 -0.5517 -0.6882 +vn 0.2506 0.5734 -0.7800 +vn 0.2726 0.0404 -0.9613 +vn 0.3665 -0.3395 -0.8662 +vn 0.9744 0.2145 -0.0671 +vn 0.9857 0.1509 -0.0744 +vn 0.2074 -0.2071 -0.9561 +vn -0.0326 -0.1888 -0.9815 +vn 0.4509 -0.5767 -0.6812 +vn 0.3959 -0.2961 -0.8693 +vn 0.8077 0.5514 -0.2088 +vn 0.9332 0.3326 -0.1365 +vn 0.8820 0.4566 -0.1162 +vn 0.8617 0.1065 -0.4962 +vn 0.1504 0.9084 -0.3900 +vn 0.4885 0.3529 -0.7980 +vn 0.3556 0.7052 -0.6134 +vn 0.1387 0.7361 -0.6625 +vn 0.3951 0.5494 -0.7363 +vn 0.3690 -0.0160 -0.9293 +vn 0.5278 -0.1434 -0.8372 +vn 0.3953 -0.1320 -0.9090 +vn 0.9794 0.0344 -0.1991 +vn -0.0106 -0.1659 -0.9861 +vn 0.1745 0.7218 -0.6697 +vn 0.1633 0.9568 -0.2405 +vn 0.4306 0.2942 -0.8532 +vn 0.5371 -0.1872 -0.8225 +vn 0.3508 0.3438 -0.8710 +vn 0.8106 -0.3958 -0.4315 +vn 0.9431 -0.0884 -0.3207 +vn 0.7107 0.6303 -0.3125 +vn 0.4906 0.3956 -0.7764 +vn 0.6379 0.5420 -0.5471 +vn 0.2648 -0.1351 -0.9548 +vn 0.5070 0.8298 -0.2331 +vn 0.5564 -0.1294 -0.8208 +vn 0.2610 0.8806 -0.3955 +vn 0.9583 0.2570 -0.1252 +vn 0.9614 0.2663 -0.0692 +vn 0.3949 0.8811 -0.2603 +vn 0.9102 0.2754 -0.3092 +vn 0.8881 0.3375 -0.3120 +vn 0.1150 0.8695 -0.4803 +vn 0.3658 0.4631 -0.8073 +vn 0.5063 -0.1983 -0.8392 +vn 0.5772 0.5500 -0.6036 +vn 0.9361 0.3433 -0.0766 +vn 0.5392 -0.2542 -0.8029 +vn -0.7761 -0.1922 -0.6006 +vn -0.0115 0.3481 -0.9374 +vn 0.9827 0.0780 -0.1680 +vn 0.2198 -0.1358 -0.9660 +vn 0.1342 0.8481 -0.5125 +vn 0.4880 -0.2447 -0.8379 +# 468 vertex normals + +#o default g default -usemtl default -f 1/1/1 2/2/2 3/3/3 -f 4/4/4 5/5/5 6/6/6 -f 7/7/7 8/8/8 9/9/9 -f 10/10/10 6/6/6 11/11/11 -f 12/12/12 13/13/13 14/14/14 -f 7/7/7 13/13/13 12/12/12 -f 15/15/15 16/16/16 17/17/17 -f 18/18/18 19/19/19 20/20/20 -f 21/21/21 22/22/22 23/23/23 -f 24/24/24 11/11/11 25/25/25 -f 26/26/26 27/27/27 28/28/28 -f 29/29/29 30/30/30 31/31/31 -f 32/32/32 33/33/33 34/34/34 -f 35/35/35 25/25/25 36/36/36 -f 37/37/37 38/38/38 39/39/39 -f 25/25/25 40/40/40 41/41/41 -f 42/42/42 43/43/43 21/21/21 -f 44/44/44 45/45/45 46/46/46 -f 47/47/47 48/48/48 49/49/49 -f 50/50/50 51/51/51 52/52/52 -f 53/53/53 54/54/54 55/55/55 -f 56/56/56 57/57/57 58/58/58 -f 59/59/59 33/33/33 32/32/32 -f 60/60/60 46/46/46 61/61/61 -f 62/62/62 63/63/63 64/64/64 -f 65/65/65 66/66/66 67/67/67 -f 68/68/68 69/69/69 70/70/70 -f 71/71/71 72/72/72 73/73/73 -f 74/74/74 52/52/52 75/75/75 -f 76/76/76 22/22/22 77/77/77 -f 78/78/78 79/79/79 48/48/48 -f 75/75/75 59/59/59 80/80/80 -f 81/81/81 75/75/75 82/82/82 -f 83/83/83 84/84/84 49/49/49 -f 85/85/85 62/62/62 86/86/86 -f 20/20/20 19/19/19 87/87/87 -f 40/40/40 25/25/25 11/11/11 -f 88/88/88 89/89/89 90/90/90 -f 91/91/91 92/92/92 93/93/93 -f 94/94/94 95/95/95 96/96/96 -f 97/97/97 98/98/98 99/99/99 -f 100/100/100 67/67/67 15/15/15 -f 88/88/88 101/101/101 102/102/102 -f 103/103/103 104/104/104 105/105/105 -f 89/89/89 88/88/88 106/106/106 -f 64/64/64 107/107/107 108/108/108 -f 109/109/109 14/14/14 110/110/110 -f 111/111/111 112/112/112 113/113/113 -f 114/114/114 115/115/115 116/116/116 -f 117/117/117 118/118/118 31/31/31 -f 60/60/60 119/119/119 120/120/120 -f 14/14/14 109/109/109 121/121/121 -f 122/122/122 123/123/123 124/124/124 -f 69/69/69 68/68/68 125/125/125 -f 34/34/34 126/126/126 87/87/87 -f 17/17/17 16/16/16 28/28/28 -f 127/127/127 59/59/59 75/75/75 -f 42/42/42 128/128/128 9/9/9 -f 129/129/129 130/130/130 94/94/94 -f 131/131/131 124/124/124 123/123/123 -f 132/132/132 133/133/133 134/134/134 -f 135/135/135 136/136/136 137/137/137 -f 138/138/138 139/139/139 140/140/140 -f 135/135/135 124/124/124 131/131/131 -f 141/141/141 2/2/2 142/142/142 -f 143/143/143 103/103/103 144/144/144 -f 145/145/145 146/146/146 147/147/147 -f 97/97/97 125/125/125 68/68/68 -f 148/148/148 85/85/85 76/76/76 -f 115/115/115 149/149/149 150/150/150 -f 11/11/11 6/6/6 151/151/151 -f 79/79/79 78/78/78 152/152/152 -f 86/86/86 153/153/153 110/110/110 -f 154/154/154 45/45/45 44/44/44 -f 133/133/133 155/155/155 108/108/108 -f 93/93/93 92/92/92 57/57/57 -f 156/156/156 129/129/129 157/157/157 -f 53/53/53 91/91/91 158/158/158 -f 33/33/33 44/44/44 159/159/159 -f 157/157/157 160/160/160 135/135/135 -f 127/127/127 44/44/44 33/33/33 -f 139/139/139 50/50/50 74/74/74 -f 161/161/161 143/143/143 162/162/162 -f 163/163/163 164/164/164 10/10/10 -f 62/62/62 165/165/165 153/153/153 -f 166/166/166 64/64/64 167/167/167 -f 118/118/118 168/168/168 166/166/166 -f 163/163/163 24/24/24 35/35/35 -f 45/45/45 148/148/148 169/169/169 -f 38/38/38 35/35/35 170/170/170 -f 171/171/171 126/126/126 34/34/34 -f 126/126/126 172/172/172 173/173/173 -f 174/174/174 175/175/175 16/16/16 -f 176/176/176 177/177/177 101/101/101 -f 143/143/143 178/178/178 77/77/77 -f 140/140/140 74/74/74 81/81/81 -f 179/179/179 106/106/106 180/180/180 -f 181/181/181 81/81/81 182/182/182 -f 23/23/23 110/110/110 9/9/9 -f 131/131/131 174/174/174 15/15/15 -f 183/183/183 161/161/161 142/142/142 -f 184/184/184 185/185/185 83/83/83 -f 165/165/165 168/168/168 118/118/118 -f 186/186/186 187/187/187 185/185/185 -f 106/106/106 102/102/102 26/26/26 -f 110/110/110 14/14/14 13/13/13 -f 188/188/188 73/73/73 150/150/150 -f 189/189/189 181/181/181 190/190/190 -f 177/177/177 176/176/176 99/99/99 -f 189/189/189 191/191/191 140/140/140 -f 192/192/192 193/193/193 119/119/119 -f 194/194/194 195/195/195 193/193/193 -f 30/30/30 29/29/29 196/196/196 -f 38/38/38 37/37/37 197/197/197 -f 198/198/198 98/98/98 68/68/68 -f 127/127/127 52/52/52 51/51/51 -f 19/19/19 18/18/18 199/199/199 -f 197/197/197 200/200/200 164/164/164 -f 124/124/124 135/135/135 160/160/160 -f 71/71/71 201/201/201 202/202/202 -f 123/123/123 179/179/179 175/175/175 -f 43/43/43 104/104/104 103/103/103 -f 2/2/2 1/1/1 203/203/203 -f 180/180/180 28/28/28 16/16/16 -f 204/204/204 28/28/28 27/27/27 -f 29/29/29 166/166/166 205/205/205 -f 139/139/139 138/138/138 206/206/206 -f 165/165/165 117/117/117 109/109/109 -f 144/144/144 156/156/156 141/141/141 -f 103/103/103 143/143/143 22/22/22 -f 207/207/207 179/179/179 123/123/123 -f 147/147/147 146/146/146 208/208/208 -f 209/209/209 106/106/106 179/179/179 -f 98/98/98 198/198/198 210/210/210 -f 211/211/211 212/212/212 213/213/213 -f 214/214/214 215/215/215 145/145/145 -f 136/136/136 66/66/66 3/3/3 -f 176/176/176 88/88/88 216/216/216 -f 94/94/94 130/130/130 213/213/213 -f 66/66/66 65/65/65 217/217/217 -f 126/126/126 171/171/171 120/120/120 -f 218/218/218 219/219/219 99/99/99 -f 148/148/148 41/41/41 40/40/40 -f 220/220/220 107/107/107 151/151/151 -f 208/208/208 146/146/146 221/221/221 -f 222/222/222 151/151/151 6/6/6 -f 10/10/10 164/164/164 223/223/223 -f 164/164/164 200/200/200 224/224/224 -f 131/131/131 67/67/67 66/66/66 -f 129/129/129 156/156/156 144/144/144 -f 23/23/23 22/22/22 76/76/76 -f 85/85/85 40/40/40 63/63/63 -f 117/117/117 225/225/225 121/121/121 -f 63/63/63 151/151/151 107/107/107 -f 214/214/214 30/30/30 113/113/113 -f 226/226/226 227/227/227 228/228/228 -f 229/229/229 132/132/132 221/221/221 -f 46/46/46 60/60/60 171/171/171 -f 230/230/230 58/58/58 226/226/226 -f 19/19/19 152/152/152 231/231/231 -f 146/146/146 145/145/145 215/215/215 -f 185/185/185 187/187/187 232/232/232 -f 83/83/83 185/185/185 190/190/190 -f 84/84/84 83/83/83 182/182/182 -f 47/47/47 84/84/84 82/82/82 -f 78/78/78 47/47/47 80/80/80 -f 161/161/161 183/183/183 233/233/233 -f 50/50/50 139/139/139 39/39/39 -f 51/51/51 50/50/50 170/170/170 -f 154/154/154 51/51/51 36/36/36 -f 45/45/45 154/154/154 41/41/41 -f 46/46/46 169/169/169 77/77/77 -f 2/2/2 141/141/141 137/137/137 -f 112/112/112 229/229/229 215/215/215 -f 143/143/143 161/161/161 234/234/234 -f 145/145/145 235/235/235 70/70/70 -f 78/78/78 32/32/32 231/231/231 -f 166/166/166 168/168/168 165/165/165 -f 236/236/236 194/194/194 192/192/192 -f 237/237/237 111/111/111 196/196/196 -f 134/134/134 108/108/108 107/107/107 -f 220/220/220 238/238/238 208/208/208 -f 239/239/239 237/237/237 205/205/205 -f 72/72/72 202/202/202 104/104/104 -f 211/211/211 130/130/130 129/129/129 -f 73/73/73 72/72/72 43/43/43 -f 150/150/150 73/73/73 42/42/42 -f 116/116/116 150/150/150 8/8/8 -f 227/227/227 116/116/116 7/7/7 -f 89/89/89 230/230/230 228/228/228 -f 209/209/209 56/56/56 230/230/230 -f 93/93/93 56/56/56 209/209/209 -f 158/158/158 93/93/93 207/207/207 -f 54/54/54 158/158/158 122/122/122 -f 55/55/55 54/54/54 240/240/240 -f 94/94/94 55/55/55 160/160/160 -f 132/132/132 112/112/112 133/133/133 -f 111/111/111 237/237/237 239/239/239 -f 155/155/155 239/239/239 167/167/167 -f 178/178/178 234/234/234 194/194/194 -f 133/133/133 112/112/112 111/111/111 -f 77/77/77 178/178/178 236/236/236 -f 227/227/227 241/241/241 90/90/90 -f 241/241/241 12/12/12 216/216/216 -f 12/12/12 242/242/242 218/218/218 -f 242/242/242 121/121/121 219/219/219 -f 31/31/31 30/30/30 214/214/214 -f 121/121/121 225/225/225 97/97/97 -f 225/225/225 31/31/31 125/125/125 -f 234/234/234 233/233/233 195/195/195 -f 141/141/141 156/156/156 243/243/243 -f 202/202/202 201/201/201 212/212/212 -f 104/104/104 202/202/202 211/211/211 -f 244/244/244 245/245/245 246/246/246 -f 4/4/4 247/247/247 248/248/248 -f 249/249/249 250/250/250 251/251/251 -f 247/247/247 252/252/252 253/253/253 -f 254/254/254 255/255/255 256/256/256 -f 249/249/249 257/257/257 254/254/254 -f 258/258/258 259/259/259 260/260/260 -f 18/18/18 261/261/261 262/262/262 -f 263/263/263 264/264/264 265/265/265 -f 252/252/252 266/266/266 267/267/267 -f 26/26/26 268/268/268 269/269/269 -f 270/270/270 271/271/271 272/272/272 -f 273/273/273 274/274/274 275/275/275 -f 266/266/266 276/276/276 277/277/277 -f 278/278/278 279/279/279 280/280/280 -f 267/267/267 277/277/277 281/281/281 -f 282/282/282 264/264/264 263/263/263 -f 283/283/283 284/284/284 285/285/285 -f 286/286/286 287/287/287 49/49/49 -f 288/288/288 289/289/289 290/290/290 -f 291/291/291 292/292/292 293/293/293 -f 294/294/294 295/295/295 296/296/296 -f 297/297/297 298/298/298 273/273/273 -f 299/299/299 300/300/300 301/301/301 -f 302/302/302 303/303/303 304/304/304 -f 305/305/305 306/306/306 307/307/307 -f 308/308/308 309/309/309 70/70/70 -f 310/310/310 311/311/311 312/312/312 -f 289/289/289 313/313/313 314/314/314 -f 315/315/315 316/316/316 317/317/317 -f 318/318/318 286/286/286 48/48/48 -f 314/314/314 319/319/319 298/298/298 -f 313/313/313 320/320/320 319/319/319 -f 321/321/321 322/322/322 49/49/49 -f 323/323/323 315/315/315 324/324/324 -f 262/262/262 325/325/325 326/326/326 -f 327/327/327 328/328/328 253/253/253 -f 329/329/329 330/330/330 331/331/331 -f 332/332/332 333/333/333 334/334/334 -f 335/335/335 293/293/293 292/292/292 -f 336/336/336 337/337/337 338/338/338 -f 306/306/306 259/259/259 258/258/258 -f 329/329/329 339/339/339 102/102/102 -f 340/340/340 341/341/341 342/342/342 -f 343/343/343 344/344/344 339/339/339 -f 304/304/304 345/345/345 346/346/346 -f 347/347/347 348/348/348 349/349/349 -f 350/350/350 351/351/351 352/352/352 -f 353/353/353 354/354/354 355/355/355 -f 356/356/356 357/357/357 272/272/272 -f 299/299/299 358/358/358 359/359/359 -f 256/256/256 255/255/255 360/360/360 -f 361/361/361 362/362/362 363/363/363 -f 364/364/364 365/365/365 366/366/366 -f 275/275/275 274/274/274 326/326/326 -f 260/260/260 367/367/367 269/269/269 -f 368/368/368 290/290/290 314/314/314 -f 282/282/282 369/369/369 251/251/251 -f 370/370/370 371/371/371 372/372/372 -f 373/373/373 374/374/374 375/375/375 -f 376/376/376 377/377/377 378/378/378 -f 379/379/379 380/380/380 381/381/381 -f 382/382/382 383/383/383 384/384/384 -f 379/379/379 385/385/385 373/373/373 -f 386/386/386 387/387/387 388/388/388 -f 389/389/389 387/387/387 341/341/341 -f 390/390/390 235/235/235 147/147/147 -f 336/336/336 391/391/391 308/308/308 -f 392/392/392 316/316/316 315/315/315 -f 393/393/393 355/355/355 394/394/394 -f 253/253/253 328/328/328 395/395/395 -f 79/79/79 199/199/199 396/396/396 -f 324/324/324 265/265/265 349/349/349 -f 397/397/397 368/368/368 283/283/283 -f 398/398/398 378/378/378 346/346/346 -f 334/334/334 294/294/294 399/399/399 -f 400/400/400 380/380/380 371/371/371 -f 291/291/291 401/401/401 333/333/333 -f 402/402/402 275/275/275 284/284/284 -f 371/371/371 380/380/380 379/379/379 -f 368/368/368 297/297/297 402/402/402 -f 403/403/403 384/384/384 289/289/289 -f 404/404/404 388/388/388 387/387/387 -f 405/405/405 252/252/252 247/247/247 -f 302/302/302 324/324/324 348/348/348 -f 406/406/406 407/407/407 345/345/345 -f 271/271/271 270/270/270 406/406/406 -f 405/405/405 408/408/408 266/266/266 -f 409/409/409 285/285/285 316/316/316 -f 408/408/408 280/280/280 276/276/276 -f 358/358/358 284/284/284 275/275/275 -f 410/410/410 326/326/326 325/325/325 -f 374/374/374 258/258/258 411/411/411 -f 412/412/412 329/329/329 101/101/101 -f 389/389/389 413/413/413 317/317/317 -f 384/384/384 414/414/414 313/313/313 -f 415/415/415 416/416/416 268/268/268 -f 414/414/414 417/417/417 320/320/320 -f 265/265/265 264/264/264 251/251/251 -f 373/373/373 307/307/307 258/258/258 -f 418/418/418 419/419/419 388/388/388 -f 184/184/184 322/322/322 321/321/321 -f 303/303/303 356/356/356 271/271/271 -f 186/186/186 184/184/184 420/420/420 -f 339/339/339 268/268/268 26/26/26 -f 349/349/349 251/251/251 250/250/250 -f 311/311/311 421/421/421 394/394/394 -f 422/422/422 423/423/423 417/417/417 -f 177/177/177 210/210/210 338/338/338 -f 422/422/422 414/414/414 384/384/384 -f 300/300/300 299/299/299 424/424/424 -f 425/425/425 300/300/300 426/426/426 -f 427/427/427 352/352/352 351/351/351 -f 408/408/408 405/405/405 428/428/428 -f 198/198/198 309/309/309 308/308/308 -f 368/368/368 397/397/397 429/429/429 -f 430/430/430 396/396/396 199/199/199 -f 428/428/428 405/405/405 431/431/431 -f 363/363/363 362/362/362 432/432/432 -f 310/310/310 433/433/433 434/434/434 -f 375/375/375 374/374/374 416/416/416 -f 435/435/435 263/263/263 340/340/340 -f 436/436/436 388/388/388 419/419/419 -f 268/268/268 416/416/416 411/411/411 -f 367/367/367 437/437/437 27/27/27 -f 270/270/270 351/351/351 407/407/407 -f 403/403/403 280/280/280 279/279/279 -f 303/303/303 348/348/348 347/347/347 -f 341/341/341 387/387/387 386/386/386 -f 340/340/340 263/263/263 413/413/413 -f 438/438/438 361/361/361 375/375/375 -f 147/147/147 238/238/238 439/439/439 -f 344/344/344 438/438/438 415/415/415 -f 391/391/391 338/338/338 210/210/210 -f 440/440/440 441/441/441 442/442/442 -f 365/365/365 364/364/364 390/390/390 -f 385/385/385 381/381/381 246/246/246 -f 412/412/412 443/443/443 330/330/330 -f 440/440/440 372/372/372 335/335/335 -f 444/444/444 246/246/246 245/245/245 -f 410/410/410 445/445/445 359/359/359 -f 443/443/443 412/412/412 338/338/338 -f 392/392/392 323/323/323 327/327/327 -f 220/220/220 222/222/222 395/395/395 -f 439/439/439 378/378/378 377/377/377 -f 222/222/222 5/5/5 248/248/248 -f 247/247/247 4/4/4 223/223/223 -f 431/431/431 223/223/223 224/224/224 -f 373/373/373 385/385/385 444/444/444 -f 370/370/370 342/342/342 341/341/341 -f 265/265/265 324/324/324 315/315/315 -f 323/323/323 302/302/302 328/328/328 -f 356/356/356 347/347/347 360/360/360 -f 328/328/328 304/304/304 446/446/446 -f 365/365/365 447/447/447 352/352/352 -f 354/354/354 353/353/353 448/448/448 -f 449/449/449 447/447/447 377/377/377 -f 285/285/285 284/284/284 358/358/358 -f 295/295/295 450/450/450 448/448/448 -f 430/430/430 326/326/326 274/274/274 -f 451/451/451 377/377/377 447/447/447 -f 420/420/420 417/417/417 423/423/423 -f 321/321/321 320/320/320 417/417/417 -f 287/287/287 319/319/319 320/320/320 -f 286/286/286 298/298/298 319/319/319 -f 318/318/318 273/273/273 298/298/298 -f 404/404/404 452/452/452 453/453/453 -f 288/288/288 276/276/276 280/280/280 -f 429/429/429 277/277/277 276/276/276 -f 397/397/397 281/281/281 277/277/277 -f 409/409/409 392/392/392 281/281/281 -f 285/285/285 301/301/301 317/317/317 -f 436/436/436 246/246/246 381/381/381 -f 454/454/454 352/352/352 447/447/447 -f 389/389/389 455/455/455 452/452/452 -f 390/390/390 364/364/364 70/70/70 -f 318/318/318 396/396/396 274/274/274 -f 406/406/406 304/304/304 303/303/303 -f 456/456/456 301/301/301 300/300/300 -f 457/457/457 407/407/407 351/351/351 -f 378/378/378 439/439/439 446/446/446 -f 220/220/220 446/446/446 439/439/439 -f 458/458/458 345/345/345 407/407/407 -f 433/433/433 435/435/435 459/459/459 -f 441/441/441 342/342/342 370/370/370 -f 312/312/312 282/282/282 435/435/435 -f 394/394/394 369/369/369 282/282/282 -f 355/355/355 249/249/249 369/369/369 -f 354/354/354 257/257/257 249/249/249 -f 343/343/343 331/331/331 450/450/450 -f 344/344/344 343/343/343 295/295/295 -f 334/334/334 438/438/438 344/344/344 -f 333/333/333 361/361/361 438/438/438 -f 401/401/401 362/362/362 361/361/361 -f 293/293/293 432/432/432 362/362/362 -f 372/372/372 371/371/371 432/432/432 -f 449/449/449 376/376/376 398/398/398 -f 457/457/457 350/350/350 460/460/460 -f 460/460/460 346/346/346 345/345/345 -f 455/455/455 456/456/456 425/425/425 -f 398/398/398 460/460/460 350/350/350 -f 317/317/317 301/301/301 456/456/456 -f 354/354/354 450/450/450 331/331/331 -f 257/257/257 331/331/331 330/330/330 -f 254/254/254 330/330/330 443/443/443 -f 255/255/255 443/443/443 337/337/337 -f 272/272/272 366/366/366 365/365/365 -f 360/360/360 337/337/337 336/336/336 -f 357/357/357 336/336/336 366/366/366 -f 452/452/452 425/425/425 461/461/461 -f 386/386/386 381/381/381 380/380/380 -f 434/434/434 441/441/441 462/462/462 -f 459/459/459 342/342/342 441/441/441 -f 226/226/226 228/228/228 230/230/230 -f 226/226/226 114/114/114 227/227/227 -f 213/213/213 95/95/95 94/94/94 -f 213/213/213 130/130/130 211/211/211 -f 296/296/296 399/399/399 294/294/294 -f 448/448/448 296/296/296 295/295/295 -f 448/448/448 450/450/450 354/354/354 -f 440/440/440 442/442/442 372/372/372 -f 440/440/440 462/462/462 441/441/441 -f 335/335/335 372/372/372 293/293/293 -f 239/239/239 155/155/155 111/111/111 -f 132/132/132 229/229/229 112/112/112 -f 217/217/217 1/1/1 3/3/3 -f 10/10/10 4/4/4 6/6/6 -f 13/13/13 7/7/7 9/9/9 -f 24/24/24 10/10/10 11/11/11 -f 242/242/242 12/12/12 14/14/14 -f 241/241/241 7/7/7 12/12/12 -f 463/463/463 15/15/15 17/17/17 -f 261/261/261 18/18/18 20/20/20 -f 128/128/128 21/21/21 23/23/23 -f 35/35/35 24/24/24 25/25/25 -f 180/180/180 26/26/26 28/28/28 -f 118/118/118 29/29/29 31/31/31 -f 231/231/231 32/32/32 34/34/34 -f 170/170/170 35/35/35 36/36/36 -f 206/206/206 37/37/37 39/39/39 -f 36/36/36 25/25/25 41/41/41 -f 128/128/128 42/42/42 21/21/21 -f 159/159/159 44/44/44 46/46/46 -f 84/84/84 47/47/47 49/49/49 -f 74/74/74 50/50/50 52/52/52 -f 96/96/96 53/53/53 55/55/55 -f 230/230/230 56/56/56 58/58/58 -f 80/80/80 59/59/59 32/32/32 -f 192/192/192 60/60/60 61/61/61 -f 165/165/165 62/62/62 64/64/64 -f 100/100/100 65/65/65 67/67/67 -f 309/309/309 68/68/68 70/70/70 -f 188/188/188 71/71/71 73/73/73 -f 81/81/81 74/74/74 75/75/75 -f 169/169/169 76/76/76 77/77/77 -f 47/47/47 78/78/78 48/48/48 -f 82/82/82 75/75/75 80/80/80 -f 182/182/182 81/81/81 82/82/82 -f 322/322/322 83/83/83 49/49/49 -f 76/76/76 85/85/85 86/86/86 -f 173/173/173 20/20/20 87/87/87 -f 63/63/63 40/40/40 11/11/11 -f 216/216/216 88/88/88 90/90/90 -f 158/158/158 91/91/91 93/93/93 -f 55/55/55 94/94/94 96/96/96 -f 219/219/219 97/97/97 99/99/99 -f 463/463/463 100/100/100 15/15/15 -f 106/106/106 88/88/88 102/102/102 -f 144/144/144 103/103/103 105/105/105 -f 209/209/209 89/89/89 106/106/106 -f 167/167/167 64/64/64 108/108/108 -f 153/153/153 109/109/109 110/110/110 -f 196/196/196 111/111/111 113/113/113 -f 227/227/227 114/114/114 116/116/116 -f 225/225/225 117/117/117 31/31/31 -f 171/171/171 60/60/60 120/120/120 -f 242/242/242 14/14/14 121/121/121 -f 240/240/240 122/122/122 124/124/124 -f 214/214/214 69/69/69 125/125/125 -f 231/231/231 34/34/34 87/87/87 -f 204/204/204 17/17/17 28/28/28 -f 52/52/52 127/127/127 75/75/75 -f 8/8/8 42/42/42 9/9/9 -f 157/157/157 129/129/129 94/94/94 -f 174/174/174 131/131/131 123/123/123 -f 221/221/221 132/132/132 134/134/134 -f 243/243/243 135/135/135 137/137/137 -f 191/191/191 138/138/138 140/140/140 -f 136/136/136 135/135/135 131/131/131 -f 162/162/162 141/141/141 142/142/142 -f 162/162/162 143/143/143 144/144/144 -f 235/235/235 145/145/145 147/147/147 -f 98/98/98 97/97/97 68/68/68 -f 169/169/169 148/148/148 76/76/76 -f 116/116/116 115/115/115 150/150/150 -f 63/63/63 11/11/11 151/151/151 -f 199/199/199 79/79/79 152/152/152 -f 23/23/23 86/86/86 110/110/110 -f 127/127/127 154/154/154 44/44/44 -f 134/134/134 133/133/133 108/108/108 -f 56/56/56 93/93/93 57/57/57 -f 243/243/243 156/156/156 157/157/157 -f 54/54/54 53/53/53 158/158/158 -f 34/34/34 33/33/33 159/159/159 -f 243/243/243 157/157/157 135/135/135 -f 59/59/59 127/127/127 33/33/33 -f 140/140/140 139/139/139 74/74/74 -f 142/142/142 161/161/161 162/162/162 -f 24/24/24 163/163/163 10/10/10 -f 86/86/86 62/62/62 153/153/153 -f 205/205/205 166/166/166 167/167/167 -f 29/29/29 118/118/118 166/166/166 -f 38/38/38 163/163/163 35/35/35 -f 46/46/46 45/45/45 169/169/169 -f 39/39/39 38/38/38 170/170/170 -f 159/159/159 171/171/171 34/34/34 -f 87/87/87 126/126/126 173/173/173 -f 15/15/15 174/174/174 16/16/16 -f 88/88/88 176/176/176 101/101/101 -f 22/22/22 143/143/143 77/77/77 -f 181/181/181 140/140/140 81/81/81 -f 175/175/175 179/179/179 180/180/180 -f 190/190/190 181/181/181 182/182/182 -f 128/128/128 23/23/23 9/9/9 -f 67/67/67 131/131/131 15/15/15 -f 203/203/203 183/183/183 142/142/142 -f 322/322/322 184/184/184 83/83/83 -f 117/117/117 165/165/165 118/118/118 -f 184/184/184 186/186/186 185/185/185 -f 180/180/180 106/106/106 26/26/26 -f 9/9/9 110/110/110 13/13/13 -f 149/149/149 188/188/188 150/150/150 -f 232/232/232 189/189/189 190/190/190 -f 210/210/210 177/177/177 99/99/99 -f 181/181/181 189/189/189 140/140/140 -f 60/60/60 192/192/192 119/119/119 -f 192/192/192 194/194/194 193/193/193 -f 113/113/113 30/30/30 196/196/196 -f 163/163/163 38/38/38 197/197/197 -f 309/309/309 198/198/198 68/68/68 -f 154/154/154 127/127/127 51/51/51 -f 152/152/152 19/19/19 199/199/199 -f 163/163/163 197/197/197 164/164/164 -f 240/240/240 124/124/124 160/160/160 -f 72/72/72 71/71/71 202/202/202 -f 174/174/174 123/123/123 175/175/175 -f 21/21/21 43/43/43 103/103/103 -f 142/142/142 2/2/2 203/203/203 -f 175/175/175 180/180/180 16/16/16 -f 437/437/437 204/204/204 27/27/27 -f 196/196/196 29/29/29 205/205/205 -f 39/39/39 139/139/139 206/206/206 -f 153/153/153 165/165/165 109/109/109 -f 162/162/162 144/144/144 141/141/141 -f 21/21/21 103/103/103 22/22/22 -f 122/122/122 207/207/207 123/123/123 -f 238/238/238 147/147/147 208/208/208 -f 207/207/207 209/209/209 179/179/179 -f 99/99/99 98/98/98 210/210/210 -f 69/69/69 214/214/214 145/145/145 -f 137/137/137 136/136/136 3/3/3 -f 218/218/218 176/176/176 216/216/216 -f 3/3/3 66/66/66 217/217/217 -f 172/172/172 126/126/126 120/120/120 -f 176/176/176 218/218/218 99/99/99 -f 85/85/85 148/148/148 40/40/40 -f 222/222/222 220/220/220 151/151/151 -f 134/134/134 208/208/208 221/221/221 -f 5/5/5 222/222/222 6/6/6 -f 4/4/4 10/10/10 223/223/223 -f 223/223/223 164/164/164 224/224/224 -f 136/136/136 131/131/131 66/66/66 -f 105/105/105 129/129/129 144/144/144 -f 86/86/86 23/23/23 76/76/76 -f 62/62/62 85/85/85 63/63/63 -f 109/109/109 117/117/117 121/121/121 -f 64/64/64 63/63/63 107/107/107 -f 215/215/215 214/214/214 113/113/113 -f 215/215/215 229/229/229 221/221/221 -f 159/159/159 46/46/46 171/171/171 -f 87/87/87 19/19/19 231/231/231 -f 221/221/221 146/146/146 215/215/215 -f 190/190/190 185/185/185 232/232/232 -f 182/182/182 83/83/83 190/190/190 -f 82/82/82 84/84/84 182/182/182 -f 80/80/80 47/47/47 82/82/82 -f 32/32/32 78/78/78 80/80/80 -f 234/234/234 161/161/161 233/233/233 -f 170/170/170 50/50/50 39/39/39 -f 36/36/36 51/51/51 170/170/170 -f 41/41/41 154/154/154 36/36/36 -f 148/148/148 45/45/45 41/41/41 -f 61/61/61 46/46/46 77/77/77 -f 3/3/3 2/2/2 137/137/137 -f 113/113/113 112/112/112 215/215/215 -f 178/178/178 143/143/143 234/234/234 -f 69/69/69 145/145/145 70/70/70 -f 152/152/152 78/78/78 231/231/231 -f 64/64/64 166/166/166 165/165/165 -f 61/61/61 236/236/236 192/192/192 -f 205/205/205 237/237/237 196/196/196 -f 208/208/208 134/134/134 107/107/107 -f 107/107/107 220/220/220 208/208/208 -f 167/167/167 239/239/239 205/205/205 -f 43/43/43 72/72/72 104/104/104 -f 105/105/105 211/211/211 129/129/129 -f 42/42/42 73/73/73 43/43/43 -f 8/8/8 150/150/150 42/42/42 -f 7/7/7 116/116/116 8/8/8 -f 241/241/241 227/227/227 7/7/7 -f 90/90/90 89/89/89 228/228/228 -f 89/89/89 209/209/209 230/230/230 -f 207/207/207 93/93/93 209/209/209 -f 122/122/122 158/158/158 207/207/207 -f 240/240/240 54/54/54 122/122/122 -f 160/160/160 55/55/55 240/240/240 -f 157/157/157 94/94/94 160/160/160 -f 108/108/108 155/155/155 167/167/167 -f 236/236/236 178/178/178 194/194/194 -f 155/155/155 133/133/133 111/111/111 -f 61/61/61 77/77/77 236/236/236 -f 228/228/228 227/227/227 90/90/90 -f 90/90/90 241/241/241 216/216/216 -f 216/216/216 12/12/12 218/218/218 -f 218/218/218 242/242/242 219/219/219 -f 125/125/125 31/31/31 214/214/214 -f 219/219/219 121/121/121 97/97/97 -f 97/97/97 225/225/225 125/125/125 -f 194/194/194 234/234/234 195/195/195 -f 137/137/137 141/141/141 243/243/243 -f 211/211/211 202/202/202 212/212/212 -f 105/105/105 104/104/104 211/211/211 -f 436/436/436 244/244/244 246/246/246 -f 5/5/5 4/4/4 248/248/248 -f 369/369/369 249/249/249 251/251/251 -f 248/248/248 247/247/247 253/253/253 -f 250/250/250 254/254/254 256/256/256 -f 250/250/250 249/249/249 254/254/254 -f 411/411/411 258/258/258 260/260/260 -f 430/430/430 18/18/18 262/262/262 -f 413/413/413 263/263/263 265/265/265 -f 253/253/253 252/252/252 267/267/267 -f 27/27/27 26/26/26 269/269/269 -f 427/427/427 270/270/270 272/272/272 -f 402/402/402 273/273/273 275/275/275 -f 267/267/267 266/266/266 277/277/277 -f 408/408/408 278/278/278 280/280/280 -f 327/327/327 267/267/267 281/281/281 -f 435/435/435 282/282/282 263/263/263 -f 409/409/409 283/283/283 285/285/285 -f 48/48/48 286/286/286 49/49/49 -f 429/429/429 288/288/288 290/290/290 -f 401/401/401 291/291/291 293/293/293 -f 402/402/402 297/297/297 273/273/273 -f 285/285/285 299/299/299 301/301/301 -f 328/328/328 302/302/302 304/304/304 -f 444/444/444 305/305/305 307/307/307 -f 364/364/364 308/308/308 70/70/70 -f 433/433/433 310/310/310 312/312/312 -f 290/290/290 289/289/289 314/314/314 -f 413/413/413 315/315/315 317/317/317 -f 79/79/79 318/318/318 48/48/48 -f 297/297/297 314/314/314 298/298/298 -f 314/314/314 313/313/313 319/319/319 -f 287/287/287 321/321/321 49/49/49 -f 302/302/302 323/323/323 324/324/324 -f 430/430/430 262/262/262 326/326/326 -f 267/267/267 327/327/327 253/253/253 -f 343/343/343 329/329/329 331/331/331 -f 464/464/464 332/332/332 334/334/334 -f 391/391/391 336/336/336 338/338/338 -f 307/307/307 306/306/306 258/258/258 -f 101/101/101 329/329/329 102/102/102 -f 459/459/459 340/340/340 342/342/342 -f 329/329/329 343/343/343 339/339/339 -f 446/446/446 304/304/304 346/346/346 -f 256/256/256 347/347/347 349/349/349 -f 454/454/454 350/350/350 352/352/352 -f 393/393/393 353/353/353 355/355/355 -f 271/271/271 356/356/356 272/272/272 -f 424/424/424 299/299/299 359/359/359 -f 347/347/347 256/256/256 360/360/360 -f 375/375/375 361/361/361 363/363/363 -f 308/308/308 364/364/364 366/366/366 -f 410/410/410 275/275/275 326/326/326 -f 411/411/411 260/260/260 269/269/269 -f 297/297/297 368/368/368 314/314/314 -f 264/264/264 282/282/282 251/251/251 -f 442/442/442 370/370/370 372/372/372 -f 363/363/363 373/373/373 375/375/375 -f 398/398/398 376/376/376 378/378/378 -f 385/385/385 379/379/379 381/381/381 -f 403/403/403 382/382/382 384/384/384 -f 363/363/363 379/379/379 373/373/373 -f 436/436/436 386/386/386 388/388/388 -f 340/340/340 389/389/389 341/341/341 -f 451/451/451 390/390/390 147/147/147 -f 366/366/366 336/336/336 308/308/308 -f 323/323/323 392/392/392 315/315/315 -f 421/421/421 393/393/393 394/394/394 -f 248/248/248 253/253/253 395/395/395 -f 318/318/318 79/79/79 396/396/396 -f 348/348/348 324/324/324 349/349/349 -f 409/409/409 397/397/397 283/283/283 -f 460/460/460 398/398/398 346/346/346 -f 464/464/464 334/334/334 399/399/399 -f 370/370/370 400/400/400 371/371/371 -f 332/332/332 291/291/291 333/333/333 -f 283/283/283 402/402/402 284/284/284 -f 432/432/432 371/371/371 379/379/379 -f 283/283/283 368/368/368 402/402/402 -f 288/288/288 403/403/403 289/289/289 -f 389/389/389 404/404/404 387/387/387 -f 431/431/431 405/405/405 247/247/247 -f 303/303/303 302/302/302 348/348/348 -f 304/304/304 406/406/406 345/345/345 -f 465/465/465 271/271/271 406/406/406 -f 252/252/252 405/405/405 266/266/266 -f 392/392/392 409/409/409 316/316/316 -f 266/266/266 408/408/408 276/276/276 -f 410/410/410 358/358/358 275/275/275 -f 445/445/445 410/410/410 325/325/325 -f 416/416/416 374/374/374 411/411/411 -f 177/177/177 412/412/412 101/101/101 -f 455/455/455 389/389/389 317/317/317 -f 289/289/289 384/384/384 313/313/313 -f 339/339/339 415/415/415 268/268/268 -f 313/313/313 414/414/414 320/320/320 -f 349/349/349 265/265/265 251/251/251 -f 374/374/374 373/373/373 258/258/258 -f 404/404/404 418/418/418 388/388/388 -f 420/420/420 184/184/184 321/321/321 -f 465/465/465 303/303/303 271/271/271 -f 466/466/466 186/186/186 420/420/420 -f 102/102/102 339/339/339 26/26/26 -f 256/256/256 349/349/349 250/250/250 -f 312/312/312 311/311/311 394/394/394 -f 414/414/414 422/422/422 417/417/417 -f 412/412/412 177/177/177 338/338/338 -f 383/383/383 422/422/422 384/384/384 -f 426/426/426 300/300/300 424/424/424 -f 461/461/461 425/425/425 426/426/426 -f 270/270/270 427/427/427 351/351/351 -f 278/278/278 408/408/408 428/428/428 -f 391/391/391 198/198/198 308/308/308 -f 290/290/290 368/368/368 429/429/429 -f 18/18/18 430/430/430 199/199/199 -f 467/467/467 428/428/428 431/431/431 -f 379/379/379 363/363/363 432/432/432 -f 468/468/468 310/310/310 434/434/434 -f 415/415/415 375/375/375 416/416/416 -f 459/459/459 435/435/435 340/340/340 -f 244/244/244 436/436/436 419/419/419 -f 269/269/269 268/268/268 411/411/411 -f 269/269/269 367/367/367 27/27/27 -f 406/406/406 270/270/270 407/407/407 -f 382/382/382 403/403/403 279/279/279 -f 356/356/356 303/303/303 347/347/347 -f 400/400/400 341/341/341 386/386/386 -f 389/389/389 340/340/340 413/413/413 -f 415/415/415 438/438/438 375/375/375 -f 451/451/451 147/147/147 439/439/439 -f 339/339/339 344/344/344 415/415/415 -f 198/198/198 391/391/391 210/210/210 -f 447/447/447 365/365/365 390/390/390 -f 444/444/444 385/385/385 246/246/246 -f 329/329/329 412/412/412 330/330/330 -f 305/305/305 444/444/444 245/245/245 -f 358/358/358 410/410/410 359/359/359 -f 337/337/337 443/443/443 338/338/338 -f 281/281/281 392/392/392 327/327/327 -f 446/446/446 220/220/220 395/395/395 -f 451/451/451 439/439/439 377/377/377 -f 395/395/395 222/222/222 248/248/248 -f 431/431/431 247/247/247 223/223/223 -f 467/467/467 431/431/431 224/224/224 -f 307/307/307 373/373/373 444/444/444 -f 400/400/400 370/370/370 341/341/341 -f 413/413/413 265/265/265 315/315/315 -f 327/327/327 323/323/323 328/328/328 -f 357/357/357 356/356/356 360/360/360 -f 395/395/395 328/328/328 446/446/446 -f 427/427/427 365/365/365 352/352/352 -f 376/376/376 449/449/449 377/377/377 -f 299/299/299 285/285/285 358/358/358 -f 396/396/396 430/430/430 274/274/274 -f 390/390/390 451/451/451 447/447/447 -f 466/466/466 420/420/420 423/423/423 -f 420/420/420 321/321/321 417/417/417 -f 321/321/321 287/287/287 320/320/320 -f 287/287/287 286/286/286 319/319/319 -f 286/286/286 318/318/318 298/298/298 -f 418/418/418 404/404/404 453/453/453 -f 403/403/403 288/288/288 280/280/280 -f 288/288/288 429/429/429 276/276/276 -f 429/429/429 397/397/397 277/277/277 -f 397/397/397 409/409/409 281/281/281 -f 316/316/316 285/285/285 317/317/317 -f 386/386/386 436/436/436 381/381/381 -f 449/449/449 454/454/454 447/447/447 -f 404/404/404 389/389/389 452/452/452 -f 235/235/235 390/390/390 70/70/70 -f 273/273/273 318/318/318 274/274/274 -f 465/465/465 406/406/406 303/303/303 -f 425/425/425 456/456/456 300/300/300 -f 350/350/350 457/457/457 351/351/351 -f 346/346/346 378/378/378 446/446/446 -f 238/238/238 220/220/220 439/439/439 -f 457/457/457 458/458/458 407/407/407 -f 434/434/434 433/433/433 459/459/459 -f 442/442/442 441/441/441 370/370/370 -f 433/433/433 312/312/312 435/435/435 -f 312/312/312 394/394/394 282/282/282 -f 394/394/394 355/355/355 369/369/369 -f 355/355/355 354/354/354 249/249/249 -f 295/295/295 343/343/343 450/450/450 -f 294/294/294 344/344/344 295/295/295 -f 294/294/294 334/334/334 344/344/344 -f 334/334/334 333/333/333 438/438/438 -f 333/333/333 401/401/401 361/361/361 -f 401/401/401 293/293/293 362/362/362 -f 293/293/293 372/372/372 432/432/432 -f 454/454/454 449/449/449 398/398/398 -f 458/458/458 457/457/457 460/460/460 -f 458/458/458 460/460/460 345/345/345 -f 452/452/452 455/455/455 425/425/425 -f 454/454/454 398/398/398 350/350/350 -f 455/455/455 317/317/317 456/456/456 -f 257/257/257 354/354/354 331/331/331 -f 254/254/254 257/257/257 330/330/330 -f 255/255/255 254/254/254 443/443/443 -f 360/360/360 255/255/255 337/337/337 -f 427/427/427 272/272/272 365/365/365 -f 357/357/357 360/360/360 336/336/336 -f 272/272/272 357/357/357 366/366/366 -f 453/453/453 452/452/452 461/461/461 -f 400/400/400 386/386/386 380/380/380 -f 468/468/468 434/434/434 462/462/462 -f 434/434/434 459/459/459 441/441/441 +#usemtl 07___Default +#s 1 +f 1/1/1 2/2/2 3/3/3 +f 4/4/4 5/5/5 6/6/6 +f 7/7/7 8/8/8 9/9/9 +f 10/10/10 6/6/6 11/11/11 +f 12/12/12 13/13/13 14/14/14 +f 7/7/7 13/13/13 12/12/12 +f 15/15/15 16/16/16 17/17/17 +f 18/18/18 19/19/19 20/20/20 +f 21/21/21 22/22/22 23/23/23 +f 24/24/24 11/11/11 25/25/25 +f 26/26/26 27/27/27 28/28/28 +f 29/29/29 30/30/30 31/31/31 +f 32/32/32 33/33/33 34/34/34 +f 35/35/35 25/25/25 36/36/36 +f 37/37/37 38/38/38 39/39/39 +f 25/25/25 40/40/40 41/41/41 +f 42/42/42 43/43/43 21/21/21 +f 44/44/44 45/45/45 46/46/46 +f 47/47/47 48/48/48 49/49/49 +f 50/50/50 51/51/51 52/52/52 +f 53/53/53 54/54/54 55/55/55 +f 56/56/56 57/57/57 58/58/58 +f 59/59/59 33/33/33 32/32/32 +f 60/60/60 46/46/46 61/61/61 +f 62/62/62 63/63/63 64/64/64 +f 65/65/65 66/66/66 67/67/67 +f 68/68/68 69/69/69 70/70/70 +f 71/71/71 72/72/72 73/73/73 +f 74/74/74 52/52/52 75/75/75 +f 76/76/76 22/22/22 77/77/77 +f 78/78/78 79/79/79 48/48/48 +f 75/75/75 59/59/59 80/80/80 +f 81/81/81 75/75/75 82/82/82 +f 83/83/83 84/84/84 49/49/49 +f 85/85/85 62/62/62 86/86/86 +f 20/20/20 19/19/19 87/87/87 +f 40/40/40 25/25/25 11/11/11 +f 88/88/88 89/89/89 90/90/90 +f 91/91/91 92/92/92 93/93/93 +f 94/94/94 95/95/95 96/96/96 +f 97/97/97 98/98/98 99/99/99 +f 100/100/100 67/67/67 15/15/15 +f 88/88/88 101/101/101 102/102/102 +f 103/103/103 104/104/104 105/105/105 +f 89/89/89 88/88/88 106/106/106 +f 64/64/64 107/107/107 108/108/108 +f 109/109/109 14/14/14 110/110/110 +f 111/111/111 112/112/112 113/113/113 +f 114/114/114 115/115/115 116/116/116 +f 117/117/117 118/118/118 31/31/31 +f 60/60/60 119/119/119 120/120/120 +f 14/14/14 109/109/109 121/121/121 +f 122/122/122 123/123/123 124/124/124 +f 69/69/69 68/68/68 125/125/125 +f 34/34/34 126/126/126 87/87/87 +f 17/17/17 16/16/16 28/28/28 +f 127/127/127 59/59/59 75/75/75 +f 42/42/42 128/128/128 9/9/9 +f 129/129/129 130/130/130 94/94/94 +f 131/131/131 124/124/124 123/123/123 +f 132/132/132 133/133/133 134/134/134 +f 135/135/135 136/136/136 137/137/137 +f 138/138/138 139/139/139 140/140/140 +f 135/135/135 124/124/124 131/131/131 +f 141/141/141 2/2/2 142/142/142 +f 143/143/143 103/103/103 144/144/144 +f 145/145/145 146/146/146 147/147/147 +f 97/97/97 125/125/125 68/68/68 +f 148/148/148 85/85/85 76/76/76 +f 115/115/115 149/149/149 150/150/150 +f 11/11/11 6/6/6 151/151/151 +f 79/79/79 78/78/78 152/152/152 +f 86/86/86 153/153/153 110/110/110 +f 154/154/154 45/45/45 44/44/44 +f 133/133/133 155/155/155 108/108/108 +f 93/93/93 92/92/92 57/57/57 +f 156/156/156 129/129/129 157/157/157 +f 53/53/53 91/91/91 158/158/158 +f 33/33/33 44/44/44 159/159/159 +f 157/157/157 160/160/160 135/135/135 +f 127/127/127 44/44/44 33/33/33 +f 139/139/139 50/50/50 74/74/74 +f 161/161/161 143/143/143 162/162/162 +f 163/163/163 164/164/164 10/10/10 +f 62/62/62 165/165/165 153/153/153 +f 166/166/166 64/64/64 167/167/167 +f 118/118/118 168/168/168 166/166/166 +f 163/163/163 24/24/24 35/35/35 +f 45/45/45 148/148/148 169/169/169 +f 38/38/38 35/35/35 170/170/170 +f 171/171/171 126/126/126 34/34/34 +f 126/126/126 172/172/172 173/173/173 +f 174/174/174 175/175/175 16/16/16 +f 176/176/176 177/177/177 101/101/101 +f 143/143/143 178/178/178 77/77/77 +f 140/140/140 74/74/74 81/81/81 +f 179/179/179 106/106/106 180/180/180 +f 181/181/181 81/81/81 182/182/182 +f 23/23/23 110/110/110 9/9/9 +f 131/131/131 174/174/174 15/15/15 +f 183/183/183 161/161/161 142/142/142 +f 184/184/184 185/185/185 83/83/83 +f 165/165/165 168/168/168 118/118/118 +f 186/186/186 187/187/187 185/185/185 +f 106/106/106 102/102/102 26/26/26 +f 110/110/110 14/14/14 13/13/13 +f 188/188/188 73/73/73 150/150/150 +f 189/189/189 181/181/181 190/190/190 +f 177/177/177 176/176/176 99/99/99 +f 189/189/189 191/191/191 140/140/140 +f 192/192/192 193/193/193 119/119/119 +f 194/194/194 195/195/195 193/193/193 +f 30/30/30 29/29/29 196/196/196 +f 38/38/38 37/37/37 197/197/197 +f 198/198/198 98/98/98 68/68/68 +f 127/127/127 52/52/52 51/51/51 +f 19/19/19 18/18/18 199/199/199 +f 197/197/197 200/200/200 164/164/164 +f 124/124/124 135/135/135 160/160/160 +f 71/71/71 201/201/201 202/202/202 +f 123/123/123 179/179/179 175/175/175 +f 43/43/43 104/104/104 103/103/103 +f 2/2/2 1/1/1 203/203/203 +f 180/180/180 28/28/28 16/16/16 +f 204/204/204 28/28/28 27/27/27 +f 29/29/29 166/166/166 205/205/205 +f 139/139/139 138/138/138 206/206/206 +f 165/165/165 117/117/117 109/109/109 +f 144/144/144 156/156/156 141/141/141 +f 103/103/103 143/143/143 22/22/22 +f 207/207/207 179/179/179 123/123/123 +f 147/147/147 146/146/146 208/208/208 +f 209/209/209 106/106/106 179/179/179 +f 98/98/98 198/198/198 210/210/210 +f 211/211/211 212/212/212 213/213/213 +f 214/214/214 215/215/215 145/145/145 +f 136/136/136 66/66/66 3/3/3 +f 176/176/176 88/88/88 216/216/216 +f 94/94/94 130/130/130 213/213/213 +f 66/66/66 65/65/65 217/217/217 +f 126/126/126 171/171/171 120/120/120 +f 218/218/218 219/219/219 99/99/99 +f 148/148/148 41/41/41 40/40/40 +f 220/220/220 107/107/107 151/151/151 +f 208/208/208 146/146/146 221/221/221 +f 222/222/222 151/151/151 6/6/6 +f 10/10/10 164/164/164 223/223/223 +f 164/164/164 200/200/200 224/224/224 +f 131/131/131 67/67/67 66/66/66 +f 129/129/129 156/156/156 144/144/144 +f 23/23/23 22/22/22 76/76/76 +f 85/85/85 40/40/40 63/63/63 +f 117/117/117 225/225/225 121/121/121 +f 63/63/63 151/151/151 107/107/107 +f 214/214/214 30/30/30 113/113/113 +f 226/226/226 227/227/227 228/228/228 +f 229/229/229 132/132/132 221/221/221 +f 46/46/46 60/60/60 171/171/171 +f 230/230/230 58/58/58 226/226/226 +f 19/19/19 152/152/152 231/231/231 +f 146/146/146 145/145/145 215/215/215 +f 185/185/185 187/187/187 232/232/232 +f 83/83/83 185/185/185 190/190/190 +f 84/84/84 83/83/83 182/182/182 +f 47/47/47 84/84/84 82/82/82 +f 78/78/78 47/47/47 80/80/80 +f 161/161/161 183/183/183 233/233/233 +f 50/50/50 139/139/139 39/39/39 +f 51/51/51 50/50/50 170/170/170 +f 154/154/154 51/51/51 36/36/36 +f 45/45/45 154/154/154 41/41/41 +f 46/46/46 169/169/169 77/77/77 +f 2/2/2 141/141/141 137/137/137 +f 112/112/112 229/229/229 215/215/215 +f 143/143/143 161/161/161 234/234/234 +f 145/145/145 235/235/235 70/70/70 +f 78/78/78 32/32/32 231/231/231 +f 166/166/166 168/168/168 165/165/165 +f 236/236/236 194/194/194 192/192/192 +f 237/237/237 111/111/111 196/196/196 +f 134/134/134 108/108/108 107/107/107 +f 220/220/220 238/238/238 208/208/208 +f 239/239/239 237/237/237 205/205/205 +f 72/72/72 202/202/202 104/104/104 +f 211/211/211 130/130/130 129/129/129 +f 73/73/73 72/72/72 43/43/43 +f 150/150/150 73/73/73 42/42/42 +f 116/116/116 150/150/150 8/8/8 +f 227/227/227 116/116/116 7/7/7 +f 89/89/89 230/230/230 228/228/228 +f 209/209/209 56/56/56 230/230/230 +f 93/93/93 56/56/56 209/209/209 +f 158/158/158 93/93/93 207/207/207 +f 54/54/54 158/158/158 122/122/122 +f 55/55/55 54/54/54 240/240/240 +f 94/94/94 55/55/55 160/160/160 +f 132/132/132 112/112/112 133/133/133 +f 111/111/111 237/237/237 239/239/239 +f 155/155/155 239/239/239 167/167/167 +f 178/178/178 234/234/234 194/194/194 +f 133/133/133 112/112/112 111/111/111 +f 77/77/77 178/178/178 236/236/236 +f 227/227/227 241/241/241 90/90/90 +f 241/241/241 12/12/12 216/216/216 +f 12/12/12 242/242/242 218/218/218 +f 242/242/242 121/121/121 219/219/219 +f 31/31/31 30/30/30 214/214/214 +f 121/121/121 225/225/225 97/97/97 +f 225/225/225 31/31/31 125/125/125 +f 234/234/234 233/233/233 195/195/195 +f 141/141/141 156/156/156 243/243/243 +f 202/202/202 201/201/201 212/212/212 +f 104/104/104 202/202/202 211/211/211 +f 244/244/244 245/245/245 246/246/246 +f 4/4/4 247/247/247 248/248/248 +f 249/249/249 250/250/250 251/251/251 +f 247/247/247 252/252/252 253/253/253 +f 254/254/254 255/255/255 256/256/256 +f 249/249/249 257/257/257 254/254/254 +f 258/258/258 259/259/259 260/260/260 +f 18/18/18 261/261/261 262/262/262 +f 263/263/263 264/264/264 265/265/265 +f 252/252/252 266/266/266 267/267/267 +f 26/26/26 268/268/268 269/269/269 +f 270/270/270 271/271/271 272/272/272 +f 273/273/273 274/274/274 275/275/275 +f 266/266/266 276/276/276 277/277/277 +f 278/278/278 279/279/279 280/280/280 +f 267/267/267 277/277/277 281/281/281 +f 282/282/282 264/264/264 263/263/263 +f 283/283/283 284/284/284 285/285/285 +f 286/286/286 287/287/287 49/49/49 +f 288/288/288 289/289/289 290/290/290 +f 291/291/291 292/292/292 293/293/293 +f 294/294/294 295/295/295 296/296/296 +f 297/297/297 298/298/298 273/273/273 +f 299/299/299 300/300/300 301/301/301 +f 302/302/302 303/303/303 304/304/304 +f 305/305/305 306/306/306 307/307/307 +f 308/308/308 309/309/309 70/70/70 +f 310/310/310 311/311/311 312/312/312 +f 289/289/289 313/313/313 314/314/314 +f 315/315/315 316/316/316 317/317/317 +f 318/318/318 286/286/286 48/48/48 +f 314/314/314 319/319/319 298/298/298 +f 313/313/313 320/320/320 319/319/319 +f 321/321/321 322/322/322 49/49/49 +f 323/323/323 315/315/315 324/324/324 +f 262/262/262 325/325/325 326/326/326 +f 327/327/327 328/328/328 253/253/253 +f 329/329/329 330/330/330 331/331/331 +f 332/332/332 333/333/333 334/334/334 +f 335/335/335 293/293/293 292/292/292 +f 336/336/336 337/337/337 338/338/338 +f 306/306/306 259/259/259 258/258/258 +f 329/329/329 339/339/339 102/102/102 +f 340/340/340 341/341/341 342/342/342 +f 343/343/343 344/344/344 339/339/339 +f 304/304/304 345/345/345 346/346/346 +f 347/347/347 348/348/348 349/349/349 +f 350/350/350 351/351/351 352/352/352 +f 353/353/353 354/354/354 355/355/355 +f 356/356/356 357/357/357 272/272/272 +f 299/299/299 358/358/358 359/359/359 +f 256/256/256 255/255/255 360/360/360 +f 361/361/361 362/362/362 363/363/363 +f 364/364/364 365/365/365 366/366/366 +f 275/275/275 274/274/274 326/326/326 +f 260/260/260 367/367/367 269/269/269 +f 368/368/368 290/290/290 314/314/314 +f 282/282/282 369/369/369 251/251/251 +f 370/370/370 371/371/371 372/372/372 +f 373/373/373 374/374/374 375/375/375 +f 376/376/376 377/377/377 378/378/378 +f 379/379/379 380/380/380 381/381/381 +f 382/382/382 383/383/383 384/384/384 +f 379/379/379 385/385/385 373/373/373 +f 386/386/386 387/387/387 388/388/388 +f 389/389/389 387/387/387 341/341/341 +f 390/390/390 235/235/235 147/147/147 +f 336/336/336 391/391/391 308/308/308 +f 392/392/392 316/316/316 315/315/315 +f 393/393/393 355/355/355 394/394/394 +f 253/253/253 328/328/328 395/395/395 +f 79/79/79 199/199/199 396/396/396 +f 324/324/324 265/265/265 349/349/349 +f 397/397/397 368/368/368 283/283/283 +f 398/398/398 378/378/378 346/346/346 +f 334/334/334 294/294/294 399/399/399 +f 400/400/400 380/380/380 371/371/371 +f 291/291/291 401/401/401 333/333/333 +f 402/402/402 275/275/275 284/284/284 +f 371/371/371 380/380/380 379/379/379 +f 368/368/368 297/297/297 402/402/402 +f 403/403/403 384/384/384 289/289/289 +f 404/404/404 388/388/388 387/387/387 +f 405/405/405 252/252/252 247/247/247 +f 302/302/302 324/324/324 348/348/348 +f 406/406/406 407/407/407 345/345/345 +f 271/271/271 270/270/270 406/406/406 +f 405/405/405 408/408/408 266/266/266 +f 409/409/409 285/285/285 316/316/316 +f 408/408/408 280/280/280 276/276/276 +f 358/358/358 284/284/284 275/275/275 +f 410/410/410 326/326/326 325/325/325 +f 374/374/374 258/258/258 411/411/411 +f 412/412/412 329/329/329 101/101/101 +f 389/389/389 413/413/413 317/317/317 +f 384/384/384 414/414/414 313/313/313 +f 415/415/415 416/416/416 268/268/268 +f 414/414/414 417/417/417 320/320/320 +f 265/265/265 264/264/264 251/251/251 +f 373/373/373 307/307/307 258/258/258 +f 418/418/418 419/419/419 388/388/388 +f 184/184/184 322/322/322 321/321/321 +f 303/303/303 356/356/356 271/271/271 +f 186/186/186 184/184/184 420/420/420 +f 339/339/339 268/268/268 26/26/26 +f 349/349/349 251/251/251 250/250/250 +f 311/311/311 421/421/421 394/394/394 +f 422/422/422 423/423/423 417/417/417 +f 177/177/177 210/210/210 338/338/338 +f 422/422/422 414/414/414 384/384/384 +f 300/300/300 299/299/299 424/424/424 +f 425/425/425 300/300/300 426/426/426 +f 427/427/427 352/352/352 351/351/351 +f 408/408/408 405/405/405 428/428/428 +f 198/198/198 309/309/309 308/308/308 +f 368/368/368 397/397/397 429/429/429 +f 430/430/430 396/396/396 199/199/199 +f 428/428/428 405/405/405 431/431/431 +f 363/363/363 362/362/362 432/432/432 +f 310/310/310 433/433/433 434/434/434 +f 375/375/375 374/374/374 416/416/416 +f 435/435/435 263/263/263 340/340/340 +f 436/436/436 388/388/388 419/419/419 +f 268/268/268 416/416/416 411/411/411 +f 367/367/367 437/437/437 27/27/27 +f 270/270/270 351/351/351 407/407/407 +f 403/403/403 280/280/280 279/279/279 +f 303/303/303 348/348/348 347/347/347 +f 341/341/341 387/387/387 386/386/386 +f 340/340/340 263/263/263 413/413/413 +f 438/438/438 361/361/361 375/375/375 +f 147/147/147 238/238/238 439/439/439 +f 344/344/344 438/438/438 415/415/415 +f 391/391/391 338/338/338 210/210/210 +f 440/440/440 441/441/441 442/442/442 +f 365/365/365 364/364/364 390/390/390 +f 385/385/385 381/381/381 246/246/246 +f 412/412/412 443/443/443 330/330/330 +f 440/440/440 372/372/372 335/335/335 +f 444/444/444 246/246/246 245/245/245 +f 410/410/410 445/445/445 359/359/359 +f 443/443/443 412/412/412 338/338/338 +f 392/392/392 323/323/323 327/327/327 +f 220/220/220 222/222/222 395/395/395 +f 439/439/439 378/378/378 377/377/377 +f 222/222/222 5/5/5 248/248/248 +f 247/247/247 4/4/4 223/223/223 +f 431/431/431 223/223/223 224/224/224 +f 373/373/373 385/385/385 444/444/444 +f 370/370/370 342/342/342 341/341/341 +f 265/265/265 324/324/324 315/315/315 +f 323/323/323 302/302/302 328/328/328 +f 356/356/356 347/347/347 360/360/360 +f 328/328/328 304/304/304 446/446/446 +f 365/365/365 447/447/447 352/352/352 +f 354/354/354 353/353/353 448/448/448 +f 449/449/449 447/447/447 377/377/377 +f 285/285/285 284/284/284 358/358/358 +f 295/295/295 450/450/450 448/448/448 +f 430/430/430 326/326/326 274/274/274 +f 451/451/451 377/377/377 447/447/447 +f 420/420/420 417/417/417 423/423/423 +f 321/321/321 320/320/320 417/417/417 +f 287/287/287 319/319/319 320/320/320 +f 286/286/286 298/298/298 319/319/319 +f 318/318/318 273/273/273 298/298/298 +f 404/404/404 452/452/452 453/453/453 +f 288/288/288 276/276/276 280/280/280 +f 429/429/429 277/277/277 276/276/276 +f 397/397/397 281/281/281 277/277/277 +f 409/409/409 392/392/392 281/281/281 +f 285/285/285 301/301/301 317/317/317 +f 436/436/436 246/246/246 381/381/381 +f 454/454/454 352/352/352 447/447/447 +f 389/389/389 455/455/455 452/452/452 +f 390/390/390 364/364/364 70/70/70 +f 318/318/318 396/396/396 274/274/274 +f 406/406/406 304/304/304 303/303/303 +f 456/456/456 301/301/301 300/300/300 +f 457/457/457 407/407/407 351/351/351 +f 378/378/378 439/439/439 446/446/446 +f 220/220/220 446/446/446 439/439/439 +f 458/458/458 345/345/345 407/407/407 +f 433/433/433 435/435/435 459/459/459 +f 441/441/441 342/342/342 370/370/370 +f 312/312/312 282/282/282 435/435/435 +f 394/394/394 369/369/369 282/282/282 +f 355/355/355 249/249/249 369/369/369 +f 354/354/354 257/257/257 249/249/249 +f 343/343/343 331/331/331 450/450/450 +f 344/344/344 343/343/343 295/295/295 +f 334/334/334 438/438/438 344/344/344 +f 333/333/333 361/361/361 438/438/438 +f 401/401/401 362/362/362 361/361/361 +f 293/293/293 432/432/432 362/362/362 +f 372/372/372 371/371/371 432/432/432 +f 449/449/449 376/376/376 398/398/398 +f 457/457/457 350/350/350 460/460/460 +f 460/460/460 346/346/346 345/345/345 +f 455/455/455 456/456/456 425/425/425 +f 398/398/398 460/460/460 350/350/350 +f 317/317/317 301/301/301 456/456/456 +f 354/354/354 450/450/450 331/331/331 +f 257/257/257 331/331/331 330/330/330 +f 254/254/254 330/330/330 443/443/443 +f 255/255/255 443/443/443 337/337/337 +f 272/272/272 366/366/366 365/365/365 +f 360/360/360 337/337/337 336/336/336 +f 357/357/357 336/336/336 366/366/366 +f 452/452/452 425/425/425 461/461/461 +f 386/386/386 381/381/381 380/380/380 +f 434/434/434 441/441/441 462/462/462 +f 459/459/459 342/342/342 441/441/441 +f 226/226/226 228/228/228 230/230/230 +f 226/226/226 114/114/114 227/227/227 +f 213/213/213 95/95/95 94/94/94 +f 213/213/213 130/130/130 211/211/211 +f 296/296/296 399/399/399 294/294/294 +f 448/448/448 296/296/296 295/295/295 +f 448/448/448 450/450/450 354/354/354 +f 440/440/440 442/442/442 372/372/372 +f 440/440/440 462/462/462 441/441/441 +f 335/335/335 372/372/372 293/293/293 +f 239/239/239 155/155/155 111/111/111 +f 132/132/132 229/229/229 112/112/112 +f 217/217/217 1/1/1 3/3/3 +f 10/10/10 4/4/4 6/6/6 +f 13/13/13 7/7/7 9/9/9 +f 24/24/24 10/10/10 11/11/11 +f 242/242/242 12/12/12 14/14/14 +f 241/241/241 7/7/7 12/12/12 +f 463/463/463 15/15/15 17/17/17 +f 261/261/261 18/18/18 20/20/20 +f 128/128/128 21/21/21 23/23/23 +f 35/35/35 24/24/24 25/25/25 +f 180/180/180 26/26/26 28/28/28 +f 118/118/118 29/29/29 31/31/31 +f 231/231/231 32/32/32 34/34/34 +f 170/170/170 35/35/35 36/36/36 +f 206/206/206 37/37/37 39/39/39 +f 36/36/36 25/25/25 41/41/41 +f 128/128/128 42/42/42 21/21/21 +f 159/159/159 44/44/44 46/46/46 +f 84/84/84 47/47/47 49/49/49 +f 74/74/74 50/50/50 52/52/52 +f 96/96/96 53/53/53 55/55/55 +f 230/230/230 56/56/56 58/58/58 +f 80/80/80 59/59/59 32/32/32 +f 192/192/192 60/60/60 61/61/61 +f 165/165/165 62/62/62 64/64/64 +f 100/100/100 65/65/65 67/67/67 +f 309/309/309 68/68/68 70/70/70 +f 188/188/188 71/71/71 73/73/73 +f 81/81/81 74/74/74 75/75/75 +f 169/169/169 76/76/76 77/77/77 +f 47/47/47 78/78/78 48/48/48 +f 82/82/82 75/75/75 80/80/80 +f 182/182/182 81/81/81 82/82/82 +f 322/322/322 83/83/83 49/49/49 +f 76/76/76 85/85/85 86/86/86 +f 173/173/173 20/20/20 87/87/87 +f 63/63/63 40/40/40 11/11/11 +f 216/216/216 88/88/88 90/90/90 +f 158/158/158 91/91/91 93/93/93 +f 55/55/55 94/94/94 96/96/96 +f 219/219/219 97/97/97 99/99/99 +f 463/463/463 100/100/100 15/15/15 +f 106/106/106 88/88/88 102/102/102 +f 144/144/144 103/103/103 105/105/105 +f 209/209/209 89/89/89 106/106/106 +f 167/167/167 64/64/64 108/108/108 +f 153/153/153 109/109/109 110/110/110 +f 196/196/196 111/111/111 113/113/113 +f 227/227/227 114/114/114 116/116/116 +f 225/225/225 117/117/117 31/31/31 +f 171/171/171 60/60/60 120/120/120 +f 242/242/242 14/14/14 121/121/121 +f 240/240/240 122/122/122 124/124/124 +f 214/214/214 69/69/69 125/125/125 +f 231/231/231 34/34/34 87/87/87 +f 204/204/204 17/17/17 28/28/28 +f 52/52/52 127/127/127 75/75/75 +f 8/8/8 42/42/42 9/9/9 +f 157/157/157 129/129/129 94/94/94 +f 174/174/174 131/131/131 123/123/123 +f 221/221/221 132/132/132 134/134/134 +f 243/243/243 135/135/135 137/137/137 +f 191/191/191 138/138/138 140/140/140 +f 136/136/136 135/135/135 131/131/131 +f 162/162/162 141/141/141 142/142/142 +f 162/162/162 143/143/143 144/144/144 +f 235/235/235 145/145/145 147/147/147 +f 98/98/98 97/97/97 68/68/68 +f 169/169/169 148/148/148 76/76/76 +f 116/116/116 115/115/115 150/150/150 +f 63/63/63 11/11/11 151/151/151 +f 199/199/199 79/79/79 152/152/152 +f 23/23/23 86/86/86 110/110/110 +f 127/127/127 154/154/154 44/44/44 +f 134/134/134 133/133/133 108/108/108 +f 56/56/56 93/93/93 57/57/57 +f 243/243/243 156/156/156 157/157/157 +f 54/54/54 53/53/53 158/158/158 +f 34/34/34 33/33/33 159/159/159 +f 243/243/243 157/157/157 135/135/135 +f 59/59/59 127/127/127 33/33/33 +f 140/140/140 139/139/139 74/74/74 +f 142/142/142 161/161/161 162/162/162 +f 24/24/24 163/163/163 10/10/10 +f 86/86/86 62/62/62 153/153/153 +f 205/205/205 166/166/166 167/167/167 +f 29/29/29 118/118/118 166/166/166 +f 38/38/38 163/163/163 35/35/35 +f 46/46/46 45/45/45 169/169/169 +f 39/39/39 38/38/38 170/170/170 +f 159/159/159 171/171/171 34/34/34 +f 87/87/87 126/126/126 173/173/173 +f 15/15/15 174/174/174 16/16/16 +f 88/88/88 176/176/176 101/101/101 +f 22/22/22 143/143/143 77/77/77 +f 181/181/181 140/140/140 81/81/81 +f 175/175/175 179/179/179 180/180/180 +f 190/190/190 181/181/181 182/182/182 +f 128/128/128 23/23/23 9/9/9 +f 67/67/67 131/131/131 15/15/15 +f 203/203/203 183/183/183 142/142/142 +f 322/322/322 184/184/184 83/83/83 +f 117/117/117 165/165/165 118/118/118 +f 184/184/184 186/186/186 185/185/185 +f 180/180/180 106/106/106 26/26/26 +f 9/9/9 110/110/110 13/13/13 +f 149/149/149 188/188/188 150/150/150 +f 232/232/232 189/189/189 190/190/190 +f 210/210/210 177/177/177 99/99/99 +f 181/181/181 189/189/189 140/140/140 +f 60/60/60 192/192/192 119/119/119 +f 192/192/192 194/194/194 193/193/193 +f 113/113/113 30/30/30 196/196/196 +f 163/163/163 38/38/38 197/197/197 +f 309/309/309 198/198/198 68/68/68 +f 154/154/154 127/127/127 51/51/51 +f 152/152/152 19/19/19 199/199/199 +f 163/163/163 197/197/197 164/164/164 +f 240/240/240 124/124/124 160/160/160 +f 72/72/72 71/71/71 202/202/202 +f 174/174/174 123/123/123 175/175/175 +f 21/21/21 43/43/43 103/103/103 +f 142/142/142 2/2/2 203/203/203 +f 175/175/175 180/180/180 16/16/16 +f 437/437/437 204/204/204 27/27/27 +f 196/196/196 29/29/29 205/205/205 +f 39/39/39 139/139/139 206/206/206 +f 153/153/153 165/165/165 109/109/109 +f 162/162/162 144/144/144 141/141/141 +f 21/21/21 103/103/103 22/22/22 +f 122/122/122 207/207/207 123/123/123 +f 238/238/238 147/147/147 208/208/208 +f 207/207/207 209/209/209 179/179/179 +f 99/99/99 98/98/98 210/210/210 +f 69/69/69 214/214/214 145/145/145 +f 137/137/137 136/136/136 3/3/3 +f 218/218/218 176/176/176 216/216/216 +f 3/3/3 66/66/66 217/217/217 +f 172/172/172 126/126/126 120/120/120 +f 176/176/176 218/218/218 99/99/99 +f 85/85/85 148/148/148 40/40/40 +f 222/222/222 220/220/220 151/151/151 +f 134/134/134 208/208/208 221/221/221 +f 5/5/5 222/222/222 6/6/6 +f 4/4/4 10/10/10 223/223/223 +f 223/223/223 164/164/164 224/224/224 +f 136/136/136 131/131/131 66/66/66 +f 105/105/105 129/129/129 144/144/144 +f 86/86/86 23/23/23 76/76/76 +f 62/62/62 85/85/85 63/63/63 +f 109/109/109 117/117/117 121/121/121 +f 64/64/64 63/63/63 107/107/107 +f 215/215/215 214/214/214 113/113/113 +f 215/215/215 229/229/229 221/221/221 +f 159/159/159 46/46/46 171/171/171 +f 87/87/87 19/19/19 231/231/231 +f 221/221/221 146/146/146 215/215/215 +f 190/190/190 185/185/185 232/232/232 +f 182/182/182 83/83/83 190/190/190 +f 82/82/82 84/84/84 182/182/182 +f 80/80/80 47/47/47 82/82/82 +f 32/32/32 78/78/78 80/80/80 +f 234/234/234 161/161/161 233/233/233 +f 170/170/170 50/50/50 39/39/39 +f 36/36/36 51/51/51 170/170/170 +f 41/41/41 154/154/154 36/36/36 +f 148/148/148 45/45/45 41/41/41 +f 61/61/61 46/46/46 77/77/77 +f 3/3/3 2/2/2 137/137/137 +f 113/113/113 112/112/112 215/215/215 +f 178/178/178 143/143/143 234/234/234 +f 69/69/69 145/145/145 70/70/70 +f 152/152/152 78/78/78 231/231/231 +f 64/64/64 166/166/166 165/165/165 +f 61/61/61 236/236/236 192/192/192 +f 205/205/205 237/237/237 196/196/196 +f 208/208/208 134/134/134 107/107/107 +f 107/107/107 220/220/220 208/208/208 +f 167/167/167 239/239/239 205/205/205 +f 43/43/43 72/72/72 104/104/104 +f 105/105/105 211/211/211 129/129/129 +f 42/42/42 73/73/73 43/43/43 +f 8/8/8 150/150/150 42/42/42 +f 7/7/7 116/116/116 8/8/8 +f 241/241/241 227/227/227 7/7/7 +f 90/90/90 89/89/89 228/228/228 +f 89/89/89 209/209/209 230/230/230 +f 207/207/207 93/93/93 209/209/209 +f 122/122/122 158/158/158 207/207/207 +f 240/240/240 54/54/54 122/122/122 +f 160/160/160 55/55/55 240/240/240 +f 157/157/157 94/94/94 160/160/160 +f 108/108/108 155/155/155 167/167/167 +f 236/236/236 178/178/178 194/194/194 +f 155/155/155 133/133/133 111/111/111 +f 61/61/61 77/77/77 236/236/236 +f 228/228/228 227/227/227 90/90/90 +f 90/90/90 241/241/241 216/216/216 +f 216/216/216 12/12/12 218/218/218 +f 218/218/218 242/242/242 219/219/219 +f 125/125/125 31/31/31 214/214/214 +f 219/219/219 121/121/121 97/97/97 +f 97/97/97 225/225/225 125/125/125 +f 194/194/194 234/234/234 195/195/195 +f 137/137/137 141/141/141 243/243/243 +f 211/211/211 202/202/202 212/212/212 +f 105/105/105 104/104/104 211/211/211 +f 436/436/436 244/244/244 246/246/246 +f 5/5/5 4/4/4 248/248/248 +f 369/369/369 249/249/249 251/251/251 +f 248/248/248 247/247/247 253/253/253 +f 250/250/250 254/254/254 256/256/256 +f 250/250/250 249/249/249 254/254/254 +f 411/411/411 258/258/258 260/260/260 +f 430/430/430 18/18/18 262/262/262 +f 413/413/413 263/263/263 265/265/265 +f 253/253/253 252/252/252 267/267/267 +f 27/27/27 26/26/26 269/269/269 +f 427/427/427 270/270/270 272/272/272 +f 402/402/402 273/273/273 275/275/275 +f 267/267/267 266/266/266 277/277/277 +f 408/408/408 278/278/278 280/280/280 +f 327/327/327 267/267/267 281/281/281 +f 435/435/435 282/282/282 263/263/263 +f 409/409/409 283/283/283 285/285/285 +f 48/48/48 286/286/286 49/49/49 +f 429/429/429 288/288/288 290/290/290 +f 401/401/401 291/291/291 293/293/293 +f 402/402/402 297/297/297 273/273/273 +f 285/285/285 299/299/299 301/301/301 +f 328/328/328 302/302/302 304/304/304 +f 444/444/444 305/305/305 307/307/307 +f 364/364/364 308/308/308 70/70/70 +f 433/433/433 310/310/310 312/312/312 +f 290/290/290 289/289/289 314/314/314 +f 413/413/413 315/315/315 317/317/317 +f 79/79/79 318/318/318 48/48/48 +f 297/297/297 314/314/314 298/298/298 +f 314/314/314 313/313/313 319/319/319 +f 287/287/287 321/321/321 49/49/49 +f 302/302/302 323/323/323 324/324/324 +f 430/430/430 262/262/262 326/326/326 +f 267/267/267 327/327/327 253/253/253 +f 343/343/343 329/329/329 331/331/331 +f 464/464/464 332/332/332 334/334/334 +f 391/391/391 336/336/336 338/338/338 +f 307/307/307 306/306/306 258/258/258 +f 101/101/101 329/329/329 102/102/102 +f 459/459/459 340/340/340 342/342/342 +f 329/329/329 343/343/343 339/339/339 +f 446/446/446 304/304/304 346/346/346 +f 256/256/256 347/347/347 349/349/349 +f 454/454/454 350/350/350 352/352/352 +f 393/393/393 353/353/353 355/355/355 +f 271/271/271 356/356/356 272/272/272 +f 424/424/424 299/299/299 359/359/359 +f 347/347/347 256/256/256 360/360/360 +f 375/375/375 361/361/361 363/363/363 +f 308/308/308 364/364/364 366/366/366 +f 410/410/410 275/275/275 326/326/326 +f 411/411/411 260/260/260 269/269/269 +f 297/297/297 368/368/368 314/314/314 +f 264/264/264 282/282/282 251/251/251 +f 442/442/442 370/370/370 372/372/372 +f 363/363/363 373/373/373 375/375/375 +f 398/398/398 376/376/376 378/378/378 +f 385/385/385 379/379/379 381/381/381 +f 403/403/403 382/382/382 384/384/384 +f 363/363/363 379/379/379 373/373/373 +f 436/436/436 386/386/386 388/388/388 +f 340/340/340 389/389/389 341/341/341 +f 451/451/451 390/390/390 147/147/147 +f 366/366/366 336/336/336 308/308/308 +f 323/323/323 392/392/392 315/315/315 +f 421/421/421 393/393/393 394/394/394 +f 248/248/248 253/253/253 395/395/395 +f 318/318/318 79/79/79 396/396/396 +f 348/348/348 324/324/324 349/349/349 +f 409/409/409 397/397/397 283/283/283 +f 460/460/460 398/398/398 346/346/346 +f 464/464/464 334/334/334 399/399/399 +f 370/370/370 400/400/400 371/371/371 +f 332/332/332 291/291/291 333/333/333 +f 283/283/283 402/402/402 284/284/284 +f 432/432/432 371/371/371 379/379/379 +f 283/283/283 368/368/368 402/402/402 +f 288/288/288 403/403/403 289/289/289 +f 389/389/389 404/404/404 387/387/387 +f 431/431/431 405/405/405 247/247/247 +f 303/303/303 302/302/302 348/348/348 +f 304/304/304 406/406/406 345/345/345 +f 465/465/465 271/271/271 406/406/406 +f 252/252/252 405/405/405 266/266/266 +f 392/392/392 409/409/409 316/316/316 +f 266/266/266 408/408/408 276/276/276 +f 410/410/410 358/358/358 275/275/275 +f 445/445/445 410/410/410 325/325/325 +f 416/416/416 374/374/374 411/411/411 +f 177/177/177 412/412/412 101/101/101 +f 455/455/455 389/389/389 317/317/317 +f 289/289/289 384/384/384 313/313/313 +f 339/339/339 415/415/415 268/268/268 +f 313/313/313 414/414/414 320/320/320 +f 349/349/349 265/265/265 251/251/251 +f 374/374/374 373/373/373 258/258/258 +f 404/404/404 418/418/418 388/388/388 +f 420/420/420 184/184/184 321/321/321 +f 465/465/465 303/303/303 271/271/271 +f 466/466/466 186/186/186 420/420/420 +f 102/102/102 339/339/339 26/26/26 +f 256/256/256 349/349/349 250/250/250 +f 312/312/312 311/311/311 394/394/394 +f 414/414/414 422/422/422 417/417/417 +f 412/412/412 177/177/177 338/338/338 +f 383/383/383 422/422/422 384/384/384 +f 426/426/426 300/300/300 424/424/424 +f 461/461/461 425/425/425 426/426/426 +f 270/270/270 427/427/427 351/351/351 +f 278/278/278 408/408/408 428/428/428 +f 391/391/391 198/198/198 308/308/308 +f 290/290/290 368/368/368 429/429/429 +f 18/18/18 430/430/430 199/199/199 +f 467/467/467 428/428/428 431/431/431 +f 379/379/379 363/363/363 432/432/432 +f 468/468/468 310/310/310 434/434/434 +f 415/415/415 375/375/375 416/416/416 +f 459/459/459 435/435/435 340/340/340 +f 244/244/244 436/436/436 419/419/419 +f 269/269/269 268/268/268 411/411/411 +f 269/269/269 367/367/367 27/27/27 +f 406/406/406 270/270/270 407/407/407 +f 382/382/382 403/403/403 279/279/279 +f 356/356/356 303/303/303 347/347/347 +f 400/400/400 341/341/341 386/386/386 +f 389/389/389 340/340/340 413/413/413 +f 415/415/415 438/438/438 375/375/375 +f 451/451/451 147/147/147 439/439/439 +f 339/339/339 344/344/344 415/415/415 +f 198/198/198 391/391/391 210/210/210 +f 447/447/447 365/365/365 390/390/390 +f 444/444/444 385/385/385 246/246/246 +f 329/329/329 412/412/412 330/330/330 +f 305/305/305 444/444/444 245/245/245 +f 358/358/358 410/410/410 359/359/359 +f 337/337/337 443/443/443 338/338/338 +f 281/281/281 392/392/392 327/327/327 +f 446/446/446 220/220/220 395/395/395 +f 451/451/451 439/439/439 377/377/377 +f 395/395/395 222/222/222 248/248/248 +f 431/431/431 247/247/247 223/223/223 +f 467/467/467 431/431/431 224/224/224 +f 307/307/307 373/373/373 444/444/444 +f 400/400/400 370/370/370 341/341/341 +f 413/413/413 265/265/265 315/315/315 +f 327/327/327 323/323/323 328/328/328 +f 357/357/357 356/356/356 360/360/360 +f 395/395/395 328/328/328 446/446/446 +f 427/427/427 365/365/365 352/352/352 +f 376/376/376 449/449/449 377/377/377 +f 299/299/299 285/285/285 358/358/358 +f 396/396/396 430/430/430 274/274/274 +f 390/390/390 451/451/451 447/447/447 +f 466/466/466 420/420/420 423/423/423 +f 420/420/420 321/321/321 417/417/417 +f 321/321/321 287/287/287 320/320/320 +f 287/287/287 286/286/286 319/319/319 +f 286/286/286 318/318/318 298/298/298 +f 418/418/418 404/404/404 453/453/453 +f 403/403/403 288/288/288 280/280/280 +f 288/288/288 429/429/429 276/276/276 +f 429/429/429 397/397/397 277/277/277 +f 397/397/397 409/409/409 281/281/281 +f 316/316/316 285/285/285 317/317/317 +f 386/386/386 436/436/436 381/381/381 +f 449/449/449 454/454/454 447/447/447 +f 404/404/404 389/389/389 452/452/452 +f 235/235/235 390/390/390 70/70/70 +f 273/273/273 318/318/318 274/274/274 +f 465/465/465 406/406/406 303/303/303 +f 425/425/425 456/456/456 300/300/300 +f 350/350/350 457/457/457 351/351/351 +f 346/346/346 378/378/378 446/446/446 +f 238/238/238 220/220/220 439/439/439 +f 457/457/457 458/458/458 407/407/407 +f 434/434/434 433/433/433 459/459/459 +f 442/442/442 441/441/441 370/370/370 +f 433/433/433 312/312/312 435/435/435 +f 312/312/312 394/394/394 282/282/282 +f 394/394/394 355/355/355 369/369/369 +f 355/355/355 354/354/354 249/249/249 +f 295/295/295 343/343/343 450/450/450 +f 294/294/294 344/344/344 295/295/295 +f 294/294/294 334/334/334 344/344/344 +f 334/334/334 333/333/333 438/438/438 +f 333/333/333 401/401/401 361/361/361 +f 401/401/401 293/293/293 362/362/362 +f 293/293/293 372/372/372 432/432/432 +f 454/454/454 449/449/449 398/398/398 +f 458/458/458 457/457/457 460/460/460 +f 458/458/458 460/460/460 345/345/345 +f 452/452/452 455/455/455 425/425/425 +f 454/454/454 398/398/398 350/350/350 +f 455/455/455 317/317/317 456/456/456 +f 257/257/257 354/354/354 331/331/331 +f 254/254/254 257/257/257 330/330/330 +f 255/255/255 254/254/254 443/443/443 +f 360/360/360 255/255/255 337/337/337 +f 427/427/427 272/272/272 365/365/365 +f 357/357/357 360/360/360 336/336/336 +f 272/272/272 357/357/357 366/366/366 +f 453/453/453 452/452/452 461/461/461 +f 400/400/400 386/386/386 380/380/380 +f 468/468/468 434/434/434 462/462/462 +f 434/434/434 459/459/459 441/441/441 +# 852 faces + diff --git a/app/src/main/assets/out.png b/app/src/main/assets/out.png index 889a6ad..3593cd2 100644 Binary files a/app/src/main/assets/out.png and b/app/src/main/assets/out.png differ diff --git a/app/src/main/assets/shaders/bg.frag b/app/src/main/assets/shaders/bg.frag index ee29b3d..52a3257 100644 --- a/app/src/main/assets/shaders/bg.frag +++ b/app/src/main/assets/shaders/bg.frag @@ -9,7 +9,33 @@ layout(location = 0) out vec4 outColor; // 纹理采样器 layout(binding = 0) uniform sampler2D texSampler; +layout(push_constant) uniform PushConstants { + float zoom; + float r; + float g; + float b; + float radius; + float ux; + float uy; +} pushConstants; + void main() { - // 采样纹理 - outColor = texture(texSampler, inTexCoord); + // outFragColor = color; + // 获取当前片元的屏幕坐标(左下角为原点) + vec2 fragCoord = gl_FragCoord.xy; + + // 屏幕中心(480x480 的中心是 (240, 240)) + vec2 center = vec2(240.0, 240.0); + + // 计算到中心的距离(欧氏距离,单位:像素) + float dist = length(fragCoord - center); + + // 判断是否在半径之外 + if (dist > pushConstants.radius) { + // 使用 push constant 中的 RGB 颜色(注意 alpha 设为 1.0) + outColor = vec4(pushConstants.r, pushConstants.g, pushConstants.b, 1.0); + } else { + // 采样纹理 + outColor = texture(texSampler, inTexCoord); + } } \ No newline at end of file diff --git a/app/src/main/assets/shaders/bg.frag.spv b/app/src/main/assets/shaders/bg.frag.spv index 8642dc5..dcb02d2 100644 Binary files a/app/src/main/assets/shaders/bg.frag.spv and b/app/src/main/assets/shaders/bg.frag.spv differ diff --git a/app/src/main/assets/shaders/bg.vert b/app/src/main/assets/shaders/bg.vert index 5ff8f1b..4d90fb5 100644 --- a/app/src/main/assets/shaders/bg.vert +++ b/app/src/main/assets/shaders/bg.vert @@ -38,7 +38,15 @@ const vec2 texCoords[6] = vec2[6]( // 定义 Push Constant,只有一个 float layout(push_constant) uniform PushConstants { - float myValue; + float zoom; + float r; + float g; + float b; + float radius; + float ux; + float uy; + float offset_x; + float offset_y; } pushConstants; @@ -48,7 +56,9 @@ layout(location = 0) out vec2 outTexCoord; void main() { // 获取顶点位置 vec2 position = positions[gl_VertexIndex]; - position = position * pushConstants.myValue; + position = position * pushConstants.zoom; + position.x = position.x + (pushConstants.offset_x/480); + position.y = position.y + (pushConstants.offset_y/480); // 设置输出位置(Vulkan使用不同的坐标系) gl_Position = vec4(position, 0.0, 1.0); diff --git a/app/src/main/assets/shaders/bg.vert.spv b/app/src/main/assets/shaders/bg.vert.spv index f261695..d26a9d5 100644 Binary files a/app/src/main/assets/shaders/bg.vert.spv and b/app/src/main/assets/shaders/bg.vert.spv differ diff --git a/app/src/main/assets/shaders/texture.frag b/app/src/main/assets/shaders/texture.frag index 79cefca..e228877 100644 --- a/app/src/main/assets/shaders/texture.frag +++ b/app/src/main/assets/shaders/texture.frag @@ -5,13 +5,40 @@ layout (binding = 1) uniform sampler2D samplerColor; layout (location = 0) in vec2 inUV; layout (location = 1) in vec3 inNormal; +layout(push_constant) uniform PushConstants { + float zoom; + float r; + float g; + float b; + float radius; + float ux; + float uy; +} pushConstants; + layout (location = 0) out vec4 outFragColor; void main() { - vec4 color = texture(samplerColor, inUV); + // outFragColor = color; + // 获取当前片元的屏幕坐标(左下角为原点) + vec2 fragCoord = gl_FragCoord.xy; - outFragColor = color; + // 屏幕中心(480x480 的中心是 (240, 240)) + vec2 center = vec2(240.0, 240.0); + + // 计算到中心的距离(欧氏距离,单位:像素) + float dist = length(fragCoord - center); + + // 判断是否在半径之外 + if (dist > pushConstants.radius) { + // 使用 push constant 中的 RGB 颜色(注意 alpha 设为 1.0) + outFragColor = vec4(pushConstants.r, pushConstants.g, pushConstants.b, 1.0); + } else { + vec2 pos = vec2(pushConstants.ux/4096.f, pushConstants.uy/2048.f); + vec2 uv = pos + vec2(inUV.x/8.f, inUV.y/4.f); + vec4 color = texture(samplerColor, uv); + outFragColor = color; + } } \ No newline at end of file diff --git a/app/src/main/assets/shaders/texture.frag.spv b/app/src/main/assets/shaders/texture.frag.spv index 023edc1..0c4f42b 100644 Binary files a/app/src/main/assets/shaders/texture.frag.spv and b/app/src/main/assets/shaders/texture.frag.spv differ diff --git a/app/src/main/assets/shaders/texture.vert b/app/src/main/assets/shaders/texture.vert index 183bc7b..92a3ec8 100644 --- a/app/src/main/assets/shaders/texture.vert +++ b/app/src/main/assets/shaders/texture.vert @@ -17,7 +17,15 @@ layout (location = 0) out vec2 outUV; layout (location = 1) out vec3 outNormal; layout(push_constant) uniform PushConstants { - float myValue; + float zoom; + float r; + float g; + float b; + float radius; + float ux; + float uy; + float offset_x; + float offset_y; } pushConstants; out gl_PerVertex @@ -30,7 +38,9 @@ void main() outUV = inUV; vec2 position = vec2(inPos.xy*2 -1); - position = position * pushConstants.myValue; + position = position * pushConstants.zoom; + position.x = position.x + (pushConstants.offset_x/480); + position.y = position.y + (pushConstants.offset_y/480); gl_Position = vec4(position, 0.5, 1.0); vec4 pos = ubo.model * vec4(inPos, 1.0); diff --git a/app/src/main/assets/shaders/texture.vert.spv b/app/src/main/assets/shaders/texture.vert.spv index d407944..357e47a 100644 Binary files a/app/src/main/assets/shaders/texture.vert.spv and b/app/src/main/assets/shaders/texture.vert.spv differ diff --git a/app/src/main/cpp/CrashHandler.cpp b/app/src/main/cpp/CrashHandler.cpp new file mode 100644 index 0000000..c7c997e --- /dev/null +++ b/app/src/main/cpp/CrashHandler.cpp @@ -0,0 +1,512 @@ +// CrashHandler.cpp +// +// Async-signal-safe crash dumper for the face_sdk native library. The goal +// is that the next time the app dies (e.g. another FORTIFY: pthread_mutex_lock +// called on a destroyed mutex from inside the Vulkan driver) we don't only +// have logcat — we also have a self-contained dump on the device's app data +// directory that the user can pull off and send back, even after a reboot. +// +// Why we need this: +// - DebugLog only writes "happy path" events. The Vulkan crash happens +// synchronously inside vkQueueSubmit / vkFreeCommandBuffers — there is +// no DebugLog call near the crash site, so the file log just stops. +// - logcat survives across the crash (debuggerd dumps the backtrace there) +// but logcat is volatile: a couple of reboots, a logcat -c, or a long +// idle period and it's gone. We want a persistent file. +// - tombstones in /data/tombstones/ are root-only on consumer devices. +// +// Implementation notes: +// - Inside a signal handler we MUST stick to async-signal-safe APIs +// (man 7 signal-safety). That rules out fprintf / snprintf / malloc. +// We use write(), our own integer-to-string conversion, and a single +// pre-opened fd. dladdr() is technically not on the POSIX safe list but +// bionic's implementation only takes one rwlock and is widely used in +// other crash dumpers (breakpad, crashpad, libunwindstack). We accept +// that risk because the alternative is no symbol at all. +// - We use (_Unwind_Backtrace) instead of execinfo.h because +// bionic doesn't ship execinfo.h on all NDK levels, and _Unwind_Backtrace +// is the same primitive Android's own tombstoned uses. +// - We re-raise the original signal with the default handler at the end so +// the OS still produces a tombstone / ANR record for vendors that +// read /data/tombstones/. + +#include "CrashHandler.h" + +#ifndef _WIN32 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace { + +// ---------- Globals (touched from the handler -> only POD/atomics) --------- + +constexpr size_t kCrashStackSize = 64 * 1024; // sigaltstack +constexpr size_t kMaxFrames = 64; +constexpr size_t kNoteCapacity = 256; + +uint8_t g_sigStack[kCrashStackSize]; +int g_crashFd = -1; // crash log fd (append, sync) +int g_debugFd = -1; // optional: also dup write to debug log +std::atomic g_installed{false}; +std::atomic g_handlingCrash{false}; + +// Single writer of g_note: setNote() (uses memcpy under a tiny lock, but the +// handler reads byte-by-byte so a torn read at most produces a truncated +// note, never a deref of bad memory). +char g_note[kNoteCapacity] = {0}; +pthread_mutex_t g_noteMtx = PTHREAD_MUTEX_INITIALIZER; + +const int g_signals[] = { SIGSEGV, SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSYS }; +constexpr size_t kNumSignals = sizeof(g_signals) / sizeof(g_signals[0]); + +// ----------------------- Async-signal-safe writers ------------------------- + +// Write a NUL-terminated string. Drops the trailing NUL. +void sigWrite(int fd, const char* s) { + if (fd < 0 || !s) return; + size_t n = 0; + while (s[n]) ++n; + if (n == 0) return; + // Loop until everything is written or we error out. Async-safe. + while (n > 0) { + ssize_t w = write(fd, s, n); + if (w <= 0) { + if (w < 0 && errno == EINTR) continue; + return; + } + s += w; + n -= (size_t)w; + } +} + +// Write n bytes from buf. Used for the note (may contain anything). +void sigWriteN(int fd, const char* buf, size_t n) { + if (fd < 0 || !buf) return; + while (n > 0) { + ssize_t w = write(fd, buf, n); + if (w <= 0) { + if (w < 0 && errno == EINTR) continue; + return; + } + buf += w; + n -= (size_t)w; + } +} + +// Write the same string to both the crash log and the debug log (if any). +void sigDump(const char* s) { + sigWrite(g_crashFd, s); + sigWrite(g_debugFd, s); +} + +// Convert an unsigned integer to its decimal representation. Returns the +// number of characters written into buf (without a NUL). +size_t u64ToDec(uint64_t v, char* buf, size_t cap) { + if (cap == 0) return 0; + char tmp[32]; + size_t i = 0; + if (v == 0) { + tmp[i++] = '0'; + } else { + while (v && i < sizeof(tmp)) { + tmp[i++] = (char)('0' + (v % 10)); + v /= 10; + } + } + size_t out = (i < cap) ? i : cap; + for (size_t k = 0; k < out; ++k) { + buf[k] = tmp[i - 1 - k]; + } + return out; +} + +// Convert an unsigned 64-bit value to a fixed-width 16-digit hex string. +// Useful for PC values. +size_t u64ToHex16(uint64_t v, char* buf, size_t cap) { + static const char digits[] = "0123456789abcdef"; + if (cap < 16) return 0; + for (int i = 15; i >= 0; --i) { + buf[i] = digits[v & 0xF]; + v >>= 4; + } + return 16; +} + +// Write "=\n". +void sigWriteKV_u64(int fd, const char* key, uint64_t v) { + sigWrite(fd, key); + sigWrite(fd, "="); + char num[24]; + size_t n = u64ToDec(v, num, sizeof(num)); + sigWriteN(fd, num, n); + sigWrite(fd, "\n"); +} + +// Write "=0x\n". +void sigWriteKV_ptr(int fd, const char* key, uint64_t v) { + sigWrite(fd, key); + sigWrite(fd, "=0x"); + char hx[16]; + u64ToHex16(v, hx, sizeof(hx)); + sigWriteN(fd, hx, 16); + sigWrite(fd, "\n"); +} + +// ------------------------- Signal name lookup ------------------------------ + +const char* signalName(int signo) { + switch (signo) { + case SIGSEGV: return "SIGSEGV"; + case SIGABRT: return "SIGABRT"; + case SIGBUS: return "SIGBUS"; + case SIGFPE: return "SIGFPE"; + case SIGILL: return "SIGILL"; + case SIGSYS: return "SIGSYS"; + case SIGTRAP: return "SIGTRAP"; + default: return "SIG?"; + } +} + +// si_code to short string. Only the most common ones; everything else falls +// back to the numeric value via sigWriteKV_u64. +const char* siCodeName(int signo, int code) { + switch (signo) { + case SIGSEGV: + if (code == SEGV_MAPERR) return "SEGV_MAPERR"; + if (code == SEGV_ACCERR) return "SEGV_ACCERR"; + break; + case SIGBUS: + if (code == BUS_ADRALN) return "BUS_ADRALN"; + if (code == BUS_ADRERR) return "BUS_ADRERR"; + if (code == BUS_OBJERR) return "BUS_OBJERR"; + break; + case SIGFPE: + if (code == FPE_INTDIV) return "FPE_INTDIV"; + if (code == FPE_INTOVF) return "FPE_INTOVF"; + if (code == FPE_FLTDIV) return "FPE_FLTDIV"; + break; + case SIGILL: + if (code == ILL_ILLOPC) return "ILL_ILLOPC"; + if (code == ILL_ILLOPN) return "ILL_ILLOPN"; + break; + case SIGABRT: + if (code == SI_TKILL) return "SI_TKILL"; + if (code == SI_USER) return "SI_USER"; + break; + } + return "?"; +} + +// ------------------------- Backtrace via _Unwind_Backtrace ----------------- + +struct UnwindCtx { + uintptr_t* frames; + size_t count; + size_t cap; +}; + +_Unwind_Reason_Code unwindCallback(_Unwind_Context* ctx, void* arg) { + UnwindCtx* uc = static_cast(arg); + if (uc->count >= uc->cap) return _URC_END_OF_STACK; + + uintptr_t pc = _Unwind_GetIP(ctx); + if (pc) { + // Trim Thumb bit on 32-bit ARM. No-op on aarch64/x86_64. + pc &= ~(uintptr_t)1; + uc->frames[uc->count++] = pc; + } + return _URC_NO_REASON; +} + +size_t captureBacktrace(uintptr_t* out, size_t cap) { + UnwindCtx uc{out, 0, cap}; + _Unwind_Backtrace(&unwindCallback, &uc); + return uc.count; +} + +// Dump one frame: " #02 pc 000000000000abcd /path/lib.so (Symbol+0x10)" +void dumpFrame(int fd, size_t idx, uintptr_t pc) { + sigWrite(fd, " #"); + char num[8]; + if (idx < 10) { + num[0] = '0'; + num[1] = (char)('0' + idx); + sigWriteN(fd, num, 2); + } else { + size_t n = u64ToDec(idx, num, sizeof(num)); + sigWriteN(fd, num, n); + } + sigWrite(fd, " pc "); + char hx[16]; + u64ToHex16((uint64_t)pc, hx, sizeof(hx)); + sigWriteN(fd, hx, 16); + + Dl_info info; + memset(&info, 0, sizeof(info)); + if (dladdr(reinterpret_cast(pc), &info) && info.dli_fname) { + sigWrite(fd, " "); + sigWrite(fd, info.dli_fname); + + if (info.dli_sname) { + uintptr_t sym = reinterpret_cast(info.dli_saddr); + uintptr_t off = (sym && pc >= sym) ? (pc - sym) : 0; + sigWrite(fd, " ("); + sigWrite(fd, info.dli_sname); + sigWrite(fd, "+0x"); + char ohx[16]; + u64ToHex16((uint64_t)off, ohx, sizeof(ohx)); + sigWriteN(fd, ohx, 16); + sigWrite(fd, ")"); + } else if (info.dli_fbase) { + uintptr_t base = reinterpret_cast(info.dli_fbase); + uintptr_t off = (pc >= base) ? (pc - base) : 0; + sigWrite(fd, " (offset 0x"); + char ohx[16]; + u64ToHex16((uint64_t)off, ohx, sizeof(ohx)); + sigWriteN(fd, ohx, 16); + sigWrite(fd, ")"); + } + } + sigWrite(fd, "\n"); +} + +// ------------------------- Time + tid helpers ------------------------------ + +// Builds "YYYY-MM-DD HH:MM:SS.mmm UTC" into the given buffer (no NUL). +// Returns the number of bytes written. Async-signal-safe (no stdio, no +// localtime_r tz lookups). +size_t formatTimestamp(char* b, size_t cap) { + timespec ts{}; + clock_gettime(CLOCK_REALTIME, &ts); + struct tm tm_info{}; + time_t s = ts.tv_sec; + gmtime_r(&s, &tm_info); + + size_t i = 0; + auto putUInt = [&](unsigned v, int width) { + char tmp[8]; + size_t n = u64ToDec(v, tmp, sizeof(tmp)); + while ((int)n < (size_t)width) { + if (i < cap) b[i++] = '0'; + ++n; + } + for (size_t k = 0; k < n; ++k) { + if (i < cap) b[i++] = tmp[k]; + } + }; + + putUInt((unsigned)(tm_info.tm_year + 1900), 4); if (i < cap) b[i++] = '-'; + putUInt((unsigned)(tm_info.tm_mon + 1), 2); if (i < cap) b[i++] = '-'; + putUInt((unsigned)(tm_info.tm_mday), 2); if (i < cap) b[i++] = ' '; + putUInt((unsigned)(tm_info.tm_hour), 2); if (i < cap) b[i++] = ':'; + putUInt((unsigned)(tm_info.tm_min), 2); if (i < cap) b[i++] = ':'; + putUInt((unsigned)(tm_info.tm_sec), 2); if (i < cap) b[i++] = '.'; + putUInt((unsigned)(ts.tv_nsec / 1000000), 3); + static const char kSuffix[] = " UTC"; + for (size_t k = 0; k < sizeof(kSuffix) - 1; ++k) { + if (i < cap) b[i++] = kSuffix[k]; + } + return i; +} + +pid_t currentTid() { + return static_cast(syscall(SYS_gettid)); +} + +// ------------------------- Signal handler ---------------------------------- + +void crashHandler(int signo, siginfo_t* info, void* ucontext) { + (void)ucontext; + + // Re-entry guard: if a second signal fires while we're dumping (e.g. our + // own dladdr trips a SIGSEGV) just chain to the default handler. + bool expected = false; + if (!g_handlingCrash.compare_exchange_strong(expected, true, + std::memory_order_acq_rel)) { + // Already in handler -> default + bail. + signal(signo, SIG_DFL); + raise(signo); + return; + } + + sigDump("\n========== FACE_SDK CRASH ==========\n"); + sigDump("time="); + { + char tsbuf[48]; + size_t tn = formatTimestamp(tsbuf, sizeof(tsbuf)); + sigWriteN(g_crashFd, tsbuf, tn); + sigWriteN(g_debugFd, tsbuf, tn); + } + sigDump("\n"); + + sigDump("signal="); + sigDump(signalName(signo)); + sigDump(" code="); + sigDump(siCodeName(signo, info ? info->si_code : 0)); + sigDump("\n"); + + if (info) { + sigWriteKV_u64(g_crashFd, "si_signo", (uint64_t)info->si_signo); + sigWriteKV_u64(g_debugFd, "si_signo", (uint64_t)info->si_signo); + sigWriteKV_u64(g_crashFd, "si_code", (uint64_t)info->si_code); + sigWriteKV_u64(g_debugFd, "si_code", (uint64_t)info->si_code); + sigWriteKV_ptr(g_crashFd, "si_addr", (uint64_t)(uintptr_t)info->si_addr); + sigWriteKV_ptr(g_debugFd, "si_addr", (uint64_t)(uintptr_t)info->si_addr); + } + sigWriteKV_u64(g_crashFd, "pid", (uint64_t)getpid()); + sigWriteKV_u64(g_debugFd, "pid", (uint64_t)getpid()); + sigWriteKV_u64(g_crashFd, "tid", (uint64_t)currentTid()); + sigWriteKV_u64(g_debugFd, "tid", (uint64_t)currentTid()); + + // Note (current frame index, current motion, ...). + sigDump("note="); + sigWriteN(g_crashFd, g_note, strnlen(g_note, kNoteCapacity)); + sigWriteN(g_debugFd, g_note, strnlen(g_note, kNoteCapacity)); + sigDump("\n"); + + sigDump("backtrace:\n"); + uintptr_t frames[kMaxFrames]; + size_t nf = captureBacktrace(frames, kMaxFrames); + for (size_t i = 0; i < nf; ++i) { + dumpFrame(g_crashFd, i, frames[i]); + dumpFrame(g_debugFd, i, frames[i]); + } + sigDump("==================================\n"); + + // Make sure everything reaches disk before we self-destruct. + if (g_crashFd >= 0) fsync(g_crashFd); + if (g_debugFd >= 0) fsync(g_debugFd); + + // Mirror to logcat too so a quick `adb logcat -d` after a reboot still + // shows the SIGNAL line (helps cross-checking the file). + __android_log_print(ANDROID_LOG_FATAL, "FACE_DBG_CRASH", + "fatal %s @ tid=%d, see face_sdk_crash.log", + signalName(signo), currentTid()); + + // Restore default handler and re-raise. This produces /data/tombstones/* + // on rooted devices and tells debuggerd to print the official Android + // backtrace into logcat (`crash_dump64 ... DEBUG`). + struct sigaction dfl{}; + dfl.sa_handler = SIG_DFL; + sigemptyset(&dfl.sa_mask); + sigaction(signo, &dfl, nullptr); + raise(signo); +} + +} // namespace + +namespace CrashHandler { + +void install(const std::string& internalDataPath, + const std::string& debugLogPath) { + bool expected = false; + if (!g_installed.compare_exchange_strong(expected, true, + std::memory_order_acq_rel)) { + return; // already installed + } + + // Open the persistent crash log file in append mode. We keep it open + // forever so the signal handler doesn't have to call open() (which is + // safe but slow). + { + std::string path = internalDataPath.empty() + ? std::string("/data/local/tmp/face_sdk_crash.log") + : internalDataPath + "/face_sdk_crash.log"; + g_crashFd = open(path.c_str(), + O_WRONLY | O_CREAT | O_APPEND | O_CLOEXEC, + 0644); + if (g_crashFd >= 0) { + // Header for the new run. + sigWrite(g_crashFd, "\n=== CrashHandler installed pid="); + char pidbuf[16]; + size_t n = u64ToDec((uint64_t)getpid(), pidbuf, sizeof(pidbuf)); + sigWriteN(g_crashFd, pidbuf, n); + sigWrite(g_crashFd, " ===\n"); + fsync(g_crashFd); + __android_log_print(ANDROID_LOG_INFO, "FACE_DBG", + "CrashHandler log file: %s", path.c_str()); + } else { + __android_log_print(ANDROID_LOG_WARN, "FACE_DBG", + "CrashHandler failed to open %s: %s", + path.c_str(), strerror(errno)); + } + } + + // Also keep a writable fd to the DebugLog file (if any) so dumps land + // next to the regular tail of the log. We don't touch g_fp inside + // DebugLog because that would need its mutex — not safe in handler. + if (!debugLogPath.empty()) { + g_debugFd = open(debugLogPath.c_str(), + O_WRONLY | O_APPEND | O_CLOEXEC, + 0644); + if (g_debugFd < 0) { + __android_log_print(ANDROID_LOG_WARN, "FACE_DBG", + "CrashHandler: cannot open debug log %s: %s", + debugLogPath.c_str(), strerror(errno)); + } + } + + // Set up an alternate stack so we still have stack space if the original + // thread ran out (very common for Vulkan crashes inside deep driver + // call chains). + stack_t ss{}; + ss.ss_sp = g_sigStack; + ss.ss_size = sizeof(g_sigStack); + ss.ss_flags = 0; + if (sigaltstack(&ss, nullptr) != 0) { + __android_log_print(ANDROID_LOG_WARN, "FACE_DBG", + "CrashHandler: sigaltstack failed: %s", + strerror(errno)); + } + + struct sigaction sa{}; + sa.sa_sigaction = &crashHandler; + sa.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART; + sigemptyset(&sa.sa_mask); + + for (size_t i = 0; i < kNumSignals; ++i) { + if (sigaction(g_signals[i], &sa, nullptr) != 0) { + __android_log_print(ANDROID_LOG_WARN, "FACE_DBG", + "CrashHandler: sigaction(%d) failed: %s", + g_signals[i], strerror(errno)); + } + } + + __android_log_print(ANDROID_LOG_INFO, "FACE_DBG", + "CrashHandler installed for SIGSEGV/SIGABRT/SIGBUS/SIGFPE/SIGILL/SIGSYS"); +} + +void setNote(const char* note) { + if (!note) note = ""; + pthread_mutex_lock(&g_noteMtx); + size_t n = strnlen(note, kNoteCapacity - 1); + memcpy(g_note, note, n); + g_note[n] = '\0'; + pthread_mutex_unlock(&g_noteMtx); +} + +} // namespace CrashHandler + +#else // _WIN32 — no-op on host build + +namespace CrashHandler { +void install(const std::string&, const std::string&) {} +void setNote(const char*) {} +} // namespace CrashHandler + +#endif diff --git a/app/src/main/cpp/CrashHandler.h b/app/src/main/cpp/CrashHandler.h new file mode 100644 index 0000000..798316a --- /dev/null +++ b/app/src/main/cpp/CrashHandler.h @@ -0,0 +1,33 @@ +#ifndef FACE_SDK_CRASH_HANDLER_H +#define FACE_SDK_CRASH_HANDLER_H + +#include + +namespace CrashHandler { + +// Install signal handlers for SIGSEGV / SIGABRT / SIGBUS / SIGFPE / SIGILL. +// +// On a fatal signal we: +// 1) Switch to a pre-allocated 64KB sigaltstack so we still have stack +// space even if the original thread's stack was the cause. +// 2) Write a self-contained crash record to /face_sdk_crash.log +// (and also try to append it to the DebugLog file passed in). +// The record contains: signal name, si_code, si_addr, pid, tid, +// a synchronous unwound backtrace (PC + module + offset for each frame), +// and the value of any extra context the caller registered via setNote(). +// 3) Re-raise the original signal with the default handler so that the +// Android tombstone pipeline still produces /data/tombstones/* files. +// +// Safe to call once. Subsequent calls are no-ops. Must be called AFTER +// DebugLog::init() so we know the log directory. +void install(const std::string& internalDataPath, + const std::string& debugLogPath = ""); + +// Optional short note (<= 256 chars) appended to every crash dump from now on. +// Useful to record "current frame index", "current motion", etc. so we know +// what was happening at the moment of the crash. Async-signal-safe to read. +void setNote(const char* note); + +} // namespace CrashHandler + +#endif // FACE_SDK_CRASH_HANDLER_H diff --git a/app/src/main/cpp/DebugLog.cpp b/app/src/main/cpp/DebugLog.cpp new file mode 100644 index 0000000..c24881f --- /dev/null +++ b/app/src/main/cpp/DebugLog.cpp @@ -0,0 +1,165 @@ +#include "DebugLog.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +namespace { + +std::mutex g_mtx; +FILE* g_fp = nullptr; +std::string g_path; +constexpr size_t kMaxSize = 2 * 1024 * 1024; // 2 MB before rotation + +// Throttle bookkeeping: one slot per distinct key passed to log_throttled(). +struct ThrottleSlot { + int64_t last_emit_ms = 0; // when we last actually wrote a line for this key + uint32_t suppressed = 0; // number of calls swallowed since last_emit_ms +}; +std::unordered_map g_throttle; +constexpr int64_t kThrottleWindowMs = 2000; // 2 seconds + +pid_t currentTid() { + return static_cast(syscall(SYS_gettid)); +} + +int64_t nowMs() { + timespec ts{}; + clock_gettime(CLOCK_MONOTONIC, &ts); + return static_cast(ts.tv_sec) * 1000 + ts.tv_nsec / 1000000; +} + +// Assumes g_mtx is held. Writes a single pre-formatted line to disk + logcat. +void writeLineLocked(const char* body) { + pid_t tid = currentTid(); + + timespec ts{}; + clock_gettime(CLOCK_REALTIME, &ts); + struct tm tm_info{}; + localtime_r(&ts.tv_sec, &tm_info); + char timebuf[32]; + strftime(timebuf, sizeof(timebuf), "%H:%M:%S", &tm_info); + + if (g_fp) { + std::fprintf(g_fp, "[%s.%03ld][tid=%d] %s\n", + timebuf, ts.tv_nsec / 1000000, tid, body); + std::fflush(g_fp); + } + __android_log_print(ANDROID_LOG_INFO, "FACE_DBG", "[tid=%d] %s", tid, body); +} + +} // namespace + +namespace DebugLog { + +void init(const char* internalDataPath) { + std::lock_guard lk(g_mtx); + if (g_fp) { + return; // already initialized + } + + const char* base = (internalDataPath && *internalDataPath) ? internalDataPath : "/data/local/tmp"; + g_path = std::string(base) + "/face_sdk_debug.log"; + + // Rotate once if current file is too large. + struct stat st{}; + if (stat(g_path.c_str(), &st) == 0 && static_cast(st.st_size) > kMaxSize) { + std::string backup = g_path + ".old"; + std::remove(backup.c_str()); + std::rename(g_path.c_str(), backup.c_str()); + } + + g_fp = std::fopen(g_path.c_str(), "a"); + if (g_fp) { + time_t now = time(nullptr); + struct tm tm_info{}; + localtime_r(&now, &tm_info); + char tbuf[64]; + strftime(tbuf, sizeof(tbuf), "%Y-%m-%d %H:%M:%S", &tm_info); + std::fprintf(g_fp, + "\n========== DebugLog opened @ %s (pid=%d) ==========\n", + tbuf, getpid()); + std::fflush(g_fp); + } + + __android_log_print(ANDROID_LOG_INFO, "FACE_DBG", + "DebugLog file path: %s", g_path.c_str()); +} + +void log(const char* fmt, ...) { + char buf[1024]; + va_list ap; + va_start(ap, fmt); + int n = std::vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + if (n < 0) return; + + std::lock_guard lk(g_mtx); + writeLineLocked(buf); +} + +void log_throttled(const char* key, const char* fmt, ...) { + char buf[1024]; + va_list ap; + va_start(ap, fmt); + int n = std::vsnprintf(buf, sizeof(buf), fmt, ap); + va_end(ap); + if (n < 0) return; + + const char* k = key ? key : ""; + int64_t now = nowMs(); + + std::lock_guard lk(g_mtx); + auto it = g_throttle.find(k); + if (it == g_throttle.end()) { + // First time we see this key -> always log. + ThrottleSlot slot; + slot.last_emit_ms = now; + slot.suppressed = 0; + g_throttle.emplace(k, slot); + writeLineLocked(buf); + return; + } + + ThrottleSlot& slot = it->second; + int64_t elapsed = now - slot.last_emit_ms; + if (elapsed < kThrottleWindowMs) { + // Still inside the 2s window -> swallow. + ++slot.suppressed; + return; + } + + // Window elapsed: emit the line, annotated with how many we swallowed. + if (slot.suppressed > 0) { + char annotated[1200]; + std::snprintf(annotated, sizeof(annotated), + "%s (repeated %u times in last %lldms, key=%s)", + buf, slot.suppressed, (long long)elapsed, k); + writeLineLocked(annotated); + } else { + writeLineLocked(buf); + } + slot.last_emit_ms = now; + slot.suppressed = 0; +} + +void flush() { + std::lock_guard lk(g_mtx); + if (g_fp) std::fflush(g_fp); +} + +std::string getLogPath() { + std::lock_guard lk(g_mtx); + return g_path; +} + +} // namespace DebugLog diff --git a/app/src/main/cpp/DebugLog.h b/app/src/main/cpp/DebugLog.h new file mode 100644 index 0000000..6691588 --- /dev/null +++ b/app/src/main/cpp/DebugLog.h @@ -0,0 +1,33 @@ +#ifndef FACE_SDK_DEBUGLOG_H +#define FACE_SDK_DEBUGLOG_H + +#include + +namespace DebugLog { + +// Call once (e.g. in android_main) with android_app->activity->internalDataPath. +// Safe to call multiple times; subsequent calls are no-ops. +void init(const char* internalDataPath); + +// Thread-safe. Also mirrored to logcat with tag "FACE_DBG". +// Every line is prefixed with timestamp + thread id and flushed to disk immediately, +// so even a hard crash will preserve the tail. +void log(const char* fmt, ...) __attribute__((format(printf, 1, 2))); + +// Throttled variant keyed by a caller-supplied string. +// - The first call with a given key is always written. +// - Subsequent calls with the same key within 2 seconds are suppressed. +// - When the throttle window elapses, the next matching call is written with a +// "(repeated N times in last Xms)" suffix describing the suppressed ones. +// Use stable, short keys (e.g. "drawFrame.acquire", "drawFrame.present"). +void log_throttled(const char* key, const char* fmt, ...) __attribute__((format(printf, 2, 3))); + +// Force flush to disk. +void flush(); + +// Absolute path of the log file (valid after init()). +std::string getLogPath(); + +} // namespace DebugLog + +#endif // FACE_SDK_DEBUGLOG_H diff --git a/app/src/main/cpp/main.cpp b/app/src/main/cpp/main.cpp index 8ab891d..e22efc7 100644 --- a/app/src/main/cpp/main.cpp +++ b/app/src/main/cpp/main.cpp @@ -3,42 +3,106 @@ #include #include #include "AndroidOut.h" +#include "DebugLog.h" +#include "CrashHandler.h" #include "FaceApp.h" #include +#include +#include +#include #include +#include #include using namespace std; + +static inline pid_t dbg_tid() { + return static_cast(syscall(SYS_gettid)); +} + +static const char* appCmdName(int32_t cmd) { + switch (cmd) { + case APP_CMD_INIT_WINDOW: return "APP_CMD_INIT_WINDOW"; + case APP_CMD_TERM_WINDOW: return "APP_CMD_TERM_WINDOW"; + case APP_CMD_WINDOW_RESIZED: return "APP_CMD_WINDOW_RESIZED"; + case APP_CMD_WINDOW_REDRAW_NEEDED: return "APP_CMD_WINDOW_REDRAW_NEEDED"; + case APP_CMD_CONTENT_RECT_CHANGED: return "APP_CMD_CONTENT_RECT_CHANGED"; + case APP_CMD_GAINED_FOCUS: return "APP_CMD_GAINED_FOCUS"; + case APP_CMD_LOST_FOCUS: return "APP_CMD_LOST_FOCUS"; + case APP_CMD_CONFIG_CHANGED: return "APP_CMD_CONFIG_CHANGED"; + case APP_CMD_LOW_MEMORY: return "APP_CMD_LOW_MEMORY"; + case APP_CMD_START: return "APP_CMD_START"; + case APP_CMD_RESUME: return "APP_CMD_RESUME"; + case APP_CMD_SAVE_STATE: return "APP_CMD_SAVE_STATE"; + case APP_CMD_PAUSE: return "APP_CMD_PAUSE"; + case APP_CMD_STOP: return "APP_CMD_STOP"; + case APP_CMD_DESTROY: return "APP_CMD_DESTROY"; + default: return "APP_CMD_???"; + } +} + extern "C" { android_app* g_android_app = nullptr; FaceApp* g_Application = nullptr; AAssetManager* g_assetManager = nullptr; +jobject g_callback = nullptr; +jobject g_callbackAnimationFinished = nullptr; + void handle_cmd(android_app *pApp, int32_t cmd) { + DebugLog::log(">> handle_cmd %s(%d) tid=%d", appCmdName(cmd), (int)cmd, dbg_tid()); switch (cmd) { case APP_CMD_INIT_WINDOW: aout << "APP_CMD_INIT_WINDOW" << std::endl; - g_Application->initVulkan(); + DebugLog::log("handle_cmd APP_CMD_INIT_WINDOW: calling onWindowInit()"); + if (g_Application != nullptr) { + g_Application->onWindowInit(); + DebugLog::log("handle_cmd APP_CMD_INIT_WINDOW: onWindowInit() returned, isInited=%d", + (int)g_Application->isInited()); + } else { + DebugLog::log("handle_cmd APP_CMD_INIT_WINDOW: g_Application is null, skipping"); + } break; case APP_CMD_TERM_WINDOW: aout << "APP_CMD_TERM_WINDOW" << std::endl; + DebugLog::log("handle_cmd APP_CMD_TERM_WINDOW: calling onWindowLost()"); + if (g_Application != nullptr) { + g_Application->onWindowLost(); + } + DebugLog::log("handle_cmd APP_CMD_TERM_WINDOW: onWindowLost() returned"); break; default: break; } + DebugLog::log("<< handle_cmd %s done", appCmdName(cmd)); } const int ArgLen = 128*1024; char g_InitArgString[ArgLen] = {0}; void android_main(struct android_app *pApp) { + DebugLog::init(pApp->activity->internalDataPath); + // 安装信号处理器越早越好:之前的 FORTIFY: pthread_mutex_lock 崩溃 + // 是裸的 SIGABRT,没有任何 signal handler,所以 DebugLog 文件停在最后 + // 一条业务日志、看不到任何崩溃栈。装上之后任何 fatal signal 都会把: + // * 信号名 / si_code / si_addr / pid / tid / 当前 note + // * 完整 backtrace(PC + 模块 + 符号 + 偏移) + // 同步落到 internalDataPath/face_sdk_crash.log(以及 DebugLog 文件尾), + // 然后再走默认 handler 让 debuggerd 产生 tombstone。 + CrashHandler::install(pApp->activity->internalDataPath, + DebugLog::getLogPath()); + DebugLog::log("android_main start, pid=%d tid=%d, logPath=%s", + getpid(), dbg_tid(), DebugLog::getLogPath().c_str()); aout << "Welcome to android_main" << std::endl; g_android_app = pApp; g_assetManager = pApp->activity->assetManager; - FaceApp application; - g_Application = &application; - application.SetInitArg(g_InitArgString); + //FaceApp application; + //g_Application = &application; + if(g_Application == nullptr) { + g_Application = new FaceApp(); + } + g_Application->SetInitArg(g_InitArgString); pApp->onAppCmd = handle_cmd; long long last_update_time = 0; android_app_set_motion_event_filter(pApp, nullptr); @@ -70,23 +134,67 @@ void android_main(struct android_app *pApp) { } } } - if(application.isInited()) + // isInited() checks _applicationInited && _faceAppInited && _sceondInited, + // so while the window is gone (between TERM_WINDOW and the next + // INIT_WINDOW) this is false and we skip drawFrame entirely — no + // exceptions, no log spam. The outer sleep at the bottom already + // caps the loop frequency. + if(g_Application->isInited()) { auto frameTime = (start_time - _lastDrawFrameTime); _lastDrawFrameTime = chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count(); - application.drawFrame(frameTime); + + static uint64_t s_frameIdx = 0; + static uint64_t s_excCount = 0; + ++s_frameIdx; + if (s_frameIdx % 600 == 0) { + DebugLog::log("heartbeat: frame=%llu exceptions_so_far=%llu", + (unsigned long long)s_frameIdx, + (unsigned long long)s_excCount); + } + // 每 60 帧刷新一次崩溃 note,崩溃时 dump 里能看到「最后一次活着」 + // 的帧号和异常数,定位是不是在某一个固定帧附近卡死。 + if (s_frameIdx % 60 == 0) { + char note[128]; + std::snprintf(note, sizeof(note), + "drawFrame frame=%llu exc=%llu", + (unsigned long long)s_frameIdx, + (unsigned long long)s_excCount); + CrashHandler::setNote(note); + } + + try { + g_Application->drawFrame(frameTime); + } catch (const std::exception& e) { + ++s_excCount; + DebugLog::log_throttled("main.drawFrame.stdexc", + "!!! drawFrame std::exception (frame=%llu count=%llu): %s", + (unsigned long long)s_frameIdx, + (unsigned long long)s_excCount, + e.what()); + } catch (...) { + ++s_excCount; + DebugLog::log_throttled("main.drawFrame.unknown", + "!!! drawFrame unknown exception (frame=%llu count=%llu)", + (unsigned long long)s_frameIdx, + (unsigned long long)s_excCount); + } } auto end_time = chrono::duration_cast(chrono::system_clock::now().time_since_epoch()).count(); auto frameTime = end_time - last_update_time; last_update_time = end_time; auto function_time = (end_time - start_time); - aout << "function_time:" << function_time << " fps:" << (1000/frameTime) << std::endl; + //aout << "function_time:" << function_time << " fps:" << (1000/frameTime) << std::endl; if(function_time < 35) { this_thread::sleep_for(chrono::milliseconds((35-function_time))); } } while (!pApp->destroyRequested); - application.cleanup(); + DebugLog::log("android_main: destroyRequested, running cleanup"); + //application.cleanup(); + g_Application->cleanupSecondInit(); + g_Application->clearnSecondFaceApp(); + DebugLog::log("android_main: exit"); } } @@ -106,6 +214,12 @@ Java_com_hmwl_face_1sdk_FaceActivity_processImageNative(JNIEnv *env, jobject thi jint width, jint height, jint format, jint row_stride, jint pixel_stride, jint rotation) { + static std::atomic s_imgCount{0}; + uint64_t n = s_imgCount.fetch_add(1) + 1; + if (n == 1 || n % 300 == 0) { + DebugLog::log("processImageNative #%llu tid=%d w=%d h=%d", + (unsigned long long)n, dbg_tid(), width, height); + } // TODO: implement processImageNative() uint8_t* imageData = static_cast(env->GetDirectBufferAddress(buffer)); jlong capacity = env->GetDirectBufferCapacity(buffer); @@ -122,6 +236,12 @@ extern "C" JNIEXPORT void JNICALL Java_com_hmwl_face_1sdk_FaceActivity_passDataToNative(JNIEnv *env, jobject thiz, jobject buffer, jint point_count, jint width, jint height) { + static std::atomic s_ptCount{0}; + uint64_t n = s_ptCount.fetch_add(1) + 1; + if (n == 1 || n % 300 == 0) { + DebugLog::log("passDataToNative #%llu tid=%d point_count=%d w=%d h=%d", + (unsigned long long)n, dbg_tid(), point_count, width, height); + } // TODO: implement passDataToNative() float* pos = static_cast(env->GetDirectBufferAddress(buffer)); @@ -137,9 +257,9 @@ Java_com_hmwl_face_1sdk_FaceActivity_passDataToNative(JNIEnv *env, jobject thiz, extern "C" JNIEXPORT void JNICALL Java_com_hmwl_face_1sdk_FaceActivity_SetCppInitArg(JNIEnv *env, jobject thiz, jstring json) { - // TODO: implement SetCppInitArg() const char *nativeString = env->GetStringUTFChars(json, nullptr); jsize len = env->GetStringUTFLength(json); + DebugLog::log("JNI SetCppInitArg tid=%d len=%d", dbg_tid(), (int)len); if(len > ArgLen) { aout << "ArgLen to long:" << len << std::endl; @@ -147,19 +267,228 @@ Java_com_hmwl_face_1sdk_FaceActivity_SetCppInitArg(JNIEnv *env, jobject thiz, js } memcpy(g_InitArgString, nativeString, len); } + extern "C" JNIEXPORT void JNICALL -Java_com_hmwl_face_1sdk_FaceActivity_ChangeStateCpp(JNIEnv *env, jobject thiz, jstring json) { - // TODO: implement ChangeStateCpp() +Java_com_hmwl_face_1sdk_FaceActivity_StopRunning(JNIEnv *env, jobject thiz) { + DebugLog::log("JNI StopRunning tid=%d", dbg_tid()); + g_Application->Stop(); +} + +JavaVM* g_jvm = nullptr; + +// 添加 JNI_OnLoad 函数 +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) { + g_jvm = vm; // 保存 JavaVM 指针,供其他线程使用 + return JNI_VERSION_1_6; +} + +void CppCallback() +{ + JNIEnv* env = nullptr; + bool needDetach = false; + + // 获取当前线程的 JNIEnv + JavaVM* vm = g_jvm; // 你需要提前保存 JavaVM* 到全局变量 g_jvm + int status = vm->GetEnv((void**)&env, JNI_VERSION_1_6); + if (status == JNI_EDETACHED) { + // 当前线程未 attach,需 attach + if (vm->AttachCurrentThread(&env, nullptr) != 0) { + return; + } + needDetach = true; + } else if (status != JNI_OK) { + return; + } + + if (g_callback == nullptr) { + if (needDetach) vm->DetachCurrentThread(); + return; + } + + // 1. 获取 CallbackInterface 的 class + jclass callbackClass = env->GetObjectClass(g_callback); + if (callbackClass == nullptr) { + if (needDetach) vm->DetachCurrentThread(); + return; + } + + // 2. 获取 OnLoadActionFinished 方法 ID(注意方法名大小写必须一致!) + jmethodID methodId = env->GetMethodID(callbackClass, "OnLoadMotionListFinished", "(Ljava/lang/String;)V"); + if (methodId == nullptr) { + env->ExceptionDescribe(); // 打印异常 + env->ExceptionClear(); + if (needDetach) vm->DetachCurrentThread(); + return; + } + + // 3. 构造 jstring 参数 + jstring jResult = env->NewStringUTF("ok"); + + // 4. 调用 Java 回调 + env->CallVoidMethod(g_callback, methodId, jResult); + + // 5. 检查是否抛出异常 + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + env->ExceptionClear(); + } + + // 6. 释放局部引用(可选,但推荐) + env->DeleteLocalRef(jResult); + env->DeleteLocalRef(callbackClass); + + // 7. 如果是临时 attach 的线程,要 detach + if (needDetach) { + vm->DetachCurrentThread(); + } +} + + +void CppAnimationFinishedCallback() +{ + JNIEnv* env = nullptr; + bool needDetach = false; + + // 获取当前线程的 JNIEnv + JavaVM* vm = g_jvm; // 你需要提前保存 JavaVM* 到全局变量 g_jvm + int status = vm->GetEnv((void**)&env, JNI_VERSION_1_6); + if (status == JNI_EDETACHED) { + // 当前线程未 attach,需 attach + if (vm->AttachCurrentThread(&env, nullptr) != 0) { + return; + } + needDetach = true; + } else if (status != JNI_OK) { + return; + } + + if (g_callbackAnimationFinished == nullptr) { + if (needDetach) vm->DetachCurrentThread(); + return; + } + + // 1. 获取 CallbackInterface 的 class + jclass callbackClass = env->GetObjectClass(g_callbackAnimationFinished); + if (callbackClass == nullptr) { + if (needDetach) vm->DetachCurrentThread(); + return; + } + + // 2. 获取 OnLoadActionFinished 方法 ID(注意方法名大小写必须一致!) + jmethodID methodId = env->GetMethodID(callbackClass, "OnPlayMotionListFinished", "()V"); + if (methodId == nullptr) { + env->ExceptionDescribe(); // 打印异常 + env->ExceptionClear(); + if (needDetach) vm->DetachCurrentThread(); + return; + } + + // 4. 调用 Java 回调 + env->CallVoidMethod(g_callbackAnimationFinished, methodId); + + // 5. 检查是否抛出异常 + if (env->ExceptionCheck()) { + env->ExceptionDescribe(); + env->ExceptionClear(); + } + + env->DeleteLocalRef(callbackClass); + + // 7. 如果是临时 attach 的线程,要 detach + if (needDetach) { + vm->DetachCurrentThread(); + } +} + + + +extern "C" +JNIEXPORT jstring JNICALL +Java_com_hmwl_face_1sdk_FaceActivity_PreReadAction(JNIEnv *env, jobject thiz, jstring motion, + jobject callback) { + DebugLog::log("JNI PreReadAction tid=%d", dbg_tid()); + // 清理旧的全局引用 + if (g_callback != nullptr) { + env->DeleteGlobalRef(g_callback); + g_callback = nullptr; + } + + // 保存新的回调 + if (callback != nullptr) { + g_callback = env->NewGlobalRef(callback); + } else { + g_callback = nullptr; + } + + const char *nativeString = env->GetStringUTFChars(motion, nullptr); + jsize len = env->GetStringUTFLength(motion); + if(len > ArgLen) + { + aout << "ArgLen to long:" << len << std::endl; + } + + std::string ret = g_Application->preLoadMotionList(nativeString, CppCallback); + return env->NewStringUTF(ret.c_str()); +} + +const char DELIMITER = 0x1F; // same as \u001F + +std::vector splitMotionString(const std::string& input) { + std::vector result; + if (input.empty()) return result; + + size_t start = 0; + size_t pos = input.find(DELIMITER); + + while (pos != std::string::npos) { + result.push_back(input.substr(start, pos - start)); + start = pos + 1; + pos = input.find(DELIMITER, start); + } + // Add last part + result.push_back(input.substr(start)); + + return result; +} + +extern "C" +JNIEXPORT void JNICALL +Java_com_hmwl_face_1sdk_FaceActivity_ChangeMotionCpp(JNIEnv *env, jobject thiz, jstring json, + jobject callback, jboolean loop) { const char *nativeString = env->GetStringUTFChars(json, nullptr); jsize len = env->GetStringUTFLength(json); + DebugLog::log_throttled("JNI.ChangeMotionCpp", + "JNI ChangeMotionCpp tid=%d len=%d loop=%d", + dbg_tid(), (int)len, (int)loop); if(len > ArgLen) { aout << "ArgLen to long:" << len << std::endl; return; } + + // 保存新的回调 + if (callback != nullptr) { + g_callbackAnimationFinished = env->NewGlobalRef(callback); + } else { + g_callbackAnimationFinished = nullptr; + } + if(g_Application->isInited()) { - g_Application->changeMotion(nativeString); + std::vector motions = splitMotionString(nativeString); + g_Application->changeMotionList(motions, CppAnimationFinishedCallback, loop); } +} +extern "C" +JNIEXPORT void JNICALL +Java_com_hmwl_face_1sdk_FaceActivity_StopMotionNative(JNIEnv *env, jobject thiz) { + DebugLog::log("JNI StopMotionNative tid=%d", dbg_tid()); + g_Application->StopMotion(); +} +extern "C" +JNIEXPORT void JNICALL +Java_com_hmwl_face_1sdk_FaceActivity_ResumeMotionNative(JNIEnv *env, jobject thiz) { + DebugLog::log("JNI ResumeMotionNative tid=%d", dbg_tid()); + g_Application->ResumeMotion(); } \ No newline at end of file diff --git a/app/src/main/java/com/hmwl/face_sdk/FaceActivity.java b/app/src/main/java/com/hmwl/face_sdk/FaceActivity.java index 80b4af4..effe851 100644 --- a/app/src/main/java/com/hmwl/face_sdk/FaceActivity.java +++ b/app/src/main/java/com/hmwl/face_sdk/FaceActivity.java @@ -4,7 +4,6 @@ import android.Manifest; import android.content.pm.PackageManager; import android.os.Bundle; import android.util.Log; -import android.view.MotionEvent; import android.view.View; import androidx.annotation.NonNull; @@ -31,7 +30,6 @@ import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; public class FaceActivity extends GameActivity implements FaceLandmarkerHelper.LandmarkerListener { private static final String TAG = "FaceActivity"; @@ -50,6 +48,21 @@ public class FaceActivity extends GameActivity implements FaceLandmarkerHelper.L } } + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + + if (requestCode == REQUEST_CAMERA_PERMISSION) { + // 检查权限是否被授予 + if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { + // 用户授予了权限,启动相机 + startCamera(); + } else { + requestCameraPermission(); + } + } + } + private void startCamera() { ListenableFuture cameraProviderFuture = ProcessCameraProvider.getInstance(this); @@ -81,12 +94,12 @@ public class FaceActivity extends GameActivity implements FaceLandmarkerHelper.L { detectFace(image); } - else - { - image.close(); - } +// else +// { +// image.close(); +// } } finally { - //image.close(); // 确保在这里关闭 + image.close(); // 确保在这里关闭 //Log.d("Camera", "Image closed, ready for next frame"); } } @@ -122,6 +135,22 @@ public class FaceActivity extends GameActivity implements FaceLandmarkerHelper.L } } + public void Stop(){ + StopRunning(); + } + + private native void StopMotionNative(); + public void StopMotion(){ + StopMotionNative(); + } + + private native void ResumeMotionNative(); + public void ResumeMotion(){ + ResumeMotionNative(); + } + + private native void StopRunning(); + // Native 方法 private native void processImageNative(ByteBuffer buffer, int width, int height, int format, int rowStride, int pixelStride, @@ -261,21 +290,45 @@ public class FaceActivity extends GameActivity implements FaceLandmarkerHelper.L protected native void SetCppInitArg(String json); - protected void SetInitArg(String json) + public void SetInitArg(String json) { SetCppInitArg(json); } - protected native void ChangeStateCpp(String json); - protected void ChangeState(String json){ - Log.i("FaceActivity", "ChangeState:" + json); - ChangeStateCpp(json); + public interface LoadMotionListFinishedCallback { + void OnLoadMotionListFinished(String result); + } + + public interface PlayMotionListFinishedCallback { + void OnPlayMotionListFinished(); + } + + protected native String PreReadAction(String motion, LoadMotionListFinishedCallback callback); + public String PreLoadAction(String json, LoadMotionListFinishedCallback callback){ + return PreReadAction(json, callback); + } + + protected native void ChangeMotionCpp(String json, PlayMotionListFinishedCallback callback, boolean loop); + public void PlayMotionList(List motionList, boolean loop, PlayMotionListFinishedCallback callback) + { + if(callback == null) + { + callback = new PlayMotionListFinishedCallback() { + @Override + public void OnPlayMotionListFinished() { + Log.i(TAG, "OnPlayMotionListFinished: "); + } + }; + } + final String DELIMITER = "\u001F"; // ASCII Unit Separator + String motion_list_str = String.join(DELIMITER, motionList); + ChangeMotionCpp(motion_list_str, callback, loop); } // 添加这个缺失的方法 @Override public void onEmpty() { // 当没有检测到人脸时的处理逻辑 - Log.d(TAG, "No face detected in the current frame"); + //Log.d(TAG, "No face detected in the current frame"); } } \ No newline at end of file diff --git a/app/src/main/java/com/hmwl/face_sdk/FaceLandmarkerHelper.kt b/app/src/main/java/com/hmwl/face_sdk/FaceLandmarkerHelper.kt index c708ba5..c9f0cba 100644 --- a/app/src/main/java/com/hmwl/face_sdk/FaceLandmarkerHelper.kt +++ b/app/src/main/java/com/hmwl/face_sdk/FaceLandmarkerHelper.kt @@ -67,6 +67,9 @@ class FaceLandmarkerHelper( } } + minFaceDetectionConfidence = 0.1f; + minFaceTrackingConfidence = 0.1f; + minFacePresenceConfidence = 0.1f; try { val baseOptions = baseOptionBuilder.build() // Create an option builder with base options and specific @@ -189,7 +192,7 @@ class FaceLandmarkerHelper( Bitmap.Config.ARGB_8888 ) imageProxy.use { bitmapBuffer.copyPixelsFromBuffer(imageProxy.planes[0].buffer) } - imageProxy.close() + //imageProxy.close() val matrix = Matrix().apply { // Rotate the frame received from the camera to be in the same direction as it'll be shown @@ -238,32 +241,33 @@ class FaceLandmarkerHelper( val frameId = result.timestampMs() if( result.faceLandmarks().size > 0 ) { // 计算各种延时 - val timings = frameTimings[frameId] - if (timings != null) { - val totalLatency = resultTime - timings.captureTime - val preprocessLatency = timings.preprocessEndTime - timings.preprocessStartTime - val detectionLatency = resultTime - timings.detectionStartTime - val captureToDetectionLatency = timings.detectionStartTime - timings.captureTime - - Log.i("TimeLatency", - "总延时: ${totalLatency}ms | " + - "预处理: ${preprocessLatency}ms | " + - "检测: ${detectionLatency}ms | " + - "捕获到检测: ${captureToDetectionLatency}ms | " + - "FPS: ${String.format("%.1f", currentFps)}" - ) - - val finishTimeMs = SystemClock.uptimeMillis() - val inferenceTime = finishTimeMs - result.timestampMs() - faceLandmarkerHelperListener?.onResults( - ResultBundle( - result, - inferenceTime, // 主要是检测时间 - input.height, - input.width, - ) - ) - } else { +// val timings = frameTimings[frameId] +// if (timings != null) { +// val totalLatency = resultTime - timings.captureTime +// val preprocessLatency = timings.preprocessEndTime - timings.preprocessStartTime +// val detectionLatency = resultTime - timings.detectionStartTime +// val captureToDetectionLatency = timings.detectionStartTime - timings.captureTime +// +// Log.i("TimeLatency", +// "总延时: ${totalLatency}ms | " + +// "预处理: ${preprocessLatency}ms | " + +// "检测: ${detectionLatency}ms | " + +// "捕获到检测: ${captureToDetectionLatency}ms | " + +// "FPS: ${String.format("%.1f", currentFps)}" +// ) +// +// val finishTimeMs = SystemClock.uptimeMillis() +// val inferenceTime = finishTimeMs - result.timestampMs() +// faceLandmarkerHelperListener?.onResults( +// ResultBundle( +// result, +// inferenceTime, // 主要是检测时间 +// input.height, +// input.width, +// ) +// ) +// } else + //{ val finishTimeMs = SystemClock.uptimeMillis() val inferenceTime = finishTimeMs - result.timestampMs() Log.i("TimeLatency", @@ -277,7 +281,7 @@ class FaceLandmarkerHelper( input.width ) ) - } + //} } else { faceLandmarkerHelperListener?.onEmpty() diff --git a/app/src/main/java/com/hmwl/face_sdk/Frame.java b/app/src/main/java/com/hmwl/face_sdk/Frame.java new file mode 100644 index 0000000..831b6bd --- /dev/null +++ b/app/src/main/java/com/hmwl/face_sdk/Frame.java @@ -0,0 +1,27 @@ +package com.hmwl.face_sdk; + +import org.json.JSONObject; + +public class Frame { + public String name; + public float x; + public float y; + public Frame(String name, float x, float y) + { + this.name = name; + this.x = x; + this.y = y; + } + public JSONObject toJsonObject(){ + try { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("name", name); + jsonObject.put("x", x); + jsonObject.put("y", y); + return jsonObject; + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } +} diff --git a/app/src/main/java/com/hmwl/face_sdk/InitArg.java b/app/src/main/java/com/hmwl/face_sdk/InitArg.java index 3c311f5..634c0b1 100644 --- a/app/src/main/java/com/hmwl/face_sdk/InitArg.java +++ b/app/src/main/java/com/hmwl/face_sdk/InitArg.java @@ -4,13 +4,23 @@ import org.json.JSONObject; public class InitArg { public int action_fps; public float zoom; - public Motion motion; + public float r; + public float g; + public float b; + public float radius; + public float offset_x; + public float offset_y; public String toJson() { try { JSONObject jsonObject = new JSONObject(); jsonObject.put("action_fps", action_fps); jsonObject.put("zoom", zoom); - jsonObject.put("motion", motion.toJsonObject()); + jsonObject.put("r", r); + jsonObject.put("g", g); + jsonObject.put("b", b); + jsonObject.put("radius", radius); + jsonObject.put("offset_x", offset_x); + jsonObject.put("offset_y", offset_y); return jsonObject.toString(); } catch (Exception e) { e.printStackTrace(); diff --git a/app/src/main/java/com/hmwl/face_sdk/Motion.java b/app/src/main/java/com/hmwl/face_sdk/Motion.java index ee0a7e8..6552c17 100644 --- a/app/src/main/java/com/hmwl/face_sdk/Motion.java +++ b/app/src/main/java/com/hmwl/face_sdk/Motion.java @@ -5,32 +5,29 @@ import org.json.JSONObject; import java.util.ArrayList; import java.util.List; + public class Motion { - public String type = "no"; - public List png_names = new ArrayList<>(); + public String name = "no"; + public List frames = new ArrayList<>(); + public Motion(String name, List frames) + { + this.name = name; + this.frames = frames; + } public JSONObject toJsonObject() { try { JSONObject jsonObject = new JSONObject(); - jsonObject.put("type", type); - JSONArray ja = new JSONArray(); - for(int i = 0; i < png_names.size(); ++i){ - ja.put(png_names.get(i)); + jsonObject.put("name", name); + JSONArray jframes = new JSONArray(); + for(int i = 0; i < frames.size(); ++i){ + jframes.put(frames.get(i).toJsonObject()); } - jsonObject.put("png_names", ja); + jsonObject.put("frames", jframes); return jsonObject; } catch (Exception e) { e.printStackTrace(); return null; } } - - public String toJson() { - try { - return toJsonObject().toString(); - } catch (Exception e) { - e.printStackTrace(); - return null; - } - } }; diff --git a/app/src/main/java/com/hmwl/face_sdk/MotionList.java b/app/src/main/java/com/hmwl/face_sdk/MotionList.java new file mode 100644 index 0000000..b3d248d --- /dev/null +++ b/app/src/main/java/com/hmwl/face_sdk/MotionList.java @@ -0,0 +1,28 @@ +package com.hmwl.face_sdk; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.util.ArrayList; +import java.util.List; + +public class MotionList { + public List motions = new ArrayList<>(); + public JSONObject toJsonObject() { + try { + JSONObject jsonObject = new JSONObject(); + JSONArray jMotions = new JSONArray(); + for(int i = 0; i < motions.size(); ++i){ + jMotions.put(motions.get(i).toJsonObject()); + } + jsonObject.put("motions", jMotions); + return jsonObject; + } catch (Exception e) { + e.printStackTrace(); + return new JSONObject(); + } + } + public String toJsonString(){ + return toJsonObject().toString(); + } +} diff --git a/build.gradle b/build.gradle index 60094ff..3f2f157 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,19 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. +buildscript { + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:8.3.2' + } +} + plugins { alias(libs.plugins.android.application) apply false - alias(libs.plugins.android.library) apply false // 添加这行 - id 'org.jetbrains.kotlin.android' version '1.9.0' apply false + alias(libs.plugins.android.library) apply false + alias(libs.plugins.kotlin.android) apply false // 添加这行 + //alias(libs.plugins.kotlin.android) apply false + //id 'org.jetbrains.kotlin.android' version '2.2.0' apply false } \ No newline at end of file diff --git a/compile_shader.bat b/compile_shader.bat index 4093d63..2d46b71 100644 --- a/compile_shader.bat +++ b/compile_shader.bat @@ -4,8 +4,9 @@ glslangValidator -V app/src/main/assets/shaders/bg.vert -o app/src/main/assets/s glslangValidator -V app/src/main/assets/shaders/texture.frag -o app/src/main/assets/shaders/texture.frag.spv glslangValidator -V app/src/main/assets/shaders/texture.vert -o app/src/main/assets/shaders/texture.vert.spv -glslangValidator -V app/src/main/assets/shaders/texture_thick.frag -o app/src/main/assets/shaders/texture_thick.frag.spv -glslangValidator -V app/src/main/assets/shaders/texture_thick.vert -o app/src/main/assets/shaders/texture_thick.vert.spv - glslangValidator -V app/src/main/assets/shaders/simple_shader.frag -o app/src/main/assets/shaders/simple_shader.frag.spv -glslangValidator -V app/src/main/assets/shaders/simple_shader.vert -o app/src/main/assets/shaders/simple_shader.vert.spv \ No newline at end of file +glslangValidator -V app/src/main/assets/shaders/simple_shader.vert -o app/src/main/assets/shaders/simple_shader.vert.spv + +glslangValidator -V app/src/main/assets/shaders/texture_thick.frag -o app/src/main/assets/shaders/texture_thick.frag.spv +rem glslangValidator -V app/src/main/assets/shaders/texture_thick.vert -o app/src/main/assets/shaders/texture_thick.vert.spv + diff --git a/example/build.gradle b/example/build.gradle index 28dbfaa..c81bf46 100644 --- a/example/build.gradle +++ b/example/build.gradle @@ -1,13 +1,15 @@ plugins { alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + //alias(libs.plugins.kotlin.android) } android { - namespace 'com.hmwl.example' + namespace 'com.inewme.uvmirror' compileSdk 36 defaultConfig { - applicationId "com.hmwl.f20251110" + applicationId "com.inewme.uvmirror.f20260113" minSdk 30 targetSdk 36 versionCode 1 @@ -18,6 +20,7 @@ android { buildTypes { release { + signingConfig signingConfigs.debug minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } @@ -26,6 +29,20 @@ android { sourceCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17 } + + buildFeatures { + compose true + } + + composeOptions { + kotlinCompilerExtensionVersion '1.5.1' + } + kotlinOptions { + jvmTarget = '17' + } +// kotlinOptions { +// jvmTarget = '17' +// } } dependencies { @@ -33,11 +50,21 @@ dependencies { implementation libs.appcompat implementation libs.material implementation libs.games.activity + implementation libs.core.ktx + implementation libs.androidx.core.ktx testImplementation libs.junit androidTestImplementation libs.ext.junit androidTestImplementation libs.espresso.core implementation project(':app') + // Jetpack Compose + implementation "androidx.compose.ui:ui:1.5.0" + implementation "androidx.compose.material3:material3:1.0.0" + implementation "androidx.compose.foundation:foundation:1.5.0" + implementation "androidx.compose.runtime:runtime:1.5.0" + implementation "androidx.activity:activity-compose:1.7.2" // �ؼ����ṩ setContent + + implementation "androidx.compose.ui:ui-tooling:1.5.4" def camerax_version = '1.4.2' implementation "androidx.camera:camera-core:$camerax_version" @@ -53,4 +80,7 @@ dependencies { implementation 'com.google.flogger:flogger-system-backend:0.7.4' implementation 'com.google.guava:guava:31.1-android' + + implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7") // 提供 lifecycleScope + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0") } \ No newline at end of file diff --git a/example/src/main/AndroidManifest.xml b/example/src/main/AndroidManifest.xml index 2f6f785..70485aa 100644 --- a/example/src/main/AndroidManifest.xml +++ b/example/src/main/AndroidManifest.xml @@ -20,6 +20,10 @@ android:name="android.app.lib_name" android:value="face_sdk" /> + + \ No newline at end of file diff --git a/example/src/main/assets/pic/11.png b/example/src/main/assets/pic/11.png deleted file mode 100644 index ddc955b..0000000 Binary files a/example/src/main/assets/pic/11.png and /dev/null differ diff --git a/example/src/main/assets/pic/11/000000.png b/example/src/main/assets/pic/11/000000.png new file mode 100644 index 0000000..620be32 Binary files /dev/null and b/example/src/main/assets/pic/11/000000.png differ diff --git a/example/src/main/assets/pic/11/000001.png b/example/src/main/assets/pic/11/000001.png new file mode 100644 index 0000000..d23247a Binary files /dev/null and b/example/src/main/assets/pic/11/000001.png differ diff --git a/example/src/main/assets/pic/11/000002.png b/example/src/main/assets/pic/11/000002.png new file mode 100644 index 0000000..26a15f0 Binary files /dev/null and b/example/src/main/assets/pic/11/000002.png differ diff --git a/example/src/main/assets/pic/11/000003.png b/example/src/main/assets/pic/11/000003.png new file mode 100644 index 0000000..7c34325 Binary files /dev/null and b/example/src/main/assets/pic/11/000003.png differ diff --git a/example/src/main/assets/pic/11/000004.png b/example/src/main/assets/pic/11/000004.png new file mode 100644 index 0000000..901d5d6 Binary files /dev/null and b/example/src/main/assets/pic/11/000004.png differ diff --git a/example/src/main/assets/pic/11/000005.png b/example/src/main/assets/pic/11/000005.png new file mode 100644 index 0000000..24e5a2c Binary files /dev/null and b/example/src/main/assets/pic/11/000005.png differ diff --git a/example/src/main/assets/pic/11/000006.png b/example/src/main/assets/pic/11/000006.png new file mode 100644 index 0000000..3039055 Binary files /dev/null and b/example/src/main/assets/pic/11/000006.png differ diff --git a/example/src/main/assets/pic/11/000007.png b/example/src/main/assets/pic/11/000007.png new file mode 100644 index 0000000..ab30124 Binary files /dev/null and b/example/src/main/assets/pic/11/000007.png differ diff --git a/example/src/main/assets/pic/11/000008.png b/example/src/main/assets/pic/11/000008.png new file mode 100644 index 0000000..698ab21 Binary files /dev/null and b/example/src/main/assets/pic/11/000008.png differ diff --git a/example/src/main/assets/pic/11/000009.png b/example/src/main/assets/pic/11/000009.png new file mode 100644 index 0000000..4fe0263 Binary files /dev/null and b/example/src/main/assets/pic/11/000009.png differ diff --git a/example/src/main/assets/pic/11/000010.png b/example/src/main/assets/pic/11/000010.png new file mode 100644 index 0000000..f1d6cdb Binary files /dev/null and b/example/src/main/assets/pic/11/000010.png differ diff --git a/example/src/main/assets/pic/11/000011.png b/example/src/main/assets/pic/11/000011.png new file mode 100644 index 0000000..b110934 Binary files /dev/null and b/example/src/main/assets/pic/11/000011.png differ diff --git a/example/src/main/assets/pic/11/000012.png b/example/src/main/assets/pic/11/000012.png new file mode 100644 index 0000000..ec76189 Binary files /dev/null and b/example/src/main/assets/pic/11/000012.png differ diff --git a/example/src/main/assets/pic/11/000013.png b/example/src/main/assets/pic/11/000013.png new file mode 100644 index 0000000..0405cab Binary files /dev/null and b/example/src/main/assets/pic/11/000013.png differ diff --git a/example/src/main/assets/pic/11/000014.png b/example/src/main/assets/pic/11/000014.png new file mode 100644 index 0000000..f89b0f1 Binary files /dev/null and b/example/src/main/assets/pic/11/000014.png differ diff --git a/example/src/main/assets/pic/11/000015.png b/example/src/main/assets/pic/11/000015.png new file mode 100644 index 0000000..158955f Binary files /dev/null and b/example/src/main/assets/pic/11/000015.png differ diff --git a/example/src/main/assets/pic/11/000016.png b/example/src/main/assets/pic/11/000016.png new file mode 100644 index 0000000..50a9c1e Binary files /dev/null and b/example/src/main/assets/pic/11/000016.png differ diff --git a/example/src/main/assets/pic/11/000017.png b/example/src/main/assets/pic/11/000017.png new file mode 100644 index 0000000..7afac46 Binary files /dev/null and b/example/src/main/assets/pic/11/000017.png differ diff --git a/example/src/main/assets/pic/11/000018.png b/example/src/main/assets/pic/11/000018.png new file mode 100644 index 0000000..ee59a38 Binary files /dev/null and b/example/src/main/assets/pic/11/000018.png differ diff --git a/example/src/main/assets/pic/11/000019.png b/example/src/main/assets/pic/11/000019.png new file mode 100644 index 0000000..ab27922 Binary files /dev/null and b/example/src/main/assets/pic/11/000019.png differ diff --git a/example/src/main/assets/pic/11/000020.png b/example/src/main/assets/pic/11/000020.png new file mode 100644 index 0000000..06596fd Binary files /dev/null and b/example/src/main/assets/pic/11/000020.png differ diff --git a/example/src/main/assets/pic/11/000021.png b/example/src/main/assets/pic/11/000021.png new file mode 100644 index 0000000..74a3a1e Binary files /dev/null and b/example/src/main/assets/pic/11/000021.png differ diff --git a/example/src/main/assets/pic/11/000022.png b/example/src/main/assets/pic/11/000022.png new file mode 100644 index 0000000..7b0f14e Binary files /dev/null and b/example/src/main/assets/pic/11/000022.png differ diff --git a/example/src/main/assets/pic/11/000023.png b/example/src/main/assets/pic/11/000023.png new file mode 100644 index 0000000..f64ce8a Binary files /dev/null and b/example/src/main/assets/pic/11/000023.png differ diff --git a/example/src/main/assets/pic/11/11.png b/example/src/main/assets/pic/11/11.png deleted file mode 100644 index ddc955b..0000000 Binary files a/example/src/main/assets/pic/11/11.png and /dev/null differ diff --git a/example/src/main/assets/pic/11ex.png b/example/src/main/assets/pic/11ex.png new file mode 100644 index 0000000..b39ce4a Binary files /dev/null and b/example/src/main/assets/pic/11ex.png differ diff --git a/example/src/main/assets/pic/12.png b/example/src/main/assets/pic/12.png deleted file mode 100644 index a526eb1..0000000 Binary files a/example/src/main/assets/pic/12.png and /dev/null differ diff --git a/example/src/main/assets/pic/12/000000.png b/example/src/main/assets/pic/12/000000.png new file mode 100644 index 0000000..cb4e030 Binary files /dev/null and b/example/src/main/assets/pic/12/000000.png differ diff --git a/example/src/main/assets/pic/12/000001.png b/example/src/main/assets/pic/12/000001.png new file mode 100644 index 0000000..21f9f84 Binary files /dev/null and b/example/src/main/assets/pic/12/000001.png differ diff --git a/example/src/main/assets/pic/12/000002.png b/example/src/main/assets/pic/12/000002.png new file mode 100644 index 0000000..8636122 Binary files /dev/null and b/example/src/main/assets/pic/12/000002.png differ diff --git a/example/src/main/assets/pic/12/000003.png b/example/src/main/assets/pic/12/000003.png new file mode 100644 index 0000000..20e982b Binary files /dev/null and b/example/src/main/assets/pic/12/000003.png differ diff --git a/example/src/main/assets/pic/12/000004.png b/example/src/main/assets/pic/12/000004.png new file mode 100644 index 0000000..3ab2469 Binary files /dev/null and b/example/src/main/assets/pic/12/000004.png differ diff --git a/example/src/main/assets/pic/12/000005.png b/example/src/main/assets/pic/12/000005.png new file mode 100644 index 0000000..94cdc60 Binary files /dev/null and b/example/src/main/assets/pic/12/000005.png differ diff --git a/example/src/main/assets/pic/12/000006.png b/example/src/main/assets/pic/12/000006.png new file mode 100644 index 0000000..338e1da Binary files /dev/null and b/example/src/main/assets/pic/12/000006.png differ diff --git a/example/src/main/assets/pic/12/000007.png b/example/src/main/assets/pic/12/000007.png new file mode 100644 index 0000000..bdfc54b Binary files /dev/null and b/example/src/main/assets/pic/12/000007.png differ diff --git a/example/src/main/assets/pic/12/000008.png b/example/src/main/assets/pic/12/000008.png new file mode 100644 index 0000000..0394f12 Binary files /dev/null and b/example/src/main/assets/pic/12/000008.png differ diff --git a/example/src/main/assets/pic/12/000009.png b/example/src/main/assets/pic/12/000009.png new file mode 100644 index 0000000..976d25d Binary files /dev/null and b/example/src/main/assets/pic/12/000009.png differ diff --git a/example/src/main/assets/pic/12/000010.png b/example/src/main/assets/pic/12/000010.png new file mode 100644 index 0000000..12a325d Binary files /dev/null and b/example/src/main/assets/pic/12/000010.png differ diff --git a/example/src/main/assets/pic/12/000011.png b/example/src/main/assets/pic/12/000011.png new file mode 100644 index 0000000..fe16fb5 Binary files /dev/null and b/example/src/main/assets/pic/12/000011.png differ diff --git a/example/src/main/assets/pic/12/000012.png b/example/src/main/assets/pic/12/000012.png new file mode 100644 index 0000000..609e245 Binary files /dev/null and b/example/src/main/assets/pic/12/000012.png differ diff --git a/example/src/main/assets/pic/12/000013.png b/example/src/main/assets/pic/12/000013.png new file mode 100644 index 0000000..c040bba Binary files /dev/null and b/example/src/main/assets/pic/12/000013.png differ diff --git a/example/src/main/assets/pic/12/000014.png b/example/src/main/assets/pic/12/000014.png new file mode 100644 index 0000000..7462c60 Binary files /dev/null and b/example/src/main/assets/pic/12/000014.png differ diff --git a/example/src/main/assets/pic/12/000015.png b/example/src/main/assets/pic/12/000015.png new file mode 100644 index 0000000..4e770c0 Binary files /dev/null and b/example/src/main/assets/pic/12/000015.png differ diff --git a/example/src/main/assets/pic/12/000016.png b/example/src/main/assets/pic/12/000016.png new file mode 100644 index 0000000..675f741 Binary files /dev/null and b/example/src/main/assets/pic/12/000016.png differ diff --git a/example/src/main/assets/pic/12/000017.png b/example/src/main/assets/pic/12/000017.png new file mode 100644 index 0000000..b799b8c Binary files /dev/null and b/example/src/main/assets/pic/12/000017.png differ diff --git a/example/src/main/assets/pic/12/000018.png b/example/src/main/assets/pic/12/000018.png new file mode 100644 index 0000000..68ad2eb Binary files /dev/null and b/example/src/main/assets/pic/12/000018.png differ diff --git a/example/src/main/assets/pic/12/000019.png b/example/src/main/assets/pic/12/000019.png new file mode 100644 index 0000000..84c96e8 Binary files /dev/null and b/example/src/main/assets/pic/12/000019.png differ diff --git a/example/src/main/assets/pic/12/000020.png b/example/src/main/assets/pic/12/000020.png new file mode 100644 index 0000000..9b49ef8 Binary files /dev/null and b/example/src/main/assets/pic/12/000020.png differ diff --git a/example/src/main/assets/pic/12/000021.png b/example/src/main/assets/pic/12/000021.png new file mode 100644 index 0000000..60e404f Binary files /dev/null and b/example/src/main/assets/pic/12/000021.png differ diff --git a/example/src/main/assets/pic/12/000022.png b/example/src/main/assets/pic/12/000022.png new file mode 100644 index 0000000..07fe8a0 Binary files /dev/null and b/example/src/main/assets/pic/12/000022.png differ diff --git a/example/src/main/assets/pic/12/000023.png b/example/src/main/assets/pic/12/000023.png new file mode 100644 index 0000000..9857232 Binary files /dev/null and b/example/src/main/assets/pic/12/000023.png differ diff --git a/example/src/main/assets/pic/12/12.png b/example/src/main/assets/pic/12/12.png deleted file mode 100644 index a526eb1..0000000 Binary files a/example/src/main/assets/pic/12/12.png and /dev/null differ diff --git a/example/src/main/assets/pic/12ex.png b/example/src/main/assets/pic/12ex.png new file mode 100644 index 0000000..b86d959 Binary files /dev/null and b/example/src/main/assets/pic/12ex.png differ diff --git a/example/src/main/assets/pic/13.png b/example/src/main/assets/pic/13.png deleted file mode 100644 index 782c858..0000000 Binary files a/example/src/main/assets/pic/13.png and /dev/null differ diff --git a/example/src/main/assets/pic/13/000000.png b/example/src/main/assets/pic/13/000000.png new file mode 100644 index 0000000..3596e2c Binary files /dev/null and b/example/src/main/assets/pic/13/000000.png differ diff --git a/example/src/main/assets/pic/13/000001.png b/example/src/main/assets/pic/13/000001.png new file mode 100644 index 0000000..68b7f40 Binary files /dev/null and b/example/src/main/assets/pic/13/000001.png differ diff --git a/example/src/main/assets/pic/13/000002.png b/example/src/main/assets/pic/13/000002.png new file mode 100644 index 0000000..859b9a9 Binary files /dev/null and b/example/src/main/assets/pic/13/000002.png differ diff --git a/example/src/main/assets/pic/13/000003.png b/example/src/main/assets/pic/13/000003.png new file mode 100644 index 0000000..c892917 Binary files /dev/null and b/example/src/main/assets/pic/13/000003.png differ diff --git a/example/src/main/assets/pic/13/000004.png b/example/src/main/assets/pic/13/000004.png new file mode 100644 index 0000000..f3c16f9 Binary files /dev/null and b/example/src/main/assets/pic/13/000004.png differ diff --git a/example/src/main/assets/pic/13/000005.png b/example/src/main/assets/pic/13/000005.png new file mode 100644 index 0000000..31759ca Binary files /dev/null and b/example/src/main/assets/pic/13/000005.png differ diff --git a/example/src/main/assets/pic/13/000006.png b/example/src/main/assets/pic/13/000006.png new file mode 100644 index 0000000..3477050 Binary files /dev/null and b/example/src/main/assets/pic/13/000006.png differ diff --git a/example/src/main/assets/pic/13/000007.png b/example/src/main/assets/pic/13/000007.png new file mode 100644 index 0000000..9f31bcb Binary files /dev/null and b/example/src/main/assets/pic/13/000007.png differ diff --git a/example/src/main/assets/pic/13/000008.png b/example/src/main/assets/pic/13/000008.png new file mode 100644 index 0000000..b3ae60a Binary files /dev/null and b/example/src/main/assets/pic/13/000008.png differ diff --git a/example/src/main/assets/pic/13/000009.png b/example/src/main/assets/pic/13/000009.png new file mode 100644 index 0000000..14482c6 Binary files /dev/null and b/example/src/main/assets/pic/13/000009.png differ diff --git a/example/src/main/assets/pic/13/000010.png b/example/src/main/assets/pic/13/000010.png new file mode 100644 index 0000000..ebe5760 Binary files /dev/null and b/example/src/main/assets/pic/13/000010.png differ diff --git a/example/src/main/assets/pic/13/000011.png b/example/src/main/assets/pic/13/000011.png new file mode 100644 index 0000000..d1af26c Binary files /dev/null and b/example/src/main/assets/pic/13/000011.png differ diff --git a/example/src/main/assets/pic/13/000012.png b/example/src/main/assets/pic/13/000012.png new file mode 100644 index 0000000..e9ba52a Binary files /dev/null and b/example/src/main/assets/pic/13/000012.png differ diff --git a/example/src/main/assets/pic/13/000013.png b/example/src/main/assets/pic/13/000013.png new file mode 100644 index 0000000..3d5b16e Binary files /dev/null and b/example/src/main/assets/pic/13/000013.png differ diff --git a/example/src/main/assets/pic/13/000014.png b/example/src/main/assets/pic/13/000014.png new file mode 100644 index 0000000..886886f Binary files /dev/null and b/example/src/main/assets/pic/13/000014.png differ diff --git a/example/src/main/assets/pic/13/000015.png b/example/src/main/assets/pic/13/000015.png new file mode 100644 index 0000000..e394a41 Binary files /dev/null and b/example/src/main/assets/pic/13/000015.png differ diff --git a/example/src/main/assets/pic/13/000016.png b/example/src/main/assets/pic/13/000016.png new file mode 100644 index 0000000..032a82d Binary files /dev/null and b/example/src/main/assets/pic/13/000016.png differ diff --git a/example/src/main/assets/pic/13/000017.png b/example/src/main/assets/pic/13/000017.png new file mode 100644 index 0000000..c7f4b0f Binary files /dev/null and b/example/src/main/assets/pic/13/000017.png differ diff --git a/example/src/main/assets/pic/13/000018.png b/example/src/main/assets/pic/13/000018.png new file mode 100644 index 0000000..8a67c2c Binary files /dev/null and b/example/src/main/assets/pic/13/000018.png differ diff --git a/example/src/main/assets/pic/13/000019.png b/example/src/main/assets/pic/13/000019.png new file mode 100644 index 0000000..e87aac9 Binary files /dev/null and b/example/src/main/assets/pic/13/000019.png differ diff --git a/example/src/main/assets/pic/13/000020.png b/example/src/main/assets/pic/13/000020.png new file mode 100644 index 0000000..adb8886 Binary files /dev/null and b/example/src/main/assets/pic/13/000020.png differ diff --git a/example/src/main/assets/pic/13/000021.png b/example/src/main/assets/pic/13/000021.png new file mode 100644 index 0000000..7ae9e8f Binary files /dev/null and b/example/src/main/assets/pic/13/000021.png differ diff --git a/example/src/main/assets/pic/13/000022.png b/example/src/main/assets/pic/13/000022.png new file mode 100644 index 0000000..4c9706e Binary files /dev/null and b/example/src/main/assets/pic/13/000022.png differ diff --git a/example/src/main/assets/pic/13/000023.png b/example/src/main/assets/pic/13/000023.png new file mode 100644 index 0000000..6cf2493 Binary files /dev/null and b/example/src/main/assets/pic/13/000023.png differ diff --git a/example/src/main/assets/pic/13/000024.png b/example/src/main/assets/pic/13/000024.png new file mode 100644 index 0000000..3786403 Binary files /dev/null and b/example/src/main/assets/pic/13/000024.png differ diff --git a/example/src/main/assets/pic/13/000025.png b/example/src/main/assets/pic/13/000025.png new file mode 100644 index 0000000..265faa5 Binary files /dev/null and b/example/src/main/assets/pic/13/000025.png differ diff --git a/example/src/main/assets/pic/13/000026.png b/example/src/main/assets/pic/13/000026.png new file mode 100644 index 0000000..0b75dd7 Binary files /dev/null and b/example/src/main/assets/pic/13/000026.png differ diff --git a/example/src/main/assets/pic/13/000027.png b/example/src/main/assets/pic/13/000027.png new file mode 100644 index 0000000..068d952 Binary files /dev/null and b/example/src/main/assets/pic/13/000027.png differ diff --git a/example/src/main/assets/pic/13/000028.png b/example/src/main/assets/pic/13/000028.png new file mode 100644 index 0000000..14cd2c3 Binary files /dev/null and b/example/src/main/assets/pic/13/000028.png differ diff --git a/example/src/main/assets/pic/13/000029.png b/example/src/main/assets/pic/13/000029.png new file mode 100644 index 0000000..b0deda6 Binary files /dev/null and b/example/src/main/assets/pic/13/000029.png differ diff --git a/example/src/main/assets/pic/13/000030.png b/example/src/main/assets/pic/13/000030.png new file mode 100644 index 0000000..d43b9bb Binary files /dev/null and b/example/src/main/assets/pic/13/000030.png differ diff --git a/example/src/main/assets/pic/13/000031.png b/example/src/main/assets/pic/13/000031.png new file mode 100644 index 0000000..c3286a0 Binary files /dev/null and b/example/src/main/assets/pic/13/000031.png differ diff --git a/example/src/main/assets/pic/13/13.png b/example/src/main/assets/pic/13/13.png deleted file mode 100644 index 782c858..0000000 Binary files a/example/src/main/assets/pic/13/13.png and /dev/null differ diff --git a/example/src/main/assets/pic/13ex.png b/example/src/main/assets/pic/13ex.png new file mode 100644 index 0000000..1332aac Binary files /dev/null and b/example/src/main/assets/pic/13ex.png differ diff --git a/example/src/main/assets/pic/14.png b/example/src/main/assets/pic/14.png deleted file mode 100644 index bc9672f..0000000 Binary files a/example/src/main/assets/pic/14.png and /dev/null differ diff --git a/example/src/main/assets/pic/14/000000.png b/example/src/main/assets/pic/14/000000.png new file mode 100644 index 0000000..1f3629b Binary files /dev/null and b/example/src/main/assets/pic/14/000000.png differ diff --git a/example/src/main/assets/pic/14/000001.png b/example/src/main/assets/pic/14/000001.png new file mode 100644 index 0000000..cce0199 Binary files /dev/null and b/example/src/main/assets/pic/14/000001.png differ diff --git a/example/src/main/assets/pic/14/000002.png b/example/src/main/assets/pic/14/000002.png new file mode 100644 index 0000000..d90e21c Binary files /dev/null and b/example/src/main/assets/pic/14/000002.png differ diff --git a/example/src/main/assets/pic/14/000003.png b/example/src/main/assets/pic/14/000003.png new file mode 100644 index 0000000..f92c967 Binary files /dev/null and b/example/src/main/assets/pic/14/000003.png differ diff --git a/example/src/main/assets/pic/14/000004.png b/example/src/main/assets/pic/14/000004.png new file mode 100644 index 0000000..aa5282a Binary files /dev/null and b/example/src/main/assets/pic/14/000004.png differ diff --git a/example/src/main/assets/pic/14/000005.png b/example/src/main/assets/pic/14/000005.png new file mode 100644 index 0000000..352df1e Binary files /dev/null and b/example/src/main/assets/pic/14/000005.png differ diff --git a/example/src/main/assets/pic/14/000006.png b/example/src/main/assets/pic/14/000006.png new file mode 100644 index 0000000..85c4e55 Binary files /dev/null and b/example/src/main/assets/pic/14/000006.png differ diff --git a/example/src/main/assets/pic/14/000007.png b/example/src/main/assets/pic/14/000007.png new file mode 100644 index 0000000..4d6e8e8 Binary files /dev/null and b/example/src/main/assets/pic/14/000007.png differ diff --git a/example/src/main/assets/pic/14/000008.png b/example/src/main/assets/pic/14/000008.png new file mode 100644 index 0000000..589d4f2 Binary files /dev/null and b/example/src/main/assets/pic/14/000008.png differ diff --git a/example/src/main/assets/pic/14/000009.png b/example/src/main/assets/pic/14/000009.png new file mode 100644 index 0000000..36ab863 Binary files /dev/null and b/example/src/main/assets/pic/14/000009.png differ diff --git a/example/src/main/assets/pic/14/000010.png b/example/src/main/assets/pic/14/000010.png new file mode 100644 index 0000000..965049f Binary files /dev/null and b/example/src/main/assets/pic/14/000010.png differ diff --git a/example/src/main/assets/pic/14/000011.png b/example/src/main/assets/pic/14/000011.png new file mode 100644 index 0000000..2b497fd Binary files /dev/null and b/example/src/main/assets/pic/14/000011.png differ diff --git a/example/src/main/assets/pic/14/000012.png b/example/src/main/assets/pic/14/000012.png new file mode 100644 index 0000000..55df32b Binary files /dev/null and b/example/src/main/assets/pic/14/000012.png differ diff --git a/example/src/main/assets/pic/14/000013.png b/example/src/main/assets/pic/14/000013.png new file mode 100644 index 0000000..a96c54b Binary files /dev/null and b/example/src/main/assets/pic/14/000013.png differ diff --git a/example/src/main/assets/pic/14/000014.png b/example/src/main/assets/pic/14/000014.png new file mode 100644 index 0000000..c2f417d Binary files /dev/null and b/example/src/main/assets/pic/14/000014.png differ diff --git a/example/src/main/assets/pic/48/48.png b/example/src/main/assets/pic/14/000015.png similarity index 51% rename from example/src/main/assets/pic/48/48.png rename to example/src/main/assets/pic/14/000015.png index 2d96db4..1f26815 100644 Binary files a/example/src/main/assets/pic/48/48.png and b/example/src/main/assets/pic/14/000015.png differ diff --git a/example/src/main/assets/pic/14/000016.png b/example/src/main/assets/pic/14/000016.png new file mode 100644 index 0000000..e6939bd Binary files /dev/null and b/example/src/main/assets/pic/14/000016.png differ diff --git a/example/src/main/assets/pic/14/000017.png b/example/src/main/assets/pic/14/000017.png new file mode 100644 index 0000000..2917a8c Binary files /dev/null and b/example/src/main/assets/pic/14/000017.png differ diff --git a/example/src/main/assets/pic/14/000018.png b/example/src/main/assets/pic/14/000018.png new file mode 100644 index 0000000..3267815 Binary files /dev/null and b/example/src/main/assets/pic/14/000018.png differ diff --git a/example/src/main/assets/pic/14/000019.png b/example/src/main/assets/pic/14/000019.png new file mode 100644 index 0000000..decbd59 Binary files /dev/null and b/example/src/main/assets/pic/14/000019.png differ diff --git a/example/src/main/assets/pic/14/000020.png b/example/src/main/assets/pic/14/000020.png new file mode 100644 index 0000000..8ac7474 Binary files /dev/null and b/example/src/main/assets/pic/14/000020.png differ diff --git a/example/src/main/assets/pic/14/000021.png b/example/src/main/assets/pic/14/000021.png new file mode 100644 index 0000000..a0c54f9 Binary files /dev/null and b/example/src/main/assets/pic/14/000021.png differ diff --git a/example/src/main/assets/pic/14/000022.png b/example/src/main/assets/pic/14/000022.png new file mode 100644 index 0000000..24bbde5 Binary files /dev/null and b/example/src/main/assets/pic/14/000022.png differ diff --git a/example/src/main/assets/pic/14/000023.png b/example/src/main/assets/pic/14/000023.png new file mode 100644 index 0000000..36db1b2 Binary files /dev/null and b/example/src/main/assets/pic/14/000023.png differ diff --git a/example/src/main/assets/pic/14/000024.png b/example/src/main/assets/pic/14/000024.png new file mode 100644 index 0000000..61c42ee Binary files /dev/null and b/example/src/main/assets/pic/14/000024.png differ diff --git a/example/src/main/assets/pic/14/000025.png b/example/src/main/assets/pic/14/000025.png new file mode 100644 index 0000000..9abcd31 Binary files /dev/null and b/example/src/main/assets/pic/14/000025.png differ diff --git a/example/src/main/assets/pic/14/000026.png b/example/src/main/assets/pic/14/000026.png new file mode 100644 index 0000000..0ed7129 Binary files /dev/null and b/example/src/main/assets/pic/14/000026.png differ diff --git a/example/src/main/assets/pic/14/000027.png b/example/src/main/assets/pic/14/000027.png new file mode 100644 index 0000000..7131260 Binary files /dev/null and b/example/src/main/assets/pic/14/000027.png differ diff --git a/example/src/main/assets/pic/14/000028.png b/example/src/main/assets/pic/14/000028.png new file mode 100644 index 0000000..e217028 Binary files /dev/null and b/example/src/main/assets/pic/14/000028.png differ diff --git a/example/src/main/assets/pic/14/000029.png b/example/src/main/assets/pic/14/000029.png new file mode 100644 index 0000000..39ce00f Binary files /dev/null and b/example/src/main/assets/pic/14/000029.png differ diff --git a/example/src/main/assets/pic/14/000030.png b/example/src/main/assets/pic/14/000030.png new file mode 100644 index 0000000..0706bc3 Binary files /dev/null and b/example/src/main/assets/pic/14/000030.png differ diff --git a/example/src/main/assets/pic/14/000031.png b/example/src/main/assets/pic/14/000031.png new file mode 100644 index 0000000..1f26815 Binary files /dev/null and b/example/src/main/assets/pic/14/000031.png differ diff --git a/example/src/main/assets/pic/14/14.png b/example/src/main/assets/pic/14/14.png deleted file mode 100644 index bc9672f..0000000 Binary files a/example/src/main/assets/pic/14/14.png and /dev/null differ diff --git a/example/src/main/assets/pic/14ex.png b/example/src/main/assets/pic/14ex.png new file mode 100644 index 0000000..5afea4c Binary files /dev/null and b/example/src/main/assets/pic/14ex.png differ diff --git a/example/src/main/assets/pic/21.png b/example/src/main/assets/pic/21.png deleted file mode 100644 index 91982af..0000000 Binary files a/example/src/main/assets/pic/21.png and /dev/null differ diff --git a/example/src/main/assets/pic/21/000000.png b/example/src/main/assets/pic/21/000000.png new file mode 100644 index 0000000..90edc5e Binary files /dev/null and b/example/src/main/assets/pic/21/000000.png differ diff --git a/example/src/main/assets/pic/21/000001.png b/example/src/main/assets/pic/21/000001.png new file mode 100644 index 0000000..a5c60e5 Binary files /dev/null and b/example/src/main/assets/pic/21/000001.png differ diff --git a/example/src/main/assets/pic/21/000002.png b/example/src/main/assets/pic/21/000002.png new file mode 100644 index 0000000..2b9c248 Binary files /dev/null and b/example/src/main/assets/pic/21/000002.png differ diff --git a/example/src/main/assets/pic/21/000003.png b/example/src/main/assets/pic/21/000003.png new file mode 100644 index 0000000..6b48be1 Binary files /dev/null and b/example/src/main/assets/pic/21/000003.png differ diff --git a/example/src/main/assets/pic/21/000004.png b/example/src/main/assets/pic/21/000004.png new file mode 100644 index 0000000..41408f2 Binary files /dev/null and b/example/src/main/assets/pic/21/000004.png differ diff --git a/example/src/main/assets/pic/21/000005.png b/example/src/main/assets/pic/21/000005.png new file mode 100644 index 0000000..2a01769 Binary files /dev/null and b/example/src/main/assets/pic/21/000005.png differ diff --git a/example/src/main/assets/pic/21/000006.png b/example/src/main/assets/pic/21/000006.png new file mode 100644 index 0000000..3f4e974 Binary files /dev/null and b/example/src/main/assets/pic/21/000006.png differ diff --git a/example/src/main/assets/pic/21/000007.png b/example/src/main/assets/pic/21/000007.png new file mode 100644 index 0000000..25a67a3 Binary files /dev/null and b/example/src/main/assets/pic/21/000007.png differ diff --git a/example/src/main/assets/pic/21/000008.png b/example/src/main/assets/pic/21/000008.png new file mode 100644 index 0000000..d43919d Binary files /dev/null and b/example/src/main/assets/pic/21/000008.png differ diff --git a/example/src/main/assets/pic/21/000009.png b/example/src/main/assets/pic/21/000009.png new file mode 100644 index 0000000..dfe1afa Binary files /dev/null and b/example/src/main/assets/pic/21/000009.png differ diff --git a/example/src/main/assets/pic/21/000010.png b/example/src/main/assets/pic/21/000010.png new file mode 100644 index 0000000..a41e2d2 Binary files /dev/null and b/example/src/main/assets/pic/21/000010.png differ diff --git a/example/src/main/assets/pic/21/000011.png b/example/src/main/assets/pic/21/000011.png new file mode 100644 index 0000000..4e1a472 Binary files /dev/null and b/example/src/main/assets/pic/21/000011.png differ diff --git a/example/src/main/assets/pic/21/000012.png b/example/src/main/assets/pic/21/000012.png new file mode 100644 index 0000000..0c0fd08 Binary files /dev/null and b/example/src/main/assets/pic/21/000012.png differ diff --git a/example/src/main/assets/pic/21/000013.png b/example/src/main/assets/pic/21/000013.png new file mode 100644 index 0000000..c9243f4 Binary files /dev/null and b/example/src/main/assets/pic/21/000013.png differ diff --git a/example/src/main/assets/pic/21/000014.png b/example/src/main/assets/pic/21/000014.png new file mode 100644 index 0000000..dce127f Binary files /dev/null and b/example/src/main/assets/pic/21/000014.png differ diff --git a/example/src/main/assets/pic/21/000015.png b/example/src/main/assets/pic/21/000015.png new file mode 100644 index 0000000..62116b4 Binary files /dev/null and b/example/src/main/assets/pic/21/000015.png differ diff --git a/example/src/main/assets/pic/21/000016.png b/example/src/main/assets/pic/21/000016.png new file mode 100644 index 0000000..eb34f23 Binary files /dev/null and b/example/src/main/assets/pic/21/000016.png differ diff --git a/example/src/main/assets/pic/21/000017.png b/example/src/main/assets/pic/21/000017.png new file mode 100644 index 0000000..afd394b Binary files /dev/null and b/example/src/main/assets/pic/21/000017.png differ diff --git a/example/src/main/assets/pic/21/000018.png b/example/src/main/assets/pic/21/000018.png new file mode 100644 index 0000000..8950558 Binary files /dev/null and b/example/src/main/assets/pic/21/000018.png differ diff --git a/example/src/main/assets/pic/21/000019.png b/example/src/main/assets/pic/21/000019.png new file mode 100644 index 0000000..d9a02b7 Binary files /dev/null and b/example/src/main/assets/pic/21/000019.png differ diff --git a/example/src/main/assets/pic/21/000020.png b/example/src/main/assets/pic/21/000020.png new file mode 100644 index 0000000..6c80dec Binary files /dev/null and b/example/src/main/assets/pic/21/000020.png differ diff --git a/example/src/main/assets/pic/21/000021.png b/example/src/main/assets/pic/21/000021.png new file mode 100644 index 0000000..833093c Binary files /dev/null and b/example/src/main/assets/pic/21/000021.png differ diff --git a/example/src/main/assets/pic/21/000022.png b/example/src/main/assets/pic/21/000022.png new file mode 100644 index 0000000..aa7297c Binary files /dev/null and b/example/src/main/assets/pic/21/000022.png differ diff --git a/example/src/main/assets/pic/21/000023.png b/example/src/main/assets/pic/21/000023.png new file mode 100644 index 0000000..9d68253 Binary files /dev/null and b/example/src/main/assets/pic/21/000023.png differ diff --git a/example/src/main/assets/pic/21/000024.png b/example/src/main/assets/pic/21/000024.png new file mode 100644 index 0000000..535e069 Binary files /dev/null and b/example/src/main/assets/pic/21/000024.png differ diff --git a/example/src/main/assets/pic/21/000025.png b/example/src/main/assets/pic/21/000025.png new file mode 100644 index 0000000..2b5cfc2 Binary files /dev/null and b/example/src/main/assets/pic/21/000025.png differ diff --git a/example/src/main/assets/pic/21/000026.png b/example/src/main/assets/pic/21/000026.png new file mode 100644 index 0000000..fa65c9e Binary files /dev/null and b/example/src/main/assets/pic/21/000026.png differ diff --git a/example/src/main/assets/pic/21/000027.png b/example/src/main/assets/pic/21/000027.png new file mode 100644 index 0000000..776b5c0 Binary files /dev/null and b/example/src/main/assets/pic/21/000027.png differ diff --git a/example/src/main/assets/pic/21/000028.png b/example/src/main/assets/pic/21/000028.png new file mode 100644 index 0000000..126896d Binary files /dev/null and b/example/src/main/assets/pic/21/000028.png differ diff --git a/example/src/main/assets/pic/21/000029.png b/example/src/main/assets/pic/21/000029.png new file mode 100644 index 0000000..0e5b9f5 Binary files /dev/null and b/example/src/main/assets/pic/21/000029.png differ diff --git a/example/src/main/assets/pic/21/000030.png b/example/src/main/assets/pic/21/000030.png new file mode 100644 index 0000000..0841a81 Binary files /dev/null and b/example/src/main/assets/pic/21/000030.png differ diff --git a/example/src/main/assets/pic/21/000031.png b/example/src/main/assets/pic/21/000031.png new file mode 100644 index 0000000..62116b4 Binary files /dev/null and b/example/src/main/assets/pic/21/000031.png differ diff --git a/example/src/main/assets/pic/21/21.png b/example/src/main/assets/pic/21/21.png deleted file mode 100644 index 91982af..0000000 Binary files a/example/src/main/assets/pic/21/21.png and /dev/null differ diff --git a/example/src/main/assets/pic/21ex.png b/example/src/main/assets/pic/21ex.png new file mode 100644 index 0000000..d55f143 Binary files /dev/null and b/example/src/main/assets/pic/21ex.png differ diff --git a/example/src/main/assets/pic/23.png b/example/src/main/assets/pic/23.png deleted file mode 100644 index e4cff43..0000000 Binary files a/example/src/main/assets/pic/23.png and /dev/null differ diff --git a/example/src/main/assets/pic/23/23.png b/example/src/main/assets/pic/23/23.png deleted file mode 100644 index e4cff43..0000000 Binary files a/example/src/main/assets/pic/23/23.png and /dev/null differ diff --git a/example/src/main/assets/pic/24.png b/example/src/main/assets/pic/24.png deleted file mode 100644 index 787078e..0000000 Binary files a/example/src/main/assets/pic/24.png and /dev/null differ diff --git a/example/src/main/assets/pic/24/24.png b/example/src/main/assets/pic/24/24.png deleted file mode 100644 index 787078e..0000000 Binary files a/example/src/main/assets/pic/24/24.png and /dev/null differ diff --git a/example/src/main/assets/pic/26.png b/example/src/main/assets/pic/26.png deleted file mode 100644 index 0eb9e2f..0000000 Binary files a/example/src/main/assets/pic/26.png and /dev/null differ diff --git a/example/src/main/assets/pic/26/26.png b/example/src/main/assets/pic/26/26.png deleted file mode 100644 index 0eb9e2f..0000000 Binary files a/example/src/main/assets/pic/26/26.png and /dev/null differ diff --git a/example/src/main/assets/pic/27.png b/example/src/main/assets/pic/27.png deleted file mode 100644 index a659059..0000000 Binary files a/example/src/main/assets/pic/27.png and /dev/null differ diff --git a/example/src/main/assets/pic/27/27.png b/example/src/main/assets/pic/27/27.png deleted file mode 100644 index a659059..0000000 Binary files a/example/src/main/assets/pic/27/27.png and /dev/null differ diff --git a/example/src/main/assets/pic/48.png b/example/src/main/assets/pic/3/000000.png similarity index 56% rename from example/src/main/assets/pic/48.png rename to example/src/main/assets/pic/3/000000.png index 2d96db4..928a9ba 100644 Binary files a/example/src/main/assets/pic/48.png and b/example/src/main/assets/pic/3/000000.png differ diff --git a/example/src/main/assets/pic/32.png b/example/src/main/assets/pic/32.png deleted file mode 100644 index f5d3644..0000000 Binary files a/example/src/main/assets/pic/32.png and /dev/null differ diff --git a/example/src/main/assets/pic/32/32.png b/example/src/main/assets/pic/32/32.png deleted file mode 100644 index f5d3644..0000000 Binary files a/example/src/main/assets/pic/32/32.png and /dev/null differ diff --git a/example/src/main/assets/pic/37.png b/example/src/main/assets/pic/37.png deleted file mode 100644 index 884132c..0000000 Binary files a/example/src/main/assets/pic/37.png and /dev/null differ diff --git a/example/src/main/assets/pic/37/37.png b/example/src/main/assets/pic/37/37.png deleted file mode 100644 index 884132c..0000000 Binary files a/example/src/main/assets/pic/37/37.png and /dev/null differ diff --git a/example/src/main/assets/pic/3ex.png b/example/src/main/assets/pic/3ex.png new file mode 100644 index 0000000..edb6fb5 Binary files /dev/null and b/example/src/main/assets/pic/3ex.png differ diff --git a/example/src/main/assets/pic/4.png b/example/src/main/assets/pic/4.png deleted file mode 100644 index 1ef1851..0000000 Binary files a/example/src/main/assets/pic/4.png and /dev/null differ diff --git a/example/src/main/assets/pic/4/000000.png b/example/src/main/assets/pic/4/000000.png new file mode 100644 index 0000000..1634b44 Binary files /dev/null and b/example/src/main/assets/pic/4/000000.png differ diff --git a/example/src/main/assets/pic/4/000001.png b/example/src/main/assets/pic/4/000001.png new file mode 100644 index 0000000..d14fb54 Binary files /dev/null and b/example/src/main/assets/pic/4/000001.png differ diff --git a/example/src/main/assets/pic/4/000002.png b/example/src/main/assets/pic/4/000002.png new file mode 100644 index 0000000..777efe7 Binary files /dev/null and b/example/src/main/assets/pic/4/000002.png differ diff --git a/example/src/main/assets/pic/4/000003.png b/example/src/main/assets/pic/4/000003.png new file mode 100644 index 0000000..730d370 Binary files /dev/null and b/example/src/main/assets/pic/4/000003.png differ diff --git a/example/src/main/assets/pic/4/000004.png b/example/src/main/assets/pic/4/000004.png new file mode 100644 index 0000000..2e6f49a Binary files /dev/null and b/example/src/main/assets/pic/4/000004.png differ diff --git a/example/src/main/assets/pic/4/000005.png b/example/src/main/assets/pic/4/000005.png new file mode 100644 index 0000000..741f3f8 Binary files /dev/null and b/example/src/main/assets/pic/4/000005.png differ diff --git a/example/src/main/assets/pic/4/000006.png b/example/src/main/assets/pic/4/000006.png new file mode 100644 index 0000000..8fe5a70 Binary files /dev/null and b/example/src/main/assets/pic/4/000006.png differ diff --git a/example/src/main/assets/pic/4/000007.png b/example/src/main/assets/pic/4/000007.png new file mode 100644 index 0000000..a1116a1 Binary files /dev/null and b/example/src/main/assets/pic/4/000007.png differ diff --git a/example/src/main/assets/pic/4/000008.png b/example/src/main/assets/pic/4/000008.png new file mode 100644 index 0000000..b571314 Binary files /dev/null and b/example/src/main/assets/pic/4/000008.png differ diff --git a/example/src/main/assets/pic/4/000009.png b/example/src/main/assets/pic/4/000009.png new file mode 100644 index 0000000..38d318e Binary files /dev/null and b/example/src/main/assets/pic/4/000009.png differ diff --git a/example/src/main/assets/pic/4/000010.png b/example/src/main/assets/pic/4/000010.png new file mode 100644 index 0000000..505eca7 Binary files /dev/null and b/example/src/main/assets/pic/4/000010.png differ diff --git a/example/src/main/assets/pic/4/000011.png b/example/src/main/assets/pic/4/000011.png new file mode 100644 index 0000000..a47faca Binary files /dev/null and b/example/src/main/assets/pic/4/000011.png differ diff --git a/example/src/main/assets/pic/4/000012.png b/example/src/main/assets/pic/4/000012.png new file mode 100644 index 0000000..432104b Binary files /dev/null and b/example/src/main/assets/pic/4/000012.png differ diff --git a/example/src/main/assets/pic/4/000013.png b/example/src/main/assets/pic/4/000013.png new file mode 100644 index 0000000..a9eb6c6 Binary files /dev/null and b/example/src/main/assets/pic/4/000013.png differ diff --git a/example/src/main/assets/pic/4/000014.png b/example/src/main/assets/pic/4/000014.png new file mode 100644 index 0000000..97bc25a Binary files /dev/null and b/example/src/main/assets/pic/4/000014.png differ diff --git a/example/src/main/assets/pic/4/000015.png b/example/src/main/assets/pic/4/000015.png new file mode 100644 index 0000000..089b01d Binary files /dev/null and b/example/src/main/assets/pic/4/000015.png differ diff --git a/example/src/main/assets/pic/4/000016.png b/example/src/main/assets/pic/4/000016.png new file mode 100644 index 0000000..4850f79 Binary files /dev/null and b/example/src/main/assets/pic/4/000016.png differ diff --git a/example/src/main/assets/pic/4/000017.png b/example/src/main/assets/pic/4/000017.png new file mode 100644 index 0000000..49046fe Binary files /dev/null and b/example/src/main/assets/pic/4/000017.png differ diff --git a/example/src/main/assets/pic/4/000018.png b/example/src/main/assets/pic/4/000018.png new file mode 100644 index 0000000..5b00069 Binary files /dev/null and b/example/src/main/assets/pic/4/000018.png differ diff --git a/example/src/main/assets/pic/4/000019.png b/example/src/main/assets/pic/4/000019.png new file mode 100644 index 0000000..89b3c53 Binary files /dev/null and b/example/src/main/assets/pic/4/000019.png differ diff --git a/example/src/main/assets/pic/4/000020.png b/example/src/main/assets/pic/4/000020.png new file mode 100644 index 0000000..83e638f Binary files /dev/null and b/example/src/main/assets/pic/4/000020.png differ diff --git a/example/src/main/assets/pic/4/000021.png b/example/src/main/assets/pic/4/000021.png new file mode 100644 index 0000000..183dc9e Binary files /dev/null and b/example/src/main/assets/pic/4/000021.png differ diff --git a/example/src/main/assets/pic/4/000022.png b/example/src/main/assets/pic/4/000022.png new file mode 100644 index 0000000..1919864 Binary files /dev/null and b/example/src/main/assets/pic/4/000022.png differ diff --git a/example/src/main/assets/pic/4/000023.png b/example/src/main/assets/pic/4/000023.png new file mode 100644 index 0000000..1729e73 Binary files /dev/null and b/example/src/main/assets/pic/4/000023.png differ diff --git a/example/src/main/assets/pic/4/000024.png b/example/src/main/assets/pic/4/000024.png new file mode 100644 index 0000000..f90dd48 Binary files /dev/null and b/example/src/main/assets/pic/4/000024.png differ diff --git a/example/src/main/assets/pic/4/000025.png b/example/src/main/assets/pic/4/000025.png new file mode 100644 index 0000000..72cb76d Binary files /dev/null and b/example/src/main/assets/pic/4/000025.png differ diff --git a/example/src/main/assets/pic/4/000026.png b/example/src/main/assets/pic/4/000026.png new file mode 100644 index 0000000..996fb28 Binary files /dev/null and b/example/src/main/assets/pic/4/000026.png differ diff --git a/example/src/main/assets/pic/4/000027.png b/example/src/main/assets/pic/4/000027.png new file mode 100644 index 0000000..31fcf7a Binary files /dev/null and b/example/src/main/assets/pic/4/000027.png differ diff --git a/example/src/main/assets/pic/4/000028.png b/example/src/main/assets/pic/4/000028.png new file mode 100644 index 0000000..a96e380 Binary files /dev/null and b/example/src/main/assets/pic/4/000028.png differ diff --git a/example/src/main/assets/pic/4/000029.png b/example/src/main/assets/pic/4/000029.png new file mode 100644 index 0000000..167ace5 Binary files /dev/null and b/example/src/main/assets/pic/4/000029.png differ diff --git a/example/src/main/assets/pic/4/000030.png b/example/src/main/assets/pic/4/000030.png new file mode 100644 index 0000000..d6ec1ab Binary files /dev/null and b/example/src/main/assets/pic/4/000030.png differ diff --git a/example/src/main/assets/pic/4/000031.png b/example/src/main/assets/pic/4/000031.png new file mode 100644 index 0000000..84d58ae Binary files /dev/null and b/example/src/main/assets/pic/4/000031.png differ diff --git a/example/src/main/assets/pic/4/4.png b/example/src/main/assets/pic/4/4.png deleted file mode 100644 index 1ef1851..0000000 Binary files a/example/src/main/assets/pic/4/4.png and /dev/null differ diff --git a/example/src/main/assets/pic/40.png b/example/src/main/assets/pic/40.png deleted file mode 100644 index b6fc97b..0000000 Binary files a/example/src/main/assets/pic/40.png and /dev/null differ diff --git a/example/src/main/assets/pic/40/40.png b/example/src/main/assets/pic/40/40.png deleted file mode 100644 index b6fc97b..0000000 Binary files a/example/src/main/assets/pic/40/40.png and /dev/null differ diff --git a/example/src/main/assets/pic/45.png b/example/src/main/assets/pic/45.png deleted file mode 100644 index 87fa44c..0000000 Binary files a/example/src/main/assets/pic/45.png and /dev/null differ diff --git a/example/src/main/assets/pic/45/45.png b/example/src/main/assets/pic/45/45.png deleted file mode 100644 index 87fa44c..0000000 Binary files a/example/src/main/assets/pic/45/45.png and /dev/null differ diff --git a/example/src/main/assets/pic/49.png b/example/src/main/assets/pic/49.png deleted file mode 100644 index 4de2382..0000000 Binary files a/example/src/main/assets/pic/49.png and /dev/null differ diff --git a/example/src/main/assets/pic/49/49.png b/example/src/main/assets/pic/49/49.png deleted file mode 100644 index 4de2382..0000000 Binary files a/example/src/main/assets/pic/49/49.png and /dev/null differ diff --git a/example/src/main/assets/pic/4ex.png b/example/src/main/assets/pic/4ex.png new file mode 100644 index 0000000..9e4a3d1 Binary files /dev/null and b/example/src/main/assets/pic/4ex.png differ diff --git a/example/src/main/assets/pic/5.png b/example/src/main/assets/pic/5.png deleted file mode 100644 index 388c97e..0000000 Binary files a/example/src/main/assets/pic/5.png and /dev/null differ diff --git a/example/src/main/assets/pic/5/000000.png b/example/src/main/assets/pic/5/000000.png new file mode 100644 index 0000000..8e73278 Binary files /dev/null and b/example/src/main/assets/pic/5/000000.png differ diff --git a/example/src/main/assets/pic/5/000001.png b/example/src/main/assets/pic/5/000001.png new file mode 100644 index 0000000..b70f626 Binary files /dev/null and b/example/src/main/assets/pic/5/000001.png differ diff --git a/example/src/main/assets/pic/5/000002.png b/example/src/main/assets/pic/5/000002.png new file mode 100644 index 0000000..e9ba317 Binary files /dev/null and b/example/src/main/assets/pic/5/000002.png differ diff --git a/example/src/main/assets/pic/5/000003.png b/example/src/main/assets/pic/5/000003.png new file mode 100644 index 0000000..c5fe643 Binary files /dev/null and b/example/src/main/assets/pic/5/000003.png differ diff --git a/example/src/main/assets/pic/5/000004.png b/example/src/main/assets/pic/5/000004.png new file mode 100644 index 0000000..b4f3557 Binary files /dev/null and b/example/src/main/assets/pic/5/000004.png differ diff --git a/example/src/main/assets/pic/5/000005.png b/example/src/main/assets/pic/5/000005.png new file mode 100644 index 0000000..045a6f3 Binary files /dev/null and b/example/src/main/assets/pic/5/000005.png differ diff --git a/example/src/main/assets/pic/5/000006.png b/example/src/main/assets/pic/5/000006.png new file mode 100644 index 0000000..0cfcd71 Binary files /dev/null and b/example/src/main/assets/pic/5/000006.png differ diff --git a/example/src/main/assets/pic/5/000007.png b/example/src/main/assets/pic/5/000007.png new file mode 100644 index 0000000..00a036c Binary files /dev/null and b/example/src/main/assets/pic/5/000007.png differ diff --git a/example/src/main/assets/pic/5/000008.png b/example/src/main/assets/pic/5/000008.png new file mode 100644 index 0000000..3fc185d Binary files /dev/null and b/example/src/main/assets/pic/5/000008.png differ diff --git a/example/src/main/assets/pic/5/000009.png b/example/src/main/assets/pic/5/000009.png new file mode 100644 index 0000000..83d0f43 Binary files /dev/null and b/example/src/main/assets/pic/5/000009.png differ diff --git a/example/src/main/assets/pic/5/000010.png b/example/src/main/assets/pic/5/000010.png new file mode 100644 index 0000000..46a81c8 Binary files /dev/null and b/example/src/main/assets/pic/5/000010.png differ diff --git a/example/src/main/assets/pic/5/000011.png b/example/src/main/assets/pic/5/000011.png new file mode 100644 index 0000000..1fa8b00 Binary files /dev/null and b/example/src/main/assets/pic/5/000011.png differ diff --git a/example/src/main/assets/pic/5/000012.png b/example/src/main/assets/pic/5/000012.png new file mode 100644 index 0000000..58056f1 Binary files /dev/null and b/example/src/main/assets/pic/5/000012.png differ diff --git a/example/src/main/assets/pic/5/000013.png b/example/src/main/assets/pic/5/000013.png new file mode 100644 index 0000000..2748b3d Binary files /dev/null and b/example/src/main/assets/pic/5/000013.png differ diff --git a/example/src/main/assets/pic/5/000014.png b/example/src/main/assets/pic/5/000014.png new file mode 100644 index 0000000..16ff141 Binary files /dev/null and b/example/src/main/assets/pic/5/000014.png differ diff --git a/example/src/main/assets/pic/5/000015.png b/example/src/main/assets/pic/5/000015.png new file mode 100644 index 0000000..3fc1519 Binary files /dev/null and b/example/src/main/assets/pic/5/000015.png differ diff --git a/example/src/main/assets/pic/5/000016.png b/example/src/main/assets/pic/5/000016.png new file mode 100644 index 0000000..b457a1d Binary files /dev/null and b/example/src/main/assets/pic/5/000016.png differ diff --git a/example/src/main/assets/pic/5/000017.png b/example/src/main/assets/pic/5/000017.png new file mode 100644 index 0000000..aa5009b Binary files /dev/null and b/example/src/main/assets/pic/5/000017.png differ diff --git a/example/src/main/assets/pic/5/000018.png b/example/src/main/assets/pic/5/000018.png new file mode 100644 index 0000000..53136e4 Binary files /dev/null and b/example/src/main/assets/pic/5/000018.png differ diff --git a/example/src/main/assets/pic/5/000019.png b/example/src/main/assets/pic/5/000019.png new file mode 100644 index 0000000..f0bfd6b Binary files /dev/null and b/example/src/main/assets/pic/5/000019.png differ diff --git a/example/src/main/assets/pic/5/000020.png b/example/src/main/assets/pic/5/000020.png new file mode 100644 index 0000000..a337c1e Binary files /dev/null and b/example/src/main/assets/pic/5/000020.png differ diff --git a/example/src/main/assets/pic/5/000021.png b/example/src/main/assets/pic/5/000021.png new file mode 100644 index 0000000..f71ec94 Binary files /dev/null and b/example/src/main/assets/pic/5/000021.png differ diff --git a/example/src/main/assets/pic/5/000022.png b/example/src/main/assets/pic/5/000022.png new file mode 100644 index 0000000..f8a9005 Binary files /dev/null and b/example/src/main/assets/pic/5/000022.png differ diff --git a/example/src/main/assets/pic/5/000023.png b/example/src/main/assets/pic/5/000023.png new file mode 100644 index 0000000..8d2db41 Binary files /dev/null and b/example/src/main/assets/pic/5/000023.png differ diff --git a/example/src/main/assets/pic/5/000024.png b/example/src/main/assets/pic/5/000024.png new file mode 100644 index 0000000..3c75bd7 Binary files /dev/null and b/example/src/main/assets/pic/5/000024.png differ diff --git a/example/src/main/assets/pic/5/000025.png b/example/src/main/assets/pic/5/000025.png new file mode 100644 index 0000000..4688a07 Binary files /dev/null and b/example/src/main/assets/pic/5/000025.png differ diff --git a/example/src/main/assets/pic/5/000026.png b/example/src/main/assets/pic/5/000026.png new file mode 100644 index 0000000..5878626 Binary files /dev/null and b/example/src/main/assets/pic/5/000026.png differ diff --git a/example/src/main/assets/pic/5/000027.png b/example/src/main/assets/pic/5/000027.png new file mode 100644 index 0000000..5d51bc4 Binary files /dev/null and b/example/src/main/assets/pic/5/000027.png differ diff --git a/example/src/main/assets/pic/5/000028.png b/example/src/main/assets/pic/5/000028.png new file mode 100644 index 0000000..e7ee156 Binary files /dev/null and b/example/src/main/assets/pic/5/000028.png differ diff --git a/example/src/main/assets/pic/5/000029.png b/example/src/main/assets/pic/5/000029.png new file mode 100644 index 0000000..45ecd73 Binary files /dev/null and b/example/src/main/assets/pic/5/000029.png differ diff --git a/example/src/main/assets/pic/5/000030.png b/example/src/main/assets/pic/5/000030.png new file mode 100644 index 0000000..d3b7a62 Binary files /dev/null and b/example/src/main/assets/pic/5/000030.png differ diff --git a/example/src/main/assets/pic/5/000031.png b/example/src/main/assets/pic/5/000031.png new file mode 100644 index 0000000..750ada1 Binary files /dev/null and b/example/src/main/assets/pic/5/000031.png differ diff --git a/example/src/main/assets/pic/5/5.png b/example/src/main/assets/pic/5/5.png deleted file mode 100644 index 388c97e..0000000 Binary files a/example/src/main/assets/pic/5/5.png and /dev/null differ diff --git a/example/src/main/assets/pic/53.png b/example/src/main/assets/pic/53.png deleted file mode 100644 index 7089599..0000000 Binary files a/example/src/main/assets/pic/53.png and /dev/null differ diff --git a/example/src/main/assets/pic/53/53.png b/example/src/main/assets/pic/53/53.png deleted file mode 100644 index 7089599..0000000 Binary files a/example/src/main/assets/pic/53/53.png and /dev/null differ diff --git a/example/src/main/assets/pic/56.png b/example/src/main/assets/pic/56.png deleted file mode 100644 index 3cf5eeb..0000000 Binary files a/example/src/main/assets/pic/56.png and /dev/null differ diff --git a/example/src/main/assets/pic/56/000000.png b/example/src/main/assets/pic/56/000000.png new file mode 100644 index 0000000..dc203d7 Binary files /dev/null and b/example/src/main/assets/pic/56/000000.png differ diff --git a/example/src/main/assets/pic/56/000001.png b/example/src/main/assets/pic/56/000001.png new file mode 100644 index 0000000..559acb2 Binary files /dev/null and b/example/src/main/assets/pic/56/000001.png differ diff --git a/example/src/main/assets/pic/56/000002.png b/example/src/main/assets/pic/56/000002.png new file mode 100644 index 0000000..492d454 Binary files /dev/null and b/example/src/main/assets/pic/56/000002.png differ diff --git a/example/src/main/assets/pic/56/000003.png b/example/src/main/assets/pic/56/000003.png new file mode 100644 index 0000000..8c322a0 Binary files /dev/null and b/example/src/main/assets/pic/56/000003.png differ diff --git a/example/src/main/assets/pic/56/000004.png b/example/src/main/assets/pic/56/000004.png new file mode 100644 index 0000000..667b853 Binary files /dev/null and b/example/src/main/assets/pic/56/000004.png differ diff --git a/example/src/main/assets/pic/56/000005.png b/example/src/main/assets/pic/56/000005.png new file mode 100644 index 0000000..b25f188 Binary files /dev/null and b/example/src/main/assets/pic/56/000005.png differ diff --git a/example/src/main/assets/pic/56/000006.png b/example/src/main/assets/pic/56/000006.png new file mode 100644 index 0000000..1844de1 Binary files /dev/null and b/example/src/main/assets/pic/56/000006.png differ diff --git a/example/src/main/assets/pic/56/000007.png b/example/src/main/assets/pic/56/000007.png new file mode 100644 index 0000000..90bfae8 Binary files /dev/null and b/example/src/main/assets/pic/56/000007.png differ diff --git a/example/src/main/assets/pic/56/000008.png b/example/src/main/assets/pic/56/000008.png new file mode 100644 index 0000000..441b108 Binary files /dev/null and b/example/src/main/assets/pic/56/000008.png differ diff --git a/example/src/main/assets/pic/56/000009.png b/example/src/main/assets/pic/56/000009.png new file mode 100644 index 0000000..4445e76 Binary files /dev/null and b/example/src/main/assets/pic/56/000009.png differ diff --git a/example/src/main/assets/pic/56/000010.png b/example/src/main/assets/pic/56/000010.png new file mode 100644 index 0000000..774adeb Binary files /dev/null and b/example/src/main/assets/pic/56/000010.png differ diff --git a/example/src/main/assets/pic/56/000011.png b/example/src/main/assets/pic/56/000011.png new file mode 100644 index 0000000..7227ef6 Binary files /dev/null and b/example/src/main/assets/pic/56/000011.png differ diff --git a/example/src/main/assets/pic/56/000012.png b/example/src/main/assets/pic/56/000012.png new file mode 100644 index 0000000..5451354 Binary files /dev/null and b/example/src/main/assets/pic/56/000012.png differ diff --git a/example/src/main/assets/pic/56/000013.png b/example/src/main/assets/pic/56/000013.png new file mode 100644 index 0000000..07ef17e Binary files /dev/null and b/example/src/main/assets/pic/56/000013.png differ diff --git a/example/src/main/assets/pic/56/000014.png b/example/src/main/assets/pic/56/000014.png new file mode 100644 index 0000000..ec2ea0f Binary files /dev/null and b/example/src/main/assets/pic/56/000014.png differ diff --git a/example/src/main/assets/pic/56/000015.png b/example/src/main/assets/pic/56/000015.png new file mode 100644 index 0000000..509274e Binary files /dev/null and b/example/src/main/assets/pic/56/000015.png differ diff --git a/example/src/main/assets/pic/56/000016.png b/example/src/main/assets/pic/56/000016.png new file mode 100644 index 0000000..8c37626 Binary files /dev/null and b/example/src/main/assets/pic/56/000016.png differ diff --git a/example/src/main/assets/pic/56/000017.png b/example/src/main/assets/pic/56/000017.png new file mode 100644 index 0000000..c059e79 Binary files /dev/null and b/example/src/main/assets/pic/56/000017.png differ diff --git a/example/src/main/assets/pic/56/000018.png b/example/src/main/assets/pic/56/000018.png new file mode 100644 index 0000000..85fd249 Binary files /dev/null and b/example/src/main/assets/pic/56/000018.png differ diff --git a/example/src/main/assets/pic/56/000019.png b/example/src/main/assets/pic/56/000019.png new file mode 100644 index 0000000..7250c80 Binary files /dev/null and b/example/src/main/assets/pic/56/000019.png differ diff --git a/example/src/main/assets/pic/56/000020.png b/example/src/main/assets/pic/56/000020.png new file mode 100644 index 0000000..2c9b6d6 Binary files /dev/null and b/example/src/main/assets/pic/56/000020.png differ diff --git a/example/src/main/assets/pic/56/000021.png b/example/src/main/assets/pic/56/000021.png new file mode 100644 index 0000000..5c7d9ae Binary files /dev/null and b/example/src/main/assets/pic/56/000021.png differ diff --git a/example/src/main/assets/pic/56/000022.png b/example/src/main/assets/pic/56/000022.png new file mode 100644 index 0000000..af125d6 Binary files /dev/null and b/example/src/main/assets/pic/56/000022.png differ diff --git a/example/src/main/assets/pic/56/000023.png b/example/src/main/assets/pic/56/000023.png new file mode 100644 index 0000000..9f2eeea Binary files /dev/null and b/example/src/main/assets/pic/56/000023.png differ diff --git a/example/src/main/assets/pic/56/000024.png b/example/src/main/assets/pic/56/000024.png new file mode 100644 index 0000000..e18ae0c Binary files /dev/null and b/example/src/main/assets/pic/56/000024.png differ diff --git a/example/src/main/assets/pic/56/000025.png b/example/src/main/assets/pic/56/000025.png new file mode 100644 index 0000000..6cd5a05 Binary files /dev/null and b/example/src/main/assets/pic/56/000025.png differ diff --git a/example/src/main/assets/pic/56/000026.png b/example/src/main/assets/pic/56/000026.png new file mode 100644 index 0000000..6836e62 Binary files /dev/null and b/example/src/main/assets/pic/56/000026.png differ diff --git a/example/src/main/assets/pic/56/000027.png b/example/src/main/assets/pic/56/000027.png new file mode 100644 index 0000000..3ac26cc Binary files /dev/null and b/example/src/main/assets/pic/56/000027.png differ diff --git a/example/src/main/assets/pic/56/000028.png b/example/src/main/assets/pic/56/000028.png new file mode 100644 index 0000000..42f8017 Binary files /dev/null and b/example/src/main/assets/pic/56/000028.png differ diff --git a/example/src/main/assets/pic/56/000029.png b/example/src/main/assets/pic/56/000029.png new file mode 100644 index 0000000..c524dbc Binary files /dev/null and b/example/src/main/assets/pic/56/000029.png differ diff --git a/example/src/main/assets/pic/56/000030.png b/example/src/main/assets/pic/56/000030.png new file mode 100644 index 0000000..4504b98 Binary files /dev/null and b/example/src/main/assets/pic/56/000030.png differ diff --git a/example/src/main/assets/pic/56/000031.png b/example/src/main/assets/pic/56/000031.png new file mode 100644 index 0000000..509274e Binary files /dev/null and b/example/src/main/assets/pic/56/000031.png differ diff --git a/example/src/main/assets/pic/56/56.png b/example/src/main/assets/pic/56/56.png deleted file mode 100644 index 3cf5eeb..0000000 Binary files a/example/src/main/assets/pic/56/56.png and /dev/null differ diff --git a/example/src/main/assets/pic/56ex.png b/example/src/main/assets/pic/56ex.png new file mode 100644 index 0000000..30e9959 Binary files /dev/null and b/example/src/main/assets/pic/56ex.png differ diff --git a/example/src/main/assets/pic/59.png b/example/src/main/assets/pic/59.png deleted file mode 100644 index dc8bd0d..0000000 Binary files a/example/src/main/assets/pic/59.png and /dev/null differ diff --git a/example/src/main/assets/pic/59/000000.png b/example/src/main/assets/pic/59/000000.png new file mode 100644 index 0000000..ce80321 Binary files /dev/null and b/example/src/main/assets/pic/59/000000.png differ diff --git a/example/src/main/assets/pic/59/000001.png b/example/src/main/assets/pic/59/000001.png new file mode 100644 index 0000000..40f38af Binary files /dev/null and b/example/src/main/assets/pic/59/000001.png differ diff --git a/example/src/main/assets/pic/59/000002.png b/example/src/main/assets/pic/59/000002.png new file mode 100644 index 0000000..695a26b Binary files /dev/null and b/example/src/main/assets/pic/59/000002.png differ diff --git a/example/src/main/assets/pic/59/000003.png b/example/src/main/assets/pic/59/000003.png new file mode 100644 index 0000000..501e2fe Binary files /dev/null and b/example/src/main/assets/pic/59/000003.png differ diff --git a/example/src/main/assets/pic/59/000004.png b/example/src/main/assets/pic/59/000004.png new file mode 100644 index 0000000..118240c Binary files /dev/null and b/example/src/main/assets/pic/59/000004.png differ diff --git a/example/src/main/assets/pic/59/000005.png b/example/src/main/assets/pic/59/000005.png new file mode 100644 index 0000000..7558b17 Binary files /dev/null and b/example/src/main/assets/pic/59/000005.png differ diff --git a/example/src/main/assets/pic/59/000006.png b/example/src/main/assets/pic/59/000006.png new file mode 100644 index 0000000..b3bf6a5 Binary files /dev/null and b/example/src/main/assets/pic/59/000006.png differ diff --git a/example/src/main/assets/pic/59/000007.png b/example/src/main/assets/pic/59/000007.png new file mode 100644 index 0000000..67247e6 Binary files /dev/null and b/example/src/main/assets/pic/59/000007.png differ diff --git a/example/src/main/assets/pic/59/000008.png b/example/src/main/assets/pic/59/000008.png new file mode 100644 index 0000000..5a7af5c Binary files /dev/null and b/example/src/main/assets/pic/59/000008.png differ diff --git a/example/src/main/assets/pic/59/000009.png b/example/src/main/assets/pic/59/000009.png new file mode 100644 index 0000000..8ad3198 Binary files /dev/null and b/example/src/main/assets/pic/59/000009.png differ diff --git a/example/src/main/assets/pic/59/000010.png b/example/src/main/assets/pic/59/000010.png new file mode 100644 index 0000000..72dfcb8 Binary files /dev/null and b/example/src/main/assets/pic/59/000010.png differ diff --git a/example/src/main/assets/pic/59/000011.png b/example/src/main/assets/pic/59/000011.png new file mode 100644 index 0000000..bb929fc Binary files /dev/null and b/example/src/main/assets/pic/59/000011.png differ diff --git a/example/src/main/assets/pic/59/000012.png b/example/src/main/assets/pic/59/000012.png new file mode 100644 index 0000000..7f3a4f9 Binary files /dev/null and b/example/src/main/assets/pic/59/000012.png differ diff --git a/example/src/main/assets/pic/59/000013.png b/example/src/main/assets/pic/59/000013.png new file mode 100644 index 0000000..710bd33 Binary files /dev/null and b/example/src/main/assets/pic/59/000013.png differ diff --git a/example/src/main/assets/pic/59/000014.png b/example/src/main/assets/pic/59/000014.png new file mode 100644 index 0000000..acdeca7 Binary files /dev/null and b/example/src/main/assets/pic/59/000014.png differ diff --git a/example/src/main/assets/pic/59/000015.png b/example/src/main/assets/pic/59/000015.png new file mode 100644 index 0000000..30d1cae Binary files /dev/null and b/example/src/main/assets/pic/59/000015.png differ diff --git a/example/src/main/assets/pic/59/000016.png b/example/src/main/assets/pic/59/000016.png new file mode 100644 index 0000000..116b8a1 Binary files /dev/null and b/example/src/main/assets/pic/59/000016.png differ diff --git a/example/src/main/assets/pic/59/000017.png b/example/src/main/assets/pic/59/000017.png new file mode 100644 index 0000000..a49492d Binary files /dev/null and b/example/src/main/assets/pic/59/000017.png differ diff --git a/example/src/main/assets/pic/59/000018.png b/example/src/main/assets/pic/59/000018.png new file mode 100644 index 0000000..2ca8b8d Binary files /dev/null and b/example/src/main/assets/pic/59/000018.png differ diff --git a/example/src/main/assets/pic/59/000019.png b/example/src/main/assets/pic/59/000019.png new file mode 100644 index 0000000..31ba3a7 Binary files /dev/null and b/example/src/main/assets/pic/59/000019.png differ diff --git a/example/src/main/assets/pic/59/000020.png b/example/src/main/assets/pic/59/000020.png new file mode 100644 index 0000000..959a869 Binary files /dev/null and b/example/src/main/assets/pic/59/000020.png differ diff --git a/example/src/main/assets/pic/59/000021.png b/example/src/main/assets/pic/59/000021.png new file mode 100644 index 0000000..8c27e26 Binary files /dev/null and b/example/src/main/assets/pic/59/000021.png differ diff --git a/example/src/main/assets/pic/59/000022.png b/example/src/main/assets/pic/59/000022.png new file mode 100644 index 0000000..f0df206 Binary files /dev/null and b/example/src/main/assets/pic/59/000022.png differ diff --git a/example/src/main/assets/pic/59/000023.png b/example/src/main/assets/pic/59/000023.png new file mode 100644 index 0000000..414faf9 Binary files /dev/null and b/example/src/main/assets/pic/59/000023.png differ diff --git a/example/src/main/assets/pic/59/59.png b/example/src/main/assets/pic/59/59.png deleted file mode 100644 index dc8bd0d..0000000 Binary files a/example/src/main/assets/pic/59/59.png and /dev/null differ diff --git a/example/src/main/assets/pic/59ex.png b/example/src/main/assets/pic/59ex.png new file mode 100644 index 0000000..1d3bb35 Binary files /dev/null and b/example/src/main/assets/pic/59ex.png differ diff --git a/example/src/main/assets/pic/5ex.png b/example/src/main/assets/pic/5ex.png new file mode 100644 index 0000000..4b48dd0 Binary files /dev/null and b/example/src/main/assets/pic/5ex.png differ diff --git a/example/src/main/assets/pic/6.png b/example/src/main/assets/pic/6.png deleted file mode 100644 index bff8bff..0000000 Binary files a/example/src/main/assets/pic/6.png and /dev/null differ diff --git a/example/src/main/assets/pic/6/000000.png b/example/src/main/assets/pic/6/000000.png new file mode 100644 index 0000000..d2679c2 Binary files /dev/null and b/example/src/main/assets/pic/6/000000.png differ diff --git a/example/src/main/assets/pic/6/000001.png b/example/src/main/assets/pic/6/000001.png new file mode 100644 index 0000000..2fba049 Binary files /dev/null and b/example/src/main/assets/pic/6/000001.png differ diff --git a/example/src/main/assets/pic/6/000002.png b/example/src/main/assets/pic/6/000002.png new file mode 100644 index 0000000..6fd82ab Binary files /dev/null and b/example/src/main/assets/pic/6/000002.png differ diff --git a/example/src/main/assets/pic/6/000003.png b/example/src/main/assets/pic/6/000003.png new file mode 100644 index 0000000..231b173 Binary files /dev/null and b/example/src/main/assets/pic/6/000003.png differ diff --git a/example/src/main/assets/pic/6/000004.png b/example/src/main/assets/pic/6/000004.png new file mode 100644 index 0000000..80eb567 Binary files /dev/null and b/example/src/main/assets/pic/6/000004.png differ diff --git a/example/src/main/assets/pic/6/000005.png b/example/src/main/assets/pic/6/000005.png new file mode 100644 index 0000000..5c3d456 Binary files /dev/null and b/example/src/main/assets/pic/6/000005.png differ diff --git a/example/src/main/assets/pic/6/000006.png b/example/src/main/assets/pic/6/000006.png new file mode 100644 index 0000000..8f5eeeb Binary files /dev/null and b/example/src/main/assets/pic/6/000006.png differ diff --git a/example/src/main/assets/pic/6/000007.png b/example/src/main/assets/pic/6/000007.png new file mode 100644 index 0000000..9e93f28 Binary files /dev/null and b/example/src/main/assets/pic/6/000007.png differ diff --git a/example/src/main/assets/pic/6/000008.png b/example/src/main/assets/pic/6/000008.png new file mode 100644 index 0000000..2d0a76c Binary files /dev/null and b/example/src/main/assets/pic/6/000008.png differ diff --git a/example/src/main/assets/pic/6/000009.png b/example/src/main/assets/pic/6/000009.png new file mode 100644 index 0000000..05aa3cb Binary files /dev/null and b/example/src/main/assets/pic/6/000009.png differ diff --git a/example/src/main/assets/pic/6/000010.png b/example/src/main/assets/pic/6/000010.png new file mode 100644 index 0000000..2db444e Binary files /dev/null and b/example/src/main/assets/pic/6/000010.png differ diff --git a/example/src/main/assets/pic/6/000011.png b/example/src/main/assets/pic/6/000011.png new file mode 100644 index 0000000..7709f73 Binary files /dev/null and b/example/src/main/assets/pic/6/000011.png differ diff --git a/example/src/main/assets/pic/6/000012.png b/example/src/main/assets/pic/6/000012.png new file mode 100644 index 0000000..7bee292 Binary files /dev/null and b/example/src/main/assets/pic/6/000012.png differ diff --git a/example/src/main/assets/pic/6/000013.png b/example/src/main/assets/pic/6/000013.png new file mode 100644 index 0000000..079c2bd Binary files /dev/null and b/example/src/main/assets/pic/6/000013.png differ diff --git a/example/src/main/assets/pic/6/000014.png b/example/src/main/assets/pic/6/000014.png new file mode 100644 index 0000000..9dcebb5 Binary files /dev/null and b/example/src/main/assets/pic/6/000014.png differ diff --git a/example/src/main/assets/pic/6/000015.png b/example/src/main/assets/pic/6/000015.png new file mode 100644 index 0000000..89d8f85 Binary files /dev/null and b/example/src/main/assets/pic/6/000015.png differ diff --git a/example/src/main/assets/pic/6/000016.png b/example/src/main/assets/pic/6/000016.png new file mode 100644 index 0000000..e6e76ae Binary files /dev/null and b/example/src/main/assets/pic/6/000016.png differ diff --git a/example/src/main/assets/pic/6/000017.png b/example/src/main/assets/pic/6/000017.png new file mode 100644 index 0000000..61388c3 Binary files /dev/null and b/example/src/main/assets/pic/6/000017.png differ diff --git a/example/src/main/assets/pic/6/000018.png b/example/src/main/assets/pic/6/000018.png new file mode 100644 index 0000000..119bd46 Binary files /dev/null and b/example/src/main/assets/pic/6/000018.png differ diff --git a/example/src/main/assets/pic/6/000019.png b/example/src/main/assets/pic/6/000019.png new file mode 100644 index 0000000..f65e3da Binary files /dev/null and b/example/src/main/assets/pic/6/000019.png differ diff --git a/example/src/main/assets/pic/6/000020.png b/example/src/main/assets/pic/6/000020.png new file mode 100644 index 0000000..17f7e79 Binary files /dev/null and b/example/src/main/assets/pic/6/000020.png differ diff --git a/example/src/main/assets/pic/6/000021.png b/example/src/main/assets/pic/6/000021.png new file mode 100644 index 0000000..2db444e Binary files /dev/null and b/example/src/main/assets/pic/6/000021.png differ diff --git a/example/src/main/assets/pic/6/000022.png b/example/src/main/assets/pic/6/000022.png new file mode 100644 index 0000000..fc0c094 Binary files /dev/null and b/example/src/main/assets/pic/6/000022.png differ diff --git a/example/src/main/assets/pic/6/000023.png b/example/src/main/assets/pic/6/000023.png new file mode 100644 index 0000000..c751b4a Binary files /dev/null and b/example/src/main/assets/pic/6/000023.png differ diff --git a/example/src/main/assets/pic/6/000024.png b/example/src/main/assets/pic/6/000024.png new file mode 100644 index 0000000..07d16db Binary files /dev/null and b/example/src/main/assets/pic/6/000024.png differ diff --git a/example/src/main/assets/pic/6/000025.png b/example/src/main/assets/pic/6/000025.png new file mode 100644 index 0000000..04f5ca2 Binary files /dev/null and b/example/src/main/assets/pic/6/000025.png differ diff --git a/example/src/main/assets/pic/6/000026.png b/example/src/main/assets/pic/6/000026.png new file mode 100644 index 0000000..a24cc44 Binary files /dev/null and b/example/src/main/assets/pic/6/000026.png differ diff --git a/example/src/main/assets/pic/6/000027.png b/example/src/main/assets/pic/6/000027.png new file mode 100644 index 0000000..97b0130 Binary files /dev/null and b/example/src/main/assets/pic/6/000027.png differ diff --git a/example/src/main/assets/pic/6/000028.png b/example/src/main/assets/pic/6/000028.png new file mode 100644 index 0000000..89e3185 Binary files /dev/null and b/example/src/main/assets/pic/6/000028.png differ diff --git a/example/src/main/assets/pic/6/000029.png b/example/src/main/assets/pic/6/000029.png new file mode 100644 index 0000000..de6fdd4 Binary files /dev/null and b/example/src/main/assets/pic/6/000029.png differ diff --git a/example/src/main/assets/pic/6/000030.png b/example/src/main/assets/pic/6/000030.png new file mode 100644 index 0000000..9e0bf25 Binary files /dev/null and b/example/src/main/assets/pic/6/000030.png differ diff --git a/example/src/main/assets/pic/6/000031.png b/example/src/main/assets/pic/6/000031.png new file mode 100644 index 0000000..2db444e Binary files /dev/null and b/example/src/main/assets/pic/6/000031.png differ diff --git a/example/src/main/assets/pic/6/6.png b/example/src/main/assets/pic/6/6.png deleted file mode 100644 index bff8bff..0000000 Binary files a/example/src/main/assets/pic/6/6.png and /dev/null differ diff --git a/example/src/main/assets/pic/62.png b/example/src/main/assets/pic/62.png deleted file mode 100644 index ad3fce6..0000000 Binary files a/example/src/main/assets/pic/62.png and /dev/null differ diff --git a/example/src/main/assets/pic/62/000000.png b/example/src/main/assets/pic/62/000000.png new file mode 100644 index 0000000..a07ebec Binary files /dev/null and b/example/src/main/assets/pic/62/000000.png differ diff --git a/example/src/main/assets/pic/62/000001.png b/example/src/main/assets/pic/62/000001.png new file mode 100644 index 0000000..56f81d1 Binary files /dev/null and b/example/src/main/assets/pic/62/000001.png differ diff --git a/example/src/main/assets/pic/62/000002.png b/example/src/main/assets/pic/62/000002.png new file mode 100644 index 0000000..42e1e46 Binary files /dev/null and b/example/src/main/assets/pic/62/000002.png differ diff --git a/example/src/main/assets/pic/62/000003.png b/example/src/main/assets/pic/62/000003.png new file mode 100644 index 0000000..1c1346e Binary files /dev/null and b/example/src/main/assets/pic/62/000003.png differ diff --git a/example/src/main/assets/pic/62/000004.png b/example/src/main/assets/pic/62/000004.png new file mode 100644 index 0000000..52186f6 Binary files /dev/null and b/example/src/main/assets/pic/62/000004.png differ diff --git a/example/src/main/assets/pic/62/000005.png b/example/src/main/assets/pic/62/000005.png new file mode 100644 index 0000000..cd80330 Binary files /dev/null and b/example/src/main/assets/pic/62/000005.png differ diff --git a/example/src/main/assets/pic/62/000006.png b/example/src/main/assets/pic/62/000006.png new file mode 100644 index 0000000..c829531 Binary files /dev/null and b/example/src/main/assets/pic/62/000006.png differ diff --git a/example/src/main/assets/pic/62/000007.png b/example/src/main/assets/pic/62/000007.png new file mode 100644 index 0000000..4f6b741 Binary files /dev/null and b/example/src/main/assets/pic/62/000007.png differ diff --git a/example/src/main/assets/pic/62/000008.png b/example/src/main/assets/pic/62/000008.png new file mode 100644 index 0000000..e3fcb86 Binary files /dev/null and b/example/src/main/assets/pic/62/000008.png differ diff --git a/example/src/main/assets/pic/62/000009.png b/example/src/main/assets/pic/62/000009.png new file mode 100644 index 0000000..53dcaaa Binary files /dev/null and b/example/src/main/assets/pic/62/000009.png differ diff --git a/example/src/main/assets/pic/62/000010.png b/example/src/main/assets/pic/62/000010.png new file mode 100644 index 0000000..2e66948 Binary files /dev/null and b/example/src/main/assets/pic/62/000010.png differ diff --git a/example/src/main/assets/pic/62/000011.png b/example/src/main/assets/pic/62/000011.png new file mode 100644 index 0000000..3bc4e9c Binary files /dev/null and b/example/src/main/assets/pic/62/000011.png differ diff --git a/example/src/main/assets/pic/62/000012.png b/example/src/main/assets/pic/62/000012.png new file mode 100644 index 0000000..fedda1a Binary files /dev/null and b/example/src/main/assets/pic/62/000012.png differ diff --git a/example/src/main/assets/pic/62/000013.png b/example/src/main/assets/pic/62/000013.png new file mode 100644 index 0000000..13c1352 Binary files /dev/null and b/example/src/main/assets/pic/62/000013.png differ diff --git a/example/src/main/assets/pic/62/000014.png b/example/src/main/assets/pic/62/000014.png new file mode 100644 index 0000000..e8ad088 Binary files /dev/null and b/example/src/main/assets/pic/62/000014.png differ diff --git a/example/src/main/assets/pic/62/000015.png b/example/src/main/assets/pic/62/000015.png new file mode 100644 index 0000000..b7f0b44 Binary files /dev/null and b/example/src/main/assets/pic/62/000015.png differ diff --git a/example/src/main/assets/pic/62/000016.png b/example/src/main/assets/pic/62/000016.png new file mode 100644 index 0000000..d51c050 Binary files /dev/null and b/example/src/main/assets/pic/62/000016.png differ diff --git a/example/src/main/assets/pic/62/000017.png b/example/src/main/assets/pic/62/000017.png new file mode 100644 index 0000000..7a5544b Binary files /dev/null and b/example/src/main/assets/pic/62/000017.png differ diff --git a/example/src/main/assets/pic/62/000018.png b/example/src/main/assets/pic/62/000018.png new file mode 100644 index 0000000..9488b20 Binary files /dev/null and b/example/src/main/assets/pic/62/000018.png differ diff --git a/example/src/main/assets/pic/62/000019.png b/example/src/main/assets/pic/62/000019.png new file mode 100644 index 0000000..3a120c9 Binary files /dev/null and b/example/src/main/assets/pic/62/000019.png differ diff --git a/example/src/main/assets/pic/62/000020.png b/example/src/main/assets/pic/62/000020.png new file mode 100644 index 0000000..3e6f06d Binary files /dev/null and b/example/src/main/assets/pic/62/000020.png differ diff --git a/example/src/main/assets/pic/62/000021.png b/example/src/main/assets/pic/62/000021.png new file mode 100644 index 0000000..08a7937 Binary files /dev/null and b/example/src/main/assets/pic/62/000021.png differ diff --git a/example/src/main/assets/pic/62/000022.png b/example/src/main/assets/pic/62/000022.png new file mode 100644 index 0000000..f82d13c Binary files /dev/null and b/example/src/main/assets/pic/62/000022.png differ diff --git a/example/src/main/assets/pic/62/000023.png b/example/src/main/assets/pic/62/000023.png new file mode 100644 index 0000000..087981b Binary files /dev/null and b/example/src/main/assets/pic/62/000023.png differ diff --git a/example/src/main/assets/pic/62/000024.png b/example/src/main/assets/pic/62/000024.png new file mode 100644 index 0000000..1e437fb Binary files /dev/null and b/example/src/main/assets/pic/62/000024.png differ diff --git a/example/src/main/assets/pic/62/000025.png b/example/src/main/assets/pic/62/000025.png new file mode 100644 index 0000000..de955fc Binary files /dev/null and b/example/src/main/assets/pic/62/000025.png differ diff --git a/example/src/main/assets/pic/62/000026.png b/example/src/main/assets/pic/62/000026.png new file mode 100644 index 0000000..6034b87 Binary files /dev/null and b/example/src/main/assets/pic/62/000026.png differ diff --git a/example/src/main/assets/pic/62/000027.png b/example/src/main/assets/pic/62/000027.png new file mode 100644 index 0000000..a8c8608 Binary files /dev/null and b/example/src/main/assets/pic/62/000027.png differ diff --git a/example/src/main/assets/pic/62/000028.png b/example/src/main/assets/pic/62/000028.png new file mode 100644 index 0000000..a22411a Binary files /dev/null and b/example/src/main/assets/pic/62/000028.png differ diff --git a/example/src/main/assets/pic/62/000029.png b/example/src/main/assets/pic/62/000029.png new file mode 100644 index 0000000..54847fa Binary files /dev/null and b/example/src/main/assets/pic/62/000029.png differ diff --git a/example/src/main/assets/pic/62/000030.png b/example/src/main/assets/pic/62/000030.png new file mode 100644 index 0000000..cc3da8f Binary files /dev/null and b/example/src/main/assets/pic/62/000030.png differ diff --git a/example/src/main/assets/pic/62/000031.png b/example/src/main/assets/pic/62/000031.png new file mode 100644 index 0000000..6697b3e Binary files /dev/null and b/example/src/main/assets/pic/62/000031.png differ diff --git a/example/src/main/assets/pic/62/62.png b/example/src/main/assets/pic/62/62.png deleted file mode 100644 index ad3fce6..0000000 Binary files a/example/src/main/assets/pic/62/62.png and /dev/null differ diff --git a/example/src/main/assets/pic/62ex.png b/example/src/main/assets/pic/62ex.png new file mode 100644 index 0000000..efa1124 Binary files /dev/null and b/example/src/main/assets/pic/62ex.png differ diff --git a/example/src/main/assets/pic/65.png b/example/src/main/assets/pic/65.png deleted file mode 100644 index bb1015b..0000000 Binary files a/example/src/main/assets/pic/65.png and /dev/null differ diff --git a/example/src/main/assets/pic/65/000000.png b/example/src/main/assets/pic/65/000000.png new file mode 100644 index 0000000..9374b02 Binary files /dev/null and b/example/src/main/assets/pic/65/000000.png differ diff --git a/example/src/main/assets/pic/65/000001.png b/example/src/main/assets/pic/65/000001.png new file mode 100644 index 0000000..dd5b7a9 Binary files /dev/null and b/example/src/main/assets/pic/65/000001.png differ diff --git a/example/src/main/assets/pic/65/000002.png b/example/src/main/assets/pic/65/000002.png new file mode 100644 index 0000000..e64a19c Binary files /dev/null and b/example/src/main/assets/pic/65/000002.png differ diff --git a/example/src/main/assets/pic/65/000003.png b/example/src/main/assets/pic/65/000003.png new file mode 100644 index 0000000..6f22ffd Binary files /dev/null and b/example/src/main/assets/pic/65/000003.png differ diff --git a/example/src/main/assets/pic/65/000004.png b/example/src/main/assets/pic/65/000004.png new file mode 100644 index 0000000..2216fe1 Binary files /dev/null and b/example/src/main/assets/pic/65/000004.png differ diff --git a/example/src/main/assets/pic/65/000005.png b/example/src/main/assets/pic/65/000005.png new file mode 100644 index 0000000..4383f38 Binary files /dev/null and b/example/src/main/assets/pic/65/000005.png differ diff --git a/example/src/main/assets/pic/65/000006.png b/example/src/main/assets/pic/65/000006.png new file mode 100644 index 0000000..85c3aa0 Binary files /dev/null and b/example/src/main/assets/pic/65/000006.png differ diff --git a/example/src/main/assets/pic/65/000007.png b/example/src/main/assets/pic/65/000007.png new file mode 100644 index 0000000..e292b9e Binary files /dev/null and b/example/src/main/assets/pic/65/000007.png differ diff --git a/example/src/main/assets/pic/65/000008.png b/example/src/main/assets/pic/65/000008.png new file mode 100644 index 0000000..ca0f9f5 Binary files /dev/null and b/example/src/main/assets/pic/65/000008.png differ diff --git a/example/src/main/assets/pic/65/000009.png b/example/src/main/assets/pic/65/000009.png new file mode 100644 index 0000000..86c7676 Binary files /dev/null and b/example/src/main/assets/pic/65/000009.png differ diff --git a/example/src/main/assets/pic/65/000010.png b/example/src/main/assets/pic/65/000010.png new file mode 100644 index 0000000..5c1ccf4 Binary files /dev/null and b/example/src/main/assets/pic/65/000010.png differ diff --git a/example/src/main/assets/pic/65/000011.png b/example/src/main/assets/pic/65/000011.png new file mode 100644 index 0000000..14121be Binary files /dev/null and b/example/src/main/assets/pic/65/000011.png differ diff --git a/example/src/main/assets/pic/65/000012.png b/example/src/main/assets/pic/65/000012.png new file mode 100644 index 0000000..2c25e6a Binary files /dev/null and b/example/src/main/assets/pic/65/000012.png differ diff --git a/example/src/main/assets/pic/65/000013.png b/example/src/main/assets/pic/65/000013.png new file mode 100644 index 0000000..8b99ee0 Binary files /dev/null and b/example/src/main/assets/pic/65/000013.png differ diff --git a/example/src/main/assets/pic/65/000014.png b/example/src/main/assets/pic/65/000014.png new file mode 100644 index 0000000..0a0aab6 Binary files /dev/null and b/example/src/main/assets/pic/65/000014.png differ diff --git a/example/src/main/assets/pic/65/000015.png b/example/src/main/assets/pic/65/000015.png new file mode 100644 index 0000000..5db2bb8 Binary files /dev/null and b/example/src/main/assets/pic/65/000015.png differ diff --git a/example/src/main/assets/pic/65/000016.png b/example/src/main/assets/pic/65/000016.png new file mode 100644 index 0000000..6ae411a Binary files /dev/null and b/example/src/main/assets/pic/65/000016.png differ diff --git a/example/src/main/assets/pic/65/000017.png b/example/src/main/assets/pic/65/000017.png new file mode 100644 index 0000000..8226bd3 Binary files /dev/null and b/example/src/main/assets/pic/65/000017.png differ diff --git a/example/src/main/assets/pic/65/000018.png b/example/src/main/assets/pic/65/000018.png new file mode 100644 index 0000000..605d075 Binary files /dev/null and b/example/src/main/assets/pic/65/000018.png differ diff --git a/example/src/main/assets/pic/65/000019.png b/example/src/main/assets/pic/65/000019.png new file mode 100644 index 0000000..44c92ac Binary files /dev/null and b/example/src/main/assets/pic/65/000019.png differ diff --git a/example/src/main/assets/pic/65/000020.png b/example/src/main/assets/pic/65/000020.png new file mode 100644 index 0000000..fdccfba Binary files /dev/null and b/example/src/main/assets/pic/65/000020.png differ diff --git a/example/src/main/assets/pic/65/000021.png b/example/src/main/assets/pic/65/000021.png new file mode 100644 index 0000000..13d52a5 Binary files /dev/null and b/example/src/main/assets/pic/65/000021.png differ diff --git a/example/src/main/assets/pic/65/000022.png b/example/src/main/assets/pic/65/000022.png new file mode 100644 index 0000000..c310eea Binary files /dev/null and b/example/src/main/assets/pic/65/000022.png differ diff --git a/example/src/main/assets/pic/65/000023.png b/example/src/main/assets/pic/65/000023.png new file mode 100644 index 0000000..d0dff1b Binary files /dev/null and b/example/src/main/assets/pic/65/000023.png differ diff --git a/example/src/main/assets/pic/65/000024.png b/example/src/main/assets/pic/65/000024.png new file mode 100644 index 0000000..cb1687b Binary files /dev/null and b/example/src/main/assets/pic/65/000024.png differ diff --git a/example/src/main/assets/pic/65/000025.png b/example/src/main/assets/pic/65/000025.png new file mode 100644 index 0000000..84da3a6 Binary files /dev/null and b/example/src/main/assets/pic/65/000025.png differ diff --git a/example/src/main/assets/pic/65/000026.png b/example/src/main/assets/pic/65/000026.png new file mode 100644 index 0000000..b2121f9 Binary files /dev/null and b/example/src/main/assets/pic/65/000026.png differ diff --git a/example/src/main/assets/pic/65/000027.png b/example/src/main/assets/pic/65/000027.png new file mode 100644 index 0000000..80d8060 Binary files /dev/null and b/example/src/main/assets/pic/65/000027.png differ diff --git a/example/src/main/assets/pic/65/000028.png b/example/src/main/assets/pic/65/000028.png new file mode 100644 index 0000000..381fe82 Binary files /dev/null and b/example/src/main/assets/pic/65/000028.png differ diff --git a/example/src/main/assets/pic/65/000029.png b/example/src/main/assets/pic/65/000029.png new file mode 100644 index 0000000..cd20770 Binary files /dev/null and b/example/src/main/assets/pic/65/000029.png differ diff --git a/example/src/main/assets/pic/65/000030.png b/example/src/main/assets/pic/65/000030.png new file mode 100644 index 0000000..bd9116b Binary files /dev/null and b/example/src/main/assets/pic/65/000030.png differ diff --git a/example/src/main/assets/pic/65/000031.png b/example/src/main/assets/pic/65/000031.png new file mode 100644 index 0000000..5db2bb8 Binary files /dev/null and b/example/src/main/assets/pic/65/000031.png differ diff --git a/example/src/main/assets/pic/65/65.png b/example/src/main/assets/pic/65/65.png deleted file mode 100644 index bb1015b..0000000 Binary files a/example/src/main/assets/pic/65/65.png and /dev/null differ diff --git a/example/src/main/assets/pic/65ex.png b/example/src/main/assets/pic/65ex.png new file mode 100644 index 0000000..7ac1f6c Binary files /dev/null and b/example/src/main/assets/pic/65ex.png differ diff --git a/example/src/main/assets/pic/68.png b/example/src/main/assets/pic/68.png deleted file mode 100644 index 17ec183..0000000 Binary files a/example/src/main/assets/pic/68.png and /dev/null differ diff --git a/example/src/main/assets/pic/68/000000.png b/example/src/main/assets/pic/68/000000.png new file mode 100644 index 0000000..34c7fc4 Binary files /dev/null and b/example/src/main/assets/pic/68/000000.png differ diff --git a/example/src/main/assets/pic/68/000001.png b/example/src/main/assets/pic/68/000001.png new file mode 100644 index 0000000..8355dff Binary files /dev/null and b/example/src/main/assets/pic/68/000001.png differ diff --git a/example/src/main/assets/pic/68/000002.png b/example/src/main/assets/pic/68/000002.png new file mode 100644 index 0000000..7c217e3 Binary files /dev/null and b/example/src/main/assets/pic/68/000002.png differ diff --git a/example/src/main/assets/pic/68/000003.png b/example/src/main/assets/pic/68/000003.png new file mode 100644 index 0000000..80616ab Binary files /dev/null and b/example/src/main/assets/pic/68/000003.png differ diff --git a/example/src/main/assets/pic/68/000004.png b/example/src/main/assets/pic/68/000004.png new file mode 100644 index 0000000..a76e15e Binary files /dev/null and b/example/src/main/assets/pic/68/000004.png differ diff --git a/example/src/main/assets/pic/68/000005.png b/example/src/main/assets/pic/68/000005.png new file mode 100644 index 0000000..fe3ebe4 Binary files /dev/null and b/example/src/main/assets/pic/68/000005.png differ diff --git a/example/src/main/assets/pic/68/000006.png b/example/src/main/assets/pic/68/000006.png new file mode 100644 index 0000000..e65438d Binary files /dev/null and b/example/src/main/assets/pic/68/000006.png differ diff --git a/example/src/main/assets/pic/68/000007.png b/example/src/main/assets/pic/68/000007.png new file mode 100644 index 0000000..97a356a Binary files /dev/null and b/example/src/main/assets/pic/68/000007.png differ diff --git a/example/src/main/assets/pic/68/000008.png b/example/src/main/assets/pic/68/000008.png new file mode 100644 index 0000000..117b3ad Binary files /dev/null and b/example/src/main/assets/pic/68/000008.png differ diff --git a/example/src/main/assets/pic/68/000009.png b/example/src/main/assets/pic/68/000009.png new file mode 100644 index 0000000..72a033d Binary files /dev/null and b/example/src/main/assets/pic/68/000009.png differ diff --git a/example/src/main/assets/pic/68/000010.png b/example/src/main/assets/pic/68/000010.png new file mode 100644 index 0000000..72805f9 Binary files /dev/null and b/example/src/main/assets/pic/68/000010.png differ diff --git a/example/src/main/assets/pic/68/000011.png b/example/src/main/assets/pic/68/000011.png new file mode 100644 index 0000000..ed4c8d8 Binary files /dev/null and b/example/src/main/assets/pic/68/000011.png differ diff --git a/example/src/main/assets/pic/68/000012.png b/example/src/main/assets/pic/68/000012.png new file mode 100644 index 0000000..e969a7c Binary files /dev/null and b/example/src/main/assets/pic/68/000012.png differ diff --git a/example/src/main/assets/pic/68/000013.png b/example/src/main/assets/pic/68/000013.png new file mode 100644 index 0000000..815d819 Binary files /dev/null and b/example/src/main/assets/pic/68/000013.png differ diff --git a/example/src/main/assets/pic/68/000014.png b/example/src/main/assets/pic/68/000014.png new file mode 100644 index 0000000..1e38b5f Binary files /dev/null and b/example/src/main/assets/pic/68/000014.png differ diff --git a/example/src/main/assets/pic/68/000015.png b/example/src/main/assets/pic/68/000015.png new file mode 100644 index 0000000..c69140f Binary files /dev/null and b/example/src/main/assets/pic/68/000015.png differ diff --git a/example/src/main/assets/pic/68/000016.png b/example/src/main/assets/pic/68/000016.png new file mode 100644 index 0000000..f3ecdee Binary files /dev/null and b/example/src/main/assets/pic/68/000016.png differ diff --git a/example/src/main/assets/pic/68/000017.png b/example/src/main/assets/pic/68/000017.png new file mode 100644 index 0000000..96f6a8f Binary files /dev/null and b/example/src/main/assets/pic/68/000017.png differ diff --git a/example/src/main/assets/pic/68/000018.png b/example/src/main/assets/pic/68/000018.png new file mode 100644 index 0000000..dc654d3 Binary files /dev/null and b/example/src/main/assets/pic/68/000018.png differ diff --git a/example/src/main/assets/pic/68/000019.png b/example/src/main/assets/pic/68/000019.png new file mode 100644 index 0000000..5f22d27 Binary files /dev/null and b/example/src/main/assets/pic/68/000019.png differ diff --git a/example/src/main/assets/pic/68/000020.png b/example/src/main/assets/pic/68/000020.png new file mode 100644 index 0000000..8e521b5 Binary files /dev/null and b/example/src/main/assets/pic/68/000020.png differ diff --git a/example/src/main/assets/pic/68/000021.png b/example/src/main/assets/pic/68/000021.png new file mode 100644 index 0000000..db5fe0c Binary files /dev/null and b/example/src/main/assets/pic/68/000021.png differ diff --git a/example/src/main/assets/pic/68/000022.png b/example/src/main/assets/pic/68/000022.png new file mode 100644 index 0000000..2bd037e Binary files /dev/null and b/example/src/main/assets/pic/68/000022.png differ diff --git a/example/src/main/assets/pic/68/000023.png b/example/src/main/assets/pic/68/000023.png new file mode 100644 index 0000000..9aa6472 Binary files /dev/null and b/example/src/main/assets/pic/68/000023.png differ diff --git a/example/src/main/assets/pic/68/000024.png b/example/src/main/assets/pic/68/000024.png new file mode 100644 index 0000000..5dc4990 Binary files /dev/null and b/example/src/main/assets/pic/68/000024.png differ diff --git a/example/src/main/assets/pic/68/000025.png b/example/src/main/assets/pic/68/000025.png new file mode 100644 index 0000000..eae7431 Binary files /dev/null and b/example/src/main/assets/pic/68/000025.png differ diff --git a/example/src/main/assets/pic/68/000026.png b/example/src/main/assets/pic/68/000026.png new file mode 100644 index 0000000..4df5484 Binary files /dev/null and b/example/src/main/assets/pic/68/000026.png differ diff --git a/example/src/main/assets/pic/68/000027.png b/example/src/main/assets/pic/68/000027.png new file mode 100644 index 0000000..6c79e97 Binary files /dev/null and b/example/src/main/assets/pic/68/000027.png differ diff --git a/example/src/main/assets/pic/68/000028.png b/example/src/main/assets/pic/68/000028.png new file mode 100644 index 0000000..f9939fa Binary files /dev/null and b/example/src/main/assets/pic/68/000028.png differ diff --git a/example/src/main/assets/pic/68/000029.png b/example/src/main/assets/pic/68/000029.png new file mode 100644 index 0000000..e72ebb8 Binary files /dev/null and b/example/src/main/assets/pic/68/000029.png differ diff --git a/example/src/main/assets/pic/68/000030.png b/example/src/main/assets/pic/68/000030.png new file mode 100644 index 0000000..67c0dda Binary files /dev/null and b/example/src/main/assets/pic/68/000030.png differ diff --git a/example/src/main/assets/pic/68/000031.png b/example/src/main/assets/pic/68/000031.png new file mode 100644 index 0000000..dfe23b5 Binary files /dev/null and b/example/src/main/assets/pic/68/000031.png differ diff --git a/example/src/main/assets/pic/68/68.png b/example/src/main/assets/pic/68/68.png deleted file mode 100644 index 17ec183..0000000 Binary files a/example/src/main/assets/pic/68/68.png and /dev/null differ diff --git a/example/src/main/assets/pic/68ex.png b/example/src/main/assets/pic/68ex.png new file mode 100644 index 0000000..3d53730 Binary files /dev/null and b/example/src/main/assets/pic/68ex.png differ diff --git a/example/src/main/assets/pic/6ex.png b/example/src/main/assets/pic/6ex.png new file mode 100644 index 0000000..a9ae812 Binary files /dev/null and b/example/src/main/assets/pic/6ex.png differ diff --git a/example/src/main/assets/pic/7.png b/example/src/main/assets/pic/7.png deleted file mode 100644 index 7c34052..0000000 Binary files a/example/src/main/assets/pic/7.png and /dev/null differ diff --git a/example/src/main/assets/pic/7/000000.png b/example/src/main/assets/pic/7/000000.png new file mode 100644 index 0000000..3f5f4f9 Binary files /dev/null and b/example/src/main/assets/pic/7/000000.png differ diff --git a/example/src/main/assets/pic/7/000001.png b/example/src/main/assets/pic/7/000001.png new file mode 100644 index 0000000..cdbdf8d Binary files /dev/null and b/example/src/main/assets/pic/7/000001.png differ diff --git a/example/src/main/assets/pic/7/000002.png b/example/src/main/assets/pic/7/000002.png new file mode 100644 index 0000000..e32cea1 Binary files /dev/null and b/example/src/main/assets/pic/7/000002.png differ diff --git a/example/src/main/assets/pic/7/000003.png b/example/src/main/assets/pic/7/000003.png new file mode 100644 index 0000000..44bdc5a Binary files /dev/null and b/example/src/main/assets/pic/7/000003.png differ diff --git a/example/src/main/assets/pic/7/000004.png b/example/src/main/assets/pic/7/000004.png new file mode 100644 index 0000000..299144d Binary files /dev/null and b/example/src/main/assets/pic/7/000004.png differ diff --git a/example/src/main/assets/pic/7/000005.png b/example/src/main/assets/pic/7/000005.png new file mode 100644 index 0000000..925947d Binary files /dev/null and b/example/src/main/assets/pic/7/000005.png differ diff --git a/example/src/main/assets/pic/7/000006.png b/example/src/main/assets/pic/7/000006.png new file mode 100644 index 0000000..0206539 Binary files /dev/null and b/example/src/main/assets/pic/7/000006.png differ diff --git a/example/src/main/assets/pic/7/000007.png b/example/src/main/assets/pic/7/000007.png new file mode 100644 index 0000000..5ff29b9 Binary files /dev/null and b/example/src/main/assets/pic/7/000007.png differ diff --git a/example/src/main/assets/pic/7/000008.png b/example/src/main/assets/pic/7/000008.png new file mode 100644 index 0000000..9de5f00 Binary files /dev/null and b/example/src/main/assets/pic/7/000008.png differ diff --git a/example/src/main/assets/pic/7/000009.png b/example/src/main/assets/pic/7/000009.png new file mode 100644 index 0000000..616e1a9 Binary files /dev/null and b/example/src/main/assets/pic/7/000009.png differ diff --git a/example/src/main/assets/pic/7/000010.png b/example/src/main/assets/pic/7/000010.png new file mode 100644 index 0000000..838c033 Binary files /dev/null and b/example/src/main/assets/pic/7/000010.png differ diff --git a/example/src/main/assets/pic/7/000011.png b/example/src/main/assets/pic/7/000011.png new file mode 100644 index 0000000..d5e4a35 Binary files /dev/null and b/example/src/main/assets/pic/7/000011.png differ diff --git a/example/src/main/assets/pic/7/000012.png b/example/src/main/assets/pic/7/000012.png new file mode 100644 index 0000000..5960d85 Binary files /dev/null and b/example/src/main/assets/pic/7/000012.png differ diff --git a/example/src/main/assets/pic/7/000013.png b/example/src/main/assets/pic/7/000013.png new file mode 100644 index 0000000..05f7f27 Binary files /dev/null and b/example/src/main/assets/pic/7/000013.png differ diff --git a/example/src/main/assets/pic/7/000014.png b/example/src/main/assets/pic/7/000014.png new file mode 100644 index 0000000..4d73872 Binary files /dev/null and b/example/src/main/assets/pic/7/000014.png differ diff --git a/example/src/main/assets/pic/7/000015.png b/example/src/main/assets/pic/7/000015.png new file mode 100644 index 0000000..980d610 Binary files /dev/null and b/example/src/main/assets/pic/7/000015.png differ diff --git a/example/src/main/assets/pic/7/000016.png b/example/src/main/assets/pic/7/000016.png new file mode 100644 index 0000000..5ee30cf Binary files /dev/null and b/example/src/main/assets/pic/7/000016.png differ diff --git a/example/src/main/assets/pic/7/000017.png b/example/src/main/assets/pic/7/000017.png new file mode 100644 index 0000000..505179f Binary files /dev/null and b/example/src/main/assets/pic/7/000017.png differ diff --git a/example/src/main/assets/pic/7/000018.png b/example/src/main/assets/pic/7/000018.png new file mode 100644 index 0000000..f8915bd Binary files /dev/null and b/example/src/main/assets/pic/7/000018.png differ diff --git a/example/src/main/assets/pic/7/000019.png b/example/src/main/assets/pic/7/000019.png new file mode 100644 index 0000000..51d88c6 Binary files /dev/null and b/example/src/main/assets/pic/7/000019.png differ diff --git a/example/src/main/assets/pic/7/000020.png b/example/src/main/assets/pic/7/000020.png new file mode 100644 index 0000000..eebbc71 Binary files /dev/null and b/example/src/main/assets/pic/7/000020.png differ diff --git a/example/src/main/assets/pic/7/000021.png b/example/src/main/assets/pic/7/000021.png new file mode 100644 index 0000000..f5fb813 Binary files /dev/null and b/example/src/main/assets/pic/7/000021.png differ diff --git a/example/src/main/assets/pic/7/000022.png b/example/src/main/assets/pic/7/000022.png new file mode 100644 index 0000000..ed435cb Binary files /dev/null and b/example/src/main/assets/pic/7/000022.png differ diff --git a/example/src/main/assets/pic/7/000023.png b/example/src/main/assets/pic/7/000023.png new file mode 100644 index 0000000..d1aec8d Binary files /dev/null and b/example/src/main/assets/pic/7/000023.png differ diff --git a/example/src/main/assets/pic/7/000024.png b/example/src/main/assets/pic/7/000024.png new file mode 100644 index 0000000..06d8b99 Binary files /dev/null and b/example/src/main/assets/pic/7/000024.png differ diff --git a/example/src/main/assets/pic/7/000025.png b/example/src/main/assets/pic/7/000025.png new file mode 100644 index 0000000..286e969 Binary files /dev/null and b/example/src/main/assets/pic/7/000025.png differ diff --git a/example/src/main/assets/pic/7/000026.png b/example/src/main/assets/pic/7/000026.png new file mode 100644 index 0000000..3367939 Binary files /dev/null and b/example/src/main/assets/pic/7/000026.png differ diff --git a/example/src/main/assets/pic/7/000027.png b/example/src/main/assets/pic/7/000027.png new file mode 100644 index 0000000..ead3d79 Binary files /dev/null and b/example/src/main/assets/pic/7/000027.png differ diff --git a/example/src/main/assets/pic/7/000028.png b/example/src/main/assets/pic/7/000028.png new file mode 100644 index 0000000..f42c808 Binary files /dev/null and b/example/src/main/assets/pic/7/000028.png differ diff --git a/example/src/main/assets/pic/7/000029.png b/example/src/main/assets/pic/7/000029.png new file mode 100644 index 0000000..ddbb5ad Binary files /dev/null and b/example/src/main/assets/pic/7/000029.png differ diff --git a/example/src/main/assets/pic/7/000030.png b/example/src/main/assets/pic/7/000030.png new file mode 100644 index 0000000..4489b61 Binary files /dev/null and b/example/src/main/assets/pic/7/000030.png differ diff --git a/example/src/main/assets/pic/7/000031.png b/example/src/main/assets/pic/7/000031.png new file mode 100644 index 0000000..980d610 Binary files /dev/null and b/example/src/main/assets/pic/7/000031.png differ diff --git a/example/src/main/assets/pic/7/7.png b/example/src/main/assets/pic/7/7.png deleted file mode 100644 index 7c34052..0000000 Binary files a/example/src/main/assets/pic/7/7.png and /dev/null differ diff --git a/example/src/main/assets/pic/71.png b/example/src/main/assets/pic/71.png deleted file mode 100644 index 93e3156..0000000 Binary files a/example/src/main/assets/pic/71.png and /dev/null differ diff --git a/example/src/main/assets/pic/71/000000.png b/example/src/main/assets/pic/71/000000.png new file mode 100644 index 0000000..18c1a4b Binary files /dev/null and b/example/src/main/assets/pic/71/000000.png differ diff --git a/example/src/main/assets/pic/71/000001.png b/example/src/main/assets/pic/71/000001.png new file mode 100644 index 0000000..a35f836 Binary files /dev/null and b/example/src/main/assets/pic/71/000001.png differ diff --git a/example/src/main/assets/pic/71/000002.png b/example/src/main/assets/pic/71/000002.png new file mode 100644 index 0000000..655853b Binary files /dev/null and b/example/src/main/assets/pic/71/000002.png differ diff --git a/example/src/main/assets/pic/71/000003.png b/example/src/main/assets/pic/71/000003.png new file mode 100644 index 0000000..a295399 Binary files /dev/null and b/example/src/main/assets/pic/71/000003.png differ diff --git a/example/src/main/assets/pic/71/000004.png b/example/src/main/assets/pic/71/000004.png new file mode 100644 index 0000000..0ff8294 Binary files /dev/null and b/example/src/main/assets/pic/71/000004.png differ diff --git a/example/src/main/assets/pic/71/000005.png b/example/src/main/assets/pic/71/000005.png new file mode 100644 index 0000000..e36a3fa Binary files /dev/null and b/example/src/main/assets/pic/71/000005.png differ diff --git a/example/src/main/assets/pic/71/000006.png b/example/src/main/assets/pic/71/000006.png new file mode 100644 index 0000000..8f7f43a Binary files /dev/null and b/example/src/main/assets/pic/71/000006.png differ diff --git a/example/src/main/assets/pic/71/000007.png b/example/src/main/assets/pic/71/000007.png new file mode 100644 index 0000000..21ac857 Binary files /dev/null and b/example/src/main/assets/pic/71/000007.png differ diff --git a/example/src/main/assets/pic/71/000008.png b/example/src/main/assets/pic/71/000008.png new file mode 100644 index 0000000..834881b Binary files /dev/null and b/example/src/main/assets/pic/71/000008.png differ diff --git a/example/src/main/assets/pic/71/000009.png b/example/src/main/assets/pic/71/000009.png new file mode 100644 index 0000000..b99ed96 Binary files /dev/null and b/example/src/main/assets/pic/71/000009.png differ diff --git a/example/src/main/assets/pic/71/000010.png b/example/src/main/assets/pic/71/000010.png new file mode 100644 index 0000000..e49b616 Binary files /dev/null and b/example/src/main/assets/pic/71/000010.png differ diff --git a/example/src/main/assets/pic/71/000011.png b/example/src/main/assets/pic/71/000011.png new file mode 100644 index 0000000..3adf46d Binary files /dev/null and b/example/src/main/assets/pic/71/000011.png differ diff --git a/example/src/main/assets/pic/71/000012.png b/example/src/main/assets/pic/71/000012.png new file mode 100644 index 0000000..cf4a1c6 Binary files /dev/null and b/example/src/main/assets/pic/71/000012.png differ diff --git a/example/src/main/assets/pic/71/000013.png b/example/src/main/assets/pic/71/000013.png new file mode 100644 index 0000000..0308ab1 Binary files /dev/null and b/example/src/main/assets/pic/71/000013.png differ diff --git a/example/src/main/assets/pic/71/000014.png b/example/src/main/assets/pic/71/000014.png new file mode 100644 index 0000000..30ea79d Binary files /dev/null and b/example/src/main/assets/pic/71/000014.png differ diff --git a/example/src/main/assets/pic/71/000015.png b/example/src/main/assets/pic/71/000015.png new file mode 100644 index 0000000..f4849a1 Binary files /dev/null and b/example/src/main/assets/pic/71/000015.png differ diff --git a/example/src/main/assets/pic/71/000016.png b/example/src/main/assets/pic/71/000016.png new file mode 100644 index 0000000..6429aa6 Binary files /dev/null and b/example/src/main/assets/pic/71/000016.png differ diff --git a/example/src/main/assets/pic/71/000017.png b/example/src/main/assets/pic/71/000017.png new file mode 100644 index 0000000..c72021f Binary files /dev/null and b/example/src/main/assets/pic/71/000017.png differ diff --git a/example/src/main/assets/pic/71/000018.png b/example/src/main/assets/pic/71/000018.png new file mode 100644 index 0000000..1b9c47d Binary files /dev/null and b/example/src/main/assets/pic/71/000018.png differ diff --git a/example/src/main/assets/pic/71/000019.png b/example/src/main/assets/pic/71/000019.png new file mode 100644 index 0000000..a7c3dcf Binary files /dev/null and b/example/src/main/assets/pic/71/000019.png differ diff --git a/example/src/main/assets/pic/71/000020.png b/example/src/main/assets/pic/71/000020.png new file mode 100644 index 0000000..870aadd Binary files /dev/null and b/example/src/main/assets/pic/71/000020.png differ diff --git a/example/src/main/assets/pic/71/000021.png b/example/src/main/assets/pic/71/000021.png new file mode 100644 index 0000000..95f9039 Binary files /dev/null and b/example/src/main/assets/pic/71/000021.png differ diff --git a/example/src/main/assets/pic/71/000022.png b/example/src/main/assets/pic/71/000022.png new file mode 100644 index 0000000..b57e94d Binary files /dev/null and b/example/src/main/assets/pic/71/000022.png differ diff --git a/example/src/main/assets/pic/71/000023.png b/example/src/main/assets/pic/71/000023.png new file mode 100644 index 0000000..033c8a0 Binary files /dev/null and b/example/src/main/assets/pic/71/000023.png differ diff --git a/example/src/main/assets/pic/71/000024.png b/example/src/main/assets/pic/71/000024.png new file mode 100644 index 0000000..946f790 Binary files /dev/null and b/example/src/main/assets/pic/71/000024.png differ diff --git a/example/src/main/assets/pic/71/000025.png b/example/src/main/assets/pic/71/000025.png new file mode 100644 index 0000000..f4163d0 Binary files /dev/null and b/example/src/main/assets/pic/71/000025.png differ diff --git a/example/src/main/assets/pic/71/000026.png b/example/src/main/assets/pic/71/000026.png new file mode 100644 index 0000000..208f987 Binary files /dev/null and b/example/src/main/assets/pic/71/000026.png differ diff --git a/example/src/main/assets/pic/71/000027.png b/example/src/main/assets/pic/71/000027.png new file mode 100644 index 0000000..212a8d2 Binary files /dev/null and b/example/src/main/assets/pic/71/000027.png differ diff --git a/example/src/main/assets/pic/71/000028.png b/example/src/main/assets/pic/71/000028.png new file mode 100644 index 0000000..8b2e6de Binary files /dev/null and b/example/src/main/assets/pic/71/000028.png differ diff --git a/example/src/main/assets/pic/71/000029.png b/example/src/main/assets/pic/71/000029.png new file mode 100644 index 0000000..75cb971 Binary files /dev/null and b/example/src/main/assets/pic/71/000029.png differ diff --git a/example/src/main/assets/pic/71/000030.png b/example/src/main/assets/pic/71/000030.png new file mode 100644 index 0000000..75f7ef0 Binary files /dev/null and b/example/src/main/assets/pic/71/000030.png differ diff --git a/example/src/main/assets/pic/71/000031.png b/example/src/main/assets/pic/71/000031.png new file mode 100644 index 0000000..40086c3 Binary files /dev/null and b/example/src/main/assets/pic/71/000031.png differ diff --git a/example/src/main/assets/pic/71/71.png b/example/src/main/assets/pic/71/71.png deleted file mode 100644 index 93e3156..0000000 Binary files a/example/src/main/assets/pic/71/71.png and /dev/null differ diff --git a/example/src/main/assets/pic/71ex.png b/example/src/main/assets/pic/71ex.png new file mode 100644 index 0000000..e845f2f Binary files /dev/null and b/example/src/main/assets/pic/71ex.png differ diff --git a/example/src/main/assets/pic/76.png b/example/src/main/assets/pic/76.png deleted file mode 100644 index 1431084..0000000 Binary files a/example/src/main/assets/pic/76.png and /dev/null differ diff --git a/example/src/main/assets/pic/76/76.png b/example/src/main/assets/pic/76/76.png index 1431084..4bd1506 100644 Binary files a/example/src/main/assets/pic/76/76.png and b/example/src/main/assets/pic/76/76.png differ diff --git a/example/src/main/assets/pic/76ex.png b/example/src/main/assets/pic/76ex.png new file mode 100644 index 0000000..81b0e58 Binary files /dev/null and b/example/src/main/assets/pic/76ex.png differ diff --git a/example/src/main/assets/pic/77.png b/example/src/main/assets/pic/77.png deleted file mode 100644 index 8a7a476..0000000 Binary files a/example/src/main/assets/pic/77.png and /dev/null differ diff --git a/example/src/main/assets/pic/77/77.png b/example/src/main/assets/pic/77/77.png index 8a7a476..d9a2276 100644 Binary files a/example/src/main/assets/pic/77/77.png and b/example/src/main/assets/pic/77/77.png differ diff --git a/example/src/main/assets/pic/77ex.png b/example/src/main/assets/pic/77ex.png new file mode 100644 index 0000000..2d3c7ab Binary files /dev/null and b/example/src/main/assets/pic/77ex.png differ diff --git a/example/src/main/assets/pic/78.png b/example/src/main/assets/pic/78.png deleted file mode 100644 index 834e1b4..0000000 Binary files a/example/src/main/assets/pic/78.png and /dev/null differ diff --git a/example/src/main/assets/pic/78/000000.png b/example/src/main/assets/pic/78/000000.png new file mode 100644 index 0000000..a77e931 Binary files /dev/null and b/example/src/main/assets/pic/78/000000.png differ diff --git a/example/src/main/assets/pic/78/000001.png b/example/src/main/assets/pic/78/000001.png new file mode 100644 index 0000000..4d82a6e Binary files /dev/null and b/example/src/main/assets/pic/78/000001.png differ diff --git a/example/src/main/assets/pic/78/000002.png b/example/src/main/assets/pic/78/000002.png new file mode 100644 index 0000000..01de382 Binary files /dev/null and b/example/src/main/assets/pic/78/000002.png differ diff --git a/example/src/main/assets/pic/78/000003.png b/example/src/main/assets/pic/78/000003.png new file mode 100644 index 0000000..4e3e520 Binary files /dev/null and b/example/src/main/assets/pic/78/000003.png differ diff --git a/example/src/main/assets/pic/78/000004.png b/example/src/main/assets/pic/78/000004.png new file mode 100644 index 0000000..b5587e8 Binary files /dev/null and b/example/src/main/assets/pic/78/000004.png differ diff --git a/example/src/main/assets/pic/78/000005.png b/example/src/main/assets/pic/78/000005.png new file mode 100644 index 0000000..5478267 Binary files /dev/null and b/example/src/main/assets/pic/78/000005.png differ diff --git a/example/src/main/assets/pic/78/000006.png b/example/src/main/assets/pic/78/000006.png new file mode 100644 index 0000000..8735aeb Binary files /dev/null and b/example/src/main/assets/pic/78/000006.png differ diff --git a/example/src/main/assets/pic/78/000007.png b/example/src/main/assets/pic/78/000007.png new file mode 100644 index 0000000..588313a Binary files /dev/null and b/example/src/main/assets/pic/78/000007.png differ diff --git a/example/src/main/assets/pic/78/000008.png b/example/src/main/assets/pic/78/000008.png new file mode 100644 index 0000000..e0f0330 Binary files /dev/null and b/example/src/main/assets/pic/78/000008.png differ diff --git a/example/src/main/assets/pic/78/000009.png b/example/src/main/assets/pic/78/000009.png new file mode 100644 index 0000000..b562a56 Binary files /dev/null and b/example/src/main/assets/pic/78/000009.png differ diff --git a/example/src/main/assets/pic/78/000010.png b/example/src/main/assets/pic/78/000010.png new file mode 100644 index 0000000..9860bea Binary files /dev/null and b/example/src/main/assets/pic/78/000010.png differ diff --git a/example/src/main/assets/pic/78/000011.png b/example/src/main/assets/pic/78/000011.png new file mode 100644 index 0000000..3ece334 Binary files /dev/null and b/example/src/main/assets/pic/78/000011.png differ diff --git a/example/src/main/assets/pic/78/000012.png b/example/src/main/assets/pic/78/000012.png new file mode 100644 index 0000000..f1c7e43 Binary files /dev/null and b/example/src/main/assets/pic/78/000012.png differ diff --git a/example/src/main/assets/pic/78/000013.png b/example/src/main/assets/pic/78/000013.png new file mode 100644 index 0000000..370934d Binary files /dev/null and b/example/src/main/assets/pic/78/000013.png differ diff --git a/example/src/main/assets/pic/78/000014.png b/example/src/main/assets/pic/78/000014.png new file mode 100644 index 0000000..1ddbdcc Binary files /dev/null and b/example/src/main/assets/pic/78/000014.png differ diff --git a/example/src/main/assets/pic/78/000015.png b/example/src/main/assets/pic/78/000015.png new file mode 100644 index 0000000..8a40de6 Binary files /dev/null and b/example/src/main/assets/pic/78/000015.png differ diff --git a/example/src/main/assets/pic/78/000016.png b/example/src/main/assets/pic/78/000016.png new file mode 100644 index 0000000..96c19fc Binary files /dev/null and b/example/src/main/assets/pic/78/000016.png differ diff --git a/example/src/main/assets/pic/78/000017.png b/example/src/main/assets/pic/78/000017.png new file mode 100644 index 0000000..54416c7 Binary files /dev/null and b/example/src/main/assets/pic/78/000017.png differ diff --git a/example/src/main/assets/pic/78/000018.png b/example/src/main/assets/pic/78/000018.png new file mode 100644 index 0000000..ae808db Binary files /dev/null and b/example/src/main/assets/pic/78/000018.png differ diff --git a/example/src/main/assets/pic/78/000019.png b/example/src/main/assets/pic/78/000019.png new file mode 100644 index 0000000..0b6eecf Binary files /dev/null and b/example/src/main/assets/pic/78/000019.png differ diff --git a/example/src/main/assets/pic/78/000020.png b/example/src/main/assets/pic/78/000020.png new file mode 100644 index 0000000..4f0995e Binary files /dev/null and b/example/src/main/assets/pic/78/000020.png differ diff --git a/example/src/main/assets/pic/78/000021.png b/example/src/main/assets/pic/78/000021.png new file mode 100644 index 0000000..48edbb5 Binary files /dev/null and b/example/src/main/assets/pic/78/000021.png differ diff --git a/example/src/main/assets/pic/78/000022.png b/example/src/main/assets/pic/78/000022.png new file mode 100644 index 0000000..6f24551 Binary files /dev/null and b/example/src/main/assets/pic/78/000022.png differ diff --git a/example/src/main/assets/pic/78/000023.png b/example/src/main/assets/pic/78/000023.png new file mode 100644 index 0000000..f188031 Binary files /dev/null and b/example/src/main/assets/pic/78/000023.png differ diff --git a/example/src/main/assets/pic/78/000024.png b/example/src/main/assets/pic/78/000024.png new file mode 100644 index 0000000..a591a19 Binary files /dev/null and b/example/src/main/assets/pic/78/000024.png differ diff --git a/example/src/main/assets/pic/78/000025.png b/example/src/main/assets/pic/78/000025.png new file mode 100644 index 0000000..afe5e25 Binary files /dev/null and b/example/src/main/assets/pic/78/000025.png differ diff --git a/example/src/main/assets/pic/78/000026.png b/example/src/main/assets/pic/78/000026.png new file mode 100644 index 0000000..02dc9f4 Binary files /dev/null and b/example/src/main/assets/pic/78/000026.png differ diff --git a/example/src/main/assets/pic/78/000027.png b/example/src/main/assets/pic/78/000027.png new file mode 100644 index 0000000..e934b53 Binary files /dev/null and b/example/src/main/assets/pic/78/000027.png differ diff --git a/example/src/main/assets/pic/78/000028.png b/example/src/main/assets/pic/78/000028.png new file mode 100644 index 0000000..8f4c388 Binary files /dev/null and b/example/src/main/assets/pic/78/000028.png differ diff --git a/example/src/main/assets/pic/78/000029.png b/example/src/main/assets/pic/78/000029.png new file mode 100644 index 0000000..59523cd Binary files /dev/null and b/example/src/main/assets/pic/78/000029.png differ diff --git a/example/src/main/assets/pic/78/000030.png b/example/src/main/assets/pic/78/000030.png new file mode 100644 index 0000000..ff8f328 Binary files /dev/null and b/example/src/main/assets/pic/78/000030.png differ diff --git a/example/src/main/assets/pic/78/000031.png b/example/src/main/assets/pic/78/000031.png new file mode 100644 index 0000000..8a40de6 Binary files /dev/null and b/example/src/main/assets/pic/78/000031.png differ diff --git a/example/src/main/assets/pic/78/78.png b/example/src/main/assets/pic/78/78.png deleted file mode 100644 index 834e1b4..0000000 Binary files a/example/src/main/assets/pic/78/78.png and /dev/null differ diff --git a/example/src/main/assets/pic/78ex.png b/example/src/main/assets/pic/78ex.png new file mode 100644 index 0000000..cbe7d4d Binary files /dev/null and b/example/src/main/assets/pic/78ex.png differ diff --git a/example/src/main/assets/pic/7ex.png b/example/src/main/assets/pic/7ex.png new file mode 100644 index 0000000..fae0d56 Binary files /dev/null and b/example/src/main/assets/pic/7ex.png differ diff --git a/example/src/main/assets/pic/80/80.png b/example/src/main/assets/pic/80/80.png new file mode 100644 index 0000000..e62c9c9 Binary files /dev/null and b/example/src/main/assets/pic/80/80.png differ diff --git a/example/src/main/assets/pic/80ex.png b/example/src/main/assets/pic/80ex.png new file mode 100644 index 0000000..b31b956 Binary files /dev/null and b/example/src/main/assets/pic/80ex.png differ diff --git a/example/src/main/assets/pic/81.png b/example/src/main/assets/pic/81.png deleted file mode 100644 index 7d57236..0000000 Binary files a/example/src/main/assets/pic/81.png and /dev/null differ diff --git a/example/src/main/assets/pic/81/000000.png b/example/src/main/assets/pic/81/000000.png new file mode 100644 index 0000000..66e0c2b Binary files /dev/null and b/example/src/main/assets/pic/81/000000.png differ diff --git a/example/src/main/assets/pic/81/000001.png b/example/src/main/assets/pic/81/000001.png new file mode 100644 index 0000000..eedb30e Binary files /dev/null and b/example/src/main/assets/pic/81/000001.png differ diff --git a/example/src/main/assets/pic/81/000002.png b/example/src/main/assets/pic/81/000002.png new file mode 100644 index 0000000..5ce08b9 Binary files /dev/null and b/example/src/main/assets/pic/81/000002.png differ diff --git a/example/src/main/assets/pic/81/000003.png b/example/src/main/assets/pic/81/000003.png new file mode 100644 index 0000000..d3c0421 Binary files /dev/null and b/example/src/main/assets/pic/81/000003.png differ diff --git a/example/src/main/assets/pic/81/000004.png b/example/src/main/assets/pic/81/000004.png new file mode 100644 index 0000000..061ce2a Binary files /dev/null and b/example/src/main/assets/pic/81/000004.png differ diff --git a/example/src/main/assets/pic/81/000005.png b/example/src/main/assets/pic/81/000005.png new file mode 100644 index 0000000..5805035 Binary files /dev/null and b/example/src/main/assets/pic/81/000005.png differ diff --git a/example/src/main/assets/pic/81/000006.png b/example/src/main/assets/pic/81/000006.png new file mode 100644 index 0000000..aeb3307 Binary files /dev/null and b/example/src/main/assets/pic/81/000006.png differ diff --git a/example/src/main/assets/pic/81/000007.png b/example/src/main/assets/pic/81/000007.png new file mode 100644 index 0000000..4f43f5c Binary files /dev/null and b/example/src/main/assets/pic/81/000007.png differ diff --git a/example/src/main/assets/pic/81/000008.png b/example/src/main/assets/pic/81/000008.png new file mode 100644 index 0000000..fd016d5 Binary files /dev/null and b/example/src/main/assets/pic/81/000008.png differ diff --git a/example/src/main/assets/pic/81/000009.png b/example/src/main/assets/pic/81/000009.png new file mode 100644 index 0000000..d9b0f72 Binary files /dev/null and b/example/src/main/assets/pic/81/000009.png differ diff --git a/example/src/main/assets/pic/81/000010.png b/example/src/main/assets/pic/81/000010.png new file mode 100644 index 0000000..23a8b03 Binary files /dev/null and b/example/src/main/assets/pic/81/000010.png differ diff --git a/example/src/main/assets/pic/81/000011.png b/example/src/main/assets/pic/81/000011.png new file mode 100644 index 0000000..7eb217a Binary files /dev/null and b/example/src/main/assets/pic/81/000011.png differ diff --git a/example/src/main/assets/pic/81/000012.png b/example/src/main/assets/pic/81/000012.png new file mode 100644 index 0000000..151e1a5 Binary files /dev/null and b/example/src/main/assets/pic/81/000012.png differ diff --git a/example/src/main/assets/pic/81/000013.png b/example/src/main/assets/pic/81/000013.png new file mode 100644 index 0000000..a58bec6 Binary files /dev/null and b/example/src/main/assets/pic/81/000013.png differ diff --git a/example/src/main/assets/pic/81/000014.png b/example/src/main/assets/pic/81/000014.png new file mode 100644 index 0000000..64ed63f Binary files /dev/null and b/example/src/main/assets/pic/81/000014.png differ diff --git a/example/src/main/assets/pic/81/000015.png b/example/src/main/assets/pic/81/000015.png new file mode 100644 index 0000000..82e4271 Binary files /dev/null and b/example/src/main/assets/pic/81/000015.png differ diff --git a/example/src/main/assets/pic/81/000016.png b/example/src/main/assets/pic/81/000016.png new file mode 100644 index 0000000..9928b87 Binary files /dev/null and b/example/src/main/assets/pic/81/000016.png differ diff --git a/example/src/main/assets/pic/81/000017.png b/example/src/main/assets/pic/81/000017.png new file mode 100644 index 0000000..58b5020 Binary files /dev/null and b/example/src/main/assets/pic/81/000017.png differ diff --git a/example/src/main/assets/pic/81/000018.png b/example/src/main/assets/pic/81/000018.png new file mode 100644 index 0000000..835bc02 Binary files /dev/null and b/example/src/main/assets/pic/81/000018.png differ diff --git a/example/src/main/assets/pic/81/000019.png b/example/src/main/assets/pic/81/000019.png new file mode 100644 index 0000000..33af263 Binary files /dev/null and b/example/src/main/assets/pic/81/000019.png differ diff --git a/example/src/main/assets/pic/81/000020.png b/example/src/main/assets/pic/81/000020.png new file mode 100644 index 0000000..b7cba3f Binary files /dev/null and b/example/src/main/assets/pic/81/000020.png differ diff --git a/example/src/main/assets/pic/81/000021.png b/example/src/main/assets/pic/81/000021.png new file mode 100644 index 0000000..65b6d0c Binary files /dev/null and b/example/src/main/assets/pic/81/000021.png differ diff --git a/example/src/main/assets/pic/81/000022.png b/example/src/main/assets/pic/81/000022.png new file mode 100644 index 0000000..f0f44ba Binary files /dev/null and b/example/src/main/assets/pic/81/000022.png differ diff --git a/example/src/main/assets/pic/81/000023.png b/example/src/main/assets/pic/81/000023.png new file mode 100644 index 0000000..ff09652 Binary files /dev/null and b/example/src/main/assets/pic/81/000023.png differ diff --git a/example/src/main/assets/pic/81/000024.png b/example/src/main/assets/pic/81/000024.png new file mode 100644 index 0000000..8dead55 Binary files /dev/null and b/example/src/main/assets/pic/81/000024.png differ diff --git a/example/src/main/assets/pic/81/000025.png b/example/src/main/assets/pic/81/000025.png new file mode 100644 index 0000000..712a673 Binary files /dev/null and b/example/src/main/assets/pic/81/000025.png differ diff --git a/example/src/main/assets/pic/81/000026.png b/example/src/main/assets/pic/81/000026.png new file mode 100644 index 0000000..6ada97d Binary files /dev/null and b/example/src/main/assets/pic/81/000026.png differ diff --git a/example/src/main/assets/pic/81/000027.png b/example/src/main/assets/pic/81/000027.png new file mode 100644 index 0000000..7377c5a Binary files /dev/null and b/example/src/main/assets/pic/81/000027.png differ diff --git a/example/src/main/assets/pic/81/81.png b/example/src/main/assets/pic/81/81.png deleted file mode 100644 index 7d57236..0000000 Binary files a/example/src/main/assets/pic/81/81.png and /dev/null differ diff --git a/example/src/main/assets/pic/81ex.png b/example/src/main/assets/pic/81ex.png new file mode 100644 index 0000000..86ec84a Binary files /dev/null and b/example/src/main/assets/pic/81ex.png differ diff --git a/example/src/main/assets/pic/82.png b/example/src/main/assets/pic/82.png deleted file mode 100644 index 061d518..0000000 Binary files a/example/src/main/assets/pic/82.png and /dev/null differ diff --git a/example/src/main/assets/pic/82/82.png b/example/src/main/assets/pic/82/82.png deleted file mode 100644 index 061d518..0000000 Binary files a/example/src/main/assets/pic/82/82.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000000.png b/example/src/main/assets/pic/action24/000000.png deleted file mode 100644 index b849e17..0000000 Binary files a/example/src/main/assets/pic/action24/000000.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000001.png b/example/src/main/assets/pic/action24/000001.png deleted file mode 100644 index b799c4b..0000000 Binary files a/example/src/main/assets/pic/action24/000001.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000002.png b/example/src/main/assets/pic/action24/000002.png deleted file mode 100644 index c0c05a4..0000000 Binary files a/example/src/main/assets/pic/action24/000002.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000003.png b/example/src/main/assets/pic/action24/000003.png deleted file mode 100644 index 0c75b66..0000000 Binary files a/example/src/main/assets/pic/action24/000003.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000004.png b/example/src/main/assets/pic/action24/000004.png deleted file mode 100644 index 5793257..0000000 Binary files a/example/src/main/assets/pic/action24/000004.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000005.png b/example/src/main/assets/pic/action24/000005.png deleted file mode 100644 index 547f3ce..0000000 Binary files a/example/src/main/assets/pic/action24/000005.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000006.png b/example/src/main/assets/pic/action24/000006.png deleted file mode 100644 index 66e2184..0000000 Binary files a/example/src/main/assets/pic/action24/000006.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000007.png b/example/src/main/assets/pic/action24/000007.png deleted file mode 100644 index 2e172bd..0000000 Binary files a/example/src/main/assets/pic/action24/000007.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000008.png b/example/src/main/assets/pic/action24/000008.png deleted file mode 100644 index f977aa3..0000000 Binary files a/example/src/main/assets/pic/action24/000008.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000009.png b/example/src/main/assets/pic/action24/000009.png deleted file mode 100644 index c2b33d8..0000000 Binary files a/example/src/main/assets/pic/action24/000009.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000010.png b/example/src/main/assets/pic/action24/000010.png deleted file mode 100644 index 634de66..0000000 Binary files a/example/src/main/assets/pic/action24/000010.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000011.png b/example/src/main/assets/pic/action24/000011.png deleted file mode 100644 index 637b256..0000000 Binary files a/example/src/main/assets/pic/action24/000011.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000012.png b/example/src/main/assets/pic/action24/000012.png deleted file mode 100644 index ae31935..0000000 Binary files a/example/src/main/assets/pic/action24/000012.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000013.png b/example/src/main/assets/pic/action24/000013.png deleted file mode 100644 index ca9d43b..0000000 Binary files a/example/src/main/assets/pic/action24/000013.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000014.png b/example/src/main/assets/pic/action24/000014.png deleted file mode 100644 index 7e3e3ee..0000000 Binary files a/example/src/main/assets/pic/action24/000014.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000015.png b/example/src/main/assets/pic/action24/000015.png deleted file mode 100644 index 4499b6b..0000000 Binary files a/example/src/main/assets/pic/action24/000015.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000016.png b/example/src/main/assets/pic/action24/000016.png deleted file mode 100644 index 631902c..0000000 Binary files a/example/src/main/assets/pic/action24/000016.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000017.png b/example/src/main/assets/pic/action24/000017.png deleted file mode 100644 index 3621f18..0000000 Binary files a/example/src/main/assets/pic/action24/000017.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000018.png b/example/src/main/assets/pic/action24/000018.png deleted file mode 100644 index 09d18dd..0000000 Binary files a/example/src/main/assets/pic/action24/000018.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000019.png b/example/src/main/assets/pic/action24/000019.png deleted file mode 100644 index d19b666..0000000 Binary files a/example/src/main/assets/pic/action24/000019.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000020.png b/example/src/main/assets/pic/action24/000020.png deleted file mode 100644 index 1d1b049..0000000 Binary files a/example/src/main/assets/pic/action24/000020.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000021.png b/example/src/main/assets/pic/action24/000021.png deleted file mode 100644 index a249c66..0000000 Binary files a/example/src/main/assets/pic/action24/000021.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000022.png b/example/src/main/assets/pic/action24/000022.png deleted file mode 100644 index 4692c8b..0000000 Binary files a/example/src/main/assets/pic/action24/000022.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000023.png b/example/src/main/assets/pic/action24/000023.png deleted file mode 100644 index 3bb05c2..0000000 Binary files a/example/src/main/assets/pic/action24/000023.png and /dev/null differ diff --git a/example/src/main/assets/pic/action24/000024.png b/example/src/main/assets/pic/action24/000024.png deleted file mode 100644 index 4c2e17d..0000000 Binary files a/example/src/main/assets/pic/action24/000024.png and /dev/null differ diff --git a/example/src/main/assets/pic/motion_data.json b/example/src/main/assets/pic/motion_data.json index c362634..e838501 100644 --- a/example/src/main/assets/pic/motion_data.json +++ b/example/src/main/assets/pic/motion_data.json @@ -1,122 +1,564 @@ -{ - "4": [ - "4.png" - ], - "5": [ - "5.png" - ], - "6": [ - "6.png" - ], - "7": [ - "7.png" - ], - "11": [ - "11.png" - ], - "12": [ - "12.png" - ], - "13": [ - "13.png" - ], - "14": [ - "14.png" - ], - "21": [ - "21.png" - ], - "23": [ - "23.png" - ], - "24": [ - "24.png" - ], - "26": [ - "26.png" - ], - "27": [ - "27.png" - ], - "32": [ - "32.png" - ], - "37": [ - "37.png" - ], - "40": [ - "40.png" - ], - "45": [ - "45.png" - ], - "48": [ - "48.png" - ], - "49": [ - "49.png" - ], - "53": [ - "53.png" - ], - "56": [ - "56.png" - ], - "59": [ - "59.png" - ], - "62": [ - "62.png" - ], - "65": [ - "65.png" - ], - "68": [ - "68.png" - ], - "71": [ - "71.png" - ], - "76": [ - "76.png" - ], - "77": [ - "77.png" - ], - "78": [ - "78.png" - ], - "81": [ - "81.png" - ], - "82": [ - "82.png" - ], - "action24": [ - "000000.png", - "000001.png", - "000002.png", - "000003.png", - "000004.png", - "000005.png", - "000006.png", - "000007.png", - "000008.png", - "000009.png", - "000010.png", - "000011.png", - "000012.png", - "000013.png", - "000014.png", - "000015.png", - "000016.png", - "000017.png", - "000018.png", - "000019.png", - "000020.png", - "000021.png", - "000022.png", - "000023.png", - "000024.png" - ] +{ + "3": [ + "000000.png" + ], + "4": [ + "000000.png", + "000001.png", + "000002.png", + "000003.png", + "000004.png", + "000005.png", + "000006.png", + "000007.png", + "000008.png", + "000009.png", + "000010.png", + "000011.png", + "000012.png", + "000013.png", + "000014.png", + "000015.png", + "000016.png", + "000017.png", + "000018.png", + "000019.png", + "000020.png", + "000021.png", + "000022.png", + "000023.png", + "000024.png", + "000025.png", + "000026.png", + "000027.png", + "000028.png", + "000029.png", + "000030.png", + "000031.png" + ], + "5": [ + "000000.png", + "000001.png", + "000002.png", + "000003.png", + "000004.png", + "000005.png", + "000006.png", + "000007.png", + "000008.png", + "000009.png", + "000010.png", + "000011.png", + "000012.png", + "000013.png", + "000014.png", + "000015.png", + "000016.png", + "000017.png", + "000018.png", + "000019.png", + "000020.png", + "000021.png", + "000022.png", + "000023.png", + "000024.png", + "000025.png", + "000026.png", + "000027.png", + "000028.png", + "000029.png", + "000030.png", + "000031.png" + ], + "6": [ + "000000.png", + "000001.png", + "000002.png", + "000003.png", + "000004.png", + "000005.png", + "000006.png", + "000007.png", + "000008.png", + "000009.png", + "000010.png", + "000011.png", + "000012.png", + "000013.png", + "000014.png", + "000015.png", + "000016.png", + "000017.png", + "000018.png", + "000019.png", + "000020.png", + "000021.png", + "000022.png", + "000023.png", + "000024.png", + "000025.png", + "000026.png", + "000027.png", + "000028.png", + "000029.png", + "000030.png", + "000031.png" + ], + "7": [ + "000000.png", + "000001.png", + "000002.png", + "000003.png", + "000004.png", + "000005.png", + "000006.png", + "000007.png", + "000008.png", + "000009.png", + "000010.png", + "000011.png", + "000012.png", + "000013.png", + "000014.png", + "000015.png", + "000016.png", + "000017.png", + "000018.png", + "000019.png", + "000020.png", + "000021.png", + "000022.png", + "000023.png", + "000024.png", + "000025.png", + "000026.png", + "000027.png", + "000028.png", + "000029.png", + "000030.png", + "000031.png" + ], + "11": [ + "000000.png", + "000001.png", + "000002.png", + "000003.png", + "000004.png", + "000005.png", + "000006.png", + "000007.png", + "000008.png", + "000009.png", + "000010.png", + "000011.png", + "000012.png", + "000013.png", + "000014.png", + "000015.png", + "000016.png", + "000017.png", + "000018.png", + "000019.png", + "000020.png", + "000021.png", + "000022.png", + "000023.png" + ], + "12": [ + "000000.png", + "000001.png", + "000002.png", + "000003.png", + "000004.png", + "000005.png", + "000006.png", + "000007.png", + "000008.png", + "000009.png", + "000010.png", + "000011.png", + "000012.png", + "000013.png", + "000014.png", + "000015.png", + "000016.png", + "000017.png", + "000018.png", + "000019.png", + "000020.png", + "000021.png", + "000022.png", + "000023.png" + ], + "13": [ + "000000.png", + "000001.png", + "000002.png", + "000003.png", + "000004.png", + "000005.png", + "000006.png", + "000007.png", + "000008.png", + "000009.png", + "000010.png", + "000011.png", + "000012.png", + "000013.png", + "000014.png", + "000015.png", + "000016.png", + "000017.png", + "000018.png", + "000019.png", + "000020.png", + "000021.png", + "000022.png", + "000023.png", + "000024.png", + "000025.png", + "000026.png", + "000027.png", + "000028.png", + "000029.png", + "000030.png", + "000031.png" + ], + "14": [ + "000000.png", + "000001.png", + "000002.png", + "000003.png", + "000004.png", + "000005.png", + "000006.png", + "000007.png", + "000008.png", + "000009.png", + "000010.png", + "000011.png", + "000012.png", + "000013.png", + "000014.png", + "000015.png", + "000016.png", + "000017.png", + "000018.png", + "000019.png", + "000020.png", + "000021.png", + "000022.png", + "000023.png", + "000024.png", + "000025.png", + "000026.png", + "000027.png", + "000028.png", + "000029.png", + "000030.png", + "000031.png" + ], + "21": [ + "000000.png", + "000001.png", + "000002.png", + "000003.png", + "000004.png", + "000005.png", + "000006.png", + "000007.png", + "000008.png", + "000009.png", + "000010.png", + "000011.png", + "000012.png", + "000013.png", + "000014.png", + "000015.png", + "000016.png", + "000017.png", + "000018.png", + "000019.png", + "000020.png", + "000021.png", + "000022.png", + "000023.png", + "000024.png", + "000025.png", + "000026.png", + "000027.png", + "000028.png", + "000029.png", + "000030.png", + "000031.png" + ], + "56": [ + "000000.png", + "000001.png", + "000002.png", + "000003.png", + "000004.png", + "000005.png", + "000006.png", + "000007.png", + "000008.png", + "000009.png", + "000010.png", + "000011.png", + "000012.png", + "000013.png", + "000014.png", + "000015.png", + "000016.png", + "000017.png", + "000018.png", + "000019.png", + "000020.png", + "000021.png", + "000022.png", + "000023.png", + "000024.png", + "000025.png", + "000026.png", + "000027.png", + "000028.png", + "000029.png", + "000030.png", + "000031.png" + ], + "59": [ + "000000.png", + "000001.png", + "000002.png", + "000003.png", + "000004.png", + "000005.png", + "000006.png", + "000007.png", + "000008.png", + "000009.png", + "000010.png", + "000011.png", + "000012.png", + "000013.png", + "000014.png", + "000015.png", + "000016.png", + "000017.png", + "000018.png", + "000019.png", + "000020.png", + "000021.png", + "000022.png", + "000023.png" + ], + "62": [ + "000000.png", + "000001.png", + "000002.png", + "000003.png", + "000004.png", + "000005.png", + "000006.png", + "000007.png", + "000008.png", + "000009.png", + "000010.png", + "000011.png", + "000012.png", + "000013.png", + "000014.png", + "000015.png", + "000016.png", + "000017.png", + "000018.png", + "000019.png", + "000020.png", + "000021.png", + "000022.png", + "000023.png", + "000024.png", + "000025.png", + "000026.png", + "000027.png", + "000028.png", + "000029.png", + "000030.png", + "000031.png" + ], + "65": [ + "000000.png", + "000001.png", + "000002.png", + "000003.png", + "000004.png", + "000005.png", + "000006.png", + "000007.png", + "000008.png", + "000009.png", + "000010.png", + "000011.png", + "000012.png", + "000013.png", + "000014.png", + "000015.png", + "000016.png", + "000017.png", + "000018.png", + "000019.png", + "000020.png", + "000021.png", + "000022.png", + "000023.png", + "000024.png", + "000025.png", + "000026.png", + "000027.png", + "000028.png", + "000029.png", + "000030.png", + "000031.png" + ], + "68": [ + "000000.png", + "000001.png", + "000002.png", + "000003.png", + "000004.png", + "000005.png", + "000006.png", + "000007.png", + "000008.png", + "000009.png", + "000010.png", + "000011.png", + "000012.png", + "000013.png", + "000014.png", + "000015.png", + "000016.png", + "000017.png", + "000018.png", + "000019.png", + "000020.png", + "000021.png", + "000022.png", + "000023.png", + "000024.png", + "000025.png", + "000026.png", + "000027.png", + "000028.png", + "000029.png", + "000030.png", + "000031.png" + ], + "71": [ + "000000.png", + "000001.png", + "000002.png", + "000003.png", + "000004.png", + "000005.png", + "000006.png", + "000007.png", + "000008.png", + "000009.png", + "000010.png", + "000011.png", + "000012.png", + "000013.png", + "000014.png", + "000015.png", + "000016.png", + "000017.png", + "000018.png", + "000019.png", + "000020.png", + "000021.png", + "000022.png", + "000023.png", + "000024.png", + "000025.png", + "000026.png", + "000027.png", + "000028.png", + "000029.png", + "000030.png", + "000031.png" + ], + "76": [ + "76.png" + ], + "77": [ + "77.png" + ], + "78": [ + "000000.png", + "000001.png", + "000002.png", + "000003.png", + "000004.png", + "000005.png", + "000006.png", + "000007.png", + "000008.png", + "000009.png", + "000010.png", + "000011.png", + "000012.png", + "000013.png", + "000014.png", + "000015.png", + "000016.png", + "000017.png", + "000018.png", + "000019.png", + "000020.png", + "000021.png", + "000022.png", + "000023.png", + "000024.png", + "000025.png", + "000026.png", + "000027.png", + "000028.png", + "000029.png", + "000030.png", + "000031.png" + ], + "80": [ + "80.png" + ], + "81": [ + "000000.png", + "000001.png", + "000002.png", + "000003.png", + "000004.png", + "000005.png", + "000006.png", + "000007.png", + "000008.png", + "000009.png", + "000010.png", + "000011.png", + "000012.png", + "000013.png", + "000014.png", + "000015.png", + "000016.png", + "000017.png", + "000018.png", + "000019.png", + "000020.png", + "000021.png", + "000022.png", + "000023.png", + "000024.png", + "000025.png", + "000026.png", + "000027.png" + ] } \ No newline at end of file diff --git a/example/src/main/assets/pic/motion_data_ex.json b/example/src/main/assets/pic/motion_data_ex.json new file mode 100644 index 0000000..06713ff --- /dev/null +++ b/example/src/main/assets/pic/motion_data_ex.json @@ -0,0 +1,2124 @@ +{ + "3": { + "000000.png": { + "x": 0, + "y": 0 + } + }, + "4": { + "000000.png": { + "x": 0, + "y": 0 + }, + "000001.png": { + "x": 512, + "y": 0 + }, + "000002.png": { + "x": 1024, + "y": 0 + }, + "000003.png": { + "x": 1536, + "y": 0 + }, + "000004.png": { + "x": 2048, + "y": 0 + }, + "000005.png": { + "x": 2560, + "y": 0 + }, + "000006.png": { + "x": 3072, + "y": 0 + }, + "000007.png": { + "x": 3584, + "y": 0 + }, + "000008.png": { + "x": 0, + "y": 512 + }, + "000009.png": { + "x": 512, + "y": 512 + }, + "000010.png": { + "x": 1024, + "y": 512 + }, + "000011.png": { + "x": 1536, + "y": 512 + }, + "000012.png": { + "x": 2048, + "y": 512 + }, + "000013.png": { + "x": 2560, + "y": 512 + }, + "000014.png": { + "x": 3072, + "y": 512 + }, + "000015.png": { + "x": 3584, + "y": 512 + }, + "000016.png": { + "x": 0, + "y": 1024 + }, + "000017.png": { + "x": 512, + "y": 1024 + }, + "000018.png": { + "x": 1024, + "y": 1024 + }, + "000019.png": { + "x": 1536, + "y": 1024 + }, + "000020.png": { + "x": 2048, + "y": 1024 + }, + "000021.png": { + "x": 2560, + "y": 1024 + }, + "000022.png": { + "x": 3072, + "y": 1024 + }, + "000023.png": { + "x": 3584, + "y": 1024 + }, + "000024.png": { + "x": 0, + "y": 1536 + }, + "000025.png": { + "x": 512, + "y": 1536 + }, + "000026.png": { + "x": 1024, + "y": 1536 + }, + "000027.png": { + "x": 1536, + "y": 1536 + }, + "000028.png": { + "x": 2048, + "y": 1536 + }, + "000029.png": { + "x": 2560, + "y": 1536 + }, + "000030.png": { + "x": 3072, + "y": 1536 + }, + "000031.png": { + "x": 3584, + "y": 1536 + } + }, + "5": { + "000000.png": { + "x": 0, + "y": 0 + }, + "000001.png": { + "x": 512, + "y": 0 + }, + "000002.png": { + "x": 1024, + "y": 0 + }, + "000003.png": { + "x": 1536, + "y": 0 + }, + "000004.png": { + "x": 2048, + "y": 0 + }, + "000005.png": { + "x": 2560, + "y": 0 + }, + "000006.png": { + "x": 3072, + "y": 0 + }, + "000007.png": { + "x": 3584, + "y": 0 + }, + "000008.png": { + "x": 0, + "y": 512 + }, + "000009.png": { + "x": 512, + "y": 512 + }, + "000010.png": { + "x": 1024, + "y": 512 + }, + "000011.png": { + "x": 1536, + "y": 512 + }, + "000012.png": { + "x": 2048, + "y": 512 + }, + "000013.png": { + "x": 2560, + "y": 512 + }, + "000014.png": { + "x": 3072, + "y": 512 + }, + "000015.png": { + "x": 3584, + "y": 512 + }, + "000016.png": { + "x": 0, + "y": 1024 + }, + "000017.png": { + "x": 512, + "y": 1024 + }, + "000018.png": { + "x": 1024, + "y": 1024 + }, + "000019.png": { + "x": 1536, + "y": 1024 + }, + "000020.png": { + "x": 2048, + "y": 1024 + }, + "000021.png": { + "x": 2560, + "y": 1024 + }, + "000022.png": { + "x": 3072, + "y": 1024 + }, + "000023.png": { + "x": 3584, + "y": 1024 + }, + "000024.png": { + "x": 0, + "y": 1536 + }, + "000025.png": { + "x": 512, + "y": 1536 + }, + "000026.png": { + "x": 1024, + "y": 1536 + }, + "000027.png": { + "x": 1536, + "y": 1536 + }, + "000028.png": { + "x": 2048, + "y": 1536 + }, + "000029.png": { + "x": 2560, + "y": 1536 + }, + "000030.png": { + "x": 3072, + "y": 1536 + }, + "000031.png": { + "x": 3584, + "y": 1536 + } + }, + "6": { + "000000.png": { + "x": 0, + "y": 0 + }, + "000001.png": { + "x": 512, + "y": 0 + }, + "000002.png": { + "x": 1024, + "y": 0 + }, + "000003.png": { + "x": 1536, + "y": 0 + }, + "000004.png": { + "x": 2048, + "y": 0 + }, + "000005.png": { + "x": 2560, + "y": 0 + }, + "000006.png": { + "x": 3072, + "y": 0 + }, + "000007.png": { + "x": 3584, + "y": 0 + }, + "000008.png": { + "x": 0, + "y": 512 + }, + "000009.png": { + "x": 512, + "y": 512 + }, + "000010.png": { + "x": 1024, + "y": 512 + }, + "000011.png": { + "x": 1536, + "y": 512 + }, + "000012.png": { + "x": 2048, + "y": 512 + }, + "000013.png": { + "x": 2560, + "y": 512 + }, + "000014.png": { + "x": 3072, + "y": 512 + }, + "000015.png": { + "x": 3584, + "y": 512 + }, + "000016.png": { + "x": 0, + "y": 1024 + }, + "000017.png": { + "x": 512, + "y": 1024 + }, + "000018.png": { + "x": 1024, + "y": 1024 + }, + "000019.png": { + "x": 1536, + "y": 1024 + }, + "000020.png": { + "x": 2048, + "y": 1024 + }, + "000021.png": { + "x": 2560, + "y": 1024 + }, + "000022.png": { + "x": 3072, + "y": 1024 + }, + "000023.png": { + "x": 3584, + "y": 1024 + }, + "000024.png": { + "x": 0, + "y": 1536 + }, + "000025.png": { + "x": 512, + "y": 1536 + }, + "000026.png": { + "x": 1024, + "y": 1536 + }, + "000027.png": { + "x": 1536, + "y": 1536 + }, + "000028.png": { + "x": 2048, + "y": 1536 + }, + "000029.png": { + "x": 2560, + "y": 1536 + }, + "000030.png": { + "x": 3072, + "y": 1536 + }, + "000031.png": { + "x": 3584, + "y": 1536 + } + }, + "7": { + "000000.png": { + "x": 0, + "y": 0 + }, + "000001.png": { + "x": 512, + "y": 0 + }, + "000002.png": { + "x": 1024, + "y": 0 + }, + "000003.png": { + "x": 1536, + "y": 0 + }, + "000004.png": { + "x": 2048, + "y": 0 + }, + "000005.png": { + "x": 2560, + "y": 0 + }, + "000006.png": { + "x": 3072, + "y": 0 + }, + "000007.png": { + "x": 3584, + "y": 0 + }, + "000008.png": { + "x": 0, + "y": 512 + }, + "000009.png": { + "x": 512, + "y": 512 + }, + "000010.png": { + "x": 1024, + "y": 512 + }, + "000011.png": { + "x": 1536, + "y": 512 + }, + "000012.png": { + "x": 2048, + "y": 512 + }, + "000013.png": { + "x": 2560, + "y": 512 + }, + "000014.png": { + "x": 3072, + "y": 512 + }, + "000015.png": { + "x": 3584, + "y": 512 + }, + "000016.png": { + "x": 0, + "y": 1024 + }, + "000017.png": { + "x": 512, + "y": 1024 + }, + "000018.png": { + "x": 1024, + "y": 1024 + }, + "000019.png": { + "x": 1536, + "y": 1024 + }, + "000020.png": { + "x": 2048, + "y": 1024 + }, + "000021.png": { + "x": 2560, + "y": 1024 + }, + "000022.png": { + "x": 3072, + "y": 1024 + }, + "000023.png": { + "x": 3584, + "y": 1024 + }, + "000024.png": { + "x": 0, + "y": 1536 + }, + "000025.png": { + "x": 512, + "y": 1536 + }, + "000026.png": { + "x": 1024, + "y": 1536 + }, + "000027.png": { + "x": 1536, + "y": 1536 + }, + "000028.png": { + "x": 2048, + "y": 1536 + }, + "000029.png": { + "x": 2560, + "y": 1536 + }, + "000030.png": { + "x": 3072, + "y": 1536 + }, + "000031.png": { + "x": 3584, + "y": 1536 + } + }, + "11": { + "000000.png": { + "x": 0, + "y": 0 + }, + "000001.png": { + "x": 512, + "y": 0 + }, + "000002.png": { + "x": 1024, + "y": 0 + }, + "000003.png": { + "x": 1536, + "y": 0 + }, + "000004.png": { + "x": 2048, + "y": 0 + }, + "000005.png": { + "x": 2560, + "y": 0 + }, + "000006.png": { + "x": 3072, + "y": 0 + }, + "000007.png": { + "x": 3584, + "y": 0 + }, + "000008.png": { + "x": 0, + "y": 512 + }, + "000009.png": { + "x": 512, + "y": 512 + }, + "000010.png": { + "x": 1024, + "y": 512 + }, + "000011.png": { + "x": 1536, + "y": 512 + }, + "000012.png": { + "x": 2048, + "y": 512 + }, + "000013.png": { + "x": 2560, + "y": 512 + }, + "000014.png": { + "x": 3072, + "y": 512 + }, + "000015.png": { + "x": 3584, + "y": 512 + }, + "000016.png": { + "x": 0, + "y": 1024 + }, + "000017.png": { + "x": 512, + "y": 1024 + }, + "000018.png": { + "x": 1024, + "y": 1024 + }, + "000019.png": { + "x": 1536, + "y": 1024 + }, + "000020.png": { + "x": 2048, + "y": 1024 + }, + "000021.png": { + "x": 2560, + "y": 1024 + }, + "000022.png": { + "x": 3072, + "y": 1024 + }, + "000023.png": { + "x": 3584, + "y": 1024 + } + }, + "12": { + "000000.png": { + "x": 0, + "y": 0 + }, + "000001.png": { + "x": 512, + "y": 0 + }, + "000002.png": { + "x": 1024, + "y": 0 + }, + "000003.png": { + "x": 1536, + "y": 0 + }, + "000004.png": { + "x": 2048, + "y": 0 + }, + "000005.png": { + "x": 2560, + "y": 0 + }, + "000006.png": { + "x": 3072, + "y": 0 + }, + "000007.png": { + "x": 3584, + "y": 0 + }, + "000008.png": { + "x": 0, + "y": 512 + }, + "000009.png": { + "x": 512, + "y": 512 + }, + "000010.png": { + "x": 1024, + "y": 512 + }, + "000011.png": { + "x": 1536, + "y": 512 + }, + "000012.png": { + "x": 2048, + "y": 512 + }, + "000013.png": { + "x": 2560, + "y": 512 + }, + "000014.png": { + "x": 3072, + "y": 512 + }, + "000015.png": { + "x": 3584, + "y": 512 + }, + "000016.png": { + "x": 0, + "y": 1024 + }, + "000017.png": { + "x": 512, + "y": 1024 + }, + "000018.png": { + "x": 1024, + "y": 1024 + }, + "000019.png": { + "x": 1536, + "y": 1024 + }, + "000020.png": { + "x": 2048, + "y": 1024 + }, + "000021.png": { + "x": 2560, + "y": 1024 + }, + "000022.png": { + "x": 3072, + "y": 1024 + }, + "000023.png": { + "x": 3584, + "y": 1024 + } + }, + "13": { + "000000.png": { + "x": 0, + "y": 0 + }, + "000001.png": { + "x": 512, + "y": 0 + }, + "000002.png": { + "x": 1024, + "y": 0 + }, + "000003.png": { + "x": 1536, + "y": 0 + }, + "000004.png": { + "x": 2048, + "y": 0 + }, + "000005.png": { + "x": 2560, + "y": 0 + }, + "000006.png": { + "x": 3072, + "y": 0 + }, + "000007.png": { + "x": 3584, + "y": 0 + }, + "000008.png": { + "x": 0, + "y": 512 + }, + "000009.png": { + "x": 512, + "y": 512 + }, + "000010.png": { + "x": 1024, + "y": 512 + }, + "000011.png": { + "x": 1536, + "y": 512 + }, + "000012.png": { + "x": 2048, + "y": 512 + }, + "000013.png": { + "x": 2560, + "y": 512 + }, + "000014.png": { + "x": 3072, + "y": 512 + }, + "000015.png": { + "x": 3584, + "y": 512 + }, + "000016.png": { + "x": 0, + "y": 1024 + }, + "000017.png": { + "x": 512, + "y": 1024 + }, + "000018.png": { + "x": 1024, + "y": 1024 + }, + "000019.png": { + "x": 1536, + "y": 1024 + }, + "000020.png": { + "x": 2048, + "y": 1024 + }, + "000021.png": { + "x": 2560, + "y": 1024 + }, + "000022.png": { + "x": 3072, + "y": 1024 + }, + "000023.png": { + "x": 3584, + "y": 1024 + }, + "000024.png": { + "x": 0, + "y": 1536 + }, + "000025.png": { + "x": 512, + "y": 1536 + }, + "000026.png": { + "x": 1024, + "y": 1536 + }, + "000027.png": { + "x": 1536, + "y": 1536 + }, + "000028.png": { + "x": 2048, + "y": 1536 + }, + "000029.png": { + "x": 2560, + "y": 1536 + }, + "000030.png": { + "x": 3072, + "y": 1536 + }, + "000031.png": { + "x": 3584, + "y": 1536 + } + }, + "14": { + "000000.png": { + "x": 0, + "y": 0 + }, + "000001.png": { + "x": 512, + "y": 0 + }, + "000002.png": { + "x": 1024, + "y": 0 + }, + "000003.png": { + "x": 1536, + "y": 0 + }, + "000004.png": { + "x": 2048, + "y": 0 + }, + "000005.png": { + "x": 2560, + "y": 0 + }, + "000006.png": { + "x": 3072, + "y": 0 + }, + "000007.png": { + "x": 3584, + "y": 0 + }, + "000008.png": { + "x": 0, + "y": 512 + }, + "000009.png": { + "x": 512, + "y": 512 + }, + "000010.png": { + "x": 1024, + "y": 512 + }, + "000011.png": { + "x": 1536, + "y": 512 + }, + "000012.png": { + "x": 2048, + "y": 512 + }, + "000013.png": { + "x": 2560, + "y": 512 + }, + "000014.png": { + "x": 3072, + "y": 512 + }, + "000015.png": { + "x": 3584, + "y": 512 + }, + "000016.png": { + "x": 0, + "y": 1024 + }, + "000017.png": { + "x": 512, + "y": 1024 + }, + "000018.png": { + "x": 1024, + "y": 1024 + }, + "000019.png": { + "x": 1536, + "y": 1024 + }, + "000020.png": { + "x": 2048, + "y": 1024 + }, + "000021.png": { + "x": 2560, + "y": 1024 + }, + "000022.png": { + "x": 3072, + "y": 1024 + }, + "000023.png": { + "x": 3584, + "y": 1024 + }, + "000024.png": { + "x": 0, + "y": 1536 + }, + "000025.png": { + "x": 512, + "y": 1536 + }, + "000026.png": { + "x": 1024, + "y": 1536 + }, + "000027.png": { + "x": 1536, + "y": 1536 + }, + "000028.png": { + "x": 2048, + "y": 1536 + }, + "000029.png": { + "x": 2560, + "y": 1536 + }, + "000030.png": { + "x": 3072, + "y": 1536 + }, + "000031.png": { + "x": 3584, + "y": 1536 + } + }, + "21": { + "000000.png": { + "x": 0, + "y": 0 + }, + "000001.png": { + "x": 512, + "y": 0 + }, + "000002.png": { + "x": 1024, + "y": 0 + }, + "000003.png": { + "x": 1536, + "y": 0 + }, + "000004.png": { + "x": 2048, + "y": 0 + }, + "000005.png": { + "x": 2560, + "y": 0 + }, + "000006.png": { + "x": 3072, + "y": 0 + }, + "000007.png": { + "x": 3584, + "y": 0 + }, + "000008.png": { + "x": 0, + "y": 512 + }, + "000009.png": { + "x": 512, + "y": 512 + }, + "000010.png": { + "x": 1024, + "y": 512 + }, + "000011.png": { + "x": 1536, + "y": 512 + }, + "000012.png": { + "x": 2048, + "y": 512 + }, + "000013.png": { + "x": 2560, + "y": 512 + }, + "000014.png": { + "x": 3072, + "y": 512 + }, + "000015.png": { + "x": 3584, + "y": 512 + }, + "000016.png": { + "x": 0, + "y": 1024 + }, + "000017.png": { + "x": 512, + "y": 1024 + }, + "000018.png": { + "x": 1024, + "y": 1024 + }, + "000019.png": { + "x": 1536, + "y": 1024 + }, + "000020.png": { + "x": 2048, + "y": 1024 + }, + "000021.png": { + "x": 2560, + "y": 1024 + }, + "000022.png": { + "x": 3072, + "y": 1024 + }, + "000023.png": { + "x": 3584, + "y": 1024 + }, + "000024.png": { + "x": 0, + "y": 1536 + }, + "000025.png": { + "x": 512, + "y": 1536 + }, + "000026.png": { + "x": 1024, + "y": 1536 + }, + "000027.png": { + "x": 1536, + "y": 1536 + }, + "000028.png": { + "x": 2048, + "y": 1536 + }, + "000029.png": { + "x": 2560, + "y": 1536 + }, + "000030.png": { + "x": 3072, + "y": 1536 + }, + "000031.png": { + "x": 3584, + "y": 1536 + } + }, + "56": { + "000000.png": { + "x": 0, + "y": 0 + }, + "000001.png": { + "x": 512, + "y": 0 + }, + "000002.png": { + "x": 1024, + "y": 0 + }, + "000003.png": { + "x": 1536, + "y": 0 + }, + "000004.png": { + "x": 2048, + "y": 0 + }, + "000005.png": { + "x": 2560, + "y": 0 + }, + "000006.png": { + "x": 3072, + "y": 0 + }, + "000007.png": { + "x": 3584, + "y": 0 + }, + "000008.png": { + "x": 0, + "y": 512 + }, + "000009.png": { + "x": 512, + "y": 512 + }, + "000010.png": { + "x": 1024, + "y": 512 + }, + "000011.png": { + "x": 1536, + "y": 512 + }, + "000012.png": { + "x": 2048, + "y": 512 + }, + "000013.png": { + "x": 2560, + "y": 512 + }, + "000014.png": { + "x": 3072, + "y": 512 + }, + "000015.png": { + "x": 3584, + "y": 512 + }, + "000016.png": { + "x": 0, + "y": 1024 + }, + "000017.png": { + "x": 512, + "y": 1024 + }, + "000018.png": { + "x": 1024, + "y": 1024 + }, + "000019.png": { + "x": 1536, + "y": 1024 + }, + "000020.png": { + "x": 2048, + "y": 1024 + }, + "000021.png": { + "x": 2560, + "y": 1024 + }, + "000022.png": { + "x": 3072, + "y": 1024 + }, + "000023.png": { + "x": 3584, + "y": 1024 + }, + "000024.png": { + "x": 0, + "y": 1536 + }, + "000025.png": { + "x": 512, + "y": 1536 + }, + "000026.png": { + "x": 1024, + "y": 1536 + }, + "000027.png": { + "x": 1536, + "y": 1536 + }, + "000028.png": { + "x": 2048, + "y": 1536 + }, + "000029.png": { + "x": 2560, + "y": 1536 + }, + "000030.png": { + "x": 3072, + "y": 1536 + }, + "000031.png": { + "x": 3584, + "y": 1536 + } + }, + "59": { + "000000.png": { + "x": 0, + "y": 0 + }, + "000001.png": { + "x": 512, + "y": 0 + }, + "000002.png": { + "x": 1024, + "y": 0 + }, + "000003.png": { + "x": 1536, + "y": 0 + }, + "000004.png": { + "x": 2048, + "y": 0 + }, + "000005.png": { + "x": 2560, + "y": 0 + }, + "000006.png": { + "x": 3072, + "y": 0 + }, + "000007.png": { + "x": 3584, + "y": 0 + }, + "000008.png": { + "x": 0, + "y": 512 + }, + "000009.png": { + "x": 512, + "y": 512 + }, + "000010.png": { + "x": 1024, + "y": 512 + }, + "000011.png": { + "x": 1536, + "y": 512 + }, + "000012.png": { + "x": 2048, + "y": 512 + }, + "000013.png": { + "x": 2560, + "y": 512 + }, + "000014.png": { + "x": 3072, + "y": 512 + }, + "000015.png": { + "x": 3584, + "y": 512 + }, + "000016.png": { + "x": 0, + "y": 1024 + }, + "000017.png": { + "x": 512, + "y": 1024 + }, + "000018.png": { + "x": 1024, + "y": 1024 + }, + "000019.png": { + "x": 1536, + "y": 1024 + }, + "000020.png": { + "x": 2048, + "y": 1024 + }, + "000021.png": { + "x": 2560, + "y": 1024 + }, + "000022.png": { + "x": 3072, + "y": 1024 + }, + "000023.png": { + "x": 3584, + "y": 1024 + } + }, + "62": { + "000000.png": { + "x": 0, + "y": 0 + }, + "000001.png": { + "x": 512, + "y": 0 + }, + "000002.png": { + "x": 1024, + "y": 0 + }, + "000003.png": { + "x": 1536, + "y": 0 + }, + "000004.png": { + "x": 2048, + "y": 0 + }, + "000005.png": { + "x": 2560, + "y": 0 + }, + "000006.png": { + "x": 3072, + "y": 0 + }, + "000007.png": { + "x": 3584, + "y": 0 + }, + "000008.png": { + "x": 0, + "y": 512 + }, + "000009.png": { + "x": 512, + "y": 512 + }, + "000010.png": { + "x": 1024, + "y": 512 + }, + "000011.png": { + "x": 1536, + "y": 512 + }, + "000012.png": { + "x": 2048, + "y": 512 + }, + "000013.png": { + "x": 2560, + "y": 512 + }, + "000014.png": { + "x": 3072, + "y": 512 + }, + "000015.png": { + "x": 3584, + "y": 512 + }, + "000016.png": { + "x": 0, + "y": 1024 + }, + "000017.png": { + "x": 512, + "y": 1024 + }, + "000018.png": { + "x": 1024, + "y": 1024 + }, + "000019.png": { + "x": 1536, + "y": 1024 + }, + "000020.png": { + "x": 2048, + "y": 1024 + }, + "000021.png": { + "x": 2560, + "y": 1024 + }, + "000022.png": { + "x": 3072, + "y": 1024 + }, + "000023.png": { + "x": 3584, + "y": 1024 + }, + "000024.png": { + "x": 0, + "y": 1536 + }, + "000025.png": { + "x": 512, + "y": 1536 + }, + "000026.png": { + "x": 1024, + "y": 1536 + }, + "000027.png": { + "x": 1536, + "y": 1536 + }, + "000028.png": { + "x": 2048, + "y": 1536 + }, + "000029.png": { + "x": 2560, + "y": 1536 + }, + "000030.png": { + "x": 3072, + "y": 1536 + }, + "000031.png": { + "x": 3584, + "y": 1536 + } + }, + "65": { + "000000.png": { + "x": 0, + "y": 0 + }, + "000001.png": { + "x": 512, + "y": 0 + }, + "000002.png": { + "x": 1024, + "y": 0 + }, + "000003.png": { + "x": 1536, + "y": 0 + }, + "000004.png": { + "x": 2048, + "y": 0 + }, + "000005.png": { + "x": 2560, + "y": 0 + }, + "000006.png": { + "x": 3072, + "y": 0 + }, + "000007.png": { + "x": 3584, + "y": 0 + }, + "000008.png": { + "x": 0, + "y": 512 + }, + "000009.png": { + "x": 512, + "y": 512 + }, + "000010.png": { + "x": 1024, + "y": 512 + }, + "000011.png": { + "x": 1536, + "y": 512 + }, + "000012.png": { + "x": 2048, + "y": 512 + }, + "000013.png": { + "x": 2560, + "y": 512 + }, + "000014.png": { + "x": 3072, + "y": 512 + }, + "000015.png": { + "x": 3584, + "y": 512 + }, + "000016.png": { + "x": 0, + "y": 1024 + }, + "000017.png": { + "x": 512, + "y": 1024 + }, + "000018.png": { + "x": 1024, + "y": 1024 + }, + "000019.png": { + "x": 1536, + "y": 1024 + }, + "000020.png": { + "x": 2048, + "y": 1024 + }, + "000021.png": { + "x": 2560, + "y": 1024 + }, + "000022.png": { + "x": 3072, + "y": 1024 + }, + "000023.png": { + "x": 3584, + "y": 1024 + }, + "000024.png": { + "x": 0, + "y": 1536 + }, + "000025.png": { + "x": 512, + "y": 1536 + }, + "000026.png": { + "x": 1024, + "y": 1536 + }, + "000027.png": { + "x": 1536, + "y": 1536 + }, + "000028.png": { + "x": 2048, + "y": 1536 + }, + "000029.png": { + "x": 2560, + "y": 1536 + }, + "000030.png": { + "x": 3072, + "y": 1536 + }, + "000031.png": { + "x": 3584, + "y": 1536 + } + }, + "68": { + "000000.png": { + "x": 0, + "y": 0 + }, + "000001.png": { + "x": 512, + "y": 0 + }, + "000002.png": { + "x": 1024, + "y": 0 + }, + "000003.png": { + "x": 1536, + "y": 0 + }, + "000004.png": { + "x": 2048, + "y": 0 + }, + "000005.png": { + "x": 2560, + "y": 0 + }, + "000006.png": { + "x": 3072, + "y": 0 + }, + "000007.png": { + "x": 3584, + "y": 0 + }, + "000008.png": { + "x": 0, + "y": 512 + }, + "000009.png": { + "x": 512, + "y": 512 + }, + "000010.png": { + "x": 1024, + "y": 512 + }, + "000011.png": { + "x": 1536, + "y": 512 + }, + "000012.png": { + "x": 2048, + "y": 512 + }, + "000013.png": { + "x": 2560, + "y": 512 + }, + "000014.png": { + "x": 3072, + "y": 512 + }, + "000015.png": { + "x": 3584, + "y": 512 + }, + "000016.png": { + "x": 0, + "y": 1024 + }, + "000017.png": { + "x": 512, + "y": 1024 + }, + "000018.png": { + "x": 1024, + "y": 1024 + }, + "000019.png": { + "x": 1536, + "y": 1024 + }, + "000020.png": { + "x": 2048, + "y": 1024 + }, + "000021.png": { + "x": 2560, + "y": 1024 + }, + "000022.png": { + "x": 3072, + "y": 1024 + }, + "000023.png": { + "x": 3584, + "y": 1024 + }, + "000024.png": { + "x": 0, + "y": 1536 + }, + "000025.png": { + "x": 512, + "y": 1536 + }, + "000026.png": { + "x": 1024, + "y": 1536 + }, + "000027.png": { + "x": 1536, + "y": 1536 + }, + "000028.png": { + "x": 2048, + "y": 1536 + }, + "000029.png": { + "x": 2560, + "y": 1536 + }, + "000030.png": { + "x": 3072, + "y": 1536 + }, + "000031.png": { + "x": 3584, + "y": 1536 + } + }, + "71": { + "000000.png": { + "x": 0, + "y": 0 + }, + "000001.png": { + "x": 512, + "y": 0 + }, + "000002.png": { + "x": 1024, + "y": 0 + }, + "000003.png": { + "x": 1536, + "y": 0 + }, + "000004.png": { + "x": 2048, + "y": 0 + }, + "000005.png": { + "x": 2560, + "y": 0 + }, + "000006.png": { + "x": 3072, + "y": 0 + }, + "000007.png": { + "x": 3584, + "y": 0 + }, + "000008.png": { + "x": 0, + "y": 512 + }, + "000009.png": { + "x": 512, + "y": 512 + }, + "000010.png": { + "x": 1024, + "y": 512 + }, + "000011.png": { + "x": 1536, + "y": 512 + }, + "000012.png": { + "x": 2048, + "y": 512 + }, + "000013.png": { + "x": 2560, + "y": 512 + }, + "000014.png": { + "x": 3072, + "y": 512 + }, + "000015.png": { + "x": 3584, + "y": 512 + }, + "000016.png": { + "x": 0, + "y": 1024 + }, + "000017.png": { + "x": 512, + "y": 1024 + }, + "000018.png": { + "x": 1024, + "y": 1024 + }, + "000019.png": { + "x": 1536, + "y": 1024 + }, + "000020.png": { + "x": 2048, + "y": 1024 + }, + "000021.png": { + "x": 2560, + "y": 1024 + }, + "000022.png": { + "x": 3072, + "y": 1024 + }, + "000023.png": { + "x": 3584, + "y": 1024 + }, + "000024.png": { + "x": 0, + "y": 1536 + }, + "000025.png": { + "x": 512, + "y": 1536 + }, + "000026.png": { + "x": 1024, + "y": 1536 + }, + "000027.png": { + "x": 1536, + "y": 1536 + }, + "000028.png": { + "x": 2048, + "y": 1536 + }, + "000029.png": { + "x": 2560, + "y": 1536 + }, + "000030.png": { + "x": 3072, + "y": 1536 + }, + "000031.png": { + "x": 3584, + "y": 1536 + } + }, + "76": { + "76.png": { + "x": 0, + "y": 0 + } + }, + "77": { + "77.png": { + "x": 0, + "y": 0 + } + }, + "78": { + "000000.png": { + "x": 0, + "y": 0 + }, + "000001.png": { + "x": 512, + "y": 0 + }, + "000002.png": { + "x": 1024, + "y": 0 + }, + "000003.png": { + "x": 1536, + "y": 0 + }, + "000004.png": { + "x": 2048, + "y": 0 + }, + "000005.png": { + "x": 2560, + "y": 0 + }, + "000006.png": { + "x": 3072, + "y": 0 + }, + "000007.png": { + "x": 3584, + "y": 0 + }, + "000008.png": { + "x": 0, + "y": 512 + }, + "000009.png": { + "x": 512, + "y": 512 + }, + "000010.png": { + "x": 1024, + "y": 512 + }, + "000011.png": { + "x": 1536, + "y": 512 + }, + "000012.png": { + "x": 2048, + "y": 512 + }, + "000013.png": { + "x": 2560, + "y": 512 + }, + "000014.png": { + "x": 3072, + "y": 512 + }, + "000015.png": { + "x": 3584, + "y": 512 + }, + "000016.png": { + "x": 0, + "y": 1024 + }, + "000017.png": { + "x": 512, + "y": 1024 + }, + "000018.png": { + "x": 1024, + "y": 1024 + }, + "000019.png": { + "x": 1536, + "y": 1024 + }, + "000020.png": { + "x": 2048, + "y": 1024 + }, + "000021.png": { + "x": 2560, + "y": 1024 + }, + "000022.png": { + "x": 3072, + "y": 1024 + }, + "000023.png": { + "x": 3584, + "y": 1024 + }, + "000024.png": { + "x": 0, + "y": 1536 + }, + "000025.png": { + "x": 512, + "y": 1536 + }, + "000026.png": { + "x": 1024, + "y": 1536 + }, + "000027.png": { + "x": 1536, + "y": 1536 + }, + "000028.png": { + "x": 2048, + "y": 1536 + }, + "000029.png": { + "x": 2560, + "y": 1536 + }, + "000030.png": { + "x": 3072, + "y": 1536 + }, + "000031.png": { + "x": 3584, + "y": 1536 + } + }, + "80": { + "80.png": { + "x": 0, + "y": 0 + } + }, + "81": { + "000000.png": { + "x": 0, + "y": 0 + }, + "000001.png": { + "x": 512, + "y": 0 + }, + "000002.png": { + "x": 1024, + "y": 0 + }, + "000003.png": { + "x": 1536, + "y": 0 + }, + "000004.png": { + "x": 2048, + "y": 0 + }, + "000005.png": { + "x": 2560, + "y": 0 + }, + "000006.png": { + "x": 3072, + "y": 0 + }, + "000007.png": { + "x": 3584, + "y": 0 + }, + "000008.png": { + "x": 0, + "y": 512 + }, + "000009.png": { + "x": 512, + "y": 512 + }, + "000010.png": { + "x": 1024, + "y": 512 + }, + "000011.png": { + "x": 1536, + "y": 512 + }, + "000012.png": { + "x": 2048, + "y": 512 + }, + "000013.png": { + "x": 2560, + "y": 512 + }, + "000014.png": { + "x": 3072, + "y": 512 + }, + "000015.png": { + "x": 3584, + "y": 512 + }, + "000016.png": { + "x": 0, + "y": 1024 + }, + "000017.png": { + "x": 512, + "y": 1024 + }, + "000018.png": { + "x": 1024, + "y": 1024 + }, + "000019.png": { + "x": 1536, + "y": 1024 + }, + "000020.png": { + "x": 2048, + "y": 1024 + }, + "000021.png": { + "x": 2560, + "y": 1024 + }, + "000022.png": { + "x": 3072, + "y": 1024 + }, + "000023.png": { + "x": 3584, + "y": 1024 + }, + "000024.png": { + "x": 0, + "y": 1536 + }, + "000025.png": { + "x": 512, + "y": 1536 + }, + "000026.png": { + "x": 1024, + "y": 1536 + }, + "000027.png": { + "x": 1536, + "y": 1536 + } + } +} \ No newline at end of file diff --git a/example/src/main/assets/底妆/基础上妆/2按压/区域示意图/pic0.png b/example/src/main/assets/底妆/基础上妆/2按压/区域示意图/pic0.png deleted file mode 100644 index add9422..0000000 Binary files a/example/src/main/assets/底妆/基础上妆/2按压/区域示意图/pic0.png and /dev/null differ diff --git a/example/src/main/assets/底妆/基础上妆/2按压/区域示意图/pic0_thick.png b/example/src/main/assets/底妆/基础上妆/2按压/区域示意图/pic0_thick.png deleted file mode 100644 index 1a55a07..0000000 Binary files a/example/src/main/assets/底妆/基础上妆/2按压/区域示意图/pic0_thick.png and /dev/null differ diff --git a/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/demo0.png b/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/demo0.png deleted file mode 100644 index c9e5244..0000000 Binary files a/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/demo0.png and /dev/null differ diff --git a/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/demo0_thick.png b/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/demo0_thick.png deleted file mode 100644 index 4cbe056..0000000 Binary files a/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/demo0_thick.png and /dev/null differ diff --git a/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/pic0.png b/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/pic0.png deleted file mode 100644 index 5e96f81..0000000 Binary files a/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/pic0.png and /dev/null differ diff --git a/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/pic0_thick.png b/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/pic0_thick.png deleted file mode 100644 index 3a076eb..0000000 Binary files a/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/pic0_thick.png and /dev/null differ diff --git a/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/pic1.png b/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/pic1.png deleted file mode 100644 index 3af6c63..0000000 Binary files a/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/pic1.png and /dev/null differ diff --git a/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/pic1_thick.png b/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/pic1_thick.png deleted file mode 100644 index 66d4024..0000000 Binary files a/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/pic1_thick.png and /dev/null differ diff --git a/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/pic2.png b/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/pic2.png deleted file mode 100644 index 85b1564..0000000 Binary files a/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/pic2.png and /dev/null differ diff --git a/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/pic2_thick.png b/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/pic2_thick.png deleted file mode 100644 index fea7c4f..0000000 Binary files a/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/pic2_thick.png and /dev/null differ diff --git a/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/test0.png b/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/test0.png deleted file mode 100644 index acbb2d2..0000000 Binary files a/example/src/main/assets/底妆/基础上妆/2按压/方向示意图/test0.png and /dev/null differ diff --git a/example/src/main/java/com/hmwl/example/MainActivity.java b/example/src/main/java/com/hmwl/example/MainActivity.java deleted file mode 100644 index 2e1e537..0000000 --- a/example/src/main/java/com/hmwl/example/MainActivity.java +++ /dev/null @@ -1,150 +0,0 @@ -package com.hmwl.example; - -import android.content.Context; -import android.os.Bundle; -import android.util.Log; -import android.view.MotionEvent; -import android.widget.Toast; - -import com.hmwl.face_sdk.InitArg; -import com.hmwl.face_sdk.Motion; - - -import com.hmwl.face_sdk.FaceActivity; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -public class MainActivity extends FaceActivity -{ - - @Override - protected void onCreate(Bundle savedInstanceState) - { - Motion motion = new Motion(); - motion.type = "4"; - motion.png_names.add("4.png"); - InitArg initArg = new InitArg(); - initArg.action_fps = 29; - initArg.zoom = 1.5f; - initArg.motion = motion; - SetInitArg(initArg.toJson()); - - - super.onCreate(savedInstanceState); - FaceInit(this); - Toast.makeText(this, "4.png", Toast.LENGTH_LONG).show(); - } - - String GetCurMotionState(int index) - { - Motion motion = new Motion(); - motion.type = pngFilesByFolder.get(index).folderName; - motion.png_names = pngFilesByFolder.get(index).getFileList(); - return motion.toJson(); - } - - @Override - public boolean onTouchEvent(MotionEvent event) { - // 获取触控动作 - int action = event.getAction(); - - switch (action) { - case MotionEvent.ACTION_DOWN: - // 手指按下 - Log.d("TouchEvent", "手指按下 - X: " + event.getX() + ", Y: " + event.getY()); - break; - - case MotionEvent.ACTION_MOVE: - // 手指移动 - Log.d("TouchEvent", "手指移动 - X: " + event.getX() + ", Y: " + event.getY()); - break; - - case MotionEvent.ACTION_UP: - // 手指抬起 - Log.d("TouchEvent", "手指抬起"); - curIndex++; - if(curIndex > pngFilesByFolder.size()-1) - { - curIndex = 0; - } - ChangeState(GetCurMotionState(curIndex)); - Toast.makeText(this, pngFilesByFolder.get(curIndex).folderName, Toast.LENGTH_LONG).show(); - break; - } - - return true; // 表示已处理该事件 - } - - private class FolderInfo { - private String folderName; - private List fileList; - - public FolderInfo(String folderName, List fileList) { - this.folderName = folderName; - this.fileList = fileList; - } - - public String getFolderName() { - return folderName; - } - - public List getFileList() { - return fileList; - } - } - - private List readPngFilenamesFromAssets(Context context, String filename) { - List folderList = new ArrayList<>(); - - try { - InputStream is = context.getAssets().open(filename); - BufferedReader reader = new BufferedReader(new InputStreamReader(is)); - StringBuilder stringBuilder = new StringBuilder(); - String line; - while ((line = reader.readLine()) != null) { - stringBuilder.append(line); - } - - JSONObject jsonObject = new JSONObject(stringBuilder.toString()); - - // 遍历所有文件夹 - Iterator folderIterator = jsonObject.keys(); - while (folderIterator.hasNext()) { - String folderName = folderIterator.next(); - JSONArray fileArray = jsonObject.getJSONArray(folderName); - - List filesInFolder = new ArrayList<>(); - for (int i = 0; i < fileArray.length(); i++) { - filesInFolder.add(fileArray.getString(i)); - } - - folderList.add(new FolderInfo(folderName, filesInFolder)); - } - - reader.close(); - is.close(); - } catch (Exception e) { - e.printStackTrace(); - } - - return folderList; - } - int curIndex = 0; - List pngFilesByFolder = null; - private void FaceInit(Context context){ - pngFilesByFolder = readPngFilenamesFromAssets(context, "pic/motion_data.json"); - } - -} diff --git a/example/src/main/java/com/inewme/uvmirror/MainActivity.kt b/example/src/main/java/com/inewme/uvmirror/MainActivity.kt new file mode 100644 index 0000000..41077d4 --- /dev/null +++ b/example/src/main/java/com/inewme/uvmirror/MainActivity.kt @@ -0,0 +1,64 @@ +package com.inewme.uvmirror + +import android.content.Intent +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.unit.dp +import androidx.compose.ui.tooling.preview.Preview + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + MyApp() + } + } +} + +@Composable +fun MyApp(modifier: Modifier = Modifier) { + MaterialTheme { + Surface(modifier = modifier) { + Greeting("Android") + } + } +} + +@Composable +fun Greeting(name: String, modifier: Modifier = Modifier) { + val context = LocalContext.current // 获取上下文用于启动 Activity + + Column( + modifier = modifier.padding(16.dp) + ) { + Text(text = "Hello $name!") + + Button( + onClick = { + // 跳转到 MakeupActivity + val intent = Intent(context, MakeupActivity::class.java) + context.startActivity(intent) + } + ) { + Text("Go to Makeup") + } + } +} + +@Preview(showBackground = true) +@Composable +fun GreetingPreview() { + MaterialTheme { + Greeting("Android") + } +} \ No newline at end of file diff --git a/example/src/main/java/com/inewme/uvmirror/MakeupActivity.kt b/example/src/main/java/com/inewme/uvmirror/MakeupActivity.kt new file mode 100644 index 0000000..b94d2c9 --- /dev/null +++ b/example/src/main/java/com/inewme/uvmirror/MakeupActivity.kt @@ -0,0 +1,145 @@ + +package com.inewme.uvmirror + +import android.os.Bundle +import android.util.Log +import android.view.KeyEvent +import android.view.KeyEvent.KEYCODE_BACK +import android.view.MotionEvent +import androidx.lifecycle.lifecycleScope + +import com.hmwl.face_sdk.FaceActivity +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch + + +class MakeupActivity : FaceActivity() +{ + lateinit var motionMgr: MotionManager + private var updateJob: Job? = null + override fun onCreate(savedInstanceState: Bundle?) { + motionMgr = MotionManager(this, 10, 1.5f, 0f,0f,1f,240f, 200f, -200f) + super.onCreate(savedInstanceState) + // 启动一个生命周期感知的协程, 每10ms 调用一次,可以通过update 来处理业务的逻辑 + updateJob = lifecycleScope.launch { + while (true) { + update() + delay(10) // 每 10 毫秒执行一次 + } + } + + // 首先一次性加载当前业务逻辑所要求的所有动画资源, 之后就可以任意跳转,和播放,不用考虑状态 + motionMgr.LoadMotionList(sequenceAll){ + //当加载完成了所有资源后会回调 + isMotionLoadFinished = true + } + } + + //定义加载完成的变量,通过回调函数设置,加载完成后才可以进行动画播放的操作 + var isMotionLoadFinished: Boolean = false + + + + //这里是模拟业务逻辑的地方 + // 模拟问题1, 打断当前的动画,然后跳转到指定步骤 + // 首先播放动画序列 粉底(4、5、6、7)、腮红(55、59)、口红由(76、77、78) 一直循环播放 "4", "5", "6", "7", "55", "59", "76", "77", "78" + // 然后 当播放到 10秒的时候,也可以是其他事件,需要暂停动画 + // 然后 暂停5秒,这个时候需要继续播放动画 + // 然后 又播放了8秒钟,这个时候要却换到 (11, 13, 21 动画序列了), 同时设置序列播放完成回调函数 + // 然后 播放完这个序列又要切换为原来的序列播放,通过序列播放完成回调函数实现 + private var elapsedTime = 0 // 总经过时间(ms) + private val sequenceA = listOf("4") + private val sequenceB = listOf("56") + private val sequenceAll = listOf("4", "56") + + private fun update() + { + if(isMotionLoadFinished) + { + if(elapsedTime == 0){ + //这次播放是一直循环播放,我们不需要判断动画是否播放完成, 回调函数直接传入null + PlayMotionList(sequenceA, true, null) + } + + elapsedTime += 10 // 动画加载完成后开始计时,每次调用增加 10ms + + if(elapsedTime == 10*1000){ + //暂停动画 + StopMotion() + } + + if(elapsedTime == 10*1000 + 5*1000){ + //恢复播放动画 + ResumeMotion() + } + + if(elapsedTime == 10*1000 + 5*1000 + 8*1000){ + PlayMotionList(sequenceB, true){ + //这里是播放完动画后的回调,再次切换到原来的 sequenceA + PlayMotionList(sequenceA, true, null) + } + } + + } + + } + + // 模拟问题2, 当语音播报结束的时候,打断当前的动画, 跳转到另外一个动画 + // 首先播放动画序列 粉底(4、5、6、7)、 + // 然后 当播放到 10秒的时候,表示语音播报结束, 条装到 "55", "59" 动画 +// private var elapsedTime = 0 // 总经过时间(ms) +// private val sequenceA = listOf("4", "5", "6") +// private val sequenceB = listOf("7", "55", "59") +// private val sequenceAll = listOf("4", "5", "6", "7", "55", "59") +// +// private fun update() +// { +// if(isMotionLoadFinished) +// { +// if(elapsedTime == 0){ +// //这次播放是一直循环播放,我们不需要判断动画是否播放完成, 回调函数直接传入null +// PlayMotionList(sequenceA, true, null) +// } +// +// elapsedTime += 10 // 动画加载完成后开始计时,每次调用增加 10ms +// +// if(elapsedTime == 10*1000){ +// //暂停动画 +// PlayMotionList(sequenceB, true, null) +// } +// } +// +// } + + + override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { + if (keyCode == KEYCODE_BACK) { + Log.d("MakeupActivity", "Back key pressed") + handleBackPress() + return true // 消费事件,防止默认行为(如直接 finish) + } + return super.onKeyDown(keyCode, event) + } + + private fun handleBackPress() { + Stop() + finish() + } + + + var animationFinishedFun = object : PlayMotionListFinishedCallback { + override fun OnPlayMotionListFinished() { + Log.i("MakeupActivity", "OnAnimationFinished: ") + } + } + + override fun onTouchEvent(event: MotionEvent): Boolean { + when (event.action) { + MotionEvent.ACTION_UP -> { + + } + } + return true + } +} \ No newline at end of file diff --git a/example/src/main/java/com/inewme/uvmirror/MotionManager.kt b/example/src/main/java/com/inewme/uvmirror/MotionManager.kt new file mode 100644 index 0000000..f3a61f0 --- /dev/null +++ b/example/src/main/java/com/inewme/uvmirror/MotionManager.kt @@ -0,0 +1,103 @@ +package com.inewme.uvmirror + +import android.content.Context +import com.hmwl.face_sdk.FaceActivity +import com.hmwl.face_sdk.FaceActivity.PlayMotionListFinishedCallback +import com.hmwl.face_sdk.FaceActivity.LoadMotionListFinishedCallback +import com.hmwl.face_sdk.Frame +import com.hmwl.face_sdk.InitArg +import com.hmwl.face_sdk.Motion +import com.hmwl.face_sdk.MotionList +import org.json.JSONObject +import java.io.BufferedReader +import java.io.InputStreamReader + +class MotionManager { + var faceActivity:FaceActivity + + constructor(activity: FaceActivity, fps: Int, z: Float, r: Float, g: Float, b: Float, radius: Float, offset_x:Float, offset_y: Float) { + faceActivity = activity + val initArg = InitArg().apply { + action_fps = fps + this.zoom = z + this.r = r + this.g = g + this.b = b + this.radius = radius + this.offset_x = offset_x; + this.offset_y = offset_y; + } + activity.SetInitArg(initArg.toJson()) + existMotions = readMotionsFromAssets(activity, "pic/motion_data_ex.json") + + + } + + + + + fun LoadMotionList(motions:List, loadMotionFinishedCallback: LoadMotionListFinishedCallback){ + val mlist = MotionList(); + for(s in motions){ + getMotionByName(s)?.let { mlist.motions.add(it) } + } + + faceActivity.PreLoadAction(mlist.toJsonString(), loadMotionFinishedCallback) + } + + private fun getMotionByName(m: String): Motion? { + return existMotions?.get(m); + } + +// public fun update() +// { +// if(actionState == ActionState.LoadingFinished) +// { +// faceActivity.ChangeMotionList(animationFinishedFun, true) +// actionState = ActionState.Playing +// } +// } + + + private var existMotions: Map? = null + private fun readMotionsFromAssets(context: Context, filename: String): Map { + val motionMap = mutableMapOf() + + try { + context.assets.open(filename).use { inputStream -> + BufferedReader(InputStreamReader(inputStream)).use { reader -> + val stringBuilder = StringBuilder() + var line: String? + while (reader.readLine().also { line = it } != null) { + stringBuilder.append(line) + } + + val jsonObject = JSONObject(stringBuilder.toString()) + // 遍历JSON对象 + val keys = jsonObject.keys() + while (keys.hasNext()) { + val key = keys.next() // 获取键,即"Motion"的名字 + val motionObject = jsonObject.getJSONObject(key) + + val frameList = mutableListOf() + val fileKeys = motionObject.keys() + while (fileKeys.hasNext()) { + val fileKey = fileKeys.next() // 获取每个文件名 + val fileObject = motionObject.getJSONObject(fileKey) + val x = fileObject.getDouble("x").toFloat() + val y = fileObject.getDouble("y").toFloat() + frameList.add(Frame(fileKey, x, y)) + } + + motionMap[key] = Motion(key, frameList) + } + + } + } + } catch (e: Exception) { + e.printStackTrace() + } + + return motionMap + } +} \ No newline at end of file diff --git a/example/src/main/res/values/strings.xml b/example/src/main/res/values/strings.xml index 6d4f3ef..ad5cc65 100644 --- a/example/src/main/res/values/strings.xml +++ b/example/src/main/res/values/strings.xml @@ -1,3 +1,3 @@ - f20251110 + f20260113 \ No newline at end of file diff --git a/example/src/test/java/com/hmwl/example/ExampleUnitTest.java b/example/src/test/java/com/hmwl/example/ExampleUnitTest.java deleted file mode 100644 index 63c26a9..0000000 --- a/example/src/test/java/com/hmwl/example/ExampleUnitTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.hmwl.example; - -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Example local unit test, which will execute on the development machine (host). - * - * @see Testing documentation - */ -public class ExampleUnitTest { - @Test - public void addition_isCorrect() { - assertEquals(4, 2 + 2); - } -} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e383a1f..9f1a1dc 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -6,6 +6,11 @@ espressoCore = "3.7.0" appcompat = "1.7.1" material = "1.13.0" gamesActivity = "2.0.2" +kotlin = "1.9.0" +coreKtx = "1.12.0" +kotlinVersion = "1.9.0" +coreKtxVersion = "1.12.0" +androidxCoreKtx = "1.12.0" [libraries] junit = { group = "junit", name = "junit", version.ref = "junit" } @@ -14,7 +19,11 @@ espresso-core = { group = "androidx.test.espresso", name = "espresso-core", vers appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } material = { group = "com.google.android.material", name = "material", version.ref = "material" } games-activity = { group = "androidx.games", name = "games-activity", version.ref = "gamesActivity" } +core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } +androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtxVersion" } +androidx-core-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "androidxCoreKtx" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } android-library = { id = "com.android.library", version.ref = "agp" } +kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlinVersion" } diff --git a/python/combin_png.py b/python/combin_png.py new file mode 100644 index 0000000..5dbb236 --- /dev/null +++ b/python/combin_png.py @@ -0,0 +1,96 @@ +import json +from PIL import Image +import os + +# 全局变量定义分辨率 +RESIZE_TO = (512, 512) +LARGE_IMAGE_SIZE = (4096, 2048) +IMAGE_COUNT = 32 + +ROOT_DIR = '../example/src/main/assets/pic' + +def load_json(file_path): + with open(file_path, 'r') as file: + return json.load(file) + +def remove_white_border(image): + """ + 去除图片边缘的一个像素宽的白色边框。 + :param image: 输入的PIL Image对象。 + :return: 处理后的PIL Image对象。 + """ + # 获取图像尺寸 + width, height = image.size + + # 定义白色阈值,允许一定的误差范围 + white_threshold = (250, 250, 250) + + # 查找左边界 + left = 0 + while left < width and all(image.getpixel((left, y))[:3] >= white_threshold for y in range(height)): + left += 1 + + # 查找右边界 + right = width - 1 + while right > 0 and all(image.getpixel((right, y))[:3] >= white_threshold for y in range(height)): + right -= 1 + + # 查找上边界 + top = 0 + while top < height and all(image.getpixel((x, top))[:3] >= white_threshold for x in range(width)): + top += 1 + + # 查找下边界 + bottom = height - 1 + while bottom > 0 and all(image.getpixel((x, bottom))[:3] >= white_threshold for x in range(width)): + bottom -= 1 + + # 如果发现有白色边框,则裁剪它们 + if left < right and top < bottom: + image = image.crop((left, top, right + 1, bottom + 1)) + + return image + +def resize_image(image_path): + image = Image.open(image_path).convert('RGBA') + image = remove_white_border(image) + #return image.resize(RESIZE_TO) + return image + +def main(json_file_path): + # 确保使用完整路径 + json_file_path = os.path.join(ROOT_DIR, json_file_path) + data = load_json(json_file_path) + + new_data = {} + + for folder_name, images in data.items(): + large_image = Image.new('RGBA', LARGE_IMAGE_SIZE, color=(0, 0, 0, 0)) + images_coordinates = {} + index = 0 + + for image_name in images: + if index >= IMAGE_COUNT: + break + # 图片位于子文件夹内 + img_path = os.path.join(ROOT_DIR, folder_name, image_name) + img = resize_image(img_path) + x = (index % 8) * RESIZE_TO[0] + y = (index // 8) * RESIZE_TO[1] + large_image.paste(img, (x, y)) + images_coordinates[image_name] = {'x': x, 'y': y} + index += 1 + + output_image_path = os.path.join(ROOT_DIR, f"{folder_name}ex.png") + large_image.save(output_image_path, format='png') + + # 将坐标信息直接保存到new_data字典中 + new_data[folder_name] = images_coordinates + + # 输出新的json文件 + output_json_path = os.path.join(ROOT_DIR, 'motion_data_ex.json') + with open(output_json_path, 'w') as outfile: + json.dump(new_data, outfile, indent=4) + +# 使用示例 +main('motion_data.json') \ No newline at end of file diff --git a/vulkan/Application.cpp b/vulkan/Application.cpp index 15bbffc..b23940b 100644 --- a/vulkan/Application.cpp +++ b/vulkan/Application.cpp @@ -1,15 +1,55 @@ -#include "Application.h" +#include "Application.h" #include "lodepng.h" +#include #ifdef _WIN32 - + #include #else #include #include #include #include "../app/src/main/cpp/AndroidOut.h" + #include "../app/src/main/cpp/DebugLog.h" #endif +#ifdef _WIN32 +#define FACE_DBG_LOG(...) ((void)0) +#else +#define FACE_DBG_LOG(...) DebugLog::log(__VA_ARGS__) +#endif + +static const char* VkResultStr(VkResult r) { + switch (r) { + case VK_SUCCESS: return "VK_SUCCESS"; + case VK_NOT_READY: return "VK_NOT_READY"; + case VK_TIMEOUT: return "VK_TIMEOUT"; + case VK_EVENT_SET: return "VK_EVENT_SET"; + case VK_EVENT_RESET: return "VK_EVENT_RESET"; + case VK_INCOMPLETE: return "VK_INCOMPLETE"; + case VK_SUBOPTIMAL_KHR: return "VK_SUBOPTIMAL_KHR"; + case VK_ERROR_OUT_OF_HOST_MEMORY: return "VK_ERROR_OUT_OF_HOST_MEMORY"; + case VK_ERROR_OUT_OF_DEVICE_MEMORY: return "VK_ERROR_OUT_OF_DEVICE_MEMORY"; + case VK_ERROR_INITIALIZATION_FAILED: return "VK_ERROR_INITIALIZATION_FAILED"; + case VK_ERROR_DEVICE_LOST: return "VK_ERROR_DEVICE_LOST"; + case VK_ERROR_MEMORY_MAP_FAILED: return "VK_ERROR_MEMORY_MAP_FAILED"; + case VK_ERROR_LAYER_NOT_PRESENT: return "VK_ERROR_LAYER_NOT_PRESENT"; + case VK_ERROR_EXTENSION_NOT_PRESENT: return "VK_ERROR_EXTENSION_NOT_PRESENT"; + case VK_ERROR_FEATURE_NOT_PRESENT: return "VK_ERROR_FEATURE_NOT_PRESENT"; + case VK_ERROR_INCOMPATIBLE_DRIVER: return "VK_ERROR_INCOMPATIBLE_DRIVER"; + case VK_ERROR_TOO_MANY_OBJECTS: return "VK_ERROR_TOO_MANY_OBJECTS"; + case VK_ERROR_FORMAT_NOT_SUPPORTED: return "VK_ERROR_FORMAT_NOT_SUPPORTED"; + case VK_ERROR_FRAGMENTED_POOL: return "VK_ERROR_FRAGMENTED_POOL"; + case VK_ERROR_OUT_OF_DATE_KHR: return "VK_ERROR_OUT_OF_DATE_KHR"; + case VK_ERROR_SURFACE_LOST_KHR: return "VK_ERROR_SURFACE_LOST_KHR"; + case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: return "VK_ERROR_NATIVE_WINDOW_IN_USE_KHR"; + case VK_ERROR_OUT_OF_POOL_MEMORY: return "VK_ERROR_OUT_OF_POOL_MEMORY"; + case VK_ERROR_INVALID_EXTERNAL_HANDLE: return "VK_ERROR_INVALID_EXTERNAL_HANDLE"; + case VK_ERROR_FRAGMENTATION: return "VK_ERROR_FRAGMENTATION"; + case VK_ERROR_UNKNOWN: return "VK_ERROR_UNKNOWN"; + default: return "VK_UNMAPPED_VALUE"; + } +} + void Application::initWindow() @@ -53,25 +93,220 @@ void Application::createSurface() { void Application::initVulkan() { - initWindow(); - createInstance(); // 创建 Vulkan 实例 - setupDebugMessenger(); // 在这里调用 - createSurface(); // 创建窗口表面 - pickPhysicalDevice(physicalDevice, surface); // 选择物理设备 - createLogicalDevice(); // 创建逻辑设备 - createSwapChain(); // 创建交换链 - createImageViews(); // 创建交换链图像视图 - createRenderPass(); // 创建渲染流程 - createPipelineLayout(); // 在这里调用 - createGraphicsPipeline(); // 创建图形管线 - createFramebuffers(); // 创建帧缓冲区 - createCommandPool(); // 创建命令池 - createCommandBuffer(); // 创建命令缓冲区 - createSyncObjects(); // 创建同步对象 - _lastDrawFrameTime = getCurrentTimeMillis(); - inited = true; + if (!_applicationInited) + { + initWindow(); + createInstance(); // 创建 Vulkan 实例 + setupDebugMessenger(); // 在这里调用 + createSurface(); // 创建窗口表面 + pickPhysicalDevice(physicalDevice, surface); // 选择物理设备 + createLogicalDevice(); // 创建逻辑设备 + createSwapChain(); // 创建交换链 + createImageViews(); // 创建交换链图像视图 + createRenderPass(); // 创建渲染流程 + createPipelineLayout(); // 在这里调用 + createGraphicsPipeline(); // 创建图形管线 + createFramebuffers(); // 创建帧缓冲区 + createCommandPool(); // 创建命令池 + createCommandBuffer(); // 创建命令缓冲区 + createSyncObjects(); // 创建同步对象 + // 复用式 single-time-command 资源:从 commandPool_ex 预分配 + // kTransferSlotCount 个 cmdbuf + 同数 signaled fence, + // 之后所有 copyBuffer / updateTexture 走 runTransferCommand, + // 不再每次 vkAllocate/vkFree。 + createTransferResources(); + _lastDrawFrameTime = getCurrentTimeMillis(); + _applicationInited = true; + // The first branch above already built all of the window-dependent + // objects. Mark _sceondInited so we don't fall into the recovery + // branch below and leak a second copy of surface/swapChain/etc. + _sceondInited = true; + } + else if (!_sceondInited) { + createSurface(); + createSwapChain(); + createImageViews(); + createRenderPass(); + createPipelineLayout(); + createGraphicsPipeline(); + createFramebuffers(); + _sceondInited = true; + } } +void Application::cleanupSecondInit() +{ + vkDestroySwapchainKHR(device, swapChain, nullptr); + vkDestroySurfaceKHR(instance, surface, nullptr); + vkDestroyPipeline(device, graphicsPipeline, nullptr); + vkDestroyPipelineLayout(device, pipelineLayout, nullptr); + vkDestroyRenderPass(device, renderPass, nullptr); + for (auto imageView : swapChainImageViews) { + vkDestroyImageView(device, imageView, nullptr); + } + for (auto framebuffer : swapChainFramebuffers) + { + if (framebuffer != VK_NULL_HANDLE) + { + vkDestroyFramebuffer(device, framebuffer, nullptr); + } + } + swapChainFramebuffers.clear(); + + _sceondInited = false; +} + +void Application::cleanupForWindowLost() +{ + if (!_applicationInited || !_sceondInited) { + FACE_DBG_LOG("cleanupForWindowLost: skip (_applicationInited=%d _sceondInited=%d)", + (int)_applicationInited, (int)_sceondInited); + return; + } + FACE_DBG_LOG("cleanupForWindowLost: begin (imageCount=%zu MAX_FRAMES_IN_FLIGHT=%d extent=%ux%u format=%d)", + swapChainImages.size(), MAX_FRAMES_IN_FLIGHT, + swapChainExtent.width, swapChainExtent.height, (int)swapChainImageFormat); + + // Snapshot before we destroy the swapchain so reinitForNewWindow() can + // decide whether the new swapchain needs renderPass / pipelines rebuilt. + _prevSwapChainExtent = swapChainExtent; + _prevSwapChainImageFormat = swapChainImageFormat; + + // Block until GPU is no longer using any of the resources we are about + // to destroy. Anything weaker than this risks hitting VK_ERROR_DEVICE_LOST + // on drivers that don't tolerate destroying in-flight resources. + vkDeviceWaitIdle(device); + + for (auto framebuffer : swapChainFramebuffers) { + if (framebuffer != VK_NULL_HANDLE) { + vkDestroyFramebuffer(device, framebuffer, nullptr); + } + } + swapChainFramebuffers.clear(); + + for (auto imageView : swapChainImageViews) { + if (imageView != VK_NULL_HANDLE) { + vkDestroyImageView(device, imageView, nullptr); + } + } + swapChainImageViews.clear(); + + // Free the command buffers allocated from commandPool. The pool itself is + // kept alive so textures/staging uploads that run concurrently off the + // render thread (via commandPool_ex) aren't disrupted. + if (!commandBuffers.empty()) { + vkFreeCommandBuffers(device, commandPool, + (uint32_t)commandBuffers.size(), commandBuffers.data()); + commandBuffers.clear(); + } + + for (size_t i = 0; i < imageAvailableSemaphores.size(); ++i) { + if (imageAvailableSemaphores[i] != VK_NULL_HANDLE) { + vkDestroySemaphore(device, imageAvailableSemaphores[i], nullptr); + } + } + imageAvailableSemaphores.clear(); + for (size_t i = 0; i < renderFinishedSemaphores.size(); ++i) { + if (renderFinishedSemaphores[i] != VK_NULL_HANDLE) { + vkDestroySemaphore(device, renderFinishedSemaphores[i], nullptr); + } + } + renderFinishedSemaphores.clear(); + for (size_t i = 0; i < inFlightFences.size(); ++i) { + if (inFlightFences[i] != VK_NULL_HANDLE) { + vkDestroyFence(device, inFlightFences[i], nullptr); + } + } + inFlightFences.clear(); + imagesInFlight.clear(); + + if (swapChain != VK_NULL_HANDLE) { + vkDestroySwapchainKHR(device, swapChain, nullptr); + swapChain = VK_NULL_HANDLE; + } + swapChainImages.clear(); + + if (surface != VK_NULL_HANDLE) { + vkDestroySurfaceKHR(instance, surface, nullptr); + surface = VK_NULL_HANDLE; + } + + currentFrame = 0; + _sceondInited = false; + FACE_DBG_LOG("cleanupForWindowLost: done"); +} + +bool Application::reinitForNewWindow() +{ + if (!_applicationInited) { + FACE_DBG_LOG("reinitForNewWindow: skip, _applicationInited=0 (must go through initVulkan first)"); + return false; + } + if (_sceondInited) { + FACE_DBG_LOG("reinitForNewWindow: skip, already _sceondInited=1"); + return false; + } + FACE_DBG_LOG("reinitForNewWindow: begin (prev extent=%ux%u format=%d)", + _prevSwapChainExtent.width, _prevSwapChainExtent.height, + (int)_prevSwapChainImageFormat); + + createSurface(); + createSwapChain(); + + const bool extentChanged = (swapChainExtent.width != _prevSwapChainExtent.width) || + (swapChainExtent.height != _prevSwapChainExtent.height); + const bool formatChanged = (swapChainImageFormat != _prevSwapChainImageFormat); + const bool swapchainIncompatible = extentChanged || formatChanged; + + if (formatChanged) { + // renderPass bakes in swapChainImageFormat, so it must be rebuilt + // when the surface chose a different format. The old Application + // graphicsPipeline is tied to the old renderPass, so destroy it + // first to make the handle invalidation explicit. + FACE_DBG_LOG("reinitForNewWindow: format changed (%d -> %d), rebuilding renderPass", + (int)_prevSwapChainImageFormat, (int)swapChainImageFormat); + if (graphicsPipeline != VK_NULL_HANDLE) { + vkDestroyPipeline(device, graphicsPipeline, nullptr); + graphicsPipeline = VK_NULL_HANDLE; + } + if (pipelineLayout != VK_NULL_HANDLE) { + vkDestroyPipelineLayout(device, pipelineLayout, nullptr); + pipelineLayout = VK_NULL_HANDLE; + } + if (renderPass != VK_NULL_HANDLE) { + vkDestroyRenderPass(device, renderPass, nullptr); + renderPass = VK_NULL_HANDLE; + } + createRenderPass(); + createPipelineLayout(); + createGraphicsPipeline(); + } else if (extentChanged) { + // renderPass is still fine, but the Application pipeline has a static + // viewport baked to the old extent and must be rebuilt. + FACE_DBG_LOG("reinitForNewWindow: extent changed (%ux%u -> %ux%u), rebuilding graphicsPipeline", + _prevSwapChainExtent.width, _prevSwapChainExtent.height, + swapChainExtent.width, swapChainExtent.height); + if (graphicsPipeline != VK_NULL_HANDLE) { + vkDestroyPipeline(device, graphicsPipeline, nullptr); + graphicsPipeline = VK_NULL_HANDLE; + } + createGraphicsPipeline(); + } + + createImageViews(); + createFramebuffers(); + createCommandBuffer(); + createSyncObjects(); + + _sceondInited = true; + FACE_DBG_LOG("reinitForNewWindow: done (imageCount=%zu extent=%ux%u format=%d MAX_FRAMES_IN_FLIGHT=%d swapchainIncompatible=%d)", + swapChainImages.size(), swapChainExtent.width, swapChainExtent.height, + (int)swapChainImageFormat, MAX_FRAMES_IN_FLIGHT, (int)swapchainIncompatible); + return swapchainIncompatible; +} + + + void Application::createImageViews() { swapChainImageViews.resize(swapChainImages.size()); @@ -125,6 +360,7 @@ void Application::createFramebuffers() { void Application::mainLoop() { #ifdef _WIN32 + static int testFrame = 0; while (!glfwWindowShouldClose(window)) { auto cur_time = getCurrentTimeMillis(); @@ -132,6 +368,9 @@ void Application::mainLoop() auto functionTime = (cur_time - _lastDrawFrameTime); _lastDrawFrameTime = getCurrentTimeMillis(); drawFrame(functionTime); // 在这里调用 + if (testFrame++ == 300) { + break; + } } #else @@ -404,6 +643,17 @@ void Application::createCommandPool() { if (vkCreateCommandPool(device, &poolInfo, nullptr, &commandPool) != VK_SUCCESS) { throw std::runtime_error("failed to create command pool!"); } + + queueFamilyIndices = findQueueFamilies(physicalDevice, surface); + + VkCommandPoolCreateInfo poolInfo_ex{}; + poolInfo_ex.sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO; + poolInfo_ex.queueFamilyIndex = queueFamilyIndices.graphicsFamily.value(); + poolInfo_ex.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; // 添加标志 + + if (vkCreateCommandPool(device, &poolInfo_ex, nullptr, &commandPool_ex) != VK_SUCCESS) { + throw std::runtime_error("failed to create command pool!"); + } } void Application::createCommandBuffer() @@ -422,7 +672,6 @@ void Application::createCommandBuffer() void Application::createSyncObjects() { - imageAvailableSemaphores.resize(MAX_FRAMES_IN_FLIGHT); renderFinishedSemaphores.resize(MAX_FRAMES_IN_FLIGHT); inFlightFences.resize(MAX_FRAMES_IN_FLIGHT); @@ -435,16 +684,11 @@ void Application::createSyncObjects() fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; - // 为每个交换链图像创建信号量 for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { if (vkCreateSemaphore(device, &semaphoreInfo, nullptr, &imageAvailableSemaphores[i]) != VK_SUCCESS || vkCreateSemaphore(device, &semaphoreInfo, nullptr, &renderFinishedSemaphores[i]) != VK_SUCCESS) { throw std::runtime_error("failed to create synchronization objects!"); } - } - - // 为每个帧在飞行创建栅栏 - for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { if (vkCreateFence(device, &fenceInfo, nullptr, &inFlightFences[i]) != VK_SUCCESS) { throw std::runtime_error("failed to create synchronization objects!"); } @@ -497,14 +741,30 @@ void Application::render(VkCommandBuffer commandBuffer, long long frameTime) void Application::drawFrame(long long frameTime) { + static uint64_t s_drawFrameCount = 0; + ++s_drawFrameCount; + // 1. 等待前一帧完成 - vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX); + VkResult waitRes = vkWaitForFences(device, 1, &inFlightFences[currentFrame], VK_TRUE, UINT64_MAX); + if (waitRes != VK_SUCCESS) { +#ifndef _WIN32 + DebugLog::log_throttled("drawFrame.waitFences", + "drawFrame[%llu] vkWaitForFences -> %d (%s) currentFrame=%u", + (unsigned long long)s_drawFrameCount, + (int)waitRes, VkResultStr(waitRes), currentFrame); +#endif + } - // 2. 获取交换链图像 - 使用当前帧的信号量 + // 2. 获取交换链图像 uint32_t imageIndex; - VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX,imageAvailableSemaphores[currentFrame],VK_NULL_HANDLE, &imageIndex); - + VkResult result = vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphores[currentFrame], VK_NULL_HANDLE, &imageIndex); if (result != VK_SUCCESS) { +#ifndef _WIN32 + DebugLog::log_throttled("drawFrame.acquire", + "drawFrame[%llu] vkAcquireNextImageKHR -> %d (%s) currentFrame=%u", + (unsigned long long)s_drawFrameCount, + (int)result, VkResultStr(result), currentFrame); +#endif throw std::runtime_error("failed to acquire swap chain image!"); } @@ -512,7 +772,6 @@ void Application::drawFrame(long long frameTime) if (imagesInFlight[imageIndex] != VK_NULL_HANDLE) { vkWaitForFences(device, 1, &imagesInFlight[imageIndex], VK_TRUE, UINT64_MAX); } - // 标记该图像正在被当前帧使用 imagesInFlight[imageIndex] = inFlightFences[currentFrame]; // 4. 重置栅栏 @@ -525,40 +784,57 @@ void Application::drawFrame(long long frameTime) // 6. 提交命令缓冲区 VkSubmitInfo submitInfo{}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - - // 等待图像获取完成 VkSemaphore waitSemaphores[] = { imageAvailableSemaphores[currentFrame] }; VkPipelineStageFlags waitStages[] = { VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT }; submitInfo.waitSemaphoreCount = 1; submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitDstStageMask = waitStages; - submitInfo.commandBufferCount = 1; submitInfo.pCommandBuffers = &commandBuffers[currentFrame]; - - // 使用对应图像的渲染完成信号量 VkSemaphore signalSemaphores[] = { renderFinishedSemaphores[imageIndex] }; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = signalSemaphores; - if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]) != VK_SUCCESS) { + // 串行化 graphicsQueue/presentQueue 的 submit 与 present, + // 确保与 copyBuffer / updateTexture 等其它线程的队列提交互斥, + // 避免驱动内部 pthread_mutex 在长时间并发下被破坏。 + VkResult submitRes; + { + std::lock_guard poolLock(poolQueueMtx); + submitRes = vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFences[currentFrame]); + } + if (submitRes != VK_SUCCESS) { +#ifndef _WIN32 + DebugLog::log_throttled("drawFrame.submit", + "drawFrame[%llu] vkQueueSubmit -> %d (%s) currentFrame=%u imageIndex=%u", + (unsigned long long)s_drawFrameCount, + (int)submitRes, VkResultStr(submitRes), + currentFrame, imageIndex); +#endif throw std::runtime_error("failed to submit draw command buffer!"); } - // 7. 呈现图像 VkPresentInfoKHR presentInfo{}; presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; presentInfo.waitSemaphoreCount = 1; - presentInfo.pWaitSemaphores = signalSemaphores; // 等待对应图像的渲染完成信号量 - + presentInfo.pWaitSemaphores = signalSemaphores; VkSwapchainKHR swapChains[] = { swapChain }; presentInfo.swapchainCount = 1; presentInfo.pSwapchains = swapChains; presentInfo.pImageIndices = &imageIndex; - - result = vkQueuePresentKHR(presentQueue, &presentInfo); + { + std::lock_guard poolLock(poolQueueMtx); + result = vkQueuePresentKHR(presentQueue, &presentInfo); + } if (result != VK_SUCCESS) { +#ifndef _WIN32 + DebugLog::log_throttled("drawFrame.present", + "drawFrame[%llu] vkQueuePresentKHR -> %d (%s) currentFrame=%u imageIndex=%u", + (unsigned long long)s_drawFrameCount, + (int)result, VkResultStr(result), + currentFrame, imageIndex); +#endif throw std::runtime_error("failed to present swap chain image!"); } @@ -581,7 +857,6 @@ void Application::cleanup() { vkDeviceWaitIdle(device); - // 正确销毁所有同步对象 for (size_t i = 0; i < MAX_FRAMES_IN_FLIGHT; i++) { vkDestroySemaphore(device, imageAvailableSemaphores[i], nullptr); vkDestroySemaphore(device, renderFinishedSemaphores[i], nullptr); @@ -599,12 +874,23 @@ void Application::cleanup() { vkDestroyImageView(device, imageView, nullptr); } + for (auto framebuffer : swapChainFramebuffers) + { + if (framebuffer != VK_NULL_HANDLE) + { + vkDestroyFramebuffer(device, framebuffer, nullptr); + } + } + swapChainFramebuffers.clear(); + vkDestroySwapchainKHR(device, swapChain, nullptr); vkDestroyDevice(device, nullptr); vkDestroySurfaceKHR(instance, surface, nullptr); vkDestroyInstance(instance, nullptr); + + #ifdef _WIN32 glfwDestroyWindow(window); glfwTerminate(); @@ -630,24 +916,33 @@ uint32_t Application::findMemoryType(VkPhysicalDevice physicalDevice, uint32_t t throw std::runtime_error("Failed to find suitable memory type!"); } -Texture Application::loadTexture(std::string path, Texture& tex, bool srgb) +void Application::loadTexture(std::string path, Texture& tex, bool srgb, VkCommandPool pool) { std::vector data = readFileUnsignedChar(path, false); std::vector image; unsigned w, h; unsigned error = lodepng::decode(image, w, h, data, LCT_RGBA, 8); - processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, srgb); - return tex; + processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, srgb, pool, path); + //return tex; } + +void Application::loadTexture(std::vector& image_data, size_t image_size, int w, int h, Texture& tex, bool srgb, VkCommandPool pool, std::string path) +{ + processWithVulkan(image_data.data(), w, h, w * 4, image_size, tex, srgb, pool, path); + //return tex; +} + #ifdef _WIN32 -Texture Application::loadTextureExample(std::wstring path, Texture& tex, bool srgb) +void Application::loadTextureExample(std::wstring path, Texture& tex, bool srgb, VkCommandPool pool) { std::vector data = readFileUnsignedCharWin32(path, true); std::vector image; unsigned w, h; unsigned error = lodepng::decode(image, w, h, data, LCT_RGBA, 8); - processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, srgb); - return tex; + std::wstring_convert> converter; + std::string str = converter.to_bytes(path); + processWithVulkan(image.data(), w, h, w * 4, image.size(), tex, srgb, pool, str); + //return tex; } #endif // _WIN32 @@ -655,7 +950,7 @@ Texture Application::loadTextureExample(std::wstring path, Texture& tex, bool sr -void Application::createTexture(VkDevice device, VkPhysicalDevice physicalDevice, int width, int height, Texture& texture, bool srgb) +void Application::createTexture(VkDevice device, VkPhysicalDevice physicalDevice, int width, int height, Texture& texture, bool srgb, std::string tex_path, size_t dataSize) { texture.width = width; texture.height = height; @@ -702,6 +997,8 @@ void Application::createTexture(VkDevice device, VkPhysicalDevice physicalDevice throw std::runtime_error("Failed to allocate image memory!"); } + std::cout << "vkAllocateMemory device_memory " << tex_path << ": " << texture.device_memory << std::endl; + vkBindImageMemory(device, texture.image, texture.device_memory, 0); VkImageViewCreateInfo viewInfo = {}; @@ -750,20 +1047,56 @@ void Application::createTexture(VkDevice device, VkPhysicalDevice physicalDevice throw std::runtime_error("Failed to create texture sampler!"); } - texture.image_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; -} - -void Application::processWithVulkan(uint8_t* data, int width, int height, int rowStride, size_t dataSize, Texture& out_texture, bool srgb) -{ - std::unique_lock lock(mtx); - if (out_texture.image == VK_NULL_HANDLE) + if (texture.stagingBuffer == nullptr) { - createTexture(device, physicalDevice, width, height, out_texture, srgb); + VkBufferCreateInfo bufferInfo = {}; + bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; + bufferInfo.size = dataSize; + bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; + bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; + if (vkCreateBuffer(device, &bufferInfo, nullptr, &texture.stagingBuffer) != VK_SUCCESS) + { + throw std::runtime_error("Failed to create staging buffer!"); + } } - updateTexture(device, physicalDevice, commandPool, graphicsQueue, data, width, height, - rowStride, dataSize, out_texture); + if (texture.stagingBufferMemory == nullptr) + { + VkMemoryRequirements memRequirements; + vkGetBufferMemoryRequirements(device, texture.stagingBuffer, &memRequirements); + + VkMemoryAllocateInfo allocInfo = {}; + allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; + allocInfo.allocationSize = memRequirements.size; + allocInfo.memoryTypeIndex = findMemoryType(physicalDevice, + memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); + + if (vkAllocateMemory(device, &allocInfo, nullptr, &texture.stagingBufferMemory) != VK_SUCCESS) + { + throw std::runtime_error("Failed to allocate staging buffer memory!"); + } + + std::cout << "vkAllocateMemory stagingBufferMemory " << tex_path << ": " << texture.stagingBufferMemory << std::endl; + + vkBindBufferMemory(device, texture.stagingBuffer, texture.stagingBufferMemory, 0); + } + + texture.image_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + texture.device = device; + texture.texture_path = tex_path; +} + +void Application::processWithVulkan(uint8_t* data, int width, int height, int rowStride, size_t dataSize, Texture& texture, bool srgb, VkCommandPool pool, std::string tex_path) +{ + std::unique_lock lock(createTextureMtx); + if (texture.image == VK_NULL_HANDLE) + { + createTexture(device, physicalDevice, width, height, texture, srgb, tex_path, dataSize); + } + + updateTexture(device, physicalDevice, pool, graphicsQueue, data, width, height, + rowStride, dataSize, texture); } @@ -803,44 +1136,195 @@ void Application::endSingleTimeCommands(VkDevice device, VkCommandPool commandPo vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer); } +void Application::createTransferResources() +{ + if (m_xferInited) { +#ifndef _WIN32 + DebugLog::log("createTransferResources: already inited, skip"); +#endif + return; + } + if (commandPool_ex == VK_NULL_HANDLE) { +#ifndef _WIN32 + DebugLog::log("createTransferResources: commandPool_ex is null, abort"); +#endif + throw std::runtime_error("createTransferResources: commandPool_ex not created yet"); + } + + VkCommandBufferAllocateInfo allocInfo{}; + allocInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO; + allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; + allocInfo.commandPool = commandPool_ex; + allocInfo.commandBufferCount = kTransferSlotCount; + if (vkAllocateCommandBuffers(device, &allocInfo, m_xferCmd) != VK_SUCCESS) { + throw std::runtime_error("createTransferResources: vkAllocateCommandBuffers failed"); + } + + // fence 创建为 SIGNALED:第一次 runTransferCommand 的 vkWaitForFences + // 会立刻返回,避免冷启动卡顿。 + VkFenceCreateInfo fenceInfo{}; + fenceInfo.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO; + fenceInfo.flags = VK_FENCE_CREATE_SIGNALED_BIT; + for (uint32_t i = 0; i < kTransferSlotCount; ++i) { + if (vkCreateFence(device, &fenceInfo, nullptr, &m_xferFence[i]) != VK_SUCCESS) { + for (uint32_t j = 0; j < i; ++j) { + vkDestroyFence(device, m_xferFence[j], nullptr); + m_xferFence[j] = VK_NULL_HANDLE; + } + vkFreeCommandBuffers(device, commandPool_ex, kTransferSlotCount, m_xferCmd); + for (uint32_t j = 0; j < kTransferSlotCount; ++j) m_xferCmd[j] = VK_NULL_HANDLE; + throw std::runtime_error("createTransferResources: vkCreateFence failed"); + } + } + + m_xferIdx = 0; + m_xferInited = true; +#ifndef _WIN32 + DebugLog::log("createTransferResources: done, slots=%u pool=commandPool_ex", + (unsigned)kTransferSlotCount); +#endif +} + +void Application::destroyTransferResources() +{ + if (!m_xferInited) { + return; + } + // 调用方必须保证 GPU 已 idle 且没有线程正在 runTransferCommand。 + // 这里再加一道 m_xferMtx,串行化潜在的最后一次 transfer。 + std::lock_guard xferLock(m_xferMtx); + + for (uint32_t i = 0; i < kTransferSlotCount; ++i) { + if (m_xferFence[i] != VK_NULL_HANDLE) { + vkDestroyFence(device, m_xferFence[i], nullptr); + m_xferFence[i] = VK_NULL_HANDLE; + } + } + if (m_xferCmd[0] != VK_NULL_HANDLE && commandPool_ex != VK_NULL_HANDLE) { + vkFreeCommandBuffers(device, commandPool_ex, kTransferSlotCount, m_xferCmd); + } + for (uint32_t i = 0; i < kTransferSlotCount; ++i) { + m_xferCmd[i] = VK_NULL_HANDLE; + } + m_xferIdx = 0; + m_xferInited = false; +#ifndef _WIN32 + DebugLog::log("destroyTransferResources: done"); +#endif +} + +void Application::runTransferCommand(const std::function& record) +{ + if (!m_xferInited) { +#ifndef _WIN32 + DebugLog::log_throttled("runTransferCommand.notInited", + "runTransferCommand: not inited, skip"); +#endif + return; + } + + // 串行化所有 transfer 调用: + // - 保证 m_xferIdx 推进 / m_xferCmd[idx] 录制 / m_xferFence[idx] 等待 + // 形成一组原子动作; + // - 同时也保证 commandPool_ex 的「外部同步」语义(同一时刻只允许一个 + // 线程对它做 record/reset)。 + std::lock_guard xferLock(m_xferMtx); + + const uint32_t idx = m_xferIdx; + VkFence fence = m_xferFence[idx]; + VkCommandBuffer cmd = m_xferCmd[idx]; + + // 等上一次该 slot 的提交真正完成。fence 是独立同步对象,不需要持 + // poolQueueMtx 就可以等待,drawFrame 的 submit 不会被阻塞。 + VkResult wr = vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX); + if (wr != VK_SUCCESS) { +#ifndef _WIN32 + DebugLog::log_throttled("runTransferCommand.wait", + "runTransferCommand: vkWaitForFences slot=%u -> %d", + idx, (int)wr); +#endif + } + + vkResetFences(device, 1, &fence); + vkResetCommandBuffer(cmd, 0); + + VkCommandBufferBeginInfo beginInfo{}; + beginInfo.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO; + beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; + if (vkBeginCommandBuffer(cmd, &beginInfo) != VK_SUCCESS) { +#ifndef _WIN32 + DebugLog::log_throttled("runTransferCommand.begin", + "runTransferCommand: vkBeginCommandBuffer slot=%u failed", idx); +#endif + return; + } + + // 调用方在这里 record 命令:vkCmdCopyBuffer / vkCmdCopyBufferToImage / + // transitionImageLayout 等。这些是纯 record 操作,在 m_xferMtx 持有 + // 且 cmd 独占的前提下不需要再额外加锁。 + record(cmd); + + if (vkEndCommandBuffer(cmd) != VK_SUCCESS) { +#ifndef _WIN32 + DebugLog::log_throttled("runTransferCommand.end", + "runTransferCommand: vkEndCommandBuffer slot=%u failed", idx); +#endif + return; + } + + VkSubmitInfo submitInfo{}; + submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &cmd; + + // vkQueueSubmit 必须和 drawFrame 的 vkQueueSubmit / vkQueuePresentKHR + // 互斥(队列要求外部同步)。其它步骤只占 m_xferMtx 即可。 + { + std::lock_guard poolLock(poolQueueMtx); + VkResult sr = vkQueueSubmit(graphicsQueue, 1, &submitInfo, fence); + if (sr != VK_SUCCESS) { +#ifndef _WIN32 + DebugLog::log_throttled("runTransferCommand.submit", + "runTransferCommand: vkQueueSubmit slot=%u -> %d", + idx, (int)sr); +#endif + } + } + + // ★ 关键:调用方代码(FaceApp::uploadVertexData / Application::updateTexture) + // 在 runTransferCommand 之后会立刻 vkMapMemory + memcpy 覆写共享的 + // staging buffer,去做下一次拷贝。所以本接口必须像旧的 vkQueueWaitIdle + // 一样保证 GPU **已读完** staging 才能返回,否则覆写会 race 上 GPU + // 还在执行的 vkCmdCopyBuffer / vkCmdCopyBufferToImage,导致顶点 / 纹理 + // 数据被错位拼接(外观就是模型畸形 / 纹理花屏)。 + // + // 这里只等自己这一次的 fence,不像旧实现 vkQueueWaitIdle 那样等整个 + // graphicsQueue(包括 drawFrame 的提交),所以不会拖慢渲染主路径。 + // + // 不持 poolQueueMtx:fence 是独立同步对象,等它不需要外部互斥。 + VkResult er = vkWaitForFences(device, 1, &fence, VK_TRUE, UINT64_MAX); + if (er != VK_SUCCESS) { +#ifndef _WIN32 + DebugLog::log_throttled("runTransferCommand.endWait", + "runTransferCommand: end vkWaitForFences slot=%u -> %d", + idx, (int)er); +#endif + } + + m_xferIdx = (idx + 1) % kTransferSlotCount; +} + void Application::updateTexture(VkDevice device, VkPhysicalDevice physicalDevice, VkCommandPool commandPool, VkQueue queue, uint8_t* data, int width, int height, int rowStride, size_t dataSize, Texture& texture) { - VkBuffer stagingBuffer; - VkDeviceMemory stagingBufferMemory; - - VkBufferCreateInfo bufferInfo = {}; - bufferInfo.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; - bufferInfo.size = dataSize; - bufferInfo.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT; - bufferInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE; - - if (vkCreateBuffer(device, &bufferInfo, nullptr, &stagingBuffer) != VK_SUCCESS) - { - throw std::runtime_error("Failed to create staging buffer!"); - } - - VkMemoryRequirements memRequirements; - vkGetBufferMemoryRequirements(device, stagingBuffer, &memRequirements); - - VkMemoryAllocateInfo allocInfo = {}; - allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; - allocInfo.allocationSize = memRequirements.size; - allocInfo.memoryTypeIndex = findMemoryType(physicalDevice, - memRequirements.memoryTypeBits, VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); - - if (vkAllocateMemory(device, &allocInfo, nullptr, &stagingBufferMemory) != VK_SUCCESS) - { - throw std::runtime_error("Failed to allocate staging buffer memory!"); - } - - vkBindBufferMemory(device, stagingBuffer, stagingBufferMemory, 0); + //VkBuffer stagingBuffer; + //VkDeviceMemory stagingBufferMemory; void* mappedData; - vkMapMemory(device, stagingBufferMemory, 0, dataSize, 0, &mappedData); + vkMapMemory(device, texture.stagingBufferMemory, 0, dataSize, 0, &mappedData); if (rowStride == width * 4) { @@ -860,37 +1344,38 @@ void Application::updateTexture(VkDevice device, VkPhysicalDevice physicalDevice } } - vkUnmapMemory(device, stagingBufferMemory); + vkUnmapMemory(device, texture.stagingBufferMemory); - VkCommandBuffer commandBuffer = beginSingleTimeCommands(device, commandPool); + // 走 runTransferCommand:复用 commandPool_ex 上预分配的 cmdbuf + fence, + // 不再每帧 vkAllocate/vkFree,也不再 vkQueueWaitIdle。 + // 注意:传入的 commandPool / queue 参数保留只是为了兼容旧接口, + // 实际命令池一律换成 commandPool_ex(与渲染主管线物理隔离)。 + (void)commandPool; + (void)queue; + runTransferCommand([&](VkCommandBuffer commandBuffer) { + transitionImageLayout(commandBuffer, texture.image, + VK_IMAGE_LAYOUT_UNDEFINED, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); - transitionImageLayout(commandBuffer, texture.image, - VK_IMAGE_LAYOUT_UNDEFINED, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); + VkBufferImageCopy region = {}; + region.bufferOffset = 0; + region.bufferRowLength = 0; + region.bufferImageHeight = 0; + region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; + region.imageSubresource.mipLevel = 0; + region.imageSubresource.baseArrayLayer = 0; + region.imageSubresource.layerCount = 1; + region.imageOffset = { 0, 0, 0 }; + region.imageExtent = { static_cast(width), + static_cast(height), 1 }; - VkBufferImageCopy region = {}; - region.bufferOffset = 0; - region.bufferRowLength = 0; - region.bufferImageHeight = 0; - region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; - region.imageSubresource.mipLevel = 0; - region.imageSubresource.baseArrayLayer = 0; - region.imageSubresource.layerCount = 1; - region.imageOffset = { 0, 0, 0 }; - region.imageExtent = { static_cast(width), - static_cast(height), 1 }; + vkCmdCopyBufferToImage(commandBuffer, texture.stagingBuffer, texture.image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); - vkCmdCopyBufferToImage(commandBuffer, stagingBuffer, texture.image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion); - - transitionImageLayout(commandBuffer, texture.image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, - VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); - - endSingleTimeCommands(device, commandPool, queue, commandBuffer); - - vkDestroyBuffer(device, stagingBuffer, nullptr); - vkFreeMemory(device, stagingBufferMemory, nullptr); + transitionImageLayout(commandBuffer, texture.image, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + }); texture.image_layout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; } diff --git a/vulkan/Application.h b/vulkan/Application.h index 32416c6..4421b19 100644 --- a/vulkan/Application.h +++ b/vulkan/Application.h @@ -1,20 +1,26 @@ - + #pragma once #include "AppBase.h" #include #include +#include struct Texture { - VkSampler sampler; - VkImage image; - VkImageLayout image_layout; - VkDeviceMemory device_memory; - VkImageView view; - uint32_t width, height; - uint32_t mip_levels; + VkSampler sampler = VK_NULL_HANDLE; + VkImage image = VK_NULL_HANDLE; + VkImageLayout image_layout = VkImageLayout::VK_IMAGE_LAYOUT_UNDEFINED; + VkDeviceMemory device_memory = VK_NULL_HANDLE; + VkImageView view = VK_NULL_HANDLE; + uint32_t width = 0; + uint32_t height = 0; + uint32_t mip_levels = 0; + VkBuffer stagingBuffer = VK_NULL_HANDLE; + VkDeviceMemory stagingBufferMemory = VK_NULL_HANDLE; + VkDevice device = VK_NULL_HANDLE; + std::string texture_path; }; class Application : public AppBase @@ -41,9 +47,69 @@ public: void createSyncObjects(); virtual void drawFrame(long long frameTime); virtual void render(VkCommandBuffer commandBuffer, long long frameTime); - virtual bool isInited() { return inited; } + virtual bool isInited() { return _applicationInited; } + std::mutex createTextureMtx; + // 全局 GPU 提交互斥锁:任何对 graphicsQueue / presentQueue 的提交 + // (vkQueueSubmit / vkQueuePresentKHR / vkQueueWaitIdle)以及共享 + // commandPool 的 vkAllocateCommandBuffers / vkFreeCommandBuffers + // 都必须在持有此锁的期间执行,否则驱动内部维护命令池与队列的 + // pthread_mutex 在长时间多线程并发下会被破坏(FORTIFY: pthread_mutex_lock + // called on a destroyed mutex)。 + // 需要覆盖的 3 条并发线路: + // 1) 渲染线程 drawFrame + // 2) processImageNative → updateTexture (single-time commands) + // 3) passDataToNative → update_face_vertex_buffer → copyBuffer + std::mutex poolQueueMtx; + void processWithVulkan(uint8_t* data, int width, int height, int rowStride, size_t dataSize, Texture& texture, bool srgb, VkCommandPool pool, std::string tex_path); - void processWithVulkan(uint8_t* data, int width, int height, int rowStride, size_t dataSize, Texture& out_texture, bool srgb); + // --------------------------------------------------------------------- + // 复用式 single-time-command 接口(替代每帧 allocate+submit+waitIdle+free) + // + // ★ 同步语义(重要): + // 本接口 **同步**,返回时 GPU 已经读完 record 里访问的源数据。 + // 行为上等价于旧的 vkQueueSubmit + vkQueueWaitIdle,但只等自己这次 + // 提交的 fence,不阻塞渲染线程在 graphicsQueue 上的其它提交。 + // + // 为什么必须同步:调用方 (FaceApp::uploadVertexData / + // Application::updateTexture) 紧接着会复用同一个 staging buffer: + // + // vkMapMemory(staging); memcpy(staging, A); vkUnmapMemory; + // runTransferCommand([&](cmd){ vkCmdCopyBuffer(cmd, staging, dstA); }); + // vkMapMemory(staging); memcpy(staging, B); ← 必须等 dstA 拷完! + // vkUnmapMemory; + // runTransferCommand([&](cmd){ vkCmdCopyBuffer(cmd, staging, dstB); }); + // + // 如果 runTransferCommand 异步返回,第二次 memcpy 会在 GPU 还没读完 + // staging 里的 A 时就把它覆盖成 B —— 顶点 / 纹理立刻畸形。 + // + // 行为: + // - 共 kTransferSlotCount 个 VkCommandBuffer + 同数 VkFence, + // 从 commandPool_ex 一次性分配,在 cleanup 时一次性释放。 + // - 每次 runTransferCommand: + // 1) m_xferMtx.lock() (串行所有 transfer 提交) + // 2) 当前 slot 上 vkWaitForFences (等上一次该 slot 的提交完成) + // 3) vkResetFences + vkResetCommandBuffer + vkBegin + // 4) 调用 record(cmd) 录制命令 (vkCmdCopy* 等) + // 5) vkEndCommandBuffer + // 6) poolQueueMtx 内 vkQueueSubmit(graphicsQueue, fence) + // 7) vkWaitForFences(fence) (★ 等本次 GPU 完成才返回) + // 8) m_xferIdx 推进到下一个 slot + // + // 为什么这样设计: + // - 完全消除每帧 vkAllocateCommandBuffers / vkFreeCommandBuffers, + // 根除驱动 per-pool mutex 在长时间高频压力下被破坏导致的 + // FORTIFY: pthread_mutex_lock called on a destroyed mutex 崩溃。 + // - 用 fence 替代 vkQueueWaitIdle,等待粒度只到自己这一次提交, + // 不会 stall 整条 graphicsQueue(包括渲染主路径的提交)。 + // - 固定使用 commandPool_ex(与渲染主用的 commandPool 物理隔离), + // 即使驱动还有内部 contention,也不会波及渲染主管线。 + // + // 调用约束: + // - 调用方 **绝不能** 提前持有 poolQueueMtx;本接口内部按需短暂获取。 + // - record 函数体内只允许 vkCmd*(命令录制)这类操作,不要在里面调 + // queue / pool 级别的 API(submit / present / pool reset 等)。 + static constexpr uint32_t kTransferSlotCount = 3; + void runTransferCommand(const std::function& record); protected: @@ -61,8 +127,11 @@ protected: VkPipeline graphicsPipeline; // 图形管线 std::vector swapChainFramebuffers; // 帧缓冲区 VkQueue presentQueue; // 呈现队列 + bool _sceondInited = true; +public: VkCommandPool commandPool; + VkCommandPool commandPool_ex; std::vector commandBuffers; std::vector imageAvailableSemaphores; // 每个交换链图像一个 std::vector renderFinishedSemaphores; // 每个交换链图像一个 @@ -70,25 +139,63 @@ protected: std::vector imagesInFlight; // 跟踪每个图像的使用状态 int currentFrame = 0; int MAX_FRAMES_IN_FLIGHT = 2; - bool inited = false; - + bool _applicationInited = false; + void cleanupSecondInit(); + + // Tear down only the window-dependent Vulkan objects so we can survive an + // Android APP_CMD_TERM_WINDOW (screen off / background / rotate). + // Keeps renderPass / pipelines / VMA / textures / FaceApp resources intact, + // so pipelines created by FaceApp remain valid for the new swapchain. + // Caller MUST hold any app-level mutexes that serialize JNI -> Vulkan access. + void cleanupForWindowLost(); + + // Rebuild the window-dependent Vulkan objects torn down above. + // Safe to call only after cleanupForWindowLost(). + // Returns true when the new swapchain's extent or format differs from the + // one in use before cleanupForWindowLost(). When true, any pipeline baked + // with a static viewport/scissor from swapChainExtent -- including the + // FaceApp pipelines -- must be destroyed and recreated against the new + // renderPass / extent. Application's own renderPass + graphicsPipeline are + // already handled internally. + bool reinitForNewWindow(); + + // Extent / format captured by the most recent cleanupForWindowLost(). + // Used by reinitForNewWindow() to decide whether renderPass / pipelines + // must be rebuilt against the new swapchain. + VkExtent2D _prevSwapChainExtent = {0, 0}; + VkFormat _prevSwapChainImageFormat = VK_FORMAT_UNDEFINED; protected: - Texture loadTexture(std::string path, Texture& tex, bool srgb); + // Transfer command resources(详见 runTransferCommand 上方注释)。 + // 命令缓冲来自 commandPool_ex,与渲染主用的 commandPool 物理隔离。 + VkCommandBuffer m_xferCmd[kTransferSlotCount] = { VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE }; + VkFence m_xferFence[kTransferSlotCount] = { VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE }; + uint32_t m_xferIdx = 0; + bool m_xferInited = false; + std::mutex m_xferMtx; + + // 创建/销毁 transfer 资源。createTransferResources 必须在 createCommandPool + // 之后调用;destroyTransferResources 必须在销毁 commandPool_ex 之前调用, + // 且 GPU 已 idle(vkDeviceWaitIdle 或确认所有 fence 已 signaled)。 + void createTransferResources(); + void destroyTransferResources(); + +protected: + void loadTexture(std::string path, Texture& tex, bool srgb, VkCommandPool pool); + void loadTexture(std::vector& image_data, size_t image_size, int w, int h, Texture& tex, bool srgb, VkCommandPool pool, std::string path); #ifdef _WIN32 - Texture loadTextureExample(std::wstring path, Texture& tex, bool srgb); + void loadTextureExample(std::wstring path, Texture& tex, bool srgb, VkCommandPool pool); #endif uint32_t findMemoryType(VkPhysicalDevice physicalDevice, uint32_t typeFilter, VkMemoryPropertyFlags properties); - void createTexture(VkDevice device, VkPhysicalDevice physicalDevice, int width, int height, Texture& texture, bool srgb); + void createTexture(VkDevice device, VkPhysicalDevice physicalDevice, int width, int height, Texture& texture, bool srgb, std::string tex_path, size_t dataSize); void updateTexture(VkDevice device, VkPhysicalDevice physicalDevice, VkCommandPool commandPool, VkQueue queue, uint8_t* data, int width, int height, int rowStride, size_t dataSize, Texture& texture); VkCommandBuffer beginSingleTimeCommands(VkDevice device, VkCommandPool commandPool); void endSingleTimeCommands(VkDevice device, VkCommandPool commandPool, VkQueue queue, VkCommandBuffer commandBuffer); void transitionImageLayout(VkCommandBuffer commandBuffer, VkImage image, VkImageLayout oldLayout, VkImageLayout newLayout); void destroy_texture(Texture texture); - std::mutex mtx; + long long _lastDrawFrameTime; - - std::mutex changeMotionMtx; + }; \ No newline at end of file diff --git a/vulkan/FaceApp.cpp b/vulkan/FaceApp.cpp index 91fbdef..0df27f0 100644 --- a/vulkan/FaceApp.cpp +++ b/vulkan/FaceApp.cpp @@ -1,10 +1,20 @@ -#include "FaceApp.h" +#include "FaceApp.h" #include "hardcode_data.h" +#include "lodepng.h" #include #include #include #include +#ifndef _WIN32 +#include "../app/src/main/cpp/DebugLog.h" +#define FACE_DBG_LOG(...) DebugLog::log(__VA_ARGS__) +#define FACE_DBG_LOG_THROTTLED(key, ...) DebugLog::log_throttled(key, __VA_ARGS__) +#else +#define FACE_DBG_LOG(...) ((void)0) +#define FACE_DBG_LOG_THROTTLED(key, ...) ((void)0) +#endif + FaceApp* FaceApp::faceIns = nullptr; @@ -16,6 +26,22 @@ FaceApp::FaceApp(/* args */) FaceApp::~FaceApp() { + if(worker_.joinable()) + { + worker_.join(); + } +} + +void FaceApp::Stop() +{ + FACE_DBG_LOG("FaceApp::Stop called (_running=%d worker_joinable=%d)", + (int)_running, (int)worker_.joinable()); + _running = false; + if(worker_.joinable()) + { + worker_.join(); + } + FACE_DBG_LOG("FaceApp::Stop done"); } void ReceiveFacePoint(float* pos, int pointCount, int width, int height) @@ -105,7 +131,9 @@ void TextureLoadProcessWithVulkan(uint8_t* data, int width, int height, int rowS oldestFrame.rowStride, oldestFrame.dataSize, tex_bg, - false + false, + FaceApp::Get()->commandPool, + "data_from_camera" ); frameQueue.pop(); @@ -454,6 +482,10 @@ void FaceApp::create_face_pipelines() pipeline_create_info.pStages = shader_stages; VK_CHECK(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_create_info, nullptr, &m_graphicsPipeline)); + + // 销毁着色器模块 + vkDestroyShaderModule(device, fragShaderModule, nullptr); + vkDestroyShaderModule(device, vertShaderModule, nullptr); } @@ -515,13 +547,26 @@ void FaceApp::setup_descriptor_set_layout() pipeline_layout_create_info.setLayoutCount = 1; pipeline_layout_create_info.pSetLayouts = &m_descriptorSetLayout; - VkPushConstantRange pushConstantRange{}; - pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; - pushConstantRange.offset = 0; - pushConstantRange.size = sizeof(float); + //VkPushConstantRange pushConstantRange{}; + //pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + //pushConstantRange.offset = 0; + //pushConstantRange.size = sizeof(float); + + //pipeline_layout_create_info.pushConstantRangeCount = 1; + //pipeline_layout_create_info.pPushConstantRanges = &pushConstantRange; + + VkPushConstantRange pushConstantRanges[1]; + pushConstantRanges[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT| VK_SHADER_STAGE_FRAGMENT_BIT; + pushConstantRanges[0].offset = 0; + pushConstantRanges[0].size = sizeof(PushConstants); + + //pushConstantRanges[1].stageFlags = VK_SHADER_STAGE_FRAGMENT_BIT; + //pushConstantRanges[1].offset = sizeof(float); + //pushConstantRanges[1].size = 2*sizeof(float); + pipeline_layout_create_info.pushConstantRangeCount = 1; - pipeline_layout_create_info.pPushConstantRanges = &pushConstantRange; + pipeline_layout_create_info.pPushConstantRanges = &pushConstantRanges[0]; VK_CHECK(vkCreatePipelineLayout(device, &pipeline_layout_create_info, nullptr, &m_pipelineLayout)); } @@ -532,11 +577,11 @@ void FaceApp::setup_descriptor_pool() std::vector pool_sizes = { { .type = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, - .descriptorCount = kMaxTexture + .descriptorCount = (kTextureMax *2) }, { .type = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, - .descriptorCount = (kMaxTexture + 1) + .descriptorCount = ((kTextureMax + 1)*2) }, // 如果需要其他类型的描述符,在这里添加 }; @@ -545,7 +590,7 @@ void FaceApp::setup_descriptor_pool() descriptor_pool_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO; descriptor_pool_info.poolSizeCount = static_cast(pool_sizes.size()); descriptor_pool_info.pPoolSizes = pool_sizes.data(); - descriptor_pool_info.maxSets = kMaxTexture + (kMaxTexture + 1); + descriptor_pool_info.maxSets = kTextureMax + (kTextureMax + 1 + kTextureMax); descriptor_pool_info.flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT; VK_CHECK(vkCreateDescriptorPool(device, &descriptor_pool_info, nullptr, &descriptor_pool)); @@ -554,17 +599,31 @@ void FaceApp::setup_descriptor_pool() void FaceApp::setup_descriptor_set() { - m_descriptor_sets.resize(kMaxTexture); - std::vector layouts(kMaxTexture, m_descriptorSetLayout); + m_descriptor_sets_left.resize(kTextureMax); + std::vector layouts(kTextureMax, m_descriptorSetLayout); VkDescriptorSetAllocateInfo alloc_info{}; alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO; alloc_info.descriptorPool = descriptor_pool; alloc_info.pSetLayouts = layouts.data(); - alloc_info.descriptorSetCount = m_descriptor_sets.size(); - VK_CHECK(vkAllocateDescriptorSets(device, &alloc_info, m_descriptor_sets.data())); + alloc_info.descriptorSetCount = m_descriptor_sets_left.size(); + VK_CHECK(vkAllocateDescriptorSets(device, &alloc_info, m_descriptor_sets_left.data())); + update_descriptor_set(m_texs_left, m_descriptor_sets_left); - for (int i = 0; i < kMaxTexture; ++i) + + //m_descriptor_sets_right.resize(kTextureMax); + //VK_CHECK(vkAllocateDescriptorSets(device, &alloc_info, m_descriptor_sets_right.data())); + //update_descriptor_set(m_texs_left, m_descriptor_sets_right); +} + +void FaceApp::update_descriptor_set(vector& texs, vector& descriptSet) +{ + for (int i = 0; i < texs.size(); ++i) { + if (texs[i].image == VK_NULL_HANDLE) + { + break; + } + VkDescriptorBufferInfo buffer_descriptor{}; buffer_descriptor.buffer = uniform_buffer_vs; buffer_descriptor.range = VK_WHOLE_SIZE; @@ -572,13 +631,13 @@ void FaceApp::setup_descriptor_set() VkDescriptorImageInfo image_descriptor; - image_descriptor.imageView = m_texs[i].view; - image_descriptor.sampler = m_texs[i].sampler; - image_descriptor.imageLayout = m_texs[i].image_layout; + image_descriptor.imageView = texs[i].view; + image_descriptor.sampler = texs[i].sampler; + image_descriptor.imageLayout = texs[i].image_layout; VkWriteDescriptorSet write_descriptor_set_uniform{}; write_descriptor_set_uniform.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptor_set_uniform.dstSet = m_descriptor_sets[i]; + write_descriptor_set_uniform.dstSet = descriptSet[i]; write_descriptor_set_uniform.descriptorType = VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER; write_descriptor_set_uniform.dstBinding = 0; write_descriptor_set_uniform.pBufferInfo = &buffer_descriptor; @@ -587,7 +646,7 @@ void FaceApp::setup_descriptor_set() VkWriteDescriptorSet write_descriptor_set_image{}; write_descriptor_set_image.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptor_set_image.dstSet = m_descriptor_sets[i]; + write_descriptor_set_image.dstSet = descriptSet[i]; write_descriptor_set_image.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; write_descriptor_set_image.dstBinding = 1; write_descriptor_set_image.pImageInfo = &image_descriptor; @@ -597,14 +656,14 @@ void FaceApp::setup_descriptor_set() { // 第二个纹理描述符 - 假设你的第二个纹理变量名为 tex_demo1 VkDescriptorImageInfo image_descriptor1; - image_descriptor1.imageView = m_texs_ex[i].view; - image_descriptor1.sampler = m_texs_ex[i].sampler; - image_descriptor1.imageLayout = m_texs_ex[i].image_layout; + image_descriptor1.imageView = m_texs_thick[i].view; + image_descriptor1.sampler = m_texs_thick[i].sampler; + image_descriptor1.imageLayout = m_texs_thick[i].image_layout; // 添加第二个纹理的写入描述符 VkWriteDescriptorSet write_descriptor_set_image1{}; write_descriptor_set_image1.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - write_descriptor_set_image1.dstSet = m_descriptor_sets[i]; + write_descriptor_set_image1.dstSet = descriptSet[i]; write_descriptor_set_image1.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; write_descriptor_set_image1.dstBinding = 2; // 绑定到位置2 write_descriptor_set_image1.pImageInfo = &image_descriptor1; @@ -630,42 +689,58 @@ void FaceApp::setup_descriptor_set() vkUpdateDescriptorSets(device, static_cast(write_descriptor_sets.size()), write_descriptor_sets.data(), 0, NULL); } - - - - - - - - } - - } void FaceApp::render(VkCommandBuffer commandBuffer, long long frameTime) { - std::unique_lock lock(mtx); - std::unique_lock lock_point(mtx_point); - //Application::render(commandBuffer); vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout_bg, 0, 1, &m_descriptor_set_bg, 0, NULL); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline_bg); + vkCmdPushConstants(commandBuffer, m_pipelineLayout_bg, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(pushConstants), &pushConstants); - - vkCmdPushConstants(commandBuffer, m_pipelineLayout_bg, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(float), &myFloatValue); + vkCmdDraw(commandBuffer, 6, 1, 0, 0); + if (!_isChangeMostion) + { + return; + } + + string curMotionName = _curMotions[_curMotionIndex].name; + int loadMotionIndex = motion_list_map[curMotionName]; + //if (cur_left) + //{ + vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, &m_descriptor_sets_left[loadMotionIndex], 0, NULL); + //} + //else + //{ + // vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, &m_descriptor_sets_right[_curMotionIndex], 0, NULL); + //} + + //float fsValues[3] = { myFloatValue, 0 , 0}; + if (_curMotionIndex < _curMotions.size()) + { + if (_curFrameIndex < _curMotions[_curMotionIndex].frames.size()) + { + float ux = _curMotions[_curMotionIndex].frames[_curFrameIndex].x; + float uy = _curMotions[_curMotionIndex].frames[_curFrameIndex].y; + pushConstants.ux = ux; + pushConstants.uy = uy; + } + } + //fsValues[1] = 0; + //fsValues[2] = 360; + + vkCmdPushConstants(commandBuffer, m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT| VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(pushConstants), &pushConstants); + //vkCmdPushConstants(commandBuffer, m_pipelineLayout, VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(fsValues), fsValues); - vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_pipelineLayout, 0, 1, &m_descriptor_sets[_curTexIndex], 0, NULL); vkCmdBindPipeline(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_graphicsPipeline); - vkCmdPushConstants(commandBuffer, m_pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(float), &myFloatValue); - VkDeviceSize offsets[1] = { 0 }; VkBuffer vertexBuffers[] = { m_vertexBuffer }; vkCmdBindVertexBuffers(commandBuffer, 0, 1, vertexBuffers, offsets); @@ -709,47 +784,182 @@ void FaceApp::createVmaAllocator() void FaceApp::initVulkan() { + static int s_initVulkanCallCount = 0; + ++s_initVulkanCallCount; + FACE_DBG_LOG("FaceApp::initVulkan enter, call#%d _applicationInited=%d _faceAppInited=%d _secondfaceAppInited=%d", + s_initVulkanCallCount, (int)_applicationInited, (int)_faceAppInited, (int)_secondfaceAppInited); + Application::initVulkan(); - createVmaAllocator(); - LoadOBJ("face_picture_3dmax.obj", obj_vertices, obj_indices); - m_texs.resize(kMaxTexture); - m_texs_ex.resize(kMaxTexture); - for (int i = 0; i < kMaxTexture; ++i) + + if (!_faceAppInited) { - loadTexture("demo0.png", m_texs[i], true); - loadTexture("demo0_ex.png", m_texs_ex[i], true); - } - - loadTexture("out.png", tex_bg, true); - createVertexBuffer(); - createUniformBuffer(); - setup_descriptor_pool(); + createVmaAllocator(); + LoadOBJ("face_picture_3dmax.obj", obj_vertices, obj_indices); + //m_texs_left.resize(kTextureMax); + //m_texs_right.resize(kTextureMax); + if (kThick) + { + m_texs_thick.resize(kTextureMax); + } - setup_descriptor_set_layout(); - setup_descriptor_set(); - create_face_pipelines(); + std::vector data = readFileUnsignedChar("dummy.png", false); + unsigned error = lodepng::decode(dummy_data, dummy_w, dummy_h, data, LCT_RGBA, 8); - setup_descriptor_set_layout_bg(); - setup_descriptor_set_bg(); - create_pipelines_bg(); + for (int i = 0; i < kTextureInit; ++i) + { + //string id_str = std::to_string(i); + //loadTexture(dummy_data, dummy_data.size(), dummy_w, dummy_h, m_texs_left[i], true, commandPool, "dummy.png_left_" + id_str); + //loadTexture(dummy_data, dummy_data.size(), dummy_w, dummy_h, m_texs_right[i], true, commandPool, "dummy.png_right_" + id_str); + if (kThick) + { + //loadTexture(dummy_data, dummy_data.size(), dummy_w, dummy_h, m_texs_thick[i], true, commandPool, "dummy.png_thick_" + id_str); + } + } - uploadVertexData(); - last_update_time = getCurrentTimeMillis(); + loadTexture("out.png", tex_bg, true, commandPool); + createVertexBuffer(); + createUniformBuffer(); + setup_descriptor_pool(); + + setup_descriptor_set_layout(); + setup_descriptor_set(); + create_face_pipelines(); + + setup_descriptor_set_layout_bg(); + setup_descriptor_set_bg(); + create_pipelines_bg(); + + uploadVertexData(); + last_update_time = getCurrentTimeMillis(); + + //changeMotion(_initArg.motion); + Start(); + _faceAppInited = true; - changeMotion(_initArg.motion); - faceAppInited = true; #if _WIN32 - std::vector floatArray; - std::string& str = HardCodeData::Get().face_result_point_str; - std::stringstream ss(str); - std::string token; - while (std::getline(ss, token, ',')) { - floatArray.push_back(std::stof(token)); - } + std::vector floatArray; + std::string& str = HardCodeData::Get().face_result_point_str; + std::stringstream ss(str); + std::string token; + while (std::getline(ss, token, ',')) { + floatArray.push_back(std::stof(token)); + } - //ReceiveFacePoint(floatArray.data(), floatArray.size() / 3, 480, 480); + //ReceiveFacePoint(floatArray.data(), floatArray.size() / 3, 480, 480); #endif + } + + if (!_secondfaceAppInited) + { + Start(); + _playMotion = true; + _secondfaceAppInited = true; + } + + FACE_DBG_LOG("FaceApp::initVulkan exit, call#%d _applicationInited=%d _faceAppInited=%d _secondfaceAppInited=%d", + s_initVulkanCallCount, (int)_applicationInited, (int)_faceAppInited, (int)_secondfaceAppInited); +} + +void FaceApp::clearnSecondFaceApp() +{ + FACE_DBG_LOG("FaceApp::clearnSecondFaceApp: _secondfaceAppInited %d -> 0", + (int)_secondfaceAppInited); + _secondfaceAppInited = false; +} + +void FaceApp::Start() +{ + FACE_DBG_LOG("FaceApp::Start: _running %d -> 1", (int)_running); + _running = true; +} + +void FaceApp::onWindowLost() +{ + FACE_DBG_LOG("FaceApp::onWindowLost enter _applicationInited=%d _faceAppInited=%d _sceondInited=%d _secondfaceAppInited=%d _running=%d", + (int)_applicationInited, (int)_faceAppInited, (int)_sceondInited, + (int)_secondfaceAppInited, (int)_running); + + // Stop the render loop from touching Vulkan while we tear down. + _running = false; + + // Serialize against JNI callbacks that may concurrently submit GPU work + // via commandPool / commandPool_ex (processImageNative -> update texture, + // passDataToNative -> update vertex buffer, changeMotionList). + std::unique_lock lk_point(mtx_point); + std::unique_lock lk_motion(changeMotionMtx); + std::unique_lock lk_tex(createTextureMtx); + // 同时阻塞所有并发的 GPU 提交(drawFrame / copyBuffer / updateTexture)。 + // cleanupForWindowLost() 会执行 vkDeviceWaitIdle 并销毁 swapchain / surface / + // semaphores / fences 等窗口相关资源,如果此时有其它线程正在 vkQueueSubmit + // 或 vkQueuePresentKHR,会触发 FORTIFY: pthread_mutex_lock called on a + // destroyed mutex。这里持锁确保销毁与提交是互斥的。 + std::unique_lock lk_pool(poolQueueMtx); + + Application::cleanupForWindowLost(); + _secondfaceAppInited = false; + + FACE_DBG_LOG("FaceApp::onWindowLost done"); +} + +void FaceApp::onWindowInit() +{ + FACE_DBG_LOG("FaceApp::onWindowInit enter _applicationInited=%d _faceAppInited=%d _sceondInited=%d _secondfaceAppInited=%d", + (int)_applicationInited, (int)_faceAppInited, (int)_sceondInited, + (int)_secondfaceAppInited); + + if (!_applicationInited) { + // First-time path: go through the full initVulkan pipeline. + initVulkan(); + } else { + // Recovery path after an earlier onWindowLost. Rebuild only the + // window-dependent Vulkan objects; keep renderPass / pipelines / + // FaceApp GPU resources intact unless the new swapchain is + // incompatible (e.g. rotation changed extent). + std::unique_lock lk_point(mtx_point); + std::unique_lock lk_motion(changeMotionMtx); + std::unique_lock lk_tex(createTextureMtx); + + bool swapchainIncompatible = Application::reinitForNewWindow(); + + if (swapchainIncompatible && _faceAppInited) { + FACE_DBG_LOG("FaceApp::onWindowInit: swapchain incompatible, rebuilding FaceApp pipelines"); + recreatePipelinesForSwapchain(); + } + + if (!_secondfaceAppInited) { + _secondfaceAppInited = true; + _playMotion = true; + _running = true; + } + } + + FACE_DBG_LOG("FaceApp::onWindowInit done _applicationInited=%d _faceAppInited=%d _sceondInited=%d _secondfaceAppInited=%d _running=%d", + (int)_applicationInited, (int)_faceAppInited, (int)_sceondInited, + (int)_secondfaceAppInited, (int)_running); +} + +void FaceApp::recreatePipelinesForSwapchain() +{ + // Destroy the two FaceApp pipelines. Layouts / descriptor set layouts are + // swapchain-independent and kept as-is so existing descriptor sets keep + // pointing at the same texture/uniform resources. + if (m_graphicsPipeline != VK_NULL_HANDLE) { + vkDestroyPipeline(device, m_graphicsPipeline, nullptr); + m_graphicsPipeline = VK_NULL_HANDLE; + } + if (m_graphicsPipeline_bg != VK_NULL_HANDLE) { + vkDestroyPipeline(device, m_graphicsPipeline_bg, nullptr); + m_graphicsPipeline_bg = VK_NULL_HANDLE; + } + + // Recreate against the fresh renderPass (if format changed) and the new + // swapChainExtent (viewport/scissor are baked statically into these). + create_face_pipelines(); + create_pipelines_bg(); + + FACE_DBG_LOG("FaceApp::recreatePipelinesForSwapchain: rebuilt for extent=%ux%u", + swapChainExtent.width, swapChainExtent.height); } void FaceApp::update_uniform_buffers() @@ -849,42 +1059,20 @@ void FaceApp::update_face_vertex_buffer(float* pos, int pointCount) void FaceApp::copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size) { - VkCommandBuffer commandBuffer = beginSingleTimeCommands(); - - VkBufferCopy copyRegion = {}; - copyRegion.size = size; - vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, ©Region); - - endSingleTimeCommands(commandBuffer); -} - -VkCommandBuffer FaceApp::beginSingleTimeCommands() { - VkCommandBufferAllocateInfo allocInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; - allocInfo.level = VK_COMMAND_BUFFER_LEVEL_PRIMARY; - allocInfo.commandPool = commandPool; - allocInfo.commandBufferCount = 1; - - VkCommandBuffer commandBuffer; - vkAllocateCommandBuffers(device, &allocInfo, &commandBuffer); - - VkCommandBufferBeginInfo beginInfo = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; - beginInfo.flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT; - - vkBeginCommandBuffer(commandBuffer, &beginInfo); - return commandBuffer; -} - -void FaceApp::endSingleTimeCommands(VkCommandBuffer commandBuffer) { - vkEndCommandBuffer(commandBuffer); - - VkSubmitInfo submitInfo = { VK_STRUCTURE_TYPE_SUBMIT_INFO }; - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &commandBuffer; - - vkQueueSubmit(graphicsQueue, 1, &submitInfo, VK_NULL_HANDLE); - vkQueueWaitIdle(graphicsQueue); - - vkFreeCommandBuffers(device, commandPool, 1, &commandBuffer); + // 改造说明: + // 旧实现是 vkAllocate(commandPool) + vkBegin + vkCmdCopyBuffer + vkEnd + + // vkQueueSubmit(graphicsQueue) + vkQueueWaitIdle + vkFree(commandPool) + // 每帧 update_face_vertex_buffer 会调两次 copyBuffer(顶点 + 索引), + // 长期高频 allocate/free 会把驱动 per-pool mutex 玩坏,触发 + // FORTIFY: pthread_mutex_lock called on a destroyed mutex。 + // + // 现在改走基类的 runTransferCommand,复用 commandPool_ex 上预分配的 + // 3 个 cmdbuf + fence,并发安全由 m_xferMtx + poolQueueMtx 联合保证。 + runTransferCommand([&](VkCommandBuffer commandBuffer) { + VkBufferCopy copyRegion = {}; + copyRegion.size = size; + vkCmdCopyBuffer(commandBuffer, srcBuffer, dstBuffer, 1, ©Region); + }); } void FaceApp::createUniformBuffer() @@ -1032,6 +1220,10 @@ void FaceApp::create_pipelines_bg() pipeline_create_info.pStages = shader_stages; VK_CHECK(vkCreateGraphicsPipelines(device, VK_NULL_HANDLE, 1, &pipeline_create_info, nullptr, &m_graphicsPipeline_bg)); + + // 销毁着色器模块 + vkDestroyShaderModule(device, fragShaderModule, nullptr); + vkDestroyShaderModule(device, vertShaderModule, nullptr); } void FaceApp::setup_descriptor_set_layout_bg() @@ -1059,13 +1251,13 @@ void FaceApp::setup_descriptor_set_layout_bg() pipeline_layout_create_info.pSetLayouts = &m_descriptorSetLayout_bg; - VkPushConstantRange pushConstantRange{}; - pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT; // 只在片段着色器中使用 - pushConstantRange.offset = 0; - pushConstantRange.size = sizeof(float); // 或者 sizeof(PushConstants) + VkPushConstantRange pushConstantRanges[1]; + pushConstantRanges[0].stageFlags = VK_SHADER_STAGE_VERTEX_BIT; + pushConstantRanges[0].offset = 0; + pushConstantRanges[0].size = sizeof(PushConstants); pipeline_layout_create_info.pushConstantRangeCount = 1; - pipeline_layout_create_info.pPushConstantRanges = &pushConstantRange; + pipeline_layout_create_info.pPushConstantRanges = &pushConstantRanges[0]; VK_CHECK(vkCreatePipelineLayout(device, &pipeline_layout_create_info, nullptr, &m_pipelineLayout_bg)); } @@ -1101,86 +1293,429 @@ void FaceApp::setup_descriptor_set_bg() vkUpdateDescriptorSets(device, static_cast(write_descriptor_sets.size()), write_descriptor_sets.data(), 0, NULL); } +void FaceApp::destroyTexture(VkDevice device, Texture& texture) { + // 注意销毁顺序:先销毁依赖对象,后销毁被依赖对象 + + // 1. 销毁采样器 + if (texture.sampler != VK_NULL_HANDLE) { + vkDestroySampler(device, texture.sampler, nullptr); + texture.sampler = VK_NULL_HANDLE; + } + + // 2. 销毁图像视图 + if (texture.view != VK_NULL_HANDLE) { + vkDestroyImageView(device, texture.view, nullptr); + texture.view = VK_NULL_HANDLE; + } + + // 3. 销毁图像 + if (texture.image != VK_NULL_HANDLE) { + vkDestroyImage(device, texture.image, nullptr); + texture.image = VK_NULL_HANDLE; + } + + // 4. 释放设备内存 + if (texture.device_memory != VK_NULL_HANDLE) { + vkFreeMemory(device, texture.device_memory, nullptr); + texture.device_memory = VK_NULL_HANDLE; + //std::cout << "vkFreeMemory device_memory " << texture.texture_path << std::endl; + } + + if (texture.stagingBuffer != VK_NULL_HANDLE) + { + vkDestroyBuffer(device, texture.stagingBuffer, nullptr); + texture.stagingBuffer = VK_NULL_HANDLE; + } + + if (texture.stagingBufferMemory != VK_NULL_HANDLE) + { + vkFreeMemory(device, texture.stagingBufferMemory, nullptr); + //std::cout << "vkFreeMemory stagingBufferMemory " << texture.texture_path << std::endl; + texture.stagingBufferMemory = VK_NULL_HANDLE; + } +} + +void FaceApp::cleanupResources(VkDevice device, VmaAllocator allocator) { + // 销毁图形管线 + if (m_graphicsPipeline != VK_NULL_HANDLE) { + vkDestroyPipeline(device, m_graphicsPipeline, nullptr); + m_graphicsPipeline = VK_NULL_HANDLE; + } + + // 销毁管线布局 + if (m_pipelineLayout != VK_NULL_HANDLE) { + vkDestroyPipelineLayout(device, m_pipelineLayout, nullptr); + m_pipelineLayout = VK_NULL_HANDLE; + } + + // 销毁描述符集布局 + if (m_descriptorSetLayout != VK_NULL_HANDLE) { + vkDestroyDescriptorSetLayout(device, m_descriptorSetLayout, nullptr); + m_descriptorSetLayout = VK_NULL_HANDLE; + } + + // 销毁图形管线 + if (m_graphicsPipeline_bg != VK_NULL_HANDLE) { + vkDestroyPipeline(device, m_graphicsPipeline_bg, nullptr); + m_graphicsPipeline_bg = VK_NULL_HANDLE; + } + + // 销毁管线布局 + if (m_pipelineLayout_bg != VK_NULL_HANDLE) { + vkDestroyPipelineLayout(device, m_pipelineLayout_bg, nullptr); + m_pipelineLayout_bg = VK_NULL_HANDLE; + } + + // 销毁描述符集布局 + if (m_descriptorSetLayout_bg != VK_NULL_HANDLE) { + vkDestroyDescriptorSetLayout(device, m_descriptorSetLayout_bg, nullptr); + m_descriptorSetLayout_bg = VK_NULL_HANDLE; + } + + // 销毁顶点缓冲区 + if (m_vertexBuffer != VK_NULL_HANDLE) { + vkDestroyBuffer(device, m_vertexBuffer, nullptr); + m_vertexBuffer = VK_NULL_HANDLE; + } + if (m_vertexBufferAllocation != VK_NULL_HANDLE) { + vmaFreeMemory(allocator, m_vertexBufferAllocation); + m_vertexBufferAllocation = VK_NULL_HANDLE; + } + + // 销毁暂存缓冲区 + if (m_stagingBuffer != VK_NULL_HANDLE) { + vkDestroyBuffer(device, m_stagingBuffer, nullptr); + m_stagingBuffer = VK_NULL_HANDLE; + } + if (m_stagingBufferAllocation != VK_NULL_HANDLE) { + vmaFreeMemory(allocator, m_stagingBufferAllocation); + m_stagingBufferAllocation = VK_NULL_HANDLE; + } + + // 销毁索引缓冲区 + if (m_indexBuffer != VK_NULL_HANDLE) { + vkDestroyBuffer(device, m_indexBuffer, nullptr); + m_indexBuffer = VK_NULL_HANDLE; + } + if (m_indexBufferAllocation != VK_NULL_HANDLE) { + vmaFreeMemory(allocator, m_indexBufferAllocation); + m_indexBufferAllocation = VK_NULL_HANDLE; + } + + if (descriptor_pool != VK_NULL_HANDLE) + { + vkDestroyDescriptorPool(device, descriptor_pool, nullptr); + descriptor_pool = VK_NULL_HANDLE; + } + + // 清空描述符集列表(不需要单独销毁,由描述符池管理) + m_descriptor_sets_left.clear(); + //m_descriptor_sets_right.clear(); +} void FaceApp::cleanup() { + FACE_DBG_LOG("FaceApp::cleanup enter"); vkDeviceWaitIdle(device); + + if (uniform_buffer_mapped != nullptr) + { + vmaUnmapMemory(allocator, uniform_buffer_allocation); + uniform_buffer_mapped = nullptr; + } + + if (uniform_buffer_vs != VK_NULL_HANDLE) + { + vmaDestroyBuffer(allocator, uniform_buffer_vs, uniform_buffer_allocation); + uniform_buffer_vs = VK_NULL_HANDLE; + uniform_buffer_allocation = VK_NULL_HANDLE; // 可选,但推荐重置 + } + + cleanupResources(device, allocator); + for (int i = 0; i < this->m_texs_left.size(); ++i) + { + destroyTexture(device, m_texs_left[i]); + } + + //for (int i = 0; i < this->m_texs_right.size(); ++i) + //{ + // destroyTexture(device, m_texs_right[i]); + //} + + destroyTexture(device, tex_bg); + // 必须在销毁 commandPool_ex 之前释放从它分配的 transfer cmdbuf + fence。 + // vkDeviceWaitIdle 已在本函数开头调过,提交不会再有 in-flight。 + destroyTransferResources(); vkDestroyCommandPool(device, commandPool, nullptr); - vkDestroyPipeline(device, m_graphicsPipeline, nullptr); - vkDestroyPipelineLayout(device, m_pipelineLayout, nullptr); - //vmaUnmapMemory(allocator, m_stagingBufferAllocation); - //vmaUnmapMemory(allocator, uniform_buffer_allocation); - //vmaDestroyBuffer(allocator, uniform_buffer_vs, uniform_buffer_allocation); - //vmaDestroyBuffer(allocator, m_indexBuffer, m_indexBufferAllocation); - //vmaDestroyBuffer(allocator, m_vertexBuffer, m_vertexBufferAllocation); - //vmaDestroyBuffer(allocator, m_stagingBuffer, m_stagingBufferAllocation); - vkDestroyDescriptorSetLayout(device, m_descriptorSetLayout, nullptr); + vkDestroyCommandPool(device, commandPool_ex, nullptr); Application::cleanup(); + //if (allocator != VK_NULL_HANDLE) { + // vmaDestroyAllocator(allocator); + // allocator = VK_NULL_HANDLE; + //} + + FACE_DBG_LOG("FaceApp::cleanup done"); } void FaceApp::SetInitArg(const char* arg) { _initArg = json::parse(arg); - + pushConstants.zoom = _initArg.zoom; + pushConstants.r = _initArg.r; + pushConstants.g = _initArg.g; + pushConstants.b = _initArg.b; + pushConstants.radius = _initArg.radius; + pushConstants.offset_x = _initArg.offset_x; + pushConstants.offset_y = _initArg.offset_y; } void FaceApp::drawFrame(long long frameTime) { - std::unique_lock lock(changeMotionMtx); - static long long game_time = 0; - game_time += frameTime; - long long actionTime = (1000 / _initArg.action_fps); - if (game_time > actionTime) - { - _curTexIndex++; - if (_curTexIndex >= _curMotion.png_names.size()) - { - _curTexIndex = 0; - } - game_time = game_time - actionTime; - } - Application::drawFrame(frameTime); -} - -void FaceApp::changeMotion(const char* json) -{ - Motion motion = json::parse(json); - changeMotion(motion); -} - -void FaceApp::changeMotion(Motion& motion) -{ - if (_curMotion.getMotionId() == motion.getMotionId()) + if (!_running) { return; } - std::unique_lock lock_changeMotion(changeMotionMtx); - _curMotion = motion; - for (int i = 0; i < _curMotion.png_names.size(); ++i) + +// if (_motionState == loading_next_motion) +// { +// int i = _nextMotionIndex; +// //for (int i = 0; i < _curMotion.png_names.size(); ++i) +// { +// +//#ifdef _WIN32 +// string path = "pic"; +// string path_name = path + "/" + _nextMotion.name + "/" + _nextMotion.png_names[i];// +std::to_string(i) + ".png"; +// loadTextureExample(UTF8ToWideString(path_name), m_texs_next[i], true); +//#else +// //string path = _curMotion.type + "/" + _curMotion.technique + "/" + _curMotion.step + "/" + _curMotion.show_type; +// string path = "pic"; +// string path_name = path + "/" + _nextMotion.type + "/" + _nextMotion.png_names[i];// +std::to_string(i) + ".png"; +// loadTexture(path_name, m_texs_next[i], true); +//#endif // _WIN32 +// +// _nextMotionIndex++; +// if (_nextMotionIndex >= _nextMotion.png_names.size()) +// { +// _motionState = load_next_motion_finished; +// _callback_loadfinish(_nextMotion.name); +// } +// } +// } + + + if (_curMotions.size() > 0) { - -#ifdef _WIN32 - //string path = _curMotion.type + "/" + _curMotion.technique + "/" + _curMotion.step + "/" + _curMotion.show_type; - string path = "pic"; - string path_name = path + "/" + _curMotion.type + "/" + _curMotion.png_names[i];// +std::to_string(i) + ".png"; - loadTextureExample(UTF8ToWideString(path_name), m_texs[i], true); - if (kThick) + static long long game_time = 0; + if (_playMotion) { - string path_name_ex = path + "/" + _curMotion.type + "/" + _curMotion.png_names[i] + std::to_string(i) + "_thick.png"; - loadTextureExample(UTF8ToWideString(path_name_ex), m_texs_ex[i], true); + game_time += frameTime; } -#else - //string path = _curMotion.type + "/" + _curMotion.technique + "/" + _curMotion.step + "/" + _curMotion.show_type; - string path = "pic"; - string path_name = path + "/" + _curMotion.type + "/" + _curMotion.png_names[i];// +std::to_string(i) + ".png"; - loadTexture(path_name, m_texs[i], true); - if (kThick) + long long actionTime = (1000 / _initArg.action_fps); + if (game_time > actionTime) { - loadTexture(path_name, m_texs_ex[i], true); - } -#endif // _WIN32 + if (_curFrameIndex < _curMotions[_curMotionIndex].frames.size() - 1) + { + _curFrameIndex += 1; + } + else + { + if (_curMotionIndex < _curMotions.size() - 1) + { + _curMotionIndex++; + _curFrameIndex = 0; + } + else + { + if (_animationFinishedCallback != nullptr) + { + _animationFinishedCallback(); + } - + if (_animationLoop) + { + _curMotionIndex = 0; + _curFrameIndex = 0; + } + else + { + _animationFinishedCallback = nullptr; + } + } + } + game_time = game_time - actionTime; + } } -} \ No newline at end of file + std::unique_lock lock_point(mtx_point); + std::unique_lock lock_changeMotion(changeMotionMtx); + std::unique_lock lock_Texture(createTextureMtx); + Application::drawFrame(frameTime); +} + +//void FaceApp::changeMotion(const char* motion_type) +//{ +// //Motion motion = json::parse(json); +// changeMotion(motion); +//} + +string FaceApp::preLoadMotionList(string motion_list_str, Callback callback) +{ + FACE_DBG_LOG("FaceApp::preLoadMotionList called str_len=%zu _isLoadMotion=%d", + motion_list_str.size(), (int)_isLoadMotion); + if (_isLoadMotion) + { + return "failue load not finished"; + } + _isLoadMotion = true; + _callback_loadfinish = callback; + _curLoadMotionList.clear(); + json j = json::parse(motion_list_str); + MotionList motion_list = j.get(); + _curLoadMotionList = motion_list.motions; + if (worker_.joinable()) + { + worker_.join(); + } + worker_ = std::thread(&FaceApp::loadMotionThread, this); + FACE_DBG_LOG("FaceApp::preLoadMotionList worker_ started, todo_count=%zu", _curLoadMotionList.size()); + return "ok"; +} + +void FaceApp::loadMotionThread() +{ + FACE_DBG_LOG("FaceApp::loadMotionThread enter, todo_count=%zu", _curLoadMotionList.size()); + while (!isInited()) + { + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + + //vector* load_text = nullptr; + //if (cur_left) + //{ + // load_text = &m_texs_right; + //} + //else + //{ + // load_text = &m_texs_left; + //} + + //vector& pre_texs = *load_text; + for (auto m : _curLoadMotionList) { + string name = m.name; + if (motion_list_map.find(name) != motion_list_map.end()) + { + continue; + } + m_texs_left.push_back(Texture()); + Texture& newTex = m_texs_left[m_texs_left.size() - 1]; + loadTexture(dummy_data, dummy_data.size(), dummy_w, dummy_h, newTex, true, commandPool, ""); +#ifdef _WIN32 + string path = "pic"; + string path_name = path + "/" + name + "ex.png"; + loadTextureExample(UTF8ToWideString(path_name), newTex, true, commandPool_ex); +#else + string path = "pic"; + string path_name = path + "/" + name + "ex.png"; + loadTexture(path_name, newTex, true, commandPool_ex); +#endif // _WIN32 + motion_list_map[name] = m_texs_left.size() - 1; + _loadMotionMap[name] = m; + } + +// for (int i = 0; i < _loadMotions.size(); ++i) +// { +// if (pre_texs[i].image == VK_NULL_HANDLE) +// { +// loadTexture(dummy_data, dummy_data.size(), dummy_w, dummy_h, pre_texs[i], true, commandPool, ""); +// } +// +// +//#ifdef _WIN32 +// string path = "pic"; +// string path_name = path + "/" + _loadMotions[i].name + "ex.png"; +// loadTextureExample(UTF8ToWideString(path_name), pre_texs[i], true, commandPool_ex); +//#else +// string path = "pic"; +// string path_name = path + "/" + _loadMotions[i].name + "ex.png"; +// loadTexture(path_name, pre_texs[i], true, commandPool_ex); +//#endif // _WIN32 +// +// motion_list_map[_loadMotions[i].name] = i; +// } + update_descriptor_set(m_texs_left, m_descriptor_sets_left); + _isLoadMotion = false; + FACE_DBG_LOG("FaceApp::loadMotionThread done, loaded_total=%zu", motion_list_map.size()); + _callback_loadfinish(); +} + + +Motion FaceApp::getMotionByName(string name) +{ + return _loadMotionMap[name]; +} + +void FaceApp::changeMotionList(vector motions, AnimationFinishedCallback callback, bool loop) +{ + FACE_DBG_LOG_THROTTLED("FaceApp.changeMotionList", + "FaceApp::changeMotionList called count=%zu loop=%d _isLoadMotion=%d", + motions.size(), (int)loop, (int)_isLoadMotion); + if (_isLoadMotion) + { + return; + } + + std::unique_lock lock_changeMotion(changeMotionMtx); + + //for (int i = 0; i < _preLoadMotions.size(); ++i) + //{ + // destroyTexture(device, m_texs[i]); + //} + + //for (int i = 0; i < _preLoadMotions.size(); ++i) + //{ + // m_texs[i] = m_texs_next[i]; + // //m_texs_next[i].reset(); + //} + + vector motion_list; + for (auto ms : motions) { + Motion m = getMotionByName(ms); + motion_list.push_back(m); + } + + _curMotions = motion_list; + + //if (cur_left) + //{ + // update_descriptor_set(m_texs_right, m_descriptor_sets_right); + // cur_left = false; + //} + //else + //{ + // update_descriptor_set(m_texs_left, m_descriptor_sets_left); + // cur_left = true; + //} + + + + + + _curFrameIndex = 0; + _curMotionIndex = 0; + + _animationFinishedCallback = callback; + _animationLoop = loop; + _isChangeMostion = true; + +} + +void FaceApp::StopMotion() { + FACE_DBG_LOG("FaceApp::StopMotion: _playMotion %d -> 0", (int)_playMotion); + _playMotion = false; +} + +void FaceApp::ResumeMotion() { + FACE_DBG_LOG("FaceApp::ResumeMotion: _playMotion %d -> 1", (int)_playMotion); + _playMotion = true; +} + diff --git a/vulkan/FaceApp.h b/vulkan/FaceApp.h index cc84793..a29815f 100644 --- a/vulkan/FaceApp.h +++ b/vulkan/FaceApp.h @@ -2,6 +2,7 @@ #define __FaceApp_H__ #include "Application.h" +#include #include "../third_party/vma/include/vk_mem_alloc.h" #include #include @@ -11,29 +12,57 @@ using namespace std; using json = nlohmann::json; +struct Frame { + string name; + float x; + float y; + NLOHMANN_DEFINE_TYPE_INTRUSIVE(Frame, name, x, y) +}; + struct Motion { - string type; - vector png_names; + string name; + vector< Frame> frames; string getMotionId() { - return type; + return name; } - NLOHMANN_DEFINE_TYPE_INTRUSIVE(Motion, type, png_names) + NLOHMANN_DEFINE_TYPE_INTRUSIVE(Motion, name, frames) +}; + +struct MotionList +{ + vector motions; + NLOHMANN_DEFINE_TYPE_INTRUSIVE(MotionList, motions) }; struct InitArg { int action_fps; float zoom; - Motion motion; - NLOHMANN_DEFINE_TYPE_INTRUSIVE(InitArg, action_fps, zoom, motion); + float r; + float g; + float b; + float radius; + float offset_x; + float offset_y; + //Motion motion; + NLOHMANN_DEFINE_TYPE_INTRUSIVE(InitArg, action_fps, zoom, r, g, b, radius, offset_x, offset_y); }; struct PushConstants { - float myValue; + float zoom = 0.5f; + float r = 0; + float g = 0; + float b = 0; + float radius = 240; + float ux = 0; + float uy = 0; + float offset_x = 0; + float offset_y = 0; }; - +using Callback = std::function; +using AnimationFinishedCallback = std::function; class FaceApp :public Application { @@ -56,7 +85,7 @@ public: static FaceApp* Get() { return faceIns; } void update_face_vertex_buffer(float* pos, int pointCount); - virtual bool isInited() override { return inited && faceAppInited; } + virtual bool isInited() override { return _applicationInited && _faceAppInited && _sceondInited; } virtual void cleanup() override; Texture tex_bg = {}; @@ -79,11 +108,10 @@ private: void setup_descriptor_pool(); void setup_descriptor_set_layout(); void setup_descriptor_set(); + void update_descriptor_set(vector& texs, vector& descriptSet); const bool kThick = false; void copyBuffer(VkBuffer srcBuffer, VkBuffer dstBuffer, VkDeviceSize size); - VkCommandBuffer beginSingleTimeCommands(); - void endSingleTimeCommands(VkCommandBuffer commandBuffer); // 顶点缓冲区相关 VkBuffer m_vertexBuffer = VK_NULL_HANDLE; @@ -99,11 +127,23 @@ private: VkPipeline m_graphicsPipeline = VK_NULL_HANDLE; VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE; VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE; - vector m_descriptor_sets; - const uint32_t kMaxTexture = 30; - vector m_texs; - vector m_texs_ex; + vector m_descriptor_sets_left; + //vector m_descriptor_sets_right; + const uint32_t kTextureInit = 1; + const uint32_t kTextureMax = 20; + vector m_texs_left; + map motion_list_map; + + + //vector m_texs_right; + //bool cur_left = true; + + //vector* _cur_texs; + vector m_texs_thick; + std::vector dummy_data; + unsigned dummy_w = 4096; + unsigned dummy_h = 2048; std::vector obj_vertices; std::vector obj_indices; @@ -111,6 +151,7 @@ private: std::map vertices_map_3dmax; std::mutex mtx_point; + std::mutex changeMotionMtx; long long last_update_time; VkBuffer uniform_buffer_vs; @@ -119,9 +160,10 @@ private: void createUniformBuffer(); - bool faceAppInited = false; + - float myFloatValue = 1.5f; + //float myFloatValue = 1.5f; + PushConstants pushConstants; @@ -133,16 +175,78 @@ private: VkDescriptorSetLayout m_descriptorSetLayout_bg = VK_NULL_HANDLE; VkDescriptorSet m_descriptor_set_bg = VK_NULL_HANDLE; - + bool _secondfaceAppInited = true; public: - void changeMotion(const char* json); - void changeMotion(Motion& motion); + void clearnSecondFaceApp(); + void Start(); + void Stop(); + + // Called from main thread in response to APP_CMD_TERM_WINDOW. + // Serializes against JNI callbacks (processImageNative / passDataToNative / + // changeMotionList) by taking all three FaceApp mutexes + createTextureMtx, + // then tears down window-dependent Vulkan objects via Application. + void onWindowLost(); + + // Called from main thread in response to APP_CMD_INIT_WINDOW. + // Does the full first-time initVulkan() on the very first call, and a + // lightweight swapchain/surface rebuild on subsequent calls. When the + // new swapchain's extent or format differs from the previous one, the + // FaceApp pipelines (baked with static viewport / old renderPass) are + // also destroyed and recreated via recreatePipelinesForSwapchain(). + void onWindowInit(); + + // Destroy and recreate m_graphicsPipeline / m_graphicsPipeline_bg so they + // match the current renderPass and swapChainExtent. Descriptor set layouts, + // pipeline layouts, vertex/index buffers, uniform buffers and textures are + // all kept. Must be called with device idle and the FaceApp mutexes held. + void recreatePipelinesForSwapchain(); + void loadMotionThread(); + std::thread worker_; + bool _isLoadMotion = false; + bool _isChangeMostion = false; + Callback _callback_loadfinish; + AnimationFinishedCallback _animationFinishedCallback; + bool _animationLoop = true; + string preLoadMotionList(string motion_list_str, Callback callback); + Motion getMotionByName(string name); + map_loadMotionMap; + vector _curLoadMotionList; + vector_curMotions; + void changeMotionList(vector motions, AnimationFinishedCallback callback, bool loop); + + //void changeMotion(Motion& motion); InitArg _initArg; - Motion _curMotion; - int _curTexIndex = 0; + //Motion _curMotion; + //string _curMotion_type; + //int _curMotion_png_size; + //Motion _nextMotion; + //int _nextMotionIndex; + + //enum MotionState { + // ready, + // loading_next_motion, + // load_next_motion_finished, + //}; + + //MotionState _motionState = ready; + + int _curFrameIndex = 0; + int _curMotionIndex = 0; void SetInitArg(const char* arg); void drawFrame(long long frameTime)override; + + void destroyTexture(VkDevice device, Texture& texture); + void cleanupResources(VkDevice device, VmaAllocator allocator); + + bool _running = false; + + bool _playMotion = true; + void StopMotion(); + + void ResumeMotion(); + bool _faceAppInited = false; + }; #endif diff --git a/vulkan/main.cpp b/vulkan/main.cpp index cb5e29d..c9a0400 100644 --- a/vulkan/main.cpp +++ b/vulkan/main.cpp @@ -39,6 +39,82 @@ std::wstring ReadFileWithChinesePath(const std::wstring& filePath) { return AppBase::UTF8ToWideString(context); } +FaceApp* g_app; + + +void CppAnimationFinishedCallback() +{ + std::cout << "call CppAnimationFinishedCallback\n"; +} + +void CppCallback() +{ + vector motions = {"4"}; + g_app->changeMotionList(motions, CppAnimationFinishedCallback, true); +} + +void CppCallback2() +{ + vector motions = { "11" }; + g_app->changeMotionList(motions, CppAnimationFinishedCallback, true); +} + +// 读取JSON文件并填充到motions容器中 +void loadMotions(const std::string& filePath, std::map& motions) { + // 读取json文件 + std::ifstream i(filePath); + if (!i.is_open()) { + std::cerr << "无法打开文件" << std::endl; + return; + } + + json j; + try { + i >> j; + } + catch (json::parse_error& ex) { // 捕获解析错误 + std::cerr << "JSON解析错误: " << ex.what() << std::endl; + return; + } + + // 遍历json对象并填充到motions中 + for (auto& motionEntry : j.items()) { + Motion motion; + motion.name = motionEntry.key(); + + for (auto& frameEntry : motionEntry.value().items()) { + Frame frame; + frame.name = frameEntry.key(); + frame.x = frameEntry.value()["x"].get(); + frame.y = frameEntry.value()["y"].get(); + motion.frames.push_back(frame); + } + + motions[motion.getMotionId()] = motion; + } +} + +bool threadRun = false; + +// 线程要执行的函数 +void threadFunction() { + int startTime = 0; + for (int i = 0; i < 500; ++i) + { + if (!threadRun) + { + break; + } + startTime += 100; + if (startTime == 10 * 1000) + { + vector motions = { "5", "13"}; + g_app->changeMotionList(motions, CppAnimationFinishedCallback, true); + } + std::this_thread::sleep_for(std::chrono::milliseconds(100)); // 暂停200ms + } +} + int main() { @@ -48,42 +124,88 @@ int main() { //std::wstring content = ReadFileWithChinesePath(chinese_path); InitArg init_arg; - Motion motion; - motion.type = "action24"; - for (int i = 0; i < 25; ++i) - { - if (i < 10) - { - motion.png_names.push_back("00000" + std::to_string(i) + ".png"); - } - else - { - motion.png_names.push_back("0000" + std::to_string(i) + ".png"); + //Motion motion; + //motion.name = "4"; + //motion.png_names.push_back("4.png"); + //for (int i = 1; i < 61; ++i) + //{ + // if (i < 10) + // { + // motion.png_names.push_back("00" + std::to_string(i) + ".png"); + // } + // else + // { + // motion.png_names.push_back("0" + std::to_string(i) + ".png"); - } - - } + // } + // + //} -# + + std::map motions; + loadMotions("example/src/main/assets/pic/motion_data_ex.json", motions); - init_arg.motion = motion; + //init_arg.motion = motion; init_arg.action_fps = 10; init_arg.zoom = 1.5f; + init_arg.r = 1; + init_arg.g = 0; + init_arg.b = 0; + init_arg.radius = 240; + init_arg.offset_x = 100; + init_arg.offset_y = -100; string json_str = json(init_arg).dump(); FaceApp app; + g_app = &app; app.SetInitArg(json_str.c_str()); app.initVulkan(); + app._running = true; + //auto motion_json = json(motion); + //if (!motion_json.is_object()) { + // std::cout << "Invalid JSON structure" << std::endl; + //} + //std::string motion_str = motion_json.dump(); + //// 添加完整性检查 + //if (motion_str.empty()) { + // std::cout << "Warning: Empty motion string" << std::endl; + //} + + MotionList s_motions; + s_motions.motions.push_back(motions["4"]); + s_motions.motions.push_back(motions["5"]); + s_motions.motions.push_back(motions["13"]); + json j = s_motions; + auto s = j.dump(); + + app.preLoadMotionList(s, CppCallback); + //threadRun = true; + //std::thread t(threadFunction); app.mainLoop(); + app.cleanupSecondInit(); + + //threadRun = false; + //t.join(); //try { // app.mainLoop(); //} catch (const std::exception& e) { // std::cerr << e.what() << std::endl; // return EXIT_FAILURE; //} + + s_motions.motions.push_back(motions["4"]); + s_motions.motions.push_back(motions["5"]); + s_motions.motions.push_back(motions["13"]); + s_motions.motions.push_back(motions["11"]); + j = s_motions; + s = j.dump(); + app.initVulkan(); + app.preLoadMotionList(s, CppCallback2); + app.mainLoop(); + app.cleanup(); return EXIT_SUCCESS; } \ No newline at end of file