diff --git a/src/editor/nodes/AudioZoneNode.js b/src/editor/nodes/AudioZoneNode.js index 996db12f3..dac8ff069 100644 --- a/src/editor/nodes/AudioZoneNode.js +++ b/src/editor/nodes/AudioZoneNode.js @@ -1,9 +1,29 @@ -import { Material, BoxBufferGeometry, Mesh, BoxHelper } from "three"; +import { + Material, + BoxBufferGeometry, + LineSegments, + EdgesGeometry, + BoxGeometry, + SphereGeometry, + LineBasicMaterial, + Quaternion +} from "three"; import AudioParams, { AudioElementType } from "../objects/AudioParams"; import AudioParamsNode from "./AudioParamsNode"; const requiredProperties = ["enabled", "inOut", "outIn"]; +const DEBUG_BBAA_COLOR = 0x49ef4; +const debugMaterial = new LineBasicMaterial({ + color: DEBUG_BBAA_COLOR, + linewidth: 2 +}); + +export const AudioZoneShape = Object.freeze({ + Box: "box", + Sphere: "sphere" +}); + export default class AudioZoneNode extends AudioParamsNode(AudioParams) { static componentName = "audio-zone"; @@ -35,6 +55,7 @@ export default class AudioZoneNode extends AudioParamsNode(AudioParams) { node.enabled = zoneProps.enabled; node.inOut = zoneProps.inOut; node.outIn = zoneProps.outIn; + node.shape = zoneProps.shape || AudioZoneShape.Box; return node; } @@ -42,16 +63,42 @@ export default class AudioZoneNode extends AudioParamsNode(AudioParams) { constructor(editor) { super(editor, AudioElementType.AUDIO_ZONE); - const boxMesh = new Mesh(AudioZoneNode._geometry, AudioZoneNode._material); - const box = new BoxHelper(boxMesh, 0x00ff00); - box.layers.set(1); - this.helper = box; - this.add(box); this.enabled = true; this.inOut = true; this.outIn = true; + this.shape = AudioZoneShape.Box; + } + + set shape(shape) { + this._shape = shape; + + this.remove(this.helper); + let geo; + if (shape === AudioZoneShape.Box) { + geo = new BoxGeometry(); + } else { + geo = new SphereGeometry(); + } + const debugMesh = new LineSegments(new EdgesGeometry(geo), debugMaterial); + debugMesh.layers.set(1); + this.helper = debugMesh; + this.add(debugMesh); + this.matrixAutoUpdate = false; } + get shape() { + return this._shape; + } + + onUpdate = (function() { + const quat = new Quaternion(); + return function() { + this.quaternion.set(0, 0, 0, 1); + this.quaternion.multiply(this.parent.getWorldQuaternion(quat).inverse()); + this.updateMatrix(); + }; + })(); + copy(source, recursive = true) { if (recursive) { this.remove(this.helper); @@ -70,6 +117,7 @@ export default class AudioZoneNode extends AudioParamsNode(AudioParams) { this.enabled = source.enabled; this.inOut = source.inOut; this.outIn = source.outIn; + this._shape = source.shape; return this; } @@ -79,7 +127,8 @@ export default class AudioZoneNode extends AudioParamsNode(AudioParams) { "audio-zone": { enabled: this.enabled, inOut: this.inOut, - outIn: this.outIn + outIn: this.outIn, + shape: this.shape } }); } @@ -99,7 +148,8 @@ export default class AudioZoneNode extends AudioParamsNode(AudioParams) { target: this.gltfIndexForUUID(this.target), enabled: this.enabled, inOut: this.inOut, - outIn: this.outIn + outIn: this.outIn, + shape: this.shape }); } } diff --git a/src/ui/properties/AudioZoneNodeEditor.js b/src/ui/properties/AudioZoneNodeEditor.js index 65e4d3067..7fd7e12aa 100644 --- a/src/ui/properties/AudioZoneNodeEditor.js +++ b/src/ui/properties/AudioZoneNodeEditor.js @@ -6,6 +6,13 @@ import BooleanInput from "../inputs/BooleanInput"; import { DiceD6 } from "styled-icons/fa-solid/DiceD6"; import AudioParamsProperties from "./AudioParamsProperties"; import { SourceType } from "../../editor/objects/AudioParams"; +import SelectInput from "../inputs/SelectInput"; +import { AudioZoneShape } from "../../editor/nodes/AudioZoneNode"; + +export const AudioZoneShapeOptions = Object.keys(AudioZoneShape).map(k => ({ + label: k, + value: AudioZoneShape[k] +})); export default class AudioZoneNodeEditor extends Component { static propTypes = { @@ -38,6 +45,10 @@ export default class AudioZoneNodeEditor extends Component { this.props.editor.setPropertySelected("outIn", value); }; + onChangeShape = value => { + this.props.editor.setPropertySelected("shape", value); + }; + componentDidMount() { const options = []; @@ -72,6 +83,9 @@ export default class AudioZoneNodeEditor extends Component { > + + + ); diff --git a/test/integration/snapshots/Editor.test.js.md b/test/integration/snapshots/Editor.test.js.md index 5ed25abac..d83776da0 100644 --- a/test/integration/snapshots/Editor.test.js.md +++ b/test/integration/snapshots/Editor.test.js.md @@ -4477,6 +4477,7 @@ Generated by [AVA](https://avajs.dev). enabled: true, inOut: true, outIn: true, + shape: 'box', }, }, { @@ -6254,6 +6255,7 @@ Generated by [AVA](https://avajs.dev). enabled: true, inOut: true, outIn: true, + shape: 'box', }, }, { @@ -7972,6 +7974,7 @@ Generated by [AVA](https://avajs.dev). enabled: true, inOut: true, outIn: true, + shape: 'box', }, }, { diff --git a/test/integration/snapshots/Editor.test.js.snap b/test/integration/snapshots/Editor.test.js.snap index b29102012..2a7e38cc1 100644 Binary files a/test/integration/snapshots/Editor.test.js.snap and b/test/integration/snapshots/Editor.test.js.snap differ