Skip to content

Commit cbfedf9

Browse files
committed
feature: add wireframe view
1 parent 5b4e347 commit cbfedf9

7 files changed

Lines changed: 215 additions & 84 deletions

File tree

packages/bridge/src/types.ts

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ type Icon =
2424
| "size"
2525
| "sun"
2626
| "transform"
27-
| "world";
27+
| "world"
28+
| "mask-on"
29+
| "mask-off";
2830

2931
export interface ButtonGroupControl {
3032
buttons: {
@@ -44,10 +46,10 @@ export interface MenuControl {
4446
label: string;
4547
options: (
4648
| {
47-
group?: string;
48-
id: string;
49-
label: string;
50-
}
49+
group?: string;
50+
id: string;
51+
label: string;
52+
}
5153
| { type: "separator" }
5254
)[];
5355
type: "menu";
@@ -157,15 +159,15 @@ export interface ClientSendEventData {
157159
keyup: KeyboardEventObject;
158160
ready: undefined;
159161
"set-extension-points":
160-
| {
161-
area: "elements";
162-
controls: Actions;
163-
}
164-
| {
165-
area: "scene";
166-
controls: Controls;
167-
}
168-
| { area: "settings"; options: MenuControl["options"] };
162+
| {
163+
area: "elements";
164+
controls: Actions;
165+
}
166+
| {
167+
area: "scene";
168+
controls: Controls;
169+
}
170+
| { area: "settings"; options: MenuControl["options"] };
169171
track: { actionId: string };
170172
}
171173

@@ -207,15 +209,15 @@ export interface HostSendEventData {
207209
path: string;
208210
} | null;
209211
"extension-point-triggered":
210-
| {
211-
id: string;
212-
scope: "scene";
213-
}
214-
| {
215-
data: ExtensionPointElement;
216-
id: string;
217-
scope: "element";
218-
};
212+
| {
213+
id: string;
214+
scope: "scene";
215+
}
216+
| {
217+
data: ExtensionPointElement;
218+
id: string;
219+
scope: "element";
220+
};
219221
keydown: KeyboardEventObject;
220222
keyup: KeyboardEventObject;
221223
"request-blur-element": undefined;
@@ -234,20 +236,23 @@ export interface HostSendEventData {
234236
path: string;
235237
};
236238
"request-jump-to-element":
237-
| {
238-
astPath: string;
239-
column: number;
240-
line: number;
241-
path: string;
242-
}
243-
| undefined;
239+
| {
240+
astPath: string;
241+
column: number;
242+
line: number;
243+
path: string;
244+
}
245+
| undefined;
246+
"request-material-override": {
247+
state: "none" | "wireframe";
248+
};
244249
"request-open-component":
245-
| {
246-
encodedProps: string;
247-
exportName: string;
248-
path: string;
249-
}
250-
| undefined;
250+
| {
251+
encodedProps: string;
252+
exportName: string;
253+
path: string;
254+
}
255+
| undefined;
251256
"request-refresh-scene": { hard: true } | undefined;
252257
"request-reset-prop": {
253258
astPath: string;
@@ -289,6 +294,7 @@ export interface HostSendEventResponse {
289294
"request-delete-element": void;
290295
"request-focus-element": void;
291296
"request-jump-to-element": void;
297+
"request-material-override": void;
292298
"request-open-component": void;
293299
"request-refresh-scene": void;
294300
"request-reset-prop": void;

packages/renderer/src/features/app/index.tsx

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import { SceneLoader } from "../scene-loader";
2828
import { SwitchToComponentContext } from "./context";
2929
import { DebugAttributes } from "./debug";
3030
import { type Component } from "./types";
31+
import { MaterialOverrideProvider } from "../../stores/use-material-override";
3132

3233
export function App({
3334
files,
@@ -104,41 +105,43 @@ export function App({
104105
return (
105106
<SwitchToComponentContext.Provider value={switchToComponent}>
106107
<PlayStateProvider>
107-
<ErrorBoundaryForScene
108-
fallbackRender={() => <ErrorFallback />}
109-
onError={(err) =>
110-
send("error", {
111-
message: err.message,
112-
source: component.path,
113-
stack: err.message,
114-
subtitle:
115-
"The scene could not be rendered as there was an error parsing its module. Resolve the error and try again.",
116-
title: "Module Error",
117-
})
118-
}
119-
resetKeys={[component]}
120-
>
121-
<Suspense
122-
fallback={
123-
<LoadingLogo
124-
color="rgb(59 130 246)"
125-
position="hint"
126-
variant="stroke"
127-
/>
108+
<MaterialOverrideProvider>
109+
<ErrorBoundaryForScene
110+
fallbackRender={() => <ErrorFallback />}
111+
onError={(err) =>
112+
send("error", {
113+
message: err.message,
114+
source: component.path,
115+
stack: err.message,
116+
subtitle:
117+
"The scene could not be rendered as there was an error parsing its module. Resolve the error and try again.",
118+
title: "Module Error",
119+
})
128120
}
121+
resetKeys={[component]}
129122
>
130-
<SceneLoader
131-
exportName={component.exportName}
132-
modules={files}
133-
path={component.path}
134-
providerPath={providerPath}
135-
providers={providers}
136-
sceneProps={component.props}
137-
/>
138-
</Suspense>
139-
<Tunnel.Out />
140-
<DebugAttributes />
141-
</ErrorBoundaryForScene>
123+
<Suspense
124+
fallback={
125+
<LoadingLogo
126+
color="rgb(59 130 246)"
127+
position="hint"
128+
variant="stroke"
129+
/>
130+
}
131+
>
132+
<SceneLoader
133+
exportName={component.exportName}
134+
modules={files}
135+
path={component.path}
136+
providerPath={providerPath}
137+
providers={providers}
138+
sceneProps={component.props}
139+
/>
140+
</Suspense>
141+
<Tunnel.Out />
142+
<DebugAttributes />
143+
</ErrorBoundaryForScene>
144+
</MaterialOverrideProvider>
142145
</PlayStateProvider>
143146
</SwitchToComponentContext.Provider>
144147
);

packages/renderer/src/features/canvas/canvas.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { ThreeFiberSelection } from "../selection-three-fiber";
2424
import { CaptureShaderErrors } from "./capture-shader-errors";
2525
import { SceneLights } from "./scene-lights";
2626
import { useCanvasMounted } from "./store";
27+
import { useMaterialOverride } from "../../stores/use-material-override";
2728

2829
/**
2930
* **Canvas**
@@ -37,6 +38,7 @@ export function Canvas({ children, ...props }: CanvasProps) {
3738
const { exportName, path, providerPath, providers, scene } = useLoadedScene();
3839
const setMounted = useCanvasMounted((state) => state.setMounted);
3940
const ref = useRef<HTMLCanvasElement>(null);
41+
const materialOverride = useMaterialOverride();
4042

4143
useEffect(() => {
4244
if (playState === "play") {
@@ -62,11 +64,12 @@ export function Canvas({ children, ...props }: CanvasProps) {
6264
playState === "play"
6365
? (props.raycaster?.layers ?? defaultLayer)
6466
: // This forces the default r3f raycaster to be fired on a different layer (31)
65-
// than the default layer (0) that object3d's are set to default.
66-
editorLayer,
67+
// than the default layer (0) that object3d's are set to default.
68+
editorLayer,
6769
}}
6870
ref={ref}
6971
>
72+
<color args={[materialOverride === "wireframe" ? "#000000" : "#d9d9d9"]} attach="background" />
7073
<CaptureShaderErrors />
7174
<Camera>
7275
<ErrorBoundaryForScene

packages/renderer/src/features/scene-controls/controls-three-fiber.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export const controls: Controls = [
5353
{
5454
buttons: [
5555
{
56+
accelerator: "P",
5657
icon: "cursor",
5758
id: "none",
5859
label: "Select",
@@ -102,6 +103,25 @@ export const controls: Controls = [
102103
{
103104
type: "separator",
104105
},
106+
{
107+
buttons: [
108+
{
109+
icon: "mask-on",
110+
id: "material_override_wireframe",
111+
label: "Turn On Wireframe Override",
112+
},
113+
{
114+
icon: "mask-off",
115+
id: "material_override_none",
116+
label: "Turn Off Wireframe Override",
117+
},
118+
],
119+
groupId: "draw-type",
120+
type: "toggle-button",
121+
},
122+
{
123+
type: "separator",
124+
},
105125
{
106126
buttons: [
107127
{

packages/renderer/src/features/scene-loader/index.tsx

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { ReactDOMSelection } from "../selection-react-dom";
2121
import { ResetCountContext, SceneContext } from "./context";
2222
import { type LoadedSceneContext } from "./types";
2323
import { useSceneLoader } from "./use-scene-loader";
24+
import { MaterialOverrideComponent } from "../../stores/use-material-override";
2425

2526
export function SceneLoader({
2627
exportName,
@@ -52,13 +53,13 @@ export function SceneLoader({
5253
() =>
5354
scene
5455
? {
55-
exportName,
56-
meta: scene.meta,
57-
path,
58-
providerPath,
59-
providers,
60-
scene: scene.component,
61-
}
56+
exportName,
57+
meta: scene.meta,
58+
path,
59+
providerPath,
60+
providers,
61+
scene: scene.component,
62+
}
6263
: null,
6364
[exportName, path, providerPath, providers, scene],
6465
);
@@ -119,12 +120,14 @@ export function SceneLoader({
119120
)}
120121
{scene.meta.root === "react-three-fiber" && (
121122
<Canvas>
122-
<SceneRenderer
123-
component={scene.component}
124-
exportName={exportName}
125-
path={path}
126-
props={sceneProps}
127-
/>
123+
<MaterialOverrideComponent resetCount={resetCount}>
124+
<SceneRenderer
125+
component={scene.component}
126+
exportName={exportName}
127+
path={path}
128+
props={sceneProps}
129+
/>
130+
</MaterialOverrideComponent>
128131
</Canvas>
129132
)}
130133
<SceneControls />

0 commit comments

Comments
 (0)