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