diff --git a/tools/config.json b/tools/config.json
index 083e13e..02f0145 100644
--- a/tools/config.json
+++ b/tools/config.json
@@ -80,9 +80,14 @@
"website/o3dv/js/cookiedialog.js",
"website/o3dv/js/panelset.js",
"website/o3dv/js/navigatoritems.js",
- "website/o3dv/js/navigatorpanels.js",
+ "website/o3dv/js/navigatorpanel.js",
+ "website/o3dv/js/navigatorfilespanel.js",
+ "website/o3dv/js/navigatormaterialspanel.js",
+ "website/o3dv/js/navigatormeshespanel.js",
"website/o3dv/js/navigator.js",
- "website/o3dv/js/sidebarpanels.js",
+ "website/o3dv/js/sidebarpanel.js",
+ "website/o3dv/js/sidebardetailspanel.js",
+ "website/o3dv/js/sidebarsettingspanel.js",
"website/o3dv/js/sidebar.js",
"website/o3dv/js/hashhandler.js",
"website/o3dv/js/threemodelloaderui.js",
diff --git a/website/embed.html b/website/embed.html
index 9053760..f489287 100644
--- a/website/embed.html
+++ b/website/embed.html
@@ -108,9 +108,14 @@
-
+
+
+
+
-
+
+
+
diff --git a/website/index.html b/website/index.html
index cea1259..2519b73 100644
--- a/website/index.html
+++ b/website/index.html
@@ -110,9 +110,14 @@
-
+
+
+
+
-
+
+
+
diff --git a/website/o3dv/css/dialogs.css b/website/o3dv/css/dialogs.css
index cbcad2b..c6f4344 100644
--- a/website/o3dv/css/dialogs.css
+++ b/website/o3dv/css/dialogs.css
@@ -88,7 +88,6 @@ div.ov_dialog textarea.ov_dialog_textarea
width: 100%;
height: 120px;
border: 1px solid var(--ov_border_color);
- outline: none;
box-sizing: border-box;
}
@@ -158,7 +157,6 @@ div.ov_dialog div.ov_dialog_copyable_input input
width: 70%;
margin-top: 6px;
box-sizing: border-box;
- outline: none;
float: left;
border: 0px;
box-sizing: border-box;
diff --git a/website/o3dv/js/navigatorfilespanel.js b/website/o3dv/js/navigatorfilespanel.js
new file mode 100644
index 0000000..c672140
--- /dev/null
+++ b/website/o3dv/js/navigatorfilespanel.js
@@ -0,0 +1,66 @@
+OV.NavigatorFilesPanel = class extends OV.NavigatorPanel
+{
+ constructor (parentDiv)
+ {
+ super (parentDiv);
+ }
+
+ GetName ()
+ {
+ return 'Files';
+ }
+
+ GetIcon ()
+ {
+ return 'files';
+ }
+
+ Resize ()
+ {
+ let titleHeight = OV.GetDomElementOuterHeight (this.titleDiv);
+ let height = this.parentDiv.offsetHeight;
+ OV.SetDomElementHeight (this.treeDiv, height - titleHeight);
+ }
+
+ Clear ()
+ {
+ super.Clear ();
+ }
+
+ Fill (importResult)
+ {
+ super.Fill (importResult);
+ const usedFiles = importResult.usedFiles;
+ const missingFiles = importResult.missingFiles;
+
+ if (missingFiles.length > 0) {
+ let missingFilesItem = new OV.TreeViewGroupItem ('Missing Files', null);
+ missingFilesItem.ShowChildren (true);
+ this.treeView.AddChild (missingFilesItem);
+ for (let i = 0; i < missingFiles.length; i++) {
+ let file = missingFiles[i];
+ let item = new OV.TreeViewButtonItem (file);
+ let browseButton = new OV.TreeViewButton ('open');
+ browseButton.OnClick (() => {
+ this.callbacks.onFileBrowseButtonClicked ();
+ });
+ item.AppendButton (browseButton);
+ missingFilesItem.AddChild (item);
+ }
+ let filesItem = new OV.TreeViewGroupItem ('Available Files', null);
+ filesItem.ShowChildren (true);
+ this.treeView.AddChild (filesItem);
+ for (let i = 0; i < usedFiles.length; i++) {
+ let file = usedFiles[i];
+ let item = new OV.TreeViewSingleItem (file);
+ filesItem.AddChild (item);
+ }
+ } else {
+ for (let i = 0; i < usedFiles.length; i++) {
+ let file = usedFiles[i];
+ let item = new OV.TreeViewSingleItem (file);
+ this.treeView.AddChild (item);
+ }
+ }
+ }
+};
diff --git a/website/o3dv/js/navigatormaterialspanel.js b/website/o3dv/js/navigatormaterialspanel.js
new file mode 100644
index 0000000..aa390e6
--- /dev/null
+++ b/website/o3dv/js/navigatormaterialspanel.js
@@ -0,0 +1,138 @@
+OV.NavigatorMeshesPopupButton = class extends OV.NavigatorPopupButton
+{
+ constructor (parentDiv)
+ {
+ super (parentDiv);
+ this.meshInfoArray = null;
+ }
+
+ Update (meshInfoArray)
+ {
+ this.meshInfoArray = meshInfoArray;
+ if (this.meshInfoArray === null) {
+ return;
+ }
+
+ let meshesText = 'Meshes (' + this.meshInfoArray.length + ')';
+ this.buttonText.innerHTML = meshesText;
+ }
+
+ OnButtonClick ()
+ {
+ if (this.meshInfoArray === null) {
+ return;
+ }
+
+ let meshItems = [];
+ for (let i = 0; i < this.meshInfoArray.length; i++) {
+ let meshInfo = this.meshInfoArray[i];
+ meshItems.push ({
+ name : OV.GetMeshName (meshInfo.name)
+ });
+ }
+
+ if (meshItems.length === 0) {
+ return;
+ }
+
+ this.popup = OV.ShowListPopup (meshItems, {
+ calculatePosition : (contentDiv) => {
+ return OV.CalculatePopupPositionToElementBottomRight (this.button, contentDiv);
+ },
+ onHoverStart : (index) => {
+ const meshData = this.meshInfoArray[index];
+ this.callbacks.onMeshHover (meshData.meshId);
+ },
+ onHoverStop : (index) => {
+ this.callbacks.onMeshHover (null);
+ },
+ onClick : (index) => {
+ const meshData = this.meshInfoArray[index];
+ this.callbacks.onMeshSelected (meshData.meshId);
+ }
+ });
+ }
+};
+
+OV.NavigatorMaterialsPanel = class extends OV.NavigatorPanel
+{
+ constructor (parentDiv)
+ {
+ super (parentDiv);
+ this.callbacks = null;
+ this.materialIndexToItem = new Map ();
+
+ this.popupDiv = OV.AddDiv (this.panelDiv, 'ov_navigator_info_panel');
+ this.meshesButton = new OV.NavigatorMeshesPopupButton (this.popupDiv);
+ }
+
+ GetName ()
+ {
+ return 'Materials';
+ }
+
+ GetIcon ()
+ {
+ return 'materials';
+ }
+
+ Resize ()
+ {
+ let titleHeight = OV.GetDomElementOuterHeight (this.titleDiv);
+ let popupHeight = OV.GetDomElementOuterHeight (this.popupDiv);
+ let height = this.parentDiv.offsetHeight;
+ OV.SetDomElementHeight (this.treeDiv, height - titleHeight - popupHeight);
+ }
+
+ Clear ()
+ {
+ super.Clear ();
+ this.meshesButton.Clear ();
+ this.materialIndexToItem = new Map ();
+ }
+
+ Init (callbacks)
+ {
+ super.Init (callbacks);
+ this.meshesButton.Init ({
+ onMeshHover : (meshInstanceId) => {
+ this.callbacks.onMeshTemporarySelected (meshInstanceId);
+ },
+ onMeshSelected : (meshInstanceId) => {
+ this.callbacks.onMeshSelected (meshInstanceId);
+ }
+ });
+ }
+
+ Fill (importResult)
+ {
+ super.Fill (importResult);
+ const model = importResult.model;
+ for (let materialIndex = 0; materialIndex < model.MaterialCount (); materialIndex++) {
+ let material = model.GetMaterial (materialIndex);
+ let materialName = OV.GetMaterialName (material.name);
+ let materialItem = new OV.MaterialItem (materialName, materialIndex, {
+ onSelected : (materialIndex) => {
+ this.callbacks.onMaterialSelected (materialIndex);
+ }
+ });
+ this.materialIndexToItem.set (materialIndex, materialItem);
+ this.treeView.AddChild (materialItem);
+ }
+ }
+
+ GetMaterialItem (materialIndex)
+ {
+ return this.materialIndexToItem.get (materialIndex);
+ }
+
+ SelectMaterialItem (materialIndex, isSelected)
+ {
+ this.GetMaterialItem (materialIndex).SetSelected (isSelected);
+ }
+
+ UpdateMeshList (meshInfoArray)
+ {
+ this.meshesButton.Update (meshInfoArray);
+ }
+};
diff --git a/website/o3dv/js/navigatorpanels.js b/website/o3dv/js/navigatormeshespanel.js
similarity index 66%
rename from website/o3dv/js/navigatorpanels.js
rename to website/o3dv/js/navigatormeshespanel.js
index 1fc3b74..6d1be07 100644
--- a/website/o3dv/js/navigatorpanels.js
+++ b/website/o3dv/js/navigatormeshespanel.js
@@ -1,94 +1,3 @@
-OV.NavigatorPopupButton = class
-{
- constructor (parentDiv)
- {
- this.parentDiv = parentDiv;
- this.callbacks = null;
- this.popup = null;
-
- this.button = OV.AddDiv (this.parentDiv, 'ov_navigator_info_button');
- this.buttonText = OV.AddDiv (this.button, 'ov_navigator_info_button_text');
- OV.AddSvgIconElement (this.button, 'arrow_right', 'ov_navigator_info_button_icon');
- this.button.addEventListener ('click', () => {
- this.OnButtonClick ();
- });
- }
-
- Init (callbacks)
- {
- this.callbacks = callbacks;
- }
-
- OnButtonClick ()
- {
-
- }
-
- Clear ()
- {
- if (this.popup !== null) {
- this.popup.Hide ();
- this.popup = null;
- }
- }
-};
-
-OV.NavigatorMeshesPopupButton = class extends OV.NavigatorPopupButton
-{
- constructor (parentDiv)
- {
- super (parentDiv);
- this.meshInfoArray = null;
- }
-
- Update (meshInfoArray)
- {
- this.meshInfoArray = meshInfoArray;
- if (this.meshInfoArray === null) {
- return;
- }
-
- let meshesText = 'Meshes (' + this.meshInfoArray.length + ')';
- this.buttonText.innerHTML = meshesText;
- }
-
- OnButtonClick ()
- {
- if (this.meshInfoArray === null) {
- return;
- }
-
- let meshItems = [];
- for (let i = 0; i < this.meshInfoArray.length; i++) {
- let meshInfo = this.meshInfoArray[i];
- meshItems.push ({
- name : OV.GetMeshName (meshInfo.name)
- });
- }
-
- if (meshItems.length === 0) {
- return;
- }
-
- this.popup = OV.ShowListPopup (meshItems, {
- calculatePosition : (contentDiv) => {
- return OV.CalculatePopupPositionToElementBottomRight (this.button, contentDiv);
- },
- onHoverStart : (index) => {
- const meshData = this.meshInfoArray[index];
- this.callbacks.onMeshHover (meshData.meshId);
- },
- onHoverStop : (index) => {
- this.callbacks.onMeshHover (null);
- },
- onClick : (index) => {
- const meshData = this.meshInfoArray[index];
- this.callbacks.onMeshSelected (meshData.meshId);
- }
- });
- }
-};
-
OV.NavigatorMaterialsPopupButton = class extends OV.NavigatorPopupButton
{
constructor (parentDiv)
@@ -139,193 +48,6 @@ OV.NavigatorMaterialsPopupButton = class extends OV.NavigatorPopupButton
}
};
-OV.NavigatorPanel = class extends OV.Panel
-{
- constructor (parentDiv)
- {
- super (parentDiv);
- this.callbacks = null;
-
- this.titleDiv = OV.AddDiv (this.panelDiv, 'ov_navigator_tree_title');
- this.treeDiv = OV.AddDiv (this.panelDiv, 'ov_navigator_tree_panel ov_thin_scrollbar');
- this.treeView = new OV.TreeView (this.treeDiv);
-
- let panelName = this.GetName ();
- this.titleDiv.innerHTML = panelName;
- this.titleDiv.setAttribute ('title', panelName);
- }
-
- Clear ()
- {
- this.treeView.Clear ();
- }
-
- GetName ()
- {
- return null;
- }
-
- Init (callbacks)
- {
- this.callbacks = callbacks;
- }
-
- Fill (importResult)
- {
-
- }
-};
-
-OV.NavigatorFilesPanel = class extends OV.NavigatorPanel
-{
- constructor (parentDiv)
- {
- super (parentDiv);
- }
-
- GetName ()
- {
- return 'Files';
- }
-
- GetIcon ()
- {
- return 'files';
- }
-
- Resize ()
- {
- let titleHeight = OV.GetDomElementOuterHeight (this.titleDiv);
- let height = this.parentDiv.offsetHeight;
- OV.SetDomElementHeight (this.treeDiv, height - titleHeight);
- }
-
- Clear ()
- {
- super.Clear ();
- }
-
- Fill (importResult)
- {
- super.Fill (importResult);
- const usedFiles = importResult.usedFiles;
- const missingFiles = importResult.missingFiles;
-
- if (missingFiles.length > 0) {
- let missingFilesItem = new OV.TreeViewGroupItem ('Missing Files', null);
- missingFilesItem.ShowChildren (true);
- this.treeView.AddChild (missingFilesItem);
- for (let i = 0; i < missingFiles.length; i++) {
- let file = missingFiles[i];
- let item = new OV.TreeViewButtonItem (file);
- let browseButton = new OV.TreeViewButton ('open');
- browseButton.OnClick (() => {
- this.callbacks.onFileBrowseButtonClicked ();
- });
- item.AppendButton (browseButton);
- missingFilesItem.AddChild (item);
- }
- let filesItem = new OV.TreeViewGroupItem ('Available Files', null);
- filesItem.ShowChildren (true);
- this.treeView.AddChild (filesItem);
- for (let i = 0; i < usedFiles.length; i++) {
- let file = usedFiles[i];
- let item = new OV.TreeViewSingleItem (file);
- filesItem.AddChild (item);
- }
- } else {
- for (let i = 0; i < usedFiles.length; i++) {
- let file = usedFiles[i];
- let item = new OV.TreeViewSingleItem (file);
- this.treeView.AddChild (item);
- }
- }
- }
-};
-
-OV.NavigatorMaterialsPanel = class extends OV.NavigatorPanel
-{
- constructor (parentDiv)
- {
- super (parentDiv);
- this.callbacks = null;
- this.materialIndexToItem = new Map ();
-
- this.popupDiv = OV.AddDiv (this.panelDiv, 'ov_navigator_info_panel');
- this.meshesButton = new OV.NavigatorMeshesPopupButton (this.popupDiv);
- }
-
- GetName ()
- {
- return 'Materials';
- }
-
- GetIcon ()
- {
- return 'materials';
- }
-
- Resize ()
- {
- let titleHeight = OV.GetDomElementOuterHeight (this.titleDiv);
- let popupHeight = OV.GetDomElementOuterHeight (this.popupDiv);
- let height = this.parentDiv.offsetHeight;
- OV.SetDomElementHeight (this.treeDiv, height - titleHeight - popupHeight);
- }
-
- Clear ()
- {
- super.Clear ();
- this.meshesButton.Clear ();
- this.materialIndexToItem = new Map ();
- }
-
- Init (callbacks)
- {
- super.Init (callbacks);
- this.meshesButton.Init ({
- onMeshHover : (meshInstanceId) => {
- this.callbacks.onMeshTemporarySelected (meshInstanceId);
- },
- onMeshSelected : (meshInstanceId) => {
- this.callbacks.onMeshSelected (meshInstanceId);
- }
- });
- }
-
- Fill (importResult)
- {
- super.Fill (importResult);
- const model = importResult.model;
- for (let materialIndex = 0; materialIndex < model.MaterialCount (); materialIndex++) {
- let material = model.GetMaterial (materialIndex);
- let materialName = OV.GetMaterialName (material.name);
- let materialItem = new OV.MaterialItem (materialName, materialIndex, {
- onSelected : (materialIndex) => {
- this.callbacks.onMaterialSelected (materialIndex);
- }
- });
- this.materialIndexToItem.set (materialIndex, materialItem);
- this.treeView.AddChild (materialItem);
- }
- }
-
- GetMaterialItem (materialIndex)
- {
- return this.materialIndexToItem.get (materialIndex);
- }
-
- SelectMaterialItem (materialIndex, isSelected)
- {
- this.GetMaterialItem (materialIndex).SetSelected (isSelected);
- }
-
- UpdateMeshList (meshInfoArray)
- {
- this.meshesButton.Update (meshInfoArray);
- }
-};
-
OV.NavigatorMeshesPanel = class extends OV.NavigatorPanel
{
constructor (parentDiv)
diff --git a/website/o3dv/js/navigatorpanel.js b/website/o3dv/js/navigatorpanel.js
new file mode 100644
index 0000000..8316d39
--- /dev/null
+++ b/website/o3dv/js/navigatorpanel.js
@@ -0,0 +1,71 @@
+OV.NavigatorPopupButton = class
+{
+ constructor (parentDiv)
+ {
+ this.parentDiv = parentDiv;
+ this.callbacks = null;
+ this.popup = null;
+
+ this.button = OV.AddDiv (this.parentDiv, 'ov_navigator_info_button');
+ this.buttonText = OV.AddDiv (this.button, 'ov_navigator_info_button_text');
+ OV.AddSvgIconElement (this.button, 'arrow_right', 'ov_navigator_info_button_icon');
+ this.button.addEventListener ('click', () => {
+ this.OnButtonClick ();
+ });
+ }
+
+ Init (callbacks)
+ {
+ this.callbacks = callbacks;
+ }
+
+ OnButtonClick ()
+ {
+
+ }
+
+ Clear ()
+ {
+ if (this.popup !== null) {
+ this.popup.Hide ();
+ this.popup = null;
+ }
+ }
+};
+
+OV.NavigatorPanel = class extends OV.Panel
+{
+ constructor (parentDiv)
+ {
+ super (parentDiv);
+ this.callbacks = null;
+
+ this.titleDiv = OV.AddDiv (this.panelDiv, 'ov_navigator_tree_title');
+ this.treeDiv = OV.AddDiv (this.panelDiv, 'ov_navigator_tree_panel ov_thin_scrollbar');
+ this.treeView = new OV.TreeView (this.treeDiv);
+
+ let panelName = this.GetName ();
+ this.titleDiv.innerHTML = panelName;
+ this.titleDiv.setAttribute ('title', panelName);
+ }
+
+ Clear ()
+ {
+ this.treeView.Clear ();
+ }
+
+ GetName ()
+ {
+ return null;
+ }
+
+ Init (callbacks)
+ {
+ this.callbacks = callbacks;
+ }
+
+ Fill (importResult)
+ {
+
+ }
+};
diff --git a/website/o3dv/js/sidebar.js b/website/o3dv/js/sidebar.js
index 2d866b0..64ef49d 100644
--- a/website/o3dv/js/sidebar.js
+++ b/website/o3dv/js/sidebar.js
@@ -6,8 +6,8 @@ OV.Sidebar = class
this.splitterDiv = splitterDiv;
this.panelSet = new OV.PanelSet (mainDiv);
- this.detailsPanel = new OV.DetailsSidebarPanel (this.panelSet.GetContentDiv ());
- this.settingsPanel = new OV.SettingsSidebarPanel (this.panelSet.GetContentDiv (), settings);
+ this.detailsPanel = new OV.SidebarDetailsPanel (this.panelSet.GetContentDiv ());
+ this.settingsPanel = new OV.SidebarSettingsPanel (this.panelSet.GetContentDiv (), settings);
this.panelSet.AddPanel (this.detailsPanel);
this.panelSet.AddPanel (this.settingsPanel);
diff --git a/website/o3dv/js/sidebardetailspanel.js b/website/o3dv/js/sidebardetailspanel.js
new file mode 100644
index 0000000..0127db3
--- /dev/null
+++ b/website/o3dv/js/sidebardetailspanel.js
@@ -0,0 +1,171 @@
+OV.SidebarDetailsPanel = class extends OV.SidebarPanel
+{
+ constructor (parentDiv)
+ {
+ super (parentDiv);
+ }
+
+ GetName ()
+ {
+ return 'Details';
+ }
+
+ GetIcon ()
+ {
+ return 'details';
+ }
+
+ AddObject3DProperties (object3D)
+ {
+ this.Clear ();
+ let table = OV.AddDiv (this.contentDiv, 'ov_property_table');
+ let boundingBox = OV.GetBoundingBox (object3D);
+ let size = OV.SubCoord3D (boundingBox.max, boundingBox.min);
+ this.AddProperty (table, new OV.Property (OV.PropertyType.Integer, 'Vertices', object3D.VertexCount ()));
+ this.AddProperty (table, new OV.Property (OV.PropertyType.Integer, 'Triangles', object3D.TriangleCount ()));
+ this.AddProperty (table, new OV.Property (OV.PropertyType.Number, 'Size X', size.x));
+ this.AddProperty (table, new OV.Property (OV.PropertyType.Number, 'Size Y', size.y));
+ this.AddProperty (table, new OV.Property (OV.PropertyType.Number, 'Size Z', size.z));
+ this.AddCalculatedProperty (table, 'Volume', () => {
+ const volume = OV.CalculateVolume (object3D);
+ if (volume === null) {
+ return null;
+ }
+ return new OV.Property (OV.PropertyType.Number, null, volume);
+ });
+ this.AddCalculatedProperty (table, 'Surface', () => {
+ const volume = OV.CalculateSurfaceArea (object3D);
+ if (volume === null) {
+ return null;
+ }
+ return new OV.Property (OV.PropertyType.Number, null, volume);
+ });
+ if (object3D.PropertyGroupCount () > 0) {
+ let customTable = OV.AddDiv (this.contentDiv, 'ov_property_table ov_property_table_custom');
+ for (let i = 0; i < object3D.PropertyGroupCount (); i++) {
+ const propertyGroup = object3D.GetPropertyGroup (i);
+ this.AddPropertyGroup (customTable, propertyGroup);
+ for (let j = 0; j < propertyGroup.PropertyCount (); j++) {
+ const property = propertyGroup.GetProperty (j);
+ this.AddPropertyInGroup (customTable, property);
+ }
+ }
+ }
+ this.Resize ();
+ }
+
+ AddMaterialProperties (material)
+ {
+ function AddTextureMap (obj, table, name, map)
+ {
+ if (map === null || map.name === null) {
+ return;
+ }
+ let fileName = OV.GetFileName (map.name);
+ obj.AddProperty (table, new OV.Property (OV.PropertyType.Text, name, fileName));
+ }
+
+ this.Clear ();
+ let table = OV.AddDiv (this.contentDiv, 'ov_property_table');
+ let typeString = null;
+ if (material.type === OV.MaterialType.Phong) {
+ typeString = 'Phong';
+ } else if (material.type === OV.MaterialType.Physical) {
+ typeString = 'Physical';
+ }
+ this.AddProperty (table, new OV.Property (OV.PropertyType.Text, 'Source', material.isDefault ? 'Default' : 'Model'));
+ this.AddProperty (table, new OV.Property (OV.PropertyType.Text, 'Type', typeString));
+ this.AddProperty (table, new OV.Property (OV.PropertyType.Color, 'Color', material.color));
+ if (material.type === OV.MaterialType.Phong) {
+ this.AddProperty (table, new OV.Property (OV.PropertyType.Color, 'Ambient', material.ambient));
+ this.AddProperty (table, new OV.Property (OV.PropertyType.Color, 'Specular', material.specular));
+ } else if (material.type === OV.MaterialType.Physical) {
+ this.AddProperty (table, new OV.Property (OV.PropertyType.Percent, 'Metalness', material.metalness));
+ this.AddProperty (table, new OV.Property (OV.PropertyType.Percent, 'Roughness', material.roughness));
+ }
+ this.AddProperty (table, new OV.Property (OV.PropertyType.Percent, 'Opacity', material.opacity));
+ AddTextureMap (this, table, 'Diffuse Map', material.diffuseMap);
+ AddTextureMap (this, table, 'Bump Map', material.bumpMap);
+ AddTextureMap (this, table, 'Normal Map', material.normalMap);
+ AddTextureMap (this, table, 'Emissive Map', material.emissiveMap);
+ if (material.type === OV.MaterialType.Phong) {
+ AddTextureMap (this, table, 'Specular Map', material.specularMap);
+ } else if (material.type === OV.MaterialType.Physical) {
+ AddTextureMap (this, table, 'Metallic Map', material.metalnessMap);
+ }
+ this.Resize ();
+ }
+
+ AddPropertyGroup (table, propertyGroup)
+ {
+ let row = OV.AddDiv (table, 'ov_property_table_row group', propertyGroup.name);
+ row.setAttribute ('title', propertyGroup.name);
+ }
+
+ AddProperty (table, property)
+ {
+ let row = OV.AddDiv (table, 'ov_property_table_row');
+ let nameColumn = OV.AddDiv (row, 'ov_property_table_cell ov_property_table_name', property.name + ':');
+ let valueColumn = OV.AddDiv (row, 'ov_property_table_cell ov_property_table_value');
+ nameColumn.setAttribute ('title', property.name);
+ this.DisplayPropertyValue (property, valueColumn);
+ return row;
+ }
+
+ AddPropertyInGroup (table, property)
+ {
+ let row = this.AddProperty (table, property);
+ row.classList.add ('ingroup');
+ }
+
+ AddCalculatedProperty (table, name, calculateValue)
+ {
+ let row = OV.AddDiv (table, 'ov_property_table_row');
+ let nameColumn = OV.AddDiv (row, 'ov_property_table_cell ov_property_table_name', name + ':');
+ let valueColumn = OV.AddDiv (row, 'ov_property_table_cell ov_property_table_value');
+ nameColumn.setAttribute ('title', name);
+
+ let calculateButton = OV.AddDiv (valueColumn, 'ov_property_table_button', 'Calculate...');
+ calculateButton.addEventListener ('click', () => {
+ OV.ClearDomElement (valueColumn);
+ valueColumn.innerHTML = 'Please wait...';
+ OV.RunTaskAsync (() => {
+ let propertyValue = calculateValue ();
+ if (propertyValue === null) {
+ valueColumn.innerHTML = '-';
+ } else {
+ this.DisplayPropertyValue (propertyValue, valueColumn);
+ }
+ });
+ });
+ }
+
+ DisplayPropertyValue (property, targetDiv)
+ {
+ OV.ClearDomElement (targetDiv);
+ let valueText = null;
+ if (property.type === OV.PropertyType.Text) {
+ valueText = property.value;
+ } else if (property.type === OV.PropertyType.Integer) {
+ valueText = property.value.toLocaleString ();
+ } else if (property.type === OV.PropertyType.Number) {
+ valueText = property.value.toLocaleString (undefined, {
+ minimumFractionDigits: 2,
+ maximumFractionDigits: 2
+ });
+ } else if (property.type === OV.PropertyType.Boolean) {
+ valueText = property.value ? 'True' : 'False';
+ } else if (property.type === OV.PropertyType.Percent) {
+ valueText = parseInt (property.value * 100, 10).toString () + '%';
+ } else if (property.type === OV.PropertyType.Color) {
+ let hexString = '#' + OV.ColorToHexString (property.value);
+ let colorCircle = OV.CreateInlineColorCircle (property.value);
+ targetDiv.appendChild (colorCircle);
+ OV.AddDomElement (targetDiv, 'span', null, hexString);
+ }
+ if (valueText !== null) {
+ targetDiv.innerHTML = valueText;
+ targetDiv.setAttribute ('title', valueText);
+ }
+ }
+};
diff --git a/website/o3dv/js/sidebarpanel.js b/website/o3dv/js/sidebarpanel.js
new file mode 100644
index 0000000..b1a6267
--- /dev/null
+++ b/website/o3dv/js/sidebarpanel.js
@@ -0,0 +1,30 @@
+OV.SidebarPanel = class extends OV.Panel
+{
+ constructor (parentDiv)
+ {
+ super (parentDiv);
+ this.callbacks = null;
+
+ this.titleDiv = OV.AddDiv (this.panelDiv, 'ov_sidebar_title');
+ this.contentDiv = OV.AddDiv (this.panelDiv, 'ov_sidebar_content ov_thin_scrollbar');
+
+ let panelName = this.GetName ();
+ OV.AddDiv (this.titleDiv, 'ov_sidebar_title_text', this.GetName ());
+ this.titleDiv.setAttribute ('title', panelName);
+ }
+
+ GetName ()
+ {
+ return null;
+ }
+
+ Clear ()
+ {
+ OV.ClearDomElement (this.contentDiv);
+ }
+
+ Init (callbacks)
+ {
+ this.callbacks = callbacks;
+ }
+};
diff --git a/website/o3dv/js/sidebarpanels.js b/website/o3dv/js/sidebarsettingspanel.js
similarity index 57%
rename from website/o3dv/js/sidebarpanels.js
rename to website/o3dv/js/sidebarsettingspanel.js
index 237c2c5..b0e8662 100644
--- a/website/o3dv/js/sidebarpanels.js
+++ b/website/o3dv/js/sidebarsettingspanel.js
@@ -1,207 +1,4 @@
-OV.SidebarPanel = class extends OV.Panel
-{
- constructor (parentDiv)
- {
- super (parentDiv);
- this.callbacks = null;
-
- this.titleDiv = OV.AddDiv (this.panelDiv, 'ov_sidebar_title');
- this.contentDiv = OV.AddDiv (this.panelDiv, 'ov_sidebar_content ov_thin_scrollbar');
-
- let panelName = this.GetName ();
- OV.AddDiv (this.titleDiv, 'ov_sidebar_title_text', this.GetName ());
- this.titleDiv.setAttribute ('title', panelName);
- }
-
- GetName ()
- {
- return null;
- }
-
- Clear ()
- {
- OV.ClearDomElement (this.contentDiv);
- }
-
- Init (callbacks)
- {
- this.callbacks = callbacks;
- }
-};
-
-OV.DetailsSidebarPanel = class extends OV.SidebarPanel
-{
- constructor (parentDiv)
- {
- super (parentDiv);
- }
-
- GetName ()
- {
- return 'Details';
- }
-
- GetIcon ()
- {
- return 'details';
- }
-
- AddObject3DProperties (object3D)
- {
- this.Clear ();
- let table = OV.AddDiv (this.contentDiv, 'ov_property_table');
- let boundingBox = OV.GetBoundingBox (object3D);
- let size = OV.SubCoord3D (boundingBox.max, boundingBox.min);
- this.AddProperty (table, new OV.Property (OV.PropertyType.Integer, 'Vertices', object3D.VertexCount ()));
- this.AddProperty (table, new OV.Property (OV.PropertyType.Integer, 'Triangles', object3D.TriangleCount ()));
- this.AddProperty (table, new OV.Property (OV.PropertyType.Number, 'Size X', size.x));
- this.AddProperty (table, new OV.Property (OV.PropertyType.Number, 'Size Y', size.y));
- this.AddProperty (table, new OV.Property (OV.PropertyType.Number, 'Size Z', size.z));
- this.AddCalculatedProperty (table, 'Volume', () => {
- const volume = OV.CalculateVolume (object3D);
- if (volume === null) {
- return null;
- }
- return new OV.Property (OV.PropertyType.Number, null, volume);
- });
- this.AddCalculatedProperty (table, 'Surface', () => {
- const volume = OV.CalculateSurfaceArea (object3D);
- if (volume === null) {
- return null;
- }
- return new OV.Property (OV.PropertyType.Number, null, volume);
- });
- if (object3D.PropertyGroupCount () > 0) {
- let customTable = OV.AddDiv (this.contentDiv, 'ov_property_table ov_property_table_custom');
- for (let i = 0; i < object3D.PropertyGroupCount (); i++) {
- const propertyGroup = object3D.GetPropertyGroup (i);
- this.AddPropertyGroup (customTable, propertyGroup);
- for (let j = 0; j < propertyGroup.PropertyCount (); j++) {
- const property = propertyGroup.GetProperty (j);
- this.AddPropertyInGroup (customTable, property);
- }
- }
- }
- this.Resize ();
- }
-
- AddMaterialProperties (material)
- {
- function AddTextureMap (obj, table, name, map)
- {
- if (map === null || map.name === null) {
- return;
- }
- let fileName = OV.GetFileName (map.name);
- obj.AddProperty (table, new OV.Property (OV.PropertyType.Text, name, fileName));
- }
-
- this.Clear ();
- let table = OV.AddDiv (this.contentDiv, 'ov_property_table');
- let typeString = null;
- if (material.type === OV.MaterialType.Phong) {
- typeString = 'Phong';
- } else if (material.type === OV.MaterialType.Physical) {
- typeString = 'Physical';
- }
- this.AddProperty (table, new OV.Property (OV.PropertyType.Text, 'Source', material.isDefault ? 'Default' : 'Model'));
- this.AddProperty (table, new OV.Property (OV.PropertyType.Text, 'Type', typeString));
- this.AddProperty (table, new OV.Property (OV.PropertyType.Color, 'Color', material.color));
- if (material.type === OV.MaterialType.Phong) {
- this.AddProperty (table, new OV.Property (OV.PropertyType.Color, 'Ambient', material.ambient));
- this.AddProperty (table, new OV.Property (OV.PropertyType.Color, 'Specular', material.specular));
- } else if (material.type === OV.MaterialType.Physical) {
- this.AddProperty (table, new OV.Property (OV.PropertyType.Percent, 'Metalness', material.metalness));
- this.AddProperty (table, new OV.Property (OV.PropertyType.Percent, 'Roughness', material.roughness));
- }
- this.AddProperty (table, new OV.Property (OV.PropertyType.Percent, 'Opacity', material.opacity));
- AddTextureMap (this, table, 'Diffuse Map', material.diffuseMap);
- AddTextureMap (this, table, 'Bump Map', material.bumpMap);
- AddTextureMap (this, table, 'Normal Map', material.normalMap);
- AddTextureMap (this, table, 'Emissive Map', material.emissiveMap);
- if (material.type === OV.MaterialType.Phong) {
- AddTextureMap (this, table, 'Specular Map', material.specularMap);
- } else if (material.type === OV.MaterialType.Physical) {
- AddTextureMap (this, table, 'Metallic Map', material.metalnessMap);
- }
- this.Resize ();
- }
-
- AddPropertyGroup (table, propertyGroup)
- {
- let row = OV.AddDiv (table, 'ov_property_table_row group', propertyGroup.name);
- row.setAttribute ('title', propertyGroup.name);
- }
-
- AddProperty (table, property)
- {
- let row = OV.AddDiv (table, 'ov_property_table_row');
- let nameColumn = OV.AddDiv (row, 'ov_property_table_cell ov_property_table_name', property.name + ':');
- let valueColumn = OV.AddDiv (row, 'ov_property_table_cell ov_property_table_value');
- nameColumn.setAttribute ('title', property.name);
- this.DisplayPropertyValue (property, valueColumn);
- return row;
- }
-
- AddPropertyInGroup (table, property)
- {
- let row = this.AddProperty (table, property);
- row.classList.add ('ingroup');
- }
-
- AddCalculatedProperty (table, name, calculateValue)
- {
- let row = OV.AddDiv (table, 'ov_property_table_row');
- let nameColumn = OV.AddDiv (row, 'ov_property_table_cell ov_property_table_name', name + ':');
- let valueColumn = OV.AddDiv (row, 'ov_property_table_cell ov_property_table_value');
- nameColumn.setAttribute ('title', name);
-
- let calculateButton = OV.AddDiv (valueColumn, 'ov_property_table_button', 'Calculate...');
- calculateButton.addEventListener ('click', () => {
- OV.ClearDomElement (valueColumn);
- valueColumn.innerHTML = 'Please wait...';
- OV.RunTaskAsync (() => {
- let propertyValue = calculateValue ();
- if (propertyValue === null) {
- valueColumn.innerHTML = '-';
- } else {
- this.DisplayPropertyValue (propertyValue, valueColumn);
- }
- });
- });
- }
-
- DisplayPropertyValue (property, targetDiv)
- {
- OV.ClearDomElement (targetDiv);
- let valueText = null;
- if (property.type === OV.PropertyType.Text) {
- valueText = property.value;
- } else if (property.type === OV.PropertyType.Integer) {
- valueText = property.value.toLocaleString ();
- } else if (property.type === OV.PropertyType.Number) {
- valueText = property.value.toLocaleString (undefined, {
- minimumFractionDigits: 2,
- maximumFractionDigits: 2
- });
- } else if (property.type === OV.PropertyType.Boolean) {
- valueText = property.value ? 'True' : 'False';
- } else if (property.type === OV.PropertyType.Percent) {
- valueText = parseInt (property.value * 100, 10).toString () + '%';
- } else if (property.type === OV.PropertyType.Color) {
- let hexString = '#' + OV.ColorToHexString (property.value);
- let colorCircle = OV.CreateInlineColorCircle (property.value);
- targetDiv.appendChild (colorCircle);
- OV.AddDomElement (targetDiv, 'span', null, hexString);
- }
- if (valueText !== null) {
- targetDiv.innerHTML = valueText;
- targetDiv.setAttribute ('title', valueText);
- }
- }
-};
-
-OV.SettingsSidebarPanel = class extends OV.SidebarPanel
+OV.SidebarSettingsPanel = class extends OV.SidebarPanel
{
constructor (parentDiv, settings)
{