forked from visgl/deck.gl
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update controller-architecture-rfc.md
- Loading branch information
Showing
1 changed file
with
91 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,52 +1,121 @@ | ||
# RFC: Controller Architecture | ||
|
||
* **Authors**: Ib Green, ... | ||
* **Date**: Aug 2017 | ||
* **Date**: Sep 2017 | ||
* **Status**: Placeholder | ||
|
||
|
||
## Motivation | ||
|
||
* In deckgl v4.0 we introduced non-geospatial (orbit) controllers and viewports | ||
* For deck.gl v5.0 we started working on **first person controllers** and **first person viewports**, and we are also introducing a **multiviewport** architecture, and **viewport animation**. | ||
Enabling applications to easily compose and switch between multiple viewports and multiple controllers. | ||
|
||
The combination of various viewports in a single render, feeding them off the same "map" state data opens questions about controllers. | ||
## Idea | ||
|
||
The ability to have all `Controller` classes work on a common `ViewState` class, defining different interaction modes. | ||
|
||
## Details | ||
``` | ||
MapController \ / WebMercatorViewport | ||
\ / | ||
FirstPersonController --- ViewState --- FirstPersonViewport => Viewport => uniforms | ||
/ \ | ||
OrbitController / \ ThirdPersonViewport | ||
``` | ||
|
||
A critical step in this development was the decision to [geospatially enable all viewports](first-person-mercator-viewport-rfc.md). This unifies the API and capabilities of the various `Viewport` subclasses to a significant extent, in that they can all accept (optionally) a geospatial "anchor" or reference point, and on top of that a "meter" offset linear coordinate system. | ||
This can be seen as the "inverse" of the recently introduced ability to feed of various viewports off the same "map" state. | ||
|
||
|
||
## Background | ||
|
||
A critical step in recent deck.gl development was the Viewport unification resulting from [geospatially enabling all viewports](first-person-mercator-viewport-rfc.md). This unifies the API and capabilities of the various `Viewport` subclasses to a significant extent, in that they can all accept (optionally) a geospatial "anchor" or reference point, and on top of that a "meter" offset linear coordinate system. | ||
|
||
# Proposal | ||
This proposal wants to do a similar unification for `Controllers` | ||
|
||
* Unify the "map state" requirements so that all viewports can take all map states as parameters (some viewports may not be able to interpret all data in a specific State subclass, but it will still be able to show something "reasonable"). | ||
|
||
* Make all viewports work with a basic map state specification. | ||
# Proposal - a new `ViewState` class | ||
|
||
* Unify the "map state"/"controller state" requirements so that all controllers can take all states as parameters (just like with viewports, some controllers may not be able to interpret all `ViewState` data, but it will still be able to control something "reasonable"). | ||
|
||
TBD exact properties: | ||
* geospatial anchor: lng/lat + zoom... (optional) | ||
* position (meter offsets) | ||
* direction (angles and distance/vector) | ||
|
||
## Additional Work: Event Handling | ||
ViewState will need to offer different interfaces (bearing/pitch, and direction - already supported by math.gl classes). | ||
|
||
While the initial use of FirstPersonViewports will be to have them attached to other objects in the geometry, we will soon need "controllers" for these Viewports. | ||
|
||
What is the best way to pan (effectively, move around) when viewing at 90 degrees pitch. | ||
* Do we want a command-mouse drag [THREE.js pointer-lock controls](https://threejs.org/examples/misc_controls_pointerlock.html) | ||
* Should we provide a classic keyboard interface (arrow keys)? | ||
### Switching Controllers | ||
|
||
One could imagine the application to switch both controllers and viewport classes when switching between "modes". This will become trivially easy once we have a common `ViewState` class. | ||
|
||
### Switching between modes. | ||
|
||
One could imagine asking the application to switch both event controllers and viewport classes when switching between modes. This would keep the Viewports cleaner but make integration harder for the app. | ||
### Multiple Controllers | ||
|
||
The separation between Viewports / State / Controls / React Controllers is powerful but could perhaps be streamlined. A couple of preparatory PRs have reduced the amount of duplicated code, to simplify work in this area. | ||
In a scenario where the application has multiple viewports, it would be nice to be able to mouse/touch interact with each viewport separately. | ||
|
||
## Open Issues and Discussion Points | ||
* mouse capture - should be handled by mjolnir.js... | ||
* keyboard input - do we allow more than one? do we offer a prop to set focus? | ||
|
||
* `modelMatrix`: Allows the application to apply a modelMatrix that transforms both the position and the direction of the camera. Should this be part of the camera | ||
* meterOffset? - it might convenient to allow the camera to be moved around using meter offsets compared to a lngLat anchor rather than having to recalculate lngLats on every mode. | ||
- project/unproject - Pixel project/unproject to flat mercator coordinates may not work when pitch exceeds > 85 degrees. | ||
* VR view matrices - can support for left and right eye matrices be integrated somehow? | ||
Controller input areas can be matched to viewports in the same way that the deck.gl component resizes its children using `viewportId` props. | ||
|
||
|
||
### Multiple View States | ||
|
||
|
||
### Animation Integration | ||
|
||
* Viewport animation control. The controller architecture needs to be unified with the animation support that is currently in development. | ||
|
||
|
||
### React Controllers | ||
|
||
Per the direction to make deck.gl usable without React, React controllers will be minimal wrappers over ES6 | ||
|
||
|
||
### Interface | ||
|
||
To keep the API simple, we want to keep the interface as props to the DeckGL component | ||
``` | ||
constructor(props) { | ||
... | ||
this.state = { | ||
viewState1: new ViewState(...), | ||
viewState2: new ViewState(...), | ||
} | ||
} | ||
// onViewportChanged will be supported for backwards compat | ||
onViewStateChanged(viewState) { | ||
if (viewState.id === 'firstPerson') { | ||
this.setState(state1: viewState); | ||
} ... | ||
} | ||
render() { | ||
const {viewState1, viewState2} = this.props; | ||
const controllers = { | ||
new MapController(viewState1), | ||
new FirstPersonController(viewState1), // Controls same view as above | ||
new FirstPersonController(viewState2) // Controls a different view | ||
}; | ||
const Viewports = { | ||
new WebMercatorViewport(viewState1), | ||
new FirstPersonViewport(viewState1), // Controls same view as above | ||
new FirstPersonViewport(viewState2) // Controls a different view | ||
} | ||
<DeckGL controllers={controllers} viewports={viewports} layers={[]}> | ||
<StaticMap /> | ||
</DeckGL> | ||
} | ||
``` | ||
|
||
|
||
Remarks: | ||
* A limitation of putting the controllers inside the DeckGL component is animation, as it only affects react components that are children of deck.gl. If some part of the UI outside of DeckGL wanted to update by animation, it would either not work, or a flash would be visible as the DeckGL component fails to intercept the first changed value. | ||
|
||
|
||
|
||
### Remaining Work | ||
|
||
The separation between Viewports / State / Controls / React Controllers is very demanding. A long line of preparatory PRs have reduced the amount of duplicated code, to simplify work in this area. |