|
|
@ -6,6 +6,7 @@
|
|
|
|
#include <osg/Geometry>
|
|
|
|
#include <osg/Geometry>
|
|
|
|
#include <osg/Array>
|
|
|
|
#include <osg/Array>
|
|
|
|
#include <osg/LOD>
|
|
|
|
#include <osg/LOD>
|
|
|
|
|
|
|
|
#include <osg/TexGen>
|
|
|
|
|
|
|
|
|
|
|
|
// resource
|
|
|
|
// resource
|
|
|
|
#include <components/misc/stringops.hpp>
|
|
|
|
#include <components/misc/stringops.hpp>
|
|
|
@ -36,6 +37,7 @@
|
|
|
|
#include <osg/TexEnvCombine>
|
|
|
|
#include <osg/TexEnvCombine>
|
|
|
|
|
|
|
|
|
|
|
|
#include <components/nif/node.hpp>
|
|
|
|
#include <components/nif/node.hpp>
|
|
|
|
|
|
|
|
#include <components/nif/effect.hpp>
|
|
|
|
#include <components/sceneutil/util.hpp>
|
|
|
|
#include <components/sceneutil/util.hpp>
|
|
|
|
#include <components/sceneutil/skeleton.hpp>
|
|
|
|
#include <components/sceneutil/skeleton.hpp>
|
|
|
|
#include <components/sceneutil/riggeometry.hpp>
|
|
|
|
#include <components/sceneutil/riggeometry.hpp>
|
|
|
@ -439,6 +441,81 @@ namespace NifOsg
|
|
|
|
return lod;
|
|
|
|
return lod;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Image> handleSourceTexture(const Nif::NiSourceTexture* st, Resource::ImageManager* imageManager)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!st)
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Image> image;
|
|
|
|
|
|
|
|
if (!st->external && !st->data.empty())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
image = handleInternalTexture(st->data.getPtr());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
std::string filename = Misc::ResourceHelpers::correctTexturePath(st->filename, imageManager->getVFS());
|
|
|
|
|
|
|
|
image = imageManager->getImage(filename);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return image;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void handleEffect(const Nif::Node* nifNode, osg::Node* node, Resource::ImageManager* imageManager)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (nifNode->recType != Nif::RC_NiTextureEffect)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
std::cerr << "Unhandled effect " << nifNode->recName << " in " << mFilename << std::endl;
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const Nif::NiTextureEffect* textureEffect = static_cast<const Nif::NiTextureEffect*>(nifNode);
|
|
|
|
|
|
|
|
if (textureEffect->textureType != Nif::NiTextureEffect::Environment_Map)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
std::cerr << "Unhandled NiTextureEffect type " << textureEffect->textureType << std::endl;
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::TexGen> texGen (new osg::TexGen);
|
|
|
|
|
|
|
|
switch (textureEffect->coordGenType)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
case Nif::NiTextureEffect::World_Parallel:
|
|
|
|
|
|
|
|
texGen->setMode(osg::TexGen::OBJECT_LINEAR);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Nif::NiTextureEffect::World_Perspective:
|
|
|
|
|
|
|
|
texGen->setMode(osg::TexGen::EYE_LINEAR);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Nif::NiTextureEffect::Sphere_Map:
|
|
|
|
|
|
|
|
texGen->setMode(osg::TexGen::SPHERE_MAP);
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
std::cerr << "Unhandled NiTextureEffect coordGenType " << textureEffect->coordGenType << std::endl;
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Texture2D> texture2d (new osg::Texture2D(handleSourceTexture(textureEffect->texture.getPtr(), imageManager)));
|
|
|
|
|
|
|
|
texture2d->setName("envMap");
|
|
|
|
|
|
|
|
unsigned int clamp = static_cast<unsigned int>(textureEffect->clamp);
|
|
|
|
|
|
|
|
int wrapT = (clamp) & 0x1;
|
|
|
|
|
|
|
|
int wrapS = (clamp >> 1) & 0x1;
|
|
|
|
|
|
|
|
texture2d->setWrap(osg::Texture::WRAP_S, wrapS ? osg::Texture::REPEAT : osg::Texture::CLAMP);
|
|
|
|
|
|
|
|
texture2d->setWrap(osg::Texture::WRAP_T, wrapT ? osg::Texture::REPEAT : osg::Texture::CLAMP);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::TexEnvCombine> texEnv = new osg::TexEnvCombine;
|
|
|
|
|
|
|
|
texEnv->setCombine_Alpha(osg::TexEnvCombine::REPLACE);
|
|
|
|
|
|
|
|
texEnv->setSource0_Alpha(osg::TexEnvCombine::PREVIOUS);
|
|
|
|
|
|
|
|
texEnv->setCombine_RGB(osg::TexEnvCombine::ADD);
|
|
|
|
|
|
|
|
texEnv->setSource0_RGB(osg::TexEnvCombine::PREVIOUS);
|
|
|
|
|
|
|
|
texEnv->setSource1_RGB(osg::TexEnvCombine::TEXTURE);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int texUnit = 3; // FIXME
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
osg::StateSet* stateset = node->getOrCreateStateSet();
|
|
|
|
|
|
|
|
stateset->setTextureAttributeAndModes(texUnit, texture2d, osg::StateAttribute::ON);
|
|
|
|
|
|
|
|
stateset->setTextureAttributeAndModes(texUnit, texGen, osg::StateAttribute::ON);
|
|
|
|
|
|
|
|
stateset->setTextureAttributeAndModes(texUnit, texEnv, osg::StateAttribute::ON);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
stateset->addUniform(new osg::Uniform("envMapColor", osg::Vec4f(1,1,1,1)));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Node> handleNode(const Nif::Node* nifNode, osg::Group* parentNode, Resource::ImageManager* imageManager,
|
|
|
|
osg::ref_ptr<osg::Node> handleNode(const Nif::Node* nifNode, osg::Group* parentNode, Resource::ImageManager* imageManager,
|
|
|
|
std::vector<int> boundTextures, int animflags, int particleflags, bool skipMeshes, TextKeyMap* textKeys, osg::Node* rootNode=NULL)
|
|
|
|
std::vector<int> boundTextures, int animflags, int particleflags, bool skipMeshes, TextKeyMap* textKeys, osg::Node* rootNode=NULL)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -582,15 +659,20 @@ namespace NifOsg
|
|
|
|
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(nifNode);
|
|
|
|
const Nif::NiNode *ninode = dynamic_cast<const Nif::NiNode*>(nifNode);
|
|
|
|
if(ninode)
|
|
|
|
if(ninode)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
const Nif::NodeList &effects = ninode->effects;
|
|
|
|
|
|
|
|
for (size_t i = 0; i < effects.length(); ++i)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!effects[i].empty())
|
|
|
|
|
|
|
|
handleEffect(effects[i].getPtr(), node, imageManager);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const Nif::NodeList &children = ninode->children;
|
|
|
|
const Nif::NodeList &children = ninode->children;
|
|
|
|
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(), node, imageManager, boundTextures, animflags, particleflags, skipMeshes, textKeys, rootNode);
|
|
|
|
handleNode(children[i].getPtr(), node, imageManager, boundTextures, animflags, particleflags, skipMeshes, textKeys, rootNode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return node;
|
|
|
|
return node;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -707,8 +789,7 @@ namespace NifOsg
|
|
|
|
wrapT = inherit->getWrap(osg::Texture2D::WRAP_T);
|
|
|
|
wrapT = inherit->getWrap(osg::Texture2D::WRAP_T);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
std::string filename = Misc::ResourceHelpers::correctTexturePath(st->filename, imageManager->getVFS());
|
|
|
|
osg::ref_ptr<osg::Texture2D> texture (new osg::Texture2D(handleSourceTexture(st.getPtr(), imageManager)));
|
|
|
|
osg::ref_ptr<osg::Texture2D> texture (new osg::Texture2D(imageManager->getImage(filename)));
|
|
|
|
|
|
|
|
texture->setWrap(osg::Texture::WRAP_S, wrapS);
|
|
|
|
texture->setWrap(osg::Texture::WRAP_S, wrapS);
|
|
|
|
texture->setWrap(osg::Texture::WRAP_T, wrapT);
|
|
|
|
texture->setWrap(osg::Texture::WRAP_T, wrapT);
|
|
|
|
textures.push_back(texture);
|
|
|
|
textures.push_back(texture);
|
|
|
@ -1318,17 +1399,8 @@ namespace NifOsg
|
|
|
|
std::cerr << "Warning: texture layer " << i << " is in use but empty in " << mFilename << std::endl;
|
|
|
|
std::cerr << "Warning: texture layer " << i << " is in use but empty in " << mFilename << std::endl;
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
osg::ref_ptr<osg::Image> image;
|
|
|
|
|
|
|
|
const Nif::NiSourceTexture *st = tex.texture.getPtr();
|
|
|
|
const Nif::NiSourceTexture *st = tex.texture.getPtr();
|
|
|
|
if (!st->external && !st->data.empty())
|
|
|
|
osg::ref_ptr<osg::Image> image = handleSourceTexture(st, imageManager);
|
|
|
|
{
|
|
|
|
|
|
|
|
image = handleInternalTexture(st->data.getPtr());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
std::string filename = Misc::ResourceHelpers::correctTexturePath(st->filename, imageManager->getVFS());
|
|
|
|
|
|
|
|
image = imageManager->getImage(filename);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsigned int clamp = static_cast<unsigned int>(tex.clamp);
|
|
|
|
unsigned int clamp = static_cast<unsigned int>(tex.clamp);
|
|
|
|
int wrapT = (clamp) & 0x1;
|
|
|
|
int wrapT = (clamp) & 0x1;
|
|
|
|