forked from mirror/openmw-tes3mp
Hide NIF loader details in the implementation file
This commit is contained in:
parent
d6dea31b88
commit
ff9e2b03a0
2 changed files with 944 additions and 960 deletions
|
@ -285,24 +285,6 @@ namespace
|
||||||
int mSourceIndex;
|
int mSourceIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
osg::ref_ptr<osg::Geometry> handleMorphGeometry(const Nif::NiGeomMorpherController* morpher)
|
|
||||||
{
|
|
||||||
osg::ref_ptr<osgAnimation::MorphGeometry> morphGeom = new osgAnimation::MorphGeometry;
|
|
||||||
morphGeom->setMethod(osgAnimation::MorphGeometry::RELATIVE);
|
|
||||||
// No normals available in the MorphData
|
|
||||||
morphGeom->setMorphNormals(false);
|
|
||||||
|
|
||||||
const std::vector<Nif::NiMorphData::MorphData>& morphs = morpher->data.getPtr()->mMorphs;
|
|
||||||
// Note we are not interested in morph 0, which just contains the original vertices
|
|
||||||
for (unsigned int i = 1; i < morphs.size(); ++i)
|
|
||||||
{
|
|
||||||
osg::ref_ptr<osg::Geometry> morphTarget = new osg::Geometry;
|
|
||||||
morphTarget->setVertexArray(new osg::Vec3Array(morphs[i].mVertices.size(), &morphs[i].mVertices[0]));
|
|
||||||
morphGeom->addMorphTarget(morphTarget, 0.f);
|
|
||||||
}
|
|
||||||
return morphGeom;
|
|
||||||
}
|
|
||||||
|
|
||||||
void extractTextKeys(const Nif::NiTextKeyExtraData *tk, NifOsg::TextKeyMap &textkeys)
|
void extractTextKeys(const Nif::NiTextKeyExtraData *tk, NifOsg::TextKeyMap &textkeys)
|
||||||
{
|
{
|
||||||
for(size_t i = 0;i < tk->list.size();i++)
|
for(size_t i = 0;i < tk->list.size();i++)
|
||||||
|
@ -352,7 +334,19 @@ namespace NifOsg
|
||||||
sShowMarkers = show;
|
sShowMarkers = show;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Loader::loadKf(Nif::NIFFilePtr nif, osg::Node *rootNode, int sourceIndex, TextKeyMap& textKeys)
|
class LoaderImpl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
const VFS::Manager* mResourceManager;
|
||||||
|
bool mShowMarkers;
|
||||||
|
|
||||||
|
LoaderImpl(const VFS::Manager* resourceManager, bool showMarkers)
|
||||||
|
: mResourceManager(resourceManager)
|
||||||
|
, mShowMarkers(showMarkers)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadKf(Nif::NIFFilePtr nif, osg::Node *rootNode, int sourceIndex, TextKeyMap& textKeys)
|
||||||
{
|
{
|
||||||
if(nif->numRoots() < 1)
|
if(nif->numRoots() < 1)
|
||||||
{
|
{
|
||||||
|
@ -409,10 +403,8 @@ namespace NifOsg
|
||||||
rootNode->accept(visitor);
|
rootNode->accept(visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Node* Loader::load(Nif::NIFFilePtr nif, osg::Group *parentNode, TextKeyMap* textKeys)
|
osg::Node* load(Nif::NIFFilePtr nif, osg::Group *parentNode, TextKeyMap* textKeys)
|
||||||
{
|
{
|
||||||
mNif = nif;
|
|
||||||
|
|
||||||
if (nif->numRoots() < 1)
|
if (nif->numRoots() < 1)
|
||||||
nif->fail("Found no root nodes");
|
nif->fail("Found no root nodes");
|
||||||
|
|
||||||
|
@ -422,16 +414,12 @@ namespace NifOsg
|
||||||
if (nifNode == NULL)
|
if (nifNode == NULL)
|
||||||
nif->fail("First root was not a node, but a " + r->recName);
|
nif->fail("First root was not a node, but a " + r->recName);
|
||||||
|
|
||||||
mRootNode = parentNode;
|
|
||||||
|
|
||||||
osg::Node* created = handleNode(nifNode, parentNode, false, std::map<int, int>(), 0, 0, false, textKeys);
|
osg::Node* created = handleNode(nifNode, parentNode, false, std::map<int, int>(), 0, 0, false, textKeys);
|
||||||
return created;
|
return created;
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Node* Loader::loadAsSkeleton(Nif::NIFFilePtr nif, osg::Group *parentNode, TextKeyMap* textKeys)
|
osg::Node* loadAsSkeleton(Nif::NIFFilePtr nif, osg::Group *parentNode, TextKeyMap* textKeys)
|
||||||
{
|
{
|
||||||
mNif = nif;
|
|
||||||
|
|
||||||
if (nif->numRoots() < 1)
|
if (nif->numRoots() < 1)
|
||||||
nif->fail("Found no root nodes");
|
nif->fail("Found no root nodes");
|
||||||
|
|
||||||
|
@ -445,14 +433,12 @@ namespace NifOsg
|
||||||
osg::ref_ptr<osgAnimation::Skeleton> skel = new osgAnimation::Skeleton;
|
osg::ref_ptr<osgAnimation::Skeleton> skel = new osgAnimation::Skeleton;
|
||||||
parentNode->addChild(skel);
|
parentNode->addChild(skel);
|
||||||
|
|
||||||
mRootNode = parentNode;
|
|
||||||
|
|
||||||
handleNode(nifNode, skel, true, std::map<int, int>(), 0, 0, false, textKeys);
|
handleNode(nifNode, skel, true, std::map<int, int>(), 0, 0, false, textKeys);
|
||||||
|
|
||||||
return skel;
|
return skel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Loader::applyNodeProperties(const Nif::Node *nifNode, osg::Node *applyTo, std::map<int, int>& boundTextures, int animflags)
|
void applyNodeProperties(const Nif::Node *nifNode, osg::Node *applyTo, std::map<int, int>& boundTextures, int animflags)
|
||||||
{
|
{
|
||||||
const Nif::PropertyList& props = nifNode->props;
|
const Nif::PropertyList& props = nifNode->props;
|
||||||
for (size_t i = 0; i <props.length();++i)
|
for (size_t i = 0; i <props.length();++i)
|
||||||
|
@ -462,7 +448,7 @@ namespace NifOsg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Loader::setupController(const Nif::Controller* ctrl, Controller* toSetup, int animflags)
|
void setupController(const Nif::Controller* ctrl, Controller* toSetup, int animflags)
|
||||||
{
|
{
|
||||||
//bool autoPlay = animflags & Nif::NiNode::AnimFlag_AutoPlay;
|
//bool autoPlay = animflags & Nif::NiNode::AnimFlag_AutoPlay;
|
||||||
//if (autoPlay)
|
//if (autoPlay)
|
||||||
|
@ -471,8 +457,9 @@ namespace NifOsg
|
||||||
toSetup->mFunction = boost::shared_ptr<ControllerFunction>(new ControllerFunction(ctrl, 1 /*autoPlay*/));
|
toSetup->mFunction = boost::shared_ptr<ControllerFunction>(new ControllerFunction(ctrl, 1 /*autoPlay*/));
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::Node* Loader::handleNode(const Nif::Node* nifNode, osg::Group* parentNode, bool createSkeleton,
|
|
||||||
std::map<int, int> boundTextures, int animflags, int particleflags, bool skipMeshes, TextKeyMap* textKeys)
|
osg::Node* handleNode(const Nif::Node* nifNode, osg::Group* parentNode, bool createSkeleton,
|
||||||
|
std::map<int, int> boundTextures, int animflags, int particleflags, bool skipMeshes, TextKeyMap* textKeys, osg::Node* rootNode=NULL)
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osg::MatrixTransform> transformNode;
|
osg::ref_ptr<osg::MatrixTransform> transformNode;
|
||||||
if (nifNode->recType == Nif::RC_NiBillboardNode)
|
if (nifNode->recType == Nif::RC_NiBillboardNode)
|
||||||
|
@ -491,6 +478,10 @@ namespace NifOsg
|
||||||
{
|
{
|
||||||
transformNode = new osg::MatrixTransform(toMatrix(nifNode->trafo));
|
transformNode = new osg::MatrixTransform(toMatrix(nifNode->trafo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!rootNode)
|
||||||
|
rootNode = transformNode;
|
||||||
|
|
||||||
// Ignoring name for non-bone nodes for now. We might need it later in isolated cases, e.g. AttachLight.
|
// Ignoring name for non-bone nodes for now. We might need it later in isolated cases, e.g. AttachLight.
|
||||||
|
|
||||||
// Insert bones at position 0 to prevent update order problems (see comment in osg Skeleton.cpp)
|
// Insert bones at position 0 to prevent update order problems (see comment in osg Skeleton.cpp)
|
||||||
|
@ -518,7 +509,7 @@ namespace NifOsg
|
||||||
// String markers may contain important information
|
// String markers may contain important information
|
||||||
// affecting the entire subtree of this obj
|
// affecting the entire subtree of this obj
|
||||||
// TODO: implement show markers flag
|
// TODO: implement show markers flag
|
||||||
if(sd->string == "MRK" && !sShowMarkers)
|
if(sd->string == "MRK" && !mShowMarkers)
|
||||||
{
|
{
|
||||||
// Marker objects. These meshes are only visible in the editor.
|
// Marker objects. These meshes are only visible in the editor.
|
||||||
skipMeshes = true;
|
skipMeshes = true;
|
||||||
|
@ -560,7 +551,7 @@ namespace NifOsg
|
||||||
}
|
}
|
||||||
|
|
||||||
if(nifNode->recType == Nif::RC_NiAutoNormalParticles || nifNode->recType == Nif::RC_NiRotatingParticles)
|
if(nifNode->recType == Nif::RC_NiAutoNormalParticles || nifNode->recType == Nif::RC_NiRotatingParticles)
|
||||||
handleParticleSystem(nifNode, transformNode, animflags, particleflags);
|
handleParticleSystem(nifNode, transformNode, animflags, particleflags, rootNode);
|
||||||
|
|
||||||
if (!nifNode->controller.empty())
|
if (!nifNode->controller.empty())
|
||||||
handleNodeControllers(nifNode, transformNode, animflags);
|
handleNodeControllers(nifNode, transformNode, animflags);
|
||||||
|
@ -576,14 +567,14 @@ namespace NifOsg
|
||||||
for(size_t i = 0;i < children.length();++i)
|
for(size_t i = 0;i < children.length();++i)
|
||||||
{
|
{
|
||||||
if(!children[i].empty())
|
if(!children[i].empty())
|
||||||
handleNode(children[i].getPtr(), transformNode, createSkeleton, boundTextures, animflags, particleflags, skipMeshes, textKeys);
|
handleNode(children[i].getPtr(), transformNode, createSkeleton, boundTextures, animflags, particleflags, skipMeshes, textKeys, rootNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return transformNode;
|
return transformNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Loader::handleMeshControllers(const Nif::Node *nifNode, osg::MatrixTransform *transformNode, const std::map<int, int> &boundTextures, int animflags)
|
void handleMeshControllers(const Nif::Node *nifNode, osg::MatrixTransform *transformNode, const std::map<int, int> &boundTextures, int animflags)
|
||||||
{
|
{
|
||||||
for (Nif::ControllerPtr ctrl = nifNode->controller; !ctrl.empty(); ctrl = ctrl->next)
|
for (Nif::ControllerPtr ctrl = nifNode->controller; !ctrl.empty(); ctrl = ctrl->next)
|
||||||
{
|
{
|
||||||
|
@ -605,7 +596,7 @@ namespace NifOsg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Loader::handleNodeControllers(const Nif::Node* nifNode, osg::MatrixTransform* transformNode, int animflags)
|
void handleNodeControllers(const Nif::Node* nifNode, osg::MatrixTransform* transformNode, int animflags)
|
||||||
{
|
{
|
||||||
for (Nif::ControllerPtr ctrl = nifNode->controller; !ctrl.empty(); ctrl = ctrl->next)
|
for (Nif::ControllerPtr ctrl = nifNode->controller; !ctrl.empty(); ctrl = ctrl->next)
|
||||||
{
|
{
|
||||||
|
@ -633,7 +624,8 @@ namespace NifOsg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Loader::handleMaterialControllers(const Nif::Property *materialProperty, osg::Node* node, osg::StateSet *stateset, int animflags)
|
|
||||||
|
void handleMaterialControllers(const Nif::Property *materialProperty, osg::Node* node, osg::StateSet *stateset, int animflags)
|
||||||
{
|
{
|
||||||
for (Nif::ControllerPtr ctrl = materialProperty->controller; !ctrl.empty(); ctrl = ctrl->next)
|
for (Nif::ControllerPtr ctrl = materialProperty->controller; !ctrl.empty(); ctrl = ctrl->next)
|
||||||
{
|
{
|
||||||
|
@ -660,7 +652,8 @@ namespace NifOsg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Loader::handleTextureControllers(const Nif::Property *texProperty, osg::Node* node, osg::StateSet *stateset, int animflags)
|
|
||||||
|
void handleTextureControllers(const Nif::Property *texProperty, osg::Node* node, osg::StateSet *stateset, int animflags)
|
||||||
{
|
{
|
||||||
for (Nif::ControllerPtr ctrl = texProperty->controller; !ctrl.empty(); ctrl = ctrl->next)
|
for (Nif::ControllerPtr ctrl = texProperty->controller; !ctrl.empty(); ctrl = ctrl->next)
|
||||||
{
|
{
|
||||||
|
@ -676,13 +669,14 @@ namespace NifOsg
|
||||||
if (st.empty())
|
if (st.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::string filename = Misc::ResourceHelpers::correctTexturePath(st->filename, resourceManager);
|
std::string filename = Misc::ResourceHelpers::correctTexturePath(st->filename, mResourceManager);
|
||||||
|
|
||||||
|
// TODO: replace with texture manager
|
||||||
// tx_creature_werewolf.dds isn't loading in the correct format without this option
|
// tx_creature_werewolf.dds isn't loading in the correct format without this option
|
||||||
osgDB::Options* opts = new osgDB::Options;
|
osgDB::Options* opts = new osgDB::Options;
|
||||||
opts->setOptionString("dds_dxt1_detect_rgba");
|
opts->setOptionString("dds_dxt1_detect_rgba");
|
||||||
osgDB::ReaderWriter* reader = osgDB::Registry::instance()->getReaderWriterForExtension("dds");
|
osgDB::ReaderWriter* reader = osgDB::Registry::instance()->getReaderWriterForExtension("dds");
|
||||||
osgDB::ReaderWriter::ReadResult result = reader->readImage(*resourceManager->get(filename.c_str()), opts);
|
osgDB::ReaderWriter::ReadResult result = reader->readImage(*mResourceManager->get(filename.c_str()), opts);
|
||||||
textures.push_back(osg::ref_ptr<osg::Image>(result.getImage()));
|
textures.push_back(osg::ref_ptr<osg::Image>(result.getImage()));
|
||||||
}
|
}
|
||||||
osg::ref_ptr<FlipController> callback(new FlipController(flipctrl, textures));
|
osg::ref_ptr<FlipController> callback(new FlipController(flipctrl, textures));
|
||||||
|
@ -695,7 +689,44 @@ namespace NifOsg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Loader::handleParticleSystem(const Nif::Node *nifNode, osg::Group *parentNode, int animflags, int particleflags)
|
void handleParticleAffectors(Nif::ExtraPtr e, osg::Group *attachTo, osgParticle::ParticleSystem* partsys, osgParticle::ParticleProcessor::ReferenceFrame rf)
|
||||||
|
{
|
||||||
|
osgParticle::ModularProgram* program = new osgParticle::ModularProgram;
|
||||||
|
attachTo->addChild(program);
|
||||||
|
program->setParticleSystem(partsys);
|
||||||
|
program->setReferenceFrame(rf);
|
||||||
|
for (; !e.empty(); e = e->extra)
|
||||||
|
{
|
||||||
|
if (e->recType == Nif::RC_NiParticleGrowFade)
|
||||||
|
{
|
||||||
|
const Nif::NiParticleGrowFade *gf = static_cast<const Nif::NiParticleGrowFade*>(e.getPtr());
|
||||||
|
GrowFadeAffector* affector = new GrowFadeAffector(gf->growTime, gf->fadeTime);
|
||||||
|
program->addOperator(affector);
|
||||||
|
}
|
||||||
|
else if (e->recType == Nif::RC_NiGravity)
|
||||||
|
{
|
||||||
|
const Nif::NiGravity* gr = static_cast<const Nif::NiGravity*>(e.getPtr());
|
||||||
|
GravityAffector* affector = new GravityAffector(gr);
|
||||||
|
program->addOperator(affector);
|
||||||
|
}
|
||||||
|
else if (e->recType == Nif::RC_NiParticleColorModifier)
|
||||||
|
{
|
||||||
|
const Nif::NiParticleColorModifier *cl = static_cast<const Nif::NiParticleColorModifier*>(e.getPtr());
|
||||||
|
const Nif::NiColorData *clrdata = cl->data.getPtr();
|
||||||
|
ParticleColorAffector* affector = new ParticleColorAffector(clrdata);
|
||||||
|
program->addOperator(affector);
|
||||||
|
}
|
||||||
|
else if (e->recType == Nif::RC_NiParticleRotation)
|
||||||
|
{
|
||||||
|
// TODO: Implement?
|
||||||
|
}
|
||||||
|
else
|
||||||
|
std::cerr << "Unhandled particle modifier " << e->recName << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void handleParticleSystem(const Nif::Node *nifNode, osg::Group *parentNode, int animflags, int particleflags, osg::Node* rootNode)
|
||||||
{
|
{
|
||||||
osg::ref_ptr<ParticleSystem> partsys (new ParticleSystem);
|
osg::ref_ptr<ParticleSystem> partsys (new ParticleSystem);
|
||||||
partsys->setSortMode(osgParticle::ParticleSystem::SORT_BACK_TO_FRONT);
|
partsys->setSortMode(osgParticle::ParticleSystem::SORT_BACK_TO_FRONT);
|
||||||
|
@ -800,7 +831,7 @@ namespace NifOsg
|
||||||
|
|
||||||
// Creating emitters will need to be changed when cloning a scenegraph is implemented, the particleSystem pointer would become invalid
|
// Creating emitters will need to be changed when cloning a scenegraph is implemented, the particleSystem pointer would become invalid
|
||||||
FindRecIndexVisitor find (partctrl->emitter->recIndex);
|
FindRecIndexVisitor find (partctrl->emitter->recIndex);
|
||||||
mRootNode->accept(find);
|
rootNode->accept(find);
|
||||||
if (!find.mFound)
|
if (!find.mFound)
|
||||||
{
|
{
|
||||||
std::cerr << "can't find emitter node, wrong node order?" << std::endl;
|
std::cerr << "can't find emitter node, wrong node order?" << std::endl;
|
||||||
|
@ -816,41 +847,8 @@ namespace NifOsg
|
||||||
setupController(partctrl, callback, animflags);
|
setupController(partctrl, callback, animflags);
|
||||||
emitter->setUpdateCallback(callback);
|
emitter->setUpdateCallback(callback);
|
||||||
|
|
||||||
// ----------- affector (must be after emitters in the scene graph)
|
// affectors must be attached *after* the emitter in the scene graph for correct update order
|
||||||
osgParticle::ModularProgram* program = new osgParticle::ModularProgram;
|
handleParticleAffectors(partctrl->extra, emitterNode, partsys.get(), rf);
|
||||||
program->setParticleSystem(partsys);
|
|
||||||
program->setReferenceFrame(rf);
|
|
||||||
emitterNode->addChild(program);
|
|
||||||
for (Nif::ExtraPtr e = partctrl->extra; !e.empty(); e = e->extra)
|
|
||||||
{
|
|
||||||
if (e->recType == Nif::RC_NiParticleGrowFade)
|
|
||||||
{
|
|
||||||
const Nif::NiParticleGrowFade *gf = static_cast<const Nif::NiParticleGrowFade*>(e.getPtr());
|
|
||||||
GrowFadeAffector* affector = new GrowFadeAffector(gf->growTime, gf->fadeTime);
|
|
||||||
program->addOperator(affector);
|
|
||||||
}
|
|
||||||
else if (e->recType == Nif::RC_NiGravity)
|
|
||||||
{
|
|
||||||
const Nif::NiGravity* gr = static_cast<const Nif::NiGravity*>(e.getPtr());
|
|
||||||
GravityAffector* affector = new GravityAffector(gr);
|
|
||||||
program->addOperator(affector);
|
|
||||||
}
|
|
||||||
else if (e->recType == Nif::RC_NiParticleColorModifier)
|
|
||||||
{
|
|
||||||
const Nif::NiParticleColorModifier *cl = static_cast<const Nif::NiParticleColorModifier*>(e.getPtr());
|
|
||||||
const Nif::NiColorData *clrdata = cl->data.getPtr();
|
|
||||||
ParticleColorAffector* affector = new ParticleColorAffector(clrdata);
|
|
||||||
program->addOperator(affector);
|
|
||||||
}
|
|
||||||
else if (e->recType == Nif::RC_NiParticleRotation)
|
|
||||||
{
|
|
||||||
// TODO: Implement?
|
|
||||||
}
|
|
||||||
else
|
|
||||||
std::cerr << "Unhandled particle modifier " << e->recName << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------
|
|
||||||
|
|
||||||
osg::ref_ptr<osg::Geode> geode (new osg::Geode);
|
osg::ref_ptr<osg::Geode> geode (new osg::Geode);
|
||||||
geode->addDrawable(partsys);
|
geode->addDrawable(partsys);
|
||||||
|
@ -879,7 +877,7 @@ namespace NifOsg
|
||||||
parentNode->addChild(updater);
|
parentNode->addChild(updater);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Loader::triShapeToGeometry(const Nif::NiTriShape *triShape, osg::Geometry *geometry, osg::Geode* parentGeode, const std::map<int, int>& boundTextures, int animflags)
|
void triShapeToGeometry(const Nif::NiTriShape *triShape, osg::Geometry *geometry, osg::Geode* parentGeode, const std::map<int, int>& boundTextures, int animflags)
|
||||||
{
|
{
|
||||||
const Nif::NiTriShapeData* data = triShape->data.getPtr();
|
const Nif::NiTriShapeData* data = triShape->data.getPtr();
|
||||||
|
|
||||||
|
@ -962,7 +960,7 @@ namespace NifOsg
|
||||||
applyMaterialProperties(parentGeode, materialProps, !data->colors.empty(), animflags);
|
applyMaterialProperties(parentGeode, materialProps, !data->colors.empty(), animflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Loader::handleTriShape(const Nif::NiTriShape* triShape, osg::Group* parentNode, const std::map<int, int>& boundTextures, int animflags)
|
void handleTriShape(const Nif::NiTriShape* triShape, osg::Group* parentNode, const std::map<int, int>& boundTextures, int animflags)
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osg::Geometry> geometry;
|
osg::ref_ptr<osg::Geometry> geometry;
|
||||||
if(!triShape->controller.empty())
|
if(!triShape->controller.empty())
|
||||||
|
@ -994,7 +992,25 @@ namespace NifOsg
|
||||||
parentNode->addChild(geode);
|
parentNode->addChild(geode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Loader::handleSkinnedTriShape(const Nif::NiTriShape *triShape, osg::Group *parentNode, const std::map<int, int>& boundTextures, int animflags)
|
osg::ref_ptr<osg::Geometry> handleMorphGeometry(const Nif::NiGeomMorpherController* morpher)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osgAnimation::MorphGeometry> morphGeom = new osgAnimation::MorphGeometry;
|
||||||
|
morphGeom->setMethod(osgAnimation::MorphGeometry::RELATIVE);
|
||||||
|
// No normals available in the MorphData
|
||||||
|
morphGeom->setMorphNormals(false);
|
||||||
|
|
||||||
|
const std::vector<Nif::NiMorphData::MorphData>& morphs = morpher->data.getPtr()->mMorphs;
|
||||||
|
// Note we are not interested in morph 0, which just contains the original vertices
|
||||||
|
for (unsigned int i = 1; i < morphs.size(); ++i)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<osg::Geometry> morphTarget = new osg::Geometry;
|
||||||
|
morphTarget->setVertexArray(new osg::Vec3Array(morphs[i].mVertices.size(), &morphs[i].mVertices[0]));
|
||||||
|
morphGeom->addMorphTarget(morphTarget, 0.f);
|
||||||
|
}
|
||||||
|
return morphGeom;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleSkinnedTriShape(const Nif::NiTriShape *triShape, osg::Group *parentNode, const std::map<int, int>& boundTextures, int animflags)
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osg::Geode> geode (new osg::Geode);
|
osg::ref_ptr<osg::Geode> geode (new osg::Geode);
|
||||||
geode->setName(triShape->name); // name will be used for part filtering
|
geode->setName(triShape->name); // name will be used for part filtering
|
||||||
|
@ -1045,7 +1061,8 @@ namespace NifOsg
|
||||||
parentNode->addChild(trans);
|
parentNode->addChild(trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Loader::handleProperty(const Nif::Property *property, const Nif::Node* nifNode,
|
|
||||||
|
void handleProperty(const Nif::Property *property, const Nif::Node* nifNode,
|
||||||
osg::Node *node, std::map<int, int>& boundTextures, int animflags)
|
osg::Node *node, std::map<int, int>& boundTextures, int animflags)
|
||||||
{
|
{
|
||||||
osg::StateSet* stateset = node->getOrCreateStateSet();
|
osg::StateSet* stateset = node->getOrCreateStateSet();
|
||||||
|
@ -1171,13 +1188,14 @@ namespace NifOsg
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string filename = Misc::ResourceHelpers::correctTexturePath(st->filename, resourceManager);
|
std::string filename = Misc::ResourceHelpers::correctTexturePath(st->filename, mResourceManager);
|
||||||
|
|
||||||
|
// TODO: replace with texture manager
|
||||||
// tx_creature_werewolf.dds isn't loading in the correct format without this option
|
// tx_creature_werewolf.dds isn't loading in the correct format without this option
|
||||||
osgDB::Options* opts = new osgDB::Options;
|
osgDB::Options* opts = new osgDB::Options;
|
||||||
opts->setOptionString("dds_dxt1_detect_rgba");
|
opts->setOptionString("dds_dxt1_detect_rgba");
|
||||||
osgDB::ReaderWriter* reader = osgDB::Registry::instance()->getReaderWriterForExtension("dds");
|
osgDB::ReaderWriter* reader = osgDB::Registry::instance()->getReaderWriterForExtension("dds");
|
||||||
osgDB::ReaderWriter::ReadResult result = reader->readImage(*resourceManager->get(filename.c_str()), opts);
|
osgDB::ReaderWriter::ReadResult result = reader->readImage(*mResourceManager->get(filename.c_str()), opts);
|
||||||
osg::Image* image = result.getImage();
|
osg::Image* image = result.getImage();
|
||||||
osg::Texture2D* texture2d = new osg::Texture2D;
|
osg::Texture2D* texture2d = new osg::Texture2D;
|
||||||
texture2d->setUnRefImageDataAfterApply(true);
|
texture2d->setUnRefImageDataAfterApply(true);
|
||||||
|
@ -1246,7 +1264,7 @@ namespace NifOsg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Loader::applyMaterialProperties(osg::Node* node, const std::vector<const Nif::Property*>& properties,
|
void applyMaterialProperties(osg::Node* node, const std::vector<const Nif::Property*>& properties,
|
||||||
bool hasVertexColors, int animflags)
|
bool hasVertexColors, int animflags)
|
||||||
{
|
{
|
||||||
osg::StateSet* stateset = node->getOrCreateStateSet();
|
osg::StateSet* stateset = node->getOrCreateStateSet();
|
||||||
|
@ -1307,4 +1325,25 @@ namespace NifOsg
|
||||||
|
|
||||||
stateset->setAttributeAndModes(mat, osg::StateAttribute::ON);
|
stateset->setAttributeAndModes(mat, osg::StateAttribute::ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
osg::Node* Loader::load(Nif::NIFFilePtr file, osg::Group *parentNode, TextKeyMap *textKeys)
|
||||||
|
{
|
||||||
|
LoaderImpl loader(resourceManager, sShowMarkers);
|
||||||
|
return loader.load(file, parentNode, textKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
osg::Node* Loader::loadAsSkeleton(Nif::NIFFilePtr file, osg::Group *parentNode, TextKeyMap *textKeys)
|
||||||
|
{
|
||||||
|
LoaderImpl loader(resourceManager, sShowMarkers);
|
||||||
|
return loader.loadAsSkeleton(file, parentNode, textKeys);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Loader::loadKf(Nif::NIFFilePtr kf, osg::Node *rootNode, int sourceIndex, TextKeyMap &textKeys)
|
||||||
|
{
|
||||||
|
LoaderImpl loader(resourceManager, sShowMarkers);
|
||||||
|
loader.loadKf(kf, rootNode, sourceIndex, textKeys);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,24 +9,8 @@
|
||||||
|
|
||||||
namespace osg
|
namespace osg
|
||||||
{
|
{
|
||||||
class Geometry;
|
|
||||||
class Group;
|
class Group;
|
||||||
class Node;
|
class Node;
|
||||||
class MatrixTransform;
|
|
||||||
class StateSet;
|
|
||||||
class Geode;
|
|
||||||
}
|
|
||||||
namespace osgAnimation
|
|
||||||
{
|
|
||||||
class Bone;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Nif
|
|
||||||
{
|
|
||||||
class Node;
|
|
||||||
class NiTriShape;
|
|
||||||
class Property;
|
|
||||||
class Controller;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace NifOsg
|
namespace NifOsg
|
||||||
|
@ -62,45 +46,6 @@ namespace NifOsg
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
/// @param createSkeleton If true, use an osgAnimation::Bone for NIF nodes, otherwise an osg::MatrixTransform.
|
|
||||||
osg::Node* handleNode(const Nif::Node* nifNode, osg::Group* parentNode, bool createSkeleton,
|
|
||||||
std::map<int, int> boundTextures, int animflags, int particleflags, bool skipMeshes, TextKeyMap* textKeys);
|
|
||||||
|
|
||||||
void handleMeshControllers(const Nif::Node* nifNode, osg::MatrixTransform* transformNode, const std::map<int, int>& boundTextures, int animflags);
|
|
||||||
|
|
||||||
void handleNodeControllers(const Nif::Node* nifNode, osg::MatrixTransform* transformNode, int animflags);
|
|
||||||
|
|
||||||
void handleMaterialControllers(const Nif::Property* materialProperty, osg::Node* node, osg::StateSet* stateset, int animflags);
|
|
||||||
|
|
||||||
void handleTextureControllers(const Nif::Property* texProperty, osg::Node* node, osg::StateSet* stateset, int animflags);
|
|
||||||
|
|
||||||
void handleProperty (const Nif::Property* property, const Nif::Node* nifNode,
|
|
||||||
osg::Node* node, std::map<int, int>& boundTextures, int animflags);
|
|
||||||
|
|
||||||
void handleParticleSystem(const Nif::Node* nifNode, osg::Group* parentNode, int animflags, int particleflags);
|
|
||||||
|
|
||||||
// Creates an osg::Geometry object for the given TriShape, populates it, and attaches it to the given node.
|
|
||||||
void handleTriShape(const Nif::NiTriShape* triShape, osg::Group* parentNode, const std::map<int, int>& boundTextures, int animflags);
|
|
||||||
|
|
||||||
// Fills the vertex data for the given TriShape into the given Geometry.
|
|
||||||
void triShapeToGeometry(const Nif::NiTriShape* triShape, osg::Geometry* geom, osg::Geode* parentGeode, const std::map<int, int>& boundTextures, int animflags);
|
|
||||||
|
|
||||||
// Creates a skinned osg::Geometry object for the given TriShape, populates it, and attaches it to the given node.
|
|
||||||
void handleSkinnedTriShape(const Nif::NiTriShape* triShape, osg::Group* parentNode, const std::map<int, int>& boundTextures, int animflags);
|
|
||||||
|
|
||||||
// Applies the Properties of the given nifNode onto the StateSet of the given OSG node.
|
|
||||||
void applyNodeProperties(const Nif::Node* nifNode, osg::Node* applyTo, std::map<int, int>& boundTextures, int animflags);
|
|
||||||
|
|
||||||
void applyMaterialProperties(osg::Node* node, const std::vector<const Nif::Property*>& properties,
|
|
||||||
bool hasVertexColors, int animflags);
|
|
||||||
|
|
||||||
// Set up the default input and controller function for the given controller.
|
|
||||||
void setupController(const Nif::Controller* ctrl, Controller* toSetup, int animflags);
|
|
||||||
|
|
||||||
Nif::NIFFilePtr mNif;
|
|
||||||
|
|
||||||
osg::Group* mRootNode;
|
|
||||||
|
|
||||||
static bool sShowMarkers;
|
static bool sShowMarkers;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue