plane.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  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. )
  9. // Plane represents a plane geometry
  10. type Plane struct {
  11. Geometry
  12. Width float32
  13. Height float32
  14. WidthSegments int
  15. HeightSegments int
  16. }
  17. // NewPlane creates and returns a pointer to a Plane Geometry.
  18. // The plane is defined by its width, height and the number of width and height segments.
  19. // The minimum number of segments for the width and/or the height is 1.
  20. // The plane is generated centered in the XY plane with Z=0.
  21. func NewPlane(width, height float32, widthSegments, heightSegments int) *Plane {
  22. plane := new(Plane)
  23. plane.Geometry.Init()
  24. plane.Width = width
  25. plane.Height = height
  26. plane.WidthSegments = widthSegments
  27. plane.HeightSegments = heightSegments
  28. widthHalf := width / 2
  29. heightHalf := height / 2
  30. gridX := widthSegments
  31. gridY := heightSegments
  32. gridX1 := gridX + 1
  33. gridY1 := gridY + 1
  34. segmentWidth := width / float32(gridX)
  35. segmentHeight := height / float32(gridY)
  36. // Create buffers
  37. positions := math32.NewArrayF32(0, 16)
  38. normals := math32.NewArrayF32(0, 16)
  39. uvs := math32.NewArrayF32(0, 16)
  40. indices := math32.NewArrayU32(0, 16)
  41. // Generate plane vertices, vertices normals and vertices texture mappings.
  42. for iy := 0; iy < gridY1; iy++ {
  43. y := float32(iy)*segmentHeight - heightHalf
  44. for ix := 0; ix < gridX1; ix++ {
  45. x := float32(ix)*segmentWidth - widthHalf
  46. positions.Append(float32(x), float32(-y), 0)
  47. normals.Append(0, 0, 1)
  48. uvs.Append(float32(float64(ix)/float64(gridX)), float32(float64(1)-(float64(iy)/float64(gridY))))
  49. }
  50. }
  51. // Generate plane vertices indices for the faces
  52. for iy := 0; iy < gridY; iy++ {
  53. for ix := 0; ix < gridX; ix++ {
  54. a := ix + gridX1*iy
  55. b := ix + gridX1*(iy+1)
  56. c := (ix + 1) + gridX1*(iy+1)
  57. d := (ix + 1) + gridX1*iy
  58. indices.Append(uint32(a), uint32(b), uint32(d))
  59. indices.Append(uint32(b), uint32(c), uint32(d))
  60. }
  61. }
  62. plane.SetIndices(indices)
  63. plane.AddVBO(gls.NewVBO().AddAttrib("VertexPosition", 3).SetBuffer(positions))
  64. plane.AddVBO(gls.NewVBO().AddAttrib("VertexNormal", 3).SetBuffer(normals))
  65. plane.AddVBO(gls.NewVBO().AddAttrib("VertexTexcoord", 2).SetBuffer(uvs))
  66. // Update area
  67. plane.area = width*height
  68. plane.areaValid = true
  69. // Update volume
  70. plane.volume = 0
  71. plane.volumeValid = true
  72. return plane
  73. }