Compare commits
11 Commits
test-fail
...
rewrite-ph
| Author | SHA1 | Date | |
|---|---|---|---|
|
16c5524f34
|
|||
|
b09ec62db7
|
|||
|
e7171b583c
|
|||
|
bf456e891c
|
|||
|
99eb26e9a8
|
|||
|
a301cf7ad9
|
|||
|
3b5edae0d9
|
|||
|
f95144cab1
|
|||
|
73e3181d0c
|
|||
|
19ba8f2445
|
|||
|
0495d07e26
|
644
Cargo.lock
generated
644
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,9 @@
|
|||||||
mod body;
|
mod body;
|
||||||
mod push_solve;
|
|
||||||
mod face_crawler;
|
mod face_crawler;
|
||||||
|
mod mesh_query;
|
||||||
|
mod minkowski;
|
||||||
mod model;
|
mod model;
|
||||||
|
mod push_solve;
|
||||||
|
|
||||||
pub mod physics;
|
pub mod physics;
|
||||||
|
|
||||||
|
|||||||
36
engine/physics/src/mesh_query.rs
Normal file
36
engine/physics/src/mesh_query.rs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
pub struct Vert<VertId>(pub VertId);
|
||||||
|
pub struct Edge<VertId>(pub VertId,pub VertId);
|
||||||
|
pub struct Face<VertId>(pub VertId,pub VertId,pub VertId);
|
||||||
|
|
||||||
|
pub enum FEV<VertId>{
|
||||||
|
Vert(Vert<VertId>),
|
||||||
|
Edge(Edge<VertId>),
|
||||||
|
Face(Face<VertId>),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait MeshTopology{
|
||||||
|
type VertId;
|
||||||
|
fn for_each_vert_edge(&self,vert_id:Vert<Self::VertId>,f:impl FnMut(Edge<Self::VertId>));
|
||||||
|
fn for_each_vert_face(&self,vert_id:Vert<Self::VertId>,f:impl FnMut(Face<Self::VertId>));
|
||||||
|
fn edge_faces(&self,edge_id:Edge<Self::VertId>)->impl AsRef<[Face<Self::VertId>;2]>;
|
||||||
|
fn edge_verts(&self,edge_id:Edge<Self::VertId>)->impl AsRef<[Vert<Self::VertId>;2]>;
|
||||||
|
fn for_each_face_vert(&self,face_id:Face<Self::VertId>,f:impl FnMut(Vert<Self::VertId>));
|
||||||
|
fn for_each_face_edge(&self,face_id:Face<Self::VertId>,f:impl FnMut(Edge<Self::VertId>));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make face_nd d value relative
|
||||||
|
// euclidean point?
|
||||||
|
// Simplex physics
|
||||||
|
// Directed edge nucessary?
|
||||||
|
// recursive for_each function calls
|
||||||
|
// define faces from vertices (Fixed<2> vs Fixed<3>)
|
||||||
|
pub trait MeshQuery:MeshTopology{
|
||||||
|
type Position;
|
||||||
|
type Normal;
|
||||||
|
type Offset;
|
||||||
|
fn vert(&self,vert_id:Vert<Self::VertId>)->Self::Position;
|
||||||
|
/// This must return a point inside the mesh.
|
||||||
|
fn hint_point(&self)->Self::Position;
|
||||||
|
fn face_nd(&self,face_id:Face<Self::VertId>)->(Self::Normal,Self::Offset);
|
||||||
|
fn edge_n(&self,edge_id:Edge<Self::VertId>)->Self::Position;
|
||||||
|
}
|
||||||
75
engine/physics/src/minkowski.rs
Normal file
75
engine/physics/src/minkowski.rs
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
use crate::mesh_query::{MeshQuery,MeshTopology};
|
||||||
|
use crate::mesh_query::{Face,Edge,Vert};
|
||||||
|
|
||||||
|
struct AsRefHelper<T>(T);
|
||||||
|
impl<T> AsRef<T> for AsRefHelper<T>{
|
||||||
|
fn as_ref(&self)->&T{
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct MinkowskiVert<V>{
|
||||||
|
vert0:V,
|
||||||
|
vert1:V,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Minkowski<M>{
|
||||||
|
mesh0:M,
|
||||||
|
mesh1:M,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<M> Minkowski<M>{
|
||||||
|
pub fn sum(mesh0:M,mesh1:M)->Self{
|
||||||
|
Self{mesh0,mesh1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<M:MeshTopology> MeshTopology for Minkowski<M>{
|
||||||
|
type VertId=MinkowskiVert<M::VertId>;
|
||||||
|
fn for_each_vert_edge(&self,vert_id:Vert<Self::VertId>,f:impl FnMut(Edge<Self::VertId>)){
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn for_each_vert_face(&self,vert_id:Vert<Self::VertId>,f:impl FnMut(Face<Self::VertId>)){
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn edge_faces(&self,edge_id:Edge<Self::VertId>)->impl AsRef<[Face<Self::VertId>;2]>{
|
||||||
|
AsRefHelper(todo!())
|
||||||
|
}
|
||||||
|
fn edge_verts(&self,edge_id:Edge<Self::VertId>)->impl AsRef<[Vert<Self::VertId>;2]>{
|
||||||
|
AsRefHelper(todo!())
|
||||||
|
}
|
||||||
|
fn for_each_face_vert(&self,face_id:Face<Self::VertId>,f:impl FnMut(Vert<Self::VertId>)){
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn for_each_face_edge(&self,face_id:Face<Self::VertId>,f:impl FnMut(Edge<Self::VertId>)){
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
use strafesnet_common::integer::vec3::Vector3;
|
||||||
|
use strafesnet_common::integer::Fixed;
|
||||||
|
impl<M> MeshQuery for Minkowski<M>
|
||||||
|
where
|
||||||
|
M:MeshQuery<
|
||||||
|
Position=Vector3<Fixed<1,32>>,
|
||||||
|
Normal=Vector3<Fixed<3,96>>,
|
||||||
|
Offset=Fixed<4,128>,
|
||||||
|
>
|
||||||
|
{
|
||||||
|
type Position=M::Position;
|
||||||
|
type Normal=M::Normal;
|
||||||
|
type Offset=M::Offset;
|
||||||
|
fn vert(&self,vert_id:Vert<Self::VertId>)->Self::Position{
|
||||||
|
let Vert(MinkowskiVert{vert0,vert1})=vert_id;
|
||||||
|
self.mesh1.vert(Vert(vert1))-self.mesh0.vert(Vert(vert0))
|
||||||
|
}
|
||||||
|
fn hint_point(&self)->Self::Position{
|
||||||
|
self.mesh1.hint_point()-self.mesh0.hint_point()
|
||||||
|
}
|
||||||
|
fn face_nd(&self,face_id:Face<Self::VertId>)->(Self::Normal,Self::Offset){
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
fn edge_n(&self,edge_id:Edge<Self::VertId>)->Self::Position{
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
2
engine/physics/src/physics_mesh.rs
Normal file
2
engine/physics/src/physics_mesh.rs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
// PhysicsMesh
|
||||||
|
// TransformedMesh?
|
||||||
@@ -13,16 +13,16 @@ authors = ["Rhys Lloyd <krakow20@gmail.com>"]
|
|||||||
bytemuck = "1.14.3"
|
bytemuck = "1.14.3"
|
||||||
glam = "0.30.0"
|
glam = "0.30.0"
|
||||||
regex = { version = "1.11.3", default-features = false }
|
regex = { version = "1.11.3", default-features = false }
|
||||||
rbx_binary = { version = "1.0.1-sn5", registry = "strafesnet" }
|
|
||||||
rbx_dom_weak = { version = "3.0.1-sn5", registry = "strafesnet" }
|
|
||||||
rbx_mesh = "0.5.0"
|
rbx_mesh = "0.5.0"
|
||||||
rbx_reflection = "5.0.0"
|
|
||||||
rbx_reflection_database = "1.0.0"
|
|
||||||
rbx_xml = { version = "1.0.1-sn5", registry = "strafesnet" }
|
|
||||||
rbxassetid = { version = "0.1.0", path = "../rbxassetid", registry = "strafesnet" }
|
rbxassetid = { version = "0.1.0", path = "../rbxassetid", registry = "strafesnet" }
|
||||||
roblox_emulator = { version = "0.5.1", path = "../roblox_emulator", default-features = false, registry = "strafesnet" }
|
roblox_emulator = { version = "0.5.1", path = "../roblox_emulator", default-features = false, registry = "strafesnet" }
|
||||||
strafesnet_common = { version = "0.7.0", path = "../common", registry = "strafesnet" }
|
strafesnet_common = { version = "0.7.0", path = "../common", registry = "strafesnet" }
|
||||||
strafesnet_deferred_loader = { version = "0.5.1", path = "../deferred_loader", registry = "strafesnet" }
|
strafesnet_deferred_loader = { version = "0.5.1", path = "../deferred_loader", registry = "strafesnet" }
|
||||||
|
rbx_binary = "2.0.1"
|
||||||
|
rbx_dom_weak = "4.1.0"
|
||||||
|
rbx_reflection = "6.1.0"
|
||||||
|
rbx_reflection_database = "2.0.2"
|
||||||
|
rbx_xml = "2.0.1"
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|||||||
@@ -559,7 +559,7 @@ pub fn convert<'a>(
|
|||||||
//just going to leave it like this for now instead of reworking the data structures for this whole thing
|
//just going to leave it like this for now instead of reworking the data structures for this whole thing
|
||||||
let textureless_render_group=render_config_deferred_loader.acquire_render_config_id(None);
|
let textureless_render_group=render_config_deferred_loader.acquire_render_config_id(None);
|
||||||
|
|
||||||
let db=rbx_reflection_database::get();
|
let db=rbx_reflection_database::get().unwrap();
|
||||||
let basepart=&db.classes["BasePart"];
|
let basepart=&db.classes["BasePart"];
|
||||||
let baseparts=dom.descendants().filter(|&instance|
|
let baseparts=dom.descendants().filter(|&instance|
|
||||||
db.classes.get(instance.class.as_str()).is_some_and(|class|
|
db.classes.get(instance.class.as_str()).is_some_and(|class|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "roblox_emulator"
|
name = "roblox_emulator"
|
||||||
version = "0.5.1"
|
version = "0.5.2"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
repository = "https://git.itzana.me/StrafesNET/strafe-project"
|
repository = "https://git.itzana.me/StrafesNET/strafe-project"
|
||||||
license = "MIT OR Apache-2.0"
|
license = "MIT OR Apache-2.0"
|
||||||
@@ -15,10 +15,10 @@ run-service=[]
|
|||||||
glam = "0.30.0"
|
glam = "0.30.0"
|
||||||
mlua = { version = "0.11.3", features = ["luau"] }
|
mlua = { version = "0.11.3", features = ["luau"] }
|
||||||
phf = { version = "0.13.1", features = ["macros"] }
|
phf = { version = "0.13.1", features = ["macros"] }
|
||||||
rbx_dom_weak = { version = "3.0.1-sn5", registry = "strafesnet" }
|
rbx_dom_weak = "4.1.0"
|
||||||
rbx_reflection = "5.0.0"
|
rbx_reflection = "6.1.0"
|
||||||
rbx_reflection_database = "1.0.0"
|
rbx_reflection_database = "2.0.2"
|
||||||
rbx_types = "2.0.0"
|
rbx_types = "3.1.0"
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ impl Context{
|
|||||||
}
|
}
|
||||||
/// Creates an iterator over all items of a particular class.
|
/// Creates an iterator over all items of a particular class.
|
||||||
pub fn superclass_iter<'a>(&'a self,superclass:&'a str)->impl Iterator<Item=Ref>+'a{
|
pub fn superclass_iter<'a>(&'a self,superclass:&'a str)->impl Iterator<Item=Ref>+'a{
|
||||||
let db=rbx_reflection_database::get();
|
let db=rbx_reflection_database::get().unwrap();
|
||||||
let Some(superclass)=db.classes.get(superclass)else{
|
let Some(superclass)=db.classes.get(superclass)else{
|
||||||
panic!("Invalid class");
|
panic!("Invalid class");
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ impl PartialEq for EnumItem<'_>{
|
|||||||
pub struct Enums;
|
pub struct Enums;
|
||||||
impl Enums{
|
impl Enums{
|
||||||
pub fn get(&self,index:&str)->Option<EnumItems<'static>>{
|
pub fn get(&self,index:&str)->Option<EnumItems<'static>>{
|
||||||
let db=rbx_reflection_database::get();
|
let db=rbx_reflection_database::get().unwrap();
|
||||||
db.enums.get(index).map(|ed|EnumItems{ed})
|
db.enums.get(index).map(|ed|EnumItems{ed})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ pub fn dom_mut<T>(lua:&mlua::Lua,mut f:impl FnMut(&mut WeakDom)->mlua::Result<T>
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn class_is_a(class:&str,superclass:&str)->bool{
|
pub fn class_is_a(class:&str,superclass:&str)->bool{
|
||||||
let db=rbx_reflection_database::get();
|
let db=rbx_reflection_database::get().unwrap();
|
||||||
let (Some(class),Some(superclass))=(db.classes.get(class),db.classes.get(superclass))else{
|
let (Some(class),Some(superclass))=(db.classes.get(class),db.classes.get(superclass))else{
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
@@ -80,14 +80,14 @@ pub fn find_first_descendant_of_class<'a>(dom:&'a WeakDom,instance:&rbx_dom_weak
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_first_child_which_is_a<'a>(dom:&'a WeakDom,instance:&rbx_dom_weak::Instance,superclass:&str)->Option<&'a rbx_dom_weak::Instance>{
|
pub fn find_first_child_which_is_a<'a>(dom:&'a WeakDom,instance:&rbx_dom_weak::Instance,superclass:&str)->Option<&'a rbx_dom_weak::Instance>{
|
||||||
let db=rbx_reflection_database::get();
|
let db=rbx_reflection_database::get().unwrap();
|
||||||
let superclass_descriptor=db.classes.get(superclass)?;
|
let superclass_descriptor=db.classes.get(superclass)?;
|
||||||
instance.children().iter().filter_map(|&r|dom.get_by_ref(r)).find(|inst|{
|
instance.children().iter().filter_map(|&r|dom.get_by_ref(r)).find(|inst|{
|
||||||
db.classes.get(inst.class.as_str()).is_some_and(|descriptor|db.has_superclass(descriptor,superclass_descriptor))
|
db.classes.get(inst.class.as_str()).is_some_and(|descriptor|db.has_superclass(descriptor,superclass_descriptor))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn find_first_descendant_which_is_a<'a>(dom:&'a WeakDom,instance:&rbx_dom_weak::Instance,superclass:&str)->Option<&'a rbx_dom_weak::Instance>{
|
pub fn find_first_descendant_which_is_a<'a>(dom:&'a WeakDom,instance:&rbx_dom_weak::Instance,superclass:&str)->Option<&'a rbx_dom_weak::Instance>{
|
||||||
let db=rbx_reflection_database::get();
|
let db=rbx_reflection_database::get().unwrap();
|
||||||
let superclass_descriptor=db.classes.get(superclass)?;
|
let superclass_descriptor=db.classes.get(superclass)?;
|
||||||
dom.descendants_of(instance.referent()).find(|inst|{
|
dom.descendants_of(instance.referent()).find(|inst|{
|
||||||
db.classes.get(inst.class.as_str()).is_some_and(|descriptor|db.has_superclass(descriptor,superclass_descriptor))
|
db.classes.get(inst.class.as_str()).is_some_and(|descriptor|db.has_superclass(descriptor,superclass_descriptor))
|
||||||
@@ -282,7 +282,7 @@ impl mlua::UserData for Instance{
|
|||||||
dom_mut(lua,|dom|{
|
dom_mut(lua,|dom|{
|
||||||
let instance=this.get(dom)?;
|
let instance=this.get(dom)?;
|
||||||
//println!("__index t={} i={index:?}",instance.name);
|
//println!("__index t={} i={index:?}",instance.name);
|
||||||
let db=rbx_reflection_database::get();
|
let db=rbx_reflection_database::get().unwrap();
|
||||||
let class=db.classes.get(instance.class.as_str()).ok_or_else(||mlua::Error::runtime("Class missing"))?;
|
let class=db.classes.get(instance.class.as_str()).ok_or_else(||mlua::Error::runtime("Class missing"))?;
|
||||||
// Find existing property
|
// Find existing property
|
||||||
// Interestingly, ustr can know ahead of time if
|
// Interestingly, ustr can know ahead of time if
|
||||||
@@ -344,7 +344,7 @@ impl mlua::UserData for Instance{
|
|||||||
let index_str=&*index.to_str()?;
|
let index_str=&*index.to_str()?;
|
||||||
dom_mut(lua,|dom|{
|
dom_mut(lua,|dom|{
|
||||||
let instance=this.get_mut(dom)?;
|
let instance=this.get_mut(dom)?;
|
||||||
let db=rbx_reflection_database::get();
|
let db=rbx_reflection_database::get().unwrap();
|
||||||
let class=db.classes.get(instance.class.as_str()).ok_or_else(||mlua::Error::runtime("Class missing"))?;
|
let class=db.classes.get(instance.class.as_str()).ok_or_else(||mlua::Error::runtime("Class missing"))?;
|
||||||
let property=db.superclasses_iter(class).find_map(|cls|
|
let property=db.superclasses_iter(class).find_map(|cls|
|
||||||
cls.properties.get(index_str)
|
cls.properties.get(index_str)
|
||||||
|
|||||||
@@ -13,10 +13,10 @@ futures = "0.3.31"
|
|||||||
image = "0.25.2"
|
image = "0.25.2"
|
||||||
image_dds = "0.7.1"
|
image_dds = "0.7.1"
|
||||||
rbx_asset = { version = "0.5.0", registry = "strafesnet" }
|
rbx_asset = { version = "0.5.0", registry = "strafesnet" }
|
||||||
rbx_binary = { version = "1.0.1-sn5", registry = "strafesnet" }
|
rbx_binary = "2.0.1"
|
||||||
rbx_dom_weak = { version = "3.0.1-sn5", registry = "strafesnet" }
|
rbx_dom_weak = "4.1.0"
|
||||||
rbx_reflection_database = "1.0.0"
|
rbx_reflection_database = "2.0.2"
|
||||||
rbx_xml = { version = "1.0.1-sn5", registry = "strafesnet" }
|
rbx_xml = "2.0.1"
|
||||||
rbxassetid = { version = "0.1.0", registry = "strafesnet" }
|
rbxassetid = { version = "0.1.0", registry = "strafesnet" }
|
||||||
strafesnet_bsp_loader = { version = "0.3.1", path = "../lib/bsp_loader", registry = "strafesnet" }
|
strafesnet_bsp_loader = { version = "0.3.1", path = "../lib/bsp_loader", registry = "strafesnet" }
|
||||||
strafesnet_deferred_loader = { version = "0.5.1", path = "../lib/deferred_loader", registry = "strafesnet" }
|
strafesnet_deferred_loader = { version = "0.5.1", path = "../lib/deferred_loader", registry = "strafesnet" }
|
||||||
|
|||||||
Reference in New Issue
Block a user