Change a few of details.
This commit is contained in:
parent
d910a428b1
commit
dbd4ccd31b
@ -1,3 +1,5 @@
|
||||
use std::ops::Add;
|
||||
|
||||
pub const POINT_D: f64 = 1.0;
|
||||
|
||||
pub trait Rotate {
|
||||
@ -9,7 +11,7 @@ pub trait Rotate {
|
||||
fn rotate_radius_mut(&mut self, radius: f64);
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Default, Clone, Copy)]
|
||||
pub struct Point2D {
|
||||
pub x: f64,
|
||||
pub y: f64,
|
||||
@ -20,10 +22,6 @@ impl Point2D {
|
||||
Self { x, y }
|
||||
}
|
||||
|
||||
pub fn new_default() -> Self {
|
||||
Self { x: 0.0, y: 0.0 }
|
||||
}
|
||||
|
||||
pub fn distance(&self, other: &Point2D) -> f64 {
|
||||
let dx = (other.x - self.x).powf(2.0);
|
||||
let dy = (other.y - self.y).powf(2.0);
|
||||
@ -34,10 +32,6 @@ impl Point2D {
|
||||
self.distance(&Point2D::new(0.0, 0.0))
|
||||
}
|
||||
|
||||
pub fn add(&self, x: f64, y: f64) -> Self {
|
||||
Point2D::new(self.x + x, self.y + y)
|
||||
}
|
||||
|
||||
pub fn add_mut(&mut self, x: f64, y: f64) {
|
||||
self.x += x;
|
||||
self.y += y;
|
||||
@ -67,6 +61,17 @@ impl Rotate for Point2D {
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for Point2D {
|
||||
type Output = Self;
|
||||
|
||||
fn add(self, rhs: Self) -> Self {
|
||||
Self {
|
||||
x: self.x + rhs.x,
|
||||
y: self.y + rhs.y,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct CircularArc {
|
||||
// 半径
|
||||
@ -129,6 +134,7 @@ impl Shape {
|
||||
let x = x.unwrap_or(0.0);
|
||||
let y = y.unwrap_or(0.0);
|
||||
let degree = degree.unwrap_or(0.0);
|
||||
|
||||
Self {
|
||||
pos: Point2D::new(x, y),
|
||||
degree,
|
||||
@ -152,10 +158,12 @@ impl Shape {
|
||||
Edge::OneTimeLine(line) => {
|
||||
let start = line.start.rotate_radius(radius);
|
||||
let end = line.end.rotate_radius(radius);
|
||||
|
||||
Edge::OneTimeLine(OneTimeLine::point_new(&start, &end))
|
||||
}
|
||||
Edge::CircularArc(arc) => {
|
||||
let pos = arc.pos.rotate_radius(radius);
|
||||
|
||||
Edge::CircularArc(CircularArc {
|
||||
r: arc.r,
|
||||
pos,
|
||||
@ -166,8 +174,9 @@ impl Shape {
|
||||
})
|
||||
.collect();
|
||||
}
|
||||
|
||||
Self {
|
||||
pos: Point2D::new_default(),
|
||||
pos: Default::default(),
|
||||
degree: 0.0,
|
||||
bounds: edges,
|
||||
}
|
||||
|
@ -5,12 +5,15 @@ use rapier2d_f64::geometry::TriMeshFlags;
|
||||
use rapier2d_f64::math::{Point, Real};
|
||||
use rapier2d_f64::parry::transformation::vhacd::VHACDParameters;
|
||||
|
||||
#[derive(Default)]
|
||||
pub enum ConnectType {
|
||||
#[default]
|
||||
Stick,
|
||||
FixedPoint,
|
||||
RotatedPoint,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Connect {
|
||||
pub c_type: ConnectType,
|
||||
pub d_pos: f64,
|
||||
@ -110,7 +113,6 @@ pub struct TankProps {
|
||||
pub fuel_volume: f64,
|
||||
/// 空油罐的质量,if p_type==tank
|
||||
pub mass: f64,
|
||||
// Why the fuel type is an integer?
|
||||
/// 燃油种类,if p_type==tank
|
||||
pub fuel_type: i32,
|
||||
}
|
||||
@ -129,8 +131,8 @@ pub struct EngineProps {
|
||||
// pub throttle_exponential: f64,
|
||||
}
|
||||
|
||||
// I regard this trait as the useless one at least so far.
|
||||
// Canceling commenting this trait and deleting this two-line comment when it is truly useful.
|
||||
// 至少目前而言,我认为这个trait没有任何用途。
|
||||
// 当它真正发挥作用是时再取消对它的注释并删除这两行注释。
|
||||
|
||||
// pub trait DRComponentPropAttr<'a, T> {
|
||||
// fn name() -> &'a str;
|
||||
@ -151,7 +153,7 @@ pub struct DRComponentProps<'a, T> {
|
||||
pub name: &'a str,
|
||||
/// 描述
|
||||
pub description: &'a str,
|
||||
// Should this texture be a string instead of file?
|
||||
// 纹理需要用字符串而非文件句柄来表示吗?
|
||||
/// 贴图
|
||||
pub texture: &'a str,
|
||||
/// pub r#type: SR1PartTypeEnum,
|
||||
|
@ -9,7 +9,6 @@
|
||||
mod dr_physics;
|
||||
mod python;
|
||||
mod sr1_parse;
|
||||
mod xml_reader;
|
||||
|
||||
use pyo3::prelude::*;
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
use pyo3::prelude::*;
|
||||
use std::io::{self, Write};
|
||||
|
||||
use pyo3::prelude::*;
|
||||
|
||||
#[pyclass]
|
||||
#[pyo3(name = "Console_rs")]
|
||||
pub struct PyConsole {
|
||||
|
@ -6,12 +6,12 @@
|
||||
* -------------------------------
|
||||
*/
|
||||
|
||||
use crate::IdType;
|
||||
|
||||
use nalgebra::{Matrix2, Vector2};
|
||||
use pyo3::prelude::*;
|
||||
use rapier2d_f64::math::Real;
|
||||
|
||||
use crate::IdType;
|
||||
|
||||
/// Id 位置 碰撞体
|
||||
pub type BoundedShape = (IdType, Vector2<Real>, EditorShapeEnum);
|
||||
|
||||
|
@ -2,12 +2,8 @@ mod data_structure;
|
||||
|
||||
pub use self::data_structure::*;
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::HashMap;
|
||||
use std::io::Cursor;
|
||||
use std::ops::Deref;
|
||||
|
||||
use crate::dr_physics::math::{Edge, Shape};
|
||||
use crate::dr_physics::math::{Point2D, Rotate};
|
||||
use crate::sr1_parse::part_list::Damage as RawDamage;
|
||||
use crate::sr1_parse::part_list::{AttachPoint, AttachPoints, Engine, Lander, Rcs, Shape as RawShape, Solar, Tank};
|
||||
use crate::sr1_parse::part_list::{RawPartList, RawPartType, SR1PartTypeEnum};
|
||||
@ -16,10 +12,13 @@ use crate::sr1_parse::ship::{
|
||||
DisconnectedParts as RawDisconnectedParts, Engine as RawEngine, Part as RawPartData, Parts as RawParts,
|
||||
Pod as RawPod, RawShip, Staging as RawStaging, Step as RawStep, Tank as RawTank,
|
||||
};
|
||||
|
||||
use crate::dr_physics::math::{Point2D, Rotate};
|
||||
use crate::IdType;
|
||||
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::collections::HashMap;
|
||||
use std::io::Cursor;
|
||||
use std::ops::Deref;
|
||||
|
||||
use fs_err as fs;
|
||||
use quick_xml::events::{BytesEnd, BytesStart, Event};
|
||||
use quick_xml::writer::Writer;
|
||||
@ -49,6 +48,7 @@ pub enum SR1PartTypeAttr {
|
||||
consumption: f64,
|
||||
size: f64,
|
||||
turn: f64,
|
||||
// 我觉得用枚举体表示燃料种类更好。
|
||||
/// 0 -> 普通燃料
|
||||
/// 1 -> Rcs
|
||||
/// 2 -> 电量
|
||||
@ -964,8 +964,18 @@ pub fn get_max_box(parts: &[SR1PartData], part_list: &SR1PartList) -> (f64, f64,
|
||||
let mut p2 = Point2D::new(x2, y2);
|
||||
p1.rotate_radius_mut(part.angle);
|
||||
p2.rotate_radius_mut(part.angle);
|
||||
let p1 = p1.add(part.x * 2.0, part.y * 2.0);
|
||||
let p2 = p2.add(part.x * 2.0, part.y * 2.0);
|
||||
// let p1 = p1.add(part.x * 2.0, part.y * 2.0);
|
||||
// let p2 = p2.add(part.x * 2.0, part.y * 2.0);
|
||||
let p1 = p1
|
||||
+ Point2D {
|
||||
x: part.x * 2.0,
|
||||
y: part.y * 2.0,
|
||||
};
|
||||
let p2 = p2
|
||||
+ Point2D {
|
||||
x: part.x * 2.0,
|
||||
y: part.y * 2.0,
|
||||
};
|
||||
let (x1, y1, x2, y2) = (p1.x, p1.y, p2.x, p2.y);
|
||||
// get max box
|
||||
max_box.0 = max_box.0.min(x1).min(part.x);
|
||||
|
@ -371,8 +371,8 @@ impl RawPartList {
|
||||
}
|
||||
|
||||
pub fn from_file(file_name: String) -> Option<RawPartList> {
|
||||
let part_list_file = fs::read_to_string(file_name).unwrap();
|
||||
let part_list: RawPartList = from_str(part_list_file.as_str()).unwrap();
|
||||
let part_list_file = fs::read_to_string(file_name).ok()?;
|
||||
let part_list: RawPartList = from_str(part_list_file.as_str()).ok()?;
|
||||
Some(part_list)
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,14 @@
|
||||
use std::fs;
|
||||
use crate::sr1_parse::{SR1PartData, SR1PartDataAttr, SR1Ship};
|
||||
use crate::sr1_parse::{SR1PartDataTrait, SR1ShipTrait};
|
||||
use crate::IdType;
|
||||
|
||||
use fs_err as fs;
|
||||
use pyo3::prelude::*;
|
||||
use quick_xml::de::from_str;
|
||||
use quick_xml::se::to_string;
|
||||
// use quick_xml::Error as XmlError;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::sr1_parse::{SR1PartData, SR1PartDataAttr, SR1Ship};
|
||||
use crate::sr1_parse::{SR1PartDataTrait, SR1ShipTrait};
|
||||
use crate::IdType;
|
||||
|
||||
/// https://docs.rs/quick-xml/latest/quick_xml/de/index.html#basics
|
||||
/// using quick xml
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
@ -175,11 +174,11 @@ impl SR1PartDataTrait for Part {
|
||||
let part_type = attr.get_part_type();
|
||||
SR1PartData {
|
||||
attr,
|
||||
x: self.x.to_owned(),
|
||||
y: self.y.to_owned(),
|
||||
id: self.id.to_owned(),
|
||||
angle: self.angle.to_owned(),
|
||||
angle_v: self.angle_v.to_owned(),
|
||||
x: self.x,
|
||||
y: self.y,
|
||||
id: self.id,
|
||||
angle: self.angle,
|
||||
angle_v: self.angle_v,
|
||||
flip_x: self.flip_x.unwrap_or(0_i8) != 0,
|
||||
flip_y: self.flip_y.unwrap_or(0_i8) != 0,
|
||||
editor_angle: self.editor_angle.unwrap_or(0_i32),
|
||||
@ -196,7 +195,6 @@ impl SR1PartDataTrait for Part {
|
||||
}
|
||||
|
||||
impl SR1ShipTrait for RawShip {
|
||||
#[inline]
|
||||
fn to_sr_ship(&self, name: Option<String>) -> SR1Ship {
|
||||
let mut parts = Vec::new();
|
||||
for part in &self.parts.parts {
|
||||
@ -235,14 +233,12 @@ impl SR1ShipTrait for RawShip {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn to_raw_ship(&self) -> RawShip {
|
||||
self.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl RawShip {
|
||||
#[inline]
|
||||
pub fn from_file(path: String) -> Option<RawShip> {
|
||||
let ship_file = fs::read_to_string(path); // for encoding error
|
||||
if let Err(e) = ship_file {
|
||||
@ -267,16 +263,15 @@ impl RawShip {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn save(&self, file_name: String) -> Option<()> {
|
||||
let part_list_file = to_string(self);
|
||||
pub fn save(&self, file_name: String) -> Result<(), quick_xml::DeError> {
|
||||
let part_list_file = to_string(self)?;
|
||||
print!("{:?}", part_list_file);
|
||||
if let Ok(part_list_file) = part_list_file {
|
||||
fs::write(file_name, part_list_file).unwrap();
|
||||
Some(())
|
||||
} else {
|
||||
None
|
||||
match fs::write(file_name, part_list_file) {
|
||||
Ok(()) => (),
|
||||
Err(_) => return Err(quick_xml::DeError::Custom("Failed to save file!".to_string())),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -284,7 +279,7 @@ impl RawShip {
|
||||
#[pyo3(name = "read_ship_test")]
|
||||
#[pyo3(signature = (path = "./assets/builtin/dock1.xml".to_string()))]
|
||||
pub fn py_raw_ship_from_file(path: String) -> PyResult<bool> {
|
||||
let file = fs::read_to_string(path).unwrap();
|
||||
let file = fs::read_to_string(path)?;
|
||||
let raw_ship = from_str::<RawShip>(&file);
|
||||
match raw_ship {
|
||||
Ok(ship) => {
|
||||
|
@ -1,18 +0,0 @@
|
||||
use std::io;
|
||||
|
||||
use fs_err as fs;
|
||||
|
||||
// 输入XML文件的路径。
|
||||
// 若文件不存在或非XML文件,则返回错误,否则返回文件句柄。
|
||||
// 我认为该函数仍可改进,因为它的实现并未达到我所预期的那样。
|
||||
pub fn read_xml(path: &str) -> io::Result<fs::File> {
|
||||
if path.split_inclusive('.').collect::<Vec<&str>>()[1] != "xml" {
|
||||
Err(io::Error::new(io::ErrorKind::Other, "This file is not an XML file!"))
|
||||
} else {
|
||||
fs::File::open(path)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_xml(xml_file: fs::File) {
|
||||
todo!()
|
||||
}
|
Loading…
Reference in New Issue
Block a user