Merge branch 'mantlingtalos' into 'master'

Copy triangle data from NiSkinPartition, a.k.a. SKYRIM TREES

See merge request OpenMW/openmw!3235
revert-6246b479
psi29a 1 year ago
commit 466b2f1b74

@ -446,6 +446,39 @@ namespace Nif
}
}
std::vector<unsigned short> NiSkinPartition::Partition::getTrueTriangles() const
{
if (!trueTriangles.empty())
return trueTriangles;
std::vector<unsigned short> remappedTriangles;
if (vertexMap.empty() || triangles.empty())
return remappedTriangles;
remappedTriangles = triangles;
for (unsigned short& index : remappedTriangles)
index = vertexMap[index];
return remappedTriangles;
}
std::vector<std::vector<unsigned short>> NiSkinPartition::Partition::getTrueStrips() const
{
if (!trueTriangles.empty())
return {};
std::vector<std::vector<unsigned short>> remappedStrips;
if (vertexMap.empty() || strips.empty())
return remappedStrips;
remappedStrips = strips;
for (auto& strip : remappedStrips)
for (auto& index : strip)
index = vertexMap[index];
return remappedStrips;
}
void NiMorphData::read(NIFStream* nif)
{
int morphCount = nif->getInt();

@ -222,7 +222,10 @@ namespace Nif
std::vector<unsigned short> trueTriangles;
std::vector<char> boneIndices;
BSVertexDesc mVertexDesc;
void read(NIFStream* nif);
std::vector<unsigned short> getTrueTriangles() const;
std::vector<std::vector<unsigned short>> getTrueStrips() const;
};
unsigned int mPartitionNum;
std::vector<Partition> mPartitions;

@ -385,6 +385,7 @@ namespace NifBullet
if (!niGeometry.skin.empty())
args.mAnimated = false;
// TODO: handle NiSkinPartition
std::unique_ptr<btTriangleMesh> childMesh = makeChildMesh(niGeometry);
if (childMesh == nullptr || childMesh->getNumTriangles() == 0)

@ -1378,45 +1378,86 @@ namespace NifOsg
const Nif::NiGeometry* niGeometry = static_cast<const Nif::NiGeometry*>(nifNode);
if (niGeometry->data.empty())
return;
const Nif::NiGeometryData* niGeometryData = niGeometry->data.getPtr();
if (niGeometry->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_BSLODTriShape)
{
if (niGeometryData->recType != Nif::RC_NiTriShapeData)
return;
auto triangles = static_cast<const Nif::NiTriShapeData*>(niGeometryData)->triangles;
if (triangles.empty())
return;
geometry->addPrimitiveSet(new osg::DrawElementsUShort(
osg::PrimitiveSet::TRIANGLES, triangles.size(), (unsigned short*)triangles.data()));
}
else if (niGeometry->recType == Nif::RC_NiTriStrips)
bool hasPartitions = false;
if (!niGeometry->skin.empty())
{
if (niGeometryData->recType != Nif::RC_NiTriStripsData)
return;
auto data = static_cast<const Nif::NiTriStripsData*>(niGeometryData);
bool hasGeometry = false;
for (const auto& strip : data->strips)
const Nif::NiSkinInstance* skin = niGeometry->skin.getPtr();
const Nif::NiSkinData* data = nullptr;
const Nif::NiSkinPartition* partitions = nullptr;
if (!skin->data.empty())
{
if (strip.size() < 3)
continue;
geometry->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP,
strip.size(), reinterpret_cast<const unsigned short*>(strip.data())));
hasGeometry = true;
data = skin->data.getPtr();
if (!data->partitions.empty())
partitions = data->partitions.getPtr();
}
if (!partitions && !skin->partitions.empty())
partitions = skin->partitions.getPtr();
hasPartitions = partitions != nullptr;
if (hasPartitions)
{
std::vector<unsigned short> trueTriangles;
for (const Nif::NiSkinPartition::Partition& partition : partitions->mPartitions)
{
trueTriangles = partition.getTrueTriangles();
if (!trueTriangles.empty())
{
geometry->addPrimitiveSet(new osg::DrawElementsUShort(
osg::PrimitiveSet::TRIANGLES, trueTriangles.size(), trueTriangles.data()));
}
const std::vector<std::vector<unsigned short>> trueStrips = partition.getTrueStrips();
for (const auto& strip : trueStrips)
{
geometry->addPrimitiveSet(new osg::DrawElementsUShort(
osg::PrimitiveSet::TRIANGLE_STRIP, strip.size(), strip.data()));
}
}
}
if (!hasGeometry)
return;
}
else if (niGeometry->recType == Nif::RC_NiLines)
const Nif::NiGeometryData* niGeometryData = niGeometry->data.getPtr();
if (!hasPartitions)
{
if (niGeometryData->recType != Nif::RC_NiLinesData)
return;
auto data = static_cast<const Nif::NiLinesData*>(niGeometryData);
const auto& line = data->lines;
if (line.empty())
return;
geometry->addPrimitiveSet(new osg::DrawElementsUShort(
osg::PrimitiveSet::LINES, line.size(), reinterpret_cast<const unsigned short*>(line.data())));
if (niGeometry->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_BSLODTriShape)
{
if (niGeometryData->recType != Nif::RC_NiTriShapeData)
return;
auto data = static_cast<const Nif::NiTriShapeData*>(niGeometryData);
const std::vector<unsigned short>& triangles = data->triangles;
if (triangles.empty())
return;
geometry->addPrimitiveSet(
new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, triangles.size(), triangles.data()));
}
else if (niGeometry->recType == Nif::RC_NiTriStrips)
{
if (niGeometryData->recType != Nif::RC_NiTriStripsData)
return;
auto data = static_cast<const Nif::NiTriStripsData*>(niGeometryData);
bool hasGeometry = false;
for (const std::vector<unsigned short>& strip : data->strips)
{
if (strip.size() < 3)
continue;
geometry->addPrimitiveSet(
new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP, strip.size(), strip.data()));
hasGeometry = true;
}
if (!hasGeometry)
return;
}
else if (niGeometry->recType == Nif::RC_NiLines)
{
if (niGeometryData->recType != Nif::RC_NiLinesData)
return;
auto data = static_cast<const Nif::NiLinesData*>(niGeometryData);
const auto& line = data->lines;
if (line.empty())
return;
geometry->addPrimitiveSet(
new osg::DrawElementsUShort(osg::PrimitiveSet::LINES, line.size(), line.data()));
}
}
handleNiGeometryData(geometry, niGeometryData, boundTextures, nifNode->name);

Loading…
Cancel
Save