diff --git a/src/editor/engine/BabylonScene.js b/src/editor/engine/BabylonScene.js index 15902b4..b82b57e 100644 --- a/src/editor/engine/BabylonScene.js +++ b/src/editor/engine/BabylonScene.js @@ -1332,6 +1332,9 @@ export class BabylonScene { // При окончании drag — синхронизируем this._gizmo.setOnDragEnd(() => this._onGizmoDragEnd()); + // Во время scale-drag — live-обновление тайлинга studs (кружки одного + // размера, не растягиваются пока тянешь гизмо). + this._gizmo.setOnDrag((mode) => { if (mode === 'scale') this._onGizmoScaleDrag(); }); // Привязка гизмо к выделенному this.selection.setOnSelectionChange((sel) => this._updateGizmoForSelection(sel)); @@ -3547,6 +3550,25 @@ export class BabylonScene { * Гизмо манипулировал объектом — синхронизируем через SelectionManager. * Тип операции (move/rotate/scale) определяется по режиму гизмо. */ + /** + * Во время scale-drag studs-примитива: текстура (faceUV) растягивается + * вместе с mesh.scaling и кружки превращаются в полосы. Чтобы не показывать + * это — временно прячем diffuse/bump-текстуру (плоский цвет). В dragEnd меш + * пересоздаётся с правильным faceUV и текстура возвращается. + */ + _onGizmoScaleDrag() { + if (!this.selection) return; + const sel = this.selection.getSelection?.(); + if (!sel || sel.type !== 'primitive' || sel.material !== 'studs') return; + const mat = sel.mesh?.material; + if (mat && mat.diffuseTexture && !mat._studsHidden) { + mat._studsStash = { diffuse: mat.diffuseTexture, bump: mat.bumpTexture }; + mat.diffuseTexture = null; + mat.bumpTexture = null; + mat._studsHidden = true; + } + } + _onGizmoDragEnd() { if (!this.selection || !this._gizmo) return; const sel = this.selection.getSelection(); diff --git a/src/editor/engine/GizmoController.js b/src/editor/engine/GizmoController.js index 6de0d49..af2c08f 100644 --- a/src/editor/engine/GizmoController.js +++ b/src/editor/engine/GizmoController.js @@ -38,6 +38,7 @@ export class GizmoController { setOnDragEnd(cb) { this._onDragEnd = cb; } setOnDragStart(cb) { this._onDragStart = cb; } + setOnDrag(cb) { this._onDrag = cb; } /** Главный метод — переключить режим. */ setMode(mode) { @@ -88,6 +89,13 @@ export class GizmoController { gizmo.onDragStartObservable.add(() => { if (this._onDragStart) this._onDragStart(); }); + // onDrag (в процессе перетаскивания) — для live-обновления (напр. тайлинг + // studs, чтобы кружки не растягивались пока тянешь scale-гизмо). + if (gizmo.onDragObservable) { + gizmo.onDragObservable.add(() => { + if (this._onDrag) this._onDrag(mode); + }); + } gizmo.onDragEndObservable.add(() => { if (this._onDragEnd) this._onDragEnd(); }); diff --git a/src/editor/engine/PrimitiveManager.js b/src/editor/engine/PrimitiveManager.js index 54dfd52..b666569 100644 --- a/src/editor/engine/PrimitiveManager.js +++ b/src/editor/engine/PrimitiveManager.js @@ -843,7 +843,15 @@ export class PrimitiveManager { const newMesh = this._createMeshForType(typeDef, data.id, data.sx, data.sy, data.sz, data.material, data.studDensity); newMesh.position = oldPos; if (oldRot) newMesh.rotation = oldRot; - newMesh.material = oldMat; + // studs — материал пересоздаём заново (свежий faceUV/тайлинг + текстура + // могла быть временно спрятана во время scale-drag). Иначе переносим старый. + if (data.material === 'studs') { + newMesh._studsDims = { type: data.type, sx: data.sx, sy: data.sy, sz: data.sz, density: data.studDensity }; + this._applyMaterial(newMesh, typeDef, data.color, data.material); + try { oldMat?.dispose(); } catch (e) { /* ignore */ } + } else { + newMesh.material = oldMat; + } newMesh.isPickable = true; newMesh.metadata = { ...oldMesh.metadata }; newMesh.setEnabled(data.visible); @@ -853,24 +861,8 @@ export class PrimitiveManager { catch (e) { /* ignore */ } data.mesh = newMesh; - newMesh._studsDims = { type: data.type, sx: data.sx, sy: data.sy, sz: data.sz, density: data.studDensity }; - // studs-материал: пересчитать тайлинг под новый размер меша. - // Куб уже пересоздан с новым faceUV (тайлинг в геометрии) — uScale=1. - // Для остальных форм пересчитываем uScale/vScale по размеру. - if (data.material === 'studs' && oldMat && oldMat.diffuseTexture) { - if (data.type === 'cube' || data.type === 'trigger') { - oldMat.diffuseTexture.uScale = oldMat.diffuseTexture.vScale = 1; - if (oldMat.bumpTexture) oldMat.bumpTexture.uScale = oldMat.bumpTexture.vScale = 1; - } else { - const tile = _studsTiling(data.type, data.sx, data.sy, data.sz, data.studDensity); - oldMat.diffuseTexture.uScale = tile.u; - oldMat.diffuseTexture.vScale = tile.v; - if (oldMat.bumpTexture) { - oldMat.bumpTexture.uScale = tile.u; - oldMat.bumpTexture.vScale = tile.v; - } - } - } + // _studsDims и материал studs уже выставлены выше (через _applyMaterial + // на новом меше с правильным faceUV/тайлингом). Для не-studs ничего не надо. } /** Удалить инстанс. */