zworld/plugins/geometry/cone/cone.go

92 lines
2.1 KiB
Go
Raw Normal View History

2024-01-14 22:56:06 +08:00
package cone
import (
"zworld/engine/object"
"zworld/engine/object/mesh"
"zworld/engine/renderapi/color"
"zworld/engine/renderapi/material"
"zworld/engine/renderapi/vertex"
"zworld/plugins/math"
"zworld/plugins/math/vec3"
)
type Cone struct {
object.Object
*Mesh
}
func NewObject(args Args) *Cone {
c := &Cone{
Mesh: New(args),
}
c.Mesh.Name()
c.Object.Name()
return object.New("Cone", &Cone{
Mesh: New(args),
})
}
// A Cone is a forward rendered colored cone mesh
type Mesh struct {
*mesh.Static
Args
}
type Args struct {
Mat *material.Def
Radius float32
Height float32
Segments int
Color color.T
}
func New(args Args) *Mesh {
if args.Mat == nil {
args.Mat = material.ColoredForward()
}
cone := object.NewComponent(&Mesh{
Static: mesh.New(args.Mat),
Args: args,
})
cone.generate()
return cone
}
func (c *Mesh) generate() {
data := make([]vertex.C, 6*c.Segments)
// cone
top := vec3.New(0, c.Height, 0)
sangle := 2 * math.Pi / float32(c.Segments)
for i := 0; i < c.Segments; i++ {
a1 := sangle * (float32(i) + 0.5)
a2 := sangle * (float32(i) + 1.5)
v1 := vec3.New(math.Cos(a1), 0, -math.Sin(a1)).Scaled(c.Radius)
v2 := vec3.New(math.Cos(a2), 0, -math.Sin(a2)).Scaled(c.Radius)
v1t, v2t := top.Sub(v1), top.Sub(v2)
n := vec3.Cross(v1t, v2t).Normalized()
o := 3 * i
data[o+0] = vertex.C{P: v2, N: n, C: c.Color.Vec4()}
data[o+1] = vertex.C{P: top, N: n, C: c.Color.Vec4()}
data[o+2] = vertex.C{P: v1, N: n, C: c.Color.Vec4()}
}
// bottom
base := vec3.Zero
n := vec3.New(0, -1, 0)
for i := 0; i < c.Segments; i++ {
a1 := sangle * (float32(i) + 0.5)
a2 := sangle * (float32(i) + 1.5)
v1 := vec3.New(math.Cos(a1), 0, -math.Sin(a1)).Scaled(c.Radius)
v2 := vec3.New(math.Cos(a2), 0, -math.Sin(a2)).Scaled(c.Radius)
o := 3 * (i + c.Segments)
data[o+0] = vertex.C{P: v1, N: n, C: c.Color.Vec4()}
data[o+1] = vertex.C{P: base, N: n, C: c.Color.Vec4()}
data[o+2] = vertex.C{P: v2, N: n, C: c.Color.Vec4()}
}
key := object.Key("cone", c)
mesh := vertex.NewTriangles(key, data, []uint16{})
c.VertexData.Set(mesh)
}