|
|
|
@ -612,7 +612,9 @@ namespace NifOsg
|
|
|
|
|
|
|
|
|
|
applyNodeProperties(nifNode, node, composite, imageManager, boundTextures, animflags);
|
|
|
|
|
|
|
|
|
|
if ((nifNode->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_NiTriStrips) && !skipMeshes)
|
|
|
|
|
const bool isGeometry = nifNode->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_NiTriStrips || nifNode->recType == Nif::RC_NiLines;
|
|
|
|
|
|
|
|
|
|
if (isGeometry && !skipMeshes)
|
|
|
|
|
{
|
|
|
|
|
const std::string nodeName = Misc::StringUtils::lowerCase(nifNode->name);
|
|
|
|
|
static const std::string markerName = "tri editormarker";
|
|
|
|
@ -624,9 +626,9 @@ namespace NifOsg
|
|
|
|
|
Nif::NiSkinInstancePtr skin = static_cast<const Nif::NiGeometry*>(nifNode)->skin;
|
|
|
|
|
|
|
|
|
|
if (skin.empty())
|
|
|
|
|
handleTriShape(nifNode, node, composite, boundTextures, animflags);
|
|
|
|
|
handleGeometry(nifNode, node, composite, boundTextures, animflags);
|
|
|
|
|
else
|
|
|
|
|
handleSkinnedTriShape(nifNode, node, composite, boundTextures, animflags);
|
|
|
|
|
handleSkinnedGeometry(nifNode, node, composite, boundTextures, animflags);
|
|
|
|
|
|
|
|
|
|
if (!nifNode->controller.empty())
|
|
|
|
|
handleMeshControllers(nifNode, node, composite, boundTextures, animflags);
|
|
|
|
@ -1099,8 +1101,11 @@ namespace NifOsg
|
|
|
|
|
partsys->getOrCreateStateSet();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void triCommonToGeometry(osg::Geometry *geometry, const std::vector<osg::Vec3f>& vertices, const std::vector<osg::Vec3f>& normals, const std::vector<std::vector<osg::Vec2f>>& uvlist, const std::vector<osg::Vec4f>& colors, const std::vector<unsigned int>& boundTextures, const std::string& name)
|
|
|
|
|
void handleNiGeometryData(osg::Geometry *geometry, const Nif::NiGeometryData* data, const std::vector<unsigned int>& boundTextures, const std::string& name)
|
|
|
|
|
{
|
|
|
|
|
const auto& vertices = data->vertices;
|
|
|
|
|
const auto& normals = data->normals;
|
|
|
|
|
const auto& colors = data->colors;
|
|
|
|
|
if (!vertices.empty())
|
|
|
|
|
geometry->setVertexArray(new osg::Vec3Array(vertices.size(), vertices.data()));
|
|
|
|
|
if (!normals.empty())
|
|
|
|
@ -1108,6 +1113,7 @@ namespace NifOsg
|
|
|
|
|
if (!colors.empty())
|
|
|
|
|
geometry->setColorArray(new osg::Vec4Array(colors.size(), colors.data()), osg::Array::BIND_PER_VERTEX);
|
|
|
|
|
|
|
|
|
|
const auto& uvlist = data->uvlist;
|
|
|
|
|
int textureStage = 0;
|
|
|
|
|
for (const unsigned int uvSet : boundTextures)
|
|
|
|
|
{
|
|
|
|
@ -1124,43 +1130,53 @@ namespace NifOsg
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void triShapeToGeometry(const Nif::Node *nifNode, osg::Geometry *geometry, osg::Node* parentNode, SceneUtil::CompositeStateSetUpdater* composite, const std::vector<unsigned int>& boundTextures, int animflags)
|
|
|
|
|
void handleNiGeometry(const Nif::Node *nifNode, osg::Geometry *geometry, osg::Node* parentNode, SceneUtil::CompositeStateSetUpdater* composite, const std::vector<unsigned int>& boundTextures, int animflags)
|
|
|
|
|
{
|
|
|
|
|
bool vertexColorsPresent = false;
|
|
|
|
|
const Nif::NiGeometryData* niGeometryData = nullptr;
|
|
|
|
|
if (nifNode->recType == Nif::RC_NiTriShape)
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiTriShape* triShape = static_cast<const Nif::NiTriShape*>(nifNode);
|
|
|
|
|
if (!triShape->data.empty())
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiTriShapeData* data = triShape->data.getPtr();
|
|
|
|
|
vertexColorsPresent = !data->colors.empty();
|
|
|
|
|
triCommonToGeometry(geometry, data->vertices, data->normals, data->uvlist, data->colors, boundTextures, triShape->name);
|
|
|
|
|
niGeometryData = static_cast<const Nif::NiGeometryData*>(data);
|
|
|
|
|
if (!data->triangles.empty())
|
|
|
|
|
geometry->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, data->triangles.size(),
|
|
|
|
|
(unsigned short*)data->triangles.data()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
else if (nifNode->recType == Nif::RC_NiTriStrips)
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiTriStrips* triStrips = static_cast<const Nif::NiTriStrips*>(nifNode);
|
|
|
|
|
if (!triStrips->data.empty())
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiTriStripsData* data = triStrips->data.getPtr();
|
|
|
|
|
vertexColorsPresent = !data->colors.empty();
|
|
|
|
|
triCommonToGeometry(geometry, data->vertices, data->normals, data->uvlist, data->colors, boundTextures, triStrips->name);
|
|
|
|
|
niGeometryData = static_cast<const Nif::NiGeometryData*>(data);
|
|
|
|
|
if (!data->strips.empty())
|
|
|
|
|
{
|
|
|
|
|
for (const std::vector<unsigned short>& strip : data->strips)
|
|
|
|
|
for (const auto& strip : data->strips)
|
|
|
|
|
{
|
|
|
|
|
// Can't make a triangle from less than three vertices.
|
|
|
|
|
if (strip.size() < 3)
|
|
|
|
|
continue;
|
|
|
|
|
geometry->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP, strip.size(),
|
|
|
|
|
(unsigned short*)strip.data()));
|
|
|
|
|
if (strip.size() >= 3)
|
|
|
|
|
geometry->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP, strip.size(),
|
|
|
|
|
(unsigned short*)strip.data()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (nifNode->recType == Nif::RC_NiLines)
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiLines* lines = static_cast<const Nif::NiLines*>(nifNode);
|
|
|
|
|
if (!lines->data.empty())
|
|
|
|
|
{
|
|
|
|
|
const Nif::NiLinesData* data = lines->data.getPtr();
|
|
|
|
|
niGeometryData = static_cast<const Nif::NiGeometryData*>(data);
|
|
|
|
|
const auto& line = data->lines;
|
|
|
|
|
if (!line.empty())
|
|
|
|
|
geometry->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::LINES, line.size(), (unsigned short*)line.data()));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (niGeometryData)
|
|
|
|
|
handleNiGeometryData(geometry, niGeometryData, boundTextures, nifNode->name);
|
|
|
|
|
|
|
|
|
|
// osg::Material properties are handled here for two reasons:
|
|
|
|
|
// - if there are no vertex colors, we need to disable colorMode.
|
|
|
|
@ -1168,15 +1184,15 @@ namespace NifOsg
|
|
|
|
|
// above the actual renderable would be tedious.
|
|
|
|
|
std::vector<const Nif::Property*> drawableProps;
|
|
|
|
|
collectDrawableProperties(nifNode, drawableProps);
|
|
|
|
|
applyDrawableProperties(parentNode, drawableProps, composite, vertexColorsPresent, animflags);
|
|
|
|
|
applyDrawableProperties(parentNode, drawableProps, composite, niGeometryData && !niGeometryData->colors.empty(), animflags);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void handleTriShape(const Nif::Node* nifNode, osg::Group* parentNode, SceneUtil::CompositeStateSetUpdater* composite, const std::vector<unsigned int>& boundTextures, int animflags)
|
|
|
|
|
void handleGeometry(const Nif::Node* nifNode, osg::Group* parentNode, SceneUtil::CompositeStateSetUpdater* composite, const std::vector<unsigned int>& boundTextures, int animflags)
|
|
|
|
|
{
|
|
|
|
|
assert(nifNode->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_NiTriStrips);
|
|
|
|
|
assert(nifNode->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_NiTriStrips || nifNode->recType == Nif::RC_NiLines);
|
|
|
|
|
osg::ref_ptr<osg::Drawable> drawable;
|
|
|
|
|
osg::ref_ptr<osg::Geometry> geom (new osg::Geometry);
|
|
|
|
|
triShapeToGeometry(nifNode, geom, parentNode, composite, boundTextures, animflags);
|
|
|
|
|
handleNiGeometry(nifNode, geom, parentNode, composite, boundTextures, animflags);
|
|
|
|
|
for (Nif::ControllerPtr ctrl = nifNode->controller; !ctrl.empty(); ctrl = ctrl->next)
|
|
|
|
|
{
|
|
|
|
|
if (!(ctrl->flags & Nif::NiNode::ControllerFlag_Active))
|
|
|
|
@ -1215,12 +1231,12 @@ namespace NifOsg
|
|
|
|
|
return morphGeom;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void handleSkinnedTriShape(const Nif::Node *nifNode, osg::Group *parentNode, SceneUtil::CompositeStateSetUpdater* composite,
|
|
|
|
|
void handleSkinnedGeometry(const Nif::Node *nifNode, osg::Group *parentNode, SceneUtil::CompositeStateSetUpdater* composite,
|
|
|
|
|
const std::vector<unsigned int>& boundTextures, int animflags)
|
|
|
|
|
{
|
|
|
|
|
assert(nifNode->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_NiTriStrips);
|
|
|
|
|
assert(nifNode->recType == Nif::RC_NiTriShape || nifNode->recType == Nif::RC_NiTriStrips || nifNode->recType == Nif::RC_NiLines);
|
|
|
|
|
osg::ref_ptr<osg::Geometry> geometry (new osg::Geometry);
|
|
|
|
|
triShapeToGeometry(nifNode, geometry, parentNode, composite, boundTextures, animflags);
|
|
|
|
|
handleNiGeometry(nifNode, geometry, parentNode, composite, boundTextures, animflags);
|
|
|
|
|
osg::ref_ptr<SceneUtil::RigGeometry> rig(new SceneUtil::RigGeometry);
|
|
|
|
|
rig->setSourceGeometry(geometry);
|
|
|
|
|
rig->setName(nifNode->name);
|
|
|
|
|