mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-10-22 16:43:21 +02:00
Merge remote-tracking branch 'tmj-fstate/mover_in_c++' into mover_in_c++
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();
|
||||
|
||||
233
Driver.cpp
233
Driver.cpp
@@ -469,6 +469,16 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
|
||||
}
|
||||
else {
|
||||
if( iTableDirection == 0 ) { return; }
|
||||
// NOTE: provisory fix for BUG: sempahor indices no longer matching table size
|
||||
// TODO: find and really fix the reason it happens
|
||||
if( ( SemNextIndex != -1 )
|
||||
&& ( SemNextIndex >= sSpeedTable.size() ) ) {
|
||||
SemNextIndex = -1;
|
||||
}
|
||||
if( ( SemNextStopIndex != -1 )
|
||||
&& ( SemNextStopIndex >= sSpeedTable.size() ) ) {
|
||||
SemNextStopIndex = -1;
|
||||
}
|
||||
// kontynuacja skanowania od ostatnio sprawdzonego toru (w ostatniej pozycji zawsze jest tor)
|
||||
if( ( SemNextStopIndex != -1 )
|
||||
&& ( sSpeedTable[SemNextStopIndex].fVelNext < 1.0 ) ) {
|
||||
@@ -512,11 +522,6 @@ void TController::TableTraceRoute(double fDistance, TDynamicObject *pVehicle)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef EU07_USE_OLD_SPEEDTABLE
|
||||
// jak coś się znajdzie, zostanie wpisane w tę pozycję, którą właśnie odczytano
|
||||
--iLast;
|
||||
#endif
|
||||
|
||||
while (fCurrentDistance < fDistance)
|
||||
{
|
||||
if (pTrack != tLast) // ostatni zapisany w tabelce nie był jeszcze sprawdzony
|
||||
@@ -869,8 +874,9 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
||||
// if (p7&3) //żeby jeszcze poczekał chwilę, zanim zamknie
|
||||
// WaitingSet(10); //10 sekund (wziąć z rozkładu????)
|
||||
}
|
||||
if (fStopTime > -5) // na końcu rozkładu się ustawia 60s i tu by było skrócenie
|
||||
WaitingSet(10); // 10 sekund (wziąć z rozkładu????) - czekanie
|
||||
|
||||
if( fStopTime > -5 ) // na końcu rozkładu się ustawia 60s i tu by było skrócenie
|
||||
WaitingSet( 15.0 + Random( 15.0 ) ); // 10 sekund (wziąć z rozkładu????) - czekanie
|
||||
// niezależne od sposobu obsługi drzwi, bo opóźnia również kierownika
|
||||
}
|
||||
if (TrainParams->UpdateMTable( simulation::Time, asNextStop) )
|
||||
@@ -980,11 +986,10 @@ TCommandType TController::TableUpdate(double &fVelDes, double &fDist, double &fN
|
||||
sSpeedTable[i].fVelNext = -1; // można jechać za W4
|
||||
fLastStopExpDist = -1.0f; // nie ma rozkładu, nie ma usuwania stacji
|
||||
WaitingSet(60); // tak ze 2 minuty, aż wszyscy wysiądą
|
||||
JumpToNextOrder(); // wykonanie kolejnego rozkazu (Change_direction
|
||||
// albo Shunt)
|
||||
iDrivigFlags |= moveStopHere | moveStartHorn; // ma się nie ruszać
|
||||
// aż do momentu
|
||||
// podania sygnału
|
||||
// wykonanie kolejnego rozkazu (Change_direction albo Shunt)
|
||||
JumpToNextOrder();
|
||||
// ma się nie ruszać aż do momentu podania sygnału
|
||||
iDrivigFlags |= moveStopHere | moveStartHorn;
|
||||
continue; // nie analizować prędkości
|
||||
} // koniec obsługi ostatniej stacji
|
||||
} // if (MoverParameters->Vel==0.0)
|
||||
@@ -1340,7 +1345,6 @@ void TController::TablePurger()
|
||||
// we can only update pointers safely after new table is finalized, so record their indices until then
|
||||
for( std::size_t idx = 0; idx < sSpeedTable.size() - 1; ++idx ) {
|
||||
// cache placement of semaphors in the new table, if we encounter them
|
||||
// NOTE: we rely on the semaphor actually getting added in the next step rather than skipped, but it's a pretty safe bet
|
||||
if( idx == SemNextIndex ) {
|
||||
SemNextIndex = trimmedtable.size();
|
||||
}
|
||||
@@ -1351,6 +1355,13 @@ void TController::TablePurger()
|
||||
if( ( 0 == ( speedpoint.iFlags & spEnabled ) )
|
||||
|| ( ( speedpoint.iFlags & ( spElapsed | spTrack | spCurve | spSwitch ) == ( spElapsed | spTrack | spCurve ) )
|
||||
&& ( speedpoint.fVelNext < 0.0 ) ) ) {
|
||||
// if the trimmed point happens to be currently active semaphor we need to invalidate their placements
|
||||
if( idx == SemNextIndex ) {
|
||||
SemNextIndex = -1;
|
||||
}
|
||||
if( idx == SemNextStopIndex ) {
|
||||
SemNextStopIndex = -1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// we're left with useful speed point record we should copy
|
||||
@@ -2246,76 +2257,79 @@ bool TController::ReleaseEngine()
|
||||
bool TController::IncBrake()
|
||||
{ // zwiększenie hamowania
|
||||
bool OK = false;
|
||||
switch (mvOccupied->BrakeSystem)
|
||||
{
|
||||
case Individual:
|
||||
if (mvOccupied->LocalBrake == ManualBrake)
|
||||
OK = mvOccupied->IncManualBrakeLevel( 1 + static_cast<int>( std::floor( 0.5 + std::fabs(AccDesired))) );
|
||||
else
|
||||
OK = mvOccupied->IncLocalBrakeLevel( std::floor( 1.5 + std::abs( AccDesired ) ) );
|
||||
break;
|
||||
case Pneumatic:
|
||||
// NOTE: can't perform just test whether connected vehicle == nullptr, due to virtual couplers formed with nearby vehicles
|
||||
if ((mvOccupied->Couplers[0].CouplingFlag == 0) &&
|
||||
(mvOccupied->Couplers[1].CouplingFlag == 0))
|
||||
OK = mvOccupied->IncLocalBrakeLevel(
|
||||
1 + static_cast<int>( std::floor( 0.5 + std::fabs(AccDesired))) ); // hamowanie lokalnym bo luzem jedzie
|
||||
else
|
||||
{
|
||||
if (mvOccupied->BrakeCtrlPos + 1 == mvOccupied->BrakeCtrlPosNo)
|
||||
{
|
||||
if (AccDesired < -1.5) // hamowanie nagle
|
||||
OK = mvOccupied->IncBrakeLevel();
|
||||
else
|
||||
OK = false;
|
||||
switch( mvOccupied->BrakeSystem ) {
|
||||
case Individual: {
|
||||
if( mvOccupied->LocalBrake == ManualBrake ) {
|
||||
OK = mvOccupied->IncManualBrakeLevel( 1 + static_cast<int>( std::floor( 0.5 + std::fabs( AccDesired ) ) ) );
|
||||
}
|
||||
else {
|
||||
OK = mvOccupied->IncLocalBrakeLevel( std::floor( 1.5 + std::abs( AccDesired ) ) );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Pneumatic: {
|
||||
// NOTE: can't perform just test whether connected vehicle == nullptr, due to virtual couplers formed with nearby vehicles
|
||||
bool standalone{ true };
|
||||
if( ( mvOccupied->TrainType == dt_ET41 )
|
||||
|| ( mvOccupied->TrainType == dt_ET42 ) ) {
|
||||
// NOTE: we're doing simplified checks full of presuptions here.
|
||||
// they'll break if someone does strange thing like turning around the second unit
|
||||
if( ( mvOccupied->Couplers[ 1 ].CouplingFlag & coupling::permanent )
|
||||
&& ( mvOccupied->Couplers[ 1 ].Connected->Couplers[ 1 ].CouplingFlag > 0 ) ) {
|
||||
standalone = false;
|
||||
}
|
||||
if( ( mvOccupied->Couplers[ 0 ].CouplingFlag & coupling::permanent )
|
||||
&& ( mvOccupied->Couplers[ 0 ].Connected->Couplers[ 0 ].CouplingFlag > 0 ) ) {
|
||||
standalone = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
standalone =
|
||||
( ( mvOccupied->Couplers[ 0 ].CouplingFlag == 0 )
|
||||
&& ( mvOccupied->Couplers[ 1 ].CouplingFlag == 0 ) );
|
||||
}
|
||||
if( true == standalone ) {
|
||||
OK = mvOccupied->IncLocalBrakeLevel(
|
||||
1 + static_cast<int>( std::floor( 0.5 + std::fabs( AccDesired ) ) ) ); // hamowanie lokalnym bo luzem jedzie
|
||||
}
|
||||
else {
|
||||
if( mvOccupied->BrakeCtrlPos + 1 == mvOccupied->BrakeCtrlPosNo ) {
|
||||
if( AccDesired < -1.5 ) // hamowanie nagle
|
||||
OK = mvOccupied->IncBrakeLevel();
|
||||
else
|
||||
OK = false;
|
||||
}
|
||||
else {
|
||||
// dodane dla towarowego
|
||||
if( mvOccupied->BrakeDelayFlag == bdelay_G ?
|
||||
-AccDesired * 6.6 > std::min( 2, mvOccupied->BrakeCtrlPos ) :
|
||||
true ) {
|
||||
OK = mvOccupied->IncBrakeLevel();
|
||||
}
|
||||
else
|
||||
OK = false;
|
||||
}
|
||||
}
|
||||
if( mvOccupied->BrakeCtrlPos > 0 ) {
|
||||
mvOccupied->BrakeReleaser( 0 );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ElectroPneumatic: {
|
||||
if( mvOccupied->EngineType == ElectricInductionMotor ) {
|
||||
OK = mvOccupied->IncLocalBrakeLevel( 1 );
|
||||
}
|
||||
else if( mvOccupied->fBrakeCtrlPos != mvOccupied->Handle->GetPos( bh_EPB ) ) {
|
||||
mvOccupied->BrakeLevelSet( mvOccupied->Handle->GetPos( bh_EPB ) );
|
||||
if( mvOccupied->Handle->GetPos( bh_EPR ) - mvOccupied->Handle->GetPos( bh_EPN ) < 0.1 )
|
||||
mvOccupied->SwitchEPBrake( 1 ); // to nie chce działać
|
||||
OK = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
if (AccDesired>-0.2) and ((Vel<20) or (Vel-VelNext<10)))
|
||||
begin
|
||||
if BrakeCtrlPos>0)
|
||||
OK:=IncBrakeLevel
|
||||
else;
|
||||
OK:=IncLocalBrakeLevel(1); //finezyjne hamowanie lokalnym
|
||||
end
|
||||
else
|
||||
*/
|
||||
// dodane dla towarowego
|
||||
if (mvOccupied->BrakeDelayFlag == bdelay_G ?
|
||||
-AccDesired * 6.6 > std::min(2, mvOccupied->BrakeCtrlPos) :
|
||||
true)
|
||||
{
|
||||
OK = mvOccupied->IncBrakeLevel();
|
||||
}
|
||||
else
|
||||
OK = false;
|
||||
}
|
||||
OK = false;
|
||||
break;
|
||||
}
|
||||
if (mvOccupied->BrakeCtrlPos > 0)
|
||||
mvOccupied->BrakeReleaser(0);
|
||||
break;
|
||||
case ElectroPneumatic:
|
||||
if (mvOccupied->EngineType == ElectricInductionMotor)
|
||||
{
|
||||
OK = mvOccupied->IncLocalBrakeLevel(1);
|
||||
}
|
||||
else if (mvOccupied->fBrakeCtrlPos != mvOccupied->Handle->GetPos(bh_EPB))
|
||||
{
|
||||
mvOccupied->BrakeLevelSet(mvOccupied->Handle->GetPos(bh_EPB));
|
||||
if (mvOccupied->Handle->GetPos(bh_EPR) - mvOccupied->Handle->GetPos(bh_EPN) < 0.1)
|
||||
mvOccupied->SwitchEPBrake(1); // to nie chce działać
|
||||
OK = true;
|
||||
}
|
||||
else
|
||||
OK = false;
|
||||
// if (mvOccupied->BrakeCtrlPos<mvOccupied->BrakeCtrlPosNo)
|
||||
// if
|
||||
// (mvOccupied->BrakePressureTable[mvOccupied->BrakeCtrlPos+1+2].BrakeType==ElectroPneumatic)
|
||||
// //+2 to indeks Pascala
|
||||
// OK=mvOccupied->IncBrakeLevel();
|
||||
// else
|
||||
// OK=false;
|
||||
default: { break; }
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
@@ -3367,8 +3381,8 @@ bool TController::UpdateSituation(double dt)
|
||||
}
|
||||
ElapsedTime += dt;
|
||||
WaitingTime += dt;
|
||||
fBrakeTime -=
|
||||
dt; // wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca
|
||||
// wpisana wartość jest zmniejszana do 0, gdy ujemna należy zmienić nastawę hamulca
|
||||
fBrakeTime -= dt;
|
||||
fStopTime += dt; // zliczanie czasu postoju, nie ruszy dopóki ujemne
|
||||
fActionTime += dt; // czas używany przy regulacji prędkości i zamykaniu drzwi
|
||||
if (WriteLogFlag)
|
||||
@@ -3386,7 +3400,7 @@ bool TController::UpdateSituation(double dt)
|
||||
LastUpdatedTime = LastUpdatedTime + dt;
|
||||
}
|
||||
// Ra: skanowanie również dla prowadzonego ręcznie, aby podpowiedzieć prędkość
|
||||
if ((LastReactionTime > Min0R(ReactionTime, 2.0)))
|
||||
if ((LastReactionTime > std::min(ReactionTime, 2.0)))
|
||||
{
|
||||
// Ra: nie wiem czemu ReactionTime potrafi dostać 12 sekund, to jest przegięcie, bo przeżyna
|
||||
// STÓJ
|
||||
@@ -3431,18 +3445,48 @@ bool TController::UpdateSituation(double dt)
|
||||
if (AIControllFlag)
|
||||
{ // tu bedzie logika sterowania
|
||||
if (mvOccupied->CommandIn.Command != "")
|
||||
if (!mvOccupied->RunInternalCommand()) // rozpoznaj komende bo lokomotywa jej nie
|
||||
// rozpoznaje
|
||||
if( !mvOccupied->RunInternalCommand() ) {
|
||||
// rozpoznaj komende bo lokomotywa jej nie rozpoznaje
|
||||
RecognizeCommand(); // samo czyta komendę wstawioną do pojazdu?
|
||||
if (mvOccupied->SecuritySystem.Status > 1) // jak zadziałało CA/SHP
|
||||
if (!mvOccupied->SecuritySystemReset()) // to skasuj
|
||||
// if
|
||||
// ((TestFlag(mvOccupied->SecuritySystem.Status,s_ebrake))&&(mvOccupied->BrakeCtrlPos==0)&&(AccDesired>0.0))
|
||||
if ((TestFlag(mvOccupied->SecuritySystem.Status, s_SHPebrake) ||
|
||||
TestFlag(mvOccupied->SecuritySystem.Status, s_CAebrake)) &&
|
||||
(mvOccupied->BrakeCtrlPos == 0) && (AccDesired > 0.0))
|
||||
mvOccupied->BrakeLevelSet(
|
||||
0); //!!! hm, może po prostu normalnie sterować hamulcem?
|
||||
}
|
||||
if( mvOccupied->SecuritySystem.Status > 1 ) {
|
||||
// jak zadziałało CA/SHP
|
||||
if( !mvOccupied->SecuritySystemReset() ) { // to skasuj
|
||||
if( ( mvOccupied->BrakeCtrlPos == 0 )
|
||||
&& ( AccDesired > 0.0 )
|
||||
&& ( ( TestFlag( mvOccupied->SecuritySystem.Status, s_SHPebrake ) )
|
||||
|| ( TestFlag( mvOccupied->SecuritySystem.Status, s_CAebrake ) ) ) ) {
|
||||
//!!! hm, może po prostu normalnie sterować hamulcem?
|
||||
mvOccupied->BrakeLevelSet( 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
// basic emergency stop handling, while at it
|
||||
if( ( true == mvOccupied->EmergencyBrakeFlag ) // radio-stop
|
||||
&& ( mvOccupied->Vel < 0.01 ) // and actual stop
|
||||
&& ( true == mvOccupied->Radio ) ) { // and we didn't touch the radio yet
|
||||
// turning off the radio should reset the flag, during security system check
|
||||
if( m_radiocontroltime > 2.5 ) {
|
||||
// arbitrary 2.5 sec delay between stop and disabling the radio
|
||||
mvOccupied->Radio = false;
|
||||
m_radiocontroltime = 0.0;
|
||||
}
|
||||
else {
|
||||
m_radiocontroltime += LastReactionTime;
|
||||
}
|
||||
}
|
||||
if( ( false == mvOccupied->Radio )
|
||||
&& ( false == mvOccupied->EmergencyBrakeFlag ) ) {
|
||||
// otherwise if it's safe to do so, turn the radio back on
|
||||
if( m_radiocontroltime > 5.0 ) {
|
||||
// arbitrary 5 sec delay before switching radio back on
|
||||
mvOccupied->Radio = true;
|
||||
m_radiocontroltime = 0.0;
|
||||
}
|
||||
else {
|
||||
m_radiocontroltime += LastReactionTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
switch (OrderList[OrderPos])
|
||||
{ // ustalenie prędkości przy doczepianiu i odczepianiu, dystansów w pozostałych przypadkach
|
||||
@@ -4139,6 +4183,7 @@ bool TController::UpdateSituation(double dt)
|
||||
->TTVmax); // jesli nie spozniony to nie przekraczać rozkladowej
|
||||
if (VelDesired > 0.0)
|
||||
if( ( ( SemNextIndex != -1 )
|
||||
&& ( SemNextIndex < sSpeedTable.size() ) // BUG: index can point at non-existing slot. investigate reason(s)
|
||||
&& ( sSpeedTable[SemNextIndex].fVelNext != 0.0 ) )
|
||||
|| ( ( iDrivigFlags & moveStopHere ) == 0 ) )
|
||||
{ // jeśli można jechać, to odpalić dźwięk kierownika oraz zamknąć drzwi w
|
||||
|
||||
4
Driver.h
4
Driver.h
@@ -201,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
|
||||
@@ -211,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:
|
||||
|
||||
450
DynObj.cpp
450
DynObj.cpp
@@ -1531,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;
|
||||
@@ -1879,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;
|
||||
@@ -2481,10 +2472,15 @@ bool TDynamicObject::Update(double dt, double dt1)
|
||||
}
|
||||
else {
|
||||
if( MoverParameters->PantPress >= 4.6 ) {
|
||||
// prime the pressure switch
|
||||
MoverParameters->PantPressSwitchActive = true;
|
||||
// turn off the subsystems lock
|
||||
MoverParameters->PantPressLockActive = false;
|
||||
// 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
|
||||
@@ -3564,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
|
||||
@@ -4211,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;
|
||||
@@ -4246,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 );
|
||||
@@ -4365,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"))
|
||||
@@ -5072,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;
|
||||
@@ -5577,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;
|
||||
};
|
||||
//---------------------------------------------------------------------------
|
||||
@@ -5656,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
|
||||
@@ -5744,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
|
||||
|
||||
19
DynObj.h
19
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
|
||||
{
|
||||
|
||||
35
EU07.cpp
35
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:
|
||||
@@ -383,9 +382,15 @@ int main(int argc, char *argv[])
|
||||
input::Gamepad.init();
|
||||
|
||||
Global::pWorld = &World; // Ra: wskaźnik potrzebny do usuwania pojazdów
|
||||
if (!World.Init(window))
|
||||
{
|
||||
ErrorLog( "Failed to init TWorld" );
|
||||
try {
|
||||
if( false == World.Init( window ) ) {
|
||||
ErrorLog( "Failed to init TWorld" );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
catch( std::bad_alloc const &Error ) {
|
||||
|
||||
ErrorLog( "Critical error, memory allocation failure: " + std::string( Error.what() ) );
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -406,13 +411,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()
|
||||
|
||||
15
Globals.cpp
15
Globals.cpp
@@ -83,17 +83,8 @@ 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
|
||||
opengl_light Global::DayLight;
|
||||
int Global::DynamicLightCount{ 3 };
|
||||
#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 +101,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 };
|
||||
@@ -801,6 +793,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();
|
||||
|
||||
13
Globals.h
13
Globals.h
@@ -221,20 +221,11 @@ 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 opengl_light DayLight;
|
||||
static int DynamicLightCount;
|
||||
#endif
|
||||
|
||||
static GLfloat whiteLight[];
|
||||
static GLfloat noLight[];
|
||||
static GLfloat darkLight[];
|
||||
@@ -255,6 +246,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
|
||||
@@ -287,7 +279,6 @@ class Global
|
||||
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 bool bActive; // czy jest aktywnym oknem
|
||||
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
|
||||
|
||||
767
Ground.cpp
767
Ground.cpp
File diff suppressed because it is too large
Load Diff
42
Ground.h
42
Ground.h
@@ -122,19 +122,20 @@ public:
|
||||
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
|
||||
|
||||
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
|
||||
@@ -144,6 +145,7 @@ public:
|
||||
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
|
||||
@@ -154,8 +156,6 @@ public:
|
||||
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
|
||||
@@ -166,7 +166,7 @@ public:
|
||||
return NULL;
|
||||
};
|
||||
|
||||
void Compile(bool many = false);
|
||||
void Compile(Math3D::vector3 const &Origin, bool const Multiple = false);
|
||||
void Release();
|
||||
|
||||
void RenderHidden(); // obsługa dźwięków i wyzwalaczy zdarzeń
|
||||
@@ -177,7 +177,7 @@ public:
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
@@ -192,8 +192,8 @@ 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)
|
||||
@@ -217,11 +217,6 @@ class TSubRect : public Resource, public CMesh
|
||||
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
|
||||
};
|
||||
|
||||
@@ -238,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 };
|
||||
@@ -264,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
|
||||
@@ -279,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;
|
||||
@@ -341,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);
|
||||
|
||||
@@ -847,12 +847,14 @@ 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 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*/
|
||||
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*/
|
||||
@@ -978,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
|
||||
|
||||
@@ -1565,6 +1565,7 @@ double TMoverParameters::ShowEngineRotation(int VehN)
|
||||
void TMoverParameters::ConverterCheck( double const Timestep ) {
|
||||
// TODO: move other converter checks here, to have it all in one place for potential device object
|
||||
if( ( ConverterAllow )
|
||||
&& ( ConverterAllowLocal )
|
||||
&& ( false == PantPressLockActive )
|
||||
&& ( Mains ) ) {
|
||||
// delay timer can be optionally configured, and is set anew whenever converter goes off
|
||||
@@ -3018,7 +3019,7 @@ void TMoverParameters::CompressorCheck(double dt)
|
||||
if (MaxCompressor - MinCompressor < 0.0001)
|
||||
{
|
||||
// if (Mains && (MainCtrlPos > 1))
|
||||
if (CompressorAllow && Mains && (MainCtrlPos > 0))
|
||||
if (CompressorAllow && CompressorAllowLocal && Mains && (MainCtrlPos > 0))
|
||||
{
|
||||
if (Compressor < MaxCompressor)
|
||||
if ((EngineType == DieselElectric) && (CompressorPower > 0))
|
||||
@@ -3048,8 +3049,10 @@ void TMoverParameters::CompressorCheck(double dt)
|
||||
{ // zasilanie sprężarki w członie ra z członu silnikowego (sprzęg 1)
|
||||
if (Couplers[1].Connected != NULL)
|
||||
CompressorFlag =
|
||||
(Couplers[1].Connected->CompressorAllow &&
|
||||
Couplers[1].Connected->ConverterFlag && Couplers[1].Connected->Mains);
|
||||
( Couplers[ 1 ].Connected->CompressorAllow
|
||||
&& Couplers[ 1 ].Connected->CompressorAllowLocal
|
||||
&& Couplers[ 1 ].Connected->Mains
|
||||
&& Couplers[ 1 ].Connected->ConverterFlag );
|
||||
else
|
||||
CompressorFlag = false; // bez tamtego członu nie zadziała
|
||||
}
|
||||
@@ -3057,62 +3060,116 @@ void TMoverParameters::CompressorCheck(double dt)
|
||||
{ // zasilanie sprężarki w członie ra z członu silnikowego (sprzęg 1)
|
||||
if (Couplers[0].Connected != NULL)
|
||||
CompressorFlag =
|
||||
(Couplers[0].Connected->CompressorAllow &&
|
||||
Couplers[0].Connected->ConverterFlag && Couplers[0].Connected->Mains);
|
||||
( Couplers[ 0 ].Connected->CompressorAllow
|
||||
&& Couplers[ 0 ].Connected->CompressorAllowLocal
|
||||
&& Couplers[ 0 ].Connected->Mains
|
||||
&& Couplers[ 0 ].Connected->ConverterFlag );
|
||||
else
|
||||
CompressorFlag = false; // bez tamtego członu nie zadziała
|
||||
}
|
||||
else
|
||||
CompressorFlag = (CompressorAllow) &&
|
||||
((ConverterFlag) || (CompressorPower == 0)) && (Mains);
|
||||
CompressorFlag =
|
||||
( ( CompressorAllow )
|
||||
&& ( CompressorAllowLocal )
|
||||
&& ( Mains )
|
||||
&& ( ( ConverterFlag )
|
||||
|| ( CompressorPower == 0 ) ) );
|
||||
|
||||
if( Compressor > MaxCompressor ) {
|
||||
// wyłącznik ciśnieniowy jest niezależny od sposobu zasilania
|
||||
CompressorFlag = false;
|
||||
CompressorGovernorLock = true; // prevent manual activation until the pressure goes below cut-in level
|
||||
}
|
||||
}
|
||||
else // jeśli nie załączona
|
||||
if( ( ( Compressor < MinCompressor )
|
||||
|| ( ( Compressor < MaxCompressor )
|
||||
&& ( false == CompressorGovernorLock ) ) )
|
||||
&& (LastSwitchingTime > CtrlDelay) ) {
|
||||
// załączenie przy małym ciśnieniu
|
||||
// jeśli nie załączona, a ciśnienie za małe
|
||||
// or if the switch is on and the pressure isn't maxed
|
||||
if( CompressorPower == 5 ) // jeśli zasilanie z następnego członu
|
||||
{ // zasilanie sprężarki w członie ra z członu silnikowego (sprzęg 1)
|
||||
if (Couplers[1].Connected != NULL)
|
||||
CompressorFlag =
|
||||
(Couplers[1].Connected->CompressorAllow &&
|
||||
Couplers[1].Connected->ConverterFlag && Couplers[1].Connected->Mains);
|
||||
else
|
||||
CompressorFlag = false; // bez tamtego członu nie zadziała
|
||||
}
|
||||
else if (CompressorPower == 4) // jeśli zasilanie z poprzedniego członu
|
||||
{ // zasilanie sprężarki w członie ra z członu silnikowego (sprzęg 1)
|
||||
if (Couplers[0].Connected != NULL)
|
||||
CompressorFlag =
|
||||
(Couplers[0].Connected->CompressorAllow &&
|
||||
Couplers[0].Connected->ConverterFlag && Couplers[0].Connected->Mains);
|
||||
else
|
||||
CompressorFlag = false; // bez tamtego członu nie zadziała
|
||||
}
|
||||
else
|
||||
CompressorFlag = (CompressorAllow) &&
|
||||
((ConverterFlag) || (CompressorPower == 0)) && (Mains);
|
||||
if( CompressorFlag ) {
|
||||
// jeśli została załączona
|
||||
LastSwitchingTime = 0; // to trzeba ograniczyć ponowne włączenie
|
||||
if( Compressor < MinCompressor ) {
|
||||
// if the activation took place at pressure below the cut-in level, we can reset compressor governor
|
||||
CompressorGovernorLock = false;
|
||||
|
||||
if( ( TrainType == dt_ET41 )
|
||||
|| ( TrainType == dt_ET42 ) ) {
|
||||
// for these multi-unit engines compressors turn off whenever any of them was affected by the governor
|
||||
// NOTE: this is crude implementation, TODO: re-implement when a more elegant/flexible system is in place
|
||||
if( ( Couplers[ 1 ].Connected != nullptr )
|
||||
&& ( true == TestFlag( Couplers[ 1 ].CouplingFlag, coupling::permanent ) ) ) {
|
||||
// the first unit isn't allowed to start its compressor until second unit can start its own as well
|
||||
CompressorFlag &= ( Couplers[ 1 ].Connected->CompressorGovernorLock == false );
|
||||
}
|
||||
if( ( Couplers[ 0 ].Connected != nullptr )
|
||||
&& ( true == TestFlag( Couplers[ 0 ].CouplingFlag, coupling::permanent ) ) ) {
|
||||
// the second unit isn't allowed to start its compressor until first unit can start its own as well
|
||||
CompressorFlag &= ( Couplers[ 0 ].Connected->CompressorGovernorLock == false );
|
||||
}
|
||||
}
|
||||
}
|
||||
// for b:=0 to 1 do //z Megapacka
|
||||
// with Couplers[b] do
|
||||
// if TestFlag(CouplingFlag,ctrain_scndpneumatic) then
|
||||
// Connected.CompressorFlag:=CompressorFlag;
|
||||
else {
|
||||
// jeśli nie załączona
|
||||
if( Compressor < MinCompressor ) {
|
||||
// if the pressure drops below the cut-in level, we can reset compressor governor
|
||||
CompressorGovernorLock = false;
|
||||
}
|
||||
|
||||
if( ( ( Compressor < MinCompressor )
|
||||
|| ( ( Compressor < MaxCompressor )
|
||||
&& ( false == CompressorGovernorLock ) ) )
|
||||
&& ( LastSwitchingTime > CtrlDelay ) ) {
|
||||
// załączenie przy małym ciśnieniu
|
||||
// jeśli nie załączona, a ciśnienie za małe
|
||||
// or if the switch is on and the pressure isn't maxed
|
||||
if( CompressorPower == 5 ) // jeśli zasilanie z następnego członu
|
||||
{ // zasilanie sprężarki w członie ra z członu silnikowego (sprzęg 1)
|
||||
if( Couplers[ 1 ].Connected != nullptr ) {
|
||||
CompressorFlag =
|
||||
( Couplers[ 1 ].Connected->CompressorAllow
|
||||
&& Couplers[ 1 ].Connected->CompressorAllowLocal
|
||||
&& Couplers[ 1 ].Connected->Mains
|
||||
&& Couplers[ 1 ].Connected->ConverterFlag );
|
||||
}
|
||||
else {
|
||||
CompressorFlag = false; // bez tamtego członu nie zadziała
|
||||
}
|
||||
}
|
||||
else if( CompressorPower == 4 ) // jeśli zasilanie z poprzedniego członu
|
||||
{ // zasilanie sprężarki w członie ra z członu silnikowego (sprzęg 1)
|
||||
if( Couplers[ 0 ].Connected != nullptr ) {
|
||||
CompressorFlag =
|
||||
( Couplers[ 0 ].Connected->CompressorAllow
|
||||
&& Couplers[ 0 ].Connected->CompressorAllowLocal
|
||||
&& Couplers[ 0 ].Connected->Mains
|
||||
&& Couplers[ 0 ].Connected->ConverterFlag );
|
||||
}
|
||||
else {
|
||||
CompressorFlag = false; // bez tamtego członu nie zadziała
|
||||
}
|
||||
}
|
||||
else {
|
||||
CompressorFlag =
|
||||
( ( CompressorAllow )
|
||||
&& ( CompressorAllowLocal )
|
||||
&& ( Mains )
|
||||
&& ( ( ConverterFlag )
|
||||
|| ( CompressorPower == 0 ) ) );
|
||||
}
|
||||
|
||||
// NOTE: crude way to enforce simultaneous activation of compressors in multi-unit setups
|
||||
// TODO: replace this with a more universal activation system down the road
|
||||
if( ( TrainType == dt_ET41 )
|
||||
|| ( TrainType == dt_ET42 ) ) {
|
||||
|
||||
if( ( Couplers[1].Connected != nullptr )
|
||||
&& ( true == TestFlag( Couplers[ 1 ].CouplingFlag, coupling::permanent ) ) ) {
|
||||
// the first unit isn't allowed to start its compressor until second unit can start its own as well
|
||||
CompressorFlag &= ( Couplers[ 1 ].Connected->CompressorGovernorLock == false );
|
||||
}
|
||||
if( ( Couplers[ 0 ].Connected != nullptr )
|
||||
&& ( true == TestFlag( Couplers[ 0 ].CouplingFlag, coupling::permanent ) ) ) {
|
||||
// the second unit isn't allowed to start its compressor until first unit can start its own as well
|
||||
CompressorFlag &= ( Couplers[ 0 ].Connected->CompressorGovernorLock == false );
|
||||
}
|
||||
}
|
||||
|
||||
if( CompressorFlag ) {
|
||||
// jeśli została załączona
|
||||
LastSwitchingTime = 0; // to trzeba ograniczyć ponowne włączenie
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CompressorFlag)
|
||||
if ((EngineType == DieselElectric) && (CompressorPower > 0))
|
||||
CompressedVolume += dt * CompressorSpeed * (2.0 * MaxCompressor - Compressor) /
|
||||
@@ -3628,7 +3685,8 @@ void TMoverParameters::ComputeTotalForce(double dt, double dt1, bool FullVer)
|
||||
else
|
||||
FTrain = 0;
|
||||
Fb = BrakeForce(RunningTrack);
|
||||
if( std::max( std::abs( FTrain ), Fb ) > TotalMassxg * Adhesive( RunningTrack.friction ) ) // poslizg
|
||||
if( ( Vel > 0.001 ) // crude trap, to prevent braked stationary vehicles from passing fb > mass * adhesive test
|
||||
&& ( std::max( std::abs( FTrain ), Fb ) > TotalMassxg * Adhesive( RunningTrack.friction ) ) ) // poslizg
|
||||
{
|
||||
SlippingWheels = true;
|
||||
}
|
||||
@@ -7255,9 +7313,11 @@ void TMoverParameters::LoadFIZ_Switches( std::string const &Input ) {
|
||||
|
||||
extract_value( PantSwitchType, "Pantograph", Input, "" );
|
||||
extract_value( ConvSwitchType, "Converter", Input, "" );
|
||||
extract_value( StLinSwitchType, "MotorConnectors", Input, "" );
|
||||
// because people can't make up their minds whether it's "impulse" or "Impulse"...
|
||||
PantSwitchType = ToLower( PantSwitchType );
|
||||
ConvSwitchType = ToLower( ConvSwitchType );
|
||||
StLinSwitchType = ToLower( StLinSwitchType );
|
||||
}
|
||||
|
||||
void TMoverParameters::LoadFIZ_MotorParamTable( std::string const &Input ) {
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
609
Model3d.cpp
609
Model3d.cpp
@@ -1036,421 +1036,6 @@ void TSubModel::RaAnimation(TAnimType a)
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
void TSubModel::RenderDL()
|
||||
{ // główna procedura renderowania przez DL
|
||||
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
|
||||
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()
|
||||
{ // główna procedura renderowania przez VBO
|
||||
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
|
||||
glColor3fv(f4Diffuse); // McZapkie-240702: zamiast ub
|
||||
// glMaterialfv(GL_FRONT,GL_AMBIENT_AND_DIFFUSE,f4Diffuse); //to samo,
|
||||
// co glColor
|
||||
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);
|
||||
|
||||
/* TODO: poprawic to zeby dzialalo
|
||||
|
||||
2- Inverse (Applies inverse decay. The formula is luminance=R0/R, where
|
||||
R0 is
|
||||
the radial source of the light if no attenuation is
|
||||
used, or the Near End
|
||||
value of the light if Attenuation is used. R is the
|
||||
radial distance of the
|
||||
illuminated surface from R0.)
|
||||
|
||||
3- Inverse Square (Applies inverse-square decay. The formula for this is
|
||||
(R0/R)^2.
|
||||
This is actually the "real-world" decay of light, but
|
||||
you might find it too dim
|
||||
in the world of computer graphics.)
|
||||
|
||||
<light>.DecayRadius -- The distance over which the decay occurs.
|
||||
|
||||
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;
|
||||
|
||||
*/
|
||||
GfxRenderer.Bind(0); // nie teksturować
|
||||
// glColor3f(f4Diffuse[0],f4Diffuse[1],f4Diffuse[2]);
|
||||
// glColorMaterial(GL_FRONT,GL_EMISSION);
|
||||
float color[4] = { (float)(f4Diffuse[0] * Distdimm), (float)(f4Diffuse[1] * Distdimm),
|
||||
(float)(f4Diffuse[2] * Distdimm), 0 };
|
||||
// glColor3f(f4Diffuse[0]*Distdimm,f4Diffuse[1]*Distdimm,f4Diffuse[2]*Distdimm);
|
||||
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)
|
||||
{
|
||||
// glDisable(GL_LIGHTING); //Tolaris-030603: bo mu punkty swiecace sie
|
||||
// blendowaly
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*Ra: tu coś jest bez sensu...
|
||||
else
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
// if (eType==smt_FreeSpotLight)
|
||||
// {
|
||||
// if (iFarAttenDecay==0)
|
||||
// glColor3f(Diffuse[0],Diffuse[1],Diffuse[2]);
|
||||
// }
|
||||
// else
|
||||
//TODO: poprawic zeby dzialalo
|
||||
glColor3f(f4Diffuse[0],f4Diffuse[1],f4Diffuse[2]);
|
||||
glColorMaterial(GL_FRONT,GL_EMISSION);
|
||||
glDisable(GL_LIGHTING); //Tolaris-030603: bo mu punkty
|
||||
swiecace sie blendowaly
|
||||
//glBegin(GL_POINTS);
|
||||
glDrawArrays(GL_POINTS,iVboPtr,iNumVerts); //narysuj
|
||||
wierzchołek z VBO
|
||||
// glVertex3f(0,0,0);
|
||||
//glEnd();
|
||||
glEnable(GL_LIGHTING);
|
||||
glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
|
||||
glMaterialfv(GL_FRONT,GL_EMISSION,emm2);
|
||||
//glEndList();
|
||||
}
|
||||
*/
|
||||
if (Child != NULL)
|
||||
if (iAlpha & iFlags & 0x001F0000)
|
||||
Child->RenderVBO();
|
||||
if (iFlags & 0xC000)
|
||||
glPopMatrix();
|
||||
}
|
||||
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(); // dalsze rekurencyjnie
|
||||
}; // RaRender
|
||||
|
||||
void TSubModel::RenderAlphaVBO()
|
||||
{ // renderowanie przezroczystych przez VBO
|
||||
if( ( iVisible )
|
||||
&& ( fSquareDist >= (fSquareMinDist / Global::fDistanceFactor) )
|
||||
&& ( fSquareDist <= (fSquareMaxDist * Global::fDistanceFactor) ) )
|
||||
{
|
||||
if (iFlags & 0xC000)
|
||||
{
|
||||
glPushMatrix(); // zapamiętanie matrycy
|
||||
if (fMatrix)
|
||||
glMultMatrixf(fMatrix->readArray());
|
||||
if (b_aAnim)
|
||||
RaAnimation(b_aAnim);
|
||||
}
|
||||
glColor3fv(f4Diffuse);
|
||||
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();
|
||||
if (iFlags & 0xC000)
|
||||
glPopMatrix();
|
||||
}
|
||||
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();
|
||||
}; // RaRenderAlpha
|
||||
#endif
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void TSubModel::RaArrayFill(CVertNormTex *Vert)
|
||||
@@ -1577,8 +1162,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
|
||||
@@ -1801,7 +1390,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++)
|
||||
@@ -1886,7 +1479,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;
|
||||
|
||||
@@ -1900,13 +1497,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);
|
||||
}
|
||||
@@ -1967,12 +1573,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];
|
||||
@@ -2151,11 +1765,18 @@ void TModel3d::Init()
|
||||
*/
|
||||
if (Global::bUseVBO)
|
||||
{
|
||||
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
|
||||
@@ -2176,140 +1797,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;
|
||||
Root->RenderVBO();
|
||||
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);
|
||||
Root->RenderAlphaVBO();
|
||||
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);
|
||||
Root->RenderVBO();
|
||||
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);
|
||||
Root->RenderAlphaVBO();
|
||||
EndVBO();
|
||||
}
|
||||
glPopMatrix();
|
||||
};
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 2012-02 funkcje do tworzenia terenu z E3D
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2341,6 +1828,8 @@ 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 );
|
||||
|
||||
// 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);
|
||||
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
168
Segment.cpp
168
Segment.cpp
@@ -114,28 +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ć
|
||||
*/
|
||||
}
|
||||
|
||||
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 = static_cast<int>( std::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;
|
||||
}
|
||||
|
||||
@@ -317,14 +319,16 @@ vector3 TSegment::FastGetPoint(double t)
|
||||
return (bCurve ? RaInterpolate(t) : ((1.0 - t) * Point1 + (t)*Point2));
|
||||
}
|
||||
|
||||
void TSegment::RenderLoft( CVertNormTex* &Output, const vector6 *ShapePoints, int iNumShapePoints, double fTextureLength, double Texturescale, int iSkip, int iEnd, double fOffsetX, bool Onlypositions, 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
|
||||
int vertexcount{ 0 };
|
||||
|
||||
if( !fTsBuffer )
|
||||
return; // prowizoryczne zabezpieczenie przed wysypem - ustalić faktyczną przyczynę
|
||||
return vertexcount; // prowizoryczne zabezpieczenie przed wysypem - ustalić faktyczną przyczynę
|
||||
|
||||
vector3 pos1, pos2, dir, parallel1, parallel2, pt, norm;
|
||||
double s, step, fOffset, tv1, tv2, t, fEnd;
|
||||
@@ -348,6 +352,7 @@ void TSegment::RenderLoft( CVertNormTex* &Output, const vector6 *ShapePoints, in
|
||||
fEnd = fLength * double( iEnd ) / double( iSegCount );
|
||||
m2 = s / fEnd;
|
||||
jmm2 = 1.0 - m2;
|
||||
|
||||
while( i < iEnd ) {
|
||||
|
||||
++i; // kolejny punkt łamanej
|
||||
@@ -363,12 +368,10 @@ void TSegment::RenderLoft( CVertNormTex* &Output, const vector6 *ShapePoints, in
|
||||
jmm2 = 0.0;
|
||||
}
|
||||
|
||||
if( false == Onlypositions ) {
|
||||
while( tv1 < 0.0 ) {
|
||||
tv1 += 1.0;
|
||||
}
|
||||
tv2 = tv1 - step / fTextureLength; // mapowanie na końcu segmentu
|
||||
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 );
|
||||
@@ -384,32 +387,28 @@ void TSegment::RenderLoft( CVertNormTex* &Output, const vector6 *ShapePoints, in
|
||||
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;
|
||||
if( false == Onlypositions ) {
|
||||
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 -= 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
|
||||
if( false == Onlypositions ) {
|
||||
::glNormal3f( norm.x, norm.y, norm.z );
|
||||
::glTexCoord2f( (jmm1 * ShapePoints[ j ].z + m1 * ShapePoints[ j + iNumShapePoints ].z) / Texturescale, tv1 );
|
||||
}
|
||||
::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;
|
||||
if( false == Onlypositions ) {
|
||||
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->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 )
|
||||
@@ -421,32 +420,28 @@ void TSegment::RenderLoft( CVertNormTex* &Output, const vector6 *ShapePoints, in
|
||||
// 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;
|
||||
if( false == Onlypositions ) {
|
||||
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 -= 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
|
||||
if( false == Onlypositions ) {
|
||||
::glNormal3f( norm.x, norm.y, norm.z );
|
||||
::glTexCoord2f( (jmm2 * ShapePoints[ j ].z + m2 * ShapePoints[ j + iNumShapePoints ].z) / Texturescale, tv2 );
|
||||
}
|
||||
::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;
|
||||
if( false == Onlypositions ) {
|
||||
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->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 )
|
||||
@@ -458,61 +453,56 @@ void TSegment::RenderLoft( CVertNormTex* &Output, const vector6 *ShapePoints, in
|
||||
}
|
||||
}
|
||||
else {
|
||||
for( int j = 0; j < iNumShapePoints; ++j ) {
|
||||
//łuk z jednym profilem
|
||||
pt = parallel1 * ( ShapePoints[ j ].x - fOffsetX ) + pos1;
|
||||
pt.y += ShapePoints[ j ].y;
|
||||
if( false == Onlypositions ) {
|
||||
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
|
||||
if( false == Onlypositions ) {
|
||||
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
|
||||
}
|
||||
::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;
|
||||
if( false == Onlypositions ) {
|
||||
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;
|
||||
}
|
||||
++Output;
|
||||
}
|
||||
pt = parallel2 * ShapePoints[ j ].x + pos2;
|
||||
pt.y += ShapePoints[ j ].y;
|
||||
if( false == Onlypositions ) {
|
||||
++vertexcount;
|
||||
|
||||
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
|
||||
if( false == Onlypositions ) {
|
||||
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
|
||||
}
|
||||
::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;
|
||||
if( false == Onlypositions ) {
|
||||
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;
|
||||
}
|
||||
++Output;
|
||||
++vertexcount;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -522,10 +512,10 @@ void TSegment::RenderLoft( CVertNormTex* &Output, const vector6 *ShapePoints, in
|
||||
}
|
||||
pos1 = pos2;
|
||||
parallel1 = parallel2;
|
||||
if( false == Onlypositions ) {
|
||||
tv1 = tv2;
|
||||
}
|
||||
tv1 = tv2;
|
||||
}
|
||||
|
||||
return vertexcount;
|
||||
};
|
||||
|
||||
void TSegment::Render()
|
||||
|
||||
@@ -113,7 +113,7 @@ class TSegment
|
||||
r1 = fRoll1;
|
||||
r2 = fRoll2;
|
||||
}
|
||||
void RenderLoft( CVertNormTex* &Output, const vector6 *ShapePoints, int iNumShapePoints, double fTextureLength, double Texturescale = 1.0, int iSkip = 0, int iEnd = 0, double fOffsetX = 0.0, bool Onlypositions = false, vector3 **p = nullptr, bool bRender = true);
|
||||
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()
|
||||
{
|
||||
|
||||
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
|
||||
|
||||
395
Track.cpp
395
Track.cpp
@@ -198,7 +198,7 @@ TTrack * TTrack::Create400m(int what, double dx)
|
||||
trk->bVisible = false; // nie potrzeba pokazywać, zresztą i tak nie ma tekstur
|
||||
trk->iCategoryFlag = what; // taki sam typ plus informacja, że dodatkowy
|
||||
trk->Init(); // utworzenie segmentu
|
||||
trk->Segment->Init(vector3(-dx, 0, 0), vector3(-dx, 0, 400), 0, 0, 0); // prosty
|
||||
trk->Segment->Init(vector3(-dx, 0, 0), vector3(-dx, 0, 400), 10.0, 0, 0); // prosty
|
||||
tmp->pCenter = vector3(-dx, 0, 200); //środek, aby się mogło wyświetlić
|
||||
TSubRect *r = Global::pGround->GetSubRect(tmp->pCenter.x, tmp->pCenter.z);
|
||||
r->NodeAdd(tmp); // dodanie toru do segmentu
|
||||
@@ -405,8 +405,7 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
|
||||
std::string token;
|
||||
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str = token; // typ toru
|
||||
*parser >> str; // typ toru
|
||||
|
||||
if (str == "normal")
|
||||
{
|
||||
@@ -460,8 +459,7 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
|
||||
if (iDamageFlag & 128)
|
||||
iAction |= 0x80; // flaga wykolejania z powodu uszkodzenia
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str = token; // environment
|
||||
*parser >> str; // environment
|
||||
if (str == "flat")
|
||||
eEnvironment = e_flat;
|
||||
else if (str == "mountains" || str == "mountain")
|
||||
@@ -477,7 +475,7 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
|
||||
else
|
||||
{
|
||||
eEnvironment = e_unknown;
|
||||
Error("Unknown track environment: \"" + str + "\"");
|
||||
Error( "Unknown track environment: \"" + str + "\"" );
|
||||
}
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
@@ -485,8 +483,7 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
|
||||
if (bVisible)
|
||||
{
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str = token; // railtex
|
||||
*parser >> str; // railtex
|
||||
TextureID1 = (str == "none" ? 0 : GfxRenderer.GetTextureId(
|
||||
str, szTexturePath,
|
||||
(iCategoryFlag & 1) ? Global::iRailProFiltering :
|
||||
@@ -496,8 +493,7 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
|
||||
if (fTexLength < 0.01)
|
||||
fTexLength = 4; // Ra: zabezpiecznie przed zawieszeniem
|
||||
parser->getTokens();
|
||||
*parser >> token;
|
||||
str = token; // sub || railtex
|
||||
*parser >> str; // sub || railtex
|
||||
TextureID2 = (str == "none" ? 0 : GfxRenderer.GetTextureId(
|
||||
str, szTexturePath,
|
||||
(eType == tt_Normal) ? Global::iBallastFiltering :
|
||||
@@ -532,7 +528,7 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
|
||||
// na przechyłce doliczyć jeszcze pół przechyłki
|
||||
}
|
||||
if( fRadius != 0 ) // gdy podany promień
|
||||
segsize = Min0R( 5.0, 0.2 + fabs( fRadius ) * 0.02 ); // do 250m - 5, potem 1 co 50m
|
||||
segsize = clamp( 0.2 + std::fabs( fRadius ) * 0.02, 2.0, 10.0 );
|
||||
else
|
||||
segsize = 10.0; // for straights, 10m per segment works good enough
|
||||
|
||||
@@ -595,13 +591,14 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
|
||||
// na przechyłce doliczyć jeszcze pół przechyłki?
|
||||
}
|
||||
if (fRadiusTable[0] > 0)
|
||||
segsize = Min0R(5.0, 0.2 + fRadiusTable[0] * 0.02);
|
||||
segsize = clamp( 0.2 + fRadiusTable[0] * 0.02, 2.0, 5.0 );
|
||||
else if (eType != tt_Cross) // dla skrzyżowań muszą być podane kontrolne
|
||||
{ // jak promień zerowy, to przeliczamy punkty kontrolne
|
||||
cp1 = (p1 + p1 + p2) / 3.0 - p1; // jak jest prosty, to się zoptymalizuje
|
||||
cp2 = (p1 + p2 + p2) / 3.0 - p2;
|
||||
segsize = 5.0;
|
||||
} // ułomny prosty
|
||||
|
||||
if (!(cp1 == vector3(0, 0, 0)) && !(cp2 == vector3(0, 0, 0)))
|
||||
SwitchExtension->Segments[0]->Init(p1, p1 + cp1, p2 + cp2, p2, segsize, r1, r2);
|
||||
else
|
||||
@@ -624,7 +621,8 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
|
||||
}
|
||||
|
||||
if (fRadiusTable[1] > 0)
|
||||
segsize = Min0R(5.0, 0.2 + fRadiusTable[1] * 0.02);
|
||||
segsize = clamp( 0.2 + fRadiusTable[ 1 ] * 0.02, 2.0, 5.0 );
|
||||
|
||||
else if (eType != tt_Cross) // dla skrzyżowań muszą być podane kontrolne
|
||||
{ // jak promień zerowy, to przeliczamy punkty kontrolne
|
||||
cp3 = (p3 + p3 + p4) / 3.0 - p3; // jak jest prosty, to się zoptymalizuje
|
||||
@@ -641,6 +639,7 @@ void TTrack::Load(cParser *parser, vector3 pOrigin, std::string name)
|
||||
}
|
||||
else
|
||||
SwitchExtension->Segments[1]->Init(p3, p4, segsize, r3, r4);
|
||||
|
||||
if (eType == tt_Cross)
|
||||
{ // Ra 2014-07: dla skrzyżowań będą dodatkowe segmenty
|
||||
SwitchExtension->Segments[2]->Init(p2, cp2 + p2, cp4 + p4, p4, segsize, r2, r4); // z punktu 2 do 4
|
||||
@@ -1091,6 +1090,9 @@ void TTrack::Compile(GLuint tex)
|
||||
hypot2 = hypot1;
|
||||
normal2 = normal1;
|
||||
}
|
||||
|
||||
auto const origin = pMyNode->m_rootposition;
|
||||
|
||||
double roll1, roll2;
|
||||
switch (iCategoryFlag & 15)
|
||||
{
|
||||
@@ -1217,19 +1219,19 @@ void TTrack::Compile(GLuint tex)
|
||||
}
|
||||
if (!tex)
|
||||
GfxRenderer.Bind( TextureID2 );
|
||||
Segment->RenderLoft( immediate, bpts1, iTrapezoid ? -4 : 4, fTexLength);
|
||||
Segment->RenderLoft( immediate, origin, bpts1, iTrapezoid ? -4 : 4, fTexLength);
|
||||
}
|
||||
if (TextureID1)
|
||||
if (tex ? TextureID1 == tex : true) // jeśli pasuje do grupy (tex)
|
||||
{ // szyny
|
||||
if (!tex)
|
||||
GfxRenderer.Bind( TextureID1 );
|
||||
Segment->RenderLoft( immediate, rpts1, iTrapezoid ? -nnumPts : nnumPts, fTexLength);
|
||||
Segment->RenderLoft( immediate, rpts2, iTrapezoid ? -nnumPts : nnumPts, fTexLength);
|
||||
Segment->RenderLoft( immediate, origin, rpts1, iTrapezoid ? -nnumPts : nnumPts, fTexLength);
|
||||
Segment->RenderLoft( immediate, origin, rpts2, iTrapezoid ? -nnumPts : nnumPts, fTexLength);
|
||||
}
|
||||
break;
|
||||
case tt_Switch: // dla zwrotnicy dwa razy szyny
|
||||
if (TextureID1) // zwrotnice nie są grupowane, aby prościej było je animować
|
||||
if (TextureID1 || TextureID2) // zwrotnice nie są grupowane, aby prościej było je animować
|
||||
{ // iglice liczone tylko dla zwrotnic
|
||||
// Ra: TODO: oddzielna animacja każdej iglicy, opór na docisku
|
||||
vector6 rpts3[24], rpts4[24];
|
||||
@@ -1251,27 +1253,34 @@ void TTrack::Compile(GLuint tex)
|
||||
// McZapkie-130302 - poprawione rysowanie szyn
|
||||
if (SwitchExtension->RightSwitch)
|
||||
{ // zwrotnica prawa
|
||||
GfxRenderer.Bind( TextureID1 );
|
||||
SwitchExtension->Segments[0]->RenderLoft( immediate, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2); // prawa iglica
|
||||
SwitchExtension->Segments[0]->RenderLoft( immediate, rpts1, nnumPts, fTexLength, 1.0, 2); // prawa szyna za iglicą
|
||||
SwitchExtension->Segments[0]->RenderLoft( immediate, rpts2, nnumPts, fTexLength); // lewa szyna normalnie cała
|
||||
if (TextureID2 != TextureID1) // nie wiadomo, czy OpenGL to optymalizuje
|
||||
if( TextureID1 ) {
|
||||
GfxRenderer.Bind( TextureID1 );
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( immediate, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2 ); // prawa iglica
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( immediate, origin, rpts1, nnumPts, fTexLength, 1.0, 2 ); // prawa szyna za iglicą
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( immediate, origin, rpts2, nnumPts, fTexLength ); // lewa szyna normalnie cała
|
||||
}
|
||||
if( TextureID2 ) {
|
||||
GfxRenderer.Bind( TextureID2 );
|
||||
SwitchExtension->Segments[1]->RenderLoft( immediate, rpts1, nnumPts, fTexLength); // prawa szyna normalna cała
|
||||
SwitchExtension->Segments[1]->RenderLoft( immediate, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -fMaxOffset + SwitchExtension->fOffset1); // lewa iglica
|
||||
SwitchExtension->Segments[1]->RenderLoft( immediate, rpts2, nnumPts, fTexLength, 1.0, 2); // lewa szyna za iglicą
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( immediate, origin, rpts1, nnumPts, fTexLength ); // prawa szyna normalna cała
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( immediate, origin, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -fMaxOffset + SwitchExtension->fOffset1 ); // lewa iglica
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( immediate, origin, rpts2, nnumPts, fTexLength, 1.0, 2 ); // lewa szyna za iglicą
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // lewa kiedyś działała lepiej niż prawa
|
||||
GfxRenderer.Bind( TextureID1 );
|
||||
SwitchExtension->Segments[0]->RenderLoft( immediate, rpts1, nnumPts, fTexLength); // prawa szyna normalna cała
|
||||
SwitchExtension->Segments[0]->RenderLoft( immediate, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -SwitchExtension->fOffset2); // lewa iglica
|
||||
SwitchExtension->Segments[0]->RenderLoft( immediate, rpts2, nnumPts, fTexLength, 1.0, 2); // lewa szyna za iglicą
|
||||
if (TextureID2 != TextureID1) // nie wiadomo, czy OpenGL to optymalizuje
|
||||
if( TextureID1 ) {
|
||||
GfxRenderer.Bind( TextureID1 );
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( immediate, origin, rpts1, nnumPts, fTexLength ); // prawa szyna normalna cała
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( immediate, origin, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -SwitchExtension->fOffset2 ); // lewa iglica
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( immediate, origin, rpts2, nnumPts, fTexLength, 1.0, 2 ); // lewa szyna za iglicą
|
||||
}
|
||||
if( TextureID2 ) {
|
||||
// nie wiadomo, czy OpenGL to optymalizuje
|
||||
GfxRenderer.Bind( TextureID2 );
|
||||
SwitchExtension->Segments[1]->RenderLoft( immediate, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, fMaxOffset - SwitchExtension->fOffset1); // prawa iglica
|
||||
SwitchExtension->Segments[1]->RenderLoft( immediate, rpts1, nnumPts, fTexLength, 1.0, 2); // prawa szyna za iglicą
|
||||
SwitchExtension->Segments[1]->RenderLoft( immediate, rpts2, nnumPts, fTexLength); // lewa szyna normalnie cała
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( immediate, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, fMaxOffset - SwitchExtension->fOffset1 ); // prawa iglica
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( immediate, origin, rpts1, nnumPts, fTexLength, 1.0, 2 ); // prawa szyna za iglicą
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( immediate, origin, rpts2, nnumPts, fTexLength ); // lewa szyna normalnie cała
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1309,7 +1318,7 @@ void TTrack::Compile(GLuint tex)
|
||||
{ // tworzenie trójkątów nawierzchni szosy
|
||||
if (!tex)
|
||||
GfxRenderer.Bind( TextureID1 );
|
||||
Segment->RenderLoft( immediate, bpts1, iTrapezoid ? -2 : 2, fTexLength);
|
||||
Segment->RenderLoft( immediate, origin, bpts1, iTrapezoid ? -2 : 2, fTexLength);
|
||||
}
|
||||
if (TextureID2)
|
||||
if (tex ? TextureID2 == tex : true) // jeśli pasuje do grupy (tex)
|
||||
@@ -1393,16 +1402,16 @@ void TTrack::Compile(GLuint tex)
|
||||
{ // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony
|
||||
// odcinka
|
||||
if ((fTexHeight1 >= 0.0) ? true : (slop != 0.0))
|
||||
Segment->RenderLoft( immediate, rpts1, -3, fTexLength); // tylko jeśli jest z prawej
|
||||
Segment->RenderLoft( immediate, origin, rpts1, -3, fTexLength); // tylko jeśli jest z prawej
|
||||
if ((fTexHeight1 >= 0.0) ? true : (side != 0.0))
|
||||
Segment->RenderLoft( immediate, rpts2, -3, fTexLength); // tylko jeśli jest z lewej
|
||||
Segment->RenderLoft( immediate, origin, rpts2, -3, fTexLength); // tylko jeśli jest z lewej
|
||||
}
|
||||
else
|
||||
{ // pobocza zwykłe, brak przechyłki
|
||||
if ((fTexHeight1 >= 0.0) ? true : (slop != 0.0))
|
||||
Segment->RenderLoft( immediate, rpts1, 3, fTexLength);
|
||||
Segment->RenderLoft( immediate, origin, rpts1, 3, fTexLength);
|
||||
if ((fTexHeight1 >= 0.0) ? true : (side != 0.0))
|
||||
Segment->RenderLoft( immediate, rpts2, 3, fTexLength);
|
||||
Segment->RenderLoft( immediate, origin, rpts2, 3, fTexLength);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1438,19 +1447,19 @@ void TTrack::Compile(GLuint tex)
|
||||
if( SwitchExtension->iRoads == 3 ) {
|
||||
// mogą być tylko 3 drogi zamiast 4
|
||||
SwitchExtension->iPoints =
|
||||
5 + SwitchExtension->Segments[ 0 ]->RaSegCount() +
|
||||
SwitchExtension->Segments[ 1 ]->RaSegCount() +
|
||||
SwitchExtension->Segments[ 2 ]->RaSegCount();
|
||||
SwitchExtension->Segments[ 0 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 1 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 2 ]->RaSegCount();
|
||||
}
|
||||
else {
|
||||
SwitchExtension->iPoints =
|
||||
5 + SwitchExtension->Segments[ 2 ]->RaSegCount() +
|
||||
SwitchExtension->Segments[ 3 ]->RaSegCount() +
|
||||
SwitchExtension->Segments[ 4 ]->RaSegCount() +
|
||||
SwitchExtension->Segments[ 5 ]->RaSegCount(); // mogą być tylko 3 drogi
|
||||
SwitchExtension->Segments[ 2 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 3 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 4 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 5 ]->RaSegCount();
|
||||
}
|
||||
// tablica utworzona z zapasem, ale nie wypełniona współrzędnymi
|
||||
SwitchExtension->vPoints = new vector3[SwitchExtension->iPoints];
|
||||
SwitchExtension->vPoints = new vector3[ SwitchExtension->iPoints + SwitchExtension->iRoads ];
|
||||
}
|
||||
vector3 *b =
|
||||
SwitchExtension->bPoints ?
|
||||
@@ -1545,58 +1554,62 @@ void TTrack::Compile(GLuint tex)
|
||||
if (SwitchExtension->iRoads == 4)
|
||||
{ // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony odcinka
|
||||
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
|
||||
SwitchExtension->Segments[ 2 ]->RenderLoft( immediate, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render );
|
||||
SwitchExtension->Segments[ 3 ]->RenderLoft( immediate, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render );
|
||||
SwitchExtension->Segments[ 4 ]->RenderLoft( immediate, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render );
|
||||
SwitchExtension->Segments[ 5 ]->RenderLoft( immediate, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render );
|
||||
SwitchExtension->Segments[ 2 ]->RenderLoft( immediate, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render );
|
||||
SwitchExtension->Segments[ 3 ]->RenderLoft( immediate, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render );
|
||||
SwitchExtension->Segments[ 4 ]->RenderLoft( immediate, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render );
|
||||
SwitchExtension->Segments[ 5 ]->RenderLoft( immediate, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render );
|
||||
}
|
||||
}
|
||||
else
|
||||
// to będzie ewentualnie dla prostego na skrzyżowaniu trzech dróg
|
||||
{ // punkt 3 pokrywa się z punktem 1, jak w zwrotnicy; połączenie 1->2 nie musi być prostoliniowe
|
||||
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
|
||||
SwitchExtension->Segments[ 2 ]->RenderLoft( immediate, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render ); // z P2 do P4
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( immediate, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render ); // z P4 do P3=P1 (odwrócony)
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( immediate, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render ); // z P1 do P2
|
||||
SwitchExtension->Segments[ 2 ]->RenderLoft( immediate, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render ); // z P2 do P4
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( immediate, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render ); // z P4 do P3=P1 (odwrócony)
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( immediate, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render ); // z P1 do P2
|
||||
}
|
||||
}
|
||||
}
|
||||
// renderowanie nawierzchni na końcu
|
||||
double sina0 = sin(a[0]), cosa0 = cos(a[0]);
|
||||
double u, v;
|
||||
if (!SwitchExtension->bPoints) // jeśli tablica nie wypełniona
|
||||
if (b) // ale jest wskaźnik do tablicy - może nie być?
|
||||
{ // coś się gubi w obliczeniach na wskaźnikach
|
||||
// ustalenie liczby punktów, bo mogło wyjść inaczej niż
|
||||
i = (int)(((size_t)(b)) - ((size_t)(SwitchExtension->vPoints))) / sizeof(vector3);
|
||||
// policzone z góry
|
||||
if (i > 0)
|
||||
{ // jeśli zostało to właśnie utworzone
|
||||
if (SwitchExtension->iPoints > i) // jeśli wyszło mniej niż było miejsca
|
||||
SwitchExtension->iPoints = i; // domknięcie wachlarza
|
||||
else {
|
||||
// jak tutaj wejdzie, to błąd jest - zrobić miejsce na powtórzenie pierwszego punktu na końcu
|
||||
--SwitchExtension->iPoints;
|
||||
}
|
||||
SwitchExtension->vPoints[SwitchExtension->iPoints++] = SwitchExtension->vPoints[0];
|
||||
SwitchExtension->bPoints = true; // tablica punktów została wypełniona
|
||||
}
|
||||
}
|
||||
if( ( false == SwitchExtension->bPoints ) // jeśli tablica nie wypełniona
|
||||
&& ( b != nullptr ) ) {
|
||||
SwitchExtension->bPoints = true; // tablica punktów została wypełniona
|
||||
}
|
||||
|
||||
if (TextureID1) // jeśli podana tekstura nawierzchni
|
||||
if ( (tex == TextureID1) || (tex == 0) ) // jeśli pasuje do grupy (tex)
|
||||
{
|
||||
if (!tex)
|
||||
GfxRenderer.Bind( TextureID1 );
|
||||
glBegin(GL_TRIANGLE_FAN); // takie kółeczko będzie
|
||||
// we start with a vertex in the middle...
|
||||
glNormal3f(0, 1, 0);
|
||||
glTexCoord2f(0.5, 0.5); //środek tekstury na środku skrzyżowania
|
||||
glVertex3f(oxz.x, oxz.y, oxz.z);
|
||||
for (i = SwitchExtension->iPoints - 1; i >= 0; --i)
|
||||
glVertex3f(
|
||||
oxz.x - origin.x,
|
||||
oxz.y - origin.y,
|
||||
oxz.z - origin.z );
|
||||
// ...and add one extra vertex to close the fan...
|
||||
glNormal3f( 0, 1, 0 );
|
||||
// mapowanie we współrzędnych scenerii
|
||||
u = ( SwitchExtension->vPoints[ 0 ].x - oxz.x + origin.x ) / fTexLength;
|
||||
v = ( SwitchExtension->vPoints[ 0 ].z - oxz.z + origin.z ) / ( fTexRatio1 * fTexLength );
|
||||
glTexCoord2f(
|
||||
cosa0 * u + sina0 * v + 0.5,
|
||||
-sina0 * u + cosa0 * v + 0.5 );
|
||||
glVertex3f(
|
||||
SwitchExtension->vPoints[ 0 ].x,
|
||||
SwitchExtension->vPoints[ 0 ].y,
|
||||
SwitchExtension->vPoints[ 0 ].z );
|
||||
|
||||
for ( i = SwitchExtension->iPoints + SwitchExtension->iRoads - 1; i >= 0; --i )
|
||||
{
|
||||
glNormal3f(0, 1, 0);
|
||||
// mapowanie we współrzędnych scenerii
|
||||
u = (SwitchExtension->vPoints[i].x - oxz.x) / fTexLength;
|
||||
v = (SwitchExtension->vPoints[i].z - oxz.z) / (fTexRatio1 * fTexLength);
|
||||
u = (SwitchExtension->vPoints[i].x - oxz.x + origin.x) / fTexLength;
|
||||
v = (SwitchExtension->vPoints[i].z - oxz.z + origin.z) / (fTexRatio1 * fTexLength);
|
||||
glTexCoord2f(
|
||||
cosa0 * u + sina0 * v + 0.5,
|
||||
-sina0 * u + cosa0 * v + 0.5);
|
||||
@@ -1622,7 +1635,7 @@ void TTrack::Compile(GLuint tex)
|
||||
{
|
||||
if (!tex)
|
||||
GfxRenderer.Bind( TextureID1 );
|
||||
Segment->RenderLoft( immediate, bpts1, numPts, fTexLength);
|
||||
Segment->RenderLoft( immediate, origin, bpts1, numPts, fTexLength);
|
||||
}
|
||||
if (TextureID2)
|
||||
if (tex ? TextureID2 == tex : true) // jeśli pasuje do grupy (tex)
|
||||
@@ -1634,8 +1647,8 @@ void TTrack::Compile(GLuint tex)
|
||||
vector6(-rozp, -fTexHeight1, 0.0)}; // Ra: po kiego 0.1?
|
||||
if (!tex)
|
||||
GfxRenderer.Bind( TextureID2 ); // brzeg rzeki
|
||||
Segment->RenderLoft( immediate, rpts1, 3, fTexLength);
|
||||
Segment->RenderLoft( immediate, rpts2, 3, fTexLength);
|
||||
Segment->RenderLoft( immediate, origin, rpts1, 3, fTexLength );
|
||||
Segment->RenderLoft( immediate, origin, rpts2, 3, fTexLength );
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1779,31 +1792,33 @@ int TTrack::RaArrayPrepare()
|
||||
if( SwitchExtension->iRoads == 3 ) {
|
||||
// mogą być tylko 3 drogi zamiast 4
|
||||
SwitchExtension->iPoints =
|
||||
5
|
||||
+ SwitchExtension->Segments[ 0 ]->RaSegCount()
|
||||
SwitchExtension->Segments[ 0 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 1 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 2 ]->RaSegCount();
|
||||
}
|
||||
else {
|
||||
SwitchExtension->iPoints =
|
||||
5
|
||||
+ SwitchExtension->Segments[ 2 ]->RaSegCount()
|
||||
SwitchExtension->Segments[ 2 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 3 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 4 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 5 ]->RaSegCount();
|
||||
}
|
||||
/*
|
||||
if (fTexHeight1 >= 0) {
|
||||
// normalne pobocze, na razie się składa z
|
||||
return SwitchExtension->iPoints * ((TextureID1 ? 1 : 0) + (TextureID2 ? 12 : 0));
|
||||
return ( ( TextureID1 ? SwitchExtension->iPoints + SwitchExtension->iRoads + 2 : 0 ) + ( TextureID2 ? SwitchExtension->iPoints * 12 : 0 ) );
|
||||
}
|
||||
else {
|
||||
// jeśli fTexHeight1<0, to są chodniki i może któregoś nie być
|
||||
return SwitchExtension->iPoints * ((TextureID1 ? 1 : 0) + (TextureID2 ? 6 : 0 ));
|
||||
return ( ( TextureID1 ? SwitchExtension->iPoints + SwitchExtension->iRoads + 2 : 0 ) + ( TextureID2 ? SwitchExtension->iPoints * 6 : 0 ) );
|
||||
}
|
||||
*/
|
||||
// each sub-segment covers only one side of the road, so it has points for single sideroad, if any
|
||||
return ( ( TextureID1 ? SwitchExtension->iPoints + SwitchExtension->iRoads + 2 : 0 ) + ( TextureID2 ? SwitchExtension->iPoints * 6 : 0 ) );
|
||||
}
|
||||
else // standardowo dla zwykłej drogi
|
||||
if (fTexHeight1 >= 0) // jeśli fTexHeight1<0, to są chodniki i może któregoś nie być
|
||||
return (Segment->RaSegCount()) *
|
||||
return ( Segment->RaSegCount()) *
|
||||
((TextureID1 ? 4 : 0) + (TextureID2 ? 12 : 0)); // może nie być poziomego!
|
||||
else
|
||||
return (Segment->RaSegCount()) *
|
||||
@@ -1815,7 +1830,7 @@ int TTrack::RaArrayPrepare()
|
||||
return 0;
|
||||
};
|
||||
|
||||
void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start)
|
||||
void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start, int const Vertexcount)
|
||||
{ // wypełnianie tablic VBO
|
||||
// Ra: trzeba rozdzielić szyny od podsypki, aby móc grupować wg tekstur
|
||||
double fHTW = 0.5 * fabs(fTrackWidth);
|
||||
@@ -1850,6 +1865,9 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start)
|
||||
hypot2 = hypot1;
|
||||
normal2 = normal1;
|
||||
}
|
||||
|
||||
auto const origin = pMyNode->m_rootposition;
|
||||
|
||||
double roll1, roll2;
|
||||
switch (iCategoryFlag & 15)
|
||||
{
|
||||
@@ -1951,16 +1969,16 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start)
|
||||
bpts1[3] = vector6(-rozp, -fTexHeight1 - 0.18, 0.5 + map12, -normal1.x, -normal1.y, 0.0); // prawy skos
|
||||
}
|
||||
}
|
||||
Segment->RenderLoft(Vert, bpts1, iTrapezoid ? -4 : 4, fTexLength);
|
||||
Segment->RenderLoft(Vert, origin, bpts1, iTrapezoid ? -4 : 4, fTexLength);
|
||||
}
|
||||
if (TextureID1)
|
||||
{ // szyny - generujemy dwie, najwyżej rysować się będzie jedną
|
||||
Segment->RenderLoft(Vert, rpts1, iTrapezoid ? -nnumPts : nnumPts, fTexLength);
|
||||
Segment->RenderLoft(Vert, rpts2, iTrapezoid ? -nnumPts : nnumPts, fTexLength);
|
||||
Segment->RenderLoft(Vert, origin, rpts1, iTrapezoid ? -nnumPts : nnumPts, fTexLength);
|
||||
Segment->RenderLoft(Vert, origin, rpts2, iTrapezoid ? -nnumPts : nnumPts, fTexLength);
|
||||
}
|
||||
break;
|
||||
case tt_Switch: // dla zwrotnicy dwa razy szyny
|
||||
if (TextureID1) // Ra: !!!! tu jest do poprawienia
|
||||
if( TextureID1 || TextureID2 )
|
||||
{ // iglice liczone tylko dla zwrotnic
|
||||
vector6 rpts3[24], rpts4[24];
|
||||
for (i = 0; i < 12; ++i)
|
||||
@@ -1980,27 +1998,34 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start)
|
||||
}
|
||||
if (SwitchExtension->RightSwitch)
|
||||
{ // nowa wersja z SPKS, ale odwrotnie lewa/prawa
|
||||
SwitchExtension->Segments[0]->RenderLoft( Vert, rpts2, nnumPts, fTexLength);
|
||||
SwitchExtension->Segments[0]->RenderLoft( Vert, rpts1, nnumPts, fTexLength, 1.0, 2 );
|
||||
SwitchExtension->iLeftVBO = Vert - Start; // indeks lewej iglicy
|
||||
SwitchExtension->Segments[0]->RenderLoft( Vert, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2 );
|
||||
if( TextureID1 ) {
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts2, nnumPts, fTexLength );
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts1, nnumPts, fTexLength, 1.0, 2 );
|
||||
|
||||
SwitchExtension->iRightVBO = Vert - Start; // indeks prawej iglicy
|
||||
SwitchExtension->Segments[1]->RenderLoft( Vert, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -fMaxOffset + SwitchExtension->fOffset1 );
|
||||
SwitchExtension->Segments[1]->RenderLoft( Vert, rpts2, nnumPts, fTexLength, 1.0, 2 );
|
||||
SwitchExtension->Segments[1]->RenderLoft( Vert, rpts1, nnumPts, fTexLength );
|
||||
SwitchExtension->iLeftVBO = Vert - Start; // indeks lewej iglicy
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2 );
|
||||
}
|
||||
if( TextureID2 ) {
|
||||
SwitchExtension->iRightVBO = Vert - Start; // indeks prawej iglicy
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -fMaxOffset + SwitchExtension->fOffset1 );
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts2, nnumPts, fTexLength, 1.0, 2 );
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts1, nnumPts, fTexLength );
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // lewa działa lepiej niż prawa
|
||||
SwitchExtension->Segments[0]->RenderLoft( Vert, rpts1, nnumPts, fTexLength); // lewa szyna normalna cała
|
||||
SwitchExtension->Segments[0]->RenderLoft( Vert, rpts2, nnumPts, fTexLength, 1.0, 2 ); // prawa szyna za iglicą
|
||||
SwitchExtension->iLeftVBO = Vert - Start; // indeks lewej iglicy
|
||||
SwitchExtension->Segments[0]->RenderLoft( Vert, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -SwitchExtension->fOffset2); // prawa iglica
|
||||
|
||||
SwitchExtension->iRightVBO = Vert - Start; // indeks prawej iglicy
|
||||
SwitchExtension->Segments[1]->RenderLoft( Vert, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, fMaxOffset - SwitchExtension->fOffset1); // lewa iglica
|
||||
SwitchExtension->Segments[1]->RenderLoft( Vert, rpts1, nnumPts, fTexLength, 1.0, 2); // lewa szyna za iglicą
|
||||
SwitchExtension->Segments[1]->RenderLoft( Vert, rpts2, nnumPts, fTexLength); // prawa szyna normalnie cała
|
||||
if( TextureID1 ) {
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts1, nnumPts, fTexLength ); // lewa szyna normalna cała
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts2, nnumPts, fTexLength, 1.0, 2 ); // prawa szyna za iglicą
|
||||
SwitchExtension->iLeftVBO = Vert - Start; // indeks lewej iglicy
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -SwitchExtension->fOffset2 ); // prawa iglica
|
||||
}
|
||||
if( TextureID2 ) {
|
||||
SwitchExtension->iRightVBO = Vert - Start; // indeks prawej iglicy
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, fMaxOffset - SwitchExtension->fOffset1 ); // lewa iglica
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts1, nnumPts, fTexLength, 1.0, 2 ); // lewa szyna za iglicą
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts2, nnumPts, fTexLength ); // prawa szyna normalnie cała
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2034,7 +2059,7 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start)
|
||||
}
|
||||
if (TextureID1) // jeśli podana była tekstura, generujemy trójkąty
|
||||
{ // tworzenie trójkątów nawierzchni szosy
|
||||
Segment->RenderLoft(Vert, bpts1, iTrapezoid ? -2 : 2, fTexLength);
|
||||
Segment->RenderLoft(Vert, origin, bpts1, iTrapezoid ? -2 : 2, fTexLength);
|
||||
}
|
||||
if (TextureID2)
|
||||
{ // pobocze drogi - poziome przy przechyłce (a może krawężnik i chodnik zrobić jak w Midtown Madness 2?)
|
||||
@@ -2114,18 +2139,22 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start)
|
||||
if( iTrapezoid ) // trapez albo przechyłki
|
||||
{ // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony
|
||||
// odcinka
|
||||
if( ( fTexHeight1 >= 0.0 ) || ( slop != 0.0 ) )
|
||||
Segment->RenderLoft( Vert, rpts1, -3, fTexLength ); // tylko jeśli jest z prawej
|
||||
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) )
|
||||
Segment->RenderLoft( Vert, rpts2, -3, fTexLength ); // tylko jeśli jest z lewej
|
||||
}
|
||||
else { // pobocza zwykłe, brak przechyłki
|
||||
if( ( fTexHeight1 >= 0.0 ) || ( slop != 0.0 ) )
|
||||
Segment->RenderLoft( Vert, rpts1, 3, fTexLength );
|
||||
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) )
|
||||
Segment->RenderLoft( Vert, rpts2, 3, fTexLength );
|
||||
if( ( fTexHeight1 >= 0.0 ) || ( slop != 0.0 ) ) {
|
||||
Segment->RenderLoft( Vert, origin, rpts1, -3, fTexLength ); // tylko jeśli jest z prawej
|
||||
}
|
||||
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
|
||||
Segment->RenderLoft( Vert, origin, rpts2, -3, fTexLength ); // tylko jeśli jest z lewej
|
||||
}
|
||||
}
|
||||
else { // pobocza zwykłe, brak przechyłki
|
||||
if( ( fTexHeight1 >= 0.0 ) || ( slop != 0.0 ) ) {
|
||||
Segment->RenderLoft( Vert, origin, rpts1, 3, fTexLength );
|
||||
}
|
||||
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
|
||||
Segment->RenderLoft( Vert, origin, rpts2, 3, fTexLength );
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case tt_Cross: // skrzyżowanie dróg rysujemy inaczej
|
||||
@@ -2156,24 +2185,9 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start)
|
||||
int i; // ile punktów (może byc różna ilość punktów między drogami)
|
||||
if (!SwitchExtension->vPoints)
|
||||
{ // jeśli tablica punktów nie jest jeszcze utworzona, zliczamy punkty i tworzymy ją
|
||||
if( SwitchExtension->iRoads == 3 ) {
|
||||
// mogą być tylko 3 drogi zamiast 4
|
||||
SwitchExtension->iPoints =
|
||||
5
|
||||
+ SwitchExtension->Segments[ 0 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 1 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 2 ]->RaSegCount();
|
||||
}
|
||||
else {
|
||||
SwitchExtension->iPoints =
|
||||
5
|
||||
+ SwitchExtension->Segments[ 2 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 3 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 4 ]->RaSegCount()
|
||||
+ SwitchExtension->Segments[ 5 ]->RaSegCount();
|
||||
}
|
||||
// tablica utworzona z zapasem, ale nie wypełniona współrzędnymi
|
||||
SwitchExtension->vPoints = new vector3[SwitchExtension->iPoints];
|
||||
// points were already counted during preparation stage
|
||||
// we'll need to add couple extra points for the complete fan we'll build
|
||||
SwitchExtension->vPoints = new vector3[SwitchExtension->iPoints + SwitchExtension->iRoads];
|
||||
}
|
||||
vector3 *b =
|
||||
SwitchExtension->bPoints ?
|
||||
@@ -2262,56 +2276,63 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start)
|
||||
if (SwitchExtension->iRoads == 4)
|
||||
{ // pobocza do trapezowatej nawierzchni - dodatkowe punkty z drugiej strony odcinka
|
||||
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
|
||||
SwitchExtension->Segments[ 2 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render );
|
||||
SwitchExtension->Segments[ 3 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render );
|
||||
SwitchExtension->Segments[ 4 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render );
|
||||
SwitchExtension->Segments[ 5 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render );
|
||||
SwitchExtension->Segments[ 2 ]->RenderLoft( Vert, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render );
|
||||
SwitchExtension->Segments[ 3 ]->RenderLoft( Vert, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render );
|
||||
SwitchExtension->Segments[ 4 ]->RenderLoft( Vert, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render );
|
||||
SwitchExtension->Segments[ 5 ]->RenderLoft( Vert, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render );
|
||||
}
|
||||
}
|
||||
else {
|
||||
// punkt 3 pokrywa się z punktem 1, jak w zwrotnicy; połączenie 1->2 nie musi być prostoliniowe
|
||||
if( ( fTexHeight1 >= 0.0 ) || ( side != 0.0 ) ) {
|
||||
SwitchExtension->Segments[ 2 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render ); // z P2 do P4
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render ); // z P4 do P3=P1 (odwrócony)
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, false, &b, render ); // z P1 do P2
|
||||
SwitchExtension->Segments[ 2 ]->RenderLoft( Vert, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render ); // z P2 do P4
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( Vert, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render ); // z P4 do P3=P1 (odwrócony)
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( Vert, origin, rpts2, -3, fTexLength, 1.0, 0, 0, 0.0, &b, render ); // z P1 do P2
|
||||
}
|
||||
}
|
||||
}
|
||||
// renderowanie nawierzchni na końcu
|
||||
double sina0 = sin(a[0]), cosa0 = cos(a[0]);
|
||||
double u, v;
|
||||
if (!SwitchExtension->bPoints) // jeśli tablica nie wypełniona
|
||||
if (b) // ale jest wskaźnik do tablicy - może nie być?
|
||||
{ // coś się gubi w obliczeniach na wskaźnikach
|
||||
// ustalenie liczby punktów, bo mogło wyjść inaczej niż policzone z góry
|
||||
i = (int)(((size_t)(b)) - ((size_t)(SwitchExtension->vPoints))) / sizeof(vector3);
|
||||
if (i > 0)
|
||||
{ // jeśli zostało to właśnie utworzone
|
||||
SwitchExtension->iPoints = std::min( SwitchExtension->iPoints - 2, i );
|
||||
SwitchExtension->vPoints[SwitchExtension->iPoints++] = SwitchExtension->vPoints[0];
|
||||
++SwitchExtension->iPoints; // we'll add one extra point in the middle
|
||||
SwitchExtension->bPoints = true; // tablica punktów została wypełniona
|
||||
}
|
||||
}
|
||||
if( ( false == SwitchExtension->bPoints ) // jeśli tablica nie wypełniona
|
||||
&& ( b != nullptr ) ) {
|
||||
SwitchExtension->bPoints = true; // tablica punktów została wypełniona
|
||||
}
|
||||
|
||||
if (TextureID1) {
|
||||
// jeśli podana tekstura nawierzchni
|
||||
// jeśli podana tekstura nawierzchni
|
||||
// we start with a vertex in the middle...
|
||||
Vert->nx = 0.0;
|
||||
Vert->ny = 1.0;
|
||||
Vert->nz = 0.0;
|
||||
Vert->u = 0.5;
|
||||
Vert->v = 0.5;
|
||||
Vert->x = oxz.x;
|
||||
Vert->y = oxz.y;
|
||||
Vert->z = oxz.z;
|
||||
Vert->x = oxz.x - origin.x;
|
||||
Vert->y = oxz.y - origin.y;
|
||||
Vert->z = oxz.z - origin.z;
|
||||
++Vert;
|
||||
for (i = SwitchExtension->iPoints - 2; i >= 0; --i)
|
||||
// ...and add one extra vertex to close the fan...
|
||||
Vert->nx = 0.0;
|
||||
Vert->ny = 1.0;
|
||||
Vert->nz = 0.0;
|
||||
// mapowanie we współrzędnych scenerii
|
||||
u = ( SwitchExtension->vPoints[ 0 ].x - oxz.x + origin.x ) / fTexLength;
|
||||
v = ( SwitchExtension->vPoints[ 0 ].z - oxz.z + origin.z ) / ( fTexRatio1 * fTexLength );
|
||||
Vert->u = cosa0 * u + sina0 * v + 0.5;
|
||||
Vert->v = -sina0 * u + cosa0 * v + 0.5;
|
||||
Vert->x = SwitchExtension->vPoints[ 0 ].x;
|
||||
Vert->y = SwitchExtension->vPoints[ 0 ].y;
|
||||
Vert->z = SwitchExtension->vPoints[ 0 ].z;
|
||||
++Vert;
|
||||
// ...then draw the precalculated rest
|
||||
for (i = SwitchExtension->iPoints + SwitchExtension->iRoads - 1; i >= 0; --i)
|
||||
{
|
||||
Vert->nx = 0.0;
|
||||
Vert->ny = 1.0;
|
||||
Vert->nz = 0.0;
|
||||
// mapowanie we współrzędnych scenerii
|
||||
u = (SwitchExtension->vPoints[i].x - oxz.x) / fTexLength;
|
||||
v = (SwitchExtension->vPoints[i].z - oxz.z) / (fTexRatio1 * fTexLength);
|
||||
u = (SwitchExtension->vPoints[i].x - oxz.x + origin.x ) / fTexLength;
|
||||
v = (SwitchExtension->vPoints[i].z - oxz.z + origin.z ) / (fTexRatio1 * fTexLength);
|
||||
Vert->u = cosa0 * u + sina0 * v + 0.5;
|
||||
Vert->v = -sina0 * u + cosa0 * v + 0.5;
|
||||
Vert->x = SwitchExtension->vPoints[ i ].x;
|
||||
@@ -2321,8 +2342,8 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start)
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // tt_cross
|
||||
} // road
|
||||
break;
|
||||
case 4: // Ra: rzeki na razie jak drogi, przechyłki na pewno nie mają
|
||||
switch (eType) // dalej zależnie od typu
|
||||
@@ -2357,7 +2378,7 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start)
|
||||
}
|
||||
if (TextureID1) // jeśli podana była tekstura, generujemy trójkąty
|
||||
{ // tworzenie trójkątów nawierzchni szosy
|
||||
Segment->RenderLoft(Vert, bpts1, iTrapezoid ? -2 : 2, fTexLength);
|
||||
Segment->RenderLoft(Vert, origin, bpts1, iTrapezoid ? -2 : 2, fTexLength);
|
||||
}
|
||||
if (TextureID2)
|
||||
{ // pobocze drogi - poziome przy przechyłce (a może krawężnik i chodnik zrobić jak w
|
||||
@@ -2379,19 +2400,20 @@ void TTrack::RaArrayFill(CVertNormTex *Vert, const CVertNormTex *Start)
|
||||
rpts2[3] = vector6(bpts1[3].x, bpts1[3].y, 1.0);
|
||||
rpts2[4] = vector6(bpts1[3].x - side2, bpts1[3].y, 0.5);
|
||||
rpts2[5] = vector6(-rozp2, -fTexHeight2, 0.0); // prawy brzeg prawego pobocza
|
||||
Segment->RenderLoft(Vert, rpts1, -3, fTexLength);
|
||||
Segment->RenderLoft(Vert, rpts2, -3, fTexLength);
|
||||
Segment->RenderLoft(Vert, origin, rpts1, -3, fTexLength);
|
||||
Segment->RenderLoft(Vert, origin, rpts2, -3, fTexLength);
|
||||
}
|
||||
else
|
||||
{ // pobocza zwykłe, brak przechyłki
|
||||
Segment->RenderLoft(Vert, rpts1, 3, fTexLength);
|
||||
Segment->RenderLoft(Vert, rpts2, 3, fTexLength);
|
||||
Segment->RenderLoft(Vert, origin, rpts1, 3, fTexLength);
|
||||
Segment->RenderLoft(Vert, origin, rpts2, 3, fTexLength);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return;
|
||||
};
|
||||
|
||||
void TTrack::RaRenderVBO( int iPtr ) { // renderowanie z użyciem VBO
|
||||
@@ -2405,12 +2427,12 @@ void TTrack::RaRenderVBO( int iPtr ) { // renderowanie z użyciem VBO
|
||||
if( eType == tt_Switch ) // dla zwrotnicy tylko szyny
|
||||
{
|
||||
int const bladesegmentcount = 2;
|
||||
if( TextureID1 )
|
||||
if( TextureID1 ) {
|
||||
if( ( seg = SwitchExtension->Segments[ 0 ]->RaSegCount() ) > 0 ) {
|
||||
GfxRenderer.Bind( TextureID1 ); // szyny +
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * seg );
|
||||
iPtr += 24 * seg;
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * (seg - bladesegmentcount) );
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * ( seg - bladesegmentcount ) );
|
||||
// NOTE: due to way blades bend need to render each segment separately, or some unwanted edges may show
|
||||
iPtr += 24 * ( seg - bladesegmentcount );
|
||||
for( int i = 0; i < bladesegmentcount; ++i ) {
|
||||
@@ -2418,7 +2440,8 @@ void TTrack::RaRenderVBO( int iPtr ) { // renderowanie z użyciem VBO
|
||||
iPtr += 24;
|
||||
}
|
||||
}
|
||||
if( TextureID2 )
|
||||
}
|
||||
if( TextureID2 ) {
|
||||
if( ( seg = SwitchExtension->Segments[ 1 ]->RaSegCount() ) > 0 ) {
|
||||
GfxRenderer.Bind( TextureID2 );
|
||||
// NOTE: due to way blades bend need to render each segment separately, or some unwanted edges may show
|
||||
@@ -2431,6 +2454,7 @@ void TTrack::RaRenderVBO( int iPtr ) { // renderowanie z użyciem VBO
|
||||
::glDrawArrays( GL_TRIANGLE_STRIP, iPtr, 24 * seg );
|
||||
iPtr += 24 * seg;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // dla toru podsypka plus szyny
|
||||
{
|
||||
@@ -2513,7 +2537,7 @@ void TTrack::RaRenderVBO( int iPtr ) { // renderowanie z użyciem VBO
|
||||
if( TextureID1 ) {
|
||||
// roads
|
||||
GfxRenderer.Bind( TextureID1 );
|
||||
::glDrawArrays( GL_TRIANGLE_FAN, iPtr, SwitchExtension->iPoints );
|
||||
::glDrawArrays( GL_TRIANGLE_FAN, iPtr, SwitchExtension->iPoints + SwitchExtension->iRoads + 2 );
|
||||
iPtr += SwitchExtension->iPoints;
|
||||
}
|
||||
}
|
||||
@@ -2581,11 +2605,7 @@ void TTrack::RenderDyn()
|
||||
{ // renderowanie nieprzezroczystych fragmentów pojazdów
|
||||
for( auto dynamic : Dynamics ) {
|
||||
// sam sprawdza, czy VBO; zmienia kontekst VBO!
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
dynamic->Render();
|
||||
#else
|
||||
GfxRenderer.Render( dynamic );
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2593,11 +2613,7 @@ void TTrack::RenderDynAlpha()
|
||||
{ // renderowanie przezroczystych fragmentów pojazdów
|
||||
for( auto dynamic : Dynamics ) {
|
||||
// sam sprawdza, czy VBO; zmienia kontekst VBO!
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
dynamic->RenderAlpha();
|
||||
#else
|
||||
GfxRenderer.Render_Alpha( dynamic );
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2870,19 +2886,22 @@ TTrack * TTrack::RaAnimate(GLuint const Vertexbuffer)
|
||||
|
||||
// fetch current blade geometry
|
||||
std::vector<CVertNormTex> bladesbuffer; bladesbuffer.resize( 2 * 2 * 24 ); // 2 blades, 2 segments each
|
||||
/*
|
||||
::glGetBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
SwitchExtension->iLeftVBO * sizeof( CVertNormTex ),
|
||||
bladesbuffer.size() * sizeof( CVertNormTex ),
|
||||
bladesbuffer.data() );
|
||||
*/
|
||||
auto bladevertices = bladesbuffer.data();
|
||||
auto const origin = pMyNode->m_rootposition;
|
||||
if( SwitchExtension->RightSwitch ) { // nowa wersja z SPKS, ale odwrotnie lewa/prawa
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( bladevertices, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2, true );
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( bladevertices, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -fMaxOffset + SwitchExtension->fOffset1, true );
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( bladevertices, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, SwitchExtension->fOffset2 /*, true*/ );
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( bladevertices, origin, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -fMaxOffset + SwitchExtension->fOffset1 /*, true*/ );
|
||||
}
|
||||
else {
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( bladevertices, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -SwitchExtension->fOffset2, true ); // prawa iglica
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( bladevertices, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, fMaxOffset - SwitchExtension->fOffset1, true ); // lewa iglica
|
||||
SwitchExtension->Segments[ 0 ]->RenderLoft( bladevertices, origin, rpts4, -nnumPts, fTexLength, 1.0, 0, 2, -SwitchExtension->fOffset2 /*, true*/ ); // prawa iglica
|
||||
SwitchExtension->Segments[ 1 ]->RenderLoft( bladevertices, origin, rpts3, -nnumPts, fTexLength, 1.0, 0, 2, fMaxOffset - SwitchExtension->fOffset1 /*, true*/ ); // lewa iglica
|
||||
}
|
||||
// push back updated geometry
|
||||
::glBufferSubData(
|
||||
@@ -2936,8 +2955,8 @@ TTrack * TTrack::RaAnimate(GLuint const Vertexbuffer)
|
||||
int size = RaArrayPrepare(); // wielkość tabeli potrzebna dla tej obrotnicy
|
||||
CVertNormTex *Vert = new CVertNormTex[size]; // bufor roboczy
|
||||
// CVertNormTex *v=Vert; //zmieniane przez
|
||||
RaArrayFill(Vert, Vert - SwitchExtension->iLeftVBO); // iLeftVBO powinno zostać niezmienione
|
||||
glBufferSubData(
|
||||
RaArrayFill(Vert, Vert - SwitchExtension->iLeftVBO, size); // iLeftVBO powinno zostać niezmienione
|
||||
::glBufferSubData(
|
||||
GL_ARRAY_BUFFER, SwitchExtension->iLeftVBO * sizeof(CVertNormTex),
|
||||
size * sizeof(CVertNormTex), Vert); // wysłanie fragmentu bufora VBO
|
||||
}
|
||||
|
||||
2
Track.h
2
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)
|
||||
|
||||
218
Traction.cpp
218
Traction.cpp
@@ -109,7 +109,7 @@ TTraction::~TTraction()
|
||||
glDeleteLists(uiDisplayList, 1);
|
||||
}
|
||||
|
||||
void TTraction::Optimize()
|
||||
void TTraction::Optimize( Math3D::vector3 const &Origin )
|
||||
{
|
||||
if (Global::bUseVBO)
|
||||
return;
|
||||
@@ -125,13 +125,13 @@ void TTraction::Optimize()
|
||||
// Przewoz jezdny 1 'Marcin
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(
|
||||
pPoint1.x - (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset,
|
||||
pPoint1.y,
|
||||
pPoint1.z - (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset);
|
||||
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,
|
||||
pPoint2.y,
|
||||
pPoint2.z - (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset);
|
||||
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;
|
||||
@@ -147,29 +147,39 @@ void TTraction::Optimize()
|
||||
if (Wires > 1)
|
||||
{
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(pPoint3.x, pPoint3.y, pPoint3.z);
|
||||
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,
|
||||
pt3.y - std::sqrt(t) * fHeightDifference,
|
||||
pt3.z);
|
||||
pt3.x - Origin.x,
|
||||
pt3.y - std::sqrt(t) * fHeightDifference - Origin.y,
|
||||
pt3.z - Origin.z );
|
||||
f += step;
|
||||
}
|
||||
glVertex3f(pPoint4.x, pPoint4.y, pPoint4.z);
|
||||
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, pPoint1.y,
|
||||
pPoint1.z + (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset);
|
||||
glVertex3f(pPoint2.x + (pPoint2.z / ddp - pPoint1.z / ddp) * WireOffset, pPoint2.y,
|
||||
pPoint2.z + (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset);
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -178,22 +188,29 @@ void TTraction::Optimize()
|
||||
if (Wires == 4)
|
||||
{
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(pPoint3.x, pPoint3.y - 0.65f * fHeightDifference, pPoint3.z);
|
||||
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,
|
||||
pt3.x - Origin.x,
|
||||
pt3.y - std::sqrt( t ) * fHeightDifference - (
|
||||
( ( i == 0 )
|
||||
|| ( i == iNumSections - 2 ) ) ?
|
||||
0.25f * fHeightDifference :
|
||||
0.05 ),
|
||||
pt3.z);
|
||||
0.05 )
|
||||
- Origin.y,
|
||||
pt3.z - Origin.z );
|
||||
f += step;
|
||||
}
|
||||
glVertex3f(pPoint4.x, pPoint4.y - 0.65f * fHeightDifference, pPoint4.z);
|
||||
glVertex3f(
|
||||
pPoint4.x - Origin.x,
|
||||
pPoint4.y - 0.65f * fHeightDifference - Origin.y,
|
||||
pPoint4.z - Origin.z );
|
||||
glEnd();
|
||||
}
|
||||
|
||||
@@ -214,35 +231,35 @@ void TTraction::Optimize()
|
||||
if ((i % 2) == 0)
|
||||
{
|
||||
glVertex3f(
|
||||
pt3.x,
|
||||
pt3.y - std::sqrt(t) * fHeightDifference - ((i == 0) || (i == iNumSections - 2) ? flo : flo1),
|
||||
pt3.z);
|
||||
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,
|
||||
pt4.y,
|
||||
pt4.z - (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset);
|
||||
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,
|
||||
pt3.y - std::sqrt(t) * fHeightDifference - ((i == 0) || (i == iNumSections - 2) ? flo : flo1),
|
||||
pt3.z);
|
||||
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,
|
||||
pt4.y,
|
||||
pt4.z + (-pPoint2.x / ddp + pPoint1.x / ddp) * WireOffset);
|
||||
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,
|
||||
pt3.y - std::sqrt(t) * fHeightDifference - 0.05,
|
||||
pt3.z);
|
||||
pt3.x - Origin.x,
|
||||
pt3.y - std::sqrt(t) * fHeightDifference - 0.05 - Origin.y,
|
||||
pt3.z - Origin.z );
|
||||
glVertex3f(
|
||||
pt3.x,
|
||||
pt3.y - std::sqrt(t) * fHeightDifference,
|
||||
pt3.z);
|
||||
pt3.x - Origin.x,
|
||||
pt3.y - std::sqrt(t) * fHeightDifference - Origin.y,
|
||||
pt3.z - Origin.z );
|
||||
}
|
||||
f += step;
|
||||
}
|
||||
@@ -258,7 +275,7 @@ 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
|
||||
@@ -281,7 +298,7 @@ void TTraction::RenderDL(float mgn) // McZapkie: mgn to odleglosc od obserwatora
|
||||
::glColor4f( red, green, blue, linealpha );
|
||||
// draw code
|
||||
if (!uiDisplayList)
|
||||
Optimize(); // generowanie DL w miarę potrzeby
|
||||
Optimize( Origin ); // generowanie DL w miarę potrzeby
|
||||
::glCallList(uiDisplayList);
|
||||
// cleanup
|
||||
::glLineWidth(1.0);
|
||||
@@ -324,20 +341,24 @@ int TTraction::RaArrayPrepare()
|
||||
return iLines;
|
||||
};
|
||||
|
||||
void TTraction::RaArrayFill(CVertNormTex *Vert)
|
||||
int TTraction::RaArrayFill(CVertNormTex *Vert, Math3D::vector3 const &Origin)
|
||||
{ // wypełnianie tablic VBO
|
||||
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;
|
||||
@@ -351,10 +372,11 @@ 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;
|
||||
++debugvertexcount;
|
||||
for (int i = 0; i < iNumSections - 1; ++i)
|
||||
{
|
||||
pt3 = pPoint3 + v1 * f;
|
||||
@@ -362,54 +384,63 @@ void TTraction::RaArrayFill(CVertNormTex *Vert)
|
||||
if( ( Wires < 4 )
|
||||
|| ( ( i != 0 )
|
||||
&& ( i != iNumSections - 2 ) ) ) {
|
||||
Vert->x = pt3.x;
|
||||
Vert->y = pt3.y - std::sqrt( t ) * fHeightDifference;
|
||||
Vert->z = pt3.z;
|
||||
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 > 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;
|
||||
Vert->y = pPoint3.y - 0.65f * fHeightDifference;
|
||||
Vert->z = pPoint3.z;
|
||||
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;
|
||||
Vert->x = pt3.x - Origin.x;
|
||||
Vert->y = pt3.y - std::sqrt( t ) * fHeightDifference - (
|
||||
( ( i == 0 )
|
||||
|| ( i == iNumSections - 2 ) ) ?
|
||||
0.25f * fHeightDifference :
|
||||
0.05 );
|
||||
Vert->z = pt3.z;
|
||||
0.05 )
|
||||
- Origin.y;
|
||||
Vert->z = pt3.z - Origin.z;
|
||||
++Vert;
|
||||
++debugvertexcount;
|
||||
f += step;
|
||||
}
|
||||
Vert->x = pPoint4.x;
|
||||
Vert->y = pPoint4.y - 0.65f * fHeightDifference;
|
||||
Vert->z = pPoint4.z;
|
||||
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;
|
||||
|
||||
@@ -426,40 +457,47 @@ void TTraction::RaArrayFill(CVertNormTex *Vert)
|
||||
t = (1 - std::fabs(f - mid) * 2);
|
||||
|
||||
if( ( i % 2 ) == 0 ) {
|
||||
Vert->x = pt3.x;
|
||||
Vert->y = pt3.y - std::sqrt( t ) * fHeightDifference - ( ( i == 0 ) || ( i == iNumSections - 2 ) ? flo : flo1 );
|
||||
Vert->z = pt3.z;
|
||||
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;
|
||||
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;
|
||||
++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 = pt3.x;
|
||||
Vert->y = pt3.y - std::sqrt( t ) * fHeightDifference - ( ( i == 0 ) || ( i == iNumSections - 2 ) ? flo : flo1 );
|
||||
Vert->z = pt3.z;
|
||||
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;
|
||||
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;
|
||||
++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;
|
||||
Vert->y = pt3.y - std::sqrt( t ) * fHeightDifference - 0.05;
|
||||
Vert->z = pt3.z;
|
||||
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;
|
||||
Vert->x = pt3.x;
|
||||
Vert->y = pt3.y - std::sqrt( t ) * fHeightDifference;
|
||||
Vert->z = pt3.z;
|
||||
++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;
|
||||
}
|
||||
f += step;
|
||||
}
|
||||
}
|
||||
return debugvertexcount;
|
||||
};
|
||||
|
||||
void TTraction::RenderVBO(float mgn, int iPtr)
|
||||
|
||||
@@ -56,7 +56,7 @@ class TTraction
|
||||
int iTries = 0;
|
||||
int PowerState{ 0 }; // type of incoming power, if any
|
||||
|
||||
void Optimize();
|
||||
void Optimize( Math3D::vector3 const &Origin );
|
||||
|
||||
TTraction();
|
||||
~TTraction();
|
||||
@@ -66,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);
|
||||
|
||||
307
Train.cpp
307
Train.cpp
@@ -175,8 +175,10 @@ TTrain::commandhandler_map const TTrain::m_commandhandlers = {
|
||||
{ user_command::pantographlowerall, &TTrain::OnCommand_pantographlowerall },
|
||||
{ user_command::linebreakertoggle, &TTrain::OnCommand_linebreakertoggle },
|
||||
{ user_command::convertertoggle, &TTrain::OnCommand_convertertoggle },
|
||||
{ user_command::convertertogglelocal, &TTrain::OnCommand_convertertogglelocal },
|
||||
{ user_command::converteroverloadrelayreset, &TTrain::OnCommand_converteroverloadrelayreset },
|
||||
{ user_command::compressortoggle, &TTrain::OnCommand_compressortoggle },
|
||||
{ user_command::compressortogglelocal, &TTrain::OnCommand_compressortogglelocal },
|
||||
{ user_command::motorconnectorsopen, &TTrain::OnCommand_motorconnectorsopen },
|
||||
{ user_command::motordisconnect, &TTrain::OnCommand_motordisconnect },
|
||||
{ user_command::motoroverloadrelaythresholdtoggle, &TTrain::OnCommand_motoroverloadrelaythresholdtoggle },
|
||||
@@ -1727,6 +1729,69 @@ void TTrain::OnCommand_convertertoggle( TTrain *Train, command_data const &Comma
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_convertertogglelocal( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Train->mvOccupied->ConverterStart == start::automatic ) {
|
||||
// let the automatic thing do its automatic thing...
|
||||
return;
|
||||
}
|
||||
if( Train->ggConverterLocalButton.SubModel == nullptr ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( ( false == Train->mvOccupied->ConverterAllowLocal )
|
||||
&& ( Train->ggConverterLocalButton.GetValue() < 0.5 ) ) {
|
||||
// turn on
|
||||
// sound feedback
|
||||
if( Train->ggConverterLocalButton.GetValue() < 0.5 ) {
|
||||
Train->play_sound( Train->dsbSwitch );
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggConverterLocalButton.UpdateValue( 1.0 );
|
||||
// effect
|
||||
Train->mvOccupied->ConverterAllowLocal = true;
|
||||
/*
|
||||
if( true == Train->mvControlled->ConverterSwitch( true, range::local ) ) {
|
||||
// side effects
|
||||
// control the compressor, if it's paired with the converter
|
||||
if( Train->mvControlled->CompressorPower == 2 ) {
|
||||
// hunter-091012: tak jest poprawnie
|
||||
Train->mvControlled->CompressorSwitch( true, range::local );
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
else {
|
||||
//turn off
|
||||
// sound feedback
|
||||
if( Train->ggConverterLocalButton.GetValue() > 0.5 ) {
|
||||
Train->play_sound( Train->dsbSwitch );
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggConverterLocalButton.UpdateValue( 0.0 );
|
||||
// effect
|
||||
Train->mvOccupied->ConverterAllowLocal = false;
|
||||
/*
|
||||
if( true == Train->mvControlled->ConverterSwitch( false, range::local ) ) {
|
||||
// side effects
|
||||
// control the compressor, if it's paired with the converter
|
||||
if( Train->mvControlled->CompressorPower == 2 ) {
|
||||
// hunter-091012: tak jest poprawnie
|
||||
Train->mvControlled->CompressorSwitch( false, range::local );
|
||||
}
|
||||
// if there's no (low voltage) power source left, drop pantographs
|
||||
if( false == Train->mvControlled->Battery ) {
|
||||
Train->mvControlled->PantFront( false, range::local );
|
||||
Train->mvControlled->PantRear( false, range::local );
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_converteroverloadrelayreset( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Train->ggConverterFuseButton.SubModel == nullptr ) {
|
||||
@@ -1824,6 +1889,42 @@ void TTrain::OnCommand_compressortoggle( TTrain *Train, command_data const &Comm
|
||||
*/
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_compressortogglelocal( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
if( Train->mvOccupied->CompressorPower >= 2 ) {
|
||||
return;
|
||||
}
|
||||
if( Train->ggCompressorLocalButton.SubModel == nullptr ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// only reacting to press, so the switch doesn't flip back and forth if key is held down
|
||||
if( false == Train->mvOccupied->CompressorAllowLocal ) {
|
||||
// turn on
|
||||
// sound feedback
|
||||
if( Train->ggCompressorLocalButton.GetValue() < 0.5 ) {
|
||||
Train->play_sound( Train->dsbSwitch );
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggCompressorLocalButton.UpdateValue( 1.0 );
|
||||
// effect
|
||||
Train->mvOccupied->CompressorAllowLocal = true;
|
||||
}
|
||||
else {
|
||||
//turn off
|
||||
// sound feedback
|
||||
if( Train->ggCompressorLocalButton.GetValue() > 0.5 ) {
|
||||
Train->play_sound( Train->dsbSwitch );
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggCompressorLocalButton.UpdateValue( 0.0 );
|
||||
// effect
|
||||
Train->mvOccupied->CompressorAllowLocal = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TTrain::OnCommand_motorconnectorsopen( TTrain *Train, command_data const &Command ) {
|
||||
|
||||
// TODO: don't rely on presense of 3d model to determine presence of the switch
|
||||
@@ -1833,31 +1934,111 @@ void TTrain::OnCommand_motorconnectorsopen( TTrain *Train, command_data const &C
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if( Command.action != GLFW_RELEASE ) {
|
||||
// button works while it's held down
|
||||
if( true == Train->mvControlled->StLinFlag ) {
|
||||
// NOTE: because we don't have modeled actual circuits this is a simplification of the real mechanics
|
||||
// namely, pressing the button will flip it in the entire unit, which isn't exactly physically possible
|
||||
if( Command.action == GLFW_PRESS ) {
|
||||
// button works while it's held down but we can only pay attention to initial press
|
||||
if( false == Train->mvControlled->StLinSwitchOff ) {
|
||||
// open the connectors
|
||||
Train->mvControlled->StLinSwitchOff = true;
|
||||
if( ( Train->mvControlled->TrainType == dt_ET41 )
|
||||
|| ( Train->mvControlled->TrainType == dt_ET42 ) ) {
|
||||
// crude implementation of the butto affecting entire unit for multi-unit engines
|
||||
// TODO: rework it into part of standard command propagation system
|
||||
if( ( Train->mvControlled->Couplers[ 0 ].Connected != nullptr )
|
||||
&& ( true == TestFlag( Train->mvControlled->Couplers[ 0 ].CouplingFlag, coupling::permanent ) ) ) {
|
||||
// the first unit isn't allowed to start its compressor until second unit can start its own as well
|
||||
Train->mvControlled->Couplers[ 0 ].Connected->StLinSwitchOff = true;
|
||||
}
|
||||
if( ( Train->mvControlled->Couplers[ 1 ].Connected != nullptr )
|
||||
&& ( true == TestFlag( Train->mvControlled->Couplers[ 1 ].CouplingFlag, coupling::permanent ) ) ) {
|
||||
// the first unit isn't allowed to start its compressor until second unit can start its own as well
|
||||
Train->mvControlled->Couplers[ 1 ].Connected->StLinSwitchOff = true;
|
||||
}
|
||||
}
|
||||
// sound feedback
|
||||
if( Train->ggStLinOffButton.GetValue() < 0.5 ) {
|
||||
Train->play_sound( Train->dsbSwitch );
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggStLinOffButton.UpdateValue( 1.0 );
|
||||
// effect
|
||||
if( true == Train->mvControlled->StLinFlag ) {
|
||||
Train->play_sound( Train->dsbRelay );
|
||||
}
|
||||
// yBARC - zmienione na przeciwne, bo true to zalaczone
|
||||
Train->mvControlled->StLinFlag = false;
|
||||
Train->play_sound( Train->dsbRelay );
|
||||
if( ( Train->mvControlled->TrainType == dt_ET41 )
|
||||
|| ( Train->mvControlled->TrainType == dt_ET42 ) ) {
|
||||
// crude implementation of the butto affecting entire unit for multi-unit engines
|
||||
// TODO: rework it into part of standard command propagation system
|
||||
if( ( Train->mvControlled->Couplers[ 0 ].Connected != nullptr )
|
||||
&& ( true == TestFlag( Train->mvControlled->Couplers[ 0 ].CouplingFlag, coupling::permanent ) ) ) {
|
||||
// the first unit isn't allowed to start its compressor until second unit can start its own as well
|
||||
Train->mvControlled->Couplers[ 0 ].Connected->StLinFlag = false;
|
||||
}
|
||||
if( ( Train->mvControlled->Couplers[ 1 ].Connected != nullptr )
|
||||
&& ( true == TestFlag( Train->mvControlled->Couplers[ 1 ].CouplingFlag, coupling::permanent ) ) ) {
|
||||
// the first unit isn't allowed to start its compressor until second unit can start its own as well
|
||||
Train->mvControlled->Couplers[ 1 ].Connected->StLinFlag = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
Train->mvControlled->StLinSwitchOff = true;
|
||||
// sound feedback
|
||||
if( Train->ggStLinOffButton.GetValue() < 0.05 ) {
|
||||
Train->play_sound( Train->dsbSwitch );
|
||||
else {
|
||||
if( Train->mvControlled->StLinSwitchType == "toggle" ) {
|
||||
// default type of button (impulse) has only one effect on press, but the toggle type can toggle the state
|
||||
Train->mvControlled->StLinSwitchOff = false;
|
||||
if( ( Train->mvControlled->TrainType == dt_ET41 )
|
||||
|| ( Train->mvControlled->TrainType == dt_ET42 ) ) {
|
||||
// crude implementation of the butto affecting entire unit for multi-unit engines
|
||||
// TODO: rework it into part of standard command propagation system
|
||||
if( ( Train->mvControlled->Couplers[ 0 ].Connected != nullptr )
|
||||
&& ( true == TestFlag( Train->mvControlled->Couplers[ 0 ].CouplingFlag, coupling::permanent ) ) ) {
|
||||
// the first unit isn't allowed to start its compressor until second unit can start its own as well
|
||||
Train->mvControlled->Couplers[ 0 ].Connected->StLinSwitchOff = false;
|
||||
}
|
||||
if( ( Train->mvControlled->Couplers[ 1 ].Connected != nullptr )
|
||||
&& ( true == TestFlag( Train->mvControlled->Couplers[ 1 ].CouplingFlag, coupling::permanent ) ) ) {
|
||||
// the first unit isn't allowed to start its compressor until second unit can start its own as well
|
||||
Train->mvControlled->Couplers[ 1 ].Connected->StLinSwitchOff = false;
|
||||
}
|
||||
}
|
||||
// sound feedback
|
||||
if( Train->ggStLinOffButton.GetValue() > 0.5 ) {
|
||||
Train->play_sound( Train->dsbSwitch );
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggStLinOffButton.UpdateValue( 0.0 );
|
||||
}
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggStLinOffButton.UpdateValue( 1.0 );
|
||||
}
|
||||
else {
|
||||
else if( Command.action == GLFW_RELEASE ) {
|
||||
// button released
|
||||
Train->mvControlled->StLinSwitchOff = false;
|
||||
// sound feedback
|
||||
if( Train->ggStLinOffButton.GetValue() > 0.5 ) {
|
||||
Train->play_sound( Train->dsbSwitch );
|
||||
if( Train->mvControlled->StLinSwitchType != "toggle" ) {
|
||||
// default button type (impulse) works on button release
|
||||
Train->mvControlled->StLinSwitchOff = false;
|
||||
if( ( Train->mvControlled->TrainType == dt_ET41 )
|
||||
|| ( Train->mvControlled->TrainType == dt_ET42 ) ) {
|
||||
// crude implementation of the butto affecting entire unit for multi-unit engines
|
||||
// TODO: rework it into part of standard command propagation system
|
||||
if( ( Train->mvControlled->Couplers[ 0 ].Connected != nullptr )
|
||||
&& ( true == TestFlag( Train->mvControlled->Couplers[ 0 ].CouplingFlag, coupling::permanent ) ) ) {
|
||||
// the first unit isn't allowed to start its compressor until second unit can start its own as well
|
||||
Train->mvControlled->Couplers[ 0 ].Connected->StLinSwitchOff = false;
|
||||
}
|
||||
if( ( Train->mvControlled->Couplers[ 1 ].Connected != nullptr )
|
||||
&& ( true == TestFlag( Train->mvControlled->Couplers[ 1 ].CouplingFlag, coupling::permanent ) ) ) {
|
||||
// the first unit isn't allowed to start its compressor until second unit can start its own as well
|
||||
Train->mvControlled->Couplers[ 1 ].Connected->StLinSwitchOff = false;
|
||||
}
|
||||
}
|
||||
// sound feedback
|
||||
if( Train->ggStLinOffButton.GetValue() > 0.5 ) {
|
||||
Train->play_sound( Train->dsbSwitch );
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggStLinOffButton.UpdateValue( 0.0 );
|
||||
}
|
||||
// visual feedback
|
||||
Train->ggStLinOffButton.UpdateValue( 0.0 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2700,10 +2881,12 @@ void TTrain::OnCommand_hornlowactivate( TTrain *Train, command_data const &Comma
|
||||
if( false == TestFlag( Train->mvOccupied->WarningSignal, 1 ) ) {
|
||||
// turn on
|
||||
Train->mvOccupied->WarningSignal |= 1;
|
||||
/*
|
||||
if( true == TestFlag( Train->mvOccupied->WarningSignal, 2 ) ) {
|
||||
// low and high horn are treated as mutually exclusive
|
||||
Train->mvControlled->WarningSignal &= ~2;
|
||||
}
|
||||
*/
|
||||
// audio feedback
|
||||
if( ( Train->ggHornButton.GetValue() > -0.5 )
|
||||
|| ( Train->ggHornLowButton.GetValue() < 0.5 ) ) {
|
||||
@@ -2716,8 +2899,11 @@ void TTrain::OnCommand_hornlowactivate( TTrain *Train, command_data const &Comma
|
||||
}
|
||||
else if( Command.action == GLFW_RELEASE ) {
|
||||
// turn off
|
||||
/*
|
||||
// NOTE: we turn off both low and high horn, due to unreliability of release event when shift key is involved
|
||||
Train->mvOccupied->WarningSignal &= ~( 1 | 2 );
|
||||
*/
|
||||
Train->mvOccupied->WarningSignal &= ~1;
|
||||
// audio feedback
|
||||
if( ( Train->ggHornButton.GetValue() < -0.5 )
|
||||
|| ( Train->ggHornLowButton.GetValue() > 0.5 ) ) {
|
||||
@@ -2744,10 +2930,12 @@ void TTrain::OnCommand_hornhighactivate( TTrain *Train, command_data const &Comm
|
||||
if( false == TestFlag( Train->mvOccupied->WarningSignal, 2 ) ) {
|
||||
// turn on
|
||||
Train->mvOccupied->WarningSignal |= 2;
|
||||
/*
|
||||
if( true == TestFlag( Train->mvOccupied->WarningSignal, 1 ) ) {
|
||||
// low and high horn are treated as mutually exclusive
|
||||
Train->mvControlled->WarningSignal &= ~1;
|
||||
}
|
||||
*/
|
||||
// audio feedback
|
||||
if( Train->ggHornButton.GetValue() < 0.5 ) {
|
||||
Train->play_sound( Train->dsbSwitch );
|
||||
@@ -2759,8 +2947,11 @@ void TTrain::OnCommand_hornhighactivate( TTrain *Train, command_data const &Comm
|
||||
}
|
||||
else if( Command.action == GLFW_RELEASE ) {
|
||||
// turn off
|
||||
/*
|
||||
// NOTE: we turn off both low and high horn, due to unreliability of release event when shift key is involved
|
||||
Train->mvOccupied->WarningSignal &= ~( 1 | 2 );
|
||||
*/
|
||||
Train->mvOccupied->WarningSignal &= ~2;
|
||||
// audio feedback
|
||||
if( Train->ggHornButton.GetValue() > 0.5 ) {
|
||||
Train->play_sound( Train->dsbSwitch );
|
||||
@@ -4674,9 +4865,11 @@ bool TTrain::Update( double const Deltatime )
|
||||
ggDepartureSignalButton.Update();
|
||||
// NBMX dzwignia sprezarki
|
||||
ggCompressorButton.Update();
|
||||
ggCompressorLocalButton.Update();
|
||||
ggMainButton.Update();
|
||||
ggRadioButton.Update();
|
||||
ggConverterButton.Update();
|
||||
ggConverterLocalButton.Update();
|
||||
ggConverterOffButton.Update();
|
||||
|
||||
#ifdef EU07_USE_OLD_COMMAND_SYSTEM
|
||||
@@ -5820,6 +6013,8 @@ bool TTrain::LoadMMediaFile(std::string const &asFileName)
|
||||
// NOTE: yaml-style comments are disabled until conflict in use of # is resolved
|
||||
// parser.addCommentStyle( "#", "\n" );
|
||||
//Wartości domyślne by nie wysypywało przy wybrakowanych mmd @240816 Stele
|
||||
// NOTE: should be no longer needed as safety checks were added,
|
||||
// but leaving the defaults for the sake of incomplete mmd files
|
||||
dsbPneumaticSwitch = TSoundsManager::GetFromName("silence1.wav", true);
|
||||
dsbBufferClamp = TSoundsManager::GetFromName("en57_bufferclamp.wav", true);
|
||||
dsbCouplerDetach = TSoundsManager::GetFromName("couplerdetach.wav", true);
|
||||
@@ -5847,67 +6042,67 @@ bool TTrain::LoadMMediaFile(std::string const &asFileName)
|
||||
{
|
||||
// nastawnik:
|
||||
dsbNastawnikJazdy =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "ctrlscnd:")
|
||||
{
|
||||
// hunter-081211: nastawnik bocznikowania
|
||||
dsbNastawnikBocz =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "reverserkey:")
|
||||
{
|
||||
// hunter-131211: dzwiek kierunkowego
|
||||
dsbReverserKey =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "buzzer:")
|
||||
{
|
||||
// bzyczek shp:
|
||||
dsbBuzzer =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "slipalarm:")
|
||||
{
|
||||
// Bombardier 011010: alarm przy poslizgu:
|
||||
dsbSlipAlarm =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "tachoclock:")
|
||||
{
|
||||
// cykanie rejestratora:
|
||||
dsbHasler =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "switch:")
|
||||
{
|
||||
// przelaczniki:
|
||||
dsbSwitch =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "pneumaticswitch:")
|
||||
{
|
||||
// stycznik EP:
|
||||
dsbPneumaticSwitch =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "wejscie_na_bezoporow:")
|
||||
{
|
||||
// hunter-111211: wydzielenie wejscia na bezoporowa i na drugi uklad do pliku
|
||||
dsbWejscie_na_bezoporow =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "wejscie_na_drugi_uklad:")
|
||||
{
|
||||
|
||||
dsbWejscie_na_drugi_uklad =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "relay:")
|
||||
{
|
||||
// styczniki itp:
|
||||
dsbRelay =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
if (!dsbWejscie_na_bezoporow)
|
||||
{ // hunter-111211: domyslne, gdy brak
|
||||
dsbWejscie_na_bezoporow =
|
||||
@@ -5923,39 +6118,37 @@ bool TTrain::LoadMMediaFile(std::string const &asFileName)
|
||||
{
|
||||
// wylaczniki pneumatyczne:
|
||||
dsbPneumaticRelay =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "couplerattach:")
|
||||
{
|
||||
// laczenie:
|
||||
dsbCouplerAttach =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "couplerstretch:")
|
||||
{
|
||||
// laczenie:
|
||||
dsbCouplerStretch = TSoundsManager::GetFromName(
|
||||
parser.getToken<std::string>().c_str(),
|
||||
true); // McZapkie-090503: PROWIZORKA!!! "en57_couplerstretch.wav"
|
||||
dsbCouplerStretch =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "couplerdetach:")
|
||||
{
|
||||
// rozlaczanie:
|
||||
dsbCouplerDetach =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "bufferclamp:")
|
||||
{
|
||||
// laczenie:
|
||||
dsbBufferClamp = TSoundsManager::GetFromName(
|
||||
parser.getToken<std::string>().c_str(),
|
||||
true); // McZapkie-090503: PROWIZORKA!!! "en57_bufferclamp.wav"
|
||||
dsbBufferClamp =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "ignition:")
|
||||
{
|
||||
// odpalanie silnika
|
||||
dsbDieselIgnition =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "brakesound:")
|
||||
{
|
||||
@@ -6073,25 +6266,25 @@ bool TTrain::LoadMMediaFile(std::string const &asFileName)
|
||||
{
|
||||
// podniesienie patyka:
|
||||
dsbPantUp =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "pantographdown:")
|
||||
{
|
||||
// podniesienie patyka:
|
||||
dsbPantDown =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "doorclose:")
|
||||
{
|
||||
// zamkniecie drzwi:
|
||||
dsbDoorClose =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
else if (token == "dooropen:")
|
||||
{
|
||||
// otwarcie drzwi:
|
||||
dsbDoorOpen =
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>().c_str(), true);
|
||||
TSoundsManager::GetFromName(parser.getToken<std::string>(), true);
|
||||
}
|
||||
|
||||
} while (token != "");
|
||||
@@ -6604,6 +6797,11 @@ void TTrain::set_cab_controls() {
|
||||
if( true == mvOccupied->Battery ) {
|
||||
ggBatteryButton.PutValue( 1.0 );
|
||||
}
|
||||
// motor connectors
|
||||
ggStLinOffButton.PutValue(
|
||||
( mvControlled->StLinSwitchOff ?
|
||||
1.0 :
|
||||
0.0 ) );
|
||||
// radio
|
||||
if( true == mvOccupied->Radio ) {
|
||||
ggRadioButton.PutValue( 1.0 );
|
||||
@@ -6636,10 +6834,19 @@ void TTrain::set_cab_controls() {
|
||||
1.0 :
|
||||
0.0 );
|
||||
}
|
||||
ggConverterLocalButton.PutValue(
|
||||
mvControlled->ConverterAllowLocal ?
|
||||
1.0 :
|
||||
0.0 );
|
||||
// compressor
|
||||
if( true == mvControlled->CompressorAllow ) {
|
||||
ggCompressorButton.PutValue( 1.0 );
|
||||
}
|
||||
ggCompressorButton.PutValue(
|
||||
mvControlled->CompressorAllow ?
|
||||
1.0 :
|
||||
0.0 );
|
||||
ggCompressorLocalButton.PutValue(
|
||||
mvControlled->CompressorAllowLocal ?
|
||||
1.0 :
|
||||
0.0 );
|
||||
// motor overload relay threshold / shunt mode
|
||||
if( mvControlled->Imax == mvControlled->ImaxHi ) {
|
||||
ggMaxCurrentCtrl.PutValue( 1.0 );
|
||||
@@ -7175,11 +7382,19 @@ bool TTrain::initialize_gauge(cParser &Parser, std::string const &Label, int con
|
||||
// sprezarka
|
||||
ggCompressorButton.Load(Parser, DynamicObject->mdKabina);
|
||||
}
|
||||
else if( Label == "compressorlocal_sw:" ) {
|
||||
// sprezarka
|
||||
ggCompressorLocalButton.Load( Parser, DynamicObject->mdKabina );
|
||||
}
|
||||
else if (Label == "converter_sw:")
|
||||
{
|
||||
// przetwornica
|
||||
ggConverterButton.Load(Parser, DynamicObject->mdKabina);
|
||||
}
|
||||
else if( Label == "converterlocal_sw:" ) {
|
||||
// przetwornica
|
||||
ggConverterLocalButton.Load( Parser, DynamicObject->mdKabina );
|
||||
}
|
||||
else if (Label == "converteroff_sw:")
|
||||
{
|
||||
// przetwornica wyl
|
||||
|
||||
4
Train.h
4
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
|
||||
|
||||
20
VBO.cpp
20
VBO.cpp
@@ -44,7 +44,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
|
||||
};
|
||||
@@ -57,7 +59,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)
|
||||
@@ -65,11 +73,19 @@ void CMesh::BuildVBOs(bool del)
|
||||
// pobierz numer VBO oraz ustaw go jako aktywny
|
||||
glGenBuffers(1, &m_nVBOVertices); // pobierz numer
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_nVBOVertices); // ustaw bufor jako aktualny
|
||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||
glBufferData(GL_ARRAY_BUFFER, m_nVertexCount * sizeof(CVertNormTex), m_pVNT, GL_STATIC_DRAW);
|
||||
#else
|
||||
glBufferData( GL_ARRAY_BUFFER, m_nVertexCount * sizeof( CVertNormTex ), m_pVNT.data(), GL_STATIC_DRAW );
|
||||
#endif
|
||||
// WriteLog("Assigned VBO number "+AnsiString(m_nVBOVertices)+", vertices:
|
||||
// "+AnsiString(m_nVertexCount));
|
||||
#ifdef EU07_USE_OLD_VERTEXBUFFER
|
||||
if (del)
|
||||
SafeDeleteArray(m_pVNT); // wierzchołki już się nie przydadzą
|
||||
#else
|
||||
m_pVNT.clear();
|
||||
#endif
|
||||
};
|
||||
|
||||
void CMesh::Clear()
|
||||
@@ -82,7 +98,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
|
||||
};
|
||||
|
||||
bool CMesh::StartVBO()
|
||||
|
||||
7
VBO.h
7
VBO.h
@@ -9,6 +9,9 @@ http://mozilla.org/MPL/2.0/.
|
||||
|
||||
#ifndef VBOH
|
||||
#define VBOH
|
||||
|
||||
#define EU07_USE_OLD_VERTEXBUFFER
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
class CVertNormTex
|
||||
{
|
||||
@@ -30,7 +33,11 @@ class CMesh
|
||||
{ // wsparcie dla VBO
|
||||
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();
|
||||
|
||||
606
World.cpp
606
World.cpp
@@ -375,11 +375,12 @@ bool TWorld::Init( GLFWwindow *Window ) {
|
||||
WriteLog( "Load time: " +
|
||||
std::to_string( std::chrono::duration_cast<std::chrono::seconds>(( std::chrono::system_clock::now() - timestart )).count() )
|
||||
+ " seconds");
|
||||
/*
|
||||
if (DebugModeFlag) // w Debugmode automatyczne włączenie AI
|
||||
if (Train)
|
||||
if (Train->Dynamic()->Mechanik)
|
||||
Train->Dynamic()->Mechanik->TakeControl(true);
|
||||
|
||||
*/
|
||||
UILayer.set_progress();
|
||||
UILayer.set_background( "" );
|
||||
UILayer.clear_texts();
|
||||
@@ -905,43 +906,52 @@ void TWorld::DistantView( bool const Near )
|
||||
Camera.RaLook(); // jednorazowe przestawienie kamery
|
||||
};
|
||||
|
||||
void TWorld::FollowView(bool wycisz)
|
||||
{ // ustawienie śledzenia pojazdu
|
||||
// ustawienie śledzenia pojazdu
|
||||
void TWorld::FollowView(bool wycisz) {
|
||||
|
||||
Camera.Reset(); // likwidacja obrotów - patrzy horyzontalnie na południe
|
||||
|
||||
if (Controlled) // jest pojazd do prowadzenia?
|
||||
{
|
||||
vector3 camStara =
|
||||
Camera.Pos; // przestawianie kamery jest bez sensu: do przerobienia na potem
|
||||
// Controlled->ABuSetModelShake(vector3(0,0,0));
|
||||
Ground.Silence( Camera.Pos ); // wyciszenie dźwięków z poprzedniej pozycji
|
||||
|
||||
if (FreeFlyModeFlag)
|
||||
{ // jeżeli poza kabiną, przestawiamy w jej okolicę - OK
|
||||
if (Train)
|
||||
Train->Dynamic()->ABuSetModelShake(
|
||||
vector3(0, 0, 0)); // wyłączenie trzęsienia na siłę?
|
||||
// Camera.Pos=Train->pMechPosition+Normalize(Train->GetDirection())*20;
|
||||
if( Train ) {
|
||||
// wyłączenie trzęsienia na siłę?
|
||||
Train->Dynamic()->ABuSetModelShake( vector3() );
|
||||
}
|
||||
|
||||
DistantView(); // przestawienie kamery
|
||||
//żeby nie bylo numerów z 'fruwajacym' lokiem - konsekwencja bujania pudła
|
||||
Global::SetCameraPosition(
|
||||
Camera.Pos); // tu ustawić nową, bo od niej liczą się odległości
|
||||
Ground.Silence(camStara); // wyciszenie dźwięków z poprzedniej pozycji
|
||||
// tu ustawić nową, bo od niej liczą się odległości
|
||||
Global::SetCameraPosition( Camera.Pos );
|
||||
}
|
||||
else if (Train)
|
||||
{ // korekcja ustawienia w kabinie - OK
|
||||
vector3 camStara = Camera.Pos; // przestawianie kamery jest bez sensu: do przerobienia na potem
|
||||
// Ra: czy to tu jest potrzebne, bo przelicza się kawałek dalej?
|
||||
Camera.Pos = Train->pMechPosition; // Train.GetPosition1();
|
||||
if( wycisz ) {
|
||||
// wyciszenie dźwięków z poprzedniej pozycji
|
||||
// trzymanie prawego w kabinie daje marny efekt
|
||||
Ground.Silence( Camera.Pos );
|
||||
}
|
||||
Camera.Pos = Train->pMechPosition;
|
||||
Camera.Roll = std::atan(Train->pMechShake.x * Train->fMechRoll); // hustanie kamery na boki
|
||||
Camera.Pitch -= 0.5 * std::atan(Train->vMechVelocity.z * Train->fMechPitch); // hustanie kamery przod tyl
|
||||
if (Train->Dynamic()->MoverParameters->ActiveCab == 0)
|
||||
Camera.LookAt = Train->pMechPosition + Train->GetDirection() * 5.0;
|
||||
else // patrz w strone wlasciwej kabiny
|
||||
Camera.LookAt = Train->pMechPosition + Train->GetDirection() * 5.0 * Train->Dynamic()->MoverParameters->ActiveCab;
|
||||
Train->pMechOffset.x = Train->pMechSittingPosition.x;
|
||||
Train->pMechOffset.y = Train->pMechSittingPosition.y;
|
||||
Train->pMechOffset.z = Train->pMechSittingPosition.z;
|
||||
|
||||
if( Train->Dynamic()->MoverParameters->ActiveCab == 0 ) {
|
||||
Camera.LookAt =
|
||||
Train->pMechPosition
|
||||
+ Train->GetDirection() * 5.0;
|
||||
}
|
||||
else {
|
||||
// patrz w strone wlasciwej kabiny
|
||||
Camera.LookAt =
|
||||
Train->pMechPosition
|
||||
+ Train->GetDirection() * 5.0 * Train->Dynamic()->MoverParameters->ActiveCab;
|
||||
}
|
||||
Train->pMechOffset = Train->pMechSittingPosition;
|
||||
|
||||
Global::SetCameraPosition( Train->Dynamic() ->GetPosition()); // tu ustawić nową, bo od niej liczą się odległości
|
||||
if (wycisz) // trzymanie prawego w kabinie daje marny efekt
|
||||
Ground.Silence(camStara); // wyciszenie dźwięków z poprzedniej pozycji
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1238,105 +1248,7 @@ TWorld::Update_Camera( double const Deltatime ) {
|
||||
|
||||
void TWorld::Update_Environment() {
|
||||
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
|
||||
if( Global::fMoveLight < 0.0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// double a=Global::fTimeAngleDeg/180.0*M_PI-M_PI; //kąt godzinny w radianach
|
||||
double a = fmod( Global::fTimeAngleDeg, 360.0 ) / 180.0 * M_PI -
|
||||
M_PI; // kąt godzinny w radianach
|
||||
//(a) jest traktowane jako czas miejscowy, nie uwzględniający stref czasowych ani czasu
|
||||
// letniego
|
||||
// aby wyznaczyć strefę czasową, trzeba uwzględnić południk miejscowy
|
||||
// aby uwzględnić czas letni, trzeba sprawdzić dzień roku
|
||||
double L = Global::fLatitudeDeg / 180.0 * M_PI; // szerokość geograficzna
|
||||
double H = asin( cos( L ) * cos( Global::fSunDeclination ) * cos( a ) +
|
||||
sin( L ) * sin( Global::fSunDeclination ) ); // kąt ponad horyzontem
|
||||
// double A=asin(cos(d)*sin(M_PI-a)/cos(H));
|
||||
// Declination=((0.322003-22.971*cos(t)-0.357898*cos(2*t)-0.14398*cos(3*t)+3.94638*sin(t)+0.019334*sin(2*t)+0.05928*sin(3*t)))*Pi/180
|
||||
// Altitude=asin(sin(Declination)*sin(latitude)+cos(Declination)*cos(latitude)*cos((15*(time-12))*(Pi/180)));
|
||||
// Azimuth=(acos((cos(latitude)*sin(Declination)-cos(Declination)*sin(latitude)*cos((15*(time-12))*(Pi/180)))/cos(Altitude)));
|
||||
// double A=acos(cos(L)*sin(d)-cos(d)*sin(L)*cos(M_PI-a)/cos(H));
|
||||
// dAzimuth = atan2(-sin( dHourAngle ),tan( dDeclination )*dCos_Latitude -
|
||||
// dSin_Latitude*dCos_HourAngle );
|
||||
double A = atan2( sin( a ), tan( Global::fSunDeclination ) * cos( L ) - sin( L ) * cos( a ) );
|
||||
vector3 lp = vector3( sin( A ), tan( H ), cos( A ) );
|
||||
lp = Normalize( lp ); // przeliczenie na wektor długości 1.0
|
||||
Global::lightPos[ 0 ] = (float)lp.x;
|
||||
Global::lightPos[ 1 ] = (float)lp.y;
|
||||
Global::lightPos[ 2 ] = (float)lp.z;
|
||||
glLightfv( GL_LIGHT0, GL_POSITION, Global::lightPos ); // daylight position
|
||||
if( H > 0 ) { // słońce ponad horyzontem
|
||||
Global::ambientDayLight[ 0 ] = Global::ambientLight[ 0 ];
|
||||
Global::ambientDayLight[ 1 ] = Global::ambientLight[ 1 ];
|
||||
Global::ambientDayLight[ 2 ] = Global::ambientLight[ 2 ];
|
||||
if( H > 0.02 ) // ponad 1.146° zaczynają się cienie
|
||||
{
|
||||
Global::diffuseDayLight[ 0 ] =
|
||||
Global::diffuseLight[ 0 ]; // od wschodu do zachodu maksimum ???
|
||||
Global::diffuseDayLight[ 1 ] = Global::diffuseLight[ 1 ];
|
||||
Global::diffuseDayLight[ 2 ] = Global::diffuseLight[ 2 ];
|
||||
Global::specularDayLight[ 0 ] = Global::specularLight[ 0 ]; // podobnie specular
|
||||
Global::specularDayLight[ 1 ] = Global::specularLight[ 1 ];
|
||||
Global::specularDayLight[ 2 ] = Global::specularLight[ 2 ];
|
||||
}
|
||||
else {
|
||||
Global::diffuseDayLight[ 0 ] =
|
||||
50 * H * Global::diffuseLight[ 0 ]; // wschód albo zachód
|
||||
Global::diffuseDayLight[ 1 ] = 50 * H * Global::diffuseLight[ 1 ];
|
||||
Global::diffuseDayLight[ 2 ] = 50 * H * Global::diffuseLight[ 2 ];
|
||||
Global::specularDayLight[ 0 ] =
|
||||
50 * H * Global::specularLight[ 0 ]; // podobnie specular
|
||||
Global::specularDayLight[ 1 ] = 50 * H * Global::specularLight[ 1 ];
|
||||
Global::specularDayLight[ 2 ] = 50 * H * Global::specularLight[ 2 ];
|
||||
}
|
||||
}
|
||||
else { // słońce pod horyzontem
|
||||
GLfloat lum = 3.1831 * ( H > -0.314159 ? 0.314159 + H :
|
||||
0.0 ); // po zachodzie ambient się ściemnia
|
||||
Global::ambientDayLight[ 0 ] = lum * Global::ambientLight[ 0 ];
|
||||
Global::ambientDayLight[ 1 ] = lum * Global::ambientLight[ 1 ];
|
||||
Global::ambientDayLight[ 2 ] = lum * Global::ambientLight[ 2 ];
|
||||
Global::diffuseDayLight[ 0 ] =
|
||||
Global::noLight[ 0 ]; // od zachodu do wschodu nie ma diffuse
|
||||
Global::diffuseDayLight[ 1 ] = Global::noLight[ 1 ];
|
||||
Global::diffuseDayLight[ 2 ] = Global::noLight[ 2 ];
|
||||
Global::specularDayLight[ 0 ] = Global::noLight[ 0 ]; // ani specular
|
||||
Global::specularDayLight[ 1 ] = Global::noLight[ 1 ];
|
||||
Global::specularDayLight[ 2 ] = Global::noLight[ 2 ];
|
||||
}
|
||||
// Calculate sky colour according to time of day.
|
||||
// GLfloat sin_t = sin(PI * time_of_day / 12.0);
|
||||
// back_red = 0.3 * (1.0 - sin_t);
|
||||
// back_green = 0.9 * sin_t;
|
||||
// back_blue = sin_t + 0.4, 1.0;
|
||||
// aktualizacja świateł
|
||||
glLightfv( GL_LIGHT0, GL_AMBIENT, Global::ambientDayLight );
|
||||
glLightfv( GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight );
|
||||
glLightfv( GL_LIGHT0, GL_SPECULAR, Global::specularDayLight );
|
||||
|
||||
Global::fLuminance = // to posłuży również do zapalania latarń
|
||||
+0.150 * ( Global::diffuseDayLight[ 0 ] + Global::ambientDayLight[ 0 ] ) // R
|
||||
+ 0.295 * ( Global::diffuseDayLight[ 1 ] + Global::ambientDayLight[ 1 ] ) // G
|
||||
+ 0.055 * ( Global::diffuseDayLight[ 2 ] + Global::ambientDayLight[ 2 ] ); // B
|
||||
|
||||
vector3 sky = vector3( Global::AtmoColor[ 0 ], Global::AtmoColor[ 1 ], Global::AtmoColor[ 2 ] );
|
||||
if( Global::fLuminance < 0.25 ) { // przyspieszenie zachodu/wschodu
|
||||
sky *= 4.0 * Global::fLuminance; // nocny kolor nieba
|
||||
GLfloat fog[ 3 ];
|
||||
fog[ 0 ] = Global::FogColor[ 0 ] * 4.0 * Global::fLuminance;
|
||||
fog[ 1 ] = Global::FogColor[ 1 ] * 4.0 * Global::fLuminance;
|
||||
fog[ 2 ] = Global::FogColor[ 2 ] * 4.0 * Global::fLuminance;
|
||||
glFogfv( GL_FOG_COLOR, fog ); // nocny kolor mgły
|
||||
}
|
||||
else {
|
||||
glFogfv( GL_FOG_COLOR, Global::FogColor ); // kolor mgły
|
||||
}
|
||||
#else
|
||||
Environment.update();
|
||||
#endif
|
||||
}
|
||||
|
||||
void TWorld::ResourceSweep()
|
||||
@@ -1363,11 +1275,9 @@ TWorld::Render_Cab() {
|
||||
// ABu: Rendering kabiny jako ostatniej, zeby bylo widac przez szyby, tylko w widoku ze srodka
|
||||
return;
|
||||
}
|
||||
|
||||
::glEnable( GL_LIGHTING ); // po renderowaniu drutów może być to wyłączone. TODO: have the wires render take care of its own shit
|
||||
/*
|
||||
// ABu: Rendering kabiny jako ostatniej, zeby bylo widac przez szyby, tylko w widoku ze srodka
|
||||
if( ( Train->Dynamic()->mdKabina != Train->Dynamic()->mdModel ) &&
|
||||
Train->Dynamic()->bDisplayCab && !FreeFlyModeFlag ) {
|
||||
*/
|
||||
glPushMatrix();
|
||||
vector3 pos = dynamic->GetPosition(); // wszpółrzędne pojazdu z kabiną
|
||||
// glTranslatef(pos.x,pos.y,pos.z); //przesunięcie o wektor (tak było i trzęsło)
|
||||
@@ -1376,247 +1286,28 @@ TWorld::Render_Cab() {
|
||||
glLoadIdentity(); // zacząć od macierzy jedynkowej
|
||||
Camera.SetCabMatrix( pos ); // widok z kamery po przesunięciu
|
||||
glMultMatrixd( dynamic->mMatrix.getArray() ); // ta macierz nie ma przesunięcia
|
||||
/*
|
||||
//*yB: moje smuuugi 1
|
||||
if( Global::bSmudge ) { // Ra: uwzględniłem zacienienie pojazdu przy zapalaniu smug
|
||||
|
||||
// 1. warunek na smugę wyznaczyc wcześniej
|
||||
// 2. jeśli smuga włączona, nie renderować pojazdu użytkownika w DynObj
|
||||
// 3. jeśli smuga właczona, wyrenderować pojazd użytkownia po dodaniu smugi do sceny
|
||||
auto const &frontlights = Train->Controlled()->iLights[ 0 ];
|
||||
float frontlightstrength = 0.f +
|
||||
( ( frontlights & 1 ) ? 0.3f : 0.f ) +
|
||||
( ( frontlights & 4 ) ? 0.3f : 0.f ) +
|
||||
( ( frontlights & 16 ) ? 0.3f : 0.f );
|
||||
frontlightstrength = std::max( frontlightstrength - Global::fLuminance, 0.0 );
|
||||
auto const &rearlights = Train->Controlled()->iLights[ 1 ];
|
||||
float rearlightstrength = 0.f +
|
||||
( ( rearlights & 1 ) ? 0.3f : 0.f ) +
|
||||
( ( rearlights & 4 ) ? 0.3f : 0.f ) +
|
||||
( ( rearlights & 16 ) ? 0.3f : 0.f );
|
||||
rearlightstrength = std::max( rearlightstrength - Global::fLuminance, 0.0 );
|
||||
|
||||
if( ( Train->Controlled()->Battery ) // trochę na skróty z tą baterią
|
||||
&& ( ( frontlightstrength > 0.f )
|
||||
|| ( rearlightstrength > 0.f ) ) ) {
|
||||
|
||||
if( Global::bOldSmudge == true ) {
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE );
|
||||
// glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_DST_COLOR);
|
||||
// glBlendFunc(GL_SRC_ALPHA_SATURATE,GL_ONE);
|
||||
glDisable( GL_DEPTH_TEST );
|
||||
glDisable( GL_LIGHTING );
|
||||
glDisable( GL_FOG );
|
||||
GfxRenderer.Bind( light ); // Select our texture
|
||||
glBegin( GL_QUADS );
|
||||
float fSmudge =
|
||||
dynamic->MoverParameters->DimHalf.y + 7; // gdzie zaczynać smugę
|
||||
if( frontlightstrength > 0.f ) { // wystarczy jeden zapalony z przodu
|
||||
glColor4f( 1.0f, 1.0f, 1.0f, 0.5f * frontlightstrength );
|
||||
glTexCoord2f( 0, 0 );
|
||||
glVertex3f( 15.0, 0.0, +fSmudge ); // rysowanie względem położenia modelu
|
||||
glTexCoord2f( 1, 0 );
|
||||
glVertex3f( -15.0, 0.0, +fSmudge );
|
||||
glTexCoord2f( 1, 1 );
|
||||
glVertex3f( -15.0, 2.5, 250.0 );
|
||||
glTexCoord2f( 0, 1 );
|
||||
glVertex3f( 15.0, 2.5, 250.0 );
|
||||
}
|
||||
if( rearlightstrength > 0.f ) { // wystarczy jeden zapalony z tyłu
|
||||
glColor4f( 1.0f, 1.0f, 1.0f, 0.5f * rearlightstrength );
|
||||
glTexCoord2f( 0, 0 );
|
||||
glVertex3f( -15.0, 0.0, -fSmudge );
|
||||
glTexCoord2f( 1, 0 );
|
||||
glVertex3f( 15.0, 0.0, -fSmudge );
|
||||
glTexCoord2f( 1, 1 );
|
||||
glVertex3f( 15.0, 2.5, -250.0 );
|
||||
glTexCoord2f( 0, 1 );
|
||||
glVertex3f( -15.0, 2.5, -250.0 );
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
glEnable( GL_DEPTH_TEST );
|
||||
// glEnable(GL_LIGHTING); //i tak się włączy potem
|
||||
glEnable( GL_FOG );
|
||||
}
|
||||
else {
|
||||
|
||||
glBlendFunc( GL_DST_COLOR, GL_ONE );
|
||||
glDepthFunc( GL_GEQUAL );
|
||||
glAlphaFunc( GL_GREATER, 0.004 );
|
||||
// glDisable(GL_DEPTH_TEST);
|
||||
glDisable( GL_LIGHTING );
|
||||
glDisable( GL_FOG );
|
||||
//glColor4f(0.15f, 0.15f, 0.15f, 0.25f);
|
||||
GfxRenderer.Bind( light ); // Select our texture
|
||||
//float ddl = (0.15*Global::diffuseDayLight[0]+0.295*Global::diffuseDayLight[1]+0.055*Global::diffuseDayLight[2]); //0.24:0
|
||||
glBegin( GL_QUADS );
|
||||
float fSmudge = dynamic->MoverParameters->DimHalf.y + 7; // gdzie zaczynać smugę
|
||||
if( frontlightstrength > 0.f ) {
|
||||
// wystarczy jeden zapalony z przodu
|
||||
for( int i = 15; i <= 35; i++ ) {
|
||||
float z = i * i * i * 0.01f;//25/4;
|
||||
//float C = (36 - i*0.5)*0.005*(1.5 - sqrt(ddl));
|
||||
float C = ( 36 - i*0.5 )*0.005*sqrt( ( 1 / sqrt( Global::fLuminance + 0.015 ) ) - 1 ) * frontlightstrength;
|
||||
glColor4f( C, C, C, 1.0f );// *frontlightstrength );
|
||||
glTexCoord2f( 0, 0 ); glVertex3f( -10 / 2 - 2 * i / 4, 6.0 + 0.3*z, 13 + 1.7*z / 3 );
|
||||
glTexCoord2f( 1, 0 ); glVertex3f( 10 / 2 + 2 * i / 4, 6.0 + 0.3*z, 13 + 1.7*z / 3 );
|
||||
glTexCoord2f( 1, 1 ); glVertex3f( 10 / 2 + 2 * i / 4, -5.0 - 0.5*z, 13 + 1.7*z / 3 );
|
||||
glTexCoord2f( 0, 1 ); glVertex3f( -10 / 2 - 2 * i / 4, -5.0 - 0.5*z, 13 + 1.7*z / 3 );
|
||||
}
|
||||
}
|
||||
if( rearlightstrength > 0.f ) {
|
||||
// wystarczy jeden zapalony z tyłu
|
||||
for( int i = 15; i <= 35; i++ ) {
|
||||
float z = i * i * i * 0.01f;//25/4;
|
||||
float C = ( 36 - i*0.5 )*0.005*sqrt( ( 1 / sqrt( Global::fLuminance + 0.015 ) ) - 1 ) * rearlightstrength;
|
||||
glColor4f( C, C, C, 1.0f );// *rearlightstrength );
|
||||
glTexCoord2f( 0, 0 ); glVertex3f( 10 / 2 + 2 * i / 4, 6.0 + 0.3*z, -13 - 1.7*z / 3 );
|
||||
glTexCoord2f( 1, 0 ); glVertex3f( -10 / 2 - 2 * i / 4, 6.0 + 0.3*z, -13 - 1.7*z / 3 );
|
||||
glTexCoord2f( 1, 1 ); glVertex3f( -10 / 2 - 2 * i / 4, -5.0 - 0.5*z, -13 - 1.7*z / 3 );
|
||||
glTexCoord2f( 0, 1 ); glVertex3f( 10 / 2 + 2 * i / 4, -5.0 - 0.5*z, -13 - 1.7*z / 3 );
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
// glEnable(GL_DEPTH_TEST);
|
||||
glAlphaFunc( GL_GREATER, 0.04 );
|
||||
glDepthFunc( GL_LEQUAL );
|
||||
glEnable( GL_LIGHTING ); //i tak się włączy potem
|
||||
glEnable( GL_FOG );
|
||||
}
|
||||
}
|
||||
|
||||
glEnable( GL_LIGHTING ); // po renderowaniu smugi jest to wyłączone
|
||||
// Ra: pojazd użytkownika należało by renderować po smudze, aby go nie rozświetlała
|
||||
|
||||
Global::bSmudge = false; // aby model użytkownika się teraz wyrenderował
|
||||
dynamic->Render();
|
||||
dynamic->RenderAlpha(); // przezroczyste fragmenty pojazdów na torach
|
||||
|
||||
} // yB: moje smuuugi 1 - koniec
|
||||
else
|
||||
*/ glEnable( GL_LIGHTING ); // po renderowaniu drutów może być to wyłączone. TODO: have the wires render take care of its own shit
|
||||
*/
|
||||
::glPushMatrix();
|
||||
auto const originoffset = dynamic->GetPosition() - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
::glMultMatrixd( dynamic->mMatrix.getArray() );
|
||||
|
||||
if( dynamic->mdKabina ) // bo mogła zniknąć przy przechodzeniu do innego pojazdu
|
||||
{
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
// 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++ ) { // przyciemnienie standardowe
|
||||
ambientCabLight[ li ] = Global::ambientDayLight[ li ] * 0.9;
|
||||
diffuseCabLight[ li ] = Global::diffuseDayLight[ li ] * 0.5;
|
||||
specularCabLight[ li ] = Global::specularDayLight[ li ] * 0.5;
|
||||
}
|
||||
switch( dynamic->MyTrack->eEnvironment ) { // wpływ świetła zewnętrznego
|
||||
case e_canyon:
|
||||
{
|
||||
for( int li = 0; li < 3; li++ ) {
|
||||
diffuseCabLight[ li ] *= 0.6;
|
||||
specularCabLight[ li ] *= 0.7;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case e_tunnel:
|
||||
{
|
||||
for( int li = 0; li < 3; li++ ) {
|
||||
ambientCabLight[ li ] *= 0.3;
|
||||
diffuseCabLight[ li ] *= 0.1;
|
||||
specularCabLight[ li ] *= 0.2;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
switch( Train->iCabLightFlag ) // Ra: uzeleżnic od napięcia w obwodzie sterowania
|
||||
{ // hunter-091012: uzaleznienie jasnosci od przetwornicy
|
||||
case 0: //światło wewnętrzne zgaszone
|
||||
break;
|
||||
case 1: //światło wewnętrzne przygaszone (255 216 176)
|
||||
if( dynamic->MoverParameters->ConverterFlag ==
|
||||
true ) // jasnosc dla zalaczonej przetwornicy
|
||||
{
|
||||
ambientCabLight[ 0 ] = Max0R( 0.700, ambientCabLight[ 0 ] ) * 0.75; // R
|
||||
ambientCabLight[ 1 ] = Max0R( 0.593, ambientCabLight[ 1 ] ) * 0.75; // G
|
||||
ambientCabLight[ 2 ] = Max0R( 0.483, ambientCabLight[ 2 ] ) * 0.75; // B
|
||||
|
||||
for( int i = 0; i < 3; i++ )
|
||||
if( ambientCabLight[ i ] <= ( Global::ambientDayLight[ i ] * 0.9 ) )
|
||||
ambientCabLight[ i ] = Global::ambientDayLight[ i ] * 0.9;
|
||||
}
|
||||
else {
|
||||
ambientCabLight[ 0 ] = Max0R( 0.700, ambientCabLight[ 0 ] ) * 0.375; // R
|
||||
ambientCabLight[ 1 ] = Max0R( 0.593, ambientCabLight[ 1 ] ) * 0.375; // G
|
||||
ambientCabLight[ 2 ] = Max0R( 0.483, ambientCabLight[ 2 ] ) * 0.375; // B
|
||||
|
||||
for( int i = 0; i < 3; i++ )
|
||||
if( ambientCabLight[ i ] <= ( Global::ambientDayLight[ i ] * 0.9 ) )
|
||||
ambientCabLight[ i ] = Global::ambientDayLight[ i ] * 0.9;
|
||||
}
|
||||
break;
|
||||
case 2: //światło wewnętrzne zapalone (255 216 176)
|
||||
if( dynamic->MoverParameters->ConverterFlag ==
|
||||
true ) // jasnosc dla zalaczonej przetwornicy
|
||||
{
|
||||
ambientCabLight[ 0 ] = Max0R( 1.000, ambientCabLight[ 0 ] ); // R
|
||||
ambientCabLight[ 1 ] = Max0R( 0.847, ambientCabLight[ 1 ] ); // G
|
||||
ambientCabLight[ 2 ] = Max0R( 0.690, ambientCabLight[ 2 ] ); // B
|
||||
|
||||
for( int i = 0; i < 3; i++ )
|
||||
if( ambientCabLight[ i ] <= ( Global::ambientDayLight[ i ] * 0.9 ) )
|
||||
ambientCabLight[ i ] = Global::ambientDayLight[ i ] * 0.9;
|
||||
}
|
||||
else {
|
||||
ambientCabLight[ 0 ] = Max0R( 1.000, ambientCabLight[ 0 ] ) * 0.5; // R
|
||||
ambientCabLight[ 1 ] = Max0R( 0.847, ambientCabLight[ 1 ] ) * 0.5; // G
|
||||
ambientCabLight[ 2 ] = Max0R( 0.690, ambientCabLight[ 2 ] ) * 0.5; // B
|
||||
|
||||
for( int i = 0; i < 3; i++ )
|
||||
if( ambientCabLight[ i ] <= ( Global::ambientDayLight[ i ] * 0.9 ) )
|
||||
ambientCabLight[ i ] = Global::ambientDayLight[ i ] * 0.9;
|
||||
}
|
||||
break;
|
||||
}
|
||||
glLightfv( GL_LIGHT0, GL_AMBIENT, ambientCabLight );
|
||||
glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuseCabLight );
|
||||
glLightfv( GL_LIGHT0, GL_SPECULAR, specularCabLight );
|
||||
#else
|
||||
// setup
|
||||
if( dynamic->fShade > 0.0f ) {
|
||||
// change light level based on light level of the occupied track
|
||||
Global::DayLight.apply_intensity( dynamic->fShade );
|
||||
}
|
||||
if( dynamic->InteriorLightLevel > 0.0f ) {
|
||||
|
||||
// crude way to light the cabin, until we have something more complete in place
|
||||
auto const cablight = dynamic->InteriorLight * dynamic->InteriorLightLevel;
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, &cablight.x );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
if( Global::bUseVBO ) {
|
||||
// renderowanie z użyciem VBO. NOTE: needs update, and eventual merge into single render path down the road
|
||||
dynamic->mdKabina->RaRender( 0.0, dynamic->Material()->replacable_skins, dynamic->Material()->textures_alpha );
|
||||
dynamic->mdKabina->RaRenderAlpha( 0.0, dynamic->Material()->replacable_skins, dynamic->Material()->textures_alpha );
|
||||
}
|
||||
else {
|
||||
// renderowanie z Display List
|
||||
dynamic->mdKabina->Render( 0.0, dynamic->ReplacableSkinID, dynamic->iAlpha );
|
||||
dynamic->mdKabina->RenderAlpha( 0.0, dynamic->ReplacableSkinID, dynamic->iAlpha );
|
||||
}
|
||||
#else
|
||||
// render
|
||||
GfxRenderer.Render( dynamic->mdKabina, dynamic->Material(), 0.0 );
|
||||
GfxRenderer.Render_Alpha( dynamic->mdKabina, dynamic->Material(), 0.0 );
|
||||
#endif
|
||||
#ifdef EU07_USE_OLD_LIGHTING_MODEL
|
||||
// przywrócenie standardowych, bo zawsze są zmieniane
|
||||
glLightfv( GL_LIGHT0, GL_AMBIENT, Global::ambientDayLight );
|
||||
glLightfv( GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight );
|
||||
glLightfv( GL_LIGHT0, GL_SPECULAR, Global::specularDayLight );
|
||||
#else
|
||||
// post-render restore
|
||||
if( dynamic->fShade > 0.0f ) {
|
||||
// change light level based on light level of the occupied track
|
||||
Global::DayLight.apply_intensity();
|
||||
@@ -1626,7 +1317,6 @@ TWorld::Render_Cab() {
|
||||
GLfloat ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
::glLightModelfv( GL_LIGHT_MODEL_AMBIENT, ambient );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
glPopMatrix();
|
||||
}
|
||||
@@ -1748,11 +1438,9 @@ TWorld::Update_UI() {
|
||||
Global::Bezogonkow( "| " + station + " | " + arrival + " | " + departure + " | " + vmax + " | " + tableline->StationWare, true ),
|
||||
( ( owner->iStationStart < table->StationIndex )
|
||||
&& ( i < table->StationIndex )
|
||||
&& ( time.wHour >= tableline->Dh )
|
||||
&& ( time.wMinute >= tableline->Dm ) ?
|
||||
&& ( ( time.wHour * 60 + time.wMinute ) >= ( tableline->Dh * 60 + tableline->Dm ) ) ?
|
||||
float4( 0.0f, 1.0f, 0.0f, 1.0f ) :// czas minął i odjazd był, to nazwa stacji będzie na zielono
|
||||
Global::UITextColor )
|
||||
);
|
||||
Global::UITextColor ) );
|
||||
// divider/footer
|
||||
UITable->text_lines.emplace_back( "+----------------------------+-------+-------+-----+", Global::UITextColor );
|
||||
}
|
||||
@@ -1864,9 +1552,9 @@ TWorld::Update_UI() {
|
||||
uitextline3 += ( tmp->MoverParameters->PantRearUp ? ( tmp->MoverParameters->PantRearVolt > 0.0 ? "O" : "o" ) : "." );;
|
||||
uitextline3 += ( tmp->MoverParameters->PantFrontUp ? ( tmp->MoverParameters->PantFrontVolt > 0.0 ? "P" : "p" ) : "." );;
|
||||
uitextline3 += ( tmp->MoverParameters->PantPressLockActive ? "!" : ( tmp->MoverParameters->PantPressSwitchActive ? "*" : "." ) );
|
||||
uitextline3 += ( tmp->MoverParameters->ConverterAllow ? ( tmp->MoverParameters->ConverterFlag ? "X" : "x" ) : "." );
|
||||
uitextline3 += ( false == tmp->MoverParameters->ConverterAllowLocal ? "-" : ( tmp->MoverParameters->ConverterAllow ? ( tmp->MoverParameters->ConverterFlag ? "X" : "x" ) : "." ) );
|
||||
uitextline3 += ( tmp->MoverParameters->ConvOvldFlag ? "!" : "." );
|
||||
uitextline3 += ( tmp->MoverParameters->CompressorAllow ? ( tmp->MoverParameters->CompressorFlag ? "C" : "c" ) : "." );
|
||||
uitextline3 += ( false == tmp->MoverParameters->CompressorAllowLocal ? "-" : ( tmp->MoverParameters->CompressorAllow ? ( tmp->MoverParameters->CompressorFlag ? "C" : "c" ) : "." ) );
|
||||
uitextline3 += ( tmp->MoverParameters->CompressorGovernorLock ? "!" : "." );
|
||||
|
||||
uitextline3 +=
|
||||
@@ -2385,103 +2073,119 @@ void TWorld::ModifyTGA(const std::string &dir)
|
||||
}
|
||||
*/
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
std::string last; // zmienne używane w rekurencji
|
||||
double shift = 0;
|
||||
void TWorld::CreateE3D(std::string const &dir, bool dyn)
|
||||
|
||||
void TWorld::CreateE3D(std::string const &Path, bool Dynamic)
|
||||
{ // rekurencyjna generowanie plików E3D
|
||||
|
||||
/* TODO: remove Borland file access stuff
|
||||
TTrack *trk;
|
||||
double at;
|
||||
TSearchRec sr;
|
||||
if (FindFirst(dir + "*.*", faDirectory | faArchive, sr) == 0)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (sr.Name[1] != '.')
|
||||
if ((sr.Attr & faDirectory)) // jeśli katalog, to rekurencja
|
||||
CreateE3D(dir + sr.Name + "\\", dyn);
|
||||
else if (dyn)
|
||||
{
|
||||
if (sr.Name.LowerCase().SubString(sr.Name.Length() - 3, 4) == ".mmd")
|
||||
{
|
||||
// konwersja pojazdów będzie ułomna, bo nie poustawiają się animacje na
|
||||
// submodelach określonych w MMD
|
||||
// TModelsManager::GetModel(AnsiString(dir+sr.Name).c_str(),true);
|
||||
if (last != dir)
|
||||
{ // utworzenie toru dla danego pojazdu
|
||||
last = dir;
|
||||
trk = TTrack::Create400m(1, shift);
|
||||
shift += 10.0; // następny tor będzie deczko dalej, aby nie zabić FPS
|
||||
at = 400.0;
|
||||
// if (shift>1000) break; //bezpiecznik
|
||||
std::string last; // zmienne używane w rekurencji
|
||||
TTrack *trk{ nullptr };
|
||||
double at{ 0.0 };
|
||||
double shift{ 0.0 };
|
||||
|
||||
#ifdef _WINDOWS
|
||||
|
||||
std::string searchpattern( "*.*" );
|
||||
|
||||
::WIN32_FIND_DATA filedata;
|
||||
::HANDLE search = ::FindFirstFile( ( Path + searchpattern ).c_str(), &filedata );
|
||||
|
||||
if( search == INVALID_HANDLE_VALUE ) { return; } // if nothing to do, bail out
|
||||
|
||||
do {
|
||||
|
||||
std::string filename = filedata.cFileName;
|
||||
|
||||
if( filedata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
|
||||
// launch recursive search for sub-directories...
|
||||
if( filename == "." ) { continue; }
|
||||
if( filename == ".." ) { continue; }
|
||||
CreateE3D( Path + filename + "\\", Dynamic );
|
||||
}
|
||||
else {
|
||||
// process the file
|
||||
if( filename.size() < 4 ) { continue; }
|
||||
std::string const filetype = ToLower( filename.substr( filename.size() - 4, 4 ) );
|
||||
if( filetype == ".mmd" ) {
|
||||
if( false == Dynamic ) { continue; }
|
||||
|
||||
// konwersja pojazdów będzie ułomna, bo nie poustawiają się animacje na submodelach określonych w MMD
|
||||
if( last != Path ) { // utworzenie toru dla danego pojazdu
|
||||
last = Path;
|
||||
trk = TTrack::Create400m( 1, shift );
|
||||
shift += 10.0; // następny tor będzie deczko dalej, aby nie zabić FPS
|
||||
at = 400.0;
|
||||
}
|
||||
TGroundNode *tmp = new TGroundNode();
|
||||
tmp->DynamicObject = new TDynamicObject();
|
||||
|
||||
at -= tmp->DynamicObject->Init(
|
||||
"",
|
||||
Path.substr( 8, Path.size() - 9 ), // skip leading "dynamic/" and trailing slash
|
||||
"none",
|
||||
filename.substr( 0, filename.size() - 4 ),
|
||||
trk,
|
||||
at,
|
||||
"nobody", 0.0, "none", 0.0, "", false, "" );
|
||||
|
||||
// po wczytaniu CHK zrobić pętlę po ładunkach, aby każdy z nich skonwertować
|
||||
cParser loadparser( tmp->DynamicObject->MoverParameters->LoadAccepted ); // typy ładunków
|
||||
std::string loadname;
|
||||
loadparser.getTokens( 1, true, "," ); loadparser >> loadname;
|
||||
while( loadname != "" ) {
|
||||
|
||||
if( ( true == FileExists( Path + loadname + ".t3d" ) )
|
||||
&& ( false == FileExists( Path + loadname + ".e3d" ) ) ) {
|
||||
// a nie ma jeszcze odpowiednika binarnego
|
||||
at -= tmp->DynamicObject->Init(
|
||||
"",
|
||||
Path.substr( 8, Path.size() - 9 ), // skip leading "dynamic/" and trailing slash
|
||||
"none",
|
||||
filename.substr( 0, filename.size() - 4 ),
|
||||
trk,
|
||||
at,
|
||||
"nobody", 0.0, "none", 1.0, loadname, false, "" );
|
||||
}
|
||||
TGroundNode *tmp = new TGroundNode();
|
||||
tmp->DynamicObject = new TDynamicObject();
|
||||
// Global::asCurrentTexturePath=dir; //pojazdy mają tekstury we własnych
|
||||
// katalogach
|
||||
at -= tmp->DynamicObject->Init(
|
||||
"", string((dir.SubString(9, dir.Length() - 9)).c_str()), "none",
|
||||
string(sr.Name.SubString(1, sr.Name.Length() - 4).c_str()), trk, at, "nobody", 0.0,
|
||||
"none", 0.0, "", false, "");
|
||||
// po wczytaniu CHK zrobić pętlę po ładunkach, aby każdy z nich skonwertować
|
||||
AnsiString loads, load;
|
||||
loads = AnsiString(tmp->DynamicObject->MoverParameters->LoadAccepted.c_str()); // typy ładunków
|
||||
if (!loads.IsEmpty())
|
||||
{
|
||||
loads += ","; // przecinek na końcu
|
||||
int i = loads.Pos(",");
|
||||
while (i > 1)
|
||||
{ // wypadało by sprawdzić, czy T3D ładunku jest
|
||||
load = loads.SubString(1, i - 1);
|
||||
if (FileExists(dir + load + ".t3d")) // o ile jest plik ładunku, bo
|
||||
// inaczej nie ma to sensu
|
||||
if (!FileExists(
|
||||
dir + load +
|
||||
".e3d")) // a nie ma jeszcze odpowiednika binarnego
|
||||
at -= tmp->DynamicObject->Init(
|
||||
"", dir.SubString(9, dir.Length() - 9).c_str(), "none",
|
||||
sr.Name.SubString(1, sr.Name.Length() - 4).c_str(), trk, at,
|
||||
"nobody", 0.0, "none", 1.0, load.c_str(), false, "");
|
||||
loads.Delete(1, i); // usunięcie z następującym przecinkiem
|
||||
i = loads.Pos(",");
|
||||
}
|
||||
}
|
||||
if (tmp->DynamicObject->iCabs)
|
||||
{ // jeśli ma jakąkolwiek kabinę
|
||||
delete Train;
|
||||
Train = new TTrain();
|
||||
if (tmp->DynamicObject->iCabs & 1)
|
||||
{
|
||||
tmp->DynamicObject->MoverParameters->ActiveCab = 1;
|
||||
Train->Init(tmp->DynamicObject, true);
|
||||
}
|
||||
if (tmp->DynamicObject->iCabs & 4)
|
||||
{
|
||||
tmp->DynamicObject->MoverParameters->ActiveCab = -1;
|
||||
Train->Init(tmp->DynamicObject, true);
|
||||
}
|
||||
if (tmp->DynamicObject->iCabs & 2)
|
||||
{
|
||||
tmp->DynamicObject->MoverParameters->ActiveCab = 0;
|
||||
Train->Init(tmp->DynamicObject, true);
|
||||
}
|
||||
}
|
||||
Global::asCurrentTexturePath =
|
||||
(szTexturePath); // z powrotem defaultowa sciezka do tekstur
|
||||
|
||||
loadname = "";
|
||||
loadparser.getTokens( 1, true, "," ); loadparser >> loadname;
|
||||
}
|
||||
|
||||
if( tmp->DynamicObject->iCabs ) { // jeśli ma jakąkolwiek kabinę
|
||||
delete Train;
|
||||
Train = new TTrain();
|
||||
if( tmp->DynamicObject->iCabs & 1 ) {
|
||||
tmp->DynamicObject->MoverParameters->ActiveCab = 1;
|
||||
Train->Init( tmp->DynamicObject, true );
|
||||
}
|
||||
if( tmp->DynamicObject->iCabs & 4 ) {
|
||||
tmp->DynamicObject->MoverParameters->ActiveCab = -1;
|
||||
Train->Init( tmp->DynamicObject, true );
|
||||
}
|
||||
if( tmp->DynamicObject->iCabs & 2 ) {
|
||||
tmp->DynamicObject->MoverParameters->ActiveCab = 0;
|
||||
Train->Init( tmp->DynamicObject, true );
|
||||
}
|
||||
}
|
||||
else if (sr.Name.LowerCase().SubString(sr.Name.Length() - 3, 4) == ".t3d")
|
||||
{ // z modelami jest prościej
|
||||
Global::asCurrentTexturePath = dir.c_str();
|
||||
TModelsManager::GetModel(AnsiString(dir + sr.Name).c_str(), false);
|
||||
}
|
||||
} while (FindNext(sr) == 0);
|
||||
FindClose(sr);
|
||||
}
|
||||
*/
|
||||
// z powrotem defaultowa sciezka do tekstur
|
||||
Global::asCurrentTexturePath = ( szTexturePath );
|
||||
}
|
||||
else if( filetype == ".t3d" ) {
|
||||
// z modelami jest prościej
|
||||
Global::asCurrentTexturePath = Path;
|
||||
TModelsManager::GetModel( Path + filename, false );
|
||||
}
|
||||
}
|
||||
|
||||
} while( ::FindNextFile( search, &filedata ) );
|
||||
|
||||
// all done, clean up
|
||||
::FindClose( search );
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
void TWorld::CabChange(TDynamicObject *old, TDynamicObject *now)
|
||||
{ // ewentualna zmiana kabiny użytkownikowi
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LocalDebuggerWorkingDirectory>..\..\..\development\maszyna</LocalDebuggerWorkingDirectory>
|
||||
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
|
||||
<LocalDebuggerCommandArguments>
|
||||
</LocalDebuggerCommandArguments>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LocalDebuggerWorkingDirectory>..\..\Projects\maszyna</LocalDebuggerWorkingDirectory>
|
||||
|
||||
@@ -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
|
||||
|
||||
336
renderer.cpp
336
renderer.cpp
@@ -142,9 +142,16 @@ 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 ))));
|
||||
|
||||
Render( &World.Environment );
|
||||
Render( &World.Ground );
|
||||
@@ -178,11 +185,12 @@ opengl_renderer::Render( world_environment *Environment ) {
|
||||
/*
|
||||
::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
|
||||
@@ -294,12 +302,16 @@ 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 );
|
||||
|
||||
++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 );
|
||||
@@ -310,22 +322,13 @@ 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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
::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 );
|
||||
|
||||
++TGroundRect::iFrameNumber; // zwięszenie licznika ramek (do usuwniania nadanimacji)
|
||||
|
||||
Update_Lights( Ground->m_lights );
|
||||
|
||||
Ground->CameraDirection.x = std::sin( Global::pCameraRotation ); // wektor kierunkowy
|
||||
Ground->CameraDirection.z = std::cos( Global::pCameraRotation );
|
||||
TGroundNode *node;
|
||||
@@ -354,6 +357,16 @@ opengl_renderer::Render( TGround *Ground ) {
|
||||
}
|
||||
}
|
||||
// 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
|
||||
@@ -369,18 +382,12 @@ opengl_renderer::Render( TGround *Ground ) {
|
||||
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.55 )
|
||||
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
|
||||
if( Global::bUseVBO ) {
|
||||
// vbo render path
|
||||
Ground->Rects[ ( i + c ) / iNumSubRects ][ ( j + r ) / iNumSubRects ].RenderVBO();
|
||||
}
|
||||
else {
|
||||
// display list render path
|
||||
Ground->Rects[ ( i + c ) / iNumSubRects ][ ( j + r ) / iNumSubRects ].RenderDL();
|
||||
}
|
||||
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ć
|
||||
@@ -389,29 +396,149 @@ opengl_renderer::Render( TGround *Ground ) {
|
||||
}
|
||||
} 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::bUseVBO ) {
|
||||
if( Global::pTerrainCompact ) {
|
||||
Global::pTerrainCompact->TerrainRenderVBO( TGroundRect::iFrameNumber );
|
||||
}
|
||||
}
|
||||
|
||||
// renderowanie nieprzezroczystych
|
||||
for( i = 0; i < Ground->iRendered; ++i ) {
|
||||
if( Global::bUseVBO ) {
|
||||
// vbo render path
|
||||
Ground->pRendered[ i ]->RenderVBO();
|
||||
}
|
||||
else {
|
||||
// display list render path
|
||||
Ground->pRendered[ i ]->RenderDL();
|
||||
}
|
||||
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( Global::bUseVBO ) {
|
||||
|
||||
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();
|
||||
}
|
||||
else {
|
||||
#ifdef EU07_USE_OLD_RENDERCODE
|
||||
if (Groundcell->iLastDisplay != Groundcell->iFrameNumber)
|
||||
{ // tylko jezeli dany kwadrat nie był jeszcze renderowany
|
||||
// for (TGroundNode* node=pRender;node;node=node->pNext3)
|
||||
// node->Render(); //nieprzezroczyste trójkąty kwadratu kilometrowego
|
||||
if ( Groundcell->nRender)
|
||||
{ //łączenie trójkątów w jedną listę - trochę wioska
|
||||
if (!Groundcell->nRender->DisplayListID || ( Groundcell->nRender->iVersion != Global::iReCompile))
|
||||
{ // jeżeli nie skompilowany, kompilujemy wszystkie trójkąty w jeden
|
||||
Groundcell->nRender->fSquareRadius = 5000.0 * 5000.0; // aby agregat nigdy nie znikał
|
||||
Groundcell->nRender->DisplayListID = glGenLists(1);
|
||||
glNewList( Groundcell->nRender->DisplayListID, GL_COMPILE);
|
||||
Groundcell->nRender->iVersion = Global::iReCompile; // aktualna wersja siatek
|
||||
auto const origin = Math3D::vector3( Groundcell->m_area.center.x, Groundcell->m_area.center.y, Groundcell->m_area.center.z );
|
||||
for (TGroundNode *node = Groundcell->nRender; node; node = node->nNext3) // następny tej grupy
|
||||
node->Compile(origin, true);
|
||||
glEndList();
|
||||
}
|
||||
Render( Groundcell->nRender ); // nieprzezroczyste trójkąty kwadratu kilometrowego
|
||||
}
|
||||
// submodels geometry is world-centric, so at least for the time being we need to pop the stack early
|
||||
::glPopMatrix();
|
||||
|
||||
if( Groundcell->nRootMesh ) {
|
||||
Render( Groundcell->nRootMesh );
|
||||
}
|
||||
Groundcell->iLastDisplay = Groundcell->iFrameNumber; // drugi raz nie potrzeba
|
||||
result = true;
|
||||
}
|
||||
else {
|
||||
::glPopMatrix();
|
||||
}
|
||||
#else
|
||||
if( iLastDisplay != iFrameNumber ) { // tylko jezeli dany kwadrat nie był jeszcze renderowany
|
||||
LoadNodes(); // ewentualne tworzenie siatek
|
||||
if( nRenderRect ) {
|
||||
for( TGroundNode *node = nRenderRect; node; node = node->nNext3 ) // następny tej grupy
|
||||
Render( node ); // nieprzezroczyste trójkąty kwadratu kilometrowego
|
||||
}
|
||||
if( nRootMesh )
|
||||
Render( nRootMesh );
|
||||
iLastDisplay = iFrameNumber;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
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
|
||||
if( Global::bUseVBO ) {
|
||||
// vbo render path
|
||||
if( Groundsubcell->StartVBO() ) {
|
||||
for( node = Groundsubcell->nRenderRect; node; node = node->nNext3 ) {
|
||||
if( node->iVboPtr >= 0 ) {
|
||||
Render( node );
|
||||
}
|
||||
}
|
||||
Groundsubcell->EndVBO();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// display list render path
|
||||
for( node = Groundsubcell->nRenderRect; node; node = node->nNext3 ) {
|
||||
Render( node ); // nieprzezroczyste obiekty terenu
|
||||
}
|
||||
}
|
||||
// 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
|
||||
@@ -422,8 +549,12 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -436,22 +567,30 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
||||
switch (Node->iType)
|
||||
{
|
||||
case TP_TRACK: {
|
||||
|
||||
if( Global::bUseVBO && ( 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
|
||||
if( Global::bUseVBO ) {
|
||||
if( Node->iNumVerts ) {
|
||||
Node->pTrack->RaRenderVBO( Node->iVboPtr );
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
// vbo render path
|
||||
Node->pTrack->RaRenderVBO( Node->iVboPtr );
|
||||
}
|
||||
else {
|
||||
// display list render path
|
||||
Node->pTrack->Render();
|
||||
}
|
||||
// post-render cleanup
|
||||
::glPopMatrix();
|
||||
return true;
|
||||
}
|
||||
case TP_MODEL: {
|
||||
Node->Model->Render( &Node->pCenter );
|
||||
Node->Model->Render( Node->pCenter - Global::pCameraPosition );
|
||||
return true;
|
||||
}
|
||||
case TP_MEMCELL: {
|
||||
@@ -468,7 +607,7 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
||||
// additional setup for display lists
|
||||
if( ( Node->DisplayListID == 0 )
|
||||
|| ( Node->iVersion != Global::iReCompile ) ) { // Ra: wymuszenie rekompilacji
|
||||
Node->Compile();
|
||||
Node->Compile(Node->m_rootposition);
|
||||
if( Global::bManageNodes )
|
||||
ResourceManager::Register( Node );
|
||||
};
|
||||
@@ -492,11 +631,16 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
||||
// render
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
if( Global::bUseVBO ) {
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
::glDrawArrays( Node->iType, Node->iVboPtr, Node->iNumPts );
|
||||
::glPopMatrix();
|
||||
}
|
||||
else {
|
||||
::glCallList( Node->DisplayListID );
|
||||
}
|
||||
// post-render cleanup
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
@@ -505,6 +649,11 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
||||
}
|
||||
else {
|
||||
// GL_TRIANGLE etc
|
||||
if( ( Global::bUseVBO ?
|
||||
Node->iVboPtr < 0 :
|
||||
Node->DisplayListID == 0 ) ) {
|
||||
return false;
|
||||
}
|
||||
// setup
|
||||
::glColor3ub(
|
||||
static_cast<GLubyte>( Node->Diffuse[ 0 ] ),
|
||||
@@ -517,22 +666,17 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
||||
// TODO: unify the render code after generic buffers are in place
|
||||
if( Global::bUseVBO ) {
|
||||
// vbo render path
|
||||
if( Node->iVboPtr >= 0 ) {
|
||||
::glDrawArrays( Node->iType, Node->iVboPtr, Node->iNumVerts );
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
::glPushMatrix();
|
||||
auto const originoffset = Node->m_rootposition - Global::pCameraPosition;
|
||||
::glTranslated( originoffset.x, originoffset.y, originoffset.z );
|
||||
::glDrawArrays( Node->iType, Node->iVboPtr, Node->iNumVerts );
|
||||
::glPopMatrix();
|
||||
}
|
||||
else {
|
||||
// display list render path
|
||||
if( Node->DisplayListID != 0 ) {
|
||||
::glCallList( Node->DisplayListID );
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
::glCallList( Node->DisplayListID );
|
||||
}
|
||||
// post-render cleanup
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -550,11 +694,11 @@ opengl_renderer::Render( 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
|
||||
//tu trzeba by ustawić animacje na modelu zewnętrznym
|
||||
@@ -563,7 +707,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 ) {
|
||||
@@ -666,7 +811,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();
|
||||
|
||||
@@ -864,14 +1010,7 @@ opengl_renderer::Render_Alpha( TGround *Ground ) {
|
||||
}
|
||||
for( int i = Ground->iRendered - 1; i >= 0; --i ) // od najdalszych
|
||||
{ // renderowanie przezroczystych modeli oraz pojazdów
|
||||
if( Global::bUseVBO ) {
|
||||
// vbo render path
|
||||
Ground->pRendered[ i ]->RenderAlphaVBO();
|
||||
}
|
||||
else {
|
||||
// display list render path
|
||||
Ground->pRendered[ i ]->RenderAlphaDL();
|
||||
}
|
||||
Render_Alpha( Ground->pRendered[ i ] );
|
||||
}
|
||||
|
||||
::glDisable( GL_LIGHTING ); // linie nie powinny świecić
|
||||
@@ -899,6 +1038,20 @@ opengl_renderer::Render_Alpha( TGround *Ground ) {
|
||||
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
|
||||
|
||||
@@ -932,12 +1085,19 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
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
|
||||
if( Global::bUseVBO ) {
|
||||
Node->hvTraction->RenderVBO( distancesquared, Node->iVboPtr );
|
||||
}
|
||||
else {
|
||||
Node->hvTraction->RenderDL( distancesquared );
|
||||
Node->hvTraction->RenderDL( distancesquared, Node->m_rootposition );
|
||||
}
|
||||
// post-render cleanup
|
||||
::glPopMatrix();
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
@@ -945,7 +1105,7 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
}
|
||||
}
|
||||
case TP_MODEL: {
|
||||
Node->Model->RenderAlpha( &Node->pCenter );
|
||||
Node->Model->RenderAlpha( Node->pCenter - Global::pCameraPosition );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -966,7 +1126,7 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
// additional setup for display lists
|
||||
if( ( Node->DisplayListID == 0 )
|
||||
|| ( Node->iVersion != Global::iReCompile ) ) { // Ra: wymuszenie rekompilacji
|
||||
Node->Compile();
|
||||
Node->Compile(Node->m_rootposition);
|
||||
if( Global::bManageNodes )
|
||||
ResourceManager::Register( Node );
|
||||
};
|
||||
@@ -980,6 +1140,9 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
// 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[ 0 ] ) ),
|
||||
@@ -997,12 +1160,18 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
else {
|
||||
::glCallList( Node->DisplayListID );
|
||||
}
|
||||
// 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 ] ),
|
||||
@@ -1024,8 +1193,10 @@ opengl_renderer::Render_Alpha( TGroundNode *Node ) {
|
||||
::glCallList( Node->DisplayListID );
|
||||
result = true;
|
||||
}
|
||||
// post-render cleanup
|
||||
::glPopMatrix();
|
||||
}
|
||||
// post-render cleanup
|
||||
|
||||
#ifdef _PROBLEND
|
||||
if( ( Node->PROBLEND ) ) // sprawdza, czy w nazwie nie ma @ //Q: 13122011 - Szociu: 27012012
|
||||
{
|
||||
@@ -1049,17 +1220,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 ) {
|
||||
@@ -1161,7 +1334,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();
|
||||
|
||||
@@ -1400,7 +1574,7 @@ opengl_renderer::Update_Lights( light_array const &Lights ) {
|
||||
continue;
|
||||
}
|
||||
// if the light passed tests so far, it's good enough
|
||||
renderlight->set_position( scenelight.position );
|
||||
renderlight->set_position( scenelight.position - Global::pCameraPosition );
|
||||
renderlight->direction = scenelight.direction;
|
||||
|
||||
auto luminance = Global::fLuminance; // TODO: adjust this based on location, e.g. for tunnels
|
||||
|
||||
@@ -94,7 +94,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
|
||||
@@ -124,6 +124,10 @@ public:
|
||||
Render( world_environment *Environment );
|
||||
bool
|
||||
Render( TGround *Ground );
|
||||
bool
|
||||
Render( TGroundRect *Groundcell );
|
||||
bool
|
||||
Render( TSubRect *Groundsubcell );
|
||||
bool
|
||||
Render( TGroundNode *Node );
|
||||
bool
|
||||
@@ -138,6 +142,8 @@ public:
|
||||
Render( TMemCell *Memcell );
|
||||
bool
|
||||
Render_Alpha( TGround *Ground );
|
||||
bool
|
||||
Render_Alpha( TSubRect *Groundsubcell );
|
||||
bool
|
||||
Render_Alpha( TGroundNode *Node );
|
||||
bool
|
||||
|
||||
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();
|
||||
|
||||
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 ) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#define VERSION_MAJOR 17
|
||||
#define VERSION_MINOR 517
|
||||
#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