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