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

View File

@ -1690,7 +1690,7 @@ fn handle_make_volume(
server: &mut Server,
client: EcsEntity,
target: EcsEntity,
_args: Vec<String>,
args: Vec<String>,
_action: &ServerChatCommand,
) -> CmdResult<()> {
use comp::body::ship::figuredata::VoxelCollider;
@ -1698,7 +1698,11 @@ fn handle_make_volume(
//let () = parse_args!(args);
let pos = position(server, target, "target")?;
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 terrain = server.state().terrain();
comp::Collider::Volume(Arc::new(VoxelCollider::from_fn(sz, |rpos| {
@ -1711,12 +1715,9 @@ fn handle_make_volume(
};
server
.state
.create_ship(
comp::Pos(pos.0 + Vec3::unit_z() * 50.0),
comp::Ori::default(),
ship,
move |_| collider,
)
.create_ship(comp::Pos(pos.0 + Vec3::unit_z() * (50.0 + sz.z as f32 / 2.0)), comp::Ori::default(), ship, move |_| {
collider
})
.build();
server.notify_client(

View File

@ -38,7 +38,7 @@ use common::{
comp::{
inventory::slot::EquipSlot,
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,
Scale, SkillSet, Stance, Vel,
},
@ -6329,33 +6329,49 @@ impl FigureMgr {
let sprite_hid_detail_distance = sprite_render_distance * 0.35;
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.read_storage::<Pos>(),
&ecs.read_storage::<Ori>(),
&ecs.read_storage::<Body>(),
ecs.read_storage::<Health>().maybe(),
ecs.read_storage::<Collider>().maybe(),
)
.join()
// 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)) =
self.get_sprite_instances(entity, body, collider)
{
let dist_sqrd = cam_pos.distance_squared(pos.0);
let radius = collider.map_or(f32::INFINITY, |collider| collider.bounding_radius());
let dist = collider.and_then(|collider| {
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 lod_level = if dist_sqrd < sprite_high_detail_distance.powi(2) {
let p = mat.inverted().mul_point(cam_pos);
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
} else if dist_sqrd < sprite_hid_detail_distance.powi(2) {
} else if dist < sprite_hid_detail_distance {
1
} else if dist_sqrd < sprite_mid_detail_distance.powi(2) {
} else if dist < sprite_mid_detail_distance {
2
} else if dist_sqrd < sprite_low_detail_distance.powi(2) {
} else if dist < sprite_low_detail_distance {
3
} else {
4

View File

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