| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120 |
- // Copyright 2016 The G3N Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style
- // license that can be found in the LICENSE file.
- package geometry
- import (
- "github.com/g3n/engine/gls"
- "github.com/g3n/engine/math32"
- )
- type Box struct {
- Geometry
- Width float64
- Height float64
- Depth float64
- WidthSegments int
- HeightSegments int
- DepthSegments int
- }
- // NewBox creates and returns a pointer to a new Box geometry object.
- // The geometry is defined by its width, height, depth and the number of
- // segments of each dimension (minimum = 1).
- func NewBox(width, height, depth float64, widthSegments, heightSegments, depthSegments int) *Box {
- box := new(Box)
- box.Geometry.Init()
- box.Width = width
- box.Height = height
- box.Depth = depth
- box.WidthSegments = widthSegments
- box.HeightSegments = heightSegments
- box.DepthSegments = depthSegments
- // Create buffers
- positions := math32.NewArrayF32(0, 16)
- normals := math32.NewArrayF32(0, 16)
- uvs := math32.NewArrayF32(0, 16)
- indices := math32.NewArrayU32(0, 16)
- width_half := width / 2
- height_half := height / 2
- depth_half := depth / 2
- // Internal function to build each box plane
- buildPlane := func(u, v string, udir, vdir int, width, height, depth float64, materialIndex uint) {
- gridX := widthSegments
- gridY := heightSegments
- width_half := width / 2
- height_half := height / 2
- offset := positions.Len() / 3
- var w string
- if (u == "x" && v == "y") || (u == "y" && v == "x") {
- w = "z"
- } else if (u == "x" && v == "z") || (u == "z" && v == "x") {
- w = "y"
- gridY = depthSegments
- } else if (u == "z" && v == "y") || (u == "y" && v == "z") {
- w = "x"
- gridX = depthSegments
- }
- gridX1 := gridX + 1
- gridY1 := gridY + 1
- segment_width := width / float64(gridX)
- segment_height := height / float64(gridY)
- var normal math32.Vector3
- if depth > 0 {
- normal.SetByName(w, 1)
- } else {
- normal.SetByName(w, -1)
- }
- // Generates the plane vertices, normals and uv coordinates.
- for iy := 0; iy < gridY1; iy++ {
- for ix := 0; ix < gridX1; ix++ {
- var vector math32.Vector3
- vector.SetByName(u, float32((float64(ix)*segment_width-width_half)*float64(udir)))
- vector.SetByName(v, float32((float64(iy)*segment_height-height_half)*float64(vdir)))
- vector.SetByName(w, float32(depth))
- positions.AppendVector3(&vector)
- normals.AppendVector3(&normal)
- uvs.Append(float32(float64(ix)/float64(gridX)), float32(float64(1)-(float64(iy)/float64(gridY))))
- }
- }
- gstart := indices.Size()
- matIndex := materialIndex
- // Generates the indices for the vertices, normals and uvs
- for iy := 0; iy < gridY; iy++ {
- for ix := 0; ix < gridX; ix++ {
- a := ix + gridX1*iy
- b := ix + gridX1*(iy+1)
- c := (ix + 1) + gridX1*(iy+1)
- d := (ix + 1) + gridX1*iy
- indices.Append(uint32(a+offset), uint32(b+offset), uint32(d+offset), uint32(b+offset), uint32(c+offset), uint32(d+offset))
- }
- }
- gcount := indices.Size() - gstart
- box.AddGroup(gstart, gcount, int(matIndex))
- }
- buildPlane("z", "y", -1, -1, depth, height, width_half, 0) // px
- buildPlane("z", "y", 1, -1, depth, height, -width_half, 1) // nx
- buildPlane("x", "z", 1, 1, width, depth, height_half, 2) // py
- buildPlane("x", "z", 1, -1, width, depth, -height_half, 3) // ny
- buildPlane("x", "y", 1, -1, width, height, depth_half, 4) // pz
- buildPlane("x", "y", -1, -1, width, height, -depth_half, 5) // nz
- box.SetIndices(indices)
- box.AddVBO(gls.NewVBO().AddAttrib("VertexPosition", 3).SetBuffer(positions))
- box.AddVBO(gls.NewVBO().AddAttrib("VertexNormal", 3).SetBuffer(normals))
- box.AddVBO(gls.NewVBO().AddAttrib("VertexTexcoord", 2).SetBuffer(uvs))
- return box
- }
|