* clipper tool total rewrite; works in 3d viewport
* fix: update BrushClipPlane rendering on selection change * clipper points are draggable right after been dropped
This commit is contained in:
parent
b06c551866
commit
7088653115
|
|
@ -1507,31 +1507,7 @@ BrushPrefab g_brushsphere( eBrushSphere );
|
|||
BrushPrefab g_brushrock( eBrushRock );
|
||||
BrushPrefab g_brushicosahedron( eBrushIcosahedron );
|
||||
|
||||
/*
|
||||
void FlipClip();
|
||||
void SplitClip();
|
||||
void Clip();
|
||||
void OnClipMode( bool enable );
|
||||
bool ClipMode();
|
||||
*/
|
||||
|
||||
void ClipSelected(){
|
||||
if ( ClipMode() ) {
|
||||
UndoableCommand undo( "clipperClip" );
|
||||
Clip();
|
||||
}
|
||||
}
|
||||
|
||||
void SplitSelected(){
|
||||
if ( ClipMode() ) {
|
||||
UndoableCommand undo( "clipperSplit" );
|
||||
SplitClip();
|
||||
}
|
||||
}
|
||||
|
||||
void FlipClipper(){
|
||||
FlipClip();
|
||||
}
|
||||
|
||||
|
||||
Callback g_texture_lock_status_changed;
|
||||
|
|
@ -1572,10 +1548,6 @@ void Brush_registerCommands(){
|
|||
GlobalCommands_insert( "Brush8Sided", BrushMakeSided::SetCaller( g_brushmakesided8 ), Accelerator( '8', (GdkModifierType)GDK_CONTROL_MASK ) );
|
||||
GlobalCommands_insert( "Brush9Sided", BrushMakeSided::SetCaller( g_brushmakesided9 ), Accelerator( '9', (GdkModifierType)GDK_CONTROL_MASK ) );
|
||||
|
||||
GlobalCommands_insert( "ClipSelected", FreeCaller<ClipSelected>(), Accelerator( GDK_Return ) );
|
||||
GlobalCommands_insert( "SplitSelected", FreeCaller<SplitSelected>(), Accelerator( GDK_Return, (GdkModifierType)GDK_SHIFT_MASK ) );
|
||||
GlobalCommands_insert( "FlipClip", FreeCaller<FlipClipper>(), Accelerator( GDK_Return, (GdkModifierType)GDK_CONTROL_MASK ) );
|
||||
|
||||
GlobalCommands_insert( "MakeDetail", FreeCaller<Select_MakeDetail>(), Accelerator( 'D', (GdkModifierType)GDK_MOD1_MASK ) );
|
||||
GlobalCommands_insert( "MakeStructural", FreeCaller<Select_MakeStructural>(), Accelerator( 'S', (GdkModifierType)GDK_MOD1_MASK ) );
|
||||
}
|
||||
|
|
@ -1604,9 +1576,9 @@ void Brush_constructMenu( GtkMenu* menu ){
|
|||
menu_tearoff( menu_in_menu );
|
||||
}
|
||||
|
||||
create_menu_item_with_mnemonic( menu_in_menu, "Clip selection", "ClipSelected" );
|
||||
create_menu_item_with_mnemonic( menu_in_menu, "Split selection", "SplitSelected" );
|
||||
create_menu_item_with_mnemonic( menu_in_menu, "Flip Clip orientation", "FlipClip" );
|
||||
create_menu_item_with_mnemonic( menu_in_menu, "Clip selection", "ClipperClip" );
|
||||
create_menu_item_with_mnemonic( menu_in_menu, "Split selection", "ClipperSplit" );
|
||||
create_menu_item_with_mnemonic( menu_in_menu, "Flip Clip orientation", "ClipperFlip" );
|
||||
}
|
||||
menu_separator( menu );
|
||||
create_menu_item_with_mnemonic( menu, "Make detail", "MakeDetail" );
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
#include "mainframe.h"
|
||||
#include "preferences.h"
|
||||
|
||||
#include "clippertool.h"
|
||||
|
||||
LatchedBool g_useAlternativeTextureProjection( false, "Use alternative texture-projection (\"brush primitives\")" );
|
||||
bool g_multipleBrushTypes = false;
|
||||
EBrushType g_brushTypes[3];
|
||||
|
|
@ -178,9 +180,13 @@ void Brush_Construct( EBrushType type ){
|
|||
GridStatus_getTextureLockEnabled = getTextureLockEnabled;
|
||||
GridStatus_getTexdefTypeIdLabel = getTexdefTypeIdLabel;
|
||||
g_texture_lock_status_changed = FreeCaller<GridStatus_changed>();
|
||||
|
||||
Clipper_Construct();
|
||||
}
|
||||
|
||||
void Brush_Destroy(){
|
||||
Clipper_Destroy();
|
||||
|
||||
Brush::m_maxWorldCoord = 0;
|
||||
BrushInstance::m_counter = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -20,3 +20,127 @@
|
|||
*/
|
||||
|
||||
#include "clippertool.h"
|
||||
|
||||
#include "math/plane.h"
|
||||
#include "csg.h"
|
||||
#include "iscenegraph.h"
|
||||
#include "iselection.h"
|
||||
#include "iundo.h"
|
||||
#include "mainframe.h"
|
||||
#include "camwindow.h"
|
||||
#include "xywindow.h"
|
||||
#include "gtkutil/cursor.h"
|
||||
|
||||
GdkCursor* g_clipper_cursor;
|
||||
|
||||
ClipperPoints g_clipper_points( g_vector3_identity, g_vector3_identity, g_vector3_identity );
|
||||
bool g_clipper_flipped = false;
|
||||
|
||||
bool g_clipper_caulk = true;
|
||||
|
||||
bool Clipper_ok(){
|
||||
return GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip && plane3_valid( plane3_for_points( g_clipper_points._points ) );
|
||||
}
|
||||
|
||||
ClipperPoints Clipper_getPlanePoints(){
|
||||
return g_clipper_flipped? ClipperPoints( g_clipper_points[0], g_clipper_points[2], g_clipper_points[1] ) : g_clipper_points;
|
||||
}
|
||||
|
||||
void Clipper_update(){
|
||||
Scene_BrushSetClipPlane( GlobalSceneGraph(), Clipper_getPlanePoints() );
|
||||
SceneChangeNotify();
|
||||
}
|
||||
|
||||
void Clipper_setPlanePoints( const ClipperPoints& points ){
|
||||
g_clipper_points = points;
|
||||
Clipper_update();
|
||||
}
|
||||
|
||||
void Clipper_SelectionChanged( const Selectable& selectable ){
|
||||
if ( Clipper_ok() )
|
||||
Clipper_update();
|
||||
}
|
||||
|
||||
void Clipper_modeChanged( bool isClipper ){
|
||||
GdkCursor* cursor = isClipper? g_clipper_cursor : 0;
|
||||
|
||||
if( g_pParentWnd ){
|
||||
XYWnd* xywnd;
|
||||
if( ( xywnd = g_pParentWnd->GetXYWnd() ) )
|
||||
gdk_window_set_cursor( xywnd->GetWidget()->window, cursor );
|
||||
if( ( xywnd = g_pParentWnd->GetXZWnd() ) )
|
||||
gdk_window_set_cursor( xywnd->GetWidget()->window, cursor );
|
||||
if( ( xywnd = g_pParentWnd->GetYZWnd() ) )
|
||||
gdk_window_set_cursor( xywnd->GetWidget()->window, cursor );
|
||||
if( g_pParentWnd->GetCamWnd() )
|
||||
gdk_window_set_cursor( CamWnd_getWidget( *g_pParentWnd->GetCamWnd() )->window, cursor );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void Clipper_do( bool split ){
|
||||
Scene_BrushSplitByPlane( GlobalSceneGraph(), Clipper_getPlanePoints(), g_clipper_caulk, split );
|
||||
GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eClip ); /* reset points this way */
|
||||
}
|
||||
|
||||
|
||||
void Clipper_doClip(){
|
||||
if ( Clipper_ok() ) {
|
||||
UndoableCommand undo( "clipperClip" );
|
||||
Clipper_do( false );
|
||||
}
|
||||
}
|
||||
|
||||
void Clipper_doSplit(){
|
||||
if ( Clipper_ok() ) {
|
||||
UndoableCommand undo( "clipperSplit" );
|
||||
Clipper_do( true );
|
||||
}
|
||||
}
|
||||
|
||||
void Clipper_doFlip(){
|
||||
if( Clipper_ok() ){
|
||||
g_clipper_flipped = !g_clipper_flipped;
|
||||
Clipper_update();
|
||||
}
|
||||
}
|
||||
|
||||
#include "preferencesystem.h"
|
||||
#include "stringio.h"
|
||||
#include "preferences.h"
|
||||
#include "commands.h"
|
||||
#include "signal/isignal.h"
|
||||
void Clipper_constructPreferences( PreferencesPage& page ){
|
||||
page.appendCheckBox( "", "Caulk Clipper Splits", g_clipper_caulk );
|
||||
}
|
||||
void Clipper_constructPage( PreferenceGroup& group ){
|
||||
PreferencesPage page( group.createPage( "Clipper", "Clipper Tool Settings" ) );
|
||||
Clipper_constructPreferences( page );
|
||||
}
|
||||
void Clipper_registerPreferencesPage(){
|
||||
PreferencesDialog_addSettingsPage( FreeCaller1<PreferenceGroup&, Clipper_constructPage>() );
|
||||
}
|
||||
|
||||
void Clipper_registerCommands(){
|
||||
GlobalCommands_insert( "ClipperClip", FreeCaller<Clipper_doClip>(), Accelerator( GDK_Return ) );
|
||||
GlobalCommands_insert( "ClipperSplit", FreeCaller<Clipper_doSplit>(), Accelerator( GDK_Return, (GdkModifierType)GDK_SHIFT_MASK ) );
|
||||
GlobalCommands_insert( "ClipperFlip", FreeCaller<Clipper_doFlip>(), Accelerator( GDK_Return, (GdkModifierType)GDK_CONTROL_MASK ) );
|
||||
}
|
||||
|
||||
void Clipper_Construct(){
|
||||
g_clipper_cursor = gdk_cursor_new( GDK_HAND2 );
|
||||
|
||||
Clipper_registerCommands();
|
||||
GlobalPreferenceSystem().registerPreference( "ClipperCaulk", BoolImportStringCaller( g_clipper_caulk ), BoolExportStringCaller( g_clipper_caulk ) );
|
||||
Clipper_registerPreferencesPage();
|
||||
|
||||
typedef FreeCaller1<const Selectable&, Clipper_SelectionChanged> ClipperSelectionChangedCaller;
|
||||
GlobalSelectionSystem().addSelectionChangeCallback( ClipperSelectionChangedCaller() );
|
||||
}
|
||||
|
||||
void Clipper_Destroy(){
|
||||
gdk_cursor_unref( g_clipper_cursor );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,4 +22,29 @@
|
|||
#if !defined( INCLUDED_CLIPPERTOOL_H )
|
||||
#define INCLUDED_CLIPPERTOOL_H
|
||||
|
||||
#include "generic/vector.h"
|
||||
|
||||
class ClipperPoints
|
||||
{
|
||||
public:
|
||||
Vector3 _points[3];
|
||||
ClipperPoints( const Vector3& p0, const Vector3& p1, const Vector3& p2 ){
|
||||
_points[0] = p0;
|
||||
_points[1] = p1;
|
||||
_points[2] = p2;
|
||||
}
|
||||
const Vector3& operator[]( std::size_t i ) const {
|
||||
return _points[i];
|
||||
}
|
||||
Vector3& operator[]( std::size_t i ){
|
||||
return _points[i];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
void Clipper_setPlanePoints( const ClipperPoints& points );
|
||||
void Clipper_Construct();
|
||||
void Clipper_Destroy();
|
||||
void Clipper_modeChanged( bool isClipper );
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -741,17 +741,17 @@ void CSG_Subtract(){
|
|||
}
|
||||
}
|
||||
|
||||
#include "clippertool.h"
|
||||
class BrushSplitByPlaneSelected : public scene::Graph::Walker
|
||||
{
|
||||
const Vector3& m_p0;
|
||||
const Vector3& m_p1;
|
||||
const Vector3& m_p2;
|
||||
const Plane3 m_plane;
|
||||
const ClipperPoints m_points;
|
||||
const char* m_shader;
|
||||
const TextureProjection& m_projection;
|
||||
EBrushSplit m_split;
|
||||
const bool m_split; /* split or clip */
|
||||
public:
|
||||
BrushSplitByPlaneSelected( const Vector3& p0, const Vector3& p1, const Vector3& p2, const char* shader, const TextureProjection& projection, EBrushSplit split )
|
||||
: m_p0( p0 ), m_p1( p1 ), m_p2( p2 ), m_shader( shader ), m_projection( projection ), m_split( split ){
|
||||
BrushSplitByPlaneSelected( const ClipperPoints& points, const char* shader, const TextureProjection& projection, bool split )
|
||||
: m_plane( plane3_for_points( points._points ) ), m_points( points ), m_shader( shader ), m_projection( projection ), m_split( split ){
|
||||
}
|
||||
bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
||||
return true;
|
||||
|
|
@ -761,63 +761,55 @@ void post( const scene::Path& path, scene::Instance& instance ) const {
|
|||
Brush* brush = Node_getBrush( path.top() );
|
||||
if ( brush != 0
|
||||
&& Instance_getSelectable( instance )->isSelected() ) {
|
||||
Plane3 plane( plane3_for_points( m_p0, m_p1, m_p2 ) );
|
||||
if ( plane3_valid( plane ) ) {
|
||||
brushsplit_t split = Brush_classifyPlane( *brush, m_split == eFront ? plane3_flipped( plane ) : plane );
|
||||
if ( split.counts[ePlaneBack] && split.counts[ePlaneFront] ) {
|
||||
// the plane intersects this brush
|
||||
if ( m_split == eFrontAndBack ) {
|
||||
NodeSmartReference node( ( new BrushNode() )->node() );
|
||||
Brush* fragment = Node_getBrush( node );
|
||||
fragment->copy( *brush );
|
||||
Face* newFace = fragment->addPlane( m_p0, m_p1, m_p2, m_shader, m_projection );
|
||||
if ( newFace != 0 && m_split != eFront ) {
|
||||
newFace->flipWinding();
|
||||
}
|
||||
fragment->removeEmptyFaces();
|
||||
ASSERT_MESSAGE( !fragment->empty(), "brush left with no faces after split" );
|
||||
const brushsplit_t split = Brush_classifyPlane( *brush, m_plane );
|
||||
if ( split.counts[ePlaneBack] && split.counts[ePlaneFront] ) {
|
||||
// the plane intersects this brush
|
||||
if ( m_split ) {
|
||||
NodeSmartReference node( ( new BrushNode() )->node() );
|
||||
Brush* fragment = Node_getBrush( node );
|
||||
fragment->copy( *brush );
|
||||
fragment->addPlane( m_points[0], m_points[2], m_points[1], m_shader, m_projection ); /* flip plane points */
|
||||
fragment->removeEmptyFaces();
|
||||
ASSERT_MESSAGE( !fragment->empty(), "brush left with no faces after split" );
|
||||
|
||||
Node_getTraversable( path.parent() )->insert( node );
|
||||
{
|
||||
scene::Path fragmentPath = path;
|
||||
fragmentPath.top() = makeReference( node.get() );
|
||||
selectPath( fragmentPath, true );
|
||||
}
|
||||
Node_getTraversable( path.parent() )->insert( node );
|
||||
{
|
||||
scene::Path fragmentPath = path;
|
||||
fragmentPath.top() = makeReference( node.get() );
|
||||
selectPath( fragmentPath, true );
|
||||
}
|
||||
}
|
||||
|
||||
Face* newFace = brush->addPlane( m_p0, m_p1, m_p2, m_shader, m_projection );
|
||||
if ( newFace != 0 && m_split == eFront ) {
|
||||
newFace->flipWinding();
|
||||
}
|
||||
brush->removeEmptyFaces();
|
||||
ASSERT_MESSAGE( !brush->empty(), "brush left with no faces after split" );
|
||||
}
|
||||
else
|
||||
// the plane does not intersect this brush
|
||||
if ( m_split != eFrontAndBack && split.counts[ePlaneBack] != 0 ) {
|
||||
// the brush is "behind" the plane
|
||||
Path_deleteTop( path );
|
||||
}
|
||||
brush->addPlane( m_points[0], m_points[1], m_points[2], m_shader, m_projection );
|
||||
brush->removeEmptyFaces();
|
||||
ASSERT_MESSAGE( !brush->empty(), "brush left with no faces after split" );
|
||||
}
|
||||
else
|
||||
// the plane does not intersect this brush
|
||||
if ( !m_split && split.counts[ePlaneFront] != 0 ) {
|
||||
// the brush is "behind" the plane
|
||||
Path_deleteTop( path );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void Scene_BrushSplitByPlane( scene::Graph& graph, const Vector3& p0, const Vector3& p1, const Vector3& p2, const char* shader, EBrushSplit split ){
|
||||
void Scene_BrushSplitByPlane( scene::Graph& graph, const ClipperPoints& points, bool caulk, bool split ){
|
||||
const char* shader = caulk? GetCaulkShader() : TextureBrowser_GetSelectedShader( GlobalTextureBrowser() );
|
||||
TextureProjection projection;
|
||||
TexDef_Construct_Default( projection );
|
||||
graph.traverse( BrushSplitByPlaneSelected( p0, p1, p2, shader, projection, split ) );
|
||||
graph.traverse( BrushSplitByPlaneSelected( points, shader, projection, split ) );
|
||||
SceneChangeNotify();
|
||||
}
|
||||
|
||||
|
||||
class BrushInstanceSetClipPlane : public scene::Graph::Walker
|
||||
{
|
||||
Plane3 m_plane;
|
||||
const Plane3 m_plane;
|
||||
public:
|
||||
BrushInstanceSetClipPlane( const Plane3& plane )
|
||||
: m_plane( plane ){
|
||||
BrushInstanceSetClipPlane( const ClipperPoints& points )
|
||||
: m_plane( plane3_for_points( points._points ) ){
|
||||
}
|
||||
bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
||||
BrushInstance* brush = Instance_getBrush( instance );
|
||||
|
|
@ -831,8 +823,8 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const {
|
|||
}
|
||||
};
|
||||
|
||||
void Scene_BrushSetClipPlane( scene::Graph& graph, const Plane3& plane ){
|
||||
graph.traverse( BrushInstanceSetClipPlane( plane ) );
|
||||
void Scene_BrushSetClipPlane( scene::Graph& graph, const ClipperPoints& points ){
|
||||
graph.traverse( BrushInstanceSetClipPlane( points ) );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -31,17 +31,10 @@ namespace scene
|
|||
{
|
||||
class Graph;
|
||||
}
|
||||
template<typename Element> class BasicVector3;
|
||||
typedef BasicVector3<float> Vector3;
|
||||
class Plane3;
|
||||
|
||||
void Scene_BrushSetClipPlane( scene::Graph& graph, const Plane3& plane );
|
||||
enum EBrushSplit
|
||||
{
|
||||
eFront,
|
||||
eBack,
|
||||
eFrontAndBack,
|
||||
};
|
||||
void Scene_BrushSplitByPlane( scene::Graph& graph, const Vector3& p0, const Vector3& p1, const Vector3& p2, const char* shader, EBrushSplit split );
|
||||
class ClipperPoints;
|
||||
|
||||
void Scene_BrushSetClipPlane( scene::Graph& graph, const ClipperPoints& points );
|
||||
void Scene_BrushSplitByPlane( scene::Graph& graph, const ClipperPoints& points, bool caulk, bool split );
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1474,7 +1474,7 @@ void DragMode(){
|
|||
g_currentToolMode = DragMode;
|
||||
g_currentToolModeSupportsComponentEditing = true;
|
||||
|
||||
OnClipMode( false );
|
||||
// OnClipMode( false );
|
||||
|
||||
Sys_Status( c_ResizeMode_status );
|
||||
GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eDrag );
|
||||
|
|
@ -1495,7 +1495,7 @@ void TranslateMode(){
|
|||
g_currentToolMode = TranslateMode;
|
||||
g_currentToolModeSupportsComponentEditing = true;
|
||||
|
||||
OnClipMode( false );
|
||||
// OnClipMode( false );
|
||||
|
||||
Sys_Status( c_TranslateMode_status );
|
||||
GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eTranslate );
|
||||
|
|
@ -1515,7 +1515,7 @@ void RotateMode(){
|
|||
g_currentToolMode = RotateMode;
|
||||
g_currentToolModeSupportsComponentEditing = true;
|
||||
|
||||
OnClipMode( false );
|
||||
// OnClipMode( false );
|
||||
|
||||
Sys_Status( c_RotateMode_status );
|
||||
GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eRotate );
|
||||
|
|
@ -1535,7 +1535,7 @@ void ScaleMode(){
|
|||
g_currentToolMode = ScaleMode;
|
||||
g_currentToolModeSupportsComponentEditing = true;
|
||||
|
||||
OnClipMode( false );
|
||||
// OnClipMode( false );
|
||||
|
||||
Sys_Status( c_ScaleMode_status );
|
||||
GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eScale );
|
||||
|
|
@ -1555,7 +1555,7 @@ void SkewMode(){
|
|||
g_currentToolMode = SkewMode;
|
||||
g_currentToolModeSupportsComponentEditing = true;
|
||||
|
||||
OnClipMode( false );
|
||||
// OnClipMode( false );
|
||||
|
||||
Sys_Status( c_SkewMode_status );
|
||||
GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eSkew );
|
||||
|
|
@ -1579,7 +1579,7 @@ void ClipperMode(){
|
|||
|
||||
SelectionSystem_DefaultMode();
|
||||
|
||||
OnClipMode( true );
|
||||
// OnClipMode( true );
|
||||
|
||||
Sys_Status( c_ClipperMode_status );
|
||||
GlobalSelectionSystem().SetManipulatorMode( SelectionSystem::eClip );
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ typedef MemberCaller<MainFrame, &MainFrame::SetGridStatus> SetGridStatusCaller;
|
|||
void SetActiveXY( XYWnd* p );
|
||||
XYWnd* ActiveXY(){
|
||||
return m_pActiveXY;
|
||||
};
|
||||
}
|
||||
XYWnd* GetXYWnd(){
|
||||
return m_pXYWnd;
|
||||
}
|
||||
|
|
@ -127,10 +127,10 @@ CamWnd* GetCamWnd(){
|
|||
|
||||
EViewStyle CurrentStyle(){
|
||||
return m_nCurrentStyle;
|
||||
};
|
||||
}
|
||||
bool FloatingGroupDialog(){
|
||||
return CurrentStyle() == eFloating || CurrentStyle() == eSplit;
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
extern MainFrame* g_pParentWnd;
|
||||
|
|
|
|||
|
|
@ -206,7 +206,11 @@ class Manipulatable
|
|||
public:
|
||||
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, const bool alt ) = 0;
|
||||
static const View* m_view;
|
||||
static float m_device_epsilon[2];
|
||||
};
|
||||
const View* Manipulatable::m_view;
|
||||
float Manipulatable::m_device_epsilon[2];
|
||||
|
||||
void transform_local2object( Matrix4& object, const Matrix4& local, const Matrix4& local2object ){
|
||||
object = matrix4_multiplied_by_matrix4(
|
||||
|
|
@ -715,7 +719,6 @@ Vector3 m_size;
|
|||
float m_setSizeZ; /* store separately for fine square/cube modes handling */
|
||||
scene::Node* m_newBrushNode;
|
||||
public:
|
||||
const View* m_view;
|
||||
DragNewBrush(){
|
||||
}
|
||||
void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ){
|
||||
|
|
@ -1252,8 +1255,7 @@ class Manipulator
|
|||
{
|
||||
public:
|
||||
virtual Manipulatable* GetManipulatable() = 0;
|
||||
virtual void testSelect( const View& view, const Matrix4& pivot2world ){
|
||||
}
|
||||
virtual void testSelect( const View& view, const Matrix4& pivot2world ) = 0;
|
||||
virtual void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& pivot2world ){
|
||||
}
|
||||
virtual void setSelected( bool select ) = 0;
|
||||
|
|
@ -1430,7 +1432,7 @@ void testSelect( const View& view, const Matrix4& pivot2world ){
|
|||
|
||||
{
|
||||
{
|
||||
Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_local2world_x ) );
|
||||
const Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_local2world_x ) );
|
||||
|
||||
#if defined( DEBUG_SELECTION )
|
||||
g_render_clipped.construct( view.GetViewMatrix() );
|
||||
|
|
@ -1442,7 +1444,7 @@ void testSelect( const View& view, const Matrix4& pivot2world ){
|
|||
}
|
||||
|
||||
{
|
||||
Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_local2world_y ) );
|
||||
const Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_local2world_y ) );
|
||||
|
||||
#if defined( DEBUG_SELECTION )
|
||||
g_render_clipped.construct( view.GetViewMatrix() );
|
||||
|
|
@ -1454,7 +1456,7 @@ void testSelect( const View& view, const Matrix4& pivot2world ){
|
|||
}
|
||||
|
||||
{
|
||||
Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_local2world_z ) );
|
||||
const Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_local2world_z ) );
|
||||
|
||||
#if defined( DEBUG_SELECTION )
|
||||
g_render_clipped.construct( view.GetViewMatrix() );
|
||||
|
|
@ -1467,7 +1469,7 @@ void testSelect( const View& view, const Matrix4& pivot2world ){
|
|||
}
|
||||
|
||||
{
|
||||
Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_pivot.m_viewpointSpace ) );
|
||||
const Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_pivot.m_viewpointSpace ) );
|
||||
|
||||
{
|
||||
SelectionIntersection best;
|
||||
|
|
@ -1659,11 +1661,30 @@ static float& z( Triple& triple ){
|
|||
}
|
||||
};
|
||||
|
||||
void vector3_print( const Vector3& v ){
|
||||
globalOutputStream() << "( " << v.x() << " " << v.y() << " " << v.z() << " )";
|
||||
}
|
||||
class ManipulatorSelectionChangeable
|
||||
{
|
||||
Selectable* m_selectable_prev_ptr;
|
||||
public:
|
||||
ManipulatorSelectionChangeable() : m_selectable_prev_ptr( 0 ){
|
||||
}
|
||||
void selectionChange( SelectionPool& selector ){
|
||||
if ( !selector.failed() ) {
|
||||
( *selector.begin() ).second->setSelected( true );
|
||||
if( m_selectable_prev_ptr != ( *selector.begin() ).second ){
|
||||
m_selectable_prev_ptr = ( *selector.begin() ).second;
|
||||
SceneChangeNotify();
|
||||
}
|
||||
}
|
||||
else if( m_selectable_prev_ptr ){
|
||||
m_selectable_prev_ptr = 0;
|
||||
SceneChangeNotify();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class TranslateManipulator : public Manipulator
|
||||
|
||||
|
||||
class TranslateManipulator : public Manipulator, public ManipulatorSelectionChangeable
|
||||
{
|
||||
struct RenderableArrowLine : public OpenGLRenderable
|
||||
{
|
||||
|
|
@ -1730,7 +1751,6 @@ SelectableBool m_selectable_x;
|
|||
SelectableBool m_selectable_y;
|
||||
SelectableBool m_selectable_z;
|
||||
SelectableBool m_selectable_screen;
|
||||
Selectable* m_selectable_prev_ptr;
|
||||
Pivot2World m_pivot;
|
||||
public:
|
||||
static Shader* m_state_wire;
|
||||
|
|
@ -1741,8 +1761,7 @@ TranslateManipulator( Translatable& translatable, std::size_t segments, float le
|
|||
m_axis( translatable ),
|
||||
m_arrow_head_x( 3 * 2 * ( segments << 3 ) ),
|
||||
m_arrow_head_y( 3 * 2 * ( segments << 3 ) ),
|
||||
m_arrow_head_z( 3 * 2 * ( segments << 3 ) ),
|
||||
m_selectable_prev_ptr( 0 ){
|
||||
m_arrow_head_z( 3 * 2 * ( segments << 3 ) ){
|
||||
draw_arrowline( length, m_arrow_x.m_line, 0 );
|
||||
draw_arrowhead( segments, length, m_arrow_head_x.m_vertices.data(), TripleRemapXYZ<Vertex3f>(), TripleRemapXYZ<Normal3f>() );
|
||||
draw_arrowline( length, m_arrow_y.m_line, 1 );
|
||||
|
|
@ -1825,7 +1844,7 @@ void testSelect( const View& view, const Matrix4& pivot2world ){
|
|||
bool show_z = manipulator_show_axis( m_pivot, z );
|
||||
|
||||
{
|
||||
Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_pivot.m_viewpointSpace ) );
|
||||
const Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_pivot.m_viewpointSpace ) );
|
||||
|
||||
{
|
||||
SelectionIntersection best;
|
||||
|
|
@ -1838,7 +1857,7 @@ void testSelect( const View& view, const Matrix4& pivot2world ){
|
|||
}
|
||||
|
||||
{
|
||||
Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_pivot.m_worldSpace ) );
|
||||
const Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_pivot.m_worldSpace ) );
|
||||
|
||||
#if defined( DEBUG_SELECTION )
|
||||
g_render_clipped.construct( view.GetViewMatrix() );
|
||||
|
|
@ -1866,17 +1885,7 @@ void testSelect( const View& view, const Matrix4& pivot2world ){
|
|||
}
|
||||
}
|
||||
|
||||
if ( !selector.failed() ) {
|
||||
( *selector.begin() ).second->setSelected( true );
|
||||
if( m_selectable_prev_ptr != ( *selector.begin() ).second ){
|
||||
m_selectable_prev_ptr = ( *selector.begin() ).second;
|
||||
SceneChangeNotify();
|
||||
}
|
||||
}
|
||||
else if( m_selectable_prev_ptr ){
|
||||
m_selectable_prev_ptr = 0;
|
||||
SceneChangeNotify();
|
||||
}
|
||||
selectionChange( selector );
|
||||
}
|
||||
|
||||
Manipulatable* GetManipulatable(){
|
||||
|
|
@ -1915,7 +1924,7 @@ bool isSelected() const {
|
|||
Shader* TranslateManipulator::m_state_wire;
|
||||
Shader* TranslateManipulator::m_state_fill;
|
||||
|
||||
class ScaleManipulator : public Manipulator
|
||||
class ScaleManipulator : public Manipulator, public ManipulatorSelectionChangeable
|
||||
{
|
||||
struct RenderableArrow : public OpenGLRenderable
|
||||
{
|
||||
|
|
@ -1957,13 +1966,11 @@ SelectableBool m_selectable_x;
|
|||
SelectableBool m_selectable_y;
|
||||
SelectableBool m_selectable_z;
|
||||
SelectableBool m_selectable_screen;
|
||||
Selectable* m_selectable_prev_ptr;
|
||||
Pivot2World m_pivot;
|
||||
public:
|
||||
ScaleManipulator( Scalable& scalable, std::size_t segments, float length ) :
|
||||
m_free( scalable ),
|
||||
m_axis( scalable ),
|
||||
m_selectable_prev_ptr( 0 ){
|
||||
m_axis( scalable ){
|
||||
draw_arrowline( length, m_arrow_x.m_line, 0 );
|
||||
draw_arrowline( length, m_arrow_y.m_line, 1 );
|
||||
draw_arrowline( length, m_arrow_z.m_line, 2 );
|
||||
|
|
@ -1996,7 +2003,7 @@ void testSelect( const View& view, const Matrix4& pivot2world ){
|
|||
SelectionPool selector;
|
||||
|
||||
{
|
||||
Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_pivot.m_worldSpace ) );
|
||||
const Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_pivot.m_worldSpace ) );
|
||||
|
||||
#if defined( DEBUG_SELECTION )
|
||||
g_render_clipped.construct( view.GetViewMatrix() );
|
||||
|
|
@ -2022,7 +2029,7 @@ void testSelect( const View& view, const Matrix4& pivot2world ){
|
|||
}
|
||||
|
||||
{
|
||||
Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_pivot.m_viewpointSpace ) );
|
||||
const Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_pivot.m_viewpointSpace ) );
|
||||
|
||||
{
|
||||
SelectionIntersection best;
|
||||
|
|
@ -2031,17 +2038,7 @@ void testSelect( const View& view, const Matrix4& pivot2world ){
|
|||
}
|
||||
}
|
||||
|
||||
if ( !selector.failed() ) {
|
||||
( *selector.begin() ).second->setSelected( true );
|
||||
if( m_selectable_prev_ptr != ( *selector.begin() ).second ){
|
||||
m_selectable_prev_ptr = ( *selector.begin() ).second;
|
||||
SceneChangeNotify();
|
||||
}
|
||||
}
|
||||
else if( m_selectable_prev_ptr ){
|
||||
m_selectable_prev_ptr = 0;
|
||||
SceneChangeNotify();
|
||||
}
|
||||
selectionChange( selector );
|
||||
}
|
||||
|
||||
Manipulatable* GetManipulatable(){
|
||||
|
|
@ -2078,7 +2075,8 @@ bool isSelected() const {
|
|||
};
|
||||
|
||||
|
||||
class SkewManipulator : public Manipulator {
|
||||
class SkewManipulator : public Manipulator
|
||||
{
|
||||
struct RenderableLine : public OpenGLRenderable {
|
||||
PointVertex m_line[2];
|
||||
|
||||
|
|
@ -2315,7 +2313,7 @@ public:
|
|||
|
||||
SelectionPool selector;
|
||||
|
||||
Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_worldSpace ) );
|
||||
const Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_worldSpace ) );
|
||||
/* try corner points to rotate */
|
||||
for ( int i = 0; i < 3; ++i )
|
||||
for ( int j = 0; j < 2; ++j )
|
||||
|
|
@ -3578,10 +3576,6 @@ Manipulatable* GetManipulatable(){
|
|||
return m_dragSelected? &m_freeDrag : &m_freeResize;
|
||||
}
|
||||
|
||||
void setView( const View& view ){
|
||||
m_dragNewBrush.m_view = &view;
|
||||
}
|
||||
|
||||
void testSelect( const View& view, const Matrix4& pivot2world ){
|
||||
SelectionPool selector;
|
||||
SelectionVolume test( view );
|
||||
|
|
@ -3661,21 +3655,225 @@ bool isSelected() const {
|
|||
}
|
||||
};
|
||||
|
||||
class ClipManipulator : public Manipulator
|
||||
|
||||
|
||||
#include "clippertool.h"
|
||||
|
||||
class ClipManipulator : public Manipulator, public ManipulatorSelectionChangeable, public Translatable, public Manipulatable
|
||||
{
|
||||
struct ClipperPoint : public OpenGLRenderable, public SelectableBool
|
||||
{
|
||||
PointVertex m_p; //for render
|
||||
ClipperPoint():
|
||||
m_p( vertex3f_identity ), m_set( false ) {
|
||||
}
|
||||
void render( RenderStateFlags state ) const {
|
||||
glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_p.colour );
|
||||
glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_p.vertex );
|
||||
glDrawArrays( GL_POINTS, 0, 1 );
|
||||
|
||||
glColor4ub( m_p.colour.r, m_p.colour.g, m_p.colour.b, m_p.colour.a ); ///?
|
||||
glRasterPos3f( m_namePos.x(), m_namePos.y(), m_namePos.z() );
|
||||
GlobalOpenGL().drawChar( m_name );
|
||||
}
|
||||
void setColour( const Colour4b& colour ) {
|
||||
m_p.colour = colour;
|
||||
}
|
||||
bool m_set;
|
||||
Vector3 m_point;
|
||||
Vector3 m_pointNonTransformed;
|
||||
char m_name;
|
||||
Vector3 m_namePos;
|
||||
};
|
||||
Matrix4& m_pivot2world;
|
||||
ClipperPoint m_points[3];
|
||||
TranslateFree m_drag2d;
|
||||
const AABB& m_bounds;
|
||||
Vector3 m_viewdir;
|
||||
public:
|
||||
static Shader* m_state;
|
||||
|
||||
Manipulatable* GetManipulatable(){
|
||||
ERROR_MESSAGE( "clipper is not manipulatable" );
|
||||
return 0;
|
||||
}
|
||||
ClipManipulator( Matrix4& pivot2world, const AABB& bounds ) : m_pivot2world( pivot2world ), m_drag2d( *this ), m_bounds( bounds ){
|
||||
m_points[0].m_name = '1';
|
||||
m_points[1].m_name = '2';
|
||||
m_points[2].m_name = '3';
|
||||
}
|
||||
|
||||
void setSelected( bool select ){
|
||||
}
|
||||
bool isSelected() const {
|
||||
return false;
|
||||
}
|
||||
void UpdateColours() {
|
||||
for( std::size_t i = 0; i < 3; ++i )
|
||||
m_points[i].setColour( colourSelected( g_colour_screen, m_points[i].isSelected() ) );
|
||||
}
|
||||
|
||||
void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& pivot2world ) {
|
||||
// temp hack
|
||||
UpdateColours();
|
||||
|
||||
renderer.SetState( m_state, Renderer::eWireframeOnly );
|
||||
renderer.SetState( m_state, Renderer::eFullMaterials );
|
||||
|
||||
const Matrix4 proj( matrix4_multiplied_by_matrix4( volume.GetViewport(), volume.GetViewMatrix() ) );
|
||||
const Matrix4 proj_inv( matrix4_full_inverse( proj ) );
|
||||
for( std::size_t i = 0; i < 3; ++i )
|
||||
if( m_points[i].m_set ){
|
||||
m_points[i].m_p.vertex = vertex3f_for_vector3( m_points[i].m_point );
|
||||
renderer.addRenderable( m_points[i], g_matrix4_identity );
|
||||
const Vector3 pos = vector4_projected( matrix4_transformed_vector4( proj, Vector4( m_points[i].m_point, 1 ) ) ) + Vector3( 3, 4, 0 );
|
||||
m_points[i].m_namePos = vector4_projected( matrix4_transformed_vector4( proj_inv, Vector4( pos, 1 ) ) );
|
||||
}
|
||||
}
|
||||
void updatePlane(){
|
||||
if( m_points[0].m_set && m_points[1].m_set ){
|
||||
if( !m_points[2].m_set ){
|
||||
m_points[2].m_point = m_points[0].m_point + m_viewdir * vector3_length( m_points[0].m_point - m_points[1].m_point );
|
||||
}
|
||||
Clipper_setPlanePoints( ClipperPoints( m_points[0].m_point, m_points[1].m_point, m_points[2].m_point ) );
|
||||
}
|
||||
else{
|
||||
Clipper_setPlanePoints( ClipperPoints( g_vector3_identity, g_vector3_identity, g_vector3_identity ) );
|
||||
}
|
||||
}
|
||||
std::size_t newPointIndex() const {
|
||||
std::size_t i;
|
||||
for( i = 0; i < 3; ++i )
|
||||
if( !m_points[i].m_set )
|
||||
break;
|
||||
return i;
|
||||
}
|
||||
void newPoint( const Vector3& point, const View& view ){
|
||||
{ /* update m_viewdir */
|
||||
const Vector3 viewdir( Vector3( fabs( view.GetModelview()[2] ), fabs( view.GetModelview()[6] ), fabs( view.GetModelview()[10] ) ) );
|
||||
std::size_t maxi = 0;
|
||||
for( std::size_t i = 1; i < 3; ++i )
|
||||
if( viewdir[i] > viewdir[maxi] )
|
||||
maxi = i;
|
||||
m_viewdir = ( view.GetModelview()[2 + 4 * maxi] > 0 )? g_vector3_axes[maxi] : -g_vector3_axes[maxi];
|
||||
if( view.fill() ) //viewdir, taken this way in perspective view is negative for some reason
|
||||
m_viewdir *= -1;
|
||||
}
|
||||
std::size_t i = newPointIndex();
|
||||
if( i == 3 ){
|
||||
i = 0;
|
||||
m_points[1].m_set = m_points[2].m_set = false;
|
||||
}
|
||||
m_points[i].m_set = true;
|
||||
m_points[i].m_point = point;
|
||||
|
||||
SelectionPool selector;
|
||||
selector.addSelectable( SelectionIntersection( 0, 0 ), &m_points[i] );
|
||||
selectionChange( selector );
|
||||
|
||||
updatePlane();
|
||||
}
|
||||
void testSelect( const View& view, const Matrix4& pivot2world ) {
|
||||
testSelect_points( view );
|
||||
if( !isSelected() ){
|
||||
if( view.fill() ){
|
||||
SelectionVolume test( view );
|
||||
BestPointSelector bestPointSelector;
|
||||
Scene_TestSelect_Primitive( bestPointSelector, test, view );
|
||||
test.BeginMesh( g_matrix4_identity, true );
|
||||
if( bestPointSelector.isSelected() ){
|
||||
Vector3 point = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, bestPointSelector.best().depth(), 1 ) ) );
|
||||
vector3_snap( point, GetSnapGridSize() );
|
||||
newPoint( point, view );
|
||||
}
|
||||
}
|
||||
else{
|
||||
const Vector3 viewdir( Vector3( fabs( view.GetModelview()[2] ), fabs( view.GetModelview()[6] ), fabs( view.GetModelview()[10] ) ) );
|
||||
std::size_t maxi = 0;
|
||||
for( std::size_t i = 1; i < 3; ++i )
|
||||
if( viewdir[i] > viewdir[maxi] )
|
||||
maxi = i;
|
||||
Vector3 point = vector4_projected( matrix4_transformed_vector4( matrix4_full_inverse( view.GetViewMatrix() ), Vector4( 0, 0, 0, 1 ) ) );
|
||||
vector3_snap( point, GetSnapGridSize() );
|
||||
{
|
||||
const std::size_t i = newPointIndex() % 3;
|
||||
point[maxi] = m_bounds.origin[maxi] + ( i == 2? -1 : 1 ) * m_bounds.extents[maxi];
|
||||
}
|
||||
newPoint( point, view );
|
||||
}
|
||||
}
|
||||
for( std::size_t i = 0; i < 3; ++i )
|
||||
if( m_points[i].isSelected() ){
|
||||
m_points[i].m_pointNonTransformed = m_points[i].m_point;
|
||||
m_pivot2world = matrix4_translation_for_vec3( m_points[i].m_pointNonTransformed );
|
||||
break;
|
||||
}
|
||||
}
|
||||
void testSelect_points( const View& view ) {
|
||||
SelectionPool selector;
|
||||
{
|
||||
const Matrix4 local2view( view.GetViewMatrix() );
|
||||
|
||||
for( std::size_t i = 0; i < 3; ++i ){
|
||||
if( m_points[i].m_set ){
|
||||
SelectionIntersection best;
|
||||
Point_BestPoint( local2view, PointVertex( vertex3f_for_vector3( m_points[i].m_point ) ), best );
|
||||
selector.addSelectable( best, &m_points[i] );
|
||||
}
|
||||
}
|
||||
}
|
||||
selectionChange( selector );
|
||||
}
|
||||
void reset(){
|
||||
for( std::size_t i = 0; i < 3; ++i ){
|
||||
m_points[i].m_set = false;
|
||||
m_points[i].setSelected( false ); ///?
|
||||
}
|
||||
updatePlane();
|
||||
}
|
||||
/* Translatable */
|
||||
void translate( const Vector3& translation ){ //in 2d
|
||||
for( std::size_t i = 0; i < 3; ++i )
|
||||
if( m_points[i].isSelected() ){
|
||||
m_points[i].m_point = m_points[i].m_pointNonTransformed + translation;
|
||||
updatePlane();
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Manipulatable */
|
||||
void Construct( const Matrix4& device2manip, const float x, const float y, const AABB& bounds, const Vector3& transform_origin ){
|
||||
}
|
||||
void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const float x, const float y, const bool snap, const bool snapbbox, const bool alt ){ //in 3d
|
||||
View scissored( *m_view );
|
||||
const float device_point[2] = { x, y };
|
||||
ConstructSelectionTest( scissored, SelectionBoxForPoint( device_point, m_device_epsilon ) );
|
||||
|
||||
SelectionVolume test( scissored );
|
||||
BestPointSelector bestPointSelector;
|
||||
Scene_TestSelect_Primitive( bestPointSelector, test, scissored );
|
||||
test.BeginMesh( g_matrix4_identity, true );
|
||||
if( bestPointSelector.isSelected() ){
|
||||
Vector3 point = vector4_projected( matrix4_transformed_vector4( test.getScreen2world(), Vector4( 0, 0, bestPointSelector.best().depth(), 1 ) ) );
|
||||
vector3_snap( point, GetSnapGridSize() );
|
||||
for( std::size_t i = 0; i < 3; ++i )
|
||||
if( m_points[i].isSelected() ){
|
||||
m_points[i].m_point = point;
|
||||
updatePlane();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Manipulatable* GetManipulatable() {
|
||||
if( m_view->fill() )
|
||||
return this;
|
||||
else
|
||||
return &m_drag2d;
|
||||
}
|
||||
|
||||
void setSelected( bool select ) {
|
||||
for( std::size_t i = 0; i < 3; ++i )
|
||||
m_points[i].setSelected( select );
|
||||
}
|
||||
bool isSelected() const {
|
||||
return m_points[0].isSelected() || m_points[1].isSelected() || m_points[2].isSelected();
|
||||
}
|
||||
};
|
||||
Shader* ClipManipulator::m_state;
|
||||
|
||||
|
||||
|
||||
|
||||
class TransformOriginTranslatable
|
||||
{
|
||||
|
|
@ -3724,7 +3922,8 @@ void Transform( const Matrix4& manip2object, const Matrix4& device2manip, const
|
|||
}
|
||||
};
|
||||
|
||||
class TransformOriginManipulator : public Manipulator {
|
||||
class TransformOriginManipulator : public Manipulator, public ManipulatorSelectionChangeable
|
||||
{
|
||||
struct RenderablePoint : public OpenGLRenderable
|
||||
{
|
||||
PointVertex m_point;
|
||||
|
|
@ -3745,15 +3944,13 @@ class TransformOriginManipulator : public Manipulator {
|
|||
const bool& m_pivotIsCustom;
|
||||
RenderablePoint m_point;
|
||||
SelectableBool m_selectable;
|
||||
Selectable* m_selectable_prev_ptr;
|
||||
Pivot2World m_pivot;
|
||||
public:
|
||||
static Shader* m_state;
|
||||
|
||||
TransformOriginManipulator( TransformOriginTranslatable& transformOriginTranslatable, const bool& pivotIsCustom ) :
|
||||
m_translate( transformOriginTranslatable ),
|
||||
m_pivotIsCustom( pivotIsCustom ),
|
||||
m_selectable_prev_ptr( 0 ) {
|
||||
m_pivotIsCustom( pivotIsCustom ){
|
||||
}
|
||||
|
||||
void UpdateColours() {
|
||||
|
|
@ -3781,7 +3978,7 @@ public:
|
|||
|
||||
SelectionPool selector;
|
||||
{
|
||||
Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_pivot.m_worldSpace ) );
|
||||
const Matrix4 local2view( matrix4_multiplied_by_matrix4( view.GetViewMatrix(), m_pivot.m_worldSpace ) );
|
||||
|
||||
#if defined( DEBUG_SELECTION )
|
||||
g_render_clipped.construct( view.GetViewMatrix() );
|
||||
|
|
@ -3794,17 +3991,7 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
if ( !selector.failed() ) {
|
||||
( *selector.begin() ).second->setSelected( true );
|
||||
if( m_selectable_prev_ptr != ( *selector.begin() ).second ){
|
||||
m_selectable_prev_ptr = ( *selector.begin() ).second;
|
||||
SceneChangeNotify();
|
||||
}
|
||||
}
|
||||
else if( m_selectable_prev_ptr ){
|
||||
m_selectable_prev_ptr = 0;
|
||||
SceneChangeNotify();
|
||||
}
|
||||
selectionChange( selector );
|
||||
}
|
||||
|
||||
Manipulatable* GetManipulatable() {
|
||||
|
|
@ -3943,6 +4130,7 @@ RadiantSelectionSystem() :
|
|||
m_rotate_manipulator( *this, 8, 64 ),
|
||||
m_scale_manipulator( *this, 0, 64 ),
|
||||
m_skew_manipulator( *this, *this, *this, *this, m_bounds, m_pivot2world, m_pivotIsCustom ),
|
||||
m_clip_manipulator( m_pivot2world, m_bounds ),
|
||||
m_transformOrigin_manipulator( *this, m_pivotIsCustom ),
|
||||
m_pivotChanged( false ),
|
||||
m_pivot_moving( false ),
|
||||
|
|
@ -3978,6 +4166,10 @@ EComponentMode ComponentMode() const {
|
|||
return m_componentmode;
|
||||
}
|
||||
void SetManipulatorMode( EManipulatorMode mode ){
|
||||
if( ( mode == eClip ) != ( ManipulatorMode() == eClip ) ){
|
||||
Clipper_modeChanged( mode == eClip );
|
||||
}
|
||||
|
||||
m_pivotIsCustom = false;
|
||||
m_manipulator_mode = mode;
|
||||
switch ( m_manipulator_mode )
|
||||
|
|
@ -3987,7 +4179,12 @@ void SetManipulatorMode( EManipulatorMode mode ){
|
|||
case eScale: m_manipulator = &m_scale_manipulator; break;
|
||||
case eSkew: m_manipulator = &m_skew_manipulator; break;
|
||||
case eDrag: m_manipulator = &m_drag_manipulator; break;
|
||||
case eClip: m_manipulator = &m_clip_manipulator; break;
|
||||
case eClip:
|
||||
{
|
||||
m_manipulator = &m_clip_manipulator;
|
||||
m_clip_manipulator.reset();
|
||||
break;
|
||||
}
|
||||
}
|
||||
pivotChanged();
|
||||
}
|
||||
|
|
@ -4084,7 +4281,7 @@ void startMove(){
|
|||
bool SelectManipulator( const View& view, const float device_point[2], const float device_epsilon[2] ){
|
||||
bool movingOrigin = false;
|
||||
|
||||
if ( !nothingSelected() || ManipulatorMode() == eDrag ) {
|
||||
if ( !nothingSelected() || ManipulatorMode() == eDrag || ManipulatorMode() == eClip ) {
|
||||
#if defined ( DEBUG_SELECTION )
|
||||
g_render_clipped.destroy();
|
||||
#endif
|
||||
|
|
@ -4118,9 +4315,11 @@ bool SelectManipulator( const View& view, const float device_point[2], const flo
|
|||
Matrix4 device2manip;
|
||||
ConstructDevice2Manip( device2manip, m_pivot2world_start, view.GetModelview(), view.GetProjection(), view.GetViewport() );
|
||||
if( m_pivot_moving ){
|
||||
m_manipulator->GetManipulatable()->Construct( device2manip, device_point[0], device_point[1], m_bounds, vector4_to_vector3( GetPivot2World().t() ) );
|
||||
Manipulatable::m_view = &view; //this b4 GetManipulatable()!
|
||||
Manipulatable::m_device_epsilon[0] = device_epsilon[0];
|
||||
Manipulatable::m_device_epsilon[1] = device_epsilon[1];
|
||||
|
||||
m_drag_manipulator.setView( view ); //hack, sorta
|
||||
m_manipulator->GetManipulatable()->Construct( device2manip, device_point[0], device_point[1], m_bounds, vector4_to_vector3( GetPivot2World().t() ) );
|
||||
|
||||
m_undo_begun = false;
|
||||
}
|
||||
|
|
@ -4136,7 +4335,7 @@ bool SelectManipulator( const View& view, const float device_point[2], const flo
|
|||
}
|
||||
|
||||
void HighlightManipulator( const View& view, const float device_point[2], const float device_epsilon[2] ){
|
||||
if ( !nothingSelected() && transformOrigin_isTranslatable() ) {
|
||||
if ( ( !nothingSelected() && transformOrigin_isTranslatable() ) || ManipulatorMode() == eClip ) {
|
||||
#if defined ( DEBUG_SELECTION )
|
||||
g_render_clipped.destroy();
|
||||
#endif
|
||||
|
|
@ -4147,10 +4346,15 @@ void HighlightManipulator( const View& view, const float device_point[2], const
|
|||
View scissored( view );
|
||||
ConstructSelectionTest( scissored, SelectionBoxForPoint( device_point, device_epsilon ) );
|
||||
|
||||
m_transformOrigin_manipulator.testSelect( scissored, GetPivot2World() );
|
||||
if( transformOrigin_isTranslatable() ){
|
||||
m_transformOrigin_manipulator.testSelect( scissored, GetPivot2World() );
|
||||
|
||||
if( !m_transformOrigin_manipulator.isSelected() )
|
||||
m_manipulator->testSelect( scissored, GetPivot2World() );
|
||||
if( !m_transformOrigin_manipulator.isSelected() )
|
||||
m_manipulator->testSelect( scissored, GetPivot2World() );
|
||||
}
|
||||
else if( ManipulatorMode() == eClip ){
|
||||
m_clip_manipulator.testSelect_points( scissored );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4598,6 +4802,7 @@ static void constructStatic(){
|
|||
TranslateManipulator::m_state_fill =
|
||||
SkewManipulator::m_state_fill = GlobalShaderCache().capture( "$FLATSHADE_OVERLAY" );
|
||||
TransformOriginManipulator::m_state =
|
||||
ClipManipulator::m_state =
|
||||
SkewManipulator::m_state_point = GlobalShaderCache().capture( "$BIGPOINT" );
|
||||
}
|
||||
|
||||
|
|
@ -5019,7 +5224,7 @@ AABB RadiantSelectionSystem::getSelectionAABB() const {
|
|||
|
||||
void RadiantSelectionSystem::renderSolid( Renderer& renderer, const VolumeTest& volume ) const {
|
||||
//if(view->TestPoint(m_object_pivot))
|
||||
if ( !nothingSelected() ) {
|
||||
if ( !nothingSelected() || ManipulatorMode() == eClip ) {
|
||||
renderer.Highlight( Renderer::ePrimitive, false );
|
||||
renderer.Highlight( Renderer::eFace, false );
|
||||
|
||||
|
|
@ -5468,7 +5673,8 @@ void onMouseUp( const WindowVector& position, ButtonIdentifier button, ModifierF
|
|||
&& modifiers == c_modifierNone
|
||||
&& !m_selector.m_mouseMovedWhilePressed
|
||||
&& !m_manipulator.m_moving_transformOrigin
|
||||
&& !( getSelectionSystem().Mode() == SelectionSystem::eComponent && getSelectionSystem().ManipulatorMode() == SelectionSystem::eDrag ) ){
|
||||
&& !( getSelectionSystem().Mode() == SelectionSystem::eComponent && getSelectionSystem().ManipulatorMode() == SelectionSystem::eDrag )
|
||||
&& getSelectionSystem().ManipulatorMode() != SelectionSystem::eClip ){
|
||||
m_selector.testSelect_simpleM1( device( position ) );
|
||||
}
|
||||
m_manipulator.m_moving_transformOrigin = false;
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ void PlanePointsFromClipPoints( Vector3 planepts[3], const AABB& bounds, VIEWTYP
|
|||
void Clip_Update(){
|
||||
Vector3 planepts[3];
|
||||
if ( !GlobalClipPoints_valid() ) {
|
||||
Scene_BrushSetClipPlane( GlobalSceneGraph(), Plane3( 0, 0, 0, 0 ) );
|
||||
// Scene_BrushSetClipPlane( GlobalSceneGraph(), Plane3( 0, 0, 0, 0 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -243,7 +243,7 @@ void Clip_Update(){
|
|||
if ( g_bSwitch ) {
|
||||
std::swap( planepts[0], planepts[1] );
|
||||
}
|
||||
Scene_BrushSetClipPlane( GlobalSceneGraph(), plane3_for_points( planepts[0], planepts[1], planepts[2] ) );
|
||||
// Scene_BrushSetClipPlane( GlobalSceneGraph(), plane3_for_points( planepts[0], planepts[1], planepts[2] ) );
|
||||
}
|
||||
ClipperChangeNotify();
|
||||
}
|
||||
|
|
@ -259,7 +259,7 @@ void Clip(){
|
|||
Vector3 planepts[3];
|
||||
AABB bounds( Vector3( 0, 0, 0 ), Vector3( 64, 64, 64 ) );
|
||||
PlanePointsFromClipPoints( planepts, bounds, g_clip_viewtype );
|
||||
Scene_BrushSplitByPlane( GlobalSceneGraph(), planepts[0], planepts[1], planepts[2], Clip_getShader(), ( !g_bSwitch ) ? eFront : eBack );
|
||||
// Scene_BrushSplitByPlane( GlobalSceneGraph(), planepts[0], planepts[1], planepts[2], Clip_getShader(), ( !g_bSwitch ) ? eFront : eBack );
|
||||
g_Clip1.Reset();
|
||||
g_Clip2.Reset();
|
||||
g_Clip3.Reset();
|
||||
|
|
@ -276,7 +276,7 @@ void SplitClip(){
|
|||
Vector3 planepts[3];
|
||||
AABB bounds( Vector3( 0, 0, 0 ), Vector3( 64, 64, 64 ) );
|
||||
PlanePointsFromClipPoints( planepts, bounds, g_clip_viewtype );
|
||||
Scene_BrushSplitByPlane( GlobalSceneGraph(), planepts[0], planepts[1], planepts[2], Clip_getShader(), eFrontAndBack );
|
||||
// Scene_BrushSplitByPlane( GlobalSceneGraph(), planepts[0], planepts[1], planepts[2], Clip_getShader(), eFrontAndBack );
|
||||
g_Clip1.Reset();
|
||||
g_Clip2.Reset();
|
||||
g_Clip3.Reset();
|
||||
|
|
@ -1515,15 +1515,15 @@ void XYWnd::XY_MouseDown( int x, int y, unsigned int buttons ){
|
|||
else if ( buttons == Zoom_buttons() ) {
|
||||
Zoom_Begin( x, y );
|
||||
}
|
||||
else if ( ClipMode() && ( buttons == Clipper_buttons() || buttons == Clipper_quick_buttons() ) ) {
|
||||
Clipper_OnLButtonDown( x, y );
|
||||
}
|
||||
// else if ( ClipMode() && ( buttons == Clipper_buttons() || buttons == Clipper_quick_buttons() ) ) {
|
||||
// Clipper_OnLButtonDown( x, y );
|
||||
// }
|
||||
else if ( !ClipMode() && buttons == Clipper_quick_buttons() ) {
|
||||
ClipperMode();
|
||||
g_quick_clipper = true;
|
||||
Clipper_OnLButtonDown( x, y );
|
||||
}
|
||||
else if ( buttons == NewBrushDrag_buttons() && GlobalSelectionSystem().countSelected() == 0 ) {
|
||||
else if ( buttons == NewBrushDrag_buttons() && GlobalSelectionSystem().countSelected() == 0 && !ClipMode() ) {
|
||||
NewBrushDrag_Begin( x, y );
|
||||
}
|
||||
// control mbutton = move camera
|
||||
|
|
@ -1551,11 +1551,11 @@ void XYWnd::XY_MouseUp( int x, int y, unsigned int buttons ){
|
|||
else if ( m_zoom_started ) {
|
||||
Zoom_End();
|
||||
}
|
||||
else if ( ( ClipMode() && ( buttons == Clipper_buttons() || buttons == Clipper_quick_buttons() || g_pMovingClip ) ) ||
|
||||
g_clipper_doubleclicked ){ // handle mouse release, if quit quick clipper mode via doubleclick
|
||||
Clipper_OnLButtonUp( x, y );
|
||||
g_clipper_doubleclicked = false;
|
||||
}
|
||||
// else if ( ( ClipMode() && ( buttons == Clipper_buttons() || buttons == Clipper_quick_buttons() || g_pMovingClip ) ) ||
|
||||
// g_clipper_doubleclicked ){ // handle mouse release, if quit quick clipper mode via doubleclick
|
||||
// Clipper_OnLButtonUp( x, y );
|
||||
// g_clipper_doubleclicked = false;
|
||||
// }
|
||||
else if ( m_bNewBrushDrag ) {
|
||||
m_bNewBrushDrag = false;
|
||||
NewBrushDrag_End( x, y );
|
||||
|
|
@ -1578,9 +1578,9 @@ void XYWnd::XY_MouseMoved( int x, int y, unsigned int buttons ){
|
|||
else if ( m_zoom_started ) {
|
||||
}
|
||||
|
||||
else if ( ClipMode() && g_pMovingClip != 0 ) {
|
||||
Clipper_OnMouseMoved( x, y, buttons & RAD_SHIFT );
|
||||
}
|
||||
// else if ( ClipMode() && g_pMovingClip != 0 ) {
|
||||
// Clipper_OnMouseMoved( x, y, buttons & RAD_SHIFT );
|
||||
// }
|
||||
// lbutton without selection = drag new brush
|
||||
else if ( m_bNewBrushDrag ) {
|
||||
NewBrushDrag( x, y, buttons & RAD_SHIFT, buttons & RAD_CONTROL );
|
||||
|
|
@ -1620,9 +1620,9 @@ void XYWnd::XY_MouseMoved( int x, int y, unsigned int buttons ){
|
|||
XYWnd_Update( *this );
|
||||
}
|
||||
|
||||
if( ClipMode() ){
|
||||
Clipper_Crosshair_OnMouseMoved( x, y );
|
||||
}
|
||||
// if( ClipMode() ){
|
||||
// Clipper_Crosshair_OnMouseMoved( x, y );
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2805,9 +2805,9 @@ void XYWnd::XY_Draw(){
|
|||
glEnd();
|
||||
}
|
||||
|
||||
if ( ClipMode() ) {
|
||||
GlobalClipPoints_Draw( m_fScale );
|
||||
}
|
||||
// if ( ClipMode() ) {
|
||||
// GlobalClipPoints_Draw( m_fScale );
|
||||
// }
|
||||
|
||||
GlobalOpenGL_debugAssertNoErrors();
|
||||
|
||||
|
|
@ -3353,17 +3353,6 @@ void Orthographic_registerPreferencesPage(){
|
|||
PreferencesDialog_addSettingsPage( FreeCaller1<PreferenceGroup&, Orthographic_constructPage>() );
|
||||
}
|
||||
|
||||
void Clipper_constructPreferences( PreferencesPage& page ){
|
||||
page.appendCheckBox( "", "Clipper tool uses caulk", g_clip_useCaulk );
|
||||
}
|
||||
void Clipper_constructPage( PreferenceGroup& group ){
|
||||
PreferencesPage page( group.createPage( "Clipper", "Clipper Tool Settings" ) );
|
||||
Clipper_constructPreferences( page );
|
||||
}
|
||||
void Clipper_registerPreferencesPage(){
|
||||
PreferencesDialog_addSettingsPage( FreeCaller1<PreferenceGroup&, Clipper_constructPage>() );
|
||||
}
|
||||
|
||||
|
||||
#include "preferencesystem.h"
|
||||
#include "stringio.h"
|
||||
|
|
@ -3387,8 +3376,6 @@ void XYWindow_Construct(){
|
|||
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 ) );
|
||||
|
||||
// GlobalPreferenceSystem().registerPreference( "NewRightClick", BoolImportStringCaller( g_xywindow_globals.m_bRightClick ), BoolExportStringCaller( g_xywindow_globals.m_bRightClick ) );
|
||||
GlobalPreferenceSystem().registerPreference( "XYMSAA", IntImportStringCaller( g_xywindow_globals_private.m_MSAA ), IntExportStringCaller( g_xywindow_globals_private.m_MSAA ) );
|
||||
GlobalPreferenceSystem().registerPreference( "2DZoomInToPointer", BoolImportStringCaller( g_xywindow_globals.m_bZoomInToPointer ), BoolExportStringCaller( g_xywindow_globals.m_bZoomInToPointer ) );
|
||||
|
|
@ -3421,7 +3408,6 @@ void XYWindow_Construct(){
|
|||
GlobalPreferenceSystem().registerPreference( "YZVIS", makeBoolStringImportCallback( ToggleShownImportBoolCaller( g_yz_side_shown ) ), makeBoolStringExportCallback( ToggleShownExportBoolCaller( g_yz_side_shown ) ) );
|
||||
|
||||
Orthographic_registerPreferencesPage();
|
||||
Clipper_registerPreferencesPage();
|
||||
|
||||
g_cursorMoveClipper = gdk_cursor_new( GDK_CROSSHAIR );
|
||||
g_cursorClipper = gdk_cursor_new( GDK_HAND2 );
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user