Files
GDevelop/Extensions/Lighting/tests/lightruntimeobject.spec.js
T
Harsimran Singh Virk 599ccb677f Add support for visual effects ("shaders") on objects. (#2901)
* This allows to generate interesting visual effects, which can be controlled by events. For example, you can use an outline on an object to highlight, make the player glow when launching a spell, blur objects, etc...
* A new "effects" tab is now present in the objects editor. From there, you can add visual effects, that were already available for layers, customize them from this editor.
* Actions and conditions are available to manipulate effects and change their parameters during the game.
* Learn more on the wiki: http://wiki.compilgames.net/doku.php/gdevelop5/objects/effects

Co-authored-by: Florian Rival <Florian.Rival@gmail.com>
2021-08-20 15:01:06 +02:00

203 lines
6.5 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 = new gdjs.RuntimeGame({
variables: [],
resources: {
resources: [],
},
properties: { windowWidth: 800, windowHeight: 600 },
});
const runtimeScene = new gdjs.RuntimeScene(runtimeGame);
runtimeScene.loadFromScene({
layers: [{ name: '', visibility: true, effects: [] }],
variables: [],
behaviorsSharedData: [],
objects: [],
instances: [],
});
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 = new gdjs.RuntimeGame({
variables: [],
resources: {
resources: [],
},
properties: { windowWidth: 800, windowHeight: 600 },
});
const runtimeScene = new gdjs.RuntimeScene(runtimeGame);
runtimeScene.loadFromScene({
layers: [{ name: '', visibility: true, effects: [] }],
variables: [],
behaviorsSharedData: [],
objects: [],
instances: [],
});
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);
});
});
});