Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vim-web",
"version": "0.5.0-dev.17",
"version": "0.5.0-dev.24",
"description": "A demonstration app built on top of the vim-webgl-viewer",
"type": "module",
"files": [
Expand Down
45 changes: 39 additions & 6 deletions src/vim-web/core-viewers/shared/mouseHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export class MouseHandler extends BaseInputHandler {
private _capture: CaptureHandler;
private _dragHandler: DragHandler;
private _doubleClickHandler: DoubleClickHandler = new DoubleClickHandler();
private _clickHandler: ClickHandler = new ClickHandler();

onButtonDown: (pos: THREE.Vector2, button: number) => void;
onButtonUp: (pos: THREE.Vector2, button: number) => void;
Expand Down Expand Up @@ -47,27 +48,36 @@ export class MouseHandler extends BaseInputHandler {
this._lastMouseDownPosition = pos;
// Start drag
this._dragHandler.onPointerDown(pos, event.button);
this._clickHandler.onPointerDown(pos);
this._capture.onPointerDown(event);
event.preventDefault();
}

private handlePointerUp(event: PointerEvent): void {
if (event.pointerType !== 'mouse') return;
event.preventDefault();

const pos = this.relativePosition(event);

// Button up event
this.onButtonUp?.(pos, event.button);
this._capture.onPointerUp(event);
this._dragHandler.onPointerUp();
this._clickHandler.onPointerUp();


// Click type event
if(this._doubleClickHandler.checkForDoubleClick(event)){
if(this._doubleClickHandler.isDoubleClick(event)){
this.handleDoubleClick(event);
}else{
return
}
if(this._clickHandler.isClick(event)){
this.handleMouseClick(event);
this.handleContextMenu(event);
return
}
event.preventDefault();

this.handleContextMenu(event);

}

private async handleMouseClick(event: PointerEvent): Promise<void> {
Expand Down Expand Up @@ -102,8 +112,8 @@ export class MouseHandler extends BaseInputHandler {
if (event.pointerType !== 'mouse') return;
this._canvas.focus();
const pos = this.relativePosition(event);

this._dragHandler.onPointerMove(pos);
this._clickHandler.onPointerMove(pos);
this.onMouseMove?.(pos);
}

Expand Down Expand Up @@ -157,13 +167,36 @@ class CaptureHandler {
}
}

class ClickHandler {
private _moved: boolean = false;
private _startPosition: THREE.Vector2 = new THREE.Vector2();
private _clickThreshold: number = 0.003 ;

onPointerDown(pos: THREE.Vector2): void {
this._moved = false;
this._startPosition.copy(pos);
}
onPointerMove(pos: THREE.Vector2): void {
if (pos.distanceTo(this._startPosition) > this._clickThreshold) {
this._moved = true;
}
}

onPointerUp(): void { }

isClick(event: PointerEvent): boolean {
if (event.button !== 0) return false; // Only left button
return !this._moved;
}
}

class DoubleClickHandler {
private _lastClickTime: number = 0;
private _clickDelay: number = 300; // Max time between clicks for double-click
private _lastClickPosition: THREE.Vector2 | null = null;
private _positionThreshold: number = 5; // Max pixel distance between clicks

checkForDoubleClick(event: MouseEvent): boolean {
isDoubleClick(event: MouseEvent): boolean {
const currentTime = Date.now();
const currentPosition = new THREE.Vector2(event.clientX, event.clientY);
const timeDiff = currentTime - this._lastClickTime;
Expand Down
11 changes: 11 additions & 0 deletions src/vim-web/core-viewers/ultra/viewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ import { RpcSafeClient } from "./rpcSafeClient";
export interface IViewport {
/** The HTML canvas element used for rendering */
canvas: HTMLCanvasElement

/** Updates the aspect ratio of the viewport on the server */
update(): void

/** Resizes the viewport to match its parent's dimensions */
resizeToParent(): void
}

/**
Expand Down Expand Up @@ -57,6 +61,13 @@ export class Viewport {
}
}

/**
* Resizes the viewport to match its parent's dimensions
*/
resizeToParent() {
this.update()
}

/**
* Cleans up resources by removing resize observer and clearing timeouts
*/
Expand Down
55 changes: 42 additions & 13 deletions src/vim-web/core-viewers/webgl/loader/mesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,20 +94,49 @@ export class Mesh {
}

/**
* Overrides mesh material, set to undefine to restore initial material.
*/
setMaterial (value: ModelMaterial) {
if (this._material === value) return
if (this.ignoreSceneMaterial) return
this.mesh.material = value ?? this._material

// Update material groups
this.mesh.geometry.clearGroups()
if(value instanceof Array) {
value.forEach((m, i) => {
this.mesh.geometry.addGroup(0, Infinity, i)
})
* Sets the material for this mesh.
* Set to undefined to reset to original materials.
*/
setMaterial(value: ModelMaterial) {
if (this.ignoreSceneMaterial) return;

const base = this._material; // always defined
let mat: ModelMaterial;

if (Array.isArray(value)) {
mat = this._mergeMaterials(value, base);
} else {
mat = value ?? base;
}

// Apply it
this.mesh.material = mat;

// Update groups
this.mesh.geometry.clearGroups();
if (Array.isArray(mat)) {
mat.forEach((_m, i) => {
this.mesh.geometry.addGroup(0, Infinity, i);
});
}
}

private _mergeMaterials(
value: THREE.Material[],
base: ModelMaterial
): THREE.Material[] {
const baseArr = Array.isArray(base) ? base : [base];
const result: THREE.Material[] = [];

for (const v of value) {
if (v === undefined) {
result.push(...baseArr);
} else {
result.push(v);
}
}

return result;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,20 +129,49 @@ export class InsertableMesh {
// }
}

/**
* Overrides mesh material, set to undefine to restore initial material.
*/
setMaterial (value: ModelMaterial) {
if (this._material === value) return
if (this.ignoreSceneMaterial) return
this.mesh.material = value ?? this._material

// Update material groups
this.mesh.geometry.clearGroups()
if(value instanceof Array) {
value.forEach((m, i) => {
this.mesh.geometry.addGroup(0, Infinity, i)
})
}
}
/**
* Sets the material for this mesh.
* Set to undefined to reset to original materials.
*/
setMaterial(value: ModelMaterial) {
if (this.ignoreSceneMaterial) return;

const base = this._material; // always defined
let mat: ModelMaterial;

if (Array.isArray(value)) {
mat = this._mergeMaterials(value, base);
} else {
mat = value ?? base;
}

// Apply it
this.mesh.material = mat;

// Update groups
this.mesh.geometry.clearGroups();
if (Array.isArray(mat)) {
mat.forEach((_m, i) => {
this.mesh.geometry.addGroup(0, Infinity, i);
});
}
}

private _mergeMaterials(
value: THREE.Material[],
base: ModelMaterial
): THREE.Material[] {
const baseArr = Array.isArray(base) ? base : [base];
const result: THREE.Material[] = [];

for (const v of value) {
if (v === undefined) {
result.push(...baseArr);
} else {
result.push(v);
}
}

return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,51 @@ export class InstancedMesh {
return submeshes
}

setMaterial (value: ModelMaterial) {
if (this._material === value) return
if (this.ignoreSceneMaterial) return
this.mesh.material = value ?? this._material

// Update material groups
this.mesh.geometry.clearGroups()
if(value instanceof Array) {
value.forEach((m, i) => {
this.mesh.geometry.addGroup(0, Infinity, i)
})
/**
* Sets the material for this mesh.
* Set to undefined to reset to original materials.
*/
setMaterial(value: ModelMaterial) {
if (this.ignoreSceneMaterial) return;

const base = this._material; // always defined
let mat: ModelMaterial;

if (Array.isArray(value)) {
mat = this._mergeMaterials(value, base);
} else {
mat = value ?? base;
}

// Apply it
this.mesh.material = mat;

// Update groups
this.mesh.geometry.clearGroups();
if (Array.isArray(mat)) {
mat.forEach((_m, i) => {
this.mesh.geometry.addGroup(0, Infinity, i);
});
}
}

private _mergeMaterials(
value: THREE.Material[],
base: ModelMaterial
): THREE.Material[] {
const baseArr = Array.isArray(base) ? base : [base];
const result: THREE.Material[] = [];

for (const v of value) {
if (v === undefined) {
result.push(...baseArr);
} else {
result.push(v);
}
}

return result;
}
}

private computeBoundingBoxes () {
this.mesh.geometry.computeBoundingBox()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export class Marker implements IVimElement {
return this._submesh.index
}

get isRoom(): boolean {
return false
}

private _outlineAttribute: WebglAttribute<boolean>
private _visibleAttribute: WebglAttribute<boolean>
private _coloredAttribute: WebglAttribute<boolean>
Expand Down
10 changes: 9 additions & 1 deletion src/vim-web/core-viewers/webgl/viewer/rendering/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,22 @@ export class Renderer implements IRenderer {
this.needsUpdate = true
}

/**
* Sets the material used to render models. If set to undefined, the default model or mesh material is used.
*/
get modelMaterial () {
return this._scene.modelMaterial
}

set modelMaterial (material: ModelMaterial) {
this._scene.modelMaterial = material
this._scene.modelMaterial = material ?? this.defaultModelMaterial
}

/**
* The material that will be used when setting model material to undefined.
*/
defaultModelMaterial: ModelMaterial

/**
* Signal dispatched at the end of each frame if the scene was updated, such as visibility changes.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/vim-web/core-viewers/webgl/viewer/viewport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ export class Viewport {
/**
* Resizes the canvas and updates the camera to match new parent dimensions.
*/
ResizeToParent () {
resizeToParent () {
this._onResize.dispatch()
}

Expand Down
Loading