root/OpenSceneGraph/trunk/src/osgPlugins/3ds/tracks.cpp @ 10076

Revision 10076, 23.5 kB (checked in by robert, 6 years ago)

From Neil Hughes, converted across to use istream for reading data from file to enable reading .3ds files over http (use OSG's libcurl plugin).

From Robert Osfield, ammendments of the above to better support reading of files from local directories.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
RevLine 
[8]1/*
2 * The 3D Studio File Format Library
3 * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
4 * All rights reserved.
5 *
6 * This program is  free  software;  you can redistribute it and/or modify it
[151]7 * under the terms of the  GNU Lesser General Public License  as published by
8 * the  Free Software Foundation;  either version 2.1 of the License,  or (at
[8]9 * your option) any later version.
10 *
11 * This  program  is  distributed in  the  hope that it will  be useful,  but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
[151]13 * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public 
[8]14 * License for more details.
15 *
16 * You should  have received  a copy of the GNU Lesser General Public License
17 * along with  this program;  if not, write to the  Free Software Foundation,
18 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * $Id$
21 */
22#define LIB3DS_EXPORT
[1563]23#include "tracks.h"
24#include "readwrite.h"
25#include "chunk.h"
26#include "lib3ds_float.h"
27#include "vector.h"
28#include "quat.h"
[8]29#include <stdlib.h>
30#include <string.h>
31#include <math.h>
[1563]32#include "config.h"
[8]33#ifdef WITH_DMALLOC
34#include <dmalloc.h>
35#endif
36
[151]37
[8]38/*!
39 * \defgroup tracks Keyframing Tracks
40 *
41 * \author J.E. Hoffmann <je-h@gmx.net>
42 */
43
[151]44
[8]45/*!
[151]46 * \ingroup tracks
[8]47 */
48Lib3dsBoolKey*
49lib3ds_bool_key_new()
50{
[151]51  Lib3dsBoolKey* k;
52  k=(Lib3dsBoolKey*)calloc(sizeof(Lib3dsBoolKey), 1);
53  return(k);
[8]54}
55
56
57/*!
[151]58 * \ingroup tracks
[8]59 */
60void
61lib3ds_bool_key_free(Lib3dsBoolKey *key)
62{
[151]63  ASSERT(key);
64  free(key);
[8]65}
66
67
68/*!
[151]69 * \ingroup tracks
[8]70 */
71void
72lib3ds_bool_track_free_keys(Lib3dsBoolTrack *track)
73{
[151]74  Lib3dsBoolKey *p,*q;
[8]75
[151]76  ASSERT(track);
77  for (p=track->keyL; p; p=q) {
78    q=p->next;
79    lib3ds_bool_key_free(p);
80  }
[8]81}
82
83
84/*!
[151]85 * \ingroup tracks
[8]86 */
87void
88lib3ds_bool_track_insert(Lib3dsBoolTrack *track, Lib3dsBoolKey *key)
89{
[151]90  ASSERT(track);
91  ASSERT(key);
92  ASSERT(!key->next);
[8]93
[151]94  if (!track->keyL) {
95    track->keyL=key;
96    key->next=0;
97  }
98  else {
99    Lib3dsBoolKey *k,*p;
[8]100
[151]101    for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
102      if (k->tcb.frame>key->tcb.frame) {
103        break;
104      }
[8]105    }
[151]106    if (!p) {
107      key->next=track->keyL;
108      track->keyL=key;
109    }
110    else {
111      key->next=k;
112      p->next=key;
113    }
114 
115    if (k && (key->tcb.frame==k->tcb.frame)) {
116      key->next=k->next;
117      lib3ds_bool_key_free(k);
118    }
119  }
[8]120}
121
122
123/*!
[151]124 * \ingroup tracks
[8]125 */
126void
127lib3ds_bool_track_remove(Lib3dsBoolTrack *track, Lib3dsIntd frame)
128{
[151]129  Lib3dsBoolKey *k,*p;
130 
131  ASSERT(track);
132  if (!track->keyL) {
133    return;
134  }
135  for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
136    if (k->tcb.frame==frame) {
137      if (!p) {
138        track->keyL=track->keyL->next;
139      }
140      else {
141        p->next=k->next;
142      }
143      lib3ds_bool_key_free(k);
144      break;
[8]145    }
[151]146  }
[8]147}
148
149
150/*!
[151]151 * \ingroup tracks
[8]152 */
153void
154lib3ds_bool_track_eval(Lib3dsBoolTrack *track, Lib3dsBool *p, Lib3dsFloat t)
155{
[151]156  Lib3dsBoolKey *k;
157  Lib3dsBool result;
[8]158
[151]159  ASSERT(p);
160  if (!track->keyL) {
161    *p=LIB3DS_FALSE;
162    return;
163  }
164  if (!track->keyL->next) {
165    *p = LIB3DS_TRUE;
166    return;
167  }
168
169  result=LIB3DS_FALSE;
170  k=track->keyL;
171  while ((t<(Lib3dsFloat)k->tcb.frame) && (t>=(Lib3dsFloat)k->next->tcb.frame)) {
172    if (result) {
173      result=LIB3DS_FALSE;
[8]174    }
[151]175    else {
176      result=LIB3DS_TRUE;
[8]177    }
[151]178    if (!k->next) {
179      if (track->flags&LIB3DS_REPEAT) {
180        t-=(Lib3dsFloat)k->tcb.frame;
181        k=track->keyL;
182      }
183      else {
184        break;
185      }
[8]186    }
[151]187    else {
188      k=k->next;
189    }
190  }
191  *p=result;
[8]192}
193
194
195/*!
[151]196 * \ingroup tracks
[8]197 */
198Lib3dsBool
[10076]199lib3ds_bool_track_read(Lib3dsBoolTrack *track, iostream *strm)
[8]200{
[151]201  int keys;
202  int i;
203  Lib3dsBoolKey *k;
[8]204
[10076]205  track->flags=lib3ds_word_read(strm);
206  lib3ds_dword_read(strm);
207  lib3ds_dword_read(strm);
208  keys=lib3ds_intd_read(strm);
[8]209
[151]210  for (i=0; i<keys; ++i) {
211    k=lib3ds_bool_key_new();
[10076]212    if (!lib3ds_tcb_read(&k->tcb, strm)) {
[151]213      return(LIB3DS_FALSE);
[8]214    }
[151]215    lib3ds_bool_track_insert(track, k);
216  }
217 
218  return(LIB3DS_TRUE);
[8]219}
220
221
222/*!
[151]223 * \ingroup tracks
[8]224 */
225Lib3dsBool
[10076]226lib3ds_bool_track_write(Lib3dsBoolTrack *track, iostream *strm)
[8]227{
[151]228  Lib3dsBoolKey *k;
229  Lib3dsDword num=0;
230  for (k=track->keyL; k; k=k->next) {
231    ++num;
232  }
[10076]233  lib3ds_word_write((Lib3dsWord)track->flags,strm);
234  lib3ds_dword_write(0,strm);
235  lib3ds_dword_write(0,strm);
236  lib3ds_dword_write(num,strm);
[8]237
[151]238  for (k=track->keyL; k; k=k->next) {
[10076]239    if (!lib3ds_tcb_write(&k->tcb,strm)) {
[151]240      return(LIB3DS_FALSE);
[8]241    }
[151]242  }
243  return(LIB3DS_TRUE);
[8]244}
245
246
247/*!
[151]248 * \ingroup tracks
[8]249 */
250Lib3dsLin1Key*
251lib3ds_lin1_key_new()
252{
[151]253  Lib3dsLin1Key* k;
254  k=(Lib3dsLin1Key*)calloc(sizeof(Lib3dsLin1Key), 1);
255  return(k);
[8]256}
257
258
259/*!
[151]260 * \ingroup tracks
[8]261 */
262void
263lib3ds_lin1_key_free(Lib3dsLin1Key *key)
264{
[151]265  ASSERT(key);
266  free(key);
[8]267}
268
269
270/*!
[151]271 * \ingroup tracks
[8]272 */
273void
274lib3ds_lin1_track_free_keys(Lib3dsLin1Track *track)
275{
[151]276  Lib3dsLin1Key *p,*q;
[8]277
[151]278  ASSERT(track);
279  for (p=track->keyL; p; p=q) {
280    q=p->next;
281    lib3ds_lin1_key_free(p);
282  }
[8]283}
284
285
286/*!
[151]287 * \ingroup tracks
[8]288 */
289void
290lib3ds_lin1_key_setup(Lib3dsLin1Key *p, Lib3dsLin1Key *cp, Lib3dsLin1Key *c,
[151]291  Lib3dsLin1Key *cn, Lib3dsLin1Key *n)
[8]292{
[151]293  Lib3dsFloat np,nn;
294  Lib3dsFloat ksm,ksp,kdm,kdp;
295 
296  ASSERT(c);
297  if (!cp) {
298    cp=c;
299  }
300  if (!cn) {
301    cn=c;
302  }
303  if (!p && !n) {
304    c->ds=0;
305    c->dd=0;
306    return;
307  }
[8]308
[151]309  if (n && p) {
310    lib3ds_tcb(&p->tcb, &cp->tcb, &c->tcb, &cn->tcb, &n->tcb, &ksm, &ksp, &kdm, &kdp);
311    np = c->value - p->value;
312    nn = n->value - c->value;
[8]313
[151]314    c->ds=ksm*np + ksp*nn;
315    c->dd=kdm*np + kdp*nn;
316  }
317  else {
318    if (p) {
319      np = c->value - p->value;
320      c->ds = np;
321      c->dd = np;
[8]322    }
[151]323    if (n) {
324      nn = n->value - c->value;
325      c->ds = nn;
326      c->dd = nn;
[8]327    }
[151]328  }
[8]329}
330
331
332/*!
[151]333 * \ingroup tracks
[8]334 */
335void
336lib3ds_lin1_track_setup(Lib3dsLin1Track *track)
337{
[151]338  Lib3dsLin1Key *pp,*pc,*pn,*pl;
[8]339
[151]340  ASSERT(track);
341  pc=track->keyL;
342  if (!pc) {
343    return;
344  }
345  if (!pc->next) {
346    pc->ds=0;
347    pc->dd=0;
348    return;
349  }
[8]350
[151]351  if (track->flags&LIB3DS_SMOOTH) {
352    for (pl=track->keyL; pl->next->next; pl=pl->next);
353    lib3ds_lin1_key_setup(pl, pl->next, pc, 0, pc->next);
354 }
355 else {
356   lib3ds_lin1_key_setup(0, 0, pc, 0, pc->next);
357 }
358  for (;;) {
359    pp=pc;
360    pc=pc->next;
361    pn=pc->next;
362    if (!pn) {
363      break;
[8]364    }
[151]365    lib3ds_lin1_key_setup(pp, 0, pc, 0, pn);
366  }
[8]367
[151]368  if (track->flags&LIB3DS_SMOOTH) {
369    lib3ds_lin1_key_setup(pp, 0, pc, track->keyL, track->keyL->next);
370  }
371  else {
372    lib3ds_lin1_key_setup(pp, 0, pc, 0, 0);
373  }
[8]374}
375
376
377/*!
[151]378 * \ingroup tracks
[8]379 */
380void
381lib3ds_lin1_track_insert(Lib3dsLin1Track *track, Lib3dsLin1Key *key)
382{
[151]383  ASSERT(track);
384  ASSERT(key);
385  ASSERT(!key->next);
[8]386
[151]387  if (!track->keyL) {
388    track->keyL=key;
389    key->next=0;
390  }
391  else {
392    Lib3dsLin1Key *k,*p;
[8]393
[151]394    for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
395      if (k->tcb.frame>key->tcb.frame) {
396        break;
397      }
[8]398    }
[151]399    if (!p) {
400      key->next=track->keyL;
401      track->keyL=key;
402    }
403    else {
404      key->next=k;
405      p->next=key;
406    }
407 
408    if (k && (key->tcb.frame==k->tcb.frame)) {
409      key->next=k->next;
410      lib3ds_lin1_key_free(k);
411    }
412  }
[8]413}
414
415
416/*!
[151]417 * \ingroup tracks
[8]418 */
419void
420lib3ds_lin1_track_remove(Lib3dsLin1Track *track, Lib3dsIntd frame)
421{
[151]422  Lib3dsLin1Key *k,*p;
423 
424  ASSERT(track);
425  if (!track->keyL) {
426    return;
427  }
428  for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
429    if (k->tcb.frame==frame) {
430      if (!p) {
431        track->keyL=track->keyL->next;
432      }
433      else {
434        p->next=k->next;
435      }
436      lib3ds_lin1_key_free(k);
437      break;
[8]438    }
[151]439  }
[8]440}
441
442
443/*!
[151]444 * \ingroup tracks
[8]445 */
446void
447lib3ds_lin1_track_eval(Lib3dsLin1Track *track, Lib3dsFloat *p, Lib3dsFloat t)
448{
[151]449  Lib3dsLin1Key *k;
450  Lib3dsFloat nt;
451  Lib3dsFloat u;
[8]452
[151]453  ASSERT(p);
454  if (!track->keyL) {
455    *p=0;
456    return;
457  }
458  if (!track->keyL->next) {
459    *p = track->keyL->value;
460    return;
461  }
[8]462
[151]463  for (k=track->keyL; k->next!=0; k=k->next) {
464    if ((t>=(Lib3dsFloat)k->tcb.frame) && (t<(Lib3dsFloat)k->next->tcb.frame)) {
465      break;
[8]466    }
[151]467  }
468  if (!k->next) {
469    if (track->flags&LIB3DS_REPEAT) {
[3237]470      nt=(Lib3dsFloat)fmod(t, (float)k->tcb.frame);
[151]471      for (k=track->keyL; k->next!=0; k=k->next) {
472        if ((nt>=(Lib3dsFloat)k->tcb.frame) && (nt<(Lib3dsFloat)k->next->tcb.frame)) {
473          break;
[8]474        }
[151]475      }
476      ASSERT(k->next);
[8]477    }
[151]478    else {
479      *p = k->value;
480      return;
[8]481    }
[151]482  }
483  else {
484    nt=t;
485  }
486  u=nt - (Lib3dsFloat)k->tcb.frame;
487  u/=(Lib3dsFloat)(k->next->tcb.frame - k->tcb.frame);
[8]488
[151]489  *p = lib3ds_float_cubic(
490    k->value,
491    k->dd,
492    k->next->ds,
493    k->next->value,
494    u
495  );
[8]496}
497
498
499/*!
[151]500 * \ingroup tracks
[8]501 */
502Lib3dsBool
[10076]503lib3ds_lin1_track_read(Lib3dsLin1Track *track, iostream *strm)
[8]504{
[151]505  int keys;
506  int i;
507  Lib3dsLin1Key *k;
[8]508
[10076]509  track->flags=lib3ds_word_read(strm);
510  lib3ds_dword_read(strm);
511  lib3ds_dword_read(strm);
512  keys=lib3ds_intd_read(strm);
[8]513
[151]514  for (i=0; i<keys; ++i) {
515    k=lib3ds_lin1_key_new();
[10076]516    if (!lib3ds_tcb_read(&k->tcb, strm)) {
[151]517      return(LIB3DS_FALSE);
[8]518    }
[10076]519    k->value=lib3ds_float_read(strm);
[151]520    lib3ds_lin1_track_insert(track, k);
521  }
522  lib3ds_lin1_track_setup(track);
523  return(LIB3DS_TRUE);
[8]524}
525
526
527/*!
[151]528 * \ingroup tracks
[8]529 */
530Lib3dsBool
[10076]531lib3ds_lin1_track_write(Lib3dsLin1Track *track, iostream *strm)
[8]532{
[151]533  Lib3dsLin1Key *k;
534  Lib3dsDword num=0;
535  for (k=track->keyL; k; k=k->next) {
536    ++num;
537  }
[10076]538  lib3ds_word_write((Lib3dsWord)track->flags,strm);
539  lib3ds_dword_write(0,strm);
540  lib3ds_dword_write(0,strm);
541  lib3ds_dword_write(num,strm);
[8]542
[151]543  for (k=track->keyL; k; k=k->next) {
[10076]544    if (!lib3ds_tcb_write(&k->tcb,strm)) {
[151]545      return(LIB3DS_FALSE);
[8]546    }
[10076]547    lib3ds_float_write(k->value,strm);
[151]548  }
549  return(LIB3DS_TRUE);
[8]550}
551
552
553/*!
[151]554 * \ingroup tracks
[8]555 */
556Lib3dsLin3Key*
557lib3ds_lin3_key_new()
558{
[151]559  Lib3dsLin3Key* k;
560  k=(Lib3dsLin3Key*)calloc(sizeof(Lib3dsLin3Key), 1);
561  return(k);
[8]562}
563
564
565/*!
[151]566 * \ingroup tracks
[8]567 */
568void
569lib3ds_lin3_key_free(Lib3dsLin3Key *key)
570{
[151]571  ASSERT(key);
572  free(key);
[8]573}
574
575
576/*!
[151]577 * \ingroup tracks
[8]578 */
579void
580lib3ds_lin3_track_free_keys(Lib3dsLin3Track *track)
581{
[151]582  Lib3dsLin3Key *p,*q;
[8]583
[151]584  ASSERT(track);
585  for (p=track->keyL; p; p=q) {
586    q=p->next;
587    lib3ds_lin3_key_free(p);
588  }
[8]589}
590
591
592/*!
[151]593 * \ingroup tracks
[8]594 */
595void
596lib3ds_lin3_key_setup(Lib3dsLin3Key *p, Lib3dsLin3Key *cp, Lib3dsLin3Key *c,
[151]597  Lib3dsLin3Key *cn, Lib3dsLin3Key *n)
[8]598{
[151]599  Lib3dsVector np,nn;
600  Lib3dsFloat ksm,ksp,kdm,kdp;
601  int i;
602 
603  ASSERT(c);
604  if (!cp) {
605    cp=c;
606  }
607  if (!cn) {
608    cn=c;
609  }
610  if (!p && !n) {
611    lib3ds_vector_zero(c->ds);
612    lib3ds_vector_zero(c->dd);
613    return;
614  }
[8]615
[151]616  if (n && p) {
617    lib3ds_tcb(&p->tcb, &cp->tcb, &c->tcb, &cn->tcb, &n->tcb, &ksm, &ksp, &kdm, &kdp);
618    lib3ds_vector_sub(np, c->value, p->value);
619    lib3ds_vector_sub(nn, n->value, c->value);
[8]620
[151]621    for(i=0; i<3; ++i) {
622      c->ds[i]=ksm*np[i] + ksp*nn[i];
623      c->dd[i]=kdm*np[i] + kdp*nn[i];
[8]624    }
[151]625  }
626  else {
627    if (p) {
628      lib3ds_vector_sub(np, c->value, p->value);
629      lib3ds_vector_copy(c->ds, np);
630      lib3ds_vector_copy(c->dd, np);
[8]631    }
[151]632    if (n) {
633      lib3ds_vector_sub(nn, n->value, c->value);
634      lib3ds_vector_copy(c->ds, nn);
635      lib3ds_vector_copy(c->dd, nn);
636    }
637  }
[8]638}
639
640
641/*!
[151]642 * \ingroup tracks
[8]643 */
644void
645lib3ds_lin3_track_setup(Lib3dsLin3Track *track)
646{
[151]647  Lib3dsLin3Key *pp,*pc,*pn,*pl;
[8]648
[151]649  ASSERT(track);
650  pc=track->keyL;
651  if (!pc) {
652    return;
653  }
654  if (!pc->next) {
655    lib3ds_vector_zero(pc->ds);
656    lib3ds_vector_zero(pc->dd);
657    return;
658  }
[8]659
[151]660  if (track->flags&LIB3DS_SMOOTH) {
661    for (pl=track->keyL; pl->next->next; pl=pl->next);
662    lib3ds_lin3_key_setup(pl, pl->next, pc, 0, pc->next);
663 }
664 else {
665   lib3ds_lin3_key_setup(0, 0, pc, 0, pc->next);
666 }
667  for (;;) {
668    pp=pc;
669    pc=pc->next;
670    pn=pc->next;
671    if (!pn) {
672      break;
[8]673    }
[151]674    lib3ds_lin3_key_setup(pp, 0, pc, 0, pn);
675  }
[8]676
[151]677  if (track->flags&LIB3DS_SMOOTH) {
678    lib3ds_lin3_key_setup(pp, 0, pc, track->keyL, track->keyL->next);
679  }
680  else {
681    lib3ds_lin3_key_setup(pp, 0, pc, 0, 0);
682  }
[8]683}
684
685
686/*!
[151]687 * \ingroup tracks
[8]688 */
689void
690lib3ds_lin3_track_insert(Lib3dsLin3Track *track, Lib3dsLin3Key *key)
691{
[151]692  ASSERT(track);
693  ASSERT(key);
694  ASSERT(!key->next);
[8]695
[151]696  if (!track->keyL) {
697    track->keyL=key;
698    key->next=0;
699  }
700  else {
701    Lib3dsLin3Key *k,*p;
[8]702
[151]703    for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
704      if (k->tcb.frame>key->tcb.frame) {
705        break;
706      }
[8]707    }
[151]708    if (!p) {
709      key->next=track->keyL;
710      track->keyL=key;
711    }
712    else {
713      key->next=k;
714      p->next=key;
715    }
716 
717    if (k && (key->tcb.frame==k->tcb.frame)) {
718      key->next=k->next;
719      lib3ds_lin3_key_free(k);
720    }
721  }
[8]722}
723
724
725/*!
[151]726 * \ingroup tracks
[8]727 */
728void
729lib3ds_lin3_track_remove(Lib3dsLin3Track *track, Lib3dsIntd frame)
730{
[151]731  Lib3dsLin3Key *k,*p;
732 
733  ASSERT(track);
734  if (!track->keyL) {
735    return;
736  }
737  for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
738    if (k->tcb.frame==frame) {
739      if (!p) {
740        track->keyL=track->keyL->next;
741      }
742      else {
743        p->next=k->next;
744      }
745      lib3ds_lin3_key_free(k);
746      break;
[8]747    }
[151]748  }
[8]749}
750
751
752/*!
[151]753 * \ingroup tracks
[8]754 */
755void
756lib3ds_lin3_track_eval(Lib3dsLin3Track *track, Lib3dsVector p, Lib3dsFloat t)
757{
[151]758  Lib3dsLin3Key *k;
759  Lib3dsFloat nt;
760  Lib3dsFloat u;
[8]761
[151]762  if (!track->keyL) {
763    lib3ds_vector_zero(p);
764    return;
765  }
766  if (!track->keyL->next) {
767      lib3ds_vector_copy(p, track->keyL->value);
768    return;
769  }
[8]770
[151]771  for (k=track->keyL; k->next!=0; k=k->next) {
772    if ((t>=(Lib3dsFloat)k->tcb.frame) && (t<(Lib3dsFloat)k->next->tcb.frame)) {
773      break;
[8]774    }
[151]775  }
776  if (!k->next) {
777    if (track->flags&LIB3DS_REPEAT) {
[3237]778      nt=(Lib3dsFloat)fmod(t, (float)k->tcb.frame);
[151]779      for (k=track->keyL; k->next!=0; k=k->next) {
780        if ((nt>=(Lib3dsFloat)k->tcb.frame) && (nt<(Lib3dsFloat)k->next->tcb.frame)) {
781          break;
[8]782        }
[151]783      }
784      ASSERT(k->next);
[8]785    }
[151]786    else {
787      lib3ds_vector_copy(p, k->value);
788      return;
[8]789    }
[151]790  }
791  else {
792    nt=t;
793  }
794  u=nt - (Lib3dsFloat)k->tcb.frame;
795  u/=(Lib3dsFloat)(k->next->tcb.frame - k->tcb.frame);
796 
797  lib3ds_vector_cubic(
798    p,
799    k->value,
800    k->dd,
801    k->next->ds,
802    k->next->value,
803    u
804  );
[8]805}
806
807
808/*!
[151]809 * \ingroup tracks
[8]810 */
811Lib3dsBool
[10076]812lib3ds_lin3_track_read(Lib3dsLin3Track *track, iostream *strm)
[8]813{
[151]814  int keys;
815  int i,j;
816  Lib3dsLin3Key *k;
[8]817
[10076]818  track->flags=lib3ds_word_read(strm);
819  lib3ds_dword_read(strm);
820  lib3ds_dword_read(strm);
821  keys=lib3ds_intd_read(strm);
[8]822
[151]823  for (i=0; i<keys; ++i) {
824    k=lib3ds_lin3_key_new();
[10076]825    if (!lib3ds_tcb_read(&k->tcb, strm)) {
[151]826      return(LIB3DS_FALSE);
[8]827    }
[151]828    for (j=0; j<3; ++j) {
[10076]829      k->value[j]=lib3ds_float_read(strm);
[151]830    }
831    lib3ds_lin3_track_insert(track, k);
832  }
833  lib3ds_lin3_track_setup(track);
834  return(LIB3DS_TRUE);
[8]835}
836
837
838/*!
[151]839 * \ingroup tracks
[8]840 */
841Lib3dsBool
[10076]842lib3ds_lin3_track_write(Lib3dsLin3Track *track, iostream *strm)
[8]843{
[151]844  Lib3dsLin3Key *k;
845  Lib3dsDword num=0;
846  for (k=track->keyL; k; k=k->next) {
847    ++num;
848  }
[10076]849  lib3ds_word_write((Lib3dsWord)track->flags,strm);
850  lib3ds_dword_write(0,strm);
851  lib3ds_dword_write(0,strm);
852  lib3ds_dword_write(num,strm);
[8]853
[151]854  for (k=track->keyL; k; k=k->next) {
[10076]855    if (!lib3ds_tcb_write(&k->tcb,strm)) {
[151]856      return(LIB3DS_FALSE);
[8]857    }
[10076]858    lib3ds_vector_write(k->value,strm);
[151]859  }
860  return(LIB3DS_TRUE);
[8]861}
862
863
864/*!
[151]865 * \ingroup tracks
[8]866 */
867Lib3dsQuatKey*
868lib3ds_quat_key_new()
869{
[151]870  Lib3dsQuatKey* k;
871  k=(Lib3dsQuatKey*)calloc(sizeof(Lib3dsQuatKey), 1);
872  return(k);
[8]873}
874
875
876/*!
[151]877 * \ingroup tracks
[8]878 */
879void
880lib3ds_quat_key_free(Lib3dsQuatKey *key)
881{
[151]882  ASSERT(key);
883  free(key);
[8]884}
885
886
887/*!
[151]888 * \ingroup tracks
[8]889 */
890void
891lib3ds_quat_track_free_keys(Lib3dsQuatTrack *track)
892{
[151]893  Lib3dsQuatKey *p,*q;
[8]894
[151]895  ASSERT(track);
896  for (p=track->keyL; p; p=q) {
897    q=p->next;
898    lib3ds_quat_key_free(p);
899  }
[8]900}
901
902
903/*!
[151]904 * \ingroup tracks
[8]905 */
906void
907lib3ds_quat_key_setup(Lib3dsQuatKey *p, Lib3dsQuatKey *cp, Lib3dsQuatKey *c,
[151]908  Lib3dsQuatKey *cn, Lib3dsQuatKey *n)
[8]909{
[151]910  Lib3dsFloat ksm,ksp,kdm,kdp;
911  Lib3dsQuat q,qp,qn,qa,qb;
912  int i;
913 
914  ASSERT(c);
915  if (!cp) {
916    cp=c;
917  }
918  if (!cn) {
919    cn=c;
920  }
921  if (!p || !n) {
922    lib3ds_quat_copy(c->ds, c->q);
923    lib3ds_quat_copy(c->dd, c->q);
924    return;
925  }
[8]926
[151]927  if (p) {
928    if (p->angle>LIB3DS_TWOPI-LIB3DS_EPSILON) {
929      lib3ds_quat_axis_angle(qp, p->axis, 0.0f);
930      lib3ds_quat_ln(qp);
[8]931    }
[151]932    else {
933      lib3ds_quat_copy(q, p->q);
934      if (lib3ds_quat_dot(q,c->q)<0) lib3ds_quat_neg(q);
935      lib3ds_quat_ln_dif(qp, c->q, q);
[8]936    }
[151]937  }
938  if (n) {
939    if (n->angle>LIB3DS_TWOPI-LIB3DS_EPSILON) {
940      lib3ds_quat_axis_angle(qn, n->axis, 0.0f);
941      lib3ds_quat_ln(qn);
[8]942    }
[151]943    else {
944      lib3ds_quat_copy(q, n->q);
945      if (lib3ds_quat_dot(q,c->q)<0) lib3ds_quat_neg(q);
946      lib3ds_quat_ln_dif(qn, c->q, q);
[8]947    }
[151]948  }
[8]949
[151]950  if (n && p) {
951    lib3ds_tcb(&p->tcb, &cp->tcb, &c->tcb, &cn->tcb, &n->tcb, &ksm, &ksp, &kdm, &kdp);
952    for(i=0; i<4; i++) {
953      qa[i]=-0.5f*(kdm*qn[i]+kdp*qp[i]);
954      qb[i]=-0.5f*(ksm*qn[i]+ksp*qp[i]);
[8]955    }
[151]956    lib3ds_quat_exp(qa);
957    lib3ds_quat_exp(qb);
958   
959    lib3ds_quat_mul(c->ds, c->q, qa);
960    lib3ds_quat_mul(c->dd, c->q, qb);
961  }
962  else {
963    if (p) {
964      lib3ds_quat_exp(qp);
965      lib3ds_quat_mul(c->ds, c->q, qp);
966      lib3ds_quat_mul(c->dd, c->q, qp);
[8]967    }
[151]968    if (n) {
969      lib3ds_quat_exp(qn);
970      lib3ds_quat_mul(c->ds, c->q, qn);
971      lib3ds_quat_mul(c->dd, c->q, qn);
972    }
973  }
[8]974}
975
976
977/*!
[151]978 * \ingroup tracks
[8]979 */
980void
981lib3ds_quat_track_setup(Lib3dsQuatTrack *track)
982{
[151]983  Lib3dsQuatKey *pp,*pc,*pn,*pl;
984  Lib3dsQuat q;
[8]985
[151]986  ASSERT(track);
987  for (pp=0,pc=track->keyL; pc; pp=pc,pc=pc->next) {
988    lib3ds_quat_axis_angle(q, pc->axis, pc->angle);
989    if (pp) {
990      lib3ds_quat_mul(pc->q, q, pp->q);
[8]991    }
[151]992    else {
993      lib3ds_quat_copy(pc->q, q);
[8]994    }
[151]995  }
[8]996
[151]997  pc=track->keyL;
998  if (!pc) {
999    return;
1000  }
1001  if (!pc->next) {
1002    lib3ds_quat_copy(pc->ds, pc->q);
1003    lib3ds_quat_copy(pc->dd, pc->q);
1004    return;
1005  }
[8]1006
[151]1007  if (track->flags&LIB3DS_SMOOTH) {
1008    for (pl=track->keyL; pl->next->next; pl=pl->next);
1009    lib3ds_quat_key_setup(pl, pl->next, pc, 0, pc->next);
1010 }
1011  else {
1012    lib3ds_quat_key_setup(0, 0, pc, 0, pc->next);
1013  }
1014  for (;;) {
1015    pp=pc;
1016    pc=pc->next;
1017    pn=pc->next;
1018    if (!pn) {
1019      break;
[8]1020    }
[151]1021    lib3ds_quat_key_setup(pp, 0, pc, 0, pn);
1022  }
1023
1024  if (track->flags&LIB3DS_SMOOTH) {
1025    lib3ds_quat_key_setup(pp, 0, pc, track->keyL, track->keyL->next);
1026  }
1027  else {
1028    lib3ds_quat_key_setup(pp, 0, pc, 0, 0);
1029  }
[8]1030}
1031
1032
1033/*!
[151]1034 * \ingroup tracks
[8]1035 */
1036void
1037lib3ds_quat_track_insert(Lib3dsQuatTrack *track, Lib3dsQuatKey *key)
1038{
[151]1039  ASSERT(track);
1040  ASSERT(key);
1041  ASSERT(!key->next);
[8]1042
[151]1043  if (!track->keyL) {
1044    track->keyL=key;
1045    key->next=0;
1046  }
1047  else {
1048    Lib3dsQuatKey *k,*p;
[8]1049
[151]1050    for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
1051      if (k->tcb.frame>key->tcb.frame) {
1052        break;
1053      }
[8]1054    }
[151]1055    if (!p) {
1056      key->next=track->keyL;
1057      track->keyL=key;
1058    }
1059    else {
1060      key->next=k;
1061      p->next=key;
1062    }
1063 
1064    if (k && (key->tcb.frame==k->tcb.frame)) {
1065      key->next=k->next;
1066      lib3ds_quat_key_free(k);
1067    }
1068  }
[8]1069}
1070
1071
1072/*!
[151]1073 * \ingroup tracks
[8]1074 */
1075void
1076lib3ds_quat_track_remove(Lib3dsQuatTrack *track, Lib3dsIntd frame)
1077{
[151]1078  Lib3dsQuatKey *k,*p;
1079 
1080  ASSERT(track);
1081  if (!track->keyL) {
1082    return;
1083  }
1084  for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
1085    if (k->tcb.frame==frame) {
1086      if (!p) {
1087        track->keyL=track->keyL->next;
1088      }
1089      else {
1090        p->next=k->next;
1091      }
1092      lib3ds_quat_key_free(k);
1093      break;
[8]1094    }
[151]1095  }
[8]1096}
1097
1098
1099/*!
[151]1100 * \ingroup tracks
[8]1101 */
1102void
1103lib3ds_quat_track_eval(Lib3dsQuatTrack *track, Lib3dsQuat q, Lib3dsFloat t)
1104{
[151]1105  Lib3dsQuatKey *k;
1106  Lib3dsFloat nt;
1107  Lib3dsFloat u;
[8]1108
[151]1109  if (!track->keyL) {
1110    lib3ds_quat_identity(q);
1111    return;
1112  }
1113  if (!track->keyL->next) {
1114    lib3ds_quat_copy(q, track->keyL->q);
1115    return;
1116  }
[8]1117
[151]1118  for (k=track->keyL; k->next!=0; k=k->next) {
1119    if ((t>=k->tcb.frame) && (t<k->next->tcb.frame)) {
1120      break;
[8]1121    }
[151]1122  }
1123  if (!k->next) {
1124    if (track->flags&LIB3DS_REPEAT) {
[3237]1125      nt=(Lib3dsFloat)fmod(t, (float)k->tcb.frame);
[151]1126      for (k=track->keyL; k->next!=0; k=k->next) {
1127        if ((nt>=k->tcb.frame) && (nt<k->next->tcb.frame)) {
1128          break;
[8]1129        }
[151]1130      }
1131      ASSERT(k->next);
[8]1132    }
[151]1133    else {
1134      lib3ds_quat_copy(q, k->q);
1135      return;
[8]1136    }
[151]1137  }
1138  else {
1139    nt=t;
1140  }
1141  u=nt - k->tcb.frame;
1142  u/=(k->next->tcb.frame - k->tcb.frame);
[8]1143
[151]1144  lib3ds_quat_squad(
1145    q,
1146    k->q,
1147    k->dd,
1148    k->next->ds,
1149    k->next->q,
1150    u
1151  );
[8]1152}
1153
1154
1155/*!
[151]1156 * \ingroup tracks
[8]1157 */
1158Lib3dsBool
[10076]1159lib3ds_quat_track_read(Lib3dsQuatTrack *track, iostream *strm)
[8]1160{
[151]1161  int keys;
1162  int i,j;
[569]1163  Lib3dsQuatKey *k;
[8]1164
[10076]1165  track->flags=lib3ds_word_read(strm);
1166  lib3ds_dword_read(strm);
1167  lib3ds_dword_read(strm);
1168  keys=lib3ds_intd_read(strm);
[8]1169
[569]1170  for (i=0; i<keys; ++i) {
[151]1171    k=lib3ds_quat_key_new();
[10076]1172    if (!lib3ds_tcb_read(&k->tcb, strm)) {
[151]1173      return(LIB3DS_FALSE);
[8]1174    }
[10076]1175    k->angle=lib3ds_float_read(strm);
[151]1176    for (j=0; j<3; ++j) {
[10076]1177      k->axis[j]=lib3ds_float_read(strm);
[151]1178    }
1179    lib3ds_quat_track_insert(track, k);
1180  }
1181  lib3ds_quat_track_setup(track);
1182  return(LIB3DS_TRUE);
[8]1183}
1184
1185
1186/*!
[151]1187 * \ingroup tracks
[8]1188 */
1189Lib3dsBool
[10076]1190lib3ds_quat_track_write(Lib3dsQuatTrack *track, iostream *strm)
[8]1191{
[151]1192  Lib3dsQuatKey *k;
1193  Lib3dsDword num=0;
1194  for (k=track->keyL; k; k=k->next) {
1195    ++num;
1196  }
[10076]1197  lib3ds_word_write((Lib3dsWord)track->flags,strm);
1198  lib3ds_dword_write(0,strm);
1199  lib3ds_dword_write(0,strm);
1200  lib3ds_dword_write(num,strm);
[8]1201
[151]1202  for (k=track->keyL; k; k=k->next) {
[10076]1203    if (!lib3ds_tcb_write(&k->tcb,strm)) {
[151]1204      return(LIB3DS_FALSE);
[8]1205    }
[10076]1206    lib3ds_float_write(k->angle,strm);
1207    lib3ds_vector_write(k->axis,strm);
[151]1208  }
1209  return(LIB3DS_TRUE);
[8]1210}
1211
1212
1213/*!
[151]1214 * \ingroup tracks
[8]1215 */
1216Lib3dsMorphKey*
1217lib3ds_morph_key_new()
1218{
[151]1219  Lib3dsMorphKey* k;
1220  k=(Lib3dsMorphKey*)calloc(sizeof(Lib3dsMorphKey), 1);
1221  return(k);
[8]1222}
1223
1224
1225/*!
[151]1226 * \ingroup tracks
[8]1227 */
1228void
1229lib3ds_morph_key_free(Lib3dsMorphKey *key)
1230{
[151]1231  ASSERT(key);
1232  free(key);
[8]1233}
1234
1235
1236/*!
[151]1237 * \ingroup tracks
[8]1238 */
1239void
1240lib3ds_morph_track_free_keys(Lib3dsMorphTrack *track)
1241{
[151]1242  Lib3dsMorphKey *p,*q;
[8]1243
[151]1244  ASSERT(track);
1245  for (p=track->keyL; p; p=q) {
1246    q=p->next;
1247    lib3ds_morph_key_free(p);
1248  }
[8]1249}
1250
1251
1252/*!
[151]1253 * \ingroup tracks
[8]1254 */
1255void
1256lib3ds_morph_track_insert(Lib3dsMorphTrack *track, Lib3dsMorphKey *key)
1257{
[151]1258  ASSERT(track);
1259  ASSERT(key);
1260  ASSERT(!key->next);
[8]1261
[151]1262  if (!track->keyL) {
1263    track->keyL=key;
1264    key->next=0;
1265  }
1266  else {
1267    Lib3dsMorphKey *k,*p;
[8]1268
[151]1269    for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
1270      if (k->tcb.frame>key->tcb.frame) {
1271        break;
1272      }
[8]1273    }
[151]1274    if (!p) {
1275      key->next=track->keyL;
1276      track->keyL=key;
1277    }
1278    else {
1279      key->next=k;
1280      p->next=key;
1281    }
1282 
1283    if (k && (key->tcb.frame==k->tcb.frame)) {
1284      key->next=k->next;
1285      lib3ds_morph_key_free(k);
1286    }
1287  }
[8]1288}
1289
1290
1291/*!
[151]1292 * \ingroup tracks
[8]1293 */
1294void
1295lib3ds_morph_track_remove(Lib3dsMorphTrack *track, Lib3dsIntd frame)
1296{
[151]1297  Lib3dsMorphKey *k,*p;
1298 
1299  ASSERT(track);
1300  if (!track->keyL) {
1301    return;
1302  }
1303  for (p=0,k=track->keyL; k!=0; p=k, k=k->next) {
1304    if (k->tcb.frame==frame) {
1305      if (!p) {
1306        track->keyL=track->keyL->next;
1307      }
1308      else {
1309        p->next=k->next;
1310      }
1311      lib3ds_morph_key_free(k);
1312      break;
[8]1313    }
[151]1314  }
[8]1315}
1316
1317
1318/*!
[151]1319 * \ingroup tracks
[8]1320 */
1321void
1322lib3ds_morph_track_eval(Lib3dsMorphTrack *track, char *p, Lib3dsFloat t)
1323{
[151]1324  Lib3dsMorphKey *k;
1325  char* result;
[8]1326
[151]1327  ASSERT(p);
1328  if (!track->keyL) {
1329    strcpy(p,"");
1330    return;
1331  }
1332  if (!track->keyL->next) {
1333    strcpy(p,track->keyL->name);
1334    return;
1335  }
[8]1336
[151]1337  result=0;
1338  k=track->keyL;
1339  while ((t<k->tcb.frame) && (t>=k->next->tcb.frame)) {
1340    result=k->name;
1341    if (!k->next) {
1342      if (track->flags&LIB3DS_REPEAT) {
1343        t-=k->tcb.frame;
1344        k=track->keyL;
1345      }
1346      else {
1347        break;
1348      }
[8]1349    }
[151]1350    else {
1351      k=k->next;
[8]1352    }
[151]1353  }
1354  if (result) {
1355    strcpy(p,result);
1356  }
1357  else {
1358    strcpy(p,"");
1359  }
[8]1360}
1361
1362
1363/*!
1364 * \ingroup tracks
1365 */
1366Lib3dsBool
[10076]1367lib3ds_morph_track_read(Lib3dsMorphTrack *, iostream *strm)
[8]1368{
[151]1369  /* FIXME: */
1370  return(LIB3DS_TRUE);
[8]1371}
1372
1373
1374/*!
[151]1375 * \ingroup tracks
[8]1376 */
1377Lib3dsBool
[10076]1378lib3ds_morph_track_write(Lib3dsMorphTrack *, iostream *strm)
[8]1379{
[151]1380  /* FIXME: */
1381  ASSERT(0);
1382  return(LIB3DS_FALSE);
[8]1383}
[151]1384
Note: See TracBrowser for help on using the browser.