node.go 12 KB

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