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