/** * Copyright(c) Live2D Inc. All rights reserved. * * Use of this source code is governed by the Live2D Open Software license * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. */ #pragma once #include #include #include #include #include #include "LAppWavFileHandler.hpp" /** * @brief ユーザーが実際に使用するモデルの実装クラス
* モデル生成、機能コンポーネント生成、更新処理とレンダリングの呼び出しを行う。 * */ class LAppModel : public Csm::CubismUserModel { public: /** * @brief コンストラクタ */ LAppModel(); /** * @brief デストラクタ * */ virtual ~LAppModel(); /** * @brief 获得Idle动画总数量 * @author Misaki * @return int */ int getIdleMotionCount(); /** * @brief 获得TapBody动画总数量 * @author Misaki * @return int */ int getTapBodyMotionCount(); /** * @brief 获取 Live2D 模型的 Canvas 宽度像素 (在 Live2D 坐标系下) * @return Canvas 宽度 */ [[nodiscard]] Live2D::Cubism::Framework::csmFloat32 GetModelCanvasWidthPixel() const { // _model 是 CubismModel 的基类指针 return _model ? _model->GetCanvasWidthPixel() : 0.0f; } /** * @brief 获取 Live2D 模型的 Canvas 高度像素 (在 Live2D 坐标系下) * @return Canvas 高度 */ [[nodiscard]] Live2D::Cubism::Framework::csmFloat32 GetModelCanvasHeightPixel() const { return _model ? _model->GetCanvasHeightPixel() : 0.0f; } /** * @brief 启动唇形同步并播放指定的 WAV 文件 * @param filePath WAV 文件的路径(csmString 类型) * @author Misaki */ void StartLipSync(const Csm::csmString& filePath); /** * @brief 停止唇形同步并停止播放指定的 WAV 文件 * @author Misaki */ void StopLipSync(); /** * @brief 获取模型是否有命中区域定义 * @return 是否有命中区域 */ [[nodiscard]] bool HasHitAreas() const; /** * @brief 检测点是否在模型的任何可见部分上 * @param x 视图坐标X * @param y 视图坐标Y * @return 是否命中 */ [[nodiscard]] bool IsPointOnModel(Csm::csmFloat32 x, Csm::csmFloat32 y); /** * @brief model3.jsonが置かれたディレクトリとファイルパスからモデルを生成する \n * 从 model3.json 所在的目录和文件路径生成模型 */ void LoadAssets(const Csm::csmChar* dir, const Csm::csmChar* fileName); /** * @brief レンダラを再構築する * */ void ReloadRenderer(); /** * @brief モデルの更新処理。モデルのパラメータから描画状態を決定する。 * */ void Update(); /** * @brief モデルを描画する処理。モデルを描画する空間のView-Projection行列を渡す。 * * @param[in] matrix View-Projection行列 */ void Draw(Csm::CubismMatrix44& matrix); /** * @brief 引数で指定したモーションの再生を開始する。 * * @param[in] group モーショングループ名 * @param[in] no グループ内の番号 * @param[in] priority 優先度 * @param[in] onFinishedMotionHandler モーション再生終了時に呼び出されるコールバック関数。NULLの場合、呼び出されない。 * @return 開始したモーションの識別番号を返す。個別のモーションが終了したか否かを判定するIsFinished()の引数で使用する。開始できない時は「-1」 */ Csm::CubismMotionQueueEntryHandle StartMotion(const Csm::csmChar* group, Csm::csmInt32 no, Csm::csmInt32 priority, Csm::ACubismMotion::FinishedMotionCallback onFinishedMotionHandler = NULL); /** * @brief 开始播放随机选择的动画。 * * @param[in] group 动画组名称 * @param[in] priority 优先级 * @param[in] onFinishedMotionHandler 动画播放结束时被调用的回调函数。如果为NULL,则不被调用。 * @return 返回开始播放的动画的标识编号。用于作为判断特定动画是否结束的IsFinished()函数的参数。如果无法开始播放,则返回「-1」 */ Csm::CubismMotionQueueEntryHandle StartRandomMotion(const Csm::csmChar* group, Csm::csmInt32 priority, Csm::ACubismMotion::FinishedMotionCallback onFinishedMotionHandler = NULL); /** * @brief 引数で指定した表情モーションをセットする * * @param expressionID 表情モーションのID */ void SetExpression(const Csm::csmChar* expressionID); /** * @brief ランダムに選ばれた表情モーションをセットする * */ void SetRandomExpression(); /** * @brief イベントの発火を受け取る * */ virtual void MotionEventFired(const Live2D::Cubism::Framework::csmString& eventValue); /** * @brief 当たり判定テスト。
* 指定IDの頂点リストから矩形を計算し、座標が矩形範囲内か判定する。 * * @param[in] hitAreaName 当たり判定をテストする対象のID * @param[in] x 判定を行うX座標 * @param[in] y 判定を行うY座標 */ virtual Csm::csmBool HitTest(const Csm::csmChar* hitAreaName, Csm::csmFloat32 x, Csm::csmFloat32 y); /** * @brief 別ターゲットに描画する際に使用するバッファの取得 */ Csm::Rendering::CubismOffscreenSurface_OpenGLES2& GetRenderBuffer(); /** * @brief .moc3ファイルの整合性をチェックする * * @param[in] mocName MOC3ファイル名 * @return MOC3に整合性があれば'true'、そうでなければ'false'。 */ Csm::csmBool HasMocConsistencyFromFile(const Csm::csmChar* mocFileName); protected: /** * @brief モデルを描画する処理。モデルを描画する空間のView-Projection行列を渡す。 * */ void DoDraw(); private: /** * @brief 使用Drawable检测(当没有命中区域时使用) * @param x 视图坐标X * @param y 视图坐标Y * @return 是否命中 */ [[nodiscard]] bool IsPointOnDrawable(Csm::csmFloat32 x, Csm::csmFloat32 y); private: /** * @brief model3.jsonからモデルを生成する。
* model3.jsonの記述に従ってモデル生成、モーション、物理演算などのコンポーネント生成を行う。 * * @param[in] setting ICubismModelSettingのインスタンス * */ void SetupModel(Csm::ICubismModelSetting* setting); /** * @brief OpenGLのテクスチャユニットにテクスチャをロードする * */ void SetupTextures(); /** * @brief モーションデータをグループ名から一括でロードする。
* モーションデータの名前は内部でModelSettingから取得する。 * * @param[in] group モーションデータのグループ名 */ void PreloadMotionGroup(const Csm::csmChar* group); /** * @brief モーションデータをグループ名から一括で解放する。
* モーションデータの名前は内部でModelSettingから取得する。 * * @param[in] group モーションデータのグループ名 */ void ReleaseMotionGroup(const Csm::csmChar* group) const; /** * @brief すべてのモーションデータの解放 * * すべてのモーションデータを解放する。 */ void ReleaseMotions(); /** * @brief すべての表情データの解放 * * すべての表情データを解放する。 */ void ReleaseExpressions(); Csm::ICubismModelSetting* _modelSetting; ///< モデルセッティング情報 Csm::csmString _modelHomeDir; ///< モデルセッティングが置かれたディレクトリ Csm::csmFloat32 _userTimeSeconds; ///< デルタ時間の積算値[秒] Csm::csmVector _eyeBlinkIds; ///< モデルに設定されたまばたき機能用パラメータID Csm::csmVector _lipSyncIds; ///< モデルに設定されたリップシンク機能用パラメータID Csm::csmMap _motions; ///< 読み込まれているモーションのリスト Csm::csmMap _expressions; ///< 読み込まれている表情のリスト Csm::csmVector _hitArea; Csm::csmVector _userArea; const Csm::CubismId* _idParamAngleX; ///< パラメータID: ParamAngleX const Csm::CubismId* _idParamAngleY; ///< パラメータID: ParamAngleX const Csm::CubismId* _idParamAngleZ; ///< パラメータID: ParamAngleX const Csm::CubismId* _idParamBodyAngleX; ///< パラメータID: ParamBodyAngleX const Csm::CubismId* _idParamEyeBallX; ///< パラメータID: ParamEyeBallX const Csm::CubismId* _idParamEyeBallY; ///< パラメータID: ParamEyeBallXY LAppWavFileHandler _wavFileHandler; ///< wavファイルハンドラ WAV文件处理器 // 低通滤波器参数 Live2D::Cubism::Framework::csmFloat32 alpha = 0.8f; // 滤波系数,范围在0到1之间,值越小,平滑效果越强 Live2D::Cubism::Framework::csmFloat32 filteredValue = 0.0f; // 滤波后的值 Csm::Rendering::CubismOffscreenSurface_OpenGLES2 _renderBuffer; ///< フレームバッファ以外の描画先 };