Upgrade to Cubism 4 Release R4. 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
cd5de0f5
AIL
2--- ./demo_clean/CMakeLists.txt 2022-01-02 01:49:06.929909588 +0000
3+++ ./demo_dev/CMakeLists.txt 2022-01-02 01:49:31.334289944 +0000
830d0ba4
AIL
4@@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.16)
5 # Set app name.
6 set(APP_NAME Demo)
7 # Set directory paths.
8-set(SDK_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../..)
cd5de0f5 9+set(SDK_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../CubismSdkForNative-4-r.4)
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
cd5de0f5 57--- ./demo_clean/scripts/make_gcc 2022-01-02 01:49:06.929909588 +0000
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
cd5de0f5 104--- ./demo_clean/src/CMakeLists.txt 2022-01-02 01:49:06.929909588 +0000
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
cd5de0f5 170--- ./demo_clean/src/LAppDefine.cpp 2022-01-02 01:49:06.929909588 +0000
76316970
AIL
171+++ ./demo_dev/src/LAppDefine.cpp 2021-04-28 12:18:50.948333190 +0100
172@@ -64,11 +64,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
cd5de0f5 187--- ./demo_clean/src/LAppDelegate.cpp 2022-01-02 01:49:06.929909588 +0000
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
cd5de0f5 331--- ./demo_clean/src/LAppDelegate.hpp 2022-01-02 01:49:06.929909588 +0000
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
cd5de0f5 407--- ./demo_clean/src/LAppLive2DManager.cpp 2022-01-02 01:49:06.929909588 +0000
76316970
AIL
408+++ ./demo_dev/src/LAppLive2DManager.cpp 2021-04-28 12:24:45.405646016 +0100
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
cd5de0f5
AIL
451@@ -127,21 +107,24 @@ void LAppLive2DManager::OnUpdate() const
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);
461 if (model->GetModel()->GetCanvasWidth() > 1.0f && width < height)
76316970
AIL
462 {
463 // 横に長いモデルを縦長ウィンドウに表示する際モデルの横サイズでscaleを算出する
464 model->GetModelMatrix()->SetWidth(2.0f);
465- projection.Scale(1.0f, static_cast<float>(width) / static_cast<float>(height));
466+ projection.Scale(_projScaleFactor,
467+ _projScaleFactor * static_cast<float>(width) / static_cast<float>(height));
468 }
469 else
470 {
471- projection.Scale(static_cast<float>(height) / static_cast<float>(width), 1.0f);
472+ projection.Scale(_projScaleFactor * static_cast<float>(height) / static_cast<float>(width),
473+ _projScaleFactor);
474 }
475+ projection.Translate(_translateX, _translateY);
830d0ba4 476
76316970
AIL
477 // 必要があればここで乗算
478 if (_viewMatrix != NULL)
479@@ -158,30 +141,14 @@ void LAppLive2DManager::OnUpdate() const
830d0ba4
AIL
480 }
481 }
482
483-void LAppLive2DManager::NextScene()
484-{
485- csmInt32 no = (_sceneIndex + 1) % ModelDirSize;
486- ChangeScene(no);
487-}
488-
489-void LAppLive2DManager::ChangeScene(Csm::csmInt32 index)
2c3e79c6 490+void LAppLive2DManager::SetModel(std::string modelName, bool useOldParamId)
830d0ba4
AIL
491 {
492- _sceneIndex = index;
493- if (DebugLogEnable)
494- {
495- LAppPal::PrintLog("[APP]model index: %d", _sceneIndex);
496- }
497-
498- // ModelDir[]に保持したディレクトリ名から
499- // model3.jsonのパスを決定する.
500- // ディレクトリ名とmodel3.jsonの名前を一致させておくこと.
501- std::string model = ModelDir[index];
502- std::string modelPath = LAppDelegate::GetInstance()->GetRootDirectory() + ResourcesPath + model + "/";
503- std::string modelJsonName = ModelDir[index];
504+ std::string modelPath = LAppDelegate::GetInstance()->GetRootDirectory() + ResourcesPath + modelName + "/";
505+ std::string modelJsonName = modelName;
506 modelJsonName += ".model3.json";
507
508 ReleaseAllModel();
2c3e79c6
AIL
509- _models.PushBack(new LAppModel());
510+ _models.PushBack(new LAppModel(useOldParamId));
511 _models[0]->LoadAssets(modelPath.c_str(), modelJsonName.c_str());
512
513 /*
76316970 514@@ -203,7 +170,7 @@ void LAppLive2DManager::ChangeScene(Csm:
2c3e79c6
AIL
515
516 #if defined(USE_RENDER_TARGET) || defined(USE_MODEL_RENDER_TARGET)
517 // モデル個別にαを付けるサンプルとして、もう1体モデルを作成し、少し位置をずらす
518- _models.PushBack(new LAppModel());
519+ _models.PushBack(new LAppModel(useOldParamId));
520 _models[1]->LoadAssets(modelPath.c_str(), modelJsonName.c_str());
521 _models[1]->GetModelMatrix()->TranslateX(0.2f);
522 #endif
76316970
AIL
523@@ -232,3 +199,20 @@ void LAppLive2DManager::SetViewMatrix(Cu
524 _viewMatrix->GetArray()[i] = m->GetArray()[i];
525 }
830d0ba4
AIL
526 }
527+
126d8fa4 528+void LAppLive2DManager::SetTracker(MouseCursorTracker *tracker)
830d0ba4
AIL
529+{
530+ for (auto it = _models.Begin(); it != _models.End(); ++it)
531+ {
126d8fa4 532+ (*it)->SetTracker(tracker);
830d0ba4
AIL
533+ }
534+}
535+
536+void LAppLive2DManager::SetProjectionScaleTranslate(float scaleFactor,
537+ float translateX,
538+ float translateY)
539+{
540+ _projScaleFactor = scaleFactor;
541+ _translateX = translateX;
542+ _translateY = translateY;
543+}
544diff -pruN --exclude build ./demo_clean/src/LAppLive2DManager.hpp ./demo_dev/src/LAppLive2DManager.hpp
cd5de0f5 545--- ./demo_clean/src/LAppLive2DManager.hpp 2022-01-02 01:49:06.929909588 +0000
76316970 546+++ ./demo_dev/src/LAppLive2DManager.hpp 2021-04-28 12:18:50.948333190 +0100
830d0ba4
AIL
547@@ -6,12 +6,15 @@
548 */
549 #pragma once
550
551+#include <string>
552 #include <CubismFramework.hpp>
553 #include <Math/CubismMatrix44.hpp>
554 #include <Type/csmVector.hpp>
555
556 class LAppModel;
557
126d8fa4 558+class MouseCursorTracker;
830d0ba4
AIL
559+
560 /**
561 * @brief サンプルアプリケーションにおいてCubismModelを管理するクラス<br>
562 * モデル生成と破棄、タップイベントの処理、モデル切り替えを行う。
2c3e79c6 563@@ -72,16 +75,14 @@ public:
830d0ba4
AIL
564 void OnUpdate() const;
565
566 /**
567- * @brief 次のシーンに切り替える<br>
568- * サンプルアプリケーションではモデルセットの切り替えを行う。
569- */
570- void NextScene();
571-
572- /**
573- * @brief シーンを切り替える<br>
574- * サンプルアプリケーションではモデルセットの切り替えを行う。
575- */
576- void ChangeScene(Csm::csmInt32 index);
577+ * @brief Set model data
578+ *
579+ * @param[in] modelName : Name of model, should be the same for both
580+ * the directory and the model3.json file
2c3e79c6
AIL
581+ * @param[in] useOldParamId : If true, translate new (Cubism 3+)
582+ * parameter IDs to old (Cubism 2.1) ones
830d0ba4 583+ */
2c3e79c6 584+ void SetModel(std::string modelName, bool useOldParamId);
830d0ba4
AIL
585
586 /**
587 * @brief モデル個数を得る
76316970 588@@ -94,6 +95,24 @@ public:
830d0ba4 589 */
76316970 590 void SetViewMatrix(Live2D::Cubism::Framework::CubismMatrix44* m);
830d0ba4
AIL
591
592+ /**
126d8fa4 593+ * @brief Set the pointer to the MouseCursorTracker instance
830d0ba4 594+ *
126d8fa4 595+ * @param[in] tracker : Pointer to MouseCursorTracker instance
830d0ba4 596+ */
126d8fa4 597+ void SetTracker(MouseCursorTracker *tracker);
830d0ba4
AIL
598+
599+ /**
600+ * @brief Set projection scale factor and translation parameters
601+ *
602+ * @param[in] scaleFactor : Scale factor applied in both X and Y directions
603+ * @param[in] translateX : Translation in X direction
604+ * @param[in] translateY : Translation in Y direction
605+ */
606+ void SetProjectionScaleTranslate(float scaleFactor,
607+ float translateX,
608+ float translateY);
609+
610 private:
611 /**
612 * @brief コンストラクタ
76316970 613@@ -107,5 +126,8 @@ private:
830d0ba4
AIL
614
615 Csm::CubismMatrix44* _viewMatrix; ///< モデル描画に用いるView行列
616 Csm::csmVector<LAppModel*> _models; ///< モデルインスタンスのコンテナ
617- Csm::csmInt32 _sceneIndex; ///< 表示するシーンのインデックス値
618+
619+ float _projScaleFactor;
620+ float _translateX;
621+ float _translateY;
622 };
623diff -pruN --exclude build ./demo_clean/src/LAppModel.cpp ./demo_dev/src/LAppModel.cpp
cd5de0f5 624--- ./demo_clean/src/LAppModel.cpp 2022-01-02 01:49:06.929909588 +0000
76316970 625+++ ./demo_dev/src/LAppModel.cpp 2021-04-28 12:26:56.699586813 +0100
eba2eb3a 626@@ -21,6 +21,10 @@
830d0ba4
AIL
627 #include "LAppTextureManager.hpp"
628 #include "LAppDelegate.hpp"
629
126d8fa4 630+#include "mouse_cursor_tracker.h"
830d0ba4 631+
eba2eb3a
AIL
632+#include <iostream>
633+
830d0ba4
AIL
634 using namespace Live2D::Cubism::Framework;
635 using namespace Live2D::Cubism::Framework::DefaultParameterId;
636 using namespace LAppDefine;
2c3e79c6
AIL
637@@ -45,22 +49,24 @@ namespace {
638 }
639 }
640
641-LAppModel::LAppModel()
642+LAppModel::LAppModel(bool useOldParamId)
126d8fa4
AIL
643 : CubismUserModel()
644 , _modelSetting(NULL)
645 , _userTimeSeconds(0.0f)
646+ , _tracker(nullptr)
2c3e79c6 647+ , _useOldParamId(useOldParamId)
126d8fa4
AIL
648 {
649 if (DebugLogEnable)
650 {
2c3e79c6
AIL
651 _debugMode = true;
652 }
653
654- _idParamAngleX = CubismFramework::GetIdManager()->GetId(ParamAngleX);
655- _idParamAngleY = CubismFramework::GetIdManager()->GetId(ParamAngleY);
656- _idParamAngleZ = CubismFramework::GetIdManager()->GetId(ParamAngleZ);
657- _idParamBodyAngleX = CubismFramework::GetIdManager()->GetId(ParamBodyAngleX);
658- _idParamEyeBallX = CubismFramework::GetIdManager()->GetId(ParamEyeBallX);
659- _idParamEyeBallY = CubismFramework::GetIdManager()->GetId(ParamEyeBallY);
660+ _idParamAngleX = CubismFramework::GetIdManager()->GetId(_(ParamAngleX));
661+ _idParamAngleY = CubismFramework::GetIdManager()->GetId(_(ParamAngleY));
662+ _idParamAngleZ = CubismFramework::GetIdManager()->GetId(_(ParamAngleZ));
663+ _idParamBodyAngleX = CubismFramework::GetIdManager()->GetId(_(ParamBodyAngleX));
664+ _idParamEyeBallX = CubismFramework::GetIdManager()->GetId(_(ParamEyeBallX));
665+ _idParamEyeBallY = CubismFramework::GetIdManager()->GetId(_(ParamEyeBallY));
666 }
667
668 LAppModel::~LAppModel()
669@@ -190,7 +196,7 @@ void LAppModel::SetupModel(ICubismModelS
670 breathParameters.PushBack(CubismBreath::BreathParameterData(_idParamAngleY, 0.0f, 8.0f, 3.5345f, 0.5f));
671 breathParameters.PushBack(CubismBreath::BreathParameterData(_idParamAngleZ, 0.0f, 10.0f, 5.5345f, 0.5f));
672 breathParameters.PushBack(CubismBreath::BreathParameterData(_idParamBodyAngleX, 0.0f, 4.0f, 15.5345f, 0.5f));
673- breathParameters.PushBack(CubismBreath::BreathParameterData(CubismFramework::GetIdManager()->GetId(ParamBreath), 0.5f, 0.5f, 3.2345f, 0.5f));
674+ breathParameters.PushBack(CubismBreath::BreathParameterData(CubismFramework::GetIdManager()->GetId(_(ParamBreath)), 0.5f, 0.5f, 3.2345f, 0.5f));
675
676 _breath->SetParameters(breathParameters);
677 }
76316970 678@@ -335,83 +341,118 @@ void LAppModel::Update()
830d0ba4
AIL
679 const csmFloat32 deltaTimeSeconds = LAppPal::GetDeltaTime();
680 _userTimeSeconds += deltaTimeSeconds;
681
682- _dragManager->Update(deltaTimeSeconds);
683- _dragX = _dragManager->GetX();
684- _dragY = _dragManager->GetY();
685-
686- // モーションによるパラメータ更新の有無
687- csmBool motionUpdated = false;
688-
689- //-----------------------------------------------------------------
690- _model->LoadParameters(); // 前回セーブされた状態をロード
691- if (_motionManager->IsFinished())
eba2eb3a 692- {
830d0ba4
AIL
693- // モーションの再生がない場合、待機モーションの中からランダムで再生する
694- StartRandomMotion(MotionGroupIdle, PriorityIdle);
695- }
696- else
eba2eb3a
AIL
697+ if (_tracker)
698 {
830d0ba4
AIL
699- motionUpdated = _motionManager->UpdateMotion(_model, deltaTimeSeconds); // モーションを更新
700- }
701- _model->SaveParameters(); // 状態を保存
702- //-----------------------------------------------------------------
2b1f0c7c 703+ auto idMan = CubismFramework::GetIdManager();
126d8fa4 704+ auto params = _tracker->getParams();
2b1f0c7c 705
830d0ba4
AIL
706- // まばたき
707- if (!motionUpdated)
708- {
709- if (_eyeBlink != NULL)
2b1f0c7c 710+ _model->LoadParameters(); // 前回セーブされた状態をロード
eba2eb3a
AIL
711+
712+ int paramsMotionPriority = static_cast<int>(params.motionPriority);
713+
714+ if (paramsMotionPriority != PriorityNone)
2b1f0c7c 715 {
830d0ba4
AIL
716- // メインモーションの更新がないとき
717- _eyeBlink->UpdateParameters(_model, deltaTimeSeconds); // 目パチ
eba2eb3a
AIL
718+ StartMotion(params.motionGroup.c_str(), params.motionNumber,
719+ paramsMotionPriority);
720+ }
721+ else if (params.randomIdleMotion && _motionManager->IsFinished())
722+ {
2b1f0c7c
AIL
723+ // モーションの再生がない場合、待機モーションの中からランダムで再生する
724+ StartRandomMotion(MotionGroupIdle, PriorityIdle);
725 }
830d0ba4 726- }
126d8fa4 727
830d0ba4 728- if (_expressionManager != NULL)
2b1f0c7c 729- {
830d0ba4
AIL
730- _expressionManager->UpdateMotion(_model, deltaTimeSeconds); // 表情でパラメータ更新(相対変化)
731- }
eba2eb3a
AIL
732+ // FIXME pose does not return to normal after motion
733+ // if we don't have randomIdleMotion set
734+ else
735+ {
736+ _motionManager->UpdateMotion(_model, deltaTimeSeconds); // モーションを更新
737+ }
738+ _model->SaveParameters(); // 状態を保存
126d8fa4 739
830d0ba4
AIL
740- //ドラッグによる変化
741- //ドラッグによる顔の向きの調整
742- _model->AddParameterValue(_idParamAngleX, _dragX * 30); // -30から30の値を加える
743- _model->AddParameterValue(_idParamAngleY, _dragY * 30);
744- _model->AddParameterValue(_idParamAngleZ, _dragX * _dragY * -30);
eba2eb3a 745+ if (params.expression != "")
126d8fa4 746+ {
eba2eb3a 747+ SetExpression(params.expression.c_str());
126d8fa4 748+ }
eba2eb3a 749+ if (_expressionManager != NULL)
2b1f0c7c 750+ {
eba2eb3a 751+ _expressionManager->UpdateMotion(_model, deltaTimeSeconds); // 表情でパラメータ更新(相対変化)
2b1f0c7c 752+ }
126d8fa4
AIL
753
754- //ドラッグによる体の向きの調整
755- _model->AddParameterValue(_idParamBodyAngleX, _dragX * 10); // -10から10の値を加える
eba2eb3a
AIL
756+ bool autoBlink = params.autoBlink && _eyeBlink;
757+ auto eyeLOpenIt = params.live2d.find("ParamEyeLOpen");
758+ auto eyeROpenIt = params.live2d.find("ParamEyeROpen");
2b1f0c7c 759
830d0ba4
AIL
760- //ドラッグによる目の向きの調整
761- _model->AddParameterValue(_idParamEyeBallX, _dragX); // -1から1の値を加える
762- _model->AddParameterValue(_idParamEyeBallY, _dragY);
eba2eb3a 763+ if (autoBlink)
126d8fa4 764+ {
eba2eb3a
AIL
765+ // Handle blink first
766+ _eyeBlink->UpdateParameters(_model, deltaTimeSeconds);
767+ }
830d0ba4
AIL
768
769- // 呼吸など
770- if (_breath != NULL)
771- {
772- _breath->UpdateParameters(_model, deltaTimeSeconds);
76316970 773- }
eba2eb3a
AIL
774+ if (eyeLOpenIt != params.live2d.end())
775+ {
776+ // If value specified, override blinking
2c3e79c6 777+ _model->SetParameterValue(idMan->GetId(_("ParamEyeLOpen")),
eba2eb3a
AIL
778+ eyeLOpenIt->second);
779+ }
780+ else if (!autoBlink)
781+ {
782+ // If no value specified and no auto blink, set to 1
2c3e79c6 783+ _model->SetParameterValue(idMan->GetId(_("ParamEyeLOpen")), 1);
76316970
AIL
784
785- // 物理演算の設定
786- if (_physics != NULL)
787- {
788- _physics->Evaluate(_model, deltaTimeSeconds);
789- }
eba2eb3a 790+ }
76316970
AIL
791
792- // リップシンクの設定
793- if (_lipSync)
794- {
795- // リアルタイムでリップシンクを行う場合、システムから音量を取得して0〜1の範囲で値を入力します。
796- csmFloat32 value = 0.0f;
eba2eb3a
AIL
797+ if (eyeROpenIt != params.live2d.end())
798+ {
2c3e79c6 799+ _model->SetParameterValue(idMan->GetId(_("ParamEyeROpen")),
eba2eb3a
AIL
800+ eyeROpenIt->second);
801+ }
802+ else if (!autoBlink)
803+ {
2c3e79c6 804+ _model->SetParameterValue(idMan->GetId(_("ParamEyeROpen")), 1);
eba2eb3a 805+ }
76316970
AIL
806
807- // 状態更新/RMS値取得
808- _wavFileHandler.Update(deltaTimeSeconds);
809- value = _wavFileHandler.GetRms();
810
811- for (csmUint32 i = 0; i < _lipSyncIds.GetSize(); ++i)
eba2eb3a 812+ if (params.useLipSync && _lipSync)
76316970
AIL
813 {
814- _model->AddParameterValue(_lipSyncIds[i], value, 0.8f);
eba2eb3a
AIL
815+ csmFloat32 value = params.lipSyncParam; // 0 to 1
816+
126d8fa4
AIL
817+ for (csmUint32 i = 0; i < _lipSyncIds.GetSize(); ++i)
818+ {
819+ _model->AddParameterValue(_lipSyncIds[i], value, 0.8f);
820+ }
2b1f0c7c
AIL
821+ }
822+ else
823+ {
2c3e79c6 824+ _model->SetParameterValue(idMan->GetId(_("ParamMouthOpenY")),
eba2eb3a
AIL
825+ params.live2d["ParamMouthOpenY"]);
826+ }
827+
828+ for (auto const &entry : params.live2d)
829+ {
830+ std::string key = entry.first;
831+ double val = entry.second;
832+
833+ if (key != "ParamEyeLOpen" && key != "ParamEyeROpen" &&
834+ key != "ParamMouthOpenY")
835+ {
2c3e79c6 836+ _model->SetParameterValue(idMan->GetId(_(key)), val);
eba2eb3a 837+ }
2b1f0c7c 838+ }
126d8fa4 839+
2b1f0c7c
AIL
840+ if (params.autoBreath && _breath)
841+ {
842+ // Note: _model->LoadParameters and SaveParameters is needed
843+ // before - see above.
844+ _breath->UpdateParameters(_model, deltaTimeSeconds);
76316970 845 }
830d0ba4
AIL
846 }
847
76316970
AIL
848+ // 物理演算の設定
849+ if (_physics != NULL)
850+ {
851+ _physics->Evaluate(_model, deltaTimeSeconds);
852+ }
853+
830d0ba4
AIL
854 // ポーズの設定
855 if (_pose != NULL)
856 {
76316970
AIL
857@@ -480,7 +521,6 @@ CubismMotionQueueEntryHandle LAppModel::
858 {
859 csmString path = voice;
860 path = _modelHomeDir + path;
861- _wavFileHandler.Start(path);
862 }
863
864 if (_debugMode)
865@@ -632,3 +672,42 @@ Csm::Rendering::CubismOffscreenFrame_Ope
830d0ba4
AIL
866 {
867 return _renderBuffer;
868 }
869+
126d8fa4 870+void LAppModel::SetTracker(MouseCursorTracker *tracker)
830d0ba4 871+{
126d8fa4 872+ _tracker = tracker;
830d0ba4
AIL
873+}
874+
eba2eb3a
AIL
875+Csm::ICubismModelSetting* LAppModel::GetModelSetting(void) const
876+{
877+ return _modelSetting;
878+}
879+
2c3e79c6
AIL
880+Csm::csmString LAppModel::_(std::string s)
881+{
882+ std::string ans;
883+ if (_useOldParamId)
884+ {
885+ if (s == "ParamTere")
886+ {
887+ ans = "PARAM_CHEEK";
888+ }
889+ else
890+ {
891+ for (size_t i = 0; i < s.size(); i++)
892+ {
893+ if (std::isupper(s[i]) && i != 0)
894+ {
895+ ans += '_';
896+ }
897+ ans += std::toupper(s[i]);
898+ }
899+ }
900+ }
901+ else
902+ {
903+ ans = s;
904+ }
905+ return csmString(ans.c_str());
906+}
907+
830d0ba4 908diff -pruN --exclude build ./demo_clean/src/LAppModel.hpp ./demo_dev/src/LAppModel.hpp
cd5de0f5 909--- ./demo_clean/src/LAppModel.hpp 2022-01-02 01:49:06.929909588 +0000
76316970
AIL
910+++ ./demo_dev/src/LAppModel.hpp 2021-04-28 12:27:55.836457680 +0100
911@@ -13,7 +13,7 @@
830d0ba4
AIL
912 #include <Type/csmRectF.hpp>
913 #include <Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.hpp>
914
76316970 915-#include "LAppWavFileHandler.hpp"
126d8fa4 916+#include "mouse_cursor_tracker.h"
830d0ba4
AIL
917
918 /**
919 * @brief ユーザーが実際に使用するモデルの実装クラス<br>
76316970 920@@ -25,8 +25,11 @@ class LAppModel : public Csm::CubismUser
2c3e79c6
AIL
921 public:
922 /**
923 * @brief コンストラクタ
924+ *
925+ * @param[in] useOldParamId : If true, translate new (Cubism 3+)
926+ * parameter IDs to old (Cubism 2.1) ones
927 */
928- LAppModel();
929+ LAppModel(bool useOldParamId);
930
931 /**
932 * @brief デストラクタ
76316970 933@@ -114,6 +117,15 @@ public:
830d0ba4
AIL
934 */
935 Csm::Rendering::CubismOffscreenFrame_OpenGLES2& GetRenderBuffer();
936
937+ /**
126d8fa4 938+ * @brief Set the pointer to the MouseCursorTracker instance
830d0ba4 939+ *
126d8fa4 940+ * @param[in] tracker : Pointer to MouseCursorTracker instance
830d0ba4 941+ */
126d8fa4 942+ void SetTracker(MouseCursorTracker *tracker);
830d0ba4 943+
eba2eb3a
AIL
944+ Csm::ICubismModelSetting* GetModelSetting(void) const;
945+
830d0ba4
AIL
946 protected:
947 /**
948 * @brief モデルを描画する処理。モデルを描画する空間のView-Projection行列を渡す。
76316970 949@@ -167,6 +179,17 @@ private:
2c3e79c6
AIL
950 */
951 void ReleaseExpressions();
952
953+ /**
954+ * @brief Translate new (Cubism 3+) parameter IDs to old (Cubism 2.1) ones
955+ *
956+ * @param[in] s : New parameter ID
957+ *
958+ * @return Old parameter ID
959+ */
960+ Csm::csmString _(std::string s);
961+
962+ bool _useOldParamId;
963+
964 Csm::ICubismModelSetting* _modelSetting; ///< モデルセッティング情報
965 Csm::csmString _modelHomeDir; ///< モデルセッティングが置かれたディレクトリ
966 Csm::csmFloat32 _userTimeSeconds; ///< デルタ時間の積算値[秒]
76316970
AIL
967@@ -183,9 +206,9 @@ private:
968 const Csm::CubismId* _idParamEyeBallX; ///< パラメータID: ParamEyeBallX
830d0ba4
AIL
969 const Csm::CubismId* _idParamEyeBallY; ///< パラメータID: ParamEyeBallXY
970
76316970
AIL
971- LAppWavFileHandler _wavFileHandler; ///< wavファイルハンドラ
972-
830d0ba4
AIL
973 Csm::Rendering::CubismOffscreenFrame_OpenGLES2 _renderBuffer; ///< フレームバッファ以外の描画先
974+
126d8fa4 975+ MouseCursorTracker *_tracker;
830d0ba4
AIL
976 };
977
978
979diff -pruN --exclude build ./demo_clean/src/LAppPal.cpp ./demo_dev/src/LAppPal.cpp
cd5de0f5 980--- ./demo_clean/src/LAppPal.cpp 2022-01-02 01:49:06.929909588 +0000
76316970 981+++ ./demo_dev/src/LAppPal.cpp 2021-04-28 12:18:50.952333251 +0100
830d0ba4
AIL
982@@ -6,6 +6,7 @@
983 */
984
985 #include "LAppPal.hpp"
986+#include <stdexcept>
987 #include <stdio.h>
988 #include <stdlib.h>
989 #include <stdarg.h>
eba2eb3a
AIL
990@@ -36,7 +37,6 @@ csmByte* LAppPal::LoadFileAsBytes(const
991 if (stat(path, &statBuf) == 0)
992 {
993 size = statBuf.st_size;
994- PrintLog(path);
995 }
996
997 std::fstream file;
998@@ -45,10 +45,7 @@ csmByte* LAppPal::LoadFileAsBytes(const
830d0ba4
AIL
999 file.open(path, std::ios::in | std::ios::binary);
1000 if (!file.is_open())
1001 {
1002- if (DebugLogEnable)
1003- {
1004- PrintLog("file open error");
1005- }
1006+ throw std::runtime_error("Failed to open file " + filePath);
1007 return NULL;
1008 }
1009 file.read(buf, size);
1010diff -pruN --exclude build ./demo_clean/src/LAppTextureManager.cpp ./demo_dev/src/LAppTextureManager.cpp
cd5de0f5 1011--- ./demo_clean/src/LAppTextureManager.cpp 2022-01-02 01:49:06.929909588 +0000
76316970 1012+++ ./demo_dev/src/LAppTextureManager.cpp 2021-04-28 12:18:50.952333251 +0100
830d0ba4
AIL
1013@@ -96,6 +96,46 @@ LAppTextureManager::TextureInfo* LAppTex
1014
1015 }
1016
1017+LAppTextureManager::TextureInfo* LAppTextureManager::CreateTextureFromColor(
1018+ uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha
1019+)
1020+{
1021+ int width = 8, height = 8;
1022+
1023+ uint8_t pixels[height][width][4];
1024+ for (std::size_t h = 0; h < height; h++)
1025+ {
1026+ for (std::size_t w = 0; w < width; w++)
1027+ {
1028+ pixels[h][w][0] = red;
1029+ pixels[h][w][1] = green;
1030+ pixels[h][w][2] = blue;
1031+ pixels[h][w][3] = alpha;
1032+ }
1033+ }
1034+
1035+ GLuint textureId;
1036+ glGenTextures(1, &textureId);
1037+ glBindTexture(GL_TEXTURE_2D, textureId);
1038+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1039+
1040+ glGenerateMipmap(GL_TEXTURE_2D);
1041+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1042+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1043+ glBindTexture(GL_TEXTURE_2D, 0);
1044+
1045+
1046+ LAppTextureManager::TextureInfo* textureInfo = new LAppTextureManager::TextureInfo();
1047+ textureInfo->fileName = "";
1048+ textureInfo->width = width;
1049+ textureInfo->height = height;
1050+ textureInfo->id = textureId;
1051+
1052+ _textures.PushBack(textureInfo);
1053+
1054+ return textureInfo;
1055+}
1056+
1057 void LAppTextureManager::ReleaseTextures()
1058 {
1059 for (Csm::csmUint32 i = 0; i < _textures.GetSize(); i++)
1060diff -pruN --exclude build ./demo_clean/src/LAppTextureManager.hpp ./demo_dev/src/LAppTextureManager.hpp
cd5de0f5 1061--- ./demo_clean/src/LAppTextureManager.hpp 2022-01-02 01:49:06.929909588 +0000
76316970 1062+++ ./demo_dev/src/LAppTextureManager.hpp 2021-04-28 12:18:50.952333251 +0100
830d0ba4
AIL
1063@@ -72,6 +72,8 @@ public:
1064 */
1065 TextureInfo* CreateTextureFromPngFile(std::string fileName);
1066
1067+ TextureInfo *CreateTextureFromColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha = 255);
1068+
1069 /**
1070 * @brief 画像の解放
1071 *
1072diff -pruN --exclude build ./demo_clean/src/LAppView.cpp ./demo_dev/src/LAppView.cpp
cd5de0f5 1073--- ./demo_clean/src/LAppView.cpp 2022-01-02 01:49:06.929909588 +0000
76316970 1074+++ ./demo_dev/src/LAppView.cpp 2021-04-28 12:18:50.952333251 +0100
830d0ba4
AIL
1075@@ -13,7 +13,6 @@
1076 #include "LAppLive2DManager.hpp"
1077 #include "LAppTextureManager.hpp"
1078 #include "LAppDefine.hpp"
1079-#include "TouchManager.hpp"
1080 #include "LAppSprite.hpp"
1081 #include "LAppModel.hpp"
1082
1083@@ -26,8 +25,6 @@ using namespace LAppDefine;
1084 LAppView::LAppView():
1085 _programId(0),
1086 _back(NULL),
1087- _gear(NULL),
1088- _power(NULL),
1089 _renderSprite(NULL),
1090 _renderTarget(SelectTarget_None)
1091 {
1092@@ -35,8 +32,6 @@ LAppView::LAppView():
1093 _clearColor[1] = 1.0f;
1094 _clearColor[2] = 1.0f;
1095 _clearColor[3] = 0.0f;
1096- // タッチ関係のイベント管理
1097- _touchManager = new TouchManager();
1098
1099 // デバイス座標からスクリーン座標に変換するための
1100 _deviceToScreen = new CubismMatrix44();
1101@@ -52,10 +47,7 @@ LAppView::~LAppView()
1102
1103 delete _viewMatrix;
1104 delete _deviceToScreen;
1105- delete _touchManager;
1106 delete _back;
1107- delete _gear;
1108- delete _power;
1109 }
1110
1111 void LAppView::Initialize()
76316970 1112@@ -107,9 +99,6 @@ void LAppView::Initialize()
830d0ba4
AIL
1113 void LAppView::Render()
1114 {
1115 _back->Render();
1116- _gear->Render();
1117- _power->Render();
1118-
1119
1120 LAppLive2DManager* Live2DManager = LAppLive2DManager::GetInstance();
1121
76316970 1122@@ -151,35 +140,17 @@ void LAppView::InitializeSprite()
830d0ba4
AIL
1123 glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
1124
1125 LAppTextureManager* textureManager = LAppDelegate::GetInstance()->GetTextureManager();
1126- const string resourcesPath = LAppDelegate::GetInstance()->GetRootDirectory() + ResourcesPath;
1127
1128- string imageName = BackImageName;
1129- LAppTextureManager::TextureInfo* backgroundTexture = textureManager->CreateTextureFromPngFile(resourcesPath + imageName);
1130+
1131+ LAppTextureManager::TextureInfo* backgroundTexture =
1132+ textureManager->CreateTextureFromColor(0, 255, 0);
1133
1134 float x = width * 0.5f;
1135 float y = height * 0.5f;
1136- float fWidth = static_cast<float>(backgroundTexture->width * 2.0f);
1137- float fHeight = static_cast<float>(height) * 0.95f;
1138+ float fWidth = static_cast<float>(width);
1139+ float fHeight = static_cast<float>(height);
1140 _back = new LAppSprite(x, y, fWidth, fHeight, backgroundTexture->id, _programId);
1141
1142- imageName = GearImageName;
1143- LAppTextureManager::TextureInfo* gearTexture = textureManager->CreateTextureFromPngFile(resourcesPath + imageName);
1144-
1145- x = static_cast<float>(width - gearTexture->width * 0.5f);
1146- y = static_cast<float>(height - gearTexture->height * 0.5f);
1147- fWidth = static_cast<float>(gearTexture->width);
1148- fHeight = static_cast<float>(gearTexture->height);
1149- _gear = new LAppSprite(x, y, fWidth, fHeight, gearTexture->id, _programId);
1150-
1151- imageName = PowerImageName;
1152- LAppTextureManager::TextureInfo* powerTexture = textureManager->CreateTextureFromPngFile(resourcesPath + imageName);
1153-
1154- x = static_cast<float>(width - powerTexture->width * 0.5f);
1155- y = static_cast<float>(powerTexture->height * 0.5f);
1156- fWidth = static_cast<float>(powerTexture->width);
1157- fHeight = static_cast<float>(powerTexture->height);
1158- _power = new LAppSprite(x, y, fWidth, fHeight, powerTexture->id, _programId);
1159-
1160 // 画面全体を覆うサイズ
1161 x = width * 0.5f;
1162 y = height * 0.5f;
76316970 1163@@ -187,52 +158,6 @@ void LAppView::InitializeSprite()
830d0ba4
AIL
1164
1165 }
1166
1167-void LAppView::OnTouchesBegan(float px, float py) const
1168-{
1169- _touchManager->TouchesBegan(px, py);
1170-}
1171-
1172-void LAppView::OnTouchesMoved(float px, float py) const
1173-{
1174- float viewX = this->TransformViewX(_touchManager->GetX());
1175- float viewY = this->TransformViewY(_touchManager->GetY());
1176-
1177- _touchManager->TouchesMoved(px, py);
1178-
1179- LAppLive2DManager* Live2DManager = LAppLive2DManager::GetInstance();
1180- Live2DManager->OnDrag(viewX, viewY);
1181-}
1182-
1183-void LAppView::OnTouchesEnded(float px, float py) const
1184-{
1185- // タッチ終了
1186- LAppLive2DManager* live2DManager = LAppLive2DManager::GetInstance();
1187- live2DManager->OnDrag(0.0f, 0.0f);
1188- {
1189-
1190- // シングルタップ
1191- float x = _deviceToScreen->TransformX(_touchManager->GetX()); // 論理座標変換した座標を取得。
1192- float y = _deviceToScreen->TransformY(_touchManager->GetY()); // 論理座標変換した座標を取得。
1193- if (DebugTouchLogEnable)
1194- {
1195- LAppPal::PrintLog("[APP]touchesEnded x:%.2f y:%.2f", x, y);
1196- }
1197- live2DManager->OnTap(x, y);
1198-
1199- // 歯車にタップしたか
1200- if (_gear->IsHit(px, py))
1201- {
1202- live2DManager->NextScene();
1203- }
1204-
1205- // 電源ボタンにタップしたか
1206- if (_power->IsHit(px, py))
1207- {
1208- LAppDelegate::GetInstance()->AppEnd();
1209- }
1210- }
1211-}
1212-
1213 float LAppView::TransformViewX(float deviceX) const
1214 {
1215 float screenX = _deviceToScreen->TransformX(deviceX); // 論理座標変換した座標を取得。
76316970 1216@@ -374,32 +299,4 @@ void LAppView::ResizeSprite()
830d0ba4
AIL
1217 _back->ResetRect(x, y, fWidth, fHeight);
1218 }
1219 }
1220-
1221- if (_power)
1222- {
1223- GLuint id = _power->GetTextureId();
1224- LAppTextureManager::TextureInfo* texInfo = textureManager->GetTextureInfoById(id);
1225- if (texInfo)
1226- {
1227- x = static_cast<float>(width - texInfo->width * 0.5f);
1228- y = static_cast<float>(texInfo->height * 0.5f);
1229- fWidth = static_cast<float>(texInfo->width);
1230- fHeight = static_cast<float>(texInfo->height);
1231- _power->ResetRect(x, y, fWidth, fHeight);
1232- }
1233- }
1234-
1235- if (_gear)
1236- {
1237- GLuint id = _gear->GetTextureId();
1238- LAppTextureManager::TextureInfo* texInfo = textureManager->GetTextureInfoById(id);
1239- if (texInfo)
1240- {
1241- x = static_cast<float>(width - texInfo->width * 0.5f);
1242- y = static_cast<float>(height - texInfo->height * 0.5f);
1243- fWidth = static_cast<float>(texInfo->width);
1244- fHeight = static_cast<float>(texInfo->height);
1245- _gear->ResetRect(x, y, fWidth, fHeight);
1246- }
1247- }
1248 }
1249diff -pruN --exclude build ./demo_clean/src/LAppView.hpp ./demo_dev/src/LAppView.hpp
cd5de0f5 1250--- ./demo_clean/src/LAppView.hpp 2022-01-02 01:49:06.929909588 +0000
76316970 1251+++ ./demo_dev/src/LAppView.hpp 2021-04-28 12:18:50.952333251 +0100
830d0ba4
AIL
1252@@ -14,7 +14,6 @@
1253 #include "CubismFramework.hpp"
1254 #include <Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.hpp>
1255
1256-class TouchManager;
1257 class LAppSprite;
1258 class LAppModel;
1259
1260@@ -66,30 +65,6 @@ public:
1261 void ResizeSprite();
1262
1263 /**
1264- * @brief タッチされたときに呼ばれる。
1265- *
1266- * @param[in] pointX スクリーンX座標
1267- * @param[in] pointY スクリーンY座標
1268- */
1269- void OnTouchesBegan(float pointX, float pointY) const;
1270-
1271- /**
1272- * @brief タッチしているときにポインタが動いたら呼ばれる。
1273- *
1274- * @param[in] pointX スクリーンX座標
1275- * @param[in] pointY スクリーンY座標
1276- */
1277- void OnTouchesMoved(float pointX, float pointY) const;
1278-
1279- /**
1280- * @brief タッチが終了したら呼ばれる。
1281- *
1282- * @param[in] pointX スクリーンX座標
1283- * @param[in] pointY スクリーンY座標
1284- */
1285- void OnTouchesEnded(float pointX, float pointY) const;
1286-
1287- /**
1288 * @brief X座標をView座標に変換する。
1289 *
1290 * @param[in] deviceX デバイスX座標
1291@@ -147,13 +122,10 @@ public:
1292 void SetRenderTargetClearColor(float r, float g, float b);
1293
1294 private:
1295- TouchManager* _touchManager; ///< タッチマネージャー
1296 Csm::CubismMatrix44* _deviceToScreen; ///< デバイスからスクリーンへの行列
1297 Csm::CubismViewMatrix* _viewMatrix; ///< viewMatrix
1298 GLuint _programId; ///< シェーダID
1299 LAppSprite* _back; ///< 背景画像
1300- LAppSprite* _gear; ///< ギア画像
1301- LAppSprite* _power; ///< 電源画像
1302
1303 // レンダリング先を別ターゲットにする方式の場合に使用
1304 LAppSprite* _renderSprite; ///< モードによっては_renderBufferのテクスチャを描画
1305diff -pruN --exclude build ./demo_clean/src/main.cpp ./demo_dev/src/main.cpp
cd5de0f5 1306--- ./demo_clean/src/main.cpp 2022-01-02 01:49:06.929909588 +0000
76316970 1307+++ ./demo_dev/src/main.cpp 2021-04-28 12:28:55.845339613 +0100
2c3e79c6 1308@@ -5,18 +5,188 @@
830d0ba4
AIL
1309 * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
1310 */
1311
1312+#include <thread>
1313+#include <stdexcept>
1314+#include <sstream>
eba2eb3a
AIL
1315+#include <vector>
1316+#include <utility>
1317+#include <string>
830d0ba4
AIL
1318+
1319+#ifdef __cpp_lib_filesystem
1320+#include <filesystem>
1321+namespace fs = std::filesystem;
1322+#else
1323+#include <experimental/filesystem>
1324+namespace fs = std::experimental::filesystem;
1325+#endif
1326+
eba2eb3a 1327+#include "ICubismModelSetting.hpp"
830d0ba4
AIL
1328 #include "LAppDelegate.hpp"
1329+#include "LAppLive2DManager.hpp"
eba2eb3a 1330+#include "LAppModel.hpp"
126d8fa4 1331+#include "mouse_cursor_tracker.h"
830d0ba4
AIL
1332+
1333+struct CmdArgs
1334+{
1335+ int windowWidth;
1336+ int windowHeight;
1337+ std::string windowTitle;
1338+ std::string rootDir;
1339+ float scaleFactor;
1340+ float translateX;
1341+ float translateY;
1342+ std::string modelName;
2c3e79c6 1343+ bool oldId; // If true, translate new (Cubism 3+) parameter IDs to old (Cubism 2.1) IDs
126d8fa4 1344+ std::string cfgPath; // Path to config file for MouseCursorTracker
830d0ba4
AIL
1345+};
1346+
1347+CmdArgs parseArgv(int argc, char *argv[])
1348+{
1349+ // I think the command-line args are simple enough to not justify using a library...
1350+ CmdArgs cmdArgs;
1351+ // Set default values
1352+ cmdArgs.windowWidth = 600;
1353+ cmdArgs.windowHeight = 600;
126d8fa4 1354+ cmdArgs.windowTitle = "MouseTrackerForCubism example";
830d0ba4 1355+ cmdArgs.rootDir = fs::current_path();
76316970 1356+ cmdArgs.scaleFactor = 4.5f;
830d0ba4 1357+ cmdArgs.translateX = 0.0f;
76316970 1358+ cmdArgs.translateY = -3.1f;
830d0ba4 1359+ cmdArgs.modelName = "Haru";
2c3e79c6 1360+ cmdArgs.oldId = false;
830d0ba4
AIL
1361+ cmdArgs.cfgPath = "";
1362+
1363+ int i = 1;
1364+ while (i < argc)
1365+ {
1366+ std::string arg = argv[i];
1367+ std::stringstream ss;
1368+
1369+ if (arg == "--window-width" || arg == "-W") // capital W for consistency with height
1370+ {
1371+ ss << argv[i + 1];
1372+ if (!(ss >> cmdArgs.windowWidth))
1373+ {
1374+ throw std::runtime_error("Invalid argument for window width");
1375+ }
1376+ }
1377+ else if (arg == "--window-height" || arg == "-H") // avoiding "-h", typically for help
1378+ {
1379+ ss << argv[i + 1];
1380+ if (!(ss >> cmdArgs.windowHeight))
1381+ {
1382+ throw std::runtime_error("Invalid argument for window height");
1383+ }
1384+ }
1385+ else if (arg == "--window-title" || arg == "-t")
1386+ {
1387+ cmdArgs.windowTitle = argv[i + 1];
1388+ }
1389+ else if (arg == "--root-dir" || arg == "-d")
1390+ {
1391+ cmdArgs.rootDir = argv[i + 1];
1392+ }
1393+ else if (arg == "--scale-factor" || arg == "-f")
1394+ {
1395+ ss << argv[i + 1];
1396+ if (!(ss >> cmdArgs.scaleFactor))
1397+ {
1398+ throw std::runtime_error("Invalid argument for scale factor");
1399+ }
1400+ }
1401+ else if (arg == "--translate-x" || arg == "-x")
1402+ {
1403+ ss << argv[i + 1];
1404+ if (!(ss >> cmdArgs.translateX))
1405+ {
1406+ throw std::runtime_error("Invalid argument for translate X");
1407+ }
1408+ }
1409+ else if (arg == "--translate-y" || arg == "-y")
1410+ {
1411+ ss << argv[i + 1];
1412+ if (!(ss >> cmdArgs.translateY))
1413+ {
1414+ throw std::runtime_error("Invalid argument for translate Y");
1415+ }
1416+ }
1417+ else if (arg == "--model" || arg == "-m")
1418+ {
1419+ cmdArgs.modelName = argv[i + 1];
1420+ }
1421+ else if (arg == "--config" || arg == "-c")
1422+ {
1423+ cmdArgs.cfgPath = argv[i + 1];
1424+ }
2c3e79c6
AIL
1425+ else if (arg == "--old-param-id" || arg == "-o")
1426+ {
1427+ cmdArgs.oldId = (argv[i + 1][0] == '1');
1428+ }
830d0ba4
AIL
1429+ else
1430+ {
1431+ throw std::runtime_error("Unrecognized argument: " + arg);
1432+ }
1433+
1434+ i += 2;
1435+ }
1436+
1437+ return cmdArgs;
1438+}
1439
1440 int main(int argc, char* argv[])
1441 {
1442- // create the application instance
1443- if (LAppDelegate::GetInstance()->Initialize() == GL_FALSE)
1444+ auto cmdArgs = parseArgv(argc, argv);
1445+
1446+ LAppDelegate *delegate = LAppDelegate::GetInstance();
1447+
1448+ if (!delegate->Initialize(cmdArgs.windowWidth,
1449+ cmdArgs.windowHeight,
1450+ cmdArgs.windowTitle.c_str()))
1451 {
1452- return 1;
1453+ throw std::runtime_error("Unable to initialize LAppDelegate");
1454 }
1455
1456- LAppDelegate::GetInstance()->Run();
1457+ delegate->SetRootDirectory(cmdArgs.rootDir);
1458+
830d0ba4 1459+ LAppLive2DManager *manager = LAppLive2DManager::GetInstance();
2c3e79c6 1460+ manager->SetModel(cmdArgs.modelName, cmdArgs.oldId);
830d0ba4
AIL
1461+
1462+ manager->SetProjectionScaleTranslate(cmdArgs.scaleFactor,
1463+ cmdArgs.translateX,
1464+ cmdArgs.translateY);
eba2eb3a
AIL
1465+
1466+ LAppModel *model = manager->GetModel(0);
1467+ if (!model) throw std::runtime_error("model is null");
1468+
1469+ Live2D::Cubism::Framework::ICubismModelSetting *modelSetting = model->GetModelSetting();
1470+ if (!modelSetting) throw std::runtime_error("modelSetting is null");
1471+
1472+ std::vector<std::pair<std::string, int> > motions;
1473+ int motionGroupCount = modelSetting->GetMotionGroupCount();
1474+ for (int i = 0; i < motionGroupCount; i++)
1475+ {
1476+ const char *motionGroup = modelSetting->GetMotionGroupName(i);
1477+ int motionCount = modelSetting->GetMotionCount(motionGroup);
1478+ motions.push_back(std::make_pair(std::string(motionGroup), motionCount));
1479+ }
1480+
1481+ std::vector<std::string> expressions;
1482+ int expCount = modelSetting->GetExpressionCount();
1483+ for (int i = 0; i < expCount; i++)
1484+ {
1485+ const char *expName = modelSetting->GetExpressionName(i);
1486+ expressions.push_back(std::string(expName));
1487+ }
1488+
1489+ MouseCursorTracker tracker(cmdArgs.cfgPath, motions, expressions);
1490+
1491+ std::thread trackerThread(&MouseCursorTracker::mainLoop, &tracker);
126d8fa4 1492+ manager->SetTracker(&tracker);
830d0ba4
AIL
1493+
1494+ delegate->Run();
1495+
126d8fa4
AIL
1496+ tracker.stop();
1497+ trackerThread.join();
830d0ba4
AIL
1498
1499 return 0;
1500 }
1501-