mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-21 11:39:51 -06:00
Cleanup of WaveFrontGeometry
This commit is contained in:
@@ -26,7 +26,6 @@
|
||||
#define __WAVEFRONTOBJECT_H__
|
||||
|
||||
#include <openspace/rendering/model/modelgeometry.h>
|
||||
#include <tiny_obj_loader.h>
|
||||
|
||||
namespace openspace {
|
||||
|
||||
@@ -37,44 +36,31 @@ namespace modelgeometry {
|
||||
class WavefrontGeometry : public ModelGeometry {
|
||||
public:
|
||||
WavefrontGeometry(const ghoul::Dictionary& dictionary);
|
||||
~WavefrontGeometry();
|
||||
|
||||
bool initialize(RenderableModel* parent) override;
|
||||
void deinitialize() override;
|
||||
void render() override;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GLfloat location[4];
|
||||
GLfloat tex[2];
|
||||
GLfloat normal[3];
|
||||
GLfloat padding[7];
|
||||
//GLubyte padding[4]; // Pads the struct out to 64 bytes for performance increase
|
||||
} Vertex;
|
||||
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
std::vector<tinyobj::material_t> materials;
|
||||
protected:
|
||||
private:
|
||||
struct Vertex {
|
||||
GLfloat location[4];
|
||||
GLfloat tex[2];
|
||||
GLfloat normal[3];
|
||||
};
|
||||
|
||||
bool loadObj(const std::string& filename);
|
||||
bool loadCachedFile(const std::string& filename);
|
||||
bool saveCachedFile(const std::string& filename);
|
||||
bool loadModel(const std::string& filename);
|
||||
|
||||
private:
|
||||
void createSphere();
|
||||
|
||||
GLuint _vaoID;
|
||||
GLuint _vBufferID;
|
||||
GLuint _iBufferID;
|
||||
GLuint _vbo;
|
||||
GLuint _ibo;
|
||||
|
||||
GLuint _tBufferID;
|
||||
unsigned int _tsize;
|
||||
float* _tarray;
|
||||
std::vector<Vertex> _vertices;
|
||||
std::vector<int> _indices;
|
||||
|
||||
unsigned int _isize;
|
||||
unsigned int _vsize;
|
||||
Vertex* _varray;
|
||||
int* _iarray;
|
||||
std::vector<int> _shapeCounts;
|
||||
};
|
||||
|
||||
} // namespace modelgeometry
|
||||
|
||||
@@ -88,11 +88,6 @@ namespace renderablemodel {
|
||||
const std::string keyGeometry = "Geometry";
|
||||
} // namespace renderablemodel
|
||||
|
||||
namespace modelgeometry {
|
||||
const std::string keyType = "Type";
|
||||
const std::string keyObjFile = "ObjFile";
|
||||
} // namespace modelgeometry
|
||||
|
||||
namespace renderablestars {
|
||||
const std::string keyFile = "File";
|
||||
const std::string keyTexture = "Texture";
|
||||
|
||||
@@ -28,7 +28,9 @@
|
||||
#include <openspace/util/factorymanager.h>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "ModelGeometry";
|
||||
const std::string _loggerCat = "ModelGeometry";
|
||||
|
||||
const std::string keyType = "Type";
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
@@ -38,10 +40,10 @@ ModelGeometry* ModelGeometry::createFromDictionary(const ghoul::Dictionary& dict
|
||||
{
|
||||
std::string geometryType;
|
||||
const bool success = dictionary.getValue(
|
||||
constants::modelgeometry::keyType, geometryType);
|
||||
keyType, geometryType);
|
||||
if (!success) {
|
||||
LERROR("ModelGeometry did not contain a correct value of the key '"
|
||||
<< constants::modelgeometry::keyType << "'");
|
||||
<< keyType << "'");
|
||||
return nullptr;
|
||||
}
|
||||
ghoul::TemplateFactory<ModelGeometry>* factory
|
||||
|
||||
@@ -30,11 +30,15 @@
|
||||
#include "ghoul/logging/logmanager.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <numeric>
|
||||
#include <tiny_obj_loader.h>
|
||||
|
||||
namespace {
|
||||
const std::string _loggerCat = "WavefrontGeometry";
|
||||
|
||||
const int8_t CurrentCacheVersion = 1;
|
||||
const std::string keyObjFile = "ObjFile";
|
||||
|
||||
const int8_t CurrentCacheVersion = 2;
|
||||
}
|
||||
|
||||
namespace openspace {
|
||||
@@ -42,31 +46,25 @@ namespace modelgeometry {
|
||||
|
||||
WavefrontGeometry::WavefrontGeometry(const ghoul::Dictionary& dictionary)
|
||||
: ModelGeometry()
|
||||
, _isize(0)
|
||||
, _vsize(0)
|
||||
, _varray(nullptr)
|
||||
, _iarray(nullptr)
|
||||
, _tarray(nullptr)
|
||||
{
|
||||
using constants::scenegraphnode::keyName;
|
||||
|
||||
// The name is passed down from the SceneGraphNode
|
||||
std::string name;
|
||||
bool success = dictionary.getValue(keyName, name);
|
||||
ghoul_assert(success, "Name tag was not present");
|
||||
|
||||
std::string file;
|
||||
success = dictionary.getValue(constants::modelgeometry::keyObjFile, file);
|
||||
success = dictionary.getValue(keyObjFile, file);
|
||||
if (!success) {
|
||||
LERROR("SimpleSphereGeometry of '" << name << "' did not provide a key '"
|
||||
<< constants::modelgeometry::keyObjFile << "'");
|
||||
LERROR("WaveFrontGeometry of '" << name << "' did not provide a key '"
|
||||
<< keyObjFile << "'");
|
||||
}
|
||||
const std::string filename = FileSys.absolutePath(file);
|
||||
file = FileSys.absolutePath(file);
|
||||
|
||||
if (FileSys.fileExists(filename))
|
||||
loadObj(filename);
|
||||
if (FileSys.fileExists(file, true))
|
||||
loadObj(file);
|
||||
else
|
||||
LERROR("Could not load OBJ file '" << filename << "': File not found");
|
||||
LERROR("Could not load OBJ file '" << file << "': File not found");
|
||||
}
|
||||
|
||||
bool WavefrontGeometry::loadObj(const std::string& filename){
|
||||
@@ -89,7 +87,6 @@ bool WavefrontGeometry::loadObj(const std::string& filename){
|
||||
LINFO("Cache for Model'" << filename << "' not found");
|
||||
}
|
||||
LINFO("Loading OBJ file '" << filename << "'");
|
||||
|
||||
bool success = loadModel(filename);
|
||||
if (!success)
|
||||
return false;
|
||||
@@ -98,92 +95,22 @@ bool WavefrontGeometry::loadObj(const std::string& filename){
|
||||
success = saveCachedFile(cachedFile);
|
||||
|
||||
return success;
|
||||
|
||||
|
||||
|
||||
|
||||
//if (shapes[0].mesh.texcoords.size() > 0) {
|
||||
// for (int k = 0; k < shapes[0].mesh.texcoords.size(); ++k) {
|
||||
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//if (shapes[0].mesh.texcoords.size() > 0) {
|
||||
// for (size_t k = 0; k < shapes[0].mesh.indices.size() / 3; k++) {
|
||||
// for (int j = 0; j < 3; j++) {
|
||||
// int idx = shapes[0].mesh.indices[3 * k + j];
|
||||
|
||||
// _varray[p].tex[0] = shapes[0].mesh.texcoords[2 * idx + 0];
|
||||
// _varray[p].tex[1] = shapes[0].mesh.texcoords[2 * idx + 1];
|
||||
// p++;
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
//testing with one triangle - works.
|
||||
/*
|
||||
_varray[0].location[0] = 0;
|
||||
_varray[0].location[1] = 0;
|
||||
_varray[0].location[2] = 0;
|
||||
_varray[0].location[3] = 5;
|
||||
|
||||
_varray[0].normal[0] = 1;
|
||||
_varray[0].normal[1] = 1;
|
||||
_varray[0].normal[2] = 1;
|
||||
|
||||
_varray[0].tex[0] = 0;
|
||||
_varray[0].tex[1] = 0;
|
||||
|
||||
_varray[1].location[0] = 1;
|
||||
_varray[1].location[1] = 0;
|
||||
_varray[1].location[2] = 0;
|
||||
_varray[1].location[3] = 5;
|
||||
|
||||
_varray[1].normal[0] = 1;
|
||||
_varray[1].normal[1] = 1;
|
||||
_varray[1].normal[2] = 1;
|
||||
|
||||
_varray[1].tex[0] = 1;
|
||||
_varray[1].tex[1] = 0;
|
||||
|
||||
_varray[2].location[0] = 0;
|
||||
_varray[2].location[1] = 1;
|
||||
_varray[2].location[2] = 0;
|
||||
_varray[2].location[3] = 5;
|
||||
|
||||
_varray[2].normal[0] = 1;
|
||||
_varray[2].normal[1] = 1;
|
||||
_varray[2].normal[2] = 1;
|
||||
|
||||
_varray[2].tex[0] = 0;
|
||||
_varray[2].tex[1] = 1;
|
||||
|
||||
_vsize = 3;
|
||||
_isize = 3;
|
||||
|
||||
_iarray[0] = 0;
|
||||
_iarray[1] = 1;
|
||||
_iarray[2] = 2;
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
WavefrontGeometry::~WavefrontGeometry(){
|
||||
}
|
||||
|
||||
bool WavefrontGeometry::initialize(RenderableModel* parent){
|
||||
bool WavefrontGeometry::initialize(RenderableModel* parent) {
|
||||
bool success = ModelGeometry::initialize(parent);
|
||||
createSphere();
|
||||
PowerScaledScalar ps = PowerScaledScalar(1.0, 0.0); // will set proper bounding soon.
|
||||
_parent->setBoundingSphere(ps);
|
||||
|
||||
if (_isize == 0) return false;
|
||||
if (_vertices.empty())
|
||||
return false;
|
||||
glGenVertexArrays(1, &_vaoID);
|
||||
glGenBuffers(1, &_vBufferID);
|
||||
glGenBuffers(1, &_iBufferID);
|
||||
glGenBuffers(1, &_vbo);
|
||||
glGenBuffers(1, &_ibo);
|
||||
|
||||
glBindVertexArray(_vaoID);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vBufferID);
|
||||
glBufferData(GL_ARRAY_BUFFER, _vsize * sizeof(Vertex), _varray, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, _vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, _vertices.size() * sizeof(Vertex), _vertices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glEnableVertexAttribArray(0);
|
||||
glEnableVertexAttribArray(1);
|
||||
@@ -195,45 +122,30 @@ bool WavefrontGeometry::initialize(RenderableModel* parent){
|
||||
glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex),
|
||||
reinterpret_cast<const GLvoid*>(offsetof(Vertex, normal)));
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iBufferID);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _isize * sizeof(int), _iarray, GL_STATIC_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, _indices.size() * sizeof(int), _indices.data(), GL_STATIC_DRAW);
|
||||
|
||||
glBindVertexArray(0);
|
||||
|
||||
GLint errorID = glGetError();
|
||||
if (errorID != GL_NO_ERROR) {
|
||||
LERROR("OpenGL error: " << glewGetErrorString(errorID));
|
||||
return false;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
void WavefrontGeometry::deinitialize(){
|
||||
if (_varray)
|
||||
delete[] _varray;
|
||||
if (_iarray)
|
||||
delete[] _iarray;
|
||||
|
||||
glDeleteBuffers(1, &_vBufferID);
|
||||
glDeleteBuffers(1, &_iBufferID);
|
||||
void WavefrontGeometry::deinitialize() {
|
||||
glDeleteBuffers(1, &_vbo);
|
||||
glDeleteVertexArrays(1, &_vaoID);
|
||||
|
||||
glDeleteBuffers(1, &_ibo);
|
||||
}
|
||||
|
||||
void WavefrontGeometry::render(){
|
||||
// render
|
||||
glBindVertexArray(_vaoID); // select first VAO
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _iBufferID);
|
||||
glDrawElements(GL_TRIANGLES, _isize, GL_UNSIGNED_INT, 0);
|
||||
void WavefrontGeometry::render() {
|
||||
glBindVertexArray(_vaoID);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo);
|
||||
glDrawElements(GL_TRIANGLES, _indices.size(), GL_UNSIGNED_INT, 0);
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void WavefrontGeometry::createSphere(){
|
||||
// create the power scaled scalar
|
||||
PowerScaledScalar ps = PowerScaledScalar(1.0, 0.0); // will set proper bounding soon.
|
||||
_parent->setBoundingSphere(ps);
|
||||
}
|
||||
|
||||
bool WavefrontGeometry::loadModel(const std::string& filename) {
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
std::vector<tinyobj::material_t> materials;
|
||||
std::string err = tinyobj::LoadObj(shapes, materials, filename.c_str(), filename.c_str());
|
||||
|
||||
if (!err.empty()) {
|
||||
@@ -241,48 +153,43 @@ bool WavefrontGeometry::loadModel(const std::string& filename) {
|
||||
return false;
|
||||
}
|
||||
|
||||
LINFO("Loaded Mesh");
|
||||
LINFO("Number of Shapes: " << shapes.size());
|
||||
LINFO("Number of Materials: " << materials.size());
|
||||
for (int i = 0; i < shapes.size(); ++i) {
|
||||
LINFO("Shape #" << i << ": " <<
|
||||
"Indices (" << shapes[i].mesh.indices.size() << ") " <<
|
||||
"Positions (" << shapes[i].mesh.positions.size() << ") " <<
|
||||
"Texture (" << shapes[i].mesh.texcoords.size() << ") " <<
|
||||
"Normals (" << shapes[i].mesh.normals.size() << ")");
|
||||
if (shapes.size() > 1) {
|
||||
LWARNING("Loading models with more than one shape is currently untested");
|
||||
}
|
||||
|
||||
_isize = shapes[0].mesh.indices.size();
|
||||
_vsize = shapes[0].mesh.indices.size(); // shapes[0].mesh.positions.size() + shapes[0].mesh.positions.size() / 3;
|
||||
_tsize = shapes[0].mesh.texcoords.size();
|
||||
_shapeCounts.resize(shapes.size());
|
||||
for (int i = 0; i < shapes.size(); ++i)
|
||||
_shapeCounts[i] = shapes[i].mesh.indices.size();
|
||||
int totalSize = std::accumulate(_shapeCounts.begin(), _shapeCounts.end(), 0);
|
||||
|
||||
_varray = new Vertex[_vsize];
|
||||
_iarray = new int[_isize];
|
||||
_vertices.resize(totalSize);
|
||||
_indices.resize(totalSize);
|
||||
|
||||
//copy indices
|
||||
for (int f = 0; f < shapes[0].mesh.indices.size(); f++) {
|
||||
_iarray[f] = f;// shapes[0].mesh.indices[f];
|
||||
}
|
||||
|
||||
//shapes[0].mesh.texcoords.resize(2 * _isize);
|
||||
// We add all shapes of the model into the same vertex array, one after the other
|
||||
// The _shapeCounts array stores for each shape, how many vertices that shape has
|
||||
int p = 0;
|
||||
for (auto v : shapes[0].mesh.indices) {
|
||||
_varray[p].location[0] = shapes[0].mesh.positions[3 * v + 0];
|
||||
_varray[p].location[1] = shapes[0].mesh.positions[3 * v + 1];
|
||||
_varray[p].location[2] = shapes[0].mesh.positions[3 * v + 2];
|
||||
_varray[p].location[3] = 5;
|
||||
for (int i = 0; i < shapes.size(); ++i) {
|
||||
for (int index : shapes[i].mesh.indices) {
|
||||
_vertices[index + p].location[0] = shapes[i].mesh.positions[3 * index + 0];
|
||||
_vertices[index + p].location[1] = shapes[i].mesh.positions[3 * index + 1];
|
||||
_vertices[index + p].location[2] = shapes[i].mesh.positions[3 * index + 2];
|
||||
_vertices[index + p].location[3] = 5;
|
||||
|
||||
_varray[p].normal[0] = shapes[0].mesh.normals[3 * v + 0];
|
||||
_varray[p].normal[1] = shapes[0].mesh.normals[3 * v + 1];
|
||||
_varray[p].normal[2] = shapes[0].mesh.normals[3 * v + 2];
|
||||
_vertices[index + p].normal[0] = shapes[i].mesh.normals[3 * index + 0];
|
||||
_vertices[index + p].normal[1] = shapes[i].mesh.normals[3 * index + 1];
|
||||
_vertices[index + p].normal[2] = shapes[i].mesh.normals[3 * index + 2];
|
||||
|
||||
// Only set the texture coordinates if they don't fall out of the value range
|
||||
_varray[p].tex[0] = (2 * v + 0) < shapes[0].mesh.texcoords.size() ? shapes[0].mesh.texcoords[2 * v + 0] : 0.f;
|
||||
_varray[p].tex[1] = (2 * v + 1) < shapes[0].mesh.texcoords.size() ? shapes[0].mesh.texcoords[2 * v + 1] : 0.f;
|
||||
|
||||
p++;
|
||||
// Only set the texture coordinates if they don't fall out of the value range
|
||||
_vertices[index + p].tex[0] = (2 * index + 0) < shapes[i].mesh.texcoords.size() ? shapes[0].mesh.texcoords[2 * index + 0] : 0.f;
|
||||
_vertices[index + p].tex[1] = (2 * index + 1) < shapes[i].mesh.texcoords.size() ? shapes[0].mesh.texcoords[2 * index + 1] : 0.f;
|
||||
}
|
||||
std::copy(
|
||||
shapes[i].mesh.indices.begin(),
|
||||
shapes[i].mesh.indices.end(),
|
||||
_indices.begin() + p
|
||||
);
|
||||
p += _shapeCounts[i];
|
||||
}
|
||||
p = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -293,15 +200,10 @@ bool WavefrontGeometry::saveCachedFile(const std::string& filename) {
|
||||
fileStream.write(reinterpret_cast<const char*>(&CurrentCacheVersion),
|
||||
sizeof(int8_t));
|
||||
|
||||
int64_t vSize = _vsize;
|
||||
int64_t vSize = _vertices.size();
|
||||
fileStream.write(reinterpret_cast<const char*>(&vSize), sizeof(int64_t));
|
||||
int64_t iSize = _isize;
|
||||
fileStream.write(reinterpret_cast<const char*>(&iSize), sizeof(int64_t));
|
||||
int64_t tSize = _tsize;
|
||||
fileStream.write(reinterpret_cast<const char*>(&tSize), sizeof(int64_t));
|
||||
|
||||
fileStream.write(reinterpret_cast<const char*>(_varray), sizeof(Vertex) * _vsize);
|
||||
fileStream.write(reinterpret_cast<const char*>(_iarray), sizeof(int) * _isize);
|
||||
fileStream.write(reinterpret_cast<const char*>(_vertices.data()), sizeof(Vertex) * vSize);
|
||||
|
||||
return fileStream.good();
|
||||
}
|
||||
@@ -323,19 +225,13 @@ bool WavefrontGeometry::loadCachedFile(const std::string& filename) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int64_t vSize, iSize, tSize;
|
||||
int64_t vSize, iSize;
|
||||
fileStream.read(reinterpret_cast<char*>(&vSize), sizeof(int64_t));
|
||||
fileStream.read(reinterpret_cast<char*>(&iSize), sizeof(int64_t));
|
||||
fileStream.read(reinterpret_cast<char*>(&tSize), sizeof(int64_t));
|
||||
_vsize = vSize;
|
||||
_isize = iSize;
|
||||
_tsize = tSize;
|
||||
|
||||
_vertices.resize(vSize);
|
||||
|
||||
_varray = new Vertex[vSize];
|
||||
_iarray = new int[iSize];
|
||||
|
||||
fileStream.read(reinterpret_cast<char*>(_varray), sizeof(Vertex) * vSize);
|
||||
fileStream.read(reinterpret_cast<char*>(_iarray), sizeof(int) * iSize);
|
||||
fileStream.read(reinterpret_cast<char*>(_vertices.data()), sizeof(Vertex) * vSize);
|
||||
|
||||
return fileStream.good();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user