scene_graph.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /*
  2. * Copyright (c) 2012-2016 Daniele Bartolini and individual contributors.
  3. * License: https://github.com/taylor001/crown/blob/master/LICENSE
  4. */
  5. #include "allocator.h"
  6. #include "array.h"
  7. #include "hash.h"
  8. #include "matrix3x3.h"
  9. #include "matrix4x4.h"
  10. #include "quaternion.h"
  11. #include "scene_graph.h"
  12. #include "vector3.h"
  13. #include <stdint.h> // UINT_MAX
  14. #include <string.h> // memcpy
  15. namespace crown
  16. {
  17. SceneGraph::Pose& SceneGraph::Pose::operator=(const Matrix4x4& m)
  18. {
  19. Matrix3x3 rotm = to_matrix3x3(m);
  20. normalize(rotm.x);
  21. normalize(rotm.y);
  22. normalize(rotm.z);
  23. position = translation(m);
  24. rotation = rotm;
  25. scale = crown::scale(m);
  26. return *this;
  27. }
  28. SceneGraph::SceneGraph(Allocator& a)
  29. : _marker(MARKER)
  30. , _allocator(a)
  31. , _map(a)
  32. {
  33. }
  34. SceneGraph::~SceneGraph()
  35. {
  36. _allocator.deallocate(_data.buffer);
  37. _marker = 0;
  38. }
  39. TransformInstance SceneGraph::make_instance(u32 i)
  40. {
  41. TransformInstance inst = { i };
  42. return inst;
  43. }
  44. void SceneGraph::allocate(u32 num)
  45. {
  46. CE_ASSERT(num > _data.size, "num > _data.size");
  47. const u32 bytes = num * (0
  48. + sizeof(UnitId)
  49. + sizeof(Matrix4x4)
  50. + sizeof(Pose)
  51. + sizeof(TransformInstance) * 4
  52. + sizeof(bool)
  53. );
  54. InstanceData new_data;
  55. new_data.size = _data.size;
  56. new_data.capacity = num;
  57. new_data.buffer = _allocator.allocate(bytes);
  58. new_data.unit = (UnitId*)(new_data.buffer);
  59. new_data.world = (Matrix4x4*)(new_data.unit + num);
  60. new_data.local = (Pose*)(new_data.world + num);
  61. new_data.parent = (TransformInstance*)(new_data.local + num);
  62. new_data.first_child = (TransformInstance*)(new_data.parent + num);
  63. new_data.next_sibling = (TransformInstance*)(new_data.first_child + num);
  64. new_data.prev_sibling = (TransformInstance*)(new_data.next_sibling + num);
  65. new_data.changed = (bool*)(new_data.prev_sibling + num);
  66. memcpy(new_data.unit, _data.unit, _data.size * sizeof(UnitId));
  67. memcpy(new_data.world, _data.world, _data.size * sizeof(Matrix4x4));
  68. memcpy(new_data.local, _data.local, _data.size * sizeof(Pose));
  69. memcpy(new_data.parent, _data.parent, _data.size * sizeof(TransformInstance));
  70. memcpy(new_data.first_child, _data.first_child, _data.size * sizeof(TransformInstance));
  71. memcpy(new_data.next_sibling, _data.next_sibling, _data.size * sizeof(TransformInstance));
  72. memcpy(new_data.prev_sibling, _data.prev_sibling, _data.size * sizeof(TransformInstance));
  73. memcpy(new_data.changed, _data.changed, _data.size * sizeof(bool));
  74. _allocator.deallocate(_data.buffer);
  75. _data = new_data;
  76. }
  77. TransformInstance SceneGraph::create(UnitId id, const Vector3& pos, const Quaternion& rot, const Vector3& scale)
  78. {
  79. Matrix4x4 pose;
  80. set_identity(pose);
  81. set_translation(pose, pos);
  82. set_rotation(pose, rot);
  83. set_scale(pose, scale);
  84. return create(id, pose);
  85. }
  86. TransformInstance SceneGraph::create(UnitId id, const Matrix4x4& pose)
  87. {
  88. CE_ASSERT(!hash::has(_map, id.encode()), "Unit already has transform");
  89. if (_data.capacity == _data.size)
  90. grow();
  91. const u32 last = _data.size;
  92. _data.unit[last] = id;
  93. _data.world[last] = pose;
  94. _data.local[last] = pose;
  95. _data.parent[last].i = UINT32_MAX;
  96. _data.first_child[last].i = UINT32_MAX;
  97. _data.next_sibling[last].i = UINT32_MAX;
  98. _data.prev_sibling[last].i = UINT32_MAX;
  99. _data.changed[last] = false;
  100. ++_data.size;
  101. hash::set(_map, id.encode(), last);
  102. return make_instance(last);
  103. }
  104. void SceneGraph::destroy(TransformInstance i)
  105. {
  106. const u32 last = _data.size - 1;
  107. const UnitId u = _data.unit[i.i];
  108. const UnitId last_u = _data.unit[last];
  109. _data.unit[i.i] = _data.unit[last];
  110. _data.world[i.i] = _data.world[last];
  111. _data.local[i.i] = _data.local[last];
  112. _data.parent[i.i] = _data.parent[last];
  113. _data.first_child[i.i] = _data.first_child[last];
  114. _data.next_sibling[i.i] = _data.next_sibling[last];
  115. _data.prev_sibling[i.i] = _data.prev_sibling[last];
  116. _data.changed[i.i] = _data.changed[last];
  117. hash::set(_map, last_u.encode(), i.i);
  118. hash::remove(_map, u.encode());
  119. --_data.size;
  120. }
  121. TransformInstance SceneGraph::get(UnitId id)
  122. {
  123. return make_instance(hash::get(_map, id.encode(), UINT32_MAX));
  124. }
  125. void SceneGraph::set_local_position(TransformInstance i, const Vector3& pos)
  126. {
  127. _data.local[i.i].position = pos;
  128. set_local(i);
  129. }
  130. void SceneGraph::set_local_rotation(TransformInstance i, const Quaternion& rot)
  131. {
  132. _data.local[i.i].rotation = matrix3x3(rot);
  133. set_local(i);
  134. }
  135. void SceneGraph::set_local_scale(TransformInstance i, const Vector3& scale)
  136. {
  137. _data.local[i.i].scale = scale;
  138. set_local(i);
  139. }
  140. void SceneGraph::set_local_pose(TransformInstance i, const Matrix4x4& pose)
  141. {
  142. _data.local[i.i] = pose;
  143. set_local(i);
  144. }
  145. Vector3 SceneGraph::local_position(TransformInstance i) const
  146. {
  147. return _data.local[i.i].position;
  148. }
  149. Quaternion SceneGraph::local_rotation(TransformInstance i) const
  150. {
  151. return quaternion(_data.local[i.i].rotation);
  152. }
  153. Vector3 SceneGraph::local_scale(TransformInstance i) const
  154. {
  155. return _data.local[i.i].scale;
  156. }
  157. Matrix4x4 SceneGraph::local_pose(TransformInstance i) const
  158. {
  159. Matrix4x4 tr = matrix4x4(quaternion(_data.local[i.i].rotation), _data.local[i.i].position);
  160. set_scale(tr, _data.local[i.i].scale);
  161. return tr;
  162. }
  163. Vector3 SceneGraph::world_position(TransformInstance i) const
  164. {
  165. return translation(_data.world[i.i]);
  166. }
  167. Quaternion SceneGraph::world_rotation(TransformInstance i) const
  168. {
  169. return rotation(_data.world[i.i]);
  170. }
  171. Matrix4x4 SceneGraph::world_pose(TransformInstance i) const
  172. {
  173. return _data.world[i.i];
  174. }
  175. void SceneGraph::set_world_pose(TransformInstance i, const Matrix4x4& pose)
  176. {
  177. _data.world[i.i] = pose;
  178. _data.changed[i.i] = true;
  179. }
  180. u32 SceneGraph::num_nodes() const
  181. {
  182. return _data.size;
  183. }
  184. void SceneGraph::link(TransformInstance child, TransformInstance parent)
  185. {
  186. unlink(child);
  187. if (!is_valid(_data.first_child[parent.i]))
  188. {
  189. _data.first_child[parent.i] = child;
  190. _data.parent[child.i] = parent;
  191. }
  192. else
  193. {
  194. TransformInstance prev = { UINT32_MAX };
  195. TransformInstance node = _data.first_child[parent.i];
  196. while (is_valid(node))
  197. {
  198. prev = node;
  199. node = _data.next_sibling[node.i];
  200. }
  201. _data.next_sibling[prev.i] = child;
  202. _data.first_child[child.i].i = UINT32_MAX;
  203. _data.next_sibling[child.i].i = UINT32_MAX;
  204. _data.prev_sibling[child.i] = prev;
  205. }
  206. Matrix4x4 parent_tr = _data.world[parent.i];
  207. Matrix4x4 child_tr = _data.world[child.i];
  208. const Vector3 cs = scale(child_tr);
  209. Vector3 px = x(parent_tr);
  210. Vector3 py = y(parent_tr);
  211. Vector3 pz = z(parent_tr);
  212. Vector3 cx = x(child_tr);
  213. Vector3 cy = y(child_tr);
  214. Vector3 cz = z(child_tr);
  215. set_x(parent_tr, normalize(px));
  216. set_y(parent_tr, normalize(py));
  217. set_z(parent_tr, normalize(pz));
  218. set_x(child_tr, normalize(cx));
  219. set_y(child_tr, normalize(cy));
  220. set_z(child_tr, normalize(cz));
  221. const Matrix4x4 rel_tr = child_tr * get_inverted(parent_tr);
  222. _data.local[child.i].position = translation(rel_tr);
  223. _data.local[child.i].rotation = to_matrix3x3(rel_tr);
  224. _data.local[child.i].scale = cs;
  225. _data.parent[child.i] = parent;
  226. transform(parent_tr, child);
  227. }
  228. void SceneGraph::unlink(TransformInstance child)
  229. {
  230. if (!is_valid(_data.parent[child.i]))
  231. return;
  232. if (!is_valid(_data.prev_sibling[child.i]))
  233. _data.first_child[_data.parent[child.i].i] = _data.next_sibling[child.i];
  234. else
  235. _data.next_sibling[_data.prev_sibling[child.i].i] = _data.next_sibling[child.i];
  236. if (is_valid(_data.next_sibling[child.i]))
  237. _data.prev_sibling[_data.next_sibling[child.i].i] = _data.prev_sibling[child.i];
  238. _data.parent[child.i].i = UINT32_MAX;
  239. _data.next_sibling[child.i].i = UINT32_MAX;
  240. _data.prev_sibling[child.i].i = UINT32_MAX;
  241. }
  242. void SceneGraph::clear_changed()
  243. {
  244. for (u32 i = 0; i < _data.size; ++i)
  245. {
  246. _data.changed[i] = false;
  247. }
  248. }
  249. void SceneGraph::get_changed(Array<UnitId>& units, Array<Matrix4x4>& world_poses)
  250. {
  251. for (u32 i = 0; i < _data.size; ++i)
  252. {
  253. if (_data.changed[i])
  254. {
  255. array::push_back(units, _data.unit[i]);
  256. array::push_back(world_poses, _data.world[i]);
  257. }
  258. }
  259. }
  260. bool SceneGraph::is_valid(TransformInstance i)
  261. {
  262. return i.i != UINT32_MAX;
  263. }
  264. void SceneGraph::set_local(TransformInstance i)
  265. {
  266. TransformInstance parent = _data.parent[i.i];
  267. Matrix4x4 parent_tm = is_valid(parent) ? _data.world[parent.i] : MATRIX4X4_IDENTITY;
  268. transform(parent_tm, i);
  269. _data.changed[i.i] = true;
  270. }
  271. void SceneGraph::transform(const Matrix4x4& parent, TransformInstance i)
  272. {
  273. _data.world[i.i] = local_pose(i) * parent;
  274. TransformInstance child = _data.first_child[i.i];
  275. while (is_valid(child))
  276. {
  277. transform(_data.world[i.i], child);
  278. child = _data.next_sibling[child.i];
  279. }
  280. }
  281. void SceneGraph::grow()
  282. {
  283. allocate(_data.capacity * 2 + 1);
  284. }
  285. } // namespace crown