1 // Copyright (C) 2002-2007 Nikolaus Gebhardt
2 // This file is part of the "Irrlicht Engine".
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
5 #ifndef __IRR_POINT_3D_H_INCLUDED__
6 #define __IRR_POINT_3D_H_INCLUDED__
15 //! 3d vector template class with lots of operators and methods.
21 vector3d() : X(0), Y(0), Z(0) {}
22 vector3d(T nx
, T ny
, T nz
) : X(nx
), Y(ny
), Z(nz
) {}
23 vector3d(const vector3d
<T
>& other
) : X(other
.X
), Y(other
.Y
), Z(other
.Z
) {}
27 vector3d
<T
> operator-() const { return vector3d
<T
>(-X
, -Y
, -Z
); }
29 vector3d
<T
>& operator=(const vector3d
<T
>& other
) { X
= other
.X
; Y
= other
.Y
; Z
= other
.Z
; return *this; }
31 vector3d
<T
> operator+(const vector3d
<T
>& other
) const { return vector3d
<T
>(X
+ other
.X
, Y
+ other
.Y
, Z
+ other
.Z
); }
32 vector3d
<T
>& operator+=(const vector3d
<T
>& other
) { X
+=other
.X
; Y
+=other
.Y
; Z
+=other
.Z
; return *this; }
34 vector3d
<T
> operator-(const vector3d
<T
>& other
) const { return vector3d
<T
>(X
- other
.X
, Y
- other
.Y
, Z
- other
.Z
); }
35 vector3d
<T
>& operator-=(const vector3d
<T
>& other
) { X
-=other
.X
; Y
-=other
.Y
; Z
-=other
.Z
; return *this; }
37 vector3d
<T
> operator*(const vector3d
<T
>& other
) const { return vector3d
<T
>(X
* other
.X
, Y
* other
.Y
, Z
* other
.Z
); }
38 vector3d
<T
>& operator*=(const vector3d
<T
>& other
) { X
*=other
.X
; Y
*=other
.Y
; Z
*=other
.Z
; return *this; }
39 vector3d
<T
> operator*(const T v
) const { return vector3d
<T
>(X
* v
, Y
* v
, Z
* v
); }
40 vector3d
<T
>& operator*=(const T v
) { X
*=v
; Y
*=v
; Z
*=v
; return *this; }
42 vector3d
<T
> operator/(const vector3d
<T
>& other
) const { return vector3d
<T
>(X
/ other
.X
, Y
/ other
.Y
, Z
/ other
.Z
); }
43 vector3d
<T
>& operator/=(const vector3d
<T
>& other
) { X
/=other
.X
; Y
/=other
.Y
; Z
/=other
.Z
; return *this; }
44 vector3d
<T
> operator/(const T v
) const { T i
=(T
)1.0/v
; return vector3d
<T
>(X
* i
, Y
* i
, Z
* i
); }
45 vector3d
<T
>& operator/=(const T v
) { T i
=(T
)1.0/v
; X
*=i
; Y
*=i
; Z
*=i
; return *this; }
47 bool operator<=(const vector3d
<T
>&other
) const { return X
<=other
.X
&& Y
<=other
.Y
&& Z
<=other
.Z
;};
48 bool operator>=(const vector3d
<T
>&other
) const { return X
>=other
.X
&& Y
>=other
.Y
&& Z
>=other
.Z
;};
49 bool operator<(const vector3d
<T
>&other
) const { return X
<other
.X
&& Y
<other
.Y
&& Z
<other
.Z
;};
50 bool operator>(const vector3d
<T
>&other
) const { return X
>other
.X
&& Y
>other
.Y
&& Z
>other
.Z
;};
52 //! use week float compare
53 //bool operator==(const vector3d<T>& other) const { return other.X==X && other.Y==Y && other.Z==Z; }
54 //bool operator!=(const vector3d<T>& other) const { return other.X!=X || other.Y!=Y || other.Z!=Z; }
56 bool operator==(const vector3d
<T
>& other
) const
58 return this->equals(other
);
61 bool operator!=(const vector3d
<T
>& other
) const
63 return !this->equals(other
);
68 //! returns if this vector equals the other one, taking floating point rounding errors into account
69 bool equals(const vector3d
<T
>& other
, const T tolerance
= (T
)ROUNDING_ERROR_32
) const
71 return core::equals(X
, other
.X
, tolerance
) &&
72 core::equals(Y
, other
.Y
, tolerance
) &&
73 core::equals(Z
, other
.Z
, tolerance
);
76 void set(const T nx
, const T ny
, const T nz
) {X
=nx
; Y
=ny
; Z
=nz
; }
77 void set(const vector3d
<T
>& p
) { X
=p
.X
; Y
=p
.Y
; Z
=p
.Z
;}
79 //! Returns length of the vector.
80 T
getLength() const { return (T
) sqrt((f64
)(X
*X
+ Y
*Y
+ Z
*Z
)); }
82 //! Returns squared length of the vector.
83 /** This is useful because it is much faster than
85 T
getLengthSQ() const { return X
*X
+ Y
*Y
+ Z
*Z
; }
87 //! Returns the dot product with another vector.
88 T
dotProduct(const vector3d
<T
>& other
) const
90 return X
*other
.X
+ Y
*other
.Y
+ Z
*other
.Z
;
93 //! Returns distance from another point.
94 /** Here, the vector is interpreted as point in 3 dimensional space. */
95 T
getDistanceFrom(const vector3d
<T
>& other
) const
97 return vector3d
<T
>(X
- other
.X
, Y
- other
.Y
, Z
- other
.Z
).getLength();
100 //! Returns squared distance from another point.
101 /** Here, the vector is interpreted as point in 3 dimensional space. */
102 T
getDistanceFromSQ(const vector3d
<T
>& other
) const
104 return vector3d
<T
>(X
- other
.X
, Y
- other
.Y
, Z
- other
.Z
).getLengthSQ();
107 //! Calculates the cross product with another vector
108 //! \param p: vector to multiply with.
109 //! \return Crossproduct of this vector with p.
110 vector3d
<T
> crossProduct(const vector3d
<T
>& p
) const
112 return vector3d
<T
>(Y
* p
.Z
- Z
* p
.Y
, Z
* p
.X
- X
* p
.Z
, X
* p
.Y
- Y
* p
.X
);
115 //! Returns if this vector interpreted as a point is on a line between two other points.
116 /** It is assumed that the point is on the line. */
117 //! \param begin: Beginning vector to compare between.
118 //! \param end: Ending vector to compare between.
119 //! \return True if this vector is between begin and end. False if not.
120 bool isBetweenPoints(const vector3d
<T
>& begin
, const vector3d
<T
>& end
) const
122 T f
= (end
- begin
).getLengthSQ();
123 return getDistanceFromSQ(begin
) < f
&&
124 getDistanceFromSQ(end
) < f
;
127 //! Normalizes the vector. In case of the 0 vector the result
128 //! is still 0, otherwise the length of the vector will be 1.
129 //! Todo: 64 Bit template doesnt work.. need specialized template
130 vector3d
<T
>& normalize()
132 T l
= X
*X
+ Y
*Y
+ Z
*Z
;
135 l
= (T
) reciprocal_squareroot ( (f32
)l
);
142 //! Sets the length of the vector to a new value
143 void setLength(T newlength
)
149 //! Inverts the vector.
157 //! Rotates the vector by a specified number of degrees around the Y
158 //! axis and the specified center.
159 //! \param degrees: Number of degrees to rotate around the Y axis.
160 //! \param center: The center of the rotation.
161 void rotateXZBy(f64 degrees
, const vector3d
<T
>& center
)
163 degrees
*= DEGTORAD64
;
164 T cs
= (T
)cos(degrees
);
165 T sn
= (T
)sin(degrees
);
168 set(X
*cs
- Z
*sn
, Y
, X
*sn
+ Z
*cs
);
173 //! Rotates the vector by a specified number of degrees around the Z
174 //! axis and the specified center.
175 //! \param degrees: Number of degrees to rotate around the Z axis.
176 //! \param center: The center of the rotation.
177 void rotateXYBy(f64 degrees
, const vector3d
<T
>& center
)
179 degrees
*= DEGTORAD64
;
180 T cs
= (T
)cos(degrees
);
181 T sn
= (T
)sin(degrees
);
184 set(X
*cs
- Y
*sn
, X
*sn
+ Y
*cs
, Z
);
189 //! Rotates the vector by a specified number of degrees around the X
190 //! axis and the specified center.
191 //! \param degrees: Number of degrees to rotate around the X axis.
192 //! \param center: The center of the rotation.
193 void rotateYZBy(f64 degrees
, const vector3d
<T
>& center
)
195 degrees
*= DEGTORAD64
;
196 T cs
= (T
)cos(degrees
);
197 T sn
= (T
)sin(degrees
);
200 set(X
, Y
*cs
- Z
*sn
, Y
*sn
+ Z
*cs
);
205 //! Returns interpolated vector.
206 /** \param other: other vector to interpolate between
207 \param d: value between 0.0f and 1.0f. */
208 vector3d
<T
> getInterpolated(const vector3d
<T
>& other
, const T d
) const
210 const T inv
= (T
) 1.0 - d
;
211 return vector3d
<T
>(other
.X
*inv
+ X
*d
, other
.Y
*inv
+ Y
*d
, other
.Z
*inv
+ Z
*d
);
214 //! Returns interpolated vector. ( quadratic )
215 /** \param v2: second vector to interpolate with
216 \param v3: third vector to interpolate with
217 \param d: value between 0.0f and 1.0f. */
218 vector3d
<T
> getInterpolated_quadratic(const vector3d
<T
>& v2
, const vector3d
<T
>& v3
, const T d
) const
220 // this*(1-d)*(1-d) + 2 * v2 * (1-d) + v3 * d * d;
221 const T inv
= (T
) 1.0 - d
;
222 const T mul0
= inv
* inv
;
223 const T mul1
= (T
) 2.0 * d
* inv
;
224 const T mul2
= d
* d
;
226 return vector3d
<T
> ( X
* mul0
+ v2
.X
* mul1
+ v3
.X
* mul2
,
227 Y
* mul0
+ v2
.Y
* mul1
+ v3
.Y
* mul2
,
228 Z
* mul0
+ v2
.Z
* mul1
+ v3
.Z
* mul2
);
231 //! Gets the Y and Z rotations of a vector.
232 /** Thanks to Arras on the Irrlicht forums to add this method.
233 \return A vector representing the rotation in degrees of
234 this vector. The Z component of the vector will always be 0. */
235 vector3d
<T
> getHorizontalAngle()
239 angle
.Y
= (T
)atan2(X
, Z
);
240 angle
.Y
*= (f32
)RADTODEG64
;
242 if (angle
.Y
< 0.0f
) angle
.Y
+= 360.0f
;
243 if (angle
.Y
>= 360.0f
) angle
.Y
-= 360.0f
;
245 f32 z1
= sqrtf(X
*X
+ Z
*Z
);
247 angle
.X
= (T
)atan2(z1
, Y
);
248 angle
.X
*= (f32
)RADTODEG64
;
251 if (angle
.X
< 0.0f
) angle
.X
+= 360.0f
;
252 if (angle
.X
>= 360.0f
) angle
.X
-= 360.0f
;
257 //! Fills an array of 4 values with the vector data (usually floats).
258 /** Useful for setting in shader constants for example. The fourth value
260 void getAs4Values(T
* array
) const
275 //! Typedef for a f32 3d vector.
276 typedef vector3d
<f32
> vector3df
;
277 //! Typedef for an integer 3d vector.
278 typedef vector3d
<s32
> vector3di
;
280 template<class S
, class T
> vector3d
<T
> operator*(const S scalar
, const vector3d
<T
>& vector
) { return vector
*scalar
; }
282 } // end namespace core
283 } // end namespace irr