Upgrade to Cubism 4 Release R7.
[mouse-tracker-for-cubism.git] / example / demo.patch
CommitLineData
830d0ba4 1diff -pruN --exclude build ./demo_clean/CMakeLists.txt ./demo_dev/CMakeLists.txt
2772c864
AIL
2--- ./demo_clean/CMakeLists.txt 2023-05-18 09:58:50.000000000 +0100
3+++ ./demo_dev/CMakeLists.txt 2023-05-28 09:11:29.467788463 +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}/../../../..)
2772c864 9+set(SDK_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../CubismSdkForNative-4-r.7)
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
2772c864
AIL
57--- ./demo_clean/scripts/make_gcc 2023-05-18 09:58:50.000000000 +0100
58+++ ./demo_dev/scripts/make_gcc 2023-05-28 09:11:29.467788463 +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
2772c864
AIL
104--- ./demo_clean/src/CMakeLists.txt 2023-05-18 09:58:50.000000000 +0100
105+++ ./demo_dev/src/CMakeLists.txt 2023-05-28 09:11:29.471788536 +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
2772c864
AIL
170--- ./demo_clean/src/LAppDefine.cpp 2023-05-18 09:58:50.000000000 +0100
171+++ ./demo_dev/src/LAppDefine.cpp 2023-05-28 09:11:29.471788536 +0100
5c2628e8 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
2772c864
AIL
187--- ./demo_clean/src/LAppDelegate.cpp 2023-05-18 09:58:50.000000000 +0100
188+++ ./demo_dev/src/LAppDelegate.cpp 2023-05-28 09:11:29.471788536 +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
2772c864
AIL
331--- ./demo_clean/src/LAppDelegate.hpp 2023-05-18 09:58:50.000000000 +0100
332+++ ./demo_dev/src/LAppDelegate.hpp 2023-05-28 09:11:29.467788463 +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
2772c864
AIL
407--- ./demo_clean/src/LAppLive2DManager.cpp 2023-05-18 09:58:50.000000000 +0100
408+++ ./demo_dev/src/LAppLive2DManager.cpp 2023-05-28 09:11:29.467788463 +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
2772c864
AIL
547--- ./demo_clean/src/LAppLive2DManager.hpp 2023-05-18 09:58:50.000000000 +0100
548+++ ./demo_dev/src/LAppLive2DManager.hpp 2023-05-28 09:11:29.467788463 +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
2772c864
AIL
626--- ./demo_clean/src/LAppModel.cpp 2023-05-18 09:58:50.000000000 +0100
627+++ ./demo_dev/src/LAppModel.cpp 2023-05-28 09:16:04.144770508 +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);
2772c864 706@@ -347,86 +341,117 @@ 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
2772c864
AIL
734- // 不透明度
735- _opacity = _model->GetModelOpacity();
736+ _model->LoadParameters(); // 前回セーブされた状態をロード
737
830d0ba4
AIL
738- // まばたき
739- if (!motionUpdated)
740- {
741- if (_eyeBlink != NULL)
eba2eb3a
AIL
742+ int paramsMotionPriority = static_cast<int>(params.motionPriority);
743+
744+ if (paramsMotionPriority != PriorityNone)
2b1f0c7c 745 {
830d0ba4
AIL
746- // メインモーションの更新がないとき
747- _eyeBlink->UpdateParameters(_model, deltaTimeSeconds); // 目パチ
eba2eb3a
AIL
748+ StartMotion(params.motionGroup.c_str(), params.motionNumber,
749+ paramsMotionPriority);
2772c864
AIL
750 }
751- }
eba2eb3a
AIL
752+ else if (params.randomIdleMotion && _motionManager->IsFinished())
753+ {
2b1f0c7c
AIL
754+ // モーションの再生がない場合、待機モーションの中からランダムで再生する
755+ StartRandomMotion(MotionGroupIdle, PriorityIdle);
2772c864 756+ }
eba2eb3a
AIL
757+ // FIXME pose does not return to normal after motion
758+ // if we don't have randomIdleMotion set
759+ else
760+ {
761+ _motionManager->UpdateMotion(_model, deltaTimeSeconds); // モーションを更新
762+ }
763+ _model->SaveParameters(); // 状態を保存
126d8fa4 764
2772c864
AIL
765- if (_expressionManager != NULL)
766- {
767- _expressionManager->UpdateMotion(_model, deltaTimeSeconds); // 表情でパラメータ更新(相対変化)
768- }
eba2eb3a 769+ if (params.expression != "")
126d8fa4 770+ {
eba2eb3a 771+ SetExpression(params.expression.c_str());
126d8fa4 772+ }
eba2eb3a 773+ if (_expressionManager != NULL)
2b1f0c7c 774+ {
eba2eb3a 775+ _expressionManager->UpdateMotion(_model, deltaTimeSeconds); // 表情でパラメータ更新(相対変化)
2b1f0c7c 776+ }
126d8fa4 777
2772c864
AIL
778- //ドラッグによる変化
779- //ドラッグによる顔の向きの調整
780- _model->AddParameterValue(_idParamAngleX, _dragX * 30); // -30から30の値を加える
781- _model->AddParameterValue(_idParamAngleY, _dragY * 30);
782- _model->AddParameterValue(_idParamAngleZ, _dragX * _dragY * -30);
eba2eb3a
AIL
783+ bool autoBlink = params.autoBlink && _eyeBlink;
784+ auto eyeLOpenIt = params.live2d.find("ParamEyeLOpen");
785+ auto eyeROpenIt = params.live2d.find("ParamEyeROpen");
2b1f0c7c 786
2772c864
AIL
787- //ドラッグによる体の向きの調整
788- _model->AddParameterValue(_idParamBodyAngleX, _dragX * 10); // -10から10の値を加える
eba2eb3a 789+ if (autoBlink)
126d8fa4 790+ {
eba2eb3a
AIL
791+ // Handle blink first
792+ _eyeBlink->UpdateParameters(_model, deltaTimeSeconds);
793+ }
830d0ba4 794
2772c864
AIL
795- //ドラッグによる目の向きの調整
796- _model->AddParameterValue(_idParamEyeBallX, _dragX); // -1から1の値を加える
797- _model->AddParameterValue(_idParamEyeBallY, _dragY);
eba2eb3a
AIL
798+ if (eyeLOpenIt != params.live2d.end())
799+ {
800+ // If value specified, override blinking
2c3e79c6 801+ _model->SetParameterValue(idMan->GetId(_("ParamEyeLOpen")),
eba2eb3a
AIL
802+ eyeLOpenIt->second);
803+ }
804+ else if (!autoBlink)
805+ {
806+ // If no value specified and no auto blink, set to 1
2c3e79c6 807+ _model->SetParameterValue(idMan->GetId(_("ParamEyeLOpen")), 1);
76316970 808
2772c864
AIL
809- // 呼吸など
810- if (_breath != NULL)
76316970 811- {
2772c864 812- _breath->UpdateParameters(_model, deltaTimeSeconds);
76316970 813- }
eba2eb3a 814+ }
76316970 815
2772c864
AIL
816- // 物理演算の設定
817- if (_physics != NULL)
76316970 818- {
2772c864
AIL
819- _physics->Evaluate(_model, deltaTimeSeconds);
820- }
eba2eb3a
AIL
821+ if (eyeROpenIt != params.live2d.end())
822+ {
2c3e79c6 823+ _model->SetParameterValue(idMan->GetId(_("ParamEyeROpen")),
eba2eb3a
AIL
824+ eyeROpenIt->second);
825+ }
826+ else if (!autoBlink)
827+ {
2c3e79c6 828+ _model->SetParameterValue(idMan->GetId(_("ParamEyeROpen")), 1);
eba2eb3a 829+ }
2772c864
AIL
830
831- // リップシンクの設定
832- if (_lipSync)
833- {
834- // リアルタイムでリップシンクを行う場合、システムから音量を取得して0〜1の範囲で値を入力します。
835- csmFloat32 value = 0.0f;
836
837- // 状態更新/RMS値取得
838- _wavFileHandler.Update(deltaTimeSeconds);
839- value = _wavFileHandler.GetRms();
eba2eb3a 840+ if (params.useLipSync && _lipSync)
5c2628e8 841+ {
eba2eb3a
AIL
842+ csmFloat32 value = params.lipSyncParam; // 0 to 1
843+
126d8fa4
AIL
844+ for (csmUint32 i = 0; i < _lipSyncIds.GetSize(); ++i)
845+ {
846+ _model->AddParameterValue(_lipSyncIds[i], value, 0.8f);
847+ }
2b1f0c7c
AIL
848+ }
849+ else
850+ {
2c3e79c6 851+ _model->SetParameterValue(idMan->GetId(_("ParamMouthOpenY")),
eba2eb3a
AIL
852+ params.live2d["ParamMouthOpenY"]);
853+ }
854+
855+ for (auto const &entry : params.live2d)
856+ {
857+ std::string key = entry.first;
858+ double val = entry.second;
2772c864 859+
eba2eb3a
AIL
860+ if (key != "ParamEyeLOpen" && key != "ParamEyeROpen" &&
861+ key != "ParamMouthOpenY")
862+ {
2c3e79c6 863+ _model->SetParameterValue(idMan->GetId(_(key)), val);
eba2eb3a 864+ }
2b1f0c7c 865+ }
5c2628e8
AIL
866
867- for (csmUint32 i = 0; i < _lipSyncIds.GetSize(); ++i)
2b1f0c7c 868+ if (params.autoBreath && _breath)
5c2628e8
AIL
869 {
870- _model->AddParameterValue(_lipSyncIds[i], value, 0.8f);
2b1f0c7c
AIL
871+ // Note: _model->LoadParameters and SaveParameters is needed
872+ // before - see above.
873+ _breath->UpdateParameters(_model, deltaTimeSeconds);
76316970 874 }
830d0ba4
AIL
875 }
876
76316970
AIL
877+ // 物理演算の設定
878+ if (_physics != NULL)
879+ {
880+ _physics->Evaluate(_model, deltaTimeSeconds);
881+ }
882+
830d0ba4
AIL
883 // ポーズの設定
884 if (_pose != NULL)
885 {
2772c864 886@@ -495,7 +520,6 @@ CubismMotionQueueEntryHandle LAppModel::
76316970
AIL
887 {
888 csmString path = voice;
889 path = _modelHomeDir + path;
890- _wavFileHandler.Start(path);
891 }
892
893 if (_debugMode)
2772c864 894@@ -647,3 +671,42 @@ Csm::Rendering::CubismOffscreenFrame_Ope
830d0ba4
AIL
895 {
896 return _renderBuffer;
897 }
898+
126d8fa4 899+void LAppModel::SetTracker(MouseCursorTracker *tracker)
830d0ba4 900+{
126d8fa4 901+ _tracker = tracker;
830d0ba4
AIL
902+}
903+
eba2eb3a
AIL
904+Csm::ICubismModelSetting* LAppModel::GetModelSetting(void) const
905+{
906+ return _modelSetting;
907+}
908+
2c3e79c6
AIL
909+Csm::csmString LAppModel::_(std::string s)
910+{
911+ std::string ans;
912+ if (_useOldParamId)
913+ {
914+ if (s == "ParamTere")
915+ {
916+ ans = "PARAM_CHEEK";
917+ }
918+ else
919+ {
920+ for (size_t i = 0; i < s.size(); i++)
921+ {
922+ if (std::isupper(s[i]) && i != 0)
923+ {
924+ ans += '_';
925+ }
926+ ans += std::toupper(s[i]);
927+ }
928+ }
929+ }
930+ else
931+ {
932+ ans = s;
933+ }
934+ return csmString(ans.c_str());
935+}
936+
830d0ba4 937diff -pruN --exclude build ./demo_clean/src/LAppModel.hpp ./demo_dev/src/LAppModel.hpp
2772c864
AIL
938--- ./demo_clean/src/LAppModel.hpp 2023-05-18 09:58:50.000000000 +0100
939+++ ./demo_dev/src/LAppModel.hpp 2023-05-28 09:11:29.471788536 +0100
76316970 940@@ -13,7 +13,7 @@
830d0ba4
AIL
941 #include <Type/csmRectF.hpp>
942 #include <Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.hpp>
943
76316970 944-#include "LAppWavFileHandler.hpp"
126d8fa4 945+#include "mouse_cursor_tracker.h"
830d0ba4
AIL
946
947 /**
948 * @brief ユーザーが実際に使用するモデルの実装クラス<br>
76316970 949@@ -25,8 +25,11 @@ class LAppModel : public Csm::CubismUser
2c3e79c6
AIL
950 public:
951 /**
952 * @brief コンストラクタ
953+ *
954+ * @param[in] useOldParamId : If true, translate new (Cubism 3+)
955+ * parameter IDs to old (Cubism 2.1) ones
956 */
957- LAppModel();
958+ LAppModel(bool useOldParamId);
959
960 /**
961 * @brief デストラクタ
76316970 962@@ -114,6 +117,15 @@ public:
830d0ba4
AIL
963 */
964 Csm::Rendering::CubismOffscreenFrame_OpenGLES2& GetRenderBuffer();
965
966+ /**
126d8fa4 967+ * @brief Set the pointer to the MouseCursorTracker instance
830d0ba4 968+ *
126d8fa4 969+ * @param[in] tracker : Pointer to MouseCursorTracker instance
830d0ba4 970+ */
126d8fa4 971+ void SetTracker(MouseCursorTracker *tracker);
830d0ba4 972+
eba2eb3a
AIL
973+ Csm::ICubismModelSetting* GetModelSetting(void) const;
974+
830d0ba4
AIL
975 protected:
976 /**
977 * @brief モデルを描画する処理。モデルを描画する空間のView-Projection行列を渡す。
76316970 978@@ -167,6 +179,17 @@ private:
2c3e79c6
AIL
979 */
980 void ReleaseExpressions();
981
982+ /**
983+ * @brief Translate new (Cubism 3+) parameter IDs to old (Cubism 2.1) ones
984+ *
985+ * @param[in] s : New parameter ID
986+ *
987+ * @return Old parameter ID
988+ */
989+ Csm::csmString _(std::string s);
990+
991+ bool _useOldParamId;
992+
993 Csm::ICubismModelSetting* _modelSetting; ///< モデルセッティング情報
994 Csm::csmString _modelHomeDir; ///< モデルセッティングが置かれたディレクトリ
995 Csm::csmFloat32 _userTimeSeconds; ///< デルタ時間の積算値[秒]
76316970
AIL
996@@ -183,9 +206,9 @@ private:
997 const Csm::CubismId* _idParamEyeBallX; ///< パラメータID: ParamEyeBallX
830d0ba4
AIL
998 const Csm::CubismId* _idParamEyeBallY; ///< パラメータID: ParamEyeBallXY
999
76316970
AIL
1000- LAppWavFileHandler _wavFileHandler; ///< wavファイルハンドラ
1001-
830d0ba4
AIL
1002 Csm::Rendering::CubismOffscreenFrame_OpenGLES2 _renderBuffer; ///< フレームバッファ以外の描画先
1003+
126d8fa4 1004+ MouseCursorTracker *_tracker;
830d0ba4
AIL
1005 };
1006
1007
1008diff -pruN --exclude build ./demo_clean/src/LAppPal.cpp ./demo_dev/src/LAppPal.cpp
2772c864
AIL
1009--- ./demo_clean/src/LAppPal.cpp 2023-05-18 09:58:50.000000000 +0100
1010+++ ./demo_dev/src/LAppPal.cpp 2023-05-28 09:11:29.471788536 +0100
830d0ba4
AIL
1011@@ -6,6 +6,7 @@
1012 */
1013
1014 #include "LAppPal.hpp"
1015+#include <stdexcept>
1016 #include <stdio.h>
1017 #include <stdlib.h>
1018 #include <stdarg.h>
eba2eb3a
AIL
1019@@ -36,7 +37,6 @@ csmByte* LAppPal::LoadFileAsBytes(const
1020 if (stat(path, &statBuf) == 0)
1021 {
1022 size = statBuf.st_size;
1023- PrintLog(path);
1024 }
1025
1026 std::fstream file;
1027@@ -45,10 +45,7 @@ csmByte* LAppPal::LoadFileAsBytes(const
830d0ba4
AIL
1028 file.open(path, std::ios::in | std::ios::binary);
1029 if (!file.is_open())
1030 {
1031- if (DebugLogEnable)
1032- {
1033- PrintLog("file open error");
1034- }
1035+ throw std::runtime_error("Failed to open file " + filePath);
1036 return NULL;
1037 }
1038 file.read(buf, size);
1039diff -pruN --exclude build ./demo_clean/src/LAppTextureManager.cpp ./demo_dev/src/LAppTextureManager.cpp
2772c864
AIL
1040--- ./demo_clean/src/LAppTextureManager.cpp 2023-05-18 09:58:50.000000000 +0100
1041+++ ./demo_dev/src/LAppTextureManager.cpp 2023-05-28 09:11:29.471788536 +0100
830d0ba4
AIL
1042@@ -96,6 +96,46 @@ LAppTextureManager::TextureInfo* LAppTex
1043
1044 }
1045
1046+LAppTextureManager::TextureInfo* LAppTextureManager::CreateTextureFromColor(
1047+ uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha
1048+)
1049+{
1050+ int width = 8, height = 8;
1051+
1052+ uint8_t pixels[height][width][4];
1053+ for (std::size_t h = 0; h < height; h++)
1054+ {
1055+ for (std::size_t w = 0; w < width; w++)
1056+ {
1057+ pixels[h][w][0] = red;
1058+ pixels[h][w][1] = green;
1059+ pixels[h][w][2] = blue;
1060+ pixels[h][w][3] = alpha;
1061+ }
1062+ }
1063+
1064+ GLuint textureId;
1065+ glGenTextures(1, &textureId);
1066+ glBindTexture(GL_TEXTURE_2D, textureId);
1067+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1068+
1069+ glGenerateMipmap(GL_TEXTURE_2D);
1070+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1071+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1072+ glBindTexture(GL_TEXTURE_2D, 0);
1073+
1074+
1075+ LAppTextureManager::TextureInfo* textureInfo = new LAppTextureManager::TextureInfo();
1076+ textureInfo->fileName = "";
1077+ textureInfo->width = width;
1078+ textureInfo->height = height;
1079+ textureInfo->id = textureId;
1080+
1081+ _textures.PushBack(textureInfo);
1082+
1083+ return textureInfo;
1084+}
1085+
1086 void LAppTextureManager::ReleaseTextures()
1087 {
1088 for (Csm::csmUint32 i = 0; i < _textures.GetSize(); i++)
1089diff -pruN --exclude build ./demo_clean/src/LAppTextureManager.hpp ./demo_dev/src/LAppTextureManager.hpp
2772c864
AIL
1090--- ./demo_clean/src/LAppTextureManager.hpp 2023-05-18 09:58:50.000000000 +0100
1091+++ ./demo_dev/src/LAppTextureManager.hpp 2023-05-28 09:11:29.471788536 +0100
830d0ba4
AIL
1092@@ -72,6 +72,8 @@ public:
1093 */
1094 TextureInfo* CreateTextureFromPngFile(std::string fileName);
1095
1096+ TextureInfo *CreateTextureFromColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha = 255);
1097+
1098 /**
1099 * @brief 画像の解放
1100 *
1101diff -pruN --exclude build ./demo_clean/src/LAppView.cpp ./demo_dev/src/LAppView.cpp
2772c864
AIL
1102--- ./demo_clean/src/LAppView.cpp 2023-05-18 09:58:50.000000000 +0100
1103+++ ./demo_dev/src/LAppView.cpp 2023-05-28 09:11:29.471788536 +0100
830d0ba4
AIL
1104@@ -13,7 +13,6 @@
1105 #include "LAppLive2DManager.hpp"
1106 #include "LAppTextureManager.hpp"
1107 #include "LAppDefine.hpp"
1108-#include "TouchManager.hpp"
1109 #include "LAppSprite.hpp"
1110 #include "LAppModel.hpp"
1111
1112@@ -26,8 +25,6 @@ using namespace LAppDefine;
1113 LAppView::LAppView():
1114 _programId(0),
1115 _back(NULL),
1116- _gear(NULL),
1117- _power(NULL),
1118 _renderSprite(NULL),
1119 _renderTarget(SelectTarget_None)
1120 {
1121@@ -35,8 +32,6 @@ LAppView::LAppView():
1122 _clearColor[1] = 1.0f;
1123 _clearColor[2] = 1.0f;
1124 _clearColor[3] = 0.0f;
1125- // タッチ関係のイベント管理
1126- _touchManager = new TouchManager();
1127
1128 // デバイス座標からスクリーン座標に変換するための
1129 _deviceToScreen = new CubismMatrix44();
1130@@ -52,10 +47,7 @@ LAppView::~LAppView()
1131
1132 delete _viewMatrix;
1133 delete _deviceToScreen;
1134- delete _touchManager;
1135 delete _back;
1136- delete _gear;
1137- delete _power;
1138 }
1139
1140 void LAppView::Initialize()
76316970 1141@@ -107,9 +99,6 @@ void LAppView::Initialize()
830d0ba4
AIL
1142 void LAppView::Render()
1143 {
1144 _back->Render();
1145- _gear->Render();
1146- _power->Render();
1147-
1148
1149 LAppLive2DManager* Live2DManager = LAppLive2DManager::GetInstance();
1150
76316970 1151@@ -151,35 +140,17 @@ void LAppView::InitializeSprite()
830d0ba4
AIL
1152 glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
1153
1154 LAppTextureManager* textureManager = LAppDelegate::GetInstance()->GetTextureManager();
1155- const string resourcesPath = LAppDelegate::GetInstance()->GetRootDirectory() + ResourcesPath;
1156
1157- string imageName = BackImageName;
1158- LAppTextureManager::TextureInfo* backgroundTexture = textureManager->CreateTextureFromPngFile(resourcesPath + imageName);
1159+
1160+ LAppTextureManager::TextureInfo* backgroundTexture =
1161+ textureManager->CreateTextureFromColor(0, 255, 0);
1162
1163 float x = width * 0.5f;
1164 float y = height * 0.5f;
1165- float fWidth = static_cast<float>(backgroundTexture->width * 2.0f);
1166- float fHeight = static_cast<float>(height) * 0.95f;
1167+ float fWidth = static_cast<float>(width);
1168+ float fHeight = static_cast<float>(height);
1169 _back = new LAppSprite(x, y, fWidth, fHeight, backgroundTexture->id, _programId);
1170
1171- imageName = GearImageName;
1172- LAppTextureManager::TextureInfo* gearTexture = textureManager->CreateTextureFromPngFile(resourcesPath + imageName);
1173-
1174- x = static_cast<float>(width - gearTexture->width * 0.5f);
1175- y = static_cast<float>(height - gearTexture->height * 0.5f);
1176- fWidth = static_cast<float>(gearTexture->width);
1177- fHeight = static_cast<float>(gearTexture->height);
1178- _gear = new LAppSprite(x, y, fWidth, fHeight, gearTexture->id, _programId);
1179-
1180- imageName = PowerImageName;
1181- LAppTextureManager::TextureInfo* powerTexture = textureManager->CreateTextureFromPngFile(resourcesPath + imageName);
1182-
1183- x = static_cast<float>(width - powerTexture->width * 0.5f);
1184- y = static_cast<float>(powerTexture->height * 0.5f);
1185- fWidth = static_cast<float>(powerTexture->width);
1186- fHeight = static_cast<float>(powerTexture->height);
1187- _power = new LAppSprite(x, y, fWidth, fHeight, powerTexture->id, _programId);
1188-
1189 // 画面全体を覆うサイズ
1190 x = width * 0.5f;
1191 y = height * 0.5f;
76316970 1192@@ -187,52 +158,6 @@ void LAppView::InitializeSprite()
830d0ba4
AIL
1193
1194 }
1195
1196-void LAppView::OnTouchesBegan(float px, float py) const
1197-{
1198- _touchManager->TouchesBegan(px, py);
1199-}
1200-
1201-void LAppView::OnTouchesMoved(float px, float py) const
1202-{
1203- float viewX = this->TransformViewX(_touchManager->GetX());
1204- float viewY = this->TransformViewY(_touchManager->GetY());
1205-
1206- _touchManager->TouchesMoved(px, py);
1207-
1208- LAppLive2DManager* Live2DManager = LAppLive2DManager::GetInstance();
1209- Live2DManager->OnDrag(viewX, viewY);
1210-}
1211-
1212-void LAppView::OnTouchesEnded(float px, float py) const
1213-{
1214- // タッチ終了
1215- LAppLive2DManager* live2DManager = LAppLive2DManager::GetInstance();
1216- live2DManager->OnDrag(0.0f, 0.0f);
1217- {
1218-
1219- // シングルタップ
1220- float x = _deviceToScreen->TransformX(_touchManager->GetX()); // 論理座標変換した座標を取得。
1221- float y = _deviceToScreen->TransformY(_touchManager->GetY()); // 論理座標変換した座標を取得。
1222- if (DebugTouchLogEnable)
1223- {
1224- LAppPal::PrintLog("[APP]touchesEnded x:%.2f y:%.2f", x, y);
1225- }
1226- live2DManager->OnTap(x, y);
1227-
1228- // 歯車にタップしたか
1229- if (_gear->IsHit(px, py))
1230- {
1231- live2DManager->NextScene();
1232- }
1233-
1234- // 電源ボタンにタップしたか
1235- if (_power->IsHit(px, py))
1236- {
1237- LAppDelegate::GetInstance()->AppEnd();
1238- }
1239- }
1240-}
1241-
1242 float LAppView::TransformViewX(float deviceX) const
1243 {
1244 float screenX = _deviceToScreen->TransformX(deviceX); // 論理座標変換した座標を取得。
76316970 1245@@ -374,32 +299,4 @@ void LAppView::ResizeSprite()
830d0ba4
AIL
1246 _back->ResetRect(x, y, fWidth, fHeight);
1247 }
1248 }
1249-
1250- if (_power)
1251- {
1252- GLuint id = _power->GetTextureId();
1253- LAppTextureManager::TextureInfo* texInfo = textureManager->GetTextureInfoById(id);
1254- if (texInfo)
1255- {
1256- x = static_cast<float>(width - texInfo->width * 0.5f);
1257- y = static_cast<float>(texInfo->height * 0.5f);
1258- fWidth = static_cast<float>(texInfo->width);
1259- fHeight = static_cast<float>(texInfo->height);
1260- _power->ResetRect(x, y, fWidth, fHeight);
1261- }
1262- }
1263-
1264- if (_gear)
1265- {
1266- GLuint id = _gear->GetTextureId();
1267- LAppTextureManager::TextureInfo* texInfo = textureManager->GetTextureInfoById(id);
1268- if (texInfo)
1269- {
1270- x = static_cast<float>(width - texInfo->width * 0.5f);
1271- y = static_cast<float>(height - texInfo->height * 0.5f);
1272- fWidth = static_cast<float>(texInfo->width);
1273- fHeight = static_cast<float>(texInfo->height);
1274- _gear->ResetRect(x, y, fWidth, fHeight);
1275- }
1276- }
1277 }
1278diff -pruN --exclude build ./demo_clean/src/LAppView.hpp ./demo_dev/src/LAppView.hpp
2772c864
AIL
1279--- ./demo_clean/src/LAppView.hpp 2023-05-18 09:58:50.000000000 +0100
1280+++ ./demo_dev/src/LAppView.hpp 2023-05-28 09:11:29.471788536 +0100
830d0ba4
AIL
1281@@ -14,7 +14,6 @@
1282 #include "CubismFramework.hpp"
1283 #include <Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.hpp>
1284
1285-class TouchManager;
1286 class LAppSprite;
1287 class LAppModel;
1288
1289@@ -66,30 +65,6 @@ public:
1290 void ResizeSprite();
1291
1292 /**
1293- * @brief タッチされたときに呼ばれる。
1294- *
1295- * @param[in] pointX スクリーンX座標
1296- * @param[in] pointY スクリーンY座標
1297- */
1298- void OnTouchesBegan(float pointX, float pointY) const;
1299-
1300- /**
1301- * @brief タッチしているときにポインタが動いたら呼ばれる。
1302- *
1303- * @param[in] pointX スクリーンX座標
1304- * @param[in] pointY スクリーンY座標
1305- */
1306- void OnTouchesMoved(float pointX, float pointY) const;
1307-
1308- /**
1309- * @brief タッチが終了したら呼ばれる。
1310- *
1311- * @param[in] pointX スクリーンX座標
1312- * @param[in] pointY スクリーンY座標
1313- */
1314- void OnTouchesEnded(float pointX, float pointY) const;
1315-
1316- /**
1317 * @brief X座標をView座標に変換する。
1318 *
1319 * @param[in] deviceX デバイスX座標
1320@@ -147,13 +122,10 @@ public:
1321 void SetRenderTargetClearColor(float r, float g, float b);
1322
1323 private:
1324- TouchManager* _touchManager; ///< タッチマネージャー
1325 Csm::CubismMatrix44* _deviceToScreen; ///< デバイスからスクリーンへの行列
1326 Csm::CubismViewMatrix* _viewMatrix; ///< viewMatrix
1327 GLuint _programId; ///< シェーダID
1328 LAppSprite* _back; ///< 背景画像
1329- LAppSprite* _gear; ///< ギア画像
1330- LAppSprite* _power; ///< 電源画像
1331
1332 // レンダリング先を別ターゲットにする方式の場合に使用
1333 LAppSprite* _renderSprite; ///< モードによっては_renderBufferのテクスチャを描画
1334diff -pruN --exclude build ./demo_clean/src/main.cpp ./demo_dev/src/main.cpp
2772c864
AIL
1335--- ./demo_clean/src/main.cpp 2023-05-18 09:58:50.000000000 +0100
1336+++ ./demo_dev/src/main.cpp 2023-05-28 09:11:29.467788463 +0100
2c3e79c6 1337@@ -5,18 +5,188 @@
830d0ba4
AIL
1338 * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
1339 */
1340
1341+#include <thread>
1342+#include <stdexcept>
1343+#include <sstream>
eba2eb3a
AIL
1344+#include <vector>
1345+#include <utility>
1346+#include <string>
830d0ba4
AIL
1347+
1348+#ifdef __cpp_lib_filesystem
1349+#include <filesystem>
1350+namespace fs = std::filesystem;
1351+#else
1352+#include <experimental/filesystem>
1353+namespace fs = std::experimental::filesystem;
1354+#endif
1355+
eba2eb3a 1356+#include "ICubismModelSetting.hpp"
830d0ba4
AIL
1357 #include "LAppDelegate.hpp"
1358+#include "LAppLive2DManager.hpp"
eba2eb3a 1359+#include "LAppModel.hpp"
126d8fa4 1360+#include "mouse_cursor_tracker.h"
830d0ba4
AIL
1361+
1362+struct CmdArgs
1363+{
1364+ int windowWidth;
1365+ int windowHeight;
1366+ std::string windowTitle;
1367+ std::string rootDir;
1368+ float scaleFactor;
1369+ float translateX;
1370+ float translateY;
1371+ std::string modelName;
2c3e79c6 1372+ bool oldId; // If true, translate new (Cubism 3+) parameter IDs to old (Cubism 2.1) IDs
126d8fa4 1373+ std::string cfgPath; // Path to config file for MouseCursorTracker
830d0ba4
AIL
1374+};
1375+
1376+CmdArgs parseArgv(int argc, char *argv[])
1377+{
1378+ // I think the command-line args are simple enough to not justify using a library...
1379+ CmdArgs cmdArgs;
1380+ // Set default values
1381+ cmdArgs.windowWidth = 600;
1382+ cmdArgs.windowHeight = 600;
126d8fa4 1383+ cmdArgs.windowTitle = "MouseTrackerForCubism example";
830d0ba4 1384+ cmdArgs.rootDir = fs::current_path();
76316970 1385+ cmdArgs.scaleFactor = 4.5f;
830d0ba4 1386+ cmdArgs.translateX = 0.0f;
76316970 1387+ cmdArgs.translateY = -3.1f;
830d0ba4 1388+ cmdArgs.modelName = "Haru";
2c3e79c6 1389+ cmdArgs.oldId = false;
830d0ba4
AIL
1390+ cmdArgs.cfgPath = "";
1391+
1392+ int i = 1;
1393+ while (i < argc)
1394+ {
1395+ std::string arg = argv[i];
1396+ std::stringstream ss;
1397+
1398+ if (arg == "--window-width" || arg == "-W") // capital W for consistency with height
1399+ {
1400+ ss << argv[i + 1];
1401+ if (!(ss >> cmdArgs.windowWidth))
1402+ {
1403+ throw std::runtime_error("Invalid argument for window width");
1404+ }
1405+ }
1406+ else if (arg == "--window-height" || arg == "-H") // avoiding "-h", typically for help
1407+ {
1408+ ss << argv[i + 1];
1409+ if (!(ss >> cmdArgs.windowHeight))
1410+ {
1411+ throw std::runtime_error("Invalid argument for window height");
1412+ }
1413+ }
1414+ else if (arg == "--window-title" || arg == "-t")
1415+ {
1416+ cmdArgs.windowTitle = argv[i + 1];
1417+ }
1418+ else if (arg == "--root-dir" || arg == "-d")
1419+ {
1420+ cmdArgs.rootDir = argv[i + 1];
1421+ }
1422+ else if (arg == "--scale-factor" || arg == "-f")
1423+ {
1424+ ss << argv[i + 1];
1425+ if (!(ss >> cmdArgs.scaleFactor))
1426+ {
1427+ throw std::runtime_error("Invalid argument for scale factor");
1428+ }
1429+ }
1430+ else if (arg == "--translate-x" || arg == "-x")
1431+ {
1432+ ss << argv[i + 1];
1433+ if (!(ss >> cmdArgs.translateX))
1434+ {
1435+ throw std::runtime_error("Invalid argument for translate X");
1436+ }
1437+ }
1438+ else if (arg == "--translate-y" || arg == "-y")
1439+ {
1440+ ss << argv[i + 1];
1441+ if (!(ss >> cmdArgs.translateY))
1442+ {
1443+ throw std::runtime_error("Invalid argument for translate Y");
1444+ }
1445+ }
1446+ else if (arg == "--model" || arg == "-m")
1447+ {
1448+ cmdArgs.modelName = argv[i + 1];
1449+ }
1450+ else if (arg == "--config" || arg == "-c")
1451+ {
1452+ cmdArgs.cfgPath = argv[i + 1];
1453+ }
2c3e79c6
AIL
1454+ else if (arg == "--old-param-id" || arg == "-o")
1455+ {
1456+ cmdArgs.oldId = (argv[i + 1][0] == '1');
1457+ }
830d0ba4
AIL
1458+ else
1459+ {
1460+ throw std::runtime_error("Unrecognized argument: " + arg);
1461+ }
1462+
1463+ i += 2;
1464+ }
1465+
1466+ return cmdArgs;
1467+}
1468
1469 int main(int argc, char* argv[])
1470 {
1471- // create the application instance
1472- if (LAppDelegate::GetInstance()->Initialize() == GL_FALSE)
1473+ auto cmdArgs = parseArgv(argc, argv);
1474+
1475+ LAppDelegate *delegate = LAppDelegate::GetInstance();
1476+
1477+ if (!delegate->Initialize(cmdArgs.windowWidth,
1478+ cmdArgs.windowHeight,
1479+ cmdArgs.windowTitle.c_str()))
1480 {
1481- return 1;
1482+ throw std::runtime_error("Unable to initialize LAppDelegate");
1483 }
1484
1485- LAppDelegate::GetInstance()->Run();
1486+ delegate->SetRootDirectory(cmdArgs.rootDir);
1487+
830d0ba4 1488+ LAppLive2DManager *manager = LAppLive2DManager::GetInstance();
2c3e79c6 1489+ manager->SetModel(cmdArgs.modelName, cmdArgs.oldId);
830d0ba4
AIL
1490+
1491+ manager->SetProjectionScaleTranslate(cmdArgs.scaleFactor,
1492+ cmdArgs.translateX,
1493+ cmdArgs.translateY);
eba2eb3a
AIL
1494+
1495+ LAppModel *model = manager->GetModel(0);
1496+ if (!model) throw std::runtime_error("model is null");
1497+
1498+ Live2D::Cubism::Framework::ICubismModelSetting *modelSetting = model->GetModelSetting();
1499+ if (!modelSetting) throw std::runtime_error("modelSetting is null");
1500+
1501+ std::vector<std::pair<std::string, int> > motions;
1502+ int motionGroupCount = modelSetting->GetMotionGroupCount();
1503+ for (int i = 0; i < motionGroupCount; i++)
1504+ {
1505+ const char *motionGroup = modelSetting->GetMotionGroupName(i);
1506+ int motionCount = modelSetting->GetMotionCount(motionGroup);
1507+ motions.push_back(std::make_pair(std::string(motionGroup), motionCount));
1508+ }
1509+
1510+ std::vector<std::string> expressions;
1511+ int expCount = modelSetting->GetExpressionCount();
1512+ for (int i = 0; i < expCount; i++)
1513+ {
1514+ const char *expName = modelSetting->GetExpressionName(i);
1515+ expressions.push_back(std::string(expName));
1516+ }
1517+
1518+ MouseCursorTracker tracker(cmdArgs.cfgPath, motions, expressions);
1519+
1520+ std::thread trackerThread(&MouseCursorTracker::mainLoop, &tracker);
126d8fa4 1521+ manager->SetTracker(&tracker);
830d0ba4
AIL
1522+
1523+ delegate->Run();
1524+
126d8fa4
AIL
1525+ tracker.stop();
1526+ trackerThread.join();
830d0ba4
AIL
1527
1528 return 0;
1529 }
1530-