Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Blend shape animation #374

Merged
merged 33 commits into from
Jul 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
6b80151
feat: add API design
GuoLei1990 Jun 29, 2021
a113eab
refactor: improve bendshape design
GuoLei1990 Jun 29, 2021
db39ebd
refactor: opt code
GuoLei1990 Jul 5, 2021
9d9c1b6
refactor: opt code
GuoLei1990 Jul 6, 2021
12a3e95
refactor: opt code
GuoLei1990 Jul 6, 2021
cf8af65
refactor: opt code
GuoLei1990 Jul 6, 2021
e2d3012
refactor: opt code
GuoLei1990 Jul 6, 2021
4d1ec67
refactor: opt code
GuoLei1990 Jul 7, 2021
c8f4080
refactor: opt code
GuoLei1990 Jul 7, 2021
c182109
refactor: opt code
GuoLei1990 Jul 9, 2021
6d557c8
refactor: opt code
GuoLei1990 Jul 9, 2021
c53da2b
refactor: opt code
GuoLei1990 Jul 9, 2021
b5845e1
refactor: opt code
GuoLei1990 Jul 9, 2021
dadb453
refactor: opt code
GuoLei1990 Jul 12, 2021
b199eb3
refactor: opt code
GuoLei1990 Jul 12, 2021
beb6d10
refactor: opt code
GuoLei1990 Jul 12, 2021
255db35
refactor: opt code
GuoLei1990 Jul 13, 2021
233d8af
refactor: fix bug
GuoLei1990 Jul 13, 2021
f68cb9f
refactor: opt code
GuoLei1990 Jul 13, 2021
1e2fdce
refactor: opt code
GuoLei1990 Jul 13, 2021
780e009
refactor: opt code
GuoLei1990 Jul 13, 2021
35b4d26
refactor: opt code
GuoLei1990 Jul 13, 2021
c3bcb81
refactor: opt code
GuoLei1990 Jul 13, 2021
974e2fc
refactor: opt code
GuoLei1990 Jul 13, 2021
f47a8b3
refactor: opt code
GuoLei1990 Jul 13, 2021
6554e4e
refactor: opt code
GuoLei1990 Jul 14, 2021
3874947
refactor: opt code
GuoLei1990 Jul 14, 2021
925eefe
refactor: opt code
GuoLei1990 Jul 14, 2021
6bf99bc
refactor: opt code
GuoLei1990 Jul 14, 2021
06483cf
refactor: opt code
GuoLei1990 Jul 14, 2021
fde2cba
refactor: fix uint test
GuoLei1990 Jul 14, 2021
d3c62d9
refactor: opt code
GuoLei1990 Jul 15, 2021
969a701
Merge commit '714d891043a93cc64e24aae055d493c39ce38449' into blend-sh…
GuoLei1990 Jul 19, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions packages/core/src/Transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { MathUtil, Matrix, Matrix3x3, Quaternion, Vector3 } from "@oasis-engine/
import { deepClone, ignoreClone } from "./clone/CloneManager";
import { Component } from "./Component";
import { UpdateFlag } from "./UpdateFlag";
import { UpdateFlagManager } from "./UpdateFlagManager";

/**
* Used to implement transformation related functions.
Expand Down Expand Up @@ -38,7 +39,7 @@ export class Transform extends Component {
@deepClone
private _worldMatrix: Matrix = new Matrix();
@ignoreClone
private _changeFlags: UpdateFlag[] = [];
private _updateFlagManager: UpdateFlagManager = new UpdateFlagManager();
@ignoreClone
private _isParentDirty: boolean = true;
@ignoreClone
Expand Down Expand Up @@ -505,7 +506,7 @@ export class Transform extends Component {
* @returns Change flag
*/
registerWorldChangeFlag(): UpdateFlag {
return new UpdateFlag(this._changeFlags);
return this._updateFlagManager.register();
}

/**
Expand Down Expand Up @@ -660,10 +661,7 @@ export class Transform extends Component {

private _worldAssociatedChange(type: number): void {
this._dirtyFlag |= type;
const len = this._changeFlags.length;
for (let i = len - 1; i >= 0; i--) {
this._changeFlags[i].flag = true;
}
this._updateFlagManager.distribute();
}

private _rotateByQuat(rotateQuat: Quaternion, relativeToLocal: boolean) {
Expand Down
19 changes: 19 additions & 0 deletions packages/core/src/UpdateFlagManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { UpdateFlag } from "./UpdateFlag";

/**
* @internal
*/
export class UpdateFlagManager {
private _updateFlags: UpdateFlag[] = [];

register(): UpdateFlag {
return new UpdateFlag(this._updateFlags);
}

distribute(): void {
const updateFlags = this._updateFlags;
for (let i = updateFlags.length - 1; i >= 0; i--) {
updateFlags[i].flag = true;
}
}
}
4 changes: 4 additions & 0 deletions packages/core/src/animation/AnimationClip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ export class AnimationClip extends Motion {
case "scale":
property = AnimationProperty.Scale;
break;
case "blendShapeWeights":
property = AnimationProperty.BlendShapeWeights;
break;
default:
}
const curveData: AnimationClipCurveData<Component> = {
relativePath,
Expand Down
19 changes: 18 additions & 1 deletion packages/core/src/animation/AnimationCurve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Quaternion, Vector2, Vector3, Vector4 } from "@oasis-engine/math";
import { InterpolableValueType } from "./enums/InterpolableValueType";
import { InterpolationType } from "./enums/InterpolationType";
import {
FloatArrayKeyframe,
FloatKeyframe,
InterpolableValue,
Keyframe,
Expand Down Expand Up @@ -48,6 +49,7 @@ export class AnimationCurve {
}

if (!this._valueSize) {
//CM: It's not reasonable to write here.
if (key instanceof FloatKeyframe) {
this._valueSize = 1;
this._valueType = InterpolableValueType.Float;
Expand All @@ -73,6 +75,13 @@ export class AnimationCurve {
this._valueType = InterpolableValueType.Quaternion;
this._currentValue = new Quaternion();
}

if (key instanceof FloatArrayKeyframe) {
const size = key.value.length;
this._valueSize = size;
this._valueType = InterpolableValueType.FloatArray;
this._currentValue = new Float32Array(size);
}
}
this.keys.sort((a, b) => a.time - b.time);
}
Expand All @@ -81,7 +90,7 @@ export class AnimationCurve {
* Evaluate the curve at time.
* @param time - The time within the curve you want to evaluate
*/
evaluate(time: number): Readonly<InterpolableValue> {
evaluate(time: number): InterpolableValue {
const { keys, interpolation } = this;
const { length } = this.keys;

Expand Down Expand Up @@ -163,6 +172,14 @@ export class AnimationCurve {
switch (_valueType) {
case InterpolableValueType.Float:
return <number>keys[frameIndex].value * (1 - t) + <number>keys[nextFrameIndex].value * t;
case InterpolableValueType.FloatArray:
const curValue = this._currentValue;
const value = <Float32Array>keys[frameIndex].value;
const nextValue = <Float32Array>keys[frameIndex].value;
for (let i = 0, n = value.length; i < n; i++) {
curValue[i] = value[i] * (1 - t) + nextValue[i] * t;
}
return curValue;
case InterpolableValueType.Vector2:
Vector2.lerp(
<Vector2>keys[frameIndex].value,
Expand Down
15 changes: 11 additions & 4 deletions packages/core/src/animation/Animator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Quaternion, Vector3 } from "@oasis-engine/math";
import { ignoreClone } from "../clone/CloneManager";
import { Component } from "../Component";
import { Entity } from "../Entity";
import { SkinnedMeshRenderer } from "../mesh";
import { ClassPool } from "../RenderPipeline/ClassPool";
import { Transform } from "../Transform";
import { AnimationCurve } from "./AnimationCurve";
Expand Down Expand Up @@ -559,10 +560,10 @@ export class Animator extends Component {
}
}

private _applyClipValue(owener: AnimationCurveOwner, value: InterpolableValue, weight: number): void {
if (owener.type === Transform) {
const transform = owener.target.transform;
switch (owener.property) {
private _applyClipValue(owner: AnimationCurveOwner, value: InterpolableValue, weight: number): void {
if (owner.type === Transform) {
const transform = owner.target.transform;
switch (owner.property) {
case AnimationProperty.Position:
if (weight === 1.0) {
transform.position = <Vector3>value;
Expand Down Expand Up @@ -591,6 +592,12 @@ export class Animator extends Component {
}
break;
}
} else if (owner.type === SkinnedMeshRenderer) {
switch (owner.property) {
case AnimationProperty.BlendShapeWeights:
(<SkinnedMeshRenderer>owner.component).blendShapeWeights = <Float32Array>value;
break;
}
}
}

Expand Down
16 changes: 14 additions & 2 deletions packages/core/src/animation/KeyFrame.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Vector2, Vector3, Vector4, Quaternion } from "@oasis-engine/math";

export type InterpolableValue = number | Vector2 | Vector3 | Vector4 | Quaternion;
export type InterpolableValue = number | Vector2 | Vector3 | Vector4 | Quaternion | Float32Array;

/**
* A single keyframe that can be injected into an animation curve.
Expand All @@ -13,7 +13,7 @@ export interface Keyframe {
/** The time of the keyframe. */
time: number;
/** The value of the curve at keyframe. */
value: number | Vector2 | Vector3 | Vector4 | Quaternion;
value: number | Vector2 | Vector3 | Vector4 | Quaternion | Float32Array;
}

export class FloatKeyframe implements Keyframe {
Expand All @@ -26,6 +26,18 @@ export class FloatKeyframe implements Keyframe {
/** The value of the curve at keyframe. */
value: number;
}

export class FloatArrayKeyframe implements Keyframe {
/** Sets the incoming tangent for this key. The incoming tangent affects the slope of the curve from the previous key to this key. */
inTangent?: number;
/** Sets the outgoing tangent for this key. The outgoing tangent affects the slope of the curve from this key to the next key. */
outTangent?: number;
/** The time of the keyframe. */
time: number;
/** The value of the curve at keyframe. */
value: Float32Array;
}

export class Vector2Keyframe implements Keyframe {
/** Sets the incoming tangent for this key. The incoming tangent affects the slope of the curve from the previous key to this key. */
inTangent?: Vector2;
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/animation/enums/AnimationProperty.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export enum AnimationProperty {
Position,
Rotation,
Scale
Scale,
BlendShapeWeights
}
1 change: 1 addition & 0 deletions packages/core/src/animation/enums/InterpolableValueType.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export enum InterpolableValueType {
Float,
FloatArray,
Vector2,
Vector3,
Vector4,
Expand Down
67 changes: 0 additions & 67 deletions packages/core/src/animation/internal/AnimationCureOwner.ts

This file was deleted.

10 changes: 10 additions & 0 deletions packages/core/src/animation/internal/AnimationCurveOwner.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Quaternion, Vector3 } from "@oasis-engine/math";
import { Component } from "../../Component";
import { Entity } from "../../Entity";
import { SkinnedMeshRenderer } from "../../mesh/SkinnedMeshRenderer";
import { AnimationProperty } from "../enums/AnimationProperty";
import { InterpolableValue } from "../KeyFrame";

Expand All @@ -14,6 +15,7 @@ export class AnimationCurveOwner {
readonly target: Entity;
readonly type: new (entity: Entity) => Component;
readonly property: AnimationProperty;
readonly component: Component;
readonly defaultValue: InterpolableValue;
readonly fixedPoseValue: InterpolableValue;

Expand All @@ -25,14 +27,22 @@ export class AnimationCurveOwner {
case AnimationProperty.Position:
this.defaultValue = new Vector3();
this.fixedPoseValue = new Vector3();
this.component = target.transform;
break;
case AnimationProperty.Rotation:
this.defaultValue = new Quaternion();
this.fixedPoseValue = new Quaternion();
this.component = target.transform;
break;
case AnimationProperty.Scale:
this.defaultValue = new Vector3();
this.fixedPoseValue = new Vector3();
this.component = target.transform;
break;
case AnimationProperty.BlendShapeWeights:
this.defaultValue = new Float32Array(4);
this.fixedPoseValue = new Float32Array(4);
this.component = target.getComponent(SkinnedMeshRenderer);
break;
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/base/Constant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ export enum DataType {
* Some capabilities can be smoothed out by extension, and some capabilities must use WebGL 2.0.
* */
export enum GLCapabilityType {
shaderVertexID = "shaderVertexID",
standardDerivatives = "OES_standard_derivatives",
shaderTextureLod = "EXT_shader_texture_lod",
elementIndexUint = "OES_element_index_uint",
Expand Down
15 changes: 5 additions & 10 deletions packages/core/src/graphic/Mesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { VertexBufferBinding } from "../graphic/VertexBufferBinding";
import { VertexElement } from "../graphic/VertexElement";
import { ShaderProgram } from "../shader/ShaderProgram";
import { UpdateFlag } from "../UpdateFlag";
import { UpdateFlagManager } from "../UpdateFlagManager";

/**
* Mesh.
Expand All @@ -35,7 +36,7 @@ export abstract class Mesh extends RefObject {
_vertexElements: VertexElement[] = [];

private _subMeshes: SubMesh[] = [];
private _updateFlags: UpdateFlag[] = [];
private _updateFlagManager: UpdateFlagManager = new UpdateFlagManager();

/**
* First sub-mesh. Rendered using the first material.
Expand Down Expand Up @@ -114,7 +115,7 @@ export abstract class Mesh extends RefObject {
* @returns Update flag
*/
registerUpdateFlag(): UpdateFlag {
return new UpdateFlag(this._updateFlags);
return this._updateFlagManager.register();
}

/**
Expand All @@ -139,7 +140,7 @@ export abstract class Mesh extends RefObject {
* @override
* Destroy.
*/
_onDestroy() {
_onDestroy(): void {
this._vertexBufferBindings = null;
this._indexBufferBinding = null;
this._vertexElements = null;
Expand Down Expand Up @@ -186,12 +187,6 @@ export abstract class Mesh extends RefObject {
const { semantic } = element;
this._vertexElementMap[semantic] = element;
this._vertexElements.push(element);
this._makeModified();
}

private _makeModified(): void {
for (let i = this._updateFlags.length - 1; i >= 0; i--) {
this._updateFlags[i].flag = true;
}
this._updateFlagManager.distribute();
}
}
Loading