📄 tracks.cpp
字号:
/* * The 3D Studio File Format Library * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net> * All rights reserved. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public * License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation, * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: tracks.cpp 3237 2004-08-05 13:41:52Z robert $ */#define LIB3DS_EXPORT#include "tracks.h"#include "readwrite.h"#include "chunk.h"#include "lib3ds_float.h"#include "vector.h"#include "quat.h"#include <stdlib.h>#include <string.h>#include <math.h>#include "config.h"#ifdef WITH_DMALLOC#include <dmalloc.h>#endif/*! * \defgroup tracks Keyframing Tracks * * \author J.E. Hoffmann <je-h@gmx.net> *//*! * \ingroup tracks */Lib3dsBoolKey*lib3ds_bool_key_new(){ Lib3dsBoolKey* k; k=(Lib3dsBoolKey*)calloc(sizeof(Lib3dsBoolKey), 1); return(k);}/*! * \ingroup tracks */voidlib3ds_bool_key_free(Lib3dsBoolKey *key){ ASSERT(key); free(key);}/*! * \ingroup tracks */voidlib3ds_bool_track_free_keys(Lib3dsBoolTrack *track){ Lib3dsBoolKey *p,*q; ASSERT(track); for (p=track->keyL; p; p=q) { q=p->next; lib3ds_bool_key_free(p); }}/*! * \ingroup tracks */voidlib3ds_bool_track_insert(Lib3dsBoolTrack *track, Lib3dsBoolKey *key){ ASSERT(track); ASSERT(key); ASSERT(!key->next); if (!track->keyL) { track->keyL=key; key->next=0; } else { Lib3dsBoolKey *k,*p; for (p=0,k=track->keyL; k!=0; p=k, k=k->next) { if (k->tcb.frame>key->tcb.frame) { break; } } if (!p) { key->next=track->keyL; track->keyL=key; } else { key->next=k; p->next=key; } if (k && (key->tcb.frame==k->tcb.frame)) { key->next=k->next; lib3ds_bool_key_free(k); } }}/*! * \ingroup tracks */voidlib3ds_bool_track_remove(Lib3dsBoolTrack *track, Lib3dsIntd frame){ Lib3dsBoolKey *k,*p; ASSERT(track); if (!track->keyL) { return; } for (p=0,k=track->keyL; k!=0; p=k, k=k->next) { if (k->tcb.frame==frame) { if (!p) { track->keyL=track->keyL->next; } else { p->next=k->next; } lib3ds_bool_key_free(k); break; } }}/*! * \ingroup tracks */voidlib3ds_bool_track_eval(Lib3dsBoolTrack *track, Lib3dsBool *p, Lib3dsFloat t){ Lib3dsBoolKey *k; Lib3dsBool result; ASSERT(p); if (!track->keyL) { *p=LIB3DS_FALSE; return; } if (!track->keyL->next) { *p = LIB3DS_TRUE; return; } result=LIB3DS_FALSE; k=track->keyL; while ((t<(Lib3dsFloat)k->tcb.frame) && (t>=(Lib3dsFloat)k->next->tcb.frame)) { if (result) { result=LIB3DS_FALSE; } else { result=LIB3DS_TRUE; } if (!k->next) { if (track->flags&LIB3DS_REPEAT) { t-=(Lib3dsFloat)k->tcb.frame; k=track->keyL; } else { break; } } else { k=k->next; } } *p=result;}/*! * \ingroup tracks */Lib3dsBoollib3ds_bool_track_read(Lib3dsBoolTrack *track, FILE *f){ int keys; int i; Lib3dsBoolKey *k; track->flags=lib3ds_word_read(f); lib3ds_dword_read(f); lib3ds_dword_read(f); keys=lib3ds_intd_read(f); for (i=0; i<keys; ++i) { k=lib3ds_bool_key_new(); if (!lib3ds_tcb_read(&k->tcb, f)) { return(LIB3DS_FALSE); } lib3ds_bool_track_insert(track, k); } return(LIB3DS_TRUE);}/*! * \ingroup tracks */Lib3dsBoollib3ds_bool_track_write(Lib3dsBoolTrack *track, FILE *f){ Lib3dsBoolKey *k; Lib3dsDword num=0; for (k=track->keyL; k; k=k->next) { ++num; } lib3ds_word_write((Lib3dsWord)track->flags,f); lib3ds_dword_write(0,f); lib3ds_dword_write(0,f); lib3ds_dword_write(num,f); for (k=track->keyL; k; k=k->next) { if (!lib3ds_tcb_write(&k->tcb,f)) { return(LIB3DS_FALSE); } } return(LIB3DS_TRUE);}/*! * \ingroup tracks */Lib3dsLin1Key*lib3ds_lin1_key_new(){ Lib3dsLin1Key* k; k=(Lib3dsLin1Key*)calloc(sizeof(Lib3dsLin1Key), 1); return(k);}/*! * \ingroup tracks */voidlib3ds_lin1_key_free(Lib3dsLin1Key *key){ ASSERT(key); free(key);}/*! * \ingroup tracks */voidlib3ds_lin1_track_free_keys(Lib3dsLin1Track *track){ Lib3dsLin1Key *p,*q; ASSERT(track); for (p=track->keyL; p; p=q) { q=p->next; lib3ds_lin1_key_free(p); }}/*! * \ingroup tracks */voidlib3ds_lin1_key_setup(Lib3dsLin1Key *p, Lib3dsLin1Key *cp, Lib3dsLin1Key *c, Lib3dsLin1Key *cn, Lib3dsLin1Key *n){ Lib3dsFloat np,nn; Lib3dsFloat ksm,ksp,kdm,kdp; ASSERT(c); if (!cp) { cp=c; } if (!cn) { cn=c; } if (!p && !n) { c->ds=0; c->dd=0; return; } if (n && p) { lib3ds_tcb(&p->tcb, &cp->tcb, &c->tcb, &cn->tcb, &n->tcb, &ksm, &ksp, &kdm, &kdp); np = c->value - p->value; nn = n->value - c->value; c->ds=ksm*np + ksp*nn; c->dd=kdm*np + kdp*nn; } else { if (p) { np = c->value - p->value; c->ds = np; c->dd = np; } if (n) { nn = n->value - c->value; c->ds = nn; c->dd = nn; } }}/*! * \ingroup tracks */voidlib3ds_lin1_track_setup(Lib3dsLin1Track *track){ Lib3dsLin1Key *pp,*pc,*pn,*pl; ASSERT(track); pc=track->keyL; if (!pc) { return; } if (!pc->next) { pc->ds=0; pc->dd=0; return; } if (track->flags&LIB3DS_SMOOTH) { for (pl=track->keyL; pl->next->next; pl=pl->next); lib3ds_lin1_key_setup(pl, pl->next, pc, 0, pc->next); } else { lib3ds_lin1_key_setup(0, 0, pc, 0, pc->next); } for (;;) { pp=pc; pc=pc->next; pn=pc->next; if (!pn) { break; } lib3ds_lin1_key_setup(pp, 0, pc, 0, pn); } if (track->flags&LIB3DS_SMOOTH) { lib3ds_lin1_key_setup(pp, 0, pc, track->keyL, track->keyL->next); } else { lib3ds_lin1_key_setup(pp, 0, pc, 0, 0); }}/*! * \ingroup tracks */voidlib3ds_lin1_track_insert(Lib3dsLin1Track *track, Lib3dsLin1Key *key){ ASSERT(track); ASSERT(key); ASSERT(!key->next); if (!track->keyL) { track->keyL=key; key->next=0; } else { Lib3dsLin1Key *k,*p; for (p=0,k=track->keyL; k!=0; p=k, k=k->next) { if (k->tcb.frame>key->tcb.frame) { break; } } if (!p) { key->next=track->keyL; track->keyL=key; } else { key->next=k; p->next=key; } if (k && (key->tcb.frame==k->tcb.frame)) { key->next=k->next; lib3ds_lin1_key_free(k); } }}/*! * \ingroup tracks */voidlib3ds_lin1_track_remove(Lib3dsLin1Track *track, Lib3dsIntd frame){ Lib3dsLin1Key *k,*p; ASSERT(track); if (!track->keyL) { return; } for (p=0,k=track->keyL; k!=0; p=k, k=k->next) { if (k->tcb.frame==frame) { if (!p) { track->keyL=track->keyL->next; } else { p->next=k->next; } lib3ds_lin1_key_free(k); break; } }}/*! * \ingroup tracks */voidlib3ds_lin1_track_eval(Lib3dsLin1Track *track, Lib3dsFloat *p, Lib3dsFloat t){ Lib3dsLin1Key *k; Lib3dsFloat nt; Lib3dsFloat u; ASSERT(p); if (!track->keyL) { *p=0; return; } if (!track->keyL->next) { *p = track->keyL->value; return; } for (k=track->keyL; k->next!=0; k=k->next) { if ((t>=(Lib3dsFloat)k->tcb.frame) && (t<(Lib3dsFloat)k->next->tcb.frame)) { break; } } if (!k->next) { if (track->flags&LIB3DS_REPEAT) { nt=(Lib3dsFloat)fmod(t, (float)k->tcb.frame); for (k=track->keyL; k->next!=0; k=k->next) { if ((nt>=(Lib3dsFloat)k->tcb.frame) && (nt<(Lib3dsFloat)k->next->tcb.frame)) { break; } } ASSERT(k->next); } else { *p = k->value; return; } } else { nt=t; } u=nt - (Lib3dsFloat)k->tcb.frame; u/=(Lib3dsFloat)(k->next->tcb.frame - k->tcb.frame); *p = lib3ds_float_cubic( k->value, k->dd, k->next->ds, k->next->value, u );}/*! * \ingroup tracks */Lib3dsBoollib3ds_lin1_track_read(Lib3dsLin1Track *track, FILE *f){ int keys; int i; Lib3dsLin1Key *k; track->flags=lib3ds_word_read(f); lib3ds_dword_read(f); lib3ds_dword_read(f); keys=lib3ds_intd_read(f); for (i=0; i<keys; ++i) { k=lib3ds_lin1_key_new(); if (!lib3ds_tcb_read(&k->tcb, f)) { return(LIB3DS_FALSE); } k->value=lib3ds_float_read(f); lib3ds_lin1_track_insert(track, k); } lib3ds_lin1_track_setup(track); return(LIB3DS_TRUE);}/*! * \ingroup tracks */Lib3dsBoollib3ds_lin1_track_write(Lib3dsLin1Track *track, FILE *f){ Lib3dsLin1Key *k; Lib3dsDword num=0; for (k=track->keyL; k; k=k->next) { ++num; } lib3ds_word_write((Lib3dsWord)track->flags,f); lib3ds_dword_write(0,f); lib3ds_dword_write(0,f); lib3ds_dword_write(num,f); for (k=track->keyL; k; k=k->next) { if (!lib3ds_tcb_write(&k->tcb,f)) { return(LIB3DS_FALSE); } lib3ds_float_write(k->value,f); } return(LIB3DS_TRUE);}/*! * \ingroup tracks */Lib3dsLin3Key*lib3ds_lin3_key_new(){ Lib3dsLin3Key* k; k=(Lib3dsLin3Key*)calloc(sizeof(Lib3dsLin3Key), 1); return(k);}/*! * \ingroup tracks */voidlib3ds_lin3_key_free(Lib3dsLin3Key *key){ ASSERT(key); free(key);}/*! * \ingroup tracks */voidlib3ds_lin3_track_free_keys(Lib3dsLin3Track *track){ Lib3dsLin3Key *p,*q; ASSERT(track); for (p=track->keyL; p; p=q) { q=p->next; lib3ds_lin3_key_free(p); }}/*! * \ingroup tracks */voidlib3ds_lin3_key_setup(Lib3dsLin3Key *p, Lib3dsLin3Key *cp, Lib3dsLin3Key *c, Lib3dsLin3Key *cn, Lib3dsLin3Key *n){ Lib3dsVector np,nn; Lib3dsFloat ksm,ksp,kdm,kdp; int i; ASSERT(c); if (!cp) { cp=c; } if (!cn) { cn=c; } if (!p && !n) { lib3ds_vector_zero(c->ds); lib3ds_vector_zero(c->dd); return; } if (n && p) { lib3ds_tcb(&p->tcb, &cp->tcb, &c->tcb, &cn->tcb, &n->tcb, &ksm, &ksp, &kdm, &kdp); lib3ds_vector_sub(np, c->value, p->value); lib3ds_vector_sub(nn, n->value, c->value); for(i=0; i<3; ++i) { c->ds[i]=ksm*np[i] + ksp*nn[i]; c->dd[i]=kdm*np[i] + kdp*nn[i]; } } else { if (p) { lib3ds_vector_sub(np, c->value, p->value); lib3ds_vector_copy(c->ds, np); lib3ds_vector_copy(c->dd, np); } if (n) { lib3ds_vector_sub(nn, n->value, c->value); lib3ds_vector_copy(c->ds, nn); lib3ds_vector_copy(c->dd, nn); } }}/*! * \ingroup tracks */voidlib3ds_lin3_track_setup(Lib3dsLin3Track *track){ Lib3dsLin3Key *pp,*pc,*pn,*pl; ASSERT(track); pc=track->keyL; if (!pc) { return; } if (!pc->next) { lib3ds_vector_zero(pc->ds); lib3ds_vector_zero(pc->dd); return; } if (track->flags&LIB3DS_SMOOTH) { for (pl=track->keyL; pl->next->next; pl=pl->next); lib3ds_lin3_key_setup(pl, pl->next, pc, 0, pc->next); } else { lib3ds_lin3_key_setup(0, 0, pc, 0, pc->next); } for (;;) { pp=pc; pc=pc->next; pn=pc->next; if (!pn) { break; } lib3ds_lin3_key_setup(pp, 0, pc, 0, pn); } if (track->flags&LIB3DS_SMOOTH) { lib3ds_lin3_key_setup(pp, 0, pc, track->keyL, track->keyL->next); } else { lib3ds_lin3_key_setup(pp, 0, pc, 0, 0); }}/*! * \ingroup tracks */voidlib3ds_lin3_track_insert(Lib3dsLin3Track *track, Lib3dsLin3Key *key){ ASSERT(track); ASSERT(key);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -