@babylonjs/core 6.46.1 → 6.48.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.
Files changed (72) hide show
  1. package/Buffers/buffer.align.d.ts +3 -3
  2. package/Buffers/buffer.align.js +1 -1
  3. package/Buffers/buffer.align.js.map +1 -1
  4. package/Engines/Native/nativeInterfaces.d.ts +1 -0
  5. package/Engines/Native/nativeInterfaces.js.map +1 -1
  6. package/Engines/engine.js +9 -9
  7. package/Engines/engine.js.map +1 -1
  8. package/Engines/engineFeatures.d.ts +2 -2
  9. package/Engines/engineFeatures.js.map +1 -1
  10. package/Engines/nativeEngine.d.ts +1 -0
  11. package/Engines/nativeEngine.js +21 -1
  12. package/Engines/nativeEngine.js.map +1 -1
  13. package/Engines/nullEngine.js +1 -1
  14. package/Engines/nullEngine.js.map +1 -1
  15. package/Engines/thinEngine.d.ts +5 -3
  16. package/Engines/thinEngine.js +53 -43
  17. package/Engines/thinEngine.js.map +1 -1
  18. package/Engines/webgpuEngine.js +1 -1
  19. package/Engines/webgpuEngine.js.map +1 -1
  20. package/Loading/sceneLoader.js +2 -1
  21. package/Loading/sceneLoader.js.map +1 -1
  22. package/Materials/Node/Blocks/posterizeBlock.js +1 -0
  23. package/Materials/Node/Blocks/posterizeBlock.js.map +1 -1
  24. package/Maths/index.d.ts +1 -0
  25. package/Maths/index.js +1 -0
  26. package/Maths/index.js.map +1 -1
  27. package/Maths/math.vector.functions.d.ts +22 -0
  28. package/Maths/math.vector.functions.js +28 -0
  29. package/Maths/math.vector.functions.js.map +1 -0
  30. package/Meshes/Node/Blocks/debugBlock.d.ts +1 -1
  31. package/Meshes/Node/Blocks/debugBlock.js +16 -2
  32. package/Meshes/Node/Blocks/debugBlock.js.map +1 -1
  33. package/Meshes/Node/Blocks/geometryPosterizeBlock.js +26 -1
  34. package/Meshes/Node/Blocks/geometryPosterizeBlock.js.map +1 -1
  35. package/Meshes/mesh.js +12 -0
  36. package/Meshes/mesh.js.map +1 -1
  37. package/Misc/khronosTextureContainer2Worker.js +1 -1
  38. package/Misc/khronosTextureContainer2Worker.js.map +1 -1
  39. package/NOTICE.md +10 -0
  40. package/Particles/IParticleSystem.d.ts +3 -1
  41. package/Particles/IParticleSystem.js.map +1 -1
  42. package/Particles/particleSystem.d.ts +1 -1
  43. package/Particles/particleSystem.js +17 -1
  44. package/Particles/particleSystem.js.map +1 -1
  45. package/Particles/thinParticleSystem.d.ts +5 -3
  46. package/Particles/thinParticleSystem.js +6 -4
  47. package/Particles/thinParticleSystem.js.map +1 -1
  48. package/Physics/physicsPointProximityQuery.d.ts +1 -1
  49. package/Physics/physicsPointProximityQuery.js.map +1 -1
  50. package/Physics/v2/Plugins/havokPlugin.js +3 -1
  51. package/Physics/v2/Plugins/havokPlugin.js.map +1 -1
  52. package/Physics/v2/physicsBody.d.ts +6 -1
  53. package/Physics/v2/physicsBody.js +7 -0
  54. package/Physics/v2/physicsBody.js.map +1 -1
  55. package/Physics/v2/ragdoll.d.ts +16 -5
  56. package/Physics/v2/ragdoll.js +91 -42
  57. package/Physics/v2/ragdoll.js.map +1 -1
  58. package/XR/features/WebXRAbstractFeature.d.ts +2 -1
  59. package/XR/features/WebXRAbstractFeature.js +3 -2
  60. package/XR/features/WebXRAbstractFeature.js.map +1 -1
  61. package/XR/features/WebXRControllerPointerSelection.d.ts +10 -0
  62. package/XR/features/WebXRControllerPointerSelection.js +41 -20
  63. package/XR/features/WebXRControllerPointerSelection.js.map +1 -1
  64. package/XR/features/WebXRControllerTeleportation.d.ts +1 -0
  65. package/XR/features/WebXRControllerTeleportation.js +7 -2
  66. package/XR/features/WebXRControllerTeleportation.js.map +1 -1
  67. package/assetContainer.js +1 -1
  68. package/assetContainer.js.map +1 -1
  69. package/assets/Basis/basis_transcoder.js +24 -0
  70. package/assets/Draco/draco_decoder_gltf.js +35 -0
  71. package/assets/Draco/draco_wasm_wrapper_gltf.js +116 -0
  72. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"ragdoll.js","sourceRoot":"","sources":["../../../../../dev/core/src/Physics/v2/ragdoll.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Skeleton } from \"../../Bones/skeleton\";\r\nimport { Vector3, Matrix, TmpVectors } from \"../../Maths/math.vector\";\r\nimport { Quaternion } from \"../../Maths/math.vector\";\r\nimport type { Scene } from \"../../scene\";\r\nimport { PhysicsAggregate } from \"./physicsAggregate\";\r\nimport { BallAndSocketConstraint } from \"./physicsConstraint\";\r\nimport type { Mesh } from \"../../Meshes/mesh\";\r\nimport { Axis, Space } from \"core/Maths/math.axis\";\r\nimport { PhysicsShapeType, PhysicsConstraintType } from \"./IPhysicsEnginePlugin\";\r\nimport type { Nullable } from \"../../types\";\r\nimport type { Bone } from \"../../Bones/bone\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { TransformNode } from \"../../Meshes/transformNode\";\r\n\r\n/**\r\n * Ragdoll bone properties\r\n * @experimental\r\n */\r\nexport class RagdollBoneProperties {\r\n /**\r\n * Width of the box shape\r\n */\r\n width?: number;\r\n /**\r\n * depth of the box shape\r\n */\r\n depth?: number;\r\n /**\r\n * height of the box shape\r\n */\r\n height?: number;\r\n /**\r\n * size that will be used of width, depth and height of the shape box\r\n */\r\n size?: number;\r\n /**\r\n * Type of Physics Constraint used between bones\r\n */\r\n joint?: number | undefined;\r\n /**\r\n * Main rotation axis used by the constraint, in local space\r\n */\r\n rotationAxis?: Vector3;\r\n /**\r\n * Minimum rotation angle value\r\n */\r\n min?: number;\r\n /**\r\n * Maximum rotation angle value\r\n */\r\n max?: number;\r\n /**\r\n * Offset along local axis\r\n */\r\n boxOffset?: number;\r\n /**\r\n * Axis that need an offset\r\n */\r\n boneOffsetAxis?: Vector3;\r\n}\r\n\r\n/**\r\n * Ragdoll for Physics V2\r\n * @experimental\r\n */\r\nexport class Ragdoll {\r\n private _skeleton: Skeleton;\r\n private _scene: Scene;\r\n private _mesh: Mesh;\r\n private _config: any;\r\n private _boxConfigs: Array<RagdollBoneProperties> = new Array<RagdollBoneProperties>();\r\n\r\n private _bones: Array<Bone> = new Array<Bone>();\r\n private _initialRotation: Array<Quaternion> = new Array<Quaternion>();\r\n private _boneNames: string[] = [];\r\n private _transforms: Array<TransformNode> = new Array<TransformNode>();\r\n private _aggregates: Array<PhysicsAggregate> = new Array<PhysicsAggregate>();\r\n private _ragdollMode: boolean = false;\r\n private _rootBoneName: string = \"\";\r\n private _rootBoneIndex: number = -1;\r\n private _mass: number = 10;\r\n private _restitution: number = 0;\r\n\r\n /**\r\n * Pause synchronization between physics and bone position/orientation\r\n */\r\n public pauseSync: boolean = false;\r\n\r\n private _putBoxesInBoneCenter: boolean;\r\n private _defaultJoint: number = PhysicsConstraintType.HINGE;\r\n private _defaultJointMin: number = -90;\r\n private _defaultJointMax: number = 90;\r\n\r\n private _boneOffsetAxis: Vector3;\r\n\r\n /**\r\n * Construct a new Ragdoll object. Once ready, it can be made dynamic by calling `Ragdoll` method\r\n * @param skeleton The skeleton containing bones to be physicalized\r\n * @param mesh The mesh used by the skeleton\r\n * @param config an array of `RagdollBoneProperties` corresponding to bones and their properties used to instanciate physics bodies\r\n */\r\n constructor(skeleton: Skeleton, mesh: Mesh, config: RagdollBoneProperties[]) {\r\n this._skeleton = skeleton;\r\n this._scene = skeleton.getScene();\r\n this._mesh = mesh;\r\n this._config = config; // initial, user defined box configs. May have several box configs jammed into 1 index.\r\n this._boxConfigs = []; // final box configs. Every element is a separate box config (this.config may have several configs jammed into 1 index).\r\n this._putBoxesInBoneCenter = false;\r\n this._defaultJoint = PhysicsConstraintType.HINGE;\r\n this._boneOffsetAxis = Axis.Y;\r\n }\r\n\r\n private _createColliders(): void {\r\n this._mesh.computeWorldMatrix();\r\n\r\n const config = this._config;\r\n for (let i = 0; i < config.length; i++) {\r\n const boneNames = config[i].bone !== undefined ? [config[i].bone] : config[i].bones;\r\n\r\n for (let ii = 0; ii < boneNames.length; ii++) {\r\n const currentBone = this._skeleton.bones[this._skeleton.getBoneIndexByName(boneNames[ii])];\r\n if (currentBone == undefined) {\r\n return;\r\n }\r\n\r\n // First define the box dimensions, so we can then use them when calling CreateBox().\r\n const currentRagdollBoneProperties: RagdollBoneProperties = {\r\n width: this._config[i].width,\r\n depth: this._config[i].depth,\r\n height: this._config[i].height,\r\n size: this._config[i].size,\r\n };\r\n\r\n currentRagdollBoneProperties.width = currentRagdollBoneProperties.width ?? currentRagdollBoneProperties.size;\r\n currentRagdollBoneProperties.depth = currentRagdollBoneProperties.depth ?? currentRagdollBoneProperties.size;\r\n currentRagdollBoneProperties.height = currentRagdollBoneProperties.height ?? currentRagdollBoneProperties.size;\r\n const transform = new TransformNode(boneNames[ii] + \"_transform\", this._scene);\r\n\r\n // Define the rest of the box properties.\r\n currentRagdollBoneProperties.joint = config[i].joint !== undefined ? config[i].joint : this._defaultJoint;\r\n currentRagdollBoneProperties.rotationAxis = config[i].rotationAxis !== undefined ? config[i].rotationAxis : Axis.X;\r\n currentRagdollBoneProperties.min = config[i].min !== undefined ? config[i].min : this._defaultJointMin;\r\n currentRagdollBoneProperties.max = config[i].max !== undefined ? config[i].max : this._defaultJointMax;\r\n\r\n // Offset value.\r\n let boxOffset = 0;\r\n if ((config[i].putBoxInBoneCenter !== undefined && config[i].putBoxInBoneCenter) || this._putBoxesInBoneCenter) {\r\n if (currentBone.length === undefined) {\r\n Logger.Log(\"The length property is not defined for bone \" + currentBone.name);\r\n }\r\n boxOffset = currentBone.length / 2;\r\n } else if (config[i].boxOffset !== undefined) {\r\n boxOffset = config[i].boxOffset;\r\n }\r\n currentRagdollBoneProperties.boxOffset = boxOffset;\r\n\r\n // Offset axis.\r\n const boneOffsetAxis = config[i].boneOffsetAxis !== undefined ? config[i].boneOffsetAxis : this._boneOffsetAxis;\r\n const boneDir = currentBone.getDirection(boneOffsetAxis, this._mesh);\r\n currentRagdollBoneProperties.boneOffsetAxis = boneOffsetAxis;\r\n\r\n transform.position = currentBone.getAbsolutePosition(this._mesh).add(boneDir.scale(boxOffset));\r\n\r\n const mass = config[i].mass !== undefined ? config[i].mass : this._mass;\r\n const restitution = config[i].restitution !== undefined ? config[i].restitution : this._restitution;\r\n const aggregate = new PhysicsAggregate(\r\n transform,\r\n PhysicsShapeType.BOX,\r\n {\r\n mass: mass,\r\n restitution: restitution,\r\n friction: 0.6,\r\n extents: new Vector3(currentRagdollBoneProperties.width, currentRagdollBoneProperties.height, currentRagdollBoneProperties.depth),\r\n },\r\n this._scene\r\n );\r\n aggregate.body.setCollisionCallbackEnabled(true);\r\n aggregate.body.disablePreStep = false;\r\n this._aggregates.push(aggregate);\r\n this._bones.push(currentBone);\r\n this._boneNames.push(currentBone.name);\r\n this._transforms.push(transform);\r\n this._boxConfigs.push(currentRagdollBoneProperties);\r\n this._initialRotation.push(currentBone.getRotationQuaternion(Space.WORLD));\r\n }\r\n }\r\n }\r\n\r\n private _initJoints(): void {\r\n this._mesh.computeWorldMatrix();\r\n for (let i = 0; i < this._bones.length; i++) {\r\n // The root bone has no joints.\r\n if (i == this._rootBoneIndex) continue;\r\n\r\n const nearestParent = this._findNearestParent(i);\r\n\r\n if (nearestParent == null) {\r\n Logger.Warn(\"Couldn't find a nearest parent bone in the configs for bone called \" + this._boneNames[i]);\r\n return;\r\n }\r\n\r\n const boneParentIndex = this._boneNames.indexOf(nearestParent.name);\r\n\r\n let distanceFromParentBoxToBone = this._bones[i].getAbsolutePosition(this._mesh).subtract(this._transforms[boneParentIndex].position);\r\n\r\n const wmat = this._transforms[boneParentIndex].computeWorldMatrix();\r\n const invertedWorldMat = Matrix.Invert(wmat);\r\n distanceFromParentBoxToBone = Vector3.TransformCoordinates(this._bones[i].getAbsolutePosition(this._mesh), invertedWorldMat);\r\n\r\n const boneAbsPos = this._bones[i].getAbsolutePosition(this._mesh);\r\n const boxAbsPos = this._transforms[i].position.clone();\r\n const myConnectedPivot = boneAbsPos.subtract(boxAbsPos);\r\n\r\n const joint = new BallAndSocketConstraint(\r\n distanceFromParentBoxToBone,\r\n myConnectedPivot,\r\n this._boxConfigs[i].rotationAxis!,\r\n this._boxConfigs[i].rotationAxis!,\r\n this._scene\r\n );\r\n this._aggregates[boneParentIndex].body.addConstraint(this._aggregates[i].body, joint);\r\n }\r\n }\r\n\r\n private _syncBonesAndBoxes(): void {\r\n if (this.pauseSync) {\r\n return;\r\n }\r\n\r\n if (this._ragdollMode) {\r\n this._bones[this._rootBoneIndex].getDirectionToRef(this._boxConfigs[this._rootBoneIndex].boneOffsetAxis!, this._mesh, TmpVectors.Vector3[0]);\r\n TmpVectors.Vector3[0].scaleInPlace(this._boxConfigs[this._rootBoneIndex].boxOffset!);\r\n this._bones[this._rootBoneIndex].getAbsolutePositionToRef(this._mesh, TmpVectors.Vector3[1]);\r\n TmpVectors.Vector3[1].addInPlace(TmpVectors.Vector3[0]);\r\n\r\n this._bones[this._rootBoneIndex].setAbsolutePosition(this._transforms[this._rootBoneIndex].position, this._mesh);\r\n this._addImpostorRotationToBone(this._rootBoneIndex);\r\n\r\n const rootPos = this._aggregates[this._rootBoneIndex].body.transformNode.position;\r\n\r\n // Move the mesh, to guarantee alignment between root bone and impostor box position\r\n TmpVectors.Vector3[1].subtractToRef(rootPos, TmpVectors.Vector3[0]);\r\n this._mesh.position.subtractToRef(TmpVectors.Vector3[0], this._mesh.position);\r\n\r\n for (let i = 0; i < this._bones.length; i++) {\r\n if (i == this._rootBoneIndex) continue;\r\n this._addImpostorRotationToBone(i);\r\n }\r\n }\r\n }\r\n\r\n private _addImpostorRotationToBone(boneIndex: number): void {\r\n const qmesh = this._mesh.rotationQuaternion ?? Quaternion.FromEulerAngles(this._mesh.rotation.x, this._mesh.rotation.y, this._mesh.rotation.z);\r\n const qbind = this._initialRotation[boneIndex];\r\n const qphys = this._aggregates[boneIndex].body?.transformNode?.rotationQuaternion!;\r\n\r\n // TmpVectors.Quaternion[1] = mesh.rotation * this._initialRotation[boneIndex]\r\n // TmpVectors.Quaternion[0] = body.rotation * TmpVectors.Quaternion[1]\r\n qmesh.multiplyToRef(qbind, TmpVectors.Quaternion[1]);\r\n qphys.multiplyToRef(TmpVectors.Quaternion[1], TmpVectors.Quaternion[0]);\r\n\r\n this._bones[boneIndex].setRotationQuaternion(TmpVectors.Quaternion[0], Space.WORLD, this._mesh);\r\n }\r\n\r\n // Return true if root bone is valid/exists in this.bonesNames. false otherwise.\r\n private _defineRootBone(): boolean {\r\n const skeletonRoots = this._skeleton.getChildren();\r\n if (skeletonRoots.length != 1) {\r\n Logger.Log(\"Ragdoll creation failed: there can only be one root in the skeleton.\");\r\n return false;\r\n }\r\n\r\n this._rootBoneName = skeletonRoots[0].name;\r\n this._rootBoneIndex = this._boneNames.indexOf(this._rootBoneName);\r\n if (this._rootBoneIndex == -1) {\r\n Logger.Log(\"Ragdoll creation failed: the array boneNames doesn't have the root bone. The root bone is \" + this._skeleton.getChildren());\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _findNearestParent(boneIndex: number): any {\r\n let nearestParent: Nullable<Bone> | undefined = this._bones[boneIndex].getParent();\r\n do {\r\n if (nearestParent != null && this._boneNames.includes(nearestParent.name)) {\r\n break;\r\n }\r\n\r\n nearestParent = nearestParent?.getParent();\r\n } while (nearestParent != null);\r\n\r\n return nearestParent;\r\n }\r\n\r\n private _init() {\r\n // detach bones with link transform to let physics have control\r\n this._skeleton.bones.forEach((bone) => {\r\n bone.linkTransformNode(null);\r\n });\r\n\r\n this._createColliders();\r\n\r\n // If this.defineRootBone() returns false... there is not root bone.\r\n if (!this._defineRootBone()) {\r\n return;\r\n }\r\n\r\n this._initJoints();\r\n this._scene.registerBeforeRender(() => {\r\n this._syncBonesAndBoxes();\r\n });\r\n }\r\n\r\n /**\r\n * Enable ragdoll mode. Create physics objects and make them dynamic.\r\n */\r\n public ragdoll(): void {\r\n if (!this._ragdollMode) {\r\n this._ragdollMode = true;\r\n this._init();\r\n }\r\n }\r\n\r\n /**\r\n * Dispose resources and remove physics objects\r\n */\r\n dispose(): void {\r\n this._aggregates.forEach((aggregate: PhysicsAggregate) => {\r\n aggregate.dispose();\r\n });\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"ragdoll.js","sourceRoot":"","sources":["../../../../../dev/core/src/Physics/v2/ragdoll.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Skeleton } from \"../../Bones/skeleton\";\r\nimport { Vector3, Matrix, TmpVectors, Quaternion } from \"../../Maths/math.vector\";\r\nimport type { Scene } from \"../../scene\";\r\nimport { PhysicsAggregate } from \"./physicsAggregate\";\r\nimport { PhysicsConstraint } from \"./physicsConstraint\";\r\nimport type { Mesh } from \"../../Meshes/mesh\";\r\nimport { Axis, Space } from \"core/Maths/math.axis\";\r\nimport { PhysicsShapeType, PhysicsConstraintType, PhysicsMotionType } from \"./IPhysicsEnginePlugin\";\r\nimport type { Nullable } from \"../../types\";\r\nimport type { Bone } from \"../../Bones/bone\";\r\nimport { Logger } from \"../../Misc/logger\";\r\nimport { TransformNode } from \"../../Meshes/transformNode\";\r\n\r\n/**\r\n * Ragdoll bone properties\r\n * @experimental\r\n */\r\nexport class RagdollBoneProperties {\r\n /**\r\n * Width of the box shape\r\n */\r\n width?: number;\r\n /**\r\n * depth of the box shape\r\n */\r\n depth?: number;\r\n /**\r\n * height of the box shape\r\n */\r\n height?: number;\r\n /**\r\n * size that will be used of width, depth and height of the shape box\r\n */\r\n size?: number;\r\n /**\r\n * Type of Physics Constraint used between bones\r\n */\r\n joint?: number | undefined;\r\n /**\r\n * Main rotation axis used by the constraint, in local space\r\n */\r\n rotationAxis?: Vector3;\r\n /**\r\n * Minimum rotation angle value\r\n */\r\n min?: number;\r\n /**\r\n * Maximum rotation angle value\r\n */\r\n max?: number;\r\n /**\r\n * Offset along local axis\r\n */\r\n boxOffset?: number;\r\n /**\r\n * Axis that need an offset\r\n */\r\n boneOffsetAxis?: Vector3;\r\n}\r\n\r\n/**\r\n * Ragdoll for Physics V2\r\n * @experimental\r\n */\r\nexport class Ragdoll {\r\n private _skeleton: Skeleton;\r\n private _scene: Scene;\r\n private _rootTransformNode: Mesh | TransformNode;\r\n private _config: any;\r\n private _boxConfigs: Array<RagdollBoneProperties> = new Array<RagdollBoneProperties>();\r\n private _joints: Array<PhysicsConstraint> = new Array<PhysicsConstraint>();\r\n private _bones: Array<Bone> = new Array<Bone>();\r\n private _initialRotation: Array<Quaternion> = new Array<Quaternion>();\r\n // without mesh transform, to figure out later\r\n private _initialRotation2: Array<Quaternion> = new Array<Quaternion>();\r\n private _boneNames: string[] = [];\r\n private _transforms: Array<TransformNode> = new Array<TransformNode>();\r\n private _aggregates: Array<PhysicsAggregate> = new Array<PhysicsAggregate>();\r\n private _ragdollMode: boolean = false;\r\n private _rootBoneName: string = \"\";\r\n private _rootBoneIndex: number = -1;\r\n private _mass: number = 10;\r\n private _restitution: number = 0;\r\n\r\n /**\r\n * Pause synchronization between physics and bone position/orientation\r\n */\r\n public pauseSync: boolean = false;\r\n\r\n private _putBoxesInBoneCenter: boolean;\r\n private _defaultJoint: number = PhysicsConstraintType.HINGE;\r\n private _defaultJointMin: number = -90;\r\n private _defaultJointMax: number = 90;\r\n\r\n /**\r\n * Construct a new Ragdoll object. Once ready, it can be made dynamic by calling `Ragdoll` method\r\n * @param skeleton The skeleton containing bones to be physicalized\r\n * @param rootTransformNode The mesh or its transform used by the skeleton\r\n * @param config an array of `RagdollBoneProperties` corresponding to bones and their properties used to instanciate physics bodies\r\n */\r\n constructor(skeleton: Skeleton, rootTransformNode: Mesh | TransformNode, config: RagdollBoneProperties[]) {\r\n this._skeleton = skeleton;\r\n this._scene = skeleton.getScene();\r\n this._rootTransformNode = rootTransformNode;\r\n this._config = config; // initial, user defined box configs. May have several box configs jammed into 1 index.\r\n this._boxConfigs = []; // final box configs. Every element is a separate box config (this.config may have several configs jammed into 1 index).\r\n this._putBoxesInBoneCenter = false;\r\n this._defaultJoint = PhysicsConstraintType.HINGE;\r\n\r\n this._init();\r\n }\r\n\r\n /**\r\n * Returns the aggregate corresponding to the ragdoll bone index\r\n * @param index ragdoll bone aggregate index\r\n * @returns the aggregate for the bone index for the root aggregate if index is invalid\r\n */\r\n public getAggregate(index: number): PhysicsAggregate {\r\n if (index < 0 || index >= this._aggregates.length) {\r\n return this._aggregates[this._rootBoneIndex];\r\n }\r\n return this._aggregates[index];\r\n }\r\n\r\n private _createColliders(): void {\r\n this._rootTransformNode.computeWorldMatrix();\r\n this._skeleton.computeAbsoluteMatrices(true);\r\n this._skeleton.prepare(true);\r\n\r\n const config = this._config;\r\n for (let i = 0; i < config.length; i++) {\r\n const boneNames = config[i].bone !== undefined ? [config[i].bone] : config[i].bones;\r\n\r\n for (let ii = 0; ii < boneNames.length; ii++) {\r\n const currentBone = this._skeleton.bones[this._skeleton.getBoneIndexByName(boneNames[ii])];\r\n if (currentBone == undefined) {\r\n return;\r\n }\r\n\r\n // First define the box dimensions, so we can then use them when calling CreateBox().\r\n const currentRagdollBoneProperties: RagdollBoneProperties = {\r\n width: this._config[i].width,\r\n depth: this._config[i].depth,\r\n height: this._config[i].height,\r\n size: this._config[i].size,\r\n };\r\n\r\n currentRagdollBoneProperties.width = currentRagdollBoneProperties.width ?? currentRagdollBoneProperties.size;\r\n currentRagdollBoneProperties.depth = currentRagdollBoneProperties.depth ?? currentRagdollBoneProperties.size;\r\n currentRagdollBoneProperties.height = currentRagdollBoneProperties.height ?? currentRagdollBoneProperties.size;\r\n const transform = new TransformNode(boneNames[ii] + \"_transform\", this._scene);\r\n\r\n // Define the rest of the box properties.\r\n currentRagdollBoneProperties.joint = config[i].joint !== undefined ? config[i].joint : this._defaultJoint;\r\n currentRagdollBoneProperties.rotationAxis = config[i].rotationAxis !== undefined ? config[i].rotationAxis : Axis.X;\r\n currentRagdollBoneProperties.min = config[i].min !== undefined ? config[i].min : this._defaultJointMin;\r\n currentRagdollBoneProperties.max = config[i].max !== undefined ? config[i].max : this._defaultJointMax;\r\n\r\n // Offset value.\r\n let boxOffset = 0;\r\n if ((config[i].putBoxInBoneCenter !== undefined && config[i].putBoxInBoneCenter) || this._putBoxesInBoneCenter) {\r\n if (currentBone.length === undefined) {\r\n Logger.Log(\"The length property is not defined for bone \" + currentBone.name);\r\n }\r\n boxOffset = currentBone.length / 2;\r\n } else if (config[i].boxOffset !== undefined) {\r\n boxOffset = config[i].boxOffset;\r\n }\r\n currentRagdollBoneProperties.boxOffset = boxOffset;\r\n\r\n // Offset axis.\r\n const boneOffsetAxis = config[i].boneOffsetAxis !== undefined ? config[i].boneOffsetAxis : Axis.Y;\r\n const boneDir = currentBone.getDirection(boneOffsetAxis, this._rootTransformNode);\r\n currentRagdollBoneProperties.boneOffsetAxis = boneOffsetAxis;\r\n\r\n transform.position = currentBone.getAbsolutePosition(this._rootTransformNode).add(boneDir.scale(boxOffset));\r\n\r\n const mass = config[i].mass !== undefined ? config[i].mass : this._mass;\r\n const restitution = config[i].restitution !== undefined ? config[i].restitution : this._restitution;\r\n const aggregate = new PhysicsAggregate(\r\n transform,\r\n PhysicsShapeType.BOX,\r\n {\r\n mass: mass,\r\n restitution: restitution,\r\n friction: 0.6,\r\n extents: new Vector3(currentRagdollBoneProperties.width, currentRagdollBoneProperties.height, currentRagdollBoneProperties.depth),\r\n },\r\n this._scene\r\n );\r\n aggregate.body.setCollisionCallbackEnabled(true);\r\n aggregate.body.disablePreStep = false;\r\n aggregate.body.setMotionType(PhysicsMotionType.ANIMATED);\r\n this._aggregates.push(aggregate);\r\n this._bones.push(currentBone);\r\n this._boneNames.push(currentBone.name);\r\n this._transforms.push(transform);\r\n this._boxConfigs.push(currentRagdollBoneProperties);\r\n this._initialRotation.push(currentBone.getRotationQuaternion(Space.WORLD, this._rootTransformNode));\r\n this._initialRotation2.push(currentBone.getRotationQuaternion(Space.WORLD));\r\n }\r\n }\r\n }\r\n\r\n private _initJoints(): void {\r\n this._rootTransformNode.computeWorldMatrix();\r\n for (let i = 0; i < this._bones.length; i++) {\r\n // The root bone has no joints.\r\n if (i == this._rootBoneIndex) continue;\r\n\r\n const nearestParent = this._findNearestParent(i);\r\n\r\n if (nearestParent == null) {\r\n Logger.Warn(\"Couldn't find a nearest parent bone in the configs for bone called \" + this._boneNames[i]);\r\n return;\r\n }\r\n\r\n const boneParentIndex = this._boneNames.indexOf(nearestParent.name);\r\n\r\n let distanceFromParentBoxToBone = this._bones[i].getAbsolutePosition(this._rootTransformNode).subtract(this._transforms[boneParentIndex].position);\r\n\r\n const wmat = this._transforms[boneParentIndex].computeWorldMatrix();\r\n const invertedWorldMat = Matrix.Invert(wmat);\r\n distanceFromParentBoxToBone = Vector3.TransformCoordinates(this._bones[i].getAbsolutePosition(this._rootTransformNode), invertedWorldMat);\r\n\r\n const boneAbsPos = this._bones[i].getAbsolutePosition(this._rootTransformNode);\r\n const boxAbsPos = this._transforms[i].position.clone();\r\n const myConnectedPivot = boneAbsPos.subtract(boxAbsPos);\r\n\r\n const joint = new PhysicsConstraint(\r\n PhysicsConstraintType.BALL_AND_SOCKET,\r\n {\r\n pivotA: distanceFromParentBoxToBone,\r\n pivotB: myConnectedPivot,\r\n axisA: this._boxConfigs[i].rotationAxis!,\r\n axisB: this._boxConfigs[i].rotationAxis!,\r\n collision: false,\r\n },\r\n this._scene\r\n );\r\n\r\n this._aggregates[boneParentIndex].body.addConstraint(this._aggregates[i].body, joint);\r\n joint.isEnabled = false;\r\n this._joints.push(joint);\r\n }\r\n }\r\n\r\n // set physics body orientation/position from bones\r\n private _syncBonesToPhysics(): void {\r\n const rootMatrix = this._rootTransformNode.getWorldMatrix();\r\n for (let i = 0; i < this._bones.length; i++) {\r\n // position\r\n const transform = this._aggregates[i].transformNode;\r\n const rootPos = this._bones[i].getAbsolutePosition();\r\n Vector3.TransformCoordinatesToRef(rootPos, rootMatrix, transform.position);\r\n\r\n // added offset\r\n this._bones[i].getDirectionToRef(this._boxConfigs[i].boneOffsetAxis!, this._rootTransformNode, TmpVectors.Vector3[0]);\r\n TmpVectors.Vector3[0].scaleInPlace(this._boxConfigs[i].boxOffset ?? 0);\r\n transform.position.addInPlace(TmpVectors.Vector3[0]);\r\n\r\n this._setBoneOrientationToBody(i);\r\n }\r\n }\r\n\r\n private _setBoneOrientationToBody(boneIndex: number): void {\r\n const transform = this._aggregates[boneIndex].transformNode;\r\n const bone = this._bones[boneIndex];\r\n this._initialRotation[boneIndex].conjugateToRef(TmpVectors.Quaternion[0]);\r\n bone.getRotationQuaternionToRef(Space.WORLD, this._rootTransformNode, TmpVectors.Quaternion[1]);\r\n TmpVectors.Quaternion[1].multiplyToRef(TmpVectors.Quaternion[0], transform.rotationQuaternion!);\r\n transform.rotationQuaternion!.normalize();\r\n }\r\n\r\n private _syncBonesAndBoxes(): void {\r\n if (this.pauseSync) {\r\n return;\r\n }\r\n\r\n if (this._ragdollMode) {\r\n this._setBodyOrientationToBone(this._rootBoneIndex);\r\n\r\n const rootPos = this._aggregates[this._rootBoneIndex].body.transformNode.position;\r\n this._rootTransformNode.getWorldMatrix().invertToRef(TmpVectors.Matrix[0]);\r\n\r\n Vector3.TransformCoordinatesToRef(rootPos, TmpVectors.Matrix[0], TmpVectors.Vector3[0]);\r\n this._bones[this._rootBoneIndex].setAbsolutePosition(TmpVectors.Vector3[0]);\r\n\r\n for (let i = 0; i < this._bones.length; i++) {\r\n if (i == this._rootBoneIndex) continue;\r\n this._setBodyOrientationToBone(i);\r\n }\r\n } else {\r\n this._syncBonesToPhysics();\r\n }\r\n }\r\n\r\n private _setBodyOrientationToBone(boneIndex: number): void {\r\n const qmesh =\r\n this._rootTransformNode.rotationQuaternion ??\r\n Quaternion.FromEulerAngles(this._rootTransformNode.rotation.x, this._rootTransformNode.rotation.y, this._rootTransformNode.rotation.z);\r\n const qbind = this._initialRotation2[boneIndex];\r\n const qphys = this._aggregates[boneIndex].body?.transformNode?.rotationQuaternion!;\r\n\r\n qmesh.multiplyToRef(qbind, TmpVectors.Quaternion[1]);\r\n qphys.multiplyToRef(TmpVectors.Quaternion[1], TmpVectors.Quaternion[0]);\r\n\r\n this._bones[boneIndex].setRotationQuaternion(TmpVectors.Quaternion[0], Space.WORLD, this._rootTransformNode);\r\n }\r\n\r\n // Return true if root bone is valid/exists in this.bonesNames. false otherwise.\r\n private _defineRootBone(): boolean {\r\n const skeletonRoots = this._skeleton.getChildren();\r\n if (skeletonRoots.length != 1) {\r\n Logger.Log(\"Ragdoll creation failed: there can only be one root in the skeleton.\");\r\n return false;\r\n }\r\n\r\n this._rootBoneName = skeletonRoots[0].name;\r\n this._rootBoneIndex = this._boneNames.indexOf(this._rootBoneName);\r\n if (this._rootBoneIndex == -1) {\r\n Logger.Log(\"Ragdoll creation failed: the array boneNames doesn't have the root bone. The root bone is \" + this._skeleton.getChildren());\r\n return false;\r\n }\r\n\r\n return true;\r\n }\r\n\r\n private _findNearestParent(boneIndex: number): any {\r\n let nearestParent: Nullable<Bone> | undefined = this._bones[boneIndex].getParent();\r\n do {\r\n if (nearestParent != null && this._boneNames.includes(nearestParent.name)) {\r\n break;\r\n }\r\n\r\n nearestParent = nearestParent?.getParent();\r\n } while (nearestParent != null);\r\n\r\n return nearestParent;\r\n }\r\n\r\n private _init() {\r\n this._createColliders();\r\n\r\n // If this.defineRootBone() returns ... there is not root bone.\r\n if (!this._defineRootBone()) {\r\n return;\r\n }\r\n\r\n this._initJoints();\r\n this._scene.registerBeforeRender(() => {\r\n this._syncBonesAndBoxes();\r\n });\r\n this._syncBonesToPhysics();\r\n }\r\n\r\n /**\r\n * Enable ragdoll mode. Create physics objects and make them dynamic.\r\n */\r\n public ragdoll(): void {\r\n this._ragdollMode = true;\r\n // detach bones with link transform to let physics have control\r\n this._skeleton.bones.forEach((bone) => {\r\n bone.linkTransformNode(null);\r\n });\r\n for (let i = 0; i < this._joints.length; i++) {\r\n this._joints[i].isEnabled = true;\r\n }\r\n for (let i = 0; i < this._aggregates.length; i++) {\r\n this._aggregates[i].body.setMotionType(PhysicsMotionType.DYNAMIC);\r\n }\r\n }\r\n\r\n /**\r\n * Dispose resources and remove physics objects\r\n */\r\n dispose(): void {\r\n this._aggregates.forEach((aggregate: PhysicsAggregate) => {\r\n aggregate.dispose();\r\n });\r\n }\r\n}\r\n"]}
@@ -74,8 +74,9 @@ export declare abstract class WebXRAbstractFeature implements IWebXRFeature {
74
74
  * This is used to register callbacks that will automatically be removed when detach is called.
75
75
  * @param observable the observable to which the observer will be attached
76
76
  * @param callback the callback to register
77
+ * @param insertFirst should the callback be executed as soon as it is registered
77
78
  */
78
- protected _addNewAttachObserver<T>(observable: Observable<T>, callback: (eventData: T, eventState: EventState) => void): void;
79
+ protected _addNewAttachObserver<T>(observable: Observable<T>, callback: (eventData: T, eventState: EventState) => void, insertFirst?: boolean): void;
79
80
  /**
80
81
  * Code in this function will be executed on each xrFrame received from the browser.
81
82
  * This function will not execute after the feature is detached.
@@ -126,11 +126,12 @@ export class WebXRAbstractFeature {
126
126
  * This is used to register callbacks that will automatically be removed when detach is called.
127
127
  * @param observable the observable to which the observer will be attached
128
128
  * @param callback the callback to register
129
+ * @param insertFirst should the callback be executed as soon as it is registered
129
130
  */
130
- _addNewAttachObserver(observable, callback) {
131
+ _addNewAttachObserver(observable, callback, insertFirst) {
131
132
  this._removeOnDetach.push({
132
133
  observable,
133
- observer: observable.add(callback),
134
+ observer: observable.add(callback, undefined, insertFirst),
134
135
  });
135
136
  }
136
137
  }
@@ -1 +1 @@
1
- {"version":3,"file":"WebXRAbstractFeature.js","sourceRoot":"","sources":["../../../../../dev/core/src/XR/features/WebXRAbstractFeature.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IWebXRFeature } from \"../webXRFeaturesManager\";\r\nimport type { Observer, EventState } from \"../../Misc/observable\";\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport type { Nullable } from \"../../types\";\r\nimport type { WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\n/**\r\n * This is the base class for all WebXR features.\r\n * Since most features require almost the same resources and callbacks, this class can be used to simplify the development\r\n * Note that since the features manager is using the `IWebXRFeature` you are in no way obligated to use this class\r\n */\r\nexport abstract class WebXRAbstractFeature implements IWebXRFeature {\r\n private _attached: boolean = false;\r\n private _removeOnDetach: {\r\n observer: Nullable<Observer<any>>;\r\n observable: Observable<any>;\r\n }[] = [];\r\n\r\n /**\r\n * Is this feature disposed?\r\n */\r\n public isDisposed: boolean = false;\r\n\r\n /**\r\n * Should auto-attach be disabled?\r\n */\r\n public disableAutoAttach: boolean = false;\r\n\r\n protected _xrNativeFeatureName: string = \"\";\r\n\r\n /**\r\n * The name of the native xr feature name (like anchor, hit-test, or hand-tracking)\r\n */\r\n public get xrNativeFeatureName() {\r\n return this._xrNativeFeatureName;\r\n }\r\n\r\n public set xrNativeFeatureName(name: string) {\r\n // check if feature was initialized while in session but needs to be initialized before the session starts\r\n if (!this._xrSessionManager.isNative && name && this._xrSessionManager.inXRSession && this._xrSessionManager.enabledFeatures?.indexOf(name) === -1) {\r\n Logger.Warn(`The feature ${name} needs to be enabled before starting the XR session. Note - It is still possible it is not supported.`);\r\n }\r\n this._xrNativeFeatureName = name;\r\n }\r\n\r\n /**\r\n * Observers registered here will be executed when the feature is attached\r\n */\r\n public onFeatureAttachObservable: Observable<IWebXRFeature> = new Observable();\r\n /**\r\n * Observers registered here will be executed when the feature is detached\r\n */\r\n public onFeatureDetachObservable: Observable<IWebXRFeature> = new Observable();\r\n\r\n /**\r\n * The dependencies of this feature, if any\r\n */\r\n public dependsOn?: string[];\r\n\r\n /**\r\n * Construct a new (abstract) WebXR feature\r\n * @param _xrSessionManager the xr session manager for this feature\r\n */\r\n constructor(protected _xrSessionManager: WebXRSessionManager) {}\r\n\r\n /**\r\n * Is this feature attached\r\n */\r\n public get attached() {\r\n return this._attached;\r\n }\r\n\r\n /**\r\n * attach this feature\r\n *\r\n * @param force should attachment be forced (even when already attached)\r\n * @returns true if successful, false is failed or already attached\r\n */\r\n public attach(force?: boolean): boolean {\r\n // do not attach a disposed feature\r\n if (this.isDisposed) {\r\n return false;\r\n }\r\n if (!force) {\r\n if (this.attached) {\r\n return false;\r\n }\r\n } else {\r\n if (this.attached) {\r\n // detach first, to be sure\r\n this.detach();\r\n }\r\n }\r\n\r\n // if this is a native WebXR feature, check if it is enabled on the session\r\n // For now only check if not using babylon native\r\n // vision OS doesn't support the enabledFeatures array, so just warn instead of failing\r\n if (!this._xrSessionManager.enabledFeatures) {\r\n Logger.Warn(\"session.enabledFeatures is not available on this device. It is possible that this feature is not supported.\");\r\n } else if (!this._xrSessionManager.isNative && this.xrNativeFeatureName && this._xrSessionManager.enabledFeatures.indexOf(this.xrNativeFeatureName) === -1) {\r\n return false;\r\n }\r\n\r\n this._attached = true;\r\n this._addNewAttachObserver(this._xrSessionManager.onXRFrameObservable, (frame) => this._onXRFrame(frame));\r\n this.onFeatureAttachObservable.notifyObservers(this);\r\n return true;\r\n }\r\n\r\n /**\r\n * detach this feature.\r\n *\r\n * @returns true if successful, false if failed or already detached\r\n */\r\n public detach(): boolean {\r\n if (!this._attached) {\r\n this.disableAutoAttach = true;\r\n return false;\r\n }\r\n this._attached = false;\r\n this._removeOnDetach.forEach((toRemove) => {\r\n toRemove.observable.remove(toRemove.observer);\r\n });\r\n this.onFeatureDetachObservable.notifyObservers(this);\r\n return true;\r\n }\r\n\r\n /**\r\n * Dispose this feature and all of the resources attached\r\n */\r\n public dispose(): void {\r\n this.detach();\r\n this.isDisposed = true;\r\n this.onFeatureAttachObservable.clear();\r\n this.onFeatureDetachObservable.clear();\r\n }\r\n\r\n /**\r\n * This function will be executed during before enabling the feature and can be used to not-allow enabling it.\r\n * Note that at this point the session has NOT started, so this is purely checking if the browser supports it\r\n *\r\n * @returns whether or not the feature is compatible in this environment\r\n */\r\n public isCompatible(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * This is used to register callbacks that will automatically be removed when detach is called.\r\n * @param observable the observable to which the observer will be attached\r\n * @param callback the callback to register\r\n */\r\n protected _addNewAttachObserver<T>(observable: Observable<T>, callback: (eventData: T, eventState: EventState) => void) {\r\n this._removeOnDetach.push({\r\n observable,\r\n observer: observable.add(callback),\r\n });\r\n }\r\n\r\n /**\r\n * Code in this function will be executed on each xrFrame received from the browser.\r\n * This function will not execute after the feature is detached.\r\n * @param _xrFrame the current frame\r\n */\r\n protected abstract _onXRFrame(_xrFrame: XRFrame): void;\r\n}\r\n"]}
1
+ {"version":3,"file":"WebXRAbstractFeature.js","sourceRoot":"","sources":["../../../../../dev/core/src/XR/features/WebXRAbstractFeature.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IWebXRFeature } from \"../webXRFeaturesManager\";\r\nimport type { Observer, EventState } from \"../../Misc/observable\";\r\nimport { Observable } from \"../../Misc/observable\";\r\nimport type { Nullable } from \"../../types\";\r\nimport type { WebXRSessionManager } from \"../webXRSessionManager\";\r\nimport { Logger } from \"core/Misc/logger\";\r\n\r\n/**\r\n * This is the base class for all WebXR features.\r\n * Since most features require almost the same resources and callbacks, this class can be used to simplify the development\r\n * Note that since the features manager is using the `IWebXRFeature` you are in no way obligated to use this class\r\n */\r\nexport abstract class WebXRAbstractFeature implements IWebXRFeature {\r\n private _attached: boolean = false;\r\n private _removeOnDetach: {\r\n observer: Nullable<Observer<any>>;\r\n observable: Observable<any>;\r\n }[] = [];\r\n\r\n /**\r\n * Is this feature disposed?\r\n */\r\n public isDisposed: boolean = false;\r\n\r\n /**\r\n * Should auto-attach be disabled?\r\n */\r\n public disableAutoAttach: boolean = false;\r\n\r\n protected _xrNativeFeatureName: string = \"\";\r\n\r\n /**\r\n * The name of the native xr feature name (like anchor, hit-test, or hand-tracking)\r\n */\r\n public get xrNativeFeatureName() {\r\n return this._xrNativeFeatureName;\r\n }\r\n\r\n public set xrNativeFeatureName(name: string) {\r\n // check if feature was initialized while in session but needs to be initialized before the session starts\r\n if (!this._xrSessionManager.isNative && name && this._xrSessionManager.inXRSession && this._xrSessionManager.enabledFeatures?.indexOf(name) === -1) {\r\n Logger.Warn(`The feature ${name} needs to be enabled before starting the XR session. Note - It is still possible it is not supported.`);\r\n }\r\n this._xrNativeFeatureName = name;\r\n }\r\n\r\n /**\r\n * Observers registered here will be executed when the feature is attached\r\n */\r\n public onFeatureAttachObservable: Observable<IWebXRFeature> = new Observable();\r\n /**\r\n * Observers registered here will be executed when the feature is detached\r\n */\r\n public onFeatureDetachObservable: Observable<IWebXRFeature> = new Observable();\r\n\r\n /**\r\n * The dependencies of this feature, if any\r\n */\r\n public dependsOn?: string[];\r\n\r\n /**\r\n * Construct a new (abstract) WebXR feature\r\n * @param _xrSessionManager the xr session manager for this feature\r\n */\r\n constructor(protected _xrSessionManager: WebXRSessionManager) {}\r\n\r\n /**\r\n * Is this feature attached\r\n */\r\n public get attached() {\r\n return this._attached;\r\n }\r\n\r\n /**\r\n * attach this feature\r\n *\r\n * @param force should attachment be forced (even when already attached)\r\n * @returns true if successful, false is failed or already attached\r\n */\r\n public attach(force?: boolean): boolean {\r\n // do not attach a disposed feature\r\n if (this.isDisposed) {\r\n return false;\r\n }\r\n if (!force) {\r\n if (this.attached) {\r\n return false;\r\n }\r\n } else {\r\n if (this.attached) {\r\n // detach first, to be sure\r\n this.detach();\r\n }\r\n }\r\n\r\n // if this is a native WebXR feature, check if it is enabled on the session\r\n // For now only check if not using babylon native\r\n // vision OS doesn't support the enabledFeatures array, so just warn instead of failing\r\n if (!this._xrSessionManager.enabledFeatures) {\r\n Logger.Warn(\"session.enabledFeatures is not available on this device. It is possible that this feature is not supported.\");\r\n } else if (!this._xrSessionManager.isNative && this.xrNativeFeatureName && this._xrSessionManager.enabledFeatures.indexOf(this.xrNativeFeatureName) === -1) {\r\n return false;\r\n }\r\n\r\n this._attached = true;\r\n this._addNewAttachObserver(this._xrSessionManager.onXRFrameObservable, (frame) => this._onXRFrame(frame));\r\n this.onFeatureAttachObservable.notifyObservers(this);\r\n return true;\r\n }\r\n\r\n /**\r\n * detach this feature.\r\n *\r\n * @returns true if successful, false if failed or already detached\r\n */\r\n public detach(): boolean {\r\n if (!this._attached) {\r\n this.disableAutoAttach = true;\r\n return false;\r\n }\r\n this._attached = false;\r\n this._removeOnDetach.forEach((toRemove) => {\r\n toRemove.observable.remove(toRemove.observer);\r\n });\r\n this.onFeatureDetachObservable.notifyObservers(this);\r\n return true;\r\n }\r\n\r\n /**\r\n * Dispose this feature and all of the resources attached\r\n */\r\n public dispose(): void {\r\n this.detach();\r\n this.isDisposed = true;\r\n this.onFeatureAttachObservable.clear();\r\n this.onFeatureDetachObservable.clear();\r\n }\r\n\r\n /**\r\n * This function will be executed during before enabling the feature and can be used to not-allow enabling it.\r\n * Note that at this point the session has NOT started, so this is purely checking if the browser supports it\r\n *\r\n * @returns whether or not the feature is compatible in this environment\r\n */\r\n public isCompatible(): boolean {\r\n return true;\r\n }\r\n\r\n /**\r\n * This is used to register callbacks that will automatically be removed when detach is called.\r\n * @param observable the observable to which the observer will be attached\r\n * @param callback the callback to register\r\n * @param insertFirst should the callback be executed as soon as it is registered\r\n */\r\n protected _addNewAttachObserver<T>(observable: Observable<T>, callback: (eventData: T, eventState: EventState) => void, insertFirst?: boolean) {\r\n this._removeOnDetach.push({\r\n observable,\r\n observer: observable.add(callback, undefined, insertFirst),\r\n });\r\n }\r\n\r\n /**\r\n * Code in this function will be executed on each xrFrame received from the browser.\r\n * This function will not execute after the feature is detached.\r\n * @param _xrFrame the current frame\r\n */\r\n protected abstract _onXRFrame(_xrFrame: XRFrame): void;\r\n}\r\n"]}
@@ -96,6 +96,16 @@ export interface IWebXRControllerPointerSelectionOptions {
96
96
  * The height (y) of the mesh must be 1.
97
97
  */
98
98
  customLasterPointerMeshGenerator?: () => AbstractMesh;
99
+ /**
100
+ * Use the grip space instead of the pointer space for selection, if available.
101
+ */
102
+ forceGripIfAvailable?: boolean;
103
+ /**
104
+ * If set to true, the hand rays will be disabled and the user will be able to look and pick objects.
105
+ * This requires system support (like in the vision OS) and will not work in all systems.
106
+ * @experimental - this is an experimental feature and might change int he future
107
+ */
108
+ lookAndPickMode?: boolean;
99
109
  }
100
110
  /**
101
111
  * A module that will enable pointer selection for motion controllers of XR Input Sources
@@ -28,7 +28,7 @@ export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
28
28
  // already attached
29
29
  return;
30
30
  }
31
- const { laserPointer, selectionMesh } = this._generateNewMeshPair(xrController.pointer);
31
+ const { laserPointer, selectionMesh } = this._generateNewMeshPair(this._options.forceGripIfAvailable && xrController.grip ? xrController.grip : xrController.pointer);
32
32
  // get two new meshes
33
33
  this._controllers[xrController.uniqueId] = {
34
34
  xrController,
@@ -100,6 +100,16 @@ export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
100
100
  this._screenCoordinatesRef = Vector3.Zero();
101
101
  this._viewportRef = new Viewport(0, 0, 0, 0);
102
102
  this._scene = this._xrSessionManager.scene;
103
+ // force look and pick mode if using WebXR on safari, assuming it is vision OS
104
+ // Only if not explicitly set. If set to false, it will not be forced
105
+ if (this._options.lookAndPickMode === undefined && (this._scene.getEngine()._badDesktopOS || this._scene.getEngine()._badOS)) {
106
+ this._options.lookAndPickMode = true;
107
+ }
108
+ // look and pick mode extra state changes
109
+ if (this._options.lookAndPickMode) {
110
+ this._options.enablePointerSelectionOnAllControllers = true;
111
+ this.displayLaserPointer = false;
112
+ }
103
113
  }
104
114
  /**
105
115
  * attach this feature
@@ -112,11 +122,11 @@ export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
112
122
  return false;
113
123
  }
114
124
  this._options.xrInput.controllers.forEach(this._attachController);
115
- this._addNewAttachObserver(this._options.xrInput.onControllerAddedObservable, this._attachController);
125
+ this._addNewAttachObserver(this._options.xrInput.onControllerAddedObservable, this._attachController, true);
116
126
  this._addNewAttachObserver(this._options.xrInput.onControllerRemovedObservable, (controller) => {
117
127
  // REMOVE the controller
118
128
  this._detachController(controller.uniqueId);
119
- });
129
+ }, true);
120
130
  this._scene.constantlyUpdateMeshUnderPointer = true;
121
131
  if (this._options.gazeCamera) {
122
132
  const webXRCamera = this._options.gazeCamera;
@@ -205,8 +215,12 @@ export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
205
215
  }
206
216
  _onXRFrame(_xrFrame) {
207
217
  Object.keys(this._controllers).forEach((id) => {
218
+ // look and pick mode
208
219
  // only do this for the selected pointer
209
220
  const controllerData = this._controllers[id];
221
+ if (this._options.lookAndPickMode && controllerData.xrController?.inputSource.targetRayMode !== "transient-pointer") {
222
+ return;
223
+ }
210
224
  if ((!this._options.enablePointerSelectionOnAllControllers && id !== this._attachedController) || controllerData.disabledByNearInteraction) {
211
225
  controllerData.selectionMesh.isVisible = false;
212
226
  controllerData.laserPointer.isVisible = false;
@@ -217,8 +231,11 @@ export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
217
231
  let controllerGlobalPosition;
218
232
  // Every frame check collisions/input
219
233
  if (controllerData.xrController) {
220
- controllerGlobalPosition = controllerData.xrController.pointer.position;
221
- controllerData.xrController.getWorldPointerRayToRef(controllerData.tmpRay);
234
+ controllerGlobalPosition =
235
+ this._options.forceGripIfAvailable && controllerData.xrController.grip
236
+ ? controllerData.xrController.grip.position
237
+ : controllerData.xrController.pointer.position;
238
+ controllerData.xrController.getWorldPointerRayToRef(controllerData.tmpRay, this._options.forceGripIfAvailable);
222
239
  }
223
240
  else if (controllerData.webXRCamera) {
224
241
  controllerGlobalPosition = controllerData.webXRCamera.position;
@@ -235,8 +252,8 @@ export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
235
252
  const scene = this._xrSessionManager.scene;
236
253
  const camera = this._options.xrInput.xrCamera;
237
254
  if (camera) {
238
- camera.viewport.toGlobalToRef(scene.getEngine().getRenderWidth(), scene.getEngine().getRenderHeight(), this._viewportRef);
239
- Vector3.ProjectToRef(controllerGlobalPosition, this._identityMatrix, scene.getTransformMatrix(), this._viewportRef, this._screenCoordinatesRef);
255
+ camera.viewport.toGlobalToRef(scene.getEngine().getRenderWidth() / camera.rigCameras.length, scene.getEngine().getRenderHeight(), this._viewportRef);
256
+ Vector3.ProjectToRef(controllerGlobalPosition, this._identityMatrix, camera.getTransformationMatrix(), this._viewportRef, this._screenCoordinatesRef);
240
257
  // stay safe
241
258
  if (typeof this._screenCoordinatesRef.x === "number" &&
242
259
  typeof this._screenCoordinatesRef.y === "number" &&
@@ -485,21 +502,25 @@ export class WebXRControllerPointerSelection extends WebXRAbstractFeature {
485
502
  else {
486
503
  // use the select and squeeze events
487
504
  const selectStartListener = (event) => {
488
- this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);
489
- if (controllerData.xrController && event.inputSource === controllerData.xrController.inputSource && controllerData.pick) {
490
- this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);
491
- controllerData.pointerDownTriggered = true;
492
- controllerData.selectionMesh.material.emissiveColor = this.selectionMeshPickedColor;
493
- controllerData.laserPointer.material.emissiveColor = this.laserPointerPickedColor;
494
- }
505
+ this._xrSessionManager.onXRFrameObservable.addOnce(() => {
506
+ this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);
507
+ if (controllerData.xrController && event.inputSource === controllerData.xrController.inputSource && controllerData.pick) {
508
+ this._scene.simulatePointerDown(controllerData.pick, pointerEventInit);
509
+ controllerData.pointerDownTriggered = true;
510
+ controllerData.selectionMesh.material.emissiveColor = this.selectionMeshPickedColor;
511
+ controllerData.laserPointer.material.emissiveColor = this.laserPointerPickedColor;
512
+ }
513
+ });
495
514
  };
496
515
  const selectEndListener = (event) => {
497
- this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);
498
- if (controllerData.xrController && event.inputSource === controllerData.xrController.inputSource && controllerData.pick) {
499
- this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);
500
- controllerData.selectionMesh.material.emissiveColor = this.selectionMeshDefaultColor;
501
- controllerData.laserPointer.material.emissiveColor = this.laserPointerDefaultColor;
502
- }
516
+ this._xrSessionManager.onXRFrameObservable.addOnce(() => {
517
+ this._augmentPointerInit(pointerEventInit, controllerData.id, controllerData.screenCoordinates);
518
+ if (controllerData.xrController && event.inputSource === controllerData.xrController.inputSource && controllerData.pick) {
519
+ this._scene.simulatePointerUp(controllerData.pick, pointerEventInit);
520
+ controllerData.selectionMesh.material.emissiveColor = this.selectionMeshDefaultColor;
521
+ controllerData.laserPointer.material.emissiveColor = this.laserPointerDefaultColor;
522
+ }
523
+ });
503
524
  };
504
525
  controllerData.eventListeners = {
505
526
  selectend: selectEndListener,