Compare commits
2 Commits
545207965f
...
43ffd7d87a
Author | SHA1 | Date | |
---|---|---|---|
43ffd7d87a | |||
cd57aab3fa |
|
@ -89,7 +89,7 @@ export class LinearAnimationSegment extends AnimationSegment {
|
|||
export interface AnimationTransitionFlags {
|
||||
rotation?: boolean;
|
||||
hands?: boolean;
|
||||
handsDuring?: "Actual" | "None" | "Start" | "End";
|
||||
handsDuring?: "Actual" | "None" | "Start" | "End" | Map<Hand, Offset>;
|
||||
}
|
||||
export class TransitionAnimationSegment extends AnimationSegment {
|
||||
private readonly actualAnimation: AnimationSegment;
|
||||
|
@ -122,27 +122,29 @@ export class TransitionAnimationSegment extends AnimationSegment {
|
|||
const transitionEnd = this.actualAnimation.interpolateRotation(1 - this.endTransitionProgress);
|
||||
|
||||
if (actualEnd > actualStart) {
|
||||
while (transitionStart < this.startRotation) {
|
||||
while (transitionStart <= this.startRotation - 180) {
|
||||
this.startRotation -= 360;
|
||||
}
|
||||
while (transitionEnd > this.endRotation) {
|
||||
while (transitionEnd >= this.endRotation + 180) {
|
||||
this.endRotation += 360;
|
||||
}
|
||||
} else if (actualEnd < actualStart) {
|
||||
while (transitionStart > this.startRotation) {
|
||||
while (transitionStart >= this.startRotation + 180) {
|
||||
this.startRotation += 360;
|
||||
}
|
||||
while (transitionEnd < this.endRotation) {
|
||||
while (transitionEnd <= this.endRotation - 180) {
|
||||
this.endRotation -= 360;
|
||||
}
|
||||
} else {
|
||||
while (transitionStart - this.startRotation < 180) {
|
||||
}
|
||||
|
||||
// Transitions should be short adjustments, not spins.
|
||||
while (transitionStart - this.startRotation < -180) {
|
||||
this.startRotation -= 360;
|
||||
}
|
||||
while (transitionStart - this.startRotation > 180) {
|
||||
this.startRotation += 360;
|
||||
}
|
||||
while (transitionEnd - this.endRotation < 180) {
|
||||
while (transitionEnd - this.endRotation < -180) {
|
||||
this.endRotation -= 360;
|
||||
}
|
||||
while (transitionEnd - this.endRotation > 180) {
|
||||
|
@ -150,7 +152,6 @@ export class TransitionAnimationSegment extends AnimationSegment {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override interpolateOffset(progress: number): Offset {
|
||||
return this.actualAnimation.interpolateOffset(progress);
|
||||
|
@ -185,6 +186,8 @@ export class TransitionAnimationSegment extends AnimationSegment {
|
|||
? startHand
|
||||
: this.flags.handsDuring === "End"
|
||||
? endHand
|
||||
: this.flags.handsDuring instanceof Map
|
||||
? this.flags.handsDuring.get(hand)
|
||||
: (() => { throw "Unexpected handsDuring: " + this.flags.handsDuring; })();
|
||||
|
||||
if (this.flags.hands) {
|
||||
|
@ -238,8 +241,9 @@ export class RotationAnimationSegment extends AnimationSegment {
|
|||
private readonly startFacing: Rotation;
|
||||
private readonly closer?: Closer;
|
||||
private readonly hands: Map<Hand, HandAnimation>;
|
||||
private readonly centerRelativeTo: number;
|
||||
|
||||
constructor({ beats, startPosition, endPosition, rotation, around, facing, closer, hands }: {
|
||||
constructor({ beats, startPosition, endPosition, rotation, around, facing, closer, hands, centerRelativeTo }: {
|
||||
beats: number;
|
||||
startPosition: DancerSetPosition;
|
||||
endPosition: DancerSetPosition;
|
||||
|
@ -248,6 +252,7 @@ export class RotationAnimationSegment extends AnimationSegment {
|
|||
facing: RotationAnimationFacing;
|
||||
closer?: CloserDuringRotation;
|
||||
hands?: Map<Hand, HandAnimation>;
|
||||
centerRelativeTo?: number;
|
||||
}) {
|
||||
super(beats, startPosition, endPosition);
|
||||
|
||||
|
@ -268,6 +273,7 @@ export class RotationAnimationSegment extends AnimationSegment {
|
|||
}
|
||||
this.startRotation = positionToDegrees(startPosition.position);
|
||||
this.startFacing = startPosition.rotation;
|
||||
this.centerRelativeTo = centerRelativeTo ?? this.startFacing;
|
||||
const actualRotation = normalizeRotation(positionToDegrees(endPosition.position) - this.startRotation,
|
||||
rotation);
|
||||
this.endRotation = this.startRotation + actualRotation;
|
||||
|
@ -311,14 +317,13 @@ export class RotationAnimationSegment extends AnimationSegment {
|
|||
return super.interpolateRotation(progress);
|
||||
} else {
|
||||
const degrees = interpolateLinear(progress, this.startRotation, this.endRotation);
|
||||
let rotation : number;
|
||||
switch (this.facing) {
|
||||
case RotationAnimationFacing.Start:
|
||||
return this.startFacing;
|
||||
case RotationAnimationFacing.Center:
|
||||
return degrees - 90;
|
||||
case RotationAnimationFacing.CenterRelative:
|
||||
return degrees - this.startRotation + this.startFacing;
|
||||
return degrees - this.startRotation + this.centerRelativeTo;
|
||||
case RotationAnimationFacing.Forward:
|
||||
return degrees + 180;
|
||||
case RotationAnimationFacing.Backward:
|
||||
|
|
|
@ -697,7 +697,7 @@ function moveAsLowLevelMoves({ move, nextMove, startingPos, numProgessions }: {
|
|||
return combine([
|
||||
prevEnd => ({
|
||||
beats: meltdownBeats,
|
||||
endPosition: prevEnd,
|
||||
endPosition: {...prevEnd, dancerDistance: DancerDistance.Compact },
|
||||
movementPattern: {
|
||||
kind: SemanticAnimationKind.RotateAround,
|
||||
minAmount: 360,
|
||||
|
|
|
@ -324,5 +324,5 @@ export type SemanticPosition = {
|
|||
facing: Facing,
|
||||
hands?: Map<Hand, HandConnection>,
|
||||
balance?: BalanceWeight,
|
||||
dancerDistance?: DancerDistance.Normal | DancerDistance.SwingLark | DancerDistance.SwingRobin,
|
||||
dancerDistance?: DancerDistance,
|
||||
};
|
||||
|
|
|
@ -170,6 +170,30 @@ function CenterOf(sideOrCenter: CircleSideOrCenter, setOffset?: number, lineOffs
|
|||
return { x: setCenter.x + xOffset, y: setCenter.y + yOffset };
|
||||
}
|
||||
|
||||
function swingHandPosition(role: DancerDistance.SwingLark | DancerDistance.SwingRobin, hand: Hand): Offset {
|
||||
if (role === DancerDistance.SwingLark) {
|
||||
if (hand === Hand.Left) {
|
||||
return { x: 0, y: Math.sqrt(1 / 2) };
|
||||
}
|
||||
else {
|
||||
return { x: 0.8, y: 0.5 };
|
||||
}
|
||||
} else /* role === DancerDistance.SwingRobin */ {
|
||||
if (hand === Hand.Left) {
|
||||
return { x: -0.8, y: 0.5 };
|
||||
}
|
||||
else {
|
||||
return { x: 0, y: Math.sqrt(1 / 2) };
|
||||
};
|
||||
}
|
||||
}
|
||||
function swingHandPositions(role: DancerDistance.SwingLark | DancerDistance.SwingRobin): Map<Hand, Offset> {
|
||||
return new Map<Hand, Offset>([
|
||||
[Hand.Left, swingHandPosition(role, Hand.Left)],
|
||||
[Hand.Right, swingHandPosition(role, Hand.Right)],
|
||||
]);
|
||||
}
|
||||
|
||||
function SemanticToSetPosition(semantic: SemanticPosition): DancerSetPosition {
|
||||
|
||||
let rotation: number;
|
||||
|
@ -211,8 +235,6 @@ function SemanticToSetPosition(semantic: SemanticPosition): DancerSetPosition {
|
|||
yAmount = 1;
|
||||
break;
|
||||
case DancerDistance.Compact:
|
||||
yAmount = 0.75;
|
||||
break;
|
||||
case DancerDistance.SwingLark:
|
||||
case DancerDistance.SwingRobin:
|
||||
yAmount = 0.5;
|
||||
|
@ -286,8 +308,8 @@ function SemanticToSetPosition(semantic: SemanticPosition): DancerSetPosition {
|
|||
position = OffsetPlus(position, balanceOffset, setOffset);
|
||||
|
||||
const isFacingUpOrDown = semantic.facing === Facing.Up || semantic.facing === Facing.Down;
|
||||
if (semantic.dancerDistance === DancerDistance.SwingLark) {
|
||||
if (isFacingUpOrDown) {
|
||||
if (semantic.dancerDistance === DancerDistance.SwingLark || semantic.dancerDistance == DancerDistance.SwingRobin) {
|
||||
if (isFacingUpOrDown == (semantic.dancerDistance === DancerDistance.SwingLark)) {
|
||||
rotation -= 45;
|
||||
} else {
|
||||
rotation += 45;
|
||||
|
@ -296,21 +318,8 @@ function SemanticToSetPosition(semantic: SemanticPosition): DancerSetPosition {
|
|||
return {
|
||||
position,
|
||||
rotation,
|
||||
leftArmEnd: { x: 0, y: Math.sqrt(1/2)},
|
||||
rightArmEnd: { x: 0.8, y: 0.5 },
|
||||
};
|
||||
} else if (semantic.dancerDistance === DancerDistance.SwingRobin) {
|
||||
if (isFacingUpOrDown) {
|
||||
rotation += 45;
|
||||
} else {
|
||||
rotation -= 45;
|
||||
}
|
||||
|
||||
return {
|
||||
position,
|
||||
rotation,
|
||||
leftArmEnd: { x: -0.8, y: 0.5 },
|
||||
rightArmEnd: { x: 0, y: Math.sqrt(1/2) },
|
||||
leftArmEnd: swingHandPosition(semantic.dancerDistance, Hand.Left),
|
||||
rightArmEnd: swingHandPosition(semantic.dancerDistance, Hand.Right),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -325,10 +334,11 @@ function SemanticToSetPosition(semantic: SemanticPosition): DancerSetPosition {
|
|||
case HandTo.DancerRight:
|
||||
return OffsetPlus({ x: +1, y: 0 }, balanceHandAdjustment);
|
||||
case HandTo.DancerForward:
|
||||
const armLength = yAmount + (semantic.balance === BalanceWeight.Backward ? balanceAmount : 0);
|
||||
if (hand === connection.hand) {
|
||||
return { x: 0, y: +0.5 };
|
||||
return { x: 0, y: +armLength/2 };
|
||||
} else {
|
||||
return { x: dancerWidth / 2 * (hand === Hand.Left ? -1 : +1), y: +1 };
|
||||
return { x: dancerWidth / 2 * (hand === Hand.Left ? -1 : +1), y: +armLength };
|
||||
}
|
||||
case HandTo.LeftInCircle:
|
||||
case HandTo.RightInCircle:
|
||||
|
@ -572,13 +582,13 @@ export function animateLowLevelMove(move: LowLevelMove): animation.AnimationSegm
|
|||
rotation: move.movementPattern.minAmount,
|
||||
around: {
|
||||
center: rotateCenter,
|
||||
width: setWidth / 5,
|
||||
height: setHeight / 5,
|
||||
width: 1,
|
||||
height: 1,
|
||||
},
|
||||
facing: animation.RotationAnimationFacing.Center,
|
||||
facing: animation.RotationAnimationFacing.Forward,
|
||||
closer: move.movementPattern.close ? {
|
||||
transitionBeats: 1,
|
||||
minDistance: setWidth,
|
||||
minDistance: 1,
|
||||
} : undefined,
|
||||
hands
|
||||
}),
|
||||
|
@ -611,22 +621,31 @@ export function animateLowLevelMove(move: LowLevelMove): animation.AnimationSegm
|
|||
});
|
||||
|
||||
return [
|
||||
new animation.LinearAnimationSegment({
|
||||
beats: 1,
|
||||
new animation.TransitionAnimationSegment({
|
||||
actualAnimation: new animation.RotationAnimationSegment({
|
||||
beats: move.beats - 2,
|
||||
startPosition: startSetPosition,
|
||||
endPosition: swingStart,
|
||||
}),
|
||||
new animation.RotationAnimationSegment({
|
||||
beats: move.beats - 3,
|
||||
startPosition: swingStart,
|
||||
endPosition: beforeUnfold,
|
||||
rotation: move.movementPattern.minAmount,
|
||||
around: {
|
||||
center: rotateSwingCenter,
|
||||
width: setWidth / 5,
|
||||
height: setHeight / 5,
|
||||
width: 1,
|
||||
height: 1,
|
||||
},
|
||||
facing: animation.RotationAnimationFacing.CenterRelative
|
||||
closer: {
|
||||
minDistance: 1,
|
||||
transitionBeats: 1,
|
||||
},
|
||||
facing: animation.RotationAnimationFacing.CenterRelative,
|
||||
centerRelativeTo: startSetPosition.rotation + ((move.startPosition.facing === Facing.Up || move.startPosition.facing === Facing.Down) === (dancerDistance === DancerDistance.SwingLark) ? -45 : +45)
|
||||
}),
|
||||
flags: {
|
||||
rotation: true,
|
||||
hands: true,
|
||||
handsDuring: swingHandPositions(dancerDistance),
|
||||
},
|
||||
startTransitionBeats: 1,
|
||||
endTransitionBeats: 0,
|
||||
}),
|
||||
new animation.LinearAnimationSegment({
|
||||
beats: 1,
|
||||
|
|
Loading…
Reference in New Issue
Block a user