/** * Mesh Component Inspector. * 网格组件检查器。 * * Provides custom inspector UI for MeshComponent. * 为 MeshComponent 提供自定义检查器 UI。 */ import React, { useState, useEffect, useCallback } from 'react'; import { Component, Core, getComponentInstanceTypeName } from '@esengine/ecs-framework'; import { IComponentInspector, ComponentInspectorContext, MessageHub } from '@esengine/editor-core'; import { MeshComponent } from '@esengine/mesh-3d'; import { ChevronDown, ChevronRight, Box, Info } from 'lucide-react'; import './MeshComponentInspector.css'; /** * Mesh info display props. * 网格信息显示属性。 */ interface MeshInfoProps { mesh: MeshComponent; } /** * Mesh info component. * 网格信息组件。 * * Displays detailed mesh information when a model is loaded. * 当模型加载后显示详细的网格信息。 */ function MeshInfo({ mesh }: MeshInfoProps) { const [isExpanded, setIsExpanded] = useState(true); if (!mesh.meshAsset) { return (
No model loaded
); } const asset = mesh.meshAsset; const currentMesh = mesh.currentMesh; const totalMeshes = asset.meshes?.length ?? 0; return (
setIsExpanded(!isExpanded)} > {isExpanded ? : } Mesh Info
{isExpanded && (
{/* Model name */}
{asset.name || 'Unnamed'}
{/* Total meshes */}
{totalMeshes}
{/* Current mesh details */} {currentMesh && ( <>
Current Mesh ({mesh.meshIndex})
{currentMesh.name || `Mesh ${mesh.meshIndex}`}
{currentMesh.vertices && (
{Math.floor(currentMesh.vertices.length / 3).toLocaleString()}
)} {currentMesh.indices && (
{Math.floor(currentMesh.indices.length / 3).toLocaleString()}
)} )} {/* Materials */} {asset.materials && asset.materials.length > 0 && ( <>
Materials ({asset.materials.length})
{asset.materials.map((mat, i) => (
{i} {mat.name || `Material ${i}`}
))}
)} {/* Bounds */} {asset.bounds && ( <>
Bounds
({asset.bounds.min[0].toFixed(2)}, {asset.bounds.min[1].toFixed(2)}, {asset.bounds.min[2].toFixed(2)})
({asset.bounds.max[0].toFixed(2)}, {asset.bounds.max[1].toFixed(2)}, {asset.bounds.max[2].toFixed(2)})
)}
)}
); } /** * Mesh inspector content component. * 网格检查器内容组件。 */ function MeshInspectorContent({ context }: { context: ComponentInspectorContext }) { const mesh = context.component as MeshComponent; const [, forceUpdate] = useState({}); // Force update when mesh index changes // 当网格索引变化时强制更新 useEffect(() => { forceUpdate({}); }, [mesh.meshIndex, mesh.modelGuid]); const handleChange = useCallback((propertyName: string, value: unknown) => { (mesh as unknown as Record)[propertyName] = value; context.onChange?.(propertyName, value); forceUpdate({}); // Publish scene:modified // 发布 scene:modified const messageHub = Core.services.tryResolve(MessageHub); if (messageHub) { messageHub.publish('scene:modified', {}); } }, [mesh, context]); return (
{/* Mesh info display */}
); } /** * Mesh component inspector implementation. * 网格组件检查器实现。 * * Uses 'append' mode to show mesh info after the default PropertyInspector. * 使用 'append' 模式在默认 PropertyInspector 后显示网格信息。 */ export class MeshComponentInspector implements IComponentInspector { readonly id = 'mesh-component-inspector'; readonly name = 'Mesh Component Inspector'; readonly priority = 100; readonly targetComponents = ['Mesh', 'MeshComponent']; readonly renderMode = 'append' as const; canHandle(component: Component): component is MeshComponent { const typeName = getComponentInstanceTypeName(component); return typeName === 'Mesh' || typeName === 'MeshComponent'; } render(context: ComponentInspectorContext): React.ReactElement { return React.createElement(MeshInspectorContent, { context, key: `mesh-${context.version}` }); } }