mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-02-23 15:40:42 +00:00
Support Fallout 4 skinning
Convert the skinning data into NiSkinData-compatible format
This commit is contained in:
parent
b9d42946be
commit
284129b9ec
@ -426,6 +426,8 @@ namespace Nif
|
|||||||
mSkin.post(nif);
|
mSkin.post(nif);
|
||||||
mShaderProperty.post(nif);
|
mShaderProperty.post(nif);
|
||||||
mAlphaProperty.post(nif);
|
mAlphaProperty.post(nif);
|
||||||
|
if (!mSkin.empty())
|
||||||
|
nif.setUseSkinning(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BSDynamicTriShape::read(NIFStream* nif)
|
void BSDynamicTriShape::read(NIFStream* nif)
|
||||||
|
@ -1572,6 +1572,8 @@ namespace NifOsg
|
|||||||
geometry->addPrimitiveSet(
|
geometry->addPrimitiveSet(
|
||||||
new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, triangles.size(), triangles.data()));
|
new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, triangles.size(), triangles.data()));
|
||||||
|
|
||||||
|
osg::ref_ptr<osg::Drawable> drawable = geometry;
|
||||||
|
|
||||||
auto normbyteToFloat = [](uint8_t value) { return value / 255.f * 2.f - 1.f; };
|
auto normbyteToFloat = [](uint8_t value) { return value / 255.f * 2.f - 1.f; };
|
||||||
auto halfToFloat = [](uint16_t value) {
|
auto halfToFloat = [](uint16_t value) {
|
||||||
uint32_t bits = static_cast<uint32_t>(value & 0x8000) << 16;
|
uint32_t bits = static_cast<uint32_t>(value & 0x8000) << 16;
|
||||||
@ -1639,6 +1641,39 @@ namespace NifOsg
|
|||||||
geometry->setTexCoordArray(
|
geometry->setTexCoordArray(
|
||||||
0, new osg::Vec2Array(uvlist.size(), uvlist.data()), osg::Array::BIND_PER_VERTEX);
|
0, new osg::Vec2Array(uvlist.size(), uvlist.data()), osg::Array::BIND_PER_VERTEX);
|
||||||
|
|
||||||
|
if (!bsTriShape->mSkin.empty() && bsTriShape->mSkin->recType == Nif::RC_BSSkinInstance
|
||||||
|
&& bsTriShape->mVertDesc.mFlags & Nif::BSVertexDesc::VertexAttribute::Skinned)
|
||||||
|
{
|
||||||
|
osg::ref_ptr<SceneUtil::RigGeometry> rig(new SceneUtil::RigGeometry);
|
||||||
|
rig->setSourceGeometry(geometry);
|
||||||
|
|
||||||
|
osg::ref_ptr<SceneUtil::RigGeometry::InfluenceMap> map(new SceneUtil::RigGeometry::InfluenceMap);
|
||||||
|
|
||||||
|
auto skin = static_cast<const Nif::BSSkinInstance*>(bsTriShape->mSkin.getPtr());
|
||||||
|
const Nif::BSSkinBoneData* data = skin->mData.getPtr();
|
||||||
|
const Nif::NiAVObjectList& bones = skin->mBones;
|
||||||
|
std::vector<std::vector<Nif::NiSkinData::VertWeight>> vertWeights(data->mBones.size());
|
||||||
|
for (size_t i = 0; i < vertices.size(); i++)
|
||||||
|
for (int j = 0; j < 4; j++)
|
||||||
|
vertWeights[bsTriShape->mVertData[i].mBoneIndices[j]].emplace_back(
|
||||||
|
i, halfToFloat(bsTriShape->mVertData[i].mBoneWeights[j]));
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < bones.size(); ++i)
|
||||||
|
{
|
||||||
|
std::string boneName = Misc::StringUtils::lowerCase(bones[i].getPtr()->mName);
|
||||||
|
|
||||||
|
SceneUtil::RigGeometry::BoneInfluence influence;
|
||||||
|
influence.mWeights = vertWeights[i];
|
||||||
|
influence.mInvBindMatrix = data->mBones[i].mTransform.toMatrix();
|
||||||
|
influence.mBoundSphere = data->mBones[i].mBoundSphere;
|
||||||
|
|
||||||
|
map->mData.emplace_back(boneName, influence);
|
||||||
|
}
|
||||||
|
rig->setInfluenceMap(map);
|
||||||
|
|
||||||
|
drawable = rig;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<const Nif::NiProperty*> drawableProps;
|
std::vector<const Nif::NiProperty*> drawableProps;
|
||||||
collectDrawableProperties(nifNode, parent, drawableProps);
|
collectDrawableProperties(nifNode, parent, drawableProps);
|
||||||
if (!bsTriShape->mShaderProperty.empty())
|
if (!bsTriShape->mShaderProperty.empty())
|
||||||
@ -1647,8 +1682,8 @@ namespace NifOsg
|
|||||||
drawableProps.emplace_back(bsTriShape->mAlphaProperty.getPtr());
|
drawableProps.emplace_back(bsTriShape->mAlphaProperty.getPtr());
|
||||||
applyDrawableProperties(parentNode, drawableProps, composite, !colors.empty(), animflags);
|
applyDrawableProperties(parentNode, drawableProps, composite, !colors.empty(), animflags);
|
||||||
|
|
||||||
geometry->setName(nifNode->mName);
|
drawable->setName(nifNode->mName);
|
||||||
parentNode->addChild(geometry);
|
parentNode->addChild(drawable);
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::BlendFunc::BlendFuncMode getBlendMode(int mode)
|
osg::BlendFunc::BlendFuncMode getBlendMode(int mode)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user