fix volumes

This commit is contained in:
Isse 2023-04-18 13:19:59 +02:00
parent a35a1a34c4
commit b3a70627e5
4 changed files with 39 additions and 24 deletions

View File

@ -738,7 +738,7 @@ impl ServerChatCommand {
None, None,
), ),
ServerChatCommand::MakeVolume => { ServerChatCommand::MakeVolume => {
cmd(vec![], "Create a volume (experimental)", Some(Admin)) cmd(vec![Integer("size", 15, Optional)], "Create a volume (experimental)", Some(Admin))
}, },
ServerChatCommand::Location => { ServerChatCommand::Location => {
cmd(vec![Any("name", Required)], "Teleport to a location", None) cmd(vec![Any("name", Required)], "Teleport to a location", None)

View File

@ -1690,7 +1690,7 @@ fn handle_make_volume(
server: &mut Server, server: &mut Server,
client: EcsEntity, client: EcsEntity,
target: EcsEntity, target: EcsEntity,
_args: Vec<String>, args: Vec<String>,
_action: &ServerChatCommand, _action: &ServerChatCommand,
) -> CmdResult<()> { ) -> CmdResult<()> {
use comp::body::ship::figuredata::VoxelCollider; use comp::body::ship::figuredata::VoxelCollider;
@ -1698,7 +1698,11 @@ fn handle_make_volume(
//let () = parse_args!(args); //let () = parse_args!(args);
let pos = position(server, target, "target")?; let pos = position(server, target, "target")?;
let ship = comp::ship::Body::Volume; let ship = comp::ship::Body::Volume;
let sz = Vec3::new(15, 15, 15); let sz = parse_cmd_args!(args, u32).unwrap_or(15);
if sz < 1 || sz > 127 {
return Err(format!("Size has to be between 1 and 127."));
};
let sz = Vec3::broadcast(sz);
let collider = { let collider = {
let terrain = server.state().terrain(); let terrain = server.state().terrain();
comp::Collider::Volume(Arc::new(VoxelCollider::from_fn(sz, |rpos| { comp::Collider::Volume(Arc::new(VoxelCollider::from_fn(sz, |rpos| {
@ -1711,12 +1715,9 @@ fn handle_make_volume(
}; };
server server
.state .state
.create_ship( .create_ship(comp::Pos(pos.0 + Vec3::unit_z() * (50.0 + sz.z as f32 / 2.0)), comp::Ori::default(), ship, move |_| {
comp::Pos(pos.0 + Vec3::unit_z() * 50.0), collider
comp::Ori::default(), })
ship,
move |_| collider,
)
.build(); .build();
server.notify_client( server.notify_client(

View File

@ -38,7 +38,7 @@ use common::{
comp::{ comp::{
inventory::slot::EquipSlot, inventory::slot::EquipSlot,
item::{tool::AbilityContext, Hands, ItemKind, ToolKind}, item::{tool::AbilityContext, Hands, ItemKind, ToolKind},
ship, Body, CharacterActivity, CharacterState, Collider, Controller, Health, Inventory, ship::{self, figuredata::VOXEL_COLLIDER_MANIFEST}, Body, CharacterActivity, CharacterState, Collider, Controller, Health, Inventory,
Item, ItemKey, Last, LightAnimation, LightEmitter, Ori, PhysicsState, PoiseState, Pos, Item, ItemKey, Last, LightAnimation, LightEmitter, Ori, PhysicsState, PoiseState, Pos,
Scale, SkillSet, Stance, Vel, Scale, SkillSet, Stance, Vel,
}, },
@ -6329,33 +6329,49 @@ impl FigureMgr {
let sprite_hid_detail_distance = sprite_render_distance * 0.35; let sprite_hid_detail_distance = sprite_render_distance * 0.35;
let sprite_high_detail_distance = sprite_render_distance * 0.15; let sprite_high_detail_distance = sprite_render_distance * 0.15;
for (entity, pos, body, _, collider) in ( let voxel_colliders_manifest = VOXEL_COLLIDER_MANIFEST.read();
for (entity, pos, ori, body, _, collider) in (
&ecs.entities(), &ecs.entities(),
&ecs.read_storage::<Pos>(), &ecs.read_storage::<Pos>(),
&ecs.read_storage::<Ori>(),
&ecs.read_storage::<Body>(), &ecs.read_storage::<Body>(),
ecs.read_storage::<Health>().maybe(), ecs.read_storage::<Health>().maybe(),
ecs.read_storage::<Collider>().maybe(), ecs.read_storage::<Collider>().maybe(),
) )
.join() .join()
// Don't render dead entities // Don't render dead entities
.filter(|(_, _, _, health, _)| health.map_or(true, |h| !h.is_dead)) .filter(|(_, _, _, _, health, _)| health.map_or(true, |h| !h.is_dead))
{ {
if let Some((data, sprite_instances)) = if let Some((data, sprite_instances)) =
self.get_sprite_instances(entity, body, collider) self.get_sprite_instances(entity, body, collider)
{ {
let dist_sqrd = cam_pos.distance_squared(pos.0); let dist = collider.and_then(|collider| {
let radius = collider.map_or(f32::INFINITY, |collider| collider.bounding_radius()); let vol = collider.get_vol(&voxel_colliders_manifest)?;
let dist_sqrd = dist_sqrd - radius * radius; let mat = Mat4::from(ori.to_quat()).translated_3d(pos.0)
* Mat4::translation_3d(vol.translation);
if dist_sqrd < sprite_render_distance.powi(2) { let p = mat.inverted().mul_point(cam_pos);
let lod_level = if dist_sqrd < sprite_high_detail_distance.powi(2) { let aabb = Aabb {
min: Vec3::zero(),
max: vol.volume().sz.as_(),
};
Some(if aabb.contains_point(p) {
0.0
} else {
aabb.distance_to_point(p)
})
}).unwrap_or_else(|| pos.0.distance(cam_pos));
if dist < sprite_render_distance {
let lod_level = if dist < sprite_high_detail_distance {
0 0
} else if dist_sqrd < sprite_hid_detail_distance.powi(2) { } else if dist < sprite_hid_detail_distance {
1 1
} else if dist_sqrd < sprite_mid_detail_distance.powi(2) { } else if dist < sprite_mid_detail_distance {
2 2
} else if dist_sqrd < sprite_low_detail_distance.powi(2) { } else if dist < sprite_low_detail_distance {
3 3
} else { } else {
4 4

View File

@ -3,7 +3,7 @@ use super::{
load::{BodySpec, ShipBoneMeshes}, load::{BodySpec, ShipBoneMeshes},
EcsEntity, EcsEntity,
}; };
use common::{assets, comp::ship::figuredata::VoxelCollider}; use common::{assets, comp::ship::{figuredata::VoxelCollider, AIRSHIP_SCALE}};
use std::{convert::TryFrom, sync::Arc}; use std::{convert::TryFrom, sync::Arc};
#[derive(Copy, Clone, PartialEq, Eq, Hash)] #[derive(Copy, Clone, PartialEq, Eq, Hash)]
@ -41,9 +41,7 @@ impl anim::Skeleton for VolumeKey {
buf: &mut [anim::FigureBoneData; anim::MAX_BONE_COUNT], buf: &mut [anim::FigureBoneData; anim::MAX_BONE_COUNT],
_: Self::Body, _: Self::Body,
) -> anim::Offsets { ) -> anim::Offsets {
let scale_mat = anim::vek::Mat4::scaling_3d(1.0 / 11.0); let bone = base_mat;
let bone = base_mat * scale_mat;
*(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [ *(<&mut [_; Self::BONE_COUNT]>::try_from(&mut buf[0..Self::BONE_COUNT]).unwrap()) = [
anim::make_bone(bone), anim::make_bone(bone),