Planeshift

pseffectanchor.h

Go to the documentation of this file.
00001 /*
00002  * Author: Andrew Robberts
00003  *
00004  * Copyright (C) 2003 Atomic Blue ([email protected], http://www.atomicblue.org)
00005  *
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation (version 2 of the License)
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software
00016  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017  *
00018  */
00019 
00020 #ifndef PS_EFFECT_ANCHOR_HEADER
00021 #define PS_EFFECT_ANCHOR_HEADER
00022 
00023 #include <csutil/csstring.h>
00024 #include <csutil/array.h>
00025 #include <csutil/bitarray.h>
00026 #include <csutil/leakguard.h>
00027 #include <csutil/parray.h>
00028 #include <csutil/refcount.h>
00029 #include <iutil/virtclk.h>
00030 #include <imesh/object.h>
00031 
00032 struct iDocumentNode;
00033 struct iEngine;
00034 struct iView;
00035 struct iMeshFactoryWrapper;
00036 struct iSector;
00037 struct iSectorList;
00038 
00046 class psEffectAnchorKeyFrame
00047 {
00048 public:
00049     psEffectAnchorKeyFrame();
00050     psEffectAnchorKeyFrame(iDocumentNode* node, const psEffectAnchorKeyFrame* prevKeyFrame);
00051     ~psEffectAnchorKeyFrame();
00052 
00056     void SetDefaults();
00057 
00061     void SetupFirstFrame();
00062 
00064     float time;
00065 
00066     enum INTERP_TYPE
00067     {
00068         IT_NONE = 0,
00069         IT_FLOOR,
00070         IT_CEILING,
00071         IT_LERP,
00072 
00073         IT_COUNT
00074     };
00075 
00076     enum KEY_ACTION
00077     {
00078         KA_POS_X = 1, KA_POS_Y, KA_POS_Z,
00079         KA_TOTARGET_X, KA_TOTARGET_Y, KA_TOTARGET_Z,
00080 
00081         KA_COUNT
00082     };
00083     float actions[KA_COUNT];
00084 
00085     inline const char* GetActionName(size_t idx)
00086     {
00087         switch(idx)
00088         {
00089             case KA_POS_X:
00090                 return "Position X";
00091             case KA_POS_Y:
00092                 return "Position Y";
00093             case KA_POS_Z:
00094                 return "Position Z";
00095             case KA_TOTARGET_X:
00096                 return "To Target X";
00097             case KA_TOTARGET_Y:
00098                 return "To Target Y";
00099             case KA_TOTARGET_Z:
00100                 return "To Target Z";
00101         }
00102         return "";
00103     }
00104 
00105     inline bool IsActionSet(size_t idx)
00106     {
00107         return specAction.IsBitSet(idx);
00108     }
00109 
00111     csBitArray specAction;
00112 };
00113 
00114 
00118 class psEffectAnchorKeyFrameGroup : public csRefCount
00119 {
00120 private:
00121     csPDelArray<psEffectAnchorKeyFrame> keyFrames;
00122 
00123 public:
00124     psEffectAnchorKeyFrameGroup();
00125     ~psEffectAnchorKeyFrameGroup();
00126 
00132     size_t GetSize() const
00133     {
00134         return keyFrames.GetSize();
00135     }
00136 
00143     psEffectAnchorKeyFrame* Get(size_t idx) const
00144     {
00145         return keyFrames[idx];
00146     }
00147 
00154     psEffectAnchorKeyFrame* operator [](size_t idx) const
00155     {
00156         return keyFrames[idx];
00157     }
00158 
00164     void Push(psEffectAnchorKeyFrame* keyFrame)
00165     {
00166         keyFrames.Push(keyFrame);
00167     }
00168 
00174     void DeleteIndex(size_t idx)
00175     {
00176         keyFrames.DeleteIndex(idx);
00177     }
00178 
00182     void DeleteAll()
00183     {
00184         keyFrames.DeleteAll();
00185     }
00186 };
00187 
00191 class psEffectAnchor
00192 {
00193 public:
00194     psEffectAnchor();
00195     virtual ~psEffectAnchor();
00196 
00203     virtual bool Load(iDocumentNode* node);
00204 
00213     virtual bool Create(const csVector3 &offset, iMeshWrapper* posAttach, bool rotateWithMesh = false);
00214 
00221     virtual bool Update(csTicks elapsed);
00222 
00228     void CloneBase(psEffectAnchor* newAnchor) const;
00229 
00233     virtual psEffectAnchor* Clone() const;
00234 
00242     virtual void SetPosition(const csVector3 &basePos, iSector* sector, const csMatrix3 &transf);
00243 
00251     virtual void SetPosition(const csVector3 &basePos, iSectorList* sectors, const csMatrix3 &transf);
00252 
00259     void SetTarget(const csVector3 &newTarget, const csMatrix3 &transf)
00260     {
00261         target = newTarget;
00262         targetTransf = transf;
00263     }
00264 
00270     const csString &GetName() const
00271     {
00272         return name;
00273     }
00274 
00280     void SetName(const csString &newName)
00281     {
00282         name = newName;
00283     }
00284 
00290     iMeshWrapper* GetMesh() const
00291     {
00292         return mesh;
00293     }
00294 
00300     virtual void SetRotBase(const csMatrix3 &newRotBase)
00301     {
00302         matBase = newRotBase;
00303     }
00304 
00310     void TransformOffset(csVector3 &offset);
00311 
00317     size_t GetKeyFrameCount() const
00318     {
00319         return keyFrames->GetSize();
00320     }
00321 
00328     psEffectAnchorKeyFrame* GetKeyFrame(size_t idx) const
00329     {
00330         return keyFrames->Get(idx);
00331     }
00332 
00338     const char* GetDirectionType() const;
00339 
00345     void SetDirectionType(const char* newDir);
00346 
00352     void SetAnimLength(float newAnimLength)
00353     {
00354         animLength = newAnimLength;
00355     }
00356 
00362     float GetAnimGetSize()
00363     {
00364         return animLength;
00365     }
00366 
00373     size_t AddKeyFrame(float time);
00374 
00380     bool IsReady() const
00381     {
00382         return isReady;
00383     }
00384 
00385     enum DIR_TYPE
00386     {
00387         DT_NONE = 0,
00388         DT_ORIGIN,
00389         DT_TARGET,
00390 
00391         DT_COUNT
00392     };
00393 
00397     void FillInLerps();
00398 
00399 protected:
00400 
00407     size_t FindKeyFrameByTime(float time) const;
00408 
00417     bool FindNextKeyFrameWithAction(size_t startFrame, size_t action, size_t &index) const;
00418 
00419     csString name; 
00420 
00421     float life;       
00422     float animLength; 
00423 
00424     csMatrix3 matBase; 
00425 
00431     csVector3 objEffectPos;
00432 
00434     csVector3 objBasePos;
00435 
00437     csVector3 objTargetOffset;
00438 
00440     csVector3 objOffset;
00441     csMatrix3 posTransf;
00442 
00444     csVector3 target;
00445     csMatrix3 targetTransf;
00446 
00448     csRef<iMeshWrapper> mesh;
00449 
00451     int dir;
00452 
00454     bool rotateWithMesh;
00455 
00456     size_t currKeyFrame; 
00457     size_t nextKeyFrame; 
00458 
00460     csRef<psEffectAnchorKeyFrameGroup> keyFrames;
00461 
00463     csRef<iEngine> engine;
00464 
00465     bool isReady;
00466 
00468     inline float lerp(float f1, float f2, float t1, float t2, float t)
00469     {
00470         if(t2 == t1)
00471             return f1;
00472 
00473         return f1 + (f2-f1)*(t-t1)/(t2-t1);
00474     }
00475 
00477     inline csVector3 lerpVec(const csVector3 &v1, const csVector3 &v2, float t1, float t2, float t)
00478     {
00479         if(t2 == t1)
00480             return v1;
00481 
00482         return v1 + (v2-v1)*(t-t1)/(t2-t1);
00483     }
00484 };
00485 
00488 #endif