|
|
|
 |
Reply From: |
klaas |
Hi,
the easiest way to rotate around the up-axis is rotate_y( radiants )
rotate_y( rand_range(0, PI * 2) )
https://docs.godotengine.org/en/stable/classes/class_spatial.html#class-spatial-method-rotate-y
How would I use rotate_y in this case? I cannot apply it to the transform, and I can’t apply it to the position vector I am moving the trees to. If I could get the actual instances of the trees perhaps I could apply it to them, but I’m not sure how to do that.
I could do rotate_y on the multimesh node, but that would rotate the entire plane of trees.
As far as I know I have to use the .rotated() function on my transform.
I can do
transformation.rotated(Vector3(0, 1, 0), rand_range(0, PI * 2))
but this makes some of my trees rotate off of my terrain mesh.
In the meantime I have abandoned the multimesh in my actual project and I am just instancing new tree scenes and placing them at the coordinates, this allows me to use the rotate_y function, but I thought using a multimesh would be better for performance.
Thummper | 2020-07-20 12:51
You would use it on multiMeshInstance wich is a decendand of spatial that implements the method rotate_y
Is there any way I can rotate individual instances of trees in my multimesh?
If I just rotate the whole multimesh then some of the trees will end up rotating off of my terrain - I want to apply a randomized individual rotation to each tree.
Thummper | 2020-07-20 16:54
Ok, got it now.
You have to set transform_format of your MultiMeshInstance to 3D (you can only do so if the instance count is zero, so put it back to zero make it 3D then set the count back to your value).
Here is a litle script that rotates and places the instances randomly on startup:
func _ready():
for i in range(multimesh.instance_count):
var transform = Transform()
transform = transform.translated(Vector3(rand_range(-5,5), 0, rand_range(-5,5)))
transform = transform.rotated(Vector3.UP,rand_range(0,PI * 2))
multimesh.set_instance_transform(i, transform)
make sure your trees have there pivot right in the middle bottom of the mesh
There is although a tool to populate a surface with instances … read about it here:
Using MultiMeshInstance3D — Godot Engine (stable) documentation in English
So when I use rotate like that I still end up with trees being rotated off of the map for some reason.
extends MultiMeshInstance
export(int) var treeScale = 6
func _ready():
self.scale = Vector3(treeScale, treeScale, treeScale)
func updatePositions(posArray):
print("Update tree positions")
for i in self.multimesh.instance_count:
var pos = posArray[i]
pos.y -= 6
pos /= treeScale
var transformation = Transform()
transformation = transformation.translated(pos)
transformation = transformation.rotated(Vector3.UP, rand_range(0, PI*2))
multimesh.set_instance_transform(i, transformation)
With rotation in I get trees like this that go off the map: Imgur: The magic of the Internet
With rotation commented out I get trees that stay on the map: Imgur: The magic of the Internet
Any ideas on how to fix this?
Thummper | 2020-07-20 19:23
Is the pivot of the tree is in the exact center of the tree?
I believe it is. I get the same behavior when I replace the tree mesh with a new cube mesh that is definitely positioned properly as well.
I get my desired behavior (i think), when I use this:
extends MultiMeshInstance
export(int) var treeScale = 6
func _ready():
self.scale = Vector3(treeScale, treeScale, treeScale)
func updatePositions(posArray):
print("Update tree positions")
for i in self.multimesh.instance_count:
var pos = posArray[i]
pos /= treeScale
var b = transform.basis.rotated(Vector3.UP, rand_range(0, PI*2))
var t = Transform(b, pos)
multimesh.set_instance_transform(i, t)
Not sure why this works but the other doesn’t.
Thummper | 2020-07-20 20:03
okay, i messed it up … but now
first rotate then reposition
func _ready():
for i in range(multimesh.instance_count):
var transform = Transform()
transform = transform.rotated(Vector3.UP,rand_range(0,PI * 2))
transform.origin = Vector3(rand_range(-4.8,4.8),0,rand_range(-4.8,4.8))
multimesh.set_instance_transform(i, transform)