@konitif/viewer-3d 0.284.2 → 0.285.1
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 +23 -7
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/ledRingCalibration.d.ts +2 -0
- package/dist/ledRingCalibration.d.ts.map +1 -1
- package/dist/ledRingCalibration.js +23 -1
- package/dist/ledRingCalibration.js.map +1 -1
- package/dist/orientationGizmoProjection.d.ts +15 -0
- package/dist/orientationGizmoProjection.d.ts.map +1 -0
- package/dist/orientationGizmoProjection.js +98 -0
- package/dist/orientationGizmoProjection.js.map +1 -0
- package/dist/renderer/ProjectileInteraction.d.ts +2 -0
- package/dist/renderer/ProjectileInteraction.d.ts.map +1 -1
- package/dist/renderer/ProjectileInteraction.js +2 -0
- package/dist/renderer/ProjectileInteraction.js.map +1 -1
- package/dist/renderer/Viewer3DRenderer.d.ts +8 -5
- package/dist/renderer/Viewer3DRenderer.d.ts.map +1 -1
- package/dist/renderer/Viewer3DRenderer.js +84 -53
- package/dist/renderer/Viewer3DRenderer.js.map +1 -1
- package/dist/renderer/VisualGroundLayer.d.ts +2 -37
- package/dist/renderer/VisualGroundLayer.d.ts.map +1 -1
- package/dist/renderer/VisualGroundLayer.js +2 -68
- package/dist/renderer/VisualGroundLayer.js.map +1 -1
- package/dist/visualGroundConfig.d.ts +38 -0
- package/dist/visualGroundConfig.d.ts.map +1 -0
- package/dist/visualGroundConfig.js +69 -0
- package/dist/visualGroundConfig.js.map +1 -0
- package/package.json +19 -3
- package/reference/README.md +2 -2
- package/reference/catalog.json +18 -8
|
@@ -18,7 +18,7 @@ import { SMAAPass } from 'three/examples/jsm/postprocessing/SMAAPass.js';
|
|
|
18
18
|
import { HorizontalTiltShiftShader } from 'three/examples/jsm/shaders/HorizontalTiltShiftShader.js';
|
|
19
19
|
import { VerticalTiltShiftShader } from 'three/examples/jsm/shaders/VerticalTiltShiftShader.js';
|
|
20
20
|
import { getRobotMotionAnimationDuration, interpolateRobotMotionTrackValueAtTime, toRobotMotionJointValue, resolveRobotMotionPlaybackDuration } from './robotViewerMotion.js';
|
|
21
|
-
import { createViewerProjectileLaunchSolution, createViewerProjectileTrajectoryPoints, resolveViewerProjectileChargedLaunchProfile, resolveViewerProjectileImpulse, resolveViewerProjectileLauncherWorldScale, resolveViewerSlingshotReleasePull, stepViewerProjectileAgainstGround } from './ProjectileInteraction.js';
|
|
21
|
+
import { createViewerProjectileLaunchSolution, VIEWER3D_PROJECTILE_PARTICLE_LIMIT, createViewerProjectileTrajectoryPoints, resolveViewerProjectileChargedLaunchProfile, resolveViewerProjectileImpulse, resolveViewerProjectileLauncherWorldScale, resolveViewerSlingshotReleasePull, stepViewerProjectileAgainstGround } from './ProjectileInteraction.js';
|
|
22
22
|
import { createInteractionKeyboardSignal, DEFAULT_VIEWER_INPUT_BINDINGS, VIEWER_PROJECTILE_CHARGE_ACTION_ID, VIEWER_PROJECTILE_LAUNCH_ACTION_ID } from './ViewerInputBindings.js';
|
|
23
23
|
import { ViewerProjectileParticleRenderer } from './ViewerProjectileParticleRenderer.js';
|
|
24
24
|
import { ROBOT_COMPARISON_VISIBILITY_LAYOUT_SHARE, resolveRobotComparisonVisibilityTransitionPhases } from './RobotComparisonVisibilityTransition.js';
|
|
@@ -64,7 +64,7 @@ const ROBOT_VIEWER_SCRUB_PHYSICS_SYNC_MINIMUM_INTERVAL_MS = 1000 / 30;
|
|
|
64
64
|
const ROBOT_VIEWER_PROJECTILE_MASS_KG = 0.18;
|
|
65
65
|
const ROBOT_VIEWER_PROJECTILE_RADIUS_M = 0.03;
|
|
66
66
|
const ROBOT_VIEWER_PROJECTILE_SETTLE_MS = 3_000;
|
|
67
|
-
export
|
|
67
|
+
export { VIEWER3D_PROJECTILE_PARTICLE_LIMIT } from './ProjectileInteraction.js';
|
|
68
68
|
const ROBOT_VIEWER_PROJECTILE_MAX_LIFETIME_MS = 12_000;
|
|
69
69
|
const ROBOT_VIEWER_PROJECTILE_SETTLED_HOLD_MS = 1_300;
|
|
70
70
|
const ROBOT_VIEWER_PROJECTILE_FADE_MS = 900;
|
|
@@ -192,6 +192,7 @@ const VIEWER3D_DEFAULT_CAMERA_POSITION = { x: 1.4, y: 0.9, z: 1.4 };
|
|
|
192
192
|
const VIEWER3D_DEFAULT_CAMERA_TARGET = { x: 0, y: 0.32, z: 0 };
|
|
193
193
|
const EMPTY_MUTED_TRACK_TARGET_SET = new Set();
|
|
194
194
|
export class Viewer3D {
|
|
195
|
+
displayedRecordedPhysicsObservation = null;
|
|
195
196
|
container;
|
|
196
197
|
renderer;
|
|
197
198
|
scene;
|
|
@@ -1201,7 +1202,7 @@ export class Viewer3D {
|
|
|
1201
1202
|
this.playbackTransitionState = null;
|
|
1202
1203
|
}
|
|
1203
1204
|
}
|
|
1204
|
-
async
|
|
1205
|
+
async loadPhysicsSubject(source) {
|
|
1205
1206
|
if (this.destroyed)
|
|
1206
1207
|
return;
|
|
1207
1208
|
const visualAlignment = resolvePhysicsVisualAlignmentProfile(source.metadata?.visualAlignment);
|
|
@@ -1219,7 +1220,7 @@ export class Viewer3D {
|
|
|
1219
1220
|
this.physicsResetBaselineCaptureFrames = 0;
|
|
1220
1221
|
this.physicsAuthoredJointTargets.clear();
|
|
1221
1222
|
this.resetPhysicsPostureCompensation();
|
|
1222
|
-
await this.physicsService.
|
|
1223
|
+
await this.physicsService.loadSubject(source);
|
|
1223
1224
|
if (this.destroyed)
|
|
1224
1225
|
return;
|
|
1225
1226
|
this.resetTemporalProjection();
|
|
@@ -1275,6 +1276,60 @@ export class Viewer3D {
|
|
|
1275
1276
|
getPhysicsSnapshot() {
|
|
1276
1277
|
return this.physicsService.snapshot();
|
|
1277
1278
|
}
|
|
1279
|
+
readDisplayedRobotObservation(timeSeconds) {
|
|
1280
|
+
if (!this.robot)
|
|
1281
|
+
return null;
|
|
1282
|
+
const physical = this.readPhysicsObservation();
|
|
1283
|
+
const jointAngles = this.captureRuntimeHistoryVisualJointStates();
|
|
1284
|
+
const bodies = physical?.bodyTransforms ?? this.physicsService.getBodyTransforms();
|
|
1285
|
+
const root = bodies.find(body => body.metadata?.visualRoot === true) ?? bodies.find(body => body.bodyName === this.physicsVisualRootBodyName);
|
|
1286
|
+
let bodyTransforms = [];
|
|
1287
|
+
if (root && this.physicsVisualRootToRobotMatrix) {
|
|
1288
|
+
this.robot.updateMatrix();
|
|
1289
|
+
const robotMatrix = this.robot.matrix.clone();
|
|
1290
|
+
if (this.robot.parent && this.robot.parent !== this.simulatedRobotPresentationRoot) {
|
|
1291
|
+
this.robot.parent.updateMatrixWorld(true);
|
|
1292
|
+
robotMatrix.premultiply(this.robot.parent.matrixWorld);
|
|
1293
|
+
}
|
|
1294
|
+
const canonicalMatrix = this.createPhysicsCoordinateFrameMatrix(root).invert()
|
|
1295
|
+
.multiply(robotMatrix).multiply(this.physicsVisualRootToRobotMatrix.clone().invert());
|
|
1296
|
+
const position = new Vector3(), rotation = new Quaternion(), scale = new Vector3();
|
|
1297
|
+
canonicalMatrix.decompose(position, rotation, scale);
|
|
1298
|
+
bodyTransforms = [{ ...structuredClone(root), position: { x: position.x, y: position.y, z: position.z }, rotation: { x: rotation.x, y: rotation.y, z: rotation.z, w: rotation.w } }];
|
|
1299
|
+
}
|
|
1300
|
+
const time = Number.isFinite(timeSeconds) ? timeSeconds : physical?.simulatedTimeSeconds ?? 0;
|
|
1301
|
+
return {
|
|
1302
|
+
sampleId: `displayed:${time}:${JSON.stringify(jointAngles)}:${JSON.stringify(bodyTransforms)}`,
|
|
1303
|
+
observedAtMs: performance.now(), simulatedTimeSeconds: time,
|
|
1304
|
+
jointAngles, bodyTransforms, centerOfMass: physical?.centerOfMass ?? null, navigation: null,
|
|
1305
|
+
projectionStage: this.displayedRecordedPhysicsObservation ? 'simulated' : 'authored'
|
|
1306
|
+
};
|
|
1307
|
+
}
|
|
1308
|
+
readPhysicsObservation() {
|
|
1309
|
+
if (this.displayedRecordedPhysicsObservation)
|
|
1310
|
+
return structuredClone(this.displayedRecordedPhysicsObservation);
|
|
1311
|
+
if (this.playbackState?.animation && this.robot) {
|
|
1312
|
+
const jointAngles = this.captureRuntimeHistoryVisualJointStates();
|
|
1313
|
+
const time = this.playbackState.currentTime;
|
|
1314
|
+
return {
|
|
1315
|
+
sampleId: `displayed:${this.playbackState.sourceId ?? 'animation'}:${time}:${JSON.stringify(jointAngles)}`,
|
|
1316
|
+
observedAtMs: performance.now(), simulatedTimeSeconds: time,
|
|
1317
|
+
projectionStage: 'authored', jointAngles, bodyTransforms: [], centerOfMass: null, navigation: null
|
|
1318
|
+
};
|
|
1319
|
+
}
|
|
1320
|
+
const snapshot = this.physicsService.snapshot();
|
|
1321
|
+
const bodies = this.physicsService.getBodyTransforms();
|
|
1322
|
+
if (!snapshot.loadedSourceId || !bodies.length)
|
|
1323
|
+
return null;
|
|
1324
|
+
const metadata = snapshot.backendStatus?.metadata;
|
|
1325
|
+
const time = typeof metadata?.simulatedTime === 'number' ? metadata.simulatedTime : 0;
|
|
1326
|
+
return {
|
|
1327
|
+
sampleId: `${snapshot.engine}:${snapshot.loadedSourceId}:${metadata?.stepCount ?? 0}:${metadata?.stateRevision ?? 0}`,
|
|
1328
|
+
observedAtMs: performance.now(), simulatedTimeSeconds: time,
|
|
1329
|
+
jointAngles: this.capturePhysicsVisualJointAngles(),
|
|
1330
|
+
bodyTransforms: structuredClone(bodies), centerOfMass: this.physicsService.getCenterOfMass(), navigation: null
|
|
1331
|
+
};
|
|
1332
|
+
}
|
|
1278
1333
|
readNavigationPhysicsObservation() {
|
|
1279
1334
|
const snapshot = this.physicsService.snapshot();
|
|
1280
1335
|
if (!snapshot.enabled ||
|
|
@@ -1502,6 +1557,7 @@ export class Viewer3D {
|
|
|
1502
1557
|
return true;
|
|
1503
1558
|
}
|
|
1504
1559
|
resumeRuntimeHistoryLiveProjection() {
|
|
1560
|
+
this.displayedRecordedPhysicsObservation = null;
|
|
1505
1561
|
if (!this.runtimeHistoryReplayActive) {
|
|
1506
1562
|
return;
|
|
1507
1563
|
}
|
|
@@ -2436,6 +2492,7 @@ export class Viewer3D {
|
|
|
2436
2492
|
return this.createMutedTrackTargetSet(mutedTrackTargets);
|
|
2437
2493
|
}
|
|
2438
2494
|
applyRobotPose(animation, time, mutedTrackTargets = [], durationOverride = null) {
|
|
2495
|
+
this.displayedRecordedPhysicsObservation = null;
|
|
2439
2496
|
if (!this.robot) {
|
|
2440
2497
|
return false;
|
|
2441
2498
|
}
|
|
@@ -4101,6 +4158,7 @@ export class Viewer3D {
|
|
|
4101
4158
|
}
|
|
4102
4159
|
const receivedPhysicsSample = sampleId !== this.lastTemporalProjectionSampleId;
|
|
4103
4160
|
if (receivedPhysicsSample) {
|
|
4161
|
+
this.displayedRecordedPhysicsObservation = null;
|
|
4104
4162
|
this.markFrameSignal('physics-observation');
|
|
4105
4163
|
this.lastTemporalProjectionSampleId = sampleId;
|
|
4106
4164
|
this.temporalProjection.ingest({
|
|
@@ -4114,6 +4172,7 @@ export class Viewer3D {
|
|
|
4114
4172
|
});
|
|
4115
4173
|
if (this.options.physicsObservationEnabled) {
|
|
4116
4174
|
this.options.onPhysicsObservation({
|
|
4175
|
+
jointAngles: this.capturePhysicsVisualJointAngles(),
|
|
4117
4176
|
sampleId,
|
|
4118
4177
|
observedAtMs: now,
|
|
4119
4178
|
simulatedTimeSeconds: simulatedTime,
|
|
@@ -4394,6 +4453,22 @@ export class Viewer3D {
|
|
|
4394
4453
|
// never the last live/bake observation left in these projection fields.
|
|
4395
4454
|
this.projectedPhysicsBodyTransforms = bodyTransforms;
|
|
4396
4455
|
this.projectedPhysicsCenterOfMass = centerOfMass;
|
|
4456
|
+
if (viewer.physics?.enabled && bodyTransforms.length > 0) {
|
|
4457
|
+
this.displayedRecordedPhysicsObservation = {
|
|
4458
|
+
projectionStage: 'simulated',
|
|
4459
|
+
sampleId: `recorded:${sample.id}:${sample.timeSeconds}`,
|
|
4460
|
+
observedAtMs: performance.now(), simulatedTimeSeconds: sample.timeSeconds,
|
|
4461
|
+
jointAngles: { ...(viewer.joints ?? {}) },
|
|
4462
|
+
bodyTransforms: structuredClone(bodyTransforms),
|
|
4463
|
+
centerOfMass: viewer.physics.centerOfMass ? { ...viewer.physics.centerOfMass } : null,
|
|
4464
|
+
navigation: null
|
|
4465
|
+
};
|
|
4466
|
+
if (this.options.physicsObservationEnabled)
|
|
4467
|
+
this.options.onPhysicsObservation(structuredClone(this.displayedRecordedPhysicsObservation));
|
|
4468
|
+
}
|
|
4469
|
+
else {
|
|
4470
|
+
this.displayedRecordedPhysicsObservation = null;
|
|
4471
|
+
}
|
|
4397
4472
|
const hasVisualJointStates = viewer.joints && Object.keys(viewer.joints).length > 0;
|
|
4398
4473
|
const visualJointPoseChanged = this.applyRuntimeHistoryVisualJointStates(viewer.joints ?? null);
|
|
4399
4474
|
poseChanged = visualJointPoseChanged;
|
|
@@ -5264,7 +5339,7 @@ export class Viewer3D {
|
|
|
5264
5339
|
}
|
|
5265
5340
|
resolveRobotSupportGeometryBounds(robot, candidates) {
|
|
5266
5341
|
// FSR frames are useful semantic anchors but are intentionally empty in
|
|
5267
|
-
//
|
|
5342
|
+
// an articulated model. Resolve the first candidate that owns rendered geometry
|
|
5268
5343
|
// instead of accepting an empty frame and falling back to whole-body
|
|
5269
5344
|
// bounds, which left the soles visibly above the support floor.
|
|
5270
5345
|
for (const candidate of candidates) {
|
|
@@ -9146,28 +9221,8 @@ export class Viewer3D {
|
|
|
9146
9221
|
resolveEyeRingCalibration() {
|
|
9147
9222
|
const defaults = this.options.ledRingDefaults?.eyes ?? ROBOT_VIEWER_EMPTY_LED_RING_CALIBRATION;
|
|
9148
9223
|
const calibration = this.options.eyeRingCalibration ?? {};
|
|
9149
|
-
const legacyCalibration = calibration;
|
|
9150
9224
|
return {
|
|
9151
|
-
|
|
9152
|
-
forwardOffset: this.resolveFiniteCalibrationNumber(calibration.forwardOffset, defaults.forwardOffset),
|
|
9153
|
-
verticalOffset: this.resolveFiniteCalibrationNumber(calibration.verticalOffset, defaults.verticalOffset),
|
|
9154
|
-
lateralOffset: this.resolveFiniteCalibrationNumber(calibration.lateralOffset, defaults.lateralOffset ?? 0),
|
|
9155
|
-
separation: this.resolveFiniteCalibrationNumber(calibration.separation, defaults.separation),
|
|
9156
|
-
radius: this.resolveFiniteCalibrationNumber(calibration.radius, defaults.radius),
|
|
9157
|
-
stripLength: this.resolveFiniteCalibrationNumber(calibration.stripLength, defaults.stripLength ?? defaults.radius * 2),
|
|
9158
|
-
ledCount: this.resolveFiniteCalibrationNumber(calibration.ledCount, defaults.ledCount),
|
|
9159
|
-
ledSize: this.resolveFiniteCalibrationNumber(calibration.ledSize, defaults.ledSize),
|
|
9160
|
-
rotationX: this.resolveFiniteCalibrationNumber(calibration.rotationX, defaults.rotationX),
|
|
9161
|
-
rotationY: this.resolveFiniteCalibrationNumber(calibration.rotationY ?? legacyCalibration.tiltY, defaults.rotationY),
|
|
9162
|
-
rotationZ: this.resolveFiniteCalibrationNumber(calibration.rotationZ ?? legacyCalibration.tiltX, defaults.rotationZ),
|
|
9163
|
-
isVisible: typeof calibration.isVisible === 'boolean'
|
|
9164
|
-
? calibration.isVisible
|
|
9165
|
-
: defaults.isVisible,
|
|
9166
|
-
mireVisible: typeof calibration.mireVisible === 'boolean'
|
|
9167
|
-
? calibration.mireVisible
|
|
9168
|
-
: defaults.mireVisible,
|
|
9169
|
-
variantCount: this.resolveFiniteCalibrationNumber(calibration.variantCount, defaults.variantCount),
|
|
9170
|
-
variantStep: this.resolveFiniteCalibrationNumber(calibration.variantStep, defaults.variantStep),
|
|
9225
|
+
...resolveViewerLedRingCalibration(calibration, defaults),
|
|
9171
9226
|
zones: this.resolveLedRingCalibrationZones(calibration.zones)
|
|
9172
9227
|
};
|
|
9173
9228
|
}
|
|
@@ -9205,34 +9260,9 @@ export class Viewer3D {
|
|
|
9205
9260
|
resolveFiniteCalibrationNumber(value, fallback) {
|
|
9206
9261
|
return typeof value === 'number' && Number.isFinite(value) ? value : fallback;
|
|
9207
9262
|
}
|
|
9208
|
-
resolveLedLayout(value, fallback = 'circle') {
|
|
9209
|
-
if (value === 'strip' || value === 'circle')
|
|
9210
|
-
return value;
|
|
9211
|
-
return fallback === 'strip' ? 'strip' : 'circle';
|
|
9212
|
-
}
|
|
9213
9263
|
resolveLedRingZoneCalibration(calibration, zoneId) {
|
|
9214
|
-
const base = zoneId === 'eyes'
|
|
9215
|
-
|
|
9216
|
-
: (this.options.ledRingDefaults?.[zoneId] ?? ROBOT_VIEWER_EMPTY_LED_RING_CALIBRATION);
|
|
9217
|
-
const override = calibration.zones?.[zoneId] ?? {};
|
|
9218
|
-
return {
|
|
9219
|
-
layout: this.resolveLedLayout(override.layout, base.layout),
|
|
9220
|
-
forwardOffset: this.resolveFiniteCalibrationNumber(override.forwardOffset, base.forwardOffset),
|
|
9221
|
-
verticalOffset: this.resolveFiniteCalibrationNumber(override.verticalOffset, base.verticalOffset),
|
|
9222
|
-
lateralOffset: this.resolveFiniteCalibrationNumber(override.lateralOffset, base.lateralOffset ?? 0),
|
|
9223
|
-
separation: this.resolveFiniteCalibrationNumber(override.separation, base.separation),
|
|
9224
|
-
radius: this.resolveFiniteCalibrationNumber(override.radius, base.radius),
|
|
9225
|
-
stripLength: this.resolveFiniteCalibrationNumber(override.stripLength, base.stripLength ?? base.radius * 2),
|
|
9226
|
-
ledCount: this.resolveFiniteCalibrationNumber(override.ledCount, base.ledCount),
|
|
9227
|
-
ledSize: this.resolveFiniteCalibrationNumber(override.ledSize, base.ledSize),
|
|
9228
|
-
rotationX: this.resolveFiniteCalibrationNumber(override.rotationX, base.rotationX),
|
|
9229
|
-
rotationY: this.resolveFiniteCalibrationNumber(override.rotationY, base.rotationY),
|
|
9230
|
-
rotationZ: this.resolveFiniteCalibrationNumber(override.rotationZ, base.rotationZ),
|
|
9231
|
-
isVisible: typeof override.isVisible === 'boolean' ? override.isVisible : base.isVisible,
|
|
9232
|
-
mireVisible: typeof override.mireVisible === 'boolean' ? override.mireVisible : base.mireVisible,
|
|
9233
|
-
variantCount: this.resolveFiniteCalibrationNumber(override.variantCount, base.variantCount),
|
|
9234
|
-
variantStep: this.resolveFiniteCalibrationNumber(override.variantStep, base.variantStep)
|
|
9235
|
-
};
|
|
9264
|
+
const base = zoneId === 'eyes' ? calibration : (this.options.ledRingDefaults?.[zoneId] ?? ROBOT_VIEWER_EMPTY_LED_RING_CALIBRATION);
|
|
9265
|
+
return resolveViewerLedRingCalibration(calibration.zones?.[zoneId], base);
|
|
9236
9266
|
}
|
|
9237
9267
|
resolveEyeRingDebugDimensions(calibration) {
|
|
9238
9268
|
const variantCount = Math.max(1, Math.min(7, Math.round(calibration.variantCount)));
|
|
@@ -10652,4 +10682,5 @@ function sampleNavigationPath(points, progress) {
|
|
|
10652
10682
|
}
|
|
10653
10683
|
return points[points.length - 1]?.clone() ?? new Vector3();
|
|
10654
10684
|
}
|
|
10685
|
+
import { resolveViewerLedRingCalibration } from '../ledRingCalibration.js';
|
|
10655
10686
|
//# sourceMappingURL=Viewer3DRenderer.js.map
|