Rotation improvements; allow radials be inlined

Sun, 21 Apr 2013 16:36:20 +0300

author
Santeri Piippo <crimsondusk64@gmail.com>
date
Sun, 21 Apr 2013 16:36:20 +0300
changeset 121
7e87c85ad092
parent 120
607301744394
child 122
33c227d0fa1b

Rotation improvements; allow radials be inlined

bbox.cpp file | annotate | diff | comparison | revisions
bbox.h file | annotate | diff | comparison | revisions
gldraw.cpp file | annotate | diff | comparison | revisions
gui_editactions.cpp file | annotate | diff | comparison | revisions
types.h file | annotate | diff | comparison | revisions
--- a/bbox.cpp	Sun Apr 21 04:17:05 2013 +0300
+++ b/bbox.cpp	Sun Apr 21 16:36:20 2013 +0300
@@ -28,6 +28,13 @@
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
+bbox::bbox () {
+	reset ();
+}
+
+// =============================================================================
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+// =============================================================================
 void bbox::calculate () {
 	reset ();
 	
@@ -35,19 +42,19 @@
 		return;
 	
 	for (LDObject* obj : g_CurrentFile->objects)
-		checkObject (obj);
+		calcObject (obj);
 }
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-void bbox::checkObject (LDObject* obj) {
+void bbox::calcObject (LDObject* obj) {
 	switch (obj->getType ()) {
 	case OBJ_Line:
 		{
 			LDLine* line = static_cast<LDLine*> (obj);
 			for (short i = 0; i < 2; ++i)
-				checkVertex (line->vaCoords[i]);
+				calcVertex (line->vaCoords[i]);
 		}
 		break;
 	
@@ -55,7 +62,7 @@
 		{
 			LDTriangle* tri = static_cast<LDTriangle*> (obj);
 			for (short i = 0; i < 3; ++i)
-				checkVertex (tri->vaCoords[i]);
+				calcVertex (tri->vaCoords[i]);
 		}
 		break;
 	
@@ -63,7 +70,7 @@
 		{
 			LDQuad* quad = static_cast<LDQuad*> (obj);
 			for (short i = 0; i < 4; ++i)
-				checkVertex (quad->vaCoords[i]);
+				calcVertex (quad->vaCoords[i]);
 		}
 		break;
 	
@@ -71,7 +78,7 @@
 		{
 			LDCondLine* line = static_cast<LDCondLine*> (obj);
 			for (short i = 0; i < 4; ++i)
-				checkVertex (line->vaCoords[i]);
+				calcVertex (line->vaCoords[i]);
 		}
 		break;
 	
@@ -81,10 +88,23 @@
 			vector<LDObject*> objs = ref->inlineContents (true, true);
 			
 			for (LDObject* obj : objs) {
-				checkObject (obj);
+				calcObject (obj);
 				delete obj;
 			}
 		}
+		break;
+	
+	case OBJ_Radial:
+		{
+			LDRadial* rad = static_cast<LDRadial*> (obj);
+			vector<LDObject*> objs = rad->decompose (true);
+			
+			for (LDObject* obj : objs) {
+				calcObject (obj);
+				delete obj;
+			}
+		}
+		break;
 	
 	default:
 		break;
@@ -94,7 +114,7 @@
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-void bbox::checkVertex (vertex v) {
+void bbox::calcVertex (vertex v) {
 	CHECK_DIMENSION (v, x)
 	CHECK_DIMENSION (v, y)
 	CHECK_DIMENSION (v, z)
@@ -103,22 +123,15 @@
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-bbox::bbox () {
-	reset ();
+void bbox::reset () {
+	v0.x = v0.y = v0.z = +0x7FFFFFFF;
+	v1.x = v1.y = v1.z = -0x7FFFFFFF;
 }
 
 // =============================================================================
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 // =============================================================================
-void bbox::reset () {
-	memset (&v0, 0, sizeof v0);
-	memset (&v1, 0, sizeof v1);
-}
-
-// =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
-double bbox::calcSize () {
+double bbox::size () const {
 	double fXScale = (v0.x - v1.x);
 	double fYScale = (v0.y - v1.y);
 	double fZScale = (v0.z - v1.z);
@@ -135,3 +148,11 @@
 	
 	return 1.0f;
 }
+
+// =============================================================================
+vertex bbox::center () const {
+	return vertex (
+		(v0.x + v1.x) / 2,
+		(v0.y + v1.y) / 2,
+		(v0.z + v1.z) / 2);
+}
\ No newline at end of file
--- a/bbox.h	Sun Apr 21 04:17:05 2013 +0300
+++ b/bbox.h	Sun Apr 21 16:36:20 2013 +0300
@@ -20,14 +20,15 @@
 #define __BBOX_H__
 
 #include "common.h"
+#include "types.h"
 
 // =============================================================================
-// The bounding box, bbox for short, is the
-// box that encompasses the model we have open.
+// bbox
+//
+// The bounding box is the box that encompasses a given set of objects. The
+// global instance g_BBox is the bbox for the model we have open.
 // v0 is the minimum vertex, v1 is the maximum vertex.
 // =============================================================================
-// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
-// =============================================================================
 class bbox {
 public:
 	vertex v0, v1;
@@ -36,11 +37,20 @@
 	
 	void reset ();
 	void calculate ();
-	double calcSize ();
+	double size () const;
+	void calcObject (LDObject* obj);
+	void calcVertex (vertex v);
+	vertex center () const;
 	
-private:
-	void checkObject (LDObject* obj);
-	void checkVertex (vertex v);
+	bbox& operator<< (LDObject* obj) {
+		calcObject (obj);
+		return *this;
+	}
+	
+	bbox& operator<< (vertex& v) {
+		calcVertex (v);
+		return *this;
+	}
 };
 
 #endif
\ No newline at end of file
--- a/gldraw.cpp	Sun Apr 21 04:17:05 2013 +0300
+++ b/gldraw.cpp	Sun Apr 21 16:36:20 2013 +0300
@@ -272,7 +272,7 @@
 	g_faObjectOffset[0] = -(g_BBox.v0.x + g_BBox.v1.x) / 2;
 	g_faObjectOffset[1] = -(g_BBox.v0.y + g_BBox.v1.y) / 2;
 	g_faObjectOffset[2] = -(g_BBox.v0.z + g_BBox.v1.z) / 2;
-	g_StoredBBoxSize = g_BBox.calcSize ();
+	g_StoredBBoxSize = g_BBox.size ();
 	
 	if (!g_CurrentFile) {
 		printf ("renderer: no files loaded, cannot compile anything\n");
--- a/gui_editactions.cpp	Sun Apr 21 04:17:05 2013 +0300
+++ b/gui_editactions.cpp	Sun Apr 21 16:36:20 2013 +0300
@@ -24,6 +24,7 @@
 #include "zz_historyDialog.h"
 #include "zz_setContentsDialog.h"
 #include "misc.h"
+#include "bbox.h"
 
 vector<LDObject*> g_Clipboard;
 
@@ -125,20 +126,20 @@
 	}
 	
 	for (LDObject* obj : sel) {
-		// Obviously, only subfiles can be inlined.
-		if (obj->getType() != OBJ_Subfile)
-			continue;
-		
 		// Get the index of the subfile so we know where to insert the
 		// inlined contents.
 		long idx = obj->getIndex (g_CurrentFile);
 		if (idx == -1)
 			continue;
 		
-		LDSubfile* ref = static_cast<LDSubfile*> (obj);
+		vector<LDObject*> objs;
 		
-		// Get the inlined objects. These are clones of the subfile's contents.
-		vector<LDObject*> objs = ref->inlineContents (bDeep, true);
+		if (obj->getType() == OBJ_Subfile)
+			objs = static_cast<LDSubfile*> (obj)->inlineContents (bDeep, true);
+		else if (obj->getType() == OBJ_Radial)
+			objs = static_cast<LDRadial*> (obj)->decompose (true);
+		else
+			continue;
 		
 		// Merge in the inlined objects
 		for (LDObject* inlineobj : objs) {
@@ -151,8 +152,8 @@
 		}
 		
 		// Delete the subfile now as it's been inlined.
-		g_CurrentFile->forgetObject (ref);
-		delete ref;
+		g_CurrentFile->forgetObject (obj);
+		delete obj;
 	}
 	
 	History::addEntry (new InlineHistory (ulaBitIndices, ulaRefIndices, paRefs, bDeep));
@@ -568,7 +569,12 @@
 // =============================================================================
 static void doRotate (const short l, const short m, const short n) {
 	std::vector<LDObject*> sel = g_ForgeWindow->selection ();
-	const double angle = (pi * 22.5f) / 360; // TODO
+	bbox box;
+	vertex origin;
+	std::vector<vertex*> queue;
+	
+	// TODO: generalize the angle
+	const double angle = (pi * 22.5f) / 360;
 	
 	// ref: http://en.wikipedia.org/wiki/Transformation_matrix#Rotation_2
 	matrix transform (
@@ -586,39 +592,35 @@
 	);
 	
 	// Calculate center vertex
-	vertex origin;
-	short numverts = 0;
+	for (LDObject* obj : sel)
+		box << obj;
 	
-	for (LDObject* obj : sel) {
-		for (short i = 0; i < obj->vertices (); ++i) {
-			origin.x += obj->vaCoords[i].x;
-			origin.y += obj->vaCoords[i].y;
-			origin.z += obj->vaCoords[i].z;
-			numverts++;
-		}
-	}
-	
-	origin.x /= numverts;
-	origin.y /= numverts;
-	origin.z /= numverts;
-	
-	std::vector<vertex*> verticesToTransform;
+	origin = box.center ();
+	printf ("origin: %s\n", origin.getStringRep (true).chars ());
 	
 	// Apply the above matrix to everything
 	for (LDObject* obj : sel) {
 		if (obj->vertices ())
 			for (short i = 0; i < obj->vertices (); ++i)
-				verticesToTransform.push_back (&obj->vaCoords[i]);
-		else if (obj->getType () == OBJ_Subfile)
-			verticesToTransform.push_back (&(static_cast<LDSubfile*> (obj)->vPosition));
-		else if (obj->getType () == OBJ_Radial)
-			verticesToTransform.push_back (&(static_cast<LDRadial*> (obj)->vPosition));
-		else if (obj->getType () == OBJ_Vertex)
-			verticesToTransform.push_back (&(static_cast<LDVertex*> (obj)->vPosition));
+				queue.push_back (&obj->vaCoords[i]);
+		else if (obj->getType () == OBJ_Subfile) {
+			LDSubfile* ref = static_cast<LDSubfile*> (obj);
+			
+			queue.push_back (&ref->vPosition);
+			ref->mMatrix = ref->mMatrix * transform;
+		} else if (obj->getType () == OBJ_Radial) {
+			LDRadial* rad = static_cast<LDRadial*> (obj);
+			
+			queue.push_back (&rad->vPosition);
+			// rad->mMatrix = rad->mMatrix * transform;
+		} else if (obj->getType () == OBJ_Vertex)
+			queue.push_back (&static_cast<LDVertex*> (obj)->vPosition);
 	}
 	
-	for (vertex* v : verticesToTransform) {
-		v->transform (transform, origin);
+	for (vertex* v : queue) {
+		v->move (-origin);
+		v->transform (transform, g_Origin);
+		v->move (origin);
 	}
 	
 	g_ForgeWindow->refresh ();
--- a/types.h	Sun Apr 21 04:17:05 2013 +0300
+++ b/types.h	Sun Apr 21 16:36:20 2013 +0300
@@ -25,6 +25,7 @@
 		z = fZ;
 	}
 	
+	// =========================================================================
 	void move (vertex other) {
 		x += other.x;
 		y += other.y;
@@ -38,6 +39,20 @@
 	}
 	
 	// =========================================================================
+	vertex operator/ (const double d) {
+		vertex other (*this);
+		return other /= d;
+	}
+	
+	// =========================================================================
+	vertex& operator/= (const double d) {
+		x /= d;
+		y /= d;
+		z /= d;
+		return *this;
+	}
+	
+	// =========================================================================
 	vertex operator- () const {
 		return vertex (-x, -y, -z);
 	}

mercurial