Home Reference Source

viewer/reuseloader.js

import {BimserverGeometryLoader} from "./bimservergeometryloader.js";
import {Utils} from "./utils.js";

/**
 * When loading Tiles, there is sometimes geometry (GeometryData) that is reused in other Tiles as well, in that case it is omitted in the stream, to be loaded later.
 * This class is called whenever there is a batch of GeometryData that needs to be loaded.
 */
export class ReuseLoader {
	constructor(viewer, reuseLowerThreshold, bimServerApi, fieldsToInclude, roids, quantizationMap, geometryCache, geometryDataToReuse) {
		debugger;
		this.settings = viewer.settings;
		this.viewer = viewer;
		this.reuseLowerThreshold = reuseLowerThreshold;
		this.bimServerApi = bimServerApi;
		this.fieldsToInclude = fieldsToInclude;
		this.roids = roids;
		this.quantizationMap = quantizationMap;
		this.geometryCache = geometryCache;
		this.geometryDataToReuse = geometryDataToReuse;
		this.nrReused = 0;
		this.bytesReused = 0;
		this.loaderCounter = 0;
	}
	
	/*
	 * Load an array of geometry data ids
	 */
	load(geometryDataIds) {
		if (geometryDataIds.length == 0) {
			return;
		}
		var start = performance.now();
		var query = {
			oids: geometryDataIds,
			include: {
				type: "GeometryData",
				fieldsDirect: this.fieldsToInclude
			},
			loaderSettings: JSON.parse(JSON.stringify(this.settings.loaderSettings))
		};
		
		// The returned data (GeometryData) objects should be processed as normal, not as a preparedBuffer
		query.loaderSettings.prepareBuffers = false;

		var geometryLoader = new BimserverGeometryLoader(this.loaderCounter++, this.bimServerApi, this, this.roids, this.settings.loaderSettings, this.quantizationMap, this.viewer.stats, this.settings, query, null);
		var p = geometryLoader.start();
		p.then(() => {
			var end = performance.now();
		});
		return p;
	}
	
	/*
	 * This class acts as if it's a RenderLayer, the createGeometry is called} from the BimserverGeometryLoader
	 * We just store the incoming geometry in the (global) GeometryCache
	 */
	createGeometry(loaderId, roid, uniqueModelId, geometryId, positions, normals, colors, color, indices, lineIndices, hasTransparency, reused) {
		this.nrReused++;
		var bytes = Utils.calculateBytesUsed(this.settings, positions.length, colors.length, indices.length, lineIndices ? lineIndices.length : 0, normals.length);
		this.bytesReused += bytes;
		var geometry = {
				id: geometryId,
				roid: roid,
				uniqueModelId: uniqueModelId,
				positions: positions,
				normals: normals,
				colors: colors,
				color: color,
				indices: indices,
				lineIndices: lineIndices,
				hasTransparency: hasTransparency,
				reused: reused, // How many times this geometry is reused, this does not necessarily mean the viewer is going to utilize this reuse
				reuseMaterialized: 0, // How many times this geometry has been reused in the viewer, when this number reaches "reused" we can flush the buffer fo' sho'
				bytes: bytes,
				matrices: [],
				objects: []
		};
		
		geometry.isReused = this.settings.gpuReuse;
		
		this.geometryCache.set(geometryId, geometry);
		
		geometry.isReused = geometry.reused > 1 && this.geometryDataToReuse != null && this.geometryDataToReuse.has(geometry.id);
		if (geometry.isReused) {
			this.viewer.stats.inc("Models", "Geometries reused");
		} else {
			this.viewer.stats.inc("Models", "Geometries");
		}
	}
}