automatically center the model in the renderer

Mon, 02 Apr 2018 13:21:15 +0300

author
Teemu Piippo <teemu@hecknology.net>
date
Mon, 02 Apr 2018 13:21:15 +0300
changeset 1371
b8df4748d04e
parent 1370
c6d5ba08c62c
child 1372
641060842b92

automatically center the model in the renderer

src/glShared.h file | annotate | diff | comparison | revisions
src/glcompiler.cpp file | annotate | diff | comparison | revisions
src/glcompiler.h file | annotate | diff | comparison | revisions
src/glrenderer.cpp file | annotate | diff | comparison | revisions
src/types/vertex.cpp file | annotate | diff | comparison | revisions
src/types/vertex.h file | annotate | diff | comparison | revisions
--- a/src/glShared.h	Mon Apr 02 10:59:38 2018 +0300
+++ b/src/glShared.h	Mon Apr 02 13:21:15 2018 +0300
@@ -28,6 +28,11 @@
 	glMultMatrixf(matrix.constData());
 }
 
+inline void glTranslatef(const Vertex& vertex)
+{
+	glTranslatef(vertex.x, vertex.y, vertex.z);
+}
+
 inline void glVertex(const Vertex& vertex)
 {
 	glVertex3f(vertex.x, vertex.y, vertex.z);
--- a/src/glcompiler.cpp	Mon Apr 02 10:59:38 2018 +0300
+++ b/src/glcompiler.cpp	Mon Apr 02 13:21:15 2018 +0300
@@ -331,6 +331,7 @@
 		// If we have data relating to this object, remove it.
 		// The VBOs have changed now and need to be merged.
 		m_objectInfo.remove(index);
+		this->needBoundingBoxRebuild = true;
 		needMerge();
 	}
 }
@@ -437,6 +438,12 @@
 		normals[i] = QVector3D::crossProduct(v3 - v2, v1 - v2).normalized();
 	}
 
+	if (not this->needBoundingBoxRebuild)
+	{
+		for (int i = 0; i < vertexCount; i += 1)
+			this->boundingBox.consider(poly.vertices[i]);
+	}
+
 	for (VboSubclass complement : iterateEnum<VboSubclass>())
 	{
 		const int vbonum = vboNumber (surface, complement);
@@ -475,6 +482,44 @@
 	}
 }
 
+/*
+ * Returns the center point of the model.
+ */
+Vertex GLCompiler::modelCenter()
+{
+	// If the bounding box is invalid, rebuild it now.
+	if (this->needBoundingBoxRebuild)
+	{
+		// If there's something still queued for compilation, we need to build those first so
+		// that they get into the bounding box.
+		this->compileStaged();
+		this->boundingBox = {};
+		QMapIterator<QPersistentModelIndex, ObjectVboData> iterator {m_objectInfo};
+
+		while (iterator.hasNext())
+		{
+			iterator.next();
+
+			for (VboClass vboclass : {VboClass::Triangles, VboClass::Quads})
+			{
+				// Read in the surface vertices and add them to the bounding box.
+				int vbonum = vboNumber(vboclass, VboSubclass::Surfaces);
+				const auto& vector = iterator.value().data[vbonum];
+
+				for (int i = 0; i + 2 < countof(vector); i += 3)
+					this->boundingBox.consider({vector[i], vector[i + 1], vector[i + 2]});
+			}
+		}
+
+		this->needBoundingBoxRebuild = false;
+	}
+
+	if (not this->boundingBox.isEmpty())
+		return this->boundingBox.center();
+	else
+		return {};
+}
+
 int GLCompiler::vboNumber (VboClass surface, VboSubclass complement)
 {
 	return (static_cast<int>(surface) * EnumLimits<VboSubclass>::Count) + static_cast<int>(complement);
@@ -529,6 +574,8 @@
 {
 	for (int row = topLeft.row(); row <= bottomRight.row(); row += 1)
 		m_staged.insert(m_renderer->model()->index(row));
+
+	this->needBoundingBoxRebuild = true;
 }
 
 void GLCompiler::handleObjectHighlightingChanged(
--- a/src/glcompiler.h	Mon Apr 02 10:59:38 2018 +0300
+++ b/src/glcompiler.h	Mon Apr 02 13:21:15 2018 +0300
@@ -20,6 +20,7 @@
 #include "main.h"
 #include "glrenderer.h"
 #include "glShared.h"
+#include "types/boundingbox.h"
 #include <QMap>
 #include <QSet>
 
@@ -35,6 +36,7 @@
 	~GLCompiler();
 
 	void initialize();
+	Vertex modelCenter();
 	void prepareVBO (int vbonum);
 	GLuint vbo (int vbonum) const;
 	int vboSize (int vbonum) const;
@@ -77,9 +79,11 @@
 	QSet<QPersistentModelIndex> m_staged; // Objects that need to be compiled
 	GLuint m_vbo[NumVbos];
 	bool m_vboChanged[NumVbos] = {true};
+	bool needBoundingBoxRebuild = true;
 	int m_vboSizes[NumVbos] = {0};
 	GLRenderer* m_renderer;
 	QItemSelectionModel* _selectionModel = nullptr;
+	BoundingBox boundingBox;
 
 private slots:
 	void handleRowInsertion(const QModelIndex&, int first, int last);
--- a/src/glrenderer.cpp	Mon Apr 02 10:59:38 2018 +0300
+++ b/src/glrenderer.cpp	Mon Apr 02 13:21:15 2018 +0300
@@ -387,6 +387,7 @@
 		glTranslatef(0.0f, 0.0f, -2.0f);
 		glTranslatef(panning (X), panning (Y), -zoom());
 		glMultMatrixf(m_rotationMatrix.constData());
+		glTranslatef(-this->m_compiler->modelCenter());
 	}
 
 	glEnableClientState (GL_NORMAL_ARRAY);
--- a/src/types/vertex.cpp	Mon Apr 02 10:59:38 2018 +0300
+++ b/src/types/vertex.cpp	Mon Apr 02 13:21:15 2018 +0300
@@ -200,6 +200,14 @@
 }
 
 /*
+ * Returns a vertex with all coordinates inverted.
+ */
+Vertex operator-(const Vertex& vertex)
+{
+	return {-vertex.x, -vertex.y, -vertex.z};
+}
+
+/*
  * Inserts this vertex into a data stream. This is needed for vertices to be
  * stored in QSettings.
  */
--- a/src/types/vertex.h	Mon Apr 02 10:59:38 2018 +0300
+++ b/src/types/vertex.h	Mon Apr 02 13:21:15 2018 +0300
@@ -56,8 +56,8 @@
 }
 
 Q_DECLARE_METATYPE(Vertex)
+qreal distance(const Vertex& one, const Vertex& other);
 unsigned int qHash(const Vertex& key);
+Vertex operator-(const Vertex& vertex);
 QDataStream& operator<<(QDataStream& out, const Vertex& vertex);
 QDataStream& operator>>(QDataStream& in, Vertex& vertex);
-
-qreal distance(const Vertex& one, const Vertex& other);

mercurial