📄 nv_algebra.cpp
字号:
B.a20 = A.a02; B.a21 = A.a12; B.a22 = A.a22; return B;}/* calculate the determinent of a 2x2 matrix in the from | a1 a2 | | b1 b2 |*/nv_scalar det2x2(nv_scalar a1, nv_scalar a2, nv_scalar b1, nv_scalar b2){ return a1 * b2 - b1 * a2;}/* calculate the determinent of a 3x3 matrix in the from | a1 a2 a3 | | b1 b2 b3 | | c1 c2 c3 |*/nv_scalar det3x3(nv_scalar a1, nv_scalar a2, nv_scalar a3, nv_scalar b1, nv_scalar b2, nv_scalar b3, nv_scalar c1, nv_scalar c2, nv_scalar c3){ return a1 * det2x2(b2, b3, c2, c3) - b1 * det2x2(a2, a3, c2, c3) + c1 * det2x2(a2, a3, b2, b3);}mat4 & invert(mat4& B, const mat4& A){ nv_scalar det,oodet; B.a00 = det3x3(A.a11, A.a21, A.a31, A.a12, A.a22, A.a32, A.a13, A.a23, A.a33); B.a10 = -det3x3(A.a10, A.a20, A.a30, A.a12, A.a22, A.a32, A.a13, A.a23, A.a33); B.a20 = det3x3(A.a10, A.a20, A.a30, A.a11, A.a21, A.a31, A.a13, A.a23, A.a33); B.a30 = -det3x3(A.a10, A.a20, A.a30, A.a11, A.a21, A.a31, A.a12, A.a22, A.a32); B.a01 = -det3x3(A.a01, A.a21, A.a31, A.a02, A.a22, A.a32, A.a03, A.a23, A.a33); B.a11 = det3x3(A.a00, A.a20, A.a30, A.a02, A.a22, A.a32, A.a03, A.a23, A.a33); B.a21 = -det3x3(A.a00, A.a20, A.a30, A.a01, A.a21, A.a31, A.a03, A.a23, A.a33); B.a31 = det3x3(A.a00, A.a20, A.a30, A.a01, A.a21, A.a31, A.a02, A.a22, A.a32); B.a02 = det3x3(A.a01, A.a11, A.a31, A.a02, A.a12, A.a32, A.a03, A.a13, A.a33); B.a12 = -det3x3(A.a00, A.a10, A.a30, A.a02, A.a12, A.a32, A.a03, A.a13, A.a33); B.a22 = det3x3(A.a00, A.a10, A.a30, A.a01, A.a11, A.a31, A.a03, A.a13, A.a33); B.a32 = -det3x3(A.a00, A.a10, A.a30, A.a01, A.a11, A.a31, A.a02, A.a12, A.a32); B.a03 = -det3x3(A.a01, A.a11, A.a21, A.a02, A.a12, A.a22, A.a03, A.a13, A.a23); B.a13 = det3x3(A.a00, A.a10, A.a20, A.a02, A.a12, A.a22, A.a03, A.a13, A.a23); B.a23 = -det3x3(A.a00, A.a10, A.a20, A.a01, A.a11, A.a21, A.a03, A.a13, A.a23); B.a33 = det3x3(A.a00, A.a10, A.a20, A.a01, A.a11, A.a21, A.a02, A.a12, A.a22); det = (A.a00 * B.a00) + (A.a01 * B.a10) + (A.a02 * B.a20) + (A.a03 * B.a30); oodet = nv_one / det; B.a00 *= oodet; B.a10 *= oodet; B.a20 *= oodet; B.a30 *= oodet; B.a01 *= oodet; B.a11 *= oodet; B.a21 *= oodet; B.a31 *= oodet; B.a02 *= oodet; B.a12 *= oodet; B.a22 *= oodet; B.a32 *= oodet; B.a03 *= oodet; B.a13 *= oodet; B.a23 *= oodet; B.a33 *= oodet; return B;}mat4 & invert_rot_trans(mat4& B, const mat4& A){ B.a00 = A.a00; B.a10 = A.a01; B.a20 = A.a02; B.a30 = A.a30; B.a01 = A.a10; B.a11 = A.a11; B.a21 = A.a12; B.a31 = A.a31; B.a02 = A.a20; B.a12 = A.a21; B.a22 = A.a22; B.a32 = A.a32; B.a03 = - (A.a00 * A.a03 + A.a10 * A.a13 + A.a20 * A.a23); B.a13 = - (A.a01 * A.a03 + A.a11 * A.a13 + A.a21 * A.a23); B.a23 = - (A.a02 * A.a03 + A.a12 * A.a13 + A.a22 * A.a23); B.a33 = A.a33; return B;}nv_scalar det(const mat3& A){ return det3x3(A.a00, A.a01, A.a02, A.a10, A.a11, A.a12, A.a20, A.a21, A.a22);}mat3 & invert(mat3& B, const mat3& A){ nv_scalar det,oodet; B.a00 = (A.a11 * A.a22 - A.a21 * A.a12); B.a10 = -(A.a10 * A.a22 - A.a20 * A.a12); B.a20 = (A.a10 * A.a21 - A.a20 * A.a11); B.a01 = -(A.a01 * A.a22 - A.a21 * A.a02); B.a11 = (A.a00 * A.a22 - A.a20 * A.a02); B.a21 = -(A.a00 * A.a21 - A.a20 * A.a01); B.a02 = (A.a01 * A.a12 - A.a11 * A.a02); B.a12 = -(A.a00 * A.a12 - A.a10 * A.a02); B.a22 = (A.a00 * A.a11 - A.a10 * A.a01); det = (A.a00 * B.a00) + (A.a01 * B.a10) + (A.a02 * B.a20); oodet = nv_one / det; B.a00 *= oodet; B.a01 *= oodet; B.a02 *= oodet; B.a10 *= oodet; B.a11 *= oodet; B.a12 *= oodet; B.a20 *= oodet; B.a21 *= oodet; B.a22 *= oodet; return B;}vec3 & normalize(vec3& u){ nv_scalar norm = sqrtf(u.x * u.x + u.y * u.y + u.z * u.z); if (norm > nv_eps) norm = nv_one / norm; else norm = nv_zero; return scale(u,norm); }vec4 & normalize(vec4& u){ nv_scalar norm = sqrtf(u.x * u.x + u.y * u.y + u.z * u.z + u.w * u.w); if (norm > nv_eps) norm = nv_one / norm; else norm = nv_zero; return scale(u,norm); }quat & normalize(quat & p){ nv_scalar norm = sqrtf(p.x * p.x + p.y * p.y + p.z * p.z + p.w * p.w); if (norm > nv_eps) norm = nv_one / norm; else norm = nv_zero; p.x *= norm; p.y *= norm; p.z *= norm; p.w *= norm; return p; }mat4 & look_at(mat4& M, const vec3& eye, const vec3& center, const vec3& up){ vec3 x, y, z; // make rotation matrix // Z vector z.x = eye.x - center.x; z.y = eye.y - center.y; z.z = eye.z - center.z; normalize(z); // Y vector y.x = up.x; y.y = up.y; y.z = up.z; // X vector = Y cross Z cross(x,y,z); // Recompute Y = Z cross X cross(y,z,x); // cross product gives area of parallelogram, which is < 1.0 for // non-perpendicular unit-length vectors; so normalize x, y here normalize(x); normalize(y); M.a00 = x.x; M.a01 = x.y; M.a02 = x.z; M.a03 = -x.x * eye.x - x.y * eye.y - x.z*eye.z; M.a10 = y.x; M.a11 = y.y; M.a12 = y.z; M.a13 = -y.x * eye.x - y.y * eye.y - y.z*eye.z; M.a20 = z.x; M.a21 = z.y; M.a22 = z.z; M.a23 = -z.x * eye.x - z.y * eye.y - z.z*eye.z; M.a30 = nv_zero; M.a31 = nv_zero; M.a32 = nv_zero; M.a33 = nv_one; return M;}mat4 & frustum(mat4& M, const nv_scalar l, const nv_scalar r, const nv_scalar b, const nv_scalar t, const nv_scalar n, const nv_scalar f){ M.a00 = (nv_two*n) / (r-l); M.a10 = 0.0; M.a20 = 0.0; M.a30 = 0.0; M.a01 = 0.0; M.a11 = (nv_two*n) / (t-b); M.a21 = 0.0; M.a31 = 0.0; M.a02 = (r+l) / (r-l); M.a12 = (t+b) / (t-b); M.a22 = -(f+n) / (f-n); M.a32 = -nv_one; M.a03 = 0.0; M.a13 = 0.0; M.a23 = -(nv_two*f*n) / (f-n); M.a33 = 0.0; return M;}mat4 & perspective(mat4& M, const nv_scalar fovy, const nv_scalar aspect, const nv_scalar n, const nv_scalar f){ nv_scalar xmin, xmax, ymin, ymax; ymax = n * tanf(fovy * nv_to_rad * nv_zero_5); ymin = -ymax; xmin = ymin * aspect; xmax = ymax * aspect; return frustum(M, xmin, xmax, ymin, ymax, n, f);}const quat quat::Identity(0, 0, 0, 1);quat::quat(nv_scalar x, nv_scalar y, nv_scalar z, nv_scalar w) : x(x), y(y), z(z), w(w){}quat::quat(const quat& quat){ x = quat.x; y = quat.y; z = quat.z; w = quat.w;}quat::quat(const vec3& axis, nv_scalar angle){ nv_scalar len = axis.norm(); if (len) { nv_scalar invLen = 1 / len; nv_scalar angle2 = angle / 2; nv_scalar scale = sinf(angle2) * invLen; x = scale * axis[0]; y = scale * axis[1]; z = scale * axis[2]; w = cosf(angle2); }}quat::quat(const mat3& rot){ FromMatrix(rot);}quat& quat::operator=(const quat& quat){ x = quat.x; y = quat.y; z = quat.z; w = quat.w; return *this;}quat quat::Inverse(){ return quat(- x, - y, - z, w);}void quat::Normalize(){ nv_scalar len = sqrtf(x * x + y * y + z * z + w * w); if (len > 0) { nv_scalar invLen = 1 / len; x *= invLen; y *= invLen; z *= invLen; w *= invLen; }}void quat::FromMatrix(const mat3& mat){ nv_scalar trace = mat(0, 0) + mat(1, 1) + mat(2, 2); if (trace > 0) { nv_scalar scale = sqrtf(trace + 1.0f); w = 0.5f * scale; scale = 0.5f / scale; x = scale * (mat(2, 1) - mat(1, 2)); y = scale * (mat(0, 2) - mat(2, 0)); z = scale * (mat(1, 0) - mat(0, 1)); } else { static int next[] = { 1, 2, 0 }; int i = 0; if (mat(1, 1) > mat(0, 0)) i = 1; if (mat(2, 2) > mat(i, i)) i = 2; int j = next[i]; int k = next[j]; nv_scalar scale = sqrtf(mat(i, i) - mat(j, j) - mat(k, k) + 1); nv_scalar* q[] = { &x, &y, &z }; *q[i] = 0.5f * scale; scale = 0.5f / scale; w = scale * (mat(k, j) - mat(j, k)); *q[j] = scale * (mat(j, i) + mat(i, j)); *q[k] = scale * (mat(k, i) + mat(i, k)); }}void quat::ToMatrix(mat3& mat) const{ nv_scalar x2 = x * 2; nv_scalar y2 = y * 2; nv_scalar z2 = z * 2; nv_scalar wx = x2 * w; nv_scalar wy = y2 * w; nv_scalar wz = z2 * w; nv_scalar xx = x2 * x; nv_scalar xy = y2 * x; nv_scalar xz = z2 * x; nv_scalar yy = y2 * y; nv_scalar yz = z2 * y; nv_scalar zz = z2 * z; mat(0, 0) = 1 - (yy + zz); mat(0, 1) = xy - wz; mat(0, 2) = xz + wy; mat(1, 0) = xy + wz; mat(1, 1) = 1 - (xx + zz); mat(1, 2) = yz - wx; mat(2, 0) = xz - wy; mat(2, 1) = yz + wx; mat(2, 2) = 1 - (xx + yy);}const quat operator*(const quat& p, const quat& q){ return quat( p.w * q.x + p.x * q.w + p.y * q.z - p.z * q.y, p.w * q.y + p.y * q.w + p.z * q.x - p.x * q.z, p.w * q.z + p.z * q.w + p.x * q.y - p.y * q.x, p.w * q.w - p.x * q.x - p.y * q.y - p.z * q.z );}quat& quat::operator*=(const quat& quat){ *this = *this * quat; return *this;}mat3 & quat_2_mat(mat3& M, const quat& q){ q.ToMatrix(M); return M;}quat & mat_2_quat(quat& q, const mat3& M){ q.FromMatrix(M); return q;} quat & mat_2_quat(quat& q, const mat4& M){ mat3 m; M.get_rot(m); q.FromMatrix(m); return q;} /* Given an axis and angle, compute quaternion. */quat & axis_to_quat(quat& q, const vec3& a, const nv_scalar phi){ vec3 tmp(a.x, a.y, a.z); normalize(tmp); nv_scalar s = sinf(phi/nv_two); q.x = s * tmp.x; q.y = s * tmp.y; q.z = s * tmp.z; q.w = cosf(phi/nv_two); return q;}quat & conj(quat & p){ p.x = -p.x; p.y = -p.y; p.z = -p.z; return p;} quat & conj(quat& p, const quat& q){ p.x = -q.x; p.y = -q.y; p.z = -q.z; p.w = q.w; return p;} quat & add_quats(quat& p, const quat& q1, const quat& q2){ quat t1, t2; t1 = q1; t1.x *= q2.w; t1.y *= q2.w; t1.z *= q2.w; t2 = q2; t2.x *= q1.w; t2.y *= q1.w; t2.z *= q1.w; p.x = (q2.y * q1.z) - (q2.z * q1.y) + t1.x + t2.x; p.y = (q2.z * q1.x) - (q2.x * q1.z) + t1.y + t2.y; p.z = (q2.x * q1.y) - (q2.y * q1.x) + t1.z + t2.z; p.w = q1.w * q2.w - (q1.x * q2.x + q1.y * q2.y + q1.z * q2.z); return p;}nv_scalar & dot(nv_scalar& s, const quat& q1, const quat& q2){ s = q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w; return s;}nv_scalar dot(const quat& q1, const quat& q2){ return q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w;}#ifndef acosf#define acosf acos#endifquat & slerp_quats(quat & p, nv_scalar s, const quat & q1, const quat & q2){ nv_scalar cosine = dot(q1, q2); if (cosine < -1) cosine = -1; else if (cosine > 1) cosine = 1; nv_scalar angle = acosf(cosine); if (fabs(angle) < nv_eps) { p = q1; return p; } nv_scalar sine = sinf(angle); nv_scalar sineInv = 1.0f / sine; nv_scalar c1 = sinf((1.0f - s) * angle) * sineInv; nv_scalar c2 = sinf(s * angle) * sineInv; p.x = c1 * q1.x + c2 * q2.x; p.y = c1 * q1.y + c2 * q2.y; p.z = c1 * q1.z + c2 * q2.z; p.w = c1 * q1.w + c2 * q2.w; return p;}const int HALF_RAND = (RAND_MAX / 2); nv_scalar nv_random(){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -