92 lines
2.1 KiB
Go
92 lines
2.1 KiB
Go
|
|
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)
|
||
|
|
}
|