diff --git a/ShadowEditor.Web/src/component/ControlComponent.js b/ShadowEditor.Web/src/component/control/ControlComponent.js similarity index 82% rename from ShadowEditor.Web/src/component/ControlComponent.js rename to ShadowEditor.Web/src/component/control/ControlComponent.js index 9b8a5b06..655978f4 100644 --- a/ShadowEditor.Web/src/component/ControlComponent.js +++ b/ShadowEditor.Web/src/component/control/ControlComponent.js @@ -1,7 +1,4 @@ -import BaseComponent from './BaseComponent'; -import SetValueCommand from '../command/SetValueCommand'; -import RemoveObjectCommand from '../command/RemoveObjectCommand'; -import AddObjectCommand from '../command/AddObjectCommand'; +import BaseComponent from '../BaseComponent'; /** * 控制组件 @@ -35,7 +32,7 @@ ControlComponent.prototype.render = function () { color: '#555', fontWeight: 'bold' }, - text: '场景控制' + text: '场景控制器' }] }, { xtype: 'row', @@ -48,7 +45,7 @@ ControlComponent.prototype.render = function () { scope: this.id, options: { '': '无', - 'FirstPersonControls': '第一人称控制器', + 'FirstPersonControls': '第一视角控制器', 'FlyControls': '飞行控制器', 'OrbitControls': '轨道控制器', 'PointerLockControls': '指针锁定控制器', @@ -56,14 +53,6 @@ ControlComponent.prototype.render = function () { }, onChange: this.onChangeType.bind(this) }] - }, { - xtype: 'row', - children: [{ - xtype: 'label', - text: '类型' - }, { - xtype: 'input' - }] }] }; diff --git a/ShadowEditor.Web/src/component/control/FirstPersonControlComponent.js b/ShadowEditor.Web/src/component/control/FirstPersonControlComponent.js new file mode 100644 index 00000000..ca2b2f2d --- /dev/null +++ b/ShadowEditor.Web/src/component/control/FirstPersonControlComponent.js @@ -0,0 +1,218 @@ +import BaseComponent from '../BaseComponent'; + +/** + * 第一视角控制器组件 + * @author tengge / https://github.com/tengge1 + * @param {*} options + */ +function FirstPersonControlComponent(options) { + BaseComponent.call(this, options); + this.selected = null; +} + +FirstPersonControlComponent.prototype = Object.create(BaseComponent.prototype); +FirstPersonControlComponent.prototype.constructor = FirstPersonControlComponent; + +FirstPersonControlComponent.prototype.render = function () { + var data = { + xtype: 'div', + id: 'controlPanel', + scope: this.id, + parent: this.parent, + cls: 'Panel', + style: { + borderTop: 0, + display: 'none' + }, + children: [{ + xtype: 'row', + children: [{ + xtype: 'label', + style: { + color: '#555', + fontWeight: 'bold' + }, + text: '第一视角控制器' + }] + }, { + xtype: 'row', + children: [{ + xtype: 'label', + text: 'movementSpeed' + }, { + xtype: 'number', + id: 'movementSpeed', + scope: this.id, + value: 10.0 + }] + }, { + xtype: 'row', + children: [{ + xtype: 'label', + text: 'lookSpeed' + }, { + xtype: 'number', + id: 'lookSpeed', + scope: this.id, + value: 0.05 + }] + }, { + xtype: 'row', + children: [{ + xtype: 'label', + text: 'lookVertical' + }, { + xtype: 'checkbox', + id: 'lookVertical', + scope: this.id, + value: true + }] + }, { + xtype: 'row', + children: [{ + xtype: 'label', + text: 'autoForward' + }, { + xtype: 'checkbox', + id: 'autoForward', + scope: this.id, + value: false + }] + }, { + xtype: 'row', + children: [{ + xtype: 'label', + text: 'activeLook' + }, { + xtype: 'checkbox', + id: 'activeLook', + scope: this.id, + value: true + }] + }, { + xtype: 'row', + children: [{ + xtype: 'label', + text: 'heightSpeed' + }, { + xtype: 'checkbox', + id: 'heightSpeed', + scope: this.id, + value: false + }] + }, { + xtype: 'row', + children: [{ + xtype: 'label', + text: 'heightCoef' + }, { + xtype: 'number', + id: 'heightCoef', + scope: this.id, + value: 1.0 + }] + }, { + xtype: 'row', + children: [{ + xtype: 'label', + text: 'heightMin' + }, { + xtype: 'number', + id: 'heightMin', + scope: this.id, + value: 0.0 + }] + }, { + xtype: 'row', + children: [{ + xtype: 'label', + text: 'heightMax' + }, { + xtype: 'number', + id: 'heightMax', + scope: this.id, + value: 1.0 + }] + }, { + xtype: 'row', + children: [{ + xtype: 'label', + text: 'constrainVertical' + }, { + xtype: 'checkbox', + id: 'constrainVertical', + scope: this.id, + value: false + }] + }, { + xtype: 'row', + children: [{ + xtype: 'label', + text: 'verticalMin' + }, { + xtype: 'number', + id: 'verticalMin', + scope: this.id, + value: 0 + }] + }, { + xtype: 'row', + children: [{ + xtype: 'label', + text: 'verticalMax' + }, { + xtype: 'number', + id: 'verticalMax', + scope: this.id, + value: 3.14 + }] + }] + }; + + var control = UI.create(data); + control.render(); + + this.app.on(`objectSelected.${this.id}`, this.onObjectSelected.bind(this)); + this.app.on(`objectChanged.${this.id}`, this.onObjectChanged.bind(this)); +}; + +FirstPersonControlComponent.prototype.onObjectSelected = function () { + this.updateUI(); +}; + +FirstPersonControlComponent.prototype.onObjectChanged = function () { + this.updateUI(); +}; + +FirstPersonControlComponent.prototype.updateUI = function () { + var container = UI.get('controlPanel', this.id); + var editor = this.app.editor; + if (editor.selected && editor.selected === this.app.editor.camera && editor.selected.userData.control === 'FirstPersonControls') { + container.dom.style.display = ''; + } else { + container.dom.style.display = 'none'; + return; + } + + this.selected = editor.selected; + + var movementSpeed = UI.get('movementSpeed', this.id); + var lookSpeed = UI.get('lookSpeed', this.id); + var lookVertical = UI.get('lookVertical', this.id); + var autoForward = UI.get('autoForward', this.id); + var activeLook = UI.get('activeLook', this.id); + var heightSpeed = UI.get('heightSpeed', this.id); + var heightCoef = UI.get('heightCoef', this.id); + var heightMin = UI.get('heightMin', this.id); + var heightMax = UI.get('heightMax', this.id); + var constrainVertical = UI.get('constrainVertical', this.id); + var verticalMax = UI.get('verticalMax', this.id); +}; + +FirstPersonControlComponent.prototype.onChangeType = function () { + var type = UI.get('type', this.id); + + this.selected.userData.control = type.getValue(); +}; + +export default FirstPersonControlComponent; \ No newline at end of file diff --git a/ShadowEditor.Web/src/component/control/FlyControlComponent.js b/ShadowEditor.Web/src/component/control/FlyControlComponent.js new file mode 100644 index 00000000..e69de29b diff --git a/ShadowEditor.Web/src/component/control/OrbitControlComponent.js b/ShadowEditor.Web/src/component/control/OrbitControlComponent.js new file mode 100644 index 00000000..e69de29b diff --git a/ShadowEditor.Web/src/component/control/PointerLockControlComponent.js b/ShadowEditor.Web/src/component/control/PointerLockControlComponent.js new file mode 100644 index 00000000..e69de29b diff --git a/ShadowEditor.Web/src/component/control/TrackballControlComponent.js b/ShadowEditor.Web/src/component/control/TrackballControlComponent.js new file mode 100644 index 00000000..e69de29b diff --git a/ShadowEditor.Web/src/editor/sidebar/PropertyPanel.js b/ShadowEditor.Web/src/editor/sidebar/PropertyPanel.js index f3361cd6..02a34944 100644 --- a/ShadowEditor.Web/src/editor/sidebar/PropertyPanel.js +++ b/ShadowEditor.Web/src/editor/sidebar/PropertyPanel.js @@ -21,7 +21,8 @@ import SkyComponent from '../../component/object/SkyComponent'; import PerlinTerrainComponent from '../../component/object/PerlinTerrainComponent'; import WaterComponent from '../../component/water/WaterComponent'; import ClothComponent from '../../component/object/ClothComponent'; -import ControlComponent from '../../component/ControlComponent'; +import ControlComponent from '../../component/control/ControlComponent'; +import FirstPersonControlComponent from '../../component/control/FirstPersonControlComponent'; /** * 属性面板 @@ -48,6 +49,7 @@ PropertyPanel.prototype.render = function () { new LightComponent({ app: this.app }), new ShadowComponent({ app: this.app }), new ControlComponent({ app: this.app }), + new FirstPersonControlComponent({ app: this.app }), new ReflectorComponent({ app: this.app }), new SkyComponent({ app: this.app }), new PerlinTerrainComponent({ app: this.app }),