Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enabled/Disabled Elements and Default Collapsed State #1079

Merged
merged 4 commits into from
Jan 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/editor/Editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ export default class Editor extends EventEmitter {

const scene = this.scene;

const floorPlanNode = scene.findNodeByType(FloorPlanNode);
const floorPlanNode = scene.findNodeByType(FloorPlanNode, false);

if (floorPlanNode) {
await floorPlanNode.generate(signal);
Expand Down
82 changes: 56 additions & 26 deletions src/editor/nodes/EditorNodeMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Color, Object3D } from "three";
import serializeColor from "../utils/serializeColor";
import LoadingCube from "../objects/LoadingCube";
import ErrorIcon from "../objects/ErrorIcon";
import traverseFilteredSubtrees from "../utils/traverseFilteredSubtrees";

export default function EditorNodeMixin(Object3DClass) {
return class extends Object3DClass {
Expand Down Expand Up @@ -56,7 +57,13 @@ export default function EditorNodeMixin(Object3DClass) {
const visibleComponent = json.components.find(c => c.name === "visible");

if (visibleComponent) {
node.visible = visibleComponent.props.visible;
node._visible = visibleComponent.props.visible;
}

const editorSettingsComponent = json.components.find(c => c.name === "editor-settings");

if (editorSettingsComponent) {
node.enabled = editorSettingsComponent.props.enabled;
}
}

Expand All @@ -70,13 +77,14 @@ export default function EditorNodeMixin(Object3DClass) {
this.nodeName = this.constructor.nodeName;
this.name = this.constructor.nodeName;
this.isNode = true;
this.isCollapsed = false;
this.disableTransform = this.constructor.disableTransform;
this.useMultiplePlacementMode = this.constructor.useMultiplePlacementMode;
this.ignoreRaycast = this.constructor.ignoreRaycast;

this.staticMode = StaticModes.Inherits;
this.originalStaticMode = null;
this.enabled = true;
this._visible = true;
this.saveParent = false;
this.loadingCube = null;
this.errorIcon = null;
Expand Down Expand Up @@ -110,10 +118,20 @@ export default function EditorNodeMixin(Object3DClass) {
}

this.issues = source.issues.slice();
this._visible = source._visible;
this.enabled = source.enabled;

return this;
}

get visible() {
return this.enabled && this._visible;
}

set visible(value) {
this._visible = value;
}

onPlay() {}

onUpdate(dt) {
Expand Down Expand Up @@ -163,7 +181,13 @@ export default function EditorNodeMixin(Object3DClass) {
{
name: "visible",
props: {
visible: this.visible
visible: this._visible
}
},
{
name: "editor-settings",
props: {
enabled: this.enabled
}
}
]
Expand Down Expand Up @@ -345,40 +369,46 @@ export default function EditorNodeMixin(Object3DClass) {
return isDynamic(this);
}

findNodeByType(nodeType) {
if (this.constructor === nodeType) {
return this;
}
findNodeByType(nodeType, includeDisabled = true) {
let node = null;

for (const child of this.children) {
if (child.isNode) {
const result = child.findNodeByType(nodeType);
traverseFilteredSubtrees(this, child => {
if (node) {
return false;
}

if (result) {
return result;
}
if (!child.isNode) {
return;
}
}

return null;
if (!child.enabled && !includeDisabled) {
return false;
}

if (child.constructor === nodeType) {
node = child;
}
});

return node;
}

getNodesByType(nodeType) {
getNodesByType(nodeType, includeDisabled = true) {
const nodes = [];

if (this.constructor === nodeType) {
nodes.push(this);
}
traverseFilteredSubtrees(this, child => {
if (!child.isNode) {
return;
}

for (const child of this.children) {
if (child.isNode) {
const results = child.getNodesByType(nodeType);
if (!child.enabled && !includeDisabled) {
return false;
}

for (const result of results) {
nodes.push(result);
}
if (child.constructor === nodeType) {
nodes.push(this);
}
}
});

return nodes;
}
Expand Down
13 changes: 9 additions & 4 deletions src/editor/nodes/FloorPlanNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import RecastClient from "../recast/RecastClient";
import HeightfieldClient from "../heightfield/HeightfieldClient";
import SpawnPointNode from "../nodes/SpawnPointNode";
import * as recastWasmUrl from "recast-wasm/dist/recast.wasm";
import traverseFilteredSubtrees from "../utils/traverseFilteredSubtrees";

const recastClient = new RecastClient();
const heightfieldClient = new HeightfieldClient();
Expand Down Expand Up @@ -102,13 +103,17 @@ export default class FloorPlanNode extends EditorNodeMixin(FloorPlan) {
const collidableMeshes = [];
const walkableMeshes = [];

const groundPlaneNode = this.editor.scene.findNodeByType(GroundPlaneNode);
const groundPlaneNode = this.editor.scene.findNodeByType(GroundPlaneNode, false);

if (groundPlaneNode && groundPlaneNode.walkable) {
walkableMeshes.push(groundPlaneNode.walkableMesh);
}

this.editor.scene.traverse(object => {
traverseFilteredSubtrees(this.editor.scene, object => {
if (!object.enabled) {
return false;
}

if (object.isNode && object.model && (object.collidable || object.walkable)) {
object.model.traverse(child => {
if (child.isMesh) {
Expand All @@ -124,7 +129,7 @@ export default class FloorPlanNode extends EditorNodeMixin(FloorPlan) {
}
});

const boxColliderNodes = this.editor.scene.getNodesByType(BoxColliderNode);
const boxColliderNodes = this.editor.scene.getNodesByType(BoxColliderNode, false);

for (const node of boxColliderNodes) {
if (node.walkable) {
Expand Down Expand Up @@ -179,7 +184,7 @@ export default class FloorPlanNode extends EditorNodeMixin(FloorPlan) {

let heightfield = null;
if (!this.forceTrimesh) {
const spawnPoints = this.editor.scene.getNodesByType(SpawnPointNode);
const spawnPoints = this.editor.scene.getNodesByType(SpawnPointNode, false);

let minY = Number.POSITIVE_INFINITY;
for (let j = 0; j < spawnPoints.length; j++) {
Expand Down
40 changes: 29 additions & 11 deletions src/editor/nodes/SceneNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import GroupNode from "./GroupNode";
import getNodeWithUUID from "../utils/getNodeWithUUID";
import serializeColor from "../utils/serializeColor";
import { DistanceModelType } from "../objects/AudioSource";
import traverseFilteredSubtrees from "../utils/traverseFilteredSubtrees";

// Migrate v1 spoke scene to v2
function migrateV1ToV2(json) {
Expand Down Expand Up @@ -528,7 +529,11 @@ export default class SceneNode extends EditorNodeMixin(Scene) {
});

for (const node of nodeList) {
node.prepareForExport(ctx);
if (node.enabled) {
node.prepareForExport(ctx);
} else {
node.parent.remove(node);
}
}

this.addGLTFComponent("background", {
Expand Down Expand Up @@ -617,8 +622,16 @@ export default class SceneNode extends EditorNodeMixin(Scene) {
getAnimationClips() {
const animations = [];

this.traverse(child => {
if (child.isNode && child.type === "Model") {
traverseFilteredSubtrees(this, child => {
if (!child.isNode) {
return;
}

if (!child.enabled) {
return false;
}

if (child.type === "Model") {
animations.push(...child.clips);
}
});
Expand All @@ -630,18 +643,23 @@ export default class SceneNode extends EditorNodeMixin(Scene) {
const contentAttributions = [];
const seenAttributions = new Set();

this.traverse(obj => {
if (!(obj.isNode && obj.attribution)) return;
traverseFilteredSubtrees(this, obj => {
if (!obj.isNode) {
return;
}

if (!obj.enabled) {
return false;
}

const attribution = obj.attribution;

if (!attribution) return;

if (attribution) {
const attributionKey = attribution.url || `${attribution.title}_${attribution.author}`;
if (seenAttributions.has(attributionKey)) return;
seenAttributions.add(attributionKey);
contentAttributions.push(attribution);
}
const attributionKey = attribution.url || `${attribution.title}_${attribution.author}`;
if (seenAttributions.has(attributionKey)) return;
seenAttributions.add(attributionKey);
contentAttributions.push(attribution);
});

return contentAttributions;
Expand Down
11 changes: 11 additions & 0 deletions src/editor/utils/traverseFilteredSubtrees.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export default function traverseFilteredSubtrees(object, cb) {
if (cb(object) === false) {
return;
}

const children = object.children;

for (let i = 0; i < children.length; i++) {
traverseFilteredSubtrees(children[i], cb);
}
}
Loading