mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 18:39:18 +02:00
Merge branch 'nodecloner' into sim
This commit is contained in:
102
AnimModel.cpp
102
AnimModel.cpp
@@ -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.empty()) ? m_animlist.front() : nullptr; // 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,7 +572,7 @@ void TAnimModel::LightSet(int const n, float const v)
|
|||||||
return; // przekroczony zakres
|
return; // przekroczony zakres
|
||||||
}
|
}
|
||||||
lsLights[ n ] = v;
|
lsLights[ n ] = v;
|
||||||
};
|
}
|
||||||
|
|
||||||
std::optional<std::tuple<float, float, std::optional<glm::vec3>> > TAnimModel::LightGet(const int n)
|
std::optional<std::tuple<float, float, std::optional<glm::vec3>> > TAnimModel::LightGet(const int n)
|
||||||
{
|
{
|
||||||
@@ -611,13 +594,16 @@ std::optional<std::tuple<float, float, std::optional<glm::vec3>> > TAnimModel::L
|
|||||||
|
|
||||||
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
|
||||||
|
|||||||
22
AnimModel.h
22
AnimModel.h
@@ -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 );
|
||||||
std::optional<std::tuple<float, float, std::optional<glm::vec3> > > LightGet( int const n );
|
std::optional<std::tuple<float, float, std::optional<glm::vec3> > > LightGet( int const n );
|
||||||
int TerrainCount();
|
int TerrainCount();
|
||||||
@@ -142,7 +137,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
|
||||||
@@ -159,7 +157,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;
|
||||||
|
|||||||
14
Event.cpp
14
Event.cpp
@@ -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
|
||||||
|
|||||||
2
Event.h
2
Event.h
@@ -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 };
|
||||||
|
|||||||
@@ -1060,8 +1060,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
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
11
Names.h
11
Names.h
@@ -69,6 +69,17 @@ public:
|
|||||||
lookup->second :
|
lookup->second :
|
||||||
-1 );
|
-1 );
|
||||||
}
|
}
|
||||||
|
void purge (Type_ *Item)
|
||||||
|
{
|
||||||
|
for (auto it = m_items.begin(); it != m_items.end(); it++) {
|
||||||
|
if (*it == Item) {
|
||||||
|
delete *it;
|
||||||
|
*it = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// locates item with specified name. returns pointer to the item, or nullptr
|
// locates item with specified name. returns pointer to the item, or nullptr
|
||||||
Type_ *
|
Type_ *
|
||||||
find( std::string const &Name ) const {
|
find( std::string const &Name ) const {
|
||||||
|
|||||||
@@ -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 );
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "Console.h"
|
#include "Console.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
|
#include "AnimModel.h"
|
||||||
|
|
||||||
bool
|
bool
|
||||||
editor_mode::editormode_input::init() {
|
editor_mode::editormode_input::init() {
|
||||||
@@ -179,6 +180,22 @@ editor_mode::on_key( int const Key, int const Scancode, int const Action, int co
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case GLFW_KEY_DELETE: {
|
||||||
|
TAnimModel *model = dynamic_cast<TAnimModel*>(m_node);
|
||||||
|
if (!model)
|
||||||
|
break;
|
||||||
|
|
||||||
|
m_node = nullptr;
|
||||||
|
m_dragging = false;
|
||||||
|
Application.set_cursor( GLFW_CURSOR_NORMAL );
|
||||||
|
static_cast<editor_ui*>( m_userinterface.get() )->set_node(nullptr);
|
||||||
|
|
||||||
|
simulation::Region->erase(model);
|
||||||
|
simulation::Instances.purge(model);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -229,19 +246,75 @@ editor_mode::on_mouse_button( int const Button, int const Action, int const Mods
|
|||||||
if( Button == GLFW_MOUSE_BUTTON_LEFT ) {
|
if( Button == GLFW_MOUSE_BUTTON_LEFT ) {
|
||||||
|
|
||||||
if( Action == GLFW_PRESS ) {
|
if( Action == GLFW_PRESS ) {
|
||||||
// left button press
|
// left button press
|
||||||
GfxRenderer.pick_node([this](scene::basic_node *node)
|
auto const mode = static_cast<editor_ui*>( m_userinterface.get() )->mode();
|
||||||
{
|
|
||||||
if (!m_dragging)
|
m_node = nullptr;
|
||||||
return;
|
|
||||||
m_node = node;
|
GfxRenderer.pick_node([this, mode](scene::basic_node *node)
|
||||||
if( m_node )
|
{
|
||||||
Application.set_cursor( GLFW_CURSOR_DISABLED );
|
editor_ui *ui = static_cast<editor_ui*>( m_userinterface.get() );
|
||||||
else
|
|
||||||
m_dragging = false;
|
if (mode == nodebank_panel::MODIFY) {
|
||||||
dynamic_cast<editor_ui*>( m_userinterface.get() )->set_node( m_node );
|
if (!m_dragging)
|
||||||
});
|
return;
|
||||||
m_dragging = true;
|
|
||||||
|
m_node = node;
|
||||||
|
if( m_node )
|
||||||
|
Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||||
|
else
|
||||||
|
m_dragging = false;
|
||||||
|
ui->set_node( m_node );
|
||||||
|
}
|
||||||
|
else if (mode == nodebank_panel::COPY) {
|
||||||
|
if (node && typeid(*node) == typeid(TAnimModel)) {
|
||||||
|
std::string as_text;
|
||||||
|
node->export_as_text(as_text);
|
||||||
|
|
||||||
|
ui->add_node_template(as_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_dragging = false;
|
||||||
|
}
|
||||||
|
else if (mode == nodebank_panel::ADD) {
|
||||||
|
const std::string *src = ui->get_active_node_template();
|
||||||
|
|
||||||
|
if (!src)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cParser parser(*src);
|
||||||
|
parser.getTokens(); // "node"
|
||||||
|
parser.getTokens(2); // ranges
|
||||||
|
|
||||||
|
scene::node_data nodedata;
|
||||||
|
parser >> nodedata.range_max >> nodedata.range_min;
|
||||||
|
|
||||||
|
parser.getTokens(2); // name, type
|
||||||
|
nodedata.name = "editor_" + std::to_string(LocalRandom(0.0, 100000.0));
|
||||||
|
nodedata.type = "model";
|
||||||
|
|
||||||
|
scene::scratch_data scratch;
|
||||||
|
|
||||||
|
TAnimModel *cloned = simulation::State.deserialize_model(parser, scratch, nodedata);
|
||||||
|
|
||||||
|
if (!cloned)
|
||||||
|
return;
|
||||||
|
|
||||||
|
cloned->mark_dirty();
|
||||||
|
cloned->location(Camera.Pos + GfxRenderer.Mouse_Position());
|
||||||
|
simulation::Instances.insert(cloned);
|
||||||
|
simulation::Region->insert(cloned);
|
||||||
|
|
||||||
|
if (!m_dragging)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_node = cloned;
|
||||||
|
Application.set_cursor( GLFW_CURSOR_DISABLED );
|
||||||
|
ui->set_node( m_node );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
m_dragging = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// left button release
|
// left button release
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ editor_ui::editor_ui() {
|
|||||||
clear_panels();
|
clear_panels();
|
||||||
// bind the panels with ui object. maybe not the best place for this but, eh
|
// bind the panels with ui object. maybe not the best place for this but, eh
|
||||||
push_back( &m_itempropertiespanel );
|
push_back( &m_itempropertiespanel );
|
||||||
|
push_back( &m_nodebankpanel );
|
||||||
}
|
}
|
||||||
|
|
||||||
// potentially processes provided input key. returns: true if key was processed, false otherwise
|
// potentially processes provided input key. returns: true if key was processed, false otherwise
|
||||||
@@ -54,3 +55,28 @@ editor_ui::set_node( scene::basic_node * Node ) {
|
|||||||
|
|
||||||
m_node = Node;
|
m_node = Node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
nodebank_panel::edit_mode
|
||||||
|
editor_ui::mode() {
|
||||||
|
return m_nodebankpanel.mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
editor_ui::add_node_template(const std::string &desc) {
|
||||||
|
m_nodebankpanel.add_template(desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string *editor_ui::get_active_node_template() {
|
||||||
|
return m_nodebankpanel.get_active_template();
|
||||||
|
}
|
||||||
|
|
||||||
|
void editor_ui::render_menu_contents() {
|
||||||
|
ui_layer::render_menu_contents();
|
||||||
|
|
||||||
|
if (ImGui::BeginMenu(locale::strings[locale::string::ui_mode_windows].c_str()))
|
||||||
|
{
|
||||||
|
ImGui::MenuItem(m_nodebankpanel.title.c_str(), nullptr, &m_nodebankpanel.is_open);
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -32,9 +32,19 @@ public:
|
|||||||
update() override;
|
update() override;
|
||||||
void
|
void
|
||||||
set_node( scene::basic_node * Node );
|
set_node( scene::basic_node * Node );
|
||||||
|
nodebank_panel::edit_mode
|
||||||
|
mode();
|
||||||
|
void
|
||||||
|
add_node_template(const std::string &desc);
|
||||||
|
const std::string *
|
||||||
|
get_active_node_template();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void render_menu_contents();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// members
|
// members
|
||||||
itemproperties_panel m_itempropertiespanel { "Node Properties", true };
|
itemproperties_panel m_itempropertiespanel { "Node Properties", true };
|
||||||
|
nodebank_panel m_nodebankpanel;
|
||||||
scene::basic_node * m_node { nullptr }; // currently bound scene node, if any
|
scene::basic_node * m_node { nullptr }; // currently bound scene node, if any
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -281,3 +281,50 @@ itemproperties_panel::render_group() {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nodebank_panel::nodebank_panel() : ui_panel("nodebank", true) {
|
||||||
|
size_min = { 100, 50 };
|
||||||
|
size_max = { 1000, 1000 };
|
||||||
|
title = "nodebank";
|
||||||
|
|
||||||
|
std::ifstream file;
|
||||||
|
file.open("nodebank.txt", std::ios_base::in | std::ios_base::binary);
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(file, line))
|
||||||
|
if (line.size() > 2)
|
||||||
|
m_nodebank.push_back(std::make_unique<std::string>(line));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nodebank_panel::render_contents() {
|
||||||
|
ImGui::RadioButton("modify", (int*)&mode, MODIFY);
|
||||||
|
ImGui::RadioButton("clone", (int*)&mode, COPY);
|
||||||
|
ImGui::RadioButton("add", (int*)&mode, ADD);
|
||||||
|
|
||||||
|
ImGui::PushItemWidth(-1);
|
||||||
|
if (ImGui::ListBoxHeader("##nodebank", ImVec2(-1, -1)))
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
for (auto const entry : m_nodebank) {
|
||||||
|
std::string label = *entry + "##" + std::to_string(i);
|
||||||
|
if (ImGui::Selectable(label.c_str(), entry == m_selectedtemplate))
|
||||||
|
m_selectedtemplate = entry;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::ListBoxFooter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void nodebank_panel::add_template(const std::string &desc) {
|
||||||
|
std::ofstream file;
|
||||||
|
file.open("nodebank.txt", std::ios_base::out | std::ios_base::app | std::ios_base::binary);
|
||||||
|
file << desc;
|
||||||
|
|
||||||
|
m_nodebank.push_back(std::make_unique<std::string>(desc));
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string *nodebank_panel::get_active_template() {
|
||||||
|
return m_selectedtemplate.get();
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,3 +33,23 @@ private:
|
|||||||
std::string m_groupprefix;
|
std::string m_groupprefix;
|
||||||
std::vector<text_line> m_grouplines;
|
std::vector<text_line> m_grouplines;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class nodebank_panel : public ui_panel {
|
||||||
|
std::vector<std::shared_ptr<std::string>> m_nodebank;
|
||||||
|
std::shared_ptr<std::string> m_selectedtemplate;
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum edit_mode {
|
||||||
|
MODIFY,
|
||||||
|
COPY,
|
||||||
|
ADD
|
||||||
|
};
|
||||||
|
|
||||||
|
edit_mode mode = MODIFY;
|
||||||
|
|
||||||
|
nodebank_panel();
|
||||||
|
|
||||||
|
void render_contents() override;
|
||||||
|
void add_template(const std::string &desc);
|
||||||
|
const std::string* get_active_template();
|
||||||
|
};
|
||||||
|
|||||||
@@ -23,7 +23,16 @@ namespace scene {
|
|||||||
void
|
void
|
||||||
basic_editor::translate( scene::basic_node *Node, glm::dvec3 const &Location, bool const Snaptoground ) {
|
basic_editor::translate( scene::basic_node *Node, glm::dvec3 const &Location, bool const Snaptoground ) {
|
||||||
|
|
||||||
auto const initiallocation { Node->location() };
|
auto &initiallocation { Node->location() };
|
||||||
|
|
||||||
|
// fixup NaNs
|
||||||
|
if (std::isnan(initiallocation.x))
|
||||||
|
initiallocation.x = Location.x;
|
||||||
|
if (std::isnan(initiallocation.y))
|
||||||
|
initiallocation.y = Location.y;
|
||||||
|
if (std::isnan(initiallocation.z))
|
||||||
|
initiallocation.z = Location.z;
|
||||||
|
|
||||||
auto targetlocation { Location };
|
auto targetlocation { Location };
|
||||||
if( false == Snaptoground ) {
|
if( false == Snaptoground ) {
|
||||||
targetlocation.y = initiallocation.y;
|
targetlocation.y = initiallocation.y;
|
||||||
@@ -31,6 +40,7 @@ basic_editor::translate( scene::basic_node *Node, glm::dvec3 const &Location, bo
|
|||||||
// NOTE: bit of a waste for single nodes, for the sake of less varied code down the road
|
// NOTE: bit of a waste for single nodes, for the sake of less varied code down the road
|
||||||
auto const translation { targetlocation - initiallocation };
|
auto const translation { targetlocation - initiallocation };
|
||||||
|
|
||||||
|
Node->mark_dirty();
|
||||||
if( Node->group() == null_handle ) {
|
if( Node->group() == null_handle ) {
|
||||||
translate_node( Node, Node->location() + translation );
|
translate_node( Node, Node->location() + translation );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -743,7 +743,7 @@ basic_node::export_as_text( std::ostream &Output ) const {
|
|||||||
<< ' ' << ( m_rangesquaredmax < std::numeric_limits<double>::max() ? std::sqrt( m_rangesquaredmax ) : -1 )
|
<< ' ' << ( m_rangesquaredmax < std::numeric_limits<double>::max() ? std::sqrt( m_rangesquaredmax ) : -1 )
|
||||||
<< ' ' << std::sqrt( m_rangesquaredmin )
|
<< ' ' << std::sqrt( m_rangesquaredmin )
|
||||||
// name
|
// name
|
||||||
<< ' ' << m_name << ' ';
|
<< ' ' << ((m_name.length() > 0) ? m_name : "none") << ' ';
|
||||||
// template method implementation
|
// template method implementation
|
||||||
export_as_text_( Output );
|
export_as_text_( Output );
|
||||||
}
|
}
|
||||||
|
|||||||
13
scenenode.h
13
scenenode.h
@@ -333,6 +333,8 @@ public:
|
|||||||
location( glm::dvec3 const Location );
|
location( glm::dvec3 const Location );
|
||||||
glm::dvec3 const &
|
glm::dvec3 const &
|
||||||
location() const;
|
location() const;
|
||||||
|
glm::dvec3 &
|
||||||
|
location();
|
||||||
float const &
|
float const &
|
||||||
radius();
|
radius();
|
||||||
void
|
void
|
||||||
@@ -343,6 +345,10 @@ public:
|
|||||||
group( scene::group_handle Group );
|
group( scene::group_handle Group );
|
||||||
scene::group_handle
|
scene::group_handle
|
||||||
group() const;
|
group() const;
|
||||||
|
void
|
||||||
|
mark_dirty() { m_dirty = true; }
|
||||||
|
bool
|
||||||
|
dirty() const { return m_dirty; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// members
|
// members
|
||||||
@@ -352,6 +358,7 @@ protected:
|
|||||||
double m_rangesquaredmax { 0.0 }; // visibility range, max
|
double m_rangesquaredmax { 0.0 }; // visibility range, max
|
||||||
bool m_visible { true }; // visibility flag
|
bool m_visible { true }; // visibility flag
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
|
bool m_dirty { false };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// methods
|
// methods
|
||||||
@@ -383,6 +390,12 @@ basic_node::location() const {
|
|||||||
return m_area.center;
|
return m_area.center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
glm::dvec3 &
|
||||||
|
basic_node::location() {
|
||||||
|
return m_area.center;
|
||||||
|
}
|
||||||
|
|
||||||
inline
|
inline
|
||||||
void
|
void
|
||||||
basic_node::visible( bool const Visible ) {
|
basic_node::visible( bool const Visible ) {
|
||||||
|
|||||||
@@ -145,24 +145,38 @@ node_groups::insert( scene::group_handle const Group, basic_event *Event ) {
|
|||||||
|
|
||||||
// sends basic content of the class in legacy (text) format to provided stream
|
// sends basic content of the class in legacy (text) format to provided stream
|
||||||
void
|
void
|
||||||
node_groups::export_as_text( std::ostream &Output ) const {
|
node_groups::export_as_text( std::ostream &Output, bool Dirty ) const {
|
||||||
|
|
||||||
for( auto const &group : m_groupmap ) {
|
for( auto const &group : m_groupmap ) {
|
||||||
|
bool any = false;
|
||||||
Output << "group\n";
|
|
||||||
for( auto *node : group.second.nodes ) {
|
for( auto *node : group.second.nodes ) {
|
||||||
|
if (node->dirty() != Dirty)
|
||||||
|
continue;
|
||||||
// HACK: auto-generated memory cells aren't exported, so we check for this
|
// HACK: auto-generated memory cells aren't exported, so we check for this
|
||||||
// TODO: is_exportable as basic_node method
|
// TODO: is_exportable as basic_node method
|
||||||
if( ( typeid( *node ) == typeid( TMemCell ) )
|
if( ( typeid( *node ) == typeid( TMemCell ) )
|
||||||
&& ( false == static_cast<TMemCell *>( node )->is_exportable ) ) {
|
&& ( false == static_cast<TMemCell *>( node )->is_exportable ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!any)
|
||||||
|
Output << "group\n";
|
||||||
|
any = true;
|
||||||
|
|
||||||
node->export_as_text( Output );
|
node->export_as_text( Output );
|
||||||
}
|
}
|
||||||
for( auto *event : group.second.events ) {
|
for( auto *event : group.second.events ) {
|
||||||
|
if (Dirty)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!any)
|
||||||
|
Output << "group\n";
|
||||||
|
any = true;
|
||||||
|
|
||||||
event->export_as_text( Output );
|
event->export_as_text( Output );
|
||||||
}
|
}
|
||||||
Output << "endgroup\n";
|
if (any)
|
||||||
|
Output << "endgroup\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public:
|
|||||||
return m_groupmap[ Group ]; }
|
return m_groupmap[ Group ]; }
|
||||||
// sends basic content of the class in legacy (text) format to provided stream
|
// sends basic content of the class in legacy (text) format to provided stream
|
||||||
void
|
void
|
||||||
export_as_text( std::ostream &Output ) const;
|
export_as_text(std::ostream &Output , bool Dirty) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// types
|
// types
|
||||||
|
|||||||
@@ -175,6 +175,11 @@ void state_manager::process_commands() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TAnimModel *
|
||||||
|
state_manager::deserialize_model(cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata) {
|
||||||
|
return m_serializer.deserialize_model(Input, Scratchpad, Nodedata);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
state_manager::update_clocks() {
|
state_manager::update_clocks() {
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,10 @@ public:
|
|||||||
void
|
void
|
||||||
process_commands();
|
process_commands();
|
||||||
|
|
||||||
|
// temporary for editor
|
||||||
|
TAnimModel *
|
||||||
|
deserialize_model(cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// members
|
// members
|
||||||
state_serializer m_serializer;
|
state_serializer m_serializer;
|
||||||
|
|||||||
@@ -956,7 +956,7 @@ state_serializer::transform( glm::dvec3 Location, scene::scratch_data const &Scr
|
|||||||
|
|
||||||
// stores class data in specified file, in legacy (text) format
|
// stores class data in specified file, in legacy (text) format
|
||||||
void
|
void
|
||||||
state_serializer::export_as_text( std::string const &Scenariofile ) const {
|
state_serializer::export_as_text(std::string const &Scenariofile) const {
|
||||||
|
|
||||||
if( Scenariofile == "$.scn" ) {
|
if( Scenariofile == "$.scn" ) {
|
||||||
ErrorLog( "Bad file: scenery export not supported for file \"$.scn\"" );
|
ErrorLog( "Bad file: scenery export not supported for file \"$.scn\"" );
|
||||||
@@ -965,66 +965,79 @@ state_serializer::export_as_text( std::string const &Scenariofile ) const {
|
|||||||
WriteLog( "Scenery data export in progress..." );
|
WriteLog( "Scenery data export in progress..." );
|
||||||
}
|
}
|
||||||
|
|
||||||
auto filename { Scenariofile };
|
auto filename { Scenariofile };
|
||||||
while( filename[ 0 ] == '$' ) {
|
while( filename[ 0 ] == '$' ) {
|
||||||
// trim leading $ char rainsted utility may add to the base name for modified .scn files
|
// trim leading $ char rainsted utility may add to the base name for modified .scn files
|
||||||
filename.erase( 0, 1 );
|
filename.erase( 0, 1 );
|
||||||
}
|
}
|
||||||
erase_extension( filename );
|
erase_extension( filename );
|
||||||
filename = Global.asCurrentSceneryPath + filename + "_export";
|
auto absfilename = Global.asCurrentSceneryPath + filename + "_export";
|
||||||
|
|
||||||
std::ofstream scmfile { filename + ".scm" };
|
std::ofstream scmdirtyfile { absfilename + "_dirty.scm" };
|
||||||
// groups
|
export_nodes_to_stream(scmdirtyfile, true);
|
||||||
scmfile << "// groups\n";
|
|
||||||
scene::Groups.export_as_text( scmfile );
|
|
||||||
// tracks
|
|
||||||
scmfile << "// paths\n";
|
|
||||||
for( auto const *path : Paths.sequence() ) {
|
|
||||||
if( path->group() == null_handle ) {
|
|
||||||
path->export_as_text( scmfile );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// traction
|
|
||||||
scmfile << "// traction\n";
|
|
||||||
for( auto const *traction : Traction.sequence() ) {
|
|
||||||
if( traction->group() == null_handle ) {
|
|
||||||
traction->export_as_text( scmfile );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// power grid
|
|
||||||
scmfile << "// traction power sources\n";
|
|
||||||
for( auto const *powersource : Powergrid.sequence() ) {
|
|
||||||
if( powersource->group() == null_handle ) {
|
|
||||||
powersource->export_as_text( scmfile );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// models
|
|
||||||
scmfile << "// instanced models\n";
|
|
||||||
for( auto const *instance : Instances.sequence() ) {
|
|
||||||
if( instance->group() == null_handle ) {
|
|
||||||
instance->export_as_text( scmfile );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// sounds
|
|
||||||
// NOTE: sounds currently aren't included in groups
|
|
||||||
scmfile << "// sounds\n";
|
|
||||||
Region->export_as_text( scmfile );
|
|
||||||
|
|
||||||
std::ofstream ctrfile { filename + ".ctr" };
|
std::ofstream scmfile { absfilename + ".scm" };
|
||||||
// mem cells
|
export_nodes_to_stream(scmfile, false);
|
||||||
ctrfile << "// memory cells\n";
|
|
||||||
for( auto const *memorycell : Memory.sequence() ) {
|
// sounds
|
||||||
if( ( true == memorycell->is_exportable )
|
// NOTE: sounds currently aren't included in groups
|
||||||
&& ( memorycell->group() == null_handle ) ) {
|
scmfile << "// sounds\n";
|
||||||
memorycell->export_as_text( ctrfile );
|
Region->export_as_text( scmfile );
|
||||||
}
|
|
||||||
}
|
scmfile << "// modified objects\ninclude " << filename << "_export_dirty.scm\n";
|
||||||
// events
|
|
||||||
Events.export_as_text( ctrfile );
|
std::ofstream ctrfile { absfilename + ".ctr" };
|
||||||
|
// mem cells
|
||||||
|
ctrfile << "// memory cells\n";
|
||||||
|
for( auto const *memorycell : Memory.sequence() ) {
|
||||||
|
if( ( true == memorycell->is_exportable )
|
||||||
|
&& ( memorycell->group() == null_handle ) ) {
|
||||||
|
memorycell->export_as_text( ctrfile );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// events
|
||||||
|
Events.export_as_text( ctrfile );
|
||||||
|
|
||||||
WriteLog( "Scenery data export done." );
|
WriteLog( "Scenery data export done." );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
state_serializer::export_nodes_to_stream(std::ostream &scmfile, bool Dirty) const {
|
||||||
|
// groups
|
||||||
|
scmfile << "// groups\n";
|
||||||
|
scene::Groups.export_as_text( scmfile, Dirty );
|
||||||
|
|
||||||
|
// tracks
|
||||||
|
scmfile << "// paths\n";
|
||||||
|
for( auto const *path : Paths.sequence() ) {
|
||||||
|
if( path->dirty() == Dirty && path->group() == null_handle ) {
|
||||||
|
path->export_as_text( scmfile );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// traction
|
||||||
|
scmfile << "// traction\n";
|
||||||
|
for( auto const *traction : Traction.sequence() ) {
|
||||||
|
if( traction->dirty() == Dirty && traction->group() == null_handle ) {
|
||||||
|
traction->export_as_text( scmfile );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// power grid
|
||||||
|
scmfile << "// traction power sources\n";
|
||||||
|
for( auto const *powersource : Powergrid.sequence() ) {
|
||||||
|
if( powersource->dirty() == Dirty && powersource->group() == null_handle ) {
|
||||||
|
powersource->export_as_text( scmfile );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// models
|
||||||
|
scmfile << "// instanced models\n";
|
||||||
|
for( auto const *instance : Instances.sequence() ) {
|
||||||
|
if( instance && instance->dirty() == Dirty && instance->group() == null_handle ) {
|
||||||
|
instance->export_as_text( scmfile );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // simulation
|
} // simulation
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -40,7 +40,10 @@ public:
|
|||||||
deserialize_continue(std::shared_ptr<deserializer_state> state);
|
deserialize_continue(std::shared_ptr<deserializer_state> state);
|
||||||
// stores class data in specified file, in legacy (text) format
|
// stores class data in specified file, in legacy (text) format
|
||||||
void
|
void
|
||||||
export_as_text( std::string const &Scenariofile ) const;
|
export_as_text(std::string const &Scenariofile) const;
|
||||||
|
|
||||||
|
// temporary public for editor
|
||||||
|
TAnimModel * deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// methods
|
// methods
|
||||||
@@ -56,7 +59,7 @@ private:
|
|||||||
void deserialize_group( cParser &Input, scene::scratch_data &Scratchpad );
|
void deserialize_group( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
void deserialize_endgroup( cParser &Input, scene::scratch_data &Scratchpad );
|
void deserialize_endgroup( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
void deserialize_light( cParser &Input, scene::scratch_data &Scratchpad );
|
void deserialize_light( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
void deserialize_node( cParser &Input, scene::scratch_data &Scratchpad );
|
void deserialize_node( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
void deserialize_origin( cParser &Input, scene::scratch_data &Scratchpad );
|
void deserialize_origin( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
void deserialize_endorigin( cParser &Input, scene::scratch_data &Scratchpad );
|
void deserialize_endorigin( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
void deserialize_rotate( cParser &Input, scene::scratch_data &Scratchpad );
|
void deserialize_rotate( cParser &Input, scene::scratch_data &Scratchpad );
|
||||||
@@ -70,7 +73,6 @@ private:
|
|||||||
TTractionPowerSource * deserialize_tractionpowersource( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
TTractionPowerSource * deserialize_tractionpowersource( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
TMemCell * deserialize_memorycell( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
TMemCell * deserialize_memorycell( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
TEventLauncher * deserialize_eventlauncher( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
TEventLauncher * deserialize_eventlauncher( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
TAnimModel * deserialize_model( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
|
||||||
TDynamicObject * deserialize_dynamic( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
TDynamicObject * deserialize_dynamic( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
sound_source * deserialize_sound( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
sound_source * deserialize_sound( cParser &Input, scene::scratch_data &Scratchpad, scene::node_data const &Nodedata );
|
||||||
void init_time();
|
void init_time();
|
||||||
@@ -78,6 +80,7 @@ private:
|
|||||||
void skip_until( cParser &Input, std::string const &Token );
|
void skip_until( cParser &Input, std::string const &Token );
|
||||||
// transforms provided location by specifed rotation and offset
|
// transforms provided location by specifed rotation and offset
|
||||||
glm::dvec3 transform( glm::dvec3 Location, scene::scratch_data const &Scratchpad );
|
glm::dvec3 transform( glm::dvec3 Location, scene::scratch_data const &Scratchpad );
|
||||||
|
void export_nodes_to_stream(std::ostream &, bool Dirty) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // simulation
|
} // simulation
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ void ui_panel::render()
|
|||||||
int flags = window_flags;
|
int flags = window_flags;
|
||||||
if (flags == -1)
|
if (flags == -1)
|
||||||
flags = ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoCollapse |
|
flags = ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoCollapse |
|
||||||
((size.x > 0 || size_min.x > 0) ? ImGuiWindowFlags_NoResize : 0);
|
((size.x > 0) ? ImGuiWindowFlags_NoResize : 0);
|
||||||
|
|
||||||
if (size.x > 0)
|
if (size.x > 0)
|
||||||
ImGui::SetNextWindowSize(ImVec2(size.x, size.y));
|
ImGui::SetNextWindowSize(ImVec2(size.x, size.y));
|
||||||
|
|||||||
Reference in New Issue
Block a user