* brush creation in camera; alt = modify height

This commit is contained in:
Garux 2018-04-06 12:26:06 +03:00
parent b078ec3ad0
commit 48d75b777d
8 changed files with 257 additions and 212 deletions

View File

@ -125,18 +125,8 @@ void selectPlanes( const AABB& aabb, Selector& selector, SelectionTest& test, co
for ( std::size_t i = 0; i < 6; ++i ){ for ( std::size_t i = 0; i < 6; ++i ){
const std::size_t index = i * 4; const std::size_t index = i * 4;
const Vector3 centroid = vector3_mid( corners[indices[index]], corners[indices[index + 2]] ); const Vector3 centroid = vector3_mid( corners[indices[index]], corners[indices[index + 2]] );
const Vector3 projected = vector4_projected( const Vector3 projected = vector4_projected( matrix4_transformed_vector4( test.getVolume().GetViewMatrix(), Vector4( centroid, 1 ) ) );
matrix4_transformed_vector4( const Vector3 closest_point = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, projected[2], 1 ) ) );
test.getVolume().GetViewMatrix(),
Vector4( centroid, 1 )
)
);
const Vector3 closest_point = vector4_projected(
matrix4_transformed_vector4(
test.getScreen2world(),
Vector4( 0, 0, projected[2], 1 )
)
);
if ( vector3_dot( planes[i].normal(), closest_point - corners[indices[index]] ) > 0 if ( vector3_dot( planes[i].normal(), closest_point - corners[indices[index]] ) > 0
&& vector3_dot( planes[i].normal(), closest_point - corners[indices[index + 1]] ) > 0 && vector3_dot( planes[i].normal(), closest_point - corners[indices[index + 1]] ) > 0
&& vector3_dot( planes[i].normal(), closest_point - corners[indices[index + 2]] ) > 0 && vector3_dot( planes[i].normal(), closest_point - corners[indices[index + 2]] ) > 0

View File

@ -2721,18 +2721,8 @@ void selectReversedPlane( Selector& selector, const SelectedPlanes& selectedPlan
} }
bool trySelectPlane( const SelectionTest& test ){ bool trySelectPlane( const SelectionTest& test ){
const Vector3 projected = vector4_projected( const Vector3 projected = vector4_projected( matrix4_transformed_vector4( test.getVolume().GetViewMatrix(), Vector4( getFace().centroid(), 1 ) ) );
matrix4_transformed_vector4( const Vector3 closest_point = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, projected[2], 1 ) ) );
test.getVolume().GetViewMatrix(),
Vector4( getFace().centroid(), 1 )
)
);
const Vector3 closest_point = vector4_projected(
matrix4_transformed_vector4(
test.getScreen2world(),
Vector4( 0, 0, projected[2], 1 )
)
);
for ( Winding::const_iterator i = getFace().getWinding().begin(); i != getFace().getWinding().end(); ++i ){ for ( Winding::const_iterator i = getFace().getWinding().begin(); i != getFace().getWinding().end(); ++i ){
if ( vector3_dot( getFace().plane3().normal(), closest_point - ( *i ).vertex ) < 0.005 ) /* epsilon to prevent almost perpendicular faces pickup */ if ( vector3_dot( getFace().plane3().normal(), closest_point - ( *i ).vertex ) < 0.005 ) /* epsilon to prevent almost perpendicular faces pickup */
return false; return false;

View File

@ -42,6 +42,13 @@ void Brush_ConstructCuboid( Brush& brush, const AABB& bounds, const char* shader
Vector3 mins( vector3_subtracted( bounds.origin, bounds.extents ) ); Vector3 mins( vector3_subtracted( bounds.origin, bounds.extents ) );
Vector3 maxs( vector3_added( bounds.origin, bounds.extents ) ); Vector3 maxs( vector3_added( bounds.origin, bounds.extents ) );
for( std::size_t i = 0; i < 3; ++i ){
if( mins[i] < g_MinWorldCoord )
mins[i] = g_MinWorldCoord;
if( maxs[i] > g_MaxWorldCoord )
maxs[i] = g_MaxWorldCoord;
}
brush.clear(); brush.clear();
brush.reserve( 6 ); brush.reserve( 6 );
@ -823,17 +830,31 @@ void Scene_BrushConstructPrefab( scene::Graph& graph, EBrushPrefab type, std::si
} }
} }
void Scene_BrushResize_Selected( scene::Graph& graph, const AABB& bounds, const char* shader ){ #include "filterbar.h"
if ( GlobalSelectionSystem().countSelected() != 0 ) { extern bool g_brush_always_caulk;
const scene::Path& path = GlobalSelectionSystem().ultimateSelected().path();
Brush* brush = Node_getBrush( path.top() ); void Scene_BrushResize_Cuboid( scene::Node*& node, const AABB& bounds ){
if ( node == 0 ) {
NodeSmartReference node_( GlobalBrushCreator().createBrush() );
Node_getTraversable( Map_FindOrInsertWorldspawn( g_map ) )->insert( node_ );
scene::Path brushpath( makeReference( GlobalSceneGraph().root() ) );
brushpath.push( makeReference( *Map_GetWorldspawn( g_map ) ) );
brushpath.push( makeReference( node_.get() ) );
selectPath( brushpath, true );
node = node_.get_pointer();
}
Brush* brush = Node_getBrush( *node );
if ( brush != 0 ) { if ( brush != 0 ) {
const char* shader = g_brush_always_caulk?
GetCaulkShader()
: TextureBrowser_GetSelectedShader( GlobalTextureBrowser() );
Brush_ConstructCuboid( *brush, bounds, shader, TextureTransform_getDefault() ); Brush_ConstructCuboid( *brush, bounds, shader, TextureTransform_getDefault() );
SceneChangeNotify(); SceneChangeNotify();
} }
} }
}
void Brush_ConstructPlacehoderCuboid( scene::Node& node, const AABB& bounds ){ void Brush_ConstructPlacehoderCuboid( scene::Node& node, const AABB& bounds ){
scene::Node* brush = &GlobalBrushCreator().createBrush(); scene::Node* brush = &GlobalBrushCreator().createBrush();

View File

@ -45,7 +45,7 @@ class Node;
} }
void Scene_BrushConstructPrefab( scene::Graph& graph, EBrushPrefab type, std::size_t sides, const char* shader ); void Scene_BrushConstructPrefab( scene::Graph& graph, EBrushPrefab type, std::size_t sides, const char* shader );
class AABB; class AABB;
void Scene_BrushResize_Selected( scene::Graph& graph, const AABB& bounds, const char* shader ); void Scene_BrushResize_Cuboid( scene::Node*& node, const AABB& bounds );
void Brush_ConstructPlacehoderCuboid( scene::Node& node, const AABB& bounds ); void Brush_ConstructPlacehoderCuboid( scene::Node& node, const AABB& bounds );
void Scene_BrushSetTexdef_Selected( scene::Graph& graph, const TextureProjection& projection, bool setBasis, bool resetBasis ); void Scene_BrushSetTexdef_Selected( scene::Graph& graph, const TextureProjection& projection, bool setBasis, bool resetBasis );
void Scene_BrushSetTexdef_Component_Selected( scene::Graph& graph, const TextureProjection& projection, bool setBasis, bool resetBasis ); void Scene_BrushSetTexdef_Component_Selected( scene::Graph& graph, const TextureProjection& projection, bool setBasis, bool resetBasis );

View File

@ -38,7 +38,7 @@ LatchedBool g_useAlternativeTextureProjection( false, "Use alternative texture-p
bool g_multipleBrushTypes = false; bool g_multipleBrushTypes = false;
EBrushType g_brushTypes[3]; EBrushType g_brushTypes[3];
int g_brushType; int g_brushType;
bool g_brush_always_caulk; bool g_brush_always_caulk = false;
bool getTextureLockEnabled(){ bool getTextureLockEnabled(){
return g_brush_texturelock_enabled; return g_brush_texturelock_enabled;

View File

@ -186,7 +186,7 @@ class Manipulatable
{ {
public: public:
virtual void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ) = 0; virtual void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ) = 0;
virtual void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ) = 0; virtual void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ) = 0;
}; };
void transform_local2object( Matrix4& object, const Matrix4& local, const Matrix4& local2object ){ void transform_local2object( Matrix4& object, const Matrix4& local, const Matrix4& local2object ){
@ -214,7 +214,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const
point_on_sphere( m_start, device2manip, x, y ); point_on_sphere( m_start, device2manip, x, y );
vector3_normalise( m_start ); vector3_normalise( m_start );
} }
void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){
Vector3 current; Vector3 current;
point_on_sphere( current, device2manip, x, y ); point_on_sphere( current, device2manip, x, y );
@ -252,7 +252,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const
constrain_to_axis( m_start, m_axis ); constrain_to_axis( m_start, m_axis );
} }
/// \brief Converts current position to a normalised vector orthogonal to axis. /// \brief Converts current position to a normalised vector orthogonal to axis.
void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){
Vector3 current; Vector3 current;
point_on_sphere( current, device2manip, x, y ); point_on_sphere( current, device2manip, x, y );
constrain_to_axis( current, m_axis ); constrain_to_axis( current, m_axis );
@ -285,7 +285,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const
constrain_to_axis( m_start, m_axis ); constrain_to_axis( m_start, m_axis );
} }
/// \brief Converts current position to a normalised vector orthogonal to axis. /// \brief Converts current position to a normalised vector orthogonal to axis.
void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){
Vector3 current; Vector3 current;
point_on_sphere( current, device2manip, x, y, g_origin, m_radius ); point_on_sphere( current, device2manip, x, y, g_origin, m_radius );
constrain_to_axis( current, m_axis ); constrain_to_axis( current, m_axis );
@ -325,7 +325,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const
constrain_to_axis( m_start, m_axis ); constrain_to_axis( m_start, m_axis );
} }
/// \brief Converts current position to a normalised vector orthogonal to axis. /// \brief Converts current position to a normalised vector orthogonal to axis.
void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){
Vector3 current; Vector3 current;
point_on_sphere( current, device2manip, x, y, m_sphere_origin ); point_on_sphere( current, device2manip, x, y, m_sphere_origin );
current -= m_sphere_origin; current -= m_sphere_origin;
@ -375,21 +375,20 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const
point_on_axis( m_start, m_axis, device2manip, x, y ); point_on_axis( m_start, m_axis, device2manip, x, y );
m_bounds = bounds; m_bounds = bounds;
} }
void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){
Vector3 current; Vector3 current;
point_on_axis( current, m_axis, device2manip, x, y ); point_on_axis( current, m_axis, device2manip, x, y );
current = vector3_scaled( m_axis, distance_for_axis( m_start, current, m_axis ) ); current = vector3_scaled( m_axis, distance_for_axis( m_start, current, m_axis ) );
translation_local2object( current, current, manip2object ); translation_local2object( current, current, manip2object );
if( snapbbox ){ if( snapbbox ){
float grid = GetSnapGridSize(); const Vector3 maxs( m_bounds.origin + m_bounds.extents );
Vector3 maxs( m_bounds.origin + m_bounds.extents ); const Vector3 mins( m_bounds.origin - m_bounds.extents );
Vector3 mins( m_bounds.origin - m_bounds.extents );
// globalOutputStream() << "current: " << current << "\n"; // globalOutputStream() << "current: " << current << "\n";
for( std::size_t i = 0; i < 3; ++i ){ for( std::size_t i = 0; i < 3; ++i ){
if( m_axis[i] != 0.f ){ if( m_axis[i] != 0.f ){
float snapto1 = float_snapped( maxs[i] + current[i] , grid ); float snapto1 = float_snapped( maxs[i] + current[i] , GetSnapGridSize() );
float snapto2 = float_snapped( mins[i] + current[i] , grid ); float snapto2 = float_snapped( mins[i] + current[i] , GetSnapGridSize() );
float dist1 = fabs( fabs( maxs[i] + current[i] ) - fabs( snapto1 ) ); float dist1 = fabs( fabs( maxs[i] + current[i] ) - fabs( snapto1 ) );
float dist2 = fabs( fabs( mins[i] + current[i] ) - fabs( snapto2 ) ); float dist2 = fabs( fabs( mins[i] + current[i] ) - fabs( snapto2 ) );
@ -426,7 +425,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const
point_on_plane( m_start, device2manip, x, y ); point_on_plane( m_start, device2manip, x, y );
m_bounds = bounds; m_bounds = bounds;
} }
void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){
Vector3 current; Vector3 current;
point_on_plane( current, device2manip, x, y ); point_on_plane( current, device2manip, x, y );
current = vector3_subtracted( current, m_start ); current = vector3_subtracted( current, m_start );
@ -444,14 +443,13 @@ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const
translation_local2object( current, current, manip2object ); translation_local2object( current, current, manip2object );
if( snapbbox ){ if( snapbbox ){
float grid = GetSnapGridSize(); const Vector3 maxs( m_bounds.origin + m_bounds.extents );
Vector3 maxs( m_bounds.origin + m_bounds.extents ); const Vector3 mins( m_bounds.origin - m_bounds.extents );
Vector3 mins( m_bounds.origin - m_bounds.extents );
//globalOutputStream() << "current: " << current << "\n"; //globalOutputStream() << "current: " << current << "\n";
for( std::size_t i = 0; i < 3; ++i ){ for( std::size_t i = 0; i < 3; ++i ){
if( fabs( current[i] ) > 1e-6f ){ if( fabs( current[i] ) > 1e-6f ){
float snapto1 = float_snapped( maxs[i] + current[i] , grid ); float snapto1 = float_snapped( maxs[i] + current[i] , GetSnapGridSize() );
float snapto2 = float_snapped( mins[i] + current[i] , grid ); float snapto2 = float_snapped( mins[i] + current[i] , GetSnapGridSize() );
float dist1 = fabs( fabs( maxs[i] + current[i] ) - fabs( snapto1 ) ); float dist1 = fabs( fabs( maxs[i] + current[i] ) - fabs( snapto1 ) );
float dist2 = fabs( fabs( mins[i] + current[i] ) - fabs( snapto2 ) ); float dist2 = fabs( fabs( mins[i] + current[i] ) - fabs( snapto2 ) );
@ -499,7 +497,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const
); );
m_bounds = bounds; m_bounds = bounds;
} }
void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){
//globalOutputStream() << "manip2object: " << manip2object << " device2manip: " << device2manip << " x: " << x << " y:" << y <<"\n"; //globalOutputStream() << "manip2object: " << manip2object << " device2manip: " << device2manip << " x: " << x << " y:" << y <<"\n";
Vector3 current; Vector3 current;
point_on_axis( current, m_axis, device2manip, x, y ); point_on_axis( current, m_axis, device2manip, x, y );
@ -573,7 +571,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const
); );
m_bounds = bounds; m_bounds = bounds;
} }
void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){
Vector3 current; Vector3 current;
point_on_plane( current, device2manip, x, y ); point_on_plane( current, device2manip, x, y );
Vector3 delta = vector3_subtracted( current, m_start ); Vector3 delta = vector3_subtracted( current, m_start );
@ -669,7 +667,7 @@ void Construct( const Matrix4& device2manip, const float x, const float y, const
m_bounds = bounds; m_bounds = bounds;
m_axis_by_extent = bounds.origin[m_axis_by] + bounds.extents[m_axis_by] * m_axis_by_sign - transform_origin[m_axis_by]; m_axis_by_extent = bounds.origin[m_axis_by] + bounds.extents[m_axis_by] * m_axis_by_sign - transform_origin[m_axis_by];
} }
void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){
Vector3 current; Vector3 current;
point_on_axis( current, m_axis_which, device2manip, x, y ); point_on_axis( current, m_axis_which, device2manip, x, y );
current = vector3_scaled( m_axis_which, distance_for_axis( m_start, current, m_axis_which ) ); current = vector3_scaled( m_axis_which, distance_for_axis( m_start, current, m_axis_which ) );
@ -688,7 +686,60 @@ void SetAxes( const Vector3& axis_which, int axis_by, int axis_by_sign ){
} }
}; };
#include "brushmanip.h"
class DragNewBrush : public Manipulatable
{
private:
Vector3 m_start;
Vector3 m_0;
Vector3 m_size;
scene::Node* m_newBrushNode;
public:
DragNewBrush(){
}
void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ){
point_on_plane( m_start, device2manip, x, y );
m_size[0] = m_size[1] = m_size[2] = GetGridSize();
m_newBrushNode = 0;
}
void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){
Vector3 current;
point_on_plane( current, device2manip, x, y );
current = vector3_subtracted( current, m_start );
translation_local2object( current, current, manip2object );
Vector3 current_snapped = vector3_snapped( current, GetSnapGridSize() );
for ( std::size_t i = 0; i < 3; ++i )
if( current_snapped[i] == 0 )
current_snapped[i] = current[i] < 0? -GetGridSize() : GetGridSize();
if( alt ){
current_snapped.x() = m_size.x();
current_snapped.y() = m_size.y();
}
else{
current_snapped.z() = m_size.z();
}
if( snap || snapbbox ){
const float squaresize = std::max( fabs( current_snapped.x() ), fabs( current_snapped.y() ) );
current_snapped.x() = current_snapped.x() > 0? squaresize : -squaresize;
current_snapped.y() = current_snapped.y() > 0? squaresize : -squaresize;
if( snapbbox && !alt )
current_snapped.z() = current_snapped.z() > 0? squaresize : -squaresize;
}
m_size = current_snapped;
Vector3 mins( m_0 );
Vector3 maxs( current_snapped + m_0 );
for ( std::size_t i = 0; i < 3; ++i )
if( mins[i] > maxs[i] )
std::swap( mins[i], maxs[i] );
Scene_BrushResize_Cuboid( m_newBrushNode, aabb_for_minmax( mins, maxs ) );
}
void set0( const Vector3& start ){
m_0 = start;
}
};
@ -870,13 +921,6 @@ void BestPoint( std::size_t count, Vector4 clipped[9], SelectionIntersection& be
} }
} }
// if( cull == eClipCullCW ){
// globalOutputStream() << "eClipCullCW\n";
// }
// else if( cull == eClipCullCCW ){
// globalOutputStream() << "eClipCullCCW\n";
// }
if ( cull != eClipCullNone && count > 2 ) { if ( cull != eClipCullNone && count > 2 ) {
double signed_area = triangle_signed_area_XY( normalised[0], normalised[1], normalised[2] ); double signed_area = triangle_signed_area_XY( normalised[0], normalised[1], normalised[2] );
@ -2340,18 +2384,8 @@ public:
for ( int j = 0; j < 2; ++j ){ for ( int j = 0; j < 2; ++j ){
const Vector3 normal = j? g_vector3_axes[i] : -g_vector3_axes[i]; const Vector3 normal = j? g_vector3_axes[i] : -g_vector3_axes[i];
const Vector3 centroid = m_bounds.origin + m_bounds.extents * normal; const Vector3 centroid = m_bounds.origin + m_bounds.extents * normal;
const Vector3 projected = vector4_projected( const Vector3 projected = vector4_projected( matrix4_transformed_vector4( view.GetViewMatrix(), Vector4( centroid, 1 ) ) );
matrix4_transformed_vector4( const Vector3 closest_point = vector4_projected( matrix4_transformed_vector4( screen2world, Vector4( 0, 0, projected[2], 1 ) ) );
view.GetViewMatrix(),
Vector4( centroid, 1 )
)
);
const Vector3 closest_point = vector4_projected(
matrix4_transformed_vector4(
screen2world,
Vector4( 0, 0, projected[2], 1 )
)
);
const int index = i * 8 + j * 4; const int index = i * 8 + j * 4;
if( vector3_dot( normal, closest_point - corners[indices[index]] ) > 0 if( vector3_dot( normal, closest_point - corners[indices[index]] ) > 0
@ -3456,6 +3490,39 @@ std::list<Selectable*>& best(){
} }
}; };
class BestPointSelector : public Selector
{
bool m_selected;
SelectionIntersection m_intersection;
SelectionIntersection m_bestIntersection;
Selectable* m_selectable;
public:
BestPointSelector() : m_selected( false ), m_bestIntersection( SelectionIntersection() ){
}
void pushSelectable( Selectable& selectable ){
m_intersection = SelectionIntersection();
}
void popSelectable(){
if ( m_intersection.valid() )
m_selected = true;
if ( m_intersection < m_bestIntersection )
m_bestIntersection = m_intersection;
m_intersection = SelectionIntersection();
}
void addIntersection( const SelectionIntersection& intersection ){
assign_if_closer( m_intersection, intersection );
}
bool isSelected(){
return m_selected;
}
const SelectionIntersection& best(){
return m_bestIntersection;
}
};
bool g_bAltResize_AltSelect = false; //AltDragManipulatorResize + select primitives in component modes bool g_bAltResize_AltSelect = false; //AltDragManipulatorResize + select primitives in component modes
bool g_bTmpComponentMode = false; bool g_bTmpComponentMode = false;
@ -3465,94 +3532,101 @@ TranslateFree m_freeResize;
TranslateFree m_freeDrag; TranslateFree m_freeDrag;
ResizeTranslatable m_resize; ResizeTranslatable m_resize;
DragTranslatable m_drag; DragTranslatable m_drag;
SelectableBool m_dragSelectable; //drag already selected stuff DragNewBrush m_dragNewBrush;
bool m_dragSelected; //drag selected primitives or components
bool m_selected; //components selected temporally for drag
bool m_newBrush;
Matrix4& m_pivot2world;
public: public:
bool m_selected; //selected temporally for drag DragManipulator( Matrix4& pivot2world ) : m_freeResize( m_resize ), m_freeDrag( m_drag ), m_selected( false ), m_newBrush( false ), m_pivot2world( pivot2world ){
DragManipulator() : m_freeResize( m_resize ), m_freeDrag( m_drag ), m_selected( false ){
} }
Manipulatable* GetManipulatable(){ Manipulatable* GetManipulatable(){
return m_dragSelectable.isSelected() ? &m_freeDrag : &m_freeResize; if( m_newBrush )
return &m_dragNewBrush;
else
return m_dragSelected? &m_freeDrag : &m_freeResize;
} }
void testSelect( const View& view, const Matrix4& pivot2world ){ void testSelect( const View& view, const Matrix4& pivot2world ){
SelectionPool selector; SelectionPool selector;
SelectionVolume test( view ); SelectionVolume test( view );
if( GlobalSelectionSystem().countSelected() != 0 ){
if ( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ){ if ( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ){
BooleanSelector booleanSelector; BooleanSelector booleanSelector;
Scene_TestSelect_Primitive( booleanSelector, test, view ); Scene_TestSelect_Primitive( booleanSelector, test, view );
if ( booleanSelector.isSelected() ) { if ( booleanSelector.isSelected() ) { /* hit a primitive */
if( g_bAltResize_AltSelect ){ if( g_bAltResize_AltSelect ){
DeepBestSelector deepSelector; DeepBestSelector deepSelector;
Scene_TestSelect_Component_Selected( deepSelector, test, view, SelectionSystem::eVertex ); Scene_TestSelect_Component_Selected( deepSelector, test, view, SelectionSystem::eVertex ); /* try to quickly select hit vertices */
for ( std::list<Selectable*>::iterator i = deepSelector.best().begin(); i != deepSelector.best().end(); ++i ) for ( std::list<Selectable*>::iterator i = deepSelector.best().begin(); i != deepSelector.best().end(); ++i )
{
if ( !( *i )->isSelected() ) {
GlobalSelectionSystem().setSelectedAllComponents( false );
}
selector.addSelectable( SelectionIntersection( 0, 0 ), ( *i ) ); selector.addSelectable( SelectionIntersection( 0, 0 ), ( *i ) );
m_selected = true; if( deepSelector.best().empty() ) /* otherwise drag clicked face's vertices */
m_dragSelectable.setSelected( false ); Scene_forEachTestedBrushFace_selectVertices( GlobalSceneGraph(), test );
}
if( deepSelector.best().empty() ){
Scene_forEachTestedBrushFace_selectVertices( GlobalSceneGraph(), test ); //drag clicked face
//Scene_forEachBrushPlane_selectVertices( GlobalSceneGraph(), test );
m_selected = true; m_selected = true;
} }
} else{ /* drag a primitive */
else{ m_dragSelected = true;
selector.addSelectable( SelectionIntersection( 0, 0 ), &m_dragSelectable );
m_selected = false;
} }
} }
else else{ /* haven't hit a primitive */
{
if( g_bAltResize_AltSelect ){ if( g_bAltResize_AltSelect ){
Scene_forEachBrushPlane_selectVertices( GlobalSceneGraph(), test ); Scene_forEachBrushPlane_selectVertices( GlobalSceneGraph(), test ); /* select vertices on planeSelectables */
m_selected = true; m_selected = true;
} }
else{ else{
m_selected = Scene_forEachPlaneSelectable_selectPlanes( GlobalSceneGraph(), selector, test ); m_selected = Scene_forEachPlaneSelectable_selectPlanes( GlobalSceneGraph(), selector, test ); /* select faces on planeSelectables */
} }
} }
} }
else else{
{
BestSelector bestSelector; BestSelector bestSelector;
Scene_TestSelect_Component_Selected( bestSelector, test, view, GlobalSelectionSystem().ComponentMode() ); Scene_TestSelect_Component_Selected( bestSelector, test, view, GlobalSelectionSystem().ComponentMode() ); /* drag components */
for ( std::list<Selectable*>::iterator i = bestSelector.best().begin(); i != bestSelector.best().end(); ++i ) for ( std::list<Selectable*>::iterator i = bestSelector.best().begin(); i != bestSelector.best().end(); ++i ){
{ if ( !( *i )->isSelected() )
if ( !( *i )->isSelected() ) {
GlobalSelectionSystem().setSelectedAllComponents( false ); GlobalSelectionSystem().setSelectedAllComponents( false );
}
m_selected = false;
selector.addSelectable( SelectionIntersection( 0, 0 ), ( *i ) ); selector.addSelectable( SelectionIntersection( 0, 0 ), ( *i ) );
m_dragSelectable.setSelected( true ); m_dragSelected = true;
}
if( GlobalSelectionSystem().countSelectedComponents() != 0 ){
m_dragSelectable.setSelected( true );
} }
if( GlobalSelectionSystem().countSelectedComponents() != 0 ) /* even if hit nothing, but got selected */
m_dragSelected = true;
} }
for ( SelectionPool::iterator i = selector.begin(); i != selector.end(); ++i ) for ( SelectionPool::iterator i = selector.begin(); i != selector.end(); ++i )
{
( *i ).second->setSelected( true ); ( *i ).second->setSelected( true );
}
g_bTmpComponentMode = m_selected; g_bTmpComponentMode = m_selected;
} }
else if( GlobalSelectionSystem().Mode() == SelectionSystem::ePrimitive ){
m_newBrush = true;
BestPointSelector bestPointSelector;
Scene_TestSelect_Primitive( bestPointSelector, test, view );
Vector3 start;
test.BeginMesh( g_matrix4_identity, true );
if( bestPointSelector.isSelected() ){
start = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, bestPointSelector.best().depth(), 1 ) ) );
}
else{
const Vector3 near = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, -1, 1 ) ) );
const Vector3 far = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, 1, 1 ) ) );
start = vector3_normalised( far - near ) * 256.f + near;
}
vector3_snap( start, GetSnapGridSize() );
m_dragNewBrush.set0( start );
m_pivot2world = matrix4_translation_for_vec3( start );
}
}
void setSelected( bool select ){ void setSelected( bool select ){
m_dragSelected = select;
m_selected = select; m_selected = select;
m_dragSelectable.setSelected( select ); m_newBrush = select;
} }
bool isSelected() const { bool isSelected() const {
return m_selected || m_dragSelectable.isSelected(); return m_dragSelected || m_selected || m_newBrush;
} }
}; };
@ -3590,7 +3664,7 @@ TransformOriginTranslate( TransformOriginTranslatable& transformOriginTranslatab
void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ){ void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ){
point_on_plane( m_start, device2manip, x, y ); point_on_plane( m_start, device2manip, x, y );
} }
void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox ){ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){
Vector3 current; Vector3 current;
point_on_plane( current, device2manip, x, y ); point_on_plane( current, device2manip, x, y );
current = vector3_subtracted( current, m_start ); current = vector3_subtracted( current, m_start );
@ -3838,6 +3912,7 @@ RadiantSelectionSystem() :
m_rotate_manipulator( *this, 8, 64 ), m_rotate_manipulator( *this, 8, 64 ),
m_scale_manipulator( *this, 0, 64 ), m_scale_manipulator( *this, 0, 64 ),
m_skew_manipulator( *this, *this, *this, *this, m_bounds, m_pivot2world, m_pivotIsCustom ), m_skew_manipulator( *this, *this, *this, *this, m_bounds, m_pivot2world, m_pivotIsCustom ),
m_drag_manipulator( m_pivot2world ),
m_transformOrigin_manipulator( *this, m_pivotIsCustom ), m_transformOrigin_manipulator( *this, m_pivotIsCustom ),
m_pivotChanged( false ), m_pivotChanged( false ),
m_pivot_moving( false ), m_pivot_moving( false ),
@ -3979,7 +4054,7 @@ void startMove(){
bool SelectManipulator( const View& view, const float device_point[2], const float device_epsilon[2] ){ bool SelectManipulator( const View& view, const float device_point[2], const float device_epsilon[2] ){
bool movingOrigin = false; bool movingOrigin = false;
if ( !nothingSelected() || ( ManipulatorMode() == eDrag && Mode() == eComponent ) ) { if ( !nothingSelected() || ManipulatorMode() == eDrag ) {
#if defined ( DEBUG_SELECTION ) #if defined ( DEBUG_SELECTION )
g_render_clipped.destroy(); g_render_clipped.destroy();
#endif #endif
@ -3987,7 +4062,7 @@ bool SelectManipulator( const View& view, const float device_point[2], const flo
m_transformOrigin_manipulator.setSelected( false ); m_transformOrigin_manipulator.setSelected( false );
m_manipulator->setSelected( false ); m_manipulator->setSelected( false );
if ( !nothingSelected() || ( ManipulatorMode() == eDrag && Mode() == eComponent ) ) { {
View scissored( view ); View scissored( view );
ConstructSelectionTest( scissored, SelectionBoxForPoint( device_point, device_epsilon ) ); ConstructSelectionTest( scissored, SelectionBoxForPoint( device_point, device_epsilon ) );
@ -4442,7 +4517,7 @@ void transformOriginTranslate( const Vector3& translation, const bool set[3] ){
SceneChangeNotify(); SceneChangeNotify();
} }
void MoveSelected( const View& view, const float device_point[2], bool snap, bool snapbbox ){ void MoveSelected( const View& view, const float device_point[2], bool snap, bool snapbbox, bool alt ){
if ( m_manipulator->isSelected() ) { if ( m_manipulator->isSelected() ) {
if ( !m_undo_begun ) { if ( !m_undo_begun ) {
m_undo_begun = true; m_undo_begun = true;
@ -4451,12 +4526,12 @@ void MoveSelected( const View& view, const float device_point[2], bool snap, boo
Matrix4 device2manip; Matrix4 device2manip;
ConstructDevice2Manip( device2manip, m_pivot2world_start, view.GetModelview(), view.GetProjection(), view.GetViewport() ); ConstructDevice2Manip( device2manip, m_pivot2world_start, view.GetModelview(), view.GetProjection(), view.GetViewport() );
m_manipulator->GetManipulatable()->Transform( m_manip2pivot_start, device2manip, device_point[0], device_point[1], snap, snapbbox ); m_manipulator->GetManipulatable()->Transform( m_manip2pivot_start, device2manip, device_point[0], device_point[1], snap, snapbbox, alt );
} }
else if( m_transformOrigin_manipulator.isSelected() ){ else if( m_transformOrigin_manipulator.isSelected() ){
Matrix4 device2manip; Matrix4 device2manip;
ConstructDevice2Manip( device2manip, m_pivot2world_start, view.GetModelview(), view.GetProjection(), view.GetViewport() ); ConstructDevice2Manip( device2manip, m_pivot2world_start, view.GetModelview(), view.GetProjection(), view.GetViewport() );
m_transformOrigin_manipulator.GetManipulatable()->Transform( m_manip2pivot_start, device2manip, device_point[0], device_point[1], snap, snapbbox ); m_transformOrigin_manipulator.GetManipulatable()->Transform( m_manip2pivot_start, device2manip, device_point[0], device_point[1], snap, snapbbox, alt );
} }
} }
@ -4641,9 +4716,7 @@ void RadiantSelectionSystem::Scene_TestSelect( Selector& selector, SelectionTest
switch ( mode ) switch ( mode )
{ {
case eEntity: case eEntity:
{
Scene_forEachVisible( GlobalSceneGraph(), view, testselect_entity_visible( selector, test ) ); Scene_forEachVisible( GlobalSceneGraph(), view, testselect_entity_visible( selector, test ) );
}
break; break;
case ePrimitive: case ePrimitive:
Scene_TestSelect_Primitive( selector, test, view ); Scene_TestSelect_Primitive( selector, test, view );
@ -4685,16 +4758,9 @@ bool RadiantSelectionSystem::endMove(){
freezeTransforms(); freezeTransforms();
if ( Mode() == ePrimitive ) { if ( Mode() == ePrimitive && ManipulatorMode() == eDrag ) {
if ( ManipulatorMode() == eDrag ) {
g_bTmpComponentMode = false; g_bTmpComponentMode = false;
if( g_bAltResize_AltSelect ){ Scene_SelectAll_Component( false, g_bAltResize_AltSelect? SelectionSystem::eVertex : SelectionSystem::eFace );
Scene_SelectAll_Component( false, SelectionSystem::eVertex );
}
else{
Scene_SelectAll_Component( false, SelectionSystem::eFace );
}
}
} }
m_pivot_moving = false; m_pivot_moving = false;
@ -5275,7 +5341,9 @@ bool mouseDown( DeviceVector position ){
void mouseMoved( DeviceVector position ){ void mouseMoved( DeviceVector position ){
if( m_mouseMovedWhilePressed ) if( m_mouseMovedWhilePressed )
getSelectionSystem().MoveSelected( *m_view, &position[0], ( m_state & c_modifierShift ) == c_modifierShift, ( m_state & c_modifierControl ) == c_modifierControl ); getSelectionSystem().MoveSelected( *m_view, &position[0], bitfield_enabled( m_state, c_modifierShift ),
bitfield_enabled( m_state, c_modifierControl ),
bitfield_enabled( m_state, c_modifierAlt ) );
} }
typedef MemberCaller1<Manipulator_, DeviceVector, &Manipulator_::mouseMoved> MouseMovedCaller; typedef MemberCaller1<Manipulator_, DeviceVector, &Manipulator_::mouseMoved> MouseMovedCaller;

View File

@ -1631,7 +1631,8 @@ public:
BrushGetClosestFaceVisibleWalker( SelectionTest& test, Texturable& texturable, bool seamless, bool project ) : m_test( test ), m_texturable( texturable ), m_seamless( seamless ), m_project( project ){ BrushGetClosestFaceVisibleWalker( SelectionTest& test, Texturable& texturable, bool seamless, bool project ) : m_test( test ), m_texturable( texturable ), m_seamless( seamless ), m_project( project ){
} }
bool pre( const scene::Path& path, scene::Instance& instance ) const { bool pre( const scene::Path& path, scene::Instance& instance ) const {
if ( path.top().get().visible() ) { if ( !path.top().get().visible() )
return false;
BrushInstance* brush = Instance_getBrush( instance ); BrushInstance* brush = Instance_getBrush( instance );
if ( brush != 0 ) { if ( brush != 0 ) {
m_test.BeginMesh( brush->localToWorld() ); m_test.BeginMesh( brush->localToWorld() );
@ -1664,10 +1665,6 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
} }
} }
} }
}
else{
return false;
}
return true; return true;
} }
}; };

View File

@ -75,9 +75,6 @@
void LoadTextureRGBA( qtexture_t* q, unsigned char* pPixels, int nWidth, int nHeight ); void LoadTextureRGBA( qtexture_t* q, unsigned char* pPixels, int nWidth, int nHeight );
// d1223m
extern bool g_brush_always_caulk;
bool g_bCamEntityMenu = false; bool g_bCamEntityMenu = false;
//!\todo Rewrite. //!\todo Rewrite.
@ -1206,7 +1203,7 @@ void XYWnd::NewBrushDrag( int x, int y, bool square, bool cube ){
XY_ToPoint( x, y, maxs ); XY_ToPoint( x, y, maxs );
XY_SnapToGrid( maxs ); XY_SnapToGrid( maxs );
int nDim = ( m_viewType == XY ) ? 2 : ( m_viewType == YZ ) ? 0 : 1; const int nDim = ( m_viewType == XY ) ? 2 : ( m_viewType == YZ ) ? 0 : 1;
mins[nDim] = float_snapped( Select_getWorkZone().d_work_min[nDim], GetSnapGridSize() ); mins[nDim] = float_snapped( Select_getWorkZone().d_work_min[nDim], GetSnapGridSize() );
maxs[nDim] = float_snapped( Select_getWorkZone().d_work_max[nDim], GetSnapGridSize() ); maxs[nDim] = float_snapped( Select_getWorkZone().d_work_max[nDim], GetSnapGridSize() );
@ -1216,7 +1213,7 @@ void XYWnd::NewBrushDrag( int x, int y, bool square, bool cube ){
} }
if( square || cube ){ if( square || cube ){
float squaresize = std::max( fabs( maxs[(nDim + 1) % 3] - mins[(nDim + 1) % 3] ), fabs( maxs[(nDim + 2) % 3] - mins[(nDim + 2) % 3] ) ); const float squaresize = std::max( fabs( maxs[(nDim + 1) % 3] - mins[(nDim + 1) % 3] ), fabs( maxs[(nDim + 2) % 3] - mins[(nDim + 2) % 3] ) );
maxs[(nDim + 1) % 3] = ( maxs[(nDim + 1) % 3] - mins[(nDim + 1) % 3] ) > 0.f ? ( mins[(nDim + 1) % 3] + squaresize ) : ( mins[(nDim + 1) % 3] - squaresize ); maxs[(nDim + 1) % 3] = ( maxs[(nDim + 1) % 3] - mins[(nDim + 1) % 3] ) > 0.f ? ( mins[(nDim + 1) % 3] + squaresize ) : ( mins[(nDim + 1) % 3] - squaresize );
maxs[(nDim + 2) % 3] = ( maxs[(nDim + 2) % 3] - mins[(nDim + 2) % 3] ) > 0.f ? ( mins[(nDim + 2) % 3] + squaresize ) : ( mins[(nDim + 2) % 3] - squaresize ); maxs[(nDim + 2) % 3] = ( maxs[(nDim + 2) % 3] - mins[(nDim + 2) % 3] ) > 0.f ? ( mins[(nDim + 2) % 3] + squaresize ) : ( mins[(nDim + 2) % 3] - squaresize );
if( cube ){ if( cube ){
@ -1226,34 +1223,16 @@ void XYWnd::NewBrushDrag( int x, int y, bool square, bool cube ){
for ( int i = 0 ; i < 3 ; i++ ) for ( int i = 0 ; i < 3 ; i++ )
{ {
if ( mins[i] == maxs[i] ) { if ( mins[i] == maxs[i] )
return; // don't create a degenerate brush return; // don't create a degenerate brush
} if ( mins[i] > maxs[i] )
if ( mins[i] > maxs[i] ) { std::swap( mins[i], maxs[i] );
float temp = mins[i];
mins[i] = maxs[i];
maxs[i] = temp;
}
} }
if ( m_NewBrushDrag == 0 ) { if ( m_NewBrushDrag == 0 )
GlobalUndoSystem().start(); GlobalUndoSystem().start();
NodeSmartReference node( GlobalBrushCreator().createBrush() );
Node_getTraversable( Map_FindOrInsertWorldspawn( g_map ) )->insert( node );
scene::Path brushpath( makeReference( GlobalSceneGraph().root() ) ); Scene_BrushResize_Cuboid( m_NewBrushDrag, aabb_for_minmax( mins, maxs ) );
brushpath.push( makeReference( *Map_GetWorldspawn( g_map ) ) );
brushpath.push( makeReference( node.get() ) );
selectPath( brushpath, true );
m_NewBrushDrag = node.get_pointer();
}
// d1223m
//Scene_BrushResize_Selected(GlobalSceneGraph(), aabb_for_minmax(mins, maxs), TextureBrowser_GetSelectedShader(GlobalTextureBrowser()));
Scene_BrushResize_Selected( GlobalSceneGraph(), aabb_for_minmax( mins, maxs ),
g_brush_always_caulk ?
GetCaulkShader() : TextureBrowser_GetSelectedShader( GlobalTextureBrowser() ) );
} }
int g_entityCreationOffset = 0; int g_entityCreationOffset = 0;