node.go 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587
  1. // Copyright 2016 The G3N Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package core
  5. import (
  6. "github.com/g3n/engine/gls"
  7. "github.com/g3n/engine/math32"
  8. "strings"
  9. )
  10. // INode is the interface for all node types.
  11. type INode interface {
  12. GetNode() *Node
  13. UpdateMatrixWorld()
  14. Raycast(*Raycaster, *[]Intersect)
  15. Render(gs *gls.GLS)
  16. Dispose()
  17. }
  18. // Node represents an object in 3D space existing within a hierarchy.
  19. type Node struct {
  20. Dispatcher // Embedded event dispatcher
  21. parent INode // Parent node
  22. children []INode // Children nodes
  23. name string // Optional node name
  24. loaderID string // ID used by loader
  25. visible bool // Whether the node is visible
  26. changed bool // Whether the position/orientation/scale changed
  27. userData interface{} // Generic user data
  28. // Spatial properties
  29. position math32.Vector3 // Node position in 3D space (relative to parent)
  30. scale math32.Vector3 // Node scale (relative to parent)
  31. direction math32.Vector3 // Initial direction (relative to parent)
  32. rotation math32.Vector3 // Node rotation specified in Euler angles (relative to parent)
  33. quaternion math32.Quaternion // Node rotation specified as a Quaternion (relative to parent)
  34. matrix math32.Matrix4 // Local transform matrix. Contains all position/rotation/scale information (relative to parent)
  35. matrixWorld math32.Matrix4 // World transform matrix. Contains all absolute position/rotation/scale information (i.e. relative to very top parent, generally the scene)
  36. }
  37. // NewNode returns a pointer to a new Node.
  38. func NewNode() *Node {
  39. n := new(Node)
  40. n.Init()
  41. return n
  42. }
  43. // Init initializes the node.
  44. // Normally called by other types which embed a Node.
  45. func (n *Node) Init() {
  46. n.Dispatcher.Initialize()
  47. n.children = make([]INode, 0)
  48. n.visible = true
  49. n.changed = true
  50. // Initialize spatial properties
  51. n.position.Set(0, 0, 0)
  52. n.scale.Set(1, 1, 1)
  53. n.direction.Set(0, 0, 1)
  54. n.rotation.Set(0, 0, 0)
  55. n.quaternion.Set(0, 0, 0, 1)
  56. n.matrix.Identity()
  57. n.matrixWorld.Identity()
  58. }
  59. // GetNode satisfies the INode interface
  60. // and returns a pointer to the embedded Node.
  61. func (n *Node) GetNode() *Node {
  62. return n
  63. }
  64. // Raycast satisfies the INode interface.
  65. func (n *Node) Raycast(rc *Raycaster, intersects *[]Intersect) {
  66. }
  67. // Render satisfies the INode interface.
  68. func (n *Node) Render(gs *gls.GLS) {
  69. }
  70. // Dispose satisfies the INode interface.
  71. func (n *Node) Dispose() {
  72. }
  73. // SetParent sets the parent.
  74. func (n *Node) SetParent(iparent INode) {
  75. n.parent = iparent
  76. }
  77. // Parent returns the parent.
  78. func (n *Node) Parent() INode {
  79. return n.parent
  80. }
  81. // SetName sets the (optional) name.
  82. // The name can be used for debugging or other purposes.
  83. func (n *Node) SetName(name string) {
  84. n.name = name
  85. }
  86. // Name returns the (optional) name.
  87. func (n *Node) Name() string {
  88. return n.name
  89. }
  90. // SetLoaderID is normally used by external loaders, such as Collada,
  91. // to assign an ID to the node with the ID value in the node description.
  92. // Can be used to find other loaded nodes.
  93. func (n *Node) SetLoaderID(id string) {
  94. n.loaderID = id
  95. }
  96. // LoaderID returns an optional ID set when this node was
  97. // created by an external loader such as Collada.
  98. func (n *Node) LoaderID() string {
  99. return n.loaderID
  100. }
  101. // SetVisible sets the visibility of the node.
  102. func (n *Node) SetVisible(state bool) {
  103. n.visible = state
  104. n.changed = true
  105. }
  106. // Visible returns the visibility of the node.
  107. func (n *Node) Visible() bool {
  108. return n.visible
  109. }
  110. // SetChanged sets the changed flag of the node.
  111. func (n *Node) SetChanged(changed bool) {
  112. n.changed = changed
  113. }
  114. // Changed returns the changed flag of the node.
  115. func (n *Node) Changed() bool {
  116. return n.changed
  117. }
  118. // SetUserData sets the generic user data associated to the node.
  119. func (n *Node) SetUserData(data interface{}) {
  120. n.userData = data
  121. }
  122. // UserData returns the generic user data associated to the node.
  123. func (n *Node) UserData() interface{} {
  124. return n.userData
  125. }
  126. // FindPath finds a node with the specified path starting with this node and
  127. // searching in all its children recursively.
  128. // A path is the sequence of the names from the first node to the desired node
  129. // separated by the forward slash.
  130. func (n *Node) FindPath(path string) INode {
  131. // Internal recursive function to find node
  132. var finder func(inode INode, path string) INode
  133. finder = func(inode INode, path string) INode {
  134. // Get first component of the path
  135. parts := strings.Split(path, "/")
  136. if len(parts) == 0 {
  137. return nil
  138. }
  139. first := parts[0]
  140. // Checks current node
  141. node := inode.GetNode()
  142. if node.name != first {
  143. return nil
  144. }
  145. // If the path has finished this is the desired node
  146. rest := strings.Join(parts[1:], "/")
  147. if rest == "" {
  148. return inode
  149. }
  150. // Otherwise search in this node children
  151. for _, ichild := range node.children {
  152. found := finder(ichild, rest)
  153. if found != nil {
  154. return found
  155. }
  156. }
  157. return nil
  158. }
  159. return finder(n, path)
  160. }
  161. // FindLoaderID looks in the specified node and in all its children
  162. // for a node with the specified loaderID and if found returns it.
  163. // Returns nil if not found.
  164. func (n *Node) FindLoaderID(id string) INode {
  165. var finder func(parent INode, id string) INode
  166. finder = func(parent INode, id string) INode {
  167. pnode := parent.GetNode()
  168. if pnode.loaderID == id {
  169. return parent
  170. }
  171. for _, child := range pnode.children {
  172. found := finder(child, id)
  173. if found != nil {
  174. return found
  175. }
  176. }
  177. return nil
  178. }
  179. return finder(n, id)
  180. }
  181. // Children returns the list of children.
  182. func (n *Node) Children() []INode {
  183. return n.children
  184. }
  185. // Add adds the specified INode to the list of children.
  186. func (n *Node) Add(ichild INode) *Node {
  187. child := ichild.GetNode()
  188. if n == child {
  189. panic("Node.Add: object can't be added as a child of itself")
  190. }
  191. // If this child already has a parent,
  192. // removes it from this parent children list
  193. if child.parent != nil {
  194. child.parent.GetNode().Remove(ichild)
  195. }
  196. child.parent = n
  197. n.children = append(n.children, ichild)
  198. return n
  199. }
  200. // Remove removes the specified INode from the list of children.
  201. // Returns true if found or false otherwise.
  202. func (n *Node) Remove(ichild INode) bool {
  203. for pos, current := range n.children {
  204. if current == ichild {
  205. copy(n.children[pos:], n.children[pos+1:])
  206. n.children[len(n.children)-1] = nil
  207. n.children = n.children[:len(n.children)-1]
  208. ichild.GetNode().parent = nil
  209. return true
  210. }
  211. }
  212. return false
  213. }
  214. // RemoveAll removes all children.
  215. func (n *Node) RemoveAll(recurs bool) {
  216. for pos, ichild := range n.children {
  217. n.children[pos] = nil
  218. ichild.GetNode().parent = nil
  219. if recurs {
  220. ichild.GetNode().RemoveAll(recurs)
  221. }
  222. }
  223. n.children = n.children[0:0]
  224. }
  225. // DisposeChildren removes and disposes of all children.
  226. // If 'recurs' is true, call DisposeChidren on each child recursively.
  227. func (n *Node) DisposeChildren(recurs bool) {
  228. for pos, ichild := range n.children {
  229. n.children[pos] = nil
  230. ichild.GetNode().parent = nil
  231. if recurs {
  232. ichild.GetNode().DisposeChildren(true)
  233. }
  234. ichild.Dispose()
  235. }
  236. n.children = n.children[0:0]
  237. }
  238. // SetPosition sets the position.
  239. func (n *Node) SetPosition(x, y, z float32) {
  240. n.position.Set(x, y, z)
  241. n.changed = true
  242. }
  243. // SetPositionVec sets the position based on the specified vector pointer.
  244. func (n *Node) SetPositionVec(vpos *math32.Vector3) {
  245. n.position = *vpos
  246. n.changed = true
  247. }
  248. // SetPositionX sets the X coordinate of the position.
  249. func (n *Node) SetPositionX(x float32) {
  250. n.position.X = x
  251. n.changed = true
  252. }
  253. // SetPositionY sets the Y coordinate of the position.
  254. func (n *Node) SetPositionY(y float32) {
  255. n.position.Y = y
  256. n.changed = true
  257. }
  258. // SetPositionZ sets the Z coordinate of the position.
  259. func (n *Node) SetPositionZ(z float32) {
  260. n.position.Z = z
  261. n.changed = true
  262. }
  263. // Position returns the position as a vector.
  264. func (n *Node) Position() math32.Vector3 {
  265. return n.position
  266. }
  267. // SetRotation sets the rotation in radians.
  268. // The stored quaternion is updated accordingly.
  269. func (n *Node) SetRotation(x, y, z float32) {
  270. n.rotation.Set(x, y, z)
  271. n.quaternion.SetFromEuler(&n.rotation)
  272. n.changed = true
  273. }
  274. // SetRotationVec sets the rotation in radians based on the specified vector pointer.
  275. // The stored quaternion is updated accordingly.
  276. func (n *Node) SetRotationVec(vrot *math32.Vector3) {
  277. n.rotation = *vrot
  278. n.quaternion.SetFromEuler(&n.rotation)
  279. n.changed = true
  280. }
  281. // SetRotationX sets the X rotation to the specified angle in radians.
  282. // The stored quaternion is updated accordingly.
  283. func (n *Node) SetRotationX(x float32) {
  284. n.rotation.X = x
  285. n.quaternion.SetFromEuler(&n.rotation)
  286. n.changed = true
  287. }
  288. // SetRotationY sets the Y rotation to the specified angle in radians.
  289. // The stored quaternion is updated accordingly.
  290. func (n *Node) SetRotationY(y float32) {
  291. n.rotation.Y = y
  292. n.quaternion.SetFromEuler(&n.rotation)
  293. n.changed = true
  294. }
  295. // SetRotationZ sets the Z rotation to the specified angle in radians.
  296. // The stored quaternion is updated accordingly.
  297. func (n *Node) SetRotationZ(z float32) {
  298. n.rotation.Z = z
  299. n.quaternion.SetFromEuler(&n.rotation)
  300. n.changed = true
  301. }
  302. // AddRotationX adds to the current X rotation the specified angle in radians.
  303. // The stored quaternion is updated accordingly.
  304. func (n *Node) AddRotationX(x float32) {
  305. n.rotation.X += x
  306. n.quaternion.SetFromEuler(&n.rotation)
  307. n.changed = true
  308. }
  309. // AddRotationY adds to the current Y rotation the specified angle in radians.
  310. // The stored quaternion is updated accordingly.
  311. func (n *Node) AddRotationY(y float32) {
  312. n.rotation.Y += y
  313. n.quaternion.SetFromEuler(&n.rotation)
  314. n.changed = true
  315. }
  316. // AddRotationZ adds to the current Z rotation the specified angle in radians.
  317. // The stored quaternion is updated accordingly.
  318. func (n *Node) AddRotationZ(z float32) {
  319. n.rotation.Z += z
  320. n.quaternion.SetFromEuler(&n.rotation)
  321. n.changed = true
  322. }
  323. // Rotation returns the current rotation.
  324. func (n *Node) Rotation() math32.Vector3 {
  325. return n.rotation
  326. }
  327. // SetQuaternion sets the quaternion based on the specified quaternion unit multiples.
  328. func (n *Node) SetQuaternion(x, y, z, w float32) {
  329. n.quaternion.Set(x, y, z, w)
  330. n.changed = true
  331. }
  332. // SetQuaternionQuat sets the quaternion based on the specified quaternion pointer.
  333. func (n *Node) SetQuaternionQuat(q *math32.Quaternion) {
  334. n.quaternion = *q
  335. n.changed = true
  336. }
  337. // QuaternionMult multiplies the current quaternion by the specified quaternion.
  338. func (n *Node) QuaternionMult(q *math32.Quaternion) {
  339. n.quaternion.Multiply(q)
  340. n.changed = true
  341. }
  342. // Quaternion returns the current quaternion.
  343. func (n *Node) Quaternion() math32.Quaternion {
  344. return n.quaternion
  345. }
  346. // SetScale sets the scale.
  347. func (n *Node) SetScale(x, y, z float32) {
  348. n.scale.Set(x, y, z)
  349. n.changed = true
  350. }
  351. // SetScaleVec sets the scale based on the specified vector pointer.
  352. func (n *Node) SetScaleVec(scale *math32.Vector3) {
  353. n.scale = *scale
  354. n.changed = true
  355. }
  356. // SetScaleX sets the X scale.
  357. func (n *Node) SetScaleX(sx float32) {
  358. n.scale.X = sx
  359. n.changed = true
  360. }
  361. // SetScaleY sets the Y scale.
  362. func (n *Node) SetScaleY(sy float32) {
  363. n.scale.Y = sy
  364. n.changed = true
  365. }
  366. // SetScaleZ sets the Z scale.
  367. func (n *Node) SetScaleZ(sz float32) {
  368. n.scale.Z = sz
  369. n.changed = true
  370. }
  371. // Scale returns the current scale.
  372. func (n *Node) Scale() math32.Vector3 {
  373. return n.scale
  374. }
  375. // SetDirection sets the direction.
  376. func (n *Node) SetDirection(x, y, z float32) {
  377. n.direction.Set(x, y, z)
  378. n.changed = true
  379. }
  380. // SetDirectionVec sets the direction based on a vector pointer.
  381. func (n *Node) SetDirectionVec(vdir *math32.Vector3) {
  382. n.direction = *vdir
  383. n.changed = true
  384. }
  385. // Direction returns the direction.
  386. func (n *Node) Direction() math32.Vector3 {
  387. return n.direction
  388. }
  389. // SetMatrix sets the local transformation matrix.
  390. func (n *Node) SetMatrix(m *math32.Matrix4) {
  391. n.matrix = *m
  392. n.changed = true
  393. }
  394. // Matrix returns a copy of the local transformation matrix.
  395. func (n *Node) Matrix() math32.Matrix4 {
  396. return n.matrix
  397. }
  398. // WorldPosition updates this node world matrix and gets
  399. // the current world position vector.
  400. func (n *Node) WorldPosition(result *math32.Vector3) {
  401. n.UpdateMatrixWorld()
  402. result.SetFromMatrixPosition(&n.matrixWorld)
  403. }
  404. // WorldQuaternion sets the specified result quaternion with
  405. // this node current world quaternion
  406. func (n *Node) WorldQuaternion(result *math32.Quaternion) {
  407. var position math32.Vector3
  408. var scale math32.Vector3
  409. n.UpdateMatrixWorld()
  410. n.matrixWorld.Decompose(&position, result, &scale)
  411. }
  412. // WorldRotation sets the specified result vector with
  413. // current world rotation of this node in Euler angles.
  414. func (n *Node) WorldRotation(result *math32.Vector3) {
  415. var quaternion math32.Quaternion
  416. n.WorldQuaternion(&quaternion)
  417. result.SetFromQuaternion(&quaternion)
  418. }
  419. // WorldScale sets the specified result vector with
  420. // the current world scale of this node
  421. func (n *Node) WorldScale(result *math32.Vector3) {
  422. var position math32.Vector3
  423. var quaternion math32.Quaternion
  424. n.UpdateMatrixWorld()
  425. n.matrixWorld.Decompose(&position, &quaternion, result)
  426. }
  427. // WorldDirection updates this object world matrix and sets
  428. // the current world direction.
  429. func (n *Node) WorldDirection(result *math32.Vector3) {
  430. var quaternion math32.Quaternion
  431. n.WorldQuaternion(&quaternion)
  432. *result = n.direction
  433. result.ApplyQuaternion(&quaternion)
  434. }
  435. // MatrixWorld returns a copy of this node matrix world
  436. func (n *Node) MatrixWorld() math32.Matrix4 {
  437. return n.matrixWorld
  438. }
  439. // UpdateMatrix updates this node local matrix transform from its
  440. // current position, quaternion and scale.
  441. func (n *Node) UpdateMatrix() {
  442. n.matrix.Compose(&n.position, &n.quaternion, &n.scale)
  443. }
  444. // UpdateMatrixWorld updates this node world transform matrix and of all its children
  445. func (n *Node) UpdateMatrixWorld() {
  446. n.UpdateMatrix()
  447. if n.parent == nil {
  448. n.matrixWorld = n.matrix
  449. } else {
  450. parent := n.parent.GetNode()
  451. n.matrixWorld.MultiplyMatrices(&parent.matrixWorld, &n.matrix)
  452. }
  453. // Update this Node children matrices
  454. for _, ichild := range n.children {
  455. ichild.UpdateMatrixWorld()
  456. }
  457. }