mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-03 09:19:41 +00:00
Handle changes to race record when rendering actors
This commit is contained in:
parent
b2115b60e6
commit
1276e0fa9b
7 changed files with 98 additions and 16 deletions
|
@ -89,12 +89,12 @@ opencs_units (view/render
|
|||
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
||||
previewwidget editmode instancemode instanceselectionmode instancemovemode
|
||||
orbitcameramode pathgridmode selectionmode pathgridselectionmode cameracontroller
|
||||
cellwater terraintexturemode
|
||||
cellwater terraintexturemode actor
|
||||
)
|
||||
|
||||
opencs_units_noqt (view/render
|
||||
lighting lightingday lightingnight lightingbright object cell terrainstorage tagbase
|
||||
cellarrow cellmarker cellborder pathgrid actor
|
||||
cellarrow cellmarker cellborder pathgrid
|
||||
)
|
||||
|
||||
opencs_hdrs_noqt (view/render
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "actoradapter.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <components/debug/debuglog.hpp>
|
||||
#include <components/esm/loadarmo.hpp>
|
||||
#include <components/esm/loadclot.hpp>
|
||||
#include <components/esm/loadnpc.hpp>
|
||||
|
@ -45,17 +44,56 @@ namespace CSMWorld
|
|||
|
||||
void ActorAdapter::handleReferenceableChanged(const QModelIndex& topLeft, const QModelIndex& botRight)
|
||||
{
|
||||
// TODO
|
||||
// Setup
|
||||
const int TypeColumn = mReferenceables.findColumnIndex(CSMWorld::Columns::ColumnId_RecordType);
|
||||
int rowStart = getHighestIndex(topLeft).row();
|
||||
int rowEnd = getHighestIndex(botRight).row();
|
||||
|
||||
// Handle each record
|
||||
for (int row = rowStart; row <= rowEnd; ++row)
|
||||
{
|
||||
int type = mReferenceables.getData(row, TypeColumn).toInt();
|
||||
if (type == CSMWorld::UniversalId::Type_Creature || type == CSMWorld::UniversalId::Type_Npc)
|
||||
{
|
||||
// Update the cached npc or creature
|
||||
std::string refId = mReferenceables.getId(row);
|
||||
if (mActorPartMaps.find(refId) != mActorPartMaps.end())
|
||||
updateActor(refId);
|
||||
}
|
||||
else if (type == CSMWorld::UniversalId::Type_Armor)
|
||||
{
|
||||
// TODO update everything?
|
||||
// store all items referenced when creating map and check against that here
|
||||
}
|
||||
else if (type == CSMWorld::UniversalId::Type_Clothing)
|
||||
{
|
||||
// TODO update everything?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ActorAdapter::handleRaceChanged(const QModelIndex& topLeft, const QModelIndex& botRight)
|
||||
{
|
||||
// TODO
|
||||
int rowStart = getHighestIndex(topLeft).row();
|
||||
int rowEnd = getHighestIndex(botRight).row();
|
||||
for (int row = rowStart; row <= rowEnd; ++row)
|
||||
{
|
||||
std::string raceId = mRaces.getId(row);
|
||||
updateNpcsWithRace(raceId);
|
||||
}
|
||||
}
|
||||
|
||||
void ActorAdapter::handleBodyPartChanged(const QModelIndex& topLeft, const QModelIndex& botRight)
|
||||
{
|
||||
// TODO
|
||||
Log(Debug::Info) << "Body Part Changed (" << topLeft.row() << ", " << topLeft.column() << ") (" << botRight.row() << ", " << botRight.column() << ")";
|
||||
}
|
||||
|
||||
QModelIndex ActorAdapter::getHighestIndex(QModelIndex index) const
|
||||
{
|
||||
while (index.parent().isValid())
|
||||
index = index.parent();
|
||||
return index;
|
||||
}
|
||||
|
||||
ActorAdapter::RacePartMap& ActorAdapter::getOrCreateRacePartMap(const std::string& raceId, bool isFemale)
|
||||
|
@ -174,10 +212,6 @@ namespace CSMWorld
|
|||
npcMap.emplace(static_cast<ESM::PartReferenceType>(part.mPart), bodyPartId);
|
||||
}
|
||||
}
|
||||
else if (recordType == CSMWorld::UniversalId::Type_Weapon)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -233,10 +267,24 @@ namespace CSMWorld
|
|||
}
|
||||
|
||||
mActorPartMaps[refId] = npcMap;
|
||||
emit actorChanged(refId);
|
||||
}
|
||||
|
||||
void ActorAdapter::updateCreature(const std::string& refId)
|
||||
{
|
||||
// TODO
|
||||
emit actorChanged(refId);
|
||||
}
|
||||
|
||||
void ActorAdapter::updateNpcsWithRace(const std::string& raceId)
|
||||
{
|
||||
for (auto it : mActorPartMaps)
|
||||
{
|
||||
auto& refId = it.first;
|
||||
auto& npc = dynamic_cast<const Record<ESM::NPC>&>(mReferenceables.getRecord(refId)).get();
|
||||
if (npc.mRace == raceId)
|
||||
{
|
||||
updateNpc(refId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,6 +60,11 @@ namespace CSMWorld
|
|||
|
||||
private:
|
||||
|
||||
ActorAdapter(const ActorAdapter&) = delete;
|
||||
ActorAdapter& operator=(const ActorAdapter&) = delete;
|
||||
|
||||
QModelIndex getHighestIndex(QModelIndex) const;
|
||||
|
||||
RacePartMap& getOrCreateRacePartMap(const std::string& raceId, bool isFemale);
|
||||
|
||||
void updateRaceParts(const std::string& raceId);
|
||||
|
@ -67,6 +72,8 @@ namespace CSMWorld
|
|||
void updateNpc(const std::string& refId);
|
||||
void updateCreature(const std::string& refId);
|
||||
|
||||
void updateNpcsWithRace(const std::string& raceId);
|
||||
|
||||
RefIdCollection& mReferenceables;
|
||||
IdCollection<ESM::Race>& mRaces;
|
||||
IdCollection<ESM::BodyPart>& mBodyParts;
|
||||
|
|
|
@ -20,6 +20,7 @@ namespace CSVRender
|
|||
|
||||
Actor::Actor(const std::string& id, int type, CSMWorld::Data& data)
|
||||
: mId(id)
|
||||
, mInitialized(false)
|
||||
, mType(type)
|
||||
, mData(data)
|
||||
, mBaseNode(new osg::Group())
|
||||
|
@ -45,7 +46,22 @@ namespace CSVRender
|
|||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
Log(Debug::Error) << "Exception in Actor::update(): " << e.what();
|
||||
Log(Debug::Info) << "Exception in Actor::update(): " << e.what();
|
||||
}
|
||||
|
||||
if (!mInitialized)
|
||||
{
|
||||
mInitialized = true;
|
||||
connect(mData.getActorAdapter(), SIGNAL(actorChanged(const std::string&)), this, SLOT(handleActorChanged(const std::string&)));
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::handleActorChanged(const std::string& refId)
|
||||
{
|
||||
if (mId == refId)
|
||||
{
|
||||
Log(Debug::Info) << "Actor::actorChanged " << mId;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include <osg/ref_ptr>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <components/esm/loadarmo.hpp>
|
||||
#include <components/sceneutil/visitor.hpp>
|
||||
|
||||
|
@ -26,8 +28,9 @@ namespace SceneUtil
|
|||
namespace CSVRender
|
||||
{
|
||||
/// Handles loading an npc or creature
|
||||
class Actor
|
||||
class Actor : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
/// Creates an actor.
|
||||
/// \param id The referenceable id
|
||||
|
@ -41,6 +44,9 @@ namespace CSVRender
|
|||
/// (Re)creates the npc or creature renderable
|
||||
void update();
|
||||
|
||||
private slots:
|
||||
void handleActorChanged(const std::string& refId);
|
||||
|
||||
private:
|
||||
void updateCreature();
|
||||
void updateNpc();
|
||||
|
@ -54,6 +60,7 @@ namespace CSVRender
|
|||
static const std::string MeshPrefix;
|
||||
|
||||
std::string mId;
|
||||
bool mInitialized;
|
||||
int mType;
|
||||
CSMWorld::Data& mData;
|
||||
|
||||
|
|
|
@ -134,9 +134,10 @@ void CSVRender::Object::update()
|
|||
{
|
||||
if (recordType == CSMWorld::UniversalId::Type_Npc || recordType == CSMWorld::UniversalId::Type_Creature)
|
||||
{
|
||||
Actor actor(mReferenceableId, recordType, mData);
|
||||
actor.update();
|
||||
mBaseNode->addChild(actor.getBaseNode());
|
||||
if (!mActor)
|
||||
mActor.reset(new Actor(mReferenceableId, recordType, mData));
|
||||
mActor->update();
|
||||
mBaseNode->addChild(mActor->getBaseNode());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef OPENCS_VIEW_OBJECT_H
|
||||
#define OPENCS_VIEW_OBJECT_H
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include <osg/ref_ptr>
|
||||
|
@ -41,6 +42,7 @@ namespace CSMWorld
|
|||
|
||||
namespace CSVRender
|
||||
{
|
||||
class Actor;
|
||||
class Object;
|
||||
|
||||
// An object to attach as user data to the osg::Node, allows us to get an Object back from a Node when we are doing a ray query
|
||||
|
@ -98,6 +100,7 @@ namespace CSVRender
|
|||
osg::ref_ptr<osg::Node> mMarker[3];
|
||||
int mSubMode;
|
||||
float mMarkerTransparency;
|
||||
std::unique_ptr<Actor> mActor;
|
||||
|
||||
/// Not implemented
|
||||
Object (const Object&);
|
||||
|
|
Loading…
Reference in a new issue