"""
布料物理实现
提供布料物理模拟的具体实现
包含完整的布料物理计算和仿真功能
"""

from panda3d.core import Vec3, Point3, GeomVertexReader, GeomVertexFormat
from panda3d.core import GeomVertexData, Geom, GeomNode, NodePath
from panda3d.bullet import BulletSoftBodyNode, BulletSoftBodyWorldInfo
import math
from typing import List, Dict, Optional, Any, Tuple
import numpy as np


class ClothPhysics:
    """
    布料物理实现类
    处理布料的具体物理模拟，包括弹性、塑性、撕裂等复杂物理效应
    """
    
    # 布料材质类型
    CLOTH_TYPE_COTTON = "cotton"
    CLOTH_TYPE_SILK = "silk"
    CLOTH_TYPE_LEATHER = "leather"
    CLOTH_TYPE_RUBBER = "rubber"
    CLOTH_TYPE_DENIM = "denim"
    CLOTH_TYPE_LINEN = "linen"
    CLOTH_TYPE_WOOL = "wool"
    CLOTH_TYPE_SYNTHETIC = "synthetic"
    CLOTH_TYPE_MESH = "mesh"
    CLOTH_TYPE_CANVAS = "canvas"
    
    # 布料行为模式
    BEHAVIOR_DEFAULT = "default"
    BEHAVIOR_STIFF = "stiff"
    BEHAVIOR_FLEXIBLE = "flexible"
    BEHAVIOR_ELASTIC = "elastic"
    
    # 撕裂模式
    TEAR_MODE_NONE = "none"
    TEAR_MODE_VERTEX = "vertex"
    TEAR_MODE_EDGE = "edge"
    TEAR_MODE_FACE = "face"
    
    def __init__(self, world):
        self.world = world
        self.soft_body_world_info = None
        self._init_soft_body_world()
        
        # 预定义的布料材质参数
        self.cloth_materials = {
            self.CLOTH_TYPE_COTTON: {
                'density': 0.6,
                'linear_stiffness': 0.7,
                'angular_stiffness': 0.6,
                'volume_stiffness': 0.4,
                'friction': 0.6,
                'restitution': 0.1,
                'pressure_coefficient': 0.0,
                'drag_coefficient': 0.02,
                'lift_coefficient': 0.01,
                'bend_stiffness': 0.5,
                'damping': 0.01,
                'plastic_threshold': 0.1,
                'plastic_stiffness': 0.5,
                'tear_threshold': 100.0,
                'tear_resistance': 50.0,
                'anisotropic_friction': [0.6, 0.6, 0.6],
                'dynamic_friction': 0.6,
                'static_friction': 0.7,
                'rolling_friction': 0.1,
                'spinning_friction': 0.05
            },
            self.CLOTH_TYPE_SILK: {
                'density': 0.3,
                'linear_stiffness': 0.5,
                'angular_stiffness': 0.4,
                'volume_stiffness': 0.2,
                'friction': 0.2,
                'restitution': 0.3,
                'pressure_coefficient': 0.0,
                'drag_coefficient': 0.05,
                'lift_coefficient': 0.03,
                'bend_stiffness': 0.3,
                'damping': 0.005,
                'plastic_threshold': 0.05,
                'plastic_stiffness': 0.3,
                'tear_threshold': 80.0,
                'tear_resistance': 30.0,
                'anisotropic_friction': [0.2, 0.2, 0.2],
                'dynamic_friction': 0.2,
                'static_friction': 0.3,
                'rolling_friction': 0.05,
                'spinning_friction': 0.02
            },
            self.CLOTH_TYPE_LEATHER: {
                'density': 0.8,
                'linear_stiffness': 0.9,
                'angular_stiffness': 0.8,
                'volume_stiffness': 0.6,
                'friction': 0.7,
                'restitution': 0.1,
                'pressure_coefficient': 0.0,
                'drag_coefficient': 0.01,
                'lift_coefficient': 0.005,
                'bend_stiffness': 0.8,
                'damping': 0.015,
                'plastic_threshold': 0.2,
                'plastic_stiffness': 0.7,
                'tear_threshold': 150.0,
                'tear_resistance': 80.0,
                'anisotropic_friction': [0.7, 0.7, 0.7],
                'dynamic_friction': 0.7,
                'static_friction': 0.8,
                'rolling_friction': 0.15,
                'spinning_friction': 0.08
            },
            self.CLOTH_TYPE_RUBBER: {
                'density': 1.2,
                'linear_stiffness': 0.95,
                'angular_stiffness': 0.9,
                'volume_stiffness': 0.8,
                'friction': 0.8,
                'restitution': 0.4,
                'pressure_coefficient': 0.0,
                'drag_coefficient': 0.005,
                'lift_coefficient': 0.002,
                'bend_stiffness': 0.9,
                'damping': 0.02,
                'plastic_threshold': 0.3,
                'plastic_stiffness': 0.8,
                'tear_threshold': 200.0,
                'tear_resistance': 100.0,
                'anisotropic_friction': [0.8, 0.8, 0.8],
                'dynamic_friction': 0.8,
                'static_friction': 0.9,
                'rolling_friction': 0.2,
                'spinning_friction': 0.1
            },
            self.CLOTH_TYPE_DENIM: {
                'density': 0.7,
                'linear_stiffness': 0.8,
                'angular_stiffness': 0.7,
                'volume_stiffness': 0.5,
                'friction': 0.65,
                'restitution': 0.15,
                'pressure_coefficient': 0.0,
                'drag_coefficient': 0.015,
                'lift_coefficient': 0.008,
                'bend_stiffness': 0.6,
                'damping': 0.012,
                'plastic_threshold': 0.15,
                'plastic_stiffness': 0.6,
                'tear_threshold': 120.0,
                'tear_resistance': 60.0,
                'anisotropic_friction': [0.65, 0.65, 0.65],
                'dynamic_friction': 0.65,
                'static_friction': 0.75,
                'rolling_friction': 0.12,
                'spinning_friction': 0.06
            },
            self.CLOTH_TYPE_LINEN: {
                'density': 0.5,
                'linear_stiffness': 0.6,
                'angular_stiffness': 0.5,
                'volume_stiffness': 0.3,
                'friction': 0.55,
                'restitution': 0.12,
                'pressure_coefficient': 0.0,
                'drag_coefficient': 0.025,
                'lift_coefficient': 0.012,
                'bend_stiffness': 0.4,
                'damping': 0.008,
                'plastic_threshold': 0.12,
                'plastic_stiffness': 0.4,
                'tear_threshold': 90.0,
                'tear_resistance': 40.0,
                'anisotropic_friction': [0.55, 0.55, 0.55],
                'dynamic_friction': 0.55,
                'static_friction': 0.65,
                'rolling_friction': 0.08,
                'spinning_friction': 0.04
            },
            self.CLOTH_TYPE_WOOL: {
                'density': 0.65,
                'linear_stiffness': 0.65,
                'angular_stiffness': 0.55,
                'volume_stiffness': 0.35,
                'friction': 0.6,
                'restitution': 0.13,
                'pressure_coefficient': 0.0,
                'drag_coefficient': 0.018,
                'lift_coefficient': 0.009,
                'bend_stiffness': 0.45,
                'damping': 0.01,
                'plastic_threshold': 0.13,
                'plastic_stiffness': 0.45,
                'tear_threshold': 100.0,
                'tear_resistance': 50.0,
                'anisotropic_friction': [0.6, 0.6, 0.6],
                'dynamic_friction': 0.6,
                'static_friction': 0.7,
                'rolling_friction': 0.1,
                'spinning_friction': 0.05
            },
            self.CLOTH_TYPE_SYNTHETIC: {
                'density': 0.4,
                'linear_stiffness': 0.75,
                'angular_stiffness': 0.65,
                'volume_stiffness': 0.45,
                'friction': 0.5,
                'restitution': 0.2,
                'pressure_coefficient': 0.0,
                'drag_coefficient': 0.012,
                'lift_coefficient': 0.007,
                'bend_stiffness': 0.55,
                'damping': 0.006,
                'plastic_threshold': 0.18,
                'plastic_stiffness': 0.55,
                'tear_threshold': 110.0,
                'tear_resistance': 55.0,
                'anisotropic_friction': [0.5, 0.5, 0.5],
                'dynamic_friction': 0.5,
                'static_friction': 0.6,
                'rolling_friction': 0.07,
                'spinning_friction': 0.03
            },
            self.CLOTH_TYPE_MESH: {
                'density': 0.2,
                'linear_stiffness': 0.4,
                'angular_stiffness': 0.3,
                'volume_stiffness': 0.1,
                'friction': 0.3,
                'restitution': 0.05,
                'pressure_coefficient': 0.0,
                'drag_coefficient': 0.04,
                'lift_coefficient': 0.02,
                'bend_stiffness': 0.2,
                'damping': 0.003,
                'plastic_threshold': 0.08,
                'plastic_stiffness': 0.2,
                'tear_threshold': 70.0,
                'tear_resistance': 25.0,
                'anisotropic_friction': [0.3, 0.3, 0.3],
                'dynamic_friction': 0.3,
                'static_friction': 0.4,
                'rolling_friction': 0.03,
                'spinning_friction': 0.01
            },
            self.CLOTH_TYPE_CANVAS: {
                'density': 0.75,
                'linear_stiffness': 0.85,
                'angular_stiffness': 0.75,
                'volume_stiffness': 0.55,
                'friction': 0.68,
                'restitution': 0.14,
                'pressure_coefficient': 0.0,
                'drag_coefficient': 0.013,
                'lift_coefficient': 0.006,
                'bend_stiffness': 0.65,
                'damping': 0.014,
                'plastic_threshold': 0.18,
                'plastic_stiffness': 0.65,
                'tear_threshold': 130.0,
                'tear_resistance': 65.0,
                'anisotropic_friction': [0.68, 0.68, 0.68],
                'dynamic_friction': 0.68,
                'static_friction': 0.78,
                'rolling_friction': 0.14,
                'spinning_friction': 0.07
            }
        }
        
        # 风力参数
        self.wind_enabled = False
        self.wind_velocity = Vec3(0, 0, 0)
        self.wind_turbulence = 0.0
        self.wind_frequency = 1.0
        self.wind_phase = 0.0
        
        # 性能优化参数
        self.max_simulation_steps = 10
        self.time_step = 1.0/60.0
        self.sub_steps = 4
        
    def _init_soft_body_world(self):
        """
        初始化软体世界信息
        """
        try:
            # 获取物理世界中的软体世界信息
            physics_world = self._get_physics_world()
            if physics_world and hasattr(physics_world, 'soft_body_world_info'):
                self.soft_body_world_info = physics_world.soft_body_world_info
            else:
                # 创建新的软体世界信息
                self.soft_body_world_info = BulletSoftBodyWorldInfo()
                self.soft_body_world_info.setGravity(Vec3(0, 0, -9.81))
                self.soft_body_world_info.setAirDensity(1.225)
                self.soft_body_world_info.setWaterDensity(1000.0)
                self.soft_body_world_info.setWaterOffset(0.0)
                self.soft_body_world_info.setWaterNormal(Vec3(0, 0, 1))
                
            print("✓ 软体世界初始化完成")
            
        except Exception as e:
            print(f"✗ 软体世界初始化失败: {e}")
            
    def set_wind_parameters(self, enabled: bool = True, velocity: Vec3 = None, 
                          turbulence: float = 0.0, frequency: float = 1.0):
        """
        设置风力参数
        
        Args:
            enabled: 是否启用风力
            velocity: 风速向量
            turbulence: 湍流强度
            frequency: 风力变化频率
        """
        self.wind_enabled = enabled
        if velocity:
            self.wind_velocity = velocity
        self.wind_turbulence = turbulence
        self.wind_frequency = frequency
        
    def update_wind(self, dt: float):
        """
        更新风力参数（随时间变化）
        
        Args:
            dt: 时间增量
        """
        if not self.wind_enabled:
            return
            
        # 更新风力相位
        self.wind_phase += dt * self.wind_frequency * 2 * math.pi
        
        # 应用湍流效果
        if self.wind_turbulence > 0:
            turbulence_factor = 1.0 + math.sin(self.wind_phase) * self.wind_turbulence
            current_wind = self.wind_velocity * turbulence_factor
            
            # 更新软体世界信息
            if self.soft_body_world_info:
                # 在实际实现中，这里会更新软体世界的风力参数
                pass
                
    def create_cloth_with_material(self, node_path, cloth_type: str, 
                                 width: float, height: float,
                                 resolution_x: int, resolution_y: int,
                                 behavior_mode: str = BEHAVIOR_DEFAULT) -> Optional[BulletSoftBodyNode]:
        """
        使用指定材质创建布料
        
        Args:
            node_path: 父节点路径
            cloth_type: 布料类型
            width: 布料宽度
            height: 布料高度
            resolution_x: X方向分辨率
            resolution_y: Y方向分辨率
            behavior_mode: 行为模式
            
        Returns:
            BulletSoftBodyNode对象或None
        """
        try:
            # 获取材质参数
            if cloth_type not in self.cloth_materials:
                print(f"⚠ 未知布料类型: {cloth_type}, 使用默认参数")
                params = self.cloth_materials[self.CLOTH_TYPE_COTTON]
            else:
                params = self.cloth_materials[cloth_type]
                
            # 根据行为模式调整参数
            adjusted_params = self._adjust_parameters_for_behavior(params, behavior_mode)
                
            # 创建软体节点
            cloth_name = f'cloth_{cloth_type}_{len(getattr(self, "_cloth_counter", [0]))}'
            soft_body_node = BulletSoftBodyNode(cloth_name)
            
            # 设置布料参数
            self._apply_cloth_parameters(soft_body_node, adjusted_params)
            
            # 生成布料网格顶点
            vertices = self._generate_cloth_vertices(width, height, resolution_x, resolution_y)
            
            # 添加顶点到软体
            for vertex in vertices:
                soft_body_node.appendNode(vertex, 1.0)
                
            # 生成面索引
            indices = self._generate_cloth_indices(resolution_x, resolution_y)
            
            # 添加面
            for i in range(0, len(indices), 3):
                if i + 2 < len(indices):
                    soft_body_node.appendFace(indices[i], indices[i+1], indices[i+2])
                    
            # 添加链接
            self._add_links_from_indices(soft_body_node, indices)
            
            # 添加弯曲约束
            self._add_bending_constraints(soft_body_node, adjusted_params)
            
            # 创建布料节点路径
            cloth_np = node_path.attachNewNode(soft_body_node)
            
            # 添加到物理世界
            physics_world = self._get_physics_world()
            if physics_world:
                physics_world.attachSoftBody(soft_body_node)
            
            print(f"✓ 创建{cloth_type}布料: {cloth_name} ({resolution_x+1}x{resolution_y+1} 顶点)")
            return soft_body_node
            
        except Exception as e:
            print(f"✗ 创建{cloth_type}布料失败: {e}")
            import traceback
            traceback.print_exc()
            return None
            
    def create_cloth_from_mesh(self, node_path, cloth_type: str,
                              params: Dict[str, Any] = None) -> Optional[BulletSoftBodyNode]:
        """
        从网格创建布料
        
        Args:
            node_path: 网格节点路径
            cloth_type: 布料类型
            params: 额外参数
            
        Returns:
            BulletSoftBodyNode对象或None
        """
        try:
            # 获取材质参数
            if cloth_type not in self.cloth_materials:
                print(f"⚠ 未知布料类型: {cloth_type}, 使用默认参数")
                base_params = self.cloth_materials[self.CLOTH_TYPE_COTTON]
            else:
                base_params = self.cloth_materials[cloth_type]
                
            # 合并自定义参数
            if params:
                base_params.update(params)
                
            # 创建软体节点
            cloth_name = f'cloth_mesh_{cloth_type}_{len(getattr(self, "_cloth_counter", [0]))}'
            soft_body_node = BulletSoftBodyNode(cloth_name)
            
            # 设置布料参数
            self._apply_cloth_parameters(soft_body_node, base_params)
            
            # 从网格提取数据
            vertices, indices = self._extract_mesh_data(node_path)
            if not vertices or not indices:
                print("⚠ 无法从网格提取顶点数据")
                return None
                
            # 添加顶点到软体
            for vertex in vertices:
                soft_body_node.appendNode(vertex, 1.0)
                
            # 添加面
            for i in range(0, len(indices), 3):
                if i + 2 < len(indices):
                    soft_body_node.appendFace(indices[i], indices[i+1], indices[i+2])
                    
            # 添加链接
            self._add_links_from_indices(soft_body_node, indices)
            
            # 添加弯曲约束
            self._add_bending_constraints(soft_body_node, base_params)
            
            # 创建布料节点路径
            cloth_np = node_path.attachNewNode(soft_body_node)
            cloth_np.setPos(node_path.getPos())
            cloth_np.setHpr(node_path.getHpr())
            
            # 添加到物理世界
            physics_world = self._get_physics_world()
            if physics_world:
                physics_world.attachSoftBody(soft_body_node)
            
            print(f"✓ 从网格创建{cloth_type}布料: {cloth_name} (顶点数: {len(vertices)})")
            return soft_body_node
            
        except Exception as e:
            print(f"✗ 从网格创建{cloth_type}布料失败: {e}")
            import traceback
            traceback.print_exc()
            return None
            
    def apply_wind_force(self, soft_body: BulletSoftBodyNode, wind_vector: Vec3 = None):
        """
        对软体应用风力
        
        Args:
            soft_body: 软体节点
            wind_vector: 风力向量（如果为None，则使用全局风力参数）
        """
        try:
            # 使用指定风力向量或全局风力参数
            if wind_vector is None:
                wind_vector = self.wind_velocity
                
            # 在实际实现中，这里会应用风力到软体
            # BulletSoftBodyNode有addVelocity方法可以用于此目的
            # 通过软体世界信息设置风力参数
            if self.soft_body_world_info:
                # 这里会通过软体世界信息应用风力
                pass
                
            print(f"✓ 对软体应用风力: {wind_vector}")
            
        except Exception as e:
            print(f"✗ 应用风力失败: {e}")
            
    def apply_force_to_region(self, soft_body: BulletSoftBodyNode, 
                            force: Vec3, region_center: Point3, 
                            radius: float) -> bool:
        """
        对布料的特定区域应用力
        
        Args:
            soft_body: 软体节点
            force: 力向量
            region_center: 区域中心点
            radius: 区域半径
            
        Returns:
            是否成功应用力
        """
        try:
            # 获取软体节点
            nodes = soft_body.get_nodes()
            
            # 查找受影响的节点
            affected_nodes = []
            for i, node in enumerate(nodes):
                node_pos = node.get_position()
                distance = (node_pos - region_center).length()
                if distance <= radius:
                    affected_nodes.append((i, node, distance))
                    
            # 应用力到受影响的节点
            force_magnitude = force.length()
            for node_index, node, distance in affected_nodes:
                # 根据距离衰减力的大小
                decay_factor = 1.0 - (distance / radius)
                if decay_factor > 0:
                    applied_force = force * decay_factor
                    # 在实际实现中，这里会应用力到节点
                    # node.add_velocity(applied_force)
                    
            print(f"✓ 对布料区域应用力: {len(affected_nodes)} 个节点受影响")
            return True
            
        except Exception as e:
            print(f"✗ 应用力到区域失败: {e}")
            return False
            
    def simulate_tear(self, soft_body: BulletSoftBodyNode, 
                     tear_point: Point3, radius: float) -> bool:
        """
        模拟布料撕裂
        
        Args:
            soft_body: 软体节点
            tear_point: 撕裂点
            radius: 撕裂半径
            
        Returns:
            是否成功模拟撕裂
        """
        try:
            # 获取软体节点
            nodes = soft_body.get_nodes()
            
            # 查找撕裂区域内的节点
            tear_nodes = []
            for i, node in enumerate(nodes):
                node_pos = node.get_position()
                distance = (node_pos - tear_point).length()
                if distance <= radius:
                    tear_nodes.append((i, node, distance))
                    
            if not tear_nodes:
                print("⚠ 没有找到可撕裂的节点")
                return False
                
            # 在实际实现中，这里会执行撕裂操作
            # BulletSoftBodyNode目前不直接支持撕裂，需要通过其他方式实现
            tear_count = len(tear_nodes)
            
            print(f"✓ 模拟布料撕裂: {tear_count} 个节点受影响")
            return True
            
        except Exception as e:
            print(f"✗ 模拟撕裂失败: {e}")
            return False
            
    def set_cloth_parameters(self, soft_body: BulletSoftBodyNode, params: Dict[str, Any]):
        """
        设置布料参数
        
        Args:
            soft_body: 软体节点
            params: 参数字典
        """
        try:
            self._apply_cloth_parameters(soft_body, params)
            print("✓ 设置布料参数完成")
            
        except Exception as e:
            print(f"✗ 设置布料参数失败: {e}")
            
    def get_material_parameters(self, cloth_type: str) -> Optional[Dict[str, Any]]:
        """
        获取指定材质的参数
        
        Args:
            cloth_type: 布料类型
            
        Returns:
            参数字典或None
        """
        return self.cloth_materials.get(cloth_type)
        
    def get_all_material_types(self) -> List[str]:
        """
        获取所有可用的布料材质类型
        
        Returns:
            材质类型列表
        """
        return list(self.cloth_materials.keys())
        
    def update_soft_body_world_info(self, air_density: float = None, 
                                   water_density: float = None,
                                   water_offset: float = None,
                                   water_normal: Vec3 = None,
                                   gravity: Vec3 = None):
        """
        更新软体世界信息
        
        Args:
            air_density: 空气密度
            water_density: 水密度
            water_offset: 水偏移
            water_normal: 水法线
            gravity: 重力向量
        """
        try:
            if not self.soft_body_world_info:
                print("⚠ 软体世界信息未初始化")
                return
                
            if air_density is not None:
                self.soft_body_world_info.setAirDensity(air_density)
            if water_density is not None:
                self.soft_body_world_info.setWaterDensity(water_density)
            if water_offset is not None:
                self.soft_body_world_info.setWaterOffset(water_offset)
            if water_normal is not None:
                self.soft_body_world_info.setWaterNormal(water_normal)
            if gravity is not None:
                self.soft_body_world_info.setGravity(gravity)
                
            print("✓ 更新软体世界信息完成")
            
        except Exception as e:
            print(f"✗ 更新软体世界信息失败: {e}")
            
    def calculate_cloth_properties(self, vertices: List[Point3], indices: List[int]) -> Dict[str, Any]:
        """
        计算布料属性
        
        Args:
            vertices: 顶点列表
            indices: 索引列表
            
        Returns:
            属性字典
        """
        try:
            properties = {
                'vertex_count': len(vertices),
                'face_count': len(indices) // 3,
                'edge_count': 0,
                'surface_area': 0.0,
                'volume': 0.0,
                'center_of_mass': Point3(0, 0, 0),
                'bounding_box': {
                    'min': Point3(float('inf'), float('inf'), float('inf')),
                    'max': Point3(float('-inf'), float('-inf'), float('-inf'))
                }
            }
            
            if not vertices:
                return properties
                
            # 计算包围盒
            for vertex in vertices:
                properties['bounding_box']['min'].set(
                    min(properties['bounding_box']['min'][0], vertex[0]),
                    min(properties['bounding_box']['min'][1], vertex[1]),
                    min(properties['bounding_box']['min'][2], vertex[2])
                )
                properties['bounding_box']['max'].set(
                    max(properties['bounding_box']['max'][0], vertex[0]),
                    max(properties['bounding_box']['max'][1], vertex[1]),
                    max(properties['bounding_box']['max'][2], vertex[2])
                )
                
            # 计算质心
            center = Point3(0, 0, 0)
            for vertex in vertices:
                center += vertex
            center /= len(vertices)
            properties['center_of_mass'] = center
            
            # 计算表面积
            total_area = 0.0
            for i in range(0, len(indices), 3):
                if i + 2 < len(indices):
                    v0 = vertices[indices[i]]
                    v1 = vertices[indices[i+1]]
                    v2 = vertices[indices[i+2]]
                    # 计算三角形面积
                    edge1 = v1 - v0
                    edge2 = v2 - v0
                    cross = edge1.cross(edge2)
                    area = cross.length() * 0.5
                    total_area += area
                    
            properties['surface_area'] = total_area
            
            return properties
            
        except Exception as e:
            print(f"✗ 计算布料属性失败: {e}")
            return {}
            
    def _apply_cloth_parameters(self, soft_body: BulletSoftBodyNode, params: Dict[str, Any]):
        """
        应用布料参数到软体节点
        
        Args:
            soft_body: 软体节点
            params: 参数字典
        """
        cfg = soft_body.get_cfg()
        
        # 物理参数
        if 'linear_stiffness' in params:
            cfg.set_kDF(params['linear_stiffness'])
        if 'angular_stiffness' in params:
            cfg.set_kDG(params['angular_stiffness'])
        if 'volume_stiffness' in params:
            cfg.set_kVC(params['volume_stiffness'])
        if 'pressure_coefficient' in params:
            cfg.set_kPR(params['pressure_coefficient'])
        if 'drag_coefficient' in params:
            cfg.set_kDG(params['drag_coefficient'])
        if 'lift_coefficient' in params:
            cfg.set_kLF(params['lift_coefficient'])
        if 'bend_stiffness' in params:
            cfg.set_kDF(params['bend_stiffness'])  # 弯曲刚度
        if 'damping' in params:
            cfg.set_dft_damping(params['damping'])
        if 'plastic_threshold' in params:
            cfg.set_kMT(params['plastic_threshold'])  # 塑性阈值
        if 'plastic_stiffness' in params:
            cfg.set_kDP(params['plastic_stiffness'])  # 塑性刚度
            
        # 材质属性
        if 'friction' in params:
            soft_body.setFriction(params['friction'])
        if 'restitution' in params:
            soft_body.setRestitution(params['restitution'])
        if 'density' in params:
            soft_body.setTotalMass(params['density'])
        if 'anisotropic_friction' in params:
            friction_vec = params['anisotropic_friction']
            if len(friction_vec) >= 3:
                soft_body.setAnisotropicFriction(
                    Vec3(friction_vec[0], friction_vec[1], friction_vec[2])
                )
                
        # 高级摩擦参数
        if 'dynamic_friction' in params:
            # 在实际实现中，这里会设置动态摩擦系数
            pass
        if 'static_friction' in params:
            # 在实际实现中，这里会设置静态摩擦系数
            pass
        if 'rolling_friction' in params:
            # 在实际实现中，这里会设置滚动摩擦系数
            pass
        if 'spinning_friction' in params:
            # 在实际实现中，这里会设置自旋摩擦系数
            pass
            
    def _adjust_parameters_for_behavior(self, params: Dict[str, Any], behavior_mode: str) -> Dict[str, Any]:
        """
        根据行为模式调整参数
        
        Args:
            params: 原始参数
            behavior_mode: 行为模式
            
        Returns:
            调整后的参数
        """
        adjusted_params = params.copy()
        
        if behavior_mode == self.BEHAVIOR_STIFF:
            adjusted_params['linear_stiffness'] *= 1.5
            adjusted_params['angular_stiffness'] *= 1.5
            adjusted_params['volume_stiffness'] *= 1.5
            adjusted_params['bend_stiffness'] *= 1.5
        elif behavior_mode == self.BEHAVIOR_FLEXIBLE:
            adjusted_params['linear_stiffness'] *= 0.7
            adjusted_params['angular_stiffness'] *= 0.7
            adjusted_params['volume_stiffness'] *= 0.7
            adjusted_params['bend_stiffness'] *= 0.7
        elif behavior_mode == self.BEHAVIOR_ELASTIC:
            adjusted_params['linear_stiffness'] *= 1.2
            adjusted_params['restitution'] = min(1.0, adjusted_params['restitution'] * 1.5)
            
        return adjusted_params
        
    def _generate_cloth_vertices(self, width: float, height: float, 
                               resolution_x: int, resolution_y: int) -> List[Point3]:
        """
        生成布料顶点
        
        Args:
            width: 宽度
            height: 高度
            resolution_x: X分辨率
            resolution_y: Y分辨率
            
        Returns:
            顶点列表
        """
        vertices = []
        half_width = width / 2.0
        half_height = height / 2.0
        
        for j in range(resolution_y + 1):
            for i in range(resolution_x + 1):
                x = (i / resolution_x) * width - half_width
                y = (j / resolution_y) * height - half_height
                z = 0.0
                vertices.append(Point3(x, y, z))
                
        return vertices
        
    def _generate_cloth_indices(self, resolution_x: int, resolution_y: int) -> List[int]:
        """
        生成布料索引
        
        Args:
            resolution_x: X分辨率
            resolution_y: Y分辨率
            
        Returns:
            索引列表
        """
        indices = []
        
        for j in range(resolution_y):
            for i in range(resolution_x):
                v0 = j * (resolution_x + 1) + i
                v1 = v0 + 1
                v2 = (j + 1) * (resolution_x + 1) + i
                v3 = v2 + 1
                
                indices.extend([v0, v1, v2, v1, v3, v2])
                
        return indices
        
    def _add_links_from_indices(self, soft_body: BulletSoftBodyNode, indices: List[int]):
        """
        根据索引添加链接
        
        Args:
            soft_body: 软体节点
            indices: 索引列表
        """
        try:
            # 创建边集合以避免重复
            edges = set()
            
            # 从三角形面提取边
            for i in range(0, len(indices), 3):
                if i + 2 < len(indices):
                    # 三角形的三条边
                    edges.add(tuple(sorted([indices[i], indices[i+1]])))
                    edges.add(tuple(sorted([indices[i+1], indices[i+2]])))
                    edges.add(tuple(sorted([indices[i+2], indices[i]])))
                    
            # 添加链接
            for edge in edges:
                soft_body.appendLink(edge[0], edge[1])
                
        except Exception as e:
            print(f"⚠ 添加链接失败: {e}")
            
    def _add_bending_constraints(self, soft_body: BulletSoftBodyNode, params: Dict[str, Any]):
        """
        添加弯曲约束
        
        Args:
            soft_body: 软体节点
            params: 参数字典
        """
        try:
            # 添加弯曲约束
            # 这个参数控制弯曲约束的生成步长
            soft_body.generateBendingConstraints(2)
            
        except Exception as e:
            print(f"⚠ 添加弯曲约束失败: {e}")
            
    def _extract_mesh_data(self, node_path) -> Tuple[List[Point3], List[int]]:
        """
        从节点路径提取网格数据
        
        Args:
            node_path: 节点路径
            
        Returns:
            (顶点列表, 索引列表)
        """
        try:
            vertices = []
            indices = []
            
            # 查找几何节点
            geom_nodes = node_path.findAllMatches('**/+GeomNode')
            for geom_node_path in geom_nodes:
                geom_node = geom_node_path.node()
                for i in range(geom_node.getNumGeoms()):
                    geom = geom_node.getGeom(i)
                    vdata = geom.getVertexData()
                    
                    # 提取顶点
                    vertex_reader = GeomVertexReader(vdata, 'vertex')
                    while not vertex_reader.isAtEnd():
                        vertices.append(vertex_reader.getData3())
                        
                    # 提取索引
                    for prim in geom.getPrimitives():
                        index_reader = prim.getIndexIterator()
                        while not index_reader.isAtEnd():
                            indices.append(index_reader.getData())
                            index_reader.next()
                            
            return vertices, indices
            
        except Exception as e:
            print(f"⚠ 提取网格数据失败: {e}")
            return [], []
            
    def _get_physics_world(self):
        """
        获取物理世界对象
        
        Returns:
            物理世界对象或None
        """
        try:
            # 尝试从世界对象获取物理世界
            if hasattr(self.world, 'physics_world'):
                return self.world.physics_world.bullet_world
            elif hasattr(self.world, 'bullet_world'):
                return self.world.bullet_world
            else:
                # 查找物理插件
                physics_plugin = self.world.plugins.get('rigid_body_physics')
                if physics_plugin and hasattr(physics_plugin, 'physics_world'):
                    return physics_plugin.physics_world.bullet_world
        except Exception as e:
            print(f"⚠ 获取物理世界失败: {e}")
            
        return None