mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-04-30 05:47:57 +03:00
Merge remote-tracking branch 'scrawl/master'
This commit is contained in:
commit
eb6e1576be
32 changed files with 419 additions and 229 deletions
|
@ -272,7 +272,7 @@ class NiSkinData : public Record
|
|||
public:
|
||||
struct BoneTrafo
|
||||
{
|
||||
Ogre::Matrix3 rotationScale; // Rotation offset from bone, non-uniform scale
|
||||
Ogre::Matrix3 rotation; // Rotation offset from bone?
|
||||
Ogre::Vector3 trans; // Translation
|
||||
float scale; // Probably scale (always 1)
|
||||
};
|
||||
|
@ -295,7 +295,7 @@ public:
|
|||
|
||||
void read(NIFStream *nif)
|
||||
{
|
||||
trafo.rotationScale = nif->getMatrix3();
|
||||
trafo.rotation = nif->getMatrix3();
|
||||
trafo.trans = nif->getVector3();
|
||||
trafo.scale = nif->getFloat();
|
||||
|
||||
|
@ -307,7 +307,7 @@ public:
|
|||
{
|
||||
BoneInfo &bi = bones[i];
|
||||
|
||||
bi.trafo.rotationScale = nif->getMatrix3();
|
||||
bi.trafo.rotation = nif->getMatrix3();
|
||||
bi.trafo.trans = nif->getVector3();
|
||||
bi.trafo.scale = nif->getFloat();
|
||||
bi.unknown = nif->getVector4();
|
||||
|
|
|
@ -76,7 +76,7 @@ Transformation NIFStream::getTrafo()
|
|||
{
|
||||
Transformation t;
|
||||
t.pos = getVector3();
|
||||
t.rotationScale = getMatrix3();
|
||||
t.rotation = getMatrix3();
|
||||
t.scale = getFloat();
|
||||
return t;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@ namespace Nif
|
|||
struct Transformation
|
||||
{
|
||||
Ogre::Vector3 pos;
|
||||
Ogre::Matrix3 rotationScale;
|
||||
Ogre::Matrix3 rotation;
|
||||
float scale;
|
||||
|
||||
static const Transformation& getIdentity()
|
||||
|
|
|
@ -9,10 +9,11 @@ void Node::getProperties(const Nif::NiTexturingProperty *&texprop,
|
|||
const Nif::NiVertexColorProperty *&vertprop,
|
||||
const Nif::NiZBufferProperty *&zprop,
|
||||
const Nif::NiSpecularProperty *&specprop,
|
||||
const Nif::NiWireframeProperty *&wireprop) const
|
||||
const Nif::NiWireframeProperty *&wireprop,
|
||||
const Nif::NiStencilProperty *&stencilprop) const
|
||||
{
|
||||
if(parent)
|
||||
parent->getProperties(texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop);
|
||||
parent->getProperties(texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop, stencilprop);
|
||||
|
||||
for(size_t i = 0;i < props.length();i++)
|
||||
{
|
||||
|
@ -35,6 +36,8 @@ void Node::getProperties(const Nif::NiTexturingProperty *&texprop,
|
|||
specprop = static_cast<const Nif::NiSpecularProperty*>(pr);
|
||||
else if(pr->recType == Nif::RC_NiWireframeProperty)
|
||||
wireprop = static_cast<const Nif::NiWireframeProperty*>(pr);
|
||||
else if (pr->recType == Nif::RC_NiStencilProperty)
|
||||
stencilprop = static_cast<const Nif::NiStencilProperty*>(pr);
|
||||
else
|
||||
std::cerr<< "Unhandled property type: "<<pr->recName <<std::endl;
|
||||
}
|
||||
|
@ -42,9 +45,8 @@ void Node::getProperties(const Nif::NiTexturingProperty *&texprop,
|
|||
|
||||
Ogre::Matrix4 Node::getLocalTransform() const
|
||||
{
|
||||
Ogre::Matrix4 mat4 = Ogre::Matrix4(trafo.rotationScale);
|
||||
mat4.setTrans(trafo.pos);
|
||||
mat4.setScale(Ogre::Vector3(trafo.rotationScale[0][0], trafo.rotationScale[1][1], trafo.rotationScale[2][2]) * trafo.scale);
|
||||
Ogre::Matrix4 mat4 = Ogre::Matrix4(Ogre::Matrix4::IDENTITY);
|
||||
mat4.makeTransform(trafo.pos, Ogre::Vector3(trafo.scale), Ogre::Quaternion(trafo.rotation));
|
||||
return mat4;
|
||||
}
|
||||
|
||||
|
|
|
@ -98,7 +98,8 @@ public:
|
|||
const Nif::NiVertexColorProperty *&vertprop,
|
||||
const Nif::NiZBufferProperty *&zprop,
|
||||
const Nif::NiSpecularProperty *&specprop,
|
||||
const Nif::NiWireframeProperty *&wireprop) const;
|
||||
const Nif::NiWireframeProperty *&wireprop,
|
||||
const Nif::NiStencilProperty *&stencilprop) const;
|
||||
|
||||
Ogre::Matrix4 getLocalTransform() const;
|
||||
Ogre::Matrix4 getWorldTransform() const;
|
||||
|
|
|
@ -54,6 +54,28 @@ static const char *getTestMode(int mode)
|
|||
return "less_equal";
|
||||
}
|
||||
|
||||
static void setTextureProperties(sh::MaterialInstance* material, const std::string& textureSlotName, const Nif::NiTexturingProperty::Texture& tex)
|
||||
{
|
||||
material->setProperty(textureSlotName + "UVSet", sh::makeProperty(new sh::IntValue(tex.uvSet)));
|
||||
const std::string clampMode = textureSlotName + "ClampMode";
|
||||
switch (tex.clamp)
|
||||
{
|
||||
case 0:
|
||||
material->setProperty(clampMode, sh::makeProperty(new sh::StringValue("clamp clamp")));
|
||||
break;
|
||||
case 1:
|
||||
material->setProperty(clampMode, sh::makeProperty(new sh::StringValue("clamp wrap")));
|
||||
break;
|
||||
case 2:
|
||||
material->setProperty(clampMode, sh::makeProperty(new sh::StringValue("wrap clamp")));
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
material->setProperty(clampMode, sh::makeProperty(new sh::StringValue("wrap wrap")));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ogre::String NIFMaterialLoader::getMaterial(const Nif::ShapeData *shapedata,
|
||||
const Ogre::String &name, const Ogre::String &group,
|
||||
const Nif::NiTexturingProperty *texprop,
|
||||
|
@ -63,6 +85,7 @@ Ogre::String NIFMaterialLoader::getMaterial(const Nif::ShapeData *shapedata,
|
|||
const Nif::NiZBufferProperty *zprop,
|
||||
const Nif::NiSpecularProperty *specprop,
|
||||
const Nif::NiWireframeProperty *wireprop,
|
||||
const Nif::NiStencilProperty *stencilprop,
|
||||
bool &needTangents, bool particleMaterial)
|
||||
{
|
||||
Ogre::MaterialManager &matMgr = Ogre::MaterialManager::getSingleton();
|
||||
|
@ -84,6 +107,7 @@ Ogre::String NIFMaterialLoader::getMaterial(const Nif::ShapeData *shapedata,
|
|||
// Default should be 1, but Bloodmoon's models are broken
|
||||
int specFlags = 0;
|
||||
int wireFlags = 0;
|
||||
int drawMode = 1;
|
||||
Ogre::String texName[7];
|
||||
|
||||
bool vertexColour = (shapedata->colors.size() != 0);
|
||||
|
@ -183,6 +207,20 @@ Ogre::String NIFMaterialLoader::getMaterial(const Nif::ShapeData *shapedata,
|
|||
}
|
||||
}
|
||||
|
||||
if(stencilprop)
|
||||
{
|
||||
drawMode = stencilprop->data.drawMode;
|
||||
if (stencilprop->data.enabled)
|
||||
warn("Unhandled stencil test in "+name);
|
||||
|
||||
Nif::ControllerPtr ctrls = stencilprop->controller;
|
||||
while(!ctrls.empty())
|
||||
{
|
||||
warn("Unhandled stencil controller "+ctrls->recName+" in "+name);
|
||||
ctrls = ctrls->next;
|
||||
}
|
||||
}
|
||||
|
||||
// Material
|
||||
if(matprop)
|
||||
{
|
||||
|
@ -227,8 +265,13 @@ Ogre::String NIFMaterialLoader::getMaterial(const Nif::ShapeData *shapedata,
|
|||
for(int i = 0;i < 7;i++)
|
||||
{
|
||||
if(!texName[i].empty())
|
||||
{
|
||||
boost::hash_combine(h, texName[i]);
|
||||
boost::hash_combine(h, texprop->textures[i].clamp);
|
||||
boost::hash_combine(h, texprop->textures[i].uvSet);
|
||||
}
|
||||
}
|
||||
boost::hash_combine(h, drawMode);
|
||||
boost::hash_combine(h, vertexColour);
|
||||
boost::hash_combine(h, alphaFlags);
|
||||
boost::hash_combine(h, alphaTest);
|
||||
|
@ -286,6 +329,13 @@ Ogre::String NIFMaterialLoader::getMaterial(const Nif::ShapeData *shapedata,
|
|||
instance->setProperty("polygon_mode", sh::makeProperty(new sh::StringValue("wireframe")));
|
||||
}
|
||||
|
||||
if (drawMode == 1)
|
||||
instance->setProperty("cullmode", sh::makeProperty(new sh::StringValue("clockwise")));
|
||||
else if (drawMode == 2)
|
||||
instance->setProperty("cullmode", sh::makeProperty(new sh::StringValue("anticlockwise")));
|
||||
else if (drawMode == 3)
|
||||
instance->setProperty("cullmode", sh::makeProperty(new sh::StringValue("none")));
|
||||
|
||||
instance->setProperty("diffuseMap", sh::makeProperty(texName[Nif::NiTexturingProperty::BaseTexture]));
|
||||
instance->setProperty("normalMap", sh::makeProperty(texName[Nif::NiTexturingProperty::BumpTexture]));
|
||||
instance->setProperty("detailMap", sh::makeProperty(texName[Nif::NiTexturingProperty::DetailTexture]));
|
||||
|
@ -294,22 +344,22 @@ Ogre::String NIFMaterialLoader::getMaterial(const Nif::ShapeData *shapedata,
|
|||
if (!texName[Nif::NiTexturingProperty::BaseTexture].empty())
|
||||
{
|
||||
instance->setProperty("use_diffuse_map", sh::makeProperty(new sh::BooleanValue(true)));
|
||||
instance->setProperty("diffuseMapUVSet", sh::makeProperty(new sh::IntValue(texprop->textures[Nif::NiTexturingProperty::BaseTexture].uvSet)));
|
||||
setTextureProperties(instance, "diffuseMap", texprop->textures[Nif::NiTexturingProperty::BaseTexture]);
|
||||
}
|
||||
if (!texName[Nif::NiTexturingProperty::GlowTexture].empty())
|
||||
{
|
||||
instance->setProperty("use_emissive_map", sh::makeProperty(new sh::BooleanValue(true)));
|
||||
instance->setProperty("emissiveMapUVSet", sh::makeProperty(new sh::IntValue(texprop->textures[Nif::NiTexturingProperty::GlowTexture].uvSet)));
|
||||
setTextureProperties(instance, "emissiveMap", texprop->textures[Nif::NiTexturingProperty::GlowTexture]);
|
||||
}
|
||||
if (!texName[Nif::NiTexturingProperty::DetailTexture].empty())
|
||||
{
|
||||
instance->setProperty("use_detail_map", sh::makeProperty(new sh::BooleanValue(true)));
|
||||
instance->setProperty("detailMapUVSet", sh::makeProperty(new sh::IntValue(texprop->textures[Nif::NiTexturingProperty::DetailTexture].uvSet)));
|
||||
setTextureProperties(instance, "detailMap", texprop->textures[Nif::NiTexturingProperty::DetailTexture]);
|
||||
}
|
||||
if (!texName[Nif::NiTexturingProperty::DarkTexture].empty())
|
||||
{
|
||||
instance->setProperty("use_dark_map", sh::makeProperty(new sh::BooleanValue(true)));
|
||||
instance->setProperty("darkMapUVSet", sh::makeProperty(new sh::IntValue(texprop->textures[Nif::NiTexturingProperty::DarkTexture].uvSet)));
|
||||
setTextureProperties(instance, "darkMap", texprop->textures[Nif::NiTexturingProperty::DarkTexture]);
|
||||
}
|
||||
|
||||
bool useParallax = !texName[Nif::NiTexturingProperty::BumpTexture].empty()
|
||||
|
@ -332,7 +382,7 @@ Ogre::String NIFMaterialLoader::getMaterial(const Nif::ShapeData *shapedata,
|
|||
instance->setProperty("has_vertex_colour", sh::makeProperty(new sh::BooleanValue(true)));
|
||||
|
||||
// Override alpha flags based on our override list (transparency-overrides.cfg)
|
||||
if (!texName[0].empty())
|
||||
if ((alphaFlags&1) && !texName[0].empty())
|
||||
{
|
||||
NifOverrides::TransparencyResult result = NifOverrides::Overrides::getTransparencyOverride(texName[0]);
|
||||
if (result.first)
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace Nif
|
|||
class NiZBufferProperty;
|
||||
class NiSpecularProperty;
|
||||
class NiWireframeProperty;
|
||||
class NiStencilProperty;
|
||||
}
|
||||
|
||||
namespace NifOgre
|
||||
|
@ -41,6 +42,7 @@ public:
|
|||
const Nif::NiZBufferProperty *zprop,
|
||||
const Nif::NiSpecularProperty *specprop,
|
||||
const Nif::NiWireframeProperty *wireprop,
|
||||
const Nif::NiStencilProperty *stencilprop,
|
||||
bool &needTangents, bool particleMaterial=false);
|
||||
};
|
||||
|
||||
|
|
|
@ -138,10 +138,9 @@ void NIFMeshLoader::createSubMesh(Ogre::Mesh *mesh, const Nif::NiTriShape *shape
|
|||
const Nif::NodeList &bones = skin->bones;
|
||||
for(size_t b = 0;b < bones.length();b++)
|
||||
{
|
||||
const Ogre::Matrix3& rotationScale = data->bones[b].trafo.rotationScale;
|
||||
Ogre::Matrix4 mat (rotationScale);
|
||||
mat.setTrans(data->bones[b].trafo.trans);
|
||||
mat.setScale(Ogre::Vector3(rotationScale[0][0], rotationScale[1][1], rotationScale[2][2]) * data->bones[b].trafo.scale);
|
||||
Ogre::Matrix4 mat;
|
||||
mat.makeTransform(data->bones[b].trafo.trans, Ogre::Vector3(data->bones[b].trafo.scale),
|
||||
Ogre::Quaternion(data->bones[b].trafo.rotation));
|
||||
mat = bones[b]->getWorldTransform() * mat;
|
||||
|
||||
const std::vector<Nif::NiSkinData::VertWeight> &weights = data->bones[b].weights;
|
||||
|
@ -321,13 +320,14 @@ void NIFMeshLoader::createSubMesh(Ogre::Mesh *mesh, const Nif::NiTriShape *shape
|
|||
const Nif::NiZBufferProperty *zprop = NULL;
|
||||
const Nif::NiSpecularProperty *specprop = NULL;
|
||||
const Nif::NiWireframeProperty *wireprop = NULL;
|
||||
const Nif::NiStencilProperty *stencilprop = NULL;
|
||||
bool needTangents = false;
|
||||
|
||||
shape->getProperties(texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop);
|
||||
shape->getProperties(texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop, stencilprop);
|
||||
std::string matname = NIFMaterialLoader::getMaterial(data, mesh->getName(), mGroup,
|
||||
texprop, matprop, alphaprop,
|
||||
vertprop, zprop, specprop,
|
||||
wireprop, needTangents);
|
||||
wireprop, stencilprop, needTangents);
|
||||
if(matname.length() > 0)
|
||||
sub->setMaterialName(matname);
|
||||
|
||||
|
|
|
@ -732,7 +732,8 @@ class NIFObjectLoader
|
|||
const Nif::NiZBufferProperty *zprop = NULL;
|
||||
const Nif::NiSpecularProperty *specprop = NULL;
|
||||
const Nif::NiWireframeProperty *wireprop = NULL;
|
||||
node->getProperties(texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop);
|
||||
const Nif::NiStencilProperty *stencilprop = NULL;
|
||||
node->getProperties(texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop, stencilprop);
|
||||
|
||||
Ogre::ControllerValueRealPtr srcval((animflags&Nif::NiNode::AnimFlag_AutoPlay) ?
|
||||
Ogre::ControllerManager::getSingleton().getFrameTimeSource() :
|
||||
|
@ -889,13 +890,14 @@ class NIFObjectLoader
|
|||
const Nif::NiZBufferProperty *zprop = NULL;
|
||||
const Nif::NiSpecularProperty *specprop = NULL;
|
||||
const Nif::NiWireframeProperty *wireprop = NULL;
|
||||
const Nif::NiStencilProperty *stencilprop = NULL;
|
||||
bool needTangents = false;
|
||||
|
||||
partnode->getProperties(texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop);
|
||||
partnode->getProperties(texprop, matprop, alphaprop, vertprop, zprop, specprop, wireprop, stencilprop);
|
||||
partsys->setMaterialName(NIFMaterialLoader::getMaterial(particledata, fullname, group,
|
||||
texprop, matprop, alphaprop,
|
||||
vertprop, zprop, specprop,
|
||||
wireprop, needTangents,
|
||||
wireprop, stencilprop, needTangents,
|
||||
// MW doesn't light particles, but the MaterialProperty
|
||||
// used still has lighting, so that must be ignored.
|
||||
true));
|
||||
|
|
|
@ -36,17 +36,9 @@ void NIFSkeletonLoader::buildBones(Ogre::Skeleton *skel, const Nif::Node *node,
|
|||
if(parent) parent->addChild(bone);
|
||||
mNifToOgreHandleMap[node->recIndex] = bone->getHandle();
|
||||
|
||||
// decompose the local transform into position, scale and orientation.
|
||||
// this is required for cases where the rotationScale matrix includes scaling, which the NIF format allows :(
|
||||
// the code would look a bit nicer if Ogre allowed setting the transform matrix of a Bone directly, but we can't do that.
|
||||
Ogre::Matrix4 mat(node->getLocalTransform());
|
||||
Ogre::Vector3 position, scale;
|
||||
Ogre::Quaternion orientation;
|
||||
mat.decomposition(position, scale, orientation);
|
||||
bone->setOrientation(orientation);
|
||||
bone->setPosition(position);
|
||||
bone->setScale(scale);
|
||||
|
||||
bone->setOrientation(node->trafo.rotation);
|
||||
bone->setPosition(node->trafo.pos);
|
||||
bone->setScale(Ogre::Vector3(node->trafo.scale));
|
||||
bone->setBindingPose();
|
||||
|
||||
if(!(node->recType == Nif::RC_NiNode || /* Nothing special; children traversed below */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue