Upgrade to Cubism 5 Release R1. master
authorAdrian Iain Lam <adrianiainlam@users.noreply.github.com>
Thu, 28 Mar 2024 18:52:53 +0000 (18:52 +0000)
committerAdrian Iain Lam <adrianiainlam@users.noreply.github.com>
Thu, 28 Mar 2024 18:52:53 +0000 (18:52 +0000)
.gitignore
README.md
example/build.sh
example/demo.patch
example/generate_patch.sh

index 6243a90..8a7d187 100644 (file)
@@ -1,5 +1,5 @@
 build
-example/CubismSdkForNative-4-r.*/
+example/CubismSdkForNative-*-r.*/
 example/demo_build/
 example/demo_clean/
 example/demo_dev/
index 067fe9f..9edea2a 100644 (file)
--- a/README.md
+++ b/README.md
@@ -50,17 +50,17 @@ if you don't have C++17 support.
 
 To build the example program:
 
-4. Download "Cubism 4 SDK for Native R7" from the Live2D website:
+4. Download "Cubism 5 SDK for Native R1" from the Live2D website:
    <https://www.live2d.com/en/download/cubism-sdk/download-native/>.
 
-   Extract the archive -- put the "CubismSdkForNative-4-r.7" folder under
+   Extract the archive -- put the "CubismSdkForNative-5-r.1" folder under
    the "example" folder of this repo.
 
    Note: The Cubism SDK is the property of Live2D and is not part of this
    project. You must agree to Live2D's license agreements to use it.
 
 5. Go into the
-   "example/CubismSdkForNative-4-r.7/Samples/OpenGL/thirdParty/scripts"
+   "example/CubismSdkForNative-5-r.1/Samples/OpenGL/thirdParty/scripts"
    directory and run
 
        ./setup_glew_glfw
index a674883..2c950b1 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh -e
 
 mkdir -p demo_build
-cp -r CubismSdkForNative-4-r.7/Samples/OpenGL/Demo/proj.linux.cmake/* ./demo_build/
+cp -r CubismSdkForNative-5-r.1/Samples/OpenGL/Demo/proj.linux.cmake/* ./demo_build/
 patch -d demo_build -p2 < demo.patch
 ./demo_build/scripts/make_gcc
index d519a12..4d01e49 100644 (file)
@@ -1,12 +1,12 @@
 diff -pruN --exclude build ./demo_clean/CMakeLists.txt ./demo_dev/CMakeLists.txt
---- ./demo_clean/CMakeLists.txt        2023-05-18 09:58:50.000000000 +0100
-+++ ./demo_dev/CMakeLists.txt  2023-05-28 09:11:29.467788463 +0100
+--- ./demo_clean/CMakeLists.txt        2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/CMakeLists.txt  2024-03-28 18:42:19.248653862 +0000
 @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.16)
  # Set app name.
  set(APP_NAME Demo)
  # Set directory paths.
 -set(SDK_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../../../..)
-+set(SDK_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../CubismSdkForNative-4-r.7)
++set(SDK_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../CubismSdkForNative-5-r.1)
  set(CORE_PATH ${SDK_ROOT_PATH}/Core)
  set(FRAMEWORK_PATH ${SDK_ROOT_PATH}/Framework)
  set(THIRD_PARTY_PATH ${SDK_ROOT_PATH}/Samples/OpenGL/thirdParty)
@@ -54,9 +54,9 @@ diff -pruN --exclude build ./demo_clean/CMakeLists.txt ./demo_dev/CMakeLists.txt
  # Copy resource directory to build directory.
  add_custom_command(
 diff -pruN --exclude build ./demo_clean/scripts/make_gcc ./demo_dev/scripts/make_gcc
---- ./demo_clean/scripts/make_gcc      2023-05-18 09:58:50.000000000 +0100
+--- ./demo_clean/scripts/make_gcc      2024-03-28 18:39:52.882141826 +0000
 +++ ./demo_dev/scripts/make_gcc        2023-05-28 09:11:29.467788463 +0100
-@@ -5,41 +5,9 @@ set -ue
+@@ -5,42 +5,9 @@ set -ue
  SCRIPT_PATH=$(cd $(dirname $0) && pwd)
  CMAKE_PATH=$SCRIPT_PATH/..
  BUILD_PATH=$SCRIPT_PATH/../build/make_gcc
@@ -96,13 +96,14 @@ diff -pruN --exclude build ./demo_clean/scripts/make_gcc ./demo_dev/scripts/make
  cmake -S "$CMAKE_PATH" \
    -B "$BUILD_PATH" \
 -  -D CMAKE_BUILD_TYPE=Release \
--  -D CSM_MINIMUM_DEMO=$MINIMUM_DEMO
+-  -D CSM_MINIMUM_DEMO=$MINIMUM_DEMO \
+-  -D GLFW_BUILD_WAYLAND=OFF
 -cd "$BUILD_PATH" && make
 +  -D CMAKE_BUILD_TYPE=Release
 +cd "$BUILD_PATH" && make -j4
 diff -pruN --exclude build ./demo_clean/src/CMakeLists.txt ./demo_dev/src/CMakeLists.txt
---- ./demo_clean/src/CMakeLists.txt    2023-05-18 09:58:50.000000000 +0100
-+++ ./demo_dev/src/CMakeLists.txt      2023-05-28 09:11:29.471788536 +0100
+--- ./demo_clean/src/CMakeLists.txt    2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/src/CMakeLists.txt      2024-03-28 18:43:36.369973576 +0000
 @@ -1,49 +1,22 @@
 -if (CSM_MINIMUM_DEMO)
 -  target_sources(${APP_NAME}
@@ -166,10 +167,134 @@ diff -pruN --exclude build ./demo_clean/src/CMakeLists.txt ./demo_dev/src/CMakeL
 +    ${CMAKE_CURRENT_SOURCE_DIR}/LAppView.hpp
 +    ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp
 +)
+diff -pruN --exclude build ./demo_clean/src/CubismUserModelExtend.cpp ./demo_dev/src/CubismUserModelExtend.cpp
+--- ./demo_clean/src/CubismUserModelExtend.cpp 2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/src/CubismUserModelExtend.cpp   2024-03-28 18:43:36.373973644 +0000
+@@ -119,15 +119,12 @@ void CubismUserModelExtend::SetupModel()
+             buffer = CreateBuffer(path.GetRawString(), &size);
+             ACubismMotion* motion = LoadExpression(buffer, size, name.GetRawString());
+-            if (motion)
++            if (_expressions[name])
+             {
+-                if (_expressions[name])
+-                {
+-                    ACubismMotion::Delete(_expressions[name]);
+-                    _expressions[name] = nullptr;
+-                }
+-                _expressions[name] = motion;
++                ACubismMotion::Delete(_expressions[name]);
++                _expressions[name] = nullptr;
+             }
++            _expressions[name] = motion;
+             DeleteBuffer(buffer, path.GetRawString());
+         }
+@@ -213,29 +210,26 @@ void CubismUserModelExtend::PreloadMotio
+         // モーションデータの読み込み
+         CubismMotion* tmpMotion = static_cast<CubismMotion*>(LoadMotion(buffer, size, name.GetRawString()));
+-        if (tmpMotion)
++        // フェードインの時間を取得
++        csmFloat32 fadeTime = _modelJson->GetMotionFadeInTimeValue(group, i);
++        if (fadeTime >= 0.0f)
+         {
+-            // フェードインの時間を取得
+-            csmFloat32 fadeTime = _modelJson->GetMotionFadeInTimeValue(group, i);
+-            if (fadeTime >= 0.0f)
+-            {
+-                tmpMotion->SetFadeInTime(fadeTime);
+-            }
++            tmpMotion->SetFadeInTime(fadeTime);
++        }
+-            // フェードアウトの時間を取得
+-            fadeTime = _modelJson->GetMotionFadeOutTimeValue(group, i);
+-            if (fadeTime >= 0.0f)
+-            {
+-                tmpMotion->SetFadeOutTime(fadeTime);
+-            }
++        // フェードアウトの時間を取得
++        fadeTime = _modelJson->GetMotionFadeOutTimeValue(group, i);
++        if (fadeTime >= 0.0f)
++        {
++            tmpMotion->SetFadeOutTime(fadeTime);
++        }
+-            if (_motions[name])
+-            {
+-                // インスタンスを破棄
+-                ACubismMotion::Delete(_motions[name]);
+-            }
+-            _motions[name] = tmpMotion;
++        if (_motions[name])
++        {
++            // インスタンスを破棄
++            ACubismMotion::Delete(_motions[name]);
+         }
++        _motions[name] = tmpMotion;
+         DeleteBuffer(buffer, path.GetRawString());
+     }
+@@ -309,24 +303,21 @@ Csm::CubismMotionQueueEntryHandle Cubism
+         // 一番先頭のモーションを読み込む
+         motion = static_cast<CubismMotion*>(LoadMotion(buffer, size, NULL, onFinishedMotionHandler));
+-        if (motion)
++        csmFloat32 fadeTime = _modelJson->GetMotionFadeInTimeValue(group, no);
++        if (fadeTime >= 0.0f)
+         {
+-            csmFloat32 fadeTime = _modelJson->GetMotionFadeInTimeValue(group, no);
+-            if (fadeTime >= 0.0f)
+-            {
+-                motion->SetFadeInTime(fadeTime);
+-            }
+-
+-            fadeTime = _modelJson->GetMotionFadeOutTimeValue(group, no);
+-            if (fadeTime >= 0.0f)
+-            {
+-                motion->SetFadeOutTime(fadeTime);
+-            }
++            motion->SetFadeInTime(fadeTime);
++        }
+-            // 終了時にメモリから削除
+-            autoDelete = true;
++        fadeTime = _modelJson->GetMotionFadeOutTimeValue(group, no);
++        if (fadeTime >= 0.0f)
++        {
++            motion->SetFadeOutTime(fadeTime);
+         }
++        // 終了時にメモリから削除
++        autoDelete = true;
++
+         DeleteBuffer(buffer, path.GetRawString());
+     }
+     else
 diff -pruN --exclude build ./demo_clean/src/LAppDefine.cpp ./demo_dev/src/LAppDefine.cpp
---- ./demo_clean/src/LAppDefine.cpp    2023-05-18 09:58:50.000000000 +0100
-+++ ./demo_dev/src/LAppDefine.cpp      2023-05-28 09:11:29.471788536 +0100
-@@ -65,11 +65,11 @@ namespace LAppDefine {
+--- ./demo_clean/src/LAppDefine.cpp    2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/src/LAppDefine.cpp      2024-03-28 18:43:36.377973713 +0000
+@@ -38,6 +38,18 @@ namespace LAppDefine {
+     const csmChar* PowerImageName = "close.png";
+     // モデル定義------------------------------------------
++    // モデルを配置したディレクトリ名の配列
++    // ディレクトリ名とmodel3.jsonの名前を一致させておくこと
++    const csmChar* ModelDir[] = {
++        "Haru",
++        "Hiyori",
++        "Mark",
++        "Natori",
++        "Rice",
++        "Mao"
++    };
++    const csmInt32 ModelDirSize = sizeof(ModelDir) / sizeof(const csmChar*);
++
+     // 外部定義ファイル(json)と合わせる
+     const csmChar* MotionGroupIdle = "Idle"; // アイドリング
+     const csmChar* MotionGroupTapBody = "TapBody"; // 体をタップしたとき
+@@ -53,11 +65,11 @@ namespace LAppDefine {
      const csmInt32 PriorityForce = 3;
  
      // デバッグ用ログの表示オプション
@@ -183,10 +308,31 @@ diff -pruN --exclude build ./demo_clean/src/LAppDefine.cpp ./demo_dev/src/LAppDe
  
      // デフォルトのレンダーターゲットサイズ
      const csmInt32 RenderTargetWidth = 1900;
+diff -pruN --exclude build ./demo_clean/src/LAppDefine.hpp ./demo_dev/src/LAppDefine.hpp
+--- ./demo_clean/src/LAppDefine.hpp    2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/src/LAppDefine.hpp      2024-03-28 18:43:36.377973713 +0000
+@@ -37,6 +37,9 @@ namespace LAppDefine {
+     extern const csmChar* PowerImageName;        ///< 終了ボタン画像ファイル
+     // モデル定義--------------------------------------------
++    extern const csmChar* ModelDir[];               ///< モデルを配置したディレクトリ名の配列. ディレクトリ名とmodel3.jsonの名前を一致させておく.
++    extern const csmInt32 ModelDirSize;             ///< モデルディレクトリ配列のサイズ
++
+                                                     // 外部定義ファイル(json)と合わせる
+     extern const csmChar* MotionGroupIdle;          ///< アイドリング時に再生するモーションのリスト
+     extern const csmChar* MotionGroupTapBody;       ///< 体をタップした時に再生するモーションのリスト
 diff -pruN --exclude build ./demo_clean/src/LAppDelegate.cpp ./demo_dev/src/LAppDelegate.cpp
---- ./demo_clean/src/LAppDelegate.cpp  2023-05-18 09:58:50.000000000 +0100
-+++ ./demo_dev/src/LAppDelegate.cpp    2023-05-28 09:11:29.471788536 +0100
-@@ -45,7 +45,8 @@ void LAppDelegate::ReleaseInstance()
+--- ./demo_clean/src/LAppDelegate.cpp  2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/src/LAppDelegate.cpp    2024-03-28 18:43:36.381973781 +0000
+@@ -9,7 +9,6 @@
+ #include <iostream>
+ #include <sstream>
+ #include <unistd.h>
+-#include <libgen.h>
+ #include <GL/glew.h>
+ #include <GLFW/glfw3.h>
+ #include "LAppView.hpp"
+@@ -46,11 +45,12 @@ void LAppDelegate::ReleaseInstance()
      s_instance = NULL;
  }
  
@@ -196,7 +342,19 @@ diff -pruN --exclude build ./demo_clean/src/LAppDelegate.cpp ./demo_dev/src/LApp
  {
      if (DebugLogEnable)
      {
-@@ -63,7 +64,13 @@ bool LAppDelegate::Initialize()
+-        LAppPal::PrintLogLn("START");
++        LAppPal::PrintLog("START");
+     }
+     // GLFWの初期化
+@@ -58,18 +58,24 @@ bool LAppDelegate::Initialize()
+     {
+         if (DebugLogEnable)
+         {
+-            LAppPal::PrintLogLn("Can't initilize GLFW");
++            LAppPal::PrintLog("Can't initilize GLFW");
+         }
+         return GL_FALSE;
      }
  
      // Windowの生成_
@@ -211,7 +369,22 @@ diff -pruN --exclude build ./demo_clean/src/LAppDelegate.cpp ./demo_dev/src/LApp
      if (_window == NULL)
      {
          if (DebugLogEnable)
-@@ -95,16 +102,11 @@ bool LAppDelegate::Initialize()
+         {
+-            LAppPal::PrintLogLn("Can't create GLFW window.");
++            LAppPal::PrintLog("Can't create GLFW window.");
+         }
+         glfwTerminate();
+         return GL_FALSE;
+@@ -82,7 +88,7 @@ bool LAppDelegate::Initialize()
+     if (glewInit() != GLEW_OK) {
+         if (DebugLogEnable)
+         {
+-            LAppPal::PrintLogLn("Can't initilize glew.");
++            LAppPal::PrintLog("Can't initilize glew.");
+         }
+         glfwTerminate();
+         return GL_FALSE;
+@@ -96,16 +102,11 @@ bool LAppDelegate::Initialize()
      glEnable(GL_BLEND);
      glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  
@@ -228,16 +401,16 @@ diff -pruN --exclude build ./demo_clean/src/LAppDelegate.cpp ./demo_dev/src/LApp
  
      //AppViewの初期化
      _view->Initialize();
-@@ -112,8 +114,6 @@ bool LAppDelegate::Initialize()
+@@ -113,8 +114,6 @@ bool LAppDelegate::Initialize()
      // Cubism3の初期化
      InitializeCubism();
  
--    SetRootDirectory();
+-    SetExecuteAbsolutePath();
 -
      //load model
      LAppLive2DManager::GetInstance();
  
-@@ -155,7 +155,6 @@ void LAppDelegate::Run()
+@@ -156,7 +155,6 @@ void LAppDelegate::Run()
              _windowWidth = width;
              _windowHeight = height;
          }
@@ -245,7 +418,16 @@ diff -pruN --exclude build ./demo_clean/src/LAppDelegate.cpp ./demo_dev/src/LApp
  
          // 時間更新
          LAppPal::UpdateTime();
-@@ -216,49 +215,6 @@ void LAppDelegate::InitializeCubism()
+@@ -191,7 +189,7 @@ LAppDelegate::LAppDelegate():
+     _windowWidth(0),
+     _windowHeight(0)
+ {
+-    _executeAbsolutePath = "";
++    _rootDirectory = "";
+     _view = new LAppView();
+     _textureManager = new LAppTextureManager();
+ }
+@@ -217,49 +215,6 @@ void LAppDelegate::InitializeCubism()
      LAppPal::UpdateTime();
  }
  
@@ -295,41 +477,41 @@ diff -pruN --exclude build ./demo_clean/src/LAppDelegate.cpp ./demo_dev/src/LApp
  GLuint LAppDelegate::CreateShader()
  {
      //バーテックスシェーダのコンパイル
-@@ -301,29 +257,9 @@ GLuint LAppDelegate::CreateShader()
+@@ -302,16 +257,24 @@ GLuint LAppDelegate::CreateShader()
      return programId;
  }
  
--void LAppDelegate::SetRootDirectory()
+-void LAppDelegate::SetExecuteAbsolutePath()
 +void LAppDelegate::SetRootDirectory(std::string rootDir)
  {
 -    char path[1024];
 -    ssize_t len = readlink("/proc/self/exe", path, 1024 - 1);
--
++    this->_rootDirectory = rootDir + "/";
++}
 -    if (len != -1)
--    {
++Csm::csmVector<string> LAppDelegate::Split(const std::string& baseString, char delimiter)
++{
++    Csm::csmVector<string> elems;
++    stringstream ss(baseString);
++    string item;
++
++    while(getline(ss, item, delimiter))
+     {
 -        path[len] = '\0';
--    }
--
--    std::string pathString(path);
--
--    pathString = pathString.substr(0, pathString.rfind("Demo"));
--    Csm::csmVector<string> splitStrings = this->Split(pathString, '/');
--
--    this->_rootDirectory = "";
--
--    for(int i = 0; i < splitStrings.GetSize(); i++)
--    {
--        this->_rootDirectory = this->_rootDirectory + "/" +splitStrings[i];
--    }
--
--    this->_rootDirectory += "/";
-+    this->_rootDirectory = rootDir + "/";
- }
++        if(!item.empty())
++        {
++            elems.PushBack(item);
++        }
+     }
  
- Csm::csmVector<string> LAppDelegate::Split(const std::string& baseString, char delimiter)
+-    this->_executeAbsolutePath = dirname(path);
+-    this->_executeAbsolutePath += "/";
++    return elems;
+ }
 diff -pruN --exclude build ./demo_clean/src/LAppDelegate.hpp ./demo_dev/src/LAppDelegate.hpp
---- ./demo_clean/src/LAppDelegate.hpp  2023-05-18 09:58:50.000000000 +0100
-+++ ./demo_dev/src/LAppDelegate.hpp    2023-05-28 09:11:29.467788463 +0100
+--- ./demo_clean/src/LAppDelegate.hpp  2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/src/LAppDelegate.hpp    2024-03-28 18:43:36.381973781 +0000
 @@ -40,7 +40,8 @@ public:
      /**
      * @brief   APPに必要なものを初期化する。
@@ -366,19 +548,46 @@ diff -pruN --exclude build ./demo_clean/src/LAppDelegate.hpp ./demo_dev/src/LApp
      * @brief シェーダーを登録する。
      */
      GLuint CreateShader();
-@@ -98,8 +80,10 @@ public:
+@@ -97,14 +79,16 @@ public:
+     void AppEnd() { _isEnd = true; }
  
      /**
-      * @brief   ルートディレクトリを設定する。
+-     * @brief   アプリケーションの実行パスを設定する。
++     * @brief   ルートディレクトリを設定する。
 +     *
 +     * @param[in] rootDir : The root directory to set to.
       */
--    void SetRootDirectory();
+-    void SetExecuteAbsolutePath();
 +    void SetRootDirectory(std::string rootDir);
  
      /**
-      * @brief   ルートディレクトリを取得する。
-@@ -146,24 +130,3 @@ private:
+-     * @brief   アプリケーションの実行パスを取得する。
++     * @brief   ルートディレクトリを取得する。
+      */
+-    std::string GetExecuteAbsolutePath(){ return _executeAbsolutePath;}
++    std::string GetRootDirectory(){ return _rootDirectory;}
+     /**
+      * @brief   テクスチャマネージャーを取得する。
+@@ -127,6 +111,11 @@ private:
+     */
+     void InitializeCubism();
++    /**
++     * @brief   文字列を指定の文字で切り分ける
++     */
++    Csm::csmVector<std::string> Split(const std::string& baseString, char delim);
++
+     LAppAllocator _cubismAllocator;              ///< Cubism3 Allocator
+     Csm::CubismFramework::Option _cubismOption;  ///< Cubism3 Option
+     GLFWwindow* _window;                         ///< OpenGL ウィンドウ
+@@ -136,29 +125,8 @@ private:
+     float _mouseY;                               ///< マウスY座標
+     bool _isEnd;                                 ///< APP終了しているか
+     LAppTextureManager* _textureManager;         ///< テクスチャマネージャー
+-    std::string _executeAbsolutePath;            ///< アプリケーションの実行パス
++    std::string _rootDirectory; ///< ルートディレクトリ
      int _windowWidth;                            ///< Initialize関数で設定したウィンドウ幅
      int _windowHeight;                           ///< Initialize関数で設定したウィンドウ高さ
  };
@@ -404,9 +613,46 @@ diff -pruN --exclude build ./demo_clean/src/LAppDelegate.hpp ./demo_dev/src/LApp
 -
 -};
 diff -pruN --exclude build ./demo_clean/src/LAppLive2DManager.cpp ./demo_dev/src/LAppLive2DManager.cpp
---- ./demo_clean/src/LAppLive2DManager.cpp     2023-05-18 09:58:50.000000000 +0100
-+++ ./demo_dev/src/LAppLive2DManager.cpp       2023-05-28 09:11:29.467788463 +0100
-@@ -52,11 +52,11 @@ void LAppLive2DManager::ReleaseInstance(
+--- ./demo_clean/src/LAppLive2DManager.cpp     2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/src/LAppLive2DManager.cpp       2024-03-28 18:43:36.381973781 +0000
+@@ -6,13 +6,7 @@
+  */
+ #include "LAppLive2DManager.hpp"
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <string.h>
+-#include <dirent.h>
+-#include <unistd.h>
+-#include <libgen.h>
+-#include <limits.h>
++#include <string>
+ #include <GL/glew.h>
+ #include <GLFW/glfw3.h>
+ #include <Rendering/CubismRenderer.hpp>
+@@ -25,19 +19,14 @@
+ using namespace Csm;
+ using namespace LAppDefine;
++using namespace std;
+ namespace {
+     LAppLive2DManager* s_instance = NULL;
+     void FinishedMotion(ACubismMotion* self)
+     {
+-        LAppPal::PrintLogLn("Motion Finished: %x", self);
+-    }
+-
+-    int CompareCsmString(const void* a, const void* b)
+-    {
+-        return strcmp(reinterpret_cast<const Csm::csmString*>(a)->GetRawString(),
+-            reinterpret_cast<const Csm::csmString*>(b)->GetRawString());
++        LAppPal::PrintLog("Motion Finished: %x", self);
+     }
+ }
+@@ -63,18 +52,16 @@ void LAppLive2DManager::ReleaseInstance(
  
  LAppLive2DManager::LAppLive2DManager()
      : _viewMatrix(NULL)
@@ -416,15 +662,85 @@ diff -pruN --exclude build ./demo_clean/src/LAppLive2DManager.cpp ./demo_dev/src
 +    , _translateY(0.0f)
  {
      _viewMatrix = new CubismMatrix44();
+-    SetUpModel();
 -
 -    ChangeScene(_sceneIndex);
  }
  
  LAppLive2DManager::~LAppLive2DManager()
-@@ -100,26 +100,6 @@ void LAppLive2DManager::OnTap(csmFloat32
+ {
+     ReleaseAllModel();
+-    delete _viewMatrix;
+ }
+ void LAppLive2DManager::ReleaseAllModel()
+@@ -87,60 +74,6 @@ void LAppLive2DManager::ReleaseAllModel(
+     _models.Clear();
+ }
+-void LAppLive2DManager::SetUpModel()
+-{
+-    // ResourcesPathの中にあるフォルダ名を全てクロールし、モデルが存在するフォルダを定義する。
+-    // フォルダはあるが同名の.model3.jsonが見つからなかった場合はリストに含めない。
+-    struct dirent *dirent;
+-    csmString crawlPath(LAppDelegate::GetInstance()->GetExecuteAbsolutePath().c_str());
+-    crawlPath += ResourcesPath;
+-
+-    DIR *pDir = opendir(crawlPath.GetRawString());
+-    if (pDir == NULL) return;
+-
+-    _modelDir.Clear();
+-
+-    while ((dirent = readdir(pDir)) != NULL)
+-    {
+-        if ((dirent->d_type & DT_DIR) && strcmp(dirent->d_name, "..") != 0)
+-        {
+-            // フォルダと同名の.model3.jsonがあるか探索する
+-            struct dirent *dirent2;
+-
+-            csmString modelName(dirent->d_name);
+-
+-            csmString modelPath(crawlPath);
+-            modelPath += modelName;
+-            modelPath.Append(1, '/');
+-
+-            csmString model3jsonName(modelName);
+-            model3jsonName += ".model3.json";
+-
+-            DIR *pDir2 = opendir(modelPath.GetRawString());
+-            while ((dirent2 = readdir(pDir2)) != NULL)
+-            {
+-                if (strcmp(dirent2->d_name, model3jsonName.GetRawString()) == 0)
+-                {
+-                    _modelDir.PushBack(csmString(dirent->d_name));
+-                }
+-            }
+-            closedir(pDir2);
+-        }
+-    }
+-    closedir(pDir);
+-    qsort(_modelDir.GetPtr(), _modelDir.GetSize(), sizeof(csmString), CompareCsmString);
+-}
+-
+-csmVector<csmString> LAppLive2DManager::GetModelDir() const
+-{
+-    return _modelDir;
+-}
+-
+-csmInt32 LAppLive2DManager::GetModelDirSize() const
+-{
+-    return _modelDir.GetSize();
+-}
+-
+ LAppModel* LAppLive2DManager::GetModel(csmUint32 no) const
+ {
+     if (no < _models.GetSize())
+@@ -165,27 +98,7 @@ void LAppLive2DManager::OnTap(csmFloat32
+ {
+     if (DebugLogEnable)
      {
-         LAppPal::PrintLog("[APP]tap point: {x:%.2f y:%.2f}", x, y);
-     }
+-        LAppPal::PrintLogLn("[APP]tap point: {x:%.2f y:%.2f}", x, y);
+-    }
 -
 -    for (csmUint32 i = 0; i < _models.GetSize(); i++)
 -    {
@@ -432,7 +748,7 @@ diff -pruN --exclude build ./demo_clean/src/LAppLive2DManager.cpp ./demo_dev/src
 -        {
 -            if (DebugLogEnable)
 -            {
--                LAppPal::PrintLog("[APP]hit area: [%s]", HitAreaNameHead);
+-                LAppPal::PrintLogLn("[APP]hit area: [%s]", HitAreaNameHead);
 -            }
 -            _models[i]->SetRandomExpression();
 -        }
@@ -440,15 +756,15 @@ diff -pruN --exclude build ./demo_clean/src/LAppLive2DManager.cpp ./demo_dev/src
 -        {
 -            if (DebugLogEnable)
 -            {
--                LAppPal::PrintLog("[APP]hit area: [%s]", HitAreaNameBody);
+-                LAppPal::PrintLogLn("[APP]hit area: [%s]", HitAreaNameBody);
 -            }
 -            _models[i]->StartRandomMotion(MotionGroupTapBody, PriorityNormal, FinishedMotion);
 -        }
--    }
++        LAppPal::PrintLog("[APP]tap point: {x:%.2f y:%.2f}", x, y);
+     }
  }
  
- void LAppLive2DManager::OnUpdate() const
-@@ -127,10 +107,10 @@ void LAppLive2DManager::OnUpdate() const
+@@ -194,15 +107,15 @@ void LAppLive2DManager::OnUpdate() const
      int width, height;
      glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
  
@@ -460,7 +776,13 @@ diff -pruN --exclude build ./demo_clean/src/LAppLive2DManager.cpp ./demo_dev/src
          LAppModel* model = GetModel(i);
  
          if (model->GetModel() == NULL)
-@@ -143,12 +123,15 @@ void LAppLive2DManager::OnUpdate() const
+         {
+-            LAppPal::PrintLogLn("Failed to model->GetModel().");
++            LAppPal::PrintLog("Failed to model->GetModel().");
+             continue;
+         }
+@@ -210,12 +123,15 @@ void LAppLive2DManager::OnUpdate() const
          {
              // 横に長いモデルを縦長ウィンドウに表示する際モデルの横サイズでscaleを算出する
              model->GetModelMatrix()->SetWidth(2.0f);
@@ -478,51 +800,61 @@ diff -pruN --exclude build ./demo_clean/src/LAppLive2DManager.cpp ./demo_dev/src
  
          // 必要があればここで乗算
          if (_viewMatrix != NULL)
-@@ -165,30 +148,14 @@ void LAppLive2DManager::OnUpdate() const
+@@ -232,37 +148,15 @@ void LAppLive2DManager::OnUpdate() const
      }
  }
  
 -void LAppLive2DManager::NextScene()
--{
--    csmInt32 no = (_sceneIndex + 1) % ModelDirSize;
++void LAppLive2DManager::SetModel(std::string modelName, bool useOldParamId)
+ {
+-    csmInt32 no = (_sceneIndex + 1) % GetModelDirSize();
 -    ChangeScene(no);
 -}
 -
 -void LAppLive2DManager::ChangeScene(Csm::csmInt32 index)
-+void LAppLive2DManager::SetModel(std::string modelName, bool useOldParamId)
- {
+-{
 -    _sceneIndex = index;
 -    if (DebugLogEnable)
 -    {
--        LAppPal::PrintLog("[APP]model index: %d", _sceneIndex);
+-        LAppPal::PrintLogLn("[APP]model index: %d", _sceneIndex);
 -    }
 -
 -    // ModelDir[]に保持したディレクトリ名から
 -    // model3.jsonのパスを決定する.
 -    // ディレクトリ名とmodel3.jsonの名前を一致させておくこと.
--    std::string model = ModelDir[index];
--    std::string modelPath = LAppDelegate::GetInstance()->GetRootDirectory() + ResourcesPath + model + "/";
--    std::string modelJsonName = ModelDir[index];
+-    const csmString& model = _modelDir[index];
+-    LAppPal::PrintLogLn("[APP]_modelDir: %s", model.GetRawString());
+-
+-    csmString modelPath(LAppDelegate::GetInstance()->GetExecuteAbsolutePath().c_str());
+-    modelPath += ResourcesPath;
+-    modelPath += model;
+-    modelPath.Append(1, '/');
+-
+-    csmString modelJsonName(model);
 +    std::string modelPath = LAppDelegate::GetInstance()->GetRootDirectory() + ResourcesPath + modelName + "/";
 +    std::string modelJsonName = modelName;
      modelJsonName += ".model3.json";
  
      ReleaseAllModel();
 -    _models.PushBack(new LAppModel());
+-    _models[0]->LoadAssets(modelPath.GetRawString(), modelJsonName.GetRawString());
 +    _models.PushBack(new LAppModel(useOldParamId));
-     _models[0]->LoadAssets(modelPath.c_str(), modelJsonName.c_str());
++    _models[0]->LoadAssets(modelPath.c_str(), modelJsonName.c_str());
  
      /*
-@@ -210,7 +177,7 @@ void LAppLive2DManager::ChangeScene(Csm:
+      * モデル半透明表示を行うサンプルを提示する。
+@@ -283,8 +177,8 @@ void LAppLive2DManager::ChangeScene(Csm:
  
  #if defined(USE_RENDER_TARGET) || defined(USE_MODEL_RENDER_TARGET)
          // モデル個別にαを付けるサンプルとして、もう1体モデルを作成し、少し位置をずらす
 -        _models.PushBack(new LAppModel());
+-        _models[1]->LoadAssets(modelPath.GetRawString(), modelJsonName.GetRawString());
 +        _models.PushBack(new LAppModel(useOldParamId));
-         _models[1]->LoadAssets(modelPath.c_str(), modelJsonName.c_str());
++        _models[1]->LoadAssets(modelPath.c_str(), modelJsonName.c_str());
          _models[1]->GetModelMatrix()->TranslateX(0.2f);
  #endif
-@@ -239,3 +206,20 @@ void LAppLive2DManager::SetViewMatrix(Cu
+@@ -312,3 +206,20 @@ void LAppLive2DManager::SetViewMatrix(Cu
          _viewMatrix->GetArray()[i] = m->GetArray()[i];
      }
  }
@@ -544,8 +876,8 @@ diff -pruN --exclude build ./demo_clean/src/LAppLive2DManager.cpp ./demo_dev/src
 +    _translateY = translateY;
 +}
 diff -pruN --exclude build ./demo_clean/src/LAppLive2DManager.hpp ./demo_dev/src/LAppLive2DManager.hpp
---- ./demo_clean/src/LAppLive2DManager.hpp     2023-05-18 09:58:50.000000000 +0100
-+++ ./demo_dev/src/LAppLive2DManager.hpp       2023-05-28 09:11:29.467788463 +0100
+--- ./demo_clean/src/LAppLive2DManager.hpp     2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/src/LAppLive2DManager.hpp       2024-03-28 18:43:36.381973781 +0000
 @@ -6,12 +6,15 @@
   */
  #pragma once
@@ -562,7 +894,32 @@ diff -pruN --exclude build ./demo_clean/src/LAppLive2DManager.hpp ./demo_dev/src
  /**
  * @brief サンプルアプリケーションにおいてCubismModelを管理するクラス<br>
  *         モデル生成と破棄、タップイベントの処理、モデル切り替えを行う。
-@@ -72,16 +75,14 @@ public:
+@@ -36,24 +39,6 @@ public:
+     static void ReleaseInstance();
+     /**
+-    * @brief   Resources フォルダにあるモデルフォルダ名をセットする
+-    *
+-    */
+-    void SetUpModel();
+-
+-    /**
+-    * @brief   Resources フォルダにあるモデルフォルダ名を取得する
+-    *
+-    */
+-    Csm::csmVector<Csm::csmString> GetModelDir() const;
+-
+-    /**
+-    * @brief   Resources フォルダにあるモデルフォルダのサイズを取得する
+-    *
+-    */
+-    Csm::csmInt32 GetModelDirSize() const;
+-
+-    /**
+     * @brief   現在のシーンで保持しているモデルを返す
+     *
+     * @param[in]   no  モデルリストのインデックス値
+@@ -90,16 +75,14 @@ public:
      void OnUpdate() const;
  
      /**
@@ -587,7 +944,7 @@ diff -pruN --exclude build ./demo_clean/src/LAppLive2DManager.hpp ./demo_dev/src
  
      /**
       * @brief   モデル個数を得る
-@@ -94,6 +95,24 @@ public:
+@@ -112,6 +95,24 @@ public:
       */
      void SetViewMatrix(Live2D::Cubism::Framework::CubismMatrix44* m);
  
@@ -612,19 +969,24 @@ diff -pruN --exclude build ./demo_clean/src/LAppLive2DManager.hpp ./demo_dev/src
  private:
      /**
      * @brief  コンストラクタ
-@@ -107,5 +126,8 @@ private:
+@@ -123,9 +124,10 @@ private:
+     */
+     virtual ~LAppLive2DManager();
  
-     Csm::CubismMatrix44*        _viewMatrix; ///< モデル描画に用いるView行列
-     Csm::csmVector<LAppModel*>  _models; ///< モデルインスタンスのコンテナ
--    Csm::csmInt32               _sceneIndex; ///< 表示するシーンのインデックス値
-+
+-    Csm::CubismMatrix44* _viewMatrix; ///< モデル描画に用いるView行列
+-    Csm::csmVector<LAppModel*> _models; ///< モデルインスタンスのコンテナ
+-    Csm::csmInt32 _sceneIndex; ///< 表示するシーンのインデックス値
++    Csm::CubismMatrix44*        _viewMatrix; ///< モデル描画に用いるView行列
++    Csm::csmVector<LAppModel*>  _models; ///< モデルインスタンスのコンテナ
+-    Csm::csmVector<Csm::csmString> _modelDir; ///< モデルディレクトリ名のコンテナ
 +    float _projScaleFactor;
 +    float _translateX;
 +    float _translateY;
  };
 diff -pruN --exclude build ./demo_clean/src/LAppModel.cpp ./demo_dev/src/LAppModel.cpp
---- ./demo_clean/src/LAppModel.cpp     2023-05-18 09:58:50.000000000 +0100
-+++ ./demo_dev/src/LAppModel.cpp       2023-05-28 09:16:04.144770508 +0100
+--- ./demo_clean/src/LAppModel.cpp     2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/src/LAppModel.cpp       2024-03-28 18:44:22.822767401 +0000
 @@ -21,6 +21,10 @@
  #include "LAppTextureManager.hpp"
  #include "LAppDelegate.hpp"
@@ -636,7 +998,23 @@ diff -pruN --exclude build ./demo_clean/src/LAppModel.cpp ./demo_dev/src/LAppMod
  using namespace Live2D::Cubism::Framework;
  using namespace Live2D::Cubism::Framework::DefaultParameterId;
  using namespace LAppDefine;
-@@ -45,22 +49,24 @@ namespace {
+@@ -30,7 +34,7 @@ namespace {
+     {
+         if (DebugLogEnable)
+         {
+-            LAppPal::PrintLogLn("[APP]create buffer: %s ", path);
++            LAppPal::PrintLog("[APP]create buffer: %s ", path);
+         }
+         return LAppPal::LoadFileAsBytes(path, size);
+     }
+@@ -39,28 +43,30 @@ namespace {
+     {
+         if (DebugLogEnable)
+         {
+-            LAppPal::PrintLogLn("[APP]delete buffer: %s", path);
++            LAppPal::PrintLog("[APP]delete buffer: %s", path);
+         }
+         LAppPal::ReleaseBytes(buffer);
      }
  }
  
@@ -668,20 +1046,58 @@ diff -pruN --exclude build ./demo_clean/src/LAppModel.cpp ./demo_dev/src/LAppMod
  }
  
  LAppModel::~LAppModel()
+@@ -84,7 +90,7 @@ void LAppModel::LoadAssets(const csmChar
+     if (_debugMode)
+     {
+-        LAppPal::PrintLogLn("[APP]load model setting: %s", fileName);
++        LAppPal::PrintLog("[APP]load model setting: %s", fileName);
+     }
+     csmSizeInt size;
 @@ -96,12 +102,6 @@ void LAppModel::LoadAssets(const csmChar
  
      SetupModel(setting);
  
 -    if (_model == NULL)
 -    {
--        LAppPal::PrintLog("Failed to LoadAssets().");
+-        LAppPal::PrintLogLn("Failed to LoadAssets().");
 -        return;
 -    }
 -
      CreateRenderer();
  
      SetupTextures();
-@@ -196,7 +196,7 @@ void LAppModel::SetupModel(ICubismModelS
+@@ -126,7 +126,7 @@ void LAppModel::SetupModel(ICubismModelS
+         if (_debugMode)
+         {
+-            LAppPal::PrintLogLn("[APP]create model: %s", setting->GetModelFileName());
++            LAppPal::PrintLog("[APP]create model: %s", setting->GetModelFileName());
+         }
+         buffer = CreateBuffer(path.GetRawString(), &size);
+@@ -147,15 +147,12 @@ void LAppModel::SetupModel(ICubismModelS
+             buffer = CreateBuffer(path.GetRawString(), &size);
+             ACubismMotion* motion = LoadExpression(buffer, size, name.GetRawString());
+-            if (motion)
++            if (_expressions[name] != NULL)
+             {
+-                if (_expressions[name] != NULL)
+-                {
+-                    ACubismMotion::Delete(_expressions[name]);
+-                    _expressions[name] = NULL;
+-                }
+-                _expressions[name] = motion;
++                ACubismMotion::Delete(_expressions[name]);
++                _expressions[name] = NULL;
+             }
++            _expressions[name] = motion;
+             DeleteBuffer(buffer, path.GetRawString());
+         }
+@@ -199,7 +196,7 @@ void LAppModel::SetupModel(ICubismModelS
          breathParameters.PushBack(CubismBreath::BreathParameterData(_idParamAngleY, 0.0f, 8.0f, 3.5345f, 0.5f));
          breathParameters.PushBack(CubismBreath::BreathParameterData(_idParamAngleZ, 0.0f, 10.0f, 5.5345f, 0.5f));
          breathParameters.PushBack(CubismBreath::BreathParameterData(_idParamBodyAngleX, 0.0f, 4.0f, 15.5345f, 0.5f));
@@ -690,20 +1106,71 @@ diff -pruN --exclude build ./demo_clean/src/LAppModel.cpp ./demo_dev/src/LAppMod
  
          _breath->SetParameters(breathParameters);
      }
-@@ -229,12 +229,6 @@ void LAppModel::SetupModel(ICubismModelS
+@@ -232,12 +229,6 @@ void LAppModel::SetupModel(ICubismModelS
          }
      }
  
 -    if (_modelSetting == NULL || _modelMatrix == NULL)
 -    {
--        LAppPal::PrintLog("Failed to SetupModel().");
+-        LAppPal::PrintLogLn("Failed to SetupModel().");
 -        return;
 -    }
 -
      //Layout
      csmMap<csmString, csmFloat32> layout;
      _modelSetting->GetLayoutMap(layout);
-@@ -347,86 +341,117 @@ void LAppModel::Update()
+@@ -270,7 +261,7 @@ void LAppModel::PreloadMotionGroup(const
+         if (_debugMode)
+         {
+-            LAppPal::PrintLogLn("[APP]load motion: %s => [%s_%d] ", path.GetRawString(), group, i);
++            LAppPal::PrintLog("[APP]load motion: %s => [%s_%d] ", path.GetRawString(), group, i);
+         }
+         csmByte* buffer;
+@@ -278,27 +269,24 @@ void LAppModel::PreloadMotionGroup(const
+         buffer = CreateBuffer(path.GetRawString(), &size);
+         CubismMotion* tmpMotion = static_cast<CubismMotion*>(LoadMotion(buffer, size, name.GetRawString()));
+-        if (tmpMotion)
++        csmFloat32 fadeTime = _modelSetting->GetMotionFadeInTimeValue(group, i);
++        if (fadeTime >= 0.0f)
+         {
+-            csmFloat32 fadeTime = _modelSetting->GetMotionFadeInTimeValue(group, i);
+-            if (fadeTime >= 0.0f)
+-            {
+-                tmpMotion->SetFadeInTime(fadeTime);
+-            }
++            tmpMotion->SetFadeInTime(fadeTime);
++        }
+-            fadeTime = _modelSetting->GetMotionFadeOutTimeValue(group, i);
+-            if (fadeTime >= 0.0f)
+-            {
+-                tmpMotion->SetFadeOutTime(fadeTime);
+-            }
+-            tmpMotion->SetEffectIds(_eyeBlinkIds, _lipSyncIds);
++        fadeTime = _modelSetting->GetMotionFadeOutTimeValue(group, i);
++        if (fadeTime >= 0.0f)
++        {
++            tmpMotion->SetFadeOutTime(fadeTime);
++        }
++        tmpMotion->SetEffectIds(_eyeBlinkIds, _lipSyncIds);
+-            if (_motions[name] != NULL)
+-            {
+-                ACubismMotion::Delete(_motions[name]);
+-            }
+-            _motions[name] = tmpMotion;
++        if (_motions[name] != NULL)
++        {
++            ACubismMotion::Delete(_motions[name]);
+         }
++        _motions[name] = tmpMotion;
+         DeleteBuffer(buffer, path.GetRawString());
+     }
+@@ -353,86 +341,117 @@ void LAppModel::Update()
      const csmFloat32 deltaTimeSeconds = LAppPal::GetDeltaTime();
      _userTimeSeconds += deltaTimeSeconds;
  
@@ -717,13 +1184,13 @@ diff -pruN --exclude build ./demo_clean/src/LAppModel.cpp ./demo_dev/src/LAppMod
 -    //-----------------------------------------------------------------
 -    _model->LoadParameters(); // 前回セーブされた状態をロード
 -    if (_motionManager->IsFinished())
-+    if (_tracker)
-     {
+-    {
 -        // モーションの再生がない場合、待機モーションの中からランダムで再生する
 -        StartRandomMotion(MotionGroupIdle, PriorityIdle);
 -    }
 -    else
--    {
++    if (_tracker)
+     {
 -        motionUpdated = _motionManager->UpdateMotion(_model, deltaTimeSeconds); // モーションを更新
 -    }
 -    _model->SaveParameters(); // 状態を保存
@@ -851,9 +1318,11 @@ diff -pruN --exclude build ./demo_clean/src/LAppModel.cpp ./demo_dev/src/LAppMod
 +            _model->SetParameterValue(idMan->GetId(_("ParamMouthOpenY")),
 +                                      params.live2d["ParamMouthOpenY"]);
 +        }
-+
+-        for (csmUint32 i = 0; i < _lipSyncIds.GetSize(); ++i)
 +        for (auto const &entry : params.live2d)
-+        {
+         {
+-            _model->AddParameterValue(_lipSyncIds[i], value, 0.8f);
 +            std::string key = entry.first;
 +            double val = entry.second;
 +
@@ -863,11 +1332,9 @@ diff -pruN --exclude build ./demo_clean/src/LAppModel.cpp ./demo_dev/src/LAppMod
 +                _model->SetParameterValue(idMan->GetId(_(key)), val);
 +            }
 +        }
--        for (csmUint32 i = 0; i < _lipSyncIds.GetSize(); ++i)
++
 +        if (params.autoBreath && _breath)
-         {
--            _model->AddParameterValue(_lipSyncIds[i], value, 0.8f);
++        {
 +            // Note: _model->LoadParameters and SaveParameters is needed
 +            // before - see above.
 +            _breath->UpdateParameters(_model, deltaTimeSeconds);
@@ -883,7 +1350,50 @@ diff -pruN --exclude build ./demo_clean/src/LAppModel.cpp ./demo_dev/src/LAppMod
      // ポーズの設定
      if (_pose != NULL)
      {
-@@ -495,7 +520,6 @@ CubismMotionQueueEntryHandle LAppModel::
+@@ -453,7 +472,7 @@ CubismMotionQueueEntryHandle LAppModel::
+     {
+         if (_debugMode)
+         {
+-            LAppPal::PrintLogLn("[APP]can't start motion.");
++            LAppPal::PrintLog("[APP]can't start motion.");
+         }
+         return InvalidMotionQueueEntryHandleValue;
+     }
+@@ -474,23 +493,19 @@ CubismMotionQueueEntryHandle LAppModel::
+         csmSizeInt size;
+         buffer = CreateBuffer(path.GetRawString(), &size);
+         motion = static_cast<CubismMotion*>(LoadMotion(buffer, size, NULL, onFinishedMotionHandler));
+-
+-        if (motion)
++        csmFloat32 fadeTime = _modelSetting->GetMotionFadeInTimeValue(group, no);
++        if (fadeTime >= 0.0f)
+         {
+-            csmFloat32 fadeTime = _modelSetting->GetMotionFadeInTimeValue(group, no);
+-            if (fadeTime >= 0.0f)
+-            {
+-                motion->SetFadeInTime(fadeTime);
+-            }
++            motion->SetFadeInTime(fadeTime);
++        }
+-            fadeTime = _modelSetting->GetMotionFadeOutTimeValue(group, no);
+-            if (fadeTime >= 0.0f)
+-            {
+-                motion->SetFadeOutTime(fadeTime);
+-            }
+-            motion->SetEffectIds(_eyeBlinkIds, _lipSyncIds);
+-            autoDelete = true; // 終了時にメモリから削除
++        fadeTime = _modelSetting->GetMotionFadeOutTimeValue(group, no);
++        if (fadeTime >= 0.0f)
++        {
++            motion->SetFadeOutTime(fadeTime);
+         }
++        motion->SetEffectIds(_eyeBlinkIds, _lipSyncIds);
++        autoDelete = true; // 終了時にメモリから削除
+         DeleteBuffer(buffer, path.GetRawString());
+     }
+@@ -505,12 +520,11 @@ CubismMotionQueueEntryHandle LAppModel::
      {
          csmString path = voice;
          path = _modelHomeDir + path;
@@ -891,7 +1401,31 @@ diff -pruN --exclude build ./demo_clean/src/LAppModel.cpp ./demo_dev/src/LAppMod
      }
  
      if (_debugMode)
-@@ -647,3 +671,42 @@ Csm::Rendering::CubismOffscreenFrame_Ope
+     {
+-        LAppPal::PrintLogLn("[APP]start motion: [%s_%d]", group, no);
++        LAppPal::PrintLog("[APP]start motion: [%s_%d]", group, no);
+     }
+     return  _motionManager->StartMotionPriority(motion, autoDelete, priority);
+ }
+@@ -575,7 +589,7 @@ void LAppModel::SetExpression(const csmC
+     ACubismMotion* motion = _expressions[expressionID];
+     if (_debugMode)
+     {
+-        LAppPal::PrintLogLn("[APP]expression: [%s]", expressionID);
++        LAppPal::PrintLog("[APP]expression: [%s]", expressionID);
+     }
+     if (motion != NULL)
+@@ -584,7 +598,7 @@ void LAppModel::SetExpression(const csmC
+     }
+     else
+     {
+-        if (_debugMode) LAppPal::PrintLogLn("[APP]expression[%s] is null ", expressionID);
++        if (_debugMode) LAppPal::PrintLog("[APP]expression[%s] is null ", expressionID);
+     }
+ }
+@@ -657,3 +671,42 @@ Csm::Rendering::CubismOffscreenSurface_O
  {
      return _renderBuffer;
  }
@@ -935,8 +1469,8 @@ diff -pruN --exclude build ./demo_clean/src/LAppModel.cpp ./demo_dev/src/LAppMod
 +}
 +
 diff -pruN --exclude build ./demo_clean/src/LAppModel.hpp ./demo_dev/src/LAppModel.hpp
---- ./demo_clean/src/LAppModel.hpp     2023-05-18 09:58:50.000000000 +0100
-+++ ./demo_dev/src/LAppModel.hpp       2023-05-28 09:11:29.471788536 +0100
+--- ./demo_clean/src/LAppModel.hpp     2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/src/LAppModel.hpp       2024-03-28 18:43:36.385973850 +0000
 @@ -13,7 +13,7 @@
  #include <Type/csmRectF.hpp>
  #include <Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.hpp>
@@ -961,7 +1495,7 @@ diff -pruN --exclude build ./demo_clean/src/LAppModel.hpp ./demo_dev/src/LAppMod
       * @brief デストラクタ
 @@ -114,6 +117,15 @@ public:
       */
-     Csm::Rendering::CubismOffscreenFrame_OpenGLES2& GetRenderBuffer();
+     Csm::Rendering::CubismOffscreenSurface_OpenGLES2& GetRenderBuffer();
  
 +    /**
 +     * @brief Set the pointer to the MouseCursorTracker instance
@@ -993,21 +1527,22 @@ diff -pruN --exclude build ./demo_clean/src/LAppModel.hpp ./demo_dev/src/LAppMod
      Csm::ICubismModelSetting* _modelSetting; ///< モデルセッティング情報
      Csm::csmString _modelHomeDir; ///< モデルセッティングが置かれたディレクトリ
      Csm::csmFloat32 _userTimeSeconds; ///< デルタ時間の積算値[秒]
-@@ -183,9 +206,9 @@ private:
+@@ -183,7 +206,10 @@ private:
      const Csm::CubismId* _idParamEyeBallX; ///< パラメータID: ParamEyeBallX
      const Csm::CubismId* _idParamEyeBallY; ///< パラメータID: ParamEyeBallXY
  
 -    LAppWavFileHandler _wavFileHandler; ///< wavファイルハンドラ
 -
-     Csm::Rendering::CubismOffscreenFrame_OpenGLES2 _renderBuffer;   ///< フレームバッファ以外の描画先
+     Csm::Rendering::CubismOffscreenSurface_OpenGLES2 _renderBuffer;   ///< フレームバッファ以外の描画先
 +
 +    MouseCursorTracker *_tracker;
  };
++
++
++
 diff -pruN --exclude build ./demo_clean/src/LAppPal.cpp ./demo_dev/src/LAppPal.cpp
---- ./demo_clean/src/LAppPal.cpp       2023-05-18 09:58:50.000000000 +0100
-+++ ./demo_dev/src/LAppPal.cpp 2023-05-28 09:11:29.471788536 +0100
+--- ./demo_clean/src/LAppPal.cpp       2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/src/LAppPal.cpp 2024-03-28 18:43:36.385973850 +0000
 @@ -6,6 +6,7 @@
   */
  
@@ -1016,29 +1551,116 @@ diff -pruN --exclude build ./demo_clean/src/LAppPal.cpp ./demo_dev/src/LAppPal.c
  #include <stdio.h>
  #include <stdlib.h>
  #include <stdarg.h>
-@@ -36,7 +37,6 @@ csmByte* LAppPal::LoadFileAsBytes(const
+@@ -36,37 +37,17 @@ csmByte* LAppPal::LoadFileAsBytes(const
      if (stat(path, &statBuf) == 0)
      {
          size = statBuf.st_size;
--        PrintLog(path);
+-
+-        if (size == 0)
+-        {
+-            if (DebugLogEnable)
+-            {
+-                PrintLogLn("Stat succeeded but file size is zero. path:%s", path);
+-            }
+-            return NULL;
+-        }
+-    }
+-    else
+-    {
+-        if (DebugLogEnable)
+-        {
+-            PrintLogLn("Stat failed. errno:%d path:%s", errno, path);
+-        }
+-        return NULL;
      }
  
      std::fstream file;
-@@ -45,10 +45,7 @@ csmByte* LAppPal::LoadFileAsBytes(const
++    char* buf = new char[size];
++
      file.open(path, std::ios::in | std::ios::binary);
      if (!file.is_open())
      {
 -        if (DebugLogEnable)
 -        {
--            PrintLog("file open error");
+-            PrintLogLn("File open failed. path:%s", path);
 -        }
 +        throw std::runtime_error("Failed to open file " + filePath);
          return NULL;
      }
+-
+-    char* buf = new char[size];
      file.read(buf, size);
+     file.close();
+@@ -97,17 +78,7 @@ void LAppPal::PrintLog(const csmChar* fo
+     csmChar buf[256];
+     va_start(args, format);
+     vsnprintf(buf, sizeof(buf), format, args); // 標準出力でレンダリング
+-    std::cout << buf;
+-    va_end(args);
+-}
+-
+-void LAppPal::PrintLogLn(const csmChar* format, ...)
+-{
+-    va_list args;
+-    csmChar buf[256];
+-    va_start(args, format);
+-    vsnprintf(buf, sizeof(buf), format, args); // 標準出力でレンダリング
+-    std::cout << buf << std::endl;
++    std::cerr << buf << std::endl;
+     va_end(args);
+ }
+@@ -115,8 +86,3 @@ void LAppPal::PrintMessage(const csmChar
+ {
+     PrintLog("%s", message);
+ }
+-
+-void LAppPal::PrintMessageLn(const csmChar* message)
+-{
+-    PrintLogLn("%s", message);
+-}
+diff -pruN --exclude build ./demo_clean/src/LAppPal.hpp ./demo_dev/src/LAppPal.hpp
+--- ./demo_clean/src/LAppPal.hpp       2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/src/LAppPal.hpp 2024-03-28 18:43:36.385973850 +0000
+@@ -63,17 +63,6 @@ public:
+     static void PrintLog(const Csm::csmChar* format, ...);
+     /**
+-    * @brief ログを出力し最後に改行する
+-    *
+-    * ログを出力し最後に改行する
+-    *
+-    * @param[in]   format  書式付文字列
+-    * @param[in]   ...     (可変長引数)文字列
+-    *
+-    */
+-    static void PrintLogLn(const Csm::csmChar* format, ...);
+-
+-    /**
+     * @brief メッセージを出力する
+     *
+     * メッセージを出力する
+@@ -83,16 +72,6 @@ public:
+     */
+     static void PrintMessage(const Csm::csmChar* message);
+-    /**
+-    * @brief メッセージを出力し最後に改行する
+-    *
+-    * メッセージを出力し最後に改行する
+-    *
+-    * @param[in]   message  文字列
+-    *
+-    */
+-    static void PrintMessageLn(const Csm::csmChar* message);
+-
+ private:
+     static double s_currentFrame;
+     static double s_lastFrame;
 diff -pruN --exclude build ./demo_clean/src/LAppTextureManager.cpp ./demo_dev/src/LAppTextureManager.cpp
---- ./demo_clean/src/LAppTextureManager.cpp    2023-05-18 09:58:50.000000000 +0100
-+++ ./demo_dev/src/LAppTextureManager.cpp      2023-05-28 09:11:29.471788536 +0100
+--- ./demo_clean/src/LAppTextureManager.cpp    2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/src/LAppTextureManager.cpp      2024-03-28 18:43:36.385973850 +0000
 @@ -96,6 +96,46 @@ LAppTextureManager::TextureInfo* LAppTex
  
  }
@@ -1087,8 +1709,8 @@ diff -pruN --exclude build ./demo_clean/src/LAppTextureManager.cpp ./demo_dev/sr
  {
      for (Csm::csmUint32 i = 0; i < _textures.GetSize(); i++)
 diff -pruN --exclude build ./demo_clean/src/LAppTextureManager.hpp ./demo_dev/src/LAppTextureManager.hpp
---- ./demo_clean/src/LAppTextureManager.hpp    2023-05-18 09:58:50.000000000 +0100
-+++ ./demo_dev/src/LAppTextureManager.hpp      2023-05-28 09:11:29.471788536 +0100
+--- ./demo_clean/src/LAppTextureManager.hpp    2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/src/LAppTextureManager.hpp      2024-03-28 18:43:36.385973850 +0000
 @@ -72,6 +72,8 @@ public:
      */
      TextureInfo* CreateTextureFromPngFile(std::string fileName);
@@ -1099,8 +1721,8 @@ diff -pruN --exclude build ./demo_clean/src/LAppTextureManager.hpp ./demo_dev/sr
      * @brief 画像の解放
      *
 diff -pruN --exclude build ./demo_clean/src/LAppView.cpp ./demo_dev/src/LAppView.cpp
---- ./demo_clean/src/LAppView.cpp      2023-05-18 09:58:50.000000000 +0100
-+++ ./demo_dev/src/LAppView.cpp        2023-05-28 09:11:29.471788536 +0100
+--- ./demo_clean/src/LAppView.cpp      2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/src/LAppView.cpp        2024-03-28 18:44:40.051061624 +0000
 @@ -13,7 +13,6 @@
  #include "LAppLive2DManager.hpp"
  #include "LAppTextureManager.hpp"
@@ -1152,7 +1774,7 @@ diff -pruN --exclude build ./demo_clean/src/LAppView.cpp ./demo_dev/src/LAppView
      glfwGetWindowSize(LAppDelegate::GetInstance()->GetWindow(), &width, &height);
  
      LAppTextureManager* textureManager = LAppDelegate::GetInstance()->GetTextureManager();
--    const string resourcesPath = LAppDelegate::GetInstance()->GetRootDirectory() + ResourcesPath;
+-    const string resourcesPath = LAppDelegate::GetInstance()->GetExecuteAbsolutePath() + ResourcesPath;
  
 -    string imageName = BackImageName;
 -    LAppTextureManager::TextureInfo* backgroundTexture = textureManager->CreateTextureFromPngFile(resourcesPath + imageName);
@@ -1221,7 +1843,7 @@ diff -pruN --exclude build ./demo_clean/src/LAppView.cpp ./demo_dev/src/LAppView
 -        float y = _deviceToScreen->TransformY(_touchManager->GetY()); // 論理座標変換した座標を取得。
 -        if (DebugTouchLogEnable)
 -        {
--            LAppPal::PrintLog("[APP]touchesEnded x:%.2f y:%.2f", x, y);
+-            LAppPal::PrintLogLn("[APP]touchesEnded x:%.2f y:%.2f", x, y);
 -        }
 -        live2DManager->OnTap(x, y);
 -
@@ -1276,8 +1898,8 @@ diff -pruN --exclude build ./demo_clean/src/LAppView.cpp ./demo_dev/src/LAppView
 -    }
  }
 diff -pruN --exclude build ./demo_clean/src/LAppView.hpp ./demo_dev/src/LAppView.hpp
---- ./demo_clean/src/LAppView.hpp      2023-05-18 09:58:50.000000000 +0100
-+++ ./demo_dev/src/LAppView.hpp        2023-05-28 09:11:29.471788536 +0100
+--- ./demo_clean/src/LAppView.hpp      2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/src/LAppView.hpp        2024-03-28 18:43:36.385973850 +0000
 @@ -14,7 +14,6 @@
  #include "CubismFramework.hpp"
  #include <Rendering/OpenGL/CubismOffscreenSurface_OpenGLES2.hpp>
@@ -1332,8 +1954,8 @@ diff -pruN --exclude build ./demo_clean/src/LAppView.hpp ./demo_dev/src/LAppView
      // レンダリング先を別ターゲットにする方式の場合に使用
      LAppSprite* _renderSprite;                                  ///< モードによっては_renderBufferのテクスチャを描画
 diff -pruN --exclude build ./demo_clean/src/main.cpp ./demo_dev/src/main.cpp
---- ./demo_clean/src/main.cpp  2023-05-18 09:58:50.000000000 +0100
-+++ ./demo_dev/src/main.cpp    2023-05-28 09:11:29.467788463 +0100
+--- ./demo_clean/src/main.cpp  2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/src/main.cpp    2024-03-28 18:43:36.389973918 +0000
 @@ -5,18 +5,188 @@
   * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html.
   */
@@ -1528,3 +2150,133 @@ diff -pruN --exclude build ./demo_clean/src/main.cpp ./demo_dev/src/main.cpp
      return 0;
  }
 -
+diff -pruN --exclude build ./demo_clean/src/mainMinimum.cpp ./demo_dev/src/mainMinimum.cpp
+--- ./demo_clean/src/mainMinimum.cpp   2024-03-28 18:39:52.882141826 +0000
++++ ./demo_dev/src/mainMinimum.cpp     2024-03-28 18:43:36.389973918 +0000
+@@ -9,7 +9,6 @@
+ #include <sstream>
+ #include <unistd.h>
+-#include <libgen.h>
+ #include <GL/glew.h>
+ #include <GLFW/glfw3.h>
+@@ -62,7 +61,7 @@ static LAppAllocator _cubismAllocator; /
+ static LAppTextureManager* _textureManager; ///< テクスチャの管理
+-static std::string _executeAbsolutePath; ///< アプリケーションの実行パス
++static std::string _rootDirectory; ///< ルートディレクトリ
+ static std::string _currentModelDirectory; ///< 現在のモデルのディレクトリ名
+ static GLFWwindow* _window; ///< ウィンドウオブジェクト
+@@ -86,11 +85,33 @@ static void InitializeCubism()
+ }
+ /**
+-* @brief アプリケーションの実行パスの設定
++* @brief 文字列の分割
+ *
+-* Linuxのアプリケーションの実行パスを確認し、パスを取得する
++* 指定された区切り文字で文字列を分割する
+ */
+-void SetExecuteAbsolutePath()
++Csm::csmVector<std::string> Split(const std::string& baseString, char delimiter)
++{
++    Csm::csmVector < std::string > elems;
++    std::stringstream ss(baseString);
++    std::string item;
++
++    while (getline(ss, item, delimiter))
++    {
++        if (!item.empty())
++        {
++            elems.PushBack(item);
++        }
++    }
++
++    return elems;
++}
++
++/**
++* @brief ルートディレクトリの設定
++*
++* Linuxのルートディレクトリを確認し、パスを取得する
++*/
++void SetRootDirectory()
+ {
+     const int maximumPathBufferSize = 1024;
+     char path[maximumPathBufferSize];
+@@ -101,8 +122,19 @@ void SetExecuteAbsolutePath()
+         path[len] = '\0';
+     }
+-    _executeAbsolutePath = dirname(path);
+-    _executeAbsolutePath += "/";
++    std::string pathString(path);
++
++    pathString = pathString.substr(0, pathString.rfind("Demo"));
++    Csm::csmVector<std::string> splitStrings = Split(pathString, '/');
++
++    _rootDirectory = "";
++
++    for (int i = 0; i < splitStrings.GetSize(); i++)
++    {
++        _rootDirectory += "/" + splitStrings[i];
++    }
++
++    _rootDirectory += "/";
+ }
+ /**
+@@ -112,12 +144,12 @@ void SetExecuteAbsolutePath()
+ */
+ static bool InitializeSystem()
+ {
+-    LAppPal::PrintLogLn("START");
++    LAppPal::PrintLog("START");
+     // GLFWの初期化
+     if (glfwInit() == GL_FALSE)
+     {
+-        LAppPal::PrintLogLn("Can't initilize GLFW");
++        LAppPal::PrintLog("Can't initilize GLFW");
+         return GL_FALSE;
+     }
+@@ -126,7 +158,7 @@ static bool InitializeSystem()
+     _window = glfwCreateWindow(LAppDefine::RenderTargetWidth, LAppDefine::RenderTargetHeight, "SIMPLE_SAMPLE", NULL, NULL);
+     if (_window == NULL)
+     {
+-        LAppPal::PrintLogLn("Can't create GLFW window.");
++        LAppPal::PrintLog("Can't create GLFW window.");
+         glfwTerminate();
+         return GL_FALSE;
+@@ -137,7 +169,7 @@ static bool InitializeSystem()
+     glfwSwapInterval(1);
+     if (glewInit() != GLEW_OK) {
+-        LAppPal::PrintLogLn("Can't initilize glew.");
++        LAppPal::PrintLog("Can't initilize glew.");
+         glfwTerminate();
+         return GL_FALSE;
+@@ -165,7 +197,7 @@ static bool InitializeSystem()
+     // ドラッグ入力管理クラスの初期化
+     MouseActionManager::GetInstance()->Initialize(windowWidth, windowHeight);
+-    SetExecuteAbsolutePath();
++    SetRootDirectory();
+     return GL_TRUE;
+ }
+@@ -209,7 +241,7 @@ void Release()
+ void LoadModel(const std::string modelDirectoryName)
+ {
+     // モデルのディレクトリを指定
+-    _currentModelDirectory = _executeAbsolutePath + LAppDefine::ResourcesPath + modelDirectoryName + "/";
++    _currentModelDirectory = _rootDirectory + LAppDefine::ResourcesPath + modelDirectoryName + "/";
+     // モデルデータの新規生成
+     _userModel = new CubismUserModelExtend(modelDirectoryName, _currentModelDirectory);
index f681113..947e4c7 100755 (executable)
@@ -1,5 +1,5 @@
 #!/bin/sh
 
 mkdir -p demo_clean
-cp -p -r CubismSdkForNative-4-r.7/Samples/OpenGL/Demo/proj.linux.cmake/* ./demo_clean/
+cp -p -r CubismSdkForNative-5-r.1/Samples/OpenGL/Demo/proj.linux.cmake/* ./demo_clean/
 diff -pruN --exclude build ./demo_clean ./demo_dev > ./demo.patch