- /**
- An **EdgeMaterial** is a {{#crossLink "Material"}}{{/crossLink}} that defines the appearance of attached
- {{#crossLink "Mesh"}}Meshes{{/crossLink}} when they are highlighted, selected or ghosted.
-
- ## Examples
-
- | <a href="../../examples/#effects_ghost"><img src="../../assets/images/screenshots/HighlightMaterial/teapot.png"></img></a> | <a href="../../examples/#effects_demo_housePlan"><img src="../../assets/images/screenshots/HighlightMaterial/house.png"></img></a> | <a href="../../examples/#effects_demo_gearbox"><img src="../../assets/images/screenshots/HighlightMaterial/gearbox.png"></img></a> | <a href="../../examples/#effects_demo_adam"><img src="../../assets/images/screenshots/HighlightMaterial/adam.png"></img></a>|
- |:------:|:------:|:----:|:-----:|:-----:|
- |[Example 1: Ghost effect](../../examples/#effects_ghost)|[Example 2: Ghost and highlight effects for architecture](../../examples/#effects_demo_housePlan)|[Example 3: Ghost and highlight effects for CAD](../../examples/#effects_demo_gearbox)| [Example 4: Ghost effect for CAD ](../../examples//#effects_demo_adam)|
-
- ## Overview
-
- * Ghost an {{#crossLink "Mesh"}}{{/crossLink}} by setting its {{#crossLink "Mesh/ghost:property"}}{{/crossLink}} property ````true````.
- * When ghosted, a Mesh's appearance is controlled by its EdgeMaterial.
- * An EdgeMaterial provides several preset configurations that you can set it to. Select a preset by setting {{#crossLink "EdgeMaterial/preset:property"}}{{/crossLink}} to the preset's ID. A map of available presets is provided in {{#crossLink "EdgeMaterial/presets:property"}}xeogl.EdgeMaterial.presets{{/crossLink}}.
- * By default, a Mesh uses the {{#crossLink "Scene"}}{{/crossLink}}'s global EdgeMaterials, but you can give each Mesh its own EdgeMaterial when you want to customize the effect per-Mesh.
- * Ghost all Meshes in a {{#crossLink "Model"}}{{/crossLink}} by setting the Model's {{#crossLink "Model/ghost:property"}}{{/crossLink}} property ````true````. Note that all Meshes in a Model have the Scene's global EdgeMaterial by default.
- * Modify the Scene's global EdgeMaterial to customize it.
-
- ## Usage
-
- * [Ghosting](#ghosting)
- * [Highlighting](#highlighting)
-
- ### Ghosting
-
- In the usage example below, we'll create a Mesh with a ghost effect applied to it. The Mesh gets its own EdgeMaterial for ghosting, and
- has its {{#crossLink "Mesh/ghost:property"}}{{/crossLink}} property set ````true```` to activate the effect.
-
- <a href="../../examples/#effects_ghost"><img src="../../assets/images/screenshots/HighlightMaterial/teapot.png"></img></a>
-
- ````javascript
- var mesh = new xeogl.Mesh({
- geometry: new xeogl.TeapotGeometry({
- edgeThreshold: 1
- }),
- material: new xeogl.PhongMaterial({
- diffuse: [0.2, 0.2, 1.0]
- }),
- edgeMaterial: new xeogl.EdgeMaterial({
- edges: true,
- edgeColor: [0.2, 1.0, 0.2],
- edgeAlpha: 1.0,
- edgeWidth: 2,
- vertices: true,
- vertexColor: [0.6, 1.0, 0.6],
- vertexAlpha: 1.0,
- vertexSize: 8,
- fill: true,
- fillColor: [0, 0, 0],
- fillAlpha: 0.7
- }),
- ghost: true
- });
- ````
-
- Note the **edgeThreshold** configuration on the {{#crossLink "Geometry"}}{{/crossLink}} we've created for our
- Mesh. Our EdgeMaterial is configured to draw a wireframe representation of the Geometry, which will have inner edges (ie. edges between
- adjacent co-planar triangles) removed for visual clarity. The ````edgeThreshold```` configuration indicates
- that, for this particular Geometry, an inner edge is one where the angle between the surface normals of adjacent triangles is not
- greater than ````5```` degrees. That's set to ````2```` by default, but we can override it to tweak the effect as needed for particular Geometries.
-
- Here's the example again, this time using the Scene's global EdgeMaterial by default. We'll also modify that EdgeMaterial
- to customize the effect.
-
- ````javascript
- var mesh = new xeogl.Mesh({
- geometry: new xeogl.TeapotGeometry({
- edgeThreshold: 5
- }),
- material: new xeogl.PhongMaterial({
- diffuse: [0.2, 0.2, 1.0]
- }),
- ghost: true
- });
-
- var edgeMaterial = mesh.scene.edgeMaterial;
-
- edgeMaterial.edges = true;
- edgeMaterial.edgeColor = [0.2, 1.0, 0.2];
- edgeMaterial.edgeAlpha = 1.0;
- edgeMaterial.edgeWidth = 2;
- ````
-
- ### Highlighting
-
- In the next example, we'll use a ghosting in conjunction with highlighting, to emphasise a couple of objects within
- a gearbox {{#crossLink "Model"}}{{/crossLink}}. We'll load the Model from glTF, then ghost all of its Meshes except for two gears, which we'll highlight instead. The ghosted
- Meshes have the Scene's global ghosting EdgeMaterial, which we'll modify. The highlighted Meshes also have the Scene's global highlighting EdgeMaterial, which we'll modify as well.
-
- <a href="../../examples/#effects_demo_gearbox"><img src="../../assets/images/screenshots/HighlightMaterial/gearbox.png"></img></a>
-
- ````javascript
- var model = new xeogl.GLTFModel({
- src: "models/gltf/gearbox_conical/scene.gltf",
- edgeThreshold: 10
- });
-
- model.on("loaded", function() {
-
- model.meshes["gearbox#77.0"].highlight = true;
- model.meshes["gearbox#79.0"].highlight = true;
-
- var edgeMaterial = model.scene.edgeMaterial;
-
- edgeMaterial.edgeColor = [0.4, 0.4, 1.6];
- edgeMaterial.edgeAlpha = 0.8;
- edgeMaterial.edgeWidth = 3;
-
- var highlightMaterial = model.scene.highlightMaterial;
-
- highlightMaterial.color = [1.0, 1.0, 1.0];
- highlightMaterial.alpha = 1.0;
- });
- ````
-
- ## Presets
-
- For convenience, an EdgeMaterial provides several preset configurations that you can set it to, which are provided in
- {{#crossLink "EdgeMaterial/presets:property"}}xeogl.EdgeMaterial.presets{{/crossLink}}:
-
- ````javascript
- var presets = xeogl.EdgeMaterial.presets;
- ````
-
- The presets look something like this:
-
- ````json
- {
- "default": {
- edgeColor: [0.2, 0.2, 0.2],
- edgeAlpha: 1.0,
- edgeWidth: 1
- },
-
- "sepia": {
- edgeColor: [0.45, 0.45, 0.41],
- edgeAlpha: 1.0,
- edgeWidth: 1
- },
-
- //...
- }
- ````
-
- Let's switch the Scene's global default EdgeMaterial over to the "sepia" preset used in <a href="/examples/#effects_demo_adam">Example 4: Ghost effect for CAD</a>.
-
- ````javascript
- scene.edgeMaterial.preset = "sepia";
- ````
-
- You can also just create an EdgeMaterial from a preset:
-
- ````javascript
- var mesh = new xeogl.Mesh({
- geometry: new xeogl.TeapotGeometry({
- edgeThreshold: 5
- }),
- material: new xeogl.PhongMaterial({
- diffuse: [0.2, 0.2, 1.0]
- }),
- edgeMaterial: new xeogl.EdgeMaterial({
- preset: "sepia"
- });
- ghost: true
- });
- ````
-
- Note that applying a preset just sets the EdgeMaterial's property values, which you are then free to modify afterwards.
-
- @class EdgeMaterial
- @module xeogl
- @submodule materials
- @constructor
- @extends Material
- @param [owner] {Component} Owner component. When destroyed, the owner will destroy this component as well. Creates this component within the default {{#crossLink "Scene"}}{{/crossLink}} when omitted.
- @param [cfg] {*} The EdgeMaterial configuration
- @param [cfg.id] {String} Optional ID, unique among all components in the parent {{#crossLink "Scene"}}Scene{{/crossLink}}, generated automatically when omitted.
- @param [cfg.meta=null] {String:Object} Metadata to attach to this EdgeMaterial.
-
- @param [cfg.edgeColor=[0.2,0.2,0.2]] {Array of Number} RGB color of ghost edges.
- @param [cfg.edgeAlpha=1.0] {Number} Transparency of ghost edges. A value of 0.0 indicates fully transparent, 1.0 is fully opaque.
- @param [cfg.edgeWidth=1] {Number} Width of ghost edges, in pixels.
-
- @param [cfg.preset] {String} Selects a preset EdgeMaterial configuration - see {{#crossLink "EdgeMaterial/preset:method"}}EdgeMaterial#preset(){{/crossLink}}.
- */
-
- import {Material} from './material.js';
- import {State} from '../renderer/state.js';
- import {componentClasses} from "./../componentClasses.js";
-
- const PRESETS = {
- "default": {
- edgeColor: [0.0, 0.0, 0.0],
- edgeAlpha: 1.0,
- edgeWidth: 1
- },
- "defaultWhiteBG": {
- edgeColor: [0.2, 0.2, 0.2],
- edgeAlpha: 1.0,
- edgeWidth: 1
- },
- "defaultLightBG": {
- edgeColor: [0.2, 0.2, 0.2],
- edgeAlpha: 1.0,
- edgeWidth: 1
- },
- "defaultDarkBG": {
- edgeColor: [0.5, 0.5, 0.5],
- edgeAlpha: 1.0,
- edgeWidth: 1
- }
- };
-
-
- const type = "xeogl.EdgeMaterial";
-
- class EdgeMaterial extends Material {
-
- /**
- Available EdgeMaterial presets.
-
- @property presets
- @type {Object}
- @static
- */
- static get presets() {
- return PRESETS;
- };
-
- /**
- JavaScript class name for this Component.
-
- For example: "xeogl.AmbientLight", "xeogl.MetallicMaterial" etc.
-
- @property type
- @type String
- @final
- */
- get type() {
- return type;
- }
-
- init(cfg) {
-
- super.init(cfg);
-
- this._state = new State({
- type: "EdgeMaterial",
- edgeColor: null,
- edgeAlpha: null,
- edgeWidth: null
- });
-
- this._preset = "default";
-
- if (cfg.preset) { // Apply preset then override with configs where provided
- this.preset = cfg.preset;
- if (cfg.edgeColor) {
- this.edgeColor = cfg.edgeColor;
- }
- if (cfg.edgeAlpha !== undefined) {
- this.edgeAlpha = cfg.edgeAlpha;
- }
- if (cfg.edgeWidth !== undefined) {
- this.edgeWidth = cfg.edgeWidth;
- }
- } else {
- this.edgeColor = cfg.edgeColor;
- this.edgeAlpha = cfg.edgeAlpha;
- this.edgeWidth = cfg.edgeWidth;
- }
- }
-
-
- /**
- RGB color of ghost edges.
-
- @property edgeColor
- @default [0.2, 0.2, 0.2]
- @type Float32Array
- */
- set edgeColor(value) {
- let edgeColor = this._state.edgeColor;
- if (!edgeColor) {
- edgeColor = this._state.edgeColor = new Float32Array(3);
- } else if (value && edgeColor[0] === value[0] && edgeColor[1] === value[1] && edgeColor[2] === value[2]) {
- return;
- }
- if (value) {
- edgeColor[0] = value[0];
- edgeColor[1] = value[1];
- edgeColor[2] = value[2];
- } else {
- edgeColor[0] = 0.2;
- edgeColor[1] = 0.2;
- edgeColor[2] = 0.2;
- }
- this._renderer.imageDirty();
- }
-
- get edgeColor() {
- return this._state.edgeColor;
- }
-
- /**
- Transparency of ghost edges.
-
- A value of 0.0 indicates fully transparent, 1.0 is fully opaque.
-
- @property edgeAlpha
- @default 1.0
- @type Number
- */
- set edgeAlpha(value) {
- value = (value !== undefined && value !== null) ? value : 1.0;
- if (this._state.edgeAlpha === value) {
- return;
- }
- this._state.edgeAlpha = value;
- this._renderer.imageDirty();
- }
-
- get edgeAlpha() {
- return this._state.edgeAlpha;
- }
-
- /**
- Width of ghost edges, in pixels.
-
- @property edgeWidth
- @default 1.0
- @type Number
- */
- set edgeWidth(value) {
- this._state.edgeWidth = value || 1.0;
- this._renderer.imageDirty();
- }
-
- get edgeWidth() {
- return this._state.edgeWidth;
- }
-
- /**
- Selects a preset EdgeMaterial configuration.
-
- Available presets are:
-
- * "default" - grey wireframe with translucent fill, for light backgrounds.
- * "defaultLightBG" - grey wireframe with grey translucent fill, for light backgrounds.
- * "defaultDarkBG" - grey wireframe with grey translucent fill, for dark backgrounds.
- * "vectorscope" - green wireframe with glowing vertices and black translucent fill.
- * "battlezone" - green wireframe with black opaque fill, giving a solid hidden-lines-removed effect.
- * "sepia" - light red-grey wireframe with light sepia translucent fill - easy on the eyes.
- * "gamegrid" - light blue wireframe with dark blue translucent fill - reminiscent of Tron.
- * "yellowHighlight" - light yellow translucent fill - highlights while allowing underlying detail to show through.
-
- @property preset
- @default "default"
- @type String
- */
- set preset(value) {
- value = value || "default";
- if (this._preset === value) {
- return;
- }
- const preset = PRESETS[value];
- if (!preset) {
- this.error("unsupported preset: '" + value + "' - supported values are " + Object.keys(PRESETS).join(", "));
- return;
- }
- this.edgeColor = preset.edgeColor;
- this.edgeAlpha = preset.edgeAlpha;
- this.edgeWidth = preset.edgeWidth;
- this._preset = value;
- }
-
- get preset() {
- return this._preset;
- }
-
- destroy() {
- super.destroy();
- this._state.destroy();
- }
- }
-
- componentClasses[type] = EdgeMaterial;
-
- export {EdgeMaterial};
-