From d6407794179d3e8c35f473b4f9dee5a3f79c1896 Mon Sep 17 00:00:00 2001 From: diarmidmackenzie Date: Sat, 29 Jul 2023 16:09:21 +0100 Subject: [PATCH] Move sortFunctions.js module into systems/renderer.js --- src/core/scene/sortFunctions.js | 56 ---------------------- src/systems/renderer.js | 63 +++++++++++++++++++++++-- tests/core/sortFunctions.test.js | 80 -------------------------------- tests/systems/renderer.test.js | 79 ++++++++++++++++++++++++++++++- 4 files changed, 137 insertions(+), 141 deletions(-) delete mode 100644 src/core/scene/sortFunctions.js delete mode 100644 tests/core/sortFunctions.test.js diff --git a/src/core/scene/sortFunctions.js b/src/core/scene/sortFunctions.js deleted file mode 100644 index cbcd5ada4c8..00000000000 --- a/src/core/scene/sortFunctions.js +++ /dev/null @@ -1,56 +0,0 @@ -// Custom A-Frame sort functions. -// Variations of Three.js default sort orders here: -// https://github.com/mrdoob/three.js/blob/ebbaecf9acacf259ea9abdcba7b6fb25cfcea2ab/src/renderers/webgl/WebGLRenderLists.js#L1 -// See: https://github.com/aframevr/aframe/issues/5332 - -// Default sort for opaque objects: -// - respect groupOrder & renderOrder settings -// - sort front-to-back by z-depth from camera (this should minimize overdraw) -// - otherwise leave objects in default order (object tree order) - -function sortOpaqueDefault (a, b) { - if (a.groupOrder !== b.groupOrder) { - return a.groupOrder - b.groupOrder; - } else if (a.renderOrder !== b.renderOrder) { - return a.renderOrder - b.renderOrder; - } else if (a.z !== b.z) { - return a.z - b.z; - } else { - return 0; - } -} - -// Default sort for transparent objects: -// - respect groupOrder & renderOrder settings -// - otherwise leave objects in default order (object tree order) -function sortTransparentDefault (a, b) { - if (a.groupOrder !== b.groupOrder) { - return a.groupOrder - b.groupOrder; - } else if (a.renderOrder !== b.renderOrder) { - return a.renderOrder - b.renderOrder; - } else { - return 0; - } -} - -// Spatial sort for transparent objects: -// - respect groupOrder & renderOrder settings -// - sort back-to-front by z-depth from camera -// - otherwise leave objects in default order (object tree order) -function sortTransparentSpatial (a, b) { - if (a.groupOrder !== b.groupOrder) { - return a.groupOrder - b.groupOrder; - } else if (a.renderOrder !== b.renderOrder) { - return a.renderOrder - b.renderOrder; - } else if (a.z !== b.z) { - return b.z - a.z; - } else { - return 0; - } -} - -module.exports = { - sortOpaqueDefault: sortOpaqueDefault, - sortTransparentDefault: sortTransparentDefault, - sortTransparentSpatial: sortTransparentSpatial -}; diff --git a/src/systems/renderer.js b/src/systems/renderer.js index 0b06c485036..cf67dd319c1 100644 --- a/src/systems/renderer.js +++ b/src/systems/renderer.js @@ -1,7 +1,6 @@ var registerSystem = require('../core/system').registerSystem; var utils = require('../utils/'); var THREE = require('../lib/three'); -var sortFunctions = require('../core/scene/sortFunctions'); var debug = utils.debug; var warn = debug('components:renderer:warn'); @@ -51,7 +50,7 @@ module.exports.System = registerSystem('renderer', { // These properties are always the same, regardless of rendered oonfiguration renderer.sortObjects = true; - renderer.setOpaqueSort(sortFunctions.sortOpaqueDefault); + renderer.setOpaqueSort(sortOpaqueDefault); }, update: function () { @@ -67,9 +66,9 @@ module.exports.System = registerSystem('renderer', { warn('`sortObjects` property is deprecated. Use `renderer="sortTransparentObjects: true"` instead.'); } if (data.sortTransparentObjects) { - renderer.setTransparentSort(sortFunctions.sortTransparentSpatial); + renderer.setTransparentSort(sortTransparentSpatial); } else { - renderer.setTransparentSort(sortFunctions.sortTransparentDefault); + renderer.setTransparentSort(sortTransparentDefault); } }, @@ -97,3 +96,59 @@ module.exports.System = registerSystem('renderer', { } } }); + +// Custom A-Frame sort functions. +// Variations of Three.js default sort orders here: +// https://github.com/mrdoob/three.js/blob/ebbaecf9acacf259ea9abdcba7b6fb25cfcea2ab/src/renderers/webgl/WebGLRenderLists.js#L1 +// See: https://github.com/aframevr/aframe/issues/5332 + +// Default sort for opaque objects: +// - respect groupOrder & renderOrder settings +// - sort front-to-back by z-depth from camera (this should minimize overdraw) +// - otherwise leave objects in default order (object tree order) + +function sortOpaqueDefault (a, b) { + if (a.groupOrder !== b.groupOrder) { + return a.groupOrder - b.groupOrder; + } else if (a.renderOrder !== b.renderOrder) { + return a.renderOrder - b.renderOrder; + } else if (a.z !== b.z) { + return a.z - b.z; + } else { + return 0; + } +} + +// Default sort for transparent objects: +// - respect groupOrder & renderOrder settings +// - otherwise leave objects in default order (object tree order) +function sortTransparentDefault (a, b) { + if (a.groupOrder !== b.groupOrder) { + return a.groupOrder - b.groupOrder; + } else if (a.renderOrder !== b.renderOrder) { + return a.renderOrder - b.renderOrder; + } else { + return 0; + } +} + +// Spatial sort for transparent objects: +// - respect groupOrder & renderOrder settings +// - sort back-to-front by z-depth from camera +// - otherwise leave objects in default order (object tree order) +function sortTransparentSpatial (a, b) { + if (a.groupOrder !== b.groupOrder) { + return a.groupOrder - b.groupOrder; + } else if (a.renderOrder !== b.renderOrder) { + return a.renderOrder - b.renderOrder; + } else if (a.z !== b.z) { + return b.z - a.z; + } else { + return 0; + } +} + +// exports needed for Unit Tests +module.exports.sortOpaqueDefault = sortOpaqueDefault; +module.exports.sortTransparentDefault = sortTransparentDefault; +module.exports.sortTransparentSpatial = sortTransparentSpatial; diff --git a/tests/core/sortFunctions.test.js b/tests/core/sortFunctions.test.js deleted file mode 100644 index a6e3149bc24..00000000000 --- a/tests/core/sortFunctions.test.js +++ /dev/null @@ -1,80 +0,0 @@ -/* global assert, process, suite, test, setup */ - -var {sortOpaqueDefault, sortTransparentDefault, sortTransparentSpatial} = require('core/scene/sortFunctions'); - -suite('sortFunctions', function () { - var objects; - var objectsRenderOrder; - var objectsGroupOrder; - - setup(function () { - objects = [ - { name: 'a', renderOrder: 0, z: 1 }, - { name: 'b', renderOrder: 0, z: 3 }, - { name: 'c', renderOrder: 0, z: 2 } - ]; - - objectsRenderOrder = [ - { name: 'a', renderOrder: 1, z: 1 }, - { name: 'b', renderOrder: 0, z: 3 }, - { name: 'c', renderOrder: -1, z: 2 } - ]; - - objectsGroupOrder = [ - { name: 'a', groupOrder: 0, renderOrder: 1, z: 1 }, - { name: 'b', groupOrder: 0, renderOrder: 0, z: 3 }, - { name: 'c', groupOrder: 1, renderOrder: -1, z: 2 } - ]; - }); - - function checkOrder (objects, array) { - array.forEach((item, index) => { - assert.equal(objects[index].name, item); - }); - } - - test('Opaque sort sorts front-to-back', function () { - objects.sort(sortOpaqueDefault); - checkOrder(objects, ['a', 'c', 'b']); - }); - - test('Opaque sort respects renderOrder', function () { - objectsRenderOrder.sort(sortOpaqueDefault); - checkOrder(objectsRenderOrder, ['c', 'b', 'a']); - }); - - test('Opaque sort respects groupOrder, then renderOrder', function () { - objectsGroupOrder.sort(sortOpaqueDefault); - checkOrder(objectsGroupOrder, ['b', 'a', 'c']); - }); - - test('Transparent default sort sorts in DOM order', function () { - objects.sort(sortTransparentDefault); - checkOrder(objects, ['a', 'b', 'c']); - }); - - test('Transparent default sort respects renderOrder', function () { - objectsRenderOrder.sort(sortTransparentDefault); - checkOrder(objectsRenderOrder, ['c', 'b', 'a']); - }); - - test('Transparent default sort respects groupOrder, then renderOrder', function () { - objectsGroupOrder.sort(sortTransparentDefault); - checkOrder(objectsGroupOrder, ['b', 'a', 'c']); - }); - - test('Transparent spatial sort sorts back-to-front', function () { - objects.sort(sortTransparentSpatial); - checkOrder(objects, ['b', 'c', 'a']); - }); - - test('Transparent spatial sort respects renderOrder', function () { - objectsRenderOrder.sort(sortTransparentSpatial); - checkOrder(objectsRenderOrder, ['c', 'b', 'a']); - }); - - test('Transparent spatial sort respects groupOrder, then renderOrder', function () { - objectsGroupOrder.sort(sortTransparentSpatial); - checkOrder(objectsGroupOrder, ['b', 'a', 'c']); - }); -}); diff --git a/tests/systems/renderer.test.js b/tests/systems/renderer.test.js index f3723bc1bbc..01096840e88 100644 --- a/tests/systems/renderer.test.js +++ b/tests/systems/renderer.test.js @@ -1,7 +1,7 @@ /* global assert, suite, test, setup, teardown, THREE */ var {sortOpaqueDefault, sortTransparentDefault, - sortTransparentSpatial} = require('core/scene/sortFunctions'); + sortTransparentSpatial} = require('systems/renderer'); suite('renderer', function () { function createScene () { @@ -230,4 +230,81 @@ suite('renderer', function () { console.warn = oldConsoleWarn; }); }); + + suite('sortFunctions', function () { + var objects; + var objectsRenderOrder; + var objectsGroupOrder; + + setup(function () { + objects = [ + { name: 'a', renderOrder: 0, z: 1 }, + { name: 'b', renderOrder: 0, z: 3 }, + { name: 'c', renderOrder: 0, z: 2 } + ]; + + objectsRenderOrder = [ + { name: 'a', renderOrder: 1, z: 1 }, + { name: 'b', renderOrder: 0, z: 3 }, + { name: 'c', renderOrder: -1, z: 2 } + ]; + + objectsGroupOrder = [ + { name: 'a', groupOrder: 0, renderOrder: 1, z: 1 }, + { name: 'b', groupOrder: 0, renderOrder: 0, z: 3 }, + { name: 'c', groupOrder: 1, renderOrder: -1, z: 2 } + ]; + }); + + function checkOrder (objects, array) { + array.forEach((item, index) => { + assert.equal(objects[index].name, item); + }); + } + + test('Opaque sort sorts front-to-back', function () { + objects.sort(sortOpaqueDefault); + checkOrder(objects, ['a', 'c', 'b']); + }); + + test('Opaque sort respects renderOrder', function () { + objectsRenderOrder.sort(sortOpaqueDefault); + checkOrder(objectsRenderOrder, ['c', 'b', 'a']); + }); + + test('Opaque sort respects groupOrder, then renderOrder', function () { + objectsGroupOrder.sort(sortOpaqueDefault); + checkOrder(objectsGroupOrder, ['b', 'a', 'c']); + }); + + test('Transparent default sort sorts in DOM order', function () { + objects.sort(sortTransparentDefault); + checkOrder(objects, ['a', 'b', 'c']); + }); + + test('Transparent default sort respects renderOrder', function () { + objectsRenderOrder.sort(sortTransparentDefault); + checkOrder(objectsRenderOrder, ['c', 'b', 'a']); + }); + + test('Transparent default sort respects groupOrder, then renderOrder', function () { + objectsGroupOrder.sort(sortTransparentDefault); + checkOrder(objectsGroupOrder, ['b', 'a', 'c']); + }); + + test('Transparent spatial sort sorts back-to-front', function () { + objects.sort(sortTransparentSpatial); + checkOrder(objects, ['b', 'c', 'a']); + }); + + test('Transparent spatial sort respects renderOrder', function () { + objectsRenderOrder.sort(sortTransparentSpatial); + checkOrder(objectsRenderOrder, ['c', 'b', 'a']); + }); + + test('Transparent spatial sort respects groupOrder, then renderOrder', function () { + objectsGroupOrder.sort(sortTransparentSpatial); + checkOrder(objectsGroupOrder, ['b', 'a', 'c']); + }); + }); });