afxEffectWrapper.cpp 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193
  1. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  2. // Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
  3. // Copyright (C) 2015 Faust Logic, Inc.
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to
  7. // deal in the Software without restriction, including without limitation the
  8. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9. // sell copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21. // IN THE SOFTWARE.
  22. //
  23. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  24. #include "afx/arcaneFX.h"
  25. #include "math/mathIO.h"
  26. #include "afx/ce/afxComponentEffect.h"
  27. #include "afx/afxResidueMgr.h"
  28. #include "afx/afxChoreographer.h"
  29. #include "afx/afxConstraint.h"
  30. #include "afx/xm/afxXfmMod.h"
  31. #include "afx/afxEffectWrapper.h"
  32. #include "afx/util/afxAnimCurve.h"
  33. #include "afx/util/afxEase.h"
  34. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  35. // afxEffectWrapperData
  36. IMPLEMENT_CO_DATABLOCK_V1(afxEffectBaseData);
  37. ConsoleDocClass( afxEffectBaseData,
  38. "@brief A datablock baseclass for afxEffectWrapperData and afxEffectGroupData.\n\n"
  39. "Not intended to be used directly, afxEffectBaseData exists to provide base member "
  40. "variables and generic functionality for the derived classes afxEffectWrapperData and "
  41. "afxEffectGroupData.\n\n"
  42. "@see afxEffectWrapperData\n\n"
  43. "@see afxEffectGroupData\n\n"
  44. "@ingroup afxEffects\n"
  45. "@ingroup AFX\n"
  46. "@ingroup Datablocks\n"
  47. );
  48. IMPLEMENT_CO_DATABLOCK_V1(afxEffectWrapperData);
  49. ConsoleDocClass( afxEffectWrapperData,
  50. "@brief A datablock that describes an Effect Wrapper.\n\n"
  51. "Conceptually an effect wrapper encloses a building-block effect and acts "
  52. "as a handle for adding the effect to a choreographer. Effect wrapper fields "
  53. "primarily deal with effect timing, constraints, and conditional effect execution.\n\n"
  54. "@see afxEffectBaseData\n\n"
  55. "@see afxEffectGroupData\n\n"
  56. "@ingroup afxEffects\n"
  57. "@ingroup AFX\n"
  58. "@ingroup Datablocks\n"
  59. );
  60. afxEffectWrapperData::afxEffectWrapperData()
  61. {
  62. effect_name = ST_NULLSTRING;
  63. effect_data = 0;
  64. effect_desc = 0;
  65. data_ID = 0;
  66. use_as_cons_obj = false;
  67. use_ghost_as_cons_obj = false;
  68. // constraint data
  69. cons_spec = ST_NULLSTRING;
  70. pos_cons_spec = ST_NULLSTRING;
  71. orient_cons_spec = ST_NULLSTRING;
  72. aim_cons_spec = StringTable->insert("camera");
  73. life_cons_spec = ST_NULLSTRING;
  74. // conditional execution flags
  75. effect_enabled = true;
  76. ranking_range.set(0,255);
  77. lod_range.set(0,255);
  78. life_conds = 0;
  79. for (S32 i = 0; i < MAX_CONDITION_STATES; i++)
  80. {
  81. exec_cond_on_bits[i] = 0;
  82. exec_cond_off_bits[i] = 0;
  83. exec_cond_bitmasks[i] = 0;
  84. }
  85. ewd_timing.lifetime = -1;
  86. user_fade_out_time = 0.0;
  87. is_looping = false;
  88. n_loops = 0;
  89. loop_gap_time = 0.0f;
  90. ignore_time_factor = false;
  91. propagate_time_factor = false;
  92. // residue settings
  93. // scaling factors
  94. rate_factor = 1.0f;
  95. scale_factor = 1.0f;
  96. dMemset(xfm_modifiers, 0, sizeof(xfm_modifiers));
  97. forced_bbox.minExtents.set(1,1,1);
  98. forced_bbox.maxExtents.set(-1,-1,-1);
  99. update_forced_bbox = false;
  100. // marked true if datablock ids need to
  101. // be converted into pointers
  102. do_id_convert = false;
  103. sort_priority = 0;
  104. direction.set(0,1,0);
  105. speed = 0.0f;
  106. mass = 1.0f;
  107. borrow_altitudes = false;
  108. vis_keys_spec = ST_NULLSTRING;
  109. vis_keys = 0;
  110. group_index = -1;
  111. inherit_timing = 0;
  112. }
  113. afxEffectWrapperData::afxEffectWrapperData(const afxEffectWrapperData& other, bool temp_clone) : afxEffectBaseData(other, temp_clone)
  114. {
  115. effect_name = other.effect_name;
  116. effect_data = other.effect_data;
  117. effect_desc = other.effect_desc;
  118. data_ID = other.data_ID;
  119. use_as_cons_obj = other.use_as_cons_obj;
  120. use_ghost_as_cons_obj = other.use_ghost_as_cons_obj;
  121. cons_spec = other.cons_spec;
  122. pos_cons_spec = other.pos_cons_spec;
  123. orient_cons_spec = other.orient_cons_spec;
  124. aim_cons_spec = other.aim_cons_spec;
  125. life_cons_spec = other.life_cons_spec;
  126. cons_def = other.cons_def;
  127. pos_cons_def = other.pos_cons_def;
  128. orient_cons_def = other.orient_cons_def;
  129. aim_cons_def = other.aim_cons_def;
  130. life_cons_def = other.life_cons_def;
  131. effect_enabled = other.effect_enabled;
  132. ranking_range = other.ranking_range;
  133. lod_range = other.lod_range;
  134. life_conds = other.life_conds;
  135. dMemcpy(exec_cond_on_bits, other.exec_cond_on_bits, sizeof(exec_cond_on_bits));
  136. dMemcpy(exec_cond_off_bits, other.exec_cond_off_bits, sizeof(exec_cond_off_bits));
  137. dMemcpy(exec_cond_bitmasks, other.exec_cond_bitmasks, sizeof(exec_cond_bitmasks));
  138. ewd_timing = other.ewd_timing;
  139. user_fade_out_time = other.user_fade_out_time;
  140. is_looping = other.is_looping;
  141. n_loops = other.n_loops;
  142. loop_gap_time = other.loop_gap_time;
  143. ignore_time_factor = other.ignore_time_factor;
  144. propagate_time_factor = other.propagate_time_factor;
  145. rate_factor = other.rate_factor;
  146. scale_factor = other.scale_factor;
  147. dMemcpy(xfm_modifiers, other.xfm_modifiers, sizeof(xfm_modifiers));
  148. forced_bbox = other.forced_bbox;
  149. update_forced_bbox = other.update_forced_bbox;
  150. do_id_convert = other.do_id_convert;
  151. sort_priority = other.sort_priority;
  152. direction = other.direction;
  153. speed = other.speed;
  154. mass = other.mass;
  155. borrow_altitudes = other.borrow_altitudes;
  156. vis_keys_spec = other.vis_keys_spec;
  157. vis_keys = other.vis_keys;
  158. if (other.vis_keys)
  159. {
  160. vis_keys = new afxAnimCurve();
  161. for (S32 i = 0; i < other.vis_keys->numKeys(); i++)
  162. {
  163. F32 when = other.vis_keys->getKeyTime(i);
  164. F32 what = other.vis_keys->getKeyValue(i);
  165. vis_keys->addKey(when, what);
  166. }
  167. }
  168. else
  169. vis_keys = 0;
  170. group_index = other.group_index;
  171. inherit_timing = other.inherit_timing;
  172. }
  173. afxEffectWrapperData::~afxEffectWrapperData()
  174. {
  175. if (vis_keys)
  176. delete vis_keys;
  177. }
  178. #define myOffset(field) Offset(field, afxEffectWrapperData)
  179. void afxEffectWrapperData::initPersistFields()
  180. {
  181. // the wrapped effect
  182. addField("effect", TYPEID<SimDataBlock>(), myOffset(effect_data),
  183. "...");
  184. addField("effectName", TypeString, myOffset(effect_name),
  185. "...");
  186. // constraints
  187. addField("constraint", TypeString, myOffset(cons_spec),
  188. "...");
  189. addField("posConstraint", TypeString, myOffset(pos_cons_spec),
  190. "...");
  191. addField("posConstraint2", TypeString, myOffset(aim_cons_spec),
  192. "...");
  193. addField("orientConstraint", TypeString, myOffset(orient_cons_spec),
  194. "...");
  195. addField("lifeConstraint", TypeString, myOffset(life_cons_spec),
  196. "...");
  197. //
  198. addField("isConstraintSrc", TypeBool, myOffset(use_as_cons_obj),
  199. "...");
  200. addField("ghostIsConstraintSrc", TypeBool, myOffset(use_ghost_as_cons_obj),
  201. "...");
  202. addField("delay", TypeF32, myOffset(ewd_timing.delay),
  203. "...");
  204. addField("lifetime", TypeF32, myOffset(ewd_timing.lifetime),
  205. "...");
  206. addField("fadeInTime", TypeF32, myOffset(ewd_timing.fade_in_time),
  207. "...");
  208. addField("residueLifetime", TypeF32, myOffset(ewd_timing.residue_lifetime),
  209. "...");
  210. addField("fadeInEase", TypePoint2F, myOffset(ewd_timing.fadein_ease),
  211. "...");
  212. addField("fadeOutEase", TypePoint2F, myOffset(ewd_timing.fadeout_ease),
  213. "...");
  214. addField("lifetimeBias", TypeF32, myOffset(ewd_timing.life_bias),
  215. "...");
  216. addField("fadeOutTime", TypeF32, myOffset(user_fade_out_time),
  217. "...");
  218. addField("rateFactor", TypeF32, myOffset(rate_factor),
  219. "...");
  220. addField("scaleFactor", TypeF32, myOffset(scale_factor),
  221. "...");
  222. addField("isLooping", TypeBool, myOffset(is_looping),
  223. "...");
  224. addField("loopCount", TypeS32, myOffset(n_loops),
  225. "...");
  226. addField("loopGapTime", TypeF32, myOffset(loop_gap_time),
  227. "...");
  228. addField("ignoreTimeFactor", TypeBool, myOffset(ignore_time_factor),
  229. "...");
  230. addField("propagateTimeFactor", TypeBool, myOffset(propagate_time_factor),
  231. "...");
  232. addField("effectEnabled", TypeBool, myOffset(effect_enabled),
  233. "...");
  234. addField("rankingRange", TypeByteRange, myOffset(ranking_range),
  235. "...");
  236. addField("levelOfDetailRange", TypeByteRange, myOffset(lod_range),
  237. "...");
  238. addField("lifeConditions", TypeS32, myOffset(life_conds),
  239. "...");
  240. addField("execConditions", TypeS32, myOffset(exec_cond_on_bits), MAX_CONDITION_STATES,
  241. "...");
  242. addField("execOffConditions", TypeS32, myOffset(exec_cond_off_bits), MAX_CONDITION_STATES,
  243. "...");
  244. addField("xfmModifiers", TYPEID<afxXM_BaseData>(), myOffset(xfm_modifiers), MAX_XFM_MODIFIERS,
  245. "...");
  246. addField("forcedBBox", TypeBox3F, myOffset(forced_bbox),
  247. "...");
  248. addField("updateForcedBBox", TypeBool, myOffset(update_forced_bbox),
  249. "...");
  250. addField("sortPriority", TypeS8, myOffset(sort_priority),
  251. "...");
  252. addField("direction", TypePoint3F, myOffset(direction),
  253. "...");
  254. addField("speed", TypeF32, myOffset(speed),
  255. "...");
  256. addField("mass", TypeF32, myOffset(mass),
  257. "...");
  258. addField("borrowAltitudes", TypeBool, myOffset(borrow_altitudes),
  259. "...");
  260. addField("visibilityKeys", TypeString, myOffset(vis_keys_spec),
  261. "...");
  262. addField("groupIndex", TypeS32, myOffset(group_index),
  263. "...");
  264. addField("inheritGroupTiming", TypeS32, myOffset(inherit_timing),
  265. "...");
  266. Parent::initPersistFields();
  267. // disallow some field substitutions
  268. disableFieldSubstitutions("effect");
  269. onlyKeepClearSubstitutions("xfmModifiers"); // subs resolving to "~~", or "~0" are OK
  270. // Conditional Execution Flags
  271. Con::setIntVariable("$afx::DISABLED", DISABLED);
  272. Con::setIntVariable("$afx::ENABLED", ENABLED);
  273. Con::setIntVariable("$afx::FAILING", FAILING);
  274. Con::setIntVariable("$afx::DEAD", DEAD);
  275. Con::setIntVariable("$afx::ALIVE", ALIVE);
  276. Con::setIntVariable("$afx::DYING", DYING);
  277. }
  278. bool afxEffectWrapperData::onAdd()
  279. {
  280. if (Parent::onAdd() == false)
  281. return false;
  282. if (!effect_data)
  283. {
  284. if (!Sim::findObject((SimObjectId)data_ID, effect_data))
  285. {
  286. Con::errorf("afxEffectWrapperData::onAdd() -- bad datablockId: 0x%x", data_ID);
  287. return false;
  288. }
  289. }
  290. if (effect_data)
  291. {
  292. if (!afxEffectAdapterDesc::identifyEffect(this))
  293. {
  294. Con::errorf("afxEffectWrapperData::onAdd() -- unknown effect type.");
  295. return false;
  296. }
  297. }
  298. parse_cons_specs();
  299. parse_vis_keys();
  300. // figure out if fade-out is for effect of residue
  301. if (ewd_timing.residue_lifetime > 0)
  302. {
  303. ewd_timing.residue_fadetime = user_fade_out_time;
  304. ewd_timing.fade_out_time = 0.0f;
  305. }
  306. else
  307. {
  308. ewd_timing.residue_fadetime = 0.0f;
  309. ewd_timing.fade_out_time = user_fade_out_time;
  310. }
  311. // adjust fade-in time
  312. if (ewd_timing.lifetime >= 0)
  313. {
  314. ewd_timing.fade_in_time = getMin(ewd_timing.lifetime, ewd_timing.fade_in_time);
  315. }
  316. // adjust exec-conditions
  317. for (S32 i = 0; i < MAX_CONDITION_STATES; i++)
  318. exec_cond_bitmasks[i] = exec_cond_on_bits[i] | exec_cond_off_bits[i];
  319. return true;
  320. }
  321. void afxEffectWrapperData::packData(BitStream* stream)
  322. {
  323. Parent::packData(stream);
  324. writeDatablockID(stream, effect_data, mPacked);
  325. stream->writeString(effect_name);
  326. stream->writeString(cons_spec);
  327. stream->writeString(pos_cons_spec);
  328. stream->writeString(orient_cons_spec);
  329. stream->writeString(aim_cons_spec);
  330. stream->writeString(life_cons_spec);
  331. //
  332. stream->write(use_as_cons_obj);
  333. //stream->write(use_ghost_as_cons_obj);
  334. stream->writeFlag(effect_enabled);
  335. stream->write(ranking_range.low);
  336. stream->write(ranking_range.high);
  337. stream->write(lod_range.low);
  338. stream->write(lod_range.high);
  339. for (S32 i = 0; i < MAX_CONDITION_STATES; i++)
  340. {
  341. stream->write(exec_cond_on_bits[i]);
  342. stream->write(exec_cond_off_bits[i]);
  343. }
  344. stream->write(life_conds);
  345. stream->write(ewd_timing.delay);
  346. stream->write(ewd_timing.lifetime);
  347. stream->write(ewd_timing.fade_in_time);
  348. stream->write(user_fade_out_time);
  349. stream->write(is_looping);
  350. stream->write(n_loops);
  351. stream->write(loop_gap_time);
  352. stream->write(ignore_time_factor);
  353. stream->write(propagate_time_factor);
  354. stream->write(ewd_timing.residue_lifetime);
  355. stream->write(rate_factor);
  356. stream->write(scale_factor);
  357. // modifiers
  358. pack_mods(stream, xfm_modifiers, mPacked);
  359. mathWrite(*stream, forced_bbox);
  360. stream->write(update_forced_bbox);
  361. stream->write(sort_priority);
  362. mathWrite(*stream, direction);
  363. stream->write(speed);
  364. stream->write(mass);
  365. stream->write(borrow_altitudes);
  366. if (stream->writeFlag(vis_keys_spec != ST_NULLSTRING))
  367. stream->writeLongString(1023, vis_keys_spec);
  368. if (stream->writeFlag(group_index != -1))
  369. stream->write(group_index);
  370. stream->writeInt(inherit_timing, TIMING_BITS);
  371. }
  372. void afxEffectWrapperData::unpackData(BitStream* stream)
  373. {
  374. Parent::unpackData(stream);
  375. data_ID = readDatablockID(stream);
  376. effect_name = stream->readSTString();
  377. cons_spec = stream->readSTString();
  378. pos_cons_spec = stream->readSTString();
  379. orient_cons_spec = stream->readSTString();
  380. aim_cons_spec = stream->readSTString();
  381. life_cons_spec = stream->readSTString();
  382. //
  383. stream->read(&use_as_cons_obj);
  384. //stream->read(&use_ghost_as_cons_obj);
  385. effect_enabled = stream->readFlag();
  386. stream->read(&ranking_range.low);
  387. stream->read(&ranking_range.high);
  388. stream->read(&lod_range.low);
  389. stream->read(&lod_range.high);
  390. for (S32 i = 0; i < MAX_CONDITION_STATES; i++)
  391. {
  392. stream->read(&exec_cond_on_bits[i]);
  393. stream->read(&exec_cond_off_bits[i]);
  394. }
  395. stream->read(&life_conds);
  396. stream->read(&ewd_timing.delay);
  397. stream->read(&ewd_timing.lifetime);
  398. stream->read(&ewd_timing.fade_in_time);
  399. stream->read(&user_fade_out_time);
  400. stream->read(&is_looping);
  401. stream->read(&n_loops);
  402. stream->read(&loop_gap_time);
  403. stream->read(&ignore_time_factor);
  404. stream->read(&propagate_time_factor);
  405. stream->read(&ewd_timing.residue_lifetime);
  406. stream->read(&rate_factor);
  407. stream->read(&scale_factor);
  408. // modifiers
  409. do_id_convert = true;
  410. unpack_mods(stream, xfm_modifiers);
  411. mathRead(*stream, &forced_bbox);
  412. stream->read(&update_forced_bbox);
  413. stream->read(&sort_priority);
  414. mathRead(*stream, &direction);
  415. stream->read(&speed);
  416. stream->read(&mass);
  417. stream->read(&borrow_altitudes);
  418. if (stream->readFlag())
  419. {
  420. char buf[1024];
  421. stream->readLongString(1023, buf);
  422. vis_keys_spec = StringTable->insert(buf);
  423. }
  424. else
  425. vis_keys_spec = ST_NULLSTRING;
  426. if (stream->readFlag())
  427. stream->read(&group_index);
  428. else
  429. group_index = -1;
  430. inherit_timing = stream->readInt(TIMING_BITS);
  431. }
  432. /* static*/
  433. S32 num_modifiers(afxXM_BaseData* mods[])
  434. {
  435. S32 n_mods = 0;
  436. for (int i = 0; i < afxEffectDefs::MAX_XFM_MODIFIERS; i++)
  437. {
  438. if (mods[i])
  439. {
  440. if (i != n_mods)
  441. {
  442. mods[n_mods] = mods[i];
  443. mods[i] = 0;
  444. }
  445. n_mods++;
  446. }
  447. }
  448. return n_mods;
  449. }
  450. void afxEffectWrapperData::parse_cons_specs()
  451. {
  452. // parse the constraint specifications
  453. bool runs_on_s = runsOnServer();
  454. bool runs_on_c = runsOnClient();
  455. cons_def.parseSpec(cons_spec, runs_on_s, runs_on_c);
  456. pos_cons_def.parseSpec(pos_cons_spec, runs_on_s, runs_on_c);
  457. orient_cons_def.parseSpec(orient_cons_spec, runs_on_s, runs_on_c);
  458. aim_cons_def.parseSpec(aim_cons_spec, runs_on_s, runs_on_c);
  459. life_cons_def.parseSpec(life_cons_spec, runs_on_s, runs_on_c);
  460. if (cons_def.isDefined())
  461. {
  462. pos_cons_def = cons_def;
  463. if (!orient_cons_def.isDefined())
  464. orient_cons_def = cons_def;
  465. }
  466. }
  467. void afxEffectWrapperData::parse_vis_keys()
  468. {
  469. if (vis_keys_spec != ST_NULLSTRING)
  470. {
  471. if (vis_keys)
  472. delete vis_keys;
  473. vis_keys = new afxAnimCurve();
  474. char* keys_buffer = dStrdup(vis_keys_spec);
  475. char* key_token = dStrtok(keys_buffer, " \t");
  476. while (key_token != NULL)
  477. {
  478. char* colon = dStrchr(key_token, ':');
  479. if (colon)
  480. {
  481. *colon = '\0';
  482. F32 when = dAtof(key_token);
  483. F32 what = dAtof(colon+1);
  484. vis_keys->addKey(when, what);
  485. }
  486. key_token = dStrtok(NULL, " \t");
  487. }
  488. dFree(keys_buffer);
  489. vis_keys->sort();
  490. }
  491. }
  492. void afxEffectWrapperData::gather_cons_defs(Vector<afxConstraintDef>& defs)
  493. {
  494. if (pos_cons_def.isDefined())
  495. defs.push_back(pos_cons_def);
  496. if (orient_cons_def.isDefined())
  497. defs.push_back(orient_cons_def);
  498. if (aim_cons_def.isDefined())
  499. defs.push_back(aim_cons_def);
  500. if (life_cons_def.isDefined())
  501. defs.push_back(life_cons_def);
  502. afxComponentEffectData* ce_data = dynamic_cast<afxComponentEffectData*>(effect_data);
  503. if (ce_data)
  504. ce_data->gather_cons_defs(defs);
  505. }
  506. void afxEffectWrapperData::pack_mods(BitStream* stream, afxXM_BaseData* mods[], bool packed)
  507. {
  508. S32 n_mods = num_modifiers(mods);
  509. stream->writeInt(n_mods, 6);
  510. for (int i = 0; i < n_mods; i++)
  511. writeDatablockID(stream, mods[i], packed);
  512. }
  513. void afxEffectWrapperData::unpack_mods(BitStream* stream, afxXM_BaseData* mods[])
  514. {
  515. S32 n_mods = stream->readInt(6);
  516. for (int i = 0; i < n_mods; i++)
  517. mods[i] = (afxXM_BaseData*)(uintptr_t)readDatablockID(stream);
  518. }
  519. bool afxEffectWrapperData::preload(bool server, String &errorStr)
  520. {
  521. if (!Parent::preload(server, errorStr))
  522. return false;
  523. // Resolve objects transmitted from server
  524. if (!server)
  525. {
  526. if (do_id_convert)
  527. {
  528. for (int i = 0; i < MAX_XFM_MODIFIERS; i++)
  529. {
  530. SimObjectId db_id = SimObjectId((uintptr_t)xfm_modifiers[i]);
  531. if (db_id != 0)
  532. {
  533. // try to convert id to pointer
  534. if (!Sim::findObject(db_id, xfm_modifiers[i]))
  535. {
  536. Con::errorf("afxEffectWrapperData::preload() -- bad datablockId: 0x%x (xfm_modifiers[%d])",
  537. db_id, i);
  538. }
  539. }
  540. do_id_convert = false;
  541. }
  542. }
  543. }
  544. return true;
  545. }
  546. void afxEffectWrapperData::onPerformSubstitutions()
  547. {
  548. Parent::onPerformSubstitutions();
  549. parse_cons_specs();
  550. parse_vis_keys();
  551. if (ewd_timing.residue_lifetime > 0)
  552. {
  553. ewd_timing.residue_fadetime = user_fade_out_time;
  554. ewd_timing.fade_out_time = 0.0f;
  555. }
  556. else
  557. {
  558. ewd_timing.residue_fadetime = 0.0f;
  559. ewd_timing.fade_out_time = user_fade_out_time;
  560. }
  561. }
  562. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  563. // afxEffectWrapper
  564. IMPLEMENT_CONOBJECT(afxEffectWrapper);
  565. ConsoleDocClass( afxEffectWrapper,
  566. "@brief An Effect Wrapper as defined by an afxEffectWrapperData datablock.\n\n"
  567. "Conceptually an effect wrapper encloses a building-block effect and acts "
  568. "as a handle for adding the effect to a choreographer. Effect wrapper fields "
  569. "primarily deal with effect timing, constraints, and conditional effect execution.\n\n"
  570. "Not intended to be used directly, afxEffectWrapper is an internal baseclass used to "
  571. "implement effect-specific adapter classes.\n\n"
  572. "@ingroup afxEffects\n"
  573. "@ingroup AFX\n"
  574. );
  575. afxEffectWrapper::afxEffectWrapper()
  576. {
  577. mChoreographer = 0;
  578. mDatablock = 0;
  579. mCons_mgr = 0;
  580. mCond_alive = true;
  581. mElapsed = 0;
  582. mLife_end = 0;
  583. mLife_elapsed = 0;
  584. mStopped = false;
  585. mNum_updates = 0;
  586. mFade_value = 1.0f;
  587. mLast_fade_value = 0.0f;
  588. mFade_in_end = 0.0;
  589. mFade_out_start = 0.0f;
  590. mIn_scope = true;
  591. mIs_aborted = false;
  592. mDo_fade_inout = false;
  593. mDo_fades = false;
  594. mFull_lifetime = 0;
  595. mTime_factor = 1.0f;
  596. mProp_time_factor = 1.0f;
  597. mLive_scale_factor = 1.0f;
  598. mLive_fade_factor = 1.0f;
  599. mTerrain_altitude = -1.0f;
  600. mInterior_altitude = -1.0f;
  601. mGroup_index = 0;
  602. dMemset(mXfm_modifiers, 0, sizeof(mXfm_modifiers));
  603. }
  604. afxEffectWrapper::~afxEffectWrapper()
  605. {
  606. for (S32 i = 0; i < MAX_XFM_MODIFIERS; i++)
  607. if (mXfm_modifiers[i])
  608. delete mXfm_modifiers[i];
  609. if (mDatablock && mDatablock->effect_name != ST_NULLSTRING)
  610. {
  611. mChoreographer->removeNamedEffect(this);
  612. if (mDatablock->use_as_cons_obj && !mEffect_cons_id.undefined())
  613. mCons_mgr->setReferenceEffect(mEffect_cons_id, 0);
  614. }
  615. if (mDatablock && mDatablock->isTempClone())
  616. delete mDatablock;
  617. mDatablock = 0;
  618. }
  619. #undef myOffset
  620. #define myOffset(field) Offset(field, afxEffectWrapper)
  621. void afxEffectWrapper::initPersistFields()
  622. {
  623. addField("liveScaleFactor", TypeF32, myOffset(mLive_scale_factor),
  624. "...");
  625. addField("liveFadeFactor", TypeF32, myOffset(mLive_fade_factor),
  626. "...");
  627. Parent::initPersistFields();
  628. }
  629. void afxEffectWrapper::ew_init(afxChoreographer* choreographer,
  630. afxEffectWrapperData* datablock,
  631. afxConstraintMgr* cons_mgr,
  632. F32 time_factor)
  633. {
  634. AssertFatal(choreographer != NULL, "Choreographer is missing.");
  635. AssertFatal(datablock != NULL, "Datablock is missing.");
  636. AssertFatal(cons_mgr != NULL, "Constraint manager is missing.");
  637. mChoreographer = choreographer;
  638. mDatablock = datablock;
  639. mCons_mgr = cons_mgr;
  640. ea_set_datablock(datablock->effect_data);
  641. mEW_timing = datablock->ewd_timing;
  642. if (mEW_timing.life_bias != 1.0f)
  643. {
  644. if (mEW_timing.lifetime > 0)
  645. mEW_timing.lifetime *= mEW_timing.life_bias;
  646. mEW_timing.fade_in_time *= mEW_timing.life_bias;
  647. mEW_timing.fade_out_time *= mEW_timing.life_bias;
  648. }
  649. mPos_cons_id = cons_mgr->getConstraintId(datablock->pos_cons_def);
  650. mOrient_cons_id = cons_mgr->getConstraintId(datablock->orient_cons_def);
  651. mAim_cons_id = cons_mgr->getConstraintId(datablock->aim_cons_def);
  652. mLife_cons_id = cons_mgr->getConstraintId(datablock->life_cons_def);
  653. mTime_factor = (datablock->ignore_time_factor) ? 1.0f : time_factor;
  654. if (datablock->propagate_time_factor)
  655. mProp_time_factor = time_factor;
  656. if (datablock->runsHere(choreographer->isServerObject()))
  657. {
  658. for (int i = 0; i < MAX_XFM_MODIFIERS && datablock->xfm_modifiers[i] != 0; i++)
  659. {
  660. mXfm_modifiers[i] = datablock->xfm_modifiers[i]->create(this, choreographer->isServerObject());
  661. AssertFatal(mXfm_modifiers[i] != 0, avar("Error, creation failed for xfm_modifiers[%d] of %s.", i, datablock->getName()));
  662. if (mXfm_modifiers[i] == 0)
  663. Con::errorf("Error, creation failed for xfm_modifiers[%d] of %s.", i, datablock->getName());
  664. }
  665. }
  666. if (datablock->effect_name != ST_NULLSTRING)
  667. {
  668. assignName(datablock->effect_name);
  669. choreographer->addNamedEffect(this);
  670. if (datablock->use_as_cons_obj)
  671. {
  672. mEffect_cons_id = cons_mgr->setReferenceEffect(datablock->effect_name, this);
  673. if (mEffect_cons_id.undefined() && datablock->isTempClone() && datablock->runsHere(choreographer->isServerObject()))
  674. mEffect_cons_id = cons_mgr->createReferenceEffect(datablock->effect_name, this);
  675. }
  676. }
  677. }
  678. void afxEffectWrapper::prestart()
  679. {
  680. // modify timing values by time_factor
  681. if (mEW_timing.lifetime > 0)
  682. mEW_timing.lifetime *= mTime_factor;
  683. mEW_timing.delay *= mTime_factor;
  684. mEW_timing.fade_in_time *= mTime_factor;
  685. mEW_timing.fade_out_time *= mTime_factor;
  686. if (mEW_timing.lifetime < 0)
  687. {
  688. mFull_lifetime = INFINITE_LIFETIME;
  689. mLife_end = INFINITE_LIFETIME;
  690. }
  691. else
  692. {
  693. mFull_lifetime = mEW_timing.lifetime + mEW_timing.fade_out_time;
  694. mLife_end = mEW_timing.delay + mEW_timing.lifetime;
  695. }
  696. if ((mEW_timing.fade_in_time + mEW_timing.fade_out_time) > 0.0f)
  697. {
  698. mFade_in_end = mEW_timing.delay + mEW_timing.fade_in_time;
  699. if (mFull_lifetime == INFINITE_LIFETIME)
  700. mFade_out_start = INFINITE_LIFETIME;
  701. else
  702. mFade_out_start = mEW_timing.delay + mEW_timing.lifetime;
  703. mDo_fade_inout = true;
  704. }
  705. if (!mDo_fade_inout && mDatablock->vis_keys != NULL && mDatablock->vis_keys->numKeys() > 0)
  706. {
  707. //do_fades = true;
  708. mFade_out_start = mEW_timing.delay + mEW_timing.lifetime;
  709. }
  710. }
  711. bool afxEffectWrapper::start(F32 timestamp)
  712. {
  713. if (!ea_is_enabled())
  714. {
  715. Con::warnf("afxEffectWrapper::start() -- effect type of %s is currently disabled.", mDatablock->getName());
  716. return false;
  717. }
  718. afxConstraint* life_constraint = getLifeConstraint();
  719. if (life_constraint)
  720. mCond_alive = life_constraint->getLivingState();
  721. mElapsed = timestamp;
  722. for (S32 i = 0; i < MAX_XFM_MODIFIERS; i++)
  723. {
  724. if (!mXfm_modifiers[i])
  725. break;
  726. else
  727. mXfm_modifiers[i]->start(timestamp);
  728. }
  729. if (!ea_start())
  730. {
  731. // subclass should print error message if applicable, so no message here.
  732. return false;
  733. }
  734. update(0.0f);
  735. return !isAborted();
  736. }
  737. bool afxEffectWrapper::test_life_conds()
  738. {
  739. afxConstraint* life_constraint = getLifeConstraint();
  740. if (!life_constraint || mDatablock->life_conds == 0)
  741. return true;
  742. S32 now_state = life_constraint->getDamageState();
  743. if ((mDatablock->life_conds & DEAD) != 0 && now_state == ShapeBase::Disabled)
  744. return true;
  745. if ((mDatablock->life_conds & ALIVE) != 0 && now_state == ShapeBase::Enabled)
  746. return true;
  747. if ((mDatablock->life_conds & DYING) != 0)
  748. return (mCond_alive && now_state == ShapeBase::Disabled);
  749. return false;
  750. }
  751. bool afxEffectWrapper::update(F32 dt)
  752. {
  753. mElapsed += dt;
  754. // life_elapsed won't exceed full_lifetime
  755. mLife_elapsed = getMin(mElapsed - mEW_timing.delay, mFull_lifetime);
  756. // update() returns early if elapsed is outside of active timing range
  757. // (delay <= elapsed <= delay+lifetime)
  758. // note: execution is always allowed beyond this point at least once,
  759. // even if elapsed exceeds the lifetime.
  760. if (mElapsed < mEW_timing.delay)
  761. {
  762. setScopeStatus(false);
  763. return false;
  764. }
  765. if (!mDatablock->requiresStop(mEW_timing) && mEW_timing.lifetime < 0)
  766. {
  767. F32 afterlife = mElapsed - mEW_timing.delay;
  768. if (afterlife > 1.0f || ((afterlife > 0.0f) && (mNum_updates > 0)))
  769. {
  770. setScopeStatus(mEW_timing.residue_lifetime > 0.0f);
  771. return false;
  772. }
  773. }
  774. else
  775. {
  776. F32 afterlife = mElapsed - (mFull_lifetime + mEW_timing.delay);
  777. if (afterlife > 1.0f || ((afterlife > 0.0f) && (mNum_updates > 0)))
  778. {
  779. setScopeStatus(mEW_timing.residue_lifetime > 0.0f);
  780. return false;
  781. }
  782. }
  783. // first time here, test if required conditions for effect are met
  784. if (mNum_updates == 0)
  785. {
  786. if (!test_life_conds())
  787. {
  788. mElapsed = mFull_lifetime + mEW_timing.delay;
  789. setScopeStatus(false);
  790. mNum_updates++;
  791. return false;
  792. }
  793. }
  794. setScopeStatus(true);
  795. mNum_updates++;
  796. // calculate current fade value if enabled
  797. if (mDo_fade_inout)
  798. {
  799. if (mEW_timing.fade_in_time > 0 && mElapsed <= mFade_in_end)
  800. {
  801. F32 t = mClampF((mElapsed - mEW_timing.delay)/ mEW_timing.fade_in_time, 0.0f, 1.0f);
  802. mFade_value = afxEase::t(t, mEW_timing.fadein_ease.x, mEW_timing.fadein_ease.y);
  803. mDo_fades = true;
  804. }
  805. else if (mElapsed > mFade_out_start)
  806. {
  807. if (mEW_timing.fade_out_time == 0)
  808. mFade_value = 0.0f;
  809. else
  810. {
  811. F32 t = mClampF(1.0f-(mElapsed - mFade_out_start)/ mEW_timing.fade_out_time, 0.0f, 1.0f);
  812. mFade_value = afxEase::t(t, mEW_timing.fadeout_ease.x, mEW_timing.fadeout_ease.y);
  813. }
  814. mDo_fades = true;
  815. }
  816. else
  817. {
  818. mFade_value = 1.0f;
  819. mDo_fades = false;
  820. }
  821. }
  822. else
  823. {
  824. mFade_value = 1.0;
  825. mDo_fades = false;
  826. }
  827. if (mDatablock->vis_keys && mDatablock->vis_keys->numKeys() > 0)
  828. {
  829. F32 vis = mDatablock->vis_keys->evaluate(mElapsed - mEW_timing.delay);
  830. mFade_value *= mClampF(vis, 0.0f, 1.0f);
  831. mDo_fades = (mFade_value < 1.0f);
  832. }
  833. // DEAL WITH CONSTRAINTS
  834. afxXM_Params params;
  835. Point3F& CONS_POS = params.pos;
  836. MatrixF& CONS_XFM = params.ori;
  837. Point3F& CONS_AIM = params.pos2;
  838. Point3F& CONS_SCALE = params.scale;
  839. LinearColorF& CONS_COLOR = params.color;
  840. afxConstraint* pos_constraint = getPosConstraint();
  841. if (pos_constraint)
  842. {
  843. bool valid = pos_constraint->getPosition(CONS_POS, mDatablock->pos_cons_def.mHistory_time);
  844. if (!valid)
  845. getUnconstrainedPosition(CONS_POS);
  846. setScopeStatus(valid);
  847. if (valid && mDatablock->borrow_altitudes)
  848. {
  849. F32 terr_alt, inter_alt;
  850. if (pos_constraint->getAltitudes(terr_alt, inter_alt))
  851. {
  852. mTerrain_altitude = terr_alt;
  853. mInterior_altitude = inter_alt;
  854. }
  855. }
  856. }
  857. else
  858. {
  859. getUnconstrainedPosition(CONS_POS);
  860. setScopeStatus(false);
  861. }
  862. afxConstraint* orient_constraint = getOrientConstraint();
  863. if (orient_constraint)
  864. {
  865. orient_constraint->getTransform(CONS_XFM, mDatablock->pos_cons_def.mHistory_time);
  866. }
  867. else
  868. {
  869. getUnconstrainedTransform(CONS_XFM);
  870. }
  871. afxConstraint* aim_constraint = getAimConstraint();
  872. if (aim_constraint)
  873. aim_constraint->getPosition(CONS_AIM, mDatablock->pos_cons_def.mHistory_time);
  874. else
  875. CONS_AIM.zero();
  876. CONS_SCALE.set(mDatablock->scale_factor, mDatablock->scale_factor, mDatablock->scale_factor);
  877. /*
  878. if (datablock->isPositional() && CONS_POS.isZero() && in_scope)
  879. Con::errorf("#EFFECT AT ORIGIN [%s] time=%g", datablock->getName(), dt);
  880. */
  881. getBaseColor(CONS_COLOR);
  882. params.vis = mFade_value;
  883. // apply modifiers
  884. for (int i = 0; i < MAX_XFM_MODIFIERS; i++)
  885. {
  886. if (!mXfm_modifiers[i])
  887. break;
  888. else
  889. mXfm_modifiers[i]->updateParams(dt, mLife_elapsed, params);
  890. }
  891. // final pos/orient is determined
  892. mUpdated_xfm = CONS_XFM;
  893. mUpdated_pos = CONS_POS;
  894. mUpdated_aim = CONS_AIM;
  895. mUpdated_xfm.setPosition(mUpdated_pos);
  896. mUpdated_scale = CONS_SCALE;
  897. mUpdated_color = CONS_COLOR;
  898. if (params.vis > 1.0f)
  899. mFade_value = 1.0f;
  900. else
  901. mFade_value = params.vis;
  902. if (mLast_fade_value != mFade_value)
  903. {
  904. mDo_fades = true;
  905. mLast_fade_value = mFade_value;
  906. }
  907. else
  908. {
  909. mDo_fades = (mFade_value < 1.0f);
  910. }
  911. if (!ea_update(dt))
  912. {
  913. mIs_aborted = true;
  914. Con::errorf("afxEffectWrapper::update() -- effect %s ended unexpectedly.", mDatablock->getName());
  915. }
  916. return true;
  917. }
  918. void afxEffectWrapper::stop()
  919. {
  920. if (!mDatablock->requiresStop(mEW_timing))
  921. return;
  922. mStopped = true;
  923. // this resets full_lifetime so it starts to shrink or fade
  924. if (mFull_lifetime == INFINITE_LIFETIME)
  925. {
  926. mFull_lifetime = (mElapsed - mEW_timing.delay) + afterStopTime();
  927. mLife_end = mElapsed;
  928. if (mEW_timing.fade_out_time > 0)
  929. mFade_out_start = mElapsed;
  930. }
  931. }
  932. void afxEffectWrapper::cleanup(bool was_stopped)
  933. {
  934. ea_finish(was_stopped);
  935. if (!mEffect_cons_id.undefined())
  936. {
  937. mCons_mgr->setReferenceEffect(mEffect_cons_id, 0);
  938. mEffect_cons_id = afxConstraintID();
  939. }
  940. }
  941. void afxEffectWrapper::setScopeStatus(bool in_scope)
  942. {
  943. if (mIn_scope != in_scope)
  944. {
  945. mIn_scope = in_scope;
  946. ea_set_scope_status(in_scope);
  947. }
  948. }
  949. bool afxEffectWrapper::isDone()
  950. {
  951. if (!mDatablock->is_looping)
  952. return (mElapsed >= (mLife_end + mEW_timing.fade_out_time));
  953. return false;
  954. }
  955. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  956. // static
  957. afxEffectWrapper* afxEffectWrapper::ew_create(afxChoreographer* choreographer,
  958. afxEffectWrapperData* datablock,
  959. afxConstraintMgr* cons_mgr,
  960. F32 time_factor,
  961. S32 group_index)
  962. {
  963. afxEffectWrapper* adapter = datablock->effect_desc->create();
  964. if (adapter)
  965. {
  966. adapter->mGroup_index = (datablock->group_index != -1) ? datablock->group_index : group_index;
  967. adapter->ew_init(choreographer, datablock, cons_mgr, time_factor);
  968. }
  969. return adapter;
  970. }
  971. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  972. Vector<afxEffectAdapterDesc*>* afxEffectAdapterDesc::adapters = 0;
  973. afxEffectAdapterDesc::afxEffectAdapterDesc()
  974. {
  975. if (!adapters)
  976. adapters = new Vector<afxEffectAdapterDesc*>;
  977. adapters->push_back(this);
  978. }
  979. bool afxEffectAdapterDesc::identifyEffect(afxEffectWrapperData* ew)
  980. {
  981. if (!ew || !ew->effect_data)
  982. {
  983. Con::errorf("afxEffectAdapterDesc::identifyEffect() -- effect datablock was not specified.");
  984. return false;
  985. }
  986. if (!adapters)
  987. {
  988. Con::errorf("afxEffectAdapterDesc::identifyEffect() -- adapter registration list has not been allocated.");
  989. return false;
  990. }
  991. if (adapters->size() == 0)
  992. {
  993. Con::errorf("afxEffectAdapterDesc::identifyEffect() -- no effect adapters have been registered.");
  994. return false;
  995. }
  996. for (S32 i = 0; i < adapters->size(); i++)
  997. {
  998. if ((*adapters)[i]->testEffectType(ew->effect_data))
  999. {
  1000. ew->effect_desc = (*adapters)[i];
  1001. (*adapters)[i]->prepEffect(ew);
  1002. return true;
  1003. }
  1004. }
  1005. Con::errorf("afxEffectAdapterDesc::identifyEffect() -- effect %s has an undefined type. -- %d",
  1006. ew->effect_data->getName(), adapters->size());
  1007. return false;
  1008. }
  1009. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//