Compare commits

...

3 Commits

Author SHA1 Message Date
c03a424043 holy refactor 2025-08-26 16:27:17 -07:00
a81e12f1e4 common: Mesh v2 2025-08-26 16:26:26 -07:00
3cbad7869f common: Planar32 2025-08-26 16:25:38 -07:00
4 changed files with 39 additions and 66 deletions

View File

@@ -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,PolygonIter}; use strafesnet_common::model::{self,MeshId};
use strafesnet_common::integer::{self,vec3,Fixed,Planar64,Planar64Vec3,Ratio}; use strafesnet_common::integer::{self,vec3,Fixed,Planar32Vec3,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,7 +74,7 @@ struct Face{
dot:Planar64, dot:Planar64,
} }
#[derive(Debug)] #[derive(Debug)]
struct Vert(Planar64Vec3); struct Vert(Planar32Vec3);
pub trait MeshQuery{ pub trait MeshQuery{
type Face:Copy; type Face:Copy;
type Edge:Copy+DirectedEdge; type Edge:Copy+DirectedEdge;

View File

@@ -552,6 +552,12 @@ 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>;

View File

@@ -1,6 +1,6 @@
use std::collections::HashMap; use std::collections::HashMap;
use crate::integer::{Planar64,Planar64Vec3,Planar64Affine3}; use crate::integer::{Planar32Vec3,Planar32Mat3,Planar64Vec3};
use crate::gameplay_attributes; use crate::gameplay_attributes;
pub type TextureCoordinate=glam::Vec2; pub type TextureCoordinate=glam::Vec2;
@@ -22,61 +22,32 @@ 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);
pub type IndexedVertexList=Vec<VertexId>; #[derive(Clone)]
pub trait PolygonIter{ pub struct Triangle([VertexId;3]);
fn polys(&self)->impl Iterator<Item=&[VertexId]>; impl Triangle{
} pub fn new(verts:[VertexId;3])->Self{
pub trait MapVertexId{ Self(verts)
fn map_vertex_id<F:Fn(VertexId)->VertexId>(self,f:F)->Self; }
} }
#[derive(Clone)] #[derive(Clone)]
pub struct PolygonList(Vec<IndexedVertexList>); pub struct TriangleList(Vec<Triangle>);
impl PolygonList{ impl TriangleList{
pub const fn new(list:Vec<IndexedVertexList>)->Self{ pub const fn new(list:Vec<Triangle>)->Self{
Self(list) Self(list)
} }
pub fn extend<T:IntoIterator<Item=IndexedVertexList>>(&mut self,iter:T){ pub fn extend<T:IntoIterator<Item=Triangle>>(&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{
PolygonList(PolygonList), TriangleList(TriangleList),
//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);
@@ -109,8 +80,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<Planar64Vec3>,//Unit32Vec3 pub unique_pos:Vec<Planar32Vec3>,
pub unique_normal:Vec<Planar64Vec3>,//Unit32Vec3 pub unique_normal:Vec<Planar32Vec3>,
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>,
@@ -127,13 +98,13 @@ pub struct Mesh{
#[derive(Default)] #[derive(Default)]
pub struct MeshBuilder{ pub struct MeshBuilder{
unique_pos:Vec<Planar64Vec3>,//Unit32Vec3 unique_pos:Vec<Planar32Vec3>,
unique_normal:Vec<Planar64Vec3>,//Unit32Vec3 unique_normal:Vec<Planar32Vec3>,
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<Planar64Vec3,PositionId>,//Unit32Vec3 pos_id_from:HashMap<Planar32Vec3,PositionId>,
normal_id_from:HashMap<Planar64Vec3,NormalId>,//Unit32Vec3 normal_id_from:HashMap<Planar32Vec3,NormalId>,
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>,
@@ -167,19 +138,14 @@ impl MeshBuilder{
physics_groups, physics_groups,
} }
} }
pub fn acquire_pos_id(&mut self,pos:Planar64Vec3)->PositionId{ pub fn acquire_pos_id(&mut self,pos:Planar32Vec3)->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:Planar64Vec3)->NormalId{ pub fn acquire_normal_id(&mut self,normal:Planar32Vec3)->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);
@@ -217,5 +183,6 @@ 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 transform:Planar64Affine3, pub matrix3:Planar32Mat3,
pub translation:Planar64Vec3,
} }

View File

@@ -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,PolygonGroup,PolygonList,RenderConfigId,VertexId}; use strafesnet_common::model::{self,ColorId,IndexedVertex,NormalId,PolygonGroup,Triangle,TriangleList,PositionId,RenderConfigId,TextureCoordinateId,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::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)| 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)|
vec![vertex_id_map[&v0],vertex_id_map[&v1],vertex_id_map[&v2]] Triangle::new([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(vec![ingest_vertex1(&trip[0])?,ingest_vertex1(&trip[1])?,ingest_vertex1(&trip[2])?]) Ok(Triangle::new([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::PolygonList(PolygonList::new(mesh.faces.into_iter().map(|face| polygon_groups.push(PolygonGroup::TriangleList(TriangleList::new(mesh.faces.into_iter().map(|face|
vec![vertex_id_map[&face.0],vertex_id_map[&face.1],vertex_id_map[&face.2]] Triangle::new([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)=>{