mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-01 03:21:41 +00:00
Merge branch 'mantlingtalos' into 'master'
Copy triangle data from NiSkinPartition, a.k.a. SKYRIM TREES See merge request OpenMW/openmw!3235
This commit is contained in:
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)
|
||||
bool hasPartitions = false;
|
||||
if (!niGeometry->skin.empty())
|
||||
{
|
||||
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)
|
||||
{
|
||||
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…
Reference in New Issue
Block a user