transformState.cxx 75 KB

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