1 /*---------------------------------------------------------------------------* 2 Project: NintendoWare 3 File: gfx_Skeleton.h 4 5 Copyright (C)2009-2010 Nintendo Co., Ltd./HAL Laboratory, Inc. All rights reserved. 6 7 These coded instructions, statements, and computer programs contain 8 proprietary information of Nintendo of America Inc. and/or Nintendo 9 Company Ltd., and are protected by Federal copyright law. They may 10 not be disclosed to third parties or copied or duplicated in any form, 11 in whole or in part, without the prior written consent of Nintendo. 12 13 $Revision: 25777 $ 14 *---------------------------------------------------------------------------*/ 15 16 #ifndef NW_GFX_SKELETON_H_ 17 #define NW_GFX_SKELETON_H_ 18 19 #include <nw/gfx/gfx_SceneObject.h> 20 #include <nw/gfx/res/gfx_ResSkeleton.h> 21 #include <nw/ut/ut_Signal.h> 22 23 namespace nw 24 { 25 namespace math 26 { 27 struct MTX34; 28 struct Transform3; 29 } 30 31 namespace gfx 32 { 33 34 class SkeletalModel; 35 class CalculatedTransform; 36 37 //--------------------------------------------------------------------------- 38 //! @brief SkeletalModel 内の階層構造を表すインターフェースです。 39 //! 40 //! ISkeleton は廃止され Skeleton に変更されました。 41 //--------------------------------------------------------------------------- 42 class Skeleton : public SceneObject 43 { 44 private: 45 NW_DISALLOW_COPY_AND_ASSIGN(Skeleton); 46 47 public: 48 NW_UT_RUNTIME_TYPEINFO; 49 50 //! @brief マトリクス計算時に呼ばれるコールバック用シグナルの定義です。 51 //! 52 //! @sa PreCalculateMatrixSignal 53 //! @sa PostCalculateMatrixSignal 54 typedef ut::Signal2<void, Skeleton*, int> CalculateMatrixSignal; 55 56 //! @brief マトリクス計算時に呼ばれるコールバック用スロットの定義です。 57 typedef CalculateMatrixSignal::SlotType CalculateMatrixSlot; 58 59 //! 動きを付けられるポーズを表すクラスです。 60 class TransformPose 61 { 62 private: 63 NW_DISALLOW_COPY_AND_ASSIGN(TransformPose); 64 65 public: 66 //! 計算済みトランスフォームを表す定義です。 67 typedef CalculatedTransform Transform; 68 //! トランスフォームの配列を表す定義です。 69 typedef ut::MoveArray<Transform> TransformArray; 70 //! トランスフォームの配列の範囲を表す定義です。 71 typedef std::pair<TransformArray::iterator, TransformArray::iterator> TransformRange; 72 //! トランスフォームの配列の範囲を表す定義です。 73 typedef std::pair<TransformArray::const_iterator, TransformArray::const_iterator> ConstTransformRange; 74 75 //! コンストラクタです。 TransformPose()76 TransformPose() {} 77 78 //! コンストラクタです。 TransformPose(TransformArray & transforms)79 explicit TransformPose(TransformArray& transforms) : m_Transforms(transforms) {} 80 81 //! ボーンの数を取得します。 GetBonesCount()82 int GetBonesCount() const { return m_Transforms.Size(); } 83 84 //! トランスフォームを取得します。 GetTransform(int index,Transform ** transform)85 bool GetTransform(int index, Transform** transform) 86 { 87 if (index < 0 || this->GetBonesCount() <= index) { return false; } 88 *transform = &this->m_Transforms[index]; 89 return true; 90 } 91 92 //! トランスフォームを取得します。 GetTransform(int index,const Transform ** transform)93 bool GetTransform(int index, const Transform** transform) const 94 { 95 if (index < 0 || this->GetBonesCount() <= index) { return false; } 96 *transform = &this->m_Transforms[index]; 97 return true; 98 } 99 100 //! トランスフォームを取得します。 GetTransform(int index)101 Transform* GetTransform(int index) 102 { 103 return &this->m_Transforms[index]; 104 } 105 106 //! トランスフォームを取得します。 GetTransform(int index)107 const Transform* GetTransform(int index) const 108 { 109 return &this->m_Transforms[index]; 110 } 111 112 //! トランスフォームの先頭を指すイテレータを取得します。 GetBeginTransform()113 TransformArray::iterator GetBeginTransform() { return m_Transforms.Begin(); } 114 115 //! トランスフォームの終端を指すイテレータを取得します。 GetEndTransform()116 TransformArray::iterator GetEndTransform() { return m_Transforms.End(); } 117 118 //! トランスフォームの先頭と終端を指すイテレータを取得します。 GetAllTransforms()119 TransformRange GetAllTransforms() 120 { 121 return TransformRange(m_Transforms.Begin(), m_Transforms.End()); 122 } 123 124 //! トランスフォームの先頭と終端を指すイテレータを取得します。 GetAllTransforms()125 ConstTransformRange GetAllTransforms() const 126 { 127 return ConstTransformRange(m_Transforms.Begin(), m_Transforms.End()); 128 } 129 130 private: 131 TransformArray m_Transforms; 132 }; 133 134 //! スケルトンのマトリクスを表すクラスです。 135 class MatrixPose 136 { 137 private: 138 NW_DISALLOW_COPY_AND_ASSIGN(MatrixPose); 139 140 public: 141 //! マトリクスの配列を表す定義です。 142 typedef ut::MoveArray<math::MTX34> MatrixArray; 143 //! マトリクスの配列の範囲を表す定義です。 144 typedef std::pair<MatrixArray::iterator, MatrixArray::iterator> MatrixRange; 145 //! マトリクスの配列の範囲を表す定義です。 146 typedef std::pair<MatrixArray::const_iterator, MatrixArray::const_iterator> ConstMatrixRange; 147 148 //! コンストラクタです。 MatrixPose()149 MatrixPose() {} 150 151 //! コンストラクタです。 MatrixPose(MatrixArray & matrices)152 explicit MatrixPose(MatrixArray& matrices) : m_Matrices(matrices) {} 153 154 //! ボーンの数を取得します。 GetBonesCount()155 int GetBonesCount() const { return m_Matrices.Size(); } 156 157 //! マトリクスを取得します。 GetMatrix(int index,math::MTX34 ** matrix)158 bool GetMatrix(int index, math::MTX34** matrix) 159 { 160 if (index < 0 || this->GetBonesCount() <= index) { return false; } 161 *matrix = &this->m_Matrices[index]; 162 return true; 163 } 164 165 //! マトリクスを取得します。 GetMatrix(int index,const math::MTX34 ** matrix)166 bool GetMatrix(int index, const math::MTX34** matrix) const 167 { 168 if (index < 0 || this->GetBonesCount() <= index) { return false; } 169 *matrix = &this->m_Matrices[index]; 170 return true; 171 } 172 173 //! マトリクスを取得します。 GetMatrix(int index)174 math::MTX34* GetMatrix(int index) 175 { 176 return &this->m_Matrices[index]; 177 } 178 179 //! マトリクスを取得します。 GetMatrix(int index)180 const math::MTX34* GetMatrix(int index) const 181 { 182 return &this->m_Matrices[index]; 183 } 184 185 //! マトリクスの先頭を指すイテレータを取得します。 GetBeginMatrix()186 MatrixArray::iterator GetBeginMatrix() { return m_Matrices.Begin(); } 187 188 //! マトリクスの終端を指すイテレータを取得します。 GetEndMatrix()189 MatrixArray::iterator GetEndMatrix() { return m_Matrices.End(); } 190 191 //! マトリクスの先頭と終端を指すイテレータを取得します。 GetAllMatrices()192 MatrixRange GetAllMatrices() 193 { 194 return MatrixRange(m_Matrices.Begin(), m_Matrices.End()); 195 } 196 197 //! マトリクスの先頭と終端を指すイテレータを取得します。 GetAllMatrices()198 ConstMatrixRange GetAllMatrices() const 199 { 200 return ConstMatrixRange(m_Matrices.Begin(), m_Matrices.End()); 201 } 202 203 private: 204 MatrixArray m_Matrices; 205 }; 206 207 //! スケルトンの最初のポーズを表すクラスです。 208 class OriginalPose 209 { 210 private: 211 NW_DISALLOW_COPY_AND_ASSIGN(OriginalPose); 212 213 public: 214 //! nw::math::Transform3 を表す定義です。 215 typedef math::Transform3 Transform; 216 217 //! コンストラクタです。 OriginalPose(ResSkeleton resource)218 explicit OriginalPose(ResSkeleton resource) : m_Resource(resource) {} 219 220 //! ボーンの数を取得します。 GetBonesCount()221 int GetBonesCount() const { return m_Resource.GetBonesCount(); } 222 223 //! トランスフォームを取得します。 GetTransform(int index,Transform ** transform)224 bool GetTransform(int index, Transform** transform) 225 { 226 if (index < 0 || this->GetBonesCount() <= index) { return false; } 227 ResBone bone = m_Resource.GetBones(index); 228 if (!bone.IsValid()) { return false; } 229 *transform = &bone.GetTransform(); 230 return true; 231 } 232 233 //! トランスフォームを取得します。 GetTransform(int index,const Transform ** transform)234 bool GetTransform(int index, const Transform** transform) const 235 { 236 if (index < 0 || this->GetBonesCount() <= index) { return false; } 237 ResBone bone = m_Resource.GetBones(index); 238 if (!bone.IsValid()) { return false; } 239 *transform = &bone.GetTransform(); 240 return true; 241 } 242 243 //! トランスフォームを取得します。 GetTransform(int index)244 Transform* GetTransform(int index) 245 { 246 return &m_Resource.GetBones(index).GetTransform(); 247 } 248 249 //! トランスフォームを取得します。 GetTransform(int index)250 const Transform* GetTransform(int index) const 251 { 252 return &m_Resource.GetBones(index).GetTransform(); 253 } 254 255 private: 256 ResSkeleton m_Resource; 257 }; 258 259 //---------------------------------------- 260 //! @name リソース 261 //@{ 262 263 //! スケルトンのリソースを取得します。 GetResSkeleton()264 ResSkeleton GetResSkeleton() 265 { 266 return ResStaticCast<ResSkeleton>(this->GetResSceneObject()); 267 } 268 269 //! スケルトンのリソースを取得します。 GetResSkeleton()270 const ResSkeleton GetResSkeleton() const 271 { 272 return ResStaticCast<ResSkeleton>(this->GetResSceneObject()); 273 } 274 275 //@} 276 277 //---------------------------------------- 278 //! @name 更新 279 //@{ 280 281 //! @brief スケルトンが更新済みかどうかを取得します。 IsUpdated()282 bool IsUpdated() 283 { 284 return this->m_IsUpdated; 285 } 286 287 //! @brief スケルトンが更新済みかどうかを設定します。 SetUpdated(bool isUpdated)288 void SetUpdated(bool isUpdated) 289 { 290 this->m_IsUpdated = isUpdated; 291 } 292 293 //@} 294 295 //---------------------------------------- 296 //! @name 所有者 297 //@{ 298 299 //! 所有者となるスケルタルモデルを取得します。 GetOwnerSkeletalModel()300 const SkeletalModel* GetOwnerSkeletalModel() const { return m_OwnerSkeletalModel; } 301 302 //! 所有者となるスケルタルモデルを取得します。 GetOwnerSkeletalModel()303 SkeletalModel* GetOwnerSkeletalModel() { return m_OwnerSkeletalModel; } 304 305 //! 所有者となるスケルタルモデルを設定します。 SetOwnerSkeletalModel(SkeletalModel * ownerSkeletalModel)306 void SetOwnerSkeletalModel(SkeletalModel* ownerSkeletalModel) 307 { 308 m_OwnerSkeletalModel = ownerSkeletalModel; 309 } 310 311 //@} 312 313 //---------------------------------------- 314 //! @name ポーズ 315 //@{ 316 317 //! @brief ローカルトランスフォームのポーズを取得します。 318 //! 319 //! @return ローカルトランスフォームのポーズです。 320 //! 321 virtual TransformPose& LocalTransformPose() = 0; 322 323 //! @brief ローカルトランスフォームのポーズを取得します。 324 //! 325 //! @return ローカルトランスフォームのポーズです。 326 //! 327 virtual const TransformPose& LocalTransformPose() const = 0; 328 329 //! @brief ワールドトランスフォームのポーズを取得します。 330 //! 331 //! @return ワールドトランスフォームのポーズです。 332 //! 333 virtual TransformPose& WorldTransformPose() = 0; 334 335 //! @brief ワールドトランスフォームのポーズを取得します。 336 //! 337 //! @return ワールドトランスフォームのポーズです。 338 //! 339 virtual const TransformPose& WorldTransformPose() const = 0; 340 341 //! @brief ワールドマトリクスのポーズを取得します。 342 //! 343 //! @return ワールドマトリクスのポーズです。 344 //! 345 virtual MatrixPose& WorldMatrixPose() = 0; 346 347 //! @brief ワールドマトリクスのポーズを取得します。 348 //! 349 //! @return ワールドマトリクスのポーズです。 350 //! 351 virtual const MatrixPose& WorldMatrixPose() const = 0; 352 353 //! @brief スキニングマトリクスのポーズを取得します。 354 //! 355 //! @return スキニングマトリクスのポーズです。 356 //! 357 virtual MatrixPose& SkiningMatrixPose() = 0; 358 359 //! @brief スキニングマトリクスのポーズを取得します。 360 //! 361 //! @return スキニングマトリクスのポーズです。 362 //! 363 virtual const MatrixPose& SkiningMatrixPose() const = 0; 364 365 //! @brief オリジナルポーズを取得します。 366 //! 367 //! @return オリジナルポーズです。 368 //! 369 virtual OriginalPose& LocalOriginalPose() = 0; 370 371 //! @brief オリジナルポーズを取得します。 372 //! 373 //! @return オリジナルポーズです。 374 //! 375 virtual const OriginalPose& LocalOriginalPose() const = 0; 376 377 //@} 378 379 //---------------------------------------- 380 //! @name コールバック 381 //@{ 382 383 //! @brief ボーンのマトリクス計算前のシグナルを取得します。 384 //! 385 //! @sa CalculateMatrixSignal PreCalculateMatrixSignal()386 CalculateMatrixSignal& PreCalculateMatrixSignal() { return *m_PreCalculateMatrixSignal; } 387 388 //! @brief ボーンのマトリクス計算前のシグナルを取得します。 389 //! 390 //! @sa CalculateMatrixSignal PreCalculateMatrixSignal()391 const CalculateMatrixSignal& PreCalculateMatrixSignal() const { return *m_PreCalculateMatrixSignal; } 392 393 //! @brief ボーンのマトリクス計算後のシグナルを取得します。 394 //! 395 //! @sa CalculateMatrixSignal PostCalculateMatrixSignal()396 CalculateMatrixSignal& PostCalculateMatrixSignal() { return *m_PostCalculateMatrixSignal; } 397 398 //! @brief ボーンのマトリクス計算後のシグナルを取得します。 399 //! 400 //! @sa CalculateMatrixSignal PostCalculateMatrixSignal()401 const CalculateMatrixSignal& PostCalculateMatrixSignal() const { return *m_PostCalculateMatrixSignal; } 402 403 //@} 404 405 protected: 406 //---------------------------------------- 407 //! @name コンストラクタ/デストラクタ 408 //@{ 409 410 //! コンストラクタです。 Skeleton(os::IAllocator * allocator,ResSkeleton resource,int maxCallbacks,bool isFixedSizeMemory)411 Skeleton( 412 os::IAllocator* allocator, 413 ResSkeleton resource, 414 int maxCallbacks, 415 bool isFixedSizeMemory) 416 : 417 SceneObject(allocator, resource), 418 m_PreCalculateMatrixSignal(NULL), 419 m_PostCalculateMatrixSignal(NULL), 420 m_IsUpdated(false) 421 { 422 this->SetOwnerSkeletalModel(NULL); 423 CreateCallbacks(allocator, maxCallbacks, isFixedSizeMemory); 424 } 425 426 //! デストラクタです。 ~Skeleton()427 virtual ~Skeleton() 428 { 429 SafeDestroy(this->m_PreCalculateMatrixSignal); 430 SafeDestroy(this->m_PostCalculateMatrixSignal); 431 } 432 433 //@} 434 435 //! @brief コンストラクタの実行に必要なメモリサイズを取得します。 436 //! 437 //! @details :private GetMemorySizeForConstruct(os::MemorySizeCalculator * pSize,int maxCallbacks)438 static void GetMemorySizeForConstruct( 439 os::MemorySizeCalculator* pSize, 440 int maxCallbacks) 441 { 442 // Skeleton::CreateCallbacks 443 if (maxCallbacks == 0) 444 { 445 CalculateMatrixSignal::GetMemorySizeForInvalidateSignalInternal(pSize); 446 CalculateMatrixSignal::GetMemorySizeForInvalidateSignalInternal(pSize); 447 } 448 else 449 { 450 CalculateMatrixSignal::GetMemorySizeForFixedSizedSignalInternal(pSize, maxCallbacks); 451 CalculateMatrixSignal::GetMemorySizeForFixedSizedSignalInternal(pSize, maxCallbacks); 452 } 453 } 454 455 private: 456 //! コールバック関数を生成します。 457 void CreateCallbacks(os::IAllocator* allocator, int maxCallbacks, bool isFixedSizeMemory); 458 459 SkeletalModel* m_OwnerSkeletalModel; 460 461 CalculateMatrixSignal* m_PreCalculateMatrixSignal; 462 CalculateMatrixSignal* m_PostCalculateMatrixSignal; 463 bool m_IsUpdated; 464 }; 465 466 } // namespace gfx 467 } // namespace nw 468 469 #endif // NW_GFX_SKELETON_H_ 470