Files
GDevelop/Extensions/Lighting/tests/lightruntimeobject.spec.js
D8H 75bfa5cb45 Unify variable instructions and handle local variables (#6459)
- Global or scene variables can be used with a unique action and condition.
- Object variables can be used with a unique action and condition.
- Variables need to be declared following the same logic as the new expression syntax.
- Local variable can be declared on events
- Extensions have their own variables
- Show a diagnostic report when a preview is launched and there are missing scene variables, object variables or behaviors.
  - This is especially useful if external events are shared between several scenes.
2024-05-20 23:14:07 +02:00

197 lines
6.4 KiB
JavaScript

/**
* Tests for Light Object
*/
/**
* Utility function for adding light object for tests.
* @param {gdjs.RuntimeScene} runtimeScene
* @param {number} radius
* @returns {gdjs.LightRuntimeObject}
*/
const addLightObject = (runtimeScene, radius) => {
const lightObj = new gdjs.LightRuntimeObject(runtimeScene, {
name: 'lightObject',
type: 'Lighting::LightObject',
variables: [],
behaviors: [],
effects: [],
content: {
radius: radius,
color: '#b4b4b4',
texture: '',
debugMode: false,
},
});
runtimeScene.addObject(lightObj);
return lightObj;
};
/**
* Utility function for adding light obstacle for tests.
* @param {gdjs.RuntimeScene} runtimeScene
* @param {number} width
* @param {number} height
* @returns {gdjs.RuntimeObject}
*/
const addLightObstacle = (runtimeScene, width, height) => {
const obstacle = new gdjs.RuntimeObject(runtimeScene, {
name: 'lightObstacle',
type: '',
behaviors: [
{
type: 'Lighting::LightObstacleBehavior',
},
],
effects: [],
});
obstacle.getWidth = function () {
return width;
};
obstacle.getHeight = function () {
return height;
};
runtimeScene.addObject(obstacle);
return obstacle;
};
describe('gdjs.LightRuntimeObject', function () {
PIXI.settings.FAIL_IF_MAJOR_PERFORMANCE_CAVEAT = false;
const runtimeGame = gdjs.getPixiRuntimeGame();
const runtimeScene = new gdjs.RuntimeScene(runtimeGame);
runtimeScene.loadFromScene({
sceneData: {
layers: [{ name: '', visibility: true, effects: [] }],
variables: [],
behaviorsSharedData: [],
objects: [],
instances: [],
},
usedExtensionsWithVariablesData: [],
});
const lightObj = addLightObject(runtimeScene, 100);
lightObj.setPosition(200, 200);
it('check object properties', function () {
expect(lightObj.getRadius()).to.be(100);
expect(lightObj.getColor()).to.eql('180;180;180');
expect(lightObj.getDebugMode()).to.be(false);
expect(lightObj.getDrawableX()).to.be(100);
expect(lightObj.getDrawableY()).to.be(100);
});
it('bail out early while raycasting when there is no light obstacle', function () {
expect(lightObj._renderer._computeLightVertices()).to.eql([]);
lightObj._renderer._updateBuffers();
expect(lightObj._renderer._defaultVertexBuffer).to.eql(
new Float32Array([100, 300, 300, 300, 300, 100, 100, 100])
);
expect(gdjs.LightRuntimeObjectPixiRenderer._defaultIndexBuffer).to.eql(
new Float32Array([0, 1, 2, 0, 2, 3])
);
});
});
describe('Light with obstacles around it', function () {
PIXI.settings.FAIL_IF_MAJOR_PERFORMANCE_CAVEAT = false;
const runtimeGame = gdjs.getPixiRuntimeGame();
const runtimeScene = new gdjs.RuntimeScene(runtimeGame);
runtimeScene.loadFromScene({
sceneData: {
layers: [{ name: '', visibility: true, effects: [] }],
variables: [],
behaviorsSharedData: [],
objects: [],
instances: [],
},
usedExtensionsWithVariablesData: [],
});
runtimeScene._timeManager.getElapsedTime = function () {
return (1 / 60) * 1000;
};
const light = addLightObject(runtimeScene, 100);
const obstacle = addLightObstacle(runtimeScene, 50, 50);
it('Vertex and index buffers when light obstacle is present.', function () {
light.setPosition(200, 200);
obstacle.setPosition(250, 250);
runtimeScene.renderAndStep(1000 / 60);
light.update();
const vertexBuffer = light._renderer._vertexBuffer;
const indexBuffer = light._renderer._indexBuffer;
// prettier-ignore
const expectedVertexBuffer = [
200, 200, 100, 100.0199966430664, 100, 100, 100.0199966430664, 100, 299.9800109863281,
100, 300, 100, 300, 100.0199966430664, 300, 249.9875030517578, 300, 250, 299.9750061035156,
250, 250.00999450683594, 250, 250, 250, 250,250.00999450683594, 250, 299.9750061035156, 250,
300, 249.9875030517578, 300, 100.0199966430664, 300, 100, 300, 100, 299.9800109863281,
];
// prettier-ignore
const expectedIndexBuffer = [
0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6,
0, 6, 7, 0, 7, 8, 0, 8, 9, 0, 9, 10, 0, 10, 11,
0, 11, 12, 0, 12, 13, 0, 13, 14, 0, 14, 15, 0,
15, 16, 0, 16, 17, 0, 17, 18, 0, 18, 1,
];
expectedVertexBuffer.forEach((val, index) => {
expect(vertexBuffer[index]).to.be(val);
});
expectedIndexBuffer.forEach((val, index) => {
expect(indexBuffer[index]).to.be(val);
});
});
it('Vertex and index buffers after obstacle is moved.', function () {
obstacle.setPosition(150, 250);
runtimeScene.renderAndStep(1000 / 60);
light.update();
const vertexBuffer = light._renderer._vertexBuffer;
const indexBuffer = light._renderer._indexBuffer;
// prettier-ignore
const expectedVertexBuffer = [
200, 200, 100, 100.0199966430664, 100, 100, 100.0199966430664, 100, 299.9800109863281,
100, 300, 100, 300, 100.0199966430664, 300, 299.9800109863281, 300, 300, 299.9800109863281,
300, 200.00999450683594, 300, 200, 250, 199.9949951171875, 250, 175.00625610351562, 250,
175, 250, 174.99374389648438, 250, 150.00999450683594, 250, 150, 250, 100, 299.9800109863281,
];
// prettier-ignore
const expectedIndexBuffer = [
0, 1, 2, 0, 2, 3, 0, 3, 4, 0, 4, 5, 0, 5, 6, 0,
6, 7, 0, 7, 8, 0, 8, 9, 0, 9, 10, 0, 10, 11, 0,
11, 12, 0, 12, 13, 0, 13, 14, 0, 14, 15, 0, 15,
16, 0, 16, 17, 0, 17, 18, 0, 18, 1,
];
expectedVertexBuffer.forEach((val, index) => {
expect(vertexBuffer[index]).to.be(val);
});
expectedIndexBuffer.forEach((val, index) => {
expect(indexBuffer[index]).to.be(val);
});
});
it("Obstacle moved outside light's radius.", function () {
obstacle.setPosition(400, 400);
runtimeScene.renderAndStep(1000 / 60);
light.update();
// Ensure the fallback to simple quads. There shouldn't be anymore calculations
// when the obstacle is not inside light's area.
expect(light._renderer._computeLightVertices().length).to.eql(0);
const vertexBuffer = light._renderer._defaultVertexBuffer;
const indexBuffer = gdjs.LightRuntimeObjectPixiRenderer._defaultIndexBuffer;
const vertexData = [100, 300, 300, 300, 300, 100, 100, 100];
const indexData = [0, 1, 2, 0, 2, 3];
vertexData.forEach((val, index) => {
expect(vertexBuffer[index]).to.be(val);
});
indexData.forEach((val, index) => {
expect(indexBuffer[index]).to.be(val);
});
});
});