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