@sequent-org/ifc-viewer 1.2.4-ci.41.0 → 1.2.4-ci.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/viewer/Viewer.js +116 -26
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sequent-org/ifc-viewer",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.2.4-ci.
|
|
4
|
+
"version": "1.2.4-ci.43.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "IFC 3D model viewer component for web applications - fully self-contained with local IFCLoader",
|
|
7
7
|
"main": "src/index.js",
|
package/src/viewer/Viewer.js
CHANGED
|
@@ -148,8 +148,10 @@ export class Viewer {
|
|
|
148
148
|
this._sectionClippingActive = false;
|
|
149
149
|
/** @type {WeakMap<THREE.Mesh, any>} */
|
|
150
150
|
this._sectionOriginalMaterial = new WeakMap();
|
|
151
|
-
//
|
|
152
|
-
this.
|
|
151
|
+
// Локальная подсветка "внутри": без теней, с малой дальностью (чтобы не пересвечивать фасад/внешнюю тень)
|
|
152
|
+
this._interiorAssist = { light: null, box: null, enabled: false, lastBoxAt: 0 };
|
|
153
|
+
// Пост-эффекты только "внутри": AO OFF (убирает "сетку"), чуть контраста (без глобального пересвета)
|
|
154
|
+
this._interiorPost = { snapshot: null, contrast: 0.12 };
|
|
153
155
|
|
|
154
156
|
// Snapshot начального состояния для Home
|
|
155
157
|
this._home = {
|
|
@@ -626,6 +628,9 @@ export class Viewer {
|
|
|
626
628
|
this.setSunHeight(5.9);
|
|
627
629
|
this.setShadowsEnabled(this.shadowsEnabled);
|
|
628
630
|
|
|
631
|
+
// Локальная подсветка "внутри" (по умолчанию скрыта)
|
|
632
|
+
this.#ensureInteriorAssistLight();
|
|
633
|
+
|
|
629
634
|
// Демонстрационный куб отключён для чистого прелоадера
|
|
630
635
|
// Оставим сцену пустой до загрузки модели
|
|
631
636
|
// Добавим метод фокусировки объекта
|
|
@@ -753,6 +758,8 @@ export class Viewer {
|
|
|
753
758
|
}
|
|
754
759
|
|
|
755
760
|
if (this.controls) this.controls.update();
|
|
761
|
+
// "Внутренняя" подсветка/пост-эффекты: включаются только когда камера внутри модели
|
|
762
|
+
this.#updateInteriorAssist();
|
|
756
763
|
this._notifyZoomIfChanged();
|
|
757
764
|
if (this.renderer && this.camera && this.scene) {
|
|
758
765
|
// Применим ТОЛЬКО активные (конечные) плоскости отсечения
|
|
@@ -1958,30 +1965,9 @@ export class Viewer {
|
|
|
1958
1965
|
if (next === this._sectionClippingActive) return;
|
|
1959
1966
|
this._sectionClippingActive = next;
|
|
1960
1967
|
|
|
1961
|
-
//
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
if (!this._sectionLightBoost.snapshot) {
|
|
1965
|
-
this._sectionLightBoost.snapshot = {
|
|
1966
|
-
sunIntensity: this.sunLight?.intensity ?? null,
|
|
1967
|
-
ambientIntensity: this.ambientLight?.intensity ?? null,
|
|
1968
|
-
};
|
|
1969
|
-
}
|
|
1970
|
-
if (this.sunLight && Number.isFinite(this._sectionLightBoost.snapshot.sunIntensity)) {
|
|
1971
|
-
this.sunLight.intensity = this._sectionLightBoost.snapshot.sunIntensity * this._sectionLightBoost.mul;
|
|
1972
|
-
}
|
|
1973
|
-
if (this.ambientLight && Number.isFinite(this._sectionLightBoost.snapshot.ambientIntensity)) {
|
|
1974
|
-
this.ambientLight.intensity = this._sectionLightBoost.snapshot.ambientIntensity * this._sectionLightBoost.mul;
|
|
1975
|
-
}
|
|
1976
|
-
} else {
|
|
1977
|
-
const snap = this._sectionLightBoost.snapshot;
|
|
1978
|
-
if (snap) {
|
|
1979
|
-
if (this.sunLight && Number.isFinite(snap.sunIntensity)) this.sunLight.intensity = snap.sunIntensity;
|
|
1980
|
-
if (this.ambientLight && Number.isFinite(snap.ambientIntensity)) this.ambientLight.intensity = snap.ambientIntensity;
|
|
1981
|
-
}
|
|
1982
|
-
this._sectionLightBoost.snapshot = null;
|
|
1983
|
-
}
|
|
1984
|
-
} catch (_) {}
|
|
1968
|
+
// Важно: никаких глобальных усилений света/яркости на само включение сечения.
|
|
1969
|
+
// Подсветка делается локально и только когда камера "внутри".
|
|
1970
|
+
try { this.#updateInteriorAssist(true); } catch (_) {}
|
|
1985
1971
|
|
|
1986
1972
|
// 1) self-shadowing (комнаты/стены)
|
|
1987
1973
|
if (this.activeModel) {
|
|
@@ -2002,6 +1988,110 @@ export class Viewer {
|
|
|
2002
1988
|
try { if (this.renderer?.shadowMap) this.renderer.shadowMap.needsUpdate = true; } catch (_) {}
|
|
2003
1989
|
}
|
|
2004
1990
|
|
|
1991
|
+
#ensureInteriorAssistLight() {
|
|
1992
|
+
if (!this.scene) return;
|
|
1993
|
+
if (this._interiorAssist.light) return;
|
|
1994
|
+
try {
|
|
1995
|
+
// Небольшой "fill light" около камеры. Без теней, чтобы не ломать внешнюю тень.
|
|
1996
|
+
const light = new THREE.PointLight(0xffffff, 0.9, 6.5, 2.0);
|
|
1997
|
+
light.castShadow = false;
|
|
1998
|
+
light.visible = false;
|
|
1999
|
+
light.name = 'interior-assist-light';
|
|
2000
|
+
this.scene.add(light);
|
|
2001
|
+
this._interiorAssist.light = light;
|
|
2002
|
+
} catch (_) {
|
|
2003
|
+
this._interiorAssist.light = null;
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
|
|
2007
|
+
#isCameraInsideModelBox() {
|
|
2008
|
+
const model = this.activeModel;
|
|
2009
|
+
if (!model || !this.camera) return false;
|
|
2010
|
+
const now = performance?.now?.() ?? Date.now();
|
|
2011
|
+
// Обновляем bbox не чаще ~4 раза/сек (достаточно; модель обычно статична)
|
|
2012
|
+
if (!this._interiorAssist.box || (now - (this._interiorAssist.lastBoxAt || 0)) > 250) {
|
|
2013
|
+
try {
|
|
2014
|
+
this._interiorAssist.box = new THREE.Box3().setFromObject(model);
|
|
2015
|
+
this._interiorAssist.lastBoxAt = now;
|
|
2016
|
+
} catch (_) {
|
|
2017
|
+
this._interiorAssist.box = null;
|
|
2018
|
+
}
|
|
2019
|
+
}
|
|
2020
|
+
const box = this._interiorAssist.box;
|
|
2021
|
+
if (!box) return false;
|
|
2022
|
+
const p = this.camera.position;
|
|
2023
|
+
const eps = 0.05;
|
|
2024
|
+
return (
|
|
2025
|
+
p.x > (box.min.x + eps) && p.x < (box.max.x - eps) &&
|
|
2026
|
+
p.y > (box.min.y + eps) && p.y < (box.max.y - eps) &&
|
|
2027
|
+
p.z > (box.min.z + eps) && p.z < (box.max.z - eps)
|
|
2028
|
+
);
|
|
2029
|
+
}
|
|
2030
|
+
|
|
2031
|
+
#updateInteriorAssist(force = false) {
|
|
2032
|
+
if (!this._sectionClippingActive) {
|
|
2033
|
+
if (this._interiorAssist.enabled || force) {
|
|
2034
|
+
this._interiorAssist.enabled = false;
|
|
2035
|
+
if (this._interiorAssist.light) this._interiorAssist.light.visible = false;
|
|
2036
|
+
this.#restoreInteriorPost();
|
|
2037
|
+
}
|
|
2038
|
+
return;
|
|
2039
|
+
}
|
|
2040
|
+
|
|
2041
|
+
this.#ensureInteriorAssistLight();
|
|
2042
|
+
const inside = this.#isCameraInsideModelBox();
|
|
2043
|
+
if (inside !== this._interiorAssist.enabled || force) {
|
|
2044
|
+
this._interiorAssist.enabled = inside;
|
|
2045
|
+
if (this._interiorAssist.light) this._interiorAssist.light.visible = inside;
|
|
2046
|
+
if (inside) this.#applyInteriorPost();
|
|
2047
|
+
else this.#restoreInteriorPost();
|
|
2048
|
+
}
|
|
2049
|
+
// Следуем за камерой, если активны
|
|
2050
|
+
if (inside && this._interiorAssist.light) {
|
|
2051
|
+
try { this._interiorAssist.light.position.copy(this.camera.position); } catch (_) {}
|
|
2052
|
+
}
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
#applyInteriorPost() {
|
|
2056
|
+
// AO OFF + лёгкий контраст только "внутри"
|
|
2057
|
+
if (!this._interiorPost.snapshot) {
|
|
2058
|
+
this._interiorPost.snapshot = {
|
|
2059
|
+
ao: { ...this.visual.ao },
|
|
2060
|
+
color: { ...this.visual.color },
|
|
2061
|
+
};
|
|
2062
|
+
}
|
|
2063
|
+
try { this.setAOEnabled(false); } catch (_) {}
|
|
2064
|
+
try {
|
|
2065
|
+
this.setColorCorrectionEnabled(true);
|
|
2066
|
+
this.setColorContrast(this._interiorPost.contrast);
|
|
2067
|
+
// brightness не трогаем, чтобы не пересвечивать
|
|
2068
|
+
} catch (_) {}
|
|
2069
|
+
}
|
|
2070
|
+
|
|
2071
|
+
#restoreInteriorPost() {
|
|
2072
|
+
const snap = this._interiorPost.snapshot;
|
|
2073
|
+
if (!snap) return;
|
|
2074
|
+
try {
|
|
2075
|
+
this.setAOEnabled(!!snap.ao?.enabled);
|
|
2076
|
+
if (typeof snap.ao?.intensity === 'number') this.setAOIntensity(snap.ao.intensity);
|
|
2077
|
+
if (typeof snap.ao?.radius === 'number') this.setAORadius(snap.ao.radius);
|
|
2078
|
+
if (typeof snap.ao?.minDistance === 'number') this.visual.ao.minDistance = snap.ao.minDistance;
|
|
2079
|
+
if (typeof snap.ao?.maxDistance === 'number') this.visual.ao.maxDistance = snap.ao.maxDistance;
|
|
2080
|
+
if (this._ssaoPass) {
|
|
2081
|
+
this._ssaoPass.minDistance = this.visual.ao.minDistance;
|
|
2082
|
+
this._ssaoPass.maxDistance = this.visual.ao.maxDistance;
|
|
2083
|
+
}
|
|
2084
|
+
} catch (_) {}
|
|
2085
|
+
try {
|
|
2086
|
+
this.setColorCorrectionEnabled(!!snap.color?.enabled);
|
|
2087
|
+
if (typeof snap.color?.hue === 'number') this.setColorHue(snap.color.hue);
|
|
2088
|
+
if (typeof snap.color?.saturation === 'number') this.setColorSaturation(snap.color.saturation);
|
|
2089
|
+
if (typeof snap.color?.brightness === 'number') this.setColorBrightness(snap.color.brightness);
|
|
2090
|
+
if (typeof snap.color?.contrast === 'number') this.setColorContrast(snap.color.contrast);
|
|
2091
|
+
} catch (_) {}
|
|
2092
|
+
this._interiorPost.snapshot = null;
|
|
2093
|
+
}
|
|
2094
|
+
|
|
2005
2095
|
/**
|
|
2006
2096
|
* Дамп текущих параметров тест-пресета в консоль.
|
|
2007
2097
|
*/
|