mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-30 09:36:43 +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
|
scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget
|
||||||
previewwidget editmode instancemode instanceselectionmode instancemovemode
|
previewwidget editmode instancemode instanceselectionmode instancemovemode
|
||||||
orbitcameramode pathgridmode selectionmode pathgridselectionmode cameracontroller
|
orbitcameramode pathgridmode selectionmode pathgridselectionmode cameracontroller
|
||||||
cellwater terraintexturemode
|
cellwater terraintexturemode actor
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_units_noqt (view/render
|
opencs_units_noqt (view/render
|
||||||
lighting lightingday lightingnight lightingbright object cell terrainstorage tagbase
|
lighting lightingday lightingnight lightingbright object cell terrainstorage tagbase
|
||||||
cellarrow cellmarker cellborder pathgrid actor
|
cellarrow cellmarker cellborder pathgrid
|
||||||
)
|
)
|
||||||
|
|
||||||
opencs_hdrs_noqt (view/render
|
opencs_hdrs_noqt (view/render
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#include "actoradapter.hpp"
|
#include "actoradapter.hpp"
|
||||||
|
|
||||||
#include <iostream>
|
#include <components/debug/debuglog.hpp>
|
||||||
|
|
||||||
#include <components/esm/loadarmo.hpp>
|
#include <components/esm/loadarmo.hpp>
|
||||||
#include <components/esm/loadclot.hpp>
|
#include <components/esm/loadclot.hpp>
|
||||||
#include <components/esm/loadnpc.hpp>
|
#include <components/esm/loadnpc.hpp>
|
||||||
|
@ -45,17 +44,56 @@ namespace CSMWorld
|
||||||
|
|
||||||
void ActorAdapter::handleReferenceableChanged(const QModelIndex& topLeft, const QModelIndex& botRight)
|
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)
|
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)
|
void ActorAdapter::handleBodyPartChanged(const QModelIndex& topLeft, const QModelIndex& botRight)
|
||||||
{
|
{
|
||||||
// TODO
|
// 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)
|
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);
|
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;
|
mActorPartMaps[refId] = npcMap;
|
||||||
|
emit actorChanged(refId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActorAdapter::updateCreature(const std::string& 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:
|
private:
|
||||||
|
|
||||||
|
ActorAdapter(const ActorAdapter&) = delete;
|
||||||
|
ActorAdapter& operator=(const ActorAdapter&) = delete;
|
||||||
|
|
||||||
|
QModelIndex getHighestIndex(QModelIndex) const;
|
||||||
|
|
||||||
RacePartMap& getOrCreateRacePartMap(const std::string& raceId, bool isFemale);
|
RacePartMap& getOrCreateRacePartMap(const std::string& raceId, bool isFemale);
|
||||||
|
|
||||||
void updateRaceParts(const std::string& raceId);
|
void updateRaceParts(const std::string& raceId);
|
||||||
|
@ -67,6 +72,8 @@ namespace CSMWorld
|
||||||
void updateNpc(const std::string& refId);
|
void updateNpc(const std::string& refId);
|
||||||
void updateCreature(const std::string& refId);
|
void updateCreature(const std::string& refId);
|
||||||
|
|
||||||
|
void updateNpcsWithRace(const std::string& raceId);
|
||||||
|
|
||||||
RefIdCollection& mReferenceables;
|
RefIdCollection& mReferenceables;
|
||||||
IdCollection<ESM::Race>& mRaces;
|
IdCollection<ESM::Race>& mRaces;
|
||||||
IdCollection<ESM::BodyPart>& mBodyParts;
|
IdCollection<ESM::BodyPart>& mBodyParts;
|
||||||
|
|
|
@ -20,6 +20,7 @@ namespace CSVRender
|
||||||
|
|
||||||
Actor::Actor(const std::string& id, int type, CSMWorld::Data& data)
|
Actor::Actor(const std::string& id, int type, CSMWorld::Data& data)
|
||||||
: mId(id)
|
: mId(id)
|
||||||
|
, mInitialized(false)
|
||||||
, mType(type)
|
, mType(type)
|
||||||
, mData(data)
|
, mData(data)
|
||||||
, mBaseNode(new osg::Group())
|
, mBaseNode(new osg::Group())
|
||||||
|
@ -45,7 +46,22 @@ namespace CSVRender
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
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 <osg/ref_ptr>
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
#include <components/esm/loadarmo.hpp>
|
#include <components/esm/loadarmo.hpp>
|
||||||
#include <components/sceneutil/visitor.hpp>
|
#include <components/sceneutil/visitor.hpp>
|
||||||
|
|
||||||
|
@ -26,8 +28,9 @@ namespace SceneUtil
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
{
|
{
|
||||||
/// Handles loading an npc or creature
|
/// Handles loading an npc or creature
|
||||||
class Actor
|
class Actor : public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
/// Creates an actor.
|
/// Creates an actor.
|
||||||
/// \param id The referenceable id
|
/// \param id The referenceable id
|
||||||
|
@ -41,6 +44,9 @@ namespace CSVRender
|
||||||
/// (Re)creates the npc or creature renderable
|
/// (Re)creates the npc or creature renderable
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleActorChanged(const std::string& refId);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void updateCreature();
|
void updateCreature();
|
||||||
void updateNpc();
|
void updateNpc();
|
||||||
|
@ -54,6 +60,7 @@ namespace CSVRender
|
||||||
static const std::string MeshPrefix;
|
static const std::string MeshPrefix;
|
||||||
|
|
||||||
std::string mId;
|
std::string mId;
|
||||||
|
bool mInitialized;
|
||||||
int mType;
|
int mType;
|
||||||
CSMWorld::Data& mData;
|
CSMWorld::Data& mData;
|
||||||
|
|
||||||
|
|
|
@ -134,9 +134,10 @@ void CSVRender::Object::update()
|
||||||
{
|
{
|
||||||
if (recordType == CSMWorld::UniversalId::Type_Npc || recordType == CSMWorld::UniversalId::Type_Creature)
|
if (recordType == CSMWorld::UniversalId::Type_Npc || recordType == CSMWorld::UniversalId::Type_Creature)
|
||||||
{
|
{
|
||||||
Actor actor(mReferenceableId, recordType, mData);
|
if (!mActor)
|
||||||
actor.update();
|
mActor.reset(new Actor(mReferenceableId, recordType, mData));
|
||||||
mBaseNode->addChild(actor.getBaseNode());
|
mActor->update();
|
||||||
|
mBaseNode->addChild(mActor->getBaseNode());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef OPENCS_VIEW_OBJECT_H
|
#ifndef OPENCS_VIEW_OBJECT_H
|
||||||
#define OPENCS_VIEW_OBJECT_H
|
#define OPENCS_VIEW_OBJECT_H
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include <osg/ref_ptr>
|
#include <osg/ref_ptr>
|
||||||
|
@ -41,6 +42,7 @@ namespace CSMWorld
|
||||||
|
|
||||||
namespace CSVRender
|
namespace CSVRender
|
||||||
{
|
{
|
||||||
|
class Actor;
|
||||||
class Object;
|
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
|
// 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];
|
osg::ref_ptr<osg::Node> mMarker[3];
|
||||||
int mSubMode;
|
int mSubMode;
|
||||||
float mMarkerTransparency;
|
float mMarkerTransparency;
|
||||||
|
std::unique_ptr<Actor> mActor;
|
||||||
|
|
||||||
/// Not implemented
|
/// Not implemented
|
||||||
Object (const Object&);
|
Object (const Object&);
|
||||||
|
|
Loading…
Reference in a new issue