feat(all): init commit

This commit is contained in:
plum
2026-04-19 18:46:28 +08:00
commit 5d7f479765
479 changed files with 178500 additions and 0 deletions
+213
View File
@@ -0,0 +1,213 @@
import { EventManager } from "../manager/EventManager.ts";
import { ResourceManager } from "../manager/ResourceManager.ts";
import { ClippingManager } from "../manager/ClippingManager.ts";
import { PipelineManager } from "../manager/PipelineManager.ts";
import { SelectionManager } from "../manager/SelectionManager.ts";
import { CSS2DRendererManager } from "../manager/CSS2DRendererManager.ts";
import { CSS3DRendererManager } from "../manager/CSS3DRendererManager.ts";
import { ParametricManager } from "../manager/ParametricManager.ts";
import type { ViewerEventMap } from "../enums";
import { ViewerEvents } from "../enums";
import CameraControls from "camera-controls";
import * as THREE from 'three/webgpu';
import { Inspector } from "three/examples/jsm/inspector/Inspector";
import Emittery from 'emittery';
import { RuptureEventManager } from "../manager/RuptureEventManager.ts";
import { RangeCullingManager } from "../manager/RangeCullingManager.ts";
import { VolumeMesh } from "../effect";
/**
* 相机状态接口
*/
export interface CameraState {
position: {
x: number;
y: number;
z: number;
};
target: {
x: number;
y: number;
z: number;
};
}
/**
* 场景节点接口
*/
export interface SceneNode {
uuid: string;
name: string;
/** 显示名称 */
displayName: string;
/** 是否有映射名称 */
hasMappedName?: boolean;
parent: string | null;
children: SceneNode[];
type: string;
visible: boolean;
opacity: number;
isClippingGroup: boolean;
}
/**
* 模型名称映射接口
*/
export interface ModelNameMapping {
name: string;
displayName: string;
}
/**
* 视图配置选项
*/
export interface IViewerOptions {
initCameraState?: CameraState;
raycastEnabled?: boolean;
/** 模型名称映射 */
modelNameMappings?: ModelNameMapping[];
/** 剖切配置 */
clipping?: IClippingManagerOptions;
}
/**
* 三维视图管理器
* Deep Engine 的核心类,负责管理场景、相机、渲染器等
*/
export declare class Viewer {
/** 事件管理器 */
events: EventManager;
/** 资源管理器 */
resources: ResourceManager;
/** 剖切管理器 */
clipping: ClippingManager;
container: HTMLElement | null;
scene: THREE.Scene;
sceneHelpers: THREE.Scene;
perspectiveCamera: THREE.PerspectiveCamera;
orthographicCamera: THREE.OrthographicCamera;
currentCameraType: 'perspective' | 'orthographic';
renderer: THREE.WebGPURenderer | null;
animationFrameId: number | null;
isInitialized: boolean;
pipelineManager: PipelineManager;
selection: SelectionManager;
/** CSS2D 渲染管理器 */
css2d: CSS2DRendererManager;
/** CSS3D 渲染管理器 */
css3d: CSS3DRendererManager;
/** 参数化对象管理器 */
parametric: ParametricManager;
inspector: Inspector;
/** 破裂事件管理器 */
ruptureEvents: RuptureEventManager;
emitter: Emittery<ViewerEventMap, ViewerEventMap & import("emittery").OmnipresentEventData, ViewerEvents.INIT>;
options: IViewerOptions;
/** 模型名称映射,用于存储模型名称到显示名的映射 */
modelNameMappings: Map<string, string>;
rangeCullingManager: RangeCullingManager;
timer: THREE.Timer;
private perspectiveCameraControls;
private orthographicCameraControls;
constructor(container: string | HTMLDivElement, options?: IViewerOptions);
/** 获取当前激活的相机 */
get camera(): THREE.PerspectiveCamera | THREE.OrthographicCamera;
/** 获取当前激活的相机控制器 */
get cameraControls(): CameraControls;
initCameraControls(): void;
initContainer(container: string | HTMLDivElement): void;
getSize(): {
width: number;
height: number;
};
getSizeVector2(): THREE.Vector2;
/**
* 初始化视图
* @param container - DOM 容器元素
* @param options - 配置选项
*/
initRenderer(): void;
openInspector(): void;
closeInspector(): void;
/**
* 处理窗口大小变化
*/
handleResize: () => void;
animate(time: DOMHighResTimeStamp, frame?: XRFrame): void;
/**
* 销毁视图
*/
dispose(): void;
/**
* 检查是否已初始化
* @returns 是否已初始化
*/
isReady(): boolean;
/**
* 获取模型的显示名称
* @param name - 模型原始名称
* @returns 模型的显示名称,如果没有映射则返回原始名称
*/
getModelDisplayName(name: string): string;
/**
* 添加模型名称映射
* @param mapping - 模型名称映射
*/
addModelNameMapping(mapping: ModelNameMapping): void;
/**
* 添加多个模型名称映射
* @param mappings - 模型名称映射数组
*/
addModelNameMappings(mappings: ModelNameMapping[]): void;
/**
* 清除所有模型名称映射
*/
clearModelNameMappings(): void;
serializeObject(obj: THREE.Object3D): SceneNode;
sceneToTreeJSON(scene?: THREE.Scene): SceneNode;
/**
* 序列化场景对象,只返回 Object3D 和 Group 类型的对象
* @param obj - 要序列化的对象
* @param nameFilter - 可选的名称过滤器,支持模糊匹配
* @returns 序列化后的场景节点
*/
serializeObjectFiltered(obj?: THREE.Object3D, nameFilter?: string): SceneNode | null;
/**
* 序列化场景对象,只返回 Object3D 和 Group 类型的对象,并支持名称过滤
* @param nameFilter - 可选的名称过滤器,支持模糊匹配
* @returns 序列化后的场景节点列表
*/
serializeSceneFiltered(nameFilter?: string): SceneNode[];
/**
* 将场景转换为树状 JSON 结构,只包含 Object3D 和 Group 类型的对象
* @param scene - 要转换的场景
* @param nameFilter - 可选的名称过滤器,支持模糊匹配
* @returns 序列化后的场景节点
*/
sceneToTreeJSONFiltered(scene?: THREE.Scene, nameFilter?: string): SceneNode | null;
getCameraState(): {
position: THREE.Vector3;
target: THREE.Vector3;
};
setCameraState(cameraState: CameraState, enableTransition?: boolean): Promise<void>;
resetCamera(enableTransition?: boolean): void;
/**
* 切换相机类型(透视相机和正交相机)
* 切换时保持视角不变
* @param type - 相机类型 'perspective' 或 'orthographic'
*/
switchCameraType(type: 'perspective' | 'orthographic'): Promise<void>;
/**
* 导出场景为JSON格式
* @returns 场景的JSON字符串
*/
exportSceneToJSON(): string;
/**
* 导出场景为JSON文件并下载
* @param filename - 下载的文件名
*/
downloadSceneJSON(filename?: string): void;
getAllVolumeMesh(): VolumeMesh[];
setTestBackground(): void;
/**
* 扁平化 ClippingGroup 节点,将其子节点提升到父级
* @param nodes - 节点数组
* @returns 扁平化后的节点数组
*/
private flattenClippingGroups;
}
+12
View File
@@ -0,0 +1,12 @@
import type { Viewer } from "./Viewer.ts";
export declare class ViewerManager {
viewers: Set<Viewer>;
defaultViewer: Viewer | null;
register(viewer: Viewer, makeDefault?: boolean): void;
unregister(viewer: Viewer): void;
getDefault(): Viewer;
setDefault(viewer: Viewer): void;
getAll(): Viewer[];
}
declare const viewerManager: ViewerManager;
export default viewerManager;
+3
View File
@@ -0,0 +1,3 @@
export { Viewer } from "./Viewer";
export { RuptureEventManager } from "../manager/RuptureEventManager";
export type { RuptureEvent, RuptureEventConfig } from "../manager/RuptureEventManager";
+66
View File
@@ -0,0 +1,66 @@
import * as THREE from 'three/webgpu';
import type { RenderEventData } from "../enums/ViewerEvents.ts";
interface ArrowAnimation {
mesh: THREE.Group;
basePos: THREE.Vector3;
moveDir: THREE.Vector3;
sideSign: number;
phase: number;
}
export interface FaultSlipOptions {
normal?: THREE.Vector3;
rows?: number;
cols?: number;
spacingU?: number;
spacingV?: number;
arrowLength?: number;
shaftWidth?: number;
headWidth?: number;
headLength?: number;
colorHex?: number;
arrowSideOffset?: number;
arrowMoveAmp?: number;
arrowMoveSpeed?: number;
autoStart?: boolean;
}
/**
* 断层滑移引起矿震的可视化效果
* 基于 Mesh 的包围盒生成断层面和交错箭头动画
*/
export declare class FaultSlip {
#private;
options: Required<FaultSlipOptions>;
group: THREE.Group;
active: boolean;
mesh: THREE.Mesh;
arrowAnims: ArrowAnimation[];
flatArrowShaftGeom: THREE.PlaneGeometry;
flatArrowHeadGeom: THREE.ShapeGeometry;
flatArrowMat: THREE.MeshBasicMaterial;
tmpV: THREE.Vector3;
tmpV2: THREE.Vector3;
tmpV3: THREE.Vector3;
tmpM: THREE.Matrix4;
updateBound: ((data: RenderEventData) => void) | null;
private _elapsedTime;
constructor(mesh: THREE.Mesh, options?: FaultSlipOptions);
start(): void;
stop(): void;
toggle(): void;
update(data: RenderEventData): void;
setColor(colorHex: number): void;
setOpacity(opacity: number): void;
setSpeed(speed: number): void;
setAmplitude(amplitude: number): void;
dispose(): void;
init(): void;
makeArrowMesh(params: {
length: number;
shaftWidth: number;
headWidth: number;
headLength: number;
}): THREE.Group;
orientArrowOnSection(arrow: THREE.Group, moveDir: THREE.Vector3, sectionNormal: THREE.Vector3): void;
buildVisualization(): void;
}
export {};
+301
View File
@@ -0,0 +1,301 @@
import * as THREE from "three/webgpu";
import type { Viewer } from "../core/Viewer.ts";
import type { ParametricPipe } from "../parametric/ParametricPipe.ts";
/**
* 流动粒子配置。
*/
export interface FlowParticlesGPUOptions {
/**
* 起始管道。
*/
startPipe: ParametricPipe;
/**
* 结束管道。
*/
endPipe: ParametricPipe;
/**
* 粒子总数量。
*/
particleCount?: number;
/**
* 粒子流动速度倍率。
*/
speedMultiplier?: number;
/**
* 粒子半径。
*/
particleSize?: number;
/**
* 加热阈值。
*/
heatingThreshold?: number;
/**
* 流动路径数量。
*/
flowPathCount?: number;
/**
* 颜色断点配置。
*/
colorStops?: FlowColorStop[];
}
/**
* 流动颜色断点。
*/
export interface FlowColorStop {
/**
* 颜色值。
*/
color: string;
/**
* 断点位置,范围 [0, 1]。
*/
step: number;
/**
* 当粒子经过该断点时被永久冻结颜色的概率,范围 [0, 1]。
*/
frozenProbability?: number;
}
/**
* 粒子运行时状态。
*/
interface Particle {
/**
* 当前路径进度。
*/
t: number;
/**
* 当前粒子速度。
*/
speed: number;
/**
* 横向扰动幅度。
*/
jitter: number;
/**
* 扰动相位。
*/
phase: number;
/**
* 分层系数。
*/
layer: number;
/**
* 当前路径索引。
*/
pathIndex: number;
/**
* 上一帧热值。
*/
lastHeatValue: number;
/**
* 当前颜色缓存。
*/
currentColor: THREE.Color;
/**
* 是否冻结颜色。
*/
frozen: boolean;
}
/**
* 流动粒子效果。
*/
export declare class FlowParticles {
viewer: Viewer;
startPipe: ParametricPipe;
endPipe: ParametricPipe;
particleCount: number;
speedMultiplier: number;
particleSize: number;
heatingThreshold: number;
flowPathCount: number;
colorStops: FlowColorStop[];
flowPaths: THREE.CatmullRomCurve3[];
particles: Particle[];
flowGeometry: THREE.SphereGeometry | null;
flowMaterial: THREE.Material | null;
flowPoints: THREE.InstancedMesh | null;
updateHandler: (() => void) | null;
/**
* 起始管道顶部世界坐标。
*/
private startPipeTopWorld;
/**
* 起始管道底部世界坐标。
*/
private startPipeBottomWorld;
/**
* 结束管道顶部世界坐标。
*/
private endPipeTopWorld;
/**
* 结束管道底部世界坐标。
*/
private endPipeBottomWorld;
/**
* 起始管道世界半径。
*/
private startPipeRadiusWorld;
/**
* 结束管道世界半径。
*/
private endPipeRadiusWorld;
/**
* 粒子在每轮起点冻结颜色的概率。
*/
private frozenProbability;
/**
* 构造函数。
* @param viewer 视图对象
* @param options 配置参数
*/
constructor(viewer: Viewer, options: FlowParticlesGPUOptions);
/**
* 设置粒子数量并重建系统。
* @param count 粒子数量
*/
setParticleCount(count: number): void;
/**
* 设置速度倍率。
* @param speed 速度倍率
*/
setSpeedMultiplier(speed: number): void;
/**
* 设置冻结概率。
* @param probability 冻结概率,范围 [0, 1]
*/
setFrozenProbability(probability: number): void;
/**
* 设置加热阈值。
* @param threshold 阈值,范围 [0, 1]
*/
setHeatingThreshold(threshold: number): void;
/**
* 动态更新颜色断点。
* @param stops 断点数组
*/
setColorStops(stops: FlowColorStop[]): void;
/**
* 释放资源。
*/
dispose(): void;
/**
* 点位转换为 THREE.Vector3。
* @param point 输入点
* @returns 转换结果
*/
toVector3(point: THREE.Vector3 | {
x: number;
y: number;
z: number;
}): THREE.Vector3;
/**
* 初始化。
*/
init(): void;
/**
* 生成流动路径。
*/
createFlowPaths(): void;
/**
* 初始化粒子网格。
*/
initParticles(): void;
/**
* 绑定更新循环。
*/
setupUpdateLoop(): void;
/**
* 每帧更新。
*/
update(): void;
/**
* 计算热值。
* @param t 路径进度
* @returns 热值
*/
calculateHeatColor(t: number): number;
/**
* 将粒子限制在对应管道圆柱内。
* @param position 粒子位置
* @param t 路径进度
* @returns 限制后的粒子位置
*/
private constrainParticleInsidePipe;
/**
* 将点钳制在指定圆柱管道内部。
* @param point 待处理点
* @param top 管道顶部坐标
* @param bottom 管道底部坐标
* @param radius 管道半径
* @returns 钳制后的点
*/
private clampPointInsidePipe;
/**
* 计算与轴向量垂直的单位向量。
* @param axis 轴向量
* @returns 垂直单位向量
*/
private getPerpendicularUnitVector;
/**
* 根据热值创建初始颜色状态。
* @param heatValue 当前热值
* @returns 初始颜色状态
*/
private createInitialColorState;
/**
* 根据热值插值颜色。
* @param heatValue 当前热值
* @returns 插值后的颜色
*/
private interpolateStopColor;
/**
* 重置粒子颜色状态。
* @param particle 粒子状态
* @param heatValue 当前热值
* @returns 粒子颜色
*/
private resetParticleColorState;
/**
* 刷新当前粒子颜色。
*/
private refreshParticleColors;
/**
* 标准化颜色断点。
* @param stops 原始断点
* @returns 标准化断点
*/
private normalizeColorStops;
/**
* 读取管道世界点。
* @param pipe 管道对象
* @returns 世界坐标点数组
*/
private getPipePoints;
/**
* 读取管道世界半径。
* @param pipe 管道对象
* @returns 世界半径
*/
private getPipeRadius;
/**
* 读取管道边界。
* @param pipe 管道对象
* @returns 管道边界信息
*/
private getPipeBoundary;
/**
* 根据轴向量构建正交基。
* @param direction 轴向量
* @returns 两个互相正交的单位向量
*/
private getPerpendicularBasis;
/**
* 在圆盘上生成随机偏移向量。
* @param perp1 正交基向量1
* @param perp2 正交基向量2
* @param radius 圆盘半径
* @returns 偏移向量
*/
private createRandomDiskOffset;
}
export {};
+146
View File
@@ -0,0 +1,146 @@
import * as THREE from 'three/webgpu';
interface FractureSphere {
mesh: THREE.Mesh;
targetRadius: number;
position: THREE.Vector3;
index: number;
t: number;
}
export interface FractureEffectOptions {
points: THREE.Vector3[];
curveType?: 'catmullrom' | 'linear';
tension?: number;
closed?: boolean;
spacing?: number;
bufferRatio?: number;
minRadius?: number;
maxRadius?: number;
animationDuration?: number;
sphereAnimDuration?: number;
sphereOpacity?: number;
spheresVisible?: boolean;
cracksVisible?: boolean;
colorMode?: 'random' | 'gradient' | 'fixed';
fixedColor?: number;
gradientStart?: number;
gradientEnd?: number;
autoStart?: boolean;
crackModelUrls?: string[];
}
/**
* 压裂效果
* 沿着一组点生成的曲线生成一系列带弹性动画的球体,模拟压裂过程
*/
export declare class FractureEffect {
options: Required<FractureEffectOptions>;
active: boolean;
running: boolean;
spheres: FractureSphere[];
group: THREE.Group;
crackModels: THREE.Object3D[];
crackModelTemplates: THREE.Object3D[];
progressCallback: ((progress: number) => void) | null;
curve: THREE.Curve<THREE.Vector3> | null;
constructor(options: FractureEffectOptions);
/**
* 根据点数组创建曲线
*/
createCurve(): void;
/**
* 设置进度回调
*/
onProgress(callback: (progress: number) => void): void;
/**
* 开始压裂动画
*/
start(): Promise<void>;
/**
* 停止动画
*/
stop(): void;
/**
* 清除所有球体和裂缝模型
*/
clear(): void;
/**
* 显示裂缝模型
*/
showCracks(): void;
/**
* 隐藏裂缝模型
*/
hideCracks(): void;
/**
* 切换裂缝模型显示
*/
toggleCracks(): void;
/**
* 显示球体
*/
showSpheres(): void;
/**
* 隐藏球体
*/
hideSpheres(): void;
/**
* 切换球体显示
*/
toggleSpheres(): void;
/**
* 设置球体透明度
*/
setOpacity(opacity: number): void;
/**
* 更新点数组
*/
updatePoints(points: THREE.Vector3[]): void;
/**
* 重新开始
*/
restart(): Promise<void>;
/**
* 获取球体数量
*/
getSphereCount(): number;
/**
* 获取球体列表
*/
getSpheres(): FractureSphere[];
/**
* 销毁
*/
dispose(): void;
/**
* 加载裂缝模型模板
*/
loadCrackModels(): Promise<void>;
/**
* 生成高对比度随机颜色
*/
getRandomHighContrastColor(): THREE.Color;
/**
* 根据位置获取渐变颜色
*/
getGradientColor(t: number): THREE.Color;
/**
* 获取球体颜色
*/
getSphereColor(t: number): THREE.Color;
/**
* 缓动函数 - easeOutElastic
*/
easeOutElastic(x: number): number;
/**
* 球体弹入动画
*/
animateSphereIn(sphere: THREE.Mesh): Promise<void>;
/**
* 计算球体位置
*/
calculatePositions(): Array<{
position: THREE.Vector3;
t: number;
index: number;
}>;
}
export {};
+150
View File
@@ -0,0 +1,150 @@
import * as THREE from 'three/webgpu';
import type { RenderEventData } from "../enums/ViewerEvents.ts";
/**
* 落石模型来源类型
*/
export declare enum RockDebrisModelSourceType {
/** 使用程序内置的几何体生成落石 */
GENERATED = "GENERATED",
/** 使用传入 URL 的模型生成落石 */
URL = "URL"
}
export interface RockDebrisOptions {
count?: number;
size: [number, number];
office: [number, number];
speed: number;
startPosition: THREE.Vector3;
mesh: THREE.Mesh;
modelSourceType?: RockDebrisModelSourceType;
modelUrls?: string[];
}
interface RockData {
mesh: THREE.Mesh;
active: boolean;
settled: boolean;
velocityY: number;
radius: number;
delayRemaining: number;
}
/**
* 岩爆碎片效果
*/
export declare class RockDebris {
options: Required<RockDebrisOptions>;
rocks: RockData[];
/** URL 模型模板缓存 */
private readonly rockModelTemplates;
/** URL 模型加载器 */
private readonly gltfLoader;
/** URL 模型加载状态 */
private modelLoadStatus;
/** URL 模型加载任务 */
private modelLoadTask;
active: boolean;
updateBound: ((data: RenderEventData) => void) | null;
readonly _matrix: THREE.Matrix4;
readonly _raycaster: THREE.Raycaster;
readonly _rayDirection: THREE.Vector3;
/** 单个落石生成点的最大重采样次数,防止射线检测陷入无限循环 */
readonly SPAWN_MAX_RETRY = 20;
/** 判定“靠墙”时的最小射线距离下限 */
readonly SPAWN_MIN_RAY_DISTANCE = 0.05;
/** 落石生成时复用的候选坐标,减少临时对象分配 */
private readonly _spawnCandidatePosition;
/** 用于计算碰撞网格世界包围盒的临时对象 */
private readonly _meshWorldBox;
/** 用于缓存碰撞网格世界包围盒尺寸的临时对象 */
private readonly _meshWorldSize;
/** 用于读取碰撞网格世界缩放的临时对象 */
private readonly _meshWorldScale;
readonly FALL_LIMIT = 50;
constructor(options: RockDebrisOptions);
spawn(): Promise<void>;
/**
* 确保落石对象池已初始化
* @returns 无返回值
* @throws 当场景不可用或 URL 模型初始化失败时抛错
*/
private ensureRockPoolInitialized;
/**
* 创建程序生成的落石对象池
* @returns 无返回值
* @throws 当场景不可用时抛错
*/
private createGeneratedRockPool;
/**
* 创建 URL 模型落石对象池
* @returns 无返回值
* @throws 当模板为空、场景不可用或模型数据非法时抛错
*/
private createUrlRockPool;
/**
* 确保 URL 模型模板已加载
* @returns 无返回值
* @throws 当 URL 模型加载失败或没有可用网格时抛错
*/
private ensureUrlModelTemplatesLoaded;
/**
* 加载单个 GLTF 场景
* @param url - 模型 URL
* @returns GLTF 场景根节点
*/
private loadGltfScene;
/**
* 释放材质资源(支持单材质和多材质)
* @param material - 待释放材质
* @returns 无返回值
*/
private disposeRockMaterial;
/**
* 从 ParametricArch 参数计算射线允许的最大距离
* @returns 基于 ParametricArch 参数推导的最大距离;若参数缺失返回 null
*/
private getSpawnMaxRayDistanceFromParametricArch;
/**
* 计算落石生成点射线检测允许的最大距离
* @returns 射线允许的最大距离,优先使用 ParametricArch 参数,异常情况下回退到包围盒高度
*/
private getSpawnMaxRayDistance;
/**
* 计算落石生成点射线检测允许的最小距离
* @param rockRadius - 当前落石半径
* @returns 射线最小距离阈值,距离过小会被判定为靠墙位置
*/
private getSpawnMinRayDistance;
/**
* 生成一个候选落石位置
* @param startPosition - 落石起始位置
* @param offMin - 随机偏移最小值
* @param offMax - 随机偏移最大值
* @param output - 候选位置输出对象
*/
private sampleSpawnCandidatePosition;
/**
* 对候选落石位置执行向下射线检测并给出状态
* @param candidatePosition - 候选位置
* @param minRayDistance - 射线最小距离阈值
* @param maxRayDistance - 射线最大距离阈值
* @returns 检测状态,决定是否需要继续换点重采样
*/
private getSpawnRaycastStatus;
/**
* 为落石选择一个有效生成点
* @param startPosition - 落石起始位置
* @param offMin - 随机偏移最小值
* @param offMax - 随机偏移最大值
* @param rockRadius - 当前落石半径
* @param maxRayDistance - 射线最大距离阈值
* @param output - 最终生成位置输出对象
* @returns 是否成功找到有效生成位置
*/
private tryResolveSpawnPosition;
start(): void;
stop(): void;
update(data: RenderEventData): void;
clear(): void;
dispose(): void;
init(): void;
}
export {};
+54
View File
@@ -0,0 +1,54 @@
import * as THREE from 'three/webgpu';
import type { ParametricBox } from "../parametric";
import type { RenderEventData } from "../enums/ViewerEvents.ts";
interface SeismicEmitter {
position: THREE.Vector3;
nextSpawn: number;
}
interface SeismicWaveInstance {
mesh: THREE.Mesh;
startTime: number;
}
export interface SeismicWaveOptions {
emitterPositions?: THREE.Vector3[];
minRadius?: number;
maxRadius?: number;
waveDuration?: number;
spawnInterval?: number;
opacity?: number;
color?: THREE.Color;
autoStart?: boolean;
startDelay?: number;
shape?: 'sphere' | 'hemisphere';
useRangeCulling?: boolean;
}
export declare class SeismicWave {
#private;
options: Required<SeismicWaveOptions>;
emitters: SeismicEmitter[];
waves: SeismicWaveInstance[];
geometry: THREE.SphereGeometry | null;
active: boolean;
startTime: number | null;
delayTimer: number | null;
boundingBox: ParametricBox | null;
private _elapsedTime;
private _boundUpdateHandler;
constructor(options?: SeismicWaveOptions);
constructor(position: THREE.Vector3, startDelay?: number);
constructor(positions: THREE.Vector3[], startDelay?: number);
init(): void;
start(): void;
startWithDelay(delay: number): void;
stop(): void;
clearWaves(): void;
spawnWave(position: THREE.Vector3): void;
update(data: RenderEventData): void;
removeFromScene(scene: THREE.Scene): void;
setOpacity(opacity: number): void;
setColor(color: number): void;
updateEmitterPositions(positions: THREE.Vector3[]): void;
dispose(): void;
createDefaultEmitters(): THREE.Vector3[];
}
export {};
+12
View File
@@ -0,0 +1,12 @@
export { FaultSlip } from './FaultSlip';
export type { FaultSlipOptions } from './FaultSlip';
export { FlowParticles } from './FlowParticles.ts';
export type { FlowColorStop, FlowParticlesGPUOptions } from './FlowParticles.ts';
export { FractureEffect } from './FractureEffect';
export type { FractureEffectOptions } from './FractureEffect';
export { SeismicWave } from './SeismicWave';
export type { SeismicWaveOptions } from './SeismicWave';
export { RockDebris } from './RockDebris';
export { RockDebrisModelSourceType } from "./RockDebris";
export type { RockDebrisOptions } from './RockDebris';
export * from "./volume";
+101
View File
@@ -0,0 +1,101 @@
import * as THREE from "three/webgpu";
import type { Viewer } from "../../core";
import type { PointCloudData } from "./PointCloudTool";
/**
* 点云颜色停靠点配置。
*/
export interface PointCloudColorStop {
/**
* 颜色值(支持十六进制、rgb、hsl 等 Canvas 支持的格式)。
*/
color: string;
/**
* 渐变位置,范围 0~1。
*/
step: number;
}
/**
* 点云渲染配置。
*/
export interface PointCloudOptions {
/**
* 场景树显示名称。
*/
name: string;
/**
* 外部已准备好的点云数据。
*/
pointCloudData: PointCloudData;
/**
* 颜色映射节点。
*/
colorStops?: PointCloudColorStop[];
/**
* 点大小(像素单位)。
*/
pointSize?: number;
}
/**
* 点云渲染对象。
* 参考 `webgpu_instance_points.html`
* 使用 `Sprite + PointsNodeMaterial + instancedBufferAttribute + count` 的模式进行实例化点渲染。
*/
export declare class PointCloud extends THREE.Sprite {
/**
* 场景视图实例。
*/
readonly viewer: Viewer;
/**
* 每个点的强度缓存(0~1)。
*/
private readonly densities;
/**
* 点数量缓存。
*/
private readonly pointCount;
opacity: THREE.UniformNode<'float', number>;
densityRange: THREE.UniformNode<'vec2', THREE.Vector2>;
/**
* 创建点云渲染对象。
* @param viewer 视图实例
* @param options 点云渲染配置
*/
constructor(viewer: Viewer, options: PointCloudOptions);
/**
* 按强度区间过滤点云显示。
* @param min 最小强度
* @param max 最大强度
* @returns {void}
*/
filterByIntensity(min: number, max?: number): void;
/**
* 批量更新点大小。
* @param pointSize 新的点大小(像素单位)
* @returns {void}
*/
setPointSize(pointSize: number): void;
/**
* 销毁点云对象并释放资源。
* @returns {void}
*/
dispose(): void;
/**
* 校验点云数据合法性。
* @param pointCloudData 点云数据
* @returns {void}
*/
private static validatePointCloudData;
/**
* 根据强度与颜色停靠点构建每个点的 RGB 数组。
* @param densities 点强度数组
* @param colorStops 颜色停靠点
* @returns 颜色数组(rgbrgb...
*/
private static buildColorArray;
/**
* 将颜色停靠点写入 1D 渐变贴图数据。
* @param colorStops 颜色停靠点
* @returns RGBA 字节数组
*/
private static createGradientLookupData;
}
+208
View File
@@ -0,0 +1,208 @@
/**
* 点云数据结构。
*/
export interface PointCloudData {
/**
* 点位坐标数组,格式为 xyzxyz...
*/
positions: Float32Array;
/**
* 点位强度数组,范围为 0~1。
*/
densities: Float32Array;
}
/**
* 噪声点云生成参数。
*/
export interface PointCloudNoiseOptions {
/**
* X 方向分辨率(可选,如果提供 size 则忽略)。
*/
x?: number;
/**
* Y 方向分辨率(可选,如果提供 size 则忽略)。
*/
y?: number;
/**
* Z 方向分辨率(可选,如果提供 size 则忽略)。
*/
z?: number;
/**
* 统一分辨率,同时设置 x/y/z。
*/
size?: number;
/**
* 点云空间边长。
*/
spaceSize?: number;
/**
* 点云空间最小边界 [x, y, z]。
*/
min?: [number, number, number];
/**
* 点云空间最大边界 [x, y, z]。
*/
max?: [number, number, number];
/**
* 强度阈值,范围 0~1。
*/
threshold?: number;
/**
* 噪声空间缩放。
*/
noiseScale?: number;
}
/**
* 规则网格点云参数。
*/
export interface PointCloudGridOptions {
/**
* X 轴最小值与最大值。
*/
xRange: [number, number];
/**
* Y 轴最小值与最大值。
*/
yRange: [number, number];
/**
* Z 轴最小值与最大值。
*/
zRange: [number, number];
/**
* X 轴采样数量。
*/
xCount: number;
/**
* Y 轴采样数量。
*/
yCount: number;
/**
* Z 轴采样数量。
*/
zCount: number;
/**
* 强度值或强度计算函数。
*/
density?: number | ((x: number, y: number, z: number) => number);
}
/**
* 体积数据转点云参数。
*/
export interface PointCloudFromVolumeOptions {
/**
* 体素数据,通常来自 VolumeTool(如 Uint8Array)。
*/
data: Uint8Array | Uint16Array | Float32Array;
/**
* X 方向分辨率(可选,如果提供 size 则忽略)。
*/
x?: number;
/**
* Y 方向分辨率(可选,如果提供 size 则忽略)。
*/
y?: number;
/**
* Z 方向分辨率(可选,如果提供 size 则忽略)。
*/
z?: number;
/**
* 统一分辨率,同时设置 x/y/z。
*/
size?: number;
/**
* 点云空间边长。
*/
spaceSize?: number;
/**
* 点云空间最小边界 [x, y, z]。
*/
min?: [number, number, number];
/**
* 点云空间最大边界 [x, y, z]。
*/
max?: [number, number, number];
/**
* 强度阈值,范围 0~1,仅保留大于该值的点。
*/
threshold?: number;
/**
* 原始数据最小值,默认 0。
*/
sourceMin?: number;
/**
* 原始数据最大值,默认 255(兼容 VolumeTool 输出)。
*/
sourceMax?: number;
}
/**
* 点云数据工具类。
*/
export declare class PointCloudTool {
/**
* 直接生成噪声点云数据。
* 生成逻辑基于点云密度:
* 1. 使用 3D 噪声采样
* 2. 将噪声值映射到 0~1 强度
* 3. 根据阈值筛选有效点
* @param options 生成参数
* @returns 点云数据
*/
static generateNoisePointCloudData(options: PointCloudNoiseOptions): PointCloudData;
/**
* 生成规则网格点云数据。
* @param options 规则网格参数
* @returns 点云数据
*/
static generateGridPointCloud(options: PointCloudGridOptions): PointCloudData;
/**
* 将体积数据转换为点云数据。
* 默认按 VolumeTool 输出规则将 0~255 映射为 0~1 强度,并根据阈值筛选。
* @param options 转换参数
* @returns 点云数据
*/
static convertVolumeToPointCloudData(options: PointCloudFromVolumeOptions): PointCloudData;
/**
* 将离散索引映射到 0~1(包含端点)。
* @param index 当前索引
* @param count 维度长度
* @returns 归一化结果
*/
private static resolveNormalizedIndex;
/**
* 解析噪声值对应的点强度。
* @param noiseValue 噪声值(-1~1
* @returns 点强度(0~1
*/
private static resolveNoiseDensity;
/**
* 解析体素值对应的点强度。
* @param value 体素值
* @param sourceMin 原始范围最小值
* @param sourceMax 原始范围最大值
* @returns 点强度(0~1
*/
private static resolveVolumeDensity;
/**
* 根据索引解析指定区间坐标。
* @param index 当前索引
* @param count 维度长度
* @param range 区间
* @returns 区间坐标
*/
private static resolveRangeValue;
/**
* 归一化区间,确保最小值在前、最大值在后。
* @param range 输入区间
* @returns 归一化区间
*/
private static normalizeRange;
/**
* 解析点位强度。
* @param density 输入强度定义
* @param x X 坐标
* @param y Y 坐标
* @param z Z 坐标
* @returns 强度值(0~1
*/
private static resolveDensity;
}
+69
View File
@@ -0,0 +1,69 @@
import * as THREE from 'three/webgpu';
import { ParametricWireframe } from "../../parametric";
import type { Viewer } from "../../core";
export interface ColorStop {
color: string;
step: number;
}
export declare enum VolumeRenderMode {
EmissionAbsorptionModel = 0,
MinimumIntensityProjection = 1,
MaximumIntensityProjection = 2
}
export interface VolumeRenderingOptions {
name: string;
scale?: number;
size?: number;
sizeX?: number;
sizeY?: number;
sizeZ?: number;
data: Uint8Array;
colorStops?: ColorStop[];
range?: number;
threshold?: number;
steps?: number;
useSmoothing?: boolean;
mode?: VolumeRenderMode;
clipMode?: 0 | 1;
clipPlane?: THREE.Vector4;
showWireframe?: boolean;
}
export declare function isVolumeMesh(value: any): value is VolumeMesh;
export { PointCloud } from './PointCloud';
export type { PointCloudOptions } from './PointCloud';
export declare class VolumeMesh extends THREE.Mesh<THREE.BufferGeometry, THREE.NodeMaterial> {
static panelCounter: number;
range: THREE.UniformNode<'float', number>;
threshold: THREE.UniformNode<'float', number>;
opacity: THREE.UniformNode<'float', number>;
steps: THREE.UniformNode<'float', number>;
useSmoothing: THREE.UniformNode<'float', number>;
mode: THREE.UniformNode<'float', number>;
clipMode: THREE.UniformNode<'float', number>;
clipPlane: THREE.UniformNode<'vec4', THREE.Vector4>;
clipPlaneX: THREE.UniformNode<'vec4', THREE.Vector4>;
clipPlaneY: THREE.UniformNode<'vec4', THREE.Vector4>;
clipPlaneZ: THREE.UniformNode<'vec4', THREE.Vector4>;
uniformScale: number;
data: Uint8Array;
viewer: Viewer;
volumeTexture: THREE.Data3DTexture;
transferTexture: THREE.Texture;
material: THREE.NodeMaterial;
wireframe?: ParametricWireframe;
sizeX: number;
sizeY: number;
sizeZ: number;
canvas?: HTMLCanvasElement;
colorStops: ColorStop[];
isVolumeMesh: boolean;
constructor(viewer: Viewer, options: VolumeRenderingOptions);
updateTransferTexture(colorStops: ColorStop[]): void;
updateVolumeData(data: Uint8Array): void;
setWireframeVisible(visible: boolean): void;
updateTransferTextureCanvas(colorStops: ColorStop[]): void;
createTransferTexture(colorStops: ColorStop[]): THREE.Texture;
numberToHex(n: number): string;
dispose(): void;
createDebugPanel(): void;
}
+62
View File
@@ -0,0 +1,62 @@
import { type Node } from "three/webgpu";
import type { NodeElements } from "three/src/nodes/core/Node";
export declare const remap: import("three/src/nodes/TSL.js").FnNode<any[], Node>;
export declare const RaymarchingBox: (steps: NodeElements, minx: NodeElements, miny: NodeElements, minz: NodeElements, callback: (args: {
positionRay: NodeElements;
}) => void, clipPlane?: NodeElements) => void;
export interface IVoxelMaterialOptions {
readonly colorTexture: NodeElements;
readonly texture: NodeElements;
readonly range: NodeElements;
readonly threshold: NodeElements;
readonly opacity: NodeElements;
readonly steps: NodeElements;
readonly useSmoothing: NodeElements;
readonly mode: NodeElements;
readonly clipMode: NodeElements;
readonly clipPlane: NodeElements;
readonly clipPlaneX: NodeElements;
readonly clipPlaneY: NodeElements;
readonly clipPlaneZ: NodeElements;
readonly [key: string]: unknown;
}
export interface IEmissionAbsorptionModelOptions {
readonly colorTexture: NodeElements;
readonly texture: NodeElements;
readonly range: NodeElements;
readonly threshold: NodeElements;
readonly opacity: NodeElements;
readonly steps: NodeElements;
readonly useSmoothing: NodeElements;
readonly clipMode: NodeElements;
readonly clipPlane: NodeElements;
readonly clipPlaneX: NodeElements;
readonly clipPlaneY: NodeElements;
readonly clipPlaneZ: NodeElements;
readonly [key: string]: unknown;
}
export interface IMaximumIntensityProjectionOptions {
readonly colorTexture: NodeElements;
readonly texture: NodeElements;
readonly opacity: NodeElements;
readonly steps: NodeElements;
readonly clipMode: NodeElements;
readonly clipPlane: NodeElements;
readonly clipPlaneX: NodeElements;
readonly clipPlaneY: NodeElements;
readonly clipPlaneZ: NodeElements;
readonly [key: string]: unknown;
}
export interface IMinimumIntensityProjectionOptions {
readonly colorTexture: NodeElements;
readonly texture: NodeElements;
readonly opacity: NodeElements;
readonly steps: NodeElements;
readonly clipMode: NodeElements;
readonly clipPlane: NodeElements;
readonly clipPlaneX: NodeElements;
readonly clipPlaneY: NodeElements;
readonly clipPlaneZ: NodeElements;
readonly [key: string]: unknown;
}
export declare const VolumeNode: import("three/src/nodes/TSL.js").FnNode<[import("three/tsl").ProxiedObject<IVoxelMaterialOptions>], Node>;
+144
View File
@@ -0,0 +1,144 @@
import * as THREE from 'three/webgpu';
type TRandomVolumeAroundPipeOptions = {
outerBox: THREE.Box3;
pipeStart: THREE.Vector3;
pipeEnd: THREE.Vector3;
pipeRadius: number;
size?: number;
rangeMin?: number;
rangeMax?: number;
};
/**
* 体积数据工具类
*/
export declare class VolumeTool {
/**
* 线性映射:将值从输入范围映射到输出范围
* @param value 输入值
* @param fromMin 输入范围最小值
* @param fromMax 输入范围最大值
* @param toMin 输出范围最小值(默认0)
* @param toMax 输出范围最大值(默认1)
* @returns 映射后的值
*/
static remap(value: number, fromMin: number, fromMax: number, toMin?: number, toMax?: number): number;
/**
* 生成3D体积数据,使用Simplex噪声算法
* @param options 配置选项
* @param options.x X轴分辨率(可选,如果提供size则忽略)
* @param options.y Y轴分辨率(可选,如果提供size则忽略)
* @param options.z Z轴分辨率(可选,如果提供size则忽略)
* @param options.size 统一分辨率,同时设置x/y/z(可选)
* @param options.rangeMin 数值范围最小值
* @param options.rangeMax 数值范围最大值
* @returns Uint8Array格式的体积数据
*/
static generateVolumeData({ x, y, z, size, rangeMin, rangeMax, }: {
x?: number;
y?: number;
z?: number;
size?: number;
rangeMin: number;
rangeMax: number;
}): Uint8Array;
/**
* 生成3D体积数据并清除外层,使用Simplex噪声算法
* @param options 配置选项
* @param options.x X轴分辨率(可选,如果提供size则忽略)
* @param options.y Y轴分辨率(可选,如果提供size则忽略)
* @param options.z Z轴分辨率(可选,如果提供size则忽略)
* @param options.size 统一分辨率,同时设置x/y/z(默认256)
* @param options.rangeMin 数值范围最小值
* @param options.rangeMax 数值范围最大值
* @param options.clearLayers 要清除的外层层数(默认0)
* @returns Uint8Array格式的体积数据
*/
static generateVolumeDataWithClearLayers({ x, y, z, size, rangeMin, rangeMax, clearLayers }: {
x?: number;
y?: number;
z?: number;
size?: number;
rangeMin: number;
rangeMax: number;
clearLayers?: number;
}): Uint8Array;
/**
* 在指定世界空间坐标周围生成3D噪声值
* @param options 配置选项
* @param options.size 体素空间分辨率(默认256)
* @param options.worldOrigin 世界空间原点 [x, y, z]
* @param options.worldSize 世界空间边长
* @param options.points 世界空间中的点数组,每个点包含位置和影响半径
* @param options.rangeMin 噪声值范围最小值
* @param options.rangeMax 噪声值范围最大值
* @returns Uint8Array格式的体积数据
*/
static generateNoiseAroundPoints({ size, worldOrigin, worldSize, points, rangeMin, rangeMax }: {
size?: number;
worldOrigin: [number, number, number];
worldSize: number;
points: Array<{
position: [number, number, number];
radius: number;
density: number;
}>;
rangeMin: number;
rangeMax: number;
}): Uint8Array;
/**
* 清除体素空间最外层的数据,将其设置为0
* @param options 配置选项
* @param options.data 体素数据
* @param options.width X轴分辨率
* @param options.height Y轴分辨率
* @param options.depth Z轴分辨率
* @param options.layers 要清除的外层层数
*/
static clearOuterLayers({ data, width, height, depth, layers }: {
data: Uint8Array;
width: number;
height: number;
depth: number;
layers: number;
}): void;
/**
* 在内部包围盒中生成随机体积数据
* @param options 配置选项
* @param options.outerBox 外部世界包围盒 {min: [x,y,z], max: [x,y,z]}
* @param options.innerBox 内部世界包围盒 {min: [x,y,z], max: [x,y,z]}
* @param options.size 体素空间分辨率(默认256)
* @param options.rangeMin 随机值范围最小值(默认0)
* @param options.rangeMax 随机值范围最大值(默认255)
* @returns Uint8Array格式的体积数据
*/
static generateRandomVolumeInBox({ outerBox, innerBox, size, rangeMin, rangeMax }: {
outerBox: THREE.Box3;
innerBox: THREE.Box3;
size?: number;
rangeMin?: number;
rangeMax?: number;
}): Uint8Array;
/**
* 在管道周围生成随机体积数据
* @param options 配置选项
* @param options.outerBox 外部世界包围盒
* @param options.pipeStart 管道起点
* @param options.pipeEnd 管道终点
* @param options.pipeRadius 管道半径
* @param options.size 体素空间分辨率(默认256)
* @param options.rangeMin 随机值范围最小值(默认0)
* @param options.rangeMax 随机值范围最大值(默认255)
* @returns Uint8Array格式的体积数据
*/
static generateRandomVolumeAroundPipe({ outerBox, pipeStart, pipeEnd, pipeRadius, size, rangeMin, rangeMax }: TRandomVolumeAroundPipeOptions): Uint8Array;
/**
* 在已有体积数据基础上按管道规则继续生成数据
* @param options 配置选项(与generateRandomVolumeAroundPipe一致)
* @param options.baseData 已有体积数据
* @returns Uint8Array格式的体积数据
*/
static generateRandomVolumeAroundPipeWithBaseData({ outerBox, pipeStart, pipeEnd, pipeRadius, size, rangeMin, rangeMax, baseData }: TRandomVolumeAroundPipeOptions & {
baseData: Uint8Array;
}): Uint8Array;
}
export {};
+4
View File
@@ -0,0 +1,4 @@
export * from './VolumeNode';
export * from "./VolumeTool";
export * from "./PointCloudTool";
export * from "./VolumeMesh.ts";
+39
View File
@@ -0,0 +1,39 @@
/**
* EventManager 事件名称枚举
*/
export declare enum EventManagerEvents {
RAYCAST_PICK = "raycastPick",
RAYCAST_PICK_ALL = "raycastPickAll",
BOX_SELECTION_MOVE = "boxSelectionMove",
BOX_SELECTION_COMPLETE = "boxSelectionComplete"
}
/**
* EventManager 事件映射类型
*/
export type EventManagerEventMap = {
[EventManagerEvents.RAYCAST_PICK]: {
intersects: any[];
object: any;
point: any;
face: any;
distance: any;
};
[EventManagerEvents.RAYCAST_PICK_ALL]: {
intersects: any[];
object: any;
point: any;
face: any;
distance: any;
};
[EventManagerEvents.BOX_SELECTION_MOVE]: [{
data: {
objects: any[];
collection: any;
};
}];
[EventManagerEvents.BOX_SELECTION_COMPLETE]: [{
data: {
objects: any[];
};
}];
};
+19
View File
@@ -0,0 +1,19 @@
import * as THREE from 'three/webgpu';
/**
* SelectionManager 事件名称枚举
*/
export declare enum SelectionManagerEvents {
OBJECT_SELECTED = "objectSelected",
OBJECT_UNSELECTED = "objectUnselected"
}
export interface SelectionManagerEventData {
name: SelectionManagerEvents;
data: THREE.Object3D | null;
}
/**
* SelectionManager 事件映射类型
*/
export type SelectionManagerEventMap = {
[SelectionManagerEvents.OBJECT_SELECTED]: THREE.Object3D | null;
[SelectionManagerEvents.OBJECT_UNSELECTED]: THREE.Object3D | null;
};
+31
View File
@@ -0,0 +1,31 @@
/**
* Viewer 事件名称枚举
*/
export declare enum ViewerEvents {
INIT = "init",
BEFORE_RENDER = "BEFORE_RENDER",
AFTER_RENDER = "AFTER_RENDER",
CAMERA_TYPE_CHANGED = "CAMERA_TYPE_CHANGED"
}
export interface RenderEventData {
data: {
delta: number;
};
name: ViewerEvents;
}
export interface CameraTypeChangedEventData {
type: 'perspective' | 'orthographic';
}
/**
* Viewer 事件映射类型
*/
export type ViewerEventMap = {
[ViewerEvents.INIT]: any;
[ViewerEvents.BEFORE_RENDER]: {
delta: number;
};
[ViewerEvents.AFTER_RENDER]: {
delta: number;
};
[ViewerEvents.CAMERA_TYPE_CHANGED]: CameraTypeChangedEventData;
};
+6
View File
@@ -0,0 +1,6 @@
export { EventManagerEvents } from "./EventManagerEvents";
export type { EventManagerEventMap } from "./EventManagerEvents";
export { SelectionManagerEvents } from "./SelectionManagerEvents";
export type { SelectionManagerEventMap } from "./SelectionManagerEvents";
export { ViewerEvents } from "./ViewerEvents";
export type { ViewerEventMap } from "./ViewerEvents";
+13
View File
@@ -0,0 +1,13 @@
/// <reference path="./types/render-pipeline.d.ts" />
export * from "./core";
export * from "./parametric";
export { ParametricManager } from "./manager/ParametricManager";
export { RangeCullingManager } from "./manager/RangeCullingManager";
export { ClippingPlane } from "./manager/ClippingPlane";
export type { IClippingPlaneOptions } from "./manager/ClippingPlane";
export * from "./tool";
export * from "./mesh";
export * from "./materials";
export * from "./effect";
export * from "./robot";
export * from "./enums";
+64
View File
@@ -0,0 +1,64 @@
import * as THREE from 'three/webgpu';
import { CSS2DObject, CSS2DRenderer } from 'three/examples/jsm/renderers/CSS2DRenderer.js';
import { Viewer } from '../core';
/**
* CSS2D 渲染管理类
* 负责管理 CSS2D 渲染器和 CSS2D 对象
*/
export declare class CSS2DRendererManager {
/** CSS2D 渲染器 */
renderer: CSS2DRenderer;
/** 视图实例 */
viewer: Viewer;
/** CSS2D 对象集合 */
objects: Map<string, CSS2DObject>;
/**
* 构造函数
* @param viewer - 视图实例
*/
constructor(viewer: Viewer);
/**
* 初始化 CSS2D 渲染器
*/
init(): void;
/**
* 处理窗口大小变化
*/
handleResize(): void;
/**
* 创建 CSS2D 对象
* @param element - DOM 元素
* @param position - 位置
* @returns CSS2D 对象
*/
createObject(element: HTMLElement, position: THREE.Vector3): CSS2DObject;
/**
* 添加 CSS2D 对象到场景
* @param object - CSS2D 对象
* @param parent - 父对象,默认为场景
*/
addObject(object: CSS2DObject, parent?: THREE.Object3D): void;
/**
* 从场景中移除 CSS2D 对象
* @param object - CSS2D 对象
*/
removeObject(object: CSS2DObject): void;
/**
* 渲染 CSS2D 场景
*/
render(): void;
/**
* 清理资源
*/
dispose(): void;
/**
* 获取 CSS2D 渲染器实例
* @returns CSS2D 渲染器
*/
getRenderer(): CSS2DRenderer;
/**
* 获取所有 CSS2D 对象
* @returns CSS2D 对象数组
*/
getObjects(): CSS2DObject[];
}
+71
View File
@@ -0,0 +1,71 @@
import * as THREE from 'three/webgpu';
import { CSS3DObject, CSS3DRenderer, CSS3DSprite } from 'three/examples/jsm/renderers/CSS3DRenderer.js';
import { Viewer } from '../core';
/**
* CSS3D 渲染管理类
* 负责管理 CSS3D 渲染器和 CSS3D 对象
*/
export declare class CSS3DRendererManager {
/** CSS3D 渲染器 */
renderer: CSS3DRenderer;
/** 视图实例 */
viewer: Viewer;
/** CSS3D 对象集合 */
objects: Map<string, CSS3DObject | CSS3DSprite>;
/**
* 构造函数
* @param viewer - 视图实例
*/
constructor(viewer: Viewer);
/**
* 初始化 CSS3D 渲染器
*/
init(): void;
/**
* 处理窗口大小变化
*/
handleResize(): void;
/**
* 创建 CSS3D 对象
* @param element - DOM 元素
* @param position - 位置
* @returns CSS3D 对象
*/
createObject(element: HTMLElement, position: THREE.Vector3): CSS3DObject;
/**
* 创建 CSS3D 精灵
* @param element - DOM 元素
* @param position - 位置
* @returns CSS3D 精灵
*/
createSprite(element: HTMLElement, position: THREE.Vector3): CSS3DSprite;
/**
* 添加 CSS3D 对象到场景
* @param object - CSS3D 对象或精灵
* @param parent - 父对象,默认为场景
*/
addObject(object: CSS3DObject | CSS3DSprite, parent?: THREE.Object3D): void;
/**
* 从场景中移除 CSS3D 对象
* @param object - CSS3D 对象或精灵
*/
removeObject(object: CSS3DObject | CSS3DSprite): void;
/**
* 渲染 CSS3D 场景
*/
render(): void;
/**
* 清理资源
*/
dispose(): void;
/**
* 获取 CSS3D 渲染器实例
* @returns CSS3D 渲染器
*/
getRenderer(): CSS3DRenderer;
/**
* 获取所有 CSS3D 对象
* @returns CSS3D 对象数组
*/
getObjects(): Array<CSS3DObject | CSS3DSprite>;
}
+75
View File
@@ -0,0 +1,75 @@
import * as THREE from 'three/webgpu';
import Emittery from 'emittery';
import { Viewer } from '../core';
import { ClippingPlane, type IClippingPlaneOptions } from './ClippingPlane.ts';
/**
* 剖切管理器
* 管理剖切组和任意数量的剖切面(通过 addPlane 手动创建)
*/
export declare class ClippingManager {
static panelCounter: number;
emitter: Emittery<{
clippingStart: undefined;
clippingEnd: undefined;
}, {
clippingStart: undefined;
clippingEnd: undefined;
} & import("emittery").OmnipresentEventData, import("emittery").DatalessEventNames<{
clippingStart: undefined;
clippingEnd: undefined;
}>>;
/** 剖切是否已开始 */
isClipping: boolean;
/** 所有注册的剖切平面(THREE.Plane),同步到 clippingGroup */
clippingPlanes: THREE.Plane[];
/** 已废弃的辅助对象数组(保留以防外部引用) */
clippingPlaneHelpers: THREE.PlaneHelper[];
clippingGroup: THREE.ClippingGroup;
scene: THREE.Scene;
viewer: Viewer;
/** 平面辅助对象组 */
planeHelperGroup: THREE.Group;
/** 管理的剖切面 Map */
private planes;
constructor(viewer: Viewer);
/**
* 创建默认的 X / Y / Z 三个剖切面
* @returns [planeX, planeY, planeZ]
*/
addDefaultPlanes(): [ClippingPlane, ClippingPlane, ClippingPlane];
/**
* 创建并注册一个剖切面
* @param id 唯一标识
* @param options 剖切面配置
*/
addPlane(id: string, options: IClippingPlaneOptions): ClippingPlane;
/**
* 移除剖切面
*/
removePlane(id: string): void;
/**
* 获取剖切面
*/
getPlane(id: string): ClippingPlane | undefined;
/**
* 根据剖切组包围盒自动定位 X/Y/Z 三个剖切面
* 必须先调用 addDefaultPlanes() 注册剖切面
* @param offset 从包围盒 min 边的偏移量
*/
autoPlanePosition(offset?: number): void;
addClippingObjectsByUuid(uuids: Array<string>): void;
addClippingObjects(objects: Array<THREE.Object3D>): void;
addClippingToObject(object: THREE.Object3D): void;
removeClippingObjectsByUuid(uuids: Array<string>): void;
clearClippingGroups(): void;
clearClippingPlanes(): void;
hideClippingPlanes(): void;
computeBoundingBox(): THREE.Box3;
/**
* 创建调试面板
*/
createDebugPanel(clippingObjects?: THREE.Object3D[]): void;
startClipping(): void;
stopClipping(): void;
dispose(): void;
}
+145
View File
@@ -0,0 +1,145 @@
import * as THREE from "three/webgpu";
import { TransformControls } from "three/addons/controls/TransformControls.js";
import Emittery from "emittery";
import type { Viewer } from "../core";
import { ClippingHelper } from "../mesh/ClippingHelper.ts";
export interface IClippingPlaneOptions {
normal: THREE.Vector3;
constant?: number;
color?: THREE.Color;
enableTransformControls?: boolean;
transformMode?: "translate" | "rotate";
}
export declare class ClippingPlane {
plane: THREE.Plane;
helper: ClippingHelper | undefined;
transformControl: TransformControls | undefined;
emitter: Emittery<{
move: {
position: THREE.Vector3;
constant: number;
normal: THREE.Vector3;
};
}, {
move: {
position: THREE.Vector3;
constant: number;
normal: THREE.Vector3;
};
} & import("emittery").OmnipresentEventData, never>;
readonly viewer: Viewer;
readonly options: IClippingPlaneOptions;
/**
* 平移时锁定的世界轴
*/
private readonly lockedTranslateAxis;
/** 旋转手柄是否已启用 */
private rotateHandlesEnabled;
/** 当前正在拖拽的旋转手柄 Sprite */
private activeRotateHandle;
/** 拖拽开始时的屏幕坐标 */
private dragStartScreenPos;
/** 射线检测器 */
private raycaster;
/** 鼠标/指针当前归一化坐标 */
private pointer;
/** 旋转手柄拖拽事件监听器(用于移除) */
private onPointerDownBound;
private onPointerMoveBound;
private onPointerUpBound;
/**
* 创建剖切平面实例
* @param viewer 视图实例
* @param options 剖切面配置
*/
constructor(viewer: Viewer, options: IClippingPlaneOptions);
/**
* 根据 helper 当前姿态回写 plane
*/
updatePlaneFromHelper(): void;
/**
* 创建 ClippingHelper,定位到指定世界坐标,并加入 group
* @param worldPosition 平面中心世界坐标
* @param size helper 的宽高
* @param group 要加入的父级 Group
*/
createHelper(worldPosition: THREE.Vector3, size: number, group: THREE.Group): void;
/**
* 解绑辅助对象
*/
detach(): void;
/**
* 设置变换模式
* @param mode 变换模式
*/
setTransformMode(mode: "translate" | "rotate"): void;
/**
* 设置变换空间并同步刷新轴约束
* @param space 变换空间
* @returns void
*/
setTransformSpace(space: "world" | "local"): void;
/**
* 创建调试面板,支持移动/旋转切换及 XYZ 数值控制
* @param label 面板标题
*/
createDebugPanel(label?: string): void;
/**
* 显示或隐藏旋转控制手柄图标。
* 首次调用 true 时会懒加载图标贴图;设为 false 时隐藏图标。
* @param show 是否显示旋转手柄
*/
showRotateHandles(show: boolean): void;
/**
* 释放资源
*/
dispose(): void;
/**
* 初始化变换控件
*/
private initTransformControl;
/**
* 根据法线向量解析应锁定的平移轴
* 规则为取绝对值最大的分量对应轴
* @param normal 剖切面法线向量
* @returns 锁定的世界轴
*/
private resolveLockedTranslateAxis;
/**
* 应用平移轴约束
* translate 模式只保留一个轴,其余轴禁用
* local 空间保留 gizmo 自身坐标轴显示
* world 空间使用 normal 对应的世界轴
* rotate 模式保留三个轴
* @param transformControl 变换控件实例
*/
private applyTranslateAxisConstraint;
/**
* 将屏幕 pointerEvent 坐标转换为 NDC
*/
private toNDC;
/**
* 获取当前 helper 中所有可见的旋转手柄
*/
private getVisibleHandles;
/**
* 指针按下:检测是否命中旋转手柄
*/
private onHandlePointerDown;
/**
* 指针移动:根据拖拽增量旋转 helper
* - 上方手柄(rotateAxis=x):水平拖拽 → 绕局部 Y;垂直拖拽 → 绕局部 X
* - 右方手柄(rotateAxis=y):水平拖拽 → 绕局部 Y;垂直拖拽 → 绕局部 X
*/
private onHandlePointerMove;
/**
* 在 helper 的局部空间中围绕指定轴旋转
* @param localAxis 局部旋转轴(单位向量)
* @param angle 旋转弧度
*/
private rotateHelperLocal;
/**
* 指针抬起:结束拖拽
*/
private onHandlePointerUp;
}
+81
View File
@@ -0,0 +1,81 @@
import { Camera, Object3D, Raycaster, Scene, Vector2 } from 'three/webgpu';
import { SelectionBox } from 'three/examples/jsm/interactive/SelectionBox.js';
import { SelectionHelper } from 'three/examples/jsm/interactive/SelectionHelper.js';
import Emittery from 'emittery';
import type { Viewer } from "../core/Viewer.ts";
import type { EventManagerEventMap } from "../enums/EventManagerEvents.ts";
/**
* 事件管理器
* 继承自 Emittery,提供事件的订阅、取消订阅和触发功能
*/
export declare class EventManager extends Emittery<EventManagerEventMap> {
#private;
raycaster: Raycaster;
mouse: Vector2;
camera: Camera | null;
scene: Scene | null;
filterList: Object3D[];
onDownPosition: Vector2;
onUpPosition: Vector2;
selectionBox: SelectionBox | null;
selectionHelper: SelectionHelper | null;
boxSelectionEnabled: boolean;
viewer: Viewer;
constructor(viewer: Viewer);
get enableClick(): boolean;
set enableClick(value: boolean);
/**
* 禁用射线选择功能
*/
disableRaycast(): void;
/**
* 添加对象到过滤列表(这些对象不会被射线选中)
* @param object - 要过滤的对象
*/
addToFilterList(object: Object3D): void;
/**
* 从过滤列表中移除对象
* @param object - 要移除的对象
*/
removeFromFilterList(object: Object3D): void;
/**
* 清空过滤列表
*/
clearFilterList(): void;
/**
* 获取鼠标在视口中的位置
*/
getMousePosition(dom: HTMLElement, x: number, y: number): [number, number];
/**
* 处理点击事件
*/
handleClick(): void;
/**
* 鼠标按下事件处理
*/
onMouseDown: (event: MouseEvent) => void;
/**
* 鼠标释放事件处理
*/
onMouseUp: (event: MouseEvent) => void;
/**
* 启用框选功能
*/
enableBoxSelection(): void;
/**
* 禁用框选功能
*/
disableBoxSelection(): void;
/**
* 框选开始事件处理
*/
onBoxSelectionStart: (event: PointerEvent) => void;
/**
* 框选移动事件处理
*/
onBoxSelectionMove: (event: PointerEvent) => void;
/**
* 框选结束事件处理
*/
onBoxSelectionEnd: (event: PointerEvent) => void;
}
+59
View File
@@ -0,0 +1,59 @@
import * as THREE from 'three/webgpu';
import { Icon } from '../mesh/Icon.ts';
/**
* 图标管理类 - 通过精灵图(Sprite)添加和删除图标
*/
export declare class IconManager {
scene: THREE.Scene;
icons: Map<string, THREE.Sprite>;
textureLoader: THREE.TextureLoader;
/**
* 构造函数
* @param scene Three.js场景实例
*/
constructor(scene: THREE.Scene);
/**
* 添加图标
* @param iconOrId 图标实例或图标唯一标识
* @param textureUrl 精灵图纹理URL(当第一个参数是ID时使用)
* @param position 图标位置(当第一个参数是ID时使用)
* @param size 图标大小(当第一个参数是ID时使用)
* @returns 添加的精灵图实例
*/
addIcon(iconOrId: Icon | string, textureUrl?: string, position?: THREE.Vector3, size?: number): THREE.Sprite;
/**
* 删除图标
* @param id 图标唯一标识
* @returns 是否删除成功
*/
removeIcon(id: string): boolean;
/**
* 获取图标
* @param id 图标唯一标识
* @returns 精灵图实例或undefined
*/
getIcon(id: string): THREE.Sprite | undefined;
/**
* 获取所有图标
* @returns 图标ID和精灵图实例的映射
*/
getAllIcons(): Map<string, THREE.Sprite>;
/**
* 更新图标位置
* @param id 图标唯一标识
* @param position 新位置
* @returns 是否更新成功
*/
updateIconPosition(id: string, position: THREE.Vector3): boolean;
/**
* 更新图标大小
* @param id 图标唯一标识
* @param size 新大小
* @returns 是否更新成功
*/
updateIconSize(id: string, size: number): boolean;
/**
* 清除所有图标
*/
clearAllIcons(): void;
}
+64
View File
@@ -0,0 +1,64 @@
import * as THREE from 'three/webgpu';
import type { ICubeData } from '../mesh/CubePanel.ts';
import { CubePanel } from '../mesh/CubePanel.ts';
/**
* 面板管理器配置选项
*/
export interface IPanelManagerOptions {
/** 面板大小 */
size?: number;
/** 小正方体大小 */
cubeSize?: number;
/** 小正方体间距 */
cubeGap?: number;
/** 面板位置偏移 */
panelOffset?: number;
/** 初始数据 */
initialData?: {
[face: string]: ICubeData[][];
};
}
/**
* 面板管理器
* 管理六个面的立方体面板
*/
export declare class PanelManager {
/** 主组对象 */
group: THREE.Group;
/** 面板映射 */
panels: Map<string, CubePanel>;
/** 配置选项 */
options: Required<IPanelManagerOptions>;
/**
* 创建面板管理器
* @param options - 配置选项
*/
constructor(options?: IPanelManagerOptions);
/**
* 初始化六个面
*/
initPanels(): void;
/**
* 获取指定面板
* @param name - 面板名称
* @returns 面板对象
*/
getPanel(name: string): CubePanel | undefined;
/**
* 设置指定面板的数据
* @param name - 面板名称
* @param data - 面板数据
*/
setPanelData(name: string, data: ICubeData[][]): void;
/**
* 批量设置所有面板数据
* @param data - 所有面板数据
*/
setAllPanelsData(data: {
[face: string]: ICubeData[][];
}): void;
/**
* 销毁面板管理器
*/
dispose(): void;
}
+169
View File
@@ -0,0 +1,169 @@
import type { ParametricBox } from '../parametric/ParametricBox.ts';
import type { ParametricCylinder } from '../parametric/ParametricCylinder.ts';
import type { ParametricSphere } from '../parametric/ParametricSphere.ts';
import type { ParametricPipe } from '../parametric/ParametricPipe.ts';
import { ParametricArch } from "../parametric";
/**
* 参数化对象管理器
* 管理所有参数化几何体实例,提供统一的查找和管理接口
*/
export declare class ParametricManager {
/** 所有 Box 实例 */
boxes: ParametricBox[];
/** 所有 Cylinder 实例 */
cylinders: ParametricCylinder[];
/** 所有 Sphere 实例 */
spheres: ParametricSphere[];
/** 所有 Arch 实例 */
arches: ParametricArch[];
/** 所有 Pipe 实例 */
pipes: ParametricPipe[];
/**
* 添加 Box 实例
*/
addBox(box: ParametricBox): void;
/**
* 移除 Box 实例
*/
removeBox(box: ParametricBox): void;
/**
* 添加 Cylinder 实例
*/
addCylinder(cylinder: ParametricCylinder): void;
/**
* 移除 Cylinder 实例
*/
removeCylinder(cylinder: ParametricCylinder): void;
/**
* 添加 Sphere 实例
*/
addSphere(sphere: ParametricSphere): void;
/**
* 移除 Sphere 实例
*/
removeSphere(sphere: ParametricSphere): void;
/**
* 添加 Arch 实例
*/
addArch(arch: ParametricArch): void;
/**
* 移除 Arch 实例
*/
removeArch(arch: ParametricArch): void;
/**
* 添加 Pipe 实例
*/
addPipe(pipe: ParametricPipe): void;
/**
* 移除 Pipe 实例
*/
removePipe(pipe: ParametricPipe): void;
/**
* 查找第一个符合条件的 Pipe
* @param predicate - 过滤条件函数
* @returns 找到的 Pipe 实例或 null
*/
findPipe(predicate: (pipe: ParametricPipe) => boolean): ParametricPipe | null;
/**
* 查找所有符合条件的 Pipe
* @param predicate - 过滤条件函数
* @returns 符合条件的 Pipe 实例数组
*/
findAllPipes(predicate: (pipe: ParametricPipe) => boolean): ParametricPipe[];
/**
* 根据 metadata 查找 Pipe
* @param key - metadata 的键
* @param value - metadata 的值
* @returns 找到的 Pipe 实例或 null
*/
findPipeByMetadata(key: string, value: any): ParametricPipe | null;
/**
* 根据 metadata 查找所有 Pipe
* @param key - metadata 的键
* @param value - metadata 的值
* @returns 符合条件的 Pipe 实例数组
*/
findAllPipesByMetadata(key: string, value: any): ParametricPipe[];
/**
* 根据名称查找 Pipe
* @param name - mesh 的名称
* @returns 找到的 Pipe 实例或 null
*/
findPipeByName(name: string): ParametricPipe | null;
/**
* 查找第一个符合条件的 Box
* @param predicate - 过滤条件函数
* @returns 找到的 Box 实例或 null
*/
findBox(predicate: (box: ParametricBox) => boolean): ParametricBox | null;
/**
* 查找所有符合条件的 Box
* @param predicate - 过滤条件函数
* @returns 符合条件的 Box 实例数组
*/
findAllBoxes(predicate: (box: ParametricBox) => boolean): ParametricBox[];
/**
* 查找第一个符合条件的 Cylinder
* @param predicate - 过滤条件函数
* @returns 找到的 Cylinder 实例或 null
*/
findCylinder(predicate: (cylinder: ParametricCylinder) => boolean): ParametricCylinder | null;
/**
* 查找所有符合条件的 Cylinder
* @param predicate - 过滤条件函数
* @returns 符合条件的 Cylinder 实例数组
*/
findAllCylinders(predicate: (cylinder: ParametricCylinder) => boolean): ParametricCylinder[];
/**
* 查找第一个符合条件的 Sphere
* @param predicate - 过滤条件函数
* @returns 找到的 Sphere 实例或 null
*/
findSphere(predicate: (sphere: ParametricSphere) => boolean): ParametricSphere | null;
/**
* 查找所有符合条件的 Sphere
* @param predicate - 过滤条件函数
* @returns 符合条件的 Sphere 实例数组
*/
findAllSpheres(predicate: (sphere: ParametricSphere) => boolean): ParametricSphere[];
/**
* 查找第一个符合条件的 Arch
* @param predicate - 过滤条件函数
* @returns 找到的 Arch 实例或 null
*/
findArch(predicate: (arch: ParametricArch) => boolean): ParametricArch | null;
/**
* 查找所有符合条件的 Arch
* @param predicate - 过滤条件函数
* @returns 符合条件的 Arch 实例数组
*/
findAllArches(predicate: (arch: ParametricArch) => boolean): ParametricArch[];
/**
* 清空所有 Box 实例
*/
clearBoxes(): void;
/**
* 清空所有 Cylinder 实例
*/
clearCylinders(): void;
/**
* 清空所有 Sphere 实例
*/
clearSpheres(): void;
/**
* 清空所有 Arch 实例
*/
clearArches(): void;
/**
* 清空所有 Pipe 实例
*/
clearPipes(): void;
/**
* 清空所有参数化对象
*/
clearAll(): void;
/**
* 获取所有参数化对象的总数
*/
getTotalCount(): number;
}
+164
View File
@@ -0,0 +1,164 @@
import * as THREE from 'three/webgpu';
import { OutlinePass } from '../passes/OutlinePass.ts';
import { BloomPass } from '../passes/BloomPass.ts';
import { Viewer } from '../core/Viewer.ts';
/**
* 管线管理器
* 用于管理渲染管线效果,如描边、Bloom 等
*/
export declare class PipelineManager {
renderer: THREE.WebGPURenderer;
scene: THREE.Scene;
sceneHelpers: THREE.Scene;
outlinePass: OutlinePass;
bloomPass: BloomPass;
enableOutline: boolean;
enableBloom: boolean;
private perspectiveRenderPipeline;
private orthographicRenderPipeline;
private viewer;
/**
* 构造函数
* @param viewer - Viewer 实例
*/
constructor(viewer: Viewer);
/** 获取当前激活的渲染管线 */
get renderPipeline(): THREE.RenderPipeline | null;
/**
* 初始化管线管理器
*/
init(): void;
/**
* 更新相机引用
* 当相机类型切换时调用
*/
updateCamera(): void;
/**
* 更新渲染管道
*/
updateRenderPipeline(): void;
/**
* 渲染场景
*/
render(): void;
/**
* 添加要描边的对象
* @param object - 要添加的对象
*/
addSelectedObject(object: THREE.Object3D): void;
/**
* 移除要描边的对象
* @param object - 要移除的对象
*/
removeSelectedObject(object: THREE.Object3D): void;
/**
* 清空所有要描边的对象
*/
clearSelectedObjects(): void;
/**
* 设置描边强度
* @param value - 描边强度值
*/
setEdgeStrength(value: number): void;
/**
* 设置描边 glow 效果
* @param value - glow 效果值
*/
setEdgeGlow(value: number): void;
/**
* 设置描边厚度
* @param value - 描边厚度值
*/
setEdgeThickness(value: number): void;
/**
* 设置描边脉冲周期
* @param value - 脉冲周期值
*/
setPulsePeriod(value: number): void;
/**
* 设置可见边的颜色
* @param color - 颜色值
*/
setVisibleEdgeColor(color: THREE.Color): void;
/**
* 设置隐藏边的颜色
* @param color - 颜色值
*/
setHiddenEdgeColor(color: THREE.Color): void;
/**
* 设置 Bloom 阈值
* @param value - 阈值,范围 0.0 到 1.0
*/
setBloomThreshold(value: number): void;
/**
* 设置 Bloom 强度
* @param value - 强度,范围 0.0 到 3.0
*/
setBloomStrength(value: number): void;
/**
* 设置 Bloom 半径
* @param value - 半径,范围 0.0 到 1.0
*/
setBloomRadius(value: number): void;
/**
* 启用或禁用描边效果
* @param enabled - 是否启用
*/
setOutlineEnabled(enabled: boolean): void;
/**
* 启用或禁用 Bloom 效果
* @param enabled - 是否启用
*/
setBloomEnabled(enabled: boolean): void;
/**
* 获取当前选中的对象列表
* @returns 选中的对象列表
*/
getSelectedObjects(): THREE.Object3D[];
/**
* 检查对象是否在描边列表中
* @param object - 要检查的对象
* @returns 是否在描边列表中
*/
isObjectInOutlineList(object: THREE.Object3D): boolean;
/**
* 添加要高亮的对象
* @param object - 要高亮的对象
* @param highlightColor - 高亮颜色,默认为绿色 (0, 1, 0)
*/
addHighlightedObject(object: THREE.Object3D, highlightColor?: THREE.Color): void;
/**
* 移除要高亮的对象
* @param object - 要移除的对象
*/
removeHighlightedObject(object: THREE.Object3D): void;
/**
* 清空所有要高亮的对象
*/
clearHighlightedObjects(): void;
/**
* 检查对象是否在高亮列表中
* @param object - 要检查的对象
* @returns 是否在高亮列表中
*/
isObjectInBloomList(object: THREE.Object3D): boolean;
/**
* 获取描边通道实例
* @returns 描边通道实例
*/
getOutlinePass(): OutlinePass;
/**
* 获取 Bloom 通道实例
* @returns Bloom 通道实例
*/
getBloomPass(): BloomPass;
/**
* 销毁管线管理器
*/
dispose(): void;
/**
* 创建渲染管道
* @param camera - 相机
*/
private createRenderPipeline;
}
+16
View File
@@ -0,0 +1,16 @@
import * as THREE from 'three/webgpu';
import { Viewer } from "../core";
/**
* 范围剔除管理器
*/
export declare class RangeCullingManager extends THREE.ClippingGroup {
viewer: Viewer;
name: string;
constructor(viewer: Viewer);
init(mesh: THREE.Mesh): void;
/**
* 根据普通 mesh 的包围盒生成 6 个剔除平面
* @param mesh 要计算包围盒的 mesh
*/
generateClippingPlanesFromMesh(mesh: THREE.Mesh): void;
}
+110
View File
@@ -0,0 +1,110 @@
import * as THREE from "three";
import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader.js";
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";
/**
* 资源类型
*/
export declare enum ResourceType {
/** 纹理 */
TEXTURE = "texture",
/** 材质 */
MATERIAL = "material",
/** 几何体 */
GEOMETRY = "geometry",
/** 模型 */
MODEL = "model",
/** 原始数据 */
RAW_DATA = "raw_data"
}
/**
* 资源加载进度信息
*/
export interface ILoadProgress {
/** 已加载的字节数 */
loaded: number;
/** 总字节数 */
total: number;
/** 加载进度百分比 (0-100) */
progress: number;
}
/**
* 资源管理器
* 负责加载、缓存和管理三维资源
*/
export declare class ResourceManager {
cache: Map<string, unknown>;
textureLoader: THREE.TextureLoader;
fbxLoader: FBXLoader;
gltfLoader: GLTFLoader;
fileLoader: THREE.FileLoader;
loadingManager: THREE.LoadingManager;
constructor();
/**
* 创建 GLTF 加载器
* @param manager - 加载管理器
* @returns GLTF 加载器实例
*/
createGLTFLoader(manager?: THREE.LoadingManager): GLTFLoader;
/**
* 加载纹理
* @param url - 纹理文件路径
* @param onProgress - 加载进度回调
* @returns 纹理对象
*/
loadTexture(url: string, onProgress?: (progress: ILoadProgress) => void): Promise<THREE.Texture>;
/**
* 加载 FBX 模型
* @param url - FBX 文件路径
* @param onProgress - 加载进度回调
* @returns FBX 模型对象 (Group)
*/
loadFBX(url: string, onProgress?: (progress: ILoadProgress) => void): Promise<THREE.Group>;
/**
* 加载 GLTF 模型
* @param url - GLTF 文件路径
* @param onProgress - 加载进度回调
* @returns GLTF 模型对象
*/
loadGLTF(url: string, onProgress?: (progress: ILoadProgress) => void): Promise<THREE.Object3D>;
/**
* 加载原始二进制数据
* @param url - 原始数据文件路径
* @param onProgress - 加载进度回调
* @returns ArrayBuffer 数据
*/
loadRawData(url: string, onProgress?: (progress: ILoadProgress) => void): Promise<ArrayBuffer>;
/**
* 从缓存中获取资源
* @param type - 资源类型
* @param key - 资源键名
* @returns 资源对象,如果不存在则返回 undefined
*/
get<T = unknown>(type: ResourceType, key: string): T | undefined;
/**
* 检查资源是否存在于缓存中
* @param type - 资源类型
* @param key - 资源键名
* @returns 是否存在
*/
has(type: ResourceType, key: string): boolean;
/**
* 从缓存中移除资源
* @param type - 资源类型
* @param key - 资源键名
* @returns 是否成功移除
*/
remove(type: ResourceType, key: string): boolean;
/**
* 清空所有缓存
*/
clear(): void;
/**
* 获取缓存大小
* @returns 缓存中的资源数量
*/
getCacheSize(): number;
/**
* 销毁资源管理器
*/
dispose(): void;
}
+158
View File
@@ -0,0 +1,158 @@
import * as THREE from 'three/webgpu';
import type { Viewer } from "../core/Viewer.ts";
/**
* 破裂事件数据接口
*/
export interface RuptureEvent {
position: {
x: number;
y: number;
z: number;
};
time: number;
energy: number;
}
/**
* 破裂事件配置接口
*/
export interface RuptureEventConfig {
minRadius?: number;
maxRadius?: number;
minEnergy?: number;
maxEnergy?: number;
mappingType?: 'linear' | 'logarithmic';
crackModelUrls?: string[];
crackBaseScale?: number;
}
/**
* 破裂事件管理类
* 通过球体可视化破裂事件,球体大小表示能量,颜色表示时间序列
*/
export declare class RuptureEventManager {
viewer: Viewer;
scene: THREE.Scene;
events: Map<number, {
event: RuptureEvent;
mesh: THREE.Mesh;
crackModel?: THREE.Group;
}>;
config: Required<RuptureEventConfig>;
minTime: number;
maxTime: number;
crackModels: THREE.Group[];
isLoadingModels: boolean;
/**
* 构造函数
* @param viewer Viewer实例
* @param config 配置选项
*/
constructor(viewer: Viewer, config?: RuptureEventConfig);
/**
* 预加载裂缝模型
*/
loadCrackModels(): Promise<void>;
/**
* 为破裂球创建裂缝模型
* @param event 破裂事件数据
* @param radius 球体半径
* @returns 裂缝模型实例
*/
createCrackModel(event: RuptureEvent, radius: number): THREE.Group | undefined;
/**
* 添加单个破裂事件
* @param event 破裂事件数据
* @returns 创建的球体网格
*/
addEvent(event: RuptureEvent): THREE.Mesh;
/**
* 批量添加破裂事件
* @param events 破裂事件数组
* @returns 创建的球体网格数组
*/
addEvents(events: RuptureEvent[]): THREE.Mesh[];
/**
* 删除破裂事件
* @param time 事件时间戳
* @returns 是否删除成功
*/
removeEvent(time: number): boolean;
/**
* 清空所有破裂事件
*/
clearEvents(): void;
/**
* 根据时间窗口和能量阈值过滤事件
* @param recentMinutes 最近N分钟(null表示不过滤)
* @param energyThreshold 能量阈值(null表示不过滤)
*/
applyFilter(recentMinutes: number | null, energyThreshold: number | null): void;
/**
* 取消过滤,显示所有事件
*/
cancelFilter(): void;
/**
* 获取事件
* @param time 事件时间戳
* @returns 事件数据、网格和裂缝模型
*/
getEvent(time: number): {
event: RuptureEvent;
mesh: THREE.Mesh;
crackModel?: THREE.Group;
} | undefined;
/**
* 获取所有事件
* @returns 所有事件的Map
*/
getAllEvents(): Map<number, {
event: RuptureEvent;
mesh: THREE.Mesh;
crackModel?: THREE.Group;
}>;
/**
* 获取当前显示的事件数量
* @returns 可见事件数量
*/
getVisibleEventCount(): number;
/**
* 获取总事件数量
* @returns 总事件数量
*/
getTotalEventCount(): number;
/**
* 更新配置
* @param config 新配置
*/
updateConfig(config: Partial<RuptureEventConfig>): void;
/**
* 创建事件球体
* @param event 破裂事件数据
* @returns 球体网格
*/
createEventSphere(event: RuptureEvent): THREE.Mesh;
/**
* 将能量映射到半径
* @param energy 能量值
* @returns 半径值
*/
mapEnergyToRadius(energy: number): number;
/**
* 将时间映射到颜色(蓝 → 黄 → 红)
* @param time 时间戳
* @returns 颜色
*/
mapTimeToColor(time: number): THREE.Color;
/**
* 更新时间范围
* @param time 时间戳
*/
updateTimeRange(time: number): void;
/**
* 重新计算时间范围
*/
recalculateTimeRange(): void;
/**
* 更新所有事件的颜色
*/
updateAllColors(): void;
}
+88
View File
@@ -0,0 +1,88 @@
import { Box3, Box3Helper, Camera, Object3D, Scene } from 'three/webgpu';
import { TransformControls } from 'three/addons/controls/TransformControls.js';
import { EventManager } from './EventManager.ts';
import { Viewer } from '../core/Viewer.ts';
import Emittery from 'emittery';
import type { SelectionManagerEventMap } from '../enums/SelectionManagerEvents.ts';
import { Euler, Vector3 } from "three";
/**
* 选择管理器
* 用于管理场景中物体的选择状态
*/
export declare class SelectionManager extends Emittery<SelectionManagerEventMap> {
#private;
selectedObject: Object3D | null;
scene: Scene;
eventManager: EventManager;
viewer: Viewer;
selectionBox: Box3Helper;
box: Box3;
camera: Camera;
sceneHelpers: Scene;
transformControls: TransformControls;
objectPositionOnDown: Vector3;
objectRotationOnDown: Euler;
objectScaleOnDown: Vector3;
/**
* 构造函数
* @param viewer - Viewer 实例
*/
constructor(viewer: Viewer);
get isControl(): boolean;
set isControl(value: boolean);
/**
* 初始化选择管理器
*/
init(): void;
initSelectionBox(): void;
initTransformControls(): void;
startControl(): void;
endControl(): void;
/**
* 设置选择的物体
* @param object - 要选择的物体
*/
setSelectedObject(object: Object3D | null | undefined): void;
/**
* 取消选择
*/
clearSelection(): void;
/**
* 通过 UUID 设置选择的模型
* @param uuid - 模型的 UUID
*/
selectObjectByUuid(uuid: string): void;
/**
* 获取当前选中的物体
* @returns 当前选中的物体,如果没有选中则返回 null
*/
getSelectedObject(): Object3D | null;
/**
* 设置控制模式
* @param mode 控制模式:'translate', 'rotate', 'scale'
*/
setTransformMode(mode: 'translate' | 'rotate' | 'scale'): void;
/**
* 获取当前被控制的模型
*/
getControlledObject(): Object3D | null;
/**
* 连接到渲染器的 DOM 元素
* @param domElement 渲染器的 DOM 元素
*/
connect(domElement: HTMLElement): void;
/**
* 设置变换空间
* @param space 空间:'world' 或 'local'
*/
setSpace(space: 'world' | 'local'): void;
/**
* 设置平移捕捉
* @param snap 捕捉距离
*/
setTranslationSnap(snap: number): void;
/**
* 销毁选择管理器
*/
dispose(): void;
}
+29
View File
@@ -0,0 +1,29 @@
import * as THREE from 'three/webgpu';
/**
* 岩石材质基类
* 提供纹理加载和材质创建的通用功能
*/
export declare class MaterialFactory {
/**
* 配置纹理属性
* @param texture - 要配置的纹理
*/
static configureTexture(texture: THREE.Texture): void;
/**
* 创建岩石材质
* @param baseUrl - 纹理基础URL
* @param textureFiles - 纹理文件名配置
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
protected static createMaterial(baseUrl: string, textureFiles: {
map: string;
roughness?: string;
metalness?: string;
arm?: string;
ao?: string;
displacement?: string;
normal?: string;
}, options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
}
+21
View File
@@ -0,0 +1,21 @@
import * as THREE from 'three/webgpu';
import { MaterialFactory } from './MaterialFactory.ts';
/**
* 岩石材质类(rock1
*/
export declare class Rock1Material extends MaterialFactory {
/**
* 创建岩石材质(rock1)
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
static create(options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
}
/**
* 创建岩石材质(rock1)的便捷函数
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
export declare function createRock1Material(options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
+21
View File
@@ -0,0 +1,21 @@
import * as THREE from 'three/webgpu';
import { MaterialFactory } from './MaterialFactory.ts';
/**
* 岩石材质类(rock2
*/
export declare class Rock2Material extends MaterialFactory {
/**
* 创建岩石材质(rock2)
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
static create(options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
}
/**
* 创建岩石材质(rock2)的便捷函数
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
export declare function createRock2Material(options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
+21
View File
@@ -0,0 +1,21 @@
import * as THREE from 'three/webgpu';
import { MaterialFactory } from './MaterialFactory.ts';
/**
* 岩石材质类(rock3
*/
export declare class Rock3Material extends MaterialFactory {
/**
* 创建岩石材质(rock3)
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
static create(options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
}
/**
* 创建岩石材质(rock3)的便捷函数
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
export declare function createRock3Material(options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
+21
View File
@@ -0,0 +1,21 @@
import * as THREE from 'three/webgpu';
import { MaterialFactory } from './MaterialFactory.ts';
/**
* 岩石材质类(rock4
*/
export declare class Rock4Material extends MaterialFactory {
/**
* 创建岩石材质(rock4)
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
static create(options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
}
/**
* 创建岩石材质(rock4)的便捷函数
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
export declare function createRock4Material(options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
+21
View File
@@ -0,0 +1,21 @@
import * as THREE from 'three/webgpu';
import { MaterialFactory } from './MaterialFactory.ts';
/**
* 岩石材质类(rock5
*/
export declare class Rock5Material extends MaterialFactory {
/**
* 创建岩石材质(rock5)
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
static create(options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
}
/**
* 创建岩石材质(rock5)的便捷函数
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
export declare function createRock5Material(options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
+21
View File
@@ -0,0 +1,21 @@
import * as THREE from 'three/webgpu';
import { MaterialFactory } from './MaterialFactory.ts';
/**
* 岩石材质类(rock6
*/
export declare class Rock6Material extends MaterialFactory {
/**
* 创建岩石材质(rock6)
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
static create(options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
}
/**
* 创建岩石材质(rock6)的便捷函数
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
export declare function createRock6Material(options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
+21
View File
@@ -0,0 +1,21 @@
import * as THREE from 'three/webgpu';
import { MaterialFactory } from './MaterialFactory.ts';
/**
* 岩石材质类(rock7
*/
export declare class Rock7Material extends MaterialFactory {
/**
* 创建岩石材质(rock6)
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
static create(options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
}
/**
* 创建岩石材质(rock7)的便捷函数
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
export declare function createRock7Material(options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
+21
View File
@@ -0,0 +1,21 @@
import * as THREE from 'three/webgpu';
import { MaterialFactory } from './MaterialFactory.ts';
/**
* 岩石材质类(rock8
*/
export declare class Rock8Material extends MaterialFactory {
/**
* 创建岩石材质(rock6)
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
static create(options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
}
/**
* 创建岩石材质(rock8)的便捷函数
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
export declare function createRock8Material(options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
+21
View File
@@ -0,0 +1,21 @@
import * as THREE from 'three/webgpu';
import { MaterialFactory } from './MaterialFactory.ts';
/**
* 岩石材质类(rock
*/
export declare class RockMaterial extends MaterialFactory {
/**
* 创建岩石材质(rock)
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
static create(options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
}
/**
* 创建岩石材质(rock)的便捷函数
* @param options - MeshStandardMaterial参数选项,可覆盖默认设置
* @param useDisplacement - 是否使用位移纹理设置,默认为true
* @returns THREE.MeshStandardMaterial - 带有岩石纹理的材质
*/
export declare function createRockMaterial(options?: Partial<ConstructorParameters<typeof THREE.MeshStandardMaterial>[0]>, useDisplacement?: boolean): THREE.MeshStandardMaterial;
+9
View File
@@ -0,0 +1,9 @@
export { createRockMaterial } from './RockMaterial';
export { createRock1Material } from './Rock1Material';
export { createRock2Material } from './Rock2Material';
export { createRock3Material } from './Rock3Material';
export { createRock4Material } from './Rock4Material';
export { createRock5Material } from './Rock5Material';
export { createRock6Material } from './Rock6Material';
export { createRock7Material } from './Rock7Material';
export { createRock8Material } from './Rock8Material';
+71
View File
@@ -0,0 +1,71 @@
import * as THREE from "three/webgpu";
/**
* 剖切平面辅助对象,用于可视化 {@link THREE.Plane} 实例。
*
* ```js
* const plane = new THREE.Plane( new THREE.Vector3( 1, 1, 0.2 ), 3 );
* const helper = new ClippingHelper( plane, 1, 1, 0xffff00 );
* scene.add( helper );
* ```
*
* @augments Line
*/
export declare class ClippingHelper extends THREE.Line {
/**
* 要可视化的平面。
*
* @type {THREE.Plane}
*/
plane: THREE.Plane;
/**
* 辅助对象的宽度。
*
* @type {number}
* @default 1
*/
width: number;
/**
* 辅助对象的高度。
*
* @type {number}
* @default 1
*/
height: number;
/**
* 上方旋转手柄 Sprite(绕局部 X 轴旋转)
*/
topRotateHandle: THREE.Sprite | null;
/**
* 右方旋转手柄 Sprite(绕局部 Y 轴旋转)
*/
rightRotateHandle: THREE.Sprite | null;
/**
* 纹理基础路径(由外部注入,通常为 Vite 的 base 路径)
*/
textureBasePath: string;
/**
* 构造一个新的剖切平面辅助对象。
*
* @param {THREE.Plane} plane - 要可视化的平面。
* @param {number} [width=1] - 辅助对象的宽度。
* @param {number} [height=1] - 辅助对象的高度。
* @param {number|THREE.Color|string} [hex=0xffff00] - 辅助对象的颜色。
*/
constructor(plane: THREE.Plane, width?: number, height?: number, hex?: number | THREE.Color | string);
/**
* 显示或隐藏旋转控制手柄。
* 首次调用 show=true 时会懒加载纹理并创建 Sprite。
* @param show 是否显示
*/
showRotateHandles(show: boolean): void;
/**
* 创建旋转手柄 Sprite
* @param relativePath 相对于 textureBasePath 的贴图路径
* @returns Sprite 实例
*/
private createHandleSprite;
/**
* 释放辅助对象占用的资源。
*/
dispose(): void;
}
+225
View File
@@ -0,0 +1,225 @@
import * as THREE from 'three/webgpu';
import { FontLoader } from 'three/addons/loaders/FontLoader.js';
/**
* 标签位置枚举
*/
export declare enum LabelPosition {
TOP = "top",
BOTTOM = "bottom",
LEFT = "left",
RIGHT = "right"
}
/**
* 小字配置接口
*/
export interface ISmallTextConfig {
/** 文字内容 */
text: string;
/** 目标正方体索引(0-4),-1 表示全部 */
cubeIndex: number;
/** 旋转角度(度) */
rotation?: number;
/** 字体大小(像素) */
fontSize?: number;
/** 字体颜色 */
color?: string;
/** 字体权重 */
fontWeight?: string;
/** 与面板边缘的距离(3D单位) */
offset?: number;
}
/**
* 小正方体数据接口
*/
export interface ICubeData {
/** 颜色 */
color: THREE.Color;
/** 文字 */
text: string;
}
/**
* 单个面板配置选项
*/
export interface ISinglePanelOptions {
/** 面板名称 */
name: string;
/** 面板大小,three 的单位 */
size?: number;
/** 小正方体大小 */
cubeSize?: number;
/** 小正方体间距 */
cubeGap?: number;
/** 面板位置 */
position?: THREE.Vector3;
/** 面板旋转 */
rotation?: THREE.Euler;
/** 初始数据 */
initialData?: ICubeData[][];
/** 标题配置 */
titleConfig?: {
text: string;
position: LabelPosition;
rotation?: number;
fontSize?: number;
color?: string;
offset?: number;
};
/** 小字乐配置 */
smallTextConfig?: {
position: LabelPosition;
smallText1?: ISmallTextConfig[];
smallText2?: ISmallTextConfig[];
rotation?: number;
};
/** 可见列索引数组,只有这些列会显示,其他列显示为白色 */
visibleColumns?: number[];
}
/**
* 单个面板类
* 表示一个由5*5个小正方体构成的面板
*/
export declare class CubePanel {
/** 面板名称 */
name: string;
/** 面板组对象 */
group: THREE.Group;
/** 小正方体数据映射 */
cubeData: Map<string, ICubeData>;
/** 面板网格 */
panelMesh: THREE.Mesh | null;
/** 配置选项 */
options: Required<ISinglePanelOptions>;
/** 标题对象 */
titleObject: THREE.Mesh | null;
/** 标题配置 */
titleConfig: {
text: string;
position: LabelPosition;
rotation: number;
fontSize: number;
color: string;
offset?: number;
} | null;
/** 字体加载器 */
fontLoader: FontLoader;
/** 加载的字体 */
font: any;
/** 小字对象数组 */
smallTextObjects: THREE.Mesh[];
/** 小字平面几何体数组 */
smallTextPlanes: THREE.Mesh[];
/** 小字生成的 canvas */
smallTextCanvas: HTMLCanvasElement | null;
/** 可见列索引集合 */
visibleColumns: Set<number>;
/**
* 创建单个面板
* @param options - 配置选项
*/
constructor(options: ISinglePanelOptions);
/**
* 静态方法:获取场景中指定名称的模型并计算其包围盒大小
* @param scene - Three.js 场景
* @param modelName - 模型名称
* @returns 模型的包围盒大小,如果未找到模型则返回 null
*/
static getModelSize(targetModel: THREE.Object3D): THREE.Vector3 | null;
/**
* 静态方法:获取场景中指定名称的模型并计算其包围盒六个面的中心点位置
* @param scene - Three.js 场景
* @param targetModel
* @returns 模型的包围盒六个面的中心点位置,如果未找到模型则返回 null
*/
static getModelFaceCenters(targetModel: THREE.Object3D): {
[key: string]: THREE.Vector3;
} | null;
/**
* 创建面板
*/
createPanel(): void;
/**
* 初始化默认数据
*/
initDefaultData(): void;
/**
* 生成面板的 HTML
* @returns HTML 字符串
*/
generatePanelHTML(): string;
/**
* 将 HTML 转换为纹理并更新面板
*/
updatePanelTexture(): Promise<void>;
/**
* 设置小正方体数据
* @param row - 行索引
* @param col - 列索引
* @param data - 小正方体数据
*/
setCubeData(row: number, col: number, data: ICubeData): void;
/**
* 获取小正方体数据
* @param row - 行索引
* @param col - 列索引
* @returns 小正方体数据
*/
getCubeData(row: number, col: number): ICubeData | undefined;
/**
* 批量设置面板数据
* @param data - 面板数据
*/
setPanelData(data: ICubeData[][]): void;
/**
* 设置面板标题
* @param titleConfig - 标题配置
*/
setTitle(titleConfig: ISinglePanelOptions['titleConfig']): void;
/**
* 加载字体并创建标题
*/
loadFontAndCreateTitle(): void;
/**
* 创建标题对象
*/
createTitleObject(): void;
/**
* 设置小字
* @param smallTextConfig - 小字配置
*/
setSmallText(smallTextConfig: ISinglePanelOptions['smallTextConfig']): Promise<void>;
/**
* 使用 HTML 实现小字,在一个大的 div 中创建所有小字,然后转为 canvas 到一个新的平面几何体
* @param smallTextConfig - 小字配置
*/
createSmallTextHTML(smallTextConfig: ISinglePanelOptions['smallTextConfig']): Promise<void>;
/**
* 清理小字
*/
clearSmallText(): void;
/**
* 清理标题对象
*/
clearTitle(): void;
/**
* 添加调试小球,在小字和mountGroup的原点添加不同颜色的小球
*/
addDebugSpheres(): void;
/**
* 清理调试小球
*/
clearDebugSpheres(): void;
/**
* 销毁面板
*/
dispose(): void;
/**
* 设置可见列
* @param columns - 可见列索引数组
*/
setVisibleColumns(columns: number[]): void;
/**
* 切换列的可见性
* @param column - 列索引
*/
toggleColumnVisibility(column: number): void;
}
+76
View File
@@ -0,0 +1,76 @@
import * as THREE from 'three/webgpu';
import { PathPointList, PathTubeGeometry } from 'three.path';
export declare class FlowLine {
#private;
points: THREE.Vector3[];
textureUrl: string | null;
options: {
radius: number;
radialSegments: number;
cornerRadius: number;
cornerSplit: number;
scrollSpeed: number;
flowDirection: number;
};
pathPointList: PathPointList | null;
geometry: PathTubeGeometry | null;
material: THREE.MeshPhongMaterial | null;
mesh: THREE.Mesh | null;
texture: THREE.Texture | null;
playing: boolean;
progress: number;
playSpeed: number;
textureAnimating: boolean;
textureAnimationSpeed: number;
constructor(options?: {
points?: THREE.Vector3[];
textureUrl?: string | null;
radius?: number;
radialSegments?: number;
cornerRadius?: number;
cornerSplit?: number;
scrollSpeed?: number;
flowDirection?: number;
[key: string]: any;
});
init(): void;
loadTexture(url: string): void;
addToScene(scene: THREE.Scene): void;
removeFromScene(scene: THREE.Scene): void;
startAnimation(): void;
stopAnimation(): void;
/**
* 开始纹理动画
*/
startTextureAnimation(): void;
/**
* 停止纹理动画
*/
stopTextureAnimation(): void;
update(): void;
/**
* 更新纹理动画
*/
updateTextureAnimation(): void;
/**
* 设置纹理动画速度
* @param speed 速度系数,1.0 为默认速度
*/
setTextureAnimationSpeed(speed: number): void;
/**
* 获取纹理动画速度
* @returns 纹理动画速度
*/
getTextureAnimationSpeed(): number;
/**
* 切换纹理动画状态
* @returns 切换后的状态
*/
toggleTextureAnimation(): boolean;
setFlowDirection(direction: number): void;
setScrollSpeed(speed: number): void;
setPlaySpeed(speed: number): void;
updatePoints(points: THREE.Vector3[]): void;
updateRadius(radius: number): void;
getMesh(): THREE.Mesh | null;
}
+77
View File
@@ -0,0 +1,77 @@
import * as THREE from 'three/webgpu';
/**
* CSS渲染类型枚举
*/
export declare enum CssType {
CSS2D = "css2d",
CSS3D = "css3d",
CSS3DSprite = "css3dsprite"
}
/**
* HTML面板基础类
*/
export declare class HtmlPanel {
type: CssType;
container: HTMLDivElement;
cssObject: THREE.Object3D;
isVisible: boolean;
position: THREE.Vector3;
/**
* 构造函数
* @param type CSS渲染类型
*/
constructor(type?: CssType);
/**
* 获取CSS对象
*/
getCssObject(): THREE.Object3D;
/**
* 获取唯一ID
* @returns CSS对象的UUID
*/
getUniqueId(): string;
/**
* 显示面板
*/
show(): void;
/**
* 隐藏面板
*/
hide(): void;
/**
* 切换面板可见性
*/
toggle(): void;
/**
* 更新面板位置
* @param position 新位置
*/
updatePosition(position: THREE.Vector3): void;
/**
* 更新面板内容
* @param content 新内容
*/
updateContent(content: string): void;
/**
* 获取弹窗可见性
*/
getVisible(): boolean;
/**
* 动态修改CSS类型
* @param type 新的CSS渲染类型
* @returns 新的CSS对象
*/
changeCssType(type: CssType): THREE.Object3D;
/**
* 获取当前CSS类型
*/
getCssType(): CssType;
/**
* 销毁面板,清理所有资源
*/
dispose(): void;
/**
* 创建CSS对象
*/
createCssObject(): void;
}
+35
View File
@@ -0,0 +1,35 @@
import * as THREE from 'three/webgpu';
/**
* 图标类 - 表示单个精灵图图标
*/
export declare class Icon extends THREE.Sprite {
id: string;
/**
* 构造函数
* @param id 图标唯一标识
* @param textureUrl 精灵图纹理URL
* @param size 图标大小
*/
constructor(id: string, textureUrl: string, size?: number);
/**
* 获取图标ID
* @returns 图标唯一标识
*/
getId(): string;
/**
* 设置图标位置
* @param position 新位置
* @returns 当前图标实例
*/
setPosition(position: THREE.Vector3): this;
/**
* 设置图标大小
* @param size 新大小
* @returns 当前图标实例
*/
setSize(size: number): this;
/**
* 销毁图标,清理资源
*/
dispose(): void;
}
+23
View File
@@ -0,0 +1,23 @@
import * as THREE from 'three/webgpu';
export interface SpritePanelOptions {
text: string;
textColor?: string;
backgroundColor?: string;
borderColor?: string;
borderWidth?: number;
fontSize?: number;
padding?: number;
sizeAttenuation?: boolean;
}
/**
* 精灵面板类 - 显示带背景和边框的文字面板
*/
export declare class SpritePanel extends THREE.Sprite {
canvas: HTMLCanvasElement;
context: CanvasRenderingContext2D;
options: Required<SpritePanelOptions>;
constructor(options: SpritePanelOptions);
setText(text: string): void;
dispose(): void;
updateTexture(): void;
}
+7
View File
@@ -0,0 +1,7 @@
export { CubePanel } from "./CubePanel";
export { FlowLine } from "./FlowLine";
export { Icon } from "./Icon";
export { SpritePanel } from "./SpritePanel";
export { HtmlPanel, CssType } from "./HtmlPanel.ts";
export * from "../source/DExtrudeGeometry.ts";
export * from "./CubePanel";
+127
View File
@@ -0,0 +1,127 @@
import * as THREE from 'three/webgpu';
import type { IArchOptions, IParametricGeometry } from './types';
import type { Viewer } from "../core";
import { PathArchGeometry, PathPointList } from "three.path";
import { ParametricGeometryBase } from './ParametricGeometryBase';
import type { RenderEventData } from "../enums/ViewerEvents.ts";
/**
* 高性能参数化城门洞 (基于 PathArchGeometry)
* 使用增量更新而非重建几何体,性能更优
*/
export declare class ParametricArch extends ParametricGeometryBase implements IParametricGeometry {
geometry: PathArchGeometry;
material: THREE.Material;
options: Required<IArchOptions>;
isAnimating: boolean;
animationRequestId: number | null;
originalExtrudePathPoints: any[] | null;
pathPointList: PathPointList | null;
spline: THREE.CatmullRomCurve3 | null;
animationDuration: number;
animationDelay: number;
animationProgress: number;
followMesh: THREE.Mesh | THREE.Object3D | null;
viewer: Viewer | null;
collisionProxyMesh: THREE.Mesh | null;
outerShape: THREE.Shape | null;
private _elapsedTime;
private _boundAnimateHandler;
private _lastCollisionCheckProgress;
private _debugCollisionMeshes;
/**
* 创建参数化城门洞
* @param viewer
* @param options - 城门洞配置选项
*/
constructor(viewer: Viewer, options?: IArchOptions);
/**
* 创建城门洞几何体
*/
createGeometry(): PathArchGeometry;
/**
* 更新城门洞参数
*/
updateParameters(options: Partial<IArchOptions>): void;
/**
* 更新几何体
*/
updateGeometry(): void;
/**
* 开始动画
*/
startAnimation(): void;
/**
* 停止动画
*/
stopAnimation(): void;
/**
* 重置动画
*/
resetAnimation(): void;
/**
* 设置动画时长
*/
setAnimationDuration(duration: number): void;
/**
* 设置动画延迟
*/
setAnimationDelay(delay: number): void;
/**
* 创建调试面板
*/
createDebugPanel(): void;
/**
* 同步 CSGOperator 调试开关
*/
private syncCSGDebugMode;
/**
* 销毁资源
*/
dispose(): void;
/**
* 创建形状(外轮廓,用于碰撞代理)
*/
createShapes(): void;
/**
* 创建碰撞代理 mesh
* 使用前两个路径点创建简化的城门洞几何体
*/
createCollisionProxyMesh(): void;
/**
* 更新碰撞代理 mesh 的位置和旋转
* @param p1 - 第一个点
* @param p2 - 第二个点
*/
updateCollisionProxyTransform(p1: THREE.Vector3, p2: THREE.Vector3): void;
/**
* 加载跟随动画的模型
*/
loadFollowMesh(url: string): Promise<void>;
/**
* 动画循环
*/
animate(data: RenderEventData): void;
/**
* 调试:发生碰撞时克隆代理网格并显示
*/
private debugCollisionProxyMeshOnHit;
/**
* 清理碰撞调试网格
*/
private clearDebugCollisionMeshes;
/**
* 是否应该在当前进度触发碰撞检测
*/
private shouldCheckCollisionNow;
/**
* 直接对所有已添加的碰撞目标执行 CSG 减法操作
* 使用 addCollisionTarget 添加的目标
* @returns 成功处理的目标数量
*/
subtractMesh(): number;
/**
* 获取用于 CSG 操作的 mesh(重写父类方法)
* 优先使用碰撞代理 mesh,如果不存在则回退到主 mesh
*/
protected getCSGMesh(): THREE.Mesh | null;
}
+52
View File
@@ -0,0 +1,52 @@
import { Box3, BoxGeometry, BufferGeometry, Material, Mesh, Plane } from 'three';
import type { IBoxOptions, IParametricGeometry } from './types';
import type { Viewer } from '../core';
import { BVHHelper } from 'three-mesh-bvh';
/**
* 高精度参数化长方体
* 支持完全自定义的长方体生成,包括宽度、高度、深度、分段数等参数
*/
export declare class ParametricBox extends Mesh<BufferGeometry, Material> implements IParametricGeometry {
options: Required<IBoxOptions>;
clippingPlanes: Plane[];
bvhHelper: BVHHelper | null;
/**
* 创建参数化长方体
* @param options - 长方体配置选项
*/
constructor(options?: IBoxOptions);
/**
* 创建长方体几何体
*/
createGeometry(): BoxGeometry;
/**
* 更新长方体参数
* @param options - 新的长方体配置选项
*/
updateParameters(options: Partial<IBoxOptions>): void;
/**
* 更新几何体
*/
updateGeometry(): void;
/**
* 获取 BVH 包围盒
*/
getBVHBoundingBox(): Box3 | undefined;
/**
* 创建对应长方体 6 个面的裁剪平面
* @returns 包含 6 个 THREE.Plane 的数组 [右, 左, 上, 下, 前, 后]
*/
createClippingPlanes(): Plane[];
/**
* 更新裁剪平面
*/
updateClippingPlanes(): void;
/**
* 销毁资源
*/
dispose(): void;
/**
* 创建调试面板
*/
createDebugPanel(viewer: Viewer): void;
}
+60
View File
@@ -0,0 +1,60 @@
import { BufferGeometry, CylinderGeometry, Material, Mesh } from 'three';
import type { ICylinderOptions, IParametricGeometry } from './types';
/**
* 高精度参数化圆柱体
* 支持完全自定义的圆柱体生成,包括顶部/底部半径、高度、分段数等参数
* 可以创建圆柱、圆锥、圆台等多种形状
*/
export declare class ParametricCylinder extends Mesh<BufferGeometry, Material> implements IParametricGeometry {
options: Required<ICylinderOptions>;
/**
* 创建参数化圆柱体
* @param options - 圆柱体配置选项
*/
constructor(options?: ICylinderOptions);
/**
* 创建圆锥体(顶部半径为0的圆柱体)
* @param radius - 底部半径
* @param height - 高度
* @param radialSegments - 径向分段数
* @returns 圆锥体实例
*/
static createCone(radius?: number, height?: number, radialSegments?: number): ParametricCylinder;
/**
* 创建圆柱体几何体
*
* 作用:基于当前实例的 `options` 构造并返回一个新的 `THREE.CylinderGeometry`。
* 入参:无
* 出参:`CylinderGeometry`
* 行为说明:读取 `options`(包括 `radiusTop`、`radiusBottom`、`height`、`radialSegments` 等)并以这些参数构造 `THREE.CylinderGeometry`,用于初始化或替换实例的 `geometry`。
*/
createGeometry(): CylinderGeometry;
/**
* 更新圆柱体参数并触发几何体重建
*
* 作用:合并并应用提供的参数到内部 `options`,随后重新生成几何体。
* 入参:
* @param options - `Partial<ICylinderOptions>` 要更新的参数字段集合
* 出参:`void`
* 行为说明:仅覆盖提供的字段,然后调用 `updateGeometry()` 以使几何体反映新的参数。
*/
updateParameters(options: Partial<ICylinderOptions>): void;
/**
* 更新几何体
*
* 作用:根据当前 `options` 重新生成并替换网格的几何体。
* 入参:无
* 出参:`void`
* 行为说明:销毁现有几何体(调用 `dispose()`),调用 `createGeometry()` 创建新几何并赋值给 `this.geometry`。
*/
updateGeometry(): void;
/**
* 销毁资源
*
* 作用:释放几何体与材质占用的 GPU/内存资源并断开引用。
* 入参:无
* 出参:`void`
* 行为说明:依次调用 `geometry.dispose()` 和 `material.dispose()`(若材质支持),并清理内部引用,便于垃圾回收。
*/
dispose(): void;
}
@@ -0,0 +1,64 @@
import * as THREE from 'three/webgpu';
import { CollisionDetector, CSGOperationType, CSGOperator } from '../tool';
/**
* 碰撞目标配置
*/
interface ICollisionTargetConfig {
mesh: THREE.Mesh;
operationType: CSGOperationType;
maxCollisionCount: number;
}
/**
* 参数化几何体基类
* 提供碰撞检测和 CSG 操作的通用功能
*/
export declare abstract class ParametricGeometryBase extends THREE.Mesh {
protected collisionDetector: CollisionDetector;
protected csgOperator: CSGOperator;
protected collisionTargets: ICollisionTargetConfig[];
protected collisionCountMap: WeakMap<THREE.Mesh, number>;
protected constructor();
/**
* 添加碰撞目标
* @param target - 碰撞目标网格
* @param operationType - CSG 操作类型,默认为 HOLLOW_SUBTRACTION
* @param maxCollisionCount - 最大碰撞处理次数,默认 1,-1 为无限碰撞
*/
addCollisionTarget(target: THREE.Mesh, operationType?: CSGOperationType, maxCollisionCount?: number): void;
/**
* 移除碰撞目标
* @param target - 要移除的碰撞目标
*/
removeCollisionTarget(target: THREE.Mesh): void;
/**
* 清除所有碰撞目标
*/
clearCollisionTargets(): void;
/**
* 获取所有碰撞目标
*/
getCollisionTargets(): THREE.Mesh[];
/**
* 重置碰撞处理计数
* 允许重新对目标执行 CSG 操作
*/
resetProcessedTargets(): void;
abstract updateGeometry(): void;
abstract dispose(): void;
/**
* 获取用于 CSG 操作的 mesh
* 子类可以重写此方法以提供自定义的 CSG mesh(如代理 mesh
* 该 mesh 将用于碰撞检测和 CSG 布尔运算
*/
protected getCSGMesh(): THREE.Mesh | null;
/**
* 检查碰撞并应用CSG操作
* 使用 CSG mesh 进行检测和计算
*/
protected checkCollisionsAndApplyCSG(): void;
/**
* 清理碰撞检测资源
*/
protected disposeCollisionResources(): void;
}
export {};
+275
View File
@@ -0,0 +1,275 @@
import * as THREE from 'three/webgpu';
import type { IPipeOptions } from './types';
import { PathPointList, PathTubeGeometry } from 'three.path';
import type { Viewer } from '../core';
import { ParametricGeometryBase } from './ParametricGeometryBase';
import { DrillingRobot } from '../robot';
import Emittery from 'emittery';
import { BVHHelper } from 'three-mesh-bvh';
import type { RenderEventData } from "../enums/ViewerEvents.ts";
/**
* 参数化管道
* 基于 PathTubeGeometry 实现的管道生成器,支持沿路径生成圆形截面的管道
*/
export declare class ParametricPipe extends ParametricGeometryBase {
#private;
geometry: THREE.BufferGeometry;
material: THREE.Material;
options: Required<IPipeOptions>;
emitter: Emittery;
pathPointList: PathPointList;
pathTubeGeometry: PathTubeGeometry;
viewer: Viewer | null;
startCapMesh: THREE.Mesh | null;
endCapMesh: THREE.Mesh | null;
drillingRobot: DrillingRobot | null;
collisionProxyMesh: THREE.Mesh | null;
staticCollisionProxyMesh: THREE.Mesh | null;
useStaticProxy: boolean;
bvhHelper: BVHHelper | null;
playing: boolean;
duration: number;
texture: THREE.Texture | null;
textureAnimating: boolean;
scrollSpeed: number;
scrollDirection: number;
scrollAxis: 'x' | 'y';
textureRepeatX: number;
textureRepeatY: number;
private _elapsedTime;
private _targetProgress;
private _textureElapsedTime;
private _textureDuration;
private _boundProgressHandler;
private _boundTextureHandler;
private _lastCollisionCheckProgress;
private _debugCollisionMeshes;
private _uvOffsetUniform;
/**
* 创建参数化管道
* @param viewer - Viewer 实例
* @param options - 管道配置选项
*/
constructor(viewer: Viewer, options?: IPipeOptions);
/**
* 设置使用哪种碰撞代理
* @param useStatic - true 使用静态代理,false 使用动态代理
*/
setCollisionProxyType(useStatic: boolean): void;
/**
* 创建管道几何体
*/
createGeometry(): PathTubeGeometry;
/**
* 更新管道参数
* @param options - 新的管道配置选项
*/
updateParameters(options: Partial<IPipeOptions>): void;
/**
* 更新几何体
*/
updateGeometry(): void;
/**
* 更新路径点
* @param points - 新的路径点数组
*/
updatePoints(points: Array<THREE.Vector3 | {
x: number;
y: number;
z: number;
}>): void;
/**
* 更新管道半径
* @param radius - 新的半径值
*/
updateRadius(radius: number): void;
/**
* 更新动画进度
* @param progress - 进度值 (0-1)
*/
updateProgress(progress: number): void;
/**
* 获取路径总长度
* @returns 路径长度
*/
getPathDistance(): number;
/**
* 添加到场景
*/
addToScene(): void;
/**
* 从场景移除
*/
removeFromScene(): void;
/**
* 获取 BVH 包围盒
*/
getBVHBoundingBox(): THREE.Box3 | undefined;
/**
* 销毁资源
*/
dispose(): void;
/**
* 开始进度动画
* @param targetProgress - 目标进度(0-1),如果不提供则默认为 1.0
*/
startAnimation(targetProgress?: number): void;
/**
* 继续进度动画(从当前进度继续到目标进度)
* @param targetProgress - 目标进度(0-1),如果不提供则默认为 1.0
*/
continueAnimation(targetProgress?: number): void;
/**
* 停止进度动画
*/
stopAnimation(): void;
/**
* 开始纹理滚动动画
* @param duration - 动画时长(秒),如果提供则在时长结束后派发 textureAnimationComplete 事件
*/
startTextureAnimation(duration?: number): void;
/**
* 停止纹理滚动动画
*/
stopTextureAnimation(): void;
/**
* 设置动画时长
* @param duration - 动画时长(秒)
*/
setDuration(duration: number): void;
/**
* 获取动画时长
*/
getDuration(): number;
/**
* 设置纹理滚动速度
* @param speed - 滚动速度
*/
setScrollSpeed(speed: number): void;
/**
* 获取纹理滚动速度
*/
getScrollSpeed(): number;
/**
* 设置滚动方向
* @param direction - 1 为正向,-1 为反向
*/
setScrollDirection(direction: number): void;
/**
* 设置滚动轴向
* @param axis - 'x' 为水平滚动,'y' 为垂直滚动
*/
setScrollAxis(axis: 'x' | 'y'): void;
/**
* 获取滚动轴向
*/
getScrollAxis(): 'x' | 'y';
/**
* 设置颜色节点(纹理与颜色混合)
* @param _texture - 纹理
* @param color - 混合颜色
*/
setColorNode(_texture: THREE.Texture, color?: THREE.ColorRepresentation): void;
/**
* 设置纹理重复次数
* @param repeatX - X 轴重复次数
* @param repeatY - Y 轴重复次数
*/
setTextureRepeat(repeatX: number, repeatY: number): void;
/**
* 获取纹理重复次数
*/
getTextureRepeat(): {
x: number;
y: number;
};
/**
* 设置纹理为覆盖模式(拉伸填充,不重复)
*/
setTextureCoverMode(): void;
/**
* 设置纹理缩放
* @param scaleX - X 轴缩放比例(大于1放大,小于1缩小)
* @param scaleY - Y 轴缩放比例(大于1放大,小于1缩小)
*/
setTextureScale(scaleX: number, scaleY: number): void;
/**
* 移除纹理
*/
removeTexture(): void;
/**
* 创建调试面板
*/
createDebugPanel(): void;
/**
* 创建管道端面
*/
createCaps(): void;
/**
* 清除端面
*/
disposeCaps(): void;
/**
* 创建钻进机器人
*/
createDrillingRobot(): void;
/**
* 更新钻进机器人位置
*/
updateDrillingRobotPosition(): void;
/**
* 销毁钻进机器人
*/
disposeDrillingRobot(): void;
/**
* 销毁碰撞代理 mesh
*/
disposeCollisionProxyMeshes(): void;
/**
* 创建或更新碰撞代理 mesh
* 用于 CSG 计算的简化几何体,只包含钻头部分
*/
updateCollisionProxyMesh(): void;
/**
* 创建静态碰撞代理 mesh
* 使用 CylinderGeometry,只基于前两个点生成,不动态更新
*/
createStaticCollisionProxyMesh(): void;
/**
* 更新进度动画
*/
updateProgressAnimation(data: RenderEventData): void;
/**
* 更新纹理动画
*/
updateTextureAnimation(delta: number): void;
/**
* 获取用于碰撞检测的 mesh(重写父类方法)
* 返回当前使用的碰撞代理 mesh
*/
protected getCSGMesh(): THREE.Mesh | null;
/**
* 基于 PathPointList 直接索引采样位姿(简化版)
*/
private samplePathPoseByProgress;
/**
* 获取碰撞代理圆柱高度(动态/静态共用)
*/
private getCollisionProxyHeight;
/**
* 调试:发生碰撞时克隆代理网格并显示
*/
private debugCollisionProxyMeshOnHit;
/**
* 清理碰撞调试网格
*/
private clearDebugCollisionMeshes;
/**
* 是否应该在当前进度触发碰撞检测
*/
private shouldCheckCollisionNow;
/**
* 同步 CSGOperator 调试开关
*/
private syncCSGDebugMode;
}
+32
View File
@@ -0,0 +1,32 @@
import { BufferGeometry, Material, Mesh, RingGeometry } from 'three';
import type { IParametricGeometry, IRingOptions } from './types';
/**
* 高精度参数化圆环
* 支持完全自定义的圆环生成,包括内外半径、分段数等参数
* 可用于创建套管损害、裂缝等可视化效果
*/
export declare class ParametricRing extends Mesh<BufferGeometry, Material> implements IParametricGeometry {
options: Required<IRingOptions>;
/**
* 创建参数化圆环
* @param options - 圆环配置选项
*/
constructor(options?: IRingOptions);
/**
* 创建圆环几何体
*/
createGeometry(): RingGeometry;
/**
* 更新圆环参数
* @param options - 新的圆环配置选项
*/
updateParameters(options: Partial<IRingOptions>): void;
/**
* 更新几何体
*/
updateGeometry(): void;
/**
* 销毁资源
*/
dispose(): void;
}
+35
View File
@@ -0,0 +1,35 @@
import { BufferGeometry, Material, Mesh, SphereGeometry } from 'three';
import type { IParametricGeometry, ISphereOptions } from './types';
/**
* 高精度参数化球体
* 支持完全自定义的球体生成,包括半径、分段数、起始角度等参数
*/
export declare class ParametricSphere extends Mesh<BufferGeometry, Material> implements IParametricGeometry {
options: Required<ISphereOptions>;
/**
* 创建参数化球体
* @param options - 球体配置选项
*/
constructor(options?: ISphereOptions);
/**
* 创建球体几何体
*/
createGeometry(): SphereGeometry;
/**
* 更新球体参数
* @param options - 新的球体配置选项
*/
updateParameters(options: Partial<ISphereOptions>): void;
/**
* 更新几何体
*/
updateGeometry(): void;
/**
* 获取当前参数
*/
getParameters(): ISphereOptions;
/**
* 销毁资源
*/
dispose(): void;
}
+32
View File
@@ -0,0 +1,32 @@
import { BufferGeometry, Material, Mesh, TorusGeometry } from 'three';
import type { IParametricGeometry, ITorusOptions } from './types';
/**
* 高精度参数化圆环体(甜甜圈形状)
* 支持完全自定义的圆环体生成,包括半径、管道半径、分段数等参数
* 可用于创建套管损害、管道连接等可视化效果
*/
export declare class ParametricTorus extends Mesh<BufferGeometry, Material> implements IParametricGeometry {
options: Required<ITorusOptions>;
/**
* 创建参数化圆环体
* @param options - 圆环体配置选项
*/
constructor(options?: ITorusOptions);
/**
* 创建圆环体几何体
*/
createGeometry(): TorusGeometry;
/**
* 更新圆环体参数
* @param options - 新的圆环体配置选项
*/
updateParameters(options: Partial<ITorusOptions>): void;
/**
* 更新几何体
*/
updateGeometry(): void;
/**
* 销毁资源
*/
dispose(): void;
}
+58
View File
@@ -0,0 +1,58 @@
import { BufferGeometry, LineSegments, Material } from 'three';
import type { IParametricGeometry } from './types';
import type { ParametricBox } from './ParametricBox';
/**
* 线框参数配置
*/
export interface IWireframeOptions {
/** 线框颜色 */
color?: number;
/** 线宽 */
linewidth?: number;
/** 盒子宽度 */
width?: number;
/** 盒子高度 */
height?: number;
/** 盒子深度 */
depth?: number;
/** ParametricBox 实例(可选,如果提供则从中提取尺寸) */
box?: ParametricBox;
}
/**
* 参数化线框
* 显示盒子的12条边
*/
export declare class ParametricWireframe extends LineSegments<BufferGeometry, Material> implements IParametricGeometry {
options: Required<Omit<IWireframeOptions, 'box'>>;
sourceBox?: ParametricBox;
/**
* 创建参数化线框
* @param options - 线框配置选项
*/
constructor(options?: IWireframeOptions);
/**
* 创建线框几何体
* 盒子有12条边:
* - 顶面4条边
* - 底面4条边
* - 连接顶底的4条垂直边
*/
static createWireframeGeometry(width: number, height: number, depth: number): BufferGeometry;
/**
* 更新线框参数
* @param options - 新的线框配置选项
*/
updateParameters(options: Partial<IWireframeOptions>): void;
/**
* 从关联的 ParametricBox 同步尺寸
*/
syncFromBox(): void;
/**
* 更新几何体
*/
updateGeometry(): void;
/**
* 销毁资源
*/
dispose(): void;
}
+12
View File
@@ -0,0 +1,12 @@
export { ParametricSphere } from './ParametricSphere.ts';
export { ParametricCylinder } from './ParametricCylinder.ts';
export { ParametricBox } from './ParametricBox.ts';
export { ParametricArch } from './ParametricArch.ts';
export { ParametricPipe } from './ParametricPipe.ts';
export { ParametricRing } from './ParametricRing.ts';
export { ParametricTorus } from './ParametricTorus.ts';
export { ParametricWireframe } from './ParametricWireframe.ts';
export { DrillingRobot } from '../robot/DrillingRobot.ts';
export type { IParametricGeometry, IParametricGeometryOptions, ISphereOptions, ICylinderOptions, IBoxOptions, IArchOptions, IPipeOptions, IRingOptions, ITorusOptions, } from './types';
export type { IWireframeOptions } from './ParametricWireframe.ts';
export type { IDrillingRobotOptions } from '../robot/DrillingRobot.ts';
+209
View File
@@ -0,0 +1,209 @@
import * as THREE from 'three/webgpu';
/**
* 参数化几何体的基础配置接口
*/
export interface IParametricGeometryOptions {
/** 材质 */
material?: THREE.Material;
}
/**
* 球体参数配置
*/
export interface ISphereOptions extends IParametricGeometryOptions {
/** 半径 */
radius?: number;
/** 水平分段数(经度) */
widthSegments?: number;
/** 垂直分段数(纬度) */
heightSegments?: number;
/** 水平起始角度 */
phiStart?: number;
/** 水平扫描角度 */
phiLength?: number;
/** 垂直起始角度 */
thetaStart?: number;
/** 垂直扫描角度 */
thetaLength?: number;
}
/**
* 圆柱体参数配置
*/
export interface ICylinderOptions extends IParametricGeometryOptions {
/** 顶部半径 */
radiusTop?: number;
/** 底部半径 */
radiusBottom?: number;
/** 高度 */
height?: number;
/** 径向分段数 */
radialSegments?: number;
/** 高度分段数 */
heightSegments?: number;
/** 是否开放端面 */
openEnded?: boolean;
/** 起始角度 */
thetaStart?: number;
/** 扫描角度 */
thetaLength?: number;
}
/**
* 长方体参数配置
*/
export interface IBoxOptions extends IParametricGeometryOptions {
/** 宽度 */
width?: number;
/** 高度 */
height?: number;
/** 深度 */
depth?: number;
/** 宽度分段数 */
widthSegments?: number;
/** 高度分段数 */
heightSegments?: number;
/** 深度分段数 */
depthSegments?: number;
}
/**
* 城门洞参数配置
*/
export interface IArchOptions extends IParametricGeometryOptions {
/** 宽度 */
width?: number;
/** 高度 */
height?: number;
/** 深度 */
depth?: number;
/** 厚度 */
thickness?: number;
/** 深度分段数 */
depthSegments?: number;
curveSegments?: number;
steps?: number;
/** 是否有内轮廓(洞) */
hasHole?: boolean;
/** 挤压路径点数组,可以是 THREE.Vector3 数组或包含 x,y,z 属性的对象数组 */
extrudePathPoints?: Array<THREE.Vector3 | {
x: number;
y: number;
z: number;
}>;
/** 是否启用动画,启用时第一次创建只取第一个点 */
animate?: boolean;
/** 是否生成底部面 */
bottomEnabled?: boolean;
/** 是否生成顶部面 */
topEnabled?: boolean;
/** 跟随动画的 mesh 对象 */
followMesh?: THREE.Mesh | THREE.Object3D;
/** 跟随动画的 mesh 模型 URL 路径 */
followMeshUrl?: string;
/** 跟随动画的 mesh 在动画时的位置偏移 */
followMeshOffset?: THREE.Vector3;
/** 向上方向向量,用于控制挤出时的坐标系方向 */
upVector?: THREE.Vector3;
/** 动画时是否启用 CSG 操作(含碰撞检测) */
enableCSGOperation?: boolean;
/** 是否显示 CSG 调试 mesh */
showDebugMesh?: boolean;
/** 碰撞检测触发的进度步长(0-1),<=0 表示每帧检测 */
collisionCheckProgressStep?: number;
/** 碰撞代理体深度(挙伸幼度),默认为 0.3 */
collisionProxyDepth?: number;
/** 是否启用碰撞代理网格调试显示 */
debugCollisionProxy?: boolean;
}
/**
* 管道参数配置
*/
export interface IPipeOptions extends IParametricGeometryOptions {
/** 路径点数组 */
points?: Array<THREE.Vector3 | {
x: number;
y: number;
z: number;
}>;
/** 管道半径 */
radius?: number;
/** 径向分段数 */
radialSegments?: number;
/** 拐角半径 */
cornerRadius?: number;
/** 拐角分段数 */
cornerSplit?: number;
/** 动画进度 (0-1) */
progress?: number;
/** 起始旋转角度 */
startRad?: number;
/** 向上方向向量 */
upVector?: THREE.Vector3 | null;
/** 是否闭合路径 */
close?: boolean;
/** 是否封闭起始端 */
capStart?: boolean;
/** 是否封闭结束端 */
capEnd?: boolean;
/** 是否启用钻进机器人 */
enableDrillingRobot?: boolean;
/** 钻进机器人颜色 */
robotColor?: number;
/** 机器人圆柱体长度系数(相对于管道半径) */
robotCylinderLengthRatio?: number;
/** 机器人圆锥体长度系数(相对于管道半径) */
robotConeLengthRatio?: number;
/** 是否使用静态碰撞代理 (true: CylinderGeometry, false: TubeGeometry) */
useStaticCollisionProxy?: boolean;
/** 碰撞代理圆柱高度(动态/静态共用,<=0 或不传时使用默认值) */
collisionProxyHeight?: number;
/** 元数据 */
metadata?: Record<string, any>;
/** 碰撞检测触发的进度步长(0-1),<=0 表示每帧检测 */
collisionCheckProgressStep?: number;
/** 是否启用碰撞代理网格调试显示 */
debugCollisionProxy?: boolean;
}
/**
* 圆环参数配置
*/
export interface IRingOptions extends IParametricGeometryOptions {
/** 内半径 */
innerRadius?: number;
/** 外半径 */
outerRadius?: number;
/** 圆周分段数 */
thetaSegments?: number;
/** 径向分段数 */
phiSegments?: number;
/** 起始角度 */
thetaStart?: number;
/** 扫描角度 */
thetaLength?: number;
}
/**
* 圆环体(甜甜圈)参数配置
*/
export interface ITorusOptions extends IParametricGeometryOptions {
/** 圆环半径(从圆环中心到管道中心的距离) */
radius?: number;
/** 管道半径 */
tube?: number;
/** 径向分段数(管道圆周方向) */
radialSegments?: number;
/** 管状分段数(圆环圆周方向) */
tubularSegments?: number;
/** 圆环弧度(默认 2π 为完整圆环) */
arc?: number;
}
/**
* 参数化几何体基类接口
* 实现此接口的类应该直接继承 THREE.Mesh
*/
export interface IParametricGeometry {
/** 几何体 */
geometry: THREE.BufferGeometry;
/** 材质 */
material: THREE.Material | THREE.Material[];
/** 更新几何体参数 */
updateGeometry(): void;
/** 销毁资源 */
dispose(): void;
}
+64
View File
@@ -0,0 +1,64 @@
import * as THREE from 'three/webgpu';
/**
* Bloom 通道
* 用于为场景添加 bloom 效果(光晕效果)
*/
export declare class BloomPass {
bloomPass: any;
highlightedObjects: Map<THREE.Object3D, THREE.Color>;
/**
* 构造函数
*/
constructor();
/**
* 初始化 Bloom 通道
*/
init(): void;
/**
* 获取 Bloom 效果的输出节点
* @param scenePassColor - 场景通道的颜色输出节点
* @returns Bloom 效果的输出节点
*/
getOutputNode(scenePassColor: any): any;
/**
* 设置 Bloom 阈值
* @param value - 阈值,范围 0.0 到 1.0
*/
setThreshold(value: number): void;
/**
* 设置 Bloom 强度
* @param value - 强度,范围 0.0 到 3.0
*/
setStrength(value: number): void;
/**
* 设置 Bloom 半径
* @param value - 半径,范围 0.0 到 1.0
*/
setRadius(value: number): void;
/**
* 添加要高亮的对象
* @param object - 要高亮的对象
* @param highlightColor - 高亮颜色,默认为绿色 (0, 1, 0)
*/
addHighlightedObject(object: THREE.Object3D, highlightColor?: THREE.Color): void;
/**
* 移除要高亮的对象
* @param object - 要移除的对象
*/
removeHighlightedObject(object: THREE.Object3D): void;
/**
* 清空所有要高亮的对象
*/
clearHighlightedObjects(): void;
/**
* 获取当前高亮的对象列表
* @returns 高亮的对象列表
*/
getHighlightedObjects(): THREE.Object3D[];
/**
* 检查对象是否在高亮列表中
* @param object - 要检查的对象
* @returns 是否在高亮列表中
*/
isObjectHighlighted(object: THREE.Object3D): boolean;
}
+91
View File
@@ -0,0 +1,91 @@
import * as THREE from 'three/webgpu';
/**
* 描边通道
* 用于为选中的对象添加描边效果
*/
export declare class OutlinePass {
scene: THREE.Scene;
camera: THREE.Camera;
outlinePass: any;
selectedObjects: THREE.Object3D[];
edgeStrength: THREE.UniformNode<"float", number>;
edgeGlow: THREE.UniformNode<"float", number>;
edgeThickness: THREE.UniformNode<"float", number>;
pulsePeriod: THREE.UniformNode<"float", number>;
visibleEdgeColor: THREE.UniformNode<"color", THREE.Color>;
hiddenEdgeColor: THREE.UniformNode<"color", THREE.Color>;
/**
* 构造函数
* @param scene - 场景
* @param camera - 相机
*/
constructor(scene: THREE.Scene, camera: THREE.Camera);
/**
* 初始化描边通道
*/
init(): void;
/**
* 更新相机引用
* @param camera - 新的相机
*/
updateCamera(camera: THREE.Camera): void;
/**
* 获取描边效果的输出节点
* @param scenePass - 场景通道的输出节点
* @returns 描边效果的输出节点
*/
getOutputNode(scenePass: any): any;
/**
* 添加要描边的对象
* @param object - 要添加的对象
*/
addSelectedObject(object: THREE.Object3D): void;
/**
* 移除要描边的对象
* @param object - 要移除的对象
*/
removeSelectedObject(object: THREE.Object3D): void;
/**
* 清空所有要描边的对象
*/
clearSelectedObjects(): void;
/**
* 更新要描边的对象列表
*/
updateSelectedObjects(): void;
/**
* 设置描边强度
* @param value - 描边强度值
*/
setEdgeStrength(value: number): void;
/**
* 设置描边 glow 效果
* @param value - glow 效果值
*/
setEdgeGlow(value: number): void;
/**
* 设置描边厚度
* @param value - 描边厚度值
*/
setEdgeThickness(value: number): void;
/**
* 设置描边脉冲周期
* @param value - 脉冲周期值
*/
setPulsePeriod(value: number): void;
/**
* 设置可见边的颜色
* @param color - 颜色值
*/
setVisibleEdgeColor(color: THREE.Color): void;
/**
* 设置隐藏边的颜色
* @param color - 颜色值
*/
setHiddenEdgeColor(color: THREE.Color): void;
/**
* 获取当前选中的对象列表
* @returns 选中的对象列表
*/
getSelectedObjects(): THREE.Object3D[];
}
+2
View File
@@ -0,0 +1,2 @@
export * from './BloomPass.ts';
export * from "./OutlinePass.ts";
+53
View File
@@ -0,0 +1,53 @@
import * as THREE from 'three/webgpu';
/**
* 钻进机器人配置
*/
export interface IDrillingRobotOptions {
/** 管道半径(用于计算机器人尺寸) */
pipeRadius: number;
/** 机器人颜色 */
color?: number;
/** 圆柱体长度系数(相对于管道半径) */
cylinderLengthRatio?: number;
/** 圆锥体长度系数(相对于管道半径) */
coneLengthRatio?: number;
}
/**
* 钻进机器人
* 由圆柱体和圆锥体组成,用于模拟钻进过程
*/
export declare class DrillingRobot {
group: THREE.Group;
cylinder: THREE.Mesh;
cone: THREE.Mesh;
options: Required<IDrillingRobotOptions>;
/**
* 创建钻进机器人
* @param options - 机器人配置选项
*/
constructor(options: IDrillingRobotOptions);
/**
* 设置机器人位置
* @param position - 位置向量
*/
setPosition(position: THREE.Vector3): void;
/**
* 设置机器人旋转
* @param quaternion - 旋转四元数
*/
setRotation(quaternion: THREE.Quaternion): void;
/**
* 设置机器人朝向
* @param direction - 方向向量
*/
setDirection(direction: THREE.Vector3): void;
/**
* 更新机器人尺寸(当管道半径改变时)
* @param pipeRadius - 新的管道半径
*/
updateSize(pipeRadius: number): void;
/**
* 销毁机器人资源
*/
dispose(): void;
}
+143
View File
@@ -0,0 +1,143 @@
import * as THREE from 'three/webgpu';
import { CollisionDetector } from "../tool";
import { CSGOperationType } from "../tool/CSGOperator";
import type { Viewer } from "../core/Viewer";
/**
* CSG 目标对象配置
*/
export interface ICSGTargetConfig {
/** 目标网格对象 */
mesh: THREE.Mesh;
/** CSG 操作类型 */
operationType: CSGOperationType;
/** 是否启用 */
enabled?: boolean;
}
/**
* 回采机器人配置
*/
export interface IMiningRobotOptions {
/** 机器人尺寸 */
size?: number;
/** 机器人颜色 */
color?: number;
/** 主体宽度系数 */
widthRatio?: number;
/** 主体高度系数 */
heightRatio?: number;
/** 主体深度系数 */
depthRatio?: number;
}
/**
* 挖掘动画配置
*/
export interface IMiningAnimationOptions {
/** 移动持续时间(秒) */
duration?: number;
/** CSG 执行频率系数,1.0 表示每移动切割头尺寸距离执行一次,0.5 表示每移动切割头尺寸一半距离执行一次 */
csgFrequency?: number;
/** 完成回调 */
onComplete?: () => void;
/** 进度回调 */
onProgress?: (progress: number) => void;
}
/**
* 回采机器人
* 用于模拟矿体回采过程
*/
export declare class MiningRobot {
group: THREE.Group;
mainBody: THREE.Mesh;
cuttingHead: THREE.Mesh;
connector: THREE.Mesh;
frontIndicator: THREE.Mesh;
options: Required<IMiningRobotOptions>;
animationId: number | null;
isMining: boolean;
protected collisionDetector: CollisionDetector;
/** CSG 目标对象列表 */
private csgTargets;
/** CSG 操作器 */
private csgOperator;
/** Viewer 实例 */
private viewer;
/** 动画状态 */
private animationState;
/** 渲染事件监听器取消函数 */
private unsubscribeRender;
/**
* 创建回采机器人
* @param options - 机器人配置选项
*/
constructor(options?: IMiningRobotOptions);
/**
* 添加 CSG 目标对象
* @param mesh - 目标网格对象
* @param operationType - CSG 操作类型
* @param enabled - 是否启用(默认为 true
*/
addCSGTarget(mesh: THREE.Mesh, operationType: CSGOperationType, enabled?: boolean): void;
/**
* 移除 CSG 目标对象
* @param mesh - 要移除的网格对象
*/
removeCSGTarget(mesh: THREE.Mesh): void;
/**
* 清空所有 CSG 目标对象
*/
clearCSGTargets(): void;
/**
* 获取所有 CSG 目标对象
*/
getCSGTargets(): ICSGTargetConfig[];
/**
* 设置 CSG 目标对象的启用状态
* @param mesh - 目标网格对象
* @param enabled - 是否启用
*/
setCSGTargetEnabled(mesh: THREE.Mesh, enabled: boolean): void;
/**
* 设置机器人位置
* @param position - 位置向量
*/
setPosition(position: THREE.Vector3): void;
/**
* 设置机器人朝向
* @param direction - 方向向量
*/
setDirection(direction: THREE.Vector3): void;
/**
* 更新机器人尺寸
* @param size - 新的基础尺寸
*/
updateSize(size: number): void;
/**
* 开始挖掘动画
* @param viewer - Viewer 实例
* @param startPosition - 起始位置
* @param endPosition - 结束位置
* @param options - 动画配置选项
*/
startMining(viewer: Viewer, startPosition: THREE.Vector3, endPosition: THREE.Vector3, options?: IMiningAnimationOptions): void;
/**
* 执行 CSG 操作
*/
executeCSGOperation(): void;
/**
* 停止挖掘动画
*/
stopMining(): void;
/**
* 获取是否正在挖掘
*/
getIsMining(): boolean;
/**
* 销毁机器人资源
*/
dispose(): void;
/**
* 渲染前回调,处理动画逻辑
* @param data - 渲染事件数据
*/
private onBeforeRender;
}
+2
View File
@@ -0,0 +1,2 @@
export * from './DrillingRobot';
export * from './MiningRobot';
+28
View File
@@ -0,0 +1,28 @@
import { BufferGeometry, Shape, Vector3 } from "three/webgpu";
interface ExtrudeGeometryOptions {
curveSegments?: number;
steps?: number;
depth?: number;
bevelEnabled?: boolean;
bevelThickness?: number;
bevelSize?: number;
bevelOffset?: number;
bevelSegments?: number;
extrudePath?: any;
UVGenerator?: any;
bottomEnabled?: boolean;
topEnabled?: boolean;
upVector?: Vector3;
}
export declare class DExtrudeGeometry extends BufferGeometry {
/**
* Constructs a new extrude geometry.
*
* @param {Shape|Array<Shape>} [shapes] - A shape or an array of shapes.
* @param {ExtrudeGeometry~Options} [options] - The extrude settings.
*/
constructor(shapes?: Shape, options?: ExtrudeGeometryOptions);
copy(source: any): this;
toJSON(): any;
}
export {};
+147
View File
@@ -0,0 +1,147 @@
import { Vector3 } from "three/webgpu";
/**
* An abstract base class for creating an analytic curve object that contains methods
* for interpolation.
*
* @abstract
*/
declare class DCurve {
/**
* Constructs a new curve.
*/
constructor();
/**
* This method returns a vector in 2D or 3D space (depending on the curve definition)
* for the given interpolation factor.
*
* @abstract
* @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
* @param {(Vector2|Vector3)} [optionalTarget] - The optional target vector the result is written to.
* @return {(Vector2|Vector3)} The position on the curve. It can be a 2D or 3D vector depending on the curve definition.
*/
getPoint(): void;
/**
* This method returns a vector in 2D or 3D space (depending on the curve definition)
* for the given interpolation factor. Unlike {@link Curve#getPoint}, this method honors the length
* of the curve which equidistant samples.
*
* @param {number} u - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
* @param {(Vector2|Vector3)} [optionalTarget] - The optional target vector the result is written to.
* @return {(Vector2|Vector3)} The position on the curve. It can be a 2D or 3D vector depending on the curve definition.
*/
getPointAt(u: any, optionalTarget: any): void;
/**
* This method samples the curve via {@link Curve#getPoint} and returns an array of points representing
* the curve shape.
*
* @param {number} [divisions=5] - The number of divisions.
* @return {Array<(Vector2|Vector3)>} An array holding the sampled curve values. The number of points is `divisions + 1`.
*/
getPoints(divisions?: number): void[];
/**
* This method samples the curve via {@link Curve#getPointAt} and returns an array of points representing
* the curve shape. Unlike {@link Curve#getPoints}, this method returns equi-spaced points across the entire
* curve.
*
* @param {number} [divisions=5] - The number of divisions.
* @return {Array<(Vector2|Vector3)>} An array holding the sampled curve values. The number of points is `divisions + 1`.
*/
getSpacedPoints(divisions?: number): void[];
/**
* Returns the total arc length of the curve.
*
* @return {number} The length of the curve.
*/
getLength(): any;
/**
* Returns an array of cumulative segment lengths of the curve.
*
* @param {number} [divisions=this.arcLengthDivisions] - The number of divisions.
* @return {Array<number>} An array holding the cumulative segment lengths.
*/
getLengths(divisions?: any): any;
/**
* Update the cumulative segment distance cache. The method must be called
* every time curve parameters are changed. If an updated curve is part of a
* composed curve like {@link CurvePath}, this method must be called on the
* composed curve, too.
*/
updateArcLengths(): void;
/**
* Given an interpolation factor in the range `[0,1]`, this method returns an updated
* interpolation factor in the same range that can be ued to sample equidistant points
* from a curve.
*
* @param {number} u - The interpolation factor.
* @param {?number} distance - An optional distance on the curve.
* @return {number} The updated interpolation factor.
*/
getUtoTmapping(u: any, distance?: null): number;
/**
* Returns a unit vector tangent for the given interpolation factor.
* If the derived curve does not implement its tangent derivation,
* two points a small delta apart will be used to find its gradient
* which seems to give a reasonable approximation.
*
* @param {number} t - The interpolation factor.
* @param {(Vector2|Vector3)} [optionalTarget] - The optional target vector the result is written to.
* @return {(Vector2|Vector3)} The tangent vector.
*/
getTangent(t: any, optionalTarget: any): any;
/**
* Same as {@link Curve#getTangent} but with equidistant samples.
*
* @param {number} u - The interpolation factor.
* @param {(Vector2|Vector3)} [optionalTarget] - The optional target vector the result is written to.
* @return {(Vector2|Vector3)} The tangent vector.
* @see {@link Curve#getPointAt}
*/
getTangentAt(u: any, optionalTarget: any): any;
/**
* Generates the Frenet Frames. Requires a curve definition in 3D space. Used
* in geometries like {@link TubeGeometry} or {@link ExtrudeGeometry}.
*
* @param {number} segments - The number of segments.
* @param {boolean} [closed=false] - Whether the curve is closed or not.
* @return {{tangents: Array<Vector3>, normals: Array<Vector3>, binormals: Array<Vector3>}} The Frenet Frames.
*/
computeFrenetFrames(segments: any, closed?: boolean, upVector?: null): {
tangents: any[];
normals: Vector3[];
binormals: Vector3[];
};
/**
* Returns a new curve with copied values from this instance.
*
* @return {Curve} A clone of this instance.
*/
clone(): any;
/**
* Copies the values of the given curve to this instance.
*
* @param {Curve} source - The curve to copy.
* @return {Curve} A reference to this curve.
*/
copy(source: any): this;
/**
* Serializes the curve into JSON.
*
* @return {Object} A JSON object representing the serialized curve.
* @see {@link ObjectLoader#parse}
*/
toJSON(): {
metadata: {
version: number;
type: string;
generator: string;
};
};
/**
* Deserializes the curve from the given JSON.
*
* @param {Object} json - The JSON holding the serialized curve.
* @return {Curve} A reference to this curve.
*/
fromJSON(json: any): this;
}
export { DCurve };
+55
View File
@@ -0,0 +1,55 @@
import { Vector3 } from "three/webgpu";
import { DCurve } from '../core/Curve';
/**
* A curve representing a Catmull-Rom spline.
*
* ```js
* //Create a closed wavey loop
* const curve = new THREE.CatmullRomCurve3( [
* new THREE.Vector3( -10, 0, 10 ),
* new THREE.Vector3( -5, 5, 5 ),
* new THREE.Vector3( 0, 0, 0 ),
* new THREE.Vector3( 5, -5, 5 ),
* new THREE.Vector3( 10, 0, 10 )
* ] );
*
* const points = curve.getPoints( 50 );
* const geometry = new THREE.BufferGeometry().setFromPoints( points );
*
* const material = new THREE.LineBasicMaterial( { color: 0xff0000 } );
*
* // Create the final object to add to the scene
* const curveObject = new THREE.Line( geometry, material );
* ```
*
* @augments Curve
*/
declare class DCatmullRomCurve3 extends DCurve {
/**
* Constructs a new Catmull-Rom curve.
*
* @param {Array<Vector3>} [points] - An array of 3D points defining the curve.
* @param {boolean} [closed=false] - Whether the curve is closed or not.
* @param {('centripetal'|'chordal'|'catmullrom')} [curveType='centripetal'] - The curve type.
* @param {number} [tension=0.5] - Tension of the curve.
*/
constructor(points?: never[], closed?: boolean, curveType?: string, tension?: number);
/**
* Returns a point on the curve.
*
* @param {number} t - A interpolation factor representing a position on the curve. Must be in the range `[0,1]`.
* @param {Vector3} [optionalTarget] - The optional target vector the result is written to.
* @return {Vector3} The position on the curve.
*/
getPoint(t: any, optionalTarget?: Vector3): Vector3;
copy(source: any): this;
toJSON(): {
metadata: {
version: number;
type: string;
generator: string;
};
};
fromJSON(json: any): this;
}
export { DCatmullRomCurve3 };
+129
View File
@@ -0,0 +1,129 @@
import * as THREE from 'three/webgpu';
import { Brush, Evaluator } from 'three-bvh-csg';
/**
* CSG 操作类型
*/
export declare const CSGOperationType: {
readonly ADDITION: import("three-bvh-csg").CSGOperation;
readonly SUBTRACTION: import("three-bvh-csg").CSGOperation;
readonly REVERSE_SUBTRACTION: import("three-bvh-csg").CSGOperation;
readonly INTERSECTION: import("three-bvh-csg").CSGOperation;
readonly DIFFERENCE: import("three-bvh-csg").CSGOperation;
readonly HOLLOW_SUBTRACTION: import("three-bvh-csg").CSGOperation;
readonly HOLLOW_INTERSECTION: import("three-bvh-csg").CSGOperation;
};
export type CSGOperationType = typeof CSGOperationType[keyof typeof CSGOperationType];
/**
* CSG 操作器
* 使用 three-bvh-csg 进行布尔运算
*/
export declare class CSGOperator {
evaluator: Evaluator;
/** Brush 缓存,用于复用 Brush 对象 */
private brushCache;
/** 临时对象,避免重复创建 */
private _tempWorldPosition;
private _tempWorldQuaternion;
private _tempWorldScale;
private helperGroup;
constructor();
private _debugMode;
get debugMode(): boolean;
set debugMode(value: boolean);
/**
* 清除 Brush 缓存
* @param mesh - 可选,指定要清除的网格,不指定则清除所有
*/
clearBrushCache(mesh?: THREE.Mesh): void;
/**
* 执行并集操作
* @param meshA - 网格 A
* @param meshB - 网格 B
* @returns 结果几何体
*/
union(meshA: THREE.Mesh, meshB: THREE.Mesh): THREE.BufferGeometry;
/**
* 执行差集操作 (A - B)
* @param meshA - 被减去的网格
* @param meshB - 减去的网格
* @returns 结果几何体
*/
subtract(meshA: THREE.Mesh, meshB: THREE.Mesh): THREE.BufferGeometry;
/**
* 执行反向差集操作 (B - A)
* @param meshA - 网格 A
* @param meshB - 网格 B
* @returns 结果几何体
*/
reverseSubtract(meshA: THREE.Mesh, meshB: THREE.Mesh): THREE.BufferGeometry;
/**
* 执行交集操作
* @param meshA - 网格 A
* @param meshB - 网格 B
* @returns 结果几何体
*/
intersection(meshA: THREE.Mesh, meshB: THREE.Mesh): THREE.BufferGeometry;
/**
* 执行对称差集操作
* @param meshA - 网格 A
* @param meshB - 网格 B
* @returns 结果几何体
*/
difference(meshA: THREE.Mesh, meshB: THREE.Mesh): THREE.BufferGeometry;
/**
* 执行空心差集操作
* 从 meshA 中减去 meshB,但只删除相交的面
* @param meshA - 网格 A
* @param meshB - 网格 B
* @returns 结果几何体
*/
hollowSubtract(meshA: THREE.Mesh, meshB: THREE.Mesh): THREE.BufferGeometry;
/**
* 执行空心交集操作
* 只保留相交部分的表面
* @param meshA - 网格 A
* @param meshB - 网格 B
* @returns 结果几何体
*/
hollowIntersection(meshA: THREE.Mesh, meshB: THREE.Mesh): THREE.BufferGeometry;
/**
* 通用 CSG 操作方法
* @param meshA - 网格 A
* @param meshB - 网格 B
* @param operation - CSG 操作类型
* @returns 结果几何体
*/
operate(meshA: THREE.Mesh, meshB: THREE.Mesh, operation: CSGOperationType): THREE.BufferGeometry;
/**
* 批量执行差集操作
* 从 meshA 中减去多个网格
* @param meshA - 被减去的网格
* @param meshes - 要减去的网格数组
* @returns 结果几何体
*/
subtractMultiple(meshA: THREE.Mesh, meshes: THREE.Mesh[]): THREE.BufferGeometry;
/**
* 设置属性插值
* @param attributes - 要插值的属性名称数组
*/
setAttributes(attributes: string[]): void;
/**
* 设置是否使用材质组
* @param useGroups - 是否使用组
*/
setUseGroups(useGroups: boolean): void;
/**
* 将 Mesh 转换为 Brush,使用缓存机制复用 Brush 对象
* @param mesh - 需要转换的网格
* @returns Brush 对象
*/
meshToBrush(mesh: THREE.Mesh): Brush;
/**
* 统一的 CSG 操作执行方法
* @param meshA - 网格 A
* @param meshB - 网格 B
* @param operation - CSG 操作类型
* @returns 结果几何体
*/
evaluate(meshA: THREE.Mesh, meshB: THREE.Mesh, operation: CSGOperationType): THREE.BufferGeometry;
}
+54
View File
@@ -0,0 +1,54 @@
import * as THREE from 'three/webgpu';
/**
* 碰撞检测器
* 使用 three-mesh-bvh 进行高效的碰撞检测
*/
export declare class CollisionDetector {
meshBVHMap: WeakMap<THREE.Mesh, any>;
/**
* 为几何体计算 BVH
* @param geometry 几何体
*/
static computeBoundsTree(geometry: THREE.BufferGeometry): void;
/**
* 释放几何体的 BVH
* @param geometry 几何体
*/
static disposeBoundsTree(geometry: THREE.BufferGeometry): void;
/**
* 检查几何体是否有 BVH
* @param geometry 几何体
* @returns 是否有 BVH
*/
static hasBoundsTree(geometry: THREE.BufferGeometry): boolean;
/**
* 确保几何体有 BVH(如果没有则计算)
* @param geometry 几何体
*/
static ensureBoundsTree(geometry: THREE.BufferGeometry): void;
/**
* 为网格构建 BVH
* @param mesh - 需要构建 BVH 的网格
*/
buildBVH(mesh: THREE.Mesh): void;
/**
* 检测两个网格是否相交
* @param meshA - 网格 A
* @param meshB - 网格 B
* @returns 是否相交
*/
checkIntersection(meshA: THREE.Mesh, meshB: THREE.Mesh): boolean;
/**
* 获取两个网格的相交体积
* @param meshA - 网格 A
* @param meshB - 网格 B
* @returns 相交的包围盒,如果不相交则返回 null
*/
getIntersectionVolume(meshA: THREE.Mesh, meshB: THREE.Mesh): THREE.Box3 | null;
/**
* 清理网格的 BVH
* @param mesh - 需要清理 BVH 的网格
*/
disposeBVH(mesh: THREE.Mesh): void;
disposeAll(): void;
}
+158
View File
@@ -0,0 +1,158 @@
import * as THREE from 'three/webgpu';
/**
* UserData 属性枚举
*/
export declare enum UserDataProperty {
/** 选择排除属性,为真的时候,在点击事件进行返回 */
SELECTION = "selection",
/** 场景树排除属性 */
SCENE_TREE_EXCLUDE = "sceneTreeExclude"
}
/**
* 包围盒工具类
* 提供计算物体包围盒的静态方法
*/
export declare class Tool {
/**
* 修改对象及其所有子对象的透明度
* @param object 要修改透明度的对象
* @param opacity 透明度值,范围 0-1
*/
static originalTransparentMap: WeakMap<THREE.Material<THREE.MaterialEventMap>, boolean>;
/**
* 将数值限制在指定区间
* @param value 输入值
* @param min 最小值
* @param max 最大值
* @returns 限制后的值
*/
private static clamp;
/**
* 获取对象上的材质数组
* @param object 目标对象
* @returns 材质数组
*/
private static getObjectMaterials;
/**
* 为对象定义透明度映射属性
* 读取时将材质 opacity 从 sourceMin~sourceMax 映射到 0~1,设置时反向映射回 sourceMin~sourceMax。
* @param object 目标对象(需包含 material
* @param propertyName 挂载到对象上的属性名,默认 opacity
* @param sourceMin 材质真实透明度最小值,默认 0.3
* @param sourceMax 材质真实透明度最大值,默认 1
*/
static defineMaterialOpacityMapping(object: THREE.Mesh, propertyName?: string, sourceMin?: number, sourceMax?: number): void;
/**
* 取消对象上的透明度映射属性
* 可选恢复为材质 opacity 的直接读写绑定(不做区间映射)。
* @param object 目标对象(需包含 material
* @param propertyName 挂载在对象上的属性名,默认 opacity
* @param restoreDirectBinding 是否恢复直接绑定,默认 true
*/
static removeMaterialOpacityMapping(object: THREE.Object3D, propertyName?: string, restoreDirectBinding?: boolean): void;
/**
* 计算物体的包围盒,包括所有子对象
* @param object 要计算包围盒的物体
* @returns 物体的包围盒,如果物体没有几何体则返回 null
*/
static computeBoundingBox(object: THREE.Object3D): THREE.Box3 | null;
/**
* 计算物体包围盒的大小
* @param object 要计算大小的物体
* @returns 包围盒的大小向量,如果物体没有几何体则返回 null
*/
static getBoundingBoxSize(object: THREE.Object3D): THREE.Vector3 | null;
/**
* 计算物体包围盒的中心点
* @param object 要计算中心点的物体
* @returns 包围盒的中心点向量,如果物体没有几何体则返回 null
*/
static getBoundingBoxCenter(object: THREE.Object3D): THREE.Vector3 | null;
/**
* 计算物体包围盒的六个面中心点
* @param object 要计算面中心点的物体
* @returns 六个面的中心点对象,如果物体没有几何体则返回 null
*/
static getBoundingBoxFaceCenters(object: THREE.Object3D): {
YF: THREE.Vector3;
YB: THREE.Vector3;
ZU: THREE.Vector3;
ZD: THREE.Vector3;
XL: THREE.Vector3;
XR: THREE.Vector3;
} | null;
/**
* 遍历场景并查询对象名称
* @param scene 要查询的场景或对象
* @param name 查询的名称
* @param exactMatch 是否精确匹配(true: === 匹配, false: 模糊匹配)
* @returns 匹配的对象列表
*/
static queryObjectsByName(scene: THREE.Object3D, name: string, exactMatch?: boolean): THREE.Object3D[];
/**
* 给 Three.js 对象设置 userData 属性
* @param object 要设置属性的对象
* @param key 属性名
* @param value 属性值
*/
static setUserDataProperty(object: THREE.Object3D, key: string, value: any): void;
/**
* 从 Three.js 对象中移除 userData 属性
* @param object 要移除属性的对象
* @param key 属性名
*/
static removeUserDataProperty(object: THREE.Object3D, key: string): void;
/**
* 给 Three.js 对象设置 meta 中的是否选择排除属性
* @param object 要设置属性的对象
* @param exclude 是否排除选择
*/
static setSelectionExclude(object: THREE.Object3D, exclude?: boolean): void;
/**
* 给 Three.js 对象设置 meta 中的是否场景树排除属性
* @param object 要设置属性的对象
* @param exclude 是否排除场景树
*/
static setSceneTreeExclude(object: THREE.Object3D, exclude?: boolean): void;
/**
* 同时设置选择排除和场景树排除属性
* @param object 要设置属性的对象
* @param exclude 是否排除,默认为 true
*/
static setExcludeAll(object: THREE.Object3D, exclude?: boolean): void;
/**
* 设置对象不可在树菜单显示且不可选择
* @param object 要设置属性的对象
*/
static setHiddenAndUnselectable(object: THREE.Object3D): void;
/**
* 处理单个材质的透明度
* @param object
* @param material 要处理的材质
* @param opacity 透明度值,范围 0-1
*/
static handleMaterialOpacity(object: THREE.Object3D, material: THREE.Material, opacity: number): void;
static setOpacity(object: THREE.Object3D, opacity: number): void;
/**
* 获取对象的透明度值
* @param mesh 要获取透明度的 Mesh 对象
* @param materialIndex 材质索引,当材质为数组时使用,默认为 0
* @returns 透明度值,范围 0-1
*/
static getOpacity(mesh: THREE.Mesh, materialIndex?: number): number;
static getPoints(points: Array<THREE.Vector3 | {
x: number;
y: number;
z: number;
}>): THREE.Vector3[];
/**
* 设置场景中网格的渲染顺序
* @param object 要遍历的根对象
* @param defaultRenderOrder 所有网格的默认渲染顺序值
* @param specificMeshes 可选的特定网格数组及其渲染顺序值
*/
static setRenderOrder(object: THREE.Object3D, defaultRenderOrder: number, specificMeshes?: Array<{
name: string;
renderOrder: number;
}>): void;
}
+3
View File
@@ -0,0 +1,3 @@
export { Tool, UserDataProperty } from "./Tool";
export * from "./CollisionDetector";
export * from "./CSGOperator";
+28
View File
@@ -0,0 +1,28 @@
import * as THREE from 'three/webgpu';
// 扩展 THREE 命名空间,添加 RenderPipeline 接口
declare module 'three/webgpu' {
/**
* 渲染管道类
* 用于管理渲染过程,处理后处理效果等
*/
class RenderPipeline {
outputColorTransform: boolean
/**
* 输出节点
* 用于指定渲染管道的最终输出
*/
outputNode: any;
/**
* 构造函数
* @param renderer - WebGPU 渲染器
*/
constructor(renderer: THREE.WebGPURenderer);
/**
* 渲染场景
*/
render(): void;
}
}