torus.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  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. // NewTorus creates a torus geometry with the specified revolution radius, tube radius,
  11. // number of radial segments, number of tubular segments, and arc length angle in radians.
  12. // TODO instead of 'arc' have thetaStart and thetaLength for consistency with other generators
  13. // TODO then rename this to NewTorusSector and add a NewTorus constructor
  14. func NewTorus(radius, tubeRadius float64, radialSegments, tubularSegments int, arc float64) *Geometry {
  15. t := NewGeometry()
  16. // Create buffers
  17. positions := math32.NewArrayF32(0, 0)
  18. normals := math32.NewArrayF32(0, 0)
  19. uvs := math32.NewArrayF32(0, 0)
  20. indices := math32.NewArrayU32(0, 0)
  21. var center math32.Vector3
  22. for j := 0; j <= radialSegments; j++ {
  23. for i := 0; i <= tubularSegments; i++ {
  24. u := float64(i) / float64(tubularSegments) * arc
  25. v := float64(j) / float64(radialSegments) * math.Pi * 2
  26. center.X = float32(radius * math.Cos(u))
  27. center.Y = float32(radius * math.Sin(u))
  28. var vertex math32.Vector3
  29. vertex.X = float32((radius + tubeRadius*math.Cos(v)) * math.Cos(u))
  30. vertex.Y = float32((radius + tubeRadius*math.Cos(v)) * math.Sin(u))
  31. vertex.Z = float32(tubeRadius * math.Sin(v))
  32. positions.AppendVector3(&vertex)
  33. uvs.Append(float32(float64(i)/float64(tubularSegments)), float32(float64(j)/float64(radialSegments)))
  34. normals.AppendVector3(vertex.Sub(&center).Normalize())
  35. }
  36. }
  37. for j := 1; j <= radialSegments; j++ {
  38. for i := 1; i <= tubularSegments; i++ {
  39. a := (tubularSegments+1)*j + i - 1
  40. b := (tubularSegments+1)*(j-1) + i - 1
  41. c := (tubularSegments+1)*(j-1) + i
  42. d := (tubularSegments+1)*j + i
  43. indices.Append(uint32(a), uint32(b), uint32(d), uint32(b), uint32(c), uint32(d))
  44. }
  45. }
  46. t.SetIndices(indices)
  47. t.AddVBO(gls.NewVBO(positions).AddAttrib(gls.VertexPosition))
  48. t.AddVBO(gls.NewVBO(normals).AddAttrib(gls.VertexNormal))
  49. t.AddVBO(gls.NewVBO(uvs).AddAttrib(gls.VertexTexcoord))
  50. return t
  51. }