1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-02-28 16:39:43 +00:00

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->addUniform(new osg::Uniform("colorMode", 0));
stateset->addUniform(new osg::Uniform("emissiveMult", 1.f));
stateset->addUniform(new osg::Uniform("specStrength", 1.f));
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));
sceneRoot->getOrCreateStateSet()->setAttribute(defaultMat);
sceneRoot->getOrCreateStateSet()->addUniform(new osg::Uniform("emissiveMult", 1.f));
sceneRoot->getOrCreateStateSet()->addUniform(new osg::Uniform("specStrength", 1.f));
mFog.reset(new FogManager());

View file

@ -61,7 +61,7 @@ add_component_dir (sceneutil
)
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

View file

@ -270,6 +270,15 @@ namespace Nif
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)
{
defaultVal = nif->getVector3();

View file

@ -184,6 +184,12 @@ struct bhkBlendController : public Controller
void read(NIFStream *nif) override;
};
struct NiControllerManager : public Controller
{
bool mCumulative;
void read(NIFStream *nif) override;
};
struct Interpolator : public Record { };
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)
{
if (nif->getVersion() >= NIFStream::generateVersion(10,1,0,114))

View file

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

View file

@ -94,4 +94,38 @@ void BSBound::read(NIFStream *nif)
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;
};
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
#endif

View file

@ -136,6 +136,11 @@ static std::map<std::string,RecordFactoryEntry> makeFactory()
factory["BSShaderProperty"] = {&construct <BSShaderProperty> , RC_BSShaderProperty };
factory["BSShaderPPLightingProperty"] = {&construct <BSShaderPPLightingProperty> , RC_BSShaderPPLightingProperty };
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;
}

View file

@ -8,6 +8,7 @@
#include "niftypes.hpp"
#include "controller.hpp"
#include "base.hpp"
#include "physics.hpp"
#include <components/misc/stringops.hpp>
@ -143,6 +144,9 @@ struct Node : public Named
bool hasBounds{false};
NiBoundingVolume bounds;
// Collision object info
NiCollisionObjectPtr collision;
void read(NIFStream *nif) override
{
Named::read(nif);
@ -160,7 +164,7 @@ struct Node : public Named
bounds.read(nif);
// Reference to the collision object in Gamebryo files.
if (nif->getVersion() >= NIFStream::generateVersion(10,0,1,0))
nif->skip(4);
collision.read(nif);
parent = nullptr;
@ -171,6 +175,7 @@ struct Node : public Named
{
Named::post(nif);
props.post(nif);
collision.post(nif);
}
// 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_BSShaderProperty,
RC_BSShaderPPLightingProperty,
RC_BSShaderNoLightingProperty
RC_BSShaderNoLightingProperty,
RC_BSFurnitureMarker,
RC_NiCollisionObject,
RC_bhkCollisionObject,
RC_BSDismemberSkinInstance,
RC_NiControllerManager
};
/// Base class for all records

View file

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

View file

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

View file

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

View file

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