1 /*
2      PLIB - A Suite of Portable Game Libraries
3      Copyright (C) 1998-2004  Steve Baker
4 
5      This library is free software; you can redistribute it and/or
6      modify it under the terms of the GNU Library General Public
7      License as published by the Free Software Foundation; either
8      version 2 of the License, or (at your option) any later version.
9 
10      This library 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 GNU
13      Library General Public License for more details.
14 
15      You should have received a copy of the GNU Library General Public
16      License along with this library; if not, write to the Free Software
17      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 
19      For further information visit http://plib.sourceforge.net
20 
21      $Id: ssgAnimTransform.cxx,v
22 */
23 
24 // Written by Wolfram Kuss in Oct 2004
25 
26 #include "ssgLocal.h"
27 
28 float _ssgGlobTime = 0.0f;
29 
getTypeName(void)30 const char *ssgAnimTransform::getTypeName (void) { return "ssgAnimTransform" ; }
31 
copy_from(ssgAnimTransform * src,int clone_flags)32 void ssgAnimTransform::copy_from ( ssgAnimTransform *src, int clone_flags )
33 {
34   selectBank ( src->getCurrBank () ) ;
35   mode = src->mode;
36   //ARGH!!!!!!!!!!!!!!!!!!!! transformations.copy_from(static_cast<ssgSimpleList *>(&src->transformations), clone_flags);
37   ssgBranch::copy_from ( src, clone_flags ) ;
38 }
39 
clone(int clone_flags)40 ssgBase *ssgAnimTransform::clone ( int clone_flags )
41 {
42   ssgAnimTransform *b = new ssgAnimTransform ;
43   b -> copy_from ( this, clone_flags ) ;
44   return b ;
45 }
46 
47 
48 
ssgAnimTransform(void)49 ssgAnimTransform::ssgAnimTransform (void)
50 {
51   type = ssgTypeAnimTransform () ;
52   curr_bank = 0.0f ;
53   mode = SSGTWEEN_REPEAT;
54 }
55 
56 
~ssgAnimTransform(void)57 ssgAnimTransform::~ssgAnimTransform (void)
58 {
59   removeAllKids () ;
60 }
61 // ********* done till here *************
62 
cull(sgFrustum * f,sgMat4 m,int test_needed)63 void ssgAnimTransform::cull ( sgFrustum *f, sgMat4 m, int test_needed )
64 {
65   // calculate the transformation
66 
67 // comment is partly obsolete:
68 // You need to have a object with animation loaded into memory for the following function to make sense.
69 // Animation can be discreet (in steps) or "smooth" (fluid).
70 // If you loaded an animation made of several meshes, it will use a selector and therefore always be "discreet"
71 // If you loaded some transformation matrices like some rotations to rotate the flap of a plane,
72 // the define DISCREET_STEPS will determine whether the animation is smooth (new code, WK) or
73 // in steps ("old" code, Dave McClurg).
74 //
75 // The anim_frame is for discreet animation and an index determining which matrix / which selector will be used.
76 // For the smooth animation, the parameter curr_time_ms is used that should be the current time,
77 // Typically in MilliSeconds. However, you can speed up or slow down time.
78 // You could even stop changing curr_time_ms to freeze the animation.
79 //
80 // typically, you will call ssgSetAnimTime directly before you call ssgCullAndDraw
81 //void ssgSetAnimTime( ssgEntity *e, int anim_frame, long curr_time_ms )
82 
83 
84   int num = transformations. getNum () ;
85   if ( num > 0 )
86   {
87 #ifdef DISCREET_STEPS
88     int frame = curr_bank ;
89     if ( frame >= num )
90       frame = num-1 ;
91     transformations. selection = frame ;
92     setTransform ( *( transformations. get ( transformations. selection ) ) ) ;
93 #else
94     /* fluid motion */
95     ///// copied from ssgTween.cxx and changed var names
96 
97     //if(global_mode)
98     curr_bank = _ssgGlobTime;
99 
100     if ( curr_bank < 0.0f ) curr_bank = 0.0f ;
101 
102     int   state1 = (int) floor ( curr_bank ) ;
103     int   state2 = state1 + 1 ;
104     float tween  = curr_bank - (float) state1 ;
105 
106     if ( mode == SSGTWEEN_REPEAT )
107     {
108       state1 %= num ;
109       state2 %= num ;
110     }
111     else
112     {
113       if ( state1 >= num ) state1 = num - 1 ;
114       if ( state2 >= num ) state2 = num - 1 ;
115     }
116 
117     if ( state1 == state2    ) tween  = 0.0f;
118     /////
119 
120     sgMat4 XForm, *pmFrame1;
121     pmFrame1 = transformations. get ( state1 );
122     sgMat4 *pmFrame2 = transformations. get ( state2 );
123     for(int i=0;i<4;i++)
124       for(int j=0; j<4; j++)
125         XForm[i][j] = tween * ((*pmFrame1)[i][j]) +
126                (1.0f-tween) * ((*pmFrame2)[i][j]);
127     setTransform ( XForm );
128 #endif
129   }
130 
131   ssgTransform::cull ( f, m, test_needed ) ;
132 }
133 
134 
135 // ********* below: done *************
136 
load(FILE * fd)137 int ssgAnimTransform::load ( FILE *fd )
138 {
139   _ssgReadFloat ( fd, & curr_bank ) ;
140   int int_mode;
141   _ssgReadInt ( fd, &int_mode );
142   mode = int_mode;
143   transformations.load( fd );
144 
145   return ssgBranch::load ( fd ) ;
146 }
147 
148 
save(FILE * fd)149 int ssgAnimTransform::save ( FILE *fd )
150 {
151   _ssgWriteFloat ( fd, curr_bank ) ;
152   int int_mode = mode;
153   _ssgWriteInt ( fd, int_mode );
154   transformations.save( fd );
155 
156   return ssgBranch::save ( fd ) ;
157 }
158 
159 
160 
print(FILE * fd,char * indent,int how_much)161 void ssgAnimTransform::print ( FILE *fd, char *indent, int how_much )
162 {
163   if ( how_much == 0 )
164     return ;
165 
166   fprintf ( fd, "%sCurrent Bank = %f\n", indent, curr_bank );
167   fprintf ( fd, "%sMode = %d\n", indent, (int)mode );
168   if ( how_much > 1 )
169     transformations.print( fd, indent, how_much );
170 
171   ssgBranch::print ( fd, indent, how_much ) ;
172 }
173 
174 
175