@3driseai/3drise-viewer 0.1.42 → 0.1.43
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 +4 -3
|
@@ -0,0 +1,617 @@
|
|
|
1
|
+
// Emitted from Claude outputs/urban-lab/junction.mjs by emit_object.mjs — edit the lab module and re-emit.
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// urban/junction — a road intersection: cross or T, rounded kerbs, crossings, signals
|
|
4
|
+
// =============================================================================
|
|
5
|
+
// Construction. The asphalt is ONE flat polygon: the central square (W x W, W = lanes x lane
|
|
6
|
+
// width) with an arm stub on each side (armLength) and the corners between arms cut in a
|
|
7
|
+
// quarter circle (cornerRadius), triangulated with UVs in metres. The corner pavements are
|
|
8
|
+
// the complementary shapes (square minus the quarter disc) with a kerb ribbon along their
|
|
9
|
+
// inner edge. Markings are per fragment in metres: on each arm the lane dashes, edge
|
|
10
|
+
// lines, a stop line at the box edge and a zebra behind it; the box itself stays plain.
|
|
11
|
+
// Roads butt against the arm ends (same lanes / lane width), so a crossing is a junction
|
|
12
|
+
// plus roads ending at its arms — the two never overlap.
|
|
13
|
+
//
|
|
14
|
+
// Signals. One pole per corner carries a three-light head facing the approaching arm. All
|
|
15
|
+
// heads are one merged geometry with one shader: each light knows its colour (red / amber /
|
|
16
|
+
// green) and its axis group (x arms or z arms); a phase uniform cycles the groups through
|
|
17
|
+
// green - amber - red with an all-red gap. Emissive only (no light); off by day unless the
|
|
18
|
+
// object is forced to night.
|
|
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, ribbon, mergeGeometries, SURFACE_DEPTH, buildLampGeometry, createFixtureUniforms, createFixtureMaterial, registerLamp, unregisterLamp, touchLamps, setLamps, placeLamps, } from '../urbanCore.js';
|
|
21
|
+
import { slabGeometry } from './plaza.js';
|
|
22
|
+
export const SHAPES = ['cross', 'tee', 'roundabout', 'roundabout3']; // roundabout3: three arms, no -z arm (like a T)
|
|
23
|
+
const isRound = (shape) => shape === 'roundabout' || shape === 'roundabout3';
|
|
24
|
+
export const LIGHTING = ['auto', 'day', 'night'];
|
|
25
|
+
export const STRUCTURAL = ['shape', 'islandRadius', 'lanes', 'laneWidth', 'armLength', 'cornerRadius', 'texture', 'sidewalk', 'kerbHeight', 'sidewalkTexture', 'signals', 'signalHeight', 'lamps', 'lampHeight', 'seed'];
|
|
26
|
+
// ---------------------------------------------------------------------------- asphalt material
|
|
27
|
+
export function createUniforms() {
|
|
28
|
+
return Object.assign(createSunUniforms(), createLampUniforms(), createTextureUniforms('uAsp'), {
|
|
29
|
+
uAsphaltColor: { value: new THREE.Color() },
|
|
30
|
+
uMarkingColor: { value: new THREE.Color() },
|
|
31
|
+
uWidth: { value: 7 },
|
|
32
|
+
uLaneWidth: { value: 3.5 },
|
|
33
|
+
uLanes: { value: 2 },
|
|
34
|
+
uArm: { value: 14 },
|
|
35
|
+
uCrosswalks: { value: 1 },
|
|
36
|
+
uWear: { value: 0.5 },
|
|
37
|
+
uSeed: { value: 0 },
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
export function applyConfig(u, c, tex = undefined) {
|
|
41
|
+
if (c.asphaltColor !== undefined)
|
|
42
|
+
u.uAsphaltColor.value.set(c.asphaltColor);
|
|
43
|
+
if (c.markingColor !== undefined)
|
|
44
|
+
u.uMarkingColor.value.set(c.markingColor);
|
|
45
|
+
if (c.crosswalks !== undefined)
|
|
46
|
+
u.uCrosswalks.value = c.crosswalks ? 1 : 0;
|
|
47
|
+
if (c.wear !== undefined)
|
|
48
|
+
u.uWear.value = c.wear;
|
|
49
|
+
if (c.lanes !== undefined && c.laneWidth !== undefined) {
|
|
50
|
+
u.uLanes.value = Math.max(1, Math.round(c.lanes));
|
|
51
|
+
u.uLaneWidth.value = c.laneWidth;
|
|
52
|
+
u.uWidth.value = Math.max(1, Math.round(c.lanes)) * c.laneWidth;
|
|
53
|
+
}
|
|
54
|
+
if (c.armLength !== undefined)
|
|
55
|
+
u.uArm.value = c.armLength;
|
|
56
|
+
if (c.seed !== undefined)
|
|
57
|
+
u.uSeed.value = c.seed;
|
|
58
|
+
if (tex !== undefined)
|
|
59
|
+
applyTextureSet(u, 'uAsp', tex, c.texture && c.texture.tileSize, 0.6);
|
|
60
|
+
}
|
|
61
|
+
export const VERT = /* glsl */ `
|
|
62
|
+
attribute vec2 aUV;
|
|
63
|
+
attribute float aTee; // 1 on a T (no -z arm): per vertex, so a street grid can merge tees and crosses
|
|
64
|
+
attribute float aRound; // a roundabout's island radius (0 = a crossing), per vertex for the same reason
|
|
65
|
+
varying vec3 vN; varying vec3 vP; varying vec2 vQ; varying float vTee; varying float vRound;
|
|
66
|
+
${GLSL_FOG_VERT_PARS}
|
|
67
|
+
void main() {
|
|
68
|
+
vec4 wp = modelMatrix * vec4(position, 1.0);
|
|
69
|
+
vP = wp.xyz;
|
|
70
|
+
vN = normalize(mat3(modelMatrix) * normal);
|
|
71
|
+
vQ = aUV;
|
|
72
|
+
vTee = aTee; vRound = aRound;
|
|
73
|
+
vec4 mvPosition = viewMatrix * wp;
|
|
74
|
+
gl_Position = projectionMatrix * mvPosition;
|
|
75
|
+
#include <fog_vertex>
|
|
76
|
+
}`;
|
|
77
|
+
export const FRAG = /* glsl */ `
|
|
78
|
+
precision highp float;
|
|
79
|
+
${GLSL_COMMON}
|
|
80
|
+
${glslTextureBlock('uAsp')}
|
|
81
|
+
uniform vec3 uAsphaltColor; uniform vec3 uMarkingColor;
|
|
82
|
+
uniform float uWidth; uniform float uLaneWidth; uniform float uLanes; uniform float uArm; uniform float uCrosswalks; uniform float uWear; uniform float uSeed;
|
|
83
|
+
varying vec3 vN; varying vec3 vP; varying vec2 vQ; varying float vTee; varying float vRound;
|
|
84
|
+
${GLSL_FOG_PARS}
|
|
85
|
+
|
|
86
|
+
float lineAA(float x, float w) { return 1.0 - bandAA(abs(x), w * 0.5, 1e9); }
|
|
87
|
+
float dashAA(float s) { float m = mod(s, 12.0); return bandAA(m, 0.0, 3.0); }
|
|
88
|
+
|
|
89
|
+
// Markings of one arm, in the arm's own frame: a = metres out from the box edge, t = across (metres from the arm centre).
|
|
90
|
+
// ys = 0: a crossing (a stop line across the arm); ys = +-1: a roundabout entry — a dashed give-way
|
|
91
|
+
// line across the entry half only (the half where t * ys > 0).
|
|
92
|
+
float armMarks(float a, float t, float ys) {
|
|
93
|
+
float lw = 0.12, hw = uWidth * 0.5;
|
|
94
|
+
float m = 0.0;
|
|
95
|
+
// Lane boundaries (dashed) and the centre line (dashed), edge lines solid, only past the zebra.
|
|
96
|
+
float past = bandAA(a, 5.8, 1e9);
|
|
97
|
+
float bPos = mod(t + hw + uLaneWidth * 0.5, uLaneWidth) - uLaneWidth * 0.5;
|
|
98
|
+
float even = 1.0 - mod(uLanes, 2.0);
|
|
99
|
+
float notEdge = 1.0 - step(hw - uLaneWidth * 0.25, abs(t));
|
|
100
|
+
m += lineAA(bPos, lw) * dashAA(a + 6.0) * notEdge * past;
|
|
101
|
+
m += lineAA(t, lw) * even * dashAA(a) * past;
|
|
102
|
+
m += lineAA(abs(t) - (hw - 0.3), lw);
|
|
103
|
+
// Zebra 2..5 m out, stop line at 5.4..5.75.
|
|
104
|
+
float zebra = bandAA(a, 2.0, 5.0) * bandAA(mod(t + hw, 1.0), 0.0, 0.5) * uCrosswalks;
|
|
105
|
+
if (ys == 0.0) zebra = max(zebra, bandAA(a, 5.4, 5.75) * uCrosswalks);
|
|
106
|
+
else zebra = max(zebra, bandAA(a, 0.4, 0.75) * bandAA(mod(t, 1.0), 0.0, 0.55) * step(0.0, t * ys));
|
|
107
|
+
return clamp(max(m, zebra), 0.0, 1.0);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// A roundabout's ring (local frame, island radius ri): edge lines, dashed lane lines around it, no
|
|
111
|
+
// edge line across the arm mouths.
|
|
112
|
+
float ringMarks(vec2 q, float ri) {
|
|
113
|
+
float lw = 0.12, hw = uWidth * 0.5;
|
|
114
|
+
float r = length(q), ro = ri + uWidth, inner = r - ri;
|
|
115
|
+
float ph = atan(q.y, q.x) * r;
|
|
116
|
+
float m = lineAA(r - (ri + 0.3), lw);
|
|
117
|
+
float laneLine = lineAA(mod(inner + uLaneWidth * 0.5, uLaneWidth) - uLaneWidth * 0.5, lw);
|
|
118
|
+
m += laneLine * dashAA(ph) * step(uLaneWidth * 0.5, inner) * step(inner, uWidth - uLaneWidth * 0.5);
|
|
119
|
+
float mouth = max(step(abs(q.y), hw), step(abs(q.x), hw) * max(step(0.0, q.y), 1.0 - step(0.5, vTee)));
|
|
120
|
+
m += lineAA(r - (ro - 0.3), lw) * (1.0 - mouth);
|
|
121
|
+
return clamp(m, 0.0, 1.0);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
void main() {
|
|
125
|
+
vec3 N = normalize(vN);
|
|
126
|
+
vec3 V = normalize(cameraPosition - vP);
|
|
127
|
+
vec3 T = vec3(1.0, 0.0, 0.0), B = vec3(0.0, 0.0, 1.0);
|
|
128
|
+
float rough;
|
|
129
|
+
vec3 Nb = N;
|
|
130
|
+
vec3 mul = uAspSample(vQ, Nb, T, B, rough);
|
|
131
|
+
float hw = uWidth * 0.5;
|
|
132
|
+
float x = vQ.x, z = vQ.y;
|
|
133
|
+
// Which arm (if any) this fragment is on: outside the central box along one axis.
|
|
134
|
+
float mark = 0.0, tracks = 0.0;
|
|
135
|
+
if (vRound > 0.5) {
|
|
136
|
+
// A roundabout: the ring, then the arms from the ring's outer edge (give-way on the entry half;
|
|
137
|
+
// right-hand traffic: entering the +x arm you drive toward -x on its -z half).
|
|
138
|
+
float ro = vRound + uWidth;
|
|
139
|
+
if (length(vQ) < ro + 0.01) mark = ringMarks(vQ, vRound);
|
|
140
|
+
else if (abs(z) <= hw) mark = armMarks(abs(x) - ro, z, -sign(x));
|
|
141
|
+
else if (abs(x) <= hw && !(vTee > 0.5 && z < 0.0)) mark = armMarks(abs(z) - ro, x, sign(z));
|
|
142
|
+
} else {
|
|
143
|
+
if (abs(x) > hw && abs(z) <= hw) mark = armMarks(abs(x) - hw, z, 0.0); // +x / -x arms
|
|
144
|
+
else if (abs(z) > hw && abs(x) <= hw) {
|
|
145
|
+
if (!(vTee > 0.5 && z < 0.0)) mark = armMarks(abs(z) - hw, x, 0.0); // +z / -z arms (a T has no -z arm)
|
|
146
|
+
}
|
|
147
|
+
// Wheel wear through the box along both axes.
|
|
148
|
+
float lanePosX = mod(z + hw, uLaneWidth) - uLaneWidth * 0.5;
|
|
149
|
+
float lanePosZ = mod(x + hw, uLaneWidth) - uLaneWidth * 0.5;
|
|
150
|
+
tracks = max(exp(-pow((abs(lanePosX) - 0.9) / 0.45, 2.0)) * step(abs(z), hw), exp(-pow((abs(lanePosZ) - 0.9) / 0.45, 2.0)) * step(abs(x), hw));
|
|
151
|
+
}
|
|
152
|
+
float macro = 0.92 + 0.16 * vnoise21(vQ / 9.0 + uSeed);
|
|
153
|
+
vec3 albedo = uAsphaltColor * mul * macro * (1.0 - 0.18 * uWear * tracks);
|
|
154
|
+
rough = mix(rough, 0.95, 0.4);
|
|
155
|
+
float chip = hash21(floor(vec2(x * 2.0, z * 4.0)) + uSeed);
|
|
156
|
+
mark *= 1.0 - clamp(uWear * (0.35 * step(chip, 0.25 * uWear) + 0.4 * tracks), 0.0, 0.85);
|
|
157
|
+
albedo = mix(albedo, uMarkingColor * mix(1.0, 0.75, chip * uWear), mark);
|
|
158
|
+
rough = mix(rough, 0.6, mark);
|
|
159
|
+
vec3 col = shadeSurface(albedo, Nb, vP, V, rough, 1.0);
|
|
160
|
+
${GLSL_OUT}
|
|
161
|
+
}`;
|
|
162
|
+
export function createMaterial(u) {
|
|
163
|
+
return new THREE.ShaderMaterial({ uniforms: Object.assign(THREE.UniformsUtils.clone(THREE.UniformsLib.fog), u), vertexShader: VERT, fragmentShader: FRAG, fog: true, ...SURFACE_DEPTH });
|
|
164
|
+
}
|
|
165
|
+
// ---------------------------------------------------------------------------- signals material
|
|
166
|
+
export function createSignalUniforms() {
|
|
167
|
+
return Object.assign(createSunUniforms(), createLampUniforms(), {
|
|
168
|
+
uPaint: { value: new THREE.Color('#2b2f33') },
|
|
169
|
+
uPhase: { value: 0 }, // 0..1 through one cycle
|
|
170
|
+
uOn: { value: 1 }, // night factor gate (signals also show by day, dimmer)
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
const SIGNAL_VERT = /* glsl */ `
|
|
174
|
+
attribute float aLight; // 0 red, 1 amber, 2 green, -1 body
|
|
175
|
+
attribute float aGroup; // 0 x arms, 1 z arms
|
|
176
|
+
varying vec3 vN; varying vec3 vP; varying float vL; varying float vG;
|
|
177
|
+
${GLSL_FOG_VERT_PARS}
|
|
178
|
+
void main() {
|
|
179
|
+
vec4 wp = modelMatrix * vec4(position, 1.0);
|
|
180
|
+
vP = wp.xyz; vN = normalize(mat3(modelMatrix) * normal); vL = aLight; vG = aGroup;
|
|
181
|
+
vec4 mvPosition = viewMatrix * wp;
|
|
182
|
+
gl_Position = projectionMatrix * mvPosition;
|
|
183
|
+
#include <fog_vertex>
|
|
184
|
+
}`;
|
|
185
|
+
const SIGNAL_FRAG = /* glsl */ `
|
|
186
|
+
precision highp float;
|
|
187
|
+
${GLSL_COMMON}
|
|
188
|
+
uniform vec3 uPaint; uniform float uPhase; uniform float uOn;
|
|
189
|
+
varying vec3 vN; varying vec3 vP; varying float vL; varying float vG;
|
|
190
|
+
${GLSL_FOG_PARS}
|
|
191
|
+
// One cycle: x arms green 0..0.40, amber 0.40..0.47, all red 0.47..0.50, z arms green 0.50..0.90, amber 0.90..0.97, all red 0.97..1.
|
|
192
|
+
float lit(float light, float group) {
|
|
193
|
+
float p = mod(uPhase + group * 0.5, 1.0); // the z group runs half a cycle behind
|
|
194
|
+
float green = step(p, 0.40), amber = step(0.40, p) * step(p, 0.47), red = step(0.47, p);
|
|
195
|
+
return light < 0.5 ? red : light < 1.5 ? amber : green;
|
|
196
|
+
}
|
|
197
|
+
void main() {
|
|
198
|
+
vec3 N = normalize(vN);
|
|
199
|
+
vec3 V = normalize(cameraPosition - vP);
|
|
200
|
+
vec3 col = shadeSurface(uPaint, N, vP, V, 0.5, 1.0);
|
|
201
|
+
if (vL > -0.5) {
|
|
202
|
+
vec3 c = vL < 0.5 ? vec3(1.0, 0.1, 0.05) : vL < 1.5 ? vec3(1.0, 0.6, 0.08) : vec3(0.1, 1.0, 0.35);
|
|
203
|
+
float on = lit(vL, vG);
|
|
204
|
+
// A lit lens is bright (over 1 for bloom at night); an unlit one is a dark coloured glass.
|
|
205
|
+
col = mix(c * 0.08 + col * 0.3, c * (1.2 + 1.6 * uNight), on);
|
|
206
|
+
}
|
|
207
|
+
${GLSL_OUT}
|
|
208
|
+
}`;
|
|
209
|
+
export function createSignalMaterial(u) {
|
|
210
|
+
return new THREE.ShaderMaterial({ uniforms: Object.assign(THREE.UniformsUtils.clone(THREE.UniformsLib.fog), u), vertexShader: SIGNAL_VERT, fragmentShader: SIGNAL_FRAG, fog: true });
|
|
211
|
+
}
|
|
212
|
+
/** A signal pole: post, a short arm toward the road and a 3-light head facing `facing` (unit xz). Lights tagged by group. */
|
|
213
|
+
function signalGeometry(x, z, facing, group, height) {
|
|
214
|
+
const parts = [];
|
|
215
|
+
const tag = (g, light) => { const n = g.getAttribute('position').count; g.setAttribute('aLight', new THREE.BufferAttribute(new Float32Array(n).fill(light), 1)); g.setAttribute('aGroup', new THREE.BufferAttribute(new Float32Array(n).fill(group), 1)); return g; };
|
|
216
|
+
const ang = Math.atan2(facing.x, facing.z); // rotation about y so +z faces `facing`
|
|
217
|
+
const place = (g) => { g.rotateY(ang); g.translate(x, 0, z); return g; };
|
|
218
|
+
parts.push(tag(place(new THREE.CylinderGeometry(0.06, 0.09, height, 10).translate(0, height / 2, 0)), -1));
|
|
219
|
+
// Head: a box 0.35 x 1.0 x 0.3 at the top, lenses on its +z face.
|
|
220
|
+
parts.push(tag(place(new THREE.BoxGeometry(0.36, 1.05, 0.3).translate(0, height - 0.5, 0.15)), -1));
|
|
221
|
+
// Hoods: small plates above each lens.
|
|
222
|
+
for (let i = 0; i < 3; i++) {
|
|
223
|
+
const y = height - 0.18 - i * 0.32;
|
|
224
|
+
parts.push(tag(place(new THREE.BoxGeometry(0.3, 0.03, 0.14).translate(0, y + 0.13, 0.36)), -1));
|
|
225
|
+
parts.push(tag(place(new THREE.CylinderGeometry(0.1, 0.1, 0.04, 16).rotateX(Math.PI / 2).translate(0, y, 0.31)), i));
|
|
226
|
+
}
|
|
227
|
+
return parts;
|
|
228
|
+
}
|
|
229
|
+
// ---------------------------------------------------------------------------- geometry
|
|
230
|
+
/** Outline of the asphalt (cross or T) with concave rounded corners, CCW seen from above. */
|
|
231
|
+
function asphaltOutline(half, arm, R, tee) {
|
|
232
|
+
const pts = [];
|
|
233
|
+
const L = half + arm;
|
|
234
|
+
const arc = (cx, cz, a0, a1) => { const n = 8; for (let i = 0; i <= n; i++) {
|
|
235
|
+
const a = a0 + (a1 - a0) * i / n;
|
|
236
|
+
pts.push([cx + Math.cos(a) * R, cz + Math.sin(a) * R]);
|
|
237
|
+
} };
|
|
238
|
+
R = Math.min(R, arm - 0.5);
|
|
239
|
+
// Walk the outline: +x arm end, corner (+x,+z), +z arm, corner (-x,+z), -x arm, corner (-x,-z), -z arm (or straight edge for a T), corner (+x,-z).
|
|
240
|
+
pts.push([L, -half], [L, half]);
|
|
241
|
+
arc(half + R, half + R, -Math.PI / 2, -Math.PI); // concave corner between +x and +z arms
|
|
242
|
+
pts.push([half, L], [-half, L]);
|
|
243
|
+
arc(-half - R, half + R, 0, -Math.PI / 2);
|
|
244
|
+
pts.push([-L, half], [-L, -half]);
|
|
245
|
+
if (tee) {
|
|
246
|
+
pts.push([-half, -half], [half, -half]); // straight south edge
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
arc(-half - R, -half - R, Math.PI / 2, 0);
|
|
250
|
+
pts.push([-half, -L], [half, -L]);
|
|
251
|
+
arc(half + R, -half - R, Math.PI, Math.PI / 2);
|
|
252
|
+
}
|
|
253
|
+
return pts;
|
|
254
|
+
}
|
|
255
|
+
/** One corner pavement: the square between two arms minus the quarter disc, plus its kerb path (inner edge). */
|
|
256
|
+
function cornerShape(sx, sz, half, arm, R) {
|
|
257
|
+
R = Math.min(R, arm - 0.5);
|
|
258
|
+
const L = half + arm;
|
|
259
|
+
const pts = [];
|
|
260
|
+
// From the +x arm edge along the arc to the +z arm edge, then the outer square corner. (sx, sz = ±1 mirror.)
|
|
261
|
+
const arcPts = [];
|
|
262
|
+
const n = 10;
|
|
263
|
+
for (let i = 0; i <= n; i++) {
|
|
264
|
+
const a = -Math.PI / 2 - (Math.PI / 2) * i / n;
|
|
265
|
+
arcPts.push([half + R + Math.cos(a) * R, half + R + Math.sin(a) * R]);
|
|
266
|
+
}
|
|
267
|
+
pts.push([L, half], ...arcPts.slice(1, n), [half, L], [L, L]);
|
|
268
|
+
const m = pts.map(([x, z]) => [x * sx, z * sz]);
|
|
269
|
+
const kerb = [[L, half], ...arcPts, [half, L]].map(([x, z]) => [x * sx, z * sz]);
|
|
270
|
+
return { outline: m, kerb };
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* How far from its centre a junction reaches along each arm: where a road of the same lanes
|
|
274
|
+
* starts. A crossing: half the road plus the arm; a roundabout: island, ring and the arm.
|
|
275
|
+
*/
|
|
276
|
+
export function junctionReach(c) {
|
|
277
|
+
const W = Math.max(1, Math.round(c.lanes)) * c.laneWidth;
|
|
278
|
+
if (isRound(c.shape))
|
|
279
|
+
return Math.max(2, c.islandRadius) + W + Math.max(c.armLength, 6);
|
|
280
|
+
return W / 2 + Math.max(c.armLength, 6);
|
|
281
|
+
}
|
|
282
|
+
/** A flat slab from an outline and hole outlines ([[x, z], …]) at height y; aUV = (x, z) metres, facing up. */
|
|
283
|
+
function slabWithHoles(outer, holes, y) {
|
|
284
|
+
const shape = new THREE.Shape(outer.map(([x, z]) => new THREE.Vector2(x, z)));
|
|
285
|
+
for (const h of holes)
|
|
286
|
+
shape.holes.push(new THREE.Path(h.map(([x, z]) => new THREE.Vector2(x, z))));
|
|
287
|
+
const g = new THREE.ShapeGeometry(shape, 1);
|
|
288
|
+
const pos = g.getAttribute('position');
|
|
289
|
+
const uv = new Float32Array(pos.count * 2);
|
|
290
|
+
for (let i = 0; i < pos.count; i++) {
|
|
291
|
+
const x = pos.getX(i), z = pos.getY(i);
|
|
292
|
+
pos.setXYZ(i, x, y, z);
|
|
293
|
+
uv[i * 2] = x;
|
|
294
|
+
uv[i * 2 + 1] = z;
|
|
295
|
+
}
|
|
296
|
+
pos.needsUpdate = true;
|
|
297
|
+
g.setAttribute('aUV', new THREE.BufferAttribute(uv, 2));
|
|
298
|
+
g.computeVertexNormals();
|
|
299
|
+
if (g.getAttribute('normal').getY(0) < 0) {
|
|
300
|
+
const idx = g.index;
|
|
301
|
+
for (let i = 0; i < idx.count; i += 3) {
|
|
302
|
+
const t = idx.getX(i + 1);
|
|
303
|
+
idx.setX(i + 1, idx.getX(i + 2));
|
|
304
|
+
idx.setX(i + 2, t);
|
|
305
|
+
}
|
|
306
|
+
idx.needsUpdate = true;
|
|
307
|
+
g.computeVertexNormals();
|
|
308
|
+
}
|
|
309
|
+
g.computeBoundingBox();
|
|
310
|
+
g.computeBoundingSphere();
|
|
311
|
+
return g;
|
|
312
|
+
}
|
|
313
|
+
/** A vertical kerb face along a polyline from y0 to y1, its normal turned away from (outward) or toward the centre. */
|
|
314
|
+
function kerbFace(pts, y0, y1, outward) {
|
|
315
|
+
const ks = pts.map(([x, z], i) => {
|
|
316
|
+
const q = pts[Math.min(i + 1, pts.length - 1)], p0 = pts[Math.max(i - 1, 0)];
|
|
317
|
+
const t = new THREE.Vector3(q[0] - p0[0], 0, q[1] - p0[1]).normalize();
|
|
318
|
+
return { p: new THREE.Vector3(x, 0, z), t, n: new THREE.Vector3(t.z, 0, -t.x), s: i * 1.5 };
|
|
319
|
+
});
|
|
320
|
+
const face = ribbon(ks, 0, 0, y1, y0, true, 1);
|
|
321
|
+
const nrm = face.getAttribute('normal'), p = face.getAttribute('position');
|
|
322
|
+
const k = Math.floor(nrm.count / 2);
|
|
323
|
+
const away = nrm.getX(k) * p.getX(k) + nrm.getZ(k) * p.getZ(k) > 0;
|
|
324
|
+
if (away !== outward) {
|
|
325
|
+
for (let i = 0; i < nrm.count; i++)
|
|
326
|
+
nrm.setXYZ(i, -nrm.getX(i), 0, -nrm.getZ(i));
|
|
327
|
+
const idx = face.index;
|
|
328
|
+
for (let i = 0; i < idx.count; i += 3) {
|
|
329
|
+
const a = idx.getX(i + 1);
|
|
330
|
+
idx.setX(i + 1, idx.getX(i + 2));
|
|
331
|
+
idx.setX(i + 2, a);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
return face;
|
|
335
|
+
}
|
|
336
|
+
/** Per-vertex flags the asphalt shader reads (so tees, crosses and roundabouts merge into one mesh). */
|
|
337
|
+
function tagAsphalt(g, tee, island) {
|
|
338
|
+
const n = g.getAttribute('position').count;
|
|
339
|
+
g.setAttribute('aTee', new THREE.BufferAttribute(new Float32Array(n).fill(tee ? 1 : 0), 1));
|
|
340
|
+
g.setAttribute('aRound', new THREE.BufferAttribute(new Float32Array(n).fill(island), 1));
|
|
341
|
+
return g;
|
|
342
|
+
}
|
|
343
|
+
const arc = (r, a0, a1, step = 0.07) => {
|
|
344
|
+
const n = Math.max(2, Math.ceil(Math.abs(a1 - a0) / step)), out = [];
|
|
345
|
+
for (let i = 0; i <= n; i++) {
|
|
346
|
+
const a = a0 + (a1 - a0) * i / n;
|
|
347
|
+
out.push([Math.cos(a) * r, Math.sin(a) * r]);
|
|
348
|
+
}
|
|
349
|
+
return out;
|
|
350
|
+
};
|
|
351
|
+
// ---------------------------------------------------------------------------- lab build
|
|
352
|
+
export function build(u, c) {
|
|
353
|
+
const group = new THREE.Group();
|
|
354
|
+
// The asphalt's sun / texture / knob uniforms are the SHARED objects of `u` (a grid hands one set
|
|
355
|
+
// to every junction) while its lamp list is its own — otherwise all junctions sharing `u` would
|
|
356
|
+
// show the lamps gathered for whichever junction was gathered last.
|
|
357
|
+
const aU = Object.assign({}, u, createLampUniforms());
|
|
358
|
+
const asphalt = createMaterial(aU);
|
|
359
|
+
const pavU = createPavingUniforms();
|
|
360
|
+
const paving = createPavingMaterial(pavU);
|
|
361
|
+
const sigU = createSignalUniforms();
|
|
362
|
+
const signalMat = createSignalMaterial(sigU);
|
|
363
|
+
const fixU = createFixtureUniforms();
|
|
364
|
+
const fixture = createFixtureMaterial(fixU);
|
|
365
|
+
// A roundabout's island: the paving material in its lawn mode (its own material, so a grid merge keeps it apart).
|
|
366
|
+
const islU = createPavingUniforms();
|
|
367
|
+
islU.uGrassMix.value = 1;
|
|
368
|
+
islU.uPavColor.value.set('#3e6b25');
|
|
369
|
+
const island = createPavingMaterial(islU);
|
|
370
|
+
island.userData.mergeKey = 'lawn';
|
|
371
|
+
const meshes = [];
|
|
372
|
+
let lamps = [], lampLocal = [];
|
|
373
|
+
const state = { tex: null, walkTex: null, cycle: 14, t: 0 };
|
|
374
|
+
const clear = () => {
|
|
375
|
+
for (const m of meshes) {
|
|
376
|
+
group.remove(m);
|
|
377
|
+
m.geometry.dispose();
|
|
378
|
+
}
|
|
379
|
+
meshes.length = 0;
|
|
380
|
+
for (const L of lamps)
|
|
381
|
+
unregisterLamp(L);
|
|
382
|
+
lamps = [];
|
|
383
|
+
lampLocal = [];
|
|
384
|
+
};
|
|
385
|
+
const polyToSamples = (pts) => pts.map(([x, z], i) => {
|
|
386
|
+
const q = pts[(i + 1) % pts.length], p0 = pts[(i - 1 + pts.length) % pts.length];
|
|
387
|
+
const t = new THREE.Vector3(q[0] - p0[0], 0, q[1] - p0[1]).normalize();
|
|
388
|
+
return { p: new THREE.Vector3(x, 0, z), t, n: new THREE.Vector3(t.z, 0, -t.x), s: i };
|
|
389
|
+
});
|
|
390
|
+
// A roundabout: ring road around a raised lawn island, arms of the junction's lanes from the ring's
|
|
391
|
+
// outer edge (give-way lines, no signals), pavements following the circle between the arms, a
|
|
392
|
+
// lamp in each gap. Arms at +x, +z, -x and -z (roundabout3: no -z arm, like a T).
|
|
393
|
+
const buildRoundabout = (cfg, W, half, arm) => {
|
|
394
|
+
const ri = Math.max(2, cfg.islandRadius), ro = ri + W, L = junctionReach(cfg);
|
|
395
|
+
const three = cfg.shape === 'roundabout3';
|
|
396
|
+
const angles = three ? [0, Math.PI / 2, Math.PI] : [0, Math.PI / 2, Math.PI, Math.PI * 1.5];
|
|
397
|
+
const al = Math.asin(Math.min(0.99, half / ro)), x0 = Math.sqrt(ro * ro - half * half);
|
|
398
|
+
const rot = (a, [x, z]) => [x * Math.cos(a) - z * Math.sin(a), x * Math.sin(a) + z * Math.cos(a)];
|
|
399
|
+
// Asphalt: around the circle, out along each arm and back.
|
|
400
|
+
const outline = [];
|
|
401
|
+
angles.forEach((a, k) => {
|
|
402
|
+
const next = angles[(k + 1) % angles.length] + (k === angles.length - 1 ? Math.PI * 2 : 0);
|
|
403
|
+
outline.push(rot(a, [x0, -half]), rot(a, [L, -half]), rot(a, [L, half]), rot(a, [x0, half]));
|
|
404
|
+
outline.push(...arc(ro, a + al, next - al).slice(1, -1));
|
|
405
|
+
});
|
|
406
|
+
const asph = new THREE.Mesh(tagAsphalt(slabWithHoles(outline, [arc(ri, 0, Math.PI * 2).slice(0, -1)], 0.02), three, ri), asphalt);
|
|
407
|
+
asph.frustumCulled = false;
|
|
408
|
+
group.add(asph);
|
|
409
|
+
meshes.push(asph);
|
|
410
|
+
// Island: lawn at kerb height with its kerb.
|
|
411
|
+
const kh = Math.max(0.02, cfg.kerbHeight);
|
|
412
|
+
const ring = arc(ri, 0, Math.PI * 2);
|
|
413
|
+
const isl = new THREE.Mesh(mergeGeometries([slabWithHoles(ring.slice(0, -1), [], kh), kerbFace(ring, 0, kh, true)], [['aUV', 2]]), island);
|
|
414
|
+
isl.frustumCulled = false;
|
|
415
|
+
group.add(isl);
|
|
416
|
+
meshes.push(isl);
|
|
417
|
+
// Pavements between consecutive arms, along the circle; kerb on the road side.
|
|
418
|
+
if (cfg.sidewalk) {
|
|
419
|
+
const sw = 3, ro2 = ro + sw, al2 = Math.asin(Math.min(0.99, (half + sw) / ro2)), x1 = Math.sqrt(ro2 * ro2 - (half + sw) * (half + sw));
|
|
420
|
+
const parts = [];
|
|
421
|
+
angles.forEach((a, k) => {
|
|
422
|
+
const b2 = angles[(k + 1) % angles.length] + (k === angles.length - 1 ? Math.PI * 2 : 0);
|
|
423
|
+
const inner = [rot(a, [L, half]), rot(a, [x0, half]), ...arc(ro, a + al, b2 - al).slice(1, -1), rot(b2, [x0, -half]), rot(b2, [L, -half])];
|
|
424
|
+
const outer = [rot(b2, [L, -half - sw]), rot(b2, [x1, -half - sw]), ...arc(ro2, b2 - al2, a + al2).slice(1, -1), rot(a, [x1, half + sw]), rot(a, [L, half + sw])];
|
|
425
|
+
parts.push(slabWithHoles([...inner, ...outer], [], kh), kerbFace(inner, 0, kh, false));
|
|
426
|
+
});
|
|
427
|
+
const walk = new THREE.Mesh(mergeGeometries(parts, [['aUV', 2]]), paving);
|
|
428
|
+
walk.frustumCulled = false;
|
|
429
|
+
group.add(walk);
|
|
430
|
+
meshes.push(walk);
|
|
431
|
+
}
|
|
432
|
+
// Lamps: one in each gap between arms, on the pavement, arm over the ring.
|
|
433
|
+
if (cfg.lamps) {
|
|
434
|
+
const geo = buildLampGeometry({ height: cfg.lampHeight, armReach: 1.8 });
|
|
435
|
+
const lm = new THREE.InstancedMesh(geo, fixture, angles.length);
|
|
436
|
+
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);
|
|
437
|
+
angles.forEach((a, k) => {
|
|
438
|
+
const b2 = angles[(k + 1) % angles.length] + (k === angles.length - 1 ? Math.PI * 2 : 0);
|
|
439
|
+
const mid = (a + b2) / 2, r = ro + 1.6;
|
|
440
|
+
p.set(Math.cos(mid) * r, 0, Math.sin(mid) * r);
|
|
441
|
+
q.setFromAxisAngle(up, Math.atan2(p.z, -p.x));
|
|
442
|
+
m.compose(p, q, sc);
|
|
443
|
+
lm.setMatrixAt(k, m);
|
|
444
|
+
const head = geo.userData.head.clone().applyMatrix4(m);
|
|
445
|
+
lampLocal.push(head);
|
|
446
|
+
lamps.push(registerLamp({ id: 'roundabout-' + k, position: head.clone(), color: new THREE.Color(cfg.lampColor), radius: cfg.lampRadius, intensity: cfg.lampIntensity, on: true }));
|
|
447
|
+
});
|
|
448
|
+
lm.instanceMatrix.needsUpdate = true;
|
|
449
|
+
lm.frustumCulled = false;
|
|
450
|
+
group.add(lm);
|
|
451
|
+
meshes.push(lm);
|
|
452
|
+
}
|
|
453
|
+
};
|
|
454
|
+
const rebuild = (cfg) => {
|
|
455
|
+
clear();
|
|
456
|
+
const lanes = Math.max(1, Math.round(cfg.lanes)), W = lanes * cfg.laneWidth, half = W / 2;
|
|
457
|
+
const arm = Math.max(cfg.armLength, 6), R = Math.max(0.5, cfg.cornerRadius);
|
|
458
|
+
const tee = cfg.shape === 'tee';
|
|
459
|
+
if (isRound(cfg.shape)) {
|
|
460
|
+
buildRoundabout(cfg, W, half, arm);
|
|
461
|
+
return;
|
|
462
|
+
}
|
|
463
|
+
// Asphalt slab (y = 0.02), UVs in metres.
|
|
464
|
+
const outline = asphaltOutline(half, arm, R, tee);
|
|
465
|
+
const slabGeo = slabGeometry(polyToSamples(outline), 0.02);
|
|
466
|
+
tagAsphalt(slabGeo, tee, 0);
|
|
467
|
+
const slab = new THREE.Mesh(slabGeo, asphalt);
|
|
468
|
+
slab.frustumCulled = false;
|
|
469
|
+
group.add(slab);
|
|
470
|
+
meshes.push(slab);
|
|
471
|
+
// Corner pavements + kerbs.
|
|
472
|
+
if (cfg.sidewalk) {
|
|
473
|
+
const kh = Math.max(0.02, cfg.kerbHeight);
|
|
474
|
+
const parts = [];
|
|
475
|
+
const corners = tee ? [[1, 1], [-1, 1]] : [[1, 1], [-1, 1], [-1, -1], [1, -1]];
|
|
476
|
+
for (const [sx, sz] of corners) {
|
|
477
|
+
const { outline: o, kerb } = cornerShape(sx, sz, half, arm, R);
|
|
478
|
+
const slabC = slabGeometry(polyToSamples(o), kh);
|
|
479
|
+
parts.push(slabC);
|
|
480
|
+
// Kerb face along the inner edge, facing the road (the arc centre side).
|
|
481
|
+
const ks = kerb.map(([x, z], i) => {
|
|
482
|
+
const q = kerb[Math.min(i + 1, kerb.length - 1)], p0 = kerb[Math.max(i - 1, 0)];
|
|
483
|
+
const t = new THREE.Vector3(q[0] - p0[0], 0, q[1] - p0[1]).normalize();
|
|
484
|
+
return { p: new THREE.Vector3(x, 0, z), t, n: new THREE.Vector3(t.z, 0, -t.x), s: i * 1.5 };
|
|
485
|
+
});
|
|
486
|
+
const face = ribbon(ks, 0, 0, kh, 0.0, true, 1);
|
|
487
|
+
// Point the face toward the asphalt: flip if its normal points away from the junction centre.
|
|
488
|
+
const nrm = face.getAttribute('normal');
|
|
489
|
+
const p = face.getAttribute('position');
|
|
490
|
+
if (nrm.getX(0) * p.getX(0) + nrm.getZ(0) * p.getZ(0) > 0) {
|
|
491
|
+
for (let i = 0; i < nrm.count; i++)
|
|
492
|
+
nrm.setXYZ(i, -nrm.getX(i), 0, -nrm.getZ(i));
|
|
493
|
+
const idx = face.index;
|
|
494
|
+
for (let i = 0; i < idx.count; i += 3) {
|
|
495
|
+
const a = idx.getX(i + 1);
|
|
496
|
+
idx.setX(i + 1, idx.getX(i + 2));
|
|
497
|
+
idx.setX(i + 2, a);
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
parts.push(face);
|
|
501
|
+
}
|
|
502
|
+
if (tee) {
|
|
503
|
+
// A T keeps a straight pavement along the south side.
|
|
504
|
+
const L = half + arm;
|
|
505
|
+
const south = slabGeometry(polyToSamples([[-L, -half], [L, -half], [L, -half - 3], [-L, -half - 3]]), Math.max(0.02, cfg.kerbHeight));
|
|
506
|
+
parts.push(south);
|
|
507
|
+
const ks = [[-L, -half], [L, -half]].map(([x, z], i) => ({ p: new THREE.Vector3(x, 0, z), t: new THREE.Vector3(1, 0, 0), n: new THREE.Vector3(0, 0, -1), s: i * 2 * L }));
|
|
508
|
+
parts.push(ribbon(ks, 0, 0, Math.max(0.02, cfg.kerbHeight), 0.0, true, -1));
|
|
509
|
+
}
|
|
510
|
+
const walk = new THREE.Mesh(mergeGeometries(parts, [['aUV', 2]]), paving);
|
|
511
|
+
walk.frustumCulled = false;
|
|
512
|
+
group.add(walk);
|
|
513
|
+
meshes.push(walk);
|
|
514
|
+
}
|
|
515
|
+
// Signals: one per corner, on the pavement 1 m from the kerb, facing the arm whose traffic it controls.
|
|
516
|
+
if (cfg.signals) {
|
|
517
|
+
const parts = [];
|
|
518
|
+
const h = cfg.signalHeight;
|
|
519
|
+
const corners = tee ? [[1, 1], [-1, 1]] : [[1, 1], [-1, 1], [-1, -1], [1, -1]];
|
|
520
|
+
for (const [sx, sz] of corners) {
|
|
521
|
+
// The pole at the corner controls the arm it faces: traffic on the +x arm (coming toward -x) sees the head at corner (+x, -z)... keep it simple:
|
|
522
|
+
// each corner gets one head facing along -sx (controls the x arm on its side, group 0) and one facing -sz (z arm, group 1).
|
|
523
|
+
const px = sx * (half + 1.2), pz = sz * (half + 1.2);
|
|
524
|
+
parts.push(...signalGeometry(px, pz, new THREE.Vector3(sx, 0, 0), 0, h));
|
|
525
|
+
if (!(tee && sz < 0))
|
|
526
|
+
parts.push(...signalGeometry(px + sx * 0.5, pz, new THREE.Vector3(0, 0, sz), 1, h));
|
|
527
|
+
}
|
|
528
|
+
const sig = new THREE.Mesh(mergeGeometries(parts, [['aLight', 1], ['aGroup', 1]]), signalMat);
|
|
529
|
+
sig.frustumCulled = false;
|
|
530
|
+
group.add(sig);
|
|
531
|
+
meshes.push(sig);
|
|
532
|
+
}
|
|
533
|
+
// Lamps: one per corner on the pavement, behind the signal pole, arm reaching over the kerb;
|
|
534
|
+
// registered in the lamp list so the asphalt, the pavements and nearby facades take their light.
|
|
535
|
+
if (cfg.lamps) {
|
|
536
|
+
const corners = tee ? [[1, 1], [-1, 1]] : [[1, 1], [-1, 1], [-1, -1], [1, -1]];
|
|
537
|
+
const geo = buildLampGeometry({ height: cfg.lampHeight, armReach: 1.8 });
|
|
538
|
+
const lm = new THREE.InstancedMesh(geo, fixture, corners.length);
|
|
539
|
+
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);
|
|
540
|
+
corners.forEach(([sx, sz], i) => {
|
|
541
|
+
p.set(sx * (half + 3.2), 0, sz * (half + 3.2));
|
|
542
|
+
// The arm points at the junction centre (the lamp geometry's arm is along +x).
|
|
543
|
+
q.setFromAxisAngle(up, Math.atan2(sz, -sx));
|
|
544
|
+
m.compose(p, q, sc);
|
|
545
|
+
lm.setMatrixAt(i, m);
|
|
546
|
+
const head = geo.userData.head.clone().applyMatrix4(m);
|
|
547
|
+
lampLocal.push(head);
|
|
548
|
+
lamps.push(registerLamp({ id: 'junction-' + i, position: head.clone(), color: new THREE.Color(cfg.lampColor), radius: cfg.lampRadius, intensity: cfg.lampIntensity, on: true }));
|
|
549
|
+
});
|
|
550
|
+
lm.instanceMatrix.needsUpdate = true;
|
|
551
|
+
lm.frustumCulled = false;
|
|
552
|
+
group.add(lm);
|
|
553
|
+
meshes.push(lm);
|
|
554
|
+
}
|
|
555
|
+
state.cycle = Math.max(2, cfg.signalCycle);
|
|
556
|
+
};
|
|
557
|
+
const setTextures = (cfg) => {
|
|
558
|
+
const m = cfg.texture && cfg.texture.maps;
|
|
559
|
+
state.tex = m && m.color ? loadTextureSet(m) : null;
|
|
560
|
+
if (state.tex)
|
|
561
|
+
state.tex.ready.then(() => applyConfig(u, cfg, state.tex));
|
|
562
|
+
applyConfig(u, cfg, state.tex && state.tex.color ? state.tex : null);
|
|
563
|
+
const wm = cfg.sidewalkTexture && cfg.sidewalkTexture.maps;
|
|
564
|
+
state.walkTex = wm && wm.color ? loadTextureSet(wm) : null;
|
|
565
|
+
const ap = () => applyTextureSet(pavU, 'uPav', state.walkTex && state.walkTex.color ? state.walkTex : null, cfg.sidewalkTexture && cfg.sidewalkTexture.tileSize, 0.7);
|
|
566
|
+
if (state.walkTex)
|
|
567
|
+
state.walkTex.ready.then(ap);
|
|
568
|
+
ap();
|
|
569
|
+
};
|
|
570
|
+
const apply = (cfg) => {
|
|
571
|
+
applyConfig(u, cfg, undefined);
|
|
572
|
+
if (cfg.sidewalkColor !== undefined)
|
|
573
|
+
pavU.uPavColor.value.set(cfg.sidewalkColor);
|
|
574
|
+
if (cfg.signalPaint !== undefined)
|
|
575
|
+
sigU.uPaint.value.set(cfg.signalPaint);
|
|
576
|
+
if (cfg.signalCycle !== undefined)
|
|
577
|
+
state.cycle = Math.max(2, cfg.signalCycle);
|
|
578
|
+
if (cfg.lampPaint !== undefined)
|
|
579
|
+
fixU.uPaint.value.set(cfg.lampPaint);
|
|
580
|
+
if (cfg.lampColor !== undefined)
|
|
581
|
+
fixU.uLampColor.value.set(cfg.lampColor);
|
|
582
|
+
if (cfg.lampIntensity !== undefined)
|
|
583
|
+
fixU.uLampGlow.value = cfg.lampIntensity / 2.6;
|
|
584
|
+
setLamps(lamps, cfg.lampColor, cfg.lampIntensity, cfg.lampRadius); // bumps the lamp list only on a real change
|
|
585
|
+
};
|
|
586
|
+
rebuild(c);
|
|
587
|
+
setTextures(c);
|
|
588
|
+
apply(c);
|
|
589
|
+
const lastWorld = new THREE.Matrix4();
|
|
590
|
+
return {
|
|
591
|
+
object: group,
|
|
592
|
+
materials: [asphalt, paving, signalMat, fixture, island],
|
|
593
|
+
uniformSets: [u, pavU, sigU, fixU, islU],
|
|
594
|
+
/** Lamp gathering targets: the asphalt and the pavements, each with its own lamp list. */
|
|
595
|
+
lampTargets() { const b = this.bounds(); return [{ u: aU, bounds: b }, { u: pavU, bounds: b }, { u: islU, bounds: b }]; },
|
|
596
|
+
apply,
|
|
597
|
+
rebuild(cfg) { rebuild(cfg); setTextures(cfg); apply(cfg); },
|
|
598
|
+
bounds() { const b = new THREE.Box3(); for (const m of meshes) {
|
|
599
|
+
if (!m.geometry.boundingBox)
|
|
600
|
+
m.geometry.computeBoundingBox();
|
|
601
|
+
b.union(m.geometry.boundingBox);
|
|
602
|
+
} return b; },
|
|
603
|
+
update(dt) {
|
|
604
|
+
state.t += dt;
|
|
605
|
+
sigU.uPhase.value = (state.t / state.cycle) % 1;
|
|
606
|
+
// Keep the registry's world positions in step with the object's transform.
|
|
607
|
+
group.updateMatrixWorld();
|
|
608
|
+
if (!lastWorld.equals(group.matrixWorld)) {
|
|
609
|
+
lastWorld.copy(group.matrixWorld);
|
|
610
|
+
placeLamps(lamps, lampLocal, group.matrixWorld); // positions, reach and falloff follow the object's scale
|
|
611
|
+
if (lamps.length)
|
|
612
|
+
touchLamps();
|
|
613
|
+
}
|
|
614
|
+
},
|
|
615
|
+
dispose() { clear(); asphalt.dispose(); paving.dispose(); signalMat.dispose(); fixture.dispose(); island.dispose(); },
|
|
616
|
+
};
|
|
617
|
+
}
|