mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Account for model translation in the physics. The voxel collider still needs to be north-aligned for now.
This commit is contained in:
parent
a70e569396
commit
d98efb391b
@ -1,18 +1,23 @@
|
|||||||
({
|
({
|
||||||
DefaultAirship: (
|
DefaultAirship: (
|
||||||
bone0: (
|
bone0: (
|
||||||
//offset: (-20.0, -35.0, 1.0),
|
|
||||||
//offset: (3.0, 7.0, 1.0),
|
//offset: (3.0, 7.0, 1.0),
|
||||||
offset: (0.25, 0.25, 0.25),
|
//offset: (-20.75, -34.75, 1.25),
|
||||||
central: ("object.Human_Airship"),
|
//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: (
|
bone1: (
|
||||||
offset: (0.0, 40.0, -8.0),
|
offset: (0.0, 40.0, -8.0),
|
||||||
central: ("object.propeller-l"),
|
phys_offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("propeller-l"),
|
||||||
),
|
),
|
||||||
bone2: (
|
bone2: (
|
||||||
offset: (0.0, 0.0, -4.0),
|
offset: (0.0, 0.0, -4.0),
|
||||||
central: ("object.propeller-r"),
|
phys_offset: (0.0, 0.0, 0.0),
|
||||||
|
central: ("propeller-r"),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
})
|
})
|
||||||
|
@ -17,7 +17,7 @@ impl From<Body> for super::Body {
|
|||||||
impl Body {
|
impl Body {
|
||||||
pub fn manifest_entry(&self) -> &'static str {
|
pub fn manifest_entry(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
Body::DefaultAirship => "object.Human_Airship",
|
Body::DefaultAirship => "Human_Airship",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -38,6 +38,7 @@ pub mod figuredata {
|
|||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use vek::Vec3;
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct VoxSimple(pub String);
|
pub struct VoxSimple(pub String);
|
||||||
@ -55,6 +56,7 @@ pub mod figuredata {
|
|||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct ShipCentralSubSpec {
|
pub struct ShipCentralSubSpec {
|
||||||
pub offset: [f32; 3],
|
pub offset: [f32; 3],
|
||||||
|
pub phys_offset: [f32; 3],
|
||||||
pub central: VoxSimple,
|
pub central: VoxSimple,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +64,13 @@ pub mod figuredata {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ShipSpec {
|
pub struct ShipSpec {
|
||||||
pub central: AssetHandle<Ron<ShipCentralSpec>>,
|
pub central: AssetHandle<Ron<ShipCentralSpec>>,
|
||||||
pub voxes: HashMap<String, Dyna<Block, (), ColumnAccess>>,
|
pub colliders: HashMap<String, VoxelCollider>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct VoxelCollider {
|
||||||
|
pub dyna: Dyna<Block, (), ColumnAccess>,
|
||||||
|
pub translation: Vec3<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl assets::Compound for ShipSpec {
|
impl assets::Compound for ShipSpec {
|
||||||
@ -71,26 +79,31 @@ pub mod figuredata {
|
|||||||
_: &str,
|
_: &str,
|
||||||
) -> Result<Self, assets::Error> {
|
) -> Result<Self, assets::Error> {
|
||||||
let manifest: AssetHandle<Ron<ShipCentralSpec>> = AssetExt::load("server.manifests.ship_manifest")?;
|
let manifest: AssetHandle<Ron<ShipCentralSpec>> = 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 (_, spec) in (manifest.read().0).0.iter() {
|
||||||
for bone in [&spec.bone0, &spec.bone1, &spec.bone2].iter() {
|
for bone in [&spec.bone0, &spec.bone1, &spec.bone2].iter() {
|
||||||
// TODO: avoid the requirement for symlinks in "voxygen.voxel.object.", and load
|
// TODO: avoid the requirement for symlinks in "voxygen.voxel.object.", and load
|
||||||
// the models from "server.voxel." instead
|
// the models from "server.voxel." instead
|
||||||
let vox =
|
let vox =
|
||||||
cache.load::<DotVoxAsset>(&["voxygen.voxel.", &bone.central.0].concat())?;
|
cache.load::<DotVoxAsset>(&["server.voxel.", &bone.central.0].concat())?;
|
||||||
let dyna = Dyna::<Cell, (), ColumnAccess>::from_vox(&vox.read().0, false);
|
let dyna = Dyna::<Cell, (), ColumnAccess>::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() {
|
if let Some(rgb) = cell.get_color() {
|
||||||
Block::new(BlockKind::Misc, rgb)
|
Block::new(BlockKind::Misc, rgb)
|
||||||
} else {
|
} else {
|
||||||
Block::air(SpriteKind::Empty)
|
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 {
|
Ok(ShipSpec {
|
||||||
central: manifest,
|
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
|
// 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
|
// (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)
|
// 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<ShipSpec> = AssetExt::load_expect("server.manifests.ship_manifest");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ use vek::{Quaternion, Vec2, Vec3};
|
|||||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
#[serde(into = "SerdeOri")]
|
#[serde(into = "SerdeOri")]
|
||||||
#[serde(from = "SerdeOri")]
|
#[serde(from = "SerdeOri")]
|
||||||
pub struct Ori(Quaternion<f32>);
|
pub struct Ori(pub Quaternion<f32>);
|
||||||
|
|
||||||
impl Default for Ori {
|
impl Default for Ori {
|
||||||
/// Returns the default orientation (no rotation; default Dir)
|
/// Returns the default orientation (no rotation; default Dir)
|
||||||
|
@ -364,7 +364,7 @@ impl<'a> PhysicsSystemData<'a> {
|
|||||||
} = self;
|
} = self;
|
||||||
// Apply movement inputs
|
// Apply movement inputs
|
||||||
span!(guard, "Apply movement and terrain collision");
|
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) = (
|
let (pos_writes, land_on_grounds) = (
|
||||||
&psdr.entities,
|
&psdr.entities,
|
||||||
psdr.scales.maybe(),
|
psdr.scales.maybe(),
|
||||||
@ -372,7 +372,7 @@ impl<'a> PhysicsSystemData<'a> {
|
|||||||
&psdr.colliders,
|
&psdr.colliders,
|
||||||
positions,
|
positions,
|
||||||
&mut psdw.velocities,
|
&mut psdw.velocities,
|
||||||
&psdw.orientations,
|
orientations,
|
||||||
&mut psdw.physics_states,
|
&mut psdw.physics_states,
|
||||||
previous_phys_cache,
|
previous_phys_cache,
|
||||||
!&psdr.mountings,
|
!&psdr.mountings,
|
||||||
@ -548,6 +548,7 @@ impl<'a> PhysicsSystemData<'a> {
|
|||||||
previous_cache_other,
|
previous_cache_other,
|
||||||
mass_other,
|
mass_other,
|
||||||
collider_other,
|
collider_other,
|
||||||
|
ori_other,
|
||||||
_,
|
_,
|
||||||
_,
|
_,
|
||||||
_,
|
_,
|
||||||
@ -560,6 +561,7 @@ impl<'a> PhysicsSystemData<'a> {
|
|||||||
previous_phys_cache,
|
previous_phys_cache,
|
||||||
psdr.masses.maybe(),
|
psdr.masses.maybe(),
|
||||||
&psdr.colliders,
|
&psdr.colliders,
|
||||||
|
orientations,
|
||||||
!&psdr.projectiles,
|
!&psdr.projectiles,
|
||||||
!&psdr.mountings,
|
!&psdr.mountings,
|
||||||
!&psdr.beams,
|
!&psdr.beams,
|
||||||
@ -574,10 +576,12 @@ impl<'a> PhysicsSystemData<'a> {
|
|||||||
.center
|
.center
|
||||||
.distance_squared(previous_cache_other.center)
|
.distance_squared(previous_cache_other.center)
|
||||||
> collision_boundary.powi(2)
|
> collision_boundary.powi(2)
|
||||||
|| entity == entity_other
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}*/
|
}*/
|
||||||
|
if entity == entity_other {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if let Collider::Voxel { id } = collider_other {
|
if let Collider::Voxel { id } = collider_other {
|
||||||
// use bounding cylinder regardless of our collider
|
// use bounding cylinder regardless of our collider
|
||||||
@ -589,13 +593,31 @@ impl<'a> PhysicsSystemData<'a> {
|
|||||||
let z_min = z_min * scale;
|
let z_min = z_min * scale;
|
||||||
let z_max = z_max.clamped(1.2, 1.95) * scale;
|
let z_max = z_max.clamped(1.2, 1.95) * scale;
|
||||||
|
|
||||||
|
if let Some(voxel_collider) = VOXEL_COLLIDER_MANIFEST.read().colliders.get(id) {
|
||||||
let mut physics_state_delta = physics_state.clone();
|
let mut physics_state_delta = physics_state.clone();
|
||||||
pos.0 -= pos_other.0;
|
//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);
|
let cylinder = (radius, z_min, z_max);
|
||||||
if let Some(dyna) = VOXEL_COLLIDER_MANIFEST.voxes.get(id) {
|
|
||||||
cylinder_voxel_collision(
|
cylinder_voxel_collision(
|
||||||
cylinder,
|
cylinder,
|
||||||
&*dyna,
|
&voxel_collider.dyna,
|
||||||
entity,
|
entity,
|
||||||
&mut pos,
|
&mut pos,
|
||||||
pos_delta,
|
pos_delta,
|
||||||
@ -603,8 +625,10 @@ impl<'a> PhysicsSystemData<'a> {
|
|||||||
&mut physics_state_delta,
|
&mut physics_state_delta,
|
||||||
&mut land_on_grounds,
|
&mut land_on_grounds,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
pos.0 += pos_other.0;
|
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
|
// union in the state updates, so that the state isn't just based on
|
||||||
// the most recent terrain that collision was attempted with
|
// the most recent terrain that collision was attempted with
|
||||||
physics_state.on_ground |= physics_state_delta.on_ground;
|
physics_state.on_ground |= physics_state_delta.on_ground;
|
||||||
@ -623,6 +647,7 @@ impl<'a> PhysicsSystemData<'a> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if pos != old_pos {
|
if pos != old_pos {
|
||||||
pos_writes.push((entity, pos));
|
pos_writes.push((entity, pos));
|
||||||
}
|
}
|
||||||
|
@ -1972,7 +1972,7 @@ fn create_pipelines(
|
|||||||
&shaders.figure_vert.read().0,
|
&shaders.figure_vert.read().0,
|
||||||
&shaders.figure_frag.read().0,
|
&shaders.figure_frag.read().0,
|
||||||
&include_ctx,
|
&include_ctx,
|
||||||
gfx::state::CullFace::Nothing,
|
gfx::state::CullFace::Back,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Construct a pipeline for rendering terrain
|
// Construct a pipeline for rendering terrain
|
||||||
|
@ -35,6 +35,9 @@ fn load_segment(mesh_name: &str) -> Segment {
|
|||||||
}
|
}
|
||||||
fn graceful_load_vox(mesh_name: &str) -> AssetHandle<DotVoxAsset> {
|
fn graceful_load_vox(mesh_name: &str) -> AssetHandle<DotVoxAsset> {
|
||||||
let full_specifier: String = ["voxygen.voxel.", mesh_name].concat();
|
let full_specifier: String = ["voxygen.voxel.", mesh_name].concat();
|
||||||
|
graceful_load_vox_fullspec(&full_specifier)
|
||||||
|
}
|
||||||
|
fn graceful_load_vox_fullspec(full_specifier: &str) -> AssetHandle<DotVoxAsset> {
|
||||||
match DotVoxAsset::load(&full_specifier) {
|
match DotVoxAsset::load(&full_specifier) {
|
||||||
Ok(dot_vox) => dot_vox,
|
Ok(dot_vox) => dot_vox,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
@ -46,6 +49,9 @@ fn graceful_load_vox(mesh_name: &str) -> AssetHandle<DotVoxAsset> {
|
|||||||
fn graceful_load_segment(mesh_name: &str) -> Segment {
|
fn graceful_load_segment(mesh_name: &str) -> Segment {
|
||||||
Segment::from(&graceful_load_vox(mesh_name).read().0)
|
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 {
|
fn graceful_load_segment_flipped(mesh_name: &str, flipped: bool) -> Segment {
|
||||||
Segment::from_vox(&graceful_load_vox(mesh_name).read().0, flipped)
|
Segment::from_vox(&graceful_load_vox(mesh_name).read().0, flipped)
|
||||||
}
|
}
|
||||||
@ -4241,7 +4247,7 @@ fn mesh_ship_bone<K: fmt::Debug+Eq+Hash, V, F: Fn(&V) -> &ShipCentralSubSpec>(ma
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
let bone = f(spec);
|
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))
|
(central, Vec3::from(bone.offset))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user