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