Annotations in xeogl
I recently made a Sketchfab-style annotation system for xeogl, a WebGL-based 3D engine
I’ve been working on.
An annotation is a label that you pin to the surface an entity. Click this screenshot for a demo:
The code below shows how to create an annotation. First, we’ll load our model:
Once the model has loaded, we’ll create an Annotation on one of its entities:
The annotation is pinned at the given barycentric coordinates within a triangle of its entity’s mesh (the Tank’s cannon). Whenever the entity is transformed or deformed, the annotation will always stick to that position on the surface of the entity. In the demo, this is demonstrated by the (A) annotation on our Tron Tank’s cannon, which will move wherever the cannon goes.
Camera vantage points
As we saw in the previous example, you can optionally specify a camera position from which to view the annotation, given as
up vectors. You can then fly the camera to look at the annotation by
passing the annotation to a CameraFlightAnimation:
Creating annotations by picking
I made annotations easy to create from pick results:
With this snippet, whenever we click on the surface of an entity, we’ll create an annotation at that point. We’ll also save the current camera position with the annotation, so that we can restore the camera to the vantage point that we created it from (see previous example).
The annotation system automatically hides annotations when they are occluded by other objects in the 3D view. You can see this in
the demo example, where the (C) annotation disappears while the cannon barrel moves over it.
The system uses a fast GPU-assisted occlusion technique which renders a small point at each annotation’s position, then determines the annotation to be occluded when the color of the point’s location on the canvas does not match the point. Since reading WebGL’s drawing buffer is expensive, the system performs this occlusion test for all annotations in a batch on every 10th frame or so. You’ll note a slight lag between when the annotation is occluded/revealed and hidden/shown.
This technique is much more efficient than the standard ray-casting approach for large meshes and number of objects.
Culling is enabled for an annotation by default, but you can disable it:
Annotations fire some events that you can subscribe to. Let’s make it so that when you click an annotation’s pin the camera will focus on the annotation and the label will open:
You can also track the annotation’s position in Local-space (coordinate space of entity’s geometry before modeling transformation) and World-space (after the modeling transform):
The Local position will change when the geometry is edited, while the World position will change when the geometry is edited and/or the modeling transform is updated.
Annotations manage their HTML elements internally, giving them hardcoded CSS class names. The rules for those classes are defined in annotation-style.css, so you can tweak that file if you want to customize the appearance of your annotations.
- The Annotation component class provides the means to pin labels on Entities that have triangle mesh Geometries.
- Since an annotation is pinned to a barycentric location with a its triangle, it can dynamically recalculate its Cartesian coordinates from the triangle vertices whenever the Entity is transformed or the Geometry is edited.
- An annotation can be configured with a camera vantage point from which to view it. This is useful for focusing the camera on the annotation, as part of a presentation.
- The annotation API makes it easy to create annotations from the results of picking operations.
- An Annotation will automatically hide itself when occluded by another object in the 3D view.
- You can customize the appearance of annotations by editing their CSS stylesheet.
- See the demo example to see annotations in action, click VIEW SOURCE so see the source code.
Thanks for reading!
comments powered by Disqus