Fix findUsages/undo/node-lookup bugs, split Viewport and Editor, share command and inspector helpers
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1eb28314cf
commit
f140c2fd77
58 files changed
+1969
-1171
No files matched your search
+17
-29
@@ -1,6 +1,7 @@
|
||||
import { type Removed, removeWhere } from '../util/list';
|
||||
import type { Position } from './Properties';
|
||||
import type { SceneObject } from './SceneObject';
|
||||
import { descendantsBelow, parentChain, sumAlongChain } from './walk';
|
||||
|
||||
/**
|
||||
* Parent/child structure of a scene. `scene.objects` stays a flat list (storage order =
|
||||
@@ -19,21 +20,18 @@ export function findObject(tree: ObjectTree, id: string): SceneObject | undefine
|
||||
return tree.objects.find((o) => o.id === id);
|
||||
}
|
||||
|
||||
export function childrenOf(tree: ObjectTree, parentId: string): SceneObject[] {
|
||||
function childrenOf(tree: ObjectTree, parentId: string): SceneObject[] {
|
||||
return tree.objects.filter((o) => o.parentId === parentId);
|
||||
}
|
||||
|
||||
/** The parent of an object, or undefined for a top-level one (and for a dangling link). */
|
||||
function parentOf(tree: ObjectTree, object: SceneObject): SceneObject | undefined {
|
||||
return object.parentId ? findObject(tree, object.parentId) : undefined;
|
||||
}
|
||||
|
||||
/** All objects below `id`, depth-first, parents before children. */
|
||||
export function descendantsOf(tree: ObjectTree, id: string): SceneObject[] {
|
||||
const result: SceneObject[] = [];
|
||||
const visit = (parentId: string) => {
|
||||
for (const child of childrenOf(tree, parentId)) {
|
||||
result.push(child);
|
||||
visit(child.id);
|
||||
}
|
||||
};
|
||||
visit(id);
|
||||
return result;
|
||||
return descendantsBelow(id, (parentId) => childrenOf(tree, parentId), (o) => o.id);
|
||||
}
|
||||
|
||||
/** The ids of `rootIds` and of everything below them – what group operations act on. */
|
||||
@@ -54,15 +52,7 @@ export function removeSubtrees(tree: ObjectTree, rootIds: readonly string[]): Re
|
||||
|
||||
/** An object and every parent above it, nearest first. Stops at a cycle (defensive). */
|
||||
export function chainOf(tree: ObjectTree, object: SceneObject): SceneObject[] {
|
||||
const chain = [object];
|
||||
const seen = new Set<string>([object.id]);
|
||||
let parent = object.parentId ? findObject(tree, object.parentId) : undefined;
|
||||
while (parent && !seen.has(parent.id)) {
|
||||
chain.push(parent);
|
||||
seen.add(parent.id);
|
||||
parent = parent.parentId ? findObject(tree, parent.parentId) : undefined;
|
||||
}
|
||||
return chain;
|
||||
return [...parentChain(object, (o) => parentOf(tree, o))];
|
||||
}
|
||||
|
||||
/** Ids of the ancestors of `id`, nearest parent first. Empty for a top-level object. */
|
||||
@@ -86,19 +76,17 @@ export function subtreeRoots(tree: ObjectTree, ids: readonly string[]): string[]
|
||||
return ids.filter((id) => !ancestorIdsOf(tree, id).some((ancestorId) => set.has(ancestorId)));
|
||||
}
|
||||
|
||||
function sumAlongChain(tree: ObjectTree, object: SceneObject, withEditorOffset: boolean): Position {
|
||||
const result: Position = { x: 0, y: 0, z: 0 };
|
||||
for (const o of chainOf(tree, object)) {
|
||||
result.x += o.position.x + (withEditorOffset ? o.editorOffset.x : 0);
|
||||
result.y += o.position.y + (withEditorOffset ? o.editorOffset.y : 0);
|
||||
result.z += o.position.z;
|
||||
}
|
||||
return result;
|
||||
function positionAlongChain(tree: ObjectTree, object: SceneObject, withEditorOffset: boolean): Position {
|
||||
return sumAlongChain(
|
||||
object,
|
||||
(o) => parentOf(tree, o),
|
||||
(o) => (withEditorOffset ? { x: o.position.x + o.editorOffset.x, y: o.position.y + o.editorOffset.y, z: o.position.z } : o.position),
|
||||
);
|
||||
}
|
||||
|
||||
/** Position of an object in world units (all local positions along the chain summed up). */
|
||||
export function worldPosition(tree: ObjectTree, object: SceneObject): Position {
|
||||
return sumAlongChain(tree, object, false);
|
||||
return positionAlongChain(tree, object, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,7 +95,7 @@ export function worldPosition(tree: ObjectTree, object: SceneObject): Position {
|
||||
* in the game, in collisions or in the graph ever sees it (they all use `worldPosition`).
|
||||
*/
|
||||
export function editorPosition(tree: ObjectTree, object: SceneObject): Position {
|
||||
return sumAlongChain(tree, object, true);
|
||||
return positionAlongChain(tree, object, true);
|
||||
}
|
||||
|
||||
/** The local position that puts an object at `world` under the given parent ('' = top level). */
|
||||
|
||||
Reference in new issue
Block a user