Compare commits
6 Commits
md-compare
...
luauu
| Author | SHA1 | Date | |
|---|---|---|---|
|
8801a82ee9
|
|||
|
9c4e49ce15
|
|||
|
fee511e0db
|
|||
|
c57423553a
|
|||
|
9f5af7060f
|
|||
|
6ef2e41421
|
14
Cargo.lock
generated
14
Cargo.lock
generated
@@ -1974,9 +1974,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "luau0-src"
|
||||
version = "0.15.11+luau697"
|
||||
version = "0.17.0+luau701"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bdbf698d77af7b846fab212ca666c5d597b9ff445ef1a647e181d3392e13dfdf"
|
||||
checksum = "ed8f8edd8aba9654a9eeb62b2fe7461589f2faf2d0a1bc04bd64c0123319b3fc"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
@@ -2149,12 +2149,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "mlua"
|
||||
version = "0.11.4"
|
||||
version = "0.11.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9be1c2bfc684b8a228fbaebf954af7a47a98ec27721986654a4cc2c40a20cc7e"
|
||||
checksum = "935ac67539907efcd7198137eb7358e052555f77fe1b2916600a2249351f2b33"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"either",
|
||||
"libc",
|
||||
"mlua-sys",
|
||||
"num-traits",
|
||||
"parking_lot",
|
||||
@@ -2164,9 +2165,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "mlua-sys"
|
||||
version = "0.8.3"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d4dc9cfc5a7698899802e97480617d9726f7da78c910db989d4d0fd4991d900"
|
||||
checksum = "8c968af21bf6b19fc9ca8e7b85ee16f86e4c9e3d0591de101a5608086bda0ad8"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if",
|
||||
@@ -3814,6 +3815,7 @@ dependencies = [
|
||||
"arrayvec",
|
||||
"glam",
|
||||
"id",
|
||||
"mlua",
|
||||
"strafesnet_common",
|
||||
]
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ edition = "2024"
|
||||
arrayvec = "0.7.6"
|
||||
glam = "0.30.0"
|
||||
id = { version = "0.1.0", registry = "strafesnet" }
|
||||
mlua = { version = "0.11.5", features = ["luau"] }
|
||||
strafesnet_common = { path = "../../lib/common", registry = "strafesnet" }
|
||||
|
||||
[lints]
|
||||
|
||||
@@ -3,6 +3,7 @@ mod face_crawler;
|
||||
mod model;
|
||||
mod push_solve;
|
||||
mod minimum_difference;
|
||||
mod minimum_difference_lua;
|
||||
|
||||
pub mod physics;
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ fn reduce1(
|
||||
)->Reduced{
|
||||
// --debug.profilebegin("reduceSimplex0")
|
||||
// local a = a1 - a0
|
||||
let p0=mesh.vert(v0);
|
||||
let p0=-mesh.vert(v0);
|
||||
|
||||
// local p = -a
|
||||
let p=-(p0+point);
|
||||
@@ -133,8 +133,8 @@ fn reduce2(
|
||||
// --debug.profilebegin("reduceSimplex1")
|
||||
// local a = a1 - a0
|
||||
// local b = b1 - b0
|
||||
let p0=mesh.vert(v0);
|
||||
let p1=mesh.vert(v1);
|
||||
let p0=-mesh.vert(v0);
|
||||
let p1=-mesh.vert(v1);
|
||||
|
||||
// local p = -a
|
||||
// local u = b - a
|
||||
@@ -191,9 +191,9 @@ fn reduce3(
|
||||
// local a = a1 - a0
|
||||
// local b = b1 - b0
|
||||
// local c = c1 - c0
|
||||
let p0=mesh.vert(v0);
|
||||
let p1=mesh.vert(v1);
|
||||
let p2=mesh.vert(v2);
|
||||
let p0=-mesh.vert(v0);
|
||||
let p1=-mesh.vert(v1);
|
||||
let p2=-mesh.vert(v2);
|
||||
|
||||
// local p = -a
|
||||
// local u = b - a
|
||||
@@ -301,10 +301,10 @@ fn reduce4(
|
||||
// local b = b1 - b0
|
||||
// local c = c1 - c0
|
||||
// local d = d1 - d0
|
||||
let p0=mesh.vert(v0);
|
||||
let p1=mesh.vert(v1);
|
||||
let p2=mesh.vert(v2);
|
||||
let p3=mesh.vert(v3);
|
||||
let p0=-mesh.vert(v0);
|
||||
let p1=-mesh.vert(v1);
|
||||
let p2=-mesh.vert(v2);
|
||||
let p3=-mesh.vert(v3);
|
||||
|
||||
// local p = -a
|
||||
// local u = b - a
|
||||
@@ -593,14 +593,14 @@ fn minimum_difference<const ENABLE_FAST_FAIL:bool,T>(
|
||||
// local new_point_p = queryP(initialAxis)
|
||||
// local new_point_q = queryQ(-initialAxis)
|
||||
// local direction, a0, a1, b0, b1, c0, c1, d0, d1
|
||||
let mut direction=mesh.hint_point()+point;
|
||||
let mut initial_axis=-mesh.hint_point()+point;
|
||||
// degenerate case
|
||||
if direction==vec3::zero(){
|
||||
direction=choose_any_direction();
|
||||
if initial_axis==vec3::zero(){
|
||||
initial_axis=choose_any_direction();
|
||||
}
|
||||
let last_point=mesh.farthest_vert(direction);
|
||||
// this represents the 'a' value in the commented code
|
||||
let mut last_pos=mesh.vert(last_point);
|
||||
let mut last_pos=-mesh.vert(last_point);
|
||||
let Reduced{dir:mut direction,simplex:mut simplex_small}=reduce1([last_point],mesh,point);
|
||||
|
||||
// exitRadius = testIntersection and 0 or exitRadius or 1/0
|
||||
@@ -610,7 +610,7 @@ fn minimum_difference<const ENABLE_FAST_FAIL:bool,T>(
|
||||
// new_point_q = queryQ(direction)
|
||||
// local next_point = new_point_q - new_point_p
|
||||
let next_point=mesh.farthest_vert(-direction);
|
||||
let next_pos=mesh.vert(next_point);
|
||||
let next_pos=-mesh.vert(next_point);
|
||||
|
||||
// if -direction:Dot(next_point) > (exitRadius + radiusP + radiusQ)*direction.magnitude then
|
||||
if ENABLE_FAST_FAIL&&direction.dot(next_pos+point).is_negative(){
|
||||
|
||||
159
engine/physics/src/minimum_difference_lua.rs
Normal file
159
engine/physics/src/minimum_difference_lua.rs
Normal file
@@ -0,0 +1,159 @@
|
||||
use mlua::{Lua,FromLuaMulti,IntoLuaMulti,Function,Result as LuaResult,Vector};
|
||||
use strafesnet_common::integer::{Planar64,Planar64Vec3,FixedFromFloatError};
|
||||
|
||||
use crate::model::{MeshQuery,MinkowskiMesh};
|
||||
|
||||
pub fn contains_point(
|
||||
mesh:&MinkowskiMesh,
|
||||
point:Planar64Vec3,
|
||||
)->LuaResult<bool>{
|
||||
Ok(minimum_difference(mesh,point,true)?.hits)
|
||||
}
|
||||
pub fn minimum_difference_details(
|
||||
mesh:&MinkowskiMesh,
|
||||
point:Planar64Vec3,
|
||||
)->LuaResult<(bool,Details)>{
|
||||
let md=minimum_difference(mesh,point,false)?;
|
||||
Ok((md.hits,md.details.unwrap()))
|
||||
}
|
||||
fn p64v3(v:Vector)->Result<Planar64Vec3,FixedFromFloatError>{
|
||||
Ok(Planar64Vec3::new([
|
||||
v.x().try_into()?,
|
||||
v.y().try_into()?,
|
||||
v.z().try_into()?,
|
||||
]))
|
||||
}
|
||||
fn vec(v:Planar64Vec3)->Vector{
|
||||
Vector::new(v.x.into(),v.y.into(),v.z.into())
|
||||
}
|
||||
struct MinimumDifference{
|
||||
hits:bool,
|
||||
details:Option<Details>
|
||||
}
|
||||
pub struct Details{
|
||||
pub distance:Planar64,
|
||||
pub p_pos:Planar64Vec3,
|
||||
pub p_norm:Planar64Vec3,
|
||||
pub q_pos:Planar64Vec3,
|
||||
pub q_norm:Planar64Vec3,
|
||||
}
|
||||
impl FromLuaMulti for MinimumDifference{
|
||||
fn from_lua_multi(mut values:mlua::MultiValue,_lua:&Lua)->LuaResult<Self>{
|
||||
match values.make_contiguous(){
|
||||
&mut [
|
||||
mlua::Value::Boolean(hits),
|
||||
mlua::Value::Nil,
|
||||
mlua::Value::Nil,
|
||||
mlua::Value::Nil,
|
||||
mlua::Value::Nil,
|
||||
mlua::Value::Nil,
|
||||
]=>Ok(Self{hits,details:None}),
|
||||
&mut [
|
||||
mlua::Value::Boolean(hits),
|
||||
mlua::Value::Number(distance),
|
||||
mlua::Value::Vector(p_pos),
|
||||
mlua::Value::Vector(p_norm),
|
||||
mlua::Value::Vector(q_pos),
|
||||
mlua::Value::Vector(q_norm),
|
||||
]=>Ok(Self{
|
||||
hits,
|
||||
details:Some(Details{
|
||||
distance:distance.try_into().unwrap(),
|
||||
p_pos:p64v3(p_pos).unwrap(),
|
||||
p_norm:p64v3(p_norm).unwrap(),
|
||||
q_pos:p64v3(q_pos).unwrap(),
|
||||
q_norm:p64v3(q_norm).unwrap(),
|
||||
}),
|
||||
}),
|
||||
values=>Err(mlua::Error::runtime(format!("Invalid return values: {values:?}"))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct Args{
|
||||
query_p:Function,
|
||||
radius_p:f64,
|
||||
query_q:Function,
|
||||
radius_q:f64,
|
||||
exit_radius:f64,
|
||||
test_intersection:bool,
|
||||
}
|
||||
impl Args{
|
||||
fn new(
|
||||
lua:&Lua,
|
||||
mesh:&'static MinkowskiMesh<'static>,
|
||||
point:Planar64Vec3,
|
||||
test_intersection:bool,
|
||||
)->LuaResult<Self>{
|
||||
let radius_p=0.0;
|
||||
let radius_q=0.0;
|
||||
let exit_radius=0.0;
|
||||
// Query the farthest point on the mesh in the given direction.
|
||||
let query_p=lua.create_function(move|_,dir:Option<Vector>|{
|
||||
let Some(dir)=dir else{
|
||||
return Ok(vec(mesh.mesh0.hint_point()));
|
||||
};
|
||||
let dir=p64v3(dir).unwrap();
|
||||
let vert_id=mesh.mesh0.farthest_vert(dir);
|
||||
let dir=mesh.mesh0.vert(vert_id);
|
||||
Ok(vec(dir))
|
||||
})?;
|
||||
// query_q is different since it includes the test point offset.
|
||||
let query_q=lua.create_function(move|_,dir:Option<Vector>|{
|
||||
let Some(dir)=dir else{
|
||||
return Ok(vec(mesh.mesh1.hint_point()+point));
|
||||
};
|
||||
let dir=p64v3(dir).unwrap();
|
||||
let vert_id=mesh.mesh1.farthest_vert(dir);
|
||||
let dir=mesh.mesh1.vert(vert_id)+point;
|
||||
Ok(vec(dir))
|
||||
})?;
|
||||
Ok(Args{
|
||||
query_p,
|
||||
radius_p,
|
||||
query_q,
|
||||
radius_q,
|
||||
exit_radius,
|
||||
test_intersection,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl IntoLuaMulti for Args{
|
||||
fn into_lua_multi(self,lua:&Lua)->LuaResult<mlua::MultiValue>{
|
||||
use mlua::IntoLua;
|
||||
Ok(mlua::MultiValue::from_vec(vec![
|
||||
self.query_p.into_lua(lua)?,
|
||||
self.radius_p.into_lua(lua)?,
|
||||
self.query_q.into_lua(lua)?,
|
||||
self.radius_q.into_lua(lua)?,
|
||||
self.exit_radius.into_lua(lua)?,
|
||||
self.test_intersection.into_lua(lua)?,
|
||||
]))
|
||||
}
|
||||
}
|
||||
|
||||
fn minimum_difference(
|
||||
mesh:&MinkowskiMesh,
|
||||
point:Planar64Vec3,
|
||||
test_intersection:bool,
|
||||
)->LuaResult<MinimumDifference>{
|
||||
let ctx=init_lua()?;
|
||||
// SAFETY: mesh lifetime must outlive args usages
|
||||
let mesh=unsafe{core::mem::transmute(mesh)};
|
||||
let args=Args::new(&ctx.lua,mesh,point,test_intersection)?;
|
||||
ctx.f.call(args)
|
||||
}
|
||||
|
||||
struct Ctx{
|
||||
lua:Lua,
|
||||
f:Function,
|
||||
}
|
||||
fn init_lua()->LuaResult<Ctx>{
|
||||
static SOURCE:std::sync::LazyLock<String>=std::sync::LazyLock::new(||std::fs::read_to_string("/home/quat/strafesnet/game/src/ReplicatedStorage/Shared/Trey-MinimumDifference.lua").unwrap());
|
||||
let lua=Lua::new();
|
||||
lua.sandbox(true)?;
|
||||
let lib_f=lua.load(SOURCE.as_str()).set_name("Trey-MinimumDifference").into_function()?;
|
||||
let lib:mlua::Table=lib_f.call(())?;
|
||||
let f=lib.raw_get("difference")?;
|
||||
Ok(Ctx{lua,f})
|
||||
}
|
||||
@@ -619,8 +619,8 @@ pub enum MinkowskiFace{
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MinkowskiMesh<'a>{
|
||||
mesh0:TransformedMesh<'a>,
|
||||
mesh1:TransformedMesh<'a>,
|
||||
pub mesh0:TransformedMesh<'a>,
|
||||
pub mesh1:TransformedMesh<'a>,
|
||||
}
|
||||
|
||||
//infinity fev algorithm state transition
|
||||
@@ -811,8 +811,9 @@ impl MinkowskiMesh<'_>{
|
||||
best_edge
|
||||
}
|
||||
pub fn contains_point(&self,point:Planar64Vec3)->bool{
|
||||
let contains_point_lua=crate::minimum_difference_lua::contains_point(self,point).unwrap();
|
||||
let contains_point=crate::minimum_difference::contains_point(self,point);
|
||||
println!("contains_point={contains_point}");
|
||||
println!("contains_point={contains_point} contains_point_lua={contains_point_lua}");
|
||||
contains_point
|
||||
}
|
||||
}
|
||||
@@ -853,8 +854,7 @@ impl MeshQuery for MinkowskiMesh<'_>{
|
||||
}
|
||||
}
|
||||
fn hint_point(&self)->Planar64Vec3{
|
||||
self.mesh1.transform.vertex.translation-
|
||||
self.mesh0.transform.vertex.translation
|
||||
self.mesh0.transform.vertex.translation-self.mesh1.transform.vertex.translation
|
||||
}
|
||||
fn face_edges(&self,face_id:MinkowskiFace)->impl AsRef<[MinkowskiDirectedEdge]>{
|
||||
match face_id{
|
||||
|
||||
Reference in New Issue
Block a user