Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Propagate origin displacements of child structures to parent #2150

Merged
merged 3 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
nonoverlapping-structure-merge.yaml
root-map-expansion.yaml
structure-composition.yaml
sequential-placement.yaml
sequential-placement.yaml
coordinate-offset-propagation.yaml
simultaneous-north-and-west-offset.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
version: 1
name: Structure coordinate offset propagation
author: Karl Ostmo
description: |
If a structure incorporates subplacements
entailing negative offsets, its coordinate origin must be shifted.

The updated coordinate origin should be propagated to parent structures
and utilized to offset placement.
robots:
- name: base
dir: north
loc: [0, 3]
objectives:
- goal:
- Enjoy the view.
condition: |
return true
solution: |
noop
known: [boulder, log, pixel (R), pixel (G), pixel (B), gold]
world:
structures:
- name: micro
structure:
mask: '.'
palette:
'x': [stone, gold]
map: |
xx
- name: block
structure:
mask: '.'
palette:
'x': [stone, pixel (R)]
map: |
xx
xx
- name: master
structure:
mask: '.'
palette:
'x': [stone, pixel (B)]
placements:
- src: block
offset: [0, 1]
- src: micro
offset: [-2, 0]
map: |
..x
..x
..x
- name: final
structure:
mask: '.'
palette:
'x': [stone, pixel (G)]
placements:
- src: master
map: |
x
x
x
x
dsl: |
overlay
[ {grass}
, mask (y > -4 && y < 4 || x > -4 && x < 4) {stone}
, mask (y > -2 && y < 2 || x > -2 && x < 2) {ice}
, mask (y > -1 && y < 1 || x > -1 && x < 1) {dirt}
]
mask: '.'
placements:
- src: final
offset: [0, 0]
upperleft: [0, 0]
map: ""
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ objectives:
- Must have 3 of each color visible
condition: |
def countColor = \e.
resonate e ((0, 0), (10, -5));
resonate e ((-6, 0), (4, -4));
end;

as base {
Expand Down Expand Up @@ -87,7 +87,7 @@ world:
mask: '.'
placements:
- src: block
offset: [0, -1]
offset: [0, -2]
upperleft: [0, 0]
dsl: |
{grass}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
version: 1
name: Northwest sibling structure coordinate offsets
author: Karl Ostmo
description: |
Make sure that the second sibling is displayed correctly when there
is a simultaneous negative-x and positive-y offset on the first sibling.
robots:
- name: base
dir: north
loc: [0, 2]
objectives:
- goal:
- Enjoy the view.
condition: |
return true
solution: |
noop
known: [pixel (R), gold]
world:
structures:
- name: micro
structure:
mask: '.'
palette:
'x': [stone, gold]
map: |
x
- name: block
structure:
mask: '.'
palette:
'x': [stone, pixel (R)]
map: |
xx
xx
- name: master
structure:
mask: '.'
placements:
- src: micro
offset: [-1, 1]
- src: block
map: ""
dsl: |
overlay
[ {grass}
, mask (y > -4 && y < 4 || x > -4 && x < 4) {stone}
, mask (y > -2 && y < 2 || x > -2 && x < 2) {ice}
, mask (y > -1 && y < 1 || x > -1 && x < 1) {dirt}
]
mask: '.'
placements:
- src: master
offset: [0, 0]
upperleft: [0, 0]
map: ""
2 changes: 1 addition & 1 deletion data/test/standalone-topography/circle-and-crosses.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,5 @@ placements:
orient:
up: west
- src: disc
offset: [8, -8]
offset: [5, -8]
map: ""
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,7 @@ instance FromJSONE WorldParseDependencies WorldDescription where
let placedStructures =
map (offsetLoc $ coerce ul) staticStructurePlacements

-- Override upper-left corner with explicit location
let area = mergedGrid {gridPosition = ul}

let area = modifyLoc ((ul .+^) . asVector) mergedGrid
return $ WorldDescription {..}

------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion src/swarm-topography/Swarm/Game/Location.hs
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ euclidean p1 p2 = norm (fromIntegral <$> (p2 .-. p1))

-- | Converts a 'Point' to a vector offset from the 'origin'.
asVector :: Location -> V2 Int32
asVector loc = loc .-. origin
asVector (P vec) = vec

-- | Get all the locations that are within a certain manhattan
-- distance from a given location.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ data AreaDimensions = AreaDimensions
{ rectWidth :: Int32
, rectHeight :: Int32
}
deriving (Show, Eq)

getGridDimensions :: Grid a -> AreaDimensions
getGridDimensions g = getAreaDimensions $ getRows g
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
-- as well as logic for combining them.
module Swarm.Game.Scenario.Topography.Structure.Assembly (
mergeStructures,

-- * Exposed for unit tests:
foldLayer,
)
where

Expand Down Expand Up @@ -63,30 +66,15 @@ mergeStructures ::
Parentage Placement ->
PStructure (Maybe a) ->
Either Text (MergedStructure (Maybe a))
mergeStructures inheritedStrucDefs parentPlacement (Structure origArea subStructures subPlacements subWaypoints) = do
mergeStructures inheritedStrucDefs parentPlacement baseStructure = do
overlays <-
left (elaboratePlacement parentPlacement <>) $
mapM (validatePlacement structureMap) subPlacements

let wrapPlacement (Placed z ns) =
LocatedStructure
(name ns)
(up $ orient structPose)
(offset structPose)
where
structPose = structurePose z

wrappedOverlays =
map wrapPlacement $
filter (\(Placed _ ns) -> isRecognizable ns) overlays

-- NOTE: Each successive overlay may alter the coordinate origin.
-- We make sure this new origin is propagated to subsequent sibling placements.
foldlM
(flip $ overlaySingleStructure structureMap)
(MergedStructure origArea wrappedOverlays originatedWaypoints)
overlays
foldLayer structureMap origArea overlays originatedWaypoints
where
Structure origArea subStructures subPlacements subWaypoints = baseStructure

originatedWaypoints = map (Originated parentPlacement) subWaypoints

-- deeper definitions override the outer (toplevel) ones
Expand All @@ -95,6 +83,32 @@ mergeStructures inheritedStrucDefs parentPlacement (Structure origArea subStruct
(M.fromList $ map (name &&& id) subStructures)
inheritedStrucDefs

-- | NOTE: Each successive overlay may alter the coordinate origin.
-- We make sure this new origin is propagated to subsequent sibling placements.
foldLayer ::
M.Map StructureName (NamedStructure (Maybe a)) ->
PositionedGrid (Maybe a) ->
[Placed (Maybe a)] ->
[Originated Waypoint] ->
Either Text (MergedStructure (Maybe a))
foldLayer structureMap origArea overlays originatedWaypoints =
foldlM
(flip $ overlaySingleStructure structureMap)
(MergedStructure origArea wrappedOverlays originatedWaypoints)
overlays
where
wrappedOverlays =
map wrapPlacement $
filter (\(Placed _ ns) -> isRecognizable ns) overlays

wrapPlacement (Placed z ns) =
LocatedStructure
(name ns)
(up $ orient structPose)
(offset structPose)
where
structPose = structurePose z

-- * Grid manipulation

overlayGridExpanded ::
Expand All @@ -105,14 +119,13 @@ overlayGridExpanded ::
overlayGridExpanded
baseGrid
(Pose yamlPlacementOffset orientation)
-- NOTE: The '_childAdjustedOrigin' is the sum of origin adjustments
-- to completely assemble some substructure. However, we discard
-- this when we place a substructure into a new base grid.
(PositionedGrid _childAdjustedOrigin overlayArea) =
-- The 'childAdjustedOrigin' is the sum of origin adjustments
-- to completely assemble some substructure.
(PositionedGrid childAdjustedOrigin overlayArea) =
baseGrid <> positionedOverlay
where
reorientedOverlayCells = applyOrientationTransform orientation overlayArea
placementAdjustedByOrigin = gridPosition baseGrid .+^ asVector yamlPlacementOffset
placementAdjustedByOrigin = childAdjustedOrigin .+^ asVector yamlPlacementOffset
positionedOverlay = PositionedGrid placementAdjustedByOrigin reorientedOverlayCells

-- * Validation
Expand Down
Loading
Loading