use ambient_app::{gpu, AppBuilder};
use ambient_core::{asset_cache, camera::active_camera, main_scene, transform::scale, FixedTimestepSystem};
use ambient_ecs::{FnSystem, World};
use ambient_element::ElementComponentExt;
use ambient_physics::physx::{physics_controlled, rigid_dynamic, rigid_static, sync_ecs_physics, PhysicsKey};
use ambient_primitives::{Cube, Quad};
use ambient_renderer::color;
use ambient_std::{asset_cache::SyncAssetKeyExt, math::SphericalCoords};
use glam::*;
use physxx::*;
use rand::random;
fn init(world: &mut World) -> PxSceneRef {
let _gpu = world.resource(gpu()).clone();
let assets = world.resource(asset_cache()).clone();
let physics = PhysicsKey.get(&assets);
world.add_resource(ambient_physics::physx::physics(), physics.clone());
let scene = {
let mut scene_desc = PxSceneDesc::new(physics.physics);
scene_desc.set_cpu_dispatcher(&physics.dispatcher);
scene_desc.set_gravity(vec3(0., 0., -9.82));
PxSceneRef::new(&physics.physics, &scene_desc)
};
let physics_material = PxMaterial::new(physics.physics, 0.5, 0.5, 0.6);
let ground_static = PxRigidStaticRef::new_plane(physics.physics, vec3(0., 0., 1.), 0., &physics_material);
scene.add_actor(&ground_static);
Quad.el().with(scale(), Vec3::ONE * 40.).with(color(), vec4(0.5, 0.5, 0.5, 1.)).with(rigid_static(), ground_static).spawn_static(world);
for _ in 0..10 {
let actor = PxRigidDynamicRef::new_with_geometry(
&physics.physics,
&PxTransform::from_translation(vec3(10. * (random::<f32>() * 2. - 1.), 10. * (random::<f32>() * 2. - 1.), 10.)),
&PxBoxGeometry::new(1., 1., 1.),
&physics_material,
10.,
&PxTransform::identity(),
);
scene.add_actor(&actor);
Cube.el().with(rigid_dynamic(), actor).with_default(physics_controlled()).spawn_static(world);
}
ambient_cameras::spherical::new(vec3(0., 0., 0.), SphericalCoords::new(std::f32::consts::PI / 4., std::f32::consts::PI / 4., 5.))
.with(active_camera(), 0.)
.with(main_scene(), ())
.spawn(world);
scene
}
#[tokio::main]
async fn main() {
AppBuilder::simple()
.run(|app, _| {
ambient_physics::init_all_components();
let scene = init(&mut app.world);
app.systems.add(Box::new(FixedTimestepSystem::new(1. / 60., Box::new(sync_ecs_physics()))));
app.systems.add(Box::new(FixedTimestepSystem::new(
1. / 60.,
Box::new(FnSystem::new(move |_world, _| {
scene.fetch_results(true);
scene.simulate(1. / 60.);
})),
)));
})
.await
}