torus.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. // Torus represents a torus geometry
  11. type Torus struct {
  12. Geometry // embedded geometry
  13. Radius float64 // Torus radius
  14. Tube float64 // Diameter of the torus tube
  15. RadialSegments int // Number of radial segments
  16. TubularSegments int // Number of tubular segments
  17. Arc float64 // Central angle
  18. }
  19. // NewTorus returns a pointer to a new torus geometry
  20. func NewTorus(radius, tube float64, radialSegments, tubularSegments int, arc float64) *Torus {
  21. t := new(Torus)
  22. t.Geometry.Init()
  23. t.Radius = radius
  24. t.Tube = tube
  25. t.RadialSegments = radialSegments
  26. t.TubularSegments = tubularSegments
  27. t.Arc = arc
  28. // Create buffers
  29. positions := math32.NewArrayF32(0, 0)
  30. normals := math32.NewArrayF32(0, 0)
  31. uvs := math32.NewArrayF32(0, 0)
  32. indices := math32.NewArrayU32(0, 0)
  33. var center math32.Vector3
  34. for j := 0; j <= radialSegments; j++ {
  35. for i := 0; i <= tubularSegments; i++ {
  36. u := float64(i) / float64(tubularSegments) * arc
  37. v := float64(j) / float64(radialSegments) * math.Pi * 2
  38. center.X = float32(radius * math.Cos(u))
  39. center.Y = float32(radius * math.Sin(u))
  40. var vertex math32.Vector3
  41. vertex.X = float32((radius + tube*math.Cos(v)) * math.Cos(u))
  42. vertex.Y = float32((radius + tube*math.Cos(v)) * math.Sin(u))
  43. vertex.Z = float32(tube * math.Sin(v))
  44. positions.AppendVector3(&vertex)
  45. uvs.Append(float32(float64(i)/float64(tubularSegments)), float32(float64(j)/float64(radialSegments)))
  46. normals.AppendVector3(vertex.Sub(&center).Normalize())
  47. }
  48. }
  49. for j := 1; j <= radialSegments; j++ {
  50. for i := 1; i <= tubularSegments; i++ {
  51. a := (tubularSegments+1)*j + i - 1
  52. b := (tubularSegments+1)*(j-1) + i - 1
  53. c := (tubularSegments+1)*(j-1) + i
  54. d := (tubularSegments+1)*j + i
  55. indices.Append(uint32(a), uint32(b), uint32(d), uint32(b), uint32(c), uint32(d))
  56. }
  57. }
  58. t.SetIndices(indices)
  59. t.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition, 3))
  60. t.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal, 3))
  61. t.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord, 2))
  62. return t
  63. }