transformState.cxx 76 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368
  1. /**
  2. * PANDA 3D SOFTWARE
  3. * Copyright (c) Carnegie Mellon University. All rights reserved.
  4. *
  5. * All use of this software is subject to the terms of the revised BSD
  6. * license. You should have received a copy of this license along
  7. * with this source code in a file named "LICENSE."
  8. *
  9. * @file transformState.cxx
  10. * @author drose
  11. * @date 2002-02-25
  12. */
  13. #include "transformState.h"
  14. #include "compose_matrix.h"
  15. #include "bamReader.h"
  16. #include "bamWriter.h"
  17. #include "datagramIterator.h"
  18. #include "indent.h"
  19. #include "compareTo.h"
  20. #include "pStatTimer.h"
  21. #include "config_pgraph.h"
  22. #include "lightReMutexHolder.h"
  23. #include "lightMutexHolder.h"
  24. #include "thread.h"
  25. using std::ostream;
  26. LightReMutex *TransformState::_states_lock = nullptr;
  27. TransformState::States TransformState::_states;
  28. CPT(TransformState) TransformState::_identity_state;
  29. CPT(TransformState) TransformState::_invalid_state;
  30. UpdateSeq TransformState::_last_cycle_detect;
  31. size_t TransformState::_garbage_index = 0;
  32. bool TransformState::_uniquify_matrix = true;
  33. PStatCollector TransformState::_cache_update_pcollector("*:State Cache:Update");
  34. PStatCollector TransformState::_garbage_collect_pcollector("*:State Cache:Garbage Collect");
  35. PStatCollector TransformState::_transform_compose_pcollector("*:State Cache:Compose Transform");
  36. PStatCollector TransformState::_transform_invert_pcollector("*:State Cache:Invert Transform");
  37. PStatCollector TransformState::_transform_calc_pcollector("*:State Cache:Calc Components");
  38. PStatCollector TransformState::_transform_break_cycles_pcollector("*:State Cache:Break Cycles");
  39. PStatCollector TransformState::_transform_new_pcollector("*:State Cache:New");
  40. PStatCollector TransformState::_transform_validate_pcollector("*:State Cache:Validate");
  41. PStatCollector TransformState::_transform_hash_pcollector("*:State Cache:Calc Hash");
  42. PStatCollector TransformState::_node_counter("TransformStates:On nodes");
  43. PStatCollector TransformState::_cache_counter("TransformStates:Cached");
  44. CacheStats TransformState::_cache_stats;
  45. TypeHandle TransformState::_type_handle;
  46. /**
  47. * Actually, this could be a private constructor, since no one inherits from
  48. * TransformState, but gcc gives us a spurious warning if all constructors are
  49. * private.
  50. */
  51. TransformState::
  52. TransformState() : _lock("TransformState") {
  53. if (_states_lock == nullptr) {
  54. init_states();
  55. }
  56. _saved_entry = -1;
  57. _flags = F_is_identity | F_singular_known | F_is_2d;
  58. _inv_mat = nullptr;
  59. _cache_stats.add_num_states(1);
  60. #ifdef DO_MEMORY_USAGE
  61. MemoryUsage::update_type(this, this);
  62. #endif
  63. }
  64. /**
  65. * The destructor is responsible for removing the TransformState from the
  66. * global set if it is there.
  67. */
  68. TransformState::
  69. ~TransformState() {
  70. // We'd better not call the destructor twice on a particular object.
  71. nassertv(!is_destructing());
  72. set_destructing();
  73. // Free the inverse matrix computation, if it has been stored.
  74. delete _inv_mat;
  75. _inv_mat = nullptr;
  76. LightReMutexHolder holder(*_states_lock);
  77. // unref() should have cleared these.
  78. nassertv(_saved_entry == -1);
  79. nassertv(_composition_cache.is_empty() && _invert_composition_cache.is_empty());
  80. // If this was true at the beginning of the destructor, but is no longer
  81. // true now, probably we've been double-deleted.
  82. nassertv(get_ref_count() == 0);
  83. _cache_stats.add_num_states(-1);
  84. #ifndef NDEBUG
  85. _flags = F_is_invalid | F_is_destructing;
  86. #endif
  87. }
  88. /**
  89. * Provides an arbitrary ordering among all unique TransformStates, so we can
  90. * store the essentially different ones in a big set and throw away the rest.
  91. *
  92. * Note that if this returns 0, it doesn't necessarily imply that operator ==
  93. * returns true; it uses a very slightly different comparison threshold.
  94. *
  95. * If uniquify_matrix is true, then matrix-defined TransformStates are also
  96. * uniqified. If uniquify_matrix is false, then only component-defined
  97. * TransformStates are uniquified, which is less expensive.
  98. */
  99. int TransformState::
  100. compare_to(const TransformState &other, bool uniquify_matrix) const {
  101. static const int significant_flags =
  102. (F_is_invalid | F_is_identity | F_components_given | F_hpr_given | F_quat_given | F_is_2d);
  103. int flags = (_flags & significant_flags);
  104. int other_flags = (other._flags & significant_flags);
  105. if (flags != other_flags) {
  106. return flags < other_flags ? -1 : 1;
  107. }
  108. if ((_flags & (F_is_invalid | F_is_identity)) != 0) {
  109. // All invalid transforms are equivalent to each other, and all identity
  110. // transforms are equivalent to each other.
  111. return 0;
  112. }
  113. if ((_flags & F_components_given) != 0) {
  114. // If the transform was specified componentwise, compare them
  115. // componentwise.
  116. int c = _pos.compare_to(other._pos);
  117. if (c != 0) {
  118. return c;
  119. }
  120. if ((_flags & F_hpr_given) != 0) {
  121. c = _hpr.compare_to(other._hpr);
  122. if (c != 0) {
  123. return c;
  124. }
  125. } else if ((_flags & F_quat_given) != 0) {
  126. c = _quat.compare_to(other._quat);
  127. if (c != 0) {
  128. return c;
  129. }
  130. }
  131. c = _scale.compare_to(other._scale);
  132. if (c != 0) {
  133. return c;
  134. }
  135. c = _shear.compare_to(other._shear);
  136. return c;
  137. }
  138. // Otherwise, compare the matrices . . .
  139. if (uniquify_matrix) {
  140. // . . . but only if the user thinks that's a worthwhile comparison.
  141. return get_mat().compare_to(other.get_mat());
  142. } else {
  143. // If not, we just compare the pointers.
  144. if (this != &other) {
  145. return (this < &other) ? -1 : 1;
  146. }
  147. return 0;
  148. }
  149. }
  150. /**
  151. * Tests equivalence between two transform states. We use this instead of
  152. * compare_to since this is faster, and we don't need an ordering between
  153. * TransformStates because we use a hash map.
  154. *
  155. * If uniquify_matrix is true, then matrix-defined TransformStates are also
  156. * uniqified. If uniquify_matrix is false, then only component-defined
  157. * TransformStates are uniquified, which is less expensive.
  158. */
  159. bool TransformState::
  160. operator == (const TransformState &other) const {
  161. static const int significant_flags =
  162. (F_is_invalid | F_is_identity | F_components_given | F_hpr_given | F_quat_given | F_is_2d);
  163. int flags = (_flags & significant_flags);
  164. int other_flags = (other._flags & significant_flags);
  165. if (flags != other_flags) {
  166. return false;
  167. }
  168. if ((_flags & (F_is_invalid | F_is_identity)) != 0) {
  169. // All invalid transforms are equivalent to each other, and all identity
  170. // transforms are equivalent to each other.
  171. return true;
  172. }
  173. if ((_flags & F_components_given) != 0) {
  174. // If the transform was specified componentwise, compare them
  175. // componentwise.
  176. if (_pos != other._pos) {
  177. return false;
  178. }
  179. if ((_flags & F_hpr_given) != 0) {
  180. if (_hpr != other._hpr) {
  181. return false;
  182. }
  183. } else if ((_flags & F_quat_given) != 0) {
  184. if (_quat != other._quat) {
  185. return false;
  186. }
  187. }
  188. if (_scale != other._scale) {
  189. return false;
  190. }
  191. return (_shear == other._shear);
  192. }
  193. // Otherwise, compare the matrices . . .
  194. if (_uniquify_matrix) {
  195. // . . . but only if the user thinks that's a worthwhile comparison.
  196. return get_mat().almost_equal(other.get_mat());
  197. } else {
  198. // If not, we just compare the pointers.
  199. return (this == &other);
  200. }
  201. }
  202. /**
  203. * Constructs an identity transform.
  204. */
  205. CPT(TransformState) TransformState::
  206. make_identity() {
  207. // The identity state is asked for so often, we make it a special case and
  208. // store a pointer forever once we find it the first time.
  209. if (_identity_state == nullptr) {
  210. TransformState *state = new TransformState;
  211. _identity_state = return_unique(state);
  212. }
  213. return _identity_state;
  214. }
  215. /**
  216. * Constructs an invalid transform; for instance, the result of inverting a
  217. * singular matrix.
  218. */
  219. CPT(TransformState) TransformState::
  220. make_invalid() {
  221. if (_invalid_state == nullptr) {
  222. TransformState *state = new TransformState;
  223. state->_flags = F_is_invalid | F_singular_known | F_is_singular | F_components_known | F_mat_known;
  224. _invalid_state = return_unique(state);
  225. }
  226. return _invalid_state;
  227. }
  228. /**
  229. * Makes a new TransformState with the specified components.
  230. */
  231. CPT(TransformState) TransformState::
  232. make_pos_hpr_scale_shear(const LVecBase3 &pos, const LVecBase3 &hpr,
  233. const LVecBase3 &scale, const LVecBase3 &shear) {
  234. nassertr(!(pos.is_nan() || hpr.is_nan() || scale.is_nan() || shear.is_nan()) , make_invalid());
  235. // Make a special-case check for the identity transform.
  236. if (pos == LVecBase3(0.0f, 0.0f, 0.0f) &&
  237. hpr == LVecBase3(0.0f, 0.0f, 0.0f) &&
  238. scale == LVecBase3(1.0f, 1.0f, 1.0f) &&
  239. shear == LVecBase3(0.0f, 0.0f, 0.0f)) {
  240. return make_identity();
  241. }
  242. TransformState *state = new TransformState;
  243. state->_pos = pos;
  244. state->_hpr = hpr;
  245. state->_scale = scale;
  246. state->_shear = shear;
  247. state->_flags = F_components_given | F_hpr_given | F_components_known | F_hpr_known | F_has_components;
  248. state->check_uniform_scale();
  249. return return_new(state);
  250. }
  251. /**
  252. * Makes a new TransformState with the specified components.
  253. */
  254. CPT(TransformState) TransformState::
  255. make_pos_quat_scale_shear(const LVecBase3 &pos, const LQuaternion &quat,
  256. const LVecBase3 &scale, const LVecBase3 &shear) {
  257. nassertr(!(pos.is_nan() || quat.is_nan() || scale.is_nan() || shear.is_nan()) , make_invalid());
  258. // Make a special-case check for the identity transform.
  259. if (pos == LVecBase3(0.0f, 0.0f, 0.0f) &&
  260. quat == LQuaternion::ident_quat() &&
  261. scale == LVecBase3(1.0f, 1.0f, 1.0f) &&
  262. shear == LVecBase3(0.0f, 0.0f, 0.0f)) {
  263. return make_identity();
  264. }
  265. TransformState *state = new TransformState;
  266. state->_pos = pos;
  267. state->_quat = quat;
  268. state->_scale = scale;
  269. state->_shear = shear;
  270. state->_flags = F_components_given | F_quat_given | F_components_known | F_quat_known | F_has_components;
  271. state->check_uniform_scale();
  272. return return_new(state);
  273. }
  274. /**
  275. * Makes a new TransformState with the specified transformation matrix.
  276. */
  277. CPT(TransformState) TransformState::
  278. make_mat(const LMatrix4 &mat) {
  279. nassertr(!mat.is_nan(), make_invalid());
  280. // Make a special-case check for the identity matrix.
  281. if (mat.is_identity()) {
  282. return make_identity();
  283. }
  284. TransformState *state = new TransformState;
  285. state->_mat = mat;
  286. state->_flags = F_mat_known;
  287. return return_new(state);
  288. }
  289. /**
  290. * Makes a new two-dimensional TransformState with the specified components.
  291. */
  292. CPT(TransformState) TransformState::
  293. make_pos_rotate_scale_shear2d(const LVecBase2 &pos, PN_stdfloat rotate,
  294. const LVecBase2 &scale,
  295. PN_stdfloat shear) {
  296. nassertr(!(pos.is_nan() || cnan(rotate) || scale.is_nan() || cnan(shear)) , make_invalid());
  297. // Make a special-case check for the identity transform.
  298. if (pos == LVecBase2(0.0f, 0.0f) &&
  299. rotate == 0.0f &&
  300. scale == LVecBase2(1.0f, 1.0f) &&
  301. shear == 0.0f) {
  302. return make_identity();
  303. }
  304. TransformState *state = new TransformState;
  305. state->_pos.set(pos[0], pos[1], 0.0f);
  306. switch (get_default_coordinate_system()) {
  307. default:
  308. case CS_zup_right:
  309. state->_hpr.set(rotate, 0.0f, 0.0f);
  310. break;
  311. case CS_zup_left:
  312. state->_hpr.set(-rotate, 0.0f, 0.0f);
  313. break;
  314. case CS_yup_right:
  315. state->_hpr.set(0.0f, 0.0f, -rotate);
  316. break;
  317. case CS_yup_left:
  318. state->_hpr.set(0.0, 0.0f, rotate);
  319. break;
  320. }
  321. state->_scale.set(scale[0], scale[1], 1.0f);
  322. state->_shear.set(shear, 0.0f, 0.0f);
  323. state->_flags = F_components_given | F_hpr_given | F_components_known | F_hpr_known | F_has_components | F_is_2d;
  324. state->check_uniform_scale2d();
  325. return return_new(state);
  326. }
  327. /**
  328. * Makes a new two-dimensional TransformState with the specified 3x3
  329. * transformation matrix.
  330. */
  331. CPT(TransformState) TransformState::
  332. make_mat3(const LMatrix3 &mat) {
  333. nassertr(!mat.is_nan(), make_invalid());
  334. // Make a special-case check for the identity matrix.
  335. if (mat.is_identity()) {
  336. return make_identity();
  337. }
  338. TransformState *state = new TransformState;
  339. state->_mat.set(mat(0, 0), mat(0, 1), 0.0f, mat(0, 2),
  340. mat(1, 0), mat(1, 1), 0.0f, mat(1, 2),
  341. 0.0f, 0.0f, 1.0f, 0.0f,
  342. mat(2, 0), mat(2, 1), 0.0f, mat(2, 2));
  343. state->_flags = F_mat_known | F_is_2d;
  344. return return_new(state);
  345. }
  346. /**
  347. * Returns a new TransformState object that represents the original
  348. * TransformState with its pos component replaced with the indicated value.
  349. */
  350. CPT(TransformState) TransformState::
  351. set_pos(const LVecBase3 &pos) const {
  352. nassertr(!pos.is_nan(), this);
  353. nassertr(!is_invalid(), this);
  354. if (is_identity() || components_given()) {
  355. // If we started with a componentwise transform, we keep it that way.
  356. if (quat_given()) {
  357. return make_pos_quat_scale_shear(pos, get_quat(), get_scale(), get_shear());
  358. } else {
  359. return make_pos_hpr_scale_shear(pos, get_hpr(), get_scale(), get_shear());
  360. }
  361. } else {
  362. // Otherwise, we have a matrix transform, and we keep it that way.
  363. LMatrix4 mat = get_mat();
  364. mat.set_row(3, pos);
  365. return make_mat(mat);
  366. }
  367. }
  368. /**
  369. * Returns a new TransformState object that represents the original
  370. * TransformState with its rotation component replaced with the indicated
  371. * value, if possible.
  372. */
  373. CPT(TransformState) TransformState::
  374. set_hpr(const LVecBase3 &hpr) const {
  375. nassertr(!hpr.is_nan(), this);
  376. nassertr(!is_invalid(), this);
  377. // nassertr(has_components(), this);
  378. return make_pos_hpr_scale_shear(get_pos(), hpr, get_scale(), get_shear());
  379. }
  380. /**
  381. * Returns a new TransformState object that represents the original
  382. * TransformState with its rotation component replaced with the indicated
  383. * value, if possible.
  384. */
  385. CPT(TransformState) TransformState::
  386. set_quat(const LQuaternion &quat) const {
  387. nassertr(!quat.is_nan(), this);
  388. nassertr(!is_invalid(), this);
  389. // nassertr(has_components(), this);
  390. return make_pos_quat_scale_shear(get_pos(), quat, get_scale(), get_shear());
  391. }
  392. /**
  393. * Returns a new TransformState object that represents the original
  394. * TransformState with its scale component replaced with the indicated value,
  395. * if possible.
  396. */
  397. CPT(TransformState) TransformState::
  398. set_scale(const LVecBase3 &scale) const {
  399. nassertr(!scale.is_nan(), this);
  400. nassertr(!is_invalid(), this);
  401. if (is_2d() && scale[0] == scale[1] && scale[1] == scale[2]) {
  402. // Don't inflate from 2-d to 3-d just because we got a uniform scale.
  403. return make_pos_rotate_scale_shear2d(get_pos2d(), get_rotate2d(),
  404. LVecBase2(scale[0], scale[0]),
  405. get_shear2d());
  406. }
  407. // nassertr(has_components(), this);
  408. if (quat_given()) {
  409. return make_pos_quat_scale_shear(get_pos(), get_quat(), scale, get_shear());
  410. } else {
  411. return make_pos_hpr_scale_shear(get_pos(), get_hpr(), scale, get_shear());
  412. }
  413. }
  414. /**
  415. * Returns a new TransformState object that represents the original
  416. * TransformState with its shear component replaced with the indicated value,
  417. * if possible.
  418. */
  419. CPT(TransformState) TransformState::
  420. set_shear(const LVecBase3 &shear) const {
  421. nassertr(!shear.is_nan(), this);
  422. nassertr(!is_invalid(), this);
  423. // nassertr(has_components(), this);
  424. if (quat_given()) {
  425. return make_pos_quat_scale_shear(get_pos(), get_quat(), get_scale(), shear);
  426. } else {
  427. return make_pos_hpr_scale_shear(get_pos(), get_hpr(), get_scale(), shear);
  428. }
  429. }
  430. /**
  431. * Returns a new TransformState object that represents the original 2-d
  432. * TransformState with its pos component replaced with the indicated value.
  433. */
  434. CPT(TransformState) TransformState::
  435. set_pos2d(const LVecBase2 &pos) const {
  436. nassertr(!pos.is_nan(), this);
  437. nassertr(!is_invalid(), this);
  438. if (!is_2d()) {
  439. return set_pos(LVecBase3(pos[0], pos[1], 0.0f));
  440. }
  441. if (is_identity() || components_given()) {
  442. // If we started with a componentwise transform, we keep it that way.
  443. return make_pos_rotate_scale_shear2d(pos, get_rotate2d(), get_scale2d(),
  444. get_shear2d());
  445. } else {
  446. // Otherwise, we have a matrix transform, and we keep it that way.
  447. LMatrix3 mat = get_mat3();
  448. mat.set_row(2, pos);
  449. return make_mat3(mat);
  450. }
  451. }
  452. /**
  453. * Returns a new TransformState object that represents the original 2-d
  454. * TransformState with its rotation component replaced with the indicated
  455. * value, if possible.
  456. */
  457. CPT(TransformState) TransformState::
  458. set_rotate2d(PN_stdfloat rotate) const {
  459. nassertr(!cnan(rotate), this);
  460. nassertr(!is_invalid(), this);
  461. if (!is_2d()) {
  462. switch (get_default_coordinate_system()) {
  463. default:
  464. case CS_zup_right:
  465. return set_hpr(LVecBase3(rotate, 0.0f, 0.0f));
  466. case CS_zup_left:
  467. return set_hpr(LVecBase3(-rotate, 0.0f, 0.0f));
  468. case CS_yup_right:
  469. return set_hpr(LVecBase3(0.0f, 0.0f, -rotate));
  470. case CS_yup_left:
  471. return set_hpr(LVecBase3(0.0f, 0.0f, rotate));
  472. }
  473. }
  474. return make_pos_rotate_scale_shear2d(get_pos2d(), rotate, get_scale2d(),
  475. get_shear2d());
  476. }
  477. /**
  478. * Returns a new TransformState object that represents the original 2-d
  479. * TransformState with its scale component replaced with the indicated value,
  480. * if possible.
  481. */
  482. CPT(TransformState) TransformState::
  483. set_scale2d(const LVecBase2 &scale) const {
  484. nassertr(!scale.is_nan(), this);
  485. nassertr(!is_invalid(), this);
  486. if (!is_2d()) {
  487. return set_scale(LVecBase3(scale[0], scale[1], 1.0f));
  488. }
  489. return make_pos_rotate_scale_shear2d(get_pos2d(), get_rotate2d(),
  490. scale, get_shear2d());
  491. }
  492. /**
  493. * Returns a new TransformState object that represents the original 2-d
  494. * TransformState with its shear component replaced with the indicated value,
  495. * if possible.
  496. */
  497. CPT(TransformState) TransformState::
  498. set_shear2d(PN_stdfloat shear) const {
  499. nassertr(!cnan(shear), this);
  500. nassertr(!is_invalid(), this);
  501. if (!is_2d()) {
  502. return set_shear(LVecBase3(shear, 0.0f, 0.0f));
  503. }
  504. return make_pos_rotate_scale_shear2d(get_pos2d(), get_rotate2d(),
  505. get_scale2d(), shear);
  506. }
  507. /**
  508. * Returns a new TransformState object that represents the composition of this
  509. * state with the other state.
  510. *
  511. * The result of this operation is cached, and will be retained as long as
  512. * both this TransformState object and the other TransformState object
  513. * continue to exist. Should one of them destruct, the cached entry will be
  514. * removed, and its pointer will be allowed to destruct as well.
  515. */
  516. CPT(TransformState) TransformState::
  517. compose(const TransformState *other) const {
  518. // We handle identity as a trivial special case.
  519. if (is_identity()) {
  520. return other;
  521. }
  522. if (other->is_identity()) {
  523. return this;
  524. }
  525. // If either transform is invalid, the result is invalid.
  526. if (is_invalid()) {
  527. return this;
  528. }
  529. if (other->is_invalid()) {
  530. return other;
  531. }
  532. if (!transform_cache) {
  533. return do_compose(other);
  534. }
  535. LightReMutexHolder holder(*_states_lock);
  536. // Is this composition already cached?
  537. int index = _composition_cache.find(other);
  538. if (index != -1) {
  539. const Composition &comp = _composition_cache.get_data(index);
  540. if (comp._result != nullptr) {
  541. // Success!
  542. _cache_stats.inc_hits();
  543. return comp._result;
  544. }
  545. }
  546. // Not in the cache. Compute a new result. It's important that we don't
  547. // hold the lock while we do this, or we lose the benefit of
  548. // parallelization.
  549. CPT(TransformState) result = do_compose(other);
  550. if (index != -1) {
  551. Composition &comp = _composition_cache.modify_data(index);
  552. // Well, it wasn't cached already, but we already had an entry (probably
  553. // created for the reverse direction), so use the same entry to store
  554. // the new result.
  555. comp._result = result;
  556. if (result != (const TransformState *)this) {
  557. // See the comments below about the need to up the reference count
  558. // only when the result is not the same as this.
  559. result->cache_ref();
  560. }
  561. // Here's the cache!
  562. _cache_stats.inc_hits();
  563. return result;
  564. }
  565. _cache_stats.inc_misses();
  566. // We need to make a new cache entry, both in this object and in the other
  567. // object. We make both records so the other TransformState object will
  568. // know to delete the entry from this object when it destructs, and vice-
  569. // versa.
  570. // The cache entry in this object is the only one that indicates the result;
  571. // the other will be NULL for now.
  572. _cache_stats.add_total_size(1);
  573. _cache_stats.inc_adds(_composition_cache.is_empty());
  574. _composition_cache[other]._result = result;
  575. if (other != this) {
  576. _cache_stats.add_total_size(1);
  577. _cache_stats.inc_adds(other->_composition_cache.is_empty());
  578. other->_composition_cache[this]._result = nullptr;
  579. }
  580. if (result != (TransformState *)this) {
  581. // If the result of do_compose() is something other than this, explicitly
  582. // increment the reference count. We have to be sure to decrement it
  583. // again later, when the composition entry is removed from the cache.
  584. result->cache_ref();
  585. // (If the result was just this again, we still store the result, but we
  586. // don't increment the reference count, since that would be a self-
  587. // referential leak.)
  588. }
  589. _cache_stats.maybe_report("TransformState");
  590. return result;
  591. }
  592. /**
  593. * Returns a new TransformState object that represents the composition of this
  594. * state's inverse with the other state.
  595. *
  596. * This is similar to compose(), but is particularly useful for computing the
  597. * relative state of a node as viewed from some other node.
  598. */
  599. CPT(TransformState) TransformState::
  600. invert_compose(const TransformState *other) const {
  601. // This method isn't strictly const, because it updates the cache, but we
  602. // pretend that it is because it's only a cache which is transparent to the
  603. // rest of the interface.
  604. // We handle identity as a trivial special case.
  605. if (is_identity()) {
  606. return other;
  607. }
  608. // Unlike compose(), the case of other->is_identity() is not quite as
  609. // trivial for invert_compose().
  610. // If either transform is invalid, the result is invalid.
  611. if (is_invalid()) {
  612. return this;
  613. }
  614. if (other->is_invalid()) {
  615. return other;
  616. }
  617. if (other == this) {
  618. // a->invert_compose(a) always produces identity.
  619. return make_identity();
  620. }
  621. if (!transform_cache) {
  622. return do_invert_compose(other);
  623. }
  624. LightReMutexHolder holder(*_states_lock);
  625. int index = _invert_composition_cache.find(other);
  626. if (index != -1) {
  627. const Composition &comp = _invert_composition_cache.get_data(index);
  628. if (comp._result != nullptr) {
  629. // Success!
  630. _cache_stats.inc_hits();
  631. return comp._result;
  632. }
  633. }
  634. // Not in the cache. Compute a new result. It's important that we don't
  635. // hold the lock while we do this, or we lose the benefit of
  636. // parallelization.
  637. CPT(TransformState) result = do_invert_compose(other);
  638. // Is this composition already cached?
  639. if (index != -1) {
  640. Composition &comp = _invert_composition_cache.modify_data(index);
  641. // Well, it wasn't cached already, but we already had an entry (probably
  642. // created for the reverse direction), so use the same entry to store
  643. // the new result.
  644. comp._result = result;
  645. if (result != (const TransformState *)this) {
  646. // See the comments below about the need to up the reference count
  647. // only when the result is not the same as this.
  648. result->cache_ref();
  649. }
  650. // Here's the cache!
  651. _cache_stats.inc_hits();
  652. return result;
  653. }
  654. _cache_stats.inc_misses();
  655. // We need to make a new cache entry, both in this object and in the other
  656. // object. We make both records so the other TransformState object will
  657. // know to delete the entry from this object when it destructs, and vice-
  658. // versa.
  659. // The cache entry in this object is the only one that indicates the result;
  660. // the other will be NULL for now.
  661. _cache_stats.add_total_size(1);
  662. _cache_stats.inc_adds(_invert_composition_cache.is_empty());
  663. _invert_composition_cache[other]._result = result;
  664. if (other != this) {
  665. _cache_stats.add_total_size(1);
  666. _cache_stats.inc_adds(other->_invert_composition_cache.is_empty());
  667. other->_invert_composition_cache[this]._result = nullptr;
  668. }
  669. if (result != (TransformState *)this) {
  670. // If the result of compose() is something other than this, explicitly
  671. // increment the reference count. We have to be sure to decrement it
  672. // again later, when the composition entry is removed from the cache.
  673. result->cache_ref();
  674. // (If the result was just this again, we still store the result, but we
  675. // don't increment the reference count, since that would be a self-
  676. // referential leak.)
  677. }
  678. return result;
  679. }
  680. /**
  681. * This method overrides ReferenceCount::unref() to check whether the
  682. * remaining reference count is entirely in the cache, and if so, it checks
  683. * for and breaks a cycle in the cache involving this object. This is
  684. * designed to prevent leaks from cyclical references within the cache.
  685. */
  686. bool TransformState::
  687. unref() const {
  688. if (garbage_collect_states || !transform_cache) {
  689. // If we're not using the cache at all, or if we're relying on garbage
  690. // collection, just allow the pointer to unref normally.
  691. return ReferenceCount::unref();
  692. }
  693. // Here is the normal refcounting case, with a normal cache, and without
  694. // garbage collection in effect. In this case we will pull the object out
  695. // of the cache when its reference count goes to 0.
  696. // We always have to grab the lock, since we will definitely need to be
  697. // holding it if we happen to drop the reference count to 0. Having to grab
  698. // the lock at every call to unref() is a big limiting factor on
  699. // parallelization.
  700. LightReMutexHolder holder(*_states_lock);
  701. if (auto_break_cycles && uniquify_transforms) {
  702. if (get_cache_ref_count() > 0 &&
  703. get_ref_count() == get_cache_ref_count() + 1) {
  704. // If we are about to remove the one reference that is not in the cache,
  705. // leaving only references in the cache, then we need to check for a
  706. // cycle involving this TransformState and break it if it exists.
  707. ((TransformState *)this)->detect_and_break_cycles();
  708. }
  709. }
  710. if (ReferenceCount::unref()) {
  711. // The reference count is still nonzero.
  712. return true;
  713. }
  714. // The reference count has just reached zero. Make sure the object is
  715. // removed from the global object pool, before anyone else finds it and
  716. // tries to ref it.
  717. ((TransformState *)this)->release_new();
  718. ((TransformState *)this)->remove_cache_pointers();
  719. return false;
  720. }
  721. /**
  722. * Returns true if the composition cache and invert composition cache for this
  723. * particular TransformState are self-consistent and valid, false otherwise.
  724. */
  725. bool TransformState::
  726. validate_composition_cache() const {
  727. LightReMutexHolder holder(*_states_lock);
  728. size_t size = _composition_cache.get_num_entries();
  729. for (size_t i = 0; i < size; ++i) {
  730. const TransformState *source = _composition_cache.get_key(i);
  731. if (source != nullptr) {
  732. // Check that the source also has a pointer back to this one. We always
  733. // add entries to the composition cache in pairs.
  734. int ri = source->_composition_cache.find(this);
  735. if (ri == -1) {
  736. // Failure! There is no back-pointer.
  737. pgraph_cat.error()
  738. << "TransformState::composition cache is inconsistent!\n";
  739. pgraph_cat.error(false)
  740. << *this << " compose " << *source << "\n";
  741. pgraph_cat.error(false)
  742. << "but no reverse\n";
  743. return false;
  744. }
  745. }
  746. }
  747. size = _invert_composition_cache.get_num_entries();
  748. for (size_t i = 0; i < size; ++i) {
  749. const TransformState *source = _invert_composition_cache.get_key(i);
  750. if (source != nullptr) {
  751. // Check that the source also has a pointer back to this one. We always
  752. // add entries to the composition cache in pairs.
  753. int ri = source->_invert_composition_cache.find(this);
  754. if (ri == -1) {
  755. // Failure! There is no back-pointer.
  756. pgraph_cat.error()
  757. << "TransformState::invert composition cache is inconsistent!\n";
  758. pgraph_cat.error(false)
  759. << *this << " invert compose " << *source << "\n";
  760. pgraph_cat.error(false)
  761. << "but no reverse\n";
  762. return false;
  763. }
  764. }
  765. }
  766. return true;
  767. }
  768. /**
  769. *
  770. */
  771. void TransformState::
  772. output(ostream &out) const {
  773. out << "T:";
  774. if (is_invalid()) {
  775. out << "(invalid)";
  776. } else if (is_identity()) {
  777. out << "(identity)";
  778. } else if (has_components()) {
  779. bool output_hpr = !get_hpr().almost_equal(LVecBase3(0.0f, 0.0f, 0.0f));
  780. if (!components_given()) {
  781. // A leading "m" indicates the transform was described as a full matrix,
  782. // and we are decomposing it for the benefit of the user.
  783. out << "m";
  784. } else if (output_hpr && quat_given()) {
  785. // A leading "q" indicates that the pos, scale, and shear are exactly as
  786. // specified, but the rotation was described as a quaternion, and we are
  787. // decomposing that to hpr for the benefit of the user.
  788. out << "q";
  789. }
  790. char lead = '(';
  791. if (is_2d()) {
  792. if (!get_pos2d().almost_equal(LVecBase2(0.0f, 0.0f))) {
  793. out << lead << "pos " << get_pos2d();
  794. lead = ' ';
  795. }
  796. if (output_hpr) {
  797. out << lead << "rotate " << get_rotate2d();
  798. lead = ' ';
  799. }
  800. if (!get_scale2d().almost_equal(LVecBase2(1.0f, 1.0f))) {
  801. if (has_uniform_scale()) {
  802. out << lead << "scale " << get_uniform_scale();
  803. lead = ' ';
  804. } else {
  805. out << lead << "scale " << get_scale2d();
  806. lead = ' ';
  807. }
  808. }
  809. if (has_nonzero_shear()) {
  810. out << lead << "shear " << get_shear2d();
  811. lead = ' ';
  812. }
  813. } else {
  814. if (!get_pos().almost_equal(LVecBase3(0.0f, 0.0f, 0.0f))) {
  815. out << lead << "pos " << get_pos();
  816. lead = ' ';
  817. }
  818. if (output_hpr) {
  819. out << lead << "hpr " << get_hpr();
  820. lead = ' ';
  821. }
  822. if (!get_scale().almost_equal(LVecBase3(1.0f, 1.0f, 1.0f))) {
  823. if (has_uniform_scale()) {
  824. out << lead << "scale " << get_uniform_scale();
  825. lead = ' ';
  826. } else {
  827. out << lead << "scale " << get_scale();
  828. lead = ' ';
  829. }
  830. }
  831. if (has_nonzero_shear()) {
  832. out << lead << "shear " << get_shear();
  833. lead = ' ';
  834. }
  835. }
  836. if (lead == '(') {
  837. out << "(almost identity)";
  838. } else {
  839. out << ")";
  840. }
  841. } else {
  842. if (is_2d()) {
  843. out << get_mat3();
  844. } else {
  845. out << get_mat();
  846. }
  847. }
  848. }
  849. /**
  850. *
  851. */
  852. void TransformState::
  853. write(ostream &out, int indent_level) const {
  854. indent(out, indent_level) << *this << "\n";
  855. }
  856. /**
  857. * Writes a brief description of the composition cache and invert composition
  858. * cache to the indicated ostream. This is not useful except for performance
  859. * analysis, to examine the cache structure.
  860. */
  861. void TransformState::
  862. write_composition_cache(ostream &out, int indent_level) const {
  863. indent(out, indent_level + 2) << _composition_cache << "\n";
  864. indent(out, indent_level + 2) << _invert_composition_cache << "\n";
  865. }
  866. /**
  867. * Returns the total number of unique TransformState objects allocated in the
  868. * world. This will go up and down during normal operations.
  869. */
  870. int TransformState::
  871. get_num_states() {
  872. LightReMutexHolder holder(*_states_lock);
  873. return _states.get_num_entries();
  874. }
  875. /**
  876. * Returns the total number of TransformState objects that have been allocated
  877. * but have no references outside of the internal TransformState cache.
  878. *
  879. * A nonzero return value is not necessarily indicative of leaked references;
  880. * it is normal for two TransformState objects, both of which have references
  881. * held outside the cache, to have the result of their composition stored
  882. * within the cache. This result will be retained within the cache until one
  883. * of the base TransformStates is released.
  884. *
  885. * Use list_cycles() to get an idea of the number of actual "leaked"
  886. * TransformState objects.
  887. */
  888. int TransformState::
  889. get_num_unused_states() {
  890. LightReMutexHolder holder(*_states_lock);
  891. // First, we need to count the number of times each TransformState object is
  892. // recorded in the cache. We could just trust get_cache_ref_count(), but
  893. // we'll be extra cautious for now.
  894. typedef pmap<const TransformState *, int> StateCount;
  895. StateCount state_count;
  896. size_t size = _states.get_num_entries();
  897. for (size_t si = 0; si < size; ++si) {
  898. const TransformState *state = _states.get_key(si);
  899. size_t i;
  900. size_t cache_size = state->_composition_cache.get_num_entries();
  901. for (i = 0; i < cache_size; ++i) {
  902. const TransformState *result = state->_composition_cache.get_data(i)._result;
  903. if (result != nullptr && result != state) {
  904. // Here's a TransformState that's recorded in the cache. Count it.
  905. std::pair<StateCount::iterator, bool> ir =
  906. state_count.insert(StateCount::value_type(result, 1));
  907. if (!ir.second) {
  908. // If the above insert operation fails, then it's already in the
  909. // cache; increment its value.
  910. (*(ir.first)).second++;
  911. }
  912. }
  913. }
  914. cache_size = state->_invert_composition_cache.get_num_entries();
  915. for (i = 0; i < cache_size; ++i) {
  916. const TransformState *result = state->_invert_composition_cache.get_data(i)._result;
  917. if (result != nullptr && result != state) {
  918. std::pair<StateCount::iterator, bool> ir =
  919. state_count.insert(StateCount::value_type(result, 1));
  920. if (!ir.second) {
  921. (*(ir.first)).second++;
  922. }
  923. }
  924. }
  925. }
  926. // Now that we have the appearance count of each TransformState object, we
  927. // can tell which ones are unreferenced outside of the TransformState cache,
  928. // by comparing these to the reference counts.
  929. int num_unused = 0;
  930. StateCount::iterator sci;
  931. for (sci = state_count.begin(); sci != state_count.end(); ++sci) {
  932. const TransformState *state = (*sci).first;
  933. int count = (*sci).second;
  934. nassertr(count == state->get_cache_ref_count(), num_unused);
  935. nassertr(count <= state->get_ref_count(), num_unused);
  936. if (count == state->get_ref_count()) {
  937. num_unused++;
  938. if (pgraph_cat.is_debug()) {
  939. pgraph_cat.debug()
  940. << "Unused state: " << (void *)state << ":"
  941. << state->get_ref_count() << " =\n";
  942. state->write(pgraph_cat.debug(false), 2);
  943. }
  944. }
  945. }
  946. return num_unused;
  947. }
  948. /**
  949. * Empties the cache of composed TransformStates. This makes every
  950. * TransformState forget what results when it is composed with other
  951. * TransformStates.
  952. *
  953. * This will eliminate any TransformState objects that have been allocated but
  954. * have no references outside of the internal TransformState map. It will not
  955. * eliminate TransformState objects that are still in use.
  956. *
  957. * Nowadays, this method should not be necessary, as reference-count cycles in
  958. * the composition cache should be automatically detected and broken.
  959. *
  960. * The return value is the number of TransformStates freed by this operation.
  961. */
  962. int TransformState::
  963. clear_cache() {
  964. LightReMutexHolder holder(*_states_lock);
  965. PStatTimer timer(_cache_update_pcollector);
  966. int orig_size = _states.get_num_entries();
  967. // First, we need to copy the entire set of states to a temporary vector,
  968. // reference-counting each object. That way we can walk through the copy,
  969. // without fear of dereferencing (and deleting) the objects in the map as we
  970. // go.
  971. {
  972. typedef pvector< CPT(TransformState) > TempStates;
  973. TempStates temp_states;
  974. temp_states.reserve(orig_size);
  975. size_t size = _states.get_num_entries();
  976. for (size_t si = 0; si < size; ++si) {
  977. const TransformState *state = _states.get_key(si);
  978. temp_states.push_back(state);
  979. }
  980. // Now it's safe to walk through the list, destroying the cache within
  981. // each object as we go. Nothing will be destructed till we're done.
  982. TempStates::iterator ti;
  983. for (ti = temp_states.begin(); ti != temp_states.end(); ++ti) {
  984. TransformState *state = (TransformState *)(*ti).p();
  985. size_t i;
  986. size_t cache_size = state->_composition_cache.get_num_entries();
  987. for (i = 0; i < cache_size; ++i) {
  988. const TransformState *result = state->_composition_cache.get_data(i)._result;
  989. if (result != nullptr && result != state) {
  990. result->cache_unref();
  991. nassertr(result->get_ref_count() > 0, 0);
  992. }
  993. }
  994. _cache_stats.add_total_size(-(int)state->_composition_cache.get_num_entries());
  995. state->_composition_cache.clear();
  996. cache_size = state->_invert_composition_cache.get_num_entries();
  997. for (i = 0; i < cache_size; ++i) {
  998. const TransformState *result = state->_invert_composition_cache.get_data(i)._result;
  999. if (result != nullptr && result != state) {
  1000. result->cache_unref();
  1001. nassertr(result->get_ref_count() > 0, 0);
  1002. }
  1003. }
  1004. _cache_stats.add_total_size(-(int)state->_invert_composition_cache.get_num_entries());
  1005. state->_invert_composition_cache.clear();
  1006. }
  1007. // Once this block closes and the temp_states object goes away, all the
  1008. // destruction will begin. Anything whose reference was held only within
  1009. // the various objects' caches will go away.
  1010. }
  1011. int new_size = _states.get_num_entries();
  1012. return orig_size - new_size;
  1013. }
  1014. /**
  1015. * Performs a garbage-collection cycle. This must be called periodically if
  1016. * garbage-collect-states is true to ensure that TransformStates get cleaned
  1017. * up appropriately. It does no harm to call it even if this variable is not
  1018. * true, but there is probably no advantage in that case.
  1019. */
  1020. int TransformState::
  1021. garbage_collect() {
  1022. if (!garbage_collect_states) {
  1023. return 0;
  1024. }
  1025. LightReMutexHolder holder(*_states_lock);
  1026. PStatTimer timer(_garbage_collect_pcollector);
  1027. size_t orig_size = _states.get_num_entries();
  1028. // How many elements to process this pass?
  1029. size_t size = orig_size;
  1030. size_t num_this_pass = std::max(0, int(size * garbage_collect_states_rate));
  1031. if (num_this_pass <= 0) {
  1032. return 0;
  1033. }
  1034. bool break_and_uniquify = (auto_break_cycles && uniquify_transforms);
  1035. size_t si = _garbage_index;
  1036. if (si >= size) {
  1037. si = 0;
  1038. }
  1039. num_this_pass = std::min(num_this_pass, size);
  1040. size_t stop_at_element = (si + num_this_pass) % size;
  1041. do {
  1042. TransformState *state = (TransformState *)_states.get_key(si);
  1043. if (break_and_uniquify) {
  1044. if (state->get_cache_ref_count() > 0 &&
  1045. state->get_ref_count() == state->get_cache_ref_count()) {
  1046. // If we have removed all the references to this state not in the
  1047. // cache, leaving only references in the cache, then we need to
  1048. // check for a cycle involving this TransformState and break it if
  1049. // it exists.
  1050. state->detect_and_break_cycles();
  1051. }
  1052. }
  1053. if (!state->unref_if_one()) {
  1054. // This state has recently been unreffed to 1 (the one we added when
  1055. // we stored it in the cache). Now it's time to delete it. This is
  1056. // safe, because we're holding the _states_lock, so it's not possible
  1057. // for some other thread to find the state in the cache and ref it
  1058. // while we're doing this. Also, we've just made sure to unref it to 0,
  1059. // to ensure that another thread can't get it via a weak pointer.
  1060. state->release_new();
  1061. state->remove_cache_pointers();
  1062. state->cache_unref_only();
  1063. delete state;
  1064. // When we removed it from the hash map, it swapped the last element
  1065. // with the one we just removed. So the current index contains one we
  1066. // still need to visit.
  1067. --size;
  1068. --si;
  1069. if (stop_at_element > 0) {
  1070. --stop_at_element;
  1071. }
  1072. }
  1073. si = (si + 1) % size;
  1074. } while (si != stop_at_element);
  1075. _garbage_index = si;
  1076. nassertr(_states.get_num_entries() == size, 0);
  1077. #ifdef _DEBUG
  1078. nassertr(_states.validate(), 0);
  1079. #endif
  1080. // If we just cleaned up a lot of states, see if we can reduce the table in
  1081. // size. This will help reduce iteration overhead in the future.
  1082. _states.consider_shrink_table();
  1083. return (int)orig_size - (int)size;
  1084. }
  1085. /**
  1086. * Detects all of the reference-count cycles in the cache and reports them to
  1087. * standard output.
  1088. *
  1089. * These cycles may be inadvertently created when state compositions cycle
  1090. * back to a starting point. Nowadays, these cycles should be automatically
  1091. * detected and broken, so this method should never list any cycles unless
  1092. * there is a bug in that detection logic.
  1093. *
  1094. * The cycles listed here are not leaks in the strictest sense of the word,
  1095. * since they can be reclaimed by a call to clear_cache(); but they will not
  1096. * be reclaimed automatically.
  1097. */
  1098. void TransformState::
  1099. list_cycles(ostream &out) {
  1100. LightReMutexHolder holder(*_states_lock);
  1101. typedef pset<const TransformState *> VisitedStates;
  1102. VisitedStates visited;
  1103. CompositionCycleDesc cycle_desc;
  1104. size_t size = _states.get_num_entries();
  1105. for (size_t si = 0; si < size; ++si) {
  1106. const TransformState *state = _states.get_key(si);
  1107. bool inserted = visited.insert(state).second;
  1108. if (inserted) {
  1109. ++_last_cycle_detect;
  1110. if (r_detect_cycles(state, state, 1, _last_cycle_detect, &cycle_desc)) {
  1111. // This state begins a cycle.
  1112. CompositionCycleDesc::reverse_iterator csi;
  1113. out << "\nCycle detected of length " << cycle_desc.size() + 1 << ":\n"
  1114. << "state " << (void *)state << ":" << state->get_ref_count()
  1115. << " =\n";
  1116. state->write(out, 2);
  1117. for (csi = cycle_desc.rbegin(); csi != cycle_desc.rend(); ++csi) {
  1118. const CompositionCycleDescEntry &entry = (*csi);
  1119. if (entry._inverted) {
  1120. out << "invert composed with ";
  1121. } else {
  1122. out << "composed with ";
  1123. }
  1124. out << (const void *)entry._obj << ":" << entry._obj->get_ref_count()
  1125. << " " << *entry._obj << "\n"
  1126. << "produces " << (const void *)entry._result << ":"
  1127. << entry._result->get_ref_count() << " =\n";
  1128. entry._result->write(out, 2);
  1129. visited.insert(entry._result);
  1130. }
  1131. cycle_desc.clear();
  1132. } else {
  1133. ++_last_cycle_detect;
  1134. if (r_detect_reverse_cycles(state, state, 1, _last_cycle_detect, &cycle_desc)) {
  1135. // This state begins a cycle.
  1136. CompositionCycleDesc::iterator csi;
  1137. out << "\nReverse cycle detected of length " << cycle_desc.size() + 1 << ":\n"
  1138. << "state ";
  1139. for (csi = cycle_desc.begin(); csi != cycle_desc.end(); ++csi) {
  1140. const CompositionCycleDescEntry &entry = (*csi);
  1141. out << (const void *)entry._result << ":"
  1142. << entry._result->get_ref_count() << " =\n";
  1143. entry._result->write(out, 2);
  1144. out << (const void *)entry._obj << ":"
  1145. << entry._obj->get_ref_count() << " =\n";
  1146. entry._obj->write(out, 2);
  1147. visited.insert(entry._result);
  1148. }
  1149. out << (void *)state << ":"
  1150. << state->get_ref_count() << " =\n";
  1151. state->write(out, 2);
  1152. cycle_desc.clear();
  1153. }
  1154. }
  1155. }
  1156. }
  1157. }
  1158. /**
  1159. * Lists all of the TransformStates in the cache to the output stream, one per
  1160. * line. This can be quite a lot of output if the cache is large, so be
  1161. * prepared.
  1162. */
  1163. void TransformState::
  1164. list_states(ostream &out) {
  1165. LightReMutexHolder holder(*_states_lock);
  1166. size_t size = _states.get_num_entries();
  1167. out << size << " states:\n";
  1168. for (size_t si = 0; si < size; ++si) {
  1169. const TransformState *state = _states.get_key(si);
  1170. state->write(out, 2);
  1171. }
  1172. }
  1173. /**
  1174. * Ensures that the cache is still stored in sorted order, and that none of
  1175. * the cache elements have been inadvertently deleted. Returns true if so,
  1176. * false if there is a problem (which implies someone has modified one of the
  1177. * supposedly-const TransformState objects).
  1178. */
  1179. bool TransformState::
  1180. validate_states() {
  1181. PStatTimer timer(_transform_validate_pcollector);
  1182. LightReMutexHolder holder(*_states_lock);
  1183. if (_states.is_empty()) {
  1184. return true;
  1185. }
  1186. if (!_states.validate()) {
  1187. pgraph_cat.error()
  1188. << "TransformState::_states cache is invalid!\n";
  1189. return false;
  1190. }
  1191. size_t size = _states.get_num_entries();
  1192. size_t si = 0;
  1193. nassertr(si < size, false);
  1194. nassertr(_states.get_key(si)->get_ref_count() >= 0, false);
  1195. size_t snext = si;
  1196. ++snext;
  1197. while (snext < size) {
  1198. nassertr(_states.get_key(snext)->get_ref_count() >= 0, false);
  1199. const TransformState *ssi = _states.get_key(si);
  1200. if (!ssi->validate_composition_cache()) {
  1201. return false;
  1202. }
  1203. const TransformState *ssnext = _states.get_key(snext);
  1204. bool c = (*ssi) == (*ssnext);
  1205. bool ci = (*ssnext) == (*ssi);
  1206. if (c != ci) {
  1207. pgraph_cat.error()
  1208. << "TransformState::operator == () not defined properly!\n";
  1209. pgraph_cat.error(false)
  1210. << "(a, b): " << c << "\n";
  1211. pgraph_cat.error(false)
  1212. << "(b, a): " << ci << "\n";
  1213. ssi->write(pgraph_cat.error(false), 2);
  1214. ssnext->write(pgraph_cat.error(false), 2);
  1215. return false;
  1216. }
  1217. si = snext;
  1218. ++snext;
  1219. }
  1220. return true;
  1221. }
  1222. /**
  1223. * Make sure the global _states map is allocated. This only has to be done
  1224. * once. We could make this map static, but then we run into problems if
  1225. * anyone creates a TransformState object at static init time; it also seems
  1226. * to cause problems when the Panda shared library is unloaded at application
  1227. * exit time.
  1228. */
  1229. void TransformState::
  1230. init_states() {
  1231. ConfigVariableBool uniquify_matrix
  1232. ("uniquify-matrix", true,
  1233. PRC_DESC("Set this true to look up arbitrary 4x4 transform matrices in "
  1234. "the cache, to ensure that two differently-computed transforms "
  1235. "that happen to encode the same matrix will be collapsed into "
  1236. "a single pointer. Nowadays, with the transforms stored in a "
  1237. "hashtable, we're generally better off with this set true."));
  1238. // Store this at the beginning, so that we don't have to query this every
  1239. // time that the comparison operator is invoked.
  1240. _uniquify_matrix = uniquify_matrix;
  1241. // TODO: we should have a global Panda mutex to allow us to safely create
  1242. // _states_lock without a startup race condition. For the meantime, this is
  1243. // OK because we guarantee that this method is called at static init time,
  1244. // presumably when there is still only one thread in the world.
  1245. _states_lock = new LightReMutex("TransformState::_states_lock");
  1246. _cache_stats.init();
  1247. nassertv(Thread::get_current_thread() == Thread::get_main_thread());
  1248. }
  1249. /**
  1250. * This function is used to share a common TransformState pointer for all
  1251. * equivalent TransformState objects.
  1252. *
  1253. * This is different from return_unique() in that it does not actually
  1254. * guarantee a unique pointer, unless uniquify-transforms is set.
  1255. */
  1256. CPT(TransformState) TransformState::
  1257. return_new(TransformState *state) {
  1258. nassertr(state != nullptr, state);
  1259. if (!uniquify_transforms && !state->is_identity()) {
  1260. return state;
  1261. }
  1262. return return_unique(state);
  1263. }
  1264. /**
  1265. * This function is used to share a common TransformState pointer for all
  1266. * equivalent TransformState objects.
  1267. *
  1268. * See the similar logic in RenderState. The idea is to create a new
  1269. * TransformState object and pass it through this function, which will share
  1270. * the pointer with a previously-created TransformState object if it is
  1271. * equivalent.
  1272. */
  1273. CPT(TransformState) TransformState::
  1274. return_unique(TransformState *state) {
  1275. nassertr(state != nullptr, state);
  1276. if (!transform_cache) {
  1277. return state;
  1278. }
  1279. #ifndef NDEBUG
  1280. if (paranoid_const) {
  1281. nassertr(validate_states(), state);
  1282. }
  1283. #endif
  1284. PStatTimer timer(_transform_new_pcollector);
  1285. LightReMutexHolder holder(*_states_lock);
  1286. if (state->_saved_entry != -1) {
  1287. // This state is already in the cache. nassertr(_states.find(state) ==
  1288. // state->_saved_entry, state);
  1289. return state;
  1290. }
  1291. // Save the state in a local PointerTo so that it will be freed at the end
  1292. // of this function if no one else uses it.
  1293. CPT(TransformState) pt_state = state;
  1294. int si = _states.find(state);
  1295. if (si != -1) {
  1296. // There's an equivalent state already in the set. Return it.
  1297. return _states.get_key(si);
  1298. }
  1299. // Not already in the set; add it.
  1300. if (garbage_collect_states) {
  1301. // If we'll be garbage collecting states explicitly, we'll increment the
  1302. // reference count when we store it in the cache, so that it won't be
  1303. // deleted while it's in it.
  1304. state->cache_ref();
  1305. }
  1306. si = _states.store(state, nullptr);
  1307. // Save the index and return the input state.
  1308. state->_saved_entry = si;
  1309. return pt_state;
  1310. }
  1311. /**
  1312. * The private implemention of compose(); this actually composes two
  1313. * TransformStates, without bothering with the cache.
  1314. */
  1315. CPT(TransformState) TransformState::
  1316. do_compose(const TransformState *other) const {
  1317. PStatTimer timer(_transform_compose_pcollector);
  1318. nassertr((_flags & F_is_invalid) == 0, this);
  1319. nassertr((other->_flags & F_is_invalid) == 0, other);
  1320. if (compose_componentwise &&
  1321. has_uniform_scale() &&
  1322. !has_nonzero_shear() && !other->has_nonzero_shear() &&
  1323. ((components_given() && other->has_components()) ||
  1324. (other->components_given() && has_components()))) {
  1325. // We will do this operation componentwise if *either* transform was given
  1326. // componentwise (and there is no non-uniform scale in the way).
  1327. CPT(TransformState) result;
  1328. if (is_2d() && other->is_2d()) {
  1329. // Do a 2-d compose.
  1330. LVecBase2 pos = get_pos2d();
  1331. PN_stdfloat rotate = get_rotate2d();
  1332. LQuaternion quat = get_norm_quat();
  1333. PN_stdfloat scale = get_uniform_scale();
  1334. LPoint3 op = quat.xform(other->get_pos());
  1335. pos += LVecBase2(op[0], op[1]) * scale;
  1336. rotate += other->get_rotate2d();
  1337. LVecBase2 new_scale = other->get_scale2d() * scale;
  1338. result = make_pos_rotate_scale2d(pos, rotate, new_scale);
  1339. } else {
  1340. // A normal 3-d compose.
  1341. LVecBase3 pos = get_pos();
  1342. LQuaternion quat = get_norm_quat();
  1343. PN_stdfloat scale = get_uniform_scale();
  1344. pos += quat.xform(other->get_pos()) * scale;
  1345. quat = other->get_norm_quat() * quat;
  1346. LVecBase3 new_scale = other->get_scale() * scale;
  1347. result = make_pos_quat_scale(pos, quat, new_scale);
  1348. }
  1349. #ifndef NDEBUG
  1350. if (paranoid_compose) {
  1351. // Now verify against the matrix.
  1352. LMatrix4 new_mat;
  1353. new_mat.multiply(other->get_mat(), get_mat());
  1354. if (!new_mat.almost_equal(result->get_mat(), 0.1)) {
  1355. CPT(TransformState) correct = make_mat(new_mat);
  1356. pgraph_cat.warning()
  1357. << "Componentwise composition of " << *this << " and " << *other
  1358. << " produced:\n"
  1359. << *result << "\n instead of:\n" << *correct << "\n";
  1360. result = correct;
  1361. }
  1362. }
  1363. #endif // NDEBUG
  1364. return result;
  1365. }
  1366. // Do the operation with matrices.
  1367. if (is_2d() && other->is_2d()) {
  1368. LMatrix3 new_mat = other->get_mat3() * get_mat3();
  1369. return make_mat3(new_mat);
  1370. } else {
  1371. LMatrix4 new_mat;
  1372. new_mat.multiply(other->get_mat(), get_mat());
  1373. return make_mat(new_mat);
  1374. }
  1375. }
  1376. /**
  1377. * The private implemention of invert_compose().
  1378. */
  1379. CPT(TransformState) TransformState::
  1380. do_invert_compose(const TransformState *other) const {
  1381. PStatTimer timer(_transform_invert_pcollector);
  1382. nassertr((_flags & F_is_invalid) == 0, this);
  1383. nassertr((other->_flags & F_is_invalid) == 0, other);
  1384. if (compose_componentwise &&
  1385. has_uniform_scale() &&
  1386. !has_nonzero_shear() && !other->has_nonzero_shear() &&
  1387. ((components_given() && other->has_components()) ||
  1388. (other->components_given() && has_components()))) {
  1389. // We will do this operation componentwise if *either* transform was given
  1390. // componentwise (and there is no non-uniform scale in the way).
  1391. CPT(TransformState) result;
  1392. if (is_2d() && other->is_2d()) {
  1393. // Do a 2-d invert compose.
  1394. LVecBase2 pos = get_pos2d();
  1395. PN_stdfloat rotate = get_rotate2d();
  1396. LQuaternion quat = get_norm_quat();
  1397. PN_stdfloat scale = get_uniform_scale();
  1398. // First, invert our own transform.
  1399. if (scale == 0.0f) {
  1400. ((TransformState *)this)->_flags |= F_is_singular | F_singular_known;
  1401. return make_invalid();
  1402. }
  1403. scale = 1.0f / scale;
  1404. quat.invert_in_place();
  1405. rotate = -rotate;
  1406. LVecBase3 mp = quat.xform(-LVecBase3(pos[0], pos[1], 0.0f));
  1407. pos = LVecBase2(mp[0], mp[1]) * scale;
  1408. LVecBase2 new_scale(scale, scale);
  1409. // Now compose the inverted transform with the other transform.
  1410. if (!other->is_identity()) {
  1411. LPoint3 op = quat.xform(other->get_pos());
  1412. pos += LVecBase2(op[0], op[1]) * scale;
  1413. rotate += other->get_rotate2d();
  1414. new_scale = other->get_scale2d() * scale;
  1415. }
  1416. result = make_pos_rotate_scale2d(pos, rotate, new_scale);
  1417. } else {
  1418. // Do a normal, 3-d invert compose.
  1419. LVecBase3 pos = get_pos();
  1420. LQuaternion quat = get_norm_quat();
  1421. PN_stdfloat scale = get_uniform_scale();
  1422. // First, invert our own transform.
  1423. if (scale == 0.0f) {
  1424. ((TransformState *)this)->_flags |= F_is_singular | F_singular_known;
  1425. return make_invalid();
  1426. }
  1427. scale = 1.0f / scale;
  1428. quat.invert_in_place();
  1429. pos = quat.xform(-pos) * scale;
  1430. LVecBase3 new_scale(scale, scale, scale);
  1431. // Now compose the inverted transform with the other transform.
  1432. if (!other->is_identity()) {
  1433. pos += quat.xform(other->get_pos()) * scale;
  1434. quat = other->get_norm_quat() * quat;
  1435. new_scale = other->get_scale() * scale;
  1436. }
  1437. result = make_pos_quat_scale(pos, quat, new_scale);
  1438. }
  1439. #ifndef NDEBUG
  1440. if (paranoid_compose) {
  1441. // Now verify against the matrix.
  1442. if (is_singular()) {
  1443. pgraph_cat.warning()
  1444. << "Unexpected singular matrix found for " << *this << "\n";
  1445. } else {
  1446. nassertr(_inv_mat != nullptr, make_invalid());
  1447. LMatrix4 new_mat;
  1448. new_mat.multiply(other->get_mat(), *_inv_mat);
  1449. if (!new_mat.almost_equal(result->get_mat(), 0.1)) {
  1450. CPT(TransformState) correct = make_mat(new_mat);
  1451. pgraph_cat.warning()
  1452. << "Componentwise invert-composition of " << *this << " and " << *other
  1453. << " produced:\n"
  1454. << *result << "\n instead of:\n" << *correct << "\n";
  1455. result = correct;
  1456. }
  1457. }
  1458. }
  1459. #endif // NDEBUG
  1460. return result;
  1461. }
  1462. if (is_singular()) {
  1463. return make_invalid();
  1464. }
  1465. // Now that is_singular() has returned false, we can assume that _inv_mat
  1466. // has been allocated and filled in.
  1467. nassertr(_inv_mat != nullptr, make_invalid());
  1468. if (is_2d() && other->is_2d()) {
  1469. const LMatrix4 &i = *_inv_mat;
  1470. LMatrix3 inv3(i(0, 0), i(0, 1), i(0, 3),
  1471. i(1, 0), i(1, 1), i(1, 3),
  1472. i(3, 0), i(3, 1), i(3, 3));
  1473. if (other->is_identity()) {
  1474. return make_mat3(inv3);
  1475. } else {
  1476. return make_mat3(other->get_mat3() * inv3);
  1477. }
  1478. } else {
  1479. if (other->is_identity()) {
  1480. return make_mat(*_inv_mat);
  1481. } else {
  1482. return make_mat(other->get_mat() * (*_inv_mat));
  1483. }
  1484. }
  1485. }
  1486. /**
  1487. * Detects whether there is a cycle in the cache that begins with this state.
  1488. * If any are detected, breaks them by removing this state from the cache.
  1489. */
  1490. void TransformState::
  1491. detect_and_break_cycles() {
  1492. PStatTimer timer(_transform_break_cycles_pcollector);
  1493. ++_last_cycle_detect;
  1494. if (r_detect_cycles(this, this, 1, _last_cycle_detect, nullptr)) {
  1495. // Ok, we have a cycle. This will be a leak unless we break the cycle by
  1496. // freeing the cache on this object.
  1497. if (pgraph_cat.is_debug()) {
  1498. pgraph_cat.debug()
  1499. << "Breaking cycle involving " << (*this) << "\n";
  1500. }
  1501. remove_cache_pointers();
  1502. } else {
  1503. ++_last_cycle_detect;
  1504. if (r_detect_reverse_cycles(this, this, 1, _last_cycle_detect, nullptr)) {
  1505. if (pgraph_cat.is_debug()) {
  1506. pgraph_cat.debug()
  1507. << "Breaking cycle involving " << (*this) << "\n";
  1508. }
  1509. remove_cache_pointers();
  1510. }
  1511. }
  1512. }
  1513. /**
  1514. * Detects whether there is a cycle in the cache that begins with the
  1515. * indicated state. Returns true if at least one cycle is found, false if
  1516. * this state is not part of any cycles. If a cycle is found and cycle_desc
  1517. * is not NULL, then cycle_desc is filled in with the list of the steps of the
  1518. * cycle, in reverse order.
  1519. */
  1520. bool TransformState::
  1521. r_detect_cycles(const TransformState *start_state,
  1522. const TransformState *current_state,
  1523. int length, UpdateSeq this_seq,
  1524. TransformState::CompositionCycleDesc *cycle_desc) {
  1525. if (current_state->_cycle_detect == this_seq) {
  1526. // We've already seen this state; therefore, we've found a cycle.
  1527. // However, we only care about cycles that return to the starting state
  1528. // and involve more than two steps. If only one or two nodes are
  1529. // involved, it doesn't represent a memory leak, so no problem there.
  1530. return (current_state == start_state && length > 2);
  1531. }
  1532. ((TransformState *)current_state)->_cycle_detect = this_seq;
  1533. size_t i;
  1534. size_t cache_size = current_state->_composition_cache.get_num_entries();
  1535. for (i = 0; i < cache_size; ++i) {
  1536. const TransformState *result = current_state->_composition_cache.get_data(i)._result;
  1537. if (result != nullptr) {
  1538. if (r_detect_cycles(start_state, result, length + 1,
  1539. this_seq, cycle_desc)) {
  1540. // Cycle detected.
  1541. if (cycle_desc != nullptr) {
  1542. const TransformState *other = current_state->_composition_cache.get_key(i);
  1543. CompositionCycleDescEntry entry(other, result, false);
  1544. cycle_desc->push_back(entry);
  1545. }
  1546. return true;
  1547. }
  1548. }
  1549. }
  1550. cache_size = current_state->_invert_composition_cache.get_num_entries();
  1551. for (i = 0; i < cache_size; ++i) {
  1552. const TransformState *result = current_state->_invert_composition_cache.get_data(i)._result;
  1553. if (result != nullptr) {
  1554. if (r_detect_cycles(start_state, result, length + 1,
  1555. this_seq, cycle_desc)) {
  1556. // Cycle detected.
  1557. if (cycle_desc != nullptr) {
  1558. const TransformState *other = current_state->_invert_composition_cache.get_key(i);
  1559. CompositionCycleDescEntry entry(other, result, true);
  1560. cycle_desc->push_back(entry);
  1561. }
  1562. return true;
  1563. }
  1564. }
  1565. }
  1566. // No cycle detected.
  1567. return false;
  1568. }
  1569. /**
  1570. * Works the same as r_detect_cycles, but checks for cycles in the reverse
  1571. * direction along the cache chain. (A cycle may appear in either direction,
  1572. * and we must check both.)
  1573. */
  1574. bool TransformState::
  1575. r_detect_reverse_cycles(const TransformState *start_state,
  1576. const TransformState *current_state,
  1577. int length, UpdateSeq this_seq,
  1578. TransformState::CompositionCycleDesc *cycle_desc) {
  1579. if (current_state->_cycle_detect == this_seq) {
  1580. // We've already seen this state; therefore, we've found a cycle.
  1581. // However, we only care about cycles that return to the starting state
  1582. // and involve more than two steps. If only one or two nodes are
  1583. // involved, it doesn't represent a memory leak, so no problem there.
  1584. return (current_state == start_state && length > 2);
  1585. }
  1586. ((TransformState *)current_state)->_cycle_detect = this_seq;
  1587. size_t i;
  1588. size_t cache_size = current_state->_composition_cache.get_num_entries();
  1589. for (i = 0; i < cache_size; ++i) {
  1590. const TransformState *other = current_state->_composition_cache.get_key(i);
  1591. if (other != current_state) {
  1592. int oi = other->_composition_cache.find(current_state);
  1593. nassertr(oi != -1, false);
  1594. const TransformState *result = other->_composition_cache.get_data(oi)._result;
  1595. if (result != nullptr) {
  1596. if (r_detect_reverse_cycles(start_state, result, length + 1,
  1597. this_seq, cycle_desc)) {
  1598. // Cycle detected.
  1599. if (cycle_desc != nullptr) {
  1600. const TransformState *other = current_state->_composition_cache.get_key(i);
  1601. CompositionCycleDescEntry entry(other, result, false);
  1602. cycle_desc->push_back(entry);
  1603. }
  1604. return true;
  1605. }
  1606. }
  1607. }
  1608. }
  1609. cache_size = current_state->_invert_composition_cache.get_num_entries();
  1610. for (i = 0; i < cache_size; ++i) {
  1611. const TransformState *other = current_state->_invert_composition_cache.get_key(i);
  1612. if (other != current_state) {
  1613. int oi = other->_invert_composition_cache.find(current_state);
  1614. nassertr(oi != -1, false);
  1615. const TransformState *result = other->_invert_composition_cache.get_data(oi)._result;
  1616. if (result != nullptr) {
  1617. if (r_detect_reverse_cycles(start_state, result, length + 1,
  1618. this_seq, cycle_desc)) {
  1619. // Cycle detected.
  1620. if (cycle_desc != nullptr) {
  1621. const TransformState *other = current_state->_invert_composition_cache.get_key(i);
  1622. CompositionCycleDescEntry entry(other, result, false);
  1623. cycle_desc->push_back(entry);
  1624. }
  1625. return true;
  1626. }
  1627. }
  1628. }
  1629. }
  1630. // No cycle detected.
  1631. return false;
  1632. }
  1633. /**
  1634. * This inverse of return_new, this releases this object from the global
  1635. * TransformState table.
  1636. *
  1637. * You must already be holding _states_lock before you call this method.
  1638. */
  1639. void TransformState::
  1640. release_new() {
  1641. nassertv(_states_lock->debug_is_locked());
  1642. if (_saved_entry != -1) {
  1643. _saved_entry = -1;
  1644. nassertv_always(_states.remove(this));
  1645. }
  1646. }
  1647. /**
  1648. * Remove all pointers within the cache from and to this particular
  1649. * TransformState. The pointers to this object may be scattered around in the
  1650. * various CompositionCaches from other TransformState objects.
  1651. *
  1652. * You must already be holding _states_lock before you call this method.
  1653. */
  1654. void TransformState::
  1655. remove_cache_pointers() {
  1656. nassertv(_states_lock->debug_is_locked());
  1657. // Fortunately, since we added CompositionCache records in pairs, we know
  1658. // exactly the set of TransformState objects that have us in their cache:
  1659. // it's the same set of TransformState objects that we have in our own
  1660. // cache.
  1661. /*
  1662. * We do need to put considerable thought into this loop, because as we clear
  1663. * out cache entries we'll cause other TransformState objects to destruct,
  1664. * which could cause things to get pulled out of our own _composition_cache
  1665. * map. We want to allow this (so that we don't encounter any just-destructed
  1666. * pointers in our cache), but we don't want to get bitten by this cascading
  1667. * effect. Instead of walking through the map from beginning to end,
  1668. * therefore, we just pull out the first one each time, and erase it.
  1669. */
  1670. #ifdef DO_PSTATS
  1671. if (_composition_cache.is_empty() && _invert_composition_cache.is_empty()) {
  1672. return;
  1673. }
  1674. PStatTimer timer(_cache_update_pcollector);
  1675. #endif // DO_PSTATS
  1676. // There are lots of ways to do this loop wrong. Be very careful if you
  1677. // need to modify it for any reason.
  1678. size_t i = 0;
  1679. while (!_composition_cache.is_empty()) {
  1680. // It is possible that the "other" TransformState object is currently
  1681. // within its own destructor. We therefore can't use a PT() to hold its
  1682. // pointer; that could end up calling its destructor twice. Fortunately,
  1683. // we don't need to hold its reference count to ensure it doesn't destruct
  1684. // while we process this loop; as long as we ensure that no *other*
  1685. // TransformState objects destruct, there will be no reason for that one
  1686. // to.
  1687. TransformState *other = (TransformState *)_composition_cache.get_key(i);
  1688. // We hold a copy of the composition result so we can dereference it
  1689. // later.
  1690. Composition comp = _composition_cache.get_data(i);
  1691. // Now we can remove the element from our cache. We do this now, rather
  1692. // than later, before any other TransformState objects have had a chance
  1693. // to destruct, so we are confident that our iterator is still valid.
  1694. _composition_cache.remove_element(i);
  1695. _cache_stats.add_total_size(-1);
  1696. _cache_stats.inc_dels();
  1697. if (other != this) {
  1698. int oi = other->_composition_cache.find(this);
  1699. // We may or may not still be listed in the other's cache (it might be
  1700. // halfway through pulling entries out, from within its own destructor).
  1701. if (oi != -1) {
  1702. // Hold a copy of the other composition result, too.
  1703. Composition ocomp = other->_composition_cache.get_data(oi);
  1704. other->_composition_cache.remove_element(oi);
  1705. _cache_stats.add_total_size(-1);
  1706. _cache_stats.inc_dels();
  1707. // It's finally safe to let our held pointers go away. This may have
  1708. // cascading effects as other TransformState objects are destructed,
  1709. // but there will be no harm done if they destruct now.
  1710. if (ocomp._result != nullptr && ocomp._result != other) {
  1711. cache_unref_delete(ocomp._result);
  1712. }
  1713. }
  1714. }
  1715. // It's finally safe to let our held pointers go away. (See comment
  1716. // above.)
  1717. if (comp._result != nullptr && comp._result != this) {
  1718. cache_unref_delete(comp._result);
  1719. }
  1720. }
  1721. // A similar bit of code for the invert cache.
  1722. i = 0;
  1723. while (!_invert_composition_cache.is_empty()) {
  1724. TransformState *other = (TransformState *)_invert_composition_cache.get_key(i);
  1725. nassertv(other != this);
  1726. Composition comp = _invert_composition_cache.get_data(i);
  1727. _invert_composition_cache.remove_element(i);
  1728. _cache_stats.add_total_size(-1);
  1729. _cache_stats.inc_dels();
  1730. if (other != this) {
  1731. int oi = other->_invert_composition_cache.find(this);
  1732. if (oi != -1) {
  1733. Composition ocomp = other->_invert_composition_cache.get_data(oi);
  1734. other->_invert_composition_cache.remove_element(oi);
  1735. _cache_stats.add_total_size(-1);
  1736. _cache_stats.inc_dels();
  1737. if (ocomp._result != nullptr && ocomp._result != other) {
  1738. cache_unref_delete(ocomp._result);
  1739. }
  1740. }
  1741. }
  1742. if (comp._result != nullptr && comp._result != this) {
  1743. cache_unref_delete(comp._result);
  1744. }
  1745. }
  1746. }
  1747. /**
  1748. * Computes a suitable hash value for phash_map.
  1749. */
  1750. void TransformState::
  1751. do_calc_hash() {
  1752. PStatTimer timer(_transform_hash_pcollector);
  1753. _hash = 0;
  1754. static const int significant_flags =
  1755. (F_is_invalid | F_is_identity | F_components_given | F_hpr_given | F_is_2d);
  1756. int flags = (_flags & significant_flags);
  1757. _hash = int_hash::add_hash(_hash, flags);
  1758. if ((_flags & (F_is_invalid | F_is_identity)) == 0) {
  1759. // Only bother to put the rest of the stuff in the hash if the transform
  1760. // is not invalid or empty.
  1761. if ((_flags & F_components_given) != 0) {
  1762. // If the transform was specified componentwise, hash it componentwise.
  1763. _hash = _pos.add_hash(_hash);
  1764. if ((_flags & F_hpr_given) != 0) {
  1765. _hash = _hpr.add_hash(_hash);
  1766. } else if ((_flags & F_quat_given) != 0) {
  1767. _hash = _quat.add_hash(_hash);
  1768. }
  1769. _hash = _scale.add_hash(_hash);
  1770. _hash = _shear.add_hash(_hash);
  1771. } else {
  1772. // Otherwise, hash the matrix . . .
  1773. if (_uniquify_matrix) {
  1774. // . . . but only if the user thinks that's worthwhile.
  1775. if ((_flags & F_mat_known) == 0) {
  1776. // Calculate the matrix without doubly-locking.
  1777. do_calc_mat();
  1778. }
  1779. _hash = _mat.add_hash(_hash);
  1780. } else {
  1781. // Otherwise, hash the pointer only--any two different matrix-based
  1782. // TransformStates are considered to be different, even if their
  1783. // matrices have the same values.
  1784. _hash = pointer_hash::add_hash(_hash, this);
  1785. }
  1786. }
  1787. }
  1788. _flags |= F_hash_known;
  1789. }
  1790. /**
  1791. * Determines whether the transform is singular (i.e. it scales to zero, and
  1792. * has no inverse).
  1793. */
  1794. void TransformState::
  1795. calc_singular() {
  1796. LightMutexHolder holder(_lock);
  1797. if ((_flags & F_singular_known) != 0) {
  1798. // Someone else computed it first.
  1799. return;
  1800. }
  1801. PStatTimer timer(_transform_calc_pcollector);
  1802. nassertv((_flags & F_is_invalid) == 0);
  1803. // We determine if a matrix is singular by attempting to invert it (and we
  1804. // save the result of this invert operation for a subsequent
  1805. // do_invert_compose() call, which is almost certain to be made if someone
  1806. // is asking whether we're singular).
  1807. // This should be NULL if no one has called calc_singular() yet.
  1808. nassertv(_inv_mat == nullptr);
  1809. _inv_mat = new LMatrix4;
  1810. if ((_flags & F_mat_known) == 0) {
  1811. do_calc_mat();
  1812. }
  1813. bool inverted = _inv_mat->invert_from(_mat);
  1814. if (!inverted) {
  1815. _flags |= F_is_singular;
  1816. delete _inv_mat;
  1817. _inv_mat = nullptr;
  1818. }
  1819. _flags |= F_singular_known;
  1820. }
  1821. /**
  1822. * This is the implementation of calc_components(); it assumes the lock is
  1823. * already held.
  1824. */
  1825. void TransformState::
  1826. do_calc_components() {
  1827. if ((_flags & F_components_known) != 0) {
  1828. // Someone else computed it first.
  1829. return;
  1830. }
  1831. PStatTimer timer(_transform_calc_pcollector);
  1832. nassertv((_flags & F_is_invalid) == 0);
  1833. if ((_flags & F_is_identity) != 0) {
  1834. _scale.set(1.0f, 1.0f, 1.0f);
  1835. _shear.set(0.0f, 0.0f, 0.0f);
  1836. _hpr.set(0.0f, 0.0f, 0.0f);
  1837. _quat = LQuaternion::ident_quat();
  1838. _pos.set(0.0f, 0.0f, 0.0f);
  1839. _flags |= F_has_components | F_components_known | F_hpr_known | F_quat_known | F_uniform_scale | F_identity_scale;
  1840. } else {
  1841. // If we don't have components and we're not identity, the only other
  1842. // explanation is that we were constructed via a matrix.
  1843. nassertv((_flags & F_mat_known) != 0);
  1844. if ((_flags & F_mat_known) == 0) {
  1845. do_calc_mat();
  1846. }
  1847. bool possible = decompose_matrix(_mat, _scale, _shear, _hpr, _pos);
  1848. if (!possible) {
  1849. // Some matrices can't be decomposed into scale, hpr, pos. In this
  1850. // case, we now know that we cannot compute the components; but the
  1851. // closest approximations are stored, at least.
  1852. _flags |= F_components_known | F_hpr_known;
  1853. } else {
  1854. // Otherwise, we do have the components, or at least the hpr.
  1855. _flags |= F_has_components | F_components_known | F_hpr_known;
  1856. check_uniform_scale();
  1857. }
  1858. // However, we can always get at least the pos.
  1859. _mat.get_row3(_pos, 3);
  1860. }
  1861. }
  1862. /**
  1863. * This is the implementation of calc_hpr(); it assumes the lock is already
  1864. * held.
  1865. */
  1866. void TransformState::
  1867. do_calc_hpr() {
  1868. if ((_flags & F_hpr_known) != 0) {
  1869. // Someone else computed it first.
  1870. return;
  1871. }
  1872. PStatTimer timer(_transform_calc_pcollector);
  1873. nassertv((_flags & F_is_invalid) == 0);
  1874. if ((_flags & F_components_known) == 0) {
  1875. do_calc_components();
  1876. }
  1877. if ((_flags & F_hpr_known) == 0) {
  1878. // If we don't know the hpr yet, we must have been given a quat.
  1879. // Decompose it.
  1880. nassertv((_flags & F_quat_known) != 0);
  1881. _hpr = _quat.get_hpr();
  1882. _flags |= F_hpr_known;
  1883. }
  1884. }
  1885. /**
  1886. * Derives the quat from the hpr.
  1887. */
  1888. void TransformState::
  1889. calc_quat() {
  1890. LightMutexHolder holder(_lock);
  1891. if ((_flags & F_quat_known) != 0) {
  1892. // Someone else computed it first.
  1893. return;
  1894. }
  1895. PStatTimer timer(_transform_calc_pcollector);
  1896. nassertv((_flags & F_is_invalid) == 0);
  1897. if ((_flags & F_components_known) == 0) {
  1898. do_calc_components();
  1899. }
  1900. if ((_flags & F_quat_known) == 0) {
  1901. // If we don't know the quat yet, we must have been given a hpr.
  1902. // Decompose it.
  1903. nassertv((_flags & F_hpr_known) != 0);
  1904. _quat.set_hpr(_hpr);
  1905. _flags |= F_quat_known;
  1906. }
  1907. }
  1908. /**
  1909. * Derives the normalized quat from the quat.
  1910. */
  1911. void TransformState::
  1912. calc_norm_quat() {
  1913. PStatTimer timer(_transform_calc_pcollector);
  1914. LQuaternion quat = get_quat();
  1915. LightMutexHolder holder(_lock);
  1916. _norm_quat = quat;
  1917. _norm_quat.normalize();
  1918. _flags |= F_norm_quat_known;
  1919. }
  1920. /**
  1921. * This is the implementation of calc_mat(); it assumes the lock is already
  1922. * held.
  1923. */
  1924. void TransformState::
  1925. do_calc_mat() {
  1926. if ((_flags & F_mat_known) != 0) {
  1927. // Someone else computed it first.
  1928. return;
  1929. }
  1930. PStatTimer timer(_transform_calc_pcollector);
  1931. nassertv((_flags & F_is_invalid) == 0);
  1932. if ((_flags & F_is_identity) != 0) {
  1933. _mat = LMatrix4::ident_mat();
  1934. } else {
  1935. // If we don't have a matrix and we're not identity, the only other
  1936. // explanation is that we were constructed via components.
  1937. nassertv((_flags & F_components_known) != 0);
  1938. if ((_flags & F_hpr_known) == 0) {
  1939. do_calc_hpr();
  1940. }
  1941. compose_matrix(_mat, _scale, _shear, get_hpr(), _pos);
  1942. }
  1943. _flags |= F_mat_known;
  1944. }
  1945. /**
  1946. * Moves the TransformState object from one PStats category to another, so
  1947. * that we can track in PStats how many pointers are held by nodes, and how
  1948. * many are held in the cache only.
  1949. */
  1950. void TransformState::
  1951. update_pstats(int old_referenced_bits, int new_referenced_bits) {
  1952. #ifdef DO_PSTATS
  1953. if ((old_referenced_bits & R_node) != 0) {
  1954. _node_counter.sub_level(1);
  1955. } else if ((old_referenced_bits & R_cache) != 0) {
  1956. _cache_counter.sub_level(1);
  1957. }
  1958. if ((new_referenced_bits & R_node) != 0) {
  1959. _node_counter.add_level(1);
  1960. } else if ((new_referenced_bits & R_cache) != 0) {
  1961. _cache_counter.add_level(1);
  1962. }
  1963. #endif // DO_PSTATS
  1964. }
  1965. /**
  1966. * Tells the BamReader how to create objects of type TransformState.
  1967. */
  1968. void TransformState::
  1969. register_with_read_factory() {
  1970. BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
  1971. }
  1972. /**
  1973. * Writes the contents of this object to the datagram for shipping out to a
  1974. * Bam file.
  1975. */
  1976. void TransformState::
  1977. write_datagram(BamWriter *manager, Datagram &dg) {
  1978. TypedWritable::write_datagram(manager, dg);
  1979. if ((_flags & F_is_identity) != 0) {
  1980. // Identity, nothing much to that.
  1981. int flags = F_is_identity | F_singular_known | F_is_2d;
  1982. dg.add_uint32(flags);
  1983. } else if ((_flags & F_is_invalid) != 0) {
  1984. // Invalid, nothing much to that either.
  1985. int flags = F_is_invalid | F_singular_known | F_is_singular | F_components_known | F_mat_known;
  1986. dg.add_uint32(flags);
  1987. } else if ((_flags & F_components_given) != 0) {
  1988. // A component-based transform.
  1989. int flags = F_components_given | F_components_known | F_has_components;
  1990. flags |= (_flags & F_is_2d);
  1991. if ((_flags & F_quat_given) != 0) {
  1992. flags |= (F_quat_given | F_quat_known);
  1993. } else if ((_flags & F_hpr_given) != 0) {
  1994. flags |= (F_hpr_given | F_hpr_known);
  1995. }
  1996. dg.add_uint32(flags);
  1997. _pos.write_datagram(dg);
  1998. if ((_flags & F_quat_given) != 0) {
  1999. _quat.write_datagram(dg);
  2000. } else {
  2001. get_hpr().write_datagram(dg);
  2002. }
  2003. _scale.write_datagram(dg);
  2004. _shear.write_datagram(dg);
  2005. } else {
  2006. // A general matrix.
  2007. nassertv((_flags & F_mat_known) != 0);
  2008. int flags = F_mat_known;
  2009. flags |= (_flags & F_is_2d);
  2010. dg.add_uint32(flags);
  2011. _mat.write_datagram(dg);
  2012. }
  2013. }
  2014. /**
  2015. * Called immediately after complete_pointers(), this gives the object a
  2016. * chance to adjust its own pointer if desired. Most objects don't change
  2017. * pointers after completion, but some need to.
  2018. *
  2019. * Once this function has been called, the old pointer will no longer be
  2020. * accessed.
  2021. */
  2022. PT(TypedWritableReferenceCount) TransformState::
  2023. change_this(TypedWritableReferenceCount *old_ptr, BamReader *manager) {
  2024. // First, uniquify the pointer.
  2025. TransformState *state = DCAST(TransformState, old_ptr);
  2026. CPT(TransformState) pointer = return_unique(state);
  2027. // We have to cast the pointer back to non-const, because the bam reader
  2028. // expects that.
  2029. return (TransformState *)pointer.p();
  2030. }
  2031. /**
  2032. * This function is called by the BamReader's factory when a new object of
  2033. * type TransformState is encountered in the Bam file. It should create the
  2034. * TransformState and extract its information from the file.
  2035. */
  2036. TypedWritable *TransformState::
  2037. make_from_bam(const FactoryParams &params) {
  2038. TransformState *state = new TransformState;
  2039. DatagramIterator scan;
  2040. BamReader *manager;
  2041. parse_params(params, scan, manager);
  2042. state->fillin(scan, manager);
  2043. manager->register_change_this(change_this, state);
  2044. return state;
  2045. }
  2046. /**
  2047. * This internal function is called by make_from_bam to read in all of the
  2048. * relevant data from the BamFile for the new TransformState.
  2049. */
  2050. void TransformState::
  2051. fillin(DatagramIterator &scan, BamReader *manager) {
  2052. TypedWritable::fillin(scan, manager);
  2053. _flags = scan.get_uint32();
  2054. if ((_flags & F_components_given) != 0) {
  2055. // Componentwise transform.
  2056. _pos.read_datagram(scan);
  2057. if ((_flags & F_quat_given) != 0) {
  2058. _quat.read_datagram(scan);
  2059. } else {
  2060. _hpr.read_datagram(scan);
  2061. }
  2062. _scale.read_datagram(scan);
  2063. _shear.read_datagram(scan);
  2064. check_uniform_scale();
  2065. }
  2066. if ((_flags & F_mat_known) != 0) {
  2067. // General matrix.
  2068. _mat.read_datagram(scan);
  2069. }
  2070. }