diff --git a/source/client/components/CVOrbitNavigation.ts b/source/client/components/CVOrbitNavigation.ts index 44ec8df3..79348b26 100644 --- a/source/client/components/CVOrbitNavigation.ts +++ b/source/client/components/CVOrbitNavigation.ts @@ -71,7 +71,6 @@ export default class CVOrbitNavigation extends CObject3D protected static readonly ins = { enabled: types.Boolean("Settings.Enabled", true), - type: types.Enum("Settings.Type", ENavigationType, ENavigationType.Orbit), pointerEnabled: types.Boolean("Settings.PointerEnabled", true), promptEnabled: types.Boolean("Settings.PromptEnabled", true), isInUse: types.Boolean("Camera.IsInUse", false), @@ -113,7 +112,6 @@ export default class CVOrbitNavigation extends CObject3D get settingProperties() { return [ this.ins.enabled, - this.ins.type, this.ins.orbit, this.ins.offset, this.ins.pivot, @@ -367,12 +365,12 @@ export default class CVOrbitNavigation extends CObject3D this.ins.copyValues({ enabled: !!data.enabled, - type: ENavigationType[data.type] || ENavigationType.Orbit, autoZoom: !!data.autoZoom, autoRotation: !!data.autoRotation, lightsFollowCamera: !!data.lightsFollowCamera, orbit: orbit.orbit, offset: orbit.offset, + pivot: orbit.pivot || [ 0, 0, 0 ], minOrbit: _replaceNull(orbit.minOrbit, -Infinity), maxOrbit: _replaceNull(orbit.maxOrbit, Infinity), minOffset: _replaceNull(orbit.minOffset, -Infinity), @@ -390,11 +388,12 @@ export default class CVOrbitNavigation extends CObject3D data.autoRotation = ins.autoRotation.value; data.lightsFollowCamera = ins.lightsFollowCamera.value; - data.type = ENavigationType[ins.type.value] as TNavigationType; + data.type = "Orbit"; data.orbit = { orbit: ins.orbit.cloneValue(), offset: ins.offset.cloneValue(), + pivot: ins.pivot.cloneValue(), minOrbit: ins.minOrbit.cloneValue(), maxOrbit: ins.maxOrbit.cloneValue(), minOffset: ins.minOffset.cloneValue(), diff --git a/source/client/schema/json/setup.schema.json b/source/client/schema/json/setup.schema.json index da6a3147..66fa74c2 100644 --- a/source/client/schema/json/setup.schema.json +++ b/source/client/schema/json/setup.schema.json @@ -6,6 +6,20 @@ "description": "Tours and settings for explorer documents (background, interface, etc.)", "definitions": { + "vector3nullable": { + "description": "3-component vector where each member can be null", + "$id": "#vector3", + "type": "array", + "items": { + "oneOf":[ + {"type": "number"}, + {"type": "null"} + ] + }, + "minItems": 3, + "maxItems": 3, + "default": [ 0, 0, 0 ] + }, "viewer": { "type": "object", "properties": { @@ -101,11 +115,29 @@ "type": "boolean" }, "orbit": { - "$comment": "TODO: Implement", - "type": "object", "properties": { - + "orbit":{ + "$ref": "./common.schema.json#/definitions/vector3" + }, + "offset": { + "$ref": "./common.schema.json#/definitions/vector3" + }, + "pivot": { + "$ref": "./common.schema.json#/definitions/vector3" + }, + "minOrbit": { + "$ref": "#/definitions/vector3nullable" + }, + "maxOrbit": { + "$ref": "#/definitions/vector3nullable" + }, + "minOffset": { + "$ref": "#/definitions/vector3nullable" + }, + "maxOffset": { + "$ref": "#/definitions/vector3nullable" + } } }, "walk": { diff --git a/source/client/schema/setup.ts b/source/client/schema/setup.ts index 218b6cac..1e52c4c3 100644 --- a/source/client/schema/setup.ts +++ b/source/client/schema/setup.ts @@ -96,6 +96,7 @@ export interface IOrbitNavigation { orbit: number[]; offset: number[]; + pivot?: number[]; minOrbit: number[]; maxOrbit: number[]; minOffset: number[]; diff --git a/source/client/ui/story/AddNodeMenu.ts b/source/client/ui/story/AddNodeMenu.ts new file mode 100644 index 00000000..f07df23b --- /dev/null +++ b/source/client/ui/story/AddNodeMenu.ts @@ -0,0 +1,152 @@ +// /** +// * 3D Foundation Project +// * Copyright 2021 Smithsonian Institution +// * +// * Licensed under the Apache License, Version 2.0 (the "License"); +// * you may not use this file except in compliance with the License. +// * You may obtain a copy of the License at +// * +// * http://www.apache.org/licenses/LICENSE-2.0 +// * +// * Unless required by applicable law or agreed to in writing, software +// * distributed under the License is distributed on an "AS IS" BASIS, +// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// * See the License for the specific language governing permissions and +// * limitations under the License. +// */ + +// import Popup, { customElement, html } from "@ff/ui/Popup"; + +// import "@ff/ui/Button"; +// import "@ff/ui/TextEdit"; +// import Component from "@ff/graph/Component"; + +// import CVLanguageManager from "client/components/CVLanguageManager"; +// import { CLight } from "client/components/lights/CVLight"; +// import { lightTypes } from "client/applications/coreTypes"; + +// //////////////////////////////////////////////////////////////////////////////// + + +// const nodeTypes :Array =[ +// ...lightTypes +// ]; + + +// @customElement("sv-addnode-menu") +// export default class AddNodeMenu extends Popup +// { +// protected language: CVLanguageManager = null; +// protected errorString: string = ""; +// protected selectIndex :number = -1; +// protected name :string = ""; + +// static show(parent: HTMLElement, language: CVLanguageManager): Promise<[string, typeof Component]> +// { +// const menu = new AddNodeMenu(language); +// parent.appendChild(menu); + +// return new Promise((resolve, reject) => { +// menu.on("confirm", () => resolve([menu.name, nodeTypes[menu.selectIndex]])); +// menu.on("close", () => reject()); +// }); +// } + +// constructor( language: CVLanguageManager) +// { +// super(); + +// this.language = language; +// this.position = "center"; +// this.modal = true; +// const currentLights = this.language.getGraphComponents(CLight); +// for(let idx = 0; !this.name; idx++){ +// let name = `New Light #${idx}`; +// if(!currentLights.find(l=>l.node.name === name)) this.name = name; +// } +// } + +// close() +// { +// this.dispatchEvent(new CustomEvent("close")); +// this.remove(); +// } + +// confirm() +// { +// if(!this.name){ +// this.errorString = "Provide a name for the node"; +// }else if(this.selectIndex === -1){ +// this.errorString = "select a node type"; +// }else{ +// this.errorString = null +// } +// if(this.errorString){ +// this.requestUpdate(); +// }else{ +// this.dispatchEvent(new CustomEvent("confirm")); +// this.remove(); +// } +// } + +// protected firstConnected() +// { +// super.firstConnected(); +// this.classList.add("sv-option-menu", "sv-addnode-menu"); +// } + +// protected renderNodeType(type: typeof Component, index: number) +// { +// return html`
this.onSelect(e, index)} ?selected=${ index === this.selectIndex }> +// ${("icon" in type)? html``:null} +// ${(type as any).text || type.name} +//
`; +// } + +// protected onSelect = (e:MouseEvent, index :number)=>{ +// this.selectIndex = index; +// this.requestUpdate(); +// } + +// protected onNameChange = (ev:Event)=>{ +// this.name = (ev.target as HTMLInputElement).value; +// } + +// protected render() +// { +// const language = this.language; + +// return html` +//
+//
+//
+//
Create new Node
+// +//
+//
+//
+// +//
+//
+//
+//
+//
+//
${language.getLocalizedString("Select Node Type")}:
+//
+//
+//
+// ${nodeTypes.map((NodeType, index) => this.renderNodeType(NodeType, index))} +//
+//
+//
+// +//
+//
+//
${this.errorString}
+//
+//
+//
+// `; +// } + +// }