"""
Morphing和变形动画插件 - 核心模块
提供顶点变形、morphing目标、网格变形等核心功能
"""

import math
import numpy as np
from typing import Dict, List, Tuple, Optional, Any, Callable
from dataclasses import dataclass, field
from enum import Enum

from panda3d.core import *
from direct.actor.Actor import Actor
from direct.showbase.DirectObject import DirectObject

# 定义常量
MORPHING_SETTINGS = {
    'max_morph_targets': 100,
    'default_interpolation': 'linear',
    'update_rate': 60,
    'cache_size': 200
}

# 枚举定义
class MorphingMode(Enum):
    """Morphing模式枚举"""
    VERTEX_BLEND = 0      # 顶点混合
    NORMAL_BLEND = 1      # 法线混合
    TANGENT_BLEND = 2     # 切线混合
    FULL_BLEND = 3        # 完全混合

class InterpolationMode(Enum):
    """插值模式枚举"""
    LINEAR = 0            # 线性插值
    EASE_IN = 1           # 缓入
    EASE_OUT = 2          # 缓出
    EASE_IN_OUT = 3       # 缓入缓出
    SPLINE = 4            # 样条插值

class DeformationType(Enum):
    """变形类型枚举"""
    MORPH_TARGET = 0      # Morph目标
    VERTEX_ANIMATION = 1  # 顶点动画
    SKELETAL_DEFORM = 2   # 骨骼变形
    PROCEDURAL = 3        # 程序化变形

@dataclass
class MorphTarget:
    """Morph目标数据类"""
    name: str
    vertices: List[Tuple[float, float, float]]  # 顶点位置偏移
    normals: Optional[List[Tuple[float, float, float]]] = None  # 法线偏移
    tangents: Optional[List[Tuple[float, float, float]]] = None  # 切线偏移
    weights: List[float] = field(default_factory=list)  # 权重列表
    active: bool = True

@dataclass
class MorphingAnimation:
    """Morphing动画数据类"""
    name: str
    target_weights: Dict[str, float]  # 目标权重 {target_name: weight}
    duration: float  # 持续时间
    interpolation: InterpolationMode = InterpolationMode.LINEAR
    loop: bool = False
    start_time: float = 0.0
    current_time: float = 0.0
    playing: bool = False
    paused: bool = False

@dataclass
class VertexDeformation:
    """顶点变形数据类"""
    name: str
    vertex_indices: List[int]  # 顶点索引
    target_positions: List[Tuple[float, float, float]]  # 目标位置
    duration: float  # 持续时间
    start_time: float = 0.0
    current_time: float = 0.0
    active: bool = True
    interpolation: InterpolationMode = InterpolationMode.LINEAR

@dataclass
class ProceduralDeformation:
    """程序化变形数据类"""
    name: str
    deformation_function: Callable  # 变形函数
    parameters: Dict[str, Any]  # 参数
    update_rate: float = 1.0  # 更新频率
    last_update: float = 0.0
    active: bool = True

class MorphingCache:
    """Morphing缓存系统"""
    
    def __init__(self, max_size: int = 200):
        self.max_size = max_size
        self.cache: Dict[str, Any] = {}
        self.access_order: List[str] = []
        
    def get(self, key: str) -> Optional[Any]:
        """获取缓存项"""
        if key in self.cache:
            # 更新访问顺序
            if key in self.access_order:
                self.access_order.remove(key)
            self.access_order.append(key)
            return self.cache[key]
        return None
        
    def put(self, key: str, value: Any) -> None:
        """放入缓存项"""
        # 如果缓存已满，移除最久未使用的项
        if len(self.cache) >= self.max_size:
            if self.access_order:
                oldest_key = self.access_order.pop(0)
                del self.cache[oldest_key]
                
        self.cache[key] = value
        self.access_order.append(key)
        
    def invalidate(self, key: str) -> None:
        """使缓存项失效"""
        if key in self.cache:
            del self.cache[key]
        if key in self.access_order:
            self.access_order.remove(key)
            
    def clear(self) -> None:
        """清空缓存"""
        self.cache.clear()
        self.access_order.clear()

class MorphingCore(DirectObject):
    """
    Morphing核心系统
    提供完整的顶点变形、morphing目标、网格变形等功能
    """
    
    def __init__(self, world):
        """
        初始化Morphing核心系统
        :param world: 世界对象
        """
        super().__init__()
        self.world = world
        self.morph_targets: Dict[str, Dict[str, MorphTarget]] = {}  # {model_id: {target_name: MorphTarget}}
        self.morphing_animations: Dict[str, Dict[str, MorphingAnimation]] = {}  # {model_id: {anim_name: MorphingAnimation}}
        self.vertex_deformations: Dict[str, List[VertexDeformation]] = {}  # {model_id: [VertexDeformation]}
        self.procedural_deformations: Dict[str, List[ProceduralDeformation]] = {}  # {model_id: [ProceduralDeformation]}
        self.model_data: Dict[str, Dict[str, Any]] = {}  # {model_id: {原始数据}}
        self.cache = MorphingCache(MORPHING_SETTINGS['cache_size'])
        self.is_updating = False
        self.update_task = None
        self.update_rate = MORPHING_SETTINGS['update_rate']
        
        # 性能统计
        self.stats = {
            'models_processed': 0,
            'morph_targets_created': 0,
            'animations_played': 0,
            'deformations_applied': 0,
            'cache_hits': 0,
            'cache_misses': 0
        }
        
        print("Morphing核心系统初始化完成")
        
    def register_model(self, model_node: NodePath, model_id: Optional[str] = None) -> str:
        """
        注册模型以支持morphing
        :param model_node: 模型节点
        :param model_id: 模型ID，如果为None则自动生成
        :return: 模型ID
        """
        if model_id is None:
            model_id = f"model_{len(self.model_data)}"
            
        # 检查模型是否已注册
        if model_id in self.model_data:
            print(f"警告: 模型 {model_id} 已注册，将被替换")
            self.unregister_model(model_id)
            
        # 提取模型数据
        model_data = self._extract_model_data(model_node)
        if not model_data:
            print(f"错误: 无法提取模型 {model_id} 的数据")
            return ""
            
        # 存储模型数据
        self.model_data[model_id] = model_data
        self.morph_targets[model_id] = {}
        self.morphing_animations[model_id] = {}
        self.vertex_deformations[model_id] = []
        self.procedural_deformations[model_id] = []
        
        self.stats['models_processed'] += 1
        print(f"模型已注册: {model_id}")
        return model_id
        
    def unregister_model(self, model_id: str) -> bool:
        """
        注销模型
        :param model_id: 模型ID
        :return: 是否成功注销
        """
        if model_id not in self.model_data:
            print(f"错误: 模型 {model_id} 未注册")
            return False
            
        # 清理相关数据
        if model_id in self.morph_targets:
            del self.morph_targets[model_id]
        if model_id in self.morphing_animations:
            del self.morphing_animations[model_id]
        if model_id in self.vertex_deformations:
            del self.vertex_deformations[model_id]
        if model_id in self.procedural_deformations:
            del self.procedural_deformations[model_id]
        if model_id in self.model_data:
            del self.model_data[model_id]
            
        # 使相关缓存失效
        cache_keys_to_invalidate = [key for key in self.cache.cache.keys() if key.startswith(f"{model_id}_")]
        for key in cache_keys_to_invalidate:
            self.cache.invalidate(key)
            
        print(f"模型已注销: {model_id}")
        return True
        
    def _extract_model_data(self, model_node: NodePath) -> Optional[Dict[str, Any]]:
        """
        提取模型数据
        :param model_node: 模型节点
        :return: 模型数据字典
        """
        try:
            # 查找GeomNode
            geom_nodes = model_node.findAllMatches("**/+GeomNode")
            if not geom_nodes:
                return None
                
            model_data = {
                'node_path': model_node,
                'geom_nodes': [],
                'vertex_data': [],
                'original_vertices': [],
                'original_normals': [],
                'original_tangents': []
            }
            
            # 提取每个GeomNode的数据
            for geom_node in geom_nodes:
                geom_node_obj = geom_node.node()
                for i in range(geom_node_obj.getNumGeoms()):
                    geom = geom_node_obj.getGeom(i)
                    vertex_data = geom.getVertexData()
                    
                    model_data['geom_nodes'].append(geom_node)
                    model_data['vertex_data'].append(vertex_data)
                    
                    # 提取原始顶点数据
                    vertex_reader = GeomVertexReader(vertex_data, 'vertex')
                    vertices = []
                    while not vertex_reader.isAtEnd():
                        vertex = vertex_reader.getData3f()
                        vertices.append((vertex.x, vertex.y, vertex.z))
                    model_data['original_vertices'].append(vertices)
                    
                    # 提取原始法线数据（如果存在）
                    if vertex_data.hasColumn('normal'):
                        normal_reader = GeomVertexReader(vertex_data, 'normal')
                        normals = []
                        while not normal_reader.isAtEnd():
                            normal = normal_reader.getData3f()
                            normals.append((normal.x, normal.y, normal.z))
                        model_data['original_normals'].append(normals)
                        
                    # 提取原始切线数据（如果存在）
                    if vertex_data.hasColumn('tangent'):
                        tangent_reader = GeomVertexReader(vertex_data, 'tangent')
                        tangents = []
                        while not tangent_reader.isAtEnd():
                            tangent = tangent_reader.getData3f()
                            tangents.append((tangent.x, tangent.y, tangent.z))
                        model_data['original_tangents'].append(tangents)
                        
            return model_data
            
        except Exception as e:
            print(f"提取模型数据时出错: {e}")
            import traceback
            traceback.print_exc()
            return None
            
    def create_morph_target(self, model_id: str, target_name: str, 
                          vertex_offsets: List[Tuple[float, float, float]],
                          normal_offsets: Optional[List[Tuple[float, float, float]]] = None,
                          tangent_offsets: Optional[List[Tuple[float, float, float]]] = None) -> bool:
        """
        创建Morph目标
        :param model_id: 模型ID
        :param target_name: 目标名称
        :param vertex_offsets: 顶点偏移列表
        :param normal_offsets: 法线偏移列表（可选）
        :param tangent_offsets: 切线偏移列表（可选）
        :return: 是否成功创建
        """
        if model_id not in self.model_data:
            print(f"错误: 模型 {model_id} 未注册")
            return False
            
        # 检查模型是否有足够的顶点
        total_vertices = sum(len(vertices) for vertices in self.model_data[model_id]['original_vertices'])
        if len(vertex_offsets) != total_vertices:
            print(f"错误: 顶点偏移数量 ({len(vertex_offsets)}) 与模型顶点数量 ({total_vertices}) 不匹配")
            return False
            
        # 创建Morph目标
        morph_target = MorphTarget(
            name=target_name,
            vertices=vertex_offsets,
            normals=normal_offsets,
            tangents=tangent_offsets,
            weights=[0.0] * len(vertex_offsets)
        )
        
        # 存储Morph目标
        self.morph_targets[model_id][target_name] = morph_target
        self.stats['morph_targets_created'] += 1
        
        print(f"Morph目标已创建: {target_name} (模型: {model_id})")
        return True
        
    def remove_morph_target(self, model_id: str, target_name: str) -> bool:
        """
        移除Morph目标
        :param model_id: 模型ID
        :param target_name: 目标名称
        :return: 是否成功移除
        """
        if model_id not in self.morph_targets or target_name not in self.morph_targets[model_id]:
            print(f"错误: Morph目标 {target_name} 不存在于模型 {model_id} 中")
            return False
            
        del self.morph_targets[model_id][target_name]
        print(f"Morph目标已移除: {target_name} (模型: {model_id})")
        return True
        
    def set_morph_target_weight(self, model_id: str, target_name: str, weight: float) -> bool:
        """
        设置Morph目标权重
        :param model_id: 模型ID
        :param target_name: 目标名称
        :param weight: 权重值 (0.0-1.0)
        :return: 是否成功设置
        """
        if model_id not in self.morph_targets or target_name not in self.morph_targets[model_id]:
            print(f"错误: Morph目标 {target_name} 不存在于模型 {model_id} 中")
            return False
            
        # 限制权重范围
        weight = max(0.0, min(1.0, weight))
        
        # 更新权重
        morph_target = self.morph_targets[model_id][target_name]
        morph_target.weights = [weight] * len(morph_target.weights)
        
        # 应用变形
        self._apply_morph_target(model_id, target_name, weight)
        
        return True
        
    def _apply_morph_target(self, model_id: str, target_name: str, weight: float) -> None:
        """
        应用Morph目标
        :param model_id: 模型ID
        :param target_name: 目标名称
        :param weight: 权重值
        """
        if model_id not in self.morph_targets or target_name not in self.morph_targets[model_id]:
            return
            
        morph_target = self.morph_targets[model_id][target_name]
        model_data = self.model_data[model_id]
        
        # 应用到每个GeomNode
        vertex_offset_index = 0
        for i, (geom_node, vertex_data) in enumerate(zip(model_data['geom_nodes'], model_data['vertex_data'])):
            # 创建可写的顶点数据
            writable_vertex_data = vertex_data.copy()
            
            # 更新顶点位置
            vertex_writer = GeomVertexWriter(writable_vertex_data, 'vertex')
            original_vertices = model_data['original_vertices'][i]
            
            for j, original_vertex in enumerate(original_vertices):
                if vertex_offset_index + j < len(morph_target.vertices):
                    offset = morph_target.vertices[vertex_offset_index + j]
                    new_vertex = (
                        original_vertex[0] + offset[0] * weight,
                        original_vertex[1] + offset[1] * weight,
                        original_vertex[2] + offset[2] * weight
                    )
                    vertex_writer.setRow(j)
                    vertex_writer.setData3f(new_vertex[0], new_vertex[1], new_vertex[2])
                    
            # 更新法线（如果存在）
            if morph_target.normals and writable_vertex_data.hasColumn('normal'):
                normal_writer = GeomVertexWriter(writable_vertex_data, 'normal')
                original_normals = model_data['original_normals'][i] if i < len(model_data['original_normals']) else []
                
                for j, original_normal in enumerate(original_normals):
                    if vertex_offset_index + j < len(morph_target.normals):
                        offset = morph_target.normals[vertex_offset_index + j]
                        new_normal = (
                            original_normal[0] + offset[0] * weight,
                            original_normal[1] + offset[1] * weight,
                            original_normal[2] + offset[2] * weight
                        )
                        normal_writer.setRow(j)
                        normal_writer.setData3f(new_normal[0], new_normal[1], new_normal[2])
                        
            # 更新切线（如果存在）
            if morph_target.tangents and writable_vertex_data.hasColumn('tangent'):
                tangent_writer = GeomVertexWriter(writable_vertex_data, 'tangent')
                original_tangents = model_data['original_tangents'][i] if i < len(model_data['original_tangents']) else []
                
                for j, original_tangent in enumerate(original_tangents):
                    if vertex_offset_index + j < len(morph_target.tangents):
                        offset = morph_target.tangents[vertex_offset_index + j]
                        new_tangent = (
                            original_tangent[0] + offset[0] * weight,
                            original_tangent[1] + offset[1] * weight,
                            original_tangent[2] + offset[2] * weight
                        )
                        tangent_writer.setRow(j)
                        tangent_writer.setData3f(new_tangent[0], new_tangent[1], new_tangent[2])
                        
            # 更新GeomNode的顶点数据
            geom_node.node().modifyGeom(0).setVertexData(writable_vertex_data)
            
            # 更新顶点偏移索引
            vertex_offset_index += len(original_vertices)
            
        self.stats['deformations_applied'] += 1
        
    def create_morphing_animation(self, model_id: str, anim_name: str,
                                target_weights: Dict[str, float],
                                duration: float,
                                interpolation: InterpolationMode = InterpolationMode.LINEAR,
                                loop: bool = False) -> bool:
        """
        创建Morphing动画
        :param model_id: 模型ID
        :param anim_name: 动画名称
        :param target_weights: 目标权重字典 {target_name: weight}
        :param duration: 持续时间
        :param interpolation: 插值模式
        :param loop: 是否循环
        :return: 是否成功创建
        """
        if model_id not in self.model_data:
            print(f"错误: 模型 {model_id} 未注册")
            return False
            
        # 验证Morph目标是否存在
        for target_name in target_weights.keys():
            if target_name not in self.morph_targets[model_id]:
                print(f"错误: Morph目标 {target_name} 不存在于模型 {model_id} 中")
                return False
                
        # 创建动画
        animation = MorphingAnimation(
            name=anim_name,
            target_weights=target_weights,
            duration=duration,
            interpolation=interpolation,
            loop=loop,
            start_time=globalClock.getRealTime(),
            current_time=0.0,
            playing=False,
            paused=False
        )
        
        # 存储动画
        self.morphing_animations[model_id][anim_name] = animation
        print(f"Morphing动画已创建: {anim_name} (模型: {model_id})")
        return True
        
    def play_morphing_animation(self, model_id: str, anim_name: str) -> bool:
        """
        播放Morphing动画
        :param model_id: 模型ID
        :param anim_name: 动画名称
        :return: 是否成功播放
        """
        if (model_id not in self.morphing_animations or 
            anim_name not in self.morphing_animations[model_id]):
            print(f"错误: Morphing动画 {anim_name} 不存在于模型 {model_id} 中")
            return False
            
        animation = self.morphing_animations[model_id][anim_name]
        animation.playing = True
        animation.paused = False
        animation.start_time = globalClock.getRealTime()
        animation.current_time = 0.0
        
        self.stats['animations_played'] += 1
        print(f"Morphing动画开始播放: {anim_name} (模型: {model_id})")
        return True
        
    def stop_morphing_animation(self, model_id: str, anim_name: Optional[str] = None) -> bool:
        """
        停止Morphing动画
        :param model_id: 模型ID
        :param anim_name: 动画名称，如果为None则停止所有动画
        :return: 是否成功停止
        """
        if model_id not in self.morphing_animations:
            print(f"错误: 模型 {model_id} 未注册")
            return False
            
        if anim_name:
            # 停止单个动画
            if anim_name not in self.morphing_animations[model_id]:
                print(f"错误: Morphing动画 {anim_name} 不存在于模型 {model_id} 中")
                return False
                
            animation = self.morphing_animations[model_id][anim_name]
            animation.playing = False
            animation.paused = False
            print(f"Morphing动画已停止: {anim_name} (模型: {model_id})")
        else:
            # 停止所有动画
            for animation in self.morphing_animations[model_id].values():
                animation.playing = False
                animation.paused = False
            print(f"所有Morphing动画已停止 (模型: {model_id})")
            
        return True
        
    def pause_morphing_animation(self, model_id: str, anim_name: str) -> bool:
        """
        暂停Morphing动画
        :param model_id: 模型ID
        :param anim_name: 动画名称
        :return: 是否成功暂停
        """
        if (model_id not in self.morphing_animations or 
            anim_name not in self.morphing_animations[model_id]):
            print(f"错误: Morphing动画 {anim_name} 不存在于模型 {model_id} 中")
            return False
            
        animation = self.morphing_animations[model_id][anim_name]
        if animation.playing and not animation.paused:
            animation.paused = True
            print(f"Morphing动画已暂停: {anim_name} (模型: {model_id})")
            return True
            
        return False
        
    def resume_morphing_animation(self, model_id: str, anim_name: str) -> bool:
        """
        恢复Morphing动画
        :param model_id: 模型ID
        :param anim_name: 动画名称
        :return: 是否成功恢复
        """
        if (model_id not in self.morphing_animations or 
            anim_name not in self.morphing_animations[model_id]):
            print(f"错误: Morphing动画 {anim_name} 不存在于模型 {model_id} 中")
            return False
            
        animation = self.morphing_animations[model_id][anim_name]
        if animation.playing and animation.paused:
            animation.paused = False
            # 调整开始时间以补偿暂停时间
            animation.start_time = globalClock.getRealTime() - animation.current_time
            print(f"Morphing动画已恢复: {anim_name} (模型: {model_id})")
            return True
            
        return False
        
    def create_vertex_deformation(self, model_id: str, deformation_name: str,
                                vertex_indices: List[int],
                                target_positions: List[Tuple[float, float, float]],
                                duration: float,
                                interpolation: InterpolationMode = InterpolationMode.LINEAR) -> bool:
        """
        创建顶点变形
        :param model_id: 模型ID
        :param deformation_name: 变形名称
        :param vertex_indices: 顶点索引列表
        :param target_positions: 目标位置列表
        :param duration: 持续时间
        :param interpolation: 插值模式
        :return: 是否成功创建
        """
        if model_id not in self.model_data:
            print(f"错误: 模型 {model_id} 未注册")
            return False
            
        if len(vertex_indices) != len(target_positions):
            print(f"错误: 顶点索引数量 ({len(vertex_indices)}) 与目标位置数量 ({len(target_positions)}) 不匹配")
            return False
            
        # 创建顶点变形
        deformation = VertexDeformation(
            name=deformation_name,
            vertex_indices=vertex_indices,
            target_positions=target_positions,
            duration=duration,
            interpolation=interpolation,
            start_time=globalClock.getRealTime(),
            current_time=0.0,
            active=True
        )
        
        # 存储变形
        self.vertex_deformations[model_id].append(deformation)
        print(f"顶点变形已创建: {deformation_name} (模型: {model_id})")
        return True
        
    def remove_vertex_deformation(self, model_id: str, deformation_name: str) -> bool:
        """
        移除顶点变形
        :param model_id: 模型ID
        :param deformation_name: 变形名称
        :return: 是否成功移除
        """
        if model_id not in self.vertex_deformations:
            print(f"错误: 模型 {model_id} 未注册")
            return False
            
        # 查找并移除变形
        deformations = self.vertex_deformations[model_id]
        for i, deformation in enumerate(deformations):
            if deformation.name == deformation_name:
                deformations.pop(i)
                print(f"顶点变形已移除: {deformation_name} (模型: {model_id})")
                return True
                
        print(f"错误: 顶点变形 {deformation_name} 不存在于模型 {model_id} 中")
        return False
        
    def add_procedural_deformation(self, model_id: str, deformation_name: str,
                                 deformation_function: Callable,
                                 parameters: Dict[str, Any],
                                 update_rate: float = 1.0) -> bool:
        """
        添加程序化变形
        :param model_id: 模型ID
        :param deformation_name: 变形名称
        :param deformation_function: 变形函数
        :param parameters: 参数字典
        :param update_rate: 更新频率
        :return: 是否成功添加
        """
        if model_id not in self.model_data:
            print(f"错误: 模型 {model_id} 未注册")
            return False
            
        # 创建程序化变形
        deformation = ProceduralDeformation(
            name=deformation_name,
            deformation_function=deformation_function,
            parameters=parameters,
            update_rate=update_rate,
            last_update=globalClock.getRealTime(),
            active=True
        )
        
        # 存储变形
        self.procedural_deformations[model_id].append(deformation)
        print(f"程序化变形已添加: {deformation_name} (模型: {model_id})")
        return True
        
    def remove_procedural_deformation(self, model_id: str, deformation_name: str) -> bool:
        """
        移除程序化变形
        :param model_id: 模型ID
        :param deformation_name: 变形名称
        :return: 是否成功移除
        """
        if model_id not in self.procedural_deformations:
            print(f"错误: 模型 {model_id} 未注册")
            return False
            
        # 查找并移除变形
        deformations = self.procedural_deformations[model_id]
        for i, deformation in enumerate(deformations):
            if deformation.name == deformation_name:
                deformations.pop(i)
                print(f"程序化变形已移除: {deformation_name} (模型: {model_id})")
                return True
                
        print(f"错误: 程序化变形 {deformation_name} 不存在于模型 {model_id} 中")
        return False
        
    def update(self, dt: float) -> None:
        """
        更新Morphing系统
        :param dt: 时间增量
        """
        if not self.is_updating:
            return
            
        current_time = globalClock.getRealTime()
        
        # 更新每个模型
        for model_id in self.model_data.keys():
            # 更新Morphing动画
            self._update_morphing_animations(model_id, current_time, dt)
            
            # 更新顶点变形
            self._update_vertex_deformations(model_id, current_time, dt)
            
            # 更新程序化变形
            self._update_procedural_deformations(model_id, current_time, dt)
            
    def _update_morphing_animations(self, model_id: str, current_time: float, dt: float) -> None:
        """
        更新Morphing动画
        :param model_id: 模型ID
        :param current_time: 当前时间
        :param dt: 时间增量
        """
        if model_id not in self.morphing_animations:
            return
            
        # 更新每个动画
        animations_to_remove = []
        for anim_name, animation in self.morphing_animations[model_id].items():
            if not animation.playing or animation.paused:
                continue
                
            # 更新动画时间
            animation.current_time = current_time - animation.start_time
            
            # 检查动画是否完成
            if animation.current_time >= animation.duration:
                if animation.loop:
                    # 循环播放
                    animation.start_time = current_time
                    animation.current_time = 0.0
                else:
                    # 停止动画
                    animation.playing = False
                    continue
                    
            # 计算插值因子
            t = animation.current_time / animation.duration
            if animation.interpolation == InterpolationMode.EASE_IN:
                t = t * t
            elif animation.interpolation == InterpolationMode.EASE_OUT:
                t = 1.0 - (1.0 - t) * (1.0 - t)
            elif animation.interpolation == InterpolationMode.EASE_IN_OUT:
                t = t * t * (3.0 - 2.0 * t)
            elif animation.interpolation == InterpolationMode.SPLINE:
                # 简化的样条插值
                t = t * t * (3.0 - 2.0 * t)
                
            # 应用每个目标的权重
            for target_name, target_weight in animation.target_weights.items():
                self.set_morph_target_weight(model_id, target_name, target_weight * t)
                
    def _update_vertex_deformations(self, model_id: str, current_time: float, dt: float) -> None:
        """
        更新顶点变形
        :param model_id: 模型ID
        :param current_time: 当前时间
        :param dt: 时间增量
        """
        if model_id not in self.vertex_deformations:
            return
            
        # 更新每个变形
        deformations = self.vertex_deformations[model_id]
        active_deformations = [d for d in deformations if d.active]
        
        if not active_deformations:
            return
            
        model_data = self.model_data[model_id]
        
        # 对每个GeomNode应用变形
        for i, (geom_node, vertex_data) in enumerate(zip(model_data['geom_nodes'], model_data['vertex_data'])):
            # 创建可写的顶点数据
            writable_vertex_data = vertex_data.copy()
            vertex_writer = GeomVertexWriter(writable_vertex_data, 'vertex')
            original_vertices = model_data['original_vertices'][i]
            
            # 应用每个活动变形
            for deformation in active_deformations:
                # 更新变形时间
                deformation.current_time = current_time - deformation.start_time
                
                # 检查变形是否完成
                if deformation.current_time >= deformation.duration:
                    deformation.active = False
                    continue
                    
                # 计算插值因子
                t = deformation.current_time / deformation.duration
                if deformation.interpolation == InterpolationMode.EASE_IN:
                    t = t * t
                elif deformation.interpolation == InterpolationMode.EASE_OUT:
                    t = 1.0 - (1.0 - t) * (1.0 - t)
                elif deformation.interpolation == InterpolationMode.EASE_IN_OUT:
                    t = t * t * (3.0 - 2.0 * t)
                elif deformation.interpolation == InterpolationMode.SPLINE:
                    t = t * t * (3.0 - 2.0 * t)
                    
                # 应用变形到指定顶点
                for j, vertex_index in enumerate(deformation.vertex_indices):
                    if vertex_index < len(original_vertices):
                        original_vertex = original_vertices[vertex_index]
                        target_position = deformation.target_positions[j]
                        
                        # 计算插值位置
                        interpolated_position = (
                            original_vertex[0] + (target_position[0] - original_vertex[0]) * t,
                            original_vertex[1] + (target_position[1] - original_vertex[1]) * t,
                            original_vertex[2] + (target_position[2] - original_vertex[2]) * t
                        )
                        
                        # 更新顶点位置
                        vertex_writer.setRow(vertex_index)
                        vertex_writer.setData3f(
                            interpolated_position[0],
                            interpolated_position[1],
                            interpolated_position[2]
                        )
                        
            # 更新GeomNode的顶点数据
            geom_node.node().modifyGeom(0).setVertexData(writable_vertex_data)
            
        # 移除已完成的变形
        self.vertex_deformations[model_id] = [d for d in deformations if d.active]
        
    def _update_procedural_deformations(self, model_id: str, current_time: float, dt: float) -> None:
        """
        更新程序化变形
        :param model_id: 模型ID
        :param current_time: 当前时间
        :param dt: 时间增量
        """
        if model_id not in self.procedural_deformations:
            return
            
        # 更新每个变形
        deformations = self.procedural_deformations[model_id]
        active_deformations = [d for d in deformations if d.active]
        
        for deformation in active_deformations:
            # 检查更新时间
            if current_time - deformation.last_update < 1.0 / deformation.update_rate:
                continue
                
            deformation.last_update = current_time
            
            try:
                # 调用变形函数
                deformation.deformation_function(
                    self.model_data[model_id]['node_path'],
                    **deformation.parameters
                )
            except Exception as e:
                print(f"执行程序化变形函数时出错: {e}")
                
        # 移除非活动变形
        self.procedural_deformations[model_id] = [d for d in deformations if d.active]
        
    def get_model_info(self, model_id: str) -> Optional[Dict[str, Any]]:
        """
        获取模型信息
        :param model_id: 模型ID
        :return: 模型信息字典
        """
        if model_id not in self.model_data:
            print(f"错误: 模型 {model_id} 未注册")
            return None
            
        model_data = self.model_data[model_id]
        
        return {
            'model_id': model_id,
            'morph_targets': list(self.morph_targets[model_id].keys()),
            'morphing_animations': list(self.morphing_animations[model_id].keys()),
            'vertex_deformations': [d.name for d in self.vertex_deformations[model_id]],
            'procedural_deformations': [d.name for d in self.procedural_deformations[model_id]],
            'vertex_count': sum(len(vertices) for vertices in model_data['original_vertices']),
            'geom_node_count': len(model_data['geom_nodes'])
        }
        
    def get_morph_target_info(self, model_id: str, target_name: str) -> Optional[Dict[str, Any]]:
        """
        获取Morph目标信息
        :param model_id: 模型ID
        :param target_name: 目标名称
        :return: Morph目标信息字典
        """
        if (model_id not in self.morph_targets or 
            target_name not in self.morph_targets[model_id]):
            print(f"错误: Morph目标 {target_name} 不存在于模型 {model_id} 中")
            return None
            
        morph_target = self.morph_targets[model_id][target_name]
        
        return {
            'name': morph_target.name,
            'vertex_count': len(morph_target.vertices),
            'has_normals': morph_target.normals is not None,
            'has_tangents': morph_target.tangents is not None,
            'active': morph_target.active
        }
        
    def get_animation_info(self, model_id: str, anim_name: str) -> Optional[Dict[str, Any]]:
        """
        获取动画信息
        :param model_id: 模型ID
        :param anim_name: 动画名称
        :return: 动画信息字典
        """
        if (model_id not in self.morphing_animations or 
            anim_name not in self.morphing_animations[model_id]):
            print(f"错误: Morphing动画 {anim_name} 不存在于模型 {model_id} 中")
            return None
            
        animation = self.morphing_animations[model_id][anim_name]
        
        return {
            'name': animation.name,
            'target_weights': animation.target_weights,
            'duration': animation.duration,
            'interpolation': animation.interpolation.name,
            'loop': animation.loop,
            'current_time': animation.current_time,
            'playing': animation.playing,
            'paused': animation.paused
        }
        
    def start_updating(self) -> None:
        """
        开始更新Morphing系统
        """
        if not self.is_updating:
            self.is_updating = True
            print("Morphing系统更新已启动")
            
    def stop_updating(self) -> None:
        """
        停止更新Morphing系统
        """
        if self.is_updating:
            self.is_updating = False
            print("Morphing系统更新已停止")
            
    def get_system_stats(self) -> Dict[str, Any]:
        """
        获取系统统计信息
        :return: 统计信息字典
        """
        cache_stats = {
            'size': len(self.cache.cache),
            'max_size': self.cache.max_size
        }
        
        return {
            'models_processed': self.stats['models_processed'],
            'morph_targets_created': self.stats['morph_targets_created'],
            'animations_played': self.stats['animations_played'],
            'deformations_applied': self.stats['deformations_applied'],
            'cache_stats': cache_stats,
            'registered_models': len(self.model_data),
            'total_morph_targets': sum(len(targets) for targets in self.morph_targets.values()),
            'total_animations': sum(len(anims) for anims in self.morphing_animations.values())
        }
        
    def reset_stats(self) -> None:
        """
        重置统计信息
        """
        self.stats = {
            'models_processed': 0,
            'morph_targets_created': 0,
            'animations_played': 0,
            'deformations_applied': 0,
            'cache_hits': 0,
            'cache_misses': 0
        }
        print("统计信息已重置")