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

New System for Tile Map, Tile Set, and Brush #714

Merged
merged 51 commits into from
Jan 10, 2025
Merged

Conversation

b-guild
Copy link
Contributor

@b-guild b-guild commented Dec 24, 2024

This tile map system is still a work in progress, but it is now a work in progress that is actually useable. It does everything the current tile map system can do and more. After weeks of working on it alone, I am making this pull request so that I can get some help with this enormous project. I cannot find all the problems with it myself, though I have tried and it seems to work quite well. There is just too much for one person.

It needs a lot more documentation and testing, but here are the major features that it already has:

  • Brushes and tile sets each contain multiple pages. Each page contains its own hashmap of tiles, and you can switch which page you are using by selecting a page from the area above the tiles, where each page is represented by a tile that serves as the icon for that page.
  • Brush pages allow a single brush to fill the role of multiple brushes. Instead of switching brushes, we can switch pages. Therefore I have simplified TileMap to remove the list of brushes that is no longer needed. If there is a need to switch brushes, the current brush can be changed by dragging a brush asset into the tile map control panel.
  • Tile set pages come in three flavors, each serving a different use:
    • The Material page allows you to specify a material and a tile size to easily create tiles from an atlas. Unlike the current system, this is not a one-time operation to create these tiles. Instead, the material can be replaced and the tile size can be changed at any time. Any tiles from that page in a tile map will adjust themselves accordingly, because tile map tiles know what page they are from and their position in the page.
    • The Freeform page allows you to create arbitrary tiles without needing an atlas. You can specify any material and the positions of the four corners of the tile in texture coordinates. You can put copies of existing tiles into the page by drawing them using the tile map control panel, much like drawing tiles to a tile map, but with the additional freedom to be able to flip and rotate any tile to any orientation. This allows the creation of mirrored or rotated versions of tiles from an atlas using the same material as the atlas but with different UVs.
    • The Transform Set page contains handles to tiles from other pages in groups of 8. These groups represent the ways in which a tile can be transformed by flipping and rotating. The 8 are arranged in a 2x4 rectangle. The left 2x2 area represents four 90-degree rotations, and the right 2x2 area represents those same rotations but horizontally mirrored. Thanks to this, we can flip and rotate tiles while editing a tile map, and the editor will automatically find the appropriate transformed version of the tile.
  • Collision now has multiple layers, with each layer identified by a name and UUID. The tile set editor has a tab for adding, removing, renaming, and changing the color of each layer. This is important because a single tile map will often need multiple physics bodies with different properties. Of course there is a solid rigid body for walls and floors, but often there will also be a need for icy surfaces and areas that the player can pass through, and so on. Each physics object can be assigned to a particular collision layer in the tile map.
  • A custom collider option has been added, allowing the user to specify arbitrary triangles. There is currently no GUI interface for this system; the user needs to type the triangles in as a list of points and index-triples in a provided text area. This is a clear place where improvement is possible.
  • Properties are now shared by all tiles in a tile set. Each tile does not have its own independent list of properties, but rather each tile set has a list of properties, and each tile has only its own values for those properties. This creates consistency across the tile set, with each property having a particular type, and optional list of named pre-defined values, and an order in which the properties will be presented in the tile set editor.
  • Tile map tool randomness is now a option that can be toggled using a button with a dice icon. A randomized rect fill will use random tiles from the current selection, while a non-randomized rect fill will repeat the current selection as many times as necessary to fill the area.
  • A preview widget shows the current selected tiles and adjusts itself to show those tiles after the rotations and flips have been applied. The tile map control panel now has rotation and flip buttons, though they are only fully effective for tiles that contain rotations and flips in some Transform Set page of the tile set.

@mrDIMAS
Copy link
Member

mrDIMAS commented Dec 24, 2024

17k lines... O. M. G. That's for sure will take some time to review :)

@b-guild
Copy link
Contributor Author

b-guild commented Dec 24, 2024

I think it might be wise to rename material pages to atlas pages and change the names of related concepts to match. I may not have given enough thought to what things are named in this project, so there may be other names that should be changed.

@b-guild
Copy link
Contributor Author

b-guild commented Dec 26, 2024

If anything is in any way confusing or unclear, I would be very happy to add comments, rename things, re-organize things, or in other ways adjust the PR so that it is easier to understand.

editor/src/plugins/tilemap/tile_set_import.rs Outdated Show resolved Hide resolved
fyrox-impl/src/scene/tilemap/edit.rs Outdated Show resolved Hide resolved
editor/src/plugins/tilemap/tile_bounds_editor.rs Outdated Show resolved Hide resolved
editor/src/plugins/tilemap/tileset.rs Outdated Show resolved Hide resolved
editor/src/plugins/tilemap/tileset.rs Outdated Show resolved Hide resolved
fyrox-impl/src/scene/tilemap/mod.rs Outdated Show resolved Hide resolved
fyrox-impl/src/scene/tilemap/mod.rs Outdated Show resolved Hide resolved
fyrox-impl/src/scene/tilemap/mod.rs Outdated Show resolved Hide resolved
fyrox-impl/src/scene/tilemap/edit.rs Outdated Show resolved Hide resolved
fyrox-impl/src/scene/tilemap/tileset.rs Outdated Show resolved Hide resolved
]
.map(TriangleDefinition);

let sort_index = 0; //ctx.calculate_sorting_index(render_position.position());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is confusing. I suppose highlighting should be always on top, and thus this index should have some large value, and definitely not zero. I maybe missing something.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was an experiment from a time when the highlight rendering was not working properly, and after I got the highlight working properly I forgot to undo the experiment since there was no need to fix something that was not broken. I do not actually know what sort_index does. It would be nice to have detailed documentation for RenderDataBundleStorageTrait because rendering can be quite a complex topic and some people need all the help they can get.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was an experiment from a time when the highlight rendering was not working properly, and after I got the highlight working properly I forgot to undo the experiment since there was no need to fix something that was not broken. I do not actually know what sort_index does. It would be nice to have detailed documentation for RenderDataBundleStorageTrait because rendering can be quite a complex topic and some people need all the help they can get.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out that a sort_index of 0 works, but using calculate_sorting_index causes the cursor to prevent the selection from rendering. I tried adding 1 to the sorting index of the selection, but it turns out that calculate_sorting_index was returning u64::MAX, so adding one caused a crash. Next I tried saturating_sub(1), which I suppose causes the selection to render before the cursor, thereby allowing them both to appear.

I am far from a shader expert, but it seems that the shader is checking the depth buffer before rendering, so things that render earlier at minimum depth can prevent things from rendering later at minimum depth. That depth check probably should not exist when we create a 2D version of this shader.

Copy link
Member

@mrDIMAS mrDIMAS left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finally, I finished the review. There are very few small issues in general, could you please fix them and I'll merge the PR right after.

Erase,
/// Flood a the cells of a tile map, replacing regions of identical cell. This operation is only possible on a tile map.
/// For tile set and brush editing, this oepration behaves exactly like [`DrawingMode::Draw`].
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Type oepration.

Comment on lines 787 to 790
scene
.graph
.try_get(*h)
.and_then(|n| n.component_ref::<TileMap>())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JFYI you could use scene.graph.try_get_of_type::<TileMap>(*h) instead, it does exactly the same as try_get + component_ref.

Comment on lines 461 to 463
if self.kind != TilePaletteStage::Tiles {
panic!();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be better to use assert_eq!(self.kind, TilePaletteStage::Tiles)

editor/src/plugins/tilemap/palette.rs Outdated Show resolved Hide resolved
}
}
fn accept_material_drop(&mut self, _material: MaterialResource, _ui: &UserInterface) {
// TODO
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's this todo about? Could you please add more info so it can be done later without seeking for additional info?

editor/src/plugins/tilemap/tile_inspector.rs Outdated Show resolved Hide resolved
@b-guild
Copy link
Contributor Author

b-guild commented Jan 10, 2025

As I was trying to take some screen shots for my future book PR, I managed to make the editor crash. I will have to fix that problem before this PR is merged.

@mrDIMAS
Copy link
Member

mrDIMAS commented Jan 10, 2025

Should I merge the PR or you have something to change? The stuff that I highlighted is not critical and I can merge without fixing those tiny issues.

@b-guild
Copy link
Contributor Author

b-guild commented Jan 10, 2025

I think there are no more problems to fix. If I find any problems I can fix them in the animation PR that I'll do next. That PR is almost ready to go. I'll just do the book PR first.

1 similar comment
@b-guild
Copy link
Contributor Author

b-guild commented Jan 10, 2025

I think there are no more problems to fix. If I find any problems I can fix them in the animation PR that I'll do next. That PR is almost ready to go. I'll just do the book PR first.

@mrDIMAS mrDIMAS merged commit 392db10 into FyroxEngine:master Jan 10, 2025
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants