Compare commits
6 Commits
mesh-v2
...
debug-bug3
| Author | SHA1 | Date | |
|---|---|---|---|
|
c797c32151
|
|||
|
95df720255
|
|||
|
e34cb0db53
|
|||
|
64c98493eb
|
|||
|
6b10a01a8c
|
|||
|
0f39cdb89f
|
@@ -61,6 +61,7 @@ impl<T> Body<T>
|
|||||||
self.velocity+(self.acceleration*dt).map(|elem|elem.divide().clamp_1())
|
self.velocity+(self.acceleration*dt).map(|elem|elem.divide().clamp_1())
|
||||||
}
|
}
|
||||||
pub fn advance_time(&mut self,time:Time<T>){
|
pub fn advance_time(&mut self,time:Time<T>){
|
||||||
|
println!("advance_time");
|
||||||
self.position=self.extrapolated_position(time);
|
self.position=self.extrapolated_position(time);
|
||||||
self.velocity=self.extrapolated_velocity(time);
|
self.velocity=self.extrapolated_velocity(time);
|
||||||
self.time=time;
|
self.time=time;
|
||||||
@@ -102,6 +103,7 @@ impl<T> Body<T>
|
|||||||
self.acceleration.map(|elem|(dt*elem).divide().clamp())+self.velocity
|
self.acceleration.map(|elem|(dt*elem).divide().clamp())+self.velocity
|
||||||
}
|
}
|
||||||
pub fn advance_time_ratio_dt(&mut self,dt:crate::model::GigaTime){
|
pub fn advance_time_ratio_dt(&mut self,dt:crate::model::GigaTime){
|
||||||
|
println!("advance_time_ratio_dt");
|
||||||
self.position=self.extrapolated_position_ratio_dt(dt);
|
self.position=self.extrapolated_position_ratio_dt(dt);
|
||||||
self.velocity=self.extrapolated_velocity_ratio_dt(dt);
|
self.velocity=self.extrapolated_velocity_ratio_dt(dt);
|
||||||
self.time+=dt.into();
|
self.time+=dt.into();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ use crate::physics::{Time,Body};
|
|||||||
|
|
||||||
use core::ops::Bound;
|
use core::ops::Bound;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
enum Transition<M:MeshQuery>{
|
enum Transition<M:MeshQuery>{
|
||||||
Miss,
|
Miss,
|
||||||
Next(FEV<M>,GigaTime),
|
Next(FEV<M>,GigaTime),
|
||||||
@@ -76,6 +77,8 @@ impl<F:Copy,M:MeshQuery<Normal=Vector3<F>,Offset=Fixed<4,128>>> FEV<M>
|
|||||||
M::Face:Copy,
|
M::Face:Copy,
|
||||||
M::Edge:Copy,
|
M::Edge:Copy,
|
||||||
M::Vert:Copy,
|
M::Vert:Copy,
|
||||||
|
M:std::fmt::Debug,
|
||||||
|
F:std::fmt::Display,
|
||||||
F:core::ops::Mul<Fixed<1,32>,Output=Fixed<4,128>>,
|
F:core::ops::Mul<Fixed<1,32>,Output=Fixed<4,128>>,
|
||||||
<F as core::ops::Mul<Fixed<1,32>>>::Output:core::iter::Sum,
|
<F as core::ops::Mul<Fixed<1,32>>>::Output:core::iter::Sum,
|
||||||
M::Offset:core::ops::Sub<<F as std::ops::Mul<Fixed<1,32>>>::Output>,
|
M::Offset:core::ops::Sub<<F as std::ops::Mul<Fixed<1,32>>>::Output>,
|
||||||
@@ -90,10 +93,15 @@ impl<F:Copy,M:MeshQuery<Normal=Vector3<F>,Offset=Fixed<4,128>>> FEV<M>
|
|||||||
//n=face.normal d=face.dot
|
//n=face.normal d=face.dot
|
||||||
//n.a t^2+n.v t+n.p-d==0
|
//n.a t^2+n.v t+n.p-d==0
|
||||||
let (n,d)=mesh.face_nd(face_id);
|
let (n,d)=mesh.face_nd(face_id);
|
||||||
|
println!("Face n={} d={}",n,d);
|
||||||
//TODO: use higher precision d value?
|
//TODO: use higher precision d value?
|
||||||
//use the mesh transform translation instead of baking it into the d value.
|
//use the mesh transform translation instead of baking it into the d value.
|
||||||
for dt in Fixed::<4,128>::zeroes2((n.dot(body.position)-d)*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){
|
for dt in Fixed::<4,128>::zeroes2((n.dot(body.position)-d)*2,n.dot(body.velocity)*2,n.dot(body.acceleration)){
|
||||||
if low(&lower_bound,&dt)&&upp(&dt,&upper_bound)&&n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative(){
|
let low=low(&lower_bound,&dt);
|
||||||
|
let upp=upp(&dt,&upper_bound);
|
||||||
|
let into=n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative();
|
||||||
|
println!("dt={} low={low} upp={upp} into={into}",dt.divide());
|
||||||
|
if low&&upp&&into{
|
||||||
upper_bound=Bound::Included(dt);
|
upper_bound=Bound::Included(dt);
|
||||||
best_transition=Transition::Hit(face_id,dt);
|
best_transition=Transition::Hit(face_id,dt);
|
||||||
break;
|
break;
|
||||||
@@ -128,10 +136,16 @@ impl<F:Copy,M:MeshQuery<Normal=Vector3<F>,Offset=Fixed<4,128>>> FEV<M>
|
|||||||
let face_n=mesh.face_nd(edge_face_id).0;
|
let face_n=mesh.face_nd(edge_face_id).0;
|
||||||
//edge_n gets parity from the order of edge_faces
|
//edge_n gets parity from the order of edge_faces
|
||||||
let n=face_n.cross(edge_n)*((i as i64)*2-1);
|
let n=face_n.cross(edge_n)*((i as i64)*2-1);
|
||||||
|
let d=n.dot(delta_pos).wrap_4();
|
||||||
|
println!("Edge Face={:?} boundary_n={} boundary_d={}",edge_face_id,n,d>>1);
|
||||||
//WARNING yada yada d *2
|
//WARNING yada yada d *2
|
||||||
//wrap for speed
|
//wrap for speed
|
||||||
for dt in Fixed::<4,128>::zeroes2(n.dot(delta_pos).wrap_4(),n.dot(body.velocity).wrap_4()*2,n.dot(body.acceleration).wrap_4()){
|
for dt in Fixed::<4,128>::zeroes2(d,n.dot(body.velocity).wrap_4()*2,n.dot(body.acceleration).wrap_4()){
|
||||||
if low(&lower_bound,&dt)&&upp(&dt,&upper_bound)&&n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative(){
|
let low=low(&lower_bound,&dt);
|
||||||
|
let upp=upp(&dt,&upper_bound);
|
||||||
|
let into=n.dot(body.extrapolated_velocity_ratio_dt(dt)).is_negative();
|
||||||
|
println!("dt={} low={low} upp={upp} into={into}",dt.divide());
|
||||||
|
if low&&upp&&into{
|
||||||
upper_bound=Bound::Included(dt);
|
upper_bound=Bound::Included(dt);
|
||||||
best_transition=Transition::Next(FEV::Face(edge_face_id),dt);
|
best_transition=Transition::Next(FEV::Face(edge_face_id),dt);
|
||||||
break;
|
break;
|
||||||
@@ -175,8 +189,11 @@ impl<F:Copy,M:MeshQuery<Normal=Vector3<F>,Offset=Fixed<4,128>>> FEV<M>
|
|||||||
pub fn crawl(mut self,mesh:&M,relative_body:&Body,lower_bound:Bound<&Time>,upper_bound:Bound<&Time>)->CrawlResult<M>{
|
pub fn crawl(mut self,mesh:&M,relative_body:&Body,lower_bound:Bound<&Time>,upper_bound:Bound<&Time>)->CrawlResult<M>{
|
||||||
let mut lower_bound=lower_bound.map(|&t|into_giga_time(t,relative_body.time));
|
let mut lower_bound=lower_bound.map(|&t|into_giga_time(t,relative_body.time));
|
||||||
let upper_bound=upper_bound.map(|&t|into_giga_time(t,relative_body.time));
|
let upper_bound=upper_bound.map(|&t|into_giga_time(t,relative_body.time));
|
||||||
|
println!("crawl begin={self:?}");
|
||||||
for _ in 0..20{
|
for _ in 0..20{
|
||||||
match self.next_transition(mesh,relative_body,lower_bound,upper_bound){
|
let transition=self.next_transition(mesh,relative_body,lower_bound,upper_bound);
|
||||||
|
println!("transition={transition:?}");
|
||||||
|
match transition{
|
||||||
Transition::Miss=>return CrawlResult::Miss(self),
|
Transition::Miss=>return CrawlResult::Miss(self),
|
||||||
Transition::Next(next_fev,next_time)=>(self,lower_bound)=(next_fev,Bound::Included(next_time)),
|
Transition::Next(next_fev,next_time)=>(self,lower_bound)=(next_fev,Bound::Included(next_time)),
|
||||||
Transition::Hit(face,time)=>return CrawlResult::Hit(face,time),
|
Transition::Hit(face,time)=>return CrawlResult::Hit(face,time),
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
use std::collections::{HashSet,HashMap};
|
use std::collections::{HashSet,HashMap};
|
||||||
use core::ops::{Bound,RangeBounds};
|
use core::ops::{Bound,RangeBounds};
|
||||||
use strafesnet_common::integer::vec3::Vector3;
|
use strafesnet_common::integer::vec3::Vector3;
|
||||||
use strafesnet_common::model::{self,MeshId};
|
use strafesnet_common::model::{self,MeshId,PolygonIter};
|
||||||
use strafesnet_common::integer::{self,vec3,Fixed,Planar32Vec3,Planar64,Planar64Vec3,Ratio};
|
use strafesnet_common::integer::{self,vec3,Fixed,Planar64,Planar64Vec3,Ratio};
|
||||||
use strafesnet_common::physics::Time;
|
use strafesnet_common::physics::Time;
|
||||||
|
|
||||||
type Body=crate::body::Body<strafesnet_common::physics::TimeInner>;
|
type Body=crate::body::Body<strafesnet_common::physics::TimeInner>;
|
||||||
@@ -74,11 +74,11 @@ struct Face{
|
|||||||
dot:Planar64,
|
dot:Planar64,
|
||||||
}
|
}
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Vert(Planar32Vec3);
|
struct Vert(Planar64Vec3);
|
||||||
pub trait MeshQuery{
|
pub trait MeshQuery{
|
||||||
type Face:Copy;
|
type Face:Copy+std::fmt::Debug;
|
||||||
type Edge:Copy+DirectedEdge;
|
type Edge:Copy+DirectedEdge+std::fmt::Debug;
|
||||||
type Vert:Copy;
|
type Vert:Copy+std::fmt::Debug;
|
||||||
// Vertex must be Planar64Vec3 because it represents an actual position
|
// Vertex must be Planar64Vec3 because it represents an actual position
|
||||||
type Normal;
|
type Normal;
|
||||||
type Offset;
|
type Offset;
|
||||||
@@ -756,7 +756,9 @@ impl MinkowskiMesh<'_>{
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn predict_collision_in(&self,relative_body:&Body,range:impl RangeBounds<Time>)->Option<(MinkowskiFace,GigaTime)>{
|
pub fn predict_collision_in(&self,relative_body:&Body,range:impl RangeBounds<Time>)->Option<(MinkowskiFace,GigaTime)>{
|
||||||
|
println!("@@@BEGIN SETUP@@@");
|
||||||
self.closest_fev_not_inside(*relative_body,range.start_bound()).and_then(|fev|{
|
self.closest_fev_not_inside(*relative_body,range.start_bound()).and_then(|fev|{
|
||||||
|
println!("@@@BEGIN REAL CRAWL@@@");
|
||||||
//continue forwards along the body parabola
|
//continue forwards along the body parabola
|
||||||
fev.crawl(self,relative_body,range.start_bound(),range.end_bound()).hit()
|
fev.crawl(self,relative_body,range.start_bound(),range.end_bound()).hit()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ pub enum InternalInstruction{
|
|||||||
CollisionStart(Collision,model_physics::GigaTime),
|
CollisionStart(Collision,model_physics::GigaTime),
|
||||||
CollisionEnd(Collision,model_physics::GigaTime),
|
CollisionEnd(Collision,model_physics::GigaTime),
|
||||||
StrafeTick,
|
StrafeTick,
|
||||||
|
// TODO: add GigaTime to ReachWalkTargetVelocity
|
||||||
ReachWalkTargetVelocity,
|
ReachWalkTargetVelocity,
|
||||||
// Water,
|
// Water,
|
||||||
}
|
}
|
||||||
@@ -1135,10 +1136,11 @@ impl PhysicsData{
|
|||||||
|
|
||||||
//this is the one who asks
|
//this is the one who asks
|
||||||
fn next_instruction_internal(state:&PhysicsState,data:&PhysicsData,time_limit:Time)->Option<TimedInstruction<InternalInstruction,Time>>{
|
fn next_instruction_internal(state:&PhysicsState,data:&PhysicsData,time_limit:Time)->Option<TimedInstruction<InternalInstruction,Time>>{
|
||||||
|
println!("==== next_instruction_internal ====");
|
||||||
//JUST POLLING!!! NO MUTATION
|
//JUST POLLING!!! NO MUTATION
|
||||||
let mut collector=instruction::InstructionCollector::new(time_limit);
|
let mut collector=instruction::InstructionCollector::new(time_limit);
|
||||||
|
|
||||||
collector.collect(state.next_move_instruction());
|
// collector.collect(state.next_move_instruction());
|
||||||
|
|
||||||
//check for collision ends
|
//check for collision ends
|
||||||
state.touching.predict_collision_end(&mut collector,&data.models,&data.hitbox_mesh,&state.body,state.time);
|
state.touching.predict_collision_end(&mut collector,&data.models,&data.hitbox_mesh,&state.body,state.time);
|
||||||
@@ -1150,6 +1152,7 @@ impl PhysicsData{
|
|||||||
//let relative_body=state.body.relative_to(&Body::ZERO);
|
//let relative_body=state.body.relative_to(&Body::ZERO);
|
||||||
let relative_body=&state.body;
|
let relative_body=&state.body;
|
||||||
data.bvh.sample_aabb(&aabb,&mut |&convex_mesh_id|{
|
data.bvh.sample_aabb(&aabb,&mut |&convex_mesh_id|{
|
||||||
|
println!("Sampling object id={:?}",convex_mesh_id.model_id);
|
||||||
//no checks are needed because of the time limits.
|
//no checks are needed because of the time limits.
|
||||||
let model_mesh=data.models.mesh(convex_mesh_id);
|
let model_mesh=data.models.mesh(convex_mesh_id);
|
||||||
let minkowski=model_physics::MinkowskiMesh::minkowski_sum(model_mesh,data.hitbox_mesh.transformed_mesh());
|
let minkowski=model_physics::MinkowskiMesh::minkowski_sum(model_mesh,data.hitbox_mesh.transformed_mesh());
|
||||||
@@ -1265,6 +1268,7 @@ fn set_velocity_cull(body:&mut Body,touching:&mut TouchingState,models:&PhysicsM
|
|||||||
let n=contact_normal(models,hitbox_mesh,contact);
|
let n=contact_normal(models,hitbox_mesh,contact);
|
||||||
let r=n.dot(v).is_positive();
|
let r=n.dot(v).is_positive();
|
||||||
if r{
|
if r{
|
||||||
|
println!("culled {:?}",contact.model_id);
|
||||||
culled=true;
|
culled=true;
|
||||||
}
|
}
|
||||||
!r
|
!r
|
||||||
@@ -1633,6 +1637,7 @@ fn collision_end_contact(
|
|||||||
_attr:&gameplay_attributes::ContactAttributes,
|
_attr:&gameplay_attributes::ContactAttributes,
|
||||||
contact:ContactCollision,
|
contact:ContactCollision,
|
||||||
){
|
){
|
||||||
|
println!("collision_end {:?}",contact.model_id);
|
||||||
touching.remove(&Collision::Contact(contact));//remove contact before calling contact_constrain_acceleration
|
touching.remove(&Collision::Contact(contact));//remove contact before calling contact_constrain_acceleration
|
||||||
//check ground
|
//check ground
|
||||||
//TODO do better
|
//TODO do better
|
||||||
@@ -1680,18 +1685,16 @@ fn collision_end_intersect(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:TimedInstruction<InternalInstruction,Time>){
|
fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:TimedInstruction<InternalInstruction,Time>){
|
||||||
|
println!("\n==== atomic_internal_instruction ====");
|
||||||
state.time=ins.time;
|
state.time=ins.time;
|
||||||
let (should_advance_body,goober_time)=match ins.instruction{
|
match ins.instruction{
|
||||||
|
// collisions advance the body precisely
|
||||||
InternalInstruction::CollisionStart(_,dt)
|
InternalInstruction::CollisionStart(_,dt)
|
||||||
|InternalInstruction::CollisionEnd(_,dt)=>(true,Some(dt)),
|
|InternalInstruction::CollisionEnd(_,dt)=>state.body.advance_time_ratio_dt(dt),
|
||||||
InternalInstruction::StrafeTick
|
// this advances imprecisely
|
||||||
|InternalInstruction::ReachWalkTargetVelocity=>(true,None),
|
InternalInstruction::ReachWalkTargetVelocity=>state.body.advance_time(state.time),
|
||||||
};
|
// strafe tick decides for itself whether to advance the body.
|
||||||
if should_advance_body{
|
InternalInstruction::StrafeTick=>(),
|
||||||
match goober_time{
|
|
||||||
Some(dt)=>state.body.advance_time_ratio_dt(dt),
|
|
||||||
None=>state.body.advance_time(state.time),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
match ins.instruction{
|
match ins.instruction{
|
||||||
InternalInstruction::CollisionStart(collision,_)=>{
|
InternalInstruction::CollisionStart(collision,_)=>{
|
||||||
@@ -1738,6 +1741,8 @@ fn atomic_internal_instruction(state:&mut PhysicsState,data:&PhysicsData,ins:Tim
|
|||||||
let masked_controls=strafe_settings.mask(controls);
|
let masked_controls=strafe_settings.mask(controls);
|
||||||
let control_dir=state.style.get_control_dir(masked_controls);
|
let control_dir=state.style.get_control_dir(masked_controls);
|
||||||
if control_dir!=vec3::ZERO{
|
if control_dir!=vec3::ZERO{
|
||||||
|
// manually advance time
|
||||||
|
state.body.advance_time(state.time);
|
||||||
let camera_mat=state.camera.simulate_move_rotation_y(state.input_state.lerp_delta(state.time).x);
|
let camera_mat=state.camera.simulate_move_rotation_y(state.input_state.lerp_delta(state.time).x);
|
||||||
if let Some(ticked_velocity)=strafe_settings.tick_velocity(state.body.velocity,(camera_mat*control_dir).with_length(Planar64::ONE).divide().wrap_1()){
|
if let Some(ticked_velocity)=strafe_settings.tick_velocity(state.body.velocity,(camera_mat*control_dir).with_length(Planar64::ONE).divide().wrap_1()){
|
||||||
//this is wrong but will work ig
|
//this is wrong but will work ig
|
||||||
|
|||||||
@@ -552,12 +552,6 @@ impl TryFrom<[f32;3]> for Unit32Vec3{
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// placeholder until bnum supports u8
|
|
||||||
#[derive(Clone,Copy,Debug,Hash,Eq,PartialEq,Ord,PartialOrd)]
|
|
||||||
pub struct Planar32(i32);
|
|
||||||
pub type Planar32Vec3=linear_ops::types::Vector3<Planar32>;
|
|
||||||
pub type Planar32Mat3=linear_ops::types::Matrix3<Planar32>;
|
|
||||||
|
|
||||||
pub type Planar64TryFromFloatError=fixed_wide::fixed::FixedFromFloatError;
|
pub type Planar64TryFromFloatError=fixed_wide::fixed::FixedFromFloatError;
|
||||||
pub type Planar64=fixed_wide::types::I32F32;
|
pub type Planar64=fixed_wide::types::I32F32;
|
||||||
pub type Planar64Vec3=linear_ops::types::Vector3<Planar64>;
|
pub type Planar64Vec3=linear_ops::types::Vector3<Planar64>;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::integer::{Planar32Vec3,Planar32Mat3,Planar64Vec3};
|
use crate::integer::{Planar64,Planar64Vec3,Planar64Affine3};
|
||||||
use crate::gameplay_attributes;
|
use crate::gameplay_attributes;
|
||||||
|
|
||||||
pub type TextureCoordinate=glam::Vec2;
|
pub type TextureCoordinate=glam::Vec2;
|
||||||
@@ -22,32 +22,61 @@ pub struct IndexedVertex{
|
|||||||
}
|
}
|
||||||
#[derive(Clone,Copy,Hash,id::Id,PartialEq,Eq)]
|
#[derive(Clone,Copy,Hash,id::Id,PartialEq,Eq)]
|
||||||
pub struct VertexId(u32);
|
pub struct VertexId(u32);
|
||||||
#[derive(Clone)]
|
pub type IndexedVertexList=Vec<VertexId>;
|
||||||
pub struct Triangle([VertexId;3]);
|
pub trait PolygonIter{
|
||||||
impl Triangle{
|
fn polys(&self)->impl Iterator<Item=&[VertexId]>;
|
||||||
pub fn new(verts:[VertexId;3])->Self{
|
}
|
||||||
Self(verts)
|
pub trait MapVertexId{
|
||||||
}
|
fn map_vertex_id<F:Fn(VertexId)->VertexId>(self,f:F)->Self;
|
||||||
}
|
}
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct TriangleList(Vec<Triangle>);
|
pub struct PolygonList(Vec<IndexedVertexList>);
|
||||||
impl TriangleList{
|
impl PolygonList{
|
||||||
pub const fn new(list:Vec<Triangle>)->Self{
|
pub const fn new(list:Vec<IndexedVertexList>)->Self{
|
||||||
Self(list)
|
Self(list)
|
||||||
}
|
}
|
||||||
pub fn extend<T:IntoIterator<Item=Triangle>>(&mut self,iter:T){
|
pub fn extend<T:IntoIterator<Item=IndexedVertexList>>(&mut self,iter:T){
|
||||||
self.0.extend(iter);
|
self.0.extend(iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl PolygonIter for PolygonList{
|
||||||
|
fn polys(&self)->impl Iterator<Item=&[VertexId]>{
|
||||||
|
self.0.iter().map(|poly|poly.as_slice())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl MapVertexId for PolygonList{
|
||||||
|
fn map_vertex_id<F:Fn(VertexId)->VertexId>(self,f:F)->Self{
|
||||||
|
Self(self.0.into_iter().map(|ivl|ivl.into_iter().map(&f).collect()).collect())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// pub struct TriangleStrip(IndexedVertexList);
|
||||||
|
// impl PolygonIter for TriangleStrip{
|
||||||
|
// fn polys(&self)->impl Iterator<Item=&[VertexId]>{
|
||||||
|
// self.0.vertices.windows(3).enumerate().map(|(i,s)|if i&0!=0{return s.iter().rev()}else{return s.iter()})
|
||||||
|
// }
|
||||||
|
// }
|
||||||
#[derive(Clone,Copy,Hash,id::Id,PartialEq,Eq)]
|
#[derive(Clone,Copy,Hash,id::Id,PartialEq,Eq)]
|
||||||
pub struct PolygonGroupId(u32);
|
pub struct PolygonGroupId(u32);
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum PolygonGroup{
|
pub enum PolygonGroup{
|
||||||
TriangleList(TriangleList),
|
PolygonList(PolygonList),
|
||||||
//TriangleStrip(TriangleStrip),
|
//TriangleStrip(TriangleStrip),
|
||||||
}
|
}
|
||||||
|
impl PolygonIter for PolygonGroup{
|
||||||
|
fn polys(&self)->impl Iterator<Item=&[VertexId]>{
|
||||||
|
match self{
|
||||||
|
PolygonGroup::PolygonList(list)=>list.polys(),
|
||||||
|
//PolygonGroup::TriangleStrip(strip)=>strip.polys(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl MapVertexId for PolygonGroup{
|
||||||
|
fn map_vertex_id<F:Fn(VertexId)->VertexId>(self,f:F)->Self{
|
||||||
|
match self{
|
||||||
|
PolygonGroup::PolygonList(polys)=>Self::PolygonList(polys.map_vertex_id(f)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/// Ah yes, a group of things to render at the same time
|
/// Ah yes, a group of things to render at the same time
|
||||||
#[derive(Clone,Copy,Debug,Hash,id::Id,Eq,PartialEq)]
|
#[derive(Clone,Copy,Debug,Hash,id::Id,Eq,PartialEq)]
|
||||||
pub struct TextureId(u32);
|
pub struct TextureId(u32);
|
||||||
@@ -80,8 +109,8 @@ pub struct IndexedPhysicsGroup{
|
|||||||
pub struct MeshId(u32);
|
pub struct MeshId(u32);
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Mesh{
|
pub struct Mesh{
|
||||||
pub unique_pos:Vec<Planar32Vec3>,
|
pub unique_pos:Vec<Planar64Vec3>,//Unit32Vec3
|
||||||
pub unique_normal:Vec<Planar32Vec3>,
|
pub unique_normal:Vec<Planar64Vec3>,//Unit32Vec3
|
||||||
pub unique_tex:Vec<TextureCoordinate>,
|
pub unique_tex:Vec<TextureCoordinate>,
|
||||||
pub unique_color:Vec<Color4>,
|
pub unique_color:Vec<Color4>,
|
||||||
pub unique_vertices:Vec<IndexedVertex>,
|
pub unique_vertices:Vec<IndexedVertex>,
|
||||||
@@ -98,13 +127,13 @@ pub struct Mesh{
|
|||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct MeshBuilder{
|
pub struct MeshBuilder{
|
||||||
unique_pos:Vec<Planar32Vec3>,
|
unique_pos:Vec<Planar64Vec3>,//Unit32Vec3
|
||||||
unique_normal:Vec<Planar32Vec3>,
|
unique_normal:Vec<Planar64Vec3>,//Unit32Vec3
|
||||||
unique_tex:Vec<TextureCoordinate>,
|
unique_tex:Vec<TextureCoordinate>,
|
||||||
unique_color:Vec<Color4>,
|
unique_color:Vec<Color4>,
|
||||||
unique_vertices:Vec<IndexedVertex>,
|
unique_vertices:Vec<IndexedVertex>,
|
||||||
pos_id_from:HashMap<Planar32Vec3,PositionId>,
|
pos_id_from:HashMap<Planar64Vec3,PositionId>,//Unit32Vec3
|
||||||
normal_id_from:HashMap<Planar32Vec3,NormalId>,
|
normal_id_from:HashMap<Planar64Vec3,NormalId>,//Unit32Vec3
|
||||||
tex_id_from:HashMap<[u32;2],TextureCoordinateId>,
|
tex_id_from:HashMap<[u32;2],TextureCoordinateId>,
|
||||||
color_id_from:HashMap<[u32;4],ColorId>,
|
color_id_from:HashMap<[u32;4],ColorId>,
|
||||||
vertex_id_from:HashMap<IndexedVertex,VertexId>,
|
vertex_id_from:HashMap<IndexedVertex,VertexId>,
|
||||||
@@ -138,14 +167,19 @@ impl MeshBuilder{
|
|||||||
physics_groups,
|
physics_groups,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn acquire_pos_id(&mut self,pos:Planar32Vec3)->PositionId{
|
pub fn acquire_pos_id(&mut self,pos:Planar64Vec3)->PositionId{
|
||||||
|
// Truncate the 16 most precise bits of the vertex positions.
|
||||||
|
// This allows the normal vectors to exactly represent the face.
|
||||||
|
// Remove this in Mesh V2
|
||||||
|
const MASK:Planar64=Planar64::raw(!((1<<16)-1));
|
||||||
|
let pos=pos.map(|c|c&MASK);
|
||||||
*self.pos_id_from.entry(pos).or_insert_with(||{
|
*self.pos_id_from.entry(pos).or_insert_with(||{
|
||||||
let pos_id=PositionId::new(self.unique_pos.len() as u32);
|
let pos_id=PositionId::new(self.unique_pos.len() as u32);
|
||||||
self.unique_pos.push(pos);
|
self.unique_pos.push(pos);
|
||||||
pos_id
|
pos_id
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn acquire_normal_id(&mut self,normal:Planar32Vec3)->NormalId{
|
pub fn acquire_normal_id(&mut self,normal:Planar64Vec3)->NormalId{
|
||||||
*self.normal_id_from.entry(normal).or_insert_with(||{
|
*self.normal_id_from.entry(normal).or_insert_with(||{
|
||||||
let normal_id=NormalId::new(self.unique_normal.len() as u32);
|
let normal_id=NormalId::new(self.unique_normal.len() as u32);
|
||||||
self.unique_normal.push(normal);
|
self.unique_normal.push(normal);
|
||||||
@@ -183,6 +217,5 @@ pub struct Model{
|
|||||||
pub mesh:MeshId,
|
pub mesh:MeshId,
|
||||||
pub attributes:gameplay_attributes::CollisionAttributesId,
|
pub attributes:gameplay_attributes::CollisionAttributesId,
|
||||||
pub color:Color4,//transparency is in here
|
pub color:Color4,//transparency is in here
|
||||||
pub matrix3:Planar32Mat3,
|
pub transform:Planar64Affine3,
|
||||||
pub translation:Planar64Vec3,
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::collections::HashMap;
|
|||||||
use rbx_mesh::mesh::{Vertex2,Vertex2Truncated};
|
use rbx_mesh::mesh::{Vertex2,Vertex2Truncated};
|
||||||
use strafesnet_common::aabb::Aabb;
|
use strafesnet_common::aabb::Aabb;
|
||||||
use strafesnet_common::integer::vec3;
|
use strafesnet_common::integer::vec3;
|
||||||
use strafesnet_common::model::{self,ColorId,IndexedVertex,NormalId,PolygonGroup,Triangle,TriangleList,PositionId,RenderConfigId,TextureCoordinateId,VertexId};
|
use strafesnet_common::model::{self,ColorId,IndexedVertex,PolygonGroup,PolygonList,RenderConfigId,VertexId};
|
||||||
|
|
||||||
use crate::loader::MeshWithSize;
|
use crate::loader::MeshWithSize;
|
||||||
|
|
||||||
@@ -67,8 +67,8 @@ fn ingest_faces2_lods3(
|
|||||||
){
|
){
|
||||||
//faces have to be split into polygon groups based on lod
|
//faces have to be split into polygon groups based on lod
|
||||||
polygon_groups.extend(lods.windows(2).map(|lod_pair|
|
polygon_groups.extend(lods.windows(2).map(|lod_pair|
|
||||||
PolygonGroup::TriangleList(TriangleList::new(faces[lod_pair[0].0 as usize..lod_pair[1].0 as usize].iter().map(|rbx_mesh::mesh::Face2(v0,v1,v2)|
|
PolygonGroup::PolygonList(PolygonList::new(faces[lod_pair[0].0 as usize..lod_pair[1].0 as usize].iter().map(|rbx_mesh::mesh::Face2(v0,v1,v2)|
|
||||||
Triangle::new([vertex_id_map[&v0],vertex_id_map[&v1],vertex_id_map[&v2]])
|
vec![vertex_id_map[&v0],vertex_id_map[&v1],vertex_id_map[&v2]]
|
||||||
).collect()))
|
).collect()))
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -90,7 +90,7 @@ pub fn convert(roblox_mesh_bytes:crate::data::RobloxMeshBytes)->Result<MeshWithS
|
|||||||
};
|
};
|
||||||
Ok(mb.acquire_vertex_id(vertex))
|
Ok(mb.acquire_vertex_id(vertex))
|
||||||
};
|
};
|
||||||
Ok(Triangle::new([ingest_vertex1(&trip[0])?,ingest_vertex1(&trip[1])?,ingest_vertex1(&trip[2])?))
|
Ok(vec![ingest_vertex1(&trip[0])?,ingest_vertex1(&trip[1])?,ingest_vertex1(&trip[2])?])
|
||||||
}).collect::<Result<_,_>>().map_err(Error::Planar64Vec3)?)));
|
}).collect::<Result<_,_>>().map_err(Error::Planar64Vec3)?)));
|
||||||
},
|
},
|
||||||
rbx_mesh::mesh::Mesh::V2(mesh)=>{
|
rbx_mesh::mesh::Mesh::V2(mesh)=>{
|
||||||
@@ -103,8 +103,8 @@ pub fn convert(roblox_mesh_bytes:crate::data::RobloxMeshBytes)->Result<MeshWithS
|
|||||||
rbx_mesh::mesh::SizeOfVertex2::Full=>ingest_vertices2(mesh.vertices,&mut mb),
|
rbx_mesh::mesh::SizeOfVertex2::Full=>ingest_vertices2(mesh.vertices,&mut mb),
|
||||||
}?;
|
}?;
|
||||||
//one big happy group for all the faces
|
//one big happy group for all the faces
|
||||||
polygon_groups.push(PolygonGroup::TriangleList(TriangleList::new(mesh.faces.into_iter().map(|face|
|
polygon_groups.push(PolygonGroup::PolygonList(PolygonList::new(mesh.faces.into_iter().map(|face|
|
||||||
Triangle::new([vertex_id_map[&face.0],vertex_id_map[&face.1],vertex_id_map[&face.2]])
|
vec![vertex_id_map[&face.0],vertex_id_map[&face.1],vertex_id_map[&face.2]]
|
||||||
).collect())));
|
).collect())));
|
||||||
},
|
},
|
||||||
rbx_mesh::mesh::Mesh::V3(mesh)=>{
|
rbx_mesh::mesh::Mesh::V3(mesh)=>{
|
||||||
|
|||||||
Reference in New Issue
Block a user