1 /*---------------------------------------------------------------------------*
2   Project:  Horizon
3   File:     math_Vector4.h
4 
5   Copyright (C)2009-2010 Nintendo Co., Ltd.  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: 18015 $
14  *---------------------------------------------------------------------------*/
15 
16 #ifndef NN_MATH_VECTOR4_H_
17 #define NN_MATH_VECTOR4_H_
18 
19 #include <cstring>
20 #include <nn/math/math_Config.h>
21 
22 #pragma push
23 #pragma Otime
24 
25 namespace nn {
26 namespace math {
27 
28 struct VEC4;
29 
30 /* ------------------------------------------------------------------------
31     VEC4用の関数
32    ------------------------------------------------------------------------ */
33 NN_MATH_INLINE bool VEC4IsZero(const VEC4* p);
34 NN_MATH_INLINE bool VEC4IsZeroWOne(const VEC4* p);
35 NN_MATH_INLINE VEC4* VEC4Add(VEC4* pOut, const VEC4* p1, const VEC4* p2);
36 NN_MATH_INLINE VEC4* VEC4Sub(VEC4* pOut, const VEC4* p1, const VEC4* p2);
37 NN_MATH_INLINE VEC4* VEC4Mult(VEC4* pOut, const VEC4* p1, const VEC4* p2);
38 NN_MATH_INLINE VEC4* VEC4Scale(VEC4* pOut, const VEC4* p, f32 scale);
39 NN_MATH_INLINE VEC4* VEC4Lerp(VEC4* pOut, const VEC4* p1, const VEC4* p2, f32 t);
40 NN_MATH_INLINE f32   VEC4Dot(const VEC4* p1, const VEC4* p2);
41 NN_MATH_INLINE f32   VEC4LenSq(const VEC4* p);
42 NN_MATH_INLINE f32   VEC4Len(const VEC4* p);
43 NN_MATH_INLINE VEC4* VEC4Normalize(VEC4* pOut, const VEC4* p);
44 NN_MATH_INLINE VEC4* VEC4SafeNormalize(VEC4* pOut, const VEC4* p, const VEC4& alt);
45 NN_MATH_INLINE f32   VEC4DistSq(const VEC4* p1, const VEC4* p2);
46 NN_MATH_INLINE VEC4* VEC4Maximize(VEC4* pOut, const VEC4* p1, const VEC4* p2);
47 NN_MATH_INLINE VEC4* VEC4Minimize(VEC4* pOut, const VEC4* p1, const VEC4* p2);
48 
49 /* =======================================================================
50         クラスの定義
51    ======================================================================== */
52 struct VEC4_
53 {
54     f32 x;
55     f32 y;
56     f32 z;
57     f32 w;
58 };
59 
60 
61 /*!------------------------------------------------------------------------
62     @brief        4次のベクトルクラスです。
63    ------------------------------------------------------------------------ */
64 struct VEC4 : public VEC4_
65 {
66 public:
67     static const int DIMENSION = 4; //!< 次元数です。
68 
69     //!< @brief ゼロベクトルです。
ZeroVEC470     static const VEC4& Zero()
71     {
72         static const VEC4 zero(0.0f, 0.0f, 0.0f, 0.0f);
73 
74         return zero;
75     }
76 
77     //!< @brief 同次座標でのゼロベクトルです。
ZeroWOneVEC478     static const VEC4& ZeroWOne()
79     {
80         static const VEC4 zero(0.0f, 0.0f, 0.0f, 1.0f);
81 
82         return zero;
83     }
84 
85     typedef VEC4 self_type; //!< 自分の型です
86     typedef f32  value_type; //!< 要素の型です。
87 public:
88 
89     //----------------------------------------
90     //! @name 作成
91     //@{
92 
93     //! @brief コンストラクタです。
VEC4VEC494     VEC4() {}
95     //! @brief コンストラクタです。
VEC4VEC496     VEC4(const f32* p) { x = p[0]; y = p[1]; z = p[2]; w = p[3]; }
97     //! @brief コピーコンストラクタです。
VEC4VEC498     VEC4(const VEC4_& v) { x = v.x; y = v.y; z = v.z; w = v.w; }
99     //! @brief コンストラクタです。
VEC4VEC4100     VEC4(f32 fx, f32 fy, f32 fz, f32 fw) { x = fx; y = fy; z = fz; w = fw; }
101     //! @brief コンストラクタです。
VEC4VEC4102     VEC4(const VEC3& v) { x = v.x; y = v.y; z = v.z; w = 0.0f; }
103 
104     //@}
105 
106     //----------------------------------------
107     //! @name 変換
108     //@{
109 
110     //! @brief f32 型へのキャストです。
111     operator f32*() { return &x; }
112 
113     //! @brief f32 型へのキャストです。
114     operator const f32*() const { return &x; }
115 
116     //@}
117 
118     //----------------------------------------
119     //! @name 演算
120     //@{
121     self_type& operator += (const self_type& rhs) { (void)VEC4Add(this, this, &rhs); return *this; }
122     self_type& operator -= (const self_type& rhs) { (void)VEC4Sub(this, this, &rhs); return *this; }
123     self_type& operator *= (const self_type& rhs) { (void)VEC4Mult(this, this, &rhs); return *this; }
124     self_type& operator *= (f32 f) { (void)VEC4Scale(this, this, f); return *this; }
125     self_type& operator /= (f32 f) { (void)VEC4Scale(this, this, 1/f); return *this; }
126 
127     self_type operator + () const { return *this; }
128     self_type operator - () const { return self_type(-x, -y, -z, -w); }
129 
130     self_type operator + (const self_type& rhs) const { VEC4 tmp; (void)VEC4Add(&tmp, this, &rhs); return tmp; }
131     self_type operator - (const self_type& rhs) const { VEC4 tmp; (void)VEC4Sub(&tmp, this, &rhs); return tmp; }
132     self_type operator * (f32 f) const { VEC4 tmp; (void)VEC4Scale(&tmp, this, f); return tmp; }
133     self_type operator / (f32 f) const { f32 r = 1.f / f; return operator*(r); }
134 
135     //! @brief 2つのベクトル間の線形補間を計算し設定します。
136     //!
137     //! @param[in] lhs 線形補間の始点となるベクトルです。
138     //! @param[in] rhs 線形補間の終点となるベクトルです。
139     //! @param[in] t   線形補間のパラメータ。0.0 であれば lhs が 1.0 であれば rhs が結果となります。
140     //!
LerpVEC4141     self_type& Lerp(const VEC4& lhs, const VEC4& rhs, f32 t)
142     {
143         return *VEC4Lerp(this, &lhs, &rhs, t);
144     }
145 
146     //! @brief 指定したベクトルとの内積を計算します。
147     //!
148     //! @param[in] vec 内積を行うベクトルです。
149     //!
DotVEC4150     f32 Dot(const VEC4& vec) const
151     {
152         return VEC4Dot(this, &vec);
153     }
154 
155     //! @brief ベクトルの長さの2乗を計算します。
156     //! 将来削除される可能性がありますので非推奨です。
157     //! LengthSquareを推奨します。
LenSqVEC4158     f32 LenSq() const { return VEC4LenSq(this); }
159 
160     //! @brief ベクトルの長さの2乗を計算します。
LengthSquareVEC4161     f32 LengthSquare() const { return VEC4LenSq(this); }
162 
163     //! @brief ベクトルの長さを計算します。
LengthVEC4164     f32 Length() const { return VEC4Len(this); }
165 
166     //! @brief ベクトルを正規化します。
NormalizeVEC4167     self_type& Normalize()
168     {
169         return *VEC4Normalize(this, this);
170     }
171 
172     //! @brief ベクトルを正規化します。
173     //!        正規化に失敗した場合は指定されたベクトルを設定します。
174     //!
175     //! @param[in]    alt   正規化に失敗した場合に設定するベクトルです。
SafeNormalizeVEC4176     self_type& SafeNormalize(const VEC4& alt)
177     {
178         return *VEC4SafeNormalize(this, this, alt);
179     }
180 
181     //! @brief 指定したベクトルとの距離の二乗を計算します。
182     //!
183     //! @param[in] vec 距離を計算するベクトルです。
DistanceSquareVEC4184     f32 DistanceSquare(const VEC4& vec)
185     {
186         return VEC4DistSq(this, &vec);
187     }
188 
189     //! @brief 2つのベクトルのそれぞれの成分の最小値から構成されるベクトルを作成し設定します。
190     //!
191     //! @brief lhs 最小値を計算する左辺ベクトルです。
192     //! @brief rhs 最小値を計算する右辺ベクトルです。
MaximizeVEC4193     self_type& Maximize(const VEC4& lhs, const VEC4& rhs)
194     {
195         return *VEC4Maximize(this, &lhs, &rhs);
196     }
197 
198     //! @brief ベクトルの外積を計算し設定します。
199     //!
200     //! @brief lhs 外積を計算する左辺ベクトルです。
201     //! @brief rhs 外積を計算する右辺ベクトルです。
MinimizeVEC4202     self_type& Minimize(const VEC4& lhs, const VEC4& rhs)
203     {
204         return *VEC4Minimize(this, &lhs, &rhs);
205     }
206 
207     //@}
208 
209     //----------------------------------------
210     //! @name 設定
211     //@{
212 
213     //! @brief 値を個別に設定します。
SetVEC4214     void Set(f32 fx, f32 fy, f32 fz, f32 fw) { x = fx; y = fy; z = fz; w = fw; }
215 
216     //@}
217 
218     //----------------------------------------
219     //! @name 比較
220     //@{
221 
222     //! @brief 同値であれば true を返します。
223     bool operator == (const self_type& rhs) const { return x == rhs.x && y == rhs.y && z == rhs.z && w == rhs.w; }
224 
225     //! @brief 同値でなければ true を返します。
226     bool operator != (const self_type& rhs) const { return x != rhs.x || y != rhs.y || z != rhs.z || w != rhs.w; }
227 
228     //! @brief ゼロベクトルであれば true を返します。
IsZeroVEC4229     bool IsZero() const { return VEC4IsZero(this); }
230 
231     //! @brief 同時座標のゼロベクトルであれば true を返します。
IsZeroWOneVEC4232     bool IsZeroWOne() const { return VEC4IsZeroWOne(this); }
233     //@}
234 
235     //! @brief 状態を出力します。
236     void Report(bool bNewline = true, const char* name = NULL) const;
237 };
238 
239 typedef struct VEC4 Vector4;
240 
241 inline VEC4
242 operator * (f32 f, const VEC4& rhs) { VEC4 tmp; (void)VEC4Scale(&tmp, &rhs, f); return tmp; }
243 
244 
245 }  // namespace math
246 }  // namespace nn
247 
248 
249 #if defined(NN_MATH_AS_INLINE)
250 #include <nn/math/inline/math_Vector4.ipp>
251 #endif
252 
253 namespace nn {
254 namespace math {
255 
256 //-- const 引数を参照にしたオーバーロード
VEC4IsZero(const VEC4 & v)257 inline bool VEC4IsZero(const VEC4& v){ return VEC4IsZero( &v ); }
VEC4IsZeroWOne(const VEC4 & v)258 inline bool VEC4IsZeroWOne(const VEC4& v){ return VEC4IsZeroWOne( &v ); }
VEC4Add(VEC4 * pOut,const VEC4 & v1,const VEC4 & v2)259 inline VEC4* VEC4Add(VEC4* pOut, const VEC4& v1, const VEC4& v2) { return VEC4Add( pOut, &v1, &v2 ); }
VEC4Sub(VEC4 * pOut,const VEC4 & v1,const VEC4 & v2)260 inline VEC4* VEC4Sub(VEC4* pOut, const VEC4& v1, const VEC4& v2) { return VEC4Sub( pOut, &v1, &v2 ); }
VEC4Mult(VEC4 * pOut,const VEC4 & v1,const VEC4 & v2)261 inline VEC4* VEC4Mult(VEC4* pOut, const VEC4& v1, const VEC4& v2) { return VEC4Mult( pOut, &v1, &v2 ); }
VEC4Scale(VEC4 * pOut,const VEC4 & v,f32 scale)262 inline VEC4* VEC4Scale(VEC4* pOut, const VEC4& v, f32 scale) { return VEC4Scale( pOut, &v, scale); }
VEC4Lerp(VEC4 * pOut,const VEC4 & v1,const VEC4 & v2,f32 t)263 inline VEC4* VEC4Lerp(VEC4* pOut, const VEC4& v1, const VEC4& v2, f32 t) { return VEC4Lerp( pOut, &v1, &v2, t ); }
VEC4Dot(const VEC4 & v1,const VEC4 & v2)264 inline f32   VEC4Dot(const VEC4& v1, const VEC4& v2) { return VEC4Dot( &v1, &v2 ); }
VEC4LenSq(const VEC4 & v)265 inline f32   VEC4LenSq(const VEC4& v) { return VEC4LenSq( &v ); }
VEC4Len(const VEC4 & v)266 inline f32   VEC4Len(const VEC4& v) { return VEC4Len( &v ); }
VEC4Normalize(VEC4 * pOut,const VEC4 & v)267 inline VEC4* VEC4Normalize(VEC4* pOut, const VEC4& v) { return VEC4Normalize( pOut, &v ); }
VEC4SafeNormalize(VEC4 * pOut,const VEC4 & v,const VEC4 & alt)268 inline VEC4* VEC4SafeNormalize(VEC4* pOut, const VEC4& v, const VEC4& alt) { return VEC4SafeNormalize( pOut, &v, alt ); }
VEC4DistSq(const VEC4 & v1,const VEC4 & v2)269 inline f32   VEC4DistSq(const VEC4& v1, const VEC4& v2) { return VEC4DistSq( &v1, &v2 ); }
VEC4Maximize(VEC4 * pOut,const VEC4 & v1,const VEC4 & v2)270 inline VEC4* VEC4Maximize(VEC4* pOut, const VEC4& v1, const VEC4& v2) { return VEC4Maximize( pOut, &v1, &v2 ); }
VEC4Minimize(VEC4 * pOut,const VEC4 & v1,const VEC4 & v2)271 inline VEC4* VEC4Minimize(VEC4* pOut, const VEC4& v1, const VEC4& v2) { return VEC4Minimize( pOut, &v1, &v2 ); }
272 
273 
274 }  // namespace math
275 }  // namespace nn
276 
277 #pragma pop
278 
279 #endif
280