package world import ( "testing" "github.com/stretchr/testify/require" ) func TestDrawPointsFromPlan_DuplicatesAcrossTilesAndClips(t *testing.T) { t.Parallel() // World is 10x10 world units => 10000x10000 fixed. w := NewWorld(10, 10) w.resetGrid(2 * SCALE) // Place a point near the origin so that expanded canvas (larger than world) // will require torus repetition and the point will appear in multiple tiles. id, err := w.AddPoint(1.0, 1.0) // (1000,1000) require.NoError(t, err) // Index only this object. w.indexObject(w.objects[id]) // Choose viewport such that viewport==world in pixels at zoom=1: // - With zoom=1 (zoomFp=SCALE), 1 world unit maps to 1 px. // - world width=10 units => 10 px. // Use margin=2 px on each side => canvas 14x14 px => expanded world 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{} drawPointsFromPlan(d, plan, true) // We expect 4 point copies: // (tx=0,ty=0), (tx=0,ty=1), (tx=1,ty=0), (tx=1,ty=1) // due to expanded rect spanning beyond world on both axes. wantNames := []string{ "Save", "ClipRect", "AddPoint", "Fill", "Restore", "Save", "ClipRect", "AddPoint", "Fill", "Restore", "Save", "ClipRect", "AddPoint", "Fill", "Restore", "Save", "ClipRect", "AddPoint", "Fill", "Restore", } require.Equal(t, wantNames, d.CommandNames()) pointRadiusPx := DefaultRenderStyle().PointRadiusPx // Command group 1: tile (offsetX=0, offsetY=0), clip should be (2,2,10,10), point at (3,3). { clip := requireDrawerCommandAt(t, d, 1) require.Equal(t, "ClipRect", clip.Name) requireCommandArgs(t, clip, 2, 2, 10, 10) pt := requireDrawerCommandAt(t, d, 2) require.Equal(t, "AddPoint", pt.Name) requireCommandArgs(t, pt, 3, 3, pointRadiusPx) } // Command group 2: tile (offsetX=0, offsetY=10000), clip (2,12,10,2), point at (3,13). { clip := requireDrawerCommandAt(t, d, 6) require.Equal(t, "ClipRect", clip.Name) requireCommandArgs(t, clip, 2, 12, 10, 2) pt := requireDrawerCommandAt(t, d, 7) require.Equal(t, "AddPoint", pt.Name) requireCommandArgs(t, pt, 3, 13, pointRadiusPx) } // Command group 3: tile (offsetX=10000, offsetY=0), clip (12,2,2,10), point at (13,3). { clip := requireDrawerCommandAt(t, d, 11) require.Equal(t, "ClipRect", clip.Name) requireCommandArgs(t, clip, 12, 2, 2, 10) pt := requireDrawerCommandAt(t, d, 12) require.Equal(t, "AddPoint", pt.Name) requireCommandArgs(t, pt, 13, 3, pointRadiusPx) } // Command group 4: tile (offsetX=10000, offsetY=10000), clip (12,12,2,2), point at (13,13). { clip := requireDrawerCommandAt(t, d, 16) require.Equal(t, "ClipRect", clip.Name) requireCommandArgs(t, clip, 12, 12, 2, 2) pt := requireDrawerCommandAt(t, d, 17) require.Equal(t, "AddPoint", pt.Name) requireCommandArgs(t, pt, 13, 13, pointRadiusPx) } } func TestDrawPointsFromPlan_SkipsTilesWithoutPoints(t *testing.T) { t.Parallel() w := NewWorld(10, 10) w.resetGrid(2 * SCALE) // Add only a line, no points. id, err := w.AddLine(2, 2, 8, 2) 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{} drawPointsFromPlan(d, plan, true) // No points => no drawing commands at all. require.Empty(t, d.Commands()) } func TestWorldRender_PointsOnlyStageA(t *testing.T) { t.Parallel() w := NewWorld(10, 10) w.resetGrid(2 * SCALE) _, err := w.AddPoint(5, 5) require.NoError(t, err) // Build index. In real UI it happens via IndexOnViewportChange. for _, obj := range w.objects { w.indexObject(obj) } params := RenderParams{ ViewportWidthPx: 10, ViewportHeightPx: 10, MarginXPx: 2, MarginYPx: 2, CameraXWorldFp: 5 * SCALE, CameraYWorldFp: 5 * SCALE, CameraZoom: 1.0, } d := &fakePrimitiveDrawer{} err = w.Render(d, params) require.NoError(t, err) // At least one point draw should happen. require.Contains(t, d.CommandNames(), "AddPoint") }