Bladeren bron

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js into pbr-sheen

Popov72 5 jaren geleden
bovenliggende
commit
f7b9241ffa
28 gewijzigde bestanden met toevoegingen van 584 en 125 verwijderingen
  1. 1 1
      dist/preview release/babylon.js
  2. 18 18
      dist/preview release/babylon.max.js
  3. 1 1
      dist/preview release/babylon.max.js.map
  4. 6 6
      dist/preview release/inspector/babylon.inspector.bundle.js
  5. 215 5
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  6. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  7. 24 12
      dist/preview release/inspector/babylon.inspector.d.ts
  8. 57 30
      dist/preview release/inspector/babylon.inspector.module.d.ts
  9. 11 11
      dist/preview release/serializers/babylon.glTF2Serializer.js
  10. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.js.map
  11. 4 4
      dist/preview release/serializers/babylon.objSerializer.js
  12. 1 1
      dist/preview release/serializers/babylon.objSerializer.js.map
  13. 13 13
      dist/preview release/serializers/babylonjs.serializers.js
  14. 1 1
      dist/preview release/serializers/babylonjs.serializers.js.map
  15. 6 6
      dist/preview release/viewer/babylon.viewer.js
  16. 1 1
      dist/preview release/viewer/babylon.viewer.max.js
  17. 4 0
      dist/preview release/what's new.md
  18. 10 0
      inspector/src/components/actionTabs/tabs/propertyGridTabComponent.tsx
  19. 2 2
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/texturePropertyGridComponent.tsx
  20. 137 2
      inspector/src/components/actionTabs/tabs/propertyGrids/particleSystems/particleSystemPropertyGridComponent.tsx
  21. 5 5
      inspector/src/components/embedHost/embedHostComponent.tsx
  22. 30 0
      inspector/src/components/sceneExplorer/entities/particleSystemTreeItemComponent.tsx
  23. 12 0
      inspector/src/components/sceneExplorer/sceneExplorer.scss
  24. 1 0
      inspector/src/components/sceneExplorer/sceneExplorerComponent.tsx
  25. 6 0
      inspector/src/components/sceneExplorer/treeItemSpecializedComponent.tsx
  26. 14 2
      src/Cameras/targetCamera.ts
  27. 1 1
      src/Particles/particleSystem.ts
  28. 1 1
      src/Shaders/ShadersInclude/bumpFragmentFunctions.fx

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/babylon.js


File diff suppressed because it is too large
+ 18 - 18
dist/preview release/babylon.max.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/babylon.max.js.map


File diff suppressed because it is too large
+ 6 - 6
dist/preview release/inspector/babylon.inspector.bundle.js


File diff suppressed because it is too large
+ 215 - 5
dist/preview release/inspector/babylon.inspector.bundle.max.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.max.js.map


+ 24 - 12
dist/preview release/inspector/babylon.inspector.d.ts

@@ -1351,6 +1351,19 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    interface IParticleSystemPropertyGridComponentProps {
+        globalState: GlobalState;
+        system: BABYLON.IParticleSystem;
+        lockObject: LockObject;
+        onSelectionChangedObservable?: BABYLON.Observable<any>;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+    }
+    export class ParticleSystemPropertyGridComponent extends React.Component<IParticleSystemPropertyGridComponentProps> {
+        constructor(props: IParticleSystemPropertyGridComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
     export class PropertyGridTabComponent extends PaneComponent {
         private _timerIntervalId;
         private _lockObject;
@@ -1686,6 +1699,17 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    interface IParticleSystemTreeItemComponentProps {
+        system: BABYLON.IParticleSystem;
+        extensibilityGroups?: BABYLON.IExplorerExtensibilityGroup[];
+        onClick: () => void;
+    }
+    export class ParticleSystemTreeItemComponent extends React.Component<IParticleSystemTreeItemComponentProps> {
+        constructor(props: IParticleSystemTreeItemComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
     interface ITreeItemSpecializedComponentProps {
         label: string;
         entity?: any;
@@ -1899,16 +1923,4 @@ declare module INSPECTOR {
         private static _RemoveElementFromDOM;
         static Hide(): void;
     }
-}
-declare module INSPECTOR {
-    interface IParticleSystemPropertyGridComponentProps {
-        globalState: GlobalState;
-        system: BABYLON.IParticleSystem;
-        lockObject: LockObject;
-        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
-    }
-    export class ParticleSystemPropertyGridComponent extends React.Component<IParticleSystemPropertyGridComponentProps> {
-        constructor(props: IParticleSystemPropertyGridComponentProps);
-        render(): JSX.Element;
-    }
 }

+ 57 - 30
dist/preview release/inspector/babylon.inspector.module.d.ts

@@ -1750,6 +1750,25 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/mat
         render(): JSX.Element;
     }
 }
+declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/particleSystems/particleSystemPropertyGridComponent" {
+    import * as React from "react";
+    import { Observable } from "babylonjs/Misc/observable";
+    import { PropertyChangedEvent } from "babylonjs-inspector/components/propertyChangedEvent";
+    import { LockObject } from "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/lockObject";
+    import { GlobalState } from "babylonjs-inspector/components/globalState";
+    import { IParticleSystem } from 'babylonjs/Particles/IParticleSystem';
+    interface IParticleSystemPropertyGridComponentProps {
+        globalState: GlobalState;
+        system: IParticleSystem;
+        lockObject: LockObject;
+        onSelectionChangedObservable?: Observable<any>;
+        onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
+    }
+    export class ParticleSystemPropertyGridComponent extends React.Component<IParticleSystemPropertyGridComponentProps> {
+        constructor(props: IParticleSystemPropertyGridComponentProps);
+        render(): JSX.Element;
+    }
+}
 declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGridTabComponent" {
     import { PaneComponent, IPaneComponentProps } from "babylonjs-inspector/components/actionTabs/paneComponent";
     export class PropertyGridTabComponent extends PaneComponent {
@@ -2145,6 +2164,20 @@ declare module "babylonjs-inspector/components/sceneExplorer/entities/boneTreeIt
         render(): JSX.Element;
     }
 }
+declare module "babylonjs-inspector/components/sceneExplorer/entities/particleSystemTreeItemComponent" {
+    import { IExplorerExtensibilityGroup } from "babylonjs/Debug/debugLayer";
+    import * as React from 'react';
+    import { IParticleSystem } from 'babylonjs/Particles/IParticleSystem';
+    interface IParticleSystemTreeItemComponentProps {
+        system: IParticleSystem;
+        extensibilityGroups?: IExplorerExtensibilityGroup[];
+        onClick: () => void;
+    }
+    export class ParticleSystemTreeItemComponent extends React.Component<IParticleSystemTreeItemComponentProps> {
+        constructor(props: IParticleSystemTreeItemComponentProps);
+        render(): JSX.Element;
+    }
+}
 declare module "babylonjs-inspector/components/sceneExplorer/treeItemSpecializedComponent" {
     import { IExplorerExtensibilityGroup } from "babylonjs/Debug/debugLayer";
     import * as React from "react";
@@ -2393,24 +2426,6 @@ declare module "babylonjs-inspector/inspector" {
 declare module "babylonjs-inspector/index" {
     export * from "babylonjs-inspector/inspector";
 }
-declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/particleSystems/particleSystemPropertyGridComponent" {
-    import * as React from "react";
-    import { Observable } from "babylonjs/Misc/observable";
-    import { PropertyChangedEvent } from "babylonjs-inspector/components/propertyChangedEvent";
-    import { LockObject } from "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/lockObject";
-    import { GlobalState } from "babylonjs-inspector/components/globalState";
-    import { IParticleSystem } from 'babylonjs/Particles/IParticleSystem';
-    interface IParticleSystemPropertyGridComponentProps {
-        globalState: GlobalState;
-        system: IParticleSystem;
-        lockObject: LockObject;
-        onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
-    }
-    export class ParticleSystemPropertyGridComponent extends React.Component<IParticleSystemPropertyGridComponentProps> {
-        constructor(props: IParticleSystemPropertyGridComponentProps);
-        render(): JSX.Element;
-    }
-}
 declare module "babylonjs-inspector/legacy/legacy" {
     export * from "babylonjs-inspector/index";
 }
@@ -3770,6 +3785,19 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    interface IParticleSystemPropertyGridComponentProps {
+        globalState: GlobalState;
+        system: BABYLON.IParticleSystem;
+        lockObject: LockObject;
+        onSelectionChangedObservable?: BABYLON.Observable<any>;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+    }
+    export class ParticleSystemPropertyGridComponent extends React.Component<IParticleSystemPropertyGridComponentProps> {
+        constructor(props: IParticleSystemPropertyGridComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
     export class PropertyGridTabComponent extends PaneComponent {
         private _timerIntervalId;
         private _lockObject;
@@ -4105,6 +4133,17 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    interface IParticleSystemTreeItemComponentProps {
+        system: BABYLON.IParticleSystem;
+        extensibilityGroups?: BABYLON.IExplorerExtensibilityGroup[];
+        onClick: () => void;
+    }
+    export class ParticleSystemTreeItemComponent extends React.Component<IParticleSystemTreeItemComponentProps> {
+        constructor(props: IParticleSystemTreeItemComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
     interface ITreeItemSpecializedComponentProps {
         label: string;
         entity?: any;
@@ -4318,16 +4357,4 @@ declare module INSPECTOR {
         private static _RemoveElementFromDOM;
         static Hide(): void;
     }
-}
-declare module INSPECTOR {
-    interface IParticleSystemPropertyGridComponentProps {
-        globalState: GlobalState;
-        system: BABYLON.IParticleSystem;
-        lockObject: LockObject;
-        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
-    }
-    export class ParticleSystemPropertyGridComponent extends React.Component<IParticleSystemPropertyGridComponentProps> {
-        constructor(props: IParticleSystemPropertyGridComponentProps);
-        render(): JSX.Element;
-    }
 }

+ 11 - 11
dist/preview release/serializers/babylon.glTF2Serializer.js

@@ -7,7 +7,7 @@
 		exports["babylonjs-serializers"] = factory(require("babylonjs"));
 	else
 		root["SERIALIZERS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_PBR_pbrMaterial__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Maths_math_vector__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -366,7 +366,7 @@ module.exports = g;
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KHR_lights_punctual", function() { return KHR_lights_punctual; });
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFExporter */ "./glTF/2.0/glTFExporter.ts");
 /* harmony import */ var _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFUtilities */ "./glTF/2.0/glTFUtilities.ts");
@@ -564,7 +564,7 @@ _glTFExporter__WEBPACK_IMPORTED_MODULE_1__["_Exporter"].RegisterExtension(NAME,
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KHR_materials_sheen", function() { return KHR_materials_sheen; });
 /* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFExporter */ "./glTF/2.0/glTFExporter.ts");
-/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__);
 
 
@@ -664,7 +664,7 @@ _glTFExporter__WEBPACK_IMPORTED_MODULE_0__["_Exporter"].RegisterExtension(NAME,
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return KHR_texture_transform; });
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFExporter */ "./glTF/2.0/glTFExporter.ts");
 /* harmony import */ var _shaders_textureTransform_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../shaders/textureTransform.fragment */ "./glTF/2.0/shaders/textureTransform.fragment.ts");
@@ -848,7 +848,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_GLTFAnimation", function() { return _GLTFAnimation; });
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./glTFUtilities */ "./glTF/2.0/glTFUtilities.ts");
 
@@ -1591,7 +1591,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_Exporter", function() { return _Exporter; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_BinaryWriter", function() { return _BinaryWriter; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _glTFMaterialExporter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./glTFMaterialExporter */ "./glTF/2.0/glTFMaterialExporter.ts");
 /* harmony import */ var _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./glTFUtilities */ "./glTF/2.0/glTFUtilities.ts");
@@ -3132,7 +3132,7 @@ var __IGLTFExporterExtensionV2 = 0; // I am here to allow dts to be created
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_GLTFMaterialExporter", function() { return _GLTFMaterialExporter; });
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -4331,7 +4331,7 @@ var GLTF2Export = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_GLTFUtilities", function() { return _GLTFUtilities; });
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
 
 /**
@@ -4575,7 +4575,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "textureTransformPixelShader", function() { return textureTransformPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 var name = 'textureTransformPixelShader';
@@ -4689,14 +4689,14 @@ if (typeof globalObject !== "undefined") {
 
 /***/ }),
 
-/***/ "babylonjs/Materials/PBR/pbrMaterial":
+/***/ "babylonjs/Maths/math.vector":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_PBR_pbrMaterial__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Maths_math_vector__;
 
 /***/ })
 

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/serializers/babylon.glTF2Serializer.js.map


+ 4 - 4
dist/preview release/serializers/babylon.objSerializer.js

@@ -7,7 +7,7 @@
 		exports["babylonjs-serializers"] = factory(require("babylonjs"));
 	else
 		root["SERIALIZERS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_PBR_pbrMaterial__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Maths_math_vector__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -154,7 +154,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OBJExport", function() { return OBJExport; });
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -334,14 +334,14 @@ if (typeof globalObject !== "undefined") {
 
 /***/ }),
 
-/***/ "babylonjs/Materials/PBR/pbrMaterial":
+/***/ "babylonjs/Maths/math.vector":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_PBR_pbrMaterial__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Maths_math_vector__;
 
 /***/ })
 

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/serializers/babylon.objSerializer.js.map


+ 13 - 13
dist/preview release/serializers/babylonjs.serializers.js

@@ -7,7 +7,7 @@
 		exports["babylonjs-serializers"] = factory(require("babylonjs"));
 	else
 		root["SERIALIZERS"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_PBR_pbrMaterial__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Maths_math_vector__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -383,7 +383,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "OBJExport", function() { return OBJExport; });
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -544,7 +544,7 @@ var OBJExport = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KHR_lights_punctual", function() { return KHR_lights_punctual; });
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFExporter */ "./glTF/2.0/glTFExporter.ts");
 /* harmony import */ var _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFUtilities */ "./glTF/2.0/glTFUtilities.ts");
@@ -742,7 +742,7 @@ _glTFExporter__WEBPACK_IMPORTED_MODULE_1__["_Exporter"].RegisterExtension(NAME,
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KHR_materials_sheen", function() { return KHR_materials_sheen; });
 /* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFExporter */ "./glTF/2.0/glTFExporter.ts");
-/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Materials/PBR/pbrMaterial */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_1__);
 
 
@@ -842,7 +842,7 @@ _glTFExporter__WEBPACK_IMPORTED_MODULE_0__["_Exporter"].RegisterExtension(NAME,
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return KHR_texture_transform; });
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFExporter */ "./glTF/2.0/glTFExporter.ts");
 /* harmony import */ var _shaders_textureTransform_fragment__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../shaders/textureTransform.fragment */ "./glTF/2.0/shaders/textureTransform.fragment.ts");
@@ -1026,7 +1026,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_GLTFAnimation", function() { return _GLTFAnimation; });
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _glTFUtilities__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./glTFUtilities */ "./glTF/2.0/glTFUtilities.ts");
 
@@ -1769,7 +1769,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_Exporter", function() { return _Exporter; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_BinaryWriter", function() { return _BinaryWriter; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _glTFMaterialExporter__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./glTFMaterialExporter */ "./glTF/2.0/glTFMaterialExporter.ts");
 /* harmony import */ var _glTFUtilities__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./glTFUtilities */ "./glTF/2.0/glTFUtilities.ts");
@@ -3310,7 +3310,7 @@ var __IGLTFExporterExtensionV2 = 0; // I am here to allow dts to be created
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_GLTFMaterialExporter", function() { return _GLTFMaterialExporter; });
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -4509,7 +4509,7 @@ var GLTF2Export = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_GLTFUtilities", function() { return _GLTFUtilities; });
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
 
 /**
@@ -4753,7 +4753,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "textureTransformPixelShader", function() { return textureTransformPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 var name = 'textureTransformPixelShader';
@@ -5089,7 +5089,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "STLExport", function() { return STLExport; });
-/* harmony import */ var babylonjs_Meshes_buffer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Meshes/buffer */ "babylonjs/Materials/PBR/pbrMaterial");
+/* harmony import */ var babylonjs_Meshes_buffer__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Meshes/buffer */ "babylonjs/Maths/math.vector");
 /* harmony import */ var babylonjs_Meshes_buffer__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_buffer__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -5201,14 +5201,14 @@ var STLExport = /** @class */ (function () {
 
 /***/ }),
 
-/***/ "babylonjs/Materials/PBR/pbrMaterial":
+/***/ "babylonjs/Maths/math.vector":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Materials_PBR_pbrMaterial__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Maths_math_vector__;
 
 /***/ })
 

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.js.map


File diff suppressed because it is too large
+ 6 - 6
dist/preview release/viewer/babylon.viewer.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


+ 4 - 0
dist/preview release/what's new.md

@@ -12,6 +12,10 @@
 
 - Allow logging of shader code when a compilation error occurs ([Popov72](https://github.com/Popov72))
 
+### Cameras
+
+- Added flag to TargetCamera to invert rotation direction and multiplier to adjust speed ([Exolun](https://github.com/Exolun))
+
 ### Physics
 
 - Ammo.js IDL exposed property update and raycast vehicle stablization support ([MackeyK24](https://github.com/MackeyK24))

+ 10 - 0
inspector/src/components/actionTabs/tabs/propertyGridTabComponent.tsx

@@ -89,6 +89,8 @@ import { NodeMaterial } from 'babylonjs/Materials/Node/nodeMaterial';
 import { NodeMaterialPropertyGridComponent } from './propertyGrids/materials/nodeMaterialPropertyGridComponent';
 import { MultiMaterial } from 'babylonjs/Materials/multiMaterial';
 import { MultiMaterialPropertyGridComponent } from './propertyGrids/materials/multiMaterialPropertyGridComponent';
+import { ParticleSystemPropertyGridComponent } from './propertyGrids/particleSystems/particleSystemPropertyGridComponent';
+import { IParticleSystem } from 'babylonjs/Particles/IParticleSystem';
 
 export class PropertyGridTabComponent extends PaneComponent {
     private _timerIntervalId: number;
@@ -149,6 +151,14 @@ export class PropertyGridTabComponent extends PaneComponent {
                 }
             }
 
+            if (className.indexOf("ParticleSystem") !== -1) {
+                const particleSystem = entity as IParticleSystem;
+                return (<ParticleSystemPropertyGridComponent globalState={this.props.globalState} system={particleSystem}
+                    lockObject={this._lockObject}
+                    onSelectionChangedObservable={this.props.onSelectionChangedObservable}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
             if (className.indexOf("FreeCamera") !== -1 || className.indexOf("UniversalCamera") !== -1
             || className.indexOf("WebXRCamera") !== -1  || className.indexOf("DeviceOrientationCamera") !== -1) {
                 const freeCamera = entity as FreeCamera;

+ 2 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/materials/texturePropertyGridComponent.tsx

@@ -44,6 +44,8 @@ export class TexturePropertyGridComponent extends React.Component<ITextureProper
 
         const texture = this.props.texture;
 
+        this.textureLineRef = React.createRef();
+
         if (!texture || !(texture as any).rootContainer) {
             return;
         }
@@ -53,8 +55,6 @@ export class TexturePropertyGridComponent extends React.Component<ITextureProper
         this._adtInstrumentation = new AdvancedDynamicTextureInstrumentation(adt);
         this._adtInstrumentation!.captureRenderTime = true;
         this._adtInstrumentation!.captureLayoutTime = true;
-
-        this.textureLineRef = React.createRef();
     }
 
     componentWillUnmount() {

+ 137 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/particleSystems/particleSystemPropertyGridComponent.tsx

@@ -9,11 +9,27 @@ import { LockObject } from "../lockObject";
 import { GlobalState } from '../../../../globalState';
 import { CustomPropertyGridComponent } from '../customPropertyGridComponent';
 import { IParticleSystem } from 'babylonjs/Particles/IParticleSystem';
+import { FloatLineComponent } from '../../../lines/floatLineComponent';
+import { ButtonLineComponent } from '../../../lines/buttonLineComponent';
+import { TextureLinkLineComponent } from '../../../lines/textureLinkLineComponent';
+import { OptionsLineComponent } from '../../../lines/optionsLineComponent';
+import { ParticleSystem } from 'babylonjs/Particles/particleSystem';
+import { Color4LineComponent } from '../../../lines/color4LineComponent';
+import { Vector3LineComponent } from '../../../lines/vector3LineComponent';
+import { CheckBoxLineComponent } from '../../../lines/checkBoxLineComponent';
+import { SliderLineComponent } from '../../../lines/sliderLineComponent';
+import { BoxParticleEmitter } from 'babylonjs/Particles/EmitterTypes/boxParticleEmitter';
+import { ConeParticleEmitter } from 'babylonjs/Particles/EmitterTypes/coneParticleEmitter';
+import { CylinderParticleEmitter } from 'babylonjs/Particles/EmitterTypes/cylinderParticleEmitter';
+import { HemisphericParticleEmitter } from 'babylonjs/Particles/EmitterTypes/hemisphericParticleEmitter';
+import { PointParticleEmitter } from 'babylonjs/Particles/EmitterTypes/pointParticleEmitter';
+import { SphereParticleEmitter } from 'babylonjs/Particles/EmitterTypes/sphereParticleEmitter';
 
 interface IParticleSystemPropertyGridComponentProps {
     globalState: GlobalState;
     system: IParticleSystem,
     lockObject: LockObject,
+    onSelectionChangedObservable?: Observable<any>,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
 }
 
@@ -25,6 +41,23 @@ export class ParticleSystemPropertyGridComponent extends React.Component<IPartic
     render() {
         const system = this.props.system;
 
+        var blendModeOptions = [
+            { label: "Add", value: ParticleSystem.BLENDMODE_ADD },
+            { label: "Multiply", value: ParticleSystem.BLENDMODE_MULTIPLY },
+            { label: "Multiply Add", value: ParticleSystem.BLENDMODE_MULTIPLYADD },
+            { label: "OneOne", value: ParticleSystem.BLENDMODE_ONEONE },
+            { label: "Standard", value: ParticleSystem.BLENDMODE_STANDARD },
+        ];   
+        
+        var particleEmitterTypeOptions = [
+            { label: "Box", value: 0 },
+            { label: "Cone", value: 1 },
+            { label: "Cylinder", value: 2 },
+            { label: "Hemispheric", value: 3 },
+            { label: "Point", value: 4 },
+            { label: "Sphere", value: 5 },
+        ];
+
         return (
             <div className="pane">
                 <CustomPropertyGridComponent globalState={this.props.globalState} target={system}
@@ -32,8 +65,110 @@ export class ParticleSystemPropertyGridComponent extends React.Component<IPartic
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 <LineContainerComponent globalState={this.props.globalState} title="GENERAL">
                     <TextLineComponent label="ID" value={system.id} />
-                    <TextLineComponent label="Class" value={system.getClassName()} />                                      
-                </LineContainerComponent>                
+                    <TextLineComponent label="Class" value={system.getClassName()} />  
+                    <TextureLinkLineComponent label="Texture" texture={system.particleTexture} onSelectionChangedObservable={this.props.onSelectionChangedObservable}/>
+                    <OptionsLineComponent label="Blend mode" options={blendModeOptions} target={system} propertyName="blendMode" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <Vector3LineComponent label="Gravity" target={system} propertyName="gravity"
+                        onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Is billboard" target={system} propertyName="isBillboardBased" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Is local" target={system} propertyName="isLocal" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <SliderLineComponent label="Update speed" target={system} propertyName="updateSpeed" minimum={0} maximum={1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>                      
+                <LineContainerComponent globalState={this.props.globalState} title="OPTIONS">
+                    <ButtonLineComponent label={system.isStarted() ? "Stop" : "Start"} onClick={() => {
+                        if (system.isStarted()) {
+                            system.stop();
+                        } else {
+                            system.start();
+                        }
+                    }} />
+                </LineContainerComponent>
+                <LineContainerComponent globalState={this.props.globalState} title="Emitter">
+                    <OptionsLineComponent 
+                        label="Type" 
+                        options={particleEmitterTypeOptions} 
+                        target={system}
+                        propertyName="particleEmitterType"
+                        noDirectUpdate={true}
+                        onSelect={(value: number) => {
+                            switch(value) {
+                                case 0:
+                                    system.particleEmitterType = new BoxParticleEmitter();
+                                    break;
+                                    
+                                case 1:
+                                    system.particleEmitterType = new ConeParticleEmitter();
+                                    break;
+                                    
+                                case 2:
+                                    system.particleEmitterType = new CylinderParticleEmitter();
+                                    break;
+                                    
+                                case 3:
+                                    system.particleEmitterType = new HemisphericParticleEmitter();
+                                    break;
+                                    
+                                case 4:
+                                    system.particleEmitterType = new PointParticleEmitter();
+                                    break;   
+
+                                case 5:
+                                    system.particleEmitterType = new SphereParticleEmitter();
+                                    break;
+                            }
+                        }}
+                        extractValue={() => {
+                            switch(system.particleEmitterType?.getClassName()) {
+                                case "BoxParticleEmitter":
+                                    return 0;
+                                case "ConeParticleEmitter":
+                                    return 1;
+                                case "CylinderParticleEmitter":
+                                    return 2;        
+                                case "HemisphericParticleEmitter":
+                                    return 3;
+                                case "PointParticleEmitter":
+                                    return 4;
+                                case "SphereParticleEmitter":
+                                    return 5;                                                                                                          
+                            }
+
+                            return 0;
+                        }}
+                        onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+
+                </LineContainerComponent>
+                <LineContainerComponent globalState={this.props.globalState} title="SIZE">
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Min size" target={system} propertyName="minSize" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Max size" target={system} propertyName="maxSize" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Min scale X" target={system} propertyName="minScaleX" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Max scale X" target={system} propertyName="maxScaleX" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Min scale Y" target={system} propertyName="minScaleY" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Max scale Y" target={system} propertyName="maxScaleY" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>          
+                <LineContainerComponent globalState={this.props.globalState} title="LIFETIME">
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Min lifetime" target={system} propertyName="minLifeTime" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Max lifetime" target={system} propertyName="maxLifeTime" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>           
+                <LineContainerComponent globalState={this.props.globalState} title="EMISSION">
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Rate" target={system} propertyName="emitRate" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Min emit power" target={system} propertyName="minEmitPower" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Max emit power" target={system} propertyName="maxEmitPower" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>  
+                <LineContainerComponent globalState={this.props.globalState} title="COLORS">
+                    <Color4LineComponent label="Color 1" target={system} propertyName="color1" 
+                        onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <Color4LineComponent label="Color 2" target={system} propertyName="color2" 
+                        onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <Color4LineComponent label="Color dead" target={system} propertyName="colorDead" 
+                        onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>                     
+                <LineContainerComponent globalState={this.props.globalState} title="ROTATION">
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Min angular speed" target={system} propertyName="minAngularSpeed" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Max angular speed" target={system} propertyName="maxAngularSpeed" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Min initial rotation" target={system} propertyName="minInitialRotation" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent lockObject={this.props.lockObject} label="Max initial rotation" target={system} propertyName="maxInitialRotation" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>  
             </div>
         );
     }

+ 5 - 5
inspector/src/components/embedHost/embedHostComponent.tsx

@@ -30,7 +30,11 @@ export class EmbedHostComponent extends React.Component<IEmbedHostComponentProps
     private bottomPartRef: React.RefObject<HTMLDivElement>;
 
     constructor(props: IEmbedHostComponentProps) {
-        super(props);
+        super(props);        
+
+        this.splitRef = React.createRef();
+        this.topPartRef = React.createRef();
+        this.bottomPartRef = React.createRef();
     }
 
     componentDidMount() {
@@ -45,10 +49,6 @@ export class EmbedHostComponent extends React.Component<IEmbedHostComponentProps
             minSize: [200, 200],
             gutterSize: 4
         });
-
-        this.splitRef = React.createRef();
-        this.topPartRef = React.createRef();
-        this.bottomPartRef = React.createRef();
     }
 
     renderContent() {

+ 30 - 0
inspector/src/components/sceneExplorer/entities/particleSystemTreeItemComponent.tsx

@@ -0,0 +1,30 @@
+import { IExplorerExtensibilityGroup } from "babylonjs/Debug/debugLayer";
+
+import { faBraille } from '@fortawesome/free-solid-svg-icons';
+import { TreeItemLabelComponent } from "../treeItemLabelComponent";
+import { ExtensionsComponent } from "../extensionsComponent";
+import * as React from 'react';
+import { IParticleSystem } from 'babylonjs/Particles/IParticleSystem';
+
+interface IParticleSystemTreeItemComponentProps {
+    system: IParticleSystem,
+    extensibilityGroups?: IExplorerExtensibilityGroup[],
+    onClick: () => void
+}
+
+export class ParticleSystemTreeItemComponent extends React.Component<IParticleSystemTreeItemComponentProps> {
+    constructor(props: IParticleSystemTreeItemComponentProps) {
+        super(props);
+    }
+
+    render() {
+        return (
+            <div className="particleSystemTools">
+                <TreeItemLabelComponent label={this.props.system.name || "Particle system"} onClick={() => this.props.onClick()} icon={faBraille} color="crimson" />
+                {
+                    <ExtensionsComponent target={this.props.system} extensibilityGroups={this.props.extensibilityGroups} />
+                }
+            </div>
+        )
+    }
+}

+ 12 - 0
inspector/src/components/sceneExplorer/sceneExplorer.scss

@@ -429,6 +429,18 @@
             }
         }
 
+        .particleSystemTools {
+            grid-column: 2;
+            display: grid;
+            grid-template-columns: 1fr auto 5px;
+            align-items: center;
+
+            .extensions {
+                width: 20px;
+                grid-column: 2;
+            }
+        }
+
         .postProcessTools {
             grid-column: 2;
             display: grid;

+ 1 - 0
inspector/src/components/sceneExplorer/sceneExplorerComponent.tsx

@@ -324,6 +324,7 @@ export class SceneExplorerComponent extends React.Component<ISceneExplorerCompon
             label: "Add new particle system",
             action: () => {
                 let newSystem = ParticleHelper.CreateDefault(Vector3.Zero(), 1000, scene);
+                newSystem.start();
                 this.props.globalState.onSelectionChangedObservable.notifyObservers(newSystem);
             }
         });

+ 6 - 0
inspector/src/components/sceneExplorer/treeItemSpecializedComponent.tsx

@@ -30,6 +30,8 @@ import { SkeletonTreeItemComponent } from './entities/skeletonTreeItemComponent'
 import { Skeleton } from 'babylonjs/Bones/skeleton';
 import { BoneTreeItemComponent } from './entities/boneTreeItemComponent';
 import { Bone } from 'babylonjs/Bones/bone';
+import { ParticleSystemTreeItemComponent } from './entities/particleSystemTreeItemComponent';
+import { IParticleSystem } from 'babylonjs/Particles/IParticleSystem';
 
 
 interface ITreeItemSpecializedComponentProps {
@@ -92,6 +94,10 @@ export class TreeItemSpecializedComponent extends React.Component<ITreeItemSpeci
                 return (<MaterialTreeItemComponent extensibilityGroups={this.props.extensibilityGroups} material={entity as Material} onClick={() => this.onClick()} />);
             }
 
+            if (className.indexOf("ParticleSystem") !== -1) {
+                return (<ParticleSystemTreeItemComponent extensibilityGroups={this.props.extensibilityGroups} system={entity as IParticleSystem} onClick={() => this.onClick()} />);
+            }
+
             if (className === "AdvancedDynamicTexture") {
                 return (<AdvancedDynamicTextureTreeItemComponent onSelectionChangedObservable={this.props.globalState.onSelectionChangedObservable} extensibilityGroups={this.props.extensibilityGroups} texture={entity as AdvancedDynamicTexture} onClick={() => this.onClick()} />);
             }

+ 14 - 2
src/Cameras/targetCamera.ts

@@ -53,6 +53,17 @@ export class TargetCamera extends Camera {
     public noRotationConstraint = false;
 
     /**
+     * Reverses mouselook direction to 'natural' panning as opposed to traditional direct
+     * panning
+     */
+    public invertRotation = false;
+
+    /**
+     * Speed multiplier for inverse camera panning
+     */
+    public inverseRotationSpeed = 0.2;
+
+    /**
      * Define the current target of the camera as an object or a position.
      */
     @serializeAsMeshReference("lockedTargetId")
@@ -290,6 +301,7 @@ export class TargetCamera extends Camera {
 
     /** @hidden */
     public _checkInputs(): void {
+        var directionMultiplier = this.invertRotation ? -this.inverseRotationSpeed : 1.0;
         var needToMove = this._decideIfNeedsToMove();
         var needToRotate = Math.abs(this.cameraRotation.x) > 0 || Math.abs(this.cameraRotation.y) > 0;
 
@@ -300,8 +312,8 @@ export class TargetCamera extends Camera {
 
         // Rotate
         if (needToRotate) {
-            this.rotation.x += this.cameraRotation.x;
-            this.rotation.y += this.cameraRotation.y;
+            this.rotation.x += this.cameraRotation.x * directionMultiplier;
+            this.rotation.y += this.cameraRotation.y * directionMultiplier;
 
             //rotate, if quaternion is set and rotation was used
             if (this.rotationQuaternion) {

+ 1 - 1
src/Particles/particleSystem.ts

@@ -344,7 +344,7 @@ export class ParticleSystem extends BaseParticleSystem implements IDisposable, I
                     });
                 }
 
-                if (this.isLocal) {
+                if (this.isLocal && particle._localPosition) {
                     particle._localPosition!.addInPlace(this._scaledDirection);
                     Vector3.TransformCoordinatesToRef(particle._localPosition!, this._emitterWorldMatrix, particle.position);
                 } else {

+ 1 - 1
src/Shaders/ShadersInclude/bumpFragmentFunctions.fx

@@ -62,7 +62,7 @@
 	}
 #endif
 
-#if defined(BUMP) || defined(CLEARCOAT_BUMP)
+#if defined(BUMP)
 	vec3 perturbNormal(mat3 cotangentFrame, vec3 color)
 	{
 		return perturbNormal(cotangentFrame, color, vBumpInfos.y);