implement aabb & bvh
This commit is contained in:
parent
76cd82967a
commit
43a0eef5d1
104
src/aabb.rs
104
src/aabb.rs
@ -1,3 +1,5 @@
|
||||
use crate::integer::Planar64Vec3;
|
||||
|
||||
#[derive(Debug,Clone,Copy,Hash,Eq,PartialEq)]
|
||||
pub enum AabbFace{
|
||||
Right,//+X
|
||||
@ -8,84 +10,80 @@ pub enum AabbFace{
|
||||
Front,
|
||||
}
|
||||
#[derive(Clone)]
|
||||
pub struct Aabb {
|
||||
pub min: glam::Vec3,
|
||||
pub max: glam::Vec3,
|
||||
pub struct Aabb{
|
||||
pub min:Planar64Vec3,
|
||||
pub max:Planar64Vec3,
|
||||
}
|
||||
|
||||
impl Default for Aabb {
|
||||
fn default() -> Self {
|
||||
Aabb::new()
|
||||
fn default()->Self {
|
||||
Self{min:Planar64Vec3::MAX,max:Planar64Vec3::MIN}
|
||||
}
|
||||
}
|
||||
|
||||
impl Aabb {
|
||||
const VERTEX_DATA: [glam::Vec3; 8] = [
|
||||
glam::vec3(1., -1., -1.),
|
||||
glam::vec3(1., 1., -1.),
|
||||
glam::vec3(1., 1., 1.),
|
||||
glam::vec3(1., -1., 1.),
|
||||
glam::vec3(-1., -1., 1.),
|
||||
glam::vec3(-1., 1., 1.),
|
||||
glam::vec3(-1., 1., -1.),
|
||||
glam::vec3(-1., -1., -1.),
|
||||
impl Aabb{
|
||||
const VERTEX_DATA:[Planar64Vec3;8]=[
|
||||
Planar64Vec3::int( 1,-1,-1),
|
||||
Planar64Vec3::int( 1, 1,-1),
|
||||
Planar64Vec3::int( 1, 1, 1),
|
||||
Planar64Vec3::int( 1,-1, 1),
|
||||
Planar64Vec3::int(-1,-1, 1),
|
||||
Planar64Vec3::int(-1, 1, 1),
|
||||
Planar64Vec3::int(-1, 1,-1),
|
||||
Planar64Vec3::int(-1,-1,-1),
|
||||
];
|
||||
|
||||
pub fn new() -> Self {
|
||||
Self {min: glam::Vec3::INFINITY,max: glam::Vec3::NEG_INFINITY}
|
||||
}
|
||||
|
||||
pub fn grow(&mut self, point:glam::Vec3){
|
||||
pub fn grow(&mut self,point:Planar64Vec3){
|
||||
self.min=self.min.min(point);
|
||||
self.max=self.max.max(point);
|
||||
}
|
||||
pub fn join(&mut self, aabb:&Aabb){
|
||||
pub fn join(&mut self,aabb:&Aabb){
|
||||
self.min=self.min.min(aabb.min);
|
||||
self.max=self.max.max(aabb.max);
|
||||
}
|
||||
pub fn inflate(&mut self, hs:glam::Vec3){
|
||||
pub fn inflate(&mut self,hs:Planar64Vec3){
|
||||
self.min-=hs;
|
||||
self.max+=hs;
|
||||
}
|
||||
pub fn intersects(&self,aabb:&Aabb)->bool{
|
||||
(self.min.cmplt(aabb.max)&aabb.min.cmplt(self.max)).all()
|
||||
}
|
||||
pub fn normal(face:AabbFace) -> glam::Vec3 {
|
||||
pub fn normal(face:AabbFace)->Planar64Vec3{
|
||||
match face {
|
||||
AabbFace::Right => glam::vec3(1.,0.,0.),
|
||||
AabbFace::Top => glam::vec3(0.,1.,0.),
|
||||
AabbFace::Back => glam::vec3(0.,0.,1.),
|
||||
AabbFace::Left => glam::vec3(-1.,0.,0.),
|
||||
AabbFace::Bottom => glam::vec3(0.,-1.,0.),
|
||||
AabbFace::Front => glam::vec3(0.,0.,-1.),
|
||||
AabbFace::Right=>Planar64Vec3::int(1,0,0),
|
||||
AabbFace::Top=>Planar64Vec3::int(0,1,0),
|
||||
AabbFace::Back=>Planar64Vec3::int(0,0,1),
|
||||
AabbFace::Left=>Planar64Vec3::int(-1,0,0),
|
||||
AabbFace::Bottom=>Planar64Vec3::int(0,-1,0),
|
||||
AabbFace::Front=>Planar64Vec3::int(0,0,-1),
|
||||
}
|
||||
}
|
||||
pub fn unit_vertices() -> [glam::Vec3;8] {
|
||||
pub fn unit_vertices()->[Planar64Vec3;8] {
|
||||
return Self::VERTEX_DATA;
|
||||
}
|
||||
pub fn face(&self,face:AabbFace) -> Aabb {
|
||||
let mut aabb=self.clone();
|
||||
//in this implementation face = worldspace aabb face
|
||||
match face {
|
||||
AabbFace::Right => aabb.min.x=aabb.max.x,
|
||||
AabbFace::Top => aabb.min.y=aabb.max.y,
|
||||
AabbFace::Back => aabb.min.z=aabb.max.z,
|
||||
AabbFace::Left => aabb.max.x=aabb.min.x,
|
||||
AabbFace::Bottom => aabb.max.y=aabb.min.y,
|
||||
AabbFace::Front => aabb.max.z=aabb.min.z,
|
||||
}
|
||||
return aabb;
|
||||
}
|
||||
pub fn center(&self)->glam::Vec3{
|
||||
return (self.min+self.max)/2.0
|
||||
// pub fn face(&self,face:AabbFace)->Aabb {
|
||||
// let mut aabb=self.clone();
|
||||
// //in this implementation face = worldspace aabb face
|
||||
// match face {
|
||||
// AabbFace::Right => aabb.min.x=aabb.max.x,
|
||||
// AabbFace::Top => aabb.min.y=aabb.max.y,
|
||||
// AabbFace::Back => aabb.min.z=aabb.max.z,
|
||||
// AabbFace::Left => aabb.max.x=aabb.min.x,
|
||||
// AabbFace::Bottom => aabb.max.y=aabb.min.y,
|
||||
// AabbFace::Front => aabb.max.z=aabb.min.z,
|
||||
// }
|
||||
// return aabb;
|
||||
// }
|
||||
pub fn center(&self)->Planar64Vec3{
|
||||
return self.min.midpoint(self.max)
|
||||
}
|
||||
//probably use floats for area & volume because we don't care about precision
|
||||
pub fn area_weight(&self)->f32{
|
||||
let d=self.max-self.min;
|
||||
d.x*d.y+d.y*d.z+d.z*d.x
|
||||
}
|
||||
pub fn volume(&self)->f32{
|
||||
let d=self.max-self.min;
|
||||
d.x*d.y*d.z
|
||||
}
|
||||
// pub fn area_weight(&self)->f32{
|
||||
// let d=self.max-self.min;
|
||||
// d.x*d.y+d.y*d.z+d.z*d.x
|
||||
// }
|
||||
// pub fn volume(&self)->f32{
|
||||
// let d=self.max-self.min;
|
||||
// d.x*d.y*d.z
|
||||
// }
|
||||
}
|
10
src/bvh.rs
10
src/bvh.rs
@ -36,7 +36,7 @@ pub fn generate_bvh(boxen:Vec<Aabb>)->BvhNode{
|
||||
fn generate_bvh_node(boxen:Vec<(usize,Aabb)>)->BvhNode{
|
||||
let n=boxen.len();
|
||||
if n<20{
|
||||
let mut aabb=Aabb::new();
|
||||
let mut aabb=Aabb::default();
|
||||
let models=boxen.into_iter().map(|b|{aabb.join(&b.1);b.0 as u32}).collect();
|
||||
BvhNode{
|
||||
children:Vec::new(),
|
||||
@ -51,9 +51,9 @@ fn generate_bvh_node(boxen:Vec<(usize,Aabb)>)->BvhNode{
|
||||
for (i,aabb) in boxen.iter(){
|
||||
let center=aabb.center();
|
||||
octant.insert(*i,0);
|
||||
sort_x.push((*i,center.x));
|
||||
sort_y.push((*i,center.y));
|
||||
sort_z.push((*i,center.z));
|
||||
sort_x.push((*i,center.x()));
|
||||
sort_y.push((*i,center.y()));
|
||||
sort_z.push((*i,center.z()));
|
||||
}
|
||||
sort_x.sort_by(|tup0,tup1|tup0.1.partial_cmp(&tup1.1).unwrap());
|
||||
sort_y.sort_by(|tup0,tup1|tup0.1.partial_cmp(&tup1.1).unwrap());
|
||||
@ -92,7 +92,7 @@ fn generate_bvh_node(boxen:Vec<(usize,Aabb)>)->BvhNode{
|
||||
};
|
||||
list_list[list_id].push((i,aabb));
|
||||
}
|
||||
let mut aabb=Aabb::new();
|
||||
let mut aabb=Aabb::default();
|
||||
let children=list_list.into_iter().map(|b|{
|
||||
let node=generate_bvh_node(b);
|
||||
aabb.join(&node.aabb);
|
||||
|
@ -228,7 +228,7 @@ pub struct Unit64Mat3{
|
||||
|
||||
|
||||
///[-1.0,1.0] = [-2^32,2^32]
|
||||
#[derive(Clone,Copy,Hash,PartialEq,PartialOrd)]
|
||||
#[derive(Clone,Copy,Hash,Eq,Ord,PartialEq,PartialOrd)]
|
||||
pub struct Planar64(i64);
|
||||
impl Planar64{
|
||||
pub const ZERO:Self=Self(0);
|
||||
@ -303,7 +303,7 @@ impl std::ops::Div<Planar64> for Planar64{
|
||||
|
||||
|
||||
///[-1.0,1.0] = [-2^32,2^32]
|
||||
#[derive(Clone,Copy,Hash)]
|
||||
#[derive(Clone,Copy,Hash,Eq,PartialEq)]
|
||||
pub struct Planar64Vec3(glam::I64Vec3);
|
||||
impl Planar64Vec3{
|
||||
pub const ZERO:Self=Planar64Vec3(glam::I64Vec3::ZERO);
|
||||
@ -314,6 +314,8 @@ impl Planar64Vec3{
|
||||
pub const NEG_X:Self=Planar64Vec3(glam::I64Vec3::NEG_X);
|
||||
pub const NEG_Y:Self=Planar64Vec3(glam::I64Vec3::NEG_Y);
|
||||
pub const NEG_Z:Self=Planar64Vec3(glam::I64Vec3::NEG_Z);
|
||||
pub const MIN:Self=Planar64Vec3(glam::I64Vec3::MIN);
|
||||
pub const MAX:Self=Planar64Vec3(glam::I64Vec3::MAX);
|
||||
pub fn int(x:i32,y:i32,z:i32)->Self{
|
||||
Self(glam::i64vec3((x as i64)<<32,(y as i64)<<32,(z as i64)<<32))
|
||||
}
|
||||
@ -329,6 +331,31 @@ impl Planar64Vec3{
|
||||
pub fn z(&self)->Planar64{
|
||||
Planar64(self.0.z)
|
||||
}
|
||||
#[inline]
|
||||
pub fn min(self,rhs:Self)->Self{
|
||||
Self(glam::i64vec3(
|
||||
self.0.x.min(rhs.0.x),
|
||||
self.0.y.min(rhs.0.y),
|
||||
self.0.z.min(rhs.0.z),
|
||||
))
|
||||
}
|
||||
#[inline]
|
||||
pub fn max(self,rhs:Self)->Self{
|
||||
Self(glam::i64vec3(
|
||||
self.0.x.max(rhs.0.x),
|
||||
self.0.y.max(rhs.0.y),
|
||||
self.0.z.max(rhs.0.z),
|
||||
))
|
||||
}
|
||||
#[inline]
|
||||
pub fn midpoint(self,rhs:Self)->Self{
|
||||
Self((self.0+rhs.0)/2)
|
||||
}
|
||||
#[inline]
|
||||
pub fn cmplt(self,rhs:Self)->glam::BVec3{
|
||||
self.0.cmplt(rhs.0)
|
||||
}
|
||||
|
||||
}
|
||||
impl Into<glam::Vec3> for Planar64Vec3{
|
||||
fn into(self)->glam::Vec3{
|
||||
|
@ -338,7 +338,7 @@ pub struct ModelPhysics {
|
||||
|
||||
impl ModelPhysics {
|
||||
fn from_model_transform_attributes(model:&crate::model::IndexedModel,transform:&glam::Affine3A,attributes:PhysicsCollisionAttributes)->Self{
|
||||
let mut aabb=TreyMesh::new();
|
||||
let mut aabb=TreyMesh::default();
|
||||
for indexed_vertex in &model.unique_vertices {
|
||||
aabb.grow(transform.transform_point3(Planar64Vec3::from_array(model.unique_pos[indexed_vertex.pos as usize])));
|
||||
}
|
||||
@ -361,9 +361,9 @@ impl ModelPhysics {
|
||||
pub fn mesh(&self) -> &TreyMesh {
|
||||
return &self.mesh;
|
||||
}
|
||||
pub fn face_mesh(&self,face:TreyMeshFace)->TreyMesh{
|
||||
self.mesh.face(face)
|
||||
}
|
||||
// pub fn face_mesh(&self,face:TreyMeshFace)->TreyMesh{
|
||||
// self.mesh.face(face)
|
||||
// }
|
||||
pub fn face_normal(&self,face:TreyMeshFace) -> Planar64Vec3 {
|
||||
TreyMesh::normal(face)//this is wrong for scale
|
||||
}
|
||||
@ -381,9 +381,9 @@ impl RelativeCollision {
|
||||
pub fn model<'a>(&self,models:&'a Vec<ModelPhysics>)->Option<&'a ModelPhysics>{
|
||||
models.get(self.model as usize)
|
||||
}
|
||||
pub fn mesh(&self,models:&Vec<ModelPhysics>) -> TreyMesh {
|
||||
return self.model(models).unwrap().face_mesh(self.face).clone()
|
||||
}
|
||||
// pub fn mesh(&self,models:&Vec<ModelPhysics>) -> TreyMesh {
|
||||
// return self.model(models).unwrap().face_mesh(self.face).clone()
|
||||
// }
|
||||
pub fn normal(&self,models:&Vec<ModelPhysics>) -> Planar64Vec3 {
|
||||
return self.model(models).unwrap().face_normal(self.face)
|
||||
}
|
||||
@ -745,7 +745,7 @@ impl PhysicsState {
|
||||
}
|
||||
}
|
||||
fn mesh(&self) -> TreyMesh {
|
||||
let mut aabb=TreyMesh::new();
|
||||
let mut aabb=TreyMesh::default();
|
||||
for vertex in TreyMesh::unit_vertices(){
|
||||
aabb.grow(self.body.position+self.style.hitbox_halfsize*vertex);
|
||||
}
|
||||
@ -1038,7 +1038,7 @@ impl crate::instruction::InstructionEmitter<PhysicsInstruction> for PhysicsState
|
||||
// collector.collect(self.predict_collision_end2(self.time,time_limit,collision_data));
|
||||
// }
|
||||
//check for collision start instructions (against every part in the game with no optimization!!)
|
||||
let mut aabb=crate::aabb::Aabb::new();
|
||||
let mut aabb=crate::aabb::Aabb::default();
|
||||
aabb.grow(self.body.extrapolated_position(self.time));
|
||||
aabb.grow(self.body.extrapolated_position(time_limit));
|
||||
aabb.inflate(self.style.hitbox_halfsize);
|
||||
|
Loading…
Reference in New Issue
Block a user