Add OpenMW 0.47 commits up to 23 Sep 2021

pull/593/head
David Cernat 3 years ago
commit a01c874613

@ -1,19 +1,44 @@
#include "commands.hpp" #include "commands.hpp"
#include <QPointer>
#include <components/debug/debuglog.hpp>
#include <components/esm/loadland.hpp> #include <components/esm/loadland.hpp>
#include "editmode.hpp"
#include "terrainselection.hpp" #include "terrainselection.hpp"
#include "terrainshapemode.hpp"
#include "terraintexturemode.hpp"
#include "worldspacewidget.hpp"
CSVRender::DrawTerrainSelectionCommand::DrawTerrainSelectionCommand(TerrainSelection& terrainSelection, QUndoCommand* parent) CSVRender::DrawTerrainSelectionCommand::DrawTerrainSelectionCommand(WorldspaceWidget* worldspaceWidget, QUndoCommand* parent)
: mTerrainSelection(terrainSelection) : mWorldspaceWidget(worldspaceWidget)
{ } { }
void CSVRender::DrawTerrainSelectionCommand::redo() void CSVRender::DrawTerrainSelectionCommand::redo()
{ {
mTerrainSelection.update(); tryUpdate();
} }
void CSVRender::DrawTerrainSelectionCommand::undo() void CSVRender::DrawTerrainSelectionCommand::undo()
{ {
mTerrainSelection.update(); tryUpdate();
}
void CSVRender::DrawTerrainSelectionCommand::tryUpdate()
{
if (!mWorldspaceWidget)
{
Log(Debug::Verbose) << "Can't update terrain selection, no WorldspaceWidget found!";
return;
}
auto terrainMode = dynamic_cast<CSVRender::TerrainShapeMode*>(mWorldspaceWidget->getEditMode());
if (!terrainMode)
{
Log(Debug::Verbose) << "Can't update terrain selection in current EditMode";
return;
}
terrainMode->getTerrainSelection()->update();
} }

@ -1,8 +1,12 @@
#ifndef CSV_RENDER_COMMANDS_HPP #ifndef CSV_RENDER_COMMANDS_HPP
#define CSV_RENDER_COMMANDS_HPP #define CSV_RENDER_COMMANDS_HPP
#include <QPointer>
#include <QUndoCommand> #include <QUndoCommand>
#include "worldspacewidget.hpp"
namespace CSVRender namespace CSVRender
{ {
class TerrainSelection; class TerrainSelection;
@ -21,14 +25,17 @@ namespace CSVRender
*/ */
class DrawTerrainSelectionCommand : public QUndoCommand class DrawTerrainSelectionCommand : public QUndoCommand
{ {
private: private:
TerrainSelection& mTerrainSelection; QPointer<WorldspaceWidget> mWorldspaceWidget;
public: public:
DrawTerrainSelectionCommand(TerrainSelection& terrainSelection, QUndoCommand* parent = nullptr); DrawTerrainSelectionCommand(WorldspaceWidget* worldspaceWidget, QUndoCommand* parent = nullptr);
void redo() override; void redo() override;
void undo() override; void undo() override;
void tryUpdate();
}; };
} }

@ -287,7 +287,7 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges()
undoStack.beginMacro ("Edit shape and normal records"); undoStack.beginMacro ("Edit shape and normal records");
// One command at the beginning of the macro for redrawing the terrain-selection grid when undoing the changes. // One command at the beginning of the macro for redrawing the terrain-selection grid when undoing the changes.
undoStack.push(new DrawTerrainSelectionCommand(*mTerrainShapeSelection)); undoStack.push(new DrawTerrainSelectionCommand(&getWorldspaceWidget()));
for(CSMWorld::CellCoordinates cellCoordinates: mAlteredCells) for(CSMWorld::CellCoordinates cellCoordinates: mAlteredCells)
{ {
@ -358,7 +358,7 @@ void CSVRender::TerrainShapeMode::applyTerrainEditChanges()
pushNormalsEditToCommand(landNormalsNew, document, landTable, cellId); pushNormalsEditToCommand(landNormalsNew, document, landTable, cellId);
} }
// One command at the end of the macro for redrawing the terrain-selection grid when redoing the changes. // One command at the end of the macro for redrawing the terrain-selection grid when redoing the changes.
undoStack.push(new DrawTerrainSelectionCommand(*mTerrainShapeSelection)); undoStack.push(new DrawTerrainSelectionCommand(&getWorldspaceWidget()));
undoStack.endMacro(); undoStack.endMacro();
clearTransientEdits(); clearTransientEdits();
@ -1444,6 +1444,11 @@ void CSVRender::TerrainShapeMode::mouseMoveEvent (QMouseEvent *event)
mBrushDraw->hide(); mBrushDraw->hide();
} }
std::shared_ptr<CSVRender::TerrainSelection> CSVRender::TerrainShapeMode::getTerrainSelection()
{
return mTerrainShapeSelection;
}
void CSVRender::TerrainShapeMode::setBrushSize(int brushSize) void CSVRender::TerrainShapeMode::setBrushSize(int brushSize)
{ {
mBrushSize = brushSize; mBrushSize = brushSize;

@ -92,6 +92,8 @@ namespace CSVRender
void dragMoveEvent (QDragMoveEvent *event) override; void dragMoveEvent (QDragMoveEvent *event) override;
void mouseMoveEvent (QMouseEvent *event) override; void mouseMoveEvent (QMouseEvent *event) override;
std::shared_ptr<TerrainSelection> getTerrainSelection();
private: private:
/// Remove duplicates and sort mAlteredCells, then limitAlteredHeights forward and reverse /// Remove duplicates and sort mAlteredCells, then limitAlteredHeights forward and reverse
@ -176,7 +178,7 @@ namespace CSVRender
int mDragMode = InteractionType_None; int mDragMode = InteractionType_None;
osg::Group* mParentNode; osg::Group* mParentNode;
bool mIsEditing = false; bool mIsEditing = false;
std::unique_ptr<TerrainSelection> mTerrainShapeSelection; std::shared_ptr<TerrainSelection> mTerrainShapeSelection;
int mTotalDiffY = 0; int mTotalDiffY = 0;
std::vector<CSMWorld::CellCoordinates> mAlteredCells; std::vector<CSMWorld::CellCoordinates> mAlteredCells;
osg::Vec3d mEditingPos; osg::Vec3d mEditingPos;

@ -712,6 +712,11 @@ void CSVRender::TerrainTextureMode::mouseMoveEvent (QMouseEvent *event)
mBrushDraw->hide(); mBrushDraw->hide();
} }
std::shared_ptr<CSVRender::TerrainSelection> CSVRender::TerrainTextureMode::getTerrainSelection()
{
return mTerrainTextureSelection;
}
void CSVRender::TerrainTextureMode::setBrushSize(int brushSize) void CSVRender::TerrainTextureMode::setBrushSize(int brushSize)
{ {

@ -85,6 +85,8 @@ namespace CSVRender
void mouseMoveEvent (QMouseEvent *event) override; void mouseMoveEvent (QMouseEvent *event) override;
std::shared_ptr<TerrainSelection> getTerrainSelection();
private: private:
/// \brief Handle brush mechanics, maths regarding worldspace hit etc. /// \brief Handle brush mechanics, maths regarding worldspace hit etc.
void editTerrainTextureGrid (const WorldspaceHitResult& hit); void editTerrainTextureGrid (const WorldspaceHitResult& hit);
@ -115,7 +117,7 @@ namespace CSVRender
int mDragMode; int mDragMode;
osg::Group* mParentNode; osg::Group* mParentNode;
bool mIsEditing; bool mIsEditing;
std::unique_ptr<TerrainSelection> mTerrainTextureSelection; std::shared_ptr<TerrainSelection> mTerrainTextureSelection;
const int cellSize {ESM::Land::REAL_SIZE}; const int cellSize {ESM::Land::REAL_SIZE};
const int landTextureSize {ESM::Land::LAND_TEXTURE_SIZE}; const int landTextureSize {ESM::Land::LAND_TEXTURE_SIZE};

@ -452,6 +452,11 @@ CSVRender::WorldspaceHitResult CSVRender::WorldspaceWidget::mousePick (const QPo
return hit; return hit;
} }
CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode()
{
return dynamic_cast<CSVRender::EditMode *> (mEditMode->getCurrent());
}
void CSVRender::WorldspaceWidget::abortDrag() void CSVRender::WorldspaceWidget::abortDrag()
{ {
if (mDragging) if (mDragging)
@ -697,11 +702,6 @@ void CSVRender::WorldspaceWidget::handleInteractionPress (const WorldspaceHitRes
editMode.primaryOpenPressed (hit); editMode.primaryOpenPressed (hit);
} }
CSVRender::EditMode *CSVRender::WorldspaceWidget::getEditMode()
{
return dynamic_cast<CSVRender::EditMode *> (mEditMode->getCurrent());
}
void CSVRender::WorldspaceWidget::primaryOpen(bool activate) void CSVRender::WorldspaceWidget::primaryOpen(bool activate)
{ {
handleInteraction(InteractionType_PrimaryOpen, activate); handleInteraction(InteractionType_PrimaryOpen, activate);

@ -189,6 +189,8 @@ namespace CSVRender
/// Erase all overrides and restore the visual representation to its true state. /// Erase all overrides and restore the visual representation to its true state.
virtual void reset (unsigned int elementMask) = 0; virtual void reset (unsigned int elementMask) = 0;
EditMode *getEditMode();
protected: protected:
/// Visual elements in a scene /// Visual elements in a scene
@ -215,8 +217,6 @@ namespace CSVRender
void settingChanged (const CSMPrefs::Setting *setting) override; void settingChanged (const CSMPrefs::Setting *setting) override;
EditMode *getEditMode();
bool getSpeedMode(); bool getSpeedMode();
private: private:

@ -1931,6 +1931,7 @@ namespace MWMechanics
// Standing NPCs give way to moving ones if they are not in combat (or pursue) mode and either // Standing NPCs give way to moving ones if they are not in combat (or pursue) mode and either
// follow player or have a AIWander package with non-empty wander area. // follow player or have a AIWander package with non-empty wander area.
bool shouldAvoidCollision = isMoving; bool shouldAvoidCollision = isMoving;
bool shouldGiveWay = false;
bool shouldTurnToApproachingActor = !isMoving; bool shouldTurnToApproachingActor = !isMoving;
MWWorld::Ptr currentTarget; // Combat or pursue target (NPCs should not avoid collision with their targets). MWWorld::Ptr currentTarget; // Combat or pursue target (NPCs should not avoid collision with their targets).
const auto& aiSequence = ptr.getClass().getCreatureStats(ptr).getAiSequence(); const auto& aiSequence = ptr.getClass().getCreatureStats(ptr).getAiSequence();
@ -1941,7 +1942,7 @@ namespace MWMechanics
else if (package->getTypeId() == AiPackageTypeId::Wander && giveWayWhenIdle) else if (package->getTypeId() == AiPackageTypeId::Wander && giveWayWhenIdle)
{ {
if (!static_cast<const AiWander*>(package.get())->isStationary()) if (!static_cast<const AiWander*>(package.get())->isStationary())
shouldAvoidCollision = true; shouldGiveWay = true;
} }
else if (package->getTypeId() == AiPackageTypeId::Combat || package->getTypeId() == AiPackageTypeId::Pursue) else if (package->getTypeId() == AiPackageTypeId::Combat || package->getTypeId() == AiPackageTypeId::Pursue)
{ {
@ -1951,7 +1952,7 @@ namespace MWMechanics
break; break;
} }
} }
if (!shouldAvoidCollision) if (!shouldAvoidCollision && !shouldGiveWay)
continue; continue;
osg::Vec2f baseSpeed = origMovement * maxSpeed; osg::Vec2f baseSpeed = origMovement * maxSpeed;
@ -1960,14 +1961,14 @@ namespace MWMechanics
osg::Vec3f halfExtents = world->getHalfExtents(ptr); osg::Vec3f halfExtents = world->getHalfExtents(ptr);
float maxDistToCheck = isMoving ? maxDistForPartialAvoiding : maxDistForStrictAvoiding; float maxDistToCheck = isMoving ? maxDistForPartialAvoiding : maxDistForStrictAvoiding;
float timeToCollision = maxTimeToCheck; float timeToCheck = maxTimeToCheck;
if (!shouldGiveWay && !aiSequence.isEmpty())
timeToCheck = std::min(timeToCheck, getTimeToDestination(**aiSequence.begin(), basePos, maxSpeed, duration, halfExtents));
float timeToCollision = timeToCheck;
osg::Vec2f movementCorrection(0, 0); osg::Vec2f movementCorrection(0, 0);
float angleToApproachingActor = 0; float angleToApproachingActor = 0;
const float timeToDestination = aiSequence.isEmpty()
? std::numeric_limits<float>::max()
: getTimeToDestination(**aiSequence.begin(), basePos, maxSpeed, duration, halfExtents);
// Iterate through all other actors and predict collisions. // Iterate through all other actors and predict collisions.
for(PtrActorMap::iterator otherIter(mActors.begin()); otherIter != mActors.end(); ++otherIter) for(PtrActorMap::iterator otherIter(mActors.begin()); otherIter != mActors.end(); ++otherIter)
{ {
@ -2004,7 +2005,7 @@ namespace MWMechanics
continue; // No solution; distance is always >= collisionDist. continue; // No solution; distance is always >= collisionDist.
float t = (-vr - std::sqrt(Dh)) / v2; float t = (-vr - std::sqrt(Dh)) / v2;
if (t < 0 || t > timeToCollision || t > timeToDestination) if (t < 0 || t > timeToCollision)
continue; continue;
// Check visibility and awareness last as it's expensive. // Check visibility and awareness last as it's expensive.
@ -2024,7 +2025,7 @@ namespace MWMechanics
movementCorrection.y() *= 0.5f; movementCorrection.y() *= 0.5f;
} }
if (timeToCollision < maxTimeToCheck) if (timeToCollision < timeToCheck)
{ {
// Try to evade the nearest collision. // Try to evade the nearest collision.
osg::Vec2f newMovement = origMovement + movementCorrection; osg::Vec2f newMovement = origMovement + movementCorrection;

@ -414,7 +414,7 @@ namespace MWMechanics
bool runFallback = true; bool runFallback = true;
if (pathgrid && !actor.getClass().isPureWaterCreature(actor)) if (pathgrid != nullptr && !pathgrid->mPoints.empty() && !actor.getClass().isPureWaterCreature(actor))
{ {
ESM::Pathgrid::PointList points; ESM::Pathgrid::PointList points;
Misc::CoordinateConverter coords(storage.mCell->getCell()); Misc::CoordinateConverter coords(storage.mCell->getCell());

@ -754,6 +754,9 @@ namespace MWMechanics
const ESM::Pathgrid *pathgrid = const ESM::Pathgrid *pathgrid =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*currentCell->getCell()); MWBase::Environment::get().getWorld()->getStore().get<ESM::Pathgrid>().search(*currentCell->getCell());
if (pathgrid == nullptr || pathgrid->mPoints.empty())
return;
int index = PathFinder::getClosestPoint(pathgrid, PathFinder::makeOsgVec3(dest)); int index = PathFinder::getClosestPoint(pathgrid, PathFinder::makeOsgVec3(dest));
getPathGridGraph(currentCell).getNeighbouringPoints(index, points); getPathGridGraph(currentCell).getNeighbouringPoints(index, points);

@ -206,9 +206,6 @@ namespace MWMechanics
endPointInLocalCoords, endPointInLocalCoords,
startNode); startNode);
if (!endNode.second)
return;
// if it's shorter for actor to travel from start to end, than to travel from either // if it's shorter for actor to travel from start to end, than to travel from either
// start or end to nearest pathgrid point, just travel from start to end. // start or end to nearest pathgrid point, just travel from start to end.
float startToEndLength2 = (endPointInLocalCoords - startPointInLocalCoords).length2(); float startToEndLength2 = (endPointInLocalCoords - startPointInLocalCoords).length2();
@ -279,6 +276,7 @@ namespace MWMechanics
// unreachable pathgrid point. // unreachable pathgrid point.
// //
// The AI routines will have to deal with such situations. // The AI routines will have to deal with such situations.
if (endNode.second)
*out++ = endPoint; *out++ = endPoint;
} }

Loading…
Cancel
Save