binds...
	* douplicated basic shortcuts: arrows - camera freemove, ESC - deSelect, backSpace - delete

menus...
	* modify+: snap to grid (ctrl+g)

misc...
	* fixed warning on import (q3map2_type not found)
	* patch thicken
	* removed douplicate accelerators registering
	* trigger_* entities get textures/common/trigger tex on creation
		( unless different is set in .game file via shader_trigger key )
	* opening *.map, sent via cmd line (can assign *.map files in system to be opened with radiant)
	* -aero cmd line key to enable aero transparency
	* opening maps with bad tex defs (.#QNAN, .#IND, .#INF)
		(happens sometimes after rotating & often scaling with tex lock (in BP mode)); error->warning
This commit is contained in:
Garux
2017-08-01 14:00:12 +03:00
parent f8b2b1f25e
commit a59855266c
13 changed files with 640 additions and 12 deletions

View File

@@ -196,6 +196,83 @@ void Scene_PatchDeform( scene::Graph& graph, const int deform )
}
void Patch_thicken( Patch& patch, scene::Instance& instance, const float thickness, bool seams, const int axis ){
// Create a new patch node
NodeSmartReference node(g_patchCreator->createPatch());
// Insert the node into worldspawn
Node_getTraversable(Map_FindOrInsertWorldspawn(g_map))->insert(node);
// Retrieve the contained patch from the node
Patch* targetPatch = Node_getPatch(node);
// Create the opposite patch with the given thickness = distance
bool no12 = true;
bool no34 = true;
targetPatch->createThickenedOpposite(patch, thickness, axis, no12, no34);
// Now select the newly created patches
{
scene::Path patchpath(makeReference(GlobalSceneGraph().root()));
patchpath.push(makeReference(*Map_GetWorldspawn(g_map)));
patchpath.push(makeReference(node.get()));
Instance_getSelectable(*GlobalSceneGraph().find(patchpath))->setSelected(true);
}
if (seams && thickness != 0.0f) {
int i = 0;
if ( no12 ){
i = 2;
}
int iend = 4;
if ( no34 ){
iend = 2;
}
// Now create the four walls
for ( ; i < iend; i++ ) {
// Allocate new patch
NodeSmartReference node = NodeSmartReference(g_patchCreator->createPatch());
// Insert each node into worldspawn
Node_getTraversable(Map_FindOrInsertWorldspawn(g_map))->insert(node);
// Retrieve the contained patch from the node
Patch* wallPatch = Node_getPatch(node);
// Create the wall patch by passing i as wallIndex
wallPatch->createThickenedWall( patch, *targetPatch, i);
if( ( wallPatch->localAABB().extents[0] <= 0.00005 && wallPatch->localAABB().extents[1] <= 0.00005 ) ||
( wallPatch->localAABB().extents[1] <= 0.00005 && wallPatch->localAABB().extents[2] <= 0.00005 ) ||
( wallPatch->localAABB().extents[0] <= 0.00005 && wallPatch->localAABB().extents[2] <= 0.00005 ) ){
//globalOutputStream() << "Thicken: Discarding degenerate patch.\n";
Node_getTraversable( Map_FindOrInsertWorldspawn(g_map) )->erase( node );
}
else
// Now select the newly created patches
{
scene::Path patchpath(makeReference(GlobalSceneGraph().root()));
patchpath.push(makeReference(*Map_GetWorldspawn(g_map)));
patchpath.push(makeReference(node.get()));
Instance_getSelectable(*GlobalSceneGraph().find(patchpath))->setSelected(true);
}
}
}
// Invert the target patch so that it faces the opposite direction
targetPatch->InvertMatrix();
}
void Scene_PatchThicken( scene::Graph& graph, const int thickness, bool seams, const int axis )
{
InstanceVector instances;
Scene_forEachVisibleSelectedPatchInstance( PatchStoreInstance( instances ) );
for ( InstanceVector::const_iterator i = instances.begin(); i != instances.end(); ++i )
{
Patch_thicken( *Node_getPatch( ( *i )->path().top() ), *( *i ), thickness, seams, axis );
}
}
Patch* Scene_GetUltimateSelectedVisiblePatch(){
if ( GlobalSelectionSystem().countSelected() != 0 ) {
scene::Node& node = GlobalSelectionSystem().ultimateSelected().path().top();
@@ -618,6 +695,13 @@ void Patch_Deform(){
DoPatchDeformDlg();
}
void DoPatchThickenDlg();
void Patch_Thicken(){
UndoableCommand undo( "patchThicken" );
DoPatchThickenDlg();
}
@@ -732,6 +816,7 @@ void Patch_registerCommands(){
GlobalCommands_insert( "MakeOverlayPatch", FreeCaller<Patch_OverlayOn>(), Accelerator( 'Y' ) );
GlobalCommands_insert( "ClearPatchOverlays", FreeCaller<Patch_OverlayOff>(), Accelerator( 'L', (GdkModifierType)GDK_CONTROL_MASK ) );
GlobalCommands_insert( "PatchDeform", FreeCaller<Patch_Deform>() );
GlobalCommands_insert( "PatchThicken", FreeCaller<Patch_Thicken>() );
}
void Patch_constructToolbar( GtkToolbar* toolbar ){
@@ -840,6 +925,7 @@ void Patch_constructMenu( GtkMenu* menu ){
}
menu_separator( menu );
create_menu_item_with_mnemonic( menu, "Deform...", "PatchDeform" );
create_menu_item_with_mnemonic( menu, "Thicken...", "PatchThicken" );
}
@@ -1198,3 +1284,128 @@ EMessageBoxReturn DoCapDlg( ECapDialog* type ){
return ret;
}
void DoPatchThickenDlg(){
ModalDialog dialog;
GtkWidget* thicknessW;
GtkWidget* seamsW;
GtkWidget* radX;
GtkWidget* radY;
GtkWidget* radZ;
GtkWidget* radNormals;
GtkWindow* window = create_dialog_window( MainFrame_getWindow(), "Patch thicken", G_CALLBACK( dialog_delete_callback ), &dialog );
GtkAccelGroup* accel = gtk_accel_group_new();
gtk_window_add_accel_group( window, accel );
{
GtkHBox* hbox = create_dialog_hbox( 4, 4 );
gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( hbox ) );
{
GtkTable* table = create_dialog_table( 2, 4, 4, 4 );
gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( table ), TRUE, TRUE, 0 );
{
GtkLabel* label = GTK_LABEL( gtk_label_new( "Thickness:" ) );
gtk_widget_show( GTK_WIDGET( label ) );
gtk_table_attach( table, GTK_WIDGET( label ), 0, 1, 0, 1,
(GtkAttachOptions) ( GTK_FILL ),
(GtkAttachOptions) ( 0 ), 0, 0 );
gtk_misc_set_alignment( GTK_MISC( label ), 0, 0.5 );
}
{
GtkWidget* entry = gtk_entry_new();
gtk_entry_set_text( GTK_ENTRY( entry ), "16" );
gtk_widget_set_size_request( entry, 40, -1 );
gtk_widget_show( entry );
gtk_table_attach( table, entry, 1, 2, 0, 1,
(GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
(GtkAttachOptions) ( 0 ), 0, 0 );
thicknessW = entry;
}
{
// Create the "create seams" label
GtkWidget* _seamsCheckBox = gtk_check_button_new_with_label( "Side walls" );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( _seamsCheckBox ), TRUE );
gtk_widget_show( _seamsCheckBox );
gtk_table_attach( table, _seamsCheckBox, 3, 4, 0, 1,
(GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
(GtkAttachOptions) ( 0 ), 0, 0 );
seamsW = _seamsCheckBox;
}
{
// Create the radio button group for choosing the extrude axis
GtkWidget* _radNormals = gtk_radio_button_new_with_label( NULL, "Normal" );
GtkWidget* _radX = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(_radNormals), "X" );
GtkWidget* _radY = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(_radNormals), "Y" );
GtkWidget* _radZ = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON(_radNormals), "Z" );
gtk_widget_show( _radNormals );
gtk_widget_show( _radX );
gtk_widget_show( _radY );
gtk_widget_show( _radZ );
// Pack the buttons into the table
gtk_table_attach( table, _radNormals, 0, 1, 1, 2,
(GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
(GtkAttachOptions) ( 0 ), 0, 0 );
gtk_table_attach( table, _radX, 1, 2, 1, 2,
(GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
(GtkAttachOptions) ( 0 ), 0, 0 );
gtk_table_attach( table, _radY, 2, 3, 1, 2,
(GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
(GtkAttachOptions) ( 0 ), 0, 0 );
gtk_table_attach( table, _radZ, 3, 4, 1, 2,
(GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ),
(GtkAttachOptions) ( 0 ), 0, 0 );
radX = _radX;
radY = _radY;
radZ = _radZ;
radNormals = _radNormals;
}
}
{
GtkVBox* vbox = create_dialog_vbox( 4 );
gtk_box_pack_start( GTK_BOX( hbox ), GTK_WIDGET( vbox ), TRUE, TRUE, 0 );
{
GtkButton* button = create_dialog_button( "OK", G_CALLBACK( dialog_button_ok ), &dialog );
gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 );
widget_make_default( GTK_WIDGET( button ) );
gtk_widget_grab_focus( GTK_WIDGET( button ) );
gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_Return, (GdkModifierType)0, (GtkAccelFlags)0 );
}
{
GtkButton* button = create_dialog_button( "Cancel", G_CALLBACK( dialog_button_cancel ), &dialog );
gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( button ), FALSE, FALSE, 0 );
gtk_widget_add_accelerator( GTK_WIDGET( button ), "clicked", accel, GDK_Escape, (GdkModifierType)0, (GtkAccelFlags)0 );
}
}
}
if ( modal_dialog_show( window, dialog ) == eIDOK ) {
int axis;
bool seams;
float thickness = static_cast<float>( atoi( gtk_entry_get_text( GTK_ENTRY( thicknessW ) ) ) );
seams = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON( seamsW )) ? true : false;
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radX))) {
axis = 0;
}
else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radY))) {
axis = 1;
}
else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radZ))) {
axis = 2;
}
else {
// Extrude along normals
axis = 3;
}
Scene_PatchThicken( GlobalSceneGraph(), thickness, seams, axis );
}
gtk_widget_destroy( GTK_WIDGET( window ) );
}