@@ -137,6 +137,8 @@ namespace MWRender
137
137
fog->mBounds .mMinY = mBounds .yMin ();
138
138
fog->mBounds .mMaxY = mBounds .yMax ();
139
139
fog->mNorthMarkerAngle = mAngle ;
140
+ fog->mCenterX = mCenter .x ();
141
+ fog->mCenterY = mCenter .y ();
140
142
141
143
fog->mFogTextures .reserve (segments.first * segments.second );
142
144
@@ -145,15 +147,12 @@ namespace MWRender
145
147
for (int y = 0 ; y < segments.second ; ++y)
146
148
{
147
149
const MapSegment& segment = mInteriorSegments [std::make_pair (x, y)];
148
-
149
- fog->mFogTextures .emplace_back ();
150
-
151
- // saving even if !segment.mHasFogState so we don't mess up the segmenting
152
- // plus, older openmw versions can't deal with empty images
153
- segment.saveFogOfWar (fog->mFogTextures .back ());
154
-
155
- fog->mFogTextures .back ().mX = x;
156
- fog->mFogTextures .back ().mY = y;
150
+ if (!segment.mHasFogState )
151
+ continue ;
152
+ ESM::FogTexture& texture = fog->mFogTextures .emplace_back ();
153
+ segment.saveFogOfWar (texture);
154
+ texture.mX = x;
155
+ texture.mY = y;
157
156
}
158
157
}
159
158
@@ -332,31 +331,28 @@ namespace MWRender
332
331
333
332
float zMin = mBounds .zMin ();
334
333
float zMax = mBounds .zMax ();
334
+ mCenter = osg::Vec2f (mBounds .center ().x (), mBounds .center ().y ());
335
335
336
336
// If there is fog state in the CellStore (e.g. when it came from a savegame) we need to do some checks
337
337
// to see if this state is still valid.
338
338
// Both the cell bounds and the NorthMarker rotation could be changed by the content files or exchanged models.
339
339
// If they changed by too much then parts of the interior might not be covered by the map anymore.
340
340
// The following code detects this, and discards the CellStore's fog state if it needs to.
341
- std::vector<std::pair<int , int >> segmentMappings;
342
- if (cell->getFog ())
341
+ int xOffset = 0 ;
342
+ int yOffset = 0 ;
343
+ if (const ESM::FogState* fog = cell->getFog ())
343
344
{
344
- ESM::FogState* fog = cell->getFog ();
345
-
346
345
if (std::abs (mAngle - fog->mNorthMarkerAngle ) < osg::DegreesToRadians (5 .f ))
347
346
{
348
347
// Expand mBounds so the saved textures fit the same grid
349
- int xOffset = 0 ;
350
- int yOffset = 0 ;
351
348
if (fog->mBounds .mMinX < mBounds .xMin ())
352
349
{
353
350
mBounds .xMin () = fog->mBounds .mMinX ;
354
351
}
355
352
else if (fog->mBounds .mMinX > mBounds .xMin ())
356
353
{
357
354
float diff = fog->mBounds .mMinX - mBounds .xMin ();
358
- xOffset += diff / mMapWorldSize ;
359
- xOffset++;
355
+ xOffset = std::ceil (diff / mMapWorldSize );
360
356
mBounds .xMin () = fog->mBounds .mMinX - xOffset * mMapWorldSize ;
361
357
}
362
358
if (fog->mBounds .mMinY < mBounds .yMin ())
@@ -366,8 +362,7 @@ namespace MWRender
366
362
else if (fog->mBounds .mMinY > mBounds .yMin ())
367
363
{
368
364
float diff = fog->mBounds .mMinY - mBounds .yMin ();
369
- yOffset += diff / mMapWorldSize ;
370
- yOffset++;
365
+ yOffset = std::ceil (diff / mMapWorldSize );
371
366
mBounds .yMin () = fog->mBounds .mMinY - yOffset * mMapWorldSize ;
372
367
}
373
368
if (fog->mBounds .mMaxX > mBounds .xMax ())
@@ -378,22 +373,14 @@ namespace MWRender
378
373
if (xOffset != 0 || yOffset != 0 )
379
374
Log (Debug::Warning) << " Warning: expanding fog by " << xOffset << " , " << yOffset;
380
375
381
- const auto & textures = fog->mFogTextures ;
382
- segmentMappings.reserve (textures.size ());
383
- osg::BoundingBox savedBounds{ fog->mBounds .mMinX , fog->mBounds .mMinY , 0 , fog->mBounds .mMaxX ,
384
- fog->mBounds .mMaxY , 0 };
385
- auto segments = divideIntoSegments (savedBounds, mMapWorldSize );
386
- for (int x = 0 ; x < segments.first ; ++x)
387
- for (int y = 0 ; y < segments.second ; ++y)
388
- segmentMappings.emplace_back (std::make_pair (x + xOffset, y + yOffset));
389
-
390
376
mAngle = fog->mNorthMarkerAngle ;
377
+ mCenter .x () = fog->mCenterX ;
378
+ mCenter .y () = fog->mCenterY ;
391
379
}
392
380
}
393
381
394
382
osg::Vec2f min (mBounds .xMin (), mBounds .yMin ());
395
383
396
- osg::Vec2f center (mBounds .center ().x (), mBounds .center ().y ());
397
384
osg::Quat cameraOrient (mAngle , osg::Vec3d (0 , 0 , -1 ));
398
385
399
386
auto segments = divideIntoSegments (mBounds , mMapWorldSize );
@@ -404,10 +391,10 @@ namespace MWRender
404
391
osg::Vec2f start = min + osg::Vec2f (mMapWorldSize * x, mMapWorldSize * y);
405
392
osg::Vec2f newcenter = start + osg::Vec2f (mMapWorldSize / 2 .f , mMapWorldSize / 2 .f );
406
393
407
- osg::Vec2f a = newcenter - center ;
394
+ osg::Vec2f a = newcenter - mCenter ;
408
395
osg::Vec3f rotatedCenter = cameraOrient * (osg::Vec3f (a.x (), a.y (), 0 ));
409
396
410
- osg::Vec2f pos = osg::Vec2f (rotatedCenter.x (), rotatedCenter.y ()) + center ;
397
+ osg::Vec2f pos = osg::Vec2f (rotatedCenter.x (), rotatedCenter.y ()) + mCenter ;
411
398
412
399
setupRenderToTexture (x, y, pos.x (), pos.y (), osg::Vec3f (north.x (), north.y (), 0 .f ), zMin, zMax);
413
400
@@ -416,14 +403,16 @@ namespace MWRender
416
403
if (!segment.mFogOfWarImage )
417
404
{
418
405
bool loaded = false ;
419
- for ( size_t index {}; index < segmentMappings. size (); index ++ )
406
+ if ( const ESM::FogState* fog = cell-> getFog () )
420
407
{
421
- if (segmentMappings[index ] == coords)
408
+ auto match = std::find_if (
409
+ fog->mFogTextures .begin (), fog->mFogTextures .end (), [&](const ESM::FogTexture& texture) {
410
+ return texture.mX == x - xOffset && texture.mY == y - yOffset;
411
+ });
412
+ if (match != fog->mFogTextures .end ())
422
413
{
423
- ESM::FogState* fog = cell->getFog ();
424
- segment.loadFogOfWar (fog->mFogTextures [index ]);
414
+ segment.loadFogOfWar (*match);
425
415
loaded = true ;
426
- break ;
427
416
}
428
417
}
429
418
if (!loaded)
@@ -435,7 +424,7 @@ namespace MWRender
435
424
436
425
void LocalMap::worldToInteriorMapPosition (osg::Vec2f pos, float & nX, float & nY, int & x, int & y)
437
426
{
438
- pos = rotatePoint (pos, osg::Vec2f ( mBounds . center (). x (), mBounds . center (). y ()) , mAngle );
427
+ pos = rotatePoint (pos, mCenter , mAngle );
439
428
440
429
osg::Vec2f min (mBounds .xMin (), mBounds .yMin ());
441
430
@@ -451,7 +440,7 @@ namespace MWRender
451
440
osg::Vec2f min (mBounds .xMin (), mBounds .yMin ());
452
441
osg::Vec2f pos (mMapWorldSize * (nX + x) + min.x (), mMapWorldSize * (1 .0f - nY + y) + min.y ());
453
442
454
- pos = rotatePoint (pos, osg::Vec2f ( mBounds . center (). x (), mBounds . center (). y ()) , -mAngle );
443
+ pos = rotatePoint (pos, mCenter , -mAngle );
455
444
return pos;
456
445
}
457
446
@@ -590,7 +579,7 @@ namespace MWRender
590
579
MyGUI::IntRect LocalMap::getInteriorGrid () const
591
580
{
592
581
auto segments = divideIntoSegments (mBounds , mMapWorldSize );
593
- return { 0 , 0 , segments.first - 1 , segments.second - 1 };
582
+ return { - 1 , - 1 , segments.first , segments.second };
594
583
}
595
584
596
585
void LocalMap::MapSegment::createFogOfWarTexture ()
0 commit comments