@reactvision/react-viro 2.53.1 → 2.55.0
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/README.md +85 -46
- package/android/react_viro/react_viro-release.aar +0 -0
- package/android/viro_renderer/viro_renderer-release.aar +0 -0
- package/components/AR/ViroARCamera.tsx +5 -0
- package/components/AR/ViroARImageMarker.tsx +5 -0
- package/components/AR/ViroARObjectMarker.tsx +5 -0
- package/components/AR/ViroARPlane.tsx +5 -0
- package/components/AR/ViroARPlaneSelector.tsx +5 -0
- package/components/AR/ViroARScene.tsx +5 -0
- package/components/AR/ViroARSceneNavigator.tsx +84 -0
- package/components/AR/ViroCommonProps.ts +11 -0
- package/components/Material/ViroMaterials.ts +51 -0
- package/components/Studio/StudioARScene.tsx +368 -0
- package/components/Studio/StudioSceneNavigator.tsx +191 -0
- package/components/Studio/VRTStudioModule.ts +40 -0
- package/components/Studio/domain/animationRegistry.ts +86 -0
- package/components/Studio/domain/collisionBindingsRuntime.ts +93 -0
- package/components/Studio/domain/collisionPairKey.ts +15 -0
- package/components/Studio/domain/dragConfiguration.ts +48 -0
- package/components/Studio/domain/materialConfig.ts +276 -0
- package/components/Studio/domain/physicsConfig.ts +204 -0
- package/components/Studio/domain/sceneNavigationHandler.ts +150 -0
- package/components/Studio/domain/studioMaterials.ts +33 -0
- package/components/Studio/domain/triggerImageRegistry.ts +64 -0
- package/components/Studio/domain/useStudioShaderTimeUniforms.ts +51 -0
- package/components/Studio/domain/useStudioShaderViewportUniforms.ts +52 -0
- package/components/Studio/domain/viroNodeFactory.tsx +323 -0
- package/components/Studio/index.ts +18 -0
- package/components/Studio/types.ts +164 -0
- package/components/Types/ViroEvents.ts +53 -0
- package/components/Utilities/VRModuleOpenXR.ts +50 -0
- package/components/Utilities/VRQuestNavigatorBridge.ts +168 -0
- package/components/Utilities/ViroPlatform.ts +52 -0
- package/components/Utilities/ViroUtils.tsx +48 -0
- package/components/Utilities/ViroVersion.ts +1 -1
- package/components/Utilities/useAnySourceHover.ts +55 -0
- package/components/Utilities/useAnySourcePressed.ts +70 -0
- package/components/Viro360Image.tsx +7 -0
- package/components/ViroQuestEntryPoint.tsx +79 -0
- package/components/ViroVRSceneNavigator.tsx +44 -19
- package/components/ViroXRSceneNavigator.tsx +217 -0
- package/components/VisionOS/ViroVisionOSModule.ts +93 -0
- package/dist/components/AR/ViroARCamera.d.ts +1 -1
- package/dist/components/AR/ViroARCamera.js +5 -0
- package/dist/components/AR/ViroARImageMarker.d.ts +1 -1
- package/dist/components/AR/ViroARImageMarker.js +5 -0
- package/dist/components/AR/ViroARObjectMarker.d.ts +1 -1
- package/dist/components/AR/ViroARObjectMarker.js +5 -0
- package/dist/components/AR/ViroARPlane.d.ts +1 -1
- package/dist/components/AR/ViroARPlane.js +5 -0
- package/dist/components/AR/ViroARPlaneSelector.d.ts +1 -1
- package/dist/components/AR/ViroARPlaneSelector.js +5 -0
- package/dist/components/AR/ViroARScene.d.ts +1 -1
- package/dist/components/AR/ViroARScene.js +5 -0
- package/dist/components/AR/ViroARSceneNavigator.d.ts +36 -0
- package/dist/components/AR/ViroARSceneNavigator.js +41 -0
- package/dist/components/AR/ViroCommonProps.d.ts +11 -0
- package/dist/components/Material/ViroMaterials.d.ts +12 -0
- package/dist/components/Material/ViroMaterials.js +25 -0
- package/dist/components/ReactVisionClient.d.ts +25 -0
- package/dist/components/ReactVisionClient.js +11 -0
- package/dist/components/Studio/StudioARScene.d.ts +15 -0
- package/dist/components/Studio/StudioARScene.js +299 -0
- package/dist/components/Studio/StudioSceneNavigator.d.ts +31 -0
- package/dist/components/Studio/StudioSceneNavigator.js +174 -0
- package/dist/components/Studio/VRTStudioModule.d.ts +15 -0
- package/dist/components/Studio/VRTStudioModule.js +31 -0
- package/dist/components/Studio/domain/animationRegistry.d.ts +11 -0
- package/dist/components/Studio/domain/animationRegistry.js +67 -0
- package/dist/components/Studio/domain/collisionBindingsRuntime.d.ts +21 -0
- package/dist/components/Studio/domain/collisionBindingsRuntime.js +54 -0
- package/dist/components/Studio/domain/collisionPairKey.d.ts +8 -0
- package/dist/components/Studio/domain/collisionPairKey.js +15 -0
- package/dist/components/Studio/domain/dragConfiguration.d.ts +20 -0
- package/dist/components/Studio/domain/dragConfiguration.js +37 -0
- package/dist/components/Studio/domain/materialConfig.d.ts +56 -0
- package/dist/components/Studio/domain/materialConfig.js +239 -0
- package/dist/components/Studio/domain/physicsConfig.d.ts +69 -0
- package/dist/components/Studio/domain/physicsConfig.js +165 -0
- package/dist/components/Studio/domain/sceneNavigationHandler.d.ts +12 -0
- package/dist/components/Studio/domain/sceneNavigationHandler.js +112 -0
- package/dist/components/Studio/domain/studioMaterials.d.ts +6 -0
- package/dist/components/Studio/domain/studioMaterials.js +30 -0
- package/dist/components/Studio/domain/triggerImageRegistry.d.ts +13 -0
- package/dist/components/Studio/domain/triggerImageRegistry.js +47 -0
- package/dist/components/Studio/domain/useStudioShaderTimeUniforms.d.ts +6 -0
- package/dist/components/Studio/domain/useStudioShaderTimeUniforms.js +48 -0
- package/dist/components/Studio/domain/useStudioShaderViewportUniforms.d.ts +6 -0
- package/dist/components/Studio/domain/useStudioShaderViewportUniforms.js +48 -0
- package/dist/components/Studio/domain/viroNodeFactory.d.ts +28 -0
- package/dist/components/Studio/domain/viroNodeFactory.js +193 -0
- package/dist/components/Studio/index.d.ts +3 -0
- package/dist/components/Studio/index.js +7 -0
- package/dist/components/Studio/types.d.ts +149 -0
- package/dist/components/Studio/types.js +4 -0
- package/dist/components/Types/ViroEvents.d.ts +49 -1
- package/dist/components/Types/ViroEvents.js +1 -0
- package/dist/components/Utilities/VRModuleOpenXR.d.ts +32 -0
- package/dist/components/Utilities/VRModuleOpenXR.js +44 -0
- package/dist/components/Utilities/VRQuestNavigatorBridge.d.ts +85 -0
- package/dist/components/Utilities/VRQuestNavigatorBridge.js +124 -0
- package/dist/components/Utilities/ViroPlatform.d.ts +10 -0
- package/dist/components/Utilities/ViroPlatform.js +43 -0
- package/dist/components/Utilities/ViroUtils.d.ts +19 -0
- package/dist/components/Utilities/ViroUtils.js +34 -0
- package/dist/components/Utilities/ViroVersion.d.ts +1 -1
- package/dist/components/Utilities/ViroVersion.js +1 -1
- package/dist/components/Utilities/useAnySourceHover.d.ts +36 -0
- package/dist/components/Utilities/useAnySourceHover.js +48 -0
- package/dist/components/Utilities/useAnySourcePressed.d.ts +37 -0
- package/dist/components/Utilities/useAnySourcePressed.js +61 -0
- package/dist/components/Viro360Image.d.ts +7 -0
- package/dist/components/ViroQuestEntryPoint.d.ts +13 -0
- package/dist/components/ViroQuestEntryPoint.js +104 -0
- package/dist/components/ViroVRSceneNavigator.d.ts +24 -10
- package/dist/components/ViroVRSceneNavigator.js +21 -18
- package/dist/components/ViroXRSceneNavigator.d.ts +54 -0
- package/dist/components/ViroXRSceneNavigator.js +173 -0
- package/dist/components/VisionOS/ViroVisionOSModule.d.ts +65 -0
- package/dist/components/VisionOS/ViroVisionOSModule.js +91 -0
- package/dist/index.d.ts +16 -3
- package/dist/index.js +34 -2
- package/dist/plugins/withViro.d.ts +28 -1
- package/dist/plugins/withViroAndroid.js +312 -7
- package/dist/plugins/withViroIos.js +17 -8
- package/dist/plugins/withViroVisionOS.d.ts +24 -0
- package/dist/plugins/withViroVisionOS.js +265 -0
- package/index.ts +66 -0
- package/ios/ViroReact.podspec +15 -5
- package/ios/dist/ViroRenderer/ViroKit.framework/ARCoreCoreMLSemanticsResources.bundle/Info.plist +0 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/ARCoreResources.bundle/Info.plist +0 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROARSession.h +30 -1
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROARSessioniOS.h +16 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROGLTFLoader.h +34 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROInputControllerBase.h +74 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROInputType.h +11 -3
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROMaterial.h +29 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROMorpher.h +4 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROPlatformUtil.h +13 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROPortal.h +17 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VRORenderContext.h +41 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VRORenderer.h +23 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROSemantics.h +14 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Headers/VROViewAR.h +11 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Info.plist +0 -0
- package/ios/dist/ViroRenderer/ViroKit.framework/Shaders.dat +1 -1
- package/ios/dist/ViroRenderer/ViroKit.framework/ViroKit +0 -0
- package/ios/dist/ViroRenderer/ViroKit.podspec +5 -0
- package/ios/dist/include/VRT360Image.h +1 -0
- package/ios/dist/include/VRTARSceneNavigator.h +7 -0
- package/ios/dist/include/VRTStudioModule.h +6 -0
- package/ios/dist/lib/libViroReact.a +0 -0
- package/package.json +8 -8
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dispatchCollisionBindingActions = dispatchCollisionBindingActions;
|
|
4
|
+
exports.createPlacementCollisionHandler = createPlacementCollisionHandler;
|
|
5
|
+
const collisionPairKey_1 = require("./collisionPairKey");
|
|
6
|
+
const sceneNavigationHandler_1 = require("./sceneNavigationHandler");
|
|
7
|
+
const DEFAULT_COOLDOWN_MS = 750;
|
|
8
|
+
function pairCooldownKey(pairKey, functionId) {
|
|
9
|
+
return `${pairKey}::${functionId}`;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Dispatches scene functions for collision bindings matching the canonical pair.
|
|
13
|
+
* Cooldown prevents per-frame spam while physics contacts overlap.
|
|
14
|
+
*/
|
|
15
|
+
function dispatchCollisionBindingActions(params) {
|
|
16
|
+
const { selfPlacementId, otherTag, bindingsByPairKey, sceneNavigator, animations, onSceneChange, onAnimationTrigger, cooldownMs = DEFAULT_COOLDOWN_MS, lastFiredRef, } = params;
|
|
17
|
+
if (!otherTag)
|
|
18
|
+
return;
|
|
19
|
+
const { asset_x_id, asset_y_id } = (0, collisionPairKey_1.canonicalizeCollisionAssetIds)(selfPlacementId, otherTag);
|
|
20
|
+
const pKey = (0, collisionPairKey_1.collisionPairKey)(asset_x_id, asset_y_id);
|
|
21
|
+
const rows = bindingsByPairKey.get(pKey);
|
|
22
|
+
if (!rows?.length)
|
|
23
|
+
return;
|
|
24
|
+
const now = Date.now();
|
|
25
|
+
const map = lastFiredRef.current;
|
|
26
|
+
for (const row of rows) {
|
|
27
|
+
const fn = row.scene_function;
|
|
28
|
+
if (!fn)
|
|
29
|
+
continue;
|
|
30
|
+
const ck = pairCooldownKey(pKey, row.function_id);
|
|
31
|
+
const last = map.get(ck) ?? 0;
|
|
32
|
+
if (now - last < cooldownMs)
|
|
33
|
+
continue;
|
|
34
|
+
map.set(ck, now);
|
|
35
|
+
(0, sceneNavigationHandler_1.executeFunctionWithRelations)(fn, sceneNavigator, animations, onAnimationTrigger, 0, onSceneChange);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Returns an onCollision handler for a given placement asset ID.
|
|
40
|
+
*/
|
|
41
|
+
function createPlacementCollisionHandler(placementId, bindingsByPairKey, sceneNavigator, animations, lastFiredRef, onAnimationTrigger, onSceneChange) {
|
|
42
|
+
return (viroTag) => {
|
|
43
|
+
dispatchCollisionBindingActions({
|
|
44
|
+
selfPlacementId: placementId,
|
|
45
|
+
otherTag: viroTag,
|
|
46
|
+
bindingsByPairKey,
|
|
47
|
+
sceneNavigator,
|
|
48
|
+
animations,
|
|
49
|
+
onSceneChange,
|
|
50
|
+
onAnimationTrigger,
|
|
51
|
+
lastFiredRef,
|
|
52
|
+
});
|
|
53
|
+
};
|
|
54
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical collision pair — matches DB constraint where asset_x_id < asset_y_id lexicographically.
|
|
3
|
+
*/
|
|
4
|
+
export declare function canonicalizeCollisionAssetIds(a: string, b: string): {
|
|
5
|
+
asset_x_id: string;
|
|
6
|
+
asset_y_id: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function collisionPairKey(assetX: string, assetY: string): string;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.canonicalizeCollisionAssetIds = canonicalizeCollisionAssetIds;
|
|
4
|
+
exports.collisionPairKey = collisionPairKey;
|
|
5
|
+
/**
|
|
6
|
+
* Canonical collision pair — matches DB constraint where asset_x_id < asset_y_id lexicographically.
|
|
7
|
+
*/
|
|
8
|
+
function canonicalizeCollisionAssetIds(a, b) {
|
|
9
|
+
return a < b
|
|
10
|
+
? { asset_x_id: a, asset_y_id: b }
|
|
11
|
+
: { asset_x_id: b, asset_y_id: a };
|
|
12
|
+
}
|
|
13
|
+
function collisionPairKey(assetX, assetY) {
|
|
14
|
+
return `${assetX}|${assetY}`;
|
|
15
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { StudioAsset, StudioSceneMeta } from "../types";
|
|
2
|
+
export type DragType = "FixedToWorld" | "FixedToPlane" | undefined;
|
|
3
|
+
export type DragPlane = {
|
|
4
|
+
planePoint: [number, number, number];
|
|
5
|
+
planeNormal: [number, number, number];
|
|
6
|
+
maxDistance: number;
|
|
7
|
+
};
|
|
8
|
+
export declare class DragConfiguration {
|
|
9
|
+
/**
|
|
10
|
+
* Chooses FixedToPlane when the scene uses plane detection, FixedToWorld otherwise.
|
|
11
|
+
* Returns undefined if the asset is not draggable.
|
|
12
|
+
*/
|
|
13
|
+
static getDragType(asset: StudioAsset, scene: StudioSceneMeta | null): DragType;
|
|
14
|
+
/**
|
|
15
|
+
* Returns a drag plane that passes through the object's current position,
|
|
16
|
+
* preventing objects from jumping on drag start. maxDistance caps how far
|
|
17
|
+
* objects can travel from the camera.
|
|
18
|
+
*/
|
|
19
|
+
static getDragPlane(planeAlignment: string, objectPosition: [number, number, number]): DragPlane;
|
|
20
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DragConfiguration = void 0;
|
|
4
|
+
class DragConfiguration {
|
|
5
|
+
/**
|
|
6
|
+
* Chooses FixedToPlane when the scene uses plane detection, FixedToWorld otherwise.
|
|
7
|
+
* Returns undefined if the asset is not draggable.
|
|
8
|
+
*/
|
|
9
|
+
static getDragType(asset, scene) {
|
|
10
|
+
if (!asset.is_draggable)
|
|
11
|
+
return undefined;
|
|
12
|
+
const planeDetection = (scene?.plane_detection ?? "NONE").toUpperCase();
|
|
13
|
+
if (planeDetection === "AUTOMATIC" || planeDetection === "MANUAL") {
|
|
14
|
+
return "FixedToPlane";
|
|
15
|
+
}
|
|
16
|
+
return "FixedToWorld";
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Returns a drag plane that passes through the object's current position,
|
|
20
|
+
* preventing objects from jumping on drag start. maxDistance caps how far
|
|
21
|
+
* objects can travel from the camera.
|
|
22
|
+
*/
|
|
23
|
+
static getDragPlane(planeAlignment, objectPosition) {
|
|
24
|
+
switch (planeAlignment.toLowerCase()) {
|
|
25
|
+
case "horizontal":
|
|
26
|
+
case "horizontalupward":
|
|
27
|
+
return { planePoint: objectPosition, planeNormal: [0, 1, 0], maxDistance: 1.5 };
|
|
28
|
+
case "horizontaldownward":
|
|
29
|
+
return { planePoint: objectPosition, planeNormal: [0, -1, 0], maxDistance: 1.5 };
|
|
30
|
+
case "vertical":
|
|
31
|
+
return { planePoint: objectPosition, planeNormal: [0, 0, 1], maxDistance: 1.5 };
|
|
32
|
+
default:
|
|
33
|
+
return { planePoint: objectPosition, planeNormal: [0, 1, 0], maxDistance: 1.5 };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
exports.DragConfiguration = DragConfiguration;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Studio material_config parsing and Viro material definition building.
|
|
3
|
+
* Ported from studio-go/domain/materialConfig.ts — no zod dependency.
|
|
4
|
+
*/
|
|
5
|
+
type ShaderModifierStage = {
|
|
6
|
+
uniforms?: string;
|
|
7
|
+
body?: string;
|
|
8
|
+
varyings?: unknown;
|
|
9
|
+
requiresSceneDepth?: boolean;
|
|
10
|
+
requiresCameraTexture?: boolean;
|
|
11
|
+
priority?: unknown;
|
|
12
|
+
};
|
|
13
|
+
export type MaterialConfig = {
|
|
14
|
+
presetName?: string;
|
|
15
|
+
lightingModel: "Constant" | "Lambert" | "Blinn" | "Phong" | "PBR";
|
|
16
|
+
diffuseColor?: string;
|
|
17
|
+
roughness?: number;
|
|
18
|
+
metalness?: number;
|
|
19
|
+
shininess?: number;
|
|
20
|
+
alpha?: number;
|
|
21
|
+
blendMode?: string;
|
|
22
|
+
bloomThreshold?: number | null;
|
|
23
|
+
wrapS?: "Clamp" | "Repeat" | "Mirror";
|
|
24
|
+
wrapT?: "Clamp" | "Repeat" | "Mirror";
|
|
25
|
+
diffuseTexture?: string | null;
|
|
26
|
+
normalTexture?: string | null;
|
|
27
|
+
roughnessTexture?: string | null;
|
|
28
|
+
metalnessTexture?: string | null;
|
|
29
|
+
ambientOcclusionTexture?: string | null;
|
|
30
|
+
specularTexture?: string | null;
|
|
31
|
+
shaderModifiers?: Record<string, ShaderModifierStage | string>;
|
|
32
|
+
materialUniforms?: Array<{
|
|
33
|
+
name: string;
|
|
34
|
+
type: string;
|
|
35
|
+
value: unknown;
|
|
36
|
+
}>;
|
|
37
|
+
transparencyMode?: string;
|
|
38
|
+
cullMode?: string;
|
|
39
|
+
};
|
|
40
|
+
export type ViroMaterialDefinition = Record<string, unknown>;
|
|
41
|
+
export declare function materialConfigNeedsTimeUniform(config: MaterialConfig): boolean;
|
|
42
|
+
/**
|
|
43
|
+
* True if the shader uses _rf_vpw/_rf_vph viewport uniforms.
|
|
44
|
+
* These must be pushed via ViroMaterials.updateShaderUniform on mount and orientation change.
|
|
45
|
+
*/
|
|
46
|
+
export declare function materialConfigNeedsViewportUniforms(config: MaterialConfig): boolean;
|
|
47
|
+
export declare function studioMaterialName(assetId: string): string;
|
|
48
|
+
/**
|
|
49
|
+
* Parses `scene_assets.material_config` JSON. Returns null if missing or invalid.
|
|
50
|
+
*/
|
|
51
|
+
export declare function parseMaterialConfig(raw: unknown): MaterialConfig | null;
|
|
52
|
+
/**
|
|
53
|
+
* Maps a validated Studio material_config to Viro's `createMaterials` definition shape.
|
|
54
|
+
*/
|
|
55
|
+
export declare function buildViroMaterialDefinition(config: MaterialConfig): ViroMaterialDefinition;
|
|
56
|
+
export {};
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Studio material_config parsing and Viro material definition building.
|
|
4
|
+
* Ported from studio-go/domain/materialConfig.ts — no zod dependency.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.materialConfigNeedsTimeUniform = materialConfigNeedsTimeUniform;
|
|
8
|
+
exports.materialConfigNeedsViewportUniforms = materialConfigNeedsViewportUniforms;
|
|
9
|
+
exports.studioMaterialName = studioMaterialName;
|
|
10
|
+
exports.parseMaterialConfig = parseMaterialConfig;
|
|
11
|
+
exports.buildViroMaterialDefinition = buildViroMaterialDefinition;
|
|
12
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
13
|
+
const TEXTURE_KEYS = [
|
|
14
|
+
"diffuseTexture",
|
|
15
|
+
"normalTexture",
|
|
16
|
+
"roughnessTexture",
|
|
17
|
+
"metalnessTexture",
|
|
18
|
+
"ambientOcclusionTexture",
|
|
19
|
+
"specularTexture",
|
|
20
|
+
];
|
|
21
|
+
function textureToViro(uri) {
|
|
22
|
+
if (uri == null || uri === "")
|
|
23
|
+
return undefined;
|
|
24
|
+
return { uri };
|
|
25
|
+
}
|
|
26
|
+
function collectShaderModifierStrings(config) {
|
|
27
|
+
const mods = config.shaderModifiers;
|
|
28
|
+
if (!mods)
|
|
29
|
+
return [];
|
|
30
|
+
const strings = [];
|
|
31
|
+
for (const stage of Object.values(mods)) {
|
|
32
|
+
if (typeof stage === "string") {
|
|
33
|
+
strings.push(stage);
|
|
34
|
+
}
|
|
35
|
+
else if (stage && typeof stage === "object") {
|
|
36
|
+
const s = stage;
|
|
37
|
+
if (typeof s.uniforms === "string")
|
|
38
|
+
strings.push(s.uniforms);
|
|
39
|
+
if (typeof s.body === "string")
|
|
40
|
+
strings.push(s.body);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return strings;
|
|
44
|
+
}
|
|
45
|
+
const TIME_WORD_RE = /\btime\b/i;
|
|
46
|
+
const CAMERA_TEXTURE_RE = /\bcamera_texture\b/;
|
|
47
|
+
const RF_VIEWPORT_RE = /\b_rf_vpw\b|\b_rf_vph\b/;
|
|
48
|
+
function materialConfigNeedsTimeUniform(config) {
|
|
49
|
+
if (config.materialUniforms?.some((u) => u.name === "time"))
|
|
50
|
+
return true;
|
|
51
|
+
return collectShaderModifierStrings(config).some((s) => TIME_WORD_RE.test(s));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* True if the shader uses _rf_vpw/_rf_vph viewport uniforms.
|
|
55
|
+
* These must be pushed via ViroMaterials.updateShaderUniform on mount and orientation change.
|
|
56
|
+
*/
|
|
57
|
+
function materialConfigNeedsViewportUniforms(config) {
|
|
58
|
+
return collectShaderModifierStrings(config).some((s) => RF_VIEWPORT_RE.test(s));
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Prepends GLSL uniform declarations that the body references but the uniforms block omits.
|
|
62
|
+
* Required when shaders are authored for remote delivery without explicit sampler declarations.
|
|
63
|
+
*/
|
|
64
|
+
function injectMissingGlslDeclarations(uniforms, body) {
|
|
65
|
+
let result = uniforms;
|
|
66
|
+
if (CAMERA_TEXTURE_RE.test(body) && !CAMERA_TEXTURE_RE.test(result)) {
|
|
67
|
+
result =
|
|
68
|
+
"uniform sampler2D camera_texture;\nuniform highp mat4 camera_image_transform;\n" +
|
|
69
|
+
result;
|
|
70
|
+
}
|
|
71
|
+
if (RF_VIEWPORT_RE.test(body) && !/\b_rf_vpw\b/.test(result)) {
|
|
72
|
+
result = "uniform highp float _rf_vpw;\nuniform highp float _rf_vph;\n" + result;
|
|
73
|
+
}
|
|
74
|
+
return result;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* iOS only applies `ViroMaterials.updateShaderUniform` to uniforms registered
|
|
78
|
+
* via `materialUniforms`. If a shader references `time` or viewport uniforms in
|
|
79
|
+
* GLSL only, we add the runtime binding here.
|
|
80
|
+
*/
|
|
81
|
+
function mergeMaterialUniformsForViro(config) {
|
|
82
|
+
const list = config.materialUniforms
|
|
83
|
+
? config.materialUniforms.map((u) => ({ name: u.name, type: u.type, value: u.value }))
|
|
84
|
+
: [];
|
|
85
|
+
if (materialConfigNeedsTimeUniform(config) && !list.some((u) => u.name === "time")) {
|
|
86
|
+
list.push({ name: "time", type: "float", value: 0 });
|
|
87
|
+
}
|
|
88
|
+
if (materialConfigNeedsViewportUniforms(config)) {
|
|
89
|
+
if (!list.some((u) => u.name === "_rf_vpw"))
|
|
90
|
+
list.push({ name: "_rf_vpw", type: "float", value: 0 });
|
|
91
|
+
if (!list.some((u) => u.name === "_rf_vph"))
|
|
92
|
+
list.push({ name: "_rf_vph", type: "float", value: 0 });
|
|
93
|
+
}
|
|
94
|
+
return list.length > 0 ? list : undefined;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Studio stores modifiers as `{ uniforms, body }`; Viro works best with a single
|
|
98
|
+
* GLSL string per stage. Stages with advanced fields are kept as structured objects.
|
|
99
|
+
* Camera texture usage is detected from GLSL and auto-flagged so the Viro native
|
|
100
|
+
* layer binds the camera feed even when the DB JSON omits `requiresCameraTexture`.
|
|
101
|
+
*/
|
|
102
|
+
function normalizeShaderModifiersForViro(mods) {
|
|
103
|
+
const out = {};
|
|
104
|
+
for (const [key, stage] of Object.entries(mods)) {
|
|
105
|
+
if (typeof stage === "string") {
|
|
106
|
+
out[key] = stage;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (stage && typeof stage === "object") {
|
|
110
|
+
const s = stage;
|
|
111
|
+
const uniforms = typeof s.uniforms === "string" ? s.uniforms : "";
|
|
112
|
+
const body = typeof s.body === "string" ? s.body : "";
|
|
113
|
+
// Detect camera texture usage in GLSL even when the flag is absent from DB JSON.
|
|
114
|
+
const usesCameraTexture = CAMERA_TEXTURE_RE.test(body) || CAMERA_TEXTURE_RE.test(uniforms);
|
|
115
|
+
const hasAdvanced = s.varyings != null ||
|
|
116
|
+
s.requiresSceneDepth === true ||
|
|
117
|
+
s.requiresCameraTexture === true ||
|
|
118
|
+
usesCameraTexture ||
|
|
119
|
+
s.priority != null;
|
|
120
|
+
if (hasAdvanced) {
|
|
121
|
+
if (usesCameraTexture && s.requiresCameraTexture !== true) {
|
|
122
|
+
// Auto-fix: flag the stage and inject any missing GLSL declarations so the
|
|
123
|
+
// native Viro layer binds camera_texture and the shader compiles cleanly.
|
|
124
|
+
out[key] = {
|
|
125
|
+
...s,
|
|
126
|
+
requiresCameraTexture: true,
|
|
127
|
+
uniforms: injectMissingGlslDeclarations(uniforms, body),
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
else {
|
|
131
|
+
out[key] = stage;
|
|
132
|
+
}
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
const merged = [uniforms.trim(), body.trim()].filter(Boolean).join("\n");
|
|
136
|
+
out[key] = merged.length > 0 ? merged : stage;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return out;
|
|
140
|
+
}
|
|
141
|
+
// ─── Public API ───────────────────────────────────────────────────────────────
|
|
142
|
+
function studioMaterialName(assetId) {
|
|
143
|
+
return `studio_${assetId}`;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Parses `scene_assets.material_config` JSON. Returns null if missing or invalid.
|
|
147
|
+
*/
|
|
148
|
+
function parseMaterialConfig(raw) {
|
|
149
|
+
if (raw == null || typeof raw !== "object" || Array.isArray(raw))
|
|
150
|
+
return null;
|
|
151
|
+
const r = raw;
|
|
152
|
+
try {
|
|
153
|
+
const config = {
|
|
154
|
+
lightingModel: (["Constant", "Lambert", "Blinn", "Phong", "PBR"].includes(r.lightingModel)
|
|
155
|
+
? r.lightingModel
|
|
156
|
+
: "PBR"),
|
|
157
|
+
};
|
|
158
|
+
if (typeof r.presetName === "string")
|
|
159
|
+
config.presetName = r.presetName;
|
|
160
|
+
if (typeof r.diffuseColor === "string")
|
|
161
|
+
config.diffuseColor = r.diffuseColor;
|
|
162
|
+
if (typeof r.roughness === "number")
|
|
163
|
+
config.roughness = r.roughness;
|
|
164
|
+
if (typeof r.metalness === "number")
|
|
165
|
+
config.metalness = r.metalness;
|
|
166
|
+
if (typeof r.shininess === "number")
|
|
167
|
+
config.shininess = r.shininess;
|
|
168
|
+
if (typeof r.alpha === "number")
|
|
169
|
+
config.alpha = r.alpha;
|
|
170
|
+
if (typeof r.blendMode === "string")
|
|
171
|
+
config.blendMode = r.blendMode;
|
|
172
|
+
if (r.bloomThreshold != null && typeof r.bloomThreshold === "number")
|
|
173
|
+
config.bloomThreshold = r.bloomThreshold;
|
|
174
|
+
if (["Clamp", "Repeat", "Mirror"].includes(r.wrapS))
|
|
175
|
+
config.wrapS = r.wrapS;
|
|
176
|
+
if (["Clamp", "Repeat", "Mirror"].includes(r.wrapT))
|
|
177
|
+
config.wrapT = r.wrapT;
|
|
178
|
+
if (typeof r.transparencyMode === "string")
|
|
179
|
+
config.transparencyMode = r.transparencyMode;
|
|
180
|
+
if (typeof r.cullMode === "string")
|
|
181
|
+
config.cullMode = r.cullMode;
|
|
182
|
+
for (const key of TEXTURE_KEYS) {
|
|
183
|
+
const v = r[key];
|
|
184
|
+
if (typeof v === "string" || v === null)
|
|
185
|
+
config[key] = v;
|
|
186
|
+
}
|
|
187
|
+
if (r.shaderModifiers && typeof r.shaderModifiers === "object" && !Array.isArray(r.shaderModifiers)) {
|
|
188
|
+
config.shaderModifiers = r.shaderModifiers;
|
|
189
|
+
}
|
|
190
|
+
if (Array.isArray(r.materialUniforms)) {
|
|
191
|
+
config.materialUniforms = r.materialUniforms.filter((u) => u && typeof u.name === "string" && typeof u.type === "string");
|
|
192
|
+
}
|
|
193
|
+
return config;
|
|
194
|
+
}
|
|
195
|
+
catch (e) {
|
|
196
|
+
console.warn("[material_config] Failed to parse material_config", e);
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Maps a validated Studio material_config to Viro's `createMaterials` definition shape.
|
|
202
|
+
*/
|
|
203
|
+
function buildViroMaterialDefinition(config) {
|
|
204
|
+
const out = { lightingModel: config.lightingModel };
|
|
205
|
+
if (config.diffuseColor !== undefined)
|
|
206
|
+
out.diffuseColor = config.diffuseColor;
|
|
207
|
+
if (config.roughness !== undefined)
|
|
208
|
+
out.roughness = config.roughness;
|
|
209
|
+
if (config.metalness !== undefined)
|
|
210
|
+
out.metalness = config.metalness;
|
|
211
|
+
if (config.shininess !== undefined)
|
|
212
|
+
out.shininess = config.shininess;
|
|
213
|
+
if (config.alpha !== undefined)
|
|
214
|
+
out.alpha = config.alpha;
|
|
215
|
+
if (config.blendMode !== undefined)
|
|
216
|
+
out.blendMode = config.blendMode;
|
|
217
|
+
if (config.bloomThreshold != undefined)
|
|
218
|
+
out.bloomThreshold = config.bloomThreshold;
|
|
219
|
+
if (config.wrapS !== undefined)
|
|
220
|
+
out.wrapS = config.wrapS;
|
|
221
|
+
if (config.wrapT !== undefined)
|
|
222
|
+
out.wrapT = config.wrapT;
|
|
223
|
+
if (config.transparencyMode !== undefined)
|
|
224
|
+
out.transparencyMode = config.transparencyMode;
|
|
225
|
+
if (config.cullMode !== undefined)
|
|
226
|
+
out.cullMode = config.cullMode;
|
|
227
|
+
for (const key of TEXTURE_KEYS) {
|
|
228
|
+
const mapped = textureToViro(config[key]);
|
|
229
|
+
if (mapped !== undefined)
|
|
230
|
+
out[key] = mapped;
|
|
231
|
+
}
|
|
232
|
+
if (config.shaderModifiers !== undefined) {
|
|
233
|
+
out.shaderModifiers = normalizeShaderModifiersForViro(config.shaderModifiers);
|
|
234
|
+
}
|
|
235
|
+
const mergedUniforms = mergeMaterialUniformsForViro(config);
|
|
236
|
+
if (mergedUniforms !== undefined)
|
|
237
|
+
out.materialUniforms = mergedUniforms;
|
|
238
|
+
return out;
|
|
239
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Studio physics_config and physics_world_config parsing and Viro prop building.
|
|
3
|
+
* Ported from studio-go/domain/physicsConfig.ts — no zod dependency.
|
|
4
|
+
*/
|
|
5
|
+
type Vec3 = [number, number, number];
|
|
6
|
+
type ForceEntry = {
|
|
7
|
+
value: Vec3;
|
|
8
|
+
position?: Vec3;
|
|
9
|
+
};
|
|
10
|
+
type PhysicsShape = {
|
|
11
|
+
type: "Box";
|
|
12
|
+
params: [number, number, number];
|
|
13
|
+
} | {
|
|
14
|
+
type: "Sphere";
|
|
15
|
+
params: [number];
|
|
16
|
+
} | {
|
|
17
|
+
type: "Compound";
|
|
18
|
+
children: Array<{
|
|
19
|
+
type: "Box" | "Sphere";
|
|
20
|
+
params: number[];
|
|
21
|
+
position: Vec3;
|
|
22
|
+
rotation?: Vec3;
|
|
23
|
+
}>;
|
|
24
|
+
};
|
|
25
|
+
export type PhysicsBodyConfig = {
|
|
26
|
+
enabled: boolean;
|
|
27
|
+
type: "Dynamic" | "Kinematic" | "Static";
|
|
28
|
+
mass: number;
|
|
29
|
+
shape?: PhysicsShape;
|
|
30
|
+
restitution?: number;
|
|
31
|
+
friction?: number;
|
|
32
|
+
useGravity?: boolean;
|
|
33
|
+
viroTag?: string;
|
|
34
|
+
force?: ForceEntry | ForceEntry[];
|
|
35
|
+
torque?: Vec3 | Vec3[];
|
|
36
|
+
velocity?: Vec3;
|
|
37
|
+
};
|
|
38
|
+
export type PhysicsWorldConfig = {
|
|
39
|
+
enabled: boolean;
|
|
40
|
+
gravity: Vec3;
|
|
41
|
+
drawBounds: boolean;
|
|
42
|
+
};
|
|
43
|
+
export type BuildViroPhysicsBodyOptions = {
|
|
44
|
+
/** Forces Dynamic body to Kinematic with mass 0 while dragging. */
|
|
45
|
+
kinematicDragOverride?: boolean;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Parses `scene.physics_world_config` JSON. Returns null if missing or invalid.
|
|
49
|
+
*/
|
|
50
|
+
export declare function parsePhysicsWorldConfig(raw: unknown): PhysicsWorldConfig | null;
|
|
51
|
+
/**
|
|
52
|
+
* Parses `asset.physics_config` JSON. Returns null if missing or invalid.
|
|
53
|
+
*/
|
|
54
|
+
export declare function parsePhysicsBodyConfig(raw: unknown): PhysicsBodyConfig | null;
|
|
55
|
+
/** Viro `ViroARScene` physicsWorld prop. */
|
|
56
|
+
export declare function buildViroPhysicsWorld(config: PhysicsWorldConfig): {
|
|
57
|
+
gravity: Vec3;
|
|
58
|
+
drawBounds?: boolean;
|
|
59
|
+
};
|
|
60
|
+
/** Maps validated Studio physics_config to Viro `physicsBody` prop. */
|
|
61
|
+
export declare function buildViroPhysicsBody(config: PhysicsBodyConfig, options?: BuildViroPhysicsBodyOptions): Record<string, unknown>;
|
|
62
|
+
/**
|
|
63
|
+
* Draggable Dynamic bodies need kinematic override during drag so the simulation
|
|
64
|
+
* doesn't fight the gesture.
|
|
65
|
+
*/
|
|
66
|
+
export declare function shouldUseKinematicPhysicsDrag(asset: {
|
|
67
|
+
is_draggable: boolean;
|
|
68
|
+
}, config: PhysicsBodyConfig | null): boolean;
|
|
69
|
+
export {};
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Studio physics_config and physics_world_config parsing and Viro prop building.
|
|
4
|
+
* Ported from studio-go/domain/physicsConfig.ts — no zod dependency.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.parsePhysicsWorldConfig = parsePhysicsWorldConfig;
|
|
8
|
+
exports.parsePhysicsBodyConfig = parsePhysicsBodyConfig;
|
|
9
|
+
exports.buildViroPhysicsWorld = buildViroPhysicsWorld;
|
|
10
|
+
exports.buildViroPhysicsBody = buildViroPhysicsBody;
|
|
11
|
+
exports.shouldUseKinematicPhysicsDrag = shouldUseKinematicPhysicsDrag;
|
|
12
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
13
|
+
function isVec3(v) {
|
|
14
|
+
return Array.isArray(v) && v.length === 3 && v.every((n) => typeof n === "number");
|
|
15
|
+
}
|
|
16
|
+
function parseShape(raw) {
|
|
17
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
18
|
+
return undefined;
|
|
19
|
+
const r = raw;
|
|
20
|
+
if (r.type === "Box" && Array.isArray(r.params) && r.params.length === 3) {
|
|
21
|
+
return { type: "Box", params: r.params };
|
|
22
|
+
}
|
|
23
|
+
if (r.type === "Sphere" && Array.isArray(r.params) && r.params.length >= 1) {
|
|
24
|
+
return { type: "Sphere", params: [r.params[0]] };
|
|
25
|
+
}
|
|
26
|
+
if (r.type === "Compound" && Array.isArray(r.children)) {
|
|
27
|
+
const children = r.children.filter((c) => {
|
|
28
|
+
if (!c || typeof c !== "object")
|
|
29
|
+
return false;
|
|
30
|
+
const ch = c;
|
|
31
|
+
return (ch.type === "Box" || ch.type === "Sphere") && Array.isArray(ch.params) && isVec3(ch.position);
|
|
32
|
+
});
|
|
33
|
+
if (children.length > 0)
|
|
34
|
+
return { type: "Compound", children };
|
|
35
|
+
}
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
function mapShapeToViro(shape) {
|
|
39
|
+
if (shape.type === "Box")
|
|
40
|
+
return { type: "Box", params: [...shape.params] };
|
|
41
|
+
if (shape.type === "Sphere")
|
|
42
|
+
return { type: "Sphere", params: [...shape.params] };
|
|
43
|
+
return {
|
|
44
|
+
type: "Compound",
|
|
45
|
+
params: [],
|
|
46
|
+
children: shape.children.map((c) => {
|
|
47
|
+
const base = { type: c.type, params: [...c.params], position: [...c.position] };
|
|
48
|
+
if (c.rotation)
|
|
49
|
+
base.rotation = [...c.rotation];
|
|
50
|
+
return base;
|
|
51
|
+
}),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function normalizeTorque(torque) {
|
|
55
|
+
if (Array.isArray(torque[0])) {
|
|
56
|
+
return torque.reduce((acc, t) => [acc[0] + t[0], acc[1] + t[1], acc[2] + t[2]], [0, 0, 0]);
|
|
57
|
+
}
|
|
58
|
+
return [...torque];
|
|
59
|
+
}
|
|
60
|
+
function normalizeForce(force) {
|
|
61
|
+
const arr = Array.isArray(force) ? force : [force];
|
|
62
|
+
return arr.map((f) => ({
|
|
63
|
+
value: [...f.value],
|
|
64
|
+
position: f.position != null ? [...f.position] : undefined,
|
|
65
|
+
}));
|
|
66
|
+
}
|
|
67
|
+
// ─── Public API ───────────────────────────────────────────────────────────────
|
|
68
|
+
/**
|
|
69
|
+
* Parses `scene.physics_world_config` JSON. Returns null if missing or invalid.
|
|
70
|
+
*/
|
|
71
|
+
function parsePhysicsWorldConfig(raw) {
|
|
72
|
+
if (raw == null || typeof raw !== "object" || Array.isArray(raw))
|
|
73
|
+
return null;
|
|
74
|
+
const r = raw;
|
|
75
|
+
try {
|
|
76
|
+
return {
|
|
77
|
+
enabled: typeof r.enabled === "boolean" ? r.enabled : false,
|
|
78
|
+
gravity: isVec3(r.gravity) ? r.gravity : [0, -9.8, 0],
|
|
79
|
+
drawBounds: typeof r.drawBounds === "boolean" ? r.drawBounds : false,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Parses `asset.physics_config` JSON. Returns null if missing or invalid.
|
|
88
|
+
*/
|
|
89
|
+
function parsePhysicsBodyConfig(raw) {
|
|
90
|
+
if (raw == null || typeof raw !== "object" || Array.isArray(raw))
|
|
91
|
+
return null;
|
|
92
|
+
const r = raw;
|
|
93
|
+
try {
|
|
94
|
+
const type = (["Dynamic", "Kinematic", "Static"].includes(r.type)
|
|
95
|
+
? r.type
|
|
96
|
+
: undefined);
|
|
97
|
+
if (!type)
|
|
98
|
+
return null;
|
|
99
|
+
const mass = typeof r.mass === "number" ? r.mass : 0;
|
|
100
|
+
const config = {
|
|
101
|
+
enabled: typeof r.enabled === "boolean" ? r.enabled : true,
|
|
102
|
+
type,
|
|
103
|
+
mass,
|
|
104
|
+
};
|
|
105
|
+
const shape = parseShape(r.shape);
|
|
106
|
+
if (shape)
|
|
107
|
+
config.shape = shape;
|
|
108
|
+
if (typeof r.restitution === "number")
|
|
109
|
+
config.restitution = r.restitution;
|
|
110
|
+
if (typeof r.friction === "number")
|
|
111
|
+
config.friction = r.friction;
|
|
112
|
+
if (typeof r.useGravity === "boolean")
|
|
113
|
+
config.useGravity = r.useGravity;
|
|
114
|
+
if (typeof r.viroTag === "string")
|
|
115
|
+
config.viroTag = r.viroTag;
|
|
116
|
+
if (isVec3(r.velocity))
|
|
117
|
+
config.velocity = r.velocity;
|
|
118
|
+
if (r.torque != null)
|
|
119
|
+
config.torque = r.torque;
|
|
120
|
+
if (r.force != null)
|
|
121
|
+
config.force = r.force;
|
|
122
|
+
return config;
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/** Viro `ViroARScene` physicsWorld prop. */
|
|
129
|
+
function buildViroPhysicsWorld(config) {
|
|
130
|
+
return {
|
|
131
|
+
gravity: [...config.gravity],
|
|
132
|
+
...(config.drawBounds ? { drawBounds: true } : {}),
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
/** Maps validated Studio physics_config to Viro `physicsBody` prop. */
|
|
136
|
+
function buildViroPhysicsBody(config, options) {
|
|
137
|
+
const kinematicDrag = options?.kinematicDragOverride === true && config.type === "Dynamic" && config.enabled;
|
|
138
|
+
const type = kinematicDrag ? "Kinematic" : config.type;
|
|
139
|
+
const mass = kinematicDrag ? 0 : config.mass;
|
|
140
|
+
const shape = mapShapeToViro(config.shape ?? { type: "Box", params: [1, 1, 1] });
|
|
141
|
+
const body = { type, mass, shape, enabled: config.enabled };
|
|
142
|
+
if (config.restitution !== undefined)
|
|
143
|
+
body.restitution = config.restitution;
|
|
144
|
+
if (config.friction !== undefined)
|
|
145
|
+
body.friction = config.friction;
|
|
146
|
+
if (config.useGravity !== undefined)
|
|
147
|
+
body.useGravity = kinematicDrag ? false : config.useGravity;
|
|
148
|
+
if (config.velocity !== undefined)
|
|
149
|
+
body.velocity = [...config.velocity];
|
|
150
|
+
if (config.torque !== undefined)
|
|
151
|
+
body.torque = normalizeTorque(config.torque);
|
|
152
|
+
if (config.force !== undefined)
|
|
153
|
+
body.force = normalizeForce(config.force);
|
|
154
|
+
return body;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Draggable Dynamic bodies need kinematic override during drag so the simulation
|
|
158
|
+
* doesn't fight the gesture.
|
|
159
|
+
*/
|
|
160
|
+
function shouldUseKinematicPhysicsDrag(asset, config) {
|
|
161
|
+
return (asset.is_draggable === true &&
|
|
162
|
+
config != null &&
|
|
163
|
+
config.enabled === true &&
|
|
164
|
+
config.type === "Dynamic");
|
|
165
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { StudioAnimation, StudioSceneFunction } from "../types";
|
|
2
|
+
type SceneNavigator = any;
|
|
3
|
+
/**
|
|
4
|
+
* Single dispatcher for all scene function types.
|
|
5
|
+
* Used by onClick, onCollision, and on_load_function triggers.
|
|
6
|
+
*/
|
|
7
|
+
export declare function executeFunctionWithRelations(fn: StudioSceneFunction, sceneNavigator: SceneNavigator | undefined, animations: StudioAnimation[], onAnimationTrigger?: (targetAssetId: string, animationKey: string) => void, depth?: number, onSceneChange?: (sceneId: string, sceneName: string) => void): void;
|
|
8
|
+
/**
|
|
9
|
+
* Executes the scene's on_load_function if set.
|
|
10
|
+
*/
|
|
11
|
+
export declare function executeOnLoadFunction(functionId: string, functions: StudioSceneFunction[], sceneNavigator: SceneNavigator | undefined, animations: StudioAnimation[], onAnimationTrigger?: (targetAssetId: string, animationKey: string) => void, onSceneChange?: (sceneId: string, sceneName: string) => void): void;
|
|
12
|
+
export {};
|