mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-21 14:49:19 +02:00
conversion of legacy model-based terrain to camera-centric render system
This commit is contained in:
@@ -472,8 +472,10 @@ bool TAnimModel::Load(cParser *parser, bool ter)
|
|||||||
if( name.substr( name.rfind( '.' ) ) == ".t3d" ) {
|
if( name.substr( name.rfind( '.' ) ) == ".t3d" ) {
|
||||||
name[ name.length() - 3 ] = 'e';
|
name[ name.length() - 3 ] = 'e';
|
||||||
}
|
}
|
||||||
|
#ifdef EU07_USE_OLD_TERRAINCODE
|
||||||
Global::asTerrainModel = name;
|
Global::asTerrainModel = name;
|
||||||
WriteLog("Terrain model \"" + name + "\" will be created.");
|
WriteLog("Terrain model \"" + name + "\" will be created.");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ErrorLog("Missed file: " + name);
|
ErrorLog("Missed file: " + name);
|
||||||
@@ -632,13 +634,7 @@ TSubModel * TAnimModel::TerrainSquare(int n)
|
|||||||
{ // pobieranie wskaźników do pierwszego submodelu
|
{ // pobieranie wskaźników do pierwszego submodelu
|
||||||
return pModel ? pModel->TerrainSquare(n) : 0;
|
return pModel ? pModel->TerrainSquare(n) : 0;
|
||||||
};
|
};
|
||||||
#ifdef EU07_USE_OLD_RENDERCODE
|
|
||||||
void TAnimModel::TerrainRenderVBO(int n)
|
|
||||||
{ // renderowanie terenu z VBO
|
|
||||||
if (pModel)
|
|
||||||
pModel->TerrainRenderVBO(n);
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void TAnimModel::Advanced()
|
void TAnimModel::Advanced()
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ class TAnimModel {
|
|||||||
material_data m_materialdata;
|
material_data m_materialdata;
|
||||||
|
|
||||||
std::string asText; // tekst dla wyświetlacza znakowego
|
std::string asText; // tekst dla wyświetlacza znakowego
|
||||||
TAnimAdvanced *pAdvanced;
|
TAnimAdvanced *pAdvanced { nullptr };
|
||||||
void Advanced();
|
void Advanced();
|
||||||
TLightState lsLights[iMaxNumLights];
|
TLightState lsLights[iMaxNumLights];
|
||||||
float fDark; // poziom zapalanie światła (powinno być chyba powiązane z danym światłem?)
|
float fDark; // poziom zapalanie światła (powinno być chyba powiązane z danym światłem?)
|
||||||
|
|||||||
245
Ground.cpp
245
Ground.cpp
@@ -153,73 +153,30 @@ TGroundNode::TGroundNode( TGroundNodeType t ) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TGroundNode::InitNormals()
|
// obliczenie wektorów normalnych
|
||||||
{ // obliczenie wektorów normalnych
|
void TGroundNode::InitNormals() {
|
||||||
glm::dvec3 v1, v2, v3, v4, v5;
|
|
||||||
glm::vec3 n1, n2, n3, n4;
|
glm::dvec3 v1, v2;
|
||||||
|
glm::vec3 n1;
|
||||||
glm::vec2 t1;
|
glm::vec2 t1;
|
||||||
int i;
|
|
||||||
switch (iType)
|
|
||||||
{
|
|
||||||
case GL_TRIANGLE_STRIP:
|
|
||||||
v1 = Piece->vertices[0].position - Piece->vertices[1].position;
|
|
||||||
v2 = Piece->vertices[1].position - Piece->vertices[2].position;
|
|
||||||
n1 = glm::normalize(glm::cross(v1, v2));
|
|
||||||
if (Piece->vertices[0].normal == glm::vec3())
|
|
||||||
Piece->vertices[0].normal = n1;
|
|
||||||
v3 = Piece->vertices[2].position - Piece->vertices[3].position;
|
|
||||||
n2 = glm::normalize(glm::cross(v3, v2));
|
|
||||||
if (Piece->vertices[1].normal == glm::vec3())
|
|
||||||
Piece->vertices[1].normal = (n1 + n2) * 0.5f;
|
|
||||||
|
|
||||||
for ( i = 2; i < iNumVerts - 2; i += 2)
|
for( auto i = 0; i < iNumVerts; i += 3 ) {
|
||||||
{
|
|
||||||
v4 = Piece->vertices[i - 1].position - Piece->vertices[i].position;
|
|
||||||
v5 = Piece->vertices[i].position - Piece->vertices[i + 1].position;
|
|
||||||
n3 = glm::normalize(glm::cross(v3, v4));
|
|
||||||
n4 = glm::normalize(glm::cross(v5, v4));
|
|
||||||
if (Piece->vertices[i].normal == glm::vec3())
|
|
||||||
Piece->vertices[i].normal = (n1 + n2 + n3) / 3.0f;
|
|
||||||
if (Piece->vertices[i + 1].normal == glm::vec3())
|
|
||||||
Piece->vertices[i + 1].normal = (n2 + n3 + n4) / 3.0f;
|
|
||||||
n1 = n3;
|
|
||||||
n2 = n4;
|
|
||||||
v3 = v5;
|
|
||||||
}
|
|
||||||
if (Piece->vertices[i].normal == glm::vec3())
|
|
||||||
Piece->vertices[i].normal = (n1 + n2) / 2.0f;
|
|
||||||
if (i + 1 < iNumVerts)
|
|
||||||
{
|
|
||||||
if (Piece->vertices[i + 1].normal == glm::vec3())
|
|
||||||
Piece->vertices[i + 1].normal = n2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
WriteLog("odd number of vertices, normals may be wrong!");
|
|
||||||
|
|
||||||
break;
|
v1 = Piece->vertices[ i + 0 ].position - Piece->vertices[ i + 1 ].position;
|
||||||
case GL_TRIANGLE_FAN:
|
v2 = Piece->vertices[ i + 1 ].position - Piece->vertices[ i + 2 ].position;
|
||||||
|
n1 = glm::normalize( glm::cross( v1, v2 ) );
|
||||||
break;
|
if( Piece->vertices[ i + 0 ].normal == glm::vec3() )
|
||||||
case GL_TRIANGLES:
|
Piece->vertices[ i + 0 ].normal = ( n1 );
|
||||||
for (i = 0; i < iNumVerts; i += 3)
|
if( Piece->vertices[ i + 1 ].normal == glm::vec3() )
|
||||||
{
|
Piece->vertices[ i + 1 ].normal = ( n1 );
|
||||||
v1 = Piece->vertices[i + 0].position - Piece->vertices[i + 1].position;
|
if( Piece->vertices[ i + 2 ].normal == glm::vec3() )
|
||||||
v2 = Piece->vertices[i + 1].position - Piece->vertices[i + 2].position;
|
Piece->vertices[ i + 2 ].normal = ( n1 );
|
||||||
n1 = glm::normalize(glm::cross(v1, v2));
|
t1 = glm::vec2(
|
||||||
if( Piece->vertices[i + 0].normal == glm::vec3() )
|
std::floor( Piece->vertices[ i + 0 ].texture.s ),
|
||||||
Piece->vertices[i + 0].normal = (n1);
|
std::floor( Piece->vertices[ i + 0 ].texture.t ) );
|
||||||
if( Piece->vertices[i + 1].normal == glm::vec3() )
|
Piece->vertices[ i + 1 ].texture -= t1;
|
||||||
Piece->vertices[i + 1].normal = (n1);
|
Piece->vertices[ i + 2 ].texture -= t1;
|
||||||
if( Piece->vertices[i + 2].normal == glm::vec3() )
|
Piece->vertices[ i + 0 ].texture -= t1;
|
||||||
Piece->vertices[i + 2].normal = (n1);
|
|
||||||
t1 = glm::vec2(
|
|
||||||
std::floor( Piece->vertices[ i + 0 ].texture.s ),
|
|
||||||
std::floor( Piece->vertices[ i + 0 ].texture.t ) );
|
|
||||||
Piece->vertices[ i + 1 ].texture -= t1;
|
|
||||||
Piece->vertices[ i + 2 ].texture -= t1;
|
|
||||||
Piece->vertices[ i + 0 ].texture -= t1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -704,6 +661,42 @@ TGround::GetRect( double x, double z ) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// convert tp_terrain model to a series of triangle nodes
|
||||||
|
void
|
||||||
|
TGround::convert_terrain( TGroundNode const *Terrain ) {
|
||||||
|
|
||||||
|
TSubModel *submodel { nullptr };
|
||||||
|
for( auto cellindex = 1; cellindex < Terrain->iCount; ++cellindex ) {
|
||||||
|
// go through all submodels for individual terrain cells...
|
||||||
|
submodel = Terrain->nNode[ cellindex ].smTerrain;
|
||||||
|
convert_terrain( submodel );
|
||||||
|
// if there's more than one group of triangles in the cell they're held as children of the primary submodel
|
||||||
|
submodel = submodel->ChildGet();
|
||||||
|
while( submodel != nullptr ) {
|
||||||
|
convert_terrain( submodel );
|
||||||
|
submodel = submodel->NextGet();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TGround::convert_terrain( TSubModel const *Submodel ) {
|
||||||
|
|
||||||
|
auto groundnode = new TGroundNode( GL_TRIANGLES );
|
||||||
|
Submodel->convert( *groundnode );
|
||||||
|
|
||||||
|
if( groundnode->iNumVerts > 0 ) {
|
||||||
|
// jeśli nie jest pojazdem ostatni dodany dołączamy na końcu nowego
|
||||||
|
groundnode->nNext = nRootOfType[ groundnode->iType ];
|
||||||
|
// ustawienie nowego na początku listy
|
||||||
|
nRootOfType[ groundnode->iType ] = groundnode;
|
||||||
|
++iNumNodes;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delete groundnode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
double fTrainSetVel = 0;
|
double fTrainSetVel = 0;
|
||||||
double fTrainSetDir = 0;
|
double fTrainSetDir = 0;
|
||||||
double fTrainSetDist = 0; // odległość składu od punktu 1 w stronę punktu 2
|
double fTrainSetDist = 0; // odległość składu od punktu 1 w stronę punktu 2
|
||||||
@@ -1219,61 +1212,123 @@ TGroundNode * TGround::AddGroundNode(cParser *parser)
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case TP_MODEL:
|
case TP_MODEL: {
|
||||||
if (rmin < 0)
|
#ifdef EU07_USE_OLD_TERRAINCODE
|
||||||
{
|
if( rmin < 0 ) {
|
||||||
tmp->iType = TP_TERRAIN;
|
tmp->iType = TP_TERRAIN;
|
||||||
tmp->fSquareMinRadius = 0; // to w ogóle potrzebne?
|
tmp->fSquareMinRadius = 0; // to w ogóle potrzebne?
|
||||||
}
|
}
|
||||||
parser->getTokens(3);
|
parser->getTokens( 3 );
|
||||||
*parser >> tmp->pCenter.x >> tmp->pCenter.y >> tmp->pCenter.z;
|
*parser >> tmp->pCenter.x >> tmp->pCenter.y >> tmp->pCenter.z;
|
||||||
parser->getTokens();
|
parser->getTokens();
|
||||||
*parser >> tf1;
|
*parser >> tf1;
|
||||||
// OlO_EU&KAKISH-030103: obracanie punktow zaczepien w modelu
|
// OlO_EU&KAKISH-030103: obracanie punktow zaczepien w modelu
|
||||||
tmp->pCenter.RotateY(aRotate.y / 180.0 * M_PI);
|
tmp->pCenter.RotateY( aRotate.y / 180.0 * M_PI );
|
||||||
// McZapkie-260402: model tez ma wspolrzedne wzgledne
|
// McZapkie-260402: model tez ma wspolrzedne wzgledne
|
||||||
tmp->pCenter += pOrigin;
|
tmp->pCenter += pOrigin;
|
||||||
|
|
||||||
tmp->Model = new TAnimModel();
|
tmp->Model = new TAnimModel();
|
||||||
tmp->Model->RaAnglesSet(aRotate.x, tf1 + aRotate.y, aRotate.z); // dostosowanie do pochylania linii
|
tmp->Model->RaAnglesSet( aRotate.x, tf1 + aRotate.y, aRotate.z ); // dostosowanie do pochylania linii
|
||||||
if( tmp->Model->Load( parser, tmp->iType == TP_TERRAIN ) ) {
|
if( tmp->Model->Load( parser, tmp->iType == TP_TERRAIN ) ) {
|
||||||
// wczytanie modelu, tekstury i stanu świateł...
|
// wczytanie modelu, tekstury i stanu świateł...
|
||||||
tmp->iFlags = tmp->Model->Flags() | 0x200; // ustalenie, czy przezroczysty; flaga usuwania
|
tmp->iFlags = tmp->Model->Flags() | 0x200; // ustalenie, czy przezroczysty; flaga usuwania
|
||||||
}
|
}
|
||||||
else if (tmp->iType != TP_TERRAIN)
|
else if( tmp->iType != TP_TERRAIN ) { // model nie wczytał się - ignorowanie node
|
||||||
{ // model nie wczytał się - ignorowanie node
|
|
||||||
delete tmp;
|
delete tmp;
|
||||||
tmp = NULL; // nie może być tu return
|
tmp = NULL; // nie może być tu return
|
||||||
break; // nie może być tu return?
|
break; // nie może być tu return?
|
||||||
}
|
}
|
||||||
if (tmp->iType == TP_TERRAIN)
|
if( tmp->iType == TP_TERRAIN ) { // jeśli model jest terenem, trzeba utworzyć dodatkowe obiekty
|
||||||
{ // jeśli model jest terenem, trzeba utworzyć dodatkowe obiekty
|
|
||||||
// po wczytaniu model ma już utworzone DL albo VBO
|
// po wczytaniu model ma już utworzone DL albo VBO
|
||||||
Global::pTerrainCompact = tmp->Model; // istnieje co najmniej jeden obiekt terenu
|
Global::pTerrainCompact = tmp->Model; // istnieje co najmniej jeden obiekt terenu
|
||||||
tmp->pCenter = Math3D::vector3( 0.0, 0.0, 0.0 ); // enforce placement in the world center
|
tmp->pCenter = Math3D::vector3( 0.0, 0.0, 0.0 ); // enforce placement in the world center
|
||||||
tmp->iCount = Global::pTerrainCompact->TerrainCount() + 1; // zliczenie submodeli
|
tmp->iCount = Global::pTerrainCompact->TerrainCount() + 1; // zliczenie submodeli
|
||||||
tmp->nNode = new TGroundNode[tmp->iCount]; // sztuczne node dla kwadratów
|
tmp->nNode = new TGroundNode[ tmp->iCount ]; // sztuczne node dla kwadratów
|
||||||
tmp->nNode[0].iType = TP_MODEL; // pierwszy zawiera model (dla delete)
|
tmp->nNode[ 0 ].iType = TP_MODEL; // pierwszy zawiera model (dla delete)
|
||||||
tmp->nNode[0].Model = Global::pTerrainCompact;
|
tmp->nNode[ 0 ].Model = Global::pTerrainCompact;
|
||||||
tmp->nNode[0].iFlags = 0x200; // nie wyświetlany, ale usuwany
|
tmp->nNode[ 0 ].iFlags = 0x200; // nie wyświetlany, ale usuwany
|
||||||
for (int i = 1; i < tmp->iCount; ++i)
|
for( int i = 1; i < tmp->iCount; ++i ) { // a reszta to submodele
|
||||||
{ // a reszta to submodele
|
tmp->nNode[ i ].iType = TP_SUBMODEL;
|
||||||
tmp->nNode[i].iType = TP_SUBMODEL;
|
tmp->nNode[ i ].smTerrain = Global::pTerrainCompact->TerrainSquare( i - 1 );
|
||||||
tmp->nNode[i].smTerrain = Global::pTerrainCompact->TerrainSquare(i - 1);
|
tmp->nNode[ i ].iFlags = 0x10; // nieprzezroczyste; nie usuwany
|
||||||
tmp->nNode[i].iFlags = 0x10; // nieprzezroczyste; nie usuwany
|
tmp->nNode[ i ].bVisible = true;
|
||||||
tmp->nNode[i].bVisible = true;
|
tmp->nNode[ i ].pCenter = tmp->pCenter; // nie przesuwamy w inne miejsce
|
||||||
tmp->nNode[i].pCenter = tmp->pCenter; // nie przesuwamy w inne miejsce
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!tmp->asName.empty()) // jest pusta gdy "none"
|
else if( !tmp->asName.empty() ) // jest pusta gdy "none"
|
||||||
{ // dodanie do wyszukiwarki
|
{ // dodanie do wyszukiwarki
|
||||||
if( false == m_trackmap.Add( TP_MODEL, tmp->asName, tmp ) ) {
|
if( false == m_trackmap.Add( TP_MODEL, tmp->asName, tmp ) ) {
|
||||||
// przy zdublowaniu wskaźnik zostanie podmieniony w drzewku na późniejszy (zgodność wsteczna)
|
// przy zdublowaniu wskaźnik zostanie podmieniony w drzewku na późniejszy (zgodność wsteczna)
|
||||||
ErrorLog( "Duplicated model: " + tmp->asName ); // to zgłaszać duplikat
|
ErrorLog( "Duplicated model: " + tmp->asName ); // to zgłaszać duplikat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// str=Parser->GetNextSymbol().LowerCase();
|
#else
|
||||||
|
if( rmin < 0 ) {
|
||||||
|
// legacy leftover: special case, terrain provided as 3d model
|
||||||
|
tmp->iType = TP_TERRAIN;
|
||||||
|
tmp->fSquareMinRadius = 0; // to w ogóle potrzebne?
|
||||||
|
// we ignore center and rotation for terrain; they should be set to 0 anyway
|
||||||
|
parser->getTokens( 4 );
|
||||||
|
|
||||||
|
tmp->iFlags = 0x200; // flaga usuwania
|
||||||
|
tmp->Model = new TAnimModel();
|
||||||
|
if( false == tmp->Model->Load( parser, true ) ) {
|
||||||
|
delete tmp;
|
||||||
|
tmp = nullptr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tmp->iFlags |= tmp->Model->Flags(); // ustalenie, czy przezroczysty
|
||||||
|
tmp->pCenter = Math3D::vector3(); // enforce placement in the world center
|
||||||
|
// jeśli model jest terenem, trzeba utworzyć dodatkowe obiekty
|
||||||
|
tmp->iCount = tmp->Model->TerrainCount() + 1; // zliczenie submodeli
|
||||||
|
Global::pTerrainCompact = tmp->Model;
|
||||||
|
tmp->nNode = new TGroundNode[ tmp->iCount ]; // sztuczne node dla kwadratów
|
||||||
|
tmp->nNode[ 0 ].iType = TP_MODEL; // pierwszy zawiera model (dla delete)
|
||||||
|
tmp->nNode[ 0 ].Model = Global::pTerrainCompact;
|
||||||
|
tmp->nNode[ 0 ].iFlags = 0x200; // nie wyświetlany, ale usuwany
|
||||||
|
for( auto i = 1; i < tmp->iCount; ++i ) { // a reszta to submodele
|
||||||
|
tmp->nNode[ i ].iType = TP_SUBMODEL;
|
||||||
|
tmp->nNode[ i ].smTerrain = Global::pTerrainCompact->TerrainSquare( i - 1 );
|
||||||
|
tmp->nNode[ i ].iFlags = 0x10; // nieprzezroczyste; nie usuwany
|
||||||
|
tmp->nNode[ i ].bVisible = true;
|
||||||
|
tmp->nNode[ i ].pCenter = tmp->pCenter; // nie przesuwamy w inne miejsce
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// regular 3d model
|
||||||
|
parser->getTokens( 3 );
|
||||||
|
*parser
|
||||||
|
>> tmp->pCenter.x
|
||||||
|
>> tmp->pCenter.y
|
||||||
|
>> tmp->pCenter.z;
|
||||||
|
parser->getTokens();
|
||||||
|
*parser >> tf1;
|
||||||
|
// OlO_EU&KAKISH-030103: obracanie punktow zaczepien w modelu
|
||||||
|
tmp->pCenter.RotateY( glm::radians( aRotate.y ) );
|
||||||
|
// McZapkie-260402: model tez ma wspolrzedne wzgledne
|
||||||
|
tmp->pCenter += pOrigin;
|
||||||
|
|
||||||
|
tmp->iFlags = 0x200; // flaga usuwania
|
||||||
|
tmp->Model = new TAnimModel();
|
||||||
|
tmp->Model->RaAnglesSet( aRotate.x, tf1 + aRotate.y, aRotate.z ); // dostosowanie do pochylania linii
|
||||||
|
if( false == tmp->Model->Load( parser, false ) ) {
|
||||||
|
// model nie wczytał się - ignorowanie node
|
||||||
|
delete tmp;
|
||||||
|
tmp = nullptr; // nie może być tu return
|
||||||
|
break; // nie może być tu return?
|
||||||
|
}
|
||||||
|
tmp->iFlags |= tmp->Model->Flags(); // ustalenie, czy przezroczysty
|
||||||
|
if( false == tmp->asName.empty() ) { // jest pusta gdy "none"
|
||||||
|
// dodanie do wyszukiwarki
|
||||||
|
if( false == m_trackmap.Add( TP_MODEL, tmp->asName, tmp ) ) {
|
||||||
|
// przy zdublowaniu wskaźnik zostanie podmieniony w drzewku na późniejszy (zgodność wsteczna)
|
||||||
|
ErrorLog( "Duplicated model: " + tmp->asName ); // to zgłaszać duplikat
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
// case TP_GEOMETRY :
|
// case TP_GEOMETRY :
|
||||||
case GL_TRIANGLES:
|
case GL_TRIANGLES:
|
||||||
case GL_TRIANGLE_STRIP:
|
case GL_TRIANGLE_STRIP:
|
||||||
@@ -1620,7 +1675,8 @@ void TGround::FirstInit()
|
|||||||
for (int type = 0; type < TP_LAST; ++type) {
|
for (int type = 0; type < TP_LAST; ++type) {
|
||||||
for (TGroundNode *Current = nRootOfType[type]; Current != nullptr; Current = Current->nNext) {
|
for (TGroundNode *Current = nRootOfType[type]; Current != nullptr; Current = Current->nNext) {
|
||||||
|
|
||||||
Current->InitNormals();
|
if( type == GL_TRIANGLES ) { Current->InitNormals(); }
|
||||||
|
|
||||||
if (Current->iType != TP_DYNAMIC)
|
if (Current->iType != TP_DYNAMIC)
|
||||||
{ // pojazdów w ogóle nie dotyczy dodawanie do mapy
|
{ // pojazdów w ogóle nie dotyczy dodawanie do mapy
|
||||||
if( ( type == TP_EVLAUNCH )
|
if( ( type == TP_EVLAUNCH )
|
||||||
@@ -1628,6 +1684,7 @@ void TGround::FirstInit()
|
|||||||
// dodanie do globalnego obiektu
|
// dodanie do globalnego obiektu
|
||||||
srGlobal.NodeAdd( Current );
|
srGlobal.NodeAdd( Current );
|
||||||
}
|
}
|
||||||
|
#ifdef EU07_USE_OLD_TERRAINCODE
|
||||||
else if (type == TP_TERRAIN) {
|
else if (type == TP_TERRAIN) {
|
||||||
// specjalne przetwarzanie terenu wczytanego z pliku E3D
|
// specjalne przetwarzanie terenu wczytanego z pliku E3D
|
||||||
TGroundRect *gr;
|
TGroundRect *gr;
|
||||||
@@ -1640,6 +1697,7 @@ void TGround::FirstInit()
|
|||||||
gr->nTerrain = Current->nNode + j; // zapamiętanie
|
gr->nTerrain = Current->nNode + j; // zapamiętanie
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
else {
|
else {
|
||||||
TSubRect *targetcell { nullptr };
|
TSubRect *targetcell { nullptr };
|
||||||
// test whether we can add the node to a ground cell, or a subcell
|
// test whether we can add the node to a ground cell, or a subcell
|
||||||
@@ -1743,6 +1801,15 @@ bool TGround::Init(std::string File)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#ifndef EU07_SCENERY_EDITOR
|
||||||
|
case TP_TERRAIN: {
|
||||||
|
// convert legacy terrain model to a series of triangle nodes, to take advantage of camera-centric render and geometry merging
|
||||||
|
// NOTE: this leaves us with a large model we don't use loaded and taking space. it'll sort of solve itself when the binary scenery file is in place
|
||||||
|
convert_terrain( LastNode );
|
||||||
|
SafeDelete( LastNode );
|
||||||
|
Global::pTerrainCompact = nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
default: {
|
default: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2120,8 +2187,10 @@ bool TGround::Init(std::string File)
|
|||||||
|
|
||||||
if (!bInitDone)
|
if (!bInitDone)
|
||||||
FirstInit(); // jeśli nie było w scenerii
|
FirstInit(); // jeśli nie było w scenerii
|
||||||
|
#ifdef EU07_USE_OLD_TERRAINCODE
|
||||||
if (Global::pTerrainCompact)
|
if (Global::pTerrainCompact)
|
||||||
TerrainWrite(); // Ra: teraz można zapisać teren w jednym pliku
|
TerrainWrite(); // Ra: teraz można zapisać teren w jednym pliku
|
||||||
|
#endif
|
||||||
Global::iPause &= ~0x10; // koniec pauzy wczytywania
|
Global::iPause &= ~0x10; // koniec pauzy wczytywania
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
7
Ground.h
7
Ground.h
@@ -175,10 +175,6 @@ class TSubRect : /*public Resource,*/ public CMesh
|
|||||||
TTrack **tTracks = nullptr; // tory do renderowania pojazdów
|
TTrack **tTracks = nullptr; // tory do renderowania pojazdów
|
||||||
protected:
|
protected:
|
||||||
TTrack *tTrackAnim = nullptr; // obiekty do przeliczenia animacji
|
TTrack *tTrackAnim = nullptr; // obiekty do przeliczenia animacji
|
||||||
#ifdef EU07_USE_OLD_RENDERCODE
|
|
||||||
TGroundNode *nRootMesh = nullptr; // obiekty renderujące wg tekstury (wtórne, lista po nNext2)
|
|
||||||
TGroundNode *nMeshed = nullptr; // lista obiektów dla których istnieją obiekty renderujące grupowo
|
|
||||||
#endif
|
|
||||||
public:
|
public:
|
||||||
TGroundNode *nRootNode = nullptr; // wszystkie obiekty w sektorze, z wyjątkiem renderujących i pojazdów (nNext2)
|
TGroundNode *nRootNode = nullptr; // wszystkie obiekty w sektorze, z wyjątkiem renderujących i pojazdów (nNext2)
|
||||||
TGroundNode *nRenderHidden = nullptr; // lista obiektów niewidocznych, "renderowanych" również z tyłu (nNext3)
|
TGroundNode *nRenderHidden = nullptr; // lista obiektów niewidocznych, "renderowanych" również z tyłu (nNext3)
|
||||||
@@ -333,6 +329,9 @@ class TGround
|
|||||||
void TrackJoin(TGroundNode *Current);
|
void TrackJoin(TGroundNode *Current);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// convert tp_terrain model to a series of triangle nodes
|
||||||
|
void convert_terrain( TGroundNode const *Terrain );
|
||||||
|
void convert_terrain( TSubModel const *Submodel );
|
||||||
void RaTriangleDivider(TGroundNode *node);
|
void RaTriangleDivider(TGroundNode *node);
|
||||||
void Navigate(std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam);
|
void Navigate(std::string const &ClassName, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||||
|
|
||||||
|
|||||||
76
Model3d.cpp
76
Model3d.cpp
@@ -19,6 +19,7 @@ Copyright (C) 2001-2004 Marcin Wozniak, Maciej Czapkiewicz and others
|
|||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
#include "mczapkie/mctools.h"
|
#include "mczapkie/mctools.h"
|
||||||
#include "Usefull.h"
|
#include "Usefull.h"
|
||||||
|
#include "ground.h"
|
||||||
#include "renderer.h"
|
#include "renderer.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "mtable.h"
|
#include "mtable.h"
|
||||||
@@ -1037,7 +1038,7 @@ void TSubModel::RaAnimation(TAnimType a)
|
|||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
|
|
||||||
void TSubModel::serialize_geometry( std::ostream &Output ) {
|
void TSubModel::serialize_geometry( std::ostream &Output ) const {
|
||||||
|
|
||||||
if( Child ) {
|
if( Child ) {
|
||||||
Child->serialize_geometry( Output );
|
Child->serialize_geometry( Output );
|
||||||
@@ -1076,6 +1077,65 @@ TSubModel::create_geometry( std::size_t &Dataoffset, geometrybank_handle const &
|
|||||||
Next->create_geometry( Dataoffset, Bank );
|
Next->create_geometry( Dataoffset, Bank );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// places contained geometry in provided ground node
|
||||||
|
void
|
||||||
|
TSubModel::convert( TGroundNode &Groundnode ) const {
|
||||||
|
|
||||||
|
Groundnode.asName = pName;
|
||||||
|
Groundnode.Ambient = f4Ambient;
|
||||||
|
Groundnode.Diffuse = f4Diffuse;
|
||||||
|
Groundnode.Specular = f4Specular;
|
||||||
|
Groundnode.TextureID = TextureID;
|
||||||
|
Groundnode.iFlags = (
|
||||||
|
( true == GfxRenderer.Texture( TextureID ).has_alpha ) ?
|
||||||
|
0x20 :
|
||||||
|
0x10 );
|
||||||
|
|
||||||
|
if( m_geometry == NULL ) { return; }
|
||||||
|
|
||||||
|
std::size_t vertexcount { 0 };
|
||||||
|
std::vector<TGroundVertex> importedvertices;
|
||||||
|
TGroundVertex vertex, vertex1, vertex2;
|
||||||
|
for( auto const &sourcevertex : GfxRenderer.Vertices( m_geometry ) ) {
|
||||||
|
vertex.position = sourcevertex.position;
|
||||||
|
vertex.normal = sourcevertex.normal;
|
||||||
|
vertex.texture = sourcevertex.texture;
|
||||||
|
if( vertexcount == 0 ) { vertex1 = vertex; }
|
||||||
|
else if( vertexcount == 1 ) { vertex2 = vertex; }
|
||||||
|
else if( vertexcount >= 2 ) {
|
||||||
|
if( false == degenerate( vertex1.position, vertex2.position, vertex.position ) ) {
|
||||||
|
importedvertices.emplace_back( vertex1 );
|
||||||
|
importedvertices.emplace_back( vertex2 );
|
||||||
|
importedvertices.emplace_back( vertex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++vertexcount;
|
||||||
|
if( vertexcount > 2 ) { vertexcount = 0; } // start new triangle if needed
|
||||||
|
}
|
||||||
|
if( Groundnode.Piece == nullptr ) {
|
||||||
|
Groundnode.Piece = new piece_node();
|
||||||
|
}
|
||||||
|
Groundnode.iNumVerts = importedvertices.size();
|
||||||
|
if( Groundnode.iNumVerts > 0 ) {
|
||||||
|
|
||||||
|
Groundnode.Piece->vertices.swap( importedvertices );
|
||||||
|
|
||||||
|
for( auto const &vertex : Groundnode.Piece->vertices ) {
|
||||||
|
Groundnode.pCenter += vertex.position;
|
||||||
|
}
|
||||||
|
Groundnode.pCenter /= Groundnode.iNumVerts;
|
||||||
|
|
||||||
|
double r { 0.0 };
|
||||||
|
double tf;
|
||||||
|
for( auto const &vertex : Groundnode.Piece->vertices ) {
|
||||||
|
tf = glm::length2( vertex.position - glm::dvec3{ Groundnode.pCenter } );
|
||||||
|
if( tf > r )
|
||||||
|
r = tf;
|
||||||
|
}
|
||||||
|
Groundnode.fSquareRadius += r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: leftover from static distance factor adjustment.
|
// NOTE: leftover from static distance factor adjustment.
|
||||||
// TODO: get rid of it, once we have the dynamic adjustment code in place
|
// TODO: get rid of it, once we have the dynamic adjustment code in place
|
||||||
void TSubModel::AdjustDist()
|
void TSubModel::AdjustDist()
|
||||||
@@ -1861,17 +1921,3 @@ TSubModel *TModel3d::TerrainSquare(int n)
|
|||||||
r->UnFlagNext(); // blokowanie wyświetlania po Next głównej listy
|
r->UnFlagNext(); // blokowanie wyświetlania po Next głównej listy
|
||||||
return r;
|
return r;
|
||||||
};
|
};
|
||||||
#ifdef EU07_USE_OLD_RENDERCODE
|
|
||||||
void TModel3d::TerrainRenderVBO(int n)
|
|
||||||
{ // renderowanie terenu z VBO
|
|
||||||
::glPushMatrix();
|
|
||||||
::glTranslated( -Global::pCameraPosition.x, -Global::pCameraPosition.y, -Global::pCameraPosition.z );
|
|
||||||
TSubModel *r = Root;
|
|
||||||
while( r ) {
|
|
||||||
if( r->iVisible == n ) // tylko jeśli ma być widoczny w danej ramce (problem dla 0==false)
|
|
||||||
GfxRenderer.Render( r ); // sub kolejne (Next) się nie wyrenderują
|
|
||||||
r = r->NextGet();
|
|
||||||
}
|
|
||||||
::glPopMatrix();
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
@@ -50,6 +50,8 @@ enum TAnimType // rodzaj animacji
|
|||||||
at_Undefined = 0x800000FF // animacja chwilowo nieokreślona
|
at_Undefined = 0x800000FF // animacja chwilowo nieokreślona
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TGroundNode;
|
||||||
|
|
||||||
class TSubModel
|
class TSubModel
|
||||||
{ // klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów
|
{ // klasa submodelu - pojedyncza siatka, punkt świetlny albo grupa punktów
|
||||||
//m7todo: zrobić normalną serializację
|
//m7todo: zrobić normalną serializację
|
||||||
@@ -213,7 +215,9 @@ public:
|
|||||||
std::vector<std::string>&,
|
std::vector<std::string>&,
|
||||||
std::vector<std::string>&,
|
std::vector<std::string>&,
|
||||||
std::vector<float4x4>&);
|
std::vector<float4x4>&);
|
||||||
void serialize_geometry( std::ostream &Output );
|
void serialize_geometry( std::ostream &Output ) const;
|
||||||
|
// places contained geometry in provided ground node
|
||||||
|
void convert( TGroundNode &Groundnode ) const;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
1
Train.h
1
Train.h
@@ -15,7 +15,6 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "Gauge.h"
|
#include "Gauge.h"
|
||||||
#include "Spring.h"
|
#include "Spring.h"
|
||||||
#include "AdvSound.h"
|
#include "AdvSound.h"
|
||||||
#include "FadeSound.h"
|
|
||||||
#include "PyInt.h"
|
#include "PyInt.h"
|
||||||
#include "command.h"
|
#include "command.h"
|
||||||
|
|
||||||
|
|||||||
23
World.cpp
23
World.cpp
@@ -294,6 +294,7 @@ bool TWorld::Init( GLFWwindow *Window ) {
|
|||||||
glfwSetWindowTitle( window, ( Global::AppName + " (" + Global::SceneryFile + ")" ).c_str() ); // nazwa scenerii
|
glfwSetWindowTitle( window, ( Global::AppName + " (" + Global::SceneryFile + ")" ).c_str() ); // nazwa scenerii
|
||||||
UILayer.set_progress(0.01);
|
UILayer.set_progress(0.01);
|
||||||
UILayer.set_progress( "Loading scenery / Wczytywanie scenerii" );
|
UILayer.set_progress( "Loading scenery / Wczytywanie scenerii" );
|
||||||
|
GfxRenderer.Render();
|
||||||
|
|
||||||
WriteLog( "Ground init" );
|
WriteLog( "Ground init" );
|
||||||
if( true == Ground.Init( Global::SceneryFile ) ) {
|
if( true == Ground.Init( Global::SceneryFile ) ) {
|
||||||
@@ -1039,17 +1040,17 @@ bool TWorld::Update()
|
|||||||
// NOTE: experimentally changing this to prevent the desync.
|
// NOTE: experimentally changing this to prevent the desync.
|
||||||
// TODO: test what happens if we hit more than 20 * 0.01 sec slices, i.e. less than 5 fps
|
// TODO: test what happens if we hit more than 20 * 0.01 sec slices, i.e. less than 5 fps
|
||||||
Ground.Update(dt / updatecount, updatecount); // tu zrobić tylko coklatkową aktualizację przesunięć
|
Ground.Update(dt / updatecount, updatecount); // tu zrobić tylko coklatkową aktualizację przesunięć
|
||||||
/*
|
|
||||||
if (DebugModeFlag)
|
// yB dodał przyspieszacz fizyki
|
||||||
if (Global::bActive) // nie przyspieszać, gdy jedzie w tle :)
|
if( (true == DebugModeFlag)
|
||||||
if( Console::Pressed( GLFW_KEY_ESCAPE ) ) {
|
&& (true == Global::bActive) // nie przyspieszać, gdy jedzie w tle :)
|
||||||
// yB dodał przyspieszacz fizyki
|
&& ( glfwGetKey( window, GLFW_KEY_PAUSE ) == GLFW_PRESS ) ) {
|
||||||
Ground.Update(dt, n);
|
|
||||||
Ground.Update(dt, n);
|
Ground.Update( dt, updatecount );
|
||||||
Ground.Update(dt, n);
|
Ground.Update( dt, updatecount );
|
||||||
Ground.Update(dt, n); // 5 razy
|
Ground.Update( dt, updatecount );
|
||||||
}
|
Ground.Update( dt, updatecount ); // 5 razy
|
||||||
*/
|
}
|
||||||
// secondary fixed step simulation time routines
|
// secondary fixed step simulation time routines
|
||||||
|
|
||||||
while( m_secondaryupdateaccumulator >= m_secondaryupdaterate ) {
|
while( m_secondaryupdateaccumulator >= m_secondaryupdaterate ) {
|
||||||
|
|||||||
@@ -63,9 +63,6 @@
|
|||||||
<ClCompile Include="EvLaunch.cpp">
|
<ClCompile Include="EvLaunch.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="FadeSound.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Float3d.cpp">
|
<ClCompile Include="Float3d.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -338,9 +335,6 @@
|
|||||||
<ClInclude Include="Names.h">
|
<ClInclude Include="Names.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="FadeSound.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Sound.h">
|
<ClInclude Include="Sound.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|||||||
@@ -1187,11 +1187,12 @@ opengl_renderer::Render( TGroundRect *Groundcell ) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef EU07_USE_OLD_TERRAINCODE
|
||||||
if( Groundcell->nTerrain ) {
|
if( Groundcell->nTerrain ) {
|
||||||
|
|
||||||
Render( Groundcell->nTerrain );
|
Render( Groundcell->nTerrain );
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
Groundcell->iLastDisplay = Groundcell->iFrameNumber; // drugi raz nie potrzeba
|
Groundcell->iLastDisplay = Groundcell->iFrameNumber; // drugi raz nie potrzeba
|
||||||
result = true;
|
result = true;
|
||||||
|
|
||||||
@@ -1298,7 +1299,7 @@ opengl_renderer::Render( TSubRect *Groundsubcell ) {
|
|||||||
|
|
||||||
bool
|
bool
|
||||||
opengl_renderer::Render( TGroundNode *Node ) {
|
opengl_renderer::Render( TGroundNode *Node ) {
|
||||||
|
#ifdef EU07_USE_OLD_TERRAINCODE
|
||||||
switch (Node->iType)
|
switch (Node->iType)
|
||||||
{ // obiekty renderowane niezależnie od odległości
|
{ // obiekty renderowane niezależnie od odległości
|
||||||
case TP_SUBMODEL:
|
case TP_SUBMODEL:
|
||||||
@@ -1310,7 +1311,7 @@ opengl_renderer::Render( TGroundNode *Node ) {
|
|||||||
::glPopMatrix();
|
::glPopMatrix();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
double distancesquared;
|
double distancesquared;
|
||||||
switch( m_renderpass.draw_mode ) {
|
switch( m_renderpass.draw_mode ) {
|
||||||
case rendermode::shadows: {
|
case rendermode::shadows: {
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ void
|
|||||||
bounding_box( VecType_ &Mincorner, VecType_ &Maxcorner, Iterator_ First, Iterator_ Last ) {
|
bounding_box( VecType_ &Mincorner, VecType_ &Maxcorner, Iterator_ First, Iterator_ Last ) {
|
||||||
|
|
||||||
Mincorner = VecType_( typename std::numeric_limits<VecType_::value_type>::max() );
|
Mincorner = VecType_( typename std::numeric_limits<VecType_::value_type>::max() );
|
||||||
Maxcorner = VecType_( typename std::numeric_limits<VecType_::value_type>::min() );
|
Maxcorner = VecType_( typename std::numeric_limits<VecType_::value_type>::lowest() );
|
||||||
|
|
||||||
std::for_each(
|
std::for_each(
|
||||||
First, Last,
|
First, Last,
|
||||||
|
|||||||
Reference in New Issue
Block a user