mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-21 10:09:39 +00:00
Handle creatures too
This commit is contained in:
parent
e2ac392a40
commit
6b42f37918
3 changed files with 167 additions and 130 deletions
|
@ -18,6 +18,8 @@
|
|||
|
||||
namespace CSVRender
|
||||
{
|
||||
const std::string Actor::MeshPrefix = "meshes\\";
|
||||
|
||||
Actor::Actor(const std::string& id, int type, CSMWorld::Data& data)
|
||||
: mId(id)
|
||||
, mType(type)
|
||||
|
@ -34,7 +36,42 @@ namespace CSVRender
|
|||
|
||||
void Actor::update()
|
||||
{
|
||||
const std::string MeshPrefix = "meshes\\";
|
||||
try
|
||||
{
|
||||
mBaseNode->removeChildren(0, mBaseNode->getNumChildren());
|
||||
|
||||
if (mType == CSMWorld::UniversalId::Type_Npc)
|
||||
updateNpc();
|
||||
else if (mType == CSMWorld::UniversalId::Type_Creature)
|
||||
updateCreature();
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "Caught exception: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void Actor::updateCreature()
|
||||
{
|
||||
auto& referenceables = mData.getReferenceables();
|
||||
|
||||
auto& creature = dynamic_cast<const CSMWorld::Record<ESM::Creature>& >(referenceables.getRecord(mId)).get();
|
||||
|
||||
std::string skeletonModel = MeshPrefix + creature.mModel;
|
||||
skeletonModel = Misc::ResourceHelpers::correctActorModelPath(skeletonModel, mData.getResourceSystem()->getVFS());
|
||||
loadSkeleton(skeletonModel);
|
||||
|
||||
SceneUtil::RemoveTriBipVisitor removeTriBipVisitor;
|
||||
mSkeleton->accept(removeTriBipVisitor);
|
||||
removeTriBipVisitor.remove();
|
||||
|
||||
// Post setup
|
||||
mSkeleton->markDirty();
|
||||
mSkeleton->setActive(SceneUtil::Skeleton::Active);
|
||||
}
|
||||
|
||||
void Actor::updateNpc()
|
||||
{
|
||||
const unsigned int FemaleFlag = ESM::BodyPart::BPF_Female;
|
||||
|
||||
auto& bodyParts = mData.getBodyParts();
|
||||
|
@ -42,15 +79,6 @@ namespace CSVRender
|
|||
auto& referenceables = mData.getReferenceables();
|
||||
auto sceneMgr = mData.getResourceSystem()->getSceneManager();
|
||||
|
||||
|
||||
// Remove children
|
||||
mBaseNode->removeChildren(0, mBaseNode->getNumChildren());
|
||||
|
||||
try
|
||||
{
|
||||
// Npcs and creatures are handled differently
|
||||
if (mType == CSMWorld::UniversalId::Type_Npc)
|
||||
{
|
||||
auto& npc = dynamic_cast<const CSMWorld::Record<ESM::NPC>& >(referenceables.getRecord(mId)).get();
|
||||
auto& race = dynamic_cast<const CSMWorld::Record<ESM::Race>& >(races.getRecord(npc.mRace)).get();
|
||||
|
||||
|
@ -62,36 +90,18 @@ namespace CSVRender
|
|||
// Load skeleton
|
||||
std::string skeletonModel = SceneUtil::getActorSkeleton(is1stPerson, isFemale, isBeast, isWerewolf);
|
||||
skeletonModel = Misc::ResourceHelpers::correctActorModelPath(skeletonModel, mData.getResourceSystem()->getVFS());
|
||||
{
|
||||
osg::ref_ptr<osg::Node> temp = sceneMgr->getInstance(skeletonModel);
|
||||
mSkeleton = dynamic_cast<SceneUtil::Skeleton*>(temp.get());
|
||||
if (!mSkeleton)
|
||||
{
|
||||
mSkeleton = new SceneUtil::Skeleton();
|
||||
mSkeleton->addChild(temp);
|
||||
}
|
||||
mBaseNode->addChild(mSkeleton);
|
||||
}
|
||||
loadSkeleton(skeletonModel);
|
||||
|
||||
// Get rid of the extra attachments
|
||||
SceneUtil::CleanObjectRootVisitor cleanVisitor;
|
||||
mSkeleton->accept(cleanVisitor);
|
||||
cleanVisitor.remove();
|
||||
|
||||
// Map bone names to bones
|
||||
SceneUtil::NodeMapVisitor::NodeMap nodeMap;
|
||||
SceneUtil::NodeMapVisitor nmVisitor(nodeMap);
|
||||
mSkeleton->accept(nmVisitor);
|
||||
|
||||
// Female mesh has some drawables attached, get rid of them
|
||||
SceneUtil::CleanObjectRootVisitor cleanVisitor;
|
||||
mSkeleton->accept(cleanVisitor);
|
||||
cleanVisitor.remove();
|
||||
|
||||
// Convenience method to retrieve the mesh name of a body part
|
||||
auto getBodyPartMesh = [&](std::string bpName) -> std::string {
|
||||
int index = bodyParts.searchId(bpName);
|
||||
if (index != -1 && !bodyParts.getRecord(index).isDeleted())
|
||||
return MeshPrefix + bodyParts.getRecord(index).get().mModel;
|
||||
else
|
||||
return "";
|
||||
};
|
||||
|
||||
using BPRaceKey = std::tuple<int, int, std::string>;
|
||||
using RaceToBPMap = std::map<BPRaceKey, std::string>;
|
||||
// Convenience method to generate a map from body part + race to mesh name
|
||||
|
@ -172,14 +182,34 @@ namespace CSVRender
|
|||
addBodyPart(part, "");
|
||||
}
|
||||
}
|
||||
|
||||
// Post setup
|
||||
mSkeleton->markDirty();
|
||||
mSkeleton->setActive(SceneUtil::Skeleton::Active);
|
||||
}
|
||||
}
|
||||
catch (std::exception& e)
|
||||
|
||||
void Actor::loadSkeleton(const std::string& model)
|
||||
{
|
||||
std::cout << "Caught exception: " << e.what() << std::endl;
|
||||
auto sceneMgr = mData.getResourceSystem()->getSceneManager();
|
||||
|
||||
osg::ref_ptr<osg::Node> temp = sceneMgr->getInstance(model);
|
||||
mSkeleton = dynamic_cast<SceneUtil::Skeleton*>(temp.get());
|
||||
if (!mSkeleton)
|
||||
{
|
||||
mSkeleton = new SceneUtil::Skeleton();
|
||||
mSkeleton->addChild(temp);
|
||||
}
|
||||
mBaseNode->addChild(mSkeleton);
|
||||
}
|
||||
|
||||
std::string Actor::getBodyPartMesh(const std::string& bodyPartId)
|
||||
{
|
||||
const auto& bodyParts = mData.getBodyParts();
|
||||
|
||||
int index = bodyParts.searchId(bodyPartId);
|
||||
if (index != -1 && !bodyParts.getRecord(index).isDeleted())
|
||||
return MeshPrefix + bodyParts.getRecord(index).get().mModel;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,6 +39,14 @@ namespace CSVRender
|
|||
void update();
|
||||
|
||||
private:
|
||||
void loadSkeleton(const std::string& model);
|
||||
void updateCreature();
|
||||
void updateNpc();
|
||||
|
||||
std::string getBodyPartMesh(const std::string& bodyPartId);
|
||||
|
||||
static const std::string MeshPrefix;
|
||||
|
||||
std::string mId;
|
||||
int mType;
|
||||
CSMWorld::Data& mData;
|
||||
|
|
|
@ -132,9 +132,8 @@ void CSVRender::Object::update()
|
|||
{
|
||||
try
|
||||
{
|
||||
if (recordType == CSMWorld::UniversalId::Type_Npc)
|
||||
if (recordType == CSMWorld::UniversalId::Type_Npc || recordType == CSMWorld::UniversalId::Type_Creature)
|
||||
{
|
||||
std::cout << "recordType: Npc\n";
|
||||
Actor actor(mReferenceableId, recordType, mData);
|
||||
actor.update();
|
||||
mBaseNode->addChild(actor.getBaseNode());
|
||||
|
@ -147,8 +146,8 @@ void CSVRender::Object::update()
|
|||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
// TODO: use error marker mesh
|
||||
Log(Debug::Error) << e.what();
|
||||
mBaseNode->addChild(createErrorCube());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue