W3DGranny.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program 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
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. #include "always.h"
  24. #include "hanim.h"
  25. #include "proto.h"
  26. #include "rendobj.h"
  27. #include "LightEnvironment.h"
  28. #include "w3d_file.h"
  29. #include "dx8vertexbuffer.h"
  30. #include "dx8indexbuffer.h"
  31. #include "shader.h"
  32. #include "vertmaterial.h"
  33. #include "Lib/BaseType.h"
  34. #pragma once
  35. #ifndef __W3DGRANNY_H_
  36. #define __W3DGRANNY_H_
  37. #ifdef INCLUDE_GRANNY_IN_BUILD
  38. #include "granny.h"
  39. class GrannyRenderObjSystem; ///<forward reference
  40. class GrannyPrototypeClass; ///<forward reference
  41. class GrannyLoaderClass
  42. {
  43. public:
  44. GrannyLoaderClass(void);
  45. ~GrannyLoaderClass(void);
  46. PrototypeClass * Load_W3D(const char *filename);
  47. granny_material_library *Get_Material_Library(void) {return MaterialLibrary;}
  48. private:
  49. granny_texture_library *TextureLibrary;
  50. granny_material_library *MaterialLibrary;
  51. };
  52. extern GrannyLoaderClass _GrannyLoader;
  53. /// Custom animation type specific to Granny.
  54. class GrannyAnimClass : public HAnimClass
  55. {
  56. friend class GrannyRenderObjClass;
  57. public:
  58. enum
  59. {
  60. OK,
  61. LOAD_ERROR
  62. };
  63. GrannyAnimClass(void);
  64. ~GrannyAnimClass(void);
  65. const char * Get_Name(void) const { return Name;}
  66. const char * Get_HName(void) const { return Name;}
  67. int Get_Num_Frames(void) { return NumFrames;}
  68. float Get_Frame_Rate() { return FrameRate;}
  69. float Get_Total_Time() { return (float)NumFrames / FrameRate;}
  70. void Get_Translation(Vector3& translation, int pividx,float frame) const {translation=Vector3(0,0,0);}
  71. void Get_Orientation(Quaternion& orientation, int pividx,float frame) const {orientation=Quaternion(1);}
  72. void Get_Transform(Matrix3D& mtx, int pividx, float frame) const {mtx=Matrix3D(1);}
  73. Bool Get_Visibility(int pividx,float frame) { return 1;} //assume always visible
  74. int Get_Num_Pivots(void) const { return 1;}
  75. Bool Is_Node_Motion_Present(int pividx) {return true;}
  76. int Load_W3D(const char *name);
  77. private:
  78. granny_animation *Animation;
  79. granny_file *File;
  80. int NumFrames;
  81. float FrameRate;
  82. char Name[2*W3D_NAME_LEN];
  83. };
  84. class GrannyAnimManagerClass
  85. {
  86. public:
  87. GrannyAnimManagerClass(void);
  88. ~GrannyAnimManagerClass(void);
  89. int Load_Anim(const char *name);
  90. GrannyAnimClass * Get_Anim(const char * name);
  91. GrannyAnimClass * Peek_Anim(const char * name);
  92. Bool Add_Anim(GrannyAnimClass *new_anim);
  93. void Free_All_Anims(void);
  94. void Register_Missing( const char * name );
  95. Bool Is_Missing( const char * name );
  96. void Reset_Missing( void );
  97. private:
  98. int Load_Raw_Anim(const char *name);
  99. HashTableClass * AnimPtrTable;
  100. HashTableClass * MissingAnimTable;
  101. friend class GrannyAnimManagerIterator;
  102. };
  103. /*
  104. ** An Iterator to get to all loaded HAnims in a HAnimManager
  105. */
  106. class GrannyAnimManagerIterator : public HashTableIteratorClass {
  107. public:
  108. GrannyAnimManagerIterator( GrannyAnimManagerClass & manager ) : HashTableIteratorClass( *manager.AnimPtrTable ) {}
  109. GrannyAnimClass * Get_Current_Anim( void );
  110. };
  111. /// Custom render object that draws tracks on the terrain.
  112. /**
  113. This render object handles drawing tracks left by objects moving on the terrain. It will only work
  114. with rectangular planar surfaces and was tuned with an emphasis on water.
  115. Since skies are only visible in reflections, this code will also
  116. render clouds and sky bodies.
  117. */
  118. class GrannyRenderObjClass : public RenderObjClass
  119. {
  120. friend class GrannyRenderObjSystem;
  121. friend class W3DShadow;
  122. public:
  123. GrannyRenderObjClass(const GrannyPrototypeClass &proto);
  124. ~GrannyRenderObjClass(void);
  125. /////////////////////////////////////////////////////////////////////////////
  126. // Render Object Interface (W3D methods)
  127. /////////////////////////////////////////////////////////////////////////////
  128. virtual RenderObjClass * Clone(void) const;
  129. virtual int Class_ID(void) const;
  130. virtual void Render(RenderInfoClass & rinfo);
  131. virtual void Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const;
  132. virtual void Get_Obj_Space_Bounding_Box(AABoxClass & aabox) const;
  133. virtual void Set_Animation( HAnimClass * motion, float frame, int anim_mode = ANIM_MODE_MANUAL);
  134. void Set_ObjectScale(float scale); ///<adjust internal scale factor applied to rendered asset.
  135. Bool Cast_Ray(RayCollisionTestClass & raytest); ///<returns intersection of ray and picking box.
  136. Int freeResources(void); ///<free W3D assets used for this track
  137. const GrannyPrototypeClass & getPrototype(void) const { return m_prototype;}
  138. protected:
  139. granny_model_instance *m_modelInstance; ///<granny instance used to control model
  140. granny_control *m_animationControl; ///<current animation
  141. const GrannyPrototypeClass &m_prototype; ///<prototype that was used to create this model.
  142. Int AnimMode; ///<type of animation playing
  143. Real LastSyncTime; ///<time of last animation update
  144. SphereClass m_boundingSphere; ///<bounding sphere of TerrainTracks
  145. AABoxClass m_boundingBox; ///<bounding box of TerrainTracks
  146. Int m_vertexCount; ///<number of vertices in model
  147. GrannyRenderObjClass *m_nextSystem; ///<next track system
  148. GrannyRenderObjClass *m_prevSystem; ///<previous track system
  149. };
  150. #define GRANNY_MAX_MESHES_PER_MODEL 4
  151. /** Prototype or definition of a Granny model. Contains all info need to instance a model of this type.*/
  152. class GrannyPrototypeClass : public PrototypeClass
  153. {
  154. friend class GrannyRenderObjClass;
  155. friend class GrannyRenderObjSystem;
  156. public:
  157. GrannyPrototypeClass(granny_file *file)
  158. { m_file = file; assert(m_file); m_vertexCount=0;
  159. m_name[0]='\0';
  160. m_meshCount=0;
  161. m_vertexMaterial=NEW_REF(VertexMaterialClass,());
  162. m_vertexMaterial->Set_Shininess(0.0);
  163. m_vertexMaterial->Set_Specular(0,0,0);
  164. m_vertexMaterial->Set_Lighting(true);
  165. }
  166. struct grannyMeshDesc
  167. {
  168. const UnsignedInt *index; ///< pointer to pool of face indices
  169. Int indexCount; ///< number of face indices in this mesh
  170. const granny_pnt332_vertex *vertex; ///< pointer to pool of mesh vertices
  171. Int vertexCount; ///< number of vertices in this mesh.
  172. };
  173. virtual ~GrannyPrototypeClass(void) { if (m_vertexMaterial) REF_PTR_RELEASE (m_vertexMaterial); if (m_file) GrannyFreeFile(m_file); }
  174. virtual const char * Get_Name(void) const { return m_name; }
  175. virtual int Get_Class_ID(void) const { return RenderObjClass::CLASSID_UNKNOWN; }
  176. virtual RenderObjClass * Create(void) { return NEW_REF( GrannyRenderObjClass, (*this) ); }
  177. void Set_Name(char *name) {strcpy(m_name,name);}
  178. void setBoundingBox(AABoxClass & box) {m_boundingBox=box;}
  179. void setBoundingSphere(SphereClass & sphere) {m_boundingSphere=sphere;}
  180. void setVertexCount(Int vertexCount) {m_vertexCount=vertexCount;}
  181. void setIndexCount(Int indexCount) {m_indexCount=indexCount;}
  182. void setMeshCount(Int meshCount) {m_meshCount=meshCount;}
  183. void setMeshData(grannyMeshDesc &meshdesc, Int index) {m_meshData[index]=meshdesc;}
  184. const UnsignedInt *getMeshIndexList(int index) const { if (index < m_meshCount) return m_meshData[0].index; else return NULL;}
  185. const granny_pnt332_vertex *getMeshVertexList(int index) const { if (index < m_meshCount) return m_meshData[0].vertex; else return NULL;}
  186. const Int getIndexCount(void) const {return m_indexCount;} //return total number of indices in model
  187. private:
  188. granny_file *m_file; ///<pointer to Granny allocated model data.
  189. char m_name[32]; ///<prototype name
  190. AABoxClass m_boundingBox; ///<bounding volume used for picking and frustum culling.
  191. SphereClass m_boundingSphere; ///<bounding volume used for picking and frustum culling.
  192. VertexMaterialClass *m_vertexMaterial; ///<vertex lighting material used for this model.
  193. Int m_vertexCount; ///< total/maximum number of vertices that will be needed to draw complete model.
  194. Int m_indexCount; ///< total/maximum number of indices that will be needed to draw the complete model.
  195. Int m_meshCount; ///< total number of meshes in model - meshes can have different materials
  196. grannyMeshDesc m_meshData[GRANNY_MAX_MESHES_PER_MODEL]; ///<descriptions of all meshes in this model
  197. };
  198. #define MAX_GRANNY_RENDERSTATES 32 //maximum number of render states available to granny models per frame.
  199. #define MAX_VISIBLE_GRANNY_MODELS 200 //maximum number of granny models to render per frame
  200. class GrannyRenderObjSystem
  201. {
  202. public:
  203. void AddRenderObject(RenderInfoClass & rinfo, GrannyRenderObjClass *robj); ///<buffers model for rendering at frame flush.
  204. void Flush(void); ///<renders all objects queued up for this frame.
  205. void queueUpdate(void) {m_doUpdate=TRUE;} ///<tell Granny to update all animations - do this only once per frame.
  206. protected:
  207. struct RenderStateModelList{
  208. GrannyRenderObjClass *list; ///<start of Granny models using this renderstate
  209. };
  210. RenderStateModelList m_renderStateModelList[MAX_GRANNY_RENDERSTATES]; ///<list of render states used during this frame.
  211. LightEnvironmentClass m_renderLocalLightEnv[MAX_VISIBLE_GRANNY_MODELS]; ///<pool of lighting settings available to granny
  212. Int m_renderStateCount; ///<number of different render states requested in current frame.
  213. Int m_renderObjectCount; ///<number of granny models to render this frame.
  214. Bool m_doUpdate; ///<flag to indicate if animation time needs to be updated this frame.
  215. };
  216. extern GrannyRenderObjSystem *TheGrannyRenderObjSystem; ///< singleton for drawing all Granny models.
  217. #if 0 ///@todo: Will have to implement an optimized granny rendering system
  218. /// System for loading, drawing, and updating Granny models
  219. /**
  220. This system keeps track of all the active granny objects and renders any models
  221. that were submitted in current frame.
  222. */
  223. class GrannyRenderObjClassSystem
  224. {
  225. friend class GrannyRenderObjClass;
  226. public:
  227. GrannyRenderObjClassSystem( void );
  228. ~GrannyRenderObjClassSystem( void );
  229. void ReleaseResources(void); ///< Release all dx8 resources so the device can be reset.
  230. void ReAcquireResources(void); ///< Reacquire all resources after device reset.
  231. void flush (void); ///<draw all models that were requested for rendering.
  232. void update(void); ///<update the state of all models.
  233. void init(); ///< pre-allocate resources and initialize granny.
  234. void shutdown( void ); ///< release all pre-allocated resources and kill Granny.
  235. RenderObjClass *createRenderObj(const char * name); ///< create an instance of the model
  236. protected:
  237. DX8VertexBufferClass *m_vertexBuffer; ///<vertex buffer used to draw all tracks
  238. DX8IndexBufferClass *m_indexBuffer; ///<indices defining triangles in maximum length track
  239. VertexMaterialClass *m_vertexMaterialClass; ///< vertex lighting material
  240. ShaderClass m_shaderClass; ///<shader or rendering state for heightmap
  241. GrannyRenderObjClass *m_usedModules; ///<active objects being rendered in the scene
  242. GrannyRenderObjClass *m_freeModules; //<unused modules that are free to use again
  243. }; // end class GrannyRenderObjClassSystem
  244. extern GrannyRenderObjClassSystem *TheGrannyRenderObjClassSystem; ///< singleton for track drawing system.
  245. #endif //end of GrannyRenderObjClassSystem
  246. #endif //INCLUDE_GRANNY_IN_BUILD
  247. #endif // end __W3DGRANNY_H_