Skip to main content

Object Selection

Novorender's Web API lets you highlight sets of objects. This could be used to visualize current object selection, or groups of objects, for instance the results of data queries.

Object Identity

All the objects in a scene are enumerated and assigned a unique integer id/index, expressed as PickSample.objectid.

One way of obtaining such an id is using the View.pick function, which lets you pick the frontmost object, if any, at the given x,y canvas coordinate.

const result = await view.pick(x, y);
if (result) {
const { objectId } = result;
}

Try clicking on the model to see what id the sub-object under the cursor has.

Object highlighting

Now that we've learned the object id, let's give the user better visual feedback. To highlight the picked object, we first must create a highlight object. For now, we'll simply go for lime green.

const highlightLimeGreen = createColorSetHighlight([0, 1, 0]); // make highlighted objects lime green

This highlight is actually a 5x4 transformation matrix used to perform a linear transform of the red, green, blue and alpha (opacity) channels. See RGBATransform for more details. While you can make this manually for full control, we've provided some helper functions for common transformations:

Object highlight groups

Quite often we want to highlight more than one object using the same color transformation. Enter highlight groups:

const myHighlightGroup = {
action: highlightLimeGreen, // highlight action
objectIds: [objectId], // objects to highlight
};

You can have several groups, up to 250, each with it's own action.

const groups = [myHighlightGroup];
info

If object ids overlap in two or more groups, the overlapping objects will be highlighted by the last group's action only!

Now let's see what this looks like. We picked object 2 and 2221, which happens to be the ground and roof in this particular scene. Feel free to try any other number, or combinations of numbers. You can use the pick example above to find out what id objects have.

Default action

Quite often it can be useful to apply a highlight action to all the objects that are not in a highlight group. Let's try to make everything not in a group semi-transparent by default!

return {
highlights: {
defaultAction: semiTransparent, // applies to all objects not in a group.
},
};
info

By default, the defaultAction is set to createNeutralHighlight, which will leave all colors unchanged.

Hide and filter

In addition to a color/transparency transform, the highlight RenderStateGroupAction also lets you hide or filter objects. While you can also effectively hide objects by making them 100% transparent, using the hide action is more efficient. filter will remove the objects from memory entirely, which can greatly improve rendering performance and reduce memory footprint if applied to the majority of objects.

return {
highlights: {
defaultAction: "hide", // hide all objects not in a group.
},
};
note

Changing any of the groups using the filter action will force a reload of the scene, which can take some time. We recommend you use this action only for groups that are relatively static.

Advanced highlights

It's rarely a good idea to simply replace the default material color as the chosen highlight color may clash with other materials. To avoid color clashes while retaining some of the original colors, you can apply the following techniques:

RGBA transform

In this example we apply a blue'ish hue with linear transformations, i.e. let v' = v * scale + offset:

const makeBlueish = createRGBATransformHighlight({
red: { scale: 0.5, offset: 0.25 }, // reduce contrast and brightness
green: { scale: 0.5, offset: 0.25 }, // reduce contrast and brightness
blue: { scale: 1, offset: 0.5 }, // boost blue
});

Hue, lightness and saturation transform

Here we darken and reduce color saturation for a dim, gray'ish effect:

const dimGrayish = createHSLATransformHighlight({
lightness: 0.5, // darken
saturation: 0.5, // reduce color saturation
});

By applying a combination of these effects on groups, and/or by default, you can make your selection stand out in many ways. Of course, you can also make your own linear transform matrix for even more flexibility. Feel free to inspect the source code of the existing helper functions for inspiration!

Putting it all together

Now let's try to interactively highlight the object you click on by combining object picking and object highlighting.

caution

Large scenes can have millions of objects. For large sets of object id's, we recommend you use Uint32Array to reduce memory consumption. You may also want to download active groups on demand to make your app super-scalable, particularly on mobile devices.