1
This commit is contained in:
@ -24,11 +24,18 @@ type ModelConfig = {
|
||||
|
||||
type ModelControlType = 'rotation' | 'color';
|
||||
|
||||
type ModelTransform = {
|
||||
position?: { x: number; y: number; z: number };
|
||||
rotation?: { x: number; y: number; z: number };
|
||||
scale?: { x: number; y: number; z: number };
|
||||
};
|
||||
|
||||
type ModelMetadata = {
|
||||
modelId: string;
|
||||
modelUrl: string;
|
||||
modelControlType?: ModelControlType;
|
||||
drag?: DragConfig;
|
||||
transform?: ModelTransform;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -224,14 +231,15 @@ export class AppModel extends Monobehiver {
|
||||
modelConfig.modelId,
|
||||
modelConfig.modelUrl,
|
||||
modelConfig.modelControlType,
|
||||
modelConfig.drag
|
||||
modelConfig.drag,
|
||||
modelConfig.transform
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加单个模型
|
||||
*/
|
||||
private async addSingle(modelName: string, modelUrl: string, modelControlType?: ModelControlType, drag?: DragConfig): Promise<LoadResult> {
|
||||
private async addSingle(modelName: string, modelUrl: string, modelControlType?: ModelControlType, drag?: DragConfig, transform?: ModelTransform): Promise<LoadResult> {
|
||||
// 检查是否已存在
|
||||
const existingMeshes = this.modelDic.Get(modelName);
|
||||
if (existingMeshes?.length && !existingMeshes[0].isDisposed()) {
|
||||
@ -254,9 +262,15 @@ export class AppModel extends Monobehiver {
|
||||
modelId: modelName,
|
||||
modelUrl: modelUrl,
|
||||
modelControlType: modelControlType,
|
||||
drag: drag
|
||||
drag: drag,
|
||||
transform: transform
|
||||
});
|
||||
|
||||
// 应用 transform
|
||||
if (transform) {
|
||||
this.applyTransform(modelName, transform);
|
||||
}
|
||||
|
||||
// 配置拖拽功能
|
||||
if (drag) {
|
||||
this.mainApp.appModelDrag?.configureDrag(modelName, drag);
|
||||
@ -283,7 +297,7 @@ export class AppModel extends Monobehiver {
|
||||
EventBridge.modelLoadProgress({ loaded: 0, total, progress: 0, percentage: 0 });
|
||||
|
||||
for (let i = 0; i < models.length; i++) {
|
||||
const { modelId, modelUrl, modelControlType, drag } = models[i];
|
||||
const { modelId, modelUrl, modelControlType, drag, transform } = models[i];
|
||||
|
||||
const result = await this.loadSingleModel(modelUrl, (event) => {
|
||||
this.emitProgress(i, total, modelUrl, event);
|
||||
@ -298,9 +312,15 @@ export class AppModel extends Monobehiver {
|
||||
modelId: modelId,
|
||||
modelUrl: modelUrl,
|
||||
modelControlType: modelControlType,
|
||||
drag: drag
|
||||
drag: drag,
|
||||
transform: transform
|
||||
});
|
||||
|
||||
// 应用 transform
|
||||
if (transform) {
|
||||
this.applyTransform(modelId, transform);
|
||||
}
|
||||
|
||||
// 配置拖拽功能
|
||||
if (drag) {
|
||||
this.mainApp.appModelDrag?.configureDrag(modelId, drag);
|
||||
@ -426,7 +446,8 @@ export class AppModel extends Monobehiver {
|
||||
modelConfig.modelId,
|
||||
modelConfig.modelUrl,
|
||||
modelConfig.modelControlType,
|
||||
modelConfig.drag
|
||||
modelConfig.drag,
|
||||
modelConfig.transform
|
||||
);
|
||||
}
|
||||
|
||||
@ -591,4 +612,59 @@ export class AppModel extends Monobehiver {
|
||||
mesh.scaling.z = scale.z;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 将模型放置到指定的放置区域
|
||||
* @param modelId 模型ID
|
||||
* @param zoneInfo 放置区域信息
|
||||
* @param offsetDistance 距离墙面的偏移距离(默认0.1,正数向外)
|
||||
*/
|
||||
placeToZone(modelId: string, zoneInfo: any, offsetDistance: number = 0): void {
|
||||
const meshes = this.modelDic.Get(modelId);
|
||||
if (!meshes?.length) {
|
||||
console.warn(`Model not found: ${modelId}`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算放置位置:中心点 + 法线方向的偏移
|
||||
const targetPosition = zoneInfo.center.add(zoneInfo.normal.scale(offsetDistance));
|
||||
|
||||
// 计算旋转角度:让模型面向墙面(法线的反方向)
|
||||
const targetDirection = zoneInfo.normal.scale(-1);
|
||||
const angle = Math.atan2(targetDirection.x, targetDirection.z);
|
||||
|
||||
this.getModelTransformTargets(meshes).forEach(mesh => {
|
||||
// 设置位置
|
||||
mesh.position.copyFrom(targetPosition);
|
||||
|
||||
// 设置旋转(只旋转Y轴,让模型面向墙面)
|
||||
if (mesh.rotationQuaternion) {
|
||||
mesh.rotationQuaternion = Quaternion.FromEulerAngles(0, angle, 0);
|
||||
} else {
|
||||
mesh.rotation.set(0, angle, 0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用 transform 到模型
|
||||
* @param modelId 模型ID
|
||||
* @param transform 变换信息
|
||||
*/
|
||||
private applyTransform(modelId: string, transform: ModelTransform): void {
|
||||
// 应用位置
|
||||
if (transform.position) {
|
||||
this.setPosition(modelId, transform.position);
|
||||
}
|
||||
|
||||
// 应用旋转(角度制)
|
||||
if (transform.rotation) {
|
||||
this.setRotation(modelId, transform.rotation, true);
|
||||
}
|
||||
|
||||
// 应用缩放
|
||||
if (transform.scale) {
|
||||
this.setScale(modelId, transform.scale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,6 +92,12 @@ class AppRay extends Monobehiver {
|
||||
const zones = this.mainApp.appDropZone.getPlacementZones();
|
||||
const clickedZone = zones.find(zone => zone.mesh === pickInfo.pickedMesh);
|
||||
if (clickedZone) {
|
||||
// 计算该放置区域的目标位置和旋转
|
||||
const offsetDistance = 0.1;
|
||||
const targetPosition = clickedZone.center.add(clickedZone.normal.scale(offsetDistance));
|
||||
const targetDirection = clickedZone.normal.scale(-1);
|
||||
const angle = Math.atan2(targetDirection.x, targetDirection.z);
|
||||
|
||||
EventBridge.dropZoneClick({
|
||||
wallName: clickedZone.wallName,
|
||||
index: clickedZone.index,
|
||||
@ -99,7 +105,24 @@ class AppRay extends Monobehiver {
|
||||
width: clickedZone.width,
|
||||
height: clickedZone.height,
|
||||
normal: clickedZone.normal,
|
||||
mesh: clickedZone.mesh
|
||||
mesh: clickedZone.mesh,
|
||||
transform: {
|
||||
position: {
|
||||
x: targetPosition.x,
|
||||
y: targetPosition.y,
|
||||
z: targetPosition.z
|
||||
},
|
||||
rotation: {
|
||||
x: 0,
|
||||
y: angle * 180 / Math.PI, // 转换为角度
|
||||
z: 0
|
||||
},
|
||||
scale: {
|
||||
x: 1,
|
||||
y: 1,
|
||||
z: 1
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user