@konitif/viewer-3d 0.284.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.
Files changed (175) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +34 -0
  3. package/dist/balanceFootprintDefinition.d.ts +7 -0
  4. package/dist/balanceFootprintDefinition.d.ts.map +1 -0
  5. package/dist/balanceFootprintDefinition.js +2 -0
  6. package/dist/balanceFootprintDefinition.js.map +1 -0
  7. package/dist/diagnosticContactDefinition.d.ts +7 -0
  8. package/dist/diagnosticContactDefinition.d.ts.map +1 -0
  9. package/dist/diagnosticContactDefinition.js +2 -0
  10. package/dist/diagnosticContactDefinition.js.map +1 -0
  11. package/dist/handTipDefinition.d.ts +13 -0
  12. package/dist/handTipDefinition.d.ts.map +1 -0
  13. package/dist/handTipDefinition.js +2 -0
  14. package/dist/handTipDefinition.js.map +1 -0
  15. package/dist/index.d.ts +41 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +19 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/jointHandleDefinition.d.ts +23 -0
  20. package/dist/jointHandleDefinition.d.ts.map +1 -0
  21. package/dist/jointHandleDefinition.js +2 -0
  22. package/dist/jointHandleDefinition.js.map +1 -0
  23. package/dist/ledPlacementDefinition.d.ts +38 -0
  24. package/dist/ledPlacementDefinition.d.ts.map +1 -0
  25. package/dist/ledPlacementDefinition.js +2 -0
  26. package/dist/ledPlacementDefinition.js.map +1 -0
  27. package/dist/ledReferenceFrame.d.ts +26 -0
  28. package/dist/ledReferenceFrame.d.ts.map +1 -0
  29. package/dist/ledReferenceFrame.js +2 -0
  30. package/dist/ledReferenceFrame.js.map +1 -0
  31. package/dist/ledRingCalibration.d.ts +22 -0
  32. package/dist/ledRingCalibration.d.ts.map +1 -0
  33. package/dist/ledRingCalibration.js +2 -0
  34. package/dist/ledRingCalibration.js.map +1 -0
  35. package/dist/renderer/AnimationLoop.d.ts +18 -0
  36. package/dist/renderer/AnimationLoop.d.ts.map +1 -0
  37. package/dist/renderer/AnimationLoop.js +39 -0
  38. package/dist/renderer/AnimationLoop.js.map +1 -0
  39. package/dist/renderer/CameraController.d.ts +154 -0
  40. package/dist/renderer/CameraController.d.ts.map +1 -0
  41. package/dist/renderer/CameraController.js +469 -0
  42. package/dist/renderer/CameraController.js.map +1 -0
  43. package/dist/renderer/NavigationPhysicsObservation.d.ts +25 -0
  44. package/dist/renderer/NavigationPhysicsObservation.d.ts.map +1 -0
  45. package/dist/renderer/NavigationPhysicsObservation.js +81 -0
  46. package/dist/renderer/NavigationPhysicsObservation.js.map +1 -0
  47. package/dist/renderer/ObservedRobotGroundingProjection.d.ts +206 -0
  48. package/dist/renderer/ObservedRobotGroundingProjection.d.ts.map +1 -0
  49. package/dist/renderer/ObservedRobotGroundingProjection.js +522 -0
  50. package/dist/renderer/ObservedRobotGroundingProjection.js.map +1 -0
  51. package/dist/renderer/ObservedRobotPresentationBuffer.d.ts +71 -0
  52. package/dist/renderer/ObservedRobotPresentationBuffer.d.ts.map +1 -0
  53. package/dist/renderer/ObservedRobotPresentationBuffer.js +226 -0
  54. package/dist/renderer/ObservedRobotPresentationBuffer.js.map +1 -0
  55. package/dist/renderer/PerformanceMonitor.d.ts +38 -0
  56. package/dist/renderer/PerformanceMonitor.d.ts.map +1 -0
  57. package/dist/renderer/PerformanceMonitor.js +84 -0
  58. package/dist/renderer/PerformanceMonitor.js.map +1 -0
  59. package/dist/renderer/ProjectileInteraction.d.ts +57 -0
  60. package/dist/renderer/ProjectileInteraction.d.ts.map +1 -0
  61. package/dist/renderer/ProjectileInteraction.js +152 -0
  62. package/dist/renderer/ProjectileInteraction.js.map +1 -0
  63. package/dist/renderer/RobotComparisonVisibilityTransition.d.ts +12 -0
  64. package/dist/renderer/RobotComparisonVisibilityTransition.d.ts.map +1 -0
  65. package/dist/renderer/RobotComparisonVisibilityTransition.js +23 -0
  66. package/dist/renderer/RobotComparisonVisibilityTransition.js.map +1 -0
  67. package/dist/renderer/RobotPoseTransition.d.ts +34 -0
  68. package/dist/renderer/RobotPoseTransition.d.ts.map +1 -0
  69. package/dist/renderer/RobotPoseTransition.js +66 -0
  70. package/dist/renderer/RobotPoseTransition.js.map +1 -0
  71. package/dist/renderer/RobotPostureCompensation.d.ts +31 -0
  72. package/dist/renderer/RobotPostureCompensation.d.ts.map +1 -0
  73. package/dist/renderer/RobotPostureCompensation.js +60 -0
  74. package/dist/renderer/RobotPostureCompensation.js.map +1 -0
  75. package/dist/renderer/SelectionController.d.ts +24 -0
  76. package/dist/renderer/SelectionController.d.ts.map +1 -0
  77. package/dist/renderer/SelectionController.js +68 -0
  78. package/dist/renderer/SelectionController.js.map +1 -0
  79. package/dist/renderer/TemporalProjectionModel.d.ts +71 -0
  80. package/dist/renderer/TemporalProjectionModel.d.ts.map +1 -0
  81. package/dist/renderer/TemporalProjectionModel.js +363 -0
  82. package/dist/renderer/TemporalProjectionModel.js.map +1 -0
  83. package/dist/renderer/Viewer3DRenderer.d.ts +1137 -0
  84. package/dist/renderer/Viewer3DRenderer.d.ts.map +1 -0
  85. package/dist/renderer/Viewer3DRenderer.js +10655 -0
  86. package/dist/renderer/Viewer3DRenderer.js.map +1 -0
  87. package/dist/renderer/ViewerExperimentCollector.d.ts +27 -0
  88. package/dist/renderer/ViewerExperimentCollector.d.ts.map +1 -0
  89. package/dist/renderer/ViewerExperimentCollector.js +2 -0
  90. package/dist/renderer/ViewerExperimentCollector.js.map +1 -0
  91. package/dist/renderer/ViewerExperimentPort.d.ts +19 -0
  92. package/dist/renderer/ViewerExperimentPort.d.ts.map +1 -0
  93. package/dist/renderer/ViewerExperimentPort.js +2 -0
  94. package/dist/renderer/ViewerExperimentPort.js.map +1 -0
  95. package/dist/renderer/ViewerFrameSignals.d.ts +13 -0
  96. package/dist/renderer/ViewerFrameSignals.d.ts.map +1 -0
  97. package/dist/renderer/ViewerFrameSignals.js +73 -0
  98. package/dist/renderer/ViewerFrameSignals.js.map +1 -0
  99. package/dist/renderer/ViewerHistoryData.d.ts +59 -0
  100. package/dist/renderer/ViewerHistoryData.d.ts.map +1 -0
  101. package/dist/renderer/ViewerHistoryData.js +2 -0
  102. package/dist/renderer/ViewerHistoryData.js.map +1 -0
  103. package/dist/renderer/ViewerHistoryPort.d.ts +15 -0
  104. package/dist/renderer/ViewerHistoryPort.d.ts.map +1 -0
  105. package/dist/renderer/ViewerHistoryPort.js +2 -0
  106. package/dist/renderer/ViewerHistoryPort.js.map +1 -0
  107. package/dist/renderer/ViewerIncarnationHealth.d.ts +14 -0
  108. package/dist/renderer/ViewerIncarnationHealth.d.ts.map +1 -0
  109. package/dist/renderer/ViewerIncarnationHealth.js +13 -0
  110. package/dist/renderer/ViewerIncarnationHealth.js.map +1 -0
  111. package/dist/renderer/ViewerInputBindings.d.ts +19 -0
  112. package/dist/renderer/ViewerInputBindings.d.ts.map +1 -0
  113. package/dist/renderer/ViewerInputBindings.js +44 -0
  114. package/dist/renderer/ViewerInputBindings.js.map +1 -0
  115. package/dist/renderer/ViewerMetadata.d.ts +11 -0
  116. package/dist/renderer/ViewerMetadata.d.ts.map +1 -0
  117. package/dist/renderer/ViewerMetadata.js +8 -0
  118. package/dist/renderer/ViewerMetadata.js.map +1 -0
  119. package/dist/renderer/ViewerPlaybackCompletionPolicy.d.ts +29 -0
  120. package/dist/renderer/ViewerPlaybackCompletionPolicy.d.ts.map +1 -0
  121. package/dist/renderer/ViewerPlaybackCompletionPolicy.js +27 -0
  122. package/dist/renderer/ViewerPlaybackCompletionPolicy.js.map +1 -0
  123. package/dist/renderer/ViewerProjectileParticleRenderer.d.ts +21 -0
  124. package/dist/renderer/ViewerProjectileParticleRenderer.d.ts.map +1 -0
  125. package/dist/renderer/ViewerProjectileParticleRenderer.js +134 -0
  126. package/dist/renderer/ViewerProjectileParticleRenderer.js.map +1 -0
  127. package/dist/renderer/ViewerResizePresentation.d.ts +16 -0
  128. package/dist/renderer/ViewerResizePresentation.d.ts.map +1 -0
  129. package/dist/renderer/ViewerResizePresentation.js +12 -0
  130. package/dist/renderer/ViewerResizePresentation.js.map +1 -0
  131. package/dist/renderer/ViewerTemporalProjectionExperimentAdapter.d.ts +34 -0
  132. package/dist/renderer/ViewerTemporalProjectionExperimentAdapter.d.ts.map +1 -0
  133. package/dist/renderer/ViewerTemporalProjectionExperimentAdapter.js +130 -0
  134. package/dist/renderer/ViewerTemporalProjectionExperimentAdapter.js.map +1 -0
  135. package/dist/renderer/ViewerTemporalScheduler.d.ts +6 -0
  136. package/dist/renderer/ViewerTemporalScheduler.d.ts.map +1 -0
  137. package/dist/renderer/ViewerTemporalScheduler.js +12 -0
  138. package/dist/renderer/ViewerTemporalScheduler.js.map +1 -0
  139. package/dist/renderer/VisualGroundLayer.d.ts +110 -0
  140. package/dist/renderer/VisualGroundLayer.d.ts.map +1 -0
  141. package/dist/renderer/VisualGroundLayer.js +576 -0
  142. package/dist/renderer/VisualGroundLayer.js.map +1 -0
  143. package/dist/renderer/displayFrameRate.d.ts +5 -0
  144. package/dist/renderer/displayFrameRate.d.ts.map +1 -0
  145. package/dist/renderer/displayFrameRate.js +23 -0
  146. package/dist/renderer/displayFrameRate.js.map +1 -0
  147. package/dist/renderer/index.d.ts +20 -0
  148. package/dist/renderer/index.d.ts.map +1 -0
  149. package/dist/renderer/index.js +18 -0
  150. package/dist/renderer/index.js.map +1 -0
  151. package/dist/renderer/physics/ViewerJointResolution.d.ts +19 -0
  152. package/dist/renderer/physics/ViewerJointResolution.d.ts.map +1 -0
  153. package/dist/renderer/physics/ViewerJointResolution.js +24 -0
  154. package/dist/renderer/physics/ViewerJointResolution.js.map +1 -0
  155. package/dist/renderer/physics/ViewerPhysicsFrame.d.ts +9 -0
  156. package/dist/renderer/physics/ViewerPhysicsFrame.d.ts.map +1 -0
  157. package/dist/renderer/physics/ViewerPhysicsFrame.js +26 -0
  158. package/dist/renderer/physics/ViewerPhysicsFrame.js.map +1 -0
  159. package/dist/renderer/physics/ViewerPhysicsJointMapping.d.ts +11 -0
  160. package/dist/renderer/physics/ViewerPhysicsJointMapping.d.ts.map +1 -0
  161. package/dist/renderer/physics/ViewerPhysicsJointMapping.js +20 -0
  162. package/dist/renderer/physics/ViewerPhysicsJointMapping.js.map +1 -0
  163. package/dist/renderer/physics/ViewerPhysicsMetadata.d.ts +20 -0
  164. package/dist/renderer/physics/ViewerPhysicsMetadata.d.ts.map +1 -0
  165. package/dist/renderer/physics/ViewerPhysicsMetadata.js +49 -0
  166. package/dist/renderer/physics/ViewerPhysicsMetadata.js.map +1 -0
  167. package/dist/renderer/robotViewerMotion.d.ts +49 -0
  168. package/dist/renderer/robotViewerMotion.d.ts.map +1 -0
  169. package/dist/renderer/robotViewerMotion.js +253 -0
  170. package/dist/renderer/robotViewerMotion.js.map +1 -0
  171. package/dist/supportDefinition.d.ts +11 -0
  172. package/dist/supportDefinition.d.ts.map +1 -0
  173. package/dist/supportDefinition.js +2 -0
  174. package/dist/supportDefinition.js.map +1 -0
  175. package/package.json +52 -0
@@ -0,0 +1,226 @@
1
+ import { interpolateJointAngle } from './TemporalProjectionModel.js';
2
+ const DEFAULT_CONFIG = {
3
+ minimumTransitionMs: 16,
4
+ maximumTransitionMs: 120,
5
+ maximumSampleGapMs: 250
6
+ };
7
+ const EMPTY_STATUS = {
8
+ mode: 'interpolated',
9
+ state: 'empty',
10
+ fallbackReason: 'insufficient_samples',
11
+ provenance: null,
12
+ sourceSampleIds: [],
13
+ interpolationAlpha: 1,
14
+ transitionDurationMs: 0,
15
+ active: false
16
+ };
17
+ /**
18
+ * Reconstructs only the visible pose of an observed robot between admitted
19
+ * telemetry samples. Source observations remain immutable and never inherit
20
+ * values produced by this presentation buffer.
21
+ *
22
+ * The transition clock is the local receipt clock. The upstream
23
+ * sourceObservedAtSeconds value is retained as provenance, but it is not used
24
+ * for interpolation because its clock domain is not part of the observation
25
+ * contract yet.
26
+ */
27
+ export class ObservedRobotPresentationBuffer {
28
+ config;
29
+ mode = 'interpolated';
30
+ latestSample = null;
31
+ transitionStartValues = {};
32
+ transitionSourceSampleIds = [];
33
+ transitionStartedAtMs = 0;
34
+ transitionDurationMs = 0;
35
+ pendingFallbackReason = 'insufficient_samples';
36
+ status = EMPTY_STATUS;
37
+ constructor(config = {}) {
38
+ const minimumTransitionMs = finitePositive(config.minimumTransitionMs, DEFAULT_CONFIG.minimumTransitionMs);
39
+ const maximumTransitionMs = Math.max(minimumTransitionMs, finitePositive(config.maximumTransitionMs, DEFAULT_CONFIG.maximumTransitionMs));
40
+ this.config = {
41
+ minimumTransitionMs,
42
+ maximumTransitionMs,
43
+ maximumSampleGapMs: Math.max(maximumTransitionMs, finitePositive(config.maximumSampleGapMs, DEFAULT_CONFIG.maximumSampleGapMs))
44
+ };
45
+ }
46
+ setMode(mode) {
47
+ if (this.mode === mode)
48
+ return;
49
+ this.mode = mode;
50
+ this.reset('discontinuity');
51
+ }
52
+ getMode() {
53
+ return this.mode;
54
+ }
55
+ getStatus() {
56
+ return { ...this.status, sourceSampleIds: [...this.status.sourceSampleIds] };
57
+ }
58
+ getConfig() {
59
+ return { ...this.config };
60
+ }
61
+ reset(reason = 'discontinuity') {
62
+ this.latestSample = null;
63
+ this.transitionStartValues = {};
64
+ this.transitionSourceSampleIds = [];
65
+ this.transitionStartedAtMs = 0;
66
+ this.transitionDurationMs = 0;
67
+ this.pendingFallbackReason = reason;
68
+ this.status = {
69
+ ...EMPTY_STATUS,
70
+ mode: this.mode,
71
+ fallbackReason: reason
72
+ };
73
+ }
74
+ ingest(sample) {
75
+ const normalized = normalizeSample(sample);
76
+ if (!normalized) {
77
+ this.reset('invalid_sample');
78
+ return false;
79
+ }
80
+ const previous = this.latestSample;
81
+ if (previous?.sampleId === normalized.sampleId &&
82
+ previous.connectionId === normalized.connectionId) {
83
+ return false;
84
+ }
85
+ if (previous && previous.connectionId !== normalized.connectionId) {
86
+ this.reset('discontinuity');
87
+ this.acceptFirstSample(normalized, 'discontinuity');
88
+ return true;
89
+ }
90
+ if (!previous) {
91
+ this.acceptFirstSample(normalized, this.pendingFallbackReason);
92
+ return true;
93
+ }
94
+ const sampleGapMs = normalized.receivedAtMs - previous.receivedAtMs;
95
+ if (sampleGapMs < 0) {
96
+ this.reset('invalid_sample');
97
+ this.acceptFirstSample(normalized, 'invalid_sample');
98
+ return true;
99
+ }
100
+ if (sampleGapMs > this.config.maximumSampleGapMs) {
101
+ this.acceptFirstSample(normalized, 'sample_gap');
102
+ return true;
103
+ }
104
+ const currentFrame = this.project(normalized.receivedAtMs);
105
+ this.transitionStartValues = Object.fromEntries(Object.entries(normalized.jointValues).map(([jointName, nextValue]) => [
106
+ jointName,
107
+ currentFrame?.jointValues[jointName] ?? previous.jointValues[jointName] ?? nextValue
108
+ ]));
109
+ this.transitionSourceSampleIds = uniqueTail([...(currentFrame?.sourceSampleIds ?? [previous.sampleId]), normalized.sampleId], 3);
110
+ this.latestSample = normalized;
111
+ this.transitionStartedAtMs = normalized.receivedAtMs;
112
+ this.transitionDurationMs = clamp(sampleGapMs, this.config.minimumTransitionMs, this.config.maximumTransitionMs);
113
+ this.pendingFallbackReason = 'none';
114
+ return true;
115
+ }
116
+ project(renderedAtMs) {
117
+ const latest = this.latestSample;
118
+ if (!latest || !Number.isFinite(renderedAtMs)) {
119
+ this.status = {
120
+ ...EMPTY_STATUS,
121
+ mode: this.mode,
122
+ fallbackReason: latest ? 'invalid_sample' : this.pendingFallbackReason
123
+ };
124
+ return null;
125
+ }
126
+ if (this.mode === 'raw' || this.transitionDurationMs <= 0) {
127
+ const fallbackReason = this.mode === 'raw' ? 'none' : this.pendingFallbackReason;
128
+ const frame = {
129
+ mode: this.mode,
130
+ state: fallbackReason === 'none' ? 'raw' : 'fallback',
131
+ fallbackReason,
132
+ provenance: 'observed-raw',
133
+ sourceSampleIds: [latest.sampleId],
134
+ connectionId: latest.connectionId,
135
+ sourceObservedAtSeconds: latest.sourceObservedAtSeconds,
136
+ renderedAtMs,
137
+ latestReceivedAtMs: latest.receivedAtMs,
138
+ interpolationAlpha: 1,
139
+ transitionDurationMs: 0,
140
+ active: false,
141
+ jointValues: { ...latest.jointValues }
142
+ };
143
+ this.status = createStatus(frame);
144
+ return frame;
145
+ }
146
+ const interpolationAlpha = clamp((renderedAtMs - this.transitionStartedAtMs) / this.transitionDurationMs, 0, 1);
147
+ const active = interpolationAlpha < 1;
148
+ const frame = {
149
+ mode: this.mode,
150
+ state: 'interpolated',
151
+ fallbackReason: 'none',
152
+ provenance: 'observed-interpolated',
153
+ sourceSampleIds: active ? [...this.transitionSourceSampleIds] : [latest.sampleId],
154
+ connectionId: latest.connectionId,
155
+ sourceObservedAtSeconds: latest.sourceObservedAtSeconds,
156
+ renderedAtMs,
157
+ latestReceivedAtMs: latest.receivedAtMs,
158
+ interpolationAlpha,
159
+ transitionDurationMs: this.transitionDurationMs,
160
+ active,
161
+ jointValues: Object.fromEntries(Object.entries(latest.jointValues).map(([jointName, nextValue]) => [
162
+ jointName,
163
+ interpolateJointAngle(this.transitionStartValues[jointName] ?? nextValue, nextValue, interpolationAlpha)
164
+ ]))
165
+ };
166
+ this.status = createStatus(frame);
167
+ return frame;
168
+ }
169
+ isActive(renderedAtMs) {
170
+ return Boolean(this.mode === 'interpolated' &&
171
+ this.latestSample &&
172
+ this.transitionDurationMs > 0 &&
173
+ Number.isFinite(renderedAtMs) &&
174
+ renderedAtMs < this.transitionStartedAtMs + this.transitionDurationMs);
175
+ }
176
+ acceptFirstSample(sample, fallbackReason) {
177
+ this.latestSample = sample;
178
+ this.transitionStartValues = { ...sample.jointValues };
179
+ this.transitionSourceSampleIds = [sample.sampleId];
180
+ this.transitionStartedAtMs = sample.receivedAtMs;
181
+ this.transitionDurationMs = 0;
182
+ this.pendingFallbackReason =
183
+ fallbackReason === 'none' ? 'insufficient_samples' : fallbackReason;
184
+ }
185
+ }
186
+ function normalizeSample(sample) {
187
+ if (!sample.sampleId ||
188
+ !sample.connectionId ||
189
+ !Number.isFinite(sample.receivedAtMs) ||
190
+ (sample.sourceObservedAtSeconds !== null && !Number.isFinite(sample.sourceObservedAtSeconds))) {
191
+ return null;
192
+ }
193
+ const jointValues = Object.fromEntries(Object.entries(sample.jointValues).filter((entry) => {
194
+ const [jointName, value] = entry;
195
+ return Boolean(jointName) && typeof value === 'number' && Number.isFinite(value);
196
+ }));
197
+ if (Object.keys(jointValues).length === 0)
198
+ return null;
199
+ return {
200
+ ...sample,
201
+ jointValues
202
+ };
203
+ }
204
+ function createStatus(frame) {
205
+ return {
206
+ mode: frame.mode,
207
+ state: frame.state,
208
+ fallbackReason: frame.fallbackReason,
209
+ provenance: frame.provenance,
210
+ sourceSampleIds: [...frame.sourceSampleIds],
211
+ interpolationAlpha: frame.interpolationAlpha,
212
+ transitionDurationMs: frame.transitionDurationMs,
213
+ active: frame.active
214
+ };
215
+ }
216
+ function uniqueTail(values, maximum) {
217
+ const unique = [...new Set(values)];
218
+ return unique.slice(Math.max(0, unique.length - maximum));
219
+ }
220
+ function finitePositive(value, fallback) {
221
+ return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : fallback;
222
+ }
223
+ function clamp(value, minimum, maximum) {
224
+ return Math.min(maximum, Math.max(minimum, value));
225
+ }
226
+ //# sourceMappingURL=ObservedRobotPresentationBuffer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ObservedRobotPresentationBuffer.js","sourceRoot":"","sources":["../../src/renderer/ObservedRobotPresentationBuffer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ export interface Viewer3DProfilerSample {
2
+ time: number;
3
+ rafFrameRate: number;
4
+ globalRafFrameRate: number;
5
+ renderFrameRate: number;
6
+ drawMs: number;
7
+ loopMs: number;
8
+ schedulerWaitMs: number;
9
+ longTaskMs: number;
10
+ }
11
+ export interface Viewer3DPerformanceSummary {
12
+ sampleCount: number;
13
+ averageRafFrameRate: number;
14
+ onePercentLowRafFrameRate: number;
15
+ frameTimeMs: Viewer3DPerformancePercentiles;
16
+ drawMs: Viewer3DPerformancePercentiles;
17
+ loopMs: Viewer3DPerformancePercentiles;
18
+ schedulerWaitMs: Viewer3DPerformancePercentiles;
19
+ longTaskCount: number;
20
+ longTaskTotalMs: number;
21
+ }
22
+ export interface Viewer3DPerformancePercentiles {
23
+ p50: number;
24
+ p95: number;
25
+ p99: number;
26
+ }
27
+ export declare class PerformanceMonitor {
28
+ readonly samples: Viewer3DProfilerSample[];
29
+ readonly signalCounts: Map<string, number>;
30
+ markSignal(label: string): void;
31
+ clearSignals(): void;
32
+ recordSample(sample: Viewer3DProfilerSample): void;
33
+ updateAverage(currentAverage: number, sampleMs: number): number;
34
+ formatSignals(elapsedSeconds?: number): string;
35
+ getSummary(): Viewer3DPerformanceSummary;
36
+ }
37
+ export declare function summarizeViewer3DPerformance(samples: readonly Viewer3DProfilerSample[]): Viewer3DPerformanceSummary;
38
+ //# sourceMappingURL=PerformanceMonitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PerformanceMonitor.d.ts","sourceRoot":"","sources":["../../src/renderer/PerformanceMonitor.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,yBAAyB,EAAE,MAAM,CAAC;IAClC,WAAW,EAAE,8BAA8B,CAAC;IAC5C,MAAM,EAAE,8BAA8B,CAAC;IACvC,MAAM,EAAE,8BAA8B,CAAC;IACvC,eAAe,EAAE,8BAA8B,CAAC;IAChD,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,8BAA8B;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,qBAAa,kBAAkB;IAC7B,QAAQ,CAAC,OAAO,EAAE,sBAAsB,EAAE,CAAM;IAChD,QAAQ,CAAC,YAAY,sBAA6B;IAElD,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAU/B,YAAY,IAAI,IAAI;IAIpB,YAAY,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI;IAUlD,aAAa,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAY/D,aAAa,CAAC,cAAc,SAAI,GAAG,MAAM;IAezC,UAAU,IAAI,0BAA0B;CAGzC;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,SAAS,sBAAsB,EAAE,GACzC,0BAA0B,CAkB5B"}
@@ -0,0 +1,84 @@
1
+ const ROBOT_VIEWER_PROFILER_SMOOTHING = 0.12;
2
+ const ROBOT_VIEWER_PROFILER_HISTORY_MS = 60_000;
3
+ export class PerformanceMonitor {
4
+ samples = [];
5
+ signalCounts = new Map();
6
+ markSignal(label) {
7
+ const normalizedLabel = label.trim();
8
+ if (!normalizedLabel) {
9
+ return;
10
+ }
11
+ this.signalCounts.set(normalizedLabel, (this.signalCounts.get(normalizedLabel) ?? 0) + 1);
12
+ }
13
+ clearSignals() {
14
+ this.signalCounts.clear();
15
+ }
16
+ recordSample(sample) {
17
+ this.samples.push(sample);
18
+ const cutoff = sample.time - ROBOT_VIEWER_PROFILER_HISTORY_MS;
19
+ while (this.samples.length > 0 && (this.samples[0]?.time ?? 0) < cutoff) {
20
+ this.samples.shift();
21
+ }
22
+ }
23
+ updateAverage(currentAverage, sampleMs) {
24
+ if (!Number.isFinite(sampleMs) || sampleMs < 0) {
25
+ return currentAverage;
26
+ }
27
+ if (currentAverage <= 0) {
28
+ return sampleMs;
29
+ }
30
+ return currentAverage * (1 - ROBOT_VIEWER_PROFILER_SMOOTHING) + sampleMs * ROBOT_VIEWER_PROFILER_SMOOTHING;
31
+ }
32
+ formatSignals(elapsedSeconds = 1) {
33
+ if (this.signalCounts.size === 0) {
34
+ return '-';
35
+ }
36
+ const validElapsedSeconds = Number.isFinite(elapsedSeconds) && elapsedSeconds > 0 ? elapsedSeconds : 1;
37
+ return [...this.signalCounts.entries()]
38
+ .sort((left, right) => right[1] - left[1])
39
+ .slice(0, 3)
40
+ .map(([label, count]) => `${label}:${Math.round(count / validElapsedSeconds)}`)
41
+ .join(' ');
42
+ }
43
+ getSummary() {
44
+ return summarizeViewer3DPerformance(this.samples);
45
+ }
46
+ }
47
+ export function summarizeViewer3DPerformance(samples) {
48
+ const rafFrameRates = finiteNonNegativeValues(samples.map((sample) => sample.rafFrameRate));
49
+ const frameTimes = rafFrameRates.filter((value) => value > 0).map((value) => 1000 / value);
50
+ const longTaskDurations = finiteNonNegativeValues(samples.map((sample) => sample.longTaskMs)).filter((value) => value > 0);
51
+ return {
52
+ sampleCount: samples.length,
53
+ averageRafFrameRate: average(rafFrameRates),
54
+ onePercentLowRafFrameRate: percentile(rafFrameRates, 0.01),
55
+ frameTimeMs: percentiles(frameTimes),
56
+ drawMs: percentiles(samples.map((sample) => sample.drawMs)),
57
+ loopMs: percentiles(samples.map((sample) => sample.loopMs)),
58
+ schedulerWaitMs: percentiles(samples.map((sample) => sample.schedulerWaitMs)),
59
+ longTaskCount: longTaskDurations.length,
60
+ longTaskTotalMs: longTaskDurations.reduce((total, value) => total + value, 0)
61
+ };
62
+ }
63
+ function percentiles(values) {
64
+ return {
65
+ p50: percentile(values, 0.5),
66
+ p95: percentile(values, 0.95),
67
+ p99: percentile(values, 0.99)
68
+ };
69
+ }
70
+ function percentile(values, quantile) {
71
+ const sorted = finiteNonNegativeValues(values).sort((left, right) => left - right);
72
+ if (sorted.length === 0) {
73
+ return 0;
74
+ }
75
+ const index = Math.ceil(Math.min(1, Math.max(0, quantile)) * sorted.length) - 1;
76
+ return sorted[Math.max(0, index)] ?? 0;
77
+ }
78
+ function average(values) {
79
+ return values.length === 0 ? 0 : values.reduce((total, value) => total + value, 0) / values.length;
80
+ }
81
+ function finiteNonNegativeValues(values) {
82
+ return values.filter((value) => Number.isFinite(value) && value >= 0);
83
+ }
84
+ //# sourceMappingURL=PerformanceMonitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PerformanceMonitor.js","sourceRoot":"","sources":["../../src/renderer/PerformanceMonitor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ export interface ViewerProjectileVector3 {
2
+ x: number;
3
+ y: number;
4
+ z: number;
5
+ }
6
+ export interface ViewerProjectileLaunchSolution {
7
+ origin: ViewerProjectileVector3;
8
+ target: ViewerProjectileVector3;
9
+ velocity: ViewerProjectileVector3;
10
+ gravity: ViewerProjectileVector3;
11
+ durationSeconds: number;
12
+ }
13
+ export interface ViewerProjectileLaunchInput {
14
+ origin: ViewerProjectileVector3;
15
+ target: ViewerProjectileVector3;
16
+ speedMetersPerSecond: number;
17
+ gravityMetersPerSecondSquared?: number;
18
+ minimumDurationSeconds?: number;
19
+ maximumDurationSeconds?: number;
20
+ }
21
+ export interface ViewerProjectileLaunchProfile {
22
+ speedMetersPerSecond: number;
23
+ minimumDurationSeconds: number;
24
+ maximumDurationSeconds: number;
25
+ }
26
+ export interface ViewerProjectileKinematicState {
27
+ position: ViewerProjectileVector3;
28
+ velocity: ViewerProjectileVector3;
29
+ }
30
+ export interface ViewerProjectileGroundStepOptions {
31
+ gravity: ViewerProjectileVector3;
32
+ floorY: number;
33
+ radius: number;
34
+ restitution: number;
35
+ frictionPerSecond: number;
36
+ settleSpeedMetersPerSecond: number;
37
+ }
38
+ export interface ViewerProjectileGroundStepResult extends ViewerProjectileKinematicState {
39
+ contactedGround: boolean;
40
+ settled: boolean;
41
+ }
42
+ export declare function resolveViewerProjectileLauncherWorldScale(worldUnitsPerScreenPixel: number, targetScreenPixels?: number, authoredSizeMeters?: number): number;
43
+ /**
44
+ * Keeps the projectile readable at close range without letting the ballistic
45
+ * compensation turn into an oversized bell when the camera pulls back.
46
+ */
47
+ export declare function resolveViewerProjectileLaunchProfile(distanceMeters: number): ViewerProjectileLaunchProfile;
48
+ export declare function resolveViewerProjectileChargedLaunchProfile(distanceMeters: number, chargeRatio: number): ViewerProjectileLaunchProfile;
49
+ export declare function createViewerProjectileLaunchSolution(input: ViewerProjectileLaunchInput): ViewerProjectileLaunchSolution;
50
+ export declare function sampleViewerProjectilePosition(launch: ViewerProjectileLaunchSolution, elapsedSeconds: number): ViewerProjectileVector3;
51
+ export declare function sampleViewerProjectileVelocity(launch: ViewerProjectileLaunchSolution, elapsedSeconds: number): ViewerProjectileVector3;
52
+ export declare function createViewerProjectileTrajectoryPoints(launch: ViewerProjectileLaunchSolution, segmentCount?: number): ViewerProjectileVector3[];
53
+ export declare function resolveViewerProjectileImpulse(massKilograms: number, velocity: ViewerProjectileVector3): ViewerProjectileVector3;
54
+ /** Damped elastic recoil used by the slingshot pouch after launch. */
55
+ export declare function resolveViewerSlingshotReleasePull(initialPullRatio: number, progress: number): number;
56
+ export declare function stepViewerProjectileAgainstGround(state: ViewerProjectileKinematicState, elapsedSeconds: number, options: ViewerProjectileGroundStepOptions): ViewerProjectileGroundStepResult;
57
+ //# sourceMappingURL=ProjectileInteraction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProjectileInteraction.d.ts","sourceRoot":"","sources":["../../src/renderer/ProjectileInteraction.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,uBAAuB;IACtC,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX;AAED,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,uBAAuB,CAAC;IAChC,MAAM,EAAE,uBAAuB,CAAC;IAChC,QAAQ,EAAE,uBAAuB,CAAC;IAClC,OAAO,EAAE,uBAAuB,CAAC;IACjC,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,2BAA2B;IAC1C,MAAM,EAAE,uBAAuB,CAAC;IAChC,MAAM,EAAE,uBAAuB,CAAC;IAChC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,6BAA6B,CAAC,EAAE,MAAM,CAAC;IACvC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC;AAED,MAAM,WAAW,6BAA6B;IAC5C,oBAAoB,EAAE,MAAM,CAAC;IAC7B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,sBAAsB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,EAAE,uBAAuB,CAAC;IAClC,QAAQ,EAAE,uBAAuB,CAAC;CACnC;AAED,MAAM,WAAW,iCAAiC;IAChD,OAAO,EAAE,uBAAuB,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,0BAA0B,EAAE,MAAM,CAAC;CACpC;AAED,MAAM,WAAW,gCAAiC,SAAQ,8BAA8B;IACtF,eAAe,EAAE,OAAO,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;CAClB;AAOD,wBAAgB,yCAAyC,CACvD,wBAAwB,EAAE,MAAM,EAChC,kBAAkB,SAAK,EACvB,kBAAkB,SAAO,GACxB,MAAM,CAKR;AAED;;;GAGG;AACH,wBAAgB,oCAAoC,CAAC,cAAc,EAAE,MAAM,GAAG,6BAA6B,CAU1G;AAED,wBAAgB,2CAA2C,CACzD,cAAc,EAAE,MAAM,EACtB,WAAW,EAAE,MAAM,GAClB,6BAA6B,CAc/B;AAED,wBAAgB,oCAAoC,CAClD,KAAK,EAAE,2BAA2B,GACjC,8BAA8B,CA2BhC;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,8BAA8B,EACtC,cAAc,EAAE,MAAM,GACrB,uBAAuB,CAQzB;AAED,wBAAgB,8BAA8B,CAC5C,MAAM,EAAE,8BAA8B,EACtC,cAAc,EAAE,MAAM,GACrB,uBAAuB,CAQzB;AAED,wBAAgB,sCAAsC,CACpD,MAAM,EAAE,8BAA8B,EACtC,YAAY,SAAK,GAChB,uBAAuB,EAAE,CAK3B;AAED,wBAAgB,8BAA8B,CAC5C,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,uBAAuB,GAChC,uBAAuB,CAQzB;AAED,sEAAsE;AACtE,wBAAgB,iCAAiC,CAAC,gBAAgB,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAMpG;AAED,wBAAgB,iCAAiC,CAC/C,KAAK,EAAE,8BAA8B,EACrC,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,iCAAiC,GACzC,gCAAgC,CAoClC"}
@@ -0,0 +1,152 @@
1
+ const finite = (value, fallback) => (Number.isFinite(value) ? value : fallback);
2
+ const VIEWER_PROJECTILE_MINIMUM_POWER_SCALE = 0.68;
3
+ const VIEWER_PROJECTILE_MAXIMUM_POWER_SCALE = 2.3;
4
+ const VIEWER_PROJECTILE_POWER_RANGE_OFFSET_RATIO = 0.2;
5
+ export function resolveViewerProjectileLauncherWorldScale(worldUnitsPerScreenPixel, targetScreenPixels = 72, authoredSizeMeters = 0.13) {
6
+ const worldUnitsPerPixel = Math.max(0, finite(worldUnitsPerScreenPixel, 0));
7
+ const targetPixels = Math.max(1, finite(targetScreenPixels, 72));
8
+ const authoredSize = Math.max(0.001, finite(authoredSizeMeters, 0.13));
9
+ return (worldUnitsPerPixel * targetPixels) / authoredSize;
10
+ }
11
+ /**
12
+ * Keeps the projectile readable at close range without letting the ballistic
13
+ * compensation turn into an oversized bell when the camera pulls back.
14
+ */
15
+ export function resolveViewerProjectileLaunchProfile(distanceMeters) {
16
+ const distance = Math.max(0, finite(distanceMeters, 0));
17
+ const normalized = Math.min(1, Math.max(0, (distance - 1.2) / (6 - 1.2)));
18
+ const blend = normalized * normalized * (3 - 2 * normalized);
19
+ return {
20
+ speedMetersPerSecond: 3.4 + (12 - 3.4) * blend,
21
+ minimumDurationSeconds: 0.18 + (0.14 - 0.18) * blend,
22
+ maximumDurationSeconds: 0.62 + (0.42 - 0.62) * blend
23
+ };
24
+ }
25
+ export function resolveViewerProjectileChargedLaunchProfile(distanceMeters, chargeRatio) {
26
+ const profile = resolveViewerProjectileLaunchProfile(distanceMeters);
27
+ const normalizedCharge = Math.min(1, Math.max(0, finite(chargeRatio, 0)));
28
+ const easedCharge = normalizedCharge * normalizedCharge * (3 - 2 * normalizedCharge);
29
+ const powerRange = VIEWER_PROJECTILE_MAXIMUM_POWER_SCALE - VIEWER_PROJECTILE_MINIMUM_POWER_SCALE;
30
+ const powerScale = VIEWER_PROJECTILE_MINIMUM_POWER_SCALE +
31
+ powerRange * (VIEWER_PROJECTILE_POWER_RANGE_OFFSET_RATIO + easedCharge);
32
+ return {
33
+ speedMetersPerSecond: profile.speedMetersPerSecond * powerScale,
34
+ minimumDurationSeconds: profile.minimumDurationSeconds * (1.05 + (0.7 - 1.05) * easedCharge),
35
+ maximumDurationSeconds: profile.maximumDurationSeconds * (1.15 + (0.7 - 1.15) * easedCharge)
36
+ };
37
+ }
38
+ export function createViewerProjectileLaunchSolution(input) {
39
+ const origin = normalizeVector(input.origin);
40
+ const target = normalizeVector(input.target);
41
+ const delta = subtract(target, origin);
42
+ const distance = Math.hypot(delta.x, delta.y, delta.z);
43
+ const speed = Math.max(0.1, finite(input.speedMetersPerSecond, 2.6));
44
+ const minimumDuration = Math.max(0.08, finite(input.minimumDurationSeconds ?? 0.28, 0.28));
45
+ const maximumDuration = Math.max(minimumDuration, finite(input.maximumDurationSeconds ?? 1.1, 1.1));
46
+ const durationSeconds = Math.min(maximumDuration, Math.max(minimumDuration, distance / speed));
47
+ const gravity = {
48
+ x: 0,
49
+ y: -Math.abs(finite(input.gravityMetersPerSecondSquared ?? 9.81, 9.81)),
50
+ z: 0
51
+ };
52
+ const inverseDuration = 1 / durationSeconds;
53
+ return {
54
+ origin,
55
+ target,
56
+ gravity,
57
+ durationSeconds,
58
+ velocity: {
59
+ x: (delta.x - 0.5 * gravity.x * durationSeconds * durationSeconds) * inverseDuration,
60
+ y: (delta.y - 0.5 * gravity.y * durationSeconds * durationSeconds) * inverseDuration,
61
+ z: (delta.z - 0.5 * gravity.z * durationSeconds * durationSeconds) * inverseDuration
62
+ }
63
+ };
64
+ }
65
+ export function sampleViewerProjectilePosition(launch, elapsedSeconds) {
66
+ const time = Math.min(launch.durationSeconds, Math.max(0, finite(elapsedSeconds, 0)));
67
+ return {
68
+ x: launch.origin.x + launch.velocity.x * time + 0.5 * launch.gravity.x * time * time,
69
+ y: launch.origin.y + launch.velocity.y * time + 0.5 * launch.gravity.y * time * time,
70
+ z: launch.origin.z + launch.velocity.z * time + 0.5 * launch.gravity.z * time * time
71
+ };
72
+ }
73
+ export function sampleViewerProjectileVelocity(launch, elapsedSeconds) {
74
+ const time = Math.min(launch.durationSeconds, Math.max(0, finite(elapsedSeconds, 0)));
75
+ return {
76
+ x: launch.velocity.x + launch.gravity.x * time,
77
+ y: launch.velocity.y + launch.gravity.y * time,
78
+ z: launch.velocity.z + launch.gravity.z * time
79
+ };
80
+ }
81
+ export function createViewerProjectileTrajectoryPoints(launch, segmentCount = 32) {
82
+ const segments = Math.max(2, Math.min(128, Math.round(finite(segmentCount, 32))));
83
+ return Array.from({ length: segments + 1 }, (_, index) => sampleViewerProjectilePosition(launch, (launch.durationSeconds * index) / segments));
84
+ }
85
+ export function resolveViewerProjectileImpulse(massKilograms, velocity) {
86
+ const mass = Math.max(0, finite(massKilograms, 0));
87
+ const normalizedVelocity = normalizeVector(velocity);
88
+ return {
89
+ x: normalizedVelocity.x * mass,
90
+ y: normalizedVelocity.y * mass,
91
+ z: normalizedVelocity.z * mass
92
+ };
93
+ }
94
+ /** Damped elastic recoil used by the slingshot pouch after launch. */
95
+ export function resolveViewerSlingshotReleasePull(initialPullRatio, progress) {
96
+ const initialPull = Math.min(1, Math.max(0, finite(initialPullRatio, 0)));
97
+ const normalizedProgress = Math.min(1, Math.max(0, finite(progress, 0)));
98
+ if (normalizedProgress >= 1)
99
+ return 0;
100
+ return initialPull * Math.exp(-5.2 * normalizedProgress) * Math.cos(normalizedProgress * Math.PI * 3.5);
101
+ }
102
+ export function stepViewerProjectileAgainstGround(state, elapsedSeconds, options) {
103
+ const deltaSeconds = Math.max(0, Math.min(0.05, finite(elapsedSeconds, 0)));
104
+ const gravity = normalizeVector(options.gravity);
105
+ const floorY = finite(options.floorY, 0) + Math.max(0, finite(options.radius, 0));
106
+ const restitution = Math.min(1, Math.max(0, finite(options.restitution, 0.45)));
107
+ const friction = Math.max(0, finite(options.frictionPerSecond, 4));
108
+ const settleSpeed = Math.max(0, finite(options.settleSpeedMetersPerSecond, 0.08));
109
+ const position = normalizeVector(state.position);
110
+ const velocity = normalizeVector(state.velocity);
111
+ const nextPosition = {
112
+ x: position.x + velocity.x * deltaSeconds + 0.5 * gravity.x * deltaSeconds * deltaSeconds,
113
+ y: position.y + velocity.y * deltaSeconds + 0.5 * gravity.y * deltaSeconds * deltaSeconds,
114
+ z: position.z + velocity.z * deltaSeconds + 0.5 * gravity.z * deltaSeconds * deltaSeconds
115
+ };
116
+ const nextVelocity = {
117
+ x: velocity.x + gravity.x * deltaSeconds,
118
+ y: velocity.y + gravity.y * deltaSeconds,
119
+ z: velocity.z + gravity.z * deltaSeconds
120
+ };
121
+ if (nextPosition.y > floorY) {
122
+ return { position: nextPosition, velocity: nextVelocity, contactedGround: false, settled: false };
123
+ }
124
+ nextPosition.y = floorY;
125
+ const horizontalDrag = Math.exp(-friction * deltaSeconds);
126
+ nextVelocity.x *= horizontalDrag;
127
+ nextVelocity.z *= horizontalDrag;
128
+ nextVelocity.y = Math.abs(nextVelocity.y) * restitution;
129
+ const speed = Math.hypot(nextVelocity.x, nextVelocity.y, nextVelocity.z);
130
+ const settled = speed <= settleSpeed;
131
+ if (settled) {
132
+ nextVelocity.x = 0;
133
+ nextVelocity.y = 0;
134
+ nextVelocity.z = 0;
135
+ }
136
+ return { position: nextPosition, velocity: nextVelocity, contactedGround: true, settled };
137
+ }
138
+ function normalizeVector(value) {
139
+ return {
140
+ x: finite(value.x, 0),
141
+ y: finite(value.y, 0),
142
+ z: finite(value.z, 0)
143
+ };
144
+ }
145
+ function subtract(left, right) {
146
+ return {
147
+ x: left.x - right.x,
148
+ y: left.y - right.y,
149
+ z: left.z - right.z
150
+ };
151
+ }
152
+ //# sourceMappingURL=ProjectileInteraction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ProjectileInteraction.js","sourceRoot":"","sources":["../../src/renderer/ProjectileInteraction.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export declare const ROBOT_COMPARISON_VISIBILITY_LAYOUT_SHARE = 0.62;
2
+ export interface RobotComparisonVisibilityTransitionPhases {
3
+ layoutProgress: number;
4
+ opacityProgress: number;
5
+ }
6
+ /**
7
+ * On appearance the incarnations reach their final layout before REAL fades
8
+ * in. On disappearance the order is reversed, so no visible ghost slides
9
+ * through the simulated robot.
10
+ */
11
+ export declare function resolveRobotComparisonVisibilityTransitionPhases(progress: number, appearing: boolean, layoutShare?: number): RobotComparisonVisibilityTransitionPhases;
12
+ //# sourceMappingURL=RobotComparisonVisibilityTransition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RobotComparisonVisibilityTransition.d.ts","sourceRoot":"","sources":["../../src/renderer/RobotComparisonVisibilityTransition.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,wCAAwC,OAAO,CAAC;AAE7D,MAAM,WAAW,yCAAyC;IACxD,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB;AAKD;;;;GAIG;AACH,wBAAgB,gDAAgD,CAC9D,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,OAAO,EAClB,WAAW,SAA2C,GACrD,yCAAyC,CAgB3C"}
@@ -0,0 +1,23 @@
1
+ export const ROBOT_COMPARISON_VISIBILITY_LAYOUT_SHARE = 0.62;
2
+ const clampProgress = (progress) => Math.min(1, Math.max(0, Number.isFinite(progress) ? progress : 0));
3
+ /**
4
+ * On appearance the incarnations reach their final layout before REAL fades
5
+ * in. On disappearance the order is reversed, so no visible ghost slides
6
+ * through the simulated robot.
7
+ */
8
+ export function resolveRobotComparisonVisibilityTransitionPhases(progress, appearing, layoutShare = ROBOT_COMPARISON_VISIBILITY_LAYOUT_SHARE) {
9
+ const normalized = clampProgress(progress);
10
+ const safeLayoutShare = Math.min(0.9, Math.max(0.1, layoutShare));
11
+ const opacityShare = 1 - safeLayoutShare;
12
+ if (appearing) {
13
+ return {
14
+ layoutProgress: clampProgress(normalized / safeLayoutShare),
15
+ opacityProgress: clampProgress((normalized - safeLayoutShare) / opacityShare)
16
+ };
17
+ }
18
+ return {
19
+ opacityProgress: clampProgress(normalized / opacityShare),
20
+ layoutProgress: clampProgress((normalized - opacityShare) / safeLayoutShare)
21
+ };
22
+ }
23
+ //# sourceMappingURL=RobotComparisonVisibilityTransition.js.map