[Gtkradiant] r4807 - GtkRadiant/trunk/radiant

svn-noreply at zerowing.idsoftware.com svn-noreply at zerowing.idsoftware.com
Sat Sep 25 16:59:28 CDT 2004


Author: spog
Date: 2004-09-25 16:59:23 -0500 (Sat, 25 Sep 2004)
New Revision: 4807

Modified:
   GtkRadiant/trunk/radiant/surfacedialog.cpp
Log:
applied latest textool patch

Modified: GtkRadiant/trunk/radiant/surfacedialog.cpp
===================================================================
--- GtkRadiant/trunk/radiant/surfacedialog.cpp	2004-09-25 20:52:28 UTC (rev 4806)
+++ GtkRadiant/trunk/radiant/surfacedialog.cpp	2004-09-25 21:59:23 UTC (rev 4807)
@@ -71,11 +71,16 @@
 #include "commands.h"
 #include "stringstream.h"
 
-//#define TEXTOOL_ENABLED
+//NOTE: Proper functioning of Textool currently requires that the "#if 1" lines in
+//      brush_primit.h be changed to "#if 0". add/removeScale screws this up ATM. :-)
+//      Plus, Radiant seems to work just fine without that stuff. ;-)
 
-#if defined(TEXTOOL_ENABLED)
+#define TEXTOOL_ENABLED 0
 
+#if TEXTOOL_ENABLED
+
 //Shamus: Textool function prototypes
+gboolean Textool_size_allocate(GtkWidget *, GtkAllocation *, gpointer);
 gboolean Textool_expose(GtkWidget *, GdkEventExpose *, gpointer);
 gboolean Textool_button_press(GtkWidget *, GdkEventButton *, gpointer);
 gboolean Textool_button_release(GtkWidget *, GdkEventButton *, gpointer);
@@ -266,7 +271,7 @@
 void SurfaceInspector_SelectionChanged(const SelectableInstance& selectable)
 {
   SurfaceInspector_updateSelection();
-#if defined(TEXTOOL_ENABLED)
+#if TEXTOOL_ENABLED
   //Shamus:
   Textool_Initialize();							// Set up textool for the new texture
 //globalOutputStream() << "--> [SurfaceInspector_SelectionChanged] Queue...\n";
@@ -296,7 +301,7 @@
       {
         SurfaceInspector_SetSelectedShader(name.c_str());
       }
-#if defined(TEXTOOL_ENABLED)
+#if TEXTOOL_ENABLED
   //Shamus:
 //This doesn't do crap either!
 //This really doesn't seem to do anything. :-(
@@ -417,7 +422,7 @@
   g_SurfaceInspector.importData();
   g_SurfaceInspector.ShowDlg();
 
-#if defined(TEXTOOL_ENABLED)
+#if TEXTOOL_ENABLED
   if(g_bp_globals.m_bBrushPrimitMode)
   {
   //Shamus:
@@ -483,12 +488,13 @@
   TexDef_Construct_Default(texdef, brushprimit_texdef);
 //globalOutputStream() << "    Select_SetTexdef()...\n";
 
-#if defined(TEXTOOL_ENABLED)
+#if TEXTOOL_ENABLED
 
   //Shamus:
   if (g_bp_globals.m_bBrushPrimitMode)
   {
     // Scale up texture width/height if in BP mode...
+//NOTE: This may not be correct any more! :-P
     if (!g_SelectedFaceInstances.empty())
     {
       Face & face = g_SelectedFaceInstances.last().face();
@@ -504,7 +510,7 @@
 
   Select_SetTexdef(texdef, brushprimit_texdef);
 
-#if defined(TEXTOOL_ENABLED)
+#if TEXTOOL_ENABLED
 
   //Shamus:
   if (g_bp_globals.m_bBrushPrimitMode)
@@ -521,7 +527,7 @@
   g_SurfaceInspector.exportData();
   SurfaceInspector_FitTexture();
 
-#if defined(TEXTOOL_ENABLED)
+#if TEXTOOL_ENABLED
 
   //Shamus:
   if (g_bp_globals.m_bBrushPrimitMode)
@@ -952,7 +958,7 @@
       }
     }
 
-#if defined(TEXTOOL_ENABLED)
+#if TEXTOOL_ENABLED
     if(g_bp_globals.m_bBrushPrimitMode)
 // Shamus: Textool goodies...
     {
@@ -968,10 +974,10 @@
         GTK_WIDGET_SET_FLAGS(g_textoolWin, GTK_CAN_FOCUS);
         // <-- end stuff...
         gtk_widget_show(g_textoolWin);
-        gtk_widget_set_usize(g_textoolWin, -1, 220);	//Yeah!
+        gtk_widget_set_usize(g_textoolWin, -1, 240);	//Yeah!
         gtk_container_add(GTK_CONTAINER(frame), g_textoolWin);
 
-//      g_signal_connect(G_OBJECT(g_textoolWin), "size_allocate", G_CALLBACK(Textool_size_allocate), NULL);
+        g_signal_connect(G_OBJECT(g_textoolWin), "size_allocate", G_CALLBACK(Textool_size_allocate), NULL);
         g_signal_connect(G_OBJECT(g_textoolWin), "expose_event", G_CALLBACK(Textool_expose), NULL);
         g_signal_connect(G_OBJECT(g_textoolWin), "button_press_event", G_CALLBACK(Textool_button_press), NULL);
         g_signal_connect(G_OBJECT(g_textoolWin), "button_release_event", G_CALLBACK(Textool_button_release), NULL);
@@ -1129,7 +1135,7 @@
   UndoableCommand undo("textureProjectionSetSelected");
   Select_SetTexdef(texdef, brushprimit_texdef);
 
-#if defined(TEXTOOL_ENABLED)
+#if TEXTOOL_ENABLED
 
   //Shamus:
   if (g_bp_globals.m_bBrushPrimitMode)
@@ -1205,16 +1211,18 @@
 {
 }
 
-#if defined(TEXTOOL_ENABLED)
+#if TEXTOOL_ENABLED
 //
 //Shamus: Textool functions, including GTK+ callbacks
 //
 
+//NOTE: Black screen when TT first comes up is caused by an uninitialized Extent... !!! FIX !!!
+//      But... You can see down below that it *is* initialized! WTF?
 struct Extent
 {
 	float minX, minY, maxX, maxY;
-	float width(void) { return maxX - minX; }
-	float height(void) { return maxY - minY; }
+	float width(void) { return fabs(maxX - minX); }
+	float height(void) { return fabs(maxY - minY); }
 };
 //This seems to control the texture scale... (Yep! ;-)
 Extent extents = { -2.0f, -2.0f, +2.0f, +2.0f };
@@ -1227,16 +1235,35 @@
 Vector2 textureSize;
 Vector2 windowSize;
 #define VP_PADDING	1.2
+#define PI			3.14159265358979
+#define RAD_TO_DEG	(180.0 / 3.14159265358979)
+#define DEG_TO_RAD	(3.14159265358979 / 180.0)
 bool lButtonDown = false;
 bool rButtonDown = false;
 int dragPoint;
 int anchorPoint;
 bool haveAnchor = false;
 brushprimit_texdef_t origBP;					// Original brush primitive (before we muck it up)
-Vector2 centroid;
 float controlRadius = 5.0f;
-float rotationAngle = 45.0f;
+float rotationAngle = 0.0f;
+float rotationAngle2 = 0.0f;
+float oldRotationAngle;
+Vector2 rotationPoint;
+bool translatingX = false;						// Widget state variables
+bool translatingY = false;
+bool scalingX = false;
+bool scalingY = false;
+bool rotating = false;
+bool resizingX = false;							// Not sure what this means... :-/
+bool resizingY = false;
+float origAngle, origScaleX, origScaleY;
+Vector2 oldCenter;
 
+// Function prototypes (move up to top later...)
+
+void DrawCircularArc(Vector2 ctr, float startAngle, float endAngle, float radius);
+
+
 void CopyPointsFromSelectedFace(void)
 {
 	// Make sure that there's a face and winding to get!
@@ -1257,37 +1284,48 @@
 
 	winding_t & w = face.winding();
 	int count = 0;
-	centroid.x() = centroid.y() = 0;
 
 	for(winding_t::const_iterator i=w.begin(); i!=w.end(); i++)
 	{
 		origPts[count].x() = pts[count].x() = (*i).texcoord.x(),
 		origPts[count].y() = pts[count].y() = (*i).texcoord.y();
 		count++;
+	}
 
-		// While we're here, calculate the "centroid" of the texture vertices...
+	numPts = count;
+//globalOutputStream() << "--> Original BP: [" << origBP.coords[0][0] << "][" << origBP.coords[0][1] << "][" << origBP.coords[0][2] << "]\n";
+//globalOutputStream() << "                 [" << origBP.coords[1][0] << "][" << origBP.coords[1][1] << "][" << origBP.coords[1][2] << "]\n";
+//float angle = atan2(origBP.coords[0][1], origBP.coords[0][0]) * 180.0f / 3.141592653589f;
+	origAngle = (origBP.coords[0][1] > 0 ? PI : -PI);	// Could also be -PI... !!! FIX !!! [DONE]
 
-		centroid.x() += (*i).texcoord.x();
-		centroid.y() += (*i).texcoord.y();
-	}
+	if (origBP.coords[0][0] != 0.0f)
+		origAngle = atan(origBP.coords[0][1] / origBP.coords[0][0]);
 
-	numPts = count;
-	centroid.x() /= count;						// Here's where we actually caluculate it... :-P
-	centroid.y() /= count;
+	origScaleX = origBP.coords[0][0] / cos(origAngle);
+	origScaleY = origBP.coords[1][1] / cos(origAngle);
+	rotationAngle = origAngle;
+	oldCenter[0] = oldCenter[1] = 0;
+
+globalOutputStream() << "--> BP stats: ang=" << origAngle * RAD_TO_DEG << ", scale=" << origScaleX << "/" << origScaleY << "\n";
+//Should also set the Flip X/Y checkboxes here as well... !!! FIX !!!
+//Also: should reverse texture left/right up/down instead of flipping the points...
 }
 
+	brushprimit_texdef_t bp;
 //This approach is probably wrongheaded and just not right anyway. So, !!! FIX !!! [DONE]
 void Textool_CommitChanges(void)
 {
-	brushprimit_texdef_t bp;
 	texdef_t t;									// Throwaway, since this is BP only
 
 	bp.coords[0][0] = tm.coords[0][0] * origBP.coords[0][0] + tm.coords[0][1] * origBP.coords[1][0];
 	bp.coords[0][1] = tm.coords[0][0] * origBP.coords[0][1] + tm.coords[0][1] * origBP.coords[1][1];
 	bp.coords[0][2] = tm.coords[0][0] * origBP.coords[0][2] + tm.coords[0][1] * origBP.coords[1][2] + tm.coords[0][2];
+//Ok, this works for translation...
+//	bp.coords[0][2] = tm.coords[0][0] * origBP.coords[0][2] + tm.coords[0][1] * origBP.coords[1][2] + tm.coords[0][2] * textureSize.x();
 	bp.coords[1][0] = tm.coords[1][0] * origBP.coords[0][0] + tm.coords[1][1] * origBP.coords[1][0];
 	bp.coords[1][1] = tm.coords[1][0] * origBP.coords[0][1] + tm.coords[1][1] * origBP.coords[1][1];
 	bp.coords[1][2] = tm.coords[1][0] * origBP.coords[0][2] + tm.coords[1][1] * origBP.coords[1][2] + tm.coords[1][2];
+//	bp.coords[1][2] = tm.coords[1][0] * origBP.coords[0][2] + tm.coords[1][1] * origBP.coords[1][2] + tm.coords[1][2] * textureSize.y();
 
 //This doesn't work:	g_brush_texture_changed();
 // Let's try this:
@@ -1300,15 +1338,32 @@
 //I.e., click on textool window, translate face wireframe, then controls go crazy. Dunno why.
 //It's because there were some uncommented out add/removeScale functions in brush.h and a
 //removeScale in brushwrapper.cpp... :-/
+//Translate isn't working at all now... :-(
+//It's because we need to multiply in some scaling factor (prolly the texture width/height)
+//Yep. :-P
 }
 
 void UpdateControlPoints(void)
 {
+//This is all wrong--it doesn't take the BP scaling into account... Or the ST scaling... !!! FIX !!!
 	for(int i=0; i<numPts; i++)
-		pts[i].x() = origPts[i].x() * tm.coords[0][0] + origPts[i].y() * tm.coords[0][1] + tm.coords[0][2],
-		pts[i].y() = origPts[i].x() * tm.coords[1][0] + origPts[i].y() * tm.coords[1][1] + tm.coords[1][2];
+/*		pts[i].x() = origPts[i].x() * tm.coords[0][0] + origPts[i].y() * tm.coords[0][1] + tm.coords[0][2],
+		pts[i].y() = origPts[i].x() * tm.coords[1][0] + origPts[i].y() * tm.coords[1][1] + tm.coords[1][2];//*/
+		// Kludge (& doesn't work correctly for non-square textures... !!! FIX !!!)
+		pts[i].x() = origPts[i].x() * tm.coords[0][0] + origPts[i].y() * tm.coords[0][1] + (tm.coords[0][2] / textureSize.x()),
+		pts[i].y() = origPts[i].x() * tm.coords[1][0] + origPts[i].y() * tm.coords[1][1] + (tm.coords[1][2] / textureSize.y());//*/
 
 	Textool_CommitChanges();
+
+//Disnowok...
+// NOTE FROM THE FUTURE: The reason we don't do the following is that the points *have already
+// been run through origBP*! Doing it again only screws things up worse!
+/*
+//	brushprimit_texdef_t bp = g_selectedBrushPrimitTexdef;
+
+	for(int i=0; i<numPts; i++)
+		pts[i].x() = origPts[i].x() * bp.coords[0][0] + origPts[i].y() * bp.coords[0][1] + bp.coords[0][2],
+		pts[i].y() = origPts[i].x() * bp.coords[1][0] + origPts[i].y() * bp.coords[1][1] + bp.coords[1][2];//*/
 }
 /*
 Fit texture code calls this:
@@ -1362,25 +1417,145 @@
 which just copies from brushpr to m_brushpr...
 */
 
-//Small problem with this thing: It's scaled to the texture which is all screwed up... !!! FIX !!!
+//Small problem with this thing: It's scaled to the texture which is all screwed up... !!! FIX !!! [DONE]
+//Prolly should separate out the grid drawing so that we can draw it behind the polygon.
+float gridWidth = 1.3f;// Let's try an absolute height... WORKS!!!
+// NOTE that 2.0 is the height of the viewport. Dunno why... Should make collision
+//      detection easier...
+float gridRadius = gridWidth * 0.5f;
+
+float widgetColor[10][3] = {
+	{ 1.0000f, 0.2000f, 0.0000f },			// Red
+	{ 0.9137f, 0.9765f, 0.4980f },			// Yellow
+	{ 0.0000f, 0.6000f, 0.3216f },			// Green
+	{ 0.6157f, 0.7726f, 0.8196f },			// Cyan
+	{ 0.4980f, 0.5000f, 0.4716f },			// Grey
+
+	// Highlight colors
+	{ 1.0000f, 0.6000f, 0.4000f },			// Light Red
+	{ 1.0000f, 1.0000f, 0.8980f },			// Light Yellow
+	{ 0.4000f, 1.0000f, 0.7216f },			// Light Green
+	{ 1.0000f, 1.0000f, 1.0000f },			// Light Cyan
+	{ 0.8980f, 0.9000f, 0.8716f }			// Light Grey
+};
+
+#define COLOR_RED			0
+#define COLOR_YELLOW		1
+#define COLOR_GREEN			2
+#define COLOR_CYAN			3
+#define COLOR_GREY			4
+#define COLOR_LT_RED		5
+#define COLOR_LT_YELLOW		6
+#define COLOR_LT_GREEN		7
+#define COLOR_LT_CYAN		8
+#define COLOR_LT_GREY		9
+
 void DrawControlWidgets(void)
 {
-//	qglPushMatrix();
-	qglColor3f(0.0f, 1.0f, 0.2f);
-//	qglTranslatef(centroid.x(), centroid.y(), 0);
+//Note that the grid should go *behind* the face outline... !!! FIX !!!
+	// Grid
+	float xStart = center.x() - (gridWidth / 2.0f);
+	float yStart = center.y() - (gridWidth / 2.0f);
+	float xScale = (extents.height() / extents.width()) * (textureSize.y() / textureSize.x());
+
+	qglPushMatrix();
+//Small problem with this approach: Changing the center point in the TX code doesn't seem to
+//change anything here--prolly because we load a new identity matrix. A couple of ways to fix
+//this would be to get rid of that code, or change the center to a new point by taking into
+//account the transforms that we toss with the new identity matrix. Dunno which is better.
+	qglLoadIdentity();
+	qglScalef(xScale, 1.0, 1.0);				// Will that square it up? Yup.
+	qglRotatef(rotationAngle * RAD_TO_DEG, 0.0, 0.0, -1.0);
+	qglTranslatef(-center.x(), -center.y(), 0.0);
+
+	qglColor3fv(widgetColor[COLOR_GREY]);
+	qglBegin(GL_LINES);
+
+	for(int i=0; i<11; i++)
+	{
+		qglVertex2f(xStart, yStart + i * (gridWidth / 10.0f));
+		qglVertex2f(xStart + gridWidth, yStart + i * (gridWidth / 10.0f));
+		qglVertex2f(xStart + i * (gridWidth / 10.0f), yStart);
+		qglVertex2f(xStart + i * (gridWidth / 10.0f), yStart + gridWidth);
+	}
+
+	qglEnd();
+
+	// Circle
+	qglColor3fv(translatingX && translatingY ? widgetColor[COLOR_LT_YELLOW] : widgetColor[COLOR_YELLOW]);
 	qglBegin(GL_LINE_LOOP);
+	DrawCircularArc(center, 0, 2.0f * PI, gridRadius * 0.16);
 
-controlRadius = 0.5f;
+	qglEnd();
 
-	for(float ang=0; ang<=2.0*3.1415926535f; ang+=0.1)
-		qglVertex2f(centroid.x() + controlRadius * cos(ang), centroid.y() + controlRadius * sin(ang));
+	// Axes
+	qglBegin(GL_LINES);
+	qglColor3fv(translatingY && !translatingX ? widgetColor[COLOR_LT_GREEN] : widgetColor[COLOR_GREEN]);
+	qglVertex2f(center.x(), center.y() + (gridRadius * 0.16));
+	qglVertex2f(center.x(), center.y() + (gridRadius * 1.00));
+	qglColor3fv(translatingX && !translatingY ? widgetColor[COLOR_LT_RED] : widgetColor[COLOR_RED]);
+	qglVertex2f(center.x() + (gridRadius * 0.16), center.y());
+	qglVertex2f(center.x() + (gridRadius * 1.00), center.y());
+	qglEnd();
 
+	// Arrowheads
+	qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+	qglBegin(GL_TRIANGLES);
+	qglColor3fv(translatingY && !translatingX ? widgetColor[COLOR_LT_GREEN] : widgetColor[COLOR_GREEN]);
+	qglVertex2f(center.x(), center.y() + (gridRadius * 1.10));
+	qglVertex2f(center.x() + (gridRadius * 0.06), center.y() + (gridRadius * 0.94));
+	qglVertex2f(center.x() - (gridRadius * 0.06), center.y() + (gridRadius * 0.94));
+	qglColor3fv(translatingX && !translatingY ? widgetColor[COLOR_LT_RED] : widgetColor[COLOR_RED]);
+	qglVertex2f(center.x() + (gridRadius * 1.10), center.y());
+	qglVertex2f(center.x() + (gridRadius * 0.94), center.y() + (gridRadius * 0.06));
+	qglVertex2f(center.x() + (gridRadius * 0.94), center.y() - (gridRadius * 0.06));
 	qglEnd();
+
+	// Arc
+	qglBegin(GL_LINE_STRIP);
+	qglColor3fv(rotating ? widgetColor[COLOR_LT_CYAN] : widgetColor[COLOR_CYAN]);
+	DrawCircularArc(center, 0.03f * PI, 0.47f * PI, gridRadius * 0.90);
+	qglEnd();
+
+	// Boxes
+	qglColor3fv(scalingY && !scalingX ? widgetColor[COLOR_LT_GREEN] : widgetColor[COLOR_GREEN]);
 	qglBegin(GL_LINES);
-	qglVertex2f(centroid.x(), centroid.y());
-	qglVertex2f(centroid.x() + controlRadius * cos(rotationAngle), centroid.y() + controlRadius * sin(rotationAngle));
+	qglVertex2f(center.x() + (gridRadius * 0.20), center.y() + (gridRadius * 1.50));
+	qglVertex2f(center.x() - (gridRadius * 0.20), center.y() + (gridRadius * 1.50));
 	qglEnd();
-//	qglPopMatrix();
+	qglBegin(GL_LINE_LOOP);
+	qglVertex2f(center.x() + (gridRadius * 0.10), center.y() + (gridRadius * 1.40));
+	qglVertex2f(center.x() - (gridRadius * 0.10), center.y() + (gridRadius * 1.40));
+	qglVertex2f(center.x() - (gridRadius * 0.10), center.y() + (gridRadius * 1.20));
+	qglVertex2f(center.x() + (gridRadius * 0.10), center.y() + (gridRadius * 1.20));
+	qglEnd();
+
+	qglColor3fv(scalingX && !scalingY ? widgetColor[COLOR_LT_RED] : widgetColor[COLOR_RED]);
+	qglBegin(GL_LINES);
+	qglVertex2f(center.x() + (gridRadius * 1.50), center.y() + (gridRadius * 0.20));
+	qglVertex2f(center.x() + (gridRadius * 1.50), center.y() - (gridRadius * 0.20));
+	qglEnd();
+	qglBegin(GL_LINE_LOOP);
+	qglVertex2f(center.x() + (gridRadius * 1.40), center.y() + (gridRadius * 0.10));
+	qglVertex2f(center.x() + (gridRadius * 1.40), center.y() - (gridRadius * 0.10));
+	qglVertex2f(center.x() + (gridRadius * 1.20), center.y() - (gridRadius * 0.10));
+	qglVertex2f(center.x() + (gridRadius * 1.20), center.y() + (gridRadius * 0.10));
+	qglEnd();
+
+	qglColor3fv(scalingX && scalingY ? widgetColor[COLOR_LT_CYAN] : widgetColor[COLOR_CYAN]);
+	qglBegin(GL_LINE_STRIP);
+	qglVertex2f(center.x() + (gridRadius * 1.50), center.y() + (gridRadius * 1.10));
+	qglVertex2f(center.x() + (gridRadius * 1.50), center.y() + (gridRadius * 1.50));
+	qglVertex2f(center.x() + (gridRadius * 1.10), center.y() + (gridRadius * 1.50));
+	qglEnd();
+	qglBegin(GL_LINE_LOOP);
+	qglVertex2f(center.x() + (gridRadius * 1.40), center.y() + (gridRadius * 1.40));
+	qglVertex2f(center.x() + (gridRadius * 1.40), center.y() + (gridRadius * 1.20));
+	qglVertex2f(center.x() + (gridRadius * 1.20), center.y() + (gridRadius * 1.20));
+	qglVertex2f(center.x() + (gridRadius * 1.20), center.y() + (gridRadius * 1.40));
+	qglEnd();
+
+	qglPopMatrix();
 }
 
 void DrawControlPoints(void)
@@ -1392,24 +1567,34 @@
 	
 	qglEnd();
 	qglColor3f(0, 1, 0);
-	qglPointSize(6);
+	qglPointSize(4);
 	qglBegin(GL_POINTS);
 
 	for(int i=0; i<numPts; i++)
-	{
-		if (lButtonDown && i == dragPoint)
-			qglColor3f(0, 0, 1);
-		else if (haveAnchor && i == anchorPoint)
-			qglColor3f(1, 0, 0);
-		else
-			qglColor3f(0, 1, 0);
+//	{
+//		if (lButtonDown && i == dragPoint)
+//			qglColor3f(0, 0, 1);
+//		else if (haveAnchor && i == anchorPoint)
+//			qglColor3f(1, 0, 0);
+//		else
+//			qglColor3f(0, 1, 0);
 
 		qglVertex2f(pts[i].x(), pts[i].y());
-	}
+//	}
 
 	qglEnd();
 }
 
+// Note: Setup and all that jazz must be done by the caller!
+
+void DrawCircularArc(Vector2 ctr, float startAngle, float endAngle, float radius)
+{
+	float stepSize = (2.0f * PI) / 200.0f;
+
+	for(float angle=startAngle; angle<=endAngle; angle+=stepSize)
+		qglVertex2f(ctr.x() + radius * cos(angle), ctr.y() + radius * sin(angle));
+}
+
 void Textool_Initialize(void)
 {
 	CopyPointsFromSelectedFace();
@@ -1436,6 +1621,9 @@
 
 	// Do some viewport fitting stuff...
 
+//globalOutputStream() << "--> Center: " << center.x() << ", " << center.y() << "\n";
+//globalOutputStream() << "--> Extents (stage 1): " << extents.minX << ", "
+//	<< extents.maxX << ", " << extents.minY << ", " << extents.maxY << "\n";
 	// TTimo: Apply a ratio to get the area we'll draw.
 	center.x() = 0.5f * (extents.minX + extents.maxX),
 	center.y() = 0.5f * (extents.minY + extents.maxY);
@@ -1443,26 +1631,32 @@
 	extents.minY = center.y() + VP_PADDING * (extents.minY - center.y()),
 	extents.maxX = center.x() + VP_PADDING * (extents.maxX - center.x()),
 	extents.maxY = center.y() + VP_PADDING * (extents.maxY - center.y());
+//globalOutputStream() << "--> Extents (stage 2): " << extents.minX << ", "
+//	<< extents.maxX << ", " << extents.minY << ", " << extents.maxY << "\n";
 
 	// TTimo: We want a texture with the same X / Y ratio.
 	// TTimo: Compute XY space / window size ratio.
-	float SSize = fabs(extents.maxX - extents.minX), TSize = fabs(extents.maxY - extents.minY);
-	float XSize = textureSize.x() * SSize, YSize = textureSize.y() * TSize;
-	float ratioX = XSize / (float)windowSize.x(), ratioY = YSize / (float)windowSize.y();
+	float SSize = extents.width(), TSize = extents.height();
+	float ratioX = textureSize.x() * extents.width() / windowSize.x(),
+		ratioY = textureSize.y() * extents.height() / windowSize.y();
+//globalOutputStream() << "--> Texture size: " << textureSize.x() << ", " << textureSize.y() << "\n";
+//globalOutputStream() << "--> Window size: " << windowSize.x() << ", " << windowSize.y() << "\n";
 
 	if (ratioX > ratioY)
 	{
-		YSize = (float)windowSize.y() * ratioX;
-		TSize = YSize / (float)textureSize.y();
+		TSize = (windowSize.y() * ratioX) / textureSize.y();
+//		TSize = extents.width() * (windowSize.y() / windowSize.x()) * (textureSize.x() / textureSize.y());
 	}
 	else
 	{
-		XSize = (float)windowSize.x() * ratioY;
-		SSize = XSize / (float)textureSize.x();
+		SSize = (windowSize.x() * ratioY) / textureSize.x();
+//		SSize = extents.height() * (windowSize.x() / windowSize.y()) * (textureSize.y() / textureSize.x());
 	}
 
 	extents.minX = center.x() - 0.5f * SSize, extents.maxX = center.x() + 0.5f * SSize,
 	extents.minY = center.y() - 0.5f * TSize, extents.maxY = center.y() + 0.5f * TSize;
+//globalOutputStream() << "--> Extents (stage 3): " << extents.minX << ", "
+//	<< extents.maxX << ", " << extents.minY << ", " << extents.maxY << "\n";
 
 	// Init texture transform matrix
 
@@ -1470,14 +1664,28 @@
 	tm.coords[1][0] = 0.0f, tm.coords[1][1] = 1.0f, tm.coords[1][2] = 0.0f;
 
 	// Probably should init button/anchor states here as well...
+//	rotationAngle = 0.0f;
 }
 
+gboolean Textool_size_allocate(GtkWidget * win, GtkAllocation * a, gpointer)
+{
+	windowSize.x() = a->width;
+	windowSize.y() = a->height;
+//  Camera_updateProjection(camwnd->getCamera());
+	Textool_Initialize();
+//  camwnd->m_window_observer->SetSize(camwnd->getCamera().width, camwnd->getCamera().height);
+//  camwnd->queue_draw();
+	gtk_widget_queue_draw(g_textoolWin);
+
+	return false;
+}
+
 gboolean Textool_expose(GtkWidget * win, GdkEventExpose * e, gpointer)
 {
 //	globalOutputStream() << "--> Textool Window was exposed!\n";
 //	globalOutputStream() << "    (window width/height: " << cc << "/" << e->area.height << ")\n";
 
-	windowSize.x() = e->area.width, windowSize.y() = e->area.height;
+//	windowSize.x() = e->area.width, windowSize.y() = e->area.height;
 //This needs to go elsewhere...
 //	InitTextool();
 
@@ -1528,7 +1736,7 @@
 	return false;
 }
 
-int FindSelectedPoint(int x, int y)
+/*int FindSelectedPoint(int x, int y)
 {
 	for(int i=0; i<numPts; i++)
 	{
@@ -1540,11 +1748,11 @@
 	}
 
 	return -1;
-}
+}//*/
 
-Vector2 anchorPos;
 Vector2 trans;
 Vector2 trans2;
+Vector2 oldTrans;
 gboolean Textool_button_press(GtkWidget * win, GdkEventButton * e, gpointer)
 {
 //	globalOutputStream() << "--> Textool button press...\n";
@@ -1552,52 +1760,26 @@
 	if (e->button == 1)
 	{
 		lButtonDown = true;
-		int i = FindSelectedPoint((int)e->x, (int)e->y);
-
-		if (i != -1)
-		{
-//globalOutputStream() << "--> Clicked on point #" << i << "... ";
-			dragPoint = i;
-
-			// TTimo: Perhaps we won't use translation, but we can compute it anyway.
-//			ComputeTransOffset(i);
-			if (haveAnchor)
-			{
-//Is this necessary?
-				// TTimo: We have an Anchor and selected another point.
-				anchorPos.x() = pts[anchorPoint].x();
-				anchorPos.y() = pts[anchorPoint].y();
-
-				if (anchorPoint == i)
-					// TTimo: This means we selected the Anchor, so we'll translate.
-					haveAnchor = false,
-					trans.x() = -tm.coords[0][0] * pts[i].x() - tm.coords[0][1] * pts[i].y(),
-					trans.y() = -tm.coords[1][0] * pts[i].x() - tm.coords[1][1] * pts[i].y();
-			}
-			else
-				haveAnchor = true, anchorPoint = i;
-
-//globalOutputStream() << "--> [Textool_button_press] Queue...\n";
-//			gtk_widget_queue_draw(g_textoolWin);
-
-//			return true;
-		}
-		else//Hmm...
-//Prolly should set it as the coords being pointed at instead... !!! FIX !!! [DONE]
-		{
 //disnowok
 //float nx = windowSize.x() * (e->x - extents.minX) / (extents.maxX - extents.minX);
 //float ny = windowSize.y() * (e->y - extents.minY) / (extents.maxY - extents.minY);
 //disdoes...
-//But I want it to scroll the texture window, not the points...
-			haveAnchor = false, anchorPoint = -1;
-float nx = e->x / windowSize.x() * extents.width() + extents.minX;
-float ny = e->y / windowSize.y() * extents.height() + extents.minY;
-			trans.x() = -tm.coords[0][0] * nx - tm.coords[0][1] * ny;
-			trans.y() = -tm.coords[1][0] * nx - tm.coords[1][1] * ny;
+//But I want it to scroll the texture window, not the points... !!! FIX !!!
+//Actually, should scroll the texture window only when mouse is down on no widgets...
+		float nx = e->x / windowSize.x() * extents.width() + extents.minX;
+		float ny = e->y / windowSize.y() * extents.height() + extents.minY;
+		trans.x() = -tm.coords[0][0] * nx - tm.coords[0][1] * ny;
+		trans.y() = -tm.coords[1][0] * nx - tm.coords[1][1] * ny;
 
-			trans2.x() = e->x, trans2.y() = e->y;
-		}
+//		trans2.x() = e->x, trans2.y() = e->y;
+		trans2.x() = nx, trans2.y() = ny;
+		oldRotationAngle = rotationAngle;
+//		oldTrans.x() = tm.coords[0][2] - nx * textureSize.x();
+//		oldTrans.y() = tm.coords[1][2] - ny * textureSize.y();
+		oldTrans.x() = tm.coords[0][2];
+		oldTrans.y() = tm.coords[1][2];
+		oldCenter.x() = center.x();
+		oldCenter.y() = center.y();
 
 		gtk_widget_queue_draw(g_textoolWin);
 
@@ -1619,7 +1801,19 @@
 
 	if (e->button == 1)
 	{
+/*		float ptx = e->x / windowSize.x() * extents.width() + extents.minX;
+		float pty = e->y / windowSize.y() * extents.height() + extents.minY;
+
+//This prolly should go into the mouse move code...
+//Doesn't work correctly anyway...
+		if (translatingX || translatingY)
+			center.x() = ptx, center.y() = pty;//*/
+
 		lButtonDown = false;
+		rotating = translatingX = translatingY = scalingX = scalingY
+			= resizingX = resizingY = false;
+
+		gtk_widget_queue_draw(g_textoolWin);
 	}
 	else if (e->button == 3)
 	{
@@ -1654,73 +1848,40 @@
 
 	if (lButtonDown)
 	{
-		if (haveAnchor)
+		if (translatingX || translatingY)
 		{
-			// TTimo: There's an anchor, we are rotating the shape.
-			// TTimo: We need to work in XY space for orthonormality.
-			float Pt[2];
-			Vector3 V1, V2;
-			// TTimo: Used in XY space.
-			float XYTM[2][3];
-			float XYRefAnchor[2];
-			float XYAnchor[2];
-//			m_p2DView->GridForWindow( Pt, xPos, yPos );
-Pt[0] = e->x / windowSize.x() * extents.width() + extents.minX;
-Pt[1] = e->y / windowSize.y() * extents.height() + extents.minY;
-			V2[0] = Pt[0] - anchorPos.x();
-			V2[1] = Pt[1] - anchorPos.y();
-			V2[2] = 0.0f;
-			V1[0] = origPts[dragPoint].x() - origPts[anchorPoint].x();
-			V1[1] = origPts[dragPoint].y() - origPts[anchorPoint].y();
-			V1[2] = 0.0f;
-			// TTimo: Compute transformation from V1 to V2.
-			// TTimo: We need to work in XY orthonormal space.
-//			XYSpaceForSTSpace( V1, V1 );
-//			XYSpaceForSTSpace( V2, V2 );
-			vector3_normalise(V2);
-			vector3_normalise(V1);
-			float c = vector3_dot(V1, V2);
-			Vector3 cross = vector3_cross(V1, V2);
-			float s = vector3_length(cross);
-			// TTimo: We compute the transformation matrix in XY space.
-			// TTimo: Reference position of the Anchor in XY space.
-//			XYSpaceForSTSpace( XYRefAnchor, origPts[anchorPoint] );
-			// TTimo: Current position of the Anchor in XY space.
-//			XYSpaceForSTSpace( XYAnchor, anchorPos );
-			// TTimo: Compute transformation matrix.
-			XYTM[0][0] = c;
-			XYTM[1][1] = c;
+			float ptx = e->x / windowSize.x() * extents.width() + extents.minX;
+			float pty = e->y / windowSize.y() * extents.height() + extents.minY;
 
-			if (cross[2] > 0)
-				s = -s;
+//Need to fix this to take the rotation angle into account, so that it moves along
+//the rotated X/Y axis...
+			if (translatingX)
+			{
+//				tm.coords[0][2] = (trans.x() + ptx) * textureSize.x();
+//This works, but only when the angle is zero. !!! FIX !!! [DONE]
+//				tm.coords[0][2] = oldCenter.x() + (ptx * textureSize.x());
+				tm.coords[0][2] = oldTrans.x() + (ptx - trans2.x()) * textureSize.x();
+//				center.x() = oldCenter.x() + (ptx - trans2.x());
+			}
 
-			XYTM[0][1] =  s;
-			XYTM[1][0] = -s;
-			XYTM[0][2] = -c * XYRefAnchor[0] - s * XYRefAnchor[1] + XYAnchor[0];
-			XYTM[1][2] =  s * XYRefAnchor[0] - c * XYRefAnchor[1] + XYAnchor[1];
-			// TTimo: Express this transformation matrix in ST space.
-			tm.coords[0][0] = XYTM[0][0],
-			tm.coords[1][0] = XYTM[1][0] * textureSize.x() / textureSize.y(),
-			tm.coords[0][1] = XYTM[0][1] * textureSize.y() / textureSize.x(),
-			tm.coords[1][1] = XYTM[1][1],
-			tm.coords[0][2] = XYTM[0][2] / textureSize.x(),
-			tm.coords[1][2] = XYTM[1][2] / textureSize.y();
+			if (translatingY)
+			{
+//				tm.coords[1][2] = (trans.y() + pty) * textureSize.y();
+//				tm.coords[1][2] = oldCenter.y() + (pty * textureSize.y());
+				tm.coords[1][2] = oldTrans.y() + (pty - trans2.y()) * textureSize.y();
+//				center.y() = oldCenter.y() + (pty - trans2.y());
+			}
+
+//Need to update center.x/y() so that the widget translates as well. Also, oldCenter
+//is badly named... Should be oldTrans or something like that... !!! FIX !!!
+//Changing center.x/y() here doesn't seem to change anything... :-/
 			UpdateControlPoints();
 		}
-		else
+		else if (rotating)
 		{
-/*			float Pt[2];
-			// no Anchor point is defined, we translate all points
-//			m_p2DView->GridForWindow( m_pPts->data[dragPoint], xPos, yPos );
-Pt[0] = e->x / windowSize.x() * extents.width() + extents.minX;
-Pt[1] = e->y / windowSize.y() * extents.height() + extents.minY;
-			tm.coords[0][2] = Pt[0] + trans.x(),
-			tm.coords[1][2] = Pt[1] + trans.y();
-			UpdateControlPoints();//*/
-
 			// Shamus: New rotate code
-			int cx = (int)(windowSize.x() * (centroid.x() - extents.minX) / extents.width());
-			int cy = (int)(windowSize.y() * (centroid.y() - extents.minY) / extents.height());
+			int cx = (int)(windowSize.x() * (center.x() - extents.minX) / extents.width());
+			int cy = (int)(windowSize.y() * (center.y() - extents.minY) / extents.height());
 			Vector3 v1(trans2.x() - cx, trans2.y() - cy, 0), v2(e->x - cx, e->y - cy, 0);
 
 			vector3_normalise(v1);
@@ -1732,21 +1893,69 @@
 			if (cross[2] > 0)
 				s = -s;
 
-/*
-	bp.coords[0][0] = tm.coords[0][0] * origBP.coords[0][0] + tm.coords[0][1] * origBP.coords[1][0];
-	bp.coords[0][1] = tm.coords[0][0] * origBP.coords[0][1] + tm.coords[0][1] * origBP.coords[1][1];
-	bp.coords[0][2] = tm.coords[0][0] * origBP.coords[0][2] + tm.coords[0][1] * origBP.coords[1][2] + tm.coords[0][2];
-	bp.coords[1][0] = tm.coords[1][0] * origBP.coords[0][0] + tm.coords[1][1] * origBP.coords[1][0];
-	bp.coords[1][1] = tm.coords[1][0] * origBP.coords[0][1] + tm.coords[1][1] * origBP.coords[1][1];
-*/
+// Problem with this: arcsin/cos seems to only return -90 to 90 and 0 to 180...
+// Can't derive angle from that!
+
+//rotationAngle = asin(s);// * 180.0f / 3.141592653589f;
+rotationAngle = acos(c);
+//rotationAngle2 = asin(s);
+if (cross[2] < 0)
+	rotationAngle = -rotationAngle;
+
+//Let's try this:
+//No wok.
+/*c = cos(rotationAngle - oldRotationAngle);
+s = sin(rotationAngle - oldRotationAngle);
+rotationAngle += oldRotationAngle;
+//c += cos(oldRotationAngle);
+//s += sin(oldRotationAngle);
+//rotationAngle += oldRotationAngle;
+//c %= 2.0 * PI;
+//s %= 2.0 * PI;
+//rotationAngle %= 2.0 * PI;//*/
+
 //This is wrong... Hmm...
 //It seems to shear the texture instead of rotating it... !!! FIX !!!
 // Now it rotates correctly. Seems TTimo was overcomplicating things here... ;-)
-			tm.coords[0][0] = c;
-			tm.coords[0][1] = s;
+
+// Seems like what needs to happen here is multiplying these rotations by tm... !!! FIX !!!
+
+// See brush_primit.cpp line 244 (Texdef_AxialTexture()) for where texcoords come from...
+
+			tm.coords[0][0] =  c;
+			tm.coords[0][1] =  s;
 			tm.coords[1][0] = -s;
-			tm.coords[1][1] = c;
-			UpdateControlPoints();//*/
+			tm.coords[1][1] =  c;
+//It doesn't work anymore... Dunno why...
+//tm.coords[0][2] = -trans.x();			// This works!!! Yeah!!!
+//tm.coords[1][2] = -trans.y();
+//nope.
+//tm.coords[0][2] = rotationPoint.x();	// This works, but strangely...
+//tm.coords[1][2] = rotationPoint.y();
+//tm.coords[0][2] = 0;// center.x() / 2.0f;
+//tm.coords[1][2] = 0;// center.y() / 2.0f;
+//No.
+//tm.coords[0][2] = -(center.x() * textureSize.x());
+//tm.coords[1][2] = -(center.y() * textureSize.y());
+//Eh? No, but seems to be getting closer...
+/*float ptx = e->x / windowSize.x() * extents.width() + extents.minX;
+float pty = e->y / windowSize.y() * extents.height() + extents.minY;
+tm.coords[0][2] = -c * center.x() - s * center.y() + ptx;
+tm.coords[1][2] =  s * center.x() - c * center.x() + pty;//*/
+//Kinda works, but center drifts around on non-square textures...
+/*tm.coords[0][2] = (-c * center.x() - s * center.y()) * textureSize.x();
+tm.coords[1][2] = ( s * center.x() - c * center.y()) * textureSize.y();//*/
+//Rotates correctly, but not around the actual center of the face's points...
+/*tm.coords[0][2] = -c * center.x() * textureSize.x() - s * center.y() * textureSize.y();
+tm.coords[1][2] =  s * center.x() * textureSize.x() - c * center.y() * textureSize.y();//*/
+//Yes!!!
+			tm.coords[0][2] = (-c * center.x() * textureSize.x() - s * center.y() * textureSize.y()) + center.x() * textureSize.x();
+			tm.coords[1][2] = ( s * center.x() * textureSize.x() - c * center.y() * textureSize.y()) + center.y() * textureSize.y();//*/
+//This doesn't work...
+//And this is the wrong place for this anyway (I'm pretty sure).
+/*tm.coords[0][2] += oldCenter.x();
+tm.coords[1][2] += oldCenter.y();//*/
+			UpdateControlPoints();
 		}
 
 //globalOutputStream() << "--> [Textool_motion] Queue...\n";
@@ -1754,19 +1963,85 @@
 
 		return true;
 	}
+	else									// Check for widget mouseovers
+	{
+		Vector2 tran;
+		float nx = e->x / windowSize.x() * extents.width() + extents.minX;
+		float ny = e->y / windowSize.y() * extents.height() + extents.minY;
+		// Translate nx/y to the "center" point...
+		nx -= center.x();
+		ny -= center.y();
+		ny = -ny;	// Flip Y-axis so that increasing numbers move up
 
-  return false;
+		tran.x() = tm.coords[0][0] * nx + tm.coords[0][1] * ny;
+		tran.y() = tm.coords[1][0] * nx + tm.coords[1][1] * ny;
+//This doesn't seem to generate a valid distance from the center--for some reason it
+//calculates a fixed number every time
+//Look at nx/y above: they're getting fixed there! !!! FIX !!! [DONE]
+		float dist = sqrt((nx * nx) + (ny * ny));
+		// Normalize to the 2.0 = height standard (for now)
+//globalOutputStream() << "--> Distance before: " << dist;
+		dist = dist * 2.0f / extents.height();
+//globalOutputStream() << ". After: " << dist;
+		tran.x() = tran.x() * 2.0f / extents.height();
+		tran.y() = tran.y() * 2.0f / extents.height();
+//globalOutputStream() << ". Trans: " << tran.x() << ", " << tran.y() << "\n";
+
+//Let's try this instead...
+//Interesting! It seems that e->x/y are rotated
+//(no, they're not--the TM above is what's doing it...)
+nx = ((e->x / windowSize.y()) * 2.0f) - (windowSize.x() / windowSize.y());
+ny = ((e->y / windowSize.y()) * 2.0f) - (windowSize.y() / windowSize.y());
+ny = -ny;
+//Cool! It works! Now just need to do rotation...
+
+		rotating = translatingX = translatingY = scalingX = scalingY
+			= resizingX = resizingY = false;
+
+		if (dist < (gridRadius * 0.16f))
+		{
+			translatingX = translatingY = true;
+		}
+		else if (dist > (gridRadius * 0.16f) && dist < (gridRadius * 1.10f)
+			&& fabs(ny) < (gridRadius * 0.05f) && nx > 0)
+		{
+			translatingX = true;
+		}
+		else if (dist > (gridRadius * 0.16f) && dist < (gridRadius * 1.10f)
+			&& fabs(nx) < (gridRadius * 0.05f) && ny > 0)
+		{
+			translatingY = true;
+		}
+		// Should tighten up the angle on this, or put this test after the axis tests...
+		else if (tran.x() > 0 && tran.y() > 0
+			&& (dist > (gridRadius * 0.82f) && dist < (gridRadius * 0.98f)))
+		{
+			rotating = true;
+		}
+
+		gtk_widget_queue_draw(g_textoolWin);
+
+		return true;
+	}
+
+	return false;
 }
 
 //It seems the fake tex coords conversion is screwing this stuff up... !!! FIX !!!
+//This is still wrong... Prolly need to do something with the oldScaleX/Y stuff...
 void Textool_flipX(GtkToggleButton *, gpointer)
 {
 //	globalOutputStream() << "--> Flip X...\n";
 	//Shamus:
 //	SurfaceInspector_GetSelectedBPTexdef();		// Refresh g_selectedBrushPrimitTexdef...
 //	Textool_Initialize();						// Set up textool for the change
-	tm.coords[0][0] = -tm.coords[0][0];
+//	tm.coords[0][0] = -tm.coords[0][0];
+//	tm.coords[1][0] = -tm.coords[1][0];
+//	tm.coords[0][0] = -tm.coords[0][0];			// This should be correct now...Nope.
+//	tm.coords[1][1] = -tm.coords[1][1];
+	tm.coords[0][0] = -tm.coords[0][0];			// This should be correct now...
 	tm.coords[1][0] = -tm.coords[1][0];
+//	tm.coords[2][0] = -tm.coords[2][0];//wil wok? no.
 	UpdateControlPoints();
 	gtk_widget_queue_draw(g_textoolWin);		// & update the window
 }
@@ -1774,8 +2049,13 @@
 void Textool_flipY(GtkToggleButton *, gpointer)
 {
 //	globalOutputStream() << "--> Flip Y...\n";
-	tm.coords[0][1] = -tm.coords[0][1];
+//	tm.coords[0][1] = -tm.coords[0][1];
+//	tm.coords[1][1] = -tm.coords[1][1];
+//	tm.coords[0][1] = -tm.coords[0][1];			// This should be correct now...Nope.
+//	tm.coords[1][0] = -tm.coords[1][0];
+	tm.coords[0][1] = -tm.coords[0][1];			// This should be correct now...
 	tm.coords[1][1] = -tm.coords[1][1];
+//	tm.coords[2][1] = -tm.coords[2][1];//wil wok? no.
 	UpdateControlPoints();
 	gtk_widget_queue_draw(g_textoolWin);		// & update the window
 }




More information about the Gtkradiant mailing list