Feature Request - Ability to load/toggle environment texture instead of solid color #144

This commit is contained in:
kovacsv 2022-01-22 16:03:11 +01:00
parent d4d488ad46
commit ba22d4d510
10 changed files with 167 additions and 111 deletions

View File

@ -32,12 +32,22 @@
style="border:1px solid #eeeeee;">
</iframe>
<iframe
src="../../website/embed.html#model=../test/testfiles/gltf/DamagedHelmet/glTF-Binary/DamagedHelmet.glb$envmap=fishermans_bastion"
src="../../website/embed.html#model=../test/testfiles/gltf/DamagedHelmet/glTF-Binary/DamagedHelmet.glb$envsettings=fishermans_bastion,off"
width=360 height=240
style="border:1px solid #eeeeee;">
</iframe>
<iframe
src="../../website/embed.html#model=../test/testfiles/gltf/DamagedHelmet/glTF-Binary/DamagedHelmet.glb$envmap=citadella"
src="../../website/embed.html#model=../test/testfiles/gltf/DamagedHelmet/glTF-Binary/DamagedHelmet.glb$envsettings=citadella,off"
width=360 height=240
style="border:1px solid #eeeeee;">
</iframe>
<iframe
src="../../website/embed.html#model=../test/testfiles/gltf/DamagedHelmet/glTF-Binary/DamagedHelmet.glb$envsettings=fishermans_bastion,on"
width=360 height=240
style="border:1px solid #eeeeee;">
</iframe>
<iframe
src="../../website/embed.html#model=../test/testfiles/gltf/DamagedHelmet/glTF-Binary/DamagedHelmet.glb$envsettings=citadella,on"
width=360 height=240
style="border:1px solid #eeeeee;">
</iframe>

View File

@ -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 ()

View File

@ -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', () => {

View File

@ -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;

View File

@ -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);

View File

@ -54,10 +54,10 @@ export class HashHandler
return parser.GetBackgroundColor ();
}
GetEnvironmentMapNameFromHash ()
GetEnvironmentSettingsFromHash ()
{
let parser = CreateUrlParser (this.GetHash ());
return parser.GetEnvironmentMapName ();
return parser.GetEnvironmentSettings ();
}
GetDefaultColorFromHash ()

View File

@ -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);

View File

@ -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 += '<iframe';
embeddingCode += ' width="640" height="480"';
embeddingCode += ' style="border:1px solid #eeeeee;"';
embeddingCode += ' src="https://3dviewer.net/embed.html#' + hashParameters + '">';
embeddingCode += '</iframe>';
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 += '<iframe';
embeddingCode += ' width="640" height="480"';
embeddingCode += ' style="border:1px solid #eeeeee;"';
embeddingCode += ' src="https://3dviewer.net/embed.html#' + hashParameters + '">';
embeddingCode += '</iframe>';
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;

View File

@ -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 ();
}

View File

@ -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)