summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-02-17 22:19:46 +0100
committermetamuffin <metamuffin@disroot.org>2025-02-17 22:19:46 +0100
commitaa6158cb24785871b21e60eed378e3205d1be0b6 (patch)
tree056cf9c78464a51377287131608f6d7a417b8c1a
parent0315b90767ccbaa1dcde11d450976f1dc0c928ba (diff)
downloadweareserver-aa6158cb24785871b21e60eed378e3205d1be0b6.tar
weareserver-aa6158cb24785871b21e60eed378e3205d1be0b6.tar.bz2
weareserver-aa6158cb24785871b21e60eed378e3205d1be0b6.tar.zst
import particles
-rw-r--r--shared/src/resources.rs42
-rw-r--r--world/src/main.rs48
2 files changed, 86 insertions, 4 deletions
diff --git a/shared/src/resources.rs b/shared/src/resources.rs
index 76e52f8..19ce6b2 100644
--- a/shared/src/resources.rs
+++ b/shared/src/resources.rs
@@ -31,6 +31,7 @@ pub struct Prefab {
pub collision: Vec<(Affine3A, Resource<CollisionPart>)>,
pub light: Vec<(Vec3A, Resource<LightPart>)>,
pub armature: Vec<Resource<ArmaturePart>>,
+ pub particles: Vec<(Affine3A, Resource<ParticlesPart>)>,
pub environment: Option<Resource<EnvironmentPart>>,
}
@@ -48,6 +49,16 @@ pub struct EnvironmentPart {
}
#[derive(Debug, Default, Clone)]
+pub struct ParticlesPart {
+ pub sprite: Option<Resource<MeshPart>>,
+ pub density: Option<f32>,
+ pub lifetime: Option<f32>,
+ pub lifetime_spread: Option<f32>,
+ pub velocity: Option<Vec3A>,
+ pub velocity_spread: Option<Vec3A>,
+}
+
+#[derive(Debug, Default, Clone)]
pub struct MeshPart {
pub name: Option<String>,
pub index: Option<Resource<Vec<[u32; 3]>>>,
@@ -209,6 +220,9 @@ impl ReadWrite for Prefab {
for x in &self.armature {
write_kv_opt(w, b"armature", &Some(x.clone()))?;
}
+ for x in &self.particles {
+ write_kv_opt(w, b"particles", &Some(x.clone()))?;
+ }
write_kv_opt(w, b"environment", &self.environment)?;
Ok(())
}
@@ -220,6 +234,7 @@ impl ReadWrite for Prefab {
b"collision" => Ok(s.collision.push(read_slice(v)?)),
b"light" => Ok(s.light.push(read_slice(v)?)),
b"armature" => Ok(s.armature.push(read_slice(v)?)),
+ b"particles" => Ok(s.particles.push(read_slice(v)?)),
b"environment" => Ok(s.environment = Some(read_slice(v)?)),
x => Ok(warn!(
"unknown prefab key: {:?}",
@@ -270,6 +285,33 @@ impl ReadWrite for EnvironmentPart {
Ok(s)
}
}
+impl ReadWrite for ParticlesPart {
+ fn write(&self, w: &mut dyn Write) -> Result<()> {
+ write_kv_opt(w, b"density", &self.density)?;
+ write_kv_opt(w, b"sprite", &self.sprite)?;
+ write_kv_opt(w, b"lifetime", &self.lifetime)?;
+ write_kv_opt(w, b"lifetime_spread", &self.lifetime_spread)?;
+ write_kv_opt(w, b"velocity", &self.velocity)?;
+ write_kv_opt(w, b"velocity_spread", &self.velocity_spread)?;
+ Ok(())
+ }
+ fn read(r: &mut dyn Read) -> Result<Self> {
+ let mut s = Self::default();
+ read_kv_iter(r, |k, v| match k {
+ b"density" => Ok(s.density = Some(read_slice(v)?)),
+ b"sprite" => Ok(s.sprite = Some(read_slice(v)?)),
+ b"lifetime" => Ok(s.lifetime = Some(read_slice(v)?)),
+ b"lifetime_spread" => Ok(s.lifetime_spread = Some(read_slice(v)?)),
+ b"velocity" => Ok(s.velocity = Some(read_slice(v)?)),
+ b"velocity_spread" => Ok(s.velocity_spread = Some(read_slice(v)?)),
+ x => Ok(warn!(
+ "unknown environment part key: {:?}",
+ String::from_utf8_lossy(x)
+ )),
+ })?;
+ Ok(s)
+ }
+}
impl ReadWrite for MeshPart {
fn write(&self, w: &mut dyn Write) -> Result<()> {
write_kv_opt(w, b"name", &self.name)?;
diff --git a/world/src/main.rs b/world/src/main.rs
index 7552dde..1931fdb 100644
--- a/world/src/main.rs
+++ b/world/src/main.rs
@@ -20,7 +20,7 @@ pub mod mesh;
pub mod physics;
pub mod vrm;
-use anyhow::{Result, anyhow};
+use anyhow::{Context, Result, anyhow};
use clap::Parser;
use gltf::{Gltf, Node, image::Source, import_buffers, scene::Transform};
use humansize::BINARY;
@@ -30,6 +30,8 @@ use mesh::import_mesh;
use physics::import_physics;
use rand::random;
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
+use serde::Deserialize;
+use serde_json::Value;
use std::{
borrow::Cow,
collections::{BTreeMap, HashMap},
@@ -47,7 +49,7 @@ use weareshared::{
Affine3A, Vec3A,
helper::ReadWrite,
packets::{Data, Object, Packet, Resource},
- resources::{ArmaturePart, EnvironmentPart, Image, LightPart, Prefab},
+ resources::{ArmaturePart, EnvironmentPart, Image, LightPart, ParticlesPart, Prefab},
store::ResourceStore,
vec3a,
};
@@ -230,7 +232,14 @@ fn main() -> Result<()> {
// eprintln!("{:?}", node.extensions());
// eprintln!("{:?}", node.extras());
// }
- if !node.name().unwrap_or_default().ends_with("-collider") {
+ let name = node.name().unwrap_or_default();
+ let extras: Value = node
+ .extras()
+ .to_owned()
+ .map(|v| serde_json::from_str(v.get()).unwrap())
+ .unwrap_or(Value::Object(Default::default()));
+
+ if !name.ends_with("-collider") {
if let Some(mesh) = node.mesh() {
import_mesh(
mesh,
@@ -248,7 +257,36 @@ fn main() -> Result<()> {
)?;
}
}
- let (position, _, _) = node.transform().decomposed();
+ if extras.get("particles") == Some(&Value::Bool(true)) {
+ #[derive(Deserialize)]
+ struct ParticlesAttr {
+ density: Option<f32>,
+ lifetime: Option<f32>,
+ lifetime_spread: Option<f32>,
+ velocity: Option<Vec3A>,
+ velocity_spread: Option<Vec3A>,
+ }
+ // let sprite = extras
+ // .get("sprite")
+ // .ok_or(anyhow!("particle volume is missing sprite"))?;
+
+ let attr: ParticlesAttr =
+ serde_json::from_value(extras).context("particles attributes")?;
+
+ info!("adding particles part");
+ prefab.particles.push((
+ transform_to_affine(node.transform()),
+ store.set(&ParticlesPart {
+ sprite: None,
+ density: attr.density,
+ lifetime: attr.lifetime,
+ lifetime_spread: attr.lifetime_spread,
+ velocity: attr.velocity,
+ velocity_spread: attr.velocity_spread,
+ })?,
+ ));
+ }
+
if let Some(light) = node.light() {
let name = node.name().map(|e| e.to_owned());
if let Some(name) = &name {
@@ -260,6 +298,7 @@ fn main() -> Result<()> {
if let Some(e) = emission {
debug!("emission is {e}");
}
+ let (position, _, _) = node.transform().decomposed();
prefab.light.push((
Vec3A::from_array(position),
store.set(&LightPart {
@@ -280,6 +319,7 @@ fn main() -> Result<()> {
a.collision.extend(b.collision);
a.mesh.extend(b.mesh);
a.light.extend(b.light);
+ a.particles.extend(b.particles);
a.environment = a.environment.or(b.environment);
a.name = a.name.or(b.name);
Ok(a)