From ba22d4d5102b914ce5a9553e47763d1b2d5e5811 Mon Sep 17 00:00:00 2001 From: kovacsv Date: Sat, 22 Jan 2022 16:03:11 +0100 Subject: [PATCH] Feature Request - Ability to load/toggle environment texture instead of solid color #144 --- sandbox/embed_iframe_envmaps.html | 14 ++- source/engine/parameters/parameterlist.js | 38 ++++++- source/engine/viewer/embeddedviewer.js | 3 +- source/engine/viewer/viewer.js | 28 +++-- source/website/embed.js | 32 +++++- source/website/hashhandler.js | 4 +- source/website/settings.js | 3 + source/website/sharingdialog.js | 129 +++++++++------------- source/website/sidebarsettingspanel.js | 22 ++-- source/website/website.js | 5 +- 10 files changed, 167 insertions(+), 111 deletions(-) diff --git a/sandbox/embed_iframe_envmaps.html b/sandbox/embed_iframe_envmaps.html index bcc2d16..3a44349 100644 --- a/sandbox/embed_iframe_envmaps.html +++ b/sandbox/embed_iframe_envmaps.html @@ -32,12 +32,22 @@ style="border:1px solid #eeeeee;"> + + diff --git a/source/engine/parameters/parameterlist.js b/source/engine/parameters/parameterlist.js index 50dd631..95328d0 100644 --- a/source/engine/parameters/parameterlist.js +++ b/source/engine/parameters/parameterlist.js @@ -101,6 +101,34 @@ export let ParameterConverter = return color; }, + EnvironmentSettingsToString (environmentSettings) + { + if (environmentSettings === null) { + return null; + } + let environmentSettingsParameters = [ + environmentSettings.environmentMapName, + environmentSettings.backgroundIsEnvMap ? 'on' : 'off' + ].join (','); + return environmentSettingsParameters; + }, + + StringToEnvironmentSettings : function (str) + { + if (str === null || str.length === 0) { + return null; + } + let paramParts = str.split (','); + if (paramParts.length !== 2) { + return null; + } + let environmentSettings = { + environmentMapName : paramParts[0], + backgroundIsEnvMap : paramParts[1] === 'on' ? true : false + }; + return environmentSettings; + }, + EdgeSettingsToString : function (edgeSettings) { if (edgeSettings === null) { @@ -156,9 +184,9 @@ export class ParameterListBuilder return this; } - AddEnvironmentMapName (envMapName) + AddEnvironmentSettings (envSettings) { - this.AddUrlPart ('envmap', envMapName); + this.AddUrlPart ('envsettings', ParameterConverter.EnvironmentSettingsToString (envSettings)); return this; } @@ -222,10 +250,10 @@ export class ParameterListParser return ParameterConverter.StringToCamera (keywordParams); } - GetEnvironmentMapName () + GetEnvironmentSettings () { - let envMapName = this.GetKeywordParams ('envmap'); - return envMapName; + let environmentSettingsParams = this.GetKeywordParams ('envsettings'); + return ParameterConverter.StringToEnvironmentSettings (environmentSettingsParams); } GetBackgroundColor () diff --git a/source/engine/viewer/embeddedviewer.js b/source/engine/viewer/embeddedviewer.js index 420dbdc..d72c35a 100644 --- a/source/engine/viewer/embeddedviewer.js +++ b/source/engine/viewer/embeddedviewer.js @@ -39,7 +39,8 @@ export class EmbeddedViewer } if (this.parameters.environmentMap) { - this.viewer.SetEnvironmentMap (this.parameters.environmentMap); + // TODO + this.viewer.SetEnvironmentMapSettings (this.parameters.environmentMap, false); } window.addEventListener ('resize', () => { diff --git a/source/engine/viewer/viewer.js b/source/engine/viewer/viewer.js index 26d9780..fc79241 100644 --- a/source/engine/viewer/viewer.js +++ b/source/engine/viewer/viewer.js @@ -125,6 +125,7 @@ export class ShadingModel this.ambientLight = new THREE.AmbientLight (0x888888); this.directionalLight = new THREE.DirectionalLight (0x888888); this.environment = null; + this.backgroundIsEnvMap = false; this.scene.add (this.ambientLight); this.scene.add (this.directionalLight); @@ -142,19 +143,26 @@ export class ShadingModel this.ambientLight.color.set (0x888888); this.directionalLight.color.set (0x888888); this.scene.environment = null; + this.scene.background = null; } else if (this.type === ShadingType.Physical) { this.ambientLight.color.set (0x000000); this.directionalLight.color.set (0x555555); this.scene.environment = this.environment; + if (this.backgroundIsEnvMap) { + this.scene.background = this.environment; + } else { + this.scene.background = null; + } } } - SetEnvironment (textures, onLoaded) + SetEnvironment (textures, useAsBackground, onLoaded) { let loader = new THREE.CubeTextureLoader (); this.environment = loader.load (textures, () => { onLoaded (); }); + this.backgroundIsEnvMap = useAsBackground; } UpdateByCamera (camera) @@ -245,6 +253,15 @@ export class Viewer { this.navigation.SetContextMenuHandler (onContext); } + + SetEnvironmentMapSettings (textures, useAsBackground) + { + this.shading.SetEnvironment (textures, useAsBackground, () => { + this.Render (); + }); + this.shading.UpdateShading (); + this.Render (); + } SetBackgroundColor (color) { @@ -265,15 +282,6 @@ export class Viewer this.Render (); } - SetEnvironmentMap (textures) - { - this.shading.SetEnvironment (textures, () => { - this.Render (); - }); - this.shading.UpdateShading (); - this.Render (); - } - GetCanvas () { return this.canvas; diff --git a/source/website/embed.js b/source/website/embed.js index e96709e..1af5a27 100644 --- a/source/website/embed.js +++ b/source/website/embed.js @@ -29,19 +29,41 @@ export class Embed return; } TransformFileHostUrls (urls); - let envMapName = this.hashHandler.GetEnvironmentMapNameFromHash (); - if (envMapName === null) { - envMapName = 'fishermans_bastion'; + // let envMapName = this.hashHandler.GetEnvironmentMapNameFromHash (); + // if (envMapName === null) { + // envMapName = 'fishermans_bastion'; + // } + // let envMapPath = 'assets/envmaps/' + envMapName + '/'; + // let envMapTextures = [ + // envMapPath + 'posx.jpg', + // envMapPath + 'negx.jpg', + // envMapPath + 'posy.jpg', + // envMapPath + 'negy.jpg', + // envMapPath + 'posz.jpg', + // envMapPath + 'negz.jpg' + // ]; + // // TODO + // this.viewer.SetEnvironmentMapSettings (envMapTextures, false); + + + let envMapName = 'fishermans_bastion'; + let bgIsEnvMap = false; + let environmentSettings = this.hashHandler.GetEnvironmentSettingsFromHash (); + if (environmentSettings !== null) { + envMapName = environmentSettings.environmentMapName; + bgIsEnvMap = environmentSettings.backgroundIsEnvMap; } let envMapPath = 'assets/envmaps/' + envMapName + '/'; - this.viewer.SetEnvironmentMap ([ + let envMapTextures = [ envMapPath + 'posx.jpg', envMapPath + 'negx.jpg', envMapPath + 'posy.jpg', envMapPath + 'negy.jpg', envMapPath + 'posz.jpg', envMapPath + 'negz.jpg' - ]); + ]; + this.viewer.SetEnvironmentMapSettings (envMapTextures, bgIsEnvMap); + let background = this.hashHandler.GetBackgroundFromHash (); if (background !== null) { this.viewer.SetBackgroundColor (background); diff --git a/source/website/hashhandler.js b/source/website/hashhandler.js index 5e69a57..fa7929c 100644 --- a/source/website/hashhandler.js +++ b/source/website/hashhandler.js @@ -54,10 +54,10 @@ export class HashHandler return parser.GetBackgroundColor (); } - GetEnvironmentMapNameFromHash () + GetEnvironmentSettingsFromHash () { let parser = CreateUrlParser (this.GetHash ()); - return parser.GetEnvironmentMapName (); + return parser.GetEnvironmentSettings (); } GetDefaultColorFromHash () diff --git a/source/website/settings.js b/source/website/settings.js index 41587a6..b3e3837 100644 --- a/source/website/settings.js +++ b/source/website/settings.js @@ -12,6 +12,7 @@ export class Settings constructor () { this.environmentMapName = 'fishermans_bastion'; + this.backgroundIsEnvMap = false; this.backgroundColor = new Color (255, 255, 255); this.defaultColor = new Color (200, 200, 200); this.showGrid = false; @@ -24,6 +25,7 @@ export class Settings LoadFromCookies () { this.environmentMapName = CookieGetStringVal ('ov_environment_map', 'fishermans_bastion'); + this.backgroundIsEnvMap = CookieGetBoolVal ('ov_background_is_envmap', false); this.backgroundColor = CookieGetColorVal ('ov_background_color', new Color (255, 255, 255)); this.defaultColor = CookieGetColorVal ('ov_default_color', new Color (200, 200, 200)); this.showGrid = CookieGetBoolVal ('ov_show_grid', false); @@ -36,6 +38,7 @@ export class Settings SaveToCookies () { CookieSetStringVal ('ov_environment_map', this.environmentMapName); + CookieSetBoolVal ('ov_background_is_envmap', this.backgroundIsEnvMap); CookieSetColorVal ('ov_background_color', this.backgroundColor); CookieSetColorVal ('ov_default_color', this.defaultColor); CookieSetBoolVal ('ov_show_grid', this.showGrid); diff --git a/source/website/sharingdialog.js b/source/website/sharingdialog.js index 3dcae6a..c490476 100644 --- a/source/website/sharingdialog.js +++ b/source/website/sharingdialog.js @@ -16,34 +16,6 @@ export function ShowSharingDialog (fileList, settings, camera) }); } - function GetSharingLink (params) - { - let builder = CreateUrlBuilder (); - builder.AddModelUrls (params.files); - let hashParameters = builder.GetParameterList (); - return 'https://3dviewer.net#' + hashParameters; - } - - function GetEmbeddingCode (params) - { - let builder = CreateUrlBuilder (); - builder.AddModelUrls (params.files); - builder.AddCamera (params.camera); - builder.AddEnvironmentMapName (params.environmentMapName); - builder.AddBackgroundColor (params.backgroundColor); - builder.AddDefaultColor (params.defaultColor); - builder.AddEdgeSettings (params.edgeSettings); - let hashParameters = builder.GetParameterList (); - - let embeddingCode = ''; - embeddingCode += ''; - embeddingCode += ''; - return embeddingCode; - } - function AddCopyableTextInput (parentDiv, getText) { let copyText = 'Copy'; @@ -62,53 +34,73 @@ export function ShowSharingDialog (fileList, settings, camera) return input; } - function AddSharingLinkTab (parentDiv, sharingLinkParams) + function AddSharingLinkTab (parentDiv, modelFiles) { + function GetSharingLink (modelFiles) + { + let builder = CreateUrlBuilder (); + builder.AddModelUrls (modelFiles); + let hashParameters = builder.GetParameterList (); + return 'https://3dviewer.net#' + hashParameters; + } + let section = AddDiv (parentDiv, 'ov_dialog_section'); AddDiv (section, 'ov_dialog_inner_title', 'Sharing Link'); let sharingLinkInput = AddCopyableTextInput (section, () => { HandleEvent ('model_shared', 'sharing_link'); - return GetSharingLink (sharingLinkParams); + return GetSharingLink (modelFiles); }); - sharingLinkInput.value = GetSharingLink (sharingLinkParams); + sharingLinkInput.value = GetSharingLink (modelFiles); } - function AddEmbeddingCodeTab (parentDiv, settings, embeddingCodeParams) + function AddEmbeddingCodeTab (parentDiv, modelFiles, settings, camera) { + function GetEmbeddingCode (modelFiles, useCurrentSettings, settings, camera) + { + let builder = CreateUrlBuilder (); + builder.AddModelUrls (modelFiles); + if (useCurrentSettings) { + builder.AddCamera (camera); + let environmentSettings = { + environmentMapName : settings.environmentMapName, + backgroundIsEnvMap : settings.backgroundIsEnvMap + }; + builder.AddEnvironmentSettings (environmentSettings); + builder.AddBackgroundColor (settings.backgroundColor); + builder.AddDefaultColor (settings.defaultColor); + let edgeSettings = { + showEdges : settings.showEdges, + edgeColor : settings.edgeColor, + edgeThreshold : settings.edgeThreshold + }; + builder.AddEdgeSettings (edgeSettings); + } + let hashParameters = builder.GetParameterList (); + + let embeddingCode = ''; + embeddingCode += ''; + embeddingCode += ''; + return embeddingCode; + } + + let useCurrentSettings = true; let section = AddDiv (parentDiv, 'ov_dialog_section'); section.style.marginTop = '20px'; AddDiv (section, 'ov_dialog_inner_title', 'Embedding Code'); let optionsSection = AddDiv (section, 'ov_dialog_section'); let embeddingCodeInput = AddCopyableTextInput (section, () => { HandleEvent ('model_shared', 'embedding_code'); - return GetEmbeddingCode (embeddingCodeParams); + return GetEmbeddingCode (modelFiles, useCurrentSettings, settings, camera); }); - AddCheckboxLine (optionsSection, 'Use current camera position', 'embed_camera', (checked) => { - embeddingCodeParams.camera = checked ? camera : null; - embeddingCodeInput.value = GetEmbeddingCode (embeddingCodeParams); + AddCheckboxLine (optionsSection, 'Use current settings instead of defaults', 'embed_current_settings', (checked) => { + useCurrentSettings = checked; + embeddingCodeInput.value = GetEmbeddingCode (modelFiles, useCurrentSettings, settings, camera); }); - AddCheckboxLine (optionsSection, 'Use overridden environment map', 'embed_envmap', (checked) => { - embeddingCodeParams.environmentMapName = checked ? settings.environmentMapName : null; - embeddingCodeInput.value = GetEmbeddingCode (embeddingCodeParams); - }); - AddCheckboxLine (optionsSection, 'Use overridden background color', 'embed_background', (checked) => { - embeddingCodeParams.backgroundColor = checked ? settings.backgroundColor : null; - embeddingCodeInput.value = GetEmbeddingCode (embeddingCodeParams); - }); - AddCheckboxLine (optionsSection, 'Use overridden default color', 'embed_color', (checked) => { - embeddingCodeParams.defaultColor = checked ? settings.defaultColor : null; - embeddingCodeInput.value = GetEmbeddingCode (embeddingCodeParams); - }); - AddCheckboxLine (optionsSection, 'Use overridden edge display', 'embed_edge_display', (checked) => { - const edgeSettings = { - showEdges : settings.edgeSettings, - edgeColor : settings.edgeColor, - edgeThreshold : settings.edgeThreshold - }; - embeddingCodeParams.edgeSettings = checked ? edgeSettings : null; - embeddingCodeInput.value = GetEmbeddingCode (embeddingCodeParams); - }); - embeddingCodeInput.value = GetEmbeddingCode (embeddingCodeParams); + + embeddingCodeInput.value = GetEmbeddingCode (modelFiles, useCurrentSettings, settings, camera); } if (!fileList.IsOnlyUrlSource ()) { @@ -128,23 +120,6 @@ export function ShowSharingDialog (fileList, settings, camera) } } - let sharingLinkParams = { - files : modelFiles - }; - - let embeddingCodeParams = { - files : modelFiles, - camera : camera, - environmentMapName : settings.environmentMapName, - backgroundColor : settings.backgroundColor, - defaultColor : settings.defaultColor, - edgeSettings : { - showEdges : settings.showEdges, - edgeColor : settings.edgeColor, - edgeThreshold : settings.edgeThreshold - } - }; - let dialog = new ButtonDialog (); let contentDiv = dialog.Init ('Share', [ { @@ -155,8 +130,8 @@ export function ShowSharingDialog (fileList, settings, camera) } ]); - AddSharingLinkTab (contentDiv, sharingLinkParams); - AddEmbeddingCodeTab (contentDiv, settings, embeddingCodeParams); + AddSharingLinkTab (contentDiv, modelFiles); + AddEmbeddingCodeTab (contentDiv, modelFiles, settings, camera); dialog.Show (); return dialog; diff --git a/source/website/sidebarsettingspanel.js b/source/website/sidebarsettingspanel.js index 4976273..8079949 100644 --- a/source/website/sidebarsettingspanel.js +++ b/source/website/sidebarsettingspanel.js @@ -1,5 +1,5 @@ import { Color, ColorToHexString } from '../engine/model/color.js'; -import { AddDiv, AddDomElement, AddRangeSlider, AddToggle, ShowDomElement, SetDomElementOuterHeight } from '../engine/viewer/domutils.js'; +import { AddDiv, AddDomElement, AddRangeSlider, AddToggle, AddCheckbox, ShowDomElement, SetDomElementOuterHeight } from '../engine/viewer/domutils.js'; import { CalculatePopupPositionToElementTopLeft } from './dialogs.js'; import { PopupDialog } from './modal.js'; import { Settings, Theme } from './settings.js'; @@ -50,7 +50,7 @@ class EnvironmentMapPopup extends PopupDialog super (); } - ShowPopup (buttonDiv, defaultEnvMapName, callbacks) + ShowPopup (buttonDiv, settings, callbacks) { let contentDiv = super.Init (() => { return CalculatePopupPositionToElementTopLeft (buttonDiv, contentDiv); @@ -86,7 +86,7 @@ class EnvironmentMapPopup extends PopupDialog for (let envMapImage of envMapImages) { envMapImage.element = AddDomElement (contentDiv, 'img', 'ov_environment_map_preview'); envMapImage.element.setAttribute ('src', 'assets/envmaps/' + envMapImage.name + '.jpg'); - if (envMapImage.name === defaultEnvMapName) { + if (envMapImage.name === settings.environmentMapName) { envMapImage.element.classList.add ('selected'); } envMapImage.element.addEventListener ('click', () => { @@ -94,10 +94,16 @@ class EnvironmentMapPopup extends PopupDialog otherImage.element.classList.remove ('selected'); } envMapImage.element.classList.add ('selected'); - callbacks.onEnvironmentMapChange (envMapImage.name); + settings.environmentMapName = envMapImage.name; + callbacks.onEnvironmentMapChange (); }); } + let backgroundIsEnvMapCheckbox = AddCheckbox (contentDiv, 'use_as_background', 'Use as background', settings.backgroundIsEnvMap, () => { + settings.backgroundIsEnvMap = backgroundIsEnvMapCheckbox.checked; + callbacks.onEnvironmentMapChange (); + }); + contentDiv.classList.add ('sidebar'); this.Show (); } @@ -153,9 +159,8 @@ class SettingsModelDisplaySection extends SettingsSection AddDiv (this.environmentMapButton, 'ov_panel_button_text', 'Environment Map'); this.environmentMapButton.addEventListener ('click', () => { this.environmentMapPopup = new EnvironmentMapPopup (); - this.environmentMapPopup.ShowPopup (this.environmentMapButton, settings.environmentMapName, { - onEnvironmentMapChange : (selectedEnvMap) => { - settings.environmentMapName = selectedEnvMap; + this.environmentMapPopup.ShowPopup (this.environmentMapButton, settings, { + onEnvironmentMapChange : () => { callbacks.onEnvironmentMapChange (); } }); @@ -413,6 +418,8 @@ export class SidebarSettingsPanel extends SidebarPanel { let defaultSettings = new Settings (); + this.settings.environmentMapName = defaultSettings.environmentMapName; + this.settings.backgroundIsEnvMap = defaultSettings.backgroundIsEnvMap; this.settings.backgroundColor = defaultSettings.backgroundColor; this.settings.defaultColor = defaultSettings.defaultColor; this.settings.showGrid = defaultSettings.showGrid; @@ -425,6 +432,7 @@ export class SidebarSettingsPanel extends SidebarPanel this.importParametersSection.Update (this.settings); this.appearanceSection.Update (this.settings); + this.callbacks.onEnvironmentMapChange (); this.callbacks.onThemeChange (); } diff --git a/source/website/website.js b/source/website/website.js index fbe9d91..36acc61 100644 --- a/source/website/website.js +++ b/source/website/website.js @@ -448,14 +448,15 @@ export class Website UpdateEnvironmentMap () { let envMapPath = 'assets/envmaps/' + this.settings.environmentMapName + '/'; - this.viewer.SetEnvironmentMap ([ + let envMapTextures = [ envMapPath + 'posx.jpg', envMapPath + 'negx.jpg', envMapPath + 'posy.jpg', envMapPath + 'negy.jpg', envMapPath + 'posz.jpg', envMapPath + 'negz.jpg' - ]); + ]; + this.viewer.SetEnvironmentMapSettings (envMapTextures, this.settings.backgroundIsEnvMap); } SwitchTheme (newThemeId, resetColors)