bool TextureAtlas::InsertSurface( SDL_Surface *_surface, unsigned int &x, unsigned int &y ) { boxTmp = box; surfaceTmp = _surface; bool result = InsertSurface(); x = xTmp; y = yTmp; return result; }
bool TextureAtlas::InsertSurface() { ElasticBox *boxTmpParent = boxTmp; if(boxTmp->surfaceHeight == 0 && boxTmp->surfaceWidth == 0) { SDL_Rect dstrect; xTmp = dstrect.x = boxTmp->x; yTmp = dstrect.y = boxTmp->y; // Копируем всю поверхность SDL_SetSurfaceBlendMode(surfaceTmp, SDL_BLENDMODE_NONE); int r = SDL_BlitSurface(surfaceTmp, nullptr, surface, &dstrect); if(r != 0) { LOG(LOG_ERROR, "TextureAtlas. Surfase не создана."); return false; } unsigned int w1 = boxTmp->surfaceWidth = surfaceTmp->w; unsigned int h1 = boxTmp->surfaceHeight = surfaceTmp->h; boxTmp->childrenBoxSmall = new ElasticBox; boxTmp->childrenBoxSmall->surfaceHeight = 0; boxTmp->childrenBoxSmall->surfaceWidth = 0; boxTmp->childrenBoxSmall->childrenBoxBig = nullptr; boxTmp->childrenBoxSmall->childrenBoxSmall = nullptr; boxTmp->childrenBoxBig = new ElasticBox; boxTmp->childrenBoxBig->surfaceHeight = 0; boxTmp->childrenBoxBig->surfaceWidth = 0; boxTmp->childrenBoxBig->childrenBoxBig = nullptr; boxTmp->childrenBoxBig->childrenBoxSmall = nullptr; // Правый верхний прямоугольник double d1 = sqrt(double(h1 * h1) + double((boxTmp->width - w1) * (boxTmp->width - w1))); // Левый нижний прямоугольник double d2 = sqrt(double((boxTmp->height - h1) * (boxTmp->height - h1)) + double(w1 * w1)); if(d1 < d2) { // Правый верхний прямоугольник - маленький boxTmp->childrenBoxSmall->height = h1; boxTmp->childrenBoxSmall->width = boxTmp->width - w1 - indent; boxTmp->childrenBoxSmall->x = boxTmp->x + w1 + indent; boxTmp->childrenBoxSmall->y = boxTmp->y; boxTmp->childrenBoxBig->x = boxTmp->x; boxTmp->childrenBoxBig->y = boxTmp->y + h1 + indent; boxTmp->childrenBoxBig->width = boxTmp->width; boxTmp->childrenBoxBig->height = boxTmp->height - h1 - indent; } else { // Левый нижний прямоугольник - маленький boxTmp->childrenBoxSmall->height = boxTmp->height - h1 - indent; boxTmp->childrenBoxSmall->width = w1; boxTmp->childrenBoxSmall->x = boxTmp->x; boxTmp->childrenBoxSmall->y = boxTmp->y + h1 + indent; boxTmp->childrenBoxBig->x = boxTmp->x + w1 + indent; boxTmp->childrenBoxBig->y = boxTmp->y; boxTmp->childrenBoxBig->width = boxTmp->width - w1 - indent; boxTmp->childrenBoxBig->height = boxTmp->height; } } else { // Попытаемся уместиться в маленькую площадь. if(boxTmp->childrenBoxSmall->height >= surfaceTmp->h && boxTmp->childrenBoxSmall->width >= surfaceTmp->w) { boxTmp = boxTmp->childrenBoxSmall; if(InsertSurface()) { return true; } else boxTmp = boxTmpParent; } if(boxTmp->childrenBoxBig->height >= surfaceTmp->h && boxTmp->childrenBoxBig->width >= surfaceTmp->w) { boxTmp = boxTmp->childrenBoxBig; return InsertSurface(); } return false; } return true; }
/*! * Saves for each photon the selected data. */ void PhotonMapExportDB::SaveSelectedData( std::vector< Photon* > raysLists ) { const char* tail = 0; sqlite3_stmt* stmt; QString insertCommand( "INSERT INTO Photons VALUES( @id" ); if( m_saveCoordinates ) insertCommand.append( ", @x, @y, @z" ); if( m_saveSide ) insertCommand.append( ", @side" ); if( m_savePrevNexID ) insertCommand.append( ", @prev, @next" ); if( m_saveSurfaceID ) insertCommand.append( ", @surfaceID" ); insertCommand.append( ")" ); sqlite3_prepare( m_pDB, insertCommand.toStdString().c_str(), 256, &stmt, &tail ); char* sErrMsg = 0; sqlite3_exec( m_pDB, "BEGIN TRANSACTION", 0, 0, &sErrMsg ); unsigned long nPhotonElements = raysLists.size(); double previousPhotonID = 0; for( unsigned int i = 0; i < raysLists.size(); i++ ) { int parameterIndex = 0; Photon* photon = raysLists[i]; if( photon->id < 1 ) previousPhotonID = 0; unsigned long urlId = 0; Transform worldToObject( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ); if( photon->intersectedSurface ) { if( !m_surfaceIdentfier.contains( photon->intersectedSurface ) ) InsertSurface( photon->intersectedSurface ); urlId = m_surfaceIdentfier.indexOf( photon->intersectedSurface ) ; worldToObject = m_surfaceWorldToObject[urlId]; urlId++; } sqlite3_bind_text( stmt, ++parameterIndex, QString::number(++m_exportedPhoton ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); if( m_saveCoordinates && m_saveCoordinatesInGlobal ) { Point3D photonPos = m_concentratorToWorld( photon->pos ); sqlite3_bind_text( stmt, ++parameterIndex, QString::number( photonPos.x ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); sqlite3_bind_text( stmt, ++parameterIndex, QString::number( photonPos.y ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); sqlite3_bind_text( stmt, ++parameterIndex, QString::number( photonPos.z ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); } else if( m_saveCoordinates && !m_saveCoordinatesInGlobal ) { Point3D photonPos = worldToObject( photon->pos ); sqlite3_bind_text( stmt, ++parameterIndex, QString::number( photonPos.x ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); sqlite3_bind_text( stmt, ++parameterIndex, QString::number( photonPos.y ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); sqlite3_bind_text( stmt, ++parameterIndex, QString::number( photonPos.z ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); } if( m_saveSide ) sqlite3_bind_text( stmt, ++parameterIndex, QString::number( photon->side ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); if( m_savePrevNexID ) { sqlite3_bind_text( stmt, ++parameterIndex, QString::number( previousPhotonID ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); int nextPhotonID = 0; if( ( i < ( nPhotonElements - 1 ) ) && ( raysLists[i+1]->id > 0 ) ) nextPhotonID = m_exportedPhoton +1; sqlite3_bind_text( stmt, ++parameterIndex, QString::number( nextPhotonID ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); } if( m_saveSurfaceID ) sqlite3_bind_text( stmt, ++parameterIndex, QString::number( urlId ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); sqlite3_bind_text( stmt, 1, QString::number(++m_exportedPhoton ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); sqlite3_step( stmt ); sqlite3_clear_bindings( stmt ); sqlite3_reset( stmt ); previousPhotonID = m_exportedPhoton; } int rc = sqlite3_exec( m_pDB, "END TRANSACTION", 0, 0, &sErrMsg ); sqlite3_finalize( stmt ); if( rc != SQLITE_OK ) { std::cout<< "SQL error: "<<sErrMsg<<"\n"<<std::endl; sqlite3_free( sErrMsg ); } }
/*! * Saves for each photon all the data, except previous and next photon identifier. */ void PhotonMapExportDB::SaveNotNextPrevID( std::vector< Photon* > raysLists ) { const char* tail = 0; sqlite3_stmt* stmt; char insertSQL[256] ="\0"; sprintf( insertSQL, "INSERT INTO Photons VALUES( @id, @x, @y, @z, @side, @surfaceID )" ); sqlite3_prepare( m_pDB, insertSQL, 256, &stmt, &tail ); char* sErrMsg = 0; sqlite3_exec( m_pDB, "BEGIN TRANSACTION", 0, 0, &sErrMsg ); unsigned long nPhotonElements = raysLists.size(); if( m_saveCoordinatesInGlobal ) { for( unsigned int i = 0; i < nPhotonElements; i++ ) { Photon* photon = raysLists[i]; sqlite3_bind_text( stmt, 1, QString::number(++m_exportedPhoton ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); //m_saveCoordinates Point3D photonPos = m_concentratorToWorld( photon->pos ); sqlite3_bind_text( stmt, 2, QString::number( photonPos.x ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); sqlite3_bind_text( stmt, 3, QString::number( photonPos.y ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); sqlite3_bind_text( stmt, 4, QString::number( photonPos.z ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); //m_saveSide sqlite3_bind_text( stmt, 5, QString::number( photon->side ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); //m_saveSurfaceID unsigned long urlId = 0; if( photon->intersectedSurface ) { if( !m_surfaceIdentfier.contains( photon->intersectedSurface ) ) InsertSurface( photon->intersectedSurface ); urlId = m_surfaceIdentfier.indexOf( photon->intersectedSurface ) + 1; } sqlite3_bind_text( stmt, 6, QString::number( urlId ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); sqlite3_step( stmt ); sqlite3_clear_bindings( stmt ); sqlite3_reset( stmt ); } } else { for( unsigned int i = 0; i < nPhotonElements; i++ ) { std::stringstream ss; Photon* photon = raysLists[i]; unsigned long urlId = 0; Transform worldToObject( 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ); if( photon->intersectedSurface ) { if( !m_surfaceIdentfier.contains( photon->intersectedSurface ) ) InsertSurface( photon->intersectedSurface ); urlId = m_surfaceIdentfier.indexOf( photon->intersectedSurface ) ; worldToObject = m_surfaceWorldToObject[urlId]; urlId++; } sqlite3_bind_text( stmt, 1, QString::number(++m_exportedPhoton ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); //m_saveCoordinates Point3D localPos = worldToObject( photon->pos ); sqlite3_bind_text( stmt, 2, QString::number( localPos.x ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); sqlite3_bind_text( stmt, 3, QString::number( localPos.y ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); sqlite3_bind_text( stmt, 4, QString::number( localPos.z ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); //m_saveSide sqlite3_bind_text( stmt, 5, QString::number( photon->side ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); //m_saveSurfaceID sqlite3_bind_text( stmt, 6, QString::number( urlId ).toStdString().c_str(), -1, SQLITE_TRANSIENT ); sqlite3_step( stmt ); sqlite3_clear_bindings( stmt ); sqlite3_reset( stmt ); } } int rc = sqlite3_exec( m_pDB, "END TRANSACTION", 0, 0, &sErrMsg ); sqlite3_finalize( stmt ); if( rc != SQLITE_OK ) { std::cout<< "SQL error: "<<sErrMsg<<"\n"<<std::endl; sqlite3_free( sErrMsg ); } }