Enhance | 实现了一部分编辑器内碰撞箱检测
This commit is contained in:
parent
0e1d260bb2
commit
549f85f673
@ -9,3 +9,5 @@
|
|||||||
pub mod dr;
|
pub mod dr;
|
||||||
pub mod math;
|
pub mod math;
|
||||||
pub mod sr1;
|
pub mod sr1;
|
||||||
|
|
||||||
|
pub type IdType = i128;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use nalgebra::Vector2;
|
use nalgebra::Vector2;
|
||||||
use rapier2d_f64::geometry::{SharedShape, TriMeshFlags};
|
use rapier2d_f64::geometry::TriMeshFlags;
|
||||||
use rapier2d_f64::math::{Isometry, Point, Real};
|
use rapier2d_f64::math::{Point, Real};
|
||||||
use rapier2d_f64::parry::transformation::vhacd::VHACDParameters;
|
use rapier2d_f64::parry::transformation::vhacd::VHACDParameters;
|
||||||
|
|
||||||
pub enum ConnectType {
|
pub enum ConnectType {
|
||||||
|
@ -13,8 +13,8 @@ use crate::sr1_data::ship::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::data_type::math::{Point2D, Rotatable};
|
use crate::data_type::math::{Point2D, Rotatable};
|
||||||
|
use crate::data_type::IdType;
|
||||||
|
|
||||||
pub type IdType = i64;
|
|
||||||
pub type ConnectionType = Vec<(Vec<SR1PartData>, Option<Vec<Connection>>)>;
|
pub type ConnectionType = Vec<(Vec<SR1PartData>, Option<Vec<Connection>>)>;
|
||||||
|
|
||||||
pub fn radians_map_to_degrees(angle: f64) -> f64 {
|
pub fn radians_map_to_degrees(angle: f64) -> f64 {
|
||||||
|
@ -4,9 +4,10 @@ use pyo3::exceptions::PyValueError;
|
|||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
use crate::data_type::math::{Point2D, Rotatable};
|
use crate::data_type::math::{Point2D, Rotatable};
|
||||||
|
use crate::data_type::sr1::SaveStatus;
|
||||||
use crate::data_type::sr1::{get_max_box, SR1PartData, SR1PartListTrait};
|
use crate::data_type::sr1::{get_max_box, SR1PartData, SR1PartListTrait};
|
||||||
use crate::data_type::sr1::{IdType, SaveStatus};
|
|
||||||
use crate::data_type::sr1::{SR1PartList, SR1PartType, SR1Ship};
|
use crate::data_type::sr1::{SR1PartList, SR1PartType, SR1Ship};
|
||||||
|
use crate::data_type::IdType;
|
||||||
use crate::sr1_data::part_list::RawPartList;
|
use crate::sr1_data::part_list::RawPartList;
|
||||||
|
|
||||||
#[pyclass]
|
#[pyclass]
|
||||||
@ -308,10 +309,10 @@ impl PySR1Ship {
|
|||||||
parts
|
parts
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_part_box(&self, part_id: i64) -> Option<((f64, f64), (f64, f64))> {
|
fn get_part_box(&self, part_id: IdType) -> Option<((f64, f64), (f64, f64))> {
|
||||||
let part_data = self.ship.parts.iter().find(|&x| x.id == part_id);
|
let part_data = self.ship.parts.iter().find(|&x| x.id == part_id);
|
||||||
if let Some(part_data) = part_data {
|
if let Some(part_data) = part_data {
|
||||||
let part_type = self.part_list.get_part_type(&part_data.part_type_id).unwrap();
|
if let Some(part_type) = self.part_list.get_part_type(&part_data.part_type_id) {
|
||||||
// rotate
|
// rotate
|
||||||
let radius = part_data.angle;
|
let radius = part_data.angle;
|
||||||
let ((x1, y1), (x2, y2)) = part_type.get_box();
|
let ((x1, y1), (x2, y2)) = part_type.get_box();
|
||||||
@ -324,6 +325,7 @@ impl PySR1Ship {
|
|||||||
p2.add_mut(part_data.x * 2.0, part_data.y * 2.0);
|
p2.add_mut(part_data.x * 2.0, part_data.y * 2.0);
|
||||||
return Some(((p1.x, p1.y), (p2.x, p2.y)));
|
return Some(((p1.x, p1.y), (p2.x, p2.y)));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,14 +6,141 @@
|
|||||||
* -------------------------------
|
* -------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use nalgebra::{Matrix2, Vector2};
|
||||||
use nalgebra::Vector2;
|
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
use rapier2d_f64::math::Real;
|
||||||
|
|
||||||
use crate::data_type::dr::BoxColliderEnum;
|
use crate::data_type::IdType;
|
||||||
|
|
||||||
|
/// Id 位置 碰撞体
|
||||||
|
pub type BoundedShape = (IdType, Vector2<Real>, EditorShapeEnum);
|
||||||
|
|
||||||
|
pub enum EditorShapeEnum {
|
||||||
|
/// 矩形
|
||||||
|
/// 一个方向的向量 另一个方向的向量
|
||||||
|
Cuboid(Vector2<Real>, Vector2<Real>),
|
||||||
|
/// 三角形
|
||||||
|
/// 一个方向的向量 另一个方向的向量
|
||||||
|
Triangle(Vector2<Real>, Vector2<Real>),
|
||||||
|
/// 圆
|
||||||
|
/// 半径
|
||||||
|
Ball(Real),
|
||||||
|
/// 组合
|
||||||
|
Compound(Vec<EditorShapeEnum>),
|
||||||
|
}
|
||||||
|
|
||||||
// #[pyclass]
|
// #[pyclass]
|
||||||
pub struct EditorArea {
|
pub struct EditorArea {
|
||||||
/// 存储所有碰撞箱信息
|
/// 存储所有碰撞箱信息
|
||||||
pub collision_box: Vec<BoxColliderEnum>,
|
pub collision_box: Vec<BoundedShape>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EditorArea {
|
||||||
|
/// 添加一个碰撞箱
|
||||||
|
pub fn add_box(&mut self, box_data: BoundedShape) {
|
||||||
|
self.collision_box.push(box_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 删除一个碰撞箱
|
||||||
|
pub fn remove_box_by_id(&mut self, id: IdType) -> bool {
|
||||||
|
for (i, box_data) in self.collision_box.iter().enumerate() {
|
||||||
|
if box_data.0 == id {
|
||||||
|
self.collision_box.remove(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 检查一个点是否碰撞到任意一个碰撞箱
|
||||||
|
pub fn check_hit(&self, point: Vector2<Real>) -> Option<IdType> {
|
||||||
|
for box_data in self.collision_box.iter() {
|
||||||
|
match &box_data.2 {
|
||||||
|
// 球 直接勾股定理秒了
|
||||||
|
EditorShapeEnum::Ball(r) => {
|
||||||
|
if (point - box_data.1).norm() <= *r {
|
||||||
|
return Some(box_data.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 矩形
|
||||||
|
// 进行一个旋转
|
||||||
|
EditorShapeEnum::Cuboid(dir1, dir2) => {
|
||||||
|
// 先平移坐标系
|
||||||
|
let point = point - box_data.1;
|
||||||
|
// 求出逆矩阵
|
||||||
|
let inv = Matrix2::new(dir1.x, dir2.x, dir1.y, dir2.y).try_inverse().unwrap();
|
||||||
|
// 变换
|
||||||
|
let point = inv * point;
|
||||||
|
// 判断是否在矩形内
|
||||||
|
if point.x >= 0.0 && point.x <= 1.0 && point.y >= 0.0 && point.y <= 1.0 {
|
||||||
|
return Some(box_data.0);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 三角形
|
||||||
|
EditorShapeEnum::Triangle(dir1, dir2) => {
|
||||||
|
// 先平移坐标系
|
||||||
|
let point = point - box_data.1;
|
||||||
|
// 求出逆矩阵
|
||||||
|
let inv = Matrix2::new(dir1.x, dir2.x, dir1.y, dir2.y).try_inverse().unwrap();
|
||||||
|
// 变换
|
||||||
|
let point = inv * point;
|
||||||
|
// 判断是否在三角形内
|
||||||
|
if point.x >= 0.0 && point.y >= 0.0 && point.x + point.y <= 1.0 {
|
||||||
|
return Some(box_data.0);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
EditorShapeEnum::Compound(shapes) => {
|
||||||
|
for shape in shapes {
|
||||||
|
match shape {
|
||||||
|
// 球 直接勾股定理秒了
|
||||||
|
EditorShapeEnum::Ball(r) => {
|
||||||
|
if (point - box_data.1).norm() <= *r {
|
||||||
|
return Some(box_data.0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 矩形
|
||||||
|
// 进行一个旋转
|
||||||
|
EditorShapeEnum::Cuboid(dir1, dir2) => {
|
||||||
|
// 先平移坐标系
|
||||||
|
let point = point - box_data.1;
|
||||||
|
// 求出逆矩阵
|
||||||
|
let inv = Matrix2::new(dir1.x, dir2.x, dir1.y, dir2.y).try_inverse().unwrap();
|
||||||
|
// 变换
|
||||||
|
let point = inv * point;
|
||||||
|
// 判断是否在矩形内
|
||||||
|
if point.x >= 0.0 && point.x <= 1.0 && point.y >= 0.0 && point.y <= 1.0 {
|
||||||
|
return Some(box_data.0);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 三角形
|
||||||
|
EditorShapeEnum::Triangle(dir1, dir2) => {
|
||||||
|
// 先平移坐标系
|
||||||
|
let point = point - box_data.1;
|
||||||
|
// 求出逆矩阵
|
||||||
|
let inv = Matrix2::new(dir1.x, dir2.x, dir1.y, dir2.y).try_inverse().unwrap();
|
||||||
|
// 变换
|
||||||
|
let point = inv * point;
|
||||||
|
// 判断是否在三角形内
|
||||||
|
if point.x >= 0.0 && point.y >= 0.0 && point.x + point.y <= 1.0 {
|
||||||
|
return Some(box_data.0);
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
EditorShapeEnum::Compound(_) => {
|
||||||
|
panic!("Compound in Compound");
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,8 +6,9 @@ use serde::{Deserialize, Serialize};
|
|||||||
use serde_xml_rs::from_str;
|
use serde_xml_rs::from_str;
|
||||||
use serde_xml_rs::Error as XmlError;
|
use serde_xml_rs::Error as XmlError;
|
||||||
|
|
||||||
use crate::data_type::sr1::{IdType, SR1PartData, SR1PartDataAttr, SR1Ship};
|
use crate::data_type::sr1::{SR1PartData, SR1PartDataAttr, SR1Ship};
|
||||||
use crate::data_type::sr1::{SR1PartDataTrait, SR1ShipTrait};
|
use crate::data_type::sr1::{SR1PartDataTrait, SR1ShipTrait};
|
||||||
|
use crate::data_type::IdType;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
#[serde(rename = "Ship")]
|
#[serde(rename = "Ship")]
|
||||||
@ -51,7 +52,7 @@ pub struct Part {
|
|||||||
pub pod: Option<Pod>,
|
pub pod: Option<Pod>,
|
||||||
#[serde(rename = "partType")]
|
#[serde(rename = "partType")]
|
||||||
pub part_type_id: String,
|
pub part_type_id: String,
|
||||||
pub id: i64,
|
pub id: IdType,
|
||||||
pub x: f64,
|
pub x: f64,
|
||||||
pub y: f64,
|
pub y: f64,
|
||||||
#[serde(rename = "editorAngle")]
|
#[serde(rename = "editorAngle")]
|
||||||
@ -119,7 +120,7 @@ pub struct Step {
|
|||||||
#[serde(rename = "Activate")]
|
#[serde(rename = "Activate")]
|
||||||
pub struct Activate {
|
pub struct Activate {
|
||||||
#[serde(rename = "Id")]
|
#[serde(rename = "Id")]
|
||||||
pub id: i64,
|
pub id: IdType,
|
||||||
pub moved: i8, // 1 or 0
|
pub moved: i8, // 1 or 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user