normals_helper.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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/geometry"
  8. "github.com/g3n/engine/gls"
  9. "github.com/g3n/engine/material"
  10. "github.com/g3n/engine/math32"
  11. )
  12. type NormalsHelper struct {
  13. Lines
  14. size float32
  15. target *core.Node
  16. tgeom *geometry.Geometry
  17. }
  18. // NewNormalsHelper creates, initializes and returns a pointer to Normals helper object.
  19. // This helper shows the normal vectors of the specified object.
  20. func NewNormalsHelper(ig IGraphic, size float32, color *math32.Color, lineWidth float32) *NormalsHelper {
  21. // Creates new Normals helper
  22. nh := new(NormalsHelper)
  23. nh.size = size
  24. // Saves the object to show the normals
  25. nh.target = ig.GetNode()
  26. // Get the geometry of the target object
  27. nh.tgeom = ig.GetGeometry()
  28. // Get the number of target vertex positions
  29. vertices := nh.tgeom.VBO("VertexPosition")
  30. n := vertices.Buffer().Size() * 2
  31. // Creates this helper geometry
  32. geom := geometry.NewGeometry()
  33. positions := math32.NewArrayF32(n, n)
  34. geom.AddVBO(gls.NewVBO().AddAttrib("VertexPosition", 3).SetBuffer(positions))
  35. // Creates this helper material
  36. mat := material.NewStandard(color)
  37. mat.SetLineWidth(lineWidth)
  38. // Initialize graphic
  39. nh.Lines.Init(geom, mat)
  40. nh.Update()
  41. return nh
  42. }
  43. // Update should be called in the render loop to update the normals from the
  44. // target object
  45. func (nh *NormalsHelper) Update() {
  46. var v1 math32.Vector3
  47. var v2 math32.Vector3
  48. var normalMatrix math32.Matrix3
  49. // Updates the target object matrix and get its normal matrix
  50. matrixWorld := nh.target.MatrixWorld()
  51. normalMatrix.GetNormalMatrix(&matrixWorld)
  52. // Get the target positions and normals buffers
  53. tposvbo := nh.tgeom.VBO("VertexPosition")
  54. tpositions := tposvbo.Buffer()
  55. tnormvbo := nh.tgeom.VBO("VertexNormal")
  56. tnormals := tnormvbo.Buffer()
  57. // Get this object positions buffer
  58. geom := nh.GetGeometry()
  59. posvbo := geom.VBO("VertexPosition")
  60. positions := posvbo.Buffer()
  61. // For each target object vertex position:
  62. for pos := 0; pos < tpositions.Size(); pos += 3 {
  63. // Get the target vertex position and apply the current world matrix transform
  64. // to get the base for this normal line segment.
  65. tpositions.GetVector3(pos, &v1)
  66. v1.ApplyMatrix4(&matrixWorld)
  67. // Calculates the end position of the normal line segment
  68. tnormals.GetVector3(pos, &v2)
  69. v2.ApplyMatrix3(&normalMatrix).Normalize().MultiplyScalar(nh.size).Add(&v1)
  70. // Sets the line segment representing the normal of the current target position
  71. // at this helper VBO
  72. positions.SetVector3(2*pos, &v1)
  73. positions.SetVector3(2*pos+3, &v2)
  74. }
  75. posvbo.Update()
  76. }