|
@@ -82,6 +82,9 @@ class _InstanceDataStorage {
|
|
public instancesBuffer: Nullable<Buffer>;
|
|
public instancesBuffer: Nullable<Buffer>;
|
|
public instancesData: Float32Array;
|
|
public instancesData: Float32Array;
|
|
public overridenInstanceCount: number;
|
|
public overridenInstanceCount: number;
|
|
|
|
+ public isFrozen: boolean;
|
|
|
|
+ public _previousBatch: _InstancesBatch;
|
|
|
|
+ public hardwareInstancedRendering: boolean;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -91,6 +94,7 @@ export class _InstancesBatch {
|
|
public mustReturn = false;
|
|
public mustReturn = false;
|
|
public visibleInstances = new Array<Nullable<Array<InstancedMesh>>>();
|
|
public visibleInstances = new Array<Nullable<Array<InstancedMesh>>>();
|
|
public renderSelf = new Array<boolean>();
|
|
public renderSelf = new Array<boolean>();
|
|
|
|
+ public hardwareInstancedRendering = new Array<boolean>();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -437,6 +441,7 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
|
|
this.parent = parent;
|
|
this.parent = parent;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ this._instanceDataStorage.hardwareInstancedRendering = this.getEngine().getCaps().instancedArrays;
|
|
}
|
|
}
|
|
|
|
|
|
// Methods
|
|
// Methods
|
|
@@ -1363,6 +1368,9 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
|
|
|
|
|
|
/** @hidden */
|
|
/** @hidden */
|
|
public _getInstancesRenderList(subMeshId: number): _InstancesBatch {
|
|
public _getInstancesRenderList(subMeshId: number): _InstancesBatch {
|
|
|
|
+ if (this._instanceDataStorage.isFrozen && this._instanceDataStorage._previousBatch) {
|
|
|
|
+ return this._instanceDataStorage._previousBatch;
|
|
|
|
+ }
|
|
var scene = this.getScene();
|
|
var scene = this.getScene();
|
|
let batchCache = this._instanceDataStorage.batchCache;
|
|
let batchCache = this._instanceDataStorage.batchCache;
|
|
batchCache.mustReturn = false;
|
|
batchCache.mustReturn = false;
|
|
@@ -1396,7 +1404,8 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
|
|
}
|
|
}
|
|
this._instanceDataStorage.renderIdForInstances[subMeshId] = currentRenderId;
|
|
this._instanceDataStorage.renderIdForInstances[subMeshId] = currentRenderId;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+ batchCache.hardwareInstancedRendering[subMeshId] = this._instanceDataStorage.hardwareInstancedRendering && (batchCache.visibleInstances[subMeshId] !== null) && (batchCache.visibleInstances[subMeshId] !== undefined);
|
|
|
|
+ this._instanceDataStorage._previousBatch = batchCache;
|
|
return batchCache;
|
|
return batchCache;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1502,6 +1511,25 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
|
|
return this;
|
|
return this;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /** @hidden */
|
|
|
|
+ public _freeze() {
|
|
|
|
+ this._instanceDataStorage.isFrozen = true;
|
|
|
|
+
|
|
|
|
+ if (!this.subMeshes) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Prepare batches
|
|
|
|
+ for (var index = 0; index < this.subMeshes.length; index++) {
|
|
|
|
+ this._getInstancesRenderList(index);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /** @hidden */
|
|
|
|
+ public _unFreeze() {
|
|
|
|
+ this._instanceDataStorage.isFrozen = false;
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Triggers the draw call for the mesh. Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager
|
|
* Triggers the draw call for the mesh. Usually, you don't need to call this method by your own because the mesh rendering is handled by the scene rendering manager
|
|
* @param subMesh defines the subMesh to render
|
|
* @param subMesh defines the subMesh to render
|
|
@@ -1531,7 +1559,7 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
|
|
}
|
|
}
|
|
|
|
|
|
var engine = scene.getEngine();
|
|
var engine = scene.getEngine();
|
|
- var hardwareInstancedRendering = (engine.getCaps().instancedArrays) && (batch.visibleInstances[subMesh._id] !== null) && (batch.visibleInstances[subMesh._id] !== undefined);
|
|
|
|
|
|
+ var hardwareInstancedRendering = batch.hardwareInstancedRendering[subMesh._id];
|
|
|
|
|
|
// Material
|
|
// Material
|
|
let material = subMesh.getMaterial();
|
|
let material = subMesh.getMaterial();
|
|
@@ -2420,7 +2448,7 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
|
|
for (var j = 0; j < 3; j++) {
|
|
for (var j = 0; j < 3; j++) {
|
|
a = vertexIndex[j];
|
|
a = vertexIndex[j];
|
|
b = vertexIndex[(j + 1) % 3];
|
|
b = vertexIndex[(j + 1) % 3];
|
|
- if (side[a] === undefined && side[b] === undefined) {
|
|
|
|
|
|
+ if (side[a] === undefined && side[b] === undefined) {
|
|
side[a] = new Array();
|
|
side[a] = new Array();
|
|
side[b] = new Array();
|
|
side[b] = new Array();
|
|
}
|
|
}
|
|
@@ -2432,7 +2460,7 @@ export class Mesh extends AbstractMesh implements IGetSetVerticesData {
|
|
side[b] = new Array();
|
|
side[b] = new Array();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- if (side[a][b] === undefined && side[b][a] === undefined) {
|
|
|
|
|
|
+ if (side[a][b] === undefined && side[b][a] === undefined) {
|
|
side[a][b] = [];
|
|
side[a][b] = [];
|
|
deltaPosition.x = (positions[3 * b] - positions[3 * a]) / segments;
|
|
deltaPosition.x = (positions[3 * b] - positions[3 * a]) / segments;
|
|
deltaPosition.y = (positions[3 * b + 1] - positions[3 * a + 1]) / segments;
|
|
deltaPosition.y = (positions[3 * b + 1] - positions[3 * a + 1]) / segments;
|