skeleton.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  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 graphic
  5. import (
  6. "github.com/g3n/engine/core"
  7. "github.com/g3n/engine/math32"
  8. )
  9. // Skeleton contains armature information.
  10. type Skeleton struct {
  11. core.INode
  12. inverseBindMatrices []math32.Matrix4
  13. boneMatrices []math32.Matrix4
  14. bones []*core.Node
  15. }
  16. // NewSkeleton creates and returns a pointer to a new Skeleton.
  17. func NewSkeleton(node core.INode) *Skeleton {
  18. sk := new(Skeleton)
  19. sk.INode = node
  20. sk.boneMatrices = make([]math32.Matrix4, 0)
  21. sk.bones = make([]*core.Node, 0)
  22. return sk
  23. }
  24. // AddBone adds a bone to the skeleton along with an optional inverseBindMatrix.
  25. func (sk *Skeleton) AddBone(node *core.Node, inverseBindMatrix *math32.Matrix4) {
  26. // Useful for debugging:
  27. //node.Add(NewAxisHelper(0.2))
  28. sk.bones = append(sk.bones, node)
  29. sk.boneMatrices = append(sk.boneMatrices, *math32.NewMatrix4())
  30. if inverseBindMatrix == nil {
  31. inverseBindMatrix = math32.NewMatrix4() // Identity matrix
  32. }
  33. sk.inverseBindMatrices = append(sk.inverseBindMatrices, *inverseBindMatrix)
  34. }
  35. // Bones returns the list of bones in the skeleton.
  36. func (sk *Skeleton) Bones() []*core.Node {
  37. return sk.bones
  38. }
  39. // BoneMatrices calculates and returns the bone world matrices to be sent to the shader.
  40. func (sk *Skeleton) BoneMatrices() []math32.Matrix4 {
  41. // Obtain inverse matrix world
  42. var invMat math32.Matrix4
  43. node := sk.GetNode()
  44. nMW := node.MatrixWorld()
  45. err := invMat.GetInverse(&nMW)
  46. if err != nil {
  47. log.Error("Skeleton.BoneMatrices: inverting matrix failed!")
  48. }
  49. // Update bone matrices
  50. for i := range sk.bones {
  51. bMat := sk.bones[i].MatrixWorld()
  52. bMat.MultiplyMatrices(&bMat, &sk.inverseBindMatrices[i])
  53. sk.boneMatrices[i].MultiplyMatrices(&invMat, &bMat)
  54. }
  55. return sk.boneMatrices
  56. }