1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-02-22 09:39:41 +00:00

Cleanup NIFObjectLoader some

This commit is contained in:
Chris Robinson 2013-04-14 00:06:40 -07:00
parent acb1b5f002
commit f4695ec4ac

View file

@ -331,9 +331,9 @@ public:
/** Manual resource loader for NIF objects (meshes, particle systems, etc). /** Object creator for NIFs. This is the main class responsible for creating
* This is the main class responsible for translating the internal NIF * "live" Ogre objects (entities, particle systems, controllers, etc) from
* structures into something Ogre can use. * their NIF equivalents.
*/ */
class NIFObjectLoader class NIFObjectLoader
{ {
@ -349,6 +349,57 @@ class NIFObjectLoader
} }
static void createEntity(const std::string &name, const std::string &group,
Ogre::SceneManager *sceneMgr, ObjectList &objectlist,
const Nif::Node *node, int flags, int animflags)
{
const Nif::NiTriShape *shape = static_cast<const Nif::NiTriShape*>(node);
std::string fullname = name+"@index="+Ogre::StringConverter::toString(shape->recIndex);
if(shape->name.length() > 0)
fullname += "@shape="+shape->name;
Misc::StringUtils::toLower(fullname);
Ogre::MeshManager &meshMgr = Ogre::MeshManager::getSingleton();
if(meshMgr.getByName(fullname).isNull())
NIFMeshLoader::createMesh(name, fullname, group, shape->recIndex);
Ogre::Entity *entity = sceneMgr->createEntity(fullname);
entity->setVisible(!(flags&0x01));
objectlist.mEntities.push_back(entity);
if(objectlist.mSkelBase)
{
if(entity->hasSkeleton())
entity->shareSkeletonInstanceWith(objectlist.mSkelBase);
else
{
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, shape->recIndex);
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
objectlist.mSkelBase->attachObjectToBone(trgtbone->getName(), entity);
}
}
Nif::ControllerPtr ctrl = node->controller;
while(!ctrl.empty())
{
if(ctrl->recType == Nif::RC_NiUVController)
{
const Nif::NiUVController *uv = static_cast<const Nif::NiUVController*>(ctrl.getPtr());
const Ogre::MaterialPtr &material = entity->getSubEntity(0)->getMaterial();
Ogre::ControllerValueRealPtr srcval((animflags&0x20) ? Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
Ogre::ControllerValueRealPtr());
Ogre::ControllerValueRealPtr dstval(OGRE_NEW UVController::Value(material, uv->data.getPtr()));
Ogre::ControllerFunctionRealPtr func(OGRE_NEW UVController::Function(uv, (animflags&0x20)));
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}
ctrl = ctrl->next;
}
}
static void createParticleEmitterAffectors(Ogre::ParticleSystem *partsys, const Nif::NiParticleSystemController *partctrl) static void createParticleEmitterAffectors(Ogre::ParticleSystem *partsys, const Nif::NiParticleSystemController *partctrl)
{ {
Ogre::ParticleEmitter *emitter = partsys->addEmitter("Nif"); Ogre::ParticleEmitter *emitter = partsys->addEmitter("Nif");
@ -416,9 +467,9 @@ class NIFObjectLoader
} }
} }
static Ogre::ParticleSystem *createParticleSystem(const std::string &name, const std::string &group, static void createParticleSystem(const std::string &name, const std::string &group,
Ogre::SceneManager *sceneMgr, Ogre::Entity *entitybase, Ogre::SceneManager *sceneMgr, ObjectList &objectlist,
const Nif::Node *partnode) const Nif::Node *partnode, int flags, int animflags)
{ {
const Nif::NiAutoNormalParticlesData *particledata = NULL; const Nif::NiAutoNormalParticlesData *particledata = NULL;
if(partnode->recType == Nif::RC_NiAutoNormalParticles) if(partnode->recType == Nif::RC_NiAutoNormalParticles)
@ -426,67 +477,63 @@ class NIFObjectLoader
else if(partnode->recType == Nif::RC_NiRotatingParticles) else if(partnode->recType == Nif::RC_NiRotatingParticles)
particledata = static_cast<const Nif::NiRotatingParticles*>(partnode)->data.getPtr(); particledata = static_cast<const Nif::NiRotatingParticles*>(partnode)->data.getPtr();
std::string fullname = name+"@index="+Ogre::StringConverter::toString(partnode->recIndex);
if(partnode->name.length() > 0)
fullname += "@type="+partnode->name;
Misc::StringUtils::toLower(fullname);
Ogre::ParticleSystem *partsys = sceneMgr->createParticleSystem(); Ogre::ParticleSystem *partsys = sceneMgr->createParticleSystem();
try {
std::string fullname = name+"@index="+Ogre::StringConverter::toString(partnode->recIndex);
if(partnode->name.length() > 0)
fullname += "@type="+partnode->name;
Misc::StringUtils::toLower(fullname);
const Nif::NiTexturingProperty *texprop = NULL; const Nif::NiTexturingProperty *texprop = NULL;
const Nif::NiMaterialProperty *matprop = NULL; const Nif::NiMaterialProperty *matprop = NULL;
const Nif::NiAlphaProperty *alphaprop = NULL; const Nif::NiAlphaProperty *alphaprop = NULL;
const Nif::NiVertexColorProperty *vertprop = NULL; const Nif::NiVertexColorProperty *vertprop = NULL;
const Nif::NiZBufferProperty *zprop = NULL; const Nif::NiZBufferProperty *zprop = NULL;
const Nif::NiSpecularProperty *specprop = NULL; const Nif::NiSpecularProperty *specprop = NULL;
const Nif::NiWireframeProperty *wireprop = NULL; const Nif::NiWireframeProperty *wireprop = NULL;
bool needTangents = false; bool needTangents = false;
partnode->getProperties(texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop); partnode->getProperties(texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop);
partsys->setMaterialName(NIFMaterialLoader::getMaterial(particledata, fullname, group, partsys->setMaterialName(NIFMaterialLoader::getMaterial(particledata, fullname, group,
texprop, matprop, alphaprop, texprop, matprop, alphaprop,
vertprop, zprop, specprop, vertprop, zprop, specprop,
wireprop, needTangents)); wireprop, needTangents));
partsys->setDefaultDimensions(particledata->particleRadius*2.0f, partsys->setDefaultDimensions(particledata->particleRadius*2.0f,
particledata->particleRadius*2.0f); particledata->particleRadius*2.0f);
partsys->setCullIndividually(false); partsys->setCullIndividually(false);
partsys->setParticleQuota(particledata->numParticles); partsys->setParticleQuota(particledata->numParticles);
// TODO: There is probably a field or flag to specify this, as some // TODO: There is probably a field or flag to specify this, as some
// particle effects have it and some don't. // particle effects have it and some don't.
partsys->setKeepParticlesInLocalSpace(true); partsys->setKeepParticlesInLocalSpace(true);
Nif::ControllerPtr ctrl = partnode->controller; Nif::ControllerPtr ctrl = partnode->controller;
while(!ctrl.empty()) while(!ctrl.empty())
{
if(ctrl->recType == Nif::RC_NiParticleSystemController)
{ {
if(ctrl->recType == Nif::RC_NiParticleSystemController) const Nif::NiParticleSystemController *partctrl = static_cast<const Nif::NiParticleSystemController*>(ctrl.getPtr());
createParticleEmitterAffectors(partsys, partctrl);
if(!partctrl->emitter.empty() && !partsys->isAttached())
{ {
const Nif::NiParticleSystemController *partctrl = static_cast<const Nif::NiParticleSystemController*>(ctrl.getPtr()); int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, partctrl->emitter->recIndex);
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
createParticleEmitterAffectors(partsys, partctrl); objectlist.mSkelBase->attachObjectToBone(trgtbone->getName(), partsys);
if(!partctrl->emitter.empty() && !partsys->isAttached())
{
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, partctrl->emitter->recIndex);
Ogre::Bone *trgtbone = entitybase->getSkeleton()->getBone(trgtid);
entitybase->attachObjectToBone(trgtbone->getName(), partsys);
}
} }
ctrl = ctrl->next;
}
if(!partsys->isAttached())
{
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, partnode->recIndex);
Ogre::Bone *trgtbone = entitybase->getSkeleton()->getBone(trgtid);
entitybase->attachObjectToBone(trgtbone->getName(), partsys);
} }
ctrl = ctrl->next;
} }
catch(std::exception &e) {
std::cerr<< "Particles exception: "<<e.what() <<std::endl; if(!partsys->isAttached())
sceneMgr->destroyParticleSystem(partsys); {
partsys = NULL; int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, partnode->recIndex);
}; Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
return partsys; objectlist.mSkelBase->attachObjectToBone(trgtbone->getName(), partsys);
}
partsys->setVisible(!(flags&0x01));
objectlist.mParticles.push_back(partsys);
} }
@ -569,61 +616,13 @@ class NIFObjectLoader
if(node->recType == Nif::RC_NiTriShape && !(flags&0x80000000)) if(node->recType == Nif::RC_NiTriShape && !(flags&0x80000000))
{ {
const Nif::NiTriShape *shape = static_cast<const Nif::NiTriShape*>(node); createEntity(name, group, sceneMgr, objectlist, node, flags, animflags);
std::string fullname = name+"@index="+Ogre::StringConverter::toString(shape->recIndex);
if(shape->name.length() > 0)
fullname += "@shape="+shape->name;
Misc::StringUtils::toLower(fullname);
Ogre::MeshManager &meshMgr = Ogre::MeshManager::getSingleton();
if(meshMgr.getByName(fullname).isNull())
NIFMeshLoader::createMesh(name, fullname, group, shape->recIndex);
Ogre::Entity *entity = sceneMgr->createEntity(fullname);
entity->setVisible(!(flags&0x01));
objectlist.mEntities.push_back(entity);
if(objectlist.mSkelBase)
{
if(entity->hasSkeleton())
entity->shareSkeletonInstanceWith(objectlist.mSkelBase);
else
{
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, shape->recIndex);
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
objectlist.mSkelBase->attachObjectToBone(trgtbone->getName(), entity);
}
}
Nif::ControllerPtr ctrl = node->controller;
while(!ctrl.empty())
{
if(ctrl->recType == Nif::RC_NiUVController)
{
const Nif::NiUVController *uv = static_cast<const Nif::NiUVController*>(ctrl.getPtr());
const Ogre::MaterialPtr &material = entity->getSubEntity(0)->getMaterial();
Ogre::ControllerValueRealPtr srcval((animflags&0x20) ? Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
Ogre::ControllerValueRealPtr());
Ogre::ControllerValueRealPtr dstval(OGRE_NEW UVController::Value(material, uv->data.getPtr()));
Ogre::ControllerFunctionRealPtr func(OGRE_NEW UVController::Function(uv, (animflags&0x20)));
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
}
ctrl = ctrl->next;
}
} }
if((node->recType == Nif::RC_NiAutoNormalParticles || if((node->recType == Nif::RC_NiAutoNormalParticles ||
node->recType == Nif::RC_NiRotatingParticles) && !(flags&0x40000000)) node->recType == Nif::RC_NiRotatingParticles) && !(flags&0x40000000))
{ {
Ogre::ParticleSystem *partsys = createParticleSystem(name, group, sceneMgr, objectlist.mSkelBase, node); createParticleSystem(name, group, sceneMgr, objectlist, node, flags, animflags);
if(partsys != NULL)
{
partsys->setVisible(!(flags&0x01));
objectlist.mParticles.push_back(partsys);
}
} }
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(node); const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(node);