diff --git a/assets/icons/arrow_left.svg b/assets/icons/arrow_left.svg
new file mode 100644
index 0000000..e0221d1
--- /dev/null
+++ b/assets/icons/arrow_left.svg
@@ -0,0 +1,35 @@
+
+
diff --git a/sandbox/embed_iframe_envmaps.html b/sandbox/embed_iframe_envmaps.html
new file mode 100644
index 0000000..bcc2d16
--- /dev/null
+++ b/sandbox/embed_iframe_envmaps.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+ Online 3D Viewer
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/engine/parameters/parameterlist.js b/source/engine/parameters/parameterlist.js
index 3080ab1..50dd631 100644
--- a/source/engine/parameters/parameterlist.js
+++ b/source/engine/parameters/parameterlist.js
@@ -156,6 +156,12 @@ export class ParameterListBuilder
return this;
}
+ AddEnvironmentMapName (envMapName)
+ {
+ this.AddUrlPart ('envmap', envMapName);
+ return this;
+ }
+
AddBackgroundColor (background)
{
this.AddUrlPart ('backgroundcolor', ParameterConverter.ColorToString (background));
@@ -216,6 +222,12 @@ export class ParameterListParser
return ParameterConverter.StringToCamera (keywordParams);
}
+ GetEnvironmentMapName ()
+ {
+ let envMapName = this.GetKeywordParams ('envmap');
+ return envMapName;
+ }
+
GetBackgroundColor ()
{
let backgroundParams = this.GetKeywordParams ('backgroundcolor');
diff --git a/source/engine/threejs/threemodelloader.js b/source/engine/threejs/threemodelloader.js
index 2435730..88157f6 100644
--- a/source/engine/threejs/threemodelloader.js
+++ b/source/engine/threejs/threemodelloader.js
@@ -1,3 +1,4 @@
+import { Direction } from '../geometry/geometry.js';
import { Importer } from '../import/importer.js';
import { ConvertModelToThreeObject, ModelToThreeConversionOutput, ModelToThreeConversionParams } from './threeconverter.js';
import { ConvertColorToThreeColor, HasHighpDriverIssue } from './threeutils.js';
@@ -47,6 +48,13 @@ export class ThreeModelLoader
},
onModelLoaded : (threeObject) => {
this.defaultMaterial = output.defaultMaterial;
+ if (importResult.upVector === Direction.X) {
+ let rotation = new THREE.Quaternion ().setFromAxisAngle (new THREE.Vector3 (0.0, 0.0, 1.0), Math.PI / 2.0);
+ threeObject.quaternion.multiply (rotation);
+ } else if (importResult.upVector === Direction.Z) {
+ let rotation = new THREE.Quaternion ().setFromAxisAngle (new THREE.Vector3 (1.0, 0.0, 0.0), -Math.PI / 2.0);
+ threeObject.quaternion.multiply (rotation);
+ }
callbacks.onModelFinished (importResult, threeObject);
this.inProgress = false;
}
diff --git a/source/engine/viewer/embeddedviewer.js b/source/engine/viewer/embeddedviewer.js
index 2940a44..420dbdc 100644
--- a/source/engine/viewer/embeddedviewer.js
+++ b/source/engine/viewer/embeddedviewer.js
@@ -1,4 +1,5 @@
import { IsDefined } from '../core/core.js';
+import { Direction } from '../geometry/geometry.js';
import { ImportErrorCode, ImportSettings } from '../import/importer.js';
import { FileSource, TransformFileHostUrls } from '../io/fileutils.js';
import { ParameterConverter } from '../parameters/parameterlist.js';
@@ -86,7 +87,7 @@ export class EmbeddedViewer
if (this.parameters.camera) {
this.viewer.SetCamera (this.parameters.camera);
} else {
- this.viewer.SetUpVector (importResult.upVector, false);
+ this.viewer.SetUpVector (Direction.Y, false);
}
this.viewer.FitSphereToWindow (boundingSphere, false);
},
diff --git a/source/engine/viewer/viewer.js b/source/engine/viewer/viewer.js
index a251431..26d9780 100644
--- a/source/engine/viewer/viewer.js
+++ b/source/engine/viewer/viewer.js
@@ -133,6 +133,11 @@ export class ShadingModel
SetType (type)
{
this.type = type;
+ this.UpdateShading ();
+ }
+
+ UpdateShading ()
+ {
if (this.type === ShadingType.Phong) {
this.ambientLight.color.set (0x888888);
this.directionalLight.color.set (0x888888);
@@ -265,6 +270,8 @@ export class Viewer
this.shading.SetEnvironment (textures, () => {
this.Render ();
});
+ this.shading.UpdateShading ();
+ this.Render ();
}
GetCanvas ()
@@ -518,6 +525,11 @@ export class Viewer
this.shading = new ShadingModel (this.scene);
}
+ GetShadingType ()
+ {
+ return this.shading.type;
+ }
+
GetImageSize ()
{
let originalSize = new THREE.Vector2 ();
diff --git a/source/website/dialogs.js b/source/website/dialogs.js
index 4f88729..d7ae8ed 100644
--- a/source/website/dialogs.js
+++ b/source/website/dialogs.js
@@ -53,6 +53,15 @@ export function ShowListPopup (items, callbacks)
return popup;
}
+export function CalculatePopupPositionToElementTopLeft (elementDiv, contentDiv)
+{
+ let offset = elementDiv.getBoundingClientRect ();
+ return {
+ x : offset.left - contentDiv.offsetWidth,
+ y : offset.top
+ };
+}
+
export function CalculatePopupPositionToElementBottomRight (elementDiv, contentDiv)
{
let offset = elementDiv.getBoundingClientRect ();
diff --git a/source/website/embed.js b/source/website/embed.js
index e18461c..e96709e 100644
--- a/source/website/embed.js
+++ b/source/website/embed.js
@@ -5,6 +5,7 @@ import { AddDomElement } from '../engine/viewer/domutils.js';
import { Viewer } from '../engine/viewer/viewer.js';
import { HashHandler } from './hashhandler.js';
import { ThreeModelLoaderUI } from './threemodelloaderui.js';
+import { Direction } from '../engine/geometry/geometry.js';
export class Embed
{
@@ -19,15 +20,28 @@ export class Embed
Load ()
{
let canvas = AddDomElement (this.parameters.viewerDiv, 'canvas');
- this.InitViewer (canvas);
+ this.viewer.Init (canvas);
this.Resize ();
if (this.hashHandler.HasHash ()) {
- let urls = this.hashHandler.GetModelFilesFromHash ();
+ let urls = this.hashHandler.GetModelFilesFromHash ();
if (urls === null) {
return;
}
TransformFileHostUrls (urls);
+ let envMapName = this.hashHandler.GetEnvironmentMapNameFromHash ();
+ if (envMapName === null) {
+ envMapName = 'fishermans_bastion';
+ }
+ let envMapPath = 'assets/envmaps/' + envMapName + '/';
+ this.viewer.SetEnvironmentMap ([
+ envMapPath + 'posx.jpg',
+ envMapPath + 'negx.jpg',
+ envMapPath + 'posy.jpg',
+ envMapPath + 'negy.jpg',
+ envMapPath + 'posz.jpg',
+ envMapPath + 'negz.jpg'
+ ]);
let background = this.hashHandler.GetBackgroundFromHash ();
if (background !== null) {
this.viewer.SetBackgroundColor (background);
@@ -52,7 +66,7 @@ export class Embed
},
onFinish : (importResult, threeObject) =>
{
- this.OnModelFinished (importResult, threeObject);
+ this.OnModelFinished (threeObject);
},
onRender : () =>
{
@@ -80,7 +94,7 @@ export class Embed
this.viewer.Resize (windowWidth, windowHeight);
}
- OnModelFinished (importResult, threeObject)
+ OnModelFinished (threeObject)
{
this.viewer.SetMainObject (threeObject);
let boundingSphere = this.viewer.GetBoundingSphere ((meshUserData) => {
@@ -91,21 +105,8 @@ export class Embed
if (camera !== null) {
this.viewer.SetCamera (camera);
} else {
- this.viewer.SetUpVector (importResult.upVector, false);
+ this.viewer.SetUpVector (Direction.Y, false);
}
this.viewer.FitSphereToWindow (boundingSphere, false);
}
-
- InitViewer (canvas)
- {
- this.viewer.Init (canvas);
- this.viewer.SetEnvironmentMap ([
- 'assets/envmaps/fishermans_bastion/posx.jpg',
- 'assets/envmaps/fishermans_bastion/negx.jpg',
- 'assets/envmaps/fishermans_bastion/posy.jpg',
- 'assets/envmaps/fishermans_bastion/negy.jpg',
- 'assets/envmaps/fishermans_bastion/posz.jpg',
- 'assets/envmaps/fishermans_bastion/negz.jpg'
- ]);
- }
}
diff --git a/source/website/hashhandler.js b/source/website/hashhandler.js
index 709cf94..5e69a57 100644
--- a/source/website/hashhandler.js
+++ b/source/website/hashhandler.js
@@ -54,6 +54,12 @@ export class HashHandler
return parser.GetBackgroundColor ();
}
+ GetEnvironmentMapNameFromHash ()
+ {
+ let parser = CreateUrlParser (this.GetHash ());
+ return parser.GetEnvironmentMapName ();
+ }
+
GetDefaultColorFromHash ()
{
let parser = CreateUrlParser (this.GetHash ());
diff --git a/source/website/navigatorpanel.js b/source/website/navigatorpanel.js
index 81b80ed..a008639 100644
--- a/source/website/navigatorpanel.js
+++ b/source/website/navigatorpanel.js
@@ -11,9 +11,9 @@ export class NavigatorPopupButton
this.callbacks = null;
this.popup = null;
- this.button = AddDiv (this.parentDiv, 'ov_navigator_info_button');
- this.buttonText = AddDiv (this.button, 'ov_navigator_info_button_text');
- AddSvgIconElement (this.button, 'arrow_right', 'ov_navigator_info_button_icon');
+ this.button = AddDiv (this.parentDiv, 'ov_panel_button');
+ this.buttonText = AddDiv (this.button, 'ov_panel_button_text');
+ AddSvgIconElement (this.button, 'arrow_right', 'ov_panel_button_icon');
this.button.addEventListener ('click', () => {
this.OnButtonClick ();
});
diff --git a/source/website/settings.js b/source/website/settings.js
index 21bc868..41587a6 100644
--- a/source/website/settings.js
+++ b/source/website/settings.js
@@ -1,5 +1,5 @@
import { Color } from '../engine/model/color.js';
-import { CookieGetBoolVal, CookieGetColorVal, CookieGetIntVal, CookieSetBoolVal, CookieSetColorVal, CookieSetIntVal } from './cookiehandler.js';
+import { CookieGetBoolVal, CookieGetColorVal, CookieGetIntVal, CookieGetStringVal, CookieSetBoolVal, CookieSetColorVal, CookieSetIntVal, CookieSetStringVal } from './cookiehandler.js';
export const Theme =
{
@@ -11,6 +11,7 @@ export class Settings
{
constructor ()
{
+ this.environmentMapName = 'fishermans_bastion';
this.backgroundColor = new Color (255, 255, 255);
this.defaultColor = new Color (200, 200, 200);
this.showGrid = false;
@@ -22,6 +23,7 @@ export class Settings
LoadFromCookies ()
{
+ this.environmentMapName = CookieGetStringVal ('ov_environment_map', 'fishermans_bastion');
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);
@@ -33,6 +35,7 @@ export class Settings
SaveToCookies ()
{
+ CookieSetStringVal ('ov_environment_map', this.environmentMapName);
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 26a1848..3dcae6a 100644
--- a/source/website/sharingdialog.js
+++ b/source/website/sharingdialog.js
@@ -29,6 +29,7 @@ export function ShowSharingDialog (fileList, settings, camera)
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);
@@ -86,6 +87,10 @@ export function ShowSharingDialog (fileList, settings, camera)
embeddingCodeParams.camera = checked ? camera : null;
embeddingCodeInput.value = GetEmbeddingCode (embeddingCodeParams);
});
+ 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);
@@ -130,6 +135,7 @@ export function ShowSharingDialog (fileList, settings, camera)
let embeddingCodeParams = {
files : modelFiles,
camera : camera,
+ environmentMapName : settings.environmentMapName,
backgroundColor : settings.backgroundColor,
defaultColor : settings.defaultColor,
edgeSettings : {
diff --git a/source/website/sidebar.js b/source/website/sidebar.js
index d94d932..8f3b973 100644
--- a/source/website/sidebar.js
+++ b/source/website/sidebar.js
@@ -51,6 +51,9 @@ export class Sidebar
});
this.settingsPanel.Init ({
+ onEnvironmentMapChange : () => {
+ this.callbacks.onEnvironmentMapChange ();
+ },
onBackgroundColorChange : () => {
this.callbacks.onBackgroundColorChange ();
},
@@ -79,9 +82,9 @@ export class Sidebar
});
}
- UpdateSettings (hasDefaultMaterial)
+ UpdateSettings (isPhysicallyBased, hasDefaultMaterial)
{
- this.settingsPanel.UpdateSettings (hasDefaultMaterial);
+ this.settingsPanel.UpdateSettings (isPhysicallyBased, hasDefaultMaterial);
}
UpdateMeasureTool ()
diff --git a/source/website/sidebarmeasurepanel.js b/source/website/sidebarmeasurepanel.js
index bc042dd..3d64323 100644
--- a/source/website/sidebarmeasurepanel.js
+++ b/source/website/sidebarmeasurepanel.js
@@ -28,7 +28,7 @@ export class SidebarMeasurePanel extends SidebarPanel
super.Init (callbacks);
let isActive = false;
- let activateButton = AddDiv (this.contentDiv, 'ov_button ov_sidebar_button', 'Activate');
+ let activateButton = AddDiv (this.contentDiv, 'ov_button ov_panel_button', 'Activate');
activateButton.addEventListener ('click', () => {
isActive = !isActive;
if (isActive) {
diff --git a/source/website/sidebarsettingspanel.js b/source/website/sidebarsettingspanel.js
index b525e6b..4976273 100644
--- a/source/website/sidebarsettingspanel.js
+++ b/source/website/sidebarsettingspanel.js
@@ -1,7 +1,10 @@
import { Color, ColorToHexString } from '../engine/model/color.js';
-import { AddDiv, AddDomElement, AddRangeSlider, AddToggle, ShowDomElement, GetDomElementOuterHeight, SetDomElementOuterHeight } from '../engine/viewer/domutils.js';
+import { AddDiv, AddDomElement, AddRangeSlider, AddToggle, ShowDomElement, SetDomElementOuterHeight } from '../engine/viewer/domutils.js';
+import { CalculatePopupPositionToElementTopLeft } from './dialogs.js';
+import { PopupDialog } from './modal.js';
import { Settings, Theme } from './settings.js';
import { SidebarPanel } from './sidebarpanel.js';
+import { AddSvgIconElement } from './utils.js';
function AddColorPicker (parentDiv, defaultColor, predefinedColors, onChange)
{
@@ -40,6 +43,66 @@ function AddColorPicker (parentDiv, defaultColor, predefinedColors, onChange)
return pickr;
}
+class EnvironmentMapPopup extends PopupDialog
+{
+ constructor ()
+ {
+ super ();
+ }
+
+ ShowPopup (buttonDiv, defaultEnvMapName, callbacks)
+ {
+ let contentDiv = super.Init (() => {
+ return CalculatePopupPositionToElementTopLeft (buttonDiv, contentDiv);
+ });
+
+ let envMapImages = [
+ {
+ element: null,
+ name: 'fishermans_bastion'
+ },
+ {
+ element: null,
+ name: 'citadella'
+ },
+ {
+ element: null,
+ name: 'maskonaive'
+ },
+ {
+ element: null,
+ name: 'teide'
+ },
+ {
+ element: null,
+ name: 'ice_river'
+ },
+ {
+ element: null,
+ name: 'park'
+ }
+ ];
+
+ 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) {
+ envMapImage.element.classList.add ('selected');
+ }
+ envMapImage.element.addEventListener ('click', () => {
+ for (let otherImage of envMapImages) {
+ otherImage.element.classList.remove ('selected');
+ }
+ envMapImage.element.classList.add ('selected');
+ callbacks.onEnvironmentMapChange (envMapImage.name);
+ });
+ }
+
+ contentDiv.classList.add ('sidebar');
+ this.Show ();
+ }
+}
+
class SettingsSection
{
constructor (parentDiv, title)
@@ -71,6 +134,9 @@ class SettingsModelDisplaySection extends SettingsSection
{
super (parentDiv, 'Model Display');
+ this.environmentMapButton = null;
+ this.environmentMapPopup = null;
+
this.backgroundColorPicker = null;
this.edgeDisplayToggle = null;
@@ -82,6 +148,19 @@ class SettingsModelDisplaySection extends SettingsSection
Init (settings, callbacks)
{
+ this.environmentMapButton = AddDiv (this.contentDiv, 'ov_panel_button');
+ AddSvgIconElement (this.environmentMapButton, 'arrow_left', 'ov_panel_button_left_icon');
+ 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;
+ callbacks.onEnvironmentMapChange ();
+ }
+ });
+ });
+
let backgroundColorDiv = AddDiv (this.contentDiv, 'ov_sidebar_parameter');
let backgroundColorInput = AddDiv (backgroundColorDiv, 'ov_color_picker');
AddDiv (backgroundColorDiv, null, 'Background Color');
@@ -130,6 +209,11 @@ class SettingsModelDisplaySection extends SettingsSection
ShowDomElement (this.edgeSettingsDiv, settings.showEdges);
}
+ UpdateVisibility (isPhysicallyBased)
+ {
+ ShowDomElement (this.environmentMapButton, isPhysicallyBased);
+ }
+
Update (settings)
{
if (this.backgroundColorPicker !== null) {
@@ -148,6 +232,11 @@ class SettingsModelDisplaySection extends SettingsSection
Clear ()
{
+ if (this.environmentMapPopup !== null) {
+ this.environmentMapPopup.Hide ();
+ this.environmentMapPopup = null;
+ }
+
if (this.backgroundColorPicker !== null) {
this.backgroundColorPicker.hide ();
}
@@ -244,7 +333,7 @@ export class SidebarSettingsPanel extends SidebarPanel
this.importParametersSection = new SettingsImportParametersSection (this.sectionsDiv);
this.appearanceSection = new SettingsAppearanceSection (this.sectionsDiv);
- this.resetToDefaultsButton = AddDiv (this.contentDiv, 'ov_button ov_sidebar_button outline', 'Reset to Default');
+ this.resetToDefaultsButton = AddDiv (this.contentDiv, 'ov_button ov_panel_button outline', 'Reset to Default');
this.resetToDefaultsButton.addEventListener ('click', () => {
this.ResetToDefaults ();
});
@@ -276,6 +365,9 @@ export class SidebarSettingsPanel extends SidebarPanel
{
super.Init (callbacks);
this.modelDisplaySection.Init (this.settings, {
+ onEnvironmentMapChange : () => {
+ callbacks.onEnvironmentMapChange ();
+ },
onBackgroundColorChange : () => {
callbacks.onBackgroundColorChange ();
},
@@ -310,8 +402,9 @@ export class SidebarSettingsPanel extends SidebarPanel
});
}
- UpdateSettings (hasDefaultMaterial)
+ UpdateSettings (isPhysicallyBased, hasDefaultMaterial)
{
+ this.modelDisplaySection.UpdateVisibility (isPhysicallyBased);
this.importParametersSection.UpdateVisibility (hasDefaultMaterial);
this.Resize ();
}
@@ -337,7 +430,7 @@ export class SidebarSettingsPanel extends SidebarPanel
Resize ()
{
- let resetButtonHeight = GetDomElementOuterHeight (this.resetToDefaultsButton);
+ let resetButtonHeight = this.resetToDefaultsButton.offsetHeight;
let height = this.parentDiv.offsetHeight;
SetDomElementOuterHeight (this.sectionsDiv, height - resetButtonHeight);
}
diff --git a/source/website/website.js b/source/website/website.js
index e0442b6..fbe9d91 100644
--- a/source/website/website.js
+++ b/source/website/website.js
@@ -19,6 +19,7 @@ import { ShowSharingDialog } from './sharingdialog.js';
import { HasDefaultMaterial, ReplaceDefaultMaterialColor } from '../engine/model/modelutils.js';
import { Direction } from '../engine/geometry/geometry.js';
import { CookieGetBoolVal, CookieSetBoolVal } from './cookiehandler.js';
+import { ShadingType } from '../engine/threejs/threeutils.js';
export const WebsiteUIState =
{
@@ -174,7 +175,7 @@ export class Website
this.model = importResult.model;
this.parameters.fileNameDiv.innerHTML = importResult.mainFile;
this.viewer.SetMainObject (threeObject);
- this.viewer.SetUpVector (importResult.upVector, false);
+ this.viewer.SetUpVector (Direction.Y, false);
this.navigator.FillTree (importResult);
this.UpdateSidebar ();
this.FitModelToWindow (true);
@@ -336,8 +337,10 @@ export class Website
UpdateSidebar ()
{
+ let shadingType = this.viewer.GetShadingType ();
+ let isPhysicallyBased = (shadingType === ShadingType.Physical);
let hasDefaultMaterial = HasDefaultMaterial (this.model);
- this.sidebar.UpdateSettings (hasDefaultMaterial);
+ this.sidebar.UpdateSettings (isPhysicallyBased, hasDefaultMaterial);
}
UpdateMeshesVisibility ()
@@ -442,6 +445,19 @@ export class Website
this.viewer.SetEdgeSettings (this.settings.showEdges, this.settings.edgeColor, this.settings.edgeThreshold);
}
+ UpdateEnvironmentMap ()
+ {
+ let envMapPath = 'assets/envmaps/' + this.settings.environmentMapName + '/';
+ this.viewer.SetEnvironmentMap ([
+ envMapPath + 'posx.jpg',
+ envMapPath + 'negx.jpg',
+ envMapPath + 'posy.jpg',
+ envMapPath + 'negy.jpg',
+ envMapPath + 'posz.jpg',
+ envMapPath + 'negz.jpg'
+ ]);
+ }
+
SwitchTheme (newThemeId, resetColors)
{
this.settings.themeId = newThemeId;
@@ -464,14 +480,7 @@ export class Website
this.viewer.SetGridSettings (this.settings.showGrid);
this.viewer.SetEdgeSettings (this.settings.showEdges, this.settings.edgeColor, this.settings.edgeThreshold);
this.viewer.SetBackgroundColor (this.settings.backgroundColor);
- this.viewer.SetEnvironmentMap ([
- 'assets/envmaps/fishermans_bastion/posx.jpg',
- 'assets/envmaps/fishermans_bastion/negx.jpg',
- 'assets/envmaps/fishermans_bastion/posy.jpg',
- 'assets/envmaps/fishermans_bastion/negy.jpg',
- 'assets/envmaps/fishermans_bastion/posz.jpg',
- 'assets/envmaps/fishermans_bastion/negz.jpg'
- ]);
+ this.UpdateEnvironmentMap ();
}
InitMeasureTool ()
@@ -607,6 +616,10 @@ export class Website
InitSidebar ()
{
this.sidebar.Init ({
+ onEnvironmentMapChange : () => {
+ this.settings.SaveToCookies ();
+ this.UpdateEnvironmentMap ();
+ },
onBackgroundColorChange : () => {
this.settings.SaveToCookies ();
this.viewer.SetBackgroundColor (this.settings.backgroundColor);
diff --git a/test/testfiles/o3dv/mirror_sphere.o3dv b/test/testfiles/o3dv/mirror_sphere.o3dv
new file mode 100644
index 0000000..5318313
--- /dev/null
+++ b/test/testfiles/o3dv/mirror_sphere.o3dv
@@ -0,0 +1,33 @@
+{
+ "root" : 0,
+ "nodes" : [
+ {
+ "children" : [1]
+ },
+ {
+ "transformation" : {
+ "translation" : [0.0, 0.0, 0.0]
+ },
+ "mesh" : 0
+ }
+ ],
+ "materials" : [
+ {
+ "name" : "Black",
+ "color" : [255, 255, 255],
+ "metalness" : 1.0,
+ "roughness" : 0.0
+ }
+ ],
+ "meshes" : [
+ {
+ "name" : "Sphere",
+ "type" : "sphere",
+ "material" : 0,
+ "parameters" : {
+ "radius" : 1.0,
+ "segments" : 40
+ }
+ }
+ ]
+}
diff --git a/website/assets/envmaps/citadella.jpg b/website/assets/envmaps/citadella.jpg
new file mode 100644
index 0000000..69d4013
Binary files /dev/null and b/website/assets/envmaps/citadella.jpg differ
diff --git a/website/assets/envmaps/fishermans_bastion.jpg b/website/assets/envmaps/fishermans_bastion.jpg
new file mode 100644
index 0000000..d24a387
Binary files /dev/null and b/website/assets/envmaps/fishermans_bastion.jpg differ
diff --git a/website/assets/envmaps/ice_river.jpg b/website/assets/envmaps/ice_river.jpg
new file mode 100644
index 0000000..e86ccae
Binary files /dev/null and b/website/assets/envmaps/ice_river.jpg differ
diff --git a/website/assets/envmaps/maskonaive.jpg b/website/assets/envmaps/maskonaive.jpg
new file mode 100644
index 0000000..e83e7d1
Binary files /dev/null and b/website/assets/envmaps/maskonaive.jpg differ
diff --git a/website/assets/envmaps/park.jpg b/website/assets/envmaps/park.jpg
new file mode 100644
index 0000000..12d689f
Binary files /dev/null and b/website/assets/envmaps/park.jpg differ
diff --git a/website/assets/envmaps/teide.jpg b/website/assets/envmaps/teide.jpg
new file mode 100644
index 0000000..c03abac
Binary files /dev/null and b/website/assets/envmaps/teide.jpg differ
diff --git a/website/css/O3DVIcons/O3DVIcons.woff b/website/css/O3DVIcons/O3DVIcons.woff
index c9647fe..10b2391 100644
Binary files a/website/css/O3DVIcons/O3DVIcons.woff and b/website/css/O3DVIcons/O3DVIcons.woff differ
diff --git a/website/css/icons.css b/website/css/icons.css
index 26f7ea5..10cb36e 100644
--- a/website/css/icons.css
+++ b/website/css/icons.css
@@ -1,6 +1,6 @@
@font-face {
font-family: "O3DVIcons";
- src: url("O3DVIcons/O3DVIcons.woff?70370968d2ff22490319cfdbac7bfa4a") format("woff");
+ src: url("O3DVIcons/O3DVIcons.woff?dfbca3429a4573f9f2cc136d53e6ad15") format("woff");
}
i[class^="icon-"]:before, i[class*=" icon-"]:before {
@@ -17,114 +17,117 @@ i[class^="icon-"]:before, i[class*=" icon-"]:before {
.icon-arrow_down:before {
content: "\f101";
}
-.icon-arrow_right:before {
+.icon-arrow_left:before {
content: "\f102";
}
-.icon-arrow_up:before {
+.icon-arrow_right:before {
content: "\f103";
}
-.icon-close:before {
+.icon-arrow_up:before {
content: "\f104";
}
-.icon-collapse:before {
+.icon-close:before {
content: "\f105";
}
-.icon-deisolate:before {
+.icon-collapse:before {
content: "\f106";
}
-.icon-details:before {
+.icon-deisolate:before {
content: "\f107";
}
-.icon-donate:before {
+.icon-details:before {
content: "\f108";
}
-.icon-expand:before {
+.icon-donate:before {
content: "\f109";
}
-.icon-export:before {
+.icon-expand:before {
content: "\f10a";
}
-.icon-feedback:before {
+.icon-export:before {
content: "\f10b";
}
-.icon-file_download:before {
+.icon-feedback:before {
content: "\f10c";
}
-.icon-files:before {
+.icon-file_download:before {
content: "\f10d";
}
-.icon-fit:before {
+.icon-files:before {
content: "\f10e";
}
-.icon-fix_up_off:before {
+.icon-fit:before {
content: "\f10f";
}
-.icon-fix_up_on:before {
+.icon-fix_up_off:before {
content: "\f110";
}
-.icon-flat_list:before {
+.icon-fix_up_on:before {
content: "\f111";
}
-.icon-flip:before {
+.icon-flat_list:before {
content: "\f112";
}
-.icon-github:before {
+.icon-flip:before {
content: "\f113";
}
-.icon-hidden:before {
+.icon-github:before {
content: "\f114";
}
-.icon-info:before {
+.icon-hidden:before {
content: "\f115";
}
-.icon-isolate:before {
+.icon-info:before {
content: "\f116";
}
-.icon-materials:before {
+.icon-isolate:before {
content: "\f117";
}
-.icon-measure:before {
+.icon-materials:before {
content: "\f118";
}
-.icon-meshes:before {
+.icon-measure:before {
content: "\f119";
}
-.icon-missing_files:before {
+.icon-meshes:before {
content: "\f11a";
}
-.icon-model:before {
+.icon-missing_files:before {
content: "\f11b";
}
-.icon-open_url:before {
+.icon-model:before {
content: "\f11c";
}
-.icon-open:before {
+.icon-open_url:before {
content: "\f11d";
}
-.icon-settings:before {
+.icon-open:before {
content: "\f11e";
}
-.icon-share:before {
+.icon-settings:before {
content: "\f11f";
}
-.icon-tree_mesh:before {
+.icon-share:before {
content: "\f120";
}
-.icon-tree_view:before {
+.icon-tree_mesh:before {
content: "\f121";
}
-.icon-twitter:before {
+.icon-tree_view:before {
content: "\f122";
}
-.icon-up_y:before {
+.icon-twitter:before {
content: "\f123";
}
-.icon-up_z:before {
+.icon-up_y:before {
content: "\f124";
}
-.icon-visible:before {
+.icon-up_z:before {
content: "\f125";
}
-.icon-warning:before {
+.icon-visible:before {
content: "\f126";
}
+.icon-warning:before {
+ content: "\f127";
+}
diff --git a/website/css/navigator.css b/website/css/navigator.css
index 314585c..b27544e 100644
--- a/website/css/navigator.css
+++ b/website/css/navigator.css
@@ -56,29 +56,6 @@ div.ov_navigator_info_panel
overflow: auto;
}
-div.ov_navigator_info_panel div.ov_navigator_info_button
-{
- cursor: pointer;
- margin-top: 10px;
- border: 1px solid var(--ov_border_color);
- border-radius: 5px;
- overflow: auto;
-}
-
-div.ov_navigator_info_panel div.ov_navigator_info_button_text
-{
- padding: 5px;
- float: left;
-}
-
-div.ov_navigator_info_panel div.ov_navigator_info_button_icon
-{
- color: var(--ov_light_icon_color);
- padding: 6px;
- float: right;
-}
-
-
@media (hover)
{
@@ -87,11 +64,6 @@ div.ov_navigator_info_panel div.ov_navigator_info_panel_title:hover
background: var(--ov_hover_color);
}
-div.ov_navigator_info_panel div.ov_navigator_info_button:hover
-{
- background: var(--ov_hover_color);
-}
-
div.ov_navigator_buttons div.ov_navigator_button:hover
{
background: var(--ov_hover_color);
diff --git a/website/css/panelset.css b/website/css/panelset.css
index 20ed184..c4e2f08 100644
--- a/website/css/panelset.css
+++ b/website/css/panelset.css
@@ -28,9 +28,44 @@ div.ov_panel_set_right_container div.ov_panel_set_content
overflow: auto;
}
+div.ov_panel_button
+{
+ cursor: pointer;
+ margin-top: 10px;
+ border: 1px solid var(--ov_border_color);
+ border-radius: 5px;
+ overflow: auto;
+}
+
+div.ov_panel_button_text
+{
+ padding: 5px;
+ float: left;
+}
+
+div.ov_panel_button_icon
+{
+ color: var(--ov_light_icon_color);
+ padding: 6px;
+ float: right;
+}
+
+div.ov_panel_button_left_icon
+{
+ color: var(--ov_light_icon_color);
+ padding: 6px;
+ float: left;
+}
+
@media (hover)
{
+div.ov_panel_button:hover
+{
+ background: var(--ov_hover_color);
+}
+
+
div.ov_panel_set_menu div.ov_panel_set_menu_button:hover
{
background: var(--ov_hover_color);
diff --git a/website/css/sidebar.css b/website/css/sidebar.css
index 9789bc9..27aebf5 100644
--- a/website/css/sidebar.css
+++ b/website/css/sidebar.css
@@ -104,3 +104,24 @@ div.ov_sidebar_content button.pcr-button
outline: none;
float: left;
}
+
+img.ov_environment_map_preview
+{
+ width: 160px;
+ height: 90px;
+ display: block;
+ float: left;
+ padding: 1px;
+ border: 5px solid transparent;
+ cursor: pointer;
+}
+
+img.ov_environment_map_preview.selected
+{
+ border: 5px solid var(--ov_button_color);
+}
+
+div.ov_popup.sidebar
+{
+ width: 344px;
+}