Skip to content
This repository has been archived by the owner on Jun 10, 2022. It is now read-only.

Simplify interpolation test #159

Merged
merged 1 commit into from
Jan 31, 2019
Merged
Changes from all commits
Commits
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
198 changes: 55 additions & 143 deletions packages/functional-tests/src/tests/interpolation-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,164 +5,76 @@

import * as MRESDK from '@microsoft/mixed-reality-extension-sdk';
import App from '../app';
import delay from '../utils/delay';
import destroyActors from '../utils/destroyActors';
import Test from './test';

export default class InterpolationTest extends Test {
private actors: MRESDK.Actor[] = [];
private anims: Function[] = [];
private stepSize = 0.3;
private curveNames = Object.keys(MRESDK.AnimationEaseCurves);

private get width() { return this.curveNames.length * this.stepSize; }
private sceneRoot: MRESDK.Actor;
private running = true;

constructor(app: App) {
super(app);
}

public async run(): Promise<boolean> {
this.buildPositionTest();
this.buildRotationTest();
this.buildScaleTest();
await delay(500);
this.anims.forEach(anim => anim());
await delay(30000);
destroyActors(this.actors);
this.sceneRoot = MRESDK.Actor.CreateEmpty(this.app.context).value;
const expressiveCubePromise = this.spawnExpressiveCube();
const timeout = setTimeout(() => this.running = false, 60000);
await expressiveCubePromise;
clearTimeout(timeout);
destroyActors(this.sceneRoot);
return true;
}

public buildPositionTest() {
// Spawn a line of spheres. One for each ease curve type.
let x = -this.width / 2;
const radius = 0.09;
for (const curveName of this.curveNames) {
const loadActor = MRESDK.Actor.CreatePrimitive(this.app.context, {
definition: {
shape: MRESDK.PrimitiveShape.Sphere,
radius
},
actor: {
name: `position-${x}`,
transform: { position: { x, y: radius, z: -this.width / 2 } }
},
});
const actor = loadActor.value;
this.actors.push(actor);

this.anims.push(this.buildPositionInterpolation(actor,
(MRESDK.AnimationEaseCurves as any)[curveName]));

x += this.stepSize;
}
}

public buildRotationTest() {
// Spawn a line of spheres. One for each ease curve type.
let x = -this.width / 2;
const height = 1;
for (const curveName of this.curveNames) {
const loadActor = MRESDK.Actor.CreatePrimitive(this.app.context, {
definition: {
shape: MRESDK.PrimitiveShape.Box,
dimensions: {
x: this.stepSize * 0.7,
y: height,
z: 0.05
}
},
actor: {
name: `rotation-${x}`,
transform: { position: { x, y: height / 2, z: 0 } }
},
});
const actor = loadActor.value;
this.actors.push(actor);

this.anims.push(this.buildRotationInterpolation(actor, (MRESDK.AnimationEaseCurves as any)[curveName]));

x += this.stepSize;
}
}

public buildScaleTest() {
// Spawn a line of spheres. One for each ease curve type.
let x = -this.width / 2;
const height = 1;
for (const curveName of this.curveNames) {
const loadActor = MRESDK.Actor.CreatePrimitive(this.app.context, {
definition: {
shape: MRESDK.PrimitiveShape.Box,
dimensions: {
x: 0.1,
y: height,
z: 0.1
}
private async spawnExpressiveCube() {
MRESDK.Actor.CreateEmpty(this.app.context, {
actor: {
parentId: this.sceneRoot.id,
transform: {
position: { y: 2.5 }
},
actor: {
name: `scale-${x}`,
transform: { position: { x, y: height / 2, z: this.width / 2 } }
},
});
const actor = loadActor.value;
this.actors.push(actor);

// Create a chain of `animateTo` calls to move the sphere up and down on the given ease curve.
this.anims.push(this.buildScaleInterpolation(actor, (MRESDK.AnimationEaseCurves as any)[curveName]));

x += this.stepSize;
}
}

private buildPositionInterpolation(actor: MRESDK.Actor, curve: number[]) {
const y = actor.transform.position.y;
const moveUp = () => actor.animateTo({
transform: { position: { y: this.width / 3 } } }, 1.0, curve);
const moveDown = () => actor.animateTo({
transform: { position: { y } } }, 1.0, curve);
const repeat = async () => {
await moveUp();
await delay(100);
await moveDown();
await delay(100);
await repeat();
};
return repeat;
}

private buildRotationInterpolation(actor: MRESDK.Actor, curve: number[]) {
const rotateRight = () => actor.animateTo({
transform: {
rotation: MRESDK.Quaternion.RotationAxis(MRESDK.Vector3.Up(), 180 * MRESDK.DegreesToRadians)
text: {
contents: 'Lerping scale and rotation\nClick to exit (or wait a minute)',
anchor: MRESDK.TextAnchorLocation.TopCenter,
justify: MRESDK.TextJustify.Center,
height: 0.4,
color: MRESDK.Color3.Yellow()
}
}
}, 1.0, curve);
const rotateLeft = () => actor.animateTo({
transform: {
rotation: MRESDK.Quaternion.RotationAxis(MRESDK.Vector3.Up(), 0)
});
const cube = MRESDK.Actor.CreatePrimitive(this.app.context, {
definition: {
shape: MRESDK.PrimitiveShape.Box
},
addCollider: true,
actor: {
parentId: this.sceneRoot.id,
}
}, 1.0, curve);
const repeat = async () => {
await rotateRight();
await delay(100);
await rotateLeft();
await delay(100);
await repeat();
};
return repeat;
}

private buildScaleInterpolation(actor: MRESDK.Actor, curve: number[]) {
const scaleUp = () => actor.animateTo({
transform: { scale: { y: this.width / 3 } } }, 1.0, curve);
const scaleDown = () => actor.animateTo({
transform: { scale: { y: 1 } } }, 1.0, curve);
const repeat = async () => {
await scaleUp();
await delay(100);
await scaleDown();
await delay(100);
await repeat();
};
return repeat;
}).value;

const buttonBehavior = cube.setBehavior(MRESDK.ButtonBehavior);
buttonBehavior.onClick('released', () => this.running = false);

while (this.running) {
// Random point on unit sphere (pick random axis).
const θ = Math.random() * 2 * Math.PI;
const z = Math.cos(θ);
const x = Math.sqrt(1 - z * z) * Math.cos(θ);
const y = Math.sqrt(1 - z * z) * Math.sin(θ);
const axis = new MRESDK.Vector3(x, y, z);
// Random rotation around picked axis.
const rotation = MRESDK.Quaternion.RotationAxis(axis, Math.random() * 2 * Math.PI);
// Random scale in [1..2].
const scalar = 1 + 1 * Math.random();
const scale = new MRESDK.Vector3(scalar, scalar, scalar);
// Random ease curve.
const easeCurveKeys = Object.keys(MRESDK.AnimationEaseCurves);
const easeIndex = Math.floor(Math.random() * easeCurveKeys.length);
const easeCurveKey = easeCurveKeys[easeIndex];
// Interpolate object's rotation and scale.
await cube.animateTo(
{ transform: { rotation, scale } },
1.0, (MRESDK.AnimationEaseCurves as any)[easeCurveKey]);
}
}
}