|
|
|
@ -37,54 +37,241 @@
|
|
|
|
|
#include <OgreSkeletonManager.h>
|
|
|
|
|
#include <OgreControllerManager.h>
|
|
|
|
|
|
|
|
|
|
#include <extern/shiny/Main/Factory.hpp>
|
|
|
|
|
|
|
|
|
|
#include <components/nif/node.hpp>
|
|
|
|
|
#include <components/misc/stringops.hpp>
|
|
|
|
|
|
|
|
|
|
#include "skeleton.hpp"
|
|
|
|
|
#include "material.hpp"
|
|
|
|
|
#include "mesh.hpp"
|
|
|
|
|
#include "controller.hpp"
|
|
|
|
|
|
|
|
|
|
namespace NifOgre
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
// FIXME: Should not be here.
|
|
|
|
|
class DefaultFunction : public Ogre::ControllerFunction<Ogre::Real>
|
|
|
|
|
Ogre::MaterialPtr MaterialControllerManager::getWritableMaterial(Ogre::MovableObject *movable)
|
|
|
|
|
{
|
|
|
|
|
if (mClonedMaterials.find(movable) != mClonedMaterials.end())
|
|
|
|
|
return mClonedMaterials[movable];
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Ogre::MaterialPtr mat;
|
|
|
|
|
if (Ogre::Entity* ent = dynamic_cast<Ogre::Entity*>(movable))
|
|
|
|
|
mat = ent->getSubEntity(0)->getMaterial();
|
|
|
|
|
else if (Ogre::ParticleSystem* partSys = dynamic_cast<Ogre::ParticleSystem*>(movable))
|
|
|
|
|
mat = Ogre::MaterialManager::getSingleton().getByName(partSys->getMaterialName());
|
|
|
|
|
|
|
|
|
|
static int count=0;
|
|
|
|
|
Ogre::String newName = mat->getName() + Ogre::StringConverter::toString(count++);
|
|
|
|
|
sh::Factory::getInstance().createMaterialInstance(newName, mat->getName());
|
|
|
|
|
// Make sure techniques are created
|
|
|
|
|
sh::Factory::getInstance()._ensureMaterial(newName, "Default");
|
|
|
|
|
mat = Ogre::MaterialManager::getSingleton().getByName(newName);
|
|
|
|
|
|
|
|
|
|
mClonedMaterials[movable] = mat;
|
|
|
|
|
|
|
|
|
|
if (Ogre::Entity* ent = dynamic_cast<Ogre::Entity*>(movable))
|
|
|
|
|
ent->getSubEntity(0)->setMaterial(mat);
|
|
|
|
|
else if (Ogre::ParticleSystem* partSys = dynamic_cast<Ogre::ParticleSystem*>(movable))
|
|
|
|
|
partSys->setMaterialName(mat->getName());
|
|
|
|
|
|
|
|
|
|
return mat;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MaterialControllerManager::~MaterialControllerManager()
|
|
|
|
|
{
|
|
|
|
|
for (std::map<Ogre::MovableObject*, Ogre::MaterialPtr>::iterator it = mClonedMaterials.begin(); it != mClonedMaterials.end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
sh::Factory::getInstance().destroyMaterialInstance(it->second->getName());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ObjectScene::~ObjectScene()
|
|
|
|
|
{
|
|
|
|
|
for(size_t i = 0;i < mLights.size();i++)
|
|
|
|
|
{
|
|
|
|
|
Ogre::Light *light = mLights[i];
|
|
|
|
|
// If parent is a scene node, it was created specifically for this light. Destroy it now.
|
|
|
|
|
if(light->isAttached() && !light->isParentTagPoint())
|
|
|
|
|
mSceneMgr->destroySceneNode(light->getParentSceneNode());
|
|
|
|
|
mSceneMgr->destroyLight(light);
|
|
|
|
|
}
|
|
|
|
|
for(size_t i = 0;i < mParticles.size();i++)
|
|
|
|
|
mSceneMgr->destroyParticleSystem(mParticles[i]);
|
|
|
|
|
for(size_t i = 0;i < mEntities.size();i++)
|
|
|
|
|
mSceneMgr->destroyEntity(mEntities[i]);
|
|
|
|
|
mControllers.clear();
|
|
|
|
|
mLights.clear();
|
|
|
|
|
mParticles.clear();
|
|
|
|
|
mEntities.clear();
|
|
|
|
|
mSkelBase = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Animates a texture
|
|
|
|
|
class FlipController
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
float mFrequency;
|
|
|
|
|
float mPhase;
|
|
|
|
|
float mStartTime;
|
|
|
|
|
public:
|
|
|
|
|
float mStopTime;
|
|
|
|
|
class Value : public Ogre::ControllerValue<Ogre::Real>
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
Ogre::MovableObject* mMovable;
|
|
|
|
|
int mTexSlot;
|
|
|
|
|
float mDelta;
|
|
|
|
|
std::vector<std::string> mTextures;
|
|
|
|
|
MaterialControllerManager* mMaterialControllerMgr;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
Value(Ogre::MovableObject *movable, const Nif::NiFlipController *ctrl, MaterialControllerManager* materialControllerMgr)
|
|
|
|
|
: mMovable(movable)
|
|
|
|
|
, mMaterialControllerMgr(materialControllerMgr)
|
|
|
|
|
{
|
|
|
|
|
mTexSlot = ctrl->mTexSlot;
|
|
|
|
|
mDelta = ctrl->mDelta;
|
|
|
|
|
for (unsigned int i=0; i<ctrl->mSources.length(); ++i)
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiSourceTexture* tex = ctrl->mSources[i].getPtr();
|
|
|
|
|
if (!tex->external)
|
|
|
|
|
std::cerr << "Warning: Found internal texture, ignoring." << std::endl;
|
|
|
|
|
mTextures.push_back(NIFMaterialLoader::findTextureName(tex->filename));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual Ogre::Real getValue() const
|
|
|
|
|
{
|
|
|
|
|
// Should not be called
|
|
|
|
|
return 0.0f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void setValue(Ogre::Real time)
|
|
|
|
|
{
|
|
|
|
|
if (mDelta == 0)
|
|
|
|
|
return;
|
|
|
|
|
int curTexture = int(time / mDelta) % mTextures.size();
|
|
|
|
|
|
|
|
|
|
Ogre::MaterialPtr mat = mMaterialControllerMgr->getWritableMaterial(mMovable);
|
|
|
|
|
Ogre::Material::TechniqueIterator techs = mat->getTechniqueIterator();
|
|
|
|
|
while(techs.hasMoreElements())
|
|
|
|
|
{
|
|
|
|
|
Ogre::Technique *tech = techs.getNext();
|
|
|
|
|
Ogre::Technique::PassIterator passes = tech->getPassIterator();
|
|
|
|
|
while(passes.hasMoreElements())
|
|
|
|
|
{
|
|
|
|
|
Ogre::Pass *pass = passes.getNext();
|
|
|
|
|
Ogre::Pass::TextureUnitStateIterator textures = pass->getTextureUnitStateIterator();
|
|
|
|
|
while (textures.hasMoreElements())
|
|
|
|
|
{
|
|
|
|
|
Ogre::TextureUnitState *texture = textures.getNext();
|
|
|
|
|
if ((texture->getName() == "diffuseMap" && mTexSlot == Nif::NiTexturingProperty::BaseTexture)
|
|
|
|
|
|| (texture->getName() == "normalMap" && mTexSlot == Nif::NiTexturingProperty::BumpTexture)
|
|
|
|
|
|| (texture->getName() == "detailMap" && mTexSlot == Nif::NiTexturingProperty::DetailTexture)
|
|
|
|
|
|| (texture->getName() == "emissiveMap" && mTexSlot == Nif::NiTexturingProperty::GlowTexture))
|
|
|
|
|
texture->setTextureName(mTextures[curTexture]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef DefaultFunction Function;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class AlphaController
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
DefaultFunction(const Nif::Controller *ctrl, bool deltaInput)
|
|
|
|
|
: Ogre::ControllerFunction<Ogre::Real>(deltaInput)
|
|
|
|
|
, mFrequency(ctrl->frequency)
|
|
|
|
|
, mPhase(ctrl->phase)
|
|
|
|
|
, mStartTime(ctrl->timeStart)
|
|
|
|
|
, mStopTime(ctrl->timeStop)
|
|
|
|
|
class Value : public Ogre::ControllerValue<Ogre::Real>, public ValueInterpolator
|
|
|
|
|
{
|
|
|
|
|
if(mDeltaInput)
|
|
|
|
|
mDeltaCount = mPhase;
|
|
|
|
|
}
|
|
|
|
|
private:
|
|
|
|
|
Ogre::MovableObject* mMovable;
|
|
|
|
|
Nif::FloatKeyList mData;
|
|
|
|
|
MaterialControllerManager* mMaterialControllerMgr;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
Value(Ogre::MovableObject *movable, const Nif::NiFloatData *data, MaterialControllerManager* materialControllerMgr)
|
|
|
|
|
: mMovable(movable)
|
|
|
|
|
, mData(data->mKeyList)
|
|
|
|
|
, mMaterialControllerMgr(materialControllerMgr)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual Ogre::Real getValue() const
|
|
|
|
|
{
|
|
|
|
|
// Should not be called
|
|
|
|
|
return 0.0f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void setValue(Ogre::Real time)
|
|
|
|
|
{
|
|
|
|
|
float value = interpKey(mData.mKeys, time);
|
|
|
|
|
Ogre::MaterialPtr mat = mMaterialControllerMgr->getWritableMaterial(mMovable);
|
|
|
|
|
Ogre::Material::TechniqueIterator techs = mat->getTechniqueIterator();
|
|
|
|
|
while(techs.hasMoreElements())
|
|
|
|
|
{
|
|
|
|
|
Ogre::Technique *tech = techs.getNext();
|
|
|
|
|
Ogre::Technique::PassIterator passes = tech->getPassIterator();
|
|
|
|
|
while(passes.hasMoreElements())
|
|
|
|
|
{
|
|
|
|
|
Ogre::Pass *pass = passes.getNext();
|
|
|
|
|
Ogre::ColourValue diffuse = pass->getDiffuse();
|
|
|
|
|
diffuse.a = value;
|
|
|
|
|
pass->setDiffuse(diffuse);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef DefaultFunction Function;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
virtual Ogre::Real calculate(Ogre::Real value)
|
|
|
|
|
class MaterialColorController
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
class Value : public Ogre::ControllerValue<Ogre::Real>, public ValueInterpolator
|
|
|
|
|
{
|
|
|
|
|
if(mDeltaInput)
|
|
|
|
|
private:
|
|
|
|
|
Ogre::MovableObject* mMovable;
|
|
|
|
|
Nif::Vector3KeyList mData;
|
|
|
|
|
MaterialControllerManager* mMaterialControllerMgr;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
Value(Ogre::MovableObject *movable, const Nif::NiPosData *data, MaterialControllerManager* materialControllerMgr)
|
|
|
|
|
: mMovable(movable)
|
|
|
|
|
, mData(data->mKeyList)
|
|
|
|
|
, mMaterialControllerMgr(materialControllerMgr)
|
|
|
|
|
{
|
|
|
|
|
mDeltaCount += value*mFrequency;
|
|
|
|
|
if(mDeltaCount < mStartTime)
|
|
|
|
|
mDeltaCount = mStopTime - std::fmod(mStartTime - mDeltaCount,
|
|
|
|
|
mStopTime - mStartTime);
|
|
|
|
|
mDeltaCount = std::fmod(mDeltaCount - mStartTime,
|
|
|
|
|
mStopTime - mStartTime) + mStartTime;
|
|
|
|
|
return mDeltaCount;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
value = std::min(mStopTime, std::max(mStartTime, value+mPhase));
|
|
|
|
|
return value;
|
|
|
|
|
}
|
|
|
|
|
virtual Ogre::Real getValue() const
|
|
|
|
|
{
|
|
|
|
|
// Should not be called
|
|
|
|
|
return 0.0f;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
virtual void setValue(Ogre::Real time)
|
|
|
|
|
{
|
|
|
|
|
Ogre::Vector3 value = interpKey(mData.mKeys, time);
|
|
|
|
|
Ogre::MaterialPtr mat = mMaterialControllerMgr->getWritableMaterial(mMovable);
|
|
|
|
|
Ogre::Material::TechniqueIterator techs = mat->getTechniqueIterator();
|
|
|
|
|
while(techs.hasMoreElements())
|
|
|
|
|
{
|
|
|
|
|
Ogre::Technique *tech = techs.getNext();
|
|
|
|
|
Ogre::Technique::PassIterator passes = tech->getPassIterator();
|
|
|
|
|
while(passes.hasMoreElements())
|
|
|
|
|
{
|
|
|
|
|
Ogre::Pass *pass = passes.getNext();
|
|
|
|
|
Ogre::ColourValue diffuse = pass->getDiffuse();
|
|
|
|
|
diffuse.r = value.x;
|
|
|
|
|
diffuse.g = value.y;
|
|
|
|
|
diffuse.b = value.z;
|
|
|
|
|
pass->setDiffuse(diffuse);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
typedef DefaultFunction Function;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class VisController
|
|
|
|
@ -163,48 +350,14 @@ public:
|
|
|
|
|
class KeyframeController
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
class Value : public NodeTargetValue<Ogre::Real>
|
|
|
|
|
class Value : public NodeTargetValue<Ogre::Real>, public ValueInterpolator
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
Nif::QuaternionKeyList mRotations;
|
|
|
|
|
Nif::Vector3KeyList mTranslations;
|
|
|
|
|
Nif::FloatKeyList mScales;
|
|
|
|
|
|
|
|
|
|
static float interpKey(const Nif::FloatKeyList::VecType &keys, float time)
|
|
|
|
|
{
|
|
|
|
|
if(time <= keys.front().mTime)
|
|
|
|
|
return keys.front().mValue;
|
|
|
|
|
|
|
|
|
|
Nif::FloatKeyList::VecType::const_iterator iter(keys.begin()+1);
|
|
|
|
|
for(;iter != keys.end();iter++)
|
|
|
|
|
{
|
|
|
|
|
if(iter->mTime < time)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
Nif::FloatKeyList::VecType::const_iterator last(iter-1);
|
|
|
|
|
float a = (time-last->mTime) / (iter->mTime-last->mTime);
|
|
|
|
|
return last->mValue + ((iter->mValue - last->mValue)*a);
|
|
|
|
|
}
|
|
|
|
|
return keys.back().mValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static Ogre::Vector3 interpKey(const Nif::Vector3KeyList::VecType &keys, float time)
|
|
|
|
|
{
|
|
|
|
|
if(time <= keys.front().mTime)
|
|
|
|
|
return keys.front().mValue;
|
|
|
|
|
|
|
|
|
|
Nif::Vector3KeyList::VecType::const_iterator iter(keys.begin()+1);
|
|
|
|
|
for(;iter != keys.end();iter++)
|
|
|
|
|
{
|
|
|
|
|
if(iter->mTime < time)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
Nif::Vector3KeyList::VecType::const_iterator last(iter-1);
|
|
|
|
|
float a = (time-last->mTime) / (iter->mTime-last->mTime);
|
|
|
|
|
return last->mValue + ((iter->mValue - last->mValue)*a);
|
|
|
|
|
}
|
|
|
|
|
return keys.back().mValue;
|
|
|
|
|
}
|
|
|
|
|
using ValueInterpolator::interpKey;
|
|
|
|
|
|
|
|
|
|
static Ogre::Quaternion interpKey(const Nif::QuaternionKeyList::VecType &keys, float time)
|
|
|
|
|
{
|
|
|
|
@ -276,43 +429,24 @@ public:
|
|
|
|
|
class UVController
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
class Value : public Ogre::ControllerValue<Ogre::Real>
|
|
|
|
|
class Value : public Ogre::ControllerValue<Ogre::Real>, public ValueInterpolator
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
Ogre::MaterialPtr mMaterial;
|
|
|
|
|
Ogre::MovableObject* mMovable;
|
|
|
|
|
Nif::FloatKeyList mUTrans;
|
|
|
|
|
Nif::FloatKeyList mVTrans;
|
|
|
|
|
Nif::FloatKeyList mUScale;
|
|
|
|
|
Nif::FloatKeyList mVScale;
|
|
|
|
|
|
|
|
|
|
static float lookupValue(const Nif::FloatKeyList &keys, float time, float def)
|
|
|
|
|
{
|
|
|
|
|
if(keys.mKeys.size() == 0)
|
|
|
|
|
return def;
|
|
|
|
|
|
|
|
|
|
if(time <= keys.mKeys.front().mTime)
|
|
|
|
|
return keys.mKeys.front().mValue;
|
|
|
|
|
|
|
|
|
|
Nif::FloatKeyList::VecType::const_iterator iter(keys.mKeys.begin()+1);
|
|
|
|
|
for(;iter != keys.mKeys.end();iter++)
|
|
|
|
|
{
|
|
|
|
|
if(iter->mTime < time)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
Nif::FloatKeyList::VecType::const_iterator last(iter-1);
|
|
|
|
|
float a = (time-last->mTime) / (iter->mTime-last->mTime);
|
|
|
|
|
return last->mValue + ((iter->mValue - last->mValue)*a);
|
|
|
|
|
}
|
|
|
|
|
return keys.mKeys.back().mValue;
|
|
|
|
|
}
|
|
|
|
|
MaterialControllerManager* mMaterialControllerMgr;
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
Value(const Ogre::MaterialPtr &material, const Nif::NiUVData *data)
|
|
|
|
|
: mMaterial(material)
|
|
|
|
|
Value(Ogre::MovableObject* movable, const Nif::NiUVData *data, MaterialControllerManager* materialControllerMgr)
|
|
|
|
|
: mMovable(movable)
|
|
|
|
|
, mUTrans(data->mKeyList[0])
|
|
|
|
|
, mVTrans(data->mKeyList[1])
|
|
|
|
|
, mUScale(data->mKeyList[2])
|
|
|
|
|
, mVScale(data->mKeyList[3])
|
|
|
|
|
, mMaterialControllerMgr(materialControllerMgr)
|
|
|
|
|
{ }
|
|
|
|
|
|
|
|
|
|
virtual Ogre::Real getValue() const
|
|
|
|
@ -323,12 +457,14 @@ public:
|
|
|
|
|
|
|
|
|
|
virtual void setValue(Ogre::Real value)
|
|
|
|
|
{
|
|
|
|
|
float uTrans = lookupValue(mUTrans, value, 0.0f);
|
|
|
|
|
float vTrans = lookupValue(mVTrans, value, 0.0f);
|
|
|
|
|
float uScale = lookupValue(mUScale, value, 1.0f);
|
|
|
|
|
float vScale = lookupValue(mVScale, value, 1.0f);
|
|
|
|
|
float uTrans = interpKey(mUTrans.mKeys, value, 0.0f);
|
|
|
|
|
float vTrans = interpKey(mVTrans.mKeys, value, 0.0f);
|
|
|
|
|
float uScale = interpKey(mUScale.mKeys, value, 1.0f);
|
|
|
|
|
float vScale = interpKey(mVScale.mKeys, value, 1.0f);
|
|
|
|
|
|
|
|
|
|
Ogre::MaterialPtr material = mMaterialControllerMgr->getWritableMaterial(mMovable);
|
|
|
|
|
|
|
|
|
|
Ogre::Material::TechniqueIterator techs = mMaterial->getTechniqueIterator();
|
|
|
|
|
Ogre::Material::TechniqueIterator techs = material->getTechniqueIterator();
|
|
|
|
|
while(techs.hasMoreElements())
|
|
|
|
|
{
|
|
|
|
|
Ogre::Technique *tech = techs.getNext();
|
|
|
|
@ -380,7 +516,7 @@ public:
|
|
|
|
|
class GeomMorpherController
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
class Value : public Ogre::ControllerValue<Ogre::Real>
|
|
|
|
|
class Value : public Ogre::ControllerValue<Ogre::Real>, public ValueInterpolator
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
Ogre::SubEntity *mSubEntity;
|
|
|
|
@ -389,24 +525,6 @@ public:
|
|
|
|
|
|
|
|
|
|
std::vector<Ogre::Vector3> mVertices;
|
|
|
|
|
|
|
|
|
|
static float interpKey(const Nif::FloatKeyList::VecType &keys, float time)
|
|
|
|
|
{
|
|
|
|
|
if(time <= keys.front().mTime)
|
|
|
|
|
return keys.front().mValue;
|
|
|
|
|
|
|
|
|
|
Nif::FloatKeyList::VecType::const_iterator iter(keys.begin()+1);
|
|
|
|
|
for(;iter != keys.end();iter++)
|
|
|
|
|
{
|
|
|
|
|
if(iter->mTime < time)
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
Nif::FloatKeyList::VecType::const_iterator last(iter-1);
|
|
|
|
|
float a = (time-last->mTime) / (iter->mTime-last->mTime);
|
|
|
|
|
return last->mValue + ((iter->mValue - last->mValue)*a);
|
|
|
|
|
}
|
|
|
|
|
return keys.back().mValue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
Value(Ogre::SubEntity *subent, const Nif::NiMorphData *data)
|
|
|
|
|
: mSubEntity(subent)
|
|
|
|
@ -504,7 +622,7 @@ class NIFObjectLoader
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void createEntity(const std::string &name, const std::string &group,
|
|
|
|
|
Ogre::SceneManager *sceneMgr, ObjectList &objectlist,
|
|
|
|
|
Ogre::SceneManager *sceneMgr, ObjectScenePtr scene,
|
|
|
|
|
const Nif::Node *node, int flags, int animflags)
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiTriShape *shape = static_cast<const Nif::NiTriShape*>(node);
|
|
|
|
@ -521,16 +639,16 @@ class NIFObjectLoader
|
|
|
|
|
Ogre::Entity *entity = sceneMgr->createEntity(fullname);
|
|
|
|
|
entity->setVisible(!(flags&Nif::NiNode::Flag_Hidden));
|
|
|
|
|
|
|
|
|
|
objectlist.mEntities.push_back(entity);
|
|
|
|
|
if(objectlist.mSkelBase)
|
|
|
|
|
scene->mEntities.push_back(entity);
|
|
|
|
|
if(scene->mSkelBase)
|
|
|
|
|
{
|
|
|
|
|
if(entity->hasSkeleton())
|
|
|
|
|
entity->shareSkeletonInstanceWith(objectlist.mSkelBase);
|
|
|
|
|
entity->shareSkeletonInstanceWith(scene->mSkelBase);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, shape->recIndex);
|
|
|
|
|
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
|
|
|
|
|
objectlist.mSkelBase->attachObjectToBone(trgtbone->getName(), entity);
|
|
|
|
|
Ogre::Bone *trgtbone = scene->mSkelBase->getSkeleton()->getBone(trgtid);
|
|
|
|
|
scene->mSkelBase->attachObjectToBone(trgtbone->getName(), entity);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -541,17 +659,16 @@ class NIFObjectLoader
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiUVController *uv = static_cast<const Nif::NiUVController*>(ctrl.getPtr());
|
|
|
|
|
|
|
|
|
|
const Ogre::MaterialPtr &material = entity->getSubEntity(0)->getMaterial();
|
|
|
|
|
Ogre::ControllerValueRealPtr srcval((animflags&Nif::NiNode::AnimFlag_AutoPlay) ?
|
|
|
|
|
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
|
|
|
|
|
Ogre::ControllerValueRealPtr());
|
|
|
|
|
Ogre::ControllerValueRealPtr dstval(OGRE_NEW UVController::Value(material, uv->data.getPtr()));
|
|
|
|
|
Ogre::ControllerValueRealPtr dstval(OGRE_NEW UVController::Value(entity, uv->data.getPtr(), &scene->mMaterialControllerMgr));
|
|
|
|
|
|
|
|
|
|
UVController::Function* function = OGRE_NEW UVController::Function(uv, (animflags&Nif::NiNode::AnimFlag_AutoPlay));
|
|
|
|
|
objectlist.mMaxControllerLength = std::max(function->mStopTime, objectlist.mMaxControllerLength);
|
|
|
|
|
scene->mMaxControllerLength = std::max(function->mStopTime, scene->mMaxControllerLength);
|
|
|
|
|
Ogre::ControllerFunctionRealPtr func(function);
|
|
|
|
|
|
|
|
|
|
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
|
|
|
|
|
scene->mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
|
|
|
|
|
}
|
|
|
|
|
else if(ctrl->recType == Nif::RC_NiGeomMorpherController)
|
|
|
|
|
{
|
|
|
|
@ -563,15 +680,81 @@ class NIFObjectLoader
|
|
|
|
|
Ogre::ControllerValueRealPtr dstval(OGRE_NEW GeomMorpherController::Value(entity->getSubEntity(0), geom->data.getPtr()));
|
|
|
|
|
|
|
|
|
|
GeomMorpherController::Function* function = OGRE_NEW GeomMorpherController::Function(geom, (animflags&Nif::NiNode::AnimFlag_AutoPlay));
|
|
|
|
|
objectlist.mMaxControllerLength = std::max(function->mStopTime, objectlist.mMaxControllerLength);
|
|
|
|
|
scene->mMaxControllerLength = std::max(function->mStopTime, scene->mMaxControllerLength);
|
|
|
|
|
Ogre::ControllerFunctionRealPtr func(function);
|
|
|
|
|
|
|
|
|
|
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
|
|
|
|
|
scene->mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
|
|
|
|
|
}
|
|
|
|
|
ctrl = ctrl->next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
createMaterialControllers(shape, entity, animflags, scene);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void createMaterialControllers (const Nif::Node* node, Ogre::MovableObject* movable, int animflags, ObjectScenePtr scene)
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiTexturingProperty *texprop = NULL;
|
|
|
|
|
const Nif::NiMaterialProperty *matprop = NULL;
|
|
|
|
|
const Nif::NiAlphaProperty *alphaprop = NULL;
|
|
|
|
|
const Nif::NiVertexColorProperty *vertprop = NULL;
|
|
|
|
|
const Nif::NiZBufferProperty *zprop = NULL;
|
|
|
|
|
const Nif::NiSpecularProperty *specprop = NULL;
|
|
|
|
|
const Nif::NiWireframeProperty *wireprop = NULL;
|
|
|
|
|
node->getProperties(texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop);
|
|
|
|
|
|
|
|
|
|
Ogre::ControllerValueRealPtr srcval((animflags&Nif::NiNode::AnimFlag_AutoPlay) ?
|
|
|
|
|
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
|
|
|
|
|
Ogre::ControllerValueRealPtr());
|
|
|
|
|
|
|
|
|
|
if(matprop)
|
|
|
|
|
{
|
|
|
|
|
Nif::ControllerPtr ctrls = matprop->controller;
|
|
|
|
|
while(!ctrls.empty())
|
|
|
|
|
{
|
|
|
|
|
if (ctrls->recType == Nif::RC_NiAlphaController)
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiAlphaController *alphaCtrl = dynamic_cast<const Nif::NiAlphaController*>(ctrls.getPtr());
|
|
|
|
|
Ogre::ControllerValueRealPtr dstval(OGRE_NEW AlphaController::Value(movable, alphaCtrl->data.getPtr(), &scene->mMaterialControllerMgr));
|
|
|
|
|
AlphaController::Function* function = OGRE_NEW AlphaController::Function(alphaCtrl, (animflags&Nif::NiNode::AnimFlag_AutoPlay));
|
|
|
|
|
scene->mMaxControllerLength = std::max(function->mStopTime, scene->mMaxControllerLength);
|
|
|
|
|
Ogre::ControllerFunctionRealPtr func(function);
|
|
|
|
|
scene->mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
|
|
|
|
|
}
|
|
|
|
|
else if (ctrls->recType == Nif::RC_NiMaterialColorController)
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiMaterialColorController *matCtrl = dynamic_cast<const Nif::NiMaterialColorController*>(ctrls.getPtr());
|
|
|
|
|
Ogre::ControllerValueRealPtr dstval(OGRE_NEW MaterialColorController::Value(movable, matCtrl->data.getPtr(), &scene->mMaterialControllerMgr));
|
|
|
|
|
AlphaController::Function* function = OGRE_NEW AlphaController::Function(matCtrl, (animflags&Nif::NiNode::AnimFlag_AutoPlay));
|
|
|
|
|
scene->mMaxControllerLength = std::max(function->mStopTime, scene->mMaxControllerLength);
|
|
|
|
|
Ogre::ControllerFunctionRealPtr func(function);
|
|
|
|
|
scene->mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ctrls = ctrls->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (texprop)
|
|
|
|
|
{
|
|
|
|
|
Nif::ControllerPtr ctrls = texprop->controller;
|
|
|
|
|
while(!ctrls.empty())
|
|
|
|
|
{
|
|
|
|
|
if (ctrls->recType == Nif::RC_NiFlipController)
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiFlipController *flipCtrl = dynamic_cast<const Nif::NiFlipController*>(ctrls.getPtr());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ogre::ControllerValueRealPtr dstval(OGRE_NEW FlipController::Value(
|
|
|
|
|
movable, flipCtrl, &scene->mMaterialControllerMgr));
|
|
|
|
|
FlipController::Function* function = OGRE_NEW FlipController::Function(flipCtrl, (animflags&Nif::NiNode::AnimFlag_AutoPlay));
|
|
|
|
|
scene->mMaxControllerLength = std::max(function->mStopTime, scene->mMaxControllerLength);
|
|
|
|
|
Ogre::ControllerFunctionRealPtr func(function);
|
|
|
|
|
scene->mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ctrls = ctrls->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void createParticleEmitterAffectors(Ogre::ParticleSystem *partsys,
|
|
|
|
|
const Nif::NiParticleSystemController *partctrl, Ogre::Bone* bone,
|
|
|
|
@ -647,8 +830,8 @@ class NIFObjectLoader
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void createParticleSystem(const std::string &name, const std::string &group,
|
|
|
|
|
Ogre::SceneNode *sceneNode, ObjectList &objectlist,
|
|
|
|
|
const Nif::Node *partnode, int flags, int partflags)
|
|
|
|
|
Ogre::SceneNode *sceneNode, ObjectScenePtr scene,
|
|
|
|
|
const Nif::Node *partnode, int flags, int partflags, int animflags)
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiAutoNormalParticlesData *particledata = NULL;
|
|
|
|
|
if(partnode->recType == Nif::RC_NiAutoNormalParticles)
|
|
|
|
@ -696,8 +879,8 @@ class NIFObjectLoader
|
|
|
|
|
if(!partctrl->emitter.empty())
|
|
|
|
|
{
|
|
|
|
|
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, partctrl->emitter->recIndex);
|
|
|
|
|
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
|
|
|
|
|
createParticleEmitterAffectors(partsys, partctrl, trgtbone, objectlist.mSkelBase->getName());
|
|
|
|
|
Ogre::Bone *trgtbone = scene->mSkelBase->getSkeleton()->getBone(trgtid);
|
|
|
|
|
createParticleEmitterAffectors(partsys, partctrl, trgtbone, scene->mSkelBase->getName());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ogre::ControllerValueRealPtr srcval((partflags&Nif::NiNode::ParticleFlag_AutoPlay) ?
|
|
|
|
@ -707,20 +890,22 @@ class NIFObjectLoader
|
|
|
|
|
|
|
|
|
|
ParticleSystemController::Function* function =
|
|
|
|
|
OGRE_NEW ParticleSystemController::Function(partctrl, (partflags&Nif::NiNode::ParticleFlag_AutoPlay));
|
|
|
|
|
objectlist.mMaxControllerLength = std::max(function->mStopTime, objectlist.mMaxControllerLength);
|
|
|
|
|
scene->mMaxControllerLength = std::max(function->mStopTime, scene->mMaxControllerLength);
|
|
|
|
|
Ogre::ControllerFunctionRealPtr func(function);
|
|
|
|
|
|
|
|
|
|
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
|
|
|
|
|
scene->mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
|
|
|
|
|
}
|
|
|
|
|
ctrl = ctrl->next;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
partsys->setVisible(!(flags&Nif::NiNode::Flag_Hidden));
|
|
|
|
|
objectlist.mParticles.push_back(partsys);
|
|
|
|
|
scene->mParticles.push_back(partsys);
|
|
|
|
|
|
|
|
|
|
createMaterialControllers(partnode, partsys, animflags, scene);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void createNodeControllers(const std::string &name, Nif::ControllerPtr ctrl, ObjectList &objectlist, int animflags)
|
|
|
|
|
static void createNodeControllers(const std::string &name, Nif::ControllerPtr ctrl, ObjectScenePtr scene, int animflags)
|
|
|
|
|
{
|
|
|
|
|
do {
|
|
|
|
|
if(ctrl->recType == Nif::RC_NiVisController)
|
|
|
|
@ -728,17 +913,17 @@ class NIFObjectLoader
|
|
|
|
|
const Nif::NiVisController *vis = static_cast<const Nif::NiVisController*>(ctrl.getPtr());
|
|
|
|
|
|
|
|
|
|
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, ctrl->target->recIndex);
|
|
|
|
|
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
|
|
|
|
|
Ogre::Bone *trgtbone = scene->mSkelBase->getSkeleton()->getBone(trgtid);
|
|
|
|
|
Ogre::ControllerValueRealPtr srcval((animflags&Nif::NiNode::AnimFlag_AutoPlay) ?
|
|
|
|
|
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
|
|
|
|
|
Ogre::ControllerValueRealPtr());
|
|
|
|
|
Ogre::ControllerValueRealPtr dstval(OGRE_NEW VisController::Value(trgtbone, vis->data.getPtr()));
|
|
|
|
|
|
|
|
|
|
VisController::Function* function = OGRE_NEW VisController::Function(vis, (animflags&Nif::NiNode::AnimFlag_AutoPlay));
|
|
|
|
|
objectlist.mMaxControllerLength = std::max(function->mStopTime, objectlist.mMaxControllerLength);
|
|
|
|
|
scene->mMaxControllerLength = std::max(function->mStopTime, scene->mMaxControllerLength);
|
|
|
|
|
Ogre::ControllerFunctionRealPtr func(function);
|
|
|
|
|
|
|
|
|
|
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
|
|
|
|
|
scene->mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
|
|
|
|
|
}
|
|
|
|
|
else if(ctrl->recType == Nif::RC_NiKeyframeController)
|
|
|
|
|
{
|
|
|
|
@ -746,16 +931,16 @@ class NIFObjectLoader
|
|
|
|
|
if(!key->data.empty())
|
|
|
|
|
{
|
|
|
|
|
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, ctrl->target->recIndex);
|
|
|
|
|
Ogre::Bone *trgtbone = objectlist.mSkelBase->getSkeleton()->getBone(trgtid);
|
|
|
|
|
Ogre::Bone *trgtbone = scene->mSkelBase->getSkeleton()->getBone(trgtid);
|
|
|
|
|
Ogre::ControllerValueRealPtr srcval((animflags&Nif::NiNode::AnimFlag_AutoPlay) ?
|
|
|
|
|
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
|
|
|
|
|
Ogre::ControllerValueRealPtr());
|
|
|
|
|
Ogre::ControllerValueRealPtr dstval(OGRE_NEW KeyframeController::Value(trgtbone, key->data.getPtr()));
|
|
|
|
|
KeyframeController::Function* function = OGRE_NEW KeyframeController::Function(key, (animflags&Nif::NiNode::AnimFlag_AutoPlay));
|
|
|
|
|
objectlist.mMaxControllerLength = std::max(function->mStopTime, objectlist.mMaxControllerLength);
|
|
|
|
|
scene->mMaxControllerLength = std::max(function->mStopTime, scene->mMaxControllerLength);
|
|
|
|
|
Ogre::ControllerFunctionRealPtr func(function);
|
|
|
|
|
|
|
|
|
|
objectlist.mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
|
|
|
|
|
scene->mControllers.push_back(Ogre::Controller<Ogre::Real>(srcval, dstval, func));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ctrl = ctrl->next;
|
|
|
|
@ -804,7 +989,7 @@ class NIFObjectLoader
|
|
|
|
|
|
|
|
|
|
static void createObjects(const std::string &name, const std::string &group,
|
|
|
|
|
Ogre::SceneNode *sceneNode, const Nif::Node *node,
|
|
|
|
|
ObjectList &objectlist, int flags, int animflags, int partflags)
|
|
|
|
|
ObjectScenePtr scene, int flags, int animflags, int partflags)
|
|
|
|
|
{
|
|
|
|
|
// Do not create objects for the collision shape (includes all children)
|
|
|
|
|
if(node->recType == Nif::RC_RootCollisionNode)
|
|
|
|
@ -830,7 +1015,7 @@ class NIFObjectLoader
|
|
|
|
|
const Nif::NiTextKeyExtraData *tk = static_cast<const Nif::NiTextKeyExtraData*>(e.getPtr());
|
|
|
|
|
|
|
|
|
|
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, node->recIndex);
|
|
|
|
|
extractTextKeys(tk, objectlist.mTextKeys[trgtid]);
|
|
|
|
|
extractTextKeys(tk, scene->mTextKeys[trgtid]);
|
|
|
|
|
}
|
|
|
|
|
else if(e->recType == Nif::RC_NiStringExtraData)
|
|
|
|
|
{
|
|
|
|
@ -849,7 +1034,7 @@ class NIFObjectLoader
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(!node->controller.empty() && (node->parent || node->recType != Nif::RC_NiNode))
|
|
|
|
|
createNodeControllers(name, node->controller, objectlist, animflags);
|
|
|
|
|
createNodeControllers(name, node->controller, scene, animflags);
|
|
|
|
|
|
|
|
|
|
if(node->recType == Nif::RC_NiCamera)
|
|
|
|
|
{
|
|
|
|
@ -858,13 +1043,13 @@ class NIFObjectLoader
|
|
|
|
|
|
|
|
|
|
if(node->recType == Nif::RC_NiTriShape && !(flags&0x80000000))
|
|
|
|
|
{
|
|
|
|
|
createEntity(name, group, sceneNode->getCreator(), objectlist, node, flags, animflags);
|
|
|
|
|
createEntity(name, group, sceneNode->getCreator(), scene, node, flags, animflags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if((node->recType == Nif::RC_NiAutoNormalParticles ||
|
|
|
|
|
node->recType == Nif::RC_NiRotatingParticles) && !(flags&0x40000000))
|
|
|
|
|
{
|
|
|
|
|
createParticleSystem(name, group, sceneNode, objectlist, node, flags, partflags);
|
|
|
|
|
createParticleSystem(name, group, sceneNode, scene, node, flags, partflags, animflags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(node);
|
|
|
|
@ -874,14 +1059,14 @@ class NIFObjectLoader
|
|
|
|
|
for(size_t i = 0;i < children.length();i++)
|
|
|
|
|
{
|
|
|
|
|
if(!children[i].empty())
|
|
|
|
|
createObjects(name, group, sceneNode, children[i].getPtr(), objectlist, flags, animflags, partflags);
|
|
|
|
|
createObjects(name, group, sceneNode, children[i].getPtr(), scene, flags, animflags, partflags);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void createSkelBase(const std::string &name, const std::string &group,
|
|
|
|
|
Ogre::SceneManager *sceneMgr, const Nif::Node *node,
|
|
|
|
|
ObjectList &objectlist)
|
|
|
|
|
ObjectScenePtr scene)
|
|
|
|
|
{
|
|
|
|
|
/* This creates an empty mesh to which a skeleton gets attached. This
|
|
|
|
|
* is to ensure we have an entity with a skeleton instance, even if all
|
|
|
|
@ -890,12 +1075,12 @@ class NIFObjectLoader
|
|
|
|
|
if(meshMgr.getByName(name).isNull())
|
|
|
|
|
NIFMeshLoader::createMesh(name, name, group, ~(size_t)0);
|
|
|
|
|
|
|
|
|
|
objectlist.mSkelBase = sceneMgr->createEntity(name);
|
|
|
|
|
objectlist.mEntities.push_back(objectlist.mSkelBase);
|
|
|
|
|
scene->mSkelBase = sceneMgr->createEntity(name);
|
|
|
|
|
scene->mEntities.push_back(scene->mSkelBase);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
static void load(Ogre::SceneNode *sceneNode, ObjectList &objectlist, const std::string &name, const std::string &group, int flags=0)
|
|
|
|
|
static void load(Ogre::SceneNode *sceneNode, ObjectScenePtr scene, const std::string &name, const std::string &group, int flags=0)
|
|
|
|
|
{
|
|
|
|
|
Nif::NIFFile::ptr nif = Nif::NIFFile::create(name);
|
|
|
|
|
if(nif->numRoots() < 1)
|
|
|
|
@ -919,9 +1104,9 @@ public:
|
|
|
|
|
!NIFSkeletonLoader::createSkeleton(name, group, node).isNull())
|
|
|
|
|
{
|
|
|
|
|
// Create a base skeleton entity if this NIF needs one
|
|
|
|
|
createSkelBase(name, group, sceneNode->getCreator(), node, objectlist);
|
|
|
|
|
createSkelBase(name, group, sceneNode->getCreator(), node, scene);
|
|
|
|
|
}
|
|
|
|
|
createObjects(name, group, sceneNode, node, objectlist, flags, 0, 0);
|
|
|
|
|
createObjects(name, group, sceneNode, node, scene, flags, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void loadKf(Ogre::Skeleton *skel, const std::string &name,
|
|
|
|
@ -984,37 +1169,37 @@ public:
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ObjectList Loader::createObjects(Ogre::SceneNode *parentNode, std::string name, const std::string &group)
|
|
|
|
|
ObjectScenePtr Loader::createObjects(Ogre::SceneNode *parentNode, std::string name, const std::string &group)
|
|
|
|
|
{
|
|
|
|
|
ObjectList objectlist;
|
|
|
|
|
ObjectScenePtr scene = ObjectScenePtr (new ObjectScene(parentNode->getCreator()));;
|
|
|
|
|
|
|
|
|
|
Misc::StringUtils::toLower(name);
|
|
|
|
|
NIFObjectLoader::load(parentNode, objectlist, name, group);
|
|
|
|
|
NIFObjectLoader::load(parentNode, scene, name, group);
|
|
|
|
|
|
|
|
|
|
for(size_t i = 0;i < objectlist.mEntities.size();i++)
|
|
|
|
|
for(size_t i = 0;i < scene->mEntities.size();i++)
|
|
|
|
|
{
|
|
|
|
|
Ogre::Entity *entity = objectlist.mEntities[i];
|
|
|
|
|
Ogre::Entity *entity = scene->mEntities[i];
|
|
|
|
|
if(!entity->isAttached())
|
|
|
|
|
parentNode->attachObject(entity);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return objectlist;
|
|
|
|
|
return scene;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ObjectList Loader::createObjects(Ogre::Entity *parent, const std::string &bonename,
|
|
|
|
|
ObjectScenePtr Loader::createObjects(Ogre::Entity *parent, const std::string &bonename,
|
|
|
|
|
Ogre::SceneNode *parentNode,
|
|
|
|
|
std::string name, const std::string &group)
|
|
|
|
|
{
|
|
|
|
|
ObjectList objectlist;
|
|
|
|
|
ObjectScenePtr scene = ObjectScenePtr (new ObjectScene(parentNode->getCreator()));
|
|
|
|
|
|
|
|
|
|
Misc::StringUtils::toLower(name);
|
|
|
|
|
NIFObjectLoader::load(parentNode, objectlist, name, group);
|
|
|
|
|
NIFObjectLoader::load(parentNode, scene, name, group);
|
|
|
|
|
|
|
|
|
|
bool isskinned = false;
|
|
|
|
|
for(size_t i = 0;i < objectlist.mEntities.size();i++)
|
|
|
|
|
for(size_t i = 0;i < scene->mEntities.size();i++)
|
|
|
|
|
{
|
|
|
|
|
Ogre::Entity *ent = objectlist.mEntities[i];
|
|
|
|
|
if(objectlist.mSkelBase != ent && ent->hasSkeleton())
|
|
|
|
|
Ogre::Entity *ent = scene->mEntities[i];
|
|
|
|
|
if(scene->mSkelBase != ent && ent->hasSkeleton())
|
|
|
|
|
{
|
|
|
|
|
isskinned = true;
|
|
|
|
|
break;
|
|
|
|
@ -1029,12 +1214,12 @@ ObjectList Loader::createObjects(Ogre::Entity *parent, const std::string &bonena
|
|
|
|
|
{
|
|
|
|
|
std::string filter = "@shape=tri "+bonename;
|
|
|
|
|
Misc::StringUtils::toLower(filter);
|
|
|
|
|
for(size_t i = 0;i < objectlist.mEntities.size();i++)
|
|
|
|
|
for(size_t i = 0;i < scene->mEntities.size();i++)
|
|
|
|
|
{
|
|
|
|
|
Ogre::Entity *entity = objectlist.mEntities[i];
|
|
|
|
|
Ogre::Entity *entity = scene->mEntities[i];
|
|
|
|
|
if(entity->hasSkeleton())
|
|
|
|
|
{
|
|
|
|
|
if(entity == objectlist.mSkelBase ||
|
|
|
|
|
if(entity == scene->mSkelBase ||
|
|
|
|
|
entity->getMesh()->getName().find(filter) != std::string::npos)
|
|
|
|
|
parentNode->attachObject(entity);
|
|
|
|
|
}
|
|
|
|
@ -1047,9 +1232,9 @@ ObjectList Loader::createObjects(Ogre::Entity *parent, const std::string &bonena
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
for(size_t i = 0;i < objectlist.mEntities.size();i++)
|
|
|
|
|
for(size_t i = 0;i < scene->mEntities.size();i++)
|
|
|
|
|
{
|
|
|
|
|
Ogre::Entity *entity = objectlist.mEntities[i];
|
|
|
|
|
Ogre::Entity *entity = scene->mEntities[i];
|
|
|
|
|
if(!entity->isAttached())
|
|
|
|
|
{
|
|
|
|
|
Ogre::TagPoint *tag = parent->attachObjectToBone(bonename, entity);
|
|
|
|
@ -1058,32 +1243,32 @@ ObjectList Loader::createObjects(Ogre::Entity *parent, const std::string &bonena
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(size_t i = 0;i < objectlist.mParticles.size();i++)
|
|
|
|
|
for(size_t i = 0;i < scene->mParticles.size();i++)
|
|
|
|
|
{
|
|
|
|
|
Ogre::ParticleSystem *partsys = objectlist.mParticles[i];
|
|
|
|
|
Ogre::ParticleSystem *partsys = scene->mParticles[i];
|
|
|
|
|
if(partsys->isAttached())
|
|
|
|
|
partsys->detachFromParent();
|
|
|
|
|
|
|
|
|
|
Ogre::TagPoint *tag = objectlist.mSkelBase->attachObjectToBone(
|
|
|
|
|
objectlist.mSkelBase->getSkeleton()->getRootBone()->getName(), partsys);
|
|
|
|
|
Ogre::TagPoint *tag = scene->mSkelBase->attachObjectToBone(
|
|
|
|
|
scene->mSkelBase->getSkeleton()->getRootBone()->getName(), partsys);
|
|
|
|
|
tag->setScale(scale);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return objectlist;
|
|
|
|
|
return scene;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ObjectList Loader::createObjectBase(Ogre::SceneNode *parentNode, std::string name, const std::string &group)
|
|
|
|
|
ObjectScenePtr Loader::createObjectBase(Ogre::SceneNode *parentNode, std::string name, const std::string &group)
|
|
|
|
|
{
|
|
|
|
|
ObjectList objectlist;
|
|
|
|
|
ObjectScenePtr scene = ObjectScenePtr (new ObjectScene(parentNode->getCreator()));
|
|
|
|
|
|
|
|
|
|
Misc::StringUtils::toLower(name);
|
|
|
|
|
NIFObjectLoader::load(parentNode, objectlist, name, group, 0xC0000000);
|
|
|
|
|
NIFObjectLoader::load(parentNode, scene, name, group, 0xC0000000);
|
|
|
|
|
|
|
|
|
|
if(objectlist.mSkelBase)
|
|
|
|
|
parentNode->attachObject(objectlist.mSkelBase);
|
|
|
|
|
if(scene->mSkelBase)
|
|
|
|
|
parentNode->attachObject(scene->mSkelBase);
|
|
|
|
|
|
|
|
|
|
return objectlist;
|
|
|
|
|
return scene;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|