diff --git a/ShadowEditor.Web/src/component/object/SkyComponent.js b/ShadowEditor.Web/src/component/object/SkyComponent.js new file mode 100644 index 00000000..a8cac329 --- /dev/null +++ b/ShadowEditor.Web/src/component/object/SkyComponent.js @@ -0,0 +1,174 @@ +import BaseComponent from '../BaseComponent'; +import Sky from '../../object/Sky'; + +/** + * 天空组件 + * @author tengge / https://github.com/tengge1 + * @param {*} options + */ +function SkyComponent(options) { + BaseComponent.call(this, options); + this.selected = null; +} + +SkyComponent.prototype = Object.create(BaseComponent.prototype); +SkyComponent.prototype.constructor = SkyComponent; + +SkyComponent.prototype.render = function () { + var data = { + xtype: 'div', + parent: this.parent, + id: 'skyPanel', + scope: this.id, + cls: 'Panel', + style: { + display: 'none' + }, + children: [{ + xtype: 'row', + children: [{ + xtype: 'label', + style: { + width: '100%', + color: '#555', + fontWeight: 'bold' + }, + text: '天空' + }] + }, { + xtype: 'row', + children: [{ + xtype: 'label', + text: '浑浊度' + }, { + xtype: 'number', + id: 'turbidity', + scope: this.id, + range: [0, Infinity], + value: 10, + onChange: this.onChange.bind(this) + }] + }, { + xtype: 'row', + children: [{ + xtype: 'label', + text: '瑞利' + }, { + xtype: 'number', + id: 'rayleigh', + scope: this.id, + range: [0, Infinity], + value: 2, + onChange: this.onChange.bind(this) + }] + }, { + xtype: 'row', + children: [{ + xtype: 'label', + text: '亮度' + }, { + xtype: 'number', + id: 'luminance', + scope: this.id, + range: [0, Infinity], + value: 1, + onChange: this.onChange.bind(this) + }] + }, { + xtype: 'row', + children: [{ + xtype: 'label', + text: 'Mie系数' + }, { + xtype: 'number', + id: 'mieCoefficient', + scope: this.id, + range: [0, Infinity], + value: 0.005, + unit: '%', + onChange: this.onChange.bind(this) + }] + }, { + xtype: 'row', + children: [{ + xtype: 'label', + text: 'Mie方向' + }, { + xtype: 'number', + id: 'mieDirectionalG', + scope: this.id, + range: [0, Infinity], + value: 0.005, + onChange: this.onChange.bind(this) + }] + }] + }; + + 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)); +}; + +SkyComponent.prototype.onObjectSelected = function () { + this.updateUI(); +}; + +SkyComponent.prototype.onObjectChanged = function () { + this.updateUI(); +}; + +SkyComponent.prototype.updateUI = function () { + var container = UI.get('skyPanel', this.id); + var editor = this.app.editor; + if (editor.selected && editor.selected instanceof Sky) { + container.dom.style.display = ''; + } else { + container.dom.style.display = 'none'; + return; + } + + this.selected = editor.selected; + + var turbidity = UI.get('turbidity', this.id); + var rayleigh = UI.get('rayleigh', this.id); + var luminance = UI.get('luminance', this.id); + var mieCoefficient = UI.get('mieCoefficient', this.id); + var mieDirectionalG = UI.get('mieDirectionalG', this.id); + + turbidity.setValue(this.selected.userData.turbidity); + rayleigh.setValue(this.selected.userData.rayleigh); + luminance.setValue(this.selected.userData.luminance); + mieCoefficient.setValue(this.selected.userData.mieCoefficient * 100); + mieDirectionalG.setValue(this.selected.userData.mieDirectionalG); +}; + +SkyComponent.prototype.onChange = function () { + var turbidity = UI.get('turbidity', this.id); + var rayleigh = UI.get('rayleigh', this.id); + var luminance = UI.get('luminance', this.id); + var mieCoefficient = UI.get('mieCoefficient', this.id); + var mieDirectionalG = UI.get('mieDirectionalG', this.id); + + this.selected.userData.turbidity = turbidity.getValue(); + this.selected.userData.rayleigh = rayleigh.getValue(); + this.selected.userData.luminance = luminance.getValue(); + this.selected.userData.mieCoefficient = mieCoefficient.getValue() / 100; + this.selected.userData.mieDirectionalG = mieDirectionalG.getValue(); + + var sky = this.selected.children.filter(n => n instanceof THREE.Sky)[0]; + if (sky) { + var uniforms = sky.material.uniforms; + uniforms.turbidity.value = turbidity.getValue(); + uniforms.rayleigh.value = rayleigh.getValue(); + uniforms.luminance.value = luminance.getValue(); + uniforms.mieCoefficient.value = mieCoefficient.getValue() / 100; + uniforms.mieDirectionalG.value = mieDirectionalG.getValue(); + sky.material.needsUpdate = true; + } + + this.app.call(`objectSelected`, this, this.selected); +}; + +export default SkyComponent; \ No newline at end of file diff --git a/ShadowEditor.Web/src/editor/sidebar/PropertyPanel.js b/ShadowEditor.Web/src/editor/sidebar/PropertyPanel.js index 97ec1586..2c3995d3 100644 --- a/ShadowEditor.Web/src/editor/sidebar/PropertyPanel.js +++ b/ShadowEditor.Web/src/editor/sidebar/PropertyPanel.js @@ -17,6 +17,7 @@ import ReflectorComponent from '../../component/ReflectorComponent'; import LMeshComponent from '../../component/LMeshComponent'; import MMDComponent from '../../component/MMDComponent'; import RigidBodyComponent from '../../component/physics/RigidBodyComponent'; +import SkyComponent from '../../component/object/SkyComponent'; /** * 属性面板 @@ -43,6 +44,7 @@ PropertyPanel.prototype.render = function () { new LightComponent({ app: this.app }), new ShadowComponent({ app: this.app }), new ReflectorComponent({ app: this.app }), + new SkyComponent({ app: this.app }), new AudioListenerComponent({ app: this.app }), new BackgroundMusicComponent({ app: this.app }), new PhysicsWorldComponent({ app: this.app }), diff --git a/ShadowEditor.Web/src/object/Sky.js b/ShadowEditor.Web/src/object/Sky.js index aaee63c8..fc3dad4a 100644 --- a/ShadowEditor.Web/src/object/Sky.js +++ b/ShadowEditor.Web/src/object/Sky.js @@ -8,7 +8,7 @@ function Sky(options) { options = options || {}; var turbidity = options.turbidity || 10; // 浑浊度 - var rayleigh = options.rayleigh || 2; + var rayleigh = options.rayleigh || 2; // 瑞利 var luminance = options.luminance || 1; // 亮度 var mieCoefficient = options.mieCoefficient || 0.005; var mieDirectionalG = options.mieDirectionalG || 0.8; @@ -45,7 +45,7 @@ function Sky(options) { uniforms.sunPosition.value.copy(sunSphere.position); this.userData = { - type: 'sky', + type: 'Sky', turbidity: turbidity, rayleigh: rayleigh, luminance: luminance,