348 lines
10 KiB
Python
348 lines
10 KiB
Python
"""
|
||
刚体动力学插件主管理器
|
||
整合所有物理功能模块,提供统一的接口
|
||
"""
|
||
|
||
from panda3d.core import Vec3, Point3
|
||
from .core.physics_world import PhysicsWorld
|
||
from .core.rigid_body import RigidBody
|
||
from .core.material import PhysicsMaterial, MATERIALS
|
||
from .constraints.constraint_manager import ConstraintManager
|
||
from .vehicles.vehicle_system import VehicleSystem
|
||
from .particles.particle_system import ParticleSystem
|
||
from .debug.debug_tools import PhysicsDebug, PhysicsProfiler
|
||
from .utils.physics_utils import PhysicsUtils, PhysicsConfigManager, PhysicsCollisionGroups
|
||
|
||
|
||
class RigidBodyPhysicsPlugin:
|
||
"""
|
||
刚体动力学插件主管理器
|
||
提供统一的物理系统接口
|
||
"""
|
||
|
||
def __init__(self, world_node=None, config_file=None):
|
||
"""
|
||
初始化物理插件
|
||
|
||
Args:
|
||
world_node: Panda3D世界节点(用于调试可视化)
|
||
config_file (str): 配置文件路径
|
||
"""
|
||
# 创建物理世界
|
||
self.physics_world = PhysicsWorld()
|
||
|
||
# 创建约束管理器
|
||
self.constraint_manager = ConstraintManager()
|
||
|
||
# 配置管理器
|
||
self.config_manager = PhysicsConfigManager(config_file)
|
||
|
||
# 调试工具
|
||
self.debug_tools = None
|
||
self.profiler = None
|
||
if world_node:
|
||
self.debug_tools = PhysicsDebug(self.physics_world, world_node)
|
||
self.profiler = PhysicsProfiler(self.physics_world)
|
||
|
||
# 活动对象列表
|
||
self.vehicles = []
|
||
self.particle_systems = []
|
||
|
||
print("刚体动力学插件初始化完成")
|
||
|
||
def create_rigid_body(self, node_path, shape_type='box', mass=1.0,
|
||
body_type=RigidBody.DYNAMIC, material=None):
|
||
"""
|
||
创建刚体
|
||
|
||
Args:
|
||
node_path: Panda3D节点路径
|
||
shape_type (str): 碰撞形状类型
|
||
mass (float): 质量
|
||
body_type (int): 刚体类型
|
||
material (PhysicsMaterial): 物理材质
|
||
|
||
Returns:
|
||
RigidBody: 刚体对象
|
||
"""
|
||
# 创建刚体
|
||
rigid_body = RigidBody(node_path, shape_type, mass, body_type)
|
||
|
||
# 应用材质
|
||
if material:
|
||
material.apply_to_rigid_body(rigid_body)
|
||
else:
|
||
# 使用默认材质
|
||
default_material = PhysicsMaterial('default')
|
||
default_material.apply_to_rigid_body(rigid_body)
|
||
|
||
# 添加到物理世界
|
||
self.physics_world.add_rigid_body(rigid_body)
|
||
|
||
return rigid_body
|
||
|
||
def create_constraint(self, constraint_type, body_a, body_b, **kwargs):
|
||
"""
|
||
创建约束
|
||
|
||
Args:
|
||
constraint_type (str): 约束类型
|
||
body_a (RigidBody): 第一个刚体
|
||
body_b (RigidBody): 第二个刚体
|
||
**kwargs: 约束参数
|
||
|
||
Returns:
|
||
约束对象
|
||
"""
|
||
if constraint_type == ConstraintManager.CONSTRAINT_POINT2POINT:
|
||
constraint = self.constraint_manager.create_point2point_constraint(
|
||
body_a, body_b, **kwargs)
|
||
elif constraint_type == ConstraintManager.CONSTRAINT_HINGE:
|
||
constraint = self.constraint_manager.create_hinge_constraint(
|
||
body_a, body_b, **kwargs)
|
||
elif constraint_type == ConstraintManager.CONSTRAINT_SLIDER:
|
||
constraint = self.constraint_manager.create_slider_constraint(
|
||
body_a, body_b, **kwargs)
|
||
elif constraint_type == ConstraintManager.CONSTRAINT_CONETWIST:
|
||
constraint = self.constraint_manager.create_cone_twist_constraint(
|
||
body_a, body_b, **kwargs)
|
||
elif constraint_type == ConstraintManager.CONSTRAINT_6DOF:
|
||
constraint = self.constraint_manager.create_6dof_constraint(
|
||
body_a, body_b, **kwargs)
|
||
else:
|
||
raise ValueError(f"未知的约束类型: {constraint_type}")
|
||
|
||
# 添加到物理世界
|
||
self.physics_world.add_constraint(constraint)
|
||
|
||
return constraint
|
||
|
||
def create_vehicle(self, chassis_body, wheel_configurations):
|
||
"""
|
||
创建车辆
|
||
|
||
Args:
|
||
chassis_body (RigidBody): 底盘刚体
|
||
wheel_configurations (list): 车轮配置列表
|
||
|
||
Returns:
|
||
VehicleSystem: 车辆系统对象
|
||
"""
|
||
# 创建车辆系统
|
||
vehicle = VehicleSystem(self.physics_world, chassis_body)
|
||
|
||
# 添加车轮
|
||
for wheel_config in wheel_configurations:
|
||
vehicle.add_wheel(**wheel_config)
|
||
|
||
# 保存车辆引用
|
||
self.vehicles.append(vehicle)
|
||
|
||
return vehicle
|
||
|
||
def create_particle_system(self, max_particles=1000):
|
||
"""
|
||
创建粒子系统
|
||
|
||
Args:
|
||
max_particles (int): 最大粒子数
|
||
|
||
Returns:
|
||
ParticleSystem: 粒子系统对象
|
||
"""
|
||
# 创建粒子系统
|
||
particle_system = ParticleSystem(self.physics_world, max_particles)
|
||
|
||
# 保存粒子系统引用
|
||
self.particle_systems.append(particle_system)
|
||
|
||
# 添加到物理世界
|
||
self.physics_world.add_particle_system(particle_system)
|
||
|
||
return particle_system
|
||
|
||
def update(self, dt):
|
||
"""
|
||
更新物理系统
|
||
|
||
Args:
|
||
dt (float): 时间增量
|
||
"""
|
||
# 更新物理世界
|
||
self.physics_world.update(dt)
|
||
|
||
# 更新粒子系统
|
||
for particle_system in self.particle_systems:
|
||
particle_system.update(dt)
|
||
|
||
# 更新调试工具
|
||
if self.debug_tools:
|
||
self.debug_tools.update_debug_visualization()
|
||
|
||
# 更新性能分析器
|
||
if self.profiler:
|
||
self.profiler.record_frame()
|
||
|
||
def ray_test(self, from_pos, to_pos):
|
||
"""
|
||
射线检测
|
||
|
||
Args:
|
||
from_pos (Point3): 起点
|
||
to_pos (Point3): 终点
|
||
|
||
Returns:
|
||
BulletRayHit: 射线检测结果
|
||
"""
|
||
return self.physics_world.ray_test(from_pos, to_pos)
|
||
|
||
def get_performance_stats(self):
|
||
"""
|
||
获取性能统计
|
||
|
||
Returns:
|
||
dict: 性能统计信息
|
||
"""
|
||
stats = self.physics_world.get_performance_stats()
|
||
|
||
# 添加对象计数
|
||
stats['objects'] = {
|
||
'rigid_bodies': len(self.physics_world.rigid_bodies),
|
||
'constraints': len(self.physics_world.constraints),
|
||
'vehicles': len(self.vehicles),
|
||
'particle_systems': len(self.particle_systems)
|
||
}
|
||
|
||
return stats
|
||
|
||
def enable_debug_visualization(self, enabled=True):
|
||
"""
|
||
启用调试可视化
|
||
|
||
Args:
|
||
enabled (bool): 是否启用
|
||
"""
|
||
if self.debug_tools:
|
||
self.debug_tools.enable_debug(enabled)
|
||
|
||
def set_debug_options(self, **kwargs):
|
||
"""
|
||
设置调试选项
|
||
|
||
Args:
|
||
**kwargs: 调试选项
|
||
"""
|
||
if self.debug_tools:
|
||
self.debug_tools.set_debug_options(**kwargs)
|
||
|
||
def get_predefined_material(self, material_name):
|
||
"""
|
||
获取预定义材质
|
||
|
||
Args:
|
||
material_name (str): 材质名称
|
||
|
||
Returns:
|
||
PhysicsMaterial: 物理材质
|
||
"""
|
||
return MATERIALS.get(material_name)
|
||
|
||
def create_custom_material(self, name, properties):
|
||
"""
|
||
创建自定义材质
|
||
|
||
Args:
|
||
name (str): 材质名称
|
||
properties (dict): 材质属性
|
||
|
||
Returns:
|
||
PhysicsMaterial: 物理材质
|
||
"""
|
||
return PhysicsMaterial(name, properties)
|
||
|
||
def set_gravity(self, gravity):
|
||
"""
|
||
设置重力
|
||
|
||
Args:
|
||
gravity (Vec3): 重力向量
|
||
"""
|
||
self.physics_world.set_gravity(gravity)
|
||
|
||
def set_time_step(self, time_step, max_substeps=10):
|
||
"""
|
||
设置时间步长
|
||
|
||
Args:
|
||
time_step (float): 时间步长
|
||
max_substeps (int): 最大子步数
|
||
"""
|
||
self.physics_world.set_time_step(time_step, max_substeps)
|
||
|
||
def get_collision_groups(self):
|
||
"""
|
||
获取碰撞组工具
|
||
|
||
Returns:
|
||
PhysicsCollisionGroups: 碰撞组工具
|
||
"""
|
||
return PhysicsCollisionGroups
|
||
|
||
def save_config(self, config_file=None):
|
||
"""
|
||
保存配置
|
||
|
||
Args:
|
||
config_file (str): 配置文件路径
|
||
"""
|
||
if self.config_manager:
|
||
self.config_manager.save_config(config_file)
|
||
|
||
def load_config(self, config_file):
|
||
"""
|
||
加载配置
|
||
|
||
Args:
|
||
config_file (str): 配置文件路径
|
||
"""
|
||
if self.config_manager:
|
||
self.config_manager.load_config(config_file)
|
||
|
||
def clear_all(self):
|
||
"""
|
||
清除所有物理对象
|
||
"""
|
||
# 销毁所有车辆
|
||
for vehicle in self.vehicles[:]:
|
||
vehicle.destroy()
|
||
self.vehicles.clear()
|
||
|
||
# 销毁所有粒子系统
|
||
for particle_system in self.particle_systems[:]:
|
||
particle_system.destroy()
|
||
self.particle_systems.clear()
|
||
|
||
# 清除物理世界
|
||
self.physics_world.clear()
|
||
|
||
print("所有物理对象已清除")
|
||
|
||
def destroy(self):
|
||
"""
|
||
销毁物理插件
|
||
"""
|
||
# 清除所有对象
|
||
self.clear_all()
|
||
|
||
# 销毁调试工具
|
||
if self.debug_tools:
|
||
self.debug_tools.destroy()
|
||
|
||
# 销毁性能分析器
|
||
if self.profiler:
|
||
self.profiler.destroy()
|
||
|
||
# 销毁物理世界
|
||
del self.physics_world
|
||
|
||
print("刚体动力学插件已销毁") |