@promptbook/wizard 0.112.0-117 → 0.112.0-118
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/esm/index.es.js +196 -43
- package/esm/index.es.js.map +1 -1
- package/esm/src/_packages/node.index.d.ts +10 -0
- package/esm/src/book-3.0/BookNodeAgentSource.d.ts +1 -1
- package/esm/src/book-3.0/CliAgent.d.ts +7 -2
- package/esm/src/book-3.0/cliAgentEnv.d.ts +33 -0
- package/esm/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +2 -18
- package/esm/src/version.d.ts +1 -1
- package/package.json +2 -2
- package/umd/index.umd.js +196 -43
- package/umd/index.umd.js.map +1 -1
- package/umd/src/_packages/node.index.d.ts +10 -0
- package/umd/src/book-3.0/BookNodeAgentSource.d.ts +1 -1
- package/umd/src/book-3.0/CliAgent.d.ts +7 -2
- package/umd/src/book-3.0/cliAgentEnv.d.ts +33 -0
- package/umd/src/cli/cli-commands/common/promptRunnerCliOptions.d.ts +2 -18
- package/umd/src/version.d.ts +1 -1
package/esm/index.es.js
CHANGED
|
@@ -37,7 +37,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
37
37
|
* @generated
|
|
38
38
|
* @see https://github.com/webgptorg/promptbook
|
|
39
39
|
*/
|
|
40
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-
|
|
40
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.112.0-118';
|
|
41
41
|
/**
|
|
42
42
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
43
43
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -22093,21 +22093,22 @@ function getPointBounds(points) {
|
|
|
22093
22093
|
* @private helper of `fractalAvatarVisual`
|
|
22094
22094
|
*/
|
|
22095
22095
|
function drawDragonCurveLayer(context, points, options) {
|
|
22096
|
-
const {
|
|
22096
|
+
const { primaryColor, secondaryColor, tertiaryColor, shadowColor, strokeWidth, timeMs, layerIndex } = options;
|
|
22097
22097
|
const firstPoint = points[0];
|
|
22098
22098
|
const lastPoint = points[points.length - 1];
|
|
22099
22099
|
const ribbonGradient = context.createLinearGradient(firstPoint.x, firstPoint.y, lastPoint.x, lastPoint.y);
|
|
22100
22100
|
ribbonGradient.addColorStop(0, `${primaryColor}f2`);
|
|
22101
22101
|
ribbonGradient.addColorStop(0.5, `${secondaryColor}e6`);
|
|
22102
22102
|
ribbonGradient.addColorStop(1, `${tertiaryColor}f2`);
|
|
22103
|
+
// Approximate the blurred shadow stroke with a wider semi-transparent stroke instead of
|
|
22104
|
+
// context.filter blur, which triggers a costly software rasterization pass every frame.
|
|
22103
22105
|
context.save();
|
|
22104
22106
|
context.beginPath();
|
|
22105
22107
|
tracePolyline(context, points);
|
|
22106
|
-
context.strokeStyle = `${shadowColor}
|
|
22107
|
-
context.lineWidth = strokeWidth *
|
|
22108
|
+
context.strokeStyle = `${shadowColor}48`;
|
|
22109
|
+
context.lineWidth = strokeWidth * 4.5;
|
|
22108
22110
|
context.lineJoin = 'round';
|
|
22109
22111
|
context.lineCap = 'round';
|
|
22110
|
-
context.filter = `blur(${size * 0.022}px)`;
|
|
22111
22112
|
context.stroke();
|
|
22112
22113
|
context.restore();
|
|
22113
22114
|
context.beginPath();
|
|
@@ -22691,11 +22692,23 @@ function drawMinecraftBackdrop(context, size, palette, sceneCenterX, spotlightY,
|
|
|
22691
22692
|
* @private helper of `minecraft2AvatarVisual`
|
|
22692
22693
|
*/
|
|
22693
22694
|
function drawMinecraftShadow(context, size, palette, interaction, timeMs) {
|
|
22695
|
+
const cx = size * 0.5 + interaction.gazeX * size * 0.03;
|
|
22696
|
+
const cy = size * 0.85 + Math.sin(timeMs / 880) * size * 0.01;
|
|
22697
|
+
const rx = size * (0.16 + interaction.intensity * 0.015);
|
|
22698
|
+
const ry = size * 0.055;
|
|
22699
|
+
// Radial gradient approximates the blurry ellipse shadow without context.filter blur.
|
|
22694
22700
|
context.save();
|
|
22695
|
-
context.
|
|
22696
|
-
context.
|
|
22701
|
+
context.translate(cx, cy);
|
|
22702
|
+
context.scale(1, ry / rx);
|
|
22703
|
+
const blurRadius = rx * 1.4;
|
|
22704
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
22705
|
+
shadowGradient.addColorStop(0, `${palette.shadow}7a`);
|
|
22706
|
+
shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
|
|
22707
|
+
shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
|
|
22708
|
+
shadowGradient.addColorStop(1, `${palette.shadow}00`);
|
|
22709
|
+
context.fillStyle = shadowGradient;
|
|
22697
22710
|
context.beginPath();
|
|
22698
|
-
context.
|
|
22711
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
22699
22712
|
context.fill();
|
|
22700
22713
|
context.restore();
|
|
22701
22714
|
}
|
|
@@ -22919,13 +22932,27 @@ const minecraftAvatarVisual = {
|
|
|
22919
22932
|
spotlight.addColorStop(1, `${palette.highlight}00`);
|
|
22920
22933
|
context.fillStyle = spotlight;
|
|
22921
22934
|
context.fillRect(0, 0, size, size);
|
|
22922
|
-
|
|
22923
|
-
|
|
22924
|
-
|
|
22925
|
-
|
|
22926
|
-
|
|
22927
|
-
|
|
22928
|
-
|
|
22935
|
+
{
|
|
22936
|
+
// Radial gradient approximates the blurry ellipse shadow without context.filter blur.
|
|
22937
|
+
const cx = size * 0.5;
|
|
22938
|
+
const cy = size * 0.86;
|
|
22939
|
+
const rx = size * 0.2;
|
|
22940
|
+
const ry = size * 0.06;
|
|
22941
|
+
const blurRadius = rx * 1.4;
|
|
22942
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
22943
|
+
shadowGradient.addColorStop(0, 'rgba(0,0,0,0.28)');
|
|
22944
|
+
shadowGradient.addColorStop(0.45, 'rgba(0,0,0,0.14)');
|
|
22945
|
+
shadowGradient.addColorStop(0.8, 'rgba(0,0,0,0.05)');
|
|
22946
|
+
shadowGradient.addColorStop(1, 'rgba(0,0,0,0)');
|
|
22947
|
+
context.save();
|
|
22948
|
+
context.translate(cx, cy);
|
|
22949
|
+
context.scale(1, ry / rx);
|
|
22950
|
+
context.fillStyle = shadowGradient;
|
|
22951
|
+
context.beginPath();
|
|
22952
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
22953
|
+
context.fill();
|
|
22954
|
+
context.restore();
|
|
22955
|
+
}
|
|
22929
22956
|
drawVoxelCuboid(context, {
|
|
22930
22957
|
x: bodyX,
|
|
22931
22958
|
y: bodyY,
|
|
@@ -23977,6 +24004,35 @@ const LIGHT_DIRECTION$2 = normalizeVector3({
|
|
|
23977
24004
|
y: -0.62,
|
|
23978
24005
|
z: 0.94,
|
|
23979
24006
|
});
|
|
24007
|
+
/**
|
|
24008
|
+
* Cache keyed by the `createRandom` factory reference (stable per mounted `<Avatar/>`).
|
|
24009
|
+
*
|
|
24010
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
24011
|
+
*/
|
|
24012
|
+
const octopus3dStableStateCache = new WeakMap();
|
|
24013
|
+
/**
|
|
24014
|
+
* Returns the stable per-avatar state, computing it on first access and caching for subsequent frames.
|
|
24015
|
+
*
|
|
24016
|
+
* @private helper of `octopus3dAvatarVisual`
|
|
24017
|
+
*/
|
|
24018
|
+
function getOctopus3dStableState(createRandom) {
|
|
24019
|
+
const cached = octopus3dStableStateCache.get(createRandom);
|
|
24020
|
+
if (cached !== undefined) {
|
|
24021
|
+
return cached;
|
|
24022
|
+
}
|
|
24023
|
+
const animationRandom = createRandom('octopus3d-animation-profile');
|
|
24024
|
+
const eyeRandom = createRandom('octopus3d-eye-profile');
|
|
24025
|
+
const leftEyePhaseOffset = eyeRandom() * 0.6;
|
|
24026
|
+
const rightEyePhaseOffset = eyeRandom() * 0.6;
|
|
24027
|
+
const state = {
|
|
24028
|
+
morphologyProfile: createOctopus3MorphologyProfile(createRandom),
|
|
24029
|
+
animationPhase: animationRandom() * Math.PI * 2,
|
|
24030
|
+
leftEyePhaseOffset,
|
|
24031
|
+
rightEyePhaseOffset,
|
|
24032
|
+
};
|
|
24033
|
+
octopus3dStableStateCache.set(createRandom, state);
|
|
24034
|
+
return state;
|
|
24035
|
+
}
|
|
23980
24036
|
/**
|
|
23981
24037
|
* Proper 3D Octopus visual built from projected organic meshes and tentacles.
|
|
23982
24038
|
*
|
|
@@ -23989,10 +24045,7 @@ const octopus3dAvatarVisual = {
|
|
|
23989
24045
|
isAnimated: true,
|
|
23990
24046
|
supportsPointerTracking: true,
|
|
23991
24047
|
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
23992
|
-
const morphologyProfile =
|
|
23993
|
-
const animationRandom = createRandom('octopus3d-animation-profile');
|
|
23994
|
-
const eyeRandom = createRandom('octopus3d-eye-profile');
|
|
23995
|
-
const animationPhase = animationRandom() * Math.PI * 2;
|
|
24048
|
+
const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset } = getOctopus3dStableState(createRandom);
|
|
23996
24049
|
const sceneCenterX = size * 0.5;
|
|
23997
24050
|
const sceneCenterY = size * 0.56;
|
|
23998
24051
|
const bob = Math.sin(timeMs / 920 + animationPhase) * size * 0.014;
|
|
@@ -24089,12 +24142,12 @@ const octopus3dAvatarVisual = {
|
|
|
24089
24142
|
x: -faceEyeSpacing,
|
|
24090
24143
|
y: faceEyeYOffset,
|
|
24091
24144
|
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, -faceEyeSpacing, faceEyeYOffset),
|
|
24092
|
-
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase +
|
|
24145
|
+
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
24093
24146
|
drawProjectedOrganicEye(context, {
|
|
24094
24147
|
x: faceEyeSpacing,
|
|
24095
24148
|
y: faceEyeYOffset,
|
|
24096
24149
|
z: resolveEllipsoidSurfaceDepth(mantleRadiusX, mantleRadiusY, mantleRadiusZ, faceEyeSpacing, faceEyeYOffset),
|
|
24097
|
-
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 +
|
|
24150
|
+
}, faceEyeRadiusX, faceEyeRadiusY, mantleCenter, headPitch, headYaw, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.7 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
24098
24151
|
drawProjectedOrganicMouth(context, [
|
|
24099
24152
|
{
|
|
24100
24153
|
x: -mouthHalfWidth,
|
|
@@ -24138,14 +24191,28 @@ function drawOctopus3dAtmosphere(context, size, palette, sceneCenterX, sceneCent
|
|
|
24138
24191
|
/**
|
|
24139
24192
|
* Draws the soft ground shadow below the octopus.
|
|
24140
24193
|
*
|
|
24194
|
+
* Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
|
|
24195
|
+
* blurry ellipse without triggering a costly software rasterization pass on every frame.
|
|
24196
|
+
*
|
|
24141
24197
|
* @private helper of `octopus3dAvatarVisual`
|
|
24142
24198
|
*/
|
|
24143
24199
|
function drawOctopus3dShadow(context, size, palette, interaction, timeMs) {
|
|
24200
|
+
const cx = size * 0.5 + interaction.gazeX * size * 0.04;
|
|
24201
|
+
const cy = size * 0.87 + Math.sin(timeMs / 920) * size * 0.008;
|
|
24202
|
+
const rx = size * (0.18 + interaction.intensity * 0.02);
|
|
24203
|
+
const ry = size * 0.06;
|
|
24144
24204
|
context.save();
|
|
24145
|
-
context.
|
|
24146
|
-
context.
|
|
24205
|
+
context.translate(cx, cy);
|
|
24206
|
+
context.scale(1, ry / rx);
|
|
24207
|
+
const blurRadius = rx * 1.4;
|
|
24208
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
24209
|
+
shadowGradient.addColorStop(0, `${palette.shadow}7a`);
|
|
24210
|
+
shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
|
|
24211
|
+
shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
|
|
24212
|
+
shadowGradient.addColorStop(1, `${palette.shadow}00`);
|
|
24213
|
+
context.fillStyle = shadowGradient;
|
|
24147
24214
|
context.beginPath();
|
|
24148
|
-
context.
|
|
24215
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
24149
24216
|
context.fill();
|
|
24150
24217
|
context.restore();
|
|
24151
24218
|
}
|
|
@@ -24376,6 +24443,35 @@ const LIGHT_DIRECTION$1 = normalizeVector3({
|
|
|
24376
24443
|
y: -0.6,
|
|
24377
24444
|
z: 0.98,
|
|
24378
24445
|
});
|
|
24446
|
+
/**
|
|
24447
|
+
* Cache keyed by the `createRandom` factory reference (stable per mounted `<Avatar/>`).
|
|
24448
|
+
*
|
|
24449
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
24450
|
+
*/
|
|
24451
|
+
const octopus3d2StableStateCache = new WeakMap();
|
|
24452
|
+
/**
|
|
24453
|
+
* Returns the stable per-avatar state, computing it on first access and caching for subsequent frames.
|
|
24454
|
+
*
|
|
24455
|
+
* @private helper of `octopus3d2AvatarVisual`
|
|
24456
|
+
*/
|
|
24457
|
+
function getOctopus3d2StableState(createRandom) {
|
|
24458
|
+
const cached = octopus3d2StableStateCache.get(createRandom);
|
|
24459
|
+
if (cached !== undefined) {
|
|
24460
|
+
return cached;
|
|
24461
|
+
}
|
|
24462
|
+
const animationRandom = createRandom('octopus3d2-animation-profile');
|
|
24463
|
+
const eyeRandom = createRandom('octopus3d2-eye-profile');
|
|
24464
|
+
const leftEyePhaseOffset = eyeRandom() * 0.7;
|
|
24465
|
+
const rightEyePhaseOffset = eyeRandom() * 0.7;
|
|
24466
|
+
const state = {
|
|
24467
|
+
morphologyProfile: createOctopus3MorphologyProfile(createRandom),
|
|
24468
|
+
animationPhase: animationRandom() * Math.PI * 2,
|
|
24469
|
+
leftEyePhaseOffset,
|
|
24470
|
+
rightEyePhaseOffset,
|
|
24471
|
+
};
|
|
24472
|
+
octopus3d2StableStateCache.set(createRandom, state);
|
|
24473
|
+
return state;
|
|
24474
|
+
}
|
|
24379
24475
|
/**
|
|
24380
24476
|
* Octopus 3D 2 avatar visual.
|
|
24381
24477
|
*
|
|
@@ -24388,10 +24484,7 @@ const octopus3d2AvatarVisual = {
|
|
|
24388
24484
|
isAnimated: true,
|
|
24389
24485
|
supportsPointerTracking: true,
|
|
24390
24486
|
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
24391
|
-
const morphologyProfile =
|
|
24392
|
-
const animationRandom = createRandom('octopus3d2-animation-profile');
|
|
24393
|
-
const eyeRandom = createRandom('octopus3d2-eye-profile');
|
|
24394
|
-
const animationPhase = animationRandom() * Math.PI * 2;
|
|
24487
|
+
const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset } = getOctopus3d2StableState(createRandom);
|
|
24395
24488
|
const sceneCenterX = size * 0.5;
|
|
24396
24489
|
const sceneCenterY = size * 0.575;
|
|
24397
24490
|
const bob = Math.sin(timeMs / 940 + animationPhase) * size * 0.013;
|
|
@@ -24444,8 +24537,8 @@ const octopus3d2AvatarVisual = {
|
|
|
24444
24537
|
const rightEyeLocalCenter = sampleBlobbyOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude);
|
|
24445
24538
|
const eyeRadiusX = size * morphologyProfile.face.eyeRadiusXRatio * 0.78;
|
|
24446
24539
|
const eyeRadiusY = eyeRadiusX * morphologyProfile.face.eyeHeightRatio * 0.92;
|
|
24447
|
-
drawProjectedOrganicEye(context, leftEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase +
|
|
24448
|
-
drawProjectedOrganicEye(context, rightEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.9 +
|
|
24540
|
+
drawProjectedOrganicEye(context, leftEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
24541
|
+
drawProjectedOrganicEye(context, rightEyeLocalCenter, eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.9 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
24449
24542
|
drawProjectedOrganicMouth(context, [
|
|
24450
24543
|
sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthLatitude, mouthCenterLongitude - mouthHalfLongitude),
|
|
24451
24544
|
sampleBlobbyOctopusSurfacePoint(surfaceOptions, mouthCurveLatitude, mouthCenterLongitude),
|
|
@@ -24474,14 +24567,28 @@ function drawBlobbyOctopusAtmosphere(context, size, palette, sceneCenterX, scene
|
|
|
24474
24567
|
/**
|
|
24475
24568
|
* Draws the soft floor shadow that anchors the single mesh in the frame.
|
|
24476
24569
|
*
|
|
24570
|
+
* Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
|
|
24571
|
+
* blurry ellipse without triggering a costly software rasterization pass on every frame.
|
|
24572
|
+
*
|
|
24477
24573
|
* @private helper of `octopus3d2AvatarVisual`
|
|
24478
24574
|
*/
|
|
24479
24575
|
function drawBlobbyOctopusShadow(context, size, palette, interaction, timeMs, morphologyProfile) {
|
|
24576
|
+
const cx = size * 0.5 + interaction.gazeX * size * 0.045;
|
|
24577
|
+
const cy = size * 0.88 + Math.sin(timeMs / 940) * size * 0.008;
|
|
24578
|
+
const rx = size * (0.18 + (morphologyProfile.body.horizontalStretch - 1) * 0.04 + interaction.intensity * 0.018);
|
|
24579
|
+
const ry = size * 0.062;
|
|
24480
24580
|
context.save();
|
|
24481
|
-
context.
|
|
24482
|
-
context.
|
|
24581
|
+
context.translate(cx, cy);
|
|
24582
|
+
context.scale(1, ry / rx);
|
|
24583
|
+
const blurRadius = rx * 1.4;
|
|
24584
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
24585
|
+
shadowGradient.addColorStop(0, `${palette.shadow}7a`);
|
|
24586
|
+
shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
|
|
24587
|
+
shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
|
|
24588
|
+
shadowGradient.addColorStop(1, `${palette.shadow}00`);
|
|
24589
|
+
context.fillStyle = shadowGradient;
|
|
24483
24590
|
context.beginPath();
|
|
24484
|
-
context.
|
|
24591
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
24485
24592
|
context.fill();
|
|
24486
24593
|
context.restore();
|
|
24487
24594
|
}
|
|
@@ -24637,6 +24744,40 @@ const LIGHT_DIRECTION = normalizeVector3({
|
|
|
24637
24744
|
* @private helper of `octopus3d3AvatarVisual`
|
|
24638
24745
|
*/
|
|
24639
24746
|
const OCTOPUS_TENTACLE_COUNT = 8;
|
|
24747
|
+
/**
|
|
24748
|
+
* Cache keyed by the `createRandom` factory reference, which is stable for the lifetime of one
|
|
24749
|
+
* mounted `<Avatar/>` component (created inside `resolveAvatarRenderDefinition` and held in a
|
|
24750
|
+
* React `useMemo`). Using a `WeakMap` ensures the entry is collected when the component unmounts.
|
|
24751
|
+
*
|
|
24752
|
+
* @private helper of `octopus3d3AvatarVisual`
|
|
24753
|
+
*/
|
|
24754
|
+
const stableStateCache = new WeakMap();
|
|
24755
|
+
/**
|
|
24756
|
+
* Returns the stable per-avatar state, computing it on first access and returning the cached
|
|
24757
|
+
* result on every subsequent call within the same `<Avatar/>` mount.
|
|
24758
|
+
*
|
|
24759
|
+
* @private helper of `octopus3d3AvatarVisual`
|
|
24760
|
+
*/
|
|
24761
|
+
function getOctopus3d3StableState(createRandom) {
|
|
24762
|
+
const cached = stableStateCache.get(createRandom);
|
|
24763
|
+
if (cached !== undefined) {
|
|
24764
|
+
return cached;
|
|
24765
|
+
}
|
|
24766
|
+
const morphologyProfile = createOctopus3MorphologyProfile(createRandom);
|
|
24767
|
+
const animationRandom = createRandom('octopus3d3-animation-profile');
|
|
24768
|
+
const eyeRandom = createRandom('octopus3d3-eye-profile');
|
|
24769
|
+
const leftEyePhaseOffset = eyeRandom() * 0.7;
|
|
24770
|
+
const rightEyePhaseOffset = eyeRandom() * 0.7;
|
|
24771
|
+
const state = {
|
|
24772
|
+
morphologyProfile,
|
|
24773
|
+
animationPhase: animationRandom() * Math.PI * 2,
|
|
24774
|
+
leftEyePhaseOffset,
|
|
24775
|
+
rightEyePhaseOffset,
|
|
24776
|
+
tentacleProfiles: createContinuousTentacleProfiles(createRandom, morphologyProfile),
|
|
24777
|
+
};
|
|
24778
|
+
stableStateCache.set(createRandom, state);
|
|
24779
|
+
return state;
|
|
24780
|
+
}
|
|
24640
24781
|
/**
|
|
24641
24782
|
* Octopus 3D 3 avatar visual.
|
|
24642
24783
|
*
|
|
@@ -24649,11 +24790,7 @@ const octopus3d3AvatarVisual = {
|
|
|
24649
24790
|
isAnimated: true,
|
|
24650
24791
|
supportsPointerTracking: true,
|
|
24651
24792
|
render({ context, size, palette, createRandom, timeMs, interaction }) {
|
|
24652
|
-
const morphologyProfile =
|
|
24653
|
-
const animationRandom = createRandom('octopus3d3-animation-profile');
|
|
24654
|
-
const eyeRandom = createRandom('octopus3d3-eye-profile');
|
|
24655
|
-
const animationPhase = animationRandom() * Math.PI * 2;
|
|
24656
|
-
const tentacleProfiles = createContinuousTentacleProfiles(createRandom, morphologyProfile);
|
|
24793
|
+
const { morphologyProfile, animationPhase, leftEyePhaseOffset, rightEyePhaseOffset, tentacleProfiles } = getOctopus3d3StableState(createRandom);
|
|
24657
24794
|
const sceneCenterX = size * 0.5;
|
|
24658
24795
|
const sceneCenterY = size * 0.535;
|
|
24659
24796
|
const bob = Math.sin(timeMs / 960 + animationPhase) * size * 0.012;
|
|
@@ -24730,8 +24867,8 @@ const octopus3d3AvatarVisual = {
|
|
|
24730
24867
|
size,
|
|
24731
24868
|
palette,
|
|
24732
24869
|
});
|
|
24733
|
-
drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, -eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase +
|
|
24734
|
-
drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.85 +
|
|
24870
|
+
drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, -eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + leftEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
24871
|
+
drawProjectedOrganicEye(context, sampleContinuousOctopusSurfacePoint(surfaceOptions, eyeLatitude, eyeLongitude), eyeRadiusX, eyeRadiusY, meshCenter, rotationX, rotationY, sceneCenterX, sceneCenterY, size, palette, timeMs, animationPhase + 0.85 + rightEyePhaseOffset, interaction, morphologyProfile.face.eyeStyle);
|
|
24735
24872
|
drawProjectedOrganicMouth(context, [
|
|
24736
24873
|
sampleContinuousOctopusSurfacePoint(surfaceOptions, mouthLatitude, mouthCenterLongitude - mouthHalfLongitude),
|
|
24737
24874
|
sampleContinuousOctopusSurfacePoint(surfaceOptions, mouthCurveLatitude, mouthCenterLongitude),
|
|
@@ -24782,14 +24919,30 @@ function drawContinuousOctopusAtmosphere(context, size, palette, sceneCenterX, s
|
|
|
24782
24919
|
/**
|
|
24783
24920
|
* Draws the soft lower shadow that anchors the octopus in the avatar frame.
|
|
24784
24921
|
*
|
|
24922
|
+
* Uses a scaled radial gradient instead of `context.filter = 'blur()'` to approximate the
|
|
24923
|
+
* blurry ellipse without triggering a costly software rasterization pass on every frame.
|
|
24924
|
+
*
|
|
24785
24925
|
* @private helper of `octopus3d3AvatarVisual`
|
|
24786
24926
|
*/
|
|
24787
24927
|
function drawContinuousOctopusShadow(context, size, palette, interaction, timeMs, morphologyProfile) {
|
|
24928
|
+
const cx = size * 0.5 + interaction.gazeX * size * 0.045;
|
|
24929
|
+
const cy = size * 0.9 + Math.sin(timeMs / 980) * size * 0.007;
|
|
24930
|
+
const rx = size * (0.19 + morphologyProfile.tentacles.rootSpreadScale * 0.022 + interaction.intensity * 0.02);
|
|
24931
|
+
const ry = size * 0.06;
|
|
24932
|
+
// Scale the context so that drawing a circle produces the correct ellipse aspect ratio,
|
|
24933
|
+
// then fill with a radial gradient that approximates the blurry edge without context.filter.
|
|
24788
24934
|
context.save();
|
|
24789
|
-
context.
|
|
24790
|
-
context.
|
|
24935
|
+
context.translate(cx, cy);
|
|
24936
|
+
context.scale(1, ry / rx);
|
|
24937
|
+
const blurRadius = rx * 1.4;
|
|
24938
|
+
const shadowGradient = context.createRadialGradient(0, 0, 0, 0, 0, blurRadius);
|
|
24939
|
+
shadowGradient.addColorStop(0, `${palette.shadow}7a`);
|
|
24940
|
+
shadowGradient.addColorStop(0.45, `${palette.shadow}44`);
|
|
24941
|
+
shadowGradient.addColorStop(0.8, `${palette.shadow}1a`);
|
|
24942
|
+
shadowGradient.addColorStop(1, `${palette.shadow}00`);
|
|
24943
|
+
context.fillStyle = shadowGradient;
|
|
24791
24944
|
context.beginPath();
|
|
24792
|
-
context.
|
|
24945
|
+
context.arc(0, 0, blurRadius, 0, Math.PI * 2);
|
|
24793
24946
|
context.fill();
|
|
24794
24947
|
context.restore();
|
|
24795
24948
|
}
|