#[cfg(feature = "editor-protocol-agent")]
mod agent;
#[cfg(feature = "editor-protocol-agent")]
pub use agent::*;
use crate::ecs::audio::components::AudioSource;
use crate::ecs::camera::components::Camera;
use crate::ecs::decal::components::Decal;
use crate::ecs::gizmos::GizmoMode;
use crate::ecs::light::components::Light;
use crate::ecs::material::components::Material;
use crate::ecs::particles::components::ParticleEmitter;
use crate::ecs::scene::{SceneChunkConfig, SceneLayerConfig};
use crate::ecs::text::components::TextProperties;
pub use crate::prelude::{
Atmosphere, CharacterControllerComponent, ColliderComponent, NavMeshAgent, RigidBodyComponent,
};
use serde::{Deserialize, Serialize};
pub use crate::ecs::audio::components::AudioSource as AudioSourceComponent;
pub use crate::ecs::camera::components::{
Camera as CameraComponent, OrthographicCamera, PerspectiveCamera, Projection,
};
pub use crate::ecs::decal::components::Decal as DecalComponent;
pub use crate::ecs::gizmos::GizmoMode as GizmoModeKind;
pub use crate::ecs::light::components::{AreaLightShape, Light as LightComponent, LightType};
pub use crate::ecs::material::components::{AlphaMode, Material as MaterialComponent};
pub use crate::ecs::particles::components::ParticleEmitter as ParticleEmitterComponent;
pub use crate::ecs::physics::components::ColliderShape;
pub use crate::ecs::physics::types::RigidBodyType;
pub use crate::ecs::primitives::{CameraCullingMask, CullingMask, RenderLayer};
pub use crate::ecs::text::components::TextProperties as TextPropertiesComponent;
pub use crate::prelude::{Atmosphere as AtmosphereKind, Vec2, Vec3, Vec4};
pub const MESSAGE_KEY: &str = "message";
pub const CANVAS_KEY: &str = "canvas";
pub const BYTES_KEY: &str = "bytes";
pub const GLTF_KEY: &str = "gltf";
pub const RESOURCES_KEY: &str = "resources";
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum TouchPhase {
Started,
Moved,
Ended,
Cancelled,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(
feature = "editor-protocol-agent",
derive(enum2schema::Schema),
schema(string_enum)
)]
pub enum ShapeKind {
Cube,
Plane,
Cylinder,
Cone,
Sphere,
Torus,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(
feature = "editor-protocol-agent",
derive(enum2schema::Schema),
schema(string_enum)
)]
pub enum LightKind {
Point,
Spot,
Directional,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(
feature = "editor-protocol-agent",
derive(enum2schema::Schema),
schema(string_enum)
)]
pub enum GeneratorKind {
Building,
Room,
Tower,
Stairs,
Columns,
Perimeter,
CityBlock,
Courtyard,
Wfc,
WfcCity,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(
feature = "editor-protocol-agent",
derive(enum2schema::Schema),
schema(string_enum)
)]
pub enum PolyhavenCategory {
Hdris,
Models,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum ComponentKind {
ParticleEmitter,
Decal,
AudioSource,
RigidBody,
Collider,
CharacterController,
NavmeshAgent,
Camera,
Text,
AnimationPlayer,
Visibility,
CastsShadow,
Light,
RenderLayer,
CullingMask,
CameraCullingMask,
IgnoreParentScale,
AudioListener,
CollisionListener,
PhysicsInterpolation,
MorphWeights,
MaterialVariants,
PanOrbitCamera,
ThirdPersonCamera,
CameraEnvironment,
CameraPostProcess,
ConstrainedAspect,
ViewportUpdateMode,
}
#[derive(Clone, Serialize, Deserialize)]
pub enum ComponentPayload {
Light(Light),
Visibility(bool),
CastsShadow(bool),
Camera(Camera),
RigidBody(RigidBodyComponent),
Collider(ColliderComponent),
CharacterController(CharacterControllerComponent),
NavmeshAgent(NavMeshAgent),
ParticleEmitter(Box<ParticleEmitter>),
Decal(Decal),
AudioSource(AudioSource),
RenderLayer(RenderLayer),
CullingMask(CullingMask),
CameraCullingMask(CameraCullingMask),
IgnoreParentScale(bool),
MorphWeights(Vec<f32>),
Text {
content: String,
properties: TextProperties,
},
}
impl ComponentPayload {
pub fn kind(&self) -> ComponentKind {
match self {
Self::Light(_) => ComponentKind::Light,
Self::Visibility(_) => ComponentKind::Visibility,
Self::CastsShadow(_) => ComponentKind::CastsShadow,
Self::Camera(_) => ComponentKind::Camera,
Self::RigidBody(_) => ComponentKind::RigidBody,
Self::Collider(_) => ComponentKind::Collider,
Self::CharacterController(_) => ComponentKind::CharacterController,
Self::NavmeshAgent(_) => ComponentKind::NavmeshAgent,
Self::ParticleEmitter(_) => ComponentKind::ParticleEmitter,
Self::Decal(_) => ComponentKind::Decal,
Self::AudioSource(_) => ComponentKind::AudioSource,
Self::RenderLayer(_) => ComponentKind::RenderLayer,
Self::CullingMask(_) => ComponentKind::CullingMask,
Self::CameraCullingMask(_) => ComponentKind::CameraCullingMask,
Self::IgnoreParentScale(_) => ComponentKind::IgnoreParentScale,
Self::MorphWeights(_) => ComponentKind::MorphWeights,
Self::Text { .. } => ComponentKind::Text,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
pub enum AnimationCommand {
Play { index: u32 },
PlayAll,
Pause,
Resume,
Stop,
Seek { time: f32 },
SetSpeed { speed: f32 },
SetLooping { looping: bool },
}
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "editor-protocol-agent", derive(enum2schema::Schema))]
pub struct GenerationSettings {
pub footprint_x: f32,
pub footprint_z: f32,
pub stories: u32,
pub story_height: f32,
pub wall_thickness: f32,
pub floor_thickness: f32,
pub window_spacing: f32,
pub seed: u32,
pub variation: f32,
}
#[derive(Clone, Copy, PartialEq, Serialize, Deserialize)]
pub struct RenderSettingsState {
pub ambient_light: [f32; 4],
pub bloom_enabled: bool,
pub bloom_intensity: f32,
pub bloom_threshold: f32,
pub bloom_knee: f32,
pub bloom_filter_radius: f32,
pub ssao_enabled: bool,
pub ssao_radius: f32,
pub ssao_intensity: f32,
pub ssao_bias: f32,
pub ssao_sample_count: u32,
pub ssao_visualization: bool,
pub ssgi_enabled: bool,
pub ssgi_radius: f32,
pub ssgi_intensity: f32,
pub ssgi_max_steps: u32,
pub ssr_enabled: bool,
pub ssr_max_steps: u32,
pub ssr_thickness: f32,
pub ssr_max_distance: f32,
pub ssr_stride: f32,
pub ssr_fade_start: f32,
pub ssr_fade_end: f32,
pub ssr_intensity: f32,
pub fog_enabled: bool,
pub fog_color: [f32; 3],
pub fog_start: f32,
pub fog_end: f32,
pub dof_enabled: bool,
pub dof_focus_distance: f32,
pub dof_focus_range: f32,
pub dof_max_blur_radius: f32,
pub dof_bokeh_threshold: f32,
pub dof_bokeh_intensity: f32,
pub dof_quality: u32,
pub fxaa_enabled: bool,
pub render_scale: f32,
pub ibl_blend_factor: f32,
pub pbr_debug_index: u32,
pub unlit_mode: bool,
pub selection_outline_enabled: bool,
pub selection_outline_color: [f32; 4],
pub exposure: f32,
pub saturation: f32,
pub contrast: f32,
pub brightness: f32,
pub gamma: f32,
pub show_grid: bool,
pub show_sky: bool,
pub show_normals: bool,
pub navmesh_debug: bool,
pub atmosphere: Atmosphere,
}
#[derive(Clone, PartialEq, Serialize, Deserialize)]
pub struct EditorFlags {
pub gizmo_mode: GizmoMode,
pub snap_enabled: bool,
pub snap_translation_step: f32,
pub snap_rotation_step_degrees: f32,
pub snap_scale_step: f32,
pub greybox_enabled: bool,
pub greybox_show_final: bool,
pub placement_active: bool,
pub placement_shape: ShapeKind,
pub placement_size: [f32; 3],
pub placement_orient: bool,
pub placement_status: String,
pub push_pull_active: bool,
pub play_active: bool,
pub fly_mode: bool,
pub viewer_mode: bool,
pub frame_on_load: bool,
pub day_night_hour: f32,
pub day_night_auto: bool,
pub skeleton_view: bool,
pub rotation_speed: f32,
pub active_palette: usize,
pub edit_mode_target: Option<u32>,
pub generation: GenerationSettings,
}
#[derive(Clone, PartialEq, Serialize, Deserialize)]
pub struct TreeRow {
pub id: u32,
pub name: String,
pub depth: u32,
pub has_children: bool,
pub camera: bool,
pub light: bool,
pub mesh: bool,
}
#[derive(Clone, PartialEq, Serialize, Deserialize)]
pub struct PaletteEntry {
pub label: String,
pub color: [f32; 3],
}
#[derive(Clone, PartialEq, Serialize, Deserialize)]
pub struct PrefabLink {
pub name: String,
pub source_path: Option<String>,
}
#[derive(Clone, PartialEq, Serialize, Deserialize)]
pub struct MorphMeshInfo {
pub id: u32,
pub name: String,
pub weights: Vec<f32>,
}
#[derive(Clone, PartialEq, Serialize, Deserialize)]
pub struct AnimationInfo {
pub clips: Vec<String>,
pub current: Option<u32>,
pub playing: bool,
pub time: f32,
pub duration: f32,
pub speed: f32,
pub looping: bool,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct SelectedEntity {
pub id: u32,
pub revision: u32,
pub name: String,
pub translation: [f32; 3],
pub rotation: [f32; 3],
pub scale: [f32; 3],
pub mesh: Option<String>,
pub material_name: Option<String>,
pub tags: Vec<String>,
pub layer: Option<u32>,
pub chunk: Option<u32>,
pub prefab: Option<PrefabLink>,
pub animation: Option<AnimationInfo>,
pub morph_weights: Option<Vec<f32>>,
pub selected_count: u32,
pub visibility: Option<bool>,
pub casts_shadow: bool,
pub light: Option<Light>,
pub camera: Option<Camera>,
pub is_active_camera: bool,
pub rigid_body: Option<RigidBodyComponent>,
pub collider: Option<ColliderComponent>,
pub character_controller: Option<CharacterControllerComponent>,
pub navmesh_agent: Option<NavMeshAgent>,
pub particle_emitter: Option<Box<ParticleEmitter>>,
pub decal: Option<Decal>,
pub audio_source: Option<AudioSource>,
pub render_layer: Option<RenderLayer>,
pub culling_mask: Option<CullingMask>,
pub camera_culling_mask: Option<CameraCullingMask>,
pub ignore_parent_scale: bool,
pub text: Option<(String, TextProperties)>,
pub present: Vec<ComponentKind>,
pub addable: Vec<ComponentKind>,
}
#[derive(Clone, Serialize, Deserialize)]
pub struct MaterialEntry {
pub name: String,
pub material: Material,
}
#[derive(Clone, PartialEq, Serialize, Deserialize)]
pub struct KhronosEntry {
pub label: String,
pub thumbnail: Option<String>,
}
#[derive(Clone, PartialEq, Serialize, Deserialize)]
pub struct PolyhavenEntry {
pub slug: String,
pub name: String,
pub thumbnail: String,
}
#[derive(Clone, PartialEq, Serialize, Deserialize)]
pub struct SceneStructure {
pub layers: Vec<SceneLayerConfig>,
pub chunks: Vec<SceneChunkConfig>,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[cfg_attr(feature = "editor-protocol-agent", derive(enum2schema::Schema))]
pub enum EditorAction {
ToggleGroundGrid,
ToggleSky,
ToggleLitUnlit,
ToggleViewerMode,
SetViewerMode(bool),
FrameScene,
ToggleFrameOnLoad,
ClearScene,
SnapSelectionToFloor,
BakeNavmesh,
ToggleNavmeshDebug,
SetAtmosphere(Atmosphere),
SetGizmoMode(GizmoMode),
RandomizeBoth,
SelectEntity(u32),
ToggleSelectEntity(u32),
ClearSelection,
AddEntityChild(u32),
ViewCamera(u32),
ToggleSnap,
ToggleSkeletonView,
SetMaterialVariant(Option<String>),
ToggleCameraGizmos,
ToggleShowNormals,
ToggleDayNightCycle,
SetDayNightHour(f32),
LoadKhronosByIndex(usize),
LoadPolyhavenByIndex(PolyhavenCategory, usize),
SetPolyhavenResolution(u32),
RefreshBrowsers,
DeepLink(String),
SpawnLines,
SpawnMeshes,
Spawn3DText,
SpawnTextLattice,
ClothSponza,
NewProject,
SaveProject,
ExportGlb,
SaveSelectedAsPrefab,
RefreshSelectedPrefab,
BreakSelectedPrefabLink,
SpawnPrefab(String),
Undo,
Redo,
DeleteEntity(u32),
DeleteSelectedEntity,
DuplicateEntity(u32),
DuplicateSelectedEntity,
AddShape(ShapeKind),
AddInstancedShape(ShapeKind),
ConvertSimilarToInstanced,
AddEmpty,
AddCamera,
AddPlayerSpawn,
AddSavePoint,
AddPatrolPoint,
AddTriggerVolume,
StampDecalAtCursor,
AddLight(LightKind),
AddTagToSelected(String),
RemoveTagFromSelected(String),
ToggleGreyboxMode,
ApplyGreyboxToSelection,
SnapSelectionToGrid,
MarkSelectionAsBrush,
ToggleShowFinal,
TogglePlay,
TogglePushPull,
SetPlacementActive(bool),
SetPlacementShape(ShapeKind),
SetPlacementSize([f32; 3]),
SetOrientToNormal(bool),
RunGenerator(GeneratorKind),
SetGenerationSettings(GenerationSettings),
SetPaletteIndex(usize),
SetSnapEnabled(bool),
SetSnapSteps {
translation: f32,
rotation_degrees: f32,
scale: f32,
},
SetRotationSpeed(f32),
SetEntityLayer {
id: u32,
layer: Option<u32>,
},
SetEntityChunk {
id: u32,
chunk: Option<u32>,
},
AddSceneLayer,
RemoveSceneLayer(u32),
UpdateSceneLayer(SceneLayerConfig),
AddSceneChunk,
RemoveSceneChunk(u32),
UpdateSceneChunk(SceneChunkConfig),
}
#[derive(Clone, Serialize, Deserialize)]
pub struct CameraEntry {
pub id: u32,
pub name: String,
}
#[derive(Clone, Copy, Serialize, Deserialize)]
pub struct ViewportTile {
pub camera: u32,
pub x: f32,
pub y: f32,
pub width: f32,
pub height: f32,
}
#[derive(Clone, Serialize, Deserialize)]
pub enum ClientMessage {
Init {
width: f32,
height: f32,
},
Resize {
width: f32,
height: f32,
},
SetViewportTiles(Vec<ViewportTile>),
PointerMove {
x: f32,
y: f32,
},
PointerMotion {
dx: f32,
dy: f32,
},
PointerButton {
button: u8,
pressed: bool,
},
Wheel {
delta: f32,
},
Touch {
id: u64,
phase: TouchPhase,
x: f32,
y: f32,
},
Key {
code: String,
pressed: bool,
text: Option<String>,
},
Action(Box<EditorAction>),
SetTransform {
id: u32,
translation: [f32; 3],
rotation: [f32; 3],
scale: [f32; 3],
committed: bool,
},
SetEntityName {
id: u32,
name: String,
},
SetComponent {
id: u32,
payload: Box<ComponentPayload>,
committed: bool,
},
AddComponent {
id: u32,
kind: ComponentKind,
},
RemoveComponent {
id: u32,
kind: ComponentKind,
},
Animation {
id: u32,
command: AnimationCommand,
},
UpdateMaterial {
name: String,
material: Box<Material>,
committed: bool,
},
SetRenderSettings(Box<RenderSettingsState>),
DropAsset {
name: String,
},
LoadGltfBundle {
name: String,
},
UpgradeBrush {
name: String,
},
#[cfg(feature = "editor-protocol-agent")]
Agent(Box<AgentRequest>),
}
#[derive(Clone, Serialize, Deserialize)]
pub enum WorkerMessage {
Ready {
adapter: String,
},
Stats {
fps: f32,
entity_count: u32,
},
Camera {
right: [f32; 3],
up: [f32; 3],
forward: [f32; 3],
},
Scene {
rows: Vec<TreeRow>,
},
Selected {
detail: Option<Box<SelectedEntity>>,
},
Cameras {
entries: Vec<CameraEntry>,
},
Animation {
time: f32,
duration: f32,
playing: bool,
clip: Option<u32>,
},
MorphWeights {
id: u32,
weights: Vec<f32>,
},
MorphMeshes {
entries: Vec<MorphMeshInfo>,
},
MaterialVariants {
names: Vec<String>,
active: Option<String>,
},
RenderSettings(Box<RenderSettingsState>),
Flags(Box<EditorFlags>),
Materials {
entries: Vec<MaterialEntry>,
},
Tags {
entries: Vec<(String, u32)>,
},
Structure(SceneStructure),
Palette {
entries: Vec<PaletteEntry>,
},
KhronosList {
entries: Vec<KhronosEntry>,
},
PolyhavenList {
category: PolyhavenCategory,
entries: Vec<PolyhavenEntry>,
},
Loading {
active: bool,
label: String,
},
Project {
name: String,
modified: bool,
model: Option<String>,
mode: String,
},
SaveFile {
name: String,
},
PointerLock {
locked: bool,
},
FocusEntity {
id: u32,
},
UndoState {
can_undo: bool,
can_redo: bool,
},
Toast {
message: String,
error: bool,
},
#[cfg(feature = "editor-protocol-agent")]
Agent(Box<AgentResponse>),
}