16
0
mirror of https://github.com/MaSzyna-EU07/maszyna.git synced 2026-07-22 13:59:19 +02:00

make TAnimModel possible to delete

This commit is contained in:
milek7
2019-02-23 14:44:21 +01:00
parent 5fe4e1213e
commit cbb61ce639
7 changed files with 69 additions and 79 deletions

View File

@@ -25,11 +25,10 @@ http://mozilla.org/MPL/2.0/.
#include "Logs.h" #include "Logs.h"
#include "renderer.h" #include "renderer.h"
TAnimContainer *TAnimModel::acAnimList = NULL; std::list<std::weak_ptr<TAnimContainer>> TAnimModel::acAnimList;
TAnimContainer::TAnimContainer() TAnimContainer::TAnimContainer()
{ {
pNext = NULL;
vRotateAngles = Math3D::vector3(0.0f, 0.0f, 0.0f); // aktualne kąty obrotu vRotateAngles = Math3D::vector3(0.0f, 0.0f, 0.0f); // aktualne kąty obrotu
vDesiredAngles = Math3D::vector3(0.0f, 0.0f, 0.0f); // docelowe kąty obrotu vDesiredAngles = Math3D::vector3(0.0f, 0.0f, 0.0f); // docelowe kąty obrotu
fRotateSpeed = 0.0; fRotateSpeed = 0.0;
@@ -39,15 +38,7 @@ TAnimContainer::TAnimContainer()
fAngleSpeed = 0.0; fAngleSpeed = 0.0;
pSubModel = NULL; pSubModel = NULL;
iAnim = 0; // położenie początkowe iAnim = 0; // położenie początkowe
mAnim = NULL; // nie ma macierzy obrotu dla submodelu evDone = NULL; // powiadamianie o zakończeniu animacji
evDone = NULL; // powiadamianie o zakończeniu animacji
acAnimNext = NULL; // na razie jest poza listą
}
TAnimContainer::~TAnimContainer()
{
SafeDelete(pNext);
delete mAnim; // AnimContainer jest właścicielem takich macierzy
} }
bool TAnimContainer::Init(TSubModel *pNewSubModel) bool TAnimContainer::Init(TSubModel *pNewSubModel)
@@ -73,9 +64,8 @@ void TAnimContainer::SetRotateAnim( Math3D::vector3 vNewRotateAngles, double fNe
// wyświetlania // wyświetlania
if (iAnim >= 0) if (iAnim >= 0)
{ // jeśli nie jest jeszcze na liście animacyjnej { // jeśli nie jest jeszcze na liście animacyjnej
acAnimNext = TAnimModel::acAnimList; // pozostałe doklić sobie jako ogon TAnimModel::acAnimList.push_back(shared_from_this());
TAnimModel::acAnimList = this; // a wstawić się na początek iAnim |= 0x80000000; // dodany do listy
iAnim |= 0x80000000; // dodany do listy
} }
} }
} }
@@ -96,8 +86,7 @@ void TAnimContainer::SetTranslateAnim( Math3D::vector3 vNewTranslate, double fNe
// wyświetlania // wyświetlania
if (iAnim >= 0) if (iAnim >= 0)
{ // jeśli nie jest jeszcze na liście animacyjnej { // jeśli nie jest jeszcze na liście animacyjnej
acAnimNext = TAnimModel::acAnimList; // pozostałe doklić sobie jako ogon TAnimModel::acAnimList.push_back(shared_from_this());
TAnimModel::acAnimList = this; // a wstawić się na początek
iAnim |= 0x80000000; // dodany do listy iAnim |= 0x80000000; // dodany do listy
} }
} }
@@ -264,11 +253,6 @@ TAnimModel::TAnimModel( scene::node_data const &Nodedata ) : basic_node( Nodedat
m_lightopacities.fill( 1.f ); m_lightopacities.fill( 1.f );
} }
TAnimModel::~TAnimModel()
{
SafeDelete(pRoot);
}
bool TAnimModel::Init(std::string const &asName, std::string const &asReplacableTexture) bool TAnimModel::Init(std::string const &asName, std::string const &asReplacableTexture)
{ {
if( asReplacableTexture.substr( 0, 1 ) == "*" ) { if( asReplacableTexture.substr( 0, 1 ) == "*" ) {
@@ -383,32 +367,32 @@ bool TAnimModel::Load(cParser *parser, bool ter)
return true; return true;
} }
TAnimContainer * TAnimModel::AddContainer(std::string const &Name) std::shared_ptr<TAnimContainer> TAnimModel::AddContainer(std::string const &Name)
{ // dodanie sterowania submodelem dla egzemplarza { // dodanie sterowania submodelem dla egzemplarza
if (!pModel) if (!pModel)
return NULL; return nullptr;
TSubModel *tsb = pModel->GetFromName(Name); TSubModel *tsb = pModel->GetFromName(Name);
if (tsb) if (tsb)
{ {
TAnimContainer *tmp = new TAnimContainer(); auto tmp = std::make_shared<TAnimContainer>();
tmp->Init(tsb); tmp->Init(tsb);
tmp->pNext = pRoot; m_animlist.push_back(tmp);
pRoot = tmp; return tmp;
return tmp;
} }
return NULL; return nullptr;
} }
TAnimContainer * TAnimModel::GetContainer(std::string const &Name) std::shared_ptr<TAnimContainer> TAnimModel::GetContainer(std::string const &Name)
{ // szukanie/dodanie sterowania submodelem dla egzemplarza { // szukanie/dodanie sterowania submodelem dla egzemplarza
if (true == Name.empty()) if (true == Name.empty())
return pRoot; // pobranie pierwszego (dla obrotnicy) return m_animlist.front(); // pobranie pierwszego (dla obrotnicy)
TAnimContainer *pCurrent;
for (pCurrent = pRoot; pCurrent != NULL; pCurrent = pCurrent->pNext) for (auto entry : m_animlist) {
// if (pCurrent->GetName()==pName) if (entry->NameGet() == Name)
if (Name == pCurrent->NameGet()) return entry;
return pCurrent; }
return AddContainer(Name);
return AddContainer(Name);
} }
// przeliczenie animacji - jednorazowo na klatkę // przeliczenie animacji - jednorazowo na klatkę
@@ -485,13 +469,13 @@ void TAnimModel::RaAnimate( unsigned int const Framestamp ) {
} }
// Ra 2F1I: to by można pomijać dla modeli bez animacji, których jest większość // Ra 2F1I: to by można pomijać dla modeli bez animacji, których jest większość
TAnimContainer *pCurrent; for (auto entry : m_animlist) {
for (pCurrent = pRoot; pCurrent != nullptr; pCurrent = pCurrent->pNext) if (!entry->evDone) // jeśli jest bez eventu
if (!pCurrent->evDone) // jeśli jest bez eventu entry->UpdateModel(); // przeliczenie animacji każdego submodelu
pCurrent->UpdateModel(); // przeliczenie animacji każdego submodelu }
m_framestamp = Framestamp; m_framestamp = Framestamp;
}; }
void TAnimModel::RaPrepare() void TAnimModel::RaPrepare()
{ // ustawia światła i animacje we wzorcu modelu przed renderowaniem egzemplarza { // ustawia światła i animacje we wzorcu modelu przed renderowaniem egzemplarza
@@ -555,12 +539,10 @@ void TAnimModel::RaPrepare()
} }
TSubModel::iInstance = reinterpret_cast<std::uintptr_t>( this ); //żeby nie robić cudzych animacji TSubModel::iInstance = reinterpret_cast<std::uintptr_t>( this ); //żeby nie robić cudzych animacji
TSubModel::pasText = &asText; // przekazanie tekstu do wyświetlacza (!!!! do przemyślenia) TSubModel::pasText = &asText; // przekazanie tekstu do wyświetlacza (!!!! do przemyślenia)
TAnimContainer *pCurrent;
for (pCurrent = pRoot; pCurrent != NULL; pCurrent = pCurrent->pNext) for (auto entry : m_animlist) {
pCurrent->PrepareModel(); // ustawienie animacji egzemplarza dla każdego submodelu entry->PrepareModel();
// if () //tylko dla modeli z IK !!!! }
// for (pCurrent=pRoot;pCurrent!=NULL;pCurrent=pCurrent->pNext) //albo osobny łańcuch
// pCurrent->UpdateModelIK(); //przeliczenie odwrotnej kinematyki
} }
int TAnimModel::Flags() int TAnimModel::Flags()
@@ -569,18 +551,19 @@ int TAnimModel::Flags()
if( m_materialdata.replacable_skins[ 1 ] > 0 ) // jeśli ma wymienną teksturę 0 if( m_materialdata.replacable_skins[ 1 ] > 0 ) // jeśli ma wymienną teksturę 0
i |= (i & 0x01010001) * ((m_materialdata.textures_alpha & 1) ? 0x20 : 0x10); i |= (i & 0x01010001) * ((m_materialdata.textures_alpha & 1) ? 0x20 : 0x10);
return i; return i;
}; }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
int TAnimModel::TerrainCount() int TAnimModel::TerrainCount()
{ // zliczanie kwadratów kilometrowych (główna linia po Next) do tworznia tablicy { // zliczanie kwadratów kilometrowych (główna linia po Next) do tworznia tablicy
return pModel ? pModel->TerrainCount() : 0; return pModel ? pModel->TerrainCount() : 0;
}; }
TSubModel * TAnimModel::TerrainSquare(int n) TSubModel * TAnimModel::TerrainSquare(int n)
{ // pobieranie wskaźników do pierwszego submodelu { // pobieranie wskaźników do pierwszego submodelu
return pModel ? pModel->TerrainSquare(n) : 0; return pModel ? pModel->TerrainSquare(n) : 0;
}; }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
void TAnimModel::LightSet(int const n, float const v) void TAnimModel::LightSet(int const n, float const v)
@@ -589,17 +572,20 @@ void TAnimModel::LightSet(int const n, float const v)
return; // przekroczony zakres return; // przekroczony zakres
} }
lsLights[ n ] = v; lsLights[ n ] = v;
}; }
void TAnimModel::AnimUpdate(double dt) void TAnimModel::AnimUpdate(double dt)
{ // wykonanie zakolejkowanych animacji, nawet gdy modele nie są aktualnie wyświetlane { // wykonanie zakolejkowanych animacji, nawet gdy modele nie są aktualnie wyświetlane
TAnimContainer *p = TAnimModel::acAnimList; acAnimList.remove_if([](std::weak_ptr<TAnimContainer> ptr)
while( p ) { {
std::shared_ptr<TAnimContainer> container = ptr.lock();
if (!container)
return true;
p->UpdateModel(); container->UpdateModel(); // na razie bez usuwania z listy, bo głównie obrotnica na nią wchodzi
p = p->acAnimNext; // na razie bez usuwania z listy, bo głównie obrotnica na nią wchodzi return false;
} });
}; }
// radius() subclass details, calculates node's bounding radius // radius() subclass details, calculates node's bounding radius
float float

View File

@@ -45,7 +45,7 @@ class TAnimVocaloidFrame
class basic_event; class basic_event;
class TAnimContainer class TAnimContainer : std::enable_shared_from_this<TAnimContainer>
{ // opakowanie submodelu, określające animację egzemplarza - obsługiwane jako lista { // opakowanie submodelu, określające animację egzemplarza - obsługiwane jako lista
friend TAnimModel; friend TAnimModel;
@@ -62,7 +62,7 @@ class TAnimContainer
float fAngleCurrent; // parametr interpolacyjny: 0=start, 1=docelowy float fAngleCurrent; // parametr interpolacyjny: 0=start, 1=docelowy
float fAngleSpeed; // zmiana parametru interpolacji w sekundach float fAngleSpeed; // zmiana parametru interpolacji w sekundach
TSubModel *pSubModel; TSubModel *pSubModel;
float4x4 *mAnim; // macierz do animacji kwaternionowych std::shared_ptr<float4x4> mAnim; // macierz do animacji kwaternionowych
// dla kinematyki odwróconej używane są kwaterniony // dla kinematyki odwróconej używane są kwaterniony
float fLength; // długość kości dla IK float fLength; // długość kości dla IK
int iAnim; // animacja: +1-obrót Eulera, +2-przesuw, +4-obrót kwaternionem, +8-IK int iAnim; // animacja: +1-obrót Eulera, +2-przesuw, +4-obrót kwaternionem, +8-IK
@@ -71,11 +71,8 @@ class TAnimContainer
//+0x200: drugi stopień IK - dostosować do pozycji potomnego potomnego (wnuka) //+0x200: drugi stopień IK - dostosować do pozycji potomnego potomnego (wnuka)
basic_event *evDone; // ewent wykonywany po zakończeniu animacji, np. zapór, obrotnicy basic_event *evDone; // ewent wykonywany po zakończeniu animacji, np. zapór, obrotnicy
public: public:
TAnimContainer *pNext;
TAnimContainer *acAnimNext; // lista animacji z eventem, które muszą być przeliczane również bez
// wyświetlania // wyświetlania
TAnimContainer(); TAnimContainer();
~TAnimContainer();
bool Init(TSubModel *pNewSubModel); bool Init(TSubModel *pNewSubModel);
inline inline
std::string NameGet() { std::string NameGet() {
@@ -112,14 +109,12 @@ class TAnimModel : public scene::basic_node {
public: public:
// constructors // constructors
explicit TAnimModel( scene::node_data const &Nodedata ); explicit TAnimModel( scene::node_data const &Nodedata );
// destructor
~TAnimModel();
// methods // methods
static void AnimUpdate( double dt ); static void AnimUpdate( double dt );
bool Init(std::string const &asName, std::string const &asReplacableTexture); bool Init(std::string const &asName, std::string const &asReplacableTexture);
bool Load(cParser *parser, bool ter = false); bool Load(cParser *parser, bool ter = false);
TAnimContainer * AddContainer(std::string const &Name); std::shared_ptr<TAnimContainer> AddContainer(std::string const &Name);
TAnimContainer * GetContainer(std::string const &Name = ""); std::shared_ptr<TAnimContainer> GetContainer(std::string const &Name = "");
void LightSet( int const n, float const v ); void LightSet( int const n, float const v );
int TerrainCount(); int TerrainCount();
TSubModel * TerrainSquare(int n); TSubModel * TerrainSquare(int n);
@@ -141,7 +136,10 @@ public:
Angles() const { Angles() const {
return vAngle; } return vAngle; }
// members // members
static TAnimContainer *acAnimList; // lista animacji z eventem, które muszą być przeliczane również bez wyświetlania std::list<std::shared_ptr<TAnimContainer>> m_animlist;
// lista animacji z eventem, które muszą być przeliczane również bez wyświetlania
static std::list<std::weak_ptr<TAnimContainer>> acAnimList;
private: private:
// methods // methods
@@ -158,7 +156,7 @@ private:
void export_as_text_( std::ostream &Output ) const; void export_as_text_( std::ostream &Output ) const;
// members // members
TAnimContainer *pRoot { nullptr }; // pojemniki sterujące, tylko dla aniomowanych submodeli std::shared_ptr<TAnimContainer> pRoot; // pojemniki sterujące, tylko dla aniomowanych submodeli
TModel3d *pModel { nullptr }; TModel3d *pModel { nullptr };
glm::vec3 vAngle; // bazowe obroty egzemplarza względem osi glm::vec3 vAngle; // bazowe obroty egzemplarza względem osi
material_data m_materialdata; material_data m_materialdata;

View File

@@ -1291,8 +1291,8 @@ animation_event::init() {
for( auto &target : m_targets ) { for( auto &target : m_targets ) {
auto *targetmodel { static_cast<TAnimModel *>( std::get<scene::basic_node *>( target ) ) }; auto *targetmodel { static_cast<TAnimModel *>( std::get<scene::basic_node *>( target ) ) };
if( targetmodel == nullptr ) { continue; } if( targetmodel == nullptr ) { continue; }
auto *targetcontainer{ targetmodel->GetContainer( m_animationsubmodel ) }; auto targetcontainer{ targetmodel->GetContainer( m_animationsubmodel ) };
if( targetcontainer == nullptr ) { if( !targetcontainer ) {
m_ignored = true; m_ignored = true;
ErrorLog( "Bad event: \"" + m_name + "\" (type: " + type() + ") can't find submodel " + m_animationsubmodel + " in model instance \"" + targetmodel->name() + "\"" ); ErrorLog( "Bad event: \"" + m_name + "\" (type: " + type() + ") can't find submodel " + m_animationsubmodel + " in model instance \"" + targetmodel->name() + "\"" );
break; break;
@@ -1399,7 +1399,12 @@ animation_event::run_() {
WriteLog( "Type: Animation" ); WriteLog( "Type: Animation" );
// animation modes target specific submodels // animation modes target specific submodels
for( auto *targetcontainer : m_animationcontainers ) { m_animationcontainers.remove_if([this](std::weak_ptr<TAnimContainer> ptr)
{
auto targetcontainer = ptr.lock();
if (!targetcontainer)
return true;
switch( m_animationtype ) { switch( m_animationtype ) {
case 1: { // rotate case 1: { // rotate
targetcontainer->SetRotateAnim( targetcontainer->SetRotateAnim(
@@ -1418,7 +1423,8 @@ animation_event::run_() {
break; break;
} }
} }
} return false;
});
} }
// export_as_text() subclass details // export_as_text() subclass details

View File

@@ -390,7 +390,7 @@ private:
int m_animationtype{ 0 }; int m_animationtype{ 0 };
std::array<double, 4> m_animationparams{ 0.0 }; std::array<double, 4> m_animationparams{ 0.0 };
std::string m_animationsubmodel; std::string m_animationsubmodel;
std::vector<TAnimContainer *> m_animationcontainers; std::list<std::weak_ptr<TAnimContainer>> m_animationcontainers;
std::string m_animationfilename; std::string m_animationfilename;
std::size_t m_animationfilesize{ 0 }; std::size_t m_animationfilesize{ 0 };
char *m_animationfiledata{ nullptr }; char *m_animationfiledata{ nullptr };

View File

@@ -1036,8 +1036,8 @@ void TSubModel::RaAnimation(glm::mat4 &m, TAnimType a)
} }
if (mAnimMatrix) // można by to dać np. do at_Translate if (mAnimMatrix) // można by to dać np. do at_Translate
{ {
m *= glm::make_mat4(mAnimMatrix->e); m *= glm::make_mat4(mAnimMatrix.get()->e);
mAnimMatrix = NULL; // jak animator będzie potrzebował, to ustawi ponownie mAnimMatrix.reset(); // jak animator będzie potrzebował, to ustawi ponownie
} }
}; };

View File

@@ -137,7 +137,7 @@ public: // chwilowo
float m_boundingradius { 0 }; float m_boundingradius { 0 };
std::uintptr_t iAnimOwner{ 0 }; // roboczy numer egzemplarza, który ustawił animację std::uintptr_t iAnimOwner{ 0 }; // roboczy numer egzemplarza, który ustawił animację
TAnimType b_aAnim{ TAnimType::at_None }; // kody animacji oddzielnie, bo zerowane TAnimType b_aAnim{ TAnimType::at_None }; // kody animacji oddzielnie, bo zerowane
float4x4 *mAnimMatrix{ nullptr }; // macierz do animacji kwaternionowych (należy do AnimContainer) std::shared_ptr<float4x4> mAnimMatrix; // macierz do animacji kwaternionowych
TSubModel **smLetter{ nullptr }; // wskaźnik na tablicę submdeli do generoania tekstu (docelowo zapisać do E3D) TSubModel **smLetter{ nullptr }; // wskaźnik na tablicę submdeli do generoania tekstu (docelowo zapisać do E3D)
TSubModel *Parent{ nullptr }; // nadrzędny, np. do wymnażania macierzy TSubModel *Parent{ nullptr }; // nadrzędny, np. do wymnażania macierzy
int iVisible { 1 }; // roboczy stan widoczności int iVisible { 1 }; // roboczy stan widoczności

View File

@@ -1101,7 +1101,7 @@ bool TTrack::InMovement()
if (!SwitchExtension->CurrentIndex) if (!SwitchExtension->CurrentIndex)
return false; // 0=zablokowana się nie animuje return false; // 0=zablokowana się nie animuje
// trzeba każdorazowo porównywać z kątem modelu // trzeba każdorazowo porównywać z kątem modelu
TAnimContainer *ac = ( auto ac = (
SwitchExtension->pModel ? SwitchExtension->pModel ?
SwitchExtension->pModel->GetContainer() : SwitchExtension->pModel->GetContainer() :
nullptr ); nullptr );
@@ -1883,7 +1883,7 @@ TTrack * TTrack::RaAnimate()
SwitchExtension->CurrentIndex) // 0=zablokowana się nie animuje SwitchExtension->CurrentIndex) // 0=zablokowana się nie animuje
{ // trzeba każdorazowo porównywać z kątem modelu { // trzeba każdorazowo porównywać z kątem modelu
// //pobranie kąta z modelu // //pobranie kąta z modelu
TAnimContainer *ac = ( auto ac = (
SwitchExtension->pModel ? SwitchExtension->pModel ?
SwitchExtension->pModel->GetContainer() : // pobranie głównego submodelu SwitchExtension->pModel->GetContainer() : // pobranie głównego submodelu
nullptr ); nullptr );