diff --git a/.storybook/preview.js b/.storybook/preview.js index 79516fa2..b2d56188 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -68,7 +68,7 @@ addParameters({ theme: undefined, /** - * custom sorting (adding customer properties fails) + * custom sorting (custom properties are not available) */ storySort: (a, b) => { return a[1].kind === b[1].kind ? 0 : a[1].id.localeCompare(b[1].id, { numeric: true }); diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 44d288ed..00000000 --- a/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -language: node_js -branches: - only: - - master -cache: - yarn: true - directories: - - node_modules -notifications: - email: false -node_js: - - '7.5' -before_script: - - npm prune && npm cache clean -script: - - npm run test:prod && npm run build -after_success: - - npm run deploy-docs diff --git a/src/UpdateInstance.ts b/src/UpdateInstance.ts index f2fddf1e..e7696b1e 100644 --- a/src/UpdateInstance.ts +++ b/src/UpdateInstance.ts @@ -1,9 +1,9 @@ -import { Vector3, Color3, Color4, Quaternion } from '@babylonjs/core' -import { PropertyUpdate, PropsHandler, PropChangeType } from "./PropsHandler" -import { CreatedInstance } from "./CreatedInstance" +import { Vector3, Color3, Color4, Quaternion } from '@babylonjs/core'; +import { PropertyUpdate, PropsHandler, PropChangeType } from './PropsHandler'; +import { CreatedInstance } from './CreatedInstance'; export const applyUpdateToInstance = (hostInstance: any, update: PropertyUpdate, type: string | undefined): void => { - let target = update.target !== undefined ? hostInstance[update.target] : hostInstance + let target = update.target !== undefined ? hostInstance[update.target] : hostInstance; switch (update.changeType) { case PropChangeType.Primitive: @@ -12,7 +12,7 @@ export const applyUpdateToInstance = (hostInstance: any, update: PropertyUpdate, case PropChangeType.Texture: // console.log(` > ${type}: updating ${update.changeType} on ${update.propertyName} to ${update.value}`) if (update.propertyName.indexOf('.') !== -1) { - const dotProps: string[] = update.propertyName.split('.') + const dotProps: string[] = update.propertyName.split('.'); const lastProp = dotProps.pop()!; const newTarget = dotProps.reduce((target, prop) => target[prop], target); newTarget[lastProp] = update.value; @@ -28,7 +28,7 @@ export const applyUpdateToInstance = (hostInstance: any, update: PropertyUpdate, } else { target[update.propertyName] = update.value; // ie: undefined/null? } - break + break; case PropChangeType.Color3: case PropChangeType.Color4: if (target[update.propertyName]) { @@ -41,11 +41,11 @@ export const applyUpdateToInstance = (hostInstance: any, update: PropertyUpdate, break; } } else if (update.value) { - target[update.propertyName] = update.value.clone();; + target[update.propertyName] = update.value.clone(); } else { target[update.propertyName] = update.value; } - break + break; case PropChangeType.Control: target[update.propertyName] = update.value; break; @@ -58,30 +58,30 @@ export const applyUpdateToInstance = (hostInstance: any, update: PropertyUpdate, case PropChangeType.Method: if (typeof target[update.propertyName] === "function") { if (Array.isArray(update.value)) { - target[update.propertyName](...update.value) + target[update.propertyName](...update.value); } else if (Object(update.value) !== update.value) { // primitive, undefined & null. Comparison is 7x slower than instanceof check, // TODO: should be: update.value === undefined || typeof(update.value) === 'number' || ... - target[update.propertyName](update.value) + target[update.propertyName](update.value); } else { // TODO: there is a bug here in that setTarget={new Vector3(0, 1, 0)} will throw an exception... console.error('need to make sure this isn\'t something like a Vector3 before destructuring') - target[update.propertyName](...Object.values(update.value)) + target[update.propertyName](...Object.values(update.value)); } } else { - console.error(`Cannot call [not a function] ${update.propertyName}(...) on:`, target) + console.error(`Cannot call [not a function] ${update.propertyName}(...) on:`, target); } break; case PropChangeType.Quaternion: - console.warn(`quaternion update detected ${update.propertyName} to:`, update.value) - if (target[update.propertyName]) { - (target[update.propertyName] as Quaternion).copyFrom(update.value); - } else if (update.value) { - target[update.propertyName] = (update.value as Quaternion).clone(); - } else { - target[update.propertyName] = update.value; // ie: undefined/null? - } - break + // console.warn(`quaternion update detected ${update.propertyName} to:`, update.value) + if (target[update.propertyName]) { + (target[update.propertyName] as Quaternion).copyFrom(update.value); + } else if (update.value) { + target[update.propertyName] = (update.value as Quaternion).clone(); + } else { + target[update.propertyName] = update.value; // ie: undefined/null? + } + break; default: console.error(`Unhandled property update of type '${update.changeType}'`); break; @@ -108,15 +108,15 @@ export const applyInitialPropsToInstance = (instance: CreatedInstance, prop let handlerUpdates: PropertyUpdate[] | null = propHandler.getPropertyUpdates( {}, // Here we will reapply things like 'name', so we could get default props from 'babylonObject'. props - ) + ); if (handlerUpdates !== null) { - initPayload.push(...handlerUpdates) + initPayload.push(...handlerUpdates); } }) if (initPayload.length > 0) { initPayload.forEach(update => { - applyUpdateToInstance(instance.hostInstance, update, instance.metadata!.className) + applyUpdateToInstance(instance.hostInstance, update, instance.metadata!.className); }) } } diff --git a/src/generatedCode.ts b/src/generatedCode.ts index 7b1ef96f..7a0f727c 100644 --- a/src/generatedCode.ts +++ b/src/generatedCode.ts @@ -1,6 +1,6 @@ import { PropsHandler, PropertyUpdate, HasPropsHandlers, checkColor3Diff, checkColor4Diff, checkControlDiff, checkFresnelParametersDiff, checkLambdaDiff, checkMethodDiff, checkNumericArrayDiff, checkObjectDiff, checkObservableDiff, checkPrimitiveDiff, checkQuaternionDiff, checkTextureDiff, checkVector3Diff } from "./PropsHandler"; import { CreatedInstanceMetadata } from "./CreatedInstance"; -import { FiberNodeProps, FiberTransformNodeProps, FiberAbstractMeshProps, FiberInstancedMeshProps, FiberInstancedLinesMeshProps, FiberMeshProps, FiberLinesMeshProps, FiberGroundMeshProps, FiberTrailMeshProps, FiberCameraProps, FiberTargetCameraProps, FiberFreeCameraProps, FiberTouchCameraProps, FiberUniversalCameraProps, FiberGamepadCameraProps, FiberAnaglyphGamepadCameraProps, FiberStereoscopicGamepadCameraProps, FiberAnaglyphUniversalCameraProps, FiberStereoscopicUniversalCameraProps, FiberDeviceOrientationCameraProps, FiberVRDeviceOrientationFreeCameraProps, FiberVRDeviceOrientationGamepadCameraProps, FiberAnaglyphFreeCameraProps, FiberStereoscopicFreeCameraProps, FiberVirtualJoysticksCameraProps, FiberWebVRFreeCameraProps, FiberWebXRCameraProps, FiberArcRotateCameraProps, FiberAnaglyphArcRotateCameraProps, FiberStereoscopicArcRotateCameraProps, FiberVRDeviceOrientationArcRotateCameraProps, FiberFlyCameraProps, FiberFollowCameraProps, FiberArcFollowCameraProps, FiberMaterialProps, FiberShaderMaterialProps, FiberMultiMaterialProps, FiberPushMaterialProps, FiberStandardMaterialProps, FiberBackgroundMaterialProps, FiberPBRBaseMaterialProps, FiberPBRBaseSimpleMaterialProps, FiberPBRMetallicRoughnessMaterialProps, FiberPBRSpecularGlossinessMaterialProps, FiberPBRMaterialProps, FiberNodeMaterialProps, FiberFluentMaterialProps, FiberLightProps, FiberShadowLightProps, FiberDirectionalLightProps, FiberPointLightProps, FiberSpotLightProps, FiberHemisphericLightProps, FiberControlProps, FiberContainerProps, FiberRectangleProps, FiberButtonProps, FiberSelectionPanelProps, FiberScrollViewerProps, FiberStackPanelProps, FiberVirtualKeyboardProps, FiberEllipseProps, FiberGridProps, Fiber_ScrollViewerWindowProps, FiberTextBlockProps, FiberImageProps, FiberCheckboxProps, FiberColorPickerProps, FiberInputTextProps, FiberInputPasswordProps, FiberLineProps, FiberMultiLineProps, FiberRadioButtonProps, FiberBaseSliderProps, FiberScrollBarProps, FiberImageScrollBarProps, FiberSliderProps, FiberImageBasedSliderProps, FiberDisplayGridProps, FiberControl3DProps, FiberContainer3DProps, FiberVolumeBasedPanelProps, FiberCylinderPanelProps, FiberPlanePanelProps, FiberScatterPanelProps, FiberSpherePanelProps, FiberStackPanel3DProps, FiberAbstractButton3DProps, FiberButton3DProps, FiberHolographicButtonProps, FiberMeshButton3DProps, FiberEffectLayerProps, FiberGlowLayerProps, FiberHighlightLayerProps, FiberBaseTextureProps, FiberCubeTextureProps, FiberRawCubeTextureProps, FiberTextureProps, FiberRawTextureProps, FiberProceduralTextureProps, FiberCustomProceduralTextureProps, FiberNoiseProceduralTextureProps, FiberRenderTargetTextureProps, FiberMirrorTextureProps, FiberMultiRenderTargetProps, FiberRefractionTextureProps, FiberMultiviewRenderTargetProps, FiberVideoTextureProps, FiberDynamicTextureProps, FiberAdvancedDynamicTextureProps, FiberRawTexture3DProps, FiberRawTexture2DArrayProps, FiberColorGradingTextureProps, FiberEquiRectangularCubeTextureProps, FiberHDRCubeTextureProps, FiberHtmlElementTextureProps, FiberGUI3DManagerProps, FiberShadowGeneratorProps, FiberCascadedShadowGeneratorProps, FiberEnvironmentHelperProps, FiberPhysicsImpostorProps, FiberVRExperienceHelperProps, FiberDynamicTerrainProps, FiberAutoRotationBehaviorProps, FiberBouncingBehaviorProps, FiberFramingBehaviorProps, FiberAttachToBoxBehaviorProps, FiberFadeInOutBehaviorProps, FiberMultiPointerScaleBehaviorProps, FiberPointerDragBehaviorProps, FiberSixDofDragBehaviorProps, FiberSceneProps } from "./generatedProps"; +import { FiberNodeProps, FiberTransformNodeProps, FiberAbstractMeshProps, FiberInstancedMeshProps, FiberInstancedLinesMeshProps, FiberMeshProps, FiberLinesMeshProps, FiberGroundMeshProps, FiberTrailMeshProps, FiberCameraProps, FiberTargetCameraProps, FiberFreeCameraProps, FiberTouchCameraProps, FiberUniversalCameraProps, FiberGamepadCameraProps, FiberAnaglyphGamepadCameraProps, FiberStereoscopicGamepadCameraProps, FiberAnaglyphUniversalCameraProps, FiberStereoscopicUniversalCameraProps, FiberDeviceOrientationCameraProps, FiberVRDeviceOrientationFreeCameraProps, FiberVRDeviceOrientationGamepadCameraProps, FiberAnaglyphFreeCameraProps, FiberStereoscopicFreeCameraProps, FiberVirtualJoysticksCameraProps, FiberWebVRFreeCameraProps, FiberWebXRCameraProps, FiberArcRotateCameraProps, FiberAnaglyphArcRotateCameraProps, FiberStereoscopicArcRotateCameraProps, FiberVRDeviceOrientationArcRotateCameraProps, FiberFlyCameraProps, FiberFollowCameraProps, FiberArcFollowCameraProps, FiberMaterialProps, FiberShaderMaterialProps, FiberMultiMaterialProps, FiberPushMaterialProps, FiberStandardMaterialProps, FiberBackgroundMaterialProps, FiberPBRBaseMaterialProps, FiberPBRBaseSimpleMaterialProps, FiberPBRMetallicRoughnessMaterialProps, FiberPBRSpecularGlossinessMaterialProps, FiberPBRMaterialProps, FiberNodeMaterialProps, FiberFluentMaterialProps, FiberLightProps, FiberShadowLightProps, FiberDirectionalLightProps, FiberPointLightProps, FiberSpotLightProps, FiberHemisphericLightProps, FiberControlProps, FiberContainerProps, FiberRectangleProps, FiberButtonProps, FiberSelectionPanelProps, FiberScrollViewerProps, FiberStackPanelProps, FiberVirtualKeyboardProps, FiberEllipseProps, FiberGridProps, Fiber_ScrollViewerWindowProps, FiberTextBlockProps, FiberImageProps, FiberCheckboxProps, FiberColorPickerProps, FiberInputTextProps, FiberInputPasswordProps, FiberLineProps, FiberMultiLineProps, FiberRadioButtonProps, FiberBaseSliderProps, FiberScrollBarProps, FiberImageScrollBarProps, FiberSliderProps, FiberImageBasedSliderProps, FiberDisplayGridProps, FiberControl3DProps, FiberContainer3DProps, FiberVolumeBasedPanelProps, FiberCylinderPanelProps, FiberPlanePanelProps, FiberScatterPanelProps, FiberSpherePanelProps, FiberStackPanel3DProps, FiberAbstractButton3DProps, FiberButton3DProps, FiberHolographicButtonProps, FiberMeshButton3DProps, FiberEffectLayerProps, FiberGlowLayerProps, FiberHighlightLayerProps, FiberBaseTextureProps, FiberCubeTextureProps, FiberRawCubeTextureProps, FiberTextureProps, FiberRawTextureProps, FiberProceduralTextureProps, FiberCustomProceduralTextureProps, FiberNoiseProceduralTextureProps, FiberRenderTargetTextureProps, FiberMirrorTextureProps, FiberMultiRenderTargetProps, FiberRefractionTextureProps, FiberMultiviewRenderTargetProps, FiberVideoTextureProps, FiberDynamicTextureProps, FiberAdvancedDynamicTextureProps, FiberRawTexture3DProps, FiberRawTexture2DArrayProps, FiberColorGradingTextureProps, FiberEquiRectangularCubeTextureProps, FiberHDRCubeTextureProps, FiberHtmlElementTextureProps, FiberGUI3DManagerProps, FiberShadowGeneratorProps, FiberCascadedShadowGeneratorProps, FiberEnvironmentHelperProps, FiberPhysicsImpostorProps, FiberVRExperienceHelperProps, FiberDynamicTerrainProps, FiberPointsCloudSystemProps, FiberAutoRotationBehaviorProps, FiberBouncingBehaviorProps, FiberFramingBehaviorProps, FiberAttachToBoxBehaviorProps, FiberFadeInOutBehaviorProps, FiberMultiPointerScaleBehaviorProps, FiberPointerDragBehaviorProps, FiberSixDofDragBehaviorProps, FiberSceneProps } from "./generatedProps"; import { DynamicTerrain as ExtensionsDynamicTerrain } from "./extensions/DynamicTerrain"; import { AbstractScene as BabylonjsCoreAbstractScene } from "@babylonjs/core/abstractScene"; import { Scene as BabylonjsCoreScene } from "@babylonjs/core/scene"; @@ -22,7 +22,7 @@ import { TransformNode as BabylonjsCoreTransformNode } from "@babylonjs/core/Mes import { AssetTaskState as BabylonjsCoreAssetTaskState } from "@babylonjs/core/Misc/assetsManager"; import { InspectableType as BabylonjsCoreInspectableType, IInspectable as BabylonjsCoreIInspectable } from "@babylonjs/core/Misc/iInspectable"; import { JoystickAxis as BabylonjsCoreJoystickAxis } from "@babylonjs/core/Misc/virtualJoystick"; -import { PointColor as BabylonjsCorePointColor } from "@babylonjs/core/Particles/pointsCloudSystem"; +import { PointsCloudSystem as BabylonjsCorePointsCloudSystem, PointColor as BabylonjsCorePointColor } from "@babylonjs/core/Particles/pointsCloudSystem"; import { SubEmitterType as BabylonjsCoreSubEmitterType } from "@babylonjs/core/Particles/subEmitter"; import { PhysicsRadialImpulseFalloff as BabylonjsCorePhysicsRadialImpulseFalloff, PhysicsUpdraftMode as BabylonjsCorePhysicsUpdraftMode } from "@babylonjs/core/Physics/physicsHelper"; import { PhysicsImpostor as BabylonjsCorePhysicsImpostor, IPhysicsEnabledObject as BabylonjsCoreIPhysicsEnabledObject, PhysicsImpostorParameters as BabylonjsCorePhysicsImpostorParameters } from "@babylonjs/core/Physics/physicsImpostor"; @@ -200,6 +200,7 @@ import { PhysicsJoint as BabylonjsCorePhysicsJoint } from "@babylonjs/core/Physi import { PickingInfo as BabylonjsCorePickingInfo } from "@babylonjs/core/Collisions/pickingInfo"; import { WebXRDefaultExperience as BabylonjsCoreWebXRDefaultExperience } from "@babylonjs/core/XR/webXRDefaultExperience"; import { SolidParticleSystem as BabylonjsCoreSolidParticleSystem } from "@babylonjs/core/Particles/solidParticleSystem"; +import { CloudPoint as BabylonjsCoreCloudPoint } from "@babylonjs/core/Particles/cloudPoint"; import { IPhysicsEnginePlugin as BabylonjsCoreIPhysicsEnginePlugin } from "@babylonjs/core/Physics/IPhysicsEngine"; import { Collider as BabylonjsCoreCollider } from "@babylonjs/core/Collisions/collider"; import { Ray as BabylonjsCoreRay } from "@babylonjs/core/Culling/ray"; @@ -12231,6 +12232,95 @@ export class FiberDynamicTerrain implements HasPropsHandlers { + getPropertyUpdates(oldProps: FiberPointsCloudSystemProps, newProps: FiberPointsCloudSystemProps): PropertyUpdate[] | null { + const changedProps: PropertyUpdate[] = [] + checkPrimitiveDiff(oldProps.computeBoundingBox, newProps.computeBoundingBox, 'computeBoundingBox', changedProps) + checkPrimitiveDiff(oldProps.computeParticleColor, newProps.computeParticleColor, 'computeParticleColor', changedProps) + checkPrimitiveDiff(oldProps.computeParticleRotation, newProps.computeParticleRotation, 'computeParticleRotation', changedProps) + checkPrimitiveDiff(oldProps.computeParticleTexture, newProps.computeParticleTexture, 'computeParticleTexture', changedProps) + checkPrimitiveDiff(oldProps.counter, newProps.counter, 'counter', changedProps) + checkPrimitiveDiff(oldProps.isAlwaysVisible, newProps.isAlwaysVisible, 'isAlwaysVisible', changedProps) + // type: 'BabylonjsCoreMesh' property (not coded) BabylonjsCorePointsCloudSystem.mesh. + checkPrimitiveDiff(oldProps.name, newProps.name, 'name', changedProps) + checkPrimitiveDiff(oldProps.nbParticles, newProps.nbParticles, 'nbParticles', changedProps) + // type: 'BabylonjsCoreCloudPoint[]' property (not coded) BabylonjsCorePointsCloudSystem.particles. + // type: 'any' property (not coded) BabylonjsCorePointsCloudSystem.vars. + checkMethodDiff(oldProps.addPoints, newProps.addPoints, 'addPoints', changedProps) + checkMethodDiff(oldProps.addSurfacePoints, newProps.addSurfacePoints, 'addSurfacePoints', changedProps) + checkMethodDiff(oldProps.addVolumePoints, newProps.addVolumePoints, 'addVolumePoints', changedProps) + checkMethodDiff(oldProps.setParticles, newProps.setParticles, 'setParticles', changedProps) + checkMethodDiff(oldProps.setVisibilityBox, newProps.setVisibilityBox, 'setVisibilityBox', changedProps) + return changedProps.length === 0 ? null : changedProps; + } +} + +/** + * The PointCloudSystem (PCS) is a single updatable mesh. The points corresponding to the vertices of this big mesh. + * As it is just a mesh, the PointCloudSystem has all the same properties as any other BJS mesh : not more, not less. It can be scaled, rotated, translated, enlighted, textured, moved, etc. + * + * The PointCloudSytem is also a particle system, with each point being a particle. It provides some methods to manage the particles. + * However it is behavior agnostic. This means it has no emitter, no particle physics, no particle recycler. You have to implement your own behavior. + * + * Full documentation here : TO BE ENTERED + * + * This code has been generated + */ +export class FiberPointsCloudSystem implements HasPropsHandlers { + private propsHandlers: PropsHandler[]; + + constructor() { + this.propsHandlers = [ + new FiberPointsCloudSystemPropsHandler() + ]; + } + + getPropsHandlers(): PropsHandler[] { + return this.propsHandlers; + } + + addPropsHandler(propHandler: PropsHandler): void { + this.propsHandlers.push(propHandler); + } + + public static readonly CreateInfo = { + "creationType": "Constructor", + "libraryLocation": "PointsCloudSystem", + "namespace": "@babylonjs/core", + "parameters": [ + { + "name": "name", + "type": "string", + "optional": false + }, + { + "name": "pointSize", + "type": "number", + "optional": false + }, + { + "name": "scene", + "type": "BabylonjsCoreScene", + "optional": false + }, + { + "name": "options", + "type": [ + { + "name": "updatable", + "type": "boolean", + "optional": true + } + ], + "optional": true + } + ] + }; + public static readonly Metadata: CreatedInstanceMetadata = { + "className": "FiberPointsCloudSystem" + }; +} + export class FiberAutoRotationBehaviorPropsHandler implements PropsHandler { getPropertyUpdates(oldProps: FiberAutoRotationBehaviorProps, newProps: FiberAutoRotationBehaviorProps): PropertyUpdate[] | null { const changedProps: PropertyUpdate[] = [] @@ -12804,7 +12894,7 @@ export class FiberScenePropsHandler implements PropsHandler { } } -export const ADTForMesh: string = 'ADTForMesh', ADTFullscreenUI: string = 'ADTFullscreenUI', AbstractButton3D: string = 'AbstractButton3D', AbstractMesh: string = 'AbstractMesh', AdvancedDynamicTexture: string = 'AdvancedDynamicTexture', AnaglyphArcRotateCamera: string = 'AnaglyphArcRotateCamera', AnaglyphFreeCamera: string = 'AnaglyphFreeCamera', AnaglyphGamepadCamera: string = 'AnaglyphGamepadCamera', AnaglyphUniversalCamera: string = 'AnaglyphUniversalCamera', ArcFollowCamera: string = 'ArcFollowCamera', ArcRotateCamera: string = 'ArcRotateCamera', AttachToBoxBehavior: string = 'AttachToBoxBehavior', AutoRotationBehavior: string = 'AutoRotationBehavior', BackgroundMaterial: string = 'BackgroundMaterial', BaseSlider: string = 'BaseSlider', BaseTexture: string = 'BaseTexture', BouncingBehavior: string = 'BouncingBehavior', Box: string = 'Box', Button: string = 'Button', Button3D: string = 'Button3D', Camera: string = 'Camera', CascadedShadowGenerator: string = 'CascadedShadowGenerator', Checkbox: string = 'Checkbox', ColorGradingTexture: string = 'ColorGradingTexture', ColorPicker: string = 'ColorPicker', Container: string = 'Container', Container3D: string = 'Container3D', Control: string = 'Control', Control3D: string = 'Control3D', CubeTexture: string = 'CubeTexture', CustomProceduralTexture: string = 'CustomProceduralTexture', Cylinder: string = 'Cylinder', CylinderPanel: string = 'CylinderPanel', DashedLines: string = 'DashedLines', Decal: string = 'Decal', DeviceOrientationCamera: string = 'DeviceOrientationCamera', DirectionalLight: string = 'DirectionalLight', Disc: string = 'Disc', DisplayGrid: string = 'DisplayGrid', DynamicTerrain: string = 'DynamicTerrain', DynamicTexture: string = 'DynamicTexture', EffectLayer: string = 'EffectLayer', Ellipse: string = 'Ellipse', EnvironmentHelper: string = 'EnvironmentHelper', EquiRectangularCubeTexture: string = 'EquiRectangularCubeTexture', ExtrudePolygon: string = 'ExtrudePolygon', ExtrudeShape: string = 'ExtrudeShape', ExtrudeShapeCustom: string = 'ExtrudeShapeCustom', FadeInOutBehavior: string = 'FadeInOutBehavior', FluentMaterial: string = 'FluentMaterial', FlyCamera: string = 'FlyCamera', FollowCamera: string = 'FollowCamera', FramingBehavior: string = 'FramingBehavior', FreeCamera: string = 'FreeCamera', GUI3DManager: string = 'GUI3DManager', GamepadCamera: string = 'GamepadCamera', GlowLayer: string = 'GlowLayer', Grid: string = 'Grid', Ground: string = 'Ground', GroundFromHeightMap: string = 'GroundFromHeightMap', GroundMesh: string = 'GroundMesh', HDRCubeTexture: string = 'HDRCubeTexture', HemisphericLight: string = 'HemisphericLight', HighlightLayer: string = 'HighlightLayer', HolographicButton: string = 'HolographicButton', HtmlElementTexture: string = 'HtmlElementTexture', IcoSphere: string = 'IcoSphere', Image: string = 'Image', ImageBasedSlider: string = 'ImageBasedSlider', ImageScrollBar: string = 'ImageScrollBar', InputPassword: string = 'InputPassword', InputText: string = 'InputText', InstancedLinesMesh: string = 'InstancedLinesMesh', InstancedMesh: string = 'InstancedMesh', Lathe: string = 'Lathe', Light: string = 'Light', Line: string = 'Line', LineSystem: string = 'LineSystem', Lines: string = 'Lines', LinesMesh: string = 'LinesMesh', Material: string = 'Material', Mesh: string = 'Mesh', MeshButton3D: string = 'MeshButton3D', MirrorTexture: string = 'MirrorTexture', Model: string = 'Model', MultiLine: string = 'MultiLine', MultiMaterial: string = 'MultiMaterial', MultiPointerScaleBehavior: string = 'MultiPointerScaleBehavior', MultiRenderTarget: string = 'MultiRenderTarget', MultiviewRenderTarget: string = 'MultiviewRenderTarget', Node: string = 'Node', NodeMaterial: string = 'NodeMaterial', NoiseProceduralTexture: string = 'NoiseProceduralTexture', PBRBaseMaterial: string = 'PBRBaseMaterial', PBRBaseSimpleMaterial: string = 'PBRBaseSimpleMaterial', PBRMaterial: string = 'PBRMaterial', PBRMetallicRoughnessMaterial: string = 'PBRMetallicRoughnessMaterial', PBRSpecularGlossinessMaterial: string = 'PBRSpecularGlossinessMaterial', PhysicsImpostor: string = 'PhysicsImpostor', Plane: string = 'Plane', PlanePanel: string = 'PlanePanel', PointLight: string = 'PointLight', PointerDragBehavior: string = 'PointerDragBehavior', Polygon: string = 'Polygon', Polyhedron: string = 'Polyhedron', ProceduralTexture: string = 'ProceduralTexture', PushMaterial: string = 'PushMaterial', RadioButton: string = 'RadioButton', RawCubeTexture: string = 'RawCubeTexture', RawTexture: string = 'RawTexture', RawTexture2DArray: string = 'RawTexture2DArray', RawTexture3D: string = 'RawTexture3D', Rectangle: string = 'Rectangle', RefractionTexture: string = 'RefractionTexture', RenderTargetTexture: string = 'RenderTargetTexture', Ribbon: string = 'Ribbon', ScatterPanel: string = 'ScatterPanel', ScrollBar: string = 'ScrollBar', ScrollViewer: string = 'ScrollViewer', SelectionPanel: string = 'SelectionPanel', ShaderMaterial: string = 'ShaderMaterial', ShadowGenerator: string = 'ShadowGenerator', ShadowLight: string = 'ShadowLight', SixDofDragBehavior: string = 'SixDofDragBehavior', Slider: string = 'Slider', Sphere: string = 'Sphere', SpherePanel: string = 'SpherePanel', SpotLight: string = 'SpotLight', StackPanel: string = 'StackPanel', StackPanel3D: string = 'StackPanel3D', StandardMaterial: string = 'StandardMaterial', StereoscopicArcRotateCamera: string = 'StereoscopicArcRotateCamera', StereoscopicFreeCamera: string = 'StereoscopicFreeCamera', StereoscopicGamepadCamera: string = 'StereoscopicGamepadCamera', StereoscopicUniversalCamera: string = 'StereoscopicUniversalCamera', TargetCamera: string = 'TargetCamera', TextBlock: string = 'TextBlock', Texture: string = 'Texture', TiledBox: string = 'TiledBox', TiledGround: string = 'TiledGround', TiledPlane: string = 'TiledPlane', Torus: string = 'Torus', TorusKnot: string = 'TorusKnot', TouchCamera: string = 'TouchCamera', TrailMesh: string = 'TrailMesh', TransformNode: string = 'TransformNode', Tube: string = 'Tube', UniversalCamera: string = 'UniversalCamera', VRDeviceOrientationArcRotateCamera: string = 'VRDeviceOrientationArcRotateCamera', VRDeviceOrientationFreeCamera: string = 'VRDeviceOrientationFreeCamera', VRDeviceOrientationGamepadCamera: string = 'VRDeviceOrientationGamepadCamera', VRExperienceHelper: string = 'VRExperienceHelper', VideoTexture: string = 'VideoTexture', VirtualJoysticksCamera: string = 'VirtualJoysticksCamera', VirtualKeyboard: string = 'VirtualKeyboard', VolumeBasedPanel: string = 'VolumeBasedPanel', WebVRFreeCamera: string = 'WebVRFreeCamera', WebXRCamera: string = 'WebXRCamera', _ScrollViewerWindow: string = '_ScrollViewerWindow'; +export const ADTForMesh: string = 'ADTForMesh', ADTFullscreenUI: string = 'ADTFullscreenUI', AbstractButton3D: string = 'AbstractButton3D', AbstractMesh: string = 'AbstractMesh', AdvancedDynamicTexture: string = 'AdvancedDynamicTexture', AnaglyphArcRotateCamera: string = 'AnaglyphArcRotateCamera', AnaglyphFreeCamera: string = 'AnaglyphFreeCamera', AnaglyphGamepadCamera: string = 'AnaglyphGamepadCamera', AnaglyphUniversalCamera: string = 'AnaglyphUniversalCamera', ArcFollowCamera: string = 'ArcFollowCamera', ArcRotateCamera: string = 'ArcRotateCamera', AttachToBoxBehavior: string = 'AttachToBoxBehavior', AutoRotationBehavior: string = 'AutoRotationBehavior', BackgroundMaterial: string = 'BackgroundMaterial', BaseSlider: string = 'BaseSlider', BaseTexture: string = 'BaseTexture', BouncingBehavior: string = 'BouncingBehavior', Box: string = 'Box', Button: string = 'Button', Button3D: string = 'Button3D', Camera: string = 'Camera', CascadedShadowGenerator: string = 'CascadedShadowGenerator', Checkbox: string = 'Checkbox', ColorGradingTexture: string = 'ColorGradingTexture', ColorPicker: string = 'ColorPicker', Container: string = 'Container', Container3D: string = 'Container3D', Control: string = 'Control', Control3D: string = 'Control3D', CubeTexture: string = 'CubeTexture', CustomProceduralTexture: string = 'CustomProceduralTexture', Cylinder: string = 'Cylinder', CylinderPanel: string = 'CylinderPanel', DashedLines: string = 'DashedLines', Decal: string = 'Decal', DeviceOrientationCamera: string = 'DeviceOrientationCamera', DirectionalLight: string = 'DirectionalLight', Disc: string = 'Disc', DisplayGrid: string = 'DisplayGrid', DynamicTerrain: string = 'DynamicTerrain', DynamicTexture: string = 'DynamicTexture', EffectLayer: string = 'EffectLayer', Ellipse: string = 'Ellipse', EnvironmentHelper: string = 'EnvironmentHelper', EquiRectangularCubeTexture: string = 'EquiRectangularCubeTexture', ExtrudePolygon: string = 'ExtrudePolygon', ExtrudeShape: string = 'ExtrudeShape', ExtrudeShapeCustom: string = 'ExtrudeShapeCustom', FadeInOutBehavior: string = 'FadeInOutBehavior', FluentMaterial: string = 'FluentMaterial', FlyCamera: string = 'FlyCamera', FollowCamera: string = 'FollowCamera', FramingBehavior: string = 'FramingBehavior', FreeCamera: string = 'FreeCamera', GUI3DManager: string = 'GUI3DManager', GamepadCamera: string = 'GamepadCamera', GlowLayer: string = 'GlowLayer', Grid: string = 'Grid', Ground: string = 'Ground', GroundFromHeightMap: string = 'GroundFromHeightMap', GroundMesh: string = 'GroundMesh', HDRCubeTexture: string = 'HDRCubeTexture', HemisphericLight: string = 'HemisphericLight', HighlightLayer: string = 'HighlightLayer', HolographicButton: string = 'HolographicButton', HtmlElementTexture: string = 'HtmlElementTexture', IcoSphere: string = 'IcoSphere', Image: string = 'Image', ImageBasedSlider: string = 'ImageBasedSlider', ImageScrollBar: string = 'ImageScrollBar', InputPassword: string = 'InputPassword', InputText: string = 'InputText', InstancedLinesMesh: string = 'InstancedLinesMesh', InstancedMesh: string = 'InstancedMesh', Lathe: string = 'Lathe', Light: string = 'Light', Line: string = 'Line', LineSystem: string = 'LineSystem', Lines: string = 'Lines', LinesMesh: string = 'LinesMesh', Material: string = 'Material', Mesh: string = 'Mesh', MeshButton3D: string = 'MeshButton3D', MirrorTexture: string = 'MirrorTexture', Model: string = 'Model', MultiLine: string = 'MultiLine', MultiMaterial: string = 'MultiMaterial', MultiPointerScaleBehavior: string = 'MultiPointerScaleBehavior', MultiRenderTarget: string = 'MultiRenderTarget', MultiviewRenderTarget: string = 'MultiviewRenderTarget', Node: string = 'Node', NodeMaterial: string = 'NodeMaterial', NoiseProceduralTexture: string = 'NoiseProceduralTexture', PBRBaseMaterial: string = 'PBRBaseMaterial', PBRBaseSimpleMaterial: string = 'PBRBaseSimpleMaterial', PBRMaterial: string = 'PBRMaterial', PBRMetallicRoughnessMaterial: string = 'PBRMetallicRoughnessMaterial', PBRSpecularGlossinessMaterial: string = 'PBRSpecularGlossinessMaterial', PhysicsImpostor: string = 'PhysicsImpostor', Plane: string = 'Plane', PlanePanel: string = 'PlanePanel', PointLight: string = 'PointLight', PointerDragBehavior: string = 'PointerDragBehavior', PointsCloudSystem: string = 'PointsCloudSystem', Polygon: string = 'Polygon', Polyhedron: string = 'Polyhedron', ProceduralTexture: string = 'ProceduralTexture', PushMaterial: string = 'PushMaterial', RadioButton: string = 'RadioButton', RawCubeTexture: string = 'RawCubeTexture', RawTexture: string = 'RawTexture', RawTexture2DArray: string = 'RawTexture2DArray', RawTexture3D: string = 'RawTexture3D', Rectangle: string = 'Rectangle', RefractionTexture: string = 'RefractionTexture', RenderTargetTexture: string = 'RenderTargetTexture', Ribbon: string = 'Ribbon', ScatterPanel: string = 'ScatterPanel', ScrollBar: string = 'ScrollBar', ScrollViewer: string = 'ScrollViewer', SelectionPanel: string = 'SelectionPanel', ShaderMaterial: string = 'ShaderMaterial', ShadowGenerator: string = 'ShadowGenerator', ShadowLight: string = 'ShadowLight', SixDofDragBehavior: string = 'SixDofDragBehavior', Slider: string = 'Slider', Sphere: string = 'Sphere', SpherePanel: string = 'SpherePanel', SpotLight: string = 'SpotLight', StackPanel: string = 'StackPanel', StackPanel3D: string = 'StackPanel3D', StandardMaterial: string = 'StandardMaterial', StereoscopicArcRotateCamera: string = 'StereoscopicArcRotateCamera', StereoscopicFreeCamera: string = 'StereoscopicFreeCamera', StereoscopicGamepadCamera: string = 'StereoscopicGamepadCamera', StereoscopicUniversalCamera: string = 'StereoscopicUniversalCamera', TargetCamera: string = 'TargetCamera', TextBlock: string = 'TextBlock', Texture: string = 'Texture', TiledBox: string = 'TiledBox', TiledGround: string = 'TiledGround', TiledPlane: string = 'TiledPlane', Torus: string = 'Torus', TorusKnot: string = 'TorusKnot', TouchCamera: string = 'TouchCamera', TrailMesh: string = 'TrailMesh', TransformNode: string = 'TransformNode', Tube: string = 'Tube', UniversalCamera: string = 'UniversalCamera', VRDeviceOrientationArcRotateCamera: string = 'VRDeviceOrientationArcRotateCamera', VRDeviceOrientationFreeCamera: string = 'VRDeviceOrientationFreeCamera', VRDeviceOrientationGamepadCamera: string = 'VRDeviceOrientationGamepadCamera', VRExperienceHelper: string = 'VRExperienceHelper', VideoTexture: string = 'VideoTexture', VirtualJoysticksCamera: string = 'VirtualJoysticksCamera', VirtualKeyboard: string = 'VirtualKeyboard', VolumeBasedPanel: string = 'VolumeBasedPanel', WebVRFreeCamera: string = 'WebVRFreeCamera', WebXRCamera: string = 'WebXRCamera', _ScrollViewerWindow: string = '_ScrollViewerWindow'; const classesMap: object = { dynamicTerrain: ExtensionsDynamicTerrain, DynamicTerrain: ExtensionsDynamicTerrain, abstractScene: BabylonjsCoreAbstractScene, AbstractScene: BabylonjsCoreAbstractScene, @@ -12818,6 +12908,7 @@ const classesMap: object = { mesh: BabylonjsCoreMesh, Mesh: BabylonjsCoreMesh, meshBuilder: BabylonjsCoreMeshBuilder, MeshBuilder: BabylonjsCoreMeshBuilder, transformNode: BabylonjsCoreTransformNode, TransformNode: BabylonjsCoreTransformNode, + pointsCloudSystem: BabylonjsCorePointsCloudSystem, PointsCloudSystem: BabylonjsCorePointsCloudSystem, physicsImpostor: BabylonjsCorePhysicsImpostor, PhysicsImpostor: BabylonjsCorePhysicsImpostor, advancedDynamicTexture: BabylonjsGuiAdvancedDynamicTexture, AdvancedDynamicTexture: BabylonjsGuiAdvancedDynamicTexture, gui3DManager: BabylonjsGuiGUI3DManager, GUI3DManager: BabylonjsGuiGUI3DManager, @@ -12954,6 +13045,7 @@ export const intrinsicClassMap: object = { mesh: 'Mesh', meshBuilder: 'MeshBuilder', transformNode: 'TransformNode', + pointsCloudSystem: 'PointsCloudSystem', physicsImpostor: 'PhysicsImpostor', advancedDynamicTexture: 'AdvancedDynamicTexture', gui3DManager: 'GUI3DManager', diff --git a/src/generatedProps.ts b/src/generatedProps.ts index 926fcb49..f2983317 100644 --- a/src/generatedProps.ts +++ b/src/generatedProps.ts @@ -22,7 +22,7 @@ import { TransformNode as BabylonjsCoreTransformNode } from "@babylonjs/core/Mes import { AssetTaskState as BabylonjsCoreAssetTaskState } from "@babylonjs/core/Misc/assetsManager"; import { InspectableType as BabylonjsCoreInspectableType, IInspectable as BabylonjsCoreIInspectable } from "@babylonjs/core/Misc/iInspectable"; import { JoystickAxis as BabylonjsCoreJoystickAxis } from "@babylonjs/core/Misc/virtualJoystick"; -import { PointColor as BabylonjsCorePointColor } from "@babylonjs/core/Particles/pointsCloudSystem"; +import { PointsCloudSystem as BabylonjsCorePointsCloudSystem, PointColor as BabylonjsCorePointColor } from "@babylonjs/core/Particles/pointsCloudSystem"; import { SubEmitterType as BabylonjsCoreSubEmitterType } from "@babylonjs/core/Particles/subEmitter"; import { PhysicsRadialImpulseFalloff as BabylonjsCorePhysicsRadialImpulseFalloff, PhysicsUpdraftMode as BabylonjsCorePhysicsUpdraftMode } from "@babylonjs/core/Physics/physicsHelper"; import { PhysicsImpostor as BabylonjsCorePhysicsImpostor, IPhysicsEnabledObject as BabylonjsCoreIPhysicsEnabledObject, PhysicsImpostorParameters as BabylonjsCorePhysicsImpostorParameters } from "@babylonjs/core/Physics/physicsImpostor"; @@ -200,6 +200,7 @@ import { PhysicsJoint as BabylonjsCorePhysicsJoint } from "@babylonjs/core/Physi import { PickingInfo as BabylonjsCorePickingInfo } from "@babylonjs/core/Collisions/pickingInfo"; import { WebXRDefaultExperience as BabylonjsCoreWebXRDefaultExperience } from "@babylonjs/core/XR/webXRDefaultExperience"; import { SolidParticleSystem as BabylonjsCoreSolidParticleSystem } from "@babylonjs/core/Particles/solidParticleSystem"; +import { CloudPoint as BabylonjsCoreCloudPoint } from "@babylonjs/core/Particles/cloudPoint"; import { IPhysicsEnginePlugin as BabylonjsCoreIPhysicsEnginePlugin } from "@babylonjs/core/Physics/IPhysicsEngine"; import { Collider as BabylonjsCoreCollider } from "@babylonjs/core/Collisions/collider"; import { Ray as BabylonjsCoreRay } from "@babylonjs/core/Culling/ray"; @@ -372,6 +373,7 @@ declare global { physicsImpostor: FiberPhysicsImpostorProps & FiberPhysicsImpostorPropsCtor & BabylonNode; vrExperienceHelper: FiberVRExperienceHelperProps & FiberVRExperienceHelperPropsCtor & BabylonNode; dynamicTerrain: FiberDynamicTerrainProps & FiberDynamicTerrainPropsCtor & BabylonNode; + pointsCloudSystem: FiberPointsCloudSystemProps & FiberPointsCloudSystemPropsCtor & BabylonNode; autoRotationBehavior: FiberAutoRotationBehaviorProps & FiberAutoRotationBehaviorPropsCtor & BabylonNode; bouncingBehavior: FiberBouncingBehaviorProps & FiberBouncingBehaviorPropsCtor & BabylonNode; framingBehavior: FiberFramingBehaviorProps & FiberFramingBehaviorPropsCtor & BabylonNode; @@ -2863,6 +2865,29 @@ export type FiberDynamicTerrainPropsCtor = { SPuvData?: number[][] | Float32Array[]; intializedCallback?: any; }; +export type FiberPointsCloudSystemProps = { + addPoints?: any; + addSurfacePoints?: any; + addVolumePoints?: any; + computeBoundingBox?: boolean; + computeParticleColor?: boolean; + computeParticleRotation?: boolean; + computeParticleTexture?: boolean; + counter?: number; + isAlwaysVisible?: boolean; + mesh?: BabylonjsCoreMesh; + name?: string; + nbParticles?: number; + particles?: BabylonjsCoreCloudPoint[]; + setParticles?: any; + setVisibilityBox?: any; + vars?: any; +} & CustomProps; +export type FiberPointsCloudSystemPropsCtor = { + name: string; + pointSize: number; + updatable?: boolean; +}; export type FiberAutoRotationBehaviorProps = { idleRotationSpeed?: number; idleRotationSpinupTime?: number; diff --git a/src/hooks/index.ts b/src/hooks/index.ts new file mode 100644 index 00000000..1c09652e --- /dev/null +++ b/src/hooks/index.ts @@ -0,0 +1,2 @@ +export * from './useLoader'; +export * from './useAssetManager'; \ No newline at end of file diff --git a/src/hooks/useAssetManager.ts b/src/hooks/useAssetManager.ts new file mode 100644 index 00000000..8afd31c0 --- /dev/null +++ b/src/hooks/useAssetManager.ts @@ -0,0 +1,99 @@ +import { AbstractAssetTask, AssetsManager, Nullable, Scene } from "@babylonjs/core"; +import { useBabylonScene } from "../Scene"; + +export enum TaskType { + Binary = 'Binary' +} + +export type Task = { + taskType: TaskType, + name: string, + url: string +} + +/** + * This has limited functionality, since it only works for binary assets currently. + * onProgress() cannot be reported through the Suspense boundary without context, so thought needed on how to accomplish progress indicator in fallback. + */ +const useAssetManagerWithCache = () => { + // we need our own memoized cache. useMemo, useState, etc. fail miserably - throwing a promise forces the component to remount. + const suspenseCache: Record Nullable> = {}; + + return (tasks: Task[], useDefaultLoadingScreen: boolean = false, scene?: Scene) => { + const hookScene = useBabylonScene(); + + const createGetAssets = (tasks: Task[]): () => Nullable => { + if (!Array.isArray(tasks)) { + throw new Error('Asset Manager tasks must be an array') + } + + if (scene === undefined && hookScene === null) { + throw new Error('useAssetManager can only be used inside a Scene component (or pass scene as a prop)') + } + + const assetManager: AssetsManager = new AssetsManager(scene || hookScene!); + + tasks.forEach(task => { + switch (task.taskType) { + case TaskType.Binary: + assetManager.addBinaryFileTask(task.name, task.url); + break; + default: + throw new Error(`Only binary supported currently. Not ${task.taskType}`); + } + }) + + const taskPromise = new Promise((resolve, reject) => { + let failed = false + assetManager.useDefaultLoadingScreen = useDefaultLoadingScreen; + assetManager.onFinish = (tasks: AbstractAssetTask[]) => { + if (failed === false) { + // setTimeout(() => { /* for testing delays */ + resolve(tasks); + // }, 3000); + } + }; + assetManager.onTaskError = (task: AbstractAssetTask) => { + failed = true; + reject(`Failed task ${task.errorObject ? task.errorObject.message ?? `no error message on '${task.name}'` : task.name}`) + }; + + assetManager.load(); + }); + + let result: Nullable = null; + let error: Nullable = null; + let suspender: Nullable> = (async () => { + try { + result = await taskPromise; + } catch (e) { + error = e; + } finally { + suspender = null; + } + })(); + + const getAssets = () => { + if (suspender) { + throw suspender + }; + if (error !== null) { + throw error; + } + + return result; + }; + return getAssets; + }; + + const key = JSON.stringify(tasks); + if (suspenseCache[key] === undefined) { + suspenseCache[key] = createGetAssets(tasks); + } + + const fn: () => Nullable = suspenseCache[key]; + return [fn()]; + } +} + +export const useAssetManager = useAssetManagerWithCache(); \ No newline at end of file diff --git a/src/react-babylonjs.ts b/src/react-babylonjs.ts index ca45b188..af14244c 100644 --- a/src/react-babylonjs.ts +++ b/src/react-babylonjs.ts @@ -1,7 +1,7 @@ export * from "./generatedCode"; export * from "./generatedProps"; export * from "./hooks"; -export { useLoader } from './hooks/useLoader' +export * from './hooks/index' export * from "./customComponents"; export * from "./PropsHandler"; export { applyInitialPropsToInstance } from './UpdateInstance'; // Imported by react-babylonjs-spring diff --git a/stories/babylonjs/Hooks/useAssetManager.stories.js b/stories/babylonjs/Hooks/useAssetManager.stories.js new file mode 100644 index 00000000..f23526c1 --- /dev/null +++ b/stories/babylonjs/Hooks/useAssetManager.stories.js @@ -0,0 +1,107 @@ +import React, { Suspense, useState, useMemo, useRef, useLayoutEffect } from 'react'; +import { Engine, Scene, useAssetManager, TaskType, useBeforeRender } from '../../../dist/react-babylonjs'; +import { Vector3, Color4, Color3, Axis } from '@babylonjs/core'; +import '../../style.css'; + +export default { title: 'Hooks' }; + +// redeclaring array will force load the asset (not deep equality check on by reference) +const pointCloudAssets = [{ taskType: TaskType.Binary, url: 'assets/kitti/000000.bin', name: 'Velodyne-kitt-dataset' }]; + +const MyPCS = () => { + const pcsRef = useRef(null); + const [result] = useAssetManager(pointCloudAssets); + const [pcs, setPcs] = useState(null); + const [pcsMesh, setPcsMesh] = useState(null); + + useLayoutEffect(() => { + if (pcsRef.current) { // only loaded after suspend returns + setPcs(pcsRef.current.hostInstance); + } + }, [pcsRef]); + + useMemo(() => { + if (result && pcs) { + const floats = new Float32Array(result[0].data); + const POINTS_PER_FLOAT = 4; + const numPoints = floats.length / POINTS_PER_FLOAT; + + // particle is the current particle, the i-th one in the PCS and the s-th one in its group + const particleFunc = (particle, i, s) => { + // KITTI-formatted PCD + const x = floats[POINTS_PER_FLOAT * i] + const y = floats[POINTS_PER_FLOAT * i + 1] + const z = floats[POINTS_PER_FLOAT * i + 2] + particle.position = new Vector3(x, y, z) + particle.color = Color4.FromColor3(Color3.White()) + } + + // NOTE: you can do with useRef/useState + // but you don't know WHEN the reconciler will commit those changes and add the points... + pcs.addPoints(numPoints, particleFunc); + pcs.buildMeshAsync(() => { + setPcsMesh(pcs.mesh); + }) + } + }, [result, pcsRef.current]) + + return + {pcsMesh && + + } + +} + +const MyFallback = () => { + const boxRef = useRef(); + useBeforeRender((scene) => { + if (boxRef.current) { + var deltaTimeInMillis = scene.getEngine().getDeltaTime(); + + const rpm = 10; + boxRef.current.hostInstance.rotation.x = Math.PI / 4; + boxRef.current.hostInstance.rotation.y += ((rpm / 60) * Math.PI * 2 * (deltaTimeInMillis / 1000)); + } + }) + + return +} + +export const UseAssetManager = () => ( +
+ + + + + }> + + + + +
+); + +UseAssetManager.story = { + name: 'useAssetManager', + parameters: { + notes: { + markdown: `## Citation + + ./storybook-static/assets/kitti/000000.bin is a part of [the KITTI dataset](http://www.cvlibs.net/datasets/kitti/raw_data.php): + + @ARTICLE{Geiger2013IJRR, + author = {Andreas Geiger and Philip Lenz and Christoph Stiller and Raquel Urtasun}, + title = {Vision meets Robotics: The KITTI Dataset}, + journal = {International Journal of Robotics Research (IJRR)}, + year = {2013} + } + ` + } + } +} \ No newline at end of file diff --git a/stories/babylonjs/Hooks/useLoader.stories.js b/stories/babylonjs/Hooks/useLoader.stories.js index 061b396f..c471e328 100644 --- a/stories/babylonjs/Hooks/useLoader.stories.js +++ b/stories/babylonjs/Hooks/useLoader.stories.js @@ -9,17 +9,11 @@ const MemoGlTF = ({ position }) => { const url = 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/Box/glTF/Box.gltf'; const [loaded, { meshes }] = useLoader(url); - useMemo(() => { - if (loaded) { - // if you need to re-use a mesh - use memoization - console.log('different meshes[1].uniqueId:', meshes[1].uniqueId) + if (loaded === false) { + return null; + } - meshes[1].position = position; - return meshes[1]; - } - }, [loaded]); - - return null; + return ; } export const UseLoader = () => ( diff --git a/storyboard-site/assets/kitti/000000.bin b/storyboard-site/assets/kitti/000000.bin new file mode 100644 index 00000000..7898a264 Binary files /dev/null and b/storyboard-site/assets/kitti/000000.bin differ diff --git a/tools/generate-code.ts b/tools/generate-code.ts index 1d5885ef..72816ddd 100644 --- a/tools/generate-code.ts +++ b/tools/generate-code.ts @@ -30,7 +30,6 @@ import { NamespaceDeclaration, SetAccessorDeclaration, Type, - TypeGuards, Node, SyntaxKind, FormatCodeSettings, @@ -153,6 +152,7 @@ classesOfInterest.set("VRExperienceHelper", undefined); classesOfInterest.set("DynamicTerrain", undefined); classesOfInterest.set("EffectLayer", undefined); classesOfInterest.set("Behavior", undefined); +classesOfInterest.set("PointsCloudSystem", undefined); /** * In babylon.js, Behavior is a interface, not a class. @@ -630,7 +630,7 @@ const getInstanceSetMethods = (classDeclaration: ClassDeclaration): MethodDeclar classDeclaration.getInstanceMethods().forEach((methodDeclaration: MethodDeclaration) => { const methodName = methodDeclaration.getName(); // TODO: add ? - if (methodName.startsWith("set") || methodName.startsWith('add') || methodName === "translate") { + if (methodName.startsWith('set') || methodName.startsWith('add') || methodName === 'translate') { instanceSetMethods.push(methodDeclaration) } }) @@ -870,9 +870,9 @@ function isPrimitiveType(node: Node): boolean { return false; } - const isTypeRef = TypeGuards.isTypeReferenceNode(node); + const isTypeRef = Node.isTypeReferenceNode(node); if (isTypeRef && node.getText().startsWith("Null")) { - const firstNode: Node | undefined = node.forEachDescendantAsArray().find(desc => !TypeGuards.isIdentifier(desc)); + const firstNode: Node | undefined = node.forEachDescendantAsArray().find(desc => !Node.isIdentifier(desc)); if (firstNode === undefined) { return false; } @@ -970,23 +970,23 @@ const addPropsAndHandlerClasses = (generatedCodeSourceFile: SourceFile, generate let allPrimitives: boolean = false; const propertyDescendantsParametersAndExpressions = property.forEachDescendantAsArray().filter(desc => - !TypeGuards.isIdentifier(desc) && - !TypeGuards.isUnionTypeNode(desc) && - !TypeGuards.isIntersectionTypeNode(desc) && + !Node.isIdentifier(desc) && + !Node.isUnionTypeNode(desc) && + !Node.isIntersectionTypeNode(desc) && !isQuestionToken(desc) && desc.getKind() !== SyntaxKind.PublicKeyword && desc.getKind() !== SyntaxKind.StaticKeyword // allow static setters (ie: AmbientTextureEnabled) ); - const paramDeclaration: ParameterDeclaration | undefined = TypeGuards.isParameterDeclaration(propertyDescendantsParametersAndExpressions[0]) + const paramDeclaration: ParameterDeclaration | undefined = Node.isParameterDeclaration(propertyDescendantsParametersAndExpressions[0]) ? propertyDescendantsParametersAndExpressions[0] as ParameterDeclaration : undefined; if (paramDeclaration !== undefined) { const paramDescendants = paramDeclaration.forEachDescendantAsArray(); - const expressions: Node[] = paramDescendants.filter(desc => !TypeGuards.isIdentifier(desc) && !TypeGuards.isUnionTypeNode(desc)); + const expressions: Node[] = paramDescendants.filter(desc => !Node.isIdentifier(desc) && !Node.isUnionTypeNode(desc)); allPrimitives = expressions.reduce((result, expression) => result && isPrimitiveType(expression), true); } else { - if (propertyDescendantsParametersAndExpressions.every(desc => TypeGuards.isExpression(desc) || TypeGuards.isTypeReferenceNode(desc) /* ie: Nullable<> */)) { + if (propertyDescendantsParametersAndExpressions.every(desc => Node.isExpression(desc) || Node.isTypeReferenceNode(desc) /* ie: Nullable<> */)) { allPrimitives = propertyDescendantsParametersAndExpressions.reduce((result, expression) => result && isPrimitiveType(expression), true); } } @@ -1610,25 +1610,26 @@ const generateCode = async () => { createClassesInheritedFrom(generatedCodeSourceFile, generatedPropsSourceFile, classesOfInterest.get("BaseTexture")!, fromClassName, onTexturesCreate); } - createSingleClass("GUI3DManager", generatedCodeSourceFile, generatedPropsSourceFile, undefined, { isGUI3DControl: true }, () => { return; }) - createSingleClass("ShadowGenerator", generatedCodeSourceFile, generatedPropsSourceFile, undefined, { delayCreation: true }, () => { return; }) - createSingleClass("CascadedShadowGenerator", generatedCodeSourceFile, generatedPropsSourceFile, undefined, { delayCreation: true }, () => { return; }) - createSingleClass("EnvironmentHelper", generatedCodeSourceFile, generatedPropsSourceFile, undefined, { isEnvironment: true }) - createSingleClass("PhysicsImpostor", generatedCodeSourceFile, generatedPropsSourceFile, undefined, { delayCreation: true }) - createSingleClass("VRExperienceHelper", generatedCodeSourceFile, generatedPropsSourceFile) - createSingleClass("DynamicTerrain", generatedCodeSourceFile, generatedPropsSourceFile, undefined, { acceptsMaterials: true }) + createSingleClass("GUI3DManager", generatedCodeSourceFile, generatedPropsSourceFile, undefined, { isGUI3DControl: true }, () => { return; }); + createSingleClass("ShadowGenerator", generatedCodeSourceFile, generatedPropsSourceFile, undefined, { delayCreation: true }, () => { return; }); + createSingleClass("CascadedShadowGenerator", generatedCodeSourceFile, generatedPropsSourceFile, undefined, { delayCreation: true }, () => { return; }); + createSingleClass("EnvironmentHelper", generatedCodeSourceFile, generatedPropsSourceFile, undefined, { isEnvironment: true }); + createSingleClass("PhysicsImpostor", generatedCodeSourceFile, generatedPropsSourceFile, undefined, { delayCreation: true }); + createSingleClass("VRExperienceHelper", generatedCodeSourceFile, generatedPropsSourceFile); + createSingleClass("DynamicTerrain", generatedCodeSourceFile, generatedPropsSourceFile, undefined, { acceptsMaterials: true }); + createSingleClass("PointsCloudSystem", generatedCodeSourceFile, generatedPropsSourceFile); classesOfInterest.forEach((_, className) => { if (className.includes('Behavior')) { createSingleClass(className as string, generatedCodeSourceFile, generatedPropsSourceFile, undefined, { isBehavior: true }) } - }) + }); if (classesOfInterest.get("Scene")) { // Scene we only want to generate the handlers. Constructor is very simple - just an Engine - const sceneTuple: ClassNameSpaceTuple = classesOfInterest.get("Scene")! - const className: string = sceneTuple.classDeclaration.getName()! + const sceneTuple: ClassNameSpaceTuple = classesOfInterest.get("Scene")!; + const className: string = sceneTuple.classDeclaration.getName()!; const sceneClassDeclaration = getModuleDeclarationFromClassDeclaration(sceneTuple.classDeclaration); @@ -1643,7 +1644,7 @@ const generateCode = async () => { generatedCodeSourceFile.addImportDeclaration({ moduleSpecifier: "./generatedProps", namedImports: PROPS_EXPORTS - }) + }); // Need a set, since 'hostComponent' is set in both files. const factoryClasses: Map = new Map(); @@ -1653,13 +1654,13 @@ const generateCode = async () => { const sourceFile: SourceFile = fileModuleDeclarations[0].sourceFile; const importDeclaration: ImportDeclaration = sourceFile.addImportDeclaration({ moduleSpecifier: fileModuleDeclarations[0].moduleDeclaration.moduleSpecifier - } as ImportDeclarationStructure) + } as ImportDeclarationStructure); fileModuleDeclarations.forEach((fileModuleDeclaration: FileModuleDeclaration) => { importDeclaration.addNamedImport({ name: fileModuleDeclaration.moduleDeclaration.className, alias: fileModuleDeclaration.moduleDeclaration.importAlias - }) + }); if (fileModuleDeclaration.hostComponent && !factoryClasses.has(fileModuleDeclaration.moduleDeclaration.importAlias)) { factoryClasses.set(fileModuleDeclaration.moduleDeclaration.importAlias, fileModuleDeclaration.moduleDeclaration.className);