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