Comments (2)
Physics engines have a notion of a Renderer, in our case we are only concerned with DOM Renderer at the moment. We first approached this design for web worker thinking that we need to tun Renderer on a main thread and Physics engine on the web worker. But this notion was too simplistic. Note that Sliding window component below. It supposedly belongs to the Renderer, as it controls which objects are added or removed from DOM, but it can do all its calculations on web worker. Same with the Layout Manager, which probably corresponds best to a Scene manager in typical Physics engines.
So we ended up with the following architecture:
Web worker thread runs code for:
- Physics simulation. A physics engine (PhysicsJS now, with more like p2.js to follow) is used to make HTML5 objects (otherwise called bricks, tiles or bodies) move realistically by simulating physical forces with temporal aliasing to adjust for highly fluctuating frame rate on mobiles.
- Layout. Urbini uses a hybrid layout model. We let browser lay out inside the bricks, but we use JS layout manager, like a modified masonry.js to lay out the bricks on the page. The advantage of this model is that a brick is represented by a separate GPU bitmap and JS code can control its movements in 3D by setting brick's style.transform to a specific matrix3d. This proves to work really fast.
- Sliding window. Browser can only efficiently handle DOM with the small amount of elements. The goal of the sliding window is to keep in DOM only things that might be viewed by the user soon (determined by screen size, scroll speed, direction, etc.). Specifically for scrolling this means adding objects to the DOM in the direction of the scroll and removing them from the opposite side of the DOM. This technique seems to be a 2D equivalent of frustum culling used in 3D games, e.g. a new mobile WebGL game Hobbit Experience, which used culling algo from three.js. To better understand the role of a sliding window component in overall architecture, note that we discussed its implementation based on camera. To provide bouncing at the edges of content, camera would need to be a point object itself. @TomWHall even implemented camera in PhysicsJS based on issue we opened. But this approach did not work for us as PhysicsJS at the moment has no mechanism that would tell DOM Renderer what world objects are outside of the viewport and can be thus culled.
There is a message passing mechanism between worker and the main thread.
Mark, could you document it so that we could help Stefan and Jasper figure out how to reflect that better into their engines.
from urbini.
I'm not sure how @wellcaffeinated planned to use the web worker, the way we use it may not be quite generic enough for inclusion in the PhysicsJS library. Currently we have the whole physics engine in the worker. The main thread wouldn't know mass from acceleration if an apple fell on its head.
There are/were a few considerations:
- Everything that goes through the worker is async.
Originally I wanted the worker to be as stupid as possible, so that the main thread could use virtually the same API to the physics engine as if the engine ran in the main thread. The async nature of the worker helped me abandon this idea, but I revisit it in my dreams occasionally. Instead we added ids to bodies (and may add them in the future to other objects), so that if the main thread wants to refer to a body/constraint/behavior/etc., it has a handle on it after instantiation. Many methods on the worker side simply convert from id to PhysicsJS entity and then call the intended PhysicsJS method on it. - Clock.
This is an issue that's still up for debate (and performance testing). Currently we don't run a synchronized clock between the worker and the main thread. The worker runs its own ticker and ticks away constantly (until @wellcaffienated gives us a fall-asleep-when-idle function), and the main thread basically just sits there and waits for updates. When it gets updates, it queues them up for consumption via requestAnimationFrame. This way the main thread's idle most of the time, unless something is happening on the screen. We also added a rendering resolution option to the PhysicsJS engine so we wouldn't re-render on changes less than a pixel (for example). - Layout vs rendering (DOM only for now).
We wanted to free up the main thread as much as possible, so the worker runs all the physics and sends just the CSS transforms to the main thread. In the worker, we have a layout manager which is a port of jquery.masonry by @desandro. We decided that masonry suited most of our layout needs, and that eventually every page could be laid out as masonry, if a trivial one in most cases. The main thread appends elements to the DOM, sends their dimensions to the worker, the worker lays them out and keeps track of their positions and sends the latest CSS transforms to the main thread when it decides there's something render-worthy. The sliding window that @urbien brought up is also essentially a part of the layout manager. It does however require more coordination with the main thread. It has its own simple API directed from the worker to the main thread, something along the lines of "give me more bricks," and "I removed these bricks." - Synchronized representation.
Our main thread has a MutationObserver on all bodies whose size it cares about for the purposes of updating/fixing the masonry in realtime. Each masonry instance is bounded, but those bounds can and do change dynamically. For example, an accordion widget changes the container's size with the user's every choice. In order to snap to bounds accurately, the worker needs to get updates about the new sizes of its masonry containers.
from urbini.
Related Issues (12)
- optimize speed and size by supporting Closure's advanced optimizations
- simulating 3D planes with 2D physics engine
- font smoothing is absent in firefox
- The layout in different in safari and chrome HOT 1
- yuicompressor is deprecated, minify css using cssmin, csso or some other tool
- what is the best way to model scroll edge bounce with physics engine HOT 3
- employ physics engine that supports variable framerate HOT 2
- model the fixed, animated toolbar/navbar in physics
- how should the time be synchronized between the main thread (renderer) and the webworker (world)?
- is it possible to model a sliding window with physics?
- model page transitions in physics
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from urbini.