node.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692
  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 node to the list of children and sets its parent pointer.
  186. // If the specified node had a parent, the specified node is removed from the original parent's list of children.
  187. func (n *Node) Add(ichild INode) *Node {
  188. n.setParentOf(ichild)
  189. n.children = append(n.children, ichild)
  190. return n
  191. }
  192. // AddAt adds the specified node to the list of children at the specified index and sets its parent pointer.
  193. // If the specified node had a parent, the specified node is removed from the original parent's list of children.
  194. func (n *Node) AddAt(idx int, ichild INode) {
  195. // Validate position
  196. if idx < 0 || idx > len(n.children) {
  197. panic("Node.AddAt: invalid position")
  198. }
  199. n.setParentOf(ichild)
  200. // Insert child in the specified position
  201. n.children = append(n.children, nil)
  202. copy(n.children[idx+1:], n.children[idx:])
  203. n.children[idx] = ichild
  204. }
  205. // setParentOf is used by Add and AddAt.
  206. // It verifies that the node is not being added to itself and sets the parent pointer of the specified node.
  207. // If the specified node had a parent, the specified node is removed from the original parent's list of children.
  208. // It does not add the specified node to the list of children.
  209. func (n *Node) setParentOf(ichild INode) {
  210. child := ichild.GetNode()
  211. if n == child {
  212. panic("Node.{Add,AddAt}: object can't be added as a child of itself")
  213. }
  214. // If the specified node already has a parent,
  215. // remove it from the original parent's list of children
  216. if child.parent != nil {
  217. child.parent.GetNode().Remove(ichild)
  218. }
  219. child.parent = n
  220. }
  221. // ChildAt returns the child at the specified index.
  222. func (n *Node) ChildAt(idx int) INode {
  223. if idx < 0 || idx >= len(n.children) {
  224. return nil
  225. }
  226. return n.children[idx]
  227. }
  228. // ChildIndex returns the index of the specified child (-1 if not found).
  229. func (n *Node) ChildIndex(ichild INode) int {
  230. for idx := 0; idx < len(n.children); idx++ {
  231. if n.children[idx] == ichild {
  232. return idx
  233. }
  234. }
  235. return -1
  236. }
  237. // Remove removes the specified INode from the list of children.
  238. // Returns true if found or false otherwise.
  239. func (n *Node) Remove(ichild INode) bool {
  240. for pos, current := range n.children {
  241. if current == ichild {
  242. copy(n.children[pos:], n.children[pos+1:])
  243. n.children[len(n.children)-1] = nil
  244. n.children = n.children[:len(n.children)-1]
  245. ichild.GetNode().parent = nil
  246. return true
  247. }
  248. }
  249. return false
  250. }
  251. // RemoveAt removes the child at the specified index.
  252. func (n *Node) RemoveAt(idx int) INode {
  253. // Validate position
  254. if idx < 0 || idx >= len(n.children) {
  255. panic("Node.RemoveAt: invalid position")
  256. }
  257. child := n.children[idx]
  258. // Remove child from children list
  259. copy(n.children[idx:], n.children[idx+1:])
  260. n.children[len(n.children)-1] = nil
  261. n.children = n.children[:len(n.children)-1]
  262. return child
  263. }
  264. // RemoveAll removes all children.
  265. func (n *Node) RemoveAll(recurs bool) {
  266. for pos, ichild := range n.children {
  267. n.children[pos] = nil
  268. ichild.GetNode().parent = nil
  269. if recurs {
  270. ichild.GetNode().RemoveAll(recurs)
  271. }
  272. }
  273. n.children = n.children[0:0]
  274. }
  275. // DisposeChildren removes and disposes of all children.
  276. // If 'recurs' is true, call DisposeChildren on each child recursively.
  277. func (n *Node) DisposeChildren(recurs bool) {
  278. for pos, ichild := range n.children {
  279. n.children[pos] = nil
  280. ichild.GetNode().parent = nil
  281. if recurs {
  282. ichild.GetNode().DisposeChildren(true)
  283. }
  284. ichild.Dispose()
  285. }
  286. n.children = n.children[0:0]
  287. }
  288. // SetPosition sets the position.
  289. func (n *Node) SetPosition(x, y, z float32) {
  290. n.position.Set(x, y, z)
  291. n.changed = true
  292. }
  293. // SetPositionVec sets the position based on the specified vector pointer.
  294. func (n *Node) SetPositionVec(vpos *math32.Vector3) {
  295. n.position = *vpos
  296. n.changed = true
  297. }
  298. // SetPositionX sets the X coordinate of the position.
  299. func (n *Node) SetPositionX(x float32) {
  300. n.position.X = x
  301. n.changed = true
  302. }
  303. // SetPositionY sets the Y coordinate of the position.
  304. func (n *Node) SetPositionY(y float32) {
  305. n.position.Y = y
  306. n.changed = true
  307. }
  308. // SetPositionZ sets the Z coordinate of the position.
  309. func (n *Node) SetPositionZ(z float32) {
  310. n.position.Z = z
  311. n.changed = true
  312. }
  313. // Position returns the position as a vector.
  314. func (n *Node) Position() math32.Vector3 {
  315. return n.position
  316. }
  317. // SetRotation sets the rotation in radians.
  318. // The stored quaternion is updated accordingly.
  319. func (n *Node) SetRotation(x, y, z float32) {
  320. n.rotation.Set(x, y, z)
  321. n.quaternion.SetFromEuler(&n.rotation)
  322. n.changed = true
  323. }
  324. // SetRotationVec sets the rotation in radians based on the specified vector pointer.
  325. // The stored quaternion is updated accordingly.
  326. func (n *Node) SetRotationVec(vrot *math32.Vector3) {
  327. n.rotation = *vrot
  328. n.quaternion.SetFromEuler(&n.rotation)
  329. n.changed = true
  330. }
  331. // SetRotationX sets the X rotation to the specified angle in radians.
  332. // The stored quaternion is updated accordingly.
  333. func (n *Node) SetRotationX(x float32) {
  334. n.rotation.X = x
  335. n.quaternion.SetFromEuler(&n.rotation)
  336. n.changed = true
  337. }
  338. // SetRotationY sets the Y rotation to the specified angle in radians.
  339. // The stored quaternion is updated accordingly.
  340. func (n *Node) SetRotationY(y float32) {
  341. n.rotation.Y = y
  342. n.quaternion.SetFromEuler(&n.rotation)
  343. n.changed = true
  344. }
  345. // SetRotationZ sets the Z rotation to the specified angle in radians.
  346. // The stored quaternion is updated accordingly.
  347. func (n *Node) SetRotationZ(z float32) {
  348. n.rotation.Z = z
  349. n.quaternion.SetFromEuler(&n.rotation)
  350. n.changed = true
  351. }
  352. // AddRotationX adds to the current X rotation the specified angle in radians.
  353. // The stored quaternion is updated accordingly.
  354. func (n *Node) AddRotationX(x float32) {
  355. n.rotation.X += x
  356. n.quaternion.SetFromEuler(&n.rotation)
  357. n.changed = true
  358. }
  359. // AddRotationY adds to the current Y rotation the specified angle in radians.
  360. // The stored quaternion is updated accordingly.
  361. func (n *Node) AddRotationY(y float32) {
  362. n.rotation.Y += y
  363. n.quaternion.SetFromEuler(&n.rotation)
  364. n.changed = true
  365. }
  366. // AddRotationZ adds to the current Z rotation the specified angle in radians.
  367. // The stored quaternion is updated accordingly.
  368. func (n *Node) AddRotationZ(z float32) {
  369. n.rotation.Z += z
  370. n.quaternion.SetFromEuler(&n.rotation)
  371. n.changed = true
  372. }
  373. // Rotation returns the current rotation.
  374. func (n *Node) Rotation() math32.Vector3 {
  375. return n.rotation
  376. }
  377. // SetQuaternion sets the quaternion based on the specified quaternion unit multiples.
  378. func (n *Node) SetQuaternion(x, y, z, w float32) {
  379. n.quaternion.Set(x, y, z, w)
  380. n.changed = true
  381. }
  382. // SetQuaternionQuat sets the quaternion based on the specified quaternion pointer.
  383. func (n *Node) SetQuaternionQuat(q *math32.Quaternion) {
  384. n.quaternion = *q
  385. n.changed = true
  386. }
  387. // QuaternionMult multiplies the current quaternion by the specified quaternion.
  388. func (n *Node) QuaternionMult(q *math32.Quaternion) {
  389. n.quaternion.Multiply(q)
  390. n.changed = true
  391. }
  392. // Quaternion returns the current quaternion.
  393. func (n *Node) Quaternion() math32.Quaternion {
  394. return n.quaternion
  395. }
  396. // SetScale sets the scale.
  397. func (n *Node) SetScale(x, y, z float32) {
  398. n.scale.Set(x, y, z)
  399. n.changed = true
  400. }
  401. // SetScaleVec sets the scale based on the specified vector pointer.
  402. func (n *Node) SetScaleVec(scale *math32.Vector3) {
  403. n.scale = *scale
  404. n.changed = true
  405. }
  406. // SetScaleX sets the X scale.
  407. func (n *Node) SetScaleX(sx float32) {
  408. n.scale.X = sx
  409. n.changed = true
  410. }
  411. // SetScaleY sets the Y scale.
  412. func (n *Node) SetScaleY(sy float32) {
  413. n.scale.Y = sy
  414. n.changed = true
  415. }
  416. // SetScaleZ sets the Z scale.
  417. func (n *Node) SetScaleZ(sz float32) {
  418. n.scale.Z = sz
  419. n.changed = true
  420. }
  421. // Scale returns the current scale.
  422. func (n *Node) Scale() math32.Vector3 {
  423. return n.scale
  424. }
  425. // SetDirection sets the direction.
  426. func (n *Node) SetDirection(x, y, z float32) {
  427. n.direction.Set(x, y, z)
  428. n.changed = true
  429. }
  430. // SetDirectionVec sets the direction based on a vector pointer.
  431. func (n *Node) SetDirectionVec(vdir *math32.Vector3) {
  432. n.direction = *vdir
  433. n.changed = true
  434. }
  435. // Direction returns the direction.
  436. func (n *Node) Direction() math32.Vector3 {
  437. return n.direction
  438. }
  439. // SetMatrix sets the local transformation matrix.
  440. func (n *Node) SetMatrix(m *math32.Matrix4) {
  441. n.matrix = *m
  442. n.changed = true
  443. }
  444. // Matrix returns a copy of the local transformation matrix.
  445. func (n *Node) Matrix() math32.Matrix4 {
  446. return n.matrix
  447. }
  448. // WorldPosition updates the world matrix and sets
  449. // the specified vector to the current world position of this node.
  450. func (n *Node) WorldPosition(result *math32.Vector3) {
  451. n.UpdateMatrixWorld()
  452. result.SetFromMatrixPosition(&n.matrixWorld)
  453. }
  454. // WorldQuaternion updates the world matrix and sets
  455. // the specified quaternion to the current world quaternion of this node.
  456. func (n *Node) WorldQuaternion(result *math32.Quaternion) {
  457. var position math32.Vector3
  458. var scale math32.Vector3
  459. n.UpdateMatrixWorld()
  460. n.matrixWorld.Decompose(&position, result, &scale)
  461. }
  462. // WorldRotation updates the world matrix and sets
  463. // the specified vector to the current world rotation of this node in Euler angles.
  464. func (n *Node) WorldRotation(result *math32.Vector3) {
  465. var quaternion math32.Quaternion
  466. n.WorldQuaternion(&quaternion)
  467. result.SetFromQuaternion(&quaternion)
  468. }
  469. // WorldScale updates the world matrix and sets
  470. // the specified vector to the current world scale of this node.
  471. func (n *Node) WorldScale(result *math32.Vector3) {
  472. var position math32.Vector3
  473. var quaternion math32.Quaternion
  474. n.UpdateMatrixWorld()
  475. n.matrixWorld.Decompose(&position, &quaternion, result)
  476. }
  477. // WorldDirection updates the world matrix and sets
  478. // the specified vector to the current world direction of this node.
  479. func (n *Node) WorldDirection(result *math32.Vector3) {
  480. var quaternion math32.Quaternion
  481. n.WorldQuaternion(&quaternion)
  482. *result = n.direction
  483. result.ApplyQuaternion(&quaternion)
  484. }
  485. // MatrixWorld returns a copy of the matrix world of this node.
  486. func (n *Node) MatrixWorld() math32.Matrix4 {
  487. return n.matrixWorld
  488. }
  489. // UpdateMatrix updates (if necessary) the local transform matrix
  490. // of this node based on its position, quaternion, and scale.
  491. func (n *Node) UpdateMatrix() bool {
  492. if !n.changed {
  493. return false
  494. }
  495. n.matrix.Compose(&n.position, &n.quaternion, &n.scale)
  496. n.changed = false
  497. return true
  498. }
  499. // UpdateMatrixWorld updates the world transform matrix for this node and for all of its children.
  500. func (n *Node) UpdateMatrixWorld() {
  501. if n.parent == nil {
  502. n.updateMatrixWorld(&n.matrix)
  503. } else {
  504. parent := n.parent.GetNode()
  505. n.updateMatrixWorld(&parent.matrixWorld)
  506. }
  507. }
  508. // updateMatrixWorld is used internally by UpdateMatrixWorld.
  509. // If the local transform matrix has changed, this method updates it and also the world matrix of this node.
  510. // Children are updated recursively. If any node has changed, then we update the world matrix
  511. // of all of its descendants regardless if their local matrices have changed.
  512. func (n *Node) updateMatrixWorld(parentMatrixWorld *math32.Matrix4) {
  513. // If the local transform matrix for this node has changed then we need to update the local
  514. // matrix for this node and also the world matrix for this and all subsequent nodes.
  515. if n.UpdateMatrix() {
  516. n.matrixWorld.MultiplyMatrices(parentMatrixWorld, &n.matrix)
  517. // Update matrices of children recursively, always updating the world matrix
  518. for _, ichild := range n.children {
  519. ichild.GetNode().updateMatrixWorldNoCheck(&n.matrixWorld)
  520. }
  521. } else {
  522. // Update matrices of children recursively, continuing to check for changes
  523. for _, ichild := range n.children {
  524. ichild.GetNode().updateMatrixWorld(&n.matrixWorld)
  525. }
  526. }
  527. }
  528. // updateMatrixWorldNoCheck is used internally by updateMatrixWorld.
  529. // This method should be called when a node has changed since it always updates the matrix world.
  530. func (n *Node) updateMatrixWorldNoCheck(parentMatrixWorld *math32.Matrix4) {
  531. // Update the local transform matrix (if necessary)
  532. n.UpdateMatrix()
  533. // Always update the matrix world since an ancestor of this node has changed
  534. // (i.e. and ancestor had its local transform matrix modified)
  535. n.matrixWorld.MultiplyMatrices(parentMatrixWorld, &n.matrix)
  536. // Update matrices of children recursively
  537. for _, ichild := range n.children {
  538. ichild.GetNode().updateMatrixWorldNoCheck(&n.matrixWorld)
  539. }
  540. }