Upgrade to Cubism 5 Release R1.
[mouse-tracker-for-cubism.git] / example / demo.patch
1 diff -pruN --exclude build ./demo_clean/CMakeLists.txt ./demo_dev/CMakeLists.txt
2 --- ./demo_clean/CMakeLists.txt 2024-03-28 18:39:52.882141826 +0000
3 +++ ./demo_dev/CMakeLists.txt   2024-03-28 18:42:19.248653862 +0000
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}/../../../..)
9 +set(SDK_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../CubismSdkForNative-5-r.1)
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,11 @@ target_link_libraries(Framework Live2DCu
23  # Find opengl libraries.
24  find_package(OpenGL REQUIRED)
25  
26 +# Add MouseTrackerForCubism
27 +find_package(PkgConfig)
28 +pkg_check_modules(GTKMM gtkmm-3.0)
29 +add_subdirectory(../.. MouseTrackerForCubism_build)
30 +
31  # Make executable app.
32  add_executable(${APP_NAME})
33  # Add source files.
34 @@ -73,9 +78,20 @@ target_link_libraries(${APP_NAME}
35    Framework
36    glfw
37    ${OPENGL_LIBRARIES}
38 +  MouseTrackerForCubism
39 +  stdc++fs
40  )
41  # Specify include directories.
42 -target_include_directories(${APP_NAME} PRIVATE ${STB_PATH})
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 +)
53  
54  # Copy resource directory to build directory.
55  add_custom_command(
56 diff -pruN --exclude build ./demo_clean/scripts/make_gcc ./demo_dev/scripts/make_gcc
57 --- ./demo_clean/scripts/make_gcc       2024-03-28 18:39:52.882141826 +0000
58 +++ ./demo_dev/scripts/make_gcc 2023-05-28 09:11:29.467788463 +0100
59 @@ -5,42 +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.
96  cmake -S "$CMAKE_PATH" \
97    -B "$BUILD_PATH" \
98 -  -D CMAKE_BUILD_TYPE=Release \
99 -  -D CSM_MINIMUM_DEMO=$MINIMUM_DEMO \
100 -  -D GLFW_BUILD_WAYLAND=OFF
101 -cd "$BUILD_PATH" && make
102 +  -D CMAKE_BUILD_TYPE=Release
103 +cd "$BUILD_PATH" && make -j4
104 diff -pruN --exclude build ./demo_clean/src/CMakeLists.txt ./demo_dev/src/CMakeLists.txt
105 --- ./demo_clean/src/CMakeLists.txt     2024-03-28 18:39:52.882141826 +0000
106 +++ ./demo_dev/src/CMakeLists.txt       2024-03-28 18:43:36.369973576 +0000
107 @@ -1,49 +1,22 @@
108 -if (CSM_MINIMUM_DEMO)
109 -  target_sources(${APP_NAME}
110 +target_sources(${APP_NAME}
111    PRIVATE
112      ${CMAKE_CURRENT_SOURCE_DIR}/LAppAllocator.cpp
113      ${CMAKE_CURRENT_SOURCE_DIR}/LAppAllocator.hpp
114      ${CMAKE_CURRENT_SOURCE_DIR}/LAppDefine.cpp
115      ${CMAKE_CURRENT_SOURCE_DIR}/LAppDefine.hpp
116 +    ${CMAKE_CURRENT_SOURCE_DIR}/LAppDelegate.cpp
117 +    ${CMAKE_CURRENT_SOURCE_DIR}/LAppDelegate.hpp
118 +    ${CMAKE_CURRENT_SOURCE_DIR}/LAppLive2DManager.cpp
119 +    ${CMAKE_CURRENT_SOURCE_DIR}/LAppLive2DManager.hpp
120 +    ${CMAKE_CURRENT_SOURCE_DIR}/LAppModel.cpp
121 +    ${CMAKE_CURRENT_SOURCE_DIR}/LAppModel.hpp
122      ${CMAKE_CURRENT_SOURCE_DIR}/LAppPal.cpp
123      ${CMAKE_CURRENT_SOURCE_DIR}/LAppPal.hpp
124 +    ${CMAKE_CURRENT_SOURCE_DIR}/LAppSprite.cpp
125 +    ${CMAKE_CURRENT_SOURCE_DIR}/LAppSprite.hpp
126      ${CMAKE_CURRENT_SOURCE_DIR}/LAppTextureManager.cpp
127      ${CMAKE_CURRENT_SOURCE_DIR}/LAppTextureManager.hpp
128 -    ${CMAKE_CURRENT_SOURCE_DIR}/mainMinimum.cpp
129 -    ${CMAKE_CURRENT_SOURCE_DIR}/TouchManager.cpp
130 -    ${CMAKE_CURRENT_SOURCE_DIR}/TouchManager.hpp
131 -    ${CMAKE_CURRENT_SOURCE_DIR}/CubismUserModelExtend.cpp
132 -    ${CMAKE_CURRENT_SOURCE_DIR}/CubismUserModelExtend.hpp
133 -    ${CMAKE_CURRENT_SOURCE_DIR}/CubismSampleViewMatrix.cpp
134 -    ${CMAKE_CURRENT_SOURCE_DIR}/CubismSampleViewMatrix.hpp
135 -    ${CMAKE_CURRENT_SOURCE_DIR}/MouseActionManager.cpp
136 -    ${CMAKE_CURRENT_SOURCE_DIR}/MouseActionManager.hpp
137 -  )
138 -else ()
139 -  target_sources(${APP_NAME}
140 -    PRIVATE
141 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppAllocator.cpp
142 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppAllocator.hpp
143 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppDefine.cpp
144 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppDefine.hpp
145 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppDelegate.cpp
146 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppDelegate.hpp
147 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppWavFileHandler.cpp
148 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppWavFileHandler.hpp
149 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppLive2DManager.cpp
150 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppLive2DManager.hpp
151 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppModel.cpp
152 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppModel.hpp
153 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppPal.cpp
154 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppPal.hpp
155 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppSprite.cpp
156 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppSprite.hpp
157 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppTextureManager.cpp
158 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppTextureManager.hpp
159 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppView.cpp
160 -      ${CMAKE_CURRENT_SOURCE_DIR}/LAppView.hpp
161 -      ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
162 -      ${CMAKE_CURRENT_SOURCE_DIR}/TouchManager.cpp
163 -      ${CMAKE_CURRENT_SOURCE_DIR}/TouchManager.hpp
164 -  )
165 -endif ()
166 +    ${CMAKE_CURRENT_SOURCE_DIR}/LAppView.cpp
167 +    ${CMAKE_CURRENT_SOURCE_DIR}/LAppView.hpp
168 +    ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
169 +)
170 diff -pruN --exclude build ./demo_clean/src/CubismUserModelExtend.cpp ./demo_dev/src/CubismUserModelExtend.cpp
171 --- ./demo_clean/src/CubismUserModelExtend.cpp  2024-03-28 18:39:52.882141826 +0000
172 +++ ./demo_dev/src/CubismUserModelExtend.cpp    2024-03-28 18:43:36.373973644 +0000
173 @@ -119,15 +119,12 @@ void CubismUserModelExtend::SetupModel()
174              buffer = CreateBuffer(path.GetRawString(), &size);
175              ACubismMotion* motion = LoadExpression(buffer, size, name.GetRawString());
176  
177 -            if (motion)
178 +            if (_expressions[name])
179              {
180 -                if (_expressions[name])
181 -                {
182 -                    ACubismMotion::Delete(_expressions[name]);
183 -                    _expressions[name] = nullptr;
184 -                }
185 -                _expressions[name] = motion;
186 +                ACubismMotion::Delete(_expressions[name]);
187 +                _expressions[name] = nullptr;
188              }
189 +            _expressions[name] = motion;
190  
191              DeleteBuffer(buffer, path.GetRawString());
192          }
193 @@ -213,29 +210,26 @@ void CubismUserModelExtend::PreloadMotio
194          // モーションデータの読み込み
195          CubismMotion* tmpMotion = static_cast<CubismMotion*>(LoadMotion(buffer, size, name.GetRawString()));
196  
197 -        if (tmpMotion)
198 +        // フェードインの時間を取得
199 +        csmFloat32 fadeTime = _modelJson->GetMotionFadeInTimeValue(group, i);
200 +        if (fadeTime >= 0.0f)
201          {
202 -            // フェードインの時間を取得
203 -            csmFloat32 fadeTime = _modelJson->GetMotionFadeInTimeValue(group, i);
204 -            if (fadeTime >= 0.0f)
205 -            {
206 -                tmpMotion->SetFadeInTime(fadeTime);
207 -            }
208 +            tmpMotion->SetFadeInTime(fadeTime);
209 +        }
210  
211 -            // フェードアウトの時間を取得
212 -            fadeTime = _modelJson->GetMotionFadeOutTimeValue(group, i);
213 -            if (fadeTime >= 0.0f)
214 -            {
215 -                tmpMotion->SetFadeOutTime(fadeTime);
216 -            }
217 +        // フェードアウトの時間を取得
218 +        fadeTime = _modelJson->GetMotionFadeOutTimeValue(group, i);
219 +        if (fadeTime >= 0.0f)
220 +        {
221 +            tmpMotion->SetFadeOutTime(fadeTime);
222 +        }
223  
224 -            if (_motions[name])
225 -            {
226 -                // インスタンスを破棄
227 -                ACubismMotion::Delete(_motions[name]);
228 -            }
229 -            _motions[name] = tmpMotion;
230 +        if (_motions[name])
231 +        {
232 +            // インスタンスを破棄
233 +            ACubismMotion::Delete(_motions[name]);
234          }
235 +        _motions[name] = tmpMotion;
236  
237          DeleteBuffer(buffer, path.GetRawString());
238      }
239 @@ -309,24 +303,21 @@ Csm::CubismMotionQueueEntryHandle Cubism
240          // 一番先頭のモーションを読み込む
241          motion = static_cast<CubismMotion*>(LoadMotion(buffer, size, NULL, onFinishedMotionHandler));
242  
243 -        if (motion)
244 +        csmFloat32 fadeTime = _modelJson->GetMotionFadeInTimeValue(group, no);
245 +        if (fadeTime >= 0.0f)
246          {
247 -            csmFloat32 fadeTime = _modelJson->GetMotionFadeInTimeValue(group, no);
248 -            if (fadeTime >= 0.0f)
249 -            {
250 -                motion->SetFadeInTime(fadeTime);
251 -            }
252 -
253 -            fadeTime = _modelJson->GetMotionFadeOutTimeValue(group, no);
254 -            if (fadeTime >= 0.0f)
255 -            {
256 -                motion->SetFadeOutTime(fadeTime);
257 -            }
258 +            motion->SetFadeInTime(fadeTime);
259 +        }
260  
261 -            // 終了時にメモリから削除
262 -            autoDelete = true;
263 +        fadeTime = _modelJson->GetMotionFadeOutTimeValue(group, no);
264 +        if (fadeTime >= 0.0f)
265 +        {
266 +            motion->SetFadeOutTime(fadeTime);
267          }
268  
269 +        // 終了時にメモリから削除
270 +        autoDelete = true;
271 +
272          DeleteBuffer(buffer, path.GetRawString());
273      }
274      else
275 diff -pruN --exclude build ./demo_clean/src/LAppDefine.cpp ./demo_dev/src/LAppDefine.cpp
276 --- ./demo_clean/src/LAppDefine.cpp     2024-03-28 18:39:52.882141826 +0000
277 +++ ./demo_dev/src/LAppDefine.cpp       2024-03-28 18:43:36.377973713 +0000
278 @@ -38,6 +38,18 @@ namespace LAppDefine {
279      const csmChar* PowerImageName = "close.png";
280  
281      // モデル定義------------------------------------------
282 +    // モデルを配置したディレクトリ名の配列
283 +    // ディレクトリ名とmodel3.jsonの名前を一致させておくこと
284 +    const csmChar* ModelDir[] = {
285 +        "Haru",
286 +        "Hiyori",
287 +        "Mark",
288 +        "Natori",
289 +        "Rice",
290 +        "Mao"
291 +    };
292 +    const csmInt32 ModelDirSize = sizeof(ModelDir) / sizeof(const csmChar*);
293 +
294      // 外部定義ファイル(json)と合わせる
295      const csmChar* MotionGroupIdle = "Idle"; // アイドリング
296      const csmChar* MotionGroupTapBody = "TapBody"; // 体をタップしたとき
297 @@ -53,11 +65,11 @@ namespace LAppDefine {
298      const csmInt32 PriorityForce = 3;
299  
300      // デバッグ用ログの表示オプション
301 -    const csmBool DebugLogEnable = true;
302 +    const csmBool DebugLogEnable = false;
303      const csmBool DebugTouchLogEnable = false;
304  
305      // Frameworkから出力するログのレベル設定
306 -    const CubismFramework::Option::LogLevel CubismLoggingLevel = CubismFramework::Option::LogLevel_Verbose;
307 +    const CubismFramework::Option::LogLevel CubismLoggingLevel = CubismFramework::Option::LogLevel_Warning;
308  
309      // デフォルトのレンダーターゲットサイズ
310      const csmInt32 RenderTargetWidth = 1900;
311 diff -pruN --exclude build ./demo_clean/src/LAppDefine.hpp ./demo_dev/src/LAppDefine.hpp
312 --- ./demo_clean/src/LAppDefine.hpp     2024-03-28 18:39:52.882141826 +0000
313 +++ ./demo_dev/src/LAppDefine.hpp       2024-03-28 18:43:36.377973713 +0000
314 @@ -37,6 +37,9 @@ namespace LAppDefine {
315      extern const csmChar* PowerImageName;        ///< 終了ボタン画像ファイル
316  
317      // モデル定義--------------------------------------------
318 +    extern const csmChar* ModelDir[];               ///< モデルを配置したディレクトリ名の配列. ディレクトリ名とmodel3.jsonの名前を一致させておく.
319 +    extern const csmInt32 ModelDirSize;             ///< モデルディレクトリ配列のサイズ
320 +
321                                                      // 外部定義ファイル(json)と合わせる
322      extern const csmChar* MotionGroupIdle;          ///< アイドリング時に再生するモーションのリスト
323      extern const csmChar* MotionGroupTapBody;       ///< 体をタップした時に再生するモーションのリスト
324 diff -pruN --exclude build ./demo_clean/src/LAppDelegate.cpp ./demo_dev/src/LAppDelegate.cpp
325 --- ./demo_clean/src/LAppDelegate.cpp   2024-03-28 18:39:52.882141826 +0000
326 +++ ./demo_dev/src/LAppDelegate.cpp     2024-03-28 18:43:36.381973781 +0000
327 @@ -9,7 +9,6 @@
328  #include <iostream>
329  #include <sstream>
330  #include <unistd.h>
331 -#include <libgen.h>
332  #include <GL/glew.h>
333  #include <GLFW/glfw3.h>
334  #include "LAppView.hpp"
335 @@ -46,11 +45,12 @@ void LAppDelegate::ReleaseInstance()
336      s_instance = NULL;
337  }
338  
339 -bool LAppDelegate::Initialize()
340 +bool LAppDelegate::Initialize(int initWindowWidth, int initWindowHeight,
341 +                              const char *windowTitle)
342  {
343      if (DebugLogEnable)
344      {
345 -        LAppPal::PrintLogLn("START");
346 +        LAppPal::PrintLog("START");
347      }
348  
349      // GLFWの初期化
350 @@ -58,18 +58,24 @@ bool LAppDelegate::Initialize()
351      {
352          if (DebugLogEnable)
353          {
354 -            LAppPal::PrintLogLn("Can't initilize GLFW");
355 +            LAppPal::PrintLog("Can't initilize GLFW");
356          }
357          return GL_FALSE;
358      }
359  
360      // Windowの生成_
361 -    _window = glfwCreateWindow(RenderTargetWidth, RenderTargetHeight, "SAMPLE", NULL, NULL);
362 +    _window = glfwCreateWindow(
363 +        initWindowWidth ? initWindowWidth : RenderTargetWidth,
364 +        initWindowHeight ? initWindowHeight : RenderTargetHeight,
365 +        windowTitle ? windowTitle : "SAMPLE",
366 +        NULL,
367 +        NULL);
368 +
369      if (_window == NULL)
370      {
371          if (DebugLogEnable)
372          {
373 -            LAppPal::PrintLogLn("Can't create GLFW window.");
374 +            LAppPal::PrintLog("Can't create GLFW window.");
375          }
376          glfwTerminate();
377          return GL_FALSE;
378 @@ -82,7 +88,7 @@ bool LAppDelegate::Initialize()
379      if (glewInit() != GLEW_OK) {
380          if (DebugLogEnable)
381          {
382 -            LAppPal::PrintLogLn("Can't initilize glew.");
383 +            LAppPal::PrintLog("Can't initilize glew.");
384          }
385          glfwTerminate();
386          return GL_FALSE;
387 @@ -96,16 +102,11 @@ bool LAppDelegate::Initialize()
388      glEnable(GL_BLEND);
389      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
390  
391 -    //コールバック関数の登録
392 -    glfwSetMouseButtonCallback(_window, EventHandler::OnMouseCallBack);
393 -    glfwSetCursorPosCallback(_window, EventHandler::OnMouseCallBack);
394 -
395      // ウィンドウサイズ記憶
396      int width, height;
397      glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
398      _windowWidth = width;
399      _windowHeight = height;
400 -    glViewport(0, 0, _windowWidth, _windowHeight);
401  
402      //AppViewの初期化
403      _view->Initialize();
404 @@ -113,8 +114,6 @@ bool LAppDelegate::Initialize()
405      // Cubism3の初期化
406      InitializeCubism();
407  
408 -    SetExecuteAbsolutePath();
409 -
410      //load model
411      LAppLive2DManager::GetInstance();
412  
413 @@ -156,7 +155,6 @@ void LAppDelegate::Run()
414              _windowWidth = width;
415              _windowHeight = height;
416          }
417 -        glViewport(0, 0, _windowWidth, _windowHeight);
418  
419          // 時間更新
420          LAppPal::UpdateTime();
421 @@ -191,7 +189,7 @@ LAppDelegate::LAppDelegate():
422      _windowWidth(0),
423      _windowHeight(0)
424  {
425 -    _executeAbsolutePath = "";
426 +    _rootDirectory = "";
427      _view = new LAppView();
428      _textureManager = new LAppTextureManager();
429  }
430 @@ -217,49 +215,6 @@ void LAppDelegate::InitializeCubism()
431      LAppPal::UpdateTime();
432  }
433  
434 -void LAppDelegate::OnMouseCallBack(GLFWwindow* window, int button, int action, int modify)
435 -{
436 -    if (_view == NULL)
437 -    {
438 -        return;
439 -    }
440 -    if (GLFW_MOUSE_BUTTON_LEFT != button)
441 -    {
442 -        return;
443 -    }
444 -
445 -    if (GLFW_PRESS == action)
446 -    {
447 -        _captured = true;
448 -        _view->OnTouchesBegan(_mouseX, _mouseY);
449 -    }
450 -    else if (GLFW_RELEASE == action)
451 -    {
452 -        if (_captured)
453 -        {
454 -            _captured = false;
455 -            _view->OnTouchesEnded(_mouseX, _mouseY);
456 -        }
457 -    }
458 -}
459 -
460 -void LAppDelegate::OnMouseCallBack(GLFWwindow* window, double x, double y)
461 -{
462 -    _mouseX = static_cast<float>(x);
463 -    _mouseY = static_cast<float>(y);
464 -
465 -    if (!_captured)
466 -    {
467 -        return;
468 -    }
469 -    if (_view == NULL)
470 -    {
471 -        return;
472 -    }
473 -
474 -    _view->OnTouchesMoved(_mouseX, _mouseY);
475 -}
476 -
477  GLuint LAppDelegate::CreateShader()
478  {
479      //バーテックスシェーダのコンパイル
480 @@ -302,16 +257,24 @@ GLuint LAppDelegate::CreateShader()
481      return programId;
482  }
483  
484 -void LAppDelegate::SetExecuteAbsolutePath()
485 +void LAppDelegate::SetRootDirectory(std::string rootDir)
486  {
487 -    char path[1024];
488 -    ssize_t len = readlink("/proc/self/exe", path, 1024 - 1);
489 +    this->_rootDirectory = rootDir + "/";
490 +}
491  
492 -    if (len != -1)
493 +Csm::csmVector<string> LAppDelegate::Split(const std::string& baseString, char delimiter)
494 +{
495 +    Csm::csmVector<string> elems;
496 +    stringstream ss(baseString);
497 +    string item;
498 +
499 +    while(getline(ss, item, delimiter))
500      {
501 -        path[len] = '\0';
502 +        if(!item.empty())
503 +        {
504 +            elems.PushBack(item);
505 +        }
506      }
507  
508 -    this->_executeAbsolutePath = dirname(path);
509 -    this->_executeAbsolutePath += "/";
510 +    return elems;
511  }
512 diff -pruN --exclude build ./demo_clean/src/LAppDelegate.hpp ./demo_dev/src/LAppDelegate.hpp
513 --- ./demo_clean/src/LAppDelegate.hpp   2024-03-28 18:39:52.882141826 +0000
514 +++ ./demo_dev/src/LAppDelegate.hpp     2024-03-28 18:43:36.381973781 +0000
515 @@ -40,7 +40,8 @@ public:
516      /**
517      * @brief   APPに必要なものを初期化する。
518      */
519 -    bool Initialize();
520 +    bool Initialize(int initWindowWidth = 0, int initWindowHeight = 0,
521 +                    const char *windowTitle = "SAMPLE");
522  
523      /**
524      * @brief   解放する。
525 @@ -53,25 +54,6 @@ public:
526      void Run();
527  
528      /**
529 -    * @brief   OpenGL用 glfwSetMouseButtonCallback用関数。
530 -    *
531 -    * @param[in]       window            コールバックを呼んだWindow情報
532 -    * @param[in]       button            ボタン種類
533 -    * @param[in]       action            実行結果
534 -    * @param[in]       modify
535 -    */
536 -    void OnMouseCallBack(GLFWwindow* window, int button, int action, int modify);
537 -
538 -    /**
539 -    * @brief   OpenGL用 glfwSetCursorPosCallback用関数。
540 -    *
541 -    * @param[in]       window            コールバックを呼んだWindow情報
542 -    * @param[in]       x                 x座標
543 -    * @param[in]       y                 x座標
544 -    */
545 -    void OnMouseCallBack(GLFWwindow* window, double x, double y);
546 -
547 -    /**
548      * @brief シェーダーを登録する。
549      */
550      GLuint CreateShader();
551 @@ -97,14 +79,16 @@ public:
552      void AppEnd() { _isEnd = true; }
553  
554      /**
555 -     * @brief   アプリケーションの実行パスを設定する。
556 +     * @brief   ルートディレクトリを設定する。
557 +     *
558 +     * @param[in] rootDir : The root directory to set to.
559       */
560 -    void SetExecuteAbsolutePath();
561 +    void SetRootDirectory(std::string rootDir);
562  
563      /**
564 -     * @brief   アプリケーションの実行パスを取得する。
565 +     * @brief   ルートディレクトリを取得する。
566       */
567 -    std::string GetExecuteAbsolutePath(){ return _executeAbsolutePath;}
568 +    std::string GetRootDirectory(){ return _rootDirectory;}
569  
570      /**
571       * @brief   テクスチャマネージャーを取得する。
572 @@ -127,6 +111,11 @@ private:
573      */
574      void InitializeCubism();
575  
576 +    /**
577 +     * @brief   文字列を指定の文字で切り分ける
578 +     */
579 +    Csm::csmVector<std::string> Split(const std::string& baseString, char delim);
580 +
581      LAppAllocator _cubismAllocator;              ///< Cubism3 Allocator
582      Csm::CubismFramework::Option _cubismOption;  ///< Cubism3 Option
583      GLFWwindow* _window;                         ///< OpenGL ウィンドウ
584 @@ -136,29 +125,8 @@ private:
585      float _mouseY;                               ///< マウスY座標
586      bool _isEnd;                                 ///< APP終了しているか
587      LAppTextureManager* _textureManager;         ///< テクスチャマネージャー
588 -    std::string _executeAbsolutePath;            ///< アプリケーションの実行パス
589 +    std::string _rootDirectory; ///< ルートディレクトリ
590  
591      int _windowWidth;                            ///< Initialize関数で設定したウィンドウ幅
592      int _windowHeight;                           ///< Initialize関数で設定したウィンドウ高さ
593  };
594 -
595 -class EventHandler
596 -{
597 -public:
598 -    /**
599 -    * @brief   glfwSetMouseButtonCallback用コールバック関数。
600 -    */
601 -    static void OnMouseCallBack(GLFWwindow* window, int button, int action, int modify)
602 -    {
603 -        LAppDelegate::GetInstance()->OnMouseCallBack(window, button, action, modify);
604 -    }
605 -
606 -    /**
607 -    * @brief   glfwSetCursorPosCallback用コールバック関数。
608 -    */
609 -    static void OnMouseCallBack(GLFWwindow* window, double x, double y)
610 -    {
611 -         LAppDelegate::GetInstance()->OnMouseCallBack(window, x, y);
612 -    }
613 -
614 -};
615 diff -pruN --exclude build ./demo_clean/src/LAppLive2DManager.cpp ./demo_dev/src/LAppLive2DManager.cpp
616 --- ./demo_clean/src/LAppLive2DManager.cpp      2024-03-28 18:39:52.882141826 +0000
617 +++ ./demo_dev/src/LAppLive2DManager.cpp        2024-03-28 18:43:36.381973781 +0000
618 @@ -6,13 +6,7 @@
619   */
620  
621  #include "LAppLive2DManager.hpp"
622 -#include <stdio.h>
623 -#include <stdlib.h>
624 -#include <string.h>
625 -#include <dirent.h>
626 -#include <unistd.h>
627 -#include <libgen.h>
628 -#include <limits.h>
629 +#include <string>
630  #include <GL/glew.h>
631  #include <GLFW/glfw3.h>
632  #include <Rendering/CubismRenderer.hpp>
633 @@ -25,19 +19,14 @@
634  
635  using namespace Csm;
636  using namespace LAppDefine;
637 +using namespace std;
638  
639  namespace {
640      LAppLive2DManager* s_instance = NULL;
641  
642      void FinishedMotion(ACubismMotion* self)
643      {
644 -        LAppPal::PrintLogLn("Motion Finished: %x", self);
645 -    }
646 -
647 -    int CompareCsmString(const void* a, const void* b)
648 -    {
649 -        return strcmp(reinterpret_cast<const Csm::csmString*>(a)->GetRawString(),
650 -            reinterpret_cast<const Csm::csmString*>(b)->GetRawString());
651 +        LAppPal::PrintLog("Motion Finished: %x", self);
652      }
653  }
654  
655 @@ -63,18 +52,16 @@ void LAppLive2DManager::ReleaseInstance(
656  
657  LAppLive2DManager::LAppLive2DManager()
658      : _viewMatrix(NULL)
659 -    , _sceneIndex(0)
660 +    , _projScaleFactor(1.0f)
661 +    , _translateX(0.0f)
662 +    , _translateY(0.0f)
663  {
664      _viewMatrix = new CubismMatrix44();
665 -    SetUpModel();
666 -
667 -    ChangeScene(_sceneIndex);
668  }
669  
670  LAppLive2DManager::~LAppLive2DManager()
671  {
672      ReleaseAllModel();
673 -    delete _viewMatrix;
674  }
675  
676  void LAppLive2DManager::ReleaseAllModel()
677 @@ -87,60 +74,6 @@ void LAppLive2DManager::ReleaseAllModel(
678      _models.Clear();
679  }
680  
681 -void LAppLive2DManager::SetUpModel()
682 -{
683 -    // ResourcesPathの中にあるフォルダ名を全てクロールし、モデルが存在するフォルダを定義する。
684 -    // フォルダはあるが同名の.model3.jsonが見つからなかった場合はリストに含めない。
685 -    struct dirent *dirent;
686 -    csmString crawlPath(LAppDelegate::GetInstance()->GetExecuteAbsolutePath().c_str());
687 -    crawlPath += ResourcesPath;
688 -
689 -    DIR *pDir = opendir(crawlPath.GetRawString());
690 -    if (pDir == NULL) return;
691 -
692 -    _modelDir.Clear();
693 -
694 -    while ((dirent = readdir(pDir)) != NULL)
695 -    {
696 -        if ((dirent->d_type & DT_DIR) && strcmp(dirent->d_name, "..") != 0)
697 -        {
698 -            // フォルダと同名の.model3.jsonがあるか探索する
699 -            struct dirent *dirent2;
700 -
701 -            csmString modelName(dirent->d_name);
702 -
703 -            csmString modelPath(crawlPath);
704 -            modelPath += modelName;
705 -            modelPath.Append(1, '/');
706 -
707 -            csmString model3jsonName(modelName);
708 -            model3jsonName += ".model3.json";
709 -
710 -            DIR *pDir2 = opendir(modelPath.GetRawString());
711 -            while ((dirent2 = readdir(pDir2)) != NULL)
712 -            {
713 -                if (strcmp(dirent2->d_name, model3jsonName.GetRawString()) == 0)
714 -                {
715 -                    _modelDir.PushBack(csmString(dirent->d_name));
716 -                }
717 -            }
718 -            closedir(pDir2);
719 -        }
720 -    }
721 -    closedir(pDir);
722 -    qsort(_modelDir.GetPtr(), _modelDir.GetSize(), sizeof(csmString), CompareCsmString);
723 -}
724 -
725 -csmVector<csmString> LAppLive2DManager::GetModelDir() const
726 -{
727 -    return _modelDir;
728 -}
729 -
730 -csmInt32 LAppLive2DManager::GetModelDirSize() const
731 -{
732 -    return _modelDir.GetSize();
733 -}
734 -
735  LAppModel* LAppLive2DManager::GetModel(csmUint32 no) const
736  {
737      if (no < _models.GetSize())
738 @@ -165,27 +98,7 @@ void LAppLive2DManager::OnTap(csmFloat32
739  {
740      if (DebugLogEnable)
741      {
742 -        LAppPal::PrintLogLn("[APP]tap point: {x:%.2f y:%.2f}", x, y);
743 -    }
744 -
745 -    for (csmUint32 i = 0; i < _models.GetSize(); i++)
746 -    {
747 -        if (_models[i]->HitTest(HitAreaNameHead, x, y))
748 -        {
749 -            if (DebugLogEnable)
750 -            {
751 -                LAppPal::PrintLogLn("[APP]hit area: [%s]", HitAreaNameHead);
752 -            }
753 -            _models[i]->SetRandomExpression();
754 -        }
755 -        else if (_models[i]->HitTest(HitAreaNameBody, x, y))
756 -        {
757 -            if (DebugLogEnable)
758 -            {
759 -                LAppPal::PrintLogLn("[APP]hit area: [%s]", HitAreaNameBody);
760 -            }
761 -            _models[i]->StartRandomMotion(MotionGroupTapBody, PriorityNormal, FinishedMotion);
762 -        }
763 +        LAppPal::PrintLog("[APP]tap point: {x:%.2f y:%.2f}", x, y);
764      }
765  }
766  
767 @@ -194,15 +107,15 @@ void LAppLive2DManager::OnUpdate() const
768      int width, height;
769      glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
770  
771 +    CubismMatrix44 projection;
772      csmUint32 modelCount = _models.GetSize();
773      for (csmUint32 i = 0; i < modelCount; ++i)
774      {
775 -        CubismMatrix44 projection;
776          LAppModel* model = GetModel(i);
777  
778          if (model->GetModel() == NULL)
779          {
780 -            LAppPal::PrintLogLn("Failed to model->GetModel().");
781 +            LAppPal::PrintLog("Failed to model->GetModel().");
782              continue;
783          }
784  
785 @@ -210,12 +123,15 @@ void LAppLive2DManager::OnUpdate() const
786          {
787              // 横に長いモデルを縦長ウィンドウに表示する際モデルの横サイズでscaleを算出する
788              model->GetModelMatrix()->SetWidth(2.0f);
789 -            projection.Scale(1.0f, static_cast<float>(width) / static_cast<float>(height));
790 +            projection.Scale(_projScaleFactor,
791 +                             _projScaleFactor * static_cast<float>(width) / static_cast<float>(height));
792          }
793          else
794          {
795 -            projection.Scale(static_cast<float>(height) / static_cast<float>(width), 1.0f);
796 +            projection.Scale(_projScaleFactor * static_cast<float>(height) / static_cast<float>(width),
797 +                             _projScaleFactor);
798          }
799 +        projection.Translate(_translateX, _translateY);
800  
801          // 必要があればここで乗算
802          if (_viewMatrix != NULL)
803 @@ -232,37 +148,15 @@ void LAppLive2DManager::OnUpdate() const
804      }
805  }
806  
807 -void LAppLive2DManager::NextScene()
808 +void LAppLive2DManager::SetModel(std::string modelName, bool useOldParamId)
809  {
810 -    csmInt32 no = (_sceneIndex + 1) % GetModelDirSize();
811 -    ChangeScene(no);
812 -}
813 -
814 -void LAppLive2DManager::ChangeScene(Csm::csmInt32 index)
815 -{
816 -    _sceneIndex = index;
817 -    if (DebugLogEnable)
818 -    {
819 -        LAppPal::PrintLogLn("[APP]model index: %d", _sceneIndex);
820 -    }
821 -
822 -    // ModelDir[]に保持したディレクトリ名から
823 -    // model3.jsonのパスを決定する.
824 -    // ディレクトリ名とmodel3.jsonの名前を一致させておくこと.
825 -    const csmString& model = _modelDir[index];
826 -    LAppPal::PrintLogLn("[APP]_modelDir: %s", model.GetRawString());
827 -
828 -    csmString modelPath(LAppDelegate::GetInstance()->GetExecuteAbsolutePath().c_str());
829 -    modelPath += ResourcesPath;
830 -    modelPath += model;
831 -    modelPath.Append(1, '/');
832 -
833 -    csmString modelJsonName(model);
834 +    std::string modelPath = LAppDelegate::GetInstance()->GetRootDirectory() + ResourcesPath + modelName + "/";
835 +    std::string modelJsonName = modelName;
836      modelJsonName += ".model3.json";
837  
838      ReleaseAllModel();
839 -    _models.PushBack(new LAppModel());
840 -    _models[0]->LoadAssets(modelPath.GetRawString(), modelJsonName.GetRawString());
841 +    _models.PushBack(new LAppModel(useOldParamId));
842 +    _models[0]->LoadAssets(modelPath.c_str(), modelJsonName.c_str());
843  
844      /*
845       * モデル半透明表示を行うサンプルを提示する。
846 @@ -283,8 +177,8 @@ void LAppLive2DManager::ChangeScene(Csm:
847  
848  #if defined(USE_RENDER_TARGET) || defined(USE_MODEL_RENDER_TARGET)
849          // モデル個別にαを付けるサンプルとして、もう1体モデルを作成し、少し位置をずらす
850 -        _models.PushBack(new LAppModel());
851 -        _models[1]->LoadAssets(modelPath.GetRawString(), modelJsonName.GetRawString());
852 +        _models.PushBack(new LAppModel(useOldParamId));
853 +        _models[1]->LoadAssets(modelPath.c_str(), modelJsonName.c_str());
854          _models[1]->GetModelMatrix()->TranslateX(0.2f);
855  #endif
856  
857 @@ -312,3 +206,20 @@ void LAppLive2DManager::SetViewMatrix(Cu
858          _viewMatrix->GetArray()[i] = m->GetArray()[i];
859      }
860  }
861 +
862 +void LAppLive2DManager::SetTracker(MouseCursorTracker *tracker)
863 +{
864 +    for (auto it = _models.Begin(); it != _models.End(); ++it)
865 +    {
866 +        (*it)->SetTracker(tracker);
867 +    }
868 +}
869 +
870 +void LAppLive2DManager::SetProjectionScaleTranslate(float scaleFactor,
871 +                                                    float translateX,
872 +                                                    float translateY)
873 +{
874 +    _projScaleFactor = scaleFactor;
875 +    _translateX = translateX;
876 +    _translateY = translateY;
877 +}
878 diff -pruN --exclude build ./demo_clean/src/LAppLive2DManager.hpp ./demo_dev/src/LAppLive2DManager.hpp
879 --- ./demo_clean/src/LAppLive2DManager.hpp      2024-03-28 18:39:52.882141826 +0000
880 +++ ./demo_dev/src/LAppLive2DManager.hpp        2024-03-28 18:43:36.381973781 +0000
881 @@ -6,12 +6,15 @@
882   */
883  #pragma once
884  
885 +#include <string>
886  #include <CubismFramework.hpp>
887  #include <Math/CubismMatrix44.hpp>
888  #include <Type/csmVector.hpp>
889  
890  class LAppModel;
891  
892 +class MouseCursorTracker;
893 +
894  /**
895  * @brief サンプルアプリケーションにおいてCubismModelを管理するクラス<br>
896  *         モデル生成と破棄、タップイベントの処理、モデル切り替えを行う。
897 @@ -36,24 +39,6 @@ public:
898      static void ReleaseInstance();
899  
900      /**
901 -    * @brief   Resources フォルダにあるモデルフォルダ名をセットする
902 -    *
903 -    */
904 -    void SetUpModel();
905 -
906 -    /**
907 -    * @brief   Resources フォルダにあるモデルフォルダ名を取得する
908 -    *
909 -    */
910 -    Csm::csmVector<Csm::csmString> GetModelDir() const;
911 -
912 -    /**
913 -    * @brief   Resources フォルダにあるモデルフォルダのサイズを取得する
914 -    *
915 -    */
916 -    Csm::csmInt32 GetModelDirSize() const;
917 -
918 -    /**
919      * @brief   現在のシーンで保持しているモデルを返す
920      *
921      * @param[in]   no  モデルリストのインデックス値
922 @@ -90,16 +75,14 @@ public:
923      void OnUpdate() const;
924  
925      /**
926 -    * @brief   次のシーンに切り替える<br>
927 -    *           サンプルアプリケーションではモデルセットの切り替えを行う。
928 -    */
929 -    void NextScene();
930 -
931 -    /**
932 -    * @brief   シーンを切り替える<br>
933 -    *           サンプルアプリケーションではモデルセットの切り替えを行う。
934 -    */
935 -    void ChangeScene(Csm::csmInt32 index);
936 +     * @brief Set model data
937 +     *
938 +     * @param[in] modelName : Name of model, should be the same for both
939 +     *                        the directory and the model3.json file
940 +     * @param[in] useOldParamId : If true, translate new (Cubism 3+)
941 +     *                            parameter IDs to old (Cubism 2.1) ones
942 +     */
943 +    void SetModel(std::string modelName, bool useOldParamId);
944  
945      /**
946       * @brief   モデル個数を得る
947 @@ -112,6 +95,24 @@ public:
948       */
949      void SetViewMatrix(Live2D::Cubism::Framework::CubismMatrix44* m);
950  
951 +    /**
952 +     * @brief Set the pointer to the MouseCursorTracker instance
953 +     *
954 +     * @param[in] tracker : Pointer to MouseCursorTracker instance
955 +     */
956 +    void SetTracker(MouseCursorTracker *tracker);
957 +
958 +    /**
959 +     * @brief Set projection scale factor and translation parameters
960 +     *
961 +     * @param[in] scaleFactor : Scale factor applied in both X and Y directions
962 +     * @param[in] translateX : Translation in X direction
963 +     * @param[in] translateY : Translation in Y direction
964 +     */
965 +    void SetProjectionScaleTranslate(float scaleFactor,
966 +                                     float translateX,
967 +                                     float translateY);
968 +
969  private:
970      /**
971      * @brief  コンストラクタ
972 @@ -123,9 +124,10 @@ private:
973      */
974      virtual ~LAppLive2DManager();
975  
976 -    Csm::CubismMatrix44* _viewMatrix; ///< モデル描画に用いるView行列
977 -    Csm::csmVector<LAppModel*> _models; ///< モデルインスタンスのコンテナ
978 -    Csm::csmInt32 _sceneIndex; ///< 表示するシーンのインデックス値
979 +    Csm::CubismMatrix44*        _viewMatrix; ///< モデル描画に用いるView行列
980 +    Csm::csmVector<LAppModel*>  _models; ///< モデルインスタンスのコンテナ
981  
982 -    Csm::csmVector<Csm::csmString> _modelDir; ///< モデルディレクトリ名のコンテナ
983 +    float _projScaleFactor;
984 +    float _translateX;
985 +    float _translateY;
986  };
987 diff -pruN --exclude build ./demo_clean/src/LAppModel.cpp ./demo_dev/src/LAppModel.cpp
988 --- ./demo_clean/src/LAppModel.cpp      2024-03-28 18:39:52.882141826 +0000
989 +++ ./demo_dev/src/LAppModel.cpp        2024-03-28 18:44:22.822767401 +0000
990 @@ -21,6 +21,10 @@
991  #include "LAppTextureManager.hpp"
992  #include "LAppDelegate.hpp"
993  
994 +#include "mouse_cursor_tracker.h"
995 +
996 +#include <iostream>
997 +
998  using namespace Live2D::Cubism::Framework;
999  using namespace Live2D::Cubism::Framework::DefaultParameterId;
1000  using namespace LAppDefine;
1001 @@ -30,7 +34,7 @@ namespace {
1002      {
1003          if (DebugLogEnable)
1004          {
1005 -            LAppPal::PrintLogLn("[APP]create buffer: %s ", path);
1006 +            LAppPal::PrintLog("[APP]create buffer: %s ", path);
1007          }
1008          return LAppPal::LoadFileAsBytes(path, size);
1009      }
1010 @@ -39,28 +43,30 @@ namespace {
1011      {
1012          if (DebugLogEnable)
1013          {
1014 -            LAppPal::PrintLogLn("[APP]delete buffer: %s", path);
1015 +            LAppPal::PrintLog("[APP]delete buffer: %s", path);
1016          }
1017          LAppPal::ReleaseBytes(buffer);
1018      }
1019  }
1020  
1021 -LAppModel::LAppModel()
1022 +LAppModel::LAppModel(bool useOldParamId)
1023      : CubismUserModel()
1024      , _modelSetting(NULL)
1025      , _userTimeSeconds(0.0f)
1026 +    , _tracker(nullptr)
1027 +    , _useOldParamId(useOldParamId)
1028  {
1029      if (DebugLogEnable)
1030      {
1031          _debugMode = true;
1032      }
1033  
1034 -    _idParamAngleX = CubismFramework::GetIdManager()->GetId(ParamAngleX);
1035 -    _idParamAngleY = CubismFramework::GetIdManager()->GetId(ParamAngleY);
1036 -    _idParamAngleZ = CubismFramework::GetIdManager()->GetId(ParamAngleZ);
1037 -    _idParamBodyAngleX = CubismFramework::GetIdManager()->GetId(ParamBodyAngleX);
1038 -    _idParamEyeBallX = CubismFramework::GetIdManager()->GetId(ParamEyeBallX);
1039 -    _idParamEyeBallY = CubismFramework::GetIdManager()->GetId(ParamEyeBallY);
1040 +    _idParamAngleX = CubismFramework::GetIdManager()->GetId(_(ParamAngleX));
1041 +    _idParamAngleY = CubismFramework::GetIdManager()->GetId(_(ParamAngleY));
1042 +    _idParamAngleZ = CubismFramework::GetIdManager()->GetId(_(ParamAngleZ));
1043 +    _idParamBodyAngleX = CubismFramework::GetIdManager()->GetId(_(ParamBodyAngleX));
1044 +    _idParamEyeBallX = CubismFramework::GetIdManager()->GetId(_(ParamEyeBallX));
1045 +    _idParamEyeBallY = CubismFramework::GetIdManager()->GetId(_(ParamEyeBallY));
1046  }
1047  
1048  LAppModel::~LAppModel()
1049 @@ -84,7 +90,7 @@ void LAppModel::LoadAssets(const csmChar
1050  
1051      if (_debugMode)
1052      {
1053 -        LAppPal::PrintLogLn("[APP]load model setting: %s", fileName);
1054 +        LAppPal::PrintLog("[APP]load model setting: %s", fileName);
1055      }
1056  
1057      csmSizeInt size;
1058 @@ -96,12 +102,6 @@ void LAppModel::LoadAssets(const csmChar
1059  
1060      SetupModel(setting);
1061  
1062 -    if (_model == NULL)
1063 -    {
1064 -        LAppPal::PrintLogLn("Failed to LoadAssets().");
1065 -        return;
1066 -    }
1067 -
1068      CreateRenderer();
1069  
1070      SetupTextures();
1071 @@ -126,7 +126,7 @@ void LAppModel::SetupModel(ICubismModelS
1072  
1073          if (_debugMode)
1074          {
1075 -            LAppPal::PrintLogLn("[APP]create model: %s", setting->GetModelFileName());
1076 +            LAppPal::PrintLog("[APP]create model: %s", setting->GetModelFileName());
1077          }
1078  
1079          buffer = CreateBuffer(path.GetRawString(), &size);
1080 @@ -147,15 +147,12 @@ void LAppModel::SetupModel(ICubismModelS
1081              buffer = CreateBuffer(path.GetRawString(), &size);
1082              ACubismMotion* motion = LoadExpression(buffer, size, name.GetRawString());
1083  
1084 -            if (motion)
1085 +            if (_expressions[name] != NULL)
1086              {
1087 -                if (_expressions[name] != NULL)
1088 -                {
1089 -                    ACubismMotion::Delete(_expressions[name]);
1090 -                    _expressions[name] = NULL;
1091 -                }
1092 -                _expressions[name] = motion;
1093 +                ACubismMotion::Delete(_expressions[name]);
1094 +                _expressions[name] = NULL;
1095              }
1096 +            _expressions[name] = motion;
1097  
1098              DeleteBuffer(buffer, path.GetRawString());
1099          }
1100 @@ -199,7 +196,7 @@ void LAppModel::SetupModel(ICubismModelS
1101          breathParameters.PushBack(CubismBreath::BreathParameterData(_idParamAngleY, 0.0f, 8.0f, 3.5345f, 0.5f));
1102          breathParameters.PushBack(CubismBreath::BreathParameterData(_idParamAngleZ, 0.0f, 10.0f, 5.5345f, 0.5f));
1103          breathParameters.PushBack(CubismBreath::BreathParameterData(_idParamBodyAngleX, 0.0f, 4.0f, 15.5345f, 0.5f));
1104 -        breathParameters.PushBack(CubismBreath::BreathParameterData(CubismFramework::GetIdManager()->GetId(ParamBreath), 0.5f, 0.5f, 3.2345f, 0.5f));
1105 +        breathParameters.PushBack(CubismBreath::BreathParameterData(CubismFramework::GetIdManager()->GetId(_(ParamBreath)), 0.5f, 0.5f, 3.2345f, 0.5f));
1106  
1107          _breath->SetParameters(breathParameters);
1108      }
1109 @@ -232,12 +229,6 @@ void LAppModel::SetupModel(ICubismModelS
1110          }
1111      }
1112  
1113 -    if (_modelSetting == NULL || _modelMatrix == NULL)
1114 -    {
1115 -        LAppPal::PrintLogLn("Failed to SetupModel().");
1116 -        return;
1117 -    }
1118 -
1119      //Layout
1120      csmMap<csmString, csmFloat32> layout;
1121      _modelSetting->GetLayoutMap(layout);
1122 @@ -270,7 +261,7 @@ void LAppModel::PreloadMotionGroup(const
1123  
1124          if (_debugMode)
1125          {
1126 -            LAppPal::PrintLogLn("[APP]load motion: %s => [%s_%d] ", path.GetRawString(), group, i);
1127 +            LAppPal::PrintLog("[APP]load motion: %s => [%s_%d] ", path.GetRawString(), group, i);
1128          }
1129  
1130          csmByte* buffer;
1131 @@ -278,27 +269,24 @@ void LAppModel::PreloadMotionGroup(const
1132          buffer = CreateBuffer(path.GetRawString(), &size);
1133          CubismMotion* tmpMotion = static_cast<CubismMotion*>(LoadMotion(buffer, size, name.GetRawString()));
1134  
1135 -        if (tmpMotion)
1136 +        csmFloat32 fadeTime = _modelSetting->GetMotionFadeInTimeValue(group, i);
1137 +        if (fadeTime >= 0.0f)
1138          {
1139 -            csmFloat32 fadeTime = _modelSetting->GetMotionFadeInTimeValue(group, i);
1140 -            if (fadeTime >= 0.0f)
1141 -            {
1142 -                tmpMotion->SetFadeInTime(fadeTime);
1143 -            }
1144 +            tmpMotion->SetFadeInTime(fadeTime);
1145 +        }
1146  
1147 -            fadeTime = _modelSetting->GetMotionFadeOutTimeValue(group, i);
1148 -            if (fadeTime >= 0.0f)
1149 -            {
1150 -                tmpMotion->SetFadeOutTime(fadeTime);
1151 -            }
1152 -            tmpMotion->SetEffectIds(_eyeBlinkIds, _lipSyncIds);
1153 +        fadeTime = _modelSetting->GetMotionFadeOutTimeValue(group, i);
1154 +        if (fadeTime >= 0.0f)
1155 +        {
1156 +            tmpMotion->SetFadeOutTime(fadeTime);
1157 +        }
1158 +        tmpMotion->SetEffectIds(_eyeBlinkIds, _lipSyncIds);
1159  
1160 -            if (_motions[name] != NULL)
1161 -            {
1162 -                ACubismMotion::Delete(_motions[name]);
1163 -            }
1164 -            _motions[name] = tmpMotion;
1165 +        if (_motions[name] != NULL)
1166 +        {
1167 +            ACubismMotion::Delete(_motions[name]);
1168          }
1169 +        _motions[name] = tmpMotion;
1170  
1171          DeleteBuffer(buffer, path.GetRawString());
1172      }
1173 @@ -353,86 +341,117 @@ void LAppModel::Update()
1174      const csmFloat32 deltaTimeSeconds = LAppPal::GetDeltaTime();
1175      _userTimeSeconds += deltaTimeSeconds;
1176  
1177 -    _dragManager->Update(deltaTimeSeconds);
1178 -    _dragX = _dragManager->GetX();
1179 -    _dragY = _dragManager->GetY();
1180 -
1181 -    // モーションによるパラメータ更新の有無
1182 -    csmBool motionUpdated = false;
1183 -
1184 -    //-----------------------------------------------------------------
1185 -    _model->LoadParameters(); // 前回セーブされた状態をロード
1186 -    if (_motionManager->IsFinished())
1187 -    {
1188 -        // モーションの再生がない場合、待機モーションの中からランダムで再生する
1189 -        StartRandomMotion(MotionGroupIdle, PriorityIdle);
1190 -    }
1191 -    else
1192 +    if (_tracker)
1193      {
1194 -        motionUpdated = _motionManager->UpdateMotion(_model, deltaTimeSeconds); // モーションを更新
1195 -    }
1196 -    _model->SaveParameters(); // 状態を保存
1197 -    //-----------------------------------------------------------------
1198 +        auto idMan = CubismFramework::GetIdManager();
1199 +        auto params = _tracker->getParams();
1200  
1201 -    // 不透明度
1202 -    _opacity = _model->GetModelOpacity();
1203 +        _model->LoadParameters(); // 前回セーブされた状態をロード
1204  
1205 -    // まばたき
1206 -    if (!motionUpdated)
1207 -    {
1208 -        if (_eyeBlink != NULL)
1209 +        int paramsMotionPriority = static_cast<int>(params.motionPriority);
1210 +
1211 +        if (paramsMotionPriority != PriorityNone)
1212          {
1213 -            // メインモーションの更新がないとき
1214 -            _eyeBlink->UpdateParameters(_model, deltaTimeSeconds); // 目パチ
1215 +            StartMotion(params.motionGroup.c_str(), params.motionNumber,
1216 +                        paramsMotionPriority);
1217          }
1218 -    }
1219 +        else if (params.randomIdleMotion && _motionManager->IsFinished())
1220 +        {
1221 +            // モーションの再生がない場合、待機モーションの中からランダムで再生する
1222 +            StartRandomMotion(MotionGroupIdle, PriorityIdle);
1223 +        }
1224 +        // FIXME pose does not return to normal after motion
1225 +        // if we don't have randomIdleMotion set
1226 +        else
1227 +        {
1228 +            _motionManager->UpdateMotion(_model, deltaTimeSeconds); // モーションを更新
1229 +        }
1230 +        _model->SaveParameters(); // 状態を保存
1231  
1232 -    if (_expressionManager != NULL)
1233 -    {
1234 -        _expressionManager->UpdateMotion(_model, deltaTimeSeconds); // 表情でパラメータ更新(相対変化)
1235 -    }
1236 +        if (params.expression != "")
1237 +        {
1238 +            SetExpression(params.expression.c_str());
1239 +        }
1240 +        if (_expressionManager != NULL)
1241 +        {
1242 +            _expressionManager->UpdateMotion(_model, deltaTimeSeconds); // 表情でパラメータ更新(相対変化)
1243 +        }
1244  
1245 -    //ドラッグによる変化
1246 -    //ドラッグによる顔の向きの調整
1247 -    _model->AddParameterValue(_idParamAngleX, _dragX * 30); // -30から30の値を加える
1248 -    _model->AddParameterValue(_idParamAngleY, _dragY * 30);
1249 -    _model->AddParameterValue(_idParamAngleZ, _dragX * _dragY * -30);
1250 +        bool autoBlink = params.autoBlink && _eyeBlink;
1251 +        auto eyeLOpenIt = params.live2d.find("ParamEyeLOpen");
1252 +        auto eyeROpenIt = params.live2d.find("ParamEyeROpen");
1253  
1254 -    //ドラッグによる体の向きの調整
1255 -    _model->AddParameterValue(_idParamBodyAngleX, _dragX * 10); // -10から10の値を加える
1256 +        if (autoBlink)
1257 +        {
1258 +            // Handle blink first
1259 +            _eyeBlink->UpdateParameters(_model, deltaTimeSeconds);
1260 +        }
1261  
1262 -    //ドラッグによる目の向きの調整
1263 -    _model->AddParameterValue(_idParamEyeBallX, _dragX); // -1から1の値を加える
1264 -    _model->AddParameterValue(_idParamEyeBallY, _dragY);
1265 +        if (eyeLOpenIt != params.live2d.end())
1266 +        {
1267 +            // If value specified, override blinking
1268 +            _model->SetParameterValue(idMan->GetId(_("ParamEyeLOpen")),
1269 +                                      eyeLOpenIt->second);
1270 +        }
1271 +        else if (!autoBlink)
1272 +        {
1273 +            // If no value specified and no auto blink, set to 1
1274 +            _model->SetParameterValue(idMan->GetId(_("ParamEyeLOpen")), 1);
1275  
1276 -    // 呼吸など
1277 -    if (_breath != NULL)
1278 -    {
1279 -        _breath->UpdateParameters(_model, deltaTimeSeconds);
1280 -    }
1281 +        }
1282  
1283 -    // 物理演算の設定
1284 -    if (_physics != NULL)
1285 -    {
1286 -        _physics->Evaluate(_model, deltaTimeSeconds);
1287 -    }
1288 +        if (eyeROpenIt != params.live2d.end())
1289 +        {
1290 +            _model->SetParameterValue(idMan->GetId(_("ParamEyeROpen")),
1291 +                                      eyeROpenIt->second);
1292 +        }
1293 +        else if (!autoBlink)
1294 +        {
1295 +            _model->SetParameterValue(idMan->GetId(_("ParamEyeROpen")), 1);
1296 +        }
1297  
1298 -    // リップシンクの設定
1299 -    if (_lipSync)
1300 -    {
1301 -        // リアルタイムでリップシンクを行う場合、システムから音量を取得して0〜1の範囲で値を入力します。
1302 -        csmFloat32 value = 0.0f;
1303  
1304 -        // 状態更新/RMS値取得
1305 -        _wavFileHandler.Update(deltaTimeSeconds);
1306 -        value = _wavFileHandler.GetRms();
1307 +        if (params.useLipSync && _lipSync)
1308 +        {
1309 +            csmFloat32 value = params.lipSyncParam; // 0 to 1
1310 +
1311 +            for (csmUint32 i = 0; i < _lipSyncIds.GetSize(); ++i)
1312 +            {
1313 +                _model->AddParameterValue(_lipSyncIds[i], value, 0.8f);
1314 +            }
1315 +        }
1316 +        else
1317 +        {
1318 +            _model->SetParameterValue(idMan->GetId(_("ParamMouthOpenY")),
1319 +                                      params.live2d["ParamMouthOpenY"]);
1320 +        }
1321  
1322 -        for (csmUint32 i = 0; i < _lipSyncIds.GetSize(); ++i)
1323 +        for (auto const &entry : params.live2d)
1324          {
1325 -            _model->AddParameterValue(_lipSyncIds[i], value, 0.8f);
1326 +            std::string key = entry.first;
1327 +            double val = entry.second;
1328 +
1329 +            if (key != "ParamEyeLOpen" && key != "ParamEyeROpen" &&
1330 +                key != "ParamMouthOpenY")
1331 +            {
1332 +                _model->SetParameterValue(idMan->GetId(_(key)), val);
1333 +            }
1334 +        }
1335 +
1336 +        if (params.autoBreath && _breath)
1337 +        {
1338 +            // Note: _model->LoadParameters and SaveParameters is needed
1339 +            // before - see above.
1340 +            _breath->UpdateParameters(_model, deltaTimeSeconds);
1341          }
1342      }
1343  
1344 +    // 物理演算の設定
1345 +    if (_physics != NULL)
1346 +    {
1347 +        _physics->Evaluate(_model, deltaTimeSeconds);
1348 +    }
1349 +
1350      // ポーズの設定
1351      if (_pose != NULL)
1352      {
1353 @@ -453,7 +472,7 @@ CubismMotionQueueEntryHandle LAppModel::
1354      {
1355          if (_debugMode)
1356          {
1357 -            LAppPal::PrintLogLn("[APP]can't start motion.");
1358 +            LAppPal::PrintLog("[APP]can't start motion.");
1359          }
1360          return InvalidMotionQueueEntryHandleValue;
1361      }
1362 @@ -474,23 +493,19 @@ CubismMotionQueueEntryHandle LAppModel::
1363          csmSizeInt size;
1364          buffer = CreateBuffer(path.GetRawString(), &size);
1365          motion = static_cast<CubismMotion*>(LoadMotion(buffer, size, NULL, onFinishedMotionHandler));
1366 -
1367 -        if (motion)
1368 +        csmFloat32 fadeTime = _modelSetting->GetMotionFadeInTimeValue(group, no);
1369 +        if (fadeTime >= 0.0f)
1370          {
1371 -            csmFloat32 fadeTime = _modelSetting->GetMotionFadeInTimeValue(group, no);
1372 -            if (fadeTime >= 0.0f)
1373 -            {
1374 -                motion->SetFadeInTime(fadeTime);
1375 -            }
1376 +            motion->SetFadeInTime(fadeTime);
1377 +        }
1378  
1379 -            fadeTime = _modelSetting->GetMotionFadeOutTimeValue(group, no);
1380 -            if (fadeTime >= 0.0f)
1381 -            {
1382 -                motion->SetFadeOutTime(fadeTime);
1383 -            }
1384 -            motion->SetEffectIds(_eyeBlinkIds, _lipSyncIds);
1385 -            autoDelete = true; // 終了時にメモリから削除
1386 +        fadeTime = _modelSetting->GetMotionFadeOutTimeValue(group, no);
1387 +        if (fadeTime >= 0.0f)
1388 +        {
1389 +            motion->SetFadeOutTime(fadeTime);
1390          }
1391 +        motion->SetEffectIds(_eyeBlinkIds, _lipSyncIds);
1392 +        autoDelete = true; // 終了時にメモリから削除
1393  
1394          DeleteBuffer(buffer, path.GetRawString());
1395      }
1396 @@ -505,12 +520,11 @@ CubismMotionQueueEntryHandle LAppModel::
1397      {
1398          csmString path = voice;
1399          path = _modelHomeDir + path;
1400 -        _wavFileHandler.Start(path);
1401      }
1402  
1403      if (_debugMode)
1404      {
1405 -        LAppPal::PrintLogLn("[APP]start motion: [%s_%d]", group, no);
1406 +        LAppPal::PrintLog("[APP]start motion: [%s_%d]", group, no);
1407      }
1408      return  _motionManager->StartMotionPriority(motion, autoDelete, priority);
1409  }
1410 @@ -575,7 +589,7 @@ void LAppModel::SetExpression(const csmC
1411      ACubismMotion* motion = _expressions[expressionID];
1412      if (_debugMode)
1413      {
1414 -        LAppPal::PrintLogLn("[APP]expression: [%s]", expressionID);
1415 +        LAppPal::PrintLog("[APP]expression: [%s]", expressionID);
1416      }
1417  
1418      if (motion != NULL)
1419 @@ -584,7 +598,7 @@ void LAppModel::SetExpression(const csmC
1420      }
1421      else
1422      {
1423 -        if (_debugMode) LAppPal::PrintLogLn("[APP]expression[%s] is null ", expressionID);
1424 +        if (_debugMode) LAppPal::PrintLog("[APP]expression[%s] is null ", expressionID);
1425      }
1426  }
1427  
1428 @@ -657,3 +671,42 @@ Csm::Rendering::CubismOffscreenSurface_O
1429  {
1430      return _renderBuffer;
1431  }
1432 +
1433 +void LAppModel::SetTracker(MouseCursorTracker *tracker)
1434 +{
1435 +    _tracker = tracker;
1436 +}
1437 +
1438 +Csm::ICubismModelSetting* LAppModel::GetModelSetting(void) const
1439 +{
1440 +    return _modelSetting;
1441 +}
1442 +
1443 +Csm::csmString LAppModel::_(std::string s)
1444 +{
1445 +    std::string ans;
1446 +    if (_useOldParamId)
1447 +    {
1448 +        if (s == "ParamTere")
1449 +        {
1450 +            ans = "PARAM_CHEEK";
1451 +        }
1452 +        else
1453 +        {
1454 +            for (size_t i = 0; i < s.size(); i++)
1455 +            {
1456 +                if (std::isupper(s[i]) && i != 0)
1457 +                {
1458 +                    ans += '_';
1459 +                }
1460 +                ans += std::toupper(s[i]);
1461 +            }
1462 +        }
1463 +    }
1464 +    else
1465 +    {
1466 +        ans = s;
1467 +    }
1468 +    return csmString(ans.c_str());
1469 +}
1470 +
1471 diff -pruN --exclude build ./demo_clean/src/LAppModel.hpp ./demo_dev/src/LAppModel.hpp
1472 --- ./demo_clean/src/LAppModel.hpp      2024-03-28 18:39:52.882141826 +0000
1473 +++ ./demo_dev/src/LAppModel.hpp        2024-03-28 18:43:36.385973850 +0000
1474 @@ -13,7 +13,7 @@
1475  #include <Type/csmRectF.hpp>
1476  #include <Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.hpp>
1477  
1478 -#include "LAppWavFileHandler.hpp"
1479 +#include "mouse_cursor_tracker.h"
1480  
1481  /**
1482   * @brief ユーザーが実際に使用するモデルの実装クラス<br>
1483 @@ -25,8 +25,11 @@ class LAppModel : public Csm::CubismUser
1484  public:
1485      /**
1486       * @brief コンストラクタ
1487 +     *
1488 +     * @param[in] useOldParamId : If true, translate new (Cubism 3+)
1489 +     *                            parameter IDs to old (Cubism 2.1)  ones
1490       */
1491 -    LAppModel();
1492 +    LAppModel(bool useOldParamId);
1493  
1494      /**
1495       * @brief デストラクタ
1496 @@ -114,6 +117,15 @@ public:
1497       */
1498      Csm::Rendering::CubismOffscreenSurface_OpenGLES2& GetRenderBuffer();
1499  
1500 +    /**
1501 +     * @brief Set the pointer to the MouseCursorTracker instance
1502 +     *
1503 +     * @param[in] tracker : Pointer to MouseCursorTracker instance
1504 +     */
1505 +    void SetTracker(MouseCursorTracker *tracker);
1506 +
1507 +    Csm::ICubismModelSetting* GetModelSetting(void) const;
1508 +
1509  protected:
1510      /**
1511       *  @brief  モデルを描画する処理。モデルを描画する空間のView-Projection行列を渡す。
1512 @@ -167,6 +179,17 @@ private:
1513      */
1514      void ReleaseExpressions();
1515  
1516 +    /**
1517 +     * @brief Translate new (Cubism 3+) parameter IDs to old (Cubism 2.1) ones
1518 +     *
1519 +     * @param[in] s : New parameter ID
1520 +     *
1521 +     * @return Old parameter ID
1522 +     */
1523 +    Csm::csmString _(std::string s);
1524 +
1525 +    bool _useOldParamId;
1526 +
1527      Csm::ICubismModelSetting* _modelSetting; ///< モデルセッティング情報
1528      Csm::csmString _modelHomeDir; ///< モデルセッティングが置かれたディレクトリ
1529      Csm::csmFloat32 _userTimeSeconds; ///< デルタ時間の積算値[秒]
1530 @@ -183,7 +206,10 @@ private:
1531      const Csm::CubismId* _idParamEyeBallX; ///< パラメータID: ParamEyeBallX
1532      const Csm::CubismId* _idParamEyeBallY; ///< パラメータID: ParamEyeBallXY
1533  
1534 -    LAppWavFileHandler _wavFileHandler; ///< wavファイルハンドラ
1535 -
1536      Csm::Rendering::CubismOffscreenSurface_OpenGLES2 _renderBuffer;   ///< フレームバッファ以外の描画先
1537 +
1538 +    MouseCursorTracker *_tracker;
1539  };
1540 +
1541 +
1542 +
1543 diff -pruN --exclude build ./demo_clean/src/LAppPal.cpp ./demo_dev/src/LAppPal.cpp
1544 --- ./demo_clean/src/LAppPal.cpp        2024-03-28 18:39:52.882141826 +0000
1545 +++ ./demo_dev/src/LAppPal.cpp  2024-03-28 18:43:36.385973850 +0000
1546 @@ -6,6 +6,7 @@
1547   */
1548  
1549  #include "LAppPal.hpp"
1550 +#include <stdexcept>
1551  #include <stdio.h>
1552  #include <stdlib.h>
1553  #include <stdarg.h>
1554 @@ -36,37 +37,17 @@ csmByte* LAppPal::LoadFileAsBytes(const
1555      if (stat(path, &statBuf) == 0)
1556      {
1557          size = statBuf.st_size;
1558 -
1559 -        if (size == 0)
1560 -        {
1561 -            if (DebugLogEnable)
1562 -            {
1563 -                PrintLogLn("Stat succeeded but file size is zero. path:%s", path);
1564 -            }
1565 -            return NULL;
1566 -        }
1567 -    }
1568 -    else
1569 -    {
1570 -        if (DebugLogEnable)
1571 -        {
1572 -            PrintLogLn("Stat failed. errno:%d path:%s", errno, path);
1573 -        }
1574 -        return NULL;
1575      }
1576  
1577      std::fstream file;
1578 +    char* buf = new char[size];
1579 +
1580      file.open(path, std::ios::in | std::ios::binary);
1581      if (!file.is_open())
1582      {
1583 -        if (DebugLogEnable)
1584 -        {
1585 -            PrintLogLn("File open failed. path:%s", path);
1586 -        }
1587 +        throw std::runtime_error("Failed to open file " + filePath);
1588          return NULL;
1589      }
1590 -
1591 -    char* buf = new char[size];
1592      file.read(buf, size);
1593      file.close();
1594  
1595 @@ -97,17 +78,7 @@ void LAppPal::PrintLog(const csmChar* fo
1596      csmChar buf[256];
1597      va_start(args, format);
1598      vsnprintf(buf, sizeof(buf), format, args); // 標準出力でレンダリング
1599 -    std::cout << buf;
1600 -    va_end(args);
1601 -}
1602 -
1603 -void LAppPal::PrintLogLn(const csmChar* format, ...)
1604 -{
1605 -    va_list args;
1606 -    csmChar buf[256];
1607 -    va_start(args, format);
1608 -    vsnprintf(buf, sizeof(buf), format, args); // 標準出力でレンダリング
1609 -    std::cout << buf << std::endl;
1610 +    std::cerr << buf << std::endl;
1611      va_end(args);
1612  }
1613  
1614 @@ -115,8 +86,3 @@ void LAppPal::PrintMessage(const csmChar
1615  {
1616      PrintLog("%s", message);
1617  }
1618 -
1619 -void LAppPal::PrintMessageLn(const csmChar* message)
1620 -{
1621 -    PrintLogLn("%s", message);
1622 -}
1623 diff -pruN --exclude build ./demo_clean/src/LAppPal.hpp ./demo_dev/src/LAppPal.hpp
1624 --- ./demo_clean/src/LAppPal.hpp        2024-03-28 18:39:52.882141826 +0000
1625 +++ ./demo_dev/src/LAppPal.hpp  2024-03-28 18:43:36.385973850 +0000
1626 @@ -63,17 +63,6 @@ public:
1627      static void PrintLog(const Csm::csmChar* format, ...);
1628  
1629      /**
1630 -    * @brief ログを出力し最後に改行する
1631 -    *
1632 -    * ログを出力し最後に改行する
1633 -    *
1634 -    * @param[in]   format  書式付文字列
1635 -    * @param[in]   ...     (可変長引数)文字列
1636 -    *
1637 -    */
1638 -    static void PrintLogLn(const Csm::csmChar* format, ...);
1639 -
1640 -    /**
1641      * @brief メッセージを出力する
1642      *
1643      * メッセージを出力する
1644 @@ -83,16 +72,6 @@ public:
1645      */
1646      static void PrintMessage(const Csm::csmChar* message);
1647  
1648 -    /**
1649 -    * @brief メッセージを出力し最後に改行する
1650 -    *
1651 -    * メッセージを出力し最後に改行する
1652 -    *
1653 -    * @param[in]   message  文字列
1654 -    *
1655 -    */
1656 -    static void PrintMessageLn(const Csm::csmChar* message);
1657 -
1658  private:
1659      static double s_currentFrame;
1660      static double s_lastFrame;
1661 diff -pruN --exclude build ./demo_clean/src/LAppTextureManager.cpp ./demo_dev/src/LAppTextureManager.cpp
1662 --- ./demo_clean/src/LAppTextureManager.cpp     2024-03-28 18:39:52.882141826 +0000
1663 +++ ./demo_dev/src/LAppTextureManager.cpp       2024-03-28 18:43:36.385973850 +0000
1664 @@ -96,6 +96,46 @@ LAppTextureManager::TextureInfo* LAppTex
1665  
1666  }
1667  
1668 +LAppTextureManager::TextureInfo* LAppTextureManager::CreateTextureFromColor(
1669 +    uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha
1670 +)
1671 +{
1672 +    int width = 8, height = 8;
1673 +
1674 +    uint8_t pixels[height][width][4];
1675 +    for (std::size_t h = 0; h < height; h++)
1676 +    {
1677 +        for (std::size_t w = 0; w < width; w++)
1678 +        {
1679 +            pixels[h][w][0] = red;
1680 +            pixels[h][w][1] = green;
1681 +            pixels[h][w][2] = blue;
1682 +            pixels[h][w][3] = alpha;
1683 +        }
1684 +    }
1685 +
1686 +    GLuint textureId;
1687 +    glGenTextures(1, &textureId);
1688 +    glBindTexture(GL_TEXTURE_2D, textureId);
1689 +    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1690 +
1691 +    glGenerateMipmap(GL_TEXTURE_2D);
1692 +    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
1693 +    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
1694 +    glBindTexture(GL_TEXTURE_2D, 0);
1695 +
1696 +
1697 +    LAppTextureManager::TextureInfo* textureInfo = new LAppTextureManager::TextureInfo();
1698 +    textureInfo->fileName = "";
1699 +    textureInfo->width = width;
1700 +    textureInfo->height = height;
1701 +    textureInfo->id = textureId;
1702 +
1703 +    _textures.PushBack(textureInfo);
1704 +
1705 +    return textureInfo;
1706 +}
1707 +
1708  void LAppTextureManager::ReleaseTextures()
1709  {
1710      for (Csm::csmUint32 i = 0; i < _textures.GetSize(); i++)
1711 diff -pruN --exclude build ./demo_clean/src/LAppTextureManager.hpp ./demo_dev/src/LAppTextureManager.hpp
1712 --- ./demo_clean/src/LAppTextureManager.hpp     2024-03-28 18:39:52.882141826 +0000
1713 +++ ./demo_dev/src/LAppTextureManager.hpp       2024-03-28 18:43:36.385973850 +0000
1714 @@ -72,6 +72,8 @@ public:
1715      */
1716      TextureInfo* CreateTextureFromPngFile(std::string fileName);
1717  
1718 +    TextureInfo *CreateTextureFromColor(uint8_t red, uint8_t green, uint8_t blue, uint8_t alpha = 255);
1719 +
1720      /**
1721      * @brief 画像の解放
1722      *
1723 diff -pruN --exclude build ./demo_clean/src/LAppView.cpp ./demo_dev/src/LAppView.cpp
1724 --- ./demo_clean/src/LAppView.cpp       2024-03-28 18:39:52.882141826 +0000
1725 +++ ./demo_dev/src/LAppView.cpp 2024-03-28 18:44:40.051061624 +0000
1726 @@ -13,7 +13,6 @@
1727  #include "LAppLive2DManager.hpp"
1728  #include "LAppTextureManager.hpp"
1729  #include "LAppDefine.hpp"
1730 -#include "TouchManager.hpp"
1731  #include "LAppSprite.hpp"
1732  #include "LAppModel.hpp"
1733  
1734 @@ -26,8 +25,6 @@ using namespace LAppDefine;
1735  LAppView::LAppView():
1736      _programId(0),
1737      _back(NULL),
1738 -    _gear(NULL),
1739 -    _power(NULL),
1740      _renderSprite(NULL),
1741      _renderTarget(SelectTarget_None)
1742  {
1743 @@ -35,8 +32,6 @@ LAppView::LAppView():
1744      _clearColor[1] = 1.0f;
1745      _clearColor[2] = 1.0f;
1746      _clearColor[3] = 0.0f;
1747 -    // タッチ関係のイベント管理
1748 -    _touchManager = new TouchManager();
1749  
1750      // デバイス座標からスクリーン座標に変換するための
1751      _deviceToScreen = new CubismMatrix44();
1752 @@ -52,10 +47,7 @@ LAppView::~LAppView()
1753  
1754      delete _viewMatrix;
1755      delete _deviceToScreen;
1756 -    delete _touchManager;
1757      delete _back;
1758 -    delete _gear;
1759 -    delete _power;
1760  }
1761  
1762  void LAppView::Initialize()
1763 @@ -107,9 +99,6 @@ void LAppView::Initialize()
1764  void LAppView::Render()
1765  {
1766      _back->Render();
1767 -    _gear->Render();
1768 -    _power->Render();
1769 -
1770  
1771      LAppLive2DManager* Live2DManager = LAppLive2DManager::GetInstance();
1772  
1773 @@ -151,35 +140,17 @@ void LAppView::InitializeSprite()
1774      glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
1775  
1776      LAppTextureManager* textureManager = LAppDelegate::GetInstance()->GetTextureManager();
1777 -    const string resourcesPath = LAppDelegate::GetInstance()->GetExecuteAbsolutePath() + ResourcesPath;
1778  
1779 -    string imageName = BackImageName;
1780 -    LAppTextureManager::TextureInfo* backgroundTexture = textureManager->CreateTextureFromPngFile(resourcesPath + imageName);
1781 +
1782 +    LAppTextureManager::TextureInfo* backgroundTexture =
1783 +        textureManager->CreateTextureFromColor(0, 255, 0);
1784  
1785      float x = width * 0.5f;
1786      float y = height * 0.5f;
1787 -    float fWidth = static_cast<float>(backgroundTexture->width * 2.0f);
1788 -    float fHeight = static_cast<float>(height) * 0.95f;
1789 +    float fWidth = static_cast<float>(width);
1790 +    float fHeight = static_cast<float>(height);
1791      _back = new LAppSprite(x, y, fWidth, fHeight, backgroundTexture->id, _programId);
1792  
1793 -    imageName = GearImageName;
1794 -    LAppTextureManager::TextureInfo* gearTexture = textureManager->CreateTextureFromPngFile(resourcesPath + imageName);
1795 -
1796 -    x = static_cast<float>(width - gearTexture->width * 0.5f);
1797 -    y = static_cast<float>(height - gearTexture->height * 0.5f);
1798 -    fWidth = static_cast<float>(gearTexture->width);
1799 -    fHeight = static_cast<float>(gearTexture->height);
1800 -    _gear = new LAppSprite(x, y, fWidth, fHeight, gearTexture->id, _programId);
1801 -
1802 -    imageName = PowerImageName;
1803 -    LAppTextureManager::TextureInfo* powerTexture = textureManager->CreateTextureFromPngFile(resourcesPath + imageName);
1804 -
1805 -    x = static_cast<float>(width - powerTexture->width * 0.5f);
1806 -    y = static_cast<float>(powerTexture->height * 0.5f);
1807 -    fWidth = static_cast<float>(powerTexture->width);
1808 -    fHeight = static_cast<float>(powerTexture->height);
1809 -    _power = new LAppSprite(x, y, fWidth, fHeight, powerTexture->id, _programId);
1810 -
1811      // 画面全体を覆うサイズ
1812      x = width * 0.5f;
1813      y = height * 0.5f;
1814 @@ -187,52 +158,6 @@ void LAppView::InitializeSprite()
1815  
1816  }
1817  
1818 -void LAppView::OnTouchesBegan(float px, float py) const
1819 -{
1820 -    _touchManager->TouchesBegan(px, py);
1821 -}
1822 -
1823 -void LAppView::OnTouchesMoved(float px, float py) const
1824 -{
1825 -    float viewX = this->TransformViewX(_touchManager->GetX());
1826 -    float viewY = this->TransformViewY(_touchManager->GetY());
1827 -
1828 -    _touchManager->TouchesMoved(px, py);
1829 -
1830 -    LAppLive2DManager* Live2DManager = LAppLive2DManager::GetInstance();
1831 -    Live2DManager->OnDrag(viewX, viewY);
1832 -}
1833 -
1834 -void LAppView::OnTouchesEnded(float px, float py) const
1835 -{
1836 -    // タッチ終了
1837 -    LAppLive2DManager* live2DManager = LAppLive2DManager::GetInstance();
1838 -    live2DManager->OnDrag(0.0f, 0.0f);
1839 -    {
1840 -
1841 -        // シングルタップ
1842 -        float x = _deviceToScreen->TransformX(_touchManager->GetX()); // 論理座標変換した座標を取得。
1843 -        float y = _deviceToScreen->TransformY(_touchManager->GetY()); // 論理座標変換した座標を取得。
1844 -        if (DebugTouchLogEnable)
1845 -        {
1846 -            LAppPal::PrintLogLn("[APP]touchesEnded x:%.2f y:%.2f", x, y);
1847 -        }
1848 -        live2DManager->OnTap(x, y);
1849 -
1850 -        // 歯車にタップしたか
1851 -        if (_gear->IsHit(px, py))
1852 -        {
1853 -            live2DManager->NextScene();
1854 -        }
1855 -
1856 -        // 電源ボタンにタップしたか
1857 -        if (_power->IsHit(px, py))
1858 -        {
1859 -            LAppDelegate::GetInstance()->AppEnd();
1860 -        }
1861 -    }
1862 -}
1863 -
1864  float LAppView::TransformViewX(float deviceX) const
1865  {
1866      float screenX = _deviceToScreen->TransformX(deviceX); // 論理座標変換した座標を取得。
1867 @@ -374,32 +299,4 @@ void LAppView::ResizeSprite()
1868              _back->ResetRect(x, y, fWidth, fHeight);
1869          }
1870      }
1871 -
1872 -    if (_power)
1873 -    {
1874 -        GLuint id = _power->GetTextureId();
1875 -        LAppTextureManager::TextureInfo* texInfo = textureManager->GetTextureInfoById(id);
1876 -        if (texInfo)
1877 -        {
1878 -            x = static_cast<float>(width - texInfo->width * 0.5f);
1879 -            y = static_cast<float>(texInfo->height * 0.5f);
1880 -            fWidth = static_cast<float>(texInfo->width);
1881 -            fHeight = static_cast<float>(texInfo->height);
1882 -            _power->ResetRect(x, y, fWidth, fHeight);
1883 -        }
1884 -    }
1885 -
1886 -    if (_gear)
1887 -    {
1888 -        GLuint id = _gear->GetTextureId();
1889 -        LAppTextureManager::TextureInfo* texInfo = textureManager->GetTextureInfoById(id);
1890 -        if (texInfo)
1891 -        {
1892 -            x = static_cast<float>(width - texInfo->width * 0.5f);
1893 -            y = static_cast<float>(height - texInfo->height * 0.5f);
1894 -            fWidth = static_cast<float>(texInfo->width);
1895 -            fHeight = static_cast<float>(texInfo->height);
1896 -            _gear->ResetRect(x, y, fWidth, fHeight);
1897 -        }
1898 -    }
1899  }
1900 diff -pruN --exclude build ./demo_clean/src/LAppView.hpp ./demo_dev/src/LAppView.hpp
1901 --- ./demo_clean/src/LAppView.hpp       2024-03-28 18:39:52.882141826 +0000
1902 +++ ./demo_dev/src/LAppView.hpp 2024-03-28 18:43:36.385973850 +0000
1903 @@ -14,7 +14,6 @@
1904  #include "CubismFramework.hpp"
1905  #include <Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.hpp>
1906  
1907 -class TouchManager;
1908  class LAppSprite;
1909  class LAppModel;
1910  
1911 @@ -66,30 +65,6 @@ public:
1912      void ResizeSprite();
1913  
1914      /**
1915 -    * @brief タッチされたときに呼ばれる。
1916 -    *
1917 -    * @param[in]       pointX            スクリーンX座標
1918 -    * @param[in]       pointY            スクリーンY座標
1919 -    */
1920 -    void OnTouchesBegan(float pointX, float pointY) const;
1921 -
1922 -    /**
1923 -    * @brief タッチしているときにポインタが動いたら呼ばれる。
1924 -    *
1925 -    * @param[in]       pointX            スクリーンX座標
1926 -    * @param[in]       pointY            スクリーンY座標
1927 -    */
1928 -    void OnTouchesMoved(float pointX, float pointY) const;
1929 -
1930 -    /**
1931 -    * @brief タッチが終了したら呼ばれる。
1932 -    *
1933 -    * @param[in]       pointX            スクリーンX座標
1934 -    * @param[in]       pointY            スクリーンY座標
1935 -    */
1936 -    void OnTouchesEnded(float pointX, float pointY) const;
1937 -
1938 -    /**
1939      * @brief X座標をView座標に変換する。
1940      *
1941      * @param[in]       deviceX            デバイスX座標
1942 @@ -147,13 +122,10 @@ public:
1943      void SetRenderTargetClearColor(float r, float g, float b);
1944  
1945  private:
1946 -    TouchManager* _touchManager;                 ///< タッチマネージャー
1947      Csm::CubismMatrix44* _deviceToScreen;    ///< デバイスからスクリーンへの行列
1948      Csm::CubismViewMatrix* _viewMatrix;      ///< viewMatrix
1949      GLuint _programId;                       ///< シェーダID
1950      LAppSprite* _back;                       ///< 背景画像
1951 -    LAppSprite* _gear;                       ///< ギア画像
1952 -    LAppSprite* _power;                      ///< 電源画像
1953  
1954      // レンダリング先を別ターゲットにする方式の場合に使用
1955      LAppSprite* _renderSprite;                                  ///< モードによっては_renderBufferのテクスチャを描画
1956 diff -pruN --exclude build ./demo_clean/src/main.cpp ./demo_dev/src/main.cpp
1957 --- ./demo_clean/src/main.cpp   2024-03-28 18:39:52.882141826 +0000
1958 +++ ./demo_dev/src/main.cpp     2024-03-28 18:43:36.389973918 +0000
1959 @@ -5,18 +5,188 @@
1960   * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
1961   */
1962  
1963 +#include <thread>
1964 +#include <stdexcept>
1965 +#include <sstream>
1966 +#include <vector>
1967 +#include <utility>
1968 +#include <string>
1969 +
1970 +#ifdef __cpp_lib_filesystem
1971 +#include <filesystem>
1972 +namespace fs = std::filesystem;
1973 +#else
1974 +#include <experimental/filesystem>
1975 +namespace fs = std::experimental::filesystem;
1976 +#endif
1977 +
1978 +#include "ICubismModelSetting.hpp"
1979  #include "LAppDelegate.hpp"
1980 +#include "LAppLive2DManager.hpp"
1981 +#include "LAppModel.hpp"
1982 +#include "mouse_cursor_tracker.h"
1983 +
1984 +struct CmdArgs
1985 +{
1986 +    int windowWidth;
1987 +    int windowHeight;
1988 +    std::string windowTitle;
1989 +    std::string rootDir;
1990 +    float scaleFactor;
1991 +    float translateX;
1992 +    float translateY;
1993 +    std::string modelName;
1994 +    bool oldId; // If true, translate new (Cubism 3+) parameter IDs to old (Cubism 2.1) IDs
1995 +    std::string cfgPath; // Path to config file for MouseCursorTracker
1996 +};
1997 +
1998 +CmdArgs parseArgv(int argc, char *argv[])
1999 +{
2000 +    // I think the command-line args are simple enough to not justify using a library...
2001 +    CmdArgs cmdArgs;
2002 +    // Set default values
2003 +    cmdArgs.windowWidth = 600;
2004 +    cmdArgs.windowHeight = 600;
2005 +    cmdArgs.windowTitle = "MouseTrackerForCubism example";
2006 +    cmdArgs.rootDir = fs::current_path();
2007 +    cmdArgs.scaleFactor = 4.5f;
2008 +    cmdArgs.translateX = 0.0f;
2009 +    cmdArgs.translateY = -3.1f;
2010 +    cmdArgs.modelName = "Haru";
2011 +    cmdArgs.oldId = false;
2012 +    cmdArgs.cfgPath = "";
2013 +
2014 +    int i = 1;
2015 +    while (i < argc)
2016 +    {
2017 +        std::string arg = argv[i];
2018 +        std::stringstream ss;
2019 +
2020 +        if (arg == "--window-width" || arg == "-W") // capital W for consistency with height
2021 +        {
2022 +            ss << argv[i + 1];
2023 +            if (!(ss >> cmdArgs.windowWidth))
2024 +            {
2025 +                throw std::runtime_error("Invalid argument for window width");
2026 +            }
2027 +        }
2028 +        else if (arg == "--window-height" || arg == "-H") // avoiding "-h", typically for help
2029 +        {
2030 +            ss << argv[i + 1];
2031 +            if (!(ss >> cmdArgs.windowHeight))
2032 +            {
2033 +                throw std::runtime_error("Invalid argument for window height");
2034 +            }
2035 +        }
2036 +        else if (arg == "--window-title" || arg == "-t")
2037 +        {
2038 +            cmdArgs.windowTitle = argv[i + 1];
2039 +        }
2040 +        else if (arg == "--root-dir" || arg == "-d")
2041 +        {
2042 +            cmdArgs.rootDir = argv[i + 1];
2043 +        }
2044 +        else if (arg == "--scale-factor" || arg == "-f")
2045 +        {
2046 +            ss << argv[i + 1];
2047 +            if (!(ss >> cmdArgs.scaleFactor))
2048 +            {
2049 +                throw std::runtime_error("Invalid argument for scale factor");
2050 +            }
2051 +        }
2052 +        else if (arg == "--translate-x" || arg == "-x")
2053 +        {
2054 +            ss << argv[i + 1];
2055 +            if (!(ss >> cmdArgs.translateX))
2056 +            {
2057 +                throw std::runtime_error("Invalid argument for translate X");
2058 +            }
2059 +        }
2060 +        else if (arg == "--translate-y" || arg == "-y")
2061 +        {
2062 +            ss << argv[i + 1];
2063 +            if (!(ss >> cmdArgs.translateY))
2064 +            {
2065 +                throw std::runtime_error("Invalid argument for translate Y");
2066 +            }
2067 +        }
2068 +        else if (arg == "--model" || arg == "-m")
2069 +        {
2070 +            cmdArgs.modelName = argv[i + 1];
2071 +        }
2072 +        else if (arg == "--config" || arg == "-c")
2073 +        {
2074 +            cmdArgs.cfgPath = argv[i + 1];
2075 +        }
2076 +        else if (arg == "--old-param-id" || arg == "-o")
2077 +        {
2078 +            cmdArgs.oldId = (argv[i + 1][0] == '1');
2079 +        }
2080 +        else
2081 +        {
2082 +            throw std::runtime_error("Unrecognized argument: " + arg);
2083 +        }
2084 +
2085 +        i += 2;
2086 +    }
2087 +
2088 +    return cmdArgs;
2089 +}
2090  
2091  int main(int argc, char* argv[])
2092  {
2093 -    // create the application instance
2094 -    if (LAppDelegate::GetInstance()->Initialize() == GL_FALSE)
2095 +    auto cmdArgs = parseArgv(argc, argv);
2096 +
2097 +    LAppDelegate *delegate = LAppDelegate::GetInstance();
2098 +
2099 +    if (!delegate->Initialize(cmdArgs.windowWidth,
2100 +                              cmdArgs.windowHeight,
2101 +                              cmdArgs.windowTitle.c_str()))
2102      {
2103 -        return 1;
2104 +        throw std::runtime_error("Unable to initialize LAppDelegate");
2105      }
2106  
2107 -    LAppDelegate::GetInstance()->Run();
2108 +    delegate->SetRootDirectory(cmdArgs.rootDir);
2109 +
2110 +    LAppLive2DManager *manager = LAppLive2DManager::GetInstance();
2111 +    manager->SetModel(cmdArgs.modelName, cmdArgs.oldId);
2112 +
2113 +    manager->SetProjectionScaleTranslate(cmdArgs.scaleFactor,
2114 +                                         cmdArgs.translateX,
2115 +                                         cmdArgs.translateY);
2116 +
2117 +    LAppModel *model = manager->GetModel(0);
2118 +    if (!model) throw std::runtime_error("model is null");
2119 +
2120 +    Live2D::Cubism::Framework::ICubismModelSetting *modelSetting = model->GetModelSetting();
2121 +    if (!modelSetting) throw std::runtime_error("modelSetting is null");
2122 +
2123 +    std::vector<std::pair<std::string, int> > motions;
2124 +    int motionGroupCount = modelSetting->GetMotionGroupCount();
2125 +    for (int i = 0; i < motionGroupCount; i++)
2126 +    {
2127 +        const char *motionGroup = modelSetting->GetMotionGroupName(i);
2128 +        int motionCount = modelSetting->GetMotionCount(motionGroup);
2129 +        motions.push_back(std::make_pair(std::string(motionGroup), motionCount));
2130 +    }
2131 +
2132 +    std::vector<std::string> expressions;
2133 +    int expCount = modelSetting->GetExpressionCount();
2134 +    for (int i = 0; i < expCount; i++)
2135 +    {
2136 +        const char *expName = modelSetting->GetExpressionName(i);
2137 +        expressions.push_back(std::string(expName));
2138 +    }
2139 +
2140 +    MouseCursorTracker tracker(cmdArgs.cfgPath, motions, expressions);
2141 +
2142 +    std::thread trackerThread(&MouseCursorTracker::mainLoop, &tracker);
2143 +    manager->SetTracker(&tracker);
2144 +
2145 +    delegate->Run();
2146 +
2147 +    tracker.stop();
2148 +    trackerThread.join();
2149  
2150      return 0;
2151  }
2152 -
2153 diff -pruN --exclude build ./demo_clean/src/mainMinimum.cpp ./demo_dev/src/mainMinimum.cpp
2154 --- ./demo_clean/src/mainMinimum.cpp    2024-03-28 18:39:52.882141826 +0000
2155 +++ ./demo_dev/src/mainMinimum.cpp      2024-03-28 18:43:36.389973918 +0000
2156 @@ -9,7 +9,6 @@
2157  
2158  #include <sstream>
2159  #include <unistd.h>
2160 -#include <libgen.h>
2161  #include <GL/glew.h>
2162  #include <GLFW/glfw3.h>
2163  
2164 @@ -62,7 +61,7 @@ static LAppAllocator _cubismAllocator; /
2165  
2166  static LAppTextureManager* _textureManager; ///< テクスチャの管理
2167  
2168 -static std::string _executeAbsolutePath; ///< アプリケーションの実行パス
2169 +static std::string _rootDirectory; ///< ルートディレクトリ
2170  static std::string _currentModelDirectory; ///< 現在のモデルのディレクトリ名
2171  
2172  static GLFWwindow* _window; ///< ウィンドウオブジェクト
2173 @@ -86,11 +85,33 @@ static void InitializeCubism()
2174  }
2175  
2176  /**
2177 -* @brief アプリケーションの実行パスの設定
2178 +* @brief 文字列の分割
2179  *
2180 -* Linuxのアプリケーションの実行パスを確認し、パスを取得する
2181 +* 指定された区切り文字で文字列を分割する
2182  */
2183 -void SetExecuteAbsolutePath()
2184 +Csm::csmVector<std::string> Split(const std::string& baseString, char delimiter)
2185 +{
2186 +    Csm::csmVector < std::string > elems;
2187 +    std::stringstream ss(baseString);
2188 +    std::string item;
2189 +
2190 +    while (getline(ss, item, delimiter))
2191 +    {
2192 +        if (!item.empty())
2193 +        {
2194 +            elems.PushBack(item);
2195 +        }
2196 +    }
2197 +
2198 +    return elems;
2199 +}
2200 +
2201 +/**
2202 +* @brief ルートディレクトリの設定
2203 +*
2204 +* Linuxのルートディレクトリを確認し、パスを取得する
2205 +*/
2206 +void SetRootDirectory()
2207  {
2208      const int maximumPathBufferSize = 1024;
2209      char path[maximumPathBufferSize];
2210 @@ -101,8 +122,19 @@ void SetExecuteAbsolutePath()
2211          path[len] = '\0';
2212      }
2213  
2214 -    _executeAbsolutePath = dirname(path);
2215 -    _executeAbsolutePath += "/";
2216 +    std::string pathString(path);
2217 +
2218 +    pathString = pathString.substr(0, pathString.rfind("Demo"));
2219 +    Csm::csmVector<std::string> splitStrings = Split(pathString, '/');
2220 +
2221 +    _rootDirectory = "";
2222 +
2223 +    for (int i = 0; i < splitStrings.GetSize(); i++)
2224 +    {
2225 +        _rootDirectory += "/" + splitStrings[i];
2226 +    }
2227 +
2228 +    _rootDirectory += "/";
2229  }
2230  
2231  /**
2232 @@ -112,12 +144,12 @@ void SetExecuteAbsolutePath()
2233  */
2234  static bool InitializeSystem()
2235  {
2236 -    LAppPal::PrintLogLn("START");
2237 +    LAppPal::PrintLog("START");
2238  
2239      // GLFWの初期化
2240      if (glfwInit() == GL_FALSE)
2241      {
2242 -        LAppPal::PrintLogLn("Can't initilize GLFW");
2243 +        LAppPal::PrintLog("Can't initilize GLFW");
2244  
2245          return GL_FALSE;
2246      }
2247 @@ -126,7 +158,7 @@ static bool InitializeSystem()
2248      _window = glfwCreateWindow(LAppDefine::RenderTargetWidth, LAppDefine::RenderTargetHeight, "SIMPLE_SAMPLE", NULL, NULL);
2249      if (_window == NULL)
2250      {
2251 -        LAppPal::PrintLogLn("Can't create GLFW window.");
2252 +        LAppPal::PrintLog("Can't create GLFW window.");
2253  
2254          glfwTerminate();
2255          return GL_FALSE;
2256 @@ -137,7 +169,7 @@ static bool InitializeSystem()
2257      glfwSwapInterval(1);
2258  
2259      if (glewInit() != GLEW_OK) {
2260 -        LAppPal::PrintLogLn("Can't initilize glew.");
2261 +        LAppPal::PrintLog("Can't initilize glew.");
2262  
2263          glfwTerminate();
2264          return GL_FALSE;
2265 @@ -165,7 +197,7 @@ static bool InitializeSystem()
2266      // ドラッグ入力管理クラスの初期化
2267      MouseActionManager::GetInstance()->Initialize(windowWidth, windowHeight);
2268  
2269 -    SetExecuteAbsolutePath();
2270 +    SetRootDirectory();
2271  
2272      return GL_TRUE;
2273  }
2274 @@ -209,7 +241,7 @@ void Release()
2275  void LoadModel(const std::string modelDirectoryName)
2276  {
2277      // モデルのディレクトリを指定
2278 -    _currentModelDirectory = _executeAbsolutePath + LAppDefine::ResourcesPath + modelDirectoryName + "/";
2279 +    _currentModelDirectory = _rootDirectory + LAppDefine::ResourcesPath + modelDirectoryName + "/";
2280  
2281      // モデルデータの新規生成
2282      _userModel = new CubismUserModelExtend(modelDirectoryName, _currentModelDirectory);