Mattiny / yamms

Yet Another MultiMesh Scatter for Godot
MIT License
31 stars 3 forks source link

Feature Request: Normal rotation, single-float scaling, and random scale curves #23

Closed ghost closed 7 months ago

ghost commented 11 months ago

I have recently been making some changes to my local copy of YAMMS. First I'd like to say: thank you! This is a fantastic plugin and you've done the Godot community a great service in making it.

My first addition was pulling the normal Vector3 from hit in the PMDropOn scripts. Using: var hit_normal = hit["normal"] `var normal_rot = Vector3(rad_to_deg(asin(deg_to_rad(hit_normal.z))), 0.0, -1.0 rad_to_deg(asin(deg_to_rad(hit_normal.x)))) var normal_displacement = (normal_rot * normal_influence) + rotation ... var transform = create_transform(hit_pos, normal_displacement, scale)` I was able to align scattered instances to terrain, influenced by a normal influence exported variable Float in MultiScatteritem: 0.0 will align to world Y, 1.0 will align to surface terrain. Worth noting I haven't checked this with PMDropOnCeiling, yet.

My second addition was swapping out the max_scale Vector3 with a simple Float, and having the resultant random value multiply by a Vector3.ONE. This scales uniformly, which I tend to find more convenient for e.g. plants, where non-uniform scale can look a bit strange. Perhaps a toggle for uniform/non-uniform could flip the max_scale between Float and Vector3? I also added a min_scale Float for my usage, simply as QoL as my assets tend to be on the small side.

My third addition was adding a Curve, scale curve, exported variable in MultiScatterItem alongside the scale parameters. Along with my previous addition, this changes the "Generate random scale" section of the PlacementMode script to the following: var _scale = Vector3(1.0, 1.0, 1.0) if scatterData["RandomScale"]: var min_scale = scatterData["MinScale"] var max_scale = scatterData["MaxScale"] var scale_curve = scatterData["ScaleCurve"] var curve_sample = scale_curve.sample(generate_random(0.0,1.0)) _scale = Vector3.ONE * (curve_sample * (max_scale - min_scale) + min_scale) This allows for default random scaling using a Linear Curve, or more complex scaling by adding/changing curve handle position/number/rotation. For example, when used on plants, an Ease-In Curve can produce lots of small plants, with a few very large plants randomly placed throughout, which looks very nice.

Hope this is of some use to you! sploopst

image

Mattiny commented 10 months ago

Hello,

Thank you very much for your contribution. This seems to be a useful addition. I will go through this to add it in the next release.

Sorry, my reply took a long time. But right now I am back, working on new things again.

andrew-buist commented 9 months ago

apologies for the ghost - I have merged accounts to my main. thanks for picking this up! let me know if I can be of any help

Mattiny commented 9 months ago

No worries. It takes some time for me to reply as well.

As for the "Normal Influence" on the rotation: The solution you suggest works fine. There is just one issue which needs to be solved. When normal influence and random rotation is enabled, both rotations are performed via global axis. This results in the object rotated by normal influence as expected. But then the random rotation takes place via global axis as well, so the resulting object is tilted in the wrong direction.

The solution i found so far is, doing the transform two times separately for each rotation individually.

        var transform = create_transform(hit_pos, rotation, scale)
        scatter_item.do_transform(index, transform)

        transform = create_transform(hit_pos, normal_displacement, Vector3(1.0, 1.0, 1.0))
        scatter_item.do_transform(index, transform)

Is there a way to perform both rotations together in one step?

andrew-buist commented 9 months ago

good question - I get a bit lost with vectors (I would always do the one then the other to save mental capacity haha) but I would guess you'd need to do some quaternion multiplication. https://docs.godotengine.org/en/3.5/classes/class_quat.html

Mattiny commented 7 months ago

Added