diff --git a/src/collision/aabb.go b/src/collision/aabb.go index 3d7cbd78..8b5dc5a6 100644 --- a/src/collision/aabb.go +++ b/src/collision/aabb.go @@ -67,20 +67,8 @@ func AABBFromMinMax(min, max matrix.Vec3) AABB { // Union returns the union of two AABBs func AABBUnion(a, b AABB) AABB { - aMin := a.Min() - aMax := a.Max() - bMin := b.Min() - bMax := b.Max() - min := matrix.Vec3{ - matrix.Min(aMin.X(), bMin.X()), - matrix.Min(aMin.Y(), bMin.Y()), - matrix.Min(aMin.Z(), bMin.Z()), - } - max := matrix.Vec3{ - matrix.Max(aMax.X(), bMax.X()), - matrix.Max(aMax.Y(), bMax.Y()), - matrix.Max(aMax.Z(), bMax.Z()), - } + min := matrix.Vec3Min(a.Min(), b.Min()) + max := matrix.Vec3Max(a.Max(), b.Max()) return AABBFromMinMax(min, max) } diff --git a/src/collision/bvh.go b/src/collision/bvh.go index acc75c0a..5c817bc3 100644 --- a/src/collision/bvh.go +++ b/src/collision/bvh.go @@ -21,6 +21,14 @@ type BVH struct { func NewBVH() *BVH { return &BVH{} } +func (b *BVH) Root() *BVH { + r := b + for r.Parent != nil { + r = r.Parent + } + return r +} + func (b *BVH) Bounds() AABB { if b.Transform == nil { return b.bounds @@ -103,7 +111,7 @@ func BVHInsert(into, other *BVH) *BVH { // root node to hold everything if into.IsRoot() { into.bounds = AABBUnion(ib, ob) - into.bounds.Extent.Scale(1.001) + into.bounds.Extent.ScaleAssign(1.001) return BVHInsert(into, other) } else { bvh := &BVH{ @@ -173,10 +181,16 @@ func (b *BVH) RemoveNode() { promote = parent.Right } if parent.IsRoot() { - *parent = *promote - parent.Parent = nil - parent.Left.Parent = parent - parent.Right.Parent = parent + if promote != nil { + *parent = *promote + parent.Parent = nil + parent.Left.Parent = parent + if parent.Right != nil { + parent.Right.Parent = parent + } + } else { + parent.Left = nil + } } else { if parent.IsLeft() { parent.Parent.Left = promote diff --git a/src/editor/content/content_opener/obj_opener.go b/src/editor/content/content_opener/obj_opener.go index 138a5978..8a3e16cd 100644 --- a/src/editor/content/content_opener/obj_opener.go +++ b/src/editor/content/content_opener/obj_opener.go @@ -146,6 +146,7 @@ func (o ObjOpener) Open(adi asset_info.AssetDatabaseInfo, ed interfaces.Editor) host.AddEntity(e) e.SetName(adi.MetaValue("name")) bvh := collision.NewBVH() + bvh.Transform = &e.Transform for i := range adi.Children { if err := load(host, adi.Children[i], e, bvh); err != nil { return err diff --git a/src/editor/editor.go b/src/editor/editor.go index f768c013..6f6f870f 100644 --- a/src/editor/editor.go +++ b/src/editor/editor.go @@ -125,6 +125,20 @@ func (e *Editor) StatusBar() *status_bar.StatusBar { return e.statusBar } func (e *Editor) Hierarchy() *hierarchy.Hierarchy { return e.hierarchy } func (e *Editor) BVH() *collision.BVH { return e.bvh } +func (e *Editor) BVHEntityUpdates(entities ...*engine.Entity) { + root := e.bvh + for _, e := range entities { + d := e.EditorBindings.Data("bvh") + if d == nil { + continue + } + bvh := d.(*collision.BVH) + bvh.RemoveNode() + root = collision.BVHInsert(root, bvh) + } + e.bvh = root +} + func (e *Editor) AvailableDataBindings() []codegen.GeneratedType { return e.entityData } @@ -279,8 +293,7 @@ func (e *Editor) Init() { dc.(*rendering.OITCanvas).ClearColor = matrix.ColorTransparent() ot.ClearColor = matrix.ColorTransparent() e.overlayCanvas = ot - e.transformTool = transform_tools.New(e.Host(), - &e.selection, "editor_overlay", &e.history) + e.transformTool = transform_tools.New(e.Host(), e, "editor_overlay", &e.history) e.selection.Changed.Add(func() { e.transformTool.Disable() }) diff --git a/src/editor/interfaces/editor.go b/src/editor/interfaces/editor.go index 08c9d60c..4b8226ad 100644 --- a/src/editor/interfaces/editor.go +++ b/src/editor/interfaces/editor.go @@ -63,5 +63,7 @@ type Editor interface { AvailableDataBindings() []codegen.GeneratedType ReloadEntityDataListing() CreateEntity(name string) *engine.Entity + // TODO: BVH stuff can be encapsulated into another structure BVH() *collision.BVH + BVHEntityUpdates(entities ...*engine.Entity) } diff --git a/src/editor/viewport/tools/transform_tools/tool_history.go b/src/editor/viewport/tools/transform_tools/tool_history.go index b1bf545f..43c24991 100644 --- a/src/editor/viewport/tools/transform_tools/tool_history.go +++ b/src/editor/viewport/tools/transform_tools/tool_history.go @@ -38,11 +38,13 @@ package transform_tools import ( + "kaiju/editor/interfaces" "kaiju/engine" "kaiju/matrix" ) type toolHistory struct { + editor interfaces.Editor entities []*engine.Entity from []matrix.Vec3 to []matrix.Vec3 @@ -59,6 +61,7 @@ func (h *toolHistory) Redo() { e.Transform.SetScale(h.to[i]) } } + h.editor.BVHEntityUpdates(h.editor.Selection().Entities()...) } func (h *toolHistory) Undo() { @@ -71,6 +74,7 @@ func (h *toolHistory) Undo() { e.Transform.SetScale(h.from[i]) } } + h.editor.BVHEntityUpdates(h.editor.Selection().Entities()...) } func (h *toolHistory) Delete() {} diff --git a/src/editor/viewport/tools/transform_tools/transform_tool.go b/src/editor/viewport/tools/transform_tools/transform_tool.go index c75129a3..96288613 100644 --- a/src/editor/viewport/tools/transform_tools/transform_tool.go +++ b/src/editor/viewport/tools/transform_tools/transform_tool.go @@ -39,8 +39,8 @@ package transform_tools import ( "kaiju/assets" + "kaiju/editor/interfaces" "kaiju/editor/memento" - "kaiju/editor/selection" "kaiju/engine" "kaiju/hid" "kaiju/matrix" @@ -49,7 +49,7 @@ import ( ) type TransformTool struct { - selection *selection.Selection + editor interfaces.Editor axis AxisState state ToolState lastHit matrix.Vec3 @@ -83,12 +83,12 @@ func (t *TransformTool) createWire(nameSuffix string, host *engine.Host, } } -func New(host *engine.Host, selection *selection.Selection, +func New(host *engine.Host, editor interfaces.Editor, canvas string, history *memento.History) TransformTool { wt := matrix.NewTransform() t := TransformTool{ - selection: selection, + editor: editor, wireTransform: &wt, resets: make([]matrix.Vec3, 0, 32), history: history, @@ -129,7 +129,7 @@ func (t *TransformTool) Update(host *engine.Host) (busy bool) { func (t *TransformTool) Enable(state ToolState) { for i := range t.wires { t.wires[i].ShaderData.Deactivate() - t.wireTransform.SetPosition(t.selection.Center()) + t.wireTransform.SetPosition(t.editor.Selection().Center()) t.transformDirty = 2 } switch t.axis { @@ -155,7 +155,7 @@ func (t *TransformTool) Disable() { } func (t *TransformTool) resetChange() { - all := t.selection.Entities() + all := t.editor.Selection().Entities() for i := range t.resets { if t.state == ToolStateMove { all[i].Transform.SetPosition(t.resets[i]) @@ -170,7 +170,7 @@ func (t *TransformTool) resetChange() { func (t *TransformTool) updateResets() { t.resets = t.resets[:0] - for _, e := range t.selection.Entities() { + for _, e := range t.editor.Selection().Entities() { if t.state == ToolStateMove { t.resets = append(t.resets, e.Transform.Position()) } else if t.state == ToolStateRotate { @@ -182,7 +182,7 @@ func (t *TransformTool) updateResets() { } func (t *TransformTool) addHistory() { - all := t.selection.Entities() + all := t.editor.Selection().Entities() to := make([]matrix.Vec3, len(all)) from := make([]matrix.Vec3, len(all)) for i, e := range all { @@ -196,11 +196,13 @@ func (t *TransformTool) addHistory() { } } t.history.Add(&toolHistory{ - entities: slices.Clone(t.selection.Entities()), + editor: t.editor, + entities: slices.Clone(t.editor.Selection().Entities()), from: from, to: to, state: t.state, }) + t.editor.BVHEntityUpdates(t.editor.Selection().Entities()...) } func (t *TransformTool) commitChange() { @@ -231,7 +233,7 @@ func (t *TransformTool) checkKeyboard(kb *hid.Keyboard) { func (t *TransformTool) updateDrag(host *engine.Host) { m := &host.Window.Mouse - center := t.selection.Center() + center := t.editor.Selection().Center() nml := matrix.Vec3Forward() r := host.Camera.RayCast(m.Position()) var df, db, dl, dr, du, dd matrix.Float = -1.0, -1.0, -1.0, -1.0, -1.0, -1.0 @@ -302,7 +304,7 @@ func (t *TransformTool) updateDrag(host *engine.Host) { func (t *TransformTool) transform(delta, point matrix.Vec3, snap bool) { // TODO: Move this to configuration const snapScale = 0.5 - for i, e := range t.selection.Entities() { + for i, e := range t.editor.Selection().Entities() { et := &e.Transform if t.state == ToolStateMove { d := t.resets[i].Subtract(t.wireTransform.Position())