Files

124 lines
2.7 KiB
Go

package editor
import (
"aego/core/mathx"
"aego/editor/core/context"
"aego/engine/module"
"aego/modules/physics"
"aego/modules/physics/components"
"aego/modules/physics/settings"
"aego/modules/physics/systems"
"aego/modules/physics/world"
"aego/scene"
)
var (
colVelocity = mathx.Color{R: 0.3, G: 1, B: 0.4, A: 1}
colAngular = mathx.Color{R: 0.3, G: 0.9, B: 0.9, A: 1}
colForce = mathx.Color{R: 1, G: 0.6, B: 0.2, A: 1}
colImpulse = mathx.Color{R: 1, G: 0.3, B: 0.3, A: 1}
colGravity = mathx.Color{R: 0.7, G: 0.7, B: 0.7, A: 1}
)
func simOf(v *context.VectorSink) *systems.Sim {
if v.World == nil {
return nil
}
s := physics.SimOf(v.World)
if s == nil || s.Scene() != v.Scene {
return nil
}
return s
}
func (p *plugin) velocity(v *context.VectorSink) {
sim := simOf(v)
if sim == nil {
return
}
w := sim.World()
w.ForEachBody(func(h world.BodyHandle) bool {
if t, _ := w.BodyType(h); t == world.Static {
return true
}
c, _ := w.BodyCenter(h)
vel, _, _ := w.BodyVelocity(h)
v.Arrow(c, vel, colVelocity)
return true
})
}
func (p *plugin) angular(v *context.VectorSink) {
sim := simOf(v)
if sim == nil {
return
}
w := sim.World()
w.ForEachBody(func(h world.BodyHandle) bool {
if t, _ := w.BodyType(h); t == world.Static {
return true
}
c, _ := w.BodyCenter(h)
_, av, _ := w.BodyVelocity(h)
v.Arc(c, av, colAngular)
return true
})
}
func (p *plugin) forces(v *context.VectorSink) {
sim := simOf(v)
if sim == nil {
return
}
for _, f := range sim.World().Forces() {
v.Arrow(f.Point, f.Vector, colForce)
}
}
func (p *plugin) contacts(v *context.VectorSink) {
sim := simOf(v)
if sim == nil {
return
}
w := sim.World()
w.ForEachBody(func(h world.BodyHandle) bool {
w.Contacts(h, func(c world.Contact) bool {
if c.BodyA != h || c.Trigger {
return true
}
m := &c.Manifold
for i := 0; i < m.Count; i++ {
pt := &m.Points[i]
v.Arrow(pt.Point, m.Normal.Scale(pt.TotalNormalImpulse), colImpulse)
}
return true
})
return true
})
}
func (p *plugin) gravity(v *context.VectorSink) {
var g mathx.Vec2
switch sim := simOf(v); {
case sim != nil:
g = sim.World().Gravity()
default:
g = world.DefaultConfig().Gravity
if p.ed != nil {
if s, ok := module.SectionValue[settings.Project](p.ed.Sections, settings.ID); ok {
g = s.Config().Gravity
}
}
}
b := v.View.VisibleBounds()
v.Arrow(mathx.Vec2{X: b.Min.X + v.Px*60, Y: b.Min.Y + v.Px*60}, g, colGravity)
if v.Scene == nil {
return
}
scene.Query1[components.Body2D](v.Scene).Each(func(h scene.NodeHandle, body *components.Body2D) {
if body.Type == components.Dynamic && body.GravityScale != 1 {
v.Arrow(v.Scene.WorldPosition(h), g.Scale(body.GravityScale), colGravity)
}
})
}