1 /*---------------------------------------------------------------------------*
2   Project:  NintendoWare
3   File:     gfx_CalculatedTransform.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_CalculatedTransform.h>
21 #include <nw/gfx/res/gfx_ResSkeleton.h>
22 
23 namespace nw
24 {
25 namespace gfx
26 {
27 
28 const f32 CalculatedTransform::s_VecSquareLenTol = 1.0e-6f;
29 
30 //----------------------------------------
31 void
Setup(const ResBone bone)32 CalculatedTransform::Setup(const ResBone bone)
33 {
34     bool translateZeroFlag = false;
35     bool rotateZeroFlag = false;
36 
37     this->SetTransform(bone.GetTransform());
38     if ( ut::CheckFlag(bone.GetFlags(), ResBoneData::FLAG_IS_IDENTITY) )
39     {
40         this->EnableFlags(CalculatedTransform::FLAG_IS_IDENTITY);
41     }
42     if ( ut::CheckFlag(bone.GetFlags(), ResBoneData::FLAG_IS_TRANSLATE_ZERO) )
43     {
44         this->EnableFlags(CalculatedTransform::FLAG_IS_TRANSLATE_ZERO);
45         translateZeroFlag = true;
46     }
47     if ( ut::CheckFlag(bone.GetFlags(), ResBoneData::FLAG_IS_ROTATE_ZERO) )
48     {
49         this->EnableFlags(CalculatedTransform::FLAG_IS_ROTATE_ZERO);
50         rotateZeroFlag = true;
51     }
52     if ( ut::CheckFlag(bone.GetFlags(), ResBoneData::FLAG_IS_SCALE_ONE) )
53     {
54         this->EnableFlags(CalculatedTransform::FLAG_IS_SCALE_ONE);
55     }
56     if ( ut::CheckFlag(bone.GetFlags(), ResBoneData::FLAG_IS_UNIFORM_SCALE) )
57     {
58         this->EnableFlags(CalculatedTransform::FLAG_IS_UNIFORM_SCALE);
59     }
60     if ( translateZeroFlag && rotateZeroFlag )
61     {
62         this->EnableFlags(CalculatedTransform::FLAG_IS_ROTATE_TRANSLATE_ZERO);
63     }
64 }
65 
66 //----------------------------------------
67 void
UpdateFlagsStrictly()68 CalculatedTransform::UpdateFlagsStrictly()
69 {
70     UpdateScaleFlags();
71     UpdateRotateFlagsStrictly();
72     UpdateTranslateFlags();
73     UpdateCompositeFlags();
74 }
75 //----------------------------------------
76 void
UpdateFlags()77 CalculatedTransform::UpdateFlags()
78 {
79     UpdateScaleFlags();
80     UpdateRotateFlags();
81     UpdateTranslateFlags();
82     UpdateCompositeFlags();
83 }
84 
85 //----------------------------------------
86 void
UpdateRotateFlagsStrictly()87 CalculatedTransform::UpdateRotateFlagsStrictly()
88 {
89     if (this->IsEnabledFlags(FLAG_IS_IGNORE_ROTATE))
90     {
91         return;
92     }
93 
94     const math::MTX34& mtx = this->m_TransformMatrix;
95     if (mtx.f._00 == 1.0f && mtx.f._01 == 0.0f && mtx.f._02 == 0.0f &&
96         mtx.f._10 == 0.0f && mtx.f._11 == 1.0f && mtx.f._12 == 0.0f &&
97         mtx.f._20 == 0.0f && mtx.f._21 == 0.0f && mtx.f._22 == 1.0f)
98     {
99         this->EnableFlags(FLAG_IS_ROTATE_ZERO);
100     }
101     else
102     {
103         this->DisableFlags(FLAG_IS_ROTATE_ZERO);
104     }
105 }
106 
107 //----------------------------------------
108 void
UpdateRotateFlags()109 CalculatedTransform::UpdateRotateFlags()
110 {
111     if (this->IsEnabledFlags(FLAG_IS_IGNORE_ROTATE))
112     {
113         return;
114     }
115 
116     const math::MTX34& mtx = this->m_TransformMatrix;
117     // 回転行列はノルム 1 なので、対角要素を 2 つ判断すればよい。
118     if (mtx.f._00 == 1.0f && mtx.f._11 == 1.0f)
119     {
120         // 回転行列の正規直交化をしても、計算誤差が ut::FloatEqualsWeak の範囲以上になることがあるため、
121         // 以下の警告を無効化しています。
122 #if 0
123         // 回転行列にスケール成分を含むことはできないので、
124         // 単位行列になっていなければ警告を出す。
125         NW_WARNING(
126             ut::FloatEqualsWeak(mtx.f._00, 1.0f) && ut::FloatEqualsWeak(mtx.f._01, 0.0f) && ut::FloatEqualsWeak(mtx.f._02, 0.0f) &&
127             ut::FloatEqualsWeak(mtx.f._10, 0.0f) && ut::FloatEqualsWeak(mtx.f._11, 1.0f) && ut::FloatEqualsWeak(mtx.f._12, 0.0f) &&
128             ut::FloatEqualsWeak(mtx.f._20, 0.0f) && ut::FloatEqualsWeak(mtx.f._21, 0.0f) && ut::FloatEqualsWeak(mtx.f._22, 1.0f),
129             "The rotation matrix of CalculatedTransform must not contain scale element.\n");
130 #endif
131         this->EnableFlags(FLAG_IS_ROTATE_ZERO);
132     }
133     else
134     {
135         this->DisableFlags(FLAG_IS_ROTATE_ZERO);
136     }
137 }
138 
139 //----------------------------------------
140 void
UpdateTranslateFlags()141 CalculatedTransform::UpdateTranslateFlags()
142 {
143     if (this->IsEnabledFlags(FLAG_IS_IGNORE_TRANSLATE))
144     {
145         return;
146     }
147 
148     const math::MTX34& mtx = this->m_TransformMatrix;
149     if (mtx.f._03 == 0.0f && mtx.f._13 == 0.0f && mtx.f._23 == 0.0f)
150     {
151         this->EnableFlags(FLAG_IS_TRANSLATE_ZERO);
152     }
153     else
154     {
155         this->DisableFlags(FLAG_IS_TRANSLATE_ZERO);
156     }
157 }
158 
159 //----------------------------------------
160 void
UpdateCompositeFlags()161 CalculatedTransform::UpdateCompositeFlags()
162 {
163     this->DisableFlags(FLAG_IS_ROTATE_TRANSLATE_ZERO | FLAG_IS_IDENTITY);
164 
165     if (this->IsEnabledFlags(FLAG_IS_ROTATE_ZERO | FLAG_IS_TRANSLATE_ZERO))
166     {
167         this->EnableFlags(FLAG_IS_ROTATE_TRANSLATE_ZERO);
168 
169         if (this->IsEnabledFlags(FLAG_IS_SCALE_ONE))
170         {
171             this->EnableFlags(FLAG_IS_IDENTITY);
172         }
173     }
174 }
175 
176 } // namespace gfx
177 } // namespace nw
178