Add actor control effects and related functions
This commit is contained in:
@@ -213,6 +213,11 @@ export type ControlEffect =
|
|||||||
| SetSunLightIntensityControlEffect
|
| SetSunLightIntensityControlEffect
|
||||||
| SetSunLightColorControlEffect;
|
| SetSunLightColorControlEffect;
|
||||||
|
|
||||||
|
export type ActorControlEffect =
|
||||||
|
| SetActorPresenceControlEffect
|
||||||
|
| PlayActorAnimationControlEffect
|
||||||
|
| FollowActorPathControlEffect;
|
||||||
|
|
||||||
export interface LightIntensityControlChannelDescriptor {
|
export interface LightIntensityControlChannelDescriptor {
|
||||||
channel: "light.intensity";
|
channel: "light.intensity";
|
||||||
target: LightControlTargetRef;
|
target: LightControlTargetRef;
|
||||||
@@ -480,6 +485,19 @@ export function isControlInteractionTargetKind(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isActorControlEffect(
|
||||||
|
effect: ControlEffect
|
||||||
|
): effect is ActorControlEffect {
|
||||||
|
switch (effect.type) {
|
||||||
|
case "setActorPresence":
|
||||||
|
case "playActorAnimation":
|
||||||
|
case "followActorPath":
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function createActorControlTargetRef(
|
export function createActorControlTargetRef(
|
||||||
actorId: string
|
actorId: string
|
||||||
): ActorControlTargetRef {
|
): ActorControlTargetRef {
|
||||||
@@ -579,6 +597,52 @@ export function createSetActorPresenceControlEffect(options: {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isActorPathProgressMode(
|
||||||
|
value: unknown
|
||||||
|
): value is ActorPathProgressMode {
|
||||||
|
return ACTOR_PATH_PROGRESS_MODES.includes(value as ActorPathProgressMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createPlayActorAnimationControlEffect(options: {
|
||||||
|
target: ActorControlTargetRef;
|
||||||
|
clipName: string;
|
||||||
|
loop?: boolean;
|
||||||
|
}): PlayActorAnimationControlEffect {
|
||||||
|
assertNonEmptyString(options.clipName, "Control actor animation clip name");
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: "playActorAnimation",
|
||||||
|
target: cloneControlTargetRef(options.target) as ActorControlTargetRef,
|
||||||
|
clipName: options.clipName,
|
||||||
|
loop: options.loop
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createFollowActorPathControlEffect(options: {
|
||||||
|
target: ActorControlTargetRef;
|
||||||
|
pathId: string;
|
||||||
|
speed: number;
|
||||||
|
loop?: boolean;
|
||||||
|
progressMode?: ActorPathProgressMode;
|
||||||
|
}): FollowActorPathControlEffect {
|
||||||
|
assertNonEmptyString(options.pathId, "Control actor path id");
|
||||||
|
|
||||||
|
if (!Number.isFinite(options.speed) || options.speed <= 0) {
|
||||||
|
throw new Error(
|
||||||
|
"Control actor path speed must be a finite number greater than zero."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: "followActorPath",
|
||||||
|
target: cloneControlTargetRef(options.target) as ActorControlTargetRef,
|
||||||
|
pathId: options.pathId,
|
||||||
|
speed: options.speed,
|
||||||
|
loop: options.loop ?? false,
|
||||||
|
progressMode: options.progressMode ?? "deriveFromTime"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function createPlayModelAnimationControlEffect(options: {
|
export function createPlayModelAnimationControlEffect(options: {
|
||||||
target: ModelInstanceControlTargetRef;
|
target: ModelInstanceControlTargetRef;
|
||||||
clipName: string;
|
clipName: string;
|
||||||
@@ -903,6 +967,66 @@ export function createResolvedActorPresenceState(options: {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createResolvedActorAnimationPlaybackState(options: {
|
||||||
|
target: ActorControlTargetRef;
|
||||||
|
clipName: string | null;
|
||||||
|
loop: boolean | undefined;
|
||||||
|
source: RuntimeResolvedControlSource;
|
||||||
|
}): RuntimeResolvedActorAnimationPlaybackState {
|
||||||
|
if (options.clipName !== null) {
|
||||||
|
assertNonEmptyString(options.clipName, "Resolved control actor animation clip");
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: "actorAnimationPlayback",
|
||||||
|
target: cloneControlTargetRef(options.target) as ActorControlTargetRef,
|
||||||
|
clipName: options.clipName,
|
||||||
|
loop: options.loop,
|
||||||
|
source: cloneResolvedControlSource(options.source)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createResolvedActorPathAssignmentState(options: {
|
||||||
|
target: ActorControlTargetRef;
|
||||||
|
pathId: string | null;
|
||||||
|
speed: number | null;
|
||||||
|
loop: boolean;
|
||||||
|
progressMode: ActorPathProgressMode | null;
|
||||||
|
source: RuntimeResolvedControlSource;
|
||||||
|
}): RuntimeResolvedActorPathAssignmentState {
|
||||||
|
if (options.pathId !== null) {
|
||||||
|
assertNonEmptyString(options.pathId, "Resolved control actor path id");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
options.speed !== null &&
|
||||||
|
(!Number.isFinite(options.speed) || options.speed <= 0)
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
"Resolved control actor path speed must be a finite number greater than zero."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
(options.pathId === null) !== (options.speed === null) ||
|
||||||
|
(options.pathId === null) !== (options.progressMode === null)
|
||||||
|
) {
|
||||||
|
throw new Error(
|
||||||
|
"Resolved actor path assignments must either define path, speed, and progress mode together or clear all of them."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
type: "actorPathAssignment",
|
||||||
|
target: cloneControlTargetRef(options.target) as ActorControlTargetRef,
|
||||||
|
pathId: options.pathId,
|
||||||
|
speed: options.speed,
|
||||||
|
loop: options.loop,
|
||||||
|
progressMode: options.progressMode,
|
||||||
|
source: cloneResolvedControlSource(options.source)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function createResolvedInteractionEnabledState(options: {
|
export function createResolvedInteractionEnabledState(options: {
|
||||||
target: InteractionControlTargetRef;
|
target: InteractionControlTargetRef;
|
||||||
value: boolean;
|
value: boolean;
|
||||||
|
|||||||
Reference in New Issue
Block a user