Skip to content

Commit

Permalink
[twisty] Add a property to disable latitude limits.
Browse files Browse the repository at this point in the history
  • Loading branch information
lgarron committed Jul 31, 2021
1 parent ba5f2fb commit 21d1ca2
Show file tree
Hide file tree
Showing 10 changed files with 102 additions and 10 deletions.
1 change: 1 addition & 0 deletions docs/cubing/api/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ <h1><a href="#twisty"><code>cubing/twisty</code></a></h1>
&nbsp;&nbsp;&nbsp;&nbsp;backView?: BackViewLayout;<br>
&nbsp;&nbsp;&nbsp;&nbsp;experimentalCameraLatitude?: Vector3;<br>
&nbsp;&nbsp;&nbsp;&nbsp;experimentalCameraLongitude?: Vector3;<br>
&nbsp;&nbsp;&nbsp;&nbsp;experimentalCameraLatitudeLimits?: "auto" | "none";<br>
<br>
&nbsp;&nbsp;&nbsp;&nbsp;viewerLink?: "twizzle" | "none";<br>
&nbsp;&nbsp;})<br>
Expand Down
35 changes: 35 additions & 0 deletions src/cubing/twisty/dom/TwistyPlayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { customElementsShim } from "./element/node-custom-element-shims";
import { twistyPlayerCSS } from "./TwistyPlayer.css_";
import {
BackgroundTheme,
CameraLatitudeLimits,
ControlsLocation,
defaultCameraOrbitCoordinates,
ExperimentalStickering,
Expand Down Expand Up @@ -330,6 +331,15 @@ export class TwistyPlayer extends ManagedCustomElement {
return (this.viewerElems[0] as Twisty3DCanvas)?.orbitControls ?? null;
}

#backOrbitControls(): TwistyOrbitControls | null {
if (
!["3D", "PG3D"].includes(this.#config.attributes["visualization"].value)
) {
return null;
}
return (this.viewerElems[1] as Twisty3DCanvas)?.orbitControls ?? null;
}

set experimentalCameraLatitude(latitude: number | null) {
this.#config.attributes["experimental-camera-latitude"].setValue(latitude);
const orbitControls = this.#orbitControls();
Expand Down Expand Up @@ -370,6 +380,27 @@ export class TwistyPlayer extends ManagedCustomElement {
return this.#orbitControls()?.longitude ?? null;
}

set experimentalCameraLatitudeLimits(latitudeLimits: CameraLatitudeLimits) {
this.#config.attributes["experimental-camera-latitude-limits"].setValue(
latitudeLimits,
);
const orbitControls = this.#orbitControls();
console.log({ orbitControls });
if (orbitControls) {
orbitControls.experimentalLatitudeLimits = latitudeLimits;
}
const backOrbitControls = this.#backOrbitControls(); // TODO: propagate through direct orbit controls as source of truth.
if (backOrbitControls) {
backOrbitControls.experimentalLatitudeLimits = latitudeLimits;
}
}

get experimentalCameraLatitudeLimits(): CameraLatitudeLimits {
// TODO: sync with orbit controls
return this.#config.attributes["experimental-camera-latitude-limits"]
.value as CameraLatitudeLimits;
}

set viewerLink(viewerLinkPage: ViewerLinkPage) {
this.#config.attributes["viewer-link"].setValue(viewerLinkPage);
const maybePanel = this.controlElems[1] as
Expand Down Expand Up @@ -584,6 +615,8 @@ export class TwistyPlayer extends ManagedCustomElement {
const mainViewer = new Twisty3DCanvas(this.scene, {
orbitCoordinates: this.experimentalDerivedCameraOrbitCoordinates(),
});
mainViewer.orbitControls.experimentalLatitudeLimits =
this.experimentalCameraLatitudeLimits;
this.viewerElems.push(mainViewer);
this.#viewerWrapper.addElement(mainViewer);

Expand Down Expand Up @@ -805,6 +838,8 @@ export class TwistyPlayer extends ManagedCustomElement {
orbitCoordinates: this.experimentalDerivedCameraOrbitCoordinates(),
negateCameraPosition: true,
});
backViewer.orbitControls.experimentalLatitudeLimits =
this.experimentalCameraLatitudeLimits;
this.viewerElems.push(backViewer);
(this.viewerElems[0] as Twisty3DCanvas).setMirror(backViewer);
this.#viewerWrapper.addElement(backViewer);
Expand Down
21 changes: 17 additions & 4 deletions src/cubing/twisty/dom/TwistyPlayerConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,12 @@ export interface ManagedAttribute<K> {
setValue(v: K): boolean;
}

export const cameraLatitudeLimits = {
auto: true, // default
none: true,
};
export type CameraLatitudeLimits = keyof typeof cameraLatitudeLimits;

type AnyManagedAttribute = ManagedAttribute<any>;

interface TwistyPlayerAttributes extends Record<string, AnyManagedAttribute> {
Expand All @@ -202,6 +208,7 @@ interface TwistyPlayerAttributes extends Record<string, AnyManagedAttribute> {
"back-view": StringEnumAttribute<BackViewLayout>;
"experimental-camera-latitude": RangedFloatAttribute;
"experimental-camera-longitude": RangedFloatAttribute;
"experimental-camera-latitude-limits": StringEnumAttribute<CameraLatitudeLimits>;

// Interaction
"viewer-link": StringEnumAttribute<ViewerLinkPage>;
Expand All @@ -223,6 +230,7 @@ export interface TwistyPlayerConfigValues {
backView: BackViewLayout;
experimentalCameraLatitude: number;
experimentalCameraLongitude: number;
experimentalCameraLatitudeLimits: CameraLatitudeLimits;

viewerLink: ViewerLinkPage;
}
Expand All @@ -248,6 +256,7 @@ const twistyPlayerAttributeMap: Record<
"back-view": "backView",
"experimental-camera-latitude": "experimentalCameraLatitude",
"experimental-camera-longitude": "experimentalCameraLongitude",
"experimental-camera-latitude-limits": "experimentalCameraLatitudeLimits",

"viewer-link": "viewerLink",
};
Expand Down Expand Up @@ -301,16 +310,20 @@ export class TwistyPlayerConfig {
90,
initialValues["experimentalCameraLatitude"],
),
"viewer-link": new StringEnumAttribute(
viewerLinkPages,
initialValues.viewerLink,
),
"experimental-camera-longitude": new RangedFloatAttribute(
null,
-180,
180,
initialValues["experimentalCameraLongitude"],
),
"experimental-camera-latitude-limits": new StringEnumAttribute(
cameraLatitudeLimits,
initialValues["experimentalCameraLatitudeLimits"],
),
"viewer-link": new StringEnumAttribute(
viewerLinkPages,
initialValues.viewerLink,
),
};
}

Expand Down
3 changes: 2 additions & 1 deletion src/cubing/twisty/dom/viewers/Twisty3DCanvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { OrbitCoordinates, TwistyOrbitControls } from "./TwistyOrbitControls";
import type { TwistyViewerElement } from "./TwistyViewerElement";
import { customElementsShim } from "../element/node-custom-element-shims";
import { Stats } from "../../../vendor/three/examples/jsm/libs/stats.module";
import type { CameraLatitudeLimits } from "../TwistyPlayerConfig";

let SHOW_STATS = false;
// Show render stats for newly contructed renderers.
Expand Down Expand Up @@ -122,7 +123,7 @@ export class Twisty3DCanvas
}

/** @deprecated */
public experimentalSetLatitudeLimits(limits: boolean): void {
public experimentalSetLatitudeLimits(limits: CameraLatitudeLimits): void {
this.orbitControls.experimentalLatitudeLimits = limits;
}

Expand Down
7 changes: 4 additions & 3 deletions src/cubing/twisty/dom/viewers/TwistyOrbitControls.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { Camera, Spherical, Vector3 } from "three";
import { DEGREES_PER_RADIAN } from "../../3D/TAU";
import { RenderScheduler } from "../../animation/RenderScheduler";
import type { CameraLatitudeLimits } from "../TwistyPlayerConfig";

// Buffer at the end values of the latitude (phi), to prevent gymbal lock.
// Without this, the puzzle would flip every frame if you try to push past the
// end, or snap to a standard longitude (theta).
const EPSILON = 0.00000001;

const INERTIA_DEFAULT: boolean = true;
const LATITUDE_LIMITS_DEFAULT: boolean = true;
const LATITUDE_LIMITS_DEFAULT: CameraLatitudeLimits = "auto";

const INERTIA_DURATION_MS = 500;
// If the first inertial render is this long after the last move, we assume the
Expand Down Expand Up @@ -166,7 +167,7 @@ export class TwistyOrbitControls {
/** @deprecated */
experimentalInertia: boolean = INERTIA_DEFAULT;
/** @deprecated */
experimentalLatitudeLimits: boolean = LATITUDE_LIMITS_DEFAULT;
experimentalLatitudeLimits: CameraLatitudeLimits = LATITUDE_LIMITS_DEFAULT;
private mirrorControls?: TwistyOrbitControls;
private lastTouchClientX: number = 0;
private lastTouchClientY: number = 0;
Expand Down Expand Up @@ -322,7 +323,7 @@ export class TwistyOrbitControls {

this.#spherical.theta += -2 * movementX;
this.#spherical.phi += -2 * movementY;
if (this.experimentalLatitudeLimits) {
if (this.experimentalLatitudeLimits !== "none") {
this.#spherical.phi = Math.max(this.#spherical.phi, Math.PI * 0.3); // TODO: Arctic circle: 1/6
this.#spherical.phi = Math.min(this.#spherical.phi, Math.PI * 0.7); // TODO: Antarctic circle: 5/6
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/sites/alpha.twizzle.net/explore/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ async function setAlgo(str: string, writeback: boolean): Promise<void> {
backView: getCheckbox("sidebyside") ? "side-by-side" : "top-right",
experimentalCameraLatitude: initialCameraOrbitCoordinates.latitude,
experimentalCameraLongitude: initialCameraOrbitCoordinates.longitude,
experimentalCameraLatitudeLimits: "none",
// TODO: distance?
viewerLink: "none",
},
Expand All @@ -303,7 +304,6 @@ async function setAlgo(str: string, writeback: boolean): Promise<void> {
initialCameraOrbitCoordinates,
);
for (const twisty3DCanvas of twisty3DCanvases) {
twisty3DCanvas.experimentalSetLatitudeLimits(false);
twisty3DCanvas.canvas.addEventListener(
"mouseup",
onMouseClick.bind(onMouseClick, twisty3DCanvas, "U"),
Expand Down
2 changes: 1 addition & 1 deletion src/sites/experiments.cubing.net/cubing.js/flag/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const canvas = new Twisty3DCanvas(scene, {
});
canvas.camera.position.y = 24;
canvas.camera.far = 100; // Document this for others.
canvas.experimentalSetLatitudeLimits(false);
canvas.experimentalSetLatitudeLimits("none");
document.body.appendChild(canvas);

function randomChoice<T>(l: T[]): T {
Expand Down
18 changes: 18 additions & 0 deletions src/sites/experiments.cubing.net/cubing.js/twisty/attributes.html
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,24 @@ <h2>
</div>
</div>

<div class="content">
<h2>
<code>experimental-camera-latitude-limits=&quot;none&quot;</code><br />
<code class="dim">alg=&quot;R U R' U R U2' R'&quot;</code><br />
<code class="dim">experimental-camera-latitude=&quot;80&quot;</code>
</h2>
<div class="multi" id="experimental-camera-latitude-limits">
<span>DOM attributes:</span>
<span>Constructor config object:</span>
<span>Dynamic property setter:</span>
<twisty-player
alg="R U R' U R U2' R'"
experimental-camera-latitude-limits="none"
experimental-camera-latitude="80"
></twisty-player>
</div>
</div>

<div class="content">
<h2><code>viewer-link=&quot;none&quot;</code></h2>
<div class="multi" id="viewer-link">
Expand Down
17 changes: 17 additions & 0 deletions src/sites/experiments.cubing.net/cubing.js/twisty/attributes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,23 @@ experimentalSetShareAllNewRenderers(true);
tw.experimentalCameraLongitude = 0;
}

{
document.querySelector("#experimental-camera-latitude-limits")!.appendChild(
new TwistyPlayer({
alg: "R U R' U R U2' R'",
experimentalCameraLatitudeLimits: "none",
experimentalCameraLatitude: 80,
}),
);
const tw = new TwistyPlayer();
document
.querySelector("#experimental-camera-latitude-limits")!
.appendChild(tw);
tw.alg = new Alg("R U R' U R U2' R'");
tw.experimentalCameraLatitudeLimits = "none";
tw.experimentalCameraLatitude = 80;
}

{
document.querySelector("#viewer-link")!.appendChild(
new TwistyPlayer({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {
backgroundThemes,
cameraLatitudeLimits,
controlsLocations,
experimentalStickerings,
hintFaceletStyles,
Expand Down Expand Up @@ -57,6 +58,11 @@ const enumOptions: [string, string, Record<string, any>][] = [
["controlPanel", "control-panel", controlsLocations],

["backView", "back-view", backViewLayouts],
[
"experimentalCameraLatitudeLimits",
"experimental-camera-latitude-limits",
cameraLatitudeLimits,
],

["viewerLink", "viewer-link", viewerLinkPages],
];
Expand Down

0 comments on commit 21d1ca2

Please sign in to comment.