Coder Social home page Coder Social logo

scatter's Introduction

ProtonScatter

Banner

Place anything you want in your scenes, in a procedural, non-destructive way.

What is it?

This is an add-on for Godot 4, which automates the positioning of assets in a scene. If you have a lot of props to place, and you would rather not do it by hand, ProtonScatter may be useful to you.

scatter_project.mp4
scatter_showcase.mp4
Placing grass on arbitrary geometry Editing the showcase scene

The showcase scene composition was entirely done using ProtonScatter. First, large rocks are randomly placed within an area, then trees, grass and other details are projected onto the rocks' colliders surface.

How does it work?

The basic setup is as follows:

setup

  • A ProtonScatter (1) node holds the positionning rules (2) that can be edited in the inspector. This panel is very similar to Blender's modifier stack panel. Some modifiers create points, others change their transforms. You mix different modifiers in order to obtain the result you need.

  • One or more ScatterItem nodes to select which asset you want to place.

  • One or more ScatterShape items to define the area where the scattering happens.

Creating points

grid random along_edge
Placing items aligned on a grid Placing items randomly Placing items along an edge

Defining the domain

Scatter currently ships with three shape types: Box, Sphere and Path. They can be combined to create more complex shapes. Notice how in the last example, the box is shown in red. This means the shape is marked as 'negative' and new items won't appear inside.

box sphere path combined_shapes

Other uses

Most of the examples above placed items on the floor or on a flat plane, but nothing stops you from using the full 3D space. The mushrooms are placed in the space, then projected in a random direction until they hit a tree. The tower in the background is done by stacking individual bricks using two array modifiers.

scatter_v4_mushroom.mp4

FAQ

How to install this addon?

Using the asset lib

  • Using the asset lib, look for ProtonScatter and click on Install.
  • If nothing appears, that means the add-on was not accepted yet, so use the manual method.

Manually

  • Download or clone this repository.
  • Copy the proton_scatter folder into your project's add-on folder.
  • DO NOT rename the proton_scatter folder, or it won't work.
  • Go to your Projects settings > Plugins > and enable ProtonScatter.

Does it work on Godot 3.x ?

  • Go to the v3 branch and install it from there.
  • Keep in mind that ProtonScatter was completely rewritten and overhauled for Godot 4, there will be significant differences.
  • If you're upgrading your project from Godot 3 to Godot 4, the previous Scatter objects will NOT be compatible anymore.

Where's the documentation?

  • Click on any ProtonScatter node and look at the Modifier Stack in the inspector.
  • You will see a Doc button in the top right corner. Click it to access the built-in documentation.

image

License

  • This add-on is published under the MIT license.
  • About the game assets under the demo folder:
    • 3D assets are under the MIT license.
    • Most textures bundled with this project have been created with images from Textures.com. You cannot redistribute them on their own, but they're free to use as part of a bigger project. Please visit www.textures.com for more information.

scatter's People

Contributors

addmix avatar atzuk4451 avatar deakcor avatar dillonsteyl avatar florianvazelle avatar hungryproton avatar jegber avatar norodix avatar realgdman avatar runkli avatar solitaryurt avatar tokisangames avatar yurisizov avatar zodywoolsey avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

scatter's Issues

"Project on Floor/Align with Floor normal" doesn't account for object's global rotation

Hello, thank you for great addon.
I'm using Godot 3.4.beta4 and latest Scatter

I've tried to create roads with it, and noticed that "Project on Floor" / "Align with Floor normal" doesn't take into account the global rotation of whole object.
You can notice on screenshot that panels "Distributed along the Path" correctly, but rotated instance have every individual brick overturned.

image

In my case, there is workaround, because I care only about rotation around Y axis, in project_on_floor.gd:

if align_with_floor_normal:
	var gt: Transform = transforms.path.get_global_transform()
	t = _align_with(t, hit.normal.rotated(Vector3.UP, -gt.basis.get_euler().y))

But I don't know what would be general solution.
Added simple repro project. Thanks again.
ScatterNormalsBug.zip

Add better controls to select a node in the scene tree

Currently, the "exclude" modifiers rely on a text field to know which node to use.
It's error prone so we should copy Godot default interface as much as possible by adding a select button next to the text field. This button displays a popup with the scene tree, allows the user to select a node and fills the text input automatically.

Error with Signals in curve_panel.gd

Hey, just grabbed latest mainline and I'm getting an error about "Signals" not being declared. curve_panel.gd didn't exist when I tried this plugin a couple months ago, so I'm guessing this is new WIP code? Or maybe something failed to get checked in?

"Project on Floor" not working

I've been trying to use the "project on floor" setting but it's not working, even in the demo scene, when I modify the "GrassMultimesh" enough for it to change it ends up ignoring any physics obstacles, this happens as well on my own scenes. The only useful information I've gotten are this errors shown on console:
scene/main/node.h:281 - Condition "!data.tree" is true. Returned: __null scene/resources/curve.cpp:1056 - Index p_index = -1 is out of bounds (points.size() = 8). scene/resources/curve.cpp:1076 - Index p_index = -1 is out of bounds (points.size() = 0).

Intend to support frustrum or distance culling?

Playing around with this and I love the way you've setup the modifiers, very smart!

Godot 4.x already supports Occlusion culling, but in Godot 3.x I'm not sure if frustrum culling is applied to MultiMeshInstance.

Usually I get around this by adding a VisibilityNotifier and disabling the object when it becomes invisible from the camera.

Since we're using MultiMeshInstance perhaps splitting the terrain into groups and allowing hiding would work better.

Any idea about how we could support something like that?

Scatter creates too many orphan nodes that aren't cleared

The modifier stack object, and all the individual modifiers, are node objects instead of Resources.

  • These orphaned node aren't cleared on exit.
  • This is a big oversight from me, but it can't be changed without breaking backward compatibility with existing projects.
  • The 4.0 update would be the time to fix this properly.

In the meantime for the 3.x version, we need to make sure all these nodes are added to the tree, so they can be cleaned on exit.

Scatter Not Closely Following Path Bug

In this project, but also every other one regarding this addon that I have used, the paths don't adhere closely to the path as in the demos. This can make it hard to make good dense meshes. Open the feature_list.tscn, and take a look at the two scatters that are left. I have added a new one called "Simple - Error", which shows the issue.

GodotBugs.zip

Heres a highlight of the problem:
Desktop Screenshot 2021 08 10 - 00 59 19 20
As you can see, here is a picture of the path(s)(outlined for clarity). The top ones are from the demo, and the bottom one represents the error. The ones in the demo adhere very closely to the line, while any other ones that are created do not respect the line,no matter the modifier setting.

To recreate this in any project, simply create the scatter node, child a scatter item, give an item, create a path, and the mesh won't align closely with the line.

I have tried copying all the modifier settings from the original, but no success. Maybe I did miss a setting, but I do not believe so.
This problem isn't noticeable on big areas, however as you start to handle tight spots, corners etc. this becomes a major issue.

Add linear continuity placement option for distribute along path

image
Placement along path option that maps linear segments onto the path, creating continuous placement of objects
image
Possible emulation using Curve3D 'bake interval' property and apply offset modifier
image
This method of emulation acts the same as the proposed method, but it less obvious for users

Allow specifying a different instance count for editor

My Mackbook is not so great in terms of GPU ๐Ÿ˜…

It can handle a lot of objects while testing a game, but I'd rather not thrash away at the GPU while I'm editing the map.

Perhaps having an option to decimate the mesh instance while in the editor would solve this? That way I can test and everything looks great, but I don't waste my battery life or have to listen to my fans while I'm editing the map.

There is no way for me to compensate your incredible work.

I'm sorry for posting this in the issues section. I just don't have a Twitter account and I would really like to, at the very least, give you 10-15 bucks for your hard work. I couldn't find any sort of patreon or donate link anywhere. If you're not interested I understand, but I like to support game developers that are willing to do all of this work and give it away for nothing. I'm sure there are many other people that would be more than happy to support your work. Just a thought. Feel free to close this. There is no real issue. The addon itself is pretty flawless so far. Does what it says on the tin and it works well and fast.

Can I control "Instance Count" programmatically?

I'm developing a 3D platformer and have used your plugin and the grass from the demo (with proper credit) in the game. I'm using 4000 instances of the MultiMeshInstance in my scene but I'd like to allow the player to decrease the amount of grass rendered to increase performance.

I haven't found a way to access the "Instance Count" variable in the "Distribute Inside (Random)" modifier programmatically in the documentation. Is this possible? Thank you!

image

Edit: The repo with the game if anyone is interested.

Is it possible to add support for HTerrain snap to colliders

Fairly new to commenting on github, so hopefully this is the right place to make a request.

This plugin is pretty amazing, the only issue I have is there seems to be no support for supporting HTerrain and snap to colliders, It'll snap to the ground plane at height 0, but if you use HTerrain to create hills or divots, the curve won't snap to them, placing the curves manually can result in floating objects as it's a bit hard to get it perfect. Support for this or even a trick to get this to work in the current version would be amazing.

Below I have a picture of what I mean, there's a small hill created using the HTerrain plugin, the curve nodes just sit inside the hill not conforming to it, whereas the other two on the right have and do snap to the height 0 terrain. The only immediate workaround I can think of this is to convert the HTerrain into a mesh and generate its tri-mesh collision, I'll give this a try tho it's just annoying to have to reset it all every time I want to adjust the terrain using HTerrain.
Issue

Use the built-in "changed" signal on every resources

I did not know that when I wrote most of the add-on but every Resource class have a built in "changed" signal that's automatically send when a parameter is changed so I can make use of that instead of doing it manually by emitting "parameter_updated" every time in the setget method.

This should make the source code a fair bit smaller and the wiki should be updated as well

Imported mesh data get duplicated

If you use scatter without multimesh, it creates copies of the mesh data instead of creating an external reference (meaning imported meshes won't update if you edit them). Seems this is caused by the recursive set owner. I changed _set_owner_recursive to just set the owner on the node and not its children, and that seemed to fix it. Not sure if there's a reason for setting the owner on the children.

Add an option to hide the grid

Hi,
i cannot find an option to hide the orange grid, that currently overlays all scattered objects.
It doesn't seem to have any use apart from showing the bounding area of the path.
It would be nice to be able to hide only it, as hiding the gizmo via godot options also hides the path, which is not desired.

Edit: this seems to be mostly a godot bug. If the Scatter node is selected and deselected the toolbar options linger, which makes this grid stay in the world. To remove it another node has to be selected.
It would still be helpful to hide it to better see the geometry underneath it.

[Tracker] Breaking changes to do for the 4.0 update

This issue should be updated with all the changes that should be done but can't because they break backward compatibility.

  • Most of the custom classes should inherit Resources (or References) instead of Node, see #55
  • The orientation options in Distribute along Path are confusing and some combinations are broken. Should be replaced by something simpler.
  • ...

Distribute Inside (Poisson) modifier doesn't shuffle the results

When you use more than one ScatterItem with Poisson, you end up with it placing each item in a clump rather than randomized within the area as you would expect. Using shuffle(transforms.list, global_seed) at the end of it like Distribute Inside (Grid) fixes this, but I don't know if there was a reason for this omission or if it was just an error.

Quick modifier access for performance scaling

I was wondering how to disable shadows at runtime, I see that's an option in the ScatterItem node, but I didn't dig through the code enough yet to figure out how it's mapping to the MeshInstances.

Having the ability to modify the modifiers such as count or shadows from code would be very useful for performance scaling optimisation.

Some users may feel OK without shadows displaying, while others with a better GPU will want the whole experience.

This may be related to #64 as with better abilities to modify the instance set it would become quite simple to toggle instance count while running in the editor.

Scene change crash to desktop

When two scenes have scatter nodes, and in each scene you have the scatter node selected, switching scenes causes a crash to desktop.

Steps to reproduce

Open two scenes, each containing a scatter node, in each scene select the scatter node, attempt to switch to the other scene.

Add offset along path

Offset position of objects along path, with bounds of (1, -1)
No offset
image
Proposed offset along path (Offset value of 1)
image
Proposed offset along path (Offset value of -1)
image
(Examples created using the new apply offset modifier, thanks Proton)

Issues with using 'apply offset' modifier

No offset modifier
image
Emulated path offset using apply offset modifier
Notice the incorrect placement at corners, objects extend past path location
image

Draw the grid only when necessary

Currently, the grid is drawn only when lock to plane is enabled, but when selecting another object, the grid stays on.
This quickly creates visual clutter when lots of paths are placed in the same area.

Support StaticBodys & Colliders

It would be great if Scatter would support StaticBodys and Colliders and copy them from the source node to the MeshInstance, if that is possible.
Example hierarchy:
image

Add configuration warnings

  • When the curve resource is missing or empty
  • When a ScatterItem is missing
    • On the ScatterItem when the scene path is empty
  • When the logic resource is missing
  • When the logic resource reports having a wrong configuration

Scatter Addon Not Working With Shader Material

ScatterBug.zip

In the editor, the scatter item displays correctly and uses a multimesh instance.
In the game, the scatter items don't have a material when using a multimesh instance.

Disabling "use instancing" will allow the materials to work, however this isn't a performance friendly option for massive amounts of items.

I do not know if this is intentional(I would assume not, since you can see the scatter items WITH their respective materials in the editor while using a multimesh instance)

Using a material/geometry override for the material can be a simple workaround, however it does not work if your item has multiple materials( so this hack would work for something like grass, but if you wanted to do something like a tree, no go.)

If upon loading the project the trees have no material in the editor, click on the main scatter nodes to reload the materials.

Again, if it works within the editor I would assume its a glitch/bug, but unsure

Scatter Items seem to go wildly outside their path

I was having issues with Scatter not staying within the bounds of the Curve3D path in my own scene, so I tried creating a new one inside the feature_list scene to ensure all the properties were correct.

Screenshot of an example, you can see the path and where the grass is being scattered. Above it I modified the Scatter - Simple node path to be much smaller and that seems to work. As far as I know, they both have the same modifiers activated.

Screenshot from 2021-01-27 18-50-44

ScatterItem can delete materials from MeshInstances in .tscn files if they're in Item Path

Hi. A quick word of warning, I am having a really hard time getting this bug to happen consistently. I want to give some quick details of what this might be to help tl;dr this currently incomplete issue:

  • Using Scatter 2.7.2
  • Using an Intel IGP HD Graphics 620: an IGP that doesn't like Godot GLES3 sometimes, but shouldn't affect resource errors like this.
  • I am getting ScatterItem to retain materials most of the time if I save my material resources as .tres, rather than leaving them embedded in a .tscn scene that I'm instancing.
  • I've only ever had Use Instancing on when using Scatter
  • The multimesh inside a ScatterItem shows me the material when it's there, and doesn't have the material when it's gone. I don't know if it's the culprit or just the messenger.
  • Here's my scatter modifier stack:
    image

I am working on a minimal reproduction project, but this is taking longer than expected, so I want to get this word out now in case others can fill-in with their experience.

I can give any bug-hunters my project file if you want to look for other inconsistencies, DM me on discord: Ember#1765

Essentially,

If you add a .tscn with a MeshInstance (using a primitive) to a ScatterItem after an unknown series of steps, the material associated with the MeshInstance will be removed from the mesh. If your material is an embedded resource, not saved as a .tres, that material is effectively deleted. Here is one example of a scene that's victim to this:

image

Thankfully, I saved this material as a .tres and applied it to the child MeshInstance. I didn't realize that Use Instancing was duplicating the first mesh it found rather than instancing the entire scene. From this evidence, I guess I added the material inside the Mesh resource for both MeshInstances.

image

Retracing my steps

If I save a node like this:
image

And put it in the ScatterItem's Item Path property:

image

Sometimes I can leave the scene and re-enter, only to find that the ScatterItem appears grey and empty, and the .tscn where I saved the Scene (with a Mesh root or Mesh child) has its material removed. I am still trying to fill this gap of the exact steps I took. I recall selecting the MultiMeshInstance node as well.

I can "rebuild", play the game, close the scene and re-open it, quit the project and open it again, switch tabs from 3D to 2D and Script and back, move the path around, add and remove points, it just won't remove on-command.

For a while, playing the game was fine, but resetting the scene using get_tree().reload_current_scene() at runtime temporarily made the materials a default white.
image

Mysteriously, this doesn't work anymore, the material stays. I probably need to start from a new project to try and narrow this down.

I think the magic mix to reproduce this bug is:

  • Use embedded materials, not saved
  • Place materials inside the mesh resource
  • Save a .tscn with a MeshInstance root
  • Instance the .tscn with a ScatterItem using Item Path
  • Use Distribute Even (? may not matter)
  • Use Instancing is on, so it generates a MultiMeshInstance
  • Run the scene without directly saving the original .tscn (but keep the default behaviour to save on play) so it's forced to save the Scatter scene first, then the original .tscn, then it runs the game.

Speculation

I wonder if the problem of removing materials happens when Scatter takes control of the original material resource, and changes its material to match something else that's unset. When Scatter does this in tool mode, this becomes a permanent change.

Other details

I am checking my files with Fork to see how my project changes. I didn't screenshot it, but I had a ShaderMaterial added and embedded in one commit, but it reported to have changed itself to refer an ExtResource that didn't exist elsewhere in the resource.

image

Imagine this but there's no ExtResource to point to.

Add a warning icon to modifiers

Add a warning icon (like the one from the configuration warning in the scene tree).
The behavior would be the same and this could be used to detect:

  • Invalid parameters
    • With the Exclude From Path modifier, if the supplied node name doesn't exists, it could warn the user about it.
  • Other issues
    • Project on Floor deletes anything that didn't touch the floor by default. If there's no collider under, the user may think the modifier doesn't work. Instead, we could display a warning saying that all the raycats missed and you should probably either add a collider or increase the ray length.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.