/*---------------------------------------------------------------------------* Project: NintendoWare File: anim_AnimBlend.h Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. These coded instructions, statements, and computer programs contain proprietary information of Nintendo of America Inc. and/or Nintendo Company Ltd., and are protected by Federal copyright law. They may not be disclosed to third parties or copied or duplicated in any form, in whole or in part, without the prior written consent of Nintendo. $Revision: 22716 $ *---------------------------------------------------------------------------*/ #ifndef NW_ANIM_ANIMBLEND_H_ #define NW_ANIM_ANIMBLEND_H_ #include #include #include namespace nw { namespace anim { //--------------------------------------------------------------------------- //! @brief アニメーション結果のクラスです。 //--------------------------------------------------------------------------- class AnimResult { public: //! フラグの定義です。 enum Flags { FLAG_VALID_COMPONENT0_SHIFT = 0, //!< @details :private FLAG_VALID_COMPONENT1_SHIFT = 1, //!< @details :private FLAG_VALID_COMPONENT2_SHIFT = 2, //!< @details :private FLAG_VALID_COMPONENT3_SHIFT = 3, //!< @details :private FLAG_CONVERTED_SHIFT = 30, //!< @details :private //! 0 番目の成分のアニメーションが有効なら 1 となります。 FLAG_VALID_COMPONENT0 = 0x1 << FLAG_VALID_COMPONENT0_SHIFT, //! 1 番目の成分のアニメーションが有効なら 1 となります。 FLAG_VALID_COMPONENT1 = 0x1 << FLAG_VALID_COMPONENT1_SHIFT, //! 2 番目の成分のアニメーションが有効なら 1 となります。 FLAG_VALID_COMPONENT2 = 0x1 << FLAG_VALID_COMPONENT2_SHIFT, //! 3 番目の成分のアニメーションが有効なら 1 となります。 FLAG_VALID_COMPONENT3 = 0x1 << FLAG_VALID_COMPONENT3_SHIFT, //! 操作空間に変換されていれば 1 となります。 FLAG_CONVERTED = 0x1 << FLAG_CONVERTED_SHIFT }; //! 最大成分数です。 enum { MAX_COMPONENTS = 4 }; //---------------------------------------- //! @name コンストラクタ/デストラクタ //@{ //! コンストラクタです。 AnimResult() : m_Flags(0) {} //! デストラクタです。 virtual ~AnimResult() {} //@} //---------------------------------------- //! @name 取得/設定 //@{ //! フラグの値を直接取得します。 bit32 GetFlags() const { return m_Flags; } //! フラグの値を直接設定します。 void SetFlags(bit32 flags) { m_Flags = flags; } //! フラグが有効になっているか取得します。 bool IsEnabledFlags(bit32 flags) const { return ut::CheckFlag(m_Flags, flags); } //! フラグを有効に設定します。 void EnableFlags(bit32 flags) { m_Flags = ut::EnableFlag(m_Flags, flags); } //! フラグを無効に設定します。 void DisableFlags(bit32 flags) { m_Flags = ut::DisableFlag(m_Flags, flags); } //! フラグの有効/無効を設定します。 void EnableFlags(bit32 flags, bool enable) { if (enable) { m_Flags |= flags; } else { m_Flags &= ~flags; } } //! 全てのフラグを無効に設定します。 void ResetFlags() { m_Flags = 0; } //! 値バッファを取得します。 const void* GetValueBuffer() const { return m_ValueBuf; } //! 値バッファを取得します。 void* GetValueBuffer() { return m_ValueBuf; } //! オブジェクトの先頭から値バッファまでのオフセットをバイト数で取得します。 int GetOffsetToValueBuffer() const { return reinterpret_cast(GetValueBuffer()) - reinterpret_cast(this); } //@} private: bit32 m_Flags; // ResMemberAnim::GetPrimitiveSize() の最大値以上のサイズの領域 float m_ValueBuf[(sizeof(gfx::CalculatedTransform) + sizeof(float) - 1) / sizeof(float)]; }; //--------------------------------------------------------------------------- //! @brief アニメーションのブレンドオペレーションの基底クラスです。 //--------------------------------------------------------------------------- class AnimBlendOp { public: //! 基本ブレンド処理用のフラグの定義です。 //! //! :private enum Flags { VALID_SINGLE = AnimResult::FLAG_VALID_COMPONENT0, VALID_X = AnimResult::FLAG_VALID_COMPONENT0, VALID_Y = AnimResult::FLAG_VALID_COMPONENT1, VALID_Z = AnimResult::FLAG_VALID_COMPONENT2, VALID_W = AnimResult::FLAG_VALID_COMPONENT3, VALID_XY = VALID_X | VALID_Y, VALID_XYZ = VALID_X | VALID_Y | VALID_Z, VALID_XYZW = VALID_X | VALID_Y | VALID_Z | VALID_W, VALID_R = AnimResult::FLAG_VALID_COMPONENT0, VALID_G = AnimResult::FLAG_VALID_COMPONENT1, VALID_B = AnimResult::FLAG_VALID_COMPONENT2, VALID_A = AnimResult::FLAG_VALID_COMPONENT3, VALID_RGBA = VALID_R | VALID_G | VALID_B | VALID_A, CONVERTED = AnimResult::FLAG_CONVERTED }; //---------------------------------------- //! @name コンストラクタ/デストラクタ //@{ //! @brief コンストラクタです。 //! //! @param[in] hasBlend ブレンド処理があるかどうかです。 //! @param[in] hasPostBlend ブレンド後の処理があるかどうかです。 //! AnimBlendOp(bool hasBlend, bool hasPostBlend) : m_HasBlend(hasBlend), m_HasPostBlend(hasPostBlend) {} //! デストラクタです。 virtual ~AnimBlendOp() {} //@} //---------------------------------------- //! @name 取得/設定 //@{ //! @brief ブレンド処理があるかどうかを取得します。 //! //! @return ブレンド処理があるなら true を返します。 //! bool HasBlend() const { return m_HasBlend; } //! @brief ブレンド後の処理があるかどうかを取得します。 //! //! @return ブレンド後の処理があるなら true を返します。 //! bool HasPostBlend() const { return m_HasPostBlend; } //@} //---------------------------------------- //! @name ブレンド //@{ //! @brief ブレンド処理を行います。 //! //! @param[in,out] dst ブレンド処理結果です。 //! @param[in,out] dstWeights ブレンド処理結果の成分ごとの重みの累積値です。 //! 成分ごとの重みの累積値で再正規化を行う必要がなければ NULL を指定します。 //! @param[in] src ブレンド処理の入力です。 //! @param[in] srcWeights ブレンド処理の入力の重みです。 //! ブレンドオペレーションによって、全成分で共通の場合と、成分ごとに異なる場合があります。 //! //! @return ブレンド処理のループを継続するなら true を返します。 //! virtual bool Blend( AnimResult* dst, float* dstWeights, const AnimResult* src, const float* srcWeights) const { (void)dst; (void)dstWeights; (void)src; (void)srcWeights; return true; } //! @brief ブレンド後の処理を行います。 //! //! @param[in,out] result ブレンド処理結果です。 //! @param[in] weights ブレンド処理結果の成分ごとの重みの累積値です。 //! 成分ごとの重みの累積値で再正規化を行う必要がなければ NULL を指定します。 //! //! @return 成功すれば true を返します。 //! virtual bool PostBlend(AnimResult* result, const float* weights) const { (void)result; (void)weights; return true; }; //! @brief 上書き処理を行います。 //! //! @param[in,out] dst ブレンド処理結果です。 //! @param[in] src ブレンド処理の入力です。 //! //! @return すべての成分が上書きされたら true を返します。 //! virtual bool Override(AnimResult* dst, const AnimResult* src) const = 0; //@} //---------------------------------------- //! @name 適用 //@{ //! @brief ブレンド処理結果を対象に適用します。 //! //! @param[out] target ブレンド処理結果を適用する対象です。 //! @param[in] result ブレンド処理結果です。 //! virtual void Apply(void* target, const AnimResult* result) const = 0; //! @brief 対象を AnimResult に変換します。 //! //! @param[out] result 出力の AnimResult です。 //! @param[in] source 変換元へのポインタです。 //! //! :private virtual void ConvertToAnimResult(AnimResult* result, const void* source) const = 0; //@} protected: //---------------------------------------- //! @name 基本ブレンド処理 //@{ //! FloatVector のブレンド処理を行います。 //! //! :private bool BlendFloatVector( AnimResult* dst, const AnimResult* src, float srcWeight, int compCount ) const; //! FloatVector の上書き処理を行います。 //! //! :private bool OverrideFloatVector( AnimResult* dst, const AnimResult* src, int compCount, bit32 allCompValidFlag ) const; //@} //---------------------------------------- //! @name 基本適用処理 //@{ //! FloatVector のブレンド処理結果を対象に適用します。 //! //! :private void ApplyFloatVector(void* target, const AnimResult* result, int compCount) const; //! @brief FloatVector を AnimResult に変換します。 //! //! @param[out] result 出力の AnimResult です。 //! @param[in] source 変換元へのポインタです。 //! //! :private void ConvertFloatVectorToAnimResult(AnimResult* result, const void* source, int compCount) const; //@} private: bool m_HasBlend; bool m_HasPostBlend; }; //--------------------------------------------------------------------------- //! @brief bool アニメーションのブレンドオペレーションのクラスです。 //--------------------------------------------------------------------------- class AnimBlendOpBool : public AnimBlendOp { public: //---------------------------------------- //! @name コンストラクタ/デストラクタ //@{ //! コンストラクタです。 AnimBlendOpBool() : AnimBlendOp(true, false) {} //! デストラクタです。 virtual ~AnimBlendOpBool() {} //@} //---------------------------------------- //! @name ブレンド //@{ virtual bool Blend( AnimResult* dst, float* dstWeights, const AnimResult* src, const float* srcWeights) const; virtual bool Override(AnimResult* dst, const AnimResult* src) const { *reinterpret_cast(dst->GetValueBuffer()) = *reinterpret_cast(src->GetValueBuffer()); dst->SetFlags(VALID_SINGLE); return true; } //@} //---------------------------------------- //! @name 適用 //@{ virtual void Apply(void* target, const AnimResult* result) const { *reinterpret_cast(target) = *reinterpret_cast(result->GetValueBuffer()); } virtual void ConvertToAnimResult(AnimResult* result, const void* source) const { *reinterpret_cast(result->GetValueBuffer()) = *reinterpret_cast(source); result->SetFlags(VALID_SINGLE); } //@} }; //--------------------------------------------------------------------------- //! @brief int アニメーションのブレンドオペレーションのクラスです。 //--------------------------------------------------------------------------- class AnimBlendOpInt : public AnimBlendOp { public: //---------------------------------------- //! @name コンストラクタ/デストラクタ //@{ //! コンストラクタです。 AnimBlendOpInt() : AnimBlendOp(false, false) {} // ブレンド処理なし(常に上書き) //! デストラクタです。 virtual ~AnimBlendOpInt() {} //@} //---------------------------------------- //! @name ブレンド //@{ virtual bool Override(AnimResult* dst, const AnimResult* src) const { *reinterpret_cast(dst->GetValueBuffer()) = *reinterpret_cast(src->GetValueBuffer()); dst->SetFlags(VALID_SINGLE); return true; } //@} //---------------------------------------- //! @name 適用 //@{ virtual void Apply(void* target, const AnimResult* result) const { *reinterpret_cast(target) = *reinterpret_cast(result->GetValueBuffer()); } virtual void ConvertToAnimResult(AnimResult* result, const void* source) const { *reinterpret_cast(result->GetValueBuffer()) = *reinterpret_cast(source); result->SetFlags(VALID_SINGLE); } //@} }; //--------------------------------------------------------------------------- //! @brief float アニメーションのブレンドオペレーションのクラスです。 //--------------------------------------------------------------------------- class AnimBlendOpFloat : public AnimBlendOp { public: //---------------------------------------- //! @name コンストラクタ/デストラクタ //@{ //! コンストラクタです。 AnimBlendOpFloat() : AnimBlendOp(true, false) {} //! デストラクタです。 virtual ~AnimBlendOpFloat() {} //@} //---------------------------------------- //! @name ブレンド //@{ virtual bool Blend( AnimResult* dst, float* dstWeights, const AnimResult* src, const float* srcWeights) const; virtual bool Override(AnimResult* dst, const AnimResult* src) const { *reinterpret_cast(dst->GetValueBuffer()) = *reinterpret_cast(src->GetValueBuffer()); dst->SetFlags(VALID_SINGLE); return true; } //@} //---------------------------------------- //! @name 適用 //@{ virtual void Apply(void* target, const AnimResult* result) const { *reinterpret_cast(target) = *reinterpret_cast(result->GetValueBuffer()); } virtual void ConvertToAnimResult(AnimResult* result, const void* source) const { *reinterpret_cast(result->GetValueBuffer()) = *reinterpret_cast(source); result->SetFlags(VALID_SINGLE); } //@} }; //--------------------------------------------------------------------------- //! @brief Vector2 アニメーションのブレンドオペレーションのクラスです。 //--------------------------------------------------------------------------- class AnimBlendOpVector2 : public AnimBlendOp { public: //! 成分数の定義です。 enum { COMP_COUNT = 2 }; //! フラグの定義です。 enum { VALID_ALL = VALID_XY }; //---------------------------------------- //! @name コンストラクタ/デストラクタ //@{ //! コンストラクタです。 AnimBlendOpVector2() : AnimBlendOp(true, false) {} //! デストラクタです。 virtual ~AnimBlendOpVector2() {} //@} //---------------------------------------- //! @name ブレンド //@{ virtual bool Blend( AnimResult* dst, float* dstWeights, const AnimResult* src, const float* srcWeights) const { NW_ASSERT(src->GetFlags() & VALID_ALL); (void)dstWeights; return BlendFloatVector(dst, src, srcWeights[0], COMP_COUNT); } virtual bool Override(AnimResult* dst, const AnimResult* src) const { return OverrideFloatVector(dst, src, COMP_COUNT, VALID_ALL); } //@} //---------------------------------------- //! @name 適用 //@{ virtual void Apply(void* target, const AnimResult* result) const { ApplyFloatVector(target, result, COMP_COUNT); } virtual void ConvertToAnimResult(AnimResult* result, const void* source) const { ConvertFloatVectorToAnimResult(result, source, COMP_COUNT); } //@} }; //--------------------------------------------------------------------------- //! @brief Vector3 アニメーションのブレンドオペレーションのクラスです。 //--------------------------------------------------------------------------- class AnimBlendOpVector3 : public AnimBlendOp { public: //! 成分数の定義です。 enum { COMP_COUNT = 3 }; //! フラグの定義です。 enum { VALID_ALL = VALID_XYZ }; //---------------------------------------- //! @name コンストラクタ/デストラクタ //@{ //! コンストラクタです。 AnimBlendOpVector3() : AnimBlendOp(true, false) {} //! デストラクタです。 virtual ~AnimBlendOpVector3() {} //@} //---------------------------------------- //! @name ブレンド //@{ virtual bool Blend( AnimResult* dst, float* dstWeights, const AnimResult* src, const float* srcWeights) const { NW_ASSERT(src->GetFlags() & VALID_ALL); (void)dstWeights; return BlendFloatVector(dst, src, srcWeights[0], COMP_COUNT); } virtual bool Override(AnimResult* dst, const AnimResult* src) const { return OverrideFloatVector(dst, src, COMP_COUNT, VALID_ALL); } //@} //---------------------------------------- //! @name 適用 //@{ virtual void Apply(void* target, const AnimResult* result) const { ApplyFloatVector(target, result, COMP_COUNT); } virtual void ConvertToAnimResult(AnimResult* result, const void* source) const { ConvertFloatVectorToAnimResult(result, source, COMP_COUNT); } //@} }; //--------------------------------------------------------------------------- //! @brief RGBA カラーアニメーションのブレンドオペレーションのクラスです。 //--------------------------------------------------------------------------- class AnimBlendOpRgbaColor : public AnimBlendOp { public: //! 成分数です。 enum { COMPONENT_COUNT = 4 }; //---------------------------------------- //! @name コンストラクタ/デストラクタ //@{ //! コンストラクタです。 AnimBlendOpRgbaColor() : AnimBlendOp(true, false) {} //! デストラクタです。 virtual ~AnimBlendOpRgbaColor() {} //@} //---------------------------------------- //! @name ブレンド //@{ virtual bool Blend( AnimResult* dst, float* dstWeights, const AnimResult* src, const float* srcWeights) const; virtual bool Override(AnimResult* dst, const AnimResult* src) const; //@} //---------------------------------------- //! @name 適用 //@{ virtual void Apply(void* target, const AnimResult* result) const; virtual void ConvertToAnimResult(AnimResult* result, const void* source) const; //@} }; //--------------------------------------------------------------------------- //! @brief テクスチャパターンアニメーションのブレンドオペレーションのクラスです。 //--------------------------------------------------------------------------- class AnimBlendOpTexture : public AnimBlendOp { public: //---------------------------------------- //! @name コンストラクタ/デストラクタ //@{ //! コンストラクタです。 AnimBlendOpTexture() : AnimBlendOp(false, false) {} // ブレンド処理なし(常に上書き) //! デストラクタです。 virtual ~AnimBlendOpTexture() {} //@} //---------------------------------------- //! @name ブレンド //@{ virtual bool Override(AnimResult* dst, const AnimResult* src) const { ut::Offset* dstOffset = reinterpret_cast(dst->GetValueBuffer()); const ut::Offset* srcOffset = reinterpret_cast(src->GetValueBuffer()); dstOffset->set_ptr(srcOffset->to_ptr()); dst->SetFlags(VALID_SINGLE); return true; } //@} //---------------------------------------- //! @name 適用 //@{ virtual void Apply(void* target, const AnimResult* result) const { ut::Offset* dstOffset = reinterpret_cast(target); const ut::Offset* srcOffset = reinterpret_cast(result->GetValueBuffer()); dstOffset->set_ptr(srcOffset->to_ptr()); } virtual void ConvertToAnimResult(AnimResult* result, const void* source) const { ut::Offset* dstOffset = reinterpret_cast(result->GetValueBuffer()); const ut::Offset* srcOffset = reinterpret_cast(source); dstOffset->set_ptr(srcOffset->to_ptr()); result->SetFlags(VALID_SINGLE); } //@} }; } /* namespace anim */ } /* namespace nw */ #endif /* NW_ANIM_ANIMBLEND_H_ */