载入中...
搜索中...
未找到
AnimMath.h
浏览该文件的文档.
1#pragma once
2
3#include <cmath>
4#include <algorithm>
5
6namespace eve::animation {
7
10 float px = 0.f, py = 0.f, pz = 0.f;
11 float qx = 0.f, qy = 0.f, qz = 0.f, qw = 1.f;
12 float sx = 1.f, sy = 1.f, sz = 1.f;
13
14 static TransformTRS identity() { return {}; }
15
17 const float len = std::sqrt(qx * qx + qy * qy + qz * qz + qw * qw);
18 if (len > 1e-8f) {
19 const float inv = 1.f / len;
20 qx *= inv;
21 qy *= inv;
22 qz *= inv;
23 qw *= inv;
24 } else {
25 qx = qy = qz = 0.f;
26 qw = 1.f;
27 }
28 }
29};
30
31inline float clampf(float v, float lo, float hi) {
32 return std::max(lo, std::min(hi, v));
33}
34
35inline float lerpf(float a, float b, float t) { return a + (b - a) * t; }
36
37inline void slerpQuat(float ax, float ay, float az, float aw, float bx, float by, float bz, float bw,
38 float t, float &ox, float &oy, float &oz, float &ow) {
39 float cosTheta = ax * bx + ay * by + az * bz + aw * bw;
40 if (cosTheta < 0.f) {
41 bx = -bx;
42 by = -by;
43 bz = -bz;
44 bw = -bw;
45 cosTheta = -cosTheta;
46 }
47 if (cosTheta > 0.9995f) {
48 ox = lerpf(ax, bx, t);
49 oy = lerpf(ay, by, t);
50 oz = lerpf(az, bz, t);
51 ow = lerpf(aw, bw, t);
52 const float len = std::sqrt(ox * ox + oy * oy + oz * oz + ow * ow);
53 if (len > 1e-8f) {
54 const float inv = 1.f / len;
55 ox *= inv;
56 oy *= inv;
57 oz *= inv;
58 ow *= inv;
59 }
60 return;
61 }
62 const float theta = std::acos(clampf(cosTheta, -1.f, 1.f));
63 const float sinTheta = std::sin(theta);
64 const float w0 = std::sin((1.f - t) * theta) / sinTheta;
65 const float w1 = std::sin(t * theta) / sinTheta;
66 ox = ax * w0 + bx * w1;
67 oy = ay * w0 + by * w1;
68 oz = az * w0 + bz * w1;
69 ow = aw * w0 + bw * w1;
70}
71
72inline TransformTRS blendTRS(const TransformTRS &a, const TransformTRS &b, float t) {
73 t = clampf(t, 0.f, 1.f);
74 TransformTRS out;
75 out.px = lerpf(a.px, b.px, t);
76 out.py = lerpf(a.py, b.py, t);
77 out.pz = lerpf(a.pz, b.pz, t);
78 out.sx = lerpf(a.sx, b.sx, t);
79 out.sy = lerpf(a.sy, b.sy, t);
80 out.sz = lerpf(a.sz, b.sz, t);
81 slerpQuat(a.qx, a.qy, a.qz, a.qw, b.qx, b.qy, b.qz, b.qw, t, out.qx, out.qy, out.qz, out.qw);
82 return out;
83}
84
86inline void yawToForward(float yaw, float &fx, float &fz) {
87 fx = std::sin(yaw);
88 fz = std::cos(yaw);
89}
90
91inline float length2(float x, float z) { return std::sqrt(x * x + z * z); }
92
97struct Mat4 {
98 float m[16] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
99
100 static Mat4 identity() { return {}; }
101
102 static Mat4 fromTRS(const TransformTRS &t) {
103 Mat4 out;
104 const float x = t.qx, y = t.qy, z = t.qz, w = t.qw;
105 const float x2 = x + x, y2 = y + y, z2 = z + z;
106 const float xx = x * x2, xy = x * y2, xz = x * z2;
107 const float yy = y * y2, yz = y * z2, zz = z * z2;
108 const float wx = w * x2, wy = w * y2, wz = w * z2;
109
110 out.m[0] = (1.f - (yy + zz)) * t.sx;
111 out.m[1] = (xy + wz) * t.sx;
112 out.m[2] = (xz - wy) * t.sx;
113 out.m[3] = 0.f;
114 out.m[4] = (xy - wz) * t.sy;
115 out.m[5] = (1.f - (xx + zz)) * t.sy;
116 out.m[6] = (yz + wx) * t.sy;
117 out.m[7] = 0.f;
118 out.m[8] = (xz + wy) * t.sz;
119 out.m[9] = (yz - wx) * t.sz;
120 out.m[10] = (1.f - (xx + yy)) * t.sz;
121 out.m[11] = 0.f;
122 out.m[12] = t.px;
123 out.m[13] = t.py;
124 out.m[14] = t.pz;
125 out.m[15] = 1.f;
126 return out;
127 }
128
129 static Mat4 mul(const Mat4 &a, const Mat4 &b) {
130 Mat4 out;
131 for (int col = 0; col < 4; ++col) {
132 for (int row = 0; row < 4; ++row) {
133 out.m[col * 4 + row] = a.m[0 * 4 + row] * b.m[col * 4 + 0] +
134 a.m[1 * 4 + row] * b.m[col * 4 + 1] +
135 a.m[2 * 4 + row] * b.m[col * 4 + 2] +
136 a.m[3 * 4 + row] * b.m[col * 4 + 3];
137 }
138 }
139 return out;
140 }
141
142 void transformPoint(float x, float y, float z, float &ox, float &oy, float &oz) const {
143 ox = m[0] * x + m[4] * y + m[8] * z + m[12];
144 oy = m[1] * x + m[5] * y + m[9] * z + m[13];
145 oz = m[2] * x + m[6] * y + m[10] * z + m[14];
146 }
147};
148
149} // namespace eve::animation
int y
Definition Grass.cpp:135
int z
Definition Grass.cpp:135
int x
Definition Grass.cpp:135
int w
uint32_t a
uint32_t b
int v
TransformTRS blendTRS(const TransformTRS &a, const TransformTRS &b, float t)
Definition AnimMath.h:72
void slerpQuat(float ax, float ay, float az, float aw, float bx, float by, float bz, float bw, float t, float &ox, float &oy, float &oz, float &ow)
Definition AnimMath.h:37
void yawToForward(float yaw, float &fx, float &fz)
Rotate unit +Z by yaw (radians) around Y — used for planar facing.
Definition AnimMath.h:86
float length2(float x, float z)
Definition AnimMath.h:91
float lerpf(float a, float b, float t)
Definition AnimMath.h:35
float clampf(float v, float lo, float hi)
Definition AnimMath.h:31
Column-major 4x4 matrix (OpenGL / glTF / Assimp-compatible layout). Elements: m[col * 4 + row].
Definition AnimMath.h:97
static Mat4 identity()
Definition AnimMath.h:100
static Mat4 fromTRS(const TransformTRS &t)
Definition AnimMath.h:102
void transformPoint(float x, float y, float z, float &ox, float &oy, float &oz) const
Definition AnimMath.h:142
static Mat4 mul(const Mat4 &a, const Mat4 &b)
Definition AnimMath.h:129
Local TRS used by skeletal animation (quaternion xyzw).
Definition AnimMath.h:9
static TransformTRS identity()
Definition AnimMath.h:14