Skip to content

Commit e600b16

Browse files
committed
reverse mouse 3d controls
Reverses default mouse 3d controls, and allows panning in the z axis by default. Creates new Scene settings to allow switching back to original mouse controls.
1 parent d4af525 commit e600b16

9 files changed

Lines changed: 69 additions & 5 deletions

File tree

packages/studio-base/src/i18n/en/threeDee.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ export const threeDee = {
5454
meshUpAxis: "Mesh up axis",
5555
meshUpAxisHelp:
5656
"The direction to use as “up” when loading meshes without orientation info (STL and OBJ)",
57+
reverseMouse: "Reverse mouse buttons",
58+
reverseMouseHelp:
59+
"Reverse left and right mouse buttons for pan and rotate 3D control",
60+
lockPanning: "Lock XY panning",
61+
lockPanningHelp:
62+
"Only allow panning on the XY plane",
5763
renderStats: "Render stats",
5864
scene: "Scene",
5965
takeEffectAfterReboot: "This setting requires a restart to take effect",

packages/studio-base/src/i18n/ja/threeDee.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ export const threeDee: Partial<TypeOptions["resources"]["threeDee"]> = {
5757
meshUpAxis: "メッシュの上軸",
5858
meshUpAxisHelp:
5959
"方向を使用してメッシュを読み込むときに '上' として使用する方向(STL および OBJ)",
60+
reverseMouse: "マウスを逆にする",
61+
reverseMouseHelp: "マウスを逆にする",
62+
lockPanning: "XYパンをロック",
63+
lockPanningHelp: "XYパンをロック",
6064
renderStats: "レンダリングの統計情報",
6165
scene: "シーン",
6266
takeEffectAfterReboot: "この設定は再起動後に有効になります。",

packages/studio-base/src/i18n/zh/threeDee.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ export const threeDee: Partial<TypeOptions["resources"]["threeDee"]> = {
5353
labelScaleHelp: "应用于所有标签的比例因子",
5454
meshUpAxis: "网格上轴",
5555
meshUpAxisHelp: "加载缺少方向信息的网格(STL 和 OBJ)时使用的“上”方向",
56+
reverseMouse: "反向鼠标",
57+
reverseMouseHelp: "反向鼠标",
58+
lockPanning: "锁定 XY 平移",
59+
lockPanningHelp: "锁定 XY 平移",
5660
renderStats: "渲染统计",
5761
scene: "场景",
5862
takeEffectAfterReboot: "此设置需要重新启动以生效",

packages/studio-base/src/panels/ThreeDeeRender/IRenderer.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ export type RendererConfig = {
117117
/** Ignore the <up_axis> tag in COLLADA files (matching rviz behavior) */
118118
ignoreColladaUpAxis?: boolean;
119119
meshUpAxis?: MeshUpAxis;
120+
/** Reverse the mouse controls (matching rviz behavior) */
121+
reverseMouse?: boolean;
122+
/** Lock panning to XY plane only */
123+
lockPanning?: boolean;
120124
transforms?: {
121125
/** Toggles translation and rotation offset controls for frames */
122126
editable?: boolean;
@@ -332,6 +336,8 @@ export interface IRenderer extends EventEmitter<RendererEvents> {
332336

333337
getCameraState(): CameraState | undefined;
334338

339+
updateControls(): void;
340+
335341
/** Whether the view has been modified and a reset button should be shown (image mode only). */
336342
canResetView(): boolean;
337343
/** Reset any manual view modifications (image mode only). */

packages/studio-base/src/panels/ThreeDeeRender/Renderer.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,10 @@ export class Renderer extends EventEmitter<RendererEvents> implements IRenderer
918918
return this.cameraHandler.getCameraState();
919919
}
920920

921+
public updateControls(): void {
922+
return this.cameraHandler.updateControls();
923+
}
924+
921925
public canResetView(): boolean {
922926
return this.#imageModeExtension?.hasModifiedView() ?? false;
923927
}

packages/studio-base/src/panels/ThreeDeeRender/renderables/CameraStateSettings.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,8 @@ export class CameraStateSettings extends SceneExtension implements ICameraHandle
8484
this.add(this.#cameraGroup);
8585

8686
this.#controls = new OrbitControls(this.#perspectiveCamera, this.#canvas);
87-
this.#controls.screenSpacePanning = false; // only allow panning in the XY plane
88-
this.#controls.mouseButtons.LEFT = THREE.MOUSE.PAN;
89-
this.#controls.mouseButtons.RIGHT = THREE.MOUSE.ROTATE;
90-
this.#controls.touches.ONE = THREE.TOUCH.PAN;
91-
this.#controls.touches.TWO = THREE.TOUCH.DOLLY_ROTATE;
87+
this.updateControls();
88+
9289
this.#controls.addEventListener("change", () => {
9390
if (!this.#isUpdatingCameraState) {
9491
renderer.emit("cameraMove", renderer);
@@ -493,6 +490,27 @@ export class CameraStateSettings extends SceneExtension implements ICameraHandle
493490
};
494491
}
495492

493+
public updateControls(): void {
494+
this.#isUpdatingCameraState = true;
495+
if (this.renderer.config.scene.lockPanning ?? false) {
496+
this.#controls.screenSpacePanning = false;
497+
} else {
498+
this.#controls.screenSpacePanning = true;
499+
}
500+
if (this.renderer.config.scene.reverseMouse ?? false) {
501+
this.#controls.mouseButtons.LEFT = THREE.MOUSE.PAN;
502+
this.#controls.mouseButtons.RIGHT = THREE.MOUSE.ROTATE;
503+
this.#controls.touches.ONE = THREE.TOUCH.PAN;
504+
this.#controls.touches.TWO = THREE.TOUCH.DOLLY_ROTATE;
505+
} else {
506+
this.#controls.mouseButtons.LEFT = THREE.MOUSE.ROTATE;
507+
this.#controls.mouseButtons.RIGHT = THREE.MOUSE.PAN;
508+
this.#controls.touches.ONE = THREE.TOUCH.ROTATE;
509+
this.#controls.touches.TWO = THREE.TOUCH.DOLLY_PAN;
510+
}
511+
this.#isUpdatingCameraState = false;
512+
}
513+
496514
public setCameraState(cameraState: CameraState): void {
497515
this.#isUpdatingCameraState = true;
498516
this.#updateCameras(cameraState);

packages/studio-base/src/panels/ThreeDeeRender/renderables/ICameraHandler.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ export interface ICameraHandler extends SceneExtension {
1717
* @param state - The new camera state
1818
*/
1919
setCameraState(state: CameraState | undefined): void;
20+
/**
21+
* Update the orbital controls
22+
*/
23+
updateControls (): void;
2024
/**
2125
* Gets the state of the camera if interface mode supports it, otherwise undefined
2226
*/

packages/studio-base/src/panels/ThreeDeeRender/renderables/ImageMode/ImageMode.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,10 @@ export class ImageMode
944944
return undefined;
945945
}
946946

947+
public updateControls(): undefined {
948+
return undefined;
949+
}
950+
947951
#handleErrorChange = (): void => {
948952
this.updateSettingsTree();
949953
};

packages/studio-base/src/panels/ThreeDeeRender/renderables/SceneSettings.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,18 @@ export class SceneSettings extends SceneExtension {
8383
? t("threeDee:takeEffectAfterReboot")
8484
: undefined,
8585
},
86+
reverseMouse: {
87+
label: t("threeDee:reverseMouse"),
88+
help: t("threeDee:reverseMouseHelp"),
89+
input: "boolean",
90+
value: config.scene.reverseMouse,
91+
},
92+
lockPanning: {
93+
label: t("threeDee:lockPanning"),
94+
help: t("threeDee:lockPanningHelp"),
95+
input: "boolean",
96+
value: config.scene.lockPanning,
97+
},
8698
};
8799

88100
if (process.env.NODE_ENV === "production") {
@@ -133,6 +145,8 @@ export class SceneSettings extends SceneExtension {
133145
} else if (path[1] === "labelScaleFactor") {
134146
const labelScaleFactor = value as number | undefined;
135147
this.renderer.labelPool.setScaleFactor(labelScaleFactor ?? DEFAULT_LABEL_SCALE_FACTOR);
148+
} else if (path[1] === "reverseMouse" || path[1] === "lockPanning") {
149+
this.renderer.updateControls();
136150
}
137151
} else {
138152
return;

0 commit comments

Comments
 (0)