sphereobj.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. /*
  2. ** Command & Conquer Generals(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. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : WW3D *
  23. * *
  24. * $Archive:: /Commando/Code/ww3d2/sphereobj.h $*
  25. * *
  26. * Author:: Jason Andersen *
  27. * *
  28. * $Modtime:: 5/05/01 6:28p $*
  29. * *
  30. * $Revision:: 6 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #if defined(_MSC_VER)
  36. #pragma once
  37. #endif
  38. #ifndef SPHEREOBJ_H
  39. #define SPHEREOBJ_H
  40. #include "always.h"
  41. #include "rendobj.h"
  42. #include "w3d_file.h"
  43. #include "shader.h"
  44. #include "proto.h"
  45. #include "obbox.h"
  46. #include "vector3i.h"
  47. #include "quat.h"
  48. #include "prim_anim.h"
  49. class TextureClass;
  50. struct AlphaVectorStruct
  51. {
  52. AlphaVectorStruct (void)
  53. : angle (true),
  54. intensity (1.0F) { }
  55. AlphaVectorStruct (const AlphaVectorStruct &src) { *this = src; }
  56. bool operator== (const AlphaVectorStruct &src) { return (angle.X == src.angle.X) && (angle.Y == src.angle.Y) && (angle.Z == src.angle.Z) && (intensity == src.intensity); }
  57. bool operator!= (const AlphaVectorStruct &src) { return ! operator== (src); }
  58. const AlphaVectorStruct & operator= (const AlphaVectorStruct &src) { angle = src.angle; intensity = src.intensity; return *this; }
  59. Quaternion angle;
  60. float intensity;
  61. };
  62. class AlphaVectorChannel : public PrimitiveAnimationChannelClass<AlphaVectorStruct>
  63. {
  64. public:
  65. AlphaVectorStruct Evaluate (float time)
  66. {
  67. int key_count = m_Data.Count ();
  68. AlphaVectorStruct value = m_Data[key_count - 1].Get_Value ();
  69. //
  70. // Don't interpolate past the last keyframe
  71. //
  72. if (time < m_Data[key_count - 1].Get_Time ()) {
  73. // Check to see if the last key index is valid
  74. if (time < m_Data[m_LastIndex].Get_Time ()) {
  75. m_LastIndex = 0;
  76. }
  77. KeyClass *key1 = &m_Data[m_LastIndex];
  78. KeyClass *key2 = &m_Data[key_count - 1];
  79. //
  80. // Search, using last_key as our starting point
  81. //
  82. for (int keyidx = m_LastIndex; keyidx < (key_count - 1); keyidx ++) {
  83. if (time < m_Data[keyidx+1].Get_Time ()) {
  84. key1 = &m_Data[keyidx];
  85. key2 = &m_Data[keyidx+1];
  86. m_LastIndex = keyidx;
  87. break;
  88. }
  89. }
  90. // Calculate the linear percent between the two keys
  91. float percent = (time - key1->Get_Time ()) / (key2->Get_Time () - key1->Get_Time ());
  92. // Slerp the quaternions and lerp the intensities
  93. value.intensity = (key1->Get_Value ().intensity + (key2->Get_Value ().intensity - key1->Get_Value ().intensity) * percent);
  94. Fast_Slerp (value.angle, key1->Get_Value ().angle, key2->Get_Value ().angle, percent);
  95. }
  96. return value;
  97. }
  98. };
  99. struct W3dSphereStruct
  100. {
  101. uint32 Version; // file format version
  102. uint32 Attributes; // sphere attributes (above #define's)
  103. char Name[2*W3D_NAME_LEN]; // name is in the form <containername>.<spherename>
  104. W3dVectorStruct Center; // center of the sphere
  105. W3dVectorStruct Extent; // extent of the sphere
  106. float AnimDuration; // Animation time (in seconds)
  107. W3dVectorStruct DefaultColor;
  108. float DefaultAlpha;
  109. W3dVectorStruct DefaultScale;
  110. AlphaVectorStruct DefaultVector;
  111. char TextureName[2*W3D_NAME_LEN];
  112. W3dShaderStruct Shader;
  113. //
  114. // Note this structure is followed by a series of
  115. // W3dSphereKeyArrayStruct structures which define the
  116. // variable set of keyframes for each channel.
  117. //
  118. };
  119. typedef LERPAnimationChannelClass<Vector3> SphereColorChannelClass;
  120. typedef LERPAnimationChannelClass<float> SphereAlphaChannelClass;
  121. typedef LERPAnimationChannelClass<Vector3> SphereScaleChannelClass;
  122. typedef AlphaVectorChannel SphereVectorChannelClass;
  123. //typedef AlphaVectorChannel ;
  124. class VertexMaterialClass;
  125. class SphereMeshClass
  126. {
  127. friend class SphereRenderObjClass;
  128. public:
  129. // Constructor
  130. SphereMeshClass(void);
  131. SphereMeshClass(float radius, int slices, int stacks);
  132. // Destructor
  133. ~SphereMeshClass(void);
  134. void Generate (float radius, int slices, int stacks);
  135. int Get_Num_Polys (void) { return face_ct; };
  136. void Set_Alpha_Vector (const AlphaVectorStruct &v, bool inverse, bool is_additive, bool force = false);
  137. private:
  138. void Set_DCG (bool is_additive, int index, float value);
  139. void Free(void);
  140. float Radius;
  141. int Slices;
  142. int Stacks;
  143. int face_ct; // # of faces
  144. int Vertex_ct; // vertex count
  145. Vector3 *vtx; // array of vertices
  146. Vector3 *vtx_normal; // array of vertex normals
  147. Vector2 *vtx_uv; // array of vertex uv coordinates
  148. Vector4 *dcg;
  149. AlphaVectorStruct alpha_vector; // vector last used to computer vtx_alpha array
  150. bool inverse_alpha; // inverse alpha, or not
  151. bool IsAdditive;
  152. int strip_ct; // number of strips
  153. int strip_size; // size of each strip
  154. int *strips; // array of vertex indices for each strip (# stripbs x sizeof strip)
  155. int fan_ct; // number of fans
  156. int fan_size; // size of each fan
  157. int *fans; // array of vertex indices for each fan (# of fans by fan_size)
  158. Vector3i *tri_poly; // array of triangle poly's, vertex indices (can be discard if switched to strips + fans)
  159. };
  160. inline void
  161. SphereMeshClass::Set_DCG (bool is_additive, int index, float value)
  162. {
  163. if (is_additive) {
  164. dcg[index].X = value;
  165. dcg[index].Y = value;
  166. dcg[index].Z = value;
  167. dcg[index].W = 0;
  168. } else {
  169. dcg[index].X = 1.0F;
  170. dcg[index].Y = 1.0F;
  171. dcg[index].Z = 1.0F;
  172. dcg[index].W = value;
  173. }
  174. return ;
  175. }
  176. /*
  177. ** SphereRenderObjClass: Procedurally generated render spheres
  178. **
  179. */
  180. class SphereRenderObjClass : public RenderObjClass
  181. {
  182. public:
  183. // These are bit masks, so they should enum 1,2,4,8,10,20,40 etc...
  184. enum SphereFlags {
  185. USE_ALPHA_VECTOR = 0x00000001,
  186. USE_CAMERA_ALIGN = 0x00000002,
  187. USE_INVERSE_ALPHA = 0x00000004,
  188. USE_ANIMATION_LOOP= 0x00000008,
  189. };
  190. SphereRenderObjClass(void);
  191. SphereRenderObjClass(const W3dSphereStruct & def);
  192. SphereRenderObjClass(const SphereRenderObjClass & src);
  193. SphereRenderObjClass & operator = (const SphereRenderObjClass &);
  194. ~SphereRenderObjClass(void);
  195. /////////////////////////////////////////////////////////////////////////////
  196. // Render Object Interface
  197. /////////////////////////////////////////////////////////////////////////////
  198. virtual RenderObjClass * Clone(void) const;
  199. virtual int Class_ID(void) const;
  200. virtual void Render(RenderInfoClass & rinfo);
  201. virtual void Special_Render(SpecialRenderInfoClass & rinfo);
  202. virtual void Set_Transform(const Matrix3D &m);
  203. virtual void Set_Position(const Vector3 &v);
  204. virtual void Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const;
  205. virtual void Get_Obj_Space_Bounding_Box(AABoxClass & aabox) const;
  206. virtual void Set_Hidden(int onoff) { RenderObjClass::Set_Hidden (onoff); Update_On_Visibilty (); }
  207. virtual void Set_Visible(int onoff) { RenderObjClass::Set_Visible (onoff); Update_On_Visibilty (); }
  208. virtual void Set_Animation_Hidden(int onoff) { RenderObjClass::Set_Animation_Hidden (onoff); Update_On_Visibilty (); }
  209. virtual void Set_Force_Visible(int onoff) { RenderObjClass::Set_Force_Visible (onoff); Update_On_Visibilty (); }
  210. const AABoxClass & Get_Box(void);
  211. virtual int Get_Num_Polys(void) const;
  212. virtual const char * Get_Name(void) const;
  213. virtual void Set_Name(const char * name);
  214. unsigned int Get_Flags(void) { return Flags; }
  215. void Set_Flags(unsigned int flags) { Flags = flags; }
  216. void Set_Flag(unsigned int flag, bool onoff) { Flags &= (~flag); if (onoff) Flags |= flag; }
  217. // Animation access
  218. bool Is_Animating (void) { return IsAnimating; }
  219. void Start_Animating (void) { IsAnimating = true; anim_time = 0; }
  220. void Stop_Animating (void) { IsAnimating = false; anim_time = 0; }
  221. // Current state access
  222. void Set_Color(const Vector3 & color) { Color = color; }
  223. void Set_Alpha(float alpha) { Alpha = alpha; }
  224. void Set_Scale(const Vector3 & scale) { Scale = scale; }
  225. void Set_Vector(const AlphaVectorStruct &v) { Vector = v; }
  226. const Vector3 & Get_Color(void) const { return Color; }
  227. float Get_Alpha(void) const { return Alpha; }
  228. const Vector3 & Get_Scale(void) const { return Scale; }
  229. const AlphaVectorStruct & Get_Vector(void) const { return Vector; }
  230. Vector3 Get_Default_Color(void) const;
  231. float Get_Default_Alpha(void) const;
  232. Vector3 Get_Default_Scale(void) const;
  233. AlphaVectorStruct Get_Default_Vector(void) const;
  234. // Size/position methods
  235. void Set_Extent (const Vector3 &extent);
  236. void Set_Local_Center_Extent(const Vector3 & center,const Vector3 & extent);
  237. void Set_Local_Min_Max(const Vector3 & min,const Vector3 & max);
  238. // Texture access
  239. void Set_Texture(TextureClass *tf);
  240. TextureClass * Peek_Texture(void) {return SphereTexture;}
  241. ShaderClass & Get_Shader(void) {return SphereShader;}
  242. void Set_Shader(ShaderClass &shader) {SphereShader=shader;}
  243. // Animation control
  244. float Get_Animation_Duration (void) const { return AnimDuration; }
  245. void Set_Animation_Duration (float time) { AnimDuration = time; Restart_Animation (); }
  246. void Restart_Animation (void) { anim_time = 0; }
  247. // Animatable channel access
  248. SphereColorChannelClass & Get_Color_Channel (void) { return ColorChannel; }
  249. const SphereColorChannelClass & Peek_Color_Channel (void) { return ColorChannel; }
  250. SphereAlphaChannelClass & Get_Alpha_Channel (void) { return AlphaChannel; }
  251. const SphereAlphaChannelClass & Peek_Alpha_Channel (void) { return AlphaChannel; }
  252. SphereScaleChannelClass & Get_Scale_Channel (void) { return ScaleChannel; }
  253. const SphereScaleChannelClass & Peek_Scale_Channel (void) { return ScaleChannel; }
  254. SphereVectorChannelClass & Get_Vector_Channel (void) { return VectorChannel; }
  255. const SphereVectorChannelClass & Peek_Vector_Channel (void) { return VectorChannel; }
  256. void Set_Color_Channel (const SphereColorChannelClass &data) { ColorChannel = data; }
  257. void Set_Alpha_Channel (const SphereAlphaChannelClass &data) { AlphaChannel = data; }
  258. void Set_Scale_Channel (const SphereScaleChannelClass &data) { ScaleChannel = data; }
  259. void Set_Vector_Channel (const SphereVectorChannelClass &data) { VectorChannel = data; }
  260. protected:
  261. virtual void update_cached_box(void);
  262. virtual void Update_Cached_Bounding_Volumes(void) const;
  263. void Update_On_Visibilty(void);
  264. // Initialization stuff
  265. void Init_Material (void);
  266. static void Generate_Shared_Mesh_Arrays (const AlphaVectorStruct &alphavector);
  267. // Animation Stuff
  268. void animate(void); // animation update function
  269. float anim_time; // what time in seconds are we in the animation
  270. float AnimDuration;
  271. bool IsAnimating;
  272. SphereColorChannelClass ColorChannel;
  273. SphereAlphaChannelClass AlphaChannel;
  274. SphereScaleChannelClass ScaleChannel;
  275. SphereVectorChannelClass VectorChannel;
  276. void update_mesh_data(const Vector3 & center,const Vector3 & extent);
  277. void render_sphere();
  278. void vis_render_sphere(SpecialRenderInfoClass & rinfo,const Vector3 & center,const Vector3 & extent);
  279. char Name[2*W3D_NAME_LEN];
  280. Vector3 ObjSpaceCenter;
  281. Vector3 ObjSpaceExtent;
  282. int CurrentLOD;
  283. // Current State
  284. Vector3 Color;
  285. float Alpha;
  286. Vector3 Scale;
  287. AlphaVectorStruct Vector;
  288. Quaternion Orientation;
  289. // Flags
  290. unsigned int Flags;
  291. VertexMaterialClass *SphereMaterial;
  292. ShaderClass SphereShader;
  293. TextureClass *SphereTexture;
  294. AABoxClass CachedBox;
  295. // Friend classes
  296. friend class SpherePrototypeClass;
  297. };
  298. inline void SphereRenderObjClass::Set_Extent (const Vector3 &extent)
  299. {
  300. ObjSpaceExtent = extent;
  301. update_cached_box();
  302. Update_Cached_Bounding_Volumes();
  303. }
  304. inline void SphereRenderObjClass::Set_Local_Center_Extent(const Vector3 & center,const Vector3 & extent)
  305. {
  306. ObjSpaceCenter = center;
  307. ObjSpaceExtent = extent;
  308. update_cached_box();
  309. }
  310. inline void SphereRenderObjClass::Set_Local_Min_Max(const Vector3 & min,const Vector3 & max)
  311. {
  312. ObjSpaceCenter = (max + min) / 2.0f;
  313. ObjSpaceExtent = (max - min) / 2.0f;
  314. update_cached_box();
  315. }
  316. inline const AABoxClass & SphereRenderObjClass::Get_Box(void)
  317. {
  318. Validate_Transform();
  319. update_cached_box();
  320. return CachedBox;
  321. }
  322. /*
  323. ** Loader for spheres
  324. */
  325. class SphereLoaderClass : public PrototypeLoaderClass
  326. {
  327. public:
  328. virtual int Chunk_Type (void) { return W3D_CHUNK_SPHERE; }
  329. virtual PrototypeClass * Load_W3D(ChunkLoadClass & cload);
  330. };
  331. /*
  332. ** Prototype for Sphere objects
  333. */
  334. class SpherePrototypeClass : public W3DMPO, public PrototypeClass
  335. {
  336. W3DMPO_GLUE(SpherePrototypeClass)
  337. public:
  338. SpherePrototypeClass (void);
  339. SpherePrototypeClass (SphereRenderObjClass *sphere);
  340. virtual const char * Get_Name(void) const;
  341. virtual int Get_Class_ID(void) const;
  342. virtual RenderObjClass * Create(void);
  343. virtual void DeleteSelf() { delete this; }
  344. bool Load (ChunkLoadClass &cload);
  345. bool Save (ChunkSaveClass &csave);
  346. protected:
  347. ~SpherePrototypeClass (void);
  348. private:
  349. W3dSphereStruct Definition;
  350. SphereColorChannelClass ColorChannel;
  351. SphereAlphaChannelClass AlphaChannel;
  352. SphereScaleChannelClass ScaleChannel;
  353. SphereVectorChannelClass VectorChannel;
  354. };
  355. /*
  356. ** Instance of the loader which the asset manager installs
  357. */
  358. extern SphereLoaderClass _SphereLoader;
  359. #endif // SPHEREOBJ_H
  360. // EOF - sphereobj,h