mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Add gravity and forces.
This commit is contained in:
@@ -54,6 +54,27 @@ module.exports = {
|
||||
propertyName,
|
||||
newValue
|
||||
) {
|
||||
console.log("updateProperty: " + propertyName);
|
||||
if (propertyName === 'gravityX') {
|
||||
const newValueAsNumber = parseFloat(newValue);
|
||||
if (newValueAsNumber !== newValueAsNumber) return false;
|
||||
sharedContent.getChild('gravityX').setDoubleValue(newValueAsNumber);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'gravityY') {
|
||||
const newValueAsNumber = parseFloat(newValue);
|
||||
if (newValueAsNumber !== newValueAsNumber) return false;
|
||||
sharedContent.getChild('gravityY').setDoubleValue(newValueAsNumber);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'gravityZ') {
|
||||
const newValueAsNumber = parseFloat(newValue);
|
||||
if (newValueAsNumber !== newValueAsNumber) return false;
|
||||
sharedContent.getChild('gravityZ').setDoubleValue(newValueAsNumber);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (propertyName === 'worldScale') {
|
||||
const newValueAsNumber = parseInt(newValue, 10);
|
||||
@@ -70,6 +91,29 @@ module.exports = {
|
||||
sharedData.getProperties = function (sharedContent) {
|
||||
const sharedProperties = new gd.MapStringPropertyDescriptor();
|
||||
|
||||
sharedProperties
|
||||
.getOrCreate('gravityX')
|
||||
.setValue(
|
||||
sharedContent.getChild('gravityX').getDoubleValue().toString(10)
|
||||
)
|
||||
.setType('Number')
|
||||
.setMeasurementUnit(gd.MeasurementUnit.getNewton());
|
||||
sharedProperties
|
||||
.getOrCreate('gravityY')
|
||||
.setValue(
|
||||
sharedContent.getChild('gravityY').getDoubleValue().toString(10)
|
||||
)
|
||||
.setType('Number')
|
||||
.setMeasurementUnit(gd.MeasurementUnit.getNewton());
|
||||
sharedProperties
|
||||
.getOrCreate('gravityZ')
|
||||
.setValue(
|
||||
sharedContent.getChild('gravityZ').getDoubleValue().toString(10)
|
||||
)
|
||||
.setType('Number')
|
||||
.setMeasurementUnit(gd.MeasurementUnit.getNewton());
|
||||
|
||||
|
||||
sharedProperties
|
||||
.getOrCreate('worldScale')
|
||||
.setValue(
|
||||
@@ -80,6 +124,9 @@ module.exports = {
|
||||
return sharedProperties;
|
||||
};
|
||||
sharedData.initializeContent = function (behaviorContent) {
|
||||
behaviorContent.addChild('gravityX').setDoubleValue(0);
|
||||
behaviorContent.addChild('gravityY').setDoubleValue(0);
|
||||
behaviorContent.addChild('gravityZ').setDoubleValue(-9.8);
|
||||
behaviorContent.addChild('worldScale').setDoubleValue(100);
|
||||
};
|
||||
|
||||
@@ -105,6 +152,115 @@ module.exports = {
|
||||
//.addIncludeFile('Extensions/Physics3DBehavior/jolt-physics.multithread.wasm-compat.js')
|
||||
.setOpenFullEditorLabel(_('Edit shape and advanced settings'));
|
||||
|
||||
// Forces and impulses
|
||||
aut
|
||||
.addAction(
|
||||
'ApplyForce',
|
||||
_('Apply force'),
|
||||
_(
|
||||
'Apply a force to the object over time. It "accelerates" an object and must be used every frame during a time period.'
|
||||
),
|
||||
_('Apply a force of _PARAM2_ ; _PARAM3_ ; _PARAM4_ to _PARAM0_ at _PARAM5_ ; _PARAM6_ ; _PARAM7_'),
|
||||
_('Forces & impulses'),
|
||||
'res/physics32.png',
|
||||
'res/physics32.png'
|
||||
)
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Physics3DBehavior')
|
||||
.addParameter('expression', _('X component (N)'))
|
||||
.addParameter('expression', _('Y component (N)'))
|
||||
.addParameter('expression', _('Z component (N)'))
|
||||
.setParameterLongDescription(
|
||||
_('A force is like an acceleration but depends on the mass.')
|
||||
)
|
||||
.addParameter('expression', _('Application point on X axis'))
|
||||
.addParameter('expression', _('Application point on Y axis'))
|
||||
.addParameter('expression', _('Application point on Z axis'))
|
||||
.setParameterLongDescription(
|
||||
_(
|
||||
'Use `MassCenterX` and `MassCenterY` expressions to avoid any rotation.'
|
||||
)
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('applyForce');
|
||||
|
||||
aut
|
||||
.addAction(
|
||||
'ApplyForceAtCenter',
|
||||
_('Apply force (at center)'),
|
||||
_(
|
||||
'Apply a force to the object over time. It "accelerates" an object and must be used every frame during a time period.'
|
||||
),
|
||||
_('Apply a force of _PARAM2_ ; _PARAM3_ ; _PARAM4_ at the center of _PARAM0_'),
|
||||
_('Forces & impulses'),
|
||||
'res/physics32.png',
|
||||
'res/physics32.png'
|
||||
)
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Physics3DBehavior')
|
||||
.addParameter('expression', _('X component (N)'))
|
||||
.addParameter('expression', _('Y component (N)'))
|
||||
.addParameter('expression', _('Z component (N)'))
|
||||
.setParameterLongDescription(
|
||||
_('A force is like an acceleration but depends on the mass.')
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('applyForceAtCenter');
|
||||
|
||||
aut
|
||||
.addScopedAction(
|
||||
'ApplyImpulse',
|
||||
_('Apply impulse'),
|
||||
_(
|
||||
'Apply an impulse to the object. It instantly changes the speed, to give an initial speed for instance.'
|
||||
),
|
||||
_('Apply an impulse of _PARAM2_ ; _PARAM3_ ; _PARAM4_ to _PARAM0_ at _PARAM5_ ; _PARAM6_ ; _PARAM7_'),
|
||||
_('Forces & impulses'),
|
||||
'res/physics32.png',
|
||||
'res/physics32.png'
|
||||
)
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Physics3DBehavior')
|
||||
.addParameter('expression', _('X component (N·s or kg·m·s⁻¹)'))
|
||||
.addParameter('expression', _('Y component (N·s or kg·m·s⁻¹)'))
|
||||
.addParameter('expression', _('Z component (N·s or kg·m·s⁻¹)'))
|
||||
.setParameterLongDescription(
|
||||
_('An impulse is like a speed addition but depends on the mass.')
|
||||
)
|
||||
.addParameter('expression', _('Application point on X axis'))
|
||||
.addParameter('expression', _('Application point on Y axis'))
|
||||
.addParameter('expression', _('Application point on Z axis'))
|
||||
.setParameterLongDescription(
|
||||
_(
|
||||
'Use `MassCenterX`, `MassCenterY` and `MassCenterZ` expressions to avoid any rotation.'
|
||||
)
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('applyImpulse');
|
||||
|
||||
aut
|
||||
.addScopedAction(
|
||||
'ApplyImpulseAtCenter',
|
||||
_('Apply impulse (at center)'),
|
||||
_(
|
||||
'Apply an impulse to the object. It instantly changes the speed, to give an initial speed for instance.'
|
||||
),
|
||||
_('Apply an impulse of _PARAM2_ ; _PARAM3_ ; _PARAM4_ at the center of _PARAM0_'),
|
||||
_('Forces & impulses'),
|
||||
'res/physics32.png',
|
||||
'res/physics32.png'
|
||||
)
|
||||
.addParameter('object', _('Object'), '', false)
|
||||
.addParameter('behavior', _('Behavior'), 'Physics3DBehavior')
|
||||
.addParameter('expression', _('X component (N·s or kg·m·s⁻¹)'))
|
||||
.addParameter('expression', _('Y component (N·s or kg·m·s⁻¹)'))
|
||||
.addParameter('expression', _('Z component (N·s or kg·m·s⁻¹)'))
|
||||
.setParameterLongDescription(
|
||||
_('An impulse is like a speed addition but depends on the mass.')
|
||||
)
|
||||
.getCodeExtraInformation()
|
||||
.setFunctionName('applyImpulseAtCenter');
|
||||
|
||||
return extension;
|
||||
},
|
||||
|
||||
|
@@ -45,7 +45,7 @@ namespace gdjs {
|
||||
const LAYER_MOVING = 1;
|
||||
const NUM_OBJECT_LAYERS = 2;
|
||||
|
||||
const setupCollisionFiltering = (settings) => {
|
||||
const setupCollisionFiltering = (settings: Jolt.JoltSettings) => {
|
||||
// Layer that objects can be in, determines which other objects it can collide with
|
||||
// Typically you at least want to have 1 layer for moving bodies and 1 layer for static bodies, but you can have more
|
||||
// layers if you want. E.g. you could have a layer for high detail collision (which is not used by the physics simulation
|
||||
@@ -83,6 +83,9 @@ namespace gdjs {
|
||||
};
|
||||
|
||||
export class Physics3DSharedData {
|
||||
gravityX: float;
|
||||
gravityY: float;
|
||||
gravityZ: float;
|
||||
worldScale: float;
|
||||
worldInvScale: float;
|
||||
|
||||
@@ -100,6 +103,9 @@ namespace gdjs {
|
||||
|
||||
constructor(instanceContainer: gdjs.RuntimeInstanceContainer, sharedData) {
|
||||
this._registeredBehaviors = new Set<Physics3DRuntimeBehavior>();
|
||||
this.gravityX = sharedData.gravityX;
|
||||
this.gravityY = sharedData.gravityY;
|
||||
this.gravityZ = sharedData.gravityZ;
|
||||
this.worldScale = sharedData.worldScale;
|
||||
this.worldInvScale = 1 / this.worldScale;
|
||||
|
||||
@@ -109,6 +115,9 @@ namespace gdjs {
|
||||
this.jolt = new Jolt.JoltInterface(settings);
|
||||
Jolt.destroy(settings);
|
||||
this.physicsSystem = this.jolt.GetPhysicsSystem();
|
||||
this.physicsSystem.SetGravity(
|
||||
new Jolt.Vec3(this.gravityX, this.gravityY, this.gravityZ)
|
||||
);
|
||||
this.bodyInterface = this.physicsSystem.GetBodyInterface();
|
||||
}
|
||||
|
||||
@@ -281,9 +290,11 @@ namespace gdjs {
|
||||
Jolt.EMotionType_Dynamic,
|
||||
LAYER_MOVING
|
||||
);
|
||||
bodyCreationSettings.mFriction = 0.001;
|
||||
|
||||
this._body =
|
||||
this._sharedData.bodyInterface.CreateBody(bodyCreationSettings);
|
||||
const bodyInterface = this._sharedData.bodyInterface;
|
||||
this._body = bodyInterface.CreateBody(bodyCreationSettings);
|
||||
bodyInterface.AddBody(this._body.GetID(), Jolt.EActivation_Activate);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -350,7 +361,10 @@ namespace gdjs {
|
||||
this._objectOldRotationZ = this.owner3D.getAngle();
|
||||
}
|
||||
|
||||
doStepPostEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {}
|
||||
doStepPostEvents(instanceContainer: gdjs.RuntimeInstanceContainer) {
|
||||
// Reset world step to update next frame
|
||||
this._sharedData.stepped = false;
|
||||
}
|
||||
|
||||
onObjectHotReloaded() {
|
||||
this.updateBodyFromObject();
|
||||
@@ -396,6 +410,88 @@ namespace gdjs {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
applyForce(
|
||||
forceX: float,
|
||||
forceY: float,
|
||||
forceZ: float,
|
||||
positionX: float,
|
||||
positionY: float,
|
||||
positionZ: float
|
||||
): void {
|
||||
// If there is no body, set a new one
|
||||
if (this._body === null) {
|
||||
if (!this.createBody()) return;
|
||||
}
|
||||
const body = this._body!;
|
||||
|
||||
this._sharedData.bodyInterface.AddForce(
|
||||
body.GetID(),
|
||||
new Jolt.Vec3(forceX, forceY, forceZ),
|
||||
new Jolt.RVec3(
|
||||
positionX * this._sharedData.worldInvScale,
|
||||
positionY * this._sharedData.worldInvScale,
|
||||
positionZ * this._sharedData.worldInvScale
|
||||
),
|
||||
Jolt.EActivation_Activate
|
||||
);
|
||||
}
|
||||
|
||||
applyForceAtCenter(forceX: float, forceY: float, forceZ: float): void {
|
||||
// If there is no body, set a new one
|
||||
if (this._body === null) {
|
||||
if (!this.createBody()) return;
|
||||
}
|
||||
const body = this._body!;
|
||||
|
||||
this._sharedData.bodyInterface.AddForce(
|
||||
body.GetID(),
|
||||
new Jolt.Vec3(forceX, forceY, forceZ),
|
||||
Jolt.EActivation_Activate
|
||||
);
|
||||
}
|
||||
|
||||
applyImpulse(
|
||||
impulseX: float,
|
||||
impulseY: float,
|
||||
impulseZ: float,
|
||||
positionX: float,
|
||||
positionY: float,
|
||||
positionZ: float
|
||||
): void {
|
||||
// If there is no body, set a new one
|
||||
if (this._body === null) {
|
||||
if (!this.createBody()) return;
|
||||
}
|
||||
const body = this._body!;
|
||||
|
||||
this._sharedData.bodyInterface.AddImpulse(
|
||||
body.GetID(),
|
||||
new Jolt.Vec3(impulseX, impulseY, impulseZ),
|
||||
new Jolt.RVec3(
|
||||
positionX * this._sharedData.worldInvScale,
|
||||
positionY * this._sharedData.worldInvScale,
|
||||
positionZ * this._sharedData.worldInvScale
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
applyImpulseAtCenter(
|
||||
impulseX: float,
|
||||
impulseY: float,
|
||||
impulseZ: float
|
||||
): void {
|
||||
// If there is no body, set a new one
|
||||
if (this._body === null) {
|
||||
if (!this.createBody()) return;
|
||||
}
|
||||
const body = this._body!;
|
||||
|
||||
this._sharedData.bodyInterface.AddImpulse(
|
||||
body.GetID(),
|
||||
new Jolt.Vec3(impulseX, impulseY, impulseZ)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
gdjs.registerBehavior(
|
||||
|
Reference in New Issue
Block a user