Merge branch 'buyskyrimanniversaryedition' into 'master'

Boring NIF stuff

See merge request OpenMW/openmw!1378
This commit is contained in:
psi29a 2021-11-12 19:47:37 +00:00
commit 3ade72a7ad
19 changed files with 264 additions and 4 deletions

View File

@ -359,6 +359,7 @@ namespace MWRender
stateset->setAttribute(m); stateset->setAttribute(m);
stateset->addUniform(new osg::Uniform("colorMode", 0)); stateset->addUniform(new osg::Uniform("colorMode", 0));
stateset->addUniform(new osg::Uniform("emissiveMult", 1.f)); stateset->addUniform(new osg::Uniform("emissiveMult", 1.f));
stateset->addUniform(new osg::Uniform("specStrength", 1.f));
node.setStateSet(stateset); node.setStateSet(stateset);
} }
}; };

View File

@ -500,6 +500,7 @@ namespace MWRender
defaultMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 0.f)); defaultMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4f(0.f, 0.f, 0.f, 0.f));
sceneRoot->getOrCreateStateSet()->setAttribute(defaultMat); sceneRoot->getOrCreateStateSet()->setAttribute(defaultMat);
sceneRoot->getOrCreateStateSet()->addUniform(new osg::Uniform("emissiveMult", 1.f)); sceneRoot->getOrCreateStateSet()->addUniform(new osg::Uniform("emissiveMult", 1.f));
sceneRoot->getOrCreateStateSet()->addUniform(new osg::Uniform("specStrength", 1.f));
mFog.reset(new FogManager()); mFog.reset(new FogManager());

View File

@ -61,7 +61,7 @@ add_component_dir (sceneutil
) )
add_component_dir (nif add_component_dir (nif
controlled effect niftypes record controller extra node record_ptr data niffile property nifkey base nifstream controlled effect niftypes record controller extra node record_ptr data niffile property nifkey base nifstream physics
) )
add_component_dir (nifosg add_component_dir (nifosg

View File

@ -270,6 +270,15 @@ namespace Nif
nif->getUInt(); // Zero nif->getUInt(); // Zero
} }
void NiControllerManager::read(NIFStream *nif)
{
Controller::read(nif);
mCumulative = nif->getBoolean();
unsigned int numSequences = nif->getUInt();
nif->skip(4 * numSequences); // Controller sequences
nif->skip(4); // Object palette
}
void NiPoint3Interpolator::read(NIFStream *nif) void NiPoint3Interpolator::read(NIFStream *nif)
{ {
defaultVal = nif->getVector3(); defaultVal = nif->getVector3();

View File

@ -184,6 +184,12 @@ struct bhkBlendController : public Controller
void read(NIFStream *nif) override; void read(NIFStream *nif) override;
}; };
struct NiControllerManager : public Controller
{
bool mCumulative;
void read(NIFStream *nif) override;
};
struct Interpolator : public Record { }; struct Interpolator : public Record { };
struct NiPoint3Interpolator : public Interpolator struct NiPoint3Interpolator : public Interpolator

View File

@ -34,6 +34,13 @@ void NiSkinInstance::post(NIFFile *nif)
} }
} }
void BSDismemberSkinInstance::read(NIFStream *nif)
{
NiSkinInstance::read(nif);
unsigned int numPartitions = nif->getUInt();
nif->skip(4 * numPartitions); // Body part information
}
void NiGeometryData::read(NIFStream *nif) void NiGeometryData::read(NIFStream *nif)
{ {
if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,114)) if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,114))

View File

@ -170,6 +170,11 @@ struct NiSkinInstance : public Record
void post(NIFFile *nif) override; void post(NIFFile *nif) override;
}; };
struct BSDismemberSkinInstance : public NiSkinInstance
{
void read(NIFStream *nif) override;
};
struct NiSkinData : public Record struct NiSkinData : public Record
{ {
struct VertWeight struct VertWeight

View File

@ -94,4 +94,38 @@ void BSBound::read(NIFStream *nif)
halfExtents = nif->getVector3(); halfExtents = nif->getVector3();
} }
void BSFurnitureMarker::LegacyFurniturePosition::read(NIFStream *nif)
{
mOffset = nif->getVector3();
mOrientation = nif->getUShort();
mPositionRef = nif->getChar();
nif->skip(1); // Position ref 2
}
void BSFurnitureMarker::FurniturePosition::read(NIFStream *nif)
{
mOffset = nif->getVector3();
mHeading = nif->getFloat();
mType = nif->getUShort();
mEntryPoint = nif->getUShort();
}
void BSFurnitureMarker::read(NIFStream *nif)
{
Extra::read(nif);
unsigned int num = nif->getUInt();
if (nif->getBethVersion() <= NIFFile::BethVersion::BETHVER_FO3)
{
mLegacyMarkers.resize(num);
for (auto& marker : mLegacyMarkers)
marker.read(nif);
}
else
{
mMarkers.resize(num);
for (auto& marker : mMarkers)
marker.read(nif);
}
}
} }

View File

@ -120,5 +120,30 @@ struct BSBound : public Extra
void read(NIFStream *nif) override; void read(NIFStream *nif) override;
}; };
struct BSFurnitureMarker : public Extra
{
struct LegacyFurniturePosition
{
osg::Vec3f mOffset;
uint16_t mOrientation;
uint8_t mPositionRef;
void read(NIFStream *nif);
};
struct FurniturePosition
{
osg::Vec3f mOffset;
float mHeading;
uint16_t mType;
uint16_t mEntryPoint;
void read(NIFStream *nif);
};
std::vector<LegacyFurniturePosition> mLegacyMarkers;
std::vector<FurniturePosition> mMarkers;
void read(NIFStream *nif) override;
};
} // Namespace } // Namespace
#endif #endif

View File

@ -136,6 +136,11 @@ static std::map<std::string,RecordFactoryEntry> makeFactory()
factory["BSShaderProperty"] = {&construct <BSShaderProperty> , RC_BSShaderProperty }; factory["BSShaderProperty"] = {&construct <BSShaderProperty> , RC_BSShaderProperty };
factory["BSShaderPPLightingProperty"] = {&construct <BSShaderPPLightingProperty> , RC_BSShaderPPLightingProperty }; factory["BSShaderPPLightingProperty"] = {&construct <BSShaderPPLightingProperty> , RC_BSShaderPPLightingProperty };
factory["BSShaderNoLightingProperty"] = {&construct <BSShaderNoLightingProperty> , RC_BSShaderNoLightingProperty }; factory["BSShaderNoLightingProperty"] = {&construct <BSShaderNoLightingProperty> , RC_BSShaderNoLightingProperty };
factory["BSFurnitureMarker"] = {&construct <BSFurnitureMarker> , RC_BSFurnitureMarker };
factory["NiCollisionObject"] = {&construct <NiCollisionObject> , RC_NiCollisionObject };
factory["bhkCollisionObject"] = {&construct <bhkCollisionObject> , RC_bhkCollisionObject };
factory["BSDismemberSkinInstance"] = {&construct <BSDismemberSkinInstance> , RC_BSDismemberSkinInstance };
factory["NiControllerManager"] = {&construct <NiControllerManager> , RC_NiControllerManager };
return factory; return factory;
} }

View File

@ -8,6 +8,7 @@
#include "niftypes.hpp" #include "niftypes.hpp"
#include "controller.hpp" #include "controller.hpp"
#include "base.hpp" #include "base.hpp"
#include "physics.hpp"
#include <components/misc/stringops.hpp> #include <components/misc/stringops.hpp>
@ -143,6 +144,9 @@ struct Node : public Named
bool hasBounds{false}; bool hasBounds{false};
NiBoundingVolume bounds; NiBoundingVolume bounds;
// Collision object info
NiCollisionObjectPtr collision;
void read(NIFStream *nif) override void read(NIFStream *nif) override
{ {
Named::read(nif); Named::read(nif);
@ -160,7 +164,7 @@ struct Node : public Named
bounds.read(nif); bounds.read(nif);
// Reference to the collision object in Gamebryo files. // Reference to the collision object in Gamebryo files.
if (nif->getVersion() >= NIFStream::generateVersion(10,0,1,0)) if (nif->getVersion() >= NIFStream::generateVersion(10,0,1,0))
nif->skip(4); collision.read(nif);
parent = nullptr; parent = nullptr;
@ -171,6 +175,7 @@ struct Node : public Named
{ {
Named::post(nif); Named::post(nif);
props.post(nif); props.post(nif);
collision.post(nif);
} }
// Parent node, or nullptr for the root node. As far as I'm aware, only // Parent node, or nullptr for the root node. As far as I'm aware, only

View File

@ -0,0 +1,54 @@
#include "physics.hpp"
#include "node.hpp"
namespace Nif
{
void bhkCollisionObject::read(NIFStream *nif)
{
NiCollisionObject::read(nif);
mFlags = nif->getUShort();
mBody.read(nif);
}
void bhkWorldObject::read(NIFStream *nif)
{
mShape.read(nif);
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB_OLD)
nif->skip(4); // Unknown
mFlags = nif->getUInt();
nif->skip(4); // Unused
mWorldObjectInfo.mPhaseType = nif->getChar();
nif->skip(3); // Unused
mWorldObjectInfo.mData = nif->getUInt();
mWorldObjectInfo.mSize = nif->getUInt();
mWorldObjectInfo.mCapacityAndFlags = nif->getUInt();
}
void bhkWorldObject::post(NIFFile *nif)
{
mShape.post(nif);
}
void bhkEntity::read(NIFStream *nif)
{
bhkWorldObject::read(nif);
mResponseType = static_cast<hkResponseType>(nif->getChar());
nif->skip(1); // Unused
mProcessContactDelay = nif->getUShort();
}
void HavokMaterial::read(NIFStream *nif)
{
if (nif->getVersion() <= NIFFile::NIFVersion::VER_OB_OLD)
nif->skip(4); // Unknown
mMaterial = nif->getUInt();
}
void hkSubPartData::read(NIFStream *nif)
{
mHavokFilter = nif->getUInt();
mNumVertices = nif->getUInt();
mHavokMaterial.read(nif);
}
} // Namespace

View File

@ -0,0 +1,90 @@
#ifndef OPENMW_COMPONENTS_NIF_PHYSICS_HPP
#define OPENMW_COMPONENTS_NIF_PHYSICS_HPP
#include "base.hpp"
// This header contains certain record definitions
// specific to Bethesda implementation of Havok physics
namespace Nif
{
// Generic collision object
struct NiCollisionObject : public Record
{
// The node that references this object
NodePtr mTarget;
void read(NIFStream *nif) override
{
mTarget.read(nif);
}
void post(NIFFile *nif) override
{
mTarget.post(nif);
}
};
// Bethesda Havok-specific collision object
struct bhkCollisionObject : public NiCollisionObject
{
unsigned short mFlags;
CollisionBodyPtr mBody;
void read(NIFStream *nif) override;
void post(NIFFile *nif) override
{
NiCollisionObject::post(nif);
mBody.post(nif);
}
};
// Abstract Havok shape info record
struct bhkWorldObject : public Record
{
bhkShapePtr mShape;
unsigned int mFlags; // Havok layer type, collision filter flags and group
struct WorldObjectInfo
{
unsigned char mPhaseType;
unsigned int mData;
unsigned int mSize;
unsigned int mCapacityAndFlags;
};
WorldObjectInfo mWorldObjectInfo;
void read(NIFStream *nif) override;
void post(NIFFile *nif) override;
};
struct bhkShape : public Record {};
enum class hkResponseType : uint8_t
{
Response_Invalid = 0,
Response_SimpleContact = 1,
Response_Reporting = 2,
Response_None = 3
};
struct bhkEntity : public bhkWorldObject
{
hkResponseType mResponseType;
unsigned short mProcessContactDelay;
void read(NIFStream *nif) override;
};
struct HavokMaterial
{
unsigned int mMaterial;
void read(NIFStream *nif);
};
struct hkSubPartData
{
HavokMaterial mHavokMaterial;
unsigned int mNumVertices;
unsigned int mHavokFilter;
void read(NIFStream *nif);
};
} // Namespace
#endif

View File

@ -125,7 +125,12 @@ enum RecordType
RC_BSLODTriShape, RC_BSLODTriShape,
RC_BSShaderProperty, RC_BSShaderProperty,
RC_BSShaderPPLightingProperty, RC_BSShaderPPLightingProperty,
RC_BSShaderNoLightingProperty RC_BSShaderNoLightingProperty,
RC_BSFurnitureMarker,
RC_NiCollisionObject,
RC_bhkCollisionObject,
RC_BSDismemberSkinInstance,
RC_NiControllerManager
}; };
/// Base class for all records /// Base class for all records

View File

@ -148,6 +148,9 @@ struct BSShaderTextureSet;
struct NiGeometryData; struct NiGeometryData;
struct BSShaderProperty; struct BSShaderProperty;
struct NiAlphaProperty; struct NiAlphaProperty;
struct NiCollisionObject;
struct bhkWorldObject;
struct bhkShape;
using NodePtr = RecordPtrT<Node>; using NodePtr = RecordPtrT<Node>;
using ExtraPtr = RecordPtrT<Extra>; using ExtraPtr = RecordPtrT<Extra>;
@ -175,6 +178,9 @@ using BSShaderTextureSetPtr = RecordPtrT<BSShaderTextureSet>;
using NiGeometryDataPtr = RecordPtrT<NiGeometryData>; using NiGeometryDataPtr = RecordPtrT<NiGeometryData>;
using BSShaderPropertyPtr = RecordPtrT<BSShaderProperty>; using BSShaderPropertyPtr = RecordPtrT<BSShaderProperty>;
using NiAlphaPropertyPtr = RecordPtrT<NiAlphaProperty>; using NiAlphaPropertyPtr = RecordPtrT<NiAlphaProperty>;
using NiCollisionObjectPtr = RecordPtrT<NiCollisionObject>;
using CollisionBodyPtr = RecordPtrT<bhkWorldObject>;
using bhkShapePtr = RecordPtrT<bhkShape>;
using NodeList = RecordListT<Node>; using NodeList = RecordListT<Node>;
using PropertyList = RecordListT<Property>; using PropertyList = RecordListT<Property>;

View File

@ -1932,6 +1932,7 @@ namespace NifOsg
int lightmode = 1; int lightmode = 1;
float emissiveMult = 1.f; float emissiveMult = 1.f;
float specStrength = 1.f;
for (const Nif::Property* property : properties) for (const Nif::Property* property : properties)
{ {
@ -2081,6 +2082,8 @@ namespace NifOsg
stateset->setAttributeAndModes(mat, osg::StateAttribute::ON); stateset->setAttributeAndModes(mat, osg::StateAttribute::ON);
if (emissiveMult != 1.f) if (emissiveMult != 1.f)
stateset->addUniform(new osg::Uniform("emissiveMult", emissiveMult)); stateset->addUniform(new osg::Uniform("emissiveMult", emissiveMult));
if (specStrength != 1.f)
stateset->addUniform(new osg::Uniform("specStrength", specStrength));
} }
}; };

View File

@ -524,6 +524,7 @@ namespace Resource
result.getNode()->accept(colladaAlphaTrickVisitor); result.getNode()->accept(colladaAlphaTrickVisitor);
result.getNode()->getOrCreateStateSet()->addUniform(new osg::Uniform("emissiveMult", 1.f)); result.getNode()->getOrCreateStateSet()->addUniform(new osg::Uniform("emissiveMult", 1.f));
result.getNode()->getOrCreateStateSet()->addUniform(new osg::Uniform("specStrength", 1.f));
result.getNode()->getOrCreateStateSet()->addUniform(new osg::Uniform("envMapColor", osg::Vec4f(1,1,1,1))); result.getNode()->getOrCreateStateSet()->addUniform(new osg::Uniform("envMapColor", osg::Vec4f(1,1,1,1)));
result.getNode()->getOrCreateStateSet()->addUniform(new osg::Uniform("useFalloff", false)); result.getNode()->getOrCreateStateSet()->addUniform(new osg::Uniform("useFalloff", false));
} }

View File

@ -39,6 +39,7 @@ varying vec3 passNormal;
#include "alpha.glsl" #include "alpha.glsl"
uniform float emissiveMult; uniform float emissiveMult;
uniform float specStrength;
void main() void main()
{ {
@ -80,7 +81,7 @@ void main()
gl_FragData[0].xyz *= lighting; gl_FragData[0].xyz *= lighting;
float shininess = gl_FrontMaterial.shininess; float shininess = gl_FrontMaterial.shininess;
vec3 matSpec = getSpecularColor().xyz; vec3 matSpec = getSpecularColor().xyz * specStrength;
#if @normalMap #if @normalMap
matSpec *= normalTex.a; matSpec *= normalTex.a;
#endif #endif

View File

@ -71,6 +71,7 @@ centroid varying vec3 shadowDiffuseLighting;
#else #else
uniform float emissiveMult; uniform float emissiveMult;
#endif #endif
uniform float specStrength;
varying vec3 passViewPos; varying vec3 passViewPos;
varying vec3 passNormal; varying vec3 passNormal;
@ -204,6 +205,7 @@ void main()
vec3 matSpec = getSpecularColor().xyz; vec3 matSpec = getSpecularColor().xyz;
#endif #endif
matSpec *= specStrength;
if (matSpec != vec3(0.0)) if (matSpec != vec3(0.0))
{ {
#if (!@normalMap && !@parallax && !@forcePPL) #if (!@normalMap && !@parallax && !@forcePPL)