zworld/plugins/geometry/lines/sphere.go
2024-01-14 22:56:06 +08:00

102 lines
2.3 KiB
Go

package lines
import (
"zworld/engine/object"
"zworld/engine/object/mesh"
"zworld/engine/renderapi/color"
"zworld/engine/renderapi/vertex"
"zworld/plugins/math"
"zworld/plugins/math/vec3"
)
type Sphere struct {
*mesh.Static
Radius object.Property[float32]
Color object.Property[color.T]
data vertex.MutableMesh[vertex.C, uint16]
xcolor color.T
ycolor color.T
zcolor color.T
}
type SphereArgs struct {
Radius float32
Color color.T
}
func NewSphere(args SphereArgs) *Sphere {
b := object.NewComponent(&Sphere{
Static: mesh.NewLines(),
Radius: object.NewProperty(args.Radius),
Color: object.NewProperty(args.Color),
})
b.Radius.OnChange.Subscribe(func(float32) { b.refresh() })
b.Color.OnChange.Subscribe(func(c color.T) {
b.SetAxisColors(c, c, c)
b.refresh()
})
b.data = vertex.NewLines[vertex.C, uint16](object.Key("sphere", b), nil, nil)
b.SetAxisColors(args.Color, args.Color, args.Color)
return b
}
func (b *Sphere) SetAxisColors(x color.T, y color.T, z color.T) {
b.xcolor = x
b.ycolor = y
b.zcolor = z
b.refresh()
}
func (b *Sphere) refresh() {
segments := 32
radius := b.Radius.Get()
angle := 2 * math.Pi / float32(segments)
vertices := make([]vertex.C, 0, 2*3*segments)
// x ring
for i := 0; i < segments; i++ {
a0 := float32(i) * angle
a1 := float32(i+1) * angle
vertices = append(vertices, vertex.C{
P: vec3.New(0, math.Sin(a0), math.Cos(a0)).Scaled(radius),
C: b.xcolor.Vec4(),
})
vertices = append(vertices, vertex.C{
P: vec3.New(0, math.Sin(a1), math.Cos(a1)).Scaled(radius),
C: b.xcolor.Vec4(),
})
}
// y ring
for i := 0; i < segments; i++ {
a0 := float32(i) * angle
a1 := float32(i+1) * angle
vertices = append(vertices, vertex.C{
P: vec3.New(math.Cos(a0), 0, math.Sin(a0)).Scaled(radius),
C: b.ycolor.Vec4(),
})
vertices = append(vertices, vertex.C{
P: vec3.New(math.Cos(a1), 0, math.Sin(a1)).Scaled(radius),
C: b.ycolor.Vec4(),
})
}
// z ring
for i := 0; i < segments; i++ {
a0 := float32(i) * angle
a1 := float32(i+1) * angle
vertices = append(vertices, vertex.C{
P: vec3.New(math.Cos(a0), math.Sin(a0), 0).Scaled(radius),
C: b.zcolor.Vec4(),
})
vertices = append(vertices, vertex.C{
P: vec3.New(math.Cos(a1), math.Sin(a1), 0).Scaled(radius),
C: b.zcolor.Vec4(),
})
}
b.data.Update(vertices, nil)
b.VertexData.Set(b.data)
}