Add the possibility to switch between environment maps #161
35
assets/icons/arrow_left.svg
Normal file
@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
viewBox="0 0 18 18"
|
||||
xml:space="preserve"
|
||||
version="1.1"
|
||||
id="svg4"
|
||||
sodipodi:docname="arrow_left.svg"
|
||||
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20)"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs8" /><sodipodi:namedview
|
||||
id="namedview6"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pagecheckerboard="0"
|
||||
showgrid="true"
|
||||
inkscape:zoom="43.277778"
|
||||
inkscape:cx="9"
|
||||
inkscape:cy="9"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1017"
|
||||
inkscape:window-x="-8"
|
||||
inkscape:window-y="-8"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg4"><inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid821" /></sodipodi:namedview><path
|
||||
d="m 11.502979,14.003 -4.9999997,-5 4.9999997,-5"
|
||||
style="fill:none;stroke:#263238;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:10;stroke-opacity:1"
|
||||
id="path2" /></svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
46
sandbox/embed_iframe_envmaps.html
Normal file
@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
||||
<meta name="viewport" content="width=device-width, user-scalable=no">
|
||||
|
||||
<title>Online 3D Viewer</title>
|
||||
|
||||
<script type="text/javascript" src="../../libs/three.min.js"></script>
|
||||
<script type="text/javascript" src="../build/o3dv.min-dev.js"></script>
|
||||
|
||||
<script type='text/javascript'>
|
||||
OV.SetExternalLibLocation ('../../libs');
|
||||
OV.Init3DViewerElements ();
|
||||
</script>
|
||||
|
||||
<style>
|
||||
div.online_3d_viewer
|
||||
{
|
||||
float: left;
|
||||
border: 1px solid #eeeeee;
|
||||
margin: 0px 4px 4px 0px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<iframe
|
||||
src="../../website/embed.html#model=../test/testfiles/gltf/DamagedHelmet/glTF-Binary/DamagedHelmet.glb"
|
||||
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=fishermans_bastion"
|
||||
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"
|
||||
width=360 height=240
|
||||
style="border:1px solid #eeeeee;">
|
||||
</iframe>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@ -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');
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
},
|
||||
|
||||
@ -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 ();
|
||||
|
||||
@ -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 ();
|
||||
|
||||
@ -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'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 ());
|
||||
|
||||
@ -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 ();
|
||||
});
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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 : {
|
||||
|
||||
@ -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 ()
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
33
test/testfiles/o3dv/mirror_sphere.o3dv
Normal file
@ -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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
website/assets/envmaps/citadella.jpg
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
website/assets/envmaps/fishermans_bastion.jpg
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
website/assets/envmaps/ice_river.jpg
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
website/assets/envmaps/maskonaive.jpg
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
website/assets/envmaps/park.jpg
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
website/assets/envmaps/teide.jpg
Normal file
|
After Width: | Height: | Size: 36 KiB |
@ -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";
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||