fix: external mouse init

This commit is contained in:
Kevin
2025-05-29 14:36:02 -05:00
parent 7c3842b5df
commit 28058e2e3c

View File

@ -1,16 +1,32 @@
import { Matrix4, Vector3 } from 'three'
import { Matrix4, Vector3} from 'three';
// @ts-ignore // @ts-ignore
import * as THREE from "../../node_modules/three/build/three.module.js" import * as THREE from 'three'
declare global { declare global {
var _3Dconnexion: any; var _3Dconnexion: any
interface Window { interface Window {
the3DMouse: any; the3DMouse: any
} }
} }
type SixteenNumbers = [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number]; type SixteenNumbers = [
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
]
type Min = number type Min = number
type Max = number type Max = number
@ -27,70 +43,91 @@ type ViewExtents = [Left, Bottom, FrustumFar, Right, Top, FrustrumNear]
// this function fills the action and images structures that are exposed // this function fills the action and images structures that are exposed
// to the 3Dconnexion button configuration editor // to the 3Dconnexion button configuration editor
function getApplicationCommands(buttonBank, images) { function getApplicationCommands(buttonBank, images) {
// Add a couple of categiores / menus / tabs to the buttonbank/menubar/toolbar // Add a couple of categiores / menus / tabs to the buttonbank/menubar/toolbar
// Use the categories to group actions so that the user can find them easily // Use the categories to group actions so that the user can find them easily
var fileNode = buttonBank.push(new _3Dconnexion.Category('CAT_ID_FILE', 'File')); var fileNode = buttonBank.push(
var editNode = buttonBank.push(new _3Dconnexion.Category('CAT_ID_EDIT', 'Edit')); new _3Dconnexion.Category('CAT_ID_FILE', 'File')
)
var editNode = buttonBank.push(
new _3Dconnexion.Category('CAT_ID_EDIT', 'Edit')
)
// Add menu items / actions // Add menu items / actions
fileNode.push(new _3Dconnexion.Action('ID_OPEN', 'Open', 'Open file')); fileNode.push(new _3Dconnexion.Action('ID_OPEN', 'Open', 'Open file'))
fileNode.push(new _3Dconnexion.Action('ID_CLOSE', 'Close', 'Close file')); fileNode.push(new _3Dconnexion.Action('ID_CLOSE', 'Close', 'Close file'))
fileNode.push(new _3Dconnexion.Action('ID_EXIT', 'Exit', 'Exit program')); fileNode.push(new _3Dconnexion.Action('ID_EXIT', 'Exit', 'Exit program'))
// Add menu items / actions // Add menu items / actions
editNode.push(new _3Dconnexion.Action('ID_UNDO', 'Undo', 'Shortcut is Ctrl + Z')); editNode.push(
editNode.push(new _3Dconnexion.Action('ID_REDO', 'Redo', 'Shortcut is Ctrl + Y')); new _3Dconnexion.Action('ID_UNDO', 'Undo', 'Shortcut is Ctrl + Z')
editNode.push(new _3Dconnexion.Action('ID_CUT', 'Cut', 'Shortcut is Ctrl + X')); )
editNode.push(new _3Dconnexion.Action('ID_COPY', 'Copy', 'Shortcut is Ctrl + C')); editNode.push(
editNode.push(new _3Dconnexion.Action('ID_PASTE', 'Paste', 'Shortcut is Ctrl + V')); new _3Dconnexion.Action('ID_REDO', 'Redo', 'Shortcut is Ctrl + Y')
)
editNode.push(
new _3Dconnexion.Action('ID_CUT', 'Cut', 'Shortcut is Ctrl + X')
)
editNode.push(
new _3Dconnexion.Action('ID_COPY', 'Copy', 'Shortcut is Ctrl + C')
)
editNode.push(
new _3Dconnexion.Action('ID_PASTE', 'Paste', 'Shortcut is Ctrl + V')
)
// Now add the images to the cache and associate it with the menu item by using the same id as the menu item / action // Now add the images to the cache and associate it with the menu item by using the same id as the menu item / action
// These images will be shown in the 3Dconnexion properties editor and in the UI elements which display the // These images will be shown in the 3Dconnexion properties editor and in the UI elements which display the
// active button configuration of the 3dmouse // active button configuration of the 3dmouse
images.push(_3Dconnexion.ImageItem.fromURL('images/open.png', 'ID_OPEN')); images.push(_3Dconnexion.ImageItem.fromURL('images/open.png', 'ID_OPEN'))
images.push(_3Dconnexion.ImageItem.fromURL('images/close.png', 'ID_CLOSE')); images.push(_3Dconnexion.ImageItem.fromURL('images/close.png', 'ID_CLOSE'))
images.push(_3Dconnexion.ImageItem.fromURL('images/exit.png', 'ID_EXIT')); images.push(_3Dconnexion.ImageItem.fromURL('images/exit.png', 'ID_EXIT'))
images.push(_3Dconnexion.ImageItem.fromURL('images/Macro_Cut.png', 'ID_CUT')); images.push(_3Dconnexion.ImageItem.fromURL('images/Macro_Cut.png', 'ID_CUT'))
images.push(_3Dconnexion.ImageItem.fromURL('images/Macro_Copy.png', 'ID_COPY')); images.push(
images.push(_3Dconnexion.ImageItem.fromURL('images/Macro_Paste.png', 'ID_PASTE')); _3Dconnexion.ImageItem.fromURL('images/Macro_Copy.png', 'ID_COPY')
images.push(_3Dconnexion.ImageItem.fromURL('images/Macro_Undo.png', 'ID_UNDO')); )
images.push(_3Dconnexion.ImageItem.fromURL('images/Macro_Redo.png', 'ID_REDO')); images.push(
_3Dconnexion.ImageItem.fromURL('images/Macro_Paste.png', 'ID_PASTE')
)
images.push(
_3Dconnexion.ImageItem.fromURL('images/Macro_Undo.png', 'ID_UNDO')
)
images.push(
_3Dconnexion.ImageItem.fromURL('images/Macro_Redo.png', 'ID_REDO')
)
} }
interface _3DconnexionHelper { interface _3DconnexionHelper {
connect(): boolean; connect(): boolean
debug: boolean; debug: boolean
create3dmouse(canvas: HTMLElement | null, name: string): void; create3dmouse(canvas: HTMLElement | null, name: string): void
update3dcontroller(any): void update3dcontroller(any): void
} }
interface _3DconnexionMiddleware { interface _3DconnexionMiddleware {
// Callbacks // Callbacks
getCoordinateSystem(): SixteenNumbers; getCoordinateSystem(): SixteenNumbers
getFrontView(): SixteenNumbers; getFrontView(): SixteenNumbers
getViewMatrix():SixteenNumbers; getViewMatrix(): SixteenNumbers
getFov():number; getFov(): number
getPerspective():boolean; getPerspective(): boolean
getModelExtents(): BoundingBox; getModelExtents(): BoundingBox
getPointerPosition?(): Position; getPointerPosition?(): Position
getPivotPositon?(): Position; getPivotPositon?(): Position
getViewExtents(): ViewExtents; getViewExtents(): ViewExtents
getFrameTime(): number; getFrameTime(): number
setViewExtents(viewExtents: ViewExtents): void; setViewExtents(viewExtents: ViewExtents): void
// Commands // Commands
setActiveCommand(id:any): void; setActiveCommand(id: any): void
setViewMatrix(viewMatrix: SixteenNumbers): void; setViewMatrix(viewMatrix: SixteenNumbers): void
setFov(fov: number): void; setFov(fov: number): void
setTransaction(transaction: number): void; setTransaction(transaction: number): void
onStartMotion(): void; onStartMotion(): void
onStopMotion(): void; onStopMotion(): void
// 3D mouse initialization // 3D mouse initialization
init3DMouse(): void; init3DMouse(): void
onConnect(): void; onConnect(): void
onDisconnect(reason: string): void; onDisconnect(reason: string): void
on3dmouseCreated(): void on3dmouseCreated(): void
// huh? // huh?
@ -98,7 +135,7 @@ interface _3DconnexionMiddleware {
} }
interface _3DMouseConfiguration { interface _3DMouseConfiguration {
debug: boolean, debug: boolean
name: string name: string
canvasId: string canvasId: string
} }
@ -121,24 +158,24 @@ class _3DMouse implements _3DconnexionMiddleware {
model: Model = { model: Model = {
extends: { extends: {
min: new THREE.Vector3(), min: new THREE.Vector3(),
max: new THREE.Vector3() max: new THREE.Vector3(),
} },
} }
// huh okay? // huh okay?
viewportWidth: number viewportWidth: number
viewportHeight : number viewportHeight: number
fov : number fov: number
frustumNear : number frustumNear: number
frustumFar : number frustumFar: number
left : number left: number
right: number right: number
bottom : number bottom: number
top : number top: number
constructor(configuration: _3DMouseConfiguration) { constructor(configuration: _3DMouseConfiguration) {
// no op for now // no op for now
console.log("_3DMouse has a no op constructor") console.log('_3DMouse has a no op constructor')
this.name = configuration.name this.name = configuration.name
this.debug = configuration.debug this.debug = configuration.debug
@ -152,15 +189,15 @@ class _3DMouse implements _3DconnexionMiddleware {
// callbacks // callbacks
getCoordinateSystem(): SixteenNumbers { getCoordinateSystem(): SixteenNumbers {
// In this sample the cs has Y to the right, Z-up and X out of the screen // In this sample the cs has Y to the right, Z-up and X out of the screen
return [0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1]; return [0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1]
} }
getFrontView(): SixteenNumbers { getFrontView(): SixteenNumbers {
return [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1]; return [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1]
} }
getModelExtents(): BoundingBox { getModelExtents(): BoundingBox {
return[-1,-1,-1,1,1,1] return [-1, -1, -1, 1, 1, 1]
} }
getPerspective(): boolean { getPerspective(): boolean {
@ -176,7 +213,14 @@ class _3DMouse implements _3DconnexionMiddleware {
} }
getViewExtents(): ViewExtents { getViewExtents(): ViewExtents {
return [this.left, this.bottom, -this.frustumFar, this.right, this.top, -this.frustumNear]; return [
this.left,
this.bottom,
-this.frustumFar,
this.right,
this.top,
-this.frustumNear,
]
} }
getFrameTime(): number { getFrameTime(): number {
@ -195,8 +239,7 @@ class _3DMouse implements _3DconnexionMiddleware {
this.spaceMouse = new _3Dconnexion(this) this.spaceMouse = new _3Dconnexion(this)
this.spaceMouse.debug = this.debug this.spaceMouse.debug = this.debug
if (!this.spaceMouse.connect()) { if (!this.spaceMouse.connect()) {
if (this.debug) if (this.debug) console.log('Cannot connect to 3Dconnexion NL-Proxy')
console.log("Cannot connect to 3Dconnexion NL-Proxy");
} }
} }
@ -206,19 +249,20 @@ class _3DMouse implements _3DconnexionMiddleware {
this.viewportWidth = canvas.width this.viewportWidth = canvas.width
this.viewportHeight = canvas.height this.viewportHeight = canvas.height
this.fov = 33 * Math.PI / 180.0 this.fov = (33 * Math.PI) / 180.0
this.frustumNear = -1000 this.frustumNear = -1000
this.frustumFar = 1000 this.frustumFar = 1000
this.left = -175; this.left = -175
this.right = -this.left; this.right = -this.left
this.bottom = -(this.right - this.left) * this.viewportHeight / this.viewportWidth / 2. this.bottom =
(-(this.right - this.left) * this.viewportHeight) / this.viewportWidth / 2
this.top = -this.bottom this.top = -this.bottom
this.spaceMouse.create3dmouse(canvas, this.name) this.spaceMouse.create3dmouse(canvas, this.name)
} }
onDisconnect(reason: string): void { onDisconnect(reason: string): void {
console.log("3Dconnexion NL-Proxy disconnected " + reason); console.log('3Dconnexion NL-Proxy disconnected ' + reason)
} }
on3dmouseCreated(): void { on3dmouseCreated(): void {
@ -228,31 +272,34 @@ class _3DMouse implements _3DconnexionMiddleware {
// set ourselves as the timing source for the animation frames // set ourselves as the timing source for the animation frames
this.spaceMouse.update3dcontroller({ this.spaceMouse.update3dcontroller({
'frame': { 'timingSource': 1 } frame: { timingSource: 1 },
}) })
actionImages.onload = () => { actionImages.onload = () => {
this.spaceMouse.update3dcontroller({ 'images': actionImages.images }); this.spaceMouse.update3dcontroller({ images: actionImages.images })
}; }
// An actionset can also be considered to be a buttonbank, a menubar, or a set of toolbars // An actionset can also be considered to be a buttonbank, a menubar, or a set of toolbars
// Define a unique string for the action set to be able to specify the active action set // Define a unique string for the action set to be able to specify the active action set
// Because we only have one action set use the 'Default' action set id to not display the label // Because we only have one action set use the 'Default' action set id to not display the label
var buttonBank = actionTree.push(new _3Dconnexion.ActionSet('Default', 'Custom action set')); var buttonBank = actionTree.push(
getApplicationCommands(buttonBank, actionImages); new _3Dconnexion.ActionSet('Default', 'Custom action set')
)
getApplicationCommands(buttonBank, actionImages)
// Expose the commands to 3Dxware and specify the active buttonbank / action set // Expose the commands to 3Dxware and specify the active buttonbank / action set
this.spaceMouse.update3dcontroller({ 'commands': { 'activeSet': 'Default', 'tree': actionTree } }); this.spaceMouse.update3dcontroller({
commands: { activeSet: 'Default', tree: actionTree },
})
} }
// commands // commands
setActiveCommand(id: any): void { setActiveCommand(id: any): void {
if (id) { if (id) {
console.log("Id of command to execute= " + id) console.log('Id of command to execute= ' + id)
} }
} }
setViewMatrix(viewMatrix: SixteenNumbers): void { setViewMatrix(viewMatrix: SixteenNumbers): void {
this.cameraMatrix = viewMatrix this.cameraMatrix = viewMatrix
} }
@ -262,7 +309,7 @@ class _3DMouse implements _3DconnexionMiddleware {
} }
setTransaction(transaction: number): void { setTransaction(transaction: number): void {
if(transaction === 0) { if (transaction === 0) {
console.log('request a redraw not animating') console.log('request a redraw not animating')
} }
} }
@ -276,26 +323,25 @@ class _3DMouse implements _3DconnexionMiddleware {
} }
render(time): void { render(time): void {
if(this.animating) { if (this.animating) {
this.spaceMouse.update3dcontroller({ this.spaceMouse.update3dcontroller({
'frame': { 'time': time } frame: { time: time },
}); })
window.requestAnimationFrame(this.render.bind(this)) window.requestAnimationFrame(this.render.bind(this))
} }
} }
onStopMotion(): void { onStopMotion(): void {
console.log("stopped!") console.log('stopped!')
this.animating = false this.animating = false
} }
} }
const the3DMouse = new _3DMouse({ const the3DMouse = new _3DMouse({
// Name needs to be registered in the python proxy server! // Name needs to be registered in the python proxy server!
name:'Image Web Viewer', name: 'Image Web Viewer',
debug: true, debug: true,
canvasId: 'webgl' canvasId: 'webgl',
}) })
window.the3DMouse = the3DMouse window.the3DMouse = the3DMouse