1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_WorldMatrixUpdater.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: 24186 $
14 *---------------------------------------------------------------------------*/
15
16 #ifndef NW_GFX_WORLD_MATRIX_UPDATER_H_
17 #define NW_GFX_WORLD_MATRIX_UPDATER_H_
18
19 #include <nw/gfx/gfx_GfxObject.h>
20
21 #include <nw/ut/ut_MoveArray.h>
22 #include <nw/math.h>
23
24 namespace nw
25 {
26 namespace os
27 {
28 class IAllocator;
29 } // os
30 namespace gfx
31 {
32
33 class CalculatedTransform;
34
35 //---------------------------------------------------------------------------
36 //! @brief ワールドマトリクスを更新するためのクラスです。
37 //---------------------------------------------------------------------------
38 class WorldMatrixUpdater : public GfxObject
39 {
40 private:
41 NW_DISALLOW_COPY_AND_ASSIGN(WorldMatrixUpdater);
42
43 public:
44 //---------------------------------------------------------------------------
45 //! @brief ボーンのスケーリング方式の定義です。
46 //---------------------------------------------------------------------------
47 enum ScalingRule
48 {
49 SCALING_RULE_STANDARD, //!< 標準的なスケーリング方式です。
50 SCALING_RULE_MAYA, //!< Mayaのスケーリング方式です。
51 SCALING_RULE_SOFTIMAGE //!< Softimageのスケーリング方式です。
52 };
53
54 public:
55 //! ワールドマトリクスアップデータを構築するクラスです。
56 class Builder
57 {
58 public:
59 //! コンストラクタです。
Builder()60 Builder() {}
61
62 //! @brief ワールドマトリクスアップデータを生成します。
63 //!
64 //! @param[in] allocator アロケータです。
65 //!
66 //! @return 生成されたワールドマトリクスアップデータです。
67 //!
68 WorldMatrixUpdater* Create(os::IAllocator* allocator);
69
70 };
71
72 //! @brief Maya方式でワールドマトリクスを更新します。
73 //!
74 //! @param[out] worldMatrix 更新するワールドマトリクスです。
75 //! @param[out] worldTransform 更新する計算済みワールドトランスフォームです。
76 //! @param[in] localTransform 計算済みローカルトランスフォームです。
77 //! @param[in] parentWorldTransform 親の計算済みワールドトランスフォームです。
78 //! @param[in] parentLocalTransform 親の計算済みローカルトランスフォームです。
79 //! @param[in] isSSC MAYAのSSCによる計算を行うかどうかのフラグです。
80 //!
81 NW_INLINE void UpdateMaya(
82 math::MTX34* worldMatrix,
83 CalculatedTransform* worldTransform,
84 const CalculatedTransform& localTransform,
85 const CalculatedTransform& parentWorldTransform,
86 const CalculatedTransform& parentLocalTransform,
87 bool isSSC) const;
88
89 //! @brief XSI方式でワールドマトリクスを更新します。
90 //!
91 //! @param[out] worldMatrix 更新するワールドマトリクスです。
92 //! @param[out] worldTransform 更新する計算済みワールドトランスフォームです。
93 //! @param[in] localTransform 計算済みローカルトランスフォームです。
94 //! @param[in] parentWorldTransform 親の計算済みワールドトランスフォームです。
95 //! @param[in] parentLocalTransform 親の計算済みローカルトランスフォームです。
96 //!
97 NW_INLINE void UpdateXsi(
98 math::MTX34* worldMatrix,
99 CalculatedTransform* worldTransform,
100 const CalculatedTransform& localTransform,
101 const CalculatedTransform& parentWorldTransform,
102 const CalculatedTransform& parentLocalTransform) const;
103
104 //! @brief 通常の方式でワールドマトリクスを更新します。
105 //!
106 //! @param[out] worldMatrix 更新するワールドマトリクスです。
107 //! @param[out] worldTransform 更新する計算済みワールドトランスフォームです。
108 //! @param[in] localTransform 計算済みローカルトランスフォームです。
109 //! @param[in] parentWorldTransform 親の計算済みワールドトランスフォームです。
110 //! @param[in] parentLocalTransform 親の計算済みローカルトランスフォームです。
111 //!
112 NW_INLINE void UpdateBasic(
113 math::MTX34* worldMatrix,
114 CalculatedTransform* worldTransform,
115 const CalculatedTransform& localTransform,
116 const CalculatedTransform& parentWorldTransform,
117 const CalculatedTransform& parentLocalTransform) const;
118
119 private:
120 //! コンストラクタです。
121 WorldMatrixUpdater(
122 os::IAllocator* allocator);
123
124 //! デストラクタです。
125 virtual ~WorldMatrixUpdater();
126
127 void CalculateWorldXsi(
128 math::MTX34* transformMatrix,
129 math::VEC3* scale,
130 const CalculatedTransform& localTransform,
131 const CalculatedTransform& parentWorldTransform,
132 const CalculatedTransform& parentLocalTransform) const;
133
134 void CalculateWorldMayaSsc(
135 math::MTX34* transformMatrix,
136 math::VEC3* scale,
137 const CalculatedTransform& localTransform,
138 const CalculatedTransform& parentWorldTransform,
139 const CalculatedTransform& parentLocalTransform) const;
140
141 void CalculateWorldBasic(
142 math::MTX34* transformMatrix,
143 math::VEC3* scale,
144 const CalculatedTransform& localTransform,
145 const CalculatedTransform& parentWorldTransform,
146 const CalculatedTransform& parentLocalTransform) const;
147
148 template<typename TMatrix, typename UMatrix>
MultScale(TMatrix * dstMatrix,const UMatrix * srcMatrix,const math::VEC3 & scale)149 void MultScale(TMatrix* dstMatrix, const UMatrix* srcMatrix, const math::VEC3& scale) const
150 {
151 dstMatrix->f._00 = srcMatrix->f._00 * scale.x;
152 dstMatrix->f._10 = srcMatrix->f._10 * scale.x;
153 dstMatrix->f._20 = srcMatrix->f._20 * scale.x;
154
155 dstMatrix->f._01 = srcMatrix->f._01 * scale.y;
156 dstMatrix->f._11 = srcMatrix->f._11 * scale.y;
157 dstMatrix->f._21 = srcMatrix->f._21 * scale.y;
158
159 dstMatrix->f._02 = srcMatrix->f._02 * scale.z;
160 dstMatrix->f._12 = srcMatrix->f._12 * scale.z;
161 dstMatrix->f._22 = srcMatrix->f._22 * scale.z;
162 }
163
164 template<typename TMatrix>
ScaleMatrix(TMatrix * dstMatrix,const math::VEC3 & scale)165 void ScaleMatrix(TMatrix* dstMatrix, const math::VEC3& scale) const
166 {
167 dstMatrix->f._00 *= scale.x;
168 dstMatrix->f._10 *= scale.x;
169 dstMatrix->f._20 *= scale.x;
170
171 dstMatrix->f._01 *= scale.y;
172 dstMatrix->f._11 *= scale.y;
173 dstMatrix->f._21 *= scale.y;
174
175 dstMatrix->f._02 *= scale.z;
176 dstMatrix->f._12 *= scale.z;
177 dstMatrix->f._22 *= scale.z;
178 }
179
CopyTranslate(math::MTX34 * dstMatrix,const math::MTX34 & srcMatrix)180 void CopyTranslate(math::MTX34* dstMatrix, const math::MTX34& srcMatrix) const
181 {
182 dstMatrix->f._03 = srcMatrix.f._03;
183 dstMatrix->f._13 = srcMatrix.f._13;
184 dstMatrix->f._23 = srcMatrix.f._23;
185 }
186
AddTranslate(math::MTX34 * dstMatrix,const math::VEC3 & translate)187 void AddTranslate(math::MTX34* dstMatrix, const math::VEC3& translate) const
188 {
189 dstMatrix->f._03 += translate.x;
190 dstMatrix->f._13 += translate.y;
191 dstMatrix->f._23 += translate.z;
192 }
193
CompensateScale(math::VEC3 & scale)194 void CompensateScale(math::VEC3& scale) const
195 {
196 // Restrict scale to over 1 / 1000000
197 const float MinimumScale = 0.001f * 0.001f;
198 float mag = (scale.x * scale.x + scale.y * scale.y + scale.z * scale.z);
199
200 if (mag < MinimumScale)
201 {
202 scale.x = (scale.x < 0.0f) ? -MinimumScale : MinimumScale;
203 scale.y = (scale.y < 0.0f) ? -MinimumScale : MinimumScale;
204 scale.z = (scale.z < 0.0f) ? -MinimumScale : MinimumScale;
205 }
206 }
207 };
208
209 //----------------------------------------
210 NW_INLINE void
UpdateMaya(math::MTX34 * worldMatrix,CalculatedTransform * worldTransform,const CalculatedTransform & localTransform,const CalculatedTransform & parentWorldTransform,const CalculatedTransform & parentLocalTransform,bool isSSC)211 WorldMatrixUpdater::UpdateMaya(
212 math::MTX34* worldMatrix,
213 CalculatedTransform* worldTransform,
214 const CalculatedTransform& localTransform,
215 const CalculatedTransform& parentWorldTransform,
216 const CalculatedTransform& parentLocalTransform,
217 bool isSSC) const
218 {
219 NW_NULL_ASSERT(worldMatrix);
220 NW_NULL_ASSERT(worldTransform);
221
222 math::VEC3 scale;
223 // Update WorldTransform
224 if (isSSC)
225 {
226 CalculateWorldMayaSsc(
227 &worldTransform->m_TransformMatrix,
228 &scale,
229 localTransform,
230 parentWorldTransform,
231 parentLocalTransform
232 );
233 }
234 else
235 {
236 CalculateWorldBasic(
237 &worldTransform->m_TransformMatrix,
238 &scale,
239 localTransform,
240 parentWorldTransform,
241 parentLocalTransform
242 );
243 }
244
245 this->CompensateScale(scale);
246
247 worldTransform->m_Scale = scale;
248
249 // Update WorldMatrix
250 math::MTX34MultScale(worldMatrix, worldTransform->m_TransformMatrix, localTransform.m_Scale);
251
252 #if defined(NW_GFX_WORLD_MATRIX_FLAG_UPDATE_ENABLED)
253 worldTransform->UpdateFlags();
254 #else
255 worldTransform->ResetTransformFlags();
256 worldTransform->UpdateScaleFlags();
257 #endif
258 }
259
260 //----------------------------------------
261 NW_INLINE void
UpdateBasic(math::MTX34 * worldMatrix,CalculatedTransform * worldTransform,const CalculatedTransform & localTransform,const CalculatedTransform & parentWorldTransform,const CalculatedTransform & parentLocalTransform)262 WorldMatrixUpdater::UpdateBasic(
263 math::MTX34* worldMatrix,
264 CalculatedTransform* worldTransform,
265 const CalculatedTransform& localTransform,
266 const CalculatedTransform& parentWorldTransform,
267 const CalculatedTransform& parentLocalTransform) const
268 {
269 NW_NULL_ASSERT(worldMatrix);
270 NW_NULL_ASSERT(worldTransform);
271
272 math::VEC3 scale;
273
274 // Update WorldTransform
275 CalculateWorldBasic(
276 &worldTransform->m_TransformMatrix,
277 &scale,
278 localTransform,
279 parentWorldTransform,
280 parentLocalTransform
281 );
282
283 this->CompensateScale(scale);
284
285 worldTransform->m_Scale = scale;
286
287 // Update WorldMatrix
288 math::MTX34MultScale(worldMatrix, worldTransform->m_TransformMatrix, localTransform.m_Scale);
289
290 #if defined(NW_GFX_WORLD_MATRIX_FLAG_UPDATE_ENABLED)
291 worldTransform->UpdateFlags();
292 #else
293 worldTransform->ResetTransformFlags();
294 worldTransform->UpdateScaleFlags();
295 #endif
296 }
297
298 //----------------------------------------
299 NW_INLINE void
UpdateXsi(math::MTX34 * worldMatrix,CalculatedTransform * worldTransform,const CalculatedTransform & localTransform,const CalculatedTransform & parentWorldTransform,const CalculatedTransform & parentLocalTransform)300 WorldMatrixUpdater::UpdateXsi(
301 math::MTX34* worldMatrix,
302 CalculatedTransform* worldTransform,
303 const CalculatedTransform& localTransform,
304 const CalculatedTransform& parentWorldTransform,
305 const CalculatedTransform& parentLocalTransform) const
306 {
307 NW_NULL_ASSERT(worldMatrix);
308 NW_NULL_ASSERT(worldTransform);
309
310 math::VEC3 scale;
311
312 // Update WorldTransform
313 CalculateWorldXsi(
314 &worldTransform->m_TransformMatrix,
315 &scale,
316 localTransform,
317 parentWorldTransform,
318 parentLocalTransform
319 );
320
321 this->CompensateScale(scale);
322
323 worldTransform->m_Scale = scale;
324
325 // Update WorldMatrix
326 math::MTX34MultScale(worldMatrix, worldTransform->m_TransformMatrix, worldTransform->m_Scale);
327
328 #if defined(NW_GFX_WORLD_MATRIX_FLAG_UPDATE_ENABLED)
329 worldTransform->UpdateFlags();
330 #else
331 worldTransform->ResetTransformFlags();
332 worldTransform->UpdateScaleFlags();
333 #endif
334 }
335
336 } // gfx
337 } // nw
338
339 #endif // NW_GFX_WORLD_MATRIX_UPDATER_H_
340