diff --git a/components/nif/data.cpp b/components/nif/data.cpp index 082b5aa63..0813ab36b 100644 --- a/components/nif/data.cpp +++ b/components/nif/data.cpp @@ -1,9 +1,6 @@ #include "data.hpp" #include "node.hpp" -#include -#include - namespace Nif { void NiSkinInstance::read(NIFStream *nif) @@ -40,51 +37,33 @@ void ShapeData::read(NIFStream *nif) { int verts = nif->getUShort(); - // Assign a VBO right off the bat to avoid race conditions later, in case two threads load this data into a Geometry at the same time - osg::ref_ptr vbo = new osg::VertexBufferObject; - - if(nif->getInt() && verts) - { - vertices = new osg::Vec3Array; + if(nif->getInt()) nif->getVector3s(vertices, verts); - vertices->setVertexBufferObject(vbo); - } - if(nif->getInt() && verts) - { - normals = new osg::Vec3Array(osg::Array::BIND_PER_VERTEX); + if(nif->getInt()) nif->getVector3s(normals, verts); - normals->setVertexBufferObject(vbo); - } center = nif->getVector3(); radius = nif->getFloat(); - if(nif->getInt() && verts) - { - colors = new osg::Vec4Array(osg::Array::BIND_PER_VERTEX); + if(nif->getInt()) nif->getVector4s(colors, verts); - colors->setVertexBufferObject(vbo); - } // Only the first 6 bits are used as a count. I think the rest are // flags of some sort. int uvs = nif->getUShort(); uvs &= 0x3f; - if(nif->getInt() && verts) + if(nif->getInt()) { uvlist.resize(uvs); for(int i = 0;i < uvs;i++) { - osg::Vec2Array* list = uvlist[i] = new osg::Vec2Array(osg::Array::BIND_PER_VERTEX); - list->setVertexBufferObject(vbo); - nif->getVector2s(list, verts); - + nif->getVector2s(uvlist[i], verts); // flip the texture coordinates to convert them to the OpenGL convention of bottom-left image origin - for (unsigned int uv=0; uvsize(); ++uv) + for (unsigned int uv=0; uvgetInt(); - if (cnt) - { - triangles = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES); - nif->getUShorts(triangles, cnt); - - // Assign an EBO right off the bat to avoid race conditions later, in case two threads load this data into a Geometry at the same time - triangles->setElementBufferObject(new osg::ElementBufferObject); - } + nif->getUShorts(triangles, cnt); // Read the match list, which lists the vertices that are equal to // vertices. We don't actually need need this for anything, so @@ -132,9 +104,8 @@ void NiAutoNormalParticlesData::read(NIFStream *nif) if(nif->getInt()) { - int numVerts = vertices->size(); // Particle sizes - nif->getFloats(sizes, numVerts); + nif->getFloats(sizes, vertices.size()); } } @@ -144,9 +115,8 @@ void NiRotatingParticlesData::read(NIFStream *nif) if(nif->getInt()) { - int numVerts = vertices->size(); // Rotation quaternions. - nif->getQuaternions(rotations, numVerts); + nif->getQuaternions(rotations, vertices.size()); } } @@ -265,7 +235,6 @@ 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 89886b66f..e6227b52a 100644 --- a/components/nif/data.hpp +++ b/components/nif/data.hpp @@ -28,8 +28,6 @@ #include "niftypes.hpp" // Transformation -#include - namespace Nif { @@ -37,10 +35,9 @@ namespace Nif class ShapeData : public Record { public: - osg::ref_ptr vertices, normals; - osg::ref_ptr colors; - - std::vector< osg::ref_ptr > uvlist; + std::vector vertices, normals; + std::vector colors; + std::vector< std::vector > uvlist; osg::Vec3f center; float radius; @@ -51,7 +48,7 @@ class NiTriShapeData : public ShapeData { public: // Triangles, three vertex indices per triangle - osg::ref_ptr triangles; + std::vector triangles; void read(NIFStream *nif); }; @@ -190,7 +187,7 @@ struct NiMorphData : public Record { struct MorphData { FloatKeyMapPtr mKeyFrames; - osg::ref_ptr mVertices; + std::vector mVertices; }; std::vector mMorphs; diff --git a/components/nif/nifstream.cpp b/components/nif/nifstream.cpp index 5f49c2d21..d0fc9bab0 100644 --- a/components/nif/nifstream.cpp +++ b/components/nif/nifstream.cpp @@ -103,11 +103,11 @@ std::string NIFStream::getVersionString() return result; } -void NIFStream::getUShorts(osg::VectorGLushort* vec, size_t size) +void NIFStream::getUShorts(std::vector &vec, size_t size) { - vec->reserve(size); - for(size_t i = 0;i < size;i++) - vec->push_back(getUShort()); + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = 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(osg::Vec2Array* vec, size_t size) +void NIFStream::getVector2s(std::vector &vec, size_t size) { - vec->reserve(size); - for(size_t i = 0;i < size;i++) - vec->push_back(getVector2()); + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getVector2(); } -void NIFStream::getVector3s(osg::Vec3Array* vec, size_t size) +void NIFStream::getVector3s(std::vector &vec, size_t size) { - vec->reserve(size); - for(size_t i = 0;i < size;i++) - vec->push_back(getVector3()); + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getVector3(); } -void NIFStream::getVector4s(osg::Vec4Array* vec, size_t size) +void NIFStream::getVector4s(std::vector &vec, size_t size) { - vec->reserve(size); - for(size_t i = 0;i < size;i++) - vec->push_back(getVector4()); + vec.resize(size); + for(size_t i = 0;i < vec.size();i++) + vec[i] = getVector4(); } void NIFStream::getQuaternions(std::vector &quat, size_t size) { diff --git a/components/nif/nifstream.hpp b/components/nif/nifstream.hpp index f5d777bdf..f4163ce47 100644 --- a/components/nif/nifstream.hpp +++ b/components/nif/nifstream.hpp @@ -12,12 +12,9 @@ #include #include #include -#include -#include #include "niftypes.hpp" - namespace Nif { @@ -62,11 +59,11 @@ public: ///This is special since the version string doesn't start with a number, and ends with "\n" std::string getVersionString(); - void getUShorts(osg::VectorGLushort* vec, size_t size); + void getUShorts(std::vector &vec, size_t size); void getFloats(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 getVector2s(std::vector &vec, size_t size); + void getVector3s(std::vector &vec, size_t size); + void getVector4s(std::vector &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 6a369931a..1cfac15eb 100644 --- a/components/nifbullet/bulletnifloader.cpp +++ b/components/nifbullet/bulletnifloader.cpp @@ -268,9 +268,7 @@ void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags, if (shape->data.empty()) return; - - const Nif::NiTriShapeData *data = shape->data.getPtr(); - if (!data->triangles || !data->vertices) + if (shape->data->triangles.empty()) return; if (isAnimated) @@ -280,14 +278,15 @@ void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags, btTriangleMesh* childMesh = new btTriangleMesh(); - childMesh->preallocateVertices(data->vertices->size()); - childMesh->preallocateIndices(data->triangles->size()); + const Nif::NiTriShapeData *data = shape->data.getPtr(); - const osg::Vec3Array& vertices = *data->vertices; - const osg::DrawElementsUShort& triangles = *data->triangles; + childMesh->preallocateVertices(data->vertices.size()); + childMesh->preallocateIndices(data->triangles.size()); - size_t numtris = data->triangles->size(); - for(size_t i = 0;i < numtris;i+=3) + const std::vector &vertices = data->vertices; + const std::vector &triangles = data->triangles; + + for(size_t i = 0;i < data->triangles.size();i+=3) { osg::Vec3f b1 = vertices[triangles[i+0]]; osg::Vec3f b2 = vertices[triangles[i+1]]; @@ -320,13 +319,14 @@ void BulletNifLoader::handleNiTriShape(const Nif::NiTriShape *shape, int flags, mStaticMesh = new btTriangleMesh(false); // Static shape, just transform all vertices into position - const osg::Vec3Array& vertices = *data->vertices; - const osg::DrawElementsUShort& triangles = *data->triangles; + const Nif::NiTriShapeData *data = shape->data.getPtr(); + const std::vector &vertices = data->vertices; + const std::vector &triangles = data->triangles; - mStaticMesh->preallocateVertices(data->vertices->size()); - mStaticMesh->preallocateIndices(data->triangles->size()); + mStaticMesh->preallocateVertices(data->vertices.size()); + mStaticMesh->preallocateIndices(data->triangles.size()); - size_t numtris = data->triangles->size(); + size_t numtris = data->triangles.size(); for(size_t i = 0;i < numtris;i+=3) { osg::Vec3f b1 = vertices[triangles[i+0]]*transform; diff --git a/components/nifosg/nifloader.cpp b/components/nifosg/nifloader.cpp index a247c62a4..9624e7396 100644 --- a/components/nifosg/nifloader.cpp +++ b/components/nifosg/nifloader.cpp @@ -898,10 +898,6 @@ namespace NifOsg osg::BoundingBox box; - osg::Vec3Array* verts = particledata->vertices; - if (!verts) - return; - int i=0; for (std::vector::const_iterator it = partctrl->particles.begin(); iactiveCount && it != partctrl->particles.end(); ++it, ++i) @@ -916,12 +912,12 @@ 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); - const osg::Vec3f& position = verts->at(particle.vertex); + const osg::Vec3f& position = particledata->vertices.at(particle.vertex); created->setPosition(position); osg::Vec4f partcolor (1.f,1.f,1.f,1.f); - if (particledata->colors.valid() && 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; @@ -1080,10 +1076,11 @@ namespace NifOsg { const Nif::NiTriShapeData* data = triShape->data.getPtr(); - geometry->setVertexArray(data->vertices); - - if (data->normals) - geometry->setNormalArray(data->normals); + { + 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); + } int textureStage = 0; for (std::vector::const_iterator it = boundTextures.begin(); it != boundTextures.end(); ++it,++textureStage) @@ -1093,18 +1090,19 @@ namespace NifOsg { std::cerr << "Warning: out of bounds UV set " << uvSet << " on TriShape \"" << triShape->name << "\" in " << mFilename << std::endl; if (!data->uvlist.empty()) - geometry->setTexCoordArray(textureStage, data->uvlist[0]); + geometry->setTexCoordArray(textureStage, new osg::Vec2Array(data->uvlist[0].size(), &data->uvlist[0][0]), osg::Array::BIND_PER_VERTEX); continue; } - geometry->setTexCoordArray(textureStage, data->uvlist[uvSet]); + geometry->setTexCoordArray(textureStage, new osg::Vec2Array(data->uvlist[uvSet].size(), &data->uvlist[uvSet][0]), osg::Array::BIND_PER_VERTEX); } - if (data->colors) - geometry->setColorArray(data->colors); + if (!data->colors.empty()) + geometry->setColorArray(new osg::Vec4Array(data->colors.size(), &data->colors[0]), osg::Array::BIND_PER_VERTEX); - if (data->triangles) - geometry->addPrimitiveSet(data->triangles); + geometry->addPrimitiveSet(new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, + data->triangles.size(), + (unsigned short*)&data->triangles[0])); // osg::Material properties are handled here for two reasons: // - if there are no vertex colors, we need to disable colorMode. @@ -1112,7 +1110,7 @@ namespace NifOsg // above the actual renderable would be tedious. std::vector drawableProps; collectDrawableProperties(triShape, drawableProps); - applyDrawableProperties(parentNode, drawableProps, composite, data->colors.valid(), animflags, false); + applyDrawableProperties(parentNode, drawableProps, composite, !data->colors.empty(), animflags, false); } void handleTriShape(const Nif::NiTriShape* triShape, osg::Group* parentNode, SceneUtil::CompositeStateSetUpdater* composite, const std::vector& boundTextures, int animflags) @@ -1179,13 +1177,13 @@ namespace NifOsg for (unsigned int i = 1; i < morphs.size(); ++i) { osg::ref_ptr morphTarget = new osg::Geometry; - morphTarget->setVertexArray(morphs[i].mVertices); + morphTarget->setVertexArray(new osg::Vec3Array(morphs[i].mVertices.size(), &morphs[i].mVertices[0])); 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. @@ -1196,19 +1194,19 @@ namespace NifOsg for (unsigned int i = 1; i < morphs.size(); ++i) { - for (unsigned int j=0; jsize() && vertBounds.size(); ++j) + for (unsigned int j=0; j