Skip to content

Commit 5cd8893

Browse files
authored
Merge 36fee14 into d233eef
2 parents d233eef + 36fee14 commit 5cd8893

File tree

8 files changed

+233
-223
lines changed

8 files changed

+233
-223
lines changed

packages/core/src/Camera.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ export class Camera extends Component {
7777
_replacementShader: Shader = null;
7878
/** @internal */
7979
_replacementSubShaderTag: ShaderTagKey = null;
80+
/** @internal */
81+
@ignoreClone
82+
_cameraIndex: number = -1;
8083

8184
private _priority: number = 0;
8285
private _shaderData: ShaderData = new ShaderData(ShaderDataGroup.Camera);
@@ -198,8 +201,8 @@ export class Camera extends Component {
198201

199202
set priority(value: number) {
200203
if (this._priority !== value) {
201-
if (this._entity._isActiveInScene && this.enabled) {
202-
this.scene._cameraNeedSorting = true;
204+
if (this._phasedActiveInScene) {
205+
this.scene._componentsManager._cameraNeedSorting = true;
203206
}
204207
this._priority = value;
205208
}
@@ -564,14 +567,14 @@ export class Camera extends Component {
564567
* @inheritdoc
565568
*/
566569
override _onEnableInScene(): void {
567-
this.scene._attachRenderCamera(this);
570+
this.scene._componentsManager.addCamera(this);
568571
}
569572

570573
/**
571574
* @inheritdoc
572575
*/
573576
override _onDisableInScene(): void {
574-
this.scene._detachRenderCamera(this);
577+
this.scene._componentsManager.removeCamera(this);
575578
}
576579

577580
/**

packages/core/src/ComponentsManager.ts

+29
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ import { Animator } from "./animation";
99
* The manager of the components.
1010
*/
1111
export class ComponentsManager {
12+
/* @internal */
13+
_cameraNeedSorting: boolean = false;
14+
/** @internal */
15+
_activeCameras: DisorderedArray<Camera> = new DisorderedArray();
1216
/** @internal */
1317
_renderers: DisorderedArray<Renderer> = new DisorderedArray();
1418

@@ -30,6 +34,30 @@ export class ComponentsManager {
3034
// Delay dispose active/inActive Pool
3135
private _componentsContainerPool: Component[][] = [];
3236

37+
addCamera(camera: Camera) {
38+
camera._cameraIndex = this._activeCameras.length;
39+
this._activeCameras.add(camera);
40+
this._cameraNeedSorting = true;
41+
}
42+
43+
removeCamera(camera: Camera) {
44+
const replaced = this._activeCameras.deleteByIndex(camera._cameraIndex);
45+
replaced && (replaced._cameraIndex = camera._cameraIndex);
46+
camera._cameraIndex = -1;
47+
this._cameraNeedSorting = true;
48+
}
49+
50+
sortCameras(): void {
51+
if (this._cameraNeedSorting) {
52+
const activeCameras = this._activeCameras;
53+
activeCameras.sort((a, b) => a.priority - b.priority);
54+
for (let i = 0, n = activeCameras.length; i < n; i++) {
55+
activeCameras.get(i)._cameraIndex = i;
56+
}
57+
this._cameraNeedSorting = false;
58+
}
59+
}
60+
3361
addRenderer(renderer: Renderer) {
3462
renderer._rendererIndex = this._renderers.length;
3563
this._renderers.add(renderer);
@@ -233,5 +261,6 @@ export class ComponentsManager {
233261
this._onPhysicsUpdateScripts.garbageCollection();
234262
this._onUpdateAnimations.garbageCollection();
235263
this._onUpdateRenderers.garbageCollection();
264+
this._activeCameras.garbageCollection();
236265
}
237266
}

packages/core/src/DisorderedArray.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { Utils } from "./Utils";
2+
13
/**
24
* High-performance unordered array, delete uses exchange method to improve performance, internal capacity only increases.
35
*/
@@ -69,7 +71,7 @@ export class DisorderedArray<T> {
6971
forEach(callbackFn: (element: T) => void, swapFn: (element: T, index: number) => void): void {
7072
this._startLoop();
7173
const elements = this._elements;
72-
for (let i = 0; i < this.length; i++) {
74+
for (let i = 0, n = this.length; i < n; i++) {
7375
const element = elements[i];
7476
element && callbackFn(element);
7577
}
@@ -79,13 +81,17 @@ export class DisorderedArray<T> {
7981
forEachAndClean(callbackFn: (e: T) => void): void {
8082
this._startLoop();
8183
const elements = this._elements;
82-
for (let i = 0; i < this.length; i++) {
84+
for (let i = 0, n = this.length; i < n; i++) {
8385
const element = elements[i];
8486
element && callbackFn(element);
8587
}
8688
this._endLoopAndClear();
8789
}
8890

91+
sort(compareFn: (a: T, b: T) => number): void {
92+
Utils._quickSort(this._elements, 0, this.length, compareFn);
93+
}
94+
8995
garbageCollection(): void {
9096
this._elements.length = this.length;
9197
}

packages/core/src/Engine.ts

+19-12
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { IPhysics, IPhysicsManager, IShaderLab } from "@galacean/engine-design";
22
import { Color } from "@galacean/engine-math/src/Color";
3+
import { SpriteMaskInteraction } from "./2d";
34
import { Font } from "./2d/text/Font";
5+
import { Camera } from "./Camera";
46
import { Canvas } from "./Canvas";
57
import { EngineSettings } from "./EngineSettings";
68
import { Entity } from "./Entity";
@@ -25,6 +27,7 @@ import { ParticleBufferUtils } from "./particle/ParticleBufferUtils";
2527
import { PhysicsScene } from "./physics/PhysicsScene";
2628
import { ColliderShape } from "./physics/shape/ColliderShape";
2729
import { IHardwareRenderer } from "./renderingHardwareInterface";
30+
import { CompareFunction } from "./shader";
2831
import { Shader } from "./shader/Shader";
2932
import { ShaderMacro } from "./shader/ShaderMacro";
3033
import { ShaderMacroCollection } from "./shader/ShaderMacroCollection";
@@ -38,8 +41,6 @@ import { CullMode } from "./shader/enums/CullMode";
3841
import { RenderQueueType } from "./shader/enums/RenderQueueType";
3942
import { RenderState } from "./shader/state/RenderState";
4043
import { Texture2D, Texture2DArray, TextureCube, TextureCubeFace, TextureFormat } from "./texture";
41-
import { CompareFunction } from "./shader";
42-
import { SpriteMaskInteraction } from "./2d";
4344

4445
ShaderPool.init();
4546

@@ -336,8 +337,9 @@ export class Engine extends EventDispatcher {
336337
for (let i = 0; i < sceneCount; i++) {
337338
const scene = scenes[i];
338339
if (!scene.isActive || scene.destroyed) continue;
339-
scene._cameraNeedSorting && scene._sortCameras();
340-
scene._componentsManager.callScriptOnStart();
340+
const componentsManager = scene._componentsManager;
341+
componentsManager.sortCameras();
342+
componentsManager.callScriptOnStart();
341343
}
342344

343345
// Update physics and fire `onPhysicsUpdate`
@@ -498,11 +500,15 @@ export class Engine extends EventDispatcher {
498500
for (let i = 0, n = scenes.length; i < n; i++) {
499501
const scene = scenes[i];
500502
if (!scene.isActive || scene.destroyed) continue;
501-
const cameras = scene._activeCameras;
502-
const cameraCount = cameras.length;
503-
if (cameraCount > 0) {
504-
for (let i = 0; i < cameraCount; i++) {
505-
const camera = cameras[i];
503+
const cameras = scene._componentsManager._activeCameras;
504+
505+
if (cameras.length === 0) {
506+
Logger.debug("No active camera in scene.");
507+
continue;
508+
}
509+
510+
cameras.forEach(
511+
(camera: Camera) => {
506512
const componentsManager = scene._componentsManager;
507513
componentsManager.callCameraOnBeginRender(camera);
508514
camera.render();
@@ -512,10 +518,11 @@ export class Engine extends EventDispatcher {
512518
if (this._hardwareRenderer._options._forceFlush) {
513519
this._hardwareRenderer.flush();
514520
}
521+
},
522+
(camera: Camera, index: number) => {
523+
camera._cameraIndex = index;
515524
}
516-
} else {
517-
Logger.debug("No active camera in scene.");
518-
}
525+
);
519526
}
520527
}
521528

packages/core/src/RenderPipeline/RenderQueue.ts

+2-104
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Camera } from "../Camera";
22
import { Engine } from "../Engine";
33
import { Layer } from "../Layer";
4+
import { Utils } from "../Utils";
45
import { RenderQueueType, Shader } from "../shader";
56
import { ShaderMacroCollection } from "../shader/ShaderMacroCollection";
67
import { RenderContext } from "./RenderContext";
@@ -194,7 +195,7 @@ export class RenderQueue {
194195
* Sort the elements.
195196
*/
196197
sort(compareFunc: Function): void {
197-
this._quickSort(this.elements, 0, this.elements.length, compareFunc);
198+
Utils._quickSort(this.elements, 0, this.elements.length, compareFunc);
198199
}
199200

200201
/**
@@ -204,107 +205,4 @@ export class RenderQueue {
204205
_initSpriteBatcher(engine: Engine): void {
205206
this._spriteBatcher = new SpriteBatcher(engine);
206207
}
207-
208-
/**
209-
* @remarks
210-
* Modified based on v8.
211-
* https://github.com/v8/v8/blob/7.2-lkgr/src/js/array.js
212-
*/
213-
private _quickSort<T>(a: T[], from: number, to: number, compareFunc: Function): void {
214-
while (true) {
215-
// Insertion sort is faster for short arrays.
216-
if (to - from <= 10) {
217-
this._insertionSort(a, from, to, compareFunc);
218-
return;
219-
}
220-
const third_index = (from + to) >> 1;
221-
// Find a pivot as the median of first, last and middle element.
222-
let v0 = a[from];
223-
let v1 = a[to - 1];
224-
let v2 = a[third_index];
225-
const c01 = compareFunc(v0, v1);
226-
if (c01 > 0) {
227-
// v1 < v0, so swap them.
228-
const tmp = v0;
229-
v0 = v1;
230-
v1 = tmp;
231-
} // v0 <= v1.
232-
const c02 = compareFunc(v0, v2);
233-
if (c02 >= 0) {
234-
// v2 <= v0 <= v1.
235-
const tmp = v0;
236-
v0 = v2;
237-
v2 = v1;
238-
v1 = tmp;
239-
} else {
240-
// v0 <= v1 && v0 < v2
241-
const c12 = compareFunc(v1, v2);
242-
if (c12 > 0) {
243-
// v0 <= v2 < v1
244-
const tmp = v1;
245-
v1 = v2;
246-
v2 = tmp;
247-
}
248-
}
249-
// v0 <= v1 <= v2
250-
a[from] = v0;
251-
a[to - 1] = v2;
252-
const pivot = v1;
253-
let low_end = from + 1; // Upper bound of elements lower than pivot.
254-
let high_start = to - 1; // Lower bound of elements greater than pivot.
255-
a[third_index] = a[low_end];
256-
a[low_end] = pivot;
257-
258-
// From low_end to i are elements equal to pivot.
259-
// From i to high_start are elements that haven't been compared yet.
260-
partition: for (let i = low_end + 1; i < high_start; i++) {
261-
let element = a[i];
262-
let order = compareFunc(element, pivot);
263-
if (order < 0) {
264-
a[i] = a[low_end];
265-
a[low_end] = element;
266-
low_end++;
267-
} else if (order > 0) {
268-
do {
269-
high_start--;
270-
if (high_start == i) break partition;
271-
const top_elem = a[high_start];
272-
order = compareFunc(top_elem, pivot);
273-
} while (order > 0);
274-
a[i] = a[high_start];
275-
a[high_start] = element;
276-
if (order < 0) {
277-
element = a[i];
278-
a[i] = a[low_end];
279-
a[low_end] = element;
280-
low_end++;
281-
}
282-
}
283-
}
284-
if (to - high_start < low_end - from) {
285-
this._quickSort(a, high_start, to, compareFunc);
286-
to = low_end;
287-
} else {
288-
this._quickSort(a, from, low_end, compareFunc);
289-
from = high_start;
290-
}
291-
}
292-
}
293-
294-
private _insertionSort<T>(a: T[], from: number, to: number, compareFunc: Function): void {
295-
for (let i = from + 1; i < to; i++) {
296-
let j;
297-
const element = a[i];
298-
for (j = i - 1; j >= from; j--) {
299-
const tmp = a[j];
300-
const order = compareFunc(tmp, element);
301-
if (order > 0) {
302-
a[j + 1] = tmp;
303-
} else {
304-
break;
305-
}
306-
}
307-
a[j + 1] = element;
308-
}
309-
}
310208
}

packages/core/src/Scene.ts

-39
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Color, Vector3, Vector4 } from "@galacean/engine-math";
22
import { Background } from "./Background";
3-
import { Camera } from "./Camera";
43
import { ComponentsManager } from "./ComponentsManager";
54
import { Engine } from "./Engine";
65
import { Entity } from "./Entity";
@@ -44,15 +43,11 @@ export class Scene extends EngineObject {
4443
/** Max Shadow distance. */
4544
shadowDistance: number = 50;
4645

47-
/* @internal */
48-
_cameraNeedSorting: boolean = false;
4946
/* @internal */
5047
_lightManager: LightManager = new LightManager();
5148
/* @internal */
5249
_componentsManager: ComponentsManager = new ComponentsManager();
5350
/** @internal */
54-
_activeCameras: Camera[] = [];
55-
/** @internal */
5651
_isActiveInEngine: boolean = false;
5752
/** @internal */
5853
_sceneManager: SceneManager;
@@ -401,39 +396,6 @@ export class Scene extends EngineObject {
401396
return null;
402397
}
403398

404-
/**
405-
* @internal
406-
*/
407-
_sortCameras(): void {
408-
this._activeCameras.sort((a, b) => a.priority - b.priority);
409-
this._cameraNeedSorting = false;
410-
}
411-
412-
/**
413-
* @internal
414-
*/
415-
_attachRenderCamera(camera: Camera): void {
416-
const activeCameras = this._activeCameras;
417-
const index = activeCameras.indexOf(camera);
418-
if (index === -1) {
419-
activeCameras.push(camera);
420-
this._cameraNeedSorting = true;
421-
} else {
422-
Logger.warn("Camera already attached.");
423-
}
424-
}
425-
426-
/**
427-
* @internal
428-
*/
429-
_detachRenderCamera(camera: Camera): void {
430-
const activeCameras = this._activeCameras;
431-
const index = activeCameras.indexOf(camera);
432-
if (index !== -1) {
433-
activeCameras.splice(index, 1);
434-
}
435-
}
436-
437399
/**
438400
* @internal
439401
*/
@@ -514,7 +476,6 @@ export class Scene extends EngineObject {
514476
while (this.rootEntitiesCount > 0) {
515477
this._rootEntities[0].destroy();
516478
}
517-
this._activeCameras.length = 0;
518479
this.background.destroy();
519480
this._ambientLight && this._ambientLight._removeFromScene(this);
520481
this.shaderData._addReferCount(-1);

0 commit comments

Comments
 (0)