Compare commits

...

3 Commits

Author SHA1 Message Date
InfyniteHeap
dbd4ccd31b
Change a few of details. 2023-12-24 23:59:52 +08:00
InfyniteHeap
d910a428b1
Change both the Chinese Doc and the English Doc. 2023-12-24 22:17:10 +08:00
InfyniteHeap
3224c8fc9f
Adjust file structures and bump version to 0.3.1. 2023-12-24 21:29:04 +08:00
21 changed files with 173 additions and 223 deletions

View File

@ -1,17 +1,13 @@
<div style="text-align: center;">
# Difficult Rocket # Difficult Rocket
中文 | [English](./docs/README-en.md) 中文 | [English](./docs/README-en.md)
- [GitHub](https://github.com/shenjackyuanjie/Difficult-Rocket) - [GitHub](https://github.com/shenjackyuanjie/Difficult-Rocket)
- [gitee](https://gitee.com/shenjackyuanjie/Difficult-Rocket) - [Gitee](https://gitee.com/shenjackyuanjie/Difficult-Rocket)
- [discord](https://discord.gg/kWzw2JrG6M) - [Discord](https://discord.gg/kWzw2JrG6M)
- [kook](https://kook.top/sRPjFG) - [Kook](https://kook.top/sRPjFG)
## 请注意 这个仓库未来只会发布 `DR SDK` 的更新 `DR game` 的更新会在 [这里](https://github.com/shenjackyuanjie/DR-game) 发布 >注意:本仓库未来只会发布`DR SDK`的更新。`DR game`的更新会在[这里](https://github.com/shenjackyuanjie/DR-game)发布。
![demo](docs/src/demo.png)
[![996.icu](https://img.shields.io/badge/996.icu-996.icu-red.svg)](https://996.icu) [![996.icu](https://img.shields.io/badge/996.icu-996.icu-red.svg)](https://996.icu)
[![semver](https://img.shields.io/badge/SemVer-2.0.0-blue.svg)](https://Semver.org/) [![semver](https://img.shields.io/badge/SemVer-2.0.0-blue.svg)](https://Semver.org/)
@ -33,23 +29,19 @@
[DR rs 最新 Action 构建](https://nightly.link/shenjackyuanjie/Difficult-Rocket/workflows/dr_rs/main) [DR rs 最新 Action 构建](https://nightly.link/shenjackyuanjie/Difficult-Rocket/workflows/dr_rs/main)
## English README please look [here](./docs/README-en.md) ## 介绍
> 这是一个用Python制作的类Simple Rocket游戏(简称:火箭模拟器) 这是一个用Python制作的类Simple Rocket游戏简称火箭模拟器。相对于原版SR它更加轻量。
## 优势 [计划特性列表](docs/src/plan_features/README.md)
> 相对于原版SR比较“轻量化”
## [计划特性列表](docs/src/plan_features/README.md)
[YouTrack](https://difficult-rocket.youtrack.cloud/projects/8dafd498-59c0-4ce7-9900-d9292e9ed1f0) [YouTrack](https://difficult-rocket.youtrack.cloud/projects/8dafd498-59c0-4ce7-9900-d9292e9ed1f0)
## [更新日志](docs/src/change_log/readme.md) [更新日志](docs/src/change_log/readme.md)
## 运行方式 ## 运行
### clone ### 1. Clone
```bash title="clone.sh" ```bash title="clone.sh"
mkdir DR mkdir DR
@ -61,7 +53,7 @@ git clone https://gitee.com/shenjackyuanjie/Difficult-Rocket.git
git clone git@github.com:shenjackyuanjie/Difficult-Rocket.git git clone git@github.com:shenjackyuanjie/Difficult-Rocket.git
``` ```
### 安装依赖 ### 2. 安装依赖
```bash title="install.sh" ```bash title="install.sh"
python -m pip install -r requirement.txt python -m pip install -r requirement.txt
@ -71,13 +63,15 @@ python -m pip install ./lib_not_dr
python -m pip install ./pyglet python -m pip install ./pyglet
``` ```
### 运行 ### 3. 运行
```bash title="run.sh" ```bash title="run.sh"
python DR.py python DR.py
``` ```
## 环境需求 (测试过的 / 开发平台) ## 环境需求
>开发环境使用的Python版本为`3.8.10`,但`3.10.11`同样可用。
- `开发平台 1 - Windows 10 x64 22H2` - `开发平台 1 - Windows 10 x64 22H2`
- Python `3.8.10` / `3.10.11` - Python `3.8.10` / `3.10.11`
@ -108,7 +102,7 @@ python DR.py
[requirement-build.txt](requirement-build.txt) [requirement-build.txt](requirement-build.txt)
[requirement-dev.txt](requirement-dev.txt) [requirement-dev.txt](requirement-dev.txt)
## ##
- 开源项目 - 开源项目
- [pyglet](https://github.com/pyglet/pyglet) : GUI 和画面渲染 - [pyglet](https://github.com/pyglet/pyglet) : GUI 和画面渲染
@ -124,11 +118,11 @@ python DR.py
- [@Billchyi](https://github.com/Billchyi) : 文档矫正 - [@Billchyi](https://github.com/Billchyi) : 文档矫正
- [@MSDNicrosoft](https://github.com/MSDNicrosoft) : 优化代码 - [@MSDNicrosoft](https://github.com/MSDNicrosoft) : 优化代码
</div>
## 相关链接 ## 相关链接
## 关于分享协议 >待完善。
## 许可
#### https://creativecommons.org/licenses/by-nc-sa/4.0/ #### https://creativecommons.org/licenses/by-nc-sa/4.0/

View File

@ -3,13 +3,11 @@
[中文](../README.md) | English [中文](../README.md) | English
- [GitHub](https://github.com/shenjackyuanjie/Difficult-Rocket) - [GitHub](https://github.com/shenjackyuanjie/Difficult-Rocket)
- [gitee](https://gitee.com/shenjackyuanjie/Difficult-Rocket) - [Gitee](https://gitee.com/shenjackyuanjie/Difficult-Rocket)
- [discord](https://discord.gg/kWzw2JrG6M) - [Discord](https://discord.gg/kWzw2JrG6M)
- [kook](https://kook.top/sRPjFG) - [Kook](https://kook.top/sRPjFG)
## Notice: This repo will only publish `DR SDK` updates, `DR game` updates will be published [here](https://github.com/shenjackyuanjie/DR-game) >Note: This repo will only publish `DR SDK` updates, `DR game` updates will be published [here](https://github.com/shenjackyuanjie/DR-game).
![demo](docs/src/demo.png)
[![996.icu](https://img.shields.io/badge/996.icu-996.icu-red.svg)](https://996.icu) [![996.icu](https://img.shields.io/badge/996.icu-996.icu-red.svg)](https://996.icu)
[![semver](https://img.shields.io/badge/SemVer-2.0.0-blue.svg)](https://Semver.org/) [![semver](https://img.shields.io/badge/SemVer-2.0.0-blue.svg)](https://Semver.org/)
@ -31,23 +29,19 @@
[DR rs latest Action build](https://nightly.link/shenjackyuanjie/Difficult-Rocket/workflows/dr_rs/main) [DR rs latest Action build](https://nightly.link/shenjackyuanjie/Difficult-Rocket/workflows/dr_rs/main)
## 中文README请移步 [这里](../README.md) ## Introduction
> Difficult-rocket is a Simple Rocket liked game build with Python (in short: rocket simulator) Difficult-rocket is a Simple Rocket liked game build with Python (shorten as "rocket simulator"). It is lighter than Vanilla SR.
## Advantage [Plan feature list](src/plan_features/README.md)
> Lighter than Vanilla SR
## [Plan feature list](src/plan_features/README.md)
[YouTrack](https://difficult-rocket.youtrack.cloud/projects/8dafd498-59c0-4ce7-9900-d9292e9ed1f0) [YouTrack](https://difficult-rocket.youtrack.cloud/projects/8dafd498-59c0-4ce7-9900-d9292e9ed1f0)
## [Update logs](src/change_log/readme.md) [Update logs](src/change_log/readme.md)
## How To Run ## Run
### clone ### 1. Clone
```bash title="clone.sh" ```bash title="clone.sh"
mkdir DR mkdir DR
@ -59,7 +53,7 @@ git clone https://gitee.com/shenjackyuanjie/Difficult-Rocket.git
git clone git@github.com:shenjackyuanjie/Difficult-Rocket.git git clone git@github.com:shenjackyuanjie/Difficult-Rocket.git
``` ```
### Install requirements ### 2. Install requirements
```bash title="install.sh" ```bash title="install.sh"
python -m pip install -r requirements.txt python -m pip install -r requirements.txt
@ -69,13 +63,15 @@ python -m pip install ./lib_not_dr
python -m pip install ./pyglet python -m pip install ./pyglet
``` ```
### Run ### 3. Run
```bash title="run.sh" ```bash title="run.sh"
python DR.py python DR.py
``` ```
## Environment (been tested / developed on) ## Environment
>The developing environment used Python `3.8.10`, but `3.10.11` is also available.
- `Develop platform 1 - Windows 10 x64 22H2` - `Develop platform 1 - Windows 10 x64 22H2`
- Python `3.8.10` / `3.10.11` - Python `3.8.10` / `3.10.11`
@ -96,7 +92,7 @@ python DR.py
- `AMD R5 5600X` - `AMD R5 5600X`
- `AMD RX 550 4G` - `AMD RX 550 4G`
## Required python modules ## Required Python Modules
- `pyglet` (pre-installed V2.0.8 path:`./libs/pyglet`) - `pyglet` (pre-installed V2.0.8 path:`./libs/pyglet`)
- `xmltodict` (pre-installed V0.12.0 path:`./libs/xmltodict`) - `xmltodict` (pre-installed V0.12.0 path:`./libs/xmltodict`)
@ -106,7 +102,7 @@ python DR.py
[requirement-build.txt](requirement-build.txt) [requirement-build.txt](requirement-build.txt)
[requirement-dev.txt](requirement-dev.txt) [requirement-dev.txt](requirement-dev.txt)
## thanks to ## Credits
- Open Source Projects - Open Source Projects
- [pyglet](https://github.com/pyglet/pyglet): GUI and graphics - [pyglet](https://github.com/pyglet/pyglet): GUI and graphics
@ -122,9 +118,11 @@ python DR.py
- [@Billchyi](https://github.com/Billchyi) : Check mistake in docs - [@Billchyi](https://github.com/Billchyi) : Check mistake in docs
- [@MSDNicrosoft](https://github.com/MSDNicrosoft) : Optimize code - [@MSDNicrosoft](https://github.com/MSDNicrosoft) : Optimize code
## Other links ## Other Links
## About License >Pending to be completed.
## License
#### https://creativecommons.org/licenses/by-nc-sa/4.0/ #### https://creativecommons.org/licenses/by-nc-sa/4.0/

View File

@ -67,9 +67,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]] [[package]]
name = "crossbeam" name = "crossbeam"
version = "0.8.2" version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2801af0d36612ae591caa9568261fddce32ce6e08a7275ea334a06a4ad021a2c" checksum = "6eb9105919ca8e40d437fc9cbb8f1975d916f1bd28afe795a48aae32a2cc8920"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"crossbeam-channel", "crossbeam-channel",
@ -81,9 +81,9 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-channel" name = "crossbeam-channel"
version = "0.5.9" version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c3242926edf34aec4ac3a77108ad4854bffaa2e4ddc1824124ce59231302d5" checksum = "82a9b73a36529d9c47029b9fb3a6f0ea3cc916a261195352ba19e770fc1748b2"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"crossbeam-utils", "crossbeam-utils",
@ -102,21 +102,20 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-epoch" name = "crossbeam-epoch"
version = "0.9.16" version = "0.9.17"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d2fe95351b870527a5d09bf563ed3c97c0cffb87cf1c78a591bf48bb218d9aa" checksum = "0e3681d554572a651dda4186cd47240627c3d0114d45a95f6ad27f2f22e7548d"
dependencies = [ dependencies = [
"autocfg", "autocfg",
"cfg-if", "cfg-if",
"crossbeam-utils", "crossbeam-utils",
"memoffset",
] ]
[[package]] [[package]]
name = "crossbeam-queue" name = "crossbeam-queue"
version = "0.3.9" version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9bcf5bdbfdd6030fb4a1c497b5d5fc5921aa2f60d359a17e249c0e6df3de153" checksum = "adc6598521bb5a83d491e8c1fe51db7296019d2ca3cb93cc6c2a20369a4d78a2"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"crossbeam-utils", "crossbeam-utils",
@ -124,9 +123,9 @@ dependencies = [
[[package]] [[package]]
name = "crossbeam-utils" name = "crossbeam-utils"
version = "0.8.17" version = "0.8.18"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d96137f14f244c37f989d9fff8f95e6c18b918e71f36638f8c49112e4c78f" checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
] ]
@ -144,7 +143,7 @@ dependencies = [
[[package]] [[package]]
name = "difficult_rocket_rs" name = "difficult_rocket_rs"
version = "0.3.0" version = "0.3.1"
dependencies = [ dependencies = [
"dict_derive", "dict_derive",
"fs-err", "fs-err",
@ -381,9 +380,9 @@ checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.70" version = "1.0.71"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39278fbbf5fb4f646ce651690877f89d1c5811a3d4acb27700c1cb3cdb78fd3b" checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@ -434,7 +433,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"pyo3-macros-backend", "pyo3-macros-backend",
"quote", "quote",
"syn 2.0.41", "syn 2.0.42",
] ]
[[package]] [[package]]
@ -446,7 +445,7 @@ dependencies = [
"heck", "heck",
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.41", "syn 2.0.42",
] ]
[[package]] [[package]]
@ -548,7 +547,7 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.41", "syn 2.0.42",
] ]
[[package]] [[package]]
@ -604,9 +603,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.41" version = "2.0.42"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269" checksum = "5b7d0a2c048d661a1a59fcd7355baa232f7ed34e0ee4df2eef3c1c1c0d3852d8"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@ -718,20 +717,20 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]] [[package]]
name = "zerocopy" name = "zerocopy"
version = "0.7.31" version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c4061bedbb353041c12f413700357bec76df2c7e2ca8e4df8bac24c6bf68e3d" checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
dependencies = [ dependencies = [
"zerocopy-derive", "zerocopy-derive",
] ]
[[package]] [[package]]
name = "zerocopy-derive" name = "zerocopy-derive"
version = "0.7.31" version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3c129550b3e6de3fd0ba67ba5c81818f9805e58b8d7fee80a3a59d2c9fc601a" checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn 2.0.41", "syn 2.0.42",
] ]

View File

@ -1,6 +1,6 @@
[package] [package]
name = "difficult_rocket_rs" name = "difficult_rocket_rs"
version = "0.3.0" version = "0.3.1"
edition = "2021" edition = "2021"
license-file = '../../LICENSE' license-file = '../../LICENSE'
authors = ["shenjackyuanjie <3695888@qq.com>"] authors = ["shenjackyuanjie <3695888@qq.com>"]
@ -14,13 +14,10 @@ crate-type = ["cdylib"]
#[profile.dev.package.rapier2d-f64] #[profile.dev.package.rapier2d-f64]
#opt-level = 2 #opt-level = 2
[profile.dev]
opt-level = 0
[profile.release] [profile.release]
lto = "fat" lto = "fat"
# Abort panic info to rapidly terminate program instead of unwinding call stacks. # 舍弃恐慌信息以快速终止程序,而非展开调用栈。
# To check panic info, compile the program in dev mode. # 请以开发模式编译程序以检查恐慌信息。
panic = "abort" panic = "abort"
opt-level = 2 opt-level = 2
@ -28,9 +25,7 @@ opt-level = 2
fs-err = "2.11.0" fs-err = "2.11.0"
quick-xml = { version = "0.31.0", features = ["serialize"] } quick-xml = { version = "0.31.0", features = ["serialize"] }
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
nalgebra = "0.32.3" nalgebra = "0.32.3"
rapier2d-f64 = { version = "0.17.2", features = ["simd-stable"] } rapier2d-f64 = { version = "0.17.2", features = ["simd-stable"] }
pyo3 = { version = "0.20.0", features = ["extension-module", "macros"] } pyo3 = { version = "0.20.0", features = ["extension-module", "macros"] }
dict_derive = "0.5" dict_derive = "0.5"

View File

@ -12,7 +12,7 @@ package_path = "Difficult_Rocket_rs"
setup( setup(
name="Difficult_Rocket_rs", name="Difficult_Rocket_rs",
version="0.3.0", version="0.3.1",
author="shenjackyuanjie", author="shenjackyuanjie",
author_email="3695888@qq.com", author_email="3695888@qq.com",
rust_extensions=[ rust_extensions=[

View File

@ -1,13 +0,0 @@
/*
* -------------------------------
* Difficult Rocket
* Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
* All rights reserved
* -------------------------------
*/
pub mod dr;
pub mod math;
pub mod sr1;
pub type IdType = i64;

View File

@ -0,0 +1,3 @@
pub mod math;
pub mod rigid;
pub mod simulation;

View File

@ -1,6 +1,8 @@
use std::ops::Add;
pub const POINT_D: f64 = 1.0; pub const POINT_D: f64 = 1.0;
pub trait Rotatable { pub trait Rotate {
// 懒了,直接实现一个协议得了 // 懒了,直接实现一个协议得了
fn rotate(&self, angle: f64) -> Self; fn rotate(&self, angle: f64) -> Self;
fn rotate_radius(&self, radius: f64) -> Self; fn rotate_radius(&self, radius: f64) -> Self;
@ -9,7 +11,7 @@ pub trait Rotatable {
fn rotate_radius_mut(&mut self, radius: f64); fn rotate_radius_mut(&mut self, radius: f64);
} }
#[derive(Clone, Copy)] #[derive(Default, Clone, Copy)]
pub struct Point2D { pub struct Point2D {
pub x: f64, pub x: f64,
pub y: f64, pub y: f64,
@ -20,10 +22,6 @@ impl Point2D {
Self { x, y } Self { x, y }
} }
pub fn new_default() -> Self {
Self { x: 0.0, y: 0.0 }
}
pub fn distance(&self, other: &Point2D) -> f64 { pub fn distance(&self, other: &Point2D) -> f64 {
let dx = (other.x - self.x).powf(2.0); let dx = (other.x - self.x).powf(2.0);
let dy = (other.y - self.y).powf(2.0); let dy = (other.y - self.y).powf(2.0);
@ -34,17 +32,13 @@ impl Point2D {
self.distance(&Point2D::new(0.0, 0.0)) 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) { pub fn add_mut(&mut self, x: f64, y: f64) {
self.x += x; self.x += x;
self.y += y; self.y += y;
} }
} }
impl Rotatable for Point2D { impl Rotate for Point2D {
fn rotate_radius(&self, radius: f64) -> Self { fn rotate_radius(&self, radius: f64) -> Self {
let sin = radius.sin(); let sin = radius.sin();
let cos = radius.cos(); let cos = radius.cos();
@ -67,6 +61,17 @@ impl Rotatable 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)] #[derive(Clone, Copy)]
pub struct CircularArc { pub struct CircularArc {
// 半径 // 半径
@ -85,13 +90,14 @@ pub struct OneTimeLine {
// pub b: f64, // pub b: f64,
// y = kx + b // y = kx + b
// kx + b - y = 0 // kx + b - y = 0
pub start: Point2D,
// start point // start point
pub end: Point2D, pub start: Point2D,
// end point // end point
pub end: Point2D,
} }
impl Rotatable for OneTimeLine { impl Rotate for OneTimeLine {
fn rotate(&self, angle: f64) -> Self { fn rotate(&self, angle: f64) -> Self {
self.rotate_radius(angle.to_radians()) self.rotate_radius(angle.to_radians())
} }
@ -128,6 +134,7 @@ impl Shape {
let x = x.unwrap_or(0.0); let x = x.unwrap_or(0.0);
let y = y.unwrap_or(0.0); let y = y.unwrap_or(0.0);
let degree = degree.unwrap_or(0.0); let degree = degree.unwrap_or(0.0);
Self { Self {
pos: Point2D::new(x, y), pos: Point2D::new(x, y),
degree, degree,
@ -151,10 +158,12 @@ impl Shape {
Edge::OneTimeLine(line) => { Edge::OneTimeLine(line) => {
let start = line.start.rotate_radius(radius); let start = line.start.rotate_radius(radius);
let end = line.end.rotate_radius(radius); let end = line.end.rotate_radius(radius);
Edge::OneTimeLine(OneTimeLine::point_new(&start, &end)) Edge::OneTimeLine(OneTimeLine::point_new(&start, &end))
} }
Edge::CircularArc(arc) => { Edge::CircularArc(arc) => {
let pos = arc.pos.rotate_radius(radius); let pos = arc.pos.rotate_radius(radius);
Edge::CircularArc(CircularArc { Edge::CircularArc(CircularArc {
r: arc.r, r: arc.r,
pos, pos,
@ -165,8 +174,9 @@ impl Shape {
}) })
.collect(); .collect();
} }
Self { Self {
pos: Point2D::new_default(), pos: Default::default(),
degree: 0.0, degree: 0.0,
bounds: edges, bounds: edges,
} }

View File

@ -5,12 +5,15 @@ use rapier2d_f64::geometry::TriMeshFlags;
use rapier2d_f64::math::{Point, Real}; use rapier2d_f64::math::{Point, Real};
use rapier2d_f64::parry::transformation::vhacd::VHACDParameters; use rapier2d_f64::parry::transformation::vhacd::VHACDParameters;
#[derive(Default)]
pub enum ConnectType { pub enum ConnectType {
#[default]
Stick, Stick,
FixedPoint, FixedPoint,
RotatedPoint, RotatedPoint,
} }
#[derive(Default)]
pub struct Connect { pub struct Connect {
pub c_type: ConnectType, pub c_type: ConnectType,
pub d_pos: f64, pub d_pos: f64,
@ -110,7 +113,6 @@ pub struct TankProps {
pub fuel_volume: f64, pub fuel_volume: f64,
/// 空油罐的质量if p_type==tank /// 空油罐的质量if p_type==tank
pub mass: f64, pub mass: f64,
// Why the fuel type is an integer?
/// 燃油种类if p_type==tank /// 燃油种类if p_type==tank
pub fuel_type: i32, pub fuel_type: i32,
} }
@ -129,8 +131,8 @@ pub struct EngineProps {
// pub throttle_exponential: f64, // pub throttle_exponential: f64,
} }
// I regard this trait as the useless one at least so far. // 至少目前而言我认为这个trait没有任何用途。
// Canceling commenting this trait and deleting this two-line comment when it is truly useful. // 当它真正发挥作用是时再取消对它的注释并删除这两行注释。
// pub trait DRComponentPropAttr<'a, T> { // pub trait DRComponentPropAttr<'a, T> {
// fn name() -> &'a str; // fn name() -> &'a str;
@ -151,7 +153,7 @@ pub struct DRComponentProps<'a, T> {
pub name: &'a str, pub name: &'a str,
/// 描述 /// 描述
pub description: &'a str, pub description: &'a str,
// Should this texture be a string instead of file? // 纹理需要用字符串而非文件句柄来表示吗?
/// 贴图 /// 贴图
pub texture: &'a str, pub texture: &'a str,
/// pub r#type: SR1PartTypeEnum, /// pub r#type: SR1PartTypeEnum,

View File

@ -6,18 +6,17 @@
* ------------------------------- * -------------------------------
*/ */
mod data_type; mod dr_physics;
mod plugin_loader;
mod python; mod python;
mod simulator; mod sr1_parse;
mod sr1_data;
mod xml_reader;
use pyo3::prelude::*; use pyo3::prelude::*;
pub type IdType = i64;
#[pyfunction] #[pyfunction]
fn get_version_str() -> String { fn get_version_str() -> String {
"0.3.0".to_string() "0.3.1".to_string()
} }
#[pyfunction] #[pyfunction]
@ -31,8 +30,8 @@ fn test_call(py_obj: &PyAny) -> PyResult<bool> {
fn module_init(_py: Python<'_>, m: &PyModule) -> PyResult<()> { fn module_init(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(get_version_str, m)?)?; m.add_function(wrap_pyfunction!(get_version_str, m)?)?;
m.add_function(wrap_pyfunction!(test_call, m)?)?; m.add_function(wrap_pyfunction!(test_call, m)?)?;
m.add_function(wrap_pyfunction!(sr1_data::part_list::read_part_list_py, m)?)?; m.add_function(wrap_pyfunction!(sr1_parse::part_list::read_part_list_py, m)?)?;
m.add_function(wrap_pyfunction!(sr1_data::ship::py_raw_ship_from_file, m)?)?; m.add_function(wrap_pyfunction!(sr1_parse::ship::py_raw_ship_from_file, m)?)?;
m.add_function(wrap_pyfunction!(python::data::load_and_save_test, m)?)?; m.add_function(wrap_pyfunction!(python::data::load_and_save_test, m)?)?;
m.add_class::<python::data::PySR1Ship>()?; m.add_class::<python::data::PySR1Ship>()?;
m.add_class::<python::data::PySR1PartList>()?; m.add_class::<python::data::PySR1PartList>()?;

View File

@ -1,22 +0,0 @@
/*
* -------------------------------
* Difficult Rocket
* Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
* All rights reserved
* -------------------------------
*/
// TODO libloading
/// https://docs.rs/libloading/latest/libloading/
/// 插件加载
///
pub struct ModInfo {
pub name: String,
pub version: String,
}
pub trait ModInfoTrait {
fn info() -> ModInfo;
}

View File

@ -1,6 +1,7 @@
use pyo3::prelude::*;
use std::io::{self, Write}; use std::io::{self, Write};
use pyo3::prelude::*;
#[pyclass] #[pyclass]
#[pyo3(name = "Console_rs")] #[pyo3(name = "Console_rs")]
pub struct PyConsole { pub struct PyConsole {

View File

@ -3,13 +3,13 @@ use std::collections::HashMap;
use pyo3::exceptions::PyValueError; use pyo3::exceptions::PyValueError;
use pyo3::prelude::*; use pyo3::prelude::*;
use crate::data_type::math::{Point2D, Rotatable}; use crate::dr_physics::math::{Point2D, Rotate};
use crate::data_type::sr1::SaveStatus; use crate::sr1_parse::part_list::RawPartList;
use crate::data_type::sr1::{get_max_box, SR1PartData, SR1PartListTrait}; use crate::sr1_parse::ship::RawShip;
use crate::data_type::sr1::{SR1PartList, SR1PartType, SR1Ship}; use crate::sr1_parse::SaveStatus;
use crate::data_type::IdType; use crate::sr1_parse::{get_max_box, SR1PartData, SR1PartListTrait};
use crate::sr1_data::part_list::RawPartList; use crate::sr1_parse::{SR1PartList, SR1PartType, SR1Ship};
use crate::sr1_data::ship::RawShip; use crate::IdType;
// use serde_xml_rs::to_string; // use serde_xml_rs::to_string;
use quick_xml::se::to_string; use quick_xml::se::to_string;

View File

@ -6,12 +6,12 @@
* ------------------------------- * -------------------------------
*/ */
use crate::IdType;
use nalgebra::{Matrix2, Vector2}; use nalgebra::{Matrix2, Vector2};
use pyo3::prelude::*; use pyo3::prelude::*;
use rapier2d_f64::math::Real; use rapier2d_f64::math::Real;
use crate::data_type::IdType;
/// Id 位置 碰撞体 /// Id 位置 碰撞体
pub type BoundedShape = (IdType, Vector2<Real>, EditorShapeEnum); pub type BoundedShape = (IdType, Vector2<Real>, EditorShapeEnum);

View File

@ -1,22 +1,25 @@
use std::cell::{Cell, RefCell}; mod data_structure;
use std::collections::HashMap;
use std::fs;
use std::io::Cursor;
use std::ops::Deref;
use super::math::{Edge, Shape}; pub use self::data_structure::*;
use crate::sr1_data::part_list::Damage as RawDamage;
use crate::sr1_data::part_list::{AttachPoint, AttachPoints, Engine, Lander, Rcs, Shape as RawShape, Solar, Tank}; use crate::dr_physics::math::{Edge, Shape};
use crate::sr1_data::part_list::{RawPartList, RawPartType, SR1PartTypeEnum}; use crate::dr_physics::math::{Point2D, Rotate};
use crate::sr1_data::ship::{ 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};
use crate::sr1_parse::ship::{
Activate as RawActivate, Connection, Connections, DisconnectedPart as RawDisconnectedPart, Activate as RawActivate, Connection, Connections, DisconnectedPart as RawDisconnectedPart,
DisconnectedParts as RawDisconnectedParts, Engine as RawEngine, Part as RawPartData, Parts as RawParts, 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, Pod as RawPod, RawShip, Staging as RawStaging, Step as RawStep, Tank as RawTank,
}; };
use crate::IdType;
use crate::data_type::math::{Point2D, Rotatable}; use std::cell::{Cell, RefCell};
use crate::data_type::IdType; 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::events::{BytesEnd, BytesStart, Event};
use quick_xml::writer::Writer; use quick_xml::writer::Writer;
@ -45,11 +48,12 @@ pub enum SR1PartTypeAttr {
consumption: f64, consumption: f64,
size: f64, size: f64,
turn: f64, turn: f64,
fuel_type: i32, // 我觉得用枚举体表示燃料种类更好。
/// 0 -> 普通燃料 /// 0 -> 普通燃料
/// 1 -> Rcs /// 1 -> Rcs
/// 2 -> 电量 /// 2 -> 电量
/// 3 -> 固推 /// 3 -> 固推
fuel_type: i32,
throttle_exponential: bool, throttle_exponential: bool,
}, },
Rcs { Rcs {
@ -161,7 +165,6 @@ pub struct SR1PartList {
} }
impl SR1PartList { impl SR1PartList {
#[inline]
pub fn new(name: String, types: Vec<SR1PartType>) -> SR1PartList { pub fn new(name: String, types: Vec<SR1PartType>) -> SR1PartList {
SR1PartList { SR1PartList {
types, types,
@ -170,7 +173,6 @@ impl SR1PartList {
} }
} }
#[inline]
pub fn from_file(file_name: String) -> Option<SR1PartList> { pub fn from_file(file_name: String) -> Option<SR1PartList> {
if let Some(raw_list) = RawPartList::from_file(file_name) { if let Some(raw_list) = RawPartList::from_file(file_name) {
let sr_list = raw_list.to_sr_part_list(None); let sr_list = raw_list.to_sr_part_list(None);
@ -191,7 +193,6 @@ impl SR1PartList {
self.cache.borrow().clone().unwrap() self.cache.borrow().clone().unwrap()
} }
#[inline]
pub fn get_part_type(&self, type_name: &String) -> Option<SR1PartType> { pub fn get_part_type(&self, type_name: &String) -> Option<SR1PartType> {
let cache = self.get_cache(); let cache = self.get_cache();
cache.get(type_name).cloned() cache.get(type_name).cloned()
@ -373,12 +374,10 @@ impl SR1PartTypeData for SR1PartType {
} }
impl SR1PartDataTrait for SR1PartData { impl SR1PartDataTrait for SR1PartData {
#[inline]
fn to_sr_part_data(&self) -> SR1PartData { fn to_sr_part_data(&self) -> SR1PartData {
self.clone() self.clone()
} }
#[inline]
fn to_raw_part_data(&self) -> RawPartData { fn to_raw_part_data(&self) -> RawPartData {
let (tank, engine) = if let Some(fuel) = &self.attr.fuel { let (tank, engine) = if let Some(fuel) = &self.attr.fuel {
match self.part_type { match self.part_type {
@ -600,7 +599,6 @@ impl SR1PartDataAttr {
Some(pod.throttle), Some(pod.throttle),
Some(pod.stages.current_stage), Some(pod.stages.current_stage),
Some({ Some({
// The mother-fucking nests come out again!
let mut steps = Vec::new(); let mut steps = Vec::new();
match &pod.stages.steps { match &pod.stages.steps {
Some(step_vec) => { Some(step_vec) => {
@ -697,7 +695,6 @@ impl SR1Ship {
part.part_type = SR1PartTypeEnum::strut; part.part_type = SR1PartTypeEnum::strut;
} }
} }
// Why are you fucking nesting such this fucking loops?!
for disconnects in self.disconnected.iter_mut() { for disconnects in self.disconnected.iter_mut() {
for (parts, _) in disconnects.iter_mut() { for (parts, _) in disconnects.iter_mut() {
for part in parts.iter_mut() { for part in parts.iter_mut() {
@ -967,8 +964,18 @@ pub fn get_max_box(parts: &[SR1PartData], part_list: &SR1PartList) -> (f64, f64,
let mut p2 = Point2D::new(x2, y2); let mut p2 = Point2D::new(x2, y2);
p1.rotate_radius_mut(part.angle); p1.rotate_radius_mut(part.angle);
p2.rotate_radius_mut(part.angle); p2.rotate_radius_mut(part.angle);
let p1 = p1.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 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); let (x1, y1, x2, y2) = (p1.x, p1.y, p2.x, p2.y);
// get max box // get max box
max_box.0 = max_box.0.min(x1).min(part.x); max_box.0 = max_box.0.min(x1).min(part.x);

View File

@ -1,10 +1,10 @@
use crate::data_type::sr1::{SR1PartList, SR1PartType, SR1PartTypeAttr}; use crate::sr1_parse::{SR1PartList, SR1PartType, SR1PartTypeAttr};
use crate::data_type::sr1::{SR1PartListTrait, SR1PartTypeData}; use crate::sr1_parse::{SR1PartListTrait, SR1PartTypeData};
use fs_err as fs; use fs_err as fs;
use pyo3::prelude::*; use pyo3::prelude::*;
use serde::{Deserialize, Serialize};
use quick_xml::de::from_str; use quick_xml::de::from_str;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
pub struct RawPartList { pub struct RawPartList {
@ -138,8 +138,8 @@ pub struct Damage {
} }
impl Damage { impl Damage {
pub fn take_damage(&self) -> crate::data_type::sr1::Damage { pub fn take_damage(&self) -> crate::sr1_parse::Damage {
crate::data_type::sr1::Damage { crate::sr1_parse::Damage {
disconnect: self.disconnect, disconnect: self.disconnect,
explode: self.explode, explode: self.explode,
explosion_power: self.explosion_power.unwrap_or(100_f64), explosion_power: self.explosion_power.unwrap_or(100_f64),
@ -371,8 +371,8 @@ impl RawPartList {
} }
pub fn from_file(file_name: String) -> Option<RawPartList> { pub fn from_file(file_name: String) -> Option<RawPartList> {
let part_list_file = fs::read_to_string(file_name).unwrap(); let part_list_file = fs::read_to_string(file_name).ok()?;
let part_list: RawPartList = from_str(part_list_file.as_str()).unwrap(); let part_list: RawPartList = from_str(part_list_file.as_str()).ok()?;
Some(part_list) Some(part_list)
} }

View File

@ -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 pyo3::prelude::*;
use quick_xml::de::from_str; use quick_xml::de::from_str;
use quick_xml::se::to_string; use quick_xml::se::to_string;
// use quick_xml::Error as XmlError; // use quick_xml::Error as XmlError;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::data_type::sr1::{SR1PartData, SR1PartDataAttr, SR1Ship};
use crate::data_type::sr1::{SR1PartDataTrait, SR1ShipTrait};
use crate::data_type::IdType;
/// https://docs.rs/quick-xml/latest/quick_xml/de/index.html#basics /// https://docs.rs/quick-xml/latest/quick_xml/de/index.html#basics
/// using quick xml /// using quick xml
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
@ -175,11 +174,11 @@ impl SR1PartDataTrait for Part {
let part_type = attr.get_part_type(); let part_type = attr.get_part_type();
SR1PartData { SR1PartData {
attr, attr,
x: self.x.to_owned(), x: self.x,
y: self.y.to_owned(), y: self.y,
id: self.id.to_owned(), id: self.id,
angle: self.angle.to_owned(), angle: self.angle,
angle_v: self.angle_v.to_owned(), angle_v: self.angle_v,
flip_x: self.flip_x.unwrap_or(0_i8) != 0, flip_x: self.flip_x.unwrap_or(0_i8) != 0,
flip_y: self.flip_y.unwrap_or(0_i8) != 0, flip_y: self.flip_y.unwrap_or(0_i8) != 0,
editor_angle: self.editor_angle.unwrap_or(0_i32), editor_angle: self.editor_angle.unwrap_or(0_i32),
@ -196,7 +195,6 @@ impl SR1PartDataTrait for Part {
} }
impl SR1ShipTrait for RawShip { impl SR1ShipTrait for RawShip {
#[inline]
fn to_sr_ship(&self, name: Option<String>) -> SR1Ship { fn to_sr_ship(&self, name: Option<String>) -> SR1Ship {
let mut parts = Vec::new(); let mut parts = Vec::new();
for part in &self.parts.parts { for part in &self.parts.parts {
@ -235,14 +233,12 @@ impl SR1ShipTrait for RawShip {
} }
} }
#[inline]
fn to_raw_ship(&self) -> RawShip { fn to_raw_ship(&self) -> RawShip {
self.clone() self.clone()
} }
} }
impl RawShip { impl RawShip {
#[inline]
pub fn from_file(path: String) -> Option<RawShip> { pub fn from_file(path: String) -> Option<RawShip> {
let ship_file = fs::read_to_string(path); // for encoding error let ship_file = fs::read_to_string(path); // for encoding error
if let Err(e) = ship_file { if let Err(e) = ship_file {
@ -267,16 +263,15 @@ impl RawShip {
} }
} }
#[inline] pub fn save(&self, file_name: String) -> Result<(), quick_xml::DeError> {
pub fn save(&self, file_name: String) -> Option<()> { let part_list_file = to_string(self)?;
let part_list_file = to_string(self);
print!("{:?}", part_list_file); print!("{:?}", part_list_file);
if let Ok(part_list_file) = part_list_file { match fs::write(file_name, part_list_file) {
fs::write(file_name, part_list_file).unwrap(); Ok(()) => (),
Some(()) Err(_) => return Err(quick_xml::DeError::Custom("Failed to save file!".to_string())),
} else {
None
} }
Ok(())
} }
} }
@ -284,7 +279,7 @@ impl RawShip {
#[pyo3(name = "read_ship_test")] #[pyo3(name = "read_ship_test")]
#[pyo3(signature = (path = "./assets/builtin/dock1.xml".to_string()))] #[pyo3(signature = (path = "./assets/builtin/dock1.xml".to_string()))]
pub fn py_raw_ship_from_file(path: String) -> PyResult<bool> { 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); let raw_ship = from_str::<RawShip>(&file);
match raw_ship { match raw_ship {
Ok(ship) => { Ok(ship) => {

View File

@ -1,18 +0,0 @@
use std::io;
use fs_err as fs;
// Input the directory of the xml file.
// If file does not exsit or not the XML file, return errors or return file handle.
// I think this fuction can be improved as its implementations are not as good as what I expected.
pub fn read_xml(dir: &str) -> io::Result<fs::File> {
if dir.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(dir)
}
}
pub fn parse_xml(xml_file: fs::File) {
todo!()
}