Ambient
Ambient copied to clipboard
dynamic collisions on Prefab entities
I have an entity that is is loaded as a prefab from the pipeline like:
[[pipelines]]
type = "Models"
sources = ["*.glb"]
[pipelines.collider]
type = "FromModel"
The entity looks like
let player_mesh_id = Entity::new()
.with(name(), "PlayerMesh".to_string())
.with(parent(), player_controller_id)
.with(local_to_parent(), Default::default())
.with(local_to_world(), Default::default())
.with_merge(make_transformable())
.with(prefab_from_url(), assets::url("fighter01.glb"))
.with(scale(), Vec3::ONE * 0.3)
// rotate blender mesh to fit world coordinates
.with(
rotation(),
Quat::from_rotation_z(-std::f32::consts::FRAC_PI_2)
* Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2),
)
.spawn();
I dynamically move this entity from parent transformations, It's collision is updated like: https://github.com/AmbientRun/Ambient/pull/885
I noticed when moving this entity through other collision bodies it doesn't register collisions. I dug into the physxs components a bit more and found that by default the entity is treated as a 'static' body and collisions don't get registered unless its a 'dynamic' entity. I tried adding the dynamic
component to this entity .with(dynamic(), true)
. This did nothing.
I built another test case in which I tried on another non-prefab collision body and the dynamic
component worked as expected.
Entity::new()
.with(name(), "Bullet".to_string())
.with(bullet_owner_ref(), player_id)
.with_merge(make_sphere())
.with(sphere_collider(), 1.0)
.with(dynamic(), true)
.with(scale(), vec3(0.1, 0.7, 1.0))
.with(self::color(), vec4(1., 0.1, 1., 1.))
.with_merge(make_transformable())
.with(
translation(),
ship_position + (bullet_heading.normalize() * 1.3),
)
.with(bullet_target(), bullet_heading.normalize())
.spawn();
I saw in the asset pipeline docs there's flag to specify collision type. I updated the pipeline to add the collision type like:
[[pipelines]]
type = "Models"
sources = ["*.glb"]
collider_type = "Dynamic"
[pipelines.collider]
type = "FromModel"
The prefab entity is now correctly registered as a "Dynamic" Physics body and collisions get registered. But there is undesired behavior now in which the physx engine transformation updates override the custom transformations I have built. Essentially I have lost control of the entities translation and rotation because its receiving its updates from the physics engine.
How can I get collision behavior similar to the Bullet entity ? Also could somebody point me to where the physics components like dynamic
are applied during the prefab_from_url
construction?
@kevzettler It sounds like what you want is kinematic
(here's the physx docs: https://gameworksdocs.nvidia.com/PhysX/4.1/documentation/physxguide/Manual/RigidBodyDynamics.html#kinematic-actors ).
Also it might be worth to try to dump the server state to make sure the entities have the right components (ambient run --debugger
and the click "dump server world")
I have added the .with(kinematic(), ())
component and this fixes the behavior with the collision body being hijacked and managed by physxs instead of our dynamic updates. Unfortunately it still does not register collision events against other bodies.
@kevzettler Could you try putting a breakpoint of println here and see if the collision is triggered at all from physx? https://github.com/AmbientRun/Ambient/blob/main/crates/physics/src/lib.rs#L73
From the server dump server_hiearchy.yml
Here is the player mesh prefab that is behaving incorrectly...
- "id=ZQrAWe9bxjNyWRQfX_4pMQ loc=62:0":
"ambient_core::app::name": "\"PlayerMesh\""
"ambient_core::hierarchy::parent": "EntityId(IcWsLFGOhVxDguFC9DCqaw, 143111078922968181966099845513996977441)"
"ambient_core::model::model_from_url": "\"ambient-assets:/lsvr7wpee4biw3sleyscm7har4xzjvoa/assets/ships/fighter01.glb/models/main.json\""
"ambient_core::physics::angular_velocity": "Vec3(0.0, 0.0, 0.0)"
"ambient_core::physics::collider_loaded": ()
"ambient_core::physics::dynamic": "true"
"ambient_core::physics::kinematic": ()
"ambient_core::physics::linear_velocity": "Vec3(0.0, 0.0, 0.0)"
"ambient_core::prefab::prefab_from_url": "\"ambient-assets:/lsvr7wpee4biw3sleyscm7har4xzjvoa/assets/ships/fighter01.glb\""
"ambient_core::prefab::spawned": ()
"ambient_core::transform::local_to_parent": "Mat4 { x_axis: Vec4(1.1920929e-7, -0.9999999, 0.0, 0.0), y_axis: Vec4(0.0, 1.1920929e-7, -0.9999999, 0.0), z_axis: Vec4(0.9999999, 0.0, 1.1920929e-7, 0.0), w_axis: Vec4(0.0, 0.0, 0.0, 1.0) }"
"ambient_core::transform::local_to_world": "Mat4 { x_axis: Vec4(0.76182234, -0.64778584, 1.1400717e-7, 0.0), y_axis: Vec4(0.5385441, 0.6333498, -0.55573195, 0.0), z_axis: Vec4(0.35999534, 0.423369, 0.8313614, 0.0), w_axis: Vec4(779.1699, 2185.8381, 160.05618, 1.0) }"
"ambient_core::transform::rotation": "Quat(-0.49999997, 0.49999997, -0.49999997, 0.49999997)"
"ambient_core::transform::scale": "Vec3(1.0, 1.0, 1.0)"
"ambient_core::transform::translation": "Vec3(0.0, 0.0, 0.0)"
"ambient_core::physics::rigid_actor": "..."
"ambient_core::physics::rigid_dynamic": "..."
"ambient_core::physics::physics_shape": "..."
"ambient_core::physics::collider": "Asset { collider: TypedAssetUrl(ambient-assets:/lsvr7wpee4biw3sleyscm7har4xzjvoa/assets/ships/fighter01.glb/colliders/main.json, PhantomData<ambient_native_std::uncategorized::asset_url::ColliderAssetType>) }"
"ambient_core::physics::collider_type": Dynamic
"ambient_core::physics::collider_shapes": "..."
"ambient_core::physics::collider_shapes_convex": "..."
"lsvr7wpee4biw3sleyscm7har4xzjvoa::owner_player_id": "EntityId(KHqDENPKWRgWP4v1KaajKA, 54018834423678847093558392131707697704)"
children: []
Here is the bullet mesh that is behaving correctly....
- "id=zxu8sgSKTmMjdfZDbQqFoQ loc=74:0":
"ambient_core::app::name": "\"Bullet\""
"ambient_core::physics::angular_velocity": "Vec3(0.0, 0.0, 0.0)"
"ambient_core::physics::collider_loaded": ()
"ambient_core::physics::dynamic": "true"
"ambient_core::physics::linear_velocity": "Vec3(0.0, 0.0, 0.0)"
"ambient_core::physics::mass": "5.57528"
"ambient_core::physics::physics_controlled": ()
"ambient_core::physics::sphere_collider": "1.0"
"ambient_core::physics::visualize_collider": ()
"ambient_core::primitives::sphere": ()
"ambient_core::primitives::sphere_radius": "0.5"
"ambient_core::primitives::sphere_sectors": "36"
"ambient_core::primitives::sphere_stacks": "18"
"ambient_core::rendering::color": "Vec4(1.0, 0.1, 1.0, 1.0)"
"ambient_core::transform::local_to_world": "Mat4 { x_axis: Vec4(1.1, 0.0, 0.0, 0.0), y_axis: Vec4(0.0, 1.7, 0.0, 0.0), z_axis: Vec4(0.0, 0.0, 2.0, 0.0), w_axis: Vec4(1227.4658, 3602.9219, -546.807, 1.0) }"
"ambient_core::transform::rotation": "Quat(0.0, 0.0, 0.0, 1.0)"
"ambient_core::transform::scale": "Vec3(1.1, 1.7, 2.0)"
"ambient_core::transform::translation": "Vec3(1228.5403, 3605.1194, -547.6371)"
"ambient_core::gizmos::local_gizmos": "[Sphere { origin: Vec3(1227.4658, 3602.9219, -546.807), radius: 0.15, color: Vec3(1.0, 0.0, 0.0), border_width: 0.15 }, Sphere { origin: Vec3(1227.4658, 3602.9219, -546.807), radius: 0.1, color: Vec3(0.0, 1.0, 0.0), border_width: 0.1 }]"
"ambient_core::physics::rigid_actor": "..."
"ambient_core::physics::rigid_dynamic": "..."
"ambient_core::physics::physics_shape": "..."
"ambient_core::physics::collider": "Sphere { radius: 1.0, center: Vec3(0.0, 0.0, 0.0) }"
"ambient_core::physics::collider_type": Dynamic
"ambient_core::physics::collider_shapes": "..."
"ambient_core::physics::collider_shapes_convex": "..."
"lsvr7wpee4biw3sleyscm7har4xzjvoa::bullet_heading": "Vec3(0.41596055, 0.8507181, -0.32133415)"
"lsvr7wpee4biw3sleyscm7har4xzjvoa::bullet_auto_aim_target": "EntityId(AAAAAAAAAAAAAAAAAAAAAA, 0)"
"lsvr7wpee4biw3sleyscm7har4xzjvoa::owner_player_id": "EntityId(KHqDENPKWRgWP4v1KaajKA, 54018834423678847093558392131707697704)"
children: []
@FredrikNoren I tried this
@kevzettler Could you try putting a breakpoint of println here and see if the collision is triggered at all from physx? https://github.com/AmbientRun/Ambient/blob/main/crates/physics/src/lib.rs#L73
The breakpoint was triggered for the primitive Bullet entities but not the prefab entity...
Looking above at the server hierarchy dump the the prefab seems to be missing the
"ambient_core::physics::physics_controlled": ()
Where the primitive shape has that. Seems suspicious.
@kevzettler If you look in the prefab file (i.e. assets/your_model.glb/prefabs/main.json
), does it have it there? I checked a file here and it didn't seem to have it. Think that might be the problem.
This is what my prefab json looks like:
{"AQAAAAAAAAAAAAAAAAAAAA":{"ambient_core::hierarchy::children":["9AJ0r_AW2-LkEBvlDIZamA"]},"9AJ0r_AW2-LkEBvlDIZamA":{"ambient_core::model::model_from_url":"../models/main.json","ambient_core::physics::collider":{"Asset":{"collider":"../colliders/main.json"}},"ambient_core::physics::collider_type":"Dynamic"}}%
Not seeing mention of "ambient_core::physics::physics_controlled"
suspicious that there is a reference in the children
array. Not sure what the hierarchy is here there is only one mesh in the .glb
The ..colliders/main.json
file it references is also there
kevzettler@kevs-mbp-3 aceclone % cat build/lsvr7wpee4biw3sleyscm7har4xzjvoa/assets/ships/fighter01.glb/colliders/main.json
{"concave":[[[1.0,0.0,0.0,0.0,0.0,0.0,1.0,0.0,0.0,1.0,0.0,0.0,0.0,0.0,0.0,1.0],"../px_triangle_meshes/mesh_0_0.pxtm"]],"convex":[[[-0.9999999,0.0,0.0,0.0,0.0,5.9604645e-8,0.99999994,0.0,0.0,0.99999994,5.9604645e-8,0.0,0.0,0.0,0.0,1.0],"../px_convex_meshes/mesh_0_0_npp.pxcm"]]}%
I've tried adding physics_controlled
at runtime like:
.with(physics_controlled(), ())
.with(kinematic(), ())
.with(dynamic(), true)
but it doesn't seem to persist in the server_hierarchy dump..
One detail I don't know if I mentioned is that I can trigger collisions between:
primitve runtime entities -> prefab dynamics
So at some level the prefab dynamics are in the physx
Also
primitive runtime entities -> prefab statics
Works as well
but not
prefab dynamics -> prefab statics
I have added the
.with(kinematic(), ())
component and this fixes the behavior with the collision body being hijacked and managed by physxs instead of our dynamic updates. Unfortunately it still does not register collision events against other bodies.
Are these other bodies being dynamic or static? If you look at the documentation of PhysX 4.1 under the kinematic actors, it says:
There is no interaction or collision between kinematic actors and static actors. However, it is possible to request contact information for these cases with the PxSceneDesc::kineKineFilteringMode and PxSceneDesc::staticKineFilteringMode.
It is possible that you are hitting one of those edge cases (by design), as those flags are not set by default because they come with a performance cost. (We may need to expose those somehow).
If one of those actors where actually dynamic bodies, then I would expect the contacts to be reported by the callback.
@fabiopolimeni I built a minimal isolated reproduction case for this issue at:
https://github.com/kevzettler/ambient_collision_bug
you can git clone
it and ambient run
It makes 2 cubes. one prefab and one runtime and collides them into the ground. The prefab one exhibits the issue I described above. The collisions are logged with println!
the prefab and runtime cubes collide. The runtime and ground collide. The prefab and ground do not collide.