diff --git a/assets/server/manifests/ship_manifest.ron b/assets/server/manifests/ship_manifest.ron
index e8e96539ca..6b361aa535 100644
--- a/assets/server/manifests/ship_manifest.ron
+++ b/assets/server/manifests/ship_manifest.ron
@@ -1,18 +1,23 @@
({
DefaultAirship: (
bone0: (
- //offset: (-20.0, -35.0, 1.0),
//offset: (3.0, 7.0, 1.0),
- offset: (0.25, 0.25, 0.25),
- central: ("object.Human_Airship"),
+ //offset: (-20.75, -34.75, 1.25),
+ //offset: (0.0, 0.0, 0.0),
+ offset: (-20.0, -35.0, 1.0),
+ //phys_offset: (0.25, 0.25, 0.25),
+ phys_offset: (0.0, 0.0, 0.0),
+ central: ("Human_Airship"),
),
bone1: (
offset: (0.0, 40.0, -8.0),
- central: ("object.propeller-l"),
+ phys_offset: (0.0, 0.0, 0.0),
+ central: ("propeller-l"),
),
bone2: (
offset: (0.0, 0.0, -4.0),
- central: ("object.propeller-r"),
+ phys_offset: (0.0, 0.0, 0.0),
+ central: ("propeller-r"),
),
),
})
diff --git a/common/src/comp/body/ship.rs b/common/src/comp/body/ship.rs
index f607cf2ae6..3cab7a0ecb 100644
--- a/common/src/comp/body/ship.rs
+++ b/common/src/comp/body/ship.rs
@@ -17,7 +17,7 @@ impl From
for super::Body {
impl Body {
pub fn manifest_entry(&self) -> &'static str {
match self {
- Body::DefaultAirship => "object.Human_Airship",
+ Body::DefaultAirship => "Human_Airship",
}
}
}
@@ -38,6 +38,7 @@ pub mod figuredata {
use hashbrown::HashMap;
use lazy_static::lazy_static;
use serde::Deserialize;
+ use vek::Vec3;
#[derive(Deserialize)]
pub struct VoxSimple(pub String);
@@ -55,6 +56,7 @@ pub mod figuredata {
#[derive(Deserialize)]
pub struct ShipCentralSubSpec {
pub offset: [f32; 3],
+ pub phys_offset: [f32; 3],
pub central: VoxSimple,
}
@@ -62,7 +64,13 @@ pub mod figuredata {
#[derive(Clone)]
pub struct ShipSpec {
pub central: AssetHandle>,
- pub voxes: HashMap>,
+ pub colliders: HashMap,
+ }
+
+ #[derive(Clone)]
+ pub struct VoxelCollider {
+ pub dyna: Dyna,
+ pub translation: Vec3,
}
impl assets::Compound for ShipSpec {
@@ -71,26 +79,31 @@ pub mod figuredata {
_: &str,
) -> Result {
let manifest: AssetHandle> = AssetExt::load("server.manifests.ship_manifest")?;
- let mut voxes = HashMap::new();
+ let mut colliders = HashMap::new();
for (_, spec) in (manifest.read().0).0.iter() {
for bone in [&spec.bone0, &spec.bone1, &spec.bone2].iter() {
// TODO: avoid the requirement for symlinks in "voxygen.voxel.object.", and load
// the models from "server.voxel." instead
let vox =
- cache.load::(&["voxygen.voxel.", &bone.central.0].concat())?;
+ cache.load::(&["server.voxel.", &bone.central.0].concat())?;
let dyna = Dyna::::from_vox(&vox.read().0, false);
- voxes.insert(bone.central.0.clone(), dyna.map_into(|cell| {
+ let dyna = dyna.map_into(|cell| {
if let Some(rgb) = cell.get_color() {
Block::new(BlockKind::Misc, rgb)
} else {
Block::air(SpriteKind::Empty)
}
- }));
+ });
+ let collider = VoxelCollider {
+ dyna,
+ translation: Vec3::from(bone.offset) + Vec3::from(bone.phys_offset),
+ };
+ colliders.insert(bone.central.0.clone(), collider);
}
}
Ok(ShipSpec {
central: manifest,
- voxes,
+ colliders,
})
}
}
@@ -99,6 +112,6 @@ pub mod figuredata {
// TODO: load this from the ECS as a resource, and maybe make it more general than ships
// (although figuring out how to keep the figure bones in sync with the terrain offsets seems
// like a hard problem if they're not the same manifest)
- pub static ref VOXEL_COLLIDER_MANIFEST: ShipSpec = AssetExt::load_expect_cloned("server.manifests.ship_manifest");
+ pub static ref VOXEL_COLLIDER_MANIFEST: AssetHandle = AssetExt::load_expect("server.manifests.ship_manifest");
}
}
diff --git a/common/src/comp/ori.rs b/common/src/comp/ori.rs
index 351db07066..de9e969bcc 100644
--- a/common/src/comp/ori.rs
+++ b/common/src/comp/ori.rs
@@ -9,7 +9,7 @@ use vek::{Quaternion, Vec2, Vec3};
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(into = "SerdeOri")]
#[serde(from = "SerdeOri")]
-pub struct Ori(Quaternion);
+pub struct Ori(pub Quaternion);
impl Default for Ori {
/// Returns the default orientation (no rotation; default Dir)
diff --git a/common/sys/src/phys.rs b/common/sys/src/phys.rs
index ebe19689ad..91cfd540df 100644
--- a/common/sys/src/phys.rs
+++ b/common/sys/src/phys.rs
@@ -364,7 +364,7 @@ impl<'a> PhysicsSystemData<'a> {
} = self;
// Apply movement inputs
span!(guard, "Apply movement and terrain collision");
- let (positions, previous_phys_cache) = (&psdw.positions, &psdw.previous_phys_cache);
+ let (positions, previous_phys_cache, orientations) = (&psdw.positions, &psdw.previous_phys_cache, &psdw.orientations);
let (pos_writes, land_on_grounds) = (
&psdr.entities,
psdr.scales.maybe(),
@@ -372,7 +372,7 @@ impl<'a> PhysicsSystemData<'a> {
&psdr.colliders,
positions,
&mut psdw.velocities,
- &psdw.orientations,
+ orientations,
&mut psdw.physics_states,
previous_phys_cache,
!&psdr.mountings,
@@ -548,6 +548,7 @@ impl<'a> PhysicsSystemData<'a> {
previous_cache_other,
mass_other,
collider_other,
+ ori_other,
_,
_,
_,
@@ -560,6 +561,7 @@ impl<'a> PhysicsSystemData<'a> {
previous_phys_cache,
psdr.masses.maybe(),
&psdr.colliders,
+ orientations,
!&psdr.projectiles,
!&psdr.mountings,
!&psdr.beams,
@@ -574,10 +576,12 @@ impl<'a> PhysicsSystemData<'a> {
.center
.distance_squared(previous_cache_other.center)
> collision_boundary.powi(2)
- || entity == entity_other
{
continue;
}*/
+ if entity == entity_other {
+ continue;
+ }
if let Collider::Voxel { id } = collider_other {
// use bounding cylinder regardless of our collider
@@ -589,13 +593,31 @@ impl<'a> PhysicsSystemData<'a> {
let z_min = z_min * scale;
let z_max = z_max.clamped(1.2, 1.95) * scale;
- let mut physics_state_delta = physics_state.clone();
- pos.0 -= pos_other.0;
- let cylinder = (radius, z_min, z_max);
- if let Some(dyna) = VOXEL_COLLIDER_MANIFEST.voxes.get(id) {
+ if let Some(voxel_collider) = VOXEL_COLLIDER_MANIFEST.read().colliders.get(id) {
+ let mut physics_state_delta = physics_state.clone();
+ //let ori_2d = ori_other.look_dir().xy();
+ //let ori_2d_quat = Quaternion::rotation_z(ori_2d.y.atan2(ori_2d.x));
+ //let ori_2d_quat = Quaternion::from_xyzw(ori_2d.x, ori_2d.y, 0.0, 1.0).normalized();
+ // deliberately don't use scale yet here, because the 11.0/0.8
+ // thing is in the comp::Scale for visual reasons
+ let t1 = Mat4::from(Transform {
+ position: pos_other.0 + voxel_collider.translation,
+ orientation: Quaternion::identity(),
+ scale: Vec3::broadcast(1.0),
+ });
+ let t2 = Mat4::from(Transform {
+ position: Vec3::zero(),
+ orientation: ori_other.0.normalized(),
+ scale: Vec3::broadcast(1.0),
+ });
+ //let transform = t2 * t1;
+ let transform = t1;
+ pos.0 = transform.inverted().mul_point(pos.0);
+ //vel.0 = t2.inverted().mul_point(pos.0);
+ let cylinder = (radius, z_min, z_max);
cylinder_voxel_collision(
cylinder,
- &*dyna,
+ &voxel_collider.dyna,
entity,
&mut pos,
pos_delta,
@@ -603,24 +625,27 @@ impl<'a> PhysicsSystemData<'a> {
&mut physics_state_delta,
&mut land_on_grounds,
);
+
+ pos.0 = transform.mul_point(pos.0);
+ //vel.0 = t2.mul_point(vel.0);
+
+ // union in the state updates, so that the state isn't just based on
+ // the most recent terrain that collision was attempted with
+ physics_state.on_ground |= physics_state_delta.on_ground;
+ physics_state.on_ceiling |= physics_state_delta.on_ceiling;
+ physics_state.on_wall =
+ physics_state.on_wall.or(physics_state_delta.on_wall);
+ physics_state
+ .touch_entities
+ .append(&mut physics_state_delta.touch_entities);
+ physics_state.in_liquid =
+ match (physics_state.in_liquid, physics_state_delta.in_liquid) {
+ // this match computes `x <|> y <|> liftA2 max x y`
+ (Some(x), Some(y)) => Some(x.max(y)),
+ (_, y @ Some(_)) => y,
+ _ => None,
+ };
}
- pos.0 += pos_other.0;
- // union in the state updates, so that the state isn't just based on
- // the most recent terrain that collision was attempted with
- physics_state.on_ground |= physics_state_delta.on_ground;
- physics_state.on_ceiling |= physics_state_delta.on_ceiling;
- physics_state.on_wall =
- physics_state.on_wall.or(physics_state_delta.on_wall);
- physics_state
- .touch_entities
- .append(&mut physics_state_delta.touch_entities);
- physics_state.in_liquid =
- match (physics_state.in_liquid, physics_state_delta.in_liquid) {
- // this match computes `x <|> y <|> liftA2 max x y`
- (Some(x), Some(y)) => Some(x.max(y)),
- (_, y @ Some(_)) => y,
- _ => None,
- };
}
}
if pos != old_pos {
diff --git a/voxygen/src/render/renderer.rs b/voxygen/src/render/renderer.rs
index eec891e144..6856dbbb4b 100644
--- a/voxygen/src/render/renderer.rs
+++ b/voxygen/src/render/renderer.rs
@@ -1972,7 +1972,7 @@ fn create_pipelines(
&shaders.figure_vert.read().0,
&shaders.figure_frag.read().0,
&include_ctx,
- gfx::state::CullFace::Nothing,
+ gfx::state::CullFace::Back,
)?;
// Construct a pipeline for rendering terrain
diff --git a/voxygen/src/scene/figure/load.rs b/voxygen/src/scene/figure/load.rs
index a584812462..ff334213e2 100644
--- a/voxygen/src/scene/figure/load.rs
+++ b/voxygen/src/scene/figure/load.rs
@@ -35,6 +35,9 @@ fn load_segment(mesh_name: &str) -> Segment {
}
fn graceful_load_vox(mesh_name: &str) -> AssetHandle {
let full_specifier: String = ["voxygen.voxel.", mesh_name].concat();
+ graceful_load_vox_fullspec(&full_specifier)
+}
+fn graceful_load_vox_fullspec(full_specifier: &str) -> AssetHandle {
match DotVoxAsset::load(&full_specifier) {
Ok(dot_vox) => dot_vox,
Err(_) => {
@@ -46,6 +49,9 @@ fn graceful_load_vox(mesh_name: &str) -> AssetHandle {
fn graceful_load_segment(mesh_name: &str) -> Segment {
Segment::from(&graceful_load_vox(mesh_name).read().0)
}
+fn graceful_load_segment_fullspec(full_specifier: &str) -> Segment {
+ Segment::from(&graceful_load_vox_fullspec(full_specifier).read().0)
+}
fn graceful_load_segment_flipped(mesh_name: &str, flipped: bool) -> Segment {
Segment::from_vox(&graceful_load_vox(mesh_name).read().0, flipped)
}
@@ -4241,7 +4247,7 @@ fn mesh_ship_bone &ShipCentralSubSpec>(ma
},
};
let bone = f(spec);
- let central = graceful_load_segment(&bone.central.0);
+ let central = graceful_load_segment_fullspec(&["server.voxel.", &bone.central.0].concat());
(central, Vec3::from(bone.offset))
}
|