Subversion Repositories Games.Carmageddon

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
20 pmbaty 1
#include "quat.h"
2
#include "matrix34.h"
3
#include "matrix4.h"
4
#include "harness/trace.h"
5
#include <math.h>
6
 
7
#define M(x, y) mat->m[x][y]
8
#define M_DIAG(x) (((br_scalar*)mat->m)[4*(x)])
9
#define Q_EL(e) (((br_scalar*)&(q->x))[(e)])
10
 
11
// IDA: br_quat* __cdecl BrQuatMul(br_quat *q, br_quat *l, br_quat *r)
12
br_quat* BrQuatMul(br_quat* q, br_quat* l, br_quat* r) {
13
    br_scalar x1;
14
    br_scalar x2;
15
    br_scalar x3;
16
    br_scalar x4;
17
    //br_scalar x5; // Pierre-Marie Baty -- unused variable
18
    //br_scalar x6; // Pierre-Marie Baty -- unused variable
19
    //br_scalar x7; // Pierre-Marie Baty -- unused variable
20
    //br_scalar x8; // Pierre-Marie Baty -- unused variable
21
    br_scalar s;
22
    //br_scalar t; // Pierre-Marie Baty -- unused variable
23
    LOG_TRACE("(%p, %p, %p)", q, l, r);
24
 
25
    x1 = (l->x + l->z) * (r->y + r->x);
26
    x2 = (l->w + l->y) * (r->w - r->z);
27
    x3 = (l->w - l->y) * (r->w + r->z);
28
    s = x1 + x2 + x3;
29
    x4 = ((l->z - l->x) * (r->x - r->y) + s) * 0.5f;
30
    q->x = x4 + (l->w + l->x) * (r->w + r->x) - s;
31
    q->y = x4 + (l->w - l->x) * (r->z + r->y) - x3;
32
    q->z = x4 + (l->y + l->z) * (r->w - r->x) - x2;
33
    q->w = x4 + (l->z - l->y) * (r->y - r->z) - x1;
34
    return q;
35
}
36
 
37
// IDA: br_quat* __cdecl BrQuatNormalise(br_quat *q, br_quat *qq)
38
br_quat* BrQuatNormalise(br_quat* q, br_quat* qq) {
39
    br_scalar s;
40
    LOG_TRACE("(%p, %p)", q, qq);
41
 
42
    s = 1.f / sqrtf(qq->x * qq->x + qq->y * qq->y + qq->z * qq->z + qq->w * qq->w);
43
    q->x = qq->x * s;
44
    q->y = qq->y * s;
45
    q->z = qq->z * s;
46
    q->w = qq->w * s;
47
    return q;
48
}
49
 
50
// IDA: br_quat* __cdecl BrQuatInvert(br_quat *q, br_quat *qq)
51
br_quat* BrQuatInvert(br_quat* q, br_quat* qq) {
52
    LOG_TRACE("(%p, %p)", q, qq);
53
 
54
    q->x = -qq->x;
55
    q->y = -qq->y;
56
    q->z = -qq->z;
57
    q->w = qq->w;
58
    return q;
59
}
60
 
61
// IDA: br_quat* __cdecl BrQuatSlerp(br_quat *q, br_quat *l, br_quat *r, br_scalar a, br_int_16 spins)
62
br_quat* BrQuatSlerp(br_quat* q, br_quat* l, br_quat* r, br_scalar a, br_int_16 spins) {
63
    int omega;
64
    int omega_spin;
65
    br_scalar s_omega;
66
    br_scalar c_omega;
67
    br_scalar scale_l;
68
    br_scalar scale_r;
69
    br_quat t;
70
    LOG_TRACE("(%p, %p, %p, %f, %d)", q, l, r, a, spins);
71
 
72
    // Animating rotation with quaternion curves, Ken Shoemake,SIGGRAPH Computer Graphics, 19(3):245–254, 1985. doi:10.1145/325165.325242.
73
    c_omega = l->x * r->x + l->y * r->y + l->z * r->z + l->w * r->w;
74
    if (c_omega >= 0.f) {
75
        t.x = r->x;
76
        t.y = r->y;
77
        t.z = r->z;
78
        t.w = r->w;
79
    } else {
80
        t.x = -r->x;
81
        t.y = -r->y;
82
        t.z = -r->z;
83
        t.w = -r->w;
84
        c_omega = -c_omega;
85
    }
86
 
87
    if ((1.f - c_omega) <= BR_SCALAR_EPSILON) {
88
        scale_l = 1.f - a;
89
        scale_r = a;
90
    } else {
91
        omega = BrRadianToAngle(acosf(c_omega));
92
        s_omega = sinf(BrAngleToRadian(omega));
93
        omega_spin = omega + spins * BR_ANGLE_RAD(PI);
94
        scale_l = sinf(BrAngleToRadian(omega - a * omega_spin)) / s_omega;
95
        scale_r = sinf(BrAngleToRadian(a * omega_spin)) / s_omega;
96
    }
97
    q->x = scale_l * l->x + scale_r * t.x;
98
    q->y = scale_l * l->y + scale_r * t.y;
99
    q->z = scale_l * l->z + scale_r * t.z;
100
    q->w = scale_l * l->w + scale_r * t.w;
101
    return q;
102
}
103
 
104
// IDA: br_matrix34* __cdecl BrQuatToMatrix34(br_matrix34 *mat, br_quat *q)
105
br_matrix34* BrQuatToMatrix34(br_matrix34* mat, br_quat* q) {
106
    br_scalar xs;
107
    br_scalar ys;
108
    br_scalar zs;
109
    br_scalar wx;
110
    br_scalar wy;
111
    br_scalar wz;
112
    br_scalar xx;
113
    br_scalar xy;
114
    br_scalar xz;
115
    br_scalar yy;
116
    br_scalar yz;
117
    br_scalar zz;
118
    LOG_TRACE("(%p, %p)", mat, q);
119
 
120
    zz = q->z + q->z;
121
    yy = q->y + q->y;
122
    zs = q->z * zz;
123
    xx = q->x + q->x;
124
    wx = q->w * xx;
125
    wy = q->w * yy;
126
    wz = q->w * zz;
127
    xy = q->x * yy;
128
    xz = q->x * zz;
129
    ys = q->y * yy;
130
    xs = q->x * xx;
131
    yz = q->y * zz;
132
 
133
    M(0, 0) = 1.f - (ys + zs);
134
    M(1, 0) = xy - wz;
135
    M(2, 0) = xz + wy;
136
    M(0, 1) = xy + wz;
137
    M(1, 1) = 1.f - (zs + xs);
138
    M(2, 1) = yz - wx;
139
    M(0, 2) = xz - wy;
140
    M(1, 2) = yz + wx;
141
    M(2, 2) = 1.f - (xs + ys);
142
    M(3, 0) = 0.f;
143
    M(3, 1) = 0.f;
144
    M(3, 2) = 0.f;
145
 
146
    return mat;
147
}
148
 
149
// IDA: br_quat* __cdecl BrMatrix34ToQuat(br_quat *q, br_matrix34 *mat)
150
br_quat* BrMatrix34ToQuat(br_quat* q, br_matrix34* mat) {
151
    br_scalar tr;
152
    br_scalar s;
153
    int i;
154
    int j;
155
    int k;
156
    LOG_TRACE("(%p, %p)", q, mat);
157
 
158
    tr = M(0, 0) + M(1, 1) + M(2, 2);
159
    if (tr >= 0.f) {
160
        tr = sqrtf(tr + 1.f);
161
        s = 0.5f / tr;
162
        q->w = tr * 0.5f;
163
        q->x = (M(1, 2) - M(2, 1)) * s;
164
        q->y = (M(2, 0) - M(0, 2)) * s;
165
        q->z = (M(0, 1) - M(1, 0)) * s;
166
        return q;
167
    }
168
    i = M_DIAG(1) >= M_DIAG(0) ? 1 : 0;
169
    i = M_DIAG(2) >= M_DIAG(i) ? 2 : i;
170
    j = (i + 1) % 3;
171
    k = (j + 1) % 3;
172
    tr = sqrtf(M_DIAG(i) - (M_DIAG(j) + M_DIAG(k)) + 1.f);
173
    s = 0.5f / tr;
174
    Q_EL(i) = 0.5f * tr;
175
    Q_EL(j) = (M(i, j) + M(j, i)) * s;
176
    Q_EL(k) = (M(i, k) + M(k, i)) * s;
177
    q->w = (M(k, j) - M(j, k)) * s;
178
    return q;
179
}
180
 
181
// IDA: br_matrix4* __cdecl BrQuatToMatrix4(br_matrix4 *mat, br_quat *q)
182
br_matrix4* BrQuatToMatrix4(br_matrix4* mat, br_quat* q) {
183
    br_matrix34 tmp;
184
    LOG_TRACE("(%p, %p)", mat, q);
185
 
186
    BrQuatToMatrix34(&tmp, q);
187
    BrMatrix4Copy34(mat, &tmp);
188
    return mat;
189
}
190
 
191
// IDA: br_quat* __cdecl BrMatrix4ToQuat(br_quat *q, br_matrix4 *mat)
192
br_quat* BrMatrix4ToQuat(br_quat* q, br_matrix4* mat) {
193
    br_matrix34 tmp;
194
    LOG_TRACE("(%p, %p)", q, mat);
195
 
196
    BrMatrix34Copy4(&tmp, mat);
197
    return BrMatrix34ToQuat(q, &tmp);
198
}