Compare commits

..

No commits in common. "5bb8bfe747306849af021248a5fe0ba2c32b40df" and "edd25ba7d126bd646f95620b7f24df1f8c90e946" have entirely different histories.

3 changed files with 59 additions and 108 deletions

View File

@ -565,17 +565,7 @@ function danceAsLowLevelMoves(moves: Move[], startingPos: Map<DancerIdentity, Se
} }
export let mappedDance: Move[]; export const mappedDance = exampleDance.map(nameLibFigureParameters);
export let interpretedDance: Map<DancerIdentity, LowLevelMove[]>; export const interpretedDance = danceAsLowLevelMoves(mappedDance, handsFourImproper);
export let interpretedAnimation: animation.Animation; export const interpretedAnimation: animation.Animation = animateFromLowLevelMoves(interpretedDance);
export function loadDance(dance: LibFigureDance): animation.Animation {
mappedDance = dance.map(nameLibFigureParameters);
interpretedDance = danceAsLowLevelMoves(mappedDance, handsFourImproper);
interpretedAnimation = animateFromLowLevelMoves(interpretedDance);
return interpretedAnimation;
}
loadDance(exampleDance);

View File

@ -491,17 +491,11 @@ export function animateLowLevelMove(move: LowLevelMove): animation.AnimationSegm
throw "Unsupported move in animateLowLevelMove: " + JSON.stringify(move); throw "Unsupported move in animateLowLevelMove: " + JSON.stringify(move);
} }
const anim: animation.AnimationSegment[] = handleMove(); return [
animation.LinearAnimationSegment.standStill(startSetPosition),
// Normalize start/end positions if necessary. ...handleMove(),
if (JSON.stringify(anim[0].startPosition) != JSON.stringify(startSetPosition)) { animation.LinearAnimationSegment.standStill(endSetPosition),
anim.unshift(animation.LinearAnimationSegment.standStill(startSetPosition)) ];
}
if (JSON.stringify(anim[anim.length - 1].endPosition) != JSON.stringify(endSetPosition)) {
anim.push(animation.LinearAnimationSegment.standStill(endSetPosition))
}
return anim;
} }
export function animateFromLowLevelMoves(moves: Map<DancerIdentity, LowLevelMove[]>): animation.Animation { export function animateFromLowLevelMoves(moves: Map<DancerIdentity, LowLevelMove[]>): animation.Animation {

View File

@ -2,7 +2,7 @@ import * as animation from "./animation.js";
import * as interpreter from "./interpreter.js"; import * as interpreter from "./interpreter.js";
import * as renderer from "./renderer.js"; import * as renderer from "./renderer.js";
import { DancerIdentity } from "./danceCommon.js"; import { DancerIdentity } from "./danceCommon.js";
import { LibFigureDance, Move } from "./libfigureMapper.js"; import { Move } from "./libfigureMapper.js";
import { animateLowLevelMove, LowLevelMove } from "./lowLevelMove.js"; import { animateLowLevelMove, LowLevelMove } from "./lowLevelMove.js";
const body = document.querySelector('body')!; const body = document.querySelector('body')!;
@ -139,32 +139,6 @@ function playAnimation(bpm: number, start: number, end: number) {
anim(); anim();
} }
// Two Hearts in Time by Isaac Banner. Selected arbitrarily.
const exampleDance: LibFigureDance = [{ "parameter_values": [true, 8], "move": "petronella" }, { "parameter_values": [true, 8], "move": "petronella" }, { "parameter_values": ["neighbors", "balance", 16], "move": "swing" }, { "parameter_values": ["ladles", true, 540, 8], "move": "allemande" }, { "parameter_values": ["partners", "none", 8], "move": "swing" }, { "parameter_values": ["gentlespoons", 360, 6], "move": "mad robin" }, { "parameter_values": [true, 270, 6], "move": "circle" }, { "parameter_values": ["partners", 4], "move": "California twirl", "progression": 1 }];
const danceJsonArea = document.createElement('textarea');
danceJsonArea.value = JSON.stringify(exampleDance, undefined, 2);
danceJsonArea.rows = 15;
danceJsonArea.cols = 30;
const loadDanceButton = document.createElement('button');
loadDanceButton.innerText = 'Load Dance';
wrapperDiv.appendChild(document.createElement('br'));
wrapperDiv.appendChild(danceJsonArea);
wrapperDiv.appendChild(loadDanceButton);
loadDanceButton.addEventListener('click', (ev) => {
const dance: LibFigureDance = JSON.parse(danceJsonArea.value);
r.animation = interpreter.loadDance(dance);
if (cancelAnim !== undefined) {
cancelAnimationFrame(cancelAnim);
playButton.innerText = 'Play';
}
beatSlider.value = '0';
beatDisplay.innerText = '0';
r.drawSetsWithTrails(0);
buildDebugTable();
});
function createJsonCell(content: any, rowSpan?: number, id?: DancerIdentity) { function createJsonCell(content: any, rowSpan?: number, id?: DancerIdentity) {
const cell = document.createElement('td'); const cell = document.createElement('td');
const pre = document.createElement('pre'); const pre = document.createElement('pre');
@ -221,68 +195,61 @@ body.appendChild(showDebugLabel);
const table = document.createElement('table'); const table = document.createElement('table');
table.id = 'debug' table.id = 'debug'
function buildDebugTable() { const headerRow = document.createElement('tr');
while (table.childNodes.length > 0) { const roles = [DancerIdentity.OnesLark, DancerIdentity.OnesRobin,
table.removeChild(table.childNodes[table.childNodes.length - 1]); DancerIdentity.TwosLark, DancerIdentity.TwosRobin];
} headerRow.appendChild(createHeaderCell("Move"));
for (const role of roles) {
headerRow.appendChild(createHeaderCell(role.toString(), role));
}
table.appendChild(headerRow);
const headerRow = document.createElement('tr'); const byMove: { move: Move, byRole: Map<DancerIdentity, { lowLevelMove?: LowLevelMove, animationSegment: animation.AnimationSegment, numSegments?: number }[]> }[] = [];
const roles = [DancerIdentity.OnesLark, DancerIdentity.OnesRobin, for (const [role, moveList] of interpreter.interpretedDance.entries()) {
DancerIdentity.TwosLark, DancerIdentity.TwosRobin]; for (const move of moveList) {
headerRow.appendChild(createHeaderCell("Move")); let entry = byMove.find(el => el.move === move.move);
for (const role of roles) { if (!entry) {
headerRow.appendChild(createHeaderCell(role.toString(), role)); entry = { move: move.move, byRole: new Map<DancerIdentity, { lowLevelMove?: LowLevelMove, animationSegment: animation.AnimationSegment, numSegments?: number }[]>() };
} byMove.push(entry);
table.appendChild(headerRow);
const byMove: { move: Move, byRole: Map<DancerIdentity, { lowLevelMove?: LowLevelMove, animationSegment: animation.AnimationSegment, numSegments?: number }[]> }[] = [];
for (const [role, moveList] of interpreter.interpretedDance.entries()) {
for (const move of moveList) {
let entry = byMove.find(el => el.move === move.move);
if (!entry) {
entry = { move: move.move, byRole: new Map<DancerIdentity, { lowLevelMove?: LowLevelMove, animationSegment: animation.AnimationSegment, numSegments?: number }[]>() };
byMove.push(entry);
}
let forRole = entry.byRole.get(role);
if (!forRole) {
forRole = [];
entry.byRole.set(role, forRole);
}
const animation = animateLowLevelMove(move);
let first = true;
for (const animationSegment of animation) {
if (first) {
forRole.push({ lowLevelMove: move, animationSegment, numSegments: animation.length });
first = false;
} else {
forRole.push({ animationSegment });
}
}
} }
} let forRole = entry.byRole.get(role);
if (!forRole) {
for (const infoForMove of byMove) { forRole = [];
const moveRow = document.createElement('tr'); entry.byRole.set(role, forRole);
const numRows = Math.max(...[...infoForMove.byRole.values()].map(l => l.length)); }
moveRow.appendChild(createJsonCell(infoForMove.move, numRows)); const animation = animateLowLevelMove(move);
let first = true;
for (let i = 0; i < numRows; i++) { for (const animationSegment of animation) {
const row = i == 0 ? moveRow : document.createElement('tr'); if (first) {
forRole.push({ lowLevelMove: move, animationSegment, numSegments: animation.length });
for (const role of roles) { first = false;
const lowLevelMove = infoForMove.byRole.get(role)?.at(i); } else {
if (!lowLevelMove) { forRole.push({ animationSegment });
row.appendChild(createJsonCell(undefined, undefined, role));
} else if (lowLevelMove.lowLevelMove) {
row.appendChild(createJsonCell(lowLevelMove.lowLevelMove, lowLevelMove.numSegments, role));
}
row.appendChild(createJsonCell(lowLevelMove?.animationSegment, undefined, role));
} }
table.appendChild(row);
} }
} }
} }
buildDebugTable();
for (const infoForMove of byMove) {
const moveRow = document.createElement('tr');
const numRows = Math.max(...[...infoForMove.byRole.values()].map(l => l.length));
moveRow.appendChild(createJsonCell(infoForMove.move, numRows));
for (let i = 0; i < numRows; i++) {
const row = i == 0 ? moveRow : document.createElement('tr');
for (const role of roles) {
const lowLevelMove = infoForMove.byRole.get(role)?.at(i);
if (!lowLevelMove) {
row.appendChild(createJsonCell(undefined, undefined, role));
} else if (lowLevelMove.lowLevelMove) {
row.appendChild(createJsonCell(lowLevelMove.lowLevelMove, lowLevelMove.numSegments, role));
}
row.appendChild(createJsonCell(lowLevelMove?.animationSegment, undefined, role));
}
table.appendChild(row);
}
}
body.appendChild(table); body.appendChild(table);