node.go 13 KB

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