Quellcode durchsuchen

Associated with #6012 (back face rendering)

David Catuhe vor 6 Jahren
Ursprung
Commit
df5138e588

+ 20 - 4
nodeEditor/src/components/preview/previewAreaComponent.tsx

@@ -2,7 +2,7 @@
 import * as React from "react";
 import { GlobalState } from '../../globalState';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faPlay, faStop, faPalette } from '@fortawesome/free-solid-svg-icons';
+import { faPlay, faStop, faPalette, faCheckDouble } from '@fortawesome/free-solid-svg-icons';
 import { Color3, Color4 } from 'babylonjs/Maths/math.color';
 import { DataStorage } from '../../dataStorage';
 
@@ -30,6 +30,13 @@ export class PreviewAreaComponent extends React.Component<IPreviewAreaComponent>
         this.props.globalState.onPreviewBackgroundChanged.notifyObservers();
     }
 
+    changeBackFaceCulling(value: boolean) {        
+        this.props.globalState.backFaceCulling = value;
+        DataStorage.StoreBoolean("BackFaceCulling", value);
+        this.props.globalState.onBackFaceCullingChanged.notifyObservers();
+        this.forceUpdate();
+    }
+
     render() {
         return (
             <>
@@ -37,15 +44,24 @@ export class PreviewAreaComponent extends React.Component<IPreviewAreaComponent>
                     <canvas id="preview-canvas"/>
                 </div>                
                 <div id="preview-config-bar">
-                    <div onClick={() => this.changeAnimation()} className={"button"}>
+                    <div                     
+                        title="Turn-table animation"
+                        onClick={() => this.changeAnimation()} className={"button"}>
                         <FontAwesomeIcon icon={this.props.globalState.rotatePreview ? faStop : faPlay} />
                     </div>
-                    <div className={"button align"}>
+                    <div 
+                        title="Background color"
+                        className={"button align"}>
                         <label htmlFor="color-picker" id="color-picker-label">
                             <FontAwesomeIcon icon={faPalette} />
                         </label>
                         <input ref="color-picker" id="color-picker" type="color" onChange={evt => this.changeBackground(evt.target.value)} />
-                    </div>
+                    </div>                        
+                    <div
+                        title="Render without back face culling"
+                        onClick={() => this.changeBackFaceCulling(!this.props.globalState.backFaceCulling)} className={"button" + (!this.props.globalState.backFaceCulling ? " selected" : "")}>
+                        <FontAwesomeIcon icon={faCheckDouble} />
+                    </div>  
                 </div>
             </>
         );

+ 9 - 0
nodeEditor/src/components/preview/previewManager.ts

@@ -22,6 +22,7 @@ export class PreviewManager {
     private _onAnimationCommandActivatedObserver: Nullable<Observer<void>>;
     private _onUpdateRequiredObserver: Nullable<Observer<void>>;
     private _onPreviewBackgroundChangedObserver: Nullable<Observer<void>>;
+    private _onBackFaceCullingChangedObserver: Nullable<Observer<void>>;
     private _engine: Engine;
     private _scene: Scene;
     private _light: HemisphericLight;
@@ -57,6 +58,11 @@ export class PreviewManager {
             this._handleAnimations();
         });
 
+        this._onBackFaceCullingChangedObserver = globalState.onBackFaceCullingChanged.add(() => {
+            let serializationObject = this._nodeMaterial.serialize();
+            this._updatePreview(serializationObject);
+        });
+
         this._engine = new Engine(targetCanvas, true);
         this._scene = new Scene(this._engine);
         this._camera = new ArcRotateCamera("Camera", 0, 0.8, 4, Vector3.Zero(), this._scene);
@@ -190,6 +196,8 @@ export class PreviewManager {
         try {
             let tempMaterial = NodeMaterial.Parse(serializationObject, this._scene);
 
+            tempMaterial.backFaceCulling = this._globalState.backFaceCulling;
+
             if (this._meshes.length) {
                 let tasks = this._meshes.map(m => this._forceCompilationAsync(tempMaterial, m));
 
@@ -218,6 +226,7 @@ export class PreviewManager {
         this._globalState.onUpdateRequiredObservable.remove(this._onUpdateRequiredObserver);
         this._globalState.onAnimationCommandActivated.remove(this._onAnimationCommandActivatedObserver);
         this._globalState.onPreviewBackgroundChanged.remove(this._onPreviewBackgroundChangedObserver);
+        this._globalState.onBackFaceCullingChanged.remove(this._onBackFaceCullingChangedObserver);
 
         if (this._material) {
             this._material.dispose();

+ 19 - 7
nodeEditor/src/components/preview/previewMeshControlComponent.tsx

@@ -41,25 +41,37 @@ export class PreviewMeshControlComponent extends React.Component<IPreviewMeshCon
     render() {
         return (
             <div id="preview-mesh-bar">
-                <div onClick={() => this.changeMeshType(PreviewMeshType.Box)} className={"button" + (this.props.globalState.previewMeshType === PreviewMeshType.Box ? " selected" : "")}>
+                <div
+                    title="Preview with a cube" 
+                    onClick={() => this.changeMeshType(PreviewMeshType.Box)} className={"button" + (this.props.globalState.previewMeshType === PreviewMeshType.Box ? " selected" : "")}>
                     <FontAwesomeIcon icon={faCube} />
                 </div>
-                <div onClick={() => this.changeMeshType(PreviewMeshType.Sphere)} className={"button" + (this.props.globalState.previewMeshType === PreviewMeshType.Sphere ? " selected" : "")}>
+                <div
+                    title="Preview with a sphere"  
+                    onClick={() => this.changeMeshType(PreviewMeshType.Sphere)} className={"button" + (this.props.globalState.previewMeshType === PreviewMeshType.Sphere ? " selected" : "")}>
                     <FontAwesomeIcon icon={faCircle} />
                 </div>
-                <div onClick={() => this.changeMeshType(PreviewMeshType.Torus)} className={"button" + (this.props.globalState.previewMeshType === PreviewMeshType.Torus ? " selected" : "")}>
+                <div
+                    title="Preview with a torus"  
+                    onClick={() => this.changeMeshType(PreviewMeshType.Torus)} className={"button" + (this.props.globalState.previewMeshType === PreviewMeshType.Torus ? " selected" : "")}>
                     <FontAwesomeIcon icon={faRing} />
                 </div>
-                <div onClick={() => this.changeMeshType(PreviewMeshType.Cylinder)} className={"button" + (this.props.globalState.previewMeshType === PreviewMeshType.Cylinder ? " selected" : "")}>
+                <div
+                    title="Preview with a cylinder"  
+                    onClick={() => this.changeMeshType(PreviewMeshType.Cylinder)} className={"button" + (this.props.globalState.previewMeshType === PreviewMeshType.Cylinder ? " selected" : "")}>
                     <FontAwesomeIcon icon={faHockeyPuck} />
                 </div>
-                <div onClick={() => this.changeMeshType(PreviewMeshType.Plane)} className={"button" + (this.props.globalState.previewMeshType === PreviewMeshType.Plane ? " selected" : "")}>
+                <div
+                    title="Preview with a plane"  
+                    onClick={() => this.changeMeshType(PreviewMeshType.Plane)} className={"button" + (this.props.globalState.previewMeshType === PreviewMeshType.Plane ? " selected" : "")}>
                     <FontAwesomeIcon icon={faSquareFull} />
                 </div>      
-                <div onClick={() => this.changeMeshType(PreviewMeshType.ShaderBall)} className={"button" + (this.props.globalState.previewMeshType === PreviewMeshType.ShaderBall ? " selected" : "")}>
+                <div
+                    title="Preview with a shader ball"  
+                    onClick={() => this.changeMeshType(PreviewMeshType.ShaderBall)} className={"button" + (this.props.globalState.previewMeshType === PreviewMeshType.ShaderBall ? " selected" : "")}>
                     <FontAwesomeIcon icon={faDotCircle} />
                 </div>                           
-                <div className={"button align"}>
+                <div className={"button align"} title="Preview with a custom mesh" >
                     <label htmlFor="file-picker" id="file-picker-label">
                         <FontAwesomeIcon icon={faPlus} />
                     </label>

+ 3 - 0
nodeEditor/src/globalState.ts

@@ -24,18 +24,21 @@ export class GlobalState {
     onErrorMessageDialogRequiredObservable = new Observable<string>();
     onPreviewCommandActivated = new Observable<void>();
     onPreviewBackgroundChanged = new Observable<void>();
+    onBackFaceCullingChanged = new Observable<void>();
     onAnimationCommandActivated = new Observable<void>();
     onGetNodeFromBlock: (block: NodeMaterialBlock) => NodeModel;
     previewMeshType: PreviewMeshType;
     previewMeshFile: File;
     rotatePreview: boolean;
     backgroundColor: Color4;
+    backFaceCulling: boolean;
     blockKeyboardEvents = false;
     
     customSave?: {label: string, action: (data: string) => Promise<void>};
 
     public constructor() {
         this.previewMeshType = DataStorage.ReadNumber("PreviewMeshType", PreviewMeshType.Box);
+        this.backFaceCulling = DataStorage.ReadBoolean("BackFaceCulling", true);
 
         let r = DataStorage.ReadNumber("BackgroundColorR", 0.37);
         let g = DataStorage.ReadNumber("BackgroundColorG", 0.37);

+ 1 - 1
src/Materials/Node/Blocks/Input/inputBlock.ts

@@ -573,7 +573,7 @@ export class InputBlock extends NodeMaterialBlock {
             return finalOutput;
         }
         return "";
-    }    
+    }
 
     public serialize(): any {
         let serializationObject = super.serialize();