/* * The 3D Studio File Format Library * Copyright (C) 1996-2001 by J.E. Hoffmann * 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$ */ #define LIB3DS_EXPORT #include "quat.h" #include /*! * \defgroup quat Quaternion Mathematics * * \author J.E. Hoffmann */ /*! * \typedef Lib3dsQuat * \ingroup quat */ /*! * \ingroup quat */ void lib3ds_quat_zero(Lib3dsQuat c) { c[0]=c[1]=c[2]=c[3]=0.0f; } /*! * \ingroup quat */ void lib3ds_quat_identity(Lib3dsQuat c) { c[0]=c[1]=c[2]=0.0f; c[3]=1.0f; } /*! * \ingroup quat */ void lib3ds_quat_copy(Lib3dsQuat dest, Lib3dsQuat src) { int i; for (i=0; i<4; ++i) { dest[i]=src[i]; } } /*! * \ingroup quat */ void lib3ds_quat_axis_angle(Lib3dsQuat c, Lib3dsVector axis, Lib3dsFloat angle) { Lib3dsDouble omega,s; Lib3dsDouble l; l=sqrt(axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]); if (lLIB3DS_EPSILON) { if (fabs(l)>1.0f) l/=fabs(l); om=acos(l); sinom=sin(om); if (fabs(sinom)>LIB3DS_EPSILON) { sp=sin((1.0f-t)*om)/sinom; sq=sin(t*om)/sinom; } else { sp=1.0f-t; sq=t; } c[0]=(Lib3dsFloat)(sp*a[0] + sq*b[0]); c[1]=(Lib3dsFloat)(sp*a[1] + sq*b[1]); c[2]=(Lib3dsFloat)(sp*a[2] + sq*b[2]); c[3]=(Lib3dsFloat)(sp*a[3] + sq*b[3]); } else { q[0]=-a[1]; q[1]=a[0]; q[2]=-a[3]; q[3]=a[2]; sp=sin((1.0-t)*LIB3DS_HALFPI); sq=sin(t*LIB3DS_HALFPI); c[0]=(Lib3dsFloat)(sp*a[0] + sq*q[0]); c[1]=(Lib3dsFloat)(sp*a[1] + sq*q[1]); c[2]=(Lib3dsFloat)(sp*a[2] + sq*q[2]); c[3]=(Lib3dsFloat)(sp*a[3] + sq*q[3]); } } /*! * \ingroup quat */ void lib3ds_quat_squad(Lib3dsQuat c, Lib3dsQuat a, Lib3dsQuat p, Lib3dsQuat q, Lib3dsQuat b, Lib3dsFloat t) { Lib3dsQuat ab; Lib3dsQuat pq; lib3ds_quat_slerp(ab,a,b,t); lib3ds_quat_slerp(pq,p,q,t); lib3ds_quat_slerp(c,ab,pq,2*t*(1-t)); } /*! * \ingroup quat */ void lib3ds_quat_tangent(Lib3dsQuat c, Lib3dsQuat p, Lib3dsQuat q, Lib3dsQuat n) { Lib3dsQuat dn,dp,x; int i; lib3ds_quat_ln_dif(dn, q, n); lib3ds_quat_ln_dif(dp, q, p); for (i=0; i<4; i++) { x[i]=-1.0f/4.0f*(dn[i]+dp[i]); } lib3ds_quat_exp(x); lib3ds_quat_mul(c,q,x); } /*! * \ingroup quat */ void lib3ds_quat_dump(Lib3dsQuat q) { printf("%f %f %f %f\n", q[0], q[1], q[2], q[3]); }