@3driseai/3drise-viewer 0.1.42 → 0.1.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/animationsV2/ClipsRuntime.d.ts +16 -1
- package/dist/animationsV2/ClipsRuntime.d.ts.map +1 -1
- package/dist/animationsV2/ClipsRuntime.js +144 -25
- package/dist/animationsV2/appliers.d.ts +9 -0
- package/dist/animationsV2/appliers.d.ts.map +1 -1
- package/dist/animationsV2/appliers.js +62 -2
- package/dist/animationsV2/clipUtils.d.ts +30 -0
- package/dist/animationsV2/clipUtils.d.ts.map +1 -1
- package/dist/animationsV2/clipUtils.js +163 -17
- package/dist/animationsV2/elementSettings.d.ts +5 -0
- package/dist/animationsV2/elementSettings.d.ts.map +1 -1
- package/dist/animationsV2/elementSettings.js +6 -3
- package/dist/animationsV2/sequenceUtils.js +4 -4
- package/dist/animationsV2/types.d.ts +23 -0
- package/dist/animationsV2/types.d.ts.map +1 -1
- package/dist/api/sceneHandle.js +2 -2
- package/dist/components/CreatedObject.d.ts +3 -0
- package/dist/components/CreatedObject.d.ts.map +1 -1
- package/dist/components/CreatedObject.js +6 -2
- package/dist/components/CustomPrimitive.d.ts.map +1 -1
- package/dist/components/CustomPrimitive.js +1 -10
- package/dist/components/EnvironmentManager.d.ts.map +1 -1
- package/dist/components/EnvironmentManager.js +11 -5
- package/dist/components/GeometryShape.d.ts +5 -2
- package/dist/components/GeometryShape.d.ts.map +1 -1
- package/dist/components/GeometryShape.js +71 -10
- package/dist/components/LandObject.d.ts.map +1 -1
- package/dist/components/LandObject.js +1 -1
- package/dist/components/LayoutInstances.d.ts +2 -1
- package/dist/components/LayoutInstances.d.ts.map +1 -1
- package/dist/components/LayoutInstances.js +39 -6
- package/dist/components/LightObject.d.ts.map +1 -1
- package/dist/components/LightObject.js +3 -0
- package/dist/components/ObjectNode.d.ts.map +1 -1
- package/dist/components/ObjectNode.js +62 -13
- package/dist/components/OceanBuilder.d.ts +2 -0
- package/dist/components/OceanBuilder.d.ts.map +1 -1
- package/dist/components/OceanBuilder.js +2 -1
- package/dist/components/RenderEffects.d.ts +8 -0
- package/dist/components/RenderEffects.d.ts.map +1 -0
- package/dist/components/RenderEffects.js +120 -0
- package/dist/components/SceneBuilder.d.ts.map +1 -1
- package/dist/components/SceneBuilder.js +18 -9
- package/dist/components/SportsObject.d.ts +9 -0
- package/dist/components/SportsObject.d.ts.map +1 -0
- package/dist/components/SportsObject.js +20 -0
- package/dist/components/UrbanObject.d.ts +9 -0
- package/dist/components/UrbanObject.d.ts.map +1 -0
- package/dist/components/UrbanObject.js +28 -0
- package/dist/components/VegetationObject.d.ts +9 -0
- package/dist/components/VegetationObject.d.ts.map +1 -0
- package/dist/components/VegetationObject.js +26 -0
- package/dist/components/WaterObject.d.ts +15 -0
- package/dist/components/WaterObject.d.ts.map +1 -0
- package/dist/components/WaterObject.js +29 -0
- package/dist/components/index.d.ts +7 -2
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +6 -1
- package/dist/components/land/LandPatch.d.ts +3 -1
- package/dist/components/land/LandPatch.d.ts.map +1 -1
- package/dist/components/land/LandPatch.js +80 -7
- package/dist/components/layout/InstancedLayout.d.ts +19 -0
- package/dist/components/layout/InstancedLayout.d.ts.map +1 -0
- package/dist/components/layout/InstancedLayout.js +154 -0
- package/dist/components/layout/LayoutGrounds.d.ts +19 -0
- package/dist/components/layout/LayoutGrounds.d.ts.map +1 -0
- package/dist/components/layout/LayoutGrounds.js +104 -0
- package/dist/components/layout/LinkProxies.d.ts +5 -0
- package/dist/components/layout/LinkProxies.d.ts.map +1 -0
- package/dist/components/layout/LinkProxies.js +51 -0
- package/dist/components/layout/LinkedSource.d.ts +14 -0
- package/dist/components/layout/LinkedSource.d.ts.map +1 -0
- package/dist/components/layout/LinkedSource.js +129 -0
- package/dist/components/projector/Projector.d.ts +14 -0
- package/dist/components/projector/Projector.d.ts.map +1 -0
- package/dist/components/projector/Projector.js +44 -0
- package/dist/components/projector/index.d.ts +4 -0
- package/dist/components/projector/index.d.ts.map +1 -0
- package/dist/components/projector/index.js +2 -0
- package/dist/components/projector/projectorCore.d.ts +19 -0
- package/dist/components/projector/projectorCore.d.ts.map +1 -0
- package/dist/components/projector/projectorCore.js +545 -0
- package/dist/components/sports/SportsBall.d.ts +9 -0
- package/dist/components/sports/SportsBall.d.ts.map +1 -0
- package/dist/components/sports/SportsBall.js +23 -0
- package/dist/components/sports/SportsCourt.d.ts +9 -0
- package/dist/components/sports/SportsCourt.d.ts.map +1 -0
- package/dist/components/sports/SportsCourt.js +23 -0
- package/dist/components/sports/SportsEquipment.d.ts +9 -0
- package/dist/components/sports/SportsEquipment.d.ts.map +1 -0
- package/dist/components/sports/SportsEquipment.js +23 -0
- package/dist/components/sports/SportsGoal.d.ts +9 -0
- package/dist/components/sports/SportsGoal.d.ts.map +1 -0
- package/dist/components/sports/SportsGoal.js +23 -0
- package/dist/components/sports/core/ball.d.ts +166 -0
- package/dist/components/sports/core/ball.d.ts.map +1 -0
- package/dist/components/sports/core/ball.js +402 -0
- package/dist/components/sports/core/court.d.ts +442 -0
- package/dist/components/sports/core/court.d.ts.map +1 -0
- package/dist/components/sports/core/court.js +658 -0
- package/dist/components/sports/core/equipment.d.ts +103 -0
- package/dist/components/sports/core/equipment.d.ts.map +1 -0
- package/dist/components/sports/core/equipment.js +403 -0
- package/dist/components/sports/core/goal.d.ts +98 -0
- package/dist/components/sports/core/goal.d.ts.map +1 -0
- package/dist/components/sports/core/goal.js +44 -0
- package/dist/components/sports/index.d.ts +11 -0
- package/dist/components/sports/index.d.ts.map +1 -0
- package/dist/components/sports/index.js +8 -0
- package/dist/components/sports/sportsCore.d.ts +195 -0
- package/dist/components/sports/sportsCore.d.ts.map +1 -0
- package/dist/components/sports/sportsCore.js +758 -0
- package/dist/components/sports/useSportsInstance.d.ts +35 -0
- package/dist/components/sports/useSportsInstance.d.ts.map +1 -0
- package/dist/components/sports/useSportsInstance.js +47 -0
- package/dist/components/terrain/TerrainSurface.d.ts.map +1 -1
- package/dist/components/terrain/TerrainSurface.js +14 -0
- package/dist/components/urban/UrbanBlock.d.ts +9 -0
- package/dist/components/urban/UrbanBlock.d.ts.map +1 -0
- package/dist/components/urban/UrbanBlock.js +23 -0
- package/dist/components/urban/UrbanBuilding.d.ts +9 -0
- package/dist/components/urban/UrbanBuilding.d.ts.map +1 -0
- package/dist/components/urban/UrbanBuilding.js +23 -0
- package/dist/components/urban/UrbanJunction.d.ts +9 -0
- package/dist/components/urban/UrbanJunction.d.ts.map +1 -0
- package/dist/components/urban/UrbanJunction.js +23 -0
- package/dist/components/urban/UrbanPark.d.ts +9 -0
- package/dist/components/urban/UrbanPark.d.ts.map +1 -0
- package/dist/components/urban/UrbanPark.js +23 -0
- package/dist/components/urban/UrbanParkingLot.d.ts +9 -0
- package/dist/components/urban/UrbanParkingLot.d.ts.map +1 -0
- package/dist/components/urban/UrbanParkingLot.js +23 -0
- package/dist/components/urban/UrbanPlaza.d.ts +9 -0
- package/dist/components/urban/UrbanPlaza.d.ts.map +1 -0
- package/dist/components/urban/UrbanPlaza.js +23 -0
- package/dist/components/urban/UrbanRoad.d.ts +9 -0
- package/dist/components/urban/UrbanRoad.d.ts.map +1 -0
- package/dist/components/urban/UrbanRoad.js +23 -0
- package/dist/components/urban/UrbanSignage.d.ts +9 -0
- package/dist/components/urban/UrbanSignage.d.ts.map +1 -0
- package/dist/components/urban/UrbanSignage.js +23 -0
- package/dist/components/urban/UrbanSkyline.d.ts +9 -0
- package/dist/components/urban/UrbanSkyline.d.ts.map +1 -0
- package/dist/components/urban/UrbanSkyline.js +23 -0
- package/dist/components/urban/UrbanStreetFurniture.d.ts +9 -0
- package/dist/components/urban/UrbanStreetFurniture.d.ts.map +1 -0
- package/dist/components/urban/UrbanStreetFurniture.js +23 -0
- package/dist/components/urban/UrbanStreetGrid.d.ts +9 -0
- package/dist/components/urban/UrbanStreetGrid.d.ts.map +1 -0
- package/dist/components/urban/UrbanStreetGrid.js +34 -0
- package/dist/components/urban/UrbanTraffic.d.ts +9 -0
- package/dist/components/urban/UrbanTraffic.d.ts.map +1 -0
- package/dist/components/urban/UrbanTraffic.js +23 -0
- package/dist/components/urban/core/block.d.ts +119 -0
- package/dist/components/urban/core/block.d.ts.map +1 -0
- package/dist/components/urban/core/block.js +266 -0
- package/dist/components/urban/core/building.d.ts +128 -0
- package/dist/components/urban/core/building.d.ts.map +1 -0
- package/dist/components/urban/core/building.js +741 -0
- package/dist/components/urban/core/junction.d.ts +152 -0
- package/dist/components/urban/core/junction.d.ts.map +1 -0
- package/dist/components/urban/core/junction.js +617 -0
- package/dist/components/urban/core/park.d.ts +67 -0
- package/dist/components/urban/core/park.d.ts.map +1 -0
- package/dist/components/urban/core/park.js +176 -0
- package/dist/components/urban/core/parkingLot.d.ts +82 -0
- package/dist/components/urban/core/parkingLot.d.ts.map +1 -0
- package/dist/components/urban/core/parkingLot.js +284 -0
- package/dist/components/urban/core/plaza.d.ts +24 -0
- package/dist/components/urban/core/plaza.d.ts.map +1 -0
- package/dist/components/urban/core/plaza.js +243 -0
- package/dist/components/urban/core/road.d.ts +113 -0
- package/dist/components/urban/core/road.d.ts.map +1 -0
- package/dist/components/urban/core/road.js +347 -0
- package/dist/components/urban/core/signage.d.ts +83 -0
- package/dist/components/urban/core/signage.d.ts.map +1 -0
- package/dist/components/urban/core/signage.js +209 -0
- package/dist/components/urban/core/skyline.d.ts +100 -0
- package/dist/components/urban/core/skyline.d.ts.map +1 -0
- package/dist/components/urban/core/skyline.js +89 -0
- package/dist/components/urban/core/streetFurniture.d.ts +75 -0
- package/dist/components/urban/core/streetFurniture.d.ts.map +1 -0
- package/dist/components/urban/core/streetFurniture.js +193 -0
- package/dist/components/urban/core/streetGrid.d.ts +134 -0
- package/dist/components/urban/core/streetGrid.d.ts.map +1 -0
- package/dist/components/urban/core/streetGrid.js +422 -0
- package/dist/components/urban/core/traffic.d.ts +125 -0
- package/dist/components/urban/core/traffic.d.ts.map +1 -0
- package/dist/components/urban/core/traffic.js +305 -0
- package/dist/components/urban/index.d.ts +29 -0
- package/dist/components/urban/index.d.ts.map +1 -0
- package/dist/components/urban/index.js +16 -0
- package/dist/components/urban/textureSetResolver.d.ts +8 -0
- package/dist/components/urban/textureSetResolver.d.ts.map +1 -0
- package/dist/components/urban/textureSetResolver.js +16 -0
- package/dist/components/urban/urbanCore.d.ts +262 -0
- package/dist/components/urban/urbanCore.d.ts.map +1 -0
- package/dist/components/urban/urbanCore.js +928 -0
- package/dist/components/urban/useUrbanInstance.d.ts +53 -0
- package/dist/components/urban/useUrbanInstance.d.ts.map +1 -0
- package/dist/components/urban/useUrbanInstance.js +100 -0
- package/dist/components/vegetation/VegetationBush.d.ts +9 -0
- package/dist/components/vegetation/VegetationBush.d.ts.map +1 -0
- package/dist/components/vegetation/VegetationBush.js +23 -0
- package/dist/components/vegetation/VegetationCrops.d.ts +9 -0
- package/dist/components/vegetation/VegetationCrops.d.ts.map +1 -0
- package/dist/components/vegetation/VegetationCrops.js +23 -0
- package/dist/components/vegetation/VegetationFlowers.d.ts +9 -0
- package/dist/components/vegetation/VegetationFlowers.d.ts.map +1 -0
- package/dist/components/vegetation/VegetationFlowers.js +23 -0
- package/dist/components/vegetation/VegetationForest.d.ts +9 -0
- package/dist/components/vegetation/VegetationForest.d.ts.map +1 -0
- package/dist/components/vegetation/VegetationForest.js +23 -0
- package/dist/components/vegetation/VegetationFruit.d.ts +9 -0
- package/dist/components/vegetation/VegetationFruit.d.ts.map +1 -0
- package/dist/components/vegetation/VegetationFruit.js +23 -0
- package/dist/components/vegetation/VegetationGrass.d.ts +9 -0
- package/dist/components/vegetation/VegetationGrass.d.ts.map +1 -0
- package/dist/components/vegetation/VegetationGrass.js +23 -0
- package/dist/components/vegetation/VegetationHedge.d.ts +9 -0
- package/dist/components/vegetation/VegetationHedge.d.ts.map +1 -0
- package/dist/components/vegetation/VegetationHedge.js +23 -0
- package/dist/components/vegetation/VegetationIvy.d.ts +9 -0
- package/dist/components/vegetation/VegetationIvy.d.ts.map +1 -0
- package/dist/components/vegetation/VegetationIvy.js +23 -0
- package/dist/components/vegetation/VegetationTree.d.ts +9 -0
- package/dist/components/vegetation/VegetationTree.d.ts.map +1 -0
- package/dist/components/vegetation/VegetationTree.js +23 -0
- package/dist/components/vegetation/VegetationVegetable.d.ts +9 -0
- package/dist/components/vegetation/VegetationVegetable.d.ts.map +1 -0
- package/dist/components/vegetation/VegetationVegetable.js +23 -0
- package/dist/components/vegetation/core/bush.d.ts +1256 -0
- package/dist/components/vegetation/core/bush.d.ts.map +1 -0
- package/dist/components/vegetation/core/bush.js +376 -0
- package/dist/components/vegetation/core/crops.d.ts +1033 -0
- package/dist/components/vegetation/core/crops.d.ts.map +1 -0
- package/dist/components/vegetation/core/crops.js +378 -0
- package/dist/components/vegetation/core/flowers.d.ts +648 -0
- package/dist/components/vegetation/core/flowers.d.ts.map +1 -0
- package/dist/components/vegetation/core/flowers.js +225 -0
- package/dist/components/vegetation/core/forest.d.ts +138 -0
- package/dist/components/vegetation/core/forest.d.ts.map +1 -0
- package/dist/components/vegetation/core/forest.js +310 -0
- package/dist/components/vegetation/core/fruit.d.ts +99 -0
- package/dist/components/vegetation/core/fruit.d.ts.map +1 -0
- package/dist/components/vegetation/core/fruit.js +77 -0
- package/dist/components/vegetation/core/grass.d.ts +103 -0
- package/dist/components/vegetation/core/grass.d.ts.map +1 -0
- package/dist/components/vegetation/core/grass.js +102 -0
- package/dist/components/vegetation/core/hedge.d.ts +193 -0
- package/dist/components/vegetation/core/hedge.d.ts.map +1 -0
- package/dist/components/vegetation/core/hedge.js +243 -0
- package/dist/components/vegetation/core/ivy.d.ts +213 -0
- package/dist/components/vegetation/core/ivy.d.ts.map +1 -0
- package/dist/components/vegetation/core/ivy.js +173 -0
- package/dist/components/vegetation/core/tree.d.ts +1117 -0
- package/dist/components/vegetation/core/tree.d.ts.map +1 -0
- package/dist/components/vegetation/core/tree.js +408 -0
- package/dist/components/vegetation/core/vegetable.d.ts +99 -0
- package/dist/components/vegetation/core/vegetable.d.ts.map +1 -0
- package/dist/components/vegetation/core/vegetable.js +76 -0
- package/dist/components/vegetation/index.d.ts +23 -0
- package/dist/components/vegetation/index.d.ts.map +1 -0
- package/dist/components/vegetation/index.js +14 -0
- package/dist/components/vegetation/produceCore.d.ts +929 -0
- package/dist/components/vegetation/produceCore.d.ts.map +1 -0
- package/dist/components/vegetation/produceCore.js +723 -0
- package/dist/components/vegetation/useVegetationInstance.d.ts +39 -0
- package/dist/components/vegetation/useVegetationInstance.d.ts.map +1 -0
- package/dist/components/vegetation/useVegetationInstance.js +45 -0
- package/dist/components/vegetation/vegetationCore.d.ts +412 -0
- package/dist/components/vegetation/vegetationCore.d.ts.map +1 -0
- package/dist/components/vegetation/vegetationCore.js +1728 -0
- package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts +5 -0
- package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts.map +1 -1
- package/dist/components/volumetricClouds/VolumetricCloudsPass.js +39 -13
- package/dist/components/water/OceanSurface.d.ts.map +1 -1
- package/dist/components/water/OceanSurface.js +3 -2
- package/dist/components/water/WaterBody.d.ts.map +1 -1
- package/dist/components/water/WaterBody.js +31 -10
- package/dist/components/water/WaterFountain.d.ts +9 -0
- package/dist/components/water/WaterFountain.d.ts.map +1 -0
- package/dist/components/water/WaterFountain.js +24 -0
- package/dist/components/water/WaterStream.d.ts +9 -0
- package/dist/components/water/WaterStream.d.ts.map +1 -0
- package/dist/components/water/WaterStream.js +24 -0
- package/dist/components/water/WaterWaterfall.d.ts +9 -0
- package/dist/components/water/WaterWaterfall.d.ts.map +1 -0
- package/dist/components/water/WaterWaterfall.js +24 -0
- package/dist/components/water/core/fountain.d.ts +70 -0
- package/dist/components/water/core/fountain.d.ts.map +1 -0
- package/dist/components/water/core/fountain.js +619 -0
- package/dist/components/water/core/stream.d.ts +72 -0
- package/dist/components/water/core/stream.d.ts.map +1 -0
- package/dist/components/water/core/stream.js +167 -0
- package/dist/components/water/core/waterfall.d.ts +78 -0
- package/dist/components/water/core/waterfall.d.ts.map +1 -0
- package/dist/components/water/core/waterfall.js +325 -0
- package/dist/components/water/index.d.ts +8 -0
- package/dist/components/water/index.d.ts.map +1 -1
- package/dist/components/water/index.js +7 -0
- package/dist/components/water/types.d.ts +3 -0
- package/dist/components/water/types.d.ts.map +1 -1
- package/dist/components/water/useWaterInstance.d.ts +43 -0
- package/dist/components/water/useWaterInstance.d.ts.map +1 -0
- package/dist/components/water/useWaterInstance.js +89 -0
- package/dist/components/water/waterCore.d.ts +179 -0
- package/dist/components/water/waterCore.d.ts.map +1 -0
- package/dist/components/water/waterCore.js +516 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +9 -1
- package/dist/hooks/index.d.ts +7 -2
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +5 -2
- package/dist/hooks/useActionPatch.d.ts +23 -0
- package/dist/hooks/useActionPatch.d.ts.map +1 -0
- package/dist/hooks/useActionPatch.js +38 -0
- package/dist/hooks/useCloudSun.d.ts.map +1 -1
- package/dist/hooks/useCloudSun.js +3 -2
- package/dist/hooks/useCommittedInstance.d.ts +6 -0
- package/dist/hooks/useCommittedInstance.d.ts.map +1 -0
- package/dist/hooks/useCommittedInstance.js +42 -0
- package/dist/hooks/useConfigLive.d.ts +1 -1
- package/dist/hooks/useConfigLive.d.ts.map +1 -1
- package/dist/hooks/useContinuousEffects.d.ts.map +1 -1
- package/dist/hooks/useContinuousEffects.js +36 -20
- package/dist/hooks/useGridLayout.d.ts +7 -0
- package/dist/hooks/useGridLayout.d.ts.map +1 -0
- package/dist/hooks/useGridLayout.js +10 -0
- package/dist/hooks/useInteractionEffects.d.ts.map +1 -1
- package/dist/hooks/useInteractionEffects.js +48 -9
- package/dist/hooks/useLightLive.d.ts.map +1 -1
- package/dist/hooks/useLightLive.js +2 -0
- package/dist/hooks/useLinkStatus.d.ts +7 -0
- package/dist/hooks/useLinkStatus.d.ts.map +1 -0
- package/dist/hooks/useLinkStatus.js +20 -0
- package/dist/hooks/useMaterialApplication.d.ts +6 -1
- package/dist/hooks/useMaterialApplication.d.ts.map +1 -1
- package/dist/hooks/useMaterialApplication.js +7 -2
- package/dist/hooks/useOceanMaterial.d.ts +11 -1
- package/dist/hooks/useOceanMaterial.d.ts.map +1 -1
- package/dist/hooks/useOceanMaterial.js +185 -27
- package/dist/hooks/usePathAnimation.d.ts +8 -0
- package/dist/hooks/usePathAnimation.d.ts.map +1 -1
- package/dist/hooks/usePathAnimation.js +140 -59
- package/dist/hooks/useResolvedLayout.d.ts +10 -0
- package/dist/hooks/useResolvedLayout.d.ts.map +1 -0
- package/dist/hooks/useResolvedLayout.js +17 -0
- package/dist/hooks/useTimeLighting.d.ts +36 -0
- package/dist/hooks/useTimeLighting.d.ts.map +1 -0
- package/dist/hooks/useTimeLighting.js +67 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/operations/catalogue/shaderLayers.d.ts.map +1 -1
- package/dist/operations/catalogue/shaderLayers.js +26 -3
- package/dist/render/renderLive.d.ts +11 -0
- package/dist/render/renderLive.d.ts.map +1 -0
- package/dist/render/renderLive.js +57 -0
- package/dist/shaders/glsl/oceanCore.glsl.d.ts +2 -2
- package/dist/shaders/glsl/oceanCore.glsl.d.ts.map +1 -1
- package/dist/shaders/glsl/oceanCore.glsl.js +35 -5
- package/dist/shaders/ocean/OceanSurfaceMaterial.d.ts +12 -0
- package/dist/shaders/ocean/OceanSurfaceMaterial.d.ts.map +1 -1
- package/dist/shaders/ocean/OceanSurfaceMaterial.js +55 -7
- package/dist/shaders/terrain/TerrainMaterial.d.ts.map +1 -1
- package/dist/shaders/terrain/TerrainMaterial.js +28 -0
- package/dist/triggers/kinds/change.js +1 -1
- package/dist/utils/composerHostedPass.d.ts +74 -0
- package/dist/utils/composerHostedPass.d.ts.map +1 -0
- package/dist/utils/composerHostedPass.js +63 -0
- package/dist/utils/geometryScript.d.ts +17 -0
- package/dist/utils/geometryScript.d.ts.map +1 -0
- package/dist/utils/geometryScript.js +92 -0
- package/dist/utils/geometryScript.worker.d.ts +2 -0
- package/dist/utils/geometryScript.worker.d.ts.map +1 -0
- package/dist/utils/geometryScript.worker.js +42 -0
- package/dist/utils/groundRegistry.d.ts +11 -0
- package/dist/utils/groundRegistry.d.ts.map +1 -0
- package/dist/utils/groundRegistry.js +39 -0
- package/dist/utils/instancingSupport.d.ts +9 -0
- package/dist/utils/instancingSupport.d.ts.map +1 -0
- package/dist/utils/instancingSupport.js +13 -0
- package/dist/utils/landPatch.d.ts +26 -5
- package/dist/utils/landPatch.d.ts.map +1 -1
- package/dist/utils/landPatch.js +124 -9
- package/dist/utils/layoutPlacement.d.ts +30 -0
- package/dist/utils/layoutPlacement.d.ts.map +1 -0
- package/dist/utils/layoutPlacement.js +113 -0
- package/dist/utils/linkRegistry.d.ts +15 -0
- package/dist/utils/linkRegistry.d.ts.map +1 -0
- package/dist/utils/linkRegistry.js +11 -0
- package/dist/utils/shapes.d.ts +28 -2
- package/dist/utils/shapes.d.ts.map +1 -1
- package/dist/utils/shapes.js +32 -3
- package/dist/utils/sharedParts.d.ts +61 -0
- package/dist/utils/sharedParts.d.ts.map +1 -0
- package/dist/utils/sharedParts.js +268 -0
- package/dist/utils/svgAsset.d.ts +6 -0
- package/dist/utils/svgAsset.d.ts.map +1 -0
- package/dist/utils/svgAsset.js +46 -0
- package/dist/utils/waterLight.d.ts +29 -0
- package/dist/utils/waterLight.d.ts.map +1 -0
- package/dist/utils/waterLight.js +67 -0
- package/dist/utils/waterReflection.d.ts +185 -0
- package/dist/utils/waterReflection.d.ts.map +1 -0
- package/dist/utils/waterReflection.js +616 -0
- package/package.json +6 -4
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
// Emitted from Claude outputs/urban-lab/road.mjs by emit_object.mjs — edit the lab module and re-emit.
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// urban/road — a street along a polyline: lanes, markings, kerbs, sidewalks, lamps
|
|
4
|
+
// =============================================================================
|
|
5
|
+
// Construction. The polyline (config.points, metres in the object's XZ) is run through a
|
|
6
|
+
// Catmull-Rom spline (the `curve` knob is its tension: 0 keeps the corners, 1 rounds them)
|
|
7
|
+
// and sampled every ~1.5 m. Each sample gives a frame (tangent, right normal) and the
|
|
8
|
+
// ribbons are swept along it: asphalt [-W/2, W/2], a kerb face up to kerbHeight, the
|
|
9
|
+
// sidewalk slab and its outer face. Every vertex carries (s, t): metres along and across
|
|
10
|
+
// the road, so markings live in the fragment shader — centre line (dashed / solid /
|
|
11
|
+
// double), lane dashes, edge lines, zebra crossings at both ends — anti-aliased with
|
|
12
|
+
// fwidth, worn by a hash along s. Tyre tracks darken the wheel paths of every lane.
|
|
13
|
+
//
|
|
14
|
+
// Light. Asphalt and paving are library texture sets normalised to their mean (the colour
|
|
15
|
+
// knob decides). Street lamps every lampSpacing metres are instances of the shared lamp
|
|
16
|
+
// fixture; their heads are emissive and they are REGISTERED in the lamp list — the road's
|
|
17
|
+
// own asphalt and sidewalks, nearby facades and other roads light themselves from it.
|
|
18
|
+
// No THREE light anywhere.
|
|
19
|
+
import * as THREE from 'three';
|
|
20
|
+
import { createSunUniforms, createLampUniforms, createTextureUniforms, applyTextureSet, glslTextureBlock, GLSL_COMMON, GLSL_FOG_PARS, GLSL_FOG_VERT_PARS, GLSL_OUT, loadTextureSet, createPavingUniforms, createPavingMaterial, buildLampGeometry, createFixtureUniforms, createFixtureMaterial, registerLamp, unregisterLamp, touchLamps, setLamps, placeLamps, mergeGeometries, samplePath, ribbon, SURFACE_DEPTH, } from '../urbanCore.js';
|
|
21
|
+
export const MARKINGS = ['dashed', 'solid', 'double', 'none'];
|
|
22
|
+
export const LAMP_SIDES = ['both', 'left', 'right', 'alternate', 'none'];
|
|
23
|
+
export const LIGHTING = ['auto', 'day', 'night'];
|
|
24
|
+
export const STRUCTURAL = ['points', 'curve', 'lanes', 'laneWidth', 'sidewalk', 'kerbHeight', 'lampSpacing', 'lampSide', 'lampHeight', 'seed', 'texture', 'sidewalkTexture'];
|
|
25
|
+
// ---------------------------------------------------------------------------- path
|
|
26
|
+
export function roadWidth(c) { return Math.max(1, Math.round(c.lanes)) * c.laneWidth; }
|
|
27
|
+
/** Where the lamps stand: [{ x, z, ry, side }] in object space (head arm turned toward the road). */
|
|
28
|
+
export function lampPositions(c, samples) {
|
|
29
|
+
const out = [];
|
|
30
|
+
if (!samples.length || !(c.lampSpacing > 0) || c.lampSide === 'none')
|
|
31
|
+
return out;
|
|
32
|
+
const W = roadWidth(c);
|
|
33
|
+
const setback = c.sidewalk > 0.5 ? W / 2 + Math.min(c.sidewalk * 0.45, 1.2) : W / 2 + 0.8;
|
|
34
|
+
const L = samples[samples.length - 1].s;
|
|
35
|
+
const count = Math.max(1, Math.floor(L / c.lampSpacing));
|
|
36
|
+
const start = (L - (count - 1) * c.lampSpacing) / 2;
|
|
37
|
+
let k = 0;
|
|
38
|
+
for (let i = 0; i < count; i++) {
|
|
39
|
+
const s = start + i * c.lampSpacing;
|
|
40
|
+
let j = 0;
|
|
41
|
+
while (j < samples.length - 1 && samples[j + 1].s < s)
|
|
42
|
+
j++;
|
|
43
|
+
const S = samples[j];
|
|
44
|
+
const sides = c.lampSide === 'both' ? [1, -1] : c.lampSide === 'left' ? [-1] : c.lampSide === 'right' ? [1] : [k++ % 2 === 0 ? 1 : -1];
|
|
45
|
+
for (const side of sides) {
|
|
46
|
+
const x = S.p.x + S.n.x * setback * side, z = S.p.z + S.n.z * setback * side;
|
|
47
|
+
// The fixture's arm points along +x: aim it at the road (opposite the side normal).
|
|
48
|
+
const ax = -S.n.x * side, az = -S.n.z * side;
|
|
49
|
+
out.push({ x, z, ry: Math.atan2(-az, ax), side });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return out;
|
|
53
|
+
}
|
|
54
|
+
// ---------------------------------------------------------------------------- asphalt material
|
|
55
|
+
export function createUniforms() {
|
|
56
|
+
return Object.assign(createSunUniforms(), createLampUniforms(), createTextureUniforms('uAsp'), {
|
|
57
|
+
uAsphaltColor: { value: new THREE.Color() },
|
|
58
|
+
uMarkingColor: { value: new THREE.Color() },
|
|
59
|
+
uWidth: { value: 7 },
|
|
60
|
+
uLaneWidth: { value: 3.5 },
|
|
61
|
+
uLanes: { value: 2 },
|
|
62
|
+
uMarking: { value: 0 },
|
|
63
|
+
uLaneLines: { value: 1 },
|
|
64
|
+
uEdgeLines: { value: 1 },
|
|
65
|
+
uCrosswalks: { value: 1 },
|
|
66
|
+
uWear: { value: 0.5 },
|
|
67
|
+
uLength: { value: 100 },
|
|
68
|
+
uSeed: { value: 0 },
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
export function applyConfig(u, c, tex = undefined) {
|
|
72
|
+
if (c.asphaltColor !== undefined)
|
|
73
|
+
u.uAsphaltColor.value.set(c.asphaltColor);
|
|
74
|
+
if (c.markingColor !== undefined)
|
|
75
|
+
u.uMarkingColor.value.set(c.markingColor);
|
|
76
|
+
if (c.markings !== undefined)
|
|
77
|
+
u.uMarking.value = MARKINGS.indexOf(c.markings);
|
|
78
|
+
if (c.laneLines !== undefined)
|
|
79
|
+
u.uLaneLines.value = c.laneLines ? 1 : 0;
|
|
80
|
+
if (c.edgeLines !== undefined)
|
|
81
|
+
u.uEdgeLines.value = c.edgeLines ? 1 : 0;
|
|
82
|
+
if (c.crosswalks !== undefined)
|
|
83
|
+
u.uCrosswalks.value = c.crosswalks ? 1 : 0;
|
|
84
|
+
if (c.wear !== undefined)
|
|
85
|
+
u.uWear.value = c.wear;
|
|
86
|
+
if (c.lanes !== undefined && c.laneWidth !== undefined) {
|
|
87
|
+
u.uLanes.value = Math.max(1, Math.round(c.lanes));
|
|
88
|
+
u.uLaneWidth.value = c.laneWidth;
|
|
89
|
+
u.uWidth.value = roadWidth(c);
|
|
90
|
+
}
|
|
91
|
+
if (c.seed !== undefined)
|
|
92
|
+
u.uSeed.value = c.seed;
|
|
93
|
+
if (tex !== undefined)
|
|
94
|
+
applyTextureSet(u, 'uAsp', tex, c.texture && c.texture.tileSize, 0.6);
|
|
95
|
+
}
|
|
96
|
+
export const VERT = /* glsl */ `
|
|
97
|
+
attribute vec2 aUV;
|
|
98
|
+
varying vec3 vN; varying vec3 vP; varying vec2 vST;
|
|
99
|
+
${GLSL_FOG_VERT_PARS}
|
|
100
|
+
void main() {
|
|
101
|
+
vec4 wp = modelMatrix * vec4(position, 1.0);
|
|
102
|
+
vP = wp.xyz;
|
|
103
|
+
vN = normalize(mat3(modelMatrix) * normal);
|
|
104
|
+
vST = aUV;
|
|
105
|
+
vec4 mvPosition = viewMatrix * wp;
|
|
106
|
+
gl_Position = projectionMatrix * mvPosition;
|
|
107
|
+
#include <fog_vertex>
|
|
108
|
+
}`;
|
|
109
|
+
export const FRAG = /* glsl */ `
|
|
110
|
+
precision highp float;
|
|
111
|
+
${GLSL_COMMON}
|
|
112
|
+
${glslTextureBlock('uAsp')}
|
|
113
|
+
uniform vec3 uAsphaltColor; uniform vec3 uMarkingColor;
|
|
114
|
+
uniform float uWidth; uniform float uLaneWidth; uniform float uLanes; uniform float uMarking;
|
|
115
|
+
uniform float uLaneLines; uniform float uEdgeLines; uniform float uCrosswalks; uniform float uWear; uniform float uLength; uniform float uSeed;
|
|
116
|
+
varying vec3 vN; varying vec3 vP; varying vec2 vST;
|
|
117
|
+
${GLSL_FOG_PARS}
|
|
118
|
+
|
|
119
|
+
// A painted line of width w centred on x = 0, anti-aliased.
|
|
120
|
+
float lineAA(float x, float w) { return 1.0 - bandAA(abs(x), w * 0.5, 1e9); }
|
|
121
|
+
// 3 m dash, 9 m gap, anti-aliased along s.
|
|
122
|
+
float dashAA(float s) { float m = mod(s, 12.0); return bandAA(m, 0.0, 3.0); }
|
|
123
|
+
|
|
124
|
+
void main() {
|
|
125
|
+
vec3 N = normalize(vN);
|
|
126
|
+
vec3 V = normalize(cameraPosition - vP);
|
|
127
|
+
float s = vST.x, t = vST.y;
|
|
128
|
+
// Texture along the road: u = s, v = t (so the asphalt grain follows the lanes).
|
|
129
|
+
vec3 T = vec3(1.0, 0.0, 0.0), B = vec3(0.0, 0.0, 1.0);
|
|
130
|
+
float rough;
|
|
131
|
+
vec3 Nb = N;
|
|
132
|
+
vec3 mul = uAspSample(vec2(s, t), Nb, T, B, rough);
|
|
133
|
+
// Wheel tracks: two darker paths per lane, 0.9 m either side of the lane centre.
|
|
134
|
+
float lanePos = mod(t + uWidth * 0.5, uLaneWidth) - uLaneWidth * 0.5;
|
|
135
|
+
float tracks = exp(-pow((abs(lanePos) - 0.9) / 0.45, 2.0));
|
|
136
|
+
float macro = 0.92 + 0.16 * vnoise21(vec2(s, t) / 9.0 + uSeed);
|
|
137
|
+
vec3 albedo = uAsphaltColor * mul * macro * (1.0 - 0.22 * uWear * tracks);
|
|
138
|
+
rough = mix(rough, 0.95, 0.4) - 0.1 * uWear * tracks;
|
|
139
|
+
|
|
140
|
+
// Markings ---------------------------------------------------------------
|
|
141
|
+
float lw = 0.12;
|
|
142
|
+
float mark = 0.0;
|
|
143
|
+
// Centre line (between the two middle lanes when the lane count is even; the middle of the middle lane is never painted when odd).
|
|
144
|
+
float even = 1.0 - mod(uLanes, 2.0);
|
|
145
|
+
float centre = lineAA(t, lw);
|
|
146
|
+
if (uMarking < 0.5) centre *= dashAA(s);
|
|
147
|
+
else if (uMarking > 1.5 && uMarking < 2.5) centre = lineAA(abs(t) - 0.11, lw);
|
|
148
|
+
else if (uMarking > 2.5) centre = 0.0;
|
|
149
|
+
mark += centre * even;
|
|
150
|
+
// Lane lines: dashed at every lane boundary except the centre line and the two edges.
|
|
151
|
+
float bPos = mod(t + uWidth * 0.5 + uLaneWidth * 0.5, uLaneWidth) - uLaneWidth * 0.5; // 0 at a boundary
|
|
152
|
+
float boundary = lineAA(bPos, lw) * dashAA(s + 6.0);
|
|
153
|
+
float notCentre = 1.0 - step(abs(t), uLaneWidth * 0.25) * even;
|
|
154
|
+
float notEdge = 1.0 - step(uWidth * 0.5 - uLaneWidth * 0.25, abs(t));
|
|
155
|
+
mark += boundary * uLaneLines * notCentre * notEdge;
|
|
156
|
+
// Edge lines, solid, 0.3 m in from the kerb.
|
|
157
|
+
mark += lineAA(abs(t) - (uWidth * 0.5 - 0.3), lw) * uEdgeLines;
|
|
158
|
+
// Zebra crossings at both ends: 3 m of 0.5 m stripes across the road, 2 m from the end.
|
|
159
|
+
float endDist = min(s, uLength - s);
|
|
160
|
+
float zebraZone = bandAA(endDist, 2.0, 5.0);
|
|
161
|
+
float stripes = bandAA(mod(t + uWidth * 0.5, 1.0), 0.0, 0.5);
|
|
162
|
+
float zebra = zebraZone * stripes * uCrosswalks;
|
|
163
|
+
// The stop line before each crossing.
|
|
164
|
+
zebra = max(zebra, bandAA(endDist, 5.4, 5.75) * uCrosswalks);
|
|
165
|
+
mark = clamp(max(mark, zebra), 0.0, 1.0);
|
|
166
|
+
// Paint wear: chips along s and fading where the tyres run.
|
|
167
|
+
float chip = hash21(floor(vec2(s * 2.0, t * 4.0)) + uSeed);
|
|
168
|
+
float wear = uWear * (0.35 * step(chip, 0.25 * uWear) + 0.5 * tracks);
|
|
169
|
+
mark *= 1.0 - clamp(wear, 0.0, 0.85);
|
|
170
|
+
vec3 paint = uMarkingColor * mix(1.0, 0.75, chip * uWear);
|
|
171
|
+
albedo = mix(albedo, paint, mark);
|
|
172
|
+
rough = mix(rough, 0.6, mark);
|
|
173
|
+
|
|
174
|
+
vec3 col = shadeSurface(albedo, Nb, vP, V, rough, 1.0);
|
|
175
|
+
${GLSL_OUT}
|
|
176
|
+
}`;
|
|
177
|
+
export function createMaterial(u) {
|
|
178
|
+
return new THREE.ShaderMaterial({ uniforms: Object.assign(THREE.UniformsUtils.clone(THREE.UniformsLib.fog), u), vertexShader: VERT, fragmentShader: FRAG, fog: true, ...SURFACE_DEPTH });
|
|
179
|
+
}
|
|
180
|
+
// ---------------------------------------------------------------------------- lab build
|
|
181
|
+
/**
|
|
182
|
+
* build(u, c) -> { object, materials, apply, rebuild, update, dispose, bounds, lamps }
|
|
183
|
+
* `u` is the asphalt uniforms; the paving and fixture uniforms are created here and share
|
|
184
|
+
* the sun / lamp values through applySun on all three (the component does the same).
|
|
185
|
+
*/
|
|
186
|
+
export const CHUNK_M = 120; // a long road is drawn in chunks so each one gathers its own lamps
|
|
187
|
+
export function build(u, c) {
|
|
188
|
+
const group = new THREE.Group();
|
|
189
|
+
const pavU = createPavingUniforms();
|
|
190
|
+
const fixU = createFixtureUniforms();
|
|
191
|
+
const fixture = createFixtureMaterial(fixU);
|
|
192
|
+
// Per chunk: one asphalt + one paving material whose sun / texture / knob uniforms are the
|
|
193
|
+
// SHARED objects (u / pavU) and whose lamp uniforms are its own.
|
|
194
|
+
const chunks = []; // { road, walk, u, pavU, bounds }
|
|
195
|
+
let lampMesh = null;
|
|
196
|
+
let lamps = []; // registry entries
|
|
197
|
+
let lampLocal = []; // head positions in object space
|
|
198
|
+
const state = { tex: null, walkTex: null, samples: [] };
|
|
199
|
+
const clear = () => {
|
|
200
|
+
for (const ch of chunks) {
|
|
201
|
+
for (const m of [ch.road, ch.walk])
|
|
202
|
+
if (m) {
|
|
203
|
+
group.remove(m);
|
|
204
|
+
m.geometry.dispose();
|
|
205
|
+
m.material.dispose();
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
chunks.length = 0;
|
|
209
|
+
if (lampMesh) {
|
|
210
|
+
group.remove(lampMesh);
|
|
211
|
+
lampMesh.geometry.dispose();
|
|
212
|
+
lampMesh = null;
|
|
213
|
+
}
|
|
214
|
+
for (const L of lamps)
|
|
215
|
+
unregisterLamp(L);
|
|
216
|
+
lamps = [];
|
|
217
|
+
lampLocal = [];
|
|
218
|
+
};
|
|
219
|
+
const rebuild = (cfg) => {
|
|
220
|
+
clear();
|
|
221
|
+
const samples = samplePath(cfg.points, cfg.curve);
|
|
222
|
+
state.samples = samples;
|
|
223
|
+
if (samples.length < 2)
|
|
224
|
+
return;
|
|
225
|
+
const W = roadWidth(cfg);
|
|
226
|
+
u.uLength.value = samples[samples.length - 1].s;
|
|
227
|
+
const L = samples[samples.length - 1].s;
|
|
228
|
+
const nChunks = Math.max(1, Math.ceil(L / CHUNK_M));
|
|
229
|
+
for (let k = 0; k < nChunks; k++) {
|
|
230
|
+
const s0 = (k * L) / nChunks, s1 = ((k + 1) * L) / nChunks;
|
|
231
|
+
let i0 = 0;
|
|
232
|
+
while (i0 < samples.length - 1 && samples[i0 + 1].s <= s0)
|
|
233
|
+
i0++;
|
|
234
|
+
let i1 = i0;
|
|
235
|
+
while (i1 < samples.length - 1 && samples[i1].s < s1)
|
|
236
|
+
i1++;
|
|
237
|
+
const part = samples.slice(i0, i1 + 1);
|
|
238
|
+
if (part.length < 2)
|
|
239
|
+
continue;
|
|
240
|
+
const chU = Object.assign({}, u, createLampUniforms());
|
|
241
|
+
const road = new THREE.Mesh(ribbon(part, -W / 2, W / 2, 0.02, 0.02, false), createMaterial(chU));
|
|
242
|
+
road.frustumCulled = false;
|
|
243
|
+
group.add(road);
|
|
244
|
+
const ch = { road, walk: null, u: chU, pavU: null, bounds: new THREE.Box3() };
|
|
245
|
+
road.geometry.computeBoundingBox();
|
|
246
|
+
ch.bounds.union(road.geometry.boundingBox);
|
|
247
|
+
if (cfg.sidewalk > 0.05) {
|
|
248
|
+
const kh = Math.max(0, cfg.kerbHeight), sw = cfg.sidewalk;
|
|
249
|
+
const parts = [
|
|
250
|
+
ribbon(part, W / 2, W / 2, 0.0, kh, true, -1), // right kerb face (toward the road)
|
|
251
|
+
ribbon(part, W / 2, W / 2 + sw, kh, kh, false), // right slab
|
|
252
|
+
ribbon(part, W / 2 + sw, W / 2 + sw, kh, 0.0, true, 1), // right outer drop
|
|
253
|
+
ribbon(part, -W / 2, -W / 2, kh, 0.0, true, -1), // left kerb face
|
|
254
|
+
ribbon(part, -W / 2 - sw, -W / 2, kh, kh, false), // left slab
|
|
255
|
+
ribbon(part, -W / 2 - sw, -W / 2 - sw, 0.0, kh, true, 1), // left outer drop
|
|
256
|
+
];
|
|
257
|
+
ch.pavU = Object.assign({}, pavU, createLampUniforms());
|
|
258
|
+
ch.walk = new THREE.Mesh(mergeGeometries(parts, [['aUV', 2]]), createPavingMaterial(ch.pavU));
|
|
259
|
+
ch.walk.frustumCulled = false;
|
|
260
|
+
group.add(ch.walk);
|
|
261
|
+
ch.bounds.union(ch.walk.geometry.boundingBox);
|
|
262
|
+
}
|
|
263
|
+
chunks.push(ch);
|
|
264
|
+
}
|
|
265
|
+
// Lamps: one fixture geometry, instanced.
|
|
266
|
+
const where = lampPositions(cfg, samples);
|
|
267
|
+
if (where.length) {
|
|
268
|
+
const geo = buildLampGeometry({ height: cfg.lampHeight, armReach: 1.8 });
|
|
269
|
+
lampMesh = new THREE.InstancedMesh(geo, fixture, where.length);
|
|
270
|
+
const m = new THREE.Matrix4(), q = new THREE.Quaternion(), p = new THREE.Vector3(), sc = new THREE.Vector3(1, 1, 1), up = new THREE.Vector3(0, 1, 0);
|
|
271
|
+
for (let i = 0; i < where.length; i++) {
|
|
272
|
+
const w = where[i];
|
|
273
|
+
p.set(w.x, 0, w.z);
|
|
274
|
+
q.setFromAxisAngle(up, w.ry);
|
|
275
|
+
m.compose(p, q, sc);
|
|
276
|
+
lampMesh.setMatrixAt(i, m);
|
|
277
|
+
const head = geo.userData.head.clone().applyMatrix4(m);
|
|
278
|
+
lampLocal.push(head);
|
|
279
|
+
lamps.push(registerLamp({ id: 'road-' + i, position: head.clone(), color: new THREE.Color(cfg.lampColor), radius: cfg.lampRadius, intensity: cfg.lampIntensity, on: true }));
|
|
280
|
+
}
|
|
281
|
+
lampMesh.instanceMatrix.needsUpdate = true;
|
|
282
|
+
lampMesh.frustumCulled = false;
|
|
283
|
+
group.add(lampMesh);
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
const setTextures = (cfg) => {
|
|
287
|
+
const maps = cfg.texture && cfg.texture.maps;
|
|
288
|
+
state.tex = maps && maps.color ? loadTextureSet(maps) : null;
|
|
289
|
+
if (state.tex)
|
|
290
|
+
state.tex.ready.then(() => applyConfig(u, cfg, state.tex));
|
|
291
|
+
applyConfig(u, cfg, state.tex && state.tex.color ? state.tex : null);
|
|
292
|
+
const wm = cfg.sidewalkTexture && cfg.sidewalkTexture.maps;
|
|
293
|
+
state.walkTex = wm && wm.color ? loadTextureSet(wm) : null;
|
|
294
|
+
const applyWalk = () => applyTextureSet(pavU, 'uPav', state.walkTex && state.walkTex.color ? state.walkTex : null, cfg.sidewalkTexture && cfg.sidewalkTexture.tileSize, 0.7);
|
|
295
|
+
if (state.walkTex)
|
|
296
|
+
state.walkTex.ready.then(applyWalk);
|
|
297
|
+
applyWalk();
|
|
298
|
+
};
|
|
299
|
+
const apply = (cfg) => {
|
|
300
|
+
applyConfig(u, cfg, undefined);
|
|
301
|
+
if (cfg.sidewalkColor !== undefined)
|
|
302
|
+
pavU.uPavColor.value.set(cfg.sidewalkColor);
|
|
303
|
+
if (cfg.lampPaint !== undefined)
|
|
304
|
+
fixU.uPaint.value.set(cfg.lampPaint);
|
|
305
|
+
if (cfg.lampColor !== undefined)
|
|
306
|
+
fixU.uLampColor.value.set(cfg.lampColor);
|
|
307
|
+
if (cfg.lampIntensity !== undefined)
|
|
308
|
+
fixU.uLampGlow.value = cfg.lampIntensity / 2.6;
|
|
309
|
+
setLamps(lamps, cfg.lampColor, cfg.lampIntensity, cfg.lampRadius); // bumps the lamp list only on a real change
|
|
310
|
+
};
|
|
311
|
+
rebuild(c);
|
|
312
|
+
setTextures(c);
|
|
313
|
+
apply(c);
|
|
314
|
+
const lastWorld = new THREE.Matrix4();
|
|
315
|
+
return {
|
|
316
|
+
object: group,
|
|
317
|
+
get materials() { const out = [fixture]; for (const ch of chunks) {
|
|
318
|
+
out.push(ch.road.material);
|
|
319
|
+
if (ch.walk)
|
|
320
|
+
out.push(ch.walk.material);
|
|
321
|
+
} return out; },
|
|
322
|
+
/** The shared uniform sets (sun goes here once; the chunks reference the same objects). */
|
|
323
|
+
uniformSets: [u, pavU, fixU],
|
|
324
|
+
/** Lamp gathering targets: each chunk's asphalt and paving with its local bounds. */
|
|
325
|
+
lampTargets() { const out = []; for (const ch of chunks) {
|
|
326
|
+
out.push({ u: ch.u, bounds: ch.bounds });
|
|
327
|
+
if (ch.pavU)
|
|
328
|
+
out.push({ u: ch.pavU, bounds: ch.bounds });
|
|
329
|
+
} return out; },
|
|
330
|
+
apply,
|
|
331
|
+
rebuild(cfg) { rebuild(cfg); setTextures(cfg); apply(cfg); },
|
|
332
|
+
/** Local-space bounds (the caller applies the object's world matrix). */
|
|
333
|
+
bounds() { const b = new THREE.Box3(); for (const ch of chunks)
|
|
334
|
+
b.union(ch.bounds); return b; },
|
|
335
|
+
/** Keep the registry's world positions in step with the object's transform. */
|
|
336
|
+
update() {
|
|
337
|
+
group.updateMatrixWorld();
|
|
338
|
+
if (!lastWorld.equals(group.matrixWorld)) {
|
|
339
|
+
lastWorld.copy(group.matrixWorld);
|
|
340
|
+
placeLamps(lamps, lampLocal, group.matrixWorld); // positions, reach and falloff follow the object's scale
|
|
341
|
+
if (lamps.length)
|
|
342
|
+
touchLamps();
|
|
343
|
+
}
|
|
344
|
+
},
|
|
345
|
+
dispose() { clear(); fixture.dispose(); },
|
|
346
|
+
};
|
|
347
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import * as THREE from 'three';
|
|
2
|
+
export declare const KINDS: string[];
|
|
3
|
+
export declare const LIGHTING: string[];
|
|
4
|
+
export declare const STRUCTURAL: string[];
|
|
5
|
+
export declare function createUniforms(): {
|
|
6
|
+
uSunDir: {
|
|
7
|
+
value: THREE.Vector3;
|
|
8
|
+
};
|
|
9
|
+
uSunColor: {
|
|
10
|
+
value: THREE.Color;
|
|
11
|
+
};
|
|
12
|
+
uSkyAmbient: {
|
|
13
|
+
value: THREE.Color;
|
|
14
|
+
};
|
|
15
|
+
uGroundAmbient: {
|
|
16
|
+
value: THREE.Color;
|
|
17
|
+
};
|
|
18
|
+
uNight: {
|
|
19
|
+
value: number;
|
|
20
|
+
};
|
|
21
|
+
} & {
|
|
22
|
+
uLamps: {
|
|
23
|
+
value: any[];
|
|
24
|
+
};
|
|
25
|
+
uLampColors: {
|
|
26
|
+
value: any[];
|
|
27
|
+
};
|
|
28
|
+
uLampAims: {
|
|
29
|
+
value: any[];
|
|
30
|
+
};
|
|
31
|
+
uLampCount: {
|
|
32
|
+
value: number;
|
|
33
|
+
};
|
|
34
|
+
uLampTop: {
|
|
35
|
+
value: number;
|
|
36
|
+
};
|
|
37
|
+
uLampField: {
|
|
38
|
+
value: any;
|
|
39
|
+
};
|
|
40
|
+
uLampFieldRect: {
|
|
41
|
+
value: THREE.Vector4;
|
|
42
|
+
};
|
|
43
|
+
uLampFieldOn: {
|
|
44
|
+
value: number;
|
|
45
|
+
};
|
|
46
|
+
} & {
|
|
47
|
+
uImage: {
|
|
48
|
+
value: THREE.DataTexture;
|
|
49
|
+
};
|
|
50
|
+
uHasImage: {
|
|
51
|
+
value: number;
|
|
52
|
+
};
|
|
53
|
+
uImageAspect: {
|
|
54
|
+
value: number;
|
|
55
|
+
};
|
|
56
|
+
uPanelAspect: {
|
|
57
|
+
value: number;
|
|
58
|
+
};
|
|
59
|
+
uColor: {
|
|
60
|
+
value: THREE.Color;
|
|
61
|
+
};
|
|
62
|
+
uFrame: {
|
|
63
|
+
value: THREE.Color;
|
|
64
|
+
};
|
|
65
|
+
uGlow: {
|
|
66
|
+
value: number;
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
export declare function applyConfig(u: any, c: any): void;
|
|
70
|
+
export declare const VERT = "\nvarying vec3 vN; varying vec3 vP; varying vec2 vUv;\n#include <fog_pars_vertex>\nvoid main() {\n vec4 wp = modelMatrix * vec4(position, 1.0);\n vP = wp.xyz; vN = normalize(mat3(modelMatrix) * normal); vUv = uv;\n vec4 mvPosition = viewMatrix * wp;\n gl_Position = projectionMatrix * mvPosition;\n #include <fog_vertex>\n}";
|
|
71
|
+
export declare const FRAG = "\nprecision highp float;\n\nuniform vec3 uSunDir;\nuniform vec3 uSunColor;\nuniform vec3 uSkyAmbient;\nuniform vec3 uGroundAmbient;\nuniform float uNight;\nuniform vec4 uLamps[48];\nuniform vec4 uLampColors[48];\nuniform vec4 uLampAims[48];\nuniform int uLampCount;\nuniform float uLampTop;\nuniform sampler2D uLampField;\nuniform vec4 uLampFieldRect;\nuniform float uLampFieldOn;\n\nfloat hash11(float p) { p = fract(p * 0.1031); p *= p + 33.33; p *= p + p; return fract(p); }\nfloat hash21(vec2 p) { vec3 p3 = fract(vec3(p.xyx) * 0.1031); p3 += dot(p3, p3.yzx + 33.33); return fract((p3.x + p3.y) * p3.z); }\nfloat vnoise21(vec2 p) { vec2 i = floor(p), f = fract(p); f = f * f * (3.0 - 2.0 * f); return mix(mix(hash21(i), hash21(i + vec2(1.0, 0.0)), f.x), mix(hash21(i + vec2(0.0, 1.0)), hash21(i + vec2(1.0, 1.0)), f.x), f.y); }\nfloat hash31(vec3 p) { p = fract(p * 0.1031); p += dot(p, p.zyx + 31.32); return fract((p.x + p.y) * p.z); }\n\n// Irradiance from the gathered lamps. Each lamp is a downward-facing head: a smooth\n// window to its radius, inverse-square falloff softened near the head, a cosine cone so\n// it pools on the ground and only grazes walls, Lambert on the receiver. Scaled by the\n// night factor so pools fade in with dusk.\nvec3 lampLight(vec3 P, vec3 N) {\n vec3 acc = vec3(0.0);\n if (uNight < 0.002) return acc;\n // A baked lamp field (a street grid): the ground's light at this xz, decoded; walls take a share.\n if (uLampFieldOn > 0.5) {\n vec3 e = texture2D(uLampField, (P.xz - uLampFieldRect.xy) / uLampFieldRect.zw).rgb;\n return e * e * 4.0 * (0.3 + 0.7 * max(N.y, 0.0)) * uNight;\n }\n // Above the reach of every gathered lamp (most of a facade) the loop is skipped.\n if (P.y > uLampTop) return acc;\n for (int i = 0; i < 48; i++) {\n if (i >= uLampCount) break;\n vec4 L = uLamps[i];\n vec3 d = L.xyz - P;\n float r2 = dot(d, d);\n float r = sqrt(r2);\n vec3 l = d / max(r, 1e-3);\n float x = r / L.w;\n float win = clamp(1.0 - x * x * x * x, 0.0, 1.0);\n win *= win;\n float ndl = max(dot(N, l), 0.0);\n vec4 A = uLampAims[i];\n if (A.w > 0.0) {\n // a projector: an aimed beam (soft edge from the outer cone in), throw nearly flat over its\n // reach, so a few towers light a whole stadium evenly; walls facing it take light too\n float spot = smoothstep(A.w, mix(A.w, 1.0, 0.45), dot(-l, A.xyz));\n acc += uLampColors[i].rgb * (uLampColors[i].a * win * spot * (0.35 + 0.65 * ndl) * 4.0 / (1.0 + x * x * 3.0));\n continue;\n }\n float cone = smoothstep(0.1, 0.7, l.y);\n float ls = A.w < 0.0 ? -A.w : 1.0; // the lamp's object scale: falloff over its own metres\n // Intensity 1 puts ~0.75 irradiance on the ground under an 8 m head, a tenth of that\n // 14 m along the kerb: street-lamp contrast, not a wash.\n acc += uLampColors[i].rgb * (uLampColors[i].a * win * ndl * cone * 4.0 / (1.0 + r2 * 0.06 / (ls * ls)));\n }\n return acc * uNight;\n}\n\n// Sun + sky + ground + lamps on a rough dielectric. Radiance units: a 0.5 albedo at noon\n// lands near 0.9, so NoToneMapping keeps it under 1.\nvec3 shadeSurface(vec3 albedo, vec3 N, vec3 P, vec3 V, float rough, float ao) {\n float ndl = max(dot(N, uSunDir), 0.0);\n vec3 sky = uSkyAmbient * (0.55 + 0.45 * N.y);\n vec3 gnd = uGroundAmbient * (0.5 - 0.5 * N.y);\n vec3 col = albedo * (uSunColor * ndl + (sky + gnd) * ao);\n vec3 H = normalize(uSunDir + V);\n float spec = pow(max(dot(N, H), 0.0), mix(90.0, 6.0, rough)) * (1.0 - rough) * 0.35 * ndl;\n col += uSunColor * spec;\n col += albedo * lampLight(P, N);\n return col;\n}\n\n// Box-filtered coverage of the band [a, b] over this pixel's footprint on x: exact\n// anti-aliasing at the edge AND the right average when the band is thinner than a pixel\n// (a far facade blends to the mean of glass and spandrel instead of sparkling).\nfloat bandAA(float x, float a, float b) {\n float w = max(fwidth(x), 1e-5);\n float lo = max(a, x - 0.5 * w), hi = min(b, x + 0.5 * w);\n return clamp((hi - lo) / w, 0.0, 1.0);\n}\n\nuniform sampler2D uImage; uniform float uHasImage; uniform float uImageAspect; uniform float uPanelAspect;\nuniform vec3 uColor; uniform vec3 uFrame; uniform float uGlow;\nvarying vec3 vN; varying vec3 vP; varying vec2 vUv;\n#include <fog_pars_fragment>\nvoid main() {\n vec3 N = normalize(vN);\n if (!gl_FrontFacing) N = -N;\n vec3 V = normalize(cameraPosition - vP);\n // Frame: a 3 % border; inside it the picture, fitted to cover the panel.\n vec2 b = vec2(0.03 / uPanelAspect * 2.0, 0.03);\n float inside = bandAA(vUv.x, b.x, 1.0 - b.x) * bandAA(vUv.y, b.y, 1.0 - b.y);\n vec2 uv = (vUv - b) / (1.0 - 2.0 * b);\n float r = uPanelAspect / max(uImageAspect, 0.01);\n vec2 cuv = r > 1.0 ? vec2(uv.x, (uv.y - 0.5) / r + 0.5) : vec2((uv.x - 0.5) * r + 0.5, uv.y);\n vec3 pic = mix(uColor, texture2D(uImage, cuv).rgb, uHasImage);\n // Day: a matte print lit by the scene. Night: the print itself glows (backlit box).\n vec3 lit = shadeSurface(pic, N, vP, V, 0.7, 1.0);\n vec3 glow = pic * (0.9 + 1.1 * uGlow) * uNight;\n vec3 face = lit + glow;\n vec3 frame = shadeSurface(uFrame, N, vP, V, 0.5, 1.0);\n vec3 col = mix(frame, face, inside);\n\n gl_FragColor = vec4(col, 1.0);\n #include <tonemapping_fragment>\n #include <colorspace_fragment>\n #include <fog_fragment>\n\n}";
|
|
72
|
+
export declare function createMaterial(u: any, doubleSided: any): THREE.ShaderMaterial;
|
|
73
|
+
export declare function build(u: any, c: any): {
|
|
74
|
+
object: THREE.Group<THREE.Object3DEventMap>;
|
|
75
|
+
materials: THREE.ShaderMaterial[];
|
|
76
|
+
uniformSets: any[];
|
|
77
|
+
apply: (cfg: any) => void;
|
|
78
|
+
rebuild(cfg: any): void;
|
|
79
|
+
bounds(): THREE.Box3;
|
|
80
|
+
update(): void;
|
|
81
|
+
dispose(): void;
|
|
82
|
+
};
|
|
83
|
+
//# sourceMappingURL=signage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"signage.d.ts","sourceRoot":"","sources":["../../../../src/components/urban/core/signage.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,eAAO,MAAM,KAAK,UAAoC,CAAC;AACvD,eAAO,MAAM,QAAQ,UAA2B,CAAC;AAEjD,eAAO,MAAM,UAAU,UAA0D,CAAC;AAclF,wBAAgB,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAU7B;AAED,wBAAgB,WAAW,CAAC,CAAC,KAAA,EAAE,CAAC,KAAA,QAK/B;AAED,eAAO,MAAM,IAAI,uVASf,CAAC;AACH,eAAO,MAAM,IAAI,m8KAyBf,CAAC;AACH,wBAAgB,cAAc,CAAC,CAAC,KAAA,EAAE,WAAW,KAAA,wBAE5C;AA8BD,wBAAgB,KAAK,CAAC,CAAC,KAAA,EAAE,CAAC,KAAA;;;;;;;;;EAkDzB"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
// Emitted from Claude outputs/urban-lab/signage.mjs by emit_object.mjs — edit the lab module and re-emit.
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// urban/signage — billboard, totem or rooftop sign carrying a picture, backlit at night
|
|
4
|
+
// =============================================================================
|
|
5
|
+
// Construction. A panel (width x height) with a frame, carried by its kind: billboard = two
|
|
6
|
+
// posts to `elevation`; totem = a tall narrow panel on a plinth at ground level; rooftop =
|
|
7
|
+
// an open truss frame to `elevation` (place the object on a roof). The panel's fragment
|
|
8
|
+
// shader fits the picture (cover) inside the frame over a background colour; by day it is
|
|
9
|
+
// a lit print (sun + sky through the shared sun block), at night a backlit box: the picture
|
|
10
|
+
// itself emits (glow), so it reads from across the street, and it registers as a weak lamp
|
|
11
|
+
// so the pavement below picks up its light. No real light. The posts and frame use the
|
|
12
|
+
// family's fixture material.
|
|
13
|
+
import * as THREE from 'three';
|
|
14
|
+
import { createSunUniforms, createLampUniforms, GLSL_COMMON, GLSL_FOG_PARS, GLSL_FOG_VERT_PARS, GLSL_OUT, createFixtureUniforms, createFixtureMaterial, mergeGeometries, registerLamp, unregisterLamp, touchLamps, setLamps, placeLamps, } from '../urbanCore.js';
|
|
15
|
+
export const KINDS = ['billboard', 'totem', 'rooftop'];
|
|
16
|
+
export const LIGHTING = ['auto', 'day', 'night'];
|
|
17
|
+
export const STRUCTURAL = ['kind', 'width', 'height', 'elevation', 'doubleSided'];
|
|
18
|
+
// ---------------------------------------------------------------------------- panel material
|
|
19
|
+
const _none = (() => { const t = new THREE.DataTexture(new Uint8Array([0, 0, 0, 0]), 1, 1); t.needsUpdate = true; return t; })();
|
|
20
|
+
const _imgCache = new Map();
|
|
21
|
+
function loadImage(url, onLoad) {
|
|
22
|
+
if (!url)
|
|
23
|
+
return null;
|
|
24
|
+
if (_imgCache.has(url)) {
|
|
25
|
+
const t = _imgCache.get(url);
|
|
26
|
+
onLoad(t);
|
|
27
|
+
return t;
|
|
28
|
+
}
|
|
29
|
+
const loader = new THREE.TextureLoader();
|
|
30
|
+
loader.setCrossOrigin('anonymous');
|
|
31
|
+
const t = loader.load(url, (tex) => { tex.colorSpace = THREE.SRGBColorSpace; tex.anisotropy = 8; onLoad(tex); });
|
|
32
|
+
_imgCache.set(url, t);
|
|
33
|
+
return t;
|
|
34
|
+
}
|
|
35
|
+
export function createUniforms() {
|
|
36
|
+
return Object.assign(createSunUniforms(), createLampUniforms(), {
|
|
37
|
+
uImage: { value: _none },
|
|
38
|
+
uHasImage: { value: 0 },
|
|
39
|
+
uImageAspect: { value: 1 },
|
|
40
|
+
uPanelAspect: { value: 2 },
|
|
41
|
+
uColor: { value: new THREE.Color() },
|
|
42
|
+
uFrame: { value: new THREE.Color() },
|
|
43
|
+
uGlow: { value: 1 },
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
export function applyConfig(u, c) {
|
|
47
|
+
if (c.color !== undefined)
|
|
48
|
+
u.uColor.value.set(c.color);
|
|
49
|
+
if (c.frameColor !== undefined)
|
|
50
|
+
u.uFrame.value.set(c.frameColor);
|
|
51
|
+
if (c.glow !== undefined)
|
|
52
|
+
u.uGlow.value = c.glow;
|
|
53
|
+
if (c.width !== undefined && c.height !== undefined)
|
|
54
|
+
u.uPanelAspect.value = c.width / Math.max(c.height, 0.01);
|
|
55
|
+
}
|
|
56
|
+
export const VERT = /* glsl */ `
|
|
57
|
+
varying vec3 vN; varying vec3 vP; varying vec2 vUv;
|
|
58
|
+
${GLSL_FOG_VERT_PARS}
|
|
59
|
+
void main() {
|
|
60
|
+
vec4 wp = modelMatrix * vec4(position, 1.0);
|
|
61
|
+
vP = wp.xyz; vN = normalize(mat3(modelMatrix) * normal); vUv = uv;
|
|
62
|
+
vec4 mvPosition = viewMatrix * wp;
|
|
63
|
+
gl_Position = projectionMatrix * mvPosition;
|
|
64
|
+
#include <fog_vertex>
|
|
65
|
+
}`;
|
|
66
|
+
export const FRAG = /* glsl */ `
|
|
67
|
+
precision highp float;
|
|
68
|
+
${GLSL_COMMON}
|
|
69
|
+
uniform sampler2D uImage; uniform float uHasImage; uniform float uImageAspect; uniform float uPanelAspect;
|
|
70
|
+
uniform vec3 uColor; uniform vec3 uFrame; uniform float uGlow;
|
|
71
|
+
varying vec3 vN; varying vec3 vP; varying vec2 vUv;
|
|
72
|
+
${GLSL_FOG_PARS}
|
|
73
|
+
void main() {
|
|
74
|
+
vec3 N = normalize(vN);
|
|
75
|
+
if (!gl_FrontFacing) N = -N;
|
|
76
|
+
vec3 V = normalize(cameraPosition - vP);
|
|
77
|
+
// Frame: a 3 % border; inside it the picture, fitted to cover the panel.
|
|
78
|
+
vec2 b = vec2(0.03 / uPanelAspect * 2.0, 0.03);
|
|
79
|
+
float inside = bandAA(vUv.x, b.x, 1.0 - b.x) * bandAA(vUv.y, b.y, 1.0 - b.y);
|
|
80
|
+
vec2 uv = (vUv - b) / (1.0 - 2.0 * b);
|
|
81
|
+
float r = uPanelAspect / max(uImageAspect, 0.01);
|
|
82
|
+
vec2 cuv = r > 1.0 ? vec2(uv.x, (uv.y - 0.5) / r + 0.5) : vec2((uv.x - 0.5) * r + 0.5, uv.y);
|
|
83
|
+
vec3 pic = mix(uColor, texture2D(uImage, cuv).rgb, uHasImage);
|
|
84
|
+
// Day: a matte print lit by the scene. Night: the print itself glows (backlit box).
|
|
85
|
+
vec3 lit = shadeSurface(pic, N, vP, V, 0.7, 1.0);
|
|
86
|
+
vec3 glow = pic * (0.9 + 1.1 * uGlow) * uNight;
|
|
87
|
+
vec3 face = lit + glow;
|
|
88
|
+
vec3 frame = shadeSurface(uFrame, N, vP, V, 0.5, 1.0);
|
|
89
|
+
vec3 col = mix(frame, face, inside);
|
|
90
|
+
${GLSL_OUT}
|
|
91
|
+
}`;
|
|
92
|
+
export function createMaterial(u, doubleSided) {
|
|
93
|
+
return new THREE.ShaderMaterial({ uniforms: Object.assign(THREE.UniformsUtils.clone(THREE.UniformsLib.fog), u), vertexShader: VERT, fragmentShader: FRAG, fog: true, side: doubleSided ? THREE.DoubleSide : THREE.FrontSide });
|
|
94
|
+
}
|
|
95
|
+
// ---------------------------------------------------------------------------- geometry
|
|
96
|
+
const box = (w, h, d, x, y, z) => { const g = new THREE.BoxGeometry(w, h, d); g.translate(x, y, z); return g; };
|
|
97
|
+
/** The carrier for a kind: { frame (fixture geometry), panelY (centre height), panelZ } */
|
|
98
|
+
function carrier(kind, w, h, elev) {
|
|
99
|
+
const parts = [];
|
|
100
|
+
if (kind === 'billboard') {
|
|
101
|
+
const y0 = Math.max(elev, 0.5);
|
|
102
|
+
for (const sx of [-w * 0.3, w * 0.3])
|
|
103
|
+
parts.push(new THREE.CylinderGeometry(0.12, 0.16, y0 + h * 0.5, 12).translate(sx, (y0 + h * 0.5) / 2, -0.25));
|
|
104
|
+
parts.push(box(w * 0.7, 0.12, 0.12, 0, y0 + 0.1, -0.25));
|
|
105
|
+
return { frame: parts, panelY: y0 + h / 2, panelZ: 0 };
|
|
106
|
+
}
|
|
107
|
+
if (kind === 'totem') {
|
|
108
|
+
parts.push(box(w * 1.1, 0.25, 0.8, 0, 0.125, 0));
|
|
109
|
+
return { frame: parts, panelY: 0.25 + h / 2, panelZ: 0 };
|
|
110
|
+
}
|
|
111
|
+
// rooftop: a light truss of posts and diagonals up to the elevation
|
|
112
|
+
const y0 = Math.max(elev, 0.5);
|
|
113
|
+
const n = Math.max(2, Math.round(w / 2.5));
|
|
114
|
+
for (let i = 0; i < n; i++) {
|
|
115
|
+
const x = -w / 2 + (i + 0.5) * (w / n);
|
|
116
|
+
parts.push(new THREE.CylinderGeometry(0.05, 0.05, y0, 8).translate(x, y0 / 2, -0.2));
|
|
117
|
+
parts.push(new THREE.CylinderGeometry(0.04, 0.04, y0, 8).translate(x, y0 / 2, -1.0));
|
|
118
|
+
const diag = new THREE.CylinderGeometry(0.03, 0.03, Math.hypot(y0, 0.8), 6);
|
|
119
|
+
diag.rotateX(Math.atan2(0.8, y0));
|
|
120
|
+
diag.translate(x, y0 / 2, -0.6);
|
|
121
|
+
parts.push(diag);
|
|
122
|
+
}
|
|
123
|
+
parts.push(box(w, 0.06, 1.0, 0, y0, -0.6));
|
|
124
|
+
return { frame: parts, panelY: y0 + h / 2, panelZ: 0 };
|
|
125
|
+
}
|
|
126
|
+
export function build(u, c) {
|
|
127
|
+
const group = new THREE.Group();
|
|
128
|
+
const panelMat = createMaterial(u, c.doubleSided);
|
|
129
|
+
const fixU = createFixtureUniforms();
|
|
130
|
+
const fixture = createFixtureMaterial(fixU);
|
|
131
|
+
let panel = null, frame = null, lamp = null, headLocal = null, img = null;
|
|
132
|
+
const clear = () => {
|
|
133
|
+
for (const m of [panel, frame])
|
|
134
|
+
if (m) {
|
|
135
|
+
group.remove(m);
|
|
136
|
+
m.geometry.dispose();
|
|
137
|
+
}
|
|
138
|
+
panel = frame = null;
|
|
139
|
+
if (lamp) {
|
|
140
|
+
unregisterLamp(lamp);
|
|
141
|
+
lamp = null;
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
const rebuild = (cfg) => {
|
|
145
|
+
clear();
|
|
146
|
+
const w = Math.max(0.3, cfg.width), h = Math.max(0.3, cfg.height);
|
|
147
|
+
const car = carrier(cfg.kind, w, h, cfg.elevation);
|
|
148
|
+
panelMat.side = cfg.doubleSided ? THREE.DoubleSide : THREE.FrontSide;
|
|
149
|
+
panelMat.needsUpdate = true;
|
|
150
|
+
panel = new THREE.Mesh(new THREE.PlaneGeometry(w, h), panelMat);
|
|
151
|
+
panel.position.set(0, car.panelY, car.panelZ);
|
|
152
|
+
group.add(panel);
|
|
153
|
+
if (car.frame.length) {
|
|
154
|
+
frame = new THREE.Mesh(mergeGeometries(car.frame, [['aEmissive', 1], ['aAccent', 1]]), fixture);
|
|
155
|
+
group.add(frame);
|
|
156
|
+
}
|
|
157
|
+
headLocal = new THREE.Vector3(0, car.panelY - h * 0.3, 1.0);
|
|
158
|
+
lamp = registerLamp({ id: 'sign', position: headLocal.clone(), color: new THREE.Color(cfg.color).lerp(new THREE.Color('#ffffff'), 0.6), radius: Math.max(6, w * 1.2), intensity: 0.5 * cfg.glow, on: true });
|
|
159
|
+
};
|
|
160
|
+
const setImage = (cfg) => {
|
|
161
|
+
const url = cfg.imageUrl || '';
|
|
162
|
+
if (!url) {
|
|
163
|
+
u.uImage.value = _none;
|
|
164
|
+
u.uHasImage.value = 0;
|
|
165
|
+
img = null;
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
img = loadImage(url, (t) => { u.uImage.value = t; u.uHasImage.value = 1; const im = t.image; if (im && im.width)
|
|
169
|
+
u.uImageAspect.value = im.width / im.height; });
|
|
170
|
+
};
|
|
171
|
+
const apply = (cfg) => {
|
|
172
|
+
applyConfig(u, cfg);
|
|
173
|
+
if (cfg.frameColor !== undefined)
|
|
174
|
+
fixU.uPaint.value.set(cfg.frameColor);
|
|
175
|
+
if (cfg.imageUrl !== undefined && (img === null || cfg.imageUrl !== (img.__url || ''))) {
|
|
176
|
+
setImage(cfg);
|
|
177
|
+
if (img)
|
|
178
|
+
img.__url = cfg.imageUrl;
|
|
179
|
+
}
|
|
180
|
+
if (lamp && cfg.glow !== undefined)
|
|
181
|
+
setLamps([lamp], undefined, 0.5 * cfg.glow);
|
|
182
|
+
};
|
|
183
|
+
rebuild(c);
|
|
184
|
+
apply(c);
|
|
185
|
+
const lastWorld = new THREE.Matrix4();
|
|
186
|
+
return {
|
|
187
|
+
object: group,
|
|
188
|
+
materials: [panelMat, fixture],
|
|
189
|
+
uniformSets: [u, fixU],
|
|
190
|
+
apply,
|
|
191
|
+
rebuild(cfg) { rebuild(cfg); apply(cfg); },
|
|
192
|
+
bounds() { const b = new THREE.Box3(); for (const m of [panel, frame])
|
|
193
|
+
if (m) {
|
|
194
|
+
m.updateMatrix();
|
|
195
|
+
if (!m.geometry.boundingBox)
|
|
196
|
+
m.geometry.computeBoundingBox();
|
|
197
|
+
b.union(m.geometry.boundingBox.clone().applyMatrix4(m.matrix));
|
|
198
|
+
} return b; },
|
|
199
|
+
update() {
|
|
200
|
+
group.updateMatrixWorld();
|
|
201
|
+
if (lamp && !lastWorld.equals(group.matrixWorld)) {
|
|
202
|
+
lastWorld.copy(group.matrixWorld);
|
|
203
|
+
placeLamps([lamp], [headLocal], group.matrixWorld);
|
|
204
|
+
touchLamps();
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
dispose() { clear(); panelMat.dispose(); fixture.dispose(); },
|
|
208
|
+
};
|
|
209
|
+
}
|