Add player animation blending
This commit is contained in:
parent
46a66b4419
commit
89004dcb4f
Binary file not shown.
|
@ -5,6 +5,8 @@
|
|||
#include "mathf.h"
|
||||
#include <math.h>
|
||||
|
||||
struct Quaternion gQuaternionZero = {0.0f, 0.0f, 0.0f, 0.0f};
|
||||
|
||||
void quatIdent(struct Quaternion* q) {
|
||||
q->x = 0.0f;
|
||||
q->y = 0.0f;
|
||||
|
|
|
@ -9,6 +9,8 @@ struct Quaternion {
|
|||
float x, y, z, w;
|
||||
};
|
||||
|
||||
extern struct Quaternion gQuaternionZero;
|
||||
|
||||
void quatIdent(struct Quaternion* q);
|
||||
void quatAxisAngle(struct Vector3* axis, float angle, struct Quaternion* out);
|
||||
void quatAxisComplex(struct Vector3* axis, struct Vector2* complex, struct Quaternion* out);
|
||||
|
|
|
@ -98,9 +98,10 @@ void playerInit(struct Player* player, struct Location* startLocation, struct Ve
|
|||
collisionSceneAddDynamicObject(&player->collisionObject);
|
||||
|
||||
skArmatureInit(&player->armature, &player_chell_armature);
|
||||
skAnimatorV2Init(&player->animator, player_chell_armature.numberOfBones);
|
||||
skBlenderInit(&player->animator, player_chell_armature.numberOfBones);
|
||||
|
||||
skAnimatorV2RunClip(&player->animator, &player_chell_Armature_runn_clip, 0.0f, SKAnimatorV2FlagsLoop);
|
||||
skAnimatorRunClip(&player->animator.from, &player_chell_Armature_runn_clip, 0.0f, SKAnimatorFlagsLoop);
|
||||
skAnimatorRunClip(&player->animator.to, &player_chell_Armature_runc_clip, 0.0f, SKAnimatorFlagsLoop);
|
||||
|
||||
player->body.velocity = *velocity;
|
||||
player->grabbingThroughPortal = PLAYER_GRABBING_THROUGH_NOTHING;
|
||||
|
@ -294,11 +295,53 @@ void playerGetMoveBasis(struct Transform* transform, struct Vector3* forward, st
|
|||
vector3Normalize(right, right);
|
||||
}
|
||||
|
||||
struct SKAnimationClip* playerDetermineNextClip(struct Player* player, float* blendLerp, float* startTime, struct Vector3* forwardDir, struct Vector3* rightDir) {
|
||||
float horzSpeed = player->body.velocity.x * player->body.velocity.x + player->body.velocity.z * player->body.velocity.z;
|
||||
|
||||
if (horzSpeed < 0.0001f) {
|
||||
*blendLerp = 0.0f;
|
||||
*startTime = 0.0f;
|
||||
return &player_chell_Armature_idle_clip;
|
||||
}
|
||||
|
||||
horzSpeed = sqrtf(horzSpeed);
|
||||
|
||||
*blendLerp = 1.0f - horzSpeed * (1.0f / PLAYER_SPEED);
|
||||
|
||||
if (*blendLerp < 0.0f) {
|
||||
*blendLerp = 0.0f;
|
||||
}
|
||||
|
||||
if (*blendLerp > 1.0f) {
|
||||
*blendLerp = 1.0f;
|
||||
}
|
||||
|
||||
*startTime = player->animator.from.currentTime;
|
||||
|
||||
float forward = forwardDir->x * player->body.velocity.x + forwardDir->z * player->body.velocity.z;
|
||||
float right = rightDir->x * player->body.velocity.x + rightDir->z * player->body.velocity.z;
|
||||
|
||||
if (fabsf(forward) > fabsf(right)) {
|
||||
if (forward > 0.0f) {
|
||||
return &player_chell_Armature_runs_clip;
|
||||
} else {
|
||||
return &player_chell_Armature_runn_clip;
|
||||
}
|
||||
} else {
|
||||
if (right > 0.0f) {
|
||||
return &player_chell_Armature_rune_clip;
|
||||
} else {
|
||||
return &player_chell_Armature_runw_clip;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
|
||||
struct Vector3 forward;
|
||||
struct Vector3 right;
|
||||
|
||||
skAnimatorV2Update(&player->animator, player->armature.boneTransforms, FIXED_DELTA_TIME);
|
||||
skBlenderUpdate(&player->animator, player->armature.boneTransforms, FIXED_DELTA_TIME);
|
||||
|
||||
int doorwayMask = worldCheckDoorwaySides(&gCurrentLevel->world, &player->lookTransform.position, player->body.currentRoom);
|
||||
playerGetMoveBasis(&player->lookTransform, &forward, &right);
|
||||
|
@ -448,4 +491,11 @@ void playerUpdate(struct Player* player, struct Transform* cameraTransform) {
|
|||
player->body.currentRoom = worldCheckDoorwayCrossings(&gCurrentLevel->world, &player->lookTransform.position, player->body.currentRoom, doorwayMask);
|
||||
|
||||
dynamicSceneSetRoomFlags(player->dynamicId, ROOM_FLAG_FROM_INDEX(player->body.currentRoom));
|
||||
|
||||
float startTime = 0.0f;
|
||||
struct SKAnimationClip* clip = playerDetermineNextClip(player, &player->animator.blendLerp, &startTime, &forward, &right);
|
||||
|
||||
if (clip != player->animator.from.currentClip) {
|
||||
skAnimatorRunClip(&player->animator.from, clip, startTime, SKAnimatorFlagsLoop);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ struct Player {
|
|||
struct RigidBody body;
|
||||
struct Transform lookTransform;
|
||||
struct SKArmature armature;
|
||||
struct SKAnimatorV2 animator;
|
||||
struct SKAnimatorBlender animator;
|
||||
short grabbingThroughPortal;
|
||||
short dynamicId;
|
||||
struct CollisionObject* grabbing;
|
||||
|
|
|
@ -100,7 +100,7 @@ void boxDropperInit(struct BoxDropper* dropper, struct BoxDropperDefinition* def
|
|||
|
||||
skArmatureInit(&dropper->armature, &props_box_dropper_armature);
|
||||
|
||||
skAnimatorV2Init(&dropper->animator, PROPS_BOX_DROPPER_DEFAULT_BONES_COUNT);
|
||||
skAnimatorInit(&dropper->animator, PROPS_BOX_DROPPER_DEFAULT_BONES_COUNT);
|
||||
|
||||
dropper->flags = 0;
|
||||
dropper->reloadTimer = DROOPER_RELOAD_TIME;
|
||||
|
@ -109,7 +109,7 @@ void boxDropperInit(struct BoxDropper* dropper, struct BoxDropperDefinition* def
|
|||
}
|
||||
|
||||
void boxDropperUpdate(struct BoxDropper* dropper) {
|
||||
skAnimatorV2Update(&dropper->animator, dropper->armature.boneTransforms, FIXED_DELTA_TIME);
|
||||
skAnimatorUpdate(&dropper->animator, dropper->armature.boneTransforms, FIXED_DELTA_TIME);
|
||||
|
||||
if (dropper->reloadTimer > 0.0f) {
|
||||
dropper->reloadTimer -= FIXED_DELTA_TIME;
|
||||
|
@ -143,7 +143,7 @@ void boxDropperUpdate(struct BoxDropper* dropper) {
|
|||
boxDropperFakePos(dropper, &pendingCubePos);
|
||||
|
||||
decorObjectInit(&dropper->activeCube, decorObjectDefinitionForId(DECOR_TYPE_CUBE), &pendingCubePos, dropper->roomIndex);
|
||||
skAnimatorV2RunClip(&dropper->animator, &props_box_dropper_Armature_DropCube_clip, 0.0f, 0);
|
||||
skAnimatorRunClip(&dropper->animator, &props_box_dropper_Armature_DropCube_clip, 0.0f, 0);
|
||||
|
||||
dropper->flags &= ~BoxDropperFlagsCubeRequested;
|
||||
dropper->flags |= BoxDropperFlagsCubeIsActive;
|
||||
|
|
|
@ -17,7 +17,7 @@ enum BoxDropperFlags {
|
|||
struct BoxDropper {
|
||||
struct Transform transform;
|
||||
struct SKArmature armature;
|
||||
struct SKAnimatorV2 animator;
|
||||
struct SKAnimator animator;
|
||||
|
||||
struct DecorObject activeCube;
|
||||
float reloadTimer;
|
||||
|
|
|
@ -60,7 +60,7 @@ void pedestalInit(struct Pedestal* pedestal, struct PedestalDefinition* definiti
|
|||
|
||||
skArmatureInit(&pedestal->armature, &pedestal_armature);
|
||||
|
||||
skAnimatorV2Init(&pedestal->animator, PEDESTAL_DEFAULT_BONES_COUNT);
|
||||
skAnimatorInit(&pedestal->animator, PEDESTAL_DEFAULT_BONES_COUNT);
|
||||
|
||||
pedestal->dynamicId = dynamicSceneAdd(pedestal, pedestalRender, &pedestal->transform, 0.8f);
|
||||
|
||||
|
@ -82,7 +82,7 @@ void pedestalDetermineHolderAngle(struct Pedestal* pedestal, struct Vector2* out
|
|||
}
|
||||
|
||||
void pedestalUpdate(struct Pedestal* pedestal) {
|
||||
skAnimatorV2Update(&pedestal->animator, pedestal->armature.boneTransforms, FIXED_DELTA_TIME);
|
||||
skAnimatorUpdate(&pedestal->animator, pedestal->armature.boneTransforms, FIXED_DELTA_TIME);
|
||||
|
||||
if (pedestal->flags & PedestalFlagsIsPointing) {
|
||||
struct Vector2 target;
|
||||
|
@ -99,7 +99,7 @@ void pedestalUpdate(struct Pedestal* pedestal) {
|
|||
void pedestalHide(struct Pedestal* pedestal) {
|
||||
pedestal->flags |= PedestalFlagsDown;
|
||||
|
||||
skAnimatorV2RunClip(&pedestal->animator, &pedestal_Armature_Hide_clip, 0.0f, 0);
|
||||
skAnimatorRunClip(&pedestal->animator, &pedestal_Armature_Hide_clip, 0.0f, 0);
|
||||
}
|
||||
|
||||
void pedestalPointAt(struct Pedestal* pedestal, struct Vector3* target) {
|
||||
|
|
|
@ -13,7 +13,7 @@ enum PedestalFlags {
|
|||
struct Pedestal {
|
||||
struct Transform transform;
|
||||
struct SKArmature armature;
|
||||
struct SKAnimatorV2 animator;
|
||||
struct SKAnimator animator;
|
||||
|
||||
short dynamicId;
|
||||
short roomIndex;
|
||||
|
|
|
@ -31,7 +31,7 @@ void skAnimatorCopy(u32 romAddress, void* target, u32 size) {
|
|||
osEPiStartDma(gAnimationPiHandle, ioMesg, OS_READ);
|
||||
}
|
||||
|
||||
void skAnimatorV2Init(struct SKAnimatorV2* animator, int nBones) {
|
||||
void skAnimatorInit(struct SKAnimator* animator, int nBones) {
|
||||
animator->currentClip = NULL;
|
||||
animator->currentTime = 0.0f;
|
||||
animator->blendLerp = 0.0f;
|
||||
|
@ -43,7 +43,7 @@ void skAnimatorV2Init(struct SKAnimatorV2* animator, int nBones) {
|
|||
animator->nBones = nBones;
|
||||
}
|
||||
|
||||
void skAnimatorV2Cleanup(struct SKAnimatorV2* animator) {
|
||||
void skAnimatorCleanup(struct SKAnimator* animator) {
|
||||
free(animator->boneState[0]);
|
||||
free(animator->boneState[1]);
|
||||
|
||||
|
@ -51,7 +51,7 @@ void skAnimatorV2Cleanup(struct SKAnimatorV2* animator) {
|
|||
animator->boneState[1] = NULL;
|
||||
}
|
||||
|
||||
void skAnimatorV2RequestNext(struct SKAnimatorV2* animator) {
|
||||
void skAnimatorRequestNext(struct SKAnimator* animator) {
|
||||
struct SKAnimationClip* currentClip = animator->currentClip;
|
||||
|
||||
if (!currentClip) {
|
||||
|
@ -77,63 +77,88 @@ void skAnimatorV2RequestNext(struct SKAnimatorV2* animator) {
|
|||
skAnimatorCopy((u32)currentClip->frames + frameSize * nextFrame, (void*)animator->boneState[animator->latestBoneState], sizeof(struct SKAnimationBoneFrame) * boneCount);
|
||||
}
|
||||
|
||||
void skAnimatorV2Extractstate(struct SKAnimationBoneFrame* frames, int boneCount, struct Transform* result) {
|
||||
for (int i = 0; i < boneCount; ++i) {
|
||||
result[i].position.x = (float)frames[i].position.x;
|
||||
result[i].position.y = (float)frames[i].position.y;
|
||||
result[i].position.z = (float)frames[i].position.z;
|
||||
void skAnimatorExtractBone(struct SKAnimationBoneFrame* bone, struct Transform* result) {
|
||||
result->position.x = (float)bone->position.x;
|
||||
result->position.y = (float)bone->position.y;
|
||||
result->position.z = (float)bone->position.z;
|
||||
|
||||
result[i].rotation.x = frames[i].rotation.x * (1.0f / 32767.0f);
|
||||
result[i].rotation.y = frames[i].rotation.y * (1.0f / 32767.0f);
|
||||
result[i].rotation.z = frames[i].rotation.z * (1.0f / 32767.0f);
|
||||
float wSqrd = 1.0f - (result[i].rotation.x * result[i].rotation.x + result[i].rotation.y * result[i].rotation.y + result[i].rotation.z * result[i].rotation.z);
|
||||
if (wSqrd <= 0.0f) {
|
||||
result[i].rotation.w = 0.0f;
|
||||
} else {
|
||||
result[i].rotation.w = sqrtf(wSqrd);
|
||||
}
|
||||
|
||||
result[i].scale = gOneVec;
|
||||
result->rotation.x = bone->rotation.x * (1.0f / 32767.0f);
|
||||
result->rotation.y = bone->rotation.y * (1.0f / 32767.0f);
|
||||
result->rotation.z = bone->rotation.z * (1.0f / 32767.0f);
|
||||
float wSqrd = 1.0f - (result->rotation.x * result->rotation.x + result->rotation.y * result->rotation.y + result->rotation.z * result->rotation.z);
|
||||
if (wSqrd <= 0.0f) {
|
||||
result->rotation.w = 0.0f;
|
||||
} else {
|
||||
result->rotation.w = sqrtf(wSqrd);
|
||||
}
|
||||
}
|
||||
|
||||
void skAnimatorV2ReadTransform(struct SKAnimatorV2* animator, struct Transform* transforms) {
|
||||
void skAnimatorInitZeroTransform(struct SKAnimator* animator, struct Transform* transforms) {
|
||||
if (animator->latestBoneState == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (animator->blendLerp >= 1.0f) {
|
||||
skAnimatorV2Extractstate(animator->boneState[animator->latestBoneState], animator->nBones, transforms);
|
||||
return;
|
||||
}
|
||||
|
||||
struct Transform fromState[animator->nBones];
|
||||
struct Transform toState[animator->nBones];
|
||||
|
||||
skAnimatorV2Extractstate(animator->boneState[animator->latestBoneState], animator->nBones, toState);
|
||||
skAnimatorV2Extractstate(animator->boneState[animator->latestBoneState ^ 1], animator->nBones, fromState);
|
||||
|
||||
for (int i = 0; i < animator->nBones; ++i) {
|
||||
transformLerp(&fromState[i], &toState[i], animator->blendLerp, &transforms[i]);
|
||||
transforms[i].position = gZeroVec;
|
||||
transforms[i].rotation = gQuaternionZero;
|
||||
transforms[i].scale = gOneVec;
|
||||
}
|
||||
}
|
||||
|
||||
void skAnimatorV2Update(struct SKAnimatorV2* animator, struct Transform* transforms, float deltaTime) {
|
||||
void skAnimatorNormalize(struct SKAnimator* animator, struct Transform* transforms) {
|
||||
for (int i = 0; i < animator->nBones; ++i) {
|
||||
quatNormalize(&transforms[i].rotation, &transforms[i].rotation);
|
||||
}
|
||||
}
|
||||
|
||||
void skAnimatorBlendTransform(struct SKAnimationBoneFrame* frame, struct Transform* transforms, int nBones, float weight) {
|
||||
for (int i = 0; i < nBones; ++i) {
|
||||
struct Transform boneTransform;
|
||||
skAnimatorExtractBone(&frame[i], &boneTransform);
|
||||
|
||||
vector3AddScaled(&transforms[i].position, &boneTransform.position, weight, &transforms[i].position);
|
||||
|
||||
transforms[i].rotation.x += boneTransform.rotation.x * weight;
|
||||
transforms[i].rotation.y += boneTransform.rotation.y * weight;
|
||||
transforms[i].rotation.z += boneTransform.rotation.z * weight;
|
||||
transforms[i].rotation.w += boneTransform.rotation.w * weight;
|
||||
}
|
||||
}
|
||||
|
||||
void skAnimatorReadTransformWithWeight(struct SKAnimator* animator, struct Transform* transforms, float weight) {
|
||||
if (animator->blendLerp >= 1.0f) {
|
||||
skAnimatorBlendTransform(animator->boneState[animator->latestBoneState], transforms, animator->nBones, weight);
|
||||
return;
|
||||
}
|
||||
|
||||
skAnimatorBlendTransform(animator->boneState[animator->latestBoneState], transforms, animator->nBones, animator->blendLerp * weight);
|
||||
skAnimatorBlendTransform(animator->boneState[animator->latestBoneState ^ 1], transforms, animator->nBones, (1.0f - animator->blendLerp) * weight);
|
||||
}
|
||||
|
||||
void skAnimatorReadTransform(struct SKAnimator* animator, struct Transform* transforms) {
|
||||
if (animator->latestBoneState == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
skAnimatorInitZeroTransform(animator, transforms);
|
||||
skAnimatorReadTransformWithWeight(animator, transforms, 1.0f);
|
||||
skAnimatorNormalize(animator, transforms);
|
||||
}
|
||||
|
||||
void skAnimatorStep(struct SKAnimator* animator, float deltaTime) {
|
||||
struct SKAnimationClip* currentClip = animator->currentClip;
|
||||
|
||||
if (!currentClip) {
|
||||
return;
|
||||
}
|
||||
|
||||
skAnimatorV2ReadTransform(animator, transforms);
|
||||
|
||||
animator->currentTime += deltaTime;
|
||||
|
||||
float currentFrameFractional = animator->currentTime * currentClip->fps;
|
||||
int currentFrame = (int)ceilf(currentFrameFractional);
|
||||
|
||||
while (currentFrame >= currentClip->nFrames) {
|
||||
if (!(animator->flags & SKAnimatorV2FlagsLoop)) {
|
||||
if (!(animator->flags & SKAnimatorFlagsLoop)) {
|
||||
animator->blendLerp = 1.0f;
|
||||
return;
|
||||
}
|
||||
|
@ -162,10 +187,22 @@ void skAnimatorV2Update(struct SKAnimatorV2* animator, struct Transform* transfo
|
|||
animator->blendLerp = 1.0f;
|
||||
}
|
||||
|
||||
skAnimatorV2RequestNext(animator);
|
||||
skAnimatorRequestNext(animator);
|
||||
}
|
||||
|
||||
void skAnimatorV2RunClip(struct SKAnimatorV2* animator, struct SKAnimationClip* clip, float startTime, int flags) {
|
||||
void skAnimatorUpdate(struct SKAnimator* animator, struct Transform* transforms, float deltaTime) {
|
||||
struct SKAnimationClip* currentClip = animator->currentClip;
|
||||
|
||||
if (!currentClip) {
|
||||
return;
|
||||
}
|
||||
|
||||
skAnimatorReadTransform(animator, transforms);
|
||||
|
||||
skAnimatorStep(animator, deltaTime);
|
||||
}
|
||||
|
||||
void skAnimatorRunClip(struct SKAnimator* animator, struct SKAnimationClip* clip, float startTime, int flags) {
|
||||
animator->currentClip = clip;
|
||||
|
||||
if (!clip) {
|
||||
|
@ -184,7 +221,7 @@ void skAnimatorV2RunClip(struct SKAnimatorV2* animator, struct SKAnimationClip*
|
|||
animator->currentTime = startTime;
|
||||
animator->flags = flags;
|
||||
|
||||
skAnimatorV2RequestNext(animator);
|
||||
skAnimatorRequestNext(animator);
|
||||
}
|
||||
|
||||
static unsigned gSegmentLocations[SK_SEGMENT_COUNT];
|
||||
|
@ -196,4 +233,48 @@ void skSetSegmentLocation(unsigned segmentNumber, unsigned segmentLocation) {
|
|||
u32 skTranslateSegment(unsigned address) {
|
||||
unsigned segment = (address >> 24) & 0xF;
|
||||
return (address & 0xFFFFFF) + gSegmentLocations[segment];
|
||||
}
|
||||
|
||||
void skBlenderInit(struct SKAnimatorBlender* blender, int nBones) {
|
||||
skAnimatorInit(&blender->from, nBones);
|
||||
skAnimatorInit(&blender->to, nBones);
|
||||
blender->blendLerp = 0.0f;
|
||||
}
|
||||
|
||||
void skBlenderApply(struct SKAnimatorBlender* blender, struct Transform* transforms) {
|
||||
float lerp = blender->blendLerp;
|
||||
|
||||
if (blender->from.latestBoneState == -1) {
|
||||
if (blender->to.latestBoneState == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
lerp = 1.0f;
|
||||
}
|
||||
|
||||
if (blender->to.latestBoneState == -1) {
|
||||
lerp = 0.0f;
|
||||
}
|
||||
|
||||
skAnimatorInitZeroTransform(&blender->from, transforms);
|
||||
|
||||
if (lerp == 1.0f) {
|
||||
skAnimatorReadTransformWithWeight(&blender->to, transforms, 1.0f);
|
||||
} else if (lerp == 0.0f) {
|
||||
skAnimatorReadTransformWithWeight(&blender->from, transforms, 1.0f);
|
||||
} else {
|
||||
skAnimatorReadTransformWithWeight(&blender->to, transforms, lerp);
|
||||
skAnimatorReadTransformWithWeight(&blender->from, transforms, 1.0f - lerp);
|
||||
}
|
||||
}
|
||||
|
||||
void skBlenderCleanup(struct SKAnimatorBlender* blender) {
|
||||
skAnimatorCleanup(&blender->from);
|
||||
skAnimatorCleanup(&blender->to);
|
||||
}
|
||||
|
||||
void skBlenderUpdate(struct SKAnimatorBlender* blender, struct Transform* transforms, float deltaTime) {
|
||||
skBlenderApply(blender, transforms);
|
||||
skAnimatorStep(&blender->from, deltaTime);
|
||||
skAnimatorStep(&blender->to, deltaTime);
|
||||
}
|
|
@ -4,11 +4,11 @@
|
|||
#include "skelatool_clip.h"
|
||||
#include "../math/transform.h"
|
||||
|
||||
enum SKAnimatorV2Flags {
|
||||
SKAnimatorV2FlagsLoop = (1 << 0),
|
||||
enum SKAnimatorFlags {
|
||||
SKAnimatorFlagsLoop = (1 << 0),
|
||||
};
|
||||
|
||||
struct SKAnimatorV2 {
|
||||
struct SKAnimator {
|
||||
struct SKAnimationClip* currentClip;
|
||||
float currentTime;
|
||||
float blendLerp;
|
||||
|
@ -19,15 +19,26 @@ struct SKAnimatorV2 {
|
|||
short nBones;
|
||||
};
|
||||
|
||||
void skAnimatorV2Init(struct SKAnimatorV2* animator, int nBones);
|
||||
void skAnimatorV2Cleanup(struct SKAnimatorV2* animator);
|
||||
void skAnimatorV2Update(struct SKAnimatorV2* animator, struct Transform* transforms, float deltaTime);
|
||||
void skAnimatorInit(struct SKAnimator* animator, int nBones);
|
||||
void skAnimatorCleanup(struct SKAnimator* animator);
|
||||
void skAnimatorUpdate(struct SKAnimator* animator, struct Transform* transforms, float deltaTime);
|
||||
|
||||
void skAnimatorV2RunClip(struct SKAnimatorV2* animator, struct SKAnimationClip* clip, float startTime, int flags);
|
||||
void skAnimatorRunClip(struct SKAnimator* animator, struct SKAnimationClip* clip, float startTime, int flags);
|
||||
|
||||
#define SK_SEGMENT_COUNT 16
|
||||
|
||||
void skSetSegmentLocation(unsigned segmentNumber, unsigned segmentLocatoin);
|
||||
u32 skTranslateSegment(unsigned address);
|
||||
|
||||
struct SKAnimatorBlender {
|
||||
struct SKAnimator from;
|
||||
struct SKAnimator to;
|
||||
|
||||
float blendLerp;
|
||||
};
|
||||
|
||||
void skBlenderInit(struct SKAnimatorBlender* blender, int nBones);
|
||||
void skBlenderCleanup(struct SKAnimatorBlender* animator);
|
||||
void skBlenderUpdate(struct SKAnimatorBlender* blender, struct Transform* transforms, float deltaTime);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue