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