mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-18 07:49:19 +02:00
5841 lines
255 KiB
C++
5841 lines
255 KiB
C++
/*
|
||
This Source Code Form is subject to the
|
||
terms of the Mozilla Public License, v.
|
||
2.0. If a copy of the MPL was not
|
||
distributed with this file, You can
|
||
obtain one at
|
||
http://mozilla.org/MPL/2.0/.
|
||
*/
|
||
/*
|
||
MaSzyna EU07 locomotive simulator
|
||
Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others
|
||
|
||
*/
|
||
|
||
#include "stdafx.h"
|
||
#include "DynObj.h"
|
||
|
||
#include "logs.h"
|
||
#include "MdlMngr.h"
|
||
#include "Timer.h"
|
||
#include "Usefull.h"
|
||
// McZapkie-260202
|
||
#include "Globals.h"
|
||
#include "Texture.h"
|
||
#include "AirCoupler.h"
|
||
|
||
#include "TractionPower.h"
|
||
#include "Ground.h" //bo Global::pGround->bDynamicRemove
|
||
#include "Event.h"
|
||
#include "Driver.h"
|
||
#include "Camera.h" //bo likwidujemy trz<72>sienie
|
||
#include "Console.h"
|
||
#include "Traction.h"
|
||
|
||
// Ra: taki zapis funkcjonuje lepiej, ale mo<6D>e nie jest optymalny
|
||
#define vWorldFront Math3D::vector3(0, 0, 1)
|
||
#define vWorldUp Math3D::vector3(0, 1, 0)
|
||
#define vWorldLeft CrossProduct(vWorldUp, vWorldFront)
|
||
|
||
// Ra: bo te poni<6E>ej to si<73> powiela<6C>y w ka<6B>dym module odobno
|
||
// vector3 vWorldFront=vector3(0,0,1);
|
||
// vector3 vWorldUp=vector3(0,1,0);
|
||
// vector3 vWorldLeft=CrossProduct(vWorldUp,vWorldFront);
|
||
|
||
#define M_2PI 6.283185307179586476925286766559;
|
||
const float maxrot = (M_PI / 3.0); // 60<36>
|
||
|
||
//---------------------------------------------------------------------------
|
||
void TAnimPant::AKP_4E()
|
||
{ // ustawienie wymiar<61>w dla pantografu AKP-4E
|
||
vPos = vector3(0, 0, 0); // przypisanie domy<6D>nych wsp<73><70>czynnik<69>w do pantograf<61>w
|
||
fLenL1 = 1.22; // 1.176289 w modelach
|
||
fLenU1 = 1.755; // 1.724482197 w modelach
|
||
fHoriz = 0.535; // 0.54555075 przesuni<6E>cie <20>lizgu w d<>ugo<67>ci pojazdu wzgl<67>dem
|
||
// osi obrotu dolnego
|
||
// ramienia
|
||
fHeight = 0.07; // wysoko<6B><6F> <20>lizgu ponad o<> obrotu
|
||
fWidth = 0.635; // po<70>owa szeroko<6B>ci <20>lizgu, 0.635 dla AKP-1 i AKP-4E
|
||
fAngleL0 = DegToRad(2.8547285515689267247882521833308);
|
||
fAngleL = fAngleL0; // pocz<63>tkowy k<>t dolnego ramienia
|
||
// fAngleU0=acos((1.22*cos(fAngleL)+0.535)/1.755); //g<>rne rami<6D>
|
||
fAngleU0 = acos((fLenL1 * cos(fAngleL) + fHoriz) / fLenU1); // g<>rne rami<6D>
|
||
fAngleU = fAngleU0; // pocz<63>tkowy k<>t
|
||
// PantWys=1.22*sin(fAngleL)+1.755*sin(fAngleU); //wysoko<6B><6F> pocz<63>tkowa
|
||
PantWys = fLenL1 * sin(fAngleL) + fLenU1 * sin(fAngleU) + fHeight; // wysoko<6B><6F> pocz<63>tkowa
|
||
PantTraction = PantWys;
|
||
hvPowerWire = NULL;
|
||
fWidthExtra = 0.381; //(2.032m-1.027)/2
|
||
// poza obszarem roboczym jest aproksymacja <20>aman<61> o 5 odcinkach
|
||
fHeightExtra[0] = 0.0; //+0.0762
|
||
fHeightExtra[1] = -0.01; //+0.1524
|
||
fHeightExtra[2] = -0.03; //+0.2286
|
||
fHeightExtra[3] = -0.07; //+0.3048
|
||
fHeightExtra[4] = -0.15; //+0.3810
|
||
};
|
||
//---------------------------------------------------------------------------
|
||
int TAnim::TypeSet(int i, int fl)
|
||
{ // ustawienie typu animacji i zale<6C>nej od
|
||
// niego ilo<6C>ci animowanych submodeli
|
||
fMaxDist = -1.0; // normalnie nie pokazywa<77>
|
||
switch (i)
|
||
{ // maska 0x000F: ile u<>ywa wska<6B>nik<69>w na submodele (0 gdy jeden,
|
||
// wtedy bez tablicy)
|
||
// maska 0x00F0:
|
||
// 0-osie,1-drzwi,2-obracane,3-zderzaki,4-w<>zki,5-pantografy,6-t<>oki
|
||
// maska 0xFF00: ile u<>ywa liczb float dla wsp<73><70>czynnik<69>w i stanu
|
||
case 0:
|
||
iFlags = 0x000;
|
||
break; // 0-o<>
|
||
case 1:
|
||
iFlags = 0x010;
|
||
break; // 1-drzwi
|
||
case 2:
|
||
iFlags = 0x020;
|
||
fParam = fl ? new float[fl] : NULL;
|
||
iFlags += fl << 8;
|
||
break; // 2-wahacz, d<>wignia itp.
|
||
case 3:
|
||
iFlags = 0x030;
|
||
break; // 3-zderzak
|
||
case 4:
|
||
iFlags = 0x040;
|
||
break; // 4-w<>zek
|
||
case 5: // 5-pantograf - 5 submodeli
|
||
iFlags = 0x055;
|
||
fParamPants = new TAnimPant();
|
||
fParamPants->AKP_4E();
|
||
break;
|
||
case 6:
|
||
iFlags = 0x068;
|
||
break; // 6-t<>ok i rozrz<72>d - 8 submodeli
|
||
default:
|
||
iFlags = 0;
|
||
}
|
||
yUpdate = nullptr;
|
||
return iFlags & 15; // ile wska<6B>nik<69>w rezerwowa<77> dla danego typu animacji
|
||
};
|
||
TAnim::TAnim()
|
||
{ // potrzebne to w og<6F>le?
|
||
iFlags = -1; // nieznany typ - destruktor nic nie usuwa
|
||
};
|
||
TAnim::~TAnim()
|
||
{ // usuwanie animacji
|
||
switch (iFlags & 0xF0)
|
||
{ // usuwanie struktur, zale<6C>nie ile zosta<74>o stworzonych
|
||
case 0x20: // 2-wahacz, d<>wignia itp.
|
||
delete fParam;
|
||
break;
|
||
case 0x50: // 5-pantograf
|
||
delete fParamPants;
|
||
break;
|
||
case 0x60: // 6-t<>ok i rozrz<72>d
|
||
break;
|
||
}
|
||
};
|
||
void TAnim::Parovoz(){
|
||
// animowanie t<>oka i rozrz<72>du parowozu
|
||
};
|
||
//---------------------------------------------------------------------------
|
||
TDynamicObject * TDynamicObject::FirstFind(int &coupler_nr, int cf)
|
||
{ // szukanie skrajnego po<70><6F>czonego pojazdu w pociagu
|
||
// od strony sprzegu (coupler_nr) obiektu (start)
|
||
TDynamicObject *temp = this;
|
||
for (int i = 0; i < 300; i++) // ograniczenie do 300 na wypadek zap<61>tlenia sk<73>adu
|
||
{
|
||
if (!temp)
|
||
return NULL; // Ra: zabezpieczenie przed ewentaulnymi b<><62>dami sprz<72>g<EFBFBD>w
|
||
if ((temp->MoverParameters->Couplers[coupler_nr].CouplingFlag & cf) != cf)
|
||
return temp; // nic nie ma ju<6A> dalej pod<6F><64>czone sprz<72>giem cf
|
||
if (coupler_nr == 0)
|
||
{ // je<6A>eli szukamy od sprz<72>gu 0
|
||
if (temp->PrevConnected) // je<6A>li mamy co<63> z przodu
|
||
{
|
||
if (temp->PrevConnectedNo == 0) // je<6A>li pojazd od strony sprz<72>gu 0 jest odwr<77>cony
|
||
coupler_nr = 1 - coupler_nr; // to zmieniamy kierunek sprz<72>gu
|
||
temp = temp->PrevConnected; // ten jest od strony 0
|
||
}
|
||
else
|
||
return temp; // je<6A>li jednak z przodu nic nie ma
|
||
}
|
||
else
|
||
{
|
||
if (temp->NextConnected)
|
||
{
|
||
if (temp->NextConnectedNo == 1) // je<6A>li pojazd od strony sprz<72>gu 1 jest odwr<77>cony
|
||
coupler_nr = 1 - coupler_nr; // to zmieniamy kierunek sprz<72>gu
|
||
temp = temp->NextConnected; // ten pojazd jest od strony 1
|
||
}
|
||
else
|
||
return temp; // je<6A>li jednak z ty<74>u nic nie ma
|
||
}
|
||
}
|
||
return NULL; // to tylko po wyczerpaniu p<>tli
|
||
};
|
||
|
||
//---------------------------------------------------------------------------
|
||
float TDynamicObject::GetEPP()
|
||
{ // szukanie skrajnego po<70><6F>czonego pojazdu w
|
||
// pociagu
|
||
// od strony sprzegu (coupler_nr) obiektu (start)
|
||
TDynamicObject *temp = this;
|
||
int coupler_nr = 0;
|
||
float eq = 0, am = 0;
|
||
|
||
for (int i = 0; i < 300; i++) // ograniczenie do 300 na wypadek zap<61>tlenia sk<73>adu
|
||
{
|
||
if (!temp)
|
||
break; // Ra: zabezpieczenie przed ewentaulnymi b<><62>dami sprz<72>g<EFBFBD>w
|
||
eq += temp->MoverParameters->PipePress * temp->MoverParameters->Dim.L;
|
||
am += temp->MoverParameters->Dim.L;
|
||
if ((temp->MoverParameters->Couplers[coupler_nr].CouplingFlag & 2) != 2)
|
||
break; // nic nie ma ju<6A> dalej pod<6F><64>czone
|
||
if (coupler_nr == 0)
|
||
{ // je<6A>eli szukamy od sprz<72>gu 0
|
||
if (temp->PrevConnected) // je<6A>li mamy co<63> z przodu
|
||
{
|
||
if (temp->PrevConnectedNo == 0) // je<6A>li pojazd od strony sprz<72>gu 0 jest odwr<77>cony
|
||
coupler_nr = 1 - coupler_nr; // to zmieniamy kierunek sprz<72>gu
|
||
temp = temp->PrevConnected; // ten jest od strony 0
|
||
}
|
||
else
|
||
break; // je<6A>li jednak z przodu nic nie ma
|
||
}
|
||
else
|
||
{
|
||
if (temp->NextConnected)
|
||
{
|
||
if (temp->NextConnectedNo == 1) // je<6A>li pojazd od strony sprz<72>gu 1 jest odwr<77>cony
|
||
coupler_nr = 1 - coupler_nr; // to zmieniamy kierunek sprz<72>gu
|
||
temp = temp->NextConnected; // ten pojazd jest od strony 1
|
||
}
|
||
else
|
||
break; // je<6A>li jednak z ty<74>u nic nie ma
|
||
}
|
||
}
|
||
|
||
temp = this;
|
||
coupler_nr = 1;
|
||
for (int i = 0; i < 300; i++) // ograniczenie do 300 na wypadek zap<61>tlenia sk<73>adu
|
||
{
|
||
if (!temp)
|
||
break; // Ra: zabezpieczenie przed ewentaulnymi b<><62>dami sprz<72>g<EFBFBD>w
|
||
eq += temp->MoverParameters->PipePress * temp->MoverParameters->Dim.L;
|
||
am += temp->MoverParameters->Dim.L;
|
||
if ((temp->MoverParameters->Couplers[coupler_nr].CouplingFlag & 2) != 2)
|
||
break; // nic nie ma ju<6A> dalej pod<6F><64>czone
|
||
if (coupler_nr == 0)
|
||
{ // je<6A>eli szukamy od sprz<72>gu 0
|
||
if (temp->PrevConnected) // je<6A>li mamy co<63> z przodu
|
||
{
|
||
if (temp->PrevConnectedNo == 0) // je<6A>li pojazd od strony sprz<72>gu 0 jest odwr<77>cony
|
||
coupler_nr = 1 - coupler_nr; // to zmieniamy kierunek sprz<72>gu
|
||
temp = temp->PrevConnected; // ten jest od strony 0
|
||
}
|
||
else
|
||
break; // je<6A>li jednak z przodu nic nie ma
|
||
}
|
||
else
|
||
{
|
||
if (temp->NextConnected)
|
||
{
|
||
if (temp->NextConnectedNo == 1) // je<6A>li pojazd od strony sprz<72>gu 1 jest odwr<77>cony
|
||
coupler_nr = 1 - coupler_nr; // to zmieniamy kierunek sprz<72>gu
|
||
temp = temp->NextConnected; // ten pojazd jest od strony 1
|
||
}
|
||
else
|
||
break; // je<6A>li jednak z ty<74>u nic nie ma
|
||
}
|
||
}
|
||
eq -= MoverParameters->PipePress * MoverParameters->Dim.L;
|
||
am -= MoverParameters->Dim.L;
|
||
return eq / am;
|
||
};
|
||
|
||
//---------------------------------------------------------------------------
|
||
TDynamicObject * TDynamicObject::GetFirstDynamic(int cpl_type, int cf)
|
||
{ // Szukanie skrajnego po<70><6F>czonego pojazdu w pociagu
|
||
// od strony sprzegu (cpl_type) obiektu szukajacego
|
||
// Ra: wystarczy jedna funkcja do szukania w obu kierunkach
|
||
return FirstFind(cpl_type, cf); // u<>ywa referencji
|
||
};
|
||
|
||
/*
|
||
TDynamicObject* TDynamicObject::GetFirstCabDynamic(int cpl_type)
|
||
{//ZiomalCl: szukanie skrajnego obiektu z kabin<69>
|
||
TDynamicObject* temp=this;
|
||
int coupler_nr=cpl_type;
|
||
for (int i=0;i<300;i++) //ograniczenie do 300 na wypadek zap<61>tlenia sk<73>adu
|
||
{
|
||
if (!temp)
|
||
return NULL; //Ra: zabezpieczenie przed ewentaulnymi b<><62>dami sprz<72>g<EFBFBD>w
|
||
if (temp->MoverParameters->CabNo!=0&&temp->MoverParameters->SandCapacity!=0)
|
||
return temp; //nic nie ma ju<6A> dalej pod<6F><64>czone
|
||
if (temp->MoverParameters->Couplers[coupler_nr].CouplingFlag==0)
|
||
return NULL;
|
||
if (coupler_nr==0)
|
||
{//je<6A>eli szukamy od sprz<72>gu 0
|
||
if (temp->PrevConnectedNo==0) //je<6A>li pojazd od strony sprz<72>gu 0 jest
|
||
odwr<EFBFBD>cony
|
||
coupler_nr=1-coupler_nr; //to zmieniamy kierunek sprz<72>gu
|
||
if (temp->PrevConnected)
|
||
temp=temp->PrevConnected; //ten jest od strony 0
|
||
}
|
||
else
|
||
{
|
||
if (temp->NextConnectedNo==1) //je<6A>li pojazd od strony sprz<72>gu 1 jest
|
||
odwr<EFBFBD>cony
|
||
coupler_nr=1-coupler_nr; //to zmieniamy kierunek sprz<72>gu
|
||
if (temp->NextConnected)
|
||
temp=temp->NextConnected; //ten pojazd jest od strony 1
|
||
}
|
||
}
|
||
return NULL; //to tylko po wyczerpaniu p<>tli
|
||
};
|
||
*/
|
||
|
||
void TDynamicObject::ABuSetModelShake(vector3 mShake)
|
||
{
|
||
modelShake = mShake;
|
||
};
|
||
|
||
int TDynamicObject::GetPneumatic(bool front, bool red)
|
||
{
|
||
int x, y, z; // 1=prosty, 2=sko<6B>ny
|
||
if (red)
|
||
{
|
||
if (front)
|
||
{
|
||
x = btCPneumatic1.GetStatus();
|
||
y = btCPneumatic1r.GetStatus();
|
||
}
|
||
else
|
||
{
|
||
x = btCPneumatic2.GetStatus();
|
||
y = btCPneumatic2r.GetStatus();
|
||
}
|
||
}
|
||
else if (front)
|
||
{
|
||
x = btPneumatic1.GetStatus();
|
||
y = btPneumatic1r.GetStatus();
|
||
}
|
||
else
|
||
{
|
||
x = btPneumatic2.GetStatus();
|
||
y = btPneumatic2r.GetStatus();
|
||
}
|
||
z = 0; // brak w<><77>y?
|
||
if ((x == 1) && (y == 1))
|
||
z = 3; // dwa proste
|
||
if ((x == 2) && (y == 0))
|
||
z = 1; // lewy sko<6B>ny, brak prawego
|
||
if ((x == 0) && (y == 2))
|
||
z = 2; // brak lewego, prawy sko<6B>ny
|
||
|
||
return z;
|
||
}
|
||
|
||
void TDynamicObject::SetPneumatic(bool front, bool red)
|
||
{
|
||
int x = 0,
|
||
ten = 0,
|
||
tamten = 0;
|
||
ten = GetPneumatic(front, red); // 1=lewy skos,2=prawy skos,3=dwa proste
|
||
if (front)
|
||
if (PrevConnected) // pojazd od strony sprz<72>gu 0
|
||
tamten = PrevConnected->GetPneumatic((PrevConnectedNo == 0 ? true : false), red);
|
||
if (!front)
|
||
if (NextConnected) // pojazd od strony sprz<72>gu 1
|
||
tamten = NextConnected->GetPneumatic((NextConnectedNo == 0 ? true : false), red);
|
||
if (ten == tamten) // je<6A>li uk<75>ad jest symetryczny
|
||
switch (ten)
|
||
{
|
||
case 1:
|
||
x = 2;
|
||
break; // mamy lewy skos, da<64> lewe skosy
|
||
case 2:
|
||
x = 3;
|
||
break; // mamy prawy skos, da<64> prawe skosy
|
||
case 3: // wszystkie cztery na prosto
|
||
if (MoverParameters->Couplers[front ? 0 : 1].Render)
|
||
x = 1;
|
||
else
|
||
x = 4;
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
if (ten == 2)
|
||
x = 4;
|
||
if (ten == 1)
|
||
x = 1;
|
||
if (ten == 3)
|
||
if (tamten == 1)
|
||
x = 4;
|
||
else
|
||
x = 1;
|
||
}
|
||
if (front)
|
||
{
|
||
if (red)
|
||
cp1 = x;
|
||
else
|
||
sp1 = x;
|
||
} // kt<6B>ry pokazywa<77> z przodu
|
||
else
|
||
{
|
||
if (red)
|
||
cp2 = x;
|
||
else
|
||
sp2 = x;
|
||
} // kt<6B>ry pokazywa<77> z ty<74>u
|
||
}
|
||
|
||
void TDynamicObject::UpdateAxle(TAnim *pAnim)
|
||
{ // animacja osi
|
||
pAnim->smAnimated->SetRotate(float3(1, 0, 0), *pAnim->dWheelAngle);
|
||
};
|
||
|
||
void TDynamicObject::UpdateBoogie(TAnim *pAnim)
|
||
{ // animacja w<>zka
|
||
pAnim->smAnimated->SetRotate(float3(1, 0, 0), *pAnim->dWheelAngle);
|
||
};
|
||
|
||
void TDynamicObject::UpdateDoorTranslate(TAnim *pAnim)
|
||
{ // animacja drzwi - przesuw
|
||
// WriteLog("Dla drzwi nr:", i);
|
||
// WriteLog("Wspolczynnik", DoorSpeedFactor[i]);
|
||
// Ra: te wsp<73><70>czynniki s<> bez sensu, bo modyfikuj<75> wektor przesuni<6E>cia
|
||
// w efekcie drzwi otwierane na zewn<77>trz b<>d<EFBFBD> odlatywac dowolnie daleko :)
|
||
// ograniczy<7A>em zakres ruchu funkcj<63> max
|
||
if (pAnim->smAnimated)
|
||
{
|
||
if (pAnim->iNumber & 1)
|
||
pAnim->smAnimated->SetTranslate(
|
||
vector3(0, 0, Min0R(dDoorMoveR * pAnim->fSpeed, dDoorMoveR)));
|
||
else
|
||
pAnim->smAnimated->SetTranslate(
|
||
vector3(0, 0, Min0R(dDoorMoveL * pAnim->fSpeed, dDoorMoveL)));
|
||
}
|
||
};
|
||
|
||
void TDynamicObject::UpdateDoorRotate(TAnim *pAnim)
|
||
{ // animacja drzwi - obr<62>t
|
||
if (pAnim->smAnimated)
|
||
{ // if (MoverParameters->DoorOpenMethod==2) //obrotowe
|
||
// albo dw<64>j<EFBFBD>omne (trzeba kombinowac
|
||
// submodelami i ShiftL=90,R=180)
|
||
if (pAnim->iNumber & 1)
|
||
pAnim->smAnimated->SetRotate(float3(1, 0, 0), dDoorMoveR);
|
||
else
|
||
pAnim->smAnimated->SetRotate(float3(1, 0, 0), dDoorMoveL);
|
||
}
|
||
};
|
||
|
||
void TDynamicObject::UpdateDoorFold(TAnim *pAnim)
|
||
{ // animacja drzwi - obr<62>t
|
||
if (pAnim->smAnimated)
|
||
{ // if (MoverParameters->DoorOpenMethod==2) //obrotowe
|
||
// albo dw<64>j<EFBFBD>omne (trzeba kombinowac
|
||
// submodelami i ShiftL=90,R=180)
|
||
if (pAnim->iNumber & 1)
|
||
{
|
||
pAnim->smAnimated->SetRotate(float3(0, 0, 1), dDoorMoveR);
|
||
TSubModel *sm = pAnim->smAnimated->ChildGet(); // skrzyd<79>o mniejsze
|
||
if (sm)
|
||
{
|
||
sm->SetRotate(float3(0, 0, 1), -dDoorMoveR - dDoorMoveR); // skrzyd<79>o wi<77>ksze
|
||
sm = sm->ChildGet();
|
||
if (sm)
|
||
sm->SetRotate(float3(0, 1, 0), dDoorMoveR); // podn<64><6E>ek?
|
||
}
|
||
}
|
||
else
|
||
{
|
||
pAnim->smAnimated->SetRotate(float3(0, 0, 1), dDoorMoveL);
|
||
// SubModel->SetRotate(float3(0,1,0),fValue*360.0);
|
||
TSubModel *sm = pAnim->smAnimated->ChildGet(); // skrzyd<79>o mniejsze
|
||
if (sm)
|
||
{
|
||
sm->SetRotate(float3(0, 0, 1), -dDoorMoveL - dDoorMoveL); // skrzyd<79>o wi<77>ksze
|
||
sm = sm->ChildGet();
|
||
if (sm)
|
||
sm->SetRotate(float3(0, 1, 0), dDoorMoveL); // podn<64><6E>ek?
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
void TDynamicObject::UpdatePant(TAnim *pAnim)
|
||
{ // animacja pantografu - 4 obracane ramiona, <20>lizg pi<70>ty
|
||
float a, b, c;
|
||
a = RadToDeg(pAnim->fParamPants->fAngleL - pAnim->fParamPants->fAngleL0);
|
||
b = RadToDeg(pAnim->fParamPants->fAngleU - pAnim->fParamPants->fAngleU0);
|
||
c = a + b;
|
||
if (pAnim->smElement[0])
|
||
pAnim->smElement[0]->SetRotate(float3(-1, 0, 0), a); // dolne rami<6D>
|
||
if (pAnim->smElement[1])
|
||
pAnim->smElement[1]->SetRotate(float3(1, 0, 0), a);
|
||
if (pAnim->smElement[2])
|
||
pAnim->smElement[2]->SetRotate(float3(1, 0, 0), c); // g<>rne rami<6D>
|
||
if (pAnim->smElement[3])
|
||
pAnim->smElement[3]->SetRotate(float3(-1, 0, 0), c);
|
||
if (pAnim->smElement[4])
|
||
pAnim->smElement[4]->SetRotate(float3(-1, 0, 0), b); //<2F>lizg
|
||
};
|
||
|
||
void TDynamicObject::UpdateDoorPlug(TAnim *pAnim)
|
||
{ // animacja drzwi - odskokprzesuw
|
||
if (pAnim->smAnimated)
|
||
{
|
||
if (pAnim->iNumber & 1)
|
||
pAnim->smAnimated->SetTranslate(
|
||
vector3(Min0R(dDoorMoveR * 2, MoverParameters->DoorMaxPlugShift), 0,
|
||
Max0R(0, Min0R(dDoorMoveR * pAnim->fSpeed, dDoorMoveR) -
|
||
MoverParameters->DoorMaxPlugShift * 0.5f)));
|
||
else
|
||
pAnim->smAnimated->SetTranslate(
|
||
vector3(Min0R(dDoorMoveL * 2, MoverParameters->DoorMaxPlugShift), 0,
|
||
Max0R(0, Min0R(dDoorMoveL * pAnim->fSpeed, dDoorMoveL) -
|
||
MoverParameters->DoorMaxPlugShift * 0.5f)));
|
||
}
|
||
};
|
||
|
||
void TDynamicObject::UpdateLeverDouble(TAnim *pAnim)
|
||
{ // animacja ga<67>ki zale<6C>na od double
|
||
pAnim->smAnimated->SetRotate(float3(1, 0, 0), pAnim->fSpeed * *pAnim->fDoubleBase);
|
||
};
|
||
void TDynamicObject::UpdateLeverFloat(TAnim *pAnim)
|
||
{ // animacja ga<67>ki zale<6C>na od float
|
||
pAnim->smAnimated->SetRotate(float3(1, 0, 0), pAnim->fSpeed * *pAnim->fFloatBase);
|
||
};
|
||
void TDynamicObject::UpdateLeverInt(TAnim *pAnim)
|
||
{ // animacja ga<67>ki zale<6C>na od int
|
||
pAnim->smAnimated->SetRotate(float3(1, 0, 0), pAnim->fSpeed * *pAnim->iIntBase);
|
||
};
|
||
void TDynamicObject::UpdateLeverEnum(TAnim *pAnim)
|
||
{ // ustawienie k<>ta na
|
||
// warto<74><6F> wskazan<61> przez
|
||
// int z tablicy fParam
|
||
// pAnim->fParam[0]; - doda<64> lepko<6B><6F>
|
||
pAnim->smAnimated->SetRotate(float3(1, 0, 0), pAnim->fParam[*pAnim->iIntBase]);
|
||
};
|
||
|
||
// ABu 29.01.05 przeklejone z render i renderalpha: *********************
|
||
void __inline TDynamicObject::ABuLittleUpdate(double ObjSqrDist)
|
||
{ // ABu290105: pozbierane i uporzadkowane powtarzajace
|
||
// sie rzeczy z Render i RenderAlpha
|
||
// dodatkowy warunek, if (ObjSqrDist<...) zeby niepotrzebnie nie zmianiec w
|
||
// obiektach,
|
||
// ktorych i tak nie widac
|
||
// NBMX wrzesien, MC listopad: zuniwersalnione
|
||
btnOn = false; // czy przywr<77>ci<63> stan domy<6D>lny po renderowaniu
|
||
|
||
if (mdLoad) // tymczasowo <20>adunek na poziom pod<6F>ogi
|
||
if (vFloor.z > 0.0)
|
||
mdLoad->GetSMRoot()->SetTranslate(modelShake + vFloor);
|
||
|
||
if (ObjSqrDist < 160000) // gdy bli<6C>ej ni<6E> 400m
|
||
{
|
||
for (int i = 0; i < iAnimations; ++i) // wykonanie kolejnych animacji
|
||
if (ObjSqrDist < pAnimations[i].fMaxDist)
|
||
if (pAnimations[i].yUpdate) // je<6A>li zdefiniowana funkcja
|
||
pAnimations[i].yUpdate(pAnimations +
|
||
i); // aktualizacja animacji (po<70>o<EFBFBD>enia submodeli
|
||
if (ObjSqrDist < 2500) // gdy bli<6C>ej ni<6E> 50m
|
||
{
|
||
// ABu290105: rzucanie pudlem
|
||
// te animacje wymagaj<61> banan<61>w w modelach!
|
||
mdModel->GetSMRoot()->SetTranslate(modelShake);
|
||
if (mdKabina)
|
||
mdKabina->GetSMRoot()->SetTranslate(modelShake);
|
||
if (mdLoad)
|
||
mdLoad->GetSMRoot()->SetTranslate(modelShake + vFloor);
|
||
if (mdLowPolyInt)
|
||
mdLowPolyInt->GetSMRoot()->SetTranslate(modelShake);
|
||
if (mdPrzedsionek)
|
||
mdPrzedsionek->GetSMRoot()->SetTranslate(modelShake);
|
||
// ABu: koniec rzucania
|
||
// ABu011104: liczenie obrotow wozkow
|
||
ABuBogies();
|
||
// Mczapkie-100402: rysowanie lub nie - sprzegow
|
||
// ABu-240105: Dodatkowy warunek: if (...).Render, zeby rysowal tylko
|
||
// jeden
|
||
// z polaczonych sprzegow
|
||
if ((TestFlag(MoverParameters->Couplers[0].CouplingFlag, ctrain_coupler)) &&
|
||
(MoverParameters->Couplers[0].Render))
|
||
{
|
||
btCoupler1.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btCoupler1.TurnOff();
|
||
if ((TestFlag(MoverParameters->Couplers[1].CouplingFlag, ctrain_coupler)) &&
|
||
(MoverParameters->Couplers[1].Render))
|
||
{
|
||
btCoupler2.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btCoupler2.TurnOff();
|
||
//********************************************************************************
|
||
// przewody powietrzne j.w., ABu: decyzja czy rysowac tylko na podstawie
|
||
// 'render' - juz
|
||
// nie
|
||
// przewody powietrzne, yB: decyzja na podstawie polaczen w t3d
|
||
if (Global::bnewAirCouplers)
|
||
{
|
||
SetPneumatic(false, false); // wczytywanie z t3d ulozenia wezykow
|
||
SetPneumatic(true, false); // i zapisywanie do zmiennej
|
||
SetPneumatic(true, true); // ktore z nich nalezy
|
||
SetPneumatic(false, true); // wyswietlic w tej klatce
|
||
|
||
if (TestFlag(MoverParameters->Couplers[0].CouplingFlag, ctrain_pneumatic))
|
||
{
|
||
switch (cp1)
|
||
{
|
||
case 1:
|
||
btCPneumatic1.TurnOn();
|
||
break;
|
||
case 2:
|
||
btCPneumatic1.TurnxOn();
|
||
break;
|
||
case 3:
|
||
btCPneumatic1r.TurnxOn();
|
||
break;
|
||
case 4:
|
||
btCPneumatic1r.TurnOn();
|
||
break;
|
||
}
|
||
btnOn = true;
|
||
}
|
||
// else
|
||
//{
|
||
// btCPneumatic1.TurnOff();
|
||
// btCPneumatic1r.TurnOff();
|
||
//}
|
||
|
||
if (TestFlag(MoverParameters->Couplers[1].CouplingFlag, ctrain_pneumatic))
|
||
{
|
||
switch (cp2)
|
||
{
|
||
case 1:
|
||
btCPneumatic2.TurnOn();
|
||
break;
|
||
case 2:
|
||
btCPneumatic2.TurnxOn();
|
||
break;
|
||
case 3:
|
||
btCPneumatic2r.TurnxOn();
|
||
break;
|
||
case 4:
|
||
btCPneumatic2r.TurnOn();
|
||
break;
|
||
}
|
||
btnOn = true;
|
||
}
|
||
// else
|
||
//{
|
||
// btCPneumatic2.TurnOff();
|
||
// btCPneumatic2r.TurnOff();
|
||
//}
|
||
|
||
// przewody zasilajace, j.w. (yB)
|
||
if (TestFlag(MoverParameters->Couplers[0].CouplingFlag, ctrain_scndpneumatic))
|
||
{
|
||
switch (sp1)
|
||
{
|
||
case 1:
|
||
btPneumatic1.TurnOn();
|
||
break;
|
||
case 2:
|
||
btPneumatic1.TurnxOn();
|
||
break;
|
||
case 3:
|
||
btPneumatic1r.TurnxOn();
|
||
break;
|
||
case 4:
|
||
btPneumatic1r.TurnOn();
|
||
break;
|
||
}
|
||
btnOn = true;
|
||
}
|
||
// else
|
||
//{
|
||
// btPneumatic1.TurnOff();
|
||
// btPneumatic1r.TurnOff();
|
||
//}
|
||
|
||
if (TestFlag(MoverParameters->Couplers[1].CouplingFlag, ctrain_scndpneumatic))
|
||
{
|
||
switch (sp2)
|
||
{
|
||
case 1:
|
||
btPneumatic2.TurnOn();
|
||
break;
|
||
case 2:
|
||
btPneumatic2.TurnxOn();
|
||
break;
|
||
case 3:
|
||
btPneumatic2r.TurnxOn();
|
||
break;
|
||
case 4:
|
||
btPneumatic2r.TurnOn();
|
||
break;
|
||
}
|
||
btnOn = true;
|
||
}
|
||
// else
|
||
//{
|
||
// btPneumatic2.TurnOff();
|
||
// btPneumatic2r.TurnOff();
|
||
//}
|
||
}
|
||
//*********************************************************************************/
|
||
else // po staremu ABu'oewmu
|
||
{
|
||
// przewody powietrzne j.w., ABu: decyzja czy rysowac tylko na podstawie
|
||
// 'render'
|
||
if (TestFlag(MoverParameters->Couplers[0].CouplingFlag, ctrain_pneumatic))
|
||
{
|
||
if (MoverParameters->Couplers[0].Render)
|
||
btCPneumatic1.TurnOn();
|
||
else
|
||
btCPneumatic1r.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else
|
||
//{
|
||
// btCPneumatic1.TurnOff();
|
||
// btCPneumatic1r.TurnOff();
|
||
//}
|
||
|
||
if (TestFlag(MoverParameters->Couplers[1].CouplingFlag, ctrain_pneumatic))
|
||
{
|
||
if (MoverParameters->Couplers[1].Render)
|
||
btCPneumatic2.TurnOn();
|
||
else
|
||
btCPneumatic2r.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else
|
||
//{
|
||
// btCPneumatic2.TurnOff();
|
||
// btCPneumatic2r.TurnOff();
|
||
//}
|
||
|
||
// przewody powietrzne j.w., ABu: decyzja czy rysowac tylko na podstawie
|
||
// 'render'
|
||
// //yB - zasilajace
|
||
if (TestFlag(MoverParameters->Couplers[0].CouplingFlag, ctrain_scndpneumatic))
|
||
{
|
||
if (MoverParameters->Couplers[0].Render)
|
||
btPneumatic1.TurnOn();
|
||
else
|
||
btPneumatic1r.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else
|
||
//{
|
||
// btPneumatic1.TurnOff();
|
||
// btPneumatic1r.TurnOff();
|
||
//}
|
||
|
||
if (TestFlag(MoverParameters->Couplers[1].CouplingFlag, ctrain_scndpneumatic))
|
||
{
|
||
if (MoverParameters->Couplers[1].Render)
|
||
btPneumatic2.TurnOn();
|
||
else
|
||
btPneumatic2r.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else
|
||
//{
|
||
// btPneumatic2.TurnOff();
|
||
// btPneumatic2r.TurnOff();
|
||
//}
|
||
}
|
||
//*************************************************************/// koniec
|
||
// wezykow
|
||
// uginanie zderzakow
|
||
for (int i = 0; i < 2; i++)
|
||
{
|
||
double dist = MoverParameters->Couplers[i].Dist / 2.0;
|
||
if (smBuforLewy[i])
|
||
if (dist < 0)
|
||
smBuforLewy[i]->SetTranslate(vector3(dist, 0, 0));
|
||
if (smBuforPrawy[i])
|
||
if (dist < 0)
|
||
smBuforPrawy[i]->SetTranslate(vector3(dist, 0, 0));
|
||
}
|
||
}
|
||
|
||
// Winger 160204 - podnoszenie pantografow
|
||
|
||
// przewody sterowania ukrotnionego
|
||
if (TestFlag(MoverParameters->Couplers[0].CouplingFlag, ctrain_controll))
|
||
{
|
||
btCCtrl1.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btCCtrl1.TurnOff();
|
||
if (TestFlag(MoverParameters->Couplers[1].CouplingFlag, ctrain_controll))
|
||
{
|
||
btCCtrl2.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btCCtrl2.TurnOff();
|
||
// McZapkie-181103: mostki przejsciowe
|
||
if (TestFlag(MoverParameters->Couplers[0].CouplingFlag, ctrain_passenger))
|
||
{
|
||
btCPass1.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btCPass1.TurnOff();
|
||
if (TestFlag(MoverParameters->Couplers[1].CouplingFlag, ctrain_passenger))
|
||
{
|
||
btCPass2.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btCPass2.TurnOff();
|
||
if (MoverParameters->Battery)
|
||
{ // sygnaly konca pociagu
|
||
if (btEndSignals1.Active())
|
||
{
|
||
if (TestFlag(iLights[0], 2) || TestFlag(iLights[0], 32))
|
||
{
|
||
btEndSignals1.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btEndSignals1.TurnOff();
|
||
}
|
||
else
|
||
{
|
||
if (TestFlag(iLights[0], 2))
|
||
{
|
||
btEndSignals11.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btEndSignals11.TurnOff();
|
||
if (TestFlag(iLights[0], 32))
|
||
{
|
||
btEndSignals13.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btEndSignals13.TurnOff();
|
||
}
|
||
if (btEndSignals2.Active())
|
||
{
|
||
if (TestFlag(iLights[1], 2) || TestFlag(iLights[1], 32))
|
||
{
|
||
btEndSignals2.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btEndSignals2.TurnOff();
|
||
}
|
||
else
|
||
{
|
||
if (TestFlag(iLights[1], 2))
|
||
{
|
||
btEndSignals21.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btEndSignals21.TurnOff();
|
||
if (TestFlag(iLights[1], 32))
|
||
{
|
||
btEndSignals23.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btEndSignals23.TurnOff();
|
||
}
|
||
}
|
||
// tablice blaszane:
|
||
if (TestFlag(iLights[0], 64))
|
||
{
|
||
btEndSignalsTab1.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btEndSignalsTab1.TurnOff();
|
||
if (TestFlag(iLights[1], 64))
|
||
{
|
||
btEndSignalsTab2.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btEndSignalsTab2.TurnOff();
|
||
// McZapkie-181002: krecenie wahaczem (korzysta z kata obrotu silnika)
|
||
if (iAnimType[ANIM_LEVERS])
|
||
for (int i = 0; i < 4; ++i)
|
||
if (smWahacze[i])
|
||
smWahacze[i]->SetRotate(float3(1, 0, 0),
|
||
fWahaczeAmp * cos(MoverParameters->eAngle));
|
||
|
||
if (Mechanik)
|
||
{ // rysowanie figurki mechanika
|
||
/*
|
||
if (smMechanik0) // mechanik od strony sprz<72>gu 0
|
||
if (smMechanik1) // jak jest drugi, to pierwszego jedynie pokazujemy
|
||
smMechanik0->iVisible = MoverParameters->ActiveCab > 0;
|
||
else
|
||
{ // jak jest tylko jeden, to do drugiej kabiny go obracamy
|
||
smMechanik0->iVisible = (MoverParameters->ActiveCab != 0);
|
||
smMechanik0->SetRotate(
|
||
float3(0, 0, 1),
|
||
MoverParameters->ActiveCab >= 0 ? 0 : 180); // obr<62>t wzgl<67>dem osi Z
|
||
}
|
||
if (smMechanik1) // mechanik od strony sprz<72>gu 1
|
||
smMechanik1->iVisible = MoverParameters->ActiveCab < 0;
|
||
*/
|
||
if (MoverParameters->ActiveCab > 0)
|
||
{
|
||
btMechanik1.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
if (MoverParameters->ActiveCab < 0)
|
||
{
|
||
btMechanik2.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
}
|
||
// ABu: Przechyly na zakretach
|
||
// Ra: przechy<68>k<EFBFBD> za<7A>atwiamy na etapie przesuwania modelu
|
||
// if (ObjSqrDist<80000) ABuModelRoll(); //przechy<68>ki od 400m
|
||
}
|
||
if (MoverParameters->Battery)
|
||
{ // sygna<6E>y czo<7A>a pociagu //Ra: wy<77>wietlamy bez
|
||
// ogranicze<7A> odleg<65>o<EFBFBD>ci, by by<62>y widoczne z
|
||
// daleka
|
||
if (TestFlag(iLights[0], 1))
|
||
{
|
||
btHeadSignals11.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btHeadSignals11.TurnOff();
|
||
if (TestFlag(iLights[0], 4))
|
||
{
|
||
btHeadSignals12.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btHeadSignals12.TurnOff();
|
||
if (TestFlag(iLights[0], 16))
|
||
{
|
||
btHeadSignals13.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btHeadSignals13.TurnOff();
|
||
if (TestFlag(iLights[1], 1))
|
||
{
|
||
btHeadSignals21.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btHeadSignals21.TurnOff();
|
||
if (TestFlag(iLights[1], 4))
|
||
{
|
||
btHeadSignals22.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btHeadSignals22.TurnOff();
|
||
if (TestFlag(iLights[1], 16))
|
||
{
|
||
btHeadSignals23.TurnOn();
|
||
btnOn = true;
|
||
}
|
||
// else btHeadSignals23.TurnOff();
|
||
}
|
||
}
|
||
// ABu 29.01.05 koniec przeklejenia *************************************
|
||
|
||
double ABuAcos(const vector3 &calc_temp)
|
||
{ // Odpowiednik funkcji Arccos, bo cos
|
||
// mi tam nie dzialalo.
|
||
return atan2(-calc_temp.x, calc_temp.z); // Ra: tak pro<72>ciej
|
||
}
|
||
|
||
TDynamicObject * TDynamicObject::ABuFindNearestObject(TTrack *Track,
|
||
TDynamicObject *MyPointer,
|
||
int &CouplNr)
|
||
{ // zwraca wskaznik do obiektu znajdujacego sie na torze
|
||
// (Track), kt<6B>rego sprz<72>g jest najblizszy
|
||
// kamerze
|
||
// s<>u<EFBFBD>y np. do <20><>czenia i rozpinania sprz<72>g<EFBFBD>w
|
||
// WE: Track - tor, na ktorym odbywa sie poszukiwanie
|
||
// MyPointer - wskaznik do obiektu szukajacego
|
||
// WY: CouplNr - kt<6B>ry sprz<72>g znalezionego obiektu jest bli<6C>szy kamerze
|
||
|
||
// Uwaga! Jesli CouplNr==-2 to szukamy njblizszego obiektu, a nie sprzegu!!!
|
||
|
||
if ((Track->iNumDynamics) > 0)
|
||
{ // o ile w og<6F>le jest co przegl<67>da<64> na tym torze
|
||
// vector3 poz; //pozycja pojazdu XYZ w scenerii
|
||
// vector3 kon; //wektor czo<7A>a wzgl<67>dem <20>rodka pojazdu wzgl<67>em pocz<63>tku toru
|
||
vector3 tmp; // wektor pomi<6D>dzy kamer<65> i sprz<72>giem
|
||
double dist; // odleg<65>o<EFBFBD><6F>
|
||
for (int i = 0; i < Track->iNumDynamics; i++)
|
||
{
|
||
if (CouplNr == -2)
|
||
{ // wektor [kamera-obiekt] - poszukiwanie obiektu
|
||
tmp = Global::GetCameraPosition() - Track->Dynamics[i]->vPosition;
|
||
dist = tmp.x * tmp.x + tmp.y * tmp.y + tmp.z * tmp.z; // odleg<65>o<EFBFBD><6F> do kwadratu
|
||
if (dist < 100.0) // 10 metr<74>w
|
||
return Track->Dynamics[i];
|
||
}
|
||
else // je<6A>li (CouplNr) inne niz -2, szukamy sprz<72>gu
|
||
{ // wektor [kamera-sprzeg0], potem [kamera-sprzeg1]
|
||
// Powinno byc wyliczone, ale nie zaszkodzi drugi raz:
|
||
//(bo co, jesli nie wykonuje sie obrotow wozkow?) - Ra: ale zawsze s<>
|
||
// liczone
|
||
// wsp<73><70>rz<72>dne sprz<72>g<EFBFBD>w
|
||
// Track->Dynamics[i]->modelRot.z=ABuAcos(Track->Dynamics[i]->Axle0.pPosition-Track->Dynamics[i]->Axle1.pPosition);
|
||
// poz=Track->Dynamics[i]->vPosition; //pozycja <20>rodka pojazdu
|
||
// kon=vector3( //po<70>o<EFBFBD>enie przodu wzgl<67>dem <20>rodka
|
||
// -((0.5*Track->Dynamics[i]->MoverParameters->Dim.L)*sin(Track->Dynamics[i]->modelRot.z)),
|
||
// 0, //yyy... je<6A>li du<64>e pochylenie i d<>ugi pojazd, to mo<6D>e by<62> problem
|
||
// +((0.5*Track->Dynamics[i]->MoverParameters->Dim.L)*cos(Track->Dynamics[i]->modelRot.z))
|
||
//);
|
||
tmp =
|
||
Global::GetCameraPosition() -
|
||
Track->Dynamics[i]->vCoulpler[0]; // Ra: pozycje sprz<72>g<EFBFBD>w te<74> s<> zawsze liczone
|
||
dist = tmp.x * tmp.x + tmp.y * tmp.y + tmp.z * tmp.z; // odleg<65>o<EFBFBD><6F> do kwadratu
|
||
if (dist < 25.0) // 5 metr<74>w
|
||
{
|
||
CouplNr = 0;
|
||
return Track->Dynamics[i];
|
||
}
|
||
tmp = Global::GetCameraPosition() - Track->Dynamics[i]->vCoulpler[1];
|
||
dist = tmp.x * tmp.x + tmp.y * tmp.y + tmp.z * tmp.z; // odleg<65>o<EFBFBD><6F> do kwadratu
|
||
if (dist < 25.0) // 5 metr<74>w
|
||
{
|
||
CouplNr = 1;
|
||
return Track->Dynamics[i];
|
||
}
|
||
}
|
||
}
|
||
return NULL;
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
TDynamicObject * TDynamicObject::ABuScanNearestObject(TTrack *Track, double ScanDir,
|
||
double ScanDist, int &CouplNr)
|
||
{ // skanowanie toru w poszukiwaniu obiektu najblizszego
|
||
// kamerze
|
||
// double MyScanDir=ScanDir; //Moja orientacja na torze. //Ra: nie u<>ywane
|
||
if (ABuGetDirection() < 0)
|
||
ScanDir = -ScanDir;
|
||
TDynamicObject *FoundedObj;
|
||
FoundedObj =
|
||
ABuFindNearestObject(Track, this, CouplNr); // zwraca numer sprz<72>gu znalezionego pojazdu
|
||
if (FoundedObj == NULL)
|
||
{
|
||
double ActDist; // Przeskanowana odleglosc.
|
||
double CurrDist = 0; // Aktualna dlugosc toru.
|
||
if (ScanDir >= 0)
|
||
ActDist =
|
||
Track->Length() - RaTranslationGet(); //???-przesuni<6E>cie w<>zka wzgl<67>dem Point1 toru
|
||
else
|
||
ActDist = RaTranslationGet(); // przesuni<6E>cie w<>zka wzgl<67>dem Point1 toru
|
||
while (ActDist < ScanDist)
|
||
{
|
||
ActDist += CurrDist;
|
||
if (ScanDir > 0) // do przodu
|
||
{
|
||
if (Track->iNextDirection)
|
||
{
|
||
Track = Track->CurrentNext();
|
||
ScanDir = -ScanDir;
|
||
}
|
||
else
|
||
Track = Track->CurrentNext();
|
||
}
|
||
else // do ty<74>u
|
||
{
|
||
if (Track->iPrevDirection)
|
||
Track = Track->CurrentPrev();
|
||
else
|
||
{
|
||
Track = Track->CurrentPrev();
|
||
ScanDir = -ScanDir;
|
||
}
|
||
}
|
||
if (Track != NULL)
|
||
{ // jesli jest kolejny odcinek toru
|
||
CurrDist = Track->Length();
|
||
FoundedObj = ABuFindNearestObject(Track, this, CouplNr);
|
||
if (FoundedObj != NULL)
|
||
ActDist = ScanDist;
|
||
}
|
||
else // Jesli nie ma, to wychodzimy.
|
||
ActDist = ScanDist;
|
||
}
|
||
} // Koniec szukania najblizszego toru z jakims obiektem.
|
||
return FoundedObj;
|
||
}
|
||
|
||
// ABu 01.11.04 poczatek wyliczania przechylow pudla **********************
|
||
void TDynamicObject::ABuModelRoll()
|
||
{ // ustawienie przechy<68>ki pojazdu i jego
|
||
// zawarto<74>ci
|
||
// Ra: przechy<68>k<EFBFBD> za<7A>atwiamy na etapie przesuwania modelu
|
||
}
|
||
|
||
// ABu 06.05.04 poczatek wyliczania obrotow wozkow **********************
|
||
|
||
void TDynamicObject::ABuBogies()
|
||
{ // Obracanie wozkow na zakretach. Na razie
|
||
// uwzgl<67>dnia tylko zakr<6B>ty,
|
||
// bez zadnych gorek i innych przeszkod.
|
||
if ((smBogie[0] != NULL) && (smBogie[1] != NULL))
|
||
{
|
||
// modelRot.z=ABuAcos(Axle0.pPosition-Axle1.pPosition); //k<>t obrotu pojazdu
|
||
// [rad]
|
||
// bogieRot[0].z=ABuAcos(Axle0.pPosition-Axle3.pPosition);
|
||
bogieRot[0].z = Axle0.vAngles.z;
|
||
bogieRot[0] = RadToDeg(modelRot - bogieRot[0]); // mno<6E>enie wektora przez sta<74><61>
|
||
smBogie[0]->SetRotateXYZ(bogieRot[0]);
|
||
// bogieRot[1].z=ABuAcos(Axle2.pPosition-Axle1.pPosition);
|
||
bogieRot[1].z = Axle1.vAngles.z;
|
||
bogieRot[1] = RadToDeg(modelRot - bogieRot[1]);
|
||
smBogie[1]->SetRotateXYZ(bogieRot[1]);
|
||
}
|
||
};
|
||
// ABu 06.05.04 koniec wyliczania obrotow wozkow ************************
|
||
|
||
// ABu 16.03.03 sledzenie toru przed obiektem: **************************
|
||
void TDynamicObject::ABuCheckMyTrack()
|
||
{ // Funkcja przypisujaca obiekt
|
||
// prawidlowej tablicy Dynamics,
|
||
// bo gdzies jest jakis blad i wszystkie obiekty z danego
|
||
// pociagu na poczatku stawiane sa na jednym torze i wpisywane
|
||
// do jednej tablicy. Wykonuje sie tylko raz - po to 'ABuChecked'
|
||
TTrack *OldTrack = MyTrack;
|
||
TTrack *NewTrack = Axle0.GetTrack();
|
||
if ((NewTrack != OldTrack) && OldTrack)
|
||
{
|
||
OldTrack->RemoveDynamicObject(this);
|
||
NewTrack->AddDynamicObject(this);
|
||
}
|
||
iAxleFirst = 0; // pojazd powi<77>zany z przedni<6E> osi<73> - Axle0
|
||
}
|
||
|
||
// Ra: w poni<6E>szej funkcji jest problem ze sprz<72>gami
|
||
TDynamicObject * TDynamicObject::ABuFindObject(TTrack *Track, int ScanDir,
|
||
BYTE &CouplFound, double &dist)
|
||
{ // Zwraca wska<6B>nik najbli<6C>szego obiektu znajduj<75>cego si<73>
|
||
// na torze w okre<72>lonym kierunku, ale tylko wtedy, kiedy
|
||
// obiekty mog<6F> si<73> zderzy<7A>, tzn. nie mijaj<61> si<73>.
|
||
|
||
// WE: Track - tor, na ktorym odbywa sie poszukiwanie,
|
||
// MyPointer - wskaznik do obiektu szukajacego. //Ra: zamieni<6E>em na "this"
|
||
// ScanDir - kierunek szukania na torze (+1:w stron<6F> Point2, -1:w stron<6F>
|
||
// Point1)
|
||
// MyScanDir - kierunek szukania obiektu szukajacego (na jego torze); Ra:
|
||
// nie potrzebne
|
||
// MyCouplFound - nr sprzegu obiektu szukajacego; Ra: nie potrzebne
|
||
|
||
// WY: wskaznik do znalezionego obiektu.
|
||
// CouplFound - nr sprzegu znalezionego obiektu
|
||
if (Track->iNumDynamics > 0)
|
||
{ // sens szukania na tym torze jest tylko, gdy s<> na nim pojazdy
|
||
double ObjTranslation; // pozycja najblizszego obiektu na torze
|
||
double MyTranslation; // pozycja szukaj<61>cego na torze
|
||
double MinDist = Track->Length(); // najmniejsza znaleziona odleglo<6C><6F>
|
||
// (zaczynamy od d<>ugo<67>ci toru)
|
||
double TestDist; // robocza odleg<65>o<EFBFBD><6F> od kolejnych pojazd<7A>w na danym odcinku
|
||
int iMinDist = -1; // indeks wykrytego obiektu
|
||
// if (Track->iNumDynamics>1)
|
||
// iMinDist+=0; //tymczasowo pu<70>apka
|
||
if (MyTrack == Track) // gdy szukanie na tym samym torze
|
||
MyTranslation = RaTranslationGet(); // po<70>o<EFBFBD>enie w<>zka wzgl<67>dem Point1 toru
|
||
else // gdy szukanie na innym torze
|
||
if (ScanDir > 0)
|
||
MyTranslation = 0; // szukanie w kierunku Point2 (od zera) - jeste<74>my w Point1
|
||
else
|
||
MyTranslation = MinDist; // szukanie w kierunku Point1 (do zera) - jeste<74>my w Point2
|
||
if (ScanDir >= 0)
|
||
{ // je<6A>li szukanie w kierunku Point2
|
||
for (int i = 0; i < Track->iNumDynamics; i++)
|
||
{ // p<>tla po pojazdach
|
||
if (Track->Dynamics[i] != this) // szukaj<61>cy si<73> nie liczy
|
||
{
|
||
TestDist = (Track->Dynamics[i]->RaTranslationGet()) -
|
||
MyTranslation; // odleg<65>og<6F>o<EFBFBD><6F> tamtego od szukaj<61>cego
|
||
if ((TestDist > 0) && (TestDist <= MinDist))
|
||
{ // gdy jest po w<>a<EFBFBD>ciwej stronie i bli<6C>ej
|
||
// ni<6E> jaki<6B> wcze<7A>niejszy
|
||
CouplFound = (Track->Dynamics[i]->RaDirectionGet() > 0) ?
|
||
1 :
|
||
0; // to, bo (ScanDir>=0)
|
||
if (Track->iCategoryFlag & 254) // trajektoria innego typu ni<6E> tor kolejowy
|
||
{ // dla tor<6F>w nie ma sensu tego sprawdza<7A>, rzadko co jedzie po
|
||
// jednej
|
||
// szynie i si<73> mija
|
||
// Ra: mijanie samochod<6F>w wcale nie jest proste
|
||
// Przesuniecie wzgledne pojazdow. Wyznaczane, zeby sprawdzic,
|
||
// czy pojazdy faktycznie sie zderzaja (moga byc przesuniete
|
||
// w/m siebie tak, ze nie zachodza na siebie i wtedy sie mijaja).
|
||
double RelOffsetH; // wzajemna odleg<65>o<EFBFBD><6F> poprzeczna
|
||
if (CouplFound) // my na tym torze by<62>my byli w kierunku Point2
|
||
// dla CouplFound=1 s<> zwroty zgodne - istotna r<><72>nica
|
||
// przesuni<6E><69>
|
||
RelOffsetH = (MoverParameters->OffsetTrackH -
|
||
Track->Dynamics[i]->MoverParameters->OffsetTrackH);
|
||
else
|
||
// dla CouplFound=0 s<> zwroty przeciwne - przesuni<6E>cia sumuj<75>
|
||
// si<73>
|
||
RelOffsetH = (MoverParameters->OffsetTrackH +
|
||
Track->Dynamics[i]->MoverParameters->OffsetTrackH);
|
||
if (RelOffsetH < 0)
|
||
RelOffsetH = -RelOffsetH;
|
||
if (RelOffsetH + RelOffsetH >
|
||
MoverParameters->Dim.W + Track->Dynamics[i]->MoverParameters->Dim.W)
|
||
continue; // odleg<65>o<EFBFBD><6F> wi<77>ksza od po<70>owy sumy szeroko<6B>ci -
|
||
// kolizji
|
||
// nie b<>dzie
|
||
// je<6A>li zahaczenie jest niewielkie, a jest miejsce na poboczu, to
|
||
// zjecha<68> na pobocze
|
||
}
|
||
iMinDist = i; // potencjalna kolizja
|
||
MinDist = TestDist; // odleglo<6C><6F> pomi<6D>dzy aktywnymi osiami pojazd<7A>w
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else //(ScanDir<0)
|
||
{
|
||
for (int i = 0; i < Track->iNumDynamics; i++)
|
||
{
|
||
if (Track->Dynamics[i] != this)
|
||
{
|
||
TestDist = MyTranslation -
|
||
(Track->Dynamics[i]->RaTranslationGet()); //???-przesuni<6E>cie w<>zka
|
||
// wzgl<67>dem Point1 toru
|
||
if ((TestDist > 0) && (TestDist < MinDist))
|
||
{
|
||
CouplFound = (Track->Dynamics[i]->RaDirectionGet() > 0) ?
|
||
0 :
|
||
1; // odwrotnie, bo (ScanDir<0)
|
||
if (Track->iCategoryFlag & 254) // trajektoria innego typu ni<6E> tor kolejowy
|
||
{ // dla tor<6F>w nie ma sensu tego sprawdza<7A>, rzadko co jedzie po
|
||
// jednej
|
||
// szynie i si<73> mija
|
||
// Ra: mijanie samochod<6F>w wcale nie jest proste
|
||
// Przesuni<6E>cie wzgl<67>dne pojazd<7A>w. Wyznaczane, <20>eby sprawdzi<7A>,
|
||
// czy pojazdy faktycznie si<73> zderzaj<61> (mog<6F> by<62> przesuni<6E>te
|
||
// w/m siebie tak, <20>e nie zachodz<64> na siebie i wtedy sie mijaj<61>).
|
||
double RelOffsetH; // wzajemna odleg<65>o<EFBFBD><6F> poprzeczna
|
||
if (CouplFound) // my na tym torze by<62>my byli w kierunku Point1
|
||
// dla CouplFound=1 s<> zwroty zgodne - istotna r<><72>nica
|
||
// przesuni<6E><69>
|
||
RelOffsetH = (MoverParameters->OffsetTrackH -
|
||
Track->Dynamics[i]->MoverParameters->OffsetTrackH);
|
||
else
|
||
// dla CouplFound=0 s<> zwroty przeciwne - przesuni<6E>cia sumuj<75>
|
||
// si<73>
|
||
RelOffsetH = (MoverParameters->OffsetTrackH +
|
||
Track->Dynamics[i]->MoverParameters->OffsetTrackH);
|
||
if (RelOffsetH < 0)
|
||
RelOffsetH = -RelOffsetH;
|
||
if (RelOffsetH + RelOffsetH >
|
||
MoverParameters->Dim.W + Track->Dynamics[i]->MoverParameters->Dim.W)
|
||
continue; // odleg<65>o<EFBFBD><6F> wi<77>ksza od po<70>owy sumy szeroko<6B>ci -
|
||
// kolizji
|
||
// nie b<>dzie
|
||
}
|
||
iMinDist = i; // potencjalna kolizja
|
||
MinDist = TestDist; // odleglo<6C><6F> pomi<6D>dzy aktywnymi osiami pojazd<7A>w
|
||
}
|
||
}
|
||
}
|
||
}
|
||
dist += MinDist; // doliczenie odleg<65>o<EFBFBD>ci przeszkody albo d<>ugo<67>ci odcinka
|
||
// do przeskanowanej
|
||
// odleg<65>o<EFBFBD>ci
|
||
return (iMinDist >= 0) ? Track->Dynamics[iMinDist] : NULL;
|
||
}
|
||
dist += Track->Length(); // doliczenie d<>ugo<67>ci odcinka do przeskanowanej
|
||
// odleg<65>o<EFBFBD>ci
|
||
return NULL; // nie ma pojazd<7A>w na torze, to jest NULL
|
||
}
|
||
|
||
int TDynamicObject::DettachStatus(int dir)
|
||
{ // sprawdzenie odleg<65>o<EFBFBD>ci sprz<72>g<EFBFBD>w
|
||
// rzeczywistych od strony (dir):
|
||
// 0=prz<72>d,1=ty<74>
|
||
// Ra: dziwne, <20>e ta funkcja nie jest u<>ywana
|
||
if (!MoverParameters->Couplers[dir].CouplingFlag)
|
||
return 0; // je<6A>li nic nie pod<6F><64>czone, to jest OK
|
||
return (MoverParameters->DettachStatus(dir)); // czy jest w odpowiedniej odleg<65>o<EFBFBD>ci?
|
||
}
|
||
|
||
int TDynamicObject::Dettach(int dir)
|
||
{ // roz<6F><7A>czenie sprz<72>g<EFBFBD>w rzeczywistych od
|
||
// strony (dir): 0=prz<72>d,1=ty<74>
|
||
// zwraca mask<73> bitow<6F> aktualnych sprzeg<65>w (0 je<6A>li roz<6F><7A>czony)
|
||
if (ctOwner)
|
||
{ // je<6A>li pojazd ma przypisany obiekt nadzoruj<75>cy sk<73>ad, to p<>ki
|
||
// s<> wska<6B>niki
|
||
TDynamicObject *d = this;
|
||
while (d)
|
||
{
|
||
d->ctOwner = NULL; // usuwanie w<>a<EFBFBD>ciciela
|
||
d = d->Prev();
|
||
}
|
||
d = Next();
|
||
while (d)
|
||
{
|
||
d->ctOwner = NULL; // usuwanie w<>a<EFBFBD>ciciela
|
||
d = d->Next(); // i w drug<75> stron<6F>
|
||
}
|
||
}
|
||
if (MoverParameters->Couplers[dir].CouplingFlag) // odczepianie, o ile co<63> pod<6F><64>czone
|
||
MoverParameters->Dettach(dir);
|
||
return MoverParameters->Couplers[dir]
|
||
.CouplingFlag; // sprz<72>g po roz<6F><7A>czaniu (czego si<73> nie da odpi<70><69>
|
||
}
|
||
|
||
void TDynamicObject::CouplersDettach(double MinDist, int MyScanDir)
|
||
{ // funkcja roz<6F><7A>czajaca pod<6F><64>czone sprz<72>gi,
|
||
// je<6A>li odleg<65>o<EFBFBD><6F> przekracza (MinDist)
|
||
// MinDist - dystans minimalny, dla ktorego mozna roz<6F><7A>cza<7A>
|
||
if (MyScanDir > 0)
|
||
{
|
||
if (PrevConnected) // pojazd od strony sprz<72>gu 0
|
||
{
|
||
if (MoverParameters->Couplers[0].CoupleDist >
|
||
MinDist) // sprz<72>gi wirtualne zawsze przekraczaj<61>
|
||
{
|
||
if ((PrevConnectedNo ? PrevConnected->NextConnected :
|
||
PrevConnected->PrevConnected) == this)
|
||
{ // Ra: nie roz<6F><7A>czamy znalezionego, je<6A>eli nie do nas
|
||
// pod<6F><64>czony (mo<6D>e jecha<68> w
|
||
// innym kierunku)
|
||
PrevConnected->MoverParameters->Couplers[PrevConnectedNo].Connected = NULL;
|
||
if (PrevConnectedNo == 0)
|
||
{
|
||
PrevConnected->PrevConnectedNo = 2; // sprz<72>g 0 nie pod<6F><64>czony
|
||
PrevConnected->PrevConnected = NULL;
|
||
}
|
||
else if (PrevConnectedNo == 1)
|
||
{
|
||
PrevConnected->NextConnectedNo = 2; // sprz<72>g 1 nie pod<6F><64>czony
|
||
PrevConnected->NextConnected = NULL;
|
||
}
|
||
}
|
||
// za to zawsze od<6F><64>czamy siebie
|
||
PrevConnected = NULL;
|
||
PrevConnectedNo = 2; // sprz<72>g 0 nie pod<6F><64>czony
|
||
MoverParameters->Couplers[0].Connected = NULL;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (NextConnected) // pojazd od strony sprz<72>gu 1
|
||
{
|
||
if (MoverParameters->Couplers[1].CoupleDist >
|
||
MinDist) // sprz<72>gi wirtualne zawsze przekraczaj<61>
|
||
{
|
||
if ((NextConnectedNo ? NextConnected->NextConnected :
|
||
NextConnected->PrevConnected) == this)
|
||
{ // Ra: nie roz<6F><7A>czamy znalezionego, je<6A>eli nie do nas
|
||
// pod<6F><64>czony (mo<6D>e jecha<68> w
|
||
// innym kierunku)
|
||
NextConnected->MoverParameters->Couplers[NextConnectedNo].Connected = NULL;
|
||
if (NextConnectedNo == 0)
|
||
{
|
||
NextConnected->PrevConnectedNo = 2; // sprz<72>g 0 nie pod<6F><64>czony
|
||
NextConnected->PrevConnected = NULL;
|
||
}
|
||
else if (NextConnectedNo == 1)
|
||
{
|
||
NextConnected->NextConnectedNo = 2; // sprz<72>g 1 nie pod<6F><64>czony
|
||
NextConnected->NextConnected = NULL;
|
||
}
|
||
}
|
||
NextConnected = NULL;
|
||
NextConnectedNo = 2; // sprz<72>g 1 nie pod<6F><64>czony
|
||
MoverParameters->Couplers[1].Connected = NULL;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
void TDynamicObject::ABuScanObjects(int ScanDir, double ScanDist)
|
||
{ // skanowanie toru w poszukiwaniu koliduj<75>cych pojazd<7A>w
|
||
// ScanDir - okre<72>la kierunek poszukiwania zale<6C>nie od zwrotu pr<70>dko<6B>ci
|
||
// pojazdu
|
||
// ScanDir=1 - od strony Coupler0, ScanDir=-1 - od strony Coupler1
|
||
int MyScanDir = ScanDir; // zapami<6D>tanie kierunku poszukiwa<77> na torze
|
||
// pocz<63>tkowym, wzgl<67>dem sprz<72>g<EFBFBD>w
|
||
TTrackFollower *FirstAxle = (MyScanDir > 0 ? &Axle0 : &Axle1); // mo<6D>na by to trzyma<6D> w trainset
|
||
TTrack *Track = FirstAxle->GetTrack(); // tor na kt<6B>rym "stoi" skrajny w<>zek
|
||
// (mo<6D>e by<62> inny ni<6E> tor pojazdu)
|
||
if (FirstAxle->GetDirection() < 0) // czy o<> jest ustawiona w stron<6F> Point1?
|
||
ScanDir = -ScanDir; // je<6A>li tak, to kierunek szukania b<>dzie przeciwny
|
||
// (teraz wzgl<67>dem
|
||
// toru)
|
||
BYTE MyCouplFound; // numer sprz<72>gu do pod<6F><64>czenia w obiekcie szukajacym
|
||
MyCouplFound = (MyScanDir < 0) ? 1 : 0;
|
||
BYTE CouplFound; // numer sprz<72>gu w znalezionym obiekcie (znaleziony wype<70>ni)
|
||
TDynamicObject *FoundedObj; // znaleziony obiekt
|
||
double ActDist = 0; // przeskanowana odleglo<6C><6F>; odleg<65>o<EFBFBD><6F> do zawalidrogi
|
||
FoundedObj = ABuFindObject(Track, ScanDir, CouplFound,
|
||
ActDist); // zaczynamy szuka<6B> na tym samym torze
|
||
|
||
/*
|
||
if (FoundedObj) //jak co<63> znajdzie, to <20>ledzimy
|
||
{//powt<77>rzenie wyszukiwania tylko do zastawiania pu<70>epek podczas test<73>w
|
||
if (ABuGetDirection()<0) ScanDir=ScanDir; //ustalenie kierunku wzgl<67>dem toru
|
||
FoundedObj=ABuFindObject(Track,this,ScanDir,CouplFound);
|
||
}
|
||
*/
|
||
|
||
if (DebugModeFlag)
|
||
if (FoundedObj) // kod s<>u<EFBFBD><75>cy do logowania b<><62>d<EFBFBD>w
|
||
if (CouplFound == 0)
|
||
{
|
||
if (FoundedObj->PrevConnected)
|
||
if (FoundedObj->PrevConnected != this) // od<6F>wie<69>enie tego samego si<73> nie liczy
|
||
WriteLog("0! Coupler warning on " + asName + ":" +
|
||
to_string(MyCouplFound) + " - " + FoundedObj->asName +
|
||
":0 connected to " + FoundedObj->PrevConnected->asName + ":" +
|
||
to_string(FoundedObj->PrevConnectedNo));
|
||
}
|
||
else
|
||
{
|
||
if (FoundedObj->NextConnected)
|
||
if (FoundedObj->NextConnected != this) // od<6F>wie<69>enie tego samego si<73> nie liczy
|
||
WriteLog("0! Coupler warning on " + asName + ":" +
|
||
to_string(MyCouplFound) + " - " + FoundedObj->asName +
|
||
":1 connected to " + FoundedObj->NextConnected->asName + ":" +
|
||
to_string(FoundedObj->NextConnectedNo));
|
||
}
|
||
|
||
if (FoundedObj == NULL) // je<6A>li nie ma na tym samym, szukamy po okolicy
|
||
{ // szukanie najblizszego toru z jakims obiektem
|
||
// praktycznie przeklejone z TraceRoute()...
|
||
// double CurrDist=0; //aktualna dlugosc toru
|
||
if (ScanDir >= 0) // uwzgl<67>dniamy kawalek przeanalizowanego wcze<7A>niej toru
|
||
ActDist = Track->Length() - FirstAxle->GetTranslation(); // odleg<65>o<EFBFBD><6F> osi od Point2 toru
|
||
else
|
||
ActDist = FirstAxle->GetTranslation(); // odleg<65>o<EFBFBD><6F> osi od Point1 toru
|
||
while (ActDist < ScanDist)
|
||
{
|
||
// ActDist+=CurrDist; //odleg<65>o<EFBFBD><6F> ju<6A> przeanalizowana
|
||
if (ScanDir > 0) // w kierunku Point2 toru
|
||
{
|
||
if (Track ? Track->iNextDirection :
|
||
false) // je<6A>li nast<73>pny tor jest podpi<70>ty od Point2
|
||
ScanDir = -ScanDir; // to zmieniamy kierunek szukania na tym torze
|
||
Track = Track->CurrentNext(); // potem dopiero zmieniamy wska<6B>nik
|
||
}
|
||
else // w kierunku Point1
|
||
{
|
||
if (Track ? !Track->iPrevDirection :
|
||
true) // je<6A>li poprzedni tor nie jest podpi<70>ty od Point2
|
||
ScanDir = -ScanDir; // to zmieniamy kierunek szukania na tym torze
|
||
Track = Track->CurrentPrev(); // potem dopiero zmieniamy wska<6B>nik
|
||
}
|
||
if (Track)
|
||
{ // jesli jest kolejny odcinek toru
|
||
// CurrDist=Track->Length(); //doliczenie tego toru do przejrzanego
|
||
// dystandu
|
||
FoundedObj = ABuFindObject(Track, ScanDir, CouplFound,
|
||
ActDist); // przejrzenie pojazd<7A>w tego toru
|
||
if (FoundedObj)
|
||
{
|
||
// ActDist=ScanDist; //wyj<79>cie z p<>tli poszukiwania
|
||
break;
|
||
}
|
||
}
|
||
else // je<6A>li toru nie ma, to wychodzimy
|
||
{
|
||
ActDist = ScanDist + 1.0; // koniec przegl<67>dania tor<6F>w
|
||
break;
|
||
}
|
||
}
|
||
} // Koniec szukania najbli<6C>szego toru z jakim<69> obiektem.
|
||
// teraz odczepianie i je<6A>li co<63> si<73> znalaz<61>o, doczepianie.
|
||
if (MyScanDir > 0 ? PrevConnected : NextConnected)
|
||
if ((MyScanDir > 0 ? PrevConnected : NextConnected) != FoundedObj)
|
||
CouplersDettach(1.0, MyScanDir); // od<6F><64>czamy, je<6A>li dalej ni<6E> metr
|
||
// i <20><>czenie sprz<72>giem wirtualnym
|
||
if (FoundedObj)
|
||
{ // siebie mo<6D>na bezpiecznie pod<6F><64>czy<7A> jednostronnie do
|
||
// znalezionego
|
||
MoverParameters->Attach(MyCouplFound, CouplFound, FoundedObj->MoverParameters,
|
||
ctrain_virtual);
|
||
// MoverParameters->Couplers[MyCouplFound].Render=false; //wirtualnego nie
|
||
// renderujemy
|
||
if (MyCouplFound == 0)
|
||
{
|
||
PrevConnected = FoundedObj; // pojazd od strony sprz<72>gu 0
|
||
PrevConnectedNo = CouplFound;
|
||
}
|
||
else
|
||
{
|
||
NextConnected = FoundedObj; // pojazd od strony sprz<72>gu 1
|
||
NextConnectedNo = CouplFound;
|
||
}
|
||
if (FoundedObj->MoverParameters->Couplers[CouplFound].CouplingFlag == ctrain_virtual)
|
||
{ // Ra: wpinamy si<73> wirtualnym tylko je<6A>li znaleziony
|
||
// ma wirtualny sprz<72>g
|
||
FoundedObj->MoverParameters->Attach(CouplFound, MyCouplFound, this->MoverParameters,
|
||
ctrain_virtual);
|
||
if (CouplFound == 0) // je<6A>li widoczny sprz<72>g 0 znalezionego
|
||
{
|
||
if (DebugModeFlag)
|
||
if (FoundedObj->PrevConnected)
|
||
if (FoundedObj->PrevConnected != this)
|
||
WriteLog("1! Coupler warning on " + asName + ":" +
|
||
to_string(MyCouplFound) + " - " + FoundedObj->asName +
|
||
":0 connected to " + FoundedObj->PrevConnected->asName + ":" +
|
||
to_string(FoundedObj->PrevConnectedNo));
|
||
FoundedObj->PrevConnected = this;
|
||
FoundedObj->PrevConnectedNo = MyCouplFound;
|
||
}
|
||
else // je<6A>li widoczny sprz<72>g 1 znalezionego
|
||
{
|
||
if (DebugModeFlag)
|
||
if (FoundedObj->NextConnected)
|
||
if (FoundedObj->NextConnected != this)
|
||
WriteLog("1! Coupler warning on " + asName + ":" +
|
||
to_string(MyCouplFound) + " - " + FoundedObj->asName +
|
||
":1 connected to " + FoundedObj->NextConnected->asName + ":" +
|
||
to_string(FoundedObj->NextConnectedNo));
|
||
FoundedObj->NextConnected = this;
|
||
FoundedObj->NextConnectedNo = MyCouplFound;
|
||
}
|
||
}
|
||
// Ra: je<6A>li dwa samochody si<73> mijaj<61> na odcinku przed zawrotk<74>, to
|
||
// odleg<65>o<EFBFBD><6F> mi<6D>dzy nimi
|
||
// nie mo<6D>e by<62> liczona w linii prostej!
|
||
fTrackBlock = MoverParameters->Couplers[MyCouplFound]
|
||
.CoupleDist; // odleg<65>o<EFBFBD><6F> do najbli<6C>szego pojazdu w linii prostej
|
||
if (Track->iCategoryFlag > 1) // je<6A>li samoch<63>d
|
||
if (ActDist > MoverParameters->Dim.L +
|
||
FoundedObj->MoverParameters->Dim
|
||
.L) // przeskanowana odleg<65>o<EFBFBD><6F> wi<77>ksza od d<>ugo<67>ci pojazd<7A>w
|
||
// else if (ActDist<ScanDist) //dla samochod<6F>w musi by<62> uwzgl<67>dniona
|
||
// droga do
|
||
// zawr<77>cenia
|
||
fTrackBlock = ActDist; // ta odleg<65>o<EFBFBD><6F> jest wiecej warta
|
||
// if (fTrackBlock<500.0)
|
||
// WriteLog("Collision of "+AnsiString(fTrackBlock)+"m detected by
|
||
// "+asName+":"+AnsiString(MyCouplFound)+" with "+FoundedObj->asName);
|
||
}
|
||
else // nic nie znalezione, to nie ma przeszk<7A>d
|
||
fTrackBlock = 10000.0;
|
||
}
|
||
//----------ABu: koniec skanowania pojazdow
|
||
|
||
TDynamicObject::TDynamicObject()
|
||
{
|
||
modelShake = vector3(0, 0, 0);
|
||
fTrackBlock = 10000.0; // brak przeszkody na drodze
|
||
btnOn = false;
|
||
vUp = vWorldUp;
|
||
vFront = vWorldFront;
|
||
vLeft = vWorldLeft;
|
||
iNumAxles = 0;
|
||
MoverParameters = NULL;
|
||
Mechanik = NULL;
|
||
MechInside = false;
|
||
// McZapkie-270202
|
||
Controller = AIdriver;
|
||
bDisplayCab = false; // 030303
|
||
bBrakeAcc = false;
|
||
NextConnected = PrevConnected = NULL;
|
||
NextConnectedNo = PrevConnectedNo = 2; // ABu: Numery sprzegow. 2=nie pod<6F><64>czony
|
||
CouplCounter = 50; // b<>dzie sprawdza<7A> na pocz<63>tku
|
||
asName = "";
|
||
bEnabled = true;
|
||
MyTrack = NULL;
|
||
// McZapkie-260202
|
||
dRailLength = 25.0;
|
||
for (int i = 0; i < MaxAxles; i++)
|
||
dRailPosition[i] = 0.0;
|
||
for (int i = 0; i < MaxAxles; i++)
|
||
dWheelsPosition[i] = 0.0; // b<>dzie wczytane z MMD
|
||
iAxles = 0;
|
||
dWheelAngle[0] = 0.0;
|
||
dWheelAngle[1] = 0.0;
|
||
dWheelAngle[2] = 0.0;
|
||
// Winger 160204 - pantografy
|
||
// PantVolume = 3.5;
|
||
NoVoltTime = 0;
|
||
dDoorMoveL = 0.0;
|
||
dDoorMoveR = 0.0;
|
||
// for (int i=0;i<8;i++)
|
||
//{
|
||
// DoorSpeedFactor[i]=random(150);
|
||
// DoorSpeedFactor[i]=(DoorSpeedFactor[i]+100)/100;
|
||
//}
|
||
mdModel = NULL;
|
||
mdKabina = NULL;
|
||
ReplacableSkinID[0] = 0;
|
||
ReplacableSkinID[1] = 0;
|
||
ReplacableSkinID[2] = 0;
|
||
ReplacableSkinID[3] = 0;
|
||
ReplacableSkinID[4] = 0;
|
||
iAlpha = 0x30300030; // tak gdy tekstury wymienne nie maj<61> przezroczysto<74>ci
|
||
// smWiazary[0]=smWiazary[1]=NULL;
|
||
smWahacze[0] = smWahacze[1] = smWahacze[2] = smWahacze[3] = NULL;
|
||
fWahaczeAmp = 0;
|
||
smBrakeMode = NULL;
|
||
smLoadMode = NULL;
|
||
mdLoad = NULL;
|
||
mdLowPolyInt = NULL;
|
||
mdPrzedsionek = NULL;
|
||
//smMechanik0 = smMechanik1 = NULL;
|
||
smBuforLewy[0] = smBuforLewy[1] = NULL;
|
||
smBuforPrawy[0] = smBuforPrawy[1] = NULL;
|
||
enginevolume = 0;
|
||
smBogie[0] = smBogie[1] = NULL;
|
||
bogieRot[0] = bogieRot[1] = vector3(0, 0, 0);
|
||
modelRot = vector3(0, 0, 0);
|
||
eng_vol_act = 0.8;
|
||
eng_dfrq = 0;
|
||
eng_frq_act = 1;
|
||
eng_turbo = 0;
|
||
cp1 = cp2 = sp1 = sp2 = 0;
|
||
iDirection = 1; // stoi w kierunku tradycyjnym (0, gdy jest odwr<77>cony)
|
||
iAxleFirst = 0; // numer pierwszej osi w kierunku ruchu (prze<7A><65>czenie
|
||
// nast<73>puje, gdy osie sa na
|
||
// tym samym torze)
|
||
iInventory = 0; // flagi bitowe posiadanych submodeli (zaktualizuje si<73> po
|
||
// wczytaniu MMD)
|
||
RaLightsSet(0, 0); // pocz<63>tkowe zerowanie stanu <20>wiate<74>
|
||
// Ra: domy<6D>lne ilo<6C>ci animacji dla zgodno<6E>ci wstecz (gdy brak ilo<6C>ci podanych
|
||
// w MMD)
|
||
// ustawienie liczby modeli animowanych podczas konstruowania obiektu a nie na 0
|
||
// prowadzi prosto do wysyp<79>w je<6A>li <20>le zdefiniowane mmd
|
||
iAnimType[ANIM_WHEELS] = 0; // 0-osie (8)
|
||
iAnimType[ANIM_DOORS] = 0; // 1-drzwi (8)
|
||
iAnimType[ANIM_LEVERS] = 0; // 2-wahacze (4) - np. nogi konia
|
||
iAnimType[ANIM_BUFFERS] = 0; // 3-zderzaki (4)
|
||
iAnimType[ANIM_BOOGIES] = 0; // 4-w<>zki (2)
|
||
iAnimType[ANIM_PANTS] = 0; // 5-pantografy (2)
|
||
iAnimType[ANIM_STEAMS] = 0; // 6-t<>oki (nap<61>d parowozu)
|
||
iAnimations = 0; // na razie nie ma <20>adnego
|
||
pAnimations = NULL;
|
||
pAnimated = NULL;
|
||
fShade = 0.0; // standardowe o<>wietlenie na starcie
|
||
iHornWarning = 1; // numer syreny do u<>ycia po otrzymaniu sygna<6E>u do jazdy
|
||
asDestination = "none"; // stoj<6F>cy nigdzie nie jedzie
|
||
pValveGear = NULL; // Ra: tymczasowo
|
||
iCabs = 0; // maski bitowe modeli kabin
|
||
smBrakeSet = NULL; // nastawa hamulca (wajcha)
|
||
smLoadSet = NULL; // nastawa <20>adunku (wajcha)
|
||
smWiper = NULL; // wycieraczka (poniek<65>d te<74> wajcha)
|
||
fScanDist = 300.0; // odleg<65>o<EFBFBD><6F> skanowania, zwi<77>kszana w trybie <20><>czenia
|
||
ctOwner = NULL; // na pocz<63>tek niczyj
|
||
iOverheadMask = 0; // maska przydzielana przez AI pojazdom posiadaj<61>cym
|
||
// pantograf, aby wymusza<7A>y
|
||
// jazd<7A> bezpr<70>dow<6F>
|
||
tmpTraction.TractionVoltage = 0; // Ra 2F1H: prowizorka, trzeba przechowa<77>
|
||
// napi<70>cie, <20>eby nie wywala<6C>o WS pod
|
||
// izolatorem
|
||
fAdjustment = 0.0; // korekcja odleg<65>o<EFBFBD>ci pomi<6D>dzy w<>zkami (np. na <20>ukach)
|
||
}
|
||
|
||
TDynamicObject::~TDynamicObject()
|
||
{ // McZapkie-250302 - zamykanie logowania
|
||
// parametrow fizycznych
|
||
SafeDelete(Mechanik);
|
||
SafeDelete(MoverParameters);
|
||
// Ra: wy<77><79>czanie d<>wi<77>k<EFBFBD>w powinno by<62> dodane w ich destruktorach, ale si<73>
|
||
// sypie
|
||
/* to te<74> si<73> sypie
|
||
for (int i=0;i<MaxAxles;++i)
|
||
rsStukot[i].Stop(); //dzwieki poszczegolnych osi
|
||
rsSilnik.Stop();
|
||
rsWentylator.Stop();
|
||
rsPisk.Stop();
|
||
rsDerailment.Stop();
|
||
sPantUp.Stop();
|
||
sPantDown.Stop();
|
||
sBrakeAcc.Stop(); //dzwiek przyspieszacza
|
||
rsDiesielInc.Stop();
|
||
rscurve.Stop();
|
||
*/
|
||
delete[] pAnimations; // obiekty obs<62>uguj<75>ce animacj<63>
|
||
delete[] pAnimated; // lista animowanych submodeli
|
||
}
|
||
|
||
double
|
||
TDynamicObject::Init(std::string Name, // nazwa pojazdu, np. "EU07-424"
|
||
std::string BaseDir, // z kt<6B>rego katalogu wczytany, np. "PKP/EU07"
|
||
std::string asReplacableSkin, // nazwa wymiennej tekstury
|
||
std::string Type_Name, // nazwa CHK/MMD, np. "303E"
|
||
TTrack *Track, // tor pocz<63>tkowy wstwawienia (pocz<63>tek sk<73>adu)
|
||
double fDist, // dystans wzgl<67>dem punktu 1
|
||
std::string DriverType, // typ obsady
|
||
double fVel, // pr<70>dko<6B><6F> pocz<63>tkowa
|
||
std::string TrainName, // nazwa sk<73>adu, np. "PE2307" albo Vmax, je<6A>li pliku
|
||
// nie ma a s<> cyfry
|
||
float Load, // ilo<6C><6F> <20>adunku
|
||
std::string LoadType, // nazwa <20>adunku
|
||
bool Reversed, // true, je<6A>li ma sta<74> odwrotnie w sk<73>adzie
|
||
std::string MoreParams // dodatkowe parametry wczytywane w postaci tekstowej
|
||
)
|
||
{ // Ustawienie pocz<63>tkowe pojazdu
|
||
iDirection = (Reversed ? 0 : 1); // Ra: 0, je<6A>li ma by<62> wstawiony jako obr<62>cony ty<74>em
|
||
asBaseDir = "dynamic\\" + BaseDir + "\\"; // McZapkie-310302
|
||
asName = Name;
|
||
std::string asAnimName = ""; // zmienna robocza do wyszukiwania osi i w<>zk<7A>w
|
||
// Ra: zmieniamy znaczenie obsady na jednoliterowe, <20>eby dosadzi<7A> kierownika
|
||
if (DriverType == "headdriver")
|
||
DriverType = "1"; // steruj<75>cy kabin<69> +1
|
||
else if (DriverType == "reardriver")
|
||
DriverType = "2"; // steruj<75>cy kabin<69> -1
|
||
// else if (DriverType=="connected") DriverType="c"; //tego trzeba si<73> pozby<62>
|
||
// na rzecz
|
||
// ukrotnienia
|
||
else if (DriverType == "passenger")
|
||
DriverType = "p"; // to do przemy<6D>lenia
|
||
else if (DriverType == "nobody")
|
||
DriverType = ""; // nikt nie siedzi
|
||
int Cab = 0; // numer kabiny z obsad<61> (nie mo<6D>na zaj<61><6A> obu)
|
||
if (DriverType == "1") // od przodu sk<73>adu
|
||
Cab = 1; // iDirection?1:-1; //iDirection=1 gdy normalnie, =0 odwrotnie
|
||
else if (DriverType == "2") // od ty<74>u sk<73>adu
|
||
Cab = -1; // iDirection?-1:1;
|
||
else if (DriverType == "p")
|
||
{
|
||
if (Random(6) < 3)
|
||
Cab = 1;
|
||
else
|
||
Cab = -1; // losowy przydzia<69> kabiny
|
||
}
|
||
/* to nie ma uzasadnienia
|
||
else
|
||
{//obsada nie rozpoznana
|
||
Cab=0; //McZapkie-010303: w przyszlosci dac tez pomocnika, palacza,
|
||
konduktora itp.
|
||
Error("Unknown DriverType description: "+DriverType);
|
||
DriverType="nobody";
|
||
}
|
||
*/
|
||
// utworzenie parametr<74>w fizyki
|
||
MoverParameters =
|
||
new TMoverParameters(iDirection ? fVel : -fVel, Type_Name, asName, Load, LoadType, Cab);
|
||
iLights = MoverParameters->iLights; // wska<6B>nik na stan w<>asnych <20>wiate<74>
|
||
// (zmienimy dla rozrz<72>dczych EZT)
|
||
// McZapkie: TypeName musi byc nazw<7A> CHK/MMD pojazdu
|
||
if (!MoverParameters->LoadFIZ(asBaseDir))
|
||
{ // jak wczytanie CHK si<73> nie uda, to b<><62>d
|
||
if (ConversionError == -8)
|
||
ErrorLog("Missed file: " + BaseDir + "\\" + Type_Name + ".fiz");
|
||
Error("Cannot load dynamic object " + asName + " from:\r\n" + BaseDir + "\\" + Type_Name +
|
||
".fiz\r\nError " + to_string(ConversionError) + " in line " + to_string(LineCount));
|
||
return 0.0; // zerowa d<>ugo<67><6F> to brak pojazdu
|
||
}
|
||
bool driveractive = (fVel != 0.0); // je<6A>li pr<70>dko<6B><6F> niezerowa, to aktywujemy ruch
|
||
if (!MoverParameters->CheckLocomotiveParameters(
|
||
driveractive,
|
||
(fVel > 0 ? 1 : -1) * Cab *
|
||
(iDirection ? 1 : -1))) // jak jedzie lub obsadzony to gotowy do drogi
|
||
{
|
||
Error("Parameters mismatch: dynamic object " + asName + " from\n" + BaseDir + "\\" +
|
||
Type_Name);
|
||
return 0.0; // zerowa d<>ugo<67><6F> to brak pojazdu
|
||
}
|
||
// ustawienie pozycji hamulca
|
||
MoverParameters->LocalBrakePos = 0;
|
||
if (driveractive)
|
||
{
|
||
if (Cab == 0)
|
||
MoverParameters->BrakeCtrlPos =
|
||
floor(MoverParameters->Handle->GetPos(bh_NP));
|
||
else
|
||
MoverParameters->BrakeCtrlPos = floor(MoverParameters->Handle->GetPos(bh_RP));
|
||
}
|
||
else
|
||
MoverParameters->BrakeCtrlPos =
|
||
floor(MoverParameters->Handle->GetPos(bh_NP));
|
||
|
||
MoverParameters->BrakeLevelSet(
|
||
MoverParameters->BrakeCtrlPos); // poprawienie hamulca po ewentualnym
|
||
// przestawieniu przez Pascal
|
||
|
||
// dodatkowe parametry yB
|
||
MoreParams += "."; // wykonuje o jedn<64> iteracj<63> za ma<6D>o, wi<77>c trzeba mu doda<64>
|
||
// kropk<70> na koniec
|
||
int kropka = MoreParams.find("."); // znajd<6A> kropke
|
||
std::string ActPar; // na parametry
|
||
while (kropka != std::string::npos) // jesli sa kropki jeszcze
|
||
{
|
||
int dlugosc = MoreParams.length();
|
||
ActPar = ToUpper(MoreParams.substr(0, kropka)); // pierwszy parametr;
|
||
MoreParams = MoreParams.substr(kropka + 1, dlugosc - kropka); // reszta do dalszej
|
||
// obrobki
|
||
kropka = MoreParams.find(".");
|
||
|
||
if (ActPar.substr(0, 1) == "B") // jesli hamulce
|
||
{ // sprawdzanie kolejno nastaw
|
||
WriteLog("Wpis hamulca: " + ActPar);
|
||
if (ActPar.find('G') != std::string::npos)
|
||
{
|
||
MoverParameters->BrakeDelaySwitch(bdelay_G);
|
||
}
|
||
if( ActPar.find( 'P' ) != std::string::npos )
|
||
{
|
||
MoverParameters->BrakeDelaySwitch(bdelay_P);
|
||
}
|
||
if( ActPar.find( 'R' ) != std::string::npos )
|
||
{
|
||
MoverParameters->BrakeDelaySwitch(bdelay_R);
|
||
}
|
||
if( ActPar.find( 'M' ) != std::string::npos )
|
||
{
|
||
MoverParameters->BrakeDelaySwitch(bdelay_R);
|
||
MoverParameters->BrakeDelaySwitch(bdelay_R + bdelay_M);
|
||
}
|
||
// wylaczanie hamulca
|
||
if (ActPar.find("<>") != std::string::npos) // wylaczanie na probe hamowania naglego
|
||
{
|
||
MoverParameters->BrakeStatus |= 128; // wylacz
|
||
}
|
||
if (ActPar.find('0') != std::string::npos) // wylaczanie na sztywno
|
||
{
|
||
MoverParameters->BrakeStatus |= 128; // wylacz
|
||
MoverParameters->Hamulec->ForceEmptiness();
|
||
MoverParameters->BrakeReleaser(1); // odluznij automatycznie
|
||
}
|
||
if (ActPar.find('E') != std::string::npos) // oprozniony
|
||
{
|
||
MoverParameters->Hamulec->ForceEmptiness();
|
||
MoverParameters->BrakeReleaser(1); // odluznij automatycznie
|
||
MoverParameters->Pipe->CreatePress(0);
|
||
MoverParameters->Pipe2->CreatePress(0);
|
||
}
|
||
if (ActPar.find('Q') != std::string::npos) // oprozniony
|
||
{
|
||
// MoverParameters->Hamulec->ForceEmptiness(); //TODO: sprawdzic,
|
||
// dlaczego
|
||
// pojawia sie blad przy uzyciu tej linijki w lokomotywie
|
||
MoverParameters->BrakeReleaser(1); // odluznij automatycznie
|
||
MoverParameters->Pipe->CreatePress(0.0);
|
||
MoverParameters->PipePress = 0.0;
|
||
MoverParameters->Pipe2->CreatePress(0.0);
|
||
MoverParameters->ScndPipePress = 0.0;
|
||
MoverParameters->PantVolume = 1;
|
||
MoverParameters->PantPress = 0;
|
||
MoverParameters->CompressedVolume = 0;
|
||
}
|
||
|
||
if (ActPar.find('1') != std::string::npos) // wylaczanie 10%
|
||
{
|
||
if (Random(10) < 1) // losowanie 1/10
|
||
{
|
||
MoverParameters->BrakeStatus |= 128; // wylacz
|
||
MoverParameters->Hamulec->ForceEmptiness();
|
||
MoverParameters->BrakeReleaser(1); // odluznij automatycznie
|
||
}
|
||
}
|
||
if (ActPar.find('X') != std::string::npos) // agonalny wylaczanie 20%, usrednienie przekladni
|
||
{
|
||
if (Random(100) < 20) // losowanie 20/100
|
||
{
|
||
MoverParameters->BrakeStatus |= 128; // wylacz
|
||
MoverParameters->Hamulec->ForceEmptiness();
|
||
MoverParameters->BrakeReleaser(1); // odluznij automatycznie
|
||
}
|
||
if (MoverParameters->BrakeCylMult[2] * MoverParameters->BrakeCylMult[1] >
|
||
0.01) // jesli jest nastawiacz mechaniczny PL
|
||
{
|
||
float rnd = Random(100);
|
||
if (rnd < 20) // losowanie 20/100 usrednienie
|
||
{
|
||
MoverParameters->BrakeCylMult[2] = MoverParameters->BrakeCylMult[1] =
|
||
(MoverParameters->BrakeCylMult[2] + MoverParameters->BrakeCylMult[1]) /
|
||
2;
|
||
}
|
||
else if (rnd < 70) // losowanie 70/100-20/100 oslabienie
|
||
{
|
||
MoverParameters->BrakeCylMult[1] = MoverParameters->BrakeCylMult[1] * 0.50;
|
||
MoverParameters->BrakeCylMult[2] = MoverParameters->BrakeCylMult[2] * 0.75;
|
||
}
|
||
else if (rnd < 80) // losowanie 80/100-70/100 tylko prozny
|
||
{
|
||
MoverParameters->BrakeCylMult[2] = MoverParameters->BrakeCylMult[1];
|
||
}
|
||
else // tylko ladowny
|
||
{
|
||
MoverParameters->BrakeCylMult[1] = MoverParameters->BrakeCylMult[2];
|
||
}
|
||
}
|
||
}
|
||
// nastawianie ladunku
|
||
if (ActPar.find('T') != std::string::npos) // prozny
|
||
{
|
||
MoverParameters->DecBrakeMult();
|
||
MoverParameters->DecBrakeMult();
|
||
} // dwa razy w dol
|
||
if (ActPar.find('H') != std::string::npos) // ladowny I (dla P-<2D> dalej prozny)
|
||
{
|
||
MoverParameters->IncBrakeMult();
|
||
MoverParameters->IncBrakeMult();
|
||
MoverParameters->DecBrakeMult();
|
||
} // dwa razy w gore i obniz
|
||
if (ActPar.find('F') != std::string::npos) // ladowny II
|
||
{
|
||
MoverParameters->IncBrakeMult();
|
||
MoverParameters->IncBrakeMult();
|
||
} // dwa razy w gore
|
||
if (ActPar.find('N') != std::string::npos) // parametr neutralny
|
||
{
|
||
}
|
||
} // koniec hamulce
|
||
else if (ActPar.substr(0, 1) == "") // tu mozna wpisac inny prefiks i inne rzeczy
|
||
{
|
||
// jakies inne prefiksy
|
||
}
|
||
|
||
} // koniec while kropka
|
||
|
||
if (MoverParameters->CategoryFlag & 2) // je<6A>li samoch<63>d
|
||
{ // ustawianie samochodow na poboczu albo na <20>rodku drogi
|
||
if (Track->fTrackWidth < 3.5) // je<6A>li droga w<>ska
|
||
MoverParameters->OffsetTrackH = 0.0; // to stawiamy na <20>rodku, niezale<6C>nie od stanu
|
||
// ruchu
|
||
else if (driveractive) // od 3.5m do 8.0m jedzie po <20>rodku pasa, dla
|
||
// szerszych w odleg<65>o<EFBFBD>ci
|
||
// 1.5m
|
||
MoverParameters->OffsetTrackH =
|
||
Track->fTrackWidth <= 8.0 ? -Track->fTrackWidth * 0.25 : -1.5;
|
||
else // jak stoi, to ko<6B>em na poboczu i pobieramy szeroko<6B><6F> razem z
|
||
// poboczem, ale nie z
|
||
// chodnikiem
|
||
MoverParameters->OffsetTrackH =
|
||
-0.5 * (Track->WidthTotal() - MoverParameters->Dim.W) + 0.05;
|
||
iHornWarning = 0; // nie b<>dzie tr<74>bienia po podaniu zezwolenia na jazd<7A>
|
||
if (fDist < 0.0) //-0.5*MoverParameters->Dim.L) //je<6A>li jest przesuni<6E>cie do ty<74>u
|
||
if (!Track->CurrentPrev()) // a nie ma tam odcinka i trzeba by co<63>
|
||
// wygenerowa<77>
|
||
fDist = -fDist; // to traktujemy, jakby przesuni<6E>cie by<62>o w drug<75> stron<6F>
|
||
}
|
||
// w wagonie tez niech jedzie
|
||
// if (MoverParameters->MainCtrlPosNo>0 &&
|
||
// if (MoverParameters->CabNo!=0)
|
||
if (DriverType != "")
|
||
{ // McZapkie-040602: je<6A>li co<63> siedzi w poje<6A>dzie
|
||
if (Name == Global::asHumanCtrlVehicle) // je<6A>li pojazd wybrany do prowadzenia
|
||
{
|
||
if (DebugModeFlag ? false : MoverParameters->EngineType !=
|
||
Dumb) // jak nie Debugmode i nie jest dumbem
|
||
Controller = Humandriver; // wsadzamy tam steruj<75>cego
|
||
else // w przeciwnym razie trzeba w<><77>czy<7A> pokazywanie kabiny
|
||
bDisplayCab = true;
|
||
}
|
||
// McZapkie-151102: rozk<7A>ad jazdy czytany z pliku *.txt z katalogu w kt<6B>rym
|
||
// jest sceneria
|
||
if (DriverType == "1" || DriverType == "2")
|
||
{ // McZapkie-110303: mechanik i rozklad tylko gdy jest obsada
|
||
// MoverParameters->ActiveCab=MoverParameters->CabNo; //ustalenie aktywnej
|
||
// kabiny
|
||
// (rozrz<72>d)
|
||
Mechanik = new TController(Controller, this, Aggressive);
|
||
if (TrainName.empty()) // je<6A>li nie w sk<73>adzie
|
||
{
|
||
Mechanik->DirectionInitial(); // za<7A><61>czenie rozrz<72>du (wirtualne kabiny) itd.
|
||
Mechanik->PutCommand(
|
||
"Timetable:", iDirection ? -fVel : fVel, 0,
|
||
NULL); // tryb poci<63>gowy z ustalon<6F> pr<70>dko<6B>ci<63> (wzgl<67>dem sprz<72>g<EFBFBD>w)
|
||
}
|
||
// if (TrainName!="none")
|
||
// Mechanik->PutCommand("Timetable:"+TrainName,fVel,0,NULL);
|
||
}
|
||
else if (DriverType == "p")
|
||
{ // obserwator w charakterze pasa<73>era
|
||
// Ra: to jest niebezpieczne, bo w razie co b<>dzie pomaga<67> hamulcem
|
||
// bezpiecze<7A>stwa
|
||
Mechanik = new TController(Controller, this, Easyman, false);
|
||
}
|
||
}
|
||
// McZapkie-250202
|
||
iAxles = (MaxAxles < MoverParameters->NAxles) ? MaxAxles : MoverParameters->NAxles; // ilo<6C><6F> osi
|
||
// wczytywanie z pliku nazwatypu.mmd, w tym model
|
||
LoadMMediaFile(asBaseDir, Type_Name, asReplacableSkin);
|
||
// McZapkie-100402: wyszukiwanie submodeli sprzeg<65>w
|
||
btCoupler1.Init("coupler1", mdModel, false); // false - ma by<62> wy<77><79>czony
|
||
btCoupler2.Init("coupler2", mdModel, false);
|
||
btCPneumatic1.Init("cpneumatic1", mdModel);
|
||
btCPneumatic2.Init("cpneumatic2", mdModel);
|
||
btCPneumatic1r.Init("cpneumatic1r", mdModel);
|
||
btCPneumatic2r.Init("cpneumatic2r", mdModel);
|
||
btPneumatic1.Init("pneumatic1", mdModel);
|
||
btPneumatic2.Init("pneumatic2", mdModel);
|
||
btPneumatic1r.Init("pneumatic1r", mdModel);
|
||
btPneumatic2r.Init("pneumatic2r", mdModel);
|
||
btCCtrl1.Init("cctrl1", mdModel, false);
|
||
btCCtrl2.Init("cctrl2", mdModel, false);
|
||
btCPass1.Init("cpass1", mdModel, false);
|
||
btCPass2.Init("cpass2", mdModel, false);
|
||
// sygnaly
|
||
// ABu 060205: Zmiany dla koncowek swiecacych:
|
||
btEndSignals11.Init("endsignal13", mdModel, false);
|
||
btEndSignals21.Init("endsignal23", mdModel, false);
|
||
btEndSignals13.Init("endsignal12", mdModel, false);
|
||
btEndSignals23.Init("endsignal22", mdModel, false);
|
||
iInventory |= btEndSignals11.Active() ? 0x01 : 0; // informacja, czy ma poszczeg<65>lne <20>wiat<61>a
|
||
iInventory |= btEndSignals21.Active() ? 0x02 : 0;
|
||
iInventory |= btEndSignals13.Active() ? 0x04 : 0;
|
||
iInventory |= btEndSignals23.Active() ? 0x08 : 0;
|
||
// ABu: to niestety zostawione dla kompatybilnosci modeli:
|
||
btEndSignals1.Init("endsignals1", mdModel, false);
|
||
btEndSignals2.Init("endsignals2", mdModel, false);
|
||
btEndSignalsTab1.Init("endtab1", mdModel, false);
|
||
btEndSignalsTab2.Init("endtab2", mdModel, false);
|
||
iInventory |= btEndSignals1.Active() ? 0x10 : 0;
|
||
iInventory |= btEndSignals2.Active() ? 0x20 : 0;
|
||
iInventory |= btEndSignalsTab1.Active() ? 0x40 : 0; // tabliczki blaszane
|
||
iInventory |= btEndSignalsTab2.Active() ? 0x80 : 0;
|
||
// ABu Uwaga! tu zmienic w modelu!
|
||
btHeadSignals11.Init("headlamp13", mdModel, false); // lewe
|
||
btHeadSignals12.Init("headlamp11", mdModel, false); // g<>rne
|
||
btHeadSignals13.Init("headlamp12", mdModel, false); // prawe
|
||
btHeadSignals21.Init("headlamp23", mdModel, false);
|
||
btHeadSignals22.Init("headlamp21", mdModel, false);
|
||
btHeadSignals23.Init("headlamp22", mdModel, false);
|
||
btMechanik1.Init("mechanik1", mdLowPolyInt, false);
|
||
btMechanik2.Init("mechanik2", mdLowPolyInt, false);
|
||
TurnOff(); // resetowanie zmiennych submodeli
|
||
// wyszukiwanie zderzakow
|
||
if (mdModel) // je<6A>li ma w czym szuka<6B>
|
||
for (int i = 0; i < 2; i++)
|
||
{
|
||
asAnimName = std::string("buffer_left0") + to_string(i + 1);
|
||
smBuforLewy[i] = mdModel->GetFromName(asAnimName.c_str());
|
||
if (smBuforLewy[i])
|
||
smBuforLewy[i]->WillBeAnimated(); // ustawienie flagi animacji
|
||
asAnimName = std::string("buffer_right0") + to_string(i + 1);
|
||
smBuforPrawy[i] = mdModel->GetFromName(asAnimName.c_str());
|
||
if (smBuforPrawy[i])
|
||
smBuforPrawy[i]->WillBeAnimated();
|
||
}
|
||
for (int i = 0; i < iAxles; i++) // wyszukiwanie osi (0 jest na ko<6B>cu, dlatego dodajemy
|
||
// d<>ugo<67><6F>?)
|
||
dRailPosition[i] =
|
||
(Reversed ? -dWheelsPosition[i] : (dWheelsPosition[i] + MoverParameters->Dim.L)) +
|
||
fDist;
|
||
// McZapkie-250202 end.
|
||
Track->AddDynamicObject(this); // wstawiamy do toru na pozycj<63> 0, a potem przesuniemy
|
||
// McZapkie: zmieniono na ilosc osi brane z chk
|
||
// iNumAxles=(MoverParameters->NAxles>3 ? 4 : 2 );
|
||
iNumAxles = 2;
|
||
// McZapkie-090402: odleglosc miedzy czopami skretu lub osiami
|
||
fAxleDist = Max0R(MoverParameters->BDist, MoverParameters->ADist);
|
||
if (fAxleDist < 0.2)
|
||
fAxleDist = 0.2; //<2F>eby si<73> da<64>o wektory policzy<7A>
|
||
if (fAxleDist > MoverParameters->Dim.L - 0.2) // nie mog<6F> by<62> za daleko
|
||
fAxleDist = MoverParameters->Dim.L - 0.2; // bo b<>dzie "walenie w mur"
|
||
double fAxleDistHalf = fAxleDist * 0.5;
|
||
// WriteLog("Dynamic "+Type_Name+" of length "+MoverParameters->Dim.L+" at
|
||
// "+AnsiString(fDist));
|
||
// if (Cab) //je<6A>li ma obsad<61> - zgodno<6E><6F> wstecz, je<6A>li tor startowy ma Event0
|
||
// if (Track->Event0) //je<6A>li tor ma Event0
|
||
// if (fDist>=0.0) //je<6A>li je<6A>li w starych sceneriach pocz<63>tek sk<73>adu by<62>by
|
||
// wysuni<6E>ty na ten
|
||
// tor
|
||
// if (fDist<=0.5*MoverParameters->Dim.L+0.2) //ale nie jest wysuni<6E>ty
|
||
// fDist+=0.5*MoverParameters->Dim.L+0.2; //wysun<75><6E> go na ten tor
|
||
// przesuwanie pojazdu tak, aby jego pocz<63>tek by<62> we wskazanym miejcu
|
||
fDist -= 0.5 * MoverParameters->Dim.L; // dodajemy p<><70> d<>ugo<67>ci pojazdu, bo
|
||
// ustawiamy jego <20>rodek (zliczanie na
|
||
// minus)
|
||
switch (iNumAxles)
|
||
{ // Ra: pojazdy wstawiane s<> na tor pocz<63>tkowy, a potem
|
||
// przesuwane
|
||
case 2: // ustawianie osi na torze
|
||
Axle0.Init(Track, this, iDirection ? 1 : -1);
|
||
Axle0.Move((iDirection ? fDist : -fDist) + fAxleDistHalf, false);
|
||
Axle1.Init(Track, this, iDirection ? 1 : -1);
|
||
Axle1.Move((iDirection ? fDist : -fDist) - fAxleDistHalf,
|
||
false); // false, <20>eby nie generowa<77> event<6E>w
|
||
// Axle2.Init(Track,this,iDirection?1:-1);
|
||
// Axle2.Move((iDirection?fDist:-fDist)-fAxleDistHalft+0.01),false);
|
||
// Axle3.Init(Track,this,iDirection?1:-1);
|
||
// Axle3.Move((iDirection?fDist:-fDist)+fAxleDistHalf-0.01),false);
|
||
break;
|
||
case 4:
|
||
Axle0.Init(Track, this, iDirection ? 1 : -1);
|
||
Axle0.Move((iDirection ? fDist : -fDist) + (fAxleDistHalf + MoverParameters->ADist * 0.5),
|
||
false);
|
||
Axle1.Init(Track, this, iDirection ? 1 : -1);
|
||
Axle1.Move((iDirection ? fDist : -fDist) - (fAxleDistHalf + MoverParameters->ADist * 0.5),
|
||
false);
|
||
// Axle2.Init(Track,this,iDirection?1:-1);
|
||
// Axle2.Move((iDirection?fDist:-fDist)-(fAxleDistHalf-MoverParameters->ADist*0.5),false);
|
||
// Axle3.Init(Track,this,iDirection?1:-1);
|
||
// Axle3.Move((iDirection?fDist:-fDist)+(fAxleDistHalf-MoverParameters->ADist*0.5),false);
|
||
break;
|
||
}
|
||
Move(0.0001); // potrzebne do wyliczenia aktualnej pozycji; nie mo<6D>e by<62> zero,
|
||
// bo nie przeliczy
|
||
// pozycji
|
||
// teraz jeszcze trzeba przypisa<73> pojazdy do nowego toru, bo przesuwanie
|
||
// pocz<63>tkowe osi nie
|
||
// zrobi<62>o tego
|
||
ABuCheckMyTrack(); // zmiana toru na ten, co o<> Axle0 (o<> z przodu)
|
||
TLocation loc; // Ra: ustawienie pozycji do obliczania sprz<72>g<EFBFBD>w
|
||
loc.X = -vPosition.x;
|
||
loc.Y = vPosition.z;
|
||
loc.Z = vPosition.y;
|
||
MoverParameters->Loc = loc; // normalnie przesuwa ComputeMovement() w Update()
|
||
// pOldPos4=Axle1.pPosition; //Ra: nie u<>ywane
|
||
// pOldPos1=Axle0.pPosition;
|
||
// ActualTrack= GetTrack(); //McZapkie-030303
|
||
// ABuWozki 060504
|
||
if (mdModel) // je<6A>li ma w czym szuka<6B>
|
||
{
|
||
smBogie[0] = mdModel->GetFromName("bogie1"); // Ra: bo nazwy s<> ma<6D>ymi
|
||
smBogie[1] = mdModel->GetFromName("bogie2");
|
||
if (!smBogie[0])
|
||
smBogie[0] = mdModel->GetFromName("boogie01"); // Ra: alternatywna nazwa
|
||
if (!smBogie[1])
|
||
smBogie[1] = mdModel->GetFromName("boogie02"); // Ra: alternatywna nazwa
|
||
if (smBogie[0])
|
||
smBogie[0]->WillBeAnimated();
|
||
if (smBogie[1])
|
||
smBogie[1]->WillBeAnimated();
|
||
}
|
||
// ABu: zainicjowanie zmiennej, zeby nic sie nie ruszylo
|
||
// w pierwszej klatce, potem juz liczona prawidlowa wartosc masy
|
||
MoverParameters->ComputeConstans();
|
||
/*Ra: to nie dzia<69>a - Event0 musi by<62> wykonywany ci<63>gle
|
||
if (fVel==0.0) //je<6A>li stoi
|
||
if (MoverParameters->CabNo!=0) //i ma kogo<67> w kabinie
|
||
if (Track->Event0) //a jest w tym torze event od stania
|
||
RaAxleEvent(Track->Event0); //dodanie eventu stania do kolejki
|
||
*/
|
||
vFloor = vector3(0, 0, MoverParameters->Floor); // wektor pod<6F>ogi dla wagon<6F>w, przesuwa <20>adunek
|
||
return MoverParameters->Dim.L; // d<>ugo<67><6F> wi<77>ksza od zera oznacza OK; 2mm docisku?
|
||
}
|
||
|
||
void TDynamicObject::FastMove(double fDistance)
|
||
{
|
||
MoverParameters->dMoveLen = MoverParameters->dMoveLen + fDistance;
|
||
}
|
||
|
||
void TDynamicObject::Move(double fDistance)
|
||
{ // przesuwanie pojazdu po
|
||
// trajektorii polega na
|
||
// przesuwaniu poszczeg<65>lnych osi
|
||
// Ra: warto<74><6F> pr<70>dko<6B>ci 2km/h ma ograniczy<7A> aktywacj<63> event<6E>w w przypadku
|
||
// drga<67>
|
||
if (Axle0.GetTrack() == Axle1.GetTrack()) // przed przesuni<6E>ciem
|
||
{ // powi<77>zanie pojazdu z osi<73> mo<6D>na zmieni<6E> tylko wtedy, gdy skrajne osie s<>
|
||
// na tym samym torze
|
||
if (MoverParameters->Vel >
|
||
2) //|[km/h]| nie ma sensu zmiana osi, jesli pojazd drga na postoju
|
||
iAxleFirst = (MoverParameters->V >= 0.0) ?
|
||
1 :
|
||
0; //[m/s] ?1:0 - aktywna druga o<> w kierunku jazdy
|
||
// aktualnie eventy aktywuje druga o<>, <20>eby AI nie wy<77><79>cza<7A>o sobie semafora
|
||
// za szybko
|
||
}
|
||
if (fDistance > 0.0)
|
||
{ // gdy ruch w stron<6F> sprz<72>gu 0, doliczy<7A> korekt<6B> do osi 1
|
||
bEnabled &= Axle0.Move(fDistance, !iAxleFirst); // o<> z przodu pojazdu
|
||
bEnabled &= Axle1.Move(fDistance /*-fAdjustment*/, iAxleFirst); // o<> z ty<74>u pojazdu
|
||
}
|
||
else if (fDistance < 0.0)
|
||
{ // gdy ruch w stron<6F> sprz<72>gu 1, doliczy<7A> korekt<6B> do osi 0
|
||
bEnabled &= Axle1.Move(fDistance, iAxleFirst); // o<> z ty<74>u pojazdu prusza si<73> pierwsza
|
||
bEnabled &= Axle0.Move(fDistance /*-fAdjustment*/, !iAxleFirst); // o<> z przodu pojazdu
|
||
}
|
||
else // gf: bez wywolania Move na postoju nie ma event0
|
||
{
|
||
bEnabled &= Axle1.Move(fDistance, iAxleFirst); // o<> z ty<74>u pojazdu prusza si<73> pierwsza
|
||
bEnabled &= Axle0.Move(fDistance, !iAxleFirst); // o<> z przodu pojazdu
|
||
}
|
||
if (fDistance != 0.0) // nie liczy<7A> ponownie, je<6A>li stoi
|
||
{ // liczenie pozycji pojazdu tutaj, bo jest u<>ywane w wielu miejscach
|
||
vPosition = 0.5 * (Axle1.pPosition + Axle0.pPosition); //<2F>rodek mi<6D>dzy skrajnymi osiami
|
||
vFront = Axle0.pPosition - Axle1.pPosition; // wektor pomi<6D>dzy skrajnymi osiami
|
||
// Ra 2F1J: to nie jest stabilne (powoduje rzucanie taborem) i wymaga
|
||
// dopracowania
|
||
fAdjustment = vFront.Length() - fAxleDist; // na <20>uku b<>dzie ujemny
|
||
// if (fabs(fAdjustment)>0.02) //je<6A>li jest zbyt du<64>o, to roz<6F>o<EFBFBD>y<EFBFBD> na kilka
|
||
// przelicze<7A>
|
||
// (wygasza drgania?)
|
||
//{//par<61> centymetr<74>w trzeba by ju<6A> skorygowa<77>; te b<><62>dy mog<6F> si<73> te<74>
|
||
// generowa<77> na ostrych
|
||
//<2F>ukach
|
||
// fAdjustment*=0.5; //w jednym kroku korygowany jest u<>amek b<><62>du
|
||
//}
|
||
// else
|
||
// fAdjustment=0.0;
|
||
vFront = Normalize(vFront); // kierunek ustawienia pojazdu (wektor jednostkowy)
|
||
vLeft = Normalize(CrossProduct(vWorldUp, vFront)); // wektor poziomy w lewo,
|
||
// normalizacja potrzebna z powodu
|
||
// pochylenia (vFront)
|
||
vUp = CrossProduct(vFront, vLeft); // wektor w g<>r<EFBFBD>, b<>dzie jednostkowy
|
||
modelRot.z = atan2(-vFront.x, vFront.z); // k<>t obrotu pojazdu [rad]; z ABuBogies()
|
||
double a = ((Axle1.GetRoll() + Axle0.GetRoll())); // suma przechy<68>ek
|
||
if (a != 0.0)
|
||
{ // wyznaczanie przechylenia tylko je<6A>li jest przechy<68>ka
|
||
// mo<6D>na by pobra<72> wektory normalne z toru...
|
||
mMatrix.Identity(); // ta macierz jest potrzebna g<><67>wnie do wy<77>wietlania
|
||
mMatrix.Rotation(a * 0.5, vFront); // obr<62>t wzd<7A>u<EFBFBD> osi o przechy<68>k<EFBFBD>
|
||
vUp = mMatrix * vUp; // wektor w g<>r<EFBFBD> pojazdu (przekr<6B>cenie na przechy<68>ce)
|
||
// vLeft=mMatrix*DynamicObject->vLeft;
|
||
// vUp=CrossProduct(vFront,vLeft); //wektor w g<>r<EFBFBD>
|
||
// vLeft=Normalize(CrossProduct(vWorldUp,vFront)); //wektor w lewo
|
||
vLeft = Normalize(CrossProduct(vUp, vFront)); // wektor w lewo
|
||
// vUp=CrossProduct(vFront,vLeft); //wektor w g<>r<EFBFBD>
|
||
}
|
||
mMatrix.Identity(); // to te<74> mo<6D>na by od razu policzy<7A>, ale potrzebne jest
|
||
// do wy<77>wietlania
|
||
mMatrix.BasisChange(vLeft, vUp, vFront); // przesuwanie jest jednak rzadziej ni<6E>
|
||
// renderowanie
|
||
mMatrix = Inverse(mMatrix); // wyliczenie macierzy dla pojazdu (potrzebna
|
||
// tylko do wy<77>wietlania?)
|
||
// if (MoverParameters->CategoryFlag&2)
|
||
{ // przesuni<6E>cia s<> u<>ywane po wyrzuceniu poci<63>gu z toru
|
||
vPosition.x += MoverParameters->OffsetTrackH * vLeft.x; // dodanie przesuni<6E>cia w bok
|
||
vPosition.z +=
|
||
MoverParameters->OffsetTrackH * vLeft.z; // vLeft jest wektorem poprzecznym
|
||
// if () na przechy<68>ce b<>dzie dodatkowo zmiana wysoko<6B>ci samochodu
|
||
vPosition.y += MoverParameters->OffsetTrackV; // te offsety s<> liczone przez moverparam
|
||
}
|
||
// Ra: skopiowanie pozycji do fizyki, tam potrzebna do zrywania sprz<72>g<EFBFBD>w
|
||
// MoverParameters->Loc.X=-vPosition.x; //robi to {Fast}ComputeMovement()
|
||
// MoverParameters->Loc.Y= vPosition.z;
|
||
// MoverParameters->Loc.Z= vPosition.y;
|
||
// obliczanie pozycji sprz<72>g<EFBFBD>w do liczenia zderze<7A>
|
||
vector3 dir = (0.5 * MoverParameters->Dim.L) * vFront; // wektor sprz<72>gu
|
||
vCoulpler[0] = vPosition + dir; // wsp<73><70>rz<72>dne sprz<72>gu na pocz<63>tku
|
||
vCoulpler[1] = vPosition - dir; // wsp<73><70>rz<72>dne sprz<72>gu na ko<6B>cu
|
||
MoverParameters->vCoulpler[0] = vCoulpler[0]; // tymczasowo kopiowane na inny poziom
|
||
MoverParameters->vCoulpler[1] = vCoulpler[1];
|
||
// bCameraNear=
|
||
// if (bCameraNear) //je<6A>li istotne s<> szczeg<65><67>y (blisko kamery)
|
||
{ // przeliczenie cienia
|
||
TTrack *t0 = Axle0.GetTrack(); // ju<6A> po przesuni<6E>ciu
|
||
TTrack *t1 = Axle1.GetTrack();
|
||
if ((t0->eEnvironment == e_flat) && (t1->eEnvironment == e_flat)) // mo<6D>e by<62>
|
||
// e_bridge...
|
||
fShade = 0.0; // standardowe o<>wietlenie
|
||
else
|
||
{ // je<6A>eli te tory maj<61> niestandardowy stopie<69> zacienienia
|
||
// (e_canyon, e_tunnel)
|
||
if (t0->eEnvironment == t1->eEnvironment)
|
||
{
|
||
switch (t0->eEnvironment)
|
||
{ // typ zmiany o<>wietlenia
|
||
case e_canyon:
|
||
fShade = 0.65;
|
||
break; // zacienienie w kanionie
|
||
case e_tunnel:
|
||
fShade = 0.20;
|
||
break; // zacienienie w tunelu
|
||
}
|
||
}
|
||
else // dwa r<><72>ne
|
||
{ // liczymy proporcj<63>
|
||
double d = Axle0.GetTranslation(); // aktualne po<70>o<EFBFBD>enie na torze
|
||
if (Axle0.GetDirection() < 0)
|
||
d = t0->fTrackLength - d; // od drugiej strony liczona d<>ugo<67><6F>
|
||
d /= fAxleDist; // rozsataw osi procentowe znajdowanie si<73> na torze
|
||
switch (t0->eEnvironment)
|
||
{ // typ zmiany o<>wietlenia - zak<61>adam, <20>e
|
||
// drugi tor ma e_flat
|
||
case e_canyon:
|
||
fShade = (d * 0.65) + (1.0 - d);
|
||
break; // zacienienie w kanionie
|
||
case e_tunnel:
|
||
fShade = (d * 0.20) + (1.0 - d);
|
||
break; // zacienienie w tunelu
|
||
}
|
||
switch (t1->eEnvironment)
|
||
{ // typ zmiany o<>wietlenia - zak<61>adam, <20>e
|
||
// pierwszy tor ma e_flat
|
||
case e_canyon:
|
||
fShade = d + (1.0 - d) * 0.65;
|
||
break; // zacienienie w kanionie
|
||
case e_tunnel:
|
||
fShade = d + (1.0 - d) * 0.20;
|
||
break; // zacienienie w tunelu
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
};
|
||
|
||
void TDynamicObject::AttachPrev(TDynamicObject *Object, int iType)
|
||
{ // Ra: doczepia Object na ko<6B>cu
|
||
// sk<73>adu (nazwa funkcji mo<6D>e by<62>
|
||
// myl<79>ca)
|
||
// Ra: u<>ywane tylko przy wczytywaniu scenerii
|
||
/*
|
||
//Ra: po wstawieniu pojazdu do scenerii nie mia<69> on ustawionej pozycji, teraz
|
||
ju<6A> ma
|
||
TLocation loc;
|
||
loc.X=-vPosition.x;
|
||
loc.Y=vPosition.z;
|
||
loc.Z=vPosition.y;
|
||
MoverParameters->Loc=loc; //Ra: do obliczania sprz<72>g<EFBFBD>w, na starcie nie s<>
|
||
przesuni<6E>te
|
||
loc.X=-Object->vPosition.x;
|
||
loc.Y=Object->vPosition.z;
|
||
loc.Z=Object->vPosition.y;
|
||
Object->MoverParameters->Loc=loc; //ustawienie dodawanego pojazdu
|
||
*/
|
||
MoverParameters->Attach(iDirection, Object->iDirection ^ 1, Object->MoverParameters, iType,
|
||
true);
|
||
MoverParameters->Couplers[iDirection].Render = false;
|
||
Object->MoverParameters->Attach(Object->iDirection ^ 1, iDirection, MoverParameters, iType,
|
||
true);
|
||
Object->MoverParameters->Couplers[Object->iDirection ^ 1].Render =
|
||
true; // rysowanie sprz<72>gu w do<64><6F>czanym
|
||
if (iDirection)
|
||
{ //<2F><>czenie standardowe
|
||
NextConnected = Object; // normalnie doczepiamy go sobie do sprz<72>gu 1
|
||
NextConnectedNo = Object->iDirection ^ 1;
|
||
}
|
||
else
|
||
{ //<2F><>czenie odwrotne
|
||
PrevConnected = Object; // doczepiamy go sobie do sprz<72>gu 0, gdy stoimy odwrotnie
|
||
PrevConnectedNo = Object->iDirection ^ 1;
|
||
}
|
||
if (Object->iDirection)
|
||
{ // do<64><6F>czany jest normalnie ustawiany
|
||
Object->PrevConnected = this; // on ma nas z przodu
|
||
Object->PrevConnectedNo = iDirection;
|
||
}
|
||
else
|
||
{ // do<64><6F>czany jest odwrotnie ustawiany
|
||
Object->NextConnected = this; // on ma nas z ty<74>u
|
||
Object->NextConnectedNo = iDirection;
|
||
}
|
||
if (MoverParameters->TrainType & dt_EZT) // w przypadku <20><>czenia cz<63>on<6F>w,
|
||
// <20>wiat<61>a w rozrz<72>dczym zale<6C><65> od
|
||
// stanu w silnikowym
|
||
if (MoverParameters->Couplers[iDirection].AllowedFlag &
|
||
ctrain_depot) // gdy sprz<72>gi <20><>czone warsztatowo (powiedzmy)
|
||
if ((MoverParameters->Power < 1.0) &&
|
||
(Object->MoverParameters->Power > 1.0)) // my nie mamy mocy, ale ten drugi ma
|
||
iLights = Object->MoverParameters->iLights; // to w tym z moc<6F> b<>d<EFBFBD> <20>wiat<61>a
|
||
// za<7A><61>czane, a w tym bez tylko widoczne
|
||
else if ((MoverParameters->Power > 1.0) &&
|
||
(Object->MoverParameters->Power < 1.0)) // my mamy moc, ale ten drugi nie ma
|
||
Object->iLights = MoverParameters->iLights; // to w tym z moc<6F> b<>d<EFBFBD> <20>wiat<61>a
|
||
// za<7A><61>czane, a w tym bez tylko widoczne
|
||
return;
|
||
// SetPneumatic(1,1); //Ra: to i tak si<73> nie wykonywa<77>o po return
|
||
// SetPneumatic(1,0);
|
||
// SetPneumatic(0,1);
|
||
// SetPneumatic(0,0);
|
||
}
|
||
|
||
bool TDynamicObject::UpdateForce(double dt, double dt1, bool FullVer)
|
||
{
|
||
if (!bEnabled)
|
||
return false;
|
||
if (dt > 0)
|
||
MoverParameters->ComputeTotalForce(dt, dt1,
|
||
FullVer); // wywalenie WS zale<6C>y od ustawienia kierunku
|
||
return true;
|
||
}
|
||
|
||
void TDynamicObject::LoadUpdate()
|
||
{ // prze<7A>adowanie modelu <20>adunku
|
||
// Ra: nie pr<70>bujemy wczytywa<77> modeli miliony razy podczas renderowania!!!
|
||
if ((mdLoad == NULL) && (MoverParameters->Load > 0))
|
||
{
|
||
std::string asLoadName =
|
||
asBaseDir + MoverParameters->LoadType + ".t3d"; // zapami<6D>tany katalog pojazdu
|
||
// asLoadName=MoverParameters->LoadType;
|
||
// if (MoverParameters->LoadType!=AnsiString("passengers"))
|
||
Global::asCurrentTexturePath = asBaseDir; // bie<69><65>ca <20>cie<69>ka do tekstur to dynamic/...
|
||
mdLoad = TModelsManager::GetModel(asLoadName.c_str()); // nowy <20>adunek
|
||
Global::asCurrentTexturePath =
|
||
std::string(szTexturePath); // z powrotem defaultowa sciezka do tekstur
|
||
// Ra: w MMD mo<6D>na by zapisa<73> po<70>o<EFBFBD>enie modelu <20>adunku (np. w<>giel) w
|
||
// zale<6C>no<6E>ci od
|
||
// za<7A>adowania
|
||
}
|
||
else if (MoverParameters->Load == 0)
|
||
mdLoad = NULL; // nie ma <20>adunku
|
||
// if ((mdLoad==NULL)&&(MoverParameters->Load>0))
|
||
// {
|
||
// mdLoad=NULL; //Ra: to jest tu bez sensu - co autor mia<69> na my<6D>li?
|
||
// }
|
||
MoverParameters->LoadStatus &= 3; // po zako<6B>czeniu b<>dzie r<>wne zero
|
||
};
|
||
|
||
/*
|
||
double ComputeRadius(double p1x, double p1z, double p2x, double p2z,
|
||
double p3x, double p3z, double p4x, double p4z)
|
||
{
|
||
|
||
double v1z= p1x-p2x;
|
||
double v1x= p1z-p2z;
|
||
double v4z= p3x-p4x;
|
||
double v4x= p3z-p4z;
|
||
double A1= p2z-p1z;
|
||
double B1= p1x-p2x;
|
||
double C1= -p1z*B1-p1x*A1;
|
||
double A2= p4z-p3z;
|
||
double B2= p3x-p4x;
|
||
double C2= -p3z*B1-p3x*A1;
|
||
double y= (A1*C2/A2-C1)/(B1-A1*B2/A2);
|
||
double x= (-B2*y-C2)/A2;
|
||
}
|
||
*/
|
||
double TDynamicObject::ComputeRadius(vector3 p1, vector3 p2, vector3 p3, vector3 p4)
|
||
{
|
||
// vector3 v1
|
||
|
||
// TLine l1= TLine(p1,p1-p2);
|
||
// TLine l4= TLine(p4,p4-p3);
|
||
// TPlane p1= l1.GetPlane();
|
||
// vector3 pt;
|
||
// CrossPoint(pt,l4,p1);
|
||
double R = 0.0;
|
||
vector3 p12 = p1 - p2;
|
||
vector3 p34 = p3 - p4;
|
||
p12 = CrossProduct(p12, vector3(0.0, 0.1, 0.0));
|
||
p12 = Normalize(p12);
|
||
p34 = CrossProduct(p34, vector3(0.0, 0.1, 0.0));
|
||
p34 = Normalize(p34);
|
||
if (fabs(p1.x - p2.x) > 0.01)
|
||
{
|
||
if (fabs(p12.x - p34.x) > 0.001)
|
||
R = (p1.x - p4.x) / (p34.x - p12.x);
|
||
}
|
||
else
|
||
{
|
||
if (fabs(p12.z - p34.z) > 0.001)
|
||
R = (p1.z - p4.z) / (p34.z - p12.z);
|
||
}
|
||
return (R);
|
||
}
|
||
|
||
/*
|
||
double TDynamicObject::ComputeRadius()
|
||
{
|
||
double L=0;
|
||
double d=0;
|
||
d=sqrt(SquareMagnitude(Axle0.pPosition-Axle1.pPosition));
|
||
L=Axle1.GetLength(Axle1.pPosition,Axle1.pPosition-Axle2.pPosition,Axle0.pPosition-Axle3.pPosition,Axle0.pPosition);
|
||
|
||
double eps=0.01;
|
||
double R= 0;
|
||
double L_d;
|
||
if ((L>0) || (d>0))
|
||
{
|
||
L_d= L-d;
|
||
if (L_d>eps)
|
||
{
|
||
R=L*sqrt(L/(24*(L_d)));
|
||
}
|
||
}
|
||
return R;
|
||
}
|
||
*/
|
||
|
||
/* Ra: na razie nie potrzebne
|
||
void TDynamicObject::UpdatePos()
|
||
{
|
||
MoverParameters->Loc.X= -vPosition.x;
|
||
MoverParameters->Loc.Y= vPosition.z;
|
||
MoverParameters->Loc.Z= vPosition.y;
|
||
}
|
||
*/
|
||
|
||
/*
|
||
Ra:
|
||
Powinny by<62> dwie funkcje wykonuj<75>ce aktualizacj<63> fizyki. Jedna wykonuj<75>ca
|
||
krok oblicze<7A>, powtarzana odpowiedni<6E> liczb<7A> razy, a druga wykonuj<75>ca zbiorcz<63>
|
||
aktualzacj<EFBFBD> mniej istotnych element<6E>w.
|
||
Ponadto nale<6C>a<EFBFBD>o by ustali<6C> odleg<65>o<EFBFBD><6F> sk<73>ad<61>w od kamery i je<6A>li przekracza
|
||
ona np. 10km, to traktowa<77> sk<73>ady jako uproszczone, np. bez wnikania w si<73>y
|
||
na sprz<72>gach, op<6F><70>nienie dzia<69>ania hamulca itp. Oczywi<77>cie musi mie<69> to pewn<77>
|
||
histerez<EFBFBD> czasow<6F>, aby te tryby pracy nie prze<7A><65>cza<7A>y si<73> zbyt szybko.
|
||
*/
|
||
|
||
bool TDynamicObject::Update(double dt, double dt1)
|
||
{
|
||
if (dt == 0)
|
||
return true; // Ra: pauza
|
||
if (!MoverParameters->PhysicActivation &&
|
||
!MechInside) // to drugie, bo b<>d<EFBFBD>c w maszynowym blokuje si<73> fizyka
|
||
return true; // McZapkie: wylaczanie fizyki gdy nie potrzeba
|
||
if (!MyTrack)
|
||
return false; // pojazdy postawione na torach portalowych maj<61> MyTrack==NULL
|
||
if (!bEnabled)
|
||
return false; // a normalnie powinny mie<69> bEnabled==false
|
||
|
||
// Ra: przenios<6F>em - no ju<6A> lepiej tu, ni<6E> w wy<77>wietlaniu!
|
||
// if ((MoverParameters->ConverterFlag==false) &&
|
||
// (MoverParameters->TrainType!=dt_ET22))
|
||
// Ra: to nie mo<6D>e tu by<62>, bo wy<77><79>cza spr<70><72>ark<72> w rozrz<72>dczym EZT!
|
||
// if
|
||
// ((MoverParameters->ConverterFlag==false)&&(MoverParameters->CompressorPower!=0))
|
||
// MoverParameters->CompressorFlag=false;
|
||
// if (MoverParameters->CompressorPower==2)
|
||
// MoverParameters->CompressorAllow=MoverParameters->ConverterFlag;
|
||
|
||
// McZapkie-260202
|
||
if ((MoverParameters->EnginePowerSource.SourceType == CurrentCollector) &&
|
||
(MoverParameters->Power > 1.0)) // aby rozrz<72>dczy nie opuszcza<7A> silnikowemu
|
||
if ((MechInside) || (MoverParameters->TrainType == dt_EZT))
|
||
{
|
||
// if
|
||
// ((!MoverParameters->PantCompFlag)&&(MoverParameters->CompressedVolume>=2.8))
|
||
// MoverParameters->PantVolume=MoverParameters->CompressedVolume;
|
||
if (MoverParameters->PantPress < (MoverParameters->TrainType == dt_EZT ? 2.4 : 3.5))
|
||
{ // 3.5 wg
|
||
// http://www.transportszynowy.pl/eu06-07pneumat.php
|
||
//"Wy<57><79>czniki ci<63>nieniowe odbierak<61>w pr<70>du wy<77><79>czaj<61> sterowanie
|
||
// wy<77><79>cznika szybkiego
|
||
// oraz uniemo<6D>liwiaj<61> podniesienie odbierak<61>w pr<70>du, gdy w instalacji
|
||
// rozrz<72>du
|
||
// ci<63>nienie spadnie poni<6E>ej warto<74>ci 3,5 bara."
|
||
// Ra 2013-12: Niebugoc<6F>aw m<>wi, <20>e w EZT podnosz<73> si<73> przy 2.5
|
||
// if (!MoverParameters->PantCompFlag)
|
||
// MoverParameters->PantVolume=MoverParameters->CompressedVolume;
|
||
MoverParameters->PantFront(false); // opuszczenie pantograf<61>w przy niskim ci<63>nieniu
|
||
MoverParameters->PantRear(false); // to idzie w ukrotnieniu, a nie powinno...
|
||
}
|
||
// Winger - automatyczne wylaczanie malej sprezarki
|
||
else if (MoverParameters->PantPress >= 4.8)
|
||
MoverParameters->PantCompFlag = false;
|
||
} // Ra: do Mover to trzeba przenie<69><65>, <20>eby AI te<74> mog<6F>o sobie podpompowa<77>
|
||
|
||
double dDOMoveLen;
|
||
|
||
TLocation l;
|
||
l.X = -vPosition.x; // przekazanie pozycji do fizyki
|
||
l.Y = vPosition.z;
|
||
l.Z = vPosition.y;
|
||
TRotation r;
|
||
r.Rx = r.Ry = r.Rz = 0;
|
||
// McZapkie: parametry powinny byc pobierane z toru
|
||
|
||
// TTrackShape ts;
|
||
// ts.R=MyTrack->fRadius;
|
||
// if (ABuGetDirection()<0) ts.R=-ts.R;
|
||
// ts.R=MyTrack->fRadius; //ujemne promienie s<> ju<6A> zamienione przy
|
||
// wczytywaniu
|
||
if (Axle0.vAngles.z != Axle1.vAngles.z)
|
||
{ // wyliczenie promienia z obrot<6F>w
|
||
// osi - modyfikacj<63> zg<7A>osi<73> youBy
|
||
ts.R = Axle0.vAngles.z - Axle1.vAngles.z; // r<><72>nica mo<6D>e dawa<77> sta<74><61> <20>M_2PI
|
||
if (ts.R > M_PI)
|
||
ts.R -= M_2PI else if (ts.R < -M_PI) ts.R += M_2PI; // normalizacja
|
||
// ts.R=fabs(0.5*MoverParameters->BDist/sin(ts.R*0.5));
|
||
ts.R = -0.5 * MoverParameters->BDist / sin(ts.R * 0.5);
|
||
if ((ts.R > 15000.0) || (ts.R < -15000.0))
|
||
ts.R = 0.0; // szkoda czasu na zbyt du<64>e promienie, 4km to promie<69> nie
|
||
// wymagaj<61>cy
|
||
// przechy<68>ki
|
||
}
|
||
else
|
||
ts.R = 0.0;
|
||
// ts.R=ComputeRadius(Axle1.pPosition,Axle2.pPosition,Axle3.pPosition,Axle0.pPosition);
|
||
// Ra: sk<73>adow<6F> pochylenia wzd<7A>u<EFBFBD>nego mamy policzon<6F> w jednostkowym wektorze
|
||
// vFront
|
||
ts.Len = 1.0; // Max0R(MoverParameters->BDist,MoverParameters->ADist);
|
||
ts.dHtrack = -vFront.y; // Axle1.pPosition.y-Axle0.pPosition.y; //wektor
|
||
// mi<6D>dzy skrajnymi osiami
|
||
// (!!!odwrotny)
|
||
ts.dHrail = (Axle1.GetRoll() + Axle0.GetRoll()) * 0.5; //<2F>rednia przechy<68>ka pud<75>a
|
||
// TTrackParam tp;
|
||
tp.Width = MyTrack->fTrackWidth;
|
||
// McZapkie-250202
|
||
tp.friction = MyTrack->fFriction * Global::fFriction;
|
||
tp.CategoryFlag = MyTrack->iCategoryFlag & 15;
|
||
tp.DamageFlag = MyTrack->iDamageFlag;
|
||
tp.QualityFlag = MyTrack->iQualityFlag;
|
||
if ((MoverParameters->Couplers[0].CouplingFlag > 0) &&
|
||
(MoverParameters->Couplers[1].CouplingFlag > 0))
|
||
{
|
||
MoverParameters->InsideConsist = true;
|
||
}
|
||
else
|
||
{
|
||
MoverParameters->InsideConsist = false;
|
||
}
|
||
// napiecie sieci trakcyjnej
|
||
// Ra 15-01: przeliczenie poboru pr<70>du powinno by<62> robione wcze<7A>niej, <20>eby na
|
||
// tym etapie by<62>y
|
||
// znane napi<70>cia
|
||
// TTractionParam tmpTraction;
|
||
// tmpTraction.TractionVoltage=0;
|
||
if (MoverParameters->EnginePowerSource.SourceType == CurrentCollector)
|
||
{ // dla EZT tylko silnikowy
|
||
// if (Global::bLiveTraction)
|
||
{ // Ra 2013-12: to ni<6E>ej jest chyba troch<63> bez sensu
|
||
double v = MoverParameters->PantRearVolt;
|
||
if (v == 0.0)
|
||
{
|
||
v = MoverParameters->PantFrontVolt;
|
||
if (v == 0.0)
|
||
if ((MoverParameters->TrainType & (dt_EZT | dt_ET40 | dt_ET41 | dt_ET42)) &&
|
||
MoverParameters->EngineType !=
|
||
ElectricInductionMotor) // dwucz<63>ony mog<6F> mie<69> sprz<72>g WN
|
||
v = MoverParameters->GetTrainsetVoltage(); // ostatnia szansa
|
||
}
|
||
if (v != 0.0)
|
||
{ // je<6A>li jest zasilanie
|
||
NoVoltTime = 0;
|
||
tmpTraction.TractionVoltage = v;
|
||
}
|
||
else
|
||
{
|
||
/*
|
||
if (MoverParameters->Vel>0.1f) //je<6A>li jedzie
|
||
if (NoVoltTime==0.0) //tylko przy pierwszym zaniku napi<70>cia
|
||
if (MoverParameters->PantFrontUp||MoverParameters->PantRearUp)
|
||
//if
|
||
((pants[0].fParamPants->PantTraction>1.0)||(pants[1].fParamPants->PantTraction>1.0))
|
||
{//wspomagacz usuwania problem<65>w z sieci<63>
|
||
if (!Global::iPause)
|
||
{//Ra: tymczasowa teleportacja do miejsca, gdzie brakuje pr<70>du
|
||
Global::SetCameraPosition(vPosition+vector3(0,0,5)); //nowa
|
||
pozycja dla
|
||
generowania obiekt<6B>w
|
||
Global::pCamera->Init(vPosition+vector3(0,0,5),Global::pFreeCameraInitAngle[0]);
|
||
//przestawienie
|
||
}
|
||
Global:l::pGround->Silence(Global::pCamera->Pos); //wyciszenie
|
||
wszystkiego
|
||
z poprzedniej pozycji
|
||
Globa:iPause|=1; //tymczasowe zapauzowanie, gdy problem z
|
||
sieci<63>
|
||
}
|
||
*/
|
||
NoVoltTime = NoVoltTime + dt;
|
||
if (NoVoltTime > 0.2) // je<6A>li brak zasilania d<>u<EFBFBD>ej ni<6E> 0.2 sekundy (25km/h pod
|
||
// izolatorem daje 0.15s)
|
||
{ // Ra 2F1H: prowizorka, trzeba przechowa<77> napi<70>cie, <20>eby nie wywala<6C>o
|
||
// WS pod
|
||
// izolatorem
|
||
if (MoverParameters->Vel > 0.5) // je<6A>li jedzie
|
||
if (MoverParameters->PantFrontUp ||
|
||
MoverParameters->PantRearUp) // Ra 2014-07: dora<72>na blokada logowania
|
||
// zimnych lokomotyw - zrobi<62> to trzeba
|
||
// inaczej
|
||
// if (NoVoltTime>0.02) //tu mo<6D>na ograniczy<7A> czas roz<6F><7A>czenia
|
||
// if (DebugModeFlag) //logowanie nie zawsze
|
||
if ((MoverParameters->Mains) &&
|
||
((MoverParameters->EngineType != ElectricInductionMotor)
|
||
|| (MoverParameters->GetTrainsetVoltage() < 0.1f)))
|
||
{ // Ra 15-01: logowa<77> tylko, je<6A>li WS za<7A><61>czony
|
||
// yB 16-03: i nie jest to asynchron zasilany z daleka
|
||
// if (MoverParameters->PantFrontUp&&pants)
|
||
// Ra 15-01: bezwzgl<67>dne wsp<73><70>rz<72>dne pantografu nie s<> dost<73>pne,
|
||
// wi<77>c lepiej si<73> tego nie zaloguje
|
||
ErrorLog("Voltage loss: by " + MoverParameters->Name + " at " +
|
||
to_string(vPosition.x, 2, 7) + " " +
|
||
to_string(vPosition.y, 2, 7) + " " +
|
||
to_string(vPosition.z, 2, 7) + ", time " +
|
||
to_string(NoVoltTime, 2, 7));
|
||
// if (MoverParameters->PantRearUp)
|
||
// if (iAnimType[ANIM_PANTS]>1)
|
||
// if (pants[1])
|
||
// ErrorLog("Voltage loss: by "+MoverParameters->Name+" at
|
||
// "+FloatToStrF(vPosition.x,ffFixed,7,2)+"
|
||
// "+FloatToStrF(vPosition.y,ffFixed,7,2)+"
|
||
// "+FloatToStrF(vPosition.z,ffFixed,7,2)+", time
|
||
// "+FloatToStrF(NoVoltTime,ffFixed,7,2));
|
||
}
|
||
// Ra 2F1H: nie by<62>o sensu wpisywa<77> tu zera po up<75>ywie czasu, bo
|
||
// zmienna by<62>a
|
||
// tymczasowa, a napi<70>cie zerowane od razu
|
||
tmpTraction.TractionVoltage = 0; // Ra 2013-12: po co tak?
|
||
// pControlled->MainSwitch(false); //mo<6D>e tak?
|
||
}
|
||
}
|
||
}
|
||
// else //Ra: nie no, trzeba podnie<69><65> pantografy, jak nie b<>dzie drutu, to
|
||
// b<>d<EFBFBD> mia<69>y pr<70>d
|
||
// po osi<73>gni<6E>ciu 1.4m
|
||
// tmpTraction.TractionVoltage=0.95*MoverParameters->EnginePowerSource.MaxVoltage;
|
||
}
|
||
else
|
||
tmpTraction.TractionVoltage = 0.95 * MoverParameters->EnginePowerSource.MaxVoltage;
|
||
tmpTraction.TractionFreq = 0;
|
||
tmpTraction.TractionMaxCurrent = 7500; // Ra: chyba za du<64>o? powinno wywala<6C> przy 1500
|
||
tmpTraction.TractionResistivity = 0.3;
|
||
|
||
// McZapkie: predkosc w torze przekazac do TrackParam
|
||
// McZapkie: Vel ma wymiar [km/h] (absolutny), V ma wymiar [m/s], taka
|
||
// przyjalem notacje
|
||
tp.Velmax = MyTrack->VelocityGet();
|
||
|
||
if (Mechanik)
|
||
{ // Ra 2F3F: do Driver.cpp to przenie<69><65>?
|
||
MoverParameters->EqvtPipePress = GetEPP(); // srednie cisnienie w PG
|
||
if ((Mechanik->Primary()) &&
|
||
(MoverParameters->EngineType == ElectricInductionMotor)) // jesli glowny i z
|
||
// asynchronami, to
|
||
// niech steruje
|
||
{ // hamulcem lacznie dla calego pociagu/ezt
|
||
bool kier = (DirectionGet() * MoverParameters->ActiveCab > 0);
|
||
float FED = 0;
|
||
int np = 0;
|
||
float masa = 0;
|
||
float FrED = 0;
|
||
float masamax = 0;
|
||
float FmaxPN = 0;
|
||
float FfulED = 0;
|
||
float FmaxED = 0;
|
||
float Fzad = 0;
|
||
float FzadED = 0;
|
||
float FzadPN = 0;
|
||
float Frj = 0;
|
||
float amax = 0;
|
||
float osie = 0;
|
||
// 1. ustal wymagana sile hamowania calego pociagu
|
||
// - opoznienie moze byc ustalane na podstawie charakterystyki
|
||
// - opoznienie moze byc ustalane na podstawie mas i cisnien granicznych
|
||
//
|
||
|
||
// 2. ustal mozliwa do realizacji sile hamowania ED
|
||
// - w szczegolnosci powinien brac pod uwage rozne sily hamowania
|
||
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
||
(kier ? p = p->NextC(4) : p = p->PrevC(4)))
|
||
{
|
||
np++;
|
||
masamax += p->MoverParameters->MBPM +
|
||
(p->MoverParameters->MBPM > 1 ? 0 : p->MoverParameters->Mass) +
|
||
p->MoverParameters->Mred;
|
||
float Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] -
|
||
p->MoverParameters->BrakeCylSpring) *
|
||
p->MoverParameters->BrakeCylMult[0] -
|
||
p->MoverParameters->BrakeSlckAdj) *
|
||
p->MoverParameters->BrakeCylNo * p->MoverParameters->BrakeRigEff;
|
||
FmaxPN += Nmax * p->MoverParameters->Hamulec->GetFC(
|
||
Nmax / (p->MoverParameters->NAxles * p->MoverParameters->NBpA),
|
||
p->MoverParameters->Vmax) *
|
||
1000; // sila hamowania pn
|
||
FmaxED += ((p->MoverParameters->Mains) && (p->MoverParameters->ActiveDir != 0) &&
|
||
(p->MoverParameters->eimc[eimc_p_Fh] * p->MoverParameters->NPoweredAxles >
|
||
0) ?
|
||
p->MoverParameters->eimc[eimc_p_Fh] * 1000 :
|
||
0); // chwilowy max ED -> do rozdzialu sil
|
||
FED -= Min0R(p->MoverParameters->eimv[eimv_Fmax], 0) *
|
||
1000; // chwilowy max ED -> do rozdzialu sil
|
||
FfulED = Min0R(p->MoverParameters->eimv[eimv_Fful], 0) *
|
||
1000; // chwilowy max ED -> do rozdzialu sil
|
||
FrED -= Min0R(p->MoverParameters->eimv[eimv_Fr], 0) *
|
||
1000; // chwilowo realizowane ED -> do pneumatyki
|
||
Frj += Max0R(p->MoverParameters->eimv[eimv_Fr], 0) *
|
||
1000;// chwilowo realizowany nap<61>d -> do utrzymuj<75>cego
|
||
masa += p->MoverParameters->TotalMass;
|
||
osie += p->MoverParameters->NAxles;
|
||
}
|
||
amax = FmaxPN / masamax;
|
||
if ((MoverParameters->Vel < 0.5) && (MoverParameters->BrakePress > 0.2) ||
|
||
(dDoorMoveL > 0.001) || (dDoorMoveR > 0.001))
|
||
{
|
||
MoverParameters->ShuntMode = true;
|
||
}
|
||
if (MoverParameters->ShuntMode)
|
||
{
|
||
MoverParameters->ShuntModeAllow = (dDoorMoveL < 0.001) && (dDoorMoveR < 0.001) &&
|
||
(MoverParameters->LocalBrakeRatio() < 0.01);
|
||
}
|
||
if ((MoverParameters->Vel > 1) && (dDoorMoveL < 0.001) && (dDoorMoveR < 0.001))
|
||
{
|
||
MoverParameters->ShuntMode = false;
|
||
MoverParameters->ShuntModeAllow = (MoverParameters->BrakePress > 0.2) &&
|
||
(MoverParameters->LocalBrakeRatio() < 0.01);
|
||
}
|
||
Fzad = amax * MoverParameters->LocalBrakeRatio() * masa;
|
||
if ((MoverParameters->ScndS) &&
|
||
(MoverParameters->Vel > MoverParameters->eimc[eimc_p_Vh1]) && (FmaxED > 0))
|
||
{
|
||
Fzad = Min0R(MoverParameters->LocalBrakeRatio() * FmaxED, FfulED);
|
||
}
|
||
if (((MoverParameters->ShuntMode) && (Frj < 0.0015 * masa)) ||
|
||
(MoverParameters->V * MoverParameters->DirAbsolute < -0.2))
|
||
{
|
||
Fzad = Max0R(MoverParameters->StopBrakeDecc * masa, Fzad);
|
||
}
|
||
|
||
if (MoverParameters->BrakeHandle == MHZ_EN57?MoverParameters->BrakeOpModeFlag & bom_MED:MoverParameters->EpFuse)
|
||
FzadED = Min0R(Fzad, FmaxED);
|
||
else
|
||
FzadED = 0;
|
||
FzadPN = Fzad - FrED;
|
||
//np = 0;
|
||
bool* PrzekrF = new bool[np];
|
||
float nPrzekrF = 0;
|
||
bool test = true;
|
||
float* FzED = new float[np];
|
||
float* FzEP = new float[np];
|
||
float* FmaxEP = new float[np];
|
||
// 3. ustaw pojazdom sile hamowania ED
|
||
// - proporcjonalnie do mozliwosci
|
||
|
||
// 4. ustal potrzebne dohamowanie pneumatyczne
|
||
// - od sily zadanej trzeba odjac realizowana przez ED
|
||
// 5. w razie potrzeby wlacz hamulec utrzymujacy
|
||
// - gdy zahamowany ma ponizej 2 km/h
|
||
// 6. ustaw pojazdom sile hamowania ep
|
||
// - proporcjonalnie do masy, do liczby osi, rowne cisnienia - jak
|
||
// bedzie, tak bedzie dobrze
|
||
float Fpoj = 0; // MoverParameters->ActiveCab < 0
|
||
////ALGORYTM 2 - KAZDEMU PO ROWNO, ale nie wiecej niz eped * masa
|
||
// 1. najpierw daj kazdemu tyle samo
|
||
int i = 0;
|
||
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
||
(kier > 0 ? p = p->NextC(4) : p = p->PrevC(4)))
|
||
{
|
||
float Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] -
|
||
p->MoverParameters->BrakeCylSpring) *
|
||
p->MoverParameters->BrakeCylMult[0] -
|
||
p->MoverParameters->BrakeSlckAdj) *
|
||
p->MoverParameters->BrakeCylNo * p->MoverParameters->BrakeRigEff;
|
||
FmaxEP[i] = Nmax *
|
||
p->MoverParameters->Hamulec->GetFC(
|
||
Nmax / (p->MoverParameters->NAxles * p->MoverParameters->NBpA),
|
||
p->MoverParameters->Vmax) *
|
||
1000; // sila hamowania pn
|
||
|
||
PrzekrF[i] = false;
|
||
FzED[i] = (FmaxED > 0 ? FzadED / FmaxED : 0);
|
||
p->MoverParameters->AnPos =
|
||
(MoverParameters->ScndS ? MoverParameters->LocalBrakeRatio() : FzED[i]);
|
||
FzEP[i] = FzadPN * p->MoverParameters->NAxles / osie;
|
||
i++;
|
||
p->MoverParameters->ShuntMode = MoverParameters->ShuntMode;
|
||
p->MoverParameters->ShuntModeAllow = MoverParameters->ShuntModeAllow;
|
||
}
|
||
while (test)
|
||
{
|
||
test = false;
|
||
i = 0;
|
||
float przek = 0;
|
||
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
||
(kier > 0 ? p = p->NextC(4) : p = p->PrevC(4)))
|
||
{
|
||
if ((FzEP[i] > 0.01) &&
|
||
(FzEP[i] >
|
||
p->MoverParameters->TotalMass * p->MoverParameters->eimc[eimc_p_eped] +
|
||
Min0R(p->MoverParameters->eimv[eimv_Fr], 0) * 1000) &&
|
||
(!PrzekrF[i]))
|
||
{
|
||
float przek1 = -Min0R(p->MoverParameters->eimv[eimv_Fr], 0) * 1000 +
|
||
FzEP[i] -
|
||
p->MoverParameters->TotalMass *
|
||
p->MoverParameters->eimc[eimc_p_eped] * 0.999;
|
||
PrzekrF[i] = true;
|
||
test = true;
|
||
nPrzekrF++;
|
||
przek1 = Min0R(przek1, FzEP[i]);
|
||
FzEP[i] -= przek1;
|
||
if (FzEP[i] < 0)
|
||
FzEP[i] = 0;
|
||
przek += przek1;
|
||
}
|
||
i++;
|
||
}
|
||
i = 0;
|
||
przek = przek / (np - nPrzekrF);
|
||
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
||
(kier > 0 ? p = p->NextC(4) : p = p->PrevC(4)))
|
||
{
|
||
if (!PrzekrF[i])
|
||
{
|
||
FzEP[i] += przek;
|
||
}
|
||
i++;
|
||
}
|
||
}
|
||
i = 0;
|
||
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0, 4); p;
|
||
(kier > 0 ? p = p->NextC(4) : p = p->PrevC(4)))
|
||
{
|
||
float Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] -
|
||
p->MoverParameters->BrakeCylSpring) *
|
||
p->MoverParameters->BrakeCylMult[0] -
|
||
p->MoverParameters->BrakeSlckAdj) *
|
||
p->MoverParameters->BrakeCylNo * p->MoverParameters->BrakeRigEff;
|
||
float FmaxPoj = Nmax *
|
||
p->MoverParameters->Hamulec->GetFC(
|
||
Nmax / (p->MoverParameters->NAxles * p->MoverParameters->NBpA),
|
||
p->MoverParameters->Vel) *
|
||
1000; // sila hamowania pn
|
||
p->MoverParameters->LocalBrakePosA = (p->MoverParameters->SlippingWheels ? 0 : FzEP[i] / FmaxPoj);
|
||
if (p->MoverParameters->LocalBrakePosA>0.009)
|
||
if (p->MoverParameters->P2FTrans * p->MoverParameters->BrakeCylMult[0] *
|
||
p->MoverParameters->MaxBrakePress[0] != 0)
|
||
{
|
||
float x = (p->MoverParameters->BrakeSlckAdj / p->MoverParameters->BrakeCylMult[0] +
|
||
p->MoverParameters->BrakeCylSpring) / (p->MoverParameters->P2FTrans *
|
||
p->MoverParameters->MaxBrakePress[0]);
|
||
p->MoverParameters->LocalBrakePosA = x + (1 - x) * p->MoverParameters->LocalBrakePosA;
|
||
}
|
||
else
|
||
p->MoverParameters->LocalBrakePosA = p->MoverParameters->LocalBrakePosA;
|
||
else
|
||
p->MoverParameters->LocalBrakePosA = 0;
|
||
i++;
|
||
}
|
||
/* ////ALGORYTM 1 - KAZDEMU PO ROWNO
|
||
for (TDynamicObject *p = GetFirstDynamic(MoverParameters->ActiveCab < 0 ? 1 : 0); p;
|
||
(iDirection > 0 ? p = p->NextC(4) : p = p->PrevC(4)))
|
||
{
|
||
|
||
float Nmax = ((p->MoverParameters->P2FTrans * p->MoverParameters->MaxBrakePress[0] -
|
||
p->MoverParameters->BrakeCylSpring) *
|
||
p->MoverParameters->BrakeCylMult[0] -
|
||
p->MoverParameters->BrakeSlckAdj) *
|
||
p->MoverParameters->BrakeCylNo * p->MoverParameters->BrakeRigEff;
|
||
float FmaxPoj = Nmax *
|
||
p->MoverParameters->Hamulec->GetFC(
|
||
Nmax / (p->MoverParameters->NAxles * p->MoverParameters->NBpA),
|
||
p->MoverParameters->Vel) *
|
||
1000; // sila hamowania pn
|
||
// Fpoj=(FED>0?-FzadED*p->MoverParameters->eimv[eimv_Fmax]*1000/FED:0);
|
||
// p->MoverParameters->AnPos=(p->MoverParameters->eimc[eimc_p_Fh]>1?0.001f*Fpoj/(p->MoverParameters->eimc[eimc_p_Fh]):0);
|
||
p->MoverParameters->AnPos = (FmaxED > 0 ? FzadED / FmaxED : 0);
|
||
// Fpoj = FzadPN * Min0R(p->MoverParameters->TotalMass / masa, 1);
|
||
// p->MoverParameters->LocalBrakePosA =
|
||
// (p->MoverParameters->SlippingWheels ? 0 : Min0R(Max0R(Fpoj / FmaxPoj, 0), 1));
|
||
p->MoverParameters->LocalBrakePosA = (p->MoverParameters->SlippingWheels ? 0 : FzadPN / FmaxPN);
|
||
} */
|
||
|
||
MED[0][0] = masa*0.001;
|
||
MED[0][1] = amax;
|
||
MED[0][2] = Fzad*0.001;
|
||
MED[0][3] = FmaxPN*0.001;
|
||
MED[0][4] = FmaxED*0.001;
|
||
MED[0][5] = FrED*0.001;
|
||
MED[0][6] = FzadPN*0.001;
|
||
MED[0][7] = nPrzekrF;
|
||
|
||
delete[] PrzekrF;
|
||
delete[] FzED;
|
||
delete[] FzEP;
|
||
delete[] FmaxEP;
|
||
}
|
||
|
||
// yB: cos (AI) tu jest nie kompatybilne z czyms (hamulce)
|
||
// if (Controller!=Humandriver)
|
||
// if (Mechanik->LastReactionTime>0.5)
|
||
// {
|
||
// MoverParameters->BrakeCtrlPos=0;
|
||
// Mechanik->LastReactionTime=0;
|
||
// }
|
||
|
||
Mechanik->UpdateSituation(dt1); // przeb<65>yski <20>wiadomo<6D>ci AI
|
||
}
|
||
|
||
// fragment "z EXE Kursa"
|
||
if (MoverParameters->Mains) // nie wchodzi<7A> w funkcj<63> bez potrzeby
|
||
if ((!MoverParameters->Battery) && (Controller == Humandriver) &&
|
||
(MoverParameters->EngineType != DieselEngine) &&
|
||
(MoverParameters->EngineType != WheelsDriven))
|
||
{ // je<6A>li bateria wy<77><79>czona, a nie diesel ani drezyna
|
||
// reczna
|
||
if (MoverParameters->MainSwitch(false)) // wy<77><79>czy<7A> zasilanie
|
||
MoverParameters->EventFlag = true;
|
||
}
|
||
if (MoverParameters->TrainType == dt_ET42)
|
||
{ // powinny by<62> wszystkie dwucz<63>ony oraz EZT
|
||
/*
|
||
//Ra: to jest bez sensu, bo wy<77><79>cza WS przy przechodzeniu przez
|
||
"wewn<77>trzne" kabiny (z
|
||
powodu ActiveCab)
|
||
//trzeba to zrobi<62> inaczej, np. dla cz<63>onu A sprawdza<7A>, czy jest B
|
||
//albo sprawdza<7A> w momencie za<7A><61>czania WS i zmiany w sprz<72>gach
|
||
if
|
||
(((TestFlag(MoverParameters->Couplers[1].CouplingFlag,ctrain_controll))&&(MoverParameters->ActiveCab>0)&&(NextConnected->MoverParameters->TrainType!=dt_ET42))||((TestFlag(MoverParameters->Couplers[0].CouplingFlag,ctrain_controll))&&(MoverParameters->ActiveCab<0)&&(PrevConnected->MoverParameters->TrainType!=dt_ET42)))
|
||
{//sprawdzenie, czy z ty<74>u kabiny mamy drugi cz<63>on
|
||
if (MoverParameters->MainSwitch(false))
|
||
MoverParameters->EventFlag=true;
|
||
}
|
||
if
|
||
((!(TestFlag(MoverParameters->Couplers[1].CouplingFlag,ctrain_controll))&&(MoverParameters->ActiveCab>0))||(!(TestFlag(MoverParameters->Couplers[0].CouplingFlag,ctrain_controll))&&(MoverParameters->ActiveCab<0)))
|
||
{
|
||
if (MoverParameters->MainSwitch(false))
|
||
MoverParameters->EventFlag=true;
|
||
}
|
||
*/
|
||
}
|
||
|
||
// McZapkie-260202 - dMoveLen przyda sie przy stukocie kol
|
||
dDOMoveLen =
|
||
GetdMoveLen() + MoverParameters->ComputeMovement(dt, dt1, ts, tp, tmpTraction, l, r);
|
||
// yB: zeby zawsze wrzucalo w jedna strone zakretu
|
||
MoverParameters->AccN *= -ABuGetDirection();
|
||
// if (dDOMoveLen!=0.0) //Ra: nie mo<6D>e by<62>, bo blokuje Event0
|
||
Move(dDOMoveLen);
|
||
if (!bEnabled) // usuwane pojazdy nie maj<61> toru
|
||
{ // pojazd do usuni<6E>cia
|
||
Global::pGround->bDynamicRemove = true; // sprawdzi<7A>
|
||
return false;
|
||
}
|
||
Global::ABuDebug = dDOMoveLen / dt1;
|
||
ResetdMoveLen();
|
||
// McZapkie-260202
|
||
// tupot mew, tfu, stukot kol:
|
||
DWORD stat;
|
||
// taka prowizorka zeby sciszyc stukot dalekiej lokomotywy
|
||
double ObjectDist;
|
||
double vol = 0;
|
||
// double freq; //Ra: nie u<>ywane
|
||
ObjectDist = SquareMagnitude(Global::pCameraPosition - vPosition);
|
||
// McZapkie-270202
|
||
if (MyTrack->fSoundDistance != -1)
|
||
{
|
||
if (ObjectDist < rsStukot[0].dSoundAtt * rsStukot[0].dSoundAtt * 15.0)
|
||
{
|
||
vol = (20.0 + MyTrack->iDamageFlag) / 21;
|
||
if (MyTrack->eEnvironment == e_tunnel)
|
||
{
|
||
vol *= 1.1;
|
||
// freq=1.02;
|
||
}
|
||
else if (MyTrack->eEnvironment == e_bridge)
|
||
{
|
||
vol *= 1.2;
|
||
// freq=0.99; //MC: stukot w zaleznosci od
|
||
// tego gdzie
|
||
// jest tor
|
||
}
|
||
if (MyTrack->fSoundDistance != dRailLength)
|
||
{
|
||
dRailLength = MyTrack->fSoundDistance;
|
||
for (int i = 0; i < iAxles; i++)
|
||
{
|
||
dRailPosition[i] = dWheelsPosition[i] + MoverParameters->Dim.L;
|
||
}
|
||
}
|
||
if (dRailLength != -1)
|
||
{
|
||
if (abs(MoverParameters->V) > 0)
|
||
{
|
||
for (int i = 0; i < iAxles; i++)
|
||
{
|
||
dRailPosition[i] -= dDOMoveLen * Sign(dDOMoveLen);
|
||
if (dRailPosition[i] < 0)
|
||
{
|
||
// McZapkie-040302
|
||
if (i == iAxles - 1)
|
||
{
|
||
rsStukot[0].Stop();
|
||
MoverParameters->AccV +=
|
||
0.5 * GetVelocity() / (1 + MoverParameters->Vmax);
|
||
}
|
||
else
|
||
{
|
||
rsStukot[i + 1].Stop();
|
||
}
|
||
rsStukot[i].Play(vol, 0, MechInside,
|
||
vPosition); // poprawic pozycje o uklad osi
|
||
if (i == 1)
|
||
MoverParameters->AccV -=
|
||
0.5 * GetVelocity() / (1 + MoverParameters->Vmax);
|
||
dRailPosition[i] += dRailLength;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
// McZapkie-260202 end
|
||
|
||
// yB: przyspieszacz (moze zadziala, ale dzwiek juz jest)
|
||
int flag = MoverParameters->Hamulec->GetSoundFlag();
|
||
if ((bBrakeAcc) && (TestFlag(flag, sf_Acc)) && (ObjectDist < 2500))
|
||
{
|
||
sBrakeAcc->SetVolume(-ObjectDist * 3 - (FreeFlyModeFlag ? 0 : 2000));
|
||
sBrakeAcc->Play(0, 0, 0);
|
||
sBrakeAcc->SetPan(10000 * sin(ModCamRot));
|
||
}
|
||
if ((rsUnbrake.AM != 0) && (ObjectDist < 5000))
|
||
{
|
||
if ((TestFlag(flag, sf_CylU)) &&
|
||
((MoverParameters->BrakePress * MoverParameters->MaxBrakePress[3]) > 0.05))
|
||
{
|
||
vol = Min0R(
|
||
0.2 +
|
||
1.6 * sqrt((MoverParameters->BrakePress > 0 ? MoverParameters->BrakePress : 0) /
|
||
MoverParameters->MaxBrakePress[3]),
|
||
1);
|
||
vol = vol + (FreeFlyModeFlag ? 0 : -0.5) - ObjectDist / 5000;
|
||
rsUnbrake.SetPan(10000 * sin(ModCamRot));
|
||
rsUnbrake.Play(vol, DSBPLAY_LOOPING, MechInside, GetPosition());
|
||
}
|
||
else
|
||
rsUnbrake.Stop();
|
||
}
|
||
|
||
// fragment z EXE Kursa
|
||
/* if (MoverParameters->TrainType==dt_ET42)
|
||
{
|
||
if ((MoverParameters->DynamicBrakeType=dbrake_switch) &&
|
||
((MoverParameters->BrakePress >
|
||
0.2) || ( MoverParameters->PipePress < 0.36 )))
|
||
{
|
||
MoverParameters->StLinFlag=true;
|
||
}
|
||
else
|
||
if ((MoverParameters->DynamicBrakeType=dbrake_switch) &&
|
||
(MoverParameters->BrakePress <
|
||
0.1))
|
||
{
|
||
MoverParameters->StLinFlag=false;
|
||
|
||
}
|
||
} */
|
||
if ((MoverParameters->TrainType == dt_ET40) || (MoverParameters->TrainType == dt_EP05))
|
||
{ // dla ET40 i EU05 automatyczne cofanie nastawnika - i tak
|
||
// nie b<>dzie to dzia<69>a<EFBFBD> dobrze...
|
||
/* if
|
||
((MoverParameters->MainCtrlPos>MoverParameters->MainCtrlActualPos)&&(abs(MoverParameters->Im)>MoverParameters->IminHi))
|
||
{
|
||
MoverParameters->DecMainCtrl(1);
|
||
} */
|
||
if ((!Console::Pressed(Global::Keys[k_IncMainCtrl])) &&
|
||
(MoverParameters->MainCtrlPos > MoverParameters->MainCtrlActualPos))
|
||
{
|
||
MoverParameters->DecMainCtrl(1);
|
||
}
|
||
if ((!Console::Pressed(Global::Keys[k_DecMainCtrl])) &&
|
||
(MoverParameters->MainCtrlPos < MoverParameters->MainCtrlActualPos))
|
||
{
|
||
MoverParameters->IncMainCtrl(1); // Ra 15-01: a to nie mia<69>o by<62> tylko cofanie?
|
||
}
|
||
}
|
||
|
||
if (MoverParameters->Vel != 0)
|
||
{ // McZapkie-050402: krecenie kolami:
|
||
dWheelAngle[0] += 114.59155902616464175359630962821 * MoverParameters->V * dt1 /
|
||
MoverParameters->WheelDiameterL; // przednie toczne
|
||
dWheelAngle[1] += MoverParameters->nrot * dt1 * 360.0; // nap<61>dne
|
||
dWheelAngle[2] += 114.59155902616464175359630962821 * MoverParameters->V * dt1 /
|
||
MoverParameters->WheelDiameterT; // tylne toczne
|
||
if (dWheelAngle[0] > 360.0)
|
||
dWheelAngle[0] -= 360.0; // a w drug<75> stron<6F> jak si<73> kr<6B>c<EFBFBD>?
|
||
if (dWheelAngle[1] > 360.0)
|
||
dWheelAngle[1] -= 360.0;
|
||
if (dWheelAngle[2] > 360.0)
|
||
dWheelAngle[2] -= 360.0;
|
||
}
|
||
if (pants) // pantograf mo<6D>e by<62> w wagonie kuchennym albo poje<6A>dzie rewizyjnym
|
||
// (np. SR61)
|
||
{ // przeliczanie k<>t<EFBFBD>w dla pantograf<61>w
|
||
double k; // tymczasowy k<>t
|
||
double PantDiff;
|
||
TAnimPant *p; // wska<6B>nik do obiektu danych pantografu
|
||
double fCurrent = (MoverParameters->DynamicBrakeFlag && MoverParameters->ResistorsFlag ?
|
||
0 :
|
||
MoverParameters->Itot) +
|
||
MoverParameters->TotalCurrent; // pr<70>d pobierany przez pojazd - bez
|
||
// sensu z tym (TotalCurrent)
|
||
// TotalCurrent to bedzie prad nietrakcyjny (niezwiazany z napedem)
|
||
// fCurrent+=fabs(MoverParameters->Voltage)*1e-6; //pr<70>d p<>yn<79>cy przez
|
||
// woltomierz,
|
||
// roz<6F>adowuje kondensator orgromowy 4<>F
|
||
double fPantCurrent = fCurrent; // normalnie ca<63>y pr<70>d przez jeden pantograf
|
||
if (pants)
|
||
if (iAnimType[ANIM_PANTS] > 1) // a je<6A>li s<> dwa pantografy //Ra 1014-11:
|
||
// proteza, trzeba zrobi<62> sensowniej
|
||
if (pants[0].fParamPants->hvPowerWire &&
|
||
pants[1].fParamPants->hvPowerWire) // i oba pod<6F><64>czone do drut<75>w
|
||
fPantCurrent = fCurrent * 0.5; // to dzielimy pr<70>d r<>wno na oba (troch<63> bez
|
||
// sensu, ale lepiej tak ni<6E> podwoi<6F> pr<70>d)
|
||
for (int i = 0; i < iAnimType[ANIM_PANTS]; ++i)
|
||
{ // p<>tla po wszystkich pantografach
|
||
p = pants[i].fParamPants;
|
||
if (p->PantWys < 0)
|
||
{ // patograf zosta<74> po<70>amany, liczony nie b<>dzie
|
||
if (p->fAngleL > p->fAngleL0)
|
||
p->fAngleL -= 0.2 * dt1; // nieco szybciej ni<6E> jak dla opuszczania
|
||
if (p->fAngleL < p->fAngleL0)
|
||
p->fAngleL = p->fAngleL0; // k<>t graniczny
|
||
if (p->fAngleU < M_PI)
|
||
p->fAngleU += 0.5 * dt1; // g<>rne si<73> musi rusza<7A> szybciej.
|
||
if (p->fAngleU > M_PI)
|
||
p->fAngleU = M_PI;
|
||
if (i & 1) // zg<7A>oszono, <20>e po po<70>amaniu potrafi zosta<74> zasilanie
|
||
MoverParameters->PantRearVolt = 0.0;
|
||
else
|
||
MoverParameters->PantFrontVolt = 0.0;
|
||
continue; // reszta wtedy nie jest wykonywana
|
||
}
|
||
PantDiff = p->PantTraction - p->PantWys; // docelowy-aktualny
|
||
switch (i) // numer pantografu
|
||
{ // trzeba usun<75><6E> to rozr<7A><72>nienie
|
||
case 0:
|
||
if (Global::bLiveTraction ? false :
|
||
!p->hvPowerWire) // je<6A>li nie ma drutu, mo<6D>e pooszukiwa<77>
|
||
MoverParameters->PantFrontVolt =
|
||
(p->PantWys >= 1.2) ? 0.95 * MoverParameters->EnginePowerSource.MaxVoltage :
|
||
0.0;
|
||
else if (MoverParameters->PantFrontUp ? (PantDiff < 0.01) :
|
||
false) // tolerancja niedolegania
|
||
{
|
||
if ((MoverParameters->PantFrontVolt == 0.0) &&
|
||
(MoverParameters->PantRearVolt == 0.0))
|
||
sPantUp.Play(vol, 0, MechInside, vPosition);
|
||
if (p->hvPowerWire) // TODO: wyliczy<7A> trzeba pr<70>d przypadaj<61>cy na
|
||
// pantograf i
|
||
// wstawi<77> do GetVoltage()
|
||
{
|
||
MoverParameters->PantFrontVolt =
|
||
p->hvPowerWire->VoltageGet(MoverParameters->Voltage, fPantCurrent);
|
||
fCurrent -= fPantCurrent; // taki pr<70>d p<>ynie przez powy<77>szy pantograf
|
||
}
|
||
else
|
||
MoverParameters->PantFrontVolt = 0.0;
|
||
}
|
||
else
|
||
MoverParameters->PantFrontVolt = 0.0;
|
||
break;
|
||
case 1:
|
||
if (Global::bLiveTraction ? false :
|
||
!p->hvPowerWire) // je<6A>li nie ma drutu, mo<6D>e pooszukiwa<77>
|
||
MoverParameters->PantRearVolt =
|
||
(p->PantWys >= 1.2) ? 0.95 * MoverParameters->EnginePowerSource.MaxVoltage :
|
||
0.0;
|
||
else if (MoverParameters->PantRearUp ? (PantDiff < 0.01) : false)
|
||
{
|
||
if ((MoverParameters->PantRearVolt == 0.0) &&
|
||
(MoverParameters->PantFrontVolt == 0.0))
|
||
sPantUp.Play(vol, 0, MechInside, vPosition);
|
||
if (p->hvPowerWire) // TODO: wyliczy<7A> trzeba pr<70>d przypadaj<61>cy na
|
||
// pantograf i
|
||
// wstawi<77> do GetVoltage()
|
||
{
|
||
MoverParameters->PantRearVolt =
|
||
p->hvPowerWire->VoltageGet(MoverParameters->Voltage, fPantCurrent);
|
||
fCurrent -= fPantCurrent; // taki pr<70>d p<>ynie przez powy<77>szy pantograf
|
||
}
|
||
else
|
||
MoverParameters->PantRearVolt = 0.0;
|
||
}
|
||
else
|
||
MoverParameters->PantRearVolt = 0.0;
|
||
break;
|
||
} // pozosta<74>e na razie nie obs<62>ugiwane
|
||
if (MoverParameters->PantPress >
|
||
(MoverParameters->TrainType == dt_EZT ? 2.5 : 3.3)) // Ra 2013-12:
|
||
// Niebugoc<6F>aw
|
||
// m<>wi, <20>e w EZT
|
||
// podnosz<73> si<73>
|
||
// przy 2.5
|
||
pantspeedfactor = 0.015 * (MoverParameters->PantPress) *
|
||
dt1; // z EXE Kursa //Ra: wysoko<6B><6F> zale<6C>y od ci<63>nienia !!!
|
||
else
|
||
pantspeedfactor = 0.0;
|
||
if (pantspeedfactor < 0)
|
||
pantspeedfactor = 0;
|
||
k = p->fAngleL;
|
||
if (i ? MoverParameters->PantRearUp :
|
||
MoverParameters->PantFrontUp) // je<6A>li ma by<62> podniesiony
|
||
{
|
||
if (PantDiff > 0.001) // je<6A>li nie dolega do drutu
|
||
{ // je<6A>li poprzednia wysoko<6B><6F> jest mniejsza ni<6E> po<70><6F>dana, zwi<77>kszy<7A> k<>t
|
||
// dolnego
|
||
// ramienia zgodnie z ci<63>nieniem
|
||
if (pantspeedfactor >
|
||
0.55 * PantDiff) // 0.55 to oko<6B>o pochodna k<>ta po wysoko<6B>ci
|
||
k += 0.55 * PantDiff; // ograniczenie "skoku" w danej klatce
|
||
else
|
||
k += pantspeedfactor; // dolne rami<6D>
|
||
// je<6A>li przekroczono k<>t graniczny, zablokowa<77> pantograf (wymaga
|
||
// interwencji
|
||
// poci<63>gu sieciowego)
|
||
}
|
||
else if (PantDiff < -0.001)
|
||
{ // drut si<73> obni<6E>y<EFBFBD> albo pantograf
|
||
// podniesiony za wysoko
|
||
// je<6A>li wysoko<6B><6F> jest zbyt du<64>a, wyznaczy<7A> zmniejszenie k<>ta
|
||
// je<6A>li zmniejszenie k<>ta jest zbyt du<64>e, przej<65><6A> do trybu <20>amania
|
||
// pantografu
|
||
// if (PantFrontDiff<-0.05) //skok w d<><64> o 5cm daje z<><7A>manie
|
||
// pantografu
|
||
k += 0.4 * PantDiff; // mniej ni<6E> pochodna k<>ta po wysoko<6B>ci
|
||
} // je<6A>li wysoko<6B><6F> jest dobra, nic wi<77>cej nie liczy<7A>
|
||
}
|
||
else
|
||
{ // je<6A>li ma by<62> na dole
|
||
if (k > p->fAngleL0) // je<6A>li wy<77>ej ni<6E> po<70>o<EFBFBD>enie wyj<79>ciowe
|
||
k -= 0.15 * dt1; // ruch w d<><64>
|
||
if (k < p->fAngleL0)
|
||
k = p->fAngleL0; // po<70>o<EFBFBD>enie minimalne
|
||
}
|
||
if (k != p->fAngleL)
|
||
{ //<2F>eby nie liczy<7A> w kilku miejscach ani gdy nie potrzeba
|
||
if (k + p->fAngleU < M_PI)
|
||
{ // o ile nie zosta<74> osi<73>gni<6E>ty k<>t maksymalny
|
||
p->fAngleL = k; // zmieniony k<>t
|
||
// wyliczy<7A> k<>t g<>rnego ramienia z wzoru (a)cosinusowego
|
||
//=acos((b*cos()+c)/a)
|
||
// p->dPantAngleT=acos((1.22*cos(k)+0.535)/1.755); //g<>rne rami<6D>
|
||
p->fAngleU = acos((p->fLenL1 * cos(k) + p->fHoriz) / p->fLenU1); // g<>rne rami<6D>
|
||
// wyliczy<7A> aktualn<6C> wysoko<6B><6F> z wzoru sinusowego
|
||
// h=a*sin()+b*sin()
|
||
p->PantWys = p->fLenL1 * sin(k) + p->fLenU1 * sin(p->fAngleU) +
|
||
p->fHeight; // wysoko<6B><6F> ca<63>o<EFBFBD>ci
|
||
}
|
||
}
|
||
} // koniec p<>tli po pantografach
|
||
if ((MoverParameters->PantFrontSP == false) && (MoverParameters->PantFrontUp == false))
|
||
{
|
||
sPantDown.Play(vol, 0, MechInside, vPosition);
|
||
MoverParameters->PantFrontSP = true;
|
||
}
|
||
if ((MoverParameters->PantRearSP == false) && (MoverParameters->PantRearUp == false))
|
||
{
|
||
sPantDown.Play(vol, 0, MechInside, vPosition);
|
||
MoverParameters->PantRearSP = true;
|
||
}
|
||
if (MoverParameters->EnginePowerSource.SourceType == CurrentCollector)
|
||
{ // Winger 240404 - wylaczanie sprezarki i
|
||
// przetwornicy przy braku napiecia
|
||
if (tmpTraction.TractionVoltage == 0)
|
||
{ // to co<63> wy<77><79>cza<7A>o d<>wi<77>k silnika w ST43!
|
||
MoverParameters->ConverterFlag = false;
|
||
MoverParameters->CompressorFlag = false; // Ra: to jest w<>tpliwe - wy<77><79>czenie
|
||
// spr<70><72>arki powinno by<62> w jednym miejscu!
|
||
}
|
||
}
|
||
}
|
||
else if (MoverParameters->EnginePowerSource.SourceType == InternalSource)
|
||
if (MoverParameters->EnginePowerSource.PowerType == SteamPower)
|
||
// if (smPatykird1[0])
|
||
{ // Ra: animacja rozrz<72>du parowozu, na razie nieoptymalizowane
|
||
/* //Ra: tymczasowo wy<77><79>czone ze wzgl<67>du na porz<72>dkowanie animacji
|
||
pantograf<61>w
|
||
double fi,dx,c2,ka,kc;
|
||
double sin_fi,cos_fi;
|
||
double L1=1.6688888888888889;
|
||
double L2=5.6666666666666667; //2550/450
|
||
double Lc=0.4;
|
||
double L=5.686422222; //2558.89/450
|
||
double G1,G2,G3,ksi,sin_ksi,gam;
|
||
double G1_2,G2_2,G3_2; //kwadraty
|
||
//ruch t<>ok<6F>w oraz korbowod<6F>w
|
||
for (int i=0;i<=1;++i)
|
||
{//obie strony w ten sam spos<6F>b
|
||
fi=DegToRad(dWheelAngle[1]+(i?pant2x:pant1x)); //k<>t obrotu ko<6B>a dla
|
||
t<>oka 1
|
||
sin_fi=sin(fi);
|
||
cos_fi=cos(fi);
|
||
dx=panty*cos_fi+sqrt(panth*panth-panty*panty*sin_fi*sin_fi)-panth;
|
||
//nieoptymalne
|
||
if (smPatykird1[i]) //na razie zabezpieczenie
|
||
smPatykird1[i]->SetTranslate(float3(dx,0,0));
|
||
ka=-asin(panty/panth)*sin_fi;
|
||
if (smPatykirg1[i]) //na razie zabezpieczenie
|
||
smPatykirg1[i]->SetRotateXYZ(vector3(RadToDeg(ka),0,0));
|
||
//smPatykirg1[0]->SetRotate(float3(0,1,0),RadToDeg(fi)); //obracamy
|
||
//ruch dr<64><72>ka mimo<6D>rodkowego oraz jarzma
|
||
//korzysta<74>em z pliku PDF "mm.pdf" (opis czworoboku
|
||
korbowo-wahaczowego):
|
||
//"MECHANIKA MASZYN. Szkic wyk<79>adu i laboratorium komputerowego."
|
||
//Prof. dr hab. in<69>. Jerzy Zaj<61>czkowski, 2007, Politechnika <20><>dzka
|
||
//L1 - wysoko<6B><6F> (w pionie) osi jarzma ponad osi<73> ko<6B>a
|
||
//L2 - odleg<65>o<EFBFBD><6F> w poziomie osi jarzma od osi ko<6B>a
|
||
//Lc - d<>ugo<67><6F> korby mimo<6D>rodu na kole
|
||
//Lr - promie<69> jarzma =1.0 (pozosta<74>e przeliczone proporcjonalnie)
|
||
//L - d<>ugo<67><6F> dr<64><72>ka mimo<6D>rodowego
|
||
//fi - k<>t obrotu ko<6B>a
|
||
//ksi - k<>t obrotu jarzma (od pionu)
|
||
//gam - odchylenie dr<64><72>ka mimo<6D>rodowego od poziomu
|
||
//G1=(Lr*Lr+L1*L1+L2*L2+Kc*Lc-L*L-2.0*Lc*L2*cos(fi)+2.0*Lc*L1*sin(fi))/(Lr*Lr);
|
||
//G2=2.0*(L2-Lc*cos(fi))/Lr;
|
||
//G3=2.0*(L1-Lc*sin(fi))/Lr;
|
||
fi=DegToRad(dWheelAngle[1]+(i?pant2x:pant1x)-96.77416667); //k<>t
|
||
obrotu ko<6B>a dla
|
||
t<>oka 1
|
||
//1) dla dWheelAngle[1]=0<> korba jest w d<><64>, a mimo<6D>r<EFBFBD>d w stron<6F>
|
||
jarzma, czyli
|
||
fi=-7<>
|
||
//2) dla dWheelAngle[1]=90<39> korba jest do ty<74>u, a mimo<6D>r<EFBFBD>d w d<><64>,
|
||
czyli fi=83<38>
|
||
sin_fi=sin(fi);
|
||
cos_fi=cos(fi);
|
||
G1=(1.0+L1*L1+L2*L2+Lc*Lc-L*L-2.0*Lc*L2*cos_fi+2.0*Lc*L1*sin_fi);
|
||
G1_2=G1*G1;
|
||
G2=2.0*(L2-Lc*cos_fi);
|
||
G2_2=G2*G2;
|
||
G3=2.0*(L1-Lc*sin_fi);
|
||
G3_2=G3*G3;
|
||
sin_ksi=(G1*G2-G3*_fm_sqrt(G2_2+G3_2-G1_2))/(G2_2+G3_2); //x1 (minus
|
||
delta)
|
||
ksi=asin(sin_ksi); //k<>t jarzma
|
||
if (smPatykirg2[i])
|
||
smPatykirg2[i]->SetRotateXYZ(vector3(RadToDeg(ksi),0,0)); //obr<62>cenie
|
||
jarzma
|
||
//1) ksi=-23<32>, gam=
|
||
//2) ksi=10<31>, gam=
|
||
//gam=acos((L2-sin_ksi-Lc*cos_fi)/L); //k<>t od poziomu, liczony
|
||
wzgl<67>dem poziomu
|
||
//gam=asin((L1-cos_ksi-Lc*sin_fi)/L); //k<>t od poziomu, liczony
|
||
wzgl<67>dem pionu
|
||
gam=atan2((L1-cos(ksi)+Lc*sin_fi),(L2-sin_ksi+Lc*cos_fi)); //k<>t od
|
||
poziomu
|
||
if (smPatykird2[i]) //na razie zabezpieczenie
|
||
smPatykird2[i]->SetRotateXYZ(vector3(RadToDeg(-gam-ksi),0,0));
|
||
//obr<62>cenie dr<64><72>ka
|
||
mimo<6D>rodowego
|
||
}
|
||
*/
|
||
}
|
||
|
||
// NBMX Obsluga drzwi, MC: zuniwersalnione
|
||
if ((dDoorMoveL < MoverParameters->DoorMaxShiftL) && (MoverParameters->DoorLeftOpened))
|
||
{
|
||
rsDoorOpen.Play(1, 0, MechInside, vPosition);
|
||
dDoorMoveL += dt1 * 0.5 * MoverParameters->DoorOpenSpeed;
|
||
}
|
||
if ((dDoorMoveL > 0) && (!MoverParameters->DoorLeftOpened))
|
||
{
|
||
rsDoorClose.Play(1, 0, MechInside, vPosition);
|
||
dDoorMoveL -= dt1 * MoverParameters->DoorCloseSpeed;
|
||
if (dDoorMoveL < 0)
|
||
dDoorMoveL = 0;
|
||
}
|
||
if ((dDoorMoveR < MoverParameters->DoorMaxShiftR) && (MoverParameters->DoorRightOpened))
|
||
{
|
||
rsDoorOpen.Play(1, 0, MechInside, vPosition);
|
||
dDoorMoveR += dt1 * 0.5 * MoverParameters->DoorOpenSpeed;
|
||
}
|
||
if ((dDoorMoveR > 0) && (!MoverParameters->DoorRightOpened))
|
||
{
|
||
rsDoorClose.Play(1, 0, MechInside, vPosition);
|
||
dDoorMoveR -= dt1 * MoverParameters->DoorCloseSpeed;
|
||
if (dDoorMoveR < 0)
|
||
dDoorMoveR = 0;
|
||
}
|
||
|
||
// ABu-160303 sledzenie toru przed obiektem: *******************************
|
||
// Z obserwacji: v>0 -> Coupler 0; v<0 ->coupler1 (Ra: pr<70>dko<6B><6F> jest zwi<77>zana
|
||
// z pojazdem)
|
||
// Rozroznienie jest tutaj, zeby niepotrzebnie nie skakac do funkcji. Nie jest
|
||
// uzaleznione
|
||
// od obecnosci AI, zeby uwzglednic np. jadace bez lokomotywy wagony.
|
||
// Ra: mo<6D>na by przenie<69><65> na poziom obiektu reprezentuj<75>cego sk<73>ad, aby nie
|
||
// sprawdza<7A> <20>rodkowych
|
||
if (CouplCounter > 25) // licznik, aby nie robi<62> za ka<6B>dym razem
|
||
{ // poszukiwanie czego<67> do zderzenia si<73>
|
||
fTrackBlock = 10000.0; // na razie nie ma przeszk<7A>d (na wypadek nie
|
||
// uruchomienia skanowania)
|
||
// je<6A>li nie ma zwrotnicy po drodze, to tylko przeliczy<7A> odleg<65>o<EFBFBD><6F>?
|
||
if (MoverParameters->V > 0.03) //[m/s] je<6A>li jedzie do przodu (w kierunku Coupler 0)
|
||
{
|
||
if (MoverParameters->Couplers[0].CouplingFlag ==
|
||
ctrain_virtual) // brak pojazdu podpi<70>tego?
|
||
{
|
||
ABuScanObjects(1, fScanDist); // szukanie czego<67> do pod<6F><64>czenia
|
||
// WriteLog(asName+" - block 0: "+AnsiString(fTrackBlock));
|
||
}
|
||
}
|
||
else if (MoverParameters->V < -0.03) //[m/s] je<6A>li jedzie do ty<74>u (w kierunku Coupler 1)
|
||
if (MoverParameters->Couplers[1].CouplingFlag ==
|
||
ctrain_virtual) // brak pojazdu podpi<70>tego?
|
||
{
|
||
ABuScanObjects(-1, fScanDist);
|
||
// WriteLog(asName+" - block 1: "+AnsiString(fTrackBlock));
|
||
}
|
||
CouplCounter = Random(20); // ponowne sprawdzenie po losowym czasie
|
||
}
|
||
if (MoverParameters->Vel > 0.1) //[km/h]
|
||
++CouplCounter; // jazda sprzyja poszukiwaniu po<70><6F>czenia
|
||
else
|
||
{
|
||
CouplCounter = 25; // a bezruch nie, ale trzeba zaktualizowa<77> odleg<65>o<EFBFBD><6F>, bo
|
||
// zawalidroga mo<6D>e
|
||
// sobie pojecha<68>
|
||
}
|
||
if (MoverParameters->DerailReason > 0)
|
||
{
|
||
switch (MoverParameters->DerailReason)
|
||
{
|
||
case 1:
|
||
ErrorLog("Bad driving: " + asName + " derailed due to end of track");
|
||
break;
|
||
case 2:
|
||
ErrorLog("Bad driving: " + asName + " derailed due to too high speed");
|
||
break;
|
||
case 3:
|
||
ErrorLog("Bad dynamic: " + asName + " derailed due to track width");
|
||
break; // b<><62>d w scenerii
|
||
case 4:
|
||
ErrorLog("Bad dynamic: " + asName + " derailed due to wrong track type");
|
||
break; // b<><62>d w scenerii
|
||
}
|
||
MoverParameters->DerailReason = 0; //<2F>eby tylko raz
|
||
}
|
||
if (MoverParameters->LoadStatus)
|
||
LoadUpdate(); // zmiana modelu <20>adunku
|
||
|
||
return true; // Ra: chyba tak?
|
||
}
|
||
|
||
bool TDynamicObject::FastUpdate(double dt)
|
||
{
|
||
if (dt == 0.0)
|
||
return true; // Ra: pauza
|
||
double dDOMoveLen;
|
||
if (!MoverParameters->PhysicActivation)
|
||
return true; // McZapkie: wylaczanie fizyki gdy nie potrzeba
|
||
|
||
if (!bEnabled)
|
||
return false;
|
||
|
||
TLocation l;
|
||
l.X = -vPosition.x;
|
||
l.Y = vPosition.z;
|
||
l.Z = vPosition.y;
|
||
TRotation r;
|
||
r.Rx = r.Ry = r.Rz = 0.0;
|
||
|
||
// McZapkie: parametry powinny byc pobierane z toru
|
||
// ts.R=MyTrack->fRadius;
|
||
// ts.Len= Max0R(MoverParameters->BDist,MoverParameters->ADist);
|
||
// ts.dHtrack=Axle1.pPosition.y-Axle0.pPosition.y;
|
||
// ts.dHrail=((Axle1.GetRoll())+(Axle0.GetRoll()))*0.5f;
|
||
// tp.Width=MyTrack->fTrackWidth;
|
||
// McZapkie-250202
|
||
// tp.friction= MyTrack->fFriction;
|
||
// tp.CategoryFlag= MyTrack->iCategoryFlag&15;
|
||
// tp.DamageFlag=MyTrack->iDamageFlag;
|
||
// tp.QualityFlag=MyTrack->iQualityFlag;
|
||
dDOMoveLen = MoverParameters->FastComputeMovement(dt, ts, tp, l, r); // ,ts,tp,tmpTraction);
|
||
// Move(dDOMoveLen);
|
||
// ResetdMoveLen();
|
||
FastMove(dDOMoveLen);
|
||
|
||
if (MoverParameters->LoadStatus)
|
||
LoadUpdate(); // zmiana modelu <20>adunku
|
||
return true; // Ra: chyba tak?
|
||
}
|
||
|
||
// McZapkie-040402: liczenie pozycji uwzgledniajac wysokosc szyn itp.
|
||
// vector3 TDynamicObject::GetPosition()
|
||
//{//Ra: pozycja pojazdu jest liczona zaraz po przesuni<6E>ciu
|
||
// return vPosition;
|
||
//};
|
||
|
||
void TDynamicObject::TurnOff()
|
||
{ // wy<77><79>czenie rysowania submodeli zmiennych dla
|
||
// egemplarza pojazdu
|
||
btnOn = false;
|
||
btCoupler1.TurnOff();
|
||
btCoupler2.TurnOff();
|
||
btCPneumatic1.TurnOff();
|
||
btCPneumatic1r.TurnOff();
|
||
btCPneumatic2.TurnOff();
|
||
btCPneumatic2r.TurnOff();
|
||
btPneumatic1.TurnOff();
|
||
btPneumatic1r.TurnOff();
|
||
btPneumatic2.TurnOff();
|
||
btPneumatic2r.TurnOff();
|
||
btCCtrl1.TurnOff();
|
||
btCCtrl2.TurnOff();
|
||
btCPass1.TurnOff();
|
||
btCPass2.TurnOff();
|
||
btEndSignals11.TurnOff();
|
||
btEndSignals13.TurnOff();
|
||
btEndSignals21.TurnOff();
|
||
btEndSignals23.TurnOff();
|
||
btEndSignals1.TurnOff();
|
||
btEndSignals2.TurnOff();
|
||
btEndSignalsTab1.TurnOff();
|
||
btEndSignalsTab2.TurnOff();
|
||
btHeadSignals11.TurnOff();
|
||
btHeadSignals12.TurnOff();
|
||
btHeadSignals13.TurnOff();
|
||
btHeadSignals21.TurnOff();
|
||
btHeadSignals22.TurnOff();
|
||
btHeadSignals23.TurnOff();
|
||
btMechanik1.TurnOff();
|
||
btMechanik2.TurnOff();
|
||
};
|
||
|
||
void TDynamicObject::Render()
|
||
{ // rysowanie element<6E>w nieprzezroczystych
|
||
// youBy - sprawdzamy, czy jest sens renderowac
|
||
double modelrotate;
|
||
vector3 tempangle;
|
||
// zmienne
|
||
renderme = false;
|
||
// przeklejka
|
||
double ObjSqrDist = SquareMagnitude(Global::pCameraPosition - vPosition);
|
||
// koniec przeklejki
|
||
if (ObjSqrDist < 500) // jak jest blisko - do 70m
|
||
modelrotate = 0.01; // ma<6D>y k<>t, <20>eby nie znika<6B>o
|
||
else
|
||
{ // Global::pCameraRotation to k<>t bewzgl<67>dny w <20>wiecie (zero - na
|
||
// p<><70>noc)
|
||
tempangle = (vPosition - Global::pCameraPosition); // wektor od kamery
|
||
modelrotate = ABuAcos(tempangle); // okre<72>lenie k<>ta
|
||
// if (modelrotate>M_PI) modelrotate-=(2*M_PI);
|
||
modelrotate += Global::pCameraRotation;
|
||
}
|
||
if (modelrotate > M_PI)
|
||
modelrotate -= (2 * M_PI);
|
||
if (modelrotate < -M_PI)
|
||
modelrotate += (2 * M_PI);
|
||
ModCamRot = modelrotate;
|
||
|
||
modelrotate = abs(modelrotate);
|
||
|
||
if (modelrotate < maxrot)
|
||
renderme = true;
|
||
|
||
if (renderme)
|
||
{
|
||
TSubModel::iInstance = (int)this; //<2F>eby nie robi<62> cudzych animacji
|
||
// AnsiString asLoadName="";
|
||
double ObjSqrDist = SquareMagnitude(Global::pCameraPosition - vPosition);
|
||
ABuLittleUpdate(ObjSqrDist); // ustawianie zmiennych submodeli dla wsp<73>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<7A>w w postaci ostros<6F>up<75>w, wymaga
|
||
// GLUT32.DLL
|
||
double dir = RadToDeg(atan2(vLeft.z, vLeft.x));
|
||
Axle0.Render(0);
|
||
Axle1.Render(1); // bogieRot[0]
|
||
// if (PrevConnected) //renderowanie po<70><6F>czenia
|
||
}
|
||
#endif
|
||
|
||
glPushMatrix();
|
||
// vector3 pos= vPosition;
|
||
// double ObjDist= SquareMagnitude(Global::pCameraPosition-pos);
|
||
if (this == Global::pUserDynamic)
|
||
{ // specjalne ustawienie, aby nie trz<72>s<EFBFBD>o
|
||
if (Global::bSmudge)
|
||
{ // jak jest widoczna smuga, to pojazd renderowa<77> po
|
||
// wyrenderowaniu smugi
|
||
glPopMatrix(); // a to trzeba zebra<72> przed wyj<79>ciem
|
||
return;
|
||
}
|
||
// if (Global::pWorld->) //tu trzeba by ustawi<77> animacje na modelu
|
||
// zewn<77>trznym
|
||
glLoadIdentity(); // zacz<63><7A> od macierzy jedynkowej
|
||
Global::pCamera->SetCabMatrix(vPosition); // specjalne ustawienie kamery
|
||
}
|
||
else
|
||
glTranslated(vPosition.x, vPosition.y,
|
||
vPosition.z); // standardowe przesuni<6E>cie wzgl<67>dem pocz<63>tku scenerii
|
||
glMultMatrixd(mMatrix.getArray());
|
||
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<63> 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);
|
||
}
|
||
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 <20>adunku
|
||
mdLoad->RaRender(ObjSqrDist, ReplacableSkinID, iAlpha);
|
||
if (mdPrzedsionek)
|
||
mdPrzedsionek->RaRender(ObjSqrDist, ReplacableSkinID, iAlpha);
|
||
}
|
||
else
|
||
{ // wersja Display Lists
|
||
if (mdLowPolyInt)
|
||
if (FreeFlyModeFlag ? true : !mdKabina || !bDisplayCab)
|
||
mdLowPolyInt->Render(ObjSqrDist, ReplacableSkinID, iAlpha);
|
||
mdModel->Render(ObjSqrDist, ReplacableSkinID, iAlpha);
|
||
if (mdLoad) // renderowanie nieprzezroczystego <20>adunku
|
||
mdLoad->Render(ObjSqrDist, ReplacableSkinID, iAlpha);
|
||
if (mdPrzedsionek)
|
||
mdPrzedsionek->Render(ObjSqrDist, ReplacableSkinID, iAlpha);
|
||
}
|
||
|
||
// Ra: czy ta kabina tu ma sens?
|
||
// Ra: czy nie renderuje si<73> dwukrotnie?
|
||
// Ra: dlaczego jest zablokowana w przezroczystych?
|
||
if (mdKabina) // je<6A>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: <20>wiet<65>a s<> ustawione dla zewn<77>trza danego pojazdu
|
||
// 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.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;
|
||
}
|
||
glLightfv(GL_LIGHT0, GL_AMBIENT, ambientCabLight);
|
||
glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuseCabLight);
|
||
glLightfv(GL_LIGHT0, GL_SPECULAR, specularCabLight);
|
||
if (Global::bUseVBO)
|
||
mdKabina->RaRender(ObjSqrDist, 0);
|
||
else
|
||
mdKabina->Render(ObjSqrDist, 0);
|
||
glLightfv(GL_LIGHT0, GL_AMBIENT, Global::ambientDayLight);
|
||
glLightfv(GL_LIGHT0, GL_DIFFUSE, Global::diffuseDayLight);
|
||
glLightfv(GL_LIGHT0, GL_SPECULAR, Global::specularDayLight);
|
||
}
|
||
if (fShade != 0.0) // tylko je<6A>li by<62>o zmieniane
|
||
{ // przywr<77>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);
|
||
}
|
||
glPopMatrix();
|
||
if (btnOn)
|
||
TurnOff(); // przywr<77>cenie domy<6D>lnych pozycji submodeli
|
||
} // yB - koniec mieszania z grafika
|
||
};
|
||
|
||
void TDynamicObject::RenderSounds()
|
||
{ // przeliczanie d<>wi<77>k<EFBFBD>w, bo b<>dzie
|
||
// s<>ycha<68> bez wy<77>wietlania sektora z
|
||
// pojazdem
|
||
// McZapkie-010302: ulepszony dzwiek silnika
|
||
double freq;
|
||
double vol = 0;
|
||
double dt = Timer::GetDeltaTime();
|
||
|
||
// double sounddist;
|
||
// sounddist=SquareMagnitude(Global::pCameraPosition-vPosition);
|
||
|
||
if (MoverParameters->Power > 0)
|
||
{
|
||
if ((rsSilnik.AM != 0) && ((MoverParameters->Mains) || (MoverParameters->EngineType ==
|
||
DieselEngine))) // McZapkie-280503:
|
||
// zeby dla dumb
|
||
// dzialal silnik na
|
||
// jalowych obrotach
|
||
{
|
||
if ((fabs(MoverParameters->enrot) > 0.01) ||
|
||
(MoverParameters->EngineType == Dumb)) //&& (MoverParameters->EnginePower>0.1))
|
||
{
|
||
freq = rsSilnik.FM * fabs(MoverParameters->enrot) + rsSilnik.FA;
|
||
if (MoverParameters->EngineType == Dumb)
|
||
freq = freq -
|
||
0.2 * MoverParameters->EnginePower / (1 + MoverParameters->Power * 1000);
|
||
rsSilnik.AdjFreq(freq, dt);
|
||
if (MoverParameters->EngineType == DieselEngine)
|
||
{
|
||
if (MoverParameters->enrot > 0)
|
||
{
|
||
if (MoverParameters->EnginePower > 0)
|
||
vol = rsSilnik.AM * MoverParameters->dizel_fill + rsSilnik.AA;
|
||
else
|
||
vol =
|
||
rsSilnik.AM * fabs(MoverParameters->enrot / MoverParameters->nmax) +
|
||
rsSilnik.AA * 0.9;
|
||
}
|
||
else
|
||
vol = 0;
|
||
}
|
||
else if (MoverParameters->EngineType == DieselElectric)
|
||
vol = rsSilnik.AM *
|
||
(MoverParameters->EnginePower / 1000 / MoverParameters->Power) +
|
||
0.2 * (MoverParameters->enrot * 60) /
|
||
(MoverParameters->DElist[MoverParameters->MainCtrlPosNo].RPM) +
|
||
rsSilnik.AA;
|
||
else if (MoverParameters->EngineType == ElectricInductionMotor)
|
||
vol = rsSilnik.AM *
|
||
(MoverParameters->EnginePower + fabs(MoverParameters->enrot * 2)) +
|
||
rsSilnik.AA;
|
||
else
|
||
vol = rsSilnik.AM * (MoverParameters->EnginePower / 1000 +
|
||
fabs(MoverParameters->enrot) * 60.0) +
|
||
rsSilnik.AA;
|
||
// McZapkie-250302 - natezenie zalezne od obrotow i mocy
|
||
if ((vol < 1) && (MoverParameters->EngineType == ElectricSeriesMotor) &&
|
||
(MoverParameters->EnginePower < 100))
|
||
{
|
||
float volrnd =
|
||
Random(100) * MoverParameters->enrot / (1 + MoverParameters->nmax);
|
||
if (volrnd < 2)
|
||
vol = vol + volrnd / 200.0;
|
||
}
|
||
switch (MyTrack->eEnvironment)
|
||
{
|
||
case e_tunnel:
|
||
{
|
||
vol += 0.1;
|
||
}
|
||
break;
|
||
case e_canyon:
|
||
{
|
||
vol += 0.05;
|
||
}
|
||
break;
|
||
}
|
||
if ((MoverParameters->DynamicBrakeFlag) && (MoverParameters->EnginePower > 0.1) &&
|
||
(MoverParameters->EngineType ==
|
||
ElectricSeriesMotor)) // Szociu - 29012012 - je<6A>eli uruchomiony
|
||
// jest hamulec
|
||
// elektrodynamiczny, odtwarzany jest d<>wi<77>k silnika
|
||
vol += 0.8;
|
||
|
||
if (enginevolume > 0.0001)
|
||
if (MoverParameters->EngineType != DieselElectric)
|
||
{
|
||
rsSilnik.Play(enginevolume, DSBPLAY_LOOPING, MechInside, GetPosition());
|
||
}
|
||
else
|
||
{
|
||
sConverter.UpdateAF(vol, freq, MechInside, GetPosition());
|
||
|
||
float fincvol;
|
||
fincvol = 0;
|
||
if ((MoverParameters->ConverterFlag) &&
|
||
(MoverParameters->enrot * 60 > MoverParameters->DElist[0].RPM))
|
||
{
|
||
fincvol = (MoverParameters->DElist[MoverParameters->MainCtrlPos].RPM -
|
||
(MoverParameters->enrot * 60));
|
||
fincvol /= (0.05 * MoverParameters->DElist[0].RPM);
|
||
};
|
||
if (fincvol > 0.02)
|
||
rsDiesielInc.Play(fincvol, DSBPLAY_LOOPING, MechInside, GetPosition());
|
||
else
|
||
rsDiesielInc.Stop();
|
||
}
|
||
}
|
||
else
|
||
rsSilnik.Stop();
|
||
}
|
||
enginevolume = (enginevolume + vol) / 2;
|
||
if (enginevolume < 0.01)
|
||
rsSilnik.Stop();
|
||
if ((MoverParameters->EngineType == ElectricSeriesMotor) ||
|
||
(MoverParameters->EngineType == ElectricInductionMotor) && rsWentylator.AM != 0)
|
||
{
|
||
if (MoverParameters->RventRot > 0.1)
|
||
{
|
||
freq = rsWentylator.FM * MoverParameters->RventRot + rsWentylator.FA;
|
||
rsWentylator.AdjFreq(freq, dt);
|
||
if (MoverParameters->EngineType == ElectricInductionMotor)
|
||
vol =
|
||
rsWentylator.AM * sqrt(fabs(MoverParameters->dizel_fill)) + rsWentylator.AA;
|
||
else
|
||
vol = rsWentylator.AM * MoverParameters->RventRot + rsWentylator.AA;
|
||
rsWentylator.Play(vol, DSBPLAY_LOOPING, MechInside, GetPosition());
|
||
}
|
||
else
|
||
rsWentylator.Stop();
|
||
}
|
||
if (MoverParameters->TrainType == dt_ET40)
|
||
{
|
||
if (MoverParameters->Vel > 0.1)
|
||
{
|
||
freq = rsPrzekladnia.FM * (MoverParameters->Vel) + rsPrzekladnia.FA;
|
||
rsPrzekladnia.AdjFreq(freq, dt);
|
||
vol = rsPrzekladnia.AM * (MoverParameters->Vel) + rsPrzekladnia.AA;
|
||
rsPrzekladnia.Play(vol, DSBPLAY_LOOPING, MechInside, GetPosition());
|
||
}
|
||
else
|
||
rsPrzekladnia.Stop();
|
||
}
|
||
}
|
||
|
||
// youBy: dzwiek ostrych lukow i ciasnych zwrotek
|
||
|
||
if ((ts.R * ts.R > 1) && (MoverParameters->Vel > 0))
|
||
vol = MoverParameters->AccN * MoverParameters->AccN;
|
||
else
|
||
vol = 0;
|
||
// vol+=(50000/ts.R*ts.R);
|
||
|
||
if (vol > 0.001)
|
||
{
|
||
rscurve.Play(2 * vol, DSBPLAY_LOOPING, MechInside, GetPosition());
|
||
}
|
||
else
|
||
rscurve.Stop();
|
||
|
||
// McZapkie-280302 - pisk mocno zacisnietych hamulcow - trzeba jeszcze
|
||
// zabezpieczyc przed
|
||
// brakiem deklaracji w mmedia.dta
|
||
if (rsPisk.AM != 0)
|
||
{
|
||
if ((MoverParameters->Vel > (rsPisk.GetStatus() != 0 ? 0.01 : 0.5)) &&
|
||
(!MoverParameters->SlippingWheels) && (MoverParameters->UnitBrakeForce > rsPisk.AM))
|
||
{
|
||
vol = MoverParameters->UnitBrakeForce / (rsPisk.AM + 1) + rsPisk.AA;
|
||
rsPisk.Play(vol, DSBPLAY_LOOPING, MechInside, GetPosition());
|
||
}
|
||
else
|
||
rsPisk.Stop();
|
||
}
|
||
|
||
if (MoverParameters->SandDose) // Dzwiek piasecznicy
|
||
sSand.TurnOn(MechInside, GetPosition());
|
||
else
|
||
sSand.TurnOff(MechInside, GetPosition());
|
||
sSand.Update(MechInside, GetPosition());
|
||
if (MoverParameters->Hamulec->GetStatus() & b_rls) // Dzwiek odluzniacza
|
||
sReleaser.TurnOn(MechInside, GetPosition());
|
||
else
|
||
sReleaser.TurnOff(MechInside, GetPosition());
|
||
//sReleaser.Update(MechInside, GetPosition());
|
||
double releaser_vol = 1;
|
||
if (MoverParameters->BrakePress < 0.1)
|
||
releaser_vol = MoverParameters->BrakePress * 10;
|
||
sReleaser.UpdateAF(releaser_vol, 1, MechInside, GetPosition());
|
||
// if ((MoverParameters->ConverterFlag==false) &&
|
||
// (MoverParameters->TrainType!=dt_ET22))
|
||
// if
|
||
// ((MoverParameters->ConverterFlag==false)&&(MoverParameters->CompressorPower!=0))
|
||
// MoverParameters->CompressorFlag=false; //Ra: wywali<6C> to st<73>d, tu tylko dla
|
||
// wy<77>wietlanych!
|
||
// Ra: no to ju<6A> wiemy, dlaczego poci<63>gi je<6A>d<EFBFBD><64> lepiej, gdy si<73> na nie patrzy!
|
||
// if (MoverParameters->CompressorPower==2)
|
||
// MoverParameters->CompressorAllow=MoverParameters->ConverterFlag;
|
||
|
||
// McZapkie! - dzwiek compressor.wav tylko gdy dziala sprezarka
|
||
if (MoverParameters->VeselVolume != 0)
|
||
{
|
||
if (MoverParameters->CompressorFlag)
|
||
sCompressor.TurnOn(MechInside, GetPosition());
|
||
else
|
||
sCompressor.TurnOff(MechInside, GetPosition());
|
||
sCompressor.Update(MechInside, GetPosition());
|
||
}
|
||
if (MoverParameters->PantCompFlag) // Winger 160404 - dzwiek malej sprezarki
|
||
sSmallCompressor.TurnOn(MechInside, GetPosition());
|
||
else
|
||
sSmallCompressor.TurnOff(MechInside, GetPosition());
|
||
sSmallCompressor.Update(MechInside, GetPosition());
|
||
|
||
// youBy - przenioslem, bo diesel tez moze miec turbo
|
||
if ((MoverParameters->MainCtrlPos) >=
|
||
(MoverParameters->TurboTest)) // hunter-250312: dlaczego zakomentowane?
|
||
// Ra: bo nie dzia<69>a<EFBFBD>o dobrze
|
||
{
|
||
// udawanie turbo: (6.66*(eng_vol-0.85))
|
||
if (eng_turbo > 6.66 * (enginevolume - 0.8) + 0.2 * dt)
|
||
eng_turbo = eng_turbo - 0.2 * dt; // 0.125
|
||
else if (eng_turbo < 6.66 * (enginevolume - 0.8) - 0.4 * dt)
|
||
eng_turbo = eng_turbo + 0.4 * dt; // 0.333
|
||
else
|
||
eng_turbo = 6.66 * (enginevolume - 0.8);
|
||
|
||
sTurbo.TurnOn(MechInside, GetPosition());
|
||
// sTurbo.UpdateAF(eng_turbo,0.7+(eng_turbo*0.6),MechInside,GetPosition());
|
||
sTurbo.UpdateAF(3 * eng_turbo - 1, 0.4 + eng_turbo * 0.4, MechInside, GetPosition());
|
||
// eng_vol_act=enginevolume;
|
||
// eng_frq_act=eng_frq;
|
||
}
|
||
else
|
||
sTurbo.TurnOff(MechInside, GetPosition());
|
||
|
||
if (MoverParameters->TrainType == dt_PseudoDiesel)
|
||
{
|
||
// ABu: udawanie woodwarda dla lok. spalinowych
|
||
// jesli silnik jest podpiety pod dzwiek przetwornicy
|
||
if (MoverParameters->ConverterFlag) // NBMX dzwiek przetwornicy
|
||
{
|
||
sConverter.TurnOn(MechInside, GetPosition());
|
||
}
|
||
else
|
||
sConverter.TurnOff(MechInside, GetPosition());
|
||
|
||
// glosnosc zalezy od stosunku mocy silnika el. do mocy max
|
||
double eng_vol;
|
||
if (MoverParameters->Power > 1)
|
||
// 0.85+0.000015*(...)
|
||
eng_vol = 0.8 + 0.00002 * (MoverParameters->EnginePower / MoverParameters->Power);
|
||
else
|
||
eng_vol = 1;
|
||
|
||
eng_dfrq = eng_dfrq + (eng_vol_act - eng_vol);
|
||
if (eng_dfrq > 0)
|
||
{
|
||
eng_dfrq = eng_dfrq - 0.025 * dt;
|
||
if (eng_dfrq < 0.025 * dt)
|
||
eng_dfrq = 0;
|
||
}
|
||
else if (eng_dfrq < 0)
|
||
{
|
||
eng_dfrq = eng_dfrq + 0.025 * dt;
|
||
if (eng_dfrq > -0.025 * dt)
|
||
eng_dfrq = 0;
|
||
}
|
||
double defrot;
|
||
if (MoverParameters->MainCtrlPos != 0)
|
||
{
|
||
double CtrlPos = MoverParameters->MainCtrlPos;
|
||
double CtrlPosNo = MoverParameters->MainCtrlPosNo;
|
||
// defrot=1+0.4*(CtrlPos/CtrlPosNo);
|
||
defrot = 1 + 0.5 * (CtrlPos / CtrlPosNo);
|
||
}
|
||
else
|
||
defrot = 1;
|
||
|
||
if (eng_frq_act < defrot)
|
||
{
|
||
// if (MoverParameters->MainCtrlPos==1) eng_frq_act=eng_frq_act+0.1*dt;
|
||
eng_frq_act = eng_frq_act + 0.4 * dt; // 0.05
|
||
if (eng_frq_act > defrot - 0.4 * dt)
|
||
eng_frq_act = defrot;
|
||
}
|
||
else if (eng_frq_act > defrot)
|
||
{
|
||
eng_frq_act = eng_frq_act - 0.1 * dt; // 0.05
|
||
if (eng_frq_act < defrot + 0.1 * dt)
|
||
eng_frq_act = defrot;
|
||
}
|
||
sConverter.UpdateAF(eng_vol_act, eng_frq_act + eng_dfrq, MechInside, GetPosition());
|
||
// udawanie turbo: (6.66*(eng_vol-0.85))
|
||
if (eng_turbo > 6.66 * (eng_vol - 0.8) + 0.2 * dt)
|
||
eng_turbo = eng_turbo - 0.2 * dt; // 0.125
|
||
else if (eng_turbo < 6.66 * (eng_vol - 0.8) - 0.4 * dt)
|
||
eng_turbo = eng_turbo + 0.4 * dt; // 0.333
|
||
else
|
||
eng_turbo = 6.66 * (eng_vol - 0.8);
|
||
|
||
sTurbo.TurnOn(MechInside, GetPosition());
|
||
// sTurbo.UpdateAF(eng_turbo,0.7+(eng_turbo*0.6),MechInside,GetPosition());
|
||
sTurbo.UpdateAF(3 * eng_turbo - 1, 0.4 + eng_turbo * 0.4, MechInside, GetPosition());
|
||
eng_vol_act = eng_vol;
|
||
// eng_frq_act=eng_frq;
|
||
}
|
||
else
|
||
{
|
||
if (MoverParameters->ConverterFlag) // NBMX dzwiek przetwornicy
|
||
sConverter.TurnOn(MechInside, GetPosition());
|
||
else
|
||
sConverter.TurnOff(MechInside, GetPosition());
|
||
sConverter.Update(MechInside, GetPosition());
|
||
}
|
||
if (MoverParameters->WarningSignal > 0)
|
||
{
|
||
if (TestFlag(MoverParameters->WarningSignal, 1))
|
||
sHorn1.TurnOn(MechInside, GetPosition());
|
||
else
|
||
sHorn1.TurnOff(MechInside, GetPosition());
|
||
if (TestFlag(MoverParameters->WarningSignal, 2))
|
||
sHorn2.TurnOn(MechInside, GetPosition());
|
||
else
|
||
sHorn2.TurnOff(MechInside, GetPosition());
|
||
}
|
||
else
|
||
{
|
||
sHorn1.TurnOff(MechInside, GetPosition());
|
||
sHorn2.TurnOff(MechInside, GetPosition());
|
||
}
|
||
if (MoverParameters->DoorClosureWarning)
|
||
{
|
||
if (MoverParameters->DepartureSignal) // NBMX sygnal odjazdu, MC: pod warunkiem ze jest
|
||
// zdefiniowane w chk
|
||
sDepartureSignal.TurnOn(MechInside, GetPosition());
|
||
else
|
||
sDepartureSignal.TurnOff(MechInside, GetPosition());
|
||
sDepartureSignal.Update(MechInside, GetPosition());
|
||
}
|
||
sHorn1.Update(MechInside, GetPosition());
|
||
sHorn2.Update(MechInside, GetPosition());
|
||
// McZapkie: w razie wykolejenia
|
||
if (MoverParameters->EventFlag)
|
||
{
|
||
if (TestFlag(MoverParameters->DamageFlag, dtrain_out) && GetVelocity() > 0)
|
||
rsDerailment.Play(1, 0, true, GetPosition());
|
||
if (GetVelocity() == 0)
|
||
rsDerailment.Stop();
|
||
}
|
||
/* //Ra: dwa razy?
|
||
if (MoverParameters->EventFlag)
|
||
{
|
||
if (TestFlag(MoverParameters->DamageFlag,dtrain_out) && GetVelocity()>0)
|
||
rsDerailment.Play(1,0,true,GetPosition());
|
||
if (GetVelocity()==0)
|
||
rsDerailment.Stop();
|
||
}
|
||
*/
|
||
};
|
||
|
||
void TDynamicObject::RenderAlpha()
|
||
{ // rysowanie element<6E>w p<><70>przezroczystych
|
||
if (renderme)
|
||
{
|
||
TSubModel::iInstance = (int)this; //<2F>eby nie robi<62> cudzych animacji
|
||
double ObjSqrDist = SquareMagnitude(Global::pCameraPosition - vPosition);
|
||
ABuLittleUpdate(ObjSqrDist); // ustawianie zmiennych submodeli dla wsp<73>lnego modelu
|
||
glPushMatrix();
|
||
if (this == Global::pUserDynamic)
|
||
{ // specjalne ustawienie, aby nie trz<72>s<EFBFBD>o
|
||
if (Global::bSmudge)
|
||
{ // jak smuga, to rysowa<77> po smudze
|
||
glPopMatrix(); // to trzeba zebra<72> przed wy<77>ciem
|
||
return;
|
||
}
|
||
glLoadIdentity(); // zacz<63><7A> od macierzy jedynkowej
|
||
Global::pCamera->SetCabMatrix(vPosition); // specjalne ustawienie kamery
|
||
}
|
||
else
|
||
glTranslated(vPosition.x, vPosition.y,
|
||
vPosition.z); // standardowe przesuni<6E>cie wzgl<67>dem pocz<63>tku scenerii
|
||
glMultMatrixd(mMatrix.getArray());
|
||
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<63> 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);
|
||
}
|
||
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);
|
||
// if (mdPrzedsionek) //Ra: przedsionk<6E>w tu wcze<7A>niej nie by<62>o - w<><77>czy<7A>?
|
||
// mdPrzedsionek->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);
|
||
// if (mdPrzedsionek) //Ra: przedsionk<6E>w tu wcze<7A>niej nie by<62>o - w<><77>czy<7A>?
|
||
// mdPrzedsionek->RenderAlpha(ObjSqrDist,ReplacableSkinID,iAlpha);
|
||
}
|
||
/* skoro false to mo<6D>na wyci<63>c
|
||
//ABu: Tylko w trybie freefly
|
||
if (false)//((mdKabina!=mdModel) && bDisplayCab && FreeFlyModeFlag)
|
||
{
|
||
//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.6;
|
||
specularCabLight[li]*= 0.8;
|
||
}
|
||
}
|
||
break;
|
||
case e_tunnel:
|
||
{
|
||
for (int li=0; li<3; li++)
|
||
{
|
||
ambientCabLight[li]*= 0.3;
|
||
diffuseCabLight[li]*= 0.1;
|
||
specularCabLight[li]*= 0.2;
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
// dorobic swiatlo od drugiej strony szyby
|
||
|
||
glLightfv(GL_LIGHT0,GL_AMBIENT,ambientCabLight);
|
||
glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseCabLight);
|
||
glLightfv(GL_LIGHT0,GL_SPECULAR,specularCabLight);
|
||
|
||
mdKabina->RenderAlpha(ObjSqrDist,0);
|
||
//smierdzi
|
||
// mdModel->RenderAlpha(SquareMagnitude(Global::pCameraPosition-pos),0);
|
||
|
||
glLightfv(GL_LIGHT0,GL_AMBIENT,Global::ambientDayLight);
|
||
glLightfv(GL_LIGHT0,GL_DIFFUSE,Global::diffuseDayLight);
|
||
glLightfv(GL_LIGHT0,GL_SPECULAR,Global::specularDayLight);
|
||
}
|
||
*/
|
||
if (fShade != 0.0) // tylko je<6A>li by<62>o zmieniane
|
||
{ // przywr<77>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);
|
||
}
|
||
glPopMatrix();
|
||
if (btnOn)
|
||
TurnOff(); // przywr<77>cenie domy<6D>lnych pozycji submodeli
|
||
}
|
||
return;
|
||
} // koniec renderalpha
|
||
|
||
// McZapkie-250202
|
||
// wczytywanie pliku z danymi multimedialnymi (dzwieki)
|
||
void TDynamicObject::LoadMMediaFile(std::string BaseDir, std::string TypeName,
|
||
std::string ReplacableSkin)
|
||
{
|
||
double dSDist;
|
||
// asBaseDir=BaseDir;
|
||
Global::asCurrentDynamicPath = BaseDir;
|
||
std::string asFileName = BaseDir + TypeName + ".mmd";
|
||
std::string asLoadName = BaseDir + MoverParameters->LoadType + ".t3d";
|
||
|
||
std::string asAnimName;
|
||
bool Stop_InternalData = false;
|
||
pants = NULL; // wska<6B>nik pierwszego obiektu animuj<75>cego dla pantograf<61>w
|
||
cParser parser( TypeName + ".mmd", cParser::buffer_FILE, BaseDir );
|
||
std::string token;
|
||
int i;
|
||
do {
|
||
token = "";
|
||
parser.getTokens(); parser >> token;
|
||
|
||
if( token == "models:") {
|
||
// modele i podmodele
|
||
iMultiTex = 0; // czy jest wiele tekstur wymiennych?
|
||
parser.getTokens();
|
||
parser >> asModel;
|
||
if (asModel.find('#') == asModel.length()) // Ra 2015-01: nie podoba mi si<73> to
|
||
{ // model wymaga wielu tekstur wymiennych
|
||
iMultiTex = 1;
|
||
asModel = asModel.substr(0, asModel.length() - 1);
|
||
}
|
||
if ((i = asModel.find(',')) != std::string::npos)
|
||
{ // Ra 2015-01: mo<6D>e szuka<6B> przecinka w
|
||
// nazwie modelu, a po przecinku by<62>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
|
||
}
|
||
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);
|
||
if (ReplacableSkin != "none")
|
||
{ // 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] = TTexturesManager::GetTextureID(NULL, NULL, Global::asCurrentTexturePath + "nowhere", 9);
|
||
/*
|
||
if ((i = ReplacableSkin.Pos("|")) > 0) // replacable dzielone
|
||
{
|
||
iMultiTex = -1;
|
||
ReplacableSkinID[-iMultiTex] = TTexturesManager::GetTextureID(
|
||
NULL, NULL, ReplacableSkin.SubString(1, i - 1).c_str(),
|
||
Global::iDynamicFiltering);
|
||
ReplacableSkin.Delete(1, i); // usuni<6E>cie razem z pionow<6F> kresk<73>
|
||
ReplacableSkin = Global::asCurrentTexturePath +
|
||
ReplacableSkin; // odtworzenie pocz<63>tku <20>cie<69>ki
|
||
// sprawdzi<7A>, ile jest i ustawi<77> iMultiTex na liczb<7A> podanych tekstur
|
||
if (!ReplacableSkin.IsEmpty())
|
||
{ // pr<70>ba wyci<63>cia drugiej nazwy
|
||
iMultiTex = -2; // skoro zosta<74>o co<63> po kresce, to s<> co najmniej dwie
|
||
if ((i = ReplacableSkin.Pos("|")) == 0) // gdy nie ma ju<6A> kreski
|
||
ReplacableSkinID[-iMultiTex] = TTexturesManager::GetTextureID(
|
||
NULL, NULL, ReplacableSkin.SubString(1, i - 1).c_str(),
|
||
Global::iDynamicFiltering);
|
||
else
|
||
{ // jak jest kreska, to wczyta<74> drug<75> i pr<70>bowa<77> trzeci<63>
|
||
ReplacableSkinID[-iMultiTex] = TTexturesManager::GetTextureID(
|
||
NULL, NULL, ReplacableSkin.SubString(1, i - 1).c_str(),
|
||
Global::iDynamicFiltering);
|
||
ReplacableSkin.Delete(1, i); // usuni<6E>cie razem z pionow<6F> kresk<73>
|
||
ReplacableSkin = Global::asCurrentTexturePath +
|
||
ReplacableSkin; // odtworzenie pocz<63>tku <20>cie<69>ki
|
||
if (!ReplacableSkin.IsEmpty())
|
||
{ // pr<70>ba wyci<63>cia trzeciej nazwy
|
||
iMultiTex =
|
||
-3; // skoro zosta<74>o co<63> po kresce, to s<> co najmniej trzy
|
||
if ((i = ReplacableSkin.Pos("|")) == 0) // gdy nie ma ju<6A> kreski
|
||
ReplacableSkinID[-iMultiTex] = TTexturesManager::GetTextureID(
|
||
NULL, NULL, ReplacableSkin.SubString(1, i - 1).c_str(),
|
||
Global::iDynamicFiltering);
|
||
else
|
||
{ // jak jest kreska, to wczyta<74> trzeci<63> i pr<70>bowa<77> czwart<72>
|
||
ReplacableSkinID[-iMultiTex] = TTexturesManager::GetTextureID(
|
||
NULL, NULL, ReplacableSkin.SubString(1, i - 1).c_str(),
|
||
Global::iDynamicFiltering);
|
||
ReplacableSkin.Delete(1, i); // usuni<6E>cie razem z pionow<6F> kresk<73>
|
||
ReplacableSkin = Global::asCurrentTexturePath +
|
||
ReplacableSkin; // odtworzenie pocz<63>tku <20>cie<69>ki
|
||
if (!ReplacableSkin.IsEmpty())
|
||
{ // pr<70>ba wyci<63>cia trzeciej nazwy
|
||
iMultiTex = -4; // skoro zosta<74>o co<63> po kresce, to s<> co
|
||
// najmniej cztery
|
||
ReplacableSkinID[-iMultiTex] =
|
||
TTexturesManager::GetTextureID(
|
||
NULL, NULL,
|
||
ReplacableSkin.SubString(1, i - 1).c_str(),
|
||
Global::iDynamicFiltering);
|
||
// wi<77>cej na razie nie zadzia<69>a, a u tak trzeba to do modeli
|
||
// przenie<69><65>
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
*/
|
||
if (iMultiTex > 0)
|
||
{ // je<6A>li model ma 4 tekstury
|
||
ReplacableSkinID[1] = TTexturesManager::GetTextureID(
|
||
NULL, NULL, ReplacableSkin + ",1", Global::iDynamicFiltering);
|
||
if (ReplacableSkinID[1])
|
||
{ // pierwsza z zestawu znaleziona
|
||
ReplacableSkinID[2] = TTexturesManager::GetTextureID(
|
||
NULL, NULL, ReplacableSkin + ",2", Global::iDynamicFiltering);
|
||
if (ReplacableSkinID[2])
|
||
{
|
||
iMultiTex = 2; // ju<6A> s<> dwie
|
||
ReplacableSkinID[3] = TTexturesManager::GetTextureID(
|
||
NULL, NULL, ReplacableSkin + ",3",
|
||
Global::iDynamicFiltering);
|
||
if (ReplacableSkinID[3])
|
||
{
|
||
iMultiTex = 3; // a teraz nawet trzy
|
||
ReplacableSkinID[4] = TTexturesManager::GetTextureID(
|
||
NULL, NULL, ReplacableSkin + ",4",
|
||
Global::iDynamicFiltering);
|
||
if (ReplacableSkinID[4])
|
||
iMultiTex = 4; // jak s<> cztery, to blokujemy podmian<61> tekstury
|
||
// rozk<7A>adem
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{ // zestaw nie zadzia<69>a<EFBFBD>, pr<70>bujemy normanie
|
||
iMultiTex = 0;
|
||
ReplacableSkinID[1] = TTexturesManager::GetTextureID(
|
||
NULL, NULL, ReplacableSkin, Global::iDynamicFiltering);
|
||
}
|
||
}
|
||
else
|
||
|
||
ReplacableSkinID[1] = TTexturesManager::GetTextureID(
|
||
NULL, NULL, ReplacableSkin, Global::iDynamicFiltering);
|
||
if (TTexturesManager::GetAlpha(ReplacableSkinID[1]))
|
||
iAlpha = 0x31310031; // tekstura -1 z kana<6E>em alfa - nie renderowa<77> w cyklu
|
||
// nieprzezroczystych
|
||
else
|
||
iAlpha = 0x30300030; // wszystkie tekstury nieprzezroczyste - nie
|
||
// renderowa<77> w
|
||
// cyklu przezroczystych
|
||
if (ReplacableSkinID[2])
|
||
if (TTexturesManager::GetAlpha(ReplacableSkinID[2]))
|
||
iAlpha |= 0x02020002; // tekstura -2 z kana<6E>em alfa - nie renderowa<77>
|
||
// w cyklu
|
||
// nieprzezroczystych
|
||
if (ReplacableSkinID[3])
|
||
if (TTexturesManager::GetAlpha(ReplacableSkinID[3]))
|
||
iAlpha |= 0x04040004; // tekstura -3 z kana<6E>em alfa - nie renderowa<77>
|
||
// w cyklu
|
||
// nieprzezroczystych
|
||
if (ReplacableSkinID[4])
|
||
if (TTexturesManager::GetAlpha(ReplacableSkinID[4]))
|
||
iAlpha |= 0x08080008; // tekstura -4 z kana<6E>em alfa - nie renderowa<77>
|
||
// w cyklu
|
||
// nieprzezroczystych
|
||
}
|
||
// Winger 040304 - ladowanie przedsionkow dla EZT
|
||
if (MoverParameters->TrainType == dt_EZT)
|
||
{
|
||
asModel = "przedsionki.t3d";
|
||
asModel = BaseDir + asModel;
|
||
mdPrzedsionek = TModelsManager::GetModel(asModel, true);
|
||
}
|
||
if (!MoverParameters->LoadAccepted.empty())
|
||
// if (MoverParameters->LoadAccepted!=AnsiString("")); // &&
|
||
// MoverParameters->LoadType!=AnsiString("passengers"))
|
||
if (MoverParameters->EnginePowerSource.SourceType == CurrentCollector)
|
||
{ // warto<74><6F> niby "pantstate" - nazwa dla
|
||
// formalno<6E>ci, wa<77>na jest ilo<6C><6F>
|
||
if (MoverParameters->Load == 1)
|
||
MoverParameters->PantFront(true);
|
||
else if (MoverParameters->Load == 2)
|
||
MoverParameters->PantRear(true);
|
||
else if (MoverParameters->Load == 3)
|
||
{
|
||
MoverParameters->PantFront(true);
|
||
MoverParameters->PantRear(true);
|
||
}
|
||
else if (MoverParameters->Load == 4)
|
||
MoverParameters->DoubleTr = -1;
|
||
else if (MoverParameters->Load == 5)
|
||
{
|
||
MoverParameters->DoubleTr = -1;
|
||
MoverParameters->PantRear(true);
|
||
}
|
||
else if (MoverParameters->Load == 6)
|
||
{
|
||
MoverParameters->DoubleTr = -1;
|
||
MoverParameters->PantFront(true);
|
||
}
|
||
else if (MoverParameters->Load == 7)
|
||
{
|
||
MoverParameters->DoubleTr = -1;
|
||
MoverParameters->PantFront(true);
|
||
MoverParameters->PantRear(true);
|
||
}
|
||
}
|
||
else // Ra: tu wczytywanie modelu <20>adunku jest w porz<72>dku
|
||
mdLoad = TModelsManager::GetModel(asLoadName, true); // ladunek
|
||
Global::asCurrentTexturePath = szTexturePath; // z powrotem defaultowa sciezka do tekstur
|
||
do {
|
||
token = "";
|
||
parser.getTokens(); parser >> token;
|
||
|
||
if( token == "animations:" ) {
|
||
// Ra: ustawienie ilo<6C>ci poszczeg<65>lnych animacji -
|
||
// musi by<62> jako pierwsze, inaczej ilo<6C>ci b<>d<EFBFBD> domy<6D>lne
|
||
if( nullptr == pAnimations )
|
||
{ // je<6A>li nie ma jeszcze tabeli animacji, mo<6D>na
|
||
// odczyta<74> nowe ilo<6C>ci
|
||
int co = 0, ile = -1;
|
||
iAnimations = 0;
|
||
do
|
||
{ // kolejne liczby to ilo<6C><6F> animacj, -1 to znacznik ko<6B>ca
|
||
parser.getTokens( 1, false );
|
||
parser >> ile;
|
||
// animacji
|
||
// if (co==ANIM_PANTS)
|
||
// if (!Global::bLoadTraction)
|
||
// if (!DebugModeFlag) //w debugmode pantografy maj<61> "niby
|
||
// dzia<69>a<EFBFBD>"
|
||
// ile=0; //wy<77><79>czenie animacji pantograf<61>w
|
||
if (co < ANIM_TYPES)
|
||
if (ile >= 0)
|
||
{
|
||
iAnimType[co] = ile; // zapami<6D>tanie
|
||
iAnimations += ile; // og<6F>lna ilo<6C><6F> animacji
|
||
}
|
||
++co;
|
||
} while (ile >= 0); //-1 to znacznik ko<6B>ca
|
||
|
||
while( co < ANIM_TYPES ) {
|
||
iAnimType[ co++ ] = 0; // zerowanie pozosta<74>ych
|
||
}
|
||
|
||
parser.getTokens(); parser >> token; // NOTE: should this be here? seems at best superfluous
|
||
}
|
||
// WriteLog("Total animations: "+AnsiString(iAnimations));
|
||
}
|
||
if( nullptr == pAnimations )
|
||
{ // Ra: tworzenie tabeli animacji, je<6A>li jeszcze nie
|
||
// by<62>o
|
||
if (!iAnimations) // je<6A>li nie podano jawnie, ile ma by<62> animacji
|
||
iAnimations = 28; // tyle by<62>o kiedy<64> w ka<6B>dym poje<6A>dzie (2 wi<77>zary wypad<61>y)
|
||
/* //pojazd mo<6D>e mie<69> pantograf do innych cel<65>w ni<6E> nap<61>d
|
||
if (MoverParameters->EnginePowerSource.SourceType!=CurrentCollector)
|
||
{//nie b<>dzie pantograf<61>w, to si<73> troch<63> upro<72>ci
|
||
iAnimations-=iAnimType[ANIM_PANTS]; //domy<6D>lnie by<62>y 2 pantografy
|
||
iAnimType[ANIM_PANTS]=0;
|
||
}
|
||
*/
|
||
pAnimations = new TAnim[iAnimations];
|
||
int i, j, k = 0, sm = 0;
|
||
for (j = 0; j < ANIM_TYPES; ++j)
|
||
for (i = 0; i < iAnimType[j]; ++i)
|
||
{
|
||
if (j == ANIM_PANTS) // zliczamy poprzednie animacje
|
||
if (!pants)
|
||
if (iAnimType[ANIM_PANTS]) // o ile jakie<69> pantografy s<> (a
|
||
// domy<6D>lnie s<>)
|
||
pants = pAnimations +
|
||
k; // zapami<6D>tanie na potrzeby wyszukania submodeli
|
||
pAnimations[k].iShift = sm; // przesuni<6E>cie do przydzielenia wska<6B>nika
|
||
sm += pAnimations[k++].TypeSet(j); // ustawienie typu animacji i
|
||
// zliczanie tablicowanych
|
||
// submodeli
|
||
}
|
||
if (sm) // o ile s<> bardziej z<>o<EFBFBD>one animacje
|
||
{
|
||
pAnimated = new TSubModel *[sm]; // tabela na animowane submodele
|
||
for (k = 0; k < iAnimations; ++k)
|
||
pAnimations[k].smElement =
|
||
pAnimated +
|
||
pAnimations[k].iShift; // przydzielenie wska<6B>nika do tabelki
|
||
}
|
||
}
|
||
|
||
if(token == "lowpolyinterior:") {
|
||
// ABu: wnetrze lowpoly
|
||
parser.getTokens();
|
||
parser >> asModel;
|
||
asModel = BaseDir + asModel; // McZapkie-200702 - dynamics maja swoje modele w dynamic/basedir
|
||
Global::asCurrentTexturePath = BaseDir; // biezaca sciezka do tekstur to dynamic/...
|
||
mdLowPolyInt = TModelsManager::GetModel(asModel, true);
|
||
// Global::asCurrentTexturePath=AnsiString(szTexturePath); //kiedy<64>
|
||
// uproszczone
|
||
// wn<77>trze miesza<7A>o tekstury nieba
|
||
}
|
||
|
||
if( token == "brakemode:" ) {
|
||
// Ra 15-01: ga<67>ka nastawy hamulca
|
||
parser.getTokens();
|
||
parser >> asAnimName;
|
||
smBrakeMode = mdModel->GetFromName(asAnimName.c_str());
|
||
// jeszcze wczyta<74> k<>ty obrotu dla poszczeg<65>lnych ustawie<69>
|
||
}
|
||
|
||
if( token == "loadmode:" ) {
|
||
// Ra 15-01: ga<67>ka nastawy hamulca
|
||
parser.getTokens();
|
||
parser >> asAnimName;
|
||
smLoadMode = mdModel->GetFromName(asAnimName.c_str());
|
||
// jeszcze wczyta<74> k<>ty obrotu dla poszczeg<65>lnych ustawie<69>
|
||
}
|
||
|
||
else if (token == "animwheelprefix:") {
|
||
// prefiks kr<6B>c<EFBFBD>cych si<73> k<><6B>
|
||
int i, j, k, m;
|
||
parser.getTokens( 1, false ); parser >> token;
|
||
for (i = 0; i < iAnimType[ANIM_WHEELS]; ++i) // liczba osi
|
||
{ // McZapkie-050402: wyszukiwanie kol o nazwie str*
|
||
asAnimName = token + std::to_string(i + 1);
|
||
pAnimations[i].smAnimated =
|
||
mdModel->GetFromName(asAnimName.c_str()); // ustalenie submodelu
|
||
if (pAnimations[i].smAnimated)
|
||
{ //++iAnimatedAxles;
|
||
pAnimations[i].smAnimated->WillBeAnimated(); // wy<77><79>czenie optymalizacji
|
||
// transformu
|
||
/* pAnimations[i].yUpdate = UpdateAxle; // animacja osi
|
||
*/ pAnimations[ i ].yUpdate = std::bind( &TDynamicObject::UpdateAxle, this, std::placeholders::_1 );
|
||
pAnimations[i].fMaxDist =
|
||
50 *
|
||
MoverParameters->WheelDiameter; // nie kr<6B>ci<63> w wi<77>kszej odleg<65>o<EFBFBD>ci
|
||
pAnimations[i].fMaxDist *=
|
||
pAnimations[i].fMaxDist *
|
||
MoverParameters->WheelDiameter; // 50m do kwadratu, a <20>rednica
|
||
// do trzeciej
|
||
pAnimations[i].fMaxDist *= Global::fDistanceFactor; // wsp<73><70>czynnik
|
||
// przeliczeniowy
|
||
// jako<6B>ci ekranu
|
||
}
|
||
}
|
||
// Ra: ustawianie indeks<6B>w osi
|
||
for (i = 0; i < iAnimType[ANIM_WHEELS];
|
||
++i) // ilo<6C><6F> osi (zabezpieczenie przed b<><62>dami w CHK)
|
||
pAnimations[i].dWheelAngle =
|
||
dWheelAngle + 1; // domy<6D>lnie wska<6B>nik na nap<61>dzaj<61>ce
|
||
i = 0;
|
||
j = 1;
|
||
k = 0;
|
||
m = 0; // numer osi; kolejny znak; ile osi danego typu; kt<6B>ra <20>rednica
|
||
if ((MoverParameters->WheelDiameterL != MoverParameters->WheelDiameter) ||
|
||
(MoverParameters->WheelDiameterT != MoverParameters->WheelDiameter))
|
||
{ // obs<62>uga r<><72>nych <20>rednic, o
|
||
// ile wyst<73>puj<75>
|
||
while ((i < iAnimType[ANIM_WHEELS]) &&
|
||
(j <= MoverParameters->AxleArangement.length()))
|
||
{ // wersja ze wska<6B>nikami jest
|
||
// bardziej elastyczna na nietypowe
|
||
// uk<75>ady
|
||
if ((k >= 'A') && (k <= 'J')) // 10 chyba maksimum?
|
||
{
|
||
pAnimations[i++].dWheelAngle =
|
||
dWheelAngle + 1; // obr<62>t osi nap<61>dzaj<61>cych
|
||
--k; // nast<73>pna b<>dzie albo taka sama, albo bierzemy kolejny
|
||
// znak
|
||
m = 2; // nast<73>puj<75>ce toczne b<>d<EFBFBD> mia<69>y inn<6E> <20>rednic<69>
|
||
}
|
||
else if ((k >= '1') && (k <= '9'))
|
||
{
|
||
pAnimations[i++].dWheelAngle = dWheelAngle + m; // obr<62>t osi
|
||
// tocznych
|
||
--k; // nast<73>pna b<>dzie albo taka sama, albo bierzemy kolejny
|
||
// znak
|
||
}
|
||
else
|
||
k = MoverParameters->AxleArangement[j++]; // pobranie kolejnego
|
||
// znaku
|
||
}
|
||
}
|
||
}
|
||
// else if (str==AnsiString("animrodprefix:")) //prefiks wiazarow dwoch
|
||
// {
|
||
// str= Parser->GetNextSymbol();
|
||
// for (int i=1; i<=2; i++)
|
||
// {//McZapkie-050402: wyszukiwanie max 2 wiazarow o nazwie str*
|
||
// asAnimName=str+i;
|
||
// smWiazary[i-1]=mdModel->GetFromName(asAnimName.c_str());
|
||
// smWiazary[i-1]->WillBeAnimated();
|
||
// }
|
||
// }
|
||
|
||
else if( token == "animpantprefix:" ) {
|
||
// Ra: pantografy po
|
||
// nowemu maj<61> literki
|
||
// i numerki
|
||
}
|
||
// Pantografy - Winger 160204
|
||
if( token == "animpantrd1prefix:" ) {
|
||
// prefiks ramion dolnych 1
|
||
parser.getTokens(); parser >> token;
|
||
float4x4 m; // macierz do wyliczenia pozycji i wektora ruchu pantografu
|
||
TSubModel *sm;
|
||
if (pants)
|
||
for (int i = 0; i < iAnimType[ANIM_PANTS]; i++)
|
||
{ // Winger 160204: wyszukiwanie max 2 patykow o nazwie
|
||
// str*
|
||
asAnimName = token + std::to_string(i + 1);
|
||
sm = mdModel->GetFromName(asAnimName.c_str());
|
||
pants[i].smElement[0] = sm; // jak NULL, to nie b<>dzie animowany
|
||
if (sm)
|
||
{ // w EP09 wywala<6C>o si<73> tu z powodu NULL
|
||
sm->WillBeAnimated();
|
||
sm->ParentMatrix(&m); // pobranie macierzy transformacji
|
||
// m(3)[1]=m[3][1]+0.054; //w g<>r<EFBFBD> o wysoko<6B><6F> <20>lizgu (na razie
|
||
// tak)
|
||
if ((mdModel->Flags() & 0x8000) == 0) // je<6A>li wczytano z T3D
|
||
m.InitialRotate(); // mo<6D>e by<62> potrzebny dodatkowy obr<62>t,
|
||
// je<6A>li
|
||
// wczytano z T3D, tzn. przed wykonaniem
|
||
// Init()
|
||
pants[i].fParamPants->vPos.z =
|
||
m[3][0]; // przesuni<6E>cie w bok (asymetria)
|
||
pants[i].fParamPants->vPos.y =
|
||
m[3][1]; // przesuni<6E>cie w g<>r<EFBFBD> odczytane z modelu
|
||
if ((sm = pants[i].smElement[0]->ChildGet()) != NULL)
|
||
{ // je<6A>li ma potomny, mo<6D>na policzy<7A> d<>ugo<67><6F>
|
||
// (odleg<65>o<EFBFBD><6F> potomnego
|
||
// od osi obrotu)
|
||
m = float4x4(*sm->GetMatrix()); // wystarczy<7A>by wska<6B>nik, nie
|
||
// trzeba kopiowa<77>
|
||
// mo<6D>e trzeba: pobra<72> macierz dolnego ramienia, wyzerowa<77>
|
||
// przesuni<6E>cie, przemno<6E>y<EFBFBD> przez macierz g<>rnego
|
||
pants[i].fParamPants->fHoriz = -fabs(m[3][1]);
|
||
pants[i].fParamPants->fLenL1 =
|
||
hypot(m[3][1], m[3][2]); // po osi OX nie potrzeba
|
||
pants[i].fParamPants->fAngleL0 =
|
||
atan2(fabs(m[3][2]), fabs(m[3][1]));
|
||
// if (pants[i].fParamPants->fAngleL0<M_PI_2)
|
||
// pants[i].fParamPants->fAngleL0+=M_PI; //gdyby w odwrotn<74>
|
||
// stron<6F> wysz<73>o
|
||
// if
|
||
// ((pants[i].fParamPants->fAngleL0<0.03)||(pants[i].fParamPants->fAngleL0>0.09))
|
||
// //normalnie ok. 0.05
|
||
// pants[i].fParamPants->fAngleL0=pants[i].fParamPants->fAngleL;
|
||
pants[i].fParamPants->fAngleL =
|
||
pants[i].fParamPants->fAngleL0; // pocz<63>tkowy k<>t dolnego
|
||
// ramienia
|
||
if ((sm = sm->ChildGet()) != NULL)
|
||
{ // je<6A>li dalej jest
|
||
// <20>lizg, mo<6D>na policzy<7A>
|
||
// d<>ugo<67><6F> g<>rnego
|
||
// ramienia
|
||
m = float4x4(*sm->GetMatrix()); // wystarczy<7A>by wska<6B>nik,
|
||
// nie trzeba kopiowa<77>
|
||
// trzeba by uwzgl<67>dni<6E> macierz dolnego ramienia, <20>eby
|
||
// uzyska<6B> k<>t do poziomu...
|
||
pants[i].fParamPants->fHoriz +=
|
||
fabs(m(3)[1]); // r<><72>nica d<>ugo<67>ci rzut<75>w ramion na
|
||
// p<>aszczyzn<7A> podstawy (jedna dodatnia,
|
||
// druga ujemna)
|
||
pants[i].fParamPants->fLenU1 =
|
||
hypot(m[3][1], m[3][2]); // po osi OX nie potrzeba
|
||
// pants[i].fParamPants->pantu=acos((1.22*cos(pants[i].fParamPants->fAngleL)+0.535)/1.755);
|
||
// //g<>rne rami<6D>
|
||
// pants[i].fParamPants->fAngleU0=acos((1.176289*cos(pants[i].fParamPants->fAngleL)+0.54555075)/1.724482197);
|
||
// //g<>rne rami<6D>
|
||
pants[i].fParamPants->fAngleU0 =
|
||
atan2(fabs(m[3][2]),
|
||
fabs(m[3][1])); // pocz<63>tkowy k<>t g<>rnego
|
||
// ramienia, odczytany z modelu
|
||
// if (pants[i].fParamPants->fAngleU0<M_PI_2)
|
||
// pants[i].fParamPants->fAngleU0+=M_PI; //gdyby w odwrotn<74>
|
||
// stron<6F> wysz<73>o
|
||
// if (pants[i].fParamPants->fAngleU0<0)
|
||
// pants[i].fParamPants->fAngleU0=-pants[i].fParamPants->fAngleU0;
|
||
// if
|
||
// ((pants[i].fParamPants->fAngleU0<0.00)||(pants[i].fParamPants->fAngleU0>0.09))
|
||
// //normalnie ok. 0.07
|
||
// pants[i].fParamPants->fAngleU0=acos((pants[i].fParamPants->fLenL1*cos(pants[i].fParamPants->fAngleL)+pants[i].fParamPants->fHoriz)/pants[i].fParamPants->fLenU1);
|
||
pants[i].fParamPants->fAngleU =
|
||
pants[i].fParamPants->fAngleU0; // pocz<63>tkowy k<>t
|
||
// Ra: ze wzgl<67>du na to, <20>e niekt<6B>re modele pantograf<61>w s<>
|
||
// zr<7A>bane, ich mierzenie ma obecnie ograniczony sens
|
||
sm->ParentMatrix(&m); // pobranie macierzy transformacji
|
||
// pivota <20>lizgu wzgl<67>dem wstawienia
|
||
// pojazdu
|
||
if ((mdModel->Flags() & 0x8000) == 0) // je<6A>li wczytano z
|
||
// T3D
|
||
m.InitialRotate(); // mo<6D>e by<62> potrzebny dodatkowy
|
||
// obr<62>t, je<6A>li wczytano z T3D, tzn.
|
||
// przed wykonaniem Init()
|
||
float det = Det(m);
|
||
if (std::fabs(det - 1.0) < 0.001) // dopuszczamy 1 promil b<><62>du
|
||
// na skalowaniu <20>lizgu
|
||
{ // skalowanie jest w normie, mo<6D>na pobra<72> wymiary z modelu
|
||
pants[i].fParamPants->fHeight =
|
||
sm->MaxY(m); // przeliczenie maksimum wysoko<6B>ci
|
||
// wierzcho<68>k<EFBFBD>w wzgl<67>dem macierzy
|
||
pants[i].fParamPants->fHeight -=
|
||
m[3][1]; // odj<64>cie wysoko<6B>ci pivota <20>lizgu
|
||
pants[i].fParamPants->vPos.x =
|
||
m[3][2]; // przy okazji odczyta<74> z modelu pozycj<63> w
|
||
// d<>ugo<67>ci
|
||
// ErrorLog("Model OK: "+asModel+",
|
||
// height="+pants[i].fParamPants->fHeight);
|
||
// ErrorLog("Model OK: "+asModel+",
|
||
// pos.x="+pants[i].fParamPants->vPos.x);
|
||
}
|
||
else
|
||
{ // gdy kto<74> przesadzi<7A> ze skalowaniem
|
||
pants[i].fParamPants->fHeight =
|
||
0.0; // niech b<>dzie odczyt z pantfactors:
|
||
ErrorLog("Bad model: " + asModel + ", scale of " +
|
||
(sm->pName) + " is " +
|
||
std::to_string(100.0 * det) + "%");
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else
|
||
ErrorLog("Bad model: " + asFileName + " - missed submodel " +
|
||
asAnimName); // brak ramienia
|
||
}
|
||
}
|
||
|
||
else if( token == "animpantrd2prefix:" ) {
|
||
// prefiks ramion dolnych 2
|
||
parser.getTokens(); parser >> token;
|
||
float4x4 m; // macierz do wyliczenia pozycji i wektora ruchu pantografu
|
||
TSubModel *sm;
|
||
if( pants ) {
|
||
for( int i = 0; i < iAnimType[ ANIM_PANTS ]; i++ ) { // Winger 160204: wyszukiwanie max 2 patykow o nazwie
|
||
// str*
|
||
asAnimName = token + std::to_string( i + 1 );
|
||
sm = mdModel->GetFromName( asAnimName.c_str() );
|
||
pants[ i ].smElement[ 1 ] = sm; // jak NULL, to nie b<>dzie animowany
|
||
if( sm ) { // w EP09 wywala<6C>o si<73> tu z powodu NULL
|
||
sm->WillBeAnimated();
|
||
if( pants[ i ].fParamPants->vPos.y == 0.0 ) { // je<6A>li pierwsze rami<6D> nie ustawi<77>o tej warto<74>ci,
|
||
// pr<70>bowa<77> drugim
|
||
//!!!! docelowo zrobi<62> niezale<6C>n<EFBFBD> animacj<63> ramion z ka<6B>dej
|
||
// strony
|
||
m = float4x4(
|
||
*sm->GetMatrix() ); // skopiowanie, bo b<>dziemy mno<6E>y<EFBFBD>
|
||
m( 3 )[ 1 ] =
|
||
m[ 3 ][ 1 ] + 0.054; // w g<>r<EFBFBD> o wysoko<6B><6F> <20>lizgu (na razie tak)
|
||
while( sm->Parent ) {
|
||
if( sm->Parent->GetMatrix() )
|
||
m = *sm->Parent->GetMatrix() * m;
|
||
sm = sm->Parent;
|
||
}
|
||
pants[ i ].fParamPants->vPos.z =
|
||
m[ 3 ][ 0 ]; // przesuni<6E>cie w bok (asymetria)
|
||
pants[ i ].fParamPants->vPos.y =
|
||
m[ 3 ][ 1 ]; // przesuni<6E>cie w g<>r<EFBFBD> odczytane z modelu
|
||
}
|
||
}
|
||
else
|
||
ErrorLog( "Bad model: " + asFileName + " - missed submodel " +
|
||
asAnimName ); // brak ramienia
|
||
}
|
||
}
|
||
}
|
||
|
||
else if( token == "animpantrg1prefix:" ) {
|
||
// prefiks ramion g<>rnych 1
|
||
parser.getTokens(); parser >> token;
|
||
if( pants ) {
|
||
for( int i = 0; i < iAnimType[ ANIM_PANTS ]; i++ ) { // Winger 160204: wyszukiwanie max 2 patykow o nazwie
|
||
// str*
|
||
asAnimName = token + std::to_string( i + 1 );
|
||
pants[ i ].smElement[ 2 ] = mdModel->GetFromName( asAnimName.c_str() );
|
||
pants[ i ].smElement[ 2 ]->WillBeAnimated();
|
||
}
|
||
}
|
||
}
|
||
|
||
else if( token == "animpantrg2prefix:" ) {
|
||
// prefiks ramion g<>rnych 2
|
||
parser.getTokens(); parser >> token;
|
||
if( pants ) {
|
||
for( int i = 0; i < iAnimType[ ANIM_PANTS ]; i++ ) { // Winger 160204: wyszukiwanie max 2 patykow o nazwie
|
||
// str*
|
||
asAnimName = token + std::to_string( i + 1 );
|
||
pants[ i ].smElement[ 3 ] = mdModel->GetFromName( asAnimName.c_str() );
|
||
pants[ i ].smElement[ 3 ]->WillBeAnimated();
|
||
}
|
||
}
|
||
}
|
||
|
||
else if( token == "animpantslprefix:" ) {
|
||
// prefiks <20>lizgaczy
|
||
parser.getTokens(); parser >> token;
|
||
if( pants ) {
|
||
for( int i = 0; i < iAnimType[ ANIM_PANTS ]; i++ ) { // Winger 160204: wyszukiwanie max 2 patykow o nazwie
|
||
// str*
|
||
asAnimName = token + std::to_string( i + 1 );
|
||
pants[ i ].smElement[ 4 ] = mdModel->GetFromName( asAnimName.c_str() );
|
||
pants[ i ].smElement[ 4 ]->WillBeAnimated();
|
||
/* pants[ i ].yUpdate = UpdatePant;
|
||
*/ pants[ i ].yUpdate = std::bind( &TDynamicObject::UpdatePant, this, std::placeholders::_1 );
|
||
pants[ i ].fMaxDist = 300 * 300; // nie podnosi<73> w wi<77>kszej odleg<65>o<EFBFBD>ci
|
||
pants[ i ].iNumber = i;
|
||
}
|
||
}
|
||
}
|
||
else if( token == "pantfactors:" ) {
|
||
// Winger 010304:
|
||
// parametry pantografow
|
||
double pant1x, pant2x, pant1h, pant2h;
|
||
parser.getTokens( 4, false );
|
||
parser
|
||
>> pant1x
|
||
>> pant2x
|
||
>> pant1h // wysoko<6B><6F> pierwszego <20>lizgu
|
||
>> pant2h;// wysoko<6B><6F> drugiego <20>lizgu
|
||
if( pant1h > 0.5 ) {
|
||
pant1h = pant2h; // tu mo<6D>e by<62> zbyt du<64>a warto<74><6F>
|
||
}
|
||
if ((pant1x < 0) &&
|
||
(pant2x > 0)) // pierwsza powinna by<62> dodatnia, a druga ujemna
|
||
{
|
||
pant1x = -pant1x;
|
||
pant2x = -pant2x;
|
||
}
|
||
if( pants ) {
|
||
for( int i = 0; i < iAnimType[ ANIM_PANTS ]; ++i ) { // przepisanie wsp<73><70>czynnik<69>w do pantograf<61>w (na razie
|
||
// nie b<>dzie lepiej)
|
||
pants[ i ].fParamPants->fAngleL =
|
||
pants[ i ].fParamPants->fAngleL0; // pocz<63>tkowy k<>t dolnego ramienia
|
||
pants[ i ].fParamPants->fAngleU =
|
||
pants[ i ].fParamPants->fAngleU0; // pocz<63>tkowy k<>t
|
||
// pants[i].fParamPants->PantWys=1.22*sin(pants[i].fParamPants->fAngleL)+1.755*sin(pants[i].fParamPants->fAngleU);
|
||
// //wysoko<6B><6F> pocz<63>tkowa
|
||
// pants[i].fParamPants->PantWys=1.176289*sin(pants[i].fParamPants->fAngleL)+1.724482197*sin(pants[i].fParamPants->fAngleU);
|
||
// //wysoko<6B><6F> pocz<63>tkowa
|
||
if( pants[ i ].fParamPants->fHeight == 0.0 ) // gdy jest
|
||
// nieprawdopodobna
|
||
// warto<74><6F> (np. nie
|
||
// znaleziony <20>lizg)
|
||
{ // gdy pomiary modelu nie uda<64>y si<73>, odczyt podanych parametr<74>w
|
||
// z MMD
|
||
pants[ i ].fParamPants->vPos.x = ( i & 1 ) ? pant2x : pant1x;
|
||
pants[ i ].fParamPants->fHeight =
|
||
( i & 1 ) ? pant2h :
|
||
pant1h; // wysoko<6B><6F> <20>lizgu jest zapisana w MMD
|
||
}
|
||
pants[ i ].fParamPants->PantWys =
|
||
pants[ i ].fParamPants->fLenL1 * sin( pants[ i ].fParamPants->fAngleL ) +
|
||
pants[ i ].fParamPants->fLenU1 * sin( pants[ i ].fParamPants->fAngleU ) +
|
||
pants[ i ].fParamPants->fHeight; // wysoko<6B><6F> pocz<63>tkowa
|
||
// pants[i].fParamPants->vPos.y=panty-panth-pants[i].fParamPants->PantWys;
|
||
// //np. 4.429-0.097=4.332=~4.335
|
||
// pants[i].fParamPants->vPos.z=0; //niezerowe dla pantograf<61>w
|
||
// asymetrycznych
|
||
pants[ i ].fParamPants->PantTraction = pants[ i ].fParamPants->PantWys;
|
||
pants[ i ].fParamPants->fWidth =
|
||
0.5 *
|
||
MoverParameters->EnginePowerSource.CollectorParameters
|
||
.CSW; // po<70>owa szeroko<6B>ci <20>lizgu; jest w "Power: CSW="
|
||
}
|
||
}
|
||
}
|
||
|
||
else if (token == "animpistonprefix:") {
|
||
// prefiks t<>oczysk - na razie u<>ywamy modeli pantograf<61>w
|
||
parser.getTokens(1, false); parser >> token;
|
||
for( int i = 1; i <= 2; ++i )
|
||
{
|
||
// asAnimName=str+i;
|
||
// smPatykird1[i-1]=mdModel->GetFromName(asAnimName.c_str());
|
||
// smPatykird1[i-1]->WillBeAnimated();
|
||
}
|
||
}
|
||
|
||
else if( token == "animconrodprefix:" ) {
|
||
// prefiks korbowod<6F>w - na razie u<>ywamy modeli pantograf<61>w
|
||
parser.getTokens(); parser >> token;
|
||
for( int i = 1; i <= 2; i++ )
|
||
{
|
||
// asAnimName=str+i;
|
||
// smPatykirg1[i-1]=mdModel->GetFromName(asAnimName.c_str());
|
||
// smPatykirg1[i-1]->WillBeAnimated();
|
||
}
|
||
}
|
||
|
||
else if( token == "pistonfactors:" ) {
|
||
// Ra: parametry
|
||
// silnika parowego
|
||
// (t<>oka)
|
||
/* //Ra: tymczasowo wy<77><79>czone ze wzgl<67>du na porz<72>dkowanie animacji
|
||
pantograf<61>w
|
||
pant1x=Parser->GetNextSymbol().ToDouble(); //k<>t przesuni<6E>cia
|
||
dla
|
||
pierwszego t<>oka
|
||
pant2x=Parser->GetNextSymbol().ToDouble(); //k<>t przesuni<6E>cia
|
||
dla
|
||
drugiego t<>oka
|
||
panty=Parser->GetNextSymbol().ToDouble(); //d<>ugo<67><6F> korby (r)
|
||
panth=Parser->GetNextSymbol().ToDouble(); //d<>ugo<67> korbowodu
|
||
(k)
|
||
*/
|
||
MoverParameters->EnginePowerSource.PowerType =
|
||
SteamPower; // Ra: po chamsku, ale z CHK nie dzia<69>a
|
||
}
|
||
|
||
else if( token == "animreturnprefix:" ) {
|
||
// prefiks dr<64><72>ka mimo<6D>rodowego - na razie u<>ywamy modeli pantograf<61>w
|
||
parser.getTokens(1, false); parser >> token;
|
||
for( int i = 1; i <= 2; i++ )
|
||
{
|
||
// asAnimName=str+i;
|
||
// smPatykird2[i-1]=mdModel->GetFromName(asAnimName.c_str());
|
||
// smPatykird2[i-1]->WillBeAnimated();
|
||
}
|
||
}
|
||
|
||
else if (token == "animexplinkprefix:"){ // animreturnprefix:
|
||
// prefiks jarzma - na razie u<>ywamy modeli pantograf<61>w
|
||
parser.getTokens(1, false); parser >> token;
|
||
for( int i = 1; i <= 2; i++ )
|
||
{
|
||
// asAnimName=str+i;
|
||
// smPatykirg2[i-1]=mdModel->GetFromName(asAnimName.c_str());
|
||
// smPatykirg2[i-1]->WillBeAnimated();
|
||
}
|
||
}
|
||
|
||
else if( token == "animpendulumprefix:" ) {
|
||
// prefiks wahaczy
|
||
parser.getTokens(); parser >> token;
|
||
asAnimName = "";
|
||
for (int i = 1; i <= 4; i++)
|
||
{ // McZapkie-050402: wyszukiwanie max 4
|
||
// wahaczy o nazwie str*
|
||
asAnimName = token + std::to_string(i);
|
||
smWahacze[i - 1] = mdModel->GetFromName(asAnimName.c_str());
|
||
smWahacze[i - 1]->WillBeAnimated();
|
||
}
|
||
parser.getTokens(); parser >> token;
|
||
if( token == "pendulumamplitude:" ) {
|
||
parser.getTokens( 1, false );
|
||
parser >> fWahaczeAmp;
|
||
}
|
||
}
|
||
/*
|
||
else if (str == AnsiString("engineer:"))
|
||
{ // nazwa submodelu maszynisty
|
||
str = Parser->GetNextSymbol();
|
||
smMechanik0 = mdModel->GetFromName(str.c_str());
|
||
if (!smMechanik0)
|
||
{ // jak nie ma bez numerka, to mo<6D>e jest z
|
||
// numerkiem?
|
||
smMechanik0 = mdModel->GetFromName(AnsiString(str + "1").c_str());
|
||
smMechanik1 = mdModel->GetFromName(AnsiString(str + "2").c_str());
|
||
}
|
||
// aby da<64>o si<73> go obraca<63>, musi mie<69> w<><77>czon<6F> animacj<63> w T3D!
|
||
// if (!smMechanik1) //je<6A>li drugiego nie ma
|
||
// if (smMechanik0) //a jest pierwszy
|
||
// smMechanik0->WillBeAnimated(); //to b<>dziemy go obraca<63>
|
||
}
|
||
*/
|
||
|
||
else if( token == "animdoorprefix:" ) {
|
||
// nazwa animowanych drzwi
|
||
int i, j, k, m;
|
||
parser.getTokens(1, false); parser >> token;
|
||
for (i = 0, j = 0; i < ANIM_DOORS; ++i)
|
||
j += iAnimType[i]; // zliczanie wcze<7A>niejszych animacji
|
||
for (i = 0; i < iAnimType[ANIM_DOORS]; ++i) // liczba drzwi
|
||
{ // NBMX wrzesien 2003: wyszukiwanie drzwi o nazwie str*
|
||
asAnimName = token + std::to_string(i + 1);
|
||
pAnimations[i + j].smAnimated =
|
||
mdModel->GetFromName(asAnimName.c_str()); // ustalenie submodelu
|
||
if (pAnimations[i + j].smAnimated)
|
||
{ //++iAnimatedDoors;
|
||
pAnimations[i + j].smAnimated->WillBeAnimated(); // wy<77><79>czenie
|
||
// optymalizacji
|
||
// transformu
|
||
switch (MoverParameters->DoorOpenMethod)
|
||
{ // od razu zapinamy
|
||
// potrzebny typ
|
||
// animacji
|
||
case 1:
|
||
/* pAnimations[i + j].yUpdate = UpdateDoorTranslate;
|
||
*/ pAnimations[ i + j ].yUpdate = std::bind( &TDynamicObject::UpdateDoorTranslate, this, std::placeholders::_1 );
|
||
break;
|
||
case 2:
|
||
/* pAnimations[i + j].yUpdate = UpdateDoorRotate;
|
||
*/ pAnimations[ i + j ].yUpdate = std::bind( &TDynamicObject::UpdateDoorRotate, this, std::placeholders::_1 );
|
||
break;
|
||
case 3:
|
||
/* pAnimations[i + j].yUpdate = UpdateDoorFold;
|
||
*/ pAnimations[ i + j ].yUpdate = std::bind( &TDynamicObject::UpdateDoorFold, this, std::placeholders::_1 );
|
||
break; // obr<62>t 3 kolejnych submodeli
|
||
case 4:
|
||
/* pAnimations[i + j].yUpdate = UpdateDoorPlug;
|
||
*/ pAnimations[ i + j ].yUpdate = std::bind( &TDynamicObject::UpdateDoorPlug, this, std::placeholders::_1 );
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
pAnimations[i + j].iNumber = i; // parzyste dzia<69>aj<61> inaczej ni<6E> nieparzyste
|
||
pAnimations[i + j].fMaxDist = 300 * 300; // drzwi to z daleka wida<64>
|
||
pAnimations[i + j].fSpeed = Random(150); // oryginalny koncept z DoorSpeedFactor
|
||
pAnimations[i + j].fSpeed = (pAnimations[i + j].fSpeed + 100) / 100;
|
||
// Ra: te wsp<73><70>czynniki s<> bez sensu, bo modyfikuj<75> wektor
|
||
// przesuni<6E>cia
|
||
}
|
||
}
|
||
}
|
||
|
||
} while( ( token != "" )
|
||
&& ( token != "endmodels" ) );
|
||
|
||
}
|
||
|
||
else if( token == "sounds:" ) {
|
||
// dzwieki
|
||
do {
|
||
token = "";
|
||
parser.getTokens(); parser >> token;
|
||
if( token == "wheel_clatter:" ){
|
||
// polozenia osi w/m srodka pojazdu
|
||
parser.getTokens( 1, false );
|
||
parser >> dSDist;
|
||
for( int i = 0; i < iAxles; i++ ) {
|
||
parser.getTokens( 1, false );
|
||
parser >> dWheelsPosition[ i ];
|
||
parser.getTokens();
|
||
parser >> token;
|
||
if( token != "end" ) {
|
||
rsStukot[ i ].Init( token, dSDist, GetPosition().x,
|
||
GetPosition().y + dWheelsPosition[ i ], GetPosition().z,
|
||
true );
|
||
}
|
||
}
|
||
if( token != "end" ) {
|
||
// TODO: double-check if this if() and/or retrieval makes sense here
|
||
parser.getTokens( 1, false ); parser >> token;
|
||
}
|
||
}
|
||
|
||
else if( ( token == "engine:" )
|
||
&& ( MoverParameters->Power > 0 ) ) {
|
||
// plik z dzwiekiem silnika, mnozniki i ofsety amp. i czest.
|
||
double attenuation;
|
||
parser.getTokens( 2, false );
|
||
parser
|
||
>> token
|
||
>> attenuation;
|
||
rsSilnik.Init(
|
||
token, attenuation,
|
||
GetPosition().x, GetPosition().y, GetPosition().z,
|
||
true, true );
|
||
if( rsSilnik.GetWaveTime() == 0 ) {
|
||
ErrorLog( "Missed sound: \"" + token + "\" for " + asFileName );
|
||
}
|
||
parser.getTokens( 1, false );
|
||
parser >> rsSilnik.AM;
|
||
if( MoverParameters->EngineType == DieselEngine ) {
|
||
|
||
rsSilnik.AM /= ( MoverParameters->Power + MoverParameters->nmax * 60 );
|
||
}
|
||
else if( MoverParameters->EngineType == DieselElectric ) {
|
||
|
||
rsSilnik.AM /= ( MoverParameters->Power * 3 );
|
||
}
|
||
else {
|
||
|
||
rsSilnik.AM /= ( MoverParameters->Power + MoverParameters->nmax * 60 + MoverParameters->Power + MoverParameters->Power );
|
||
}
|
||
parser.getTokens( 3, false );
|
||
parser
|
||
>> rsSilnik.AA
|
||
>> rsSilnik.FM // MoverParameters->nmax;
|
||
>> rsSilnik.FA;
|
||
}
|
||
|
||
else if( ( token == "ventilator:" )
|
||
&& ( ( MoverParameters->EngineType == ElectricSeriesMotor )
|
||
|| ( MoverParameters->EngineType == ElectricInductionMotor ) ) ) {
|
||
// plik z dzwiekiem wentylatora, mnozniki i ofsety amp. i czest.
|
||
double attenuation;
|
||
parser.getTokens( 2, false );
|
||
parser
|
||
>> token
|
||
>> attenuation;
|
||
rsWentylator.Init(
|
||
token, attenuation,
|
||
GetPosition().x, GetPosition().y, GetPosition().z,
|
||
true, true );
|
||
parser.getTokens( 4, false );
|
||
parser
|
||
>> rsWentylator.AM
|
||
>> rsWentylator.AA
|
||
>> rsWentylator.FM
|
||
>> rsWentylator.FA;
|
||
rsWentylator.AM /= MoverParameters->RVentnmax;
|
||
rsWentylator.FM /= MoverParameters->RVentnmax;
|
||
}
|
||
|
||
else if( ( token == "transmission:" )
|
||
&& ( MoverParameters->EngineType == ElectricSeriesMotor ) ) {
|
||
// plik z dzwiekiem, mnozniki i ofsety amp. i czest.
|
||
double attenuation;
|
||
parser.getTokens( 2, false );
|
||
parser
|
||
>> token
|
||
>> attenuation;
|
||
rsPrzekladnia.Init(
|
||
token, attenuation,
|
||
GetPosition().x, GetPosition().y, GetPosition().z,
|
||
true );
|
||
rsPrzekladnia.AM = 0.029;
|
||
rsPrzekladnia.AA = 0.1;
|
||
rsPrzekladnia.FM = 0.005;
|
||
rsPrzekladnia.FA = 1.0;
|
||
}
|
||
|
||
else if( token == "brake:" ){
|
||
// plik z piskiem hamulca, mnozniki i ofsety amplitudy.
|
||
double attenuation;
|
||
parser.getTokens( 2, false );
|
||
parser
|
||
>> token
|
||
>> attenuation;
|
||
rsPisk.Init(
|
||
token, attenuation,
|
||
GetPosition().x, GetPosition().y, GetPosition().z,
|
||
true );
|
||
rsPisk.AM = parser.getToken<double>();
|
||
rsPisk.AA = parser.getToken<double>() * ( 105 - Random( 10 ) ) / 100;
|
||
rsPisk.FM = 1.0;
|
||
rsPisk.FA = 0.0;
|
||
}
|
||
|
||
else if( token == "brakeacc:" ) {
|
||
// 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 );
|
||
bBrakeAcc = true;
|
||
// sBrakeAcc.AM=1.0;
|
||
// sBrakeAcc.AA=0.0;
|
||
// sBrakeAcc.FM=1.0;
|
||
// sBrakeAcc.FA=0.0;
|
||
}
|
||
|
||
else if( token == "unbrake:" ) {
|
||
// plik z piskiem hamulca, mnozniki i ofsety amplitudy.
|
||
double attenuation;
|
||
parser.getTokens( 2, false );
|
||
parser
|
||
>> token
|
||
>> attenuation;
|
||
rsUnbrake.Init(
|
||
token, attenuation,
|
||
GetPosition().x, GetPosition().y, GetPosition().z,
|
||
true );
|
||
rsUnbrake.AM = 1.0;
|
||
rsUnbrake.AA = 0.0;
|
||
rsUnbrake.FM = 1.0;
|
||
rsUnbrake.FA = 0.0;
|
||
}
|
||
|
||
else if( token == "derail:" ) {
|
||
// dzwiek przy wykolejeniu
|
||
double attenuation;
|
||
parser.getTokens( 2, false );
|
||
parser
|
||
>> token
|
||
>> attenuation;
|
||
rsDerailment.Init(
|
||
token, attenuation,
|
||
GetPosition().x, GetPosition().y, GetPosition().z,
|
||
true );
|
||
rsDerailment.AM = 1.0;
|
||
rsDerailment.AA = 0.0;
|
||
rsDerailment.FM = 1.0;
|
||
rsDerailment.FA = 0.0;
|
||
}
|
||
|
||
else if( token == "dieselinc:" ) {
|
||
// dzwiek przy wlazeniu na obroty woodwarda
|
||
double attenuation;
|
||
parser.getTokens( 2, false );
|
||
parser
|
||
>> token
|
||
>> attenuation;
|
||
rsDiesielInc.Init(
|
||
token, attenuation,
|
||
GetPosition().x, GetPosition().y, GetPosition().z,
|
||
true );
|
||
rsDiesielInc.AM = 1.0;
|
||
rsDiesielInc.AA = 0.0;
|
||
rsDiesielInc.FM = 1.0;
|
||
rsDiesielInc.FA = 0.0;
|
||
}
|
||
|
||
else if( token == "curve:" ) {
|
||
|
||
double attenuation;
|
||
parser.getTokens( 2, false );
|
||
parser
|
||
>> token
|
||
>> attenuation;
|
||
rscurve.Init(
|
||
token, attenuation,
|
||
GetPosition().x, GetPosition().y, GetPosition().z,
|
||
true );
|
||
rscurve.AM = 1.0;
|
||
rscurve.AA = 0.0;
|
||
rscurve.FM = 1.0;
|
||
rscurve.FA = 0.0;
|
||
}
|
||
|
||
else if( token == "horn1:" ) {
|
||
// pliki z trabieniem
|
||
sHorn1.Load( parser, GetPosition() );
|
||
}
|
||
|
||
else if( token == "horn2:" ) {
|
||
// pliki z trabieniem wysokoton.
|
||
sHorn2.Load( parser, GetPosition() );
|
||
if( iHornWarning ) {
|
||
iHornWarning = 2; // numer syreny do u<>ycia po otrzymaniu sygna<6E>u do jazdy
|
||
}
|
||
}
|
||
|
||
else if( token == "departuresignal:" ) {
|
||
// pliki z sygnalem odjazdu
|
||
sDepartureSignal.Load( parser, GetPosition() );
|
||
}
|
||
|
||
else if( token == "pantographup:" ) {
|
||
// pliki dzwiekow pantografow
|
||
parser.getTokens( 1, false ); parser >> token;
|
||
sPantUp.Init(
|
||
token, 50,
|
||
GetPosition().x, GetPosition().y, GetPosition().z,
|
||
true );
|
||
sPantUp.AM = 50000;
|
||
sPantUp.AA = -1 * ( 105 - Random( 10 ) ) / 100;
|
||
sPantUp.FM = 1.0;
|
||
sPantUp.FA = 0.0;
|
||
}
|
||
|
||
else if( token == "pantographdown:" ) {
|
||
// pliki dzwiekow pantografow
|
||
parser.getTokens( 1, false ); parser >> token;
|
||
sPantDown.Init(
|
||
token, 50,
|
||
GetPosition().x, GetPosition().y, GetPosition().z,
|
||
true );
|
||
sPantDown.AM = 50000;
|
||
sPantDown.AA = -1 * ( 105 - Random( 10 ) ) / 100;
|
||
sPantDown.FM = 1.0;
|
||
sPantDown.FA = 0.0;
|
||
}
|
||
|
||
else if( token == "compressor:" ) {
|
||
// pliki ze sprezarka
|
||
sCompressor.Load( parser, GetPosition() );
|
||
}
|
||
|
||
else if( token == "converter:" ) {
|
||
// pliki z przetwornica
|
||
// if (MoverParameters->EngineType==DieselElectric) //b<>dzie modulowany?
|
||
sConverter.Load( parser, GetPosition() );
|
||
}
|
||
|
||
else if( token == "turbo:" ) {
|
||
// pliki z turbogeneratorem
|
||
sTurbo.Load( parser, GetPosition() );
|
||
}
|
||
|
||
else if( token == "small-compressor:" ) {
|
||
// pliki z przetwornica
|
||
sSmallCompressor.Load( parser, GetPosition() );
|
||
}
|
||
|
||
else if( token == "dooropen:" ) {
|
||
|
||
parser.getTokens( 1, false ); parser >> token;
|
||
rsDoorOpen.Init(
|
||
token, 50,
|
||
GetPosition().x, GetPosition().y, GetPosition().z,
|
||
true );
|
||
rsDoorOpen.AM = 50000;
|
||
rsDoorOpen.AA = -1 * ( 105 - Random( 10 ) ) / 100;
|
||
rsDoorOpen.FM = 1.0;
|
||
rsDoorOpen.FA = 0.0;
|
||
}
|
||
|
||
else if( token == "doorclose:" ) {
|
||
|
||
parser.getTokens( 1, false ); parser >> token;
|
||
rsDoorClose.Init(
|
||
token, 50,
|
||
GetPosition().x, GetPosition().y, GetPosition().z,
|
||
true );
|
||
rsDoorClose.AM = 50000;
|
||
rsDoorClose.AA = -1 * ( 105 - Random( 10 ) ) / 100;
|
||
rsDoorClose.FM = 1.0;
|
||
rsDoorClose.FA = 0.0;
|
||
}
|
||
|
||
else if( token == "sand:" ) {
|
||
// pliki z piasecznica
|
||
sSand.Load( parser, GetPosition() );
|
||
}
|
||
|
||
else if( token == "releaser:" ) {
|
||
// pliki z odluzniaczem
|
||
sReleaser.Load( parser, GetPosition() );
|
||
}
|
||
|
||
} while( ( token != "" )
|
||
&& ( token != "endsounds" ) );
|
||
|
||
}
|
||
|
||
else if (token == "internaldata:") {
|
||
// dalej nie czytaj
|
||
do {
|
||
// zbieranie informacji o kabinach
|
||
token = "";
|
||
parser.getTokens(); parser >> token;
|
||
if(token == "cab0model:")
|
||
{
|
||
parser.getTokens(); parser >> token;
|
||
if( token != "none" ) { iCabs = 2; }
|
||
}
|
||
else if (token == "cab1model:")
|
||
{
|
||
parser.getTokens(); parser >> token;
|
||
if( token != "none" ) { iCabs = 1; }
|
||
}
|
||
else if (token == "cab2model:")
|
||
{
|
||
parser.getTokens(); parser >> token;
|
||
if( token != "none" ) { iCabs = 4; }
|
||
}
|
||
|
||
} while( token != "" );
|
||
|
||
Stop_InternalData = true;
|
||
}
|
||
|
||
} while( ( token != "" )
|
||
&& ( false == Stop_InternalData ) );
|
||
|
||
if (mdModel)
|
||
mdModel->Init(); // obr<62>cenie modelu oraz optymalizacja, r<>wnie<69> zapisanie
|
||
// binarnego
|
||
if (mdLoad)
|
||
mdLoad->Init();
|
||
if (mdPrzedsionek)
|
||
mdPrzedsionek->Init();
|
||
if (mdLowPolyInt)
|
||
mdLowPolyInt->Init();
|
||
// sHorn2.CopyIfEmpty(sHorn1); //<2F>eby jednak tr<74>bi<62> te<74> drugim
|
||
Global::asCurrentTexturePath = szTexturePath; // kiedy<64> uproszczone wn<77>trze miesza<7A>o tekstury nieba
|
||
}
|
||
|
||
//---------------------------------------------------------------------------
|
||
void TDynamicObject::RadioStop()
|
||
{ // zatrzymanie pojazdu
|
||
if (Mechanik) // o ile kto<74> go prowadzi
|
||
if (MoverParameters->SecuritySystem.RadioStop &&
|
||
MoverParameters->Radio) // je<6A>li pojazd ma RadioStop i jest on aktywny
|
||
Mechanik->PutCommand("Emergency_brake", 1.0, 1.0, &vPosition, stopRadio);
|
||
};
|
||
|
||
//---------------------------------------------------------------------------
|
||
void TDynamicObject::Damage(char flag)
|
||
{
|
||
if (flag & 1) //r<><72>nic<69>wka nie robi nic
|
||
{
|
||
MoverParameters->MainSwitch(false);
|
||
MoverParameters->FuseOff();
|
||
}
|
||
else
|
||
{
|
||
}
|
||
|
||
if (flag & 2) //usterka sterowania
|
||
{
|
||
MoverParameters->StLinFlag = false;
|
||
if (MoverParameters->InitialCtrlDelay<100000000)
|
||
MoverParameters->InitialCtrlDelay += 100000001;
|
||
}
|
||
else
|
||
{
|
||
if (MoverParameters->InitialCtrlDelay>100000000)
|
||
MoverParameters->InitialCtrlDelay -= 100000001;
|
||
}
|
||
|
||
if (flag & 4) //blokada przetwornicy
|
||
{
|
||
MoverParameters->ConvOvldFlag = true;
|
||
}
|
||
else
|
||
{
|
||
}
|
||
|
||
if (flag & 8) //blokada sprezarki
|
||
{
|
||
if (MoverParameters->MinCompressor>0)
|
||
MoverParameters->MinCompressor -= 100000001;
|
||
if (MoverParameters->MaxCompressor>0)
|
||
MoverParameters->MaxCompressor -= 100000001;
|
||
}
|
||
else
|
||
{
|
||
if (MoverParameters->MinCompressor<0)
|
||
MoverParameters->MinCompressor += 100000001;
|
||
if (MoverParameters->MaxCompressor<0)
|
||
MoverParameters->MaxCompressor += 100000001;
|
||
}
|
||
|
||
if (flag & 16) //blokada wa<77>u
|
||
{
|
||
if (MoverParameters->CtrlDelay<100000000)
|
||
MoverParameters->CtrlDelay += 100000001;
|
||
if (MoverParameters->CtrlDownDelay<100000000)
|
||
MoverParameters->CtrlDownDelay += 100000001;
|
||
}
|
||
else
|
||
{
|
||
if (MoverParameters->CtrlDelay>100000000)
|
||
MoverParameters->CtrlDelay -= 100000001;
|
||
if (MoverParameters->CtrlDownDelay>100000000)
|
||
MoverParameters->CtrlDownDelay -= 100000001;
|
||
}
|
||
|
||
if (flag & 32) //hamowanie nag<61>e
|
||
{
|
||
}
|
||
else
|
||
{
|
||
}
|
||
|
||
MoverParameters->EngDmgFlag = flag;
|
||
};
|
||
|
||
void TDynamicObject::RaLightsSet(int head, int rear)
|
||
{ // zapalenie <20>wiate<74> z przodu i z
|
||
// ty<74>u, zale<6C>ne od kierunku
|
||
// pojazdu
|
||
if (!MoverParameters)
|
||
return; // mo<6D>e tego nie by<62> na pocz<63>tku
|
||
if (rear == 2 + 32 + 64)
|
||
{ // je<6A>li koniec poci<63>gu, to trzeba ustali<6C>, czy
|
||
// jest tam czynna lokomotywa
|
||
// EN57 mo<6D>e nie mie<69> ko<6B>c<EFBFBD>wek od <20>rodka cz<63>onu
|
||
if (MoverParameters->Power > 1.0) // je<6A>li ma moc nap<61>dow<6F>
|
||
if (!MoverParameters->ActiveDir) // je<6A>li nie ma ustawionego kierunku
|
||
{ // je<6A>li ma zar<61>wno <20>wiat<61>a jak i ko<6B>c<EFBFBD>wki, ustali<6C>, czy jest w stanie
|
||
// aktywnym
|
||
// np. lokomotywa na zimno b<>dzie mie<69> ko<6B>c<EFBFBD>wki a nie <20>wiat<61>a
|
||
rear = 64; // tablice blaszane
|
||
// trzeba to uzale<6C>ni<6E> od "za<7A><61>czenia baterii" w poje<6A>dzie
|
||
}
|
||
if (rear == 2 + 32 + 64) // je<6A>li nadal obydwie mo<6D>liwo<77>ci
|
||
if (iInventory &
|
||
(iDirection ? 0x2A : 0x15)) // czy ma jakie<69> <20>wiat<61>a czerowone od danej strony
|
||
rear = 2 + 32; // dwa <20>wiat<61>a czerwone
|
||
else
|
||
rear = 64; // tablice blaszane
|
||
}
|
||
if (iDirection) // w zale<6C>no<6E>ci od kierunku pojazdu w sk<73>adzie
|
||
{ // jesli pojazd stoi sprz<72>giem 0 w stron<6F> czo<7A>a
|
||
if (head >= 0)
|
||
iLights[0] = head;
|
||
if (rear >= 0)
|
||
iLights[1] = rear;
|
||
}
|
||
else
|
||
{ // jak jest odwr<77>cony w sk<73>adzie (-1), to zapalamy odwrotnie
|
||
if (head >= 0)
|
||
iLights[1] = head;
|
||
if (rear >= 0)
|
||
iLights[0] = rear;
|
||
}
|
||
};
|
||
|
||
int TDynamicObject::DirectionSet(int d)
|
||
{ // ustawienie kierunku w sk<73>adzie (wykonuje AI)
|
||
iDirection = d > 0 ? 1 : 0; // d:1=zgodny,-1=przeciwny; iDirection:1=zgodny,0=przeciwny;
|
||
CouplCounter = 20; //<2F>eby normalnie skanowa<77> kolizje, to musi ruszy<7A> z miejsca
|
||
if (MyTrack)
|
||
{ // podczas wczytywania wstawiane jest AI, ale mo<6D>e jeszcze nie
|
||
// by<62> toru
|
||
// AI ustawi kierunek ponownie po uruchomieniu silnika
|
||
if (iDirection) // je<6A>li w kierunku Coupler 0
|
||
{
|
||
if (MoverParameters->Couplers[0].CouplingFlag ==
|
||
ctrain_virtual) // brak pojazdu podpi<70>tego?
|
||
ABuScanObjects(1, 300); // szukanie czego<67> do pod<6F><64>czenia
|
||
}
|
||
else if (MoverParameters->Couplers[1].CouplingFlag ==
|
||
ctrain_virtual) // brak pojazdu podpi<70>tego?
|
||
ABuScanObjects(-1, 300);
|
||
}
|
||
return 1 - (iDirection ? NextConnectedNo : PrevConnectedNo); // informacja o po<70>o<EFBFBD>eniu
|
||
// nast<73>pnego
|
||
};
|
||
|
||
TDynamicObject * TDynamicObject::PrevAny()
|
||
{ // wska<6B>nik na poprzedni,
|
||
// nawet wirtualny
|
||
return iDirection ? PrevConnected : NextConnected;
|
||
};
|
||
TDynamicObject * TDynamicObject::Prev()
|
||
{
|
||
if (MoverParameters->Couplers[iDirection ^ 1].CouplingFlag)
|
||
return iDirection ? PrevConnected : NextConnected;
|
||
return NULL; // gdy sprz<72>g wirtualny, to jakby nic nie by<62>o
|
||
};
|
||
TDynamicObject * TDynamicObject::Next()
|
||
{
|
||
if (MoverParameters->Couplers[iDirection].CouplingFlag)
|
||
return iDirection ? NextConnected : PrevConnected;
|
||
return NULL; // gdy sprz<72>g wirtualny, to jakby nic nie by<62>o
|
||
};
|
||
TDynamicObject * TDynamicObject::PrevC(int C)
|
||
{
|
||
if (MoverParameters->Couplers[iDirection ^ 1].CouplingFlag & C)
|
||
return iDirection ? PrevConnected : NextConnected;
|
||
return NULL; // gdy sprz<72>g wirtualny, to jakby nic nie by<62>o
|
||
};
|
||
TDynamicObject * TDynamicObject::NextC(int C)
|
||
{
|
||
if (MoverParameters->Couplers[iDirection].CouplingFlag & C)
|
||
return iDirection ? NextConnected : PrevConnected;
|
||
return NULL; // gdy sprz<72>g inny, to jakby nic nie by<62>o
|
||
};
|
||
double TDynamicObject::NextDistance(double d)
|
||
{ // ustalenie odleg<65>o<EFBFBD>ci do
|
||
// nast<73>pnego pojazdu, potrzebne
|
||
// do wstecznego skanowania
|
||
if (!MoverParameters->Couplers[iDirection].Connected)
|
||
return d; // je<6A>li nic nie ma, zwr<77>cenie domy<6D>lnej warto<74>ci
|
||
if ((d <= 0.0) || (MoverParameters->Couplers[iDirection].CoupleDist < d))
|
||
return MoverParameters->Couplers[iDirection].Dist;
|
||
else
|
||
return d;
|
||
};
|
||
|
||
TDynamicObject * TDynamicObject::Neightbour(int &dir)
|
||
{ // ustalenie nast<73>pnego (1) albo poprzedniego (0) w sk<73>adzie bez
|
||
// wzgl<67>du na prawid<69>owo<77><6F>
|
||
// iDirection
|
||
int d = dir; // zapami<6D>tanie kierunku
|
||
dir = 1 - (dir ? NextConnectedNo : PrevConnectedNo); // nowa warto<74><6F>
|
||
return (d ? (MoverParameters->Couplers[1].CouplingFlag ? NextConnected : NULL) :
|
||
(MoverParameters->Couplers[0].CouplingFlag ? PrevConnected : NULL));
|
||
};
|
||
|
||
void TDynamicObject::CoupleDist()
|
||
{ // obliczenie odleg<65>o<EFBFBD>ci sprz<72>g<EFBFBD>w
|
||
if (MyTrack ? (MyTrack->iCategoryFlag & 1) :
|
||
true) // je<6A>li nie ma przypisanego toru, to liczy<7A> jak dla kolei
|
||
{ // je<6A>li jedzie po szynach (r<>wnie<69> unimog), liczenie kul wystarczy
|
||
MoverParameters->SetCoupleDist();
|
||
}
|
||
else
|
||
{ // na drodze trzeba uwzgl<67>dni<6E> wektory ruchu
|
||
double d0 = MoverParameters->Couplers[0].CoupleDist;
|
||
// double d1=MoverParameters->Couplers[1].CoupleDist; //sprz<72>g z ty<74>u
|
||
// samochodu mo<6D>na ola<6C>,
|
||
// dop<6F>ki nie je<6A>dzi na wstecznym
|
||
vector3 p1, p2;
|
||
double d, w; // dopuszczalny dystans w poprzek
|
||
MoverParameters->SetCoupleDist(); // liczenie standardowe
|
||
if (MoverParameters->Couplers[0].Connected) // je<6A>li cokolwiek pod<6F><64>czone
|
||
if (MoverParameters->Couplers[0].CouplingFlag == 0) // je<6A>li wirtualny
|
||
if (MoverParameters->Couplers[0].CoupleDist < 300.0) // i mniej ni<6E> 300m
|
||
{ // przez MoverParameters->Couplers[0].Connected nie da si<73> dosta<74> do
|
||
// DynObj, st<73>d
|
||
// prowizorka
|
||
// WriteLog("Collision of
|
||
// "+AnsiString(MoverParameters->Couplers[0].CoupleDist)+"m detected
|
||
// by
|
||
// "+asName+":0.");
|
||
w = 0.5 * (MoverParameters->Couplers[0].Connected->Dim.W +
|
||
MoverParameters->Dim.W); // minimalna odleg<65>o<EFBFBD><6F> mini<6E>cia
|
||
d = -DotProduct(vLeft, vCoulpler[0]); // odleg<65>o<EFBFBD><6F> prostej ruchu od pocz<63>tku
|
||
// uk<75>adu wsp<73><70>rz<72>dnych
|
||
d = fabs(
|
||
DotProduct(vLeft,
|
||
((TMoverParameters *)(MoverParameters->Couplers[0].Connected))
|
||
->vCoulpler[MoverParameters->Couplers[0].ConnectedNr]) +
|
||
d);
|
||
// WriteLog("Distance "+AnsiString(d)+"m from "+asName+":0.");
|
||
if (d > w)
|
||
MoverParameters->Couplers[0].CoupleDist =
|
||
(d0 < 10 ? 50 : d0); // przywr<77>cenie poprzedniej
|
||
}
|
||
if (MoverParameters->Couplers[1].Connected) // je<6A>li cokolwiek pod<6F><64>czone
|
||
if (MoverParameters->Couplers[1].CouplingFlag == 0) // je<6A>li wirtualny
|
||
if (MoverParameters->Couplers[1].CoupleDist < 300.0) // i mniej ni<6E> 300m
|
||
{
|
||
// WriteLog("Collision of
|
||
// "+AnsiString(MoverParameters->Couplers[1].CoupleDist)+"m detected
|
||
// by
|
||
// "+asName+":1.");
|
||
w = 0.5 * (MoverParameters->Couplers[1].Connected->Dim.W +
|
||
MoverParameters->Dim.W); // minimalna odleg<65>o<EFBFBD><6F> mini<6E>cia
|
||
d = -DotProduct(vLeft, vCoulpler[1]); // odleg<65>o<EFBFBD><6F> prostej ruchu od pocz<63>tku
|
||
// uk<75>adu wsp<73><70>rz<72>dnych
|
||
d = fabs(
|
||
DotProduct(vLeft,
|
||
((TMoverParameters *)(MoverParameters->Couplers[1].Connected))
|
||
->vCoulpler[MoverParameters->Couplers[1].ConnectedNr]) +
|
||
d);
|
||
// WriteLog("Distance "+AnsiString(d)+"m from "+asName+":1.");
|
||
if (d > w)
|
||
MoverParameters->Couplers[0].CoupleDist =
|
||
(d0 < 10 ? 50 : d0); // przywr<77>cenie poprzedniej
|
||
}
|
||
}
|
||
};
|
||
|
||
TDynamicObject * TDynamicObject::ControlledFind()
|
||
{ // taka proteza:
|
||
// chc<68> pod<6F><64>czy<7A>
|
||
// kabin<69> EN57
|
||
// bezpo<70>rednio z
|
||
// silnikowym, aby
|
||
// nie robi<62> tego
|
||
// przez
|
||
// ukrotnienie
|
||
// drugi silnikowy i tak musi by<62> ukrotniony, podobnie jak kolejna jednostka
|
||
// lepiej by by<62>o przesy<73>a<EFBFBD> komendy sterowania, co jednak wymaga przebudowy
|
||
// transmisji komend
|
||
// (LD)
|
||
// problem si<73> robi ze <20>wiat<61>ami, kt<6B>re b<>d<EFBFBD> zapalane w silnikowym, ale musz<73>
|
||
// <20>wieci<63> si<73> w
|
||
// rozrz<72>dczych
|
||
// dla EZT <20>wiat<61><74> czo<7A>owe b<>d<EFBFBD> "zapalane w silnikowym", ale widziane z
|
||
// rozrz<72>dczych
|
||
// r<>wnie<69> wczytywanie MMD powinno dotyczy<7A> aktualnego cz<63>onu
|
||
// problematyczna mo<6D>e by<62> kwestia wybranej kabiny (w silnikowym...)
|
||
// je<6A>li silnikowy b<>dzie zapi<70>ty odwrotnie (tzn. -1), to i tak powinno
|
||
// je<6A>dzi<7A> dobrze
|
||
// r<>wnie<69> hamowanie wykonuje si<73> zaworem w cz<63>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<63>on od sprz<72>gu 1, a sprz<72>g <20><>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<77> tym z moc<6F>
|
||
}
|
||
else if (d->PrevConnected ? d->MoverParameters->Couplers[0].AllowedFlag & ctrain_depot :
|
||
false)
|
||
{ // gdy jest cz<63>on od sprz<72>gu 0, a sprz<72>g <20><>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<77> tym z moc<6F>
|
||
}
|
||
return d;
|
||
};
|
||
//---------------------------------------------------------------------------
|
||
|
||
void TDynamicObject::ParamSet(int what, int into)
|
||
{ // ustawienie lokalnego parametru (what) na stan (into)
|
||
switch (what & 0xFF00)
|
||
{
|
||
case 0x0100: // to np. s<> drzwi, bity 0..7 okre<72>laj<61> numer 1..254 albo mask<73>
|
||
// dla 8 r<><72>nych
|
||
if (what & 1) // na razie mamy lewe oraz prawe, czyli u<>ywamy mask<73> 1=lewe,
|
||
// 2=prawe, 3=wszystkie
|
||
if (MoverParameters->DoorLeftOpened)
|
||
{ // s<> otwarte
|
||
if (!into) // je<6A>li zamykanie
|
||
{
|
||
// d<>wi<77>k zamykania
|
||
}
|
||
}
|
||
else
|
||
{ // s<> zamkni<6E>te
|
||
if (into) // je<6A>li otwieranie
|
||
{
|
||
// d<>wi<77>k otwierania
|
||
}
|
||
}
|
||
if (what & 2) // prawe dzia<69>aj<61> niezale<6C>nie od lewych
|
||
if (MoverParameters->DoorRightOpened)
|
||
{ // s<> otwarte
|
||
if (!into) // je<6A>li zamykanie
|
||
{
|
||
// d<>wi<77>k zamykania
|
||
}
|
||
}
|
||
else
|
||
{ // s<> zamkni<6E>te
|
||
if (into) // je<6A>li otwieranie
|
||
{
|
||
// d<>wi<77>k otwierania
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
};
|
||
|
||
int TDynamicObject::RouteWish(TTrack *tr)
|
||
{ // zapytanie do AI, po kt<6B>rym
|
||
// segmencie (-6..6) jecha<68> na
|
||
// skrzy<7A>owaniu (tr)
|
||
return Mechanik ? Mechanik->CrossRoute(tr) : 0; // wg AI albo prosto
|
||
};
|
||
|
||
std::string TDynamicObject::TextureTest(std::string const &name)
|
||
{ // Ra 2015-01: sprawdzenie dost<73>pno<6E>ci tekstury o podanej nazwie
|
||
std::string x = name + ".dds"; // na razie prymitywnie
|
||
if (FileExists(x.c_str()))
|
||
return x;
|
||
else
|
||
{
|
||
x = name + ".tga"; // w zasadzie to nale<6C>a<EFBFBD>oby uwzgl<67>dni<6E> deklarowan<61> kolejno<6E><6F>
|
||
if (FileExists(x.c_str()))
|
||
return x;
|
||
else
|
||
{
|
||
x = name + ".bmp";
|
||
if (FileExists(x.c_str()))
|
||
return x;
|
||
}
|
||
}
|
||
return ""; // nie znaleziona
|
||
};
|
||
|
||
void TDynamicObject::DestinationSet(std::string to, std::string numer)
|
||
{ // ustawienie stacji
|
||
// docelowej oraz wymiennej
|
||
// tekstury 4, je<6A>li
|
||
// istnieje plik
|
||
// w zasadzie, to ka<6B>dy wagon m<>g<EFBFBD>by mie<69> inn<6E> stacj<63> docelow<6F>
|
||
// zw<7A>aszcza w towarowych, pod k<>tem zautomatyzowania maewr<77>w albo pracy g<>rki
|
||
// ale to jeszcze potrwa, zanim b<>dzie mo<6D>liwe, na razie mo<6D>na wpisa<73> stacj<63> z
|
||
// rozk<7A>adu
|
||
if (abs(iMultiTex) >= 4)
|
||
return; // jak s<> 4 tekstury wymienne, to nie zmienia<69> rozk<7A>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] = TTexturesManager::GetTextureID( NULL, NULL, x, 9); // rozmywania 0,1,4,5 nie nadaj<61> si<73>
|
||
return;
|
||
}
|
||
x = TextureTest(asBaseDir + numer );
|
||
if (!x.empty())
|
||
{
|
||
ReplacableSkinID[4] = TTexturesManager::GetTextureID( NULL, NULL, x, 9); // rozmywania 0,1,4,5 nie nadaj<61> si<73>
|
||
return;
|
||
}
|
||
if (to.empty())
|
||
to = "nowhere";
|
||
x = TextureTest(asBaseDir + to + "@" + MoverParameters->TypeName); // w pierwszej kolejno<6E>ci z nazw<7A> FIZ/MMD
|
||
if (!x.empty())
|
||
{
|
||
ReplacableSkinID[4] = TTexturesManager::GetTextureID( NULL, NULL, x, 9); // rozmywania 0,1,4,5 nie nadaj<61> si<73>
|
||
return;
|
||
}
|
||
x = TextureTest(asBaseDir + to); // na razie prymitywnie
|
||
if (!x.empty())
|
||
ReplacableSkinID[4] = TTexturesManager::GetTextureID( NULL, NULL, x, 9); // rozmywania 0,1,4,5 nie nadaj<61> si<73>
|
||
else
|
||
{
|
||
x = TextureTest(asBaseDir + "nowhere"); // jak nie znalaz<61> dedykowanej, to niech daje nowhere
|
||
if (!x.empty())
|
||
ReplacableSkinID[4] = TTexturesManager::GetTextureID(NULL, NULL, x, 9);
|
||
}
|
||
// Ra 2015-01: <20>eby zalogowa<77> b<><62>d, trzeba by mie<69> pewno<6E><6F>, <20>e model u<>ywa
|
||
// tekstury nr 4
|
||
};
|
||
|
||
void TDynamicObject::OverheadTrack(float o)
|
||
{ // ewentualne wymuszanie jazdy
|
||
// bezpr<70>dowej z powodu informacji
|
||
// w torze
|
||
if (ctOwner) // je<6A>li ma obiekt nadzoruj<75>cy
|
||
{ // trzeba zaktualizowa<77> map<61> flag bitowych jazdy bezpr<70>dowej
|
||
if (o < 0.0)
|
||
{ // normalna jazda po tym torze
|
||
ctOwner->iOverheadZero &= ~iOverheadMask; // zerowanie bitu - mo<6D>e pobiera<72> pr<70>d
|
||
ctOwner->iOverheadDown &= ~iOverheadMask; // zerowanie bitu - mo<6D>e podnie<69><65> pantograf
|
||
}
|
||
else if (o > 0.0)
|
||
{ // opuszczenie pantograf<61>w
|
||
ctOwner->iOverheadZero |=
|
||
iOverheadMask; // ustawienie bitu - ma jecha<68> bez pobierania pr<70>du
|
||
ctOwner->iOverheadDown |= iOverheadMask; // ustawienie bitu - ma opu<70>ci<63> pantograf
|
||
}
|
||
else
|
||
{ // jazda bezpr<70>dowa z podniesionym pantografem
|
||
ctOwner->iOverheadZero |=
|
||
iOverheadMask; // ustawienie bitu - ma jecha<68> bez pobierania pr<70>du
|
||
ctOwner->iOverheadDown &= ~iOverheadMask; // zerowanie bitu - mo<6D>e podnie<69><65> pantograf
|
||
}
|
||
}
|
||
};
|