forked from teamnwah/openmw-tes3coop
Implement NiBillboardNode. Flags not handled yet.
This commit is contained in:
parent
a3ff9e5be8
commit
5931fdcbde
14 changed files with 76 additions and 9 deletions
|
@ -150,9 +150,12 @@ void Actors::removeCell(MWWorld::Ptr::CellStore* store)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Actors::update (float duration)
|
void Actors::update (Ogre::Camera* camera)
|
||||||
{
|
{
|
||||||
// Nothing to do
|
for(PtrAnimationMap::iterator iter = mAllActors.begin();iter != mAllActors.end(); ++iter)
|
||||||
|
{
|
||||||
|
iter->second->preRender(camera);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Animation* Actors::getAnimation(const MWWorld::Ptr &ptr)
|
Animation* Actors::getAnimation(const MWWorld::Ptr &ptr)
|
||||||
|
|
|
@ -47,7 +47,7 @@ namespace MWRender
|
||||||
|
|
||||||
void removeCell(MWWorld::CellStore* store);
|
void removeCell(MWWorld::CellStore* store);
|
||||||
|
|
||||||
void update (float duration);
|
void update (Ogre::Camera* camera);
|
||||||
|
|
||||||
/// Updates containing cell for object rendering data
|
/// Updates containing cell for object rendering data
|
||||||
void updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur);
|
void updateObjectCell(const MWWorld::Ptr &old, const MWWorld::Ptr &cur);
|
||||||
|
|
|
@ -1117,6 +1117,16 @@ void Animation::updateEffects(float duration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Animation::preRender(Ogre::Camera *camera)
|
||||||
|
{
|
||||||
|
for (std::vector<EffectParams>::iterator it = mEffects.begin(); it != mEffects.end(); ++it)
|
||||||
|
{
|
||||||
|
NifOgre::ObjectScenePtr objects = it->mObjects;
|
||||||
|
objects->rotateBillboardNodes(camera);
|
||||||
|
}
|
||||||
|
mObjectRoot->rotateBillboardNodes(camera);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Should not be here
|
// TODO: Should not be here
|
||||||
Ogre::Vector3 Animation::getEnchantmentColor(MWWorld::Ptr item)
|
Ogre::Vector3 Animation::getEnchantmentColor(MWWorld::Ptr item)
|
||||||
{
|
{
|
||||||
|
@ -1180,6 +1190,8 @@ bool ObjectAnimation::canBatch() const
|
||||||
{
|
{
|
||||||
if(!mObjectRoot->mParticles.empty() || !mObjectRoot->mLights.empty() || !mObjectRoot->mControllers.empty())
|
if(!mObjectRoot->mParticles.empty() || !mObjectRoot->mLights.empty() || !mObjectRoot->mControllers.empty())
|
||||||
return false;
|
return false;
|
||||||
|
if (!mObjectRoot->mBillboardNodes.empty())
|
||||||
|
return false;
|
||||||
return std::find_if(mObjectRoot->mEntities.begin(), mObjectRoot->mEntities.end(),
|
return std::find_if(mObjectRoot->mEntities.begin(), mObjectRoot->mEntities.end(),
|
||||||
FindEntityTransparency()) == mObjectRoot->mEntities.end();
|
FindEntityTransparency()) == mObjectRoot->mEntities.end();
|
||||||
}
|
}
|
||||||
|
|
|
@ -216,6 +216,9 @@ public:
|
||||||
void removeEffect (int effectId);
|
void removeEffect (int effectId);
|
||||||
void getLoopingEffects (std::vector<int>& out);
|
void getLoopingEffects (std::vector<int>& out);
|
||||||
|
|
||||||
|
/// Prepare this animation for being rendered with \a camera (rotates billboard nodes)
|
||||||
|
virtual void preRender (Ogre::Camera* camera);
|
||||||
|
|
||||||
virtual void setAlpha(float alpha) {}
|
virtual void setAlpha(float alpha) {}
|
||||||
private:
|
private:
|
||||||
void updateEffects(float duration);
|
void updateEffects(float duration);
|
||||||
|
|
|
@ -730,6 +730,17 @@ void NpcAnimation::setAlpha(float alpha)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NpcAnimation::preRender(Ogre::Camera *camera)
|
||||||
|
{
|
||||||
|
Animation::preRender(camera);
|
||||||
|
for (int i=0; i<ESM::PRT_Count; ++i)
|
||||||
|
{
|
||||||
|
if (mObjectParts[i].isNull())
|
||||||
|
continue;
|
||||||
|
mObjectParts[i]->rotateBillboardNodes(camera);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void NpcAnimation::applyAlpha(float alpha, Ogre::Entity *ent, NifOgre::ObjectScenePtr scene)
|
void NpcAnimation::applyAlpha(float alpha, Ogre::Entity *ent, NifOgre::ObjectScenePtr scene)
|
||||||
{
|
{
|
||||||
ent->getSubEntity(0)->setRenderQueueGroup(alpha != 1.f || ent->getSubEntity(0)->getMaterial()->isTransparent()
|
ent->getSubEntity(0)->setRenderQueueGroup(alpha != 1.f || ent->getSubEntity(0)->getMaterial()->isTransparent()
|
||||||
|
|
|
@ -116,6 +116,9 @@ public:
|
||||||
|
|
||||||
/// Make the NPC only partially visible
|
/// Make the NPC only partially visible
|
||||||
virtual void setAlpha(float alpha);
|
virtual void setAlpha(float alpha);
|
||||||
|
|
||||||
|
/// Prepare this animation for being rendered with \a camera (rotates billboard nodes)
|
||||||
|
virtual void preRender (Ogre::Camera* camera);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -245,11 +245,16 @@ void Objects::disableLights()
|
||||||
it->second->enableLights(false);
|
it->second->enableLights(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Objects::update(const float dt)
|
void Objects::update(float dt, Ogre::Camera* camera)
|
||||||
{
|
{
|
||||||
PtrAnimationMap::const_iterator it = mObjects.begin();
|
PtrAnimationMap::const_iterator it = mObjects.begin();
|
||||||
for(;it != mObjects.end();it++)
|
for(;it != mObjects.end();it++)
|
||||||
it->second->runAnimation(dt);
|
it->second->runAnimation(dt);
|
||||||
|
|
||||||
|
it = mObjects.begin();
|
||||||
|
for(;it != mObjects.end();it++)
|
||||||
|
it->second->preRender(camera);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Objects::rebuildStaticGeometry()
|
void Objects::rebuildStaticGeometry()
|
||||||
|
|
|
@ -48,7 +48,7 @@ public:
|
||||||
void enableLights();
|
void enableLights();
|
||||||
void disableLights();
|
void disableLights();
|
||||||
|
|
||||||
void update (const float dt);
|
void update (float dt, Ogre::Camera* camera);
|
||||||
///< per-frame update
|
///< per-frame update
|
||||||
|
|
||||||
Ogre::AxisAlignedBox getDimensions(MWWorld::CellStore*);
|
Ogre::AxisAlignedBox getDimensions(MWWorld::CellStore*);
|
||||||
|
|
|
@ -372,9 +372,9 @@ void RenderingManager::update (float duration, bool paused)
|
||||||
if(paused)
|
if(paused)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
mActors->update (duration);
|
mActors->update (mRendering.getCamera());
|
||||||
mObjects->update (duration);
|
mPlayerAnimation->preRender(mRendering.getCamera());
|
||||||
|
mObjects->update (duration, mRendering.getCamera());
|
||||||
|
|
||||||
mSkyManager->update(duration);
|
mSkyManager->update(duration);
|
||||||
|
|
||||||
|
|
|
@ -210,7 +210,7 @@ static const RecordFactoryEntry recordFactories [] = {
|
||||||
{ "AvoidNode", &construct <NiNode >, RC_AvoidNode },
|
{ "AvoidNode", &construct <NiNode >, RC_AvoidNode },
|
||||||
{ "NiBSParticleNode", &construct <NiNode >, RC_NiBSParticleNode },
|
{ "NiBSParticleNode", &construct <NiNode >, RC_NiBSParticleNode },
|
||||||
{ "NiBSAnimationNode", &construct <NiNode >, RC_NiBSAnimationNode },
|
{ "NiBSAnimationNode", &construct <NiNode >, RC_NiBSAnimationNode },
|
||||||
{ "NiBillboardNode", &construct <NiNode >, RC_NiNode },
|
{ "NiBillboardNode", &construct <NiNode >, RC_NiBillboardNode },
|
||||||
{ "NiTriShape", &construct <NiTriShape >, RC_NiTriShape },
|
{ "NiTriShape", &construct <NiTriShape >, RC_NiTriShape },
|
||||||
{ "NiRotatingParticles", &construct <NiRotatingParticles >, RC_NiRotatingParticles },
|
{ "NiRotatingParticles", &construct <NiRotatingParticles >, RC_NiRotatingParticles },
|
||||||
{ "NiAutoNormalParticles", &construct <NiAutoNormalParticles >, RC_NiAutoNormalParticles },
|
{ "NiAutoNormalParticles", &construct <NiAutoNormalParticles >, RC_NiAutoNormalParticles },
|
||||||
|
|
|
@ -36,6 +36,7 @@ enum RecordType
|
||||||
{
|
{
|
||||||
RC_MISSING = 0,
|
RC_MISSING = 0,
|
||||||
RC_NiNode,
|
RC_NiNode,
|
||||||
|
RC_NiBillboardNode,
|
||||||
RC_AvoidNode,
|
RC_AvoidNode,
|
||||||
RC_NiTriShape,
|
RC_NiTriShape,
|
||||||
RC_NiRotatingParticles,
|
RC_NiRotatingParticles,
|
||||||
|
|
|
@ -110,6 +110,17 @@ ObjectScene::~ObjectScene()
|
||||||
mSkelBase = NULL;
|
mSkelBase = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ObjectScene::rotateBillboardNodes(Ogre::Camera *camera)
|
||||||
|
{
|
||||||
|
for (std::vector<Ogre::Node*>::iterator it = mBillboardNodes.begin(); it != mBillboardNodes.end(); ++it)
|
||||||
|
{
|
||||||
|
assert(mSkelBase);
|
||||||
|
Ogre::Node* node = *it;
|
||||||
|
node->_setDerivedOrientation(mSkelBase->getParentNode()->_getDerivedOrientation().Inverse() *
|
||||||
|
camera->getRealOrientation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Animates a texture
|
// Animates a texture
|
||||||
class FlipController
|
class FlipController
|
||||||
{
|
{
|
||||||
|
@ -1007,6 +1018,17 @@ class NIFObjectLoader
|
||||||
else
|
else
|
||||||
flags |= node->flags;
|
flags |= node->flags;
|
||||||
|
|
||||||
|
if (node->recType == Nif::RC_NiBillboardNode)
|
||||||
|
{
|
||||||
|
// TODO: figure out what the flags mean.
|
||||||
|
// NifSkope has names for them, but doesn't implement them.
|
||||||
|
// Change mBillboardNodes to map <Bone, billboard type>
|
||||||
|
int trgtid = NIFSkeletonLoader::lookupOgreBoneHandle(name, node->recIndex);
|
||||||
|
Ogre::Bone* bone = scene->mSkelBase->getSkeleton()->getBone(trgtid);
|
||||||
|
bone->setManuallyControlled(true);
|
||||||
|
scene->mBillboardNodes.push_back(bone);
|
||||||
|
}
|
||||||
|
|
||||||
Nif::ExtraPtr e = node->extra;
|
Nif::ExtraPtr e = node->extra;
|
||||||
while(!e.empty())
|
while(!e.empty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,6 +61,9 @@ struct ObjectScene {
|
||||||
std::vector<Ogre::ParticleSystem*> mParticles;
|
std::vector<Ogre::ParticleSystem*> mParticles;
|
||||||
std::vector<Ogre::Light*> mLights;
|
std::vector<Ogre::Light*> mLights;
|
||||||
|
|
||||||
|
// Nodes that should always face the camera when rendering
|
||||||
|
std::vector<Ogre::Node*> mBillboardNodes;
|
||||||
|
|
||||||
Ogre::SceneManager* mSceneMgr;
|
Ogre::SceneManager* mSceneMgr;
|
||||||
|
|
||||||
// The maximum length on any of the controllers. For animations with controllers, but no text keys, consider this the animation length.
|
// The maximum length on any of the controllers. For animations with controllers, but no text keys, consider this the animation length.
|
||||||
|
@ -76,6 +79,9 @@ struct ObjectScene {
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
~ObjectScene();
|
~ObjectScene();
|
||||||
|
|
||||||
|
// Rotate nodes in mBillboardNodes so they face the given camera
|
||||||
|
void rotateBillboardNodes(Ogre::Camera* camera);
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Ogre::SharedPtr<ObjectScene> ObjectScenePtr;
|
typedef Ogre::SharedPtr<ObjectScene> ObjectScenePtr;
|
||||||
|
|
|
@ -30,6 +30,7 @@ void NIFSkeletonLoader::buildBones(Ogre::Skeleton *skel, const Nif::Node *node,
|
||||||
node->recType == Nif::RC_RootCollisionNode || /* handled in nifbullet (hopefully) */
|
node->recType == Nif::RC_RootCollisionNode || /* handled in nifbullet (hopefully) */
|
||||||
node->recType == Nif::RC_NiTriShape || /* Handled in the mesh loader */
|
node->recType == Nif::RC_NiTriShape || /* Handled in the mesh loader */
|
||||||
node->recType == Nif::RC_NiBSAnimationNode || /* Handled in the object loader */
|
node->recType == Nif::RC_NiBSAnimationNode || /* Handled in the object loader */
|
||||||
|
node->recType == Nif::RC_NiBillboardNode || /* Handled in the object loader */
|
||||||
node->recType == Nif::RC_NiBSParticleNode ||
|
node->recType == Nif::RC_NiBSParticleNode ||
|
||||||
node->recType == Nif::RC_NiCamera ||
|
node->recType == Nif::RC_NiCamera ||
|
||||||
node->recType == Nif::RC_NiAutoNormalParticles ||
|
node->recType == Nif::RC_NiAutoNormalParticles ||
|
||||||
|
|
Loading…
Reference in a new issue