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