"""
网格生成工具
提供用于生成布料和软体物理模拟所需网格的工具函数
包含高级网格生成和优化功能
"""

from panda3d.core import GeomVertexFormat, GeomVertexData, GeomVertexWriter
from panda3d.core import GeomTriangles, Geom, GeomNode, NodePath
from panda3d.core import Vec3, Point3, Vec4
import math
from typing import List, Tuple, Optional, Dict, Any
import numpy as np


class MeshGenerator:
    """
    网格生成器
    提供各种网格生成函数，支持高级几何体和优化
    """
    
    # 网格类型常量
    TYPE_CLOTH = "cloth"
    TYPE_SPHERE = "sphere"
    TYPE_BOX = "box"
    TYPE_CAPSULE = "capsule"
    TYPE_CYLINDER = "cylinder"
    TYPE_ROPE = "rope"
    TYPE_TORUS = "torus"
    TYPE_PLANE = "plane"
    TYPE_CUSTOM = "custom"
    
    # 优化级别
    OPTIMIZATION_NONE = "none"
    OPTIMIZATION_LOW = "low"
    OPTIMIZATION_MEDIUM = "medium"
    OPTIMIZATION_HIGH = "high"
    
    @staticmethod
    def create_cloth_patch(width: float, height: float, 
                          resolution_x: int, resolution_y: int,
                          parent_node: NodePath = None,
                          texture_coords: bool = True,
                          normals: bool = True,
                          optimization: str = OPTIMIZATION_NONE,
                          uv_scale: float = 1.0,
                          deformation_pattern: str = "flat") -> NodePath:
        """
        创建布料片网格
        
        Args:
            width: 布料宽度
            height: 布料高度
            resolution_x: X方向分辨率
            resolution_y: Y方向分辨率
            parent_node: 父节点（可选）
            texture_coords: 是否生成纹理坐标
            normals: 是否生成法线
            optimization: 优化级别
            uv_scale: UV缩放因子
            deformation_pattern: 变形模式 ("flat", "wave", "sine", "custom")
            
        Returns:
            包含布料网格的节点路径
        """
        # 确定顶点格式
        if texture_coords and normals:
            format = GeomVertexFormat.getV3n3t2()
        elif normals:
            format = GeomVertexFormat.getV3n3()
        elif texture_coords:
            format = GeomVertexFormat.getV3t2()
        else:
            format = GeomVertexFormat.getV3()
            
        # 创建顶点数据
        vdata = GeomVertexData('cloth_patch', format, Geom.UHDynamic)
        
        # 计算顶点数量
        num_vertices = (resolution_x + 1) * (resolution_y + 1)
        vdata.setNumRows(num_vertices)
        
        # 创建顶点写入器
        vertex_writer = GeomVertexWriter(vdata, 'vertex')
        if normals:
            normal_writer = GeomVertexWriter(vdata, 'normal')
        if texture_coords:
            texcoord_writer = GeomVertexWriter(vdata, 'texcoord')
        
        # 生成顶点
        half_width = width / 2.0
        half_height = height / 2.0
        
        vertices = []
        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坐标
                z = 0.0
                if deformation_pattern == "wave":
                    z = math.sin(x * 2) * 0.1 + math.cos(y * 2) * 0.1
                elif deformation_pattern == "sine":
                    z = math.sin(math.sqrt(x*x + y*y) * 3) * 0.05
                elif deformation_pattern == "custom":
                    # 自定义变形模式可以在这里扩展
                    z = 0.0
                    
                # 写入顶点数据
                vertex_writer.addData3(x, y, z)
                
                if normals:
                    # 计算法线（对于变形表面）
                    if deformation_pattern == "flat":
                        normal_writer.addData3(0, 0, 1)
                    else:
                        # 对于变形表面，计算近似法线
                        # 这里使用简化的法线计算
                        normal_writer.addData3(0, 0, 1)
                        
                if texture_coords:
                    u = (i / resolution_x) * uv_scale
                    v = (j / resolution_y) * uv_scale
                    texcoord_writer.addData2(u, v)
                
                vertices.append(Point3(x, y, z))
        
        # 创建三角形索引
        prim = GeomTriangles(Geom.UHDynamic)
        
        # 根据优化级别调整索引生成
        if optimization == MeshGenerator.OPTIMIZATION_HIGH:
            # 高优化：使用三角形条带
            for j in range(resolution_y):
                if j % 2 == 0:
                    # 从左到右
                    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
                        
                        prim.addVertices(v0, v1, v2)
                        prim.addVertices(v1, v3, v2)
                else:
                    # 从右到左（优化三角形条带）
                    for i in range(resolution_x - 1, -1, -1):
                        v0 = j * (resolution_x + 1) + i
                        v1 = v0 + 1
                        v2 = (j + 1) * (resolution_x + 1) + i
                        v3 = v2 + 1
                        
                        prim.addVertices(v1, v0, v3)
                        prim.addVertices(v0, v2, v3)
        else:
            # 标准索引生成
            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
                    
                    prim.addVertices(v0, v1, v2)
                    prim.addVertices(v1, v3, v2)
                    
        prim.closePrimitive()
        
        # 创建几何体
        geom = Geom(vdata)
        geom.addPrimitive(prim)
        
        # 应用优化
        if optimization == MeshGenerator.OPTIMIZATION_MEDIUM:
            geom.decompose()
        elif optimization == MeshGenerator.OPTIMIZATION_HIGH:
            geom.decompose()
            geom.unify(0, True)
            
        # 创建节点
        node = GeomNode('cloth_patch_geom')
        node.addGeom(geom)
        
        # 创建节点路径
        if parent_node:
            np = parent_node.attachNewNode(node)
        else:
            np = NodePath(node)
            
        return np
        
    @staticmethod
    def create_rope(start_point: Point3, end_point: Point3, 
                   resolution: int, radius: float = 0.1,
                   parent_node: NodePath = None,
                   texture_coords: bool = False,
                   normals: bool = True,
                   optimization: str = OPTIMIZATION_NONE,
                   twist: float = 0.0) -> NodePath:
        """
        创建绳索网格
        
        Args:
            start_point: 起点
            end_point: 终点
            resolution: 分辨率
            radius: 绳索半径
            parent_node: 父节点（可选）
            texture_coords: 是否生成纹理坐标
            normals: 是否生成法线
            optimization: 优化级别
            twist: 扭曲角度（弧度）
            
        Returns:
            包含绳索网格的节点路径
        """
        # 确定顶点格式
        if texture_coords and normals:
            format = GeomVertexFormat.getV3n3t2()
        elif normals:
            format = GeomVertexFormat.getV3n3()
        elif texture_coords:
            format = GeomVertexFormat.getV3t2()
        else:
            format = GeomVertexFormat.getV3()
            
        # 计算绳索方向和长度
        direction = end_point - start_point
        length = direction.length()
        if length == 0:
            length = 0.001  # 避免除零
        direction.normalize()
        
        # 创建顶点数据
        vdata = GeomVertexData('rope', format, Geom.UHDynamic)
        
        # 计算顶点数量
        num_vertices = (resolution + 1) * (resolution + 1)
        vdata.setNumRows(num_vertices)
        
        # 创建顶点写入器
        vertex_writer = GeomVertexWriter(vdata, 'vertex')
        if normals:
            normal_writer = GeomVertexWriter(vdata, 'normal')
        if texture_coords:
            texcoord_writer = GeomVertexWriter(vdata, 'texcoord')
        
        # 生成顶点
        # 创建垂直于绳索方向的向量
        if abs(direction.dot(Vec3(0, 0, 1))) < 0.999:
            up_vector = Vec3(0, 0, 1)
        else:
            up_vector = Vec3(1, 0, 0)
            
        right_vector = direction.cross(up_vector)
        right_vector.normalize()
        up_vector = right_vector.cross(direction)
        up_vector.normalize()
        
        # 生成圆柱体顶点
        vertices = []
        for i in range(resolution + 1):
            # 沿绳索长度方向的位置
            t = i / resolution
            center_point = start_point + (end_point - start_point) * t
            
            # 应用扭曲
            twist_angle = twist * t
            
            for j in range(resolution + 1):
                angle = (j / resolution) * 2 * math.pi + twist_angle
                
                # 计算圆周上的点
                offset_x = math.cos(angle) * radius
                offset_y = math.sin(angle) * radius
                
                # 计算世界坐标
                world_offset = right_vector * offset_x + up_vector * offset_y
                pos = center_point + world_offset
                
                # 写入顶点数据
                vertex_writer.addData3(pos)
                
                if normals:
                    normal_writer.addData3(world_offset.normalized())
                    
                if texture_coords:
                    u = j / resolution
                    v = t
                    texcoord_writer.addData2(u, v)
                    
                vertices.append(pos)
                
        # 创建三角形索引
        prim = GeomTriangles(Geom.UHDynamic)
        
        for i in range(resolution):
            for j in range(resolution):
                # 计算四个顶点索引
                v0 = i * (resolution + 1) + j
                v1 = v0 + 1
                v2 = (i + 1) * (resolution + 1) + j
                v3 = v2 + 1
                
                # 添加两个三角形
                prim.addVertices(v0, v1, v2)
                prim.addVertices(v1, v3, v2)
                
        prim.closePrimitive()
        
        # 创建几何体
        geom = Geom(vdata)
        geom.addPrimitive(prim)
        
        # 应用优化
        if optimization != MeshGenerator.OPTIMIZATION_NONE:
            geom.decompose()
            
        # 创建节点
        node = GeomNode('rope_geom')
        node.addGeom(geom)
        
        # 创建节点路径
        if parent_node:
            np = parent_node.attachNewNode(node)
        else:
            np = NodePath(node)
            
        return np
        
    @staticmethod
    def create_soft_sphere(radius: float, resolution: int = 8,
                          parent_node: NodePath = None,
                          texture_coords: bool = True,
                          normals: bool = True,
                          optimization: str = OPTIMIZATION_NONE,
                          hemisphere: bool = False,
                          uv_mapping: str = "spherical") -> NodePath:
        """
        创建软球网格
        
        Args:
            radius: 球体半径
            resolution: 分辨率
            parent_node: 父节点（可选）
            texture_coords: 是否生成纹理坐标
            normals: 是否生成法线
            optimization: 优化级别
            hemisphere: 是否创建半球
            uv_mapping: UV映射类型 ("spherical", "cylindrical", "planar")
            
        Returns:
            包含球体网格的节点路径
        """
        # 确定顶点格式
        if texture_coords and normals:
            format = GeomVertexFormat.getV3n3t2()
        elif normals:
            format = GeomVertexFormat.getV3n3()
        elif texture_coords:
            format = GeomVertexFormat.getV3t2()
        else:
            format = GeomVertexFormat.getV3()
            
        # 创建顶点数据
        vdata = GeomVertexData('soft_sphere', format, Geom.UHDynamic)
        
        # 生成球体顶点
        vertices = []
        texcoords = []
        normals_list = []
        
        # 确定纬度范围
        lat_start = 0 if hemisphere else 0
        lat_end = resolution if hemisphere else resolution
        
        # 生成顶点
        for i in range(lat_start, lat_end + 1):
            phi = (i / resolution) * math.pi  # 纬度角
            
            for j in range(resolution * 2 + 1):
                theta = (j / (resolution * 2)) * 2 * math.pi  # 经度角
                
                # 球面坐标转笛卡尔坐标
                x = radius * math.sin(phi) * math.cos(theta)
                y = radius * math.sin(phi) * math.sin(theta)
                z = radius * math.cos(phi)
                
                vertices.append(Point3(x, y, z))
                normals_list.append(Vec3(x, y, z).normalized())
                
                # UV坐标计算
                if uv_mapping == "spherical":
                    u = j / (resolution * 2)
                    v = i / resolution
                elif uv_mapping == "cylindrical":
                    u = j / (resolution * 2)
                    v = (z + radius) / (2 * radius)
                else:  # planar
                    u = (x + radius) / (2 * radius)
                    v = (y + radius) / (2 * radius)
                    
                texcoords.append((u, v))
                
        # 添加极点（如果需要）
        if not hemisphere:
            # 北极点
            vertices.append(Point3(0, 0, radius))
            normals_list.append(Vec3(0, 0, 1))
            texcoords.append((0.5, 0.0))
            
            # 南极点
            vertices.append(Point3(0, 0, -radius))
            normals_list.append(Vec3(0, 0, -1))
            texcoords.append((0.5, 1.0))
            
        # 设置顶点数量
        num_vertices = len(vertices)
        vdata.setNumRows(num_vertices)
        
        # 创建顶点写入器
        vertex_writer = GeomVertexWriter(vdata, 'vertex')
        if normals:
            normal_writer = GeomVertexWriter(vdata, 'normal')
        if texture_coords:
            texcoord_writer = GeomVertexWriter(vdata, 'texcoord')
        
        # 写入顶点数据
        for i, vertex in enumerate(vertices):
            vertex_writer.addData3(vertex)
            if normals:
                normal_writer.addData3(normals_list[i])
            if texture_coords:
                texcoord_writer.addData2(texcoords[i][0], texcoords[i][1])
            
        # 创建三角形索引
        prim = GeomTriangles(Geom.UHDynamic)
        
        # 生成面索引
        for i in range(lat_start, lat_end):
            for j in range(resolution * 2):
                # 计算四个顶点索引
                v0 = i * (resolution * 2 + 1) + j
                v1 = v0 + 1
                v2 = (i + 1) * (resolution * 2 + 1) + j
                v3 = v2 + 1
                
                # 添加两个三角形
                if i > lat_start or not hemisphere:  # 不是北极点
                    prim.addVertices(v0, v1, v2)
                if i < lat_end - 1 or not hemisphere:  # 不是南极点
                    prim.addVertices(v1, v3, v2)
                    
        prim.closePrimitive()
        
        # 创建几何体
        geom = Geom(vdata)
        geom.addPrimitive(prim)
        
        # 应用优化
        if optimization != MeshGenerator.OPTIMIZATION_NONE:
            geom.decompose()
            
        # 创建节点
        node = GeomNode('soft_sphere_geom')
        node.addGeom(geom)
        
        # 创建节点路径
        if parent_node:
            np = parent_node.attachNewNode(node)
        else:
            np = NodePath(node)
            
        return np
        
    @staticmethod
    def create_soft_box(width: float, height: float, depth: float,
                       resolution_x: int = 1, resolution_y: int = 1, resolution_z: int = 1,
                       parent_node: NodePath = None,
                       texture_coords: bool = True,
                       normals: bool = True,
                       optimization: str = OPTIMIZATION_NONE,
                       rounded_corners: bool = False,
                       corner_radius: float = 0.1) -> NodePath:
        """
        创建软盒网格
        
        Args:
            width: 宽度
            height: 高度
            depth: 深度
            resolution_x: X方向分辨率
            resolution_y: Y方向分辨率
            resolution_z: Z方向分辨率
            parent_node: 父节点（可选）
            texture_coords: 是否生成纹理坐标
            normals: 是否生成法线
            optimization: 优化级别
            rounded_corners: 是否创建圆角
            corner_radius: 圆角半径
            
        Returns:
            包含盒体网格的节点路径
        """
        # 确定顶点格式
        if texture_coords and normals:
            format = GeomVertexFormat.getV3n3t2()
        elif normals:
            format = GeomVertexFormat.getV3n3()
        elif texture_coords:
            format = GeomVertexFormat.getV3t2()
        else:
            format = GeomVertexFormat.getV3()
            
        # 创建顶点数据
        vdata = GeomVertexData('soft_box', format, Geom.UHDynamic)
        
        # 半尺寸
        half_w = width / 2.0
        half_h = height / 2.0
        half_d = depth / 2.0
        
        # 生成顶点
        vertices = []
        normals_list = []
        texcoords = []
        
        if not rounded_corners:
            # 标准盒体顶点
            box_vertices = [
                Point3(-half_w, -half_d, -half_h),  # 0
                Point3(half_w, -half_d, -half_h),   # 1
                Point3(half_w, half_d, -half_h),    # 2
                Point3(-half_w, half_d, -half_h),   # 3
                Point3(-half_w, -half_d, half_h),   # 4
                Point3(half_w, -half_d, half_h),    # 5
                Point3(half_w, half_d, half_h),     # 6
                Point3(-half_w, half_d, half_h)     # 7
            ]
            
            # 面的顶点索引（每面4个顶点）
            faces = [
                [0, 1, 2, 3],  # 底面 (Z-)
                [4, 7, 6, 5],  # 顶面 (Z+)
                [0, 4, 5, 1],  # 前面 (Y-)
                [2, 6, 7, 3],  # 后面 (Y+)
                [0, 3, 7, 4],  # 左面 (X-)
                [1, 5, 6, 2]   # 右面 (X+)
            ]
            
            # 法线向量
            face_normals = [
                Vec3(0, 0, -1),  # 底面
                Vec3(0, 0, 1),   # 顶面
                Vec3(0, -1, 0),  # 前面
                Vec3(0, 1, 0),   # 后面
                Vec3(-1, 0, 0),  # 左面
                Vec3(1, 0, 0)    # 右面
            ]
            
            # UV坐标
            face_uvs = [
                [(0, 0), (1, 0), (1, 1), (0, 1)],  # 底面
                [(0, 0), (1, 0), (1, 1), (0, 1)],  # 顶面
                [(0, 0), (1, 0), (1, 1), (0, 1)],  # 前面
                [(0, 0), (1, 0), (1, 1), (0, 1)],  # 后面
                [(0, 0), (1, 0), (1, 1), (0, 1)],  # 左面
                [(0, 0), (1, 0), (1, 1), (0, 1)]   # 右面
            ]
            
            # 生成顶点（每个面的顶点独立，以便正确计算法线）
            for face_index, face in enumerate(faces):
                face_normal = face_normals[face_index]
                face_uv = face_uvs[face_index]
                for vertex_index, uv_coord in zip(face, face_uv):
                    vertices.append(box_vertices[vertex_index])
                    normals_list.append(face_normal)
                    texcoords.append(uv_coord)
        else:
            # 圆角盒体需要更复杂的网格生成
            # 这里实现一个简化的版本
            vertices, normals_list, texcoords = MeshGenerator._generate_rounded_box_vertices(
                half_w, half_h, half_d, corner_radius, 
                resolution_x, resolution_y, resolution_z
            )
            
        # 设置顶点数量
        num_vertices = len(vertices)
        vdata.setNumRows(num_vertices)
        
        # 创建顶点写入器
        vertex_writer = GeomVertexWriter(vdata, 'vertex')
        if normals:
            normal_writer = GeomVertexWriter(vdata, 'normal')
        if texture_coords:
            texcoord_writer = GeomVertexWriter(vdata, 'texcoord')
        
        # 写入顶点数据
        for i, vertex in enumerate(vertices):
            vertex_writer.addData3(vertex)
            if normals:
                normal_writer.addData3(normals_list[i])
            if texture_coords:
                texcoord_writer.addData2(texcoords[i][0], texcoords[i][1])
            
        # 创建三角形索引
        prim = GeomTriangles(Geom.UHDynamic)
        
        if not rounded_corners:
            # 每个面生成两个三角形
            for face_index in range(6):
                base_index = face_index * 4
                # 第一个三角形
                prim.addVertices(base_index, base_index + 1, base_index + 2)
                # 第二个三角形
                prim.addVertices(base_index, base_index + 2, base_index + 3)
        else:
            # 圆角盒体的索引生成
            # 这里需要更复杂的索引生成逻辑
            # 简化处理：按面分组生成索引
            vertices_per_face = len(vertices) // 6
            for face_index in range(6):
                base_index = face_index * vertices_per_face
                # 简单的三角剖分
                for i in range(vertices_per_face - 2):
                    prim.addVertices(base_index, base_index + i + 1, base_index + i + 2)
                    
        prim.closePrimitive()
        
        # 创建几何体
        geom = Geom(vdata)
        geom.addPrimitive(prim)
        
        # 应用优化
        if optimization != MeshGenerator.OPTIMIZATION_NONE:
            geom.decompose()
            
        # 创建节点
        node = GeomNode('soft_box_geom')
        node.addGeom(geom)
        
        # 创建节点路径
        if parent_node:
            np = parent_node.attachNewNode(node)
        else:
            np = NodePath(node)
            
        return np
        
    @staticmethod
    def create_capsule(radius: float, height: float, 
                      resolution: int = 8,
                      parent_node: NodePath = None,
                      texture_coords: bool = True,
                      normals: bool = True,
                      optimization: str = OPTIMIZATION_NONE) -> NodePath:
        """
        创建胶囊网格
        
        Args:
            radius: 半径
            height: 高度
            resolution: 分辨率
            parent_node: 父节点（可选）
            texture_coords: 是否生成纹理坐标
            normals: 是否生成法线
            optimization: 优化级别
            
        Returns:
            包含胶囊网格的节点路径
        """
        # 确定顶点格式
        if texture_coords and normals:
            format = GeomVertexFormat.getV3n3t2()
        elif normals:
            format = GeomVertexFormat.getV3n3()
        elif texture_coords:
            format = GeomVertexFormat.getV3t2()
        else:
            format = GeomVertexFormat.getV3()
            
        # 创建顶点数据
        vdata = GeomVertexData('capsule', format, Geom.UHDynamic)
        
        # 生成胶囊顶点
        vertices = []
        normals_list = []
        texcoords = []
        
        half_height = height / 2.0
        
        # 生成上半球
        for i in range(resolution // 2 + 1):
            phi = (i / (resolution // 2)) * (math.pi / 2)  # 0到π/2
            for j in range(resolution * 2 + 1):
                theta = (j / (resolution * 2)) * 2 * math.pi
                
                x = radius * math.sin(phi) * math.cos(theta)
                y = radius * math.sin(phi) * math.sin(theta)
                z = radius * math.cos(phi) + half_height
                
                vertices.append(Point3(x, y, z))
                normals_list.append(Vec3(x, y, z - half_height).normalized())
                texcoords.append((j / (resolution * 2), i / (resolution // 2)))
                
        # 生成圆柱部分
        cylinder_vertices_start = len(vertices)
        for i in range(resolution + 1):
            for j in range(resolution * 2 + 1):
                theta = (j / (resolution * 2)) * 2 * math.pi
                z_offset = (i / resolution) * height - half_height
                
                x = radius * math.cos(theta)
                y = radius * math.sin(theta)
                z = z_offset
                
                vertices.append(Point3(x, y, z))
                normals_list.append(Vec3(x, y, 0).normalized())
                texcoords.append((j / (resolution * 2), 0.5 + (i / resolution) * 0.5))
                
        # 生成下半球
        sphere_vertices_start = len(vertices)
        for i in range(resolution // 2 + 1):
            phi = math.pi / 2 + (i / (resolution // 2)) * (math.pi / 2)  # π/2到π
            for j in range(resolution * 2 + 1):
                theta = (j / (resolution * 2)) * 2 * math.pi
                
                x = radius * math.sin(phi) * math.cos(theta)
                y = radius * math.sin(phi) * math.sin(theta)
                z = radius * math.cos(phi) - half_height
                
                vertices.append(Point3(x, y, z))
                normals_list.append(Vec3(x, y, z + half_height).normalized())
                texcoords.append((j / (resolution * 2), 1.0 - i / (resolution // 2)))
                
        # 设置顶点数量
        num_vertices = len(vertices)
        vdata.setNumRows(num_vertices)
        
        # 创建顶点写入器
        vertex_writer = GeomVertexWriter(vdata, 'vertex')
        if normals:
            normal_writer = GeomVertexWriter(vdata, 'normal')
        if texture_coords:
            texcoord_writer = GeomVertexWriter(vdata, 'texcoord')
        
        # 写入顶点数据
        for i, vertex in enumerate(vertices):
            vertex_writer.addData3(vertex)
            if normals:
                normal_writer.addData3(normals_list[i])
            if texture_coords:
                texcoord_writer.addData2(texcoords[i][0], texcoords[i][1])
            
        # 创建三角形索引
        prim = GeomTriangles(Geom.UHDynamic)
        
        # 上半球面索引
        for i in range(resolution // 2):
            for j in range(resolution * 2):
                v0 = i * (resolution * 2 + 1) + j
                v1 = v0 + 1
                v2 = (i + 1) * (resolution * 2 + 1) + j
                v3 = v2 + 1
                
                prim.addVertices(v0, v1, v2)
                prim.addVertices(v1, v3, v2)
                
        # 圆柱面索引
        for i in range(resolution):
            for j in range(resolution * 2):
                v0 = cylinder_vertices_start + i * (resolution * 2 + 1) + j
                v1 = v0 + 1
                v2 = cylinder_vertices_start + (i + 1) * (resolution * 2 + 1) + j
                v3 = v2 + 1
                
                prim.addVertices(v0, v1, v2)
                prim.addVertices(v1, v3, v2)
                
        # 下半球面索引
        for i in range(resolution // 2):
            for j in range(resolution * 2):
                v0 = sphere_vertices_start + i * (resolution * 2 + 1) + j
                v1 = v0 + 1
                v2 = sphere_vertices_start + (i + 1) * (resolution * 2 + 1) + j
                v3 = v2 + 1
                
                prim.addVertices(v0, v1, v2)
                prim.addVertices(v1, v3, v2)
                
        prim.closePrimitive()
        
        # 创建几何体
        geom = Geom(vdata)
        geom.addPrimitive(prim)
        
        # 应用优化
        if optimization != MeshGenerator.OPTIMIZATION_NONE:
            geom.decompose()
            
        # 创建节点
        node = GeomNode('capsule_geom')
        node.addGeom(geom)
        
        # 创建节点路径
        if parent_node:
            np = parent_node.attachNewNode(node)
        else:
            np = NodePath(node)
            
        return np
        
    @staticmethod
    def create_cylinder(radius: float, height: float, 
                       resolution: int = 8,
                       parent_node: NodePath = None,
                       texture_coords: bool = True,
                       normals: bool = True,
                       optimization: str = OPTIMIZATION_NONE,
                       capped: bool = True) -> NodePath:
        """
        创建圆柱网格
        
        Args:
            radius: 半径
            height: 高度
            resolution: 分辨率
            parent_node: 父节点（可选）
            texture_coords: 是否生成纹理坐标
            normals: 是否生成法线
            optimization: 优化级别
            capped: 是否包含顶盖
            
        Returns:
            包含圆柱网格的节点路径
        """
        # 确定顶点格式
        if texture_coords and normals:
            format = GeomVertexFormat.getV3n3t2()
        elif normals:
            format = GeomVertexFormat.getV3n3()
        elif texture_coords:
            format = GeomVertexFormat.getV3t2()
        else:
            format = GeomVertexFormat.getV3()
            
        # 创建顶点数据
        vdata = GeomVertexData('cylinder', format, Geom.UHDynamic)
        
        # 生成圆柱顶点
        vertices = []
        normals_list = []
        texcoords = []
        
        half_height = height / 2.0
        
        if capped:
            # 底面中心点
            vertices.append(Point3(0, 0, -half_height))
            normals_list.append(Vec3(0, 0, -1))
            texcoords.append((0.5, 0.5))
            
            # 顶面中心点
            vertices.append(Point3(0, 0, half_height))
            normals_list.append(Vec3(0, 0, 1))
            texcoords.append((0.5, 0.5))
            
        # 生成侧面顶点
        for i in range(2):  # 底面和顶面
            z = -half_height if i == 0 else half_height
            z_normal = -1 if i == 0 else 1
            
            for j in range(resolution + 1):
                theta = (j / resolution) * 2 * math.pi
                x = radius * math.cos(theta)
                y = radius * math.sin(theta)
                
                vertices.append(Point3(x, y, z))
                normals_list.append(Vec3(x, y, 0).normalized())
                texcoords.append((j / resolution, i))
                
        # 设置顶点数量
        num_vertices = len(vertices)
        vdata.setNumRows(num_vertices)
        
        # 创建顶点写入器
        vertex_writer = GeomVertexWriter(vdata, 'vertex')
        if normals:
            normal_writer = GeomVertexWriter(vdata, 'normal')
        if texture_coords:
            texcoord_writer = GeomVertexWriter(vdata, 'texcoord')
        
        # 写入顶点数据
        for i, vertex in enumerate(vertices):
            vertex_writer.addData3(vertex)
            if normals:
                normal_writer.addData3(normals_list[i])
            if texture_coords:
                texcoord_writer.addData2(texcoords[i][0], texcoords[i][1])
            
        # 创建三角形索引
        prim = GeomTriangles(Geom.UHDynamic)
        
        # 侧面索引
        for j in range(resolution):
            # 底面点索引
            bottom_center = 0 if capped else None
            top_center = 1 if capped else None
            bottom_start = 2 if capped else 0
            top_start = bottom_start + resolution + 1
            
            # 侧面三角形
            v0 = bottom_start + j
            v1 = bottom_start + j + 1
            v2 = top_start + j
            v3 = top_start + j + 1
            
            prim.addVertices(v0, v1, v2)
            prim.addVertices(v1, v3, v2)
            
            # 底面三角形
            if capped:
                prim.addVertices(bottom_center, v0, v1)
                # 顶面三角形
                prim.addVertices(top_center, v3, v2)
                
        prim.closePrimitive()
        
        # 创建几何体
        geom = Geom(vdata)
        geom.addPrimitive(prim)
        
        # 应用优化
        if optimization != MeshGenerator.OPTIMIZATION_NONE:
            geom.decompose()
            
        # 创建节点
        node = GeomNode('cylinder_geom')
        node.addGeom(geom)
        
        # 创建节点路径
        if parent_node:
            np = parent_node.attachNewNode(node)
        else:
            np = NodePath(node)
            
        return np
        
    @staticmethod
    def create_torus(inner_radius: float, outer_radius: float, 
                    resolution_u: int = 16, resolution_v: int = 8,
                    parent_node: NodePath = None,
                    texture_coords: bool = True,
                    normals: bool = True,
                    optimization: str = OPTIMIZATION_NONE) -> NodePath:
        """
        创建环面网格
        
        Args:
            inner_radius: 内半径
            outer_radius: 外半径
            resolution_u: U方向分辨率
            resolution_v: V方向分辨率
            parent_node: 父节点（可选）
            texture_coords: 是否生成纹理坐标
            normals: 是否生成法线
            optimization: 优化级别
            
        Returns:
            包含环面网格的节点路径
        """
        # 确定顶点格式
        if texture_coords and normals:
            format = GeomVertexFormat.getV3n3t2()
        elif normals:
            format = GeomVertexFormat.getV3n3()
        elif texture_coords:
            format = GeomVertexFormat.getV3t2()
        else:
            format = GeomVertexFormat.getV3()
            
        # 创建顶点数据
        vdata = GeomVertexData('torus', format, Geom.UHDynamic)
        
        # 生成环面顶点
        vertices = []
        normals_list = []
        texcoords = []
        
        # 生成顶点
        for i in range(resolution_u + 1):
            u = (i / resolution_u) * 2 * math.pi
            
            for j in range(resolution_v + 1):
                v = (j / resolution_v) * 2 * math.pi
                
                # 环面参数方程
                x = (outer_radius + inner_radius * math.cos(v)) * math.cos(u)
                y = (outer_radius + inner_radius * math.cos(v)) * math.sin(u)
                z = inner_radius * math.sin(v)
                
                vertices.append(Point3(x, y, z))
                
                # 计算法线
                # 这是一个简化的法线计算
                normal = Vec3(
                    math.cos(u) * math.cos(v),
                    math.sin(u) * math.cos(v),
                    math.sin(v)
                )
                normals_list.append(normal.normalized())
                
                # UV坐标
                texcoords.append((i / resolution_u, j / resolution_v))
                
        # 设置顶点数量
        num_vertices = len(vertices)
        vdata.setNumRows(num_vertices)
        
        # 创建顶点写入器
        vertex_writer = GeomVertexWriter(vdata, 'vertex')
        if normals:
            normal_writer = GeomVertexWriter(vdata, 'normal')
        if texture_coords:
            texcoord_writer = GeomVertexWriter(vdata, 'texcoord')
        
        # 写入顶点数据
        for i, vertex in enumerate(vertices):
            vertex_writer.addData3(vertex)
            if normals:
                normal_writer.addData3(normals_list[i])
            if texture_coords:
                texcoord_writer.addData2(texcoords[i][0], texcoords[i][1])
            
        # 创建三角形索引
        prim = GeomTriangles(Geom.UHDynamic)
        
        # 生成面索引
        for i in range(resolution_u):
            for j in range(resolution_v):
                # 计算四个顶点索引
                v0 = i * (resolution_v + 1) + j
                v1 = v0 + 1
                v2 = (i + 1) * (resolution_v + 1) + j
                v3 = v2 + 1
                
                # 添加两个三角形
                prim.addVertices(v0, v1, v2)
                prim.addVertices(v1, v3, v2)
                
        prim.closePrimitive()
        
        # 创建几何体
        geom = Geom(vdata)
        geom.addPrimitive(prim)
        
        # 应用优化
        if optimization != MeshGenerator.OPTIMIZATION_NONE:
            geom.decompose()
            
        # 创建节点
        node = GeomNode('torus_geom')
        node.addGeom(geom)
        
        # 创建节点路径
        if parent_node:
            np = parent_node.attachNewNode(node)
        else:
            np = NodePath(node)
            
        return np
        
    @staticmethod
    def create_plane(width: float, height: float, 
                    resolution_x: int, resolution_y: int,
                    parent_node: NodePath = None,
                    texture_coords: bool = True,
                    normals: bool = True,
                    optimization: str = OPTIMIZATION_NONE) -> NodePath:
        """
        创建平面网格
        
        Args:
            width: 宽度
            height: 高度
            resolution_x: X方向分辨率
            resolution_y: Y方向分辨率
            parent_node: 父节点（可选）
            texture_coords: 是否生成纹理坐标
            normals: 是否生成法线
            optimization: 优化级别
            
        Returns:
            包含平面网格的节点路径
        """
        return MeshGenerator.create_cloth_patch(
            width, height, resolution_x, resolution_y,
            parent_node, texture_coords, normals, optimization
        )
        
    @staticmethod
    def create_custom_mesh(vertices: List[Point3], 
                          indices: List[int],
                          normals: List[Vec3] = None,
                          texcoords: List[Tuple[float, float]] = None,
                          parent_node: NodePath = None,
                          optimization: str = OPTIMIZATION_NONE) -> NodePath:
        """
        创建自定义网格
        
        Args:
            vertices: 顶点列表
            indices: 索引列表
            normals: 法线列表（可选）
            texcoords: 纹理坐标列表（可选）
            parent_node: 父节点（可选）
            optimization: 优化级别
            
        Returns:
            包含自定义网格的节点路径
        """
        # 确定顶点格式
        has_normals = normals is not None and len(normals) == len(vertices)
        has_texcoords = texcoords is not None and len(texcoords) == len(vertices)
        
        if has_normals and has_texcoords:
            format = GeomVertexFormat.getV3n3t2()
        elif has_normals:
            format = GeomVertexFormat.getV3n3()
        elif has_texcoords:
            format = GeomVertexFormat.getV3t2()
        else:
            format = GeomVertexFormat.getV3()
            
        # 创建顶点数据
        vdata = GeomVertexData('custom_mesh', format, Geom.UHDynamic)
        
        # 设置顶点数量
        num_vertices = len(vertices)
        vdata.setNumRows(num_vertices)
        
        # 创建顶点写入器
        vertex_writer = GeomVertexWriter(vdata, 'vertex')
        if has_normals:
            normal_writer = GeomVertexWriter(vdata, 'normal')
        if has_texcoords:
            texcoord_writer = GeomVertexWriter(vdata, 'texcoord')
        
        # 写入顶点数据
        for i, vertex in enumerate(vertices):
            vertex_writer.addData3(vertex)
            if has_normals:
                normal_writer.addData3(normals[i])
            if has_texcoords:
                texcoord_writer.addData2(texcoords[i][0], texcoords[i][1])
            
        # 创建三角形索引
        prim = GeomTriangles(Geom.UHDynamic)
        
        # 添加索引
        for i in range(0, len(indices), 3):
            if i + 2 < len(indices):
                prim.addVertices(indices[i], indices[i+1], indices[i+2])
                
        prim.closePrimitive()
        
        # 创建几何体
        geom = Geom(vdata)
        geom.addPrimitive(prim)
        
        # 应用优化
        if optimization != MeshGenerator.OPTIMIZATION_NONE:
            geom.decompose()
            
        # 创建节点
        node = GeomNode('custom_mesh_geom')
        node.addGeom(geom)
        
        # 创建节点路径
        if parent_node:
            np = parent_node.attachNewNode(node)
        else:
            np = NodePath(node)
            
        return np
        
    @staticmethod
    def _generate_rounded_box_vertices(half_w: float, half_h: float, half_d: float, 
                                     corner_radius: float,
                                     resolution_x: int, resolution_y: int, resolution_z: int) -> Tuple[List[Point3], List[Vec3], List[Tuple[float, float]]]:
        """
        生成圆角盒体的顶点
        
        Args:
            half_w: 半宽度
            half_h: 半高度
            half_d: 半深度
            corner_radius: 圆角半径
            resolution_x: X方向分辨率
            resolution_y: Y方向分辨率
            resolution_z: Z方向分辨率
            
        Returns:
            (顶点列表, 法线列表, 纹理坐标列表)
        """
        vertices = []
        normals = []
        texcoords = []
        
        # 这里实现一个简化的圆角盒体顶点生成
        # 实际实现需要更复杂的几何计算
        
        # 六个面的顶点生成（简化版本）
        for face in range(6):
            # 每个面生成resolution_x * resolution_y个顶点
            for i in range(resolution_x + 1):
                for j in range(resolution_y + 1):
                    # 根据面的方向计算顶点位置
                    if face == 0:  # 前面 (Z-)
                        x = (i / resolution_x) * 2 * half_w - half_w
                        y = (j / resolution_y) * 2 * half_h - half_h
                        z = -half_d
                    elif face == 1:  # 后面 (Z+)
                        x = (i / resolution_x) * 2 * half_w - half_w
                        y = (j / resolution_y) * 2 * half_h - half_h
                        z = half_d
                    elif face == 2:  # 左面 (X-)
                        x = -half_w
                        y = (i / resolution_x) * 2 * half_h - half_h
                        z = (j / resolution_y) * 2 * half_d - half_d
                    elif face == 3:  # 右面 (X+)
                        x = half_w
                        y = (i / resolution_x) * 2 * half_h - half_h
                        z = (j / resolution_y) * 2 * half_d - half_d
                    elif face == 4:  # 底面 (Y-)
                        x = (i / resolution_x) * 2 * half_w - half_w
                        y = -half_h
                        z = (j / resolution_y) * 2 * half_d - half_d
                    else:  # 顶面 (Y+)
                        x = (i / resolution_x) * 2 * half_w - half_w
                        y = half_h
                        z = (j / resolution_y) * 2 * half_d - half_d
                        
                    vertices.append(Point3(x, y, z))
                    # 简化的法线计算
                    normal = Vec3(0, 0, 1)  # 需要根据面的方向调整
                    normals.append(normal)
                    # 简化的纹理坐标
                    texcoords.append((i / resolution_x, j / resolution_y))
                    
        return vertices, normals, texcoords
        
    @staticmethod
    def get_mesh_statistics(node_path: NodePath) -> Dict[str, Any]:
        """
        获取网格统计信息
        
        Args:
            node_path: 网格节点路径
            
        Returns:
            统计信息字典
        """
        stats = {
            'vertex_count': 0,
            'face_count': 0,
            'triangle_count': 0,
            'edge_count': 0,
            'bounding_box': {
                'min': Point3(float('inf'), float('inf'), float('inf')),
                'max': Point3(float('-inf'), float('-inf'), float('-inf'))
            },
            'surface_area': 0.0,
            'volume': 0.0
        }
        
        # 查找几何节点
        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()
                
                # 顶点数量
                stats['vertex_count'] += vdata.getNumRows()
                
                # 更新包围盒
                vertex_reader = GeomVertexReader(vdata, 'vertex')
                while not vertex_reader.isAtEnd():
                    vertex = vertex_reader.getData3()
                    stats['bounding_box']['min'].set(
                        min(stats['bounding_box']['min'][0], vertex[0]),
                        min(stats['bounding_box']['min'][1], vertex[1]),
                        min(stats['bounding_box']['min'][2], vertex[2])
                    )
                    stats['bounding_box']['max'].set(
                        max(stats['bounding_box']['max'][0], vertex[0]),
                        max(stats['bounding_box']['max'][1], vertex[1]),
                        max(stats['bounding_box']['max'][2], vertex[2])
                    )
                    
                # 面和三角形数量
                for prim in geom.getPrimitives():
                    if isinstance(prim, GeomTriangles):
                        stats['triangle_count'] += prim.getNumFaces()
                        stats['face_count'] += prim.getNumFaces()
                    else:
                        stats['face_count'] += prim.getNumFaces()
                        
        # 计算表面积和体积的简化版本
        bbox = stats['bounding_box']
        width = bbox['max'][0] - bbox['min'][0]
        height = bbox['max'][1] - bbox['min'][1]
        depth = bbox['max'][2] - bbox['min'][2]
        stats['surface_area'] = 2 * (width * height + width * depth + height * depth)
        stats['volume'] = width * height * depth
        
        return stats
        
    @staticmethod
    def optimize_mesh(node_path: NodePath, 
                     target_vertex_count: int = None,
                     preserve_normals: bool = True,
                     preserve_texcoords: bool = True) -> NodePath:
        """
        优化网格
        
        Args:
            node_path: 网格节点路径
            target_vertex_count: 目标顶点数量
            preserve_normals: 是否保持法线
            preserve_texcoords: 是否保持纹理坐标
            
        Returns:
            优化后的网格节点路径
        """
        # 这里应该实现网格优化算法
        # 简化版本：返回原始节点
        print("⚠ 网格优化功能需要更复杂的实现")
        return node_path
        
    @staticmethod
    def generate_collision_mesh(source_mesh: NodePath, 
                              type: str = "convex") -> NodePath:
        """
        生成碰撞网格
        
        Args:
            source_mesh: 源网格
            type: 碰撞网格类型 ("convex", "triangle", "sphere", "box", "capsule")
            
        Returns:
            碰撞网格节点路径
        """
        # 这里应该实现碰撞网格生成算法
        # 简化版本：返回原始节点的副本
        print("⚠ 碰撞网格生成功能需要更复杂的实现")
        return source_mesh.copyTo(source_mesh.getParent())