Feature/py camera #35
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
from .lib import *
|
from .lib import *
|
||||||
|
|
||||||
from typing import TYPE_CHECKING, Dict, Tuple, Optional
|
from typing import TYPE_CHECKING, Dict, Tuple, Optional, List, Tuple
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|
||||||
@ -107,6 +107,20 @@ if TYPE_CHECKING:
|
|||||||
|
|
||||||
def get_part_type(self, name: str) -> SR1PartType_rs: ...
|
def get_part_type(self, name: str) -> SR1PartType_rs: ...
|
||||||
|
|
||||||
|
class SR1PartData_rs:
|
||||||
|
""" 用于从 rust 中读取 SR1PartData (其实好像也没啥用哈)
|
||||||
|
"""
|
||||||
|
@property
|
||||||
|
def part_type_id(self) -> str: ...
|
||||||
|
@property
|
||||||
|
def pos(self) -> Tuple[float, float]: ...
|
||||||
|
@property
|
||||||
|
def angle(self) -> float: ...
|
||||||
|
@property
|
||||||
|
def flip_x(self) -> bool: ...
|
||||||
|
@property
|
||||||
|
def flip_y(self) -> bool: ...
|
||||||
|
|
||||||
class SR1Ship_rs:
|
class SR1Ship_rs:
|
||||||
""" 用于高效且省内存的读取 SR1Ship """
|
""" 用于高效且省内存的读取 SR1Ship """
|
||||||
def __init__(self, file_path = './configs/dock1.xml', part_list = './configs/PartList.xml', ship_name = 'NewShip'): ...
|
def __init__(self, file_path = './configs/dock1.xml', part_list = './configs/PartList.xml', ship_name = 'NewShip'): ...
|
||||||
@ -122,6 +136,8 @@ if TYPE_CHECKING:
|
|||||||
def img_pos(self) -> Tuple[int, int, int, int]: ...
|
def img_pos(self) -> Tuple[int, int, int, int]: ...
|
||||||
""" -x -y +x +y 左下右上 """
|
""" -x -y +x +y 左下右上 """
|
||||||
def get_part_box(self, part_id: int) -> Optional[Tuple[Tuple[int, int], Tuple[int, int]]]: ...
|
def get_part_box(self, part_id: int) -> Optional[Tuple[Tuple[int, int], Tuple[int, int]]]: ...
|
||||||
|
def as_dict(self) -> Dict[int, List[Tuple[SR1PartType_rs, SR1PartData]]]:
|
||||||
|
"""用于返回一个包含所有已连接零件的字典"""
|
||||||
|
|
||||||
class Console_rs:
|
class Console_rs:
|
||||||
def __init__(self) -> None: ...
|
def __init__(self) -> None: ...
|
||||||
|
@ -12,7 +12,6 @@ mod python;
|
|||||||
mod render;
|
mod render;
|
||||||
mod simulator;
|
mod simulator;
|
||||||
mod sr1_data;
|
mod sr1_data;
|
||||||
mod translate;
|
|
||||||
mod types;
|
mod types;
|
||||||
|
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
@ -27,7 +26,7 @@ enum LoadState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
fn get_version_str() -> String { "0.2.11.0".to_string() }
|
fn get_version_str() -> String { "0.2.12.0".to_string() }
|
||||||
|
|
||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
fn test_call(py_obj: &PyAny) -> PyResult<bool> {
|
fn test_call(py_obj: &PyAny) -> PyResult<bool> {
|
||||||
|
@ -74,7 +74,7 @@ pub mod data {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn get_part_type(&self, name: String) -> Option<PySR1PartType> {
|
fn get_part_type(&self, name: String) -> Option<PySR1PartType> {
|
||||||
let part_type = self.data.get_part_type(name.clone());
|
let part_type = self.data.get_part_type(&name);
|
||||||
if let Some(part_type) = part_type {
|
if let Some(part_type) = part_type {
|
||||||
Some(PySR1PartType::new(part_type.clone()))
|
Some(PySR1PartType::new(part_type.clone()))
|
||||||
} else {
|
} else {
|
||||||
@ -89,6 +89,28 @@ pub mod data {
|
|||||||
pub data: SR1PartData,
|
pub data: SR1PartData,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PySR1PartData {
|
||||||
|
pub fn new(data: SR1PartData) -> Self { Self { data } }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl PySR1PartData {
|
||||||
|
#[getter]
|
||||||
|
fn get_part_type_id(&self) -> String { self.data.part_type_id.clone() }
|
||||||
|
|
||||||
|
#[getter]
|
||||||
|
fn get_pos(&self) -> (f64, f64) { (self.data.x, self.data.y) }
|
||||||
|
|
||||||
|
#[getter]
|
||||||
|
fn get_angle(&self) -> f64 { self.data.angle }
|
||||||
|
|
||||||
|
#[getter]
|
||||||
|
fn get_flip_x(&self) -> bool { self.data.flip_x }
|
||||||
|
|
||||||
|
#[getter]
|
||||||
|
fn get_flip_y(&self) -> bool { self.data.flip_y }
|
||||||
|
}
|
||||||
|
|
||||||
#[pyclass]
|
#[pyclass]
|
||||||
#[pyo3(name = "SR1Ship_rs")]
|
#[pyo3(name = "SR1Ship_rs")]
|
||||||
#[pyo3(text_signature = "(file_path = './configs/dock1.xml', part_list = './configs/PartList.xml', ship_name = 'NewShip')")]
|
#[pyo3(text_signature = "(file_path = './configs/dock1.xml', part_list = './configs/PartList.xml', ship_name = 'NewShip')")]
|
||||||
@ -101,8 +123,9 @@ pub mod data {
|
|||||||
impl PySR1Ship {
|
impl PySR1Ship {
|
||||||
#[new]
|
#[new]
|
||||||
fn new(file_path: String, part_list: String, ship_name: String) -> Self {
|
fn new(file_path: String, part_list: String, ship_name: String) -> Self {
|
||||||
let ship = SR1Ship::from_file(file_path, Some(ship_name)).unwrap();
|
let mut ship = SR1Ship::from_file(file_path, Some(ship_name)).unwrap();
|
||||||
let part_list = SR1PartList::from_file(part_list).unwrap();
|
let part_list = SR1PartList::from_file(part_list).unwrap();
|
||||||
|
ship.parse_part_list_to_part(&part_list); //
|
||||||
Self { ship, part_list }
|
Self { ship, part_list }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,14 +155,28 @@ pub mod data {
|
|||||||
#[getter]
|
#[getter]
|
||||||
fn get_touch_ground(&self) -> bool { self.ship.touch_ground.to_owned() }
|
fn get_touch_ground(&self) -> bool { self.ship.touch_ground.to_owned() }
|
||||||
|
|
||||||
fn iter_parts(&self) -> HashMap<i64, (PySR1PartType, PySR1PartData)> {
|
#[getter]
|
||||||
let mut parts = HashMap::new();
|
fn get_mass(&self) -> f64 {
|
||||||
|
let mut mass = 0_f64;
|
||||||
for part_data in self.ship.parts.iter() {
|
for part_data in self.ship.parts.iter() {
|
||||||
let part_type = self.part_list.get_part_type(part_data.part_type_id.clone()).unwrap();
|
let part_type = self.part_list.get_part_type(&part_data.part_type_id).unwrap();
|
||||||
parts.insert(
|
mass += part_type.mass
|
||||||
part_data.id,
|
}
|
||||||
(PySR1PartType::new(part_type), PySR1PartData { data: part_data.clone() }),
|
mass
|
||||||
);
|
}
|
||||||
|
|
||||||
|
fn as_dict(&self) -> HashMap<i64, Vec<(PySR1PartType, PySR1PartData)>> {
|
||||||
|
let mut parts: HashMap<i64, Vec<(PySR1PartType, PySR1PartData)>> = HashMap::new();
|
||||||
|
for part_data in self.ship.parts.iter() {
|
||||||
|
if let Some(part_type) = self.part_list.get_part_type(&part_data.part_type_id) {
|
||||||
|
let part_type = PySR1PartType::new(part_type.clone());
|
||||||
|
let py_part_data = PySR1PartData::new(part_data.clone());
|
||||||
|
if let Some(part_list) = parts.get_mut(&part_data.id) {
|
||||||
|
part_list.push((part_type, py_part_data));
|
||||||
|
} else {
|
||||||
|
parts.insert(part_data.id, vec![(part_type, py_part_data)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
parts
|
parts
|
||||||
}
|
}
|
||||||
@ -147,7 +184,7 @@ pub mod data {
|
|||||||
fn get_part_box(&self, part_id: i64) -> Option<((f64, f64), (f64, f64))> {
|
fn get_part_box(&self, part_id: i64) -> 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.clone()).unwrap();
|
let part_type = self.part_list.get_part_type(&part_data.part_type_id).unwrap();
|
||||||
// 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();
|
||||||
@ -162,11 +199,12 @@ pub mod data {
|
|||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub mod translate {
|
fn save(&self, file_path: String) -> PyResult<()> {
|
||||||
use crate::translate;
|
self.ship.save(file_path).unwrap();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod console {
|
pub mod console {
|
||||||
|
@ -64,8 +64,38 @@ pub fn simulation() -> () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(unused)]
|
pub struct Simulator {
|
||||||
|
pub rigid_body_set: RigidBodySet,
|
||||||
|
pub collider_set: ColliderSet,
|
||||||
|
pub gravity: Vector<f64>,
|
||||||
|
pub integration_parameters: IntegrationParameters,
|
||||||
|
pub physics_pipeline: PhysicsPipeline,
|
||||||
|
pub island_manager: IslandManager,
|
||||||
|
pub broad_phase: BroadPhase,
|
||||||
|
pub narrow_phase: NarrowPhase,
|
||||||
|
pub impulse_joint_set: ImpulseJointSet,
|
||||||
|
pub multibody_joint_set: MultibodyJointSet,
|
||||||
|
pub ccd_solver: CCDSolver,
|
||||||
|
pub physics_hooks: (),
|
||||||
|
pub event_handler: (),
|
||||||
|
}
|
||||||
|
|
||||||
pub mod python {
|
pub mod python {
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
use rapier2d_f64::prelude::*;
|
use rapier2d_f64::prelude::*;
|
||||||
|
|
||||||
|
#[pyclass]
|
||||||
|
pub struct PyIntegrationParameters {
|
||||||
|
pub data: IntegrationParameters,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl PyIntegrationParameters {
|
||||||
|
#[new]
|
||||||
|
fn new() -> Self {
|
||||||
|
PyIntegrationParameters {
|
||||||
|
data: IntegrationParameters::default(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -607,6 +607,17 @@ pub mod ship {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn save(&self, file_name: String) -> Option<()> {
|
||||||
|
let part_list_file = serde_xml_rs::to_string(self);
|
||||||
|
if let Ok(part_list_file) = part_list_file {
|
||||||
|
fs::write(file_name, part_list_file).unwrap();
|
||||||
|
Some(())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
|
@ -1,16 +0,0 @@
|
|||||||
/*
|
|
||||||
* -------------------------------
|
|
||||||
* Difficult Rocket
|
|
||||||
* Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
|
||||||
* All rights reserved
|
|
||||||
* -------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
type TranslateMapper = HashMap<String, HashMap<String, HashMap<String, String>>>;
|
|
||||||
|
|
||||||
pub struct Translater {
|
|
||||||
pub data: TranslateMapper,
|
|
||||||
pub language: String,
|
|
||||||
}
|
|
@ -246,9 +246,9 @@ pub mod sr1 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[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();
|
||||||
match cache.get(&type_name) {
|
match cache.get(type_name) {
|
||||||
Some(part) => Some(part.clone()),
|
Some(part) => Some(part.clone()),
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
@ -699,11 +699,10 @@ pub mod sr1 {
|
|||||||
Some(ship.to_sr_ship(ship_name))
|
Some(ship.to_sr_ship(ship_name))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_part_list_to_part(&mut self, part_list: SR1PartList) {
|
pub fn parse_part_list_to_part(&mut self, part_list: &SR1PartList) {
|
||||||
// parse parts
|
// parse parts
|
||||||
for part in self.parts.iter_mut() {
|
for part in self.parts.iter_mut() {
|
||||||
let part_type_id = part.part_type_id.clone();
|
if let Some(part_type) = part_list.get_part_type(&part.part_type_id) {
|
||||||
if let Some(part_type) = part_list.get_part_type(part_type_id) {
|
|
||||||
part.part_type = part_type.p_type;
|
part.part_type = part_type.p_type;
|
||||||
} else {
|
} else {
|
||||||
part.part_type = SR1PartTypeEnum::strut;
|
part.part_type = SR1PartTypeEnum::strut;
|
||||||
@ -712,8 +711,7 @@ pub mod sr1 {
|
|||||||
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() {
|
||||||
let part_type_id = part.part_type_id.clone();
|
if let Some(part_type) = part_list.get_part_type(&part.part_type_id) {
|
||||||
if let Some(part_type) = part_list.get_part_type(part_type_id) {
|
|
||||||
part.part_type = part_type.p_type;
|
part.part_type = part_type.p_type;
|
||||||
} else {
|
} else {
|
||||||
part.part_type = SR1PartTypeEnum::strut;
|
part.part_type = SR1PartTypeEnum::strut;
|
||||||
@ -722,6 +720,27 @@ pub mod sr1 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn part_as_hashmap(&self) -> HashMap<i64, Vec<SR1PartData>> {
|
||||||
|
// 返回一个 HashMap 用于快速查找
|
||||||
|
// 同时为了 防止出现多个相同的 PartID 造成的数据丢失
|
||||||
|
// 采用 Vec 存储
|
||||||
|
let mut result: HashMap<i64, Vec<SR1PartData>> = HashMap::new();
|
||||||
|
for part_data in self.parts.iter() {
|
||||||
|
if let Some(part_vec) = result.get_mut(&part_data.id) {
|
||||||
|
part_vec.push(part_data.clone());
|
||||||
|
} else {
|
||||||
|
result.insert(part_data.id, vec![part_data.clone()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn save(&self, file_name: String) -> Option<()> {
|
||||||
|
let raw_ship = self.to_raw_ship();
|
||||||
|
raw_ship.save(file_name);
|
||||||
|
Some(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SR1ShipTrait for SR1Ship {
|
impl SR1ShipTrait for SR1Ship {
|
||||||
@ -780,7 +799,7 @@ pub mod sr1 {
|
|||||||
pub fn get_max_box(parts: &Vec<SR1PartData>, part_list: &SR1PartList) -> (f64, f64, f64, f64) {
|
pub fn get_max_box(parts: &Vec<SR1PartData>, part_list: &SR1PartList) -> (f64, f64, f64, f64) {
|
||||||
let mut max_box = (0_f64, 0_f64, 0_f64, 0_f64);
|
let mut max_box = (0_f64, 0_f64, 0_f64, 0_f64);
|
||||||
for part in parts.iter() {
|
for part in parts.iter() {
|
||||||
let part_type = part_list.get_part_type(part.part_type_id.clone()).unwrap();
|
let part_type = part_list.get_part_type(&part.part_type_id).unwrap();
|
||||||
let ((x1, y1), (x2, y2)) = part_type.get_box();
|
let ((x1, y1), (x2, y2)) = part_type.get_box();
|
||||||
// rotate
|
// rotate
|
||||||
let mut p1 = Point2D::new(x1, y1);
|
let mut p1 = Point2D::new(x1, y1);
|
||||||
|
@ -17,7 +17,7 @@ from Difficult_Rocket.api.mod import ModInfo
|
|||||||
from Difficult_Rocket.client import ClientWindow
|
from Difficult_Rocket.client import ClientWindow
|
||||||
from Difficult_Rocket.api.types import Options, Version
|
from Difficult_Rocket.api.types import Options, Version
|
||||||
|
|
||||||
DR_rust_version = Version("0.2.11.0") # DR_mod 的 Rust 编写部分的兼容版本
|
DR_rust_version = Version("0.2.12.0") # DR_mod 的 Rust 编写部分的兼容版本
|
||||||
|
|
||||||
logger = logging.getLogger('client.dr_game')
|
logger = logging.getLogger('client.dr_game')
|
||||||
|
|
||||||
|
@ -8,6 +8,5 @@ xml.load_done = "XML 文件加载完成"
|
|||||||
xml.load_time = "XML 文件加载消耗时间: {} 秒"
|
xml.load_time = "XML 文件加载消耗时间: {} 秒"
|
||||||
ship.load = "正在加载飞船: {}"
|
ship.load = "正在加载飞船: {}"
|
||||||
ship.load_time = "飞船加载消耗时间: {} 秒"
|
ship.load_time = "飞船加载消耗时间: {} 秒"
|
||||||
#ship.info = "飞船信息:\n- 部件数量: {}\n- 部件重量: {}\n- 文件大小: {}"
|
|
||||||
ship.info = "飞船信息:\n- 部件数量: {}\n- 部件重量: {}"
|
ship.info = "飞船信息:\n- 部件数量: {}\n- 部件重量: {}"
|
||||||
ship.render.done = "飞船渲染完成"
|
ship.render.done = "飞船渲染完成"
|
||||||
|
@ -430,6 +430,14 @@ class SR1ShipRender(BaseScreen):
|
|||||||
img.paste(pil_image, (int(self.part_data[part].x * 60 + img_center[0]), int(-self.part_data[part].y * 60 + img_center[1])), pil_image)
|
img.paste(pil_image, (int(self.part_data[part].x * 60 + img_center[0]), int(-self.part_data[part].y * 60 + img_center[1])), pil_image)
|
||||||
img.save(f'test{time.time()}.png', 'PNG')
|
img.save(f'test{time.time()}.png', 'PNG')
|
||||||
|
|
||||||
|
elif command.find('test'):
|
||||||
|
if command.find('save'):
|
||||||
|
if not self.rendered:
|
||||||
|
return
|
||||||
|
if not DR_mod_runtime.use_DR_rust:
|
||||||
|
return
|
||||||
|
self.rust_ship.save('./test-save.xml')
|
||||||
|
|
||||||
def on_mouse_drag(self, x: int, y: int, dx: int, dy: int, buttons: int, modifiers: int, window: "ClientWindow"):
|
def on_mouse_drag(self, x: int, y: int, dx: int, dy: int, buttons: int, modifiers: int, window: "ClientWindow"):
|
||||||
if not self.focus:
|
if not self.focus:
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user