viewerLabs.ts 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import { PBREnvironment, EnvironmentDeserializer } from "./environmentSerializer";
  2. import { Tools, Quaternion, ShadowLight, Vector3, Axis, Matrix, SphericalPolynomial, Tmp, Scene } from 'babylonjs';
  3. import { TextureUtils } from "./texture";
  4. /**
  5. * The ViewerLabs class will hold functions that are not (!) backwards compatible.
  6. * The APIs in all labs-related classes and configuration might change.
  7. * Once stable, lab features will be moved to the publis API and configuration object.
  8. */
  9. export class ViewerLabs {
  10. constructor(private _scene: Scene) { }
  11. public assetsRootURL: string;
  12. public environment: PBREnvironment = {
  13. //irradiance
  14. irradiancePolynomialCoefficients: {
  15. x: new Vector3(0, 0, 0),
  16. y: new Vector3(0, 0, 0),
  17. z: new Vector3(0, 0, 0),
  18. xx: new Vector3(0, 0, 0),
  19. yy: new Vector3(0, 0, 0),
  20. zz: new Vector3(0, 0, 0),
  21. yz: new Vector3(0, 0, 0),
  22. zx: new Vector3(0, 0, 0),
  23. xy: new Vector3(0, 0, 0)
  24. },
  25. textureIntensityScale: 1.0
  26. };
  27. /**
  28. * Loads an environment map from a given URL
  29. * @param url URL of environment map
  30. * @param onSuccess Callback fired after environment successfully applied to the scene
  31. * @param onProgress Callback fired at progress events while loading the environment map
  32. * @param onError Callback fired when the load fails
  33. */
  34. public loadEnvironment(url: string, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
  35. /**
  36. * Loads an environment map from a given URL
  37. * @param buffer ArrayBuffer containing environment map
  38. * @param onSuccess Callback fired after environment successfully applied to the scene
  39. * @param onProgress Callback fired at progress events while loading the environment map
  40. * @param onError Callback fired when the load fails
  41. */
  42. public loadEnvironment(buffer: ArrayBuffer, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
  43. /**
  44. * Sets the environment to an already loaded environment
  45. * @param env PBREnvironment instance
  46. * @param onSuccess Callback fired after environment successfully applied to the scene
  47. * @param onProgress Callback fired at progress events while loading the environment map
  48. * @param onError Callback fired when the load fails
  49. */
  50. public loadEnvironment(env: PBREnvironment, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void;
  51. public loadEnvironment(data: string | ArrayBuffer | PBREnvironment, onSuccess?: (env: PBREnvironment) => void, onProgress?: (bytesLoaded: number, bytesTotal: number) => void, onError?: (e: any) => void): void {
  52. //@! todo: should loadEnvironment cancel any currently loading environments?
  53. if (data instanceof ArrayBuffer) {
  54. this.environment = EnvironmentDeserializer.Parse(data);
  55. if (onSuccess) onSuccess(this.environment);
  56. } else if (typeof data === 'string') {
  57. let url = this.getAssetUrl(data);
  58. this._scene._loadFile(
  59. url,
  60. (arrayBuffer: ArrayBuffer) => {
  61. this.environment = EnvironmentDeserializer.Parse(arrayBuffer);
  62. if (onSuccess) onSuccess(this.environment);
  63. },
  64. (progressEvent) => { if (onProgress) onProgress(progressEvent.loaded, progressEvent.total); },
  65. false,
  66. true,
  67. (r, e) => {
  68. if (onError) {
  69. onError(e);
  70. }
  71. }
  72. );
  73. } else {
  74. //data assumed to be PBREnvironment object
  75. this.environment = data;
  76. if (onSuccess) onSuccess(data);
  77. }
  78. }
  79. /**
  80. * Applies an `EnvironmentMapConfiguration` to the scene
  81. * @param environmentMapConfiguration Environment map configuration to apply
  82. */
  83. public applyEnvironmentMapConfiguration(rotationY?: number) {
  84. if (!this.environment) return;
  85. //set orientation
  86. let rotatquatRotationionY = Quaternion.RotationAxis(Axis.Y, rotationY || 0);
  87. // Add env texture to the scene.
  88. if (this.environment.specularTexture) {
  89. // IE crashes when disposing the old texture and setting a new one
  90. if (!this._scene.environmentTexture) {
  91. this._scene.environmentTexture = TextureUtils.GetBabylonCubeTexture(this._scene, this.environment.specularTexture, false, true);
  92. }
  93. if (this._scene.environmentTexture) {
  94. this._scene.environmentTexture.level = this.environment.textureIntensityScale;
  95. this._scene.environmentTexture.invertZ = true;
  96. this._scene.environmentTexture.lodLevelInAlpha = true;
  97. var poly = this._scene.environmentTexture.sphericalPolynomial || new SphericalPolynomial();
  98. poly.x = this.environment.irradiancePolynomialCoefficients.x;
  99. poly.y = this.environment.irradiancePolynomialCoefficients.y;
  100. poly.z = this.environment.irradiancePolynomialCoefficients.z;
  101. poly.xx = this.environment.irradiancePolynomialCoefficients.xx;
  102. poly.xy = this.environment.irradiancePolynomialCoefficients.xy;
  103. poly.yy = this.environment.irradiancePolynomialCoefficients.yy;
  104. poly.yz = this.environment.irradiancePolynomialCoefficients.yz;
  105. poly.zx = this.environment.irradiancePolynomialCoefficients.zx;
  106. poly.zz = this.environment.irradiancePolynomialCoefficients.zz;
  107. this._scene.environmentTexture.sphericalPolynomial = poly;
  108. //set orientation
  109. Matrix.FromQuaternionToRef(rotatquatRotationionY, this._scene.environmentTexture.getReflectionTextureMatrix());
  110. }
  111. }
  112. }
  113. /**
  114. * Get an environment asset url by using the configuration if the path is not absolute.
  115. * @param url Asset url
  116. * @returns The Asset url using the `environmentAssetsRootURL` if the url is not an absolute path.
  117. */
  118. public getAssetUrl(url: string): string {
  119. let returnUrl = url;
  120. if (url && url.toLowerCase().indexOf("//") === -1) {
  121. if (!this.assetsRootURL) {
  122. // Tools.Warn("Please, specify the root url of your assets before loading the configuration (labs.environmentAssetsRootURL) or disable the background through the viewer options.");
  123. return url;
  124. }
  125. returnUrl = this.assetsRootURL + returnUrl;
  126. }
  127. return returnUrl;
  128. }
  129. public rotateShadowLight(shadowLight: ShadowLight, amount: number, point = Vector3.Zero(), axis = Axis.Y, target = Vector3.Zero()) {
  130. axis.normalize();
  131. point.subtractToRef(shadowLight.position, Tmp.Vector3[0]);
  132. Matrix.TranslationToRef(Tmp.Vector3[0].x, Tmp.Vector3[0].y, Tmp.Vector3[0].z, Tmp.Matrix[0]);
  133. Tmp.Matrix[0].invertToRef(Tmp.Matrix[2]);
  134. Matrix.RotationAxisToRef(axis, amount, Tmp.Matrix[1]);
  135. Tmp.Matrix[2].multiplyToRef(Tmp.Matrix[1], Tmp.Matrix[2]);
  136. Tmp.Matrix[2].multiplyToRef(Tmp.Matrix[0], Tmp.Matrix[2]);
  137. Tmp.Matrix[2].decompose(Tmp.Vector3[0], Tmp.Quaternion[0], Tmp.Vector3[1]);
  138. shadowLight.position.addInPlace(Tmp.Vector3[1]);
  139. shadowLight.setDirectionToTarget(target);
  140. }
  141. }