scene_graph.cpp 7.1 KB

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