Planeshift
|
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