Skip to content

Inspector v2: Make properties services and component structure consistent and stub out services for the rest of the entity types #16943

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

Merged
merged 3 commits into from
Jul 30, 2025
Merged
Show file tree
Hide file tree
Changes from 2 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
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import { BoundProperty } from "../boundProperty";
import type { DropdownOption } from "shared-ui-components/fluent/primitives/dropdown";
import { NumberDropdownPropertyLine } from "shared-ui-components/fluent/hoc/propertyLines/dropdownPropertyLine";

const TransparencyModeOptions: DropdownOption[] = [
const TransparencyModeOptions = [
{ label: "Opaque", value: PBRMaterial.PBRMATERIAL_OPAQUE },
{ label: "Alpha test", value: PBRMaterial.PBRMATERIAL_ALPHATEST },
{ label: "Alpha blend", value: PBRMaterial.PBRMATERIAL_ALPHABLEND },
{ label: "Alpha blend and test", value: PBRMaterial.PBRMATERIAL_ALPHATESTANDBLEND },
];
] as const satisfies DropdownOption[];

export const MaterialTransparencyProperties: FunctionComponent<{ material: Material }> = (props) => {
const { material } = props;
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import type { FunctionComponent } from "react";

import type { AbstractMesh } from "core/index";
import type { ISelectionService } from "../../../services/selectionService";

import { Collapse } from "@fluentui/react-motion-components-preview";

import { Color3PropertyLine } from "shared-ui-components/fluent/hoc/propertyLines/colorPropertyLine";
import { LinkPropertyLine } from "shared-ui-components/fluent/hoc/propertyLines/linkPropertyLine";
import { SwitchPropertyLine } from "shared-ui-components/fluent/hoc/propertyLines/switchPropertyLine";
import { useColor3Property, useProperty } from "../../../hooks/compoundPropertyHooks";
import { useObservableState } from "../../../hooks/observableHooks";
import { BoundProperty } from "../boundProperty";

// Ensures that the outlineRenderer properties exist on the prototype of the Mesh
import "core/Rendering/outlineRenderer";

export const AbstractMeshGeneralProperties: FunctionComponent<{ mesh: AbstractMesh; selectionService: ISelectionService }> = (props) => {
const { mesh, selectionService } = props;

// Use the observable to keep keep state up-to-date and re-render the component when it changes.
const material = useObservableState(() => mesh.material, mesh.onMaterialChangedObservable);

return (
<>
{material && !material.reservedDataStore?.hidden && (
<LinkPropertyLine
key="Material"
label="Material"
description={`The material used by the mesh.`}
value={material.name}
onLink={() => (selectionService.selectedEntity = material)}
/>
)}
</>
);
};

export const AbstractMeshAdvancedProperties: FunctionComponent<{ mesh: AbstractMesh }> = (props) => {
const { mesh } = props;

return (
<>
{mesh.useBones && (
<BoundProperty
component={SwitchPropertyLine}
label="Compute Bones Using Shaders"
description="Whether to compute bones using shaders."
target={mesh}
propertyKey={"computeBonesUsingShaders"}
/>
)}
<BoundProperty component={SwitchPropertyLine} label="Check Collisions" description="Whether to check for collisions." target={mesh} propertyKey={"checkCollisions"} />
</>
);
};

export const AbstractMeshOutlineOverlayProperties: FunctionComponent<{ mesh: AbstractMesh }> = (props) => {
const { mesh } = props;

const renderOverlay = useProperty(mesh, "renderOverlay");
const overlayColor = useColor3Property(mesh, "overlayColor");
const renderOutline = useProperty(mesh, "renderOutline");
const outlineColor = useColor3Property(mesh, "outlineColor");

return (
<>
<BoundProperty component={SwitchPropertyLine} label="Render Overlay" target={mesh} propertyKey={"renderOverlay"} />
<Collapse visible={renderOverlay}>
<Color3PropertyLine
key="OverlayColor"
label="Overlay Color"
value={overlayColor}
onChange={(color) => {
mesh.overlayColor = color;
}}
/>
</Collapse>
<BoundProperty component={SwitchPropertyLine} label="Render Outline" target={mesh} propertyKey={"renderOutline"} />
<Collapse visible={renderOutline}>
<Color3PropertyLine
key="OutlineColor"
label="Outline Color"
value={outlineColor}
onChange={(color) => {
mesh.outlineColor = color;
}}
/>
</Collapse>
</>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { Node } from "core/index";

import type { FunctionComponent } from "react";

import { LinkPropertyLine } from "shared-ui-components/fluent/hoc/propertyLines/linkPropertyLine";
import { useProperty } from "../../../hooks/compoundPropertyHooks";
import { useObservableState } from "../../../hooks/observableHooks";
import { SwitchPropertyLine } from "shared-ui-components/fluent/hoc/propertyLines/switchPropertyLine";

export const NodeGeneralProperties: FunctionComponent<{ node: Node; setSelectedEntity: (entity: unknown) => void }> = (props) => {
const { node, setSelectedEntity } = props;

const parent = useProperty(node, "parent");
const isEnabled = useObservableState(() => node.isEnabled(false), node.onEnabledStateChangedObservable);

return (
<>
{parent && <LinkPropertyLine key="Parent" label="Parent" description={`The parent of this node.`} value={parent.name} onLink={() => setSelectedEntity(parent)} />}
<SwitchPropertyLine
key="NodeIsEnabled"
label="Is enabled"
description="Whether the node is enabled or not."
value={isEnabled}
onChange={(checked) => node.setEnabled(checked)}
/>
</>
);
};
10 changes: 8 additions & 2 deletions packages/dev/inspector-v2/src/inspector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@ import { DebugServiceDefinition } from "./services/panes/debugService";
import { AnimationPropertiesServiceDefinition } from "./services/panes/properties/animationPropertiesService";
import { CameraPropertiesServiceDefinition } from "./services/panes/properties/cameraPropertiesService";
import { CommonPropertiesServiceDefinition } from "./services/panes/properties/commonPropertiesService";
import { EffectLayerPropertiesServiceDefinition } from "./services/panes/properties/effectLayerPropertiesService";
import { FrameGraphPropertiesServiceDefinition } from "./services/panes/properties/frameGraphPropertiesService";
import { LightPropertiesServiceDefinition } from "./services/panes/properties/lightPropertiesServices";
import { MaterialPropertiesServiceDefinition } from "./services/panes/properties/materialPropertiesService";
import { MeshPropertiesServiceDefinition } from "./services/panes/properties/meshPropertiesService";
import { NodePropertiesServiceDefinition } from "./services/panes/properties/nodePropertiesService";
import { ParticleSystemPropertiesServiceDefinition } from "./services/panes/properties/particleSystemPropertiesService";
import { PhysicsPropertiesServiceDefinition } from "./services/panes/properties/physicsPropertiesService";
import { PostProcessPropertiesServiceDefinition } from "./services/panes/properties/postProcessPropertiesService";
import { PropertiesServiceDefinition } from "./services/panes/properties/propertiesService";
import { RenderingPipelinePropertiesServiceDefinition } from "./services/panes/properties/renderingPipelinePropertiesService";
import { SkeletonPropertiesServiceDefinition } from "./services/panes/properties/skeletonPropertiesService";
import { SpritePropertiesServiceDefinition } from "./services/panes/properties/spritePropertiesService";
import { TransformPropertiesServiceDefinition } from "./services/panes/properties/transformPropertiesService";
Expand Down Expand Up @@ -202,14 +205,17 @@ function _ShowInspector(scene: Nullable<Scene>, options: Partial<IInspectorOptio
TransformPropertiesServiceDefinition,
AnimationPropertiesServiceDefinition,
NodePropertiesServiceDefinition,
MeshPropertiesServiceDefinition,
PhysicsPropertiesServiceDefinition,
SkeletonPropertiesServiceDefinition,
MaterialPropertiesServiceDefinition,
LightPropertiesServiceDefinition,
SpritePropertiesServiceDefinition,
ParticleSystemPropertiesServiceDefinition,
CameraPropertiesServiceDefinition,
PostProcessPropertiesServiceDefinition,
RenderingPipelinePropertiesServiceDefinition,
EffectLayerPropertiesServiceDefinition,
FrameGraphPropertiesServiceDefinition,

// Debug pane tab and related services.
DebugServiceDefinition,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { ServiceDefinition } from "../../../modularity/serviceDefinition";
import type { IPropertiesService } from "./propertiesService";

import { PropertiesServiceIdentity } from "./propertiesService";

export const EffectLayerPropertiesServiceDefinition: ServiceDefinition<[], [IPropertiesService]> = {
friendlyName: "Effect Layer Properties",
consumes: [PropertiesServiceIdentity],
factory: (propertiesService) => {
// TODO: Add content registrations for each section and for each type in the EffectLayer class hierarchy.

return {
dispose: () => {
// TODO: Dispose content registrations.
},
};
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { ServiceDefinition } from "../../../modularity/serviceDefinition";
import type { IPropertiesService } from "./propertiesService";

import { PropertiesServiceIdentity } from "./propertiesService";

export const FrameGraphPropertiesServiceDefinition: ServiceDefinition<[], [IPropertiesService]> = {
friendlyName: "Frame Graph Properties",
consumes: [PropertiesServiceIdentity],
factory: (propertiesService) => {
// TODO: Add content registrations for each section and for each type in the FrameGraph class hierarchy.

return {
dispose: () => {
// TODO: Dispose content registrations.
},
};
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ import { PropertiesServiceIdentity } from "./propertiesService";
import { SelectionServiceIdentity } from "../../selectionService";

import { Material } from "core/Materials";
import { MaterialTransparencyProperties } from "../../../components/properties/materials/materialTransparencyProperties";
import { MaterialTransparencyProperties } from "../../../components/properties/materials/materialProperties";

export const MaterialPropertiesServiceDefinition: ServiceDefinition<[], [IPropertiesService, ISelectionService]> = {
friendlyName: "Material Properties",
consumes: [PropertiesServiceIdentity, SelectionServiceIdentity],
factory: (propertiesService) => {
const materialContentRegistration = propertiesService.addSectionContent({
key: "Material Properties",
predicate: (entity: unknown): entity is Material => entity instanceof Material,
predicate: (entity: unknown) => entity instanceof Material,
content: [
{
section: "Transparency",
Expand Down
Loading
Loading