From a7c5beb7c5d495446e5d7facaa780fbf851d1848 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 18 Jun 2015 01:26:45 +0200 Subject: [PATCH] Remove redundant allocations for NIF meshes --- components/nif/data.cpp | 17 ++++++++-- components/nif/data.hpp | 13 +++++--- components/nif/nifstream.cpp | 32 +++++++++--------- components/nif/nifstream.hpp | 11 ++++--- components/nifbullet/bulletnifloader.cpp | 18 +++++----- components/nifosg/nifloader.cpp | 42 +++++++++++------------- 6 files changed, 76 insertions(+), 57 deletions(-) diff --git a/components/nif/data.cpp b/components/nif/data.cpp index fc0631b841..5a60ab8a5e 100644 --- a/components/nif/data.cpp +++ b/components/nif/data.cpp @@ -1,6 +1,9 @@ #include "data.hpp" #include "node.hpp" +#include +#include + namespace Nif { void NiSkinInstance::read(NIFStream *nif) @@ -37,15 +40,18 @@ void ShapeData::read(NIFStream *nif) { int verts = nif->getUShort(); + vertices = new osg::Vec3Array; if(nif->getInt()) nif->getVector3s(vertices, verts); + normals = new osg::Vec3Array(osg::Array::BIND_PER_VERTEX); if(nif->getInt()) nif->getVector3s(normals, verts); center = nif->getVector3(); radius = nif->getFloat(); + colors = new osg::Vec4Array(osg::Array::BIND_PER_VERTEX); if(nif->getInt()) nif->getVector4s(colors, verts); @@ -58,7 +64,10 @@ void ShapeData::read(NIFStream *nif) { uvlist.resize(uvs); for(int i = 0;i < uvs;i++) + { + uvlist[i] = new osg::Vec2Array(osg::Array::BIND_PER_VERTEX); nif->getVector2s(uvlist[i], verts); + } } } @@ -71,6 +80,7 @@ void NiTriShapeData::read(NIFStream *nif) // We have three times as many vertices as triangles, so this // is always equal to tris*3. int cnt = nif->getInt(); + triangles = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES); nif->getUShorts(triangles, cnt); // Read the match list, which lists the vertices that are equal to @@ -97,8 +107,9 @@ void NiAutoNormalParticlesData::read(NIFStream *nif) if(nif->getInt()) { + int numVerts = vertices->size(); // Particle sizes - nif->getFloats(sizes, vertices.size()); + nif->getFloats(sizes, numVerts); } } @@ -108,8 +119,9 @@ void NiRotatingParticlesData::read(NIFStream *nif) if(nif->getInt()) { + int numVerts = vertices->size(); // Rotation quaternions. - nif->getQuaternions(rotations, vertices.size()); + nif->getQuaternions(rotations, numVerts); } } @@ -224,6 +236,7 @@ void NiMorphData::read(NIFStream *nif) { mMorphs[i].mKeyFrames.reset(new FloatKeyMap); mMorphs[i].mKeyFrames->read(nif, true); + mMorphs[i].mVertices = new osg::Vec3Array; nif->getVector3s(mMorphs[i].mVertices, vertCount); } } diff --git a/components/nif/data.hpp b/components/nif/data.hpp index 63dc42aded..95f2441295 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -28,6 +28,8 @@ #include "niftypes.hpp" // Transformation +#include + namespace Nif { @@ -35,9 +37,10 @@ namespace Nif class ShapeData : public Record { public: - std::vector vertices, normals; - std::vector colors; - std::vector< std::vector > uvlist; + osg::ref_ptr vertices, normals; + osg::ref_ptr colors; + + std::vector< osg::ref_ptr > uvlist; osg::Vec3f center; float radius; @@ -48,7 +51,7 @@ class NiTriShapeData : public ShapeData { public: // Triangles, three vertex indices per triangle - std::vector triangles; + osg::ref_ptr triangles; void read(NIFStream *nif); }; @@ -166,7 +169,7 @@ struct NiMorphData : public Record { struct MorphData { FloatKeyMapPtr mKeyFrames; - std::vector mVertices; + osg::ref_ptr mVertices; }; std::vector mMorphs; diff --git a/components/nif/nifstream.cpp b/components/nif/nifstream.cpp index d0fc9bab03..5f49c2d21e 100644 --- a/components/nif/nifstream.cpp +++ b/components/nif/nifstream.cpp @@ -103,11 +103,11 @@ std::string NIFStream::getVersionString() return result; } -void NIFStream::getUShorts(std::vector &vec, size_t size) +void NIFStream::getUShorts(osg::VectorGLushort* vec, size_t size) { - vec.resize(size); - for(size_t i = 0;i < vec.size();i++) - vec[i] = getUShort(); + vec->reserve(size); + for(size_t i = 0;i < size;i++) + vec->push_back(getUShort()); } void NIFStream::getFloats(std::vector &vec, size_t size) { @@ -115,23 +115,23 @@ void NIFStream::getFloats(std::vector &vec, size_t size) for(size_t i = 0;i < vec.size();i++) vec[i] = getFloat(); } -void NIFStream::getVector2s(std::vector &vec, size_t size) +void NIFStream::getVector2s(osg::Vec2Array* vec, size_t size) { - vec.resize(size); - for(size_t i = 0;i < vec.size();i++) - vec[i] = getVector2(); + vec->reserve(size); + for(size_t i = 0;i < size;i++) + vec->push_back(getVector2()); } -void NIFStream::getVector3s(std::vector &vec, size_t size) +void NIFStream::getVector3s(osg::Vec3Array* vec, size_t size) { - vec.resize(size); - for(size_t i = 0;i < vec.size();i++) - vec[i] = getVector3(); + vec->reserve(size); + for(size_t i = 0;i < size;i++) + vec->push_back(getVector3()); } -void NIFStream::getVector4s(std::vector &vec, size_t size) +void NIFStream::getVector4s(osg::Vec4Array* vec, size_t size) { - vec.resize(size); - for(size_t i = 0;i < vec.size();i++) - vec[i] = getVector4(); + vec->reserve(size); + for(size_t i = 0;i < size;i++) + vec->push_back(getVector4()); } void NIFStream::getQuaternions(std::vector &quat, size_t size) { diff --git a/components/nif/nifstream.hpp b/components/nif/nifstream.hpp index f4163ce47c..f5d777bdfc 100644 --- a/components/nif/nifstream.hpp +++ b/components/nif/nifstream.hpp @@ -12,9 +12,12 @@ #include #include #include +#include +#include #include "niftypes.hpp" + namespace Nif { @@ -59,11 +62,11 @@ public: ///This is special since the version string doesn't start with a number, and ends with "\n" std::string getVersionString(); - void getUShorts(std::vector &vec, size_t size); + void getUShorts(osg::VectorGLushort* vec, size_t size); void getFloats(std::vector &vec, size_t size); - void getVector2s(std::vector &vec, size_t size); - void getVector3s(std::vector &vec, size_t size); - void getVector4s(std::vector &vec, size_t size); + void getVector2s(osg::Vec2Array* vec, size_t size); + void getVector3s(osg::Vec3Array* vec, size_t size); + void getVector4s(osg::Vec4Array* vec, size_t size); void getQuaternions(std::vector &quat, size_t size); }; diff --git a/components/nifbullet/bulletnifloader.cpp b/components/nifbullet/bulletnifloader.cpp index 495c6ba50d..adf961dc25 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -292,13 +292,14 @@ void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags, const Nif::NiTriShapeData *data = shape->data.getPtr(); - childMesh->preallocateVertices(data->vertices.size()); - childMesh->preallocateIndices(data->triangles.size()); + childMesh->preallocateVertices(data->vertices->size()); + childMesh->preallocateIndices(data->triangles->size()); - const std::vector &vertices = data->vertices; - const std::vector &triangles = data->triangles; + const osg::Vec3Array& vertices = *data->vertices; + const osg::DrawElementsUShort& triangles = *data->triangles; - for(size_t i = 0;i < data->triangles.size();i+=3) + size_t numtris = data->triangles->size(); + for(size_t i = 0;i < numtris;i+=3) { osg::Vec3f b1 = vertices[triangles[i+0]]; osg::Vec3f b2 = vertices[triangles[i+1]]; @@ -332,10 +333,11 @@ void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags, // Static shape, just transform all vertices into position const Nif::NiTriShapeData *data = shape->data.getPtr(); - const std::vector &vertices = data->vertices; - const std::vector &triangles = data->triangles; + const osg::Vec3Array& vertices = *data->vertices; + const osg::DrawElementsUShort& triangles = *data->triangles; - for(size_t i = 0;i < data->triangles.size();i+=3) + size_t numtris = data->triangles->size(); + for(size_t i = 0;i < numtris;i+=3) { osg::Vec3f b1 = vertices[triangles[i+0]]*transform; osg::Vec3f b2 = vertices[triangles[i+1]]*transform; diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index d8920646d1..802ca5425f 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -736,11 +736,11 @@ namespace NifOsg // Note this position and velocity is not correct for a particle system with absolute reference frame, // which can not be done in this loader since we are not attached to the scene yet. Will be fixed up post-load in the SceneManager. created->setVelocity(particle.velocity); - created->setPosition(particledata->vertices.at(particle.vertex)); + created->setPosition(particledata->vertices->at(particle.vertex)); osg::Vec4f partcolor (1.f,1.f,1.f,1.f); - if (particle.vertex < int(particledata->colors.size())) - partcolor = particledata->colors.at(particle.vertex); + if (particle.vertex < int(particledata->colors->size())) + partcolor = particledata->colors->at(particle.vertex); float size = particledata->sizes.at(particle.vertex) * partctrl->size; @@ -892,11 +892,10 @@ namespace NifOsg { const Nif::NiTriShapeData* data = triShape->data.getPtr(); - { - geometry->setVertexArray(new osg::Vec3Array(data->vertices.size(), &data->vertices[0])); - if (!data->normals.empty()) - geometry->setNormalArray(new osg::Vec3Array(data->normals.size(), &data->normals[0]), osg::Array::BIND_PER_VERTEX); - } + geometry->setVertexArray(data->vertices); + + if (!data->normals->empty()) + geometry->setNormalArray(data->normals); int textureStage = 0; for (std::vector::const_iterator it = boundTextures.begin(); it != boundTextures.end(); ++it,++textureStage) @@ -909,15 +908,14 @@ namespace NifOsg continue; } - geometry->setTexCoordArray(textureStage, new osg::Vec2Array(data->uvlist[uvSet].size(), &data->uvlist[uvSet][0]), osg::Array::BIND_PER_VERTEX); + geometry->setTexCoordArray(textureStage, data->uvlist[uvSet]); } - if (!data->colors.empty()) - geometry->setColorArray(new osg::Vec4Array(data->colors.size(), &data->colors[0]), osg::Array::BIND_PER_VERTEX); + if (!data->colors->empty()) + geometry->setColorArray(data->colors); - geometry->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, - data->triangles.size(), - (unsigned short*)&data->triangles[0])); + if (!data->triangles->empty()) + geometry->addPrimitiveSet(data->triangles); // osg::Material properties are handled here for two reasons: // - if there are no vertex colors, we need to disable colorMode. @@ -925,7 +923,7 @@ namespace NifOsg // above the actual renderable would be tedious. std::vector materialProps; collectMaterialProperties(triShape, materialProps); - applyMaterialProperties(parentNode, materialProps, composite, !data->colors.empty(), animflags); + applyMaterialProperties(parentNode, materialProps, composite, !data->colors->empty(), animflags); } void handleTriShape(const Nif::NiTriShape* triShape, osg::Group* parentNode, SceneUtil::CompositeStateSetUpdater* composite, const std::vector& boundTextures, int animflags) @@ -988,13 +986,13 @@ namespace NifOsg for (unsigned int i = 1; i < morphs.size(); ++i) { osg::ref_ptr morphTarget = new osg::Geometry; - morphTarget->setVertexArray(new osg::Vec3Array(morphs[i].mVertices.size(), &morphs[i].mVertices[0])); + morphTarget->setVertexArray(morphs[i].mVertices); morphGeom->addMorphTarget(morphTarget, 0.f); } // build the bounding box containing all possible morph combinations - std::vector vertBounds(morphs[0].mVertices.size()); + std::vector vertBounds(morphs[0].mVertices->size()); // Since we don't know what combinations of morphs are being applied we need to keep track of a bounding box for each vertex. // The minimum/maximum of the box is the minimum/maximum offset the vertex can have from its starting position. @@ -1005,19 +1003,19 @@ namespace NifOsg for (unsigned int i = 1; i < morphs.size(); ++i) { - for (unsigned int j=0; jsize() && vertBounds.size(); ++j) { osg::BoundingBox& bounds = vertBounds[j]; - bounds.expandBy(bounds._max + morphs[i].mVertices[j]); - bounds.expandBy(bounds._min + morphs[i].mVertices[j]); + bounds.expandBy(bounds._max + (*morphs[i].mVertices)[j]); + bounds.expandBy(bounds._min + (*morphs[i].mVertices)[j]); } } osg::BoundingBox box; for (unsigned int i=0; i