mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 19:19:56 +00:00
Remove redundant allocations for NIF meshes
This commit is contained in:
parent
43384596d4
commit
a7c5beb7c5
6 changed files with 76 additions and 57 deletions
|
@ -1,6 +1,9 @@
|
||||||
#include "data.hpp"
|
#include "data.hpp"
|
||||||
#include "node.hpp"
|
#include "node.hpp"
|
||||||
|
|
||||||
|
#include <osg/Array>
|
||||||
|
#include <osg/PrimitiveSet>
|
||||||
|
|
||||||
namespace Nif
|
namespace Nif
|
||||||
{
|
{
|
||||||
void NiSkinInstance::read(NIFStream *nif)
|
void NiSkinInstance::read(NIFStream *nif)
|
||||||
|
@ -37,15 +40,18 @@ void ShapeData::read(NIFStream *nif)
|
||||||
{
|
{
|
||||||
int verts = nif->getUShort();
|
int verts = nif->getUShort();
|
||||||
|
|
||||||
|
vertices = new osg::Vec3Array;
|
||||||
if(nif->getInt())
|
if(nif->getInt())
|
||||||
nif->getVector3s(vertices, verts);
|
nif->getVector3s(vertices, verts);
|
||||||
|
|
||||||
|
normals = new osg::Vec3Array(osg::Array::BIND_PER_VERTEX);
|
||||||
if(nif->getInt())
|
if(nif->getInt())
|
||||||
nif->getVector3s(normals, verts);
|
nif->getVector3s(normals, verts);
|
||||||
|
|
||||||
center = nif->getVector3();
|
center = nif->getVector3();
|
||||||
radius = nif->getFloat();
|
radius = nif->getFloat();
|
||||||
|
|
||||||
|
colors = new osg::Vec4Array(osg::Array::BIND_PER_VERTEX);
|
||||||
if(nif->getInt())
|
if(nif->getInt())
|
||||||
nif->getVector4s(colors, verts);
|
nif->getVector4s(colors, verts);
|
||||||
|
|
||||||
|
@ -58,7 +64,10 @@ void ShapeData::read(NIFStream *nif)
|
||||||
{
|
{
|
||||||
uvlist.resize(uvs);
|
uvlist.resize(uvs);
|
||||||
for(int i = 0;i < uvs;i++)
|
for(int i = 0;i < uvs;i++)
|
||||||
|
{
|
||||||
|
uvlist[i] = new osg::Vec2Array(osg::Array::BIND_PER_VERTEX);
|
||||||
nif->getVector2s(uvlist[i], verts);
|
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
|
// We have three times as many vertices as triangles, so this
|
||||||
// is always equal to tris*3.
|
// is always equal to tris*3.
|
||||||
int cnt = nif->getInt();
|
int cnt = nif->getInt();
|
||||||
|
triangles = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES);
|
||||||
nif->getUShorts(triangles, cnt);
|
nif->getUShorts(triangles, cnt);
|
||||||
|
|
||||||
// Read the match list, which lists the vertices that are equal to
|
// Read the match list, which lists the vertices that are equal to
|
||||||
|
@ -97,8 +107,9 @@ void NiAutoNormalParticlesData::read(NIFStream *nif)
|
||||||
|
|
||||||
if(nif->getInt())
|
if(nif->getInt())
|
||||||
{
|
{
|
||||||
|
int numVerts = vertices->size();
|
||||||
// Particle sizes
|
// Particle sizes
|
||||||
nif->getFloats(sizes, vertices.size());
|
nif->getFloats(sizes, numVerts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,8 +119,9 @@ void NiRotatingParticlesData::read(NIFStream *nif)
|
||||||
|
|
||||||
if(nif->getInt())
|
if(nif->getInt())
|
||||||
{
|
{
|
||||||
|
int numVerts = vertices->size();
|
||||||
// Rotation quaternions.
|
// 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.reset(new FloatKeyMap);
|
||||||
mMorphs[i].mKeyFrames->read(nif, true);
|
mMorphs[i].mKeyFrames->read(nif, true);
|
||||||
|
mMorphs[i].mVertices = new osg::Vec3Array;
|
||||||
nif->getVector3s(mMorphs[i].mVertices, vertCount);
|
nif->getVector3s(mMorphs[i].mVertices, vertCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
#include "niftypes.hpp" // Transformation
|
#include "niftypes.hpp" // Transformation
|
||||||
|
|
||||||
|
#include <osg/Array>
|
||||||
|
|
||||||
namespace Nif
|
namespace Nif
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -35,9 +37,10 @@ namespace Nif
|
||||||
class ShapeData : public Record
|
class ShapeData : public Record
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::vector<osg::Vec3f> vertices, normals;
|
osg::ref_ptr<osg::Vec3Array> vertices, normals;
|
||||||
std::vector<osg::Vec4f> colors;
|
osg::ref_ptr<osg::Vec4Array> colors;
|
||||||
std::vector< std::vector<osg::Vec2f> > uvlist;
|
|
||||||
|
std::vector< osg::ref_ptr<osg::Vec2Array> > uvlist;
|
||||||
osg::Vec3f center;
|
osg::Vec3f center;
|
||||||
float radius;
|
float radius;
|
||||||
|
|
||||||
|
@ -48,7 +51,7 @@ class NiTriShapeData : public ShapeData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// Triangles, three vertex indices per triangle
|
// Triangles, three vertex indices per triangle
|
||||||
std::vector<unsigned short> triangles;
|
osg::ref_ptr<osg::DrawElementsUShort> triangles;
|
||||||
|
|
||||||
void read(NIFStream *nif);
|
void read(NIFStream *nif);
|
||||||
};
|
};
|
||||||
|
@ -166,7 +169,7 @@ struct NiMorphData : public Record
|
||||||
{
|
{
|
||||||
struct MorphData {
|
struct MorphData {
|
||||||
FloatKeyMapPtr mKeyFrames;
|
FloatKeyMapPtr mKeyFrames;
|
||||||
std::vector<osg::Vec3f> mVertices;
|
osg::ref_ptr<osg::Vec3Array> mVertices;
|
||||||
};
|
};
|
||||||
std::vector<MorphData> mMorphs;
|
std::vector<MorphData> mMorphs;
|
||||||
|
|
||||||
|
|
|
@ -103,11 +103,11 @@ std::string NIFStream::getVersionString()
|
||||||
return result;
|
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);
|
vec->reserve(size);
|
||||||
for(size_t i = 0;i < vec.size();i++)
|
for(size_t i = 0;i < size;i++)
|
||||||
vec[i] = getUShort();
|
vec->push_back(getUShort());
|
||||||
}
|
}
|
||||||
void NIFStream::getFloats(std::vector<float> &vec, size_t size)
|
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++)
|
for(size_t i = 0;i < vec.size();i++)
|
||||||
vec[i] = getFloat();
|
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);
|
vec->reserve(size);
|
||||||
for(size_t i = 0;i < vec.size();i++)
|
for(size_t i = 0;i < size;i++)
|
||||||
vec[i] = getVector2();
|
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);
|
vec->reserve(size);
|
||||||
for(size_t i = 0;i < vec.size();i++)
|
for(size_t i = 0;i < size;i++)
|
||||||
vec[i] = getVector3();
|
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);
|
vec->reserve(size);
|
||||||
for(size_t i = 0;i < vec.size();i++)
|
for(size_t i = 0;i < size;i++)
|
||||||
vec[i] = getVector4();
|
vec->push_back(getVector4());
|
||||||
}
|
}
|
||||||
void NIFStream::getQuaternions(std::vector<osg::Quat> &quat, size_t size)
|
void NIFStream::getQuaternions(std::vector<osg::Quat> &quat, size_t size)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,9 +12,12 @@
|
||||||
#include <osg/Vec3f>
|
#include <osg/Vec3f>
|
||||||
#include <osg/Vec4f>
|
#include <osg/Vec4f>
|
||||||
#include <osg/Quat>
|
#include <osg/Quat>
|
||||||
|
#include <osg/Array>
|
||||||
|
#include <osg/PrimitiveSet>
|
||||||
|
|
||||||
#include "niftypes.hpp"
|
#include "niftypes.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace Nif
|
namespace Nif
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -59,11 +62,11 @@ public:
|
||||||
///This is special since the version string doesn't start with a number, and ends with "\n"
|
///This is special since the version string doesn't start with a number, and ends with "\n"
|
||||||
std::string getVersionString();
|
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 getFloats(std::vector<float> &vec, size_t size);
|
||||||
void getVector2s(std::vector<osg::Vec2f> &vec, size_t size);
|
void getVector2s(osg::Vec2Array* vec, size_t size);
|
||||||
void getVector3s(std::vector<osg::Vec3f> &vec, size_t size);
|
void getVector3s(osg::Vec3Array* vec, size_t size);
|
||||||
void getVector4s(std::vector<osg::Vec4f> &vec, size_t size);
|
void getVector4s(osg::Vec4Array* vec, size_t size);
|
||||||
void getQuaternions(std::vector<osg::Quat> &quat, 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();
|
const Nif::NiTriShapeData *data = shape->data.getPtr();
|
||||||
|
|
||||||
childMesh->preallocateVertices(data->vertices.size());
|
childMesh->preallocateVertices(data->vertices->size());
|
||||||
childMesh->preallocateIndices(data->triangles.size());
|
childMesh->preallocateIndices(data->triangles->size());
|
||||||
|
|
||||||
const std::vector<osg::Vec3f> &vertices = data->vertices;
|
const osg::Vec3Array& vertices = *data->vertices;
|
||||||
const std::vector<unsigned short> &triangles = data->triangles;
|
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 b1 = vertices[triangles[i+0]];
|
||||||
osg::Vec3f b2 = vertices[triangles[i+1]];
|
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
|
// Static shape, just transform all vertices into position
|
||||||
const Nif::NiTriShapeData *data = shape->data.getPtr();
|
const Nif::NiTriShapeData *data = shape->data.getPtr();
|
||||||
const std::vector<osg::Vec3f> &vertices = data->vertices;
|
const osg::Vec3Array& vertices = *data->vertices;
|
||||||
const std::vector<unsigned short> &triangles = data->triangles;
|
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 b1 = vertices[triangles[i+0]]*transform;
|
||||||
osg::Vec3f b2 = vertices[triangles[i+1]]*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,
|
// 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.
|
// 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->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);
|
osg::Vec4f partcolor (1.f,1.f,1.f,1.f);
|
||||||
if (particle.vertex < int(particledata->colors.size()))
|
if (particle.vertex < int(particledata->colors->size()))
|
||||||
partcolor = particledata->colors.at(particle.vertex);
|
partcolor = particledata->colors->at(particle.vertex);
|
||||||
|
|
||||||
float size = particledata->sizes.at(particle.vertex) * partctrl->size;
|
float size = particledata->sizes.at(particle.vertex) * partctrl->size;
|
||||||
|
|
||||||
|
@ -892,11 +892,10 @@ namespace NifOsg
|
||||||
{
|
{
|
||||||
const Nif::NiTriShapeData* data = triShape->data.getPtr();
|
const Nif::NiTriShapeData* data = triShape->data.getPtr();
|
||||||
|
|
||||||
{
|
geometry->setVertexArray(data->vertices);
|
||||||
geometry->setVertexArray(new osg::Vec3Array(data->vertices.size(), &data->vertices[0]));
|
|
||||||
if (!data->normals.empty())
|
if (!data->normals->empty())
|
||||||
geometry->setNormalArray(new osg::Vec3Array(data->normals.size(), &data->normals[0]), osg::Array::BIND_PER_VERTEX);
|
geometry->setNormalArray(data->normals);
|
||||||
}
|
|
||||||
|
|
||||||
int textureStage = 0;
|
int textureStage = 0;
|
||||||
for (std::vector<int>::const_iterator it = boundTextures.begin(); it != boundTextures.end(); ++it,++textureStage)
|
for (std::vector<int>::const_iterator it = boundTextures.begin(); it != boundTextures.end(); ++it,++textureStage)
|
||||||
|
@ -909,15 +908,14 @@ namespace NifOsg
|
||||||
continue;
|
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())
|
if (!data->colors->empty())
|
||||||
geometry->setColorArray(new osg::Vec4Array(data->colors.size(), &data->colors[0]), osg::Array::BIND_PER_VERTEX);
|
geometry->setColorArray(data->colors);
|
||||||
|
|
||||||
geometry->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES,
|
if (!data->triangles->empty())
|
||||||
data->triangles.size(),
|
geometry->addPrimitiveSet(data->triangles);
|
||||||
(unsigned short*)&data->triangles[0]));
|
|
||||||
|
|
||||||
// osg::Material properties are handled here for two reasons:
|
// osg::Material properties are handled here for two reasons:
|
||||||
// - if there are no vertex colors, we need to disable colorMode.
|
// - if there are no vertex colors, we need to disable colorMode.
|
||||||
|
@ -925,7 +923,7 @@ namespace NifOsg
|
||||||
// above the actual renderable would be tedious.
|
// above the actual renderable would be tedious.
|
||||||
std::vector<const Nif::Property*> materialProps;
|
std::vector<const Nif::Property*> materialProps;
|
||||||
collectMaterialProperties(triShape, 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)
|
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)
|
for (unsigned int i = 1; i < morphs.size(); ++i)
|
||||||
{
|
{
|
||||||
osg::ref_ptr<osg::Geometry> morphTarget = new osg::Geometry;
|
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);
|
morphGeom->addMorphTarget(morphTarget, 0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
// build the bounding box containing all possible morph combinations
|
// 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.
|
// 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.
|
// 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 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];
|
osg::BoundingBox& bounds = vertBounds[j];
|
||||||
bounds.expandBy(bounds._max + morphs[i].mVertices[j]);
|
bounds.expandBy(bounds._max + (*morphs[i].mVertices)[j]);
|
||||||
bounds.expandBy(bounds._min + morphs[i].mVertices[j]);
|
bounds.expandBy(bounds._min + (*morphs[i].mVertices)[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
osg::BoundingBox box;
|
osg::BoundingBox box;
|
||||||
for (unsigned int i=0; i<vertBounds.size(); ++i)
|
for (unsigned int i=0; i<vertBounds.size(); ++i)
|
||||||
{
|
{
|
||||||
vertBounds[i]._max += morphs[0].mVertices[i];
|
vertBounds[i]._max += (*morphs[0].mVertices)[i];
|
||||||
vertBounds[i]._min += morphs[0].mVertices[i];
|
vertBounds[i]._min += (*morphs[0].mVertices)[i];
|
||||||
box.expandBy(vertBounds[i]);
|
box.expandBy(vertBounds[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue