From b46c761373c97532952294451384f75752d75955 Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Sat, 30 May 2026 11:32:21 +0300 Subject: [PATCH] =?UTF-8?q?feat(stereo3d):=20=D0=A4=D0=B0=D0=B7=D0=B0=204?= =?UTF-8?q?=20=E2=80=94=20=D0=B2=D0=B8=D0=B7=D1=83=D0=B0=D0=BB=20(=D0=BF?= =?UTF-8?q?=D0=BE=D0=B4=D0=BF=D0=B8=D1=81=D0=B8=20=D0=BE=D1=81=D0=B5=D0=B9?= =?UTF-8?q?,=20=D1=81=D0=B2=D0=B5=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D1=88=D0=B8=D0=BD,=20=D0=BA=D0=BE=D0=BD=D1=82?= =?UTF-8?q?=D1=80=D0=B0=D1=81=D1=82=20=D1=80=D1=91=D0=B1=D0=B5=D1=80)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - подписи осей X/Y/Z цветами AxesHelper - мягкое additive-свечение вершин (без текстур), вершины поверх рёбер - рёбра контрастнее (opacity 0.9, renderOrder над полупрозрачным телом) - bump stereo.js?v=7 Co-Authored-By: Claude Opus 4.8 (1M context) --- frontend/js/labs/stereo.js | 27 +++++++++++++++++++++++++-- frontend/lab.html | 2 +- plans/STEREO_3D_IMPROVEMENT.md | 8 +++++--- 3 files changed, 31 insertions(+), 6 deletions(-) diff --git a/frontend/js/labs/stereo.js b/frontend/js/labs/stereo.js index 868fab9..11ba084 100644 --- a/frontend/js/labs/stereo.js +++ b/frontend/js/labs/stereo.js @@ -917,6 +917,16 @@ class StereoSim { axes.material.transparent = true; axes.material.opacity = 0.4; this._gridGroup.add(axes); + // axis letters, coloured to match AxesHelper (X red, Y green, Z blue) + const axLabel = (txt, color, pos) => { + const s = this._makeTextSprite(txt, color, 38); + s.position.copy(pos); + s.scale.multiplyScalar(0.85); + this._gridGroup.add(s); + }; + axLabel('X', '#ff5b5b', new THREE.Vector3(6.5, 0.15, 0)); + axLabel('Y', '#5bff8d', new THREE.Vector3(0, 6.6, 0)); + axLabel('Z', '#5b9bff', new THREE.Vector3(0, 0.15, 6.5)); } this._invalidate(); } @@ -1432,13 +1442,15 @@ class StereoSim { this._figGroup.add(new THREE.Mesh(geo, mat)); } - _addEdges(opac = 0.8) { + _addEdges(opac = 0.9) { if (!this.showEdges) return; for (const e of this._edges) { const pts = [e.from, e.to]; const geo = new THREE.BufferGeometry().setFromPoints(pts); const mat = new THREE.LineBasicMaterial({ color: 0xFFFFFF, transparent: true, opacity: opac, linewidth: 2 }); - this._figGroup.add(new THREE.Line(geo, mat)); + const line = new THREE.Line(geo, mat); + line.renderOrder = 2; // draw over the translucent solid for crisp contrast + this._figGroup.add(line); if (this.showEdgeLengths) { const len = e.from.distanceTo(e.to); @@ -1454,10 +1466,21 @@ class StereoSim { _addVerticesAndLabels() { for (const v of this._vertices) { if (this.showVertices) { + // soft additive glow halo (texture-free → safe with _clearGroup disposal) + const gGeo = new THREE.SphereGeometry(0.17, 12, 12); + const gMat = new THREE.MeshBasicMaterial({ + color: 0x9B5DE5, transparent: true, opacity: 0.16, + blending: THREE.AdditiveBlending, depthWrite: false, + }); + const glow = new THREE.Mesh(gGeo, gMat); + glow.position.copy(v.pos); + this._figGroup.add(glow); + const sGeo = new THREE.SphereGeometry(0.08, 12, 12); const sMat = new THREE.MeshBasicMaterial({ color: 0xFFFFFF }); const sphere = new THREE.Mesh(sGeo, sMat); sphere.position.copy(v.pos); + sphere.renderOrder = 3; this._figGroup.add(sphere); } diff --git a/frontend/lab.html b/frontend/lab.html index 3539c85..6e0b251 100644 --- a/frontend/lab.html +++ b/frontend/lab.html @@ -4819,7 +4819,7 @@ - + diff --git a/plans/STEREO_3D_IMPROVEMENT.md b/plans/STEREO_3D_IMPROVEMENT.md index 0fe3f5b..b8b31f8 100644 --- a/plans/STEREO_3D_IMPROVEMENT.md +++ b/plans/STEREO_3D_IMPROVEMENT.md @@ -36,10 +36,12 @@ Бэклог: полное «построение сечения по следам» (продление рёбер, след на грани); readout углов (двугранный/линия-плоскость) — сейчас угол только в 3D-метке. -## Фаза 4 — Визуал +## Фаза 4 — Визуал — ГОТОВО (см. бэклог) -- [ ] 4.1 Материалы: рёбра с anti-alias, подсветка активной грани, свечение вершин. -- [ ] 4.2 Аккуратные оси X/Y/Z с подписями, опциональный фон (тёмный/бумага). +- [x] 4.1 Свечение вершин (мягкий additive-ореол без текстур, безопасно с `_clearGroup`); рёбра контрастнее (opacity 0.9, `renderOrder` поверх полупрозрачного тела), вершины поверх рёбер. _(Подсветка грани по ховеру отложена — текущий centroid-пикинг граней грубоват для плавного hover.)_ +- [x] 4.2 Подписи осей X/Y/Z, цвета совпадают с AxesHelper (X крас., Y зел., Z син.). + +Бэклог: подсветка грани по ховеру (нужен точный raycast по логическим граням); градиентный/бумажный фон (учесть захват в скриншоте). ## Фаза 5 — Интеграция и архитектура