Skip to content

Commit

Permalink
Merge branch 'minimap' into 'main'
Browse files Browse the repository at this point in the history
Bachelorprojekt Minimap Baumann

See merge request ExplorViz/code/frontend!218
  • Loading branch information
Malte-Hansen committed Nov 18, 2024
2 parents 82dac81 + 3391932 commit ffdcbf3
Show file tree
Hide file tree
Showing 27 changed files with 1,031 additions and 46 deletions.
2 changes: 1 addition & 1 deletion .dev/.env
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
SPAN_PORT=8083
USER_PORT=8084
COLLABORATION_PORT=4444
COLLABORATION_PORT=4444
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import LocalUser from 'collaboration/services/local-user';
import MessageSender from 'collaboration/services/message-sender';
import RoomSerializer from 'collaboration/services/room-serializer';
import PopupData from '../../../../rendering/popups/popup-data';
import MinimapService from 'explorviz-frontend/services/minimap-service';
import SceneRepository from 'explorviz-frontend/services/repos/scene-repository';
import { Mesh } from 'three';

Expand Down Expand Up @@ -53,6 +54,9 @@ export default class Settings extends Component<Args> {
@service('user-settings')
private userSettings!: UserSettings;

@service('minimap-service')
private minimapService!: MinimapService;

colorSchemes: { name: string; id: ColorSchemeId }[] = [
{ name: 'Default', id: 'default' },
{ name: 'Classic (Initial)', id: 'classic' },
Expand All @@ -68,6 +72,7 @@ export default class Settings extends Component<Args> {
ApplicationSettingId[]
> = {
Camera: [],
Minimap: [],
Colors: [],
Controls: [],
Communication: [],
Expand Down Expand Up @@ -141,6 +146,9 @@ export default class Settings extends Component<Args> {
this.userSettings.applicationSettings.cameraFov.value;
this.localUser.defaultCamera.updateProjectionMatrix();
break;
case 'zoom':
this.minimapService.updateSphereRadius();
break;
default:
break;
}
Expand Down Expand Up @@ -176,12 +184,40 @@ export default class Settings extends Component<Args> {

@action
updateFlagSetting(name: ApplicationSettingId, value: boolean) {
const settingId = name as ApplicationSettingId;
const settingId = name;
const settingString = settingId as string;
try {
this.userSettings.updateApplicationSetting(settingId, value);
} catch (e) {
this.toastHandlerService.showErrorToastMessage(e.message);
}
if (settingString.startsWith('layer')) {
const layerNumber = parseInt(settingString.slice(5), 10); // Extract the layer number from settingId
if (!isNaN(layerNumber)) {
// Ensure it's a valid number
if (value || value === undefined) {
this.localUser.minimapCamera.layers.enable(layerNumber);
} else {
this.localUser.minimapCamera.layers.disable(layerNumber);
}
}
} else {
switch (settingId) {
case 'applyHighlightingOnHover':
if (this.args.updateHighlighting) {
this.args.updateHighlighting();
}
break;
case 'enableGamepadControls':
this.args.setGamepadSupport(value);
break;
case 'minimap':
this.minimapService.minimapEnabled = value;
break;
default:
break;
}
}

const scene = this.sceneRepo.getScene();
const directionalLight = scene.getObjectByName('DirectionalLight');
Expand Down
45 changes: 32 additions & 13 deletions app/components/visualization/rendering/browser-rendering.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ import { Class } from 'explorviz-frontend/utils/landscape-schemes/structure-data
import ApplicationObject3D from 'explorviz-frontend/view-objects/3d/application/application-object-3d';
import ComponentMesh from 'explorviz-frontend/view-objects/3d/application/component-mesh';
import FoundationMesh from 'explorviz-frontend/view-objects/3d/application/foundation-mesh';
import HeatmapConfiguration from 'heatmap/services/heatmap-configuration';
import { Vector3 } from 'three';
import * as THREE from 'three';
import { MapControls } from 'three/examples/jsm/controls/MapControls';
import SpectateUser from 'collaboration/services/spectate-user';
import {
Expand All @@ -42,14 +45,12 @@ import { removeAllHighlightingFor } from 'explorviz-frontend/utils/application-r
import LinkRenderer from 'explorviz-frontend/services/link-renderer';
import SceneRepository from 'explorviz-frontend/services/repos/scene-repository';
import RoomSerializer from 'collaboration/services/room-serializer';
import HeatmapConfiguration from 'explorviz-frontend/services/heatmap-configuration';
import ThreeForceGraph from 'three-forcegraph';
import { Vector3 } from 'three/src/math/Vector3';
import * as THREE from 'three';
import AnnotationHandlerService from 'explorviz-frontend/services/annotation-handler';
import { SnapshotToken } from 'explorviz-frontend/services/snapshot-token';
import Auth from 'explorviz-frontend/services/auth';
import GamepadControls from 'explorviz-frontend/utils/controls/gamepad/gamepad-controls';
import MinimapService from 'explorviz-frontend/services/minimap-service';
import Raycaster from 'explorviz-frontend/utils/raycaster';
import PopupData from './popups/popup-data';

interface BrowserRenderingArgs {
Expand Down Expand Up @@ -104,6 +105,9 @@ export default class BrowserRendering extends Component<BrowserRenderingArgs> {
@service('repos/scene-repository')
sceneRepo!: SceneRepository;

@service('minimap-service')
minimapService!: MinimapService;

@service('annotation-handler')
annotationHandler!: AnnotationHandlerService;

Expand All @@ -115,7 +119,7 @@ export default class BrowserRendering extends Component<BrowserRenderingArgs> {
private ideCrossCommunication: IdeCrossCommunication;

@tracked
readonly graph: ThreeForceGraph;
readonly graph: ForceGraph;

@tracked
readonly scene: THREE.Scene;
Expand Down Expand Up @@ -178,16 +182,19 @@ export default class BrowserRendering extends Component<BrowserRenderingArgs> {

// Force graph
const forceGraph = new ForceGraph(getOwner(this), 0.02);
this.graph = forceGraph.graph;
this.graph = forceGraph;
this.scene.add(forceGraph.graph);
this.updatables.push(forceGraph);
this.updatables.push(this);

// Spectate
this.updatables.push(this.spectateUserService);

// Minimap
this.updatables.push(this.minimapService);

this.popupHandler = new PopupHandler(getOwner(this));
this.applicationRenderer.forceGraph = this.graph;
this.applicationRenderer.forceGraph = this.graph.graph;

// IDE Websocket
this.ideWebsocket = new IdeWebsocket(
Expand All @@ -208,7 +215,6 @@ export default class BrowserRendering extends Component<BrowserRenderingArgs> {
this.collaborationSession.idToRemoteUser.forEach((remoteUser) => {
remoteUser.update(delta);
});

if (this.initDone && this.linkRenderer.flag) {
this.linkRenderer.flag = false;
}
Expand Down Expand Up @@ -337,9 +343,21 @@ export default class BrowserRendering extends Component<BrowserRenderingArgs> {
this.canvas
);
this.spectateUserService.cameraControls = this.cameraControls;

this.localUser.cameraControls = this.cameraControls;
this.updatables.push(this.localUser);
this.updatables.push(this.cameraControls);

// initialize minimap
this.minimapService.initializeMinimap(
this.scene,
this.graph,
this.cameraControls
);

this.minimapService.raycaster = new Raycaster(
this.localUser.minimapCamera,
this.minimapService
);
}

/**
Expand All @@ -357,6 +375,7 @@ export default class BrowserRendering extends Component<BrowserRenderingArgs> {
this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
this.renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
this.renderer.setSize(width, height);
this.debug('Renderer set up');

this.renderingLoop = new RenderingLoop(getOwner(this), {
camera: this.camera,
Expand All @@ -368,8 +387,8 @@ export default class BrowserRendering extends Component<BrowserRenderingArgs> {

// if snapshot is loaded, set the camera position of the saved camera position of the snapshot
if (this.args.snapshot || this.args.snapshotReload) {
this.graph.onFinishUpdate(() => {
if (!this.initDone && this.graph.graphData().nodes.length > 0) {
this.graph.graph.onFinishUpdate(() => {
if (!this.initDone && this.graph.graph.graphData().nodes.length > 0) {
this.debug('initdone!');
setTimeout(() => {
this.applicationRenderer.getOpenApplications();
Expand All @@ -378,8 +397,8 @@ export default class BrowserRendering extends Component<BrowserRenderingArgs> {
}
});
} else {
this.graph.onFinishUpdate(() => {
if (!this.initDone && this.graph.graphData().nodes.length > 0) {
this.graph.graph.onFinishUpdate(() => {
if (!this.initDone && this.graph.graph.graphData().nodes.length > 0) {
this.debug('initdone!');
setTimeout(() => {
this.cameraControls.resetCameraFocusOn(
Expand Down
88 changes: 81 additions & 7 deletions app/modifiers/interaction-modifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import { action } from '@ember/object';
import { inject as service } from '@ember/service';
import CollaborationSession from 'collaboration/services/collaboration-session';
import LocalUser from 'collaboration/services/local-user';
import RemoteUser from 'collaboration/utils/remote-user';
import debugLogger from 'ember-debug-logger';
import Modifier, { ArgsFor } from 'ember-modifier';
import MinimapService from 'explorviz-frontend/services/minimap-service';
import UserSettings from 'explorviz-frontend/services/user-settings';
import Raycaster from 'explorviz-frontend/utils/raycaster';
import { Object3D, Vector2 } from 'three';
Expand Down Expand Up @@ -86,6 +88,9 @@ export default class InteractionModifierModifier extends Modifier<InteractionMod
@service('user-settings')
userSettings!: UserSettings;

@service('minimap-service')
minimapService!: MinimapService;

isMouseOnCanvas = false;

pointer = new THREE.Vector2();
Expand Down Expand Up @@ -157,7 +162,7 @@ export default class InteractionModifierModifier extends Modifier<InteractionMod

constructor(owner: any, args: ArgsFor<InteractionModifierArgs>) {
super(owner, args);
this.raycaster = new Raycaster();
this.raycaster = new Raycaster(this.localUser.minimapCamera);
}

@action
Expand Down Expand Up @@ -225,9 +230,15 @@ export default class InteractionModifierModifier extends Modifier<InteractionMod
this.onTouchMove(event);
} else if (this.pointers.length === 1) {
this.handleMouseMovePan(event);
} else if (this.minimapService.makeFullsizeMinimap) {
const intersectedViewObj = this.minimapService.raycastForObjects(
event,
this.localUser.minimapCamera,
this.raycastObjects
);
this.namedArgs.mouseMove?.(intersectedViewObj, event);
} else {
const intersectedViewObj = this.raycast(event);

this.namedArgs.mouseMove?.(intersectedViewObj, event);
}
}
Expand Down Expand Up @@ -296,6 +307,29 @@ export default class InteractionModifierModifier extends Modifier<InteractionMod
event: MouseEvent,
intersectedViewObj: THREE.Intersection | null
) {
// check for click on Minimap
let intersectedViewObjectCopy = intersectedViewObj;
const isOnMinimap = this.minimapService.isClickInsideMinimap(event);
const rayMarkers = this.minimapService.raycastForMarkers(event);
// if rayMarkers are present, it means that the click was on a marker
if (rayMarkers) {
this.handleMinimapOnLeftClick(isOnMinimap, rayMarkers);
return;
} else if (this.minimapService.makeFullsizeMinimap && isOnMinimap) {
const rayObjects = this.minimapService.raycastForObjects(
event,
this.localUser.minimapCamera,
this.raycastObjects
);

intersectedViewObjectCopy = rayObjects;
} else if (this.minimapService.makeFullsizeMinimap && !isOnMinimap) {
this.minimapService.toggleFullsizeMinimap(false);
return;
} else if (isOnMinimap) {
this.handleMinimapOnLeftClick(isOnMinimap, rayMarkers);
return;
}
// Treat shift + single click as double click
if (event.shiftKey) {
this.onDoubleClick(event);
Expand All @@ -308,7 +342,7 @@ export default class InteractionModifierModifier extends Modifier<InteractionMod
this.latestSingleClickTimestamp = event.timeStamp;
this.timer = setTimeout(() => {
this.mouseClickCounter = 0;
this.namedArgs.singleClick?.(intersectedViewObj);
this.namedArgs.singleClick?.(intersectedViewObjectCopy);
}, this.DOUBLE_CLICK_TIME_MS);
}

Expand All @@ -317,6 +351,42 @@ export default class InteractionModifierModifier extends Modifier<InteractionMod
this.onDoubleClick(event);
}
}
/**
* Handler Function if the click was on the minimap
* @param isOnMinimap indicates if the click was on the minimap
* @param ray indicates the object that was hit by the ray
*/
private handleMinimapOnLeftClick(
isOnMinimap: boolean,
ray: THREE.Intersection | null
) {
if (this.minimapService.makeFullsizeMinimap && !isOnMinimap) {
this.minimapService.toggleFullsizeMinimap(false);
} else if (isOnMinimap) {
if (ray) {
this.minimapService.handleHit(
this.collaborativeSession.getUserById(ray.object.name) as RemoteUser
);
} else {
this.minimapService.toggleFullsizeMinimap(true);
}
}
}
/**
* Handler Function for double click on minimap
* @param event Mouse event of the click
* @returns The object that was hit by the ray
*/
private handleMinimapDoubleClick(event: MouseEvent) {
if (this.minimapService.isClickInsideMinimap(event)) {
return this.minimapService.raycastForObjects(
event,
this.localUser.minimapCamera,
this.raycastObjects
);
}
return null;
}

@action
ping(intersectedViewObj: THREE.Intersection | null) {
Expand All @@ -329,9 +399,14 @@ export default class InteractionModifierModifier extends Modifier<InteractionMod
onDoubleClick(event: MouseEvent) {
clearTimeout(this.timer);

const intersectedViewObj = this.raycast(event);
if (intersectedViewObj) {
this.namedArgs.doubleClick?.(intersectedViewObj);
const minimapViewObj = this.handleMinimapDoubleClick(event);
if (minimapViewObj) {
this.namedArgs.doubleClick?.(minimapViewObj);
} else {
const intersectedViewObj = this.raycast(event);
if (intersectedViewObj) {
this.namedArgs.doubleClick?.(intersectedViewObj);
}
}
}

Expand All @@ -348,7 +423,6 @@ export default class InteractionModifierModifier extends Modifier<InteractionMod
this.raycastObjects instanceof Object3D
? [this.raycastObjects]
: this.raycastObjects;

return this.raycaster.raycasting(origin, this.camera, possibleObjects);
}

Expand Down
2 changes: 1 addition & 1 deletion app/modifiers/landscape-data-watcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export default class LandscapeDataWatcherModifier extends Modifier<Args> {
{ landscapeData, graph }: any
) {
this.landscapeData = landscapeData;
this.graph = graph;
this.graph = graph.graph;
this.handleUpdatedLandscapeData.perform();
}

Expand Down
Loading

0 comments on commit ffdcbf3

Please sign in to comment.