4 #define vlen2(v) (_vlen2 = (v), dotproduct(_vlen2, _vlen2))
7 /** Vector distance comparison, avoids sqrt() */
8 #define vdist(v, cmp, f) (vlen2(v) cmp ((f) ** 2))
10 #define vdist(v, cmp, f) (vlen(v) cmp (f))
14 #define dotproduct(a, b) ((a) * (b))
16 noref vector _dotproduct_a, _dotproduct_b;
17 #define dotproduct(a, b) \
18 (_dotproduct_a = (a), _dotproduct_b = (b), \
19 _dotproduct_a.x * _dotproduct_b.x \
20 + _dotproduct_a.y * _dotproduct_b.y \
21 + _dotproduct_a.z * _dotproduct_b.z)
25 #define cross(a, b) ((a) >< (b))
28 vector cross(vector a, vector b)
31 '1 0 0' * (a.y * b.z - a.z * b.y)
32 + '0 1 0' * (a.z * b.x - a.x * b.z)
33 + '0 0 1' * (a.x * b.y - a.y * b.x);
37 noref vector _vmul_a, _vmul_b;
39 (_vmul_a = (a), _vmul_b = (b), \
40 '1 0 0' * (_vmul_a.x * _vmul_b.x) \
41 + '0 1 0' * (_vmul_a.y * _vmul_b.y) \
42 + '0 0 1' * (_vmul_a.z * _vmul_b.z))
44 const vector eX = '1 0 0';
45 const vector eY = '0 1 0';
46 const vector eZ = '0 0 1';
49 vector randompos(vector m1, vector m2)
53 v_x = m2_x * random() + m1_x;
54 v_y = m2_y * random() + m1_y;
55 v_z = m2_z * random() + m1_z;
60 float vlen_maxnorm2d(vector v)
62 return max(v.x, v.y, -v.x, -v.y);
66 float vlen_minnorm2d(vector v)
68 return min(max(v.x, -v.x), max(v.y, -v.y));
71 /** requires that m2>m1 in all coordinates, and that m4>m3 */
73 float boxesoverlap(vector m1, vector m2, vector m3, vector m4) { return m2_x >= m3_x && m1_x <= m4_x && m2_y >= m3_y && m1_y <= m4_y && m2_z >= m3_z && m1_z <= m4_z; }
75 /** requires the same as boxesoverlap, but is a stronger condition */
77 float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs) { return smins.x >= bmins.x && smaxs.x <= bmaxs.x && smins.y >= bmins.y && smaxs.y <= bmaxs.y && smins.z >= bmins.z && smaxs.z <= bmaxs.z; }
79 #define pointinsidebox(point, bmins, bmaxs) boxinsidebox(point, point, bmins, bmaxs)
81 #define PITCH(v) ((v).x)
82 #define YAW(v) ((v).y)
83 #define ROLL(v) ((v).z)
86 // vector vec2(vector v); // returns a vector with just the x and y components of the given vector
87 // vector vec2(float x, float y); // returns a vector with the given x and y components
90 #define vec2(...) EVAL(OVERLOAD(vec2, __VA_ARGS__))
91 #define vec2_1(v) (_vec2 = (v), _vec2.z = 0, _vec2)
92 #define vec2_2(x, y) (_vec2_x = (x), _vec2_y = (y), _vec2)
95 #define vec3(_x, _y, _z) (_vec3.x = (_x), _vec3.y = (_y), _vec3.z = (_z), _vec3)
97 #define VEC_NAN vec3(FLOAT_NAN, FLOAT_NAN, FLOAT_NAN);
100 bool is_all_nans(vector v) {
101 return isnan(v.x) && isnan(v.y) && isnan(v.z);
105 vector Rotate(vector v, float a)
107 float a_sin = sin(a), a_cos = cos(a);
108 return vec2(v.x * a_cos + v.y * a_sin, -v.x * a_sin + v.y * a_cos);
111 noref vector _yinvert;
112 #define yinvert(v) (_yinvert = (v), _yinvert.y = 1 - _yinvert.y, _yinvert)
114 /// \param[in] p point
115 /// \param[in] l0 starting point of ldir
116 /// \param[in] ldir line
117 /// \return Vector starting from p perpendicular to ldir
119 vector point_line_vec(vector p, vector l0, vector ldir)
121 ldir = normalize(ldir);
123 // remove the component in line direction from p
124 return p - ((p * ldir) * ldir);
128 * @param dir the directional vector
129 * @param norm the normalized normal
130 * @returns dir reflected by norm
133 vector reflect(vector dir, vector norm)
135 return dir - 2 * (dir * norm) * norm;
139 * clip vel along the plane defined by norm (assuming 0 distance away), bounciness determined by bounce 0..1
142 vector vec_reflect(vector vel, vector norm, float bounce)
144 return vel - (1 + bounce) * (vel * norm) * norm;
148 vector vec_epsilon(vector this, float eps)
150 if (this.x > -eps && this.x < eps) this.x = 0;
151 if (this.y > -eps && this.y < eps) this.y = 0;
152 if (this.z > -eps && this.z < eps) this.z = 0;
156 #define ClipVelocity(in, normal, out, overbounce) \
157 (out = vec_epsilon(vec_reflect(in, normal, (overbounce) - 1), 0.1))
161 vector get_corner_position(entity box, int corner)
165 case 1: return vec3(box.absmin.x, box.absmin.y, box.absmin.z);
166 case 2: return vec3(box.absmax.x, box.absmin.y, box.absmin.z);
167 case 3: return vec3(box.absmin.x, box.absmax.y, box.absmin.z);
168 case 4: return vec3(box.absmin.x, box.absmin.y, box.absmax.z);
169 case 5: return vec3(box.absmax.x, box.absmax.y, box.absmin.z);
170 case 6: return vec3(box.absmin.x, box.absmax.y, box.absmax.z);
171 case 7: return vec3(box.absmax.x, box.absmin.y, box.absmax.z);
172 case 8: return vec3(box.absmax.x, box.absmax.y, box.absmax.z);
173 default: return '0 0 0';
178 vector NearestPointOnBox(entity box, vector org)
180 vector mi = box.mins + box.origin;
181 vector ma = box.maxs + box.origin;
184 bound(mi.x, org.x, ma.x),
185 bound(mi.y, org.y, ma.y),
186 bound(mi.z, org.z, ma.z)
191 vector NearestPointOnBoundingBox(vector mi, vector ma, vector org)
194 bound(mi.x, org.x, ma.x),
195 bound(mi.y, org.y, ma.y),
196 bound(mi.z, org.z, ma.z)