torus.go 2.2 KB

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