disk.go 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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 geometry
  5. import (
  6. "github.com/g3n/engine/gls"
  7. "github.com/g3n/engine/math32"
  8. "math"
  9. )
  10. // NewDisk creates a disk (filled circle) geometry with the specified
  11. // radius and number of radial segments/triangles (minimum 3).
  12. func NewDisk(radius float64, segments int) *Geometry {
  13. return NewDiskSector(radius, segments, 0, 2*math.Pi)
  14. }
  15. // NewDiskSector creates a disk (filled circle) or disk sector geometry with the specified radius,
  16. // number of radial segments/triangles (minimum 3), sector start angle in radians, and sector size angle in radians.
  17. // The center of the disk is at the origin, and theta runs counter-clockwise on the XY plane, starting at (x,y,z)=(1,0,0).
  18. func NewDiskSector(radius float64, segments int, thetaStart, thetaLength float64) *Geometry {
  19. d := NewGeometry()
  20. // Validate arguments
  21. if segments < 3 {
  22. panic("Invalid argument: segments. The number of segments needs to be greater or equal to 3.")
  23. }
  24. // Create buffers
  25. positions := math32.NewArrayF32(0, 16)
  26. normals := math32.NewArrayF32(0, 16)
  27. uvs := math32.NewArrayF32(0, 16)
  28. indices := math32.NewArrayU32(0, 16)
  29. // Append circle center position
  30. center := math32.NewVector3(0, 0, 0)
  31. positions.AppendVector3(center)
  32. // Append circle center normal
  33. var normal math32.Vector3
  34. normal.Z = 1
  35. normals.AppendVector3(&normal)
  36. // Append circle center uv coordinate
  37. centerUV := math32.NewVector2(0.5, 0.5)
  38. uvs.AppendVector2(centerUV)
  39. // Generate the segments
  40. for i := 0; i <= segments; i++ {
  41. segment := thetaStart + float64(i)/float64(segments)*thetaLength
  42. vx := float32(radius * math.Cos(segment))
  43. vy := float32(radius * math.Sin(segment))
  44. // Appends vertex position, normal and uv coordinates
  45. positions.Append(vx, vy, 0)
  46. normals.AppendVector3(&normal)
  47. uvs.Append((vx/float32(radius)+1)/2, (vy/float32(radius)+1)/2)
  48. }
  49. for i := 1; i <= segments; i++ {
  50. indices.Append(uint32(i), uint32(i)+1, 0)
  51. }
  52. d.SetIndices(indices)
  53. d.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
  54. d.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal))
  55. d.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord))
  56. // Update volume
  57. d.volume = 0
  58. d.volumeValid = true
  59. return d
  60. }