1 /*---------------------------------------------------------------------------*
2 Project: NintendoWare
3 File: gfx_WorldMatrixUpdater.cpp
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: 24263 $
14 *---------------------------------------------------------------------------*/
15
16 #include "precompiled.h"
17
18 #include <nw/gfx/gfx_WorldMatrixUpdater.h>
19 #include <nw/gfx/gfx_CalculatedTransform.h>
20 #include <nw/ut/ut_MoveArray.h>
21 #include <nw/math.h>
22 #include <nw/os/os_Memory.h>
23
24 #include <nw/dev.h>
25
26 namespace nw {
27 namespace gfx {
28
29 //----------------------------------------
30 WorldMatrixUpdater*
Create(os::IAllocator * allocator)31 WorldMatrixUpdater::Builder::Create(
32 os::IAllocator* allocator
33 )
34 {
35 NW_NULL_ASSERT(allocator);
36
37 void* updaterMemory = allocator->Alloc(sizeof(WorldMatrixUpdater));
38 NW_NULL_ASSERT(updaterMemory);
39
40 return new(updaterMemory) WorldMatrixUpdater(allocator);
41 }
42
43 //----------------------------------------
WorldMatrixUpdater(os::IAllocator * allocator)44 WorldMatrixUpdater::WorldMatrixUpdater(
45 os::IAllocator* allocator
46 )
47 : GfxObject(allocator)
48 {
49 NW_NULL_ASSERT(allocator);
50 }
51
52 //----------------------------------------
~WorldMatrixUpdater()53 WorldMatrixUpdater::~WorldMatrixUpdater()
54 {
55 }
56
57 //----------------------------------------
58 void
CalculateWorldXsi(math::MTX34 * transformMatrix,math::VEC3 * scale,const CalculatedTransform & localTransform,const CalculatedTransform & parentWorldTransform,const CalculatedTransform & parentLocalTransform) const59 WorldMatrixUpdater::CalculateWorldXsi(
60 math::MTX34* transformMatrix,
61 math::VEC3* scale,
62 const CalculatedTransform& localTransform,
63 const CalculatedTransform& parentWorldTransform,
64 const CalculatedTransform& parentLocalTransform
65 ) const
66 {
67 NW_NULL_ASSERT(transformMatrix);
68 NW_NULL_ASSERT(scale);
69
70 NW_UNUSED_VARIABLE(parentLocalTransform);
71
72 const math::MTX34& parentMatrix = parentWorldTransform.TransformMatrix();
73
74 if (localTransform.IsEnabledFlagsOr(
75 CalculatedTransform::FLAG_IS_IDENTITY | CalculatedTransform::FLAG_IS_ROTATE_TRANSLATE_ZERO))
76 {
77 // TR(i) = TR(i-1)
78 math::MTX34Copy(transformMatrix, parentMatrix);
79 }
80 else
81 {
82 bool isParentScaleOne = parentWorldTransform.IsEnabledFlags(CalculatedTransform::FLAG_IS_SCALE_ONE);
83 const math::VEC3& parentScale = parentWorldTransform.m_Scale;
84
85 const math::MTX34& localMatrix = localTransform.TransformMatrix();
86 math::VEC3 localTranslate = localTransform.TransformMatrix().GetColumn(3);
87
88 if (localTransform.IsEnabledFlags(CalculatedTransform::FLAG_IS_ROTATE_ZERO))
89 {
90 // TR(i) = TR(i-1) * S(i-1) * t(i) * Rev(S(i-1))
91 if (isParentScaleOne)
92 {
93 // TR(i) = TR(i-1) * t(i)
94 math::MTX34MultTranslate(transformMatrix, &parentMatrix, &localTranslate);
95 }
96 else
97 {
98 // S(i-1) != 1
99 math::VEC3Mult(&localTranslate, &localTranslate, &parentScale);
100 math::MTX34MultTranslate(transformMatrix, &parentMatrix, &localTranslate);
101 }
102 }
103 else
104 {
105 if (isParentScaleOne)
106 {
107 // TR(i) = TR(i-1) * t(i) * r(i)
108 math::MTX34Mult(transformMatrix, &parentMatrix, &localMatrix);
109 }
110 else
111 {
112 // TR(i) = TR(i-1) * S(i-1) * t(i) * Rev(S(i-1)) * r(i)
113 math::MTX34 scaledLocalMatrix;
114 math::MTX34Copy(&scaledLocalMatrix, &localMatrix);
115 scaledLocalMatrix.f._03 *= parentScale.x;
116 scaledLocalMatrix.f._13 *= parentScale.y;
117 scaledLocalMatrix.f._23 *= parentScale.z;
118 math::MTX34Mult(transformMatrix, &parentMatrix, &scaledLocalMatrix);
119 }
120 }
121 }
122
123 if (parentWorldTransform.IsEnabledFlags(CalculatedTransform::FLAG_IS_SCALE_ONE))
124 {
125 scale->Set(localTransform.m_Scale);
126 }
127 else
128 {
129 math::VEC3Mult(scale, &parentWorldTransform.m_Scale, &localTransform.m_Scale);
130 }
131 }
132
133 //----------------------------------------
134 void
CalculateWorldMayaSsc(math::MTX34 * transformMatrix,math::VEC3 * scale,const CalculatedTransform & localTransform,const CalculatedTransform & parentWorldTransform,const CalculatedTransform & parentLocalTransform) const135 WorldMatrixUpdater::CalculateWorldMayaSsc(
136 math::MTX34* transformMatrix,
137 math::VEC3* scale,
138 const CalculatedTransform& localTransform,
139 const CalculatedTransform& parentWorldTransform,
140 const CalculatedTransform& parentLocalTransform
141 ) const
142 {
143 NW_NULL_ASSERT(transformMatrix);
144 NW_NULL_ASSERT(scale);
145
146 const math::MTX34& parentMatrix = parentWorldTransform.m_TransformMatrix;
147
148 if (localTransform.IsEnabledFlagsOr(CalculatedTransform::FLAG_IS_IDENTITY | CalculatedTransform::FLAG_IS_ROTATE_TRANSLATE_ZERO))
149 {
150 // TR(i) = TR(i-1)
151 math::MTX34Copy(transformMatrix, parentMatrix);
152 }
153 else
154 {
155 const math::MTX34& localMatrix = localTransform.m_TransformMatrix;
156 math::VEC3 localTranslate = localTransform.m_TransformMatrix.GetColumn(3);
157
158 if (localTransform.IsEnabledFlags(CalculatedTransform::FLAG_IS_ROTATE_ZERO))
159 {
160 if (parentLocalTransform.IsEnabledFlags(CalculatedTransform::FLAG_IS_SCALE_ONE))
161 {
162 // TR(i) = TR(i-1) * t(i)
163 math::MTX34MultTranslate(transformMatrix, &parentMatrix, &localTranslate);
164 }
165 else
166 {
167 // TR(i) = TR(i-1) * S(i-1) * t(i) * Rev(S(i-1))
168 math::MTX34Copy(transformMatrix, parentMatrix);
169 math::MTX33 scaledParentRotate(*transformMatrix);
170 const math::VEC3& parentScale = parentLocalTransform.m_Scale;
171 this->ScaleMatrix(&scaledParentRotate, parentScale);
172 math::VEC3Transform(&localTranslate, &scaledParentRotate, &localTranslate);
173 this->AddTranslate(transformMatrix, localTranslate);
174 }
175 }
176 else
177 {
178 if (parentLocalTransform.IsEnabledFlags(CalculatedTransform::FLAG_IS_SCALE_ONE))
179 {
180 // TR(i) = TR(i-1) * t(i) * r(i)
181 math::MTX34MultTranslate(transformMatrix, &parentMatrix, &localTranslate);
182 math::MTX33Mult(transformMatrix, transformMatrix, &localMatrix);
183 }
184 else
185 {
186 // TR(i) = TR(i-1) * S(i-1) * t(i) * Rev(S(i-1)) * r(i)
187 math::MTX34Copy(transformMatrix, parentMatrix);
188 math::MTX33 scaledParentRotate(*transformMatrix);
189 const math::VEC3& parentScale = parentLocalTransform.m_Scale;
190 this->ScaleMatrix(&scaledParentRotate, parentScale);
191 math::VEC3Transform(&localTranslate, &scaledParentRotate, &localTranslate);
192 this->AddTranslate(transformMatrix, localTranslate);
193 math::MTX33Mult(transformMatrix, transformMatrix, &localMatrix);
194 }
195 }
196 }
197
198 if (parentWorldTransform.IsEnabledFlags(CalculatedTransform::FLAG_IS_SCALE_ONE))
199 {
200 scale->Set(localTransform.m_Scale);
201 }
202 else
203 {
204 math::VEC3Mult(scale, &parentWorldTransform.m_Scale, &localTransform.m_Scale);
205 }
206 }
207
208 //----------------------------------------
209 void
CalculateWorldBasic(math::MTX34 * transformMatrix,math::VEC3 * scale,const CalculatedTransform & localTransform,const CalculatedTransform & parentWorldTransform,const CalculatedTransform & parentLocalTransform) const210 WorldMatrixUpdater::CalculateWorldBasic(
211 math::MTX34* transformMatrix,
212 math::VEC3* scale,
213 const CalculatedTransform& localTransform,
214 const CalculatedTransform& parentWorldTransform,
215 const CalculatedTransform& parentLocalTransform
216 ) const
217 {
218 NW_NULL_ASSERT(transformMatrix);
219 NW_NULL_ASSERT(scale);
220
221 const math::MTX34& parentMatrix = parentWorldTransform.m_TransformMatrix;
222
223 if (localTransform.IsEnabledFlagsOr(CalculatedTransform::FLAG_IS_IDENTITY | CalculatedTransform::FLAG_IS_ROTATE_TRANSLATE_ZERO))
224 {
225 if (parentLocalTransform.IsEnabledFlags(CalculatedTransform::FLAG_IS_SCALE_ONE))
226 {
227 // TR(i) = TR(i-1)
228 math::MTX34Copy(transformMatrix, parentMatrix);
229 }
230 else
231 {
232 // TR(i) = TR(i-1) * S(i-1)
233 this->MultScale(transformMatrix, &parentMatrix, parentLocalTransform.m_Scale);
234 this->CopyTranslate(transformMatrix, parentMatrix);
235 }
236 }
237 else
238 {
239 if (localTransform.IsEnabledFlags(CalculatedTransform::FLAG_IS_ROTATE_ZERO))
240 {
241 if (parentLocalTransform.IsEnabledFlags(CalculatedTransform::FLAG_IS_SCALE_ONE))
242 {
243 math::VEC3 localTranslate = localTransform.m_TransformMatrix.GetColumn(3);
244
245 // TR(i) = TR(i-1) * t(i)
246 math::MTX34MultTranslate(transformMatrix, &parentMatrix, &localTranslate);
247 }
248 else
249 {
250 math::VEC3 localTranslate = localTransform.m_TransformMatrix.GetColumn(3);
251
252 // TR(i) = TR(i-1) * S(i-1) * t(i)
253 this->MultScale(transformMatrix, &parentMatrix, parentLocalTransform.m_Scale);
254 this->CopyTranslate(transformMatrix, parentMatrix);
255 math::MTX34MultTranslate(transformMatrix, transformMatrix, &localTranslate);
256 }
257 }
258 else
259 {
260 if (parentLocalTransform.IsEnabledFlags(CalculatedTransform::FLAG_IS_SCALE_ONE))
261 {
262 math::VEC3 localTranslate = localTransform.m_TransformMatrix.GetColumn(3);
263
264 // TR(i) = TR(i-1) * t(i) * r(i)
265 math::MTX34MultTranslate(transformMatrix, &parentMatrix, &localTranslate);
266 math::MTX33Mult(transformMatrix, transformMatrix, &localTransform.m_TransformMatrix);
267 }
268 else
269 {
270 math::VEC3 localTranslate = localTransform.m_TransformMatrix.GetColumn(3);
271
272 // TR(i) = TR(i-1) * S(i-1) * t(i) * r(i)
273 this->MultScale(transformMatrix, &parentMatrix, parentLocalTransform.m_Scale);
274 this->CopyTranslate(transformMatrix, parentMatrix);
275 math::MTX34MultTranslate(transformMatrix, transformMatrix, &localTranslate);
276 math::MTX33Mult(transformMatrix, transformMatrix, &localTransform.m_TransformMatrix);
277 }
278 }
279 }
280
281 if (parentWorldTransform.IsEnabledFlags(CalculatedTransform::FLAG_IS_SCALE_ONE))
282 {
283 scale->Set(localTransform.m_Scale);
284 }
285 else
286 {
287 math::VEC3Mult(scale, &parentWorldTransform.m_Scale, &localTransform.m_Scale);
288 }
289 }
290
291 } // namespace gfx
292 } // namespace nw
293