Browse Source

Merge pull request #8515 from toledoal/stop-animation

Stop animation and other bugs
sebavan 5 years ago
parent
commit
1a7e0d3bac

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

@@ -9,7 +9,7 @@
 - Reflection probes can now be used to give accurate shading with PBR ([CraigFeldpsar](https://github.com/craigfeldspar) and ([Sebavan](https://github.com/sebavan/)))
 - Added SubSurfaceScattering on PBR materials ([CraigFeldpsar](https://github.com/craigfeldspar) and ([Sebavan](https://github.com/sebavan/)))
 - Added editing of PBR materials, Post processes and Particle fragment shaders in the node material editor ([Popov72](https://github.com/Popov72))
-- Added Curve editor to manage entity's animations and edit animation groups in Inspector ([pixelspace](https://github.com/devpixelspace))
+- Added Curve editor to manage selected entity's animations and edit animation groups in Inspector ([pixelspace](https://github.com/devpixelspace))
 - Added support in `ShadowGenerator` for fast fake soft transparent shadows ([Popov72](https://github.com/Popov72))
 - Added support for **thin instances** for faster mesh instances. [Doc](https://doc.babylonjs.com/how_to/how_to_use_thininstances) ([Popov72](https://github.com/Popov72))
 

+ 2 - 3
inspector/src/components/actionTabs/tabs/propertyGrids/animations/addAnimation.tsx

@@ -376,15 +376,14 @@ export class AddAnimation extends React.Component<
                 onChange={(e) => this.handleTypeChange(e)}
                 value={this.state.animationType}
               >
+                <option value={Animation.ANIMATIONTYPE_COLOR3}>Color3</option>
+                <option value={Animation.ANIMATIONTYPE_COLOR4}>Color4</option>
                 <option value={Animation.ANIMATIONTYPE_FLOAT}>Float</option>
                 <option value={Animation.ANIMATIONTYPE_VECTOR3}>Vector3</option>
                 <option value={Animation.ANIMATIONTYPE_VECTOR2}>Vector2</option>
                 <option value={Animation.ANIMATIONTYPE_QUATERNION}>
                   Quaternion
                 </option>
-                <option value={Animation.ANIMATIONTYPE_COLOR3}>Color3</option>
-                <option value={Animation.ANIMATIONTYPE_COLOR4}>Color4</option>
-                <option value={Animation.ANIMATIONTYPE_SIZE}>Size</option>
               </select>
             </div>
           )}

+ 56 - 30
inspector/src/components/actionTabs/tabs/propertyGrids/animations/animationCurveEditorComponent.tsx

@@ -37,6 +37,11 @@ interface ICanvasAxis {
   label: number;
 }
 
+export interface IActionableKeyFrame {
+  frame: number;
+  value: any;
+}
+
 interface ICurveData {
   pathData: string;
   pathLength: number;
@@ -73,6 +78,7 @@ export class AnimationCurveEditorComponent extends React.Component<
     panningY: number;
     panningX: number;
     repositionCanvas: boolean;
+    actionableKeyframe: IActionableKeyFrame;
   }
 > {
   private _snippetUrl = 'https://snippet.babylonjs.com';
@@ -177,6 +183,7 @@ export class AnimationCurveEditorComponent extends React.Component<
       panningY: 0,
       panningX: 0,
       repositionCanvas: false,
+      actionableKeyframe: { frame: 0, value: 0 },
     };
   }
 
@@ -603,8 +610,26 @@ export class AnimationCurveEditorComponent extends React.Component<
         notification: 'Frame input only accepts integer values',
       });
     } else {
-      frame = parseInt(event.target.value);
-      this.changeCurrentFrame(frame);
+      if (this.state.selected !== null) {
+        let animation = this.state.selected;
+        let keys = animation.getKeys();
+        frame = parseInt(event.target.value);
+
+        let isKeyframe = keys.find((k) => k.frame === frame);
+
+        let value = this.state.actionableKeyframe.value;
+
+        if (isKeyframe) {
+          value = isKeyframe.value;
+        }
+
+        this.setState({
+          actionableKeyframe: {
+            frame: frame,
+            value: value,
+          },
+        });
+      }
     }
   }
 
@@ -617,19 +642,24 @@ export class AnimationCurveEditorComponent extends React.Component<
       });
     } else {
       this.setState(
-        { currentValue: parseFloat(parseFloat(event.target.value).toFixed(3)) },
+        {
+          actionableKeyframe: {
+            frame: this.state.actionableKeyframe.frame,
+            value: parseFloat(parseFloat(event.target.value).toFixed(3)),
+          },
+        },
         () => {
           if (this.state.selected !== null) {
             let animation = this.state.selected;
             let keys = animation.getKeys();
 
             let isKeyframe = keys.find(
-              (k) => k.frame === this.state.currentFrame
+              (k) => k.frame === this.state.actionableKeyframe.frame
             );
             if (isKeyframe) {
               let updatedKeys = keys.map((k) => {
-                if (k.frame === this.state.currentFrame) {
-                  k.value = this.state.currentValue;
+                if (k.frame === this.state.actionableKeyframe.frame) {
+                  k.value = this.state.actionableKeyframe.value;
                 }
                 return k;
               });
@@ -685,8 +715,8 @@ export class AnimationCurveEditorComponent extends React.Component<
 
       if (currentAnimation.dataType === Animation.ANIMATIONTYPE_FLOAT) {
         let keys = currentAnimation.getKeys();
-        let x = this.state.currentFrame;
-        let y = this.state.currentValue;
+        let x = this.state.actionableKeyframe.frame;
+        let y = this.state.actionableKeyframe.value;
 
         keys.push({ frame: x, value: y, inTangent: 0, outTangent: 0 });
         keys.sort((a, b) => a.frame - b.frame);
@@ -1075,18 +1105,6 @@ export class AnimationCurveEditorComponent extends React.Component<
 
       let y = this._heightScale - keyframe_valueAsArray * middle;
 
-      let nextKeyframe = keyframes[i + 1];
-      let prevKeyframe = keyframes[i - 1];
-      if (nextKeyframe !== undefined) {
-        let distance = keyframes[i + 1].frame - key.frame;
-        defaultWeight = distance * 1; // Adjust for scaled
-      }
-
-      if (prevKeyframe !== undefined) {
-        let distance = key.frame - keyframes[i - 1].frame;
-        defaultWeight = distance * 1; // Adjust for scaled
-      }
-
       if (inT !== null) {
         let valueIn = y * inT + y;
         inTangent = new Vector2(
@@ -1397,6 +1415,16 @@ export class AnimationCurveEditorComponent extends React.Component<
     }
   }
 
+  setIsLooping() {
+    this.setState({ isLooping: !this.state.isLooping, isPlaying: false }, () =>
+      this.stopAnimation()
+    );
+  }
+
+  setFramesPerSecond(fps: number) {
+    this.setState({ fps: fps, isPlaying: false }, () => this.stopAnimation());
+  }
+
   analizeAnimationForLerp(animation: Animation | null) {
     if (animation !== null) {
       const { easingMode, easingType, usesTangents } = this.getAnimationData(
@@ -1422,6 +1450,7 @@ export class AnimationCurveEditorComponent extends React.Component<
    */
   changeCurrentFrame(frame: number) {
     let currentValue;
+    this.stopAnimation();
     if (this.state.selectedPathData) {
       let selectedCurve = this.state.selectedPathData[
         this.state.selectedCoordinate
@@ -1443,8 +1472,9 @@ export class AnimationCurveEditorComponent extends React.Component<
 
         this.setState({
           currentFrame: frame,
-          currentValue: currentValue,
+          currentValue: parseFloat(currentValue.toFixed(3)),
           currentPoint: currentP,
+          isPlaying: false,
         });
       }
     }
@@ -1524,6 +1554,7 @@ export class AnimationCurveEditorComponent extends React.Component<
   }
 
   moveFrameTo(e: React.MouseEvent<SVGRectElement, MouseEvent>) {
+    this.stopAnimation();
     var svg = e.currentTarget as SVGRectElement;
     var CTM = svg.getScreenCTM();
     let position;
@@ -1533,7 +1564,7 @@ export class AnimationCurveEditorComponent extends React.Component<
         (e.clientY - CTM.f) / CTM.d
       );
       let selectedFrame = Math.round(position.x / this._pixelFrameUnit);
-      this.setState({ currentFrame: selectedFrame });
+      this.setState({ currentFrame: selectedFrame, isPlaying: false });
     }
   }
 
@@ -1579,8 +1610,7 @@ export class AnimationCurveEditorComponent extends React.Component<
           }
           title={this._entityName}
           close={this.props.close}
-          currentValue={this.state.currentValue}
-          currentFrame={this.state.currentFrame}
+          actionableKeyframe={this.state.actionableKeyframe}
           handleFrameChange={(e) => this.handleFrameChange(e)}
           handleValueChange={(e) => this.handleValueChange(e)}
           addKeyframe={() => this.addKeyframeClick()}
@@ -1610,12 +1640,8 @@ export class AnimationCurveEditorComponent extends React.Component<
               globalState={this.props.globalState}
               snippetServer={this._snippetUrl}
               fps={this.state.fps}
-              setFps={(fps: number) => {
-                this.setState({ fps: fps });
-              }}
-              setIsLooping={() => {
-                this.setState({ isLooping: !this.state.isLooping });
-              }}
+              setFps={(fps: number) => this.setFramesPerSecond(fps)}
+              setIsLooping={() => this.setIsLooping()}
             />
 
             <div

+ 0 - 12
inspector/src/components/actionTabs/tabs/propertyGrids/animations/curveEditor.scss

@@ -497,18 +497,6 @@
           outline: solid 1px #ccc;
         }
       }
-      &.frame-input {
-        input::-webkit-outer-spin-button,
-        input::-webkit-inner-spin-button {
-          -webkit-appearance: none;
-          margin: 0;
-        }
-
-        /* Firefox */
-        input[type='number'] {
-          -moz-appearance: textfield;
-        }
-      }
     }
   }
 

+ 6 - 6
inspector/src/components/actionTabs/tabs/propertyGrids/animations/graphActionsBar.tsx

@@ -1,5 +1,6 @@
 import * as React from 'react';
 import { IconButtonLineComponent } from '../../../lines/iconButtonLineComponent';
+import { IActionableKeyFrame } from './animationCurveEditorComponent';
 
 interface IGraphActionsBarProps {
   addKeyframe: () => void;
@@ -11,8 +12,7 @@ interface IGraphActionsBarProps {
   setLerpMode: () => void;
   brokenMode: boolean;
   lerpMode: boolean;
-  currentValue: number;
-  currentFrame: number;
+  actionableKeyframe: IActionableKeyFrame;
   title: string;
   close: (event: any) => void;
   enabled: boolean;
@@ -37,17 +37,17 @@ export class GraphActionsBar extends React.Component<IGraphActionsBarProps> {
           <div className='action-input frame-input'>
             <input
               type='number'
-              readOnly
-              value={this.props.currentFrame}
+              onChange={this.props.handleFrameChange}
+              value={this.props.actionableKeyframe.frame}
               step='1'
             />
           </div>
           <div className='action-input'>
             <input
               type='number'
-              value={this.props.currentValue}
+              value={this.props.actionableKeyframe.value}
               onChange={this.props.handleValueChange}
-              step='0.1'
+              step='0.01'
             />
           </div>
           <IconButtonLineComponent