Hi,
I tried to generate a field of mining resources (asteroids, etc.) in 3D space. As visual instances I used different MultiMeshInstances (one for each possible mesh) feeded by a MeshLibrary. Within a script I generate random positions, rotations and scalings and applied them to the different MultiMeshInstances.
func generate_field() -> void:
for _element_index in range(max_element_count):
var index: int = rng.get_random_int(0, _multi_mesh_instances.size()-1)
var mmi = get_multi_mesh_instance(index)
# get an unused position
var element_position = Vector3.ZERO
while not element_position in _positions:
element_position = rng.get_random_vector_3d(-extension, extension) * element_density # !!! not clamped atm, so extension will be bigger
if not element_position in _positions:
_positions.append(element_position)
_position_indices.append(index)
var element_rotation_amount = rng.get_random_float(0, 359)
var scale_factor = rng.get_random_float(min_scale_factor, max_scale_factor)
var element_scale = Vector3.ONE * scale_factor
var xform: Transform = Transform.translated(element_position).scaled(element_scale).rotated(Vector3.ONE.normalized(), element_rotation_amount)
mmi.add_instance(xform)
The last function call (add_instance) is in a script representing my MultiMeshInstance to apply another visible instance of its MultiMesh with the given transform:
func add_instance(xform: Transform) -> void:
multimesh.visible_instance_count += 1
multimesh.set_instance_transform(multimesh.visible_instance_count-1, xform)
var scale_factor = xform.basis.get_scale()
# !!! create collision shape here
var ps = PhysicsServer
var body = ps.body_create()
ps.body_set_mode(body, ps.BODY_MODE_RIGID)
ps.body_set_state(body, ps.BODY_STATE_TRANSFORM, xform)
ps.body_set_state(body, ps.BODY_STATE_CAN_SLEEP, true)
ps.body_set_param(body, ps.BODY_PARAM_GRAVITY_SCALE, 0)
ps.body_set_param(body, ps.BODY_PARAM_MASS, 100 * ((scale_factor.x * scale_factor.y * scale_factor.z) / 3))
ps.body_set_enable_continuous_collision_detection(body, true)
ps.body_set_max_contacts_reported(body, 10)
ps.body_set_space(body, get_world().space)
ps.body_set_collision_layer(body, 1)
ps.body_set_collision_mask(body, 1)
var shape = ps.shape_create(ps.SHAPE_CONVEX_POLYGON)
ps.shape_set_data(shape, collision_shape.shape.points) #is this correct?
ps.body_add_shape(body, shape)
ps.body_set_shape_transform(body, 0, xform)
ps.body_set_force_integration_callback(body, self, "_on_body_moved", 0)
_bodies.append(body) # just to keep reference of the created physics bodies
_shapes.append(shape)`# keep the created shapes too (not really neccessary)
In the same script i try to change the transform for the corresponding visible instance of the multi mesh (not sure if it will work this way):
func _on_body_moved(state, index) -> void:
multimesh.set_instance_transform(index, state.transform)
The visual part works fine and all meshes are visible. But I can't get a collision with the player (a KinematicBody scene). I checked the collision layers and masks too (all are at 1). I also tried to comment out some lines out corresponding to some rigid body properties (continuous cd, contact reports, can sleep).
Example of the problem can be viewed at Youtube
What could have been missing or doing wrong?
Is it possible to draw collisions in debug for PhysicsServer-created elements too (like the ones from scenes) and if yes, how? (it would be helpful to see, if collisions are at the correct transform)
If anything is not clear, I can post more situation details.
Thx for help in advance and cheers
Z3R0PTR