Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

ssgKeyframeTransform.cpp

Go to the documentation of this file.
00001 /*
00002  * ssgKeyframeTransform.cpp
00003  *
00004  * Part of Fly! Legacy project
00005  *
00006  * Copyright 2003 Chris Wallace
00007  *
00008  * Fly! Legacy is free software; you can redistribute it and/or modify
00009  *   it under the terms of the GNU General Public License as published by
00010  *   the Free Software Foundation; either version 2 of the License, or
00011  *   (at your option) any later version.
00012  *
00013  * Fly! Legacy is distributed in the hope that it will be useful,
00014  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  *   GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  *   along with Fly! Legacy; if not, write to the Free Software
00020  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  */
00023 
00029 #include "ssgLocal.h"
00030 #include "../Include/FlyLegacy.h"
00031 
00032 //
00033 // ssgKeyframeTransform
00034 //
00035 /*
00036 void ssgKeyframeTransform::copy_from ( ssgKeyframeTransform *src, int clone_flags ) 
00037 {
00038   ssgBaseTransform::copy_from ( src, clone_flags ) ;
00039 
00040   nFrames = src->nFrames;
00041   min = src->min;
00042   max = src->max;
00043   next = src->next;
00044   memcpy (data, src->data, nFrames * sizeof(SKeyframe));
00045 }
00046 
00047 ssgBase *ssgKeyframeTransform::clone ( int clone_flags )
00048 {
00049   ssgKeyframeTransform *b = new ssgKeyframeTransform (nFrames, min, max);
00050   b -> copy_from ( this, clone_flags ) ;
00051   return b;
00052 }
00053 */
00054 
00055 
00056 //
00057 // Constructor
00058 //
00059 ssgKeyframeTransform::ssgKeyframeTransform (int n,
00060                       float minValue,
00061                       float maxValue)
00062 {
00063   type = ssgTypeKeyframeTransform();
00064 
00065   // Allocate storage for keyframe data table and init 'next entry' index
00066   nFrames = n;
00067   data = new SKeyframe[nFrames];
00068   next = 0;
00069 
00070   min = minValue;
00071   max = maxValue;
00072 }
00073 
00074 
00075 //
00076 // Destructor
00077 //
00078 ssgKeyframeTransform::~ssgKeyframeTransform (void)
00079 {
00080   delete data;
00081 }
00082 
00083 
00084 void ssgKeyframeTransform::addKeyframe (float frame, sgCoord *xform)
00085 {
00086   if (next < nFrames) {
00087     // Store keyframe value
00088     data[next].frame = frame;
00089 
00090     // Convert sgCoord to mat4
00091     sgCopyCoord (&data[next].transform, xform);
00092 
00093     // Increment index of next keyframe
00094     next++;
00095   }
00096 }
00097 
00098 
00099 void ssgKeyframeTransform::setKeyframe (float frame)
00100 {
00101   // Search for keyframes before and after the frame value
00102   SKeyframe *pPre = NULL;
00103   SKeyframe *pPost = NULL;
00104   SKeyframe *pMatch = NULL;
00105 
00106   if (frame <= min) {
00107     pMatch = &data[0];
00108   } else if (frame >= max) {
00109     pMatch = &data[nFrames-1];
00110   } else
00111     for (int i=0; i<nFrames; i++) {
00112       SKeyframe *f = &data[i];
00113 
00114       if (f->frame == frame) {
00115         // Exact match
00116         pMatch = f;
00117         break;
00118       } else {
00119         if (f->frame < frame) {
00120           // Replace 'pre' with this keyframe
00121           pPre = f;
00122         } else {
00123           if ((f->frame > frame) && (pPost == NULL)) {
00124             pPost = f;
00125           }
00126         }
00127       }
00128     }
00129 
00130   // If an exact match was found then just use the matching values
00131   if (pMatch) {
00132     setTransform (&pMatch->transform);
00133   } else {
00134     if ((pPre == NULL) || (pPost == NULL)) {
00135       gtfo ("ssgKeyframeTransform::setKeyframe : Could not find pre/post entries");
00136     } else {
00137       // Interpolate between pre and post
00138       float scale = (frame - pPre->frame) / (pPost->frame - pPre->frame);
00139       float dx = pPost->transform.xyz[0] - pPre->transform.xyz[0];
00140       float dy = pPost->transform.xyz[1] - pPre->transform.xyz[1];
00141       float dz = pPost->transform.xyz[2] - pPre->transform.xyz[2];
00142       float dh = pPost->transform.hpr[0] - pPre->transform.hpr[0];
00143       float dp = pPost->transform.hpr[1] - pPre->transform.hpr[1];
00144       float dr = pPost->transform.hpr[2] - pPre->transform.hpr[2];
00145 
00146       sgCoord coord;
00147       coord.xyz[0] = pPre->transform.xyz[0] + (scale * dx);
00148       coord.xyz[1] = pPre->transform.xyz[1] + (scale * dy);
00149       coord.xyz[2] = pPre->transform.xyz[2] + (scale * dz);
00150       coord.hpr[0] = pPre->transform.hpr[0] + (scale * dh);
00151       coord.hpr[1] = pPre->transform.hpr[1] + (scale * dp);
00152       coord.hpr[2] = pPre->transform.hpr[2] + (scale * dr);
00153       setTransform (&coord);
00154     }
00155   }
00156 }
00157 
00158 
SourceForge.net Logo Documentation generated by doxygen