gdcore-tools 2.0.0-gd-v5.4.220-autobuild → 2.0.0-gd-v5.5.222-autobuild

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 (29) hide show
  1. package/dist/Runtime/Extensions/3D/JsExtension.js +3 -3
  2. package/dist/Runtime/Extensions/DialogueTree/bondage.js/dist/bondage.d.ts +39 -0
  3. package/dist/Runtime/Extensions/DialogueTree/dialoguetools.js +2 -2
  4. package/dist/Runtime/Extensions/DialogueTree/dialoguetools.js.map +2 -2
  5. package/dist/Runtime/Extensions/Physics2Behavior/JsExtension.js +4 -2
  6. package/dist/Runtime/Extensions/Physics2Behavior/physics2runtimebehavior.js +1 -1
  7. package/dist/Runtime/Extensions/Physics2Behavior/physics2runtimebehavior.js.map +2 -2
  8. package/dist/Runtime/Extensions/Physics3DBehavior/JsExtension.js +64 -10
  9. package/dist/Runtime/Extensions/Physics3DBehavior/Physics3DRuntimeBehavior.js +1 -1
  10. package/dist/Runtime/Extensions/Physics3DBehavior/Physics3DRuntimeBehavior.js.map +2 -2
  11. package/dist/Runtime/Extensions/Physics3DBehavior/PhysicsCharacter3DRuntimeBehavior.js +1 -1
  12. package/dist/Runtime/Extensions/Physics3DBehavior/PhysicsCharacter3DRuntimeBehavior.js.map +2 -2
  13. package/dist/Runtime/Extensions/Physics3DBehavior/jolt-physics.d.ts +283 -5
  14. package/dist/Runtime/Extensions/Physics3DBehavior/jolt-physics.wasm.js +1 -1
  15. package/dist/Runtime/Extensions/Physics3DBehavior/jolt-physics.wasm.js.map +2 -2
  16. package/dist/Runtime/Extensions/Physics3DBehavior/jolt-physics.wasm.wasm +0 -0
  17. package/dist/Runtime/Extensions/TextInput/JsExtension.js +110 -8
  18. package/dist/Runtime/Extensions/TextInput/textinputruntimeobject-pixi-renderer.js +1 -1
  19. package/dist/Runtime/Extensions/TextInput/textinputruntimeobject-pixi-renderer.js.map +2 -2
  20. package/dist/Runtime/Extensions/TextInput/textinputruntimeobject.js +1 -1
  21. package/dist/Runtime/Extensions/TextInput/textinputruntimeobject.js.map +2 -2
  22. package/dist/Runtime/events-tools/soundtools.js +1 -1
  23. package/dist/Runtime/events-tools/soundtools.js.map +2 -2
  24. package/dist/Runtime/types/project-data.d.ts +0 -1
  25. package/dist/lib/libGD.cjs +1 -1
  26. package/dist/lib/libGD.wasm +0 -0
  27. package/dist/loaders.cjs +3 -3
  28. package/gd.d.ts +44 -24
  29. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../GDevelop/Extensions/Physics3DBehavior/PhysicsCharacter3DRuntimeBehavior.ts"],
4
- "sourcesContent": ["/// <reference path=\"./jolt-physics.d.ts\" />\n\nnamespace Jolt {\n export interface Body {\n gdjsAssociatedCharacterBehavior: gdjs.PhysicsCharacter3DRuntimeBehavior | null;\n }\n}\n\nnamespace gdjs {\n interface PhysicsCharacter3DNetworkSyncDataType {\n fwa: float;\n fws: float;\n sws: float;\n fs: float;\n js: float;\n cj: boolean;\n lek: boolean;\n rik: boolean;\n upk: boolean;\n dok: boolean;\n juk: boolean;\n us: boolean;\n sa: float;\n sf: float;\n tscjs: float;\n jkhsjs: boolean;\n }\n\n export interface PhysicsCharacter3DNetworkSyncData\n extends BehaviorNetworkSyncData {\n props: PhysicsCharacter3DNetworkSyncDataType;\n }\n\n type Physics3D = {\n behavior: gdjs.Physics3DRuntimeBehavior;\n extendedUpdateSettings: Jolt.ExtendedUpdateSettings;\n broadPhaseLayerFilter: Jolt.BroadPhaseLayerFilter;\n objectLayerFilter: Jolt.ObjectLayerFilter;\n bodyFilter: Jolt.BodyFilter;\n shapeFilter: Jolt.ShapeFilter;\n };\n\n export class PhysicsCharacter3DRuntimeBehavior\n extends gdjs.RuntimeBehavior\n implements gdjs.Physics3DRuntimeBehavior.Physics3DHook {\n owner3D: gdjs.RuntimeObject3D;\n private _physics3DBehaviorName: string;\n private _physics3D: Physics3D | null = null;\n character: Jolt.CharacterVirtual | null = null;\n /**\n * sharedData is a reference to the shared data of the scene, that registers\n * every physics behavior that is created so that collisions can be cleared\n * before stepping the world.\n */\n _sharedData: gdjs.Physics3DSharedData;\n\n // TODO Should there be angle were the character can climb but will slip?\n _slopeMaxAngle: float;\n private _slopeClimbingFactor: float = 1;\n private _slopeClimbingMinNormalZ: float = Math.cos(Math.PI / 4);\n private _forwardAngle: float = 0;\n private _shouldBindObjectAndForwardAngle: boolean;\n private _forwardAcceleration: float;\n private _forwardDeceleration: float;\n private _forwardSpeedMax: float;\n private _sidewaysAcceleration: float;\n private _sidewaysDeceleration: float;\n private _sidewaysSpeedMax: float;\n private _gravity: float;\n private _maxFallingSpeed: float;\n private _jumpSpeed: float;\n private _jumpSustainTime: float;\n\n private _hasPressedForwardKey: boolean = false;\n private _hasPressedBackwardKey: boolean = false;\n private _hasPressedRightKey: boolean = false;\n private _hasPressedLeftKey: boolean = false;\n private _hasPressedJumpKey: boolean = false;\n private _hasUsedStick: boolean = false;\n private _stickAngle: float = 0;\n private _stickForce: float = 0;\n private _currentForwardSpeed: float = 0;\n private _currentSidewaysSpeed: float = 0;\n private _currentFallSpeed: float = 0;\n private _canJump: boolean = false;\n private _currentJumpSpeed: float = 0;\n private _timeSinceCurrentJumpStart: float = 0;\n private _jumpKeyHeldSinceJumpStart: boolean = false;\n private _hasReallyMoved: boolean = false;\n private _oldPhysicsPosition: FloatPoint = [0, 0];\n\n // This is useful for extensions that need to know\n // which keys were pressed and doesn't know the mapping\n // done by the scene events.\n private _wasLeftKeyPressed: boolean = false;\n private _wasRightKeyPressed: boolean = false;\n private _wasForwardKeyPressed: boolean = false;\n private _wasBackwardKeyPressed: boolean = false;\n private _wasJumpKeyPressed: boolean = false;\n private _wasStickUsed: boolean = false;\n\n // This is useful when the object is synchronized by an external source\n // like in a multiplayer game, and we want to be able to predict the\n // movement of the object, even if the inputs are not updated every frame.\n private _dontClearInputsBetweenFrames: boolean = false;\n\n /**\n * A very small value compare to 1 pixel, yet very huge compare to rounding errors.\n */\n private static readonly epsilon = 2 ** -20;\n\n constructor(\n instanceContainer: gdjs.RuntimeInstanceContainer,\n behaviorData,\n owner: gdjs.RuntimeObject3D\n ) {\n super(instanceContainer, behaviorData, owner);\n this.owner3D = owner;\n this._physics3DBehaviorName = behaviorData.physics3D;\n this._sharedData = gdjs.Physics3DSharedData.getSharedData(\n instanceContainer.getScene(),\n behaviorData.Physics3D\n );\n\n this._slopeMaxAngle = 0;\n this.setSlopeMaxAngle(behaviorData.slopeMaxAngle);\n this._forwardAcceleration = behaviorData.forwardAcceleration;\n this._forwardDeceleration = behaviorData.forwardDeceleration;\n this._forwardSpeedMax = behaviorData.forwardSpeedMax;\n this._sidewaysAcceleration = behaviorData.sidewaysAcceleration;\n this._sidewaysDeceleration = behaviorData.sidewaysDeceleration;\n this._sidewaysSpeedMax = behaviorData.sidewaysSpeedMax;\n this._gravity = behaviorData.gravity;\n this._maxFallingSpeed = behaviorData.fallingSpeedMax;\n this._jumpSustainTime = behaviorData.jumpSustainTime;\n this._jumpSpeed = this.getJumpSpeedToReach(behaviorData.jumpHeight);\n this._shouldBindObjectAndForwardAngle =\n behaviorData.shouldBindObjectAndForwardAngle;\n }\n\n private getVec3(x: float, y: float, z: float): Jolt.Vec3 {\n const tempVec3 = this._sharedData._tempVec3;\n tempVec3.Set(x, y, z);\n return tempVec3;\n }\n\n getPhysics3D(): Physics3D {\n if (this._physics3D) {\n return this._physics3D;\n }\n const behavior = this.owner.getBehavior(\n this._physics3DBehaviorName\n ) as gdjs.Physics3DRuntimeBehavior;\n\n const sharedData = behavior._sharedData;\n const jolt = sharedData.jolt;\n const extendedUpdateSettings = new Jolt.ExtendedUpdateSettings();\n extendedUpdateSettings.mWalkStairsStepUp = this.getVec3(0, 0, 0.4);\n const broadPhaseLayerFilter = new Jolt.DefaultBroadPhaseLayerFilter(\n jolt.GetObjectVsBroadPhaseLayerFilter(),\n gdjs.Physics3DSharedData.dynamicBroadPhaseLayerIndex\n );\n const objectLayerFilter = new Jolt.DefaultObjectLayerFilter(\n jolt.GetObjectLayerPairFilter(),\n behavior.getBodyLayer()\n );\n const bodyFilter = new Jolt.BodyFilter();\n const shapeFilter = new Jolt.ShapeFilter();\n\n this._physics3D = {\n behavior,\n extendedUpdateSettings,\n broadPhaseLayerFilter,\n objectLayerFilter,\n bodyFilter,\n shapeFilter,\n };\n sharedData.registerHook(this);\n\n behavior.bodyUpdater = new gdjs.PhysicsCharacter3DRuntimeBehavior.CharacterBodyUpdater(\n this\n );\n behavior.recreateBody();\n\n // Always begin in the direction of the object.\n this._forwardAngle = this.owner.getAngle();\n\n return this._physics3D;\n }\n\n updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {\n if (oldBehaviorData.gravity !== newBehaviorData.gravity) {\n this.setGravity(newBehaviorData.gravity);\n }\n if (oldBehaviorData.maxFallingSpeed !== newBehaviorData.maxFallingSpeed) {\n this.setMaxFallingSpeed(newBehaviorData.maxFallingSpeed);\n }\n if (\n oldBehaviorData.forwardAcceleration !==\n newBehaviorData.forwardAcceleration\n ) {\n this.setForwardAcceleration(newBehaviorData.forwardAcceleration);\n }\n if (\n oldBehaviorData.forwardDeceleration !==\n newBehaviorData.forwardDeceleration\n ) {\n this.setForwardDeceleration(newBehaviorData.forwardDeceleration);\n }\n if (oldBehaviorData.forwardSpeedMax !== newBehaviorData.forwardSpeedMax) {\n this.setForwardSpeedMax(newBehaviorData.forwardSpeedMax);\n }\n if (\n oldBehaviorData.sidewaysAcceleration !==\n newBehaviorData.sidewaysAcceleration\n ) {\n this.setSidewaysAcceleration(newBehaviorData.sidewaysAcceleration);\n }\n if (\n oldBehaviorData.sidewaysDeceleration !==\n newBehaviorData.sidewaysDeceleration\n ) {\n this.setSidewaysDeceleration(newBehaviorData.sidewaysDeceleration);\n }\n if (\n oldBehaviorData.sidewaysSpeedMax !== newBehaviorData.sidewaysSpeedMax\n ) {\n this.setSidewaysSpeedMax(newBehaviorData.sidewaysSpeedMax);\n }\n if (oldBehaviorData.jumpSustainTime !== newBehaviorData.jumpSustainTime) {\n this.setJumpSustainTime(newBehaviorData.jumpSustainTime);\n }\n if (oldBehaviorData.jumpHeight !== newBehaviorData.jumpHeight) {\n this.setJumpSpeed(this.getJumpSpeedToReach(newBehaviorData.jumpHeight));\n }\n if (\n oldBehaviorData.shouldBindObjectAndForwardAngle !==\n newBehaviorData.shouldBindObjectAndForwardAngle\n ) {\n this.setShouldBindObjectAndForwardAngle(\n newBehaviorData.shouldBindObjectAndForwardAngle\n );\n }\n return true;\n }\n\n getNetworkSyncData(): PhysicsCharacter3DNetworkSyncData {\n // This method is called, so we are synchronizing this object.\n // Let's clear the inputs between frames as we control it.\n this._dontClearInputsBetweenFrames = false;\n\n return {\n ...super.getNetworkSyncData(),\n props: {\n fwa: this._forwardAngle,\n fws: this._currentForwardSpeed,\n sws: this._currentSidewaysSpeed,\n fs: this._currentFallSpeed,\n js: this._currentJumpSpeed,\n cj: this._canJump,\n lek: this._wasLeftKeyPressed,\n rik: this._wasRightKeyPressed,\n upk: this._wasForwardKeyPressed,\n dok: this._wasBackwardKeyPressed,\n juk: this._wasJumpKeyPressed,\n us: this._wasStickUsed,\n sa: this._stickAngle,\n sf: this._stickForce,\n tscjs: this._timeSinceCurrentJumpStart,\n jkhsjs: this._jumpKeyHeldSinceJumpStart,\n },\n };\n }\n\n updateFromNetworkSyncData(\n networkSyncData: PhysicsCharacter3DNetworkSyncData\n ) {\n super.updateFromNetworkSyncData(networkSyncData);\n\n const behaviorSpecificProps = networkSyncData.props;\n this._forwardAngle = behaviorSpecificProps.fwa;\n this._currentForwardSpeed = behaviorSpecificProps.fws;\n this._currentSidewaysSpeed = behaviorSpecificProps.sws;\n this._currentFallSpeed = behaviorSpecificProps.fs;\n this._currentJumpSpeed = behaviorSpecificProps.js;\n this._canJump = behaviorSpecificProps.cj;\n this._hasPressedForwardKey = behaviorSpecificProps.upk;\n this._hasPressedBackwardKey = behaviorSpecificProps.dok;\n this._hasPressedLeftKey = behaviorSpecificProps.lek;\n this._hasPressedRightKey = behaviorSpecificProps.rik;\n this._hasPressedJumpKey = behaviorSpecificProps.juk;\n this._hasUsedStick = behaviorSpecificProps.us;\n this._stickAngle = behaviorSpecificProps.sa;\n this._stickForce = behaviorSpecificProps.sf;\n this._timeSinceCurrentJumpStart = behaviorSpecificProps.tscjs;\n this._jumpKeyHeldSinceJumpStart = behaviorSpecificProps.jkhsjs;\n\n // When the object is synchronized from the network, the inputs must not be cleared.\n this._dontClearInputsBetweenFrames = true;\n }\n\n getPhysicsPosition(result: Jolt.RVec3): Jolt.RVec3 {\n const { behavior } = this.getPhysics3D();\n // The character origin is at its feet:\n // - the center is used for X and Y because Box3D origin is at the top-left corner\n // - the origin is used for Z because, when the character is made smaller,\n // it must stay on the ground and not fell from its old size.\n result.Set(\n this.owner3D.getCenterXInScene() * this._sharedData.worldInvScale,\n this.owner3D.getCenterYInScene() * this._sharedData.worldInvScale,\n this.owner3D.getZ() * this._sharedData.worldInvScale +\n behavior._shapeHalfDepth\n );\n return result;\n }\n\n moveObjectToPhysicsPosition(physicsPosition: Jolt.RVec3): void {\n const { behavior } = this.getPhysics3D();\n this.owner3D.setCenterXInScene(\n physicsPosition.GetX() * this._sharedData.worldScale\n );\n this.owner3D.setCenterYInScene(\n physicsPosition.GetY() * this._sharedData.worldScale\n );\n this.owner3D.setZ(\n (physicsPosition.GetZ() - behavior._shapeHalfDepth) *\n this._sharedData.worldScale\n );\n }\n\n onDeActivate() {}\n\n onActivate() {}\n\n onDestroy() {\n this.onDeActivate();\n }\n\n doStepPreEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {\n // Trigger createAndAddBody()\n this.getPhysics3D();\n }\n\n doBeforePhysicsStep(timeDelta: float): void {\n const {\n behavior,\n extendedUpdateSettings,\n broadPhaseLayerFilter,\n objectLayerFilter,\n bodyFilter,\n shapeFilter,\n } = this.getPhysics3D();\n if (!this.character) {\n return;\n }\n const characterBody = behavior._body;\n if (!characterBody) {\n return;\n }\n const worldInvScale = this._sharedData.worldInvScale;\n\n const oldX = this.character.GetPosition().GetX();\n const oldY = this.character.GetPosition().GetY();\n const oldZ = this.character.GetPosition().GetZ();\n\n if (this._shouldBindObjectAndForwardAngle) {\n this._forwardAngle = this.owner.getAngle();\n }\n\n this.updateCharacterSpeedFromInputs(timeDelta);\n\n if (this._currentJumpSpeed > 0) {\n this._timeSinceCurrentJumpStart += timeDelta;\n }\n // Check if the jump key is continuously held since\n // the beginning of the jump.\n if (!this._hasPressedJumpKey) {\n this._jumpKeyHeldSinceJumpStart = false;\n }\n if (\n this._canJump &&\n this._hasPressedJumpKey &&\n // Avoid the character to jump in loop when the jump key is held.\n !this._jumpKeyHeldSinceJumpStart\n ) {\n this._currentJumpSpeed = this._jumpSpeed;\n this._currentFallSpeed = 0;\n this._canJump = false;\n this._jumpKeyHeldSinceJumpStart = true;\n this._timeSinceCurrentJumpStart = 0;\n }\n if (!this.isOnFloor()) {\n // Decrease jump speed after the (optional) jump sustain time is over.\n const sustainJumpSpeed =\n this._jumpKeyHeldSinceJumpStart &&\n this._timeSinceCurrentJumpStart < this._jumpSustainTime;\n if (!sustainJumpSpeed) {\n this._currentJumpSpeed = Math.max(\n 0,\n this._currentJumpSpeed - this._gravity * timeDelta\n );\n }\n this._currentFallSpeed = Math.min(\n this._maxFallingSpeed,\n this._currentFallSpeed + this._gravity * timeDelta\n );\n }\n\n // Follow moving platforms.\n let groundVelocityX = 0;\n let groundVelocityY = 0;\n let groundVelocityZ = 0;\n if (this.character.IsSupported()) {\n const shouldFollow = this.updateGroundVelocity(behavior, timeDelta);\n if (shouldFollow) {\n const groundVelocity = this.character.GetGroundVelocity();\n groundVelocityX = groundVelocity.GetX();\n groundVelocityY = groundVelocity.GetY();\n groundVelocityZ = groundVelocity.GetZ();\n }\n }\n\n // Update walking speed\n let forwardSpeed = this._currentForwardSpeed;\n let sidewaysSpeed = this._currentSidewaysSpeed;\n if (sidewaysSpeed !== 0 && forwardSpeed !== 0) {\n // It avoids the speed vector to go outside of an ellipse.\n const speedNormalizationInverseRatio = Math.hypot(\n forwardSpeed / this._forwardSpeedMax,\n sidewaysSpeed / this._sidewaysSpeedMax\n );\n if (speedNormalizationInverseRatio > 1) {\n forwardSpeed /= speedNormalizationInverseRatio;\n sidewaysSpeed /= speedNormalizationInverseRatio;\n }\n }\n forwardSpeed *= worldInvScale;\n sidewaysSpeed *= worldInvScale;\n const angle = gdjs.toRad(this._forwardAngle);\n const cosA = Math.cos(angle);\n const sinA = Math.sin(angle);\n const speedX = forwardSpeed * cosA - sidewaysSpeed * sinA;\n const speedY = forwardSpeed * sinA + sidewaysSpeed * cosA;\n this.character.SetLinearVelocity(\n this.getVec3(\n groundVelocityX + speedX,\n groundVelocityY + speedY,\n // The ground velocity is not added on Z as it's handled by mStickToFloorStepDown.\n (this._currentJumpSpeed - this._currentFallSpeed) * worldInvScale\n )\n );\n\n if (this.isOnFloor()) {\n // Keep the character on the floor when walking down-hill.\n const walkingDistance = Math.max(\n Math.hypot(\n this.character.GetPosition().GetX() - this._oldPhysicsPosition[0],\n this.character.GetPosition().GetY() - this._oldPhysicsPosition[1]\n ),\n Math.hypot(\n this.character.GetLinearVelocity().GetX(),\n this.character.GetLinearVelocity().GetY()\n ) * timeDelta\n );\n this._oldPhysicsPosition[0] = this.character.GetPosition().GetX();\n this._oldPhysicsPosition[1] = this.character.GetPosition().GetY();\n\n // A safety margin is taken as if the ground normal is too steep, the\n // character will fall next step anyway.\n const stickToFloorStepDownZ = Math.max(\n -0.01 +\n 1.01 *\n Math.min(\n // Follow the platform slope...\n -walkingDistance * this._slopeClimbingFactor,\n // ...and follow a platform falling...\n groundVelocityZ * timeDelta\n ),\n // ...but never fall faster than the max fall speed.\n -this._maxFallingSpeed * worldInvScale * timeDelta\n );\n extendedUpdateSettings.mStickToFloorStepDown.Set(\n 0,\n 0,\n stickToFloorStepDownZ\n );\n } else {\n extendedUpdateSettings.mStickToFloorStepDown.Set(0, 0, 0);\n }\n\n this.character.ExtendedUpdate(\n timeDelta,\n this.character.GetUp(),\n extendedUpdateSettings,\n broadPhaseLayerFilter,\n objectLayerFilter,\n bodyFilter,\n shapeFilter,\n this._sharedData.jolt.GetTempAllocator()\n );\n\n if (this.isOnFloor()) {\n this._canJump = true;\n this._currentFallSpeed = 0;\n this._currentJumpSpeed = 0;\n }\n\n this._wasForwardKeyPressed = this._hasPressedForwardKey;\n this._wasBackwardKeyPressed = this._hasPressedBackwardKey;\n this._wasRightKeyPressed = this._hasPressedRightKey;\n this._wasLeftKeyPressed = this._hasPressedLeftKey;\n this._wasJumpKeyPressed = this._hasPressedJumpKey;\n this._wasStickUsed = this._hasPressedJumpKey;\n\n if (!this._dontClearInputsBetweenFrames) {\n this._hasPressedForwardKey = false;\n this._hasPressedBackwardKey = false;\n this._hasPressedRightKey = false;\n this._hasPressedLeftKey = false;\n this._hasPressedJumpKey = false;\n this._hasUsedStick = false;\n }\n\n this._hasReallyMoved =\n Math.abs(this.character.GetPosition().GetX() - oldX) >\n PhysicsCharacter3DRuntimeBehavior.epsilon ||\n Math.abs(this.character.GetPosition().GetY() - oldY) >\n PhysicsCharacter3DRuntimeBehavior.epsilon ||\n Math.abs(this.character.GetPosition().GetZ() - oldZ) >\n PhysicsCharacter3DRuntimeBehavior.epsilon;\n }\n\n private updateCharacterSpeedFromInputs(timeDelta: float) {\n /** A stick with a half way force targets a lower speed than the maximum speed. */\n let targetedForwardSpeed = 0;\n // Change the speed according to the player's input.\n // TODO Give priority to the last key for faster reaction time.\n if (this._hasPressedBackwardKey !== this._hasPressedForwardKey) {\n if (this._hasPressedBackwardKey) {\n targetedForwardSpeed = -this._forwardSpeedMax;\n } else if (this._hasPressedForwardKey) {\n targetedForwardSpeed = this._forwardSpeedMax;\n }\n } else if (this._hasUsedStick) {\n targetedForwardSpeed =\n -this._forwardSpeedMax *\n this._stickForce *\n Math.sin(gdjs.toRad(this._stickAngle));\n }\n this._currentForwardSpeed = PhysicsCharacter3DRuntimeBehavior.getAcceleratedSpeed(\n this._currentForwardSpeed,\n targetedForwardSpeed,\n this._forwardSpeedMax,\n this._forwardAcceleration,\n this._forwardDeceleration,\n timeDelta\n );\n /** A stick with a half way force targets a lower speed than the maximum speed. */\n let targetedSidewaysSpeed = 0;\n if (this._hasPressedLeftKey !== this._hasPressedRightKey) {\n if (this._hasPressedLeftKey) {\n targetedSidewaysSpeed = -this._sidewaysSpeedMax;\n } else if (this._hasPressedRightKey) {\n targetedSidewaysSpeed = this._sidewaysSpeedMax;\n }\n } else if (this._hasUsedStick) {\n targetedSidewaysSpeed =\n this._sidewaysSpeedMax *\n this._stickForce *\n Math.cos(gdjs.toRad(this._stickAngle));\n }\n this._currentSidewaysSpeed = PhysicsCharacter3DRuntimeBehavior.getAcceleratedSpeed(\n this._currentSidewaysSpeed,\n targetedSidewaysSpeed,\n this._sidewaysSpeedMax,\n this._sidewaysAcceleration,\n this._sidewaysDeceleration,\n timeDelta\n );\n }\n\n private static getAcceleratedSpeed(\n currentSpeed: float,\n targetedSpeed: float,\n speedMax: float,\n acceleration: float,\n deceleration: float,\n timeDelta: float\n ): float {\n let newSpeed = currentSpeed;\n if (targetedSpeed < 0) {\n if (currentSpeed <= targetedSpeed) {\n // Reduce the speed to match the stick force.\n newSpeed = Math.min(\n targetedSpeed,\n currentSpeed + deceleration * timeDelta\n );\n } else if (currentSpeed <= 0) {\n // Accelerate\n newSpeed -= Math.max(-speedMax, acceleration * timeDelta);\n } else {\n // Turn back at least as fast as it would stop.\n newSpeed = Math.max(\n targetedSpeed,\n currentSpeed - Math.max(acceleration, deceleration) * timeDelta\n );\n }\n } else if (targetedSpeed > 0) {\n if (currentSpeed >= targetedSpeed) {\n // Reduce the speed to match the stick force.\n newSpeed = Math.max(\n targetedSpeed,\n currentSpeed - deceleration * timeDelta\n );\n } else if (currentSpeed >= 0) {\n // Accelerate\n newSpeed = Math.min(\n speedMax,\n currentSpeed + acceleration * timeDelta\n );\n } else {\n // Turn back at least as fast as it would stop.\n newSpeed = Math.min(\n targetedSpeed,\n currentSpeed + Math.max(acceleration, deceleration) * timeDelta\n );\n }\n } else {\n // Decelerate and stop.\n if (currentSpeed < 0) {\n newSpeed = Math.min(currentSpeed + deceleration * timeDelta, 0);\n }\n if (currentSpeed > 0) {\n newSpeed = Math.max(currentSpeed - deceleration * timeDelta, 0);\n }\n }\n return newSpeed;\n }\n\n private updateGroundVelocity(\n behavior: Physics3DRuntimeBehavior,\n timeDelta: float\n ): boolean {\n if (!this.character) {\n return false;\n }\n const characterBody = behavior._body;\n if (!characterBody) {\n return false;\n }\n const worldInvScale = this._sharedData.worldInvScale;\n\n if (!this.character.IsSupported()) {\n return false;\n }\n\n const groundBody = this._sharedData.physicsSystem\n .GetBodyLockInterface()\n .TryGetBody(this.character.GetGroundBodyID());\n\n const stillKinematicPlatform =\n groundBody.IsKinematic() &&\n groundBody.GetLinearVelocity().Equals(Jolt.Vec3.prototype.sZero()) &&\n groundBody.GetAngularVelocity().Equals(Jolt.Vec3.prototype.sZero());\n if (stillKinematicPlatform) {\n const groundBehavior = groundBody.gdjsAssociatedBehavior;\n if (groundBehavior) {\n const inverseTimeDelta = 1 / timeDelta;\n // The platform may be moved by position changes instead of velocity.\n // Emulate a velocity from the position changes.\n groundBody.SetLinearVelocity(\n this.getVec3(\n (groundBehavior.owner3D.getX() - groundBehavior._objectOldX) *\n worldInvScale *\n inverseTimeDelta,\n (groundBehavior.owner3D.getY() - groundBehavior._objectOldY) *\n worldInvScale *\n inverseTimeDelta,\n (groundBehavior.owner3D.getZ() - groundBehavior._objectOldZ) *\n worldInvScale *\n inverseTimeDelta\n )\n );\n groundBody.SetAngularVelocity(\n this.getVec3(\n 0,\n 0,\n gdjs.toRad(\n gdjs.evtTools.common.angleDifference(\n groundBehavior.owner3D.getAngle(),\n groundBehavior._objectOldRotationZ\n )\n ) * inverseTimeDelta\n )\n );\n }\n }\n this.character.UpdateGroundVelocity();\n\n const groundAngularVelocityZ = groundBody.GetAngularVelocity().GetZ();\n if (groundAngularVelocityZ !== 0) {\n // Make the character rotate with the platform on Z axis.\n const angleDelta = groundAngularVelocityZ * timeDelta;\n this.character.SetRotation(\n Jolt.Quat.prototype.sEulerAngles(\n this.getVec3(\n 0,\n 0,\n this.character\n .GetRotation()\n .GetRotationAngle(Jolt.Vec3.prototype.sAxisZ()) + angleDelta\n )\n )\n );\n // Also update the forward angle to make sure it stays the same\n // relatively to the object angle.\n this._forwardAngle += gdjs.toDegrees(angleDelta);\n }\n if (stillKinematicPlatform) {\n groundBody.SetLinearVelocity(Jolt.Vec3.prototype.sZero());\n groundBody.SetAngularVelocity(Jolt.Vec3.prototype.sZero());\n }\n\n // Characters should not try to magnet on a body that rolls on the ground.\n const rollingSpeedMax = (1 * Math.PI) / 180;\n const shouldFollow =\n Math.abs(groundBody.GetAngularVelocity().GetX()) < rollingSpeedMax &&\n Math.abs(groundBody.GetAngularVelocity().GetY()) < rollingSpeedMax;\n return shouldFollow;\n }\n\n doStepPostEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {}\n\n onObjectHotReloaded() {}\n\n /**\n * Get maximum angle of a slope for the Character to run on it as a floor.\n * @returns the slope maximum angle, in degrees.\n */\n getSlopeMaxAngle(): float {\n return this._slopeMaxAngle;\n }\n\n /**\n * Set the maximum slope angle of the Character.\n * @param slopeMaxAngle The new maximum slope angle.\n */\n setSlopeMaxAngle(slopeMaxAngle: float): void {\n if (slopeMaxAngle < 0 || slopeMaxAngle >= 90) {\n return;\n }\n this._slopeMaxAngle = slopeMaxAngle;\n\n //Avoid rounding errors\n if (slopeMaxAngle === 45) {\n this._slopeClimbingFactor = 1;\n } else {\n // Avoid a `_slopeClimbingFactor` set to exactly 0.\n // Otherwise, this can lead the floor finding functions to consider\n // a floor to be \"too high\" to reach, even if the object is very slightly\n // inside it, which can happen because of rounding errors.\n // See \"Floating-point error mitigations\" tests.\n this._slopeClimbingFactor = Math.max(\n 1 / 1024,\n Math.tan(gdjs.toRad(slopeMaxAngle))\n );\n }\n // The floor is in 3D but to go back to 2D trigonometry, we can take the\n // 2D space generated by the floor normal and the Z axis, given that:\n // - The normal keeps the same Z coordinate (as the Z axis is included in the 2D space)\n // - The normal keeps the same length (as the normal is included in the 2D space)\n this._slopeClimbingMinNormalZ = Math.min(\n Math.cos(gdjs.toRad(slopeMaxAngle)),\n 1 - 1 / 1024\n );\n }\n\n /**\n * Get the gravity of the Character.\n * @returns The current gravity.\n */\n getGravity(): float {\n return this._gravity;\n }\n\n /**\n * Set the gravity of the Character.\n * @param gravity The new gravity.\n */\n setGravity(gravity: float): void {\n this._gravity = gravity;\n }\n\n /**\n * Get the maximum falling speed of the Character.\n * @returns The maximum falling speed.\n */\n getMaxFallingSpeed(): float {\n return this._maxFallingSpeed;\n }\n\n /**\n * Set the maximum falling speed of the Character.\n * @param maxFallingSpeed The maximum falling speed.\n * @param tryToPreserveAirSpeed If true and if jumping, tune the current\n * jump speed to preserve the overall speed in the air.\n */\n setMaxFallingSpeed(\n maxFallingSpeed: float,\n tryToPreserveAirSpeed: boolean = false\n ): void {\n if (tryToPreserveAirSpeed && !this.isOnFloor()) {\n // If the falling speed is too high compared to the new max falling speed,\n // reduce it and adapt the jump speed to preserve the overall vertical speed.\n const fallingSpeedOverflow = this._currentFallSpeed - maxFallingSpeed;\n if (fallingSpeedOverflow > 0) {\n this._currentFallSpeed -= fallingSpeedOverflow;\n this._currentJumpSpeed = Math.max(\n 0,\n this.getCurrentJumpSpeed() - fallingSpeedOverflow\n );\n }\n }\n this._maxFallingSpeed = maxFallingSpeed;\n }\n\n /**\n * Get the forward acceleration value of the Character.\n * @returns The current acceleration.\n */\n getForwardAcceleration(): float {\n return this._forwardAcceleration;\n }\n\n /**\n * Set the forward acceleration of the Character.\n * @param forwardAcceleration The new acceleration.\n */\n setForwardAcceleration(forwardAcceleration: float): void {\n this._forwardAcceleration = forwardAcceleration;\n }\n\n /**\n * Get the forward deceleration of the Character.\n * @returns The current deceleration.\n */\n getForwardDeceleration(): float {\n return this._forwardDeceleration;\n }\n\n /**\n * Set the forward deceleration of the Character.\n * @param forwardDeceleration The new deceleration.\n */\n setForwardDeceleration(forwardDeceleration: float): void {\n this._forwardDeceleration = forwardDeceleration;\n }\n\n /**\n * Get the forward maximum speed of the Character.\n * @returns The maximum speed.\n */\n getForwardSpeedMax(): float {\n return this._forwardSpeedMax;\n }\n\n /**\n * Set the forward maximum speed of the Character.\n * @param forwardSpeedMax The new maximum speed.\n */\n setForwardSpeedMax(forwardSpeedMax: float): void {\n this._forwardSpeedMax = forwardSpeedMax;\n }\n\n /**\n * Get the sideways acceleration value of the Character.\n * @returns The current acceleration.\n */\n getSidewaysAcceleration(): float {\n return this._sidewaysAcceleration;\n }\n\n /**\n * Set the sideways acceleration of the Character.\n * @param sidewaysAcceleration The new acceleration.\n */\n setSidewaysAcceleration(sidewaysAcceleration: float): void {\n this._sidewaysAcceleration = sidewaysAcceleration;\n }\n\n /**\n * Get the sideways deceleration of the Character.\n * @returns The current deceleration.\n */\n getSidewaysDeceleration(): float {\n return this._sidewaysDeceleration;\n }\n\n /**\n * Set the sideways deceleration of the Character.\n * @param sidewaysDeceleration The new deceleration.\n */\n setSidewaysDeceleration(sidewaysDeceleration: float): void {\n this._sidewaysDeceleration = sidewaysDeceleration;\n }\n\n /**\n * Get the sideways maximum speed of the Character.\n * @returns The maximum speed.\n */\n getSidewaysSpeedMax(): float {\n return this._sidewaysSpeedMax;\n }\n\n /**\n * Set the sideways maximum speed of the Character.\n * @param sidewaysSpeedMax The new maximum speed.\n */\n setSidewaysSpeedMax(sidewaysSpeedMax: float): void {\n this._sidewaysSpeedMax = sidewaysSpeedMax;\n }\n\n /**\n * Get the jump speed of the Character.\n * @returns The jump speed.\n */\n getJumpSpeed(): float {\n return this._jumpSpeed;\n }\n\n /**\n * Set the jump speed of the Character.\n * @param jumpSpeed The new jump speed.\n */\n setJumpSpeed(jumpSpeed: float): void {\n this._jumpSpeed = jumpSpeed;\n }\n\n /**\n * Get the jump sustain time of the Character.\n * @returns The jump sustain time.\n */\n getJumpSustainTime(): float {\n return this._jumpSustainTime;\n }\n\n /**\n * Set the jump sustain time of the Character.\n * @param jumpSpeed The new jump sustain time.\n */\n setJumpSustainTime(jumpSustainTime: float): void {\n this._jumpSustainTime = jumpSustainTime;\n }\n\n getForwardAngle(): float {\n return this._forwardAngle;\n }\n\n setForwardAngle(angle: float): void {\n this._forwardAngle = angle;\n if (this._shouldBindObjectAndForwardAngle) {\n this.owner.setAngle(angle);\n }\n }\n\n isForwardAngleAround(degreeAngle: float, tolerance: float) {\n return (\n Math.abs(\n gdjs.evtTools.common.angleDifference(this._forwardAngle, degreeAngle)\n ) <= tolerance\n );\n }\n\n shouldBindObjectAndForwardAngle(): boolean {\n return this._shouldBindObjectAndForwardAngle;\n }\n\n setShouldBindObjectAndForwardAngle(\n shouldBindObjectAndForwardAngle: boolean\n ): void {\n this._shouldBindObjectAndForwardAngle = shouldBindObjectAndForwardAngle;\n }\n\n /**\n * Get the current speed of the Character.\n * @returns The current speed.\n */\n getCurrentForwardSpeed(): float {\n return this._currentForwardSpeed;\n }\n\n /**\n * Set the current speed of the Character.\n * @param currentForwardSpeed The current speed.\n */\n setCurrentForwardSpeed(currentForwardSpeed: float): void {\n this._currentForwardSpeed = currentForwardSpeed;\n }\n\n /**\n * Get the current speed of the Character.\n * @returns The current speed.\n */\n getCurrentSidewaysSpeed(): float {\n return this._currentSidewaysSpeed;\n }\n\n /**\n * Set the current speed of the Character.\n * @param currentSidewaysSpeed The current speed.\n */\n setCurrentSidewaysSpeed(currentSidewaysSpeed: float): void {\n this._currentSidewaysSpeed = currentSidewaysSpeed;\n }\n\n /**\n * Get the speed at which the object is falling. It is 0 when the object is\n * on a floor, and non 0 as soon as the object leaves the floor.\n * @returns The current fall speed.\n */\n getCurrentFallSpeed(): float {\n return this._currentFallSpeed;\n }\n\n /**\n * Set the current fall speed.\n */\n setCurrentFallSpeed(currentFallSpeed: float) {\n this._currentFallSpeed = gdjs.evtTools.common.clamp(\n currentFallSpeed,\n 0,\n this._maxFallingSpeed\n );\n }\n\n /**\n * Get the current jump speed of the Character.\n * @returns The current jump speed.\n */\n getCurrentJumpSpeed(): float {\n return this._currentJumpSpeed;\n }\n\n /**\n * Set the current jump speed.\n */\n setCurrentJumpSpeed(currentJumpSpeed: float) {\n this._currentJumpSpeed = Math.max(0, currentJumpSpeed);\n }\n\n /**\n * Check if the Character can jump.\n * @returns Returns true if the object can jump.\n */\n canJump(): boolean {\n return this._canJump;\n }\n\n /**\n * Allow the Character to jump again.\n */\n setCanJump(): void {\n this._canJump = true;\n }\n\n /**\n * Forbid the Character to air jump.\n */\n setCanNotAirJump(): void {\n if (this.isJumping() || this.isFalling()) {\n this._canJump = false;\n }\n }\n\n /**\n * Abort the current jump.\n *\n * When the character is not in the jumping state this method has no effect.\n */\n abortJump(): void {\n if (this.isJumping()) {\n this._currentFallSpeed = 0;\n this._currentJumpSpeed = 0;\n }\n }\n\n simulateForwardKey(): void {\n this._hasPressedForwardKey = true;\n }\n\n wasForwardKeyPressed(): boolean {\n return this._wasForwardKeyPressed;\n }\n\n simulateBackwardKey(): void {\n this._hasPressedBackwardKey = true;\n }\n\n wasBackwardKeyPressed(): boolean {\n return this._wasBackwardKeyPressed;\n }\n\n simulateRightKey(): void {\n this._hasPressedRightKey = true;\n }\n\n wasRightKeyPressed(): boolean {\n return this._wasRightKeyPressed;\n }\n\n simulateLeftKey(): void {\n this._hasPressedLeftKey = true;\n }\n\n wasLeftKeyPressed(): boolean {\n return this._wasLeftKeyPressed;\n }\n\n simulateJumpKey(): void {\n this._hasPressedJumpKey = true;\n }\n\n wasJumpKeyPressed(): boolean {\n return this._wasJumpKeyPressed;\n }\n\n simulateStick(stickAngle: float, stickForce: float) {\n this._hasUsedStick = true;\n this._stickAngle = stickAngle;\n this._stickForce = Math.max(0, Math.min(1, stickForce));\n }\n\n wasStickUsed(): boolean {\n return this._wasStickUsed;\n }\n\n getStickAngle(): float {\n return this._wasStickUsed ? this._stickAngle : 0;\n }\n\n getStickForce(): float {\n return this._wasStickUsed ? this._stickForce : 0;\n }\n\n // TODO Should we add a \"is sliding\" condition?\n /**\n * Check if the Character is on a floor.\n * @returns Returns true if on a floor and false if not.\n */\n isOnFloor(): boolean {\n return this.character\n ? this.character.IsSupported() &&\n // Ensure characters don't land on too step floor.\n this.character.GetGroundNormal().GetZ() >=\n this._slopeClimbingMinNormalZ &&\n // Ensure characters don't land on a platform corner while jumping.\n this._currentJumpSpeed <= this._currentFallSpeed\n : false;\n }\n\n /**\n * Check if the Character is on the given object.\n * @returns Returns true if on the object and false if not.\n */\n isOnFloorObject(physics3DBehavior: gdjs.Physics3DRuntimeBehavior): boolean {\n if (!physics3DBehavior._body || !this.character || !this.isOnFloor()) {\n return false;\n }\n return (\n this.character.GetGroundBodyID().GetIndexAndSequenceNumber() ===\n physics3DBehavior._body.GetID().GetIndexAndSequenceNumber()\n );\n }\n\n /**\n * Check if the Character is jumping.\n * @returns Returns true if jumping and false if not.\n */\n isJumping(): boolean {\n return this._currentJumpSpeed > 0;\n }\n\n /**\n * Check if the Character is in the falling state. This is false\n * if the object is jumping, even if the object is going down after reaching\n * the jump peak.\n * @returns Returns true if it is falling and false if not.\n */\n isFallingWithoutJumping(): boolean {\n return !this.isOnFloor() && this._currentJumpSpeed === 0;\n }\n\n /**\n * Check if the Character is \"going down\", either because it's in the\n * falling state *or* because it's jumping but reached the jump peak and\n * is now going down (because the jump speed can't compensate anymore the\n * falling speed).\n *\n * If you want to check if the object is falling outside of a jump (or because\n * the jump is entirely finished and there is no jump speed applied to the object\n * anymore), consider using `isFallingWithoutJumping`.\n *\n * @returns Returns true if it is \"going down\" and false if not.\n */\n isFalling(): boolean {\n return (\n !this.isOnFloor() && this._currentJumpSpeed < this._currentFallSpeed\n );\n }\n\n /**\n * Check if the Character is moving.\n * @returns Returns true if it is moving and false if not.\n */\n isMovingEvenALittle(): boolean {\n return (\n (this._hasReallyMoved && this._currentForwardSpeed !== 0) ||\n this._currentJumpSpeed !== 0 ||\n this._currentFallSpeed !== 0\n );\n }\n\n getJumpSpeedToReach(jumpHeight: float): float {\n // Formulas used in this extension were generated from a math model.\n // They are probably not understandable on their own.\n // If you need to modify them or need to write new feature,\n // please take a look at the platformer extension documentation:\n // https://github.com/4ian/GDevelop/tree/master/Extensions/PlatformBehavior#readme\n\n jumpHeight = -Math.abs(jumpHeight);\n\n const gravity = this._gravity;\n const maxFallingSpeed = this._maxFallingSpeed;\n const jumpSustainTime = this._jumpSustainTime;\n\n const maxFallingSpeedReachedTime = maxFallingSpeed / gravity;\n\n // The implementation jumps from one quadratic resolution to another\n // to find the right formula to use as the time is unknown.\n\n const sustainCase = (jumpHeight) => Math.sqrt(-jumpHeight * gravity * 2);\n const maxFallingCase = (jumpHeight) =>\n -gravity * jumpSustainTime +\n maxFallingSpeed +\n Math.sqrt(\n gravity * gravity * jumpSustainTime * jumpSustainTime -\n 2 * jumpHeight * gravity -\n maxFallingSpeed * maxFallingSpeed\n );\n\n let jumpSpeed = 0;\n let peakTime = 0;\n if (maxFallingSpeedReachedTime > jumpSustainTime) {\n // common case\n jumpSpeed =\n -gravity * jumpSustainTime +\n Math.sqrt(\n 2 * gravity * gravity * jumpSustainTime * jumpSustainTime -\n 4 * jumpHeight * gravity\n );\n peakTime = (gravity * jumpSustainTime + jumpSpeed) / (2 * gravity);\n if (peakTime < jumpSustainTime) {\n jumpSpeed = sustainCase(jumpHeight);\n } else if (peakTime > maxFallingSpeedReachedTime) {\n jumpSpeed = maxFallingCase(jumpHeight);\n }\n } else {\n // affine case can't have a maximum\n\n // sustain case\n jumpSpeed = sustainCase(jumpHeight);\n peakTime = jumpSpeed / gravity;\n if (peakTime > maxFallingSpeedReachedTime) {\n jumpSpeed = maxFallingCase(jumpHeight);\n }\n }\n return jumpSpeed;\n }\n }\n\n gdjs.registerBehavior(\n 'Physics3D::PhysicsCharacter3D',\n gdjs.PhysicsCharacter3DRuntimeBehavior\n );\n\n export namespace PhysicsCharacter3DRuntimeBehavior {\n export class CharacterBodyUpdater {\n characterBehavior: gdjs.PhysicsCharacter3DRuntimeBehavior;\n\n constructor(characterBehavior: gdjs.PhysicsCharacter3DRuntimeBehavior) {\n this.characterBehavior = characterBehavior;\n }\n\n createAndAddBody(): Jolt.Body {\n const { _slopeMaxAngle, owner3D, _sharedData } = this.characterBehavior;\n const { behavior } = this.characterBehavior.getPhysics3D();\n\n const shape = behavior.createShape();\n\n const settings = new Jolt.CharacterVirtualSettings();\n settings.mInnerBodyLayer = behavior.getBodyLayer();\n settings.mInnerBodyShape = shape;\n settings.mMass = shape.GetMassProperties().get_mMass();\n settings.mMaxSlopeAngle = gdjs.toRad(_slopeMaxAngle);\n settings.mShape = shape;\n settings.mUp = Jolt.Vec3.prototype.sAxisZ();\n settings.mBackFaceMode = Jolt.EBackFaceMode_CollideWithBackFaces;\n // TODO Should we make them configurable?\n //settings.mMaxStrength = maxStrength;\n //settings.mCharacterPadding = characterPadding;\n //settings.mPenetrationRecoverySpeed = penetrationRecoverySpeed;\n //settings.mPredictiveContactDistance = predictiveContactDistance;\n const depth = owner3D.getDepth() * _sharedData.worldInvScale;\n const width = owner3D.getWidth() * _sharedData.worldInvScale;\n const height = owner3D.getHeight() * _sharedData.worldInvScale;\n // Only the bottom of the capsule can make a contact with the floor.\n // It avoids characters from sticking to walls.\n const capsuleHalfLength = depth / 2;\n const capsuleRadius = Math.sqrt(width * height) / 2;\n settings.mSupportingVolume = new Jolt.Plane(\n Jolt.Vec3.prototype.sAxisZ(),\n // TODO It's strange that the value is positive.\n // Use a big safety margin as the ground normal will be checked anyway.\n // It only avoids to detect walls as ground.\n capsuleHalfLength -\n capsuleRadius *\n (1 - Math.cos(gdjs.toRad(Math.min(_slopeMaxAngle + 20, 70))))\n );\n const character = new Jolt.CharacterVirtual(\n settings,\n this.characterBehavior.getPhysicsPosition(\n _sharedData.getRVec3(0, 0, 0)\n ),\n behavior.getPhysicsRotation(_sharedData.getQuat(0, 0, 0, 1)),\n _sharedData.physicsSystem\n );\n const body = _sharedData.physicsSystem\n .GetBodyLockInterface()\n .TryGetBody(character.GetInnerBodyID());\n this.characterBehavior.character = character;\n // TODO This is not really reliable. We could choose to disable it and force user to use the \"is on platform\" condition.\n //body.SetCollideKinematicVsNonDynamic(true);\n return body;\n }\n\n updateObjectFromBody() {\n const { behavior } = this.characterBehavior.getPhysics3D();\n const { character } = this.characterBehavior;\n if (!character) {\n return;\n }\n // We can't rely on the body position because of mCharacterPadding.\n this.characterBehavior.moveObjectToPhysicsPosition(\n character.GetPosition()\n );\n // TODO No need to update the rotation for X and Y as CharacterVirtual doesn't change it.\n behavior.moveObjectToPhysicsRotation(character.GetRotation());\n }\n\n updateBodyFromObject() {\n const { behavior } = this.characterBehavior.getPhysics3D();\n const { character, owner3D, _sharedData } = this.characterBehavior;\n if (!character) {\n return;\n }\n if (\n behavior._objectOldX !== owner3D.getX() ||\n behavior._objectOldY !== owner3D.getY() ||\n behavior._objectOldZ !== owner3D.getZ()\n ) {\n this.updateCharacterPosition();\n }\n if (\n behavior._objectOldRotationX !== owner3D.getRotationX() ||\n behavior._objectOldRotationY !== owner3D.getRotationY() ||\n behavior._objectOldRotationZ !== owner3D.getAngle()\n ) {\n // TODO No need to update the rotation for X and Y as CharacterVirtual doesn't change it.\n character.SetRotation(\n behavior.getPhysicsRotation(_sharedData.getQuat(0, 0, 0, 1))\n );\n }\n }\n\n updateCharacterPosition() {\n const { character, _sharedData } = this.characterBehavior;\n if (!character) {\n return;\n }\n character.SetPosition(\n this.characterBehavior.getPhysicsPosition(\n _sharedData.getRVec3(0, 0, 0)\n )\n );\n }\n\n recreateShape() {\n const {\n behavior,\n broadPhaseLayerFilter,\n objectLayerFilter,\n bodyFilter,\n shapeFilter,\n } = this.characterBehavior.getPhysics3D();\n const { character, _sharedData } = this.characterBehavior;\n if (!character) {\n return;\n }\n const shape = behavior.createShape();\n const isShapeValid = character.SetShape(\n shape,\n Number.MAX_VALUE,\n broadPhaseLayerFilter,\n objectLayerFilter,\n bodyFilter,\n shapeFilter,\n _sharedData.jolt.GetTempAllocator()\n );\n if (!isShapeValid) {\n return;\n }\n character.SetInnerBodyShape(shape);\n character.SetMass(shape.GetMassProperties().get_mMass());\n\n // shapeHalfDepth may have changed, update the character position accordingly.\n this.updateCharacterPosition();\n }\n }\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/// <reference path=\"./jolt-physics.d.ts\" />\n\nnamespace Jolt {\n export interface Body {\n gdjsAssociatedCharacterBehavior: gdjs.PhysicsCharacter3DRuntimeBehavior | null;\n }\n}\n\nnamespace gdjs {\n interface PhysicsCharacter3DNetworkSyncDataType {\n fwa: float;\n fws: float;\n sws: float;\n fs: float;\n js: float;\n cj: boolean;\n lek: boolean;\n rik: boolean;\n upk: boolean;\n dok: boolean;\n juk: boolean;\n us: boolean;\n sa: float;\n sf: float;\n tscjs: float;\n jkhsjs: boolean;\n }\n\n export interface PhysicsCharacter3DNetworkSyncData\n extends BehaviorNetworkSyncData {\n props: PhysicsCharacter3DNetworkSyncDataType;\n }\n\n type Physics3D = {\n behavior: gdjs.Physics3DRuntimeBehavior;\n extendedUpdateSettings: Jolt.ExtendedUpdateSettings;\n broadPhaseLayerFilter: Jolt.BroadPhaseLayerFilter;\n objectLayerFilter: Jolt.ObjectLayerFilter;\n bodyFilter: Jolt.BodyFilter;\n shapeFilter: Jolt.ShapeFilter;\n };\n\n export class PhysicsCharacter3DRuntimeBehavior\n extends gdjs.RuntimeBehavior\n implements gdjs.Physics3DRuntimeBehavior.Physics3DHook {\n owner3D: gdjs.RuntimeObject3D;\n private _physics3DBehaviorName: string;\n private _physics3D: Physics3D | null = null;\n character: Jolt.CharacterVirtual | null = null;\n /**\n * sharedData is a reference to the shared data of the scene, that registers\n * every physics behavior that is created so that collisions can be cleared\n * before stepping the world.\n */\n _sharedData: gdjs.Physics3DSharedData;\n collisionChecker: gdjs.PhysicsCharacter3DRuntimeBehavior.CharacterCollisionChecker;\n\n // TODO Should there be angle were the character can climb but will slip?\n _slopeMaxAngle: float;\n private _slopeClimbingFactor: float = 1;\n private _slopeClimbingMinNormalZ: float = Math.cos(Math.PI / 4);\n private _forwardAngle: float = 0;\n private _shouldBindObjectAndForwardAngle: boolean;\n private _forwardAcceleration: float;\n private _forwardDeceleration: float;\n private _forwardSpeedMax: float;\n private _sidewaysAcceleration: float;\n private _sidewaysDeceleration: float;\n private _sidewaysSpeedMax: float;\n private _gravity: float;\n private _maxFallingSpeed: float;\n private _jumpSpeed: float;\n private _jumpSustainTime: float;\n private _stairHeightMax: float;\n _canBePushed: boolean;\n\n private _hasPressedForwardKey: boolean = false;\n private _hasPressedBackwardKey: boolean = false;\n private _hasPressedRightKey: boolean = false;\n private _hasPressedLeftKey: boolean = false;\n private _hasPressedJumpKey: boolean = false;\n private _hasUsedStick: boolean = false;\n private _stickAngle: float = 0;\n private _stickForce: float = 0;\n private _currentForwardSpeed: float = 0;\n private _currentSidewaysSpeed: float = 0;\n private _currentFallSpeed: float = 0;\n private _canJump: boolean = false;\n private _currentJumpSpeed: float = 0;\n private _timeSinceCurrentJumpStart: float = 0;\n private _jumpKeyHeldSinceJumpStart: boolean = false;\n private _hasReallyMoved: boolean = false;\n private _oldPhysicsPosition: FloatPoint = [0, 0];\n\n // This is useful for extensions that need to know\n // which keys were pressed and doesn't know the mapping\n // done by the scene events.\n private _wasLeftKeyPressed: boolean = false;\n private _wasRightKeyPressed: boolean = false;\n private _wasForwardKeyPressed: boolean = false;\n private _wasBackwardKeyPressed: boolean = false;\n private _wasJumpKeyPressed: boolean = false;\n private _wasStickUsed: boolean = false;\n\n // This is useful when the object is synchronized by an external source\n // like in a multiplayer game, and we want to be able to predict the\n // movement of the object, even if the inputs are not updated every frame.\n private _dontClearInputsBetweenFrames: boolean = false;\n\n /**\n * A very small value compare to 1 pixel, yet very huge compare to rounding errors.\n */\n private static readonly epsilon = 2 ** -20;\n\n constructor(\n instanceContainer: gdjs.RuntimeInstanceContainer,\n behaviorData,\n owner: gdjs.RuntimeObject3D\n ) {\n super(instanceContainer, behaviorData, owner);\n this.owner3D = owner;\n this._physics3DBehaviorName = behaviorData.physics3D;\n this._sharedData = gdjs.Physics3DSharedData.getSharedData(\n instanceContainer.getScene(),\n behaviorData.Physics3D\n );\n this.collisionChecker = new gdjs.PhysicsCharacter3DRuntimeBehavior.CharacterCollisionChecker(\n this\n );\n\n this._slopeMaxAngle = 0;\n this.setSlopeMaxAngle(behaviorData.slopeMaxAngle);\n this._forwardAcceleration = behaviorData.forwardAcceleration;\n this._forwardDeceleration = behaviorData.forwardDeceleration;\n this._forwardSpeedMax = behaviorData.forwardSpeedMax;\n this._sidewaysAcceleration = behaviorData.sidewaysAcceleration;\n this._sidewaysDeceleration = behaviorData.sidewaysDeceleration;\n this._sidewaysSpeedMax = behaviorData.sidewaysSpeedMax;\n this._gravity = behaviorData.gravity;\n this._maxFallingSpeed = behaviorData.fallingSpeedMax;\n this._jumpSustainTime = behaviorData.jumpSustainTime;\n this._jumpSpeed = this.getJumpSpeedToReach(behaviorData.jumpHeight);\n this._shouldBindObjectAndForwardAngle =\n behaviorData.shouldBindObjectAndForwardAngle;\n this._stairHeightMax =\n behaviorData.stairHeightMax === undefined\n ? 20\n : behaviorData.stairHeightMax;\n this._canBePushed =\n behaviorData.canBePushed === undefined\n ? true\n : behaviorData.canBePushed;\n }\n\n private getVec3(x: float, y: float, z: float): Jolt.Vec3 {\n const tempVec3 = this._sharedData._tempVec3;\n tempVec3.Set(x, y, z);\n return tempVec3;\n }\n\n getPhysics3D(): Physics3D {\n if (this._physics3D) {\n return this._physics3D;\n }\n const behavior = this.owner.getBehavior(\n this._physics3DBehaviorName\n ) as gdjs.Physics3DRuntimeBehavior;\n\n const sharedData = behavior._sharedData;\n const jolt = sharedData.jolt;\n const extendedUpdateSettings = new Jolt.ExtendedUpdateSettings();\n const broadPhaseLayerFilter = new Jolt.DefaultBroadPhaseLayerFilter(\n jolt.GetObjectVsBroadPhaseLayerFilter(),\n gdjs.Physics3DSharedData.dynamicBroadPhaseLayerIndex\n );\n const objectLayerFilter = new Jolt.DefaultObjectLayerFilter(\n jolt.GetObjectLayerPairFilter(),\n behavior.getBodyLayer()\n );\n const bodyFilter = new Jolt.BodyFilter();\n const shapeFilter = new Jolt.ShapeFilter();\n\n this._physics3D = {\n behavior,\n extendedUpdateSettings,\n broadPhaseLayerFilter,\n objectLayerFilter,\n bodyFilter,\n shapeFilter,\n };\n this.setStairHeightMax(this._stairHeightMax);\n sharedData.registerHook(this);\n\n behavior.bodyUpdater = new gdjs.PhysicsCharacter3DRuntimeBehavior.CharacterBodyUpdater(\n this\n );\n behavior.collisionChecker = this.collisionChecker;\n behavior.recreateBody();\n\n // Always begin in the direction of the object.\n this._forwardAngle = this.owner.getAngle();\n\n return this._physics3D;\n }\n\n updateFromBehaviorData(oldBehaviorData, newBehaviorData): boolean {\n if (oldBehaviorData.gravity !== newBehaviorData.gravity) {\n this.setGravity(newBehaviorData.gravity);\n }\n if (oldBehaviorData.maxFallingSpeed !== newBehaviorData.maxFallingSpeed) {\n this.setMaxFallingSpeed(newBehaviorData.maxFallingSpeed);\n }\n if (\n oldBehaviorData.forwardAcceleration !==\n newBehaviorData.forwardAcceleration\n ) {\n this.setForwardAcceleration(newBehaviorData.forwardAcceleration);\n }\n if (\n oldBehaviorData.forwardDeceleration !==\n newBehaviorData.forwardDeceleration\n ) {\n this.setForwardDeceleration(newBehaviorData.forwardDeceleration);\n }\n if (oldBehaviorData.forwardSpeedMax !== newBehaviorData.forwardSpeedMax) {\n this.setForwardSpeedMax(newBehaviorData.forwardSpeedMax);\n }\n if (\n oldBehaviorData.sidewaysAcceleration !==\n newBehaviorData.sidewaysAcceleration\n ) {\n this.setSidewaysAcceleration(newBehaviorData.sidewaysAcceleration);\n }\n if (\n oldBehaviorData.sidewaysDeceleration !==\n newBehaviorData.sidewaysDeceleration\n ) {\n this.setSidewaysDeceleration(newBehaviorData.sidewaysDeceleration);\n }\n if (\n oldBehaviorData.sidewaysSpeedMax !== newBehaviorData.sidewaysSpeedMax\n ) {\n this.setSidewaysSpeedMax(newBehaviorData.sidewaysSpeedMax);\n }\n if (oldBehaviorData.jumpSustainTime !== newBehaviorData.jumpSustainTime) {\n this.setJumpSustainTime(newBehaviorData.jumpSustainTime);\n }\n if (oldBehaviorData.jumpHeight !== newBehaviorData.jumpHeight) {\n this.setJumpSpeed(this.getJumpSpeedToReach(newBehaviorData.jumpHeight));\n }\n if (\n oldBehaviorData.shouldBindObjectAndForwardAngle !==\n newBehaviorData.shouldBindObjectAndForwardAngle\n ) {\n this.setShouldBindObjectAndForwardAngle(\n newBehaviorData.shouldBindObjectAndForwardAngle\n );\n }\n if (oldBehaviorData.stairHeightMax !== newBehaviorData.stairHeightMax) {\n this.setStairHeightMax(newBehaviorData.stairHeightMax);\n }\n return true;\n }\n\n getNetworkSyncData(): PhysicsCharacter3DNetworkSyncData {\n // This method is called, so we are synchronizing this object.\n // Let's clear the inputs between frames as we control it.\n this._dontClearInputsBetweenFrames = false;\n\n return {\n ...super.getNetworkSyncData(),\n props: {\n fwa: this._forwardAngle,\n fws: this._currentForwardSpeed,\n sws: this._currentSidewaysSpeed,\n fs: this._currentFallSpeed,\n js: this._currentJumpSpeed,\n cj: this._canJump,\n lek: this._wasLeftKeyPressed,\n rik: this._wasRightKeyPressed,\n upk: this._wasForwardKeyPressed,\n dok: this._wasBackwardKeyPressed,\n juk: this._wasJumpKeyPressed,\n us: this._wasStickUsed,\n sa: this._stickAngle,\n sf: this._stickForce,\n tscjs: this._timeSinceCurrentJumpStart,\n jkhsjs: this._jumpKeyHeldSinceJumpStart,\n },\n };\n }\n\n updateFromNetworkSyncData(\n networkSyncData: PhysicsCharacter3DNetworkSyncData\n ) {\n super.updateFromNetworkSyncData(networkSyncData);\n\n const behaviorSpecificProps = networkSyncData.props;\n this._forwardAngle = behaviorSpecificProps.fwa;\n this._currentForwardSpeed = behaviorSpecificProps.fws;\n this._currentSidewaysSpeed = behaviorSpecificProps.sws;\n this._currentFallSpeed = behaviorSpecificProps.fs;\n this._currentJumpSpeed = behaviorSpecificProps.js;\n this._canJump = behaviorSpecificProps.cj;\n this._hasPressedForwardKey = behaviorSpecificProps.upk;\n this._hasPressedBackwardKey = behaviorSpecificProps.dok;\n this._hasPressedLeftKey = behaviorSpecificProps.lek;\n this._hasPressedRightKey = behaviorSpecificProps.rik;\n this._hasPressedJumpKey = behaviorSpecificProps.juk;\n this._hasUsedStick = behaviorSpecificProps.us;\n this._stickAngle = behaviorSpecificProps.sa;\n this._stickForce = behaviorSpecificProps.sf;\n this._timeSinceCurrentJumpStart = behaviorSpecificProps.tscjs;\n this._jumpKeyHeldSinceJumpStart = behaviorSpecificProps.jkhsjs;\n\n // When the object is synchronized from the network, the inputs must not be cleared.\n this._dontClearInputsBetweenFrames = true;\n }\n\n getPhysicsPosition(result: Jolt.RVec3): Jolt.RVec3 {\n const { behavior } = this.getPhysics3D();\n // The character origin is at its feet:\n // - the center is used for X and Y because Box3D origin is at the top-left corner\n // - the origin is used for Z because, when the character is made smaller,\n // it must stay on the ground and not fell from its old size.\n result.Set(\n this.owner3D.getCenterXInScene() * this._sharedData.worldInvScale,\n this.owner3D.getCenterYInScene() * this._sharedData.worldInvScale,\n this.owner3D.getZ() * this._sharedData.worldInvScale +\n behavior._shapeHalfDepth\n );\n return result;\n }\n\n getPhysicsRotation(result: Jolt.Quat): Jolt.Quat {\n // Characters body should not rotate around X and Y.\n const rotation = result.sEulerAngles(\n this.getVec3(0, 0, gdjs.toRad(this.owner3D.getAngle()))\n );\n result.Set(\n rotation.GetX(),\n rotation.GetY(),\n rotation.GetZ(),\n rotation.GetW()\n );\n Jolt.destroy(rotation);\n return result;\n }\n\n moveObjectToPhysicsPosition(physicsPosition: Jolt.RVec3): void {\n const { behavior } = this.getPhysics3D();\n this.owner3D.setCenterXInScene(\n physicsPosition.GetX() * this._sharedData.worldScale\n );\n this.owner3D.setCenterYInScene(\n physicsPosition.GetY() * this._sharedData.worldScale\n );\n this.owner3D.setZ(\n (physicsPosition.GetZ() - behavior._shapeHalfDepth) *\n this._sharedData.worldScale\n );\n }\n\n moveObjectToPhysicsRotation(physicsRotation: Jolt.Quat): void {\n const threeObject = this.owner3D.get3DRendererObject();\n threeObject.quaternion.x = physicsRotation.GetX();\n threeObject.quaternion.y = physicsRotation.GetY();\n threeObject.quaternion.z = physicsRotation.GetZ();\n threeObject.quaternion.w = physicsRotation.GetW();\n // TODO Avoid this instantiation\n const euler = new THREE.Euler(0, 0, 0, 'ZYX');\n euler.setFromQuaternion(threeObject.quaternion);\n // No need to update the rotation for X and Y as CharacterVirtual doesn't change it.\n this.owner3D.setAngle(gdjs.toDegrees(euler.z));\n }\n\n onDeActivate() {\n this.collisionChecker.clearContacts();\n }\n\n onActivate() {}\n\n onDestroy() {\n this.onDeActivate();\n }\n\n doStepPreEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {\n // Trigger createAndAddBody()\n this.getPhysics3D();\n }\n\n doBeforePhysicsStep(timeDelta: float): void {\n const {\n behavior,\n extendedUpdateSettings,\n broadPhaseLayerFilter,\n objectLayerFilter,\n bodyFilter,\n shapeFilter,\n } = this.getPhysics3D();\n if (!this.character) {\n return;\n }\n const characterBody = behavior._body;\n if (!characterBody) {\n return;\n }\n const worldInvScale = this._sharedData.worldInvScale;\n\n const oldX = this.character.GetPosition().GetX();\n const oldY = this.character.GetPosition().GetY();\n const oldZ = this.character.GetPosition().GetZ();\n\n if (this._shouldBindObjectAndForwardAngle) {\n this._forwardAngle = this.owner.getAngle();\n }\n\n this.updateCharacterSpeedFromInputs(timeDelta);\n\n if (this._currentJumpSpeed > 0) {\n this._timeSinceCurrentJumpStart += timeDelta;\n }\n // Check if the jump key is continuously held since\n // the beginning of the jump.\n if (!this._hasPressedJumpKey) {\n this._jumpKeyHeldSinceJumpStart = false;\n }\n if (\n this._canJump &&\n this._hasPressedJumpKey &&\n // Avoid the character to jump in loop when the jump key is held.\n !this._jumpKeyHeldSinceJumpStart\n ) {\n this._currentJumpSpeed = this._jumpSpeed;\n this._currentFallSpeed = 0;\n this._canJump = false;\n this._jumpKeyHeldSinceJumpStart = true;\n this._timeSinceCurrentJumpStart = 0;\n }\n if (!this.isOnFloor()) {\n // Decrease jump speed after the (optional) jump sustain time is over.\n const sustainJumpSpeed =\n this._jumpKeyHeldSinceJumpStart &&\n this._timeSinceCurrentJumpStart < this._jumpSustainTime;\n if (!sustainJumpSpeed) {\n this._currentJumpSpeed = Math.max(\n 0,\n this._currentJumpSpeed - this._gravity * timeDelta\n );\n }\n this._currentFallSpeed = Math.min(\n this._maxFallingSpeed,\n this._currentFallSpeed + this._gravity * timeDelta\n );\n }\n\n // Follow moving platforms.\n let groundVelocityX = 0;\n let groundVelocityY = 0;\n let groundVelocityZ = 0;\n if (this.character.IsSupported()) {\n const shouldFollow = this.updateGroundVelocity(behavior, timeDelta);\n if (shouldFollow) {\n const groundVelocity = this.character.GetGroundVelocity();\n groundVelocityX = groundVelocity.GetX();\n groundVelocityY = groundVelocity.GetY();\n groundVelocityZ = groundVelocity.GetZ();\n }\n }\n\n // Update walking speed\n let forwardSpeed = this._currentForwardSpeed;\n let sidewaysSpeed = this._currentSidewaysSpeed;\n if (sidewaysSpeed !== 0 && forwardSpeed !== 0) {\n // It avoids the speed vector to go outside of an ellipse.\n const speedNormalizationInverseRatio = Math.hypot(\n forwardSpeed / this._forwardSpeedMax,\n sidewaysSpeed / this._sidewaysSpeedMax\n );\n if (speedNormalizationInverseRatio > 1) {\n forwardSpeed /= speedNormalizationInverseRatio;\n sidewaysSpeed /= speedNormalizationInverseRatio;\n }\n }\n forwardSpeed *= worldInvScale;\n sidewaysSpeed *= worldInvScale;\n const angle = gdjs.toRad(this._forwardAngle);\n const cosA = Math.cos(angle);\n const sinA = Math.sin(angle);\n const speedX = forwardSpeed * cosA - sidewaysSpeed * sinA;\n const speedY = forwardSpeed * sinA + sidewaysSpeed * cosA;\n this.character.SetLinearVelocity(\n this.getVec3(\n groundVelocityX + speedX,\n groundVelocityY + speedY,\n // The ground velocity is not added on Z as it's handled by mStickToFloorStepDown.\n (this._currentJumpSpeed - this._currentFallSpeed) * worldInvScale\n )\n );\n\n if (this.isOnFloor()) {\n // Keep the character on the floor when walking down-hill.\n const walkingDistance = Math.max(\n Math.hypot(\n this.character.GetPosition().GetX() - this._oldPhysicsPosition[0],\n this.character.GetPosition().GetY() - this._oldPhysicsPosition[1]\n ),\n Math.hypot(\n this.character.GetLinearVelocity().GetX(),\n this.character.GetLinearVelocity().GetY()\n ) * timeDelta\n );\n this._oldPhysicsPosition[0] = this.character.GetPosition().GetX();\n this._oldPhysicsPosition[1] = this.character.GetPosition().GetY();\n\n // A safety margin is taken as if the ground normal is too steep, the\n // character will fall next step anyway.\n const stickToFloorStepDownZ = Math.max(\n -0.01 +\n 1.01 *\n Math.min(\n // Follow the platform slope...\n -walkingDistance * this._slopeClimbingFactor,\n // ...and follow a platform falling...\n groundVelocityZ * timeDelta\n ),\n // ...but never fall faster than the max fall speed.\n -this._maxFallingSpeed * worldInvScale * timeDelta\n );\n extendedUpdateSettings.mStickToFloorStepDown.Set(\n 0,\n 0,\n stickToFloorStepDownZ\n );\n } else {\n extendedUpdateSettings.mStickToFloorStepDown.Set(0, 0, 0);\n }\n\n this.character.ExtendedUpdate(\n timeDelta,\n this.character.GetUp(),\n extendedUpdateSettings,\n broadPhaseLayerFilter,\n objectLayerFilter,\n bodyFilter,\n shapeFilter,\n this._sharedData.jolt.GetTempAllocator()\n );\n this.collisionChecker.updateContacts();\n\n if (this.isOnFloor()) {\n this._canJump = true;\n this._currentFallSpeed = 0;\n this._currentJumpSpeed = 0;\n }\n\n this._wasForwardKeyPressed = this._hasPressedForwardKey;\n this._wasBackwardKeyPressed = this._hasPressedBackwardKey;\n this._wasRightKeyPressed = this._hasPressedRightKey;\n this._wasLeftKeyPressed = this._hasPressedLeftKey;\n this._wasJumpKeyPressed = this._hasPressedJumpKey;\n this._wasStickUsed = this._hasPressedJumpKey;\n\n if (!this._dontClearInputsBetweenFrames) {\n this._hasPressedForwardKey = false;\n this._hasPressedBackwardKey = false;\n this._hasPressedRightKey = false;\n this._hasPressedLeftKey = false;\n this._hasPressedJumpKey = false;\n this._hasUsedStick = false;\n }\n\n this._hasReallyMoved =\n Math.abs(this.character.GetPosition().GetX() - oldX) >\n PhysicsCharacter3DRuntimeBehavior.epsilon ||\n Math.abs(this.character.GetPosition().GetY() - oldY) >\n PhysicsCharacter3DRuntimeBehavior.epsilon ||\n Math.abs(this.character.GetPosition().GetZ() - oldZ) >\n PhysicsCharacter3DRuntimeBehavior.epsilon;\n }\n\n private updateCharacterSpeedFromInputs(timeDelta: float) {\n /** A stick with a half way force targets a lower speed than the maximum speed. */\n let targetedForwardSpeed = 0;\n // Change the speed according to the player's input.\n // TODO Give priority to the last key for faster reaction time.\n if (this._hasPressedBackwardKey !== this._hasPressedForwardKey) {\n if (this._hasPressedBackwardKey) {\n targetedForwardSpeed = -this._forwardSpeedMax;\n } else if (this._hasPressedForwardKey) {\n targetedForwardSpeed = this._forwardSpeedMax;\n }\n } else if (this._hasUsedStick) {\n targetedForwardSpeed =\n -this._forwardSpeedMax *\n this._stickForce *\n Math.sin(gdjs.toRad(this._stickAngle));\n }\n this._currentForwardSpeed = PhysicsCharacter3DRuntimeBehavior.getAcceleratedSpeed(\n this._currentForwardSpeed,\n targetedForwardSpeed,\n this._forwardSpeedMax,\n this._forwardAcceleration,\n this._forwardDeceleration,\n timeDelta\n );\n /** A stick with a half way force targets a lower speed than the maximum speed. */\n let targetedSidewaysSpeed = 0;\n if (this._hasPressedLeftKey !== this._hasPressedRightKey) {\n if (this._hasPressedLeftKey) {\n targetedSidewaysSpeed = -this._sidewaysSpeedMax;\n } else if (this._hasPressedRightKey) {\n targetedSidewaysSpeed = this._sidewaysSpeedMax;\n }\n } else if (this._hasUsedStick) {\n targetedSidewaysSpeed =\n this._sidewaysSpeedMax *\n this._stickForce *\n Math.cos(gdjs.toRad(this._stickAngle));\n }\n this._currentSidewaysSpeed = PhysicsCharacter3DRuntimeBehavior.getAcceleratedSpeed(\n this._currentSidewaysSpeed,\n targetedSidewaysSpeed,\n this._sidewaysSpeedMax,\n this._sidewaysAcceleration,\n this._sidewaysDeceleration,\n timeDelta\n );\n }\n\n private static getAcceleratedSpeed(\n currentSpeed: float,\n targetedSpeed: float,\n speedMax: float,\n acceleration: float,\n deceleration: float,\n timeDelta: float\n ): float {\n let newSpeed = currentSpeed;\n if (targetedSpeed < 0) {\n if (currentSpeed <= targetedSpeed) {\n // Reduce the speed to match the stick force.\n newSpeed = Math.min(\n targetedSpeed,\n currentSpeed + deceleration * timeDelta\n );\n } else if (currentSpeed <= 0) {\n // Accelerate\n newSpeed -= Math.max(-speedMax, acceleration * timeDelta);\n } else {\n // Turn back at least as fast as it would stop.\n newSpeed = Math.max(\n targetedSpeed,\n currentSpeed - Math.max(acceleration, deceleration) * timeDelta\n );\n }\n } else if (targetedSpeed > 0) {\n if (currentSpeed >= targetedSpeed) {\n // Reduce the speed to match the stick force.\n newSpeed = Math.max(\n targetedSpeed,\n currentSpeed - deceleration * timeDelta\n );\n } else if (currentSpeed >= 0) {\n // Accelerate\n newSpeed = Math.min(\n speedMax,\n currentSpeed + acceleration * timeDelta\n );\n } else {\n // Turn back at least as fast as it would stop.\n newSpeed = Math.min(\n targetedSpeed,\n currentSpeed + Math.max(acceleration, deceleration) * timeDelta\n );\n }\n } else {\n // Decelerate and stop.\n if (currentSpeed < 0) {\n newSpeed = Math.min(currentSpeed + deceleration * timeDelta, 0);\n }\n if (currentSpeed > 0) {\n newSpeed = Math.max(currentSpeed - deceleration * timeDelta, 0);\n }\n }\n return newSpeed;\n }\n\n private updateGroundVelocity(\n behavior: Physics3DRuntimeBehavior,\n timeDelta: float\n ): boolean {\n if (!this.character) {\n return false;\n }\n const characterBody = behavior._body;\n if (!characterBody) {\n return false;\n }\n const worldInvScale = this._sharedData.worldInvScale;\n\n if (!this.character.IsSupported()) {\n return false;\n }\n\n const groundBody = this._sharedData.physicsSystem\n .GetBodyLockInterface()\n .TryGetBody(this.character.GetGroundBodyID());\n\n const stillKinematicPlatform =\n groundBody.IsKinematic() &&\n groundBody.GetLinearVelocity().Equals(Jolt.Vec3.prototype.sZero()) &&\n groundBody.GetAngularVelocity().Equals(Jolt.Vec3.prototype.sZero());\n if (stillKinematicPlatform) {\n const groundBehavior = groundBody.gdjsAssociatedBehavior;\n if (groundBehavior) {\n const inverseTimeDelta = 1 / timeDelta;\n // The platform may be moved by position changes instead of velocity.\n // Emulate a velocity from the position changes.\n groundBody.SetLinearVelocity(\n this.getVec3(\n (groundBehavior.owner3D.getX() - groundBehavior._objectOldX) *\n worldInvScale *\n inverseTimeDelta,\n (groundBehavior.owner3D.getY() - groundBehavior._objectOldY) *\n worldInvScale *\n inverseTimeDelta,\n (groundBehavior.owner3D.getZ() - groundBehavior._objectOldZ) *\n worldInvScale *\n inverseTimeDelta\n )\n );\n groundBody.SetAngularVelocity(\n this.getVec3(\n 0,\n 0,\n gdjs.toRad(\n gdjs.evtTools.common.angleDifference(\n groundBehavior.owner3D.getAngle(),\n groundBehavior._objectOldRotationZ\n )\n ) * inverseTimeDelta\n )\n );\n }\n }\n this.character.UpdateGroundVelocity();\n\n const groundAngularVelocityZ = groundBody.GetAngularVelocity().GetZ();\n if (groundAngularVelocityZ !== 0) {\n // Make the character rotate with the platform on Z axis.\n const angleDelta = groundAngularVelocityZ * timeDelta;\n this.character.SetRotation(\n Jolt.Quat.prototype.sEulerAngles(\n this.getVec3(\n 0,\n 0,\n this.character\n .GetRotation()\n .GetRotationAngle(Jolt.Vec3.prototype.sAxisZ()) + angleDelta\n )\n )\n );\n // Also update the forward angle to make sure it stays the same\n // relatively to the object angle.\n this._forwardAngle += gdjs.toDegrees(angleDelta);\n }\n if (stillKinematicPlatform) {\n groundBody.SetLinearVelocity(Jolt.Vec3.prototype.sZero());\n groundBody.SetAngularVelocity(Jolt.Vec3.prototype.sZero());\n }\n\n // Characters should not try to magnet on a body that rolls on the ground.\n const rollingSpeedMax = (1 * Math.PI) / 180;\n const shouldFollow =\n Math.abs(groundBody.GetAngularVelocity().GetX()) < rollingSpeedMax &&\n Math.abs(groundBody.GetAngularVelocity().GetY()) < rollingSpeedMax;\n return shouldFollow;\n }\n\n doStepPostEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {}\n\n onObjectHotReloaded() {}\n\n /**\n * Get maximum angle of a slope for the Character to run on it as a floor.\n * @returns the slope maximum angle, in degrees.\n */\n getSlopeMaxAngle(): float {\n return this._slopeMaxAngle;\n }\n\n /**\n * Set the maximum slope angle of the Character.\n * @param slopeMaxAngle The new maximum slope angle.\n */\n setSlopeMaxAngle(slopeMaxAngle: float): void {\n if (slopeMaxAngle < 0 || slopeMaxAngle >= 90) {\n return;\n }\n this._slopeMaxAngle = slopeMaxAngle;\n\n //Avoid rounding errors\n if (slopeMaxAngle === 45) {\n this._slopeClimbingFactor = 1;\n } else {\n // Avoid a `_slopeClimbingFactor` set to exactly 0.\n // Otherwise, this can lead the floor finding functions to consider\n // a floor to be \"too high\" to reach, even if the object is very slightly\n // inside it, which can happen because of rounding errors.\n // See \"Floating-point error mitigations\" tests.\n this._slopeClimbingFactor = Math.max(\n 1 / 1024,\n Math.tan(gdjs.toRad(slopeMaxAngle))\n );\n }\n // The floor is in 3D but to go back to 2D trigonometry, we can take the\n // 2D space generated by the floor normal and the Z axis, given that:\n // - The normal keeps the same Z coordinate (as the Z axis is included in the 2D space)\n // - The normal keeps the same length (as the normal is included in the 2D space)\n this._slopeClimbingMinNormalZ = Math.min(\n Math.cos(gdjs.toRad(slopeMaxAngle)),\n 1 - 1 / 1024\n );\n }\n\n getStairHeightMax(): float {\n return this._stairHeightMax;\n }\n\n setStairHeightMax(stairHeightMax: float): void {\n const { extendedUpdateSettings } = this.getPhysics3D();\n this._stairHeightMax = stairHeightMax;\n const walkStairsStepUp = stairHeightMax * this._sharedData.worldInvScale;\n extendedUpdateSettings.mWalkStairsStepUp = this.getVec3(\n 0,\n 0,\n walkStairsStepUp\n );\n // Use default values proportionally;\n // \"The factors are arbitrary but works well when tested in a game.\"\n extendedUpdateSettings.mWalkStairsMinStepForward =\n (0.02 / 0.4) * walkStairsStepUp;\n extendedUpdateSettings.mWalkStairsStepForwardTest =\n (0.15 / 0.4) * walkStairsStepUp;\n }\n\n /**\n * Get the gravity of the Character.\n * @returns The current gravity.\n */\n getGravity(): float {\n return this._gravity;\n }\n\n /**\n * Set the gravity of the Character.\n * @param gravity The new gravity.\n */\n setGravity(gravity: float): void {\n this._gravity = gravity;\n }\n\n /**\n * Get the maximum falling speed of the Character.\n * @returns The maximum falling speed.\n */\n getMaxFallingSpeed(): float {\n return this._maxFallingSpeed;\n }\n\n /**\n * Set the maximum falling speed of the Character.\n * @param maxFallingSpeed The maximum falling speed.\n * @param tryToPreserveAirSpeed If true and if jumping, tune the current\n * jump speed to preserve the overall speed in the air.\n */\n setMaxFallingSpeed(\n maxFallingSpeed: float,\n tryToPreserveAirSpeed: boolean = false\n ): void {\n if (tryToPreserveAirSpeed && !this.isOnFloor()) {\n // If the falling speed is too high compared to the new max falling speed,\n // reduce it and adapt the jump speed to preserve the overall vertical speed.\n const fallingSpeedOverflow = this._currentFallSpeed - maxFallingSpeed;\n if (fallingSpeedOverflow > 0) {\n this._currentFallSpeed -= fallingSpeedOverflow;\n this._currentJumpSpeed = Math.max(\n 0,\n this.getCurrentJumpSpeed() - fallingSpeedOverflow\n );\n }\n }\n this._maxFallingSpeed = maxFallingSpeed;\n }\n\n /**\n * Get the forward acceleration value of the Character.\n * @returns The current acceleration.\n */\n getForwardAcceleration(): float {\n return this._forwardAcceleration;\n }\n\n /**\n * Set the forward acceleration of the Character.\n * @param forwardAcceleration The new acceleration.\n */\n setForwardAcceleration(forwardAcceleration: float): void {\n this._forwardAcceleration = forwardAcceleration;\n }\n\n /**\n * Get the forward deceleration of the Character.\n * @returns The current deceleration.\n */\n getForwardDeceleration(): float {\n return this._forwardDeceleration;\n }\n\n /**\n * Set the forward deceleration of the Character.\n * @param forwardDeceleration The new deceleration.\n */\n setForwardDeceleration(forwardDeceleration: float): void {\n this._forwardDeceleration = forwardDeceleration;\n }\n\n /**\n * Get the forward maximum speed of the Character.\n * @returns The maximum speed.\n */\n getForwardSpeedMax(): float {\n return this._forwardSpeedMax;\n }\n\n /**\n * Set the forward maximum speed of the Character.\n * @param forwardSpeedMax The new maximum speed.\n */\n setForwardSpeedMax(forwardSpeedMax: float): void {\n this._forwardSpeedMax = forwardSpeedMax;\n }\n\n /**\n * Get the sideways acceleration value of the Character.\n * @returns The current acceleration.\n */\n getSidewaysAcceleration(): float {\n return this._sidewaysAcceleration;\n }\n\n /**\n * Set the sideways acceleration of the Character.\n * @param sidewaysAcceleration The new acceleration.\n */\n setSidewaysAcceleration(sidewaysAcceleration: float): void {\n this._sidewaysAcceleration = sidewaysAcceleration;\n }\n\n /**\n * Get the sideways deceleration of the Character.\n * @returns The current deceleration.\n */\n getSidewaysDeceleration(): float {\n return this._sidewaysDeceleration;\n }\n\n /**\n * Set the sideways deceleration of the Character.\n * @param sidewaysDeceleration The new deceleration.\n */\n setSidewaysDeceleration(sidewaysDeceleration: float): void {\n this._sidewaysDeceleration = sidewaysDeceleration;\n }\n\n /**\n * Get the sideways maximum speed of the Character.\n * @returns The maximum speed.\n */\n getSidewaysSpeedMax(): float {\n return this._sidewaysSpeedMax;\n }\n\n /**\n * Set the sideways maximum speed of the Character.\n * @param sidewaysSpeedMax The new maximum speed.\n */\n setSidewaysSpeedMax(sidewaysSpeedMax: float): void {\n this._sidewaysSpeedMax = sidewaysSpeedMax;\n }\n\n /**\n * Get the jump speed of the Character.\n * @returns The jump speed.\n */\n getJumpSpeed(): float {\n return this._jumpSpeed;\n }\n\n /**\n * Set the jump speed of the Character.\n * @param jumpSpeed The new jump speed.\n */\n setJumpSpeed(jumpSpeed: float): void {\n this._jumpSpeed = jumpSpeed;\n }\n\n /**\n * Get the jump sustain time of the Character.\n * @returns The jump sustain time.\n */\n getJumpSustainTime(): float {\n return this._jumpSustainTime;\n }\n\n /**\n * Set the jump sustain time of the Character.\n * @param jumpSpeed The new jump sustain time.\n */\n setJumpSustainTime(jumpSustainTime: float): void {\n this._jumpSustainTime = jumpSustainTime;\n }\n\n getForwardAngle(): float {\n return this._forwardAngle;\n }\n\n setForwardAngle(angle: float): void {\n this._forwardAngle = angle;\n if (this._shouldBindObjectAndForwardAngle) {\n this.owner.setAngle(angle);\n }\n }\n\n isForwardAngleAround(degreeAngle: float, tolerance: float) {\n return (\n Math.abs(\n gdjs.evtTools.common.angleDifference(this._forwardAngle, degreeAngle)\n ) <= tolerance\n );\n }\n\n shouldBindObjectAndForwardAngle(): boolean {\n return this._shouldBindObjectAndForwardAngle;\n }\n\n setShouldBindObjectAndForwardAngle(\n shouldBindObjectAndForwardAngle: boolean\n ): void {\n this._shouldBindObjectAndForwardAngle = shouldBindObjectAndForwardAngle;\n }\n\n /**\n * Get the current speed of the Character.\n * @returns The current speed.\n */\n getCurrentForwardSpeed(): float {\n return this._currentForwardSpeed;\n }\n\n /**\n * Set the current speed of the Character.\n * @param currentForwardSpeed The current speed.\n */\n setCurrentForwardSpeed(currentForwardSpeed: float): void {\n this._currentForwardSpeed = currentForwardSpeed;\n }\n\n /**\n * Get the current speed of the Character.\n * @returns The current speed.\n */\n getCurrentSidewaysSpeed(): float {\n return this._currentSidewaysSpeed;\n }\n\n /**\n * Set the current speed of the Character.\n * @param currentSidewaysSpeed The current speed.\n */\n setCurrentSidewaysSpeed(currentSidewaysSpeed: float): void {\n this._currentSidewaysSpeed = currentSidewaysSpeed;\n }\n\n /**\n * Get the speed at which the object is falling. It is 0 when the object is\n * on a floor, and non 0 as soon as the object leaves the floor.\n * @returns The current fall speed.\n */\n getCurrentFallSpeed(): float {\n return this._currentFallSpeed;\n }\n\n /**\n * Set the current fall speed.\n */\n setCurrentFallSpeed(currentFallSpeed: float) {\n this._currentFallSpeed = gdjs.evtTools.common.clamp(\n currentFallSpeed,\n 0,\n this._maxFallingSpeed\n );\n }\n\n /**\n * Get the current jump speed of the Character.\n * @returns The current jump speed.\n */\n getCurrentJumpSpeed(): float {\n return this._currentJumpSpeed;\n }\n\n /**\n * Set the current jump speed.\n */\n setCurrentJumpSpeed(currentJumpSpeed: float) {\n this._currentJumpSpeed = Math.max(0, currentJumpSpeed);\n }\n\n /**\n * Check if the Character can jump.\n * @returns Returns true if the object can jump.\n */\n canJump(): boolean {\n return this._canJump;\n }\n\n /**\n * Allow the Character to jump again.\n */\n setCanJump(): void {\n this._canJump = true;\n }\n\n /**\n * Forbid the Character to air jump.\n */\n setCanNotAirJump(): void {\n if (this.isJumping() || this.isFalling()) {\n this._canJump = false;\n }\n }\n\n /**\n * Abort the current jump.\n *\n * When the character is not in the jumping state this method has no effect.\n */\n abortJump(): void {\n if (this.isJumping()) {\n this._currentFallSpeed = 0;\n this._currentJumpSpeed = 0;\n }\n }\n\n simulateForwardKey(): void {\n this._hasPressedForwardKey = true;\n }\n\n wasForwardKeyPressed(): boolean {\n return this._wasForwardKeyPressed;\n }\n\n simulateBackwardKey(): void {\n this._hasPressedBackwardKey = true;\n }\n\n wasBackwardKeyPressed(): boolean {\n return this._wasBackwardKeyPressed;\n }\n\n simulateRightKey(): void {\n this._hasPressedRightKey = true;\n }\n\n wasRightKeyPressed(): boolean {\n return this._wasRightKeyPressed;\n }\n\n simulateLeftKey(): void {\n this._hasPressedLeftKey = true;\n }\n\n wasLeftKeyPressed(): boolean {\n return this._wasLeftKeyPressed;\n }\n\n simulateJumpKey(): void {\n this._hasPressedJumpKey = true;\n }\n\n wasJumpKeyPressed(): boolean {\n return this._wasJumpKeyPressed;\n }\n\n simulateStick(stickAngle: float, stickForce: float) {\n this._hasUsedStick = true;\n this._stickAngle = stickAngle;\n this._stickForce = Math.max(0, Math.min(1, stickForce));\n }\n\n wasStickUsed(): boolean {\n return this._wasStickUsed;\n }\n\n getStickAngle(): float {\n return this._wasStickUsed ? this._stickAngle : 0;\n }\n\n getStickForce(): float {\n return this._wasStickUsed ? this._stickForce : 0;\n }\n\n // TODO Should we add a \"is sliding\" condition?\n /**\n * Check if the Character is on a floor.\n * @returns Returns true if on a floor and false if not.\n */\n isOnFloor(): boolean {\n return this.character\n ? this.character.IsSupported() &&\n // Ensure characters don't land on too step floor.\n this.character.GetGroundNormal().GetZ() >=\n this._slopeClimbingMinNormalZ &&\n // Ensure characters don't land on a platform corner while jumping.\n this._currentJumpSpeed <= this._currentFallSpeed\n : false;\n }\n\n /**\n * Check if the Character is on the given object.\n * @returns Returns true if on the object and false if not.\n */\n isOnFloorObject(physics3DBehavior: gdjs.Physics3DRuntimeBehavior): boolean {\n if (!physics3DBehavior._body || !this.character || !this.isOnFloor()) {\n return false;\n }\n return (\n this.character.GetGroundBodyID().GetIndexAndSequenceNumber() ===\n physics3DBehavior._body.GetID().GetIndexAndSequenceNumber()\n );\n }\n\n /**\n * Check if the Character is jumping.\n * @returns Returns true if jumping and false if not.\n */\n isJumping(): boolean {\n return this._currentJumpSpeed > 0;\n }\n\n /**\n * Check if the Character is in the falling state. This is false\n * if the object is jumping, even if the object is going down after reaching\n * the jump peak.\n * @returns Returns true if it is falling and false if not.\n */\n isFallingWithoutJumping(): boolean {\n return !this.isOnFloor() && !this.isJumping();\n }\n\n /**\n * Check if the Character is \"going down\", either because it's in the\n * falling state *or* because it's jumping but reached the jump peak and\n * is now going down (because the jump speed can't compensate anymore the\n * falling speed).\n *\n * If you want to check if the object is falling outside of a jump (or because\n * the jump is entirely finished and there is no jump speed applied to the object\n * anymore), consider using `isFallingWithoutJumping`.\n *\n * @returns Returns true if it is \"going down\" and false if not.\n */\n isFalling(): boolean {\n return (\n this.isFallingWithoutJumping() ||\n (this.isJumping() && this._currentFallSpeed > this._currentJumpSpeed)\n );\n }\n\n /**\n * Check if the Character is moving.\n * @returns Returns true if it is moving and false if not.\n */\n isMovingEvenALittle(): boolean {\n return (\n (this._hasReallyMoved && this._currentForwardSpeed !== 0) ||\n this._currentJumpSpeed !== 0 ||\n this._currentFallSpeed !== 0\n );\n }\n\n getJumpSpeedToReach(jumpHeight: float): float {\n // Formulas used in this extension were generated from a math model.\n // They are probably not understandable on their own.\n // If you need to modify them or need to write new feature,\n // please take a look at the platformer extension documentation:\n // https://github.com/4ian/GDevelop/tree/master/Extensions/PlatformBehavior#readme\n\n jumpHeight = -Math.abs(jumpHeight);\n\n const gravity = this._gravity;\n const maxFallingSpeed = this._maxFallingSpeed;\n const jumpSustainTime = this._jumpSustainTime;\n\n const maxFallingSpeedReachedTime = maxFallingSpeed / gravity;\n\n // The implementation jumps from one quadratic resolution to another\n // to find the right formula to use as the time is unknown.\n\n const sustainCase = (jumpHeight) => Math.sqrt(-jumpHeight * gravity * 2);\n const maxFallingCase = (jumpHeight) =>\n -gravity * jumpSustainTime +\n maxFallingSpeed +\n Math.sqrt(\n gravity * gravity * jumpSustainTime * jumpSustainTime -\n 2 * jumpHeight * gravity -\n maxFallingSpeed * maxFallingSpeed\n );\n\n let jumpSpeed = 0;\n let peakTime = 0;\n if (maxFallingSpeedReachedTime > jumpSustainTime) {\n // common case\n jumpSpeed =\n -gravity * jumpSustainTime +\n Math.sqrt(\n 2 * gravity * gravity * jumpSustainTime * jumpSustainTime -\n 4 * jumpHeight * gravity\n );\n peakTime = (gravity * jumpSustainTime + jumpSpeed) / (2 * gravity);\n if (peakTime < jumpSustainTime) {\n jumpSpeed = sustainCase(jumpHeight);\n } else if (peakTime > maxFallingSpeedReachedTime) {\n jumpSpeed = maxFallingCase(jumpHeight);\n }\n } else {\n // affine case can't have a maximum\n\n // sustain case\n jumpSpeed = sustainCase(jumpHeight);\n peakTime = jumpSpeed / gravity;\n if (peakTime > maxFallingSpeedReachedTime) {\n jumpSpeed = maxFallingCase(jumpHeight);\n }\n }\n return jumpSpeed;\n }\n }\n\n gdjs.registerBehavior(\n 'Physics3D::PhysicsCharacter3D',\n gdjs.PhysicsCharacter3DRuntimeBehavior\n );\n\n export namespace PhysicsCharacter3DRuntimeBehavior {\n export class CharacterBodyUpdater {\n characterBehavior: gdjs.PhysicsCharacter3DRuntimeBehavior;\n /** Handle collisions between characters that can push each other. */\n static characterVsCharacterCollision: Jolt.CharacterVsCharacterCollisionSimple | null = null;\n\n constructor(characterBehavior: gdjs.PhysicsCharacter3DRuntimeBehavior) {\n this.characterBehavior = characterBehavior;\n }\n\n createAndAddBody(): Jolt.Body {\n const { _slopeMaxAngle, owner3D, _sharedData } = this.characterBehavior;\n const { behavior } = this.characterBehavior.getPhysics3D();\n\n const shape = behavior.createShape();\n\n const settings = new Jolt.CharacterVirtualSettings();\n // Characters innerBody are Kinematic body, they don't allow other\n // characters to push them.\n // The layer 0 doesn't allow any collision as masking them always result to 0.\n // This allows CharacterVsCharacterCollisionSimple to handle the collisions.\n settings.mInnerBodyLayer = this.characterBehavior._canBePushed\n ? 0\n : behavior.getBodyLayer();\n settings.mInnerBodyShape = shape;\n settings.mMass = shape.GetMassProperties().get_mMass();\n settings.mMaxSlopeAngle = gdjs.toRad(_slopeMaxAngle);\n settings.mShape = shape;\n settings.mUp = Jolt.Vec3.prototype.sAxisZ();\n settings.mBackFaceMode = Jolt.EBackFaceMode_CollideWithBackFaces;\n // TODO Should we make them configurable?\n //settings.mMaxStrength = maxStrength;\n //settings.mCharacterPadding = characterPadding;\n //settings.mPenetrationRecoverySpeed = penetrationRecoverySpeed;\n //settings.mPredictiveContactDistance = predictiveContactDistance;\n const depth = owner3D.getDepth() * _sharedData.worldInvScale;\n const width = owner3D.getWidth() * _sharedData.worldInvScale;\n const height = owner3D.getHeight() * _sharedData.worldInvScale;\n // Only the bottom of the capsule can make a contact with the floor.\n // It avoids characters from sticking to walls.\n const capsuleHalfLength = depth / 2;\n const capsuleRadius = Math.sqrt(width * height) / 2;\n settings.mSupportingVolume = new Jolt.Plane(\n Jolt.Vec3.prototype.sAxisZ(),\n // TODO It's strange that the value is positive.\n // Use a big safety margin as the ground normal will be checked anyway.\n // It only avoids to detect walls as ground.\n capsuleHalfLength -\n capsuleRadius *\n (1 - Math.cos(gdjs.toRad(Math.min(_slopeMaxAngle + 20, 70))))\n );\n const character = new Jolt.CharacterVirtual(\n settings,\n this.characterBehavior.getPhysicsPosition(\n _sharedData.getRVec3(0, 0, 0)\n ),\n behavior.getPhysicsRotation(_sharedData.getQuat(0, 0, 0, 1)),\n _sharedData.physicsSystem\n );\n const body = _sharedData.physicsSystem\n .GetBodyLockInterface()\n .TryGetBody(character.GetInnerBodyID());\n this.characterBehavior.character = character;\n\n if (this.characterBehavior._canBePushed) {\n // CharacterVsCharacterCollisionSimple handle characters pushing each other.\n let characterVsCharacterCollision =\n CharacterBodyUpdater.characterVsCharacterCollision;\n if (!characterVsCharacterCollision) {\n characterVsCharacterCollision = new Jolt.CharacterVsCharacterCollisionSimple();\n CharacterBodyUpdater.characterVsCharacterCollision = characterVsCharacterCollision;\n }\n characterVsCharacterCollision.Add(character);\n character.SetCharacterVsCharacterCollision(\n characterVsCharacterCollision\n );\n\n const characterContactListener = new Jolt.CharacterContactListenerJS();\n characterContactListener.OnAdjustBodyVelocity = (\n character,\n body2Ptr,\n linearVelocityPtr,\n angularVelocity\n ) => {};\n characterContactListener.OnContactValidate = (\n character,\n bodyID2,\n subShapeID2\n ) => {\n return true;\n };\n characterContactListener.OnCharacterContactValidate = (\n characterPtr,\n otherCharacterPtr,\n subShapeID2\n ) => {\n // CharacterVsCharacterCollisionSimple doesn't handle collision layers.\n // We have to filter characters ourself.\n const character = Jolt.wrapPointer(\n characterPtr,\n Jolt.CharacterVirtual\n );\n const otherCharacter = Jolt.wrapPointer(\n otherCharacterPtr,\n Jolt.CharacterVirtual\n );\n\n const body = _sharedData.physicsSystem\n .GetBodyLockInterface()\n .TryGetBody(character.GetInnerBodyID());\n const otherBody = _sharedData.physicsSystem\n .GetBodyLockInterface()\n .TryGetBody(otherCharacter.GetInnerBodyID());\n\n const physicsBehavior = body.gdjsAssociatedBehavior;\n const otherPhysicsBehavior = otherBody.gdjsAssociatedBehavior;\n\n if (!physicsBehavior || !otherPhysicsBehavior) {\n return true;\n }\n return physicsBehavior.canCollideAgainst(otherPhysicsBehavior);\n };\n characterContactListener.OnContactAdded = (\n character,\n bodyID2,\n subShapeID2,\n contactPosition,\n contactNormal,\n settings\n ) => {};\n characterContactListener.OnCharacterContactAdded = (\n character,\n otherCharacter,\n subShapeID2,\n contactPosition,\n contactNormal,\n settings\n ) => {};\n characterContactListener.OnContactSolve = (\n character,\n bodyID2,\n subShapeID2,\n contactPosition,\n contactNormal,\n contactVelocity,\n contactMaterial,\n characterVelocity,\n newCharacterVelocity\n ) => {};\n characterContactListener.OnCharacterContactSolve = (\n character,\n otherCharacter,\n subShapeID2,\n contactPosition,\n contactNormal,\n contactVelocity,\n contactMaterial,\n characterVelocityPtr,\n newCharacterVelocityPtr\n ) => {};\n character.SetListener(characterContactListener);\n }\n\n // TODO This is not really reliable. We could choose to disable it and force user to use the \"is on platform\" condition.\n //body.SetCollideKinematicVsNonDynamic(true);\n return body;\n }\n\n updateObjectFromBody() {\n const { character } = this.characterBehavior;\n if (!character) {\n return;\n }\n // We can't rely on the body position because of mCharacterPadding.\n this.characterBehavior.moveObjectToPhysicsPosition(\n character.GetPosition()\n );\n this.characterBehavior.moveObjectToPhysicsRotation(\n character.GetRotation()\n );\n }\n\n updateBodyFromObject() {\n const { behavior } = this.characterBehavior.getPhysics3D();\n const { character, owner3D, _sharedData } = this.characterBehavior;\n if (!character) {\n return;\n }\n if (\n behavior._objectOldX !== owner3D.getX() ||\n behavior._objectOldY !== owner3D.getY() ||\n behavior._objectOldZ !== owner3D.getZ()\n ) {\n this.updateCharacterPosition();\n }\n if (\n behavior._objectOldRotationX !== owner3D.getRotationX() ||\n behavior._objectOldRotationY !== owner3D.getRotationY() ||\n behavior._objectOldRotationZ !== owner3D.getAngle()\n ) {\n character.SetRotation(\n this.characterBehavior.getPhysicsRotation(\n _sharedData.getQuat(0, 0, 0, 1)\n )\n );\n }\n }\n\n updateCharacterPosition() {\n const { character, _sharedData } = this.characterBehavior;\n if (!character) {\n return;\n }\n character.SetPosition(\n this.characterBehavior.getPhysicsPosition(\n _sharedData.getRVec3(0, 0, 0)\n )\n );\n }\n\n recreateShape() {\n const {\n behavior,\n broadPhaseLayerFilter,\n objectLayerFilter,\n bodyFilter,\n shapeFilter,\n } = this.characterBehavior.getPhysics3D();\n const { character, _sharedData } = this.characterBehavior;\n if (!character) {\n return;\n }\n const shape = behavior.createShape();\n const isShapeValid = character.SetShape(\n shape,\n Number.MAX_VALUE,\n broadPhaseLayerFilter,\n objectLayerFilter,\n bodyFilter,\n shapeFilter,\n _sharedData.jolt.GetTempAllocator()\n );\n if (!isShapeValid) {\n return;\n }\n character.SetInnerBodyShape(shape);\n character.SetMass(shape.GetMassProperties().get_mMass());\n\n // shapeHalfDepth may have changed, update the character position accordingly.\n this.updateCharacterPosition();\n }\n }\n\n /**\n * A character is simulated by Jolt before the rest of the physics simulation\n * (see `doBeforePhysicsStep`).\n * This means that contacts with the character would only rarely be recognized by\n * the physics engine if using the default contact listeners.\n * Instead, this class allows to properly track contacts of the character\n * using Jolt `CharacterVirtual::GetActiveContacts`.\n */\n export class CharacterCollisionChecker\n implements gdjs.Physics3DRuntimeBehavior.CollisionChecker {\n characterBehavior: gdjs.PhysicsCharacter3DRuntimeBehavior;\n\n _currentContacts: Array<Physics3DRuntimeBehavior> = [];\n _previousContacts: Array<Physics3DRuntimeBehavior> = [];\n\n constructor(characterBehavior: gdjs.PhysicsCharacter3DRuntimeBehavior) {\n this.characterBehavior = characterBehavior;\n }\n\n clearContacts(): void {\n this._previousContacts.length = 0;\n this._currentContacts.length = 0;\n }\n\n updateContacts(): void {\n const swap = this._previousContacts;\n this._previousContacts = this._currentContacts;\n this._currentContacts = swap;\n this._currentContacts.length = 0;\n\n const { character, _sharedData } = this.characterBehavior;\n if (!character) {\n return;\n }\n const contacts = character.GetActiveContacts();\n for (let index = 0; index < contacts.size(); index++) {\n const contact = contacts.at(index);\n\n const bodyLockInterface = _sharedData.physicsSystem.GetBodyLockInterface();\n const body = bodyLockInterface.TryGetBody(contact.mBodyB);\n const behavior = body.gdjsAssociatedBehavior;\n if (behavior) {\n this._currentContacts.push(behavior);\n }\n }\n }\n\n isColliding(object: gdjs.RuntimeObject): boolean {\n const { character } = this.characterBehavior;\n if (!character) {\n return false;\n }\n return this._currentContacts.some(\n (behavior) => behavior.owner === object\n );\n }\n\n hasCollisionStartedWith(object: gdjs.RuntimeObject): boolean {\n const { character } = this.characterBehavior;\n if (!character) {\n return false;\n }\n return (\n this._currentContacts.some((behavior) => behavior.owner === object) &&\n !this._previousContacts.some((behavior) => behavior.owner === object)\n );\n }\n\n hasCollisionStoppedWith(object: gdjs.RuntimeObject): boolean {\n const { character } = this.characterBehavior;\n if (!character) {\n return false;\n }\n return (\n !this._currentContacts.some(\n (behavior) => behavior.owner === object\n ) &&\n this._previousContacts.some((behavior) => behavior.owner === object)\n );\n }\n }\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }