|
|
@@ -28,11 +28,13 @@ import {
|
|
|
|
createDefaultMaterial,
|
|
|
|
createDefaultMaterial,
|
|
|
|
createSurfaceRoleMaterial,
|
|
|
|
createSurfaceRoleMaterial,
|
|
|
|
type RenderShading,
|
|
|
|
type RenderShading,
|
|
|
|
|
|
|
|
resolveMaterialRef,
|
|
|
|
|
|
|
|
resolveSlotDefaultMaterial,
|
|
|
|
useNodeEvents,
|
|
|
|
useNodeEvents,
|
|
|
|
useViewer,
|
|
|
|
useViewer,
|
|
|
|
} from '@pascal-app/viewer'
|
|
|
|
} from '@pascal-app/viewer'
|
|
|
|
import { useFrame } from '@react-three/fiber'
|
|
|
|
import { useFrame } from '@react-three/fiber'
|
|
|
|
import { useCallback, useLayoutEffect, useMemo, useRef } from 'react'
|
|
|
|
import { createContext, useCallback, useContext, useLayoutEffect, useMemo, useRef } from 'react'
|
|
|
|
import {
|
|
|
|
import {
|
|
|
|
BoxGeometry,
|
|
|
|
BoxGeometry,
|
|
|
|
CylinderGeometry,
|
|
|
|
CylinderGeometry,
|
|
|
@@ -43,6 +45,13 @@ import {
|
|
|
|
TorusGeometry,
|
|
|
|
TorusGeometry,
|
|
|
|
} from 'three'
|
|
|
|
} from 'three'
|
|
|
|
import { useShallow } from 'zustand/react/shallow'
|
|
|
|
import { useShallow } from 'zustand/react/shallow'
|
|
|
|
|
|
|
|
import {
|
|
|
|
|
|
|
|
ELEVATOR_CAB_SLOT_DEFAULT,
|
|
|
|
|
|
|
|
ELEVATOR_DOORS_SLOT_DEFAULT,
|
|
|
|
|
|
|
|
ELEVATOR_GLASS_SLOT_DEFAULT,
|
|
|
|
|
|
|
|
ELEVATOR_SHAFT_SLOT_DEFAULT,
|
|
|
|
|
|
|
|
type ElevatorSlotId,
|
|
|
|
|
|
|
|
} from './slots'
|
|
|
|
|
|
|
|
|
|
|
|
const DEFAULT_STRUCTURE_WHITE = '#f2f0ed'
|
|
|
|
const DEFAULT_STRUCTURE_WHITE = '#f2f0ed'
|
|
|
|
const SHAFT_WALL_COLOR = DEFAULT_STRUCTURE_WHITE
|
|
|
|
const SHAFT_WALL_COLOR = DEFAULT_STRUCTURE_WHITE
|
|
|
@@ -360,48 +369,102 @@ function getElevatorMaterials(
|
|
|
|
return materials
|
|
|
|
return materials
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
let {
|
|
|
|
type ElevatorSceneMaterials = ReturnType<typeof useScene.getState>['materials']
|
|
|
|
SHAFT_WALL_MATERIAL,
|
|
|
|
|
|
|
|
SHAFT_SIDE_MATERIAL,
|
|
|
|
|
|
|
|
SHAFT_TRIM_MATERIAL,
|
|
|
|
|
|
|
|
CAB_MATERIAL,
|
|
|
|
|
|
|
|
DOOR_MATERIAL,
|
|
|
|
|
|
|
|
DOOR_GROOVE_MATERIAL,
|
|
|
|
|
|
|
|
GLASS_MATERIAL,
|
|
|
|
|
|
|
|
PANEL_MATERIAL,
|
|
|
|
|
|
|
|
LANDING_PANEL_MATERIAL,
|
|
|
|
|
|
|
|
INDICATOR_SCREEN_MATERIALS,
|
|
|
|
|
|
|
|
INDICATOR_GLYPH_MATERIALS,
|
|
|
|
|
|
|
|
BUTTON_FACE_MATERIALS,
|
|
|
|
|
|
|
|
BUTTON_RING_MATERIALS,
|
|
|
|
|
|
|
|
BUTTON_GLOW_MATERIALS,
|
|
|
|
|
|
|
|
BUTTON_LABEL_MATERIALS,
|
|
|
|
|
|
|
|
QUEUE_STRIP_MATERIALS,
|
|
|
|
|
|
|
|
} = getElevatorMaterials('rendered')
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function setElevatorMaterials(
|
|
|
|
function resolveElevatorFinishMaterial(
|
|
|
|
|
|
|
|
node: ElevatorNode,
|
|
|
|
|
|
|
|
slotId: ElevatorSlotId,
|
|
|
|
|
|
|
|
slotDefault: string,
|
|
|
|
|
|
|
|
sceneMaterials: ElevatorSceneMaterials,
|
|
|
|
shading: RenderShading,
|
|
|
|
shading: RenderShading,
|
|
|
|
textures = true,
|
|
|
|
roughness: number,
|
|
|
|
colorPreset: ColorPreset = 'clay',
|
|
|
|
): Material {
|
|
|
|
) {
|
|
|
|
const ref = node.slots?.[slotId]
|
|
|
|
;({
|
|
|
|
if (ref) {
|
|
|
|
SHAFT_WALL_MATERIAL,
|
|
|
|
const resolved = resolveMaterialRef(ref, sceneMaterials, shading)
|
|
|
|
SHAFT_SIDE_MATERIAL,
|
|
|
|
if (resolved) return resolved
|
|
|
|
SHAFT_TRIM_MATERIAL,
|
|
|
|
}
|
|
|
|
CAB_MATERIAL,
|
|
|
|
return resolveSlotDefaultMaterial(slotDefault, shading, roughness)
|
|
|
|
DOOR_MATERIAL,
|
|
|
|
}
|
|
|
|
DOOR_GROOVE_MATERIAL,
|
|
|
|
|
|
|
|
GLASS_MATERIAL,
|
|
|
|
function withElevatorGlassTransparency(material: Material): Material {
|
|
|
|
PANEL_MATERIAL,
|
|
|
|
const glass = material.clone()
|
|
|
|
LANDING_PANEL_MATERIAL,
|
|
|
|
glass.depthWrite = false
|
|
|
|
INDICATOR_SCREEN_MATERIALS,
|
|
|
|
glass.opacity = 0.2
|
|
|
|
INDICATOR_GLYPH_MATERIALS,
|
|
|
|
glass.transparent = true
|
|
|
|
BUTTON_FACE_MATERIALS,
|
|
|
|
glass.needsUpdate = true
|
|
|
|
BUTTON_RING_MATERIALS,
|
|
|
|
return glass
|
|
|
|
BUTTON_GLOW_MATERIALS,
|
|
|
|
}
|
|
|
|
BUTTON_LABEL_MATERIALS,
|
|
|
|
|
|
|
|
QUEUE_STRIP_MATERIALS,
|
|
|
|
function getResolvedElevatorMaterials(
|
|
|
|
} = getElevatorMaterials(shading, textures, colorPreset))
|
|
|
|
node: ElevatorNode,
|
|
|
|
|
|
|
|
shading: RenderShading,
|
|
|
|
|
|
|
|
textures: boolean,
|
|
|
|
|
|
|
|
colorPreset: ColorPreset,
|
|
|
|
|
|
|
|
sceneMaterials: ElevatorSceneMaterials,
|
|
|
|
|
|
|
|
): ElevatorMaterialSet {
|
|
|
|
|
|
|
|
const materials = getElevatorMaterials(shading, textures, colorPreset)
|
|
|
|
|
|
|
|
if (!textures) return materials
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const cab = resolveElevatorFinishMaterial(
|
|
|
|
|
|
|
|
node,
|
|
|
|
|
|
|
|
'cab',
|
|
|
|
|
|
|
|
ELEVATOR_CAB_SLOT_DEFAULT,
|
|
|
|
|
|
|
|
sceneMaterials,
|
|
|
|
|
|
|
|
shading,
|
|
|
|
|
|
|
|
0.48,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
const doors = resolveElevatorFinishMaterial(
|
|
|
|
|
|
|
|
node,
|
|
|
|
|
|
|
|
'doors',
|
|
|
|
|
|
|
|
ELEVATOR_DOORS_SLOT_DEFAULT,
|
|
|
|
|
|
|
|
sceneMaterials,
|
|
|
|
|
|
|
|
shading,
|
|
|
|
|
|
|
|
0.34,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
const shaft = resolveElevatorFinishMaterial(
|
|
|
|
|
|
|
|
node,
|
|
|
|
|
|
|
|
'shaft',
|
|
|
|
|
|
|
|
ELEVATOR_SHAFT_SLOT_DEFAULT,
|
|
|
|
|
|
|
|
sceneMaterials,
|
|
|
|
|
|
|
|
shading,
|
|
|
|
|
|
|
|
0.56,
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
const glass = withElevatorGlassTransparency(
|
|
|
|
|
|
|
|
resolveElevatorFinishMaterial(
|
|
|
|
|
|
|
|
node,
|
|
|
|
|
|
|
|
'glass',
|
|
|
|
|
|
|
|
ELEVATOR_GLASS_SLOT_DEFAULT,
|
|
|
|
|
|
|
|
sceneMaterials,
|
|
|
|
|
|
|
|
shading,
|
|
|
|
|
|
|
|
0.08,
|
|
|
|
|
|
|
|
),
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
|
|
|
...materials,
|
|
|
|
|
|
|
|
SHAFT_WALL_MATERIAL: shaft,
|
|
|
|
|
|
|
|
SHAFT_SIDE_MATERIAL: shaft,
|
|
|
|
|
|
|
|
SHAFT_TRIM_MATERIAL: shaft,
|
|
|
|
|
|
|
|
CAB_MATERIAL: cab,
|
|
|
|
|
|
|
|
DOOR_MATERIAL: doors,
|
|
|
|
|
|
|
|
DOOR_GROOVE_MATERIAL: doors,
|
|
|
|
|
|
|
|
GLASS_MATERIAL: glass,
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const DEFAULT_ELEVATOR_MATERIALS = getElevatorMaterials('rendered')
|
|
|
|
|
|
|
|
const ElevatorMaterialsContext = createContext<ElevatorMaterialSet>(DEFAULT_ELEVATOR_MATERIALS)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function useElevatorMaterialSet(): ElevatorMaterialSet {
|
|
|
|
|
|
|
|
return useContext(ElevatorMaterialsContext)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const ELEVATOR_SLOT_USER_DATA: Record<ElevatorSlotId, { slotId: ElevatorSlotId }> = {
|
|
|
|
|
|
|
|
cab: { slotId: 'cab' },
|
|
|
|
|
|
|
|
doors: { slotId: 'doors' },
|
|
|
|
|
|
|
|
shaft: { slotId: 'shaft' },
|
|
|
|
|
|
|
|
glass: { slotId: 'glass' },
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
type ElevatorButtonAction = 'open-door' | 'request-level'
|
|
|
|
type ElevatorButtonAction = 'open-door' | 'request-level'
|
|
|
@@ -449,6 +512,7 @@ function BoxPrimitive({
|
|
|
|
receiveShadow = false,
|
|
|
|
receiveShadow = false,
|
|
|
|
rotation,
|
|
|
|
rotation,
|
|
|
|
scale,
|
|
|
|
scale,
|
|
|
|
|
|
|
|
slotId,
|
|
|
|
}: {
|
|
|
|
}: {
|
|
|
|
castShadow?: boolean
|
|
|
|
castShadow?: boolean
|
|
|
|
material: Material
|
|
|
|
material: Material
|
|
|
@@ -456,6 +520,7 @@ function BoxPrimitive({
|
|
|
|
receiveShadow?: boolean
|
|
|
|
receiveShadow?: boolean
|
|
|
|
rotation?: Vector3Tuple
|
|
|
|
rotation?: Vector3Tuple
|
|
|
|
scale: Vector3Tuple
|
|
|
|
scale: Vector3Tuple
|
|
|
|
|
|
|
|
slotId?: ElevatorSlotId
|
|
|
|
}) {
|
|
|
|
}) {
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<mesh
|
|
|
|
<mesh
|
|
|
@@ -467,6 +532,7 @@ function BoxPrimitive({
|
|
|
|
receiveShadow={receiveShadow}
|
|
|
|
receiveShadow={receiveShadow}
|
|
|
|
rotation={rotation}
|
|
|
|
rotation={rotation}
|
|
|
|
scale={scale}
|
|
|
|
scale={scale}
|
|
|
|
|
|
|
|
userData={slotId ? ELEVATOR_SLOT_USER_DATA[slotId] : undefined}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -597,6 +663,8 @@ function ElevatorFloorIndicator({
|
|
|
|
scale?: number
|
|
|
|
scale?: number
|
|
|
|
showReadout?: boolean
|
|
|
|
showReadout?: boolean
|
|
|
|
}) {
|
|
|
|
}) {
|
|
|
|
|
|
|
|
const { INDICATOR_GLYPH_MATERIALS, INDICATOR_SCREEN_MATERIALS, PANEL_MATERIAL } =
|
|
|
|
|
|
|
|
useElevatorMaterialSet()
|
|
|
|
const glyphMaterial = active ? INDICATOR_GLYPH_MATERIALS.active : INDICATOR_GLYPH_MATERIALS.idle
|
|
|
|
const glyphMaterial = active ? INDICATOR_GLYPH_MATERIALS.active : INDICATOR_GLYPH_MATERIALS.idle
|
|
|
|
const screenMaterial = active
|
|
|
|
const screenMaterial = active
|
|
|
|
? INDICATOR_SCREEN_MATERIALS.active
|
|
|
|
? INDICATOR_SCREEN_MATERIALS.active
|
|
|
@@ -721,6 +789,12 @@ function ElevatorMeshButton({
|
|
|
|
queued: boolean
|
|
|
|
queued: boolean
|
|
|
|
radius?: number
|
|
|
|
radius?: number
|
|
|
|
}) {
|
|
|
|
}) {
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
|
|
|
BUTTON_FACE_MATERIALS,
|
|
|
|
|
|
|
|
BUTTON_GLOW_MATERIALS,
|
|
|
|
|
|
|
|
BUTTON_LABEL_MATERIALS,
|
|
|
|
|
|
|
|
BUTTON_RING_MATERIALS,
|
|
|
|
|
|
|
|
} = useElevatorMaterialSet()
|
|
|
|
const state = disabled ? 'disabled' : active ? 'active' : queued ? 'queued' : 'idle'
|
|
|
|
const state = disabled ? 'disabled' : active ? 'active' : queued ? 'queued' : 'idle'
|
|
|
|
const depth = active ? 0.028 : 0.04
|
|
|
|
const depth = active ? 0.028 : 0.04
|
|
|
|
const faceZ = faceSign * (depth / 2 + 0.004)
|
|
|
|
const faceZ = faceSign * (depth / 2 + 0.004)
|
|
|
@@ -845,6 +919,7 @@ function DoorLeaf({
|
|
|
|
y: number
|
|
|
|
y: number
|
|
|
|
z: number
|
|
|
|
z: number
|
|
|
|
}) {
|
|
|
|
}) {
|
|
|
|
|
|
|
|
const { DOOR_GROOVE_MATERIAL, DOOR_MATERIAL, GLASS_MATERIAL } = useElevatorMaterialSet()
|
|
|
|
const ref = useRef<Group>(null)
|
|
|
|
const ref = useRef<Group>(null)
|
|
|
|
const getLeafX = (openAmount: number) => getElevatorDoorLeafX(side, width, openAmount, doorStyle)
|
|
|
|
const getLeafX = (openAmount: number) => getElevatorDoorLeafX(side, width, openAmount, doorStyle)
|
|
|
|
const leafWidth = getElevatorDoorLeafWidth(width, doorStyle)
|
|
|
|
const leafWidth = getElevatorDoorLeafWidth(width, doorStyle)
|
|
|
@@ -880,6 +955,7 @@ function DoorLeaf({
|
|
|
|
position={[0, height / 2 - railHeight / 2, 0]}
|
|
|
|
position={[0, height / 2 - railHeight / 2, 0]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[leafWidth, railHeight, 0.05]}
|
|
|
|
scale={[leafWidth, railHeight, 0.05]}
|
|
|
|
|
|
|
|
slotId="doors"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
|
castShadow
|
|
|
|
castShadow
|
|
|
@@ -887,6 +963,7 @@ function DoorLeaf({
|
|
|
|
position={[0, -height / 2 + railHeight / 2, 0]}
|
|
|
|
position={[0, -height / 2 + railHeight / 2, 0]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[leafWidth, railHeight, 0.05]}
|
|
|
|
scale={[leafWidth, railHeight, 0.05]}
|
|
|
|
|
|
|
|
slotId="doors"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
|
castShadow
|
|
|
|
castShadow
|
|
|
@@ -894,6 +971,7 @@ function DoorLeaf({
|
|
|
|
position={[-leafWidth / 2 + stileWidth / 2, 0, 0]}
|
|
|
|
position={[-leafWidth / 2 + stileWidth / 2, 0, 0]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[stileWidth, height, 0.05]}
|
|
|
|
scale={[stileWidth, height, 0.05]}
|
|
|
|
|
|
|
|
slotId="doors"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
|
castShadow
|
|
|
|
castShadow
|
|
|
@@ -901,11 +979,13 @@ function DoorLeaf({
|
|
|
|
position={[leafWidth / 2 - stileWidth / 2, 0, 0]}
|
|
|
|
position={[leafWidth / 2 - stileWidth / 2, 0, 0]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[stileWidth, height, 0.05]}
|
|
|
|
scale={[stileWidth, height, 0.05]}
|
|
|
|
|
|
|
|
slotId="doors"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
|
material={GLASS_MATERIAL}
|
|
|
|
material={GLASS_MATERIAL}
|
|
|
|
position={[0, 0, -0.004]}
|
|
|
|
position={[0, 0, -0.004]}
|
|
|
|
scale={[glassWidth, glassHeight, 0.012]}
|
|
|
|
scale={[glassWidth, glassHeight, 0.012]}
|
|
|
|
|
|
|
|
slotId="glass"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</>
|
|
|
|
</>
|
|
|
|
) : (
|
|
|
|
) : (
|
|
|
@@ -916,11 +996,13 @@ function DoorLeaf({
|
|
|
|
position={[0, 0, 0]}
|
|
|
|
position={[0, 0, 0]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[leafWidth, height, 0.05]}
|
|
|
|
scale={[leafWidth, height, 0.05]}
|
|
|
|
|
|
|
|
slotId="doors"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
|
material={DOOR_GROOVE_MATERIAL}
|
|
|
|
material={DOOR_GROOVE_MATERIAL}
|
|
|
|
position={[0, 0, -0.028]}
|
|
|
|
position={[0, 0, -0.028]}
|
|
|
|
scale={[0.018, panelInsetHeight, 0.01]}
|
|
|
|
scale={[0.018, panelInsetHeight, 0.01]}
|
|
|
|
|
|
|
|
slotId="doors"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
{resolvedPanelStyle === 'segmented-panel'
|
|
|
|
{resolvedPanelStyle === 'segmented-panel'
|
|
|
|
? Array.from({ length: segmentCount - 1 }).map((_, index) => (
|
|
|
|
? Array.from({ length: segmentCount - 1 }).map((_, index) => (
|
|
|
@@ -929,6 +1011,7 @@ function DoorLeaf({
|
|
|
|
material={DOOR_GROOVE_MATERIAL}
|
|
|
|
material={DOOR_GROOVE_MATERIAL}
|
|
|
|
position={[0, -panelInsetHeight / 2 + segmentSpacing * (index + 1), -0.03]}
|
|
|
|
position={[0, -panelInsetHeight / 2 + segmentSpacing * (index + 1), -0.03]}
|
|
|
|
scale={[panelInsetWidth, 0.018, 0.012]}
|
|
|
|
scale={[panelInsetWidth, 0.018, 0.012]}
|
|
|
|
|
|
|
|
slotId="doors"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
))
|
|
|
|
))
|
|
|
|
: null}
|
|
|
|
: null}
|
|
|
@@ -936,11 +1019,13 @@ function DoorLeaf({
|
|
|
|
material={DOOR_GROOVE_MATERIAL}
|
|
|
|
material={DOOR_GROOVE_MATERIAL}
|
|
|
|
position={[0, panelInsetHeight / 2, -0.029]}
|
|
|
|
position={[0, panelInsetHeight / 2, -0.029]}
|
|
|
|
scale={[panelInsetWidth, 0.012, 0.01]}
|
|
|
|
scale={[panelInsetWidth, 0.012, 0.01]}
|
|
|
|
|
|
|
|
slotId="doors"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
|
material={DOOR_GROOVE_MATERIAL}
|
|
|
|
material={DOOR_GROOVE_MATERIAL}
|
|
|
|
position={[0, -panelInsetHeight / 2, -0.029]}
|
|
|
|
position={[0, -panelInsetHeight / 2, -0.029]}
|
|
|
|
scale={[panelInsetWidth, 0.012, 0.01]}
|
|
|
|
scale={[panelInsetWidth, 0.012, 0.01]}
|
|
|
|
|
|
|
|
slotId="doors"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</>
|
|
|
|
</>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
@@ -1011,6 +1096,7 @@ function LandingDoorFrame({
|
|
|
|
shaftWidth: number
|
|
|
|
shaftWidth: number
|
|
|
|
z: number
|
|
|
|
z: number
|
|
|
|
}) {
|
|
|
|
}) {
|
|
|
|
|
|
|
|
const { SHAFT_TRIM_MATERIAL, SHAFT_WALL_MATERIAL } = useElevatorMaterialSet()
|
|
|
|
const wallDepth = 0.09
|
|
|
|
const wallDepth = 0.09
|
|
|
|
const levelHeight = Math.max(levelTopY - levelY, 0.01)
|
|
|
|
const levelHeight = Math.max(levelTopY - levelY, 0.01)
|
|
|
|
const jambWidth = Math.max((shaftWidth - doorWidth) / 2, 0.08)
|
|
|
|
const jambWidth = Math.max((shaftWidth - doorWidth) / 2, 0.08)
|
|
|
@@ -1026,6 +1112,7 @@ function LandingDoorFrame({
|
|
|
|
position={[-jambCenterOffset, levelY + levelHeight / 2, z]}
|
|
|
|
position={[-jambCenterOffset, levelY + levelHeight / 2, z]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[jambWidth, levelHeight, wallDepth]}
|
|
|
|
scale={[jambWidth, levelHeight, wallDepth]}
|
|
|
|
|
|
|
|
slotId="shaft"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
|
castShadow
|
|
|
|
castShadow
|
|
|
@@ -1033,6 +1120,7 @@ function LandingDoorFrame({
|
|
|
|
position={[jambCenterOffset, levelY + levelHeight / 2, z]}
|
|
|
|
position={[jambCenterOffset, levelY + levelHeight / 2, z]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[jambWidth, levelHeight, wallDepth]}
|
|
|
|
scale={[jambWidth, levelHeight, wallDepth]}
|
|
|
|
|
|
|
|
slotId="shaft"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
{headerHeight > 0.01 && (
|
|
|
|
{headerHeight > 0.01 && (
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
@@ -1041,6 +1129,7 @@ function LandingDoorFrame({
|
|
|
|
position={[0, levelY + doorHeight + headerHeight / 2, z]}
|
|
|
|
position={[0, levelY + doorHeight + headerHeight / 2, z]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[shaftWidth, headerHeight, wallDepth]}
|
|
|
|
scale={[shaftWidth, headerHeight, wallDepth]}
|
|
|
|
|
|
|
|
slotId="shaft"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
)}
|
|
|
|
)}
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
@@ -1049,6 +1138,7 @@ function LandingDoorFrame({
|
|
|
|
position={[0, levelY + trim / 2, z - 0.006]}
|
|
|
|
position={[0, levelY + trim / 2, z - 0.006]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[doorWidth + trim * 2, trim, wallDepth * 1.12]}
|
|
|
|
scale={[doorWidth + trim * 2, trim, wallDepth * 1.12]}
|
|
|
|
|
|
|
|
slotId="shaft"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
|
castShadow
|
|
|
|
castShadow
|
|
|
@@ -1056,6 +1146,7 @@ function LandingDoorFrame({
|
|
|
|
position={[-doorWidth / 2 - trim / 2, levelY + doorHeight / 2, z - 0.006]}
|
|
|
|
position={[-doorWidth / 2 - trim / 2, levelY + doorHeight / 2, z - 0.006]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[trim, doorHeight, wallDepth * 1.12]}
|
|
|
|
scale={[trim, doorHeight, wallDepth * 1.12]}
|
|
|
|
|
|
|
|
slotId="shaft"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
|
castShadow
|
|
|
|
castShadow
|
|
|
@@ -1063,6 +1154,7 @@ function LandingDoorFrame({
|
|
|
|
position={[doorWidth / 2 + trim / 2, levelY + doorHeight / 2, z - 0.006]}
|
|
|
|
position={[doorWidth / 2 + trim / 2, levelY + doorHeight / 2, z - 0.006]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[trim, doorHeight, wallDepth * 1.12]}
|
|
|
|
scale={[trim, doorHeight, wallDepth * 1.12]}
|
|
|
|
|
|
|
|
slotId="shaft"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
|
castShadow
|
|
|
|
castShadow
|
|
|
@@ -1070,6 +1162,7 @@ function LandingDoorFrame({
|
|
|
|
position={[0, levelY + doorHeight + trim / 2, z - 0.006]}
|
|
|
|
position={[0, levelY + doorHeight + trim / 2, z - 0.006]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[doorWidth + trim * 2, trim, wallDepth * 1.12]}
|
|
|
|
scale={[doorWidth + trim * 2, trim, wallDepth * 1.12]}
|
|
|
|
|
|
|
|
slotId="shaft"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
</>
|
|
|
|
</>
|
|
|
|
)
|
|
|
|
)
|
|
|
@@ -1119,6 +1212,7 @@ export const ElevatorRenderer = ({ node }: { node: ElevatorNode }) => {
|
|
|
|
const shading = useViewer((state) => state.shading)
|
|
|
|
const shading = useViewer((state) => state.shading)
|
|
|
|
const textures = useViewer((state) => state.textures)
|
|
|
|
const textures = useViewer((state) => state.textures)
|
|
|
|
const colorPreset = useViewer((state) => state.colorPreset)
|
|
|
|
const colorPreset = useViewer((state) => state.colorPreset)
|
|
|
|
|
|
|
|
const sceneMaterials = useScene((state) => state.materials)
|
|
|
|
const liveOverrides = useLiveNodeOverrides((state) => state.get(node.id))
|
|
|
|
const liveOverrides = useLiveNodeOverrides((state) => state.get(node.id))
|
|
|
|
const liveTransform = useLiveTransforms((state) => state.get(node.id))
|
|
|
|
const liveTransform = useLiveTransforms((state) => state.get(node.id))
|
|
|
|
const renderNode = useMemo(
|
|
|
|
const renderNode = useMemo(
|
|
|
@@ -1128,8 +1222,19 @@ export const ElevatorRenderer = ({ node }: { node: ElevatorNode }) => {
|
|
|
|
const levelContextNodes = useScene(
|
|
|
|
const levelContextNodes = useScene(
|
|
|
|
useShallow((state) => getElevatorLevelContextNodes(renderNode, state.nodes)),
|
|
|
|
useShallow((state) => getElevatorLevelContextNodes(renderNode, state.nodes)),
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
const materials = useMemo(
|
|
|
|
setElevatorMaterials(shading, textures, colorPreset)
|
|
|
|
() => getResolvedElevatorMaterials(renderNode, shading, textures, colorPreset, sceneMaterials),
|
|
|
|
|
|
|
|
[colorPreset, renderNode, sceneMaterials, shading, textures],
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
const {
|
|
|
|
|
|
|
|
CAB_MATERIAL,
|
|
|
|
|
|
|
|
GLASS_MATERIAL,
|
|
|
|
|
|
|
|
LANDING_PANEL_MATERIAL,
|
|
|
|
|
|
|
|
PANEL_MATERIAL,
|
|
|
|
|
|
|
|
QUEUE_STRIP_MATERIALS,
|
|
|
|
|
|
|
|
SHAFT_SIDE_MATERIAL,
|
|
|
|
|
|
|
|
SHAFT_TRIM_MATERIAL,
|
|
|
|
|
|
|
|
} = materials
|
|
|
|
|
|
|
|
|
|
|
|
useRegistry(node.id, 'elevator', ref)
|
|
|
|
useRegistry(node.id, 'elevator', ref)
|
|
|
|
|
|
|
|
|
|
|
@@ -1174,6 +1279,7 @@ export const ElevatorRenderer = ({ node }: { node: ElevatorNode }) => {
|
|
|
|
const doorStyle = getResolvedDoorStyle(renderNode.doorStyle)
|
|
|
|
const doorStyle = getResolvedDoorStyle(renderNode.doorStyle)
|
|
|
|
const shaftStyle = getResolvedShaftStyle(renderNode.shaftStyle)
|
|
|
|
const shaftStyle = getResolvedShaftStyle(renderNode.shaftStyle)
|
|
|
|
const shaftShellMaterial = shaftStyle === 'glass' ? GLASS_MATERIAL : SHAFT_SIDE_MATERIAL
|
|
|
|
const shaftShellMaterial = shaftStyle === 'glass' ? GLASS_MATERIAL : SHAFT_SIDE_MATERIAL
|
|
|
|
|
|
|
|
const shaftShellSlotId: ElevatorSlotId = shaftStyle === 'glass' ? 'glass' : 'shaft'
|
|
|
|
const shaftTopMaterial = shaftStyle === 'glass' ? SHAFT_TRIM_MATERIAL : SHAFT_SIDE_MATERIAL
|
|
|
|
const shaftTopMaterial = shaftStyle === 'glass' ? SHAFT_TRIM_MATERIAL : SHAFT_SIDE_MATERIAL
|
|
|
|
const shaftHeight = Math.max(totalHeight, cabHeight + 0.3)
|
|
|
|
const shaftHeight = Math.max(totalHeight, cabHeight + 0.3)
|
|
|
|
const shaftBodyHeight = Math.max(shaftHeight - shaftWallThickness, 0.01)
|
|
|
|
const shaftBodyHeight = Math.max(shaftHeight - shaftWallThickness, 0.01)
|
|
|
@@ -1269,19 +1375,21 @@ export const ElevatorRenderer = ({ node }: { node: ElevatorNode }) => {
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
return (
|
|
|
|
<group
|
|
|
|
<ElevatorMaterialsContext.Provider value={materials}>
|
|
|
|
position={liveTransform?.position ?? renderNode.position}
|
|
|
|
<group
|
|
|
|
ref={ref}
|
|
|
|
position={liveTransform?.position ?? renderNode.position}
|
|
|
|
rotation-y={liveTransform?.rotation ?? renderNode.rotation}
|
|
|
|
ref={ref}
|
|
|
|
visible={renderNode.visible}
|
|
|
|
rotation-y={liveTransform?.rotation ?? renderNode.rotation}
|
|
|
|
{...handlers}
|
|
|
|
visible={renderNode.visible}
|
|
|
|
>
|
|
|
|
{...handlers}
|
|
|
|
|
|
|
|
>
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
|
castShadow
|
|
|
|
castShadow
|
|
|
|
material={shaftShellMaterial}
|
|
|
|
material={shaftShellMaterial}
|
|
|
|
position={[0, shaftBodyCenterY, shaftDepth / 2 + shaftWallThickness / 2]}
|
|
|
|
position={[0, shaftBodyCenterY, shaftDepth / 2 + shaftWallThickness / 2]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[shaftWidth + shaftWallThickness * 2, shaftBodyHeight, shaftWallThickness]}
|
|
|
|
scale={[shaftWidth + shaftWallThickness * 2, shaftBodyHeight, shaftWallThickness]}
|
|
|
|
|
|
|
|
slotId={shaftShellSlotId}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
|
castShadow
|
|
|
|
castShadow
|
|
|
@@ -1289,6 +1397,7 @@ export const ElevatorRenderer = ({ node }: { node: ElevatorNode }) => {
|
|
|
|
position={[-shaftWidth / 2 - shaftWallThickness / 2, shaftBodyCenterY, 0]}
|
|
|
|
position={[-shaftWidth / 2 - shaftWallThickness / 2, shaftBodyCenterY, 0]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[shaftWallThickness, shaftBodyHeight, shaftDepth + shaftWallThickness * 2]}
|
|
|
|
scale={[shaftWallThickness, shaftBodyHeight, shaftDepth + shaftWallThickness * 2]}
|
|
|
|
|
|
|
|
slotId={shaftShellSlotId}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
|
castShadow
|
|
|
|
castShadow
|
|
|
@@ -1296,6 +1405,7 @@ export const ElevatorRenderer = ({ node }: { node: ElevatorNode }) => {
|
|
|
|
position={[shaftWidth / 2 + shaftWallThickness / 2, shaftBodyCenterY, 0]}
|
|
|
|
position={[shaftWidth / 2 + shaftWallThickness / 2, shaftBodyCenterY, 0]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[shaftWallThickness, shaftBodyHeight, shaftDepth + shaftWallThickness * 2]}
|
|
|
|
scale={[shaftWallThickness, shaftBodyHeight, shaftDepth + shaftWallThickness * 2]}
|
|
|
|
|
|
|
|
slotId={shaftShellSlotId}
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
|
castShadow
|
|
|
|
castShadow
|
|
|
@@ -1307,6 +1417,7 @@ export const ElevatorRenderer = ({ node }: { node: ElevatorNode }) => {
|
|
|
|
shaftWallThickness,
|
|
|
|
shaftWallThickness,
|
|
|
|
shaftDepth + shaftWallThickness * 2,
|
|
|
|
shaftDepth + shaftWallThickness * 2,
|
|
|
|
]}
|
|
|
|
]}
|
|
|
|
|
|
|
|
slotId="shaft"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<group ref={cabRef} position={[0, cabBaseY, 0]}>
|
|
|
|
<group ref={cabRef} position={[0, cabBaseY, 0]}>
|
|
|
@@ -1316,6 +1427,7 @@ export const ElevatorRenderer = ({ node }: { node: ElevatorNode }) => {
|
|
|
|
position={[0, 0.04, cabCenterZ]}
|
|
|
|
position={[0, 0.04, cabCenterZ]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[cabWidth, 0.08, cabDepth]}
|
|
|
|
scale={[cabWidth, 0.08, cabDepth]}
|
|
|
|
|
|
|
|
slotId="cab"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
@@ -1324,6 +1436,7 @@ export const ElevatorRenderer = ({ node }: { node: ElevatorNode }) => {
|
|
|
|
position={[0, cabHeight - 0.04, cabCenterZ]}
|
|
|
|
position={[0, cabHeight - 0.04, cabCenterZ]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[cabWidth, 0.08, cabDepth]}
|
|
|
|
scale={[cabWidth, 0.08, cabDepth]}
|
|
|
|
|
|
|
|
slotId="cab"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
@@ -1332,6 +1445,7 @@ export const ElevatorRenderer = ({ node }: { node: ElevatorNode }) => {
|
|
|
|
position={[0, cabHeight / 2, cabCenterZ + cabDepth / 2 - 0.04]}
|
|
|
|
position={[0, cabHeight / 2, cabCenterZ + cabDepth / 2 - 0.04]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[cabWidth, cabHeight, 0.08]}
|
|
|
|
scale={[cabWidth, cabHeight, 0.08]}
|
|
|
|
|
|
|
|
slotId="cab"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
@@ -1340,6 +1454,7 @@ export const ElevatorRenderer = ({ node }: { node: ElevatorNode }) => {
|
|
|
|
position={[-cabWidth / 2 + 0.04, cabHeight / 2, cabCenterZ]}
|
|
|
|
position={[-cabWidth / 2 + 0.04, cabHeight / 2, cabCenterZ]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[0.08, cabHeight, cabDepth]}
|
|
|
|
scale={[0.08, cabHeight, cabDepth]}
|
|
|
|
|
|
|
|
slotId="cab"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<BoxPrimitive
|
|
|
|
<BoxPrimitive
|
|
|
@@ -1348,6 +1463,7 @@ export const ElevatorRenderer = ({ node }: { node: ElevatorNode }) => {
|
|
|
|
position={[cabWidth / 2 - 0.04, cabHeight / 2, cabCenterZ]}
|
|
|
|
position={[cabWidth / 2 - 0.04, cabHeight / 2, cabCenterZ]}
|
|
|
|
receiveShadow
|
|
|
|
receiveShadow
|
|
|
|
scale={[0.08, cabHeight, cabDepth]}
|
|
|
|
scale={[0.08, cabHeight, cabDepth]}
|
|
|
|
|
|
|
|
slotId="cab"
|
|
|
|
/>
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
<ElevatorDoorLeaves
|
|
|
|
<ElevatorDoorLeaves
|
|
|
@@ -1479,7 +1595,8 @@ export const ElevatorRenderer = ({ node }: { node: ElevatorNode }) => {
|
|
|
|
</group>
|
|
|
|
</group>
|
|
|
|
)
|
|
|
|
)
|
|
|
|
})}
|
|
|
|
})}
|
|
|
|
</group>
|
|
|
|
</group>
|
|
|
|
|
|
|
|
</ElevatorMaterialsContext.Provider>
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|