disable fastnormalize for light: was increasing dirt from arealights, lighting with acute angle

Radiant:

binds...
	* QE tool: alt + m1 drag in primitives mode:
		click face = clicked faces shear
	* m3 in texbro: select texture w/o applying to selection
	* `: XYFocusOnSelected
	* ctrl + shift + e: Select Connected Entities
misc...
	* search in shortcuts list
	* edit shortcuts on m1 dbl click
	* edit shortcuts fix: could highlight a few rows for editing
	* texbro: toggle off hideUnused on loading a tag
	* fix of: undo something, select tex in texbro, no redo available
	* epsilon in resize brush selector to prevent perpendicular faces pickup
	* clone group entity primitives to separate entity on cloneSelectedMakeUnique
	* Focus on Selected option in Entity List (focus cam and center xy)
	* entity inspector: connected entities walker (select target / targeting / both)(focus)
This commit is contained in:
Garux 2017-08-02 09:21:32 +03:00
parent 461d008daa
commit dfce2da577
20 changed files with 424 additions and 44 deletions

View File

@ -102,12 +102,19 @@ void _CrossProduct( vec3_t v1, vec3_t v2, vec3_t cross );
// This define affect the precision of VectorNormalize() function only.
#define MATHLIB_VECTOR_NORMALIZE_PRECISION_FIX 1
vec_t VectorAccurateNormalize( const vec3_t in, vec3_t out );
vec_t VectorFastNormalize( const vec3_t in, vec3_t out );
vec_t VectorFastNormalize_( const vec3_t in, vec3_t out );
#if MATHLIB_VECTOR_NORMALIZE_PRECISION_FIX
#define VectorNormalize VectorAccurateNormalize
#else
#define VectorNormalize VectorFastNormalize
#define VectorNormalize VectorFastNormalize_
#endif
#if 0 //use fastnormalize in a few -light spots
#define VectorFastNormalize VectorFastNormalize_
#else
#define VectorFastNormalize VectorNormalize
#endif
vec_t ColorNormalize( const vec3_t in, vec3_t out );
void VectorInverse( vec3_t v );
void VectorPolar( vec3_t v, float radius, float theta, float phi );

View File

@ -179,7 +179,7 @@ vec_t VectorAccurateNormalize( const vec3_t in, vec3_t out ) {
return (vec_t) length;
}
vec_t VectorFastNormalize( const vec3_t in, vec3_t out ) {
vec_t VectorFastNormalize_( const vec3_t in, vec3_t out ) {
// SmileTheory: This is ioquake3's VectorNormalize2
// for when accuracy matters less than speed

View File

@ -84,7 +84,12 @@ ID_INLINE mat3_t::mat3_t() {
}
ID_INLINE mat3_t::mat3_t( float src[ 3 ][ 3 ] ) {
memcpy( mat, src, sizeof( src ) );
//memcpy( mat, src, sizeof( src ) );
for( unsigned int i = 0; i < 3; i++ ) {
mat[i].x = src[i][0];
mat[i].y = src[i][1];
mat[i].z = src[i][2];
}
}
ID_INLINE mat3_t::mat3_t( idVec3 const &x, idVec3 const &y, idVec3 const &z ) {

View File

@ -2425,6 +2425,34 @@ void forEachLight( const RendererLightCallback& callback ) const {
}
};
class BoolSelector : public Selector
{
bool m_selected;
SelectionIntersection m_intersection;
Selectable* m_selectable;
public:
BoolSelector() : m_selected( false ){
}
void pushSelectable( Selectable& selectable ){
m_intersection = SelectionIntersection();
m_selectable = &selectable;
}
void popSelectable(){
if ( m_intersection.valid() ) {
m_selected = true;
}
m_intersection = SelectionIntersection();
}
void addIntersection( const SelectionIntersection& intersection ){
assign_if_closer( m_intersection, intersection );
}
bool isSelected(){
return m_selected;
}
};
class FaceInstance
{
Face* m_face;
@ -2624,7 +2652,9 @@ void selectPlane( Selector& selector, const Line& line, const PlaneCallback& sel
{
Vector3 v( vector3_subtracted( line_closest_point( line, ( *i ).vertex ), ( *i ).vertex ) );
double dot = vector3_dot( getFace().plane3().normal(), v );
if ( dot <= 0 ) {
//globalOutputStream() << dot << "\n";
//epsilon to prevent perpendicular faces pickup
if ( dot <= 0.005 ) {
return;
}
}
@ -2643,7 +2673,8 @@ bool trySelectPlane( const Line& line ){
for ( Winding::const_iterator i = getFace().getWinding().begin(); i != getFace().getWinding().end(); ++i ){
Vector3 v( vector3_subtracted( line_closest_point( line, ( *i ).vertex ), ( *i ).vertex ) );
double dot = vector3_dot( getFace().plane3().normal(), v );
if ( dot <= 0 ) {
//epsilon to prevent perpendicular faces pickup
if ( dot <= 0.005 ) {
return false;
}
}
@ -3020,6 +3051,20 @@ void selectVerticesOnPlanes( SelectionTest& test ){
}
while ( faceVertex.getFace() != m_vertex->m_faceVertex.getFace() );
}
void selectVerticesOnTestedFaces( SelectionTest& test ){
FaceVertexId faceVertex = m_vertex->m_faceVertex;
do
{
BoolSelector selector;
m_faceInstances[faceVertex.getFace()].testSelect( selector, test );
if( selector.isSelected() ){
setSelected( true );
}
faceVertex = next_vertex( m_vertex->m_faces, faceVertex );
}
while ( faceVertex.getFace() != m_vertex->m_faceVertex.getFace() );
}
};
class BrushInstanceVisitor
@ -3486,6 +3531,15 @@ void selectVerticesOnPlanes( SelectionTest& test ){
}
void selectVerticesOnTestedFaces( SelectionTest& test ){
test.BeginMesh( localToWorld() );
for ( VertexInstances::iterator i = m_vertexInstances.begin(); i != m_vertexInstances.end(); ++i ){
( *i ).selectVerticesOnTestedFaces( test );
}
}
void transformComponents( const Matrix4& matrix ){
for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
{

View File

@ -1695,20 +1695,22 @@ void GlobalCamera_ResetAngles(){
void GlobalCamera_FocusOnSelected(){
CamWnd& camwnd = *g_camwnd;
/*
Vector3 angles( Camera_getAngles( camwnd ) );
Vector3 radangles( degrees_to_radians( angles[0] ), degrees_to_radians( angles[1] ), degrees_to_radians( angles[2] ) );
Vector3 viewvector;
viewvector[0] = cos( radangles[1] ) * cos( radangles[0] );
viewvector[1] = sin( radangles[1] ) * cos( radangles[0] );
viewvector[2] = sin( radangles[0] );
*/
Vector3 camorigin( Camera_getOrigin( camwnd ) );
AABB aabb( aabb_for_minmax( Select_getWorkZone().d_work_min, Select_getWorkZone().d_work_max ) );
View& view = *( camwnd.getCamera().m_view );
Vector3 viewvector( -view.GetModelview()[2], -view.GetModelview()[6], -view.GetModelview()[10] );
Plane3 frustumPlanes[4];
frustumPlanes[0] = plane3_translated( view.getFrustum().left, camorigin - aabb.origin );
frustumPlanes[1] = plane3_translated( view.getFrustum().right, camorigin - aabb.origin );
@ -1732,6 +1734,13 @@ void GlobalCamera_FocusOnSelected(){
}
}
}
/*
globalOutputStream() << viewvector << "\n";
globalOutputStream() << view.GetModelview()[0] << " " << view.GetModelview()[1] << " " << view.GetModelview()[2] << " " << view.GetModelview()[3] << "\n"
<< view.GetModelview()[4] << " " << view.GetModelview()[5] << " " << view.GetModelview()[6] << " " << view.GetModelview()[7] << "\n"
<< view.GetModelview()[8] << " " << view.GetModelview()[9] << " " << view.GetModelview()[10] << " " << view.GetModelview()[11] << "\n"
<< view.GetModelview()[12] << " " << view.GetModelview()[13] << " " << view.GetModelview()[14] << " " << view.GetModelview()[15] << "\n";
*/
Camera_setOrigin( camwnd, aabb.origin - viewvector * offset );
}

View File

@ -50,6 +50,8 @@ void GlobalCamera_Benchmark();
const Vector3& Camera_getOrigin( CamWnd& camwnd );
void Camera_setOrigin( CamWnd& camwnd, const Vector3& origin );
void GlobalCamera_FocusOnSelected();
enum
{
CAMERA_PITCH = 0, // up / down

View File

@ -226,6 +226,11 @@ void accelerator_edit_button_clicked( GtkButton *btn, gpointer dialogptr ){
if ( !gtk_tree_selection_get_selected( sel, &model, &iter ) ) {
return;
}
if ( dialog.m_waiting_for_key ) {
// unhighlight highlit
dialog.m_waiting_for_key = false;
gtk_list_store_set( GTK_LIST_STORE( dialog.m_model ), &dialog.m_command_iter, 2, false, -1 );
}
dialog.m_command_iter = iter;
dialog.m_model = model;
@ -239,6 +244,14 @@ void accelerator_edit_button_clicked( GtkButton *btn, gpointer dialogptr ){
dialog.m_waiting_for_key = true;
}
gboolean accelerator_tree_butt_press( GtkWidget* widget, GdkEventButton* event, gpointer dialogptr ){
if ( event->type == GDK_2BUTTON_PRESS && event->button == 1 ) {
accelerator_edit_button_clicked( 0, dialogptr );
return TRUE;
}
return FALSE;
}
gboolean accelerator_window_key_press( GtkWidget *widget, GdkEventKey *event, gpointer dialogptr ){
command_list_dialog_t &dialog = *(command_list_dialog_t *) dialogptr;
@ -413,7 +426,9 @@ void DoCommandListDlg(){
GtkWidget* view = gtk_tree_view_new_with_model( GTK_TREE_MODEL( store ) );
dialog.m_list = GTK_TREE_VIEW( view );
gtk_tree_view_set_enable_search( GTK_TREE_VIEW( view ), false ); // annoying
//gtk_tree_view_set_enable_search( GTK_TREE_VIEW( view ), false ); // annoying
g_signal_connect( G_OBJECT( view ), "button_press_event", G_CALLBACK( accelerator_tree_butt_press ), &dialog );
{
GtkCellRenderer* renderer = gtk_cell_renderer_text_new();

View File

@ -49,6 +49,7 @@
#include <gtk/gtkscrolledwindow.h>
#include <gtk/gtkentry.h>
#include <gtk/gtkcombobox.h>
#include <gtk/gtkstock.h>
#include "os/path.h"
@ -78,6 +79,8 @@
#include "textureentry.h"
#include "groupdialog.h"
#include "select.h"
GtkEntry* numeric_entry_new(){
GtkEntry* entry = GTK_ENTRY( gtk_entry_new() );
gtk_widget_show( GTK_WIDGET( entry ) );
@ -778,6 +781,8 @@ GtkCheckButton* g_entitySpawnflagsCheck[MAX_FLAGS];
GtkEntry* g_entityKeyEntry;
GtkEntry* g_entityValueEntry;
GtkToggleButton* g_focusToggleButton;
GtkListStore* g_entlist_store;
GtkListStore* g_entprops_store;
const EntityClass* g_current_flags = 0;
@ -1411,6 +1416,21 @@ static gint EntityInspector_hideWindowKB( GtkWidget* widget, GdkEventKey* event,
return FALSE;
}
void EntityInspector_selectTargeting( GtkButton *button, gpointer user_data ){
bool focus = gtk_toggle_button_get_active( g_focusToggleButton );
Select_ConnectedEntities( true, false, focus );
}
void EntityInspector_selectTargets( GtkButton *button, gpointer user_data ){
bool focus = gtk_toggle_button_get_active( g_focusToggleButton );
Select_ConnectedEntities( false, true, focus );
}
void EntityInspector_selectConnected( GtkButton *button, gpointer user_data ){
bool focus = gtk_toggle_button_get_active( g_focusToggleButton );
Select_ConnectedEntities( true, true, focus );
}
GtkWidget* EntityInspector_constructWindow( GtkWindow* toplevel ){
GtkWidget* vbox = gtk_vbox_new( FALSE, 2 );
gtk_widget_show( vbox );
@ -1619,22 +1639,60 @@ GtkWidget* EntityInspector_constructWindow( GtkWindow* toplevel ){
}
{
GtkBox* hbox = GTK_BOX( gtk_hbox_new( TRUE, 4 ) );
GtkBox* hbox = GTK_BOX( gtk_hbox_new( FALSE, 4 ) );
gtk_widget_show( GTK_WIDGET( hbox ) );
gtk_box_pack_start( GTK_BOX( vbox2 ), GTK_WIDGET( hbox ), FALSE, TRUE, 0 );
{
GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "Clear All" ) );
GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_FOCUS );
gtk_widget_show( GTK_WIDGET( button ) );
g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_clearAllKeyValues ), 0 );
gtk_box_pack_start( hbox, GTK_WIDGET( button ), TRUE, TRUE, 0 );
}
{
GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "Delete Key" ) );
GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_FOCUS );
gtk_widget_show( GTK_WIDGET( button ) );
g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_clearKeyValue ), 0 );
gtk_box_pack_start( hbox, GTK_WIDGET( button ), TRUE, TRUE, 0 );
}
{
GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "<" ) );
gtk_widget_set_tooltip_text( GTK_WIDGET( button ), "Select targeting entities" );
GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_FOCUS );
gtk_widget_show( GTK_WIDGET( button ) );
g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_selectTargeting ), 0 );
gtk_box_pack_start( hbox, GTK_WIDGET( button ), FALSE, FALSE, 0 );
}
{
GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( ">" ) );
gtk_widget_set_tooltip_text( GTK_WIDGET( button ), "Select targets" );
GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_FOCUS );
gtk_widget_show( GTK_WIDGET( button ) );
g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_selectTargets ), 0 );
gtk_box_pack_start( hbox, GTK_WIDGET( button ), FALSE, FALSE, 0 );
}
{
GtkButton* button = GTK_BUTTON( gtk_button_new_with_label( "<->" ) );
gtk_widget_set_tooltip_text( GTK_WIDGET( button ), "Select connected entities" );
GTK_WIDGET_UNSET_FLAGS( GTK_WIDGET( button ), GTK_CAN_FOCUS );
gtk_widget_show( GTK_WIDGET( button ) );
g_signal_connect( G_OBJECT( button ), "clicked", G_CALLBACK( EntityInspector_selectConnected ), 0 );
gtk_box_pack_start( hbox, GTK_WIDGET( button ), FALSE, FALSE, 0 );
}
{
GtkWidget* button = gtk_toggle_button_new();
GtkImage* image = GTK_IMAGE( gtk_image_new_from_stock( GTK_STOCK_ZOOM_IN, GTK_ICON_SIZE_SMALL_TOOLBAR ) );
gtk_widget_show( GTK_WIDGET( image ) );
gtk_container_add( GTK_CONTAINER( button ), GTK_WIDGET( image ) );
gtk_button_set_relief( GTK_BUTTON( button ), GTK_RELIEF_NONE );
GTK_WIDGET_UNSET_FLAGS( button, GTK_CAN_FOCUS );
gtk_box_pack_start( hbox, button, FALSE, FALSE, 0 );
gtk_widget_set_tooltip_text( button, "Focus on Selected" );
gtk_widget_show( button );
g_focusToggleButton = GTK_TOGGLE_BUTTON( button );
}
}
}

View File

@ -27,6 +27,8 @@
#include <gtk/gtktreeview.h>
#include <gtk/gtktreeselection.h>
#include <gtk/gtkcellrenderertext.h>
#include <gtk/gtkcheckbutton.h>
#include <gtk/gtkvbox.h>
#include "string/string.h"
#include "scenelib.h"
@ -42,6 +44,8 @@
#include "treemodel.h"
#include "mainframe.h"
void RedrawEntityList();
typedef FreeCaller<RedrawEntityList> RedrawEntityListCaller;
@ -63,6 +67,7 @@ IdleDraw m_idleDraw;
WindowPositionTracker m_positionTracker;
GtkWindow* m_window;
GtkWidget* m_check;
GtkTreeView* m_tree_view;
GraphTreeModel* m_tree_model;
bool m_selection_disabled;
@ -157,6 +162,9 @@ static gboolean entitylist_tree_select( GtkTreeSelection *selection, GtkTreeMode
getEntityList().m_selection_disabled = true;
selectable->setSelected( path_currently_selected == FALSE );
getEntityList().m_selection_disabled = false;
if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( getEntityList().m_check ) ) ){
FocusAllViews();
}
return TRUE;
}
@ -295,8 +303,14 @@ void EntityList_constructWindow( GtkWindow* main_window ){
getEntityList().m_window = window;
{
GtkVBox* vbox = GTK_VBOX( gtk_vbox_new( FALSE, 0 ) );
gtk_container_set_border_width( GTK_CONTAINER( vbox ), 0 );
gtk_widget_show( GTK_WIDGET( vbox ) );
gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( vbox ) );
GtkScrolledWindow* scr = create_scrolled_window( GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC );
gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( scr ) );
//gtk_container_add( GTK_CONTAINER( window ), GTK_WIDGET( scr ) );
gtk_box_pack_start( GTK_BOX( vbox ), GTK_WIDGET( scr ), TRUE, TRUE, 0 );
{
GtkWidget* view = gtk_tree_view_new();
@ -319,6 +333,13 @@ void EntityList_constructWindow( GtkWindow* main_window ){
gtk_container_add( GTK_CONTAINER( scr ), view );
getEntityList().m_tree_view = GTK_TREE_VIEW( view );
}
{
GtkWidget* check = gtk_check_button_new_with_label( "Focus on Selected" );
gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( check ), FALSE );
gtk_widget_show( check );
gtk_box_pack_start( GTK_BOX( vbox ), check, FALSE, FALSE, 0 );
getEntityList().m_check = check;
}
}
EntityList_ConnectSignals( getEntityList().m_tree_view );

View File

@ -1163,6 +1163,12 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
&& selectable->isSelected() ) {
return false;
}
if( doMakeUnique && instance.childSelected() ){
NodeSmartReference clone( Node_Clone_Selected( path.top() ) );
Map_gatherNamespaced( clone );
Node_getTraversable( path.parent().get() )->insert( clone );
return false;
}
}
return true;
@ -1916,6 +1922,7 @@ GtkMenuItem* create_edit_menu(){
// }
create_menu_item_with_mnemonic( menu, "Select All Of Type", "SelectAllOfType" );
create_menu_item_with_mnemonic( menu, "_Expand Selection To Entities", "ExpandSelectionToEntities" );
create_menu_item_with_mnemonic( menu, "Select Connected Entities", "SelectConnectedEntities" );
menu_separator( menu );
create_menu_item_with_mnemonic( menu, "Pre_ferences...", "Preferences" );
@ -1994,6 +2001,7 @@ GtkMenuItem* create_view_menu( MainFrame::EViewStyle style ){
create_menu_item_with_mnemonic( orthographic_menu, "Center on Selected", "NextView" );
}
create_menu_item_with_mnemonic( orthographic_menu, "Focus on Selected", "XYFocusOnSelected" );
create_menu_item_with_mnemonic( orthographic_menu, "Center on Selected", "CenterXYView" );
menu_separator( orthographic_menu );
create_menu_item_with_mnemonic( orthographic_menu, "_XY 100%", "Zoom100" );
@ -3393,6 +3401,10 @@ void Maximize_View(){
g_maximizeview.toggle();
}
void FocusAllViews(){
XY_Centralize(); //using centralizing here, not focusing function
GlobalCamera_FocusOnSelected();
}
#include "preferencesystem.h"
#include "stringio.h"
@ -3431,6 +3443,7 @@ void MainFrame_Construct(){
GlobalCommands_insert( "SelectInside", FreeCaller<Select_Inside>() );
GlobalCommands_insert( "SelectTouching", FreeCaller<Select_Touching>() );
GlobalCommands_insert( "ExpandSelectionToEntities", FreeCaller<Scene_ExpandSelectionToEntities>(), Accelerator( 'E', (GdkModifierType)GDK_SHIFT_MASK ) );
GlobalCommands_insert( "SelectConnectedEntities", FreeCaller<SelectConnectedEntities>(), Accelerator( 'E', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
GlobalCommands_insert( "Preferences", FreeCaller<PreferencesDialog_showDialog>(), Accelerator( 'P' ) );
GlobalCommands_insert( "ToggleConsole", FreeCaller<Console_ToggleShow>(), Accelerator( 'O' ) );

View File

@ -277,4 +277,6 @@ void XYWindowMouseDown_disconnect( MouseEventHandlerId id );
extern GtkWidget* g_page_entity;
void FocusAllViews();
#endif

View File

@ -734,6 +734,50 @@ scene::Node& Node_Clone( scene::Node& node ){
return clone;
}
bool Node_instanceSelected( scene::Node& node );
class CloneAllSelected : public scene::Traversable::Walker
{
mutable scene::Path m_path;
public:
CloneAllSelected( scene::Node& root )
: m_path( makeReference( root ) ){
}
bool pre( scene::Node& node ) const {
if ( node.isRoot() ) {
return false;
}
if( Node_instanceSelected( node ) ){
m_path.push( makeReference( node_clone( node ) ) );
m_path.top().get().IncRef();
}
return true;
}
void post( scene::Node& node ) const {
if ( node.isRoot() ) {
return;
}
if( Node_instanceSelected( node ) ){
Node_getTraversable( m_path.parent() )->insert( m_path.top() );
m_path.top().get().DecRef();
m_path.pop();
}
}
};
scene::Node& Node_Clone_Selected( scene::Node& node ){
scene::Node& clone = node_clone( node );
scene::Traversable* traversable = Node_getTraversable( node );
if ( traversable != 0 ) {
traversable->traverse( CloneAllSelected( clone ) );
}
return clone;
}
typedef std::map<CopiedString, std::size_t> EntityBreakdown;

View File

@ -125,6 +125,7 @@ bool Map_Save();
bool Map_SaveAs();
scene::Node& Node_Clone( scene::Node& node );
scene::Node& Node_Clone_Selected( scene::Node& node );
void DoMapInfo();

View File

@ -841,8 +841,10 @@ void Patch_registerCommands(){
GlobalCommands_insert( "PatchDeleteFirstRow", FreeCaller<Patch_DeleteFirstRow>() );
GlobalCommands_insert( "PatchDeleteLastRow", FreeCaller<Patch_DeleteLastRow>(), Accelerator( GDK_KP_Subtract, (GdkModifierType)GDK_CONTROL_MASK ) );
GlobalCommands_insert( "InvertCurve", FreeCaller<Patch_Invert>(), Accelerator( 'I', (GdkModifierType)GDK_CONTROL_MASK ) );
GlobalCommands_insert( "RedisperseRows", FreeCaller<Patch_RedisperseRows>(), Accelerator( 'E', (GdkModifierType)GDK_CONTROL_MASK ) );
GlobalCommands_insert( "RedisperseCols", FreeCaller<Patch_RedisperseCols>(), Accelerator( 'E', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
//GlobalCommands_insert( "RedisperseRows", FreeCaller<Patch_RedisperseRows>(), Accelerator( 'E', (GdkModifierType)GDK_CONTROL_MASK ) );
GlobalCommands_insert( "RedisperseRows", FreeCaller<Patch_RedisperseRows>() );
//GlobalCommands_insert( "RedisperseCols", FreeCaller<Patch_RedisperseCols>(), Accelerator( 'E', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
GlobalCommands_insert( "RedisperseCols", FreeCaller<Patch_RedisperseCols>() );
GlobalCommands_insert( "SmoothRows", FreeCaller<Patch_SmoothRows>(), Accelerator( 'W', (GdkModifierType)GDK_CONTROL_MASK ) );
GlobalCommands_insert( "SmoothCols", FreeCaller<Patch_SmoothCols>(), Accelerator( 'W', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
GlobalCommands_insert( "MatrixTranspose", FreeCaller<Patch_Transpose>(), Accelerator( 'M', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );

View File

@ -463,6 +463,13 @@ void Select_SetShader( const char* shader ){
Scene_BrushSetShader_Component_Selected( GlobalSceneGraph(), shader );
}
void Select_SetShader_Undo( const char* shader ){
if ( GlobalSelectionSystem().countSelectedComponents() != 0 || GlobalSelectionSystem().countSelected() != 0 ) {
UndoableCommand undo( "textureNameSetSelected" );
Select_SetShader( shader );
}
}
void Select_SetTexdef( const TextureProjection& projection ){
if ( GlobalSelectionSystem().Mode() != SelectionSystem::eComponent ) {
Scene_BrushSetTexdef_Selected( GlobalSceneGraph(), projection );
@ -1390,3 +1397,79 @@ void DoScaleDlg(){
gtk_widget_show( GTK_WIDGET( g_scale_dialog.window ) );
}
class EntityGetSelectedPropertyValuesWalker_nonEmpty : public scene::Graph::Walker
{
PropertyValues& m_propertyvalues;
const char *m_prop;
const NodeSmartReference worldspawn;
public:
EntityGetSelectedPropertyValuesWalker_nonEmpty( const char *prop, PropertyValues& propertyvalues )
: m_propertyvalues( propertyvalues ), m_prop( prop ), worldspawn( Map_FindOrInsertWorldspawn( g_map ) ){
}
bool pre( const scene::Path& path, scene::Instance& instance ) const {
Entity* entity = Node_getEntity( path.top() );
if ( entity != 0 ){
if( path.top().get() != worldspawn ){
Selectable* selectable = Instance_getSelectable( instance );
if ( ( selectable != 0 && selectable->isSelected() ) || instance.childSelected() ) {
const char* keyvalue = entity->getKeyValue( m_prop );
if ( !string_empty( keyvalue ) && !propertyvalues_contain( m_propertyvalues, keyvalue ) ) {
m_propertyvalues.push_back( keyvalue );
}
}
}
return false;
}
return true;
}
};
void Scene_EntityGetPropertyValues_nonEmpty( scene::Graph& graph, const char *prop, PropertyValues& propertyvalues ){
graph.traverse( EntityGetSelectedPropertyValuesWalker_nonEmpty( prop, propertyvalues ) );
}
#include "preferences.h"
void Select_ConnectedEntities( bool targeting, bool targets, bool focus ){
PropertyValues target_propertyvalues;
PropertyValues targetname_propertyvalues;
const char *target_prop = "target";
const char *targetname_prop;
if ( g_pGameDescription->mGameType == "doom3" ) {
targetname_prop = "name";
}
else{
targetname_prop = "targetname";
}
if( targeting ){
Scene_EntityGetPropertyValues_nonEmpty( GlobalSceneGraph(), targetname_prop, targetname_propertyvalues );
}
if( targets ){
Scene_EntityGetPropertyValues_nonEmpty( GlobalSceneGraph(), target_prop, target_propertyvalues );
}
if( target_propertyvalues.empty() && targetname_propertyvalues.empty() ){
globalErrorStream() << "SelectConnectedEntities: nothing found\n";
return;
}
if( !targeting || !targets ){
GlobalSelectionSystem().setSelectedAll( false );
}
if ( targeting && !targetname_propertyvalues.empty() ) {
Scene_EntitySelectByPropertyValues( GlobalSceneGraph(), target_prop, targetname_propertyvalues );
}
if ( targets && !target_propertyvalues.empty() ) {
Scene_EntitySelectByPropertyValues( GlobalSceneGraph(), targetname_prop, target_propertyvalues );
}
if( focus ){
FocusAllViews();
}
}
void SelectConnectedEntities(){
Select_ConnectedEntities( true, true, false );
}

View File

@ -46,11 +46,15 @@ void Selection_MoveUp();
void Select_AllOfType();
void Select_ConnectedEntities( bool targeting, bool targets, bool focus );
void SelectConnectedEntities();
void DoRotateDlg();
void DoScaleDlg();
void Select_SetShader( const char* shader );
void Select_SetShader_Undo( const char* shader );
class TextureProjection;
void Select_SetTexdef( const TextureProjection& projection );

View File

@ -1889,12 +1889,12 @@ bool Scene_forEachPlaneSelectable_selectPlanes( scene::Graph& graph, Selector& s
#include "brush.h"
/*
class TestedBrushPlanesSelectVeritces : public scene::Graph::Walker
class TestedBrushFacesSelectVeritces : public scene::Graph::Walker
{
SelectionTest& m_test;
public:
TestedBrushPlanesSelectVeritces( SelectionTest& test )
TestedBrushFacesSelectVeritces( SelectionTest& test )
: m_test( test ){
}
bool pre( const scene::Path& path, scene::Instance& instance ) const {
@ -1903,7 +1903,7 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
if ( selectable != 0 && selectable->isSelected() ) {
BrushInstance* brushInstance = Instance_getBrush( instance );
if ( brushInstance != 0 ) {
brushInstance->selectVerticesOnPlanes( m_test );
brushInstance->selectVerticesOnTestedFaces( m_test );
}
}
}
@ -1911,10 +1911,10 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
}
};
void Scene_forEachTestedBrushPlane_selectVertices( scene::Graph& graph, SelectionTest& test ){
graph.traverse( TestedBrushPlanesSelectVeritces( test ) );
void Scene_forEachTestedBrushFace_selectVertices( scene::Graph& graph, SelectionTest& test ){
graph.traverse( TestedBrushFacesSelectVeritces( test ) );
}
*/
class BrushPlanesSelectVeritces : public scene::Graph::Walker
{
SelectionTest& m_test;
@ -2683,8 +2683,8 @@ void testSelect( const View& view, const Matrix4& pivot2world ){
m_dragSelectable.setSelected( false );
}
if( deepSelector.best().empty() ){
//Scene_forEachTestedBrushPlane_selectVertices( GlobalSceneGraph(), test ); //todo? drag clicked face
Scene_forEachBrushPlane_selectVertices( GlobalSceneGraph(), test );
Scene_forEachTestedBrushFace_selectVertices( GlobalSceneGraph(), test ); //drag clicked face
//Scene_forEachBrushPlane_selectVertices( GlobalSceneGraph(), test );
m_selected = true;
}
}

View File

@ -974,16 +974,15 @@ IShader* Texture_At( TextureBrowser& textureBrowser, int mx, int my ){
By mouse click
==============
*/
void SelectTexture( TextureBrowser& textureBrowser, int mx, int my, guint32 flags ){
void SelectTexture( TextureBrowser& textureBrowser, int mx, int my, guint32 flags, bool texturizeSelection ){
if ( ( flags & GDK_SHIFT_MASK ) == 0 ) {
IShader* shader = Texture_At( textureBrowser, mx, my );
if ( shader != 0 ) {
TextureBrowser_SetSelectedShader( textureBrowser, shader->getName() );
TextureBrowser_textureSelected( shader->getName() );
if ( !FindTextureDialog_isOpen() && !textureBrowser.m_rmbSelected ) {
UndoableCommand undo( "textureNameSetSelected" );
Select_SetShader( shader->getName() );
if ( !FindTextureDialog_isOpen() && !textureBrowser.m_rmbSelected && !texturizeSelection ) {
Select_SetShader_Undo( shader->getName() );
}
}
}
@ -1025,8 +1024,8 @@ void TextureBrowser_Tracking_MouseDown( TextureBrowser& textureBrowser ){
textureBrowser.m_freezePointer.freeze_pointer( textureBrowser.m_parent, textureBrowser.m_gl_widget, TextureBrowser_trackingDelta, &textureBrowser );
}
void TextureBrowser_Selection_MouseDown( TextureBrowser& textureBrowser, guint32 flags, int pointx, int pointy ){
SelectTexture( textureBrowser, pointx, textureBrowser.height - 1 - pointy, flags );
void TextureBrowser_Selection_MouseDown( TextureBrowser& textureBrowser, guint32 flags, int pointx, int pointy, bool texturizeSelection ){
SelectTexture( textureBrowser, pointx, textureBrowser.height - 1 - pointy, flags, texturizeSelection );
}
void TextureBrowser_Selection_MouseUp( TextureBrowser& textureBrowser, guint32 flags, int pointx, int pointy ){
@ -1382,7 +1381,7 @@ gboolean TextureBrowser_button_press( GtkWidget* widget, GdkEventButton* event,
if ( event->button == 3 ) {
if ( GlobalTextureBrowser().m_tags ) {
textureBrowser->m_rmbSelected = true;
TextureBrowser_Selection_MouseDown( *textureBrowser, event->state, static_cast<int>( event->x ), static_cast<int>( event->y ) );
TextureBrowser_Selection_MouseDown( *textureBrowser, event->state, static_cast<int>( event->x ), static_cast<int>( event->y ), false );
BuildStoreAssignedTags( textureBrowser->m_assigned_store, textureBrowser->shader.c_str(), textureBrowser );
BuildStoreAvailableTags( textureBrowser->m_available_store, textureBrowser->m_assigned_store, textureBrowser->m_all_tags, textureBrowser );
@ -1398,8 +1397,8 @@ gboolean TextureBrowser_button_press( GtkWidget* widget, GdkEventButton* event,
TextureBrowser_Tracking_MouseDown( *textureBrowser );
}
}
else if ( event->button == 1 ) {
TextureBrowser_Selection_MouseDown( *textureBrowser, event->state, static_cast<int>( event->x ), static_cast<int>( event->y ) );
else if ( event->button == 1 || event->button == 2 ) {
TextureBrowser_Selection_MouseDown( *textureBrowser, event->state, static_cast<int>( event->x ), static_cast<int>( event->y ), event->button == 2 );
if ( GlobalTextureBrowser().m_tags ) {
textureBrowser->m_rmbSelected = false;
@ -1409,7 +1408,6 @@ gboolean TextureBrowser_button_press( GtkWidget* widget, GdkEventButton* event,
}
else if ( event->type == GDK_2BUTTON_PRESS && event->button == 1 ) {
CopiedString texName = textureBrowser->shader;
//const char* sh = texName.c_str();
char* sh = const_cast<char*>( texName.c_str() );
char* dir = strrchr( sh, '/' );
if( dir != NULL ){
@ -1966,6 +1964,7 @@ void TextureBrowser_searchTags(){
TextureDirectory_loadTexture( path.c_str(), name.c_str() );
}
}
TextureBrowser_SetHideUnused( g_TextureBrowser, false );
g_TextureBrowser.m_searchedTags = true;
g_TextureBrowser_currentDirectory = tags_searched;

View File

@ -550,6 +550,20 @@ void XYWnd::ZoomInWithMouse( int pointx, int pointy ){
}
}
void XYWnd::FocusOnBounds( AABB& bounds ){
SetOrigin( bounds.origin );
int nDim1 = ( m_viewType == YZ ) ? 1 : 0;
int nDim2 = ( m_viewType == XY ) ? 1 : 2;
if( bounds.extents[ nDim1 ] < 128.f )
bounds.extents[ nDim1 ] = 128.f;
if( bounds.extents[ nDim2 ] < 128.f )
bounds.extents[ nDim2 ] = 128.f;
float scale1 = Width() / ( 3.f * bounds.extents[ nDim1 ] );
float scale2 = Height() / ( 3.f * bounds.extents[ nDim2 ] );
SetScale( MIN( scale1, scale2 ) );
}
VIEWTYPE GlobalXYWnd_getCurrentViewType(){
ASSERT_NOTNULL( g_pParentWnd );
ASSERT_NOTNULL( g_pParentWnd->ActiveXY() );
@ -2703,7 +2717,7 @@ void XYWnd::OnEntityCreate( const char* item ){
void GetFocusPosition( Vector3& position ){
void GetCenterPosition( Vector3& position ){
if ( GlobalSelectionSystem().countSelected() != 0 ) {
Select_GetMid( position );
}
@ -2713,15 +2727,15 @@ void GetFocusPosition( Vector3& position ){
}
}
void XYWnd_Focus( XYWnd* xywnd ){
void XYWnd_Centralize( XYWnd* xywnd ){
Vector3 position;
GetFocusPosition( position );
GetCenterPosition( position );
xywnd->PositionView( position );
}
void XY_Split_Focus(){
void XY_Split_Centralize(){
Vector3 position;
GetFocusPosition( position );
GetCenterPosition( position );
if ( g_pParentWnd->GetXYWnd() ) {
g_pParentWnd->GetXYWnd()->PositionView( position );
}
@ -2733,10 +2747,52 @@ void XY_Split_Focus(){
}
}
void XY_Centralize(){
if ( g_pParentWnd->CurrentStyle() == MainFrame::eSplit || g_pParentWnd->CurrentStyle() == MainFrame::eFloating ) {
// centralize all
XY_Split_Centralize();
return;
}
XYWnd* xywnd = g_pParentWnd->GetXYWnd();
XYWnd_Centralize( xywnd );
}
void GetSelectionBbox( AABB& bounds ){
if ( GlobalSelectionSystem().countSelected() != 0 ) {
Scene_BoundsSelected( GlobalSceneGraph(), bounds );
}
else
{
bounds = AABB( Camera_getOrigin( *g_pParentWnd->GetCamWnd() ), Vector3( 128.f, 128.f, 128.f ) );
}
}
void XYWnd_Focus( XYWnd* xywnd ){
AABB bounds;
GetSelectionBbox( bounds );
xywnd->FocusOnBounds( bounds );
}
void XY_Split_Focus(){
AABB bounds;
GetSelectionBbox( bounds );
if ( g_pParentWnd->GetXYWnd() ) {
g_pParentWnd->GetXYWnd()->FocusOnBounds( bounds );
}
if ( g_pParentWnd->GetXZWnd() ) {
g_pParentWnd->GetXZWnd()->FocusOnBounds( bounds );
}
if ( g_pParentWnd->GetYZWnd() ) {
g_pParentWnd->GetYZWnd()->FocusOnBounds( bounds );
}
}
void XY_Focus(){
if ( g_pParentWnd->CurrentStyle() == MainFrame::eSplit || g_pParentWnd->CurrentStyle() == MainFrame::eFloating ) {
// cannot do this in a split window
// do something else that the user may want here
// focus all
XY_Split_Focus();
return;
}
@ -2745,16 +2801,18 @@ void XY_Focus(){
XYWnd_Focus( xywnd );
}
void XY_TopFrontSide( VIEWTYPE viewtype ){
if ( g_pParentWnd->CurrentStyle() == MainFrame::eSplit ) {
// cannot do this in a split window
// do something else that the user may want here
XY_Split_Focus();
XY_Split_Centralize();
return;
}
XYWnd* xywnd = g_pParentWnd->CurrentStyle() == MainFrame::eFloating ? g_pParentWnd->ActiveXY() : g_pParentWnd->GetXYWnd();
xywnd->SetViewType( viewtype );
XYWnd_Focus( xywnd );
XYWnd_Centralize( xywnd );
}
void XY_Top(){
@ -2779,14 +2837,14 @@ void XY_NextView( XYWnd* xywnd ){
else{
xywnd->SetViewType( XY );
}
XYWnd_Focus( xywnd );
XYWnd_Centralize( xywnd );
}
void XY_Next(){
if ( g_pParentWnd->CurrentStyle() == MainFrame::eSplit ) {
// cannot do this in a split window
// do something else that the user may want here
XY_Split_Focus();
XY_Split_Centralize();
return;
}
XYWnd* xywnd = g_pParentWnd->CurrentStyle() == MainFrame::eFloating ? g_pParentWnd->ActiveXY() : g_pParentWnd->GetXYWnd();
@ -3070,7 +3128,8 @@ void XYWindow_Construct(){
GlobalCommands_insert( "ViewSide", FreeCaller<XY_Side>(), Accelerator( GDK_KP_Page_Down ) );
GlobalCommands_insert( "ViewFront", FreeCaller<XY_Front>(), Accelerator( GDK_KP_End ) );
GlobalCommands_insert( "Zoom100", FreeCaller<XY_Zoom100>() );
GlobalCommands_insert( "CenterXYView", FreeCaller<XY_Focus>(), Accelerator( GDK_Tab, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
GlobalCommands_insert( "CenterXYView", FreeCaller<XY_Centralize>(), Accelerator( GDK_Tab, (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) );
GlobalCommands_insert( "XYFocusOnSelected", FreeCaller<XY_Focus>(), Accelerator( GDK_grave ) );
GlobalPreferenceSystem().registerPreference( "ClipCaulk", BoolImportStringCaller( g_clip_useCaulk ), BoolExportStringCaller( g_clip_useCaulk ) );

View File

@ -129,6 +129,7 @@ guint m_zoom_focusOut;
void ZoomIn();
void ZoomOut();
void ZoomInWithMouse( int pointx, int pointy );
void FocusOnBounds( AABB& bounds );
void RenderActive();
void SetActive( bool b ){
@ -251,6 +252,7 @@ inline void XYWnd_Update( XYWnd& xywnd ){
xywnd.queueDraw();
}
void XY_Centralize();
struct xywindow_globals_t
{