1
This commit is contained in:
BIN
ScreenShot_2026-05-13_115939_146.png
Normal file
BIN
ScreenShot_2026-05-13_115939_146.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 718 KiB |
BIN
ScreenShot_2026-05-13_115950_310.png
Normal file
BIN
ScreenShot_2026-05-13_115950_310.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 730 KiB |
BIN
ScreenShot_2026-05-13_120444_480.png
Normal file
BIN
ScreenShot_2026-05-13_120444_480.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 729 KiB |
134
index.html
134
index.html
@ -355,7 +355,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="hotspot-btn">生成热点</button>
|
<button id="hotspot-btn">生成热点</button>
|
||||||
<button id="prevent-btn">生成防止区域</button>
|
<button id="prevent-btn">生成防止区域</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -513,7 +513,6 @@
|
|||||||
|
|
||||||
|
|
||||||
document.querySelector('#hotspot-btn').addEventListener('click', async function () {
|
document.querySelector('#hotspot-btn').addEventListener('click', async function () {
|
||||||
console.log(11111111111111);
|
|
||||||
|
|
||||||
await hotspotRequest();
|
await hotspotRequest();
|
||||||
})
|
})
|
||||||
@ -526,7 +525,7 @@
|
|||||||
if (result.code === 200 && result.data) {
|
if (result.code === 200 && result.data) {
|
||||||
console.log('SKU配置数据:', result.data);
|
console.log('SKU配置数据:', result.data);
|
||||||
console.log('关联事件:', result.data.events);
|
console.log('关联事件:', result.data.events);
|
||||||
|
placementWall(1);
|
||||||
// 使用 for...of 循环以支持 await
|
// 使用 for...of 循环以支持 await
|
||||||
for (const event of result.data.events) {
|
for (const event of result.data.events) {
|
||||||
if (event.event_type === 'change_model') {
|
if (event.event_type === 'change_model') {
|
||||||
@ -738,10 +737,10 @@
|
|||||||
const materialName = window.getCurrentMaterialName();
|
const materialName = window.getCurrentMaterialName();
|
||||||
if (materialName) {
|
if (materialName) {
|
||||||
console.log('切换为白色,材质名:', materialName);
|
console.log('切换为白色,材质名:', materialName);
|
||||||
kernel.material.apply({
|
kernel.material.apply({
|
||||||
target: materialName,
|
target: materialName,
|
||||||
albedoColor: '#FFFFFF',
|
albedoColor: '#FFFFFF',
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log('没有选中材质');
|
console.log('没有选中材质');
|
||||||
}
|
}
|
||||||
@ -752,10 +751,10 @@
|
|||||||
const materialName = window.getCurrentMaterialName();
|
const materialName = window.getCurrentMaterialName();
|
||||||
if (materialName) {
|
if (materialName) {
|
||||||
console.log('切换为黑色,材质名:', materialName);
|
console.log('切换为黑色,材质名:', materialName);
|
||||||
kernel.material.apply({
|
kernel.material.apply({
|
||||||
target: materialName,
|
target: materialName,
|
||||||
albedoColor: '#000000',
|
albedoColor: '#000000',
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
console.log('没有选中材质');
|
console.log('没有选中材质');
|
||||||
}
|
}
|
||||||
@ -821,51 +820,8 @@
|
|||||||
let dropZoneVisible = false;
|
let dropZoneVisible = false;
|
||||||
document.getElementById('dropzone-btn').addEventListener('click', () => {
|
document.getElementById('dropzone-btn').addEventListener('click', () => {
|
||||||
if (!dropZoneVisible) {
|
if (!dropZoneVisible) {
|
||||||
// 先清除旧的放置区域
|
|
||||||
kernel.dropZone.clearAll();
|
|
||||||
|
|
||||||
// 生成新的放置区域(使用新的墙面参数化API)
|
|
||||||
kernel.dropZone.generate({
|
|
||||||
walls: [
|
|
||||||
{
|
|
||||||
name: 'front',
|
|
||||||
startPoint: [-1.4, 0, -1.4],
|
|
||||||
endPoint: [1.4, 0, -1.4],
|
|
||||||
height: 2.3,
|
|
||||||
divisions: 5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'back',
|
|
||||||
startPoint: [50, 0, 50],
|
|
||||||
endPoint: [-50, 0, 50],
|
|
||||||
height: 30,
|
|
||||||
divisions: 5
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'left',
|
|
||||||
startPoint: [-50, 0, 50],
|
|
||||||
endPoint: [-50, 0, -50],
|
|
||||||
height: 30,
|
|
||||||
divisions: 4
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'right',
|
|
||||||
startPoint: [50, 0, -50],
|
|
||||||
endPoint: [50, 0, 50],
|
|
||||||
height: 30,
|
|
||||||
divisions: 4
|
|
||||||
}
|
|
||||||
],
|
|
||||||
color: "#21c7ff",
|
|
||||||
alpha: 0.3,
|
|
||||||
thickness: 2,
|
|
||||||
showBorder: true,
|
|
||||||
borderColor: "#ffffff"
|
|
||||||
});
|
|
||||||
|
|
||||||
// 显示放置区域
|
|
||||||
kernel.dropZone.showAll();
|
|
||||||
dropZoneVisible = true;
|
|
||||||
|
|
||||||
// 更新按钮文字
|
// 更新按钮文字
|
||||||
document.getElementById('dropzone-btn').textContent = '隐藏放置区域';
|
document.getElementById('dropzone-btn').textContent = '隐藏放置区域';
|
||||||
@ -880,6 +836,76 @@
|
|||||||
console.log('已隐藏放置区域');
|
console.log('已隐藏放置区域');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const placementWall = (divisions) => {
|
||||||
|
|
||||||
|
// 先清除旧的放置区域
|
||||||
|
kernel.dropZone.clearAll();
|
||||||
|
|
||||||
|
// 生成新的放置区域(使用新的墙面参数化API)
|
||||||
|
// 调整 baseY 来控制整体高度(正数向上,负数向下)
|
||||||
|
const baseY = 0.08; // 修改这个值来调整整体高度
|
||||||
|
|
||||||
|
// 调整 offset 来控制每个面向外或向内的偏移
|
||||||
|
// 正数 = 向外移动,负数 = 向内移动
|
||||||
|
const wallOffset = -0.07; // 修改这个值来调整墙面偏移
|
||||||
|
|
||||||
|
kernel.dropZone.generate({
|
||||||
|
walls: [
|
||||||
|
{
|
||||||
|
name: 'front',
|
||||||
|
startPoint: [-1.43, baseY, -1.4],
|
||||||
|
endPoint: [1.37, baseY, -1.4],
|
||||||
|
height: 2.2,
|
||||||
|
divisions: divisions,
|
||||||
|
offset: wallOffset // 向外或向内偏移
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'back',
|
||||||
|
startPoint: [1.37, baseY, 1.4],
|
||||||
|
endPoint: [-1.43, baseY, 1.4],
|
||||||
|
height: 2.2,
|
||||||
|
divisions: divisions,
|
||||||
|
offset: wallOffset
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'left',
|
||||||
|
startPoint: [-1.43, baseY, 1.39],
|
||||||
|
endPoint: [-1.43, baseY, -1.43],
|
||||||
|
height: 2.2,
|
||||||
|
divisions: divisions,
|
||||||
|
offset: wallOffset
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'right',
|
||||||
|
startPoint: [1.37, baseY, -1.43],
|
||||||
|
endPoint: [1.37, baseY, 1.4],
|
||||||
|
height: 2.2,
|
||||||
|
divisions: divisions,
|
||||||
|
offset: wallOffset
|
||||||
|
}
|
||||||
|
],
|
||||||
|
color: "#21c7ff",
|
||||||
|
alpha: 0.3,
|
||||||
|
thickness: 2,
|
||||||
|
showBorder: true,
|
||||||
|
borderColor: "#ffffff"
|
||||||
|
});
|
||||||
|
|
||||||
|
// 显示放置区域
|
||||||
|
kernel.dropZone.showAll();
|
||||||
|
dropZoneVisible = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 监听放置区域点击事件
|
||||||
|
kernel.on('dropzone:click', (data) => {
|
||||||
|
console.log('点击了放置区域:', data);
|
||||||
|
console.log('中心点:', data.center);
|
||||||
|
console.log('宽度:', data.width);
|
||||||
|
console.log('高度:', data.height);
|
||||||
|
console.log('法线:', data.normal);
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
18
index.js
18
index.js
@ -28,18 +28,18 @@ const config = {
|
|||||||
|
|
||||||
kernel.init(config);
|
kernel.init(config);
|
||||||
|
|
||||||
const response = await fetch('http://localhost:3001/api/models/auto-load/list')
|
const response = await fetch('http://localhost:3001/api/models/auto-load/list')
|
||||||
const data = await response.json()
|
const data = await response.json()
|
||||||
const models = data.data // 这就是模型列表
|
const models = data.data // 这就是模型列表
|
||||||
console.log(models);
|
console.log(models);
|
||||||
|
|
||||||
models.forEach(model => {
|
models.forEach(model => {
|
||||||
kernel.model.add({
|
kernel.model.add({
|
||||||
modelId: model.id,
|
modelId: model.id,
|
||||||
modelUrl: model.file_url || `http://localhost:3001${model.file_path}`,
|
modelUrl: model.file_url || `http://localhost:3001${model.file_path}`,
|
||||||
modelControlType: model.model_control_type,
|
modelControlType: model.model_control_type,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
|
|
||||||
// kernel.model.add({
|
// kernel.model.add({
|
||||||
// modelId: "框架",
|
// modelId: "框架",
|
||||||
|
|||||||
@ -25,7 +25,7 @@ export class AppCamera extends Monobehiver {
|
|||||||
this.object = new ArcRotateCamera('Camera', Tools.ToRadians(70), Tools.ToRadians(85), 5, new Vector3(0, 2, 0), scene);
|
this.object = new ArcRotateCamera('Camera', Tools.ToRadians(70), Tools.ToRadians(85), 5, new Vector3(0, 2, 0), scene);
|
||||||
this.object.attachControl(canvas, true);
|
this.object.attachControl(canvas, true);
|
||||||
this.object.minZ = 0.01; // 近裁剪面
|
this.object.minZ = 0.01; // 近裁剪面
|
||||||
// this.object.wheelPrecision =999999; // 滚轮缩放精度
|
this.object.wheelPrecision =200; // 滚轮缩放精度
|
||||||
this.object.panningSensibility = 0;
|
this.object.panningSensibility = 0;
|
||||||
|
|
||||||
// 限制垂直角范围,实现上帝视角
|
// 限制垂直角范围,实现上帝视角
|
||||||
|
|||||||
@ -54,6 +54,13 @@ export class AppDropZone {
|
|||||||
return this.placementWall.getZone(wallName, index);
|
return this.placementWall.getZone(wallName, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置点击回调
|
||||||
|
*/
|
||||||
|
setOnZoneClick(callback: (zoneInfo: PlacementZoneInfo) => void): void {
|
||||||
|
this.placementWall.setOnZoneClick(callback);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示所有放置区域
|
* 显示所有放置区域
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Scene, Mesh, MeshBuilder, StandardMaterial, Color3, Vector3 } from '@babylonjs/core';
|
import { Scene, Mesh, MeshBuilder, StandardMaterial, Color3, Vector3, ActionManager, ExecuteCodeAction } from '@babylonjs/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 墙面配置 - 定义一个垂直面的起始和结束坐标
|
* 墙面配置 - 定义一个垂直面的起始和结束坐标
|
||||||
@ -9,6 +9,7 @@ export interface WallConfig {
|
|||||||
endPoint: Vector3; // 结束点坐标(右下角)
|
endPoint: Vector3; // 结束点坐标(右下角)
|
||||||
height: number; // 墙面高度
|
height: number; // 墙面高度
|
||||||
divisions: number; // 分割数(将这个面分成几块)
|
divisions: number; // 分割数(将这个面分成几块)
|
||||||
|
offset?: number; // 偏移量(正数向外,负数向内,默认0)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,6 +41,7 @@ export class AppPlacementWall {
|
|||||||
private scene: Scene;
|
private scene: Scene;
|
||||||
private placementZones: PlacementZoneInfo[] = [];
|
private placementZones: PlacementZoneInfo[] = [];
|
||||||
private borderLines: Mesh[] = [];
|
private borderLines: Mesh[] = [];
|
||||||
|
private onZoneClickCallback?: (zoneInfo: PlacementZoneInfo) => void;
|
||||||
|
|
||||||
constructor(scene: Scene) {
|
constructor(scene: Scene) {
|
||||||
this.scene = scene;
|
this.scene = scene;
|
||||||
@ -83,7 +85,7 @@ export class AppPlacementWall {
|
|||||||
material: StandardMaterial,
|
material: StandardMaterial,
|
||||||
thickness: number
|
thickness: number
|
||||||
): PlacementZoneInfo[] {
|
): PlacementZoneInfo[] {
|
||||||
const { name, startPoint, endPoint, height, divisions } = wall;
|
const { name, startPoint, endPoint, height, divisions, offset = 0 } = wall;
|
||||||
|
|
||||||
// 计算墙面的方向向量和长度
|
// 计算墙面的方向向量和长度
|
||||||
const direction = endPoint.subtract(startPoint);
|
const direction = endPoint.subtract(startPoint);
|
||||||
@ -96,15 +98,18 @@ export class AppPlacementWall {
|
|||||||
// 计算墙面的法线方向(垂直于墙面,指向外侧)
|
// 计算墙面的法线方向(垂直于墙面,指向外侧)
|
||||||
const normal = new Vector3(-normalizedDir.z, 0, normalizedDir.x);
|
const normal = new Vector3(-normalizedDir.z, 0, normalizedDir.x);
|
||||||
|
|
||||||
|
// 应用偏移量(沿着法线方向)
|
||||||
|
const offsetVector = normal.scale(offset);
|
||||||
|
|
||||||
const zones: PlacementZoneInfo[] = [];
|
const zones: PlacementZoneInfo[] = [];
|
||||||
|
|
||||||
for (let i = 0; i < divisions; i++) {
|
for (let i = 0; i < divisions; i++) {
|
||||||
// 计算当前块的中心位置
|
// 计算当前块的中心位置
|
||||||
const offset = blockWidth * (i + 0.5);
|
const offset_i = blockWidth * (i + 0.5);
|
||||||
const centerX = startPoint.x + normalizedDir.x * offset;
|
const centerX = startPoint.x + normalizedDir.x * offset_i;
|
||||||
const centerY = startPoint.y + height / 2;
|
const centerY = startPoint.y + height / 2;
|
||||||
const centerZ = startPoint.z + normalizedDir.z * offset;
|
const centerZ = startPoint.z + normalizedDir.z * offset_i;
|
||||||
const center = new Vector3(centerX, centerY, centerZ);
|
const center = new Vector3(centerX, centerY, centerZ).add(offsetVector);
|
||||||
|
|
||||||
// 创建放置区域平面
|
// 创建放置区域平面
|
||||||
const plane = MeshBuilder.CreatePlane(
|
const plane = MeshBuilder.CreatePlane(
|
||||||
@ -127,6 +132,28 @@ export class AppPlacementWall {
|
|||||||
// 启用拾取
|
// 启用拾取
|
||||||
plane.isPickable = true;
|
plane.isPickable = true;
|
||||||
|
|
||||||
|
// 添加点击事件
|
||||||
|
plane.actionManager = new ActionManager(this.scene);
|
||||||
|
plane.actionManager.registerAction(
|
||||||
|
new ExecuteCodeAction(
|
||||||
|
ActionManager.OnPickTrigger,
|
||||||
|
() => {
|
||||||
|
const zoneInfo: PlacementZoneInfo = {
|
||||||
|
mesh: plane,
|
||||||
|
wallName: name,
|
||||||
|
index: i,
|
||||||
|
center: center.clone(),
|
||||||
|
width: blockWidth,
|
||||||
|
height: height,
|
||||||
|
normal: normal.clone()
|
||||||
|
};
|
||||||
|
if (this.onZoneClickCallback) {
|
||||||
|
this.onZoneClickCallback(zoneInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// 为每个块创建边框
|
// 为每个块创建边框
|
||||||
this.createBlockBorder(name, i, center, blockWidth, height, normalizedDir, normal);
|
this.createBlockBorder(name, i, center, blockWidth, height, normalizedDir, normal);
|
||||||
|
|
||||||
@ -204,13 +231,21 @@ export class AppPlacementWall {
|
|||||||
* 创建墙面边框
|
* 创建墙面边框
|
||||||
*/
|
*/
|
||||||
private createWallBorder(wall: WallConfig, color: string): void {
|
private createWallBorder(wall: WallConfig, color: string): void {
|
||||||
const { name, startPoint, endPoint, height } = wall;
|
const { name, startPoint, endPoint, height, offset = 0 } = wall;
|
||||||
|
|
||||||
// 计算四个角点
|
// 计算法线方向
|
||||||
const bottomLeft = startPoint.clone();
|
const direction = endPoint.subtract(startPoint);
|
||||||
const bottomRight = endPoint.clone();
|
const normalizedDir = direction.normalize();
|
||||||
const topLeft = new Vector3(startPoint.x, startPoint.y + height, startPoint.z);
|
const normal = new Vector3(-normalizedDir.z, 0, normalizedDir.x);
|
||||||
const topRight = new Vector3(endPoint.x, endPoint.y + height, endPoint.z);
|
|
||||||
|
// 应用偏移量
|
||||||
|
const offsetVector = normal.scale(offset);
|
||||||
|
|
||||||
|
// 计算四个角点(应用偏移)
|
||||||
|
const bottomLeft = startPoint.clone().add(offsetVector);
|
||||||
|
const bottomRight = endPoint.clone().add(offsetVector);
|
||||||
|
const topLeft = new Vector3(startPoint.x, startPoint.y + height, startPoint.z).add(offsetVector);
|
||||||
|
const topRight = new Vector3(endPoint.x, endPoint.y + height, endPoint.z).add(offsetVector);
|
||||||
|
|
||||||
// 创建四条边
|
// 创建四条边
|
||||||
const edges = [
|
const edges = [
|
||||||
@ -240,7 +275,8 @@ export class AppPlacementWall {
|
|||||||
private createMaterial(color: string, alpha: number): StandardMaterial {
|
private createMaterial(color: string, alpha: number): StandardMaterial {
|
||||||
const material = new StandardMaterial('placementMaterial', this.scene);
|
const material = new StandardMaterial('placementMaterial', this.scene);
|
||||||
const rgb = this.hexToRgb(color);
|
const rgb = this.hexToRgb(color);
|
||||||
material.diffuseColor = new Color3(rgb.r, rgb.g, rgb.b);
|
material.emissiveColor = new Color3(rgb.r, rgb.g, rgb.b);
|
||||||
|
material.disableLighting = true;
|
||||||
material.alpha = alpha;
|
material.alpha = alpha;
|
||||||
material.backFaceCulling = false;
|
material.backFaceCulling = false;
|
||||||
return material;
|
return material;
|
||||||
@ -283,6 +319,13 @@ export class AppPlacementWall {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置点击回调
|
||||||
|
*/
|
||||||
|
setOnZoneClick(callback: (zoneInfo: PlacementZoneInfo) => void): void {
|
||||||
|
this.onZoneClickCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示所有放置区域
|
* 显示所有放置区域
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -87,6 +87,24 @@ class AppRay extends Monobehiver {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查是否点击的是放置区域
|
||||||
|
if (pickInfo.pickedMesh.name.startsWith('placement_')) {
|
||||||
|
const zones = this.mainApp.appDropZone.getPlacementZones();
|
||||||
|
const clickedZone = zones.find(zone => zone.mesh === pickInfo.pickedMesh);
|
||||||
|
if (clickedZone) {
|
||||||
|
EventBridge.dropZoneClick({
|
||||||
|
wallName: clickedZone.wallName,
|
||||||
|
index: clickedZone.index,
|
||||||
|
center: clickedZone.center,
|
||||||
|
width: clickedZone.width,
|
||||||
|
height: clickedZone.height,
|
||||||
|
normal: clickedZone.normal,
|
||||||
|
mesh: clickedZone.mesh
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.mainApp.appDomTo3D.hideAll()
|
this.mainApp.appDomTo3D.hideAll()
|
||||||
|
|
||||||
const materialName = pickInfo.pickedMesh.material?.name || '';
|
const materialName = pickInfo.pickedMesh.material?.name || '';
|
||||||
|
|||||||
@ -5,7 +5,8 @@ import {
|
|||||||
ModelLoadErrorPayload,
|
ModelLoadErrorPayload,
|
||||||
ModelLoadProgressPayload,
|
ModelLoadProgressPayload,
|
||||||
SceneReadyPayload,
|
SceneReadyPayload,
|
||||||
HotspotClickPayload
|
HotspotClickPayload,
|
||||||
|
DropZoneClickPayload
|
||||||
} from './types';
|
} from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,6 +40,10 @@ export class EventBridge {
|
|||||||
return emit("hotspot:click", payload);
|
return emit("hotspot:click", payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static dropZoneClick(payload: DropZoneClickPayload): Emitter {
|
||||||
|
return emit("dropzone:click", payload);
|
||||||
|
}
|
||||||
|
|
||||||
// Listeners
|
// Listeners
|
||||||
static onModelLoadProgress(callback: (payload: ModelLoadProgressPayload) => void, context?: unknown): Emitter {
|
static onModelLoadProgress(callback: (payload: ModelLoadProgressPayload) => void, context?: unknown): Emitter {
|
||||||
return on("model:load:progress", callback, context);
|
return on("model:load:progress", callback, context);
|
||||||
@ -65,6 +70,11 @@ export class EventBridge {
|
|||||||
static onHotspotClick(callback: (payload: HotspotClickPayload) => void, context?: unknown): Emitter {
|
static onHotspotClick(callback: (payload: HotspotClickPayload) => void, context?: unknown): Emitter {
|
||||||
return on("hotspot:click", callback, context);
|
return on("hotspot:click", callback, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static onDropZoneClick(callback: (payload: DropZoneClickPayload) => void, context?: unknown): Emitter {
|
||||||
|
return on("dropzone:click", callback, context);
|
||||||
|
}
|
||||||
|
|
||||||
static onceSceneReady(callback: (payload: SceneReadyPayload) => void, context?: unknown): Emitter {
|
static onceSceneReady(callback: (payload: SceneReadyPayload) => void, context?: unknown): Emitter {
|
||||||
return once("scene:ready", callback, context);
|
return once("scene:ready", callback, context);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -46,3 +46,13 @@ export type HotspotClickPayload = {
|
|||||||
meshName?: string;
|
meshName?: string;
|
||||||
payload?: unknown;
|
payload?: unknown;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type DropZoneClickPayload = {
|
||||||
|
wallName: string;
|
||||||
|
index: number;
|
||||||
|
center: any;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
normal: any;
|
||||||
|
mesh: any;
|
||||||
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user