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