This commit is contained in:
2026-05-18 12:13:34 +08:00
parent 8d784c2939
commit fdc031673f
12 changed files with 361672 additions and 297926 deletions

342
examples/app-global.js Normal file
View File

@ -0,0 +1,342 @@
// 存储 kernel 实例
let kernelInstance = null;
/**
* 初始化应用逻辑 - 注入 kernel 实例
* @param {Object} kernel - SDK kernel 实例
* @returns {Object} kernel 实例
*/
const initApp = (kernel) => {
if (!kernel) {
throw new Error('kernel 实例是必需的');
}
kernelInstance = kernel;
console.log('应用逻辑已初始化kernel 实例已注入');
return kernelInstance;
};
/**
* 获取当前 kernel 实例
*/
const getKernel = () => {
if (!kernelInstance) {
throw new Error('请先调用 initApp(kernel) 初始化 kernel 实例');
}
return kernelInstance;
};
//初始化
const init = async (customConfig = {}) => {
const kernel = getKernel();
const defaultConfig = {
container: document.querySelector('#renderDom'),
modelUrlList: [],
env: { envPath: 'https://sdk.zguiy.com/resurces/hdr/hdr.env', intensity: 1.2, rotationY: 0.3, background: true },
gizmo: {
position: false,
rotation: false,
scale: false
},
outline: {
enable: true,
color: "#2196F3",
thickness: 1,
occlusionStrength: 0.1,
occlusionThreshold: 0.0002
}
};
// 合并用户自定义配置
const config = { ...defaultConfig, ...customConfig };
kernel.init(config);
}
//初始化加载模型
const getAutoLoadModelList = async () => {
const kernel = getKernel();
const url = getApiUrl('/api/models/auto-load/list')
console.log('API URL:', url)
const response = await fetch(url)
const data = await response.json()
const models = data.data // 这就是模型列表
models.forEach(model => {
console.log(model.placement_zone);
if (model.placement_zone) {
const { alpha, border_color, color, show_border, thickness, walls } = model.placement_zone
kernel.dropZone.setData({
color: color,
alpha: +alpha,
thickness: thickness,
showBorder: !show_border,
borderColor: border_color,
walls: walls
});
}
kernel.model.add({
modelId: model.category,
modelUrl: model.file_url,
modelControlType: model.model_control_type,
});
})
}
//获取放置区域
const getPlacementZone = async (sku) => {
const kernel = getKernel();
const response = await fetch(getApiUrl(`/api/product-configs/by-sku/${sku}`));
const result = await response.json();
if (result.code === 200) {
// await initPlacementZoneConfig();
const { enable_placement_zone, wall_divisions } = result.data;
// const {position_x, position_y, position_z} = data;
if (enable_placement_zone && wall_divisions != undefined) {
// 只清除旧的放置区域网格,不清除模型
kernel.dropZone.clearZones();
const divisions = wall_divisions.map(wall => ({
name: wall.name, // 获取最后一个下划线后的部分
divisions: wall.divisions
}))
kernel.dropZone.updateDivisions(divisions);
// 显示放置区域
kernel.dropZone.show();
}
}
}
//执行事件
const getEvent = async (dropzone_data, sku) => {
// 将模型放置到该区域
try {
const response = await fetch(getApiUrl(`/api/product-configs/by-sku/${sku}`));
const result = await response.json();
if (result.code === 200 && result.data) {
console.log('SKU配置数据:', result.data);
console.log('关联事件:', result.data.events);
// 使用 for...of 循环以支持 await
await executeEvent(dropzone_data, result)
} else {
console.log(`未查询到数据`);
}
} catch (error) {
console.error(`查询SKU配置或替换模型失败:`, error);
}
}
//点击放置区域执行事件
const executeEvent = async (dropzone_data, result) => {
const kernel = getKernel();
const { wallName, index, transform } = dropzone_data;
const { position, rotation } = transform;
for (const event of result.data.events) {
if (event.event_type === 'change_model') {
console.log(event.target_data);
const { id, name, file_url, model_control_type, category } = event.target_data;
console.log('替换百叶模型:', event);
console.log('替换百叶模型类型:', category);
// 生成唯一的模型ID
const modelId = id + '_' + Date.now();
// 先记录模型放置(会自动处理替换逻辑)
kernel.dropZone.recordModelPlacement(wallName, index, modelId);
console.log(Math.abs(rotation.y - 90), Math.abs(rotation.y - 90) > 5 ? 'x' : 'z');
// 加载并放置模型
await kernel.model.add({
modelId: modelId,
modelUrl: file_url,
modelControlType: model_control_type,
drag: {
enable: true,
axis: rotation.y === 0 || rotation.y === 180 ? 'x' : 'z',
step: 0.1,
},
transform: {
position: position,
rotation: rotation,
}
});
console.log(`百叶模型已放置为 ${name}`);
}
if (event.event_type === 'change_color') {
const materialName = event.material_name;
const { color, color_map_url, normal_map_url, metallic, roughness } = event.target_data;
console.log('替换百叶模型颜色:', event.target_data);
kernel.material.apply({
target: materialName,
albedoColor: color,
albedoTexture: color_map_url,
normalMap: normal_map_url,
metallic: metallic,
roughness: roughness
});
console.log(`百叶模型颜色已替换为 ${color}`);
}
}
}
//换棚子
const executeEvent2 = async (result) => {
const kernel = getKernel();
// 检查是否有模型更换事件
const hasModelChange = result.data.events.some(e => e.event_type === 'change_model');
// 只有在需要更换模型时才清除
if (hasModelChange) {
kernel.dropZone.clearZones();
kernel.model.removeAll();
}
// 先处理所有 change_model 事件
for (const event of result.data.events) {
if (event.event_type === 'change_model') {
const { target_data } = event;
console.log(event.target_data);
if (!target_data) {
console.error('change_model事件缺少target_data')
return;
};
const { id, name, file_url, model_control_type, category, placement_zone } = target_data;
console.log('替换百叶模型:', event);
console.log('替换百叶模型类型:', category);
if (placement_zone) {
const { alpha, border_color, color, show_border, thickness, walls } = placement_zone
kernel.dropZone.setData({
color: color,
alpha: +alpha,
thickness: thickness,
showBorder: !show_border,
borderColor: border_color,
walls: walls
});
}
// 加载并放置模型(使用 category 作为 modelId
await kernel.model.add({
modelId: category,
modelUrl: file_url,
modelControlType: model_control_type,
})
console.log(`百叶模型已放置为 ${name}`);
}
}
// 等待模型加载完成后,再处理 change_color 事件
for (const event of result.data.events) {
if (event.event_type === 'change_color') {
const materialName = event.material_name;
const { color, color_map_url, normal_map_url, metallic, roughness } = event.target_data;
console.log('替换百叶模型颜色:', event.target_data);
kernel.material.apply({
target: materialName,
albedoColor: color,
albedoTexture: color_map_url,
normalMap: normal_map_url,
metallic: metallic,
roughness: roughness
});
console.log(`百叶模型颜色已替换为 ${color}`);
}
}
}
//加载热点
const getHotspot = async () => {
const kernel = getKernel();
try {
// 从后端获取激活状态的热点列表
const response = await fetch(getApiUrl('/api/hotspots?status=active&page=1&pageSize=100'));
const result = await response.json();
if (result.code === 200 && result.data.list.length > 0) {
// 将后端数据转换为 SDK 需要的格式
const hotspots = result.data.list.map(item => ({
id: item.id,
type: 'hotspot',
name: item.name,
meshName: item.name, // 可以根据实际情况调整
icon: item.image_url,
position: [item.position_x, item.position_y, item.position_z],
radius: item.radius,
color: "#000000",
payload: {
skus: item.skus || [],
},
}));
// 渲染热点
kernel.hotspot.render(hotspots);
console.log('热点渲染成功:', hotspots);
} else {
console.log('没有可用的热点数据');
}
} catch (error) {
console.error('获取热点数据失败:', error);
}
}
//点击右侧按钮自动判断
const getProductConfig = async (sku) => {
try {
const response = await fetch(`${getApiUrl(`/api/product-configs/by-sku/${sku}`)}`);
const result = await response.json();
if (result.code === 200) {
console.log(result.data);
const { enable_placement_zone } = result.data;
// await initPlacementZoneConfig();
if (enable_placement_zone) {
getPlacementZone(sku)
}
else {
executeEvent2(result)
}
}
} catch (error) {
console.error('获取产品配置失败:', error);
}
}
// API 配置
const API_BASE_URL = 'https://ztserver.zguiy.com';
const getApiUrl = (path) => {
return `${API_BASE_URL}${path}`;
};
// 将所有函数挂载到 window.AppLogic
window.AppLogic = {
initApp,
init,
getAutoLoadModelList,
getPlacementZone,
getEvent,
executeEvent,
executeEvent2,
getHotspot,
getProductConfig
};