“This is the 28th day of my participation in the First Challenge 2022. For details: First Challenge 2022”

The sample code USES three. Js – r73 version: cdnjs.cloudflare.com/ajax/libs/t…

We have used VTKLoader to load our VTK model, so VTKLoader internal how to implement it, let’s take a look.

VTKLoader constructor

THREE.VTKLoader = function (manager) {

	this.manager = (manager ! = =undefined)? manager : THREE.DefaultLoadingManager; }; THREE.VTKLoader.prototype = {constructor: THREE.VTKLoader,
}
Copy the code
  • THREE.VTKLoaderThe constructor is set on the prototype,
    • Can pass inmanagerParameter, which allows you to customize the load manager
    • If not, it is the default load manager within THREETHREE.DefaultLoadingManager

THREE.DefaultLoadingManager

  • What does the default load manager do
THREE.DefaultLoadingManager = new THREE.LoadingManager();
Copy the code
  • The default load manager is instantiatedTHREE.LoadingManager

THREE.LoadingManager

  • There are some variables defined in this function
THREE.LoadingManager = function (onLoad, onProgress, onError) {
	// Outer this alias
	var scope = this;

	var isLoading = false,
		itemsLoaded = 0.// Indicates the number of loaded bytes
		itemsTotal = 0; // represents the total number of loaded bytes

	this.onStart = undefined;  // This function is undefined at initialization time and needs to be overwritten
	this.onLoad = onLoad; // Load the completed callback
	this.onProgress = onProgress; // A callback to the loading progress
	this.onError = onError; // Load the wrong callback. }Copy the code
  • One thing to noteitemsLoadedanditemsTotalIt’s the number of bytes
  • The whole life of the function looks like this
    • ItemStart before loading
    • OnStart loads the starting callback
    • ItemEnd is finished loading
    • OnLoad completes the callback to load

ItemStart and itemEnd are called each time the server returns data

// Load the URL
this.itemStart = function (url) {
  // Total number of loaded bytes
  itemsTotal++;
  // If not loaded
  if (isLoading === false) {
    // 
    if(scope.onStart ! = =undefined) {
      // Number of loaded urls Total number of loaded urlsscope.onStart(url, itemsLoaded, itemsTotal); }}// Set to loading
  isLoading = true;
};
Copy the code
  • ItemStart records the total number of loaded bytes per call
  • This method is called if there is no load and there is an onStart callback
  • Record the recorded state as being loaded
this.itemEnd = function (url) {
  // The number of bytes loaded
  itemsLoaded++;
  if(scope.onProgress ! = =undefined) {
    scope.onProgress(url, itemsLoaded, itemsTotal);
  }
  // The number of bytes loaded is equal to the total number of bytes
  if (itemsLoaded === itemsTotal) {
    isLoading = false;
    if(scope.onLoad ! = =undefined) {
      / / call onLoadscope.onLoad(); }}};Copy the code
  • ItemEnd records the number of bytes that have been loaded
  • If I defineonProgressThe callback function is called
  • If the number of loaded bytes equals the total number of bytes, the loading is completeonLoadThe callback function

VTKLoader load method

  • With constructors out of the way, let’s look at VTKLoader’s load method
	/ * * * *@param {*} Url Indicates the URL address *@param {*} OnLoad successfully loaded callback *@param {*} OnProgress load process callback *@param {*} OnError loads the error callback */
	load: function (url, onLoad, onProgress, onError) {

		var scope = this;
		// Call THREE's XHR request instance, passing in the load manager
		var loader = new THREE.XHRLoader(scope.manager);
		/ / set the cross
		loader.setCrossOrigin(this.crossOrigin);
		// Call the load function to return text data
		loader.load(url, function (text) {
			// Parse the text data, and return Geometry
			onLoad(scope.parse(text));

		}, onProgress, onError);

	},
Copy the code
  • The load method is simple, passing in the URL address, then requesting the resource and calling the corresponding callback function
  • instantiationTHREE.XHRLoader, and returns the text data, which is parsed by the parse function (more on this in the next section), and returns Geometry

THREE.XHRLoader

  • This is THREE’s internal request loader based on the XHR definition
THREE.XHRLoader = function (manager) {
	this.manager = (manager ! = =undefined)? manager : THREE.DefaultLoadingManager; }; THREE.XHRLoader.prototype = {constructor: THREE.XHRLoader,
  ...
}
Copy the code
  • THREE.XHRLoaderIs used by defaultTHREE.DefaultLoadingManager
  • Let’s focus on the load method
load: function (url, onLoad, onProgress, onError) {
		var scope = this;
		// Get the cached URL data
		var cached = THREE.Cache.get(url);
		// If there is data in the cache, go directly to the cache
		if(cached ! = =undefined) {
			if (onLoad) {
				setTimeout(function () {
					onLoad(cached);
				}, 0);
			}
			return cached;
		}
		// Create a GET request for XHR
		var request = new XMLHttpRequest();
		request.open('GET', url, true);
		// Listen for loading status
		request.addEventListener('load'.function (event) {
			// Get the response data
			var response = event.target.response;
			// Cache the url
			THREE.Cache.add(url, response);
			// Call the onLoad callback to return data
			if (onLoad) onLoad(response);
			// Call the loading end method
			scope.manager.itemEnd(url);

		}, false);
		// If we define the onProgress callback, listen for the loading progress
		if(onProgress ! = =undefined) {
			request.addEventListener('progress'.function (event) {
				onProgress(event);
			}, false);
		}
		// Listening load error
		request.addEventListener('error'.function (event) {
			// If the onError callback is defined, the corresponding data is returned
			if (onError) onError(event);
      scope.manager.itemError(url);
    }, false);
		/ / set the cross
		if (this.crossOrigin ! = =undefined) request.crossOrigin = this.crossOrigin;
		// Set the response type
		if (this.responseType ! = =undefined) request.responseType = this.responseType;
		// Sets whether credentials are carried across domains
		if (this.withCredentials ! = =undefined) request.withCredentials = this.withCredentials;
		// Send the request
		request.send(null);
		// Call itemStart lifecycle
		scope.manager.itemStart(url);
		return request;
	}
Copy the code
  • The cache data is retrieved and, if there is any, returned directly
  • The data is then retrieved by creating XHR get requests and cached
  • Call the lifecycle method to complete the callback notification

THREE.Cache

  • Three cache method implementation
THREE.Cache = {
	enabled: false.// Whether to enable caching
	files: {}, // Cache data
	add: function (key, file) {
		if (this.enabled === false) return;
		this.files[key] = file;
	},
	get: function (key) {
		if (this.enabled === false) return;
		return this.files[key];
	},
	remove: function (key) {
		delete this.files[key];
	},
	clear: function () {
		this.files = {}; }};Copy the code
  • Enabled: Whether to enable the cache function
  • Files: The cached data is actually a locally scoped object
  • The add, get, remove and clear methods are defined

Function execution flow

  • After the introduction of the core function, let’s look at the execution process of the whole VTKloader function

conclusion

In this section, we mainly talk about the following contents:

  • VTKLoader constructor
  • THREE. DefaultLoadingManager loader by default
  • THREE.LoadingManager loads the constructor
  • THREE. XHRLoader request loader
  • Cache implementation
  • VTKLoader requests resources