Skip to content

Commit

Permalink
feat: depthWrite property
Browse files Browse the repository at this point in the history
  • Loading branch information
bbohlender committed Nov 4, 2024
1 parent c42e52b commit c1458cb
Show file tree
Hide file tree
Showing 24 changed files with 267 additions and 266 deletions.
23 changes: 11 additions & 12 deletions docs/getting-started/components-and-properties.md
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ In addition to the flexbox properties, the container has properties for styling
| zIndexOffset | number |
| receiveShadow | boolean |
| castShadow | boolean |
| depthTest | boolean |
| depthWrite | boolean |
| renderOrder | number |
| backgroundColor | ColorRepresentation |
| backgroundOpacity | number |
| panelMaterialClass | Material class |
Expand Down Expand Up @@ -126,7 +129,7 @@ In addition to the flexbox properties, the container has properties for styling

## Root

Every layout needs to start with a `Root` component. The `Root` component has all the properties of a `Container` component. The `pixelSize` property of the `Root` component allows you to specify the relation of pixels inside the layout with the three.js units in the scene. The `anchorX` and `anchorY` properties allow you to specify where the `Root` component is anchored in relation to its position. The `sizeX` and `sizeY` properties can be used to give the layout a fixed size in three.js units. The `Root` component also allows to control the `renderOrder` and `depthTest` of the whole user interface.
Every layout needs to start with a `Root` component. The `Root` component has all the properties of a `Container` component. The `pixelSize` property of the `Root` component allows you to specify the relation of pixels inside the layout with the three.js units in the scene. The `anchorX` and `anchorY` properties allow you to specify where the `Root` component is anchored in relation to its position. The `sizeX` and `sizeY` properties can be used to give the layout a fixed size in three.js units.

```jsx showLineNumbers
<Root sizeX={2} sizeY={1} flexDirection="row">
Expand All @@ -138,14 +141,12 @@ Every layout needs to start with a `Root` component. The `Root` component has al
<details>
<summary>View all properties specific to the `Root` component</summary>

| Property | Type |
| ----------- | ------------------------- |
| anchorX | "left", "center", "right" |
| anchorY | "top", "center", "bottom" |
| sizeX | number |
| sizeY | number |
| renderOrder | number |
| depthTest | boolean |
| Property | Type |
| -------- | ------------------------- |
| anchorX | "left", "center", "right" |
| anchorY | "top", "center", "bottom" |
| sizeX | number |
| sizeY | number |

</details>

Expand All @@ -167,8 +168,6 @@ The `Fullscreen` component wraps the `Root` component and binds its content dire
| ---------------- | ------- |
| attachCamera | boolean |
| distanceToCamera | number |
| renderOrder | number |
| depthTest | boolean |

</details>

Expand Down Expand Up @@ -544,5 +543,5 @@ Each component exposes the `ComponentInternals` when using a `ref`. The componen
| maxScrollPosition | the maximum x/y scroll position, based on the size of the children |
| isClipped | exploses whether the element is fully clipped by some ancestor |
| setStyle | modifies the styles of the element (the provided styles have a higher precedence then the element's properties) |
| getStyle | get the current style of the object |
| getStyle | get the current style of the object |
| getComputedProperty | read the current value for any property (combines default properties, direct properties, and styles) |
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@
"typescript-json-schema": "^0.63.0",
"vite": "^5.0.12",
"vercel": "^34.1.8",
"@react-three/xr": "6.4.3"
"@react-three/xr": "6.4.4"
}
}
2 changes: 1 addition & 1 deletion packages/react/src/container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const Container: (
<AddHandlers properties={properties} handlers={internals.handlers} ref={outerRef}>
<primitive object={internals.interactionPanel} />
<object3D matrixAutoUpdate={false} ref={innerRef}>
<DefaultProperties {...internals.pointerEventsProperties}>
<DefaultProperties {...internals.defaultProperties}>
<ParentProvider value={internals}>{properties.children}</ParentProvider>
</DefaultProperties>
</object3D>
Expand Down
1 change: 1 addition & 0 deletions packages/react/src/default.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export function DefaultProperties(properties: DefaultPropertiesProperties) {
if (key === 'children') {
continue
}
//TODO: this is not correctly merged but rather overwritten
const value = properties[key as keyof AllOptionalProperties]
if (value == null) {
continue
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/image.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const Image: (
<AddHandlers properties={properties} ref={outerRef} handlers={internals.handlers}>
<primitive object={internals.interactionPanel} />
<object3D matrixAutoUpdate={false} ref={innerRef}>
<DefaultProperties {...internals.pointerEventsProperties}>
<DefaultProperties {...internals.defaultProperties}>
<ParentProvider value={internals}>{properties.children}</ParentProvider>
</DefaultProperties>
</object3D>
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/root.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export const Root: (
<AddHandlers properties={properties} handlers={internals.handlers} ref={outerRef}>
<primitive object={internals.interactionPanel} />
<object3D matrixAutoUpdate={false} ref={innerRef}>
<DefaultProperties {...internals.pointerEventsProperties}>
<DefaultProperties {...internals.defaultProperties}>
<ParentProvider value={internals}>{properties.children}</ParentProvider>
</DefaultProperties>
</object3D>
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/svg.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const Svg: (
<primitive object={internals.interactionPanel} />
<primitive object={internals.centerGroup} />
<object3D matrixAutoUpdate={false} ref={innerRef}>
<DefaultProperties {...internals.pointerEventsProperties}>
<DefaultProperties {...internals.defaultProperties}>
<ParentProvider value={internals}>{properties.children}</ParentProvider>
</DefaultProperties>
</object3D>
Expand Down
22 changes: 14 additions & 8 deletions packages/uikit/src/components/container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import { darkPropertyTransformers } from '../dark.js'
import { getDefaultPanelMaterialConfig } from '../panel/index.js'
import {
computedInheritableProperty,
computePointerEventsProperties,
computeOutgoingDefaultProperties,
setupInteractableDecendant,
setupPointerEvents,
UpdateMatrixWorldProperties,
Expand Down Expand Up @@ -66,7 +66,7 @@ export function createContainer(
parentCtx: ParentContext,
style: Signal<ContainerProperties | undefined>,
properties: Signal<ContainerProperties | undefined>,
defaultProperties: Signal<AllOptionalProperties | undefined>,
incommingDefaultProperties: Signal<AllOptionalProperties | undefined>,
object: Object3DRef,
childrenContainer: Object3DRef,
) {
Expand All @@ -79,7 +79,7 @@ export function createContainer(
setupCursorCleanup(hoveredSignal, initializers)

//properties
const mergedProperties = computedMergedProperties(style, properties, defaultProperties, {
const mergedProperties = computedMergedProperties(style, properties, incommingDefaultProperties, {
...darkPropertyTransformers,
...createResponsivePropertyTransformers(parentCtx.root.size),
...createHoverPropertyTransformers(hoveredSignal),
Expand Down Expand Up @@ -144,9 +144,8 @@ export function createContainer(
globalMatrix,
initializers,
)
const pointerEventsProperties = computePointerEventsProperties(mergedProperties)
setupPointerEvents(pointerEventsProperties, interactionPanel, initializers)
setupInteractableDecendant(pointerEventsProperties.pointerEvents, parentCtx.root, interactionPanel, initializers)
setupPointerEvents(mergedProperties, interactionPanel, initializers)
setupInteractableDecendant(mergedProperties, parentCtx.root, interactionPanel, initializers)
const scrollHandlers = computedScrollHandlers(
scrollPosition,
parentCtx.anyAncestorScrollable,
Expand All @@ -166,7 +165,7 @@ export function createContainer(
setupClippedListeners(style, properties, isClipped, initializers)

return Object.assign(flexState, {
pointerEventsProperties,
defaultProperties: computeOutgoingDefaultProperties(mergedProperties),
globalMatrix,
isClipped,
isVisible,
Expand All @@ -179,7 +178,14 @@ export function createContainer(
root: parentCtx.root,
scrollPosition,
interactionPanel,
handlers: computedHandlers(style, properties, defaultProperties, hoveredSignal, activeSignal, scrollHandlers),
handlers: computedHandlers(
style,
properties,
incommingDefaultProperties,
hoveredSignal,
activeSignal,
scrollHandlers,
),
initializers,
})
}
32 changes: 20 additions & 12 deletions packages/uikit/src/components/content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ import { AllOptionalProperties, WithClasses, WithReactive } from '../properties/
import { createResponsivePropertyTransformers } from '../responsive.js'
import { ElementType, OrderInfo, ZIndexProperties, computedOrderInfo, setupRenderOrder } from '../order.js'
import { createActivePropertyTransfomers } from '../active.js'
import { Signal, computed, effect, signal } from '@preact/signals-core'
import { Signal, computed, effect, signal, untracked } from '@preact/signals-core'
import {
VisibilityProperties,
WithConditionals,
computePointerEventsProperties,
computedGlobalMatrix,
computedHandlers,
computedIsVisible,
Expand All @@ -27,7 +26,11 @@ import {
import { Initializers, alignmentZMap } from '../utils.js'
import { Listeners, setupLayoutListeners, setupClippedListeners } from '../listeners.js'
import { Object3DRef, ParentContext, RootContext } from '../context.js'
import { PanelGroupProperties, computedPanelGroupDependencies } from '../panel/instanced-panel-group.js'
import {
PanelGroupProperties,
RenderProperties,
computedPanelGroupDependencies,
} from '../panel/instanced-panel-group.js'
import { createInteractionPanel } from '../panel/instanced-panel-mesh.js'
import { Box3, Material, Mesh, Object3D, Vector3 } from 'three'
import { darkPropertyTransformers } from '../dark.js'
Expand All @@ -47,7 +50,8 @@ export type InheritableContentProperties = WithClasses<
PanelGroupProperties &
DepthAlignProperties &
KeepAspectRatioProperties &
VisibilityProperties
VisibilityProperties &
RenderProperties
>
>
>
Expand Down Expand Up @@ -136,15 +140,13 @@ export function createContent(
)

setupMatrixWorldUpdate(true, true, object, parentCtx.root, globalMatrix, initializers, false)
const pointerEventsProperties = computePointerEventsProperties(mergedProperties)
setupPointerEvents(pointerEventsProperties, object, initializers)
setupInteractableDecendant(pointerEventsProperties.pointerEvents, parentCtx.root, object, initializers)
setupPointerEvents(mergedProperties, object, initializers)
setupInteractableDecendant(mergedProperties, parentCtx.root, object, initializers)

setupLayoutListeners(style, properties, flexState.size, initializers)
setupClippedListeners(style, properties, isClipped, initializers)

return Object.assign(flexState, {
pointerEventsProperties,
globalMatrix,
isClipped,
isVisible,
Expand Down Expand Up @@ -196,6 +198,7 @@ function createMeasureContent(
visible: boolean,
renderOrder: number,
depthTest: boolean,
depthWrite: boolean,
) => {
if (content == null) {
return
Expand All @@ -210,6 +213,7 @@ function createMeasureContent(
return
}
object.material.depthTest = depthTest
object.material.depthWrite = depthWrite
})
root.requestRender()
}
Expand Down Expand Up @@ -243,11 +247,13 @@ function createMeasureContent(
initializers.push(
() =>
effect(() => {
const properties = propertiesSignal.value
updateRenderProperties(
contentContainerRef.current,
isVisible.value,
root.renderOrder.value,
root.depthTest.value,
properties.read('renderOrder', 0),
properties.read('depthTest', true),
properties.read('depthWrite', false),
)
root.requestRender()
}),
Expand Down Expand Up @@ -302,11 +308,13 @@ function createMeasureContent(
},
)
return () => {
const properties = propertiesSignal.peek()
updateRenderProperties(
contentContainerRef.current,
isVisible.peek(),
root.renderOrder.peek(),
root.depthTest.peek(),
untracked(() => properties.read('renderOrder', 0)),
untracked(() => properties.read('depthTest', true)),
untracked(() => properties.read('depthWrite', false)),
)
measureContent()
}
Expand Down
31 changes: 18 additions & 13 deletions packages/uikit/src/components/custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ import {
setupMatrixWorldUpdate,
setupInteractableDecendant,
setupPointerEvents,
computeOutgoingDefaultProperties,
} from './utils.js'
import { Initializers } from '../utils.js'
import { Listeners, setupLayoutListeners, setupClippedListeners } from '../listeners.js'
import { Object3DRef, ParentContext } from '../context.js'
import { FrontSide, Material, Mesh } from 'three'
import { darkPropertyTransformers } from '../dark.js'
import { ShadowProperties, makeClippedCast } from '../panel/index.js'
import { computePointerEventsProperties } from '../internals.js'
import { RenderProperties, ShadowProperties, makeClippedCast } from '../panel/index.js'

export type InheritableCustomContainerProperties = WithClasses<
WithConditionals<
Expand All @@ -40,7 +40,8 @@ export type InheritableCustomContainerProperties = WithClasses<
TransformProperties &
ScrollbarProperties &
ShadowProperties &
VisibilityProperties
VisibilityProperties &
RenderProperties
>
>
>
Expand Down Expand Up @@ -98,18 +99,24 @@ export function createCustomContainer(
material.clippingPlanes = clippingPlanes
material.needsUpdate = true
material.shadowSide = FrontSide
subscriptions.push(() =>
effect(() => {
material.depthTest = parentCtx.root.depthTest.value
parentCtx.root.requestRender()
}),
subscriptions.push(
() =>
effect(() => {
material.depthTest = mergedProperties.value.read('depthTest', true)
parentCtx.root.requestRender()
}),
() =>
effect(() => {
material.depthWrite = mergedProperties.value.read('depthWrite', false)
parentCtx.root.requestRender()
}),
)
}
mesh.raycast = makeClippedCast(mesh, mesh.raycast, parentCtx.root.object, parentCtx.clippingRect, orderInfo)
setupRenderOrder(mesh, parentCtx.root, orderInfo)
subscriptions.push(
effect(() => {
mesh.renderOrder = parentCtx.root.renderOrder.value
mesh.renderOrder = mergedProperties.value.read('renderOrder', 0)
parentCtx.root.requestRender()
}),
effect(() => {
Expand Down Expand Up @@ -140,15 +147,13 @@ export function createCustomContainer(

setupMatrixWorldUpdate(true, true, object, parentCtx.root, globalMatrix, initializers, false)

const pointerEventsProperties = computePointerEventsProperties(mergedProperties)
setupPointerEvents(pointerEventsProperties, object, initializers)
setupInteractableDecendant(pointerEventsProperties.pointerEvents, parentCtx.root, object, initializers)
setupPointerEvents(mergedProperties, object, initializers)
setupInteractableDecendant(mergedProperties, parentCtx.root, object, initializers)

setupLayoutListeners(style, properties, flexState.size, initializers)
setupClippedListeners(style, properties, isClipped, initializers)

return Object.assign(flexState, {
pointerEventsProperties,
globalMatrix,
isClipped,
isVisible,
Expand Down
10 changes: 4 additions & 6 deletions packages/uikit/src/components/icon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
VisibilityProperties,
WithConditionals,
applyAppearancePropertiesToGroup,
computePointerEventsProperties,
computeOutgoingDefaultProperties,
computedGlobalMatrix,
computedHandlers,
computedIsVisible,
Expand Down Expand Up @@ -138,15 +138,13 @@ export function createIcon(

setupMatrixWorldUpdate(true, true, object, parentCtx.root, globalMatrix, initializers, false)

const pointerEventsProperties = computePointerEventsProperties(mergedProperties)
setupPointerEvents(pointerEventsProperties, object, initializers)
setupInteractableDecendant(pointerEventsProperties.pointerEvents, parentCtx.root, object, initializers)
setupPointerEvents(mergedProperties, object, initializers)
setupInteractableDecendant(mergedProperties, parentCtx.root, object, initializers)

setupLayoutListeners(style, properties, flexState.size, initializers)
setupClippedListeners(style, properties, isClipped, initializers)

return Object.assign(flexState, {
pointerEventsProperties,
globalMatrix,
isClipped,
isVisible,
Expand Down Expand Up @@ -243,6 +241,6 @@ function createIconGroup(
parentContext.root.requestRender()
}),
)
applyAppearancePropertiesToGroup(propertiesSignal, group, initializers, parentContext.root)
applyAppearancePropertiesToGroup(propertiesSignal, group, initializers)
return group
}
Loading

0 comments on commit c1458cb

Please sign in to comment.