@konitif/viewer-3d 0.285.6 → 0.285.8
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/README.md +15 -0
- package/dist/renderer/CameraController.d.ts +3 -0
- package/dist/renderer/CameraController.d.ts.map +1 -1
- package/dist/renderer/CameraController.js +36 -24
- package/dist/renderer/CameraController.js.map +1 -1
- package/dist/renderer/CardinalGridLayer.d.ts +22 -0
- package/dist/renderer/CardinalGridLayer.d.ts.map +1 -0
- package/dist/renderer/CardinalGridLayer.js +127 -0
- package/dist/renderer/CardinalGridLayer.js.map +1 -0
- package/dist/renderer/OrthographicGroundReflection.d.ts +5 -0
- package/dist/renderer/OrthographicGroundReflection.d.ts.map +1 -0
- package/dist/renderer/OrthographicGroundReflection.js +58 -0
- package/dist/renderer/OrthographicGroundReflection.js.map +1 -0
- package/dist/renderer/PerformanceObservation.d.ts +8 -0
- package/dist/renderer/PerformanceObservation.d.ts.map +1 -0
- package/dist/renderer/PerformanceObservation.js +21 -0
- package/dist/renderer/PerformanceObservation.js.map +1 -0
- package/dist/renderer/SceneAstronomy.d.ts +34 -0
- package/dist/renderer/SceneAstronomy.d.ts.map +1 -0
- package/dist/renderer/SceneAstronomy.js +96 -0
- package/dist/renderer/SceneAstronomy.js.map +1 -0
- package/dist/renderer/SceneDayCycle.d.ts +21 -0
- package/dist/renderer/SceneDayCycle.d.ts.map +1 -0
- package/dist/renderer/SceneDayCycle.js +27 -0
- package/dist/renderer/SceneDayCycle.js.map +1 -0
- package/dist/renderer/SceneEnvironmentLayer.d.ts +26 -0
- package/dist/renderer/SceneEnvironmentLayer.d.ts.map +1 -0
- package/dist/renderer/SceneEnvironmentLayer.js +89 -0
- package/dist/renderer/SceneEnvironmentLayer.js.map +1 -0
- package/dist/renderer/Viewer3DRenderer.d.ts +30 -1
- package/dist/renderer/Viewer3DRenderer.d.ts.map +1 -1
- package/dist/renderer/Viewer3DRenderer.js +74 -11
- package/dist/renderer/Viewer3DRenderer.js.map +1 -1
- package/dist/renderer/VisualGroundLayer.d.ts.map +1 -1
- package/dist/renderer/VisualGroundLayer.js +37 -5
- package/dist/renderer/VisualGroundLayer.js.map +1 -1
- package/dist/renderer/index.d.ts +2 -0
- package/dist/renderer/index.d.ts.map +1 -1
- package/dist/renderer/index.js +2 -0
- package/dist/renderer/index.js.map +1 -1
- package/package.json +1 -1
- package/reference/catalog.json +10 -0
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { ViewerCardinalGridLayer } from './CardinalGridLayer.js';
|
|
2
|
+
import { ViewerSceneEnvironmentLayer } from './SceneEnvironmentLayer.js';
|
|
3
|
+
import { measureViewerOperation } from './PerformanceObservation.js';
|
|
1
4
|
import { createViewerPhysicsFrameQuaternion, resolveViewerSceneYaw, projectViewerImpulseByFrame, projectViewerPointByFrame } from './physics/ViewerPhysicsFrame.js';
|
|
2
5
|
import { resolveViewerJointMapping, selectDirectViewerJointMappings } from './physics/ViewerJointResolution.js';
|
|
3
6
|
import { createPhysicsJointTargetValue, createVisualJointValueFromPhysics, createVisualJointValueFromSource } from './physics/ViewerPhysicsJointMapping.js';
|
|
@@ -257,6 +260,9 @@ export class Viewer3D {
|
|
|
257
260
|
gridHelper = null;
|
|
258
261
|
visualGroundLayer = null;
|
|
259
262
|
keyLight = null;
|
|
263
|
+
cardinalGrid = null;
|
|
264
|
+
sceneDayCycle = null;
|
|
265
|
+
sceneFog = null;
|
|
260
266
|
trajectoryGroup = null;
|
|
261
267
|
contactPointGroup = null;
|
|
262
268
|
physicsDebugGroup = null;
|
|
@@ -700,6 +706,12 @@ export class Viewer3D {
|
|
|
700
706
|
}
|
|
701
707
|
this.scheduleLoop();
|
|
702
708
|
}
|
|
709
|
+
/** Signal a projection-only change made to caller-owned scene contributions.
|
|
710
|
+
* Uses the viewer's existing coalesced frame loop; does not advance simulation or transport.
|
|
711
|
+
*/
|
|
712
|
+
requestPresentationFrame() {
|
|
713
|
+
this.requestRender();
|
|
714
|
+
}
|
|
703
715
|
setStatsVisible(showStats) {
|
|
704
716
|
if (this.options.showStats === showStats) {
|
|
705
717
|
return;
|
|
@@ -729,6 +741,31 @@ export class Viewer3D {
|
|
|
729
741
|
this.globalRafProbeFrame = 0;
|
|
730
742
|
}
|
|
731
743
|
}
|
|
744
|
+
/** Set a static local solar time; the caller owns persistence and playback. */
|
|
745
|
+
setSceneTimeHours(timeHours) {
|
|
746
|
+
this.sceneDayCycle ??= new ViewerSceneEnvironmentLayer(this.scene, this.renderer, this.keyLight, () => this.requestRender(), this.options.transparent);
|
|
747
|
+
this.sceneDayCycle.setFog(this.sceneFog);
|
|
748
|
+
this.sceneDayCycle.setTime(timeHours);
|
|
749
|
+
}
|
|
750
|
+
/** A null density delegates to the environment. Manual density survives day/night and theme changes. */
|
|
751
|
+
setSceneFog(settings) {
|
|
752
|
+
this.sceneFog = settings ? { enabled: settings.enabled, density: typeof settings.density === 'number' && Number.isFinite(settings.density) ? Math.max(0, Math.min(.5, settings.density)) : null } : null;
|
|
753
|
+
if (this.sceneDayCycle)
|
|
754
|
+
this.sceneDayCycle.setFog(this.sceneFog);
|
|
755
|
+
else
|
|
756
|
+
this.updateVisualGroundEnvironment();
|
|
757
|
+
this.requestRender();
|
|
758
|
+
}
|
|
759
|
+
setCardinalGridVisible(visible) {
|
|
760
|
+
if (visible)
|
|
761
|
+
this.cardinalGrid ??= new ViewerCardinalGridLayer(this.scene, () => this.controls.target, this.renderer.domElement.parentElement ?? undefined);
|
|
762
|
+
else {
|
|
763
|
+
this.cardinalGrid?.dispose();
|
|
764
|
+
this.cardinalGrid = null;
|
|
765
|
+
}
|
|
766
|
+
this.requestRender();
|
|
767
|
+
}
|
|
768
|
+
clearSceneTimeHours() { this.sceneDayCycle?.dispose(); this.sceneDayCycle = null; this.applyTheme(); }
|
|
732
769
|
setGridVisible(showGrid) {
|
|
733
770
|
if (this.options.showGrid === showGrid) {
|
|
734
771
|
return;
|
|
@@ -1453,6 +1490,11 @@ export class Viewer3D {
|
|
|
1453
1490
|
getPerformanceSummary() {
|
|
1454
1491
|
return this.performanceMonitor.getSummary();
|
|
1455
1492
|
}
|
|
1493
|
+
performanceObserver = null;
|
|
1494
|
+
/** Borrowed, optional sink. Does not allocate a loop, timer or browser observer. */
|
|
1495
|
+
setPerformanceObserver(observer) {
|
|
1496
|
+
this.performanceObserver = observer;
|
|
1497
|
+
}
|
|
1456
1498
|
setTemporalProjectionMode(mode) {
|
|
1457
1499
|
if (this.temporalProjection.getMode() === mode) {
|
|
1458
1500
|
return;
|
|
@@ -3144,6 +3186,11 @@ export class Viewer3D {
|
|
|
3144
3186
|
this.requestRender();
|
|
3145
3187
|
}
|
|
3146
3188
|
destroy(options = {}) {
|
|
3189
|
+
this.cardinalGrid?.dispose();
|
|
3190
|
+
this.cardinalGrid = null;
|
|
3191
|
+
this.sceneDayCycle?.dispose();
|
|
3192
|
+
this.sceneDayCycle = null;
|
|
3193
|
+
this.performanceObserver = null;
|
|
3147
3194
|
if (this.destroyed) {
|
|
3148
3195
|
return;
|
|
3149
3196
|
}
|
|
@@ -3309,14 +3356,14 @@ export class Viewer3D {
|
|
|
3309
3356
|
}
|
|
3310
3357
|
this.updateVisualGroundShadowCasters();
|
|
3311
3358
|
this.updateVisualGroundFocusTiltPasses();
|
|
3312
|
-
const fogEnabled = this.options.showVisualGround && (config?.components.fogFade ?? true);
|
|
3359
|
+
const fogEnabled = this.sceneFog?.enabled ?? (this.options.showVisualGround && (config?.components.fogFade ?? true));
|
|
3313
3360
|
if (!fogEnabled || this.options.transparent) {
|
|
3314
3361
|
this.scene.fog = null;
|
|
3315
3362
|
return;
|
|
3316
3363
|
}
|
|
3317
3364
|
const themeBackgroundColor = this.resolveThemeColor('--color-background-canvas', '#111722');
|
|
3318
3365
|
const fogColor = this.resolveVisualGroundSkyColor(themeBackgroundColor);
|
|
3319
|
-
const fogDensity = config?.fogDensity ?? DEFAULT_VIEWER_VISUAL_GROUND_CONFIG.fogDensity;
|
|
3366
|
+
const fogDensity = this.sceneFog?.density ?? config?.fogDensity ?? DEFAULT_VIEWER_VISUAL_GROUND_CONFIG.fogDensity;
|
|
3320
3367
|
if (this.scene.fog instanceof FogExp2) {
|
|
3321
3368
|
// Preserve the same fog authority while Viewer settings react. Replacing
|
|
3322
3369
|
// the object on every layer update invalidated material state and could
|
|
@@ -3438,6 +3485,7 @@ export class Viewer3D {
|
|
|
3438
3485
|
if (this.scene.fog instanceof FogExp2) {
|
|
3439
3486
|
this.scene.fog.color.copy(backgroundColor);
|
|
3440
3487
|
}
|
|
3488
|
+
this.sceneDayCycle?.apply();
|
|
3441
3489
|
if (!this.gridHelper) {
|
|
3442
3490
|
this.requestRender();
|
|
3443
3491
|
return;
|
|
@@ -3668,7 +3716,10 @@ export class Viewer3D {
|
|
|
3668
3716
|
this.perspectiveCamera.near = planes.near;
|
|
3669
3717
|
this.perspectiveCamera.far = planes.far;
|
|
3670
3718
|
this.perspectiveCamera.updateProjectionMatrix();
|
|
3671
|
-
|
|
3719
|
+
// Orthographic projection has no perspective eye plane. Include geometry
|
|
3720
|
+
// on both sides of the camera plane, especially the foreground floor
|
|
3721
|
+
// at grazing angles; otherwise it is sliced by a positive near plane.
|
|
3722
|
+
this.orthographicCamera.near = -planes.far;
|
|
3672
3723
|
this.orthographicCamera.far = planes.far;
|
|
3673
3724
|
this.orthographicCamera.updateProjectionMatrix();
|
|
3674
3725
|
}
|
|
@@ -3936,6 +3987,9 @@ export class Viewer3D {
|
|
|
3936
3987
|
if (!this.animationLoop.beginFrame()) {
|
|
3937
3988
|
return;
|
|
3938
3989
|
}
|
|
3990
|
+
measureViewerOperation(this.performanceObserver, 'viewer.loop.cpu', () => this.runFrame());
|
|
3991
|
+
};
|
|
3992
|
+
runFrame() {
|
|
3939
3993
|
const loopStartedAt = performance.now();
|
|
3940
3994
|
const rafNow = loopStartedAt;
|
|
3941
3995
|
this.temporalScheduler.frame(rafNow / 1000);
|
|
@@ -4012,7 +4066,7 @@ export class Viewer3D {
|
|
|
4012
4066
|
const controlsStartedAt = performance.now();
|
|
4013
4067
|
const shouldUpdateControls = this.controls.enabled && (this.controlsActive || this.controlsSettlingFrames > 0);
|
|
4014
4068
|
if (shouldUpdateControls) {
|
|
4015
|
-
this.controls.update();
|
|
4069
|
+
measureViewerOperation(this.performanceObserver, 'viewer.controls.cpu', () => this.controls.update());
|
|
4016
4070
|
}
|
|
4017
4071
|
if (shouldUpdateControls) {
|
|
4018
4072
|
this.markFrameSignal('controls');
|
|
@@ -4097,8 +4151,12 @@ export class Viewer3D {
|
|
|
4097
4151
|
if (shouldContinueLoop && this.animationLoop.isIdle()) {
|
|
4098
4152
|
this.scheduleLoop();
|
|
4099
4153
|
}
|
|
4100
|
-
}
|
|
4154
|
+
}
|
|
4101
4155
|
render() {
|
|
4156
|
+
measureViewerOperation(this.performanceObserver, 'viewer.draw.cpu', () => this.renderScene());
|
|
4157
|
+
}
|
|
4158
|
+
renderScene() {
|
|
4159
|
+
this.cardinalGrid?.update(this.camera);
|
|
4102
4160
|
this.projectComparisonSimulation();
|
|
4103
4161
|
if (this.observedRobotGhostMirrorsSimulatedRobot) {
|
|
4104
4162
|
this.syncObservedRobotGhostFromSimulatedRobot();
|
|
@@ -4814,6 +4872,11 @@ export class Viewer3D {
|
|
|
4814
4872
|
: undefined
|
|
4815
4873
|
};
|
|
4816
4874
|
}
|
|
4875
|
+
/** Invalidate the on-demand projection after caller-owned scene changes. */
|
|
4876
|
+
notifySceneChanged() {
|
|
4877
|
+
if (!this.destroyed)
|
|
4878
|
+
this.requestRender();
|
|
4879
|
+
}
|
|
4817
4880
|
requestRender() {
|
|
4818
4881
|
this.animationLoop.requestRender();
|
|
4819
4882
|
}
|
|
@@ -11063,8 +11126,8 @@ export class Viewer3D {
|
|
|
11063
11126
|
this.updateViewerDebugLayers({ poseHandles: true });
|
|
11064
11127
|
}
|
|
11065
11128
|
setCameraPose(position, target = this.options.cameraTarget, up) {
|
|
11066
|
-
if (this.options.cameraControlMode === 'orbit') {
|
|
11067
|
-
const worldUpPose = resolveWorldUpCameraPose(new Vector3(position.x, position.y, position.z), new Vector3(target.x, target.y, target.z),
|
|
11129
|
+
if (this.options.cameraControlMode === 'orbit' && !up) {
|
|
11130
|
+
const worldUpPose = resolveWorldUpCameraPose(new Vector3(position.x, position.y, position.z), new Vector3(target.x, target.y, target.z), this.camera.up);
|
|
11068
11131
|
this.cameraController.setCameraPose(this.serializeCameraVector(worldUpPose.position), target, this.serializeCameraVector(worldUpPose.up));
|
|
11069
11132
|
return;
|
|
11070
11133
|
}
|
|
@@ -11108,13 +11171,13 @@ export class Viewer3D {
|
|
|
11108
11171
|
z: Number(vector.z.toFixed(4))
|
|
11109
11172
|
};
|
|
11110
11173
|
}
|
|
11111
|
-
transitionCameraPose(position, target = this.options.cameraTarget, durationMs = 420, up) {
|
|
11112
|
-
if (this.options.cameraControlMode === 'orbit') {
|
|
11174
|
+
transitionCameraPose(position, target = this.options.cameraTarget, durationMs = 420, up, transition = {}) {
|
|
11175
|
+
if (this.options.cameraControlMode === 'orbit' && !transition.orbit) {
|
|
11113
11176
|
const worldUpPose = resolveWorldUpCameraPose(new Vector3(position.x, position.y, position.z), new Vector3(target.x, target.y, target.z), up ? new Vector3(up.x, up.y, up.z) : this.camera.up);
|
|
11114
|
-
this.cameraController.transitionCameraPose(this.serializeCameraVector(worldUpPose.position), target, durationMs, this.serializeCameraVector(worldUpPose.up));
|
|
11177
|
+
this.cameraController.transitionCameraPose(this.serializeCameraVector(worldUpPose.position), target, durationMs, this.serializeCameraVector(worldUpPose.up), transition);
|
|
11115
11178
|
return;
|
|
11116
11179
|
}
|
|
11117
|
-
this.cameraController.transitionCameraPose(position, target, durationMs, up);
|
|
11180
|
+
this.cameraController.transitionCameraPose(position, target, durationMs, up, transition);
|
|
11118
11181
|
}
|
|
11119
11182
|
resetCameraView(durationMs = 520) {
|
|
11120
11183
|
this.transitionCameraPose(VIEWER3D_DEFAULT_CAMERA_POSITION, VIEWER3D_DEFAULT_CAMERA_TARGET, durationMs, {
|