mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-07-12 19:21:42 +00:00
Add OpenMW 0.47 commits up to 23 Sep 2021
This commit is contained in:
commit
a01c874613
12 changed files with 81 additions and 33 deletions
|
@ -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,7 +276,8 @@ 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.
|
||||||
*out++ = endPoint;
|
if (endNode.second)
|
||||||
|
*out++ = endPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
float PathFinder::getZAngleToNext(float x, float y) const
|
float PathFinder::getZAngleToNext(float x, float y) const
|
||||||
|
|
Loading…
Reference in a new issue