2
Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
5
This program is free software: you can redistribute it and/or modify
6
it under the terms of the GNU Lesser General Public License as published
7
by the Free Software Foundation, either version 2.1 of the License, or
8
(at your option) any later version.
10
Thisprogram is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU Lesser General Public License for more details.
15
You should have received a copy of the GNU Lesser General Public License
16
along with this program; If not, see <http://www.gnu.org/licenses/>.
18
#include "lib3ds_impl.h"
22
lib3ds_track_new(Lib3dsTrackType type, int nkeys) {
23
Lib3dsTrack *track = (Lib3dsTrack*)calloc(sizeof(Lib3dsTrack), 1);
25
lib3ds_track_resize(track, nkeys);
31
lib3ds_track_free(Lib3dsTrack *track) {
33
lib3ds_track_resize(track, 0);
34
memset(track, 0, sizeof(Lib3dsTrack));
40
lib3ds_track_resize(Lib3dsTrack *track, int nkeys) {
44
if (track->nkeys == nkeys)
47
p = (char*)realloc(track->keys, sizeof(Lib3dsKey) * nkeys);
48
if (nkeys > track->nkeys) {
49
memset(p + (sizeof(Lib3dsKey)*track->nkeys), 0, sizeof(Lib3dsKey)*(nkeys - track->nkeys));
51
track->keys = (Lib3dsKey*)p;
57
pos_key_setup(int n, Lib3dsKey *pp, Lib3dsKey *pc, Lib3dsKey *pn, float *dd, float *ds) {
58
float tm, cm, cp, bm, bp, tmcm, tmcp, ksm, ksp, kdm, kdp, c;
60
float delm[3], delp[3];
66
dt = 0.5f * (pn->frame - pp->frame);
67
fp = (float)(pc->frame - pp->frame) / dt;
68
fn = (float)(pn->frame - pc->frame) / dt;
69
c = (float)fabs(pc->cont);
75
tm = 0.5f * (1.0f - pc->tens);
86
for (i = 0; i < n; ++i) delm[i] = delp[i] = 0;
88
for (i = 0; i < n; ++i) delm[i] = pc->value[i] - pp->value[i];
91
for (i = 0; i < n; ++i) delp[i] = pn->value[i] - pc->value[i];
94
for (i = 0; i < n; ++i) delm[i] = delp[i];
97
for (i = 0; i < n; ++i) delp[i] = delm[i];
100
for (i = 0; i < n; ++i) {
101
ds[i] = ksm * delm[i] + ksp * delp[i];
102
dd[i] = kdm * delm[i] + kdp * delp[i];
108
rot_key_setup(Lib3dsKey *prev, Lib3dsKey *cur, Lib3dsKey *next, float a[4], float b[4]) {
109
float tm, cm, cp, bm, bp, tmcm, tmcp, ksm, ksp, kdm, kdp, c;
111
float q[4], qm[4], qp[4], qa[4], qb[4];
116
if (cur->value[3] > LIB3DS_TWOPI - LIB3DS_EPSILON) {
117
lib3ds_quat_axis_angle(qm, cur->value, 0.0f);
120
lib3ds_quat_copy(q, prev->value);
121
if (lib3ds_quat_dot(q, cur->value) < 0) lib3ds_quat_neg(q);
122
lib3ds_quat_ln_dif(qm, q, cur->value);
126
if (next->value[3] > LIB3DS_TWOPI - LIB3DS_EPSILON) {
127
lib3ds_quat_axis_angle(qp, next->value, 0.0f);
130
lib3ds_quat_copy(q, next->value);
131
if (lib3ds_quat_dot(q, cur->value) < 0) lib3ds_quat_neg(q);
132
lib3ds_quat_ln_dif(qp, cur->value, q);
135
if (!prev) lib3ds_quat_copy(qm, qp);
136
if (!next) lib3ds_quat_copy(qp, qm);
139
cm = 1.0f - cur->cont;
141
dt = 0.5f * (next->frame - prev->frame);
142
fp = (float)(cur->frame - prev->frame) / dt;
143
fn = (float)(next->frame - cur->frame) / dt;
144
c = (float)fabs(cur->cont);
145
fp = fp + c - c * fp;
146
fn = fn + c - c * fn;
149
tm = 0.5f * (1.0f - cur->tens);
151
bm = 1.0f - cur->bias;
155
ksm = 1.0f - tmcm * bp * fp;
156
ksp = -tmcp * bm * fp;
157
kdm = tmcp * bp * fn;
158
kdp = tmcm * bm * fn - 1.0f;
160
for (i = 0; i < 4; i++) {
161
qa[i] = 0.5f * (kdm * qm[i] + kdp * qp[i]);
162
qb[i] = 0.5f * (ksm * qm[i] + ksp * qp[i]);
167
lib3ds_quat_mul(a, cur->value, qa);
168
lib3ds_quat_mul(b, cur->value, qb);
173
quat_for_index(Lib3dsTrack *track, int index, float q[4]) {
176
lib3ds_quat_identity(q);
177
for (i = 0; i <= index; ++i) {
178
lib3ds_quat_axis_angle(p, track->keys[i].value, track->keys[i].value[3]);
179
lib3ds_quat_mul(q, p, q);
185
find_index(Lib3dsTrack *track, float t, float *u) {
191
assert(track->nkeys > 0);
193
if (track->nkeys <= 1)
196
t0 = track->keys[0].frame;
197
t1 = track->keys[track->nkeys-1].frame;
198
if (track->flags & LIB3DS_TRACK_REPEAT) {
199
nt = (float)fmod((float)(t - t0), (float)(t1 - t0)) + t0;
211
for (i = 1; i < track->nkeys; ++i) {
212
if (nt < track->keys[i].frame)
216
*u = nt - (float)track->keys[i-1].frame;
217
*u /= (float)(track->keys[i].frame - track->keys[i-1].frame);
219
assert((*u >= 0.0f) && (*u <= 1.0f));
225
setup_segment(Lib3dsTrack *track, int index, Lib3dsKey *pp, Lib3dsKey *p0, Lib3dsKey *p1, Lib3dsKey *pn) {
229
pp->frame = pn->frame = -1;
232
*pp = track->keys[index - 2];
234
if (track->flags & LIB3DS_TRACK_SMOOTH) {
235
ip = track->nkeys - 2;
236
*pp = track->keys[track->nkeys - 2];
237
pp->frame = track->keys[track->nkeys - 2].frame - (track->keys[track->nkeys - 1].frame - track->keys[0].frame);
241
*p0 = track->keys[index - 1];
242
*p1 = track->keys[index];
244
if (index < (int)track->nkeys - 1) {
246
*pn = track->keys[index + 1];
248
if (track->flags & LIB3DS_TRACK_SMOOTH) {
250
*pn = track->keys[1];
251
pn->frame = track->keys[1].frame + (track->keys[track->nkeys-1].frame - track->keys[0].frame);
255
if (track->type == LIB3DS_TRACK_QUAT) {
257
if (pp->frame >= 0) {
258
quat_for_index(track, ip, pp->value);
260
lib3ds_quat_identity(pp->value);
263
quat_for_index(track, index - 1, p0->value);
264
lib3ds_quat_axis_angle(q, track->keys[index].value, track->keys[index].value[3]);
265
lib3ds_quat_mul(p1->value, q, p0->value);
267
if (pn->frame >= 0) {
268
lib3ds_quat_axis_angle(q, track->keys[in].value, track->keys[in].value[3]);
269
lib3ds_quat_mul(pn->value, q, p1->value);
271
lib3ds_quat_identity(pn->value);
278
lib3ds_track_eval_bool(Lib3dsTrack *track, int *b, float t) {
284
assert(track->type == LIB3DS_TRACK_BOOL);
289
index = find_index(track, t, &u);
294
if (index >= track->nkeys) {
295
*b = !(track->nkeys & 1);
304
track_eval_linear(Lib3dsTrack *track, float *value, float t) {
305
Lib3dsKey pp, p0, p1, pn;
308
float dsp[3], ddp[3], dsn[3], ddn[3];
313
for (i = 0; i < track->type; ++i) value[i] = 0.0f;
317
index = find_index(track, t, &u);
321
for (i = 0; i < track->type; ++i) value[i] = track->keys[0].value[i];
324
if (index >= track->nkeys) {
326
for (i = 0; i < track->type; ++i) value[i] = track->keys[track->nkeys-1].value[i];
330
setup_segment(track, index, &pp, &p0, &p1, &pn);
332
pos_key_setup(track->type, pp.frame>=0? &pp : NULL, &p0, &p1, ddp, dsp);
333
pos_key_setup(track->type, &p0, &p1, pn.frame>=0? &pn : NULL, ddn, dsn);
335
lib3ds_math_cubic_interp(
348
lib3ds_track_eval_float(Lib3dsTrack *track, float *f, float t) {
351
assert(track->type == LIB3DS_TRACK_FLOAT);
352
track_eval_linear(track, f, t);
358
lib3ds_track_eval_vector(Lib3dsTrack *track, float v[3], float t) {
359
lib3ds_vector_zero(v);
361
assert(track->type == LIB3DS_TRACK_VECTOR);
362
track_eval_linear(track, v, t);
368
lib3ds_track_eval_quat(Lib3dsTrack *track, float q[4], float t) {
369
lib3ds_quat_identity(q);
371
Lib3dsKey pp, p0, p1, pn;
374
float ap[4], bp[4], an[4], bn[4];
376
assert(track->type == LIB3DS_TRACK_QUAT);
381
index = find_index(track, t, &u);
383
lib3ds_quat_axis_angle(q, track->keys[0].value, track->keys[0].value[3]);
386
if (index >= track->nkeys) {
387
quat_for_index(track, track->nkeys - 1, q);
391
setup_segment(track, index, &pp, &p0, &p1, &pn);
393
rot_key_setup(pp.frame>=0? &pp : NULL, &p0, &p1, ap, bp);
394
rot_key_setup(&p0, &p1, pn.frame>=0? &pn : NULL, an, bn);
396
lib3ds_quat_squad(q, p0.value, ap, bn, p1.value, u);
402
tcb_read(Lib3dsKey *key, Lib3dsIo *io) {
403
key->flags = lib3ds_io_read_word(io);
404
if (key->flags & LIB3DS_KEY_USE_TENS) {
405
key->tens = lib3ds_io_read_float(io);
407
if (key->flags & LIB3DS_KEY_USE_CONT) {
408
key->cont = lib3ds_io_read_float(io);
410
if (key->flags & LIB3DS_KEY_USE_BIAS) {
411
key->bias = lib3ds_io_read_float(io);
413
if (key->flags & LIB3DS_KEY_USE_EASE_TO) {
414
key->ease_to = lib3ds_io_read_float(io);
416
if (key->flags & LIB3DS_KEY_USE_EASE_FROM) {
417
key->ease_from = lib3ds_io_read_float(io);
423
lib3ds_track_read(Lib3dsTrack *track, Lib3dsIo *io) {
427
track->flags = lib3ds_io_read_word(io);
428
lib3ds_io_read_dword(io);
429
lib3ds_io_read_dword(io);
430
nkeys = lib3ds_io_read_intd(io);
431
lib3ds_track_resize(track, nkeys);
433
switch (track->type) {
434
case LIB3DS_TRACK_BOOL:
435
for (i = 0; i < nkeys; ++i) {
436
track->keys[i].frame = lib3ds_io_read_intd(io);
437
tcb_read(&track->keys[i], io);
441
case LIB3DS_TRACK_FLOAT:
442
for (i = 0; i < nkeys; ++i) {
443
track->keys[i].frame = lib3ds_io_read_intd(io);
444
tcb_read(&track->keys[i], io);
445
track->keys[i].value[0] = lib3ds_io_read_float(io);
449
case LIB3DS_TRACK_VECTOR:
450
for (i = 0; i < nkeys; ++i) {
451
track->keys[i].frame = lib3ds_io_read_intd(io);
452
tcb_read(&track->keys[i], io);
453
lib3ds_io_read_vector(io, track->keys[i].value);
457
case LIB3DS_TRACK_QUAT:
458
for (i = 0; i < nkeys; ++i) {
459
track->keys[i].frame = lib3ds_io_read_intd(io);
460
tcb_read(&track->keys[i], io);
461
track->keys[i].value[3] = lib3ds_io_read_float(io);
462
lib3ds_io_read_vector(io, track->keys[i].value);
466
/*case LIB3DS_TRACK_MORPH:
467
for (i = 0; i < nkeys; ++i) {
468
track->keys[i].frame = lib3ds_io_read_intd(io);
469
tcb_read(&track->keys[i].tcb, io);
470
lib3ds_io_read_string(io, track->keys[i].data.m.name, 64);
481
tcb_write(Lib3dsKey *key, Lib3dsIo *io) {
482
lib3ds_io_write_word(io, (uint16_t)key->flags);
483
if (key->flags & LIB3DS_KEY_USE_TENS) {
484
lib3ds_io_write_float(io, key->tens);
486
if (key->flags & LIB3DS_KEY_USE_CONT) {
487
lib3ds_io_write_float(io, key->cont);
489
if (key->flags & LIB3DS_KEY_USE_BIAS) {
490
lib3ds_io_write_float(io, key->bias);
492
if (key->flags & LIB3DS_KEY_USE_EASE_TO) {
493
lib3ds_io_write_float(io, key->ease_to);
495
if (key->flags & LIB3DS_KEY_USE_EASE_FROM) {
496
lib3ds_io_write_float(io, key->ease_from);
502
lib3ds_track_write(Lib3dsTrack *track, Lib3dsIo *io) {
505
lib3ds_io_write_word(io, (uint16_t)track->flags);
506
lib3ds_io_write_dword(io, 0);
507
lib3ds_io_write_dword(io, 0);
508
lib3ds_io_write_dword(io, track->nkeys);
510
switch (track->type) {
511
case LIB3DS_TRACK_BOOL:
512
for (i = 0; i < track->nkeys; ++i) {
513
lib3ds_io_write_intd(io, track->keys[i].frame);
514
tcb_write(&track->keys[i], io);
518
case LIB3DS_TRACK_FLOAT:
519
for (i = 0; i < track->nkeys; ++i) {
520
lib3ds_io_write_intd(io, track->keys[i].frame);
521
tcb_write(&track->keys[i], io);
522
lib3ds_io_write_float(io, track->keys[i].value[0]);
526
case LIB3DS_TRACK_VECTOR:
527
for (i = 0; i < track->nkeys; ++i) {
528
lib3ds_io_write_intd(io, track->keys[i].frame);
529
tcb_write(&track->keys[i], io);
530
lib3ds_io_write_vector(io, track->keys[i].value);
534
case LIB3DS_TRACK_QUAT:
535
for (i = 0; i < track->nkeys; ++i) {
536
lib3ds_io_write_intd(io, track->keys[i].frame);
537
tcb_write(&track->keys[i], io);
538
lib3ds_io_write_float(io, track->keys[i].value[3]);
539
lib3ds_io_write_vector(io, track->keys[i].value);
543
/*case LIB3DS_TRACK_MORPH:
544
for (i = 0; i < track->nkeys; ++i) {
545
lib3ds_io_write_intd(io, track->keys[i].frame);
546
tcb_write(&track->keys[i].tcb, io);
547
lib3ds_io_write_string(io, track->keys[i].data.m.name);