ui: basic map scroller
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
package world
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestDrawCirclesFromPlan_DuplicatesAcrossTilesAndClips(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
// World is 10x10 world units => 10000x10000 fixed.
|
||||
w := NewWorld(10, 10)
|
||||
w.resetGrid(2 * SCALE)
|
||||
|
||||
// Circle near origin so that in expanded canvas (bigger than world)
|
||||
// it will appear in multiple torus tiles.
|
||||
id, err := w.AddCircle(1.0, 1.0, 1.0) // center (1000,1000), radius 1000
|
||||
require.NoError(t, err)
|
||||
|
||||
w.indexObject(w.objects[id])
|
||||
|
||||
// Same geometry as points-only test:
|
||||
// viewport 10x10 px, margins 2px => canvas 14x14 px at zoom=1 => expanded span 14 units > world.
|
||||
params := RenderParams{
|
||||
ViewportWidthPx: 10,
|
||||
ViewportHeightPx: 10,
|
||||
MarginXPx: 2,
|
||||
MarginYPx: 2,
|
||||
CameraXWorldFp: 5 * SCALE,
|
||||
CameraYWorldFp: 5 * SCALE,
|
||||
CameraZoom: 1.0,
|
||||
}
|
||||
|
||||
plan, err := w.buildRenderPlanStageA(params)
|
||||
require.NoError(t, err)
|
||||
|
||||
d := &fakePrimitiveDrawer{}
|
||||
drawCirclesFromPlan(d, plan, w.W, w.H)
|
||||
|
||||
// Expect 4 circle copies, one per tile that covers the expanded canvas.
|
||||
wantNames := []string{
|
||||
"Save", "ClipRect", "AddCircle", "Fill", "Restore",
|
||||
"Save", "ClipRect", "AddCircle", "Fill", "Restore",
|
||||
"Save", "ClipRect", "AddCircle", "Fill", "Restore",
|
||||
"Save", "ClipRect", "AddCircle", "Fill", "Restore",
|
||||
}
|
||||
require.Equal(t, wantNames, d.CommandNames())
|
||||
|
||||
// At zoom=1, 1 world unit -> 1 px, so:
|
||||
// circle center at (1,1) => base copy at (3,3) like point test
|
||||
// radius 1 => 1 px
|
||||
//
|
||||
// The rest are shifted by +10px in X and/or Y due to torus tiling.
|
||||
{
|
||||
clip := requireDrawerCommandAt(t, d, 1)
|
||||
require.Equal(t, "ClipRect", clip.Name)
|
||||
requireCommandArgs(t, clip, 2, 2, 10, 10)
|
||||
|
||||
c := requireDrawerCommandAt(t, d, 2)
|
||||
require.Equal(t, "AddCircle", c.Name)
|
||||
requireCommandArgs(t, c, 3, 3, 1)
|
||||
}
|
||||
|
||||
{
|
||||
clip := requireDrawerCommandAt(t, d, 6)
|
||||
require.Equal(t, "ClipRect", clip.Name)
|
||||
requireCommandArgs(t, clip, 2, 12, 10, 2)
|
||||
|
||||
c := requireDrawerCommandAt(t, d, 7)
|
||||
require.Equal(t, "AddCircle", c.Name)
|
||||
requireCommandArgs(t, c, 3, 13, 1)
|
||||
}
|
||||
|
||||
{
|
||||
clip := requireDrawerCommandAt(t, d, 11)
|
||||
require.Equal(t, "ClipRect", clip.Name)
|
||||
requireCommandArgs(t, clip, 12, 2, 2, 10)
|
||||
|
||||
c := requireDrawerCommandAt(t, d, 12)
|
||||
require.Equal(t, "AddCircle", c.Name)
|
||||
requireCommandArgs(t, c, 13, 3, 1)
|
||||
}
|
||||
|
||||
{
|
||||
clip := requireDrawerCommandAt(t, d, 16)
|
||||
require.Equal(t, "ClipRect", clip.Name)
|
||||
requireCommandArgs(t, clip, 12, 12, 2, 2)
|
||||
|
||||
c := requireDrawerCommandAt(t, d, 17)
|
||||
require.Equal(t, "AddCircle", c.Name)
|
||||
requireCommandArgs(t, c, 13, 13, 1)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDrawCirclesFromPlan_SkipsTilesWithoutCircles(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
w := NewWorld(10, 10)
|
||||
w.resetGrid(2 * SCALE)
|
||||
|
||||
// Add only a point, no circles.
|
||||
id, err := w.AddPoint(5, 5)
|
||||
require.NoError(t, err)
|
||||
w.indexObject(w.objects[id])
|
||||
|
||||
params := RenderParams{
|
||||
ViewportWidthPx: 10,
|
||||
ViewportHeightPx: 10,
|
||||
MarginXPx: 2,
|
||||
MarginYPx: 2,
|
||||
CameraXWorldFp: 5 * SCALE,
|
||||
CameraYWorldFp: 5 * SCALE,
|
||||
CameraZoom: 1.0,
|
||||
}
|
||||
|
||||
plan, err := w.buildRenderPlanStageA(params)
|
||||
require.NoError(t, err)
|
||||
|
||||
d := &fakePrimitiveDrawer{}
|
||||
drawCirclesFromPlan(d, plan, w.W, w.H)
|
||||
|
||||
// No circles => no commands.
|
||||
require.Empty(t, d.Commands())
|
||||
}
|
||||
|
||||
func TestDrawCirclesFromPlan_ProjectsRadiusWithZoom(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
w := NewWorld(100, 100)
|
||||
w.resetGrid(10 * SCALE)
|
||||
|
||||
// radius 2 world units; zoom=2 => should be 4 px when 1 unit == 1px at zoom=1.
|
||||
id, err := w.AddCircle(50, 50, 2)
|
||||
require.NoError(t, err)
|
||||
w.indexObject(w.objects[id])
|
||||
|
||||
params := RenderParams{
|
||||
ViewportWidthPx: 10,
|
||||
ViewportHeightPx: 10,
|
||||
MarginXPx: 2,
|
||||
MarginYPx: 2,
|
||||
CameraXWorldFp: 50 * SCALE,
|
||||
CameraYWorldFp: 50 * SCALE,
|
||||
CameraZoom: 2.0,
|
||||
}
|
||||
|
||||
plan, err := w.buildRenderPlanStageA(params)
|
||||
require.NoError(t, err)
|
||||
|
||||
d := &fakePrimitiveDrawer{}
|
||||
drawCirclesFromPlan(d, plan, w.W, w.H)
|
||||
|
||||
// There should be at least one AddCircle.
|
||||
cmds := d.CommandsByName("AddCircle")
|
||||
require.NotEmpty(t, cmds)
|
||||
|
||||
// All circles in this plan should have radius 4px (2 units * 2x zoom).
|
||||
for _, c := range cmds {
|
||||
require.Len(t, c.Args, 3)
|
||||
require.Equal(t, 4.0, c.Args[2])
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user