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