normals_helper.go 2.8 KB

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