Object4D - Adding native animation to THREE.js

Tuesday, December 17, 2013 Posted by Josh Staples 0 comments
In some of my development, I've had to figure out a way to animate a number of different kind of objects synchronously between geospatial locations.  Additionally, I have to sometimes stop, redirect or delete a mesh.

In other words, PubSub animation for THREE.js.

DEMO of Object4D

GitHub Code

Initially I tried TWEEN.js but quickly found that it didn't provide the kind of micro-control I needed in my objects.  In lieu of TWEEN.js, I ended up creating a dozen or so animation objects for each kind of mesh I had to animate.   After creating these classes, I quickly realized they were all essentially the same and I could easily extend the THREE.Object3D class and create a new one called Object4D.

Here is what Object4D looks like:

After creating an Object4D object, I also created a manager for the animated objects.  The manager passes a clock delta to each object between frame renders.   Each Object4D element updates it's own position based upon the latter clock delta, it's speed, movement vector and target location.   In essence, these objects are self-tweening.   Unlike many tweening approaches, you can easily stop or interrupt the animation and even re-direct the target movement mid-tween.   The demo above demonstrates this behaviour.  Here is a Gist of the manager class:

In short, it works great for my purposes and I think it is pretty clever to extend the base Object3D class.   Additionally, it makes it really easy to extend the animation functionality just by modifying the base Object4D class.

Cached Marquee Selection with THREE.js

Thursday, December 5, 2013 Posted by Josh Staples 0 comments
In my previous post on marquee selection I demonstrated how to marquee select a bunch of elements within a WebGL canvas using THREE.js.  While the approach works great, once you start loading a larger number of meshes into the scene, the approach slows to a crawl.

To resolve this slowdown, I created a caching object that takes all unprojected 3D coordinates and associated meshes and throws them into an array.   This allows us to circumvent gobs of math and processing required to unproject rays and do a comparison during each mouse event.  Using this approach, the cache is created on the first mousemove event (you could pre-create it as well) and subsequently used in all future mousemove events until the "dirty" flag is set.

The speedup is incredible.   Easily 1000 cubes in real time.   If you bump that up to 10,000 cubes, disabled cache use is impossible and there is only a slight lag on the marquee selection with the cache enabled.

One MAJOR caveat:
  • If the camera moves, the cache is worthless.  You'll need to recreate it.
In that regard, I added a "dirty" flag so when the camera does move you can tell the cache and it will re-create the cache on the first mousemove event.   I haven't experimented too much with a moving camera (my current work's 3D environment is pretty static) but it should still provide a pretty good speedup even within a dynamic scene.

FYI, I also included an "active" flag in the cache.   This was included so you can turn the cache on and off from the browser.

Here is a demo

Here is a Gist of the Cache object:

3D Tic-Tac-Toe with Ray Intersection via THREE.js

Wednesday, December 4, 2013 Posted by Josh Staples 0 comments
I have wanted to create a 3D tic-tac-toe game for years but was always put out by my ham-fisted approach to determining a winner. When resolving an issue at work the other day I realized I could put together a cool demo using rays and the raycaster object of THREE.js. See the demo here:  3D Tic-Tac-Toe Demo

3D tic tac toe using rays
While click interactions with THREE.js are old-hat by now, I thought it would be interesting to use rays and intersections to determine the winner.

In short I've created 49 rays that are checked after each user cube selection.  In my demo, I also created THREE.js ArrowHelpers to demonstrate the ray placement.  Here is a Gist showing the ray creation:

After setting up all the rays, the last step was to loop through an array of the rays and inspect each ray's individual collisions. If every intersected object has been selected by a single user, a winner is declared and the game is over.    Please note that intersected objects are not Object3D meshes but rather the faces of each individual mesh. In other words, we aren't looking for 3 sequential user intersections but rather twice that number.

The code is pretty modular and wouldn't take much work to make this demo work for  a 4x4x4 or NxNxN tic-tac-toe grid.   Feel free to check out the code at Github.