mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-23 23:49:17 +02:00
merge (incomplete)
This commit is contained in:
133
AnimModel.cpp
133
AnimModel.cpp
@@ -411,13 +411,7 @@ TAnimModel::TAnimModel()
|
||||
pModel = NULL;
|
||||
iNumLights = 0;
|
||||
fBlinkTimer = 0;
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
ReplacableSkinId[ 0 ] = 0;
|
||||
ReplacableSkinId[ 1 ] = 0;
|
||||
ReplacableSkinId[ 2 ] = 0;
|
||||
ReplacableSkinId[ 3 ] = 0;
|
||||
ReplacableSkinId[ 4 ] = 0;
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < iMaxNumLights; i++)
|
||||
{
|
||||
LightsOn[i] = LightsOff[i] = NULL; // normalnie nie ma
|
||||
@@ -443,28 +437,7 @@ bool TAnimModel::Init(TModel3d *pNewModel)
|
||||
pModel = pNewModel;
|
||||
return (pModel != NULL);
|
||||
}
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
bool TAnimModel::Init(std::string const &asName, std::string const &asReplacableTexture)
|
||||
{
|
||||
if (asReplacableTexture.substr(0, 1) ==
|
||||
"*") // od gwiazdki zaczynają się teksty na wyświetlaczach
|
||||
asText = asReplacableTexture.substr(1, asReplacableTexture.length() - 1); // zapamiętanie tekstu
|
||||
else if (asReplacableTexture != "none")
|
||||
ReplacableSkinId[1] =
|
||||
GfxRenderer.GetTextureId( asReplacableTexture, "" );
|
||||
if( ( ReplacableSkinId[ 1 ] != 0 )
|
||||
&& ( GfxRenderer.Texture( ReplacableSkinId[ 1 ] ).has_alpha ) ) {
|
||||
// tekstura z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
iTexAlpha = 0x31310031;
|
||||
}
|
||||
else{
|
||||
// tekstura nieprzezroczysta - nie renderować w cyklu
|
||||
iTexAlpha = 0x30300030;
|
||||
}
|
||||
// przezroczystych
|
||||
return (Init(TModelsManager::GetModel(asName)));
|
||||
}
|
||||
#else
|
||||
|
||||
bool TAnimModel::Init(std::string const &asName, std::string const &asReplacableTexture)
|
||||
{
|
||||
if (asReplacableTexture.substr(0, 1) ==
|
||||
@@ -485,7 +458,6 @@ bool TAnimModel::Init(std::string const &asName, std::string const &asReplacable
|
||||
// przezroczystych
|
||||
return (Init(TModelsManager::GetModel(asName)));
|
||||
}
|
||||
#endif
|
||||
|
||||
bool TAnimModel::Load(cParser *parser, bool ter)
|
||||
{ // rozpoznanie wpisu modelu i ustawienie świateł
|
||||
@@ -622,111 +594,29 @@ void TAnimModel::RaPrepare()
|
||||
// for (pCurrent=pRoot;pCurrent!=NULL;pCurrent=pCurrent->pNext) //albo osobny łańcuch
|
||||
// pCurrent->UpdateModelIK(); //przeliczenie odwrotnej kinematyki
|
||||
}
|
||||
/*
|
||||
void TAnimModel::RenderVBO(vector3 pPosition, double fAngle)
|
||||
{ // sprawdza światła i rekurencyjnie renderuje TModel3d
|
||||
RaAnimate(); // jednorazowe przeliczenie animacji
|
||||
RaPrepare();
|
||||
if (pModel) // renderowanie rekurencyjne submodeli
|
||||
pModel->RaRender(pPosition, fAngle, ReplacableSkinId, iTexAlpha);
|
||||
}
|
||||
|
||||
void TAnimModel::RenderAlphaVBO(vector3 pPosition, double fAngle)
|
||||
{
|
||||
RaPrepare();
|
||||
if (pModel) // renderowanie rekurencyjne submodeli
|
||||
pModel->RaRenderAlpha(pPosition, fAngle, ReplacableSkinId, iTexAlpha);
|
||||
};
|
||||
|
||||
void TAnimModel::RenderDL(vector3 pPosition, double fAngle)
|
||||
{
|
||||
RaAnimate(); // jednorazowe przeliczenie animacji
|
||||
RaPrepare();
|
||||
if (pModel) // renderowanie rekurencyjne submodeli
|
||||
pModel->Render(pPosition, fAngle, ReplacableSkinId, iTexAlpha);
|
||||
}
|
||||
|
||||
void TAnimModel::RenderAlphaDL(vector3 pPosition, double fAngle)
|
||||
{
|
||||
RaPrepare();
|
||||
if (pModel)
|
||||
pModel->RenderAlpha(pPosition, fAngle, ReplacableSkinId, iTexAlpha);
|
||||
};
|
||||
*/
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
int TAnimModel::Flags()
|
||||
{ // informacja dla TGround, czy ma być w Render, RenderAlpha, czy RenderMixed
|
||||
int i = pModel ? pModel->Flags() : 0; // pobranie flag całego modelu
|
||||
if (ReplacableSkinId[1] > 0) // jeśli ma wymienną teksturę 0
|
||||
i |= (i & 0x01010001) * ((iTexAlpha & 1) ? 0x20 : 0x10);
|
||||
// if (ReplacableSkinId[2]>0) //jeśli ma wymienną teksturę 1
|
||||
// i|=(i&0x02020002)*((iTexAlpha&1)?0x10:0x08);
|
||||
// if (ReplacableSkinId[3]>0) //jeśli ma wymienną teksturę 2
|
||||
// i|=(i&0x04040004)*((iTexAlpha&1)?0x08:0x04);
|
||||
// if (ReplacableSkinId[4]>0) //jeśli ma wymienną teksturę 3
|
||||
// i|=(i&0x08080008)*((iTexAlpha&1)?0x04:0x02);
|
||||
return i;
|
||||
};
|
||||
#else
|
||||
int TAnimModel::Flags()
|
||||
{ // informacja dla TGround, czy ma być w Render, RenderAlpha, czy RenderMixed
|
||||
int i = pModel ? pModel->Flags() : 0; // pobranie flag całego modelu
|
||||
if( m_materialdata.replacable_skins[ 1 ] > 0 ) // jeśli ma wymienną teksturę 0
|
||||
i |= (i & 0x01010001) * ((m_materialdata.textures_alpha & 1) ? 0x20 : 0x10);
|
||||
// if (ReplacableSkinId[2]>0) //jeśli ma wymienną teksturę 1
|
||||
// i|=(i&0x02020002)*((iTexAlpha&1)?0x10:0x08);
|
||||
// if (ReplacableSkinId[3]>0) //jeśli ma wymienną teksturę 2
|
||||
// i|=(i&0x04040004)*((iTexAlpha&1)?0x08:0x04);
|
||||
// if (ReplacableSkinId[4]>0) //jeśli ma wymienną teksturę 3
|
||||
// i|=(i&0x08080008)*((iTexAlpha&1)?0x04:0x02);
|
||||
return i;
|
||||
};
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 2011-03-16 cztery nowe funkcje renderowania z możliwością pochylania obiektów
|
||||
// 2011-03-16 funkcje renderowania z możliwością pochylania obiektów
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
void TAnimModel::RenderDL(vector3 *vPosition)
|
||||
{
|
||||
void TAnimModel::Render( vector3 const &Position ) {
|
||||
RaAnimate(); // jednorazowe przeliczenie animacji
|
||||
RaPrepare();
|
||||
if( pModel ) // renderowanie rekurencyjne submodeli
|
||||
pModel->Render(vPosition, &vAngle, ReplacableSkinId, iTexAlpha);
|
||||
GfxRenderer.Render( pModel, Material(), Position, vAngle );
|
||||
};
|
||||
void TAnimModel::RenderAlphaDL(vector3 *vPosition)
|
||||
{
|
||||
RaPrepare();
|
||||
if (pModel) // renderowanie rekurencyjne submodeli
|
||||
pModel->RenderAlpha(vPosition, &vAngle, ReplacableSkinId, iTexAlpha);
|
||||
};
|
||||
|
||||
void TAnimModel::RenderVBO(vector3 *vPosition)
|
||||
{
|
||||
RaAnimate(); // jednorazowe przeliczenie animacji
|
||||
RaPrepare();
|
||||
if (pModel) // renderowanie rekurencyjne submodeli
|
||||
pModel->RaRender( vPosition, &vAngle, Material()->replacable_skins, Material()->textures_alpha );
|
||||
};
|
||||
void TAnimModel::RenderAlphaVBO(vector3 *vPosition)
|
||||
{
|
||||
RaPrepare();
|
||||
if (pModel) // renderowanie rekurencyjne submodeli
|
||||
pModel->RaRenderAlpha( vPosition, &vAngle, Material()->replacable_skins, Material()->textures_alpha );
|
||||
};
|
||||
#else
|
||||
void TAnimModel::Render( vector3 *vPosition ) {
|
||||
RaAnimate(); // jednorazowe przeliczenie animacji
|
||||
void TAnimModel::RenderAlpha( vector3 const &Position ) {
|
||||
RaPrepare();
|
||||
if( pModel ) // renderowanie rekurencyjne submodeli
|
||||
GfxRenderer.Render( pModel, Material(), *vPosition, vAngle );
|
||||
GfxRenderer.Render_Alpha( pModel, Material(), Position, vAngle );
|
||||
};
|
||||
void TAnimModel::RenderAlpha( vector3 *vPosition ) {
|
||||
RaPrepare();
|
||||
if( pModel ) // renderowanie rekurencyjne submodeli
|
||||
GfxRenderer.Render_Alpha( pModel, Material(), *vPosition, vAngle );
|
||||
};
|
||||
#endif
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
bool TAnimModel::TerrainLoaded()
|
||||
@@ -901,13 +791,8 @@ void TAnimModel::LightSet(int n, float v)
|
||||
void TAnimModel::AnimUpdate(double dt)
|
||||
{ // wykonanie zakolejkowanych animacji, nawet gdy modele nie są aktualnie wyświetlane
|
||||
TAnimContainer *p = TAnimModel::acAnimList;
|
||||
while (p)
|
||||
{ // jeśli w ogóle jest co animować
|
||||
// if ((*p)->fTranslateSpeed==0.0)
|
||||
// if ((*p)->fRotateSpeed==0.0)
|
||||
// {//jak się naanimował, to usunąć z listy
|
||||
// *p=(*p)->ListRemove(); //zwraca wskaźnik do kolejnego z listy
|
||||
// }
|
||||
while( p ) {
|
||||
|
||||
p->UpdateModel();
|
||||
p = p->acAnimNext; // na razie bez usuwania z listy, bo głównie obrotnica na nią wchodzi
|
||||
}
|
||||
|
||||
30
AnimModel.h
30
AnimModel.h
@@ -12,8 +12,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef AnimModelH
|
||||
#define AnimModelH
|
||||
#pragma once
|
||||
|
||||
#include "Model3d.h"
|
||||
#include "Texture.h"
|
||||
@@ -139,11 +138,7 @@ class TAnimModel
|
||||
TSubModel *LightsOn[iMaxNumLights]; // Ra: te wskaźniki powinny być w ramach TModel3d
|
||||
TSubModel *LightsOff[iMaxNumLights];
|
||||
vector3 vAngle; // bazowe obroty egzemplarza względem osi
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
int iTexAlpha; //żeby nie sprawdzać za każdym razem, dla 4 wymiennych tekstur
|
||||
#else
|
||||
material_data m_materialdata;
|
||||
#endif
|
||||
|
||||
std::string asText; // tekst dla wyświetlacza znakowego
|
||||
TAnimAdvanced *pAdvanced;
|
||||
@@ -155,14 +150,9 @@ class TAnimModel
|
||||
void RaAnimate(); // przeliczenie animacji egzemplarza
|
||||
void RaPrepare(); // ustawienie animacji egzemplarza na wzorcu
|
||||
public:
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
texture_manager::size_type ReplacableSkinId[5]; // McZapkie-020802: zmienialne skory
|
||||
#endif
|
||||
static TAnimContainer *acAnimList; // lista animacji z eventem, które muszą być przeliczane również bez wyświetlania
|
||||
#ifndef EU07_USE_OLD_RENDERCODE
|
||||
inline
|
||||
material_data const *Material() const { return &m_materialdata; }
|
||||
#endif
|
||||
|
||||
TAnimModel();
|
||||
~TAnimModel();
|
||||
@@ -171,20 +161,8 @@ class TAnimModel
|
||||
bool Load(cParser *parser, bool ter = false);
|
||||
TAnimContainer * AddContainer(char *pName);
|
||||
TAnimContainer * GetContainer(char *pName);
|
||||
/* void RenderDL(vector3 pPosition = vector3(0, 0, 0), double fAngle = 0);
|
||||
void RenderAlphaDL(vector3 pPosition = vector3(0, 0, 0), double fAngle = 0);
|
||||
void RenderVBO(vector3 pPosition = vector3(0, 0, 0), double fAngle = 0);
|
||||
void RenderAlphaVBO(vector3 pPosition = vector3(0, 0, 0), double fAngle = 0);
|
||||
*/
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
void RenderDL( vector3 *vPosition );
|
||||
void RenderAlphaDL(vector3 *vPosition);
|
||||
void RenderVBO(vector3 *vPosition);
|
||||
void RenderAlphaVBO(vector3 *vPosition);
|
||||
#else
|
||||
void Render( vector3 *vPosition );
|
||||
void RenderAlpha( vector3 *vPosition );
|
||||
#endif
|
||||
void Render( vector3 const &Position );
|
||||
void RenderAlpha( vector3 const &Position );
|
||||
int Flags();
|
||||
void RaAnglesSet(double a, double b, double c)
|
||||
{
|
||||
@@ -201,6 +179,4 @@ class TAnimModel
|
||||
static void AnimUpdate(double dt);
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
|
||||
16
Camera.cpp
16
Camera.cpp
@@ -410,21 +410,21 @@ bool TCamera::SetMatrix()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TCamera::SetMatrix( glm::mat4 &Matrix ) {
|
||||
bool TCamera::SetMatrix( glm::dmat4 &Matrix ) {
|
||||
|
||||
Matrix = glm::rotate( Matrix, (float)-Roll, glm::vec3( 0.0f, 0.0f, 1.0f ) ); // po wyłączeniu tego kręci się pojazd, a sceneria nie
|
||||
Matrix = glm::rotate( Matrix, (float)-Pitch, glm::vec3( 1.0f, 0.0f, 0.0f ) );
|
||||
Matrix = glm::rotate( Matrix, (float)-Yaw, glm::vec3( 0.0f, 1.0f, 0.0f ) ); // w zewnętrznym widoku: kierunek patrzenia
|
||||
Matrix = glm::rotate( Matrix, -Roll, glm::dvec3( 0.0, 0.0, 1.0 ) ); // po wyłączeniu tego kręci się pojazd, a sceneria nie
|
||||
Matrix = glm::rotate( Matrix, -Pitch, glm::dvec3( 1.0, 0.0, 0.0 ) );
|
||||
Matrix = glm::rotate( Matrix, -Yaw, glm::dvec3( 0.0, 1.0, 0.0 ) ); // w zewnętrznym widoku: kierunek patrzenia
|
||||
|
||||
if( Type == tp_Follow ) {
|
||||
|
||||
Matrix *= glm::lookAt(
|
||||
glm::vec3( Pos.x, Pos.y, Pos.z ),
|
||||
glm::vec3( LookAt.x, LookAt.y, LookAt.z ),
|
||||
glm::vec3( vUp.x, vUp.y, vUp.z ) );
|
||||
glm::dvec3( Pos.x, Pos.y, Pos.z ),
|
||||
glm::dvec3( LookAt.x, LookAt.y, LookAt.z ),
|
||||
glm::dvec3( vUp.x, vUp.y, vUp.z ) );
|
||||
}
|
||||
else {
|
||||
Matrix = glm::translate( Matrix, glm::vec3( -Pos.x, -Pos.y, -Pos.z ) ); // nie zmienia kierunku patrzenia
|
||||
Matrix = glm::translate( Matrix, glm::dvec3( -Pos.x, -Pos.y, -Pos.z ) ); // nie zmienia kierunku patrzenia
|
||||
}
|
||||
|
||||
Global::SetCameraPosition( Pos ); // było +pOffset
|
||||
|
||||
2
Camera.h
2
Camera.h
@@ -58,7 +58,7 @@ class TCamera
|
||||
void Update();
|
||||
vector3 GetDirection();
|
||||
bool SetMatrix();
|
||||
bool SetMatrix(glm::mat4 &Matrix);
|
||||
bool SetMatrix(glm::dmat4 &Matrix);
|
||||
void SetCabMatrix( vector3 &p );
|
||||
void RaLook();
|
||||
void Stop();
|
||||
|
||||
1248
Driver.cpp
1248
Driver.cpp
File diff suppressed because it is too large
Load Diff
49
Driver.h
49
Driver.h
@@ -102,6 +102,7 @@ enum TAction
|
||||
|
||||
enum TSpeedPosFlag
|
||||
{ // wartości dla iFlag w TSpeedPos
|
||||
spNone = 0x0,
|
||||
spEnabled = 0x1, // pozycja brana pod uwagę
|
||||
spTrack = 0x2, // to jest tor
|
||||
spReverse = 0x4, // odwrotnie
|
||||
@@ -126,11 +127,11 @@ enum TSpeedPosFlag
|
||||
class TSpeedPos
|
||||
{ // pozycja tabeli prędkości dla AI
|
||||
public:
|
||||
double fDist; // aktualna odległość (ujemna gdy minięte)
|
||||
double fVelNext; // prędkość obowiązująca od tego miejsca
|
||||
double fSectionVelocityDist; // długość ograniczenia prędkości
|
||||
double fDist{ 0.0 }; // aktualna odległość (ujemna gdy minięte)
|
||||
double fVelNext{ -1.0 }; // prędkość obowiązująca od tego miejsca
|
||||
double fSectionVelocityDist{ 0.0 }; // długość ograniczenia prędkości
|
||||
// double fAcc;
|
||||
int iFlags; // flagi typu wpisu do tabelki
|
||||
int iFlags{ spNone }; // flagi typu wpisu do tabelki
|
||||
// 1=istotny,2=tor,4=odwrotnie,8-zwrotnica (może się zmienić),16-stan
|
||||
// zwrotnicy,32-minięty,64=koniec,128=łuk
|
||||
// 0x100=event,0x200=manewrowa,0x400=przystanek,0x800=SBL,0x1000=wysłana komenda,0x2000=W5
|
||||
@@ -138,8 +139,8 @@ class TSpeedPos
|
||||
vector3 vPos; // współrzędne XYZ do liczenia odległości
|
||||
struct
|
||||
{
|
||||
TTrack *trTrack; // wskaźnik na tor o zmiennej prędkości (zwrotnica, obrotnica)
|
||||
TEvent *evEvent; // połączenie z eventem albo komórką pamięci
|
||||
TTrack *trTrack{ nullptr }; // wskaźnik na tor o zmiennej prędkości (zwrotnica, obrotnica)
|
||||
TEvent *evEvent{ nullptr }; // połączenie z eventem albo komórką pamięci
|
||||
};
|
||||
void CommandCheck();
|
||||
|
||||
@@ -166,16 +167,14 @@ extern bool WriteLogFlag; // logowanie parametrów fizycznych
|
||||
class TController
|
||||
{
|
||||
private: // obsługa tabelki prędkości (musi mieć możliwość odhaczania stacji w rozkładzie)
|
||||
TSpeedPos *sSpeedTable = nullptr; // najbliższe zmiany prędkości
|
||||
int iSpeedTableSize = 16; // wielkość tabelki
|
||||
int iFirst = 0; // aktualna pozycja w tabeli (modulo iSpeedTableSize)
|
||||
int iLast = 0; // ostatnia wypełniona pozycja w tabeli <iFirst (modulo iSpeedTableSize)
|
||||
int iTableDirection = 0; // kierunek zapełnienia tabelki względem pojazdu z AI
|
||||
size_t iLast{ 0 }; // ostatnia wypełniona pozycja w tabeli <iFirst (modulo iSpeedTableSize)
|
||||
int iTableDirection{ 0 }; // kierunek zapełnienia tabelki względem pojazdu z AI
|
||||
std::vector<TSpeedPos> sSpeedTable;
|
||||
double fLastVel = 0.0; // prędkość na poprzednio sprawdzonym torze
|
||||
TTrack *tLast = nullptr; // ostatni analizowany tor
|
||||
TEvent *eSignSkip = nullptr; // można pominąć ten SBL po zatrzymaniu
|
||||
TSpeedPos *sSemNext = nullptr; // następny semafor na drodze zależny od trybu jazdy
|
||||
TSpeedPos *sSemNextStop = nullptr; // następny semafor na drodze zależny od trybu jazdy i na stój
|
||||
std::size_t SemNextIndex{ std::size_t(-1) };
|
||||
std::size_t SemNextStopIndex{ std::size_t( -1 ) };
|
||||
private: // parametry aktualnego składu
|
||||
double fLength = 0.0; // długość składu (do wyciągania z ograniczeń)
|
||||
double fMass = 0.0; // całkowita masa do liczenia stycznej składowej grawitacji
|
||||
@@ -202,8 +201,7 @@ class TController
|
||||
public:
|
||||
double fLastStopExpDist = -1.0; // odległość wygasania ostateniego przystanku
|
||||
double ReactionTime = 0.0; // czas reakcji Ra: czego i na co? świadomości AI
|
||||
double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę
|
||||
// hamulca
|
||||
double fBrakeTime = 0.0; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca
|
||||
private:
|
||||
double fReady = 0.0; // poziom odhamowania wagonów
|
||||
bool Ready = false; // ABu: stan gotowosci do odjazdu - sprawdzenie odhamowania wagonow
|
||||
@@ -212,6 +210,7 @@ class TController
|
||||
double deltalog = 0.05; // przyrost czasu
|
||||
double LastReactionTime = 0.0;
|
||||
double fActionTime = 0.0; // czas używany przy regulacji prędkości i zamykaniu drzwi
|
||||
double m_radiocontroltime{ 0.0 }; // timer used to control speed of radio operations
|
||||
TAction eAction = actSleep; // aktualny stan
|
||||
bool HelpMeFlag = false; // wystawiane True jesli cos niedobrego sie dzieje
|
||||
public:
|
||||
@@ -321,9 +320,11 @@ class TController
|
||||
// procedury dotyczace rozkazow dla maszynisty
|
||||
void SetVelocity(double NewVel, double NewVelNext,
|
||||
TStopReason r = stopNone); // uaktualnia informacje o prędkości
|
||||
/*
|
||||
bool SetProximityVelocity(
|
||||
double NewDist,
|
||||
double NewVelNext); // uaktualnia informacje o prędkości przy nastepnym semaforze
|
||||
*/
|
||||
public:
|
||||
void JumpToNextOrder();
|
||||
void JumpToFirstOrder();
|
||||
@@ -332,6 +333,7 @@ class TController
|
||||
inline TOrders OrderCurrentGet();
|
||||
inline TOrders OrderNextGet();
|
||||
bool CheckVehicles(TOrders user = Wait_for_orders);
|
||||
int CheckDirection();
|
||||
|
||||
private:
|
||||
void CloseLog();
|
||||
@@ -352,19 +354,22 @@ class TController
|
||||
void DirectionForward(bool forward);
|
||||
int OrderDirectionChange(int newdir, TMoverParameters *Vehicle);
|
||||
void Lights(int head, int rear);
|
||||
double Distance(vector3 &p1, vector3 &n, vector3 &p2);
|
||||
// double Distance(vector3 &p1, vector3 &n, vector3 &p2);
|
||||
|
||||
private: // Ra: metody obsługujące skanowanie toru
|
||||
TEvent *CheckTrackEvent(double fDirection, TTrack *Track);
|
||||
bool TableCheckEvent(TEvent *e);
|
||||
// bool TableCheckEvent(TEvent *e);
|
||||
bool TableAddNew();
|
||||
bool TableNotFound(TEvent *e);
|
||||
void TableClear();
|
||||
TEvent *TableCheckTrackEvent(double fDirection, TTrack *Track);
|
||||
bool TableNotFound(TEvent const *Event) const;
|
||||
// TEvent *TableCheckTrackEvent(double fDirection, TTrack *Track);
|
||||
void TableTraceRoute(double fDistance, TDynamicObject *pVehicle = NULL);
|
||||
void TableCheck(double fDistance);
|
||||
TCommandType TableUpdate(double &fVelDes, double &fDist, double &fNext, double &fAcc);
|
||||
void TablePurger();
|
||||
public:
|
||||
std::size_t TableSize() const { return sSpeedTable.size(); }
|
||||
void TableClear();
|
||||
int TableDirection() { return iTableDirection; }
|
||||
|
||||
private: // Ra: stare funkcje skanujące, używane do szukania sygnalizatora z tyłu
|
||||
bool BackwardTrackBusy(TTrack *Track);
|
||||
@@ -395,9 +400,9 @@ class TController
|
||||
};
|
||||
void MoveTo(TDynamicObject *to);
|
||||
void DirectionInitial();
|
||||
std::string TableText(int i);
|
||||
std::string TableText(std::size_t const Index);
|
||||
int CrossRoute(TTrack *tr);
|
||||
void RouteSwitch(int d);
|
||||
std::string OwnerName();
|
||||
std::string OwnerName() const;
|
||||
TMoverParameters const *Controlling() const { return mvControlling; }
|
||||
};
|
||||
|
||||
669
DynObj.cpp
669
DynObj.cpp
@@ -45,6 +45,11 @@ http://mozilla.org/MPL/2.0/.
|
||||
#define M_2PI 6.283185307179586476925286766559;
|
||||
const float maxrot = (float)(M_PI / 3.0); // 60°
|
||||
|
||||
std::string const TDynamicObject::MED_labels[] = {
|
||||
"masa: ", "amax: ", "Fzad: ", "FmPN: ", "FmED: ", "FrED: ", "FzPN: ", "nPrF: "
|
||||
};
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void TAnimPant::AKP_4E()
|
||||
{ // ustawienie wymiarów dla pantografu AKP-4E
|
||||
@@ -798,7 +803,7 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
|
||||
btnOn = true;
|
||||
}
|
||||
// else btCPass2.TurnOff();
|
||||
if (MoverParameters->Battery)
|
||||
if (MoverParameters->Battery || MoverParameters->ConverterFlag)
|
||||
{ // sygnaly konca pociagu
|
||||
if (btEndSignals1.Active())
|
||||
{
|
||||
@@ -900,7 +905,7 @@ void TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
|
||||
// Ra: przechyłkę załatwiamy na etapie przesuwania modelu
|
||||
// if (ObjSqrDist<80000) ABuModelRoll(); //przechyłki od 400m
|
||||
}
|
||||
if (MoverParameters->Battery)
|
||||
if( MoverParameters->Battery || MoverParameters->ConverterFlag )
|
||||
{ // sygnały czoła pociagu //Ra: wyświetlamy bez
|
||||
// ograniczeń odległości, by były widoczne z
|
||||
// daleka
|
||||
@@ -1526,14 +1531,6 @@ TDynamicObject::TDynamicObject()
|
||||
//}
|
||||
mdModel = NULL;
|
||||
mdKabina = NULL;
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
ReplacableSkinID[ 0 ] = 0;
|
||||
ReplacableSkinID[ 1 ] = 0;
|
||||
ReplacableSkinID[ 2 ] = 0;
|
||||
ReplacableSkinID[ 3 ] = 0;
|
||||
ReplacableSkinID[ 4 ] = 0;
|
||||
iAlpha = 0x30300030; // tak gdy tekstury wymienne nie mają przezroczystości
|
||||
#endif
|
||||
// smWiazary[0]=smWiazary[1]=NULL;
|
||||
smWahacze[0] = smWahacze[1] = smWahacze[2] = smWahacze[3] = NULL;
|
||||
fWahaczeAmp = 0;
|
||||
@@ -1753,52 +1750,45 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||||
// wylaczanie hamulca
|
||||
if (ActPar.find("<>") != std::string::npos) // wylaczanie na probe hamowania naglego
|
||||
{
|
||||
MoverParameters->BrakeStatus |= 128; // wylacz
|
||||
MoverParameters->Hamulec->SetBrakeStatus( MoverParameters->Hamulec->GetBrakeStatus() | b_dmg ); // wylacz
|
||||
}
|
||||
if (ActPar.find('0') != std::string::npos) // wylaczanie na sztywno
|
||||
{
|
||||
MoverParameters->BrakeStatus |= 128; // wylacz
|
||||
MoverParameters->Hamulec->SetBrakeStatus( MoverParameters->Hamulec->GetBrakeStatus() | b_dmg ); // wylacz
|
||||
MoverParameters->Hamulec->ForceEmptiness();
|
||||
MoverParameters->BrakeReleaser(1); // odluznij automatycznie
|
||||
}
|
||||
if (ActPar.find('E') != std::string::npos) // oprozniony
|
||||
{
|
||||
MoverParameters->Hamulec->ForceEmptiness();
|
||||
MoverParameters->BrakeReleaser(1); // odluznij automatycznie
|
||||
MoverParameters->Pipe->CreatePress(0);
|
||||
MoverParameters->Pipe2->CreatePress(0);
|
||||
}
|
||||
if (ActPar.find('Q') != std::string::npos) // oprozniony
|
||||
{
|
||||
// MoverParameters->Hamulec->ForceEmptiness(); //TODO: sprawdzic,
|
||||
// dlaczego
|
||||
// pojawia sie blad przy uzyciu tej linijki w lokomotywie
|
||||
MoverParameters->BrakeReleaser(1); // odluznij automatycznie
|
||||
MoverParameters->Hamulec->ForceEmptiness();
|
||||
MoverParameters->Pipe->CreatePress(0.0);
|
||||
MoverParameters->PipePress = 0.0;
|
||||
MoverParameters->Pipe2->CreatePress(0.0);
|
||||
MoverParameters->ScndPipePress = 0.0;
|
||||
MoverParameters->PantVolume = 1;
|
||||
MoverParameters->PantPress = 0;
|
||||
MoverParameters->CompressedVolume = 0;
|
||||
MoverParameters->PantVolume = 0.1;
|
||||
MoverParameters->PantPress = 0.0;
|
||||
MoverParameters->CompressedVolume = 0.0;
|
||||
}
|
||||
|
||||
if (ActPar.find('1') != std::string::npos) // wylaczanie 10%
|
||||
{
|
||||
if (Random(10) < 1) // losowanie 1/10
|
||||
{
|
||||
MoverParameters->BrakeStatus |= 128; // wylacz
|
||||
MoverParameters->Hamulec->SetBrakeStatus( MoverParameters->Hamulec->GetBrakeStatus() | b_dmg ); // wylacz
|
||||
MoverParameters->Hamulec->ForceEmptiness();
|
||||
MoverParameters->BrakeReleaser(1); // odluznij automatycznie
|
||||
}
|
||||
}
|
||||
if (ActPar.find('X') != std::string::npos) // agonalny wylaczanie 20%, usrednienie przekladni
|
||||
{
|
||||
if (Random(100) < 20) // losowanie 20/100
|
||||
{
|
||||
MoverParameters->BrakeStatus |= 128; // wylacz
|
||||
MoverParameters->Hamulec->SetBrakeStatus( MoverParameters->Hamulec->GetBrakeStatus() | b_dmg ); // wylacz
|
||||
MoverParameters->Hamulec->ForceEmptiness();
|
||||
MoverParameters->BrakeReleaser(1); // odluznij automatycznie
|
||||
}
|
||||
if (MoverParameters->BrakeCylMult[2] * MoverParameters->BrakeCylMult[1] >
|
||||
0.01) // jesli jest nastawiacz mechaniczny PL
|
||||
@@ -1881,8 +1871,7 @@ TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||||
{ // McZapkie-040602: jeśli coś siedzi w pojeździe
|
||||
if (Name == Global::asHumanCtrlVehicle) // jeśli pojazd wybrany do prowadzenia
|
||||
{
|
||||
if (DebugModeFlag ? false : MoverParameters->EngineType !=
|
||||
Dumb) // jak nie Debugmode i nie jest dumbem
|
||||
if ( MoverParameters->EngineType != Dumb)
|
||||
Controller = Humandriver; // wsadzamy tam sterującego
|
||||
else // w przeciwnym razie trzeba włączyć pokazywanie kabiny
|
||||
bDisplayCab = true;
|
||||
@@ -2443,43 +2432,66 @@ bool TDynamicObject::Update(double dt, double dt1)
|
||||
if (!bEnabled)
|
||||
return false; // a normalnie powinny mieć bEnabled==false
|
||||
|
||||
// Ra: przeniosłem - no już lepiej tu, niż w wyświetlaniu!
|
||||
// if ((MoverParameters->ConverterFlag==false) &&
|
||||
// (MoverParameters->TrainType!=dt_ET22))
|
||||
// Ra: to nie może tu być, bo wyłącza sprężarkę w rozrządczym EZT!
|
||||
// if
|
||||
// ((MoverParameters->ConverterFlag==false)&&(MoverParameters->CompressorPower!=0))
|
||||
// MoverParameters->CompressorFlag=false;
|
||||
// if (MoverParameters->CompressorPower==2)
|
||||
// MoverParameters->CompressorAllow=MoverParameters->ConverterFlag;
|
||||
|
||||
// McZapkie-260202
|
||||
if ((MoverParameters->EnginePowerSource.SourceType == CurrentCollector) &&
|
||||
(MoverParameters->Power > 1.0)) // aby rozrządczy nie opuszczał silnikowemu
|
||||
/*
|
||||
if ((MechInside) || (MoverParameters->TrainType == dt_EZT))
|
||||
{
|
||||
*/
|
||||
// if
|
||||
// ((!MoverParameters->PantCompFlag)&&(MoverParameters->CompressedVolume>=2.8))
|
||||
// MoverParameters->PantVolume=MoverParameters->CompressedVolume;
|
||||
if (MoverParameters->PantPress < (MoverParameters->TrainType == dt_EZT ? 2.4 : 3.5))
|
||||
{ // 3.5 wg
|
||||
// http://www.transportszynowy.pl/eu06-07pneumat.php
|
||||
//"Wyłączniki ciśnieniowe odbieraków prądu wyłączają sterowanie
|
||||
// wyłącznika szybkiego
|
||||
// oraz uniemożliwiają podniesienie odbieraków prądu, gdy w instalacji
|
||||
// rozrządu
|
||||
// ciśnienie spadnie poniżej wartości 3,5 bara."
|
||||
// Ra 2013-12: Niebugocław mówi, że w EZT podnoszą się przy 2.5
|
||||
// if (!MoverParameters->PantCompFlag)
|
||||
// MoverParameters->PantVolume=MoverParameters->CompressedVolume;
|
||||
MoverParameters->PantFront(false); // opuszczenie pantografów przy niskim ciśnieniu
|
||||
MoverParameters->PantRear(false); // to idzie w ukrotnieniu, a nie powinno...
|
||||
}
|
||||
// Winger - automatyczne wylaczanie malej sprezarki
|
||||
else if (MoverParameters->PantPress >= 4.8)
|
||||
MoverParameters->PantCompFlag = false;
|
||||
} // Ra: do Mover to trzeba przenieść, żeby AI też mogło sobie podpompować
|
||||
|
||||
if( MoverParameters->PantPress < MoverParameters->EnginePowerSource.CollectorParameters.MinPress ) {
|
||||
// 3.5 wg http://www.transportszynowy.pl/eu06-07pneumat.php
|
||||
if( true == MoverParameters->PantPressSwitchActive ) {
|
||||
// opuszczenie pantografów przy niskim ciśnieniu
|
||||
/*
|
||||
// NOTE: disabled, the pantographs drop by themseleves when the pantograph tank pressure gets low enough
|
||||
MoverParameters->PantFront( false, ( MoverParameters->TrainType == dt_EZT ? range::unit : range::local ) );
|
||||
MoverParameters->PantRear( false, ( MoverParameters->TrainType == dt_EZT ? range::unit : range::local ) );
|
||||
*/
|
||||
if( MoverParameters->TrainType != dt_EZT ) {
|
||||
// pressure switch safety measure -- open the line breaker, unless there's alternate source of traction voltage
|
||||
if( MoverParameters->GetTrainsetVoltage() < 0.5 * MoverParameters->EnginePowerSource.MaxVoltage ) {
|
||||
// TODO: check whether line breaker should be open EMU-wide
|
||||
MoverParameters->MainSwitch( false, ( MoverParameters->TrainType == dt_EZT ? range::unit : range::local ) );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// specialized variant for EMU -- pwr system disables converter and heating,
|
||||
// and prevents their activation until pressure switch is set again
|
||||
MoverParameters->PantPressLockActive = true;
|
||||
// TODO: separate 'heating allowed' from actual heating flag, so we can disable it here without messing up heating toggle
|
||||
MoverParameters->ConverterSwitch( false, range::unit );
|
||||
}
|
||||
// mark the pressure switch as spent
|
||||
MoverParameters->PantPressSwitchActive = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if( MoverParameters->PantPress >= 4.6 ) {
|
||||
// NOTE: we require active low power source to prime the pressure switch
|
||||
// this is a work-around for potential isssues caused by the switch activating on otherwise idle vehicles, but should check whether it's accurate
|
||||
if( ( true == MoverParameters->Battery )
|
||||
|| ( true == MoverParameters->ConverterFlag ) ) {
|
||||
// prime the pressure switch
|
||||
MoverParameters->PantPressSwitchActive = true;
|
||||
// turn off the subsystems lock
|
||||
MoverParameters->PantPressLockActive = false;
|
||||
}
|
||||
|
||||
if( MoverParameters->PantPress >= 4.8 ) {
|
||||
// Winger - automatyczne wylaczanie malej sprezarki
|
||||
// TODO: governor lock, disables usage until pressure drop below 3.8 (should really make compressor object we could reuse)
|
||||
MoverParameters->PantCompFlag = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
} // Ra: do Mover to trzeba przenieść, żeby AI też mogło sobie podpompować
|
||||
*/
|
||||
double dDOMoveLen;
|
||||
|
||||
TLocation l;
|
||||
@@ -2911,37 +2923,29 @@ bool TDynamicObject::Update(double dt, double dt1)
|
||||
|
||||
// fragment "z EXE Kursa"
|
||||
if (MoverParameters->Mains) // nie wchodzić w funkcję bez potrzeby
|
||||
if ( ( false == MoverParameters->Battery)
|
||||
if ( ( false == MoverParameters->Battery )
|
||||
&& ( false == MoverParameters->ConverterFlag ) // added alternative power source. TODO: more generic power check
|
||||
&& ( Controller == Humandriver)
|
||||
/*
|
||||
// NOTE: disabled on account of multi-unit setups, where the unmanned unit wouldn't be affected
|
||||
&& ( Controller == Humandriver )
|
||||
*/
|
||||
&& ( MoverParameters->EngineType != DieselEngine )
|
||||
&& ( MoverParameters->EngineType != WheelsDriven ) )
|
||||
{ // jeśli bateria wyłączona, a nie diesel ani drezyna reczna
|
||||
if (MoverParameters->MainSwitch(false)) // wyłączyć zasilanie
|
||||
if( MoverParameters->MainSwitch( false, ( MoverParameters->TrainType == dt_EZT ? range::unit : range::local ) ) ) {
|
||||
// wyłączyć zasilanie
|
||||
// NOTE: we turn off entire EMU, but only the affected unit for other multi-unit consists
|
||||
MoverParameters->EventFlag = true;
|
||||
// drop pantographs
|
||||
// NOTE: this isn't universal behaviour
|
||||
// TODO: have this dependant on .fiz-driven flag
|
||||
// NOTE: moved to pantspeed calculation part a little later in the function. all remarks and todo still apply
|
||||
/*
|
||||
MoverParameters->PantFront( false, ( MoverParameters->TrainType == dt_EZT ? range::unit : range::local ) );
|
||||
MoverParameters->PantRear( false, ( MoverParameters->TrainType == dt_EZT ? range::unit : range::local ) );
|
||||
*/
|
||||
}
|
||||
}
|
||||
if (MoverParameters->TrainType == dt_ET42)
|
||||
{ // powinny być wszystkie dwuczłony oraz EZT
|
||||
/*
|
||||
//Ra: to jest bez sensu, bo wyłącza WS przy przechodzeniu przez
|
||||
"wewnętrzne" kabiny (z
|
||||
powodu ActiveCab)
|
||||
//trzeba to zrobić inaczej, np. dla członu A sprawdzać, czy jest B
|
||||
//albo sprawdzać w momencie załączania WS i zmiany w sprzęgach
|
||||
if
|
||||
(((TestFlag(MoverParameters->Couplers[1].CouplingFlag,ctrain_controll))&&(MoverParameters->ActiveCab>0)&&(NextConnected->MoverParameters->TrainType!=dt_ET42))||((TestFlag(MoverParameters->Couplers[0].CouplingFlag,ctrain_controll))&&(MoverParameters->ActiveCab<0)&&(PrevConnected->MoverParameters->TrainType!=dt_ET42)))
|
||||
{//sprawdzenie, czy z tyłu kabiny mamy drugi człon
|
||||
if (MoverParameters->MainSwitch(false))
|
||||
MoverParameters->EventFlag=true;
|
||||
}
|
||||
if
|
||||
((!(TestFlag(MoverParameters->Couplers[1].CouplingFlag,ctrain_controll))&&(MoverParameters->ActiveCab>0))||(!(TestFlag(MoverParameters->Couplers[0].CouplingFlag,ctrain_controll))&&(MoverParameters->ActiveCab<0)))
|
||||
{
|
||||
if (MoverParameters->MainSwitch(false))
|
||||
MoverParameters->EventFlag=true;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// McZapkie-260202 - dMoveLen przyda sie przy stukocie kol
|
||||
dDOMoveLen =
|
||||
@@ -3210,21 +3214,27 @@ bool TDynamicObject::Update(double dt, double dt1)
|
||||
MoverParameters->PantRearVolt = 0.0;
|
||||
break;
|
||||
} // pozostałe na razie nie obsługiwane
|
||||
if (MoverParameters->PantPress >
|
||||
(MoverParameters->TrainType == dt_EZT ? 2.5 : 3.3)) // Ra 2013-12:
|
||||
// Niebugocław
|
||||
// mówi, że w EZT
|
||||
// podnoszą się
|
||||
// przy 2.5
|
||||
pantspeedfactor = 0.015 * (MoverParameters->PantPress) *
|
||||
dt1; // z EXE Kursa //Ra: wysokość zależy od ciśnienia !!!
|
||||
else
|
||||
if( MoverParameters->PantPress > (
|
||||
MoverParameters->TrainType == dt_EZT ?
|
||||
2.45 : // Ra 2013-12: Niebugocław mówi, że w EZT podnoszą się przy 2.5
|
||||
3.45 ) ) {
|
||||
// z EXE Kursa
|
||||
// Ra: wysokość zależy od ciśnienia !!!
|
||||
pantspeedfactor = 0.015 * ( MoverParameters->PantPress ) * dt1;
|
||||
}
|
||||
else {
|
||||
pantspeedfactor = 0.0;
|
||||
if (pantspeedfactor < 0)
|
||||
pantspeedfactor = 0;
|
||||
}
|
||||
if( ( false == MoverParameters->Battery )
|
||||
&& ( false == MoverParameters->ConverterFlag ) ) {
|
||||
pantspeedfactor = 0.0;
|
||||
}
|
||||
pantspeedfactor = std::max( 0.0, pantspeedfactor );
|
||||
k = p->fAngleL;
|
||||
if (i ? MoverParameters->PantRearUp :
|
||||
MoverParameters->PantFrontUp) // jeśli ma być podniesiony
|
||||
if( ( pantspeedfactor > 0.0 )
|
||||
&& ( i ?
|
||||
MoverParameters->PantRearUp :
|
||||
MoverParameters->PantFrontUp ) )// jeśli ma być podniesiony
|
||||
{
|
||||
if (PantDiff > 0.001) // jeśli nie dolega do drutu
|
||||
{ // jeśli poprzednia wysokość jest mniejsza niż pożądana, zwiększyć kąt
|
||||
@@ -3283,6 +3293,9 @@ bool TDynamicObject::Update(double dt, double dt1)
|
||||
sPantDown.Play(vol, 0, MechInside, vPosition);
|
||||
MoverParameters->PantRearSP = true;
|
||||
}
|
||||
/*
|
||||
// NOTE: disabled because it's both redundant and doesn't take into account alternative power sources
|
||||
// converter and compressor will (should) turn off during their individual checks, in the mover's (fast)computemovement() calls
|
||||
if (MoverParameters->EnginePowerSource.SourceType == CurrentCollector)
|
||||
{ // Winger 240404 - wylaczanie sprezarki i
|
||||
// przetwornicy przy braku napiecia
|
||||
@@ -3292,6 +3305,7 @@ bool TDynamicObject::Update(double dt, double dt1)
|
||||
MoverParameters->CompressorFlag = false; // Ra: to jest wątpliwe - wyłączenie sprężarki powinno być w jednym miejscu!
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
else if (MoverParameters->EnginePowerSource.SourceType == InternalSource)
|
||||
if (MoverParameters->EnginePowerSource.PowerType == SteamPower)
|
||||
@@ -3546,262 +3560,6 @@ void TDynamicObject::TurnOff()
|
||||
btMechanik1.TurnOff();
|
||||
btMechanik2.TurnOff();
|
||||
};
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
void TDynamicObject::Render()
|
||||
{ // rysowanie elementów nieprzezroczystych
|
||||
// youBy - sprawdzamy, czy jest sens renderowac
|
||||
|
||||
if (GfxRenderer.Visible(this))
|
||||
{
|
||||
TSubModel::iInstance = (size_t)this; //żeby nie robić cudzych animacji
|
||||
// AnsiString asLoadName="";
|
||||
double ObjSqrDist = SquareMagnitude(Global::pCameraPosition - vPosition) / Global::ZoomFactor;
|
||||
ABuLittleUpdate(ObjSqrDist); // ustawianie zmiennych submodeli dla wspólnego modelu
|
||||
|
||||
// Cone(vCoulpler[0],modelRot.z,0);
|
||||
// Cone(vCoulpler[1],modelRot.z,1);
|
||||
|
||||
// ActualTrack= GetTrack(); //McZapkie-240702
|
||||
|
||||
#if RENDER_CONE
|
||||
{ // Ra: testowe renderowanie pozycji wózków w postaci ostrosłupów, wymaga
|
||||
// GLUT32.DLL
|
||||
double dir = RadToDeg(atan2(vLeft.z, vLeft.x));
|
||||
Axle0.Render(0);
|
||||
Axle1.Render(1); // bogieRot[0]
|
||||
// if (PrevConnected) //renderowanie połączenia
|
||||
}
|
||||
#endif
|
||||
|
||||
glPushMatrix();
|
||||
// vector3 pos= vPosition;
|
||||
// double ObjDist= SquareMagnitude(Global::pCameraPosition-pos);
|
||||
if (this == Global::pUserDynamic)
|
||||
{ // specjalne ustawienie, aby nie trzęsło
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
if (Global::bSmudge)
|
||||
{ // jak jest widoczna smuga, to pojazd renderować po
|
||||
// wyrenderowaniu smugi
|
||||
glPopMatrix(); // a to trzeba zebrać przed wyjściem
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// if (Global::pWorld->) //tu trzeba by ustawić animacje na modelu
|
||||
// zewnętrznym
|
||||
glLoadIdentity(); // zacząć od macierzy jedynkowej
|
||||
Global::pCamera->SetCabMatrix(vPosition); // specjalne ustawienie kamery
|
||||
}
|
||||
else
|
||||
glTranslated(vPosition.x, vPosition.y,
|
||||
vPosition.z); // standardowe przesunięcie względem początku scenerii
|
||||
glMultMatrixd(mMatrix.getArray());
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
if (fShade > 0.0)
|
||||
{ // Ra: zmiana oswietlenia w tunelu, wykopie
|
||||
GLfloat ambientLight[4] = {0.5f, 0.5f, 0.5f, 1.0f};
|
||||
GLfloat diffuseLight[4] = {0.5f, 0.5f, 0.5f, 1.0f};
|
||||
GLfloat specularLight[4] = {0.5f, 0.5f, 0.5f, 1.0f};
|
||||
// trochę problem z ambientem w wykopie...
|
||||
for (int li = 0; li < 3; li++)
|
||||
{
|
||||
ambientLight[li] = Global::ambientDayLight[li] * fShade;
|
||||
diffuseLight[li] = Global::diffuseDayLight[li] * fShade;
|
||||
specularLight[li] = Global::specularDayLight[li] * fShade;
|
||||
}
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
|
||||
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
|
||||
}
|
||||
#else
|
||||
if( fShade > 0.0f ) {
|
||||
// change light level based on light level of the occupied track
|
||||
Global::DayLight.apply_intensity( fShade );
|
||||
}
|
||||
#endif
|
||||
if (Global::bUseVBO)
|
||||
{ // wersja VBO
|
||||
if (mdLowPolyInt)
|
||||
if (FreeFlyModeFlag ? true : !mdKabina || !bDisplayCab)
|
||||
mdLowPolyInt->RaRender(ObjSqrDist, ReplacableSkinID, iAlpha);
|
||||
mdModel->RaRender(ObjSqrDist, ReplacableSkinID, iAlpha);
|
||||
if (mdLoad) // renderowanie nieprzezroczystego ładunku
|
||||
mdLoad->RaRender(ObjSqrDist, ReplacableSkinID, iAlpha);
|
||||
}
|
||||
else
|
||||
{ // wersja Display Lists
|
||||
if( mdLowPolyInt ) {
|
||||
// low poly interior
|
||||
if( FreeFlyModeFlag ? true : !mdKabina || !bDisplayCab ) {
|
||||
// enable cab light if needed
|
||||
if( InteriorLightLevel > 0.0f ) {
|
||||
|
||||
// crude way to light the cabin, until we have something more complete in place
|
||||
auto const cablight = InteriorLight * InteriorLightLevel;
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
|
||||
}
|
||||
|
||||
mdLowPolyInt->Render( ObjSqrDist, ReplacableSkinID, iAlpha );
|
||||
|
||||
if( InteriorLightLevel > 0.0f ) {
|
||||
// reset the overall ambient
|
||||
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
|
||||
}
|
||||
}
|
||||
}
|
||||
mdModel->Render(ObjSqrDist, ReplacableSkinID, iAlpha);
|
||||
if (mdLoad) // renderowanie nieprzezroczystego ładunku
|
||||
mdLoad->Render(ObjSqrDist, ReplacableSkinID, iAlpha);
|
||||
}
|
||||
|
||||
// Ra: czy ta kabina tu ma sens?
|
||||
// Ra: czy nie renderuje się dwukrotnie?
|
||||
// Ra: dlaczego jest zablokowana w przezroczystych?
|
||||
if (mdKabina) // jeśli ma model kabiny
|
||||
if ((mdKabina != mdModel) && bDisplayCab && FreeFlyModeFlag)
|
||||
{ // rendering kabiny gdy jest oddzielnym modelem i
|
||||
// ma byc wyswietlana
|
||||
// ABu: tylko w trybie FreeFly, zwykly tryb w world.cpp
|
||||
// Ra: świetła są ustawione dla zewnętrza danego pojazdu
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
// TODO: re-mplement this
|
||||
// oswietlenie kabiny
|
||||
GLfloat ambientCabLight[4] = {0.5f, 0.5f, 0.5f, 1.0f};
|
||||
GLfloat diffuseCabLight[4] = {0.5f, 0.5f, 0.5f, 1.0f};
|
||||
GLfloat specularCabLight[4] = {0.5f, 0.5f, 0.5f, 1.0f};
|
||||
for (int li = 0; li < 3; li++)
|
||||
{
|
||||
ambientCabLight[li] = Global::ambientDayLight[li] * 0.9;
|
||||
diffuseCabLight[li] = Global::diffuseDayLight[li] * 0.5;
|
||||
specularCabLight[li] = Global::specularDayLight[li] * 0.5;
|
||||
}
|
||||
switch (MyTrack->eEnvironment)
|
||||
{
|
||||
case e_canyon:
|
||||
{
|
||||
for (int li = 0; li < 3; li++)
|
||||
{
|
||||
diffuseCabLight[li] *= 0.6f;
|
||||
specularCabLight[li] *= 0.7f;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case e_tunnel:
|
||||
{
|
||||
for (int li = 0; li < 3; li++)
|
||||
{
|
||||
ambientCabLight[li] *= 0.3f;
|
||||
diffuseCabLight[li] *= 0.1f;
|
||||
specularCabLight[li] *= 0.2f;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientCabLight);
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseCabLight);
|
||||
glLightfv(GL_LIGHT0, GL_SPECULAR, specularCabLight);
|
||||
#endif
|
||||
if (Global::bUseVBO)
|
||||
mdKabina->RaRender(ObjSqrDist, 0);
|
||||
else
|
||||
mdKabina->Render(ObjSqrDist, 0);
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT, Global::ambientDayLight);
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight);
|
||||
glLightfv(GL_LIGHT0, GL_SPECULAR, Global::specularDayLight);
|
||||
#endif
|
||||
}
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
if( fShade != 0.0 ) // tylko jeśli było zmieniane
|
||||
{ // przywrócenie standardowego oświetlenia
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT, Global::ambientDayLight);
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight);
|
||||
glLightfv(GL_LIGHT0, GL_SPECULAR, Global::specularDayLight);
|
||||
}
|
||||
#else
|
||||
if( fShade > 0.0f ) {
|
||||
// restore regular light level
|
||||
Global::DayLight.apply_intensity();
|
||||
}
|
||||
#endif
|
||||
glPopMatrix();
|
||||
if (btnOn)
|
||||
TurnOff(); // przywrócenie domyślnych pozycji submodeli
|
||||
} // yB - koniec mieszania z grafika
|
||||
};
|
||||
|
||||
void TDynamicObject::RenderAlpha()
|
||||
{ // rysowanie elementów półprzezroczystych
|
||||
if (renderme)
|
||||
{
|
||||
TSubModel::iInstance = (size_t)this; //żeby nie robić cudzych animacji
|
||||
double ObjSqrDist = SquareMagnitude(Global::pCameraPosition - vPosition);
|
||||
ABuLittleUpdate(ObjSqrDist); // ustawianie zmiennych submodeli dla wspólnego modelu
|
||||
glPushMatrix();
|
||||
if (this == Global::pUserDynamic)
|
||||
{ // specjalne ustawienie, aby nie trzęsło
|
||||
glPopMatrix(); // to trzeba zebrać przed wyściem
|
||||
return;
|
||||
glLoadIdentity(); // zacząć od macierzy jedynkowej
|
||||
Global::pCamera->SetCabMatrix(vPosition); // specjalne ustawienie kamery
|
||||
}
|
||||
else
|
||||
glTranslated(vPosition.x, vPosition.y,
|
||||
vPosition.z); // standardowe przesunięcie względem początku scenerii
|
||||
glMultMatrixd(mMatrix.getArray());
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
// TODO: re-implement this
|
||||
if (fShade > 0.0)
|
||||
{ // Ra: zmiana oswietlenia w tunelu, wykopie
|
||||
GLfloat ambientLight[4] = {0.5f, 0.5f, 0.5f, 1.0f};
|
||||
GLfloat diffuseLight[4] = {0.5f, 0.5f, 0.5f, 1.0f};
|
||||
GLfloat specularLight[4] = {0.5f, 0.5f, 0.5f, 1.0f};
|
||||
// trochę problem z ambientem w wykopie...
|
||||
for (int li = 0; li < 3; li++)
|
||||
{
|
||||
ambientLight[li] = Global::ambientDayLight[li] * fShade;
|
||||
diffuseLight[li] = Global::diffuseDayLight[li] * fShade;
|
||||
specularLight[li] = Global::specularDayLight[li] * fShade;
|
||||
}
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientLight);
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseLight);
|
||||
glLightfv(GL_LIGHT0, GL_SPECULAR, specularLight);
|
||||
}
|
||||
#endif
|
||||
if (Global::bUseVBO)
|
||||
{ // wersja VBO
|
||||
if (mdLowPolyInt)
|
||||
if (FreeFlyModeFlag ? true : !mdKabina || !bDisplayCab)
|
||||
mdLowPolyInt->RaRenderAlpha(ObjSqrDist, ReplacableSkinID, iAlpha);
|
||||
mdModel->RaRenderAlpha(ObjSqrDist, ReplacableSkinID, iAlpha);
|
||||
if (mdLoad)
|
||||
mdLoad->RaRenderAlpha(ObjSqrDist, ReplacableSkinID, iAlpha);
|
||||
}
|
||||
else
|
||||
{ // wersja Display Lists
|
||||
if (mdLowPolyInt)
|
||||
if (FreeFlyModeFlag ? true : !mdKabina || !bDisplayCab)
|
||||
mdLowPolyInt->RenderAlpha(ObjSqrDist, ReplacableSkinID, iAlpha);
|
||||
mdModel->RenderAlpha(ObjSqrDist, ReplacableSkinID, iAlpha);
|
||||
if (mdLoad)
|
||||
mdLoad->RenderAlpha(ObjSqrDist, ReplacableSkinID, iAlpha);
|
||||
}
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
// TODO: re-implement this
|
||||
if (fShade != 0.0) // tylko jeśli było zmieniane
|
||||
{ // przywrócenie standardowego oświetlenia
|
||||
glLightfv(GL_LIGHT0, GL_AMBIENT, Global::ambientDayLight);
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight);
|
||||
glLightfv(GL_LIGHT0, GL_SPECULAR, Global::specularDayLight);
|
||||
}
|
||||
#endif
|
||||
glPopMatrix();
|
||||
if (btnOn)
|
||||
TurnOff(); // przywrócenie domyślnych pozycji submodeli
|
||||
}
|
||||
return;
|
||||
} // koniec renderalpha
|
||||
#endif
|
||||
|
||||
void TDynamicObject::RenderSounds()
|
||||
{ // przeliczanie dźwięków, bo będzie słychać bez wyświetlania sektora z pojazdem
|
||||
@@ -4124,22 +3882,20 @@ void TDynamicObject::RenderSounds()
|
||||
sConverter.TurnOff(MechInside, GetPosition());
|
||||
sConverter.Update(MechInside, GetPosition());
|
||||
}
|
||||
if (MoverParameters->WarningSignal > 0)
|
||||
{
|
||||
if (TestFlag(MoverParameters->WarningSignal, 1))
|
||||
sHorn1.TurnOn(MechInside, GetPosition());
|
||||
else
|
||||
sHorn1.TurnOff(MechInside, GetPosition());
|
||||
if (TestFlag(MoverParameters->WarningSignal, 2))
|
||||
sHorn2.TurnOn(MechInside, GetPosition());
|
||||
else
|
||||
sHorn2.TurnOff(MechInside, GetPosition());
|
||||
|
||||
if( TestFlag( MoverParameters->WarningSignal, 1 ) ) {
|
||||
sHorn1.TurnOn( MechInside, GetPosition() );
|
||||
}
|
||||
else
|
||||
{
|
||||
sHorn1.TurnOff(MechInside, GetPosition());
|
||||
sHorn2.TurnOff(MechInside, GetPosition());
|
||||
else {
|
||||
sHorn1.TurnOff( MechInside, GetPosition() );
|
||||
}
|
||||
if( TestFlag( MoverParameters->WarningSignal, 2 ) ) {
|
||||
sHorn2.TurnOn( MechInside, GetPosition() );
|
||||
}
|
||||
else {
|
||||
sHorn2.TurnOff( MechInside, GetPosition() );
|
||||
}
|
||||
|
||||
if (MoverParameters->DoorClosureWarning)
|
||||
{
|
||||
if (MoverParameters->DepartureSignal) // NBMX sygnal odjazdu, MC: pod warunkiem ze jest
|
||||
@@ -4195,26 +3951,6 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
|
||||
if( token == "models:") {
|
||||
// modele i podmodele
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
iMultiTex = 0; // czy jest wiele tekstur wymiennych?
|
||||
parser.getTokens();
|
||||
parser >> asModel;
|
||||
if( asModel[asModel.size() - 1] == '#' ) // Ra 2015-01: nie podoba mi siê to
|
||||
{ // model wymaga wielu tekstur wymiennych
|
||||
iMultiTex = 1;
|
||||
asModel.erase( asModel.length() - 1 );
|
||||
}
|
||||
std::size_t i = asModel.find( ',' );
|
||||
if ( i != std::string::npos )
|
||||
{ // Ra 2015-01: może szukać przecinka w nazwie modelu, a po przecinku była by liczba tekstur?
|
||||
if (i < asModel.length())
|
||||
iMultiTex = asModel[i + 1] - '0';
|
||||
if (iMultiTex < 0)
|
||||
iMultiTex = 0;
|
||||
else if (iMultiTex > 1)
|
||||
iMultiTex = 1; // na razie ustawiamy na 1
|
||||
}
|
||||
#else
|
||||
m_materialdata.multi_textures = 0; // czy jest wiele tekstur wymiennych?
|
||||
parser.getTokens();
|
||||
parser >> asModel;
|
||||
@@ -4230,71 +3966,13 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
m_materialdata.multi_textures = asModel[i + 1] - '0';
|
||||
m_materialdata.multi_textures = clamp( m_materialdata.multi_textures, 0, 1 ); // na razie ustawiamy na 1
|
||||
}
|
||||
#endif
|
||||
asModel = BaseDir + asModel; // McZapkie 2002-07-20: dynamics maja swoje
|
||||
// modele w dynamics/basedir
|
||||
Global::asCurrentTexturePath = BaseDir; // biezaca sciezka do tekstur to dynamic/...
|
||||
mdModel = TModelsManager::GetModel(asModel, true);
|
||||
assert( mdModel != nullptr ); // TODO: handle this more gracefully than all going to shit
|
||||
if (ReplacableSkin != "none")
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
{ // tekstura wymienna jest raczej jedynie w "dynamic\"
|
||||
ReplacableSkin =
|
||||
Global::asCurrentTexturePath + ReplacableSkin; // skory tez z dynamic/...
|
||||
std::string x = TextureTest(Global::asCurrentTexturePath + "nowhere"); // na razie prymitywnie
|
||||
if (!x.empty())
|
||||
ReplacableSkinID[4] = GfxRenderer.GetTextureId( Global::asCurrentTexturePath + "nowhere", "", 9);
|
||||
|
||||
if (iMultiTex > 0)
|
||||
{ // jeśli model ma 4 tekstury
|
||||
ReplacableSkinID[1] = GfxRenderer.GetTextureId(
|
||||
ReplacableSkin + ",1", "", Global::iDynamicFiltering);
|
||||
if (ReplacableSkinID[1])
|
||||
{ // pierwsza z zestawu znaleziona
|
||||
ReplacableSkinID[2] = GfxRenderer.GetTextureId(
|
||||
ReplacableSkin + ",2", "", Global::iDynamicFiltering);
|
||||
if (ReplacableSkinID[2])
|
||||
{
|
||||
iMultiTex = 2; // już są dwie
|
||||
ReplacableSkinID[3] = GfxRenderer.GetTextureId(
|
||||
ReplacableSkin + ",3", "", Global::iDynamicFiltering);
|
||||
if (ReplacableSkinID[3])
|
||||
{
|
||||
iMultiTex = 3; // a teraz nawet trzy
|
||||
ReplacableSkinID[4] = GfxRenderer.GetTextureId(
|
||||
ReplacableSkin + ",4", "", Global::iDynamicFiltering);
|
||||
if (ReplacableSkinID[4])
|
||||
iMultiTex = 4; // jak są cztery, to blokujemy podmianę tekstury rozkładem
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // zestaw nie zadziałał, próbujemy normanie
|
||||
iMultiTex = 0;
|
||||
ReplacableSkinID[1] = GfxRenderer.GetTextureId(
|
||||
ReplacableSkin, "", Global::iDynamicFiltering);
|
||||
}
|
||||
}
|
||||
else
|
||||
ReplacableSkinID[1] = GfxRenderer.GetTextureId(
|
||||
ReplacableSkin, "", Global::iDynamicFiltering);
|
||||
if (GfxRenderer.Texture(ReplacableSkinID[1]).has_alpha)
|
||||
iAlpha = 0x31310031; // tekstura -1 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
else
|
||||
iAlpha = 0x30300030; // wszystkie tekstury nieprzezroczyste - nie renderować w cyklu przezroczystych
|
||||
if (ReplacableSkinID[2])
|
||||
if (GfxRenderer.Texture(ReplacableSkinID[2]).has_alpha)
|
||||
iAlpha |= 0x02020002; // tekstura -2 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
if (ReplacableSkinID[3])
|
||||
if (GfxRenderer.Texture(ReplacableSkinID[3]).has_alpha)
|
||||
iAlpha |= 0x04040004; // tekstura -3 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
if (ReplacableSkinID[4])
|
||||
if (GfxRenderer.Texture(ReplacableSkinID[4]).has_alpha)
|
||||
iAlpha |= 0x08080008; // tekstura -4 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
}
|
||||
#else
|
||||
{ // tekstura wymienna jest raczej jedynie w "dynamic\"
|
||||
// ReplacableSkin = Global::asCurrentTexturePath + ReplacableSkin; // skory tez z dynamic/...
|
||||
{
|
||||
std::string nowheretexture = TextureTest(Global::asCurrentTexturePath + "nowhere"); // na razie prymitywnie
|
||||
if( false == nowheretexture.empty() ) {
|
||||
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.GetTextureId( nowheretexture, "", 9 );
|
||||
@@ -4349,7 +4027,6 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
if( GfxRenderer.Texture( m_materialdata.replacable_skins[ 4 ] ).has_alpha )
|
||||
m_materialdata.textures_alpha |= 0x08080008; // tekstura -4 z kanałem alfa - nie renderować w cyklu nieprzezroczystych
|
||||
}
|
||||
#endif
|
||||
if (!MoverParameters->LoadAccepted.empty())
|
||||
// if (MoverParameters->LoadAccepted!=AnsiString("")); // &&
|
||||
// MoverParameters->LoadType!=AnsiString("passengers"))
|
||||
@@ -5056,7 +4733,7 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
// plik z przyspieszaczem (upust po zlapaniu hamowania)
|
||||
// sBrakeAcc.Init(str.c_str(),Parser->GetNextSymbol().ToDouble(),GetPosition().x,GetPosition().y,GetPosition().z,true);
|
||||
parser.getTokens( 1, false ); parser >> token;
|
||||
sBrakeAcc = TSoundsManager::GetFromName( token.c_str(), true );
|
||||
sBrakeAcc = TSoundsManager::GetFromName( token, true );
|
||||
bBrakeAcc = true;
|
||||
// sBrakeAcc.AM=1.0;
|
||||
// sBrakeAcc.AA=0.0;
|
||||
@@ -5271,10 +4948,19 @@ void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||||
//---------------------------------------------------------------------------
|
||||
void TDynamicObject::RadioStop()
|
||||
{ // zatrzymanie pojazdu
|
||||
if (Mechanik) // o ile ktoś go prowadzi
|
||||
if (MoverParameters->SecuritySystem.RadioStop &&
|
||||
MoverParameters->Radio) // jeśli pojazd ma RadioStop i jest on aktywny
|
||||
Mechanik->PutCommand("Emergency_brake", 1.0, 1.0, &vPosition, stopRadio);
|
||||
if( Mechanik ) {
|
||||
// o ile ktoś go prowadzi
|
||||
if( ( MoverParameters->SecuritySystem.RadioStop )
|
||||
&& ( MoverParameters->Radio ) ) {
|
||||
// jeśli pojazd ma RadioStop i jest on aktywny
|
||||
Mechanik->PutCommand( "Emergency_brake", 1.0, 1.0, &vPosition, stopRadio );
|
||||
// add onscreen notification for human driver
|
||||
// TODO: do it selectively for the 'local' driver once the multiplayer is in
|
||||
if( false == Mechanik->AIControllFlag ) {
|
||||
Global::tranTexts.AddLine( "!! RADIO-STOP !!", 0.0, 10.0, false );
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -5552,22 +5238,27 @@ TDynamicObject * TDynamicObject::ControlledFind()
|
||||
// jeździć dobrze
|
||||
// również hamowanie wykonuje się zaworem w członie, a nie w silnikowym...
|
||||
TDynamicObject *d = this; // zaczynamy od aktualnego
|
||||
if (d->MoverParameters->TrainType & dt_EZT) // na razie dotyczy to EZT
|
||||
if (d->NextConnected ? d->MoverParameters->Couplers[1].AllowedFlag & ctrain_depot : false)
|
||||
{ // gdy jest człon od sprzęgu 1, a sprzęg łączony
|
||||
// warsztatowo (powiedzmy)
|
||||
if ((d->MoverParameters->Power < 1.0) && (d->NextConnected->MoverParameters->Power >
|
||||
1.0)) // my nie mamy mocy, ale ten drugi ma
|
||||
if( d->MoverParameters->TrainType & dt_EZT ) {
|
||||
// na razie dotyczy to EZT
|
||||
if( ( d->NextConnected != nullptr )
|
||||
&& ( true == TestFlag( d->MoverParameters->Couplers[ 1 ].AllowedFlag, coupling::permanent ) ) ) {
|
||||
// gdy jest człon od sprzęgu 1, a sprzęg łączony warsztatowo (powiedzmy)
|
||||
if( ( d->MoverParameters->Power < 1.0 )
|
||||
&& ( d->NextConnected->MoverParameters->Power > 1.0 ) ) {
|
||||
// my nie mamy mocy, ale ten drugi ma
|
||||
d = d->NextConnected; // będziemy sterować tym z mocą
|
||||
}
|
||||
}
|
||||
else if (d->PrevConnected ? d->MoverParameters->Couplers[0].AllowedFlag & ctrain_depot :
|
||||
false)
|
||||
{ // gdy jest człon od sprzęgu 0, a sprzęg łączony
|
||||
// warsztatowo (powiedzmy)
|
||||
if ((d->MoverParameters->Power < 1.0) && (d->PrevConnected->MoverParameters->Power >
|
||||
1.0)) // my nie mamy mocy, ale ten drugi ma
|
||||
else if( ( d->PrevConnected != nullptr )
|
||||
&& ( true == TestFlag( d->MoverParameters->Couplers[ 0 ].AllowedFlag, coupling::permanent ) ) ) {
|
||||
// gdy jest człon od sprzęgu 0, a sprzęg łączony warsztatowo (powiedzmy)
|
||||
if( ( d->MoverParameters->Power < 1.0 )
|
||||
&& ( d->PrevConnected->MoverParameters->Power > 1.0 ) ) {
|
||||
// my nie mamy mocy, ale ten drugi ma
|
||||
d = d->PrevConnected; // będziemy sterować tym z mocą
|
||||
}
|
||||
}
|
||||
}
|
||||
return d;
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -5631,62 +5322,16 @@ std::string TDynamicObject::TextureTest(std::string const &name)
|
||||
return ""; // nie znaleziona
|
||||
};
|
||||
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
void TDynamicObject::DestinationSet(std::string to, std::string numer)
|
||||
{ // ustawienie stacji
|
||||
// docelowej oraz wymiennej
|
||||
// tekstury 4, jeśli
|
||||
// istnieje plik
|
||||
// w zasadzie, to każdy wagon mógłby mieć inną stację docelową
|
||||
// zwłaszcza w towarowych, pod kątem zautomatyzowania maewrów albo pracy górki
|
||||
// ale to jeszcze potrwa, zanim będzie możliwe, na razie można wpisać stację z
|
||||
// rozkładu
|
||||
if (abs(iMultiTex) >= 4)
|
||||
return; // jak są 4 tekstury wymienne, to nie zmieniać rozkładem
|
||||
numer = Global::Bezogonkow(numer);
|
||||
asDestination = to;
|
||||
to = Global::Bezogonkow(to); // do szukania pliku obcinamy ogonki
|
||||
std::string x = TextureTest(asBaseDir + numer + "@" + MoverParameters->TypeName);
|
||||
if (!x.empty())
|
||||
{
|
||||
ReplacableSkinID[4] = GfxRenderer.GetTextureId( x, "", 9); // rozmywania 0,1,4,5 nie nadają się
|
||||
return;
|
||||
}
|
||||
x = TextureTest(asBaseDir + numer );
|
||||
if (!x.empty())
|
||||
{
|
||||
ReplacableSkinID[4] = GfxRenderer.GetTextureId( x, "", 9); // rozmywania 0,1,4,5 nie nadają się
|
||||
return;
|
||||
}
|
||||
if (to.empty())
|
||||
to = "nowhere";
|
||||
x = TextureTest(asBaseDir + to + "@" + MoverParameters->TypeName); // w pierwszej kolejności z nazwą FIZ/MMD
|
||||
if (!x.empty())
|
||||
{
|
||||
ReplacableSkinID[4] = GfxRenderer.GetTextureId( x, "", 9); // rozmywania 0,1,4,5 nie nadają się
|
||||
return;
|
||||
}
|
||||
x = TextureTest(asBaseDir + to); // na razie prymitywnie
|
||||
if (!x.empty())
|
||||
ReplacableSkinID[4] = GfxRenderer.GetTextureId( x, "", 9); // rozmywania 0,1,4,5 nie nadają się
|
||||
else
|
||||
{
|
||||
x = TextureTest(asBaseDir + "nowhere"); // jak nie znalazł dedykowanej, to niech daje nowhere
|
||||
if (!x.empty())
|
||||
ReplacableSkinID[4] = GfxRenderer.GetTextureId( x, "", 9);
|
||||
}
|
||||
// Ra 2015-01: żeby zalogować błąd, trzeba by mieć pewność, że model używa
|
||||
// tekstury nr 4
|
||||
};
|
||||
#else
|
||||
void TDynamicObject::DestinationSet(std::string to, std::string numer)
|
||||
{ // ustawienie stacji docelowej oraz wymiennej tekstury 4, jeśli istnieje plik
|
||||
// w zasadzie, to każdy wagon mógłby mieć inną stację docelową
|
||||
// zwłaszcza w towarowych, pod kątem zautomatyzowania maewrów albo pracy górki
|
||||
// ale to jeszcze potrwa, zanim będzie możliwe, na razie można wpisać stację z
|
||||
// rozkładu
|
||||
if( std::abs( m_materialdata.multi_textures ) >= 4 )
|
||||
return; // jak są 4 tekstury wymienne, to nie zmieniać rozkładem
|
||||
if( std::abs( m_materialdata.multi_textures ) >= 4 ) {
|
||||
// jak są 4 tekstury wymienne, to nie zmieniać rozkładem
|
||||
return;
|
||||
}
|
||||
numer = Global::Bezogonkow(numer);
|
||||
asDestination = to;
|
||||
to = Global::Bezogonkow(to); // do szukania pliku obcinamy ogonki
|
||||
@@ -5719,10 +5364,8 @@ void TDynamicObject::DestinationSet(std::string to, std::string numer)
|
||||
if (!x.empty())
|
||||
m_materialdata.replacable_skins[ 4 ] = GfxRenderer.GetTextureId( x, "", 9 );
|
||||
}
|
||||
// Ra 2015-01: żeby zalogować błąd, trzeba by mieć pewność, że model używa
|
||||
// tekstury nr 4
|
||||
// Ra 2015-01: żeby zalogować błąd, trzeba by mieć pewność, że model używa tekstury nr 4
|
||||
};
|
||||
#endif
|
||||
|
||||
void TDynamicObject::OverheadTrack(float o)
|
||||
{ // ewentualne wymuszanie jazdy
|
||||
|
||||
20
DynObj.h
20
DynObj.h
@@ -137,11 +137,8 @@ class TAnim
|
||||
void Parovoz(); // wykonanie obliczeń animacji
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef EU07_USE_OLD_RENDERCODE
|
||||
// parameters for the material object, as currently used by various simulator models
|
||||
struct material_data {
|
||||
|
||||
@@ -153,7 +150,6 @@ struct material_data {
|
||||
::SecureZeroMemory( replacable_skins, sizeof( replacable_skins ) );
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
class TDynamicObject { // klasa pojazdu
|
||||
|
||||
@@ -200,15 +196,11 @@ public: // modele składowe pojazdu
|
||||
float fShade; // zacienienie: 0:normalnie, -1:w ciemności, +1:dodatkowe światło (brak koloru?)
|
||||
|
||||
private: // zmienne i metody do animacji submodeli; Ra: sprzatam animacje w pojeździe
|
||||
#ifndef EU07_USE_OLD_RENDERCODE
|
||||
material_data m_materialdata;
|
||||
#endif
|
||||
|
||||
public:
|
||||
#ifndef EU07_USE_OLD_RENDERCODE
|
||||
inline
|
||||
material_data const *Material() const { return &m_materialdata; }
|
||||
#endif
|
||||
material_data const *Material() const { return &m_materialdata; }
|
||||
// tymczasowo udostępnione do wyszukiwania drutu
|
||||
int iAnimType[ ANIM_TYPES ]; // 0-osie,1-drzwi,2-obracane,3-zderzaki,4-wózki,5-pantografy,6-tłoki
|
||||
private:
|
||||
@@ -421,11 +413,6 @@ public: // modele składowe pojazdu
|
||||
int iCabs; // maski bitowe modeli kabin
|
||||
TTrack *MyTrack; // McZapkie-030303: tor na ktorym stoi, ABu
|
||||
std::string asBaseDir;
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
texture_manager::size_type ReplacableSkinID[5]; // McZapkie:zmienialne nadwozie
|
||||
int iAlpha; // maska przezroczystości tekstur
|
||||
int iMultiTex; //<0 tekstury wskazane wpisem, >0 tekstury z przecinkami, =0 jedna
|
||||
#endif
|
||||
int iOverheadMask; // maska przydzielana przez AI pojazdom posiadającym pantograf, aby wymuszały
|
||||
// jazdę bezprądową
|
||||
TTractionParam tmpTraction;
|
||||
@@ -444,10 +431,6 @@ public: // modele składowe pojazdu
|
||||
bool FastUpdate(double dt);
|
||||
void Move(double fDistance);
|
||||
void FastMove(double fDistance);
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
void Render();
|
||||
void RenderAlpha();
|
||||
#endif
|
||||
void RenderSounds();
|
||||
inline vector3 GetPosition() const
|
||||
{
|
||||
@@ -546,6 +529,7 @@ public: // modele składowe pojazdu
|
||||
std::string TextureTest(std::string const &name);
|
||||
void OverheadTrack(float o);
|
||||
double MED[9][8]; // lista zmiennych do debugowania hamulca ED
|
||||
static std::string const MED_labels[ 8 ];
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
51
EU07.cpp
51
EU07.cpp
@@ -9,7 +9,6 @@ http://mozilla.org/MPL/2.0/.
|
||||
/*
|
||||
MaSzyna EU07 locomotive simulator
|
||||
Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others
|
||||
|
||||
*/
|
||||
/*
|
||||
Authors:
|
||||
@@ -40,6 +39,7 @@ Stele, firleju, szociu, hunter, ZiomalCl, OLI_EU and others
|
||||
#pragma comment (lib, "winmm.lib")
|
||||
#pragma comment (lib, "setupapi.lib")
|
||||
#pragma comment (lib, "dbghelp.lib")
|
||||
#pragma comment (lib, "version.lib")
|
||||
|
||||
TWorld World;
|
||||
|
||||
@@ -195,7 +195,9 @@ int main(int argc, char *argv[])
|
||||
SetConsoleTextAttribute( GetStdHandle( STD_OUTPUT_HANDLE ), FOREGROUND_GREEN );
|
||||
}
|
||||
|
||||
for (int i = 1; i < argc; i++)
|
||||
Global::asVersion = "NG";
|
||||
|
||||
for (int i = 1; i < argc; ++i)
|
||||
{
|
||||
std::string token(argv[i]);
|
||||
|
||||
@@ -297,20 +299,17 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
|
||||
Global::pWorld = &World; // Ra: wskaźnik potrzebny do usuwania pojazdów
|
||||
try
|
||||
{
|
||||
if ((false == GfxRenderer.Init(window))
|
||||
|| (false == UILayer.init(window)))
|
||||
return -1;
|
||||
input::Keyboard.init();
|
||||
input::Gamepad.init();
|
||||
try {
|
||||
if( false == World.Init( window ) ) {
|
||||
ErrorLog( "Failed to init TWorld" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
catch( std::bad_alloc const &Error ) {
|
||||
|
||||
if (!World.Init(window))
|
||||
{
|
||||
std::cout << "failed to init TWorld" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
ErrorLog( "Critical error, memory allocation failure: " + std::string( Error.what() ) );
|
||||
return -1;
|
||||
}
|
||||
catch (std::runtime_error e)
|
||||
{
|
||||
WriteLog(e.what());
|
||||
@@ -334,13 +333,23 @@ int main(int argc, char *argv[])
|
||||
} // po zrobieniu E3D odpalamy normalnie scenerię, by ją zobaczyć
|
||||
|
||||
Console::On(); // włączenie konsoli
|
||||
while (!glfwWindowShouldClose(window)
|
||||
&& World.Update()
|
||||
&& GfxRenderer.Render())
|
||||
{
|
||||
glfwPollEvents();
|
||||
input::Gamepad.poll();
|
||||
|
||||
try {
|
||||
while( ( false == glfwWindowShouldClose( window ) )
|
||||
&& ( true == World.Update() )
|
||||
&& ( true == GfxRenderer.Render() ) ) {
|
||||
glfwPollEvents();
|
||||
if( true == Global::InputGamepad ) {
|
||||
input::Gamepad.poll();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( std::bad_alloc const &Error ) {
|
||||
|
||||
ErrorLog( "Critical error, memory allocation failure: " + std::string( Error.what() ) );
|
||||
return -1;
|
||||
}
|
||||
|
||||
Console::Off(); // wyłączenie konsoli (komunikacji zwrotnej)
|
||||
}
|
||||
|
||||
|
||||
34
Event.cpp
34
Event.cpp
@@ -610,14 +610,32 @@ void TEvent::Load(cParser *parser, vector3 *org)
|
||||
}
|
||||
};
|
||||
|
||||
void TEvent::AddToQuery(TEvent *e)
|
||||
{ // dodanie eventu do kolejki
|
||||
if (evNext ? (e->fStartTime >= evNext->fStartTime) : false)
|
||||
evNext->AddToQuery(e); // sortowanie wg czasu
|
||||
else
|
||||
{ // dodanie z przodu
|
||||
e->evNext = evNext;
|
||||
evNext = e;
|
||||
void TEvent::AddToQuery( TEvent *Event, TEvent *&Start ) {
|
||||
|
||||
TEvent *target( Start );
|
||||
TEvent *previous( nullptr );
|
||||
while( ( Event->fStartTime >= target->fStartTime )
|
||||
&& ( target->evNext != nullptr ) ) {
|
||||
previous = target;
|
||||
target = target->evNext;
|
||||
}
|
||||
// the new event will be either before or after the one we located
|
||||
if( Event->fStartTime >= target->fStartTime ) {
|
||||
assert( target->evNext == nullptr );
|
||||
target->evNext = Event;
|
||||
// if we have resurrected event land at the end of list, the link from previous run could potentially "add" unwanted events to the queue
|
||||
Event->evNext = nullptr;
|
||||
}
|
||||
else {
|
||||
if( previous != nullptr ) {
|
||||
previous->evNext = Event;
|
||||
Event->evNext = target;
|
||||
}
|
||||
else {
|
||||
// special case, we're inserting our event before the provided start point
|
||||
Event->evNext = Start;
|
||||
Start = Event;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
2
Event.h
2
Event.h
@@ -105,7 +105,7 @@ class TEvent // zmienne: ev*
|
||||
~TEvent();
|
||||
void Init();
|
||||
void Load(cParser *parser, vector3 *org);
|
||||
void AddToQuery(TEvent *e);
|
||||
static void AddToQuery( TEvent *Event, TEvent *&Start );
|
||||
std::string CommandGet();
|
||||
TCommandType Command();
|
||||
double ValueGet(int n);
|
||||
|
||||
@@ -25,7 +25,7 @@ void TFadeSound::Free()
|
||||
{
|
||||
}
|
||||
|
||||
void TFadeSound::Init(char *Name, float fNewFade)
|
||||
void TFadeSound::Init(std::string const &Name, float fNewFade)
|
||||
{
|
||||
Sound = TSoundsManager::GetFromName(Name, false);
|
||||
if (Sound)
|
||||
|
||||
@@ -24,7 +24,7 @@ class TFadeSound
|
||||
public:
|
||||
TFadeSound();
|
||||
~TFadeSound();
|
||||
void Init(char *Name, float fNewFade);
|
||||
void Init(std::string const &Name, float fNewFade);
|
||||
void TurnOn();
|
||||
void TurnOff();
|
||||
bool Playing()
|
||||
|
||||
21
Globals.cpp
21
Globals.cpp
@@ -32,8 +32,7 @@ std::string Global::AppName{ "EU07" };
|
||||
std::string Global::asCurrentSceneryPath = "scenery/";
|
||||
std::string Global::asCurrentTexturePath = std::string(szTexturePath);
|
||||
std::string Global::asCurrentDynamicPath = "";
|
||||
int Global::iSlowMotion =
|
||||
0; // info o malym FPS: 0-OK, 1-wyłączyć multisampling, 3-promień 1.5km, 7-1km
|
||||
int Global::iSlowMotion = 0; // info o malym FPS: 0-OK, 1-wyłączyć multisampling, 3-promień 1.5km, 7-1km
|
||||
TDynamicObject *Global::changeDynObj = NULL; // info o zmianie pojazdu
|
||||
double Global::ABuDebug = 0;
|
||||
std::string Global::asSky = "1";
|
||||
@@ -48,8 +47,7 @@ GLFWwindow *Global::window;
|
||||
bool Global::shiftState;
|
||||
bool Global::ctrlState;
|
||||
int Global::iCameraLast = -1;
|
||||
std::string Global::asRelease = "NG";
|
||||
std::string Global::asVersion = "EU07++NG";
|
||||
std::string Global::asVersion = "UNKNOWN";
|
||||
int Global::iTextMode = 0; // tryb pracy wyświetlacza tekstowego
|
||||
int Global::iScreenMode[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // numer ekranu wyświetlacza tekstowego
|
||||
double Global::fSunDeclination = 0.0; // deklinacja Słońca
|
||||
@@ -84,16 +82,7 @@ GLfloat Global::FogColor[] = {0.6f, 0.7f, 0.8f};
|
||||
double Global::fFogStart = 1700;
|
||||
double Global::fFogEnd = 2000;
|
||||
float Global::Overcast{ 0.1f }; // NOTE: all this weather stuff should be moved elsewhere
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
GLfloat Global::ambientDayLight[] = {0.40f, 0.40f, 0.45f, 1.0f}; // robocze
|
||||
GLfloat Global::diffuseDayLight[] = {0.55f, 0.54f, 0.50f, 1.0f};
|
||||
GLfloat Global::specularDayLight[] = {0.95f, 0.94f, 0.90f, 1.0f};
|
||||
GLfloat Global::ambientLight[] = {0.80f, 0.80f, 0.85f, 1.0f}; // stałe
|
||||
GLfloat Global::diffuseLight[] = {0.85f, 0.85f, 0.80f, 1.0f};
|
||||
GLfloat Global::specularLight[] = {0.95f, 0.94f, 0.90f, 1.0f};
|
||||
#else
|
||||
int Global::DynamicLightCount = 7;
|
||||
#endif
|
||||
GLfloat Global::whiteLight[] = {1.00f, 1.00f, 1.00f, 1.0f};
|
||||
GLfloat Global::noLight[] = {0.00f, 0.00f, 0.00f, 1.0f};
|
||||
GLfloat Global::darkLight[] = {0.03f, 0.03f, 0.03f, 1.0f}; //śladowe
|
||||
@@ -110,6 +99,7 @@ int Global::iWindowHeight = 600;
|
||||
float Global::fDistanceFactor = Global::ScreenHeight / 768.0; // baza do przeliczania odległości dla LoD
|
||||
int Global::iFeedbackMode = 1; // tryb pracy informacji zwrotnej
|
||||
int Global::iFeedbackPort = 0; // dodatkowy adres dla informacji zwrotnych
|
||||
bool Global::InputGamepad{ true };
|
||||
bool Global::bFreeFly = false;
|
||||
bool Global::bFullScreen = false;
|
||||
bool Global::VSync{ false };
|
||||
@@ -796,6 +786,11 @@ void Global::ConfigParse(cParser &Parser)
|
||||
>> Global::Background[1] // g
|
||||
>> Global::Background[2]; // b
|
||||
}
|
||||
else if( token == "input.gamepad" ) {
|
||||
// czy grupować eventy o tych samych nazwach
|
||||
Parser.getTokens();
|
||||
Parser >> Global::InputGamepad;
|
||||
}
|
||||
// maciek001: ustawienia MWD
|
||||
else if (token == "mwdmasterenable") { // główne włączenie maszyny!
|
||||
Parser.getTokens();
|
||||
|
||||
17
Globals.h
17
Globals.h
@@ -130,7 +130,9 @@ class TTranscript
|
||||
float fHide; // czas ukrycia/usunięcia
|
||||
std::string asText; // tekst gotowy do wyświetlenia (usunięte znaczniki czasu)
|
||||
bool bItalic; // czy kursywa (dźwięk nieistotny dla prowadzącego)
|
||||
/*
|
||||
int iNext; // następna używana linijka, żeby nie przestawiać fizycznie tabeli
|
||||
*/
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -219,19 +221,10 @@ class Global
|
||||
static GLfloat FogColor[];
|
||||
static float Overcast;
|
||||
// static bool bTimeChange;
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
static opengl_light AmbientLight;
|
||||
|
||||
static GLfloat ambientDayLight[];
|
||||
static GLfloat diffuseDayLight[];
|
||||
static GLfloat specularDayLight[];
|
||||
static GLfloat ambientLight[];
|
||||
static GLfloat diffuseLight[];
|
||||
static GLfloat specularLight[];
|
||||
#else
|
||||
// TODO: put these things in the renderer
|
||||
static int DynamicLightCount;
|
||||
#endif
|
||||
|
||||
static GLfloat whiteLight[];
|
||||
static GLfloat noLight[];
|
||||
static GLfloat darkLight[];
|
||||
@@ -251,6 +244,7 @@ class Global
|
||||
static std::string LastGLError;
|
||||
static int iFeedbackMode; // tryb pracy informacji zwrotnej
|
||||
static int iFeedbackPort; // dodatkowy adres dla informacji zwrotnych
|
||||
static bool InputGamepad; // whether gamepad support is enabled
|
||||
static double fLuminance; // jasność światła do automatycznego zapalania
|
||||
static float SunAngle; // angle of the sun relative to horizon
|
||||
static int iMultiplayer; // blokada działania niektórych eventów na rzecz kominikacji
|
||||
@@ -262,7 +256,6 @@ class Global
|
||||
static float ZoomFactor; // determines current camera zoom level. TODO: move it to the renderer
|
||||
static float FieldOfView; // vertical field of view for the camera. TODO: move it to the renderer
|
||||
static int iCameraLast;
|
||||
static std::string asRelease; // numer
|
||||
static std::string asVersion; // z opisem
|
||||
static GLint iMaxTextureSize; // maksymalny rozmiar tekstury
|
||||
static int iTextMode; // tryb pracy wyświetlacza tekstowego
|
||||
@@ -283,7 +276,7 @@ class Global
|
||||
static bool bGlutFont; // tekst generowany przez GLUT
|
||||
static int iKeyLast; // ostatnio naciśnięty klawisz w celu logowania
|
||||
static int iPause; // globalna pauza ruchu: b0=start,b1=klawisz,b2=tło,b3=lagi,b4=wczytywanie
|
||||
static void BindTexture(GLuint t);
|
||||
|
||||
static int iConvertModels; // tworzenie plików binarnych
|
||||
static int iErorrCounter; // licznik sprawdzań do śledzenia błędów OpenGL
|
||||
static bool bInactivePause; // automatyczna pauza, gdy okno nieaktywne
|
||||
|
||||
1556
Ground.cpp
1556
Ground.cpp
File diff suppressed because it is too large
Load Diff
108
Ground.h
108
Ground.h
@@ -69,7 +69,7 @@ struct TGroundVertex
|
||||
{
|
||||
vector3 Point;
|
||||
vector3 Normal;
|
||||
float tu, tv;
|
||||
float tu{ 0.0f }, tv{ 0.0f };
|
||||
void HalfSet(const TGroundVertex &v1, const TGroundVertex &v2)
|
||||
{ // wyliczenie współrzędnych i mapowania punktu na środku odcinka v1<->v2
|
||||
Point = 0.5 * (v1.Point + v2.Point);
|
||||
@@ -97,12 +97,13 @@ struct TGroundVertex
|
||||
}
|
||||
};
|
||||
|
||||
class TSubRect; // sektor (aktualnie 200m×200m, ale może być zmieniony)
|
||||
|
||||
class TGroundNode : public Resource
|
||||
{ // obiekt scenerii
|
||||
private:
|
||||
public:
|
||||
|
||||
friend class opengl_renderer;
|
||||
|
||||
private:
|
||||
public:
|
||||
TGroundNodeType iType; // typ obiektu
|
||||
union
|
||||
{ // Ra: wskażniki zależne od typu - zrobić klasy dziedziczone zamiast
|
||||
@@ -121,24 +122,20 @@ class TGroundNode : public Resource
|
||||
TGroundNode *nNode; // obiekt renderujący grupowo ma tu wskaźnik na listę obiektów
|
||||
};
|
||||
std::string asName; // nazwa (nie zawsze ma znaczenie)
|
||||
|
||||
vector3 pCenter; // współrzędne środka do przydzielenia sektora
|
||||
vector3 m_rootposition; // position of the ground (sub)rectangle holding the node, in the 3d world
|
||||
// visualization-related data
|
||||
// TODO: wrap these in a struct, when cleaning objects up
|
||||
union
|
||||
{
|
||||
int iNumVerts; // dla trójkątów
|
||||
int iNumPts; // dla linii
|
||||
int iCount; // dla terenu
|
||||
// int iState; //Ra: nie używane - dźwięki zapętlone
|
||||
};
|
||||
vector3 pCenter; // współrzędne środka do przydzielenia sektora
|
||||
|
||||
union
|
||||
{
|
||||
// double fAngle; //kąt obrotu dla modelu
|
||||
double fLineThickness; // McZapkie-120702: grubosc linii
|
||||
// int Status; //McZapkie-170303: status dzwieku
|
||||
};
|
||||
double fLineThickness; // McZapkie-120702: grubosc linii
|
||||
double fSquareRadius; // kwadrat widoczności do
|
||||
double fSquareMinRadius; // kwadrat widoczności od
|
||||
// TGroundNode *nMeshGroup; //Ra: obiekt grupujący trójkąty w TSubRect dla tekstury
|
||||
int iVersion; // wersja siatki (do wykonania rekompilacji)
|
||||
// union ?
|
||||
GLuint DisplayListID; // numer siatki DisplayLists
|
||||
@@ -148,6 +145,7 @@ class TGroundNode : public Resource
|
||||
int iFlags; // tryb przezroczystości: 0x10-nieprz.,0x20-przezroczysty,0x30-mieszany
|
||||
int Ambient[4], Diffuse[4], Specular[4]; // oświetlenie
|
||||
bool bVisible;
|
||||
|
||||
TGroundNode *nNext; // lista wszystkich w scenerii, ostatni na początku
|
||||
TGroundNode *nNext2; // lista obiektów w sektorze
|
||||
TGroundNode *nNext3; // lista obiektów renderowanych we wspólnym cyklu
|
||||
@@ -158,8 +156,6 @@ class TGroundNode : public Resource
|
||||
void InitCenter(); // obliczenie współrzędnych środka
|
||||
void InitNormals();
|
||||
|
||||
void MoveMe(vector3 pPosition); // przesuwanie (nie działa)
|
||||
|
||||
// bool Disable();
|
||||
inline TGroundNode * Find(const std::string &asNameToFind, TGroundNodeType iNodeType)
|
||||
{ // wyszukiwanie czołgowe z typem
|
||||
@@ -170,23 +166,18 @@ class TGroundNode : public Resource
|
||||
return NULL;
|
||||
};
|
||||
|
||||
void Compile(bool many = false);
|
||||
void Compile(Math3D::vector3 const &Origin, bool const Multiple = false);
|
||||
void Release();
|
||||
bool GetTraction();
|
||||
|
||||
void RenderHidden(); // obsługa dźwięków i wyzwalaczy zdarzeń
|
||||
void RenderDL(); // renderowanie nieprzezroczystych w Display Lists
|
||||
void RenderAlphaDL(); // renderowanie przezroczystych w Display Lists
|
||||
// (McZapkie-131202)
|
||||
void RaRenderVBO(); // renderowanie (nieprzezroczystych) ze wspólnego VBO
|
||||
void RenderVBO(); // renderowanie nieprzezroczystych z własnego VBO
|
||||
void RenderAlphaVBO(); // renderowanie przezroczystych z (własnego) VBO
|
||||
|
||||
};
|
||||
|
||||
struct bounding_area {
|
||||
|
||||
float3 center; // mid point of the rectangle
|
||||
glm::vec3 center; // mid point of the rectangle
|
||||
float radius{ 0.0f }; // radius of the bounding sphere
|
||||
};
|
||||
|
||||
@@ -201,16 +192,17 @@ class TSubRect : public Resource, public CMesh
|
||||
TGroundNode *nRootMesh = nullptr; // obiekty renderujące wg tekstury (wtórne, lista po nNext2)
|
||||
TGroundNode *nMeshed = nullptr; // lista obiektów dla których istnieją obiekty renderujące grupowo
|
||||
public:
|
||||
TGroundNode *
|
||||
nRootNode = nullptr; // wszystkie obiekty w sektorze, z wyjątkiem renderujących i pojazdów (nNext2)
|
||||
TGroundNode *
|
||||
nRenderHidden = nullptr; // lista obiektów niewidocznych, "renderowanych" również z tyłu (nNext3)
|
||||
TGroundNode *nRootNode = nullptr; // wszystkie obiekty w sektorze, z wyjątkiem renderujących i pojazdów (nNext2)
|
||||
TGroundNode *nRenderHidden = nullptr; // lista obiektów niewidocznych, "renderowanych" również z tyłu (nNext3)
|
||||
TGroundNode *nRenderRect = nullptr; // z poziomu sektora - nieprzezroczyste (nNext3)
|
||||
TGroundNode *nRenderRectAlpha = nullptr; // z poziomu sektora - przezroczyste (nNext3)
|
||||
TGroundNode *nRenderWires = nullptr; // z poziomu sektora - druty i inne linie (nNext3)
|
||||
TGroundNode *nRender = nullptr; // indywidualnie - nieprzezroczyste (nNext3)
|
||||
TGroundNode *nRenderMixed = nullptr; // indywidualnie - nieprzezroczyste i przezroczyste (nNext3)
|
||||
TGroundNode *nRenderAlpha = nullptr; // indywidualnie - przezroczyste (nNext3)
|
||||
#ifdef EU07_SCENERY_EDITOR
|
||||
std::deque< TGroundNode* > m_memcells; // collection of memcells present in the sector
|
||||
#endif
|
||||
int iNodeCount = 0; // licznik obiektów, do pomijania pustych sektorów
|
||||
public:
|
||||
void LoadNodes(); // utworzenie VBO sektora
|
||||
@@ -222,15 +214,9 @@ class TSubRect : public Resource, public CMesh
|
||||
void Sort(); // optymalizacja obiektów w sektorze (sortowanie wg tekstur)
|
||||
TTrack * FindTrack(vector3 *Point, int &iConnection, TTrack *Exclude);
|
||||
TTraction * FindTraction(vector3 *Point, int &iConnection, TTraction *Exclude);
|
||||
bool StartVBO(); // ustwienie VBO sektora dla (nRenderRect), (nRenderRectAlpha) i
|
||||
// (nRenderWires)
|
||||
bool StartVBO(); // ustwienie VBO sektora dla (nRenderRect), (nRenderRectAlpha) i (nRenderWires)
|
||||
bool RaTrackAnimAdd(TTrack *t); // zgłoszenie toru do animacji
|
||||
void RaAnimate(); // przeliczenie animacji torów
|
||||
void RenderDL(); // renderowanie nieprzezroczystych w Display Lists
|
||||
void RenderAlphaDL(); // renderowanie przezroczystych w Display Lists
|
||||
// (McZapkie-131202)
|
||||
void RenderVBO(); // renderowanie nieprzezroczystych z własnego VBO
|
||||
void RenderAlphaVBO(); // renderowanie przezroczystych z (własnego) VBO
|
||||
void RenderSounds(); // dźwięki pojazdów z niewidocznych sektorów
|
||||
};
|
||||
|
||||
@@ -247,6 +233,8 @@ class TGroundRect : public TSubRect
|
||||
{ // kwadrat kilometrowy
|
||||
// obiekty o niewielkiej ilości wierzchołków będą renderowane stąd
|
||||
// Ra: 2012-02 doszły submodele terenu
|
||||
friend class opengl_renderer;
|
||||
|
||||
private:
|
||||
int iLastDisplay; // numer klatki w której był ostatnio wyświetlany
|
||||
TSubRect *pSubRects{ nullptr };
|
||||
@@ -273,8 +261,6 @@ class TGroundRect : public TSubRect
|
||||
for (int i = iNumSubRects * iNumSubRects - 1; i >= 0; --i)
|
||||
pSubRects[i].Sort(); // optymalizacja obiektów w sektorach
|
||||
};
|
||||
void RenderDL();
|
||||
void RenderVBO();
|
||||
};
|
||||
|
||||
class TGround
|
||||
@@ -288,9 +274,7 @@ class TGround
|
||||
TGroundRect Rects[iNumRects][iNumRects]; // mapa kwadratów kilometrowych
|
||||
TEvent *RootEvent = nullptr; // lista zdarzeń
|
||||
TEvent *QueryRootEvent = nullptr,
|
||||
*tmpEvent = nullptr,
|
||||
*tmp2Event = nullptr,
|
||||
*OldQRE = nullptr;
|
||||
*tmpEvent = nullptr;
|
||||
TSubRect *pRendered[1500]; // lista renderowanych sektorów
|
||||
int iNumNodes = 0;
|
||||
vector3 pOrigin;
|
||||
@@ -299,8 +283,6 @@ class TGround
|
||||
TGroundNode *nRootOfType[TP_LAST]; // tablica grupująca obiekty, przyspiesza szukanie
|
||||
// TGroundNode *nLastOfType[TP_LAST]; //ostatnia
|
||||
TSubRect srGlobal; // zawiera obiekty globalne (na razie wyzwalacze czasowe)
|
||||
int hh = 0,
|
||||
mm = 0; // ustawienia czasu
|
||||
// int tracks,tracksfar; //liczniki torów
|
||||
typedef std::unordered_map<std::string, TEvent *> event_map;
|
||||
event_map m_eventmap;
|
||||
@@ -313,9 +295,6 @@ class TGround
|
||||
public:
|
||||
bool bDynamicRemove = false; // czy uruchomić procedurę usuwania pojazdów
|
||||
TDynamicObject *LastDyn = nullptr; // ABu: paskudnie, ale na bardzo szybko moze jakos przejdzie...
|
||||
// TTrain *pTrain;
|
||||
// double fVDozwolona;
|
||||
// bool bTrabil;
|
||||
|
||||
TGround();
|
||||
~TGround();
|
||||
@@ -329,7 +308,6 @@ class TGround
|
||||
TTrack * FindTrack(vector3 Point, int &iConnection, TGroundNode *Exclude);
|
||||
TTraction * FindTraction(vector3 *Point, int &iConnection, TGroundNode *Exclude);
|
||||
TTraction * TractionNearestFind(vector3 &p, int dir, TGroundNode *n);
|
||||
// TGroundNode* CreateGroundNode();
|
||||
TGroundNode * AddGroundNode(cParser *parser);
|
||||
bool AddGroundNode(double x, double z, TGroundNode *Node)
|
||||
{
|
||||
@@ -342,39 +320,12 @@ class TGround
|
||||
else
|
||||
return false;
|
||||
};
|
||||
// bool Include(TQueryParserComp *Parser);
|
||||
// TGroundNode* GetVisible(AnsiString asName);
|
||||
TGroundNode * GetNode(std::string asName);
|
||||
bool AddDynamic(TGroundNode *Node);
|
||||
void MoveGroundNode(vector3 pPosition);
|
||||
void UpdatePhys(double dt, int iter); // aktualizacja fizyki stałym krokiem
|
||||
bool Update(double dt, int iter); // aktualizacja przesunięć zgodna z FPS
|
||||
void Update_Lights(); // updates scene lights array
|
||||
bool AddToQuery(TEvent *Event, TDynamicObject *Node);
|
||||
bool GetTraction(TDynamicObject *model);
|
||||
bool Render( Math3D::vector3 const &Camera );
|
||||
bool RenderDL(vector3 pPosition);
|
||||
bool RenderAlphaDL(vector3 pPosition);
|
||||
bool RenderVBO(vector3 pPosition);
|
||||
bool RenderAlphaVBO(vector3 pPosition);
|
||||
bool CheckQuery();
|
||||
// GetRect(double x, double z) { return
|
||||
// &(Rects[int(x/fSubRectSize+fHalfNumRects)][int(z/fSubRectSize+fHalfNumRects)]); };
|
||||
/*
|
||||
int GetRowFromZ(double z) { return (z/fRectSize+fHalfNumRects); };
|
||||
int GetColFromX(double x) { return (x/fRectSize+fHalfNumRects); };
|
||||
int GetSubRowFromZ(double z) { return (z/fSubRectSize+fHalfNumSubRects); };
|
||||
int GetSubColFromX(double x) { return (x/fSubRectSize+fHalfNumSubRects); };
|
||||
*/
|
||||
/*
|
||||
inline TGroundNode* FindGroundNode(const AnsiString &asNameToFind )
|
||||
{
|
||||
if (RootNode)
|
||||
return (RootNode->Find( asNameToFind ));
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
*/
|
||||
TGroundNode * DynamicFindAny(std::string asNameToFind);
|
||||
TGroundNode * DynamicFind(std::string asNameToFind);
|
||||
void DynamicList(bool all = false);
|
||||
@@ -383,16 +334,15 @@ class TGround
|
||||
{
|
||||
return &Rects[GetColFromX(x) / iNumSubRects][GetRowFromZ(z) / iNumSubRects];
|
||||
};
|
||||
TSubRect * GetSubRect( int iCol, int iRow );
|
||||
TSubRect * GetSubRect(double x, double z)
|
||||
{
|
||||
return GetSubRect(GetColFromX(x), GetRowFromZ(z));
|
||||
};
|
||||
TSubRect * FastGetSubRect(double x, double z)
|
||||
{
|
||||
return FastGetSubRect(GetColFromX(x), GetRowFromZ(z));
|
||||
TSubRect * FastGetSubRect( int iCol, int iRow );
|
||||
TSubRect * FastGetSubRect( double x, double z ) {
|
||||
return FastGetSubRect( GetColFromX( x ), GetRowFromZ( z ) );
|
||||
};
|
||||
TSubRect * GetSubRect(int iCol, int iRow);
|
||||
TSubRect * FastGetSubRect(int iCol, int iRow);
|
||||
int GetRowFromZ(double z)
|
||||
{
|
||||
return (int)(z / fSubRectSize + fHalfTotalNumSubRects);
|
||||
@@ -406,7 +356,6 @@ class TGround
|
||||
void TrackJoin(TGroundNode *Current);
|
||||
|
||||
private:
|
||||
void OpenGLUpdate(HDC hDC);
|
||||
void RaTriangleDivider(TGroundNode *node);
|
||||
void Navigate(std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||
bool PROBLEND;
|
||||
@@ -419,7 +368,6 @@ class TGround
|
||||
void WyslijNamiary(TGroundNode *t);
|
||||
void WyslijParam(int nr, int fl);
|
||||
void WyslijUszkodzenia(const std::string &t, char fl);
|
||||
void WyslijPojazdy(int nr); // -> skladanie wielu pojazdow
|
||||
void WyslijObsadzone(); // -> skladanie wielu pojazdow
|
||||
void RadioStop(vector3 pPosition);
|
||||
TDynamicObject * DynamicNearest(vector3 pPosition, double distance = 20.0,
|
||||
|
||||
2
Logs.cpp
2
Logs.cpp
@@ -112,7 +112,7 @@ void ErrorLog(const char *str)
|
||||
"logs/errors (" + filename_scenery() + ") " + filename_date() + ".txt" :
|
||||
"errors.txt" );
|
||||
errors.open( filename, std::ios::trunc );
|
||||
errors << "EU07.EXE " + Global::asRelease << "\n";
|
||||
errors << "EU07.EXE " + Global::asVersion << "\n";
|
||||
}
|
||||
if (str)
|
||||
errors << str;
|
||||
|
||||
112
McZapkie/MOVER.h
112
McZapkie/MOVER.h
@@ -139,7 +139,29 @@ static int const ctrain_passenger = 16; //mostek przejściowy
|
||||
static int const ctrain_scndpneumatic = 32; //przewody 8 atm (żółte; zasilanie powietrzem)
|
||||
static int const ctrain_heating = 64; //przewody ogrzewania WN
|
||||
static int const ctrain_depot = 128; //nie rozłączalny podczas zwykłych manewrów (międzyczłonowy), we wpisie wartość ujemna
|
||||
|
||||
// possible coupling types; can be combined
|
||||
enum coupling {
|
||||
faux = 0x0,
|
||||
coupler = 0x1,
|
||||
brakehose = 0x2,
|
||||
control = 0x4,
|
||||
highvoltage = 0x8,
|
||||
gangway = 0x10,
|
||||
mainhose = 0x20,
|
||||
heating = 0x40,
|
||||
permanent = 0x80
|
||||
};
|
||||
// possible effect ranges for control commands; exclusive
|
||||
enum range {
|
||||
local,
|
||||
unit,
|
||||
consist
|
||||
};
|
||||
// start method for devices; exclusive
|
||||
enum start {
|
||||
manual,
|
||||
automatic
|
||||
};
|
||||
/*typ hamulca elektrodynamicznego*/
|
||||
static int const dbrake_none = 0;
|
||||
static int const dbrake_passive = 1;
|
||||
@@ -269,7 +291,8 @@ struct TCommand
|
||||
std::string Command; /*komenda*/
|
||||
double Value1 = 0.0; /*argumenty komendy*/
|
||||
double Value2 = 0.0;
|
||||
TLocation Location;
|
||||
int Coupling{ ctrain_controll }; // coupler flag used to determine command propagation
|
||||
TLocation Location;
|
||||
};
|
||||
|
||||
/*tory*/
|
||||
@@ -360,14 +383,14 @@ struct TBoilerType {
|
||||
};
|
||||
/*rodzaj odbieraka pradu*/
|
||||
struct TCurrentCollector {
|
||||
long CollectorsNo; //musi być tu, bo inaczej się kopie
|
||||
double MinH; double MaxH; //zakres ruchu pantografu, nigdzie nie używany
|
||||
double CSW; //szerokość części roboczej (styku) ślizgacza
|
||||
double MinV; double MaxV; //minimalne i maksymalne akceptowane napięcie
|
||||
double OVP; //czy jest przekaznik nadnapieciowy
|
||||
double InsetV; //minimalne napięcie wymagane do załączenia
|
||||
double MinPress; //minimalne ciśnienie do załączenia WS
|
||||
double MaxPress; //maksymalne ciśnienie za reduktorem
|
||||
long CollectorsNo{ 0 }; //musi być tu, bo inaczej się kopie
|
||||
double MinH{ 0.0 }; double MaxH{ 0.0 }; //zakres ruchu pantografu, nigdzie nie używany
|
||||
double CSW{ 0.0 }; //szerokość części roboczej (styku) ślizgacza
|
||||
double MinV{ 0.0 }; double MaxV{ 0.0 }; //minimalne i maksymalne akceptowane napięcie
|
||||
double OVP{ 0.0 }; //czy jest przekaznik nadnapieciowy
|
||||
double InsetV{ 0.0 }; //minimalne napięcie wymagane do załączenia
|
||||
double MinPress{ 0.0 }; //minimalne ciśnienie do załączenia WS
|
||||
double MaxPress{ 0.0 }; //maksymalne ciśnienie za reduktorem
|
||||
//inline TCurrentCollector() {
|
||||
// CollectorsNo = 0;
|
||||
// MinH, MaxH, CSW, MinV, MaxV = 0.0;
|
||||
@@ -536,6 +559,12 @@ struct TTransmision
|
||||
|
||||
enum TCouplerType { NoCoupler, Articulated, Bare, Chain, Screw, Automatic };
|
||||
|
||||
struct power_coupling {
|
||||
double current{ 0.0 };
|
||||
double voltage{ 0.0 };
|
||||
bool local{ false }; // whether the power comes from external or onboard source
|
||||
};
|
||||
|
||||
struct TCoupling {
|
||||
/*parametry*/
|
||||
double SpringKB = 1.0; /*stala sprezystosci zderzaka/sprzegu, %tlumiennosci */
|
||||
@@ -556,6 +585,9 @@ struct TCoupling {
|
||||
double CForce = 0.0; /*sila z jaka dzialal*/
|
||||
double Dist = 0.0; /*strzalka ugiecia zderzaków*/
|
||||
bool CheckCollision = false; /*czy sprawdzac sile czy pedy*/
|
||||
|
||||
power_coupling power_high;
|
||||
power_coupling power_low; // TODO: implement this
|
||||
};
|
||||
|
||||
class TMoverParameters
|
||||
@@ -747,6 +779,7 @@ public:
|
||||
double Ftmax = 0.0;
|
||||
/*- dla lokomotyw z silnikami indukcyjnymi -*/
|
||||
double eimc[26];
|
||||
static std::vector<std::string> const eimc_labels;
|
||||
/*-dla wagonow*/
|
||||
double MaxLoad = 0.0; /*masa w T lub ilosc w sztukach - ladownosc*/
|
||||
std::string LoadAccepted; std::string LoadQuantity; /*co moze byc zaladowane, jednostki miary*/
|
||||
@@ -768,7 +801,17 @@ public:
|
||||
TRotation Rot;
|
||||
std::string Name; /*nazwa wlasna*/
|
||||
TCoupling Couplers[2]; //urzadzenia zderzno-sprzegowe, polaczenia miedzy wagonami
|
||||
double HVCouplers[2][2]; //przewod WN
|
||||
enum side {
|
||||
front = 0,
|
||||
rear
|
||||
};
|
||||
#ifdef EU07_USE_OLD_HVCOUPLERS
|
||||
double HVCouplers[ 2 ][ 2 ]; //przewod WN
|
||||
enum hvcoupler {
|
||||
current = 0,
|
||||
voltage
|
||||
};
|
||||
#endif
|
||||
int ScanCounter = 0; /*pomocnicze do skanowania sprzegow*/
|
||||
bool EventFlag = false; /*!o true jesli cos nietypowego sie wydarzy*/
|
||||
int SoundFlag = 0; /*!o patrz stale sound_ */
|
||||
@@ -804,15 +847,25 @@ public:
|
||||
bool CompressorFlag = false; /*!o czy wlaczona sprezarka*/
|
||||
bool PantCompFlag = false; /*!o czy wlaczona sprezarka pantografow*/
|
||||
bool CompressorAllow = false; /*! zezwolenie na uruchomienie sprezarki NBMX*/
|
||||
bool ConverterFlag = false ; /*! czy wlaczona przetwornica NBMX*/
|
||||
bool CompressorAllowLocal{ true }; // local device state override (most units don't have this fitted so it's set to true not to intefere)
|
||||
bool CompressorGovernorLock{ false }; // indicates whether compressor pressure switch was activated due to reaching cut-out pressure
|
||||
// TODO converter parameters, for when we start cleaning up mover parameters
|
||||
start ConverterStart{ manual }; // whether converter is started manually, or by other means
|
||||
float ConverterStartDelay{ 0.0f }; // delay (in seconds) before the converter is started, once its activation conditions are met
|
||||
double ConverterStartDelayTimer{ 0.0 }; // helper, for tracking whether converter start delay passed
|
||||
bool ConverterAllow = false; /*zezwolenie na prace przetwornicy NBMX*/
|
||||
int BrakeCtrlPos = -2; /*nastawa hamulca zespolonego*/
|
||||
bool ConverterAllowLocal{ true }; // local device state override (most units don't have this fitted so it's set to true not to intefere)
|
||||
bool ConverterFlag = false; /*! czy wlaczona przetwornica NBMX*/
|
||||
|
||||
int BrakeCtrlPos = -2; /*nastawa hamulca zespolonego*/
|
||||
double BrakeCtrlPosR = 0.0; /*nastawa hamulca zespolonego - plynna dla FV4a*/
|
||||
double BrakeCtrlPos2 = 0.0; /*nastawa hamulca zespolonego - kapturek dla FV4a*/
|
||||
int LocalBrakePos = 0; /*nastawa hamulca indywidualnego*/
|
||||
int ManualBrakePos = 0; /*nastawa hamulca recznego*/
|
||||
double LocalBrakePosA = 0.0;
|
||||
int BrakeStatus = b_off; /*0 - odham, 1 - ham., 2 - uszk., 4 - odluzniacz, 8 - antyposlizg, 16 - uzyte EP, 32 - pozycja R, 64 - powrot z R*/
|
||||
/*
|
||||
int BrakeStatus = b_off; //0 - odham, 1 - ham., 2 - uszk., 4 - odluzniacz, 8 - antyposlizg, 16 - uzyte EP, 32 - pozycja R, 64 - powrot z R
|
||||
*/
|
||||
bool EmergencyBrakeFlag = false; /*hamowanie nagle*/
|
||||
int BrakeDelayFlag = 0; /*nastawa opoznienia ham. osob/towar/posp/exp 0/1/2/4*/
|
||||
int BrakeDelays = 0; /*nastawy mozliwe do uzyskania*/
|
||||
@@ -886,7 +939,9 @@ public:
|
||||
double RventRot = 0.0; /*!s obroty wentylatorow rozruchowych*/
|
||||
bool UnBrake = false; /*w EZT - nacisniete odhamowywanie*/
|
||||
double PantPress = 0.0; /*Cisnienie w zbiornikach pantografow*/
|
||||
bool s_CAtestebrake = false; //hunter-091012: zmienna dla testu ca
|
||||
bool PantPressSwitchActive{ false }; // state of the pantograph pressure switch. gets primed at defined pressure level in pantograph air system
|
||||
bool PantPressLockActive{ false }; // pwr system state flag. fires when pressure switch activates by pantograph pressure dropping below defined level
|
||||
bool s_CAtestebrake = false; //hunter-091012: zmienna dla testu ca
|
||||
|
||||
/*-zmienne dla lokomotywy spalinowej z przekladnia mechaniczna*/
|
||||
double dizel_fill = 0.0; /*napelnienie*/
|
||||
@@ -898,6 +953,7 @@ public:
|
||||
|
||||
/*- zmienne dla lokomotyw z silnikami indukcyjnymi -*/
|
||||
double eimv[21];
|
||||
static std::vector<std::string> const eimv_labels;
|
||||
|
||||
/*-zmienne dla drezyny*/
|
||||
double PulseForce = 0.0; /*przylozona sila*/
|
||||
@@ -924,8 +980,10 @@ public:
|
||||
int PantRearStart = 0;
|
||||
double PantFrontVolt = 0.0; //pantograf pod napieciem? 'Winger 160404
|
||||
double PantRearVolt = 0.0;
|
||||
// TODO: move these switch types where they belong, cabin definition
|
||||
std::string PantSwitchType;
|
||||
std::string ConvSwitchType;
|
||||
std::string StLinSwitchType;
|
||||
|
||||
bool Heating = false; //ogrzewanie 'Winger 020304
|
||||
int DoubleTr = 1; //trakcja ukrotniona - przedni pojazd 'Winger 160304
|
||||
@@ -982,11 +1040,11 @@ public:
|
||||
|
||||
/*! przesylanie komend sterujacych*/
|
||||
bool SendCtrlBroadcast(std::string CtrlCommand, double ctrlvalue);
|
||||
bool SendCtrlToNext(std::string CtrlCommand, double ctrlvalue, double dir);
|
||||
bool SetInternalCommand(std::string NewCommand, double NewValue1, double NewValue2);
|
||||
bool SendCtrlToNext(std::string const CtrlCommand, double const ctrlvalue, double const dir, int const Couplertype = ctrain_controll);
|
||||
bool SetInternalCommand( std::string NewCommand, double NewValue1, double NewValue2, int const Couplertype = ctrain_controll );
|
||||
double GetExternalCommand(std::string &Command);
|
||||
bool RunCommand(std::string Command, double CValue1, double CValue2);
|
||||
bool RunInternalCommand(void);
|
||||
bool RunCommand( std::string Command, double CValue1, double CValue2, int const Couplertype = ctrain_controll );
|
||||
bool RunInternalCommand();
|
||||
void PutCommand(std::string NewCommand, double NewValue1, double NewValue2, const TLocation &NewLocation);
|
||||
bool CabActivisation(void);
|
||||
bool CabDeactivisation(void);
|
||||
@@ -1002,7 +1060,7 @@ public:
|
||||
|
||||
bool AddPulseForce(int Multipler);/*dla drezyny*/
|
||||
|
||||
bool SandDoseOn(void);/*wlacza/wylacza sypanie piasku*/
|
||||
bool Sandbox( bool const State, int const Notify = range::consist );/*wlacza/wylacza sypanie piasku*/
|
||||
|
||||
/*! zbijanie czuwaka/SHP*/
|
||||
void SSReset(void);
|
||||
@@ -1058,12 +1116,12 @@ public:
|
||||
|
||||
/*--funkcje dla lokomotyw*/
|
||||
bool DirectionBackward(void);/*! kierunek ruchu*/
|
||||
bool MainSwitch(bool State);/*! wylacznik glowny*/
|
||||
bool ConverterSwitch(bool State);/*! wl/wyl przetwornicy*/
|
||||
bool CompressorSwitch(bool State);/*! wl/wyl sprezarki*/
|
||||
bool MainSwitch( bool const State, int const Notify = range::consist );/*! wylacznik glowny*/
|
||||
bool ConverterSwitch( bool State, int const Notify = range::consist );/*! wl/wyl przetwornicy*/
|
||||
bool CompressorSwitch( bool State, int const Notify = range::consist );/*! wl/wyl sprezarki*/
|
||||
|
||||
/*-funkcje typowe dla lokomotywy elektrycznej*/
|
||||
void ConverterCheck(); // przetwornica
|
||||
void ConverterCheck( double const Timestep ); // przetwornica
|
||||
bool FuseOn(void); //bezpiecznik nadamiary
|
||||
bool FuseFlagCheck(void); // sprawdzanie flagi nadmiarowego
|
||||
void FuseOff(void); // wylaczenie nadmiarowego
|
||||
@@ -1074,7 +1132,7 @@ public:
|
||||
/*function ShowEngineRotation(VehN:int): integer; //Ra 2014-06: przeniesione do C++*/
|
||||
/*funkcje uzalezniajace sile pociagowa od predkosci: v2n, n2r, current, momentum*/
|
||||
double v2n(void);
|
||||
double current(double n, double U);
|
||||
double Current(double n, double U);
|
||||
double Momentum(double I);
|
||||
double MomentumF(double I, double Iw, int SCP);
|
||||
|
||||
@@ -1086,8 +1144,8 @@ public:
|
||||
bool AutoRelayCheck(void);//symulacja automatycznego rozruchu
|
||||
|
||||
bool ResistorsFlagCheck(void); //sprawdzenie kontrolki oporow rozruchowych NBMX
|
||||
bool PantFront(bool State); //obsluga pantografou przedniego
|
||||
bool PantRear(bool State); //obsluga pantografu tylnego
|
||||
bool PantFront( bool const State, int const Notify = range::consist ); //obsluga pantografou przedniego
|
||||
bool PantRear( bool const State, int const Notify = range::consist ); //obsluga pantografu tylnego
|
||||
|
||||
/*-funkcje typowe dla lokomotywy spalinowej z przekladnia mechaniczna*/
|
||||
bool dizel_EngageSwitch(double state);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -16,6 +16,7 @@ Copyright (C) 2007-2014 Maciej Cierniak
|
||||
#include "hamulce.h"
|
||||
#include <typeinfo>
|
||||
#include "Mover.h"
|
||||
#include "usefull.h"
|
||||
|
||||
//---FUNKCJE OGOLNE---
|
||||
|
||||
@@ -51,10 +52,10 @@ double PF_old(double P1, double P2, double S)
|
||||
|
||||
double PF( double const P1, double const P2, double const S, double const DP )
|
||||
{
|
||||
double PH = std::max(P1, P2) + 1; // wyzsze cisnienie absolutne
|
||||
double PL = P1 + P2 - PH + 2; // nizsze cisnienie absolutne
|
||||
double sg = PL / PH; // bezwymiarowy stosunek cisnien
|
||||
double FM = PH * 197 * S * Sign(P2 - P1); // najwyzszy mozliwy przeplyw, wraz z kierunkiem
|
||||
double const PH = std::max(P1, P2) + 1.0; // wyzsze cisnienie absolutne
|
||||
double const PL = P1 + P2 - PH + 2.0; // nizsze cisnienie absolutne
|
||||
double const sg = PL / PH; // bezwymiarowy stosunek cisnien
|
||||
double const FM = PH * 197.0 * S * Sign(P2 - P1); // najwyzszy mozliwy przeplyw, wraz z kierunkiem
|
||||
if (sg > 0.5) // jesli ponizej stosunku krytycznego
|
||||
if ((PH - PL) < DP) // niewielka roznica cisnien
|
||||
return (1.0 - sg) / DPL * FM * 2.0 * std::sqrt((DP) * (PH - DP));
|
||||
@@ -69,15 +70,15 @@ double PF1( double const P1, double const P2, double const S )
|
||||
{
|
||||
static double const DPS = 0.001;
|
||||
|
||||
double PH = std::max(P1, P2) + 1; // wyzsze cisnienie absolutne
|
||||
double PL = P1 + P2 - PH + 2; // nizsze cisnienie absolutne
|
||||
double sg = PL / PH; // bezwymiarowy stosunek cisnien
|
||||
double FM = PH * 197 * S * Sign(P2 - P1); // najwyzszy mozliwy przeplyw, wraz z kierunkiem
|
||||
if ((sg > 0.5)) // jesli ponizej stosunku krytycznego
|
||||
if ((sg < DPS)) // niewielka roznica cisnien
|
||||
return (1 - sg) / DPS * FM * 2 * std::sqrt((DPS) * (1 - DPS));
|
||||
double const PH = std::max(P1, P2) + 1.0; // wyzsze cisnienie absolutne
|
||||
double const PL = P1 + P2 - PH + 2.0; // nizsze cisnienie absolutne
|
||||
double const sg = PL / PH; // bezwymiarowy stosunek cisnien
|
||||
double const FM = PH * 197.0 * S * Sign(P2 - P1); // najwyzszy mozliwy przeplyw, wraz z kierunkiem
|
||||
if (sg > 0.5) // jesli ponizej stosunku krytycznego
|
||||
if (sg < DPS) // niewielka roznica cisnien
|
||||
return (1.0 - sg) / DPS * FM * 2.0 * std::sqrt((DPS) * (1.0 - DPS));
|
||||
else
|
||||
return FM * 2 * std::sqrt((sg) * (1 - sg));
|
||||
return FM * 2.0 * std::sqrt((sg) * (1.0 - sg));
|
||||
else // powyzej stosunku krytycznego
|
||||
return FM;
|
||||
}
|
||||
@@ -1184,50 +1185,50 @@ void TESt3AL2::Init( double const PP, double const HPP, double const LPP, double
|
||||
double TLSt::GetPF( double const PP, double const dt, double const Vel )
|
||||
{
|
||||
double result;
|
||||
double dv;
|
||||
double dV1;
|
||||
double temp;
|
||||
double VVP;
|
||||
double BVP;
|
||||
double BCP;
|
||||
double CVP;
|
||||
|
||||
// ValveRes.CreatePress(LBP);
|
||||
// LBP:=0;
|
||||
|
||||
BVP = BrakeRes->P();
|
||||
VVP = ValveRes->P();
|
||||
BCP = ImplsRes->P();
|
||||
CVP = CntrlRes->P();
|
||||
double const BVP{ BrakeRes->P() };
|
||||
double const VVP{ ValveRes->P() };
|
||||
double const BCP{ ImplsRes->P() };
|
||||
double const CVP{ CntrlRes->P() };
|
||||
|
||||
dv = 0;
|
||||
dV1 = 0;
|
||||
double dV{ 0.0 };
|
||||
double dV1{ 0.0 };
|
||||
|
||||
// sprawdzanie stanu
|
||||
if ((BrakeStatus & b_rls) == b_rls)
|
||||
if ((CVP < 0))
|
||||
if( ( BrakeStatus & b_rls ) == b_rls ) {
|
||||
if( CVP < 0.0 ) {
|
||||
BrakeStatus &= ~b_rls;
|
||||
}
|
||||
else
|
||||
{ // 008
|
||||
dv = PF1(CVP, BCP, 0.024) * dt;
|
||||
CntrlRes->Flow(+dv);
|
||||
// dV1:=+dV; //minus potem jest
|
||||
// ImplsRes->Flow(-dV1);
|
||||
dV = PF1( CVP, BCP, 0.024 ) * dt;
|
||||
CntrlRes->Flow( dV );
|
||||
/*
|
||||
// NOTE: attempted fix, disabled because it breaks when releaser is used while releasing breakes
|
||||
dV = PF1(CVP, VVP, 0.024) * dt;
|
||||
CntrlRes->Flow( dV );
|
||||
dV1 = dV; //minus potem jest
|
||||
ImplsRes->Flow( -dV1 );
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
VVP = ValveRes->P();
|
||||
double temp;
|
||||
// przeplyw ZS <-> PG
|
||||
if (((CVP - BCP) * BVM > 0.5))
|
||||
temp = 0;
|
||||
temp = 0.0;
|
||||
else if ((VVP > CVP + 0.4))
|
||||
temp = 0.5;
|
||||
else
|
||||
temp = 0.5;
|
||||
|
||||
dv = PF1(CVP, VVP, 0.0015 * temp / 1.8 / 2) * dt;
|
||||
CntrlRes->Flow(+dv);
|
||||
ValveRes->Flow(-0.04 * dv);
|
||||
dV1 = dV1 - 0.96 * dv;
|
||||
dV = PF1(CVP, VVP, 0.0015 * temp / 1.8 / 2) * dt;
|
||||
CntrlRes->Flow(+dV);
|
||||
ValveRes->Flow(-0.04 * dV);
|
||||
dV1 = dV1 - 0.96 * dV;
|
||||
|
||||
// luzowanie KI {G}
|
||||
// if VVP>BCP then
|
||||
@@ -1236,26 +1237,38 @@ double TLSt::GetPF( double const PP, double const dt, double const Vel )
|
||||
// dV:=PF(VVP,BCP,0.00020*(1.33-int((CVP-BCP)*BVM>0.65)))*dt
|
||||
// else dV:=0; 0.00025 P
|
||||
/*P*/
|
||||
if (VVP > BCP)
|
||||
dv = PF(VVP, BCP,
|
||||
0.00043 * (1.5 - int(((CVP - BCP) * BVM > 1) && (BrakeDelayFlag == bdelay_G))),
|
||||
0.1) *
|
||||
dt;
|
||||
else if ((CVP - BCP) < 1.5)
|
||||
dv = PF(VVP, BCP,
|
||||
0.001472 * (1.36 - int(((CVP - BCP) * BVM > 1) && (BrakeDelayFlag == bdelay_G))),
|
||||
0.1) *
|
||||
dt;
|
||||
else
|
||||
dv = 0;
|
||||
if( VVP > BCP ) {
|
||||
dV =
|
||||
PF( VVP, BCP,
|
||||
0.00043 * ( 1.5 - (
|
||||
true == ( ( ( CVP - BCP ) * BVM > 1.0 )
|
||||
&& ( BrakeDelayFlag == bdelay_G ) ) ?
|
||||
1.0 :
|
||||
0.0 ) ),
|
||||
0.1 )
|
||||
* dt;
|
||||
}
|
||||
else if( ( CVP - BCP ) < 1.5 ) {
|
||||
dV = PF( VVP, BCP,
|
||||
0.001472 * ( 1.36 - (
|
||||
true == ( ( ( CVP - BCP ) * BVM > 1.0 )
|
||||
&& ( BrakeDelayFlag == bdelay_G ) ) ?
|
||||
1.0 :
|
||||
0.0 ) ),
|
||||
0.1 )
|
||||
* dt;
|
||||
}
|
||||
else {
|
||||
dV = 0;
|
||||
}
|
||||
|
||||
ImplsRes->Flow(-dv);
|
||||
ValveRes->Flow(+dv);
|
||||
ImplsRes->Flow(-dV);
|
||||
ValveRes->Flow(+dV);
|
||||
// przeplyw PG <-> rozdzielacz
|
||||
dv = PF(PP, VVP, 0.01, 0.1) * dt;
|
||||
ValveRes->Flow(-dv);
|
||||
dV = PF(PP, VVP, 0.01, 0.1) * dt;
|
||||
ValveRes->Flow(-dV);
|
||||
|
||||
result = dv - dV1;
|
||||
result = dV - dV1;
|
||||
|
||||
// if Vel>55 then temp:=0.72 else
|
||||
// temp:=1;{R}
|
||||
@@ -1272,18 +1285,18 @@ double TLSt::GetPF( double const PP, double const dt, double const Vel )
|
||||
if ((BrakeCyl->P() > temp + 0.005) || (temp < 0.28))
|
||||
// dV:=PF(0,BrakeCyl->P(),0.0015*3*sizeBC)*dt
|
||||
// dV:=PF(0,BrakeCyl->P(),0.005*3*sizeBC)*dt
|
||||
dv = PFVd(BrakeCyl->P(), 0, 0.005 * 7 * SizeBC, temp) * dt;
|
||||
dV = PFVd(BrakeCyl->P(), 0, 0.005 * 7 * SizeBC, temp) * dt;
|
||||
else
|
||||
dv = 0;
|
||||
BrakeCyl->Flow(-dv);
|
||||
dV = 0;
|
||||
BrakeCyl->Flow(-dV);
|
||||
// przeplyw ZP <-> CH
|
||||
if ((BrakeCyl->P() < temp - 0.005) && (temp > 0.29))
|
||||
// dV:=PF(BVP,BrakeCyl->P(),0.002*3*sizeBC*2)*dt
|
||||
dv = -PFVa(BVP, BrakeCyl->P(), 0.002 * 7 * SizeBC * 2, temp) * dt;
|
||||
dV = -PFVa(BVP, BrakeCyl->P(), 0.002 * 7 * SizeBC * 2, temp) * dt;
|
||||
else
|
||||
dv = 0;
|
||||
BrakeRes->Flow(dv);
|
||||
BrakeCyl->Flow(-dv);
|
||||
dV = 0;
|
||||
BrakeRes->Flow(dV);
|
||||
BrakeCyl->Flow(-dV);
|
||||
|
||||
ImplsRes->Act();
|
||||
ValveRes->Act();
|
||||
@@ -2198,124 +2211,145 @@ double TFV4aM::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||
static int const LBDelay = 100;
|
||||
static double const xpM = 0.3; // mnoznik membrany komory pod
|
||||
|
||||
double LimPP;
|
||||
double dpPipe;
|
||||
double dpMainValve;
|
||||
double ActFlowSpeed;
|
||||
double DP;
|
||||
double pom;
|
||||
int i;
|
||||
ep = (PP / 2.0) * 1.5 + (ep / 2.0) * 0.5; // SPKS!!
|
||||
|
||||
ep = PP / 2 * 1.5 + ep / 2 * 0.5; // SPKS!!
|
||||
// ep:=pp;
|
||||
// ep:=cp/3+pp/3+ep/3;
|
||||
// ep:=cp;
|
||||
for( int idx = 0; idx < 5; ++idx ) {
|
||||
Sounds[ idx ] = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 5; ++i)
|
||||
Sounds[i] = 0;
|
||||
DP = 0;
|
||||
// na wszelki wypadek, zeby nie wyszlo poza zakres
|
||||
i_bcp = clamp( i_bcp, -1.999, 5.999 );
|
||||
|
||||
i_bcp = Max0R(Min0R(i_bcp, 5.999), -1.999); // na wszelki wypadek, zeby nie wyszlo poza zakres
|
||||
|
||||
if ((TP > 0))
|
||||
{ // jesli czasowy jest niepusty
|
||||
// dp:=0.07; //od cisnienia 5 do 0 w 60 sekund ((5-0)*dt/75)
|
||||
double DP{ 0.0 };
|
||||
if( TP > 0.0 ) {
|
||||
// jesli czasowy jest niepusty
|
||||
DP = 0.045; // 2.5 w 55 sekund (5,35->5,15 w PG)
|
||||
TP = TP - DP * dt;
|
||||
TP -= DP * dt;
|
||||
Sounds[s_fv4a_t] = DP;
|
||||
}
|
||||
else //.08
|
||||
{
|
||||
TP = 0;
|
||||
else {
|
||||
//.08
|
||||
TP = 0.0;
|
||||
}
|
||||
|
||||
if ((XP > 0)) // jesli komora pod niepusta jest niepusty
|
||||
{
|
||||
if (XP > 0) {
|
||||
// jesli komora pod niepusta jest niepusty
|
||||
DP = 2.5;
|
||||
Sounds[s_fv4a_x] = DP * XP;
|
||||
XP = XP - dt * DP * 2; // od cisnienia 5 do 0 w 10 sekund ((5-0)*dt/10)
|
||||
XP -= dt * DP * 2.0; // od cisnienia 5 do 0 w 10 sekund ((5-0)*dt/10)
|
||||
}
|
||||
else {
|
||||
// jak pusty, to pusty
|
||||
XP = 0.0;
|
||||
}
|
||||
else //.75
|
||||
XP = 0; // jak pusty, to pusty
|
||||
|
||||
LimPP = Min0R(LPP_RP(i_bcp) + TP * 0.08 + RedAdj, HP); // pozycja + czasowy lub zasilanie
|
||||
ActFlowSpeed = BPT[lround(i_bcp) + 2][0];
|
||||
double pom;
|
||||
if( EQ( i_bcp, -1.0 ) ) {
|
||||
pom = std::min( HP, 5.4 + RedAdj );
|
||||
}
|
||||
else {
|
||||
pom = std::min( CP, HP );
|
||||
}
|
||||
|
||||
if ((EQ(i_bcp, -1)))
|
||||
pom = Min0R(HP, 5.4 + RedAdj);
|
||||
else
|
||||
pom = Min0R(CP, HP);
|
||||
|
||||
if ((pom > RP + 0.25))
|
||||
if( pom > RP + 0.25 ) {
|
||||
Fala = true;
|
||||
if ((Fala))
|
||||
if ((pom > RP + 0.3))
|
||||
// if(ep>rp+0.11)then
|
||||
XP = XP - 20 * PR(pom, XP) * dt;
|
||||
// else
|
||||
// xp:=xp-16*(ep-(ep+0.01))/(0.1)*PR(ep,xp)*dt;
|
||||
else
|
||||
}
|
||||
if( Fala ) {
|
||||
if( pom > RP + 0.3 ) {
|
||||
XP = XP - 20.0 * PR( pom, XP ) * dt;
|
||||
}
|
||||
else {
|
||||
Fala = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ((LimPP > CP)) // podwyzszanie szybkie
|
||||
CP = CP + 5 * 60 * Min0R(abs(LimPP - CP), 0.05) * PR(CP, LimPP) * dt; // zbiornik sterujacy;
|
||||
else
|
||||
CP = CP + 13 * Min0R(abs(LimPP - CP), 0.05) * PR(CP, LimPP) * dt; // zbiornik sterujacy
|
||||
double LimPP = std::min(
|
||||
LPP_RP( i_bcp ) + TP * 0.08 + RedAdj,
|
||||
HP ); // pozycja + czasowy lub zasilanie
|
||||
|
||||
// zbiornik sterujacy
|
||||
if( LimPP > CP ) {
|
||||
// podwyzszanie szybkie
|
||||
CP +=
|
||||
5.0 * 60.0
|
||||
* std::min(
|
||||
std::abs( LimPP - CP ),
|
||||
0.05 )
|
||||
* PR( CP, LimPP )
|
||||
* dt;
|
||||
}
|
||||
else {
|
||||
CP +=
|
||||
13
|
||||
* std::min(
|
||||
std::abs( LimPP - CP ),
|
||||
0.05 )
|
||||
* PR( CP, LimPP )
|
||||
* dt;
|
||||
}
|
||||
|
||||
LimPP = pom; // cp
|
||||
dpPipe = Min0R(HP, LimPP + XP * xpM);
|
||||
double const dpPipe = std::min(HP, LimPP + XP * xpM);
|
||||
|
||||
if (dpPipe > PP)
|
||||
dpMainValve = -PFVa(HP, PP, ActFlowSpeed / LBDelay, dpPipe, 0.4);
|
||||
else
|
||||
dpMainValve = PFVd(PP, 0, ActFlowSpeed / LBDelay, dpPipe, 0.4);
|
||||
double const ActFlowSpeed = BPT[ std::lround( i_bcp ) + 2 ][ 0 ];
|
||||
|
||||
if (EQ(i_bcp, -1))
|
||||
{
|
||||
if ((TP < 5))
|
||||
TP = TP + dt; // 5/10
|
||||
if ((TP < 1))
|
||||
TP = TP - 0.5 * dt; // 5/10
|
||||
// dpMainValve:=dpMainValve*2;
|
||||
//+1*PF(dpPipe,pp,ActFlowSpeed/LBDelay)//coby
|
||||
// nie przeszkadzal przy ladowaniu z zaworu obok
|
||||
double dpMainValve;
|
||||
if( dpPipe > PP ) {
|
||||
dpMainValve = -PFVa( HP, PP, ActFlowSpeed / LBDelay, dpPipe, 0.4 );
|
||||
}
|
||||
else {
|
||||
dpMainValve = PFVd( PP, 0, ActFlowSpeed / LBDelay, dpPipe, 0.4 );
|
||||
}
|
||||
|
||||
if (EQ(i_bcp, 0))
|
||||
{
|
||||
if ((TP > 2))
|
||||
dpMainValve = dpMainValve * 1.5; //+0.5*PF(dpPipe,pp,ActFlowSpeed/LBDelay)//coby nie
|
||||
// przeszkadzal przy ladowaniu z zaworu obok
|
||||
if (EQ(i_bcp, -1)) {
|
||||
|
||||
if( TP < 5 ) { TP += dt; }
|
||||
if( TP < 1 ) { TP -= 0.5 * dt; }
|
||||
}
|
||||
|
||||
if (EQ(i_bcp, 0)) {
|
||||
|
||||
if( TP > 2 ) {
|
||||
dpMainValve *= 1.5;
|
||||
}
|
||||
}
|
||||
|
||||
ep = dpPipe;
|
||||
if ((EQ(i_bcp, 0) || (RP > ep)))
|
||||
RP = RP + PF(RP, ep, 0.0007) * dt; // powolne wzrastanie, ale szybsze na jezdzie;
|
||||
else
|
||||
RP = RP + PF(RP, ep, 0.000093 / 2 * 2) * dt; // powolne wzrastanie i to bardzo
|
||||
// jednak trzeba wydluzyc, bo
|
||||
// obecnie zle dziala
|
||||
if ((RP < ep) &&
|
||||
(RP <
|
||||
BPT[lround(i_bcpno) + 2][1])) // jesli jestesmy ponizej cisnienia w sterujacym (2.9 bar)
|
||||
RP = RP + PF(RP, CP, 0.005) * dt; // przypisz cisnienie w PG - wydluzanie napelniania o czas
|
||||
// potrzebny do napelnienia PG
|
||||
if( ( EQ( i_bcp, 0 )
|
||||
|| ( RP > ep ) ) ) {
|
||||
// powolne wzrastanie, ale szybsze na jezdzie;
|
||||
RP += PF( RP, ep, 0.0007 ) * dt;
|
||||
}
|
||||
else {
|
||||
// powolne wzrastanie i to bardzo
|
||||
RP += PF( RP, ep, 0.000093 / 2 * 2 ) * dt;
|
||||
}
|
||||
// jednak trzeba wydluzyc, bo obecnie zle dziala
|
||||
if( ( RP < ep )
|
||||
&& ( RP < BPT[ std::lround( i_bcpno ) + 2 ][ 1 ] ) ) {
|
||||
// jesli jestesmy ponizej cisnienia w sterujacym (2.9 bar)
|
||||
// przypisz cisnienie w PG - wydluzanie napelniania o czas potrzebny do napelnienia PG
|
||||
RP += PF( RP, CP, 0.005 ) * dt;
|
||||
}
|
||||
|
||||
if ((EQ(i_bcp, i_bcpno)) || (EQ(i_bcp, -2)))
|
||||
{
|
||||
DP = PF(0, PP, ActFlowSpeed / LBDelay);
|
||||
if( ( EQ( i_bcp, i_bcpno ) )
|
||||
|| ( EQ( i_bcp, -2 ) ) ) {
|
||||
|
||||
DP = PF( 0.0, PP, ActFlowSpeed / LBDelay );
|
||||
dpMainValve = DP;
|
||||
Sounds[s_fv4a_e] = DP;
|
||||
Sounds[s_fv4a_u] = 0;
|
||||
Sounds[s_fv4a_b] = 0;
|
||||
Sounds[s_fv4a_x] = 0;
|
||||
Sounds[s_fv4a_u] = 0.0;
|
||||
Sounds[s_fv4a_b] = 0.0;
|
||||
Sounds[s_fv4a_x] = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dpMainValve > 0)
|
||||
Sounds[s_fv4a_b] = dpMainValve;
|
||||
else
|
||||
Sounds[s_fv4a_u] = -dpMainValve;
|
||||
else {
|
||||
|
||||
if( dpMainValve > 0.0 ) {
|
||||
Sounds[ s_fv4a_b ] = dpMainValve;
|
||||
}
|
||||
else {
|
||||
Sounds[ s_fv4a_u ] = -dpMainValve;
|
||||
}
|
||||
}
|
||||
|
||||
return dpMainValve * dt;
|
||||
@@ -2347,17 +2381,11 @@ double TFV4aM::GetPos(int i)
|
||||
|
||||
double TFV4aM::LPP_RP(double pos) // cisnienie z zaokraglonej pozycji;
|
||||
{
|
||||
int i_pos;
|
||||
int const i_pos = 2 + std::floor( pos ); // zaokraglone w dol
|
||||
|
||||
i_pos = lround(pos - 0.5) + 2; // zaokraglone w dol
|
||||
double i, j, k, l;
|
||||
i = BPT[i_pos][1];
|
||||
j = BPT[i_pos + 1][1];
|
||||
k = pos + 2 - i_pos;
|
||||
l = i + (j - i) * k;
|
||||
double r = BPT[i_pos][1] +
|
||||
(BPT[i_pos + 1][1] - BPT[i_pos][1]) * (pos + 2 - i_pos); // interpolacja liniowa
|
||||
return r;
|
||||
return
|
||||
BPT[i_pos][1]
|
||||
+ (BPT[i_pos + 1][1] - BPT[i_pos][1]) * ((pos + 2) - i_pos); // interpolacja liniowa
|
||||
}
|
||||
bool TFV4aM::EQ(double pos, double i_pos)
|
||||
{
|
||||
@@ -2366,8 +2394,7 @@ bool TFV4aM::EQ(double pos, double i_pos)
|
||||
|
||||
//---FV4a/M--- nowonapisany kran bez poprawki IC
|
||||
|
||||
double TMHZ_EN57::GetPF(double i_bcp, double PP, double HP, double dt, double ep)
|
||||
{
|
||||
double TMHZ_EN57::GetPF( double i_bcp, double PP, double HP, double dt, double ep ) {
|
||||
static int const LBDelay = 100;
|
||||
|
||||
double LimPP;
|
||||
@@ -2376,13 +2403,11 @@ double TMHZ_EN57::GetPF(double i_bcp, double PP, double HP, double dt, double ep
|
||||
double ActFlowSpeed;
|
||||
double DP;
|
||||
double pom;
|
||||
int i;
|
||||
|
||||
{
|
||||
long i_end = 5;
|
||||
for (i = 0; i < i_end; ++i)
|
||||
Sounds[i] = 0;
|
||||
for( int idx = 0; idx < 5; ++idx ) {
|
||||
Sounds[ idx ] = 0;
|
||||
}
|
||||
|
||||
DP = 0;
|
||||
|
||||
i_bcp = Max0R(Min0R(i_bcp, 9.999), -0.999); // na wszelki wypadek, zeby nie wyszlo poza zakres
|
||||
|
||||
@@ -184,7 +184,7 @@ class TBrake {
|
||||
bool DCV = false; //podwojny zawor zwrotny
|
||||
double ASBP = 0.0; //cisnienie hamulca pp
|
||||
|
||||
int BrakeStatus = 0; //flaga stanu
|
||||
int BrakeStatus{ b_off }; //flaga stanu
|
||||
int SoundFlag = 0;
|
||||
|
||||
public:
|
||||
@@ -213,6 +213,8 @@ class TBrake {
|
||||
void SetASBP( double const Press ); //ustalenie cisnienia pp
|
||||
virtual void ForceEmptiness();
|
||||
int GetSoundFlag();
|
||||
int GetBrakeStatus() const { return BrakeStatus; }
|
||||
void SetBrakeStatus( int const Status ) { BrakeStatus = Status; }
|
||||
virtual void SetED( double const EDstate ) {}; //stan hamulca ED do luzowania
|
||||
};
|
||||
|
||||
|
||||
@@ -144,98 +144,6 @@ bool FuzzyLogicAI(double Test, double Threshold, double Probability)
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string ReadWord(std::ifstream &infile)
|
||||
{
|
||||
std::string s = "";
|
||||
char c;
|
||||
bool nextword = false;
|
||||
|
||||
while ((!infile.eof()) && (!nextword))
|
||||
{
|
||||
infile.get(c);
|
||||
if (_spacesigns.find(c) != std::string::npos)
|
||||
if (s != "")
|
||||
nextword = true;
|
||||
if (_spacesigns.find(c) == std::string::npos)
|
||||
s += c;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string TrimSpace(std::string &s)
|
||||
{
|
||||
/*int ii;
|
||||
|
||||
switch (Just)
|
||||
{
|
||||
case CutLeft:
|
||||
{
|
||||
ii = 0;
|
||||
while ((ii < s.length()) && (s[ii + 1] == (char)" "))
|
||||
++ii;
|
||||
s = s.substr(ii + 1, s.length() - ii);
|
||||
}
|
||||
case CutRight:
|
||||
{
|
||||
ii = s.length();
|
||||
while ((ii > 0) && (s[ii] == (char)" "))
|
||||
--ii;
|
||||
s = s.substr(0, ii);
|
||||
}
|
||||
case CutBoth:
|
||||
{
|
||||
s = TrimSpace(s, CutLeft);
|
||||
s = TrimSpace(s, CutRight);
|
||||
}
|
||||
}
|
||||
return s;*/
|
||||
|
||||
if (s.empty())
|
||||
return "";
|
||||
size_t first = s.find_first_not_of(' ');
|
||||
if (first == std::string::npos)
|
||||
return "";
|
||||
size_t last = s.find_last_not_of(' ');
|
||||
return s.substr(first, (last - first + 1));
|
||||
}
|
||||
|
||||
char* TrimAndReduceSpaces(const char* s)
|
||||
{ // redukuje spacje pomiedzy znakami do jednej
|
||||
char* tmp = nullptr;
|
||||
if (s)
|
||||
{
|
||||
|
||||
tmp = _strdup(s);
|
||||
char* from = tmp + strspn(tmp, " ");
|
||||
char* to = tmp;
|
||||
|
||||
do if ((*to = *from++) == ' ')
|
||||
from += strspn(from, " ");
|
||||
while (*to++);
|
||||
|
||||
while (*--to == ' ')
|
||||
*to = '\0';
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
std::string ExtractKeyWord(std::string InS, std::string KeyWord)
|
||||
{
|
||||
std::string s;
|
||||
InS = InS + " ";
|
||||
std::size_t kwp = InS.find(KeyWord);
|
||||
if (kwp != std::string::npos)
|
||||
{
|
||||
s = InS.substr(kwp, InS.length());
|
||||
//s = Copy(InS, kwp, length(InS));
|
||||
s = s.substr(0, s.find_first_of(" "));
|
||||
//s = Copy(s, 1, Pos(" ", s) - 1);
|
||||
}
|
||||
else
|
||||
s = "";
|
||||
return s;
|
||||
}
|
||||
|
||||
std::string DUE(std::string s) /*Delete Before Equal sign*/
|
||||
{
|
||||
//DUE = Copy(s, Pos("=", s) + 1, length(s));
|
||||
@@ -473,8 +381,7 @@ void ComputeALine(double X0, double Y0, double Xn, double Yn, double L, double R
|
||||
bool FileExists( std::string const &Filename ) {
|
||||
|
||||
std::ifstream file( Filename );
|
||||
if( file.is_open() == false ) { return false; }
|
||||
else { return true; }
|
||||
return( true == file.is_open() );
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -105,11 +105,6 @@ bool FuzzyLogicAI(double Test, double Threshold, double Probability);
|
||||
/*to samo ale zawsze niezaleznie od DebugFlag*/
|
||||
|
||||
/*operacje na stringach*/
|
||||
std::string ReadWord( std::ifstream& infile); /*czyta slowo z wiersza pliku tekstowego*/
|
||||
//std::string Ups(std::string s);
|
||||
//std::string TrimSpace(std::string &s);
|
||||
//char* TrimAndReduceSpaces(const char* s);
|
||||
//std::string ExtractKeyWord(std::string InS, std::string KeyWord); /*wyciaga slowo kluczowe i lancuch do pierwszej spacji*/
|
||||
std::string DUE(std::string s); /*Delete Until Equal sign*/
|
||||
std::string DWE(std::string s); /*Delete While Equal sign*/
|
||||
std::string ExchangeCharInString(std::string const &s, const char &aim, const char &target); // zamienia jeden znak na drugi
|
||||
|
||||
@@ -56,7 +56,8 @@ void TModelsManager::Init()
|
||||
*/
|
||||
void TModelsManager::Free()
|
||||
{
|
||||
SafeDeleteArray(Models);
|
||||
delete[] Models;
|
||||
Models = nullptr;
|
||||
}
|
||||
|
||||
TModel3d * TModelsManager::LoadModel(std::string const &Name, bool dynamic)
|
||||
|
||||
@@ -14,16 +14,12 @@ http://mozilla.org/MPL/2.0/.
|
||||
class TMdlContainer
|
||||
{
|
||||
friend class TModelsManager;
|
||||
TMdlContainer()
|
||||
{
|
||||
Model = NULL;
|
||||
};
|
||||
~TMdlContainer()
|
||||
{
|
||||
SafeDelete(Model);
|
||||
delete Model;
|
||||
};
|
||||
TModel3d * LoadModel(std::string const &NewName, bool dynamic);
|
||||
TModel3d *Model;
|
||||
TModel3d *Model{ nullptr };
|
||||
std::string Name;
|
||||
};
|
||||
|
||||
|
||||
573
Model3d.cpp
573
Model3d.cpp
@@ -973,357 +973,6 @@ void TSubModel::RaAnimation(glm::mat4 &m, TAnimType a)
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
void TSubModel::RenderDL()
|
||||
{ // główna procedura renderowania przez DL
|
||||
return;
|
||||
if( ( iVisible )
|
||||
&& ( fSquareDist >= (fSquareMinDist / Global::fDistanceFactor) )
|
||||
&& ( fSquareDist <= (fSquareMaxDist * Global::fDistanceFactor) ) )
|
||||
{
|
||||
if (iFlags & 0xC000)
|
||||
{
|
||||
glPushMatrix();
|
||||
if (fMatrix)
|
||||
glMultMatrixf(fMatrix->readArray());
|
||||
// if (b_Anim)
|
||||
// RaAnimation(b_Anim);
|
||||
}
|
||||
if (eType < TP_ROTATOR)
|
||||
{ // renderowanie obiektów OpenGL
|
||||
if (iAlpha & iFlags & 0x1F) // rysuj gdy element nieprzezroczysty
|
||||
{
|
||||
if (TextureID < 0) // && (ReplacableSkinId!=0))
|
||||
{ // zmienialne skóry
|
||||
GfxRenderer.Bind(ReplacableSkinId[-TextureID]);
|
||||
// TexAlpha=!(iAlpha&1); //zmiana tylko w przypadku wymienej tekstury
|
||||
}
|
||||
else
|
||||
GfxRenderer.Bind(TextureID); // również 0
|
||||
if (Global::fLuminance < fLight)
|
||||
{
|
||||
glMaterialfv(GL_FRONT, GL_EMISSION, f4Diffuse); // zeby swiecilo na kolorowo
|
||||
glCallList(uiDisplayList); // tylko dla siatki
|
||||
glMaterialfv(GL_FRONT, GL_EMISSION, emm2);
|
||||
}
|
||||
else
|
||||
glCallList(uiDisplayList); // tylko dla siatki
|
||||
}
|
||||
}
|
||||
else if (eType == TP_FREESPOTLIGHT)
|
||||
{ // wersja DL
|
||||
matrix4x4 mat; // macierz opisuje układ renderowania względem kamery
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX, mat.getArray());
|
||||
// kąt między kierunkiem światła a współrzędnymi kamery
|
||||
vector3 gdzie = mat * vector3(0, 0, 0); // pozycja punktu świecącego względem kamery
|
||||
fCosViewAngle = DotProduct(Normalize(mat * vector3(0, 0, 1) - gdzie), Normalize(gdzie));
|
||||
if (fCosViewAngle > fCosFalloffAngle) // kąt większy niż maksymalny stożek swiatła
|
||||
{
|
||||
double Distdimm = 1.0;
|
||||
if (fCosViewAngle <
|
||||
fCosHotspotAngle) // zmniejszona jasność między Hotspot a Falloff
|
||||
if (fCosFalloffAngle < fCosHotspotAngle)
|
||||
Distdimm = 1.0 -
|
||||
(fCosHotspotAngle - fCosViewAngle) /
|
||||
(fCosHotspotAngle - fCosFalloffAngle);
|
||||
glColor3f(f4Diffuse[0] * Distdimm, f4Diffuse[1] * Distdimm,
|
||||
f4Diffuse[2] * Distdimm);
|
||||
/* TODO: poprawic to zeby dzialalo
|
||||
if (iFarAttenDecay>0)
|
||||
switch (iFarAttenDecay)
|
||||
{
|
||||
case 1:
|
||||
Distdimm=fFarDecayRadius/(1+sqrt(fSquareDist));
|
||||
//dorobic od kata
|
||||
break;
|
||||
case 2:
|
||||
Distdimm=fFarDecayRadius/(1+fSquareDist);
|
||||
//dorobic od kata
|
||||
break;
|
||||
}
|
||||
if (Distdimm>1)
|
||||
Distdimm=1;
|
||||
glColor3f(Diffuse[0]*Distdimm,Diffuse[1]*Distdimm,Diffuse[2]*Distdimm);
|
||||
*/
|
||||
// glPopMatrix();
|
||||
// return;
|
||||
glCallList(uiDisplayList); // wyświetlenie warunkowe
|
||||
}
|
||||
}
|
||||
else if (eType == TP_STARS)
|
||||
{
|
||||
// glDisable(GL_LIGHTING); //Tolaris-030603: bo mu punkty swiecace sie
|
||||
// blendowaly
|
||||
if (Global::fLuminance < fLight)
|
||||
{
|
||||
glMaterialfv(GL_FRONT, GL_EMISSION, f4Diffuse); // zeby swiecilo na kolorowo
|
||||
glCallList(uiDisplayList); // narysuj naraz wszystkie punkty z DL
|
||||
glMaterialfv(GL_FRONT, GL_EMISSION, emm2);
|
||||
}
|
||||
}
|
||||
if (Child != NULL)
|
||||
if (iAlpha & iFlags & 0x001F0000)
|
||||
Child->RenderDL();
|
||||
if (iFlags & 0xC000)
|
||||
glPopMatrix();
|
||||
}
|
||||
if (b_Anim < at_SecondsJump)
|
||||
b_Anim = at_None; // wyłączenie animacji dla kolejnego użycia subm
|
||||
if (Next)
|
||||
if (iAlpha & iFlags & 0x1F000000)
|
||||
Next->RenderDL(); // dalsze rekurencyjnie
|
||||
}; // Render
|
||||
|
||||
void TSubModel::RenderAlphaDL()
|
||||
{ // renderowanie przezroczystych przez DL
|
||||
return;
|
||||
if( ( iVisible )
|
||||
&& ( fSquareDist >= (fSquareMinDist / Global::fDistanceFactor) )
|
||||
&& ( fSquareDist <= (fSquareMaxDist * Global::fDistanceFactor) ) )
|
||||
{
|
||||
if (iFlags & 0xC000)
|
||||
{
|
||||
glPushMatrix();
|
||||
if (fMatrix)
|
||||
glMultMatrixf(fMatrix->readArray());
|
||||
// if (b_aAnim)
|
||||
// RaAnimation(b_aAnim);
|
||||
}
|
||||
if (eType < TP_ROTATOR)
|
||||
{ // renderowanie obiektów OpenGL
|
||||
if (iAlpha & iFlags & 0x2F) // rysuj gdy element przezroczysty
|
||||
{
|
||||
if (TextureID < 0) // && (ReplacableSkinId!=0))
|
||||
{ // zmienialne skóry
|
||||
GfxRenderer.Bind(ReplacableSkinId[-TextureID]);
|
||||
// TexAlpha=iAlpha&1; //zmiana tylko w przypadku wymienej tekstury
|
||||
}
|
||||
else
|
||||
GfxRenderer.Bind(TextureID); // również 0
|
||||
if (Global::fLuminance < fLight)
|
||||
{
|
||||
glMaterialfv(GL_FRONT, GL_EMISSION, f4Diffuse); // zeby swiecilo na kolorowo
|
||||
glCallList(uiDisplayList); // tylko dla siatki
|
||||
glMaterialfv(GL_FRONT, GL_EMISSION, emm2);
|
||||
}
|
||||
else
|
||||
glCallList(uiDisplayList); // tylko dla siatki
|
||||
}
|
||||
}
|
||||
else if (eType == TP_FREESPOTLIGHT)
|
||||
{
|
||||
// dorobić aureolę!
|
||||
}
|
||||
if (Child != NULL)
|
||||
if (eType == TP_TEXT)
|
||||
{ // tekst renderujemy w specjalny sposób, zamiast
|
||||
// submodeli z łańcucha Child
|
||||
int i, j = (int)pasText->size();
|
||||
TSubModel *p;
|
||||
if (!smLetter)
|
||||
{ // jeśli nie ma tablicy, to ją stworzyć; miejsce
|
||||
// nieodpowiednie, ale tymczasowo
|
||||
// może być
|
||||
smLetter = new TSubModel *[256]; // tablica wskaźników submodeli dla
|
||||
// wyświetlania tekstu
|
||||
ZeroMemory(smLetter, 256 * sizeof(TSubModel *)); // wypełnianie zerami
|
||||
p = Child;
|
||||
while (p)
|
||||
{
|
||||
smLetter[p->pName[0]] = p;
|
||||
p = p->Next; // kolejny znak
|
||||
}
|
||||
}
|
||||
for (i = 1; i <= j; ++i)
|
||||
{
|
||||
p = smLetter[(*pasText)[i]]; // znak do wyświetlenia
|
||||
if (p)
|
||||
{ // na razie tylko jako przezroczyste
|
||||
p->RenderAlphaDL();
|
||||
if (p->fMatrix)
|
||||
glMultMatrixf(p->fMatrix->readArray()); // przesuwanie widoku
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (iAlpha & iFlags & 0x002F0000)
|
||||
Child->RenderAlphaDL();
|
||||
if (iFlags & 0xC000)
|
||||
glPopMatrix();
|
||||
}
|
||||
if (b_aAnim < at_SecondsJump)
|
||||
b_aAnim = at_None; // wyłączenie animacji dla kolejnego użycia submodelu
|
||||
if (Next != NULL)
|
||||
if (iAlpha & iFlags & 0x2F000000)
|
||||
Next->RenderAlphaDL();
|
||||
}; // RenderAlpha
|
||||
|
||||
void TSubModel::RenderVBO(glm::mat4 m)
|
||||
{ // główna procedura renderowania przez VBO
|
||||
if( ( iVisible )
|
||||
&& ( fSquareDist >= (fSquareMinDist / Global::fDistanceFactor) )
|
||||
&& ( fSquareDist <= (fSquareMaxDist * Global::fDistanceFactor) ) )
|
||||
{
|
||||
glm::mat4 mm = m;
|
||||
if (iFlags & 0xC000)
|
||||
{
|
||||
if (fMatrix)
|
||||
mm *= glm::make_mat4(fMatrix->e);
|
||||
if (b_Anim)
|
||||
RaAnimation(mm, b_Anim);
|
||||
World.shader.set_mv(mm);
|
||||
}
|
||||
if (eType < TP_ROTATOR)
|
||||
{ // renderowanie obiektów OpenGL
|
||||
if (iAlpha & iFlags & 0x1F) // rysuj gdy element nieprzezroczysty
|
||||
{
|
||||
if (TextureID < 0) // && (ReplacableSkinId!=0))
|
||||
{ // zmienialne skóry
|
||||
GfxRenderer.Bind(ReplacableSkinId[-TextureID]);
|
||||
}
|
||||
else
|
||||
GfxRenderer.Bind(TextureID); // również 0
|
||||
//glColor3fv(f4Diffuse); // McZapkie-240702: zamiast ub
|
||||
if (Global::fLuminance < fLight)
|
||||
{
|
||||
//glMaterialfv(GL_FRONT, GL_EMISSION, f4Diffuse); // zeby swiecilo na kolorowo
|
||||
glDrawArrays(eType, iVboPtr,
|
||||
iNumVerts); // narysuj naraz wszystkie trójkąty z VBO
|
||||
//glMaterialfv(GL_FRONT, GL_EMISSION, emm2);
|
||||
}
|
||||
else
|
||||
glDrawArrays(eType, iVboPtr,
|
||||
iNumVerts); // narysuj naraz wszystkie trójkąty z VBO
|
||||
}
|
||||
}
|
||||
else if (eType == TP_FREESPOTLIGHT)
|
||||
{ // wersja VBO
|
||||
/*
|
||||
matrix4x4 mat; // macierz opisuje układ renderowania względem kamery
|
||||
glGetDoublev(GL_MODELVIEW_MATRIX, mat.getArray());
|
||||
*/
|
||||
matrix4x4 mat; mat.OpenGL_Matrix( OpenGLMatrices.data_array( GL_MODELVIEW ) );
|
||||
// kąt między kierunkiem światła a współrzędnymi kamery
|
||||
vector3 gdzie = mat * vector3(0, 0, 0); // pozycja punktu świecącego względem kamery
|
||||
fCosViewAngle = DotProduct(Normalize(mat * vector3(0, 0, 1) - gdzie), Normalize(gdzie));
|
||||
if (fCosViewAngle > fCosFalloffAngle) // kąt większy niż maksymalny stożek swiatła
|
||||
{
|
||||
double Distdimm = 1.0;
|
||||
if (fCosViewAngle <
|
||||
fCosHotspotAngle) // zmniejszona jasność między Hotspot a Falloff
|
||||
if (fCosFalloffAngle < fCosHotspotAngle)
|
||||
Distdimm = 1.0 -
|
||||
(fCosHotspotAngle - fCosViewAngle) /
|
||||
(fCosHotspotAngle - fCosFalloffAngle);
|
||||
|
||||
GfxRenderer.Bind(0); // nie teksturować
|
||||
|
||||
float color[4] = { (float)(f4Diffuse[0] * Distdimm), (float)(f4Diffuse[1] * Distdimm),
|
||||
(float)(f4Diffuse[2] * Distdimm), 0 };
|
||||
|
||||
//glColorMaterial(GL_FRONT, GL_EMISSION);
|
||||
//glDisable(GL_LIGHTING); // Tolaris-030603: bo mu punkty swiecace sie blendowaly
|
||||
//glColor3fv(color); // inaczej są białe
|
||||
//glMaterialfv(GL_FRONT, GL_EMISSION, color);
|
||||
glDrawArrays(GL_POINTS, iVboPtr, iNumVerts); // narysuj wierzchołek z VBO
|
||||
//glEnable(GL_LIGHTING);
|
||||
//glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // co ma ustawiać glColor
|
||||
//glMaterialfv(GL_FRONT, GL_EMISSION, emm2); // bez tego słupy się świecą
|
||||
}
|
||||
}
|
||||
else if (eType == TP_STARS)
|
||||
{
|
||||
if (Global::fLuminance < fLight)
|
||||
{ // Ra: pewnie można by to zrobić
|
||||
// lepiej, bez powtarzania StartVBO()
|
||||
pRoot->EndVBO(); // Ra: to też nie jest zbyt ładne
|
||||
if (pRoot->StartColorVBO())
|
||||
{ // wyświetlanie kolorowych punktów zamiast
|
||||
// trójkątów
|
||||
GfxRenderer.Bind(0); // tekstury nie ma
|
||||
glColorMaterial(GL_FRONT, GL_EMISSION);
|
||||
glDisable(GL_LIGHTING); // Tolaris-030603: bo mu punkty swiecace sie
|
||||
// blendowaly
|
||||
// glMaterialfv(GL_FRONT,GL_EMISSION,f4Diffuse); //zeby swiecilo na
|
||||
// kolorowo
|
||||
glDrawArrays(GL_POINTS, iVboPtr,
|
||||
iNumVerts); // narysuj naraz wszystkie punkty z VBO
|
||||
glEnable(GL_LIGHTING);
|
||||
glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
|
||||
// glMaterialfv(GL_FRONT,GL_EMISSION,emm2);
|
||||
pRoot->EndVBO();
|
||||
pRoot->StartVBO();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Child != NULL)
|
||||
if (iAlpha & iFlags & 0x001F0000)
|
||||
Child->RenderVBO(mm);
|
||||
if (iFlags & 0xC000)
|
||||
World.shader.set_mv(m);
|
||||
}
|
||||
if (b_Anim < at_SecondsJump)
|
||||
b_Anim = at_None; // wyłączenie animacji dla kolejnego użycia submodelu
|
||||
if (Next)
|
||||
if (iAlpha & iFlags & 0x1F000000)
|
||||
Next->RenderVBO(m); // dalsze rekurencyjnie
|
||||
}; // RaRender
|
||||
|
||||
void TSubModel::RenderAlphaVBO(glm::mat4 m)
|
||||
{ // renderowanie przezroczystych przez VBO
|
||||
if( ( iVisible )
|
||||
&& ( fSquareDist >= (fSquareMinDist / Global::fDistanceFactor) )
|
||||
&& ( fSquareDist <= (fSquareMaxDist * Global::fDistanceFactor) ) )
|
||||
{
|
||||
glm::mat4 mm = m;
|
||||
if (iFlags & 0xC000)
|
||||
{
|
||||
if (fMatrix)
|
||||
mm *= glm::make_mat4(fMatrix->e);
|
||||
if (b_Anim)
|
||||
RaAnimation(mm, b_Anim);
|
||||
World.shader.set_mv(mm);
|
||||
}
|
||||
|
||||
if (eType < TP_ROTATOR)
|
||||
{ // renderowanie obiektów OpenGL
|
||||
if (iAlpha & iFlags & 0x2F) // rysuj gdy element przezroczysty
|
||||
{
|
||||
if (TextureID < 0) // && (ReplacableSkinId!=0))
|
||||
{ // zmienialne skory
|
||||
GfxRenderer.Bind(ReplacableSkinId[-TextureID]);
|
||||
// TexAlpha=iAlpha&1; //zmiana tylko w przypadku wymienej tekstury
|
||||
}
|
||||
else
|
||||
GfxRenderer.Bind(TextureID); // również 0
|
||||
if (Global::fLuminance < fLight)
|
||||
{
|
||||
//glMaterialfv(GL_FRONT, GL_EMISSION, f4Diffuse); // zeby swiecilo na kolorowo
|
||||
glDrawArrays(eType, iVboPtr,
|
||||
iNumVerts); // narysuj naraz wszystkie trójkąty z VBO
|
||||
//glMaterialfv(GL_FRONT, GL_EMISSION, emm2);
|
||||
}
|
||||
else
|
||||
glDrawArrays(eType, iVboPtr,
|
||||
iNumVerts); // narysuj naraz wszystkie trójkąty z VBO
|
||||
}
|
||||
}
|
||||
else if (eType == TP_FREESPOTLIGHT)
|
||||
{
|
||||
// dorobić aureolę!
|
||||
}
|
||||
if (Child)
|
||||
if (iAlpha & iFlags & 0x002F0000)
|
||||
Child->RenderAlphaVBO(mm);
|
||||
if (iFlags & 0xC000)
|
||||
World.shader.set_mv(m);
|
||||
}
|
||||
if (b_aAnim < at_SecondsJump)
|
||||
b_aAnim = at_None; // wyłączenie animacji dla kolejnego użycia submodelu
|
||||
if (Next)
|
||||
if (iAlpha & iFlags & 0x2F000000)
|
||||
Next->RenderAlphaVBO(m);
|
||||
}; // RaRenderAlpha
|
||||
#endif
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void TSubModel::RaArrayFill(CVertNormTex *Vert)
|
||||
@@ -1450,8 +1099,12 @@ TModel3d::~TModel3d()
|
||||
}
|
||||
else
|
||||
{ // wczytano z pliku binarnego (jest właścicielem tablic)
|
||||
m_pVNT = NULL; // nie usuwać tego, bo wskazuje na iModel
|
||||
Root = NULL;
|
||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||
m_pVNT = nullptr; // nie usuwać tego, bo wskazuje na iModel
|
||||
#else
|
||||
m_pVNT.clear();
|
||||
#endif
|
||||
Root = nullptr;
|
||||
delete[] iModel; // usuwamy cały wczytany plik i to wystarczy
|
||||
}
|
||||
// później się jeszcze usuwa obiekt z którego dziedziczymy tabelę VBO
|
||||
@@ -1674,7 +1327,11 @@ void TModel3d::SaveToBinFile(char const *FileName)
|
||||
transforms[i].serialize_float32(s);
|
||||
|
||||
MakeArray(iNumVerts);
|
||||
Root->RaArrayFill(m_pVNT);
|
||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||
Root->RaArrayFill(m_pVNT);
|
||||
#else
|
||||
Root->RaArrayFill( m_pVNT.data() );
|
||||
#endif
|
||||
sn_utils::ls_uint32(s, MAKE_ID4('V', 'N', 'T', '0'));
|
||||
sn_utils::ls_uint32(s, 8 + iNumVerts * 32);
|
||||
for (size_t i = 0; i < (size_t)iNumVerts; i++)
|
||||
@@ -1759,7 +1416,11 @@ void TSubModel::deserialize(std::istream &s)
|
||||
|
||||
void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
|
||||
{
|
||||
m_pVNT = nullptr;
|
||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||
m_pVNT = nullptr;
|
||||
#else
|
||||
m_pVNT.clear();
|
||||
#endif
|
||||
Root = nullptr;
|
||||
float4x4 *tm = nullptr;
|
||||
|
||||
@@ -1773,13 +1434,22 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
|
||||
|
||||
if (type == MAKE_ID4('V', 'N', 'T', '0'))
|
||||
{
|
||||
if (m_pVNT != nullptr)
|
||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||
if (m_pVNT != nullptr)
|
||||
#else
|
||||
if( false == m_pVNT.empty() )
|
||||
#endif
|
||||
throw std::runtime_error("e3d: duplicated VNT chunk");
|
||||
|
||||
size_t vt_cnt = size / 32;
|
||||
iNumVerts = (int)vt_cnt;
|
||||
m_nVertexCount = (int)vt_cnt;
|
||||
m_pVNT = new CVertNormTex[vt_cnt];
|
||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||
assert( m_pVNT == nullptr );
|
||||
m_pVNT = new CVertNormTex[vt_cnt];
|
||||
#else
|
||||
m_pVNT.resize( vt_cnt );
|
||||
#endif
|
||||
for (size_t i = 0; i < vt_cnt; i++)
|
||||
m_pVNT[i].deserialize(s);
|
||||
}
|
||||
@@ -1840,12 +1510,20 @@ void TModel3d::deserialize(std::istream &s, size_t size, bool dynamic)
|
||||
if (!Root)
|
||||
throw std::runtime_error("e3d: no submodels");
|
||||
|
||||
if (!m_pVNT)
|
||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||
if (!m_pVNT)
|
||||
#else
|
||||
if(m_pVNT.empty() )
|
||||
#endif
|
||||
throw std::runtime_error("e3d: no vertices");
|
||||
|
||||
for (size_t i = 0; (int)i < iSubModelsCount; i++)
|
||||
{
|
||||
Root[i].BinInit(Root, tm, (float8*)m_pVNT, &Textures, &Names, dynamic);
|
||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||
Root[i].BinInit(Root, tm, (float8*)m_pVNT, &Textures, &Names, dynamic);
|
||||
#else
|
||||
Root[ i ].BinInit( Root, tm, (float8*)m_pVNT.data(), &Textures, &Names, dynamic );
|
||||
#endif
|
||||
|
||||
if (Root[i].ChildGet())
|
||||
Root[i].ChildGet()->Parent = &Root[i];
|
||||
@@ -2019,11 +1697,18 @@ void TModel3d::Init()
|
||||
Root->AdjustDist(); // aktualizacja odległości faz LoD, zależnie od
|
||||
// rozdzielczości pionowej oraz multisamplingu
|
||||
*/
|
||||
if (!m_pVNT) // jeśli nie ma jeszcze tablicy (wczytano z pliku
|
||||
// tekstowego)
|
||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||
if (!m_pVNT) // jeśli nie ma jeszcze tablicy (wczytano z pliku tekstowego)
|
||||
#else
|
||||
if( m_pVNT.empty() )
|
||||
#endif
|
||||
{ // tworzenie tymczasowej tablicy z wierzchołkami całego modelu
|
||||
MakeArray(iNumVerts); // tworzenie tablic dla VBO
|
||||
Root->RaArrayFill(m_pVNT); // wypełnianie tablicy
|
||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||
Root->RaArrayFill(m_pVNT); // wypełnianie tablicy
|
||||
#else
|
||||
Root->RaArrayFill( m_pVNT.data() ); // wypełnianie tablicy
|
||||
#endif
|
||||
BuildVBOs(); // tworzenie VBO i usuwanie tablicy z pamięci
|
||||
}
|
||||
else
|
||||
@@ -2039,168 +1724,6 @@ void TModel3d::BreakHierarhy()
|
||||
Error("Not implemented yet :(");
|
||||
};
|
||||
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
void TModel3d::Render(double fSquareDistance, texture_manager::size_type *ReplacableSkinId, int iAlpha)
|
||||
{
|
||||
iAlpha ^= 0x0F0F000F; // odwrócenie flag tekstur, aby wyłapać nieprzezroczyste
|
||||
if (iAlpha & iFlags & 0x1F1F001F) // czy w ogóle jest co robić w tym cyklu?
|
||||
{
|
||||
TSubModel::fSquareDist = fSquareDistance; // zmienna globalna!
|
||||
Root->ReplacableSet(ReplacableSkinId, iAlpha);
|
||||
Root->RenderDL();
|
||||
}
|
||||
};
|
||||
|
||||
void TModel3d::RenderAlpha(double fSquareDistance, texture_manager::size_type *ReplacableSkinId, int iAlpha)
|
||||
{
|
||||
if (iAlpha & iFlags & 0x2F2F002F)
|
||||
{
|
||||
TSubModel::fSquareDist = fSquareDistance; // zmienna globalna!
|
||||
Root->ReplacableSet(ReplacableSkinId, iAlpha);
|
||||
Root->RenderAlphaDL();
|
||||
}
|
||||
};
|
||||
|
||||
void TModel3d::RaRender(double fSquareDistance, texture_manager::size_type const *ReplacableSkinId, int iAlpha)
|
||||
{ // renderowanie specjalne, np. kabiny
|
||||
iAlpha ^= 0x0F0F000F; // odwrócenie flag tekstur, aby wyłapać nieprzezroczyste
|
||||
if (iAlpha & iFlags & 0x1F1F001F) // czy w ogóle jest co robić w tym cyklu?
|
||||
{
|
||||
TSubModel::fSquareDist = fSquareDistance; // zmienna globalna!
|
||||
if (StartVBO())
|
||||
{ // odwrócenie flag, aby wyłapać nieprzezroczyste
|
||||
Root->ReplacableSet(ReplacableSkinId, iAlpha);
|
||||
Root->pRoot = this;
|
||||
|
||||
float mv[16], p[16];
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, mv);
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, p);
|
||||
World.shader.set_mv(glm::make_mat4(mv));
|
||||
World.shader.set_p(glm::make_mat4(p));
|
||||
Root->RenderVBO(glm::make_mat4(mv));
|
||||
|
||||
EndVBO();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void TModel3d::RaRenderAlpha(double fSquareDistance, texture_manager::size_type const *ReplacableSkinId, int iAlpha)
|
||||
{ // renderowanie specjalne, np. kabiny
|
||||
if (iAlpha & iFlags & 0x2F2F002F) // czy w ogóle jest co robić w tym cyklu?
|
||||
{
|
||||
TSubModel::fSquareDist = fSquareDistance; // zmienna globalna!
|
||||
if (StartVBO())
|
||||
{
|
||||
Root->ReplacableSet(ReplacableSkinId, iAlpha);
|
||||
|
||||
float mv[16], p[16];
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, mv);
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, p);
|
||||
World.shader.set_mv(glm::make_mat4(mv));
|
||||
World.shader.set_p(glm::make_mat4(p));
|
||||
Root->RenderAlphaVBO(glm::make_mat4(mv));
|
||||
|
||||
EndVBO();
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
// 2011-03-16 cztery nowe funkcje renderowania z możliwością pochylania obiektów
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
void TModel3d::Render(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId, int iAlpha)
|
||||
{ // nieprzezroczyste, Display List
|
||||
glPushMatrix();
|
||||
glTranslated(vPosition->x, vPosition->y, vPosition->z);
|
||||
if (vAngle->y != 0.0)
|
||||
glRotated(vAngle->y, 0.0, 1.0, 0.0);
|
||||
if (vAngle->x != 0.0)
|
||||
glRotated(vAngle->x, 1.0, 0.0, 0.0);
|
||||
if (vAngle->z != 0.0)
|
||||
glRotated(vAngle->z, 0.0, 0.0, 1.0);
|
||||
TSubModel::fSquareDist =
|
||||
SquareMagnitude(*vPosition - Global::GetCameraPosition()); // zmienna globalna!
|
||||
// odwrócenie flag, aby wyłapać nieprzezroczyste
|
||||
Root->ReplacableSet(ReplacableSkinId, iAlpha ^ 0x0F0F000F);
|
||||
Root->RenderDL();
|
||||
glPopMatrix();
|
||||
};
|
||||
void TModel3d::RenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId,
|
||||
int iAlpha)
|
||||
{ // przezroczyste, Display List
|
||||
glPushMatrix();
|
||||
glTranslated(vPosition->x, vPosition->y, vPosition->z);
|
||||
if (vAngle->y != 0.0)
|
||||
glRotated(vAngle->y, 0.0, 1.0, 0.0);
|
||||
if (vAngle->x != 0.0)
|
||||
glRotated(vAngle->x, 1.0, 0.0, 0.0);
|
||||
if (vAngle->z != 0.0)
|
||||
glRotated(vAngle->z, 0.0, 0.0, 1.0);
|
||||
TSubModel::fSquareDist =
|
||||
SquareMagnitude(*vPosition - Global::GetCameraPosition()); // zmienna globalna!
|
||||
Root->ReplacableSet(ReplacableSkinId, iAlpha);
|
||||
Root->RenderAlphaDL();
|
||||
glPopMatrix();
|
||||
};
|
||||
|
||||
void TModel3d::RaRender(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type const *ReplacableSkinId, int iAlpha)
|
||||
{ // nieprzezroczyste, VBO
|
||||
glPushMatrix();
|
||||
glTranslated(vPosition->x, vPosition->y, vPosition->z);
|
||||
if (vAngle->y != 0.0)
|
||||
glRotated(vAngle->y, 0.0, 1.0, 0.0);
|
||||
if (vAngle->x != 0.0)
|
||||
glRotated(vAngle->x, 1.0, 0.0, 0.0);
|
||||
if (vAngle->z != 0.0)
|
||||
glRotated(vAngle->z, 0.0, 0.0, 1.0);
|
||||
TSubModel::fSquareDist =
|
||||
SquareMagnitude(*vPosition - Global::GetCameraPosition()); // zmienna globalna!
|
||||
if (StartVBO())
|
||||
{ // odwrócenie flag, aby wyłapać nieprzezroczyste
|
||||
Root->ReplacableSet(ReplacableSkinId, iAlpha ^ 0x0F0F000F);
|
||||
|
||||
float mv[16], p[16];
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, mv);
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, p);
|
||||
World.shader.set_mv(glm::make_mat4(mv));
|
||||
World.shader.set_p(glm::make_mat4(p));
|
||||
Root->RenderVBO(glm::make_mat4(mv));
|
||||
|
||||
EndVBO();
|
||||
}
|
||||
glPopMatrix();
|
||||
};
|
||||
void TModel3d::RaRenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type const *ReplacableSkinId,
|
||||
int iAlpha)
|
||||
{ // przezroczyste, VBO
|
||||
glPushMatrix();
|
||||
glTranslated(vPosition->x, vPosition->y, vPosition->z);
|
||||
if (vAngle->y != 0.0)
|
||||
glRotated(vAngle->y, 0.0, 1.0, 0.0);
|
||||
if (vAngle->x != 0.0)
|
||||
glRotated(vAngle->x, 1.0, 0.0, 0.0);
|
||||
if (vAngle->z != 0.0)
|
||||
glRotated(vAngle->z, 0.0, 0.0, 1.0);
|
||||
TSubModel::fSquareDist =
|
||||
SquareMagnitude(*vPosition - Global::GetCameraPosition()); // zmienna globalna!
|
||||
if (StartVBO())
|
||||
{
|
||||
Root->ReplacableSet(ReplacableSkinId, iAlpha);
|
||||
|
||||
float mv[16], p[16];
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, mv);
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, p);
|
||||
World.shader.set_mv(glm::make_mat4(mv));
|
||||
World.shader.set_p(glm::make_mat4(p));
|
||||
Root->RenderAlphaVBO(glm::make_mat4(mv));
|
||||
|
||||
EndVBO();
|
||||
}
|
||||
glPopMatrix();
|
||||
};
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 2012-02 funkcje do tworzenia terenu z E3D
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2232,7 +1755,7 @@ TSubModel *TModel3d::TerrainSquare(int n)
|
||||
void TModel3d::TerrainRenderVBO(int n)
|
||||
{ // renderowanie terenu z VBO
|
||||
glPushMatrix();
|
||||
|
||||
::glTranslated( -Global::pCameraPosition.x, -Global::pCameraPosition.y, -Global::pCameraPosition.z );
|
||||
float mv[16], p[16];
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, mv);
|
||||
glGetFloatv(GL_PROJECTION_MATRIX, p);
|
||||
|
||||
20
Model3d.h
20
Model3d.h
@@ -255,12 +255,6 @@ public:
|
||||
void SetRotateIK1(float3 vNewAngles);
|
||||
TSubModel * GetFromName(std::string const &search, bool i = true);
|
||||
TSubModel * GetFromName(char const *search, bool i = true);
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
void RenderDL();
|
||||
void RenderAlphaDL();
|
||||
void RenderVBO();
|
||||
void RenderAlphaVBO();
|
||||
#endif
|
||||
// inline matrix4x4* GetMatrix() {return dMatrix;};
|
||||
inline float4x4 * GetMatrix()
|
||||
{
|
||||
@@ -361,20 +355,6 @@ public:
|
||||
bool LoadFromFile(std::string const &FileName, bool dynamic);
|
||||
void SaveToBinFile(char const *FileName);
|
||||
void BreakHierarhy();
|
||||
// renderowanie specjalne
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
void Render(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
|
||||
void RenderAlpha(double fSquareDistance, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
|
||||
#endif
|
||||
void RaRender(double fSquareDistance, texture_manager::size_type const *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
|
||||
void RaRenderAlpha(double fSquareDistance, texture_manager::size_type const *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
|
||||
// trzy kąty obrotu
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
void Render( vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030 );
|
||||
void RenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
|
||||
#endif
|
||||
void RaRender(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type const *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
|
||||
void RaRenderAlpha(vector3 *vPosition, vector3 *vAngle, texture_manager::size_type const *ReplacableSkinId = NULL, int iAlpha = 0x30300030);
|
||||
// inline int GetSubModelsCount() { return (SubModelsCount); };
|
||||
int Flags() const
|
||||
{
|
||||
|
||||
@@ -40,7 +40,7 @@ void TRealSound::Init(std::string const &SoundName, double DistanceAttenuation,
|
||||
bool Dynamic, bool freqmod, double rmin)
|
||||
{
|
||||
// Nazwa=SoundName; //to tak raczej nie zadziała, (SoundName) jest tymczasowe
|
||||
pSound = TSoundsManager::GetFromName(SoundName.c_str(), Dynamic, &fFrequency);
|
||||
pSound = TSoundsManager::GetFromName(SoundName, Dynamic, &fFrequency);
|
||||
if (pSound)
|
||||
{
|
||||
if (freqmod)
|
||||
@@ -48,8 +48,7 @@ void TRealSound::Init(std::string const &SoundName, double DistanceAttenuation,
|
||||
{ // dla modulowanych nie może być zmiany mnożnika, bo częstotliwość w nagłówku byłą
|
||||
// ignorowana, a mogła być inna niż 22050
|
||||
fFrequency = 22050.0;
|
||||
ErrorLog("Bad sound: " + std::string(SoundName) +
|
||||
", as modulated, should have 22.05kHz in header");
|
||||
ErrorLog("Bad sound: " + SoundName + ", as modulated, should have 22.05kHz in header");
|
||||
}
|
||||
AM = 1.0;
|
||||
pSound->SetVolume(DSBVOLUME_MIN);
|
||||
@@ -57,7 +56,7 @@ void TRealSound::Init(std::string const &SoundName, double DistanceAttenuation,
|
||||
else
|
||||
{ // nie ma dźwięku, to jest wysyp
|
||||
AM = 0;
|
||||
ErrorLog("Missed sound: " + std::string(SoundName));
|
||||
ErrorLog("Missed sound: " + SoundName);
|
||||
}
|
||||
if (DistanceAttenuation > 0.0)
|
||||
{
|
||||
@@ -268,26 +267,8 @@ void TTextSound::Play(double Volume, int Looping, bool ListenerInside, vector3 N
|
||||
{ // jeśli ma powiązany tekst
|
||||
DWORD stat;
|
||||
pSound->GetStatus(&stat);
|
||||
if (!(stat & DSBSTATUS_PLAYING)) // jeśli nie jest aktualnie odgrywany
|
||||
{
|
||||
/*
|
||||
std::string t( asText );
|
||||
size_t i;
|
||||
do
|
||||
{ // na razie zrobione jakkolwiek, docelowo przenieść teksty do tablicy nazw
|
||||
i = t.find('\r'); // znak nowej linii
|
||||
if( i == std::string::npos ) {
|
||||
Global::tranTexts.Add( t, fTime, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
Global::tranTexts.Add(t.substr(0, i), fTime, true);
|
||||
t.erase(0, i + 1);
|
||||
while (t.empty() ? false : (unsigned char)(t[1]) < 33)
|
||||
t.erase(0, 1);
|
||||
}
|
||||
} while (i != std::string::npos);
|
||||
*/
|
||||
if (!(stat & DSBSTATUS_PLAYING)) {
|
||||
// jeśli nie jest aktualnie odgrywany
|
||||
Global::tranTexts.Add( asText, fTime, true );
|
||||
}
|
||||
}
|
||||
|
||||
908
Segment.cpp
908
Segment.cpp
@@ -19,12 +19,6 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
// 101206 Ra: trapezoidalne drogi
|
||||
// 110806 Ra: odwrócone mapowanie wzdłuż - Point1 == 1.0
|
||||
|
||||
float Interpolate( float const First, float const Second, float const Factor ) {
|
||||
|
||||
return ( First * ( 1.0f - Factor ) ) + ( Second * Factor );
|
||||
}
|
||||
|
||||
std::string Where(vector3 p)
|
||||
{ // zamiana współrzędnych na tekst, używana w błędach
|
||||
return std::to_string(p.x) + " " + std::to_string(p.y) + " " + std::to_string(p.z);
|
||||
@@ -120,29 +114,30 @@ bool TSegment::Init(vector3 &NewPoint1, vector3 NewCPointOut, vector3 NewCPointI
|
||||
{
|
||||
ErrorLog( "Bad geometry (zero length) for spline \"" + pOwner->NameGet() + "\" at " + Where( Point1 ) );
|
||||
// MessageBox(0,"Length<=0","TSegment::Init",MB_OK);
|
||||
fLength = 0.01; // crude workaround TODO: fix this properly
|
||||
/*
|
||||
return false; // zerowe nie mogą być
|
||||
*/
|
||||
}
|
||||
fStoop = atan2((Point2.y - Point1.y),
|
||||
fLength); // pochylenie toru prostego, żeby nie liczyć wielokrotnie
|
||||
|
||||
if( ( pOwner->eType == tt_Switch )
|
||||
&& ( fStep * 3.0 > fLength ) ) {
|
||||
// NOTE: a workaround for too short switches (less than 3 segments) messing up animation/generation of blades
|
||||
fStep = fLength / 3.0;
|
||||
}
|
||||
|
||||
fStoop = std::atan2((Point2.y - Point1.y), fLength); // pochylenie toru prostego, żeby nie liczyć wielokrotnie
|
||||
SafeDeleteArray(fTsBuffer);
|
||||
|
||||
if( ( bCurve ) && ( fStep > 0 ) ) {
|
||||
if( fStep > 0 ) { // Ra: prosty dostanie podział, jak ma różną przechyłkę na końcach
|
||||
double s = 0;
|
||||
int i = 0;
|
||||
iSegCount = ceil( fLength / fStep ); // potrzebne do VBO
|
||||
// fStep=fLength/(double)(iSegCount-1); //wyrównanie podziału
|
||||
fTsBuffer = new double[ iSegCount + 1 ];
|
||||
fTsBuffer[ 0 ] = 0; /* TODO : fix fTsBuffer */
|
||||
while( s < fLength ) {
|
||||
i++;
|
||||
s += fStep;
|
||||
if( s > fLength )
|
||||
s = fLength;
|
||||
fTsBuffer[ i ] = GetTFromS( s );
|
||||
}
|
||||
}
|
||||
iSegCount = static_cast<int>( std::ceil( fLength / fStep ) ); // potrzebne do VBO
|
||||
fStep = fLength / iSegCount; // update step to equalize size of individual pieces
|
||||
fTsBuffer = new double[ iSegCount + 1 ];
|
||||
fTsBuffer[ 0 ] = 0.0;
|
||||
for( int i = 1; i < iSegCount; ++i ) {
|
||||
fTsBuffer[ i ] = GetTFromS( i * fStep );
|
||||
}
|
||||
fTsBuffer[ iSegCount ] = 1.0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -324,410 +319,203 @@ vector3 TSegment::FastGetPoint(double t)
|
||||
return (bCurve ? RaInterpolate(t) : ((1.0 - t) * Point1 + (t)*Point2));
|
||||
}
|
||||
|
||||
void TSegment::RenderLoft(const vector6 *ShapePoints, int iNumShapePoints, double fTextureLength,
|
||||
int iSkip, int iQualityFactor, vector3 **p, bool bRender)
|
||||
int TSegment::RenderLoft( CVertNormTex* &Output, Math3D::vector3 const &Origin, const vector6 *ShapePoints, int iNumShapePoints, double fTextureLength, double Texturescale, int iSkip, int iEnd, double fOffsetX, vector3 **p, bool bRender)
|
||||
{ // generowanie trójkątów dla odcinka trajektorii ruchu
|
||||
// standardowo tworzy triangle_strip dla prostego albo ich zestaw dla łuku
|
||||
// po modyfikacji - dla ujemnego (iNumShapePoints) w dodatkowych polach tabeli
|
||||
// podany jest przekrój końcowy
|
||||
// podsypka toru jest robiona za pomocą 6 punktów, szyna 12, drogi i rzeki na 3+2+3
|
||||
if (iQualityFactor < 1)
|
||||
iQualityFactor = 1; // co który segment ma być uwzględniony
|
||||
int vertexcount{ 0 };
|
||||
|
||||
if( !fTsBuffer )
|
||||
return vertexcount; // prowizoryczne zabezpieczenie przed wysypem - ustalić faktyczną przyczynę
|
||||
|
||||
vector3 pos1, pos2, dir, parallel1, parallel2, pt, norm;
|
||||
double s, step, fOffset, tv1, tv2, t;
|
||||
int i, j;
|
||||
bool trapez = iNumShapePoints < 0; // sygnalizacja trapezowatości
|
||||
iNumShapePoints = abs(iNumShapePoints);
|
||||
if (bCurve)
|
||||
{
|
||||
double m1, jmm1, m2, jmm2; // pozycje względne na odcinku 0...1 (ale nie parametr Beziera)
|
||||
tv1 = 1.0; // Ra: to by można było wyliczać dla odcinka, wyglądało by lepiej
|
||||
step = fStep * iQualityFactor;
|
||||
s = fStep * iSkip; // iSkip - ile odcinków z początku pominąć
|
||||
i = iSkip; // domyślnie 0
|
||||
if (!fTsBuffer)
|
||||
return; // prowizoryczne zabezpieczenie przed wysypem - ustalić faktyczną przyczynę
|
||||
if (i > iSegCount)
|
||||
return; // prowizoryczne zabezpieczenie przed wysypem - ustalić faktyczną przyczynę
|
||||
t = fTsBuffer[i]; // tabela watości t dla segmentów
|
||||
fOffset = 0.1 / fLength; // pierwsze 10cm
|
||||
pos1 = FastGetPoint(t); // wektor początku segmentu
|
||||
dir = FastGetDirection(t, fOffset); // wektor kierunku
|
||||
// parallel1=Normalize(CrossProduct(dir,vector3(0,1,0))); //wektor poprzeczny
|
||||
parallel1 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
m2 = s / fLength;
|
||||
jmm2 = 1.0 - m2;
|
||||
while (s < fLength)
|
||||
{
|
||||
// step=SquareMagnitude(Global::GetCameraPosition()+pos);
|
||||
i += iQualityFactor; // kolejny punkt łamanej
|
||||
s += step; // końcowa pozycja segmentu [m]
|
||||
m1 = m2;
|
||||
jmm1 = jmm2; // stara pozycja
|
||||
m2 = s / fLength;
|
||||
jmm2 = 1.0 - m2; // nowa pozycja
|
||||
if (s > fLength - 0.5) // Ra: -0.5 żeby nie robiło cieniasa na końcu
|
||||
{ // gdy przekroczyliśmy koniec - stąd dziury w torach...
|
||||
step -= (s - fLength); // jeszcze do wyliczenia mapowania potrzebny
|
||||
s = fLength;
|
||||
i = iSegCount; // 20/5 ma dawać 4
|
||||
m2 = 1.0;
|
||||
jmm2 = 0.0;
|
||||
}
|
||||
while (tv1 < 0.0)
|
||||
tv1 += 1.0; // przestawienie mapowania
|
||||
tv2 = tv1 - step / fTextureLength; // mapowanie na końcu segmentu
|
||||
t = fTsBuffer[i]; // szybsze od GetTFromS(s);
|
||||
pos2 = FastGetPoint(t);
|
||||
dir = FastGetDirection(t, fOffset); // nowy wektor kierunku
|
||||
// parallel2=CrossProduct(dir,vector3(0,1,0)); //wektor poprzeczny
|
||||
parallel2 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
if (trapez)
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{
|
||||
norm = (jmm1 * ShapePoints[j].n.x + m1 * ShapePoints[j + iNumShapePoints].n.x) *
|
||||
parallel1;
|
||||
norm.y += jmm1 * ShapePoints[j].n.y + m1 * ShapePoints[j + iNumShapePoints].n.y;
|
||||
pt = parallel1 *
|
||||
(jmm1 * ShapePoints[j].x + m1 * ShapePoints[j + iNumShapePoints].x) +
|
||||
pos1;
|
||||
pt.y += jmm1 * ShapePoints[j].y + m1 * ShapePoints[j + iNumShapePoints].y;
|
||||
if (bRender)
|
||||
{ // skrzyżowania podczas łączenia siatek mogą nie renderować poboczy, ale
|
||||
// potrzebować punktów
|
||||
glNormal3f(norm.x, norm.y, norm.z);
|
||||
glTexCoord2f(
|
||||
jmm1 * ShapePoints[j].z + m1 * ShapePoints[j + iNumShapePoints].z, tv1);
|
||||
glVertex3f(pt.x, pt.y, pt.z); // pt nie mamy gdzie zapamiętać?
|
||||
}
|
||||
// BUG: things blow up badly in the following part in 64bit version on baltyk.scn
|
||||
// TODO: sort this mess out when the time comes to reorganize spline generation
|
||||
if( p ) // jeśli jest wskaźnik do tablicy
|
||||
if (*p)
|
||||
if (!j) // to dla pierwszego punktu
|
||||
{
|
||||
*(*p) = pt;
|
||||
(*p)++;
|
||||
} // zapamiętanie brzegu jezdni
|
||||
// dla trapezu drugi koniec ma inne współrzędne
|
||||
norm = (jmm1 * ShapePoints[j].n.x + m1 * ShapePoints[j + iNumShapePoints].n.x) *
|
||||
parallel2;
|
||||
norm.y += jmm1 * ShapePoints[j].n.y + m1 * ShapePoints[j + iNumShapePoints].n.y;
|
||||
pt = parallel2 *
|
||||
(jmm2 * ShapePoints[j].x + m2 * ShapePoints[j + iNumShapePoints].x) +
|
||||
pos2;
|
||||
pt.y += jmm2 * ShapePoints[j].y + m2 * ShapePoints[j + iNumShapePoints].y;
|
||||
if (bRender)
|
||||
{ // skrzyżowania podczas łączenia siatek mogą nie renderować poboczy, ale
|
||||
// potrzebować punktów
|
||||
glNormal3f(norm.x, norm.y, norm.z);
|
||||
glTexCoord2f(
|
||||
jmm2 * ShapePoints[j].z + m2 * ShapePoints[j + iNumShapePoints].z, tv2);
|
||||
glVertex3f(pt.x, pt.y, pt.z);
|
||||
}
|
||||
if (p) // jeśli jest wskaźnik do tablicy
|
||||
if (*p)
|
||||
if (!j) // to dla pierwszego punktu
|
||||
if (i == iSegCount)
|
||||
{
|
||||
*(*p) = pt;
|
||||
(*p)++;
|
||||
} // zapamiętanie brzegu jezdni
|
||||
}
|
||||
else
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{ //łuk z jednym profilem
|
||||
norm = ShapePoints[j].n.x * parallel1;
|
||||
norm.y += ShapePoints[j].n.y;
|
||||
pt = parallel1 * ShapePoints[j].x + pos1;
|
||||
pt.y += ShapePoints[j].y;
|
||||
glNormal3f(norm.x, norm.y, norm.z);
|
||||
glTexCoord2f(ShapePoints[j].z, tv1);
|
||||
glVertex3f(pt.x, pt.y, pt.z); // punkt na początku odcinka
|
||||
norm = ShapePoints[j].n.x * parallel2;
|
||||
norm.y += ShapePoints[j].n.y;
|
||||
pt = parallel2 * ShapePoints[j].x + pos2;
|
||||
pt.y += ShapePoints[j].y;
|
||||
glNormal3f(norm.x, norm.y, norm.z);
|
||||
glTexCoord2f(ShapePoints[j].z, tv2);
|
||||
glVertex3f(pt.x, pt.y, pt.z); // punkt na końcu odcinka
|
||||
}
|
||||
glEnd();
|
||||
pos1 = pos2;
|
||||
parallel1 = parallel2;
|
||||
tv1 = tv2;
|
||||
double s, step, fOffset, tv1, tv2, t, fEnd;
|
||||
bool const trapez = iNumShapePoints < 0; // sygnalizacja trapezowatości
|
||||
iNumShapePoints = std::abs( iNumShapePoints );
|
||||
fTextureLength *= Texturescale;
|
||||
|
||||
double m1, jmm1, m2, jmm2; // pozycje względne na odcinku 0...1 (ale nie parametr Beziera)
|
||||
step = fStep;
|
||||
tv1 = 1.0; // Ra: to by można było wyliczać dla odcinka, wyglądało by lepiej
|
||||
s = fStep * iSkip; // iSkip - ile odcinków z początku pominąć
|
||||
int i = iSkip; // domyślnie 0
|
||||
t = fTsBuffer[ i ]; // tabela wattości t dla segmentów
|
||||
// BUG: length of spline can be 0, we should skip geometry generation for such cases
|
||||
fOffset = 0.1 / fLength; // pierwsze 10cm
|
||||
pos1 = FastGetPoint( t ); // wektor początku segmentu
|
||||
dir = FastGetDirection( t, fOffset ); // wektor kierunku
|
||||
parallel1 = Normalize( vector3( -dir.z, 0.0, dir.x ) ); // wektor poprzeczny
|
||||
if( iEnd == 0 )
|
||||
iEnd = iSegCount;
|
||||
fEnd = fLength * double( iEnd ) / double( iSegCount );
|
||||
m2 = s / fEnd;
|
||||
jmm2 = 1.0 - m2;
|
||||
|
||||
while( i < iEnd ) {
|
||||
|
||||
++i; // kolejny punkt łamanej
|
||||
s += step; // końcowa pozycja segmentu [m]
|
||||
m1 = m2;
|
||||
jmm1 = jmm2; // stara pozycja
|
||||
m2 = s / fEnd;
|
||||
jmm2 = 1.0 - m2; // nowa pozycja
|
||||
if( i == iEnd ) { // gdy przekroczyliśmy koniec - stąd dziury w torach...
|
||||
step -= ( s - fEnd ); // jeszcze do wyliczenia mapowania potrzebny
|
||||
s = fEnd;
|
||||
m2 = 1.0;
|
||||
jmm2 = 0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
{ // gdy prosty, nie modyfikujemy wektora kierunkowego i poprzecznego
|
||||
pos1 = FastGetPoint((fStep * iSkip) / fLength);
|
||||
pos2 = FastGetPoint_1();
|
||||
dir = GetDirection();
|
||||
// parallel1=Normalize(CrossProduct(dir,vector3(0,1,0)));
|
||||
parallel1 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
if (trapez)
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{
|
||||
norm = ShapePoints[j].n.x * parallel1;
|
||||
norm.y += ShapePoints[j].n.y;
|
||||
pt = parallel1 * ShapePoints[j].x + pos1;
|
||||
pt.y += ShapePoints[j].y;
|
||||
glNormal3f(norm.x, norm.y, norm.z);
|
||||
glTexCoord2f(ShapePoints[j].z, 0);
|
||||
glVertex3f(pt.x, pt.y, pt.z);
|
||||
// dla trapezu drugi koniec ma inne współrzędne względne
|
||||
norm = ShapePoints[j + iNumShapePoints].n.x * parallel1;
|
||||
norm.y += ShapePoints[j + iNumShapePoints].n.y;
|
||||
pt = parallel1 * ShapePoints[j + iNumShapePoints].x + pos2; // odsunięcie
|
||||
pt.y += ShapePoints[j + iNumShapePoints].y; // wysokość
|
||||
glNormal3f(norm.x, norm.y, norm.z);
|
||||
glTexCoord2f(ShapePoints[j + iNumShapePoints].z, fLength / fTextureLength);
|
||||
glVertex3f(pt.x, pt.y, pt.z);
|
||||
|
||||
while( tv1 < 0.0 ) {
|
||||
tv1 += 1.0;
|
||||
}
|
||||
tv2 = tv1 - step / fTextureLength; // mapowanie na końcu segmentu
|
||||
|
||||
t = fTsBuffer[ i ]; // szybsze od GetTFromS(s);
|
||||
pos2 = FastGetPoint( t );
|
||||
dir = FastGetDirection( t, fOffset ); // nowy wektor kierunku
|
||||
parallel2 = Normalize( vector3( -dir.z, 0.0, dir.x ) ); // wektor poprzeczny
|
||||
|
||||
if( Output == nullptr ) {
|
||||
// immediate mode
|
||||
::glBegin( GL_TRIANGLE_STRIP );
|
||||
}
|
||||
|
||||
if( trapez ) {
|
||||
for( int j = 0; j < iNumShapePoints; ++j ) {
|
||||
pt = parallel1 * ( jmm1 * ( ShapePoints[ j ].x - fOffsetX ) + m1 * ShapePoints[ j + iNumShapePoints ].x ) + pos1;
|
||||
pt.y += jmm1 * ShapePoints[ j ].y + m1 * ShapePoints[ j + iNumShapePoints ].y;
|
||||
pt -= Origin;
|
||||
norm = ( jmm1 * ShapePoints[ j ].n.x + m1 * ShapePoints[ j + iNumShapePoints ].n.x ) * parallel1;
|
||||
norm.y += jmm1 * ShapePoints[ j ].n.y + m1 * ShapePoints[ j + iNumShapePoints ].n.y;
|
||||
if( bRender ) { // skrzyżowania podczas łączenia siatek mogą nie renderować poboczy, ale potrzebować punktów
|
||||
if( Output == nullptr ) {
|
||||
// immediate mode
|
||||
::glNormal3f( norm.x, norm.y, norm.z );
|
||||
::glTexCoord2f( (jmm1 * ShapePoints[ j ].z + m1 * ShapePoints[ j + iNumShapePoints ].z) / Texturescale, tv1 );
|
||||
::glVertex3f( pt.x, pt.y, pt.z ); // pt nie mamy gdzie zapamiętać?
|
||||
}
|
||||
else {
|
||||
Output->x = pt.x;
|
||||
Output->y = pt.y;
|
||||
Output->z = pt.z;
|
||||
Output->nx = norm.x;
|
||||
Output->ny = norm.y;
|
||||
Output->nz = norm.z;
|
||||
Output->u = (jmm1 * ShapePoints[ j ].z + m1 * ShapePoints[ j + iNumShapePoints ].z) / Texturescale;
|
||||
Output->v = tv1;
|
||||
++Output;
|
||||
}
|
||||
++vertexcount;
|
||||
}
|
||||
if( p ) // jeśli jest wskaźnik do tablicy
|
||||
if( *p )
|
||||
if( !j ) // to dla pierwszego punktu
|
||||
{
|
||||
*( *p ) = pt;
|
||||
( *p )++;
|
||||
} // zapamiętanie brzegu jezdni
|
||||
// dla trapezu drugi koniec ma inne współrzędne
|
||||
pt = parallel2 * ( jmm2 * ( ShapePoints[ j ].x - fOffsetX ) + m2 * ShapePoints[ j + iNumShapePoints ].x ) + pos2;
|
||||
pt.y += jmm2 * ShapePoints[ j ].y + m2 * ShapePoints[ j + iNumShapePoints ].y;
|
||||
pt -= Origin;
|
||||
norm = ( jmm1 * ShapePoints[ j ].n.x + m1 * ShapePoints[ j + iNumShapePoints ].n.x ) * parallel2;
|
||||
norm.y += jmm1 * ShapePoints[ j ].n.y + m1 * ShapePoints[ j + iNumShapePoints ].n.y;
|
||||
if( bRender ) { // skrzyżowania podczas łączenia siatek mogą nie renderować poboczy, ale potrzebować punktów
|
||||
if( Output == nullptr ) {
|
||||
// immediate mode
|
||||
::glNormal3f( norm.x, norm.y, norm.z );
|
||||
::glTexCoord2f( (jmm2 * ShapePoints[ j ].z + m2 * ShapePoints[ j + iNumShapePoints ].z) / Texturescale, tv2 );
|
||||
::glVertex3f( pt.x, pt.y, pt.z );
|
||||
}
|
||||
else {
|
||||
Output->x = pt.x;
|
||||
Output->y = pt.y;
|
||||
Output->z = pt.z;
|
||||
Output->nx = norm.x;
|
||||
Output->ny = norm.y;
|
||||
Output->nz = norm.z;
|
||||
Output->u = (jmm2 * ShapePoints[ j ].z + m2 * ShapePoints[ j + iNumShapePoints ].z) / Texturescale;
|
||||
Output->v = tv2;
|
||||
++Output;
|
||||
}
|
||||
++vertexcount;
|
||||
}
|
||||
if( p ) // jeśli jest wskaźnik do tablicy
|
||||
if( *p )
|
||||
if( !j ) // to dla pierwszego punktu
|
||||
if( i == iSegCount ) {
|
||||
*( *p ) = pt;
|
||||
( *p )++;
|
||||
} // zapamiętanie brzegu jezdni
|
||||
}
|
||||
else
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{
|
||||
norm = ShapePoints[j].n.x * parallel1;
|
||||
norm.y += ShapePoints[j].n.y;
|
||||
pt = parallel1 * ShapePoints[j].x + pos1;
|
||||
pt.y += ShapePoints[j].y;
|
||||
glNormal3f(norm.x, norm.y, norm.z);
|
||||
glTexCoord2f(ShapePoints[j].z, 0);
|
||||
glVertex3f(pt.x, pt.y, pt.z);
|
||||
pt = parallel1 * ShapePoints[j].x + pos2;
|
||||
pt.y += ShapePoints[j].y;
|
||||
glNormal3f(norm.x, norm.y, norm.z);
|
||||
glTexCoord2f(ShapePoints[j].z, fLength / fTextureLength);
|
||||
glVertex3f(pt.x, pt.y, pt.z);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
#else
|
||||
{
|
||||
Math3D::vector3 const pos0 = FastGetPoint( ( fStep * iSkip ) / fLength );
|
||||
Math3D::vector3 const pos1 = FastGetPoint_1();
|
||||
dir = GetDirection();
|
||||
Math3D::vector3 const parallel = Normalize( vector3( -dir.z, 0.0, dir.x ) ); // wektor poprzeczny
|
||||
|
||||
Math3D::vector3 startnormal0, startnormal1, endnormal0, endnormal1;
|
||||
Math3D::vector3 startvertex0, startvertex1, endvertex0, endvertex1;
|
||||
float startuv0, startuv1, enduv0, enduv1;
|
||||
|
||||
for( j = 0; j < iNumShapePoints - 1; ++j ) {
|
||||
|
||||
startnormal0 = ShapePoints[ j ].n.x * parallel;
|
||||
startnormal0.y += ShapePoints[ j ].n.y;
|
||||
startvertex0 = parallel * ShapePoints[ j ].x + pos0;
|
||||
startvertex0.y += ShapePoints[ j ].y;
|
||||
startuv0 = ShapePoints[ j ].z;
|
||||
startnormal1 = ShapePoints[ j + 1 ].n.x * parallel;
|
||||
startnormal1.y += ShapePoints[ j + 1 ].n.y;
|
||||
startvertex1 = parallel * ShapePoints[ j + 1 ].x + pos0;
|
||||
startvertex1.y += ShapePoints[ j + 1 ].y;
|
||||
startuv1 = ShapePoints[ j + 1 ].z;
|
||||
|
||||
if( trapez == false ) {
|
||||
// single profile throughout
|
||||
endnormal0 = startnormal0;
|
||||
endvertex0 = startvertex0 + ( pos1 - pos0 );
|
||||
enduv0 = startuv0;
|
||||
endnormal1 = startnormal1;
|
||||
endvertex1 = startvertex1 + ( pos1 - pos0 );
|
||||
enduv1 = startuv1;
|
||||
}
|
||||
else {
|
||||
// end profile is different
|
||||
endnormal0 = ShapePoints[ j + iNumShapePoints ].n.x * parallel;
|
||||
endnormal0.y += ShapePoints[ j + iNumShapePoints ].n.y;
|
||||
endvertex0 = parallel * ShapePoints[ j + iNumShapePoints ].x + pos1; // odsunięcie
|
||||
endvertex0.y += ShapePoints[ j + iNumShapePoints ].y; // wysokość
|
||||
enduv0 = ShapePoints[ j + iNumShapePoints ].z;
|
||||
endnormal1 = ShapePoints[ j + iNumShapePoints + 1 ].n.x * parallel;
|
||||
endnormal1.y += ShapePoints[ j + iNumShapePoints + 1 ].n.y;
|
||||
endvertex1 = parallel * ShapePoints[ j + iNumShapePoints + 1 ].x + pos1; // odsunięcie
|
||||
endvertex1.y += ShapePoints[ j + iNumShapePoints + 1 ].y; // wysokość
|
||||
enduv1 = ShapePoints[ j + iNumShapePoints + 1 ].z;
|
||||
}
|
||||
// now build strips, lerping from start to endpoint
|
||||
step = 10.0; // arbitrary segment size for straights
|
||||
float s = 0.0,
|
||||
t = 0.0,
|
||||
uv = 0.0;
|
||||
glBegin( GL_TRIANGLE_STRIP );
|
||||
while( s < fLength ) {
|
||||
if( bRender ) {
|
||||
for( int j = 0; j < iNumShapePoints; ++j ) {
|
||||
//łuk z jednym profilem
|
||||
pt = parallel1 * ( ShapePoints[ j ].x - fOffsetX ) + pos1;
|
||||
pt.y += ShapePoints[ j ].y;
|
||||
pt -= Origin;
|
||||
norm = ShapePoints[ j ].n.x * parallel1;
|
||||
norm.y += ShapePoints[ j ].n.y;
|
||||
if( Output == nullptr ) {
|
||||
// immediate mode
|
||||
::glNormal3f( norm.x, norm.y, norm.z );
|
||||
::glTexCoord2f( ShapePoints[ j ].z / Texturescale, tv1 );
|
||||
::glVertex3f( pt.x, pt.y, pt.z ); // punkt na początku odcinka
|
||||
}
|
||||
else {
|
||||
Output->x = pt.x;
|
||||
Output->y = pt.y;
|
||||
Output->z = pt.z;
|
||||
Output->nx = norm.x;
|
||||
Output->ny = norm.y;
|
||||
Output->nz = norm.z;
|
||||
Output->u = ShapePoints[ j ].z / Texturescale;
|
||||
Output->v = tv1;
|
||||
++Output;
|
||||
}
|
||||
++vertexcount;
|
||||
|
||||
t = s / fLength;
|
||||
uv = s / fTextureLength;
|
||||
|
||||
auto const normal1lerp = Interpolate( startnormal1, endnormal1, t );
|
||||
glNormal3dv( &normal1lerp.x );
|
||||
auto const uv1lerp = Interpolate( startuv1, enduv1, t );
|
||||
glTexCoord2f( uv1lerp, uv );
|
||||
auto const vertex1lerp = Interpolate( startvertex1, endvertex1, t );
|
||||
glVertex3dv( &vertex1lerp.x );
|
||||
|
||||
auto const normal0lerp = Interpolate( startnormal0, endnormal0, t );
|
||||
glNormal3dv( &normal0lerp.x );
|
||||
auto const uv0lerp = Interpolate( startuv0, enduv0, t );
|
||||
glTexCoord2f( uv0lerp, uv );
|
||||
auto const vertex0lerp = Interpolate( startvertex0, endvertex0, t );
|
||||
glVertex3dv( &vertex0lerp.x );
|
||||
|
||||
s += step;
|
||||
}
|
||||
// add ending vertex pair if needed
|
||||
glNormal3dv( &endnormal1.x );
|
||||
glTexCoord2f( enduv1, fLength / fTextureLength );
|
||||
glVertex3dv( &endvertex1.x );
|
||||
glNormal3dv( &endnormal0.x );
|
||||
glTexCoord2f( enduv0, fLength / fTextureLength );
|
||||
glVertex3dv( &endvertex0.x );
|
||||
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
void TSegment::RenderSwitchRail(const vector6 *ShapePoints1, const vector6 *ShapePoints2,
|
||||
int iNumShapePoints, double fTextureLength, int iSkip,
|
||||
double fOffsetX)
|
||||
{ // tworzenie siatki trójkątów dla iglicy
|
||||
vector3 pos1, pos2, dir, parallel1, parallel2, pt;
|
||||
double a1, a2, s, step, offset, tv1, tv2, t, t2step, oldt2;
|
||||
int i, j;
|
||||
if (bCurve)
|
||||
{ // dla toru odchylonego
|
||||
// t2= 0;
|
||||
t2step = 1 / double(iSkip); // przesunięcie tekstury?
|
||||
oldt2 = 1;
|
||||
tv1 = 1.0;
|
||||
step = fStep; // długść segmentu
|
||||
s = 0;
|
||||
i = 0;
|
||||
t = fTsBuffer[i]; // wartość t krzywej Beziera dla początku
|
||||
a1 = 0;
|
||||
// step= fStep/fLength;
|
||||
offset = 0.1 / fLength; // około 10cm w sensie parametru t
|
||||
pos1 = FastGetPoint(t); // współrzędne dla parmatru t
|
||||
// dir= GetDirection1();
|
||||
dir = FastGetDirection(t, offset); // wektor wzdłużny
|
||||
// parallel1=Normalize(CrossProduct(dir,vector3(0,1,0))); //poprzeczny?
|
||||
parallel1 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
|
||||
while (s < fLength && i < iSkip)
|
||||
{
|
||||
// step= SquareMagnitude(Global::GetCameraPosition()+pos);
|
||||
// t2= oldt2+t2step;
|
||||
i++;
|
||||
s += step;
|
||||
|
||||
if (s > fLength)
|
||||
{
|
||||
step -= (s - fLength);
|
||||
s = fLength;
|
||||
}
|
||||
|
||||
while (tv1 < 0.0)
|
||||
tv1 += 1.0;
|
||||
tv2 = tv1 - step / fTextureLength;
|
||||
|
||||
t = fTsBuffer[i];
|
||||
pos2 = FastGetPoint(t);
|
||||
dir = FastGetDirection(t, offset);
|
||||
// parallel2=Normalize(CrossProduct(dir,vector3(0,1,0)));
|
||||
parallel2 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
|
||||
a2 = double(i) / (iSkip);
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{ // po dwa punkty trapezu
|
||||
pt = parallel1 *
|
||||
(ShapePoints1[j].x * a1 + (ShapePoints2[j].x - fOffsetX) * (1.0 - a1)) +
|
||||
pos1;
|
||||
pt.y += ShapePoints1[j].y * a1 + ShapePoints2[j].y * (1.0 - a1);
|
||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
||||
glTexCoord2f(ShapePoints1[j].z * a1 + ShapePoints2[j].z * (1.0 - a1), tv1);
|
||||
glVertex3f(pt.x, pt.y, pt.z);
|
||||
|
||||
pt = parallel2 *
|
||||
(ShapePoints1[j].x * a2 + (ShapePoints2[j].x - fOffsetX) * (1.0 - a2)) +
|
||||
pos2;
|
||||
pt.y += ShapePoints1[j].y * a2 + ShapePoints2[j].y * (1.0 - a2);
|
||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
||||
glTexCoord2f(ShapePoints1[j].z * a2 + ShapePoints2[j].z * (1.0 - a2), tv2);
|
||||
glVertex3f(pt.x, pt.y, pt.z);
|
||||
pt = parallel2 * ShapePoints[ j ].x + pos2;
|
||||
pt.y += ShapePoints[ j ].y;
|
||||
pt -= Origin;
|
||||
norm = ShapePoints[ j ].n.x * parallel2;
|
||||
norm.y += ShapePoints[ j ].n.y;
|
||||
if( Output == nullptr ) {
|
||||
// immediate mode
|
||||
::glNormal3f( norm.x, norm.y, norm.z );
|
||||
::glTexCoord2f( ShapePoints[ j ].z / Texturescale, tv2 );
|
||||
::glVertex3f( pt.x, pt.y, pt.z ); // punkt na końcu odcinka
|
||||
}
|
||||
else {
|
||||
Output->x = pt.x;
|
||||
Output->y = pt.y;
|
||||
Output->z = pt.z;
|
||||
Output->nx = norm.x;
|
||||
Output->ny = norm.y;
|
||||
Output->nz = norm.z;
|
||||
Output->u = ShapePoints[ j ].z / Texturescale;
|
||||
Output->v = tv2;
|
||||
++Output;
|
||||
}
|
||||
++vertexcount;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( Output == nullptr ) {
|
||||
// immediate mode
|
||||
glEnd();
|
||||
pos1 = pos2;
|
||||
parallel1 = parallel2;
|
||||
tv1 = tv2;
|
||||
a1 = a2;
|
||||
}
|
||||
pos1 = pos2;
|
||||
parallel1 = parallel2;
|
||||
tv1 = tv2;
|
||||
}
|
||||
else
|
||||
{ // dla toru prostego
|
||||
tv1 = 1.0;
|
||||
s = 0;
|
||||
i = 0;
|
||||
// pos1= FastGetPoint( (5*iSkip)/fLength );
|
||||
pos1 = FastGetPoint_0();
|
||||
dir = GetDirection();
|
||||
// parallel1=CrossProduct(dir,vector3(0,1,0));
|
||||
parallel1 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
|
||||
step = 5;
|
||||
a1 = 0;
|
||||
|
||||
while (i < iSkip)
|
||||
{
|
||||
// step= SquareMagnitude(Global::GetCameraPosition()+pos);
|
||||
i++;
|
||||
s += step;
|
||||
|
||||
if (s > fLength)
|
||||
{
|
||||
step -= (s - fLength);
|
||||
s = fLength;
|
||||
}
|
||||
|
||||
while (tv1 < 0.0)
|
||||
tv1 += 1.0;
|
||||
|
||||
tv2 = tv1 - step / fTextureLength;
|
||||
|
||||
t = s / fLength;
|
||||
pos2 = FastGetPoint(t);
|
||||
|
||||
a2 = double(i) / (iSkip);
|
||||
glBegin(GL_TRIANGLE_STRIP);
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{
|
||||
pt = parallel1 *
|
||||
(ShapePoints1[j].x * a1 + (ShapePoints2[j].x - fOffsetX) * (1.0 - a1)) +
|
||||
pos1;
|
||||
pt.y += ShapePoints1[j].y * a1 + ShapePoints2[j].y * (1.0 - a1);
|
||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
||||
glTexCoord2f((ShapePoints1[j].z), tv1);
|
||||
glVertex3f(pt.x, pt.y, pt.z);
|
||||
|
||||
pt = parallel1 *
|
||||
(ShapePoints1[j].x * a2 + (ShapePoints2[j].x - fOffsetX) * (1.0 - a2)) +
|
||||
pos2;
|
||||
pt.y += ShapePoints1[j].y * a2 + ShapePoints2[j].y * (1.0 - a2);
|
||||
glNormal3f(0.0f, 1.0f, 0.0f);
|
||||
glTexCoord2f(ShapePoints2[j].z, tv2);
|
||||
glVertex3f(pt.x, pt.y, pt.z);
|
||||
}
|
||||
glEnd();
|
||||
pos1 = pos2;
|
||||
tv1 = tv2;
|
||||
a1 = a2;
|
||||
}
|
||||
}
|
||||
return vertexcount;
|
||||
};
|
||||
|
||||
void TSegment::Render()
|
||||
@@ -778,300 +566,4 @@ void TSegment::Render()
|
||||
}
|
||||
}
|
||||
|
||||
void TSegment::RaRenderLoft(CVertNormTex *&Vert, const vector6 *ShapePoints, int iNumShapePoints,
|
||||
double fTextureLength, int iSkip, int iEnd, double fOffsetX)
|
||||
{ // generowanie trójkątów dla odcinka trajektorii ruchu
|
||||
// standardowo tworzy triangle_strip dla prostego albo ich zestaw dla łuku
|
||||
// po modyfikacji - dla ujemnego (iNumShapePoints) w dodatkowych polach tabeli
|
||||
// podany jest przekrój końcowy
|
||||
// podsypka toru jest robiona za pomocą 6 punktów, szyna 12, drogi i rzeki na 3+2+3
|
||||
// na użytek VBO strip dla łuków jest tworzony wzdłuż
|
||||
// dla skróconego odcinka (iEnd<iSegCount), ShapePoints dotyczy
|
||||
// końców skróconych, a nie całości (to pod kątem iglic jest)
|
||||
vector3 pos1, pos2, dir, parallel1, parallel2, pt, norm;
|
||||
double s, step, fOffset, tv1, tv2, t, fEnd;
|
||||
int i, j;
|
||||
bool trapez = iNumShapePoints < 0; // sygnalizacja trapezowatości
|
||||
iNumShapePoints = abs(iNumShapePoints);
|
||||
if (bCurve)
|
||||
{
|
||||
double m1, jmm1, m2, jmm2; // pozycje względne na odcinku 0...1 (ale nie parametr Beziera)
|
||||
step = fStep;
|
||||
tv1 = 1.0; // Ra: to by można było wyliczać dla odcinka, wyglądało by lepiej
|
||||
s = fStep * iSkip; // iSkip - ile odcinków z początku pominąć
|
||||
i = iSkip; // domyślnie 0
|
||||
t = fTsBuffer[i]; // tabela wattości t dla segmentów
|
||||
fOffset = 0.1 / fLength; // pierwsze 10cm
|
||||
pos1 = FastGetPoint(t); // wektor początku segmentu
|
||||
dir = FastGetDirection(t, fOffset); // wektor kierunku
|
||||
// parallel1=Normalize(CrossProduct(dir,vector3(0,1,0))); //wektor prostopadły
|
||||
parallel1 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
if (iEnd == 0)
|
||||
iEnd = iSegCount;
|
||||
fEnd = fLength * double(iEnd) / double(iSegCount);
|
||||
m2 = s / fEnd;
|
||||
jmm2 = 1.0 - m2;
|
||||
while (i < iEnd)
|
||||
{
|
||||
++i; // kolejny punkt łamanej
|
||||
s += step; // końcowa pozycja segmentu [m]
|
||||
m1 = m2;
|
||||
jmm1 = jmm2; // stara pozycja
|
||||
m2 = s / fEnd;
|
||||
jmm2 = 1.0 - m2; // nowa pozycja
|
||||
if (i == iEnd)
|
||||
{ // gdy przekroczyliśmy koniec - stąd dziury w torach...
|
||||
step -= (s - fEnd); // jeszcze do wyliczenia mapowania potrzebny
|
||||
s = fEnd;
|
||||
// i=iEnd; //20/5 ma dawać 4
|
||||
m2 = 1.0;
|
||||
jmm2 = 0.0;
|
||||
}
|
||||
while (tv1 < 0.0)
|
||||
tv1 += 1.0;
|
||||
tv2 = tv1 - step / fTextureLength; // mapowanie na końcu segmentu
|
||||
t = fTsBuffer[i]; // szybsze od GetTFromS(s);
|
||||
pos2 = FastGetPoint(t);
|
||||
dir = FastGetDirection(t, fOffset); // nowy wektor kierunku
|
||||
// parallel2=Normalize(CrossProduct(dir,vector3(0,1,0)));
|
||||
parallel2 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
if (trapez)
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{ // współrzędne początku
|
||||
norm = (jmm1 * ShapePoints[j].n.x + m1 * ShapePoints[j + iNumShapePoints].n.x) *
|
||||
parallel1;
|
||||
norm.y += jmm1 * ShapePoints[j].n.y + m1 * ShapePoints[j + iNumShapePoints].n.y;
|
||||
pt = parallel1 * (jmm1 * (ShapePoints[j].x - fOffsetX) +
|
||||
m1 * ShapePoints[j + iNumShapePoints].x) +
|
||||
pos1;
|
||||
pt.y += jmm1 * ShapePoints[j].y + m1 * ShapePoints[j + iNumShapePoints].y;
|
||||
Vert->nx = norm.x; // niekoniecznie tak
|
||||
Vert->ny = norm.y;
|
||||
Vert->nz = norm.z;
|
||||
Vert->u = jmm1 * ShapePoints[j].z + m1 * ShapePoints[j + iNumShapePoints].z;
|
||||
Vert->v = tv1;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na początku odcinka
|
||||
Vert++;
|
||||
// dla trapezu drugi koniec ma inne współrzędne względne
|
||||
norm = (jmm1 * ShapePoints[j].n.x + m1 * ShapePoints[j + iNumShapePoints].n.x) *
|
||||
parallel2;
|
||||
norm.y += jmm1 * ShapePoints[j].n.y + m1 * ShapePoints[j + iNumShapePoints].n.y;
|
||||
pt = parallel2 * (jmm2 * (ShapePoints[j].x - fOffsetX) +
|
||||
m2 * ShapePoints[j + iNumShapePoints].x) +
|
||||
pos2;
|
||||
pt.y += jmm2 * ShapePoints[j].y + m2 * ShapePoints[j + iNumShapePoints].y;
|
||||
Vert->nx = norm.x; // niekoniecznie tak
|
||||
Vert->ny = norm.y;
|
||||
Vert->nz = norm.z;
|
||||
Vert->u = jmm2 * ShapePoints[j].z + m2 * ShapePoints[j + iNumShapePoints].z;
|
||||
Vert->v = tv2;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na końcu odcinka
|
||||
Vert++;
|
||||
}
|
||||
else
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{ // współrzędne początku
|
||||
norm = ShapePoints[j].n.x * parallel1;
|
||||
norm.y += ShapePoints[j].n.y;
|
||||
pt = parallel1 * (ShapePoints[j].x - fOffsetX) + pos1;
|
||||
pt.y += ShapePoints[j].y;
|
||||
Vert->nx = norm.x; // niekoniecznie tak
|
||||
Vert->ny = norm.y;
|
||||
Vert->nz = norm.z;
|
||||
Vert->u = ShapePoints[j].z;
|
||||
Vert->v = tv1;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na początku odcinka
|
||||
Vert++;
|
||||
norm = ShapePoints[j].n.x * parallel2;
|
||||
norm.y += ShapePoints[j].n.y;
|
||||
pt = parallel2 * ShapePoints[j].x + pos2;
|
||||
pt.y += ShapePoints[j].y;
|
||||
Vert->nx = norm.x; // niekoniecznie tak
|
||||
Vert->ny = norm.y;
|
||||
Vert->nz = norm.z;
|
||||
Vert->u = ShapePoints[j].z;
|
||||
Vert->v = tv2;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na końcu odcinka
|
||||
Vert++;
|
||||
}
|
||||
pos1 = pos2;
|
||||
parallel1 = parallel2;
|
||||
tv1 = tv2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // gdy prosty
|
||||
pos1 = FastGetPoint((fStep * iSkip) / fLength);
|
||||
pos2 = FastGetPoint_1();
|
||||
dir = GetDirection();
|
||||
// parallel1=Normalize(CrossProduct(dir,vector3(0,1,0)));
|
||||
parallel1 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
if (trapez)
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{
|
||||
norm = ShapePoints[j].n.x * parallel1;
|
||||
norm.y += ShapePoints[j].n.y;
|
||||
pt = parallel1 * (ShapePoints[j].x - fOffsetX) + pos1;
|
||||
pt.y += ShapePoints[j].y;
|
||||
Vert->nx = norm.x; // niekoniecznie tak
|
||||
Vert->ny = norm.y;
|
||||
Vert->nz = norm.z;
|
||||
Vert->u = ShapePoints[j].z;
|
||||
Vert->v = 0;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na początku odcinka
|
||||
Vert++;
|
||||
// dla trapezu drugi koniec ma inne współrzędne
|
||||
norm = ShapePoints[j + iNumShapePoints].n.x * parallel1;
|
||||
norm.y += ShapePoints[j + iNumShapePoints].n.y;
|
||||
pt = parallel1 * (ShapePoints[j + iNumShapePoints].x - fOffsetX) +
|
||||
pos2; // odsunięcie
|
||||
pt.y += ShapePoints[j + iNumShapePoints].y; // wysokość
|
||||
Vert->nx = norm.x; // niekoniecznie tak
|
||||
Vert->ny = norm.y;
|
||||
Vert->nz = norm.z;
|
||||
Vert->u = ShapePoints[j + iNumShapePoints].z;
|
||||
Vert->v = fLength / fTextureLength;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na końcu odcinka
|
||||
Vert++;
|
||||
}
|
||||
else
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{
|
||||
norm = ShapePoints[j].n.x * parallel1;
|
||||
norm.y += ShapePoints[j].n.y;
|
||||
pt = parallel1 * (ShapePoints[j].x - fOffsetX) + pos1;
|
||||
pt.y += ShapePoints[j].y;
|
||||
Vert->nx = norm.x; // niekoniecznie tak
|
||||
Vert->ny = norm.y;
|
||||
Vert->nz = norm.z;
|
||||
Vert->u = ShapePoints[j].z;
|
||||
Vert->v = 0;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na początku odcinka
|
||||
Vert++;
|
||||
pt = parallel1 * (ShapePoints[j].x - fOffsetX) + pos2;
|
||||
pt.y += ShapePoints[j].y;
|
||||
Vert->nx = norm.x; // niekoniecznie tak
|
||||
Vert->ny = norm.y;
|
||||
Vert->nz = norm.z;
|
||||
Vert->u = ShapePoints[j].z;
|
||||
Vert->v = fLength / fTextureLength;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na końcu odcinka
|
||||
Vert++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void TSegment::RaAnimate(CVertNormTex *&Vert, const vector6 *ShapePoints, int iNumShapePoints,
|
||||
double fTextureLength, int iSkip, int iEnd, double fOffsetX)
|
||||
{ // jak wyżej, tylko z pominięciem mapowania i braku trapezowania
|
||||
vector3 pos1, pos2, dir, parallel1, parallel2, pt;
|
||||
double s, step, fOffset, t, fEnd;
|
||||
int i, j;
|
||||
bool trapez = iNumShapePoints < 0; // sygnalizacja trapezowatości
|
||||
iNumShapePoints = abs(iNumShapePoints);
|
||||
if (bCurve)
|
||||
{
|
||||
double m1, jmm1, m2, jmm2; // pozycje względne na odcinku 0...1 (ale nie parametr Beziera)
|
||||
step = fStep;
|
||||
s = fStep * iSkip; // iSkip - ile odcinków z początku pominąć
|
||||
i = iSkip; // domyślnie 0
|
||||
t = fTsBuffer[i]; // tabela wattości t dla segmentów
|
||||
fOffset = 0.1 / fLength; // pierwsze 10cm
|
||||
pos1 = FastGetPoint(t); // wektor początku segmentu
|
||||
dir = FastGetDirection(t, fOffset); // wektor kierunku
|
||||
// parallel1=Normalize(CrossProduct(dir,vector3(0,1,0))); //wektor prostopadły
|
||||
parallel1 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
if (iEnd == 0)
|
||||
iEnd = iSegCount;
|
||||
fEnd = fLength * double(iEnd) / double(iSegCount);
|
||||
m2 = s / fEnd;
|
||||
jmm2 = 1.0 - m2;
|
||||
while (i < iEnd)
|
||||
{
|
||||
++i; // kolejny punkt łamanej
|
||||
s += step; // końcowa pozycja segmentu [m]
|
||||
m1 = m2;
|
||||
jmm1 = jmm2; // stara pozycja
|
||||
m2 = s / fEnd;
|
||||
jmm2 = 1.0 - m2; // nowa pozycja
|
||||
if (i == iEnd)
|
||||
{ // gdy przekroczyliśmy koniec - stąd dziury w torach...
|
||||
step -= (s - fEnd); // jeszcze do wyliczenia mapowania potrzebny
|
||||
s = fEnd;
|
||||
// i=iEnd; //20/5 ma dawać 4
|
||||
m2 = 1.0;
|
||||
jmm2 = 0.0;
|
||||
}
|
||||
t = fTsBuffer[i]; // szybsze od GetTFromS(s);
|
||||
pos2 = FastGetPoint(t);
|
||||
dir = FastGetDirection(t, fOffset); // nowy wektor kierunku
|
||||
// parallel2=Normalize(CrossProduct(dir,vector3(0,1,0)));
|
||||
parallel2 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
if (trapez)
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{ // współrzędne początku
|
||||
pt = parallel1 * (jmm1 * (ShapePoints[j].x - fOffsetX) +
|
||||
m1 * ShapePoints[j + iNumShapePoints].x) +
|
||||
pos1;
|
||||
pt.y += jmm1 * ShapePoints[j].y + m1 * ShapePoints[j + iNumShapePoints].y;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na początku odcinka
|
||||
Vert++;
|
||||
// dla trapezu drugi koniec ma inne współrzędne
|
||||
pt = parallel2 * (jmm2 * (ShapePoints[j].x - fOffsetX) +
|
||||
m2 * ShapePoints[j + iNumShapePoints].x) +
|
||||
pos2;
|
||||
pt.y += jmm2 * ShapePoints[j].y + m2 * ShapePoints[j + iNumShapePoints].y;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na końcu odcinka
|
||||
Vert++;
|
||||
}
|
||||
pos1 = pos2;
|
||||
parallel1 = parallel2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // gdy prosty
|
||||
pos1 = FastGetPoint((fStep * iSkip) / fLength);
|
||||
pos2 = FastGetPoint_1();
|
||||
dir = GetDirection();
|
||||
// parallel1=Normalize(CrossProduct(dir,vector3(0,1,0)));
|
||||
parallel1 = Normalize(vector3(-dir.z, 0.0, dir.x)); // wektor poprzeczny
|
||||
if (trapez)
|
||||
for (j = 0; j < iNumShapePoints; j++)
|
||||
{
|
||||
pt = parallel1 * (ShapePoints[j].x - fOffsetX) + pos1;
|
||||
pt.y += ShapePoints[j].y;
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na początku odcinka
|
||||
Vert++;
|
||||
pt = parallel1 * (ShapePoints[j + iNumShapePoints].x - fOffsetX) +
|
||||
pos2; // odsunięcie
|
||||
pt.y += ShapePoints[j + iNumShapePoints].y; // wysokość
|
||||
Vert->x = pt.x;
|
||||
Vert->y = pt.y;
|
||||
Vert->z = pt.z; // punkt na końcu odcinka
|
||||
Vert++;
|
||||
}
|
||||
}
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
23
Segment.h
23
Segment.h
@@ -13,6 +13,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "VBO.h"
|
||||
#include "dumb3d.h"
|
||||
#include "Classes.h"
|
||||
#include "usefull.h"
|
||||
|
||||
using namespace Math3D;
|
||||
|
||||
@@ -61,8 +62,6 @@ class TSegment
|
||||
double fDirection = 0.0; // Ra: kąt prostego w planie; dla łuku kąt od Point1
|
||||
double fStoop = 0.0; // Ra: kąt wzniesienia; dla łuku od Point1
|
||||
vector3 vA, vB, vC; // współczynniki wielomianów trzeciego stopnia vD==Point1
|
||||
// TSegment *pPrev; //odcinek od strony punktu 1 - w segmencie, żeby nie skakać na zwrotnicach
|
||||
// TSegment *pNext; //odcinek od strony punktu 2
|
||||
TTrack *pOwner = nullptr; // wskaźnik na właściciela
|
||||
double fAngle[2]; // kąty zakończenia drogi na przejazdach
|
||||
|
||||
@@ -71,12 +70,8 @@ class TSegment
|
||||
double GetTFromS(double s);
|
||||
vector3 RaInterpolate(double t);
|
||||
vector3 RaInterpolate0(double t);
|
||||
// TSegment *segNeightbour[2]; //sąsiednie odcinki - musi być przeniesione z Track
|
||||
// int iNeightbour[2]; //do którego końca doczepiony
|
||||
public:
|
||||
bool bCurve = false;
|
||||
// int iShape; //Ra: flagi kształtu dadzą więcej możliwości optymalizacji
|
||||
// (0-Bezier,1-prosty,2/3-łuk w lewo/prawo,6/7-przejściowa w lewo/prawo)
|
||||
TSegment(TTrack *owner);
|
||||
~TSegment();
|
||||
bool Init(vector3 NewPoint1, vector3 NewPoint2, double fNewStep, double fNewRoll1 = 0,
|
||||
@@ -109,21 +104,16 @@ class TSegment
|
||||
{
|
||||
return Point2;
|
||||
};
|
||||
inline double GetRoll(double s)
|
||||
inline double GetRoll(double const Distance)
|
||||
{
|
||||
s /= fLength;
|
||||
return ((1.0 - s) * fRoll1 + s * fRoll2);
|
||||
return interpolate( fRoll1, fRoll2, Distance / fLength );
|
||||
}
|
||||
void GetRolls(double &r1, double &r2)
|
||||
{ // pobranie przechyłek (do generowania trójkątów)
|
||||
r1 = fRoll1;
|
||||
r2 = fRoll2;
|
||||
}
|
||||
void RenderLoft(const vector6 *ShapePoints, int iNumShapePoints, double fTextureLength,
|
||||
int iSkip = 0, int iQualityFactor = 1, vector3 **p = NULL, bool bRender = true);
|
||||
void RenderSwitchRail(const vector6 *ShapePoints1, const vector6 *ShapePoints2,
|
||||
int iNumShapePoints, double fTextureLength, int iSkip = 0,
|
||||
double fOffsetX = 0.0f);
|
||||
int RenderLoft( CVertNormTex* &Output, Math3D::vector3 const &Origin, vector6 const *ShapePoints, int iNumShapePoints, double fTextureLength, double Texturescale = 1.0, int iSkip = 0, int iEnd = 0, double fOffsetX = 0.0, vector3 **p = nullptr, bool bRender = true);
|
||||
void Render();
|
||||
inline double GetLength()
|
||||
{
|
||||
@@ -145,15 +135,10 @@ class TSegment
|
||||
return 1;
|
||||
return iSegCount;
|
||||
};
|
||||
void RaRenderLoft(CVertNormTex *&Vert, const vector6 *ShapePoints, int iNumShapePoints,
|
||||
double fTextureLength, int iSkip = 0, int iEnd = 0, double fOffsetX = 0.0);
|
||||
void RaAnimate(CVertNormTex *&Vert, const vector6 *ShapePoints, int iNumShapePoints,
|
||||
double fTextureLength, int iSkip = 0, int iEnd = 0, double fOffsetX = 0.0);
|
||||
void AngleSet(int i, double a)
|
||||
{
|
||||
fAngle[i] = a;
|
||||
};
|
||||
void Rollment(double w1, double w2); // poprawianie przechyłki
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
116
Sound.cpp
116
Sound.cpp
@@ -14,7 +14,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "Usefull.h"
|
||||
#include "mczapkie/mctools.h"
|
||||
#include "WavRead.h"
|
||||
//#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
|
||||
|
||||
#define SAFE_RELEASE(p) \
|
||||
{ \
|
||||
if (p) \
|
||||
@@ -24,43 +24,31 @@ http://mozilla.org/MPL/2.0/.
|
||||
} \
|
||||
}
|
||||
|
||||
char Directory[] = "sounds\\";
|
||||
|
||||
LPDIRECTSOUND TSoundsManager::pDS;
|
||||
LPDIRECTSOUNDNOTIFY TSoundsManager::pDSNotify;
|
||||
|
||||
int TSoundsManager::Count = 0;
|
||||
TSoundContainer *TSoundsManager::First = NULL;
|
||||
|
||||
TSoundContainer::TSoundContainer(LPDIRECTSOUND pDS, const char *Directory, const char *strFileName,
|
||||
int NConcurrent)
|
||||
TSoundContainer::TSoundContainer(LPDIRECTSOUND pDS, std::string const &Directory, std::string const &Filename, int NConcurrent)
|
||||
{ // wczytanie pliku dźwiękowego
|
||||
int hr = 111;
|
||||
DSBuffer = NULL; // na początek, gdyby uruchomić dźwięków się nie udało
|
||||
|
||||
DSBuffer = nullptr; // na początek, gdyby uruchomić dźwięków się nie udało
|
||||
Concurrent = NConcurrent;
|
||||
|
||||
Oldest = 0;
|
||||
// strcpy(Name, strFileName);
|
||||
|
||||
strcpy(Name, Directory);
|
||||
strcat(Name, strFileName);
|
||||
|
||||
CWaveSoundRead *pWaveSoundRead;
|
||||
m_name = Directory + Filename;
|
||||
|
||||
// Create a new wave file class
|
||||
pWaveSoundRead = new CWaveSoundRead();
|
||||
std::shared_ptr<CWaveSoundRead> pWaveSoundRead = std::make_shared<CWaveSoundRead>();
|
||||
|
||||
// Load the wave file
|
||||
if (FAILED(pWaveSoundRead->Open(Name)))
|
||||
if (FAILED(pWaveSoundRead->Open(strdup(strFileName))))
|
||||
{
|
||||
// SetFileUI( hDlg, TEXT("Bad wave file.") );
|
||||
ErrorLog( "Missed sound: " + std::string( strFileName ) );
|
||||
return;
|
||||
}
|
||||
if( ( FAILED( pWaveSoundRead->Open( m_name ) ) )
|
||||
&& ( FAILED( pWaveSoundRead->Open( Filename ) ) ) ) {
|
||||
ErrorLog( "Missed sound: " + Filename );
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(Name, ToLower(strFileName).c_str());
|
||||
m_name = ToLower( Filename );
|
||||
|
||||
// Set up the direct sound buffer, and only request the flags needed
|
||||
// since each requires some overhead and limits if the buffer can
|
||||
@@ -133,27 +121,10 @@ TSoundContainer::TSoundContainer(LPDIRECTSOUND pDS, const char *Directory, const
|
||||
// We dont need the wav file data buffer anymore, so delete it
|
||||
delete[] pbWavData;
|
||||
|
||||
delete pWaveSoundRead;
|
||||
|
||||
DSBuffers.push(DSBuffer);
|
||||
|
||||
/*
|
||||
for (int i=1; i<Concurrent; i++)
|
||||
{
|
||||
if( FAILED( hr= pDS->DuplicateSoundBuffer(pDSBuffer[0],&(pDSBuffer[i]))))
|
||||
{
|
||||
Concurrent= i;
|
||||
break;
|
||||
};
|
||||
|
||||
|
||||
};*/
|
||||
};
|
||||
TSoundContainer::~TSoundContainer()
|
||||
{
|
||||
// for (int i=Concurrent-1; i>=0; i--)
|
||||
// SAFE_RELEASE( pDSBuffer[i] );
|
||||
// free(pDSBuffer);
|
||||
while (!DSBuffers.empty())
|
||||
{
|
||||
SAFE_RELEASE(DSBuffers.top());
|
||||
@@ -185,84 +156,51 @@ void TSoundsManager::Free()
|
||||
SAFE_RELEASE(pDS);
|
||||
};
|
||||
|
||||
TSoundContainer * TSoundsManager::LoadFromFile(const char *Dir, const char *Name, int Concurrent)
|
||||
TSoundContainer * TSoundsManager::LoadFromFile( std::string const &Dir, std::string const &Filename, int Concurrent)
|
||||
{
|
||||
TSoundContainer *Tmp = First;
|
||||
First = new TSoundContainer(pDS, Dir, Name, Concurrent);
|
||||
First->Next = Tmp;
|
||||
TSoundContainer *tmp = First;
|
||||
First = new TSoundContainer(pDS, Dir, Filename, Concurrent);
|
||||
First->Next = tmp;
|
||||
Count++;
|
||||
return First; // albo NULL, jak nie wyjdzie (na razie zawsze wychodzi)
|
||||
};
|
||||
|
||||
void TSoundsManager::LoadSounds(char *Directory)
|
||||
{ // wczytanie wszystkich plików z katalogu - mało elastyczne
|
||||
WIN32_FIND_DATA FindFileData;
|
||||
HANDLE handle = FindFirstFile("sounds\\*.wav", &FindFileData);
|
||||
if (handle != INVALID_HANDLE_VALUE)
|
||||
do
|
||||
{
|
||||
LoadFromFile(Directory, FindFileData.cFileName, 1);
|
||||
} while (FindNextFile(handle, &FindFileData));
|
||||
FindClose(handle);
|
||||
};
|
||||
|
||||
LPDIRECTSOUNDBUFFER TSoundsManager::GetFromName(const char *Name, bool Dynamic, float *fSamplingRate)
|
||||
LPDIRECTSOUNDBUFFER TSoundsManager::GetFromName(std::string const &Name, bool Dynamic, float *fSamplingRate)
|
||||
{ // wyszukanie dźwięku w pamięci albo wczytanie z pliku
|
||||
std::string name{ ToLower(Name) };
|
||||
std::string file;
|
||||
if (Dynamic)
|
||||
{ // próba wczytania z katalogu pojazdu
|
||||
file = Global::asCurrentDynamicPath + Name;
|
||||
file = Global::asCurrentDynamicPath + name;
|
||||
if (FileExists(file))
|
||||
Name = file.c_str(); // nowa nazwa
|
||||
name = file; // nowa nazwa
|
||||
else
|
||||
Dynamic = false; // wczytanie z "sounds/"
|
||||
}
|
||||
TSoundContainer *Next = First;
|
||||
for (int i = 0; i < Count; i++)
|
||||
{
|
||||
if (strcmp(Name, Next->Name) == 0)
|
||||
{
|
||||
if( name == Next->m_name ) {
|
||||
|
||||
if (fSamplingRate)
|
||||
*fSamplingRate = Next->fSamplingRate; // częstotliwość
|
||||
return (Next->GetUnique(pDS));
|
||||
// DSBuffers.
|
||||
/*
|
||||
Next->pDSBuffer[Next->Oldest]->Stop();
|
||||
Next->pDSBuffer[Next->Oldest]->SetCurrentPosition(0);
|
||||
if (Next->Oldest<Next->Concurrent-1)
|
||||
{
|
||||
Next->Oldest++;
|
||||
return (Next->pDSBuffer[Next->Oldest-1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Next->Oldest= 0;
|
||||
return (Next->pDSBuffer[Next->Concurrent-1]);
|
||||
};
|
||||
|
||||
/* for (int j=0; j<Next->Concurrent; j++)
|
||||
{
|
||||
|
||||
Next->pDSBuffer[j]->GetStatus(&dwStatus);
|
||||
if ((dwStatus & DSBSTATUS_PLAYING) != DSBSTATUS_PLAYING)
|
||||
return (Next->pDSBuffer[j]);
|
||||
} */
|
||||
}
|
||||
else
|
||||
Next = Next->Next;
|
||||
};
|
||||
if (Dynamic) // wczytanie z katalogu pojazdu
|
||||
Next = LoadFromFile("", Name, 1);
|
||||
Next = LoadFromFile("", name, 1);
|
||||
else
|
||||
Next = LoadFromFile(Directory, Name, 1);
|
||||
Next = LoadFromFile(szSoundPath, name, 1);
|
||||
if (Next)
|
||||
{ //
|
||||
if (fSamplingRate)
|
||||
*fSamplingRate = Next->fSamplingRate; // częstotliwość
|
||||
return Next->GetUnique(pDS);
|
||||
}
|
||||
ErrorLog("Missed sound: " + std::string(Name) );
|
||||
return (NULL);
|
||||
ErrorLog("Missed sound: " + Name );
|
||||
return (nullptr);
|
||||
};
|
||||
|
||||
void TSoundsManager::RestoreAll()
|
||||
@@ -299,10 +237,6 @@ void TSoundsManager::RestoreAll()
|
||||
};
|
||||
};
|
||||
|
||||
// void TSoundsManager::Init(char *Name, int Concurrent)
|
||||
// TSoundsManager::TSoundsManager(HWND hWnd)
|
||||
// void TSoundsManager::Init(HWND hWnd, char *NDirectory)
|
||||
|
||||
void TSoundsManager::Init(HWND hWnd)
|
||||
{
|
||||
|
||||
|
||||
38
Sound.h
38
Sound.h
@@ -7,56 +7,44 @@ obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
#ifndef SoundH
|
||||
#define SoundH
|
||||
#pragma once
|
||||
|
||||
#include <stack>
|
||||
#include <dsound.h>
|
||||
|
||||
typedef LPDIRECTSOUNDBUFFER PSound;
|
||||
|
||||
// inline Playing(PSound Sound)
|
||||
//{
|
||||
|
||||
//}
|
||||
|
||||
class TSoundContainer
|
||||
{
|
||||
public:
|
||||
public:
|
||||
int Concurrent;
|
||||
int Oldest;
|
||||
char Name[80];
|
||||
std::string m_name;
|
||||
LPDIRECTSOUNDBUFFER DSBuffer;
|
||||
float fSamplingRate; // częstotliwość odczytana z pliku
|
||||
int iBitsPerSample; // ile bitów na próbkę
|
||||
TSoundContainer *Next;
|
||||
std::stack<LPDIRECTSOUNDBUFFER> DSBuffers;
|
||||
LPDIRECTSOUNDBUFFER GetUnique(LPDIRECTSOUND pDS);
|
||||
TSoundContainer(LPDIRECTSOUND pDS, const char *Directory, const char *strFileName, int NConcurrent);
|
||||
|
||||
TSoundContainer(LPDIRECTSOUND pDS, std::string const &Directory, std::string const &Filename, int NConcurrent);
|
||||
~TSoundContainer();
|
||||
LPDIRECTSOUNDBUFFER GetUnique( LPDIRECTSOUND pDS );
|
||||
};
|
||||
|
||||
class TSoundsManager
|
||||
{
|
||||
private:
|
||||
private:
|
||||
static LPDIRECTSOUND pDS;
|
||||
static LPDIRECTSOUNDNOTIFY pDSNotify;
|
||||
// static char Directory[80];
|
||||
static int Count;
|
||||
static TSoundContainer *First;
|
||||
static TSoundContainer * LoadFromFile(const char *Dir, const char *Name, int Concurrent);
|
||||
static int Count;
|
||||
|
||||
public:
|
||||
// TSoundsManager(HWND hWnd);
|
||||
// static void Init(HWND hWnd, char *NDirectory);
|
||||
static void Init(HWND hWnd);
|
||||
static TSoundContainer * LoadFromFile( std::string const &Directory, std::string const &FileName, int Concurrent);
|
||||
|
||||
public:
|
||||
~TSoundsManager();
|
||||
static void Init( HWND hWnd );
|
||||
static void Free();
|
||||
static void Init(char *Name, int Concurrent);
|
||||
static void LoadSounds(char *Directory);
|
||||
static LPDIRECTSOUNDBUFFER GetFromName(const char *Name, bool Dynamic, float *fSamplingRate = NULL);
|
||||
static LPDIRECTSOUNDBUFFER GetFromName( std::string const &Name, bool Dynamic, float *fSamplingRate = NULL );
|
||||
static void RestoreAll();
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
||||
|
||||
@@ -424,7 +424,6 @@ opengl_texture::load_TGA() {
|
||||
else if( tgaheader[ 2 ] == 10 ) {
|
||||
// compressed TGA
|
||||
int currentpixel = 0;
|
||||
int currentbyte = 0;
|
||||
|
||||
unsigned char buffer[ 4 ] = { 255, 255, 255, 255 };
|
||||
const int pixelcount = data_width * data_height;
|
||||
|
||||
4
Track.h
4
Track.h
@@ -240,7 +240,7 @@ class TTrack : public Resource
|
||||
|
||||
void Render(); // renderowanie z Display Lists
|
||||
int RaArrayPrepare(); // zliczanie rozmiaru dla VBO sektroa
|
||||
void RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start); // wypełnianie VBO
|
||||
void RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int const Vertexcount); // wypełnianie VBO
|
||||
void RaRenderVBO(int iPtr); // renderowanie z VBO sektora
|
||||
void RenderDyn(); // renderowanie nieprzezroczystych pojazdów (oba tryby)
|
||||
void RenderDynAlpha(); // renderowanie przezroczystych pojazdów (oba tryby)
|
||||
@@ -256,7 +256,7 @@ class TTrack : public Resource
|
||||
void RaAssign(TGroundNode *gn, TAnimContainer *ac);
|
||||
void RaAssign(TGroundNode *gn, TAnimModel *am, TEvent *done, TEvent *joined);
|
||||
void RaAnimListAdd(TTrack *t);
|
||||
TTrack * RaAnimate();
|
||||
TTrack * RaAnimate(GLuint const Vertexbuffer = -1);
|
||||
|
||||
void RadioStop();
|
||||
void AxleCounter(int i, TDynamicObject *o)
|
||||
|
||||
721
Traction.cpp
721
Traction.cpp
@@ -108,9 +108,160 @@ TTraction::~TTraction()
|
||||
|
||||
}
|
||||
|
||||
void TTraction::Optimize()
|
||||
void TTraction::Optimize( Math3D::vector3 const &Origin )
|
||||
{
|
||||
|
||||
if (Wires != 0)
|
||||
{
|
||||
// Dlugosc odcinka trakcji 'Winger
|
||||
double ddp = std::hypot(pPoint2.x - pPoint1.x, pPoint2.z - pPoint1.z);
|
||||
if (Wires == 2)
|
||||
WireOffset = 0;
|
||||
// Przewoz jezdny 1 'Marcin
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(
|
||||
pPoint1.x - (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset - Origin.x,
|
||||
pPoint1.y - Origin.y,
|
||||
pPoint1.z - (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset - Origin.z);
|
||||
glVertex3f(
|
||||
pPoint2.x - (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset - Origin.x,
|
||||
pPoint2.y - Origin.y,
|
||||
pPoint2.z - (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset - Origin.z );
|
||||
glEnd();
|
||||
// Nie wiem co 'Marcin
|
||||
Math3D::vector3 pt1, pt2, pt3, pt4, v1, v2;
|
||||
v1 = pPoint4 - pPoint3;
|
||||
v2 = pPoint2 - pPoint1;
|
||||
float step = 0;
|
||||
if (iNumSections > 0)
|
||||
step = 1.0f / (float)iNumSections;
|
||||
float f = step;
|
||||
float mid = 0.5;
|
||||
float t;
|
||||
// Przewod nosny 'Marcin
|
||||
if (Wires > 1)
|
||||
{
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(
|
||||
pPoint3.x - Origin.x,
|
||||
pPoint3.y - Origin.y,
|
||||
pPoint3.z - Origin.z );
|
||||
for (int i = 0; i < iNumSections - 1; ++i)
|
||||
{
|
||||
pt3 = pPoint3 + v1 * f;
|
||||
t = (1 - std::fabs(f - mid) * 2);
|
||||
if ((Wires < 4) || ((i != 0) && (i != iNumSections - 2)))
|
||||
glVertex3f(
|
||||
pt3.x - Origin.x,
|
||||
pt3.y - std::sqrt(t) * fHeightDifference - Origin.y,
|
||||
pt3.z - Origin.z );
|
||||
f += step;
|
||||
}
|
||||
glVertex3f(
|
||||
pPoint4.x - Origin.x,
|
||||
pPoint4.y - Origin.y,
|
||||
pPoint4.z - Origin.z );
|
||||
glEnd();
|
||||
}
|
||||
// Drugi przewod jezdny 'Winger
|
||||
if (Wires > 2)
|
||||
{
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(
|
||||
pPoint1.x + (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset - Origin.x,
|
||||
pPoint1.y - Origin.y,
|
||||
pPoint1.z + (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset - Origin.z );
|
||||
glVertex3f(
|
||||
pPoint2.x + (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset - Origin.x,
|
||||
pPoint2.y - Origin.y,
|
||||
pPoint2.z + (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset - Origin.z );
|
||||
glEnd();
|
||||
}
|
||||
|
||||
f = step;
|
||||
|
||||
if (Wires == 4)
|
||||
{
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(
|
||||
pPoint3.x - Origin.x,
|
||||
pPoint3.y - 0.65f * fHeightDifference - Origin.y,
|
||||
pPoint3.z - Origin.z );
|
||||
for (int i = 0; i < iNumSections - 1; ++i)
|
||||
{
|
||||
pt3 = pPoint3 + v1 * f;
|
||||
t = (1 - std::fabs(f - mid) * 2);
|
||||
glVertex3f(
|
||||
pt3.x - Origin.x,
|
||||
pt3.y - std::sqrt( t ) * fHeightDifference - (
|
||||
( ( i == 0 )
|
||||
|| ( i == iNumSections - 2 ) ) ?
|
||||
0.25f * fHeightDifference :
|
||||
0.05 )
|
||||
- Origin.y,
|
||||
pt3.z - Origin.z );
|
||||
f += step;
|
||||
}
|
||||
glVertex3f(
|
||||
pPoint4.x - Origin.x,
|
||||
pPoint4.y - 0.65f * fHeightDifference - Origin.y,
|
||||
pPoint4.z - Origin.z );
|
||||
glEnd();
|
||||
}
|
||||
|
||||
f = step;
|
||||
|
||||
// Przewody pionowe (wieszaki) 'Marcin, poprawki na 2 przewody jezdne 'Winger
|
||||
if (Wires != 1)
|
||||
{
|
||||
glBegin(GL_LINES);
|
||||
for (int i = 0; i < iNumSections - 1; ++i)
|
||||
{
|
||||
float flo, flo1;
|
||||
flo = (Wires == 4 ? 0.25f * fHeightDifference : 0);
|
||||
flo1 = (Wires == 4 ? +0.05 : 0);
|
||||
pt3 = pPoint3 + v1 * f;
|
||||
pt4 = pPoint1 + v2 * f;
|
||||
t = (1 - std::fabs(f - mid) * 2);
|
||||
if ((i % 2) == 0)
|
||||
{
|
||||
glVertex3f(
|
||||
pt3.x - Origin.x,
|
||||
pt3.y - std::sqrt(t) * fHeightDifference - ((i == 0) || (i == iNumSections - 2) ? flo : flo1) - Origin.y,
|
||||
pt3.z - Origin.z );
|
||||
glVertex3f(
|
||||
pt4.x - (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset - Origin.x,
|
||||
pt4.y - Origin.y,
|
||||
pt4.z - (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset - Origin.z );
|
||||
}
|
||||
else
|
||||
{
|
||||
glVertex3f(
|
||||
pt3.x - Origin.x,
|
||||
pt3.y - std::sqrt(t) * fHeightDifference - ((i == 0) || (i == iNumSections - 2) ? flo : flo1) - Origin.y,
|
||||
pt3.z - Origin.z );
|
||||
glVertex3f(
|
||||
pt4.x + (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset - Origin.x,
|
||||
pt4.y - Origin.y,
|
||||
pt4.z + (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset - Origin.z );
|
||||
}
|
||||
if ((Wires == 4) && ((i == 1) || (i == iNumSections - 3)))
|
||||
{
|
||||
glVertex3f(
|
||||
pt3.x - Origin.x,
|
||||
pt3.y - std::sqrt(t) * fHeightDifference - 0.05 - Origin.y,
|
||||
pt3.z - Origin.z );
|
||||
glVertex3f(
|
||||
pt3.x - Origin.x,
|
||||
pt3.y - std::sqrt(t) * fHeightDifference - Origin.y,
|
||||
pt3.z - Origin.z );
|
||||
}
|
||||
f += step;
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
glEndList();
|
||||
}
|
||||
}
|
||||
/*
|
||||
void TTraction::InitCenter(vector3 Angles, vector3 pOrigin)
|
||||
@@ -119,149 +270,96 @@ void TTraction::InitCenter(vector3 Angles, vector3 pOrigin)
|
||||
fSquaredRadius= SquareMagnitude((pPoint2-pPoint1)*0.5f);
|
||||
} */
|
||||
|
||||
void TTraction::RenderDL(float mgn) // McZapkie: mgn to odleglosc od obserwatora
|
||||
void TTraction::RenderDL(float mgn, Math3D::vector3 const &Origin ) // McZapkie: mgn to odleglosc od obserwatora
|
||||
{
|
||||
// McZapkie: ustalanie przezroczystosci i koloru linii:
|
||||
if (Wires != 0 && !TestFlag(DamageFlag, 128)) // rysuj jesli sa druty i nie zerwana
|
||||
if( Wires != 0 && !TestFlag( DamageFlag, 128 ) ) // rysuj jesli sa druty i nie zerwana
|
||||
{
|
||||
// glDisable(GL_LIGHTING); //aby nie używało wektorów normalnych do kolorowania
|
||||
glColor4f(0, 0, 0, 1); // jak nieznany kolor to czarne nieprzezroczyste
|
||||
if (!Global::bSmoothTraction)
|
||||
glDisable(GL_LINE_SMOOTH); // na liniach kiepsko wygląda - robi gradient
|
||||
float linealpha = 5000 * WireThickness / (mgn + 1.0); //*WireThickness
|
||||
if (linealpha > 1.2f)
|
||||
linealpha = 1.2f; // zbyt grube nie są dobre
|
||||
glLineWidth(linealpha);
|
||||
if (linealpha > 1.0f)
|
||||
linealpha = 1.0f;
|
||||
// McZapkie-261102: kolor zalezy od materialu i zasniedzenia
|
||||
float r, g, b;
|
||||
switch (Material)
|
||||
{ // Ra: kolory podzieliłem przez 2, bo po zmianie ambient za jasne były
|
||||
// trzeba uwzględnić kierunek świecenia Słońca - tylko ze Słońcem widać kolor
|
||||
case 1:
|
||||
if (TestFlag(DamageFlag, 1))
|
||||
{
|
||||
r = 0.00000f;
|
||||
g = 0.32549f;
|
||||
b = 0.2882353f; // zielona miedź
|
||||
}
|
||||
else
|
||||
{
|
||||
r = 0.35098f;
|
||||
g = 0.22549f;
|
||||
b = 0.1f; // czerwona miedź
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (TestFlag(DamageFlag, 1))
|
||||
{
|
||||
r = 0.10f;
|
||||
g = 0.10f;
|
||||
b = 0.10f; // czarne Al
|
||||
}
|
||||
else
|
||||
{
|
||||
r = 0.25f;
|
||||
g = 0.25f;
|
||||
b = 0.25f; // srebrne Al
|
||||
}
|
||||
break;
|
||||
// tymczasowo pokazanie zasilanych odcinków
|
||||
case 4:
|
||||
r = 0.5f;
|
||||
g = 0.5f;
|
||||
b = 1.0f;
|
||||
break; // niebieskie z podłączonym zasilaniem
|
||||
case 5:
|
||||
r = 1.0f;
|
||||
g = 0.0f;
|
||||
b = 0.0f;
|
||||
break; // czerwone z podłączonym zasilaniem 1
|
||||
case 6:
|
||||
r = 0.0f;
|
||||
g = 1.0f;
|
||||
b = 0.0f;
|
||||
break; // zielone z podłączonym zasilaniem 2
|
||||
case 7:
|
||||
r = 1.0f;
|
||||
g = 1.0f;
|
||||
b = 0.0f;
|
||||
break; //żółte z podłączonym zasilaniem z obu stron
|
||||
// setup
|
||||
GfxRenderer.Bind( 0 );
|
||||
if( !Global::bSmoothTraction ) {
|
||||
// na liniach kiepsko wygląda - robi gradient
|
||||
::glDisable( GL_LINE_SMOOTH );
|
||||
}
|
||||
if (DebugModeFlag)
|
||||
if (hvParallel)
|
||||
{ // jeśli z bieżnią wspólną, to dodatkowo przyciemniamy
|
||||
r *= 0.6f;
|
||||
g *= 0.6f;
|
||||
b *= 0.6f;
|
||||
}
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
r *= Global::ambientDayLight[ 0 ]; // w zaleźności od koloru swiatła
|
||||
g *= Global::ambientDayLight[ 1 ];
|
||||
b *= Global::ambientDayLight[ 2 ];
|
||||
#else
|
||||
r *= Global::daylight.ambient.x; // w zaleźności od koloru swiatła
|
||||
g *= Global::daylight.ambient.y;
|
||||
b *= Global::daylight.ambient.z;
|
||||
#endif
|
||||
if (linealpha > 1.0f)
|
||||
linealpha = 1.0f; // trzeba ograniczyć do <=1
|
||||
glColor4f(r, g, b, linealpha);
|
||||
float linealpha = 5000 * WireThickness / ( mgn + 1.0 ); //*WireThickness
|
||||
linealpha = std::min( 1.2f, linealpha ); // zbyt grube nie są dobre
|
||||
::glLineWidth( linealpha );
|
||||
// McZapkie-261102: kolor zalezy od materialu i zasniedzenia
|
||||
float
|
||||
red{ 0.0f },
|
||||
green{ 0.0f },
|
||||
blue{ 0.0f };
|
||||
wire_color( red, green, blue );
|
||||
::glColor4f( red, green, blue, linealpha );
|
||||
// draw code
|
||||
if (!uiDisplayList)
|
||||
Optimize(); // generowanie DL w miarę potrzeby
|
||||
glCallList(uiDisplayList);
|
||||
glLineWidth(1.0);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
// glEnable(GL_LIGHTING); //bez tego się modele nie oświetlają
|
||||
Optimize( Origin ); // generowanie DL w miarę potrzeby
|
||||
::glCallList(uiDisplayList);
|
||||
// cleanup
|
||||
::glLineWidth(1.0);
|
||||
::glEnable(GL_LINE_SMOOTH);
|
||||
}
|
||||
}
|
||||
|
||||
// przygotowanie tablic do skopiowania do VBO (zliczanie wierzchołków)
|
||||
int TTraction::RaArrayPrepare()
|
||||
{ // przygotowanie tablic do skopiowania do VBO (zliczanie wierzchołków)
|
||||
// if (bVisible) //o ile w ogóle widać
|
||||
switch (Wires)
|
||||
{
|
||||
case 1:
|
||||
iLines = 2;
|
||||
break;
|
||||
case 2:
|
||||
iLines = iNumSections ? 4 * (iNumSections)-2 + 2 : 4;
|
||||
break;
|
||||
case 3:
|
||||
iLines = iNumSections ? 4 * (iNumSections)-2 + 4 : 6;
|
||||
break;
|
||||
case 4:
|
||||
iLines = iNumSections ? 4 * (iNumSections)-2 + 6 : 8;
|
||||
break;
|
||||
default:
|
||||
iLines = 0;
|
||||
{
|
||||
// jezdny
|
||||
iLines = 2;
|
||||
// przewod nosny
|
||||
if( Wires > 1 ) {
|
||||
iLines += 2 + (
|
||||
Wires < 4 ?
|
||||
std::max( 0, iNumSections - 1 ) :
|
||||
( iNumSections > 2 ?
|
||||
std::max( 0, iNumSections - 1 - 2 ) :
|
||||
std::max( 0, iNumSections - 1 - 1 ) ) );
|
||||
}
|
||||
// drugi przewod jezdny
|
||||
if( Wires > 2 ) {
|
||||
iLines += 2;
|
||||
}
|
||||
if( Wires == 4 ) {
|
||||
iLines += 2 + std::max( 0, iNumSections - 1 );
|
||||
}
|
||||
// przewody pionowe (wieszaki)
|
||||
if( Wires > 1 ) {
|
||||
iLines += 2 * ( std::max( 0, iNumSections - 1 ) );
|
||||
if( ( Wires == 4 )
|
||||
&&( iNumSections > 0 ) ) {
|
||||
iLines += (
|
||||
iNumSections > 4 ?
|
||||
4 :
|
||||
2 );
|
||||
}
|
||||
}
|
||||
// else iLines=0;
|
||||
return iLines;
|
||||
};
|
||||
|
||||
void TTraction::RaArrayFill(CVertNormTex *Vert)
|
||||
int TTraction::RaArrayFill(CVertNormTex *Vert, Math3D::vector3 const &Origin)
|
||||
{ // wypełnianie tablic VBO
|
||||
CVertNormTex *old = Vert;
|
||||
double ddp = hypot(pPoint2.x - pPoint1.x, pPoint2.z - pPoint1.z);
|
||||
int debugvertexcount{ 0 };
|
||||
|
||||
double ddp = std::hypot(pPoint2.x - pPoint1.x, pPoint2.z - pPoint1.z);
|
||||
if (Wires == 2)
|
||||
WireOffset = 0;
|
||||
// jezdny
|
||||
Vert->x = pPoint1.x - (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset;
|
||||
Vert->y = pPoint1.y;
|
||||
Vert->z = pPoint1.z - (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset;
|
||||
Vert->x = pPoint1.x - ( pPoint2.z / ddp - pPoint1.z / ddp ) * WireOffset - Origin.x;
|
||||
Vert->y = pPoint1.y - Origin.y;
|
||||
Vert->z = pPoint1.z - ( -pPoint2.x / ddp + pPoint1.x / ddp ) * WireOffset - Origin.z;
|
||||
++Vert;
|
||||
Vert->x = pPoint2.x - (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset;
|
||||
Vert->y = pPoint2.y;
|
||||
Vert->z = pPoint2.z - (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset;
|
||||
++debugvertexcount;
|
||||
Vert->x = pPoint2.x - ( pPoint2.z / ddp - pPoint1.z / ddp ) * WireOffset - Origin.x;
|
||||
Vert->y = pPoint2.y - Origin.y;
|
||||
Vert->z = pPoint2.z - ( -pPoint2.x / ddp + pPoint1.x / ddp ) * WireOffset - Origin.z;
|
||||
++Vert;
|
||||
++debugvertexcount;
|
||||
// Nie wiem co 'Marcin
|
||||
Math3D::vector3 pt1, pt2, pt3, pt4, v1, v2;
|
||||
v1 = pPoint4 - pPoint3;
|
||||
v2 = pPoint2 - pPoint1;
|
||||
float step = 0;
|
||||
if (iNumSections > 0)
|
||||
if( iNumSections > 0 )
|
||||
step = 1.0f / (float)iNumSections;
|
||||
float f = step;
|
||||
float mid = 0.5;
|
||||
@@ -269,159 +367,197 @@ void TTraction::RaArrayFill(CVertNormTex *Vert)
|
||||
// Przewod nosny 'Marcin
|
||||
if (Wires > 1)
|
||||
{ // lina nośna w kawałkach
|
||||
Vert->x = pPoint3.x;
|
||||
Vert->y = pPoint3.y;
|
||||
Vert->z = pPoint3.z;
|
||||
Vert->x = pPoint3.x - Origin.x;
|
||||
Vert->y = pPoint3.y - Origin.y;
|
||||
Vert->z = pPoint3.z - Origin.z;
|
||||
++Vert;
|
||||
for (int i = 0; i < iNumSections - 1; i++)
|
||||
++debugvertexcount;
|
||||
for (int i = 0; i < iNumSections - 1; ++i)
|
||||
{
|
||||
pt3 = pPoint3 + v1 * f;
|
||||
t = (1 - fabs(f - mid) * 2);
|
||||
Vert->x = pt3.x;
|
||||
Vert->y = pt3.y - sqrt(t) * fHeightDifference;
|
||||
Vert->z = pt3.z;
|
||||
++Vert;
|
||||
Vert->x = pt3.x; // drugi raz, bo nie jest line_strip
|
||||
Vert->y = pt3.y - sqrt(t) * fHeightDifference;
|
||||
Vert->z = pt3.z;
|
||||
++Vert;
|
||||
t = (1 - std::fabs(f - mid) * 2);
|
||||
if( ( Wires < 4 )
|
||||
|| ( ( i != 0 )
|
||||
&& ( i != iNumSections - 2 ) ) ) {
|
||||
Vert->x = pt3.x - Origin.x;
|
||||
Vert->y = pt3.y - std::sqrt( t ) * fHeightDifference - Origin.y;
|
||||
Vert->z = pt3.z - Origin.z;
|
||||
++Vert;
|
||||
++debugvertexcount;
|
||||
}
|
||||
f += step;
|
||||
}
|
||||
Vert->x = pPoint4.x;
|
||||
Vert->y = pPoint4.y;
|
||||
Vert->z = pPoint4.z;
|
||||
Vert->x = pPoint4.x - Origin.x;
|
||||
Vert->y = pPoint4.y - Origin.y;
|
||||
Vert->z = pPoint4.z - Origin.z;
|
||||
++Vert;
|
||||
++debugvertexcount;
|
||||
}
|
||||
// Drugi przewod jezdny 'Winger
|
||||
if (Wires == 3)
|
||||
if (Wires > 2)
|
||||
{
|
||||
Vert->x = pPoint1.x + (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset;
|
||||
Vert->y = pPoint1.y;
|
||||
Vert->z = pPoint1.z + (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset;
|
||||
Vert->x = pPoint1.x + (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset - Origin.x;
|
||||
Vert->y = pPoint1.y - Origin.y;
|
||||
Vert->z = pPoint1.z + (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset - Origin.z;
|
||||
++Vert;
|
||||
Vert->x = pPoint2.x + (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset;
|
||||
Vert->y = pPoint2.y;
|
||||
Vert->z = pPoint2.z + (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset;
|
||||
++debugvertexcount;
|
||||
Vert->x = pPoint2.x + (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset - Origin.x;
|
||||
Vert->y = pPoint2.y - Origin.y;
|
||||
Vert->z = pPoint2.z + (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset - Origin.z;
|
||||
++Vert;
|
||||
++debugvertexcount;
|
||||
}
|
||||
|
||||
f = step;
|
||||
|
||||
if( Wires == 4 ) {
|
||||
Vert->x = pPoint3.x - Origin.x;
|
||||
Vert->y = pPoint3.y - 0.65f * fHeightDifference - Origin.y;
|
||||
Vert->z = pPoint3.z - Origin.z;
|
||||
++Vert;
|
||||
++debugvertexcount;
|
||||
for( int i = 0; i < iNumSections - 1; ++i ) {
|
||||
pt3 = pPoint3 + v1 * f;
|
||||
t = ( 1 - std::fabs( f - mid ) * 2 );
|
||||
Vert->x = pt3.x - Origin.x;
|
||||
Vert->y = pt3.y - std::sqrt( t ) * fHeightDifference - (
|
||||
( ( i == 0 )
|
||||
|| ( i == iNumSections - 2 ) ) ?
|
||||
0.25f * fHeightDifference :
|
||||
0.05 )
|
||||
- Origin.y;
|
||||
Vert->z = pt3.z - Origin.z;
|
||||
++Vert;
|
||||
++debugvertexcount;
|
||||
f += step;
|
||||
}
|
||||
Vert->x = pPoint4.x - Origin.x;
|
||||
Vert->y = pPoint4.y - 0.65f * fHeightDifference - Origin.y;
|
||||
Vert->z = pPoint4.z - Origin.z;
|
||||
++Vert;
|
||||
++debugvertexcount;
|
||||
}
|
||||
f = step;
|
||||
|
||||
// Przewody pionowe (wieszaki) 'Marcin, poprawki na 2 przewody jezdne 'Winger
|
||||
if (Wires > 1)
|
||||
{
|
||||
for (int i = 0; i < iNumSections - 1; i++)
|
||||
for (int i = 0; i < iNumSections - 1; ++i)
|
||||
{
|
||||
float flo, flo1;
|
||||
flo = ( Wires == 4 ? 0.25f * fHeightDifference : 0 );
|
||||
flo1 = ( Wires == 4 ? +0.05 : 0 );
|
||||
pt3 = pPoint3 + v1 * f;
|
||||
pt4 = pPoint1 + v2 * f;
|
||||
t = (1 - fabs(f - mid) * 2);
|
||||
Vert->x = pt3.x;
|
||||
Vert->y = pt3.y - sqrt(t) * fHeightDifference;
|
||||
Vert->z = pt3.z;
|
||||
++Vert;
|
||||
if ((i % 2) == 0)
|
||||
{
|
||||
Vert->x = pt4.x - (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset;
|
||||
Vert->y = pt4.y;
|
||||
Vert->z = pt4.z - (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset;
|
||||
t = (1 - std::fabs(f - mid) * 2);
|
||||
|
||||
if( ( i % 2 ) == 0 ) {
|
||||
Vert->x = pt3.x - Origin.x;
|
||||
Vert->y = pt3.y - std::sqrt( t ) * fHeightDifference - ( ( i == 0 ) || ( i == iNumSections - 2 ) ? flo : flo1 ) - Origin.y;
|
||||
Vert->z = pt3.z - Origin.z;
|
||||
++Vert;
|
||||
++debugvertexcount;
|
||||
Vert->x = pt4.x - ( pPoint2.z / ddp - pPoint1.z / ddp ) * WireOffset - Origin.x;
|
||||
Vert->y = pt4.y - Origin.y;
|
||||
Vert->z = pt4.z - ( -pPoint2.x / ddp + pPoint1.x / ddp ) * WireOffset - Origin.z;
|
||||
++Vert;
|
||||
++debugvertexcount;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vert->x = pt4.x + (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset;
|
||||
Vert->y = pt4.y;
|
||||
Vert->z = pt4.z + (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset;
|
||||
else {
|
||||
Vert->x = pt3.x - Origin.x;
|
||||
Vert->y = pt3.y - std::sqrt( t ) * fHeightDifference - ( ( i == 0 ) || ( i == iNumSections - 2 ) ? flo : flo1 ) - Origin.y;
|
||||
Vert->z = pt3.z - Origin.z;
|
||||
++Vert;
|
||||
++debugvertexcount;
|
||||
Vert->x = pt4.x + ( pPoint2.z / ddp - pPoint1.z / ddp ) * WireOffset - Origin.x;
|
||||
Vert->y = pt4.y - Origin.y;
|
||||
Vert->z = pt4.z + ( -pPoint2.x / ddp + pPoint1.x / ddp ) * WireOffset - Origin.z;
|
||||
++Vert;
|
||||
++debugvertexcount;
|
||||
}
|
||||
if( ( ( Wires == 4 )
|
||||
&& ( ( i == 1 )
|
||||
|| ( i == iNumSections - 3 ) ) ) ) {
|
||||
Vert->x = pt3.x - Origin.x;
|
||||
Vert->y = pt3.y - std::sqrt( t ) * fHeightDifference - 0.05 - Origin.y;
|
||||
Vert->z = pt3.z - Origin.z;
|
||||
++Vert;
|
||||
++debugvertexcount;
|
||||
Vert->x = pt3.x - Origin.x;
|
||||
Vert->y = pt3.y - std::sqrt( t ) * fHeightDifference - Origin.y;
|
||||
Vert->z = pt3.z - Origin.z;
|
||||
++Vert;
|
||||
++debugvertexcount;
|
||||
}
|
||||
++Vert;
|
||||
f += step;
|
||||
}
|
||||
}
|
||||
if ((Vert - old) != iLines)
|
||||
WriteLog("!!! Wygenerowano punktów " + std::to_string(Vert - old) + ", powinno być " +
|
||||
std::to_string(iLines));
|
||||
return debugvertexcount;
|
||||
};
|
||||
|
||||
void TTraction::RenderVBO(float mgn, int iPtr)
|
||||
{ // renderowanie z użyciem VBO
|
||||
if (Wires != 0 && !TestFlag(DamageFlag, 128)) // rysuj jesli sa druty i nie zerwana
|
||||
{
|
||||
// setup
|
||||
GfxRenderer.Bind(0);
|
||||
glDisable(GL_LIGHTING); // aby nie używało wektorów normalnych do kolorowania
|
||||
glColor4f(0, 0, 0, 1); // jak nieznany kolor to czarne nieprzezroczyste
|
||||
if (!Global::bSmoothTraction)
|
||||
glDisable(GL_LINE_SMOOTH); // na liniach kiepsko wygląda - robi gradient
|
||||
float linealpha = 5000 * WireThickness / (mgn + 1.0); //*WireThickness
|
||||
if (linealpha > 1.2f)
|
||||
linealpha = 1.2f; // zbyt grube nie są dobre
|
||||
glLineWidth(linealpha);
|
||||
// McZapkie-261102: kolor zalezy od materialu i zasniedzenia
|
||||
float r, g, b;
|
||||
switch (Material)
|
||||
{ // Ra: kolory podzieliłem przez 2, bo po zmianie ambient za jasne były
|
||||
// trzeba uwzględnić kierunek świecenia Słońca - tylko ze Słońcem widać kolor
|
||||
case 1:
|
||||
if (TestFlag(DamageFlag, 1))
|
||||
{
|
||||
r = 0.00000f;
|
||||
g = 0.32549f;
|
||||
b = 0.2882353f; // zielona miedź
|
||||
}
|
||||
else
|
||||
{
|
||||
r = 0.35098f;
|
||||
g = 0.22549f;
|
||||
b = 0.1f; // czerwona miedź
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
if (TestFlag(DamageFlag, 1))
|
||||
{
|
||||
r = 0.10f;
|
||||
g = 0.10f;
|
||||
b = 0.10f; // czarne Al
|
||||
}
|
||||
else
|
||||
{
|
||||
r = 0.25f;
|
||||
g = 0.25f;
|
||||
b = 0.25f; // srebrne Al
|
||||
}
|
||||
break;
|
||||
// tymczasowo pokazanie zasilanych odcinków
|
||||
case 4:
|
||||
r = 0.5f;
|
||||
g = 0.5f;
|
||||
b = 1.0f;
|
||||
break; // niebieskie z podłączonym zasilaniem
|
||||
case 5:
|
||||
r = 1.0f;
|
||||
g = 0.0f;
|
||||
b = 0.0f;
|
||||
break; // czerwone z podłączonym zasilaniem 1
|
||||
case 6:
|
||||
r = 0.0f;
|
||||
g = 1.0f;
|
||||
b = 0.0f;
|
||||
break; // zielone z podłączonym zasilaniem 2
|
||||
case 7:
|
||||
r = 1.0f;
|
||||
g = 1.0f;
|
||||
b = 0.0f;
|
||||
break; //żółte z podłączonym zasilaniem z obu stron
|
||||
if( !Global::bSmoothTraction ) {
|
||||
// na liniach kiepsko wygląda - robi gradient
|
||||
::glDisable( GL_LINE_SMOOTH );
|
||||
}
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
r *= Global::ambientDayLight[ 0 ]; // w zaleźności od koloru swiatła
|
||||
g *= Global::ambientDayLight[ 1 ];
|
||||
b *= Global::ambientDayLight[ 2 ];
|
||||
#else
|
||||
r *= Global::daylight.ambient.x; // w zaleźności od koloru swiatła
|
||||
g *= Global::daylight.ambient.y;
|
||||
b *= Global::daylight.ambient.z;
|
||||
#endif
|
||||
if (linealpha > 1.0f)
|
||||
linealpha = 1.0f; // trzeba ograniczyć do <=1
|
||||
glColor4f(r, g, b, linealpha);
|
||||
glDrawArrays(GL_LINES, iPtr, iLines);
|
||||
glLineWidth(1.0);
|
||||
glEnable(GL_LINE_SMOOTH);
|
||||
glEnable(GL_LIGHTING); // bez tego się modele nie oświetlają
|
||||
float linealpha = 5000 * WireThickness / (mgn + 1.0); //*WireThickness
|
||||
linealpha = std::min( 1.2f, linealpha ); // zbyt grube nie są dobre
|
||||
::glLineWidth(linealpha);
|
||||
// McZapkie-261102: kolor zalezy od materialu i zasniedzenia
|
||||
float
|
||||
red{ 0.0f },
|
||||
green{ 0.0f },
|
||||
blue{ 0.0f };
|
||||
wire_color( red, green, blue );
|
||||
::glColor4f(red, green, blue, linealpha);
|
||||
// draw code
|
||||
// jezdny
|
||||
::glDrawArrays( GL_LINE_STRIP, iPtr, 2 );
|
||||
iPtr += 2;
|
||||
// przewod nosny
|
||||
if( Wires > 1 ) {
|
||||
auto const piececount = 2 + (
|
||||
Wires < 4 ?
|
||||
std::max( 0 , iNumSections - 1 ) :
|
||||
( iNumSections > 2 ?
|
||||
std::max( 0, iNumSections - 1 - 2 ) :
|
||||
std::max( 0, iNumSections - 1 - 1 ) ) );
|
||||
::glDrawArrays( GL_LINE_STRIP, iPtr, piececount );
|
||||
iPtr += piececount;
|
||||
}
|
||||
// drugi przewod jezdny
|
||||
if( Wires > 2 ) {
|
||||
::glDrawArrays( GL_LINE_STRIP, iPtr, 2 );
|
||||
iPtr += 2;
|
||||
}
|
||||
if( Wires == 4 ) {
|
||||
auto const piececount = 2 + std::max( 0, iNumSections - 1 );
|
||||
::glDrawArrays( GL_LINE_STRIP, iPtr, piececount );
|
||||
iPtr += piececount;
|
||||
}
|
||||
// przewody pionowe (wieszaki)
|
||||
if( Wires != 1 ) {
|
||||
auto piececount = 2 * std::max( 0, iNumSections - 1 );
|
||||
if( ( Wires == 4 )
|
||||
&& ( iNumSections > 0 ) ) {
|
||||
piececount += (
|
||||
iNumSections > 4 ?
|
||||
4 :
|
||||
2 );
|
||||
}
|
||||
if( piececount > 0 ) {
|
||||
::glDrawArrays( GL_LINES, iPtr, piececount );
|
||||
iPtr += piececount;
|
||||
}
|
||||
}
|
||||
// cleanup
|
||||
::glLineWidth(1.0);
|
||||
::glEnable(GL_LINE_SMOOTH);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -492,11 +628,16 @@ void TTraction::ResistanceCalc(int d, double r, TTractionPowerSource *ps)
|
||||
else
|
||||
ps = psPower[d ^ 1]; // zasilacz od przeciwnej strony niż idzie analiza
|
||||
d = iNext[d]; // kierunek
|
||||
// double r; //sumaryczna rezystancja
|
||||
#ifdef EU07_USE_OLD_TRACTIONPOWER_CODE
|
||||
if (DebugModeFlag) // tylko podczas testów
|
||||
Material = 4; // pokazanie, że to przęsło ma podłączone zasilanie
|
||||
while (t ? !t->psPower[d] : false) // jeśli jest jakiś kolejny i nie ma ustalonego zasilacza
|
||||
#else
|
||||
PowerState = 4;
|
||||
#endif
|
||||
while( ( t != nullptr )
|
||||
&& ( t->psPower[d] == nullptr ) ) // jeśli jest jakiś kolejny i nie ma ustalonego zasilacza
|
||||
{ // ustawienie zasilacza i policzenie rezystancji zastępczej
|
||||
#ifdef EU07_USE_OLD_TRACTIONPOWER_CODE
|
||||
if (DebugModeFlag) // tylko podczas testów
|
||||
if (t->Material != 4) // przęsła zasilającego nie modyfikować
|
||||
{
|
||||
@@ -504,6 +645,19 @@ void TTraction::ResistanceCalc(int d, double r, TTractionPowerSource *ps)
|
||||
t->Material = 4; // tymczasowo, aby zmieniła kolor
|
||||
t->Material |= d ? 2 : 1; // kolor zależny od strony, z której jest zasilanie
|
||||
}
|
||||
#else
|
||||
if( t->PowerState != 4 ) {
|
||||
// przęsła zasilającego nie modyfikować
|
||||
if( t->psPowered != nullptr ) {
|
||||
|
||||
t->PowerState = 4;
|
||||
}
|
||||
else {
|
||||
// kolor zależny od strony, z której jest zasilanie
|
||||
t->PowerState |= d ? 2 : 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
t->psPower[d] = ps; // skopiowanie wskaźnika zasilacza od danej strony
|
||||
t->fResistance[d] = r; // wpisanie rezystancji w kierunku tego zasilacza
|
||||
r += t->fResistivity * Length3(t->vParametric); // doliczenie oporu kolejnego odcinka
|
||||
@@ -589,3 +743,84 @@ double TTraction::VoltageGet(double u, double i)
|
||||
return psPower[1]->CurrentGet(res + r1t) * res;
|
||||
return 0.0; // gdy nie podłączony wcale?
|
||||
};
|
||||
|
||||
void
|
||||
TTraction::wire_color( float &Red, float &Green, float &Blue ) const {
|
||||
|
||||
if( false == DebugModeFlag ) {
|
||||
switch( Material ) { // Ra: kolory podzieliłem przez 2, bo po zmianie ambient za jasne były
|
||||
// trzeba uwzględnić kierunek świecenia Słońca - tylko ze Słońcem widać kolor
|
||||
case 1: {
|
||||
if( TestFlag( DamageFlag, 1 ) ) {
|
||||
Red = 0.00000f;
|
||||
Green = 0.32549f;
|
||||
Blue = 0.2882353f; // zielona miedź
|
||||
}
|
||||
else {
|
||||
Red = 0.35098f;
|
||||
Green = 0.22549f;
|
||||
Blue = 0.1f; // czerwona miedź
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
if( TestFlag( DamageFlag, 1 ) ) {
|
||||
Red = 0.10f;
|
||||
Green = 0.10f;
|
||||
Blue = 0.10f; // czarne Al
|
||||
}
|
||||
else {
|
||||
Red = 0.25f;
|
||||
Green = 0.25f;
|
||||
Blue = 0.25f; // srebrne Al
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {break; }
|
||||
}
|
||||
// w zaleźności od koloru swiatła
|
||||
Red *= Global::daylight.ambient.x;
|
||||
Green *= Global::daylight.ambient.y;
|
||||
Blue *= Global::daylight.ambient.z;
|
||||
}
|
||||
else {
|
||||
// tymczasowo pokazanie zasilanych odcinków
|
||||
switch( PowerState ) {
|
||||
|
||||
case 1: {
|
||||
// czerwone z podłączonym zasilaniem 1
|
||||
Red = 1.0f;
|
||||
Green = 0.0f;
|
||||
Blue = 0.0f;
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
// zielone z podłączonym zasilaniem 2
|
||||
Red = 0.0f;
|
||||
Green = 1.0f;
|
||||
Blue = 0.0f;
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
//żółte z podłączonym zasilaniem z obu stron
|
||||
Red = 1.0f;
|
||||
Green = 1.0f;
|
||||
Blue = 0.0f;
|
||||
break;
|
||||
}
|
||||
case 4: {
|
||||
// niebieskie z podłączonym zasilaniem
|
||||
Red = 0.5f;
|
||||
Green = 0.5f;
|
||||
Blue = 1.0f;
|
||||
break;
|
||||
}
|
||||
default: { break; }
|
||||
}
|
||||
if( hvParallel ) { // jeśli z bieżnią wspólną, to dodatkowo przyciemniamy
|
||||
Red *= 0.6f;
|
||||
Green *= 0.6f;
|
||||
Blue *= 0.6f;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Traction.h
11
Traction.h
@@ -54,10 +54,9 @@ class TTraction
|
||||
TTraction *hvParallel = nullptr; // jednokierunkowa i zapętlona lista przęseł ewentualnej bieżni wspólnej
|
||||
float fResistance[2]; // rezystancja zastępcza do punktu zasilania (0: przęsło zasilane, <0: do policzenia)
|
||||
int iTries = 0;
|
||||
// bool bVisible;
|
||||
// DWORD dwFlags;
|
||||
int PowerState{ 0 }; // type of incoming power, if any
|
||||
|
||||
void Optimize();
|
||||
void Optimize( Math3D::vector3 const &Origin );
|
||||
|
||||
TTraction();
|
||||
~TTraction();
|
||||
@@ -67,9 +66,9 @@ class TTraction
|
||||
// { return TNode::Hit(x,z,hitPoint,hitDirection); };
|
||||
// virtual bool Move(double dx, double dy, double dz) { return false; };
|
||||
// virtual void SelectedRender();
|
||||
void RenderDL(float mgn);
|
||||
void RenderDL(float mgn, Math3D::vector3 const &Origin );
|
||||
int RaArrayPrepare();
|
||||
void RaArrayFill(CVertNormTex *Vert);
|
||||
int RaArrayFill( CVertNormTex *Vert, Math3D::vector3 const &Origin );
|
||||
void RenderVBO(float mgn, int iPtr);
|
||||
int TestPoint(Math3D::vector3 *Point);
|
||||
void Connect(int my, TTraction *with, int to);
|
||||
@@ -78,5 +77,7 @@ class TTraction
|
||||
void ResistanceCalc(int d = -1, double r = 0, TTractionPowerSource *ps = NULL);
|
||||
void PowerSet(TTractionPowerSource *ps);
|
||||
double VoltageGet(double u, double i);
|
||||
private:
|
||||
void wire_color( float &Red, float &Green, float &Blue ) const;
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
5
Train.h
5
Train.h
@@ -146,8 +146,10 @@ class TTrain
|
||||
static void OnCommand_pantographlowerall( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_linebreakertoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_convertertoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_convertertogglelocal( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_converteroverloadrelayreset( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compressortoggle( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_compressortogglelocal( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motorconnectorsopen( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motordisconnect( TTrain *Train, command_data const &Command );
|
||||
static void OnCommand_motoroverloadrelaythresholdtoggle( TTrain *Train, command_data const &Command );
|
||||
@@ -251,7 +253,9 @@ public: // reszta może by?publiczna
|
||||
TGauge ggIgnitionKey;
|
||||
|
||||
TGauge ggCompressorButton;
|
||||
TGauge ggCompressorLocalButton; // controls only compressor of its own unit (et42-specific)
|
||||
TGauge ggConverterButton;
|
||||
TGauge ggConverterLocalButton; // controls only converter of its own unit (et42-specific)
|
||||
TGauge ggConverterOffButton;
|
||||
|
||||
// ABu 090305 - syrena i prad nastepnego czlonu
|
||||
@@ -484,6 +488,7 @@ public: // reszta może by?publiczna
|
||||
|
||||
public:
|
||||
float fPress[20][3]; // cisnienia dla wszystkich czlonow
|
||||
static std::vector<std::string> const fPress_labels;
|
||||
float fEIMParams[9][10]; // parametry dla silnikow asynchronicznych
|
||||
int RadioChannel() { return iRadioChannel; };
|
||||
inline TDynamicObject *Dynamic() { return DynamicObject; };
|
||||
|
||||
12
VBO.cpp
12
VBO.cpp
@@ -45,7 +45,9 @@ void CVertNormTex::serialize(std::ostream &s)
|
||||
|
||||
CMesh::CMesh()
|
||||
{ // utworzenie pustego obiektu
|
||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||
m_pVNT = nullptr;
|
||||
#endif
|
||||
m_nVertexCount = -1;
|
||||
m_nVBOVertices = 0; // nie zarezerwowane
|
||||
};
|
||||
@@ -58,7 +60,13 @@ CMesh::~CMesh()
|
||||
void CMesh::MakeArray(int n)
|
||||
{ // tworzenie tablic
|
||||
m_nVertexCount = n;
|
||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||
assert( m_pVNT == nullptr );
|
||||
m_pVNT = new CVertNormTex[m_nVertexCount]; // przydzielenie pamięci dla tablicy
|
||||
#else
|
||||
m_pVNT.clear();
|
||||
m_pVNT.resize( m_nVertexCount );
|
||||
#endif
|
||||
};
|
||||
|
||||
void CMesh::BuildVBOs(bool del)
|
||||
@@ -91,7 +99,11 @@ void CMesh::Clear()
|
||||
}
|
||||
m_nVBOVertices = 0;
|
||||
m_nVertexCount = -1; // do ponownego zliczenia
|
||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||
SafeDeleteArray(m_pVNT); // usuwanie tablic, gdy były użyte do Vertex Array
|
||||
#else
|
||||
m_pVNT.clear();
|
||||
#endif
|
||||
};
|
||||
|
||||
extern TWorld World;
|
||||
|
||||
7
VBO.h
7
VBO.h
@@ -11,6 +11,9 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef VBOH
|
||||
#define VBOH
|
||||
|
||||
#define EU07_USE_OLD_VERTEXBUFFER
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
class CVertNormTex
|
||||
{
|
||||
@@ -34,7 +37,11 @@ class CMesh
|
||||
gl_program shader;
|
||||
public:
|
||||
int m_nVertexCount; // liczba wierzchołków
|
||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||
CVertNormTex *m_pVNT;
|
||||
#else
|
||||
std::vector<CVertNormTex> m_pVNT;
|
||||
#endif
|
||||
unsigned int m_nVBOVertices; // numer VBO z wierzchołkami
|
||||
CMesh();
|
||||
~CMesh();
|
||||
|
||||
@@ -47,8 +47,10 @@ commanddescription_sequence Commands_descriptions = {
|
||||
{ "reverserdecrease", command_target::vehicle },
|
||||
{ "linebreakertoggle", command_target::vehicle },
|
||||
{ "convertertoggle", command_target::vehicle },
|
||||
{ "convertertogglelocal", command_target::vehicle },
|
||||
{ "converteroverloadrelayreset", command_target::vehicle },
|
||||
{ "compressortoggle", command_target::vehicle },
|
||||
{ "compressortogglelocal", command_target::vehicle },
|
||||
{ "motoroverloadrelaythresholdtoggle", command_target::vehicle },
|
||||
{ "motoroverloadrelayreset", command_target::vehicle },
|
||||
{ "notchingrelaytoggle", command_target::vehicle },
|
||||
|
||||
@@ -42,8 +42,10 @@ enum class user_command {
|
||||
reverserdecrease,
|
||||
linebreakertoggle,
|
||||
convertertoggle,
|
||||
convertertogglelocal,
|
||||
converteroverloadrelayreset,
|
||||
compressortoggle,
|
||||
compressortogglelocal,
|
||||
motoroverloadrelaythresholdtoggle,
|
||||
motoroverloadrelayreset,
|
||||
notchingrelaytoggle,
|
||||
|
||||
8
dumb3d.h
8
dumb3d.h
@@ -104,14 +104,8 @@ class vector3
|
||||
return &x;
|
||||
}
|
||||
|
||||
// union
|
||||
// {
|
||||
// struct
|
||||
// {
|
||||
double x, y, z;
|
||||
// };
|
||||
// scalar_t e[3];
|
||||
// };
|
||||
|
||||
bool inline Equal(vector3 *v)
|
||||
{ // sprawdzenie odległości punktów
|
||||
if (std::fabs(x - v->x) > 0.02)
|
||||
|
||||
@@ -27,6 +27,9 @@ public:
|
||||
calculate(glm::mat4 const &Projection, glm::mat4 const &Modelview);
|
||||
// returns true if specified point is inside of the frustum
|
||||
inline
|
||||
bool
|
||||
point_inside( glm::vec3 const &Point ) const { return point_inside( Point.x, Point.y, Point.z ); }
|
||||
inline
|
||||
bool
|
||||
point_inside( float3 const &Point ) const { return point_inside( Point.x, Point.y, Point.z ); }
|
||||
inline
|
||||
@@ -36,6 +39,9 @@ public:
|
||||
point_inside( float const X, float const Y, float const Z ) const;
|
||||
// tests if the sphere is in frustum, returns the distance between origin and sphere centre
|
||||
inline
|
||||
float
|
||||
sphere_inside( glm::vec3 const &Center, float const Radius ) const { return sphere_inside( Center.x, Center.y, Center.z, Radius ); }
|
||||
inline
|
||||
float
|
||||
sphere_inside( float3 const &Center, float const Radius ) const { return sphere_inside( Center.x, Center.y, Center.z, Radius ); }
|
||||
inline
|
||||
@@ -45,6 +51,9 @@ public:
|
||||
sphere_inside( float const X, float const Y, float const Z, float const Radius ) const;
|
||||
// returns true if specified cube is inside of the frustum. Size = half of the length
|
||||
inline
|
||||
bool
|
||||
cube_inside( glm::vec3 const &Center, float const Size ) const { return cube_inside( Center.x, Center.y, Center.z, Size ); }
|
||||
inline
|
||||
bool
|
||||
cube_inside( float3 const &Center, float const Size ) const { return cube_inside( Center.x, Center.y, Center.z, Size ); }
|
||||
inline
|
||||
|
||||
@@ -80,7 +80,7 @@ private:
|
||||
glm::vec2 m_leftstick;
|
||||
glm::vec2 m_rightstick;
|
||||
glm::vec2 m_triggers;
|
||||
double m_modeaccumulator; // used to throttle command input rate for vehicle controls
|
||||
double m_modeaccumulator{ 0.0 }; // used to throttle command input rate for vehicle controls
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -228,10 +228,14 @@ keyboard_input::default_bindings() {
|
||||
{ GLFW_KEY_M },
|
||||
// convertertoggle
|
||||
{ GLFW_KEY_X },
|
||||
// convertertogglelocal
|
||||
{ GLFW_KEY_X | keymodifier::shift },
|
||||
// converteroverloadrelayreset
|
||||
{ GLFW_KEY_N | keymodifier::control },
|
||||
// compressortoggle
|
||||
{ GLFW_KEY_C },
|
||||
// compressortoggleloal
|
||||
{ GLFW_KEY_C | keymodifier::shift },
|
||||
// motoroverloadrelaythresholdtoggle
|
||||
{ GLFW_KEY_F },
|
||||
// motoroverloadrelayreset
|
||||
|
||||
@@ -70,7 +70,7 @@ private:
|
||||
bool m_shift{ false };
|
||||
bool m_ctrl{ false };
|
||||
bindings_cache m_bindingscache;
|
||||
std::array<char, GLFW_KEY_LAST> m_keys;
|
||||
std::array<char, GLFW_KEY_LAST + 1> m_keys;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -82,9 +82,9 @@ typedef std::vector<opengl_stack> openglstack_array;
|
||||
public:
|
||||
// constructors:
|
||||
opengl_matrices() {
|
||||
m_stacks.emplace_back(); // projection
|
||||
m_stacks.emplace_back(); // modelview
|
||||
}
|
||||
m_stacks.emplace_back(); // projection
|
||||
m_stacks.emplace_back(); // modelview
|
||||
}
|
||||
|
||||
// methods:
|
||||
void
|
||||
|
||||
610
renderer.cpp
610
renderer.cpp
@@ -11,8 +11,12 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include "renderer.h"
|
||||
#include "globals.h"
|
||||
#include "World.h"
|
||||
#include "timer.h"
|
||||
#include "world.h"
|
||||
#include "data.h"
|
||||
#include "dynobj.h"
|
||||
#include "animmodel.h"
|
||||
#include "traction.h"
|
||||
#include "uilayer.h"
|
||||
#include "logs.h"
|
||||
#include "usefull.h"
|
||||
@@ -32,11 +36,11 @@ bool
|
||||
opengl_camera::visible( TDynamicObject const *Dynamic ) const {
|
||||
|
||||
// sphere test is faster than AABB, so we'll use it here
|
||||
float3 diagonal(
|
||||
Dynamic->MoverParameters->Dim.L,
|
||||
Dynamic->MoverParameters->Dim.H,
|
||||
Dynamic->MoverParameters->Dim.W );
|
||||
float const radius = diagonal.Length() * 0.5f;
|
||||
glm::vec3 diagonal(
|
||||
static_cast<float>( Dynamic->MoverParameters->Dim.L ),
|
||||
static_cast<float>( Dynamic->MoverParameters->Dim.H ),
|
||||
static_cast<float>( Dynamic->MoverParameters->Dim.W ) );
|
||||
float const radius = glm::length( diagonal ) * 0.5f;
|
||||
|
||||
return ( m_frustum.sphere_inside( Dynamic->GetPosition(), radius ) > 0.0f );
|
||||
}
|
||||
@@ -103,13 +107,19 @@ opengl_renderer::Init( GLFWwindow *Window ) {
|
||||
World.shader = gl_program_light({ gl_shader("lighting.vert"), gl_shader("blinnphong.frag") });
|
||||
Global::daylight.intensity = 1.0f; //m7todo: przenieść
|
||||
|
||||
WriteLog("Loading common gfx data...");
|
||||
m_glaretextureid = GetTextureId("fx\\lightglare", szTexturePath);
|
||||
m_suntextureid = GetTextureId("fx\\sun", szTexturePath);
|
||||
m_moontextureid = GetTextureId("fx\\moon", szTexturePath);
|
||||
WriteLog("...gfx data pre-loading done");
|
||||
|
||||
return true;
|
||||
// preload some common textures
|
||||
WriteLog( "Loading common gfx data..." );
|
||||
m_glaretextureid = GetTextureId( "fx\\lightglare", szTexturePath );
|
||||
m_suntextureid = GetTextureId( "fx\\sun", szTexturePath );
|
||||
m_moontextureid = GetTextureId( "fx\\moon", szTexturePath );
|
||||
WriteLog( "...gfx data pre-loading done" );
|
||||
|
||||
// prepare debug mode objects
|
||||
m_quadric = gluNewQuadric();
|
||||
gluQuadricNormals( m_quadric, GLU_FLAT );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -132,15 +142,22 @@ opengl_renderer::Render() {
|
||||
::glLoadIdentity();
|
||||
|
||||
if( World.InitPerformed() ) {
|
||||
/*
|
||||
World.Camera.SetMatrix();
|
||||
m_camera.update_frustum();
|
||||
*/
|
||||
glm::dmat4 worldcamera;
|
||||
World.Camera.SetMatrix( worldcamera );
|
||||
m_camera.update_frustum( OpenGLMatrices.data( GL_PROJECTION ), worldcamera );
|
||||
// frustum tests are performed in 'world space' but after we set up frustum
|
||||
// we no longer need camera translation, only rotation
|
||||
::glMultMatrixd( glm::value_ptr( glm::dmat4( glm::dmat3( worldcamera ))));
|
||||
|
||||
glDisable(GL_FRAMEBUFFER_SRGB);
|
||||
Render( &World.Environment );
|
||||
|
||||
glUseProgram(World.shader);
|
||||
glEnable(GL_FRAMEBUFFER_SRGB);
|
||||
World.Ground.Render( World.Camera.Pos );
|
||||
Render( &World.Ground );
|
||||
|
||||
glDebug("rendering cab");
|
||||
World.Render_Cab();
|
||||
@@ -171,13 +188,20 @@ opengl_renderer::Render( world_environment *Environment ) {
|
||||
::glDisable( GL_DEPTH_TEST );
|
||||
::glDepthMask( GL_FALSE );
|
||||
::glPushMatrix();
|
||||
/*
|
||||
::glTranslatef( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z );
|
||||
|
||||
*/
|
||||
/*
|
||||
glm::mat4 worldcamera;
|
||||
World.Camera.SetMatrix( worldcamera );
|
||||
glLoadIdentity();
|
||||
glMultMatrixf( glm::value_ptr( glm::mat4( glm::mat3( worldcamera ) ) ) );
|
||||
*/
|
||||
// setup fog
|
||||
if( Global::fFogEnd > 0 ) {
|
||||
// fog setup
|
||||
::glFogfv( GL_FOG_COLOR, Global::FogColor );
|
||||
::glFogf( GL_FOG_DENSITY, 1.0f / Global::fFogEnd );
|
||||
::glFogf( GL_FOG_DENSITY, static_cast<GLfloat>( 1.0 / Global::fFogEnd ) );
|
||||
::glEnable( GL_FOG );
|
||||
}
|
||||
else { ::glDisable( GL_FOG ); }
|
||||
@@ -230,7 +254,7 @@ opengl_renderer::Render( world_environment *Environment ) {
|
||||
{
|
||||
Bind( m_moontextureid );
|
||||
float3 mooncolor( 255.0f / 255.0f, 242.0f / 255.0f, 231.0f / 255.0f );
|
||||
::glColor4f( mooncolor.x, mooncolor.y, mooncolor.z, 1.0f - Global::fLuminance * 0.5f );
|
||||
::glColor4f( mooncolor.x, mooncolor.y, mooncolor.z, static_cast<GLfloat>( 1.0 - Global::fLuminance * 0.5 ) );
|
||||
|
||||
auto const moonvector = Environment->m_moon.getDirection();
|
||||
auto const moonposition = modelview * glm::vec4( moonvector.x, moonvector.y, moonvector.z, 1.0f );
|
||||
@@ -284,14 +308,18 @@ opengl_renderer::Render( world_environment *Environment ) {
|
||||
bool
|
||||
opengl_renderer::Render( TGround *Ground ) {
|
||||
|
||||
glDisable( GL_BLEND );
|
||||
glAlphaFunc( GL_GREATER, 0.50f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
|
||||
glEnable( GL_LIGHTING );
|
||||
glColor3f( 1.0f, 1.0f, 1.0f );
|
||||
::glEnable( GL_LIGHTING );
|
||||
::glDisable( GL_BLEND );
|
||||
::glAlphaFunc( GL_GREATER, 0.50f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
|
||||
::glColor3f( 1.0f, 1.0f, 1.0f );
|
||||
|
||||
float3 const cameraposition = float3( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z );
|
||||
int const camerax = std::floor( cameraposition.x / 1000.0f ) + iNumRects / 2;
|
||||
int const cameraz = std::floor( cameraposition.z / 1000.0f ) + iNumRects / 2;
|
||||
++TGroundRect::iFrameNumber; // zwięszenie licznika ramek (do usuwniania nadanimacji)
|
||||
|
||||
Update_Lights( Ground->m_lights );
|
||||
/*
|
||||
glm::vec3 const cameraposition( Global::pCameraPosition.x, Global::pCameraPosition.y, Global::pCameraPosition.z );
|
||||
int const camerax = static_cast<int>( std::floor( cameraposition.x / 1000.0f ) + iNumRects / 2 );
|
||||
int const cameraz = static_cast<int>( std::floor( cameraposition.z / 1000.0f ) + iNumRects / 2 );
|
||||
int const segmentcount = 2 * static_cast<int>(std::ceil( m_drawrange * Global::fDistanceFactor / 1000.0f ));
|
||||
int const originx = std::max( 0, camerax - segmentcount / 2 );
|
||||
int const originz = std::max( 0, cameraz - segmentcount / 2 );
|
||||
@@ -299,34 +327,300 @@ opengl_renderer::Render( TGround *Ground ) {
|
||||
for( int column = originx; column <= originx + segmentcount; ++column ) {
|
||||
for( int row = originz; row <= originz + segmentcount; ++row ) {
|
||||
|
||||
auto &rectangle = Ground->Rects[ column ][ row ];
|
||||
if( m_camera.visible( rectangle.m_area ) ) {
|
||||
rectangle.RenderDL();
|
||||
auto *rectangle = &Ground->Rects[ column ][ row ];
|
||||
if( m_camera.visible( rectangle->m_area ) ) {
|
||||
Render( rectangle );
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
Ground->CameraDirection.x = std::sin( Global::pCameraRotation ); // wektor kierunkowy
|
||||
Ground->CameraDirection.z = std::cos( Global::pCameraRotation );
|
||||
TGroundNode *node;
|
||||
// rednerowanie globalnych (nie za często?)
|
||||
for( node = Ground->srGlobal.nRenderHidden; node; node = node->nNext3 ) {
|
||||
node->RenderHidden();
|
||||
}
|
||||
// renderowanie czołgowe dla obiektów aktywnych a niewidocznych
|
||||
int n = 2 * iNumSubRects; //(2*==2km) promień wyświetlanej mapy w sektorach
|
||||
int c = Ground->GetColFromX( Global::pCameraPosition.x );
|
||||
int r = Ground->GetRowFromZ( Global::pCameraPosition.z );
|
||||
TSubRect *tmp;
|
||||
int i, j, k;
|
||||
for( j = r - n; j <= r + n; j++ ) {
|
||||
for( i = c - n; i <= c + n; i++ ) {
|
||||
if( ( tmp = Ground->FastGetSubRect( i, j ) ) != nullptr ) {
|
||||
// oznaczanie aktywnych sektorów
|
||||
tmp->LoadNodes();
|
||||
|
||||
for( node = tmp->nRenderHidden; node; node = node->nNext3 ) {
|
||||
node->RenderHidden();
|
||||
}
|
||||
// jeszcze dźwięki pojazdów by się przydały, również niewidocznych
|
||||
tmp->RenderSounds();
|
||||
}
|
||||
}
|
||||
}
|
||||
// renderowanie progresywne - zależne od FPS oraz kierunku patrzenia
|
||||
// pre-calculate camera view span
|
||||
double const fieldofviewcosine =
|
||||
std::cos(
|
||||
std::max(
|
||||
// vertical...
|
||||
Global::FieldOfView / Global::ZoomFactor,
|
||||
// ...or horizontal, whichever is bigger
|
||||
Global::FieldOfView / Global::ZoomFactor
|
||||
* std::max( 1.0f, (float)Global::ScreenWidth ) / std::max( 1.0f, (float)Global::ScreenHeight ) ) );
|
||||
|
||||
Ground->iRendered = 0; // ilość renderowanych sektorów
|
||||
Math3D::vector3 direction;
|
||||
for( k = 0; k < Global::iSegmentsRendered; ++k ) // sektory w kolejności odległości
|
||||
{ // przerobione na użycie SectorOrder
|
||||
i = SectorOrder[ k ].x; // na starcie oba >=0
|
||||
j = SectorOrder[ k ].y;
|
||||
do {
|
||||
// pierwszy przebieg: j<=0, i>=0; drugi: j>=0, i<=0; trzeci: j<=0, i<=0 czwarty: j>=0, i>=0;
|
||||
if( j <= 0 )
|
||||
i = -i;
|
||||
j = -j; // i oraz j musi być zmienione wcześniej, żeby continue działało
|
||||
direction = Math3D::vector3( i, 0, j ); // wektor od kamery do danego sektora
|
||||
if( Math3D::LengthSquared3( direction ) > 5 ) // te blisko są zawsze wyświetlane
|
||||
{
|
||||
direction = Math3D::SafeNormalize( direction ); // normalizacja
|
||||
if( Ground->CameraDirection.x * direction.x + Ground->CameraDirection.z * direction.z < 0.5 )
|
||||
continue; // pomijanie sektorów poza kątem patrzenia
|
||||
}
|
||||
// kwadrat kilometrowy nie zawsze, bo szkoda FPS
|
||||
Render( &Ground->Rects[ ( i + c ) / iNumSubRects ][ ( j + r ) / iNumSubRects ] );
|
||||
|
||||
if( ( tmp = Ground->FastGetSubRect( i + c, j + r ) ) != nullptr ) {
|
||||
if( tmp->iNodeCount ) {
|
||||
// o ile są jakieś obiekty, bo po co puste sektory przelatywać
|
||||
Ground->pRendered[ Ground->iRendered++ ] = tmp; // tworzenie listy sektorów do renderowania
|
||||
}
|
||||
}
|
||||
} while( ( i < 0 ) || ( j < 0 ) ); // są 4 przypadki, oprócz i=j=0
|
||||
}
|
||||
// dodać renderowanie terenu z E3D - jedno VBO jest używane dla całego modelu, chyba że jest ich więcej
|
||||
if( Global::pTerrainCompact ) {
|
||||
Global::pTerrainCompact->TerrainRenderVBO( TGroundRect::iFrameNumber );
|
||||
}
|
||||
// renderowanie nieprzezroczystych
|
||||
for( i = 0; i < Ground->iRendered; ++i ) {
|
||||
Render( Ground->pRendered[ i ] );
|
||||
}
|
||||
// regular render takes care of all solid geometry present in the scene, thus we can launch alpha parts render here
|
||||
return Render_Alpha( Ground );
|
||||
}
|
||||
|
||||
// TODO: unify ground render code, until then old version is in place
|
||||
#define EU07_USE_OLD_RENDERCODE
|
||||
bool
|
||||
opengl_renderer::Render( TGroundRect *Groundcell ) {
|
||||
|
||||
::glPushMatrix();
|
||||
auto const &cellorigin = Groundcell->m_area.center;
|
||||
// TODO: unify all math objects
|
||||
auto const originoffset = Math3D::vector3( cellorigin.x, cellorigin.y, cellorigin.z ) - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
|
||||
bool result{ false }; // will be true if we do any rendering
|
||||
|
||||
// TODO: unify render paths
|
||||
|
||||
if ( Groundcell->iLastDisplay != Groundcell->iFrameNumber)
|
||||
{ // tylko jezeli dany kwadrat nie był jeszcze renderowany
|
||||
Groundcell->LoadNodes(); // ewentualne tworzenie siatek
|
||||
if ( Groundcell->nRenderRect && Groundcell->StartVBO())
|
||||
{
|
||||
for (TGroundNode *node = Groundcell->nRenderRect; node; node = node->nNext3) // następny tej grupy
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
node->RaRenderVBO(); // nieprzezroczyste trójkąty kwadratu kilometrowego
|
||||
#else
|
||||
Render( node ); // nieprzezroczyste trójkąty kwadratu kilometrowego
|
||||
#endif
|
||||
Groundcell->EndVBO();
|
||||
Groundcell->iLastDisplay = Groundcell->iFrameNumber;
|
||||
result = true;
|
||||
}
|
||||
if ( Groundcell->nTerrain)
|
||||
Groundcell->nTerrain->smTerrain->iVisible = Groundcell->iFrameNumber; // ma się wyświetlić w tej ramce
|
||||
}
|
||||
::glPopMatrix();
|
||||
|
||||
return result;
|
||||
}
|
||||
#undef EU07_USE_OLD_RENDERCODE
|
||||
|
||||
bool
|
||||
opengl_renderer::Render( TSubRect *Groundsubcell ) {
|
||||
|
||||
Groundsubcell->RaAnimate(); // przeliczenia animacji torów w sektorze
|
||||
|
||||
TGroundNode *node;
|
||||
// nieprzezroczyste obiekty terenu
|
||||
|
||||
// vbo render path
|
||||
if( Groundsubcell->StartVBO() ) {
|
||||
for( node = Groundsubcell->nRenderRect; node; node = node->nNext3 ) {
|
||||
if( node->iVboPtr >= 0 ) {
|
||||
Render( node );
|
||||
}
|
||||
}
|
||||
Groundsubcell->EndVBO();
|
||||
}
|
||||
|
||||
// nieprzezroczyste obiekty (oprócz pojazdów)
|
||||
for( node = Groundsubcell->nRender; node; node = node->nNext3 )
|
||||
Render( node );
|
||||
// nieprzezroczyste z mieszanych modeli
|
||||
for( node = Groundsubcell->nRenderMixed; node; node = node->nNext3 )
|
||||
Render( node );
|
||||
// nieprzezroczyste fragmenty pojazdów na torach
|
||||
for( int j = 0; j < Groundsubcell->iTracks; ++j )
|
||||
Groundsubcell->tTracks[ j ]->RenderDyn();
|
||||
#ifdef EU07_SCENERY_EDITOR
|
||||
// memcells
|
||||
if( DebugModeFlag ) {
|
||||
for( auto const memcell : m_memcells ) {
|
||||
memcell->RenderDL();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
opengl_renderer::Render( TGroundNode *Node ) {
|
||||
|
||||
Node->SetLastUsage( Timer::GetSimulationTime() );
|
||||
|
||||
switch (Node->iType)
|
||||
{ // obiekty renderowane niezależnie od odległości
|
||||
case TP_SUBMODEL:
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->pCenter - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
TSubModel::fSquareDist = 0;
|
||||
Render( Node->smTerrain );
|
||||
::glPopMatrix();
|
||||
return true;
|
||||
}
|
||||
|
||||
double const distancesquared = SquareMagnitude( ( Node->pCenter - Global::pCameraPosition ) / Global::ZoomFactor );
|
||||
if( ( distancesquared > ( Node->fSquareRadius * Global::fDistanceFactor ) )
|
||||
|| ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (Node->iType)
|
||||
{
|
||||
case TP_TRACK: {
|
||||
|
||||
if( ( Node->iNumVerts <= 0 ) ) {
|
||||
return false;
|
||||
}
|
||||
// setup
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
// vbo render path
|
||||
Node->pTrack->RaRenderVBO( Node->iVboPtr );
|
||||
|
||||
// post-render cleanup
|
||||
::glPopMatrix();
|
||||
return true;
|
||||
}
|
||||
case TP_MODEL: {
|
||||
Node->Model->Render( Node->pCenter - Global::pCameraPosition );
|
||||
return true;
|
||||
}
|
||||
case TP_MEMCELL: {
|
||||
GfxRenderer.Render( Node->MemCell );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: sprawdzic czy jest potrzebny warunek fLineThickness < 0
|
||||
if( ( Node->iFlags & 0x10 )
|
||||
|| ( Node->fLineThickness < 0 ) ) {
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
|
||||
if( ( Node->iType == GL_LINES )
|
||||
|| ( Node->iType == GL_LINE_STRIP )
|
||||
|| ( Node->iType == GL_LINE_LOOP ) ) {
|
||||
// wszelkie linie są rysowane na samym końcu
|
||||
if( Node->iNumPts ) {
|
||||
// setup
|
||||
// w zaleznosci od koloru swiatla
|
||||
::glColor4ub(
|
||||
static_cast<GLubyte>( std::floor( Node->Diffuse[ 0 ] * Global::daylight.ambient.x ) ),
|
||||
static_cast<GLubyte>( std::floor( Node->Diffuse[ 1 ] * Global::daylight.ambient.y ) ),
|
||||
static_cast<GLubyte>( std::floor( Node->Diffuse[ 2 ] * Global::daylight.ambient.z ) ),
|
||||
static_cast<GLubyte>( std::min( 255.0, 255000 * Node->fLineThickness / ( distancesquared + 1.0 ) ) ) );
|
||||
|
||||
GfxRenderer.Bind( 0 );
|
||||
|
||||
// render
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
::glDrawArrays( Node->iType, Node->iVboPtr, Node->iNumPts );
|
||||
::glPopMatrix();
|
||||
// post-render cleanup
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// GL_TRIANGLE etc
|
||||
if (Node->iVboPtr < 0) {
|
||||
return false;
|
||||
}
|
||||
// setup
|
||||
::glColor3ub(
|
||||
static_cast<GLubyte>( Node->Diffuse[ 0 ] ),
|
||||
static_cast<GLubyte>( Node->Diffuse[ 1 ] ),
|
||||
static_cast<GLubyte>( Node->Diffuse[ 2 ] ) );
|
||||
|
||||
Bind( Node->TextureID );
|
||||
|
||||
// render
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
// vbo render path
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
::glDrawArrays( Node->iType, Node->iVboPtr, Node->iNumVerts );
|
||||
::glPopMatrix();
|
||||
// post-render cleanup
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// in theory we shouldn't ever get here but, eh
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
|
||||
if( false == m_camera.visible( Dynamic ) ) {
|
||||
|
||||
Dynamic->renderme = false;
|
||||
Dynamic->renderme = m_camera.visible( Dynamic );
|
||||
if( false == Dynamic->renderme ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Dynamic->renderme = true;
|
||||
|
||||
// setup
|
||||
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
|
||||
double squaredistance = SquareMagnitude( ( Global::pCameraPosition - Dynamic->vPosition ) / Global::ZoomFactor );
|
||||
auto const originoffset = Dynamic->vPosition - Global::pCameraPosition;
|
||||
double const squaredistance = SquareMagnitude( originoffset / Global::ZoomFactor );
|
||||
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
|
||||
|
||||
::glPushMatrix();
|
||||
|
||||
/*
|
||||
if( Dynamic == Global::pUserDynamic ) {
|
||||
//specjalne ustawienie, aby nie trzęsło
|
||||
//tu trzeba by ustawić animacje na modelu zewnętrznym
|
||||
@@ -335,7 +629,8 @@ opengl_renderer::Render( TDynamicObject *Dynamic ) {
|
||||
}
|
||||
else
|
||||
::glTranslated( Dynamic->vPosition.x, Dynamic->vPosition.y, Dynamic->vPosition.z ); // standardowe przesunięcie względem początku scenerii
|
||||
|
||||
*/
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
::glMultMatrixd( Dynamic->mMatrix.getArray() );
|
||||
|
||||
if( Dynamic->fShade > 0.0f ) {
|
||||
@@ -434,7 +729,8 @@ opengl_renderer::Render( TModel3d *Model, material_data const *Material, Math3D:
|
||||
if( Angle.z != 0.0 )
|
||||
::glRotated( Angle.z, 0.0, 0.0, 1.0 );
|
||||
|
||||
auto const result = Render( Model, Material, SquareMagnitude( Position - Global::GetCameraPosition() ) );
|
||||
// auto const result = Render( Model, Material, SquareMagnitude( Position / Global::ZoomFactor ) ); // position is effectively camera offset
|
||||
auto const result = Render( Model, Material, SquareMagnitude( Position ) ); // position is effectively camera offset
|
||||
|
||||
::glPopMatrix();
|
||||
|
||||
@@ -512,7 +808,7 @@ opengl_renderer::Render( TSubModel *Submodel, glm::mat4 m) {
|
||||
float const anglefactor = ( Submodel->fCosViewAngle - Submodel->fCosFalloffAngle ) / ( 1.0f - Submodel->fCosFalloffAngle );
|
||||
// distance attenuation. NOTE: since it's fixed pipeline with built-in gamma correction we're using linear attenuation
|
||||
// we're capping how much effect the distance attenuation can have, otherwise the lights get too tiny at regular distances
|
||||
float const distancefactor = std::max( 0.5, ( Submodel->fSquareMaxDist - TSubModel::fSquareDist ) / ( Submodel->fSquareMaxDist * Global::fDistanceFactor ) );
|
||||
float const distancefactor = static_cast<float>( std::max( 0.5, ( Submodel->fSquareMaxDist - TSubModel::fSquareDist ) / ( Submodel->fSquareMaxDist * Global::fDistanceFactor ) ) );
|
||||
|
||||
if( lightlevel > 0.0f ) {
|
||||
glUseProgram(0);
|
||||
@@ -590,7 +886,226 @@ opengl_renderer::Render( TSubModel *Submodel, glm::mat4 m) {
|
||||
|
||||
if( Submodel->Next )
|
||||
if( Submodel->iAlpha & Submodel->iFlags & 0x1F000000 )
|
||||
Render( Submodel->Next, m ); // dalsze rekurencyjnie
|
||||
Render( Submodel->Next ); // dalsze rekurencyjnie
|
||||
}
|
||||
|
||||
void
|
||||
opengl_renderer::Render( TMemCell *Memcell ) {
|
||||
|
||||
::glPushAttrib( GL_ENABLE_BIT );
|
||||
// ::glDisable( GL_LIGHTING );
|
||||
::glDisable( GL_TEXTURE_2D );
|
||||
// ::glEnable( GL_BLEND );
|
||||
::glPushMatrix();
|
||||
|
||||
auto const position = Memcell->Position();
|
||||
::glTranslated( position.x, position.y + 0.5, position.z );
|
||||
::glColor3f( 0.36f, 0.75f, 0.35f );
|
||||
::gluSphere( m_quadric, 0.35, 4, 2 );
|
||||
|
||||
::glPopMatrix();
|
||||
::glPopAttrib();
|
||||
}
|
||||
|
||||
bool
|
||||
opengl_renderer::Render_Alpha( TGround *Ground ) {
|
||||
|
||||
// legacy version of the code:
|
||||
::glEnable( GL_BLEND );
|
||||
::glAlphaFunc( GL_GREATER, 0.04f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
|
||||
::glColor4f( 1.0f, 1.0f, 1.0f, 1.0f );
|
||||
|
||||
TGroundNode *node;
|
||||
TSubRect *tmp;
|
||||
// Ra: renderowanie progresywne - zależne od FPS oraz kierunku patrzenia
|
||||
for( int i = Ground->iRendered - 1; i >= 0; --i ) // od najdalszych
|
||||
{ // przezroczyste trójkąty w oddzielnym cyklu przed modelami
|
||||
tmp = Ground->pRendered[ i ];
|
||||
// vbo render path
|
||||
if( tmp->StartVBO() ) {
|
||||
for( node = tmp->nRenderRectAlpha; node; node = node->nNext3 ) {
|
||||
if( node->iVboPtr >= 0 ) {
|
||||
Render_Alpha( node );
|
||||
}
|
||||
}
|
||||
tmp->EndVBO();
|
||||
}
|
||||
}
|
||||
for( int i = Ground->iRendered - 1; i >= 0; --i ) // od najdalszych
|
||||
{ // renderowanie przezroczystych modeli oraz pojazdów
|
||||
Render_Alpha( Ground->pRendered[ i ] );
|
||||
}
|
||||
|
||||
::glDisable( GL_LIGHTING ); // linie nie powinny świecić
|
||||
|
||||
for( int i = Ground->iRendered - 1; i >= 0; --i ) // od najdalszych
|
||||
{ // druty na końcu, żeby się nie robiły białe plamy na tle lasu
|
||||
tmp = Ground->pRendered[ i ];
|
||||
// vbo render path
|
||||
if( tmp->StartVBO() ) {
|
||||
for( node = tmp->nRenderWires; node; node = node->nNext3 ) {
|
||||
Render_Alpha( node );
|
||||
}
|
||||
tmp->EndVBO();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
opengl_renderer::Render_Alpha( TSubRect *Groundsubcell ) {
|
||||
|
||||
TGroundNode *node;
|
||||
for( node = Groundsubcell->nRenderMixed; node; node = node->nNext3 )
|
||||
Render_Alpha( node ); // przezroczyste z mieszanych modeli
|
||||
for( node = Groundsubcell->nRenderAlpha; node; node = node->nNext3 )
|
||||
Render_Alpha( node ); // przezroczyste modele
|
||||
for( int j = 0; j < Groundsubcell->iTracks; ++j )
|
||||
Groundsubcell->tTracks[ j ]->RenderDynAlpha(); // przezroczyste fragmenty pojazdów na torach
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// NOTE: legacy render system switch
|
||||
#define _PROBLEND
|
||||
|
||||
bool
|
||||
opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
|
||||
// SPOSOB NA POZBYCIE SIE RAMKI DOOKOLA TEXTURY ALPHA DLA OBIEKTOW ZAGNIEZDZONYCH W SCN JAKO
|
||||
// NODE
|
||||
|
||||
// W GROUND.H dajemy do klasy TGroundNode zmienna bool PROBLEND to samo robimy w klasie TGround
|
||||
// nastepnie podczas wczytywania textury dla TRIANGLES w TGround::AddGroundNode
|
||||
// sprawdzamy czy w nazwie jest @ i wg tego
|
||||
// ustawiamy PROBLEND na true dla wlasnie wczytywanego trojkata (kazdy trojkat jest osobnym
|
||||
// nodem)
|
||||
// nastepnie podczas renderowania w bool TGroundNode::RenderAlpha()
|
||||
// na poczatku ustawiamy standardowe GL_GREATER = 0.04
|
||||
// pozniej sprawdzamy czy jest wlaczony PROBLEND dla aktualnie renderowanego noda TRIANGLE,
|
||||
// wlasciwie dla kazdego node'a
|
||||
// i jezeli tak to odpowiedni GL_GREATER w przeciwnym wypadku standardowy 0.04
|
||||
|
||||
Node->SetLastUsage( Timer::GetSimulationTime() );
|
||||
|
||||
double const distancesquared = SquareMagnitude( ( Node->pCenter - Global::pCameraPosition ) / Global::ZoomFactor );
|
||||
if( ( distancesquared > ( Node->fSquareRadius * Global::fDistanceFactor ) )
|
||||
|| ( distancesquared < ( Node->fSquareMinRadius / Global::fDistanceFactor ) ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (Node->iType)
|
||||
{
|
||||
case TP_TRACTION: {
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
if( Node->bVisible ) {
|
||||
// setup
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
// render
|
||||
Node->hvTraction->RenderVBO( distancesquared, Node->iVboPtr );
|
||||
// post-render cleanup
|
||||
::glPopMatrix();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
case TP_MODEL: {
|
||||
Node->Model->RenderAlpha( Node->pCenter - Global::pCameraPosition );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: sprawdzic czy jest potrzebny warunek fLineThickness < 0
|
||||
if( ( Node->iNumVerts && ( Node->iFlags & 0x20 ) )
|
||||
|| ( Node->iNumPts && ( Node->fLineThickness > 0 ) ) ) {
|
||||
|
||||
#ifdef _PROBLEND
|
||||
if( ( Node->PROBLEND ) ) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
|
||||
{
|
||||
::glDisable( GL_BLEND );
|
||||
::glAlphaFunc( GL_GREATER, 0.50f ); // im mniejsza wartość, tym większa ramka, domyślnie 0.1f
|
||||
};
|
||||
#endif
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
// additional setup for display lists
|
||||
if( ( Node->DisplayListID == 0 )
|
||||
|| ( Node->iVersion != Global::iReCompile ) ) { // Ra: wymuszenie rekompilacji
|
||||
Node->Compile(Node->m_rootposition);
|
||||
if( Global::bManageNodes )
|
||||
ResourceManager::Register( Node );
|
||||
};
|
||||
|
||||
bool result( false );
|
||||
|
||||
if( ( Node->iType == GL_LINES )
|
||||
|| ( Node->iType == GL_LINE_STRIP )
|
||||
|| ( Node->iType == GL_LINE_LOOP ) ) {
|
||||
// wszelkie linie są rysowane na samym końcu
|
||||
if( Node->iNumPts ) {
|
||||
// setup
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
// w zaleznosci od koloru swiatla
|
||||
::glColor4ub(
|
||||
static_cast<GLubyte>( std::floor( Node->Diffuse[ 0 ] * Global::daylight.ambient.x ) ),
|
||||
static_cast<GLubyte>( std::floor( Node->Diffuse[ 1 ] * Global::daylight.ambient.y ) ),
|
||||
static_cast<GLubyte>( std::floor( Node->Diffuse[ 2 ] * Global::daylight.ambient.z ) ),
|
||||
static_cast<GLubyte>( std::min( 255.0, 255000 * Node->fLineThickness / ( distancesquared + 1.0 ) ) ) );
|
||||
|
||||
GfxRenderer.Bind( 0 );
|
||||
|
||||
// render
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
::glDrawArrays( Node->iType, Node->iVboPtr, Node->iNumPts );
|
||||
// post-render cleanup
|
||||
::glPopMatrix();
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// GL_TRIANGLE etc
|
||||
// setup
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
|
||||
::glColor3ub(
|
||||
static_cast<GLubyte>( Node->Diffuse[ 0 ] ),
|
||||
static_cast<GLubyte>( Node->Diffuse[ 1 ] ),
|
||||
static_cast<GLubyte>( Node->Diffuse[ 2 ] ) );
|
||||
|
||||
Bind( Node->TextureID );
|
||||
|
||||
// render
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
|
||||
// vbo render path
|
||||
if( Node->iVboPtr >= 0 ) {
|
||||
::glDrawArrays( Node->iType, Node->iVboPtr, Node->iNumVerts );
|
||||
result = true;
|
||||
}
|
||||
|
||||
// post-render cleanup
|
||||
::glPopMatrix();
|
||||
}
|
||||
|
||||
#ifdef _PROBLEND
|
||||
if( ( Node->PROBLEND ) ) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
|
||||
{
|
||||
::glEnable( GL_BLEND );
|
||||
::glAlphaFunc( GL_GREATER, 0.04f );
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
// in theory we shouldn't ever get here but, eh
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
@@ -603,17 +1118,19 @@ opengl_renderer::Render_Alpha( TDynamicObject *Dynamic ) {
|
||||
|
||||
// setup
|
||||
TSubModel::iInstance = ( size_t )this; //żeby nie robić cudzych animacji
|
||||
double squaredistance = SquareMagnitude( ( Global::pCameraPosition - Dynamic->vPosition ) / Global::ZoomFactor );
|
||||
auto const originoffset = Dynamic->vPosition - Global::pCameraPosition;
|
||||
double const squaredistance = SquareMagnitude( originoffset / Global::ZoomFactor );
|
||||
Dynamic->ABuLittleUpdate( squaredistance ); // ustawianie zmiennych submodeli dla wspólnego modelu
|
||||
|
||||
::glPushMatrix();
|
||||
/*
|
||||
if( Dynamic == Global::pUserDynamic ) { // specjalne ustawienie, aby nie trzęsło
|
||||
::glLoadIdentity(); // zacząć od macierzy jedynkowej
|
||||
Global::pCamera->SetCabMatrix( Dynamic->vPosition ); // specjalne ustawienie kamery
|
||||
}
|
||||
else
|
||||
::glTranslated( Dynamic->vPosition.x, Dynamic->vPosition.y, Dynamic->vPosition.z ); // standardowe przesunięcie względem początku scenerii
|
||||
|
||||
*/
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
::glMultMatrixd( Dynamic->mMatrix.getArray() );
|
||||
|
||||
if( Dynamic->fShade > 0.0f ) {
|
||||
@@ -711,7 +1228,8 @@ opengl_renderer::Render_Alpha( TModel3d *Model, material_data const *Material, M
|
||||
if( Angle.z != 0.0 )
|
||||
::glRotated( Angle.z, 0.0, 0.0, 1.0 );
|
||||
|
||||
auto const result = Render_Alpha( Model, Material, SquareMagnitude( Position - Global::GetCameraPosition() ) );
|
||||
// auto const result = Render_Alpha( Model, Material, SquareMagnitude( Position / Global::ZoomFactor ) ); // position is effectively camera offset
|
||||
auto const result = Render_Alpha( Model, Material, SquareMagnitude( Position ) ); // position is effectively camera offset
|
||||
|
||||
::glPopMatrix();
|
||||
|
||||
@@ -849,9 +1367,9 @@ opengl_renderer::Update ( double const Deltatime ) {
|
||||
int targetsegments;
|
||||
float targetfactor;
|
||||
|
||||
if( framerate > 65.0 ) { targetsegments = 400; targetfactor = 3.0f; }
|
||||
else if( framerate > 40.0 ) { targetsegments = 225; targetfactor = 1.5f; }
|
||||
else if( framerate > 15.0 ) { targetsegments = 90; targetfactor = Global::ScreenHeight / 768.0f; }
|
||||
if( framerate > 90.0 ) { targetsegments = 400; targetfactor = 3.0f; }
|
||||
else if( framerate > 60.0 ) { targetsegments = 225; targetfactor = 1.5f; }
|
||||
else if( framerate > 30.0 ) { targetsegments = 90; targetfactor = Global::ScreenHeight / 768.0f; }
|
||||
else { targetsegments = 9; targetfactor = Global::ScreenHeight / 768.0f * 0.75f; }
|
||||
|
||||
if( targetsegments > Global::iSegmentsRendered ) {
|
||||
|
||||
27
renderer.h
27
renderer.h
@@ -14,6 +14,8 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "lightarray.h"
|
||||
#include "dumb3d.h"
|
||||
#include "frustum.h"
|
||||
#include "world.h"
|
||||
#include "memcell.h"
|
||||
#include "ground.h"
|
||||
#include "shader.h"
|
||||
#include "World.h"
|
||||
@@ -42,7 +44,7 @@ public:
|
||||
update_frustum() { m_frustum.calculate(); }
|
||||
inline
|
||||
void
|
||||
update_frustum(glm::mat4 &Projection, glm::mat4 &Modelview) { m_frustum.calculate(Projection, Modelview); }
|
||||
update_frustum(glm::mat4 const &Projection, glm::mat4 const &Modelview) { m_frustum.calculate(Projection, Modelview); }
|
||||
bool
|
||||
visible( bounding_area const &Area ) const;
|
||||
bool
|
||||
@@ -59,6 +61,9 @@ class opengl_renderer {
|
||||
public:
|
||||
// types
|
||||
|
||||
// destructor
|
||||
~opengl_renderer() { gluDeleteQuadric( m_quadric ); }
|
||||
|
||||
// methods
|
||||
bool
|
||||
Init( GLFWwindow *Window );
|
||||
@@ -69,6 +74,12 @@ public:
|
||||
Render( world_environment *Environment );
|
||||
bool
|
||||
Render( TGround *Ground );
|
||||
bool
|
||||
Render( TGroundRect *Groundcell );
|
||||
bool
|
||||
Render( TSubRect *Groundsubcell );
|
||||
bool
|
||||
Render( TGroundNode *Node );
|
||||
bool
|
||||
Render( TDynamicObject *Dynamic );
|
||||
bool
|
||||
@@ -76,9 +87,17 @@ public:
|
||||
bool
|
||||
Render( TModel3d *Model, material_data const *Material, Math3D::vector3 const &Position, Math3D::vector3 const &Angle );
|
||||
void
|
||||
Render( TSubModel *Submodel, glm::mat4 m );
|
||||
void Render(TSubModel *Submodel);
|
||||
Render( TSubModel *Submodel );
|
||||
void Render(TSubModel *Submodel, glm::mat4 m);
|
||||
void Render_Alpha(TSubModel *Submodel);
|
||||
void
|
||||
Render( TMemCell *Memcell );
|
||||
bool
|
||||
Render_Alpha( TGround *Ground );
|
||||
bool
|
||||
Render_Alpha( TSubRect *Groundsubcell );
|
||||
bool
|
||||
Render_Alpha( TGroundNode *Node );
|
||||
bool
|
||||
Render_Alpha( TDynamicObject *Dynamic );
|
||||
bool
|
||||
@@ -144,6 +163,8 @@ private:
|
||||
texture_manager::size_type m_glaretextureid{ -1 };
|
||||
texture_manager::size_type m_suntextureid{ -1 };
|
||||
texture_manager::size_type m_moontextureid{ -1 };
|
||||
GLUquadricObj *m_quadric; // helper object for drawing debug mode scene elements
|
||||
|
||||
};
|
||||
|
||||
extern opengl_renderer GfxRenderer;
|
||||
|
||||
27
sky.cpp
27
sky.cpp
@@ -31,39 +31,18 @@ void TSky::Render( float3 const &Tint )
|
||||
{
|
||||
if (mdCloud)
|
||||
{ // jeśli jest model nieba
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
// TODO: re-implement this
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
|
||||
#else
|
||||
// setup
|
||||
::glEnable( GL_LIGHTING );
|
||||
GfxRenderer.Disable_Lights();
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &Tint.x );
|
||||
#endif
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
if( Global::bUseVBO )
|
||||
{ // renderowanie z VBO
|
||||
mdCloud->RaRender( 100, 0 );
|
||||
mdCloud->RaRenderAlpha(100, 0);
|
||||
}
|
||||
else
|
||||
{ // renderowanie z Display List
|
||||
mdCloud->Render(100, 0);
|
||||
mdCloud->RenderAlpha(100, 0);
|
||||
}
|
||||
#else
|
||||
// render
|
||||
GfxRenderer.Render( mdCloud, nullptr, 100.0 );
|
||||
GfxRenderer.Render_Alpha( mdCloud, nullptr, 100.0 );
|
||||
#endif
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
glPopMatrix();
|
||||
// TODO: re-implement this
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, Global::lightPos);
|
||||
#else
|
||||
// post-render cleanup
|
||||
GLfloat noambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, noambient );
|
||||
::glEnable( GL_LIGHT0 ); // other lights will be enabled during lights update
|
||||
::glDisable( GL_LIGHTING );
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
13
stars.cpp
13
stars.cpp
@@ -14,23 +14,16 @@ cStars::init() {
|
||||
|
||||
void
|
||||
cStars::render() {
|
||||
|
||||
// setup
|
||||
::glPushMatrix();
|
||||
|
||||
::glRotatef( m_latitude, 1.0f, 0.0f, 0.0f ); // ustawienie osi OY na północ
|
||||
::glRotatef( -std::fmod( (float)Global::fTimeAngleDeg, 360.0f ), 0.0f, 1.0f, 0.0f ); // obrót dobowy osi OX
|
||||
|
||||
::glPointSize( 2.0f );
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
if( Global::bUseVBO ) {
|
||||
m_stars.RaRender( 1.0, 0 );
|
||||
}
|
||||
else {
|
||||
m_stars.Render( 1.0 );
|
||||
}
|
||||
#else
|
||||
// render
|
||||
GfxRenderer.Render( &m_stars, nullptr, 1.0 );
|
||||
#endif
|
||||
// post-render cleanup
|
||||
::glPointSize( 3.0f );
|
||||
|
||||
::glPopMatrix();
|
||||
|
||||
2
sun.cpp
2
sun.cpp
@@ -258,8 +258,6 @@ void cSun::irradiance() {
|
||||
static double degrad = 57.295779513; // converts from radians to degrees
|
||||
static double raddeg = 0.0174532925; // converts from degrees to radians
|
||||
|
||||
auto const &localtime = simulation::Time.data(); // time for the calculation
|
||||
|
||||
m_body.dayang = ( simulation::Time.year_day() - 1 ) * 360.0 / 365.0;
|
||||
double sd = sin( raddeg * m_body.dayang ); // sine of the day angle
|
||||
double cd = cos( raddeg * m_body.dayang ); // cosine of the day angle or delination
|
||||
|
||||
@@ -150,7 +150,7 @@ ui_layer::render_panels() {
|
||||
glPushAttrib( GL_ENABLE_BIT );
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
|
||||
float const width = std::min( 4.0f / 3.0f, static_cast<float>(Global::iWindowWidth) / Global::iWindowHeight ) * Global::iWindowHeight;
|
||||
float const width = std::min( 4.0f / 3.0f, static_cast<float>(Global::iWindowWidth) / std::max( 1, Global::iWindowHeight ) ) * Global::iWindowHeight;
|
||||
float const height = Global::iWindowHeight / 768.0;
|
||||
|
||||
for( auto const &panel : m_panels ) {
|
||||
|
||||
24
usefull.h
24
usefull.h
@@ -11,17 +11,6 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#define SafeDelete(a) \
|
||||
{ \
|
||||
delete (a); \
|
||||
a = nullptr; \
|
||||
}
|
||||
#define SafeDeleteArray(a) \
|
||||
{ \
|
||||
delete[](a); \
|
||||
a = nullptr; \
|
||||
}
|
||||
|
||||
#define sign(x) ((x) < 0 ? -1 : ((x) > 0 ? 1 : 0))
|
||||
|
||||
#define DegToRad(a) ((M_PI / 180.0) * (a)) //(a) w nawiasie, bo może być dodawaniem
|
||||
@@ -31,9 +20,22 @@ http://mozilla.org/MPL/2.0/.
|
||||
#define asSceneryPath std::string("scenery\\")
|
||||
#define szSceneryPath "scenery\\"
|
||||
#define szTexturePath "textures\\"
|
||||
#define szSoundPath "sounds\\"
|
||||
|
||||
#define MAKE_ID4(a,b,c,d) (((std::uint32_t)(d)<<24)|((std::uint32_t)(c)<<16)|((std::uint32_t)(b)<<8)|(std::uint32_t)(a))
|
||||
|
||||
template <typename _Type>
|
||||
void SafeDelete( _Type &Pointer ) {
|
||||
delete Pointer;
|
||||
Pointer = nullptr;
|
||||
}
|
||||
|
||||
template <typename _Type>
|
||||
void SafeDeleteArray( _Type &Pointer ) {
|
||||
delete[] Pointer;
|
||||
Pointer = nullptr;
|
||||
}
|
||||
|
||||
template <typename _Type>
|
||||
_Type
|
||||
clamp( _Type const Value, _Type const Min, _Type const Max ) {
|
||||
|
||||
5
version.h
Normal file
5
version.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#define VERSION_MAJOR 17
|
||||
#define VERSION_MINOR 602
|
||||
#define VERSION_REVISION 0
|
||||
37
wavread.cpp
37
wavread.cpp
@@ -17,26 +17,7 @@ http://mozilla.org/MPL/2.0/.
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "stdafx.h"
|
||||
#include "WavRead.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Defines, constants, and global variables
|
||||
//-----------------------------------------------------------------------------
|
||||
#define SAFE_DELETE(p) \
|
||||
{ \
|
||||
if (p) \
|
||||
{ \
|
||||
delete (p); \
|
||||
(p) = NULL; \
|
||||
} \
|
||||
}
|
||||
#define SAFE_RELEASE(p) \
|
||||
{ \
|
||||
if (p) \
|
||||
{ \
|
||||
(p)->Release(); \
|
||||
(p) = NULL; \
|
||||
} \
|
||||
}
|
||||
#include "usefull.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: ReadMMIO()
|
||||
@@ -122,13 +103,13 @@ HRESULT ReadMMIO(HMMIO hmmioIn, MMCKINFO *pckInRIFF, WAVEFORMATEX **ppwfxInfo)
|
||||
// so the data can be easily read with WaveReadFile. Returns 0 if
|
||||
// successful, the error code if not.
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT WaveOpenFile(CHAR *strFileName, HMMIO *phmmioIn, WAVEFORMATEX **ppwfxInfo,
|
||||
HRESULT WaveOpenFile( std::string const &Filename, HMMIO *phmmioIn, WAVEFORMATEX **ppwfxInfo,
|
||||
MMCKINFO *pckInRIFF)
|
||||
{
|
||||
HRESULT hr;
|
||||
HMMIO hmmioIn = NULL;
|
||||
|
||||
if (NULL == (hmmioIn = mmioOpen(strFileName, NULL, MMIO_ALLOCBUF | MMIO_READ)))
|
||||
if (NULL == (hmmioIn = mmioOpen(const_cast<char*>(Filename.c_str()), NULL, MMIO_ALLOCBUF | MMIO_READ)))
|
||||
return E_FAIL;
|
||||
|
||||
if (FAILED(hr = ReadMMIO(hmmioIn, pckInRIFF, ppwfxInfo)))
|
||||
@@ -228,20 +209,20 @@ CWaveSoundRead::CWaveSoundRead()
|
||||
CWaveSoundRead::~CWaveSoundRead()
|
||||
{
|
||||
Close();
|
||||
SAFE_DELETE(m_pwfx);
|
||||
SafeDelete(m_pwfx);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Name: Open()
|
||||
// Desc: Opens a wave file for reading
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CWaveSoundRead::Open(CHAR *strFilename)
|
||||
HRESULT CWaveSoundRead::Open(std::string const &Filename)
|
||||
{
|
||||
SAFE_DELETE(m_pwfx);
|
||||
SafeDelete(m_pwfx);
|
||||
|
||||
HRESULT hr;
|
||||
|
||||
if (FAILED(hr = WaveOpenFile(strFilename, &m_hmmioIn, &m_pwfx, &m_ckInRiff)))
|
||||
if (FAILED(hr = WaveOpenFile(Filename, &m_hmmioIn, &m_pwfx, &m_ckInRiff)))
|
||||
return hr;
|
||||
|
||||
if (FAILED(hr = Reset()))
|
||||
@@ -276,6 +257,8 @@ HRESULT CWaveSoundRead::Read(UINT nSizeToRead, BYTE *pbData, UINT *pnSizeRead)
|
||||
//-----------------------------------------------------------------------------
|
||||
HRESULT CWaveSoundRead::Close()
|
||||
{
|
||||
mmioClose(m_hmmioIn, 0);
|
||||
if( m_hmmioIn != NULL ) {
|
||||
mmioClose( m_hmmioIn, 0 );
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
12
wavread.h
12
wavread.h
@@ -15,12 +15,12 @@ http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) 1999 Microsoft Corp. All rights reserved.
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef WAVE_READ_H
|
||||
#define WAVE_READ_H
|
||||
#pragma once
|
||||
|
||||
#include <mmsystem.h>
|
||||
#include <string>
|
||||
|
||||
HRESULT WaveOpenFile(CHAR *strFileName, HMMIO *phmmioIn, WAVEFORMATEX **ppwfxInfo,
|
||||
HRESULT WaveOpenFile(std::string const &Filename, HMMIO *phmmioIn, WAVEFORMATEX **ppwfxInfo,
|
||||
MMCKINFO *pckInRIFF);
|
||||
HRESULT WaveStartDataRead(HMMIO *phmmioIn, MMCKINFO *pckIn, MMCKINFO *pckInRIFF);
|
||||
HRESULT WaveReadFile(HMMIO hmmioIn, UINT cbRead, BYTE *pbDest, MMCKINFO *pckIn, UINT *cbActualRead);
|
||||
@@ -33,7 +33,7 @@ class CWaveSoundRead
|
||||
{
|
||||
public:
|
||||
WAVEFORMATEX *m_pwfx; // Pointer to WAVEFORMATEX structure
|
||||
HMMIO m_hmmioIn; // MM I/O handle for the WAVE
|
||||
HMMIO m_hmmioIn{ NULL }; // MM I/O handle for the WAVE
|
||||
MMCKINFO m_ckIn; // Multimedia RIFF chunk
|
||||
MMCKINFO m_ckInRiff; // Use in opening a WAVE file
|
||||
|
||||
@@ -41,10 +41,8 @@ class CWaveSoundRead
|
||||
CWaveSoundRead();
|
||||
~CWaveSoundRead();
|
||||
|
||||
HRESULT Open(CHAR *strFilename);
|
||||
HRESULT Open(std::string const &Filename);
|
||||
HRESULT Reset();
|
||||
HRESULT Read(UINT nSizeToRead, BYTE *pbData, UINT *pnSizeRead);
|
||||
HRESULT Close();
|
||||
};
|
||||
|
||||
#endif WAVE_READ_H
|
||||
|
||||
Reference in New Issue
Block a user