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