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