Преглед изворни кода

SUpport for particle size gradients in inspector

David Catuhe пре 5 година
родитељ
комит
dd900c6cc2

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

@@ -264,6 +264,76 @@ $line-padding-left: 2px;
                     }
                 }
 
+                .gradient-container {
+                    margin-top: 3px;
+
+                    .gradient-label {
+                        height: 30px;
+                        display: grid;
+                        align-content: center;
+                    }
+
+                    .gradient-step {
+                        display: grid;
+                        grid-template-rows: 100%;
+                        grid-template-columns: 30px 50px 55px 40px auto 20px 5px;
+                        padding-top: 5px;
+                        padding-left: 5px;
+                        padding-bottom: 5px;
+                
+                        .step {
+                            grid-row: 1;
+                            grid-column: 1;
+                        }
+                            
+                        .factor1 {
+                            grid-row: 1;
+                            grid-column: 2;
+                            cursor: pointer;
+                        }
+
+                        .factor2 {
+                            padding-left: 5px;
+                            grid-row: 1;
+                            grid-column: 3;
+                            cursor: pointer;
+                        }
+
+                        .numeric-input {
+                            width: calc(100% - 5px);
+                        }
+                
+                        .step-value {       
+                            margin-left: 5px;     
+                            grid-row: 1;
+                            grid-column: 4;
+                            text-align: right;
+                            margin-right: 5px;
+                        }
+                
+                        .step-slider {            
+                            grid-row: 1;
+                            grid-column: 5;
+                            display: grid;
+                            justify-content: stretch;
+                            align-content: center;
+                            margin-right: 5px;
+                
+                            input {
+                                width: 100%;
+                            }
+                        }
+                
+                        .gradient-delete {            
+                            grid-row: 1;
+                            grid-column: 6;
+                            display: grid;
+                            align-content: center;
+                            justify-content: center;
+                        }
+                    }
+                }
+
                 .textInputLine {
                     padding-left: $line-padding-left;
                     height: 30px;

+ 101 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/particleSystems/factorGradientGridComponent.tsx

@@ -0,0 +1,101 @@
+import * as React from "react";
+import { Observable } from 'babylonjs/Misc/observable';
+import { PropertyChangedEvent } from '../../../../propertyChangedEvent';
+import { GlobalState } from '../../../../globalState';
+import { FactorGradient } from 'babylonjs/Misc/gradients';
+import { LockObject } from '../lockObject';
+import { ButtonLineComponent } from '../../../lines/buttonLineComponent';
+import { FactorGradientStepGridComponent } from './factorGradientStepGridComponent';
+import { Nullable } from 'babylonjs/types';
+
+interface IFactorGradientGridComponent {
+    globalState: GlobalState;
+    label: string;
+    gradients: Nullable<Array<FactorGradient>>,
+    lockObject: LockObject,
+    replaySourceReplacement?: string,
+    onCreateRequired: () => void,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class FactorGradientGridComponent extends React.Component<IFactorGradientGridComponent> {
+
+    constructor(props: IFactorGradientGridComponent) {
+        super(props)
+    }
+
+    deleteStep(step: FactorGradient) {
+        let gradients = this.props.gradients as Array<FactorGradient>;
+
+        let index = gradients.indexOf(step);
+
+        if (index > -1) {
+            gradients.splice(index, 1);
+            this.forceUpdate();
+        }
+    }
+
+    addNewStep() {
+        let gradients = this.props.gradients as Array<FactorGradient>;
+
+        let newStep = new FactorGradient();
+        newStep.gradient = 1.0;
+        newStep.factor1 = 0.0;
+        newStep.factor2 = 1.0;
+
+        gradients.push(newStep);
+
+        this.forceUpdate();
+    }
+
+    checkForReOrder() {
+        let gradients = this.props.gradients as Array<FactorGradient>;
+        gradients.sort((a, b) => {
+            if (a.gradient === b.gradient) {
+                return 0;
+            }
+
+            if (a.gradient > b.gradient) {
+                return 1;
+            }
+
+            return -1;
+        });
+
+        this.forceUpdate();
+    }
+
+    render() {
+        let gradients = this.props.gradients as Nullable<Array<FactorGradient>>;
+      
+        return (
+            <div>
+                {
+                    gradients &&
+                    <div className="gradient-container">
+                        <div className="gradient-label">{this.props.label}</div>
+                        <ButtonLineComponent label="Add new step" onClick={() => this.addNewStep()} />
+                        {
+                            gradients.map((g, i) => {
+                                return (
+                                    <FactorGradientStepGridComponent globalState={this.props.globalState} 
+                                    lockObject={this.props.lockObject}
+                                    onCheckForReOrder={() => this.checkForReOrder()}
+                                    onUpdateGradient={() => this.forceUpdate()}
+                                    key={"step-" + i} lineIndex={i} gradient={g} onDelete={() => this.deleteStep(g)}/>
+                                )
+                            })
+                        }
+                    </div>
+                }
+                {
+                    !gradients &&                    
+                    <ButtonLineComponent label={"Use " + this.props.label} onClick={() => {
+                        this.props.onCreateRequired();
+                        this.forceUpdate();
+                    }} />
+                }
+            </div>
+        );
+    }
+}

+ 94 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/particleSystems/factorGradientStepGridComponent.tsx

@@ -0,0 +1,94 @@
+import * as React from 'react';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faTrash } from '@fortawesome/free-solid-svg-icons';
+import { GlobalState } from '../../../../globalState';
+import { FactorGradient } from 'babylonjs/Misc/gradients';
+import { LockObject } from '../lockObject';
+
+interface IFactorGradientStepGridComponent {
+    globalState: GlobalState;
+    gradient: FactorGradient;
+    lockObject: LockObject;
+    lineIndex: number;
+    onDelete: () => void;
+    onUpdateGradient: () => void;
+    onCheckForReOrder: () => void;
+}
+
+export class FactorGradientStepGridComponent extends React.Component<IFactorGradientStepGridComponent, {gradient: number}> {
+
+    constructor(props: IFactorGradientStepGridComponent) {
+        super(props);
+
+        this.state={gradient: props.gradient.gradient};
+    }
+
+    updateFactor1(factor: number) {
+        this.props.gradient.factor1 = factor;
+
+        this.props.onUpdateGradient();
+        this.forceUpdate();
+    }    
+
+    updateFactor2(factor: number) {
+        this.props.gradient.factor2 = factor;
+
+        this.props.onUpdateGradient();
+        this.forceUpdate();
+    }   
+    
+    updateGradient(gradient: number) {
+        this.props.gradient.gradient = gradient;
+
+        this.setState({gradient: gradient});
+
+        this.props.onUpdateGradient();
+    }
+
+    onPointerUp() {
+        this.props.onCheckForReOrder();
+    }
+
+    lock() {
+        if (this.props.lockObject) {
+            this.props.lockObject.lock = true;
+        }
+    }
+
+    unlock() {
+        if (this.props.lockObject) {
+            this.props.lockObject.lock = false;
+        }
+    }
+
+    render() {
+        let gradient = this.props.gradient;
+
+        return (
+            <div className="gradient-step">
+                <div className="step">
+                    {`#${this.props.lineIndex}`}
+                </div>
+                <div className="factor1">
+                    <input type="number" step={"0.01"} className="numeric-input" value={gradient.factor1} onBlur={() => this.unlock()} onFocus={() => this.lock()}
+                        onChange={evt => this.updateFactor1(parseFloat(evt.target.value))} />
+                </div>
+                <div className="factor2">
+                    <input type="number" step={"0.01"} className="numeric-input" value={gradient.factor2} onBlur={() => this.unlock()} onFocus={() => this.lock()} 
+                        onChange={evt => this.updateFactor2(parseFloat(evt.target.value))} />
+                </div>
+                <div className="step-value">
+                    {gradient.gradient.toFixed(2)}
+                </div>
+                <div className="step-slider">
+                    <input className="range" type="range" step={0.01} min={0} max={1.0} value={gradient.gradient}
+                        onPointerUp={evt => this.onPointerUp()}
+                        onChange={evt => this.updateGradient(parseFloat(evt.target.value))} />
+                </div>
+                <div className="gradient-delete" onClick={() => this.props.onDelete()}>
+                    <FontAwesomeIcon icon={faTrash} />
+                </div>
+            </div>
+        )
+    }
+}

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

@@ -34,6 +34,7 @@ import { Vector3 } from 'babylonjs/Maths/math.vector';
 import { AbstractMesh } from 'babylonjs/Meshes/abstractMesh';
 import { MeshParticleEmitter } from 'babylonjs/Particles/EmitterTypes/meshParticleEmitter';
 import { MeshEmitterGridComponent } from './meshEmitterGridComponent';
+import { FactorGradientGridComponent } from './factorGradientGridComponent';
 
 interface IParticleSystemPropertyGridComponentProps {
     globalState: GlobalState;
@@ -293,6 +294,12 @@ export class ParticleSystemPropertyGridComponent extends React.Component<IPartic
                     <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} />
+                    <FactorGradientGridComponent globalState={this.props.globalState} gradients={system.getSizeGradients()!} 
+                        label="Size gradients"
+                        onCreateRequired={() => {
+                            system.addSizeGradient(0, 0, 1);
+                        }}
+                        lockObject={this.props.lockObject} 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} />