载入中...
搜索中...
未找到
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
15 static TransformTRS identity() { return {}; }
16
19 const float len = std::sqrt(qx * qx + qy * qy + qz * qz + qw * qw);
20 if (len > 1e-8f) {
21 const float inv = 1.f / len;
22 qx *= inv;
23 qy *= inv;
24 qz *= inv;
25 qw *= inv;
26 } else {
27 qx = qy = qz = 0.f;
28 qw = 1.f;
29 }
30 }
31};
32
34inline float clampf(float v, float lo, float hi) {
36 return std::max(lo, std::min(hi, v));
37}
38
40inline float lerpf(float a, float b, float t) { return a + (b - a) * t; }
41
43inline void slerpQuat(float ax, float ay, float az, float aw, float bx, float by, float bz, float bw,
44 float t, float &ox, float &oy, float &oz, float &ow) {
45 float cosTheta = ax * bx + ay * by + az * bz + aw * bw;
46 if (cosTheta < 0.f) {
47 bx = -bx;
48 by = -by;
49 bz = -bz;
50 bw = -bw;
51 cosTheta = -cosTheta;
52 }
53 if (cosTheta > 0.9995f) {
54 ox = lerpf(ax, bx, t);
55 oy = lerpf(ay, by, t);
56 oz = lerpf(az, bz, t);
57 ow = lerpf(aw, bw, t);
58 const float len = std::sqrt(ox * ox + oy * oy + oz * oz + ow * ow);
59 if (len > 1e-8f) {
60 const float inv = 1.f / len;
61 ox *= inv;
62 oy *= inv;
63 oz *= inv;
64 ow *= inv;
65 }
66 return;
67 }
68 const float theta = std::acos(clampf(cosTheta, -1.f, 1.f));
69 const float sinTheta = std::sin(theta);
70 const float w0 = std::sin((1.f - t) * theta) / sinTheta;
71 const float w1 = std::sin(t * theta) / sinTheta;
72 ox = ax * w0 + bx * w1;
73 oy = ay * w0 + by * w1;
74 oz = az * w0 + bz * w1;
75 ow = aw * w0 + bw * w1;
76}
77
79inline TransformTRS blendTRS(const TransformTRS &a, const TransformTRS &b, float t) {
80 t = clampf(t, 0.f, 1.f);
81 TransformTRS out;
82 out.px = lerpf(a.px, b.px, t);
83 out.py = lerpf(a.py, b.py, t);
84 out.pz = lerpf(a.pz, b.pz, t);
85 out.sx = lerpf(a.sx, b.sx, t);
86 out.sy = lerpf(a.sy, b.sy, t);
87 out.sz = lerpf(a.sz, b.sz, t);
89 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);
90 return out;
91}
92
94inline void multiplyQuat(float ax, float ay, float az, float aw, float bx, float by, float bz, float bw, float &ox,
95 float &oy, float &oz, float &ow) {
96 ow = aw * bw - ax * bx - ay * by - az * bz;
97 ox = aw * bx + ax * bw + ay * bz - az * by;
98 oy = aw * by - ax * bz + ay * bw + az * bx;
99 oz = aw * bz + ax * by - ay * bx + az * bw;
100}
101
114inline void applyAdditiveTRS(TransformTRS &base, const TransformTRS &sample, const TransformTRS &reference,
115 float weight) {
116 weight = clampf(weight, 0.f, 1.f);
117 if (weight <= 0.f) return;
118
119 base.px += (sample.px - reference.px) * weight;
120 base.py += (sample.py - reference.py) * weight;
121 base.pz += (sample.pz - reference.pz) * weight;
122 base.sx *= lerpf(1.f, std::fabs(reference.sx) > 1e-8f ? sample.sx / reference.sx : sample.sx, weight);
123 base.sy *= lerpf(1.f, std::fabs(reference.sy) > 1e-8f ? sample.sy / reference.sy : sample.sy, weight);
124 base.sz *= lerpf(1.f, std::fabs(reference.sz) > 1e-8f ? sample.sz / reference.sz : sample.sz, weight);
125
126 float dx, dy, dz, dw;
128 multiplyQuat(sample.qx, sample.qy, sample.qz, sample.qw, -reference.qx, -reference.qy, -reference.qz, reference.qw,
129 dx, dy, dz, dw);
130 float ax, ay, az, aw;
132 slerpQuat(0.f, 0.f, 0.f, 1.f, dx, dy, dz, dw, weight, ax, ay, az, aw);
133 float qx, qy, qz, qw;
135 multiplyQuat(base.qx, base.qy, base.qz, base.qw, ax, ay, az, aw, qx, qy, qz, qw);
136 base.qx = qx;
137 base.qy = qy;
138 base.qz = qz;
139 base.qw = qw;
140 base.normalizeRotation();
141}
142
144inline void yawToForward(float yaw, float &fx, float &fz) {
145 fx = std::sin(yaw);
146 fz = std::cos(yaw);
147}
148
150inline float length2(float x, float z) { return std::sqrt(x * x + z * z); }
151
156struct Mat4 {
157 float m[16] = {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
158
160 static Mat4 identity() { return {}; }
161
163 static Mat4 fromTRS(const TransformTRS &t) {
164 Mat4 out;
165 const float x = t.qx, y = t.qy, z = t.qz, w = t.qw;
166 const float x2 = x + x, y2 = y + y, z2 = z + z;
167 const float xx = x * x2, xy = x * y2, xz = x * z2;
168 const float yy = y * y2, yz = y * z2, zz = z * z2;
169 const float wx = w * x2, wy = w * y2, wz = w * z2;
170
171 out.m[0] = (1.f - (yy + zz)) * t.sx;
172 out.m[1] = (xy + wz) * t.sx;
173 out.m[2] = (xz - wy) * t.sx;
174 out.m[3] = 0.f;
175 out.m[4] = (xy - wz) * t.sy;
176 out.m[5] = (1.f - (xx + zz)) * t.sy;
177 out.m[6] = (yz + wx) * t.sy;
178 out.m[7] = 0.f;
179 out.m[8] = (xz + wy) * t.sz;
180 out.m[9] = (yz - wx) * t.sz;
181 out.m[10] = (1.f - (xx + yy)) * t.sz;
182 out.m[11] = 0.f;
183 out.m[12] = t.px;
184 out.m[13] = t.py;
185 out.m[14] = t.pz;
186 out.m[15] = 1.f;
187 return out;
188 }
189
191 static Mat4 mul(const Mat4 &a, const Mat4 &b) {
192 Mat4 out;
193 for (int col = 0; col < 4; ++col) {
194 for (int row = 0; row < 4; ++row) {
195 out.m[col * 4 + row] = a.m[0 * 4 + row] * b.m[col * 4 + 0] +
196 a.m[1 * 4 + row] * b.m[col * 4 + 1] +
197 a.m[2 * 4 + row] * b.m[col * 4 + 2] +
198 a.m[3 * 4 + row] * b.m[col * 4 + 3];
199 }
200 }
201 return out;
202 }
203
205 void transformPoint(float x, float y, float z, float &ox, float &oy, float &oz) const {
206 ox = m[0] * x + m[4] * y + m[8] * z + m[12];
207 oy = m[1] * x + m[5] * y + m[9] * z + m[13];
208 oz = m[2] * x + m[6] * y + m[10] * z + m[14];
209 }
210};
211
212} // namespace eve::animation
float w
Definition AnimClip.cpp:738
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
AuthorityStoreHandleRef reference
Definition Authority.cpp:24
int bz
Definition CaveMesh.cpp:114
int ax
Definition CaveMesh.cpp:113
int ay
Definition CaveMesh.cpp:113
int bx
Definition CaveMesh.cpp:114
int az
Definition CaveMesh.cpp:113
int by
Definition CaveMesh.cpp:114
float v
MeleePoint3 b
Definition MeleeHit.cpp:41
MeleePoint3 a
Definition MeleeHit.cpp:40
float t
float dz
float dy
float dx
double oy
double ox
float wz
float wx
float qy
float qx
float qw
float qz
float wy
TransformTRS blendTRS(const TransformTRS &a, const TransformTRS &b, float t)
Blend trs.
Definition AnimMath.h:79
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)
Slerp quat.
Definition AnimMath.h:43
void multiplyQuat(float ax, float ay, float az, float aw, float bx, float by, float bz, float bw, float &ox, float &oy, float &oz, float &ow)
Hamilton product a * b for unit quaternions (xyzw).
Definition AnimMath.h:94
void yawToForward(float yaw, float &fx, float &fz)
Rotate unit +Z by yaw (radians) around Y — used for planar facing.
Definition AnimMath.h:144
float length2(float x, float z)
Length 2.
Definition AnimMath.h:150
float lerpf(float a, float b, float t)
Lerpf.
Definition AnimMath.h:40
void applyAdditiveTRS(TransformTRS &base, const TransformTRS &sample, const TransformTRS &reference, float weight)
Apply an additive sample onto base using reference.
Definition AnimMath.h:114
float clampf(float v, float lo, float hi)
Clampf.
Definition AnimMath.h:34
Column-major 4x4 matrix (OpenGL / glTF / Assimp-compatible layout). Elements: m[col * 4 + row].
Definition AnimMath.h:156
static Mat4 identity()
Identity.
Definition AnimMath.h:160
static Mat4 fromTRS(const TransformTRS &t)
From trs.
Definition AnimMath.h:163
void transformPoint(float x, float y, float z, float &ox, float &oy, float &oz) const
Transform point.
Definition AnimMath.h:205
static Mat4 mul(const Mat4 &a, const Mat4 &b)
Mul.
Definition AnimMath.h:191
Local TRS used by skeletal animation (quaternion xyzw).
Definition AnimMath.h:9
static TransformTRS identity()
Identity.
Definition AnimMath.h:15
void normalizeRotation()
Normalize rotation.
Definition AnimMath.h:18