|
@@ -63,6 +63,15 @@ module BABYLON {
|
|
renderingGroupId: number;
|
|
renderingGroupId: number;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /** Interface defining initialization parameters for Scene class */
|
|
|
|
+ export interface SceneOptions {
|
|
|
|
+ /**
|
|
|
|
+ * Defines that scene should keep up-to-date a map of geometry to enable fast look-up by Id
|
|
|
|
+ * It will improve performance when the number of geometries becomes important.
|
|
|
|
+ */
|
|
|
|
+ useGeometryIdsMap?: boolean;
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Represents a scene to be rendered by the engine.
|
|
* Represents a scene to be rendered by the engine.
|
|
* @see http://doc.babylonjs.com/features/scene
|
|
* @see http://doc.babylonjs.com/features/scene
|
|
@@ -1165,10 +1174,15 @@ module BABYLON {
|
|
public _pointerUpStage = Stage.Create<PointerUpDownStageAction>();
|
|
public _pointerUpStage = Stage.Create<PointerUpDownStageAction>();
|
|
|
|
|
|
/**
|
|
/**
|
|
|
|
+ * an optional map from Geometry Id to Geometry index in the 'geometries' array
|
|
|
|
+ */
|
|
|
|
+ private geometriesById: Nullable<{ [id: string] : number | undefined }> = null;
|
|
|
|
+
|
|
|
|
+ /**
|
|
* Creates a new Scene
|
|
* Creates a new Scene
|
|
* @param engine defines the engine to use to render this scene
|
|
* @param engine defines the engine to use to render this scene
|
|
*/
|
|
*/
|
|
- constructor(engine: Engine) {
|
|
|
|
|
|
+ constructor(engine: Engine, options?: SceneOptions) {
|
|
super();
|
|
super();
|
|
this._engine = engine || Engine.LastCreatedEngine;
|
|
this._engine = engine || Engine.LastCreatedEngine;
|
|
|
|
|
|
@@ -1197,6 +1211,10 @@ module BABYLON {
|
|
}
|
|
}
|
|
|
|
|
|
this.setDefaultCandidateProviders();
|
|
this.setDefaultCandidateProviders();
|
|
|
|
+
|
|
|
|
+ if (options && options.useGeometryIdsMap === true) {
|
|
|
|
+ this.geometriesById = {};
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
private _defaultMeshCandidates: ISmartArrayLike<AbstractMesh> = {
|
|
private _defaultMeshCandidates: ISmartArrayLike<AbstractMesh> = {
|
|
@@ -1846,7 +1864,7 @@ module BABYLON {
|
|
if (!checkPicking && ActionManager && ActionManager.HasPickTriggers) {
|
|
if (!checkPicking && ActionManager && ActionManager.HasPickTriggers) {
|
|
act = this._initActionManager(act, clickInfo);
|
|
act = this._initActionManager(act, clickInfo);
|
|
if (act) {
|
|
if (act) {
|
|
- checkPicking = act.hasPickTriggers;
|
|
|
|
|
|
+ checkPicking = act.hasPickTriggers;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (checkPicking) {
|
|
if (checkPicking) {
|
|
@@ -1863,7 +1881,7 @@ module BABYLON {
|
|
if (checkSingleClickImmediately && !ActionManager.HasSpecificTrigger(ActionManager.OnDoublePickTrigger)) {
|
|
if (checkSingleClickImmediately && !ActionManager.HasSpecificTrigger(ActionManager.OnDoublePickTrigger)) {
|
|
act = this._initActionManager(act, clickInfo);
|
|
act = this._initActionManager(act, clickInfo);
|
|
if (act) {
|
|
if (act) {
|
|
- checkSingleClickImmediately = !act.hasSpecificTrigger(ActionManager.OnDoublePickTrigger);
|
|
|
|
|
|
+ checkSingleClickImmediately = !act.hasSpecificTrigger(ActionManager.OnDoublePickTrigger);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -1889,7 +1907,7 @@ module BABYLON {
|
|
if (!checkDoubleClick && ActionManager.HasSpecificTrigger(ActionManager.OnDoublePickTrigger)) {
|
|
if (!checkDoubleClick && ActionManager.HasSpecificTrigger(ActionManager.OnDoublePickTrigger)) {
|
|
act = this._initActionManager(act, clickInfo);
|
|
act = this._initActionManager(act, clickInfo);
|
|
if (act) {
|
|
if (act) {
|
|
- checkDoubleClick = act.hasSpecificTrigger(ActionManager.OnDoublePickTrigger);
|
|
|
|
|
|
+ checkDoubleClick = act.hasSpecificTrigger(ActionManager.OnDoublePickTrigger);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (checkDoubleClick) {
|
|
if (checkDoubleClick) {
|
|
@@ -3270,6 +3288,10 @@ module BABYLON {
|
|
* @param newGeometry The geometry to add
|
|
* @param newGeometry The geometry to add
|
|
*/
|
|
*/
|
|
public addGeometry(newGeometry: Geometry): void {
|
|
public addGeometry(newGeometry: Geometry): void {
|
|
|
|
+ if (this.geometriesById) {
|
|
|
|
+ this.geometriesById[newGeometry.id] = this.geometries.length;
|
|
|
|
+ }
|
|
|
|
+
|
|
this.geometries.push(newGeometry);
|
|
this.geometries.push(newGeometry);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -3535,11 +3557,19 @@ module BABYLON {
|
|
* @return the geometry or null if none found.
|
|
* @return the geometry or null if none found.
|
|
*/
|
|
*/
|
|
public getGeometryByID(id: string): Nullable<Geometry> {
|
|
public getGeometryByID(id: string): Nullable<Geometry> {
|
|
- for (var index = 0; index < this.geometries.length; index++) {
|
|
|
|
- if (this.geometries[index].id === id) {
|
|
|
|
|
|
+ if (this.geometriesById) {
|
|
|
|
+ const index = this.geometriesById[id];
|
|
|
|
+ if (index !== undefined) {
|
|
return this.geometries[index];
|
|
return this.geometries[index];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ else {
|
|
|
|
+ for (var index = 0; index < this.geometries.length; index++) {
|
|
|
|
+ if (this.geometries[index].id === id) {
|
|
|
|
+ return this.geometries[index];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
return null;
|
|
return null;
|
|
}
|
|
}
|
|
@@ -3555,7 +3585,7 @@ module BABYLON {
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
- this.geometries.push(geometry);
|
|
|
|
|
|
+ this.addGeometry(geometry);
|
|
|
|
|
|
//notify the collision coordinator
|
|
//notify the collision coordinator
|
|
if (this.collisionCoordinator) {
|
|
if (this.collisionCoordinator) {
|
|
@@ -3573,20 +3603,38 @@ module BABYLON {
|
|
* @return a boolean defining if the geometry was removed or not
|
|
* @return a boolean defining if the geometry was removed or not
|
|
*/
|
|
*/
|
|
public removeGeometry(geometry: Geometry): boolean {
|
|
public removeGeometry(geometry: Geometry): boolean {
|
|
- var index = this.geometries.indexOf(geometry);
|
|
|
|
-
|
|
|
|
- if (index > -1) {
|
|
|
|
- this.geometries.splice(index, 1);
|
|
|
|
|
|
+ let index;
|
|
|
|
+ if (this.geometriesById) {
|
|
|
|
+ index = this.geometriesById[geometry.id];
|
|
|
|
+ if (index === undefined) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ index = this.geometries.indexOf(geometry);
|
|
|
|
+ if (index < 0) {
|
|
|
|
+ return false;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- //notify the collision coordinator
|
|
|
|
- if (this.collisionCoordinator) {
|
|
|
|
- this.collisionCoordinator.onGeometryDeleted(geometry);
|
|
|
|
|
|
+ if (index !== this.geometries.length - 1) {
|
|
|
|
+ const lastGeometry = this.geometries[this.geometries.length - 1];
|
|
|
|
+ this.geometries[index] = lastGeometry;
|
|
|
|
+ if (this.geometriesById) {
|
|
|
|
+ this.geometriesById[lastGeometry.id] = index;
|
|
|
|
+ this.geometriesById[geometry.id] = undefined;
|
|
}
|
|
}
|
|
|
|
+ }
|
|
|
|
|
|
- this.onGeometryRemovedObservable.notifyObservers(geometry);
|
|
|
|
- return true;
|
|
|
|
|
|
+ this.geometries.pop();
|
|
|
|
+
|
|
|
|
+ //notify the collision coordinator
|
|
|
|
+ if (this.collisionCoordinator) {
|
|
|
|
+ this.collisionCoordinator.onGeometryDeleted(geometry);
|
|
}
|
|
}
|
|
- return false;
|
|
|
|
|
|
+
|
|
|
|
+ this.onGeometryRemovedObservable.notifyObservers(geometry);
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -4197,7 +4245,7 @@ module BABYLON {
|
|
this.activeCamera = camera;
|
|
this.activeCamera = camera;
|
|
|
|
|
|
if (!this.activeCamera) {
|
|
if (!this.activeCamera) {
|
|
- throw new Error("Active camera not set");
|
|
|
|
|
|
+ throw new Error("Active camera not set");
|
|
}
|
|
}
|
|
|
|
|
|
// Viewport
|
|
// Viewport
|
|
@@ -4498,7 +4546,7 @@ module BABYLON {
|
|
this.activeCamera = renderTarget.activeCamera || this.activeCamera;
|
|
this.activeCamera = renderTarget.activeCamera || this.activeCamera;
|
|
|
|
|
|
if (!this.activeCamera) {
|
|
if (!this.activeCamera) {
|
|
- throw new Error("Active camera not set");
|
|
|
|
|
|
+ throw new Error("Active camera not set");
|
|
}
|
|
}
|
|
|
|
|
|
// Viewport
|
|
// Viewport
|
|
@@ -4906,7 +4954,7 @@ module BABYLON {
|
|
|
|
|
|
if (!camera) {
|
|
if (!camera) {
|
|
if (!this.activeCamera) {
|
|
if (!this.activeCamera) {
|
|
- throw new Error("Active camera not set");
|
|
|
|
|
|
+ throw new Error("Active camera not set");
|
|
}
|
|
}
|
|
|
|
|
|
camera = this.activeCamera;
|
|
camera = this.activeCamera;
|
|
@@ -4955,7 +5003,7 @@ module BABYLON {
|
|
|
|
|
|
if (!camera) {
|
|
if (!camera) {
|
|
if (!this.activeCamera) {
|
|
if (!this.activeCamera) {
|
|
- throw new Error("Active camera not set");
|
|
|
|
|
|
+ throw new Error("Active camera not set");
|
|
}
|
|
}
|
|
|
|
|
|
camera = this.activeCamera;
|
|
camera = this.activeCamera;
|
|
@@ -4995,11 +5043,11 @@ module BABYLON {
|
|
|
|
|
|
var result = mesh.intersects(ray, fastCheck);
|
|
var result = mesh.intersects(ray, fastCheck);
|
|
if (!result || !result.hit) {
|
|
if (!result || !result.hit) {
|
|
- continue;
|
|
|
|
|
|
+ continue;
|
|
}
|
|
}
|
|
|
|
|
|
if (!fastCheck && pickingInfo != null && result.distance >= pickingInfo.distance) {
|
|
if (!fastCheck && pickingInfo != null && result.distance >= pickingInfo.distance) {
|
|
- continue;
|
|
|
|
|
|
+ continue;
|
|
}
|
|
}
|
|
|
|
|
|
pickingInfo = result;
|
|
pickingInfo = result;
|
|
@@ -5034,7 +5082,7 @@ module BABYLON {
|
|
|
|
|
|
var result = mesh.intersects(ray, false);
|
|
var result = mesh.intersects(ray, false);
|
|
if (!result || !result.hit) {
|
|
if (!result || !result.hit) {
|
|
- continue;
|
|
|
|
|
|
+ continue;
|
|
}
|
|
}
|
|
|
|
|
|
pickingInfos.push(result);
|
|
pickingInfos.push(result);
|