dazzle.cpp 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732
  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. *** 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/dazzle.cpp $*
  25. * *
  26. * Original Author:: Jani Penttinen *
  27. * *
  28. * $Author:: Kenny Mitchell *
  29. * *
  30. * $Modtime:: 06/26/02 4:04p $*
  31. * *
  32. * $Revision:: 32 $*
  33. * *
  34. * 06/26/02 KM Matrix name change to avoid MAX conflicts *
  35. *---------------------------------------------------------------------------------------------*
  36. * Functions: *
  37. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  38. #include "dazzle.h"
  39. #include "simplevec.h"
  40. #include "vector2.h"
  41. #include "camera.h"
  42. #include "ww3d.h"
  43. #include "wwstring.h"
  44. #include "wwdebug.h"
  45. #include "assetmgr.h"
  46. #include "vector3i.h"
  47. #include "quat.h"
  48. #include "ini.h"
  49. #include "point.h"
  50. #include "rinfo.h"
  51. #include "vertmaterial.h"
  52. #include "chunkio.h"
  53. #include "wwfile.h"
  54. #include "inisup.h"
  55. #include "persistfactory.h"
  56. #include "ww3dids.h"
  57. #include "dx8wrapper.h"
  58. #include "dx8vertexbuffer.h"
  59. #include "dx8indexbuffer.h"
  60. #include "sortingrenderer.h"
  61. #include "texture.h"
  62. #include "scene.h"
  63. #include "wwprofile.h"
  64. #include "visrasterizer.h"
  65. #include <cstdio>
  66. #include <limits.h>
  67. #include <wwprofile.h>
  68. // All dazzle types appear under Dazzles_List in the dazzle.ini file.
  69. const char* DAZZLE_LIST_STRING="Dazzles_List";
  70. // After the dot product between the camera direction and the camera space location of the light source,
  71. // we do a power to Halopow for the halo size and power to DazzlePow for the dazzle size. Halo/DazzleArea
  72. // defines the angle where the values are valid, so any angle beyond HaloArea/DazzleArea results the halo or
  73. // dazzle being scaled to zero. The angles are re-scaled from normalized angle scale of (-1.0...1.0)
  74. // only HaloArea/DazzleArea defined part is used.
  75. const char* DAZZLE_INTENSITY_POW_STRING = "DazzleIntensityPow";
  76. const char* DAZZLE_SIZE_POW_STRING = "DazzleSizePow";
  77. const char* DAZZLE_AREA_STRING = "DazzleArea"; // Something like 0.05 is a good starting point for a dazzle...
  78. const char* HALO_INTENSITY_POW = "HaloIntensityPow";
  79. // Halo and dazzle are scaled by these values
  80. const char* HALO_SCALE_X_STRING = "HaloScaleX";
  81. const char* HALO_SCALE_Y_STRING = "HaloScaleY";
  82. const char* DAZZLE_SCALE_X_STRING = "DazzleScaleX";
  83. const char* DAZZLE_SCALE_Y_STRING = "DazzleScaleY";
  84. // Dazzle and halo intensity control the base intensities.
  85. const char* HALO_INTENSITY_STRING = "HaloIntensity";
  86. const char* DAZZLE_INTENSITY_STRING = "DazzleIntensity";
  87. // Direction area defines the maximum difference between the light direction and the eyespace location,
  88. // so the dazzle can only be seen if the camera is inside the light cone. Value 0.0 means dazzle is not
  89. // directional, it can be seen from any direction. Halo is not affected. Dazzle direction defines the light
  90. // direction vector.
  91. const char* DAZZLE_DIRECTION_AREA_STRING = "DazzleDirectionArea"; // Something like 0.5 might be a good test value
  92. const char* DAZZLE_DIRECTION_STRING = "DazzleDirection";
  93. // Dazzle and halo start to afde out after FadeoutStart meters and are completely gone by FadeoutEnd meters.
  94. const char* FADEOUT_START_STRING = "FadeoutStart";
  95. const char* FADEOUT_END_STRING = "FadeoutEnd";
  96. // To be done: This parameter needs to be redefined.
  97. const char* SIZE_OPTIMIZATION_LIMIT_STRING = "SizeOptimizationLimit";
  98. // The weight of history for the intensities. The history weight is per millisecond, so if you want to have
  99. // any real history, values higher than 0.95 are recommended (don't use value of 1.0 or anything higher!)
  100. const char* HISTORY_WEIGHT_STRING = "HistoryWeight";
  101. // Textures to be used.
  102. const char* DAZZLE_TEXTURE_STRING = "DazzleTextureName";
  103. const char* HALO_TEXTURE_STRING = "HaloTextureName";
  104. // If false, camera matrix's translation term isn't used. If translation isn't used the dazzle is treated as
  105. // always visible, scene graph visibility is not used.
  106. const char* USE_CAMERA_TRANSLATION = "UseCameraTranslation";
  107. // Halo and dazzle colors, RGB, (1.0, 1.0, 1.0) is white and (0.0, 0.0, 0.0) is black
  108. const char* HALO_COLOR_STRING = "HaloColor";
  109. const char* DAZZLE_COLOR_STRING = "DazzleColor";
  110. // Dazzle test color could be white in many cases but if the level has a lot of white then another color can be defined.
  111. const char* DAZZLE_TEST_COLOR_STRING = "DazzleTestColor";
  112. // Dazzles can blink on and off. The blink period defines the time for one cycle, the blink "on time" defines
  113. // the amount of time within that period that the dazzle is "on"
  114. const char* BLINK_PERIOD_STRING = "BlinkPeriod";
  115. const char* BLINK_ON_TIME_STRING = "BlinkOnTime";
  116. // Dazzle can use a lensflare by defining a name of lensflare in the ini
  117. const char* DAZZLE_LENSFLARE_STRING = "LensflareName";
  118. // Lensflare definitions
  119. const char* LENSFLARE_LIST_STRING = "Lensflares_List";
  120. // Texture to be used by the lensflare
  121. const char* LENSFLARE_TEXTURE_STRING = "TextureName";
  122. // The number of flare sprites in lensflare. The FlareLocation, FlareSize and FlareColor paremeters are procedural, the
  123. // names are produced based on this parameter. If FlareCount is 3, there exists FlareLocation1, FlareLocation2 and
  124. // FlareLocation3... And so on.
  125. const char* FLARE_COUNT_STRING = "FlareCount";
  126. // 1D-locations of the flares. 0.0 means the location of the center of the screen and 1.0 means the location of the
  127. // lightsource. The values can be smaller than zero and larger than 1.0.
  128. const char* FLARE_LOCATION_STRING = "FlareLocation";
  129. // Normalized flare sizes
  130. const char* FLARE_SIZE_STRING = "FlareSize";
  131. // Colors for each flare sprite
  132. const char* FLARE_COLOR_STRING = "FlareColor";
  133. // Uv coordinates (as there can be only one texture used, but one may want multiple images). The values is a 4-float
  134. // vector: start_u, start_v, end_u, end_v.
  135. const char* FLARE_UV_STRING = "FlareUV";
  136. // Radius of dazzle used for raycast tests
  137. const char * RADIUS_STRING = "Radius";
  138. /*
  139. ; DAZZLE.INI example
  140. [Lensflares_List]
  141. 0=DEFAULT_LENSFLARE
  142. [Dazzles_List]
  143. 0=DEFAULT
  144. ;========================================== LENSFLARE DEFINITIONS =================
  145. [DEFAULT_LENSFLARE]
  146. TextureName=dazzle_secondary.jpg
  147. FlareCount=5
  148. FlareLocation1=0.1
  149. FlareLocation2=0.5
  150. FlareLocation3=1.1
  151. FlareLocation4=1.5
  152. FlareLocation5=-0.4
  153. FlareSize1=0.1
  154. FlareSize2=0.05
  155. FlareSize3=0.08
  156. FlareSize4=0.15
  157. FlareSize5=0.10
  158. FlareColor1=1.0,0.5,0.5
  159. FlareColor2=0.5,1.0,0.5
  160. FlareColor3=0.5,0.5,1.0
  161. FlareColor4=0.5,0.5,1.0
  162. FlareColor5=0.5,0.5,1.0
  163. ;========================================== DAZZLE DEFINITIONS ====================
  164. [DEFAULT]
  165. HaloIntensity=1.0
  166. HaloIntensityPow=0.95
  167. HaloSizePow=0.95
  168. HaloArea=1.0
  169. HaloScaleX=0.2
  170. HaloScaleY=0.2
  171. DazzleArea=0.05
  172. DazzleDirectionArea=0
  173. DazzleDirection=0,1,1
  174. DazzleSizePow=0.9
  175. DazzleIntensityPow=0.9
  176. DazzleIntensity=50
  177. DazzleScaleX=1.0
  178. DazzleScaleY=1.0
  179. FadeoutStart=30.0
  180. FadeoutEnd=40.0
  181. SizeOptimizationLimit=0.05
  182. HistoryWeight=0.975
  183. UseCameraTranslation=1
  184. DazzleTextureName=dazzle_primary.jpg
  185. HaloTextureName=dazzle_secondary.jpg
  186. DazzleColor=1,1,1
  187. HaloColor=0,0,1
  188. DazzleTestColor=1,1,1
  189. LensflareName=DEFAULT_LENSFLARE
  190. */
  191. // Global instance of a dazzle loader
  192. DazzleLoaderClass _DazzleLoader;
  193. static SimpleVecClass<DazzleRenderObjClass*> temp_ptrs;
  194. static DazzleTypeClass** types;
  195. static unsigned type_count;
  196. // Current dazzle layer - must be set before rendering
  197. static DazzleLayerClass * current_dazzle_layer = NULL;
  198. static LensflareTypeClass** lensflares;
  199. static unsigned lensflare_count;
  200. static ShaderClass default_dazzle_shader;
  201. static ShaderClass default_halo_shader;
  202. static ShaderClass vis_shader;
  203. static ShaderClass debug_shader;
  204. // static instance of a default dazzle visibility handler
  205. static DazzleVisibilityClass _DefaultVisibilityHandler;
  206. static const DazzleVisibilityClass * _VisibilityHandler = &_DefaultVisibilityHandler;
  207. bool DazzleRenderObjClass::_dazzle_rendering_enabled = true;
  208. static void Init_Shaders()
  209. {
  210. default_dazzle_shader.Set_Cull_Mode( ShaderClass::CULL_MODE_DISABLE );
  211. default_dazzle_shader.Set_Depth_Mask( ShaderClass::DEPTH_WRITE_DISABLE );
  212. default_dazzle_shader.Set_Depth_Compare( ShaderClass::PASS_ALWAYS );
  213. default_dazzle_shader.Set_Dst_Blend_Func( ShaderClass::DSTBLEND_ONE );
  214. default_dazzle_shader.Set_Src_Blend_Func( ShaderClass::SRCBLEND_ONE );
  215. default_dazzle_shader.Set_Fog_Func( ShaderClass::FOG_DISABLE );
  216. default_dazzle_shader.Set_Primary_Gradient( ShaderClass::GRADIENT_MODULATE );
  217. default_dazzle_shader.Set_Texturing( ShaderClass::TEXTURING_ENABLE );
  218. default_halo_shader.Set_Cull_Mode( ShaderClass::CULL_MODE_DISABLE );
  219. default_halo_shader.Set_Depth_Mask( ShaderClass::DEPTH_WRITE_DISABLE );
  220. default_halo_shader.Set_Depth_Compare( ShaderClass::PASS_LEQUAL );
  221. default_halo_shader.Set_Dst_Blend_Func( ShaderClass::DSTBLEND_ONE );
  222. default_halo_shader.Set_Src_Blend_Func( ShaderClass::SRCBLEND_ONE );
  223. default_halo_shader.Set_Fog_Func( ShaderClass::FOG_DISABLE );
  224. default_halo_shader.Set_Primary_Gradient( ShaderClass::GRADIENT_MODULATE );
  225. default_halo_shader.Set_Texturing( ShaderClass::TEXTURING_ENABLE );
  226. vis_shader.Set_Cull_Mode( ShaderClass::CULL_MODE_DISABLE );
  227. vis_shader.Set_Depth_Mask( ShaderClass::DEPTH_WRITE_DISABLE );
  228. vis_shader.Set_Dst_Blend_Func( ShaderClass::DSTBLEND_ZERO );
  229. vis_shader.Set_Src_Blend_Func( ShaderClass::SRCBLEND_ONE );
  230. vis_shader.Set_Fog_Func( ShaderClass::FOG_DISABLE );
  231. vis_shader.Set_Primary_Gradient( ShaderClass::GRADIENT_MODULATE );
  232. vis_shader.Set_Texturing( ShaderClass::TEXTURING_DISABLE );
  233. debug_shader.Set_Cull_Mode( ShaderClass::CULL_MODE_DISABLE );
  234. debug_shader.Set_Depth_Mask( ShaderClass::DEPTH_WRITE_DISABLE );
  235. debug_shader.Set_Dst_Blend_Func( ShaderClass::DSTBLEND_SRC_ALPHA );
  236. debug_shader.Set_Src_Blend_Func( ShaderClass::SRCBLEND_ONE );
  237. debug_shader.Set_Fog_Func( ShaderClass::FOG_DISABLE );
  238. debug_shader.Set_Primary_Gradient( ShaderClass::GRADIENT_MODULATE );
  239. debug_shader.Set_Texturing( ShaderClass::TEXTURING_DISABLE );
  240. }
  241. /*
  242. ** Derived INI to support Vector4
  243. */
  244. class DazzleINIClass : public INIClass {
  245. public:
  246. DazzleINIClass(FileClass & file) : INIClass(file) {}
  247. const Vector2 Get_Vector2(char const *section, char const *entry, const Vector2 & defvalue = Vector2(0,0) );
  248. const Vector3 Get_Vector3(char const *section, char const *entry, const Vector3 & defvalue = Vector3(0,0,0) );
  249. const Vector4 Get_Vector4(char const *section, char const *entry, const Vector4 & defvalue = Vector4(0,0,0,0) ) const;
  250. };
  251. const Vector2 DazzleINIClass::Get_Vector2(char const *section, char const *entry, const Vector2 & defvalue)
  252. {
  253. if (section != NULL && entry != NULL) {
  254. INIEntry * entryptr = Find_Entry(section, entry);
  255. if (entryptr && entryptr->Value != NULL) {
  256. Vector2 ret;
  257. if ( sscanf( entryptr->Value, "%f,%f", &ret[0], &ret[1], &ret[2] ) == 2 ) {
  258. return ret;
  259. }
  260. }
  261. }
  262. return defvalue;
  263. }
  264. const Vector3 DazzleINIClass::Get_Vector3(char const *section, char const * entry, const Vector3 & defvalue )
  265. {
  266. if (section != NULL && entry != NULL) {
  267. INIEntry * entryptr = Find_Entry(section, entry);
  268. if (entryptr && entryptr->Value != NULL) {
  269. Vector3 ret;
  270. if ( sscanf( entryptr->Value, "%f,%f,%f", &ret[0], &ret[1], &ret[2] ) == 3 ) {
  271. return ret;
  272. }
  273. }
  274. }
  275. return defvalue;
  276. }
  277. const Vector4 DazzleINIClass::Get_Vector4(char const *section, char const *entry, const Vector4 & defvalue) const
  278. {
  279. if (section != NULL && entry != NULL) {
  280. INIEntry * entryptr = Find_Entry(section, entry);
  281. if (entryptr && entryptr->Value != NULL) {
  282. Vector4 ret;
  283. if ( sscanf( entryptr->Value, "%f,%f,%f,%f", &ret[0], &ret[1], &ret[2], &ret[3] ) == 4 ) {
  284. return ret;
  285. }
  286. }
  287. }
  288. return defvalue;
  289. }
  290. // ----------------------------------------------------------------------------
  291. LensflareTypeClass::LensflareTypeClass(const LensflareInitClass& is)
  292. :
  293. lic(is),
  294. texture(NULL)
  295. {
  296. }
  297. LensflareTypeClass::~LensflareTypeClass()
  298. {
  299. REF_PTR_RELEASE(texture);
  300. }
  301. TextureClass* LensflareTypeClass::Get_Texture()
  302. {
  303. if (!texture) {
  304. texture = WW3DAssetManager::Get_Instance()->Get_Texture(lic.texture_name);
  305. SET_REF_OWNER(texture);
  306. }
  307. return texture;
  308. }
  309. void LensflareTypeClass::Generate_Vertex_Buffers(
  310. VertexFormatXYZNDUV2* vertex,
  311. int& vertex_count,
  312. float screen_x_scale,
  313. float screen_y_scale,
  314. float dazzle_intensity,
  315. const Vector4& transformed_location)
  316. {
  317. // Lensflares are placed on a line 2D that goes through the lightsource and the center of the screen
  318. // float scale=sqrt(transformed_location[0]*transformed_location[0]+transformed_location[1]*transformed_location[1]);
  319. float z=transformed_location[2];
  320. float distance_multiplier=sqrt(transformed_location[0]*transformed_location[0]+transformed_location[1]*transformed_location[1])+1.0f;
  321. for (int a=0;a<lic.flare_count;++a) {
  322. float x=lic.flare_locations[a]*transformed_location[0];
  323. float y=lic.flare_locations[a]*transformed_location[1];
  324. float size=lic.flare_sizes[a]*distance_multiplier;
  325. float ix=size*screen_x_scale;
  326. float iy=size*screen_y_scale;
  327. Vector3 col=lic.flare_colors[a]*dazzle_intensity;
  328. if (col[0]>1.0f) col[0]=1.0f;
  329. if (col[1]>1.0f) col[1]=1.0f;
  330. if (col[2]>1.0f) col[2]=1.0f;
  331. unsigned color=DX8Wrapper::Convert_Color(col,1.0f);
  332. vertex->x=x+ix;
  333. vertex->y=y-iy;
  334. vertex->z=z;
  335. vertex->u1=lic.flare_uv[a][0];
  336. vertex->v1=lic.flare_uv[a][1];
  337. vertex->diffuse=color;
  338. vertex++;
  339. vertex->x=x+ix;
  340. vertex->y=y+iy;
  341. vertex->z=z;
  342. vertex->u1=lic.flare_uv[a][2];
  343. vertex->v1=lic.flare_uv[a][1];
  344. vertex->diffuse=color;
  345. vertex++;
  346. vertex->x=x-ix;
  347. vertex->y=y+iy;
  348. vertex->z=z;
  349. vertex->u1=lic.flare_uv[a][2];
  350. vertex->v1=lic.flare_uv[a][3];
  351. vertex->diffuse=color;
  352. vertex++;
  353. vertex->x=x-ix;
  354. vertex->y=y-iy;
  355. vertex->z=z;
  356. vertex->u1=lic.flare_uv[a][0];
  357. vertex->v1=lic.flare_uv[a][3];
  358. vertex->diffuse=color;
  359. vertex++;
  360. vertex_count+=4;
  361. }
  362. }
  363. // ----------------------------------------------------------------------------
  364. DazzleTypeClass::DazzleTypeClass(const DazzleInitClass& is)
  365. :
  366. ic(is),
  367. dazzle_shader(default_dazzle_shader),
  368. halo_shader(default_halo_shader),
  369. primary_texture(NULL),
  370. secondary_texture(NULL),
  371. lensflare_id(DazzleRenderObjClass::Get_Lensflare_ID(is.lensflare_name)),
  372. radius(is.radius)
  373. {
  374. fadeout_end_sqr=ic.fadeout_end*ic.fadeout_end;
  375. fadeout_start_sqr=ic.fadeout_start*ic.fadeout_start;
  376. dazzle_test_color_integer=
  377. 0xff000000|
  378. (unsigned(255.0f*ic.dazzle_test_color[2])<<16)|
  379. (unsigned(255.0f*ic.dazzle_test_color[1])<<8)|
  380. (unsigned(255.0f*ic.dazzle_test_color[0]));
  381. dazzle_test_mask_integer=dazzle_test_color_integer&0xf8f8f8f8;
  382. }
  383. DazzleTypeClass::~DazzleTypeClass()
  384. {
  385. REF_PTR_RELEASE(primary_texture);
  386. REF_PTR_RELEASE(secondary_texture);
  387. }
  388. // ----------------------------------------------------------------------------
  389. void DazzleTypeClass::Set_Dazzle_Shader(const ShaderClass& s) // Set shader for the dazzle type
  390. {
  391. dazzle_shader=s;
  392. }
  393. // ----------------------------------------------------------------------------
  394. void DazzleTypeClass::Set_Halo_Shader(const ShaderClass& s) // Set shader for the dazzle type
  395. {
  396. halo_shader=s;
  397. }
  398. // ----------------------------------------------------------------------------
  399. TextureClass* DazzleTypeClass::Get_Dazzle_Texture()
  400. {
  401. if (!primary_texture) {
  402. primary_texture = WW3DAssetManager::Get_Instance()->Get_Texture(ic.primary_texture_name);
  403. if ( primary_texture ) {
  404. SET_REF_OWNER(primary_texture);
  405. }
  406. }
  407. return primary_texture;
  408. }
  409. // ----------------------------------------------------------------------------
  410. TextureClass* DazzleTypeClass::Get_Halo_Texture()
  411. {
  412. if (!secondary_texture) {
  413. secondary_texture = WW3DAssetManager::Get_Instance()->Get_Texture(ic.secondary_texture_name);
  414. if ( secondary_texture ) {
  415. SET_REF_OWNER(secondary_texture);
  416. }
  417. }
  418. return secondary_texture;
  419. }
  420. // ----------------------------------------------------------------------------
  421. void DazzleTypeClass::Calculate_Intensities(
  422. float& dazzle_intensity,
  423. float& dazzle_size,
  424. float& halo_intensity,
  425. const Vector3& camera_dir,
  426. const Vector3& dazzle_dir,
  427. const Vector3& dir_to_dazzle,
  428. float distance) const
  429. {
  430. float dot = -Vector3::Dot_Product(dir_to_dazzle,camera_dir);
  431. dazzle_intensity = dot;
  432. if (ic.use_camera_translation && distance>(fadeout_end_sqr)) {
  433. dazzle_intensity=0.0f;
  434. return;
  435. }
  436. dazzle_intensity-=1.0f-ic.dazzle_area;
  437. dazzle_intensity/=ic.dazzle_area;
  438. dazzle_intensity=WWMath::Clamp(dazzle_intensity);
  439. if (ic.dazzle_direction_area>0.0f) {
  440. float angle=-Vector3::Dot_Product(camera_dir,dazzle_dir);
  441. angle-=1.0f-ic.dazzle_direction_area;
  442. angle/=ic.dazzle_direction_area;
  443. angle=WWMath::Clamp(angle);
  444. dazzle_intensity*=angle;
  445. }
  446. if (dazzle_intensity>0.0f) {
  447. dazzle_size=pow(dazzle_intensity,ic.dazzle_size_pow);
  448. dazzle_intensity=pow(dazzle_intensity,ic.dazzle_intensity_pow);
  449. }
  450. else {
  451. dazzle_intensity=0.0f;
  452. }
  453. if (ic.halo_intensity_pow > WWMATH_EPSILON) {
  454. if (dot > 0.0f) {
  455. float scale = powf(dot, ic.halo_intensity_pow);
  456. halo_intensity *= scale;
  457. } else {
  458. halo_intensity = 0.0f;
  459. }
  460. }
  461. dazzle_intensity*=ic.dazzle_intensity;
  462. halo_intensity*=ic.halo_intensity;
  463. // Flare fadeout distance - fade it out...
  464. if (ic.use_camera_translation) {
  465. if (distance>(fadeout_start_sqr)) {
  466. distance=sqrt(distance);
  467. distance-=ic.fadeout_start;
  468. distance/=ic.fadeout_end-ic.fadeout_start;
  469. dazzle_intensity*=1.0f-distance; // Scale down intensity
  470. halo_intensity*=1.0f-distance; // Scale down intensity
  471. }
  472. }
  473. return;
  474. }
  475. // ----------------------------------------------------------------------------
  476. void DazzleRenderObjClass::Init_From_INI(const INIClass* ini)
  477. {
  478. if (!ini) return;
  479. if (ini->Section_Count()==0) return;
  480. Init_Shaders();
  481. unsigned count=ini->Entry_Count( LENSFLARE_LIST_STRING );
  482. unsigned entry;
  483. for ( entry = 0; entry < count; entry++ ) {
  484. char section_name[80];
  485. ini->Get_String(
  486. LENSFLARE_LIST_STRING,
  487. ini->Get_Entry( LENSFLARE_LIST_STRING, entry),
  488. "",
  489. section_name,
  490. sizeof( section_name ));
  491. LensflareInitClass lic;
  492. ini->Get_String(lic.texture_name,section_name,LENSFLARE_TEXTURE_STRING);
  493. lic.flare_count=ini->Get_Int(section_name,FLARE_COUNT_STRING,0);
  494. if (lic.flare_count) {
  495. lic.flare_locations=W3DNEWARRAY float[lic.flare_count]; // Flare location is 1D
  496. lic.flare_sizes=W3DNEWARRAY float[lic.flare_count];
  497. lic.flare_colors=W3DNEWARRAY Vector3[lic.flare_count];
  498. lic.flare_uv=W3DNEWARRAY Vector4[lic.flare_count];
  499. }
  500. else {
  501. lic.flare_locations=NULL;
  502. lic.flare_sizes=NULL;
  503. lic.flare_colors=NULL;
  504. }
  505. for (int flare=0;flare<lic.flare_count;++flare) {
  506. // Flare location
  507. StringClass tmp_name(true);
  508. tmp_name.Format("%s%d",FLARE_LOCATION_STRING,flare+1);
  509. lic.flare_locations[flare]=ini->Get_Float(section_name,tmp_name,0.0f);
  510. // Flare size
  511. tmp_name.Format("%s%d",FLARE_SIZE_STRING,flare+1);
  512. lic.flare_sizes[flare]=ini->Get_Float(section_name,tmp_name,1.0f);
  513. // Flare color
  514. tmp_name.Format("%s%d",FLARE_COLOR_STRING,flare+1);
  515. TPoint3D<float> tp=ini->Get_Point(section_name,tmp_name,TPoint3D<float>(1.0f,1.0f,1.0f));
  516. lic.flare_colors[flare]=reinterpret_cast<const Vector3&>(tp);
  517. // Flare uv
  518. const DazzleINIClass* dini=reinterpret_cast<const DazzleINIClass*>(ini);
  519. tmp_name.Format("%s%d",FLARE_UV_STRING,flare+1);
  520. lic.flare_uv[flare]=dini->Get_Vector4(section_name,tmp_name,Vector4(0.0f,0.0f,1.0f,1.0f));
  521. }
  522. lic.type=entry;
  523. Init_Lensflare(lic);
  524. lensflares[entry]->name=section_name;
  525. }
  526. count=ini->Entry_Count( DAZZLE_LIST_STRING );
  527. for ( entry = 0; entry < count; entry++ ) {
  528. char section_name[80];
  529. ini->Get_String(
  530. DAZZLE_LIST_STRING,
  531. ini->Get_Entry( DAZZLE_LIST_STRING, entry),
  532. "",
  533. section_name,
  534. sizeof( section_name ));
  535. DazzleInitClass dic;
  536. ini->Get_String(dic.primary_texture_name,section_name,DAZZLE_TEXTURE_STRING);
  537. ini->Get_String(dic.secondary_texture_name,section_name,HALO_TEXTURE_STRING);
  538. dic.halo_intensity=ini->Get_Float(section_name,HALO_INTENSITY_STRING,0.95f);
  539. dic.halo_intensity_pow=ini->Get_Float(section_name,HALO_INTENSITY_POW, 0.0f);
  540. dic.halo_scale_x=ini->Get_Float(section_name,HALO_SCALE_X_STRING,2.0f);
  541. dic.halo_scale_y=ini->Get_Float(section_name,HALO_SCALE_Y_STRING,2.0f);
  542. dic.dazzle_area=ini->Get_Float(section_name,DAZZLE_AREA_STRING,0.05f);
  543. dic.dazzle_direction_area=ini->Get_Float(section_name,DAZZLE_DIRECTION_AREA_STRING,0.50f);
  544. dic.dazzle_intensity=ini->Get_Float(section_name,DAZZLE_INTENSITY_STRING,0.90f);
  545. dic.dazzle_intensity_pow=ini->Get_Float(section_name,DAZZLE_INTENSITY_POW_STRING,0.90f);
  546. dic.dazzle_size_pow=ini->Get_Float(section_name,DAZZLE_SIZE_POW_STRING,0.90f);
  547. dic.dazzle_scale_x=ini->Get_Float(section_name,DAZZLE_SCALE_X_STRING,100.0f);
  548. dic.dazzle_scale_y=ini->Get_Float(section_name,DAZZLE_SCALE_Y_STRING,25.0f);
  549. dic.fadeout_start=ini->Get_Float(section_name,FADEOUT_START_STRING,25.0f);
  550. dic.fadeout_end=ini->Get_Float(section_name,FADEOUT_END_STRING,50.0f);
  551. dic.size_optimization_limit=ini->Get_Float(section_name,SIZE_OPTIMIZATION_LIMIT_STRING,0.05f);
  552. dic.history_weight=ini->Get_Float(section_name,HISTORY_WEIGHT_STRING,0.5f);
  553. dic.use_camera_translation=!!ini->Get_Int(section_name,USE_CAMERA_TRANSLATION,1);
  554. ini->Get_String(dic.lensflare_name,section_name,DAZZLE_LENSFLARE_STRING);
  555. dic.type=entry;
  556. TPoint3D<float> tp=ini->Get_Point(section_name,DAZZLE_DIRECTION_STRING,TPoint3D<float>(0.0f,0.0f,0.0f));
  557. tp.Normalize();
  558. dic.dazzle_direction=reinterpret_cast<const Vector3&>(tp);
  559. tp=ini->Get_Point(section_name,DAZZLE_TEST_COLOR_STRING,TPoint3D<float>(1.0f,1.0f,1.0f));
  560. dic.dazzle_test_color=reinterpret_cast<const Vector3&>(tp);
  561. tp=ini->Get_Point(section_name,DAZZLE_COLOR_STRING,TPoint3D<float>(1.0f,1.0f,1.0f));
  562. dic.dazzle_color=reinterpret_cast<const Vector3&>(tp);
  563. tp=ini->Get_Point(section_name,HALO_COLOR_STRING,TPoint3D<float>(1.0f,1.0f,1.0f));
  564. dic.halo_color=reinterpret_cast<const Vector3&>(tp);
  565. dic.radius=ini->Get_Float(section_name,RADIUS_STRING,1.0f);
  566. dic.blink_period=ini->Get_Float(section_name,BLINK_PERIOD_STRING,0.0f);
  567. dic.blink_on_time=ini->Get_Float(section_name,BLINK_ON_TIME_STRING,0.0f);
  568. Init_Type(dic);
  569. types[entry]->name=section_name;
  570. }
  571. }
  572. // ----------------------------------------------------------------------------
  573. void DazzleRenderObjClass::Init_Type(const DazzleInitClass& i)
  574. {
  575. Init_Shaders();
  576. if (i.type>=type_count) {
  577. unsigned new_count=i.type+1;
  578. DazzleTypeClass** new_types=W3DNEWARRAY DazzleTypeClass*[new_count];
  579. for (unsigned a=0;a<type_count;++a) {
  580. new_types[a]=types[a];
  581. }
  582. for (;a<new_count;++a) {
  583. new_types[a]=0;
  584. }
  585. delete[] types;
  586. types=new_types;
  587. type_count=new_count;
  588. }
  589. delete types[i.type];
  590. types[i.type]=W3DNEW DazzleTypeClass(i);
  591. }
  592. // ----------------------------------------------------------------------------
  593. void DazzleRenderObjClass::Init_Lensflare(const LensflareInitClass& i)
  594. {
  595. Init_Shaders();
  596. if (i.type>=lensflare_count) {
  597. unsigned new_count=i.type+1;
  598. LensflareTypeClass** new_lensflares=W3DNEWARRAY LensflareTypeClass*[new_count];
  599. for (unsigned a=0;a<lensflare_count;++a) {
  600. new_lensflares[a]=lensflares[a];
  601. }
  602. for (;a<new_count;++a) {
  603. new_lensflares[a]=0;
  604. }
  605. delete[] lensflares;
  606. lensflares=new_lensflares;
  607. lensflare_count=new_count;
  608. }
  609. delete lensflares[i.type];
  610. lensflares[i.type]=W3DNEW LensflareTypeClass(i);
  611. }
  612. // ----------------------------------------------------------------------------
  613. void DazzleRenderObjClass::Deinit()
  614. {
  615. // Deinit dazzle types
  616. if (types) {
  617. for (unsigned a=0;a<type_count;++a) {
  618. delete types[a];
  619. }
  620. delete[] types;
  621. }
  622. types=NULL;
  623. type_count=0;
  624. // Deinit lensflare types
  625. if (lensflares) {
  626. for (unsigned a=0;a<lensflare_count;++a) {
  627. delete lensflares[a];
  628. }
  629. delete[] lensflares;
  630. }
  631. lensflares=NULL;
  632. lensflare_count=0;
  633. }
  634. void DazzleRenderObjClass::Install_Dazzle_Visibility_Handler(const DazzleVisibilityClass * visibility_handler)
  635. {
  636. if (visibility_handler == NULL) {
  637. _VisibilityHandler = &_DefaultVisibilityHandler;
  638. } else {
  639. _VisibilityHandler = visibility_handler;
  640. }
  641. }
  642. // ----------------------------------------------------------------------------
  643. //
  644. // The parameter t defines the dazzle type. t has to be a valid type id in order
  645. // for the dazzle to work.
  646. //
  647. // ----------------------------------------------------------------------------
  648. DazzleRenderObjClass::DazzleRenderObjClass(unsigned t)
  649. :
  650. succ(NULL),
  651. type(t),
  652. current_dazzle_intensity(0.0f),
  653. current_dazzle_size(0.0f),
  654. dazzle_color(1.0f,1.0f,1.0f),
  655. halo_color(1.0f,1.0f,1.0f),
  656. lensflare_intensity(1.0f),
  657. on_list(false),
  658. visibility(0.0f),
  659. current_scale(1.0f)
  660. {
  661. if (types && types[t]) {
  662. radius = types[t]->radius;
  663. } else {
  664. radius = 0.0f;
  665. }
  666. creation_time = WW3D::Get_Sync_Time();
  667. }
  668. // ----------------------------------------------------------------------------
  669. //
  670. // Creating a dazzle with its type name is a bit slower (due to scanning) but
  671. // works equally to the creation with id.
  672. //
  673. // ----------------------------------------------------------------------------
  674. DazzleRenderObjClass::DazzleRenderObjClass(const char * type_name)
  675. :
  676. succ(NULL),
  677. type(Get_Type_ID(type_name)),
  678. current_dazzle_intensity(0.0f),
  679. current_dazzle_size(0.0f),
  680. dazzle_color(1.0f,1.0f,1.0f),
  681. halo_color(1.0f,1.0f,1.0f),
  682. lensflare_intensity(1.0f),
  683. on_list(false),
  684. visibility(0.0f),
  685. current_scale(1.0f)
  686. {
  687. int id = Get_Type_ID(type_name);
  688. if (types && types[id]) {
  689. radius = types[id]->radius;
  690. } else {
  691. radius = 0.0f;
  692. }
  693. creation_time = WW3D::Get_Sync_Time();
  694. }
  695. // ----------------------------------------------------------------------------
  696. //
  697. // Copy constructor creates an exact copy of the object, except for the visibility
  698. // information, which is initialised with default values.
  699. //
  700. // ----------------------------------------------------------------------------
  701. DazzleRenderObjClass::DazzleRenderObjClass(const DazzleRenderObjClass & src)
  702. :
  703. succ(NULL),
  704. type(src.type),
  705. current_dazzle_intensity(src.current_dazzle_intensity),
  706. current_dazzle_size(src.current_dazzle_size),
  707. current_dir(src.current_dir),
  708. dazzle_color(src.dazzle_color),
  709. halo_color(src.halo_color),
  710. lensflare_intensity(src.lensflare_intensity),
  711. on_list(false),
  712. visibility(src.visibility),
  713. radius(src.radius),
  714. current_scale(src.current_scale)
  715. {
  716. creation_time = WW3D::Get_Sync_Time();
  717. }
  718. DazzleRenderObjClass& DazzleRenderObjClass::operator = (const DazzleRenderObjClass & src)
  719. {
  720. type=src.type;
  721. current_dir=src.current_dir;
  722. current_dazzle_intensity=src.current_dazzle_intensity;
  723. current_dazzle_size=src.current_dazzle_size;
  724. dazzle_color=src.dazzle_color;
  725. halo_color=src.halo_color;
  726. lensflare_intensity=src.lensflare_intensity;
  727. visibility=src.visibility;
  728. radius=src.radius;
  729. creation_time = WW3D::Get_Sync_Time();
  730. current_scale = src.current_scale;
  731. return *this;
  732. }
  733. void DazzleRenderObjClass::Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const
  734. {
  735. sphere.Center.Set(0,0,0);
  736. sphere.Radius = radius * current_scale;
  737. }
  738. void DazzleRenderObjClass::Get_Obj_Space_Bounding_Box(AABoxClass & box) const
  739. {
  740. box.Center.Set(0,0,0);
  741. box.Extent.Set(radius,radius,radius);
  742. box.Extent *= current_scale;
  743. }
  744. void DazzleRenderObjClass::Set_Layer(DazzleLayerClass *layer)
  745. {
  746. // Never insert a dazzle into a list if it already is on one - this caould create infinite
  747. // loops in the dazzle list.
  748. if (on_list) return;
  749. // This function sets the dazzle to be visible in the given layer.
  750. if (!layer) {
  751. WWASSERT(0);
  752. return;
  753. }
  754. if (type>=type_count) return; // If the type doesn't exist the visibility can't be changed
  755. // Insert at the head of the layer's visible list
  756. succ = layer->visible_lists[type];
  757. layer->visible_lists[type] = this;
  758. on_list = true;
  759. Add_Ref();
  760. }
  761. void DazzleRenderObjClass::Set_Current_Dazzle_Layer(DazzleLayerClass *layer)
  762. {
  763. current_dazzle_layer = layer;
  764. }
  765. /////////////////////////////////////////////////////////////////////////////
  766. // Render Object Interface
  767. /////////////////////////////////////////////////////////////////////////////
  768. RenderObjClass* DazzleRenderObjClass::Clone(void) const
  769. {
  770. return NEW_REF(DazzleRenderObjClass, (*this));
  771. }
  772. // ----------------------------------------------------------------------------
  773. //
  774. // DazzleRenderObjClass's Render() function doesn't actually render the dazzle
  775. // immediatelly but just sets the dazzle visible. This is due to the way the
  776. // dazzle system works (the dazzles need to be rendered after everything else).
  777. // Having the Render() function flag the visibility offers us the visibility
  778. // functionality of the scene graph.
  779. //
  780. // ----------------------------------------------------------------------------
  781. void DazzleRenderObjClass::Render(RenderInfoClass & rinfo)
  782. {
  783. WWPROFILE("Dazzle::Render");
  784. if ( Is_Not_Hidden_At_All() &&
  785. _dazzle_rendering_enabled &&
  786. !DX8Wrapper::Is_Render_To_Texture() )
  787. {
  788. // First check if the dazzle is blinking and is "off"
  789. bool is_on = true;
  790. DazzleInitClass & ic = types[type]->ic;
  791. if (ic.blink_period > 0.0f) {
  792. float elapsed_time = ((float)(WW3D::Get_Sync_Time() - creation_time)) / 1000.0f;
  793. float wrapped_time = fmodf(elapsed_time,ic.blink_period);
  794. if (wrapped_time > ic.blink_on_time) {
  795. is_on = false;
  796. }
  797. }
  798. // Next, check visibility
  799. visibility = 1.0f;
  800. if (is_on == false) {
  801. visibility = 0.0f;
  802. } else {
  803. // Vector3 position;
  804. // Get_Transform().Get_Translation(&position);
  805. // visibility = _VisibilityHandler->Compute_Dazzle_Visibility(rinfo,this,position);
  806. Matrix4x4 view_transform,projection_transform;
  807. DX8Wrapper::Get_Transform(D3DTS_VIEW,view_transform);
  808. DX8Wrapper::Get_Transform(D3DTS_PROJECTION,projection_transform);
  809. Vector3 camera_loc(rinfo.Camera.Get_Position());
  810. Vector3 camera_dir(-view_transform[2][0],-view_transform[2][1],-view_transform[2][2]);
  811. // Matrix3D cam(rinfo.Camera.Get_Transform());
  812. // Vector3 camera_dir(-cam[2][0],-cam[2][1],-cam[2][2]);
  813. // camera_dir.Normalize();
  814. Vector3 loc=Get_Position();
  815. transformed_loc=view_transform*loc;
  816. transformed_loc=projection_transform*transformed_loc;
  817. transformed_loc[0]/=transformed_loc[3];
  818. transformed_loc[1]/=transformed_loc[3];
  819. transformed_loc[2]/=transformed_loc[3];
  820. transformed_loc[3]=1.0f;
  821. current_vloc=Vector3(transformed_loc[0],transformed_loc[1],transformed_loc[2]);
  822. float dazzle_intensity=1.0f;
  823. Vector3 dir;
  824. dir=camera_loc-loc;
  825. current_distance=dir.Length2();
  826. dir.Normalize();
  827. float dazzle_size;
  828. current_halo_intensity=1.0f;
  829. const DazzleTypeClass* params=types[type];
  830. params->Calculate_Intensities(dazzle_intensity,dazzle_size,current_halo_intensity,camera_dir,current_dir,dir,current_distance);
  831. unsigned time_ms=WW3D::Get_Frame_Time();
  832. if (time_ms==0) time_ms=1;
  833. float weight=pow(params->ic.history_weight,time_ms);
  834. if (dazzle_intensity>0.0f) {
  835. visibility = _VisibilityHandler->Compute_Dazzle_Visibility(rinfo,this,loc);
  836. //visibility=1.0f;
  837. dazzle_intensity*=visibility;
  838. }
  839. else {
  840. visibility=0.0f;
  841. }
  842. if (visibility == 0.0f) {
  843. float i=dazzle_intensity*(1.0f-weight)+current_dazzle_intensity*weight;
  844. current_dazzle_intensity=i;
  845. if (current_dazzle_intensity<0.05f) current_dazzle_intensity=0.0f;
  846. dazzle_intensity=i;
  847. float s=dazzle_size*(1.0f-weight)+current_dazzle_size*weight;
  848. current_dazzle_size=s;
  849. dazzle_size=s;
  850. } else {
  851. current_dazzle_intensity = dazzle_intensity;
  852. current_dazzle_size = dazzle_size;
  853. }
  854. }
  855. // If this dazzle is visible or it is currently fading, submit it for rendering
  856. if (/*visibility > 0.0f ||*/ current_dazzle_intensity>0.0f || current_halo_intensity>0.0f) {
  857. WWASSERT(types[type]);
  858. Set_Layer(current_dazzle_layer);
  859. }
  860. }
  861. else {
  862. visibility=0.0f;
  863. }
  864. }
  865. void DazzleRenderObjClass::Render_Dazzle(CameraClass* camera)
  866. {
  867. WWPROFILE("Dazzle::Render");
  868. Matrix4x4 old_view_transform;
  869. Matrix4x4 old_world_transform;
  870. Matrix4x4 old_projection_transform;
  871. Matrix4x4 view_transform;
  872. Matrix4x4 world_transform;
  873. Matrix4x4 projection_transform;
  874. DX8Wrapper::Get_Transform(D3DTS_VIEW,view_transform);
  875. DX8Wrapper::Get_Transform(D3DTS_WORLD,world_transform);
  876. DX8Wrapper::Get_Transform(D3DTS_PROJECTION,projection_transform);
  877. old_view_transform=view_transform;
  878. old_world_transform=world_transform;
  879. old_projection_transform=projection_transform;
  880. Vector3 camera_loc(camera->Get_Position());
  881. Vector3 camera_dir(-view_transform[2][0],-view_transform[2][1],-view_transform[2][2]);
  882. int display_width,display_height,display_bits;
  883. bool windowed;
  884. WW3D::Get_Device_Resolution(display_width,display_height,display_bits,windowed);
  885. float w=float(display_width);
  886. float h=float(display_height);
  887. float screen_x_scale=1.0f;
  888. float screen_y_scale=1.0f;
  889. if (w>h) {
  890. screen_y_scale=w/h;
  891. }
  892. else {
  893. screen_x_scale=h/w;
  894. }
  895. // unsigned time_ms=WW3D::Get_Frame_Time();
  896. // if (time_ms==0) time_ms=1;
  897. // Do NOT scale halo by current scale
  898. // because it uses screen parallel primitives
  899. // and if it's too big it will be visible until
  900. // it collides with the near clip plane and then pop and vanish
  901. float halo_scale_x=types[type]->ic.halo_scale_x;
  902. float halo_scale_y=types[type]->ic.halo_scale_y;
  903. float dazzle_scale_x=types[type]->ic.dazzle_scale_x * current_scale;
  904. float dazzle_scale_y=types[type]->ic.dazzle_scale_y * current_scale;
  905. // Allocate some arrays for the dazzle rendering
  906. int vertex_count=4;
  907. const DazzleTypeClass* params=types[type];
  908. int halo_vertex_count=0;
  909. int dazzle_vertex_count=0;
  910. int lensflare_vertex_count=0;
  911. Vector3 dl;
  912. int lens_max_verts=0;
  913. LensflareTypeClass* lensflare = DazzleRenderObjClass::Get_Lensflare_Class(types[type]->lensflare_id);
  914. if (lensflare) {
  915. lens_max_verts=4*lensflare->lic.flare_count;
  916. }
  917. DynamicVBAccessClass vb_access(BUFFER_TYPE_DYNAMIC_DX8,dynamic_fvf_type,vertex_count*2+lens_max_verts);
  918. {
  919. DynamicVBAccessClass::WriteLockClass lock(&vb_access);
  920. VertexFormatXYZNDUV2* verts=lock.Get_Formatted_Vertex_Array();
  921. float halo_size=1.0f;
  922. Vector3 dazzle_dxt(screen_x_scale,0.0f,0.0f);
  923. Vector3 halo_dxt=dazzle_dxt*halo_scale_x;
  924. dazzle_dxt*=dazzle_scale_x;
  925. Vector3 dazzle_dyt(0.0f,screen_y_scale,0.0f);
  926. Vector3 halo_dyt=dazzle_dyt*halo_scale_y;
  927. dazzle_dyt*=dazzle_scale_y;
  928. if (current_dazzle_intensity>0.0f) {
  929. VertexFormatXYZNDUV2* vertex=verts;
  930. dazzle_vertex_count+=4;
  931. Vector3 col(
  932. dazzle_color[0]*params->ic.dazzle_color[0],
  933. dazzle_color[1]*params->ic.dazzle_color[1],
  934. dazzle_color[2]*params->ic.dazzle_color[2]);
  935. col*=current_dazzle_intensity;
  936. if (col[0]>1.0f) col[0]=1.0f;
  937. if (col[1]>1.0f) col[1]=1.0f;
  938. if (col[2]>1.0f) col[2]=1.0f;
  939. unsigned color=DX8Wrapper::Convert_Color(col,1.0f);
  940. dl=current_vloc+(dazzle_dxt-dazzle_dyt)*current_dazzle_size;
  941. reinterpret_cast<Vector3&>(vertex->x)=dl;
  942. vertex->u1=0.0f;
  943. vertex->v1=0.0f;
  944. vertex->diffuse=color;
  945. vertex++;
  946. dl=current_vloc+(dazzle_dxt+dazzle_dyt)*current_dazzle_size;
  947. reinterpret_cast<Vector3&>(vertex->x)=dl;
  948. vertex->u1=1.0f;
  949. vertex->v1=0.0f;
  950. vertex->diffuse=color;
  951. vertex++;
  952. dl=current_vloc-(dazzle_dxt-dazzle_dyt)*current_dazzle_size;
  953. reinterpret_cast<Vector3&>(vertex->x)=dl;
  954. vertex->u1=1.0f;
  955. vertex->v1=1.0f;
  956. vertex->diffuse=color;
  957. vertex++;
  958. dl=current_vloc-(dazzle_dxt+dazzle_dyt)*current_dazzle_size;
  959. reinterpret_cast<Vector3&>(vertex->x)=dl;
  960. vertex->u1=0.0f;
  961. vertex->v1=1.0f;
  962. vertex->diffuse=color;
  963. }
  964. if (current_halo_intensity) {
  965. VertexFormatXYZNDUV2* vertex=verts+dazzle_vertex_count;
  966. halo_vertex_count+=4;
  967. Vector3 col(
  968. halo_color[0]*params->ic.halo_color[0],
  969. halo_color[1]*params->ic.halo_color[1],
  970. halo_color[2]*params->ic.halo_color[2]);
  971. col*=current_halo_intensity;
  972. if (col[0]>1.0f) col[0]=1.0f;
  973. if (col[1]>1.0f) col[1]=1.0f;
  974. if (col[2]>1.0f) col[2]=1.0f;
  975. unsigned color=DX8Wrapper::Convert_Color(col,1.0f);
  976. Vector3 offset;
  977. offset = (halo_dxt - halo_dyt) * halo_size;
  978. dl = current_vloc + offset;
  979. reinterpret_cast<Vector3&>(vertex->x)=dl;
  980. vertex->u1=0.0f;
  981. vertex->v1=0.0f;
  982. vertex->diffuse=color;
  983. vertex++;
  984. offset = (halo_dxt + halo_dyt) * halo_size;
  985. dl =current_vloc + offset;
  986. reinterpret_cast<Vector3&>(vertex->x)=dl;
  987. vertex->u1=1.0f;
  988. vertex->v1=0.0f;
  989. vertex->diffuse=color;
  990. vertex++;
  991. offset = -(halo_dxt - halo_dyt) * halo_size;
  992. dl = current_vloc + offset;
  993. reinterpret_cast<Vector3&>(vertex->x)=dl;
  994. vertex->u1=1.0f;
  995. vertex->v1=1.0f;
  996. vertex->diffuse=color;
  997. vertex++;
  998. offset = -(halo_dxt + halo_dyt) * halo_size;
  999. dl=current_vloc + offset;
  1000. reinterpret_cast<Vector3&>(vertex->x)=dl;
  1001. vertex->u1=0.0f;
  1002. vertex->v1=1.0f;
  1003. vertex->diffuse=color;
  1004. }
  1005. if (lensflare && current_dazzle_intensity>0.0f) {
  1006. VertexFormatXYZNDUV2* vertex=verts+halo_vertex_count+dazzle_vertex_count;
  1007. lensflare->Generate_Vertex_Buffers(
  1008. vertex,
  1009. lensflare_vertex_count,
  1010. screen_x_scale,
  1011. screen_y_scale,
  1012. current_dazzle_intensity * lensflare_intensity,
  1013. transformed_loc);
  1014. vertex_count+=lensflare_vertex_count;
  1015. }
  1016. }
  1017. int dazzle_poly_count=dazzle_vertex_count>>1;
  1018. int halo_poly_count=halo_vertex_count>>1;
  1019. int lensflare_poly_count=lensflare_vertex_count>>1;
  1020. int poly_count=halo_poly_count>dazzle_poly_count ? halo_poly_count : dazzle_poly_count;
  1021. if (lensflare_poly_count>poly_count) poly_count=lensflare_poly_count;
  1022. if (!poly_count) {
  1023. return;
  1024. }
  1025. DX8Wrapper::Set_Vertex_Buffer(vb_access);
  1026. DynamicIBAccessClass ib_access(BUFFER_TYPE_DYNAMIC_DX8,poly_count*3);
  1027. {
  1028. DynamicIBAccessClass::WriteLockClass lock(&ib_access);
  1029. unsigned short* inds=lock.Get_Index_Array();
  1030. // Proceed two polygons at a time
  1031. for (int a=0;a<poly_count/2;a++) {
  1032. *inds++=short(4*a);
  1033. *inds++=short(4*a+1);
  1034. *inds++=short(4*a+2);
  1035. *inds++=short(4*a);
  1036. *inds++=short(4*a+2);
  1037. *inds++=short(4*a+3);
  1038. }
  1039. }
  1040. DX8Wrapper::Set_World_Identity();
  1041. DX8Wrapper::Set_View_Identity();
  1042. DX8Wrapper::Set_Transform(D3DTS_PROJECTION,Matrix4x4(true));
  1043. if (halo_poly_count) {
  1044. DX8Wrapper::Set_Index_Buffer(ib_access,dazzle_vertex_count);
  1045. DX8Wrapper::Set_Shader(default_halo_shader);
  1046. DX8Wrapper::Set_Texture(0,types[type]->Get_Halo_Texture());
  1047. SphereClass sphere(Get_Position(),0.1f);
  1048. DX8Wrapper::Draw_Triangles(0,halo_poly_count,0,vertex_count);
  1049. }
  1050. if (dazzle_poly_count) {
  1051. DX8Wrapper::Set_Index_Buffer(ib_access,0);
  1052. DX8Wrapper::Set_Shader(default_dazzle_shader);
  1053. DX8Wrapper::Set_Texture(0,types[type]->Get_Dazzle_Texture());
  1054. SphereClass sphere(Vector3(0.0f,0.0f,0.0f),0.0f);
  1055. DX8Wrapper::Draw_Triangles(0,dazzle_poly_count,0,vertex_count);
  1056. }
  1057. if (lensflare_poly_count) {
  1058. DX8Wrapper::Set_Index_Buffer(ib_access,dazzle_vertex_count+halo_vertex_count);
  1059. DX8Wrapper::Set_Shader(default_dazzle_shader);
  1060. DX8Wrapper::Set_Texture(0,lensflare->Get_Texture());
  1061. SphereClass sphere(Vector3(0.0f,0.0f,0.0f),0.0f);
  1062. DX8Wrapper::Draw_Triangles(0,lensflare_poly_count,0,vertex_count);
  1063. }
  1064. DX8Wrapper::Set_Transform(D3DTS_PROJECTION,old_projection_transform);
  1065. DX8Wrapper::Set_Transform(D3DTS_VIEW,old_view_transform);
  1066. DX8Wrapper::Set_Transform(D3DTS_WORLD,old_world_transform);
  1067. }
  1068. // ----------------------------------------------------------------------------
  1069. void DazzleRenderObjClass::Set_Transform(const Matrix3D &m)
  1070. {
  1071. RenderObjClass::Set_Transform(m);
  1072. if (type<type_count) {
  1073. Matrix3D::Rotate_Vector(m,types[type]->ic.dazzle_direction,&current_dir);
  1074. }
  1075. }
  1076. // ----------------------------------------------------------------------------
  1077. //
  1078. // Return the type id of a dazzle class with given name. If such type is not
  1079. // found, return UINT_MAX.
  1080. //
  1081. // ----------------------------------------------------------------------------
  1082. unsigned DazzleRenderObjClass::Get_Type_ID(const char* name)
  1083. {
  1084. for (unsigned a=0;a<type_count;++a) {
  1085. if (types[a] && types[a]->name==name) return a;
  1086. }
  1087. return UINT_MAX;
  1088. }
  1089. // ----------------------------------------------------------------------------
  1090. //
  1091. // Return the type name of a dazzle class with given id. If the id is out
  1092. // of range, return "DEFAULT" which by convention is always defined and is
  1093. // id 0.
  1094. //
  1095. // ----------------------------------------------------------------------------
  1096. const char * DazzleRenderObjClass::Get_Type_Name(unsigned id)
  1097. {
  1098. if ((id < type_count) && (id >= 0)) {
  1099. return types[id]->name;
  1100. } else {
  1101. return "DEFAULT";
  1102. }
  1103. }
  1104. // ----------------------------------------------------------------------------
  1105. //
  1106. // Return pointer to DazzleTypeClass object with given id. If the id is out
  1107. // of range (usually UINT_MAX, in can the id was obtained with invalid name
  1108. // string) return NULL.
  1109. //
  1110. // ----------------------------------------------------------------------------
  1111. DazzleTypeClass* DazzleRenderObjClass::Get_Type_Class(unsigned id) // Return dazzle type class pointer, or NULL if not found
  1112. {
  1113. if (id>=type_count) return NULL;
  1114. return types[id];
  1115. }
  1116. // ----------------------------------------------------------------------------
  1117. //
  1118. // Return the type id of a lensflare type class with given name. If such type is
  1119. // not found, return UINT_MAX.
  1120. //
  1121. // ----------------------------------------------------------------------------
  1122. unsigned DazzleRenderObjClass::Get_Lensflare_ID(const char* name)
  1123. {
  1124. for (unsigned a=0;a<lensflare_count;++a) {
  1125. if (lensflares[a] && lensflares[a]->name==name) return a;
  1126. }
  1127. return UINT_MAX;
  1128. }
  1129. // ----------------------------------------------------------------------------
  1130. //
  1131. // Return pointer to LensflareTypeClass object with given id. If the id is out
  1132. // of range (usually UINT_MAX, in can the id was obtained with invalid name
  1133. // string) return NULL.
  1134. //
  1135. // ----------------------------------------------------------------------------
  1136. LensflareTypeClass* DazzleRenderObjClass::Get_Lensflare_Class(unsigned id) // Return lensflare type class pointer, or NULL if not found
  1137. {
  1138. if (id>=lensflare_count) return NULL;
  1139. return lensflares[id];
  1140. }
  1141. // ----------------------------------------------------------------------------
  1142. //
  1143. // Should static dazzles require vis information, here's a function that renders
  1144. // a quad at the location of the dazzle
  1145. //
  1146. // ----------------------------------------------------------------------------
  1147. void DazzleRenderObjClass::vis_render_dazzle(SpecialRenderInfoClass & rinfo)
  1148. {
  1149. WWASSERT(rinfo.VisRasterizer != NULL);
  1150. rinfo.VisRasterizer->Enable_Two_Sided_Rendering(true);
  1151. /*
  1152. ** Create a transform which is facing the camera
  1153. */
  1154. Vector3 cam_point = rinfo.VisRasterizer->Peek_Camera()->Get_Transform().Get_Translation();
  1155. Vector3 daz_point = Get_Transform().Get_Translation();
  1156. Matrix3D tm;
  1157. tm.Look_At(daz_point,cam_point,0.0f);
  1158. rinfo.VisRasterizer->Set_Model_Transform(tm);
  1159. /*
  1160. ** Now, generate a single triangle on the X-Y plane
  1161. */
  1162. Vector3 verts[4];
  1163. TriIndex polys[2];
  1164. polys[0] = TriIndex(0,1,2);
  1165. polys[1] = TriIndex(0,2,3);
  1166. Vector2 view_min,view_max;
  1167. rinfo.VisRasterizer->Peek_Camera()->Get_View_Plane(view_min,view_max);
  1168. float scale_x=types[type]->ic.halo_scale_x;
  1169. if ((scale_x < 0.001f) && (types[type]->ic.dazzle_scale_x > scale_x)) {
  1170. scale_x = types[type]->ic.dazzle_scale_x;
  1171. }
  1172. float scale_y=types[type]->ic.halo_scale_y;
  1173. if ((scale_y < 0.001f) && (types[type]->ic.dazzle_scale_y > scale_y)) {
  1174. scale_y = types[type]->ic.dazzle_scale_y;
  1175. }
  1176. float dist = (daz_point - cam_point).Length();
  1177. Vector3 dxt(dist * scale_x / (view_max.X - view_min.X),0.0f,0.0f);
  1178. Vector3 dyt(0.0f,dist * scale_y / (view_max.Y - view_min.Y),0.0f);
  1179. verts[0].Set(dxt+dyt);
  1180. verts[1].Set(dxt-dyt);
  1181. verts[2].Set(-dxt-dyt);
  1182. verts[3].Set(-dxt+dyt);
  1183. AABoxClass bounds;
  1184. float extent = 1.1f * (dxt+dyt).Length();
  1185. bounds.Center = daz_point; //making up a conservative bounding box
  1186. bounds.Extent.Set(extent,extent,extent);
  1187. /*
  1188. ** Render
  1189. */
  1190. rinfo.VisRasterizer->Enable_Two_Sided_Rendering(true);
  1191. rinfo.VisRasterizer->Render_Triangles(verts,4,polys,2,bounds);
  1192. rinfo.VisRasterizer->Enable_Two_Sided_Rendering(false);
  1193. }
  1194. void DazzleRenderObjClass::Special_Render(SpecialRenderInfoClass & rinfo)
  1195. {
  1196. if (rinfo.RenderType == SpecialRenderInfoClass::RENDER_VIS) {
  1197. vis_render_dazzle(rinfo);
  1198. }
  1199. }
  1200. /****************************************************************************************
  1201. DazzleRenderObjClass - Persistant object support.
  1202. Dazzles are going to save their type and their transform and simply
  1203. re-create another dazzle of the same type when loaded.
  1204. ****************************************************************************************/
  1205. class DazzlePersistFactoryClass : public PersistFactoryClass
  1206. {
  1207. virtual uint32 Chunk_ID(void) const;
  1208. virtual PersistClass * Load(ChunkLoadClass & cload) const;
  1209. virtual void Save(ChunkSaveClass & csave,PersistClass * obj) const;
  1210. enum
  1211. {
  1212. DAZZLEFACTORY_CHUNKID_VARIABLES = 1212000336,
  1213. DAZZLEFACTORY_VARIABLE_OBJPOINTER = 0x00,
  1214. OBSOLETE_DAZZLEFACTORY_VARIABLE_TYPE,
  1215. DAZZLEFACTORY_VARIABLE_TRANSFORM,
  1216. DAZZLEFACTORY_VARIABLE_TYPENAME,
  1217. };
  1218. };
  1219. static DazzlePersistFactoryClass _DazzleFactory;
  1220. uint32 DazzlePersistFactoryClass::Chunk_ID(void) const
  1221. {
  1222. return WW3D_PERSIST_CHUNKID_DAZZLE;
  1223. }
  1224. PersistClass * DazzlePersistFactoryClass::Load(ChunkLoadClass & cload) const
  1225. {
  1226. DazzleRenderObjClass * old_obj = NULL;
  1227. Matrix3D tm(1);
  1228. char dazzle_type[256];
  1229. dazzle_type[0] = 0;
  1230. /*
  1231. ** Load the dazzle parameters
  1232. */
  1233. while (cload.Open_Chunk()) {
  1234. switch (cload.Cur_Chunk_ID()) {
  1235. case DAZZLEFACTORY_CHUNKID_VARIABLES:
  1236. while (cload.Open_Micro_Chunk()) {
  1237. switch(cload.Cur_Micro_Chunk_ID()) {
  1238. READ_MICRO_CHUNK(cload,DAZZLEFACTORY_VARIABLE_OBJPOINTER,old_obj);
  1239. READ_MICRO_CHUNK(cload,DAZZLEFACTORY_VARIABLE_TRANSFORM,tm);
  1240. READ_MICRO_CHUNK_STRING(cload,DAZZLEFACTORY_VARIABLE_TYPENAME,dazzle_type,sizeof(dazzle_type));
  1241. }
  1242. cload.Close_Micro_Chunk();
  1243. }
  1244. break;
  1245. default:
  1246. WWDEBUG_SAY(("Unhandled Chunk: 0x%X File: %s Line: %d\r\n",__FILE__,__LINE__));
  1247. break;
  1248. };
  1249. cload.Close_Chunk();
  1250. }
  1251. /*
  1252. ** Create a new dazzle object
  1253. */
  1254. int type_index = 0;
  1255. if (strlen(dazzle_type) > 0) {
  1256. type_index = DazzleRenderObjClass::Get_Type_ID(dazzle_type);
  1257. }
  1258. RenderObjClass * new_obj = NEW_REF(DazzleRenderObjClass,(dazzle_type));
  1259. /*
  1260. ** If we failed to create it, replace it with a NULL
  1261. */
  1262. if (new_obj == NULL) {
  1263. static int count = 0;
  1264. if ( ++count < 10 ) {
  1265. WWDEBUG_SAY(("DazzlePersistFactory failed to create dazzle of type: %s!!\r\n",dazzle_type));
  1266. WWDEBUG_SAY(("Replacing it with a NULL render object!\r\n"));
  1267. }
  1268. new_obj = WW3DAssetManager::Get_Instance()->Create_Render_Obj("NULL");
  1269. }
  1270. WWASSERT(new_obj != NULL);
  1271. if (new_obj) {
  1272. new_obj->Set_Transform(tm);
  1273. }
  1274. /*
  1275. ** Register the old pointer for re-mapping to the new pointer
  1276. */
  1277. SaveLoadSystemClass::Register_Pointer(old_obj,new_obj);
  1278. return new_obj;
  1279. }
  1280. void DazzlePersistFactoryClass::Save(ChunkSaveClass & csave,PersistClass * obj) const
  1281. {
  1282. DazzleRenderObjClass * robj = (DazzleRenderObjClass *)obj;
  1283. unsigned int dazzle_type = robj->Get_Dazzle_Type();
  1284. const char * dazzle_type_name = DazzleRenderObjClass::Get_Type_Name(dazzle_type);
  1285. Matrix3D tm = robj->Get_Transform();
  1286. csave.Begin_Chunk(DAZZLEFACTORY_CHUNKID_VARIABLES);
  1287. WRITE_MICRO_CHUNK(csave,DAZZLEFACTORY_VARIABLE_OBJPOINTER,robj);
  1288. WRITE_MICRO_CHUNK(csave,DAZZLEFACTORY_VARIABLE_TRANSFORM,tm);
  1289. WRITE_MICRO_CHUNK_STRING(csave,DAZZLEFACTORY_VARIABLE_TYPENAME,dazzle_type_name);
  1290. csave.End_Chunk();
  1291. }
  1292. /*
  1293. ** DazzleRenderObj save-load.
  1294. */
  1295. const PersistFactoryClass & DazzleRenderObjClass::Get_Factory (void) const
  1296. {
  1297. return _DazzleFactory;
  1298. }
  1299. /**********************************************************************************************
  1300. **
  1301. ** DazzleLayerClass Implementation
  1302. **
  1303. **********************************************************************************************/
  1304. DazzleLayerClass::DazzleLayerClass(void) :
  1305. visible_lists(NULL)
  1306. {
  1307. if (type_count != 0) {
  1308. // Generate an array with one visible list for each type.
  1309. // NOTE - this means that this constructor must be called AFTER all types
  1310. // are initialized
  1311. WWASSERT(type_count);
  1312. visible_lists = W3DNEWARRAY DazzleRenderObjClass *[type_count];
  1313. for (unsigned int i = 0; i < type_count; i++) {
  1314. visible_lists[i] = NULL;
  1315. }
  1316. }
  1317. }
  1318. DazzleLayerClass::~DazzleLayerClass(void)
  1319. {
  1320. // NOTE - this destructor must be called BEFORE DeInit().
  1321. // WWASSERT(type_count);
  1322. for (unsigned int i = 0; i < type_count; i++) {
  1323. Clear_Visible_List(i);
  1324. }
  1325. delete [] visible_lists;
  1326. }
  1327. void DazzleLayerClass::Render(CameraClass* camera)
  1328. {
  1329. if (!camera) return;
  1330. camera->Apply();
  1331. unsigned time_ms=WW3D::Get_Frame_Time();
  1332. if (time_ms==0) time_ms=1;
  1333. DX8Wrapper::Set_Material(NULL);
  1334. for (unsigned type=0;type<type_count;++type) {
  1335. if (!types[type]) continue;
  1336. int count = Get_Visible_Item_Count(type);
  1337. if (!count) continue;
  1338. DazzleRenderObjClass* n = visible_lists[type];
  1339. while (n) {
  1340. n->Render_Dazzle(camera);
  1341. n=n->Succ();
  1342. }
  1343. // Must clear the visible list at the end of each render.
  1344. Clear_Visible_List(type);
  1345. }
  1346. }
  1347. // ----------------------------------------------------------------------------
  1348. int DazzleLayerClass::Get_Visible_Item_Count(unsigned int type) const
  1349. {
  1350. if (type >= type_count) {
  1351. WWASSERT(0);
  1352. return 0;
  1353. }
  1354. int count=0;
  1355. DazzleRenderObjClass* n = visible_lists[type];
  1356. while (n) {
  1357. count++;
  1358. n=n->Succ();
  1359. }
  1360. return count;
  1361. }
  1362. // ----------------------------------------------------------------------------
  1363. void DazzleLayerClass::Clear_Visible_List(unsigned int type)
  1364. {
  1365. if (type >= type_count) {
  1366. WWASSERT(0);
  1367. return;
  1368. }
  1369. DazzleRenderObjClass* n = visible_lists[type];
  1370. while (n) {
  1371. n->Release_Ref();
  1372. n->on_list = false;
  1373. n=n->Succ();
  1374. }
  1375. visible_lists[type] = NULL;
  1376. }
  1377. /**********************************************************************************************
  1378. **
  1379. ** DazzleVisibilityClass Implementation
  1380. ** The default dazzle visibility handler asks the scene to determine whether the dazzle
  1381. ** is occluded.
  1382. **
  1383. **********************************************************************************************/
  1384. float DazzleVisibilityClass::Compute_Dazzle_Visibility
  1385. (
  1386. RenderInfoClass & rinfo,
  1387. DazzleRenderObjClass * dazzle,
  1388. const Vector3 & point
  1389. ) const
  1390. {
  1391. /*
  1392. ** Look up the scene this dazzle is in
  1393. */
  1394. SceneClass * scene = dazzle->Get_Scene();
  1395. RenderObjClass * container = dazzle->Get_Container();
  1396. while ((scene == NULL) && (container != NULL)) {
  1397. scene = container->Get_Scene();
  1398. container = container->Get_Container();
  1399. }
  1400. /*
  1401. ** If we found the scene (we SHOULD!) then ask it to compute the visibility
  1402. */
  1403. if (scene != NULL) {
  1404. float value = scene->Compute_Point_Visibility(rinfo,point);
  1405. scene->Release_Ref();
  1406. return value;
  1407. } else {
  1408. return 1.0f;
  1409. }
  1410. }
  1411. /**********************************************************************************************
  1412. **
  1413. ** DazzlePrototypeClass Implementation
  1414. **
  1415. **********************************************************************************************/
  1416. RenderObjClass * DazzlePrototypeClass::Create(void)
  1417. {
  1418. return NEW_REF(DazzleRenderObjClass,(DazzleType));
  1419. }
  1420. WW3DErrorType DazzlePrototypeClass::Load_W3D(ChunkLoadClass & cload)
  1421. {
  1422. StringClass dazzle_type;
  1423. while (cload.Open_Chunk()) {
  1424. switch (cload.Cur_Chunk_ID())
  1425. {
  1426. READ_WWSTRING_CHUNK(cload,W3D_CHUNK_DAZZLE_NAME,Name);
  1427. READ_WWSTRING_CHUNK(cload,W3D_CHUNK_DAZZLE_TYPENAME,dazzle_type);
  1428. default:
  1429. break;
  1430. }
  1431. cload.Close_Chunk();
  1432. }
  1433. DazzleType = DazzleRenderObjClass::Get_Type_ID(dazzle_type);
  1434. if (DazzleType == UINT_MAX) {
  1435. DazzleType = 0;
  1436. }
  1437. return WW3D_ERROR_OK;
  1438. }
  1439. /**********************************************************************************************
  1440. **
  1441. ** DazzleLoaderClass Implementation
  1442. **
  1443. **********************************************************************************************/
  1444. PrototypeClass * DazzleLoaderClass::Load_W3D(ChunkLoadClass & cload)
  1445. {
  1446. DazzlePrototypeClass * new_proto = W3DNEW DazzlePrototypeClass;
  1447. new_proto->Load_W3D(cload);
  1448. return new_proto;
  1449. }