Skip to content

Commit

Permalink
Merge pull request KhronosGroup#29 from needle-tools/feature/various-…
Browse files Browse the repository at this point in the history
…fixes

Various fixes
  • Loading branch information
mattmacf98 authored Nov 13, 2024
2 parents 9ef02e5 + e9d8b76 commit cf356d1
Show file tree
Hide file tree
Showing 12 changed files with 93 additions and 17 deletions.
15 changes: 15 additions & 0 deletions src/BasicBehaveEngine/decorators/BabylonDecorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,21 @@ export class BabylonDecorator extends ADecorator {
}
}, "bool");

this.registerJsonPointer(`/nodes/${maxGltfNode}/extensions/KHR_node_visibility/visible`, (path) => {
const parts: string[] = path.split("/");
const node = this.world.glTFNodes[Number(parts[2])];
if (node instanceof AbstractMesh) {
return (node as AbstractMesh).isVisible;
}
return true;
}, (path, value) => {
const parts: string[] = path.split("/");
const node = this.world.glTFNodes[Number(parts[2])];
if (node instanceof AbstractMesh) {
(node as AbstractMesh).isVisible = value || value === undefined || value === null;
}
}, "bool");

this.registerJsonPointer(`/nodes/${maxGltfNode}/extensions/KHR_node_hoverability/hoverable`, (path) => {
const parts: string[] = path.split("/");
const metadata = this.world.glTFNodes[Number(parts[2])].metadata;
Expand Down
2 changes: 2 additions & 0 deletions src/BasicBehaveEngine/nodes/experimental/OnSelect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ export class OnSelect extends BehaveEngineNode {
value: [controllerIndex],
};

console.log("OnSelect", {node: this._nodeIndex, outValues: this.outValues});

this.addEventToWorkQueue(this.flows.out);

if (!this._stopPropagation) {
Expand Down
7 changes: 5 additions & 2 deletions src/BasicBehaveEngine/nodes/flow/Sequence.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ export class Sequence extends BehaveEngineNode {
override processNode(flowSocket?: string) {
this.graphEngine.processNodeStarted(this)

for (let i = 0; i < Number(this._numberOutputFlows); i++) {
this.processFlow(this.flows[i]);
const flows = Object.keys(this.flows);
for (let i = 0; i < flows.length; i++) {
const flow = this.flows[flows[i]];
if (!flow) continue;
this.processFlow(flow);
}
}
}
2 changes: 1 addition & 1 deletion src/BasicBehaveEngine/nodes/flow/SetDelay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export class SetDelay extends BehaveEngineNode {
} else {
const delayIndex = this.graphEngine.scheduledDelays.length;
const delayId = setTimeout(() => {
this.addEventToWorkQueue(this.flows.completed);
this.addEventToWorkQueue(this.flows.done);
}, duration * 1000);
this.graphEngine.pushScheduledDelay(delayId);
this._runningDelayIndices.push(delayIndex);
Expand Down
2 changes: 1 addition & 1 deletion src/BasicBehaveEngine/nodes/pointer/PointerGet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export class PointerGet extends BehaveEngineNode {
const typeIndex = this.getTypeIndex(typeName!);

return {
'val':{id: "val", value: this.graphEngine.getPathValue(populatedPath), type: typeIndex},
'value':{id: "value", value: this.graphEngine.getPathValue(populatedPath), type: typeIndex},
'isValid':{id: "isValid", value: [true], type: this.getTypeIndex('bool')}
};
} else {
Expand Down
2 changes: 1 addition & 1 deletion src/BasicBehaveEngine/nodes/pointer/PointerSet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {BehaveEngineNode, IBehaviourNodeProps} from "../../BehaveEngineNode";

export class PointerSet extends BehaveEngineNode {
REQUIRED_CONFIGURATIONS = [{id: "pointer"}]
REQUIRED_VALUES = [{id: "val"}]
REQUIRED_VALUES = [{id: "value"}]

_pointer: string;
_pointerVals: { id: string }[];
Expand Down
6 changes: 3 additions & 3 deletions src/authoring/AuthoringNodeSpecs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export const pointerNodeSpecs: IAuthoringNode[] = [
flows: [],
values: [
{
id: "val",
id: "value",
description: "The value to set",
types: ["bool", "int", "float","float2", "float3", "float4"]
},
Expand Down Expand Up @@ -118,7 +118,7 @@ export const pointerNodeSpecs: IAuthoringNode[] = [
],
values: [
{
id: "val",
id: "value",
description: "The value to set",
types: ["bool", "int", "float", "float2", "float3", "float4"]
}
Expand Down Expand Up @@ -984,7 +984,7 @@ export const flowNodeSpecs: IAuthoringNode[] = [
output: {
flows: [
{
id: "completed",
id: "done",
description: "The flow to be followed after the delay",
},
{
Expand Down
11 changes: 8 additions & 3 deletions src/authoring/BehaveToAuthor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,12 @@ export const behaveToAuthor = (graph: string): [Node[], Edge[], ICustomEvent[],
const nodeNumbers: number[] = [];
disjointGraph.forEach((nodeId) => {
const i = nodes.findIndex((n) => n.id === nodeId);
nodeNumbers.push(i);
if (i < 0) {
console.error(`Node with id ${nodeId} not found in nodes list. This is likely an issue with the graph data.`);
}
else {
nodeNumbers.push(i);
}
});

// Each layer is a vertical column of a disjoint graph. Since we start at the leftmost column where x = -500 (starting point).
Expand All @@ -169,7 +174,7 @@ export const behaveToAuthor = (graph: string): [Node[], Edge[], ICustomEvent[],
const nodeOutEdges: Edge[] = edges.filter(edge => Number(edge.source) === nodeIndex);
nextLayer.push(...nodeOutEdges.map(edge => Number(edge.target)));
}
nextLayer = [...new Set(nextLayer)]
nextLayer = [...new Set(nextLayer.filter(num => Number.isFinite(num)))];

let xOffset = 0;
while (nextLayer.length > 0) {
Expand All @@ -188,7 +193,7 @@ export const behaveToAuthor = (graph: string): [Node[], Edge[], ICustomEvent[],
const nodeOutEdges: Edge[] = edges.filter(edge => Number(edge.source) === nodeIndex);
nextLayer.push(...nodeOutEdges.map(edge => Number(edge.target)));
}
nextLayer = [...new Set(nextLayer)];
nextLayer = [...new Set(nextLayer.filter(num => Number.isFinite(num)))];
xOffset += 500;
}
layerYAdditive = 800 + lastMaxY;
Expand Down
8 changes: 7 additions & 1 deletion src/components/engineViews/BabylonEngineComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {Scene} from "@babylonjs/core/scene";
import "@babylonjs/loaders/glTF";
import {Spacer} from "../Spacer";
import {KHR_interactivity, KHR_INTERACTIVITY_EXTENSION_NAME} from "../../loaderExtensions/KHR_interactivity";
import {KHR_node_visibility, KHR_NODE_VISIBILITY_EXTENSION_NAME} from "../../loaderExtensions/KHR_node_visibility";
import {GLTFLoader} from "@babylonjs/loaders/glTF/2.0";
import {BabylonDecorator} from "../../BasicBehaveEngine/decorators/BabylonDecorator";
import {BasicBehaveEngine} from "../../BasicBehaveEngine/BasicBehaveEngine";
Expand All @@ -24,10 +25,15 @@ enum BabylonEngineModal {
CUSTOM_EVENT = "CUSTOM_EVENT",
NONE = "NONE"
}

GLTFLoader.RegisterExtension(KHR_INTERACTIVITY_EXTENSION_NAME, (loader) => {
return new KHR_interactivity(loader);
});

GLTFLoader.RegisterExtension(KHR_NODE_VISIBILITY_EXTENSION_NAME, (loader) => {
return new KHR_node_visibility(loader);
});

export const BabylonEngineComponent = (props: {behaveGraphRef: any, setBehaveGraphFromGlTF: any}) => {
const canvasRef = useRef<HTMLCanvasElement | null>(null);
const engineRef = useRef<Engine | null>(null);
Expand Down Expand Up @@ -179,7 +185,7 @@ export const BabylonEngineComponent = (props: {behaveGraphRef: any, setBehaveGra

glTF['extensions'] = glTF['extensions'] || {};
glTF['extensions']['KHR_interactivity'] = {
graph: props.behaveGraphRef.current
...props.behaveGraphRef.current
}
glTF['extensionsUsed'] = glTF['extensionsUsed'] || []
if (!glTF['extensionsUsed'].includes('KHR_interactivity')) {
Expand Down
4 changes: 2 additions & 2 deletions src/loaderExtensions/KHR_interactivity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ export class KHR_interactivity implements IGLTFLoaderExtension {
return GLTFLoader.LoadExtensionAsync(context, scene, this.name, (extensionContext, extension) => {
const promises = new Array<Promise<any>>();
promises.push(this._loader.loadSceneAsync(context, scene));
if (scene.extensions && scene.extensions.KHR_interactivity && scene.extensions.KHR_interactivity.graph) {
if (scene.extensions && scene.extensions.KHR_interactivity && scene.extensions.KHR_interactivity) {
const p = async () => {
this._loader.babylonScene.extras = this._loader.babylonScene.extras || {};
this._loader.babylonScene.extras.behaveGraph = scene.extensions!.KHR_interactivity.graph;
this._loader.babylonScene.extras.behaveGraph = scene.extensions!.KHR_interactivity;
};
promises.push(p());
}
Expand Down
45 changes: 45 additions & 0 deletions src/loaderExtensions/KHR_node_visibility.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { IGLTFLoaderExtension } from "@babylonjs/loaders";
import { GLTFLoader } from "@babylonjs/loaders/glTF/2.0";
import { AbstractMesh } from "@babylonjs/core";

// See also: Commit that adds KHR_node_visibility to BabylonJS 7.x
// https://github.com/BabylonJS/Babylon.js/commit/01f82d0092d804c75ec9010dded2e8df86a84287#diff-98704e8dc53eb8405b18072a7c7b6d9d0bb37826de8b4a376e48bf433cbae6e7R51
// See also: inheritVisibility in core BabylonJS
// https://github.com/BabylonJS/Babylon.js/blob/master/packages/dev/core/src/Meshes/abstractMesh.ts#L555

export const KHR_NODE_VISIBILITY_EXTENSION_NAME = 'KHR_node_visibility';
export class KHR_node_visibility implements IGLTFLoaderExtension {
name = KHR_NODE_VISIBILITY_EXTENSION_NAME;
enabled: boolean;
private _loader: GLTFLoader | null = null;

constructor(loader: GLTFLoader) {
this._loader = loader;
this.enabled = this._loader.isExtensionUsed(this.name);
}

public async onReady(): Promise<void> {
if (!this._loader) return;
this._loader.gltf.nodes?.forEach((node) => {
node._primitiveBabylonMeshes?.forEach((_mesh) => {
// TODO this is available in a later Babylon version.
// mesh.inheritVisibility = true;
});
// When the JSON Pointer is used we need to change both the transform node and the primitive meshes to the new value.
if (node.extensions?.KHR_node_visibility) {
if (node.extensions?.KHR_node_visibility.visible === false) {
if (node._babylonTransformNode) {
(node._babylonTransformNode as AbstractMesh).isVisible = false;
}
node._primitiveBabylonMeshes?.forEach((mesh) => {
mesh.isVisible = false;
});
}
}
});
}

dispose(): void {
this._loader = null;
}
}
6 changes: 3 additions & 3 deletions tst/nodes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -490,15 +490,15 @@ describe('nodes', () => {
);

const res = pointerGet.processNode();
expect(res['val']!.value[0]).toBe(2);
expect(res['value']!.value[0]).toBe(2);

const pointerGetCustomPtr: PointerGet = new PointerGet({
...defaultProps,
configuration: [{ id: 'pointer', value: '/nodes/0/value' }],
});

const resCustom = await pointerGetCustomPtr.processNode();
expect(resCustom['val']!.value[0]).toBe(1);
expect(resCustom['value']!.value[0]).toBe(1);
});

it('pointer/set', async () => {
Expand All @@ -522,7 +522,7 @@ describe('nodes', () => {
],
values: [
{ id: 'index', value: [0], type: 1 },
{ id: 'val', value: [42], type: 1 },
{ id: 'value', value: [42], type: 1 },
],
});

Expand Down

0 comments on commit cf356d1

Please sign in to comment.