The GtkRadiant sources as originally released under the GPL license.

This commit is contained in:
Travis Bradshaw
2012-01-31 15:20:35 -06:00
commit 0991a5ce8b
1590 changed files with 431941 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
*.d
*.o
*.so
Debug
Release
TexTool___Win32_Q3Debug
TexTool___Win32_Q3Release
*.aps
*.plg
*.bak
*.BAK
*.opt
*.ncb

View File

@@ -0,0 +1,2 @@
*.dsp -m 'COPY' -k 'b'
*.rc -m 'COPY' -k 'b'

202
plugins/textool/2DView.cpp Normal file
View File

@@ -0,0 +1,202 @@
/*
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
For a list of contributors, see the accompanying CONTRIBUTORS file.
This file is part of GtkRadiant.
GtkRadiant is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GtkRadiant is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GtkRadiant; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
//-----------------------------------------------------------------------------
//
// DESCRIPTION:
// a class to provide basic services for 2D view of a world
// window <-> local 2D space transforms
// snap to grid
// TODO: this one can be placed under an interface, and provided to the editor as a service
#include "StdAfx.h"
static void view_ZoomIn (GtkWidget* widget, gpointer data)
{
((C2DView*)data)->ZoomIn ();
}
static void view_ZoomOut (GtkWidget* widget, gpointer data)
{
((C2DView*)data)->ZoomOut ();
}
void C2DView::PreparePaint()
{
g_QglTable.m_pfn_qglClearColor( 0, 0, 0, 0 );
g_QglTable.m_pfn_qglViewport( 0, 0, m_rect.right, m_rect.bottom );
g_QglTable.m_pfn_qglMatrixMode( GL_PROJECTION );
g_QglTable.m_pfn_qglLoadIdentity();
g_QglTable.m_pfn_qglOrtho( m_Mins[0], m_Maxs[0], m_Maxs[1], m_Mins[1], -1, 1 );
}
void C2DView::SpaceForWindow( float c[2], int x, int y)
{
c[0] = ((float)(x))/((float)(m_rect.right-m_rect.left))*(m_Maxs[0]-m_Mins[0])+m_Mins[0];
c[1] = ((float)(y))/((float)(m_rect.bottom-m_rect.top))*(m_Maxs[1]-m_Mins[1])+m_Mins[1];
}
void C2DView::GridForWindow( float c[2], int x, int y)
{
SpaceForWindow( c, x, y );
if ( !m_bDoGrid )
return;
c[0] /= m_GridStep[0];
c[1] /= m_GridStep[1];
c[0] = (float)floor( c[0] + 0.5f );
c[1] = (float)floor( c[1] + 0.5f );
c[0] *= m_GridStep[0];
c[1] *= m_GridStep[1];
}
void C2DView::WindowForSpace( int &x, int &y, const float c[2] )
{
x = m_rect.left + (int)( ((float)(m_rect.right-m_rect.left))*(c[0]-m_Mins[0])/(m_Maxs[0]-m_Mins[0]) );
y = m_rect.top + (int)( ((float)(m_rect.bottom-m_rect.top))*(c[1]-m_Mins[1])/(m_Maxs[1]-m_Mins[1]) );
}
qboolean C2DView::DoesSelect( int x, int y, float c[2] )
{
int xc,yc;
WindowForSpace( xc, yc, c );
if ( abs(xc-x)<=3 && abs(yc-y)<=3 )
return true;
return false;
}
void C2DView::ZoomIn()
{
m_Mins[0] = 0.5f * ( m_Mins[0] - m_Center[0] ) + m_Center[0];
m_Mins[1] = 0.5f * ( m_Mins[1] - m_Center[1] ) + m_Center[1];
m_Maxs[0] = 0.5f * ( m_Maxs[0] - m_Center[0] ) + m_Center[0];
m_Maxs[1] = 0.5f * ( m_Maxs[1] - m_Center[1] ) + m_Center[1];
g_pToolWnd->Redraw ();
}
void C2DView::ZoomOut()
{
m_Mins[0] = 2.0f * ( m_Mins[0] - m_Center[0] ) + m_Center[0];
m_Mins[1] = 2.0f * ( m_Mins[1] - m_Center[1] ) + m_Center[1];
m_Maxs[0] = 2.0f * ( m_Maxs[0] - m_Center[0] ) + m_Center[0];
m_Maxs[1] = 2.0f * ( m_Maxs[1] - m_Center[1] ) + m_Center[1];
g_pToolWnd->Redraw ();
}
bool C2DView::OnRButtonDown (int x, int y)
{
if (ViewState == View_Idle)
{
m_xPosMove = x; // horizontal position of cursor
m_yPosMove = y; // vertical position of cursor
// store
m_MinsMove[0] = m_Mins[0]; m_MinsMove[1] = m_Mins[1];
m_MaxsMove[0] = m_Maxs[0]; m_MaxsMove[1] = m_Maxs[1];
ViewState = View_Move;
// set popup to true
m_bPopup = true;
return true;
}
return false;
}
bool C2DView::OnRButtonUp (int x, int y)
{
if (ViewState == View_Move)
{
// maybe it's time for popup menu
if (m_bPopup)
{
GtkWidget *menu, *item;
menu = gtk_menu_new ();
item = gtk_menu_item_new_with_label ("Validate (RETURN)");
gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (Textool_Validate), NULL);
gtk_widget_show (item);
gtk_menu_append (GTK_MENU (menu), item);
item = gtk_menu_item_new_with_label ("Zoom in (INSERT)");
gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (view_ZoomIn), this);
gtk_widget_show (item);
gtk_menu_append (GTK_MENU (menu), item);
item = gtk_menu_item_new_with_label ("Zoom out (DELETE)");
gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (view_ZoomOut), this);
gtk_widget_show (item);
gtk_menu_append (GTK_MENU (menu), item);
item = gtk_menu_item_new_with_label ("Cancel (ESC)");
gtk_signal_connect (GTK_OBJECT (item), "activate", GTK_SIGNAL_FUNC (Textool_Cancel), NULL);
gtk_widget_show (item);
gtk_menu_append (GTK_MENU (menu), item);
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 1, GDK_CURRENT_TIME);
}
// back to Idle mode
ViewState = View_Idle;
return true;
}
return false;
}
bool C2DView::OnMouseMove (int xPos, int yPos)
{
if (ViewState == View_Move)
{
float V[2];
// V is the offset
V[0] = ((float)( xPos - m_xPosMove )) * ( m_MaxsMove[0] - m_MinsMove[0] ) / ((float)( m_rect.left - m_rect.right ));
V[1] = ((float)( yPos - m_yPosMove )) * ( m_MaxsMove[1] - m_MinsMove[1] ) / ((float)( m_rect.top - m_rect.bottom ));
// update m_Mins m_Maxs and m_Center
m_Mins[0] = m_MinsMove[0] + V[0];
m_Mins[1] = m_MinsMove[1] + V[1];
m_Maxs[0] = m_MaxsMove[0] + V[0];
m_Maxs[1] = m_MaxsMove[1] + V[1];
m_Center[0] = 0.5f * ( m_Mins[0] + m_Maxs[0] );
m_Center[1] = 0.5f * ( m_Mins[1] + m_Maxs[1] );
// no popup menu if we moved
m_bPopup = false;
// send a repaint message
g_pToolWnd->Redraw ();
return true;
}
return false;
}
bool C2DView::OnKeyDown (char *s)
{
if (ViewState == View_Idle)
{
if (!strcmp(s,"Insert"))
{
ZoomOut();
return true;
}
if (!strcmp(s,"Delete"))
{
ZoomIn();
return true;
}
}
return false;
}

70
plugins/textool/2DView.h Normal file
View File

@@ -0,0 +1,70 @@
/*
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
For a list of contributors, see the accompanying CONTRIBUTORS file.
This file is part of GtkRadiant.
GtkRadiant is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GtkRadiant is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GtkRadiant; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
//-----------------------------------------------------------------------------
//
// DESCRIPTION:
// a class to provide basic services for 2D view of a world
// window <-> local 2D space transforms
// snap to grid
// TODO: this one could be placed under an interface, and provided to the editor as a service
#ifndef _2DVIEW_H_
#define _2DVIEW_H_
class C2DView
{
enum E2DViewState { View_Idle, View_Move } ViewState;
int m_xPosMove, m_yPosMove;
float m_MinsMove[2], m_MaxsMove[2];
qboolean m_bDoGrid;
float m_GridStep[2];
qboolean m_bPopup;
public:
RECT m_rect;
float m_Mins[2],m_Maxs[2],m_Center[2];
C2DView()
{
ViewState = View_Idle;
m_bDoGrid = false;
m_bPopup = false;
}
~C2DView() { }
void SetGrid( float xGridStep, float yGridStep )
{ m_bDoGrid = true; m_GridStep[0] = xGridStep; m_GridStep[1] = yGridStep; }
// get window coordinates for space coordinates
void WindowForSpace( int &x, int &y, const float c[2]);
void SpaceForWindow( float c[2], int x, int y);
void GridForWindow( float c[2], int x, int y);
qboolean DoesSelect( int x, int y, float c[2] );
void PreparePaint();
bool OnRButtonDown (int x, int y);
bool OnMouseMove (int x, int y);
bool OnRButtonUp (int x, int y);
bool OnKeyDown (char *s);
void ZoomIn();
void ZoomOut();
};
#endif

View File

@@ -0,0 +1,332 @@
/*
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
For a list of contributors, see the accompanying CONTRIBUTORS file.
This file is part of GtkRadiant.
GtkRadiant is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GtkRadiant is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GtkRadiant; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
//-----------------------------------------------------------------------------
//
// DESCRIPTION:
// a class to handle control points in a 2D view
// TODO: this one can be placed under an interface, and provided to the editor as service
//
#include "StdAfx.h"
void CControlPointsManagerBFace::Init (int iPts, CtrlPts_t *Pts, C2DView *p2DView, int TexSize[2],
_QERFaceData* pFaceData, OpenGLBinding *pQglTable)
{
ManagerState = Idle;
m_NumPoints = iPts;
m_pPts = Pts;
// store the initial config
memcpy( &m_RefPts, Pts, sizeof( CtrlPts_t ) );
// init TM
memset( m_TM, 0, sizeof( float[2][3] ) );
m_TM[0][0] = 1.0f; m_TM[1][1] = 1.0f;
m_bGotAnchor = false;
m_TransOffset[0] = 0.0f; m_TransOffset[1] = 0.0f;
m_TexSize[0] = TexSize[0];
m_TexSize[1] = TexSize[1];
m_pFaceData = pFaceData;
CControlPointsManager::Init( p2DView, pQglTable );
}
bool CControlPointsManagerBFace::OnLButtonDown (int xPos, int yPos)
{
if (ManagerState == Idle)
{
int i;
// scan the point list to see if we selected something
for ( i=0; i<m_NumPoints; i++ )
if ( m_p2DView->DoesSelect( xPos, yPos, m_pPts->data[i] ) )
{
m_iDragPoint = i;
ManagerState = Drag;
if (m_bGotAnchor && i == m_iAnchorPoint)
{
// this means we selected the Anchor, so we'll translate
m_bGotAnchor = false;
}
// perhaps we won't use translation, but we can compute it anyway
ComputeTransOffset(i);
if (m_bGotAnchor)
{
// we have an Anchor and selected another point
m_Anchor[0] = m_pPts->data[m_iAnchorPoint][0];
m_Anchor[1] = m_pPts->data[m_iAnchorPoint][1];
}
}
// send a repaint message
g_pToolWnd->Redraw ();
return true;
}
return false;
}
bool CControlPointsManagerBFace::OnMouseMove (int xPos, int yPos)
{
if (ManagerState == Drag)
{
if (m_bGotAnchor)
{
// there's an anchor, we are rotating the shape
// we need to work in XY space for orthonormality
float Pt[2];
vec3_t V1,V2;
vec3_t cross;
float c,s;
// used in XY space
float XYTM[2][3];
float XYRefAnchor[2];
float XYAnchor[2];
m_p2DView->GridForWindow( Pt, xPos, yPos );
V2[0] = Pt[0] - m_Anchor[0];
V2[1] = Pt[1] - m_Anchor[1];
V2[2] = 0.0f;
V1[0] = m_RefPts.data[m_iDragPoint][0] - m_RefPts.data[m_iAnchorPoint][0];
V1[1] = m_RefPts.data[m_iDragPoint][1] - m_RefPts.data[m_iAnchorPoint][1];
V1[2] = 0.0f;
// compute transformation from V1 to V2
// we need to work in XY orthonormal space
XYSpaceForSTSpace( V1, V1 );
XYSpaceForSTSpace( V2, V2 );
VectorNormalize( V2, V2 );
VectorNormalize( V1, V1 );
c = DotProduct( V1, V2 );
CrossProduct( V1, V2, cross );
s = VectorLength( cross );
// we compute the transformation matrix in XY space
// reference position of the Anchor in XY space
XYSpaceForSTSpace( XYRefAnchor, m_RefPts.data[m_iAnchorPoint] );
// current position of the Anchor in XY space
XYSpaceForSTSpace( XYAnchor, m_Anchor );
// compute transformation matrix
XYTM[0][0] = c; XYTM[1][1] = c;
if (cross[2]>0)
s *= -1.0f;
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];
// express this transformation matrix in ST space
m_TM[0][0] = XYTM[0][0];
m_TM[1][0] = XYTM[1][0] * (float)m_TexSize[0] / (float)m_TexSize[1];
m_TM[0][1] = XYTM[0][1] * (float)m_TexSize[1] / (float)m_TexSize[0];
m_TM[1][1] = XYTM[1][1];
m_TM[0][2] = XYTM[0][2] / (float)m_TexSize[0];
m_TM[1][2] = XYTM[1][2] / (float)m_TexSize[1];
// update all points
UpdateCtrlPts();
}
else
{
// no Anchor point is defined, we translate all points
m_p2DView->GridForWindow( m_pPts->data[m_iDragPoint], xPos, yPos );
m_TM[0][2] = m_pPts->data[m_iDragPoint][0] + m_TransOffset[0];
m_TM[1][2] = m_pPts->data[m_iDragPoint][1] + m_TransOffset[1];
// update all points
UpdateCtrlPts();
}
// send a repaint message
g_pToolWnd->Redraw ();
return true;
}
return false;
}
bool CControlPointsManagerBFace::OnLButtonUp (int x, int y)
{
if (ManagerState == Drag)
{
// this button is gonna become our Anchor
m_bGotAnchor = true;
m_iAnchorPoint = m_iDragPoint;
// let's get out of Drag mode
ManagerState = Idle;
// send a repaint message
g_pToolWnd->Redraw ();
return true;
}
return false;
}
void CControlPointsManagerBFace::render()
{
int i;
m_pQglTable->m_pfn_qglColor3f(0, 1, 0);
m_pQglTable->m_pfn_qglPointSize(6);
m_pQglTable->m_pfn_qglBegin( GL_POINTS );
for ( i=0; i<m_NumPoints; i++ )
{
if ( ManagerState == Drag && i == m_iDragPoint )
m_pQglTable->m_pfn_qglColor3f(1, 0, 0);
else if ( m_bGotAnchor && i == m_iAnchorPoint )
m_pQglTable->m_pfn_qglColor3f(0, 0, 1);
m_pQglTable->m_pfn_qglVertex2f( m_pPts->data[i][0], m_pPts->data[i][1] );
m_pQglTable->m_pfn_qglColor3f(0, 1, 0);
}
m_pQglTable->m_pfn_qglEnd();
}
void CControlPointsManagerBFace::UpdateCtrlPts()
{
int i;
// update all points
for ( i=0; i<m_NumPoints; i++ )
{
m_pPts->data[i][0] = m_RefPts.data[i][0]*m_TM[0][0]+m_RefPts.data[i][1]*m_TM[0][1]+m_TM[0][2];
m_pPts->data[i][1] = m_RefPts.data[i][0]*m_TM[1][0]+m_RefPts.data[i][1]*m_TM[1][1]+m_TM[1][2];
}
if (g_bPrefsUpdateCameraView)
{
Commit();
// tell Radiant to update
// NOTE: little speed optimisation, disable window updates, and only update camera view
g_FuncTable.m_pfnSetScreenUpdate( false );
g_SelectedFaceTable.m_pfnSetFaceInfo( 0, m_pFaceData );
g_FuncTable.m_pfnSetScreenUpdate( true );
g_FuncTable.m_pfnSysUpdateWindows( W_CAMERA );
}
}
//++timo FIXME: we are using a global for the reference data, use a m_pCancelFaceData instead
void CControlPointsManagerBFace::Commit( )
{
brushprimit_texdef_t aux;
aux.coords[0][0] = m_TM[0][0]*g_CancelFaceData.brushprimit_texdef.coords[0][0] + m_TM[0][1]*g_CancelFaceData.brushprimit_texdef.coords[1][0];
aux.coords[0][1] = m_TM[0][0]*g_CancelFaceData.brushprimit_texdef.coords[0][1] + m_TM[0][1]*g_CancelFaceData.brushprimit_texdef.coords[1][1];
aux.coords[0][2] = m_TM[0][0]*g_CancelFaceData.brushprimit_texdef.coords[0][2] + m_TM[0][1]*g_CancelFaceData.brushprimit_texdef.coords[1][2] + m_TM[0][2];
aux.coords[1][0] = m_TM[1][0]*g_CancelFaceData.brushprimit_texdef.coords[0][0] + m_TM[1][1]*g_CancelFaceData.brushprimit_texdef.coords[1][0];
aux.coords[1][1] = m_TM[1][0]*g_CancelFaceData.brushprimit_texdef.coords[0][1] + m_TM[1][1]*g_CancelFaceData.brushprimit_texdef.coords[1][1];
aux.coords[1][2] = m_TM[1][0]*g_CancelFaceData.brushprimit_texdef.coords[0][2] + m_TM[1][1]*g_CancelFaceData.brushprimit_texdef.coords[1][2] + m_TM[1][2];
memcpy( &m_pFaceData->brushprimit_texdef, &aux, sizeof(brushprimit_texdef_t) );
}
void CControlPointsManagerBFace::ComputeTransOffset(int i)
{
// compute the translation offset used to counteract rotation
m_TransOffset[0] = -m_TM[0][0]*m_RefPts.data[i][0] - m_TM[0][1]*m_RefPts.data[i][1];
m_TransOffset[1] = -m_TM[1][0]*m_RefPts.data[i][0] - m_TM[1][1]*m_RefPts.data[i][1];
}
void CControlPointsManagerBFace::XYSpaceForSTSpace( float xy[2], const float st[2] )
{
xy[0] = st[0] * (float)m_TexSize[0];
xy[1] = st[1] * (float)m_TexSize[1];
}
/*
======================================================================
patch manager
======================================================================
*/
void CControlPointsManagerPatch::Init( patchMesh_t* pWorkPatch, C2DView *p2DView, OpenGLBinding *pQglTable, patchMesh_t* pPatch )
{
CControlPointsManager::Init( p2DView, pQglTable );
m_pPatch = pPatch;
m_pWorkPatch = pWorkPatch;
}
bool CControlPointsManagerPatch::OnLButtonDown (int xPos, int yPos)
{
if (ManagerState == Idle)
{
int i,j;
// scan the point list to see if we selected something
for ( i=0; i<m_pPatch->width; i++ )
for ( j=0; j<m_pPatch->height; j++ )
if ( m_p2DView->DoesSelect( xPos, yPos, m_pWorkPatch->ctrl[i][j].st ) )
{
m_iDragPoint[0] = i;
m_iDragPoint[1] = j;
ManagerState = Drag;
}
// send a repaint message
g_pToolWnd->Redraw ();
return true;
}
return false;
}
bool CControlPointsManagerPatch::OnMouseMove (int xPos, int yPos)
{
if (ManagerState == Drag)
{
m_p2DView->GridForWindow( m_pWorkPatch->ctrl[ m_iDragPoint[0] ][ m_iDragPoint[1] ].st, xPos, yPos );
if (g_bPrefsUpdateCameraView)
{
Commit();
// ask to rebuild the patch display data
m_pPatch->bDirty = true;
// send a repaint to the camera window as well
g_FuncTable.m_pfnSysUpdateWindows( W_CAMERA );
}
// send a repaint message
g_pToolWnd->Redraw ();
return true;
}
return false;
}
bool CControlPointsManagerPatch::OnLButtonUp (int x, int y)
{
if (ManagerState == Drag)
{
ManagerState = Idle;
// send a repaint message
g_pToolWnd->Redraw ();
}
return false;
}
void CControlPointsManagerPatch::render()
{
int i,j;
m_pQglTable->m_pfn_qglColor3f(0, 1, 0);
m_pQglTable->m_pfn_qglPointSize(6);
m_pQglTable->m_pfn_qglBegin( GL_POINTS );
for ( i=0; i<m_pPatch->width; i++ )
for ( j=0; j<m_pPatch->height; j++ )
{
if ( ManagerState == Drag && i == m_iDragPoint[0] && j == m_iDragPoint[1] )
m_pQglTable->m_pfn_qglColor3f(1, 0, 0);
m_pQglTable->m_pfn_qglVertex2f( m_pWorkPatch->ctrl[i][j].st[0], m_pWorkPatch->ctrl[i][j].st[1] );
m_pQglTable->m_pfn_qglColor3f(0, 1, 0);
}
m_pQglTable->m_pfn_qglEnd();
}
void CControlPointsManagerPatch::Commit()
{
int i,j;
for ( i=0; i<m_pPatch->width; i++ )
for ( j=0; j<m_pPatch->height; j++ )
{
m_pPatch->ctrl[i][j].st[0] = m_pWorkPatch->ctrl[i][j].st[0];
m_pPatch->ctrl[i][j].st[1] = m_pWorkPatch->ctrl[i][j].st[1];
}
}

View File

@@ -0,0 +1,133 @@
/*
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
For a list of contributors, see the accompanying CONTRIBUTORS file.
This file is part of GtkRadiant.
GtkRadiant is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GtkRadiant is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GtkRadiant; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
//-----------------------------------------------------------------------------
//
// DESCRIPTION:
// a class to handle control points in a 2D view
// TODO: this one can be placed under an interface, and provided to the editor as service
//
// NOTE: the C2DView *m_p2DView is the orthogonal mapping between window and ST space
// in Drag mode (for rotation) we need an orthonormal XY space
// we do ST <-> XY transformations using the texture size
// ( for translation-only moves, orthogonal is enough )
// FIXME: is there a better way to deal between Window space <-> ST space <-> XY space ?
//
// NOTE: ControlPointsManagers are a bit different between brush faces and patches
// so there's a base virtual class, and we have two versions
#ifndef _CONTROLPOINTSMANAGER_H_
#define _CONTROLPOINTSMANAGER_H_
class CControlPointsManager
{
protected:
// used by Render
OpenGLBinding *m_pQglTable;
C2DView *m_p2DView;
public:
CControlPointsManager() { m_pQglTable = NULL; m_p2DView = NULL; }
virtual ~CControlPointsManager() { }
void Init( C2DView *p2DView, OpenGLBinding *pQglTable ) { m_pQglTable = pQglTable; m_p2DView = p2DView; }
virtual bool OnLButtonDown (int x, int y) = 0;
virtual bool OnMouseMove (int x, int y) = 0;
virtual bool OnLButtonUp (int x, int y) = 0;
virtual void render() = 0;
virtual void Commit() = 0;
};
// brush face manager
class CControlPointsManagerBFace : public CControlPointsManager
{
enum EManagerState { Idle, Drag } ManagerState;
int m_NumPoints;
// initial geometry
CtrlPts_t m_RefPts;
// current geometry
CtrlPts_t *m_pPts;
// transform matrix ( 2DView is Window <-> ST )
float m_TM[2][3];
// texture size for ST <-> XY
int m_TexSize[2];
// used when translating
float m_TransOffset[2];
// dragged point index
int m_iDragPoint;
// do we have an anchor ?
bool m_bGotAnchor;
// anchor point index
int m_iAnchorPoint;
// coordinates of Anchor
float m_Anchor[2];
// used for commit
_QERFaceData *m_pFaceData;
public:
// construction / init -------------------------------------------------
CControlPointsManagerBFace() { ManagerState = Idle; }
virtual ~CControlPointsManagerBFace() { }
// NOTE: pQglTable is sent to CControlPointsManager::Init
void Init(int iPts, CtrlPts_t *Pts, C2DView *p2DView, int TexSize[2], _QERFaceData* pFaceData, OpenGLBinding *pQglTable);
// CControlPointsManager interface -------------------------------------
virtual bool OnLButtonDown (int x, int y);
virtual bool OnMouseMove (int x, int y);
virtual bool OnLButtonUp (int x, int y);
virtual void render();
virtual void Commit();
private:
// internal members
void UpdateCtrlPts();
void ComputeTransOffset(int i);
void XYSpaceForSTSpace( float xy[2], const float st[2] );
};
// patch manager
class CControlPointsManagerPatch : public CControlPointsManager
{
enum EManagerState { Idle, Drag } ManagerState;
// reference data, used for commits
patchMesh_t* m_pPatch;
// work patch, holds current data
patchMesh_t* m_pWorkPatch;
int m_iDragPoint[2];
public:
// construction / init -------------------------------------------------
CControlPointsManagerPatch() { ManagerState = Idle; }
virtual ~CControlPointsManagerPatch() { }
// NOTE: pQglTable is sent to CControlPointsManager::Init
void Init( patchMesh_t* pWorkPatch, C2DView *p2DView, OpenGLBinding *pQglTable, patchMesh_t* pPatch );
// CControlPointsManager interface -------------------------------------
virtual bool OnLButtonDown (int x, int y);
virtual bool OnMouseMove (int x, int y);
virtual bool OnLButtonUp (int x, int y);
virtual void render();
virtual void Commit();
};
#endif

View File

@@ -0,0 +1 @@
*.jpg -m 'COPY' -k 'b'

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -0,0 +1,123 @@
<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Author" content="TTimo"><title>TexTool plugin for Q3Radiant - documentation</title></head><body text="#ffffff" bgcolor="#141432" link="#ffff00" vlink="#aaaa00" alink="#eeee00">
<center><b>
<font face="Tahoma" color="#ffff80" size="+3">TexTool plugin for Q3Radiant</font></b></center>
<hr><font face="Tahoma" color="#2cdd22" size="+2">Introduction</font>
<p>TexTool is a set of texture tools for Q3Radiant. It was designed to help fine-tuning texture placement
on brushes and patches.</p>
<font face="Tahoma" color="#2cdd22" size="+1"><i>Warning:</i></font>
<p>The plugin needs brush primitives texture coordinates to operate. If this feature is not enabled in your project
settings you'll only be able to edit patches.</p>
<hr><font face="Tahoma" color="#2cdd22" size="+2">Basic use</font>
<p>It's a "drag-n-drop control points" interface. Select a single face on a brush ( with <font color="#cc0000">shift+ctrl+left mouse clic</font>),
or a patch, and do <i>Plugins &gt; Q3 Texture Tools &gt; Go...</i>. You can select points and move them... if you are editing
a brush face, you can rotate the shape by clicking on an anchor point first, then dragging another point.</p>
<center>
<img src="Image2.jpg" width="576" height="396" border="0" alt="TexTool screenshot">
</center>
<p>There are also a few misc keys to help you. You can <i>
<font color="#cc0000">right clic + move the mouse</font></i> to change the point of view
and use <i>
<font color="#cc0000">Inser</font></i><font color="#cc0000"> and </font><i>
<font color="#cc0000">Suppr</font></i><font color="#cc0000"> to zoom in/out</font>.
</center>
<font color="#33cc00">
<br>
</font><hr>
<font face="Tahoma" color="#2cdd22" size="+2">Appendix: keyboard shortcuts</font>
<p>You can use the following keyboard shortcuts:</p>
<p></p>
<table cellpadding="2" cellspacing="2" border="1">
<tbody>
<tr valign="Top">
<td valign="Top">
<font color="#cc0000">KEY</font><br>
</td>
<td valign="Top">
<font color="#cc0000">usage</font><br>
</td>
</tr>
<tr valign="Top">
<td valign="Top">ESC<br>
</td>
<td valign="Top">cancel the changes and hide TexTool window<br>
</td>
</tr>
<tr valign="Top">
<td valign="Top">RETURN<br>
</td>
<td valign="Top">validate changes into the editor (also resets the view)<br>
</td>
</tr>
<tr valign="Top">
<td valign="Top">INSERT<br>
</td>
<td valign="Top">zoom in<br>
</td>
</tr>
<tr valign="Top">
<td valign="Top">SUPPR<br>
</td>
<td valign="Top">zoom out<br>
</td>
</tr>
<tr valign="Top">
<td valign="Top">RIGHT CLIC+MOVE<br>
</td>
<td valign="Top">move the view<br>
</td>
</tr>
<tr valign="Top">
<td valign="Top">LEFT CLIC+MOVE<br>
</td>
<td valign="Top">grab a control point and move it<br>
</td>
</tr>
<tr valign="Top">
<td valign="Top">RIGHT CLIC<br>
</td>
<td valign="Top">drop down menu<br>
</td>
</tr>
</tbody>
</table><hr>
<p> Feedback, enhancements bugs etc. to <a href="mailto:timo@qeradiant.com">timo@qeradiant.com</a></p>
<p></p>
</body>
</html>

View File

@@ -0,0 +1,28 @@
/*
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
For a list of contributors, see the accompanying CONTRIBUTORS file.
This file is part of GtkRadiant.
GtkRadiant is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GtkRadiant is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GtkRadiant; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// stdafx.cpp : source file that includes just the standard includes
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

154
plugins/textool/StdAfx.h Normal file
View File

@@ -0,0 +1,154 @@
/*
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
For a list of contributors, see the accompanying CONTRIBUTORS file.
This file is part of GtkRadiant.
GtkRadiant is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GtkRadiant is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GtkRadiant; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// stdafx.h
// precompiled headers
// standard headers
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#if defined(__linux__) || defined(__APPLE__)
// Necessary for proper boolean type declaration
#include "qertypes.h"
typedef void* HMODULE;
typedef void* LPVOID;
typedef char* LPCSTR;
#define MB_OK 0x00000000L
#define MB_OKCANCEL 0x00000001L
#define MB_ABORTRETRYIGNORE 0x00000002L
#define MB_YESNOCANCEL 0x00000003L
#define MB_YESNO 0x00000004L
#define MB_RETRYCANCEL 0x00000005L
#define MB_ICONHAND 0x00000010L
#define MB_ICONQUESTION 0x00000020L
#define MB_ICONEXCLAMATION 0x00000030L
#define MB_ICONASTERISK 0x00000040L
#define MB_USERICON 0x00000080L
#define MB_ICONWARNING MB_ICONEXCLAMATION
#define MB_ICONERROR MB_ICONHAND
#define MB_ICONINFORMATION MB_ICONASTERISK
#define MB_ICONSTOP MB_ICONHAND
#define MB_TYPEMASK 0x0000000FL
#define MB_ICONMASK 0x000000F0L
#define MB_DEFMASK 0x00000F00L
#define MB_MODEMASK 0x00003000L
#define MB_MISCMASK 0x0000C000L
#define IDOK 1
#define IDCANCEL 2
#define IDABORT 3
#define IDRETRY 4
#define IDIGNORE 5
#define IDYES 6
#define IDNO 7
typedef struct tagRECT
{
long left;
long top;
long right;
long bottom;
} RECT, *PRECT, *LPRECT;
#endif // __linux__
// plugin
// FIXME TTimo: drop this
extern "C" void Sys_Printf (char *text, ...);
#include "synapse.h"
#include "iplugin.h"
#include "qerplugin.h"
#include "mathlib.h"
#include "igl.h"
#include "iselectedface.h"
#include "isurfaceplugin.h"
#include "iui.h"
// internals
// the implementation of a IWindowListener interface to use with the native UI
// TODO: move in it's own set of files?
// NOTE: I'm not too sure about the bool flags being any use.. they are supposed to tell if we handle the event or not
class CWindowListener : public IWindowListener
{
int refCount;
public:
// Increment the number of references to this object
void IncRef () { refCount++; }
// Decrement the reference count
void DecRef () { if ( --refCount <= 0 ) delete this; }
// IWindowListener ---------------------------------------
bool OnLButtonDown(guint32 nFlags, double x, double y);
bool OnMButtonDown(guint32 nFlags, double x, double y) { return false; }
bool OnRButtonDown(guint32 nFlags, double x, double y);
bool OnLButtonUp(guint32 nFlags, double x, double y);
bool OnMButtonUp(guint32 nFlags, double x, double y) { return false; }
bool OnRButtonUp(guint32 nFlags, double x, double y);
bool OnMouseMove(guint32 nFlags, double x, double y);
bool OnKeyPressed(char *s);
bool Paint();
void Close();
};
#include "2DView.h"
typedef struct
{
float data[MAX_POINTS_ON_WINDING][2];
} CtrlPts_t;
#include "ControlPointsManager.h"
extern OpenGLBinding g_QglTable;
extern _QERFuncTable_1 g_FuncTable;
// prefs globals
// NOTE: these are used by the CControlPointsManager classes, not very C++ish
extern bool g_bPrefsUpdateCameraView;
extern _QERSelectedFaceTable g_SelectedFaceTable;
extern _QERFaceData g_CancelFaceData;
#define Sys_Printf g_FuncTable.m_pfnSysPrintf
#define Sys_FPrintf g_FuncTable.m_pfnSysFPrintf
// call to validate the current changes into the editor
extern void Textool_Validate();
extern void Textool_Cancel();
class CSynapseClientTexTool : public CSynapseClient
{
public:
// CSynapseClient API
bool RequestAPI(APIDescriptor_t *pAPI);
const char* GetInfo();
CSynapseClientTexTool() { }
virtual ~CSynapseClientTexTool() { }
};
extern IWindow *g_pToolWnd;

962
plugins/textool/TexTool.cpp Normal file
View File

@@ -0,0 +1,962 @@
/*
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
For a list of contributors, see the accompanying CONTRIBUTORS file.
This file is part of GtkRadiant.
GtkRadiant is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
GtkRadiant is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GtkRadiant; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
//-----------------------------------------------------------------------------
//
// DESCRIPTION:
// main plugin implementation
// texturing tools for Radiant
//
#include "StdAfx.h"
static void dialog_button_callback (GtkWidget *widget, gpointer data)
{
GtkWidget *parent;
int *loop, *ret;
parent = gtk_widget_get_toplevel (widget);
loop = (int*)g_object_get_data (G_OBJECT (parent), "loop");
ret = (int*)g_object_get_data (G_OBJECT (parent), "ret");
*loop = 0;
*ret = (int)data;
}
static gint dialog_delete_callback (GtkWidget *widget, GdkEvent* event, gpointer data)
{
int *loop;
gtk_widget_hide (widget);
loop = (int*)g_object_get_data (G_OBJECT (widget), "loop");
*loop = 0;
return TRUE;
}
int DoMessageBox (const char* lpText, const char* lpCaption, guint32 uType)
{
GtkWidget *window, *w, *vbox, *hbox;
int mode = (uType & MB_TYPEMASK), ret, loop = 1;
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (window), "delete_event",
GTK_SIGNAL_FUNC (dialog_delete_callback), NULL);
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (gtk_widget_destroy), NULL);
gtk_window_set_title (GTK_WINDOW (window), lpCaption);
gtk_container_border_width (GTK_CONTAINER (window), 10);
g_object_set_data (G_OBJECT (window), "loop", &loop);
g_object_set_data (G_OBJECT (window), "ret", &ret);
gtk_widget_realize (window);
vbox = gtk_vbox_new (FALSE, 10);
gtk_container_add (GTK_CONTAINER (window), vbox);
gtk_widget_show (vbox);
w = gtk_label_new (lpText);
gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 2);
gtk_label_set_justify (GTK_LABEL (w), GTK_JUSTIFY_LEFT);
gtk_widget_show (w);
w = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 2);
gtk_widget_show (w);
hbox = gtk_hbox_new (FALSE, 10);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 2);
gtk_widget_show (hbox);
if (mode == MB_OK)
{
w = gtk_button_new_with_label ("Ok");
gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT (w), "clicked",
GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
GTK_WIDGET_SET_FLAGS (w, GTK_CAN_DEFAULT);
gtk_widget_grab_default (w);
gtk_widget_show (w);
ret = IDOK;
}
else if (mode == MB_OKCANCEL)
{
w = gtk_button_new_with_label ("Ok");
gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT (w), "clicked",
GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDOK));
GTK_WIDGET_SET_FLAGS (w, GTK_CAN_DEFAULT);
gtk_widget_grab_default (w);
gtk_widget_show (w);
w = gtk_button_new_with_label ("Cancel");
gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT (w), "clicked",
GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
gtk_widget_show (w);
ret = IDCANCEL;
}
else if (mode == MB_YESNOCANCEL)
{
w = gtk_button_new_with_label ("Yes");
gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT (w), "clicked",
GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDYES));
GTK_WIDGET_SET_FLAGS (w, GTK_CAN_DEFAULT);
gtk_widget_grab_default (w);
gtk_widget_show (w);
w = gtk_button_new_with_label ("No");
gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT (w), "clicked",
GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDNO));
gtk_widget_show (w);
w = gtk_button_new_with_label ("Cancel");
gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT (w), "clicked",
GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDCANCEL));
gtk_widget_show (w);
ret = IDCANCEL;
}
else /* if (mode == MB_YESNO) */
{
w = gtk_button_new_with_label ("Yes");
gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT (w), "clicked",
GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDYES));
GTK_WIDGET_SET_FLAGS (w, GTK_CAN_DEFAULT);
gtk_widget_grab_default (w);
gtk_widget_show (w);
w = gtk_button_new_with_label ("No");
gtk_box_pack_start (GTK_BOX (hbox), w, TRUE, TRUE, 0);
gtk_signal_connect (GTK_OBJECT (w), "clicked",
GTK_SIGNAL_FUNC (dialog_button_callback), GINT_TO_POINTER (IDNO));
gtk_widget_show (w);
ret = IDNO;
}
gtk_widget_show (window);
gtk_grab_add (window);
while (loop)
gtk_main_iteration ();
gtk_grab_remove (window);
gtk_widget_destroy (window);
return ret;
}
// Radiant function table
_QERFuncTable_1 g_FuncTable;
// plugin name
const char *PLUGIN_NAME = "Q3 Texture Tools";
// commands in the menu
const char *PLUGIN_COMMANDS = "About...;Go...";
// cast to GtkWidget*
void *g_pMainWnd;
IWindow *g_pToolWnd = NULL; // handle to the window
CWindowListener g_Listen;
// plugin interfaces ---------------------------
bool g_bQglInitDone = false;
OpenGLBinding g_QglTable;
bool g_bSelectedFaceInitDone = false;
_QERSelectedFaceTable g_SelectedFaceTable;
bool g_bUITable = false;
_QERUITable g_UITable;
// selected face -------------------------------
// we use this one to commit / read with Radiant
_QERFaceData g_SelectedFaceData;
// g_pSelectedFaceWindings gets allocated with MAX_POINTS_ON_WINDING at plugin startup ( QERPlug_Init )
winding_t *g_pSelectedFaceWinding = NULL;
const float g_ViewportRatio = 1.2f;
// usefull class to manage the 2D view
C2DView g_2DView;
// control points to move the polygon
CControlPointsManagerBFace g_ControlPointsBFace;
// tells if a face is selected and we have something to render in the TexWindow
bool g_bTexViewReady = false;
// data for texture work
int g_NumPoints;
CtrlPts_t g_WorkWinding;
// reference _QERFaceData we use on Cancel, and for Commit
_QERFaceData g_CancelFaceData;
// patches -------------------------------------
bool g_bPatch = false;
//++timo we use this one to grab selected patchMesh_t
// FIXME: update when there's a real interface to read/write patches
bool g_bSurfaceTableInitDone = false;
_QERAppSurfaceTable g_SurfaceTable;
CControlPointsManagerPatch g_ControlPointsPatch;
// data for texture work
patchMesh_t* g_pPatch;
// we only use ctrl[][].st in this one
patchMesh_t g_WorkPatch;
// copy of initial g_pPatch for Cancel situation
patchMesh_t g_CancelPatch;
// ---------------------------------------------
// holds the manager we are currently using
CControlPointsManager *g_pManager = NULL;
// ---------------------------------------------
// globals flags for user preferences
//++timo TODO: this should be retrieved from the Editor's .INI prefs in a dedicated interface
// update camera view during manipulation ?
bool g_bPrefsUpdateCameraView = true;
// misc ----------------------------------------
bool g_bHelp = false;
//++timo FIXME: used to close the plugin window if InitTexView fails
// it's dirty, only use is to prevent infinite loop in DialogProc
bool g_bClosing = false;
const char *PLUGIN_ABOUT = "Texture Tools for Radiant\n\n"
"Gtk port by Leonardo Zide (leo@lokigames.com)\n"
"Original version by Timothee \"TTimo\" Besset (timo@qeradiant.com)";
extern "C" void* WINAPI QERPlug_GetFuncTable ()
{
return &g_FuncTable;
}
const char* QERPlug_Init (void* hApp, void *pWidget)
{
int size;
GtkWidget* pMainWidget = static_cast<GtkWidget*>(pWidget);
g_pMainWnd = pMainWidget;
memset(&g_FuncTable, 0, sizeof(_QERFuncTable_1));
g_FuncTable.m_nSize = sizeof(_QERFuncTable_1);
size = (int)((winding_t *)0)->points[MAX_POINTS_ON_WINDING];
g_pSelectedFaceWinding = (winding_t *)malloc( size );
memset( g_pSelectedFaceWinding, 0, size );
return "Texture tools for Radiant";
}
const char* QERPlug_GetName()
{
return (char*)PLUGIN_NAME;
}
const char* QERPlug_GetCommandList()
{
return PLUGIN_COMMANDS;
}
char *TranslateString (char *buf)
{
static char buf2[32768];
int i, l;
char *out;
l = strlen(buf);
out = buf2;
for (i=0 ; i<l ; i++)
{
if (buf[i] == '\n')
{
*out++ = '\r';
*out++ = '\n';
}
else
*out++ = buf[i];
}
*out++ = 0;
return buf2;
}
// called by InitTexView to fit the view against the bounding box of control points
void FitView (IWindow* hwndDlg, int TexSize[2])
{
// apply a ratio to get the area we'll draw
g_2DView.m_Center[0] = 0.5f * ( g_2DView.m_Mins[0] + g_2DView.m_Maxs[0] );
g_2DView.m_Center[1] = 0.5f * ( g_2DView.m_Mins[1] + g_2DView.m_Maxs[1] );
g_2DView.m_Mins[0] = g_2DView.m_Center[0] + g_ViewportRatio*( g_2DView.m_Mins[0] - g_2DView.m_Center[0] );
g_2DView.m_Mins[1] = g_2DView.m_Center[1] + g_ViewportRatio*( g_2DView.m_Mins[1] - g_2DView.m_Center[1] );
g_2DView.m_Maxs[0] = g_2DView.m_Center[0] + g_ViewportRatio*( g_2DView.m_Maxs[0] - g_2DView.m_Center[0] );
g_2DView.m_Maxs[1] = g_2DView.m_Center[1] + g_ViewportRatio*( g_2DView.m_Maxs[1] - g_2DView.m_Center[1] );
g_2DView.m_rect.left = 0;
g_2DView.m_rect.top = 0;
g_2DView.m_rect.bottom = hwndDlg->getHeight();
g_2DView.m_rect.right = hwndDlg->getWidth();
// we need to draw this area, now compute a bigger area so the texture scale is the same along X and Y
// compute box shape in XY space, let's say X <-> S we'll get a ratio for Y:
if (!g_bPatch)
{
g_SelectedFaceTable.m_pfnGetTextureSize( 0, TexSize );
}
else
{
TexSize[0] = g_pPatch->d_texture->width;
TexSize[1] = g_pPatch->d_texture->height;
}
// we want a texture with the same X / Y ratio
// compute XY space / window size ratio
float SSize = (float)fabs( g_2DView.m_Maxs[0] - g_2DView.m_Mins[0] );
float TSize = (float)fabs( g_2DView.m_Maxs[1] - g_2DView.m_Mins[1] );
float XSize = TexSize[0] * SSize;
float YSize = TexSize[1] * TSize;
float RatioX = XSize / (float)abs( g_2DView.m_rect.left - g_2DView.m_rect.right );
float RatioY = YSize / (float)abs( g_2DView.m_rect.top - g_2DView.m_rect.bottom );
if ( RatioX > RatioY )
{
YSize = (float)abs( g_2DView.m_rect.top - g_2DView.m_rect.bottom ) * RatioX;
TSize = YSize / (float)TexSize[1];
}
else
{
XSize = (float)abs( g_2DView.m_rect.left - g_2DView.m_rect.right ) * RatioY;
SSize = XSize / (float)TexSize[0];
}
g_2DView.m_Mins[0] = g_2DView.m_Center[0] - 0.5f * SSize;
g_2DView.m_Maxs[0] = g_2DView.m_Center[0] + 0.5f * SSize;
g_2DView.m_Mins[1] = g_2DView.m_Center[1] - 0.5f * TSize;
g_2DView.m_Maxs[1] = g_2DView.m_Center[1] + 0.5f * TSize;
}
// call this one each time we need to re-init
//++timo TODO: re-init objects state, g_2DView and g_ControlPointsManager
void InitTexView( IWindow* hwndDlg )
{
// size of the texture we are working on
int TexSize[2];
g_bTexViewReady = false;
if (g_SelectedFaceTable.m_pfnGetSelectedFaceCount() != 0)
{
g_SelectedFaceTable.m_pfnGetFaceInfo( 0, &g_SelectedFaceData, g_pSelectedFaceWinding );
g_bPatch = false;
int i;
// we have something selected
// setup: compute BBox for the winding ( in ST space )
//++timo FIXME: move this in a C2DView member ? used as well for patches
g_2DView.m_Mins[0] = +9999.0f; g_2DView.m_Mins[1] = +9999.0f;
g_2DView.m_Maxs[0] = -9999.0f; g_2DView.m_Maxs[1] = -9999.0f;
for ( i=0; i<g_pSelectedFaceWinding->numpoints; i++ )
{
if ( g_pSelectedFaceWinding->points[i][3] < g_2DView.m_Mins[0] )
g_2DView.m_Mins[0] = g_pSelectedFaceWinding->points[i][3];
if ( g_pSelectedFaceWinding->points[i][3] > g_2DView.m_Maxs[0] )
g_2DView.m_Maxs[0] = g_pSelectedFaceWinding->points[i][3];
if ( g_pSelectedFaceWinding->points[i][4] < g_2DView.m_Mins[1] )
g_2DView.m_Mins[1] = g_pSelectedFaceWinding->points[i][4];
if ( g_pSelectedFaceWinding->points[i][4] > g_2DView.m_Maxs[1] )
g_2DView.m_Maxs[1] = g_pSelectedFaceWinding->points[i][4];
}
// NOTE: FitView will read and init TexSize
FitView( hwndDlg, TexSize );
// now init the work tables
g_NumPoints = g_pSelectedFaceWinding->numpoints;
for ( i=0; i<g_NumPoints; i++ )
{
g_WorkWinding.data[i][0] = g_pSelectedFaceWinding->points[i][3];
g_WorkWinding.data[i][1] = g_pSelectedFaceWinding->points[i][4];
}
g_ControlPointsBFace.Init( g_NumPoints, &g_WorkWinding, &g_2DView, TexSize, &g_SelectedFaceData, &g_QglTable );
// init snap-to-grid
float fTexStep[2];
fTexStep[0] = 1.0f / float(TexSize[0]);
fTexStep[1] = 1.0f / float(TexSize[1]);
g_2DView.SetGrid( fTexStep[0], fTexStep[1] );
g_pManager = &g_ControlPointsBFace;
// prepare the "Cancel" data
memcpy( &g_CancelFaceData, &g_SelectedFaceData, sizeof(_QERFaceData) );
// we are done
g_bTexViewReady = true;
}
else if ( g_SurfaceTable.m_pfnAnyPatchesSelected())
{
g_pPatch = g_SurfaceTable.m_pfnGetSelectedPatch();
g_bPatch = true;
int i,j;
// compute BBox for all patch points
g_2DView.m_Mins[0] = +9999.0f; g_2DView.m_Mins[1] = +9999.0f;
g_2DView.m_Maxs[0] = -9999.0f; g_2DView.m_Maxs[1] = -9999.0f;
for ( i=0; i<g_pPatch->width; i++ )
{
for ( j=0; j<g_pPatch->height; j++ )
{
if ( g_pPatch->ctrl[i][j].st[0] < g_2DView.m_Mins[0] )
g_2DView.m_Mins[0] = g_pPatch->ctrl[i][j].st[0];
if ( g_pPatch->ctrl[i][j].st[0] > g_2DView.m_Maxs[0] )
g_2DView.m_Maxs[0] = g_pPatch->ctrl[i][j].st[0];
if ( g_pPatch->ctrl[i][j].st[1] < g_2DView.m_Mins[1] )
g_2DView.m_Mins[1] = g_pPatch->ctrl[i][j].st[1];
if ( g_pPatch->ctrl[i][j].st[1] > g_2DView.m_Maxs[1] )
g_2DView.m_Maxs[1] = g_pPatch->ctrl[i][j].st[1];
}
}
FitView( hwndDlg, TexSize);
// init the work tables
g_WorkPatch = *g_pPatch;
g_ControlPointsPatch.Init( &g_WorkPatch, &g_2DView, &g_QglTable, g_pPatch );
// init snap-to-grid
float fTexStep[2];
fTexStep[0] = 1.0f / float(TexSize[0]);
fTexStep[1] = 1.0f / float(TexSize[1]);
g_2DView.SetGrid( fTexStep[0], fTexStep[1] );
g_pManager = &g_ControlPointsPatch;
// prepare the "cancel" data
g_CancelPatch = *g_pPatch;
// we are done
g_bTexViewReady = true;
}
}
void Textool_Validate()
{
// validate current situation into the main view
g_pManager->Commit( );
// for a brush face we have an aditionnal step
if (!g_bPatch)
{
// tell Radiant to update (will also send update windows messages )
g_SelectedFaceTable.m_pfnSetFaceInfo( 0, &g_SelectedFaceData );
}
else
{
// ask to rebuild the patch display data
g_pPatch->bDirty = true;
// send a repaint to the camera window as well
g_FuncTable.m_pfnSysUpdateWindows( W_CAMERA );
}
// we'll need to update after that as well:
g_bTexViewReady = false;
// send a repaint message
g_pToolWnd->Redraw ();
}
void Textool_Cancel()
{
if (!g_bPatch)
{
// tell Radiant to update (will also send update windows messages )
g_SelectedFaceTable.m_pfnSetFaceInfo( 0, &g_CancelFaceData );
}
else
{
*g_pPatch = g_CancelPatch;
g_pPatch->bDirty = true;
g_FuncTable.m_pfnSysUpdateWindows( W_CAMERA );
}
// do not call destroy, decref it
g_pToolWnd->DecRef();
g_pToolWnd = NULL;
}
static void DoExpose ()
{
int i,j;
g_2DView.PreparePaint();
g_QglTable.m_pfn_qglColor3f(1, 1, 1);
// draw the texture background
g_QglTable.m_pfn_qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
if (!g_bPatch)
{
g_QglTable.m_pfn_qglBindTexture( GL_TEXTURE_2D, g_SelectedFaceTable.m_pfnGetTextureNumber(0) );
}
else
{
g_QglTable.m_pfn_qglBindTexture( GL_TEXTURE_2D, g_pPatch->d_texture->texture_number );
}
g_QglTable.m_pfn_qglEnable( GL_TEXTURE_2D );
g_QglTable.m_pfn_qglBegin( GL_QUADS );
g_QglTable.m_pfn_qglTexCoord2f( g_2DView.m_Mins[0], g_2DView.m_Mins[1] );
g_QglTable.m_pfn_qglVertex2f( g_2DView.m_Mins[0], g_2DView.m_Mins[1] );
g_QglTable.m_pfn_qglTexCoord2f( g_2DView.m_Maxs[0], g_2DView.m_Mins[1] );
g_QglTable.m_pfn_qglVertex2f( g_2DView.m_Maxs[0], g_2DView.m_Mins[1] );
g_QglTable.m_pfn_qglTexCoord2f( g_2DView.m_Maxs[0], g_2DView.m_Maxs[1] );
g_QglTable.m_pfn_qglVertex2f( g_2DView.m_Maxs[0], g_2DView.m_Maxs[1] );
g_QglTable.m_pfn_qglTexCoord2f( g_2DView.m_Mins[0], g_2DView.m_Maxs[1] );
g_QglTable.m_pfn_qglVertex2f( g_2DView.m_Mins[0], g_2DView.m_Maxs[1] );
g_QglTable.m_pfn_qglEnd();
g_QglTable.m_pfn_qglDisable( GL_TEXTURE_2D );
if (!g_bPatch)
{
g_QglTable.m_pfn_qglBegin( GL_LINE_LOOP );
for ( i=0; i<g_NumPoints; i++ )
{
g_QglTable.m_pfn_qglVertex2f( g_WorkWinding.data[i][0], g_WorkWinding.data[i][1] );
}
g_QglTable.m_pfn_qglEnd();
}
else
{
g_QglTable.m_pfn_qglBegin( GL_LINES );
for ( i=0; i<g_pPatch->width; i++ )
for ( j=0; j<g_pPatch->height; j++ )
{
if ( i < g_pPatch->width-1 )
{
g_QglTable.m_pfn_qglVertex2f( g_WorkPatch.ctrl[i][j].st[0], g_WorkPatch.ctrl[i][j].st[1] );
g_QglTable.m_pfn_qglVertex2f( g_WorkPatch.ctrl[i+1][j].st[0], g_WorkPatch.ctrl[i+1][j].st[1] );
}
if ( j < g_pPatch->height-1 )
{
g_QglTable.m_pfn_qglVertex2f( g_WorkPatch.ctrl[i][j].st[0], g_WorkPatch.ctrl[i][j].st[1] );
g_QglTable.m_pfn_qglVertex2f( g_WorkPatch.ctrl[i][j+1].st[0], g_WorkPatch.ctrl[i][j+1].st[1] );
}
}
g_QglTable.m_pfn_qglEnd();
}
// let the control points manager render
g_pManager->render( );
}
static bool CanProcess ()
{
if (!g_bTexViewReady && !g_bClosing)
{
InitTexView (g_pToolWnd);
if (!g_bTexViewReady)
{
g_bClosing = true;
DoMessageBox ("You must have brush primitives activated in your project settings and\n"
"have a patch or a single face selected to use the TexTool plugin.\n"
"See plugins/TexToolHelp for documentation.", "TexTool plugin", MB_ICONERROR | MB_OK);
// decref, this will destroy
g_pToolWnd->DecRef();
g_pToolWnd = NULL;
return 0;
}
else
g_bClosing = false;
}
else if (!g_bTexViewReady && g_bClosing)
{
return 0;
}
return 1;
}
#if 0
static void button_press (GtkWidget *widget, GdkEventButton *event, gpointer data)
{
if (CanProcess ())
{
switch (event->button)
{
case 1:
g_pManager->OnLButtonDown (event->x, event->y); break;
case 3:
g_2DView.OnRButtonDown (event->x, event->y); break;
}
}
}
static void button_release (GtkWidget *widget, GdkEventButton *event, gpointer data)
{
if (CanProcess ())
{
switch (event->button)
{
case 1:
g_pManager->OnLButtonUp (event->x, event->y); break;
case 3:
g_2DView.OnRButtonUp (event->x, event->y); break;
}
}
}
static void motion (GtkWidget *widget, GdkEventMotion *event, gpointer data)
{
if (CanProcess ())
{
if (g_2DView.OnMouseMove (event->x, event->y))
return;
if (g_pManager->OnMouseMove (event->x, event->y))
return;
}
}
static gint expose (GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
if (event->count > 0)
return TRUE;
if (!CanProcess ())
return TRUE;
if (g_bTexViewReady)
{
g_2DView.m_rect.bottom = widget->allocation.height;
g_2DView.m_rect.right = widget->allocation.width;
if (!g_QglTable.m_pfn_glwidget_make_current (g_pToolWidget))
{
Sys_Printf("TexTool: glMakeCurrent failed\n");
return TRUE;
}
DoExpose ();
g_QglTable.m_pfn_glwidget_swap_buffers (g_pToolWidget);
}
return TRUE;
}
static gint keypress (GtkWidget* widget, GdkEventKey* event, gpointer data)
{
unsigned int code = gdk_keyval_to_upper(event->keyval);
if (code == GDK_Escape)
{
gtk_widget_destroy (g_pToolWnd);
g_pToolWnd = NULL;
return TRUE;
}
if (CanProcess ())
{
if (g_2DView.OnKeyDown (code))
return FALSE;
if (code == GDK_Return)
{
Textool_Validate();
return FALSE;
}
}
return TRUE;
}
static gint close (GtkWidget *widget, GdkEvent* event, gpointer data)
{
gtk_widget_destroy (widget);
g_pToolWnd = NULL;
return TRUE;
}
static GtkWidget* CreateOpenGLWidget ()
{
g_pToolWidget = g_QglTable.m_pfn_glwidget_new (FALSE, g_QglTable.m_pfn_GetQeglobalsGLWidget ());
gtk_widget_set_events (g_pToolWidget, GDK_DESTROY | GDK_EXPOSURE_MASK | GDK_KEY_PRESS_MASK |
GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK);
// Connect signal handlers
gtk_signal_connect (GTK_OBJECT (g_pToolWidget), "expose_event", GTK_SIGNAL_FUNC (expose), NULL);
gtk_signal_connect (GTK_OBJECT (g_pToolWidget), "motion_notify_event",
GTK_SIGNAL_FUNC (motion), NULL);
gtk_signal_connect (GTK_OBJECT (g_pToolWidget), "button_press_event",
GTK_SIGNAL_FUNC (button_press), NULL);
gtk_signal_connect (GTK_OBJECT (g_pToolWidget), "button_release_event",
GTK_SIGNAL_FUNC (button_release), NULL);
gtk_signal_connect (GTK_OBJECT (g_pToolWnd), "delete_event", GTK_SIGNAL_FUNC (close), NULL);
gtk_signal_connect (GTK_OBJECT (g_pToolWnd), "key_press_event",
GTK_SIGNAL_FUNC (keypress), NULL);
return g_pToolWidget;
}
#endif
#if 0
static void DoPaint ()
{
if (!CanProcess ())
return;
if (g_bTexViewReady)
{
g_2DView.m_rect.bottom = g_pToolWnd->getHeight();
g_2DView.m_rect.right = g_pToolWnd->getWidth();
// set GL_PROJECTION
g_2DView.PreparePaint();
// render the objects
// the master is not rendered the same way, draw over a unified texture background
g_2DView.TextureBackground(g_DrawObjects[0].pObject->getTextureNumber());
if (g_nDrawObjects >= 1)
{
int i;
for (i=1;i<g_nDrawObjects;i++)
{
// we use a first step to the GL_MODELVIEW for the master object
// GL_MODELVIEW will be altered in RenderAuxiliary too
g_DrawObjects[0].pObject->PrepareModelView(g_DrawObjects[i].pTopo);
g_DrawObjects[i].pObject->RenderAuxiliary();
}
}
// draw the polygon outline and control points
g_DrawObjects[0].pObject->PrepareModelView(NULL);
g_DrawObjects[0].pObject->RenderUI();
}
}
#endif
bool CWindowListener::OnLButtonDown(guint32 nFlags, double x, double y)
{
if (CanProcess())
{
g_pManager->OnLButtonDown((int)x, (int)y);
return true;
}
return false;
}
bool CWindowListener::OnRButtonDown(guint32 nFlags, double x, double y)
{
if (CanProcess())
{
g_2DView.OnRButtonDown ((int)x, (int)y);
return true;
}
return false;
}
bool CWindowListener::OnLButtonUp(guint32 nFlags, double x, double y)
{
if (CanProcess())
{
g_pManager->OnLButtonUp((int)x, (int)y);
return true;
}
return false;
}
bool CWindowListener::OnRButtonUp(guint32 nFlags, double x, double y)
{
if (CanProcess())
{
g_2DView.OnRButtonUp ((int)x, (int)y);
return true;
}
return false;
}
bool CWindowListener::OnMouseMove(guint32 nFlags, double x, double y)
{
if (CanProcess ())
{
if (g_2DView.OnMouseMove ((int)x, (int)y))
return true;
g_pManager->OnMouseMove((int)x, (int)y);
return true;
}
return false;
}
// the widget is closing
void CWindowListener::Close()
{
g_pToolWnd = NULL;
}
bool CWindowListener::Paint()
{
if (!CanProcess ())
return false;
if (g_bTexViewReady)
DoExpose();
return true;
}
bool CWindowListener::OnKeyPressed(char *s)
{
if (!strcmp(s,"Escape"))
{
Textool_Cancel();
return TRUE;
}
if (CanProcess ())
{
if (g_2DView.OnKeyDown (s))
return TRUE;
if (!strcmp(s,"Return"))
{
Textool_Validate();
return TRUE;
}
}
return FALSE;
}
extern "C" void QERPlug_Dispatch(const char* p, vec3_t vMin, vec3_t vMax, bool bSingleBrush)
{
#if 0
// if it's the first call, perhaps we need some additional init steps
if (!g_bQglInitDone)
{
g_QglTable.m_nSize = sizeof(OpenGLBinding);
if ( g_FuncTable.m_pfnRequestInterface( QERQglTable_GUID, static_cast<LPVOID>(&g_QglTable) ) )
{
g_bQglInitDone = true;
}
else
{
Sys_Printf("TexTool plugin: OpenGLBinding interface request failed\n");
return;
}
}
if (!g_bSelectedFaceInitDone)
{
g_SelectedFaceTable.m_nSize = sizeof(_QERSelectedFaceTable);
if (g_FuncTable.m_pfnRequestInterface (QERSelectedFaceTable_GUID,
static_cast<LPVOID>(&g_SelectedFaceTable)))
{
g_bSelectedFaceInitDone = true;
}
else
{
Sys_Printf("TexTool plugin: _QERSelectedFaceTable interface request failed\n");
return;
}
}
if (!g_bSurfaceTableInitDone)
{
g_SurfaceTable.m_nSize = sizeof(_QERAppSurfaceTable);
if ( g_FuncTable.m_pfnRequestInterface( QERAppSurfaceTable_GUID, static_cast<LPVOID>(&g_SurfaceTable) ) )
{
g_bSurfaceTableInitDone = true;
}
else
{
Sys_Printf("TexTool plugin: _QERAppSurfaceTable interface request failed\n");
return;
}
}
if (!g_bUITable)
{
g_UITable.m_nSize = sizeof(_QERUITable);
if ( g_FuncTable.m_pfnRequestInterface( QERUI_GUID, static_cast<LPVOID>(&g_UITable) ) )
{
g_bUITable = true;
}
else
{
Sys_Printf("TexTool plugin: _QERUITable interface request failed\n");
return;
}
}
#endif
if (!strcmp(p, "About..."))
{
DoMessageBox (PLUGIN_ABOUT, "About ...", MB_OK );
}
else if (!strcmp(p, "Go..."))
{
if (!g_pToolWnd)
{
g_pToolWnd = g_UITable.m_pfnCreateGLWindow();
g_pToolWnd->setSizeParm(300,300);
g_pToolWnd->setName("TexTool");
// g_Listener is a static class, we need to bump the refCount to avoid premature release problems
g_Listen.IncRef();
// setListener will incRef on the listener too
g_pToolWnd->setListener(&g_Listen);
if (!g_pToolWnd->Show())
{
DoMessageBox ("Error creating texture tools window!", "TexTool plugin", MB_ICONERROR | MB_OK);
return;
}
}
g_bTexViewReady = false;
g_bClosing = false;
}
else if (!strcmp(p, "Help..."))
{
if (!g_bHelp)
DoMessageBox ("Select a brush face (ctrl+shift+left mouse) or a patch, and hit Go...\n"
"See tutorials for more", "TexTool plugin", MB_OK );
else
DoMessageBox ("Are you kidding me ?", "TexTool plugin", MB_OK );
g_bHelp = true;
}
}
// =============================================================================
// SYNAPSE
CSynapseServer* g_pSynapseServer = NULL;
CSynapseClientTexTool g_SynapseClient;
extern "C" CSynapseClient* SYNAPSE_DLL_EXPORT Synapse_EnumerateInterfaces (const char *version, CSynapseServer *pServer)
{
if (strcmp(version, SYNAPSE_VERSION))
{
Syn_Printf("ERROR: synapse API version mismatch: should be '" SYNAPSE_VERSION "', got '%s'\n", version);
return NULL;
}
g_pSynapseServer = pServer;
g_pSynapseServer->IncRef();
Set_Syn_Printf(g_pSynapseServer->Get_Syn_Printf());
g_SynapseClient.AddAPI(PLUGIN_MAJOR, "textool", sizeof(_QERPluginTable));
g_SynapseClient.AddAPI(RADIANT_MAJOR, NULL, sizeof(g_FuncTable), SYN_REQUIRE, &g_FuncTable);
g_SynapseClient.AddAPI(QGL_MAJOR, NULL, sizeof(g_QglTable), SYN_REQUIRE, &g_QglTable);
g_SynapseClient.AddAPI(SELECTEDFACE_MAJOR, NULL, sizeof(g_SelectedFaceTable), SYN_REQUIRE, &g_SelectedFaceTable);
return &g_SynapseClient;
}
bool CSynapseClientTexTool::RequestAPI(APIDescriptor_t *pAPI)
{
if (!strcmp(pAPI->major_name, PLUGIN_MAJOR))
{
_QERPluginTable *pTable = static_cast<_QERPluginTable*>(pAPI->mpTable);
pTable->m_pfnQERPlug_Init = QERPlug_Init;
pTable->m_pfnQERPlug_GetName = QERPlug_GetName;
pTable->m_pfnQERPlug_GetCommandList = QERPlug_GetCommandList;
pTable->m_pfnQERPlug_Dispatch = QERPlug_Dispatch;
return true;
}
Syn_Printf("ERROR: RequestAPI( '%s' ) not found in '%s'\n", pAPI->major_name, GetInfo());
return false;
}
#include "version.h"
const char* CSynapseClientTexTool::GetInfo()
{
return "Texture Tools plugin built " __DATE__ " " RADIANT_VERSION;
}

View File

@@ -0,0 +1,12 @@
; TexTool.def : Declares the module parameters for the DLL.
LIBRARY "TexTool"
DESCRIPTION 'TexTool Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
QERPlug_Init @1
QERPlug_GetName @2
QERPlug_GetCommandList @3
QERPlug_Dispatch @4
QERPlug_GetFuncTable @5

174
plugins/textool/TexTool.dsp Normal file
View File

@@ -0,0 +1,174 @@
# Microsoft Developer Studio Project File - Name="TexTool" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=TexTool - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "TexTool.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "TexTool.mak" CFG="TexTool - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "TexTool - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "TexTool - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName "TexTool"
# PROP Scc_LocalPath "..\.."
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "TexTool - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
F90=df.exe
# ADD BASE F90 /include:"Release/"
# ADD F90 /include:"Release/"
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEXTOOL_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /O2 /I "..\..\libs" /I "..\common" /I "..\..\include" /I "..\..\..\src-2.0\include\glib-2.0" /I "..\..\..\src-2.0\lib\glib-2.0\include" /I "..\..\..\src-2.0\lib\gtk-2.0\include" /I "..\..\..\src-2.0\include\gtk-2.0" /I "..\..\..\src-2.0\include\gtk-2.0\gdk" /I "..\..\..\src-2.0\include\pango-1.0" /I "..\..\..\src-2.0\include\atk-1.0" /I "..\..\..\STLPort\stlport" /I "..\..\..\libxml2\include" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEXTOOL_EXPORTS" /D "GTK_PLUGIN" /Yu"stdafx.h" /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x40c /d "NDEBUG"
# ADD RSC /l 0x40c /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 glib-2.0.lib gobject-2.0.lib gdk-win32-2.0.lib gtk-win32-2.0.lib mathlib.lib /nologo /dll /machine:I386 /libpath:"..\..\..\src-2.0\lib\\" /libpath:"../../libs/mathlib/Release"
!ELSEIF "$(CFG)" == "TexTool - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
F90=df.exe
# ADD BASE F90 /include:"Debug/"
# ADD F90 /include:"Debug/"
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEXTOOL_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /I "..\..\libs" /I "..\common" /I "..\..\include" /I "..\..\..\src-2.0\include\glib-2.0" /I "..\..\..\src-2.0\lib\glib-2.0\include" /I "..\..\..\src-2.0\lib\gtk-2.0\include" /I "..\..\..\src-2.0\include\gtk-2.0" /I "..\..\..\src-2.0\include\gtk-2.0\gdk" /I "..\..\..\src-2.0\include\pango-1.0" /I "..\..\..\src-2.0\include\atk-1.0" /I "..\..\..\STLPort\stlport" /I "..\..\..\libxml2\include" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "TEXTOOL_EXPORTS" /D "GTK_PLUGIN" /FR /Yu"stdafx.h" /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x40c /d "_DEBUG"
# ADD RSC /l 0x40c /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 glib-2.0.lib gobject-2.0.lib gdk-win32-2.0.lib gtk-win32-2.0.lib mathlib.lib /nologo /dll /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\src-2.0\lib\\" /libpath:"../../libs/mathlib/Debug"
!ENDIF
# Begin Target
# Name "TexTool - Win32 Release"
# Name "TexTool - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\2DView.cpp
# End Source File
# Begin Source File
SOURCE=.\ControlPointsManager.cpp
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# ADD CPP /Yc"stdafx.h"
# End Source File
# Begin Source File
SOURCE=.\TexTool.cpp
# End Source File
# Begin Source File
SOURCE=.\TexTool.def
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Group "interfaces"
# PROP Default_Filter ""
# Begin Source File
SOURCE=..\..\Q3Radiant\igl.h
# End Source File
# Begin Source File
SOURCE=..\..\Q3Radiant\ISelectedFace.h
# End Source File
# Begin Source File
SOURCE=..\..\Q3Radiant\isurfaceplugin.h
# End Source File
# End Group
# Begin Source File
SOURCE=.\2DView.h
# End Source File
# Begin Source File
SOURCE=.\ControlPointsManager.h
# End Source File
# Begin Source File
SOURCE=..\common\mathlib.h
# End Source File
# Begin Source File
SOURCE=..\..\Q3Radiant\qerplugin.h
# End Source File
# Begin Source File
SOURCE=..\..\Q3Radiant\QERTYPES.H
# End Source File
# Begin Source File
SOURCE=.\stdafx.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=.\TexTool.rc
# End Source File
# End Group
# End Target
# End Project

136
plugins/textool/TexTool.rc Normal file
View File

@@ -0,0 +1,136 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// Neutral resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_NEU)
#ifdef _WIN32
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DIALOG2 DIALOGEX 0, 0, 290, 206
STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_TOOLWINDOW
FONT 8, "MS Sans Serif"
BEGIN
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_DIALOG2, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 283
TOPMARGIN, 7
BOTTOMMARGIN, 199
END
END
#endif // APSTUDIO_INVOKED
#endif // Neutral resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_DROP_MENU MENU DISCARDABLE
BEGIN
POPUP "Drop"
BEGIN
MENUITEM "Validate (RETURN)", ID_DROP_VALIDATE
MENUITEM "Zoom in (INSERT)", ID_DROP_ZOOMIN
MENUITEM "Zoom out (SUPPR)", ID_DROP_ZOOMOUT
MENUITEM "Cancel (ESC)", ID_DROP_CANCEL
END
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// French (France) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA)
#ifdef _WIN32
LANGUAGE LANG_FRENCH, SUBLANG_FRENCH
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // French (France) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,211 @@
<?xml version="1.0" encoding = "Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.00"
Name="TexTool">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\libs,..\common,..\..\include,..\..\..\src-2.0\include\glib-2.0,..\..\..\src-2.0\lib\glib-2.0\include,..\..\..\src-2.0\lib\gtk-2.0\include,..\..\..\src-2.0\include\gtk-2.0,..\..\..\src-2.0\include\gtk-2.0\gdk,..\..\..\src-2.0\include\pango-1.0,..\..\..\src-2.0\include\atk-1.0,..\..\..\STLPort\stlport,..\..\..\libxml2\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;TEXTOOL_EXPORTS;GTK_PLUGIN"
StringPooling="TRUE"
RuntimeLibrary="2"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="3"
PrecompiledHeaderThrough="stdafx.h"
PrecompiledHeaderFile=".\Release/TexTool.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="glib-2.0.lib gobject-2.0.lib gdk-win32-2.0.lib gtk-win32-2.0.lib mathlib.lib"
OutputFile=".\Release/TexTool.dll"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\..\..\src-2.0\lib\,../../libs/mathlib/Release"
ModuleDefinitionFile=".\TexTool.def"
ProgramDatabaseFile=".\Release/TexTool.pdb"
ImportLibrary=".\Release/TexTool.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="NDEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\Release/TexTool.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1036"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\libs,..\common,..\..\include,..\..\..\src-2.0\include\glib-2.0,..\..\..\src-2.0\lib\glib-2.0\include,..\..\..\src-2.0\lib\gtk-2.0\include,..\..\..\src-2.0\include\gtk-2.0,..\..\..\src-2.0\include\gtk-2.0\gdk,..\..\..\src-2.0\include\pango-1.0,..\..\..\src-2.0\include\atk-1.0,..\..\..\STLPort\stlport,..\..\..\libxml2\include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;TEXTOOL_EXPORTS;GTK_PLUGIN"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="3"
PrecompiledHeaderThrough="stdafx.h"
PrecompiledHeaderFile=".\Debug/TexTool.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalOptions="/MACHINE:I386"
AdditionalDependencies="glib-2.0.lib gobject-2.0.lib gdk-win32-2.0.lib gtk-win32-2.0.lib mathlib.lib"
OutputFile=".\Debug/TexTool.dll"
LinkIncremental="2"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\..\..\src-2.0\lib\,../../libs/mathlib/Debug"
ModuleDefinitionFile=".\TexTool.def"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/TexTool.pdb"
ImportLibrary=".\Debug/TexTool.lib"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\Debug/TexTool.tlb"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1036"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
</Configurations>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
<File
RelativePath=".\2DView.cpp">
</File>
<File
RelativePath=".\ControlPointsManager.cpp">
</File>
<File
RelativePath=".\StdAfx.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
UsePrecompiledHeader="1"/>
</FileConfiguration>
</File>
<File
RelativePath=".\TexTool.cpp">
</File>
<File
RelativePath=".\TexTool.def">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl">
<File
RelativePath=".\2DView.h">
</File>
<File
RelativePath=".\ControlPointsManager.h">
</File>
<File
RelativePath="..\..\Q3Radiant\QERTYPES.H">
</File>
<File
RelativePath="..\common\mathlib.h">
</File>
<File
RelativePath="..\..\Q3Radiant\qerplugin.h">
</File>
<File
RelativePath=".\stdafx.h">
</File>
<Filter
Name="interfaces"
Filter="">
<File
RelativePath="..\..\Q3Radiant\ISelectedFace.h">
</File>
<File
RelativePath="..\..\Q3Radiant\igl.h">
</File>
<File
RelativePath="..\..\Q3Radiant\isurfaceplugin.h">
</File>
</Filter>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe">
<File
RelativePath=".\TexTool.rc">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,8 @@
11/19/99
first usable version
here is the TODO-list for next release, ( most certainly a wish list )
- TODO: add hooks with the selected face and selected patch data. tell the plugin when selected face
or selected patch has changed.
the hooks should use a generic interface inside Radiant for "observers"
- TODO: add other usefull texturing tools, if designers come up with good ideas

View File

@@ -0,0 +1,23 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by TexTool.rc
//
#define IDUNDO 3
#define IDD_DIALOG 101
#define IDD_DIALOG2 102
#define IDR_DROP_MENU 103
#define ID_DROP_VALIDATE 40001
#define ID_DROP_ZOOMIN 40002
#define ID_DROP_ZOOMOUT 40003
#define ID_DROP_CANCEL 40004
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 104
#define _APS_NEXT_COMMAND_VALUE 40005
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif