Pārlūkot izejas kodu

Add new color picker to inspector

David Catuhe 5 gadi atpakaļ
vecāks
revīzija
29396e7519

+ 37 - 0
inspector/src/components/actionTabs/actionTabs.scss

@@ -213,6 +213,34 @@ $line-padding-left: 2px;
                     }
                     }
                 }
                 }
 
 
+                .color-picker {
+                    height: calc(100% - 8px);
+                    margin: 4px;
+                    width: 100%;
+
+                    .color-rect {
+                        height: calc(100% - 4px);
+                        border: 2px white solid;
+                        cursor: pointer;
+                        min-height: 18px;
+                    }
+
+                    .color-picker-cover {
+                        position: fixed;
+                        top: 0px;
+                        right: 0px;
+                        bottom: 0px;
+                        left: 0px;
+                    }
+
+                    .color-picker-float {
+                        z-index: 2;
+                        position: absolute;  
+                        width: 300px;
+                        height: 300px;
+                    }                
+                }
+
                 .linkButtonLine {
                 .linkButtonLine {
                     padding-left: $line-padding-left;
                     padding-left: $line-padding-left;
                     height: 30px;
                     height: 30px;
@@ -335,6 +363,14 @@ $line-padding-left: 2px;
                             grid-row: 1;
                             grid-row: 1;
                             grid-column: 1;
                             grid-column: 1;
                         }
                         }
+
+                        .color1 {
+                            height: 100%;
+                        }
+
+                        .color2{
+                            height: 100%;
+                        }
                             
                             
                         .factor1 {
                         .factor1 {
                             grid-row: 1;
                             grid-row: 1;
@@ -840,6 +876,7 @@ $line-padding-left: 2px;
 
 
                         .color3 {
                         .color3 {
                             grid-column: 2;
                             grid-column: 2;
+                            width: 50px;
                             
                             
                             display: flex;
                             display: flex;
                             align-items: center;   
                             align-items: center;   

+ 4 - 2
inspector/src/components/actionTabs/lines/color3LineComponent.tsx

@@ -5,6 +5,7 @@ import { NumericInputComponent } from "./numericInputComponent";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
 import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
 import { Color3 } from 'babylonjs/Maths/math.color';
 import { Color3 } from 'babylonjs/Maths/math.color';
+import { ColorPickerLineComponent } from './colorPickerComponent';
 
 
 const copyIcon: string = require("./copy.svg");
 const copyIcon: string = require("./copy.svg");
 
 
@@ -136,7 +137,6 @@ export class Color3LineComponent extends React.Component<IColor3LineComponentPro
     render() {
     render() {
 
 
         const chevron = this.state.isExpanded ? <FontAwesomeIcon icon={faMinus} /> : <FontAwesomeIcon icon={faPlus} />;
         const chevron = this.state.isExpanded ? <FontAwesomeIcon icon={faMinus} /> : <FontAwesomeIcon icon={faPlus} />;
-        const colorAsColor3 = this.state.color.getClassName() === "Color3" ? this.state.color : new Color3(this.state.color.r, this.state.color.g, this.state.color.b);
 
 
         return (
         return (
             <div className="color3Line">
             <div className="color3Line">
@@ -145,7 +145,9 @@ export class Color3LineComponent extends React.Component<IColor3LineComponentPro
                         {this.props.label}
                         {this.props.label}
                     </div>
                     </div>
                     <div className="color3">
                     <div className="color3">
-                        <input type="color" value={colorAsColor3.toHexString()} onChange={(evt) => this.onChange(evt.target.value)} />
+                        <ColorPickerLineComponent value={this.state.color} disableAlpha={true} onColorChanged={color => {
+                            this.onChange(color);
+                        }} />                             
                     </div>
                     </div>
                     <div className="copy hoverIcon" onClick={() => this.copyToClipboard()} title="Copy to clipboard">
                     <div className="copy hoverIcon" onClick={() => this.copyToClipboard()} title="Copy to clipboard">
                         <img src={copyIcon} alt=""/>
                         <img src={copyIcon} alt=""/>

+ 8 - 8
inspector/src/components/actionTabs/lines/color4LineComponent.tsx

@@ -1,10 +1,11 @@
 import * as React from "react";
 import * as React from "react";
 import { Observable } from "babylonjs/Misc/observable";
 import { Observable } from "babylonjs/Misc/observable";
-import { Color3, Color4 } from "babylonjs/Maths/math.color";
+import { Color4 } from "babylonjs/Maths/math.color";
 import { NumericInputComponent } from "./numericInputComponent";
 import { NumericInputComponent } from "./numericInputComponent";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
 import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
 import { PropertyChangedEvent } from '../../propertyChangedEvent';
 import { PropertyChangedEvent } from '../../propertyChangedEvent';
+import { ColorPickerLineComponent } from './colorPickerComponent';
 
 
 const copyIcon: string = require("./copy.svg");
 const copyIcon: string = require("./copy.svg");
 
 
@@ -59,7 +60,7 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
 
 
     onChange(newValue: string) {
     onChange(newValue: string) {
         this._localChange = true;
         this._localChange = true;
-        const newColor = Color3.FromHexString(newValue);
+        const newColor = Color4.FromHexString(newValue);
 
 
         if (this.props.onPropertyChangedObservable) {
         if (this.props.onPropertyChangedObservable) {
             this.props.onPropertyChangedObservable.notifyObservers({
             this.props.onPropertyChangedObservable.notifyObservers({
@@ -70,11 +71,9 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
             });
             });
         }
         }
 
 
-        const newColor4 = new Color4(newColor.r, newColor.g, newColor.b, this.props.target[this.props.propertyName].a);
+        this.setPropertyValue(newColor);
 
 
-        this.setPropertyValue(newColor4);
-
-        this.setState({ color: newColor4 });
+        this.setState({ color: newColor });
 
 
         if (this.props.onChange) {
         if (this.props.onChange) {
             this.props.onChange();
             this.props.onChange();
@@ -162,7 +161,6 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
     render() {
     render() {
 
 
         const chevron = this.state.isExpanded ? <FontAwesomeIcon icon={faMinus} /> : <FontAwesomeIcon icon={faPlus} />;
         const chevron = this.state.isExpanded ? <FontAwesomeIcon icon={faMinus} /> : <FontAwesomeIcon icon={faPlus} />;
-        const colorAsColor3 = new Color3(this.state.color.r, this.state.color.g, this.state.color.b);
 
 
         return (
         return (
             <div className="color3Line">
             <div className="color3Line">
@@ -171,7 +169,9 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
                         {this.props.label}
                         {this.props.label}
                     </div>
                     </div>
                     <div className="color3">
                     <div className="color3">
-                        <input type="color" value={colorAsColor3.toHexString()} onChange={(evt) => this.onChange(evt.target.value)} />
+                        <ColorPickerLineComponent value={this.state.color} onColorChanged={color => {
+                            this.onChange(color);
+                        }} />                        
                     </div>
                     </div>
                     <div className="copy hoverIcon" onClick={() => this.copyToClipboard()} title="Copy to clipboard">
                     <div className="copy hoverIcon" onClick={() => this.copyToClipboard()} title="Copy to clipboard">
                         <img src={copyIcon} alt=""/>
                         <img src={copyIcon} alt=""/>

+ 111 - 0
inspector/src/components/actionTabs/lines/colorPickerComponent.tsx

@@ -0,0 +1,111 @@
+import * as React from "react";
+import { Color4, Color3 } from 'babylonjs/Maths/math.color';
+import { SketchPicker } from 'react-color';
+
+export interface IColorPickerComponentProps {
+    value: Color4 | Color3;
+    onColorChanged: (newOne: string) => void;
+    disableAlpha?: boolean;
+}
+
+interface IColorPickerComponentState {
+    pickerEnabled: boolean;
+    color: {
+        r: number,
+        g: number,
+        b: number,
+        a?: number
+    },
+    hex: string
+}
+
+export class ColorPickerLineComponent extends React.Component<IColorPickerComponentProps, IColorPickerComponentState> {
+    private _floatRef: React.RefObject<HTMLDivElement>
+    private _floatHostRef: React.RefObject<HTMLDivElement>
+
+    constructor(props: IColorPickerComponentProps) {
+        super(props);
+
+        this.state = {pickerEnabled: false, color: {
+            r: this.props.value.r * 255,
+            g: this.props.value.g * 255,
+            b: this.props.value.b * 255,
+            a: this.props.value instanceof Color4 ? this.props.value.a * 100 : 100,
+        }, hex: this.props.value.toHexString()};
+        
+        this._floatRef = React.createRef();
+        this._floatHostRef = React.createRef();
+    }
+
+    syncPositions() {
+        const div = this._floatRef.current as HTMLDivElement;
+        const host = this._floatHostRef.current as HTMLDivElement;
+
+        if (!div || !host) {
+            return;
+        }
+
+        let top = host.getBoundingClientRect().top;
+        let height = div.getBoundingClientRect().height;
+
+        if (top + height + 10 > window.innerHeight) {
+            top = window.innerHeight - height - 10;
+        }
+
+        div.style.top = top + "px";
+        div.style.left = "10px";
+    }
+
+    shouldComponentUpdate(nextProps: IColorPickerComponentProps, nextState: IColorPickerComponentState) {
+        return nextProps.value.toHexString() !== this.props.value.toHexString() 
+            || nextProps.disableAlpha !== this.props.disableAlpha 
+            || nextState.hex !== this.state.hex
+            || nextState.pickerEnabled !== this.state.pickerEnabled;
+    }
+
+    componentDidUpdate() {
+        this.syncPositions();
+    }
+
+    componentDidMount() {
+        this.syncPositions();
+    }
+
+    render() {
+        var color = this.state.color;
+
+        return (
+            <div className="color-picker">
+                <div className="color-rect"  ref={this._floatHostRef} 
+                    style={{background: this.state.hex}} 
+                    onClick={() => this.setState({pickerEnabled: true})}>
+
+                </div>
+                {
+                    this.state.pickerEnabled &&
+                    <>
+                        <div className="color-picker-cover" onClick={() => this.setState({pickerEnabled: false})}></div>
+                        <div className="color-picker-float" ref={this._floatRef}>
+                            <SketchPicker color={color} 
+                                disableAlpha={this.props.disableAlpha}
+                                onChange={(color) => {
+                                    let hex: string;
+
+                                    if (this.props.disableAlpha) {
+                                        let newColor3 = Color3.FromInts(color.rgb.r, color.rgb.g, color.rgb.b);
+                                        hex = newColor3.toHexString();    
+                                    } else {
+                                        let newColor4 = Color4.FromInts(color.rgb.r, color.rgb.g, color.rgb.b, 255 * (color.rgb.a || 0));
+                                        hex = newColor4.toHexString();   
+                                    }
+                                    this.setState({hex: hex, color: color.rgb});
+                                    this.props.onColorChanged(hex);
+                                }}
+                            />
+                        </div>
+                    </>
+                }                
+            </div>
+        );
+    }
+}

+ 13 - 17
inspector/src/components/actionTabs/tabs/propertyGrids/particleSystems/colorGradientStepGridComponent.tsx

@@ -7,6 +7,7 @@ import { LockObject } from '../lockObject';
 import { Color3, Color4 } from 'babylonjs/Maths/math.color';
 import { Color3, Color4 } from 'babylonjs/Maths/math.color';
 import { IParticleSystem } from 'babylonjs/Particles/IParticleSystem';
 import { IParticleSystem } from 'babylonjs/Particles/IParticleSystem';
 import { ParticleSystem } from 'babylonjs/Particles/particleSystem';
 import { ParticleSystem } from 'babylonjs/Particles/particleSystem';
+import { ColorPickerLineComponent } from '../../../lines/colorPickerComponent';
 
 
 interface IColorGradientStepGridComponent {
 interface IColorGradientStepGridComponent {
     globalState: GlobalState;
     globalState: GlobalState;
@@ -31,11 +32,11 @@ export class ColorGradientStepGridComponent extends React.Component<IColorGradie
 
 
     updateColor1(color: string) {
     updateColor1(color: string) {
         if (this.props.gradient instanceof ColorGradient) {
         if (this.props.gradient instanceof ColorGradient) {
-            this.props.gradient.color1 = Color4.FromColor3(Color3.FromHexString(color));
+            this.props.gradient.color1 = Color4.FromHexString(color);
             
             
             this.props.globalState.onCodeChangedObservable.notifyObservers({
             this.props.globalState.onCodeChangedObservable.notifyObservers({
                 object: this.props.host,
                 object: this.props.host,
-                code: `TARGET.${this.props.codeRecorderPropertyName}.color1 = BABYLON.Color4.FromColor3(BABYLON.Color3.FromHexString(${color}));`
+                code: `TARGET.${this.props.codeRecorderPropertyName}.color1 = BABYLON.Color4.FromHexString(${color});`
             });              
             });              
         } else {
         } else {
             this.props.gradient.color = Color3.FromHexString(color);
             this.props.gradient.color = Color3.FromHexString(color);
@@ -52,11 +53,11 @@ export class ColorGradientStepGridComponent extends React.Component<IColorGradie
 
 
     updateColor2(color: string) {
     updateColor2(color: string) {
         if (this.props.gradient instanceof ColorGradient) {
         if (this.props.gradient instanceof ColorGradient) {
-            this.props.gradient.color2 = Color4.FromColor3(Color3.FromHexString(color));
+            this.props.gradient.color2 = Color4.FromHexString(color);
 
 
             this.props.globalState.onCodeChangedObservable.notifyObservers({
             this.props.globalState.onCodeChangedObservable.notifyObservers({
                 object: this.props.host,
                 object: this.props.host,
-                code: `TARGET.${this.props.codeRecorderPropertyName}.color2 = BABYLON.Color4.FromColor3(BABYLON.Color3.FromHexString(${color}));`
+                code: `TARGET.${this.props.codeRecorderPropertyName}.color2 = BABYLON.Color4.FromHexString(${color});`
             });              
             });              
         }
         }
 
 
@@ -101,22 +102,17 @@ export class ColorGradientStepGridComponent extends React.Component<IColorGradie
                 <div className="step">
                 <div className="step">
                     {`#${this.props.lineIndex}`}
                     {`#${this.props.lineIndex}`}
                 </div>
                 </div>
-                {
-                    gradient instanceof ColorGradient &&
-                   <div className="color1">
-                        <input type="color" value={gradient.color1.toHexString(true)} onChange={(evt) => this.updateColor1(evt.target.value)} />
-                    </div>
-                }
-                {
-                    gradient instanceof Color3Gradient &&
-                   <div className="color1">
-                        <input type="color" value={gradient.color.toHexString()} onChange={(evt) => this.updateColor1(evt.target.value)} />
-                    </div>
-                }
+                <div className="color1">
+                    <ColorPickerLineComponent value={gradient instanceof Color3Gradient ? gradient.color : gradient.color1} onColorChanged={color => {
+                        this.updateColor1(color);
+                    }} disableAlpha={gradient instanceof Color3Gradient}/>
+                </div>
                 {
                 {
                     this.props.host instanceof ParticleSystem && gradient instanceof ColorGradient &&
                     this.props.host instanceof ParticleSystem && gradient instanceof ColorGradient &&
                     <div className="color2">
                     <div className="color2">
-                        <input type="color" value={gradient.color2 ? gradient.color2.toHexString(true) : "#000000"} onChange={(evt) => this.updateColor2(evt.target.value)} />
+                       <ColorPickerLineComponent value={gradient.color2 ? gradient.color2 : new Color4()} onColorChanged={color => {
+                            this.updateColor2(color);
+                       }}/>                        
                     </div>
                     </div>
                 }
                 }
                 <div className="step-value">
                 <div className="step-value">

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

@@ -324,7 +324,7 @@ export class ParticleSystemPropertyGridComponent extends React.Component<IPartic
                     <ButtonLineComponent label="Load from snippet server" onClick={() => this.loadFromSnippet()} />
                     <ButtonLineComponent label="Load from snippet server" onClick={() => this.loadFromSnippet()} />
                     <ButtonLineComponent label="Save to snippet server" onClick={() => this.saveToSnippet()} />
                     <ButtonLineComponent label="Save to snippet server" onClick={() => this.saveToSnippet()} />
                 </LineContainerComponent>                
                 </LineContainerComponent>                
-                <LineContainerComponent globalState={this.props.globalState} title="EMITTER">
+                <LineContainerComponent globalState={this.props.globalState} title="EMITTER" closed={true}>
                 <OptionsLineComponent 
                 <OptionsLineComponent 
                         label="Emitter" 
                         label="Emitter" 
                         options={emitterOptions} 
                         options={emitterOptions} 
@@ -438,7 +438,7 @@ export class ParticleSystemPropertyGridComponent extends React.Component<IPartic
                         this.renderEmitter()
                         this.renderEmitter()
                     }
                     }
                 </LineContainerComponent>       
                 </LineContainerComponent>       
-                <LineContainerComponent globalState={this.props.globalState} title="EMISSION">
+                <LineContainerComponent globalState={this.props.globalState} title="EMISSION" closed={true}>
                     <FloatLineComponent lockObject={this.props.lockObject} label="Rate" target={system} propertyName="emitRate" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Rate" target={system} propertyName="emitRate" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     {
                     {
                         system instanceof ParticleSystem && 
                         system instanceof ParticleSystem && 
@@ -502,7 +502,7 @@ export class ParticleSystemPropertyGridComponent extends React.Component<IPartic
                         mode={GradientGridMode.Factor}                        
                         mode={GradientGridMode.Factor}                        
                         lockObject={this.props.lockObject}/>
                         lockObject={this.props.lockObject}/>
                 </LineContainerComponent>                  
                 </LineContainerComponent>                  
-                <LineContainerComponent globalState={this.props.globalState} title="SIZE">
+                <LineContainerComponent globalState={this.props.globalState} title="SIZE" closed={true}>
                     {
                     {
                         (!system.getSizeGradients() || system.getSizeGradients()?.length === 0)&& 
                         (!system.getSizeGradients() || system.getSizeGradients()?.length === 0)&& 
                         <>
                         <>
@@ -546,7 +546,7 @@ export class ParticleSystemPropertyGridComponent extends React.Component<IPartic
                         mode={GradientGridMode.Factor}                        
                         mode={GradientGridMode.Factor}                        
                         lockObject={this.props.lockObject}/>
                         lockObject={this.props.lockObject}/>
                 </LineContainerComponent>          
                 </LineContainerComponent>          
-                <LineContainerComponent globalState={this.props.globalState} title="LIFETIME">
+                <LineContainerComponent globalState={this.props.globalState} title="LIFETIME" closed={true}>
                     <FloatLineComponent lockObject={this.props.lockObject} label="Min lifetime" target={system} propertyName="minLifeTime" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <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} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Max lifetime" target={system} propertyName="maxLifeTime" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Target stop duration" target={system} propertyName="targetStopDuration" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Target stop duration" target={system} propertyName="targetStopDuration" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
@@ -568,7 +568,7 @@ export class ParticleSystemPropertyGridComponent extends React.Component<IPartic
                             lockObject={this.props.lockObject}/>
                             lockObject={this.props.lockObject}/>
                     }                    
                     }                    
                 </LineContainerComponent>    
                 </LineContainerComponent>    
-                <LineContainerComponent globalState={this.props.globalState} title="COLORS">
+                <LineContainerComponent globalState={this.props.globalState} title="COLORS" closed={true}>
                     {
                     {
                         (!system.getColorGradients() || system.getColorGradients()?.length === 0) &&
                         (!system.getColorGradients() || system.getColorGradients()?.length === 0) &&
                         <>
                         <>
@@ -654,7 +654,7 @@ export class ParticleSystemPropertyGridComponent extends React.Component<IPartic
                         </>
                         </>
                     }                                   
                     }                                   
                 </LineContainerComponent>                     
                 </LineContainerComponent>                     
-                <LineContainerComponent globalState={this.props.globalState} title="ROTATION">
+                <LineContainerComponent globalState={this.props.globalState} title="ROTATION" closed={true}>
                     <FloatLineComponent lockObject={this.props.lockObject} label="Min angular speed" target={system} propertyName="minAngularSpeed" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <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="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="Min initial rotation" target={system} propertyName="minInitialRotation" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 3 - 1
package.json

@@ -105,6 +105,8 @@
         "webpack-dev-server": "^3.1.14",
         "webpack-dev-server": "^3.1.14",
         "webpack-stream": "5.0.0",
         "webpack-stream": "5.0.0",
         "xhr2": "^0.1.4",
         "xhr2": "^0.1.4",
-        "xmlbuilder": "8.2.2"
+        "xmlbuilder": "8.2.2",
+        "react-color": "^2.18.0",        
+        "@types/react-color": "^3.0.1"
     }
     }
 }
 }

+ 1 - 1
src/Particles/particle.ts

@@ -300,7 +300,7 @@ export class Particle {
             other._initialEndSpriteCellID = this._initialEndSpriteCellID;
             other._initialEndSpriteCellID = this._initialEndSpriteCellID;
         }
         }
         if (this.particleSystem.useRampGradients) {
         if (this.particleSystem.useRampGradients) {
-            if (other.remapData) {
+            if (other.remapData && this.remapData) {
                 other.remapData.copyFrom(this.remapData);
                 other.remapData.copyFrom(this.remapData);
             } else {
             } else {
                 other.remapData = new Vector4(0, 0, 0, 0);
                 other.remapData = new Vector4(0, 0, 0, 0);

+ 38 - 2
src/Particles/particleHelper.ts

@@ -115,14 +115,50 @@ export class ParticleHelper {
 
 
         return set;
         return set;
     }
     }
+    
+    /**
+     * Creates a particle system from a snippet saved in a remote file
+     * @param name defines the name of the  particle system to create
+     * @param url defines the url to load from
+     * @param scene defines the hosting scene
+     * @param gpu If the system will use gpu
+     * @param rootUrl defines the root URL to use to load textures and relative dependencies
+     * @returns a promise that will resolve to the new  particle system
+     */
+    public static ParseFromFileAsync(name: string, url: string, scene: Scene, gpu: boolean = false, rootUrl: string = ""): Promise<IParticleSystem> {
+
+        return new Promise((resolve, reject) => {
+            var request = new WebRequest();
+            request.addEventListener("readystatechange", () => {
+                if (request.readyState == 4) {
+                    if (request.status == 200) {
+                        let serializationObject = JSON.parse(request.responseText);
+                        let output: IParticleSystem;
+
+                        if (gpu) {
+                            output = GPUParticleSystem.Parse(serializationObject, scene, rootUrl);
+                        } else {
+                            output = ParticleSystem.Parse(serializationObject, scene, rootUrl);
+                        }
+                        resolve(output);
+                    } else {
+                        reject("Unable to load the particle system");
+                    }
+                }
+            });
+
+            request.open("GET", url);
+            request.send();            
+        });
+    }
 
 
     /**
     /**
-     * Creates a node material from a snippet saved by the node material editor
+     * Creates a particle system from a snippet saved by the particle system editor
      * @param snippetId defines the snippet to load
      * @param snippetId defines the snippet to load
      * @param scene defines the hosting scene
      * @param scene defines the hosting scene
      * @param gpu If the system will use gpu
      * @param gpu If the system will use gpu
      * @param rootUrl defines the root URL to use to load textures and relative dependencies
      * @param rootUrl defines the root URL to use to load textures and relative dependencies
-     * @returns a promise that will resolve to the new node material
+     * @returns a promise that will resolve to the new particle system
      */
      */
     public static CreateFromSnippetAsync(snippetId: string, scene: Scene, gpu: boolean = false, rootUrl: string = ""): Promise<IParticleSystem> {
     public static CreateFromSnippetAsync(snippetId: string, scene: Scene, gpu: boolean = false, rootUrl: string = ""): Promise<IParticleSystem> {
         return new Promise((resolve, reject) => {
         return new Promise((resolve, reject) => {