viewerLabs.ts 8.0 KB

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