Changeset View
Changeset View
Standalone View
Standalone View
ps/trunk/source/graphics/SkeletonAnimDef.cpp
/* Copyright (C) 2009 Wildfire Games. | /* Copyright (C) 2021 Wildfire Games. | ||||
* This file is part of 0 A.D. | * This file is part of 0 A.D. | ||||
* | * | ||||
* 0 A.D. is free software: you can redistribute it and/or modify | * 0 A.D. is free software: you can redistribute it and/or modify | ||||
* it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | ||||
* the Free Software Foundation, either version 2 of the License, or | * the Free Software Foundation, either version 2 of the License, or | ||||
* (at your option) any later version. | * (at your option) any later version. | ||||
* | * | ||||
* 0 A.D. is distributed in the hope that it will be useful, | * 0 A.D. is distributed in the hope that it will be useful, | ||||
Show All 10 Lines | |||||
*/ | */ | ||||
#include "precompiled.h" | #include "precompiled.h" | ||||
#include "SkeletonAnimDef.h" | #include "SkeletonAnimDef.h" | ||||
#include "maths/MathUtil.h" | #include "maths/MathUtil.h" | ||||
#include "maths/Matrix3D.h" | #include "maths/Matrix3D.h" | ||||
#include "ps/CStr.h" | #include "ps/CStr.h" | ||||
#include "ps/CLogger.h" | |||||
#include "ps/FileIo.h" | #include "ps/FileIo.h" | ||||
// Start IDs at 1 to leave 0 as a special value. | |||||
u32 CSkeletonAnimDef::nextUID = 1; | |||||
/////////////////////////////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////////////////////////////// | ||||
// CSkeletonAnimDef constructor | // CSkeletonAnimDef constructor | ||||
CSkeletonAnimDef::CSkeletonAnimDef() : m_FrameTime(0), m_NumKeys(0), m_NumFrames(0), m_Keys(0) | CSkeletonAnimDef::CSkeletonAnimDef() : m_FrameTime(0), m_NumKeys(0), m_NumFrames(0) | ||||
{ | { | ||||
m_UID = nextUID++; | |||||
// Log a warning if we ever overflow. Should that not result from a bug, bumping to u64 ought to suffice. | |||||
if (nextUID == 0) | |||||
{ | |||||
// Reset to 1. | |||||
nextUID++; | |||||
LOGWARNING("CSkeletonAnimDef unique ID overflowed to 0 - model-animation bounds may be incorrect."); | |||||
} | |||||
} | } | ||||
/////////////////////////////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////////////////////////////// | ||||
// CSkeletonAnimDef destructor | // CSkeletonAnimDef destructor | ||||
CSkeletonAnimDef::~CSkeletonAnimDef() | CSkeletonAnimDef::~CSkeletonAnimDef() | ||||
{ | { | ||||
delete[] m_Keys; | |||||
} | } | ||||
/////////////////////////////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////////////////////////////// | ||||
// BuildBoneMatrices: build matrices for all bones at the given time (in MS) in this | // BuildBoneMatrices: build matrices for all bones at the given time (in MS) in this | ||||
// animation | // animation | ||||
void CSkeletonAnimDef::BuildBoneMatrices(float time, CMatrix3D* matrices, bool loop) const | void CSkeletonAnimDef::BuildBoneMatrices(float time, CMatrix3D* matrices, bool loop) const | ||||
{ | { | ||||
float fstartframe = time/m_FrameTime; | float fstartframe = time/m_FrameTime; | ||||
Show All 34 Lines | for (size_t i = 0; i < m_NumKeys; i++) | ||||
rot.ToMatrix(matrices[i]); | rot.ToMatrix(matrices[i]); | ||||
matrices[i].Translate(trans); | matrices[i].Translate(trans); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/////////////////////////////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////////////////////////////// | ||||
// Load: try to load the anim from given file; return a new anim if successful | // Load: try to load the anim from given file; return a new anim if successful | ||||
CSkeletonAnimDef* CSkeletonAnimDef::Load(const VfsPath& filename) | std::unique_ptr<CSkeletonAnimDef> CSkeletonAnimDef::Load(const VfsPath& filename) | ||||
{ | { | ||||
CFileUnpacker unpacker; | CFileUnpacker unpacker; | ||||
unpacker.Read(filename,"PSSA"); | unpacker.Read(filename,"PSSA"); | ||||
// check version | // check version | ||||
if (unpacker.GetVersion()<FILE_READ_VERSION) { | if (unpacker.GetVersion()<FILE_READ_VERSION) { | ||||
throw PSERROR_File_InvalidVersion(); | throw PSERROR_File_InvalidVersion(); | ||||
} | } | ||||
// unpack the data | // unpack the data | ||||
CSkeletonAnimDef* anim=new CSkeletonAnimDef; | auto anim = std::make_unique<CSkeletonAnimDef>(); | ||||
try { | try { | ||||
CStr name; // unused - just here to maintain compatibility with the animation files | CStr name; // unused - just here to maintain compatibility with the animation files | ||||
unpacker.UnpackString(name); | unpacker.UnpackString(name); | ||||
unpacker.UnpackRaw(&anim->m_FrameTime,sizeof(anim->m_FrameTime)); | unpacker.UnpackRaw(&anim->m_FrameTime,sizeof(anim->m_FrameTime)); | ||||
anim->m_NumKeys = unpacker.UnpackSize(); | anim->m_NumKeys = unpacker.UnpackSize(); | ||||
anim->m_NumFrames = unpacker.UnpackSize(); | anim->m_NumFrames = unpacker.UnpackSize(); | ||||
anim->m_Keys=new Key[anim->m_NumKeys*anim->m_NumFrames]; | anim->m_Keys.resize(anim->m_NumKeys*anim->m_NumFrames); | ||||
unpacker.UnpackRaw(anim->m_Keys,anim->m_NumKeys*anim->m_NumFrames*sizeof(Key)); | unpacker.UnpackRaw(anim->m_Keys.data(), anim->m_Keys.size() * sizeof(decltype(anim->m_Keys)::value_type)); | ||||
} catch (PSERROR_File&) { | } catch (PSERROR_File&) { | ||||
delete anim; | anim.reset(); | ||||
throw; | throw; | ||||
} | } | ||||
return anim; | return anim; | ||||
} | } | ||||
/////////////////////////////////////////////////////////////////////////////////////////// | /////////////////////////////////////////////////////////////////////////////////////////// | ||||
// Save: try to save anim to file | // Save: try to save anim to file | ||||
void CSkeletonAnimDef::Save(const VfsPath& pathname,const CSkeletonAnimDef* anim) | void CSkeletonAnimDef::Save(const VfsPath& pathname, const CSkeletonAnimDef& anim) | ||||
{ | { | ||||
CFilePacker packer(FILE_VERSION, "PSSA"); | CFilePacker packer(FILE_VERSION, "PSSA"); | ||||
// pack up all the data | // pack up all the data | ||||
packer.PackString(""); | packer.PackString(""); | ||||
packer.PackRaw(&anim->m_FrameTime,sizeof(anim->m_FrameTime)); | packer.PackRaw(&anim.m_FrameTime,sizeof(anim.m_FrameTime)); | ||||
const size_t numKeys = anim->m_NumKeys; | const size_t numKeys = anim.m_NumKeys; | ||||
packer.PackSize(numKeys); | packer.PackSize(numKeys); | ||||
const size_t numFrames = anim->m_NumFrames; | const size_t numFrames = anim.m_NumFrames; | ||||
packer.PackSize(numFrames); | packer.PackSize(numFrames); | ||||
packer.PackRaw(anim->m_Keys,numKeys*numFrames*sizeof(Key)); | packer.PackRaw(anim.m_Keys.data(), anim.m_Keys.size() * sizeof(decltype(anim.m_Keys)::value_type)); | ||||
// now write it | // now write it | ||||
packer.Write(pathname); | packer.Write(pathname); | ||||
} | } |
Wildfire Games · Phabricator