| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- #include "AnimationProcedural.h"
- #include "AnimationService.h"
- dword AnimationProcedural::filesCounter[4] = {0, 0, 0, 0};
- AnimationProcedural::AnimationProcedural(AnimationScene & s, const IAnimationScene::Bone * skeleton, dword count, const char * _cppFile, long _cppLine) : scene(s)
- {
- Assert(skeleton);
- Assert(count > 0);
- Assert(count <= 256);
- refCounter = 1;
- bonesCount = count;
- //Создаём имя анимации
- string name = "*ProceduralFile";
- for(long i = 0, add = 1; i < ARRSIZE(filesCounter); i++)
- {
- name += '_';
- name += filesCounter[i];
- if(add)
- {
- add = (filesCounter[i] == 0xffffffff);
- filesCounter[i]++;
- }
- }
- //Вычисляем требуемый размер массива
- dword size = count*(sizeof(Matrix) + sizeof(BoneDesc)) + name.Len() + 0x20;
- for(dword i = 0; i < count; i++)
- {
- size += string::Len(skeleton[i].name) + 1;
- }
- buffer = NEW byte[size];
- memcpy(buffer, name.c_str(), name.Len() + 1);
- matrices = (Matrix *)(((__int64)buffer + name.Len() + 16) & ~0xf);
- bones = (BoneDesc *)(matrices + count);
- char * names = (char *)(bones + count);
- for(dword i = 0; i < count; i++)
- {
- matrices[i] = skeleton[i].mtx;
- BoneDesc & bone = bones[i];
- bone.parent = skeleton[i].parentIndex;
- bone.longName.name = names;
- bone.shortName.name = names;
- for(const char * src = skeleton[i].name; *src; *names++ = *src++)
- {
- if(*src == '|')
- {
- bone.shortName.name = names + 1;
- }
- }
- *names++ = 0;
- bones[i].longName.hash = string::HashNoCase(bones[i].longName.name);
- bones[i].shortName.hash = string::HashNoCase(bones[i].shortName.name);
- }
- Assert((byte *)names - buffer < (long)size);
- cppFile = _cppFile;
- cppLine = _cppLine;
- }
- AnimationProcedural::~AnimationProcedural()
- {
- AssertCoreThread
- delete buffer;
- matrices = null;
- bones = null;
- bonesCount = 0;
- buffer = null;
- scene.Delete(this);
- }
- //Получить имя анимации
- const char * AnimationProcedural::GetName()
- {
- return (const char *)buffer;
- }
- //Копировать интерфейс
- IAnimationTransform * AnimationProcedural::Clone()
- {
- Assert(refCounter > 0);
- refCounter++;
- return this;
- }
- //Удалить интерфейс
- void AnimationProcedural::Release()
- {
- Assert(refCounter > 0);
- refCounter--;
- if(refCounter <= 0)
- {
- delete this;
- }
- }
- //Удалить интерфейс принудительно
- void AnimationProcedural::ForceRelease()
- {
- api->Trace("Animation -> Don't release procedural animation (cpp: %s, %u)", cppFile, cppLine);
- refCounter = 1;
- Release();
- }
- //Получить количество костей в анимации
- long AnimationProcedural::GetNumBones()
- {
- return bonesCount;
- }
- //Получить имя кости
- const char * AnimationProcedural::GetBoneName(long index)
- {
- Assert(index >= 0 && index < bonesCount);
- return bones[index].longName.name;
- }
- //Получить индекс родительской кости
- long AnimationProcedural::GetBoneParent(long index)
- {
- Assert(index >= 0 && index < bonesCount);
- return bones[index].parent;
- }
- //Найти по имени кость
- long AnimationProcedural::FindBone(const char * boneName, bool shortName)
- {
- if(!boneName || !boneName[0]) return -1;
- dword hash = string::HashNoCase(boneName);
- for(long i = 0; i < bonesCount; i++)
- {
- Name & name = shortName ? bones[i].shortName : bones[i].longName;
- if(name.hash == hash)
- {
- if(string::IsEqual(name.name, boneName))
- {
- return i;
- }
- }
- }
- return -1;
- }
- //Найти по имени кость (короткое имя)
- long AnimationProcedural::FindBoneUseHash(const char * boneName, dword hash)
- {
- for(long i = 0; i < bonesCount; i++)
- {
- if(bones[i].longName.hash == hash)
- {
- if(string::IsEqual(bones[i].longName.name, boneName))
- {
- return i;
- }
- }
- }
- return -1;
- }
- //Получить матрицу кости с учётом иерархии
- const Matrix & AnimationProcedural::GetBoneMatrix(long index)
- {
- Assert(index >= 0 && index < bonesCount);
- return matrices[index];
- }
- //Получить массив матриц с учётом иерархии
- const Matrix * AnimationProcedural::GetBoneMatrices()
- {
- return matrices;
- }
- //Установить пользовательскую матрицу кости
- void AnimationProcedural::SetBoneMatrix(long index, const Matrix & mtx)
- {
- Assert(index >= 0 && index < bonesCount);
- matrices[index] = mtx;
- }
- //Установить нулевую матрицу кости
- void AnimationProcedural::CollapseBone(long index)
- {
- Assert(index >= 0 && index < bonesCount);
- matrices[index].SetZero();
- }
|