Linking experimental Raspberry Pi Live2D Cubism core library
[mouse-tracker-for-cubism.git] / example / demo.patch
CommitLineData
830d0ba4 1diff -pruN --exclude build ./demo_clean/CMakeLists.txt ./demo_dev/CMakeLists.txt
eba2eb3a 2--- ./demo_clean/CMakeLists.txt 2020-10-01 22:47:25.846828066 +0100
4780896a 3+++ ./demo_dev/CMakeLists.txt 2021-01-01 15:36:14.720039779 +0000
830d0ba4
AIL
4@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.16)
5 # Set app name.
6 set(APP_NAME Demo)
7 # Set directory paths.
8-set(SDK_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../..)
9+set(SDK_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../CubismSdkForNative-4-r.1)
10 set(CORE_PATH ${SDK_ROOT_PATH}/Core)
11 set(FRAMEWORK_PATH ${SDK_ROOT_PATH}/Framework)
12 set(THIRD_PARTY_PATH ${SDK_ROOT_PATH}/Samples/OpenGL/thirdParty)
13@@ -32,7 +32,7 @@ set(GLFW_INSTALL OFF CACHE BOOL "" FORCE
14 set(BUILD_UTILS OFF CACHE BOOL "" FORCE)
15
16 # Specify version of compiler.
17-set(CMAKE_CXX_STANDARD 14)
18+set(CMAKE_CXX_STANDARD 17)
19 set(CMAKE_CXX_STANDARD_REQUIRED ON)
20 set(CMAKE_CXX_EXTENSIONS OFF)
21
4780896a
AIL
22@@ -42,7 +42,7 @@ add_library(Live2DCubismCore STATIC IMPO
23 # Find library path.
24 set_target_properties(Live2DCubismCore
25 PROPERTIES
26- IMPORTED_LOCATION ${CORE_PATH}/lib/linux/x86_64/libLive2DCubismCore.a
27+ IMPORTED_LOCATION ${CORE_PATH}/lib/experimental/rpi/libLive2DCubismCore.a
28 INTERFACE_INCLUDE_DIRECTORIES ${CORE_PATH}/include
29 )
30
33ad240c 31@@ -64,6 +64,11 @@ target_link_libraries(Framework Live2DCu
830d0ba4
AIL
32 # Find opengl libraries.
33 find_package(OpenGL REQUIRED)
34
126d8fa4 35+# Add MouseTrackerForCubism
33ad240c
AIL
36+find_package(PkgConfig)
37+pkg_check_modules(GTKMM gtkmm-3.0)
126d8fa4 38+add_subdirectory(../.. MouseTrackerForCubism_build)
830d0ba4
AIL
39+
40 # Make executable app.
41 add_executable(${APP_NAME})
42 # Add source files.
33ad240c 43@@ -73,9 +78,20 @@ target_link_libraries(${APP_NAME}
830d0ba4
AIL
44 Framework
45 glfw
46 ${OPENGL_LIBRARIES}
126d8fa4 47+ MouseTrackerForCubism
830d0ba4
AIL
48+ stdc++fs
49 )
50 # Specify include directories.
51-target_include_directories(${APP_NAME} PRIVATE ${STB_PATH})
33ad240c
AIL
52+target_include_directories(${APP_NAME} PRIVATE ${STB_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../../include ${GTKMM_INCLUDE_DIRS})
53+
54+# Copy GUI to build directory
55+add_custom_command(
56+ TARGET ${APP_NAME}
57+ POST_BUILD
58+ COMMAND
59+ ${CMAKE_COMMAND} -E
60+ copy ${CMAKE_CURRENT_SOURCE_DIR}/../../src/gui.glade $<TARGET_FILE_DIR:${APP_NAME}>/gui.glade
61+)
830d0ba4
AIL
62
63 # Copy resource directory to build directory.
64 add_custom_command(
830d0ba4 65diff -pruN --exclude build ./demo_clean/scripts/make_gcc ./demo_dev/scripts/make_gcc
eba2eb3a 66--- ./demo_clean/scripts/make_gcc 2020-10-01 22:47:25.854827921 +0100
33ad240c 67+++ ./demo_dev/scripts/make_gcc 2021-01-01 11:34:25.583684883 +0000
126d8fa4 68@@ -10,4 +10,4 @@ BUILD_PATH=$SCRIPT_PATH/../build/make_gc
830d0ba4
AIL
69 cmake -S "$CMAKE_PATH" \
70 -B "$BUILD_PATH" \
126d8fa4 71 -D CMAKE_BUILD_TYPE=Release
830d0ba4 72-cd "$BUILD_PATH" && make
830d0ba4
AIL
73+cd "$BUILD_PATH" && make -j4
74diff -pruN --exclude build ./demo_clean/src/CMakeLists.txt ./demo_dev/src/CMakeLists.txt
eba2eb3a 75--- ./demo_clean/src/CMakeLists.txt 2020-10-01 22:47:25.850827994 +0100
126d8fa4 76+++ ./demo_dev/src/CMakeLists.txt 2020-10-01 22:47:24.842846271 +0100
830d0ba4
AIL
77@@ -19,6 +19,4 @@ target_sources(${APP_NAME}
78 ${CMAKE_CURRENT_SOURCE_DIR}/LAppView.cpp
79 ${CMAKE_CURRENT_SOURCE_DIR}/LAppView.hpp
80 ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
81- ${CMAKE_CURRENT_SOURCE_DIR}/TouchManager.cpp
82- ${CMAKE_CURRENT_SOURCE_DIR}/TouchManager.hpp
83 )
eba2eb3a
AIL
84diff -pruN --exclude build ./demo_clean/src/LAppDefine.cpp ./demo_dev/src/LAppDefine.cpp
85--- ./demo_clean/src/LAppDefine.cpp 2020-10-01 22:47:25.850827994 +0100
86+++ ./demo_dev/src/LAppDefine.cpp 2020-10-18 04:59:13.238452938 +0100
87@@ -61,11 +61,11 @@ namespace LAppDefine {
88 const csmInt32 PriorityForce = 3;
89
90 // デバッグ用ログの表示オプション
91- const csmBool DebugLogEnable = true;
92+ const csmBool DebugLogEnable = false;
93 const csmBool DebugTouchLogEnable = false;
94
95 // Frameworkから出力するログのレベル設定
96- const CubismFramework::Option::LogLevel CubismLoggingLevel = CubismFramework::Option::LogLevel_Verbose;
97+ const CubismFramework::Option::LogLevel CubismLoggingLevel = CubismFramework::Option::LogLevel_Warning;
98
99 // デフォルトのレンダーターゲットサイズ
100 const csmInt32 RenderTargetWidth = 1900;
830d0ba4 101diff -pruN --exclude build ./demo_clean/src/LAppDelegate.cpp ./demo_dev/src/LAppDelegate.cpp
eba2eb3a 102--- ./demo_clean/src/LAppDelegate.cpp 2020-10-01 22:47:25.850827994 +0100
126d8fa4 103+++ ./demo_dev/src/LAppDelegate.cpp 2020-10-01 22:47:24.698848890 +0100
830d0ba4
AIL
104@@ -45,7 +45,8 @@ void LAppDelegate::ReleaseInstance()
105 s_instance = NULL;
106 }
107
108-bool LAppDelegate::Initialize()
109+bool LAppDelegate::Initialize(int initWindowWidth, int initWindowHeight,
110+ const char *windowTitle)
111 {
112 if (DebugLogEnable)
113 {
114@@ -63,7 +64,13 @@ bool LAppDelegate::Initialize()
115 }
116
117 // Windowの生成_
118- _window = glfwCreateWindow(RenderTargetWidth, RenderTargetHeight, "SAMPLE", NULL, NULL);
119+ _window = glfwCreateWindow(
120+ initWindowWidth ? initWindowWidth : RenderTargetWidth,
121+ initWindowHeight ? initWindowHeight : RenderTargetHeight,
122+ windowTitle ? windowTitle : "SAMPLE",
123+ NULL,
124+ NULL);
125+
126 if (_window == NULL)
127 {
128 if (DebugLogEnable)
129@@ -95,10 +102,6 @@ bool LAppDelegate::Initialize()
130 glEnable(GL_BLEND);
131 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
132
133- //コールバック関数の登録
134- glfwSetMouseButtonCallback(_window, EventHandler::OnMouseCallBack);
135- glfwSetCursorPosCallback(_window, EventHandler::OnMouseCallBack);
136-
137 // ウィンドウサイズ記憶
138 int width, height;
139 glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
140@@ -111,8 +114,6 @@ bool LAppDelegate::Initialize()
141 // Cubism3の初期化
142 InitializeCubism();
143
144- SetRootDirectory();
145-
146 //load model
147 LAppLive2DManager::GetInstance();
148
149@@ -214,49 +215,6 @@ void LAppDelegate::InitializeCubism()
150 LAppPal::UpdateTime();
151 }
152
153-void LAppDelegate::OnMouseCallBack(GLFWwindow* window, int button, int action, int modify)
154-{
155- if (_view == NULL)
156- {
157- return;
158- }
159- if (GLFW_MOUSE_BUTTON_LEFT != button)
160- {
161- return;
162- }
163-
164- if (GLFW_PRESS == action)
165- {
166- _captured = true;
167- _view->OnTouchesBegan(_mouseX, _mouseY);
168- }
169- else if (GLFW_RELEASE == action)
170- {
171- if (_captured)
172- {
173- _captured = false;
174- _view->OnTouchesEnded(_mouseX, _mouseY);
175- }
176- }
177-}
178-
179-void LAppDelegate::OnMouseCallBack(GLFWwindow* window, double x, double y)
180-{
181- _mouseX = static_cast<float>(x);
182- _mouseY = static_cast<float>(y);
183-
184- if (!_captured)
185- {
186- return;
187- }
188- if (_view == NULL)
189- {
190- return;
191- }
192-
193- _view->OnTouchesMoved(_mouseX, _mouseY);
194-}
195-
196 GLuint LAppDelegate::CreateShader()
197 {
198 //バーテックスシェーダのコンパイル
199@@ -299,29 +257,9 @@ GLuint LAppDelegate::CreateShader()
200 return programId;
201 }
202
203-void LAppDelegate::SetRootDirectory()
204+void LAppDelegate::SetRootDirectory(std::string rootDir)
205 {
206- char path[1024];
207- ssize_t len = readlink("/proc/self/exe", path, 1024 - 1);
208-
209- if (len != -1)
210- {
211- path[len] = '\0';
212- }
213-
214- std::string pathString(path);
215-
216- pathString = pathString.substr(0, pathString.rfind("Demo"));
217- Csm::csmVector<string> splitStrings = this->Split(pathString, '/');
218-
219- this->_rootDirectory = "";
220-
221- for(int i = 0; i < splitStrings.GetSize(); i++)
222- {
223- this->_rootDirectory = this->_rootDirectory + "/" +splitStrings[i];
224- }
225-
226- this->_rootDirectory += "/";
227+ this->_rootDirectory = rootDir + "/";
228 }
229
230 Csm::csmVector<string> LAppDelegate::Split(const std::string& baseString, char delimiter)
231diff -pruN --exclude build ./demo_clean/src/LAppDelegate.hpp ./demo_dev/src/LAppDelegate.hpp
eba2eb3a 232--- ./demo_clean/src/LAppDelegate.hpp 2020-10-01 22:47:25.850827994 +0100
126d8fa4 233+++ ./demo_dev/src/LAppDelegate.hpp 2020-10-01 22:47:24.842846271 +0100
830d0ba4
AIL
234@@ -40,7 +40,8 @@ public:
235 /**
236 * @brief APPに必要なものを初期化する。
237 */
238- bool Initialize();
239+ bool Initialize(int initWindowWidth = 0, int initWindowHeight = 0,
240+ const char *windowTitle = "SAMPLE");
241
242 /**
243 * @brief 解放する。
244@@ -53,25 +54,6 @@ public:
245 void Run();
246
247 /**
248- * @brief OpenGL用 glfwSetMouseButtonCallback用関数。
249- *
250- * @param[in] window コールバックを呼んだWindow情報
251- * @param[in] button ボタン種類
252- * @param[in] action 実行結果
253- * @param[in] modify
254- */
255- void OnMouseCallBack(GLFWwindow* window, int button, int action, int modify);
256-
257- /**
258- * @brief OpenGL用 glfwSetCursorPosCallback用関数。
259- *
260- * @param[in] window コールバックを呼んだWindow情報
261- * @param[in] x x座標
262- * @param[in] y x座標
263- */
264- void OnMouseCallBack(GLFWwindow* window, double x, double y);
265-
266- /**
267 * @brief シェーダーを登録する。
268 */
269 GLuint CreateShader();
270@@ -98,8 +80,10 @@ public:
271
272 /**
273 * @brief ルートディレクトリを設定する。
274+ *
275+ * @param[in] rootDir : The root directory to set to.
276 */
277- void SetRootDirectory();
278+ void SetRootDirectory(std::string rootDir);
279
280 /**
281 * @brief ルートディレクトリを取得する。
282@@ -146,24 +130,3 @@ private:
283 int _windowWidth; ///< Initialize関数で設定したウィンドウ幅
284 int _windowHeight; ///< Initialize関数で設定したウィンドウ高さ
285 };
286-
287-class EventHandler
288-{
289-public:
290- /**
291- * @brief glfwSetMouseButtonCallback用コールバック関数。
292- */
293- static void OnMouseCallBack(GLFWwindow* window, int button, int action, int modify)
294- {
295- LAppDelegate::GetInstance()->OnMouseCallBack(window, button, action, modify);
296- }
297-
298- /**
299- * @brief glfwSetCursorPosCallback用コールバック関数。
300- */
301- static void OnMouseCallBack(GLFWwindow* window, double x, double y)
302- {
303- LAppDelegate::GetInstance()->OnMouseCallBack(window, x, y);
304- }
305-
306-};
307diff -pruN --exclude build ./demo_clean/src/LAppLive2DManager.cpp ./demo_dev/src/LAppLive2DManager.cpp
eba2eb3a 308--- ./demo_clean/src/LAppLive2DManager.cpp 2020-10-01 22:47:25.850827994 +0100
126d8fa4 309+++ ./demo_dev/src/LAppLive2DManager.cpp 2020-10-02 02:00:49.961556700 +0100
830d0ba4
AIL
310@@ -52,9 +52,10 @@ void LAppLive2DManager::ReleaseInstance(
311
312 LAppLive2DManager::LAppLive2DManager()
313 : _viewMatrix(NULL)
314- , _sceneIndex(0)
315+ , _projScaleFactor(1.0f)
316+ , _translateX(0.0f)
317+ , _translateY(0.0f)
318 {
319- ChangeScene(_sceneIndex);
320 }
321
322 LAppLive2DManager::~LAppLive2DManager()
323@@ -98,26 +99,6 @@ void LAppLive2DManager::OnTap(csmFloat32
324 {
325 LAppPal::PrintLog("[APP]tap point: {x:%.2f y:%.2f}", x, y);
326 }
327-
328- for (csmUint32 i = 0; i < _models.GetSize(); i++)
329- {
330- if (_models[i]->HitTest(HitAreaNameHead, x, y))
331- {
332- if (DebugLogEnable)
333- {
334- LAppPal::PrintLog("[APP]hit area: [%s]", HitAreaNameHead);
335- }
336- _models[i]->SetRandomExpression();
337- }
338- else if (_models[i]->HitTest(HitAreaNameBody, x, y))
339- {
340- if (DebugLogEnable)
341- {
342- LAppPal::PrintLog("[APP]hit area: [%s]", HitAreaNameBody);
343- }
344- _models[i]->StartRandomMotion(MotionGroupTapBody, PriorityNormal, FinishedMotion);
345- }
346- }
347 }
348
349 void LAppLive2DManager::OnUpdate() const
350@@ -125,7 +106,9 @@ void LAppLive2DManager::OnUpdate() const
351 CubismMatrix44 projection;
352 int width, height;
353 glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
354- projection.Scale(1.0f, static_cast<float>(width) / static_cast<float>(height));
355+ projection.Scale(_projScaleFactor,
356+ _projScaleFactor * static_cast<float>(width) / static_cast<float>(height));
357+ projection.Translate(_translateX, _translateY);
358
359 if (_viewMatrix != NULL)
360 {
361@@ -148,26 +131,10 @@ void LAppLive2DManager::OnUpdate() const
362 }
363 }
364
365-void LAppLive2DManager::NextScene()
366-{
367- csmInt32 no = (_sceneIndex + 1) % ModelDirSize;
368- ChangeScene(no);
369-}
370-
371-void LAppLive2DManager::ChangeScene(Csm::csmInt32 index)
372+void LAppLive2DManager::SetModel(std::string modelName)
373 {
374- _sceneIndex = index;
375- if (DebugLogEnable)
376- {
377- LAppPal::PrintLog("[APP]model index: %d", _sceneIndex);
378- }
379-
380- // ModelDir[]に保持したディレクトリ名から
381- // model3.jsonのパスを決定する.
382- // ディレクトリ名とmodel3.jsonの名前を一致させておくこと.
383- std::string model = ModelDir[index];
384- std::string modelPath = LAppDelegate::GetInstance()->GetRootDirectory() + ResourcesPath + model + "/";
385- std::string modelJsonName = ModelDir[index];
386+ std::string modelPath = LAppDelegate::GetInstance()->GetRootDirectory() + ResourcesPath + modelName + "/";
387+ std::string modelJsonName = modelName;
388 modelJsonName += ".model3.json";
389
390 ReleaseAllModel();
391@@ -215,3 +182,20 @@ csmUint32 LAppLive2DManager::GetModelNum
392 {
393 return _models.GetSize();
394 }
395+
126d8fa4 396+void LAppLive2DManager::SetTracker(MouseCursorTracker *tracker)
830d0ba4
AIL
397+{
398+ for (auto it = _models.Begin(); it != _models.End(); ++it)
399+ {
126d8fa4 400+ (*it)->SetTracker(tracker);
830d0ba4
AIL
401+ }
402+}
403+
404+void LAppLive2DManager::SetProjectionScaleTranslate(float scaleFactor,
405+ float translateX,
406+ float translateY)
407+{
408+ _projScaleFactor = scaleFactor;
409+ _translateX = translateX;
410+ _translateY = translateY;
411+}
412diff -pruN --exclude build ./demo_clean/src/LAppLive2DManager.hpp ./demo_dev/src/LAppLive2DManager.hpp
eba2eb3a 413--- ./demo_clean/src/LAppLive2DManager.hpp 2020-10-01 22:47:25.846828066 +0100
126d8fa4 414+++ ./demo_dev/src/LAppLive2DManager.hpp 2020-10-01 23:36:24.583055381 +0100
830d0ba4
AIL
415@@ -6,12 +6,15 @@
416 */
417 #pragma once
418
419+#include <string>
420 #include <CubismFramework.hpp>
421 #include <Math/CubismMatrix44.hpp>
422 #include <Type/csmVector.hpp>
423
424 class LAppModel;
425
126d8fa4 426+class MouseCursorTracker;
830d0ba4
AIL
427+
428 /**
429 * @brief サンプルアプリケーションにおいてCubismModelを管理するクラス<br>
430 * モデル生成と破棄、タップイベントの処理、モデル切り替えを行う。
431@@ -72,16 +75,12 @@ public:
432 void OnUpdate() const;
433
434 /**
435- * @brief 次のシーンに切り替える<br>
436- * サンプルアプリケーションではモデルセットの切り替えを行う。
437- */
438- void NextScene();
439-
440- /**
441- * @brief シーンを切り替える<br>
442- * サンプルアプリケーションではモデルセットの切り替えを行う。
443- */
444- void ChangeScene(Csm::csmInt32 index);
445+ * @brief Set model data
446+ *
447+ * @param[in] modelName : Name of model, should be the same for both
448+ * the directory and the model3.json file
449+ */
450+ void SetModel(std::string modelName);
451
452 /**
453 * @brief モデル個数を得る
454@@ -89,6 +88,24 @@ public:
455 */
456 Csm::csmUint32 GetModelNum() const;
457
458+ /**
126d8fa4 459+ * @brief Set the pointer to the MouseCursorTracker instance
830d0ba4 460+ *
126d8fa4 461+ * @param[in] tracker : Pointer to MouseCursorTracker instance
830d0ba4 462+ */
126d8fa4 463+ void SetTracker(MouseCursorTracker *tracker);
830d0ba4
AIL
464+
465+ /**
466+ * @brief Set projection scale factor and translation parameters
467+ *
468+ * @param[in] scaleFactor : Scale factor applied in both X and Y directions
469+ * @param[in] translateX : Translation in X direction
470+ * @param[in] translateY : Translation in Y direction
471+ */
472+ void SetProjectionScaleTranslate(float scaleFactor,
473+ float translateX,
474+ float translateY);
475+
476 private:
477 /**
478 * @brief コンストラクタ
479@@ -102,5 +119,8 @@ private:
480
481 Csm::CubismMatrix44* _viewMatrix; ///< モデル描画に用いるView行列
482 Csm::csmVector<LAppModel*> _models; ///< モデルインスタンスのコンテナ
483- Csm::csmInt32 _sceneIndex; ///< 表示するシーンのインデックス値
484+
485+ float _projScaleFactor;
486+ float _translateX;
487+ float _translateY;
488 };
489diff -pruN --exclude build ./demo_clean/src/LAppModel.cpp ./demo_dev/src/LAppModel.cpp
eba2eb3a
AIL
490--- ./demo_clean/src/LAppModel.cpp 2020-10-01 22:47:25.850827994 +0100
491+++ ./demo_dev/src/LAppModel.cpp 2020-10-18 09:26:08.998822685 +0100
492@@ -21,6 +21,10 @@
830d0ba4
AIL
493 #include "LAppTextureManager.hpp"
494 #include "LAppDelegate.hpp"
495
126d8fa4 496+#include "mouse_cursor_tracker.h"
830d0ba4 497+
eba2eb3a
AIL
498+#include <iostream>
499+
830d0ba4
AIL
500 using namespace Live2D::Cubism::Framework;
501 using namespace Live2D::Cubism::Framework::DefaultParameterId;
502 using namespace LAppDefine;
eba2eb3a 503@@ -49,6 +53,7 @@ LAppModel::LAppModel()
126d8fa4
AIL
504 : CubismUserModel()
505 , _modelSetting(NULL)
506 , _userTimeSeconds(0.0f)
507+ , _tracker(nullptr)
508 {
509 if (DebugLogEnable)
510 {
eba2eb3a 511@@ -335,59 +340,110 @@ void LAppModel::Update()
830d0ba4
AIL
512 const csmFloat32 deltaTimeSeconds = LAppPal::GetDeltaTime();
513 _userTimeSeconds += deltaTimeSeconds;
514
515- _dragManager->Update(deltaTimeSeconds);
516- _dragX = _dragManager->GetX();
517- _dragY = _dragManager->GetY();
518-
519- // モーションによるパラメータ更新の有無
520- csmBool motionUpdated = false;
521-
522- //-----------------------------------------------------------------
523- _model->LoadParameters(); // 前回セーブされた状態をロード
524- if (_motionManager->IsFinished())
eba2eb3a 525- {
830d0ba4
AIL
526- // モーションの再生がない場合、待機モーションの中からランダムで再生する
527- StartRandomMotion(MotionGroupIdle, PriorityIdle);
528- }
529- else
eba2eb3a
AIL
530+ if (_tracker)
531 {
830d0ba4
AIL
532- motionUpdated = _motionManager->UpdateMotion(_model, deltaTimeSeconds); // モーションを更新
533- }
534- _model->SaveParameters(); // 状態を保存
535- //-----------------------------------------------------------------
2b1f0c7c 536+ auto idMan = CubismFramework::GetIdManager();
126d8fa4 537+ auto params = _tracker->getParams();
2b1f0c7c 538
830d0ba4
AIL
539- // まばたき
540- if (!motionUpdated)
541- {
542- if (_eyeBlink != NULL)
2b1f0c7c 543+ _model->LoadParameters(); // 前回セーブされた状態をロード
eba2eb3a
AIL
544+
545+ int paramsMotionPriority = static_cast<int>(params.motionPriority);
546+
547+ if (paramsMotionPriority != PriorityNone)
2b1f0c7c 548 {
830d0ba4
AIL
549- // メインモーションの更新がないとき
550- _eyeBlink->UpdateParameters(_model, deltaTimeSeconds); // 目パチ
eba2eb3a
AIL
551+ StartMotion(params.motionGroup.c_str(), params.motionNumber,
552+ paramsMotionPriority);
553+ }
554+ else if (params.randomIdleMotion && _motionManager->IsFinished())
555+ {
2b1f0c7c
AIL
556+ // モーションの再生がない場合、待機モーションの中からランダムで再生する
557+ StartRandomMotion(MotionGroupIdle, PriorityIdle);
558 }
830d0ba4 559- }
126d8fa4 560
830d0ba4 561- if (_expressionManager != NULL)
2b1f0c7c 562- {
830d0ba4
AIL
563- _expressionManager->UpdateMotion(_model, deltaTimeSeconds); // 表情でパラメータ更新(相対変化)
564- }
eba2eb3a
AIL
565+ // FIXME pose does not return to normal after motion
566+ // if we don't have randomIdleMotion set
567+ else
568+ {
569+ _motionManager->UpdateMotion(_model, deltaTimeSeconds); // モーションを更新
570+ }
571+ _model->SaveParameters(); // 状態を保存
126d8fa4 572
830d0ba4
AIL
573- //ドラッグによる変化
574- //ドラッグによる顔の向きの調整
575- _model->AddParameterValue(_idParamAngleX, _dragX * 30); // -30から30の値を加える
576- _model->AddParameterValue(_idParamAngleY, _dragY * 30);
577- _model->AddParameterValue(_idParamAngleZ, _dragX * _dragY * -30);
eba2eb3a 578+ if (params.expression != "")
126d8fa4 579+ {
eba2eb3a 580+ SetExpression(params.expression.c_str());
126d8fa4 581+ }
eba2eb3a 582+ if (_expressionManager != NULL)
2b1f0c7c 583+ {
eba2eb3a 584+ _expressionManager->UpdateMotion(_model, deltaTimeSeconds); // 表情でパラメータ更新(相対変化)
2b1f0c7c 585+ }
126d8fa4
AIL
586
587- //ドラッグによる体の向きの調整
588- _model->AddParameterValue(_idParamBodyAngleX, _dragX * 10); // -10から10の値を加える
eba2eb3a
AIL
589+ bool autoBlink = params.autoBlink && _eyeBlink;
590+ auto eyeLOpenIt = params.live2d.find("ParamEyeLOpen");
591+ auto eyeROpenIt = params.live2d.find("ParamEyeROpen");
2b1f0c7c 592
830d0ba4
AIL
593- //ドラッグによる目の向きの調整
594- _model->AddParameterValue(_idParamEyeBallX, _dragX); // -1から1の値を加える
595- _model->AddParameterValue(_idParamEyeBallY, _dragY);
eba2eb3a 596+ if (autoBlink)
126d8fa4 597+ {
eba2eb3a
AIL
598+ // Handle blink first
599+ _eyeBlink->UpdateParameters(_model, deltaTimeSeconds);
600+ }
830d0ba4
AIL
601
602- // 呼吸など
603- if (_breath != NULL)
604- {
605- _breath->UpdateParameters(_model, deltaTimeSeconds);
eba2eb3a
AIL
606+ if (eyeLOpenIt != params.live2d.end())
607+ {
608+ // If value specified, override blinking
609+ _model->SetParameterValue(idMan->GetId("ParamEyeLOpen"),
610+ eyeLOpenIt->second);
611+ }
612+ else if (!autoBlink)
613+ {
614+ // If no value specified and no auto blink, set to 1
615+ _model->SetParameterValue(idMan->GetId("ParamEyeLOpen"), 1);
616+
617+ }
618+
619+ if (eyeROpenIt != params.live2d.end())
620+ {
621+ _model->SetParameterValue(idMan->GetId("ParamEyeROpen"),
622+ eyeROpenIt->second);
623+ }
624+ else if (!autoBlink)
625+ {
626+ _model->SetParameterValue(idMan->GetId("ParamEyeROpen"), 1);
627+ }
628+
629+
630+ if (params.useLipSync && _lipSync)
631+ {
632+ csmFloat32 value = params.lipSyncParam; // 0 to 1
633+
126d8fa4
AIL
634+ for (csmUint32 i = 0; i < _lipSyncIds.GetSize(); ++i)
635+ {
636+ _model->AddParameterValue(_lipSyncIds[i], value, 0.8f);
637+ }
2b1f0c7c
AIL
638+ }
639+ else
640+ {
126d8fa4 641+ _model->SetParameterValue(idMan->GetId("ParamMouthOpenY"),
eba2eb3a
AIL
642+ params.live2d["ParamMouthOpenY"]);
643+ }
644+
645+ for (auto const &entry : params.live2d)
646+ {
647+ std::string key = entry.first;
648+ double val = entry.second;
649+
650+ if (key != "ParamEyeLOpen" && key != "ParamEyeROpen" &&
651+ key != "ParamMouthOpenY")
652+ {
653+ _model->SetParameterValue(idMan->GetId(key.c_str()), val);
654+ }
2b1f0c7c 655+ }
126d8fa4 656+
2b1f0c7c
AIL
657+ if (params.autoBreath && _breath)
658+ {
659+ // Note: _model->LoadParameters and SaveParameters is needed
660+ // before - see above.
661+ _breath->UpdateParameters(_model, deltaTimeSeconds);
662+ }
830d0ba4
AIL
663 }
664
665 // 物理演算の設定
eba2eb3a 666@@ -396,17 +452,6 @@ void LAppModel::Update()
830d0ba4
AIL
667 _physics->Evaluate(_model, deltaTimeSeconds);
668 }
669
670- // リップシンクの設定
671- if (_lipSync)
672- {
673- csmFloat32 value = 0; // リアルタイムでリップシンクを行う場合、システムから音量を取得して0〜1の範囲で値を入力します。
674-
675- for (csmUint32 i = 0; i < _lipSyncIds.GetSize(); ++i)
676- {
677- _model->AddParameterValue(_lipSyncIds[i], value, 0.8f);
678- }
679- }
680-
681 // ポーズの設定
682 if (_pose != NULL)
683 {
eba2eb3a 684@@ -626,3 +671,14 @@ Csm::Rendering::CubismOffscreenFrame_Ope
830d0ba4
AIL
685 {
686 return _renderBuffer;
687 }
688+
126d8fa4 689+void LAppModel::SetTracker(MouseCursorTracker *tracker)
830d0ba4 690+{
126d8fa4 691+ _tracker = tracker;
830d0ba4
AIL
692+}
693+
eba2eb3a
AIL
694+Csm::ICubismModelSetting* LAppModel::GetModelSetting(void) const
695+{
696+ return _modelSetting;
697+}
698+
830d0ba4 699diff -pruN --exclude build ./demo_clean/src/LAppModel.hpp ./demo_dev/src/LAppModel.hpp
eba2eb3a
AIL
700--- ./demo_clean/src/LAppModel.hpp 2020-10-01 22:47:25.850827994 +0100
701+++ ./demo_dev/src/LAppModel.hpp 2020-10-18 03:04:52.142045751 +0100
830d0ba4
AIL
702@@ -13,6 +13,7 @@
703 #include <Type/csmRectF.hpp>
704 #include <Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.hpp>
705
126d8fa4 706+#include "mouse_cursor_tracker.h"
830d0ba4
AIL
707
708 /**
709 * @brief ユーザーが実際に使用するモデルの実装クラス<br>
eba2eb3a 710@@ -113,6 +114,15 @@ public:
830d0ba4
AIL
711 */
712 Csm::Rendering::CubismOffscreenFrame_OpenGLES2& GetRenderBuffer();
713
714+ /**
126d8fa4 715+ * @brief Set the pointer to the MouseCursorTracker instance
830d0ba4 716+ *
126d8fa4 717+ * @param[in] tracker : Pointer to MouseCursorTracker instance
830d0ba4 718+ */
126d8fa4 719+ void SetTracker(MouseCursorTracker *tracker);
830d0ba4 720+
eba2eb3a
AIL
721+ Csm::ICubismModelSetting* GetModelSetting(void) const;
722+
830d0ba4
AIL
723 protected:
724 /**
725 * @brief モデルを描画する処理。モデルを描画する空間のView-Projection行列を渡す。
eba2eb3a 726@@ -183,6 +193,8 @@ private:
830d0ba4
AIL
727 const Csm::CubismId* _idParamEyeBallY; ///< パラメータID: ParamEyeBallXY
728
729 Csm::Rendering::CubismOffscreenFrame_OpenGLES2 _renderBuffer; ///< フレームバッファ以外の描画先
730+
126d8fa4 731+ MouseCursorTracker *_tracker;
830d0ba4
AIL
732 };
733
734
735diff -pruN --exclude build ./demo_clean/src/LAppPal.cpp ./demo_dev/src/LAppPal.cpp
eba2eb3a
AIL
736--- ./demo_clean/src/LAppPal.cpp 2020-10-01 22:47:25.850827994 +0100
737+++ ./demo_dev/src/LAppPal.cpp 2020-10-18 04:57:43.289600308 +0100
830d0ba4
AIL
738@@ -6,6 +6,7 @@
739 */
740
741 #include "LAppPal.hpp"
742+#include <stdexcept>
743 #include <stdio.h>
744 #include <stdlib.h>
745 #include <stdarg.h>
eba2eb3a
AIL
746@@ -36,7 +37,6 @@ csmByte* LAppPal::LoadFileAsBytes(const
747 if (stat(path, &statBuf) == 0)
748 {
749 size = statBuf.st_size;
750- PrintLog(path);
751 }
752
753 std::fstream file;
754@@ -45,10 +45,7 @@ csmByte* LAppPal::LoadFileAsBytes(const
830d0ba4
AIL
755 file.open(path, std::ios::in | std::ios::binary);
756 if (!file.is_open())
757 {
758- if (DebugLogEnable)
759- {
760- PrintLog("file open error");
761- }
762+ throw std::runtime_error("Failed to open file " + filePath);
763 return NULL;
764 }
765 file.read(buf, size);
766diff -pruN --exclude build ./demo_clean/src/LAppTextureManager.cpp ./demo_dev/src/LAppTextureManager.cpp
eba2eb3a 767--- ./demo_clean/src/LAppTextureManager.cpp 2020-10-01 22:47:25.850827994 +0100
126d8fa4 768+++ ./demo_dev/src/LAppTextureManager.cpp 2020-10-01 22:47:24.654849690 +0100
830d0ba4
AIL
769@@ -96,6 +96,46 @@ LAppTextureManager::TextureInfo* LAppTex
770
771 }
772
773+LAppTextureManager::TextureInfo* LAppTextureManager::CreateTextureFromColor(
774+ uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha
775+)
776+{
777+ int width = 8, height = 8;
778+
779+ uint8_t pixels[height][width][4];
780+ for (std::size_t h = 0; h < height; h++)
781+ {
782+ for (std::size_t w = 0; w < width; w++)
783+ {
784+ pixels[h][w][0] = red;
785+ pixels[h][w][1] = green;
786+ pixels[h][w][2] = blue;
787+ pixels[h][w][3] = alpha;
788+ }
789+ }
790+
791+ GLuint textureId;
792+ glGenTextures(1, &textureId);
793+ glBindTexture(GL_TEXTURE_2D, textureId);
794+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
795+
796+ glGenerateMipmap(GL_TEXTURE_2D);
797+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
798+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
799+ glBindTexture(GL_TEXTURE_2D, 0);
800+
801+
802+ LAppTextureManager::TextureInfo* textureInfo = new LAppTextureManager::TextureInfo();
803+ textureInfo->fileName = "";
804+ textureInfo->width = width;
805+ textureInfo->height = height;
806+ textureInfo->id = textureId;
807+
808+ _textures.PushBack(textureInfo);
809+
810+ return textureInfo;
811+}
812+
813 void LAppTextureManager::ReleaseTextures()
814 {
815 for (Csm::csmUint32 i = 0; i < _textures.GetSize(); i++)
816diff -pruN --exclude build ./demo_clean/src/LAppTextureManager.hpp ./demo_dev/src/LAppTextureManager.hpp
eba2eb3a 817--- ./demo_clean/src/LAppTextureManager.hpp 2020-10-01 22:47:25.846828066 +0100
126d8fa4 818+++ ./demo_dev/src/LAppTextureManager.hpp 2020-10-01 22:47:24.786847290 +0100
830d0ba4
AIL
819@@ -72,6 +72,8 @@ public:
820 */
821 TextureInfo* CreateTextureFromPngFile(std::string fileName);
822
823+ TextureInfo *CreateTextureFromColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha = 255);
824+
825 /**
826 * @brief 画像の解放
827 *
828diff -pruN --exclude build ./demo_clean/src/LAppView.cpp ./demo_dev/src/LAppView.cpp
eba2eb3a 829--- ./demo_clean/src/LAppView.cpp 2020-10-01 22:47:25.850827994 +0100
126d8fa4 830+++ ./demo_dev/src/LAppView.cpp 2020-10-01 22:47:24.602850636 +0100
830d0ba4
AIL
831@@ -13,7 +13,6 @@
832 #include "LAppLive2DManager.hpp"
833 #include "LAppTextureManager.hpp"
834 #include "LAppDefine.hpp"
835-#include "TouchManager.hpp"
836 #include "LAppSprite.hpp"
837 #include "LAppModel.hpp"
838
839@@ -26,8 +25,6 @@ using namespace LAppDefine;
840 LAppView::LAppView():
841 _programId(0),
842 _back(NULL),
843- _gear(NULL),
844- _power(NULL),
845 _renderSprite(NULL),
846 _renderTarget(SelectTarget_None)
847 {
848@@ -35,8 +32,6 @@ LAppView::LAppView():
849 _clearColor[1] = 1.0f;
850 _clearColor[2] = 1.0f;
851 _clearColor[3] = 0.0f;
852- // タッチ関係のイベント管理
853- _touchManager = new TouchManager();
854
855 // デバイス座標からスクリーン座標に変換するための
856 _deviceToScreen = new CubismMatrix44();
857@@ -52,10 +47,7 @@ LAppView::~LAppView()
858
859 delete _viewMatrix;
860 delete _deviceToScreen;
861- delete _touchManager;
862 delete _back;
863- delete _gear;
864- delete _power;
865 }
866
867 void LAppView::Initialize()
868@@ -97,9 +89,6 @@ void LAppView::Initialize()
869 void LAppView::Render()
870 {
871 _back->Render();
872- _gear->Render();
873- _power->Render();
874-
875
876 LAppLive2DManager* Live2DManager = LAppLive2DManager::GetInstance();
877
878@@ -139,35 +128,17 @@ void LAppView::InitializeSprite()
879 glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
880
881 LAppTextureManager* textureManager = LAppDelegate::GetInstance()->GetTextureManager();
882- const string resourcesPath = LAppDelegate::GetInstance()->GetRootDirectory() + ResourcesPath;
883
884- string imageName = BackImageName;
885- LAppTextureManager::TextureInfo* backgroundTexture = textureManager->CreateTextureFromPngFile(resourcesPath + imageName);
886+
887+ LAppTextureManager::TextureInfo* backgroundTexture =
888+ textureManager->CreateTextureFromColor(0, 255, 0);
889
890 float x = width * 0.5f;
891 float y = height * 0.5f;
892- float fWidth = static_cast<float>(backgroundTexture->width * 2.0f);
893- float fHeight = static_cast<float>(height) * 0.95f;
894+ float fWidth = static_cast<float>(width);
895+ float fHeight = static_cast<float>(height);
896 _back = new LAppSprite(x, y, fWidth, fHeight, backgroundTexture->id, _programId);
897
898- imageName = GearImageName;
899- LAppTextureManager::TextureInfo* gearTexture = textureManager->CreateTextureFromPngFile(resourcesPath + imageName);
900-
901- x = static_cast<float>(width - gearTexture->width * 0.5f);
902- y = static_cast<float>(height - gearTexture->height * 0.5f);
903- fWidth = static_cast<float>(gearTexture->width);
904- fHeight = static_cast<float>(gearTexture->height);
905- _gear = new LAppSprite(x, y, fWidth, fHeight, gearTexture->id, _programId);
906-
907- imageName = PowerImageName;
908- LAppTextureManager::TextureInfo* powerTexture = textureManager->CreateTextureFromPngFile(resourcesPath + imageName);
909-
910- x = static_cast<float>(width - powerTexture->width * 0.5f);
911- y = static_cast<float>(powerTexture->height * 0.5f);
912- fWidth = static_cast<float>(powerTexture->width);
913- fHeight = static_cast<float>(powerTexture->height);
914- _power = new LAppSprite(x, y, fWidth, fHeight, powerTexture->id, _programId);
915-
916 // 画面全体を覆うサイズ
917 x = width * 0.5f;
918 y = height * 0.5f;
919@@ -175,52 +146,6 @@ void LAppView::InitializeSprite()
920
921 }
922
923-void LAppView::OnTouchesBegan(float px, float py) const
924-{
925- _touchManager->TouchesBegan(px, py);
926-}
927-
928-void LAppView::OnTouchesMoved(float px, float py) const
929-{
930- float viewX = this->TransformViewX(_touchManager->GetX());
931- float viewY = this->TransformViewY(_touchManager->GetY());
932-
933- _touchManager->TouchesMoved(px, py);
934-
935- LAppLive2DManager* Live2DManager = LAppLive2DManager::GetInstance();
936- Live2DManager->OnDrag(viewX, viewY);
937-}
938-
939-void LAppView::OnTouchesEnded(float px, float py) const
940-{
941- // タッチ終了
942- LAppLive2DManager* live2DManager = LAppLive2DManager::GetInstance();
943- live2DManager->OnDrag(0.0f, 0.0f);
944- {
945-
946- // シングルタップ
947- float x = _deviceToScreen->TransformX(_touchManager->GetX()); // 論理座標変換した座標を取得。
948- float y = _deviceToScreen->TransformY(_touchManager->GetY()); // 論理座標変換した座標を取得。
949- if (DebugTouchLogEnable)
950- {
951- LAppPal::PrintLog("[APP]touchesEnded x:%.2f y:%.2f", x, y);
952- }
953- live2DManager->OnTap(x, y);
954-
955- // 歯車にタップしたか
956- if (_gear->IsHit(px, py))
957- {
958- live2DManager->NextScene();
959- }
960-
961- // 電源ボタンにタップしたか
962- if (_power->IsHit(px, py))
963- {
964- LAppDelegate::GetInstance()->AppEnd();
965- }
966- }
967-}
968-
969 float LAppView::TransformViewX(float deviceX) const
970 {
971 float screenX = _deviceToScreen->TransformX(deviceX); // 論理座標変換した座標を取得。
972@@ -362,32 +287,4 @@ void LAppView::ResizeSprite()
973 _back->ResetRect(x, y, fWidth, fHeight);
974 }
975 }
976-
977- if (_power)
978- {
979- GLuint id = _power->GetTextureId();
980- LAppTextureManager::TextureInfo* texInfo = textureManager->GetTextureInfoById(id);
981- if (texInfo)
982- {
983- x = static_cast<float>(width - texInfo->width * 0.5f);
984- y = static_cast<float>(texInfo->height * 0.5f);
985- fWidth = static_cast<float>(texInfo->width);
986- fHeight = static_cast<float>(texInfo->height);
987- _power->ResetRect(x, y, fWidth, fHeight);
988- }
989- }
990-
991- if (_gear)
992- {
993- GLuint id = _gear->GetTextureId();
994- LAppTextureManager::TextureInfo* texInfo = textureManager->GetTextureInfoById(id);
995- if (texInfo)
996- {
997- x = static_cast<float>(width - texInfo->width * 0.5f);
998- y = static_cast<float>(height - texInfo->height * 0.5f);
999- fWidth = static_cast<float>(texInfo->width);
1000- fHeight = static_cast<float>(texInfo->height);
1001- _gear->ResetRect(x, y, fWidth, fHeight);
1002- }
1003- }
1004 }
1005diff -pruN --exclude build ./demo_clean/src/LAppView.hpp ./demo_dev/src/LAppView.hpp
eba2eb3a 1006--- ./demo_clean/src/LAppView.hpp 2020-10-01 22:47:25.846828066 +0100
126d8fa4 1007+++ ./demo_dev/src/LAppView.hpp 2020-10-01 22:47:24.802846999 +0100
830d0ba4
AIL
1008@@ -14,7 +14,6 @@
1009 #include "CubismFramework.hpp"
1010 #include <Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.hpp>
1011
1012-class TouchManager;
1013 class LAppSprite;
1014 class LAppModel;
1015
1016@@ -66,30 +65,6 @@ public:
1017 void ResizeSprite();
1018
1019 /**
1020- * @brief タッチされたときに呼ばれる。
1021- *
1022- * @param[in] pointX スクリーンX座標
1023- * @param[in] pointY スクリーンY座標
1024- */
1025- void OnTouchesBegan(float pointX, float pointY) const;
1026-
1027- /**
1028- * @brief タッチしているときにポインタが動いたら呼ばれる。
1029- *
1030- * @param[in] pointX スクリーンX座標
1031- * @param[in] pointY スクリーンY座標
1032- */
1033- void OnTouchesMoved(float pointX, float pointY) const;
1034-
1035- /**
1036- * @brief タッチが終了したら呼ばれる。
1037- *
1038- * @param[in] pointX スクリーンX座標
1039- * @param[in] pointY スクリーンY座標
1040- */
1041- void OnTouchesEnded(float pointX, float pointY) const;
1042-
1043- /**
1044 * @brief X座標をView座標に変換する。
1045 *
1046 * @param[in] deviceX デバイスX座標
1047@@ -147,13 +122,10 @@ public:
1048 void SetRenderTargetClearColor(float r, float g, float b);
1049
1050 private:
1051- TouchManager* _touchManager; ///< タッチマネージャー
1052 Csm::CubismMatrix44* _deviceToScreen; ///< デバイスからスクリーンへの行列
1053 Csm::CubismViewMatrix* _viewMatrix; ///< viewMatrix
1054 GLuint _programId; ///< シェーダID
1055 LAppSprite* _back; ///< 背景画像
1056- LAppSprite* _gear; ///< ギア画像
1057- LAppSprite* _power; ///< 電源画像
1058
1059 // レンダリング先を別ターゲットにする方式の場合に使用
1060 LAppSprite* _renderSprite; ///< モードによっては_renderBufferのテクスチャを描画
1061diff -pruN --exclude build ./demo_clean/src/main.cpp ./demo_dev/src/main.cpp
eba2eb3a
AIL
1062--- ./demo_clean/src/main.cpp 2020-10-01 22:47:25.846828066 +0100
1063+++ ./demo_dev/src/main.cpp 2020-10-18 07:03:46.194220443 +0100
1064@@ -5,18 +5,182 @@
830d0ba4
AIL
1065 * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
1066 */
1067
1068+#include <thread>
1069+#include <stdexcept>
1070+#include <sstream>
eba2eb3a
AIL
1071+#include <vector>
1072+#include <utility>
1073+#include <string>
830d0ba4
AIL
1074+
1075+#ifdef __cpp_lib_filesystem
1076+#include <filesystem>
1077+namespace fs = std::filesystem;
1078+#else
1079+#include <experimental/filesystem>
1080+namespace fs = std::experimental::filesystem;
1081+#endif
1082+
eba2eb3a 1083+#include "ICubismModelSetting.hpp"
830d0ba4
AIL
1084 #include "LAppDelegate.hpp"
1085+#include "LAppLive2DManager.hpp"
eba2eb3a 1086+#include "LAppModel.hpp"
126d8fa4 1087+#include "mouse_cursor_tracker.h"
830d0ba4
AIL
1088+
1089+struct CmdArgs
1090+{
1091+ int windowWidth;
1092+ int windowHeight;
1093+ std::string windowTitle;
1094+ std::string rootDir;
1095+ float scaleFactor;
1096+ float translateX;
1097+ float translateY;
1098+ std::string modelName;
126d8fa4 1099+ std::string cfgPath; // Path to config file for MouseCursorTracker
830d0ba4
AIL
1100+};
1101+
1102+CmdArgs parseArgv(int argc, char *argv[])
1103+{
1104+ // I think the command-line args are simple enough to not justify using a library...
1105+ CmdArgs cmdArgs;
1106+ // Set default values
1107+ cmdArgs.windowWidth = 600;
1108+ cmdArgs.windowHeight = 600;
126d8fa4 1109+ cmdArgs.windowTitle = "MouseTrackerForCubism example";
830d0ba4
AIL
1110+ cmdArgs.rootDir = fs::current_path();
1111+ cmdArgs.scaleFactor = 8.0f;
1112+ cmdArgs.translateX = 0.0f;
1113+ cmdArgs.translateY = -2.8f;
1114+ cmdArgs.modelName = "Haru";
1115+ cmdArgs.cfgPath = "";
1116+
1117+ int i = 1;
1118+ while (i < argc)
1119+ {
1120+ std::string arg = argv[i];
1121+ std::stringstream ss;
1122+
1123+ if (arg == "--window-width" || arg == "-W") // capital W for consistency with height
1124+ {
1125+ ss << argv[i + 1];
1126+ if (!(ss >> cmdArgs.windowWidth))
1127+ {
1128+ throw std::runtime_error("Invalid argument for window width");
1129+ }
1130+ }
1131+ else if (arg == "--window-height" || arg == "-H") // avoiding "-h", typically for help
1132+ {
1133+ ss << argv[i + 1];
1134+ if (!(ss >> cmdArgs.windowHeight))
1135+ {
1136+ throw std::runtime_error("Invalid argument for window height");
1137+ }
1138+ }
1139+ else if (arg == "--window-title" || arg == "-t")
1140+ {
1141+ cmdArgs.windowTitle = argv[i + 1];
1142+ }
1143+ else if (arg == "--root-dir" || arg == "-d")
1144+ {
1145+ cmdArgs.rootDir = argv[i + 1];
1146+ }
1147+ else if (arg == "--scale-factor" || arg == "-f")
1148+ {
1149+ ss << argv[i + 1];
1150+ if (!(ss >> cmdArgs.scaleFactor))
1151+ {
1152+ throw std::runtime_error("Invalid argument for scale factor");
1153+ }
1154+ }
1155+ else if (arg == "--translate-x" || arg == "-x")
1156+ {
1157+ ss << argv[i + 1];
1158+ if (!(ss >> cmdArgs.translateX))
1159+ {
1160+ throw std::runtime_error("Invalid argument for translate X");
1161+ }
1162+ }
1163+ else if (arg == "--translate-y" || arg == "-y")
1164+ {
1165+ ss << argv[i + 1];
1166+ if (!(ss >> cmdArgs.translateY))
1167+ {
1168+ throw std::runtime_error("Invalid argument for translate Y");
1169+ }
1170+ }
1171+ else if (arg == "--model" || arg == "-m")
1172+ {
1173+ cmdArgs.modelName = argv[i + 1];
1174+ }
1175+ else if (arg == "--config" || arg == "-c")
1176+ {
1177+ cmdArgs.cfgPath = argv[i + 1];
1178+ }
1179+ else
1180+ {
1181+ throw std::runtime_error("Unrecognized argument: " + arg);
1182+ }
1183+
1184+ i += 2;
1185+ }
1186+
1187+ return cmdArgs;
1188+}
1189
1190 int main(int argc, char* argv[])
1191 {
1192- // create the application instance
1193- if (LAppDelegate::GetInstance()->Initialize() == GL_FALSE)
1194+ auto cmdArgs = parseArgv(argc, argv);
1195+
1196+ LAppDelegate *delegate = LAppDelegate::GetInstance();
1197+
1198+ if (!delegate->Initialize(cmdArgs.windowWidth,
1199+ cmdArgs.windowHeight,
1200+ cmdArgs.windowTitle.c_str()))
1201 {
1202- return 1;
1203+ throw std::runtime_error("Unable to initialize LAppDelegate");
1204 }
1205
1206- LAppDelegate::GetInstance()->Run();
1207+ delegate->SetRootDirectory(cmdArgs.rootDir);
1208+
830d0ba4
AIL
1209+ LAppLive2DManager *manager = LAppLive2DManager::GetInstance();
1210+ manager->SetModel(cmdArgs.modelName);
1211+
1212+ manager->SetProjectionScaleTranslate(cmdArgs.scaleFactor,
1213+ cmdArgs.translateX,
1214+ cmdArgs.translateY);
eba2eb3a
AIL
1215+
1216+ LAppModel *model = manager->GetModel(0);
1217+ if (!model) throw std::runtime_error("model is null");
1218+
1219+ Live2D::Cubism::Framework::ICubismModelSetting *modelSetting = model->GetModelSetting();
1220+ if (!modelSetting) throw std::runtime_error("modelSetting is null");
1221+
1222+ std::vector<std::pair<std::string, int> > motions;
1223+ int motionGroupCount = modelSetting->GetMotionGroupCount();
1224+ for (int i = 0; i < motionGroupCount; i++)
1225+ {
1226+ const char *motionGroup = modelSetting->GetMotionGroupName(i);
1227+ int motionCount = modelSetting->GetMotionCount(motionGroup);
1228+ motions.push_back(std::make_pair(std::string(motionGroup), motionCount));
1229+ }
1230+
1231+ std::vector<std::string> expressions;
1232+ int expCount = modelSetting->GetExpressionCount();
1233+ for (int i = 0; i < expCount; i++)
1234+ {
1235+ const char *expName = modelSetting->GetExpressionName(i);
1236+ expressions.push_back(std::string(expName));
1237+ }
1238+
1239+ MouseCursorTracker tracker(cmdArgs.cfgPath, motions, expressions);
1240+
1241+ std::thread trackerThread(&MouseCursorTracker::mainLoop, &tracker);
126d8fa4 1242+ manager->SetTracker(&tracker);
830d0ba4
AIL
1243+
1244+ delegate->Run();
1245+
126d8fa4
AIL
1246+ tracker.stop();
1247+ trackerThread.join();
830d0ba4
AIL
1248
1249 return 0;
1250 }
1251-