binds...
	* ctrl + e: ExpandSelectionToPrimitives (select group entities w/o parent node)
	* ctrl + m3 texture painting by drag
misc...
	* fix: QNAN texture projection after scaling cuboid on Z axis (brush primitives + texture lock)
	* preferences->display->entities->Names Display Distance (in cam) def = 512u
	* always show selected/childSelected entity names (unselected is optional)
	* fix: mouse texture grab/paint commands ignore filtered faces (caulk filter)
This commit is contained in:
Garux 2017-08-02 09:39:45 +03:00
parent 62ccd942e5
commit 697d2714d6
18 changed files with 177 additions and 27 deletions

View File

@ -126,6 +126,8 @@ virtual void setLightRadii( bool lightRadii ) = 0;
virtual bool getLightRadii() = 0;
virtual void setShowNames( bool showNames ) = 0;
virtual bool getShowNames() = 0;
virtual void setShowNamesDist( int dist ) = 0;
virtual int getShowNamesDist() = 0;
virtual void setShowTargetNames( bool showNames ) = 0;
virtual bool getShowTargetNames() = 0;
virtual void setShowAngles( bool showAngles ) = 0;

View File

@ -363,7 +363,7 @@ void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& l
renderer.addRenderable( m_curveCatmullRom.m_renderCurve, localToWorld );
}
if ( g_showNames ) {
if ( g_showNames || selected || childSelected ) {
// draw models as usual
if ( !isModel() ) {
// don't draw the name for worldspawn

View File

@ -253,7 +253,7 @@ void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& l
renderer.PopState();
}
renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly );
if ( g_showNames ) {
if ( g_showNames || selected ) {
m_renderName.render( renderer, volume, localToWorld, selected );
}
}

View File

@ -113,6 +113,7 @@ EntityCreator::KeyValueChangedFunc KeyValue::m_entityKeyValueChanged = 0;
Counter* EntityKeyValues::m_counter = 0;
bool g_showNames = true;
int g_showNamesDist = 512;
bool g_showTargetNames = false;
bool g_showAngles = true;
bool g_lightRadii = true;
@ -266,6 +267,12 @@ void setShowNames( bool showNames ){
bool getShowNames(){
return g_showNames;
}
void setShowNamesDist( int dist ){
g_showNamesDist = dist;
}
int getShowNamesDist(){
return g_showNamesDist;
}
void setShowTargetNames( bool showNames ){
g_showTargetNames = showNames;
}
@ -376,6 +383,7 @@ void Entity_Construct( EGameType gameType ){
}
GlobalPreferenceSystem().registerPreference( "SI_ShowNames", BoolImportStringCaller( g_showNames ), BoolExportStringCaller( g_showNames ) );
GlobalPreferenceSystem().registerPreference( "SI_ShowNamesDist", IntImportStringCaller( g_showNamesDist ), IntExportStringCaller( g_showNamesDist ) );
GlobalPreferenceSystem().registerPreference( "SI_ShowTargetNames", BoolImportStringCaller( g_showTargetNames ), BoolExportStringCaller( g_showTargetNames ) );
GlobalPreferenceSystem().registerPreference( "SI_ShowAngles", BoolImportStringCaller( g_showAngles ), BoolExportStringCaller( g_showAngles ) );
GlobalPreferenceSystem().registerPreference( "LightRadiuses", BoolImportStringCaller( g_lightRadii ), BoolExportStringCaller( g_lightRadii ) );

View File

@ -39,6 +39,7 @@ void Entity_Construct( EGameType gameType = eGameTypeQuake3 );
void Entity_Destroy();
extern bool g_showNames;
extern int g_showNamesDist;
extern bool g_showTargetNames;
extern bool g_showAngles;
extern bool g_lightRadii;

View File

@ -219,7 +219,7 @@ void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& l
renderer.SetState( m_entity.getEntityClass().m_state_fill, Renderer::eFullMaterials );
renderer.addRenderable( m_aabb_solid, localToWorld );
renderArrow( renderer, volume, localToWorld );
if ( g_showNames ) {
if ( g_showNames || selected ) {
m_renderName.render( renderer, volume, localToWorld, selected );
}
}
@ -227,7 +227,7 @@ void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix
renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly );
renderer.addRenderable( m_aabb_wire, localToWorld );
renderArrow( renderer, volume, localToWorld );
if ( g_showNames ) {
if ( g_showNames || selected ) {
m_renderName.render( renderer, volume, localToWorld, selected );
}
}

View File

@ -150,7 +150,7 @@ void detach( scene::Traversable::Observer* observer ){
void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld, bool selected, bool childSelected, const AABB& childBounds ) const {
renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly );
if ( g_showNames ) {
if ( g_showNames || selected || childSelected ) {
// don't draw the name for worldspawn
if ( !strcmp( m_entity.getEntityClass().name(), "worldspawn" ) ) {
return;

View File

@ -1460,7 +1460,7 @@ void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& l
}
}
if ( g_showNames && !string_equal( m_named.name(), "light" ) ) {
if ( ( g_showNames || selected ) && !string_equal( m_named.name(), "light" ) ) {
m_renderName.render( renderer, volume, localToWorld, selected );
}
}

View File

@ -195,7 +195,7 @@ void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& l
m_renderOrigin.render( renderer, volume, localToWorld );
}
renderer.SetState( m_entity.getEntityClass().m_state_wire, Renderer::eWireframeOnly );
if ( g_showNames && !string_equal( m_named.name(), "misc_model" ) ) {
if ( ( g_showNames || selected ) && !string_equal( m_named.name(), "misc_model" ) ) {
m_renderName.render( renderer, volume, localToWorld, selected );
}
}

View File

@ -181,7 +181,7 @@ public:
Matrix4 viewproj = matrix4_multiplied_by_matrix4( volume.GetProjection(), volume.GetModelview() );
Vector3 viewer = vector4_to_vector3( viewer_from_viewproj( viewproj ) );
Vector3 pos_in_world = matrix4_transformed_point( localToWorld, m_position );
if( vector3_length_squared( pos_in_world - viewer ) > 512*512 ){
if( vector3_length_squared( pos_in_world - viewer ) > g_showNamesDist * g_showNamesDist ){
return;
}
//globalOutputStream() << viewer[0] << " " << viewer[1] << " " << viewer[2] << " Viewer\n";

View File

@ -1345,6 +1345,9 @@ void Texdef_transformLocked( TextureProjection& projection, std::size_t width, s
identity2stOriginal = matrix4_multiplied_by_matrix4( identity2stOriginal, identityCorrected );
}
else if( dot != dot ){ //catch QNAN: happens on scaling cuboid on Z and sometimes on rotating
return;
}
Matrix4 stTransformed2stOriginal = matrix4_multiplied_by_matrix4( identity2stOriginal, stTransformed2identity );

View File

@ -576,6 +576,24 @@ void Entity_constructPreferences( PreferencesPage& page ){
LightRadiiExportCaller( GlobalEntityCreator() )
);
}
*/
void ShowNamesDistImport( EntityCreator& self, int value ){
self.setShowNamesDist( value );
UpdateAllWindows();
}
typedef ReferenceCaller1<EntityCreator, int, ShowNamesDistImport> ShowNamesDistImportCaller;
void ShowNamesDistExport( EntityCreator& self, const IntImportCallback& importer ){
importer( self.getShowNamesDist() );
}
typedef ReferenceCaller1<EntityCreator, const IntImportCallback&, ShowNamesDistExport> ShowNamesDistExportCaller;
void Entity_constructPreferences( PreferencesPage& page ){
page.appendSpinner( "Names Display Distance", 512.0, 0.0, 200500.0,
IntImportCallback( ShowNamesDistImportCaller( GlobalEntityCreator() ) ),
IntExportCallback( ShowNamesDistExportCaller( GlobalEntityCreator() ) )
);
}
void Entity_constructPage( PreferenceGroup& group ){
PreferencesPage page( group.createPage( "Entities", "Entity Display Preferences" ) );
Entity_constructPreferences( page );
@ -583,7 +601,7 @@ void Entity_constructPage( PreferenceGroup& group ){
void Entity_registerPreferencesPage(){
PreferencesDialog_addDisplayPage( FreeCaller1<PreferenceGroup&, Entity_constructPage>() );
}
*/
void ShowLightRadiiExport( const BoolImportCallback& importer ){
importer( GlobalEntityCreator().getLightRadii() );
@ -626,7 +644,7 @@ void Entity_Construct(){
GlobalPreferenceSystem().registerPreference( "SI_Colors5", Vector3ImportStringCaller( g_entity_globals.color_entity ), Vector3ExportStringCaller( g_entity_globals.color_entity ) );
GlobalPreferenceSystem().registerPreference( "LastLightIntensity", IntImportStringCaller( g_iLastLightIntensity ), IntExportStringCaller( g_iLastLightIntensity ) );
// Entity_registerPreferencesPage();
Entity_registerPreferencesPage();
}
void Entity_Destroy(){

View File

@ -1937,6 +1937,7 @@ GtkMenuItem* create_edit_menu(){
// menu_tearoff( convert_menu );
// }
create_menu_item_with_mnemonic( menu, "Select All Of Type", "SelectAllOfType" );
create_menu_item_with_mnemonic( menu, "_Expand Selection To Primitives", "ExpandSelectionToPrimitives" );
create_menu_item_with_mnemonic( menu, "_Expand Selection To Entities", "ExpandSelectionToEntities" );
create_menu_item_with_mnemonic( menu, "Select Connected Entities", "SelectConnectedEntities" );
@ -3478,6 +3479,7 @@ void MainFrame_Construct(){
GlobalCommands_insert( "InvertSelection", FreeCaller<Select_Invert>(), Accelerator( 'I' ) );
GlobalCommands_insert( "SelectInside", FreeCaller<Select_Inside>() );
GlobalCommands_insert( "SelectTouching", FreeCaller<Select_Touching>() );
GlobalCommands_insert( "ExpandSelectionToPrimitives", FreeCaller<Scene_ExpandSelectionToPrimitives>(), Accelerator( 'E', (GdkModifierType)GDK_CONTROL_MASK ) );
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' ) );

View File

@ -384,6 +384,50 @@ void post( const scene::Path& path, scene::Instance& instance ) const {
}
};
class ExpandSelectionToPrimitivesWalker : public scene::Graph::Walker
{
mutable std::size_t m_depth;
NodeSmartReference worldspawn;
public:
ExpandSelectionToPrimitivesWalker() : m_depth( 0 ), worldspawn( Map_FindOrInsertWorldspawn( g_map ) ){
}
bool pre( const scene::Path& path, scene::Instance& instance ) const {
++m_depth;
if( !path.top().get().visible() )
return false;
// ignore worldspawn
// NodeSmartReference me( path.top().get() );
// if ( me == worldspawn ) {
// return false;
// }
if ( m_depth == 2 ) { // entity depth
// traverse and select children if any one is selected
bool beselected = false;
const bool isContainer = Node_getEntity( path.top() )->isContainer();
if ( instance.childSelected() || instance.isSelected() ) {
beselected = true;
Instance_setSelected( instance, !isContainer );
}
return isContainer && beselected;
}
else if ( m_depth == 3 ) { // primitive depth
Instance_setSelected( instance, true );
return false;
}
return true;
}
void post( const scene::Path& path, scene::Instance& instance ) const {
--m_depth;
}
};
void Scene_ExpandSelectionToPrimitives(){
GlobalSceneGraph().traverse( ExpandSelectionToPrimitivesWalker() );
}
class ExpandSelectionToEntitiesWalker : public scene::Graph::Walker
{
mutable std::size_t m_depth;

View File

@ -31,6 +31,7 @@ void Select_Delete();
void Select_Invert();
void Select_Inside();
void Select_Touching();
void Scene_ExpandSelectionToPrimitives();
void Scene_ExpandSelectionToEntities();
//void Selection_Flipx();

View File

@ -4072,6 +4072,75 @@ const ModifierFlags c_modifier_apply_texture2 = c_modifierControl;
const ModifierFlags c_modifier_apply_texture3 = c_modifierShift;
const ModifierFlags c_modifier_copy_texture = c_modifierNone;
void Scene_copyClosestTexture( SelectionTest& test );
void Scene_applyClosestTexture( SelectionTest& test );
class TexManipulator_
{
public:
DeviceVector m_epsilon;
const View* m_view;
ModifierFlags m_state;
bool m_undo_begun;
TexManipulator_() : m_state( c_modifierNone ), m_undo_begun( false ){
}
void mouseDown( DeviceVector position ){
View scissored( *m_view );
ConstructSelectionTest( scissored, SelectionBoxForPoint( &position[0], &m_epsilon[0] ) );
SelectionVolume volume( scissored );
if ( m_state == c_modifier_apply_texture1 || m_state == c_modifier_apply_texture2 || m_state == c_modifier_apply_texture3 ) {
m_undo_begun = true;
GlobalUndoSystem().start();
Scene_applyClosestTexture( volume );
}
else if ( m_state == c_modifier_copy_texture ) {
Scene_copyClosestTexture( volume );
}
}
void mouseMoved( DeviceVector position ){
if( m_undo_begun ){
View scissored( *m_view );
ConstructSelectionTest( scissored, SelectionBoxForPoint( &device_constrained( position )[0], &m_epsilon[0] ) );
SelectionVolume volume( scissored );
Scene_applyClosestTexture( volume );
}
}
typedef MemberCaller1<TexManipulator_, DeviceVector, &TexManipulator_::mouseMoved> MouseMovedCaller;
void mouseUp( DeviceVector position ){
if( m_undo_begun ){
GlobalUndoSystem().finish( "paintTexture" );
m_undo_begun = false;
}
g_mouseMovedCallback.clear();
g_mouseUpCallback.clear();
}
typedef MemberCaller1<TexManipulator_, DeviceVector, &TexManipulator_::mouseUp> MouseUpCaller;
void setState( ModifierFlags state ){
m_state = state;
}
ModifierFlags getState() const {
return m_state;
}
void modifierEnable( ModifierFlags type ){
setState( bitfield_enable( getState(), type ) );
}
void modifierDisable( ModifierFlags type ){
setState( bitfield_disable( getState(), type ) );
}
};
class Selector_
{
RadiantSelectionSystem::EModifier modifier_for_state( ModifierFlags state ){
@ -4253,8 +4322,7 @@ void modifierDisable( ModifierFlags type ){
}
};
void Scene_copyClosestTexture( SelectionTest& test );
void Scene_applyClosestTexture( SelectionTest& test );
class RadiantWindowObserver : public SelectionSystemWindowObserver
{
@ -4271,6 +4339,7 @@ bool m_mouse_down;
public:
Selector_ m_selector;
Manipulator_ m_manipulator;
TexManipulator_ m_texmanipulator;
RadiantWindowObserver() : m_mouse_down( false ){
}
@ -4280,6 +4349,7 @@ void release(){
void setView( const View& view ){
m_selector.m_view = &view;
m_manipulator.m_view = &view;
m_texmanipulator.m_view = &view;
}
void setRectangleDrawCallback( const RectangleCallback& callback ){
m_selector.m_window_update = callback;
@ -4288,7 +4358,7 @@ void onSizeChanged( int width, int height ){
m_width = width;
m_height = height;
DeviceVector epsilon( SELECT_EPSILON / static_cast<float>( m_width ), SELECT_EPSILON / static_cast<float>( m_height ) );
m_selector.m_epsilon = m_manipulator.m_epsilon = epsilon;
m_selector.m_epsilon = m_manipulator.m_epsilon = m_texmanipulator.m_epsilon = epsilon;
}
void onMouseDown( const WindowVector& position, ButtonIdentifier button, ModifierFlags modifiers ){
if ( button == c_button_select || ( button == c_button_select2 && modifiers != c_modifierNone ) ) {
@ -4310,18 +4380,14 @@ void onMouseDown( const WindowVector& position, ButtonIdentifier button, Modifie
}
}
else if ( button == c_button_texture ) {
m_mouse_down = true;
DeviceVector devicePosition( device_constrained( window_to_normalised_device( position, m_width, m_height ) ) );
View scissored( *m_selector.m_view );
ConstructSelectionTest( scissored, SelectionBoxForPoint( &devicePosition[0], &m_selector.m_epsilon[0] ) );
SelectionVolume volume( scissored );
m_texmanipulator.mouseDown( devicePosition );
g_mouseMovedCallback.insert( MouseEventCallback( TexManipulator_::MouseMovedCaller( m_texmanipulator ) ) );
g_mouseUpCallback.insert( MouseEventCallback( TexManipulator_::MouseUpCaller( m_texmanipulator ) ) );
if ( modifiers == c_modifier_apply_texture1 || modifiers == c_modifier_apply_texture2 || modifiers == c_modifier_apply_texture3 ) {
Scene_applyClosestTexture( volume );
}
else if ( modifiers == c_modifier_copy_texture ) {
Scene_copyClosestTexture( volume );
}
}
}
void onMouseMotion( const WindowVector& position, ModifierFlags modifiers ){
@ -4332,7 +4398,7 @@ void onMouseMotion( const WindowVector& position, ModifierFlags modifiers ){
}
}
void onMouseUp( const WindowVector& position, ButtonIdentifier button, ModifierFlags modifiers ){
if ( ( button == c_button_select || button == c_button_select2 ) && !g_mouseUpCallback.empty() ) {
if ( ( button == c_button_select || button == c_button_select2 || button == c_button_texture ) && !g_mouseUpCallback.empty() ) {
m_mouse_down = false;
g_mouseUpCallback.get() ( window_to_normalised_device( position, m_width, m_height ) );
@ -4352,10 +4418,12 @@ void onMouseUp( const WindowVector& position, ButtonIdentifier button, ModifierF
void onModifierDown( ModifierFlags type ){
m_selector.modifierEnable( type );
m_manipulator.modifierEnable( type );
m_texmanipulator.modifierEnable( type );
}
void onModifierUp( ModifierFlags type ){
m_selector.modifierDisable( type );
m_manipulator.modifierDisable( type );
m_texmanipulator.modifierDisable( type );
}
};

View File

@ -1321,6 +1321,9 @@ struct Texturable
void Face_getClosest( Face& face, SelectionTest& test, SelectionIntersection& bestIntersection, Texturable& texturable ){
if ( face.isFiltered() ) {
return;
}
SelectionIntersection intersection;
face.testSelect( test, intersection );
if ( intersection.valid()
@ -1453,11 +1456,11 @@ void Scene_copyClosestTexture( SelectionTest& test ){
}
void Scene_applyClosestTexture( SelectionTest& test ){
UndoableCommand command( "facePaintTexture" );
// UndoableCommand command( "facePaintTexture" );
Scene_setClosestTexture( GlobalSceneGraph(), test, TextureBrowser_GetSelectedShader( g_TextureBrowser ), g_faceTextureClipboard.m_projection, g_faceTextureClipboard.m_flags );
SceneChangeNotify();
//SceneChangeNotify();
}

View File

@ -3038,7 +3038,7 @@ ToggleItem g_show_names( g_show_names_caller );
void ShowNamesToggle(){
GlobalEntityCreator().setShowNames( !GlobalEntityCreator().getShowNames() );
g_show_names.update();
XY_UpdateAllWindows();
UpdateAllWindows();
}
void ShowTargetNamesExport( const BoolImportCallback& importer ){
@ -3062,7 +3062,7 @@ ToggleItem g_show_angles( g_show_angles_caller );
void ShowAnglesToggle(){
GlobalEntityCreator().setShowAngles( !GlobalEntityCreator().getShowAngles() );
g_show_angles.update();
XY_UpdateAllWindows();
UpdateAllWindows();
}
BoolExportCaller g_show_blocks_caller( g_xywindow_globals_private.show_blocks );