PageRenderTime 47ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/CS/migrated/branches/R0_14/include/csengine/cssprite.h

#
C++ Header | 651 lines | 226 code | 108 blank | 317 comment | 5 complexity | f7c0b674b68789b747af5e86e035ea7e MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, LGPL-2.0
  1. /*
  2. Copyright (C) 1998 by Jorrit Tyberghein
  3. This library is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU Library General Public
  5. License as published by the Free Software Foundation; either
  6. version 2 of the License, or (at your option) any later version.
  7. This library is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10. Library General Public License for more details.
  11. You should have received a copy of the GNU Library General Public
  12. License along with this library; if not, write to the Free
  13. Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. #ifndef CSSPRITE_H
  16. #define CSSPRITE_H
  17. #include "csgeom/math3d.h"
  18. #include "csgeom/math2d.h"
  19. #include "csgeom/polyint.h"
  20. #include "csengine/csobjvec.h"
  21. #include "csengine/rview.h"
  22. #include "csengine/cscolor.h"
  23. #include "csengine/texture.h"
  24. #include "igraph3d.h"
  25. class Dumper;
  26. class csTextureList;
  27. class csTextureHandle;
  28. class csTriangleMesh;
  29. class csLightHitsSprite;
  30. class csSkeleton;
  31. class csSkeletonState;
  32. class csSprite3D;
  33. class csBspContainer;
  34. interface ITextureHandle;
  35. /**
  36. * A frame for 3D sprite animation.
  37. */
  38. class csFrame : public csBase
  39. {
  40. private:
  41. csVector3* vertices;
  42. csVector2* texels;
  43. csVector3* normals;
  44. char* name;
  45. int max_vertex;
  46. /// Bounding box in object space for this frame.
  47. csVector3 box_min, box_max;
  48. public:
  49. ///
  50. csFrame (int max_vertices);
  51. ///
  52. virtual ~csFrame ();
  53. ///
  54. void SetVertex (int i, float x, float y, float z)
  55. {
  56. vertices[i].x = x;
  57. vertices[i].y = y;
  58. vertices[i].z = z;
  59. }
  60. ///
  61. void SetVertex (int i, const csVector3& v)
  62. {
  63. vertices[i].x = v.x;
  64. vertices[i].y = v.y;
  65. vertices[i].z = v.z;
  66. }
  67. ///
  68. void SetTexel (int i, float u, float v)
  69. {
  70. texels[i].x = u;
  71. texels[i].y = v;
  72. }
  73. ///
  74. void SetName (char * n);
  75. ///
  76. char* GetName () { return name; }
  77. ///
  78. csVector3& GetVertex (int i) { return vertices[i]; }
  79. ///
  80. csVector3* GetVertices () { return vertices; }
  81. ///
  82. csVector2& GetTexel (int i) { return texels[i]; }
  83. ///
  84. csVector3& GetNormal (int i) { return normals[i]; }
  85. /// Return true if this frame has calculated normals.
  86. bool HasNormals () { return normals != NULL; }
  87. ///
  88. void AddVertex (int num_vertices);
  89. ///
  90. int GetMaxVertices () { return max_vertex; }
  91. /**
  92. * Reorder vertices in this frame according to a mapping.
  93. * This is used after LOD precalculation to remap the vertices
  94. * in a more efficient ordering.
  95. * The index to 'mapping' is the old vertex number. The
  96. * result is the new number.
  97. */
  98. void RemapVertices (int* mapping, int num_vertices);
  99. /**
  100. * Compute all normals in this frame given the
  101. * mesh which connects the vertices in the frame.
  102. * The vertex array is also given. Note that the vertex
  103. * array from the frame is not used because it is possible
  104. * that the vertices are computed using a skeleton.
  105. */
  106. void ComputeNormals (csTriangleMesh* mesh, csVector3* object_verts, int num_vertices);
  107. /**
  108. * Compute the object space bounding box for this frame.
  109. * This has to be called after setting up the frame and before
  110. * using it.
  111. */
  112. void ComputeBoundingBox (int num_vertices);
  113. /**
  114. * Get the bounding box in object space.
  115. */
  116. void GetBoundingBox (csVector3& bbox_min, csVector3& bbox_max)
  117. { bbox_min = box_min; bbox_max = box_max; }
  118. };
  119. /**
  120. * A Action frameset for a 3D sprite animation.
  121. */
  122. class csSpriteAction : public csBase
  123. {
  124. public:
  125. /// Initialize a action object
  126. csSpriteAction ();
  127. /// Destroy this action object
  128. virtual ~csSpriteAction ();
  129. /// Add a frame to this action
  130. void AddFrame (csFrame * frame, int delay);
  131. /// Set action name
  132. void SetName (char *n);
  133. /// Get action name
  134. char * GetName ()
  135. { return name; }
  136. /// Get total number of frames in this action
  137. int GetNumFrames ()
  138. { return frames.Length (); }
  139. /// Query the frame number f
  140. csFrame* GetFrame (int f)
  141. { return (f < frames.Length ()) ? (csFrame *)frames [f] : (csFrame*)NULL; }
  142. /// Get delay for frame number f
  143. int GetFrameDelay (int f)
  144. { return (int)delays [f]; }
  145. private:
  146. char *name;
  147. csVector frames;
  148. csVector delays;
  149. };
  150. /**
  151. * A 3D sprite based on a triangle mesh with a single texture.
  152. * Animation is done with frames.
  153. * This class represents a template from which a csSprite3D
  154. * class can be made.
  155. */
  156. class csSpriteTemplate : public csObject
  157. {
  158. friend class Dumper;
  159. private:
  160. friend class csSprite3D;
  161. friend class csCollider;
  162. /// Texture handle as returned by ITextureManager.
  163. csTextureHandle* cstxt;
  164. /// The vertices.
  165. int num_vertices;
  166. /// The triangles.
  167. csTriangleMesh* base_mesh;
  168. /// An optional skeleton.
  169. csSkeleton* skeleton;
  170. /**
  171. * The order in which to introduce levels in order to get to a higher LOD.
  172. * The index of this array is the vertex number which is introduced.
  173. * The vertices of this template were reordered (by GenerateLOD()) so that
  174. * the first vertices are used in low-detail. The contents of this array
  175. * is the vertex number to emerge from.
  176. */
  177. int* emerge_from;
  178. /// The frames
  179. csObjVector frames;
  180. /// The actions (a vector of csSpriteAction objects)
  181. csObjVector actions;
  182. public:
  183. /// Create the sprite template
  184. csSpriteTemplate ();
  185. /// Destroy the template
  186. virtual ~csSpriteTemplate ();
  187. /**
  188. * Create a new sprite for this template.
  189. * The 'default' action will be made default. If there is
  190. * no default action the first action will be made default.
  191. * The sprite will also be initialized (csSprite3D::InitSprite()).
  192. */
  193. csSprite3D* NewSprite ();
  194. /**
  195. * Get the base triangle mesh of this sprite.
  196. */
  197. csTriangleMesh* GetBaseMesh () { return base_mesh; }
  198. /// Set the skeleton for this sprite template.
  199. void SetSkeleton (csSkeleton* sk);
  200. /// Get the skeleton for this sprite template.
  201. csSkeleton* GetSkeleton () { return skeleton; }
  202. /// Get the 'emerge_from' array from which you can construct triangles.
  203. int* GetEmergeFrom () { return emerge_from; }
  204. /**
  205. * Generate the collapse order.
  206. * This function will also reorder all the vertices in the template.
  207. * So be careful!
  208. */
  209. void GenerateLOD ();
  210. /**
  211. * Compute the object space bounding box for all frames in this
  212. * template. This has to be called after setting up the template and before
  213. * using it.
  214. */
  215. void ComputeBoundingBox ();
  216. /// Set the number of vertices.
  217. void SetNumVertices (int v) { num_vertices = v; }
  218. /// Query the number of vertices.
  219. int GetNumVertices () { return num_vertices; }
  220. /// Create and add a new frame to the sprite.
  221. csFrame* AddFrame ();
  222. /// find a named frame into the sprite.
  223. csFrame* FindFrame (char * name);
  224. /// Query the number of frames
  225. int GetNumFrames () { return frames.Length (); }
  226. /// Query the frame number f
  227. csFrame* GetFrame (int f)
  228. { return (f < frames.Length ()) ? (csFrame *)frames [f] : (csFrame*)NULL; }
  229. /// Create and add a new action frameset to the sprite.
  230. csSpriteAction* AddAction ();
  231. /// find a named action into the sprite.
  232. csSpriteAction* FindAction (const char * name);
  233. /// Get the first action.
  234. csSpriteAction* GetFirstAction ()
  235. { return (csSpriteAction *)actions [0]; }
  236. /// Get number of actions in sprite
  237. int GetNumActions ()
  238. { return actions.Length (); }
  239. /// Get action number No
  240. csSpriteAction* GetAction (int No)
  241. { return (csSpriteAction *)actions [No]; }
  242. /// Get the texture
  243. csTextureHandle* GetTexture () const { return cstxt; }
  244. /// Get the texture handle.
  245. ITextureHandle* GetTextureHandle () const { return cstxt->GetTextureHandle (); }
  246. /// Set the texture used for this sprite
  247. void SetTexture (csTextureList* textures, char *texname);
  248. CSOBJTYPE;
  249. };
  250. /// A callback function for csSprite3D::Draw().
  251. typedef void (csSpriteCallback) (csSprite3D* spr, csRenderView* rview);
  252. /**
  253. * A 3D sprite based on a triangle mesh with a single texture.
  254. * Animation is done with frames (a frame may be controlled by
  255. * a skeleton).
  256. */
  257. class csSprite3D : public csObject
  258. {
  259. friend class Dumper;
  260. friend class csCollider;
  261. private:
  262. /// Static vertex array.
  263. static csVector3* tr_verts;
  264. /// Static z array.
  265. static float* z_verts;
  266. /// Static uv array.
  267. static csVector2* uv_verts;
  268. /// The perspective corrected vertices.
  269. static csVector2* persp;
  270. /// Array which indicates which vertices are visible and which are not.
  271. static bool* visible;
  272. /// Array for lighting.
  273. static csLight** light_worktable;
  274. static int max_light_worktable;
  275. /// Update the above tables with a new size.
  276. static void UpdateWorkTables (int max_size);
  277. /// Update defered lighting.
  278. void UpdateDeferedLighting ();
  279. public:
  280. /// List of sectors where this sprite is.
  281. csObjVector sectors;
  282. /**
  283. * Configuration value for global LOD. 0 is lowest detail, 1 is maximum.
  284. * If negative then the base mesh is used and no LOD reduction/computation
  285. * is done.
  286. */
  287. static float cfg_lod_detail;
  288. protected:
  289. UInt MixMode;
  290. private:
  291. /// Object to world transformation.
  292. csVector3 v_obj2world;
  293. /// Object to world transformation.
  294. csMatrix3 m_obj2world;
  295. /// World to object transformation.
  296. csMatrix3 m_world2obj;
  297. /**
  298. * A mesh which contains a number of triangles as generated
  299. * by the LOD algorithm. This is static since it will likely
  300. * change every frame anyway. We hold it static also since
  301. * we don't want to allocate it again every time.
  302. */
  303. static csTriangleMesh mesh;
  304. /**
  305. * Array of colors for the vertices. If not set then this
  306. * sprite does not have colored vertices.
  307. */
  308. csColor* vertex_colors;
  309. /// The template.
  310. csSpriteTemplate* tpl;
  311. /// The texture handle as returned by ITextureManager.
  312. csTextureHandle* cstxt;
  313. /// The current frame number.
  314. int cur_frame;
  315. /// The current action.
  316. csSpriteAction* cur_action;
  317. /// The last frame time action
  318. int last_time;
  319. ///
  320. bool force_otherskin;
  321. /**
  322. * List of light-hits-sprites for this sprite.
  323. */
  324. csLightHitsSprite* dynamiclights;
  325. /// Skeleton state (optional).
  326. csSkeletonState* skeleton_state;
  327. /// Defered lighting. If > 0 then we have defered lighting.
  328. int defered_num_lights;
  329. /// Flags to use for defered lighting.
  330. int defered_lighting_flags;
  331. /// The callback which is called just before drawing.
  332. csSpriteCallback* draw_callback;
  333. /**
  334. * Flag which is set to true when the sprite is visible.
  335. * This is used by the c-buffer/bsp routines. The sprite itself
  336. * will not use this flag in any way at all. It is simply intended
  337. * for external visibility culling routines.
  338. */
  339. bool is_visible;
  340. public:
  341. ///
  342. csSprite3D ();
  343. ///
  344. virtual ~csSprite3D ();
  345. ///
  346. void SetTemplate (csSpriteTemplate* tmpl);
  347. ///
  348. csSpriteTemplate* GetTemplate () { return tpl; }
  349. /// Get the skeleton state for this sprite.
  350. csSkeletonState* GetSkeletonState () { return skeleton_state; }
  351. /// force a new texture skin other than default
  352. void SetTexture (char * name, csTextureList* textures);
  353. /// Mark this sprite as visible.
  354. void MarkVisible () { is_visible = true; }
  355. /// Mark this sprite as invisible.
  356. void MarkInvisible () { is_visible = false; }
  357. /// Return if this sprite is visible.
  358. bool IsVisible () { return is_visible; }
  359. /**
  360. * Set a color for a vertex.
  361. * As soon as you use this function this sprite will be rendered
  362. * using gouraud shading. Calling this function for the first time
  363. * will initialize all colors to black.
  364. */
  365. void SetVertexColor (int i, const csColor& col);
  366. /**
  367. * Add a color for a vertex.
  368. * As soon as you use this function this sprite will be rendered
  369. * using gouraud shading. Calling this function for the first time
  370. * will initialize all colors to black.
  371. */
  372. void AddVertexColor (int i, const csColor& col);
  373. /**
  374. * Reset the color list. If you call this function then the
  375. * sprite will no longer use gouraud shading.
  376. */
  377. void ResetVertexColors ();
  378. /**
  379. * Clamp all vertice colors to 2.0. This is called inside
  380. * csSprite3D::UpdateLighting() so that 3D renderer doesn't have
  381. * to deal with brightness lighter than 2.0
  382. */
  383. void FixVertexColors ();
  384. /**
  385. * Light sprite according to the given array of lights (i.e.
  386. * fill the vertex color array).
  387. * No shadow calculation will be done. This is assumed to have
  388. * been done earlier. This is a primitive lighting process
  389. * based on the lights which hit one point of the sprite (usually
  390. * the center). More elaborate lighting systems are possible
  391. * but this will do for now.
  392. */
  393. void UpdateLighting (csLight** lights, int num_lights);
  394. /**
  395. * Update lighting as soon as the sprite becomes visible.
  396. * This will call world->GetNearestLights with the supplied
  397. * parameters.
  398. */
  399. void DeferUpdateLighting (int flags, int num_lights);
  400. ///
  401. void UnsetTexture ()
  402. { force_otherskin = false; }
  403. /// Sets the mode that is used, when drawing that sprite.
  404. void SetMixmode (UInt m) { MixMode = m; }
  405. /**
  406. * Set the transformation vector to move sprite to some position.
  407. */
  408. void SetMove (const csVector3& v) { SetMove (v.x, v.y, v.z); }
  409. /**
  410. * Set the transformation vector to move sprite to some position.
  411. */
  412. void SetMove (float x, float y, float z);
  413. /**
  414. * Set the transformation matrix to rotate the sprite in some
  415. * orientation
  416. */
  417. void SetTransform (const csMatrix3& matrix);
  418. /**
  419. * Relative move
  420. */
  421. void Move (float dx, float dy, float dz);
  422. /**
  423. * Relative move
  424. */
  425. void Move (csVector3& v) { Move (v.x, v.y, v.z); }
  426. /**
  427. * Absolute move
  428. */
  429. bool MoveTo (const csVector3& v);
  430. /**
  431. * The same as above
  432. */
  433. bool MoveTo (float x, float y, float z) { return MoveTo (csVector3 (x, y, z)); }
  434. /**
  435. * Relative transform.
  436. */
  437. void Transform (csMatrix3& matrix);
  438. /**
  439. * Calculate a bounding box for this sprite in world space and add
  440. * the resulting polygons to the given container.
  441. */
  442. void AddBoundingBox (csBspContainer* container);
  443. /**
  444. * Fill the static mesh with the current sprite
  445. * for a given LOD level.
  446. */
  447. void GenerateSpriteLOD (int num_vts);
  448. /**
  449. * Draw this sprite given a camera transformation.
  450. * If needed the skeleton state will first be updated.
  451. * Optionally update lighting if needed (DeferUpdateLighting()).
  452. */
  453. void Draw (csRenderView& rview);
  454. /**
  455. * Set a callback which is called just before the sprite is drawn.
  456. * This is useful to do some expensive computations which only need
  457. * to be done on a visible sprite.
  458. */
  459. void SetDrawCallback (csSpriteCallback* callback) { draw_callback = callback; }
  460. /**
  461. * Get the draw callback. If there are multiple draw callbacks you can
  462. * use this function to chain.
  463. */
  464. csSpriteCallback* GetDrawCallback () { return draw_callback; }
  465. /**
  466. * Go to the next frame depending on the current time in milliseconds.
  467. */
  468. bool NextFrame (long current_time, bool onestep = false, bool stoptoend = false);
  469. /**
  470. * Go to a specified frame.
  471. */
  472. void SetFrame (int f)
  473. {
  474. if (cur_action && f < cur_action->GetNumFrames ()) cur_frame = f;
  475. }
  476. /**
  477. * Get the current frame number.
  478. */
  479. int GetCurFrame () { return cur_frame; }
  480. /**
  481. * Get the current frame number.
  482. */
  483. csSpriteAction* GetCurAction () { return cur_action; }
  484. /**
  485. * Get the number of frames.
  486. */
  487. int GetNumFrames () { return cur_action->GetNumFrames (); }
  488. /**
  489. * Select an action.
  490. */
  491. void SetAction (const char * name)
  492. {
  493. csSpriteAction *act;
  494. if ((act = tpl->FindAction (name)) != NULL)
  495. {
  496. SetFrame (0);
  497. cur_action = act;
  498. }
  499. }
  500. /**
  501. * Initialize a sprite. This function is called automatically
  502. * from within 'load'. However you should call it directly
  503. * if you created the sprite on the fly (without 'load').
  504. */
  505. void InitSprite ();
  506. /// Get world to local transformation matrix
  507. inline csMatrix3 GetW2T () const { return m_world2obj; }
  508. /// Get world to local translation
  509. inline csVector3 GetW2TTranslation () const { return -v_obj2world; }
  510. /// Move this sprite to one sector (conveniance function).
  511. void MoveToSector (csSector* s);
  512. /// Remove this sprite from all sectors it is in (but not from the world).
  513. void RemoveFromSectors ();
  514. /**
  515. * Get an array of object vertices which is valid for the given frame.
  516. * This function correcty acounts for sprites which use skeletons. In
  517. * that case it will use the current transformation state of the skeleton
  518. * to compute object space vertices.<br>
  519. * Warning! The returned array should be used immediatelly or copied. It
  520. * points to a private static array in the sprite class and can be reused
  521. * if other calls to the sprite happen.
  522. */
  523. csVector3* GetObjectVerts (csFrame* fr);
  524. /**
  525. * Unlink a light-hits-sprite from the list.
  526. * Warning! This function does not test if it
  527. * is really on the list!
  528. */
  529. void UnlinkDynamicLight (csLightHitsSprite* lp);
  530. /**
  531. * Add a light-hits-sprite to the list.
  532. */
  533. void AddDynamicLight (csLightHitsSprite *lp);
  534. /**
  535. * Get the list of dynamic lights that hit this sprite.
  536. */
  537. csLightHitsSprite* GetDynamicLights () { return dynamiclights; }
  538. CSOBJTYPE;
  539. };
  540. #endif /*CSSPRITE_H*/