From 358b88e7fe466e8909b4b84345f9560ebcc3d593 Mon Sep 17 00:00:00 2001 From: Amatsugu Date: Sun, 24 Nov 2024 00:05:07 -0500 Subject: [PATCH] gltf prefabs --- game/buildings/src/assets/building_asset.rs | 95 ++++++++++++++++----- game/buildings/src/building_plugin.rs | 17 +++- game/main/assets | 2 +- game/main/src/phos.rs | 2 + game/shared/src/animation_plugin.rs | 18 ++++ game/shared/src/component_defination.rs | 20 +++++ game/shared/src/lib.rs | 2 + game/shared/src/prefab_defination.rs | 20 ++++- 8 files changed, 150 insertions(+), 26 deletions(-) create mode 100644 game/shared/src/animation_plugin.rs create mode 100644 game/shared/src/component_defination.rs diff --git a/game/buildings/src/assets/building_asset.rs b/game/buildings/src/assets/building_asset.rs index 765619e..0cdbb3e 100644 --- a/game/buildings/src/assets/building_asset.rs +++ b/game/buildings/src/assets/building_asset.rs @@ -1,7 +1,10 @@ use asset_loader::create_asset_loader; -use bevy::{gltf::GltfMesh, prelude::*}; +use bevy::{ + gltf::{GltfMesh, GltfNode}, + prelude::*, +}; use serde::{Deserialize, Serialize}; -use shared::{identifiers::ResourceIdentifier, prefab_defination::*}; +use shared::{component_defination::ComponentDefination, identifiers::ResourceIdentifier, prefab_defination::*}; use crate::{ buildings::{ @@ -29,7 +32,7 @@ pub struct BuildingAsset { pub health: u32, pub building_type: BuildingType, - pub children: Option>, + pub components: Option>, } impl BuildingAsset { @@ -40,30 +43,78 @@ impl BuildingAsset { gltf: &Gltf, commands: &mut Commands, meshes: &Assets, + nodes: &Assets, ) -> Option { - let keys: Vec<_> = gltf.named_meshes.keys().collect(); - info!("{keys:#?}"); - let mesh_handle = &gltf.named_meshes[&self.base_mesh_path.clone().into_boxed_str()]; - if let Some(gltf_mesh) = meshes.get(mesh_handle.id()) { - let (mesh, mat) = gltf_mesh.unpack(); - let mut entity = commands.spawn(( - PbrBundle { - mesh, - material: mat, - transform: Transform::from_translation(pos) - .with_rotation(Quat::from_rotation_arc(Vec3::NEG_Z, Vec3::Y) * rot), - ..Default::default() - }, - Building, - )); - if let Some(children) = &self.children { + let base_node = &gltf.named_nodes[&self.base_mesh_path.clone().into_boxed_str()]; + if let Some(node) = nodes.get(base_node.id()) { + if let Some(mesh_handle) = &node.mesh { + if let Some(gltf_mesh) = meshes.get(mesh_handle.id()) { + let (mesh, mat) = gltf_mesh.unpack(); + let mut entity = commands.spawn(( + PbrBundle { + mesh, + material: mat, + transform: Transform::from_translation(pos).with_rotation(rot), + ..Default::default() + }, + Building, + )); + entity.with_children(|b| { + for child in &node.children { + self.process_node(child, meshes, b, &node.name); + } + }); + if let Some(component) = self.get_component_def(&format!("/{0}", &node.name)) { + component.apply(&mut entity); + } + return Some(entity.id()); + } + } + } + return None; + } + + fn process_node( + &self, + node: &GltfNode, + meshes: &Assets, + commands: &mut ChildBuilder, + parent: &String, + ) -> Option { + let path = format!("{0}/{1}", parent, node.name); + if let Some(mesh) = &node.mesh { + if let Some(gltf_mesh) = meshes.get(mesh.id()) { + let (mesh, mat) = gltf_mesh.unpack(); + let mut entity = commands.spawn(( + PbrBundle { + mesh, + material: mat, + transform: node.transform, + ..Default::default() + }, + Building, + )); entity.with_children(|b| { - for child in children { - child.spawn_recursive(gltf, b, meshes); + for child in &node.children { + self.process_node(child, meshes, b, &path); } }); + if let Some(component) = self.get_component_def(&path) { + component.apply(&mut entity); + } + return Some(entity.id()); + } + } + return None; + } + + fn get_component_def(&self, path: &String) -> Option<&ComponentDefination> { + if let Some(components) = &self.components { + for c in components { + if c.path.eq(path) { + return Some(c); + } } - return Some(entity.id()); } return None; } diff --git a/game/buildings/src/building_plugin.rs b/game/buildings/src/building_plugin.rs index bfd207f..40719fd 100644 --- a/game/buildings/src/building_plugin.rs +++ b/game/buildings/src/building_plugin.rs @@ -1,6 +1,11 @@ use std::f32::consts::E; -use bevy::{ecs::world::CommandQueue, gltf::GltfMesh, prelude::*, window::PrimaryWindow}; +use bevy::{ + ecs::world::CommandQueue, + gltf::{GltfMesh, GltfNode}, + prelude::*, + window::PrimaryWindow, +}; use bevy_asset_loader::loading_state::{ config::{ConfigureLoadingState, LoadingStateConfig}, LoadingStateAppExt, @@ -123,6 +128,7 @@ fn process_build_queue( building_assets: Res>, gltf_assets: Res>, gltf_meshes: Res>, + gltf_nodes: Res>, mut building_map: ResMut, heightmap: Res, ) { @@ -132,7 +138,14 @@ fn process_build_queue( let h = heightmap.sample_height(&item.pos); println!("Spawning {} at {}", building.name, item.pos); if let Some(gltf) = gltf_assets.get(building.prefab.id()) { - let e = building.spawn(item.pos.to_world(h), Quat::IDENTITY, gltf, &mut commands, &gltf_meshes); + let e = building.spawn( + item.pos.to_world(h), + Quat::IDENTITY, + gltf, + &mut commands, + &gltf_meshes, + &gltf_nodes, + ); if let Some(b) = e { building_map.add_building(BuildingEntry::new(item.pos, b)); } diff --git a/game/main/assets b/game/main/assets index 4f7ec75..bba1aa9 160000 --- a/game/main/assets +++ b/game/main/assets @@ -1 +1 @@ -Subproject commit 4f7ec753b1ee5c3194506c66717ee082cbca2f69 +Subproject commit bba1aa96298ca39418f897ab45197ab975d87b07 diff --git a/game/main/src/phos.rs b/game/main/src/phos.rs index e0461eb..0e43288 100644 --- a/game/main/src/phos.rs +++ b/game/main/src/phos.rs @@ -15,6 +15,7 @@ use bevy_rapier3d::geometry::Collider; use bevy_rapier3d::plugin::{NoUserData, RapierPhysicsPlugin}; use buildings::BuildingPugin; use iyes_perf_ui::prelude::*; +use shared::animation_plugin::SimpleAnimationPlugin; use shared::sets::GameplaySet; use shared::states::{GameplayState, MenuState}; use shared::{despawn::DespawnPuglin, states::AssetLoadState}; @@ -38,6 +39,7 @@ impl Plugin for PhosGamePlugin { MapInitPlugin, RenderDistancePlugin, BuildingPugin, + SimpleAnimationPlugin, // BuildUiPlugin, UnitsPlugin, DespawnPuglin, diff --git a/game/shared/src/animation_plugin.rs b/game/shared/src/animation_plugin.rs new file mode 100644 index 0000000..44cdd50 --- /dev/null +++ b/game/shared/src/animation_plugin.rs @@ -0,0 +1,18 @@ +use bevy::prelude::*; + +use crate::prefab_defination::RotationAnimation; + +pub struct SimpleAnimationPlugin; + +impl Plugin for SimpleAnimationPlugin { + fn build(&self, app: &mut App) { + app.add_systems(Update, rotate); + } +} + +fn rotate(mut query: Query<(&mut Transform, &RotationAnimation)>, time: Res