Remove redundant allocations for NIF meshes

c++11
scrawl 10 years ago
parent 43384596d4
commit a7c5beb7c5

@ -1,6 +1,9 @@
#include "data.hpp"
#include "node.hpp"
#include <osg/Array>
#include <osg/PrimitiveSet>
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);
}
}

@ -28,6 +28,8 @@
#include "niftypes.hpp" // Transformation
#include <osg/Array>
namespace Nif
{
@ -35,9 +37,10 @@ namespace Nif
class ShapeData : public Record
{
public:
std::vector<osg::Vec3f> vertices, normals;
std::vector<osg::Vec4f> colors;
std::vector< std::vector<osg::Vec2f> > uvlist;
osg::ref_ptr<osg::Vec3Array> vertices, normals;
osg::ref_ptr<osg::Vec4Array> colors;
std::vector< osg::ref_ptr<osg::Vec2Array> > uvlist;
osg::Vec3f center;
float radius;
@ -48,7 +51,7 @@ class NiTriShapeData : public ShapeData
{
public:
// Triangles, three vertex indices per triangle
std::vector<unsigned short> triangles;
osg::ref_ptr<osg::DrawElementsUShort> triangles;
void read(NIFStream *nif);
};
@ -166,7 +169,7 @@ struct NiMorphData : public Record
{
struct MorphData {
FloatKeyMapPtr mKeyFrames;
std::vector<osg::Vec3f> mVertices;
osg::ref_ptr<osg::Vec3Array> mVertices;
};
std::vector<MorphData> mMorphs;

@ -103,11 +103,11 @@ std::string NIFStream::getVersionString()
return result;
}
void NIFStream::getUShorts(std::vector<unsigned short> &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<float> &vec, size_t size)
{
@ -115,23 +115,23 @@ void NIFStream::getFloats(std::vector<float> &vec, size_t size)
for(size_t i = 0;i < vec.size();i++)
vec[i] = getFloat();
}
void NIFStream::getVector2s(std::vector<osg::Vec2f> &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<osg::Vec3f> &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<osg::Vec4f> &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<osg::Quat> &quat, size_t size)
{

@ -12,9 +12,12 @@
#include <osg/Vec3f>
#include <osg/Vec4f>
#include <osg/Quat>
#include <osg/Array>
#include <osg/PrimitiveSet>
#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<unsigned short> &vec, size_t size);
void getUShorts(osg::VectorGLushort* vec, size_t size);
void getFloats(std::vector<float> &vec, size_t size);
void getVector2s(std::vector<osg::Vec2f> &vec, size_t size);
void getVector3s(std::vector<osg::Vec3f> &vec, size_t size);
void getVector4s(std::vector<osg::Vec4f> &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<osg::Quat> &quat, size_t size);
};

@ -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<osg::Vec3f> &vertices = data->vertices;
const std::vector<unsigned short> &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<osg::Vec3f> &vertices = data->vertices;
const std::vector<unsigned short> &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;

@ -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<int>::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<const Nif::Property*> 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<int>& boundTextures, int animflags)
@ -988,13 +986,13 @@ namespace NifOsg
for (unsigned int i = 1; i < morphs.size(); ++i)
{
osg::ref_ptr<osg::Geometry> 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<osg::BoundingBox> vertBounds(morphs[0].mVertices.size());
std::vector<osg::BoundingBox> 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; j<morphs[i].mVertices.size() && vertBounds.size(); ++j)
for (unsigned int j=0; j<morphs[i].mVertices->size() && 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<vertBounds.size(); ++i)
{
vertBounds[i]._max += morphs[0].mVertices[i];
vertBounds[i]._min += morphs[0].mVertices[i];
vertBounds[i]._max += (*morphs[0].mVertices)[i];
vertBounds[i]._min += (*morphs[0].mVertices)[i];
box.expandBy(vertBounds[i]);
}

Loading…
Cancel
Save